From 31261bbe13b1d092c485bb9099ff654a0066f870 Mon Sep 17 00:00:00 2001 From: Fangliding Date: Sat, 4 May 2024 09:23:53 +0000 Subject: [PATCH] deploy: XTLS/Xray-docs-next@1bd1e18a9eeee18d4588795d2f09716571e72592 --- 404.html | 8 +- about/news.html | 6 +- ....html-3GimCU_9.js => 404.html-ZlBMbAmj.js} | 2 +- ...ermaid-AwfEy8fz.js => Mermaid-IzGpoWNz.js} | 4 +- assets/{Tab-zEFzyfPv.js => Tab-7BB5fVJi.js} | 2 +- assets/{Tabs-coEt0t4G.js => Tabs--CmfscRM.js} | 2 +- ....html-Bpdd1mqW.js => api.html-n2welLJa.js} | 2 +- ....html-ZyK7et4F.js => api.html-obbK2QQ5.js} | 2 +- assets/{app-PDrbPfzp.js => app-UOvWaKji.js} | 4 +- assets/{arc-XT00965o.js => arc-5GdQY_kf.js} | 2 +- ...5o0GnugA.js => blackhole.html-2q5PndzG.js} | 2 +- ..._QMN6sZq.js => blackhole.html-MeysKqPJ.js} | 2 +- ...6.js => blockDiagram-91b80b7a-6EYGTs6T.js} | 2 +- ...Keb.js => browser_dialer.html-ioRP4mhn.js} | 2 +- ...x9j.js => browser_dialer.html-oLr7tN0I.js} | 2 +- ...NFqu.js => c4Diagram-b2a90758-Ozn2CEAW.js} | 2 +- ...ruxaH.js => ch01-preface.html-Xp85YRwD.js} | 2 +- ...Wqh8J.js => ch01-preface.html-bIl_Km3k.js} | 2 +- ...z.js => ch02-preparation.html-flUUoP_1.js} | 2 +- ...W.js => ch02-preparation.html-lZJv5DvE.js} | 2 +- ...-kdsftrBp.js => ch03-ssh.html-PreKlYZo.js} | 2 +- ...-34HWUQzq.js => ch03-ssh.html-ZqJB8vGA.js} | 2 +- ...ShHh.js => ch04-security.html-33MaGmAV.js} | 2 +- ...bCda.js => ch04-security.html-zUuYrXhG.js} | 2 +- ...GqU2C.js => ch05-webpage.html-H5TsNIcu.js} | 2 +- ...4PY0o.js => ch05-webpage.html-lTr31Joi.js} | 2 +- ....js => ch06-certificates.html-vKtVQYmc.js} | 2 +- ....js => ch06-certificates.html-vz4TPMTq.js} | 2 +- ...O.js => ch07-xray-server.html-M88Oyw5u.js} | 2 +- ...v.js => ch07-xray-server.html-TVGmVR8g.js} | 2 +- ....js => ch08-xray-clients.html-VmriEsh2.js} | 2 +- ....js => ch08-xray-clients.html-s9iITOvA.js} | 2 +- ...PKr6.js => ch09-appendix.html-BpoURQUR.js} | 2 +- ...J-AJ.js => ch09-appendix.html-Ouutf7uu.js} | 2 +- assets/channel-GQnHP4O7.js | 1 - assets/channel-hMLbS6Zi.js | 1 + ...t.js => classDiagram-30eddba6-LzAW2Y3L.js} | 2 +- ...s => classDiagram-v2-f2df5561-L_-CRfCF.js} | 2 +- assets/clone-bRwIupqN.js | 1 + assets/clone-jETecP85.js | 1 - ...l-MQnx7SGt.js => command.html-GmQWX7Oz.js} | 2 +- ...l-Q2_pBtQX.js => command.html-Pk9D3c6o.js} | 2 +- ...l-QZoJ6y29.js => compile.html-B6Lx1oYG.js} | 2 +- ...l-t_m_hch4.js => compile.html-p25837Gy.js} | 2 +- ...ml-Hj3P0-iE.js => config.html-FFB6YdOZ.js} | 2 +- ...ml-862ghCov.js => config.html-RkLhbZyp.js} | 2 +- ...zU9.js => createText-6b48ae7d-yUX1YD6G.js} | 2 +- ...ml-9OU4NAkY.js => design.html-2PskSFhP.js} | 2 +- ...ml-oldCFeI5.js => design.html-fPrl8l20.js} | 2 +- ....html-KHoheVAl.js => dns.html-C2aGNNlR.js} | 2 +- ....html-VxRYmR2X.js => dns.html-nzh_mzUH.js} | 2 +- ....html-k6tvDtjK.js => dns.html-qUo2_myA.js} | 2 +- ....html-FvK6oEVD.js => dns.html-s7z_7JTn.js} | 2 +- ...-tw05mdL_.js => document.html-OTBh_E9Y.js} | 2 +- ...-IBOddkUf.js => document.html-WKG-xpF1.js} | 2 +- ...-p5Zz9pNk.js => dokodemo.html-9tXE84yJ.js} | 2 +- ...-m7ra4W8c.js => dokodemo.html-s_SNa9En.js} | 2 +- ...JhZlD.js => domainsocket.html-fCTWcn10.js} | 2 +- ...uPmBS.js => domainsocket.html-zhkqh_tc.js} | 2 +- ...iT1MEq_Y.js => edges-d32062c0-DdP-jtfh.js} | 2 +- ....html-UjH5T2XA.js => env.html-98sQ-YHZ.js} | 2 +- ....html-sFYt-_pK.js => env.html-Wh-9-BVt.js} | 2 +- ...LOL9.js => erDiagram-47591fe2-RWR6JLP0.js} | 2 +- ...l-usFdfR00.js => fakedns.html-7yy_Hwj4.js} | 2 +- ...l-aUN-NotP.js => fakedns.html-jPUstbOM.js} | 2 +- ...-1NLLtTvN.js => fallback.html-GSgUfNDP.js} | 2 +- ...-j-WsWvnI.js => fallback.html-SRUkF-k8.js} | 2 +- ...8itW.js => fallbacks-lv1.html--wD9yMzq.js} | 2 +- ...P3Lr.js => fallbacks-lv1.html-SBMi_sxl.js} | 2 +- ...js => fallbacks-with-sni.html-EwR1fYMf.js} | 2 +- ...js => fallbacks-with-sni.html-bYbXLNvx.js} | 2 +- ...Ahi6J2v.js => flowDb-4b19a42f-e0bq62ON.js} | 2 +- ...7I.js => flowDiagram-5540d9b9-mp-41puG.js} | 2 +- assets/flowDiagram-v2-3b53844e-Cs1ZpX_T.js | 1 + assets/flowDiagram-v2-3b53844e-VJ0ZCiud.js | 1 - ...chart-elk-definition-5fe447d6-pCydUlJz.js} | 2 +- ...l-Br08NJvS.js => freedom.html-IBZ61bfy.js} | 2 +- ...l-uApcqWvy.js => freedom.html-vLTb4l01.js} | 2 +- ...S.js => ganttDiagram-9a3bba1f-KGvD9HhD.js} | 2 +- ...s => gitGraphDiagram-96e6b4ee-kyRwI9Lw.js} | 2 +- .../{graph-cZfODKa1.js => graph-yVkSecXb.js} | 2 +- ...html-XKtsy_pl.js => grpc.html-m78M3EJR.js} | 2 +- ...html-owthEglu.js => grpc.html-wuI--JNX.js} | 2 +- ...tml-C5_iWVEd.js => guide.html-rhDtidv8.js} | 2 +- ...tml-K0U2knuj.js => guide.html-yvvDMK2K.js} | 2 +- ...2.html-GaXRW7zG.js => h2.html-8klqPb9j.js} | 2 +- ...2.html-Qs5yO4Vz.js => h2.html-XhOE9s1o.js} | 2 +- ...html-FQ-Y96ef.js => http.html-FEDggO-p.js} | 2 +- ...html-TnUHA5fS.js => http.html-PUYLTCZT.js} | 2 +- ...html-WXAZvIym.js => http.html-_yXVXvnY.js} | 2 +- ...html-bLJEWSqs.js => http.html-gFUfd4hn.js} | 2 +- ...rMkERg.js => httpupgrade.html-8y62ZYsJ.js} | 2 +- ...UuHOb_.js => httpupgrade.html-HCGGfbXe.js} | 2 +- ...l-xA8fmFfL.js => inbound.html-LOzJibnU.js} | 2 +- ...l-7sY9D7Up.js => inbound.html-fVeoUFmr.js} | 2 +- ...knA-ZLJ0.js => index-fc10efb0-cfY4JypU.js} | 2 +- ...tml-9pCVMb8K.js => index.html-GzgMAJYU.js} | 2 +- ...tml-OGTuF_nH.js => index.html-JMYPbZuF.js} | 2 +- ...tml-glFsxwLj.js => index.html-RZwWF3O4.js} | 2 +- ...tml-DEQtxzNJ.js => index.html-W0PzUpCJ.js} | 2 +- ...tml-_vJQzZ80.js => index.html-cm8hOcNA.js} | 2 +- ...tml-Mbhofp-W.js => index.html-ecj8aV3P.js} | 2 +- ...tml-UNm3UMUZ.js => index.html-gKKe0Pu1.js} | 2 +- ...tml-xynTfTar.js => index.html-l5bGGUL1.js} | 2 +- ...tml-ihOMAxW0.js => index.html-p2MYx25S.js} | 2 +- ...tml-1LatBnTC.js => index.html-qxx9ljxd.js} | 2 +- ...tml-AMhQDD2G.js => index.html-sJo1M-Sj.js} | 2 +- ...tml-h67PRaMY.js => index.html-uM2EqCct.js} | 2 +- ...tml-kLtDZulC.js => index.html-x0joMVfy.js} | 2 +- ...tml-e3Eb14uc.js => index.html-xbzqWGZe.js} | 2 +- ...Zm.js => infoDiagram-bcd20f53-qNUwp2oi.js} | 2 +- ...l-Q9rZTV_2.js => install.html-H_t1fqr8.js} | 2 +- ...l-C76Ht-N3.js => install.html-VE-T3hko.js} | 2 +- ...EZycZ.js => iptables_gid.html-XKlKifPE.js} | 2 +- ...dGUsZ.js => iptables_gid.html-f-TyOGt0.js} | 2 +- ...js => journeyDiagram-4fe6b3dc-v7Caieti.js} | 2 +- ...{layout-konkdG3Z.js => layout-2f_iGf4E.js} | 2 +- assets/{line-_nnM_7ZX.js => line-3Gyevr9q.js} | 2 +- ...{linear-yB98X29G.js => linear-eA8J8eJ4.js} | 2 +- ....html-6VYWlh7_.js => log.html-7A6BNzqC.js} | 2 +- ....html-CNcmi473.js => log.html-NTUL9-8j.js} | 2 +- ...--hPilBz9.js => loopback.html-Bzq00ZYC.js} | 2 +- ...-4ZKd-9LO.js => loopback.html-hvdhvF1l.js} | 2 +- ...e-95b3ca__.js => mermaid.core-Q3WVcjPF.js} | 8 +- ...l-M_EKpCet.js => metrics.html-ebI0OPa_.js} | 2 +- ...l-O2MdDQGJ.js => metrics.html-mI5FrxlZ.js} | 2 +- ...> mindmap-definition-f354de21-llC7ZqOF.js} | 2 +- ...html-oWZkTGfJ.js => mkcp.html-DONGnnA_.js} | 2 +- ...html-KvSr11eW.js => mkcp.html-P3j-P5YO.js} | 2 +- ...html-z0TX3kIH.js => mkcp.html-censPzO_.js} | 2 +- ...html-8I8osN8v.js => mkcp.html-i8OOkSjS.js} | 2 +- assets/multiple.html-TLF_RZel.js | 87 ------------- assets/multiple.html-g48N6K0K.js | 1 - ...-1mvnHAHO.js => multiple.html-iAO2Lnc3.js} | 2 +- assets/multiple.html-lXhmxiM0.js | 1 + assets/multiple.html-zE8J70pG.js | 75 +++++++++++ ...l-evEdSRWg.js => muxcool.html-_Q_MClhY.js} | 2 +- ...l-Qf6P8rXo.js => muxcool.html-mWlirYUy.js} | 2 +- ...html-KjqE-CJP.js => news.html--Ypfy9X2.js} | 2 +- ...html-Symbtc2m.js => news.html-ayZea3Z8.js} | 2 +- ...nx_or_haproxy_tls_tunnel.html-1_qLmdh0.js} | 2 +- ...nx_or_haproxy_tls_tunnel.html-J7GQDlYh.js} | 2 +- ...-pTrUMPv-.js => outbound.html-c9chlcYi.js} | 2 +- ...-Uyme5CaQ.js => outbound.html-nhfh9iOW.js} | 2 +- ...ShQ.js => pieDiagram-79897490-xf0NxzxJ.js} | 2 +- ...ml-nFbqdJoW.js => policy.html-60KZMSiW.js} | 2 +- ...ml-yO5cVi3O.js => policy.html-RrAD2wsU.js} | 2 +- ...s => quadrantDiagram-62f64e94-cAAwIO1z.js} | 2 +- ...html-ES7-n1_Y.js => quic.html-2dnyw5D-.js} | 2 +- ...html-tieiwfcI.js => quic.html-WnhipFbM.js} | 2 +- ...-Z0rUViRJ.js => redirect.html-Fo5Y5X-S.js} | 2 +- ...-J60JFiXJ.js => redirect.html-b2j-2sFY.js} | 2 +- ...> requirementDiagram-05bf5f74-HkrjUmOA.js} | 2 +- ...l-kt-Xsscv.js => reverse.html-pdrvooXr.js} | 2 +- ...l-wshR1As_.js => reverse.html-w7txkdmv.js} | 2 +- ....js => routing-lv1-part1.html-WHpw4v1x.js} | 2 +- ....js => routing-lv1-part1.html-s_m1VGph.js} | 2 +- ....js => routing-lv1-part2.html-FFYQ14md.js} | 2 +- ....js => routing-lv1-part2.html-J8wCOEnV.js} | 2 +- ...l-h85eQ1aY.js => routing.html-mmvuVaFi.js} | 2 +- ...l-xothq4nq.js => routing.html-oysaUhpj.js} | 2 +- ....js => sankeyDiagram-97764748-XP-AU6IQ.js} | 2 +- ...s => sequenceDiagram-acc0e65c-So47ZKCj.js} | 2 +- ...kJPTtP.js => shadowsocks.html-2sZeanJM.js} | 2 +- ..._uET28.js => shadowsocks.html-CX52is5W.js} | 2 +- ...zaiMQX.js => shadowsocks.html-U6pVq6AU.js} | 2 +- ...wGKt2T.js => shadowsocks.html-qiN3SGfm.js} | 2 +- ...tml-BHL_zNqv.js => socks.html-AQ8z9yrR.js} | 2 +- ...tml-NHy_YtOR.js => socks.html-RHePOH-J.js} | 2 +- ...tml-0nKX1rUP.js => socks.html-SJq0hqhp.js} | 2 +- ...tml-hTp9HjkK.js => socks.html-_F9IwK5H.js} | 2 +- ...H.js => stateDiagram-0ff1cf1a-Rh0IBuDT.js} | 2 +- ...s => stateDiagram-v2-9a9d610d-Gp1zKQgn.js} | 2 +- ...tml-oDAoa3xt.js => stats.html-Ev72Xnyf.js} | 2 +- ...tml-N9FgSeRj.js => stats.html-hOtiN8ks.js} | 2 +- ...Bozeukd.js => styles-3ed67cfa-xu8Odik1.js} | 2 +- ...HdkyrCb.js => styles-991ebdfc-6jesWoI2.js} | 2 +- ...W20WKkm.js => styles-d20c7d72-fXd0DLOZ.js} | 2 +- ....js => svgDrawCommon-5ccd53ef-wBNBFr7n.js} | 2 +- ....html-3jgF7WlU.js => tcp.html-A1382ftf.js} | 2 +- ....html-boyh_9AY.js => tcp.html-ZlB-8N_8.js} | 2 +- ... timeline-definition-fea2a41d-Scl62dAd.js} | 2 +- ...ml-lyGaCi6Q.js => tproxy.html-VWEtc--I.js} | 2 +- ...ml-9M3-wGDd.js => tproxy.html-nklfTqvg.js} | 2 +- ... => tproxy_ipv4_and_ipv6.html-YTH3X_7C.js} | 2 +- ... => tproxy_ipv4_and_ipv6.html-mtR0hhvb.js} | 2 +- ...-DEd.js => traffic_stats.html-HWyX5twA.js} | 2 +- ...1-3n.js => traffic_stats.html-qY70pWXT.js} | 2 +- ....js => transparent_proxy.html-RiPSpqp_.js} | 2 +- ....js => transparent_proxy.html-bIbjewZt.js} | 2 +- ...w0GXOLfO.js => transport.html-mYn2VrkQ.js} | 2 +- ...fjf1PegS.js => transport.html-yVjoGdDV.js} | 2 +- ...ml-LeKVwimm.js => trojan.html-5IABW9eX.js} | 2 +- ...ml-8Xtn_ZhO.js => trojan.html-MDx9UVlc.js} | 2 +- ...ml-ID_eR97m.js => trojan.html-O_FJql5l.js} | 2 +- ...ml-qii0knEl.js => trojan.html-zN8km5_s.js} | 2 +- ...tml-atmKcdJ9.js => vless.html--6fAlyfP.js} | 2 +- ...tml-462FM1ut.js => vless.html-62T-Q8OK.js} | 2 +- ...tml-ydRLwf6Z.js => vless.html-K1mymGPl.js} | 2 +- ...tml-3H2ueBQw.js => vless.html-RePhqH5Q.js} | 2 +- ...tml-hLM6-o-1.js => vless.html-TuQcbXVI.js} | 2 +- ...tml-BeDExndi.js => vless.html-w-KHS2qb.js} | 2 +- ...tml-3hG8mFqR.js => vmess.html-14n3YBGD.js} | 2 +- ...tml-MOyi84fJ.js => vmess.html-5Z4DWDCo.js} | 2 +- ...tml-Ajbfrx88.js => vmess.html-BwXqJ3Vn.js} | 2 +- ...tml-gVQqtA6f.js => vmess.html-Q9QMl6ca.js} | 2 +- ...tml-wh0ZrbYC.js => vmess.html-XpONl2yo.js} | 2 +- ...tml-mxEzZ4Nm.js => vmess.html-bWXrud15.js} | 2 +- ...html-co4A2qJl.js => warp.html-InWQqDIT.js} | 2 +- ...html-A8L2N42a.js => warp.html-Nyf1dpD9.js} | 2 +- ...5im3Rtj5.js => websocket.html-G4eliqnC.js} | 2 +- ...YSPsZ2_H.js => websocket.html-fT5fCDqV.js} | 2 +- ...OyUeeF20.js => wireguard.html-BCZ3AkFH.js} | 2 +- ...yFYoQrs2.js => wireguard.html-K_sm3lda.js} | 2 +- ...html-5iU00aiu.js => work.html-HxgjsHti.js} | 2 +- ...html-rHkxptVO.js => work.html-fccvP5Wo.js} | 2 +- ...html-vMAM7WFy.js => xtls.html-5PMkSJTh.js} | 2 +- ...html--f-cdwuj.js => xtls.html-6RQbZOas.js} | 2 +- ...js => xychartDiagram-ab372869-zbSuzsOs.js} | 2 +- config/api.html | 6 +- config/dns.html | 6 +- config/fakedns.html | 6 +- config/features/browser_dialer.html | 6 +- config/features/env.html | 6 +- config/features/fallback.html | 6 +- config/features/multiple.html | 120 ++++++++---------- config/features/xtls.html | 6 +- config/inbound.html | 6 +- config/inbounds/dokodemo.html | 6 +- config/inbounds/http.html | 6 +- config/inbounds/shadowsocks.html | 6 +- config/inbounds/socks.html | 6 +- config/inbounds/trojan.html | 6 +- config/inbounds/vless.html | 6 +- config/inbounds/vmess.html | 6 +- config/index.html | 6 +- config/log.html | 6 +- config/metrics.html | 6 +- config/outbound.html | 6 +- config/outbounds/blackhole.html | 6 +- config/outbounds/dns.html | 6 +- config/outbounds/freedom.html | 6 +- config/outbounds/http.html | 6 +- config/outbounds/loopback.html | 6 +- config/outbounds/shadowsocks.html | 6 +- config/outbounds/socks.html | 6 +- config/outbounds/trojan.html | 6 +- config/outbounds/vless.html | 6 +- config/outbounds/vmess.html | 6 +- config/outbounds/wireguard.html | 6 +- config/policy.html | 6 +- config/reverse.html | 6 +- config/routing.html | 6 +- config/stats.html | 6 +- config/transport.html | 6 +- config/transports/domainsocket.html | 6 +- config/transports/grpc.html | 6 +- config/transports/h2.html | 6 +- config/transports/httpupgrade.html | 6 +- config/transports/mkcp.html | 6 +- config/transports/quic.html | 6 +- config/transports/tcp.html | 6 +- config/transports/websocket.html | 6 +- development/index.html | 6 +- development/intro/compile.html | 6 +- development/intro/design.html | 6 +- development/intro/guide.html | 6 +- development/protocols/mkcp.html | 6 +- development/protocols/muxcool.html | 6 +- development/protocols/vless.html | 6 +- development/protocols/vmess.html | 6 +- document/command.html | 6 +- document/config.html | 6 +- document/document.html | 6 +- document/index.html | 6 +- document/install.html | 6 +- document/level-0/ch01-preface.html | 6 +- document/level-0/ch02-preparation.html | 6 +- document/level-0/ch03-ssh.html | 6 +- document/level-0/ch04-security.html | 6 +- document/level-0/ch05-webpage.html | 6 +- document/level-0/ch06-certificates.html | 6 +- document/level-0/ch07-xray-server.html | 6 +- document/level-0/ch08-xray-clients.html | 6 +- document/level-0/ch09-appendix.html | 6 +- document/level-0/index.html | 6 +- document/level-1/fallbacks-lv1.html | 6 +- document/level-1/fallbacks-with-sni.html | 6 +- document/level-1/index.html | 6 +- document/level-1/routing-lv1-part1.html | 6 +- document/level-1/routing-lv1-part2.html | 6 +- document/level-1/work.html | 6 +- document/level-2/index.html | 6 +- document/level-2/iptables_gid.html | 6 +- .../level-2/nginx_or_haproxy_tls_tunnel.html | 6 +- document/level-2/redirect.html | 6 +- document/level-2/tproxy.html | 6 +- document/level-2/tproxy_ipv4_and_ipv6.html | 6 +- document/level-2/traffic_stats.html | 6 +- .../transparent_proxy/transparent_proxy.html | 6 +- document/level-2/warp.html | 6 +- en/about/news.html | 6 +- en/config/api.html | 6 +- en/config/dns.html | 6 +- en/config/fakedns.html | 6 +- en/config/features/browser_dialer.html | 6 +- en/config/features/env.html | 6 +- en/config/features/fallback.html | 6 +- en/config/features/multiple.html | 6 +- en/config/features/xtls.html | 6 +- en/config/inbound.html | 6 +- en/config/inbounds/dokodemo.html | 6 +- en/config/inbounds/http.html | 6 +- en/config/inbounds/shadowsocks.html | 6 +- en/config/inbounds/socks.html | 6 +- en/config/inbounds/trojan.html | 6 +- en/config/inbounds/vless.html | 6 +- en/config/inbounds/vmess.html | 6 +- en/config/index.html | 6 +- en/config/log.html | 6 +- en/config/metrics.html | 6 +- en/config/outbound.html | 6 +- en/config/outbounds/blackhole.html | 6 +- en/config/outbounds/dns.html | 6 +- en/config/outbounds/freedom.html | 6 +- en/config/outbounds/http.html | 6 +- en/config/outbounds/loopback.html | 6 +- en/config/outbounds/shadowsocks.html | 6 +- en/config/outbounds/socks.html | 6 +- en/config/outbounds/trojan.html | 6 +- en/config/outbounds/vless.html | 6 +- en/config/outbounds/vmess.html | 6 +- en/config/outbounds/wireguard.html | 6 +- en/config/policy.html | 6 +- en/config/reverse.html | 6 +- en/config/routing.html | 6 +- en/config/stats.html | 6 +- en/config/transport.html | 6 +- en/config/transports/domainsocket.html | 6 +- en/config/transports/grpc.html | 6 +- en/config/transports/h2.html | 6 +- en/config/transports/httpupgrade.html | 6 +- en/config/transports/mkcp.html | 6 +- en/config/transports/quic.html | 6 +- en/config/transports/tcp.html | 6 +- en/config/transports/websocket.html | 6 +- en/development/index.html | 6 +- en/development/intro/compile.html | 6 +- en/development/intro/design.html | 6 +- en/development/intro/guide.html | 6 +- en/development/protocols/mkcp.html | 6 +- en/development/protocols/muxcool.html | 6 +- en/development/protocols/vless.html | 6 +- en/development/protocols/vmess.html | 6 +- en/document/command.html | 6 +- en/document/config.html | 6 +- en/document/document.html | 6 +- en/document/index.html | 6 +- en/document/install.html | 6 +- en/document/level-0/ch01-preface.html | 6 +- en/document/level-0/ch02-preparation.html | 6 +- en/document/level-0/ch03-ssh.html | 6 +- en/document/level-0/ch04-security.html | 6 +- en/document/level-0/ch05-webpage.html | 6 +- en/document/level-0/ch06-certificates.html | 6 +- en/document/level-0/ch07-xray-server.html | 6 +- en/document/level-0/ch08-xray-clients.html | 6 +- en/document/level-0/ch09-appendix.html | 6 +- en/document/level-0/index.html | 6 +- en/document/level-1/fallbacks-lv1.html | 6 +- en/document/level-1/fallbacks-with-sni.html | 6 +- en/document/level-1/index.html | 6 +- en/document/level-1/routing-lv1-part1.html | 6 +- en/document/level-1/routing-lv1-part2.html | 6 +- en/document/level-1/work.html | 6 +- en/document/level-2/index.html | 6 +- en/document/level-2/iptables_gid.html | 6 +- .../level-2/nginx_or_haproxy_tls_tunnel.html | 6 +- en/document/level-2/redirect.html | 6 +- en/document/level-2/tproxy.html | 6 +- en/document/level-2/tproxy_ipv4_and_ipv6.html | 6 +- en/document/level-2/traffic_stats.html | 6 +- .../transparent_proxy/transparent_proxy.html | 6 +- en/document/level-2/warp.html | 6 +- en/index.html | 6 +- index.html | 6 +- 386 files changed, 850 insertions(+), 874 deletions(-) rename assets/{404.html-3GimCU_9.js => 404.html-ZlBMbAmj.js} (63%) rename assets/{Mermaid-AwfEy8fz.js => Mermaid-IzGpoWNz.js} (89%) rename assets/{Tab-zEFzyfPv.js => Tab-7BB5fVJi.js} (89%) rename assets/{Tabs-coEt0t4G.js => Tabs--CmfscRM.js} (95%) rename assets/{api.html-Bpdd1mqW.js => api.html-n2welLJa.js} (99%) rename assets/{api.html-ZyK7et4F.js => api.html-obbK2QQ5.js} (99%) rename assets/{app-PDrbPfzp.js => app-UOvWaKji.js} (54%) rename assets/{arc-XT00965o.js => arc-5GdQY_kf.js} (96%) rename assets/{blackhole.html-5o0GnugA.js => blackhole.html-2q5PndzG.js} (97%) rename assets/{blackhole.html-_QMN6sZq.js => blackhole.html-MeysKqPJ.js} (97%) rename assets/{blockDiagram-91b80b7a-W38ApPQ6.js => blockDiagram-91b80b7a-6EYGTs6T.js} (98%) rename assets/{browser_dialer.html-oocymKeb.js => browser_dialer.html-ioRP4mhn.js} (98%) rename assets/{browser_dialer.html-xSfDwx9j.js => browser_dialer.html-oLr7tN0I.js} (98%) rename assets/{c4Diagram-b2a90758-61jLNFqu.js => c4Diagram-b2a90758-Ozn2CEAW.js} (99%) rename assets/{ch01-preface.html-ltnruxaH.js => ch01-preface.html-Xp85YRwD.js} (99%) rename assets/{ch01-preface.html-h3OWqh8J.js => ch01-preface.html-bIl_Km3k.js} (99%) rename assets/{ch02-preparation.html-7bycodSz.js => ch02-preparation.html-flUUoP_1.js} (98%) rename assets/{ch02-preparation.html-nUCvuwbW.js => ch02-preparation.html-lZJv5DvE.js} (98%) rename assets/{ch03-ssh.html-kdsftrBp.js => ch03-ssh.html-PreKlYZo.js} (99%) rename assets/{ch03-ssh.html-34HWUQzq.js => ch03-ssh.html-ZqJB8vGA.js} (99%) rename assets/{ch04-security.html-tFoBShHh.js => ch04-security.html-33MaGmAV.js} (99%) rename assets/{ch04-security.html-fCxnbCda.js => ch04-security.html-zUuYrXhG.js} (99%) rename assets/{ch05-webpage.html-XwVGqU2C.js => ch05-webpage.html-H5TsNIcu.js} (99%) rename assets/{ch05-webpage.html-lik4PY0o.js => ch05-webpage.html-lTr31Joi.js} (99%) rename assets/{ch06-certificates.html-kGI8p0zP.js => ch06-certificates.html-vKtVQYmc.js} (99%) rename assets/{ch06-certificates.html-3Wj6Kppi.js => ch06-certificates.html-vz4TPMTq.js} (99%) rename assets/{ch07-xray-server.html-vH8VA1RO.js => ch07-xray-server.html-M88Oyw5u.js} (99%) rename assets/{ch07-xray-server.html-Cs4sLfUv.js => ch07-xray-server.html-TVGmVR8g.js} (99%) rename assets/{ch08-xray-clients.html-6ijP-wsT.js => ch08-xray-clients.html-VmriEsh2.js} (99%) rename assets/{ch08-xray-clients.html-w9IqqavR.js => ch08-xray-clients.html-s9iITOvA.js} (99%) rename assets/{ch09-appendix.html-eMozPKr6.js => ch09-appendix.html-BpoURQUR.js} (99%) rename assets/{ch09-appendix.html-XGC3J-AJ.js => ch09-appendix.html-Ouutf7uu.js} (99%) delete mode 100644 assets/channel-GQnHP4O7.js create mode 100644 assets/channel-hMLbS6Zi.js rename assets/{classDiagram-30eddba6-OAikPNdt.js => classDiagram-30eddba6-LzAW2Y3L.js} (97%) rename assets/{classDiagram-v2-f2df5561-yJMOQ1KK.js => classDiagram-v2-f2df5561-L_-CRfCF.js} (92%) create mode 100644 assets/clone-bRwIupqN.js delete mode 100644 assets/clone-jETecP85.js rename assets/{command.html-MQnx7SGt.js => command.html-GmQWX7Oz.js} (99%) rename assets/{command.html-Q2_pBtQX.js => command.html-Pk9D3c6o.js} (99%) rename assets/{compile.html-QZoJ6y29.js => compile.html-B6Lx1oYG.js} (99%) rename assets/{compile.html-t_m_hch4.js => compile.html-p25837Gy.js} (98%) rename assets/{config.html-Hj3P0-iE.js => config.html-FFB6YdOZ.js} (99%) rename assets/{config.html-862ghCov.js => config.html-RkLhbZyp.js} (99%) rename assets/{createText-6b48ae7d-9AoX5zU9.js => createText-6b48ae7d-yUX1YD6G.js} (99%) rename assets/{design.html-9OU4NAkY.js => design.html-2PskSFhP.js} (98%) rename assets/{design.html-oldCFeI5.js => design.html-fPrl8l20.js} (97%) rename assets/{dns.html-KHoheVAl.js => dns.html-C2aGNNlR.js} (99%) rename assets/{dns.html-VxRYmR2X.js => dns.html-nzh_mzUH.js} (99%) rename assets/{dns.html-k6tvDtjK.js => dns.html-qUo2_myA.js} (98%) rename assets/{dns.html-FvK6oEVD.js => dns.html-s7z_7JTn.js} (98%) rename assets/{document.html-tw05mdL_.js => document.html-OTBh_E9Y.js} (98%) rename assets/{document.html-IBOddkUf.js => document.html-WKG-xpF1.js} (98%) rename assets/{dokodemo.html-p5Zz9pNk.js => dokodemo.html-9tXE84yJ.js} (98%) rename assets/{dokodemo.html-m7ra4W8c.js => dokodemo.html-s_SNa9En.js} (98%) rename assets/{domainsocket.html-VOdJhZlD.js => domainsocket.html-fCTWcn10.js} (97%) rename assets/{domainsocket.html-o3wuPmBS.js => domainsocket.html-zhkqh_tc.js} (97%) rename assets/{edges-d32062c0-iT1MEq_Y.js => edges-d32062c0-DdP-jtfh.js} (99%) rename assets/{env.html-UjH5T2XA.js => env.html-98sQ-YHZ.js} (97%) rename assets/{env.html-sFYt-_pK.js => env.html-Wh-9-BVt.js} (97%) rename assets/{erDiagram-47591fe2-CbfSLOL9.js => erDiagram-47591fe2-RWR6JLP0.js} (99%) rename assets/{fakedns.html-usFdfR00.js => fakedns.html-7yy_Hwj4.js} (99%) rename assets/{fakedns.html-aUN-NotP.js => fakedns.html-jPUstbOM.js} (99%) rename assets/{fallback.html-1NLLtTvN.js => fallback.html-GSgUfNDP.js} (99%) rename assets/{fallback.html-j-WsWvnI.js => fallback.html-SRUkF-k8.js} (99%) rename assets/{fallbacks-lv1.html-LXNm8itW.js => fallbacks-lv1.html--wD9yMzq.js} (99%) rename assets/{fallbacks-lv1.html-o6nPP3Lr.js => fallbacks-lv1.html-SBMi_sxl.js} (99%) rename assets/{fallbacks-with-sni.html-_rwOIQFb.js => fallbacks-with-sni.html-EwR1fYMf.js} (99%) rename assets/{fallbacks-with-sni.html-Hu3dL1kT.js => fallbacks-with-sni.html-bYbXLNvx.js} (99%) rename assets/{flowDb-4b19a42f-sAhi6J2v.js => flowDb-4b19a42f-e0bq62ON.js} (99%) rename assets/{flowDiagram-5540d9b9-XEePSu7I.js => flowDiagram-5540d9b9-mp-41puG.js} (97%) create mode 100644 assets/flowDiagram-v2-3b53844e-Cs1ZpX_T.js delete mode 100644 assets/flowDiagram-v2-3b53844e-VJ0ZCiud.js rename assets/{flowchart-elk-definition-5fe447d6-2wwBOAT6.js => flowchart-elk-definition-5fe447d6-pCydUlJz.js} (99%) rename assets/{freedom.html-Br08NJvS.js => freedom.html-IBZ61bfy.js} (99%) rename assets/{freedom.html-uApcqWvy.js => freedom.html-vLTb4l01.js} (98%) rename assets/{ganttDiagram-9a3bba1f-Mk83ufVS.js => ganttDiagram-9a3bba1f-KGvD9HhD.js} (99%) rename assets/{gitGraphDiagram-96e6b4ee-Sl4MCJL1.js => gitGraphDiagram-96e6b4ee-kyRwI9Lw.js} (99%) rename assets/{graph-cZfODKa1.js => graph-yVkSecXb.js} (99%) rename assets/{grpc.html-XKtsy_pl.js => grpc.html-m78M3EJR.js} (99%) rename assets/{grpc.html-owthEglu.js => grpc.html-wuI--JNX.js} (99%) rename assets/{guide.html-C5_iWVEd.js => guide.html-rhDtidv8.js} (99%) rename assets/{guide.html-K0U2knuj.js => guide.html-yvvDMK2K.js} (99%) rename assets/{h2.html-GaXRW7zG.js => h2.html-8klqPb9j.js} (98%) rename assets/{h2.html-Qs5yO4Vz.js => h2.html-XhOE9s1o.js} (98%) rename assets/{http.html-FQ-Y96ef.js => http.html-FEDggO-p.js} (99%) rename assets/{http.html-TnUHA5fS.js => http.html-PUYLTCZT.js} (98%) rename assets/{http.html-WXAZvIym.js => http.html-_yXVXvnY.js} (99%) rename assets/{http.html-bLJEWSqs.js => http.html-gFUfd4hn.js} (98%) rename assets/{httpupgrade.html-nQrMkERg.js => httpupgrade.html-8y62ZYsJ.js} (98%) rename assets/{httpupgrade.html-KlUuHOb_.js => httpupgrade.html-HCGGfbXe.js} (98%) rename assets/{inbound.html-xA8fmFfL.js => inbound.html-LOzJibnU.js} (99%) rename assets/{inbound.html-7sY9D7Up.js => inbound.html-fVeoUFmr.js} (99%) rename assets/{index-fc10efb0-knA-ZLJ0.js => index-fc10efb0-cfY4JypU.js} (96%) rename assets/{index.html-9pCVMb8K.js => index.html-GzgMAJYU.js} (98%) rename assets/{index.html-OGTuF_nH.js => index.html-JMYPbZuF.js} (97%) rename assets/{index.html-glFsxwLj.js => index.html-RZwWF3O4.js} (98%) rename assets/{index.html-DEQtxzNJ.js => index.html-W0PzUpCJ.js} (98%) rename assets/{index.html-_vJQzZ80.js => index.html-cm8hOcNA.js} (99%) rename assets/{index.html-Mbhofp-W.js => index.html-ecj8aV3P.js} (98%) rename assets/{index.html-UNm3UMUZ.js => index.html-gKKe0Pu1.js} (98%) rename assets/{index.html-xynTfTar.js => index.html-l5bGGUL1.js} (94%) rename assets/{index.html-ihOMAxW0.js => index.html-p2MYx25S.js} (94%) rename assets/{index.html-1LatBnTC.js => index.html-qxx9ljxd.js} (97%) rename assets/{index.html-AMhQDD2G.js => index.html-sJo1M-Sj.js} (98%) rename assets/{index.html-h67PRaMY.js => index.html-uM2EqCct.js} (99%) rename assets/{index.html-kLtDZulC.js => index.html-x0joMVfy.js} (98%) rename assets/{index.html-e3Eb14uc.js => index.html-xbzqWGZe.js} (98%) rename assets/{infoDiagram-bcd20f53-aQsUByZm.js => infoDiagram-bcd20f53-qNUwp2oi.js} (98%) rename assets/{install.html-Q9rZTV_2.js => install.html-H_t1fqr8.js} (99%) rename assets/{install.html-C76Ht-N3.js => install.html-VE-T3hko.js} (99%) rename assets/{iptables_gid.html-dUUEZycZ.js => iptables_gid.html-XKlKifPE.js} (99%) rename assets/{iptables_gid.html-PN1dGUsZ.js => iptables_gid.html-f-TyOGt0.js} (99%) rename assets/{journeyDiagram-4fe6b3dc-5Up4aSjD.js => journeyDiagram-4fe6b3dc-v7Caieti.js} (98%) rename assets/{layout-konkdG3Z.js => layout-2f_iGf4E.js} (99%) rename assets/{line-_nnM_7ZX.js => line-3Gyevr9q.js} (93%) rename assets/{linear-yB98X29G.js => linear-eA8J8eJ4.js} (99%) rename assets/{log.html-6VYWlh7_.js => log.html-7A6BNzqC.js} (98%) rename assets/{log.html-CNcmi473.js => log.html-NTUL9-8j.js} (98%) rename assets/{loopback.html--hPilBz9.js => loopback.html-Bzq00ZYC.js} (98%) rename assets/{loopback.html-4ZKd-9LO.js => loopback.html-hvdhvF1l.js} (99%) rename assets/{mermaid.core-95b3ca__.js => mermaid.core-Q3WVcjPF.js} (98%) rename assets/{metrics.html-M_EKpCet.js => metrics.html-ebI0OPa_.js} (99%) rename assets/{metrics.html-O2MdDQGJ.js => metrics.html-mI5FrxlZ.js} (99%) rename assets/{mindmap-definition-f354de21-iPbIx-mR.js => mindmap-definition-f354de21-llC7ZqOF.js} (99%) rename assets/{mkcp.html-oWZkTGfJ.js => mkcp.html-DONGnnA_.js} (99%) rename assets/{mkcp.html-KvSr11eW.js => mkcp.html-P3j-P5YO.js} (98%) rename assets/{mkcp.html-z0TX3kIH.js => mkcp.html-censPzO_.js} (99%) rename assets/{mkcp.html-8I8osN8v.js => mkcp.html-i8OOkSjS.js} (98%) delete mode 100644 assets/multiple.html-TLF_RZel.js delete mode 100644 assets/multiple.html-g48N6K0K.js rename assets/{multiple.html-1mvnHAHO.js => multiple.html-iAO2Lnc3.js} (99%) create mode 100644 assets/multiple.html-lXhmxiM0.js create mode 100644 assets/multiple.html-zE8J70pG.js rename assets/{muxcool.html-evEdSRWg.js => muxcool.html-_Q_MClhY.js} (99%) rename assets/{muxcool.html-Qf6P8rXo.js => muxcool.html-mWlirYUy.js} (99%) rename assets/{news.html-KjqE-CJP.js => news.html--Ypfy9X2.js} (99%) rename assets/{news.html-Symbtc2m.js => news.html-ayZea3Z8.js} (99%) rename assets/{nginx_or_haproxy_tls_tunnel.html-2rfRu13n.js => nginx_or_haproxy_tls_tunnel.html-1_qLmdh0.js} (99%) rename assets/{nginx_or_haproxy_tls_tunnel.html-L37cuaZc.js => nginx_or_haproxy_tls_tunnel.html-J7GQDlYh.js} (99%) rename assets/{outbound.html-pTrUMPv-.js => outbound.html-c9chlcYi.js} (99%) rename assets/{outbound.html-Uyme5CaQ.js => outbound.html-nhfh9iOW.js} (99%) rename assets/{pieDiagram-79897490-axGt9ShQ.js => pieDiagram-79897490-xf0NxzxJ.js} (98%) rename assets/{policy.html-nFbqdJoW.js => policy.html-60KZMSiW.js} (99%) rename assets/{policy.html-yO5cVi3O.js => policy.html-RrAD2wsU.js} (99%) rename assets/{quadrantDiagram-62f64e94-DSAXizG6.js => quadrantDiagram-62f64e94-cAAwIO1z.js} (99%) rename assets/{quic.html-ES7-n1_Y.js => quic.html-2dnyw5D-.js} (98%) rename assets/{quic.html-tieiwfcI.js => quic.html-WnhipFbM.js} (98%) rename assets/{redirect.html-Z0rUViRJ.js => redirect.html-Fo5Y5X-S.js} (99%) rename assets/{redirect.html-J60JFiXJ.js => redirect.html-b2j-2sFY.js} (99%) rename assets/{requirementDiagram-05bf5f74--Z92gB8m.js => requirementDiagram-05bf5f74-HkrjUmOA.js} (98%) rename assets/{reverse.html-kt-Xsscv.js => reverse.html-pdrvooXr.js} (99%) rename assets/{reverse.html-wshR1As_.js => reverse.html-w7txkdmv.js} (99%) rename assets/{routing-lv1-part1.html-aK2Ox0S3.js => routing-lv1-part1.html-WHpw4v1x.js} (99%) rename assets/{routing-lv1-part1.html-XHZo4O7q.js => routing-lv1-part1.html-s_m1VGph.js} (99%) rename assets/{routing-lv1-part2.html-tkJjuuVl.js => routing-lv1-part2.html-FFYQ14md.js} (99%) rename assets/{routing-lv1-part2.html-JpbPk6FW.js => routing-lv1-part2.html-J8wCOEnV.js} (99%) rename assets/{routing.html-h85eQ1aY.js => routing.html-mmvuVaFi.js} (99%) rename assets/{routing.html-xothq4nq.js => routing.html-oysaUhpj.js} (99%) rename assets/{sankeyDiagram-97764748-A3D0wPEg.js => sankeyDiagram-97764748-XP-AU6IQ.js} (99%) rename assets/{sequenceDiagram-acc0e65c-TzfkGb4D.js => sequenceDiagram-acc0e65c-So47ZKCj.js} (99%) rename assets/{shadowsocks.html--KkJPTtP.js => shadowsocks.html-2sZeanJM.js} (99%) rename assets/{shadowsocks.html-P4_uET28.js => shadowsocks.html-CX52is5W.js} (99%) rename assets/{shadowsocks.html-gizaiMQX.js => shadowsocks.html-U6pVq6AU.js} (99%) rename assets/{shadowsocks.html-2vwGKt2T.js => shadowsocks.html-qiN3SGfm.js} (99%) rename assets/{socks.html-BHL_zNqv.js => socks.html-AQ8z9yrR.js} (98%) rename assets/{socks.html-NHy_YtOR.js => socks.html-RHePOH-J.js} (98%) rename assets/{socks.html-0nKX1rUP.js => socks.html-SJq0hqhp.js} (99%) rename assets/{socks.html-hTp9HjkK.js => socks.html-_F9IwK5H.js} (99%) rename assets/{stateDiagram-0ff1cf1a-sl2QinQH.js => stateDiagram-0ff1cf1a-Rh0IBuDT.js} (97%) rename assets/{stateDiagram-v2-9a9d610d-sZSBWe92.js => stateDiagram-v2-9a9d610d-Gp1zKQgn.js} (90%) rename assets/{stats.html-oDAoa3xt.js => stats.html-Ev72Xnyf.js} (97%) rename assets/{stats.html-N9FgSeRj.js => stats.html-hOtiN8ks.js} (97%) rename assets/{styles-3ed67cfa-FBozeukd.js => styles-3ed67cfa-xu8Odik1.js} (98%) rename assets/{styles-991ebdfc-vHdkyrCb.js => styles-991ebdfc-6jesWoI2.js} (99%) rename assets/{styles-d20c7d72-JW20WKkm.js => styles-d20c7d72-fXd0DLOZ.js} (99%) rename assets/{svgDrawCommon-5ccd53ef-iJa2TVTb.js => svgDrawCommon-5ccd53ef-wBNBFr7n.js} (95%) rename assets/{tcp.html-3jgF7WlU.js => tcp.html-A1382ftf.js} (99%) rename assets/{tcp.html-boyh_9AY.js => tcp.html-ZlB-8N_8.js} (99%) rename assets/{timeline-definition-fea2a41d-4QeTlQgD.js => timeline-definition-fea2a41d-Scl62dAd.js} (99%) rename assets/{tproxy.html-lyGaCi6Q.js => tproxy.html-VWEtc--I.js} (99%) rename assets/{tproxy.html-9M3-wGDd.js => tproxy.html-nklfTqvg.js} (99%) rename assets/{tproxy_ipv4_and_ipv6.html-IOus2e7D.js => tproxy_ipv4_and_ipv6.html-YTH3X_7C.js} (99%) rename assets/{tproxy_ipv4_and_ipv6.html-dQ2QtiC-.js => tproxy_ipv4_and_ipv6.html-mtR0hhvb.js} (99%) rename assets/{traffic_stats.html-vi4G-DEd.js => traffic_stats.html-HWyX5twA.js} (99%) rename assets/{traffic_stats.html-BjBI1-3n.js => traffic_stats.html-qY70pWXT.js} (99%) rename assets/{transparent_proxy.html-D-ct__hG.js => transparent_proxy.html-RiPSpqp_.js} (99%) rename assets/{transparent_proxy.html-oZsJizmp.js => transparent_proxy.html-bIbjewZt.js} (99%) rename assets/{transport.html-w0GXOLfO.js => transport.html-mYn2VrkQ.js} (99%) rename assets/{transport.html-fjf1PegS.js => transport.html-yVjoGdDV.js} (99%) rename assets/{trojan.html-LeKVwimm.js => trojan.html-5IABW9eX.js} (98%) rename assets/{trojan.html-8Xtn_ZhO.js => trojan.html-MDx9UVlc.js} (98%) rename assets/{trojan.html-ID_eR97m.js => trojan.html-O_FJql5l.js} (98%) rename assets/{trojan.html-qii0knEl.js => trojan.html-zN8km5_s.js} (98%) rename assets/{vless.html-atmKcdJ9.js => vless.html--6fAlyfP.js} (99%) rename assets/{vless.html-462FM1ut.js => vless.html-62T-Q8OK.js} (99%) rename assets/{vless.html-ydRLwf6Z.js => vless.html-K1mymGPl.js} (99%) rename assets/{vless.html-3H2ueBQw.js => vless.html-RePhqH5Q.js} (99%) rename assets/{vless.html-hLM6-o-1.js => vless.html-TuQcbXVI.js} (99%) rename assets/{vless.html-BeDExndi.js => vless.html-w-KHS2qb.js} (99%) rename assets/{vmess.html-3hG8mFqR.js => vmess.html-14n3YBGD.js} (99%) rename assets/{vmess.html-MOyi84fJ.js => vmess.html-5Z4DWDCo.js} (99%) rename assets/{vmess.html-Ajbfrx88.js => vmess.html-BwXqJ3Vn.js} (99%) rename assets/{vmess.html-gVQqtA6f.js => vmess.html-Q9QMl6ca.js} (99%) rename assets/{vmess.html-wh0ZrbYC.js => vmess.html-XpONl2yo.js} (99%) rename assets/{vmess.html-mxEzZ4Nm.js => vmess.html-bWXrud15.js} (99%) rename assets/{warp.html-co4A2qJl.js => warp.html-InWQqDIT.js} (99%) rename assets/{warp.html-A8L2N42a.js => warp.html-Nyf1dpD9.js} (99%) rename assets/{websocket.html-5im3Rtj5.js => websocket.html-G4eliqnC.js} (98%) rename assets/{websocket.html-YSPsZ2_H.js => websocket.html-fT5fCDqV.js} (98%) rename assets/{wireguard.html-OyUeeF20.js => wireguard.html-BCZ3AkFH.js} (99%) rename assets/{wireguard.html-yFYoQrs2.js => wireguard.html-K_sm3lda.js} (99%) rename assets/{work.html-5iU00aiu.js => work.html-HxgjsHti.js} (96%) rename assets/{work.html-rHkxptVO.js => work.html-fccvP5Wo.js} (96%) rename assets/{xtls.html-vMAM7WFy.js => xtls.html-5PMkSJTh.js} (78%) rename assets/{xtls.html--f-cdwuj.js => xtls.html-6RQbZOas.js} (76%) rename assets/{xychartDiagram-ab372869-NbNQWlrD.js => xychartDiagram-ab372869-zbSuzsOs.js} (99%) diff --git a/404.html b/404.html index b75b3fa90b..ee57df91e9 100644 --- a/404.html +++ b/404.html @@ -24,11 +24,11 @@ Project X - - + + -

404

How did we get here?
- +

404

There's nothing here.
+ diff --git a/about/news.html b/about/news.html index 2c1e5abfaa..c781c88e0e 100644 --- a/about/news.html +++ b/about/news.html @@ -24,11 +24,11 @@ 大史记 | Project X - - + +

大史记

2021.4.6

  • VuePress Next.
  • With Dark Mode.

2021.4.4

  • 本文档迎来的新的首页。
  • 本文档迎来了暗黑模式。
  • 当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。
  • 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
  • 🎉🎉🎉

2021.4.1 v1.4.2open in new tag

  • 不是愚人节玩笑,今天更新。
  • 加入 Browser Dialer,用与改变 TLS 指纹与行为。
  • 加入 uTLS,用与改变 TLS Client Hello 的指纹。
  • 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。

2021.3.25

没错还在变。 -_-

2021.3.15

文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

2021.3.14 v1.4.0open in new tag

  • Happy Pi-Day!
  • 这次是个大更新:
    • 为链式代理引入了传输层支持。
    • 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
    • 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
    • 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
    • 添加了 FakeDNS。
    • 还修复了系列的问题,添加了各类功能,详情请见更新日志。
  • 还是 VuePress 比较爽啊(

2021.3.3 1.3.1open in new tag

  • 这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。
  • 同时修复了一个会导致 Panic 的 bug。Holmium_认为这是在骗、在偷袭。
  • 修复了几个遗留问题。

2021.2.14 1.3.0open in new tag

  • Happy 🐮 Year 🎉!
  • v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。
  • OHHHHHHHHHHHH!

2021.01.31 1.2.4open in new tag

  • 解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。
  • 似乎这个版本没有什么改变,但这只是暴风雨前的宁静。
  • (没错我就是先知)

    你个傻子,你拿的是 UNO 牌。

2021.01.25

  • 全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载秘籍第一层咯...
  • 英文版文档网站逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!

2021.01.22 1.2.3open in new tag

  • 对 SS 协议的支持变强了, 支持单端口多用户!
  • 对 trojan 协议的支持也变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!
  • (VLESS: 嘤嘤嘤)
  • UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".
  • 嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.
  • 向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 a @Bohan Yangopen in new tag 致敬!
  • 其他美味小樱桃, 惯例更新品尝就对啦.

2021.01.19

  • 一些数字
    • 版本发布了 10   个 tag
    • 解决掉了 100  个 issue
    • 复刻了 300  个 fork
    • 点了 2000 个 star
    • 群 3000 个 人

2021.01.17

2021.01.15 1.2.2open in new tag

  • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
  • 之前预告的 UUID 修改正式上线.(往下看往下看)
  • 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
  • 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
  • 当然还有其他各种小糖果.(更新品尝就对了)
  • 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE

2021.01.12

  • 将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户.
    • 客户端写 "id": "我爱 🍉 老师 1314",
    • 服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)
  • 🍉 老师的小小白白话文大结局, 撒花.

2021.01.10 1.2.1open in new tag

  • 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
  • Google Voice 应该也可以正常使用 v2rayNG 拨打了.
  • 日志现在看起来更顺眼.

2021.01.07

  • 礼貌和尊重本应是社区不需要明说的准则之一。

2021.01.05

  • 文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

2021.01.03

2021.01.01

【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 1.2.0open in new tag

🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!

  • 圣诞礼物v1.1.5后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
  • (UDP 还会继续增强!)
  • 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
  • (不,下面不是广告,是里程碑。)
  • Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
    • 一人扛起了所有!支持各大主流协议!
    • 一骑绝尘的性能!
    • 日趋完善的功能!
    • 可怕的生命力与社区亲和力!
  • Xray 将继续保持前行! 因此 Xray 需要更多的英雄!!open in new tag
  • PS:请品,请细品release notesopen in new tag每一句。似乎有一个小秘密小彩蛋 (啊,有人敲门...我一会和你们说)

2020.12.29

透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, TG 群open in new tag火热测试中

2020.12.25 1.1.5open in new tag

圣诞节快乐!

  • 游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone
  • 你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...
  • (VLESS 的 UDP fullcone 和更多增强很快就到!)
  • 无须再担心证书验证被墙,OCSP stapling 已经上线!
  • kirin 带来了一大波 脚本更新.脚本在此open in new tag
  • 还有更多美味小樱桃!(不用问,更新品尝就对了)

2020.12.24

因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。 网址为:没错你正在看的就是open in new tag

大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)

文档网站需要不断完善和增加内容,以及完善设计。 因此更欢迎大家一起为文档建设添砖加瓦。 文档的仓库open in new tag

仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站. 欢迎大家查看,纠错,修改,增加心得。

2020.12.23

Xray-core Shadowsocks UDP FullCone 测试版, TG 群open in new tag火热测试中

2020.12.21

  • Project X 群人数 2000+
  • 群消息(含游戏群) 日均破万

2020.12.18 1.1.4open in new tag

  • 更低的启动内占用和内存使用优化
  • 随意定制的 TLS 提高你的 SSL 评级
  • 支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS
  • 还有在您路由器上使用的 Splice 最佳使用模式建议

2020.12.17

鉴于日益增长群人数和游戏需求, 开启了TG 游戏群open in new tag

2020.12.15

安装脚本 dev 分支open in new tag开启, 持续更新功能中.

2020.12.11 1.1.3open in new tag

  • 完整版本的 REDIRECT 透明代理模式.
  • 软路由 splice 流控模式的优化建议.

2020.12.06 1.1.2open in new tag

  • 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
  • 增强了 API 兼容

2020.12.04

增加 splice 模式

2020.11.27

  • Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
  • 登上了 GitHub Trending
  • Project X 群人数破千,频道订阅数 500+

2020.11.25 1.0.0open in new tag

Xray 的第一个版本.

  • 基于 v2ray-core 修改而来,改动较大
  • 全面增强, 性能卓越, 完全兼容

2020.11.23

project X start

梦开始的时候

- + diff --git a/assets/404.html-3GimCU_9.js b/assets/404.html-ZlBMbAmj.js similarity index 63% rename from assets/404.html-3GimCU_9.js rename to assets/404.html-ZlBMbAmj.js index bfdeed9f12..59f143203a 100644 --- a/assets/404.html-3GimCU_9.js +++ b/assets/404.html-ZlBMbAmj.js @@ -1 +1 @@ -import{_ as e,o as c,c as t}from"./app-PDrbPfzp.js";const _={};function o(r,n){return c(),t("div")}const a=e(_,[["render",o],["__file","404.html.vue"]]);export{a as default}; +import{_ as e,o as c,c as t}from"./app-UOvWaKji.js";const _={};function o(r,n){return c(),t("div")}const a=e(_,[["render",o],["__file","404.html.vue"]]);export{a as default}; diff --git a/assets/Mermaid-AwfEy8fz.js b/assets/Mermaid-IzGpoWNz.js similarity index 89% rename from assets/Mermaid-AwfEy8fz.js rename to assets/Mermaid-IzGpoWNz.js index c219d4ec87..7b8a94513a 100644 --- a/assets/Mermaid-AwfEy8fz.js +++ b/assets/Mermaid-IzGpoWNz.js @@ -1,7 +1,7 @@ -import{u as y,g as M,f as S,h as m,i as v,j as _,k as h,l as g,m as E,n as O,t as f,p as D,q as H,_ as L,o as R,c as T}from"./app-PDrbPfzp.js";function $(e){return M()?(S(e),!0):!1}function w(e){return typeof e=="function"?e():y(e)}const A=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const C=e=>e!=null;function I(e){var t;const o=w(e);return(t=o==null?void 0:o.$el)!=null?t:o}const W=A?window:void 0;function q(){const e=_(!1),t=g();return t&&h(()=>{e.value=!0},t),e}function x(e){const t=q();return m(()=>(t.value,!!e()))}function B(e,t,o={}){const{window:a=W,...r}=o;let n;const u=x(()=>a&&"MutationObserver"in a),s=()=>{n&&(n.disconnect(),n=void 0)},d=m(()=>{const i=w(e),c=(Array.isArray(i)?i:[i]).map(I).filter(C);return new Set(c)}),b=v(()=>d.value,i=>{s(),u.value&&a&&i.size&&(n=new MutationObserver(t),i.forEach(c=>n.observe(c,r)))},{immediate:!0,flush:"post"}),k=()=>n==null?void 0:n.takeRecords(),l=()=>{s(),b()};return $(l),{isSupported:u,stop:l,takeRecords:k}}const p=()=>{const e=document.documentElement;return e.classList.contains("dark")||e.getAttribute("data-theme")==="dark"},G=E({name:"Mermaid",props:{id:{type:String,required:!0},code:{type:String,required:!0}},setup(e){const t=O({innerHtml:""}),o=f(e,"id"),a=f(e,"code"),r=_(!1),n=async()=>{const u=await H(()=>import("./mermaid.core-95b3ca__.js").then(s=>s.b9),__vite__mapDeps([0,1]));u.default.initialize({theme:r.value?"dark":"default",startOnLoad:!1}),u.default.render(o.value,decodeURI(a.value)).then(({svg:s,bindFunctions:d})=>{t.innerHtml=s})};return h(()=>{r.value=p(),D(n)}),typeof document<"u"&&B(document.documentElement,()=>{r.value=p()},{attributeFilter:["class","data-theme"],attributes:!0}),v(r,()=>n()),{tag:o,payload:t}}}),z=["innerHTML"];function F(e,t,o,a,r,n){return R(),T("div",{innerHTML:e.payload.innerHtml},null,8,z)}const V=L(G,[["render",F],["__file","Mermaid.vue"]]);export{V as default}; +import{u as y,g as M,f as S,h as m,i as v,j as _,k as h,l as g,m as E,n as O,t as f,p as D,q as H,_ as L,o as R,c as T}from"./app-UOvWaKji.js";function $(e){return M()?(S(e),!0):!1}function w(e){return typeof e=="function"?e():y(e)}const A=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const C=e=>e!=null;function I(e){var t;const o=w(e);return(t=o==null?void 0:o.$el)!=null?t:o}const W=A?window:void 0;function q(){const e=_(!1),t=g();return t&&h(()=>{e.value=!0},t),e}function x(e){const t=q();return m(()=>(t.value,!!e()))}function B(e,t,o={}){const{window:a=W,...r}=o;let n;const u=x(()=>a&&"MutationObserver"in a),s=()=>{n&&(n.disconnect(),n=void 0)},d=m(()=>{const i=w(e),c=(Array.isArray(i)?i:[i]).map(I).filter(C);return new Set(c)}),b=v(()=>d.value,i=>{s(),u.value&&a&&i.size&&(n=new MutationObserver(t),i.forEach(c=>n.observe(c,r)))},{immediate:!0,flush:"post"}),k=()=>n==null?void 0:n.takeRecords(),l=()=>{s(),b()};return $(l),{isSupported:u,stop:l,takeRecords:k}}const p=()=>{const e=document.documentElement;return e.classList.contains("dark")||e.getAttribute("data-theme")==="dark"},G=E({name:"Mermaid",props:{id:{type:String,required:!0},code:{type:String,required:!0}},setup(e){const t=O({innerHtml:""}),o=f(e,"id"),a=f(e,"code"),r=_(!1),n=async()=>{const u=await H(()=>import("./mermaid.core-Q3WVcjPF.js").then(s=>s.b9),__vite__mapDeps([0,1]));u.default.initialize({theme:r.value?"dark":"default",startOnLoad:!1}),u.default.render(o.value,decodeURI(a.value)).then(({svg:s,bindFunctions:d})=>{t.innerHtml=s})};return h(()=>{r.value=p(),D(n)}),typeof document<"u"&&B(document.documentElement,()=>{r.value=p()},{attributeFilter:["class","data-theme"],attributes:!0}),v(r,()=>n()),{tag:o,payload:t}}}),z=["innerHTML"];function F(e,t,o,a,r,n){return R(),T("div",{innerHTML:e.payload.innerHtml},null,8,z)}const V=L(G,[["render",F],["__file","Mermaid.vue"]]);export{V as default}; function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { - __vite__mapDeps.viteFileDeps = ["assets/mermaid.core-95b3ca__.js","assets/app-PDrbPfzp.js"] + __vite__mapDeps.viteFileDeps = ["assets/mermaid.core-Q3WVcjPF.js","assets/app-UOvWaKji.js"] } return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) } diff --git a/assets/Tab-zEFzyfPv.js b/assets/Tab-7BB5fVJi.js similarity index 89% rename from assets/Tab-zEFzyfPv.js rename to assets/Tab-7BB5fVJi.js index 0a9f5ffd94..29a39fb45b 100644 --- a/assets/Tab-zEFzyfPv.js +++ b/assets/Tab-7BB5fVJi.js @@ -1 +1 @@ -import{m as e,_ as a,o as s,c as l,s as r}from"./app-PDrbPfzp.js";const i=e({props:{title:{type:String}},data(){return{tabID:this.title}},mounted(){this.tabID="tab-"+Math.random().toString(36).substring(2),this.$parent.$data.children.push({id:this.tabID,title:this.title})},computed:{labelID(){return this.tabID+"-label"}}}),o=["id","aria-labelledby"];function n(t,d,b,p,c,u){return s(),l("div",{class:"tab-pane fade",id:t.tabID,role:"tabpanel","aria-labelledby":t.labelID},[r(t.$slots,"default",{},void 0,!0)],8,o)}const h=a(i,[["render",n],["__scopeId","data-v-88372a6c"],["__file","Tab.vue"]]);export{h as default}; +import{m as e,_ as a,o as s,c as l,s as r}from"./app-UOvWaKji.js";const i=e({props:{title:{type:String}},data(){return{tabID:this.title}},mounted(){this.tabID="tab-"+Math.random().toString(36).substring(2),this.$parent.$data.children.push({id:this.tabID,title:this.title})},computed:{labelID(){return this.tabID+"-label"}}}),o=["id","aria-labelledby"];function n(t,d,b,p,c,u){return s(),l("div",{class:"tab-pane fade",id:t.tabID,role:"tabpanel","aria-labelledby":t.labelID},[r(t.$slots,"default",{},void 0,!0)],8,o)}const h=a(i,[["render",n],["__scopeId","data-v-88372a6c"],["__file","Tab.vue"]]);export{h as default}; diff --git a/assets/Tabs-coEt0t4G.js b/assets/Tabs--CmfscRM.js similarity index 95% rename from assets/Tabs-coEt0t4G.js rename to assets/Tabs--CmfscRM.js index b5d59b91f5..4936e24230 100644 --- a/assets/Tabs-coEt0t4G.js +++ b/assets/Tabs--CmfscRM.js @@ -1,4 +1,4 @@ -import{m as i,q as r,_ as d,o as a,c as n,a as s,F as l,v as c,s as u,x as _}from"./app-PDrbPfzp.js";const p=i({props:{title:{type:String}},data(){return{children:[]}},beforeMount(){this.children=[]},mounted(){this.$nextTick(async function(){const t=await r(()=>import("./bootstrap.esm-azflQEBN.js"),__vite__mapDeps([]));let o=document.getElementById(this.children[0].id+"-label");new t.Tab(o).show()})},computed:{tag:function(){return"tabs-"+this.title},contentTag:function(){return"tabs-"+this.title+"-content"}}}),b={class:"container"},h=["id"],f=["id","aria-controls","data-bs-target"],g=["id"];function v(t,o,m,T,$,y){return a(),n("div",b,[s("nav",null,[s("div",{id:t.tag,class:"nav nav-pills",role:"tablist"},[(a(!0),n(l,null,c(t.children,e=>(a(),n("button",{id:e.id+"-label","aria-controls":e.id,"data-bs-target":"#"+e.id,"aria-selected":"false",class:"nav-link","data-bs-toggle":"tab",role:"tab",type:"button"},_(e.title),9,f))),256))],8,h)]),s("div",{id:t.contentTag,class:"tab-content"},[u(t.$slots,"default",{},void 0,!0)],8,g)])}const k=d(p,[["render",v],["__scopeId","data-v-b533ae34"],["__file","Tabs.vue"]]);export{k as default}; +import{m as i,q as r,_ as d,o as a,c as n,a as s,F as l,v as c,s as u,x as _}from"./app-UOvWaKji.js";const p=i({props:{title:{type:String}},data(){return{children:[]}},beforeMount(){this.children=[]},mounted(){this.$nextTick(async function(){const t=await r(()=>import("./bootstrap.esm-azflQEBN.js"),__vite__mapDeps([]));let o=document.getElementById(this.children[0].id+"-label");new t.Tab(o).show()})},computed:{tag:function(){return"tabs-"+this.title},contentTag:function(){return"tabs-"+this.title+"-content"}}}),b={class:"container"},h=["id"],f=["id","aria-controls","data-bs-target"],g=["id"];function v(t,o,m,T,$,y){return a(),n("div",b,[s("nav",null,[s("div",{id:t.tag,class:"nav nav-pills",role:"tablist"},[(a(!0),n(l,null,c(t.children,e=>(a(),n("button",{id:e.id+"-label","aria-controls":e.id,"data-bs-target":"#"+e.id,"aria-selected":"false",class:"nav-link","data-bs-toggle":"tab",role:"tab",type:"button"},_(e.title),9,f))),256))],8,h)]),s("div",{id:t.contentTag,class:"tab-content"},[u(t.$slots,"default",{},void 0,!0)],8,g)])}const k=d(p,[["render",v],["__scopeId","data-v-b533ae34"],["__file","Tabs.vue"]]);export{k as default}; function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { __vite__mapDeps.viteFileDeps = [] diff --git a/assets/api.html-Bpdd1mqW.js b/assets/api.html-n2welLJa.js similarity index 99% rename from assets/api.html-Bpdd1mqW.js rename to assets/api.html-n2welLJa.js index 83a83112a0..8a13686ca4 100644 --- a/assets/api.html-Bpdd1mqW.js +++ b/assets/api.html-n2welLJa.js @@ -1,4 +1,4 @@ -import{_ as c,r as o,o as r,c as l,a as s,b as n,d as a,w as p,e as i}from"./app-PDrbPfzp.js";const u={},d=s("h1",{id:"api-接口",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#api-接口"},[s("span",null,"API 接口")])],-1),v={href:"https://grpc.io/",target:"_blank",rel:"noopener noreferrer"},k=i(`

请参考本节中的 相关配置

注意

大多数用户并不会用到此 API,新手可以直接忽略这一项。

ApiObject

ApiObject 对应配置文件的 api 项。

{
+import{_ as c,r as o,o as r,c as l,a as s,b as n,d as a,w as p,e as i}from"./app-UOvWaKji.js";const u={},d=s("h1",{id:"api-接口",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#api-接口"},[s("span",null,"API 接口")])],-1),v={href:"https://grpc.io/",target:"_blank",rel:"noopener noreferrer"},k=i(`

请参考本节中的 相关配置

注意

大多数用户并不会用到此 API,新手可以直接忽略这一项。

ApiObject

ApiObject 对应配置文件的 api 项。

{
   "api": {
     "tag": "api",
     "services": ["HandlerService", "LoggerService", "StatsService"]
diff --git a/assets/api.html-ZyK7et4F.js b/assets/api.html-obbK2QQ5.js
similarity index 99%
rename from assets/api.html-ZyK7et4F.js
rename to assets/api.html-obbK2QQ5.js
index ebf45710dd..94fb34216c 100644
--- a/assets/api.html-ZyK7et4F.js
+++ b/assets/api.html-obbK2QQ5.js
@@ -1,4 +1,4 @@
-import{_ as r,r as o,o as c,c as l,a,b as n,d as s,w as i,e as p}from"./app-PDrbPfzp.js";const u={},d=a("h1",{id:"api-interface",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#api-interface"},[a("span",null,"API Interface")])],-1),v={href:"https://grpc.io/",target:"_blank",rel:"noopener noreferrer"},h=p(`

Please refer to the related configuration in this section.

Warning

Most users do not need to use this API. Novices can ignore this item directly.

ApiObject

ApiObject corresponds to the api item in the configuration file.

{
+import{_ as r,r as o,o as c,c as l,a,b as n,d as s,w as i,e as p}from"./app-UOvWaKji.js";const u={},d=a("h1",{id:"api-interface",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#api-interface"},[a("span",null,"API Interface")])],-1),v={href:"https://grpc.io/",target:"_blank",rel:"noopener noreferrer"},h=p(`

Please refer to the related configuration in this section.

Warning

Most users do not need to use this API. Novices can ignore this item directly.

ApiObject

ApiObject corresponds to the api item in the configuration file.

{
   "api": {
     "tag": "api",
     "services": ["HandlerService", "LoggerService", "StatsService"]
diff --git a/assets/app-PDrbPfzp.js b/assets/app-UOvWaKji.js
similarity index 54%
rename from assets/app-PDrbPfzp.js
rename to assets/app-UOvWaKji.js
index 18d63040ee..94aabdd814 100644
--- a/assets/app-PDrbPfzp.js
+++ b/assets/app-UOvWaKji.js
@@ -1,4 +1,4 @@
-function _i(e,t){const l=Object.create(null),n=e.split(",");for(let i=0;i!!l[i.toLowerCase()]:i=>!!l[i]}const xe={},nl=[],dt=()=>{},Qs=()=>!1,Hl=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),bi=e=>e.startsWith("onUpdate:"),De=Object.assign,ki=(e,t)=>{const l=e.indexOf(t);l>-1&&e.splice(l,1)},Js=Object.prototype.hasOwnProperty,de=(e,t)=>Js.call(e,t),le=Array.isArray,il=e=>Pn(e)==="[object Map]",vo=e=>Pn(e)==="[object Set]",oe=e=>typeof e=="function",Ae=e=>typeof e=="string",ml=e=>typeof e=="symbol",Ee=e=>e!==null&&typeof e=="object",po=e=>(Ee(e)||oe(e))&&oe(e.then)&&oe(e.catch),mo=Object.prototype.toString,Pn=e=>mo.call(e),Zs=e=>Pn(e).slice(8,-1),go=e=>Pn(e)==="[object Object]",yi=e=>Ae(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,wl=_i(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),wn=e=>{const t=Object.create(null);return l=>t[l]||(t[l]=e(l))},ea=/-(\w)/g,ht=wn(e=>e.replace(ea,(t,l)=>l?l.toUpperCase():"")),ta=/\B([A-Z])/g,Qt=wn(e=>e.replace(ta,"-$1").toLowerCase()),On=wn(e=>e.charAt(0).toUpperCase()+e.slice(1)),Hn=wn(e=>e?`on${On(e)}`:""),Yt=(e,t)=>!Object.is(e,t),$n=(e,t)=>{for(let l=0;l{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:l})},la=e=>{const t=parseFloat(e);return isNaN(t)?e:t},na=e=>{const t=Ae(e)?Number(e):NaN;return isNaN(t)?e:t};let Zi;const li=()=>Zi||(Zi=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function $l(e){if(le(e)){const t={};for(let l=0;l{if(l){const n=l.split(ra);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Ke(e){let t="";if(Ae(e))t=e;else if(le(e))for(let l=0;lAe(e)?e:e==null?"":le(e)||Ee(e)&&(e.toString===mo||!oe(e.toString))?JSON.stringify(e,bo,2):String(e),bo=(e,t)=>t&&t.__v_isRef?bo(e,t.value):il(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((l,[n,i],r)=>(l[Bn(n,r)+" =>"]=i,l),{})}:vo(t)?{[`Set(${t.size})`]:[...t.values()].map(l=>Bn(l))}:ml(t)?Bn(t):Ee(t)&&!le(t)&&!go(t)?String(t):t,Bn=(e,t="")=>{var l;return ml(e)?`Symbol(${(l=e.description)!=null?l:t})`:e};let Ge;class ua{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Ge,!t&&Ge&&(this.index=(Ge.scopes||(Ge.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const l=Ge;try{return Ge=this,t()}finally{Ge=l}}}on(){Ge=this}off(){Ge=this.parent}stop(t){if(this._active){let l,n;for(l=0,n=this.effects.length;l{const t=new Set(e);return t.w=0,t.n=0,t},yo=e=>(e.w&jt)>0,Eo=e=>(e.n&jt)>0,fa=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let l=0;for(let n=0;n{(d==="length"||!ml(d)&&d>=a)&&s.push(c)})}else switch(l!==void 0&&s.push(o.get(l)),t){case"add":le(e)?yi(l)&&s.push(o.get("length")):(s.push(o.get(qt)),il(e)&&s.push(o.get(ii)));break;case"delete":le(e)||(s.push(o.get(qt)),il(e)&&s.push(o.get(ii)));break;case"set":il(e)&&s.push(o.get(qt));break}if(s.length===1)s[0]&&ri(s[0]);else{const a=[];for(const c of s)c&&a.push(...c);ri(Ei(a))}}function ri(e,t){const l=le(e)?e:[...e];for(const n of l)n.computed&&tr(n);for(const n of l)n.computed||tr(n)}function tr(e,t){(e!==nt||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}function pa(e,t){var l;return(l=vn.get(e))==null?void 0:l.get(t)}const ma=_i("__proto__,__v_isRef,__isVue"),To=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(ml)),lr=ga();function ga(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...l){const n=ve(this);for(let r=0,o=this.length;r{e[t]=function(...l){gl();const n=ve(this)[t].apply(this,l);return _l(),n}}),e}function _a(e){const t=ve(this);return qe(t,"has",e),t.hasOwnProperty(e)}class Po{constructor(t=!1,l=!1){this._isReadonly=t,this._shallow=l}get(t,l,n){const i=this._isReadonly,r=this._shallow;if(l==="__v_isReactive")return!i;if(l==="__v_isReadonly")return i;if(l==="__v_isShallow")return r;if(l==="__v_raw")return n===(i?r?Ia:Ro:r?Ao:Oo).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(n)?t:void 0;const o=le(t);if(!i){if(o&&de(lr,l))return Reflect.get(lr,l,n);if(l==="hasOwnProperty")return _a}const s=Reflect.get(t,l,n);return(ml(l)?To.has(l):ma(l))||(i||qe(t,"get",l),r)?s:Me(s)?o&&yi(l)?s:s.value:Ee(s)?i?Rn(s):Bl(s):s}}class wo extends Po{constructor(t=!1){super(!1,t)}set(t,l,n,i){let r=t[l];if(!this._shallow){const a=cl(r);if(!pn(n)&&!cl(n)&&(r=ve(r),n=ve(n)),!le(t)&&Me(r)&&!Me(n))return a?!1:(r.value=n,!0)}const o=le(t)&&yi(l)?Number(l)e,An=e=>Reflect.getPrototypeOf(e);function Yl(e,t,l=!1,n=!1){e=e.__v_raw;const i=ve(e),r=ve(t);l||(Yt(t,r)&&qe(i,"get",t),qe(i,"get",r));const{has:o}=An(i),s=n?Li:l?wi:Sl;if(o.call(i,t))return s(e.get(t));if(o.call(i,r))return s(e.get(r));e!==i&&e.get(t)}function Ql(e,t=!1){const l=this.__v_raw,n=ve(l),i=ve(e);return t||(Yt(e,i)&&qe(n,"has",e),qe(n,"has",i)),e===i?l.has(e):l.has(e)||l.has(i)}function Jl(e,t=!1){return e=e.__v_raw,!t&&qe(ve(e),"iterate",qt),Reflect.get(e,"size",e)}function nr(e){e=ve(e);const t=ve(this);return An(t).has.call(t,e)||(t.add(e),gt(t,"add",e,e)),this}function ir(e,t){t=ve(t);const l=ve(this),{has:n,get:i}=An(l);let r=n.call(l,e);r||(e=ve(e),r=n.call(l,e));const o=i.call(l,e);return l.set(e,t),r?Yt(t,o)&>(l,"set",e,t):gt(l,"add",e,t),this}function rr(e){const t=ve(this),{has:l,get:n}=An(t);let i=l.call(t,e);i||(e=ve(e),i=l.call(t,e)),n&&n.call(t,e);const r=t.delete(e);return i&>(t,"delete",e,void 0),r}function or(){const e=ve(this),t=e.size!==0,l=e.clear();return t&>(e,"clear",void 0,void 0),l}function Zl(e,t){return function(n,i){const r=this,o=r.__v_raw,s=ve(o),a=t?Li:e?wi:Sl;return!e&&qe(s,"iterate",qt),o.forEach((c,d)=>n.call(i,a(c),a(d),r))}}function en(e,t,l){return function(...n){const i=this.__v_raw,r=ve(i),o=il(r),s=e==="entries"||e===Symbol.iterator&&o,a=e==="keys"&&o,c=i[e](...n),d=l?Li:t?wi:Sl;return!t&&qe(r,"iterate",a?ii:qt),{next(){const{value:h,done:f}=c.next();return f?{value:h,done:f}:{value:s?[d(h[0]),d(h[1])]:d(h),done:f}},[Symbol.iterator](){return this}}}}function Tt(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function xa(){const e={get(r){return Yl(this,r)},get size(){return Jl(this)},has:Ql,add:nr,set:ir,delete:rr,clear:or,forEach:Zl(!1,!1)},t={get(r){return Yl(this,r,!1,!0)},get size(){return Jl(this)},has:Ql,add:nr,set:ir,delete:rr,clear:or,forEach:Zl(!1,!0)},l={get(r){return Yl(this,r,!0)},get size(){return Jl(this,!0)},has(r){return Ql.call(this,r,!0)},add:Tt("add"),set:Tt("set"),delete:Tt("delete"),clear:Tt("clear"),forEach:Zl(!0,!1)},n={get(r){return Yl(this,r,!0,!0)},get size(){return Jl(this,!0)},has(r){return Ql.call(this,r,!0)},add:Tt("add"),set:Tt("set"),delete:Tt("delete"),clear:Tt("clear"),forEach:Zl(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(r=>{e[r]=en(r,!1,!1),l[r]=en(r,!0,!1),t[r]=en(r,!1,!0),n[r]=en(r,!0,!0)}),[e,l,t,n]}const[La,Ta,Pa,wa]=xa();function Ti(e,t){const l=t?e?wa:Pa:e?Ta:La;return(n,i,r)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(de(l,i)&&i in n?l:n,i,r)}const Oa={get:Ti(!1,!1)},Aa={get:Ti(!1,!0)},Ra={get:Ti(!0,!1)},Oo=new WeakMap,Ao=new WeakMap,Ro=new WeakMap,Ia=new WeakMap;function Da(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Sa(e){return e.__v_skip||!Object.isExtensible(e)?0:Da(Zs(e))}function Bl(e){return cl(e)?e:Pi(e,!1,ka,Oa,Oo)}function Io(e){return Pi(e,!1,Ea,Aa,Ao)}function Rn(e){return Pi(e,!0,ya,Ra,Ro)}function Pi(e,t,l,n,i){if(!Ee(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const r=i.get(e);if(r)return r;const o=Sa(e);if(o===0)return e;const s=new Proxy(e,o===2?n:l);return i.set(e,s),s}function rl(e){return cl(e)?rl(e.__v_raw):!!(e&&e.__v_isReactive)}function cl(e){return!!(e&&e.__v_isReadonly)}function pn(e){return!!(e&&e.__v_isShallow)}function Do(e){return rl(e)||cl(e)}function ve(e){const t=e&&e.__v_raw;return t?ve(t):e}function So(e){return fn(e,"__v_skip",!0),e}const Sl=e=>Ee(e)?Bl(e):e,wi=e=>Ee(e)?Rn(e):e;function Oi(e){Dt&&nt&&(e=ve(e),Lo(e.dep||(e.dep=Ei())))}function Ai(e,t){e=ve(e);const l=e.dep;l&&ri(l)}function Me(e){return!!(e&&e.__v_isRef===!0)}function ge(e){return Co(e,!1)}function jo(e){return Co(e,!0)}function Co(e,t){return Me(e)?e:new ja(e,t)}class ja{constructor(t,l){this.__v_isShallow=l,this.dep=void 0,this.__v_isRef=!0,this._rawValue=l?t:ve(t),this._value=l?t:Sl(t)}get value(){return Oi(this),this._value}set value(t){const l=this.__v_isShallow||pn(t)||cl(t);t=l?t:ve(t),Yt(t,this._rawValue)&&(this._rawValue=t,this._value=l?t:Sl(t),Ai(this))}}function te(e){return Me(e)?e.value:e}const Ca={get:(e,t,l)=>te(Reflect.get(e,t,l)),set:(e,t,l,n)=>{const i=e[t];return Me(i)&&!Me(l)?(i.value=l,!0):Reflect.set(e,t,l,n)}};function Vo(e){return rl(e)?e:new Proxy(e,Ca)}class Va{constructor(t){this.dep=void 0,this.__v_isRef=!0;const{get:l,set:n}=t(()=>Oi(this),()=>Ai(this));this._get=l,this._set=n}get value(){return this._get()}set value(t){this._set(t)}}function Fa(e){return new Va(e)}function In(e){const t=le(e)?new Array(e.length):{};for(const l in e)t[l]=Fo(e,l);return t}class Na{constructor(t,l,n){this._object=t,this._key=l,this._defaultValue=n,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return pa(ve(this._object),this._key)}}class Ma{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function Sp(e,t,l){return Me(e)?e:oe(e)?new Ma(e):Ee(e)&&arguments.length>1?Fo(e,t,l):ge(e)}function Fo(e,t,l){const n=e[t];return Me(n)?n:new Na(e,t,l)}class Ha{constructor(t,l,n,i){this._setter=l,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new xi(t,()=>{this._dirty||(this._dirty=!0,Ai(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!i,this.__v_isReadonly=n}get value(){const t=ve(this);return Oi(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function $a(e,t,l=!1){let n,i;const r=oe(e);return r?(n=e,i=dt):(n=e.get,i=e.set),new Ha(n,i,r||!i,l)}function St(e,t,l,n){let i;try{i=n?e(...n):e()}catch(r){zl(r,t,l)}return i}function et(e,t,l,n){if(oe(e)){const r=St(e,t,l,n);return r&&po(r)&&r.catch(o=>{zl(o,t,l)}),r}const i=[];for(let r=0;r>>1,i=$e[n],r=Cl(i);rut&&$e.splice(t,1)}function Ua(e){le(e)?ol.push(...e):(!mt||!mt.includes(e,e.allowRecurse?zt+1:zt))&&ol.push(e),Mo()}function sr(e,t,l=jl?ut+1:0){for(;l<$e.length;l++){const n=$e[l];if(n&&n.pre){if(e&&n.id!==e.uid)continue;$e.splice(l,1),l--,n()}}}function mn(e){if(ol.length){const t=[...new Set(ol)];if(ol.length=0,mt){mt.push(...t);return}for(mt=t,mt.sort((l,n)=>Cl(l)-Cl(n)),zt=0;zte.id==null?1/0:e.id,Ka=(e,t)=>{const l=Cl(e)-Cl(t);if(l===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return l};function Ho(e){oi=!1,jl=!0,$e.sort(Ka);try{for(ut=0;ut<$e.length;ut++){const t=$e[ut];t&&t.active!==!1&&St(t,null,14)}}finally{ut=0,$e.length=0,mn(),jl=!1,Ri=null,($e.length||ol.length)&&Ho()}}function qa(e,t,...l){if(e.isUnmounted)return;const n=e.vnode.props||xe;let i=l;const r=t.startsWith("update:"),o=r&&t.slice(7);if(o&&o in n){const d=`${o==="modelValue"?"model":o}Modifiers`,{number:h,trim:f}=n[d]||xe;f&&(i=l.map(m=>Ae(m)?m.trim():m)),h&&(i=l.map(la))}let s,a=n[s=Hn(t)]||n[s=Hn(ht(t))];!a&&r&&(a=n[s=Hn(Qt(t))]),a&&et(a,e,6,i);const c=n[s+"Once"];if(c){if(!e.emitted)e.emitted={};else if(e.emitted[s])return;e.emitted[s]=!0,et(c,e,6,i)}}function $o(e,t,l=!1){const n=t.emitsCache,i=n.get(e);if(i!==void 0)return i;const r=e.emits;let o={},s=!1;if(!oe(e)){const a=c=>{const d=$o(c,t,!0);d&&(s=!0,De(o,d))};!l&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!r&&!s?(Ee(e)&&n.set(e,null),null):(le(r)?r.forEach(a=>o[a]=null):De(o,r),Ee(e)&&n.set(e,o),o)}function Sn(e,t){return!e||!Hl(t)?!1:(t=t.slice(2).replace(/Once$/,""),de(e,t[0].toLowerCase()+t.slice(1))||de(e,Qt(t))||de(e,t))}let Fe=null,Bo=null;function gn(e){const t=Fe;return Fe=e,Bo=e&&e.type.__scopeId||null,t}function Ve(e,t=Fe,l){if(!t||e._n)return e;const n=(...i)=>{n._d&&br(-1);const r=gn(t);let o;try{o=e(...i)}finally{gn(r),n._d&&br(1)}return o};return n._n=!0,n._c=!0,n._d=!0,n}function zn(e){const{type:t,vnode:l,proxy:n,withProxy:i,props:r,propsOptions:[o],slots:s,attrs:a,emit:c,render:d,renderCache:h,data:f,setupState:m,ctx:k,inheritAttrs:T}=e;let w,I;const R=gn(e);try{if(l.shapeFlag&4){const E=i||n,F=E;w=lt(d.call(F,E,h,r,m,f,k)),I=a}else{const E=t;w=lt(E.length>1?E(r,{attrs:a,slots:s,emit:c}):E(r,null)),I=t.props?a:Xa(a)}}catch(E){Rl.length=0,zl(E,e,1),w=ie(Qe)}let b=w;if(I&&T!==!1){const E=Object.keys(I),{shapeFlag:F}=b;E.length&&F&7&&(o&&E.some(bi)&&(I=Ga(I,o)),b=Vt(b,I))}return l.dirs&&(b=Vt(b),b.dirs=b.dirs?b.dirs.concat(l.dirs):l.dirs),l.transition&&(b.transition=l.transition),w=b,gn(R),w}const Xa=e=>{let t;for(const l in e)(l==="class"||l==="style"||Hl(l))&&((t||(t={}))[l]=e[l]);return t},Ga=(e,t)=>{const l={};for(const n in e)(!bi(n)||!(n.slice(9)in t))&&(l[n]=e[n]);return l};function Ya(e,t,l){const{props:n,children:i,component:r}=e,{props:o,children:s,patchFlag:a}=t,c=r.emitsOptions;if(t.dirs||t.transition)return!0;if(l&&a>=0){if(a&1024)return!0;if(a&16)return n?ar(n,o,c):!!o;if(a&8){const d=t.dynamicProps;for(let h=0;he.__isSuspense;function Wo(e,t){t&&t.pendingBranch?le(e)?t.effects.push(...e):t.effects.push(e):Ua(e)}function tc(e,t){return Ii(e,null,t)}const tn={};function Ye(e,t,l){return Ii(e,t,l)}function Ii(e,t,{immediate:l,deep:n,flush:i,onTrack:r,onTrigger:o}=xe){var s;const a=ko()===((s=Re)==null?void 0:s.scope)?Re:null;let c,d=!1,h=!1;if(Me(e)?(c=()=>e.value,d=pn(e)):rl(e)?(c=()=>e,n=!0):le(e)?(h=!0,d=e.some(E=>rl(E)||pn(E)),c=()=>e.map(E=>{if(Me(E))return E.value;if(rl(E))return Kt(E);if(oe(E))return St(E,a,2)})):oe(e)?t?c=()=>St(e,a,2):c=()=>{if(!(a&&a.isUnmounted))return f&&f(),et(e,a,3,[m])}:c=dt,t&&n){const E=c;c=()=>Kt(E())}let f,m=E=>{f=R.onStop=()=>{St(E,a,4),f=R.onStop=void 0}},k;if(hl)if(m=dt,t?l&&et(t,a,3,[c(),h?[]:void 0,m]):c(),i==="sync"){const E=Xc();k=E.__watcherHandles||(E.__watcherHandles=[])}else return dt;let T=h?new Array(e.length).fill(tn):tn;const w=()=>{if(R.active)if(t){const E=R.run();(n||d||(h?E.some((F,G)=>Yt(F,T[G])):Yt(E,T)))&&(f&&f(),et(t,a,3,[E,T===tn?void 0:h&&T[0]===tn?[]:T,m]),T=E)}else R.run()};w.allowRecurse=!!t;let I;i==="sync"?I=w:i==="post"?I=()=>Ue(w,a&&a.suspense):(w.pre=!0,a&&(w.id=a.uid),I=()=>Dn(w));const R=new xi(c,I);t?l?w():T=R.run():i==="post"?Ue(R.run.bind(R),a&&a.suspense):R.run();const b=()=>{R.stop(),a&&a.scope&&ki(a.scope.effects,R)};return k&&k.push(b),b}function lc(e,t,l){const n=this.proxy,i=Ae(e)?e.includes(".")?Uo(n,e):()=>n[e]:e.bind(n,n);let r;oe(t)?r=t:(r=t.handler,l=t);const o=Re;dl(this);const s=Ii(i,r.bind(n),l);return o?dl(o):Gt(),s}function Uo(e,t){const l=t.split(".");return()=>{let n=e;for(let i=0;i{Kt(l,t)});else if(go(e))for(const l in e)Kt(e[l],t);return e}function _n(e,t){const l=Fe;if(l===null)return e;const n=Fn(l)||l.proxy,i=e.dirs||(e.dirs=[]);for(let r=0;r{e.isMounted=!0}),Kl(()=>{e.isUnmounting=!0}),e}const Je=[Function,Array],Ko={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Je,onEnter:Je,onAfterEnter:Je,onEnterCancelled:Je,onBeforeLeave:Je,onLeave:Je,onAfterLeave:Je,onLeaveCancelled:Je,onBeforeAppear:Je,onAppear:Je,onAfterAppear:Je,onAppearCancelled:Je},ic={name:"BaseTransition",props:Ko,setup(e,{slots:t}){const l=Ci(),n=nc();let i;return()=>{const r=t.default&&Xo(t.default(),!0);if(!r||!r.length)return;let o=r[0];if(r.length>1){for(const T of r)if(T.type!==Qe){o=T;break}}const s=ve(e),{mode:a}=s;if(n.isLeaving)return Wn(o);const c=ur(o);if(!c)return Wn(o);const d=si(c,s,n,l);ai(c,d);const h=l.subTree,f=h&&ur(h);let m=!1;const{getTransitionKey:k}=c.type;if(k){const T=k();i===void 0?i=T:T!==i&&(i=T,m=!0)}if(f&&f.type!==Qe&&(!Wt(c,f)||m)){const T=si(f,s,n,l);if(ai(f,T),a==="out-in")return n.isLeaving=!0,T.afterLeave=()=>{n.isLeaving=!1,l.update.active!==!1&&l.update()},Wn(o);a==="in-out"&&c.type!==Qe&&(T.delayLeave=(w,I,R)=>{const b=qo(n,f);b[String(f.key)]=f,w[At]=()=>{I(),w[At]=void 0,delete d.delayedLeave},d.delayedLeave=R})}return o}}},rc=ic;function qo(e,t){const{leavingVNodes:l}=e;let n=l.get(t.type);return n||(n=Object.create(null),l.set(t.type,n)),n}function si(e,t,l,n){const{appear:i,mode:r,persisted:o=!1,onBeforeEnter:s,onEnter:a,onAfterEnter:c,onEnterCancelled:d,onBeforeLeave:h,onLeave:f,onAfterLeave:m,onLeaveCancelled:k,onBeforeAppear:T,onAppear:w,onAfterAppear:I,onAppearCancelled:R}=t,b=String(e.key),E=qo(l,e),F=(y,q)=>{y&&et(y,n,9,q)},G=(y,q)=>{const O=q[1];F(y,q),le(y)?y.every(W=>W.length<=1)&&O():y.length<=1&&O()},N={mode:r,persisted:o,beforeEnter(y){let q=s;if(!l.isMounted)if(i)q=T||s;else return;y[At]&&y[At](!0);const O=E[b];O&&Wt(e,O)&&O.el[At]&&O.el[At](),F(q,[y])},enter(y){let q=a,O=c,W=d;if(!l.isMounted)if(i)q=w||a,O=I||c,W=R||d;else return;let x=!1;const C=y[ln]=ne=>{x||(x=!0,ne?F(W,[y]):F(O,[y]),N.delayedLeave&&N.delayedLeave(),y[ln]=void 0)};q?G(q,[y,C]):C()},leave(y,q){const O=String(e.key);if(y[ln]&&y[ln](!0),l.isUnmounting)return q();F(h,[y]);let W=!1;const x=y[At]=C=>{W||(W=!0,q(),C?F(k,[y]):F(m,[y]),y[At]=void 0,E[O]===e&&delete E[O])};E[O]=e,f?G(f,[y,x]):x()},clone(y){return si(y,t,l,n)}};return N}function Wn(e){if(Ul(e))return e=Vt(e),e.children=null,e}function ur(e){return Ul(e)?e.children?e.children[0]:void 0:e}function ai(e,t){e.shapeFlag&6&&e.component?ai(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Xo(e,t=!1,l){let n=[],i=0;for(let r=0;r1)for(let r=0;r!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function g(e){oe(e)&&(e={loader:e});const{loader:t,loadingComponent:l,errorComponent:n,delay:i=200,timeout:r,suspensible:o=!0,onError:s}=e;let a=null,c,d=0;const h=()=>(d++,a=null,f()),f=()=>{let m;return a||(m=a=t().catch(k=>{if(k=k instanceof Error?k:new Error(String(k)),s)return new Promise((T,w)=>{s(k,()=>T(h()),()=>w(k),d+1)});throw k}).then(k=>m!==a&&a?a:(k&&(k.__esModule||k[Symbol.toStringTag]==="Module")&&(k=k.default),c=k,k)))};return pe({name:"AsyncComponentWrapper",__asyncLoader:f,get __asyncResolved(){return c},setup(){const m=Re;if(c)return()=>Un(c,m);const k=R=>{a=null,zl(R,m,13,!n)};if(o&&m.suspense||hl)return f().then(R=>()=>Un(R,m)).catch(R=>(k(R),()=>n?ie(n,{error:R}):null));const T=ge(!1),w=ge(),I=ge(!!i);return i&&setTimeout(()=>{I.value=!1},i),r!=null&&setTimeout(()=>{if(!T.value&&!w.value){const R=new Error(`Async component timed out after ${r}ms.`);k(R),w.value=R}},r),f().then(()=>{T.value=!0,m.parent&&Ul(m.parent.vnode)&&Dn(m.parent.update)}).catch(R=>{k(R),w.value=R}),()=>{if(T.value&&c)return Un(c,m);if(w.value&&n)return ie(n,{error:w.value});if(l&&!I.value)return ie(l)}}})}function Un(e,t){const{ref:l,props:n,children:i,ce:r}=t.vnode,o=ie(e,n,i);return o.ref=l,o.ce=r,delete t.vnode.ce,o}const Ul=e=>e.type.__isKeepAlive;function oc(e,t){Go(e,"a",t)}function sc(e,t){Go(e,"da",t)}function Go(e,t,l=Re){const n=e.__wdc||(e.__wdc=()=>{let i=l;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(jn(t,n,l),l){let i=l.parent;for(;i&&i.parent;)Ul(i.parent.vnode)&&ac(n,t,l,i),i=i.parent}}function ac(e,t,l,n){const i=jn(t,e,n,!0);Cn(()=>{ki(n[t],i)},l)}function jn(e,t,l=Re,n=!1){if(l){const i=l[e]||(l[e]=[]),r=t.__weh||(t.__weh=(...o)=>{if(l.isUnmounted)return;gl(),dl(l);const s=et(t,l,e,o);return Gt(),_l(),s});return n?i.unshift(r):i.push(r),r}}const Et=e=>(t,l=Re)=>(!hl||e==="sp")&&jn(e,(...n)=>t(...n),l),cc=Et("bm"),ze=Et("m"),uc=Et("bu"),dc=Et("u"),Kl=Et("bum"),Cn=Et("um"),hc=Et("sp"),fc=Et("rtg"),vc=Et("rtc");function pc(e,t=Re){jn("ec",e,t)}function Ct(e,t,l,n){let i;const r=l&&l[n];if(le(e)||Ae(e)){i=new Array(e.length);for(let o=0,s=e.length;ot(o,s,void 0,r&&r[s]));else{const o=Object.keys(e);i=new Array(o.length);for(let s=0,a=o.length;sEn(t)?!(t.type===Qe||t.type===ye&&!Yo(t.children)):!0)?e:null}const ci=e=>e?as(e)?Fn(e)||e.proxy:ci(e.parent):null,Ol=De(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>ci(e.parent),$root:e=>ci(e.root),$emit:e=>e.emit,$options:e=>Di(e),$forceUpdate:e=>e.f||(e.f=()=>Dn(e.update)),$nextTick:e=>e.n||(e.n=Wl.bind(e.proxy)),$watch:e=>lc.bind(e)}),Kn=(e,t)=>e!==xe&&!e.__isScriptSetup&&de(e,t),mc={get({_:e},t){const{ctx:l,setupState:n,data:i,props:r,accessCache:o,type:s,appContext:a}=e;let c;if(t[0]!=="$"){const m=o[t];if(m!==void 0)switch(m){case 1:return n[t];case 2:return i[t];case 4:return l[t];case 3:return r[t]}else{if(Kn(n,t))return o[t]=1,n[t];if(i!==xe&&de(i,t))return o[t]=2,i[t];if((c=e.propsOptions[0])&&de(c,t))return o[t]=3,r[t];if(l!==xe&&de(l,t))return o[t]=4,l[t];ui&&(o[t]=0)}}const d=Ol[t];let h,f;if(d)return t==="$attrs"&&qe(e,"get",t),d(e);if((h=s.__cssModules)&&(h=h[t]))return h;if(l!==xe&&de(l,t))return o[t]=4,l[t];if(f=a.config.globalProperties,de(f,t))return f[t]},set({_:e},t,l){const{data:n,setupState:i,ctx:r}=e;return Kn(i,t)?(i[t]=l,!0):n!==xe&&de(n,t)?(n[t]=l,!0):de(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(r[t]=l,!0)},has({_:{data:e,setupState:t,accessCache:l,ctx:n,appContext:i,propsOptions:r}},o){let s;return!!l[o]||e!==xe&&de(e,o)||Kn(t,o)||(s=r[0])&&de(s,o)||de(n,o)||de(Ol,o)||de(i.config.globalProperties,o)},defineProperty(e,t,l){return l.get!=null?e._.accessCache[t]=0:de(l,"value")&&this.set(e,t,l.value,null),Reflect.defineProperty(e,t,l)}};function dr(e){return le(e)?e.reduce((t,l)=>(t[l]=null,t),{}):e}let ui=!0;function gc(e){const t=Di(e),l=e.proxy,n=e.ctx;ui=!1,t.beforeCreate&&hr(t.beforeCreate,e,"bc");const{data:i,computed:r,methods:o,watch:s,provide:a,inject:c,created:d,beforeMount:h,mounted:f,beforeUpdate:m,updated:k,activated:T,deactivated:w,beforeDestroy:I,beforeUnmount:R,destroyed:b,unmounted:E,render:F,renderTracked:G,renderTriggered:N,errorCaptured:y,serverPrefetch:q,expose:O,inheritAttrs:W,components:x,directives:C,filters:ne}=t;if(c&&_c(c,n,null),o)for(const Q in o){const K=o[Q];oe(K)&&(n[Q]=K.bind(l))}if(i){const Q=i.call(l,l);Ee(Q)&&(e.data=Bl(Q))}if(ui=!0,r)for(const Q in r){const K=r[Q],Se=oe(K)?K.bind(l,l):oe(K.get)?K.get.bind(l,l):dt,Ce=!oe(K)&&oe(K.set)?K.set.bind(l):dt,We=H({get:Se,set:Ce});Object.defineProperty(n,Q,{enumerable:!0,configurable:!0,get:()=>We.value,set:He=>We.value=He})}if(s)for(const Q in s)Qo(s[Q],n,l,Q);if(a){const Q=oe(a)?a.call(l):a;Reflect.ownKeys(Q).forEach(K=>{Xt(K,Q[K])})}d&&hr(d,e,"c");function j(Q,K){le(K)?K.forEach(Se=>Q(Se.bind(l))):K&&Q(K.bind(l))}if(j(cc,h),j(ze,f),j(uc,m),j(dc,k),j(oc,T),j(sc,w),j(pc,y),j(vc,G),j(fc,N),j(Kl,R),j(Cn,E),j(hc,q),le(O))if(O.length){const Q=e.exposed||(e.exposed={});O.forEach(K=>{Object.defineProperty(Q,K,{get:()=>l[K],set:Se=>l[K]=Se})})}else e.exposed||(e.exposed={});F&&e.render===dt&&(e.render=F),W!=null&&(e.inheritAttrs=W),x&&(e.components=x),C&&(e.directives=C)}function _c(e,t,l=dt){le(e)&&(e=di(e));for(const n in e){const i=e[n];let r;Ee(i)?"default"in i?r=Te(i.from||n,i.default,!0):r=Te(i.from||n):r=Te(i),Me(r)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>r.value,set:o=>r.value=o}):t[n]=r}}function hr(e,t,l){et(le(e)?e.map(n=>n.bind(t.proxy)):e.bind(t.proxy),t,l)}function Qo(e,t,l,n){const i=n.includes(".")?Uo(l,n):()=>l[n];if(Ae(e)){const r=t[e];oe(r)&&Ye(i,r)}else if(oe(e))Ye(i,e.bind(l));else if(Ee(e))if(le(e))e.forEach(r=>Qo(r,t,l,n));else{const r=oe(e.handler)?e.handler.bind(l):t[e.handler];oe(r)&&Ye(i,r,e)}}function Di(e){const t=e.type,{mixins:l,extends:n}=t,{mixins:i,optionsCache:r,config:{optionMergeStrategies:o}}=e.appContext,s=r.get(t);let a;return s?a=s:!i.length&&!l&&!n?a=t:(a={},i.length&&i.forEach(c=>bn(a,c,o,!0)),bn(a,t,o)),Ee(t)&&r.set(t,a),a}function bn(e,t,l,n=!1){const{mixins:i,extends:r}=t;r&&bn(e,r,l,!0),i&&i.forEach(o=>bn(e,o,l,!0));for(const o in t)if(!(n&&o==="expose")){const s=bc[o]||l&&l[o];e[o]=s?s(e[o],t[o]):t[o]}return e}const bc={data:fr,props:vr,emits:vr,methods:Pl,computed:Pl,beforeCreate:Be,created:Be,beforeMount:Be,mounted:Be,beforeUpdate:Be,updated:Be,beforeDestroy:Be,beforeUnmount:Be,destroyed:Be,unmounted:Be,activated:Be,deactivated:Be,errorCaptured:Be,serverPrefetch:Be,components:Pl,directives:Pl,watch:yc,provide:fr,inject:kc};function fr(e,t){return t?e?function(){return De(oe(e)?e.call(this,this):e,oe(t)?t.call(this,this):t)}:t:e}function kc(e,t){return Pl(di(e),di(t))}function di(e){if(le(e)){const t={};for(let l=0;l1)return l&&oe(t)?t.call(n&&n.proxy):t}}function Lc(e,t,l,n=!1){const i={},r={};fn(r,Vn,1),e.propsDefaults=Object.create(null),Zo(e,t,i,r);for(const o in e.propsOptions[0])o in i||(i[o]=void 0);l?e.props=n?i:Io(i):e.type.props?e.props=i:e.props=r,e.attrs=r}function Tc(e,t,l,n){const{props:i,attrs:r,vnode:{patchFlag:o}}=e,s=ve(i),[a]=e.propsOptions;let c=!1;if((n||o>0)&&!(o&16)){if(o&8){const d=e.vnode.dynamicProps;for(let h=0;h{a=!0;const[f,m]=es(h,t,!0);De(o,f),m&&s.push(...m)};!l&&t.mixins.length&&t.mixins.forEach(d),e.extends&&d(e.extends),e.mixins&&e.mixins.forEach(d)}if(!r&&!a)return Ee(e)&&n.set(e,nl),nl;if(le(r))for(let d=0;d-1,m[1]=T<0||k-1||de(m,"default"))&&s.push(h)}}}const c=[o,s];return Ee(e)&&n.set(e,c),c}function pr(e){return e[0]!=="$"}function mr(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function gr(e,t){return mr(e)===mr(t)}function _r(e,t){return le(t)?t.findIndex(l=>gr(l,e)):oe(t)&&gr(t,e)?0:-1}const ts=e=>e[0]==="_"||e==="$stable",Si=e=>le(e)?e.map(lt):[lt(e)],Pc=(e,t,l)=>{if(t._n)return t;const n=Ve((...i)=>Si(t(...i)),l);return n._c=!1,n},ls=(e,t,l)=>{const n=e._ctx;for(const i in e){if(ts(i))continue;const r=e[i];if(oe(r))t[i]=Pc(i,r,n);else if(r!=null){const o=Si(r);t[i]=()=>o}}},ns=(e,t)=>{const l=Si(t);e.slots.default=()=>l},wc=(e,t)=>{if(e.vnode.shapeFlag&32){const l=t._;l?(e.slots=ve(t),fn(t,"_",l)):ls(t,e.slots={})}else e.slots={},t&&ns(e,t);fn(e.slots,Vn,1)},Oc=(e,t,l)=>{const{vnode:n,slots:i}=e;let r=!0,o=xe;if(n.shapeFlag&32){const s=t._;s?l&&s===1?r=!1:(De(i,t),!l&&s===1&&delete i._):(r=!t.$stable,ls(t,i)),o=t}else t&&(ns(e,t),o={default:1});if(r)for(const s in i)!ts(s)&&o[s]==null&&delete i[s]};function yn(e,t,l,n,i=!1){if(le(e)){e.forEach((f,m)=>yn(f,t&&(le(t)?t[m]:t),l,n,i));return}if(sl(n)&&!i)return;const r=n.shapeFlag&4?Fn(n.component)||n.component.proxy:n.el,o=i?null:r,{i:s,r:a}=e,c=t&&t.r,d=s.refs===xe?s.refs={}:s.refs,h=s.setupState;if(c!=null&&c!==a&&(Ae(c)?(d[c]=null,de(h,c)&&(h[c]=null)):Me(c)&&(c.value=null)),oe(a))St(a,s,12,[o,d]);else{const f=Ae(a),m=Me(a);if(f||m){const k=()=>{if(e.f){const T=f?de(h,a)?h[a]:d[a]:a.value;i?le(T)&&ki(T,r):le(T)?T.includes(r)||T.push(r):f?(d[a]=[r],de(h,a)&&(h[a]=d[a])):(a.value=[r],e.k&&(d[e.k]=a.value))}else f?(d[a]=o,de(h,a)&&(h[a]=o)):m&&(a.value=o,e.k&&(d[e.k]=o))};o?(k.id=-1,Ue(k,l)):k()}}}let Pt=!1;const nn=e=>/svg/.test(e.namespaceURI)&&e.tagName!=="foreignObject",rn=e=>e.nodeType===8;function Ac(e){const{mt:t,p:l,o:{patchProp:n,createText:i,nextSibling:r,parentNode:o,remove:s,insert:a,createComment:c}}=e,d=(b,E)=>{if(!E.hasChildNodes()){l(null,b,E),mn(),E._vnode=b;return}Pt=!1,h(E.firstChild,b,null,null,null),mn(),E._vnode=b,Pt&&console.error("Hydration completed but contains mismatches.")},h=(b,E,F,G,N,y=!1)=>{const q=rn(b)&&b.data==="[",O=()=>T(b,E,F,G,N,q),{type:W,ref:x,shapeFlag:C,patchFlag:ne}=E;let se=b.nodeType;E.el=b,ne===-2&&(y=!1,E.dynamicChildren=null);let j=null;switch(W){case ul:se!==3?E.children===""?(a(E.el=i(""),o(b),b),j=b):j=O():(b.data!==E.children&&(Pt=!0,b.data=E.children),j=r(b));break;case Qe:R(b)?(j=r(b),I(E.el=b.content.firstChild,b,F)):se!==8||q?j=O():j=r(b);break;case Al:if(q&&(b=r(b),se=b.nodeType),se===1||se===3){j=b;const Q=!E.children.length;for(let K=0;K{y=y||!!E.dynamicChildren;const{type:q,props:O,patchFlag:W,shapeFlag:x,dirs:C,transition:ne}=E,se=q==="input"||q==="option";if(se||W!==-1){C&&ct(E,null,F,"created");let j=!1;if(R(b)){j=is(G,ne)&&F&&F.vnode.props&&F.vnode.props.appear;const K=b.content.firstChild;j&&ne.beforeEnter(K),I(K,b,F),E.el=b=K}if(O)if(se||!y||W&48)for(const K in O)(se&&(K.endsWith("value")||K==="indeterminate")||Hl(K)&&!wl(K)||K[0]===".")&&n(b,K,null,O[K],!1,void 0,F);else O.onClick&&n(b,"onClick",null,O.onClick,!1,void 0,F);let Q;if((Q=O&&O.onVnodeBeforeMount)&&Ze(Q,F,E),C&&ct(E,null,F,"beforeMount"),((Q=O&&O.onVnodeMounted)||C||j)&&Wo(()=>{Q&&Ze(Q,F,E),j&&ne.enter(b),C&&ct(E,null,F,"mounted")},G),x&16&&!(O&&(O.innerHTML||O.textContent))){let K=m(b.firstChild,E,b,F,G,N,y);for(;K;){Pt=!0;const Se=K;K=K.nextSibling,s(Se)}}else x&8&&b.textContent!==E.children&&(Pt=!0,b.textContent=E.children)}return b.nextSibling},m=(b,E,F,G,N,y,q)=>{q=q||!!E.dynamicChildren;const O=E.children,W=O.length;for(let x=0;x{const{slotScopeIds:q}=E;q&&(N=N?N.concat(q):q);const O=o(b),W=m(r(b),E,O,F,G,N,y);return W&&rn(W)&&W.data==="]"?r(E.anchor=W):(Pt=!0,a(E.anchor=c("]"),O,W),W)},T=(b,E,F,G,N,y)=>{if(Pt=!0,E.el=null,y){const W=w(b);for(;;){const x=r(b);if(x&&x!==W)s(x);else break}}const q=r(b),O=o(b);return s(b),l(null,E,O,q,F,G,nn(O),N),q},w=(b,E="[",F="]")=>{let G=0;for(;b;)if(b=r(b),b&&rn(b)&&(b.data===E&&G++,b.data===F)){if(G===0)return r(b);G--}return b},I=(b,E,F)=>{const G=E.parentNode;G&&G.replaceChild(b,E);let N=F;for(;N;)N.vnode.el===E&&(N.vnode.el=N.subTree.el=b),N=N.parent},R=b=>b.nodeType===1&&b.tagName.toLowerCase()==="template";return[d,h]}const Ue=Wo;function Rc(e){return Ic(e,Ac)}function Ic(e,t){const l=li();l.__VUE__=!0;const{insert:n,remove:i,patchProp:r,createElement:o,createText:s,createComment:a,setText:c,setElementText:d,parentNode:h,nextSibling:f,setScopeId:m=dt,insertStaticContent:k}=e,T=(v,p,_,L=null,A=null,D=null,B=!1,V=null,$=!!p.dynamicChildren)=>{if(v===p)return;v&&!Wt(v,p)&&(L=P(v),He(v,A,D,!0),v=null),p.patchFlag===-2&&($=!1,p.dynamicChildren=null);const{type:S,ref:J,shapeFlag:X}=p;switch(S){case ul:w(v,p,_,L);break;case Qe:I(v,p,_,L);break;case Al:v==null&&R(p,_,L,B);break;case ye:x(v,p,_,L,A,D,B,V,$);break;default:X&1?F(v,p,_,L,A,D,B,V,$):X&6?C(v,p,_,L,A,D,B,V,$):(X&64||X&128)&&S.process(v,p,_,L,A,D,B,V,$,M)}J!=null&&A&&yn(J,v&&v.ref,D,p||v,!p)},w=(v,p,_,L)=>{if(v==null)n(p.el=s(p.children),_,L);else{const A=p.el=v.el;p.children!==v.children&&c(A,p.children)}},I=(v,p,_,L)=>{v==null?n(p.el=a(p.children||""),_,L):p.el=v.el},R=(v,p,_,L)=>{[v.el,v.anchor]=k(v.children,p,_,L,v.el,v.anchor)},b=({el:v,anchor:p},_,L)=>{let A;for(;v&&v!==p;)A=f(v),n(v,_,L),v=A;n(p,_,L)},E=({el:v,anchor:p})=>{let _;for(;v&&v!==p;)_=f(v),i(v),v=_;i(p)},F=(v,p,_,L,A,D,B,V,$)=>{B=B||p.type==="svg",v==null?G(p,_,L,A,D,B,V,$):q(v,p,A,D,B,V,$)},G=(v,p,_,L,A,D,B,V)=>{let $,S;const{type:J,props:X,shapeFlag:Z,transition:re,dirs:ae}=v;if($=v.el=o(v.type,D,X&&X.is,X),Z&8?d($,v.children):Z&16&&y(v.children,$,null,L,A,D&&J!=="foreignObject",B,V),ae&&ct(v,null,L,"created"),N($,v,v.scopeId,B,L),X){for(const _e in X)_e!=="value"&&!wl(_e)&&r($,_e,null,X[_e],D,v.children,L,A,je);"value"in X&&r($,"value",null,X.value),(S=X.onVnodeBeforeMount)&&Ze(S,L,v)}ae&&ct(v,null,L,"beforeMount");const be=is(A,re);be&&re.beforeEnter($),n($,p,_),((S=X&&X.onVnodeMounted)||be||ae)&&Ue(()=>{S&&Ze(S,L,v),be&&re.enter($),ae&&ct(v,null,L,"mounted")},A)},N=(v,p,_,L,A)=>{if(_&&m(v,_),L)for(let D=0;D{for(let S=$;S{const V=p.el=v.el;let{patchFlag:$,dynamicChildren:S,dirs:J}=p;$|=v.patchFlag&16;const X=v.props||xe,Z=p.props||xe;let re;_&&Mt(_,!1),(re=Z.onVnodeBeforeUpdate)&&Ze(re,_,p,v),J&&ct(p,v,_,"beforeUpdate"),_&&Mt(_,!0);const ae=A&&p.type!=="foreignObject";if(S?O(v.dynamicChildren,S,V,_,L,ae,D):B||K(v,p,V,null,_,L,ae,D,!1),$>0){if($&16)W(V,p,X,Z,_,L,A);else if($&2&&X.class!==Z.class&&r(V,"class",null,Z.class,A),$&4&&r(V,"style",X.style,Z.style,A),$&8){const be=p.dynamicProps;for(let _e=0;_e{re&&Ze(re,_,p,v),J&&ct(p,v,_,"updated")},L)},O=(v,p,_,L,A,D,B)=>{for(let V=0;V{if(_!==L){if(_!==xe)for(const V in _)!wl(V)&&!(V in L)&&r(v,V,_[V],null,B,p.children,A,D,je);for(const V in L){if(wl(V))continue;const $=L[V],S=_[V];$!==S&&V!=="value"&&r(v,V,S,$,B,p.children,A,D,je)}"value"in L&&r(v,"value",_.value,L.value)}},x=(v,p,_,L,A,D,B,V,$)=>{const S=p.el=v?v.el:s(""),J=p.anchor=v?v.anchor:s("");let{patchFlag:X,dynamicChildren:Z,slotScopeIds:re}=p;re&&(V=V?V.concat(re):re),v==null?(n(S,_,L),n(J,_,L),y(p.children,_,J,A,D,B,V,$)):X>0&&X&64&&Z&&v.dynamicChildren?(O(v.dynamicChildren,Z,_,A,D,B,V),(p.key!=null||A&&p===A.subTree)&&rs(v,p,!0)):K(v,p,_,J,A,D,B,V,$)},C=(v,p,_,L,A,D,B,V,$)=>{p.slotScopeIds=V,v==null?p.shapeFlag&512?A.ctx.activate(p,_,L,B,$):ne(p,_,L,A,D,B,$):se(v,p,$)},ne=(v,p,_,L,A,D,B)=>{const V=v.component=Hc(v,L,A);if(Ul(v)&&(V.ctx.renderer=M),$c(V),V.asyncDep){if(A&&A.registerDep(V,j),!v.el){const $=V.subTree=ie(Qe);I(null,$,p,_)}return}j(V,v,p,_,A,D,B)},se=(v,p,_)=>{const L=p.component=v.component;if(Ya(v,p,_))if(L.asyncDep&&!L.asyncResolved){Q(L,p,_);return}else L.next=p,Wa(L.update),L.update();else p.el=v.el,L.vnode=p},j=(v,p,_,L,A,D,B)=>{const V=()=>{if(v.isMounted){let{next:J,bu:X,u:Z,parent:re,vnode:ae}=v,be=J,_e;Mt(v,!1),J?(J.el=ae.el,Q(v,J,B)):J=ae,X&&$n(X),(_e=J.props&&J.props.onVnodeBeforeUpdate)&&Ze(_e,re,J,ae),Mt(v,!0);const Pe=zn(v),tt=v.subTree;v.subTree=Pe,T(tt,Pe,h(tt.el),P(tt),v,A,D),J.el=Pe.el,be===null&&Qa(v,Pe.el),Z&&Ue(Z,A),(_e=J.props&&J.props.onVnodeUpdated)&&Ue(()=>Ze(_e,re,J,ae),A)}else{let J;const{el:X,props:Z}=p,{bm:re,m:ae,parent:be}=v,_e=sl(p);if(Mt(v,!1),re&&$n(re),!_e&&(J=Z&&Z.onVnodeBeforeMount)&&Ze(J,be,p),Mt(v,!0),X&&ce){const Pe=()=>{v.subTree=zn(v),ce(X,v.subTree,v,A,null)};_e?p.type.__asyncLoader().then(()=>!v.isUnmounted&&Pe()):Pe()}else{const Pe=v.subTree=zn(v);T(null,Pe,_,L,v,A,D),p.el=Pe.el}if(ae&&Ue(ae,A),!_e&&(J=Z&&Z.onVnodeMounted)){const Pe=p;Ue(()=>Ze(J,be,Pe),A)}(p.shapeFlag&256||be&&sl(be.vnode)&&be.vnode.shapeFlag&256)&&v.a&&Ue(v.a,A),v.isMounted=!0,p=_=L=null}},$=v.effect=new xi(V,()=>Dn(S),v.scope),S=v.update=()=>$.run();S.id=v.uid,Mt(v,!0),S()},Q=(v,p,_)=>{p.component=v;const L=v.vnode.props;v.vnode=p,v.next=null,Tc(v,p.props,L,_),Oc(v,p.children,_),gl(),sr(v),_l()},K=(v,p,_,L,A,D,B,V,$=!1)=>{const S=v&&v.children,J=v?v.shapeFlag:0,X=p.children,{patchFlag:Z,shapeFlag:re}=p;if(Z>0){if(Z&128){Ce(S,X,_,L,A,D,B,V,$);return}else if(Z&256){Se(S,X,_,L,A,D,B,V,$);return}}re&8?(J&16&&je(S,A,D),X!==S&&d(_,X)):J&16?re&16?Ce(S,X,_,L,A,D,B,V,$):je(S,A,D,!0):(J&8&&d(_,""),re&16&&y(X,_,L,A,D,B,V,$))},Se=(v,p,_,L,A,D,B,V,$)=>{v=v||nl,p=p||nl;const S=v.length,J=p.length,X=Math.min(S,J);let Z;for(Z=0;ZJ?je(v,A,D,!0,!1,X):y(p,_,L,A,D,B,V,$,X)},Ce=(v,p,_,L,A,D,B,V,$)=>{let S=0;const J=p.length;let X=v.length-1,Z=J-1;for(;S<=X&&S<=Z;){const re=v[S],ae=p[S]=$?Rt(p[S]):lt(p[S]);if(Wt(re,ae))T(re,ae,_,null,A,D,B,V,$);else break;S++}for(;S<=X&&S<=Z;){const re=v[X],ae=p[Z]=$?Rt(p[Z]):lt(p[Z]);if(Wt(re,ae))T(re,ae,_,null,A,D,B,V,$);else break;X--,Z--}if(S>X){if(S<=Z){const re=Z+1,ae=reZ)for(;S<=X;)He(v[S],A,D,!0),S++;else{const re=S,ae=S,be=new Map;for(S=ae;S<=Z;S++){const Xe=p[S]=$?Rt(p[S]):lt(p[S]);Xe.key!=null&&be.set(Xe.key,S)}let _e,Pe=0;const tt=Z-ae+1;let Jt=!1,Yi=0;const kl=new Array(tt);for(S=0;S=tt){He(Xe,A,D,!0);continue}let at;if(Xe.key!=null)at=be.get(Xe.key);else for(_e=ae;_e<=Z;_e++)if(kl[_e-ae]===0&&Wt(Xe,p[_e])){at=_e;break}at===void 0?He(Xe,A,D,!0):(kl[at-ae]=S+1,at>=Yi?Yi=at:Jt=!0,T(Xe,p[at],_,null,A,D,B,V,$),Pe++)}const Qi=Jt?Dc(kl):nl;for(_e=Qi.length-1,S=tt-1;S>=0;S--){const Xe=ae+S,at=p[Xe],Ji=Xe+1{const{el:D,type:B,transition:V,children:$,shapeFlag:S}=v;if(S&6){We(v.component.subTree,p,_,L);return}if(S&128){v.suspense.move(p,_,L);return}if(S&64){B.move(v,p,_,M);return}if(B===ye){n(D,p,_);for(let X=0;X<$.length;X++)We($[X],p,_,L);n(v.anchor,p,_);return}if(B===Al){b(v,p,_);return}if(L!==2&&S&1&&V)if(L===0)V.beforeEnter(D),n(D,p,_),Ue(()=>V.enter(D),A);else{const{leave:X,delayLeave:Z,afterLeave:re}=V,ae=()=>n(D,p,_),be=()=>{X(D,()=>{ae(),re&&re()})};Z?Z(D,ae,be):be()}else n(D,p,_)},He=(v,p,_,L=!1,A=!1)=>{const{type:D,props:B,ref:V,children:$,dynamicChildren:S,shapeFlag:J,patchFlag:X,dirs:Z}=v;if(V!=null&&yn(V,null,_,v,!0),J&256){p.ctx.deactivate(v);return}const re=J&1&&Z,ae=!sl(v);let be;if(ae&&(be=B&&B.onVnodeBeforeUnmount)&&Ze(be,p,v),J&6)st(v.component,_,L);else{if(J&128){v.suspense.unmount(_,L);return}re&&ct(v,null,p,"beforeUnmount"),J&64?v.type.remove(v,p,_,A,M,L):S&&(D!==ye||X>0&&X&64)?je(S,p,_,!1,!0):(D===ye&&X&384||!A&&J&16)&&je($,p,_),L&&xt(v)}(ae&&(be=B&&B.onVnodeUnmounted)||re)&&Ue(()=>{be&&Ze(be,p,v),re&&ct(v,null,p,"unmounted")},_)},xt=v=>{const{type:p,el:_,anchor:L,transition:A}=v;if(p===ye){Lt(_,L);return}if(p===Al){E(v);return}const D=()=>{i(_),A&&!A.persisted&&A.afterLeave&&A.afterLeave()};if(v.shapeFlag&1&&A&&!A.persisted){const{leave:B,delayLeave:V}=A,$=()=>B(_,D);V?V(v.el,D,$):$()}else D()},Lt=(v,p)=>{let _;for(;v!==p;)_=f(v),i(v),v=_;i(p)},st=(v,p,_)=>{const{bum:L,scope:A,update:D,subTree:B,um:V}=v;L&&$n(L),A.stop(),D&&(D.active=!1,He(B,v,p,_)),V&&Ue(V,p),Ue(()=>{v.isUnmounted=!0},p),p&&p.pendingBranch&&!p.isUnmounted&&v.asyncDep&&!v.asyncResolved&&v.suspenseId===p.pendingId&&(p.deps--,p.deps===0&&p.resolve())},je=(v,p,_,L=!1,A=!1,D=0)=>{for(let B=D;Bv.shapeFlag&6?P(v.component.subTree):v.shapeFlag&128?v.suspense.next():f(v.anchor||v.el),U=(v,p,_)=>{v==null?p._vnode&&He(p._vnode,null,null,!0):T(p._vnode||null,v,p,null,null,null,_),sr(),mn(),p._vnode=v},M={p:T,um:He,m:We,r:xt,mt:ne,mc:y,pc:K,pbc:O,n:P,o:e};let Y,ce;return t&&([Y,ce]=t(M)),{render:U,hydrate:Y,createApp:xc(U,Y)}}function Mt({effect:e,update:t},l){e.allowRecurse=t.allowRecurse=l}function is(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function rs(e,t,l=!1){const n=e.children,i=t.children;if(le(n)&&le(i))for(let r=0;r>1,e[l[s]]0&&(t[n]=l[r-1]),l[r]=n)}}for(r=l.length,o=l[r-1];r-- >0;)l[r]=o,o=t[o];return l}const Sc=e=>e.__isTeleport,ye=Symbol.for("v-fgt"),ul=Symbol.for("v-txt"),Qe=Symbol.for("v-cmt"),Al=Symbol.for("v-stc"),Rl=[];let it=null;function z(e=!1){Rl.push(it=e?null:[])}function jc(){Rl.pop(),it=Rl[Rl.length-1]||null}let Vl=1;function br(e){Vl+=e}function os(e){return e.dynamicChildren=Vl>0?it||nl:null,jc(),Vl>0&&it&&it.push(e),e}function ee(e,t,l,n,i,r){return os(he(e,t,l,n,i,r,!0))}function we(e,t,l,n,i){return os(ie(e,t,l,n,i,!0))}function En(e){return e?e.__v_isVNode===!0:!1}function Wt(e,t){return e.type===t.type&&e.key===t.key}const Vn="__vInternal",ss=({key:e})=>e??null,dn=({ref:e,ref_key:t,ref_for:l})=>(typeof e=="number"&&(e=""+e),e!=null?Ae(e)||Me(e)||oe(e)?{i:Fe,r:e,k:t,f:!!l}:e:null);function he(e,t=null,l=null,n=0,i=null,r=e===ye?0:1,o=!1,s=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&ss(t),ref:t&&dn(t),scopeId:Bo,slotScopeIds:null,children:l,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:r,patchFlag:n,dynamicProps:i,dynamicChildren:null,appContext:null,ctx:Fe};return s?(ji(a,l),r&128&&e.normalize(a)):l&&(a.shapeFlag|=Ae(l)?8:16),Vl>0&&!o&&it&&(a.patchFlag>0||r&6)&&a.patchFlag!==32&&it.push(a),a}const ie=Cc;function Cc(e,t=null,l=null,n=0,i=null,r=!1){if((!e||e===Ja)&&(e=Qe),En(e)){const s=Vt(e,t,!0);return l&&ji(s,l),Vl>0&&!r&&it&&(s.shapeFlag&6?it[it.indexOf(e)]=s:it.push(s)),s.patchFlag|=-2,s}if(Kc(e)&&(e=e.__vccOpts),t){t=Vc(t);let{class:s,style:a}=t;s&&!Ae(s)&&(t.class=Ke(s)),Ee(a)&&(Do(a)&&!le(a)&&(a=De({},a)),t.style=$l(a))}const o=Ae(e)?1:ec(e)?128:Sc(e)?64:Ee(e)?4:oe(e)?2:0;return he(e,t,l,n,i,o,r,!0)}function Vc(e){return e?Do(e)||Vn in e?De({},e):e:null}function Vt(e,t,l=!1){const{props:n,ref:i,patchFlag:r,children:o}=e,s=t?fi(n||{},t):n;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:s,key:s&&ss(s),ref:t&&t.ref?l&&i?le(i)?i.concat(dn(t)):[i,dn(t)]:dn(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:o,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ye?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Vt(e.ssContent),ssFallback:e.ssFallback&&Vt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function Ft(e=" ",t=0){return ie(ul,null,e,t)}function Fc(e,t){const l=ie(Al,null,e);return l.staticCount=t,l}function Oe(e="",t=!1){return t?(z(),we(Qe,null,e)):ie(Qe,null,e)}function lt(e){return e==null||typeof e=="boolean"?ie(Qe):le(e)?ie(ye,null,e.slice()):typeof e=="object"?Rt(e):ie(ul,null,String(e))}function Rt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Vt(e)}function ji(e,t){let l=0;const{shapeFlag:n}=e;if(t==null)t=null;else if(le(t))l=16;else if(typeof t=="object")if(n&65){const i=t.default;i&&(i._c&&(i._d=!1),ji(e,i()),i._c&&(i._d=!0));return}else{l=32;const i=t._;!i&&!(Vn in t)?t._ctx=Fe:i===3&&Fe&&(Fe.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else oe(t)?(t={default:t,_ctx:Fe},l=32):(t=String(t),n&64?(l=16,t=[Ft(t)]):l=8);e.children=t,e.shapeFlag|=l}function fi(...e){const t={};for(let l=0;lRe||Fe;let Vi,Zt,kr="__VUE_INSTANCE_SETTERS__";(Zt=li()[kr])||(Zt=li()[kr]=[]),Zt.push(e=>Re=e),Vi=e=>{Zt.length>1?Zt.forEach(t=>t(e)):Zt[0](e)};const dl=e=>{Vi(e),e.scope.on()},Gt=()=>{Re&&Re.scope.off(),Vi(null)};function as(e){return e.vnode.shapeFlag&4}let hl=!1;function $c(e,t=!1){hl=t;const{props:l,children:n}=e.vnode,i=as(e);Lc(e,l,i,t),wc(e,n);const r=i?Bc(e,t):void 0;return hl=!1,r}function Bc(e,t){const l=e.type;e.accessCache=Object.create(null),e.proxy=So(new Proxy(e.ctx,mc));const{setup:n}=l;if(n){const i=e.setupContext=n.length>1?Wc(e):null;dl(e),gl();const r=St(n,e,0,[e.props,i]);if(_l(),Gt(),po(r)){if(r.then(Gt,Gt),t)return r.then(o=>{yr(e,o,t)}).catch(o=>{zl(o,e,0)});e.asyncDep=r}else yr(e,r,t)}else cs(e,t)}function yr(e,t,l){oe(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Ee(t)&&(e.setupState=Vo(t)),cs(e,l)}let Er;function cs(e,t,l){const n=e.type;if(!e.render){if(!t&&Er&&!n.render){const i=n.template||Di(e).template;if(i){const{isCustomElement:r,compilerOptions:o}=e.appContext.config,{delimiters:s,compilerOptions:a}=n,c=De(De({isCustomElement:r,delimiters:s},o),a);n.render=Er(i,c)}}e.render=n.render||dt}{dl(e),gl();try{gc(e)}finally{_l(),Gt()}}}function zc(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,l){return qe(e,"get","$attrs"),t[l]}}))}function Wc(e){const t=l=>{e.exposed=l||{}};return{get attrs(){return zc(e)},slots:e.slots,emit:e.emit,expose:t}}function Fn(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(Vo(So(e.exposed)),{get(t,l){if(l in t)return t[l];if(l in Ol)return Ol[l](e)},has(t,l){return l in t||l in Ol}}))}function Uc(e,t=!0){return oe(e)?e.displayName||e.name:e.name||t&&e.__name}function Kc(e){return oe(e)&&"__vccOpts"in e}const H=(e,t)=>$a(e,t,hl);function fe(e,t,l){const n=arguments.length;return n===2?Ee(t)&&!le(t)?En(t)?ie(e,null,[t]):ie(e,t):ie(e,null,t):(n>3?l=Array.prototype.slice.call(arguments,2):n===3&&En(l)&&(l=[l]),ie(e,t,l))}const qc=Symbol.for("v-scx"),Xc=()=>Te(qc),Gc="3.3.13",Yc="http://www.w3.org/2000/svg",Ut=typeof document<"u"?document:null,xr=Ut&&Ut.createElement("template"),Qc={insert:(e,t,l)=>{t.insertBefore(e,l||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,l,n)=>{const i=t?Ut.createElementNS(Yc,e):Ut.createElement(e,l?{is:l}:void 0);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>Ut.createTextNode(e),createComment:e=>Ut.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ut.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,l,n,i,r){const o=l?l.previousSibling:t.lastChild;if(i&&(i===r||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),l),!(i===r||!(i=i.nextSibling)););else{xr.innerHTML=n?`${e}`:e;const s=xr.content;if(n){const a=s.firstChild;for(;a.firstChild;)s.appendChild(a.firstChild);s.removeChild(a)}t.insertBefore(s,l)}return[o?o.nextSibling:t.firstChild,l?l.previousSibling:t.lastChild]}},wt="transition",yl="animation",Fl=Symbol("_vtc"),ql=(e,{slots:t})=>fe(rc,Jc(e),t);ql.displayName="Transition";const us={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};ql.props=De({},Ko,us);const Ht=(e,t=[])=>{le(e)?e.forEach(l=>l(...t)):e&&e(...t)},Lr=e=>e?le(e)?e.some(t=>t.length>1):e.length>1:!1;function Jc(e){const t={};for(const x in e)x in us||(t[x]=e[x]);if(e.css===!1)return t;const{name:l="v",type:n,duration:i,enterFromClass:r=`${l}-enter-from`,enterActiveClass:o=`${l}-enter-active`,enterToClass:s=`${l}-enter-to`,appearFromClass:a=r,appearActiveClass:c=o,appearToClass:d=s,leaveFromClass:h=`${l}-leave-from`,leaveActiveClass:f=`${l}-leave-active`,leaveToClass:m=`${l}-leave-to`}=e,k=Zc(i),T=k&&k[0],w=k&&k[1],{onBeforeEnter:I,onEnter:R,onEnterCancelled:b,onLeave:E,onLeaveCancelled:F,onBeforeAppear:G=I,onAppear:N=R,onAppearCancelled:y=b}=t,q=(x,C,ne)=>{$t(x,C?d:s),$t(x,C?c:o),ne&&ne()},O=(x,C)=>{x._isLeaving=!1,$t(x,h),$t(x,m),$t(x,f),C&&C()},W=x=>(C,ne)=>{const se=x?N:R,j=()=>q(C,x,ne);Ht(se,[C,j]),Tr(()=>{$t(C,x?a:r),Ot(C,x?d:s),Lr(se)||Pr(C,n,T,j)})};return De(t,{onBeforeEnter(x){Ht(I,[x]),Ot(x,r),Ot(x,o)},onBeforeAppear(x){Ht(G,[x]),Ot(x,a),Ot(x,c)},onEnter:W(!1),onAppear:W(!0),onLeave(x,C){x._isLeaving=!0;const ne=()=>O(x,C);Ot(x,h),lu(),Ot(x,f),Tr(()=>{x._isLeaving&&($t(x,h),Ot(x,m),Lr(E)||Pr(x,n,w,ne))}),Ht(E,[x,ne])},onEnterCancelled(x){q(x,!1),Ht(b,[x])},onAppearCancelled(x){q(x,!0),Ht(y,[x])},onLeaveCancelled(x){O(x),Ht(F,[x])}})}function Zc(e){if(e==null)return null;if(Ee(e))return[qn(e.enter),qn(e.leave)];{const t=qn(e);return[t,t]}}function qn(e){return na(e)}function Ot(e,t){t.split(/\s+/).forEach(l=>l&&e.classList.add(l)),(e[Fl]||(e[Fl]=new Set)).add(t)}function $t(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.remove(n));const l=e[Fl];l&&(l.delete(t),l.size||(e[Fl]=void 0))}function Tr(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let eu=0;function Pr(e,t,l,n){const i=e._endId=++eu,r=()=>{i===e._endId&&n()};if(l)return setTimeout(r,l);const{type:o,timeout:s,propCount:a}=tu(e,t);if(!o)return n();const c=o+"end";let d=0;const h=()=>{e.removeEventListener(c,f),r()},f=m=>{m.target===e&&++d>=a&&h()};setTimeout(()=>{d(l[k]||"").split(", "),i=n(`${wt}Delay`),r=n(`${wt}Duration`),o=wr(i,r),s=n(`${yl}Delay`),a=n(`${yl}Duration`),c=wr(s,a);let d=null,h=0,f=0;t===wt?o>0&&(d=wt,h=o,f=r.length):t===yl?c>0&&(d=yl,h=c,f=a.length):(h=Math.max(o,c),d=h>0?o>c?wt:yl:null,f=d?d===wt?r.length:a.length:0);const m=d===wt&&/\b(transform|all)(,|$)/.test(n(`${wt}Property`).toString());return{type:d,timeout:h,propCount:f,hasTransform:m}}function wr(e,t){for(;e.lengthOr(l)+Or(e[n])))}function Or(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function lu(){return document.body.offsetHeight}function nu(e,t,l){const n=e[Fl];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):l?e.setAttribute("class",t):e.className=t}const Fi=Symbol("_vod"),xn={beforeMount(e,{value:t},{transition:l}){e[Fi]=e.style.display==="none"?"":e.style.display,l&&t?l.beforeEnter(e):El(e,t)},mounted(e,{value:t},{transition:l}){l&&t&&l.enter(e)},updated(e,{value:t,oldValue:l},{transition:n}){!t!=!l&&(n?t?(n.beforeEnter(e),El(e,!0),n.enter(e)):n.leave(e,()=>{El(e,!1)}):El(e,t))},beforeUnmount(e,{value:t}){El(e,t)}};function El(e,t){e.style.display=t?e[Fi]:"none"}const iu=Symbol("");function ru(e,t,l){const n=e.style,i=Ae(l);if(l&&!i){if(t&&!Ae(t))for(const r in t)l[r]==null&&vi(n,r,"");for(const r in l)vi(n,r,l[r])}else{const r=n.display;if(i){if(t!==l){const o=n[iu];o&&(l+=";"+o),n.cssText=l}}else t&&e.removeAttribute("style");Fi in e&&(n.display=r)}}const Ar=/\s*!important$/;function vi(e,t,l){if(le(l))l.forEach(n=>vi(e,t,n));else if(l==null&&(l=""),t.startsWith("--"))e.setProperty(t,l);else{const n=ou(e,t);Ar.test(l)?e.setProperty(Qt(n),l.replace(Ar,""),"important"):e[n]=l}}const Rr=["Webkit","Moz","ms"],Xn={};function ou(e,t){const l=Xn[t];if(l)return l;let n=ht(t);if(n!=="filter"&&n in e)return Xn[t]=n;n=On(n);for(let i=0;iGn||(fu.then(()=>Gn=0),Gn=Date.now());function pu(e,t){const l=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=l.attached)return;et(mu(n,l.value),t,5,[n])};return l.value=e,l.attached=vu(),l}function mu(e,t){if(le(t)){const l=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{l.call(e),e._stopped=!0},t.map(n=>i=>!i._stopped&&n&&n(i))}else return t}const jr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,gu=(e,t,l,n,i=!1,r,o,s,a)=>{t==="class"?nu(e,n,i):t==="style"?ru(e,l,n):Hl(t)?bi(t)||du(e,t,l,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):_u(e,t,n,i))?au(e,t,n,r,o,s,a):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),su(e,t,n,i))};function _u(e,t,l,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&jr(t)&&oe(l));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const i=e.tagName;if(i==="IMG"||i==="VIDEO"||i==="CANVAS"||i==="SOURCE")return!1}return jr(t)&&Ae(l)?!1:t in e}const bu={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},ku=(e,t)=>{const l=e._withKeys||(e._withKeys={}),n=t.join(".");return l[n]||(l[n]=i=>{if(!("key"in i))return;const r=Qt(i.key);if(t.some(o=>o===r||bu[o]===r))return e(i)})},yu=De({patchProp:gu},Qc);let Yn,Cr=!1;function Eu(){return Yn=Cr?Yn:Rc(yu),Cr=!0,Yn}const xu=(...e)=>{const t=Eu().createApp(...e),{mount:l}=t;return t.mount=n=>{const i=Lu(n);if(i)return l(i,!0,i instanceof SVGElement)},t};function Lu(e){return Ae(e)?document.querySelector(e):e}const Tu="modulepreload",Pu=function(e){return"/"+e},Vr={},u=function(t,l,n){let i=Promise.resolve();if(l&&l.length>0){const r=document.getElementsByTagName("link");i=Promise.all(l.map(o=>{if(o=Pu(o),o in Vr)return;Vr[o]=!0;const s=o.endsWith(".css"),a=s?'[rel="stylesheet"]':"";if(!!n)for(let h=r.length-1;h>=0;h--){const f=r[h];if(f.href===o&&(!s||f.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${o}"]${a}`))return;const d=document.createElement("link");if(d.rel=s?"stylesheet":Tu,s||(d.as="script",d.crossOrigin=""),d.href=o,document.head.appendChild(d),s)return new Promise((h,f)=>{d.addEventListener("load",h),d.addEventListener("error",()=>f(new Error(`Unable to preload CSS for ${o}`)))})}))}return i.then(()=>t()).catch(r=>{const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=r,window.dispatchEvent(o),!o.defaultPrevented)throw r})},wu={"v-8daa1a0e":()=>u(()=>import("./index.html-p2c5C4AU.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-aad48c6a":()=>u(()=>import("./news.html-pwjcoGoO.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f7496066":()=>u(()=>import("./index.html-z9NWHqlp.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-ba934fd8":()=>u(()=>import("./index.html-XFyzJ1xl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-41ade9da":()=>u(()=>import("./api.html-WGzp5ZHY.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-83dedd38":()=>u(()=>import("./dns.html-M7PqPYo9.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-192a19b9":()=>u(()=>import("./fakedns.html-wHw6FjrC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7f6279d8":()=>u(()=>import("./inbound.html-moDGVb2O.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1d860c29":()=>u(()=>import("./log.html-e7hnT2bq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fbaf47ec":()=>u(()=>import("./metrics.html-9VuoOtoJ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2367d756":()=>u(()=>import("./outbound.html-m7-qp10m.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4ebec35a":()=>u(()=>import("./policy.html-5wXUoyYU.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-31b7756a":()=>u(()=>import("./reverse.html-iCYMdXOv.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-70677432":()=>u(()=>import("./routing.html-z5FZ8_MJ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7e21d6ae":()=>u(()=>import("./stats.html-sE2S72lW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e3dfff38":()=>u(()=>import("./transport.html-VgBdoawf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-36b1a79b":()=>u(()=>import("./index.html-E6Im5Z2U.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-09a64f89":()=>u(()=>import("./command.html-zok3YKap.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2b1adf48":()=>u(()=>import("./config.html-aUjThaBl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-86ee963a":()=>u(()=>import("./document.html-T74UyKyv.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0e5d7b39":()=>u(()=>import("./install.html-HJ0OvsaV.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2d0a870d":()=>u(()=>import("./index.html-G23QhNrE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6a9e8054":()=>u(()=>import("./compile.html-X6FgGIuq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-95e3eaea":()=>u(()=>import("./design.html--gTpLkem.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-61e7eea6":()=>u(()=>import("./guide.html-9aEFcVqM.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6e6c37e6":()=>u(()=>import("./mkcp.html-vo5PDXHA.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-13168a21":()=>u(()=>import("./muxcool.html-nTSzbowY.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5c48c82b":()=>u(()=>import("./vless.html-qQ4zG4ni.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1ee591a8":()=>u(()=>import("./vmess.html-VN98TXTo.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0d714d87":()=>u(()=>import("./browser_dialer.html-pBajOlNq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0da7880a":()=>u(()=>import("./env.html-cjIQiZYK.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2aeb21f9":()=>u(()=>import("./fallback.html-1JIS-sqn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3acf20ea":()=>u(()=>import("./multiple.html-g48N6K0K.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-792e28f8":()=>u(()=>import("./xtls.html-B_w95T3t.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-b50d2334":()=>u(()=>import("./dokodemo.html-jpQVDK5E.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-593408b0":()=>u(()=>import("./http.html-kcI8nPMj.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-802a842a":()=>u(()=>import("./shadowsocks.html-RfXFYESa.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-29995cea":()=>u(()=>import("./socks.html-s5-aPzb4.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2a1b3d72":()=>u(()=>import("./trojan.html-1a6tGxlx.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fb92e8aa":()=>u(()=>import("./vless.html-8KqB5qGc.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-167afaac":()=>u(()=>import("./vmess.html-YK_H6TQs.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-749ad71a":()=>u(()=>import("./blackhole.html-KHhjSI5O.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6d39b970":()=>u(()=>import("./dns.html-gJ4v9Hez.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d76e893a":()=>u(()=>import("./freedom.html-bKrcmvMl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c6b4b59e":()=>u(()=>import("./http.html-ODrut9n2.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-41ec0e0e":()=>u(()=>import("./loopback.html-nkoZ0pXT.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7b293e4a":()=>u(()=>import("./shadowsocks.html-coJ5pBTn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-15f5452a":()=>u(()=>import("./socks.html-y40g6uI5.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5797bdb3":()=>u(()=>import("./trojan.html-yXVZG2Ev.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a60f016c":()=>u(()=>import("./vless.html-qqj9e8Vf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-413cee4b":()=>u(()=>import("./vmess.html-Vr1rc_Up.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-208ca3b9":()=>u(()=>import("./wireguard.html-KdrqTCQm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-775db7b1":()=>u(()=>import("./domainsocket.html-wdK_rHZQ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2877542a":()=>u(()=>import("./grpc.html-LBqi_a75.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-03a28284":()=>u(()=>import("./h2.html-KM70GQbw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-04158536":()=>u(()=>import("./httpupgrade.html-H-WqXGti.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3167b1dd":()=>u(()=>import("./mkcp.html-0Xk_HIpn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8f08dbec":()=>u(()=>import("./quic.html-m95M53yN.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-33b1b709":()=>u(()=>import("./tcp.html-jnCC9tdJ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1ff57bba":()=>u(()=>import("./websocket.html-MBy8EkDB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3f09dcfa":()=>u(()=>import("./index.html-SzZckNsL.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fb444906":()=>u(()=>import("./ch01-preface.html-tEScEaZz.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-075f3ae5":()=>u(()=>import("./ch02-preparation.html-RGVVF1aX.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-726d0633":()=>u(()=>import("./ch03-ssh.html-r0_Dxdy0.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-430c6ab8":()=>u(()=>import("./ch04-security.html-fTS70_mi.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-717c6376":()=>u(()=>import("./ch05-webpage.html-5seJ1ciw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-278039be":()=>u(()=>import("./ch06-certificates.html-S8wDl_Ux.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a0c7f88e":()=>u(()=>import("./ch07-xray-server.html-XceTyVhx.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-86586ca2":()=>u(()=>import("./ch08-xray-clients.html-ud6w1qRW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3eb62514":()=>u(()=>import("./ch09-appendix.html-sabgEttE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3f09dcbc":()=>u(()=>import("./index.html-mMCfrUS-.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-b21a2a20":()=>u(()=>import("./fallbacks-lv1.html--J_6qlTn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-da623318":()=>u(()=>import("./fallbacks-with-sni.html-qQOZMYA7.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fdd722ac":()=>u(()=>import("./routing-lv1-part1.html-cRNm4oEK.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fa6d716e":()=>u(()=>import("./routing-lv1-part2.html-5XUPXSEg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2f29e106":()=>u(()=>import("./work.html-145CR_fW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3f09dc7e":()=>u(()=>import("./index.html-BFn1lRAW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1c17916e":()=>u(()=>import("./iptables_gid.html-BjKdQK_Z.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a001cfa6":()=>u(()=>import("./nginx_or_haproxy_tls_tunnel.html-_NqxTVZn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-46333b48":()=>u(()=>import("./redirect.html-ErNGzo9V.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-338bc63e":()=>u(()=>import("./tproxy.html-y5eAJ7SY.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d68f7d58":()=>u(()=>import("./tproxy_ipv4_and_ipv6.html-JH4YyNOP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e533e2c6":()=>u(()=>import("./traffic_stats.html-_cNOE5xN.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1e465ab0":()=>u(()=>import("./warp.html-2hJhJpHa.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1080fb37":()=>u(()=>import("./news.html-gzJt0vYA.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-317fc580":()=>u(()=>import("./index.html-BGcfEeBc.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-45144c7f":()=>u(()=>import("./api.html-ehTB5jsP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-23fbd2d0":()=>u(()=>import("./dns.html-rP5naxFq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2b7ec525":()=>u(()=>import("./fakedns.html-WRT-9j2m.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5ab92300":()=>u(()=>import("./inbound.html-Mx2-iGW_.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f91d64d6":()=>u(()=>import("./log.html-p-vXJqMl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d705f114":()=>u(()=>import("./metrics.html-GccLQE2P.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-268cd669":()=>u(()=>import("./outbound.html-rUxUkwF-.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4492d567":()=>u(()=>import("./policy.html-0ggCjnWf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0d0e1e92":()=>u(()=>import("./reverse.html-Vyc-TBL8.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4bbe1d5a":()=>u(()=>import("./routing.html-gMcV9QF8.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-16426d1a":()=>u(()=>import("./stats.html-f0XRSzHJ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5de780d0":()=>u(()=>import("./transport.html-XoPNjoZf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f88d343e":()=>u(()=>import("./index.html-JeZuqWwp.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-38d56a07":()=>u(()=>import("./index.html-PAgbBg-Z.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4d046016":()=>u(()=>import("./command.html-5rSGvvaL.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-22b35270":()=>u(()=>import("./config.html-5ZOPemlE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-30bd7c12":()=>u(()=>import("./document.html-7QxaDrrB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-439608b6":()=>u(()=>import("./install.html-bu0Ticvf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-51a51d87":()=>u(()=>import("./transparent_proxy.html-ocawHfnS.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-76b9a0f3":()=>u(()=>import("./browser_dialer.html-G4IRQ_Kg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-565dbfc4":()=>u(()=>import("./env.html-vTGLOPHC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0fbd1336":()=>u(()=>import("./fallback.html-c3nG_SbK.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a0627812":()=>u(()=>import("./multiple.html-broKJH6Q.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d190d938":()=>u(()=>import("./xtls.html-VGwDVgWQ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-72afc2d2":()=>u(()=>import("./dokodemo.html-lQ2ZCHA0.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-773d731c":()=>u(()=>import("./http.html-qlBUGI3d.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f555fc02":()=>u(()=>import("./shadowsocks.html-KKd7sD5W.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e35196c2":()=>u(()=>import("./socks.html-Rr3Pd7Z4.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-29188644":()=>u(()=>import("./trojan.html-JtWYvOGZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-255a6ebf":()=>u(()=>import("./vless.html-FmnaDhwB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8cc24480":()=>u(()=>import("./vmess.html-DQRQNJRf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-64e47ef4":()=>u(()=>import("./blackhole.html-wP8aOe1s.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e979b848":()=>u(()=>import("./dns.html-fsBpY6OJ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-617f0fcf":()=>u(()=>import("./freedom.html-pEcHOOJi.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3fc98845":()=>u(()=>import("./http.html-ycpGlUVn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1b804722":()=>u(()=>import("./loopback.html-aUCjrxrz.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-63077cb6":()=>u(()=>import("./shadowsocks.html-DUgYYNSE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-516476d4":()=>u(()=>import("./socks.html-4LNnnGuU.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7d61a872":()=>u(()=>import("./trojan.html-zPYE2Rnw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6e50feb6":()=>u(()=>import("./vless.html-oJkCcWqP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-02956db7":()=>u(()=>import("./vmess.html-FLYSgYZF.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-797f8d25":()=>u(()=>import("./wireguard.html-BNOcORO_.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3eb3e9c6":()=>u(()=>import("./domainsocket.html-XJDOFjPR.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2c6058d4":()=>u(()=>import("./grpc.html--7XYo6-r.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1c38292a":()=>u(()=>import("./h2.html-an3IPz3A.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-17ff144a":()=>u(()=>import("./httpupgrade.html-pqcUDxzH.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1a7f9d6e":()=>u(()=>import("./mkcp.html-KaKSugGP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-79d41176":()=>u(()=>import("./quic.html-tQfatAaD.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5254cbc6":()=>u(()=>import("./tcp.html-D0BFi51s.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-9520f392":()=>u(()=>import("./websocket.html-u5FN1LVg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-b7760e2c":()=>u(()=>import("./compile.html-v0FcVQeh.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fb774212":()=>u(()=>import("./design.html-mn37DqeY.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-38c376c1":()=>u(()=>import("./guide.html-uQWUSL0p.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-21bccd79":()=>u(()=>import("./mkcp.html-uyvLxsmR.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-27001935":()=>u(()=>import("./muxcool.html-dKJnlJKP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-21b30c3f":()=>u(()=>import("./vless.html-oFhH_CKR.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-94110980":()=>u(()=>import("./vmess.html-tRW4iV5D.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-789ba7ef":()=>u(()=>import("./index.html-epCgXVFP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d3712ade":()=>u(()=>import("./ch01-preface.html-EhjqE-xm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-41f9c00e":()=>u(()=>import("./ch02-preparation.html-vmCsE7AE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4c013f47":()=>u(()=>import("./ch03-ssh.html-7SR0w9_k.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a75683b8":()=>u(()=>import("./ch04-security.html-AXaKPt5U.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f5341aec":()=>u(()=>import("./ch05-webpage.html-sRW5SJR3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4458f72a":()=>u(()=>import("./ch06-certificates.html-nx5r2spW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f1802e66":()=>u(()=>import("./ch07-xray-server.html-d6fAFDtx.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4ca6f1ca":()=>u(()=>import("./ch08-xray-clients.html--7VTUdFB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-b0030f00":()=>u(()=>import("./ch09-appendix.html-ocawR_gn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-789ba80e":()=>u(()=>import("./index.html-9tqrbw4-.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-103b3e5c":()=>u(()=>import("./fallbacks-lv1.html-Ue5QjCC2.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-110dd688":()=>u(()=>import("./fallbacks-with-sni.html-L4x-DI-J.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c425a7d4":()=>u(()=>import("./routing-lv1-part1.html-uWcVLGTr.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c0bbf696":()=>u(()=>import("./routing-lv1-part2.html-77qV5nP4.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5b6477cc":()=>u(()=>import("./work.html-DIaUDWrM.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-789ba82d":()=>u(()=>import("./index.html-6shuNL--.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-05ddc65d":()=>u(()=>import("./iptables_gid.html-chRdnVmo.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-474afe99":()=>u(()=>import("./nginx_or_haproxy_tls_tunnel.html-0TxfRNOy.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-930ac920":()=>u(()=>import("./redirect.html-FhWJ2sky.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c579975c":()=>u(()=>import("./tproxy.html-ad4fKtf9.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7efb7c68":()=>u(()=>import("./tproxy_ipv4_and_ipv6.html-kIWOgIT3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-12a33bee":()=>u(()=>import("./traffic_stats.html-o6SE99UZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7d2b8478":()=>u(()=>import("./warp.html-4hKe1jqm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7689d7f3":()=>u(()=>import("./transparent_proxy.html-LpjOlZS3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3706649a":()=>u(()=>import("./404.html-r6aI8Oiv.js"),__vite__mapDeps([])).then(({data:e})=>e)},Ou=JSON.parse('{"base":"/","lang":"en-US","title":"","description":"","head":[["link",{"rel":"icon","href":"/logo.png"}]],"locales":{"/":{"lang":"zh-CN","title":"Project X","description":"Xray 官方文档"},"/en/":{"lang":"en-US","title":"Project X","description":"Official document of Xray"}}}');var Au=["link","meta","script","style","noscript","template"],Ru=["title","base"],Iu=([e,t,l])=>Ru.includes(e)?e:Au.includes(e)?e==="meta"&&t.name?`${e}.${t.name}`:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,Object.entries(t).map(([n,i])=>typeof i=="boolean"?i?[n,""]:null:[n,i]).filter(n=>n!=null).sort(([n],[i])=>n.localeCompare(i)),l]):null,Du=e=>{const t=new Set,l=[];return e.forEach(n=>{const i=Iu(n);i&&!t.has(i)&&(t.add(i),l.push(n))}),l},Xl=e=>/^(https?:)?\/\//.test(e),Su=e=>/^[a-z][a-z0-9+.-]*:/.test(e),Ni=e=>Object.prototype.toString.call(e)==="[object Object]",ds=e=>e[e.length-1]==="/"?e.slice(0,-1):e,hs=e=>e[0]==="/"?e.slice(1):e,fs=(e,t)=>{const l=Object.keys(e).sort((n,i)=>{const r=i.split("/").length-n.split("/").length;return r!==0?r:i.length-n.length});for(const n of l)if(t.startsWith(n))return n;return"/"},ju=e=>typeof e=="function",rt=e=>typeof e=="string";const vs={"v-8daa1a0e":g(()=>u(()=>import("./index.html-AMhQDD2G.js"),__vite__mapDeps([]))),"v-aad48c6a":g(()=>u(()=>import("./news.html-Symbtc2m.js"),__vite__mapDeps([]))),"v-f7496066":g(()=>u(()=>import("./index.html-DEQtxzNJ.js"),__vite__mapDeps([]))),"v-ba934fd8":g(()=>u(()=>import("./index.html-_vJQzZ80.js"),__vite__mapDeps([]))),"v-41ade9da":g(()=>u(()=>import("./api.html-Bpdd1mqW.js"),__vite__mapDeps([]))),"v-83dedd38":g(()=>u(()=>import("./dns.html-VxRYmR2X.js"),__vite__mapDeps([]))),"v-192a19b9":g(()=>u(()=>import("./fakedns.html-usFdfR00.js"),__vite__mapDeps([]))),"v-7f6279d8":g(()=>u(()=>import("./inbound.html-xA8fmFfL.js"),__vite__mapDeps([]))),"v-1d860c29":g(()=>u(()=>import("./log.html-6VYWlh7_.js"),__vite__mapDeps([]))),"v-fbaf47ec":g(()=>u(()=>import("./metrics.html-M_EKpCet.js"),__vite__mapDeps([]))),"v-2367d756":g(()=>u(()=>import("./outbound.html-Uyme5CaQ.js"),__vite__mapDeps([]))),"v-4ebec35a":g(()=>u(()=>import("./policy.html-yO5cVi3O.js"),__vite__mapDeps([]))),"v-31b7756a":g(()=>u(()=>import("./reverse.html-kt-Xsscv.js"),__vite__mapDeps([]))),"v-70677432":g(()=>u(()=>import("./routing.html-h85eQ1aY.js"),__vite__mapDeps([]))),"v-7e21d6ae":g(()=>u(()=>import("./stats.html-N9FgSeRj.js"),__vite__mapDeps([]))),"v-e3dfff38":g(()=>u(()=>import("./transport.html-fjf1PegS.js"),__vite__mapDeps([]))),"v-36b1a79b":g(()=>u(()=>import("./index.html-kLtDZulC.js"),__vite__mapDeps([]))),"v-09a64f89":g(()=>u(()=>import("./command.html-MQnx7SGt.js"),__vite__mapDeps([]))),"v-2b1adf48":g(()=>u(()=>import("./config.html-Hj3P0-iE.js"),__vite__mapDeps([]))),"v-86ee963a":g(()=>u(()=>import("./document.html-IBOddkUf.js"),__vite__mapDeps([]))),"v-0e5d7b39":g(()=>u(()=>import("./install.html-Q9rZTV_2.js"),__vite__mapDeps([]))),"v-2d0a870d":g(()=>u(()=>import("./index.html-e3Eb14uc.js"),__vite__mapDeps([]))),"v-6a9e8054":g(()=>u(()=>import("./compile.html-t_m_hch4.js"),__vite__mapDeps([]))),"v-95e3eaea":g(()=>u(()=>import("./design.html-oldCFeI5.js"),__vite__mapDeps([]))),"v-61e7eea6":g(()=>u(()=>import("./guide.html-K0U2knuj.js"),__vite__mapDeps([]))),"v-6e6c37e6":g(()=>u(()=>import("./mkcp.html-KvSr11eW.js"),__vite__mapDeps([]))),"v-13168a21":g(()=>u(()=>import("./muxcool.html-evEdSRWg.js"),__vite__mapDeps([]))),"v-5c48c82b":g(()=>u(()=>import("./vless.html-BeDExndi.js"),__vite__mapDeps([]))),"v-1ee591a8":g(()=>u(()=>import("./vmess.html-3hG8mFqR.js"),__vite__mapDeps([]))),"v-0d714d87":g(()=>u(()=>import("./browser_dialer.html-oocymKeb.js"),__vite__mapDeps([]))),"v-0da7880a":g(()=>u(()=>import("./env.html-UjH5T2XA.js"),__vite__mapDeps([]))),"v-2aeb21f9":g(()=>u(()=>import("./fallback.html-j-WsWvnI.js"),__vite__mapDeps([]))),"v-3acf20ea":g(()=>u(()=>import("./multiple.html-TLF_RZel.js"),__vite__mapDeps([]))),"v-792e28f8":g(()=>u(()=>import("./xtls.html--f-cdwuj.js"),__vite__mapDeps([]))),"v-b50d2334":g(()=>u(()=>import("./dokodemo.html-m7ra4W8c.js"),__vite__mapDeps([]))),"v-593408b0":g(()=>u(()=>import("./http.html-bLJEWSqs.js"),__vite__mapDeps([]))),"v-802a842a":g(()=>u(()=>import("./shadowsocks.html-P4_uET28.js"),__vite__mapDeps([]))),"v-29995cea":g(()=>u(()=>import("./socks.html-NHy_YtOR.js"),__vite__mapDeps([]))),"v-2a1b3d72":g(()=>u(()=>import("./trojan.html-8Xtn_ZhO.js"),__vite__mapDeps([]))),"v-fb92e8aa":g(()=>u(()=>import("./vless.html-atmKcdJ9.js"),__vite__mapDeps([]))),"v-167afaac":g(()=>u(()=>import("./vmess.html-wh0ZrbYC.js"),__vite__mapDeps([]))),"v-749ad71a":g(()=>u(()=>import("./blackhole.html-5o0GnugA.js"),__vite__mapDeps([]))),"v-6d39b970":g(()=>u(()=>import("./dns.html-k6tvDtjK.js"),__vite__mapDeps([]))),"v-d76e893a":g(()=>u(()=>import("./freedom.html-Br08NJvS.js"),__vite__mapDeps([]))),"v-c6b4b59e":g(()=>u(()=>import("./http.html-FQ-Y96ef.js"),__vite__mapDeps([]))),"v-41ec0e0e":g(()=>u(()=>import("./loopback.html-4ZKd-9LO.js"),__vite__mapDeps([]))),"v-7b293e4a":g(()=>u(()=>import("./shadowsocks.html-gizaiMQX.js"),__vite__mapDeps([]))),"v-15f5452a":g(()=>u(()=>import("./socks.html-hTp9HjkK.js"),__vite__mapDeps([]))),"v-5797bdb3":g(()=>u(()=>import("./trojan.html-qii0knEl.js"),__vite__mapDeps([]))),"v-a60f016c":g(()=>u(()=>import("./vless.html-ydRLwf6Z.js"),__vite__mapDeps([]))),"v-413cee4b":g(()=>u(()=>import("./vmess.html-MOyi84fJ.js"),__vite__mapDeps([]))),"v-208ca3b9":g(()=>u(()=>import("./wireguard.html-OyUeeF20.js"),__vite__mapDeps([]))),"v-775db7b1":g(()=>u(()=>import("./domainsocket.html-o3wuPmBS.js"),__vite__mapDeps([]))),"v-2877542a":g(()=>u(()=>import("./grpc.html-owthEglu.js"),__vite__mapDeps([]))),"v-03a28284":g(()=>u(()=>import("./h2.html-Qs5yO4Vz.js"),__vite__mapDeps([]))),"v-04158536":g(()=>u(()=>import("./httpupgrade.html-nQrMkERg.js"),__vite__mapDeps([]))),"v-3167b1dd":g(()=>u(()=>import("./mkcp.html-z0TX3kIH.js"),__vite__mapDeps([]))),"v-8f08dbec":g(()=>u(()=>import("./quic.html-tieiwfcI.js"),__vite__mapDeps([]))),"v-33b1b709":g(()=>u(()=>import("./tcp.html-3jgF7WlU.js"),__vite__mapDeps([]))),"v-1ff57bba":g(()=>u(()=>import("./websocket.html-5im3Rtj5.js"),__vite__mapDeps([]))),"v-3f09dcfa":g(()=>u(()=>import("./index.html-OGTuF_nH.js"),__vite__mapDeps([]))),"v-fb444906":g(()=>u(()=>import("./ch01-preface.html-h3OWqh8J.js"),__vite__mapDeps([]))),"v-075f3ae5":g(()=>u(()=>import("./ch02-preparation.html-nUCvuwbW.js"),__vite__mapDeps([]))),"v-726d0633":g(()=>u(()=>import("./ch03-ssh.html-34HWUQzq.js"),__vite__mapDeps([]))),"v-430c6ab8":g(()=>u(()=>import("./ch04-security.html-tFoBShHh.js"),__vite__mapDeps([]))),"v-717c6376":g(()=>u(()=>import("./ch05-webpage.html-lik4PY0o.js"),__vite__mapDeps([]))),"v-278039be":g(()=>u(()=>import("./ch06-certificates.html-3Wj6Kppi.js"),__vite__mapDeps([]))),"v-a0c7f88e":g(()=>u(()=>import("./ch07-xray-server.html-Cs4sLfUv.js"),__vite__mapDeps([]))),"v-86586ca2":g(()=>u(()=>import("./ch08-xray-clients.html-w9IqqavR.js"),__vite__mapDeps([]))),"v-3eb62514":g(()=>u(()=>import("./ch09-appendix.html-XGC3J-AJ.js"),__vite__mapDeps([]))),"v-3f09dcbc":g(()=>u(()=>import("./index.html-xynTfTar.js"),__vite__mapDeps([]))),"v-b21a2a20":g(()=>u(()=>import("./fallbacks-lv1.html-LXNm8itW.js"),__vite__mapDeps([]))),"v-da623318":g(()=>u(()=>import("./fallbacks-with-sni.html-Hu3dL1kT.js"),__vite__mapDeps([]))),"v-fdd722ac":g(()=>u(()=>import("./routing-lv1-part1.html-XHZo4O7q.js"),__vite__mapDeps([]))),"v-fa6d716e":g(()=>u(()=>import("./routing-lv1-part2.html-JpbPk6FW.js"),__vite__mapDeps([]))),"v-2f29e106":g(()=>u(()=>import("./work.html-5iU00aiu.js"),__vite__mapDeps([]))),"v-3f09dc7e":g(()=>u(()=>import("./index.html-9pCVMb8K.js"),__vite__mapDeps([]))),"v-1c17916e":g(()=>u(()=>import("./iptables_gid.html-PN1dGUsZ.js"),__vite__mapDeps([]))),"v-a001cfa6":g(()=>u(()=>import("./nginx_or_haproxy_tls_tunnel.html-L37cuaZc.js"),__vite__mapDeps([]))),"v-46333b48":g(()=>u(()=>import("./redirect.html-Z0rUViRJ.js"),__vite__mapDeps([]))),"v-338bc63e":g(()=>u(()=>import("./tproxy.html-9M3-wGDd.js"),__vite__mapDeps([]))),"v-d68f7d58":g(()=>u(()=>import("./tproxy_ipv4_and_ipv6.html-dQ2QtiC-.js"),__vite__mapDeps([]))),"v-e533e2c6":g(()=>u(()=>import("./traffic_stats.html-BjBI1-3n.js"),__vite__mapDeps([]))),"v-1e465ab0":g(()=>u(()=>import("./warp.html-co4A2qJl.js"),__vite__mapDeps([]))),"v-1080fb37":g(()=>u(()=>import("./news.html-KjqE-CJP.js"),__vite__mapDeps([]))),"v-317fc580":g(()=>u(()=>import("./index.html-h67PRaMY.js"),__vite__mapDeps([]))),"v-45144c7f":g(()=>u(()=>import("./api.html-ZyK7et4F.js"),__vite__mapDeps([]))),"v-23fbd2d0":g(()=>u(()=>import("./dns.html-KHoheVAl.js"),__vite__mapDeps([]))),"v-2b7ec525":g(()=>u(()=>import("./fakedns.html-aUN-NotP.js"),__vite__mapDeps([]))),"v-5ab92300":g(()=>u(()=>import("./inbound.html-7sY9D7Up.js"),__vite__mapDeps([]))),"v-f91d64d6":g(()=>u(()=>import("./log.html-CNcmi473.js"),__vite__mapDeps([]))),"v-d705f114":g(()=>u(()=>import("./metrics.html-O2MdDQGJ.js"),__vite__mapDeps([]))),"v-268cd669":g(()=>u(()=>import("./outbound.html-pTrUMPv-.js"),__vite__mapDeps([]))),"v-4492d567":g(()=>u(()=>import("./policy.html-nFbqdJoW.js"),__vite__mapDeps([]))),"v-0d0e1e92":g(()=>u(()=>import("./reverse.html-wshR1As_.js"),__vite__mapDeps([]))),"v-4bbe1d5a":g(()=>u(()=>import("./routing.html-xothq4nq.js"),__vite__mapDeps([]))),"v-16426d1a":g(()=>u(()=>import("./stats.html-oDAoa3xt.js"),__vite__mapDeps([]))),"v-5de780d0":g(()=>u(()=>import("./transport.html-w0GXOLfO.js"),__vite__mapDeps([]))),"v-f88d343e":g(()=>u(()=>import("./index.html-glFsxwLj.js"),__vite__mapDeps([]))),"v-38d56a07":g(()=>u(()=>import("./index.html-UNm3UMUZ.js"),__vite__mapDeps([]))),"v-4d046016":g(()=>u(()=>import("./command.html-Q2_pBtQX.js"),__vite__mapDeps([]))),"v-22b35270":g(()=>u(()=>import("./config.html-862ghCov.js"),__vite__mapDeps([]))),"v-30bd7c12":g(()=>u(()=>import("./document.html-tw05mdL_.js"),__vite__mapDeps([]))),"v-439608b6":g(()=>u(()=>import("./install.html-C76Ht-N3.js"),__vite__mapDeps([]))),"v-51a51d87":g(()=>u(()=>import("./transparent_proxy.html-oZsJizmp.js"),__vite__mapDeps([]))),"v-76b9a0f3":g(()=>u(()=>import("./browser_dialer.html-xSfDwx9j.js"),__vite__mapDeps([]))),"v-565dbfc4":g(()=>u(()=>import("./env.html-sFYt-_pK.js"),__vite__mapDeps([]))),"v-0fbd1336":g(()=>u(()=>import("./fallback.html-1NLLtTvN.js"),__vite__mapDeps([]))),"v-a0627812":g(()=>u(()=>import("./multiple.html-1mvnHAHO.js"),__vite__mapDeps([]))),"v-d190d938":g(()=>u(()=>import("./xtls.html-vMAM7WFy.js"),__vite__mapDeps([]))),"v-72afc2d2":g(()=>u(()=>import("./dokodemo.html-p5Zz9pNk.js"),__vite__mapDeps([]))),"v-773d731c":g(()=>u(()=>import("./http.html-TnUHA5fS.js"),__vite__mapDeps([]))),"v-f555fc02":g(()=>u(()=>import("./shadowsocks.html--KkJPTtP.js"),__vite__mapDeps([]))),"v-e35196c2":g(()=>u(()=>import("./socks.html-BHL_zNqv.js"),__vite__mapDeps([]))),"v-29188644":g(()=>u(()=>import("./trojan.html-LeKVwimm.js"),__vite__mapDeps([]))),"v-255a6ebf":g(()=>u(()=>import("./vless.html-3H2ueBQw.js"),__vite__mapDeps([]))),"v-8cc24480":g(()=>u(()=>import("./vmess.html-Ajbfrx88.js"),__vite__mapDeps([]))),"v-64e47ef4":g(()=>u(()=>import("./blackhole.html-_QMN6sZq.js"),__vite__mapDeps([]))),"v-e979b848":g(()=>u(()=>import("./dns.html-FvK6oEVD.js"),__vite__mapDeps([]))),"v-617f0fcf":g(()=>u(()=>import("./freedom.html-uApcqWvy.js"),__vite__mapDeps([]))),"v-3fc98845":g(()=>u(()=>import("./http.html-WXAZvIym.js"),__vite__mapDeps([]))),"v-1b804722":g(()=>u(()=>import("./loopback.html--hPilBz9.js"),__vite__mapDeps([]))),"v-63077cb6":g(()=>u(()=>import("./shadowsocks.html-2vwGKt2T.js"),__vite__mapDeps([]))),"v-516476d4":g(()=>u(()=>import("./socks.html-0nKX1rUP.js"),__vite__mapDeps([]))),"v-7d61a872":g(()=>u(()=>import("./trojan.html-ID_eR97m.js"),__vite__mapDeps([]))),"v-6e50feb6":g(()=>u(()=>import("./vless.html-462FM1ut.js"),__vite__mapDeps([]))),"v-02956db7":g(()=>u(()=>import("./vmess.html-mxEzZ4Nm.js"),__vite__mapDeps([]))),"v-797f8d25":g(()=>u(()=>import("./wireguard.html-yFYoQrs2.js"),__vite__mapDeps([]))),"v-3eb3e9c6":g(()=>u(()=>import("./domainsocket.html-VOdJhZlD.js"),__vite__mapDeps([]))),"v-2c6058d4":g(()=>u(()=>import("./grpc.html-XKtsy_pl.js"),__vite__mapDeps([]))),"v-1c38292a":g(()=>u(()=>import("./h2.html-GaXRW7zG.js"),__vite__mapDeps([]))),"v-17ff144a":g(()=>u(()=>import("./httpupgrade.html-KlUuHOb_.js"),__vite__mapDeps([]))),"v-1a7f9d6e":g(()=>u(()=>import("./mkcp.html-oWZkTGfJ.js"),__vite__mapDeps([]))),"v-79d41176":g(()=>u(()=>import("./quic.html-ES7-n1_Y.js"),__vite__mapDeps([]))),"v-5254cbc6":g(()=>u(()=>import("./tcp.html-boyh_9AY.js"),__vite__mapDeps([]))),"v-9520f392":g(()=>u(()=>import("./websocket.html-YSPsZ2_H.js"),__vite__mapDeps([]))),"v-b7760e2c":g(()=>u(()=>import("./compile.html-QZoJ6y29.js"),__vite__mapDeps([]))),"v-fb774212":g(()=>u(()=>import("./design.html-9OU4NAkY.js"),__vite__mapDeps([]))),"v-38c376c1":g(()=>u(()=>import("./guide.html-C5_iWVEd.js"),__vite__mapDeps([]))),"v-21bccd79":g(()=>u(()=>import("./mkcp.html-8I8osN8v.js"),__vite__mapDeps([]))),"v-27001935":g(()=>u(()=>import("./muxcool.html-Qf6P8rXo.js"),__vite__mapDeps([]))),"v-21b30c3f":g(()=>u(()=>import("./vless.html-hLM6-o-1.js"),__vite__mapDeps([]))),"v-94110980":g(()=>u(()=>import("./vmess.html-gVQqtA6f.js"),__vite__mapDeps([]))),"v-789ba7ef":g(()=>u(()=>import("./index.html-1LatBnTC.js"),__vite__mapDeps([]))),"v-d3712ade":g(()=>u(()=>import("./ch01-preface.html-ltnruxaH.js"),__vite__mapDeps([]))),"v-41f9c00e":g(()=>u(()=>import("./ch02-preparation.html-7bycodSz.js"),__vite__mapDeps([]))),"v-4c013f47":g(()=>u(()=>import("./ch03-ssh.html-kdsftrBp.js"),__vite__mapDeps([]))),"v-a75683b8":g(()=>u(()=>import("./ch04-security.html-fCxnbCda.js"),__vite__mapDeps([]))),"v-f5341aec":g(()=>u(()=>import("./ch05-webpage.html-XwVGqU2C.js"),__vite__mapDeps([]))),"v-4458f72a":g(()=>u(()=>import("./ch06-certificates.html-kGI8p0zP.js"),__vite__mapDeps([]))),"v-f1802e66":g(()=>u(()=>import("./ch07-xray-server.html-vH8VA1RO.js"),__vite__mapDeps([]))),"v-4ca6f1ca":g(()=>u(()=>import("./ch08-xray-clients.html-6ijP-wsT.js"),__vite__mapDeps([]))),"v-b0030f00":g(()=>u(()=>import("./ch09-appendix.html-eMozPKr6.js"),__vite__mapDeps([]))),"v-789ba80e":g(()=>u(()=>import("./index.html-ihOMAxW0.js"),__vite__mapDeps([]))),"v-103b3e5c":g(()=>u(()=>import("./fallbacks-lv1.html-o6nPP3Lr.js"),__vite__mapDeps([]))),"v-110dd688":g(()=>u(()=>import("./fallbacks-with-sni.html-_rwOIQFb.js"),__vite__mapDeps([]))),"v-c425a7d4":g(()=>u(()=>import("./routing-lv1-part1.html-aK2Ox0S3.js"),__vite__mapDeps([]))),"v-c0bbf696":g(()=>u(()=>import("./routing-lv1-part2.html-tkJjuuVl.js"),__vite__mapDeps([]))),"v-5b6477cc":g(()=>u(()=>import("./work.html-rHkxptVO.js"),__vite__mapDeps([]))),"v-789ba82d":g(()=>u(()=>import("./index.html-Mbhofp-W.js"),__vite__mapDeps([]))),"v-05ddc65d":g(()=>u(()=>import("./iptables_gid.html-dUUEZycZ.js"),__vite__mapDeps([]))),"v-474afe99":g(()=>u(()=>import("./nginx_or_haproxy_tls_tunnel.html-2rfRu13n.js"),__vite__mapDeps([]))),"v-930ac920":g(()=>u(()=>import("./redirect.html-J60JFiXJ.js"),__vite__mapDeps([]))),"v-c579975c":g(()=>u(()=>import("./tproxy.html-lyGaCi6Q.js"),__vite__mapDeps([]))),"v-7efb7c68":g(()=>u(()=>import("./tproxy_ipv4_and_ipv6.html-IOus2e7D.js"),__vite__mapDeps([]))),"v-12a33bee":g(()=>u(()=>import("./traffic_stats.html-vi4G-DEd.js"),__vite__mapDeps([]))),"v-7d2b8478":g(()=>u(()=>import("./warp.html-A8L2N42a.js"),__vite__mapDeps([]))),"v-7689d7f3":g(()=>u(()=>import("./transparent_proxy.html-D-ct__hG.js"),__vite__mapDeps([]))),"v-3706649a":g(()=>u(()=>import("./404.html-3GimCU_9.js"),__vite__mapDeps([])))};var Cu=Symbol(""),ps=Symbol(""),Vu=Rn({key:"",path:"",title:"",lang:"",frontmatter:{},headers:[]}),al=()=>{const e=Te(ps);if(!e)throw new Error("pageData() is called without provider.");return e},ms=Symbol(""),_t=()=>{const e=Te(ms);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},gs=Symbol(""),Fu=()=>{const e=Te(gs);if(!e)throw new Error("usePageHead() is called without provider.");return e},Nu=Symbol(""),_s=Symbol(""),Mu=()=>{const e=Te(_s);if(!e)throw new Error("usePageLang() is called without provider.");return e},bs=Symbol(""),Hu=()=>{const e=Te(bs);if(!e)throw new Error("usePageLayout() is called without provider.");return e},$u=ge(wu),Mi=Symbol(""),Gl=()=>{const e=Te(Mi);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},ll=ge(Ou),ks=()=>ll,ys=Symbol(""),Hi=()=>{const e=Te(ys);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},Bu=Symbol(""),zu="Layout",Wu="NotFound",vt=Bl({resolveLayouts:e=>e.reduce((t,l)=>({...t,...l.layouts}),{}),resolvePageData:async e=>{const t=$u.value[e];return await(t==null?void 0:t())??Vu},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,l)=>{const n=rt(t.description)?t.description:l.description,i=[...Array.isArray(t.head)?t.head:[],...l.head,["title",{},e],["meta",{name:"description",content:n}]];return Du(i)},resolvePageHeadTitle:(e,t)=>[e.title,t.title].filter(l=>!!l).join(" | "),resolvePageLang:(e,t)=>e.lang||t.lang||"en-US",resolvePageLayout:(e,t)=>{let l;if(e.path){const n=e.frontmatter.layout;rt(n)?l=n:l=zu}else l=Wu;return t[l]},resolveRouteLocale:(e,t)=>fs(e,t),resolveSiteLocaleData:(e,t)=>{var l;return{...e,...e.locales[t],head:[...((l=e.locales[t])==null?void 0:l.head)??[],...e.head??[]]}}}),$i=pe({name:"ClientOnly",setup(e,t){const l=ge(!1);return ze(()=>{l.value=!0}),()=>{var n,i;return l.value?(i=(n=t.slots).default)==null?void 0:i.call(n):null}}}),Uu=pe({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=al(),l=H(()=>vs[e.pageKey||t.value.key]);return()=>l.value?fe(l.value):fe("div","404 Not Found")}}),Nt=(e={})=>e,Bi=e=>Xl(e)?e:`/${hs(e)}`;function Es(e,t,l){var n,i,r;t===void 0&&(t=50),l===void 0&&(l={});var o=(n=l.isImmediate)!=null&&n,s=(i=l.callback)!=null&&i,a=l.maxWait,c=Date.now(),d=[];function h(){if(a!==void 0){var m=Date.now()-c;if(m+t>=a)return a-m}return t}var f=function(){var m=[].slice.call(arguments),k=this;return new Promise(function(T,w){var I=o&&r===void 0;if(r!==void 0&&clearTimeout(r),r=setTimeout(function(){if(r=void 0,c=Date.now(),!o){var b=e.apply(k,m);s&&s(b),d.forEach(function(E){return(0,E.resolve)(b)}),d=[]}},h()),I){var R=e.apply(k,m);return s&&s(R),T(R)}d.push({resolve:T,reject:w})})};return f.cancel=function(m){r!==void 0&&clearTimeout(r),d.forEach(function(k){return(0,k.reject)(m)}),d=[]},f}/*!
+function _i(e,t){const l=Object.create(null),n=e.split(",");for(let i=0;i!!l[i.toLowerCase()]:i=>!!l[i]}const xe={},nl=[],dt=()=>{},Qs=()=>!1,Hl=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),bi=e=>e.startsWith("onUpdate:"),De=Object.assign,ki=(e,t)=>{const l=e.indexOf(t);l>-1&&e.splice(l,1)},Js=Object.prototype.hasOwnProperty,de=(e,t)=>Js.call(e,t),le=Array.isArray,il=e=>Pn(e)==="[object Map]",vo=e=>Pn(e)==="[object Set]",oe=e=>typeof e=="function",Ae=e=>typeof e=="string",ml=e=>typeof e=="symbol",Ee=e=>e!==null&&typeof e=="object",po=e=>(Ee(e)||oe(e))&&oe(e.then)&&oe(e.catch),mo=Object.prototype.toString,Pn=e=>mo.call(e),Zs=e=>Pn(e).slice(8,-1),go=e=>Pn(e)==="[object Object]",yi=e=>Ae(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,wl=_i(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),wn=e=>{const t=Object.create(null);return l=>t[l]||(t[l]=e(l))},ea=/-(\w)/g,ht=wn(e=>e.replace(ea,(t,l)=>l?l.toUpperCase():"")),ta=/\B([A-Z])/g,Qt=wn(e=>e.replace(ta,"-$1").toLowerCase()),On=wn(e=>e.charAt(0).toUpperCase()+e.slice(1)),Hn=wn(e=>e?`on${On(e)}`:""),Yt=(e,t)=>!Object.is(e,t),$n=(e,t)=>{for(let l=0;l{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:l})},la=e=>{const t=parseFloat(e);return isNaN(t)?e:t},na=e=>{const t=Ae(e)?Number(e):NaN;return isNaN(t)?e:t};let Zi;const li=()=>Zi||(Zi=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});function $l(e){if(le(e)){const t={};for(let l=0;l{if(l){const n=l.split(ra);n.length>1&&(t[n[0].trim()]=n[1].trim())}}),t}function Ke(e){let t="";if(Ae(e))t=e;else if(le(e))for(let l=0;lAe(e)?e:e==null?"":le(e)||Ee(e)&&(e.toString===mo||!oe(e.toString))?JSON.stringify(e,bo,2):String(e),bo=(e,t)=>t&&t.__v_isRef?bo(e,t.value):il(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((l,[n,i],r)=>(l[Bn(n,r)+" =>"]=i,l),{})}:vo(t)?{[`Set(${t.size})`]:[...t.values()].map(l=>Bn(l))}:ml(t)?Bn(t):Ee(t)&&!le(t)&&!go(t)?String(t):t,Bn=(e,t="")=>{var l;return ml(e)?`Symbol(${(l=e.description)!=null?l:t})`:e};let Ge;class ua{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=Ge,!t&&Ge&&(this.index=(Ge.scopes||(Ge.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const l=Ge;try{return Ge=this,t()}finally{Ge=l}}}on(){Ge=this}off(){Ge=this.parent}stop(t){if(this._active){let l,n;for(l=0,n=this.effects.length;l{const t=new Set(e);return t.w=0,t.n=0,t},yo=e=>(e.w&jt)>0,Eo=e=>(e.n&jt)>0,fa=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let l=0;for(let n=0;n{(d==="length"||!ml(d)&&d>=a)&&s.push(c)})}else switch(l!==void 0&&s.push(o.get(l)),t){case"add":le(e)?yi(l)&&s.push(o.get("length")):(s.push(o.get(qt)),il(e)&&s.push(o.get(ii)));break;case"delete":le(e)||(s.push(o.get(qt)),il(e)&&s.push(o.get(ii)));break;case"set":il(e)&&s.push(o.get(qt));break}if(s.length===1)s[0]&&ri(s[0]);else{const a=[];for(const c of s)c&&a.push(...c);ri(Ei(a))}}function ri(e,t){const l=le(e)?e:[...e];for(const n of l)n.computed&&tr(n);for(const n of l)n.computed||tr(n)}function tr(e,t){(e!==nt||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}function pa(e,t){var l;return(l=vn.get(e))==null?void 0:l.get(t)}const ma=_i("__proto__,__v_isRef,__isVue"),To=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(ml)),lr=ga();function ga(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...l){const n=ve(this);for(let r=0,o=this.length;r{e[t]=function(...l){gl();const n=ve(this)[t].apply(this,l);return _l(),n}}),e}function _a(e){const t=ve(this);return qe(t,"has",e),t.hasOwnProperty(e)}class Po{constructor(t=!1,l=!1){this._isReadonly=t,this._shallow=l}get(t,l,n){const i=this._isReadonly,r=this._shallow;if(l==="__v_isReactive")return!i;if(l==="__v_isReadonly")return i;if(l==="__v_isShallow")return r;if(l==="__v_raw")return n===(i?r?Ia:Ro:r?Ao:Oo).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(n)?t:void 0;const o=le(t);if(!i){if(o&&de(lr,l))return Reflect.get(lr,l,n);if(l==="hasOwnProperty")return _a}const s=Reflect.get(t,l,n);return(ml(l)?To.has(l):ma(l))||(i||qe(t,"get",l),r)?s:Me(s)?o&&yi(l)?s:s.value:Ee(s)?i?Rn(s):Bl(s):s}}class wo extends Po{constructor(t=!1){super(!1,t)}set(t,l,n,i){let r=t[l];if(!this._shallow){const a=cl(r);if(!pn(n)&&!cl(n)&&(r=ve(r),n=ve(n)),!le(t)&&Me(r)&&!Me(n))return a?!1:(r.value=n,!0)}const o=le(t)&&yi(l)?Number(l)e,An=e=>Reflect.getPrototypeOf(e);function Yl(e,t,l=!1,n=!1){e=e.__v_raw;const i=ve(e),r=ve(t);l||(Yt(t,r)&&qe(i,"get",t),qe(i,"get",r));const{has:o}=An(i),s=n?Li:l?wi:Sl;if(o.call(i,t))return s(e.get(t));if(o.call(i,r))return s(e.get(r));e!==i&&e.get(t)}function Ql(e,t=!1){const l=this.__v_raw,n=ve(l),i=ve(e);return t||(Yt(e,i)&&qe(n,"has",e),qe(n,"has",i)),e===i?l.has(e):l.has(e)||l.has(i)}function Jl(e,t=!1){return e=e.__v_raw,!t&&qe(ve(e),"iterate",qt),Reflect.get(e,"size",e)}function nr(e){e=ve(e);const t=ve(this);return An(t).has.call(t,e)||(t.add(e),gt(t,"add",e,e)),this}function ir(e,t){t=ve(t);const l=ve(this),{has:n,get:i}=An(l);let r=n.call(l,e);r||(e=ve(e),r=n.call(l,e));const o=i.call(l,e);return l.set(e,t),r?Yt(t,o)&>(l,"set",e,t):gt(l,"add",e,t),this}function rr(e){const t=ve(this),{has:l,get:n}=An(t);let i=l.call(t,e);i||(e=ve(e),i=l.call(t,e)),n&&n.call(t,e);const r=t.delete(e);return i&>(t,"delete",e,void 0),r}function or(){const e=ve(this),t=e.size!==0,l=e.clear();return t&>(e,"clear",void 0,void 0),l}function Zl(e,t){return function(n,i){const r=this,o=r.__v_raw,s=ve(o),a=t?Li:e?wi:Sl;return!e&&qe(s,"iterate",qt),o.forEach((c,d)=>n.call(i,a(c),a(d),r))}}function en(e,t,l){return function(...n){const i=this.__v_raw,r=ve(i),o=il(r),s=e==="entries"||e===Symbol.iterator&&o,a=e==="keys"&&o,c=i[e](...n),d=l?Li:t?wi:Sl;return!t&&qe(r,"iterate",a?ii:qt),{next(){const{value:h,done:f}=c.next();return f?{value:h,done:f}:{value:s?[d(h[0]),d(h[1])]:d(h),done:f}},[Symbol.iterator](){return this}}}}function Tt(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function xa(){const e={get(r){return Yl(this,r)},get size(){return Jl(this)},has:Ql,add:nr,set:ir,delete:rr,clear:or,forEach:Zl(!1,!1)},t={get(r){return Yl(this,r,!1,!0)},get size(){return Jl(this)},has:Ql,add:nr,set:ir,delete:rr,clear:or,forEach:Zl(!1,!0)},l={get(r){return Yl(this,r,!0)},get size(){return Jl(this,!0)},has(r){return Ql.call(this,r,!0)},add:Tt("add"),set:Tt("set"),delete:Tt("delete"),clear:Tt("clear"),forEach:Zl(!0,!1)},n={get(r){return Yl(this,r,!0,!0)},get size(){return Jl(this,!0)},has(r){return Ql.call(this,r,!0)},add:Tt("add"),set:Tt("set"),delete:Tt("delete"),clear:Tt("clear"),forEach:Zl(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(r=>{e[r]=en(r,!1,!1),l[r]=en(r,!0,!1),t[r]=en(r,!1,!0),n[r]=en(r,!0,!0)}),[e,l,t,n]}const[La,Ta,Pa,wa]=xa();function Ti(e,t){const l=t?e?wa:Pa:e?Ta:La;return(n,i,r)=>i==="__v_isReactive"?!e:i==="__v_isReadonly"?e:i==="__v_raw"?n:Reflect.get(de(l,i)&&i in n?l:n,i,r)}const Oa={get:Ti(!1,!1)},Aa={get:Ti(!1,!0)},Ra={get:Ti(!0,!1)},Oo=new WeakMap,Ao=new WeakMap,Ro=new WeakMap,Ia=new WeakMap;function Da(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Sa(e){return e.__v_skip||!Object.isExtensible(e)?0:Da(Zs(e))}function Bl(e){return cl(e)?e:Pi(e,!1,ka,Oa,Oo)}function Io(e){return Pi(e,!1,Ea,Aa,Ao)}function Rn(e){return Pi(e,!0,ya,Ra,Ro)}function Pi(e,t,l,n,i){if(!Ee(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const r=i.get(e);if(r)return r;const o=Sa(e);if(o===0)return e;const s=new Proxy(e,o===2?n:l);return i.set(e,s),s}function rl(e){return cl(e)?rl(e.__v_raw):!!(e&&e.__v_isReactive)}function cl(e){return!!(e&&e.__v_isReadonly)}function pn(e){return!!(e&&e.__v_isShallow)}function Do(e){return rl(e)||cl(e)}function ve(e){const t=e&&e.__v_raw;return t?ve(t):e}function So(e){return fn(e,"__v_skip",!0),e}const Sl=e=>Ee(e)?Bl(e):e,wi=e=>Ee(e)?Rn(e):e;function Oi(e){Dt&&nt&&(e=ve(e),Lo(e.dep||(e.dep=Ei())))}function Ai(e,t){e=ve(e);const l=e.dep;l&&ri(l)}function Me(e){return!!(e&&e.__v_isRef===!0)}function ge(e){return Co(e,!1)}function jo(e){return Co(e,!0)}function Co(e,t){return Me(e)?e:new ja(e,t)}class ja{constructor(t,l){this.__v_isShallow=l,this.dep=void 0,this.__v_isRef=!0,this._rawValue=l?t:ve(t),this._value=l?t:Sl(t)}get value(){return Oi(this),this._value}set value(t){const l=this.__v_isShallow||pn(t)||cl(t);t=l?t:ve(t),Yt(t,this._rawValue)&&(this._rawValue=t,this._value=l?t:Sl(t),Ai(this))}}function te(e){return Me(e)?e.value:e}const Ca={get:(e,t,l)=>te(Reflect.get(e,t,l)),set:(e,t,l,n)=>{const i=e[t];return Me(i)&&!Me(l)?(i.value=l,!0):Reflect.set(e,t,l,n)}};function Vo(e){return rl(e)?e:new Proxy(e,Ca)}class Va{constructor(t){this.dep=void 0,this.__v_isRef=!0;const{get:l,set:n}=t(()=>Oi(this),()=>Ai(this));this._get=l,this._set=n}get value(){return this._get()}set value(t){this._set(t)}}function Fa(e){return new Va(e)}function In(e){const t=le(e)?new Array(e.length):{};for(const l in e)t[l]=Fo(e,l);return t}class Na{constructor(t,l,n){this._object=t,this._key=l,this._defaultValue=n,this.__v_isRef=!0}get value(){const t=this._object[this._key];return t===void 0?this._defaultValue:t}set value(t){this._object[this._key]=t}get dep(){return pa(ve(this._object),this._key)}}class Ma{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0}get value(){return this._getter()}}function Sp(e,t,l){return Me(e)?e:oe(e)?new Ma(e):Ee(e)&&arguments.length>1?Fo(e,t,l):ge(e)}function Fo(e,t,l){const n=e[t];return Me(n)?n:new Na(e,t,l)}class Ha{constructor(t,l,n,i){this._setter=l,this.dep=void 0,this.__v_isRef=!0,this.__v_isReadonly=!1,this._dirty=!0,this.effect=new xi(t,()=>{this._dirty||(this._dirty=!0,Ai(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!i,this.__v_isReadonly=n}get value(){const t=ve(this);return Oi(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}function $a(e,t,l=!1){let n,i;const r=oe(e);return r?(n=e,i=dt):(n=e.get,i=e.set),new Ha(n,i,r||!i,l)}function St(e,t,l,n){let i;try{i=n?e(...n):e()}catch(r){zl(r,t,l)}return i}function et(e,t,l,n){if(oe(e)){const r=St(e,t,l,n);return r&&po(r)&&r.catch(o=>{zl(o,t,l)}),r}const i=[];for(let r=0;r>>1,i=$e[n],r=Cl(i);rut&&$e.splice(t,1)}function Ua(e){le(e)?ol.push(...e):(!mt||!mt.includes(e,e.allowRecurse?zt+1:zt))&&ol.push(e),Mo()}function sr(e,t,l=jl?ut+1:0){for(;l<$e.length;l++){const n=$e[l];if(n&&n.pre){if(e&&n.id!==e.uid)continue;$e.splice(l,1),l--,n()}}}function mn(e){if(ol.length){const t=[...new Set(ol)];if(ol.length=0,mt){mt.push(...t);return}for(mt=t,mt.sort((l,n)=>Cl(l)-Cl(n)),zt=0;zte.id==null?1/0:e.id,Ka=(e,t)=>{const l=Cl(e)-Cl(t);if(l===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return l};function Ho(e){oi=!1,jl=!0,$e.sort(Ka);try{for(ut=0;ut<$e.length;ut++){const t=$e[ut];t&&t.active!==!1&&St(t,null,14)}}finally{ut=0,$e.length=0,mn(),jl=!1,Ri=null,($e.length||ol.length)&&Ho()}}function qa(e,t,...l){if(e.isUnmounted)return;const n=e.vnode.props||xe;let i=l;const r=t.startsWith("update:"),o=r&&t.slice(7);if(o&&o in n){const d=`${o==="modelValue"?"model":o}Modifiers`,{number:h,trim:f}=n[d]||xe;f&&(i=l.map(m=>Ae(m)?m.trim():m)),h&&(i=l.map(la))}let s,a=n[s=Hn(t)]||n[s=Hn(ht(t))];!a&&r&&(a=n[s=Hn(Qt(t))]),a&&et(a,e,6,i);const c=n[s+"Once"];if(c){if(!e.emitted)e.emitted={};else if(e.emitted[s])return;e.emitted[s]=!0,et(c,e,6,i)}}function $o(e,t,l=!1){const n=t.emitsCache,i=n.get(e);if(i!==void 0)return i;const r=e.emits;let o={},s=!1;if(!oe(e)){const a=c=>{const d=$o(c,t,!0);d&&(s=!0,De(o,d))};!l&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!r&&!s?(Ee(e)&&n.set(e,null),null):(le(r)?r.forEach(a=>o[a]=null):De(o,r),Ee(e)&&n.set(e,o),o)}function Sn(e,t){return!e||!Hl(t)?!1:(t=t.slice(2).replace(/Once$/,""),de(e,t[0].toLowerCase()+t.slice(1))||de(e,Qt(t))||de(e,t))}let Fe=null,Bo=null;function gn(e){const t=Fe;return Fe=e,Bo=e&&e.type.__scopeId||null,t}function Ve(e,t=Fe,l){if(!t||e._n)return e;const n=(...i)=>{n._d&&br(-1);const r=gn(t);let o;try{o=e(...i)}finally{gn(r),n._d&&br(1)}return o};return n._n=!0,n._c=!0,n._d=!0,n}function zn(e){const{type:t,vnode:l,proxy:n,withProxy:i,props:r,propsOptions:[o],slots:s,attrs:a,emit:c,render:d,renderCache:h,data:f,setupState:m,ctx:k,inheritAttrs:T}=e;let w,I;const R=gn(e);try{if(l.shapeFlag&4){const E=i||n,F=E;w=lt(d.call(F,E,h,r,m,f,k)),I=a}else{const E=t;w=lt(E.length>1?E(r,{attrs:a,slots:s,emit:c}):E(r,null)),I=t.props?a:Xa(a)}}catch(E){Rl.length=0,zl(E,e,1),w=ie(Qe)}let b=w;if(I&&T!==!1){const E=Object.keys(I),{shapeFlag:F}=b;E.length&&F&7&&(o&&E.some(bi)&&(I=Ga(I,o)),b=Vt(b,I))}return l.dirs&&(b=Vt(b),b.dirs=b.dirs?b.dirs.concat(l.dirs):l.dirs),l.transition&&(b.transition=l.transition),w=b,gn(R),w}const Xa=e=>{let t;for(const l in e)(l==="class"||l==="style"||Hl(l))&&((t||(t={}))[l]=e[l]);return t},Ga=(e,t)=>{const l={};for(const n in e)(!bi(n)||!(n.slice(9)in t))&&(l[n]=e[n]);return l};function Ya(e,t,l){const{props:n,children:i,component:r}=e,{props:o,children:s,patchFlag:a}=t,c=r.emitsOptions;if(t.dirs||t.transition)return!0;if(l&&a>=0){if(a&1024)return!0;if(a&16)return n?ar(n,o,c):!!o;if(a&8){const d=t.dynamicProps;for(let h=0;he.__isSuspense;function Wo(e,t){t&&t.pendingBranch?le(e)?t.effects.push(...e):t.effects.push(e):Ua(e)}function tc(e,t){return Ii(e,null,t)}const tn={};function Ye(e,t,l){return Ii(e,t,l)}function Ii(e,t,{immediate:l,deep:n,flush:i,onTrack:r,onTrigger:o}=xe){var s;const a=ko()===((s=Re)==null?void 0:s.scope)?Re:null;let c,d=!1,h=!1;if(Me(e)?(c=()=>e.value,d=pn(e)):rl(e)?(c=()=>e,n=!0):le(e)?(h=!0,d=e.some(E=>rl(E)||pn(E)),c=()=>e.map(E=>{if(Me(E))return E.value;if(rl(E))return Kt(E);if(oe(E))return St(E,a,2)})):oe(e)?t?c=()=>St(e,a,2):c=()=>{if(!(a&&a.isUnmounted))return f&&f(),et(e,a,3,[m])}:c=dt,t&&n){const E=c;c=()=>Kt(E())}let f,m=E=>{f=R.onStop=()=>{St(E,a,4),f=R.onStop=void 0}},k;if(hl)if(m=dt,t?l&&et(t,a,3,[c(),h?[]:void 0,m]):c(),i==="sync"){const E=Xc();k=E.__watcherHandles||(E.__watcherHandles=[])}else return dt;let T=h?new Array(e.length).fill(tn):tn;const w=()=>{if(R.active)if(t){const E=R.run();(n||d||(h?E.some((F,G)=>Yt(F,T[G])):Yt(E,T)))&&(f&&f(),et(t,a,3,[E,T===tn?void 0:h&&T[0]===tn?[]:T,m]),T=E)}else R.run()};w.allowRecurse=!!t;let I;i==="sync"?I=w:i==="post"?I=()=>Ue(w,a&&a.suspense):(w.pre=!0,a&&(w.id=a.uid),I=()=>Dn(w));const R=new xi(c,I);t?l?w():T=R.run():i==="post"?Ue(R.run.bind(R),a&&a.suspense):R.run();const b=()=>{R.stop(),a&&a.scope&&ki(a.scope.effects,R)};return k&&k.push(b),b}function lc(e,t,l){const n=this.proxy,i=Ae(e)?e.includes(".")?Uo(n,e):()=>n[e]:e.bind(n,n);let r;oe(t)?r=t:(r=t.handler,l=t);const o=Re;dl(this);const s=Ii(i,r.bind(n),l);return o?dl(o):Gt(),s}function Uo(e,t){const l=t.split(".");return()=>{let n=e;for(let i=0;i{Kt(l,t)});else if(go(e))for(const l in e)Kt(e[l],t);return e}function _n(e,t){const l=Fe;if(l===null)return e;const n=Fn(l)||l.proxy,i=e.dirs||(e.dirs=[]);for(let r=0;r{e.isMounted=!0}),Kl(()=>{e.isUnmounting=!0}),e}const Je=[Function,Array],Ko={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Je,onEnter:Je,onAfterEnter:Je,onEnterCancelled:Je,onBeforeLeave:Je,onLeave:Je,onAfterLeave:Je,onLeaveCancelled:Je,onBeforeAppear:Je,onAppear:Je,onAfterAppear:Je,onAppearCancelled:Je},ic={name:"BaseTransition",props:Ko,setup(e,{slots:t}){const l=Ci(),n=nc();let i;return()=>{const r=t.default&&Xo(t.default(),!0);if(!r||!r.length)return;let o=r[0];if(r.length>1){for(const T of r)if(T.type!==Qe){o=T;break}}const s=ve(e),{mode:a}=s;if(n.isLeaving)return Wn(o);const c=ur(o);if(!c)return Wn(o);const d=si(c,s,n,l);ai(c,d);const h=l.subTree,f=h&&ur(h);let m=!1;const{getTransitionKey:k}=c.type;if(k){const T=k();i===void 0?i=T:T!==i&&(i=T,m=!0)}if(f&&f.type!==Qe&&(!Wt(c,f)||m)){const T=si(f,s,n,l);if(ai(f,T),a==="out-in")return n.isLeaving=!0,T.afterLeave=()=>{n.isLeaving=!1,l.update.active!==!1&&l.update()},Wn(o);a==="in-out"&&c.type!==Qe&&(T.delayLeave=(w,I,R)=>{const b=qo(n,f);b[String(f.key)]=f,w[At]=()=>{I(),w[At]=void 0,delete d.delayedLeave},d.delayedLeave=R})}return o}}},rc=ic;function qo(e,t){const{leavingVNodes:l}=e;let n=l.get(t.type);return n||(n=Object.create(null),l.set(t.type,n)),n}function si(e,t,l,n){const{appear:i,mode:r,persisted:o=!1,onBeforeEnter:s,onEnter:a,onAfterEnter:c,onEnterCancelled:d,onBeforeLeave:h,onLeave:f,onAfterLeave:m,onLeaveCancelled:k,onBeforeAppear:T,onAppear:w,onAfterAppear:I,onAppearCancelled:R}=t,b=String(e.key),E=qo(l,e),F=(y,q)=>{y&&et(y,n,9,q)},G=(y,q)=>{const O=q[1];F(y,q),le(y)?y.every(W=>W.length<=1)&&O():y.length<=1&&O()},N={mode:r,persisted:o,beforeEnter(y){let q=s;if(!l.isMounted)if(i)q=T||s;else return;y[At]&&y[At](!0);const O=E[b];O&&Wt(e,O)&&O.el[At]&&O.el[At](),F(q,[y])},enter(y){let q=a,O=c,W=d;if(!l.isMounted)if(i)q=w||a,O=I||c,W=R||d;else return;let x=!1;const C=y[ln]=ne=>{x||(x=!0,ne?F(W,[y]):F(O,[y]),N.delayedLeave&&N.delayedLeave(),y[ln]=void 0)};q?G(q,[y,C]):C()},leave(y,q){const O=String(e.key);if(y[ln]&&y[ln](!0),l.isUnmounting)return q();F(h,[y]);let W=!1;const x=y[At]=C=>{W||(W=!0,q(),C?F(k,[y]):F(m,[y]),y[At]=void 0,E[O]===e&&delete E[O])};E[O]=e,f?G(f,[y,x]):x()},clone(y){return si(y,t,l,n)}};return N}function Wn(e){if(Ul(e))return e=Vt(e),e.children=null,e}function ur(e){return Ul(e)?e.children?e.children[0]:void 0:e}function ai(e,t){e.shapeFlag&6&&e.component?ai(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function Xo(e,t=!1,l){let n=[],i=0;for(let r=0;r1)for(let r=0;r!!e.type.__asyncLoader;/*! #__NO_SIDE_EFFECTS__ */function g(e){oe(e)&&(e={loader:e});const{loader:t,loadingComponent:l,errorComponent:n,delay:i=200,timeout:r,suspensible:o=!0,onError:s}=e;let a=null,c,d=0;const h=()=>(d++,a=null,f()),f=()=>{let m;return a||(m=a=t().catch(k=>{if(k=k instanceof Error?k:new Error(String(k)),s)return new Promise((T,w)=>{s(k,()=>T(h()),()=>w(k),d+1)});throw k}).then(k=>m!==a&&a?a:(k&&(k.__esModule||k[Symbol.toStringTag]==="Module")&&(k=k.default),c=k,k)))};return pe({name:"AsyncComponentWrapper",__asyncLoader:f,get __asyncResolved(){return c},setup(){const m=Re;if(c)return()=>Un(c,m);const k=R=>{a=null,zl(R,m,13,!n)};if(o&&m.suspense||hl)return f().then(R=>()=>Un(R,m)).catch(R=>(k(R),()=>n?ie(n,{error:R}):null));const T=ge(!1),w=ge(),I=ge(!!i);return i&&setTimeout(()=>{I.value=!1},i),r!=null&&setTimeout(()=>{if(!T.value&&!w.value){const R=new Error(`Async component timed out after ${r}ms.`);k(R),w.value=R}},r),f().then(()=>{T.value=!0,m.parent&&Ul(m.parent.vnode)&&Dn(m.parent.update)}).catch(R=>{k(R),w.value=R}),()=>{if(T.value&&c)return Un(c,m);if(w.value&&n)return ie(n,{error:w.value});if(l&&!I.value)return ie(l)}}})}function Un(e,t){const{ref:l,props:n,children:i,ce:r}=t.vnode,o=ie(e,n,i);return o.ref=l,o.ce=r,delete t.vnode.ce,o}const Ul=e=>e.type.__isKeepAlive;function oc(e,t){Go(e,"a",t)}function sc(e,t){Go(e,"da",t)}function Go(e,t,l=Re){const n=e.__wdc||(e.__wdc=()=>{let i=l;for(;i;){if(i.isDeactivated)return;i=i.parent}return e()});if(jn(t,n,l),l){let i=l.parent;for(;i&&i.parent;)Ul(i.parent.vnode)&&ac(n,t,l,i),i=i.parent}}function ac(e,t,l,n){const i=jn(t,e,n,!0);Cn(()=>{ki(n[t],i)},l)}function jn(e,t,l=Re,n=!1){if(l){const i=l[e]||(l[e]=[]),r=t.__weh||(t.__weh=(...o)=>{if(l.isUnmounted)return;gl(),dl(l);const s=et(t,l,e,o);return Gt(),_l(),s});return n?i.unshift(r):i.push(r),r}}const Et=e=>(t,l=Re)=>(!hl||e==="sp")&&jn(e,(...n)=>t(...n),l),cc=Et("bm"),ze=Et("m"),uc=Et("bu"),dc=Et("u"),Kl=Et("bum"),Cn=Et("um"),hc=Et("sp"),fc=Et("rtg"),vc=Et("rtc");function pc(e,t=Re){jn("ec",e,t)}function Ct(e,t,l,n){let i;const r=l&&l[n];if(le(e)||Ae(e)){i=new Array(e.length);for(let o=0,s=e.length;ot(o,s,void 0,r&&r[s]));else{const o=Object.keys(e);i=new Array(o.length);for(let s=0,a=o.length;sEn(t)?!(t.type===Qe||t.type===ye&&!Yo(t.children)):!0)?e:null}const ci=e=>e?as(e)?Fn(e)||e.proxy:ci(e.parent):null,Ol=De(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>ci(e.parent),$root:e=>ci(e.root),$emit:e=>e.emit,$options:e=>Di(e),$forceUpdate:e=>e.f||(e.f=()=>Dn(e.update)),$nextTick:e=>e.n||(e.n=Wl.bind(e.proxy)),$watch:e=>lc.bind(e)}),Kn=(e,t)=>e!==xe&&!e.__isScriptSetup&&de(e,t),mc={get({_:e},t){const{ctx:l,setupState:n,data:i,props:r,accessCache:o,type:s,appContext:a}=e;let c;if(t[0]!=="$"){const m=o[t];if(m!==void 0)switch(m){case 1:return n[t];case 2:return i[t];case 4:return l[t];case 3:return r[t]}else{if(Kn(n,t))return o[t]=1,n[t];if(i!==xe&&de(i,t))return o[t]=2,i[t];if((c=e.propsOptions[0])&&de(c,t))return o[t]=3,r[t];if(l!==xe&&de(l,t))return o[t]=4,l[t];ui&&(o[t]=0)}}const d=Ol[t];let h,f;if(d)return t==="$attrs"&&qe(e,"get",t),d(e);if((h=s.__cssModules)&&(h=h[t]))return h;if(l!==xe&&de(l,t))return o[t]=4,l[t];if(f=a.config.globalProperties,de(f,t))return f[t]},set({_:e},t,l){const{data:n,setupState:i,ctx:r}=e;return Kn(i,t)?(i[t]=l,!0):n!==xe&&de(n,t)?(n[t]=l,!0):de(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(r[t]=l,!0)},has({_:{data:e,setupState:t,accessCache:l,ctx:n,appContext:i,propsOptions:r}},o){let s;return!!l[o]||e!==xe&&de(e,o)||Kn(t,o)||(s=r[0])&&de(s,o)||de(n,o)||de(Ol,o)||de(i.config.globalProperties,o)},defineProperty(e,t,l){return l.get!=null?e._.accessCache[t]=0:de(l,"value")&&this.set(e,t,l.value,null),Reflect.defineProperty(e,t,l)}};function dr(e){return le(e)?e.reduce((t,l)=>(t[l]=null,t),{}):e}let ui=!0;function gc(e){const t=Di(e),l=e.proxy,n=e.ctx;ui=!1,t.beforeCreate&&hr(t.beforeCreate,e,"bc");const{data:i,computed:r,methods:o,watch:s,provide:a,inject:c,created:d,beforeMount:h,mounted:f,beforeUpdate:m,updated:k,activated:T,deactivated:w,beforeDestroy:I,beforeUnmount:R,destroyed:b,unmounted:E,render:F,renderTracked:G,renderTriggered:N,errorCaptured:y,serverPrefetch:q,expose:O,inheritAttrs:W,components:x,directives:C,filters:ne}=t;if(c&&_c(c,n,null),o)for(const Q in o){const K=o[Q];oe(K)&&(n[Q]=K.bind(l))}if(i){const Q=i.call(l,l);Ee(Q)&&(e.data=Bl(Q))}if(ui=!0,r)for(const Q in r){const K=r[Q],Se=oe(K)?K.bind(l,l):oe(K.get)?K.get.bind(l,l):dt,Ce=!oe(K)&&oe(K.set)?K.set.bind(l):dt,We=H({get:Se,set:Ce});Object.defineProperty(n,Q,{enumerable:!0,configurable:!0,get:()=>We.value,set:He=>We.value=He})}if(s)for(const Q in s)Qo(s[Q],n,l,Q);if(a){const Q=oe(a)?a.call(l):a;Reflect.ownKeys(Q).forEach(K=>{Xt(K,Q[K])})}d&&hr(d,e,"c");function j(Q,K){le(K)?K.forEach(Se=>Q(Se.bind(l))):K&&Q(K.bind(l))}if(j(cc,h),j(ze,f),j(uc,m),j(dc,k),j(oc,T),j(sc,w),j(pc,y),j(vc,G),j(fc,N),j(Kl,R),j(Cn,E),j(hc,q),le(O))if(O.length){const Q=e.exposed||(e.exposed={});O.forEach(K=>{Object.defineProperty(Q,K,{get:()=>l[K],set:Se=>l[K]=Se})})}else e.exposed||(e.exposed={});F&&e.render===dt&&(e.render=F),W!=null&&(e.inheritAttrs=W),x&&(e.components=x),C&&(e.directives=C)}function _c(e,t,l=dt){le(e)&&(e=di(e));for(const n in e){const i=e[n];let r;Ee(i)?"default"in i?r=Te(i.from||n,i.default,!0):r=Te(i.from||n):r=Te(i),Me(r)?Object.defineProperty(t,n,{enumerable:!0,configurable:!0,get:()=>r.value,set:o=>r.value=o}):t[n]=r}}function hr(e,t,l){et(le(e)?e.map(n=>n.bind(t.proxy)):e.bind(t.proxy),t,l)}function Qo(e,t,l,n){const i=n.includes(".")?Uo(l,n):()=>l[n];if(Ae(e)){const r=t[e];oe(r)&&Ye(i,r)}else if(oe(e))Ye(i,e.bind(l));else if(Ee(e))if(le(e))e.forEach(r=>Qo(r,t,l,n));else{const r=oe(e.handler)?e.handler.bind(l):t[e.handler];oe(r)&&Ye(i,r,e)}}function Di(e){const t=e.type,{mixins:l,extends:n}=t,{mixins:i,optionsCache:r,config:{optionMergeStrategies:o}}=e.appContext,s=r.get(t);let a;return s?a=s:!i.length&&!l&&!n?a=t:(a={},i.length&&i.forEach(c=>bn(a,c,o,!0)),bn(a,t,o)),Ee(t)&&r.set(t,a),a}function bn(e,t,l,n=!1){const{mixins:i,extends:r}=t;r&&bn(e,r,l,!0),i&&i.forEach(o=>bn(e,o,l,!0));for(const o in t)if(!(n&&o==="expose")){const s=bc[o]||l&&l[o];e[o]=s?s(e[o],t[o]):t[o]}return e}const bc={data:fr,props:vr,emits:vr,methods:Pl,computed:Pl,beforeCreate:Be,created:Be,beforeMount:Be,mounted:Be,beforeUpdate:Be,updated:Be,beforeDestroy:Be,beforeUnmount:Be,destroyed:Be,unmounted:Be,activated:Be,deactivated:Be,errorCaptured:Be,serverPrefetch:Be,components:Pl,directives:Pl,watch:yc,provide:fr,inject:kc};function fr(e,t){return t?e?function(){return De(oe(e)?e.call(this,this):e,oe(t)?t.call(this,this):t)}:t:e}function kc(e,t){return Pl(di(e),di(t))}function di(e){if(le(e)){const t={};for(let l=0;l1)return l&&oe(t)?t.call(n&&n.proxy):t}}function Lc(e,t,l,n=!1){const i={},r={};fn(r,Vn,1),e.propsDefaults=Object.create(null),Zo(e,t,i,r);for(const o in e.propsOptions[0])o in i||(i[o]=void 0);l?e.props=n?i:Io(i):e.type.props?e.props=i:e.props=r,e.attrs=r}function Tc(e,t,l,n){const{props:i,attrs:r,vnode:{patchFlag:o}}=e,s=ve(i),[a]=e.propsOptions;let c=!1;if((n||o>0)&&!(o&16)){if(o&8){const d=e.vnode.dynamicProps;for(let h=0;h{a=!0;const[f,m]=es(h,t,!0);De(o,f),m&&s.push(...m)};!l&&t.mixins.length&&t.mixins.forEach(d),e.extends&&d(e.extends),e.mixins&&e.mixins.forEach(d)}if(!r&&!a)return Ee(e)&&n.set(e,nl),nl;if(le(r))for(let d=0;d-1,m[1]=T<0||k-1||de(m,"default"))&&s.push(h)}}}const c=[o,s];return Ee(e)&&n.set(e,c),c}function pr(e){return e[0]!=="$"}function mr(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function gr(e,t){return mr(e)===mr(t)}function _r(e,t){return le(t)?t.findIndex(l=>gr(l,e)):oe(t)&&gr(t,e)?0:-1}const ts=e=>e[0]==="_"||e==="$stable",Si=e=>le(e)?e.map(lt):[lt(e)],Pc=(e,t,l)=>{if(t._n)return t;const n=Ve((...i)=>Si(t(...i)),l);return n._c=!1,n},ls=(e,t,l)=>{const n=e._ctx;for(const i in e){if(ts(i))continue;const r=e[i];if(oe(r))t[i]=Pc(i,r,n);else if(r!=null){const o=Si(r);t[i]=()=>o}}},ns=(e,t)=>{const l=Si(t);e.slots.default=()=>l},wc=(e,t)=>{if(e.vnode.shapeFlag&32){const l=t._;l?(e.slots=ve(t),fn(t,"_",l)):ls(t,e.slots={})}else e.slots={},t&&ns(e,t);fn(e.slots,Vn,1)},Oc=(e,t,l)=>{const{vnode:n,slots:i}=e;let r=!0,o=xe;if(n.shapeFlag&32){const s=t._;s?l&&s===1?r=!1:(De(i,t),!l&&s===1&&delete i._):(r=!t.$stable,ls(t,i)),o=t}else t&&(ns(e,t),o={default:1});if(r)for(const s in i)!ts(s)&&o[s]==null&&delete i[s]};function yn(e,t,l,n,i=!1){if(le(e)){e.forEach((f,m)=>yn(f,t&&(le(t)?t[m]:t),l,n,i));return}if(sl(n)&&!i)return;const r=n.shapeFlag&4?Fn(n.component)||n.component.proxy:n.el,o=i?null:r,{i:s,r:a}=e,c=t&&t.r,d=s.refs===xe?s.refs={}:s.refs,h=s.setupState;if(c!=null&&c!==a&&(Ae(c)?(d[c]=null,de(h,c)&&(h[c]=null)):Me(c)&&(c.value=null)),oe(a))St(a,s,12,[o,d]);else{const f=Ae(a),m=Me(a);if(f||m){const k=()=>{if(e.f){const T=f?de(h,a)?h[a]:d[a]:a.value;i?le(T)&&ki(T,r):le(T)?T.includes(r)||T.push(r):f?(d[a]=[r],de(h,a)&&(h[a]=d[a])):(a.value=[r],e.k&&(d[e.k]=a.value))}else f?(d[a]=o,de(h,a)&&(h[a]=o)):m&&(a.value=o,e.k&&(d[e.k]=o))};o?(k.id=-1,Ue(k,l)):k()}}}let Pt=!1;const nn=e=>/svg/.test(e.namespaceURI)&&e.tagName!=="foreignObject",rn=e=>e.nodeType===8;function Ac(e){const{mt:t,p:l,o:{patchProp:n,createText:i,nextSibling:r,parentNode:o,remove:s,insert:a,createComment:c}}=e,d=(b,E)=>{if(!E.hasChildNodes()){l(null,b,E),mn(),E._vnode=b;return}Pt=!1,h(E.firstChild,b,null,null,null),mn(),E._vnode=b,Pt&&console.error("Hydration completed but contains mismatches.")},h=(b,E,F,G,N,y=!1)=>{const q=rn(b)&&b.data==="[",O=()=>T(b,E,F,G,N,q),{type:W,ref:x,shapeFlag:C,patchFlag:ne}=E;let se=b.nodeType;E.el=b,ne===-2&&(y=!1,E.dynamicChildren=null);let j=null;switch(W){case ul:se!==3?E.children===""?(a(E.el=i(""),o(b),b),j=b):j=O():(b.data!==E.children&&(Pt=!0,b.data=E.children),j=r(b));break;case Qe:R(b)?(j=r(b),I(E.el=b.content.firstChild,b,F)):se!==8||q?j=O():j=r(b);break;case Al:if(q&&(b=r(b),se=b.nodeType),se===1||se===3){j=b;const Q=!E.children.length;for(let K=0;K{y=y||!!E.dynamicChildren;const{type:q,props:O,patchFlag:W,shapeFlag:x,dirs:C,transition:ne}=E,se=q==="input"||q==="option";if(se||W!==-1){C&&ct(E,null,F,"created");let j=!1;if(R(b)){j=is(G,ne)&&F&&F.vnode.props&&F.vnode.props.appear;const K=b.content.firstChild;j&&ne.beforeEnter(K),I(K,b,F),E.el=b=K}if(O)if(se||!y||W&48)for(const K in O)(se&&(K.endsWith("value")||K==="indeterminate")||Hl(K)&&!wl(K)||K[0]===".")&&n(b,K,null,O[K],!1,void 0,F);else O.onClick&&n(b,"onClick",null,O.onClick,!1,void 0,F);let Q;if((Q=O&&O.onVnodeBeforeMount)&&Ze(Q,F,E),C&&ct(E,null,F,"beforeMount"),((Q=O&&O.onVnodeMounted)||C||j)&&Wo(()=>{Q&&Ze(Q,F,E),j&&ne.enter(b),C&&ct(E,null,F,"mounted")},G),x&16&&!(O&&(O.innerHTML||O.textContent))){let K=m(b.firstChild,E,b,F,G,N,y);for(;K;){Pt=!0;const Se=K;K=K.nextSibling,s(Se)}}else x&8&&b.textContent!==E.children&&(Pt=!0,b.textContent=E.children)}return b.nextSibling},m=(b,E,F,G,N,y,q)=>{q=q||!!E.dynamicChildren;const O=E.children,W=O.length;for(let x=0;x{const{slotScopeIds:q}=E;q&&(N=N?N.concat(q):q);const O=o(b),W=m(r(b),E,O,F,G,N,y);return W&&rn(W)&&W.data==="]"?r(E.anchor=W):(Pt=!0,a(E.anchor=c("]"),O,W),W)},T=(b,E,F,G,N,y)=>{if(Pt=!0,E.el=null,y){const W=w(b);for(;;){const x=r(b);if(x&&x!==W)s(x);else break}}const q=r(b),O=o(b);return s(b),l(null,E,O,q,F,G,nn(O),N),q},w=(b,E="[",F="]")=>{let G=0;for(;b;)if(b=r(b),b&&rn(b)&&(b.data===E&&G++,b.data===F)){if(G===0)return r(b);G--}return b},I=(b,E,F)=>{const G=E.parentNode;G&&G.replaceChild(b,E);let N=F;for(;N;)N.vnode.el===E&&(N.vnode.el=N.subTree.el=b),N=N.parent},R=b=>b.nodeType===1&&b.tagName.toLowerCase()==="template";return[d,h]}const Ue=Wo;function Rc(e){return Ic(e,Ac)}function Ic(e,t){const l=li();l.__VUE__=!0;const{insert:n,remove:i,patchProp:r,createElement:o,createText:s,createComment:a,setText:c,setElementText:d,parentNode:h,nextSibling:f,setScopeId:m=dt,insertStaticContent:k}=e,T=(v,p,_,L=null,A=null,D=null,B=!1,V=null,$=!!p.dynamicChildren)=>{if(v===p)return;v&&!Wt(v,p)&&(L=P(v),He(v,A,D,!0),v=null),p.patchFlag===-2&&($=!1,p.dynamicChildren=null);const{type:S,ref:J,shapeFlag:X}=p;switch(S){case ul:w(v,p,_,L);break;case Qe:I(v,p,_,L);break;case Al:v==null&&R(p,_,L,B);break;case ye:x(v,p,_,L,A,D,B,V,$);break;default:X&1?F(v,p,_,L,A,D,B,V,$):X&6?C(v,p,_,L,A,D,B,V,$):(X&64||X&128)&&S.process(v,p,_,L,A,D,B,V,$,M)}J!=null&&A&&yn(J,v&&v.ref,D,p||v,!p)},w=(v,p,_,L)=>{if(v==null)n(p.el=s(p.children),_,L);else{const A=p.el=v.el;p.children!==v.children&&c(A,p.children)}},I=(v,p,_,L)=>{v==null?n(p.el=a(p.children||""),_,L):p.el=v.el},R=(v,p,_,L)=>{[v.el,v.anchor]=k(v.children,p,_,L,v.el,v.anchor)},b=({el:v,anchor:p},_,L)=>{let A;for(;v&&v!==p;)A=f(v),n(v,_,L),v=A;n(p,_,L)},E=({el:v,anchor:p})=>{let _;for(;v&&v!==p;)_=f(v),i(v),v=_;i(p)},F=(v,p,_,L,A,D,B,V,$)=>{B=B||p.type==="svg",v==null?G(p,_,L,A,D,B,V,$):q(v,p,A,D,B,V,$)},G=(v,p,_,L,A,D,B,V)=>{let $,S;const{type:J,props:X,shapeFlag:Z,transition:re,dirs:ae}=v;if($=v.el=o(v.type,D,X&&X.is,X),Z&8?d($,v.children):Z&16&&y(v.children,$,null,L,A,D&&J!=="foreignObject",B,V),ae&&ct(v,null,L,"created"),N($,v,v.scopeId,B,L),X){for(const _e in X)_e!=="value"&&!wl(_e)&&r($,_e,null,X[_e],D,v.children,L,A,je);"value"in X&&r($,"value",null,X.value),(S=X.onVnodeBeforeMount)&&Ze(S,L,v)}ae&&ct(v,null,L,"beforeMount");const be=is(A,re);be&&re.beforeEnter($),n($,p,_),((S=X&&X.onVnodeMounted)||be||ae)&&Ue(()=>{S&&Ze(S,L,v),be&&re.enter($),ae&&ct(v,null,L,"mounted")},A)},N=(v,p,_,L,A)=>{if(_&&m(v,_),L)for(let D=0;D{for(let S=$;S{const V=p.el=v.el;let{patchFlag:$,dynamicChildren:S,dirs:J}=p;$|=v.patchFlag&16;const X=v.props||xe,Z=p.props||xe;let re;_&&Mt(_,!1),(re=Z.onVnodeBeforeUpdate)&&Ze(re,_,p,v),J&&ct(p,v,_,"beforeUpdate"),_&&Mt(_,!0);const ae=A&&p.type!=="foreignObject";if(S?O(v.dynamicChildren,S,V,_,L,ae,D):B||K(v,p,V,null,_,L,ae,D,!1),$>0){if($&16)W(V,p,X,Z,_,L,A);else if($&2&&X.class!==Z.class&&r(V,"class",null,Z.class,A),$&4&&r(V,"style",X.style,Z.style,A),$&8){const be=p.dynamicProps;for(let _e=0;_e{re&&Ze(re,_,p,v),J&&ct(p,v,_,"updated")},L)},O=(v,p,_,L,A,D,B)=>{for(let V=0;V{if(_!==L){if(_!==xe)for(const V in _)!wl(V)&&!(V in L)&&r(v,V,_[V],null,B,p.children,A,D,je);for(const V in L){if(wl(V))continue;const $=L[V],S=_[V];$!==S&&V!=="value"&&r(v,V,S,$,B,p.children,A,D,je)}"value"in L&&r(v,"value",_.value,L.value)}},x=(v,p,_,L,A,D,B,V,$)=>{const S=p.el=v?v.el:s(""),J=p.anchor=v?v.anchor:s("");let{patchFlag:X,dynamicChildren:Z,slotScopeIds:re}=p;re&&(V=V?V.concat(re):re),v==null?(n(S,_,L),n(J,_,L),y(p.children,_,J,A,D,B,V,$)):X>0&&X&64&&Z&&v.dynamicChildren?(O(v.dynamicChildren,Z,_,A,D,B,V),(p.key!=null||A&&p===A.subTree)&&rs(v,p,!0)):K(v,p,_,J,A,D,B,V,$)},C=(v,p,_,L,A,D,B,V,$)=>{p.slotScopeIds=V,v==null?p.shapeFlag&512?A.ctx.activate(p,_,L,B,$):ne(p,_,L,A,D,B,$):se(v,p,$)},ne=(v,p,_,L,A,D,B)=>{const V=v.component=Hc(v,L,A);if(Ul(v)&&(V.ctx.renderer=M),$c(V),V.asyncDep){if(A&&A.registerDep(V,j),!v.el){const $=V.subTree=ie(Qe);I(null,$,p,_)}return}j(V,v,p,_,A,D,B)},se=(v,p,_)=>{const L=p.component=v.component;if(Ya(v,p,_))if(L.asyncDep&&!L.asyncResolved){Q(L,p,_);return}else L.next=p,Wa(L.update),L.update();else p.el=v.el,L.vnode=p},j=(v,p,_,L,A,D,B)=>{const V=()=>{if(v.isMounted){let{next:J,bu:X,u:Z,parent:re,vnode:ae}=v,be=J,_e;Mt(v,!1),J?(J.el=ae.el,Q(v,J,B)):J=ae,X&&$n(X),(_e=J.props&&J.props.onVnodeBeforeUpdate)&&Ze(_e,re,J,ae),Mt(v,!0);const Pe=zn(v),tt=v.subTree;v.subTree=Pe,T(tt,Pe,h(tt.el),P(tt),v,A,D),J.el=Pe.el,be===null&&Qa(v,Pe.el),Z&&Ue(Z,A),(_e=J.props&&J.props.onVnodeUpdated)&&Ue(()=>Ze(_e,re,J,ae),A)}else{let J;const{el:X,props:Z}=p,{bm:re,m:ae,parent:be}=v,_e=sl(p);if(Mt(v,!1),re&&$n(re),!_e&&(J=Z&&Z.onVnodeBeforeMount)&&Ze(J,be,p),Mt(v,!0),X&&ce){const Pe=()=>{v.subTree=zn(v),ce(X,v.subTree,v,A,null)};_e?p.type.__asyncLoader().then(()=>!v.isUnmounted&&Pe()):Pe()}else{const Pe=v.subTree=zn(v);T(null,Pe,_,L,v,A,D),p.el=Pe.el}if(ae&&Ue(ae,A),!_e&&(J=Z&&Z.onVnodeMounted)){const Pe=p;Ue(()=>Ze(J,be,Pe),A)}(p.shapeFlag&256||be&&sl(be.vnode)&&be.vnode.shapeFlag&256)&&v.a&&Ue(v.a,A),v.isMounted=!0,p=_=L=null}},$=v.effect=new xi(V,()=>Dn(S),v.scope),S=v.update=()=>$.run();S.id=v.uid,Mt(v,!0),S()},Q=(v,p,_)=>{p.component=v;const L=v.vnode.props;v.vnode=p,v.next=null,Tc(v,p.props,L,_),Oc(v,p.children,_),gl(),sr(v),_l()},K=(v,p,_,L,A,D,B,V,$=!1)=>{const S=v&&v.children,J=v?v.shapeFlag:0,X=p.children,{patchFlag:Z,shapeFlag:re}=p;if(Z>0){if(Z&128){Ce(S,X,_,L,A,D,B,V,$);return}else if(Z&256){Se(S,X,_,L,A,D,B,V,$);return}}re&8?(J&16&&je(S,A,D),X!==S&&d(_,X)):J&16?re&16?Ce(S,X,_,L,A,D,B,V,$):je(S,A,D,!0):(J&8&&d(_,""),re&16&&y(X,_,L,A,D,B,V,$))},Se=(v,p,_,L,A,D,B,V,$)=>{v=v||nl,p=p||nl;const S=v.length,J=p.length,X=Math.min(S,J);let Z;for(Z=0;ZJ?je(v,A,D,!0,!1,X):y(p,_,L,A,D,B,V,$,X)},Ce=(v,p,_,L,A,D,B,V,$)=>{let S=0;const J=p.length;let X=v.length-1,Z=J-1;for(;S<=X&&S<=Z;){const re=v[S],ae=p[S]=$?Rt(p[S]):lt(p[S]);if(Wt(re,ae))T(re,ae,_,null,A,D,B,V,$);else break;S++}for(;S<=X&&S<=Z;){const re=v[X],ae=p[Z]=$?Rt(p[Z]):lt(p[Z]);if(Wt(re,ae))T(re,ae,_,null,A,D,B,V,$);else break;X--,Z--}if(S>X){if(S<=Z){const re=Z+1,ae=reZ)for(;S<=X;)He(v[S],A,D,!0),S++;else{const re=S,ae=S,be=new Map;for(S=ae;S<=Z;S++){const Xe=p[S]=$?Rt(p[S]):lt(p[S]);Xe.key!=null&&be.set(Xe.key,S)}let _e,Pe=0;const tt=Z-ae+1;let Jt=!1,Yi=0;const kl=new Array(tt);for(S=0;S=tt){He(Xe,A,D,!0);continue}let at;if(Xe.key!=null)at=be.get(Xe.key);else for(_e=ae;_e<=Z;_e++)if(kl[_e-ae]===0&&Wt(Xe,p[_e])){at=_e;break}at===void 0?He(Xe,A,D,!0):(kl[at-ae]=S+1,at>=Yi?Yi=at:Jt=!0,T(Xe,p[at],_,null,A,D,B,V,$),Pe++)}const Qi=Jt?Dc(kl):nl;for(_e=Qi.length-1,S=tt-1;S>=0;S--){const Xe=ae+S,at=p[Xe],Ji=Xe+1{const{el:D,type:B,transition:V,children:$,shapeFlag:S}=v;if(S&6){We(v.component.subTree,p,_,L);return}if(S&128){v.suspense.move(p,_,L);return}if(S&64){B.move(v,p,_,M);return}if(B===ye){n(D,p,_);for(let X=0;X<$.length;X++)We($[X],p,_,L);n(v.anchor,p,_);return}if(B===Al){b(v,p,_);return}if(L!==2&&S&1&&V)if(L===0)V.beforeEnter(D),n(D,p,_),Ue(()=>V.enter(D),A);else{const{leave:X,delayLeave:Z,afterLeave:re}=V,ae=()=>n(D,p,_),be=()=>{X(D,()=>{ae(),re&&re()})};Z?Z(D,ae,be):be()}else n(D,p,_)},He=(v,p,_,L=!1,A=!1)=>{const{type:D,props:B,ref:V,children:$,dynamicChildren:S,shapeFlag:J,patchFlag:X,dirs:Z}=v;if(V!=null&&yn(V,null,_,v,!0),J&256){p.ctx.deactivate(v);return}const re=J&1&&Z,ae=!sl(v);let be;if(ae&&(be=B&&B.onVnodeBeforeUnmount)&&Ze(be,p,v),J&6)st(v.component,_,L);else{if(J&128){v.suspense.unmount(_,L);return}re&&ct(v,null,p,"beforeUnmount"),J&64?v.type.remove(v,p,_,A,M,L):S&&(D!==ye||X>0&&X&64)?je(S,p,_,!1,!0):(D===ye&&X&384||!A&&J&16)&&je($,p,_),L&&xt(v)}(ae&&(be=B&&B.onVnodeUnmounted)||re)&&Ue(()=>{be&&Ze(be,p,v),re&&ct(v,null,p,"unmounted")},_)},xt=v=>{const{type:p,el:_,anchor:L,transition:A}=v;if(p===ye){Lt(_,L);return}if(p===Al){E(v);return}const D=()=>{i(_),A&&!A.persisted&&A.afterLeave&&A.afterLeave()};if(v.shapeFlag&1&&A&&!A.persisted){const{leave:B,delayLeave:V}=A,$=()=>B(_,D);V?V(v.el,D,$):$()}else D()},Lt=(v,p)=>{let _;for(;v!==p;)_=f(v),i(v),v=_;i(p)},st=(v,p,_)=>{const{bum:L,scope:A,update:D,subTree:B,um:V}=v;L&&$n(L),A.stop(),D&&(D.active=!1,He(B,v,p,_)),V&&Ue(V,p),Ue(()=>{v.isUnmounted=!0},p),p&&p.pendingBranch&&!p.isUnmounted&&v.asyncDep&&!v.asyncResolved&&v.suspenseId===p.pendingId&&(p.deps--,p.deps===0&&p.resolve())},je=(v,p,_,L=!1,A=!1,D=0)=>{for(let B=D;Bv.shapeFlag&6?P(v.component.subTree):v.shapeFlag&128?v.suspense.next():f(v.anchor||v.el),U=(v,p,_)=>{v==null?p._vnode&&He(p._vnode,null,null,!0):T(p._vnode||null,v,p,null,null,null,_),sr(),mn(),p._vnode=v},M={p:T,um:He,m:We,r:xt,mt:ne,mc:y,pc:K,pbc:O,n:P,o:e};let Y,ce;return t&&([Y,ce]=t(M)),{render:U,hydrate:Y,createApp:xc(U,Y)}}function Mt({effect:e,update:t},l){e.allowRecurse=t.allowRecurse=l}function is(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function rs(e,t,l=!1){const n=e.children,i=t.children;if(le(n)&&le(i))for(let r=0;r>1,e[l[s]]0&&(t[n]=l[r-1]),l[r]=n)}}for(r=l.length,o=l[r-1];r-- >0;)l[r]=o,o=t[o];return l}const Sc=e=>e.__isTeleport,ye=Symbol.for("v-fgt"),ul=Symbol.for("v-txt"),Qe=Symbol.for("v-cmt"),Al=Symbol.for("v-stc"),Rl=[];let it=null;function z(e=!1){Rl.push(it=e?null:[])}function jc(){Rl.pop(),it=Rl[Rl.length-1]||null}let Vl=1;function br(e){Vl+=e}function os(e){return e.dynamicChildren=Vl>0?it||nl:null,jc(),Vl>0&&it&&it.push(e),e}function ee(e,t,l,n,i,r){return os(he(e,t,l,n,i,r,!0))}function we(e,t,l,n,i){return os(ie(e,t,l,n,i,!0))}function En(e){return e?e.__v_isVNode===!0:!1}function Wt(e,t){return e.type===t.type&&e.key===t.key}const Vn="__vInternal",ss=({key:e})=>e??null,dn=({ref:e,ref_key:t,ref_for:l})=>(typeof e=="number"&&(e=""+e),e!=null?Ae(e)||Me(e)||oe(e)?{i:Fe,r:e,k:t,f:!!l}:e:null);function he(e,t=null,l=null,n=0,i=null,r=e===ye?0:1,o=!1,s=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&ss(t),ref:t&&dn(t),scopeId:Bo,slotScopeIds:null,children:l,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:r,patchFlag:n,dynamicProps:i,dynamicChildren:null,appContext:null,ctx:Fe};return s?(ji(a,l),r&128&&e.normalize(a)):l&&(a.shapeFlag|=Ae(l)?8:16),Vl>0&&!o&&it&&(a.patchFlag>0||r&6)&&a.patchFlag!==32&&it.push(a),a}const ie=Cc;function Cc(e,t=null,l=null,n=0,i=null,r=!1){if((!e||e===Ja)&&(e=Qe),En(e)){const s=Vt(e,t,!0);return l&&ji(s,l),Vl>0&&!r&&it&&(s.shapeFlag&6?it[it.indexOf(e)]=s:it.push(s)),s.patchFlag|=-2,s}if(Kc(e)&&(e=e.__vccOpts),t){t=Vc(t);let{class:s,style:a}=t;s&&!Ae(s)&&(t.class=Ke(s)),Ee(a)&&(Do(a)&&!le(a)&&(a=De({},a)),t.style=$l(a))}const o=Ae(e)?1:ec(e)?128:Sc(e)?64:Ee(e)?4:oe(e)?2:0;return he(e,t,l,n,i,o,r,!0)}function Vc(e){return e?Do(e)||Vn in e?De({},e):e:null}function Vt(e,t,l=!1){const{props:n,ref:i,patchFlag:r,children:o}=e,s=t?fi(n||{},t):n;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:s,key:s&&ss(s),ref:t&&t.ref?l&&i?le(i)?i.concat(dn(t)):[i,dn(t)]:dn(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:o,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==ye?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Vt(e.ssContent),ssFallback:e.ssFallback&&Vt(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function Ft(e=" ",t=0){return ie(ul,null,e,t)}function Fc(e,t){const l=ie(Al,null,e);return l.staticCount=t,l}function Oe(e="",t=!1){return t?(z(),we(Qe,null,e)):ie(Qe,null,e)}function lt(e){return e==null||typeof e=="boolean"?ie(Qe):le(e)?ie(ye,null,e.slice()):typeof e=="object"?Rt(e):ie(ul,null,String(e))}function Rt(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Vt(e)}function ji(e,t){let l=0;const{shapeFlag:n}=e;if(t==null)t=null;else if(le(t))l=16;else if(typeof t=="object")if(n&65){const i=t.default;i&&(i._c&&(i._d=!1),ji(e,i()),i._c&&(i._d=!0));return}else{l=32;const i=t._;!i&&!(Vn in t)?t._ctx=Fe:i===3&&Fe&&(Fe.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else oe(t)?(t={default:t,_ctx:Fe},l=32):(t=String(t),n&64?(l=16,t=[Ft(t)]):l=8);e.children=t,e.shapeFlag|=l}function fi(...e){const t={};for(let l=0;lRe||Fe;let Vi,Zt,kr="__VUE_INSTANCE_SETTERS__";(Zt=li()[kr])||(Zt=li()[kr]=[]),Zt.push(e=>Re=e),Vi=e=>{Zt.length>1?Zt.forEach(t=>t(e)):Zt[0](e)};const dl=e=>{Vi(e),e.scope.on()},Gt=()=>{Re&&Re.scope.off(),Vi(null)};function as(e){return e.vnode.shapeFlag&4}let hl=!1;function $c(e,t=!1){hl=t;const{props:l,children:n}=e.vnode,i=as(e);Lc(e,l,i,t),wc(e,n);const r=i?Bc(e,t):void 0;return hl=!1,r}function Bc(e,t){const l=e.type;e.accessCache=Object.create(null),e.proxy=So(new Proxy(e.ctx,mc));const{setup:n}=l;if(n){const i=e.setupContext=n.length>1?Wc(e):null;dl(e),gl();const r=St(n,e,0,[e.props,i]);if(_l(),Gt(),po(r)){if(r.then(Gt,Gt),t)return r.then(o=>{yr(e,o,t)}).catch(o=>{zl(o,e,0)});e.asyncDep=r}else yr(e,r,t)}else cs(e,t)}function yr(e,t,l){oe(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Ee(t)&&(e.setupState=Vo(t)),cs(e,l)}let Er;function cs(e,t,l){const n=e.type;if(!e.render){if(!t&&Er&&!n.render){const i=n.template||Di(e).template;if(i){const{isCustomElement:r,compilerOptions:o}=e.appContext.config,{delimiters:s,compilerOptions:a}=n,c=De(De({isCustomElement:r,delimiters:s},o),a);n.render=Er(i,c)}}e.render=n.render||dt}{dl(e),gl();try{gc(e)}finally{_l(),Gt()}}}function zc(e){return e.attrsProxy||(e.attrsProxy=new Proxy(e.attrs,{get(t,l){return qe(e,"get","$attrs"),t[l]}}))}function Wc(e){const t=l=>{e.exposed=l||{}};return{get attrs(){return zc(e)},slots:e.slots,emit:e.emit,expose:t}}function Fn(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(Vo(So(e.exposed)),{get(t,l){if(l in t)return t[l];if(l in Ol)return Ol[l](e)},has(t,l){return l in t||l in Ol}}))}function Uc(e,t=!0){return oe(e)?e.displayName||e.name:e.name||t&&e.__name}function Kc(e){return oe(e)&&"__vccOpts"in e}const H=(e,t)=>$a(e,t,hl);function fe(e,t,l){const n=arguments.length;return n===2?Ee(t)&&!le(t)?En(t)?ie(e,null,[t]):ie(e,t):ie(e,null,t):(n>3?l=Array.prototype.slice.call(arguments,2):n===3&&En(l)&&(l=[l]),ie(e,t,l))}const qc=Symbol.for("v-scx"),Xc=()=>Te(qc),Gc="3.3.13",Yc="http://www.w3.org/2000/svg",Ut=typeof document<"u"?document:null,xr=Ut&&Ut.createElement("template"),Qc={insert:(e,t,l)=>{t.insertBefore(e,l||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,l,n)=>{const i=t?Ut.createElementNS(Yc,e):Ut.createElement(e,l?{is:l}:void 0);return e==="select"&&n&&n.multiple!=null&&i.setAttribute("multiple",n.multiple),i},createText:e=>Ut.createTextNode(e),createComment:e=>Ut.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ut.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,l,n,i,r){const o=l?l.previousSibling:t.lastChild;if(i&&(i===r||i.nextSibling))for(;t.insertBefore(i.cloneNode(!0),l),!(i===r||!(i=i.nextSibling)););else{xr.innerHTML=n?`${e}`:e;const s=xr.content;if(n){const a=s.firstChild;for(;a.firstChild;)s.appendChild(a.firstChild);s.removeChild(a)}t.insertBefore(s,l)}return[o?o.nextSibling:t.firstChild,l?l.previousSibling:t.lastChild]}},wt="transition",yl="animation",Fl=Symbol("_vtc"),ql=(e,{slots:t})=>fe(rc,Jc(e),t);ql.displayName="Transition";const us={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};ql.props=De({},Ko,us);const Ht=(e,t=[])=>{le(e)?e.forEach(l=>l(...t)):e&&e(...t)},Lr=e=>e?le(e)?e.some(t=>t.length>1):e.length>1:!1;function Jc(e){const t={};for(const x in e)x in us||(t[x]=e[x]);if(e.css===!1)return t;const{name:l="v",type:n,duration:i,enterFromClass:r=`${l}-enter-from`,enterActiveClass:o=`${l}-enter-active`,enterToClass:s=`${l}-enter-to`,appearFromClass:a=r,appearActiveClass:c=o,appearToClass:d=s,leaveFromClass:h=`${l}-leave-from`,leaveActiveClass:f=`${l}-leave-active`,leaveToClass:m=`${l}-leave-to`}=e,k=Zc(i),T=k&&k[0],w=k&&k[1],{onBeforeEnter:I,onEnter:R,onEnterCancelled:b,onLeave:E,onLeaveCancelled:F,onBeforeAppear:G=I,onAppear:N=R,onAppearCancelled:y=b}=t,q=(x,C,ne)=>{$t(x,C?d:s),$t(x,C?c:o),ne&&ne()},O=(x,C)=>{x._isLeaving=!1,$t(x,h),$t(x,m),$t(x,f),C&&C()},W=x=>(C,ne)=>{const se=x?N:R,j=()=>q(C,x,ne);Ht(se,[C,j]),Tr(()=>{$t(C,x?a:r),Ot(C,x?d:s),Lr(se)||Pr(C,n,T,j)})};return De(t,{onBeforeEnter(x){Ht(I,[x]),Ot(x,r),Ot(x,o)},onBeforeAppear(x){Ht(G,[x]),Ot(x,a),Ot(x,c)},onEnter:W(!1),onAppear:W(!0),onLeave(x,C){x._isLeaving=!0;const ne=()=>O(x,C);Ot(x,h),lu(),Ot(x,f),Tr(()=>{x._isLeaving&&($t(x,h),Ot(x,m),Lr(E)||Pr(x,n,w,ne))}),Ht(E,[x,ne])},onEnterCancelled(x){q(x,!1),Ht(b,[x])},onAppearCancelled(x){q(x,!0),Ht(y,[x])},onLeaveCancelled(x){O(x),Ht(F,[x])}})}function Zc(e){if(e==null)return null;if(Ee(e))return[qn(e.enter),qn(e.leave)];{const t=qn(e);return[t,t]}}function qn(e){return na(e)}function Ot(e,t){t.split(/\s+/).forEach(l=>l&&e.classList.add(l)),(e[Fl]||(e[Fl]=new Set)).add(t)}function $t(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.remove(n));const l=e[Fl];l&&(l.delete(t),l.size||(e[Fl]=void 0))}function Tr(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let eu=0;function Pr(e,t,l,n){const i=e._endId=++eu,r=()=>{i===e._endId&&n()};if(l)return setTimeout(r,l);const{type:o,timeout:s,propCount:a}=tu(e,t);if(!o)return n();const c=o+"end";let d=0;const h=()=>{e.removeEventListener(c,f),r()},f=m=>{m.target===e&&++d>=a&&h()};setTimeout(()=>{d(l[k]||"").split(", "),i=n(`${wt}Delay`),r=n(`${wt}Duration`),o=wr(i,r),s=n(`${yl}Delay`),a=n(`${yl}Duration`),c=wr(s,a);let d=null,h=0,f=0;t===wt?o>0&&(d=wt,h=o,f=r.length):t===yl?c>0&&(d=yl,h=c,f=a.length):(h=Math.max(o,c),d=h>0?o>c?wt:yl:null,f=d?d===wt?r.length:a.length:0);const m=d===wt&&/\b(transform|all)(,|$)/.test(n(`${wt}Property`).toString());return{type:d,timeout:h,propCount:f,hasTransform:m}}function wr(e,t){for(;e.lengthOr(l)+Or(e[n])))}function Or(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function lu(){return document.body.offsetHeight}function nu(e,t,l){const n=e[Fl];n&&(t=(t?[t,...n]:[...n]).join(" ")),t==null?e.removeAttribute("class"):l?e.setAttribute("class",t):e.className=t}const Fi=Symbol("_vod"),xn={beforeMount(e,{value:t},{transition:l}){e[Fi]=e.style.display==="none"?"":e.style.display,l&&t?l.beforeEnter(e):El(e,t)},mounted(e,{value:t},{transition:l}){l&&t&&l.enter(e)},updated(e,{value:t,oldValue:l},{transition:n}){!t!=!l&&(n?t?(n.beforeEnter(e),El(e,!0),n.enter(e)):n.leave(e,()=>{El(e,!1)}):El(e,t))},beforeUnmount(e,{value:t}){El(e,t)}};function El(e,t){e.style.display=t?e[Fi]:"none"}const iu=Symbol("");function ru(e,t,l){const n=e.style,i=Ae(l);if(l&&!i){if(t&&!Ae(t))for(const r in t)l[r]==null&&vi(n,r,"");for(const r in l)vi(n,r,l[r])}else{const r=n.display;if(i){if(t!==l){const o=n[iu];o&&(l+=";"+o),n.cssText=l}}else t&&e.removeAttribute("style");Fi in e&&(n.display=r)}}const Ar=/\s*!important$/;function vi(e,t,l){if(le(l))l.forEach(n=>vi(e,t,n));else if(l==null&&(l=""),t.startsWith("--"))e.setProperty(t,l);else{const n=ou(e,t);Ar.test(l)?e.setProperty(Qt(n),l.replace(Ar,""),"important"):e[n]=l}}const Rr=["Webkit","Moz","ms"],Xn={};function ou(e,t){const l=Xn[t];if(l)return l;let n=ht(t);if(n!=="filter"&&n in e)return Xn[t]=n;n=On(n);for(let i=0;iGn||(fu.then(()=>Gn=0),Gn=Date.now());function pu(e,t){const l=n=>{if(!n._vts)n._vts=Date.now();else if(n._vts<=l.attached)return;et(mu(n,l.value),t,5,[n])};return l.value=e,l.attached=vu(),l}function mu(e,t){if(le(t)){const l=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{l.call(e),e._stopped=!0},t.map(n=>i=>!i._stopped&&n&&n(i))}else return t}const jr=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,gu=(e,t,l,n,i=!1,r,o,s,a)=>{t==="class"?nu(e,n,i):t==="style"?ru(e,l,n):Hl(t)?bi(t)||du(e,t,l,n,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):_u(e,t,n,i))?au(e,t,n,r,o,s,a):(t==="true-value"?e._trueValue=n:t==="false-value"&&(e._falseValue=n),su(e,t,n,i))};function _u(e,t,l,n){if(n)return!!(t==="innerHTML"||t==="textContent"||t in e&&jr(t)&&oe(l));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const i=e.tagName;if(i==="IMG"||i==="VIDEO"||i==="CANVAS"||i==="SOURCE")return!1}return jr(t)&&Ae(l)?!1:t in e}const bu={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},ku=(e,t)=>{const l=e._withKeys||(e._withKeys={}),n=t.join(".");return l[n]||(l[n]=i=>{if(!("key"in i))return;const r=Qt(i.key);if(t.some(o=>o===r||bu[o]===r))return e(i)})},yu=De({patchProp:gu},Qc);let Yn,Cr=!1;function Eu(){return Yn=Cr?Yn:Rc(yu),Cr=!0,Yn}const xu=(...e)=>{const t=Eu().createApp(...e),{mount:l}=t;return t.mount=n=>{const i=Lu(n);if(i)return l(i,!0,i instanceof SVGElement)},t};function Lu(e){return Ae(e)?document.querySelector(e):e}const Tu="modulepreload",Pu=function(e){return"/"+e},Vr={},u=function(t,l,n){let i=Promise.resolve();if(l&&l.length>0){const r=document.getElementsByTagName("link");i=Promise.all(l.map(o=>{if(o=Pu(o),o in Vr)return;Vr[o]=!0;const s=o.endsWith(".css"),a=s?'[rel="stylesheet"]':"";if(!!n)for(let h=r.length-1;h>=0;h--){const f=r[h];if(f.href===o&&(!s||f.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${o}"]${a}`))return;const d=document.createElement("link");if(d.rel=s?"stylesheet":Tu,s||(d.as="script",d.crossOrigin=""),d.href=o,document.head.appendChild(d),s)return new Promise((h,f)=>{d.addEventListener("load",h),d.addEventListener("error",()=>f(new Error(`Unable to preload CSS for ${o}`)))})}))}return i.then(()=>t()).catch(r=>{const o=new Event("vite:preloadError",{cancelable:!0});if(o.payload=r,window.dispatchEvent(o),!o.defaultPrevented)throw r})},wu={"v-8daa1a0e":()=>u(()=>import("./index.html-p2c5C4AU.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-aad48c6a":()=>u(()=>import("./news.html-pwjcoGoO.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-ba934fd8":()=>u(()=>import("./index.html-XFyzJ1xl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-41ade9da":()=>u(()=>import("./api.html-WGzp5ZHY.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-83dedd38":()=>u(()=>import("./dns.html-M7PqPYo9.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-192a19b9":()=>u(()=>import("./fakedns.html-wHw6FjrC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7f6279d8":()=>u(()=>import("./inbound.html-moDGVb2O.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1d860c29":()=>u(()=>import("./log.html-e7hnT2bq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fbaf47ec":()=>u(()=>import("./metrics.html-9VuoOtoJ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2367d756":()=>u(()=>import("./outbound.html-m7-qp10m.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4ebec35a":()=>u(()=>import("./policy.html-5wXUoyYU.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-31b7756a":()=>u(()=>import("./reverse.html-iCYMdXOv.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-70677432":()=>u(()=>import("./routing.html-z5FZ8_MJ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7e21d6ae":()=>u(()=>import("./stats.html-sE2S72lW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e3dfff38":()=>u(()=>import("./transport.html-VgBdoawf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f7496066":()=>u(()=>import("./index.html-z9NWHqlp.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-36b1a79b":()=>u(()=>import("./index.html-E6Im5Z2U.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-09a64f89":()=>u(()=>import("./command.html-zok3YKap.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2b1adf48":()=>u(()=>import("./config.html-aUjThaBl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-86ee963a":()=>u(()=>import("./document.html-T74UyKyv.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0e5d7b39":()=>u(()=>import("./install.html-HJ0OvsaV.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2d0a870d":()=>u(()=>import("./index.html-G23QhNrE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0d714d87":()=>u(()=>import("./browser_dialer.html-pBajOlNq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0da7880a":()=>u(()=>import("./env.html-cjIQiZYK.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2aeb21f9":()=>u(()=>import("./fallback.html-1JIS-sqn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3acf20ea":()=>u(()=>import("./multiple.html-lXhmxiM0.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-792e28f8":()=>u(()=>import("./xtls.html-B_w95T3t.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-b50d2334":()=>u(()=>import("./dokodemo.html-jpQVDK5E.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-593408b0":()=>u(()=>import("./http.html-kcI8nPMj.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-802a842a":()=>u(()=>import("./shadowsocks.html-RfXFYESa.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-29995cea":()=>u(()=>import("./socks.html-s5-aPzb4.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2a1b3d72":()=>u(()=>import("./trojan.html-1a6tGxlx.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fb92e8aa":()=>u(()=>import("./vless.html-8KqB5qGc.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-167afaac":()=>u(()=>import("./vmess.html-YK_H6TQs.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-749ad71a":()=>u(()=>import("./blackhole.html-KHhjSI5O.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6d39b970":()=>u(()=>import("./dns.html-gJ4v9Hez.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d76e893a":()=>u(()=>import("./freedom.html-bKrcmvMl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c6b4b59e":()=>u(()=>import("./http.html-ODrut9n2.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-41ec0e0e":()=>u(()=>import("./loopback.html-nkoZ0pXT.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7b293e4a":()=>u(()=>import("./shadowsocks.html-coJ5pBTn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-15f5452a":()=>u(()=>import("./socks.html-y40g6uI5.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5797bdb3":()=>u(()=>import("./trojan.html-yXVZG2Ev.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a60f016c":()=>u(()=>import("./vless.html-qqj9e8Vf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-413cee4b":()=>u(()=>import("./vmess.html-Vr1rc_Up.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-208ca3b9":()=>u(()=>import("./wireguard.html-KdrqTCQm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-775db7b1":()=>u(()=>import("./domainsocket.html-wdK_rHZQ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2877542a":()=>u(()=>import("./grpc.html-LBqi_a75.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-03a28284":()=>u(()=>import("./h2.html-KM70GQbw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-04158536":()=>u(()=>import("./httpupgrade.html-H-WqXGti.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3167b1dd":()=>u(()=>import("./mkcp.html-0Xk_HIpn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8f08dbec":()=>u(()=>import("./quic.html-m95M53yN.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-33b1b709":()=>u(()=>import("./tcp.html-jnCC9tdJ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1ff57bba":()=>u(()=>import("./websocket.html-MBy8EkDB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6a9e8054":()=>u(()=>import("./compile.html-X6FgGIuq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-95e3eaea":()=>u(()=>import("./design.html--gTpLkem.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-61e7eea6":()=>u(()=>import("./guide.html-9aEFcVqM.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6e6c37e6":()=>u(()=>import("./mkcp.html-vo5PDXHA.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-13168a21":()=>u(()=>import("./muxcool.html-nTSzbowY.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5c48c82b":()=>u(()=>import("./vless.html-qQ4zG4ni.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1ee591a8":()=>u(()=>import("./vmess.html-VN98TXTo.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3f09dcfa":()=>u(()=>import("./index.html-SzZckNsL.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fb444906":()=>u(()=>import("./ch01-preface.html-tEScEaZz.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-075f3ae5":()=>u(()=>import("./ch02-preparation.html-RGVVF1aX.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-726d0633":()=>u(()=>import("./ch03-ssh.html-r0_Dxdy0.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-430c6ab8":()=>u(()=>import("./ch04-security.html-fTS70_mi.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-717c6376":()=>u(()=>import("./ch05-webpage.html-5seJ1ciw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-278039be":()=>u(()=>import("./ch06-certificates.html-S8wDl_Ux.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a0c7f88e":()=>u(()=>import("./ch07-xray-server.html-XceTyVhx.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-86586ca2":()=>u(()=>import("./ch08-xray-clients.html-ud6w1qRW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3eb62514":()=>u(()=>import("./ch09-appendix.html-sabgEttE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3f09dcbc":()=>u(()=>import("./index.html-mMCfrUS-.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-b21a2a20":()=>u(()=>import("./fallbacks-lv1.html--J_6qlTn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-da623318":()=>u(()=>import("./fallbacks-with-sni.html-qQOZMYA7.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fdd722ac":()=>u(()=>import("./routing-lv1-part1.html-cRNm4oEK.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fa6d716e":()=>u(()=>import("./routing-lv1-part2.html-5XUPXSEg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2f29e106":()=>u(()=>import("./work.html-145CR_fW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3f09dc7e":()=>u(()=>import("./index.html-BFn1lRAW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1c17916e":()=>u(()=>import("./iptables_gid.html-BjKdQK_Z.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a001cfa6":()=>u(()=>import("./nginx_or_haproxy_tls_tunnel.html-_NqxTVZn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-46333b48":()=>u(()=>import("./redirect.html-ErNGzo9V.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-338bc63e":()=>u(()=>import("./tproxy.html-y5eAJ7SY.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d68f7d58":()=>u(()=>import("./tproxy_ipv4_and_ipv6.html-JH4YyNOP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e533e2c6":()=>u(()=>import("./traffic_stats.html-_cNOE5xN.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1e465ab0":()=>u(()=>import("./warp.html-2hJhJpHa.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1080fb37":()=>u(()=>import("./news.html-gzJt0vYA.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-317fc580":()=>u(()=>import("./index.html-BGcfEeBc.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-45144c7f":()=>u(()=>import("./api.html-ehTB5jsP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-23fbd2d0":()=>u(()=>import("./dns.html-rP5naxFq.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2b7ec525":()=>u(()=>import("./fakedns.html-WRT-9j2m.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5ab92300":()=>u(()=>import("./inbound.html-Mx2-iGW_.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f91d64d6":()=>u(()=>import("./log.html-p-vXJqMl.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d705f114":()=>u(()=>import("./metrics.html-GccLQE2P.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-268cd669":()=>u(()=>import("./outbound.html-rUxUkwF-.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4492d567":()=>u(()=>import("./policy.html-0ggCjnWf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0d0e1e92":()=>u(()=>import("./reverse.html-Vyc-TBL8.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4bbe1d5a":()=>u(()=>import("./routing.html-gMcV9QF8.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-16426d1a":()=>u(()=>import("./stats.html-f0XRSzHJ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5de780d0":()=>u(()=>import("./transport.html-XoPNjoZf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f88d343e":()=>u(()=>import("./index.html-JeZuqWwp.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-38d56a07":()=>u(()=>import("./index.html-PAgbBg-Z.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4d046016":()=>u(()=>import("./command.html-5rSGvvaL.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-22b35270":()=>u(()=>import("./config.html-5ZOPemlE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-30bd7c12":()=>u(()=>import("./document.html-7QxaDrrB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-439608b6":()=>u(()=>import("./install.html-bu0Ticvf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-51a51d87":()=>u(()=>import("./transparent_proxy.html-ocawHfnS.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-76b9a0f3":()=>u(()=>import("./browser_dialer.html-G4IRQ_Kg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-565dbfc4":()=>u(()=>import("./env.html-vTGLOPHC.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-0fbd1336":()=>u(()=>import("./fallback.html-c3nG_SbK.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a0627812":()=>u(()=>import("./multiple.html-broKJH6Q.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d190d938":()=>u(()=>import("./xtls.html-VGwDVgWQ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-72afc2d2":()=>u(()=>import("./dokodemo.html-lQ2ZCHA0.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-773d731c":()=>u(()=>import("./http.html-qlBUGI3d.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f555fc02":()=>u(()=>import("./shadowsocks.html-KKd7sD5W.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e35196c2":()=>u(()=>import("./socks.html-Rr3Pd7Z4.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-29188644":()=>u(()=>import("./trojan.html-JtWYvOGZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-255a6ebf":()=>u(()=>import("./vless.html-FmnaDhwB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-8cc24480":()=>u(()=>import("./vmess.html-DQRQNJRf.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-64e47ef4":()=>u(()=>import("./blackhole.html-wP8aOe1s.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-e979b848":()=>u(()=>import("./dns.html-fsBpY6OJ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-617f0fcf":()=>u(()=>import("./freedom.html-pEcHOOJi.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3fc98845":()=>u(()=>import("./http.html-ycpGlUVn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1b804722":()=>u(()=>import("./loopback.html-aUCjrxrz.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-63077cb6":()=>u(()=>import("./shadowsocks.html-DUgYYNSE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-516476d4":()=>u(()=>import("./socks.html-4LNnnGuU.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7d61a872":()=>u(()=>import("./trojan.html-zPYE2Rnw.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-6e50feb6":()=>u(()=>import("./vless.html-oJkCcWqP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-02956db7":()=>u(()=>import("./vmess.html-FLYSgYZF.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-797f8d25":()=>u(()=>import("./wireguard.html-BNOcORO_.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3eb3e9c6":()=>u(()=>import("./domainsocket.html-XJDOFjPR.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-2c6058d4":()=>u(()=>import("./grpc.html--7XYo6-r.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1c38292a":()=>u(()=>import("./h2.html-an3IPz3A.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-17ff144a":()=>u(()=>import("./httpupgrade.html-pqcUDxzH.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-1a7f9d6e":()=>u(()=>import("./mkcp.html-KaKSugGP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-79d41176":()=>u(()=>import("./quic.html-tQfatAaD.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5254cbc6":()=>u(()=>import("./tcp.html-D0BFi51s.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-9520f392":()=>u(()=>import("./websocket.html-u5FN1LVg.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-b7760e2c":()=>u(()=>import("./compile.html-v0FcVQeh.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-fb774212":()=>u(()=>import("./design.html-mn37DqeY.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-38c376c1":()=>u(()=>import("./guide.html-uQWUSL0p.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-21bccd79":()=>u(()=>import("./mkcp.html-uyvLxsmR.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-27001935":()=>u(()=>import("./muxcool.html-dKJnlJKP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-21b30c3f":()=>u(()=>import("./vless.html-oFhH_CKR.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-94110980":()=>u(()=>import("./vmess.html-tRW4iV5D.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-789ba7ef":()=>u(()=>import("./index.html-epCgXVFP.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-d3712ade":()=>u(()=>import("./ch01-preface.html-EhjqE-xm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-41f9c00e":()=>u(()=>import("./ch02-preparation.html-vmCsE7AE.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4c013f47":()=>u(()=>import("./ch03-ssh.html-7SR0w9_k.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-a75683b8":()=>u(()=>import("./ch04-security.html-AXaKPt5U.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f5341aec":()=>u(()=>import("./ch05-webpage.html-sRW5SJR3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4458f72a":()=>u(()=>import("./ch06-certificates.html-nx5r2spW.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-f1802e66":()=>u(()=>import("./ch07-xray-server.html-d6fAFDtx.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-4ca6f1ca":()=>u(()=>import("./ch08-xray-clients.html--7VTUdFB.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-b0030f00":()=>u(()=>import("./ch09-appendix.html-ocawR_gn.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-789ba80e":()=>u(()=>import("./index.html-9tqrbw4-.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-103b3e5c":()=>u(()=>import("./fallbacks-lv1.html-Ue5QjCC2.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-110dd688":()=>u(()=>import("./fallbacks-with-sni.html-L4x-DI-J.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c425a7d4":()=>u(()=>import("./routing-lv1-part1.html-uWcVLGTr.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c0bbf696":()=>u(()=>import("./routing-lv1-part2.html-77qV5nP4.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-5b6477cc":()=>u(()=>import("./work.html-DIaUDWrM.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-789ba82d":()=>u(()=>import("./index.html-6shuNL--.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-05ddc65d":()=>u(()=>import("./iptables_gid.html-chRdnVmo.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-474afe99":()=>u(()=>import("./nginx_or_haproxy_tls_tunnel.html-0TxfRNOy.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-930ac920":()=>u(()=>import("./redirect.html-FhWJ2sky.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-c579975c":()=>u(()=>import("./tproxy.html-ad4fKtf9.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7efb7c68":()=>u(()=>import("./tproxy_ipv4_and_ipv6.html-kIWOgIT3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-12a33bee":()=>u(()=>import("./traffic_stats.html-o6SE99UZ.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7d2b8478":()=>u(()=>import("./warp.html-4hKe1jqm.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-7689d7f3":()=>u(()=>import("./transparent_proxy.html-LpjOlZS3.js"),__vite__mapDeps([])).then(({data:e})=>e),"v-3706649a":()=>u(()=>import("./404.html-r6aI8Oiv.js"),__vite__mapDeps([])).then(({data:e})=>e)},Ou=JSON.parse('{"base":"/","lang":"en-US","title":"","description":"","head":[["link",{"rel":"icon","href":"/logo.png"}]],"locales":{"/":{"lang":"zh-CN","title":"Project X","description":"Xray 官方文档"},"/en/":{"lang":"en-US","title":"Project X","description":"Official document of Xray"}}}');var Au=["link","meta","script","style","noscript","template"],Ru=["title","base"],Iu=([e,t,l])=>Ru.includes(e)?e:Au.includes(e)?e==="meta"&&t.name?`${e}.${t.name}`:e==="template"&&t.id?`${e}.${t.id}`:JSON.stringify([e,Object.entries(t).map(([n,i])=>typeof i=="boolean"?i?[n,""]:null:[n,i]).filter(n=>n!=null).sort(([n],[i])=>n.localeCompare(i)),l]):null,Du=e=>{const t=new Set,l=[];return e.forEach(n=>{const i=Iu(n);i&&!t.has(i)&&(t.add(i),l.push(n))}),l},Xl=e=>/^(https?:)?\/\//.test(e),Su=e=>/^[a-z][a-z0-9+.-]*:/.test(e),Ni=e=>Object.prototype.toString.call(e)==="[object Object]",ds=e=>e[e.length-1]==="/"?e.slice(0,-1):e,hs=e=>e[0]==="/"?e.slice(1):e,fs=(e,t)=>{const l=Object.keys(e).sort((n,i)=>{const r=i.split("/").length-n.split("/").length;return r!==0?r:i.length-n.length});for(const n of l)if(t.startsWith(n))return n;return"/"},ju=e=>typeof e=="function",rt=e=>typeof e=="string";const vs={"v-8daa1a0e":g(()=>u(()=>import("./index.html-sJo1M-Sj.js"),__vite__mapDeps([]))),"v-aad48c6a":g(()=>u(()=>import("./news.html-ayZea3Z8.js"),__vite__mapDeps([]))),"v-ba934fd8":g(()=>u(()=>import("./index.html-cm8hOcNA.js"),__vite__mapDeps([]))),"v-41ade9da":g(()=>u(()=>import("./api.html-n2welLJa.js"),__vite__mapDeps([]))),"v-83dedd38":g(()=>u(()=>import("./dns.html-nzh_mzUH.js"),__vite__mapDeps([]))),"v-192a19b9":g(()=>u(()=>import("./fakedns.html-7yy_Hwj4.js"),__vite__mapDeps([]))),"v-7f6279d8":g(()=>u(()=>import("./inbound.html-LOzJibnU.js"),__vite__mapDeps([]))),"v-1d860c29":g(()=>u(()=>import("./log.html-7A6BNzqC.js"),__vite__mapDeps([]))),"v-fbaf47ec":g(()=>u(()=>import("./metrics.html-ebI0OPa_.js"),__vite__mapDeps([]))),"v-2367d756":g(()=>u(()=>import("./outbound.html-nhfh9iOW.js"),__vite__mapDeps([]))),"v-4ebec35a":g(()=>u(()=>import("./policy.html-RrAD2wsU.js"),__vite__mapDeps([]))),"v-31b7756a":g(()=>u(()=>import("./reverse.html-pdrvooXr.js"),__vite__mapDeps([]))),"v-70677432":g(()=>u(()=>import("./routing.html-mmvuVaFi.js"),__vite__mapDeps([]))),"v-7e21d6ae":g(()=>u(()=>import("./stats.html-hOtiN8ks.js"),__vite__mapDeps([]))),"v-e3dfff38":g(()=>u(()=>import("./transport.html-yVjoGdDV.js"),__vite__mapDeps([]))),"v-f7496066":g(()=>u(()=>import("./index.html-W0PzUpCJ.js"),__vite__mapDeps([]))),"v-36b1a79b":g(()=>u(()=>import("./index.html-x0joMVfy.js"),__vite__mapDeps([]))),"v-09a64f89":g(()=>u(()=>import("./command.html-GmQWX7Oz.js"),__vite__mapDeps([]))),"v-2b1adf48":g(()=>u(()=>import("./config.html-FFB6YdOZ.js"),__vite__mapDeps([]))),"v-86ee963a":g(()=>u(()=>import("./document.html-WKG-xpF1.js"),__vite__mapDeps([]))),"v-0e5d7b39":g(()=>u(()=>import("./install.html-H_t1fqr8.js"),__vite__mapDeps([]))),"v-2d0a870d":g(()=>u(()=>import("./index.html-xbzqWGZe.js"),__vite__mapDeps([]))),"v-0d714d87":g(()=>u(()=>import("./browser_dialer.html-ioRP4mhn.js"),__vite__mapDeps([]))),"v-0da7880a":g(()=>u(()=>import("./env.html-98sQ-YHZ.js"),__vite__mapDeps([]))),"v-2aeb21f9":g(()=>u(()=>import("./fallback.html-SRUkF-k8.js"),__vite__mapDeps([]))),"v-3acf20ea":g(()=>u(()=>import("./multiple.html-zE8J70pG.js"),__vite__mapDeps([]))),"v-792e28f8":g(()=>u(()=>import("./xtls.html-6RQbZOas.js"),__vite__mapDeps([]))),"v-b50d2334":g(()=>u(()=>import("./dokodemo.html-s_SNa9En.js"),__vite__mapDeps([]))),"v-593408b0":g(()=>u(()=>import("./http.html-gFUfd4hn.js"),__vite__mapDeps([]))),"v-802a842a":g(()=>u(()=>import("./shadowsocks.html-CX52is5W.js"),__vite__mapDeps([]))),"v-29995cea":g(()=>u(()=>import("./socks.html-RHePOH-J.js"),__vite__mapDeps([]))),"v-2a1b3d72":g(()=>u(()=>import("./trojan.html-MDx9UVlc.js"),__vite__mapDeps([]))),"v-fb92e8aa":g(()=>u(()=>import("./vless.html--6fAlyfP.js"),__vite__mapDeps([]))),"v-167afaac":g(()=>u(()=>import("./vmess.html-XpONl2yo.js"),__vite__mapDeps([]))),"v-749ad71a":g(()=>u(()=>import("./blackhole.html-2q5PndzG.js"),__vite__mapDeps([]))),"v-6d39b970":g(()=>u(()=>import("./dns.html-qUo2_myA.js"),__vite__mapDeps([]))),"v-d76e893a":g(()=>u(()=>import("./freedom.html-IBZ61bfy.js"),__vite__mapDeps([]))),"v-c6b4b59e":g(()=>u(()=>import("./http.html-FEDggO-p.js"),__vite__mapDeps([]))),"v-41ec0e0e":g(()=>u(()=>import("./loopback.html-hvdhvF1l.js"),__vite__mapDeps([]))),"v-7b293e4a":g(()=>u(()=>import("./shadowsocks.html-U6pVq6AU.js"),__vite__mapDeps([]))),"v-15f5452a":g(()=>u(()=>import("./socks.html-_F9IwK5H.js"),__vite__mapDeps([]))),"v-5797bdb3":g(()=>u(()=>import("./trojan.html-zN8km5_s.js"),__vite__mapDeps([]))),"v-a60f016c":g(()=>u(()=>import("./vless.html-K1mymGPl.js"),__vite__mapDeps([]))),"v-413cee4b":g(()=>u(()=>import("./vmess.html-5Z4DWDCo.js"),__vite__mapDeps([]))),"v-208ca3b9":g(()=>u(()=>import("./wireguard.html-BCZ3AkFH.js"),__vite__mapDeps([]))),"v-775db7b1":g(()=>u(()=>import("./domainsocket.html-zhkqh_tc.js"),__vite__mapDeps([]))),"v-2877542a":g(()=>u(()=>import("./grpc.html-wuI--JNX.js"),__vite__mapDeps([]))),"v-03a28284":g(()=>u(()=>import("./h2.html-XhOE9s1o.js"),__vite__mapDeps([]))),"v-04158536":g(()=>u(()=>import("./httpupgrade.html-8y62ZYsJ.js"),__vite__mapDeps([]))),"v-3167b1dd":g(()=>u(()=>import("./mkcp.html-censPzO_.js"),__vite__mapDeps([]))),"v-8f08dbec":g(()=>u(()=>import("./quic.html-WnhipFbM.js"),__vite__mapDeps([]))),"v-33b1b709":g(()=>u(()=>import("./tcp.html-A1382ftf.js"),__vite__mapDeps([]))),"v-1ff57bba":g(()=>u(()=>import("./websocket.html-G4eliqnC.js"),__vite__mapDeps([]))),"v-6a9e8054":g(()=>u(()=>import("./compile.html-p25837Gy.js"),__vite__mapDeps([]))),"v-95e3eaea":g(()=>u(()=>import("./design.html-fPrl8l20.js"),__vite__mapDeps([]))),"v-61e7eea6":g(()=>u(()=>import("./guide.html-yvvDMK2K.js"),__vite__mapDeps([]))),"v-6e6c37e6":g(()=>u(()=>import("./mkcp.html-P3j-P5YO.js"),__vite__mapDeps([]))),"v-13168a21":g(()=>u(()=>import("./muxcool.html-_Q_MClhY.js"),__vite__mapDeps([]))),"v-5c48c82b":g(()=>u(()=>import("./vless.html-w-KHS2qb.js"),__vite__mapDeps([]))),"v-1ee591a8":g(()=>u(()=>import("./vmess.html-14n3YBGD.js"),__vite__mapDeps([]))),"v-3f09dcfa":g(()=>u(()=>import("./index.html-JMYPbZuF.js"),__vite__mapDeps([]))),"v-fb444906":g(()=>u(()=>import("./ch01-preface.html-bIl_Km3k.js"),__vite__mapDeps([]))),"v-075f3ae5":g(()=>u(()=>import("./ch02-preparation.html-lZJv5DvE.js"),__vite__mapDeps([]))),"v-726d0633":g(()=>u(()=>import("./ch03-ssh.html-ZqJB8vGA.js"),__vite__mapDeps([]))),"v-430c6ab8":g(()=>u(()=>import("./ch04-security.html-33MaGmAV.js"),__vite__mapDeps([]))),"v-717c6376":g(()=>u(()=>import("./ch05-webpage.html-lTr31Joi.js"),__vite__mapDeps([]))),"v-278039be":g(()=>u(()=>import("./ch06-certificates.html-vz4TPMTq.js"),__vite__mapDeps([]))),"v-a0c7f88e":g(()=>u(()=>import("./ch07-xray-server.html-TVGmVR8g.js"),__vite__mapDeps([]))),"v-86586ca2":g(()=>u(()=>import("./ch08-xray-clients.html-s9iITOvA.js"),__vite__mapDeps([]))),"v-3eb62514":g(()=>u(()=>import("./ch09-appendix.html-Ouutf7uu.js"),__vite__mapDeps([]))),"v-3f09dcbc":g(()=>u(()=>import("./index.html-l5bGGUL1.js"),__vite__mapDeps([]))),"v-b21a2a20":g(()=>u(()=>import("./fallbacks-lv1.html--wD9yMzq.js"),__vite__mapDeps([]))),"v-da623318":g(()=>u(()=>import("./fallbacks-with-sni.html-bYbXLNvx.js"),__vite__mapDeps([]))),"v-fdd722ac":g(()=>u(()=>import("./routing-lv1-part1.html-s_m1VGph.js"),__vite__mapDeps([]))),"v-fa6d716e":g(()=>u(()=>import("./routing-lv1-part2.html-J8wCOEnV.js"),__vite__mapDeps([]))),"v-2f29e106":g(()=>u(()=>import("./work.html-HxgjsHti.js"),__vite__mapDeps([]))),"v-3f09dc7e":g(()=>u(()=>import("./index.html-GzgMAJYU.js"),__vite__mapDeps([]))),"v-1c17916e":g(()=>u(()=>import("./iptables_gid.html-f-TyOGt0.js"),__vite__mapDeps([]))),"v-a001cfa6":g(()=>u(()=>import("./nginx_or_haproxy_tls_tunnel.html-1_qLmdh0.js"),__vite__mapDeps([]))),"v-46333b48":g(()=>u(()=>import("./redirect.html-Fo5Y5X-S.js"),__vite__mapDeps([]))),"v-338bc63e":g(()=>u(()=>import("./tproxy.html-VWEtc--I.js"),__vite__mapDeps([]))),"v-d68f7d58":g(()=>u(()=>import("./tproxy_ipv4_and_ipv6.html-mtR0hhvb.js"),__vite__mapDeps([]))),"v-e533e2c6":g(()=>u(()=>import("./traffic_stats.html-qY70pWXT.js"),__vite__mapDeps([]))),"v-1e465ab0":g(()=>u(()=>import("./warp.html-InWQqDIT.js"),__vite__mapDeps([]))),"v-1080fb37":g(()=>u(()=>import("./news.html--Ypfy9X2.js"),__vite__mapDeps([]))),"v-317fc580":g(()=>u(()=>import("./index.html-uM2EqCct.js"),__vite__mapDeps([]))),"v-45144c7f":g(()=>u(()=>import("./api.html-obbK2QQ5.js"),__vite__mapDeps([]))),"v-23fbd2d0":g(()=>u(()=>import("./dns.html-C2aGNNlR.js"),__vite__mapDeps([]))),"v-2b7ec525":g(()=>u(()=>import("./fakedns.html-jPUstbOM.js"),__vite__mapDeps([]))),"v-5ab92300":g(()=>u(()=>import("./inbound.html-fVeoUFmr.js"),__vite__mapDeps([]))),"v-f91d64d6":g(()=>u(()=>import("./log.html-NTUL9-8j.js"),__vite__mapDeps([]))),"v-d705f114":g(()=>u(()=>import("./metrics.html-mI5FrxlZ.js"),__vite__mapDeps([]))),"v-268cd669":g(()=>u(()=>import("./outbound.html-c9chlcYi.js"),__vite__mapDeps([]))),"v-4492d567":g(()=>u(()=>import("./policy.html-60KZMSiW.js"),__vite__mapDeps([]))),"v-0d0e1e92":g(()=>u(()=>import("./reverse.html-w7txkdmv.js"),__vite__mapDeps([]))),"v-4bbe1d5a":g(()=>u(()=>import("./routing.html-oysaUhpj.js"),__vite__mapDeps([]))),"v-16426d1a":g(()=>u(()=>import("./stats.html-Ev72Xnyf.js"),__vite__mapDeps([]))),"v-5de780d0":g(()=>u(()=>import("./transport.html-mYn2VrkQ.js"),__vite__mapDeps([]))),"v-f88d343e":g(()=>u(()=>import("./index.html-RZwWF3O4.js"),__vite__mapDeps([]))),"v-38d56a07":g(()=>u(()=>import("./index.html-gKKe0Pu1.js"),__vite__mapDeps([]))),"v-4d046016":g(()=>u(()=>import("./command.html-Pk9D3c6o.js"),__vite__mapDeps([]))),"v-22b35270":g(()=>u(()=>import("./config.html-RkLhbZyp.js"),__vite__mapDeps([]))),"v-30bd7c12":g(()=>u(()=>import("./document.html-OTBh_E9Y.js"),__vite__mapDeps([]))),"v-439608b6":g(()=>u(()=>import("./install.html-VE-T3hko.js"),__vite__mapDeps([]))),"v-51a51d87":g(()=>u(()=>import("./transparent_proxy.html-bIbjewZt.js"),__vite__mapDeps([]))),"v-76b9a0f3":g(()=>u(()=>import("./browser_dialer.html-oLr7tN0I.js"),__vite__mapDeps([]))),"v-565dbfc4":g(()=>u(()=>import("./env.html-Wh-9-BVt.js"),__vite__mapDeps([]))),"v-0fbd1336":g(()=>u(()=>import("./fallback.html-GSgUfNDP.js"),__vite__mapDeps([]))),"v-a0627812":g(()=>u(()=>import("./multiple.html-iAO2Lnc3.js"),__vite__mapDeps([]))),"v-d190d938":g(()=>u(()=>import("./xtls.html-5PMkSJTh.js"),__vite__mapDeps([]))),"v-72afc2d2":g(()=>u(()=>import("./dokodemo.html-9tXE84yJ.js"),__vite__mapDeps([]))),"v-773d731c":g(()=>u(()=>import("./http.html-PUYLTCZT.js"),__vite__mapDeps([]))),"v-f555fc02":g(()=>u(()=>import("./shadowsocks.html-2sZeanJM.js"),__vite__mapDeps([]))),"v-e35196c2":g(()=>u(()=>import("./socks.html-AQ8z9yrR.js"),__vite__mapDeps([]))),"v-29188644":g(()=>u(()=>import("./trojan.html-5IABW9eX.js"),__vite__mapDeps([]))),"v-255a6ebf":g(()=>u(()=>import("./vless.html-RePhqH5Q.js"),__vite__mapDeps([]))),"v-8cc24480":g(()=>u(()=>import("./vmess.html-BwXqJ3Vn.js"),__vite__mapDeps([]))),"v-64e47ef4":g(()=>u(()=>import("./blackhole.html-MeysKqPJ.js"),__vite__mapDeps([]))),"v-e979b848":g(()=>u(()=>import("./dns.html-s7z_7JTn.js"),__vite__mapDeps([]))),"v-617f0fcf":g(()=>u(()=>import("./freedom.html-vLTb4l01.js"),__vite__mapDeps([]))),"v-3fc98845":g(()=>u(()=>import("./http.html-_yXVXvnY.js"),__vite__mapDeps([]))),"v-1b804722":g(()=>u(()=>import("./loopback.html-Bzq00ZYC.js"),__vite__mapDeps([]))),"v-63077cb6":g(()=>u(()=>import("./shadowsocks.html-qiN3SGfm.js"),__vite__mapDeps([]))),"v-516476d4":g(()=>u(()=>import("./socks.html-SJq0hqhp.js"),__vite__mapDeps([]))),"v-7d61a872":g(()=>u(()=>import("./trojan.html-O_FJql5l.js"),__vite__mapDeps([]))),"v-6e50feb6":g(()=>u(()=>import("./vless.html-62T-Q8OK.js"),__vite__mapDeps([]))),"v-02956db7":g(()=>u(()=>import("./vmess.html-bWXrud15.js"),__vite__mapDeps([]))),"v-797f8d25":g(()=>u(()=>import("./wireguard.html-K_sm3lda.js"),__vite__mapDeps([]))),"v-3eb3e9c6":g(()=>u(()=>import("./domainsocket.html-fCTWcn10.js"),__vite__mapDeps([]))),"v-2c6058d4":g(()=>u(()=>import("./grpc.html-m78M3EJR.js"),__vite__mapDeps([]))),"v-1c38292a":g(()=>u(()=>import("./h2.html-8klqPb9j.js"),__vite__mapDeps([]))),"v-17ff144a":g(()=>u(()=>import("./httpupgrade.html-HCGGfbXe.js"),__vite__mapDeps([]))),"v-1a7f9d6e":g(()=>u(()=>import("./mkcp.html-DONGnnA_.js"),__vite__mapDeps([]))),"v-79d41176":g(()=>u(()=>import("./quic.html-2dnyw5D-.js"),__vite__mapDeps([]))),"v-5254cbc6":g(()=>u(()=>import("./tcp.html-ZlB-8N_8.js"),__vite__mapDeps([]))),"v-9520f392":g(()=>u(()=>import("./websocket.html-fT5fCDqV.js"),__vite__mapDeps([]))),"v-b7760e2c":g(()=>u(()=>import("./compile.html-B6Lx1oYG.js"),__vite__mapDeps([]))),"v-fb774212":g(()=>u(()=>import("./design.html-2PskSFhP.js"),__vite__mapDeps([]))),"v-38c376c1":g(()=>u(()=>import("./guide.html-rhDtidv8.js"),__vite__mapDeps([]))),"v-21bccd79":g(()=>u(()=>import("./mkcp.html-i8OOkSjS.js"),__vite__mapDeps([]))),"v-27001935":g(()=>u(()=>import("./muxcool.html-mWlirYUy.js"),__vite__mapDeps([]))),"v-21b30c3f":g(()=>u(()=>import("./vless.html-TuQcbXVI.js"),__vite__mapDeps([]))),"v-94110980":g(()=>u(()=>import("./vmess.html-Q9QMl6ca.js"),__vite__mapDeps([]))),"v-789ba7ef":g(()=>u(()=>import("./index.html-qxx9ljxd.js"),__vite__mapDeps([]))),"v-d3712ade":g(()=>u(()=>import("./ch01-preface.html-Xp85YRwD.js"),__vite__mapDeps([]))),"v-41f9c00e":g(()=>u(()=>import("./ch02-preparation.html-flUUoP_1.js"),__vite__mapDeps([]))),"v-4c013f47":g(()=>u(()=>import("./ch03-ssh.html-PreKlYZo.js"),__vite__mapDeps([]))),"v-a75683b8":g(()=>u(()=>import("./ch04-security.html-zUuYrXhG.js"),__vite__mapDeps([]))),"v-f5341aec":g(()=>u(()=>import("./ch05-webpage.html-H5TsNIcu.js"),__vite__mapDeps([]))),"v-4458f72a":g(()=>u(()=>import("./ch06-certificates.html-vKtVQYmc.js"),__vite__mapDeps([]))),"v-f1802e66":g(()=>u(()=>import("./ch07-xray-server.html-M88Oyw5u.js"),__vite__mapDeps([]))),"v-4ca6f1ca":g(()=>u(()=>import("./ch08-xray-clients.html-VmriEsh2.js"),__vite__mapDeps([]))),"v-b0030f00":g(()=>u(()=>import("./ch09-appendix.html-BpoURQUR.js"),__vite__mapDeps([]))),"v-789ba80e":g(()=>u(()=>import("./index.html-p2MYx25S.js"),__vite__mapDeps([]))),"v-103b3e5c":g(()=>u(()=>import("./fallbacks-lv1.html-SBMi_sxl.js"),__vite__mapDeps([]))),"v-110dd688":g(()=>u(()=>import("./fallbacks-with-sni.html-EwR1fYMf.js"),__vite__mapDeps([]))),"v-c425a7d4":g(()=>u(()=>import("./routing-lv1-part1.html-WHpw4v1x.js"),__vite__mapDeps([]))),"v-c0bbf696":g(()=>u(()=>import("./routing-lv1-part2.html-FFYQ14md.js"),__vite__mapDeps([]))),"v-5b6477cc":g(()=>u(()=>import("./work.html-fccvP5Wo.js"),__vite__mapDeps([]))),"v-789ba82d":g(()=>u(()=>import("./index.html-ecj8aV3P.js"),__vite__mapDeps([]))),"v-05ddc65d":g(()=>u(()=>import("./iptables_gid.html-XKlKifPE.js"),__vite__mapDeps([]))),"v-474afe99":g(()=>u(()=>import("./nginx_or_haproxy_tls_tunnel.html-J7GQDlYh.js"),__vite__mapDeps([]))),"v-930ac920":g(()=>u(()=>import("./redirect.html-b2j-2sFY.js"),__vite__mapDeps([]))),"v-c579975c":g(()=>u(()=>import("./tproxy.html-nklfTqvg.js"),__vite__mapDeps([]))),"v-7efb7c68":g(()=>u(()=>import("./tproxy_ipv4_and_ipv6.html-YTH3X_7C.js"),__vite__mapDeps([]))),"v-12a33bee":g(()=>u(()=>import("./traffic_stats.html-HWyX5twA.js"),__vite__mapDeps([]))),"v-7d2b8478":g(()=>u(()=>import("./warp.html-Nyf1dpD9.js"),__vite__mapDeps([]))),"v-7689d7f3":g(()=>u(()=>import("./transparent_proxy.html-RiPSpqp_.js"),__vite__mapDeps([]))),"v-3706649a":g(()=>u(()=>import("./404.html-ZlBMbAmj.js"),__vite__mapDeps([])))};var Cu=Symbol(""),ps=Symbol(""),Vu=Rn({key:"",path:"",title:"",lang:"",frontmatter:{},headers:[]}),al=()=>{const e=Te(ps);if(!e)throw new Error("pageData() is called without provider.");return e},ms=Symbol(""),_t=()=>{const e=Te(ms);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},gs=Symbol(""),Fu=()=>{const e=Te(gs);if(!e)throw new Error("usePageHead() is called without provider.");return e},Nu=Symbol(""),_s=Symbol(""),Mu=()=>{const e=Te(_s);if(!e)throw new Error("usePageLang() is called without provider.");return e},bs=Symbol(""),Hu=()=>{const e=Te(bs);if(!e)throw new Error("usePageLayout() is called without provider.");return e},$u=ge(wu),Mi=Symbol(""),Gl=()=>{const e=Te(Mi);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},ll=ge(Ou),ks=()=>ll,ys=Symbol(""),Hi=()=>{const e=Te(ys);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},Bu=Symbol(""),zu="Layout",Wu="NotFound",vt=Bl({resolveLayouts:e=>e.reduce((t,l)=>({...t,...l.layouts}),{}),resolvePageData:async e=>{const t=$u.value[e];return await(t==null?void 0:t())??Vu},resolvePageFrontmatter:e=>e.frontmatter,resolvePageHead:(e,t,l)=>{const n=rt(t.description)?t.description:l.description,i=[...Array.isArray(t.head)?t.head:[],...l.head,["title",{},e],["meta",{name:"description",content:n}]];return Du(i)},resolvePageHeadTitle:(e,t)=>[e.title,t.title].filter(l=>!!l).join(" | "),resolvePageLang:(e,t)=>e.lang||t.lang||"en-US",resolvePageLayout:(e,t)=>{let l;if(e.path){const n=e.frontmatter.layout;rt(n)?l=n:l=zu}else l=Wu;return t[l]},resolveRouteLocale:(e,t)=>fs(e,t),resolveSiteLocaleData:(e,t)=>{var l;return{...e,...e.locales[t],head:[...((l=e.locales[t])==null?void 0:l.head)??[],...e.head??[]]}}}),$i=pe({name:"ClientOnly",setup(e,t){const l=ge(!1);return ze(()=>{l.value=!0}),()=>{var n,i;return l.value?(i=(n=t.slots).default)==null?void 0:i.call(n):null}}}),Uu=pe({name:"Content",props:{pageKey:{type:String,required:!1,default:""}},setup(e){const t=al(),l=H(()=>vs[e.pageKey||t.value.key]);return()=>l.value?fe(l.value):fe("div","404 Not Found")}}),Nt=(e={})=>e,Bi=e=>Xl(e)?e:`/${hs(e)}`;function Es(e,t,l){var n,i,r;t===void 0&&(t=50),l===void 0&&(l={});var o=(n=l.isImmediate)!=null&&n,s=(i=l.callback)!=null&&i,a=l.maxWait,c=Date.now(),d=[];function h(){if(a!==void 0){var m=Date.now()-c;if(m+t>=a)return a-m}return t}var f=function(){var m=[].slice.call(arguments),k=this;return new Promise(function(T,w){var I=o&&r===void 0;if(r!==void 0&&clearTimeout(r),r=setTimeout(function(){if(r=void 0,c=Date.now(),!o){var b=e.apply(k,m);s&&s(b),d.forEach(function(E){return(0,E.resolve)(b)}),d=[]}},h()),I){var R=e.apply(k,m);return s&&s(R),T(R)}d.push({resolve:T,reject:w})})};return f.cancel=function(m){r!==void 0&&clearTimeout(r),d.forEach(function(k){return(0,k.reject)(m)}),d=[]},f}/*!
   * vue-router v4.2.5
   * (c) 2023 Eduardo San Martin Morote
   * @license MIT
@@ -7,7 +7,7 @@ Expects a CSS selector, a Node element, a NodeList or an array.
 See: https://github.com/francoischalifour/medium-zoom`)}},ch=function(t){var l=document.createElement("div");return l.classList.add("medium-zoom-overlay"),l.style.background=t,l},uh=function(t){var l=t.getBoundingClientRect(),n=l.top,i=l.left,r=l.width,o=l.height,s=t.cloneNode(),a=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,c=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;return s.removeAttribute("id"),s.style.position="absolute",s.style.top=n+a+"px",s.style.left=i+c+"px",s.style.width=r+"px",s.style.height=o+"px",s.style.transform="",s},el=function(t,l){var n=Bt({bubbles:!1,cancelable:!1,detail:void 0},l);if(typeof window.CustomEvent=="function")return new CustomEvent(t,n);var i=document.createEvent("CustomEvent");return i.initCustomEvent(t,n.bubbles,n.cancelable,n.detail),i},dh=function e(t){var l=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=window.Promise||function(x){function C(){}x(C,C)},i=function(x){var C=x.target;if(C===q){k();return}b.indexOf(C)!==-1&&T({target:C})},r=function(){if(!(F||!y.original)){var x=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(G-x)>N.scrollOffset&&setTimeout(k,150)}},o=function(x){var C=x.key||x.keyCode;(C==="Escape"||C==="Esc"||C===27)&&k()},s=function(){var x=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},C=x;if(x.background&&(q.style.background=x.background),x.container&&x.container instanceof Object&&(C.container=Bt({},N.container,x.container)),x.template){var ne=hn(x.template)?x.template:document.querySelector(x.template);C.template=ne}return N=Bt({},N,C),b.forEach(function(se){se.dispatchEvent(el("medium-zoom:update",{detail:{zoom:O}}))}),O},a=function(){var x=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};return e(Bt({},N,x))},c=function(){for(var x=arguments.length,C=Array(x),ne=0;ne0?C.reduce(function(j,Q){return[].concat(j,lo(Q))},[]):b;return se.forEach(function(j){j.classList.remove("medium-zoom-image"),j.dispatchEvent(el("medium-zoom:detach",{detail:{zoom:O}}))}),b=b.filter(function(j){return se.indexOf(j)===-1}),O},h=function(x,C){var ne=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return b.forEach(function(se){se.addEventListener("medium-zoom:"+x,C,ne)}),E.push({type:"medium-zoom:"+x,listener:C,options:ne}),O},f=function(x,C){var ne=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};return b.forEach(function(se){se.removeEventListener("medium-zoom:"+x,C,ne)}),E=E.filter(function(se){return!(se.type==="medium-zoom:"+x&&se.listener.toString()===C.toString())}),O},m=function(){var x=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},C=x.target,ne=function(){var j={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},Q=void 0,K=void 0;if(N.container)if(N.container instanceof Object)j=Bt({},j,N.container),Q=j.width-j.left-j.right-N.margin*2,K=j.height-j.top-j.bottom-N.margin*2;else{var Se=hn(N.container)?N.container:document.querySelector(N.container),Ce=Se.getBoundingClientRect(),We=Ce.width,He=Ce.height,xt=Ce.left,Lt=Ce.top;j=Bt({},j,{width:We,height:He,left:xt,top:Lt})}Q=Q||j.width-N.margin*2,K=K||j.height-N.margin*2;var st=y.zoomedHd||y.original,je=to(st)?Q:st.naturalWidth||Q,P=to(st)?K:st.naturalHeight||K,U=st.getBoundingClientRect(),M=U.top,Y=U.left,ce=U.width,v=U.height,p=Math.min(Math.max(ce,je),Q)/ce,_=Math.min(Math.max(v,P),K)/v,L=Math.min(p,_),A=(-Y+(Q-ce)/2+N.margin+j.left)/L,D=(-M+(K-v)/2+N.margin+j.top)/L,B="scale("+L+") translate3d("+A+"px, "+D+"px, 0)";y.zoomed.style.transform=B,y.zoomedHd&&(y.zoomedHd.style.transform=B)};return new n(function(se){if(C&&b.indexOf(C)===-1){se(O);return}var j=function We(){F=!1,y.zoomed.removeEventListener("transitionend",We),y.original.dispatchEvent(el("medium-zoom:opened",{detail:{zoom:O}})),se(O)};if(y.zoomed){se(O);return}if(C)y.original=C;else if(b.length>0){var Q=b;y.original=Q[0]}else{se(O);return}if(y.original.dispatchEvent(el("medium-zoom:open",{detail:{zoom:O}})),G=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,F=!0,y.zoomed=uh(y.original),document.body.appendChild(q),N.template){var K=hn(N.template)?N.template:document.querySelector(N.template);y.template=document.createElement("div"),y.template.appendChild(K.content.cloneNode(!0)),document.body.appendChild(y.template)}if(y.original.parentElement&&y.original.parentElement.tagName==="PICTURE"&&y.original.currentSrc&&(y.zoomed.src=y.original.currentSrc),document.body.appendChild(y.zoomed),window.requestAnimationFrame(function(){document.body.classList.add("medium-zoom--opened")}),y.original.classList.add("medium-zoom-image--hidden"),y.zoomed.classList.add("medium-zoom-image--opened"),y.zoomed.addEventListener("click",k),y.zoomed.addEventListener("transitionend",j),y.original.getAttribute("data-zoom-src")){y.zoomedHd=y.zoomed.cloneNode(),y.zoomedHd.removeAttribute("srcset"),y.zoomedHd.removeAttribute("sizes"),y.zoomedHd.removeAttribute("loading"),y.zoomedHd.src=y.zoomed.getAttribute("data-zoom-src"),y.zoomedHd.onerror=function(){clearInterval(Se),console.warn("Unable to reach the zoom image target "+y.zoomedHd.src),y.zoomedHd=null,ne()};var Se=setInterval(function(){y.zoomedHd.complete&&(clearInterval(Se),y.zoomedHd.classList.add("medium-zoom-image--opened"),y.zoomedHd.addEventListener("click",k),document.body.appendChild(y.zoomedHd),ne())},10)}else if(y.original.hasAttribute("srcset")){y.zoomedHd=y.zoomed.cloneNode(),y.zoomedHd.removeAttribute("sizes"),y.zoomedHd.removeAttribute("loading");var Ce=y.zoomedHd.addEventListener("load",function(){y.zoomedHd.removeEventListener("load",Ce),y.zoomedHd.classList.add("medium-zoom-image--opened"),y.zoomedHd.addEventListener("click",k),document.body.appendChild(y.zoomedHd),ne()})}else ne()})},k=function(){return new n(function(x){if(F||!y.original){x(O);return}var C=function ne(){y.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(y.zoomed),y.zoomedHd&&document.body.removeChild(y.zoomedHd),document.body.removeChild(q),y.zoomed.classList.remove("medium-zoom-image--opened"),y.template&&document.body.removeChild(y.template),F=!1,y.zoomed.removeEventListener("transitionend",ne),y.original.dispatchEvent(el("medium-zoom:closed",{detail:{zoom:O}})),y.original=null,y.zoomed=null,y.zoomedHd=null,y.template=null,x(O)};F=!0,document.body.classList.remove("medium-zoom--opened"),y.zoomed.style.transform="",y.zoomedHd&&(y.zoomedHd.style.transform=""),y.template&&(y.template.style.transition="opacity 150ms",y.template.style.opacity=0),y.original.dispatchEvent(el("medium-zoom:close",{detail:{zoom:O}})),y.zoomed.addEventListener("transitionend",C)})},T=function(){var x=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},C=x.target;return y.original?k():m({target:C})},w=function(){return N},I=function(){return b},R=function(){return y.original},b=[],E=[],F=!1,G=0,N=l,y={original:null,zoomed:null,zoomedHd:null,template:null};Object.prototype.toString.call(t)==="[object Object]"?N=t:(t||typeof t=="string")&&c(t),N=Bt({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},N);var q=ch(N.background);document.addEventListener("click",i),document.addEventListener("keyup",o),document.addEventListener("scroll",r),window.addEventListener("resize",k);var O={open:m,close:k,toggle:T,update:s,clone:a,attach:c,detach:d,on:h,off:f,getOptions:w,getImages:I,getZoomedImage:R};return O};function hh(e,t){t===void 0&&(t={});var l=t.insertAt;if(!(!e||typeof document>"u")){var n=document.head||document.getElementsByTagName("head")[0],i=document.createElement("style");i.type="text/css",l==="top"&&n.firstChild?n.insertBefore(i,n.firstChild):n.appendChild(i),i.styleSheet?i.styleSheet.cssText=e:i.appendChild(document.createTextNode(e))}}var fh=".medium-zoom-overlay{position:fixed;top:0;right:0;bottom:0;left:0;opacity:0;transition:opacity .3s;will-change:opacity}.medium-zoom--opened .medium-zoom-overlay{cursor:pointer;cursor:zoom-out;opacity:1}.medium-zoom-image{cursor:pointer;cursor:zoom-in;transition:transform .3s cubic-bezier(.2,0,.2,1)!important}.medium-zoom-image--hidden{visibility:hidden}.medium-zoom-image--opened{position:relative;cursor:pointer;cursor:zoom-out;will-change:transform}";hh(fh);const vh=Symbol("mediumZoom");var ph={};const mh=".theme-default-content > img, .theme-default-content :not(a) > img",gh=ph,_h=300,bh=Nt({enhance({app:e,router:t}){const l=dh(gh);l.refresh=(n=mh)=>{l.detach(),l.attach(n)},e.provide(vh,l),t.afterEach(()=>{setTimeout(()=>l.refresh(),_h)})}});/**
  * NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
  * @license MIT
- */const ue={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
'},status:null,set:e=>{const t=ue.isStarted();e=ei(e,ue.settings.minimum,1),ue.status=e===1?null:e;const l=ue.render(!t),n=l.querySelector(ue.settings.barSelector),i=ue.settings.speed,r=ue.settings.easing;return l.offsetWidth,kh(o=>{sn(n,{transform:"translate3d("+no(e)+"%,0,0)",transition:"all "+i+"ms "+r}),e===1?(sn(l,{transition:"none",opacity:"1"}),l.offsetWidth,setTimeout(function(){sn(l,{transition:"all "+i+"ms linear",opacity:"0"}),setTimeout(function(){ue.remove(),o()},i)},i)):setTimeout(()=>o(),i)}),ue},isStarted:()=>typeof ue.status=="number",start:()=>{ue.status||ue.set(0);const e=()=>{setTimeout(()=>{ue.status&&(ue.trickle(),e())},ue.settings.trickleSpeed)};return ue.settings.trickle&&e(),ue},done:e=>!e&&!ue.status?ue:ue.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=ue.status;return t?(typeof e!="number"&&(e=(1-t)*ei(Math.random()*t,.1,.95)),t=ei(t+e,0,.994),ue.set(t)):ue.start()},trickle:()=>ue.inc(Math.random()*ue.settings.trickleRate),render:e=>{if(ue.isRendered())return document.getElementById("nprogress");io(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=ue.settings.template;const l=t.querySelector(ue.settings.barSelector),n=e?"-100":no(ue.status||0),i=document.querySelector(ue.settings.parent);return sn(l,{transition:"all 0 linear",transform:"translate3d("+n+"%,0,0)"}),i!==document.body&&io(i,"nprogress-custom-parent"),i==null||i.appendChild(t),t},remove:()=>{ro(document.documentElement,"nprogress-busy"),ro(document.querySelector(ue.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&yh(e)},isRendered:()=>!!document.getElementById("nprogress")},ei=(e,t,l)=>el?l:e,no=e=>(-1+e)*100,kh=function(){const e=[];function t(){const l=e.shift();l&&l(t)}return function(l){e.push(l),e.length===1&&t()}}(),sn=function(){const e=["Webkit","O","Moz","ms"],t={};function l(o){return o.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(s,a){return a.toUpperCase()})}function n(o){const s=document.body.style;if(o in s)return o;let a=e.length;const c=o.charAt(0).toUpperCase()+o.slice(1);let d;for(;a--;)if(d=e[a]+c,d in s)return d;return o}function i(o){return o=l(o),t[o]??(t[o]=n(o))}function r(o,s,a){s=i(s),o.style[s]=a}return function(o,s){for(const a in s){const c=s[a];c!==void 0&&Object.prototype.hasOwnProperty.call(s,a)&&r(o,a,c)}}}(),js=(e,t)=>(typeof e=="string"?e:Ui(e)).indexOf(" "+t+" ")>=0,io=(e,t)=>{const l=Ui(e),n=l+t;js(l,t)||(e.className=n.substring(1))},ro=(e,t)=>{const l=Ui(e);if(!js(e,t))return;const n=l.replace(" "+t+" "," ");e.className=n.substring(1,n.length-1)},Ui=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),yh=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)},Eh=()=>{ze(()=>{const e=yt(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(l=>{t.has(l.path)||ue.start()}),e.afterEach(l=>{t.add(l.path),ue.done()})})},xh=Nt({setup(){Eh()}}),Lh=JSON.parse(`{"name":"vuepress-theme-xray","smoothScroll":true,"repo":"xtls/xray-core","docsDir":"docs","docsRepo":"xtls/Xray-docs-next","docsBranch":"main","editLinks":true,"enableToggle":true,"locales":{"/":{"navbar":[{"text":"首页","link":"/"},{"text":"大史记","link":"/about/news.md"},{"text":"配置指南","link":"/config/"},{"text":"开发指南","link":"/development/"},{"text":"使用指南","link":"/document/"}],"sidebar":{"/config/":[{"text":"特性详解","children":["/config/features/xtls.md","/config/features/fallback.md","/config/features/browser_dialer.md","/config/features/env.md","/config/features/multiple.md"]},{"text":"基础配置","children":["/config/README.md","/config/log.md","/config/api.md","/config/dns.md","/config/fakedns.md","/config/inbound.md","/config/outbound.md","/config/policy.md","/config/reverse.md","/config/routing.md","/config/stats.md","/config/transport.md","/config/metrics.md"]},{"text":"入站代理","children":["/config/inbounds/dokodemo.md","/config/inbounds/http.md","/config/inbounds/shadowsocks.md","/config/inbounds/socks.md","/config/inbounds/trojan.md","/config/inbounds/vless.md","/config/inbounds/vmess.md"]},{"text":"出站代理","children":["/config/outbounds/blackhole.md","/config/outbounds/dns.md","/config/outbounds/freedom.md","/config/outbounds/http.md","/config/outbounds/loopback.md","/config/outbounds/shadowsocks.md","/config/outbounds/socks.md","/config/outbounds/trojan.md","/config/outbounds/vless.md","/config/outbounds/vmess.md","/config/outbounds/wireguard.md"]},{"text":"底层传输","children":["/config/transports/domainsocket.md","/config/transports/grpc.md","/config/transports/h2.md","/config/transports/mkcp.md","/config/transports/quic.md","/config/transports/tcp.md","/config/transports/websocket.md","/config/transports/httpupgrade.md"]}],"/document/":[{"text":"快速入门文档","children":["/document/README.md","/document/install.md","/document/config.md","/document/command.md","/document/document.md"]},{"text":"小小白白话文","children":["/document/level-0/README.md","/document/level-0/ch01-preface.md","/document/level-0/ch02-preparation.md","/document/level-0/ch03-ssh.md","/document/level-0/ch04-security.md","/document/level-0/ch05-webpage.md","/document/level-0/ch06-certificates.md","/document/level-0/ch07-xray-server.md","/document/level-0/ch08-xray-clients.md","/document/level-0/ch09-appendix.md"]},{"text":"入门技巧","children":["/document/level-1/README.md","/document/level-1/fallbacks-lv1.md","/document/level-1/routing-lv1-part1.md","/document/level-1/routing-lv1-part2.md","/document/level-1/work.md","/document/level-1/fallbacks-with-sni.md"]},{"text":"进阶技巧","children":["/document/level-2/README.md","/document/level-2/transparent_proxy/transparent_proxy.md","/document/level-2/tproxy.md","/document/level-2/tproxy_ipv4_and_ipv6.md","/document/level-2/nginx_or_haproxy_tls_tunnel.md","/document/level-2/iptables_gid.md","/document/level-2/redirect.md","/document/level-2/warp.md","/document/level-2/traffic_stats.md"]}],"/development/":[{"text":"开发指南","children":["/development/README.md","/development/intro/compile.md","/development/intro/design.md","/development/intro/guide.md"]},{"text":"协议详解","children":["/development/protocols/vless.md","/development/protocols/vmess.md","/development/protocols/muxcool.md","/development/protocols/mkcp.md"]}]},"repoLabel":"查看源码","editLinkText":"帮助我们改善此页面!","tip":"提示","warning":"注意","danger":"警告","lastUpdatedText":"最近更改","selectLanguageName":"简体中文","selectLanguageText":"多语言","selectLanguageAriaLabel":"多语言","docsDir":"docs","backToHome":"back to home","openInNewWindow":"open in new tag","toggleColorMode":"toggle color mode","toggleSidebar":"toggle side bar"},"/en/":{"sidebar":{"/en/config/":[{"text":"feature","children":["/en/config/features/xtls.md","/en/config/features/fallback.md","/en/config/features/browser_dialer.md","/en/config/features/env.md","/en/config/features/multiple.md"]},{"text":"config","children":["/en/config/README.md","/en/config/log.md","/en/config/api.md","/en/config/dns.md","/en/config/fakedns.md","/en/config/inbound.md","/en/config/outbound.md","/en/config/policy.md","/en/config/reverse.md","/en/config/routing.md","/en/config/stats.md","/en/config/transport.md","/en/config/metrics.md"]},{"text":"inbound","children":["/en/config/inbounds/dokodemo.md","/en/config/inbounds/http.md","/en/config/inbounds/shadowsocks.md","/en/config/inbounds/socks.md","/en/config/inbounds/trojan.md","/en/config/inbounds/vless.md","/en/config/inbounds/vmess.md"]},{"text":"outbound","children":["/en/config/outbounds/blackhole.md","/en/config/outbounds/dns.md","/en/config/outbounds/freedom.md","/en/config/outbounds/http.md","/en/config/outbounds/loopback.md","/en/config/outbounds/shadowsocks.md","/en/config/outbounds/socks.md","/en/config/outbounds/trojan.md","/en/config/outbounds/vless.md","/en/config/outbounds/vmess.md","/en/config/outbounds/wireguard.md"]},{"text":"transport","children":["/en/config/transports/domainsocket.md","/en/config/transports/grpc.md","/en/config/transports/h2.md","/en/config/transports/mkcp.md","/en/config/transports/quic.md","/en/config/transports/tcp.md","/en/config/transports/websocket.md","/en/config/transports/httpupgrade.md"]}],"/en/document/":[{"text":"Quick Start","children":["/en/document/README.md","/en/document/install.md","/en/document/config.md","/en/document/command.md","/en/document/document.md"]},{"text":"Beginner Tutorial","children":["/en/document/level-0/README.md","/en/document/level-0/ch01-preface.md","/en/document/level-0/ch02-preparation.md","/en/document/level-0/ch03-ssh.md","/en/document/level-0/ch04-security.md","/en/document/level-0/ch05-webpage.md","/en/document/level-0/ch06-certificates.md","/en/document/level-0/ch07-xray-server.md","/en/document/level-0/ch08-xray-clients.md","/en/document/level-0/ch09-appendix.md"]},{"text":"Getting Started Tips","children":["/en/document/level-1/README.md","/en/document/level-1/fallbacks-lv1.md","/en/document/level-1/routing-lv1-part1.md","/en/document/level-1/routing-lv1-part2.md","/en/document/level-1/work.md","/en/document/level-1/fallbacks-with-sni.md"]},{"text":"Advanced Documentation","children":["/en/document/level-2/README.md","/en/document/level-2/transparent_proxy/transparent_proxy.md","/en/document/level-2/tproxy.md","/en/document/level-2/tproxy_ipv4_and_ipv6.md","/en/document/level-2/nginx_or_haproxy_tls_tunnel.md","/en/document/level-2/iptables_gid.md","/en/document/level-2/redirect.md","/en/document/level-2/warp.md","/en/document/level-2/traffic_stats.md"]}],"/en/development/":[{"text":"Developer Guide","children":["/en/development/README.md","/en/development/intro/compile.md","/en/development/intro/design.md","/en/development/intro/guide.md"]},{"text":"Protocol Details","children":["/en/development/protocols/vless.md","/en/development/protocols/vmess.md","/en/development/protocols/muxcool.md","/en/development/protocols/mkcp.md"]}]},"navbar":[{"text":"Homepage","link":"/en"},{"text":"Website History","link":"/en/about/news.md"},{"text":"Config Reference","link":"/en/config/"},{"text":"Developer Guide","link":"/en/development/"},{"text":"Quick Start","link":"/en/document/"}],"selectLanguageName":"English (WIP)","selectLanguageText":"Multiple language","selectLanguageAriaLabel":"Multiple language","editLinkText":"Help us improve this page on GitHub!","lastUpdatedText":"Last Updated","contributorsText":"contributors","tip":"Tip","warning":"Warning","danger":"Danger","notFound":["这里什么都没有","我们怎么到这来了?","这是一个 404 页面","看起来我们进入了错误的链接"],"backToHome":"back to home","openInNewWindow":"open in new tag","toggleColorMode":"toggle color mode","toggleSidebar":"toggle side bar"},"themePlugins":{"git":true}},"colorMode":"auto","colorModeSwitch":true,"navbar":[],"logo":null,"selectLanguageText":"Languages","selectLanguageAriaLabel":"Select language","sidebar":"auto","sidebarDepth":2,"editLink":true,"editLinkText":"Edit this page","lastUpdated":true,"lastUpdatedText":"Last Updated","contributors":true,"contributorsText":"Contributors","notFound":["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],"backToHome":"Take me home","openInNewWindow":"open in new window","toggleColorMode":"toggle color mode","toggleSidebar":"toggle sidebar"}`),Th=ge(Lh),Cs=()=>Th,Vs=Symbol(""),Ph=()=>{const e=Te(Vs);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},wh=(e,t)=>{const{locales:l,...n}=e;return{...n,...l==null?void 0:l[t]}},Oh=Nt({enhance({app:e}){const t=Cs(),l=e._context.provides[Mi],n=H(()=>wh(t.value,l.value));e.provide(Vs,n),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return n.value}}})}}),Ah=pe({__name:"Badge",props:{type:{type:String,required:!1,default:"tip"},text:{type:String,required:!1,default:""},vertical:{type:String,required:!1,default:void 0}},setup(e){return(t,l)=>(z(),ee("span",{class:Ke(["badge",e.type]),style:$l({verticalAlign:e.vertical})},[ke(t.$slots,"default",{},()=>[Ft(Ie(e.text),1)])],6))}}),Le=(e,t)=>{const l=e.__vccOpts||e;for(const[n,i]of t)l[n]=i;return l},Rh=Le(Ah,[["__file","Badge.vue"]]);function Ih(e,t){let l,n,i;const r=ge(!0),o=()=>{r.value=!0,i()};Ye(e,o,{flush:"sync"});const s=typeof t=="function"?t:t.get,a=typeof t=="function"?void 0:t.set,c=Fa((d,h)=>(n=d,i=h,{get(){return r.value&&(l=s(),r.value=!1),n(),l},set(f){a==null||a(f)}}));return Object.isExtensible(c)&&(c.trigger=o),c}function Fs(e){return ko()?(ha(e),!0):!1}function pl(e){return typeof e=="function"?e():te(e)}const Dh=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Sh=Object.prototype.toString,jh=e=>Sh.call(e)==="[object Object]",Ch=()=>{};function Vh(e,t){function l(...n){return new Promise((i,r)=>{Promise.resolve(e(()=>t.apply(this,n),{fn:t,thisArg:this,args:n})).then(i).catch(r)})}return l}const Ns=e=>e();function Fh(e=Ns){const t=ge(!0);function l(){t.value=!1}function n(){t.value=!0}const i=(...r)=>{t.value&&e(...r)};return{isActive:Rn(t),pause:l,resume:n,eventFilter:i}}function Nh(e){return e||Ci()}function Mh(e,t,l={}){const{eventFilter:n=Ns,...i}=l;return Ye(e,Vh(n,t),i)}function Hh(e,t,l={}){const{eventFilter:n,...i}=l,{eventFilter:r,pause:o,resume:s,isActive:a}=Fh(n);return{stop:Mh(e,t,{...i,eventFilter:r}),pause:o,resume:s,isActive:a}}function $h(e,t=!0,l){Nh()?ze(e,l):t?e():Wl(e)}function Bh(e=!1,t={}){const{truthyValue:l=!0,falsyValue:n=!1}=t,i=Me(e),r=ge(e);function o(s){if(arguments.length)return r.value=s,r.value;{const a=pl(l);return r.value=r.value===a?pl(n):a,r.value}}return i?o:[r,o]}function zh(e){var t;const l=pl(e);return(t=l==null?void 0:l.$el)!=null?t:l}const Tn=Dh?window:void 0;function oo(...e){let t,l,n,i;if(typeof e[0]=="string"||Array.isArray(e[0])?([l,n,i]=e,t=Tn):[t,l,n,i]=e,!t)return Ch;Array.isArray(l)||(l=[l]),Array.isArray(n)||(n=[n]);const r=[],o=()=>{r.forEach(d=>d()),r.length=0},s=(d,h,f,m)=>(d.addEventListener(h,f,m),()=>d.removeEventListener(h,f,m)),a=Ye(()=>[zh(t),pl(i)],([d,h])=>{if(o(),!d)return;const f=jh(h)?{...h}:h;r.push(...l.flatMap(m=>n.map(k=>s(d,m,k,f))))},{immediate:!0,flush:"post"}),c=()=>{a(),o()};return Fs(c),c}function Wh(){const e=ge(!1),t=Ci();return t&&ze(()=>{e.value=!0},t),e}function Uh(e){const t=Wh();return H(()=>(t.value,!!e()))}function Kh(e,t={}){const{window:l=Tn}=t,n=Uh(()=>l&&"matchMedia"in l&&typeof l.matchMedia=="function");let i;const r=ge(!1),o=c=>{r.value=c.matches},s=()=>{i&&("removeEventListener"in i?i.removeEventListener("change",o):i.removeListener(o))},a=tc(()=>{n.value&&(s(),i=l.matchMedia(pl(e)),"addEventListener"in i?i.addEventListener("change",o):i.addListener(o),r.value=i.matches)});return Fs(()=>{a(),s(),i=void 0}),r}const an=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},cn="__vueuse_ssr_handlers__",qh=Xh();function Xh(){return cn in an||(an[cn]=an[cn]||{}),an[cn]}function Gh(e,t){return qh[e]||t}function Yh(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const Qh={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},so="vueuse-storage";function Ms(e,t,l,n={}){var i;const{flush:r="pre",deep:o=!0,listenToStorageChanges:s=!0,writeDefaults:a=!0,mergeDefaults:c=!1,shallow:d,window:h=Tn,eventFilter:f,onError:m=O=>{console.error(O)},initOnMounted:k}=n,T=(d?jo:ge)(typeof t=="function"?t():t);if(!l)try{l=Gh("getDefaultStorage",()=>{var O;return(O=Tn)==null?void 0:O.localStorage})()}catch(O){m(O)}if(!l)return T;const w=pl(t),I=Yh(w),R=(i=n.serializer)!=null?i:Qh[I],{pause:b,resume:E}=Hh(T,()=>G(T.value),{flush:r,deep:o,eventFilter:f});h&&s&&$h(()=>{oo(h,"storage",y),oo(h,so,q),k&&y()}),k||y();function F(O,W){h&&h.dispatchEvent(new CustomEvent(so,{detail:{key:e,oldValue:O,newValue:W,storageArea:l}}))}function G(O){try{const W=l.getItem(e);if(O==null)F(W,null),l.removeItem(e);else{const x=R.write(O);W!==x&&(l.setItem(e,x),F(W,x))}}catch(W){m(W)}}function N(O){const W=O?O.newValue:l.getItem(e);if(W==null)return a&&w!=null&&l.setItem(e,R.write(w)),w;if(!O&&c){const x=R.read(W);return typeof c=="function"?c(x,w):I==="object"&&!Array.isArray(x)?{...w,...x}:x}else return typeof W!="string"?W:R.read(W)}function y(O){if(!(O&&O.storageArea!==l)){if(O&&O.key==null){T.value=w;return}if(!(O&&O.key!==e)){b();try{(O==null?void 0:O.newValue)!==R.write(T.value)&&(T.value=N(O))}catch(W){m(W)}finally{O?Wl(E):E()}}}}function q(O){y(O.detail)}return T}function Jh(e){return Kh("(prefers-color-scheme: dark)",e)}const Zh=pe({name:"CodeGroup",slots:Object,setup(e,{slots:t}){const l=ge([]),n=ge(-1),i=Ms("vuepress-code-group",{}),r=H(()=>l.value.map(c=>c.innerText).join(","));ze(()=>{Ye(()=>i.value[r.value],(c=-1)=>{n.value!==c&&(n.value=c)},{immediate:!0}),Ye(n,c=>{i.value[r.value]!==c&&(i.value[r.value]=c)})});const o=(c=n.value)=>{c{c>0?n.value=c-1:n.value=l.value.length-1,l.value[n.value].focus()},a=(c,d)=>{c.key===" "||c.key==="Enter"?(c.preventDefault(),n.value=d):c.key==="ArrowRight"?(c.preventDefault(),o(d)):c.key==="ArrowLeft"&&(c.preventDefault(),s(d))};return()=>{var d;const c=(((d=t.default)==null?void 0:d.call(t))||[]).filter(h=>h.type.name==="CodeGroupItem").map(h=>(h.props===null&&(h.props={}),h));return c.length===0?null:(n.value<0||n.value>c.length-1?(n.value=c.findIndex(h=>h.props.active===""||h.props.active===!0),n.value===-1&&(n.value=0)):c.forEach((h,f)=>{h.props.active=f===n.value}),fe("div",{class:"code-group"},[fe("div",{class:"code-group__nav",role:"tablist"},c.map((h,f)=>{const m=f===n.value;return fe("button",{ref:k=>{k&&(l.value[f]=k)},class:{"code-group__nav-tab":!0,"code-group__nav-tab-active":m},role:"tab",ariaSelected:m,onClick:()=>n.value=f,onKeydown:k=>a(k,f)},h.props.title)})),c]))}}}),ef=pe({name:"CodeGroupItem",__name:"CodeGroupItem",props:{title:{type:String,required:!0},active:{type:Boolean,required:!1,default:!1}},setup(e){return(t,l)=>(z(),ee("div",{class:Ke(["code-group-item",{"code-group-item__active":e.active}]),role:"tabpanel"},[ke(t.$slots,"default")],2))}}),tf=Le(ef,[["__file","CodeGroupItem.vue"]]),lf=()=>Cs(),Ne=()=>Ph(),Hs=Symbol(""),Ki=()=>{const e=Te(Hs);if(!e)throw new Error("useDarkMode() is called without provider.");return e},nf=()=>{const e=Ne(),t=Jh(),l=Ms("vuepress-color-scheme",e.value.colorMode),n=H({get(){return e.value.colorModeSwitch?l.value==="auto"?t.value:l.value==="dark":e.value.colorMode==="dark"},set(i){i===t.value?l.value="auto":l.value=i?"dark":"light"}});Xt(Hs,n),rf(n)},rf=e=>{const t=(l=e.value)=>{const n=window==null?void 0:window.document.querySelector("html");n==null||n.classList.toggle("dark",l)};ze(()=>{Ye(e,t,{immediate:!0})}),Cn(()=>t())};let ti=null,Ll=null;const of={wait:()=>ti,pending:()=>{ti=new Promise(e=>Ll=e)},resolve:()=>{Ll==null||Ll(),ti=null,Ll=null}},$s=()=>of,Bs=(e,...t)=>{const l=e.resolve(...t),n=l.matched[l.matched.length-1];if(!(n!=null&&n.redirect))return l;const{redirect:i}=n,r=ju(i)?i(l):i,o=rt(r)?{path:r}:r;return Bs(e,{hash:l.hash,query:l.query,params:l.params,...o})},qi=(e,t)=>{const l=Bs(e,encodeURI(t));return{text:l.meta.title||t,link:l.name==="404"?t:l.fullPath}},ao=e=>decodeURI(e).replace(/#.*$/,"").replace(/(index)?\.(md|html)$/,""),sf=(e,t)=>{if(t.hash===e)return!0;const l=ao(t.path),n=ao(e);return l===n},zs=(e,t)=>e.link&&sf(e.link,t)?!0:e.children?e.children.some(l=>zs(l,t)):!1,Ws=e=>!Xl(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,af={GitHub:":repo/edit/:branch/:path",GitLab:":repo/-/edit/:branch/:path",Gitee:":repo/edit/:branch/:path",Bitbucket:":repo/src/:branch/:path?mode=edit&spa=0&at=:branch&fileviewer=file-view-default"},cf=({docsRepo:e,editLinkPattern:t})=>{if(t)return t;const l=Ws(e);return l!==null?af[l]:null},uf=({docsRepo:e,docsBranch:t,docsDir:l,filePathRelative:n,editLinkPattern:i})=>{if(!n)return null;const r=cf({docsRepo:e,editLinkPattern:i});return r?r.replace(/:repo/,Xl(e)?e:`https://github.com/${e}`).replace(/:branch/,t).replace(/:path/,hs(`${ds(l)}/${n}`)):null},Us=Symbol("sidebarItems"),Xi=()=>{const e=Te(Us);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},df=()=>{const e=Ne(),t=_t(),l=al(),n=bl(),i=yt(),r=H(()=>hf(t.value,e.value,l.value,i,n.path));Xt(Us,r)},hf=(e,t,l,n,i)=>{const r=e.sidebar??t.sidebar??"auto",o=e.sidebarDepth??t.sidebarDepth??2;return e.home||r===!1?[]:r==="auto"?Ks(l,o):Array.isArray(r)?qs(l,n,i,r,o):Ni(r)?vf(l,n,i,r,o):[]},ff=(e,t)=>({text:e.title,link:e.link,children:Gi(e.children,t)}),Gi=(e,t)=>t>0?e.map(l=>ff(l,t-1)):[],Ks=(e,t)=>[{text:e.title,children:Gi(e.headers,t)}],qs=(e,t,l,n,i)=>{const r=o=>{var a;let s;if(rt(o)?s=qi(t,o):s=o,s.children)return{...s,children:s.children.map(c=>r(c))};if(s.link===l){const c=((a=e.headers[0])==null?void 0:a.level)===1?e.headers[0].children:e.headers;return{...s,children:Gi(c,i)}}return s};return n.map(o=>r(o))},vf=(e,t,l,n,i)=>{const r=fs(n,l),o=n[r]??[];return o==="heading"?Ks(e,i):qs(e,t,l,o,i)},pf="719px",mf={mobile:pf};var Ml;(function(e){e.MOBILE="mobile"})(Ml||(Ml={}));var fo;const gf={[Ml.MOBILE]:Number.parseInt((fo=mf.mobile)==null?void 0:fo.replace("px",""),10)},Xs=(e,t)=>{const l=gf[e];Number.isInteger(l)&&ze(()=>{t(l),window.addEventListener("resize",()=>t(l),!1),window.addEventListener("orientationchange",()=>t(l),!1)})},_f={},bf={class:"theme-default-content"};function kf(e,t){const l=kt("Content");return z(),ee("div",bf,[ie(l)])}const yf=Le(_f,[["render",kf],["__file","HomeContent.vue"]]),Ef={key:0,class:"features"},xf=pe({__name:"HomeFeatures",setup(e){const t=_t(),l=H(()=>Array.isArray(t.value.features)?t.value.features:[]);return(n,i)=>l.value.length?(z(),ee("div",Ef,[(z(!0),ee(ye,null,Ct(l.value,r=>(z(),ee("div",{key:r.title,class:"feature"},[he("h2",null,Ie(r.title),1),he("p",null,Ie(r.details),1)]))),128))])):Oe("",!0)}}),Lf=Le(xf,[["__file","HomeFeatures.vue"]]),Tf=["innerHTML"],Pf=["textContent"],wf=pe({__name:"HomeFooter",setup(e){const t=_t(),l=H(()=>t.value.footer),n=H(()=>t.value.footerHtml);return(i,r)=>l.value?(z(),ee(ye,{key:0},[n.value?(z(),ee("div",{key:0,class:"footer",innerHTML:l.value},null,8,Tf)):(z(),ee("div",{key:1,class:"footer",textContent:Ie(l.value)},null,8,Pf))],64)):Oe("",!0)}}),Of=Le(wf,[["__file","HomeFooter.vue"]]),Af=["href","rel","target","aria-label"],Rf=pe({inheritAttrs:!1,__name:"AutoLink",props:{item:{type:Object,required:!0}},setup(e){const t=e,l=bl(),n=ks(),{item:i}=In(t),r=H(()=>Xl(i.value.link)),o=H(()=>!r.value&&Su(i.value.link)),s=H(()=>{if(!o.value){if(i.value.target)return i.value.target;if(r.value)return"_blank"}}),a=H(()=>s.value==="_blank"),c=H(()=>!r.value&&!o.value&&!a.value),d=H(()=>{if(!o.value){if(i.value.rel)return i.value.rel;if(a.value)return"noopener noreferrer"}}),h=H(()=>i.value.ariaLabel||i.value.text),f=H(()=>{const T=Object.keys(n.value.locales);return T.length?!T.some(w=>w===i.value.link):i.value.link!=="/"}),m=H(()=>f.value?l.path.startsWith(i.value.link):!1),k=H(()=>c.value?i.value.activeMatch?new RegExp(i.value.activeMatch).test(l.path):m.value:!1);return(T,w)=>{const I=kt("RouterLink"),R=kt("AutoLinkExternalIcon");return c.value?(z(),we(I,fi({key:0,class:{"router-link-active":k.value},to:te(i).link,"aria-label":h.value},T.$attrs),{default:Ve(()=>[ke(T.$slots,"before"),Ft(" "+Ie(te(i).text)+" ",1),ke(T.$slots,"after")]),_:3},16,["class","to","aria-label"])):(z(),ee("a",fi({key:1,class:"external-link",href:te(i).link,rel:d.value,target:s.value,"aria-label":h.value},T.$attrs),[ke(T.$slots,"before"),Ft(" "+Ie(te(i).text)+" ",1),a.value?(z(),we(R,{key:0})):Oe("",!0),ke(T.$slots,"after")],16,Af))}}}),bt=Le(Rf,[["__file","AutoLink.vue"]]),If={class:"hero"},Df={key:0,id:"main-title"},Sf={key:1,class:"description"},jf={key:2,class:"actions"},Cf=pe({__name:"HomeHero",setup(e){const t=_t(),l=Hi(),n=Ki(),i=H(()=>n.value&&t.value.heroImageDark!==void 0?t.value.heroImageDark:t.value.heroImage),r=H(()=>t.value.heroAlt||s.value||"hero"),o=H(()=>t.value.heroHeight||280),s=H(()=>t.value.heroText===null?null:t.value.heroText||l.value.title||"Hello"),a=H(()=>t.value.tagline===null?null:t.value.tagline||l.value.description||"Welcome to your VuePress site"),c=H(()=>Array.isArray(t.value.actions)?t.value.actions.map(({text:h,link:f,type:m="primary"})=>({text:h,link:f,type:m})):[]),d=()=>{if(!i.value)return null;const h=fe("img",{src:Bi(i.value),alt:r.value,height:o.value});return t.value.heroImageDark===void 0?h:fe($i,()=>h)};return(h,f)=>(z(),ee("header",If,[ie(d),s.value?(z(),ee("h1",Df,Ie(s.value),1)):Oe("",!0),a.value?(z(),ee("p",Sf,Ie(a.value),1)):Oe("",!0),c.value.length?(z(),ee("p",jf,[(z(!0),ee(ye,null,Ct(c.value,m=>(z(),we(bt,{key:m.text,class:Ke(["action-button",[m.type]]),item:m},null,8,["class","item"]))),128))])):Oe("",!0)]))}}),Vf=Le(Cf,[["__file","HomeHero.vue"]]),Ff={class:"home"},Nf=pe({__name:"Home",setup(e){return(t,l)=>(z(),ee("main",Ff,[ie(Vf),ie(Lf),ie(yf),ie(Of)]))}}),Mf=Le(Nf,[["__file","Home.vue"]]),Hf=["aria-hidden"],$f=pe({__name:"NavbarBrand",setup(e){const t=Gl(),l=Hi(),n=Ne(),i=Ki(),r=H(()=>n.value.home||t.value),o=H(()=>l.value.title),s=H(()=>i.value&&n.value.logoDark!==void 0?n.value.logoDark:n.value.logo),a=H(()=>n.value.logoAlt??o.value),c=H(()=>o.value.toLocaleUpperCase().trim()===a.value.toLocaleUpperCase().trim()),d=()=>{if(!s.value)return null;const h=fe("img",{class:"logo",src:Bi(s.value),alt:a.value});return n.value.logoDark===void 0?h:fe($i,()=>h)};return(h,f)=>{const m=kt("RouterLink");return z(),we(m,{to:r.value},{default:Ve(()=>[ie(d),o.value?(z(),ee("span",{key:0,class:Ke(["site-name",{"can-hide":s.value}]),"aria-hidden":c.value},Ie(o.value),11,Hf)):Oe("",!0)]),_:1},8,["to"])}}}),Bf=Le($f,[["__file","NavbarBrand.vue"]]),zf=pe({__name:"DropdownTransition",setup(e){const t=n=>{n.style.height=n.scrollHeight+"px"},l=n=>{n.style.height=""};return(n,i)=>(z(),we(ql,{name:"dropdown",onEnter:t,onAfterEnter:l,onBeforeLeave:t},{default:Ve(()=>[ke(n.$slots,"default")]),_:3}))}}),Gs=Le(zf,[["__file","DropdownTransition.vue"]]),Wf=["aria-label"],Uf={class:"title"},Kf=he("span",{class:"arrow down"},null,-1),qf=["aria-label"],Xf={class:"title"},Gf={class:"navbar-dropdown"},Yf={class:"navbar-dropdown-subtitle"},Qf={key:1},Jf={class:"navbar-dropdown-subitem-wrapper"},Zf=pe({__name:"NavbarDropdown",props:{item:{type:Object,required:!0}},setup(e){const t=e,{item:l}=In(t),n=H(()=>l.value.ariaLabel||l.value.text),i=ge(!1),r=bl();Ye(()=>r.path,()=>{i.value=!1});const o=a=>{a.detail===0?i.value=!i.value:i.value=!1},s=(a,c)=>c[c.length-1]===a;return(a,c)=>(z(),ee("div",{class:Ke(["navbar-dropdown-wrapper",{open:i.value}])},[he("button",{class:"navbar-dropdown-title",type:"button","aria-label":n.value,onClick:o},[he("span",Uf,Ie(te(l).text),1),Kf],8,Wf),he("button",{class:"navbar-dropdown-title-mobile",type:"button","aria-label":n.value,onClick:c[0]||(c[0]=d=>i.value=!i.value)},[he("span",Xf,Ie(te(l).text),1),he("span",{class:Ke(["arrow",i.value?"down":"right"])},null,2)],8,qf),ie(Gs,null,{default:Ve(()=>[_n(he("ul",Gf,[(z(!0),ee(ye,null,Ct(te(l).children,d=>(z(),ee("li",{key:d.text,class:"navbar-dropdown-item"},[d.children?(z(),ee(ye,{key:0},[he("h4",Yf,[d.link?(z(),we(bt,{key:0,item:d,onFocusout:h=>s(d,te(l).children)&&d.children.length===0&&(i.value=!1)},null,8,["item","onFocusout"])):(z(),ee("span",Qf,Ie(d.text),1))]),he("ul",Jf,[(z(!0),ee(ye,null,Ct(d.children,h=>(z(),ee("li",{key:h.link,class:"navbar-dropdown-subitem"},[ie(bt,{item:h,onFocusout:f=>s(h,d.children)&&s(d,te(l).children)&&(i.value=!1)},null,8,["item","onFocusout"])]))),128))])],64)):(z(),we(bt,{key:1,item:d,onFocusout:h=>s(d,te(l).children)&&(i.value=!1)},null,8,["item","onFocusout"]))]))),128))],512),[[xn,i.value]])]),_:1})],2))}}),ev=Le(Zf,[["__file","NavbarDropdown.vue"]]),tv=["aria-label"],lv=pe({__name:"NavbarItems",setup(e){const t=()=>{const h=yt(),f=Gl(),m=ks(),k=Hi(),T=lf(),w=Ne();return H(()=>{const I=Object.keys(m.value.locales);if(I.length<2)return[];const R=h.currentRoute.value.path,b=h.currentRoute.value.fullPath;return[{text:`${w.value.selectLanguageText}`,ariaLabel:`${w.value.selectLanguageAriaLabel??w.value.selectLanguageText}`,children:I.map(F=>{var W,x;const G=((W=m.value.locales)==null?void 0:W[F])??{},N=((x=T.value.locales)==null?void 0:x[F])??{},y=`${G.lang}`,q=N.selectLanguageName??y;let O;if(y===k.value.lang)O=b;else{const C=R.replace(f.value,F);h.getRoutes().some(ne=>ne.path===C)?O=b.replace(R,C):O=N.home??F}return{text:q,link:O}})}]})},l=()=>{const h=Ne(),f=H(()=>h.value.repo),m=H(()=>f.value?Ws(f.value):null),k=H(()=>f.value&&!Xl(f.value)?`https://github.com/${f.value}`:f.value),T=H(()=>k.value?h.value.repoLabel?h.value.repoLabel:m.value===null?"Source":m.value:null);return H(()=>!k.value||!T.value?[]:[{text:T.value,link:k.value}])},n=(h,f)=>rt(f)?qi(h,f):f.children?{...f,children:f.children.map(m=>n(h,m))}:f,i=()=>{const h=yt(),f=Ne();return H(()=>(f.value.navbar||[]).map(m=>n(h,m)))},r=ge(!1),o=i(),s=t(),a=l(),c=H(()=>[...o.value,...s.value,...a.value]);Xs(Ml.MOBILE,h=>{window.innerWidthNe().value.navbarLabel??"site navigation");return(h,f)=>c.value.length?(z(),ee("nav",{key:0,class:"navbar-items","aria-label":d.value},[(z(!0),ee(ye,null,Ct(c.value,m=>(z(),ee("div",{key:m.text,class:"navbar-item"},[m.children?(z(),we(ev,{key:0,item:m,class:Ke(r.value?"mobile":"")},null,8,["item","class"])):(z(),we(bt,{key:1,item:m},null,8,["item"]))]))),128))],8,tv)):Oe("",!0)}}),Ys=Le(lv,[["__file","NavbarItems.vue"]]),nv=["title"],iv={class:"icon",focusable:"false",viewBox:"0 0 32 32"},rv=Fc('',9),ov=[rv],sv={class:"icon",focusable:"false",viewBox:"0 0 32 32"},av=he("path",{d:"M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z",fill:"currentColor"},null,-1),cv=[av],uv=pe({__name:"ToggleColorModeButton",setup(e){const t=Ne(),l=Ki(),n=()=>{l.value=!l.value};return(i,r)=>(z(),ee("button",{class:"toggle-color-mode-button",title:te(t).toggleColorMode,onClick:n},[_n((z(),ee("svg",iv,ov,512)),[[xn,!te(l)]]),_n((z(),ee("svg",sv,cv,512)),[[xn,te(l)]])],8,nv))}}),dv=Le(uv,[["__file","ToggleColorModeButton.vue"]]),hv=["title"],fv=he("div",{class:"icon","aria-hidden":"true"},[he("span"),he("span"),he("span")],-1),vv=[fv],pv=pe({__name:"ToggleSidebarButton",emits:["toggle"],setup(e){const t=Ne();return(l,n)=>(z(),ee("div",{class:"toggle-sidebar-button",title:te(t).toggleSidebar,"aria-expanded":"false",role:"button",tabindex:"0",onClick:n[0]||(n[0]=i=>l.$emit("toggle"))},vv,8,hv))}}),mv=Le(pv,[["__file","ToggleSidebarButton.vue"]]),gv=pe({__name:"Navbar",emits:["toggle-sidebar"],setup(e){const t=Ne(),l=ge(null),n=ge(null),i=ge(0),r=H(()=>i.value?{maxWidth:i.value+"px"}:{});Xs(Ml.MOBILE,s=>{var c;const a=o(l.value,"paddingLeft")+o(l.value,"paddingRight");window.innerWidth{const c=kt("NavbarSearch");return z(),ee("header",{ref_key:"navbar",ref:l,class:"navbar"},[ie(mv,{onToggle:a[0]||(a[0]=d=>s.$emit("toggle-sidebar"))}),he("span",{ref_key:"navbarBrand",ref:n},[ie(Bf)],512),he("div",{class:"navbar-items-wrapper",style:$l(r.value)},[ke(s.$slots,"before"),ie(Ys,{class:"can-hide"}),ke(s.$slots,"after"),te(t).colorModeSwitch?(z(),we(dv,{key:0})):Oe("",!0),ie(c)],4)],512)}}}),_v=Le(gv,[["__file","Navbar.vue"]]),bv={class:"page-meta"},kv={key:0,class:"meta-item edit-link"},yv={key:1,class:"meta-item last-updated"},Ev={class:"meta-item-label"},xv={class:"meta-item-info"},Lv={key:2,class:"meta-item contributors"},Tv={class:"meta-item-label"},Pv={class:"meta-item-info"},wv=["title"],Ov=pe({__name:"PageMeta",setup(e){const t=()=>{const a=Ne(),c=al(),d=_t();return H(()=>{if(!(d.value.editLink??a.value.editLink??!0))return null;const{repo:f,docsRepo:m=f,docsBranch:k="main",docsDir:T="",editLinkText:w}=a.value;if(!m)return null;const I=uf({docsRepo:m,docsBranch:k,docsDir:T,filePathRelative:c.value.filePathRelative,editLinkPattern:d.value.editLinkPattern??a.value.editLinkPattern});return I?{text:w??"Edit this page",link:I}:null})},l=()=>{const a=Ne(),c=al(),d=_t();return H(()=>{var m,k;return!(d.value.lastUpdated??a.value.lastUpdated??!0)||!((m=c.value.git)!=null&&m.updatedTime)?null:new Date((k=c.value.git)==null?void 0:k.updatedTime).toLocaleString()})},n=()=>{const a=Ne(),c=al(),d=_t();return H(()=>{var f;return d.value.contributors??a.value.contributors??!0?((f=c.value.git)==null?void 0:f.contributors)??null:null})},i=Ne(),r=t(),o=l(),s=n();return(a,c)=>{const d=kt("ClientOnly");return z(),ee("footer",bv,[te(r)?(z(),ee("div",kv,[ie(bt,{class:"meta-item-label",item:te(r)},null,8,["item"])])):Oe("",!0),te(o)?(z(),ee("div",yv,[he("span",Ev,Ie(te(i).lastUpdatedText)+": ",1),ie(d,null,{default:Ve(()=>[he("span",xv,Ie(te(o)),1)]),_:1})])):Oe("",!0),te(s)&&te(s).length?(z(),ee("div",Lv,[he("span",Tv,Ie(te(i).contributorsText)+": ",1),he("span",Pv,[(z(!0),ee(ye,null,Ct(te(s),(h,f)=>(z(),ee(ye,{key:f},[he("span",{class:"contributor",title:`email: ${h.email}`},Ie(h.name),9,wv),f!==te(s).length-1?(z(),ee(ye,{key:0},[Ft(", ")],64)):Oe("",!0)],64))),128))])])):Oe("",!0)])}}}),Av=Le(Ov,[["__file","PageMeta.vue"]]),Rv=["aria-label"],Iv={class:"inner"},Dv={key:0,class:"prev"},Sv={key:1,class:"next"},jv=pe({__name:"PageNav",setup(e){const t=(d,h)=>h===!1?null:rt(h)?qi(d,h):Ni(h)?h:!1,l=(d,h,f)=>{const m=d.findIndex(k=>k.link===h);if(m!==-1){const k=d[m+f];return k!=null&&k.link?k:null}for(const k of d)if(k.children){const T=l(k.children,h,f);if(T)return T}return null},n=_t(),i=Xi(),r=bl(),o=yt(),s=H(()=>{const d=t(o,n.value.prev);return d!==!1?d:l(i.value,r.path,-1)}),a=H(()=>{const d=t(o,n.value.next);return d!==!1?d:l(i.value,r.path,1)}),c=H(()=>Ne().value.pageNavbarLabel??"page navigation");return(d,h)=>s.value||a.value?(z(),ee("nav",{key:0,class:"page-nav","aria-label":c.value},[he("p",Iv,[s.value?(z(),ee("span",Dv,[ie(bt,{item:s.value},null,8,["item"])])):Oe("",!0),a.value?(z(),ee("span",Sv,[ie(bt,{item:a.value},null,8,["item"])])):Oe("",!0)])],8,Rv)):Oe("",!0)}}),Cv=Le(jv,[["__file","PageNav.vue"]]),Vv={class:"page"},Fv={class:"theme-default-content"},Nv=pe({__name:"Page",setup(e){return(t,l)=>{const n=kt("Content");return z(),ee("main",Vv,[ke(t.$slots,"top"),he("div",Fv,[ke(t.$slots,"content-top"),ie(n),ke(t.$slots,"content-bottom")]),ie(Av),ie(Cv),ke(t.$slots,"bottom")])}}}),Mv=Le(Nv,[["__file","Page.vue"]]),Hv={class:"sidebar-item-children"},$v=pe({__name:"SidebarItem",props:{item:{type:Object,required:!0},depth:{type:Number,required:!1,default:0}},setup(e){const t=e,{item:l,depth:n}=In(t),i=bl(),r=yt(),o=H(()=>zs(l.value,i)),s=H(()=>({"sidebar-item":!0,"sidebar-heading":n.value===0,active:o.value,collapsible:l.value.collapsible})),a=H(()=>l.value.collapsible?o.value:!0),[c,d]=Bh(a.value),h=m=>{l.value.collapsible&&(m.preventDefault(),d())},f=r.afterEach(m=>{Wl(()=>{c.value=a.value})});return Kl(()=>{f()}),(m,k)=>{var w;const T=kt("SidebarItem",!0);return z(),ee("li",null,[te(l).link?(z(),we(bt,{key:0,class:Ke(s.value),item:te(l)},null,8,["class","item"])):(z(),ee("p",{key:1,tabindex:"0",class:Ke(s.value),onClick:h,onKeydown:ku(h,["enter"])},[Ft(Ie(te(l).text)+" ",1),te(l).collapsible?(z(),ee("span",{key:0,class:Ke(["arrow",te(c)?"down":"right"])},null,2)):Oe("",!0)],34)),(w=te(l).children)!=null&&w.length?(z(),we(Gs,{key:2},{default:Ve(()=>[_n(he("ul",Hv,[(z(!0),ee(ye,null,Ct(te(l).children,I=>(z(),we(T,{key:`${te(n)}${I.text}${I.link}`,item:I,depth:te(n)+1},null,8,["item","depth"]))),128))],512),[[xn,te(c)]])]),_:1})):Oe("",!0)])}}}),Bv=Le($v,[["__file","SidebarItem.vue"]]),zv={key:0,class:"sidebar-items"},Wv=pe({__name:"SidebarItems",setup(e){const t=bl(),l=Xi();return ze(()=>{Ye(()=>t.hash,n=>{const i=document.querySelector(".sidebar");if(!i)return;const r=document.querySelector(`.sidebar a.sidebar-item[href="${t.path}${n}"]`);if(!r)return;const{top:o,height:s}=i.getBoundingClientRect(),{top:a,height:c}=r.getBoundingClientRect();ao+s&&r.scrollIntoView(!1)})}),(n,i)=>te(l).length?(z(),ee("ul",zv,[(z(!0),ee(ye,null,Ct(te(l),r=>(z(),we(Bv,{key:`${r.text}${r.link}`,item:r},null,8,["item"]))),128))])):Oe("",!0)}}),Uv=Le(Wv,[["__file","SidebarItems.vue"]]),Kv={class:"sidebar"},qv=pe({__name:"Sidebar",setup(e){return(t,l)=>(z(),ee("aside",Kv,[ie(Ys),ke(t.$slots,"top"),ie(Uv),ke(t.$slots,"bottom")]))}}),Xv=Le(qv,[["__file","Sidebar.vue"]]),Gv=pe({__name:"Layout",setup(e){const t=al(),l=_t(),n=Ne(),i=H(()=>l.value.navbar!==!1&&n.value.navbar!==!1),r=Xi(),o=ge(!1),s=w=>{o.value=typeof w=="boolean"?w:!o.value},a={x:0,y:0},c=w=>{a.x=w.changedTouches[0].clientX,a.y=w.changedTouches[0].clientY},d=w=>{const I=w.changedTouches[0].clientX-a.x,R=w.changedTouches[0].clientY-a.y;Math.abs(I)>Math.abs(R)&&Math.abs(I)>40&&(I>0&&a.x<=80?s(!0):s(!1))},h=H(()=>[{"no-navbar":!i.value,"no-sidebar":!r.value.length,"sidebar-open":o.value},l.value.pageClass]);let f;ze(()=>{f=yt().afterEach(()=>{s(!1)})}),Cn(()=>{f()});const m=$s(),k=m.resolve,T=m.pending;return(w,I)=>(z(),ee("div",{class:Ke(["theme-container",h.value]),onTouchstart:c,onTouchend:d},[ke(w.$slots,"navbar",{},()=>[i.value?(z(),we(_v,{key:0,onToggleSidebar:s},{before:Ve(()=>[ke(w.$slots,"navbar-before")]),after:Ve(()=>[ke(w.$slots,"navbar-after")]),_:3})):Oe("",!0)]),he("div",{class:"sidebar-mask",onClick:I[0]||(I[0]=R=>s(!1))}),ke(w.$slots,"sidebar",{},()=>[ie(Xv,null,{top:Ve(()=>[ke(w.$slots,"sidebar-top")]),bottom:Ve(()=>[ke(w.$slots,"sidebar-bottom")]),_:3})]),ke(w.$slots,"page",{},()=>[te(l).home?(z(),we(Mf,{key:0})):(z(),we(ql,{key:1,name:"fade-slide-y",mode:"out-in",onBeforeEnter:te(k),onBeforeLeave:te(T)},{default:Ve(()=>[(z(),we(Mv,{key:te(t).path},{top:Ve(()=>[ke(w.$slots,"page-top")]),"content-top":Ve(()=>[ke(w.$slots,"page-content-top")]),"content-bottom":Ve(()=>[ke(w.$slots,"page-content-bottom")]),bottom:Ve(()=>[ke(w.$slots,"page-bottom")]),_:3}))]),_:3},8,["onBeforeEnter","onBeforeLeave"]))])],34))}}),Yv=Le(Gv,[["__file","Layout.vue"]]),Qv={class:"theme-container"},Jv={class:"page"},Zv={class:"theme-default-content"},ep=he("h1",null,"404",-1),tp=pe({__name:"NotFound",setup(e){const t=Gl(),l=Ne(),n=l.value.notFound??["Not Found"],i=()=>n[Math.floor(Math.random()*n.length)],r=l.value.home??t.value,o=l.value.backToHome??"Back to home";return(s,a)=>{const c=kt("RouterLink");return z(),ee("div",Qv,[he("main",Jv,[he("div",Zv,[ep,he("blockquote",null,Ie(i()),1),ie(c,{to:te(r)},{default:Ve(()=>[Ft(Ie(te(o)),1)]),_:1},8,["to"])])])])}}}),lp=Le(tp,[["__file","NotFound.vue"]]),np=Nt({enhance({app:e,router:t}){e.component("Badge",Rh),e.component("CodeGroup",Zh),e.component("CodeGroupItem",tf),e.component("AutoLinkExternalIcon",()=>{const n=e.component("ExternalLinkIcon");return n?fe(n):null}),e.component("NavbarSearch",()=>{const n=e.component("Docsearch")||e.component("SearchBox");return n?fe(n):null});const l=t.options.scrollBehavior;t.options.scrollBehavior=async(...n)=>(await $s().wait(),l(...n))},setup(){nf(),df()},layouts:{Layout:Yv,NotFound:lp}}),ip=e=>e instanceof Element?document.activeElement===e&&(["TEXTAREA","SELECT","INPUT"].includes(e.tagName)||e.hasAttribute("contenteditable")):!1,rp=(e,t)=>t.some(l=>{if(rt(l))return l===e.key;const{key:n,ctrl:i=!1,shift:r=!1,alt:o=!1}=l;return n===e.key&&i===e.ctrlKey&&r===e.shiftKey&&o===e.altKey}),op=/[^\x00-\x7F]/,sp=e=>e.split(/\s+/g).map(t=>t.trim()).filter(t=>!!t),co=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),uo=(e,t)=>{const l=t.join(" "),n=sp(e);if(op.test(e))return n.some(o=>l.toLowerCase().indexOf(o)>-1);const i=e.endsWith(" ");return new RegExp(n.map((o,s)=>n.length===s+1&&!i?`(?=.*\\b${co(o)})`:`(?=.*\\b${co(o)}\\b)`).join("")+".+","gi").test(l)},ap=({input:e,hotKeys:t})=>{if(t.value.length===0)return;const l=n=>{e.value&&rp(n,t.value)&&!ip(n.target)&&(n.preventDefault(),e.value.focus())};ze(()=>{document.addEventListener("keydown",l)}),Kl(()=>{document.removeEventListener("keydown",l)})},cp=[{title:"",headers:[{level:2,title:"XTLS ? Xray ? V2Ray ?",slug:"xtls-xray-v2ray",link:"#xtls-xray-v2ray",children:[{level:3,title:"我们是谁?",slug:"我们是谁",link:"#我们是谁",children:[]},{level:3,title:"帮助 Xray 变得更强",slug:"帮助-xray-变得更强",link:"#帮助-xray-变得更强",children:[]},{level:3,title:"Telegram",slug:"telegram",link:"#telegram",children:[]},{level:3,title:"致谢",slug:"致谢",link:"#致谢",children:[]},{level:3,title:"更多关于 Project X",slug:"更多关于-project-x",link:"#更多关于-project-x",children:[]},{level:3,title:"License",slug:"license",link:"#license",children:[]},{level:3,title:"Stargazers over time",slug:"stargazers-over-time",link:"#stargazers-over-time",children:[]}]}],path:"/",pathLocale:"/",extraFields:[]},{title:"大史记",headers:[{level:2,title:"2021.4.6",slug:"_2021-4-6",link:"#_2021-4-6",children:[]},{level:2,title:"2021.4.4",slug:"_2021-4-4",link:"#_2021-4-4",children:[]},{level:2,title:"2021.4.1 v1.4.2",slug:"_2021-4-1-v1-4-2",link:"#_2021-4-1-v1-4-2",children:[]},{level:2,title:"2021.3.25",slug:"_2021-3-25",link:"#_2021-3-25",children:[]},{level:2,title:"2021.3.15",slug:"_2021-3-15",link:"#_2021-3-15",children:[]},{level:2,title:"2021.3.14 v1.4.0",slug:"_2021-3-14-v1-4-0",link:"#_2021-3-14-v1-4-0",children:[]},{level:2,title:"2021.3.3 1.3.1",slug:"_2021-3-3-1-3-1",link:"#_2021-3-3-1-3-1",children:[]},{level:2,title:"2021.2.14 1.3.0",slug:"_2021-2-14-1-3-0",link:"#_2021-2-14-1-3-0",children:[]},{level:2,title:"2021.01.31 1.2.4",slug:"_2021-01-31-1-2-4",link:"#_2021-01-31-1-2-4",children:[]},{level:2,title:"2021.01.25",slug:"_2021-01-25",link:"#_2021-01-25",children:[]},{level:2,title:"2021.01.22 1.2.3",slug:"_2021-01-22-1-2-3",link:"#_2021-01-22-1-2-3",children:[]},{level:2,title:"2021.01.19",slug:"_2021-01-19",link:"#_2021-01-19",children:[]},{level:2,title:"2021.01.17",slug:"_2021-01-17",link:"#_2021-01-17",children:[]},{level:2,title:"2021.01.15 1.2.2",slug:"_2021-01-15-1-2-2",link:"#_2021-01-15-1-2-2",children:[]},{level:2,title:"2021.01.12",slug:"_2021-01-12",link:"#_2021-01-12",children:[]},{level:2,title:"2021.01.10 1.2.1",slug:"_2021-01-10-1-2-1",link:"#_2021-01-10-1-2-1",children:[]},{level:2,title:"2021.01.07",slug:"_2021-01-07",link:"#_2021-01-07",children:[]},{level:2,title:"2021.01.05",slug:"_2021-01-05",link:"#_2021-01-05",children:[]},{level:2,title:"2021.01.03",slug:"_2021-01-03",link:"#_2021-01-03",children:[]},{level:2,title:"2021.01.01",slug:"_2021-01-01",link:"#_2021-01-01",children:[]},{level:2,title:"2020.12.29",slug:"_2020-12-29",link:"#_2020-12-29",children:[]},{level:2,title:"2020.12.25 1.1.5",slug:"_2020-12-25-1-1-5",link:"#_2020-12-25-1-1-5",children:[]},{level:2,title:"2020.12.24",slug:"_2020-12-24",link:"#_2020-12-24",children:[]},{level:2,title:"2020.12.23",slug:"_2020-12-23",link:"#_2020-12-23",children:[]},{level:2,title:"2020.12.21",slug:"_2020-12-21",link:"#_2020-12-21",children:[]},{level:2,title:"2020.12.18 1.1.4",slug:"_2020-12-18-1-1-4",link:"#_2020-12-18-1-1-4",children:[]},{level:2,title:"2020.12.17",slug:"_2020-12-17",link:"#_2020-12-17",children:[]},{level:2,title:"2020.12.15",slug:"_2020-12-15",link:"#_2020-12-15",children:[]},{level:2,title:"2020.12.11 1.1.3",slug:"_2020-12-11-1-1-3",link:"#_2020-12-11-1-1-3",children:[]},{level:2,title:"2020.12.06 1.1.2",slug:"_2020-12-06-1-1-2",link:"#_2020-12-06-1-1-2",children:[]},{level:2,title:"2020.12.04",slug:"_2020-12-04",link:"#_2020-12-04",children:[]},{level:2,title:"2020.11.27",slug:"_2020-11-27",link:"#_2020-11-27",children:[]},{level:2,title:"2020.11.25 1.0.0",slug:"_2020-11-25-1-0-0",link:"#_2020-11-25-1-0-0",children:[]},{level:2,title:"2020.11.23",slug:"_2020-11-23",link:"#_2020-11-23",children:[]}],path:"/about/news.html",pathLocale:"/",extraFields:[]},{title:"开发指南",headers:[{level:2,title:"编译文档",slug:"编译文档",link:"#编译文档",children:[]},{level:2,title:"设计思路",slug:"设计思路",link:"#设计思路",children:[]},{level:2,title:"开发规范",slug:"开发规范",link:"#开发规范",children:[]},{level:2,title:"协议详解",slug:"协议详解",link:"#协议详解",children:[{level:3,title:"VLESS 协议",slug:"vless-协议",link:"#vless-协议",children:[]},{level:3,title:"VMess 协议",slug:"vmess-协议",link:"#vmess-协议",children:[]},{level:3,title:"Mux.Cool 协议",slug:"mux-cool-协议",link:"#mux-cool-协议",children:[]},{level:3,title:"mKCP 协议",slug:"mkcp-协议",link:"#mkcp-协议",children:[]}]}],path:"/development/",pathLocale:"/",extraFields:[]},{title:"配置文件",headers:[{level:2,title:"概述",slug:"概述",link:"#概述",children:[]},{level:2,title:"基础配置模块",slug:"基础配置模块",link:"#基础配置模块",children:[]}],path:"/config/",pathLocale:"/",extraFields:[]},{title:"API 接口",headers:[{level:2,title:"ApiObject",slug:"apiobject",link:"#apiobject",children:[]},{level:2,title:"相关配置",slug:"相关配置",link:"#相关配置",children:[]},{level:2,title:"支持的 API 列表",slug:"支持的-api-列表",link:"#支持的-api-列表",children:[{level:3,title:"HandlerService",slug:"handlerservice",link:"#handlerservice",children:[]},{level:3,title:"LoggerService",slug:"loggerservice",link:"#loggerservice",children:[]},{level:3,title:"StatsService",slug:"statsservice",link:"#statsservice",children:[]},{level:3,title:"ReflectionService",slug:"reflectionservice",link:"#reflectionservice",children:[]}]},{level:2,title:"API 调用示例",slug:"api-调用示例",link:"#api-调用示例",children:[]}],path:"/config/api.html",pathLocale:"/",extraFields:[]},{title:"内置 DNS 服务器",headers:[{level:2,title:"DNS 服务器",slug:"dns-服务器",link:"#dns-服务器",children:[]},{level:2,title:"DNS 处理流程",slug:"dns-处理流程",link:"#dns-处理流程",children:[]},{level:2,title:"DnsObject",slug:"dnsobject",link:"#dnsobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/dns.html",pathLocale:"/",extraFields:[]},{title:"FakeDNS",headers:[{level:2,title:"FakeDNSObject",slug:"fakednsobject",link:"#fakednsobject",children:[{level:3,title:"如何使用?",slug:"如何使用",link:"#如何使用",children:[]},{level:3,title:"与其它类型 DNS 搭配使用",slug:"与其它类型-dns-搭配使用",link:"#与其它类型-dns-搭配使用",children:[]}]}],path:"/config/fakedns.html",pathLocale:"/",extraFields:[]},{title:"入站代理",headers:[{level:2,title:"InboundObject",slug:"inboundobject",link:"#inboundobject",children:[{level:3,title:"SniffingObject",slug:"sniffingobject",link:"#sniffingobject",children:[]},{level:3,title:"AllocateObject",slug:"allocateobject",link:"#allocateobject",children:[]}]}],path:"/config/inbound.html",pathLocale:"/",extraFields:[]},{title:"日志配置",headers:[{level:2,title:"LogObject",slug:"logobject",link:"#logobject",children:[]}],path:"/config/log.html",pathLocale:"/",extraFields:[]},{title:"Metrics",headers:[{level:2,title:"相关配置",slug:"相关配置",link:"#相关配置",children:[]},{level:2,title:"使用方法",slug:"使用方法",link:"#使用方法",children:[{level:3,title:"pprof",slug:"pprof",link:"#pprof",children:[]},{level:3,title:"expvars",slug:"expvars",link:"#expvars",children:[]},{level:3,title:"Additional",slug:"additional",link:"#additional",children:[]}]}],path:"/config/metrics.html",pathLocale:"/",extraFields:[]},{title:"出站代理",headers:[{level:2,title:"OutboundObject",slug:"outboundobject",link:"#outboundobject",children:[{level:3,title:"ProxySettingsObject",slug:"proxysettingsobject",link:"#proxysettingsobject",children:[]},{level:3,title:"MuxObject",slug:"muxobject",link:"#muxobject",children:[]}]}],path:"/config/outbound.html",pathLocale:"/",extraFields:[]},{title:"本地策略",headers:[{level:2,title:"PolicyObject",slug:"policyobject",link:"#policyobject",children:[{level:3,title:"LevelPolicyObject",slug:"levelpolicyobject",link:"#levelpolicyobject",children:[]},{level:3,title:"SystemPolicyObject",slug:"systempolicyobject",link:"#systempolicyobject",children:[]}]}],path:"/config/policy.html",pathLocale:"/",extraFields:[]},{title:"反向代理",headers:[{level:2,title:"ReverseObject",slug:"reverseobject",link:"#reverseobject",children:[{level:3,title:"BridgeObject",slug:"bridgeobject",link:"#bridgeobject",children:[]},{level:3,title:"PortalObject",slug:"portalobject",link:"#portalobject",children:[]}]},{level:2,title:"完整配置样例",slug:"完整配置样例",link:"#完整配置样例",children:[{level:3,title:"bridge 配置",slug:"bridge-配置",link:"#bridge-配置",children:[]},{level:3,title:"portal 配置",slug:"portal-配置",link:"#portal-配置",children:[]}]}],path:"/config/reverse.html",pathLocale:"/",extraFields:[]},{title:"路由",headers:[{level:2,title:"RoutingObject",slug:"routingobject",link:"#routingobject",children:[{level:3,title:"RuleObject",slug:"ruleobject",link:"#ruleobject",children:[]},{level:3,title:"BalancerObject",slug:"balancerobject",link:"#balancerobject",children:[]},{level:3,title:"预定义域名列表",slug:"预定义域名列表",link:"#预定义域名列表",children:[]}]}],path:"/config/routing.html",pathLocale:"/",extraFields:[]},{title:"统计信息",headers:[{level:2,title:"StatsObject",slug:"statsobject",link:"#statsobject",children:[]},{level:2,title:"获取统计信息",slug:"获取统计信息",link:"#获取统计信息",children:[]}],path:"/config/stats.html",pathLocale:"/",extraFields:[]},{title:"传输方式",headers:[{level:2,title:"TransportObject",slug:"transportobject",link:"#transportobject",children:[]},{level:2,title:"StreamSettingsObject",slug:"streamsettingsobject",link:"#streamsettingsobject",children:[{level:3,title:"TLSObject",slug:"tlsobject",link:"#tlsobject",children:[]},{level:3,title:"RealityObject",slug:"realityobject",link:"#realityobject",children:[]},{level:3,title:"SockoptObject",slug:"sockoptobject",link:"#sockoptobject",children:[]}]}],path:"/config/transport.html",pathLocale:"/",extraFields:[]},{title:"快速入门",headers:[{level:2,title:"下载安装",slug:"下载安装",link:"#下载安装",children:[]},{level:2,title:"配置运行",slug:"配置运行",link:"#配置运行",children:[]},{level:2,title:"命令参数",slug:"命令参数",link:"#命令参数",children:[]},{level:2,title:"改进文档",slug:"改进文档",link:"#改进文档",children:[]},{level:2,title:"小小白白话文",slug:"小小白白话文",link:"#小小白白话文",children:[]},{level:2,title:"入门技巧",slug:"入门技巧",link:"#入门技巧",children:[]},{level:2,title:"进阶文档",slug:"进阶文档",link:"#进阶文档",children:[]}],path:"/document/",pathLocale:"/",extraFields:[]},{title:"命令参数",headers:[{level:2,title:"获取基本命令",slug:"获取基本命令",link:"#获取基本命令",children:[{level:3,title:"xray run",slug:"xray-run",link:"#xray-run",children:[]},{level:3,title:"xray version",slug:"xray-version",link:"#xray-version",children:[]},{level:3,title:"xray api",slug:"xray-api",link:"#xray-api",children:[]},{level:3,title:"xray tls",slug:"xray-tls",link:"#xray-tls",children:[]},{level:3,title:"xray uuid",slug:"xray-uuid",link:"#xray-uuid",children:[]},{level:3,title:"xray x25519",slug:"xray-x25519",link:"#xray-x25519",children:[]},{level:3,title:"xray wg",slug:"xray-wg",link:"#xray-wg",children:[]}]}],path:"/document/command.html",pathLocale:"/",extraFields:[]},{title:"配置运行",headers:[{level:2,title:"服务端配置",slug:"服务端配置",link:"#服务端配置",children:[]},{level:2,title:"客户端配置",slug:"客户端配置",link:"#客户端配置",children:[]},{level:2,title:"运行",slug:"运行",link:"#运行",children:[]}],path:"/document/config.html",pathLocale:"/",extraFields:[]},{title:"为 Project X 的文档贡献",headers:[{level:2,title:"改进文档",slug:"改进文档",link:"#改进文档",children:[]},{level:2,title:"发现问题?",slug:"发现问题",link:"#发现问题",children:[]}],path:"/document/document.html",pathLocale:"/",extraFields:[]},{title:"下载安装",headers:[{level:2,title:"平台支持",slug:"平台支持",link:"#平台支持",children:[]},{level:2,title:"下载 Xray",slug:"下载-xray",link:"#下载-xray",children:[]},{level:2,title:"验证安装包",slug:"验证安装包",link:"#验证安装包",children:[]},{level:2,title:"Windows 安装方式",slug:"windows-安装方式",link:"#windows-安装方式",children:[]},{level:2,title:"macOS 安装方式",slug:"macos-安装方式",link:"#macos-安装方式",children:[]},{level:2,title:"Linux 安装方式",slug:"linux-安装方式",link:"#linux-安装方式",children:[{level:3,title:"安装脚本",slug:"安装脚本",link:"#安装脚本",children:[]},{level:3,title:"Arch Linux",slug:"arch-linux",link:"#arch-linux",children:[]},{level:3,title:"Linuxbrew",slug:"linuxbrew",link:"#linuxbrew",children:[]},{level:3,title:"Debian",slug:"debian",link:"#debian",children:[]},{level:3,title:"Gentoo",slug:"gentoo",link:"#gentoo",children:[]}]},{level:2,title:"Docker 安装方式",slug:"docker-安装方式",link:"#docker-安装方式",children:[{level:3,title:"Docker image 的文件结构",slug:"docker-image-的文件结构",link:"#docker-image-的文件结构",children:[]}]}],path:"/document/install.html",pathLocale:"/",extraFields:[]},{title:"",headers:[{level:2,title:"XTLS? Xray? V2Ray?",slug:"xtls-xray-v2ray",link:"#xtls-xray-v2ray",children:[{level:3,title:"Who are we?",slug:"who-are-we",link:"#who-are-we",children:[]},{level:3,title:"Help Xray become stronger",slug:"help-xray-become-stronger",link:"#help-xray-become-stronger",children:[]},{level:3,title:"Telegram",slug:"telegram",link:"#telegram",children:[]},{level:3,title:"Thanks",slug:"thanks",link:"#thanks",children:[]},{level:3,title:"More about project X",slug:"more-about-project-x",link:"#more-about-project-x",children:[]},{level:3,title:"License",slug:"license",link:"#license",children:[]},{level:3,title:"Stargazers over time",slug:"stargazers-over-time",link:"#stargazers-over-time",children:[]}]}],path:"/en/",pathLocale:"/en/",extraFields:[]},{title:"编译文档",headers:[{level:2,title:"前序工作",slug:"前序工作",link:"#前序工作",children:[]},{level:2,title:"拉取 Xray 源代码",slug:"拉取-xray-源代码",link:"#拉取-xray-源代码",children:[]},{level:2,title:"构建二进制",slug:"构建二进制",link:"#构建二进制",children:[{level:3,title:"Windows(Powershell):",slug:"windows-powershell",link:"#windows-powershell",children:[]},{level:3,title:"macOS, Linux:",slug:"macos-linux",link:"#macos-linux",children:[]}]},{level:2,title:"交叉编译:",slug:"交叉编译",link:"#交叉编译",children:[]},{level:2,title:"可复现构建:",slug:"可复现构建",link:"#可复现构建",children:[]}],path:"/development/intro/compile.html",pathLocale:"/",extraFields:[]},{title:"设计目标",headers:[{level:2,title:"架构",slug:"架构",link:"#架构",children:[{level:3,title:"应用层",slug:"应用层",link:"#应用层",children:[]},{level:3,title:"代理层",slug:"代理层",link:"#代理层",children:[]},{level:3,title:"传输层",slug:"传输层",link:"#传输层",children:[]}]}],path:"/development/intro/design.html",pathLocale:"/",extraFields:[]},{title:"开发规范",headers:[{level:2,title:"基本",slug:"基本",link:"#基本",children:[{level:3,title:"版本控制",slug:"版本控制",link:"#版本控制",children:[]},{level:3,title:"分支(Branch)",slug:"分支-branch",link:"#分支-branch",children:[]},{level:3,title:"发布(Release)",slug:"发布-release",link:"#发布-release",children:[]},{level:3,title:"引用其它项目",slug:"引用其它项目",link:"#引用其它项目",children:[]}]},{level:2,title:"开发流程",slug:"开发流程",link:"#开发流程",children:[{level:3,title:"写代码之前",slug:"写代码之前",link:"#写代码之前",children:[]},{level:3,title:"修改代码",slug:"修改代码",link:"#修改代码",children:[]},{level:3,title:"Pull Request",slug:"pull-request",link:"#pull-request",children:[]},{level:3,title:"对代码的修改",slug:"对代码的修改",link:"#对代码的修改",children:[]}]},{level:2,title:"Xray 编码规范",slug:"xray-编码规范",link:"#xray-编码规范",children:[{level:3,title:"代码结构",slug:"代码结构",link:"#代码结构",children:[]},{level:3,title:"编码规范",slug:"编码规范",link:"#编码规范",children:[]}]}],path:"/development/intro/guide.html",pathLocale:"/",extraFields:[]},{title:"mKCP 协议",headers:[{level:2,title:"版本",slug:"版本",link:"#版本",children:[]},{level:2,title:"依赖",slug:"依赖",link:"#依赖",children:[{level:3,title:"底层协议",slug:"底层协议",link:"#底层协议",children:[]},{level:3,title:"函数",slug:"函数",link:"#函数",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",link:"#通讯过程",children:[]},{level:2,title:"数据格式",slug:"数据格式",link:"#数据格式",children:[{level:3,title:"数据包",slug:"数据包",link:"#数据包",children:[]},{level:3,title:"数据片段",slug:"数据片段",link:"#数据片段",children:[]},{level:3,title:"确认片段",slug:"确认片段",link:"#确认片段",children:[]},{level:3,title:"心跳片段",slug:"心跳片段",link:"#心跳片段",children:[]}]}],path:"/development/protocols/mkcp.html",pathLocale:"/",extraFields:[]},{title:"Mux.Cool 协议",headers:[{level:2,title:"版本",slug:"版本",link:"#版本",children:[]},{level:2,title:"依赖",slug:"依赖",link:"#依赖",children:[{level:3,title:"底层协议",slug:"底层协议",link:"#底层协议",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",link:"#通讯过程",children:[{level:3,title:"客户端行为",slug:"客户端行为",link:"#客户端行为",children:[]},{level:3,title:"服务器端行为",slug:"服务器端行为",link:"#服务器端行为",children:[]}]},{level:2,title:"传输格式",slug:"传输格式",link:"#传输格式",children:[{level:3,title:"帧格式",slug:"帧格式",link:"#帧格式",children:[]},{level:3,title:"元数据",slug:"元数据",link:"#元数据",children:[]},{level:3,title:"新建子连接 (New)",slug:"新建子连接-new",link:"#新建子连接-new",children:[]},{level:3,title:"保持子连接 (Keep)",slug:"保持子连接-keep",link:"#保持子连接-keep",children:[]},{level:3,title:"关闭子连接 (End)",slug:"关闭子连接-end",link:"#关闭子连接-end",children:[]},{level:3,title:"保持连接 (KeepAlive)",slug:"保持连接-keepalive",link:"#保持连接-keepalive",children:[]}]},{level:2,title:"应用",slug:"应用",link:"#应用",children:[]}],path:"/development/protocols/muxcool.html",pathLocale:"/",extraFields:[]},{title:"VLESS 协议",headers:[{level:2,title:"Request & Response",slug:"request-response",link:"#request-response",children:[]},{level:2,title:"ProtoBuf",slug:"protobuf",link:"#protobuf",children:[]},{level:2,title:"Schedulers Flow",slug:"schedulers-flow",link:"#schedulers-flow",children:[]},{level:2,title:"Encryption",slug:"encryption",link:"#encryption",children:[]},{level:2,title:"UDP issues",slug:"udp-issues",link:"#udp-issues",children:[]},{level:2,title:"客户端开发指引",slug:"客户端开发指引",link:"#客户端开发指引",children:[]},{level:2,title:"VLESS 分享链接标准",slug:"vless-分享链接标准",link:"#vless-分享链接标准",children:[]}],path:"/development/protocols/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess 协议",headers:[{level:2,title:"版本",slug:"版本",link:"#版本",children:[]},{level:2,title:"依赖",slug:"依赖",link:"#依赖",children:[{level:3,title:"底层协议",slug:"底层协议",link:"#底层协议",children:[]},{level:3,title:"用户 ID",slug:"用户-id",link:"#用户-id",children:[]},{level:3,title:"函数",slug:"函数",link:"#函数",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",link:"#通讯过程",children:[]},{level:2,title:"客户端请求",slug:"客户端请求",link:"#客户端请求",children:[{level:3,title:"认证信息",slug:"认证信息",link:"#认证信息",children:[]},{level:3,title:"指令部分",slug:"指令部分",link:"#指令部分",children:[]},{level:3,title:"数据部分",slug:"数据部分",link:"#数据部分",children:[]}]},{level:2,title:"服务器应答",slug:"服务器应答",link:"#服务器应答",children:[{level:3,title:"动态端口指令",slug:"动态端口指令",link:"#动态端口指令",children:[]}]},{level:2,title:"注释",slug:"注释",link:"#注释",children:[]}],path:"/development/protocols/vmess.html",pathLocale:"/",extraFields:[]},{title:"Browser Dialer",headers:[{level:2,title:"Background",slug:"background",link:"#background",children:[]},{level:2,title:"Xray & JS",slug:"xray-js",link:"#xray-js",children:[]},{level:2,title:"Early data",slug:"early-data",link:"#early-data",children:[]},{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[]}],path:"/config/features/browser_dialer.html",pathLocale:"/",extraFields:[]},{title:"环境变量",headers:[{level:2,title:"资源文件路径",slug:"资源文件路径",link:"#资源文件路径",children:[]},{level:2,title:"配置文件位置",slug:"配置文件位置",link:"#配置文件位置",children:[]},{level:2,title:"多配置目录",slug:"多配置目录",link:"#多配置目录",children:[]}],path:"/config/features/env.html",pathLocale:"/",extraFields:[]},{title:"Fallback 回落",headers:[{level:2,title:"fallbacks 配置",slug:"fallbacks-配置",link:"#fallbacks-配置",children:[{level:3,title:"FallbackObject",slug:"fallbackobject",link:"#fallbackobject",children:[]},{level:3,title:"补充说明",slug:"补充说明",link:"#补充说明",children:[]}]},{level:2,title:"Fallbacks 设计理论",slug:"fallbacks-设计理论",link:"#fallbacks-设计理论",children:[]}],path:"/config/features/fallback.html",pathLocale:"/",extraFields:[]},{title:"多文件配置",headers:[{level:2,title:"多文件启动",slug:"多文件启动",link:"#多文件启动",children:[]},{level:2,title:"规则说明",slug:"规则说明",link:"#规则说明",children:[{level:3,title:"普通对象({})",slug:"普通对象",link:"#普通对象",children:[]},{level:3,title:"数组([])",slug:"数组",link:"#数组",children:[]}]},{level:2,title:"接近可用配置的例子",slug:"接近可用配置的例子",link:"#接近可用配置的例子",children:[]},{level:2,title:"推荐的多文件列表",slug:"推荐的多文件列表",link:"#推荐的多文件列表",children:[]}],path:"/config/features/multiple.html",pathLocale:"/",extraFields:[]},{title:"XTLS 深度剖析",headers:[],path:"/config/features/xtls.html",pathLocale:"/",extraFields:[]},{title:"Dokodemo-Door",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[]},{level:2,title:"透明代理配置样例",slug:"透明代理配置样例",link:"#透明代理配置样例",children:[]}],path:"/config/inbounds/dokodemo.html",pathLocale:"/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",link:"#accountobject",children:[]}]}],path:"/config/inbounds/http.html",pathLocale:"/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[]},{level:2,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}],path:"/config/inbounds/shadowsocks.html",pathLocale:"/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",link:"#accountobject",children:[]}]}],path:"/config/inbounds/socks.html",pathLocale:"/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}]}],path:"/config/inbounds/trojan.html",pathLocale:"/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}]}],path:"/config/inbounds/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]},{level:3,title:"DetourObject",slug:"detourobject",link:"#detourobject",children:[]},{level:3,title:"DefaultObject",slug:"defaultobject",link:"#defaultobject",children:[]}]}],path:"/config/inbounds/vmess.html",pathLocale:"/",extraFields:[]},{title:"Blackhole",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ResponseObject",slug:"responseobject",link:"#responseobject",children:[]}]}],path:"/config/outbounds/blackhole.html",pathLocale:"/",extraFields:[]},{title:"DNS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[]},{level:2,title:"DNS 配置实例",slug:"dns-配置实例",link:"#dns-配置实例",children:[]}],path:"/config/outbounds/dns.html",pathLocale:"/",extraFields:[]},{title:"Freedom",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[]}],path:"/config/outbounds/freedom.html",pathLocale:"/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/outbounds/http.html",pathLocale:"/",extraFields:[]},{title:"Loopback",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"如何使用?",slug:"如何使用",link:"#如何使用",children:[]}]}],path:"/config/outbounds/loopback.html",pathLocale:"/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/outbounds/shadowsocks.html",pathLocale:"/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/outbounds/socks.html",pathLocale:"/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/outbounds/trojan.html",pathLocale:"/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]},{level:3,title:"UserObject",slug:"userobject",link:"#userobject",children:[]}]}],path:"/config/outbounds/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/outbounds/vmess.html",pathLocale:"/",extraFields:[]},{title:"Wireguard",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"Peers",slug:"peers",link:"#peers",children:[]}]}],path:"/config/outbounds/wireguard.html",pathLocale:"/",extraFields:[]},{title:"Domain Socket",headers:[{level:2,title:"DomainSocketObject",slug:"domainsocketobject",link:"#domainsocketobject",children:[]}],path:"/config/transports/domainsocket.html",pathLocale:"/",extraFields:[]},{title:"gRPC",headers:[{level:2,title:"GRPCObject",slug:"grpcobject",link:"#grpcobject",children:[]}],path:"/config/transports/grpc.html",pathLocale:"/",extraFields:[]},{title:"HTTP/2",headers:[{level:2,title:"HttpObject",slug:"httpobject",link:"#httpobject",children:[]}],path:"/config/transports/h2.html",pathLocale:"/",extraFields:[]},{title:"HTTPUpgrade",headers:[{level:2,title:"HttpUpgradeObject",slug:"httpupgradeobject",link:"#httpupgradeobject",children:[]}],path:"/config/transports/httpupgrade.html",pathLocale:"/",extraFields:[]},{title:"mKCP",headers:[{level:2,title:"KcpObject",slug:"kcpobject",link:"#kcpobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",link:"#headerobject",children:[]}]},{level:2,title:"鸣谢",slug:"鸣谢",link:"#鸣谢",children:[]},{level:2,title:"对 KCP 协议的改进",slug:"对-kcp-协议的改进",link:"#对-kcp-协议的改进",children:[{level:3,title:"更小的协议头",slug:"更小的协议头",link:"#更小的协议头",children:[]},{level:3,title:"确认包重传",slug:"确认包重传",link:"#确认包重传",children:[]},{level:3,title:"连接状态控制",slug:"连接状态控制",link:"#连接状态控制",children:[]}]}],path:"/config/transports/mkcp.html",pathLocale:"/",extraFields:[]},{title:"QUIC",headers:[{level:2,title:"QuicObject",slug:"quicobject",link:"#quicobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",link:"#headerobject",children:[]}]}],path:"/config/transports/quic.html",pathLocale:"/",extraFields:[]},{title:"TCP",headers:[{level:2,title:"TcpObject",slug:"tcpobject",link:"#tcpobject",children:[{level:3,title:"NoneHeaderObject",slug:"noneheaderobject",link:"#noneheaderobject",children:[]},{level:3,title:"HttpHeaderObject",slug:"httpheaderobject",link:"#httpheaderobject",children:[]}]}],path:"/config/transports/tcp.html",pathLocale:"/",extraFields:[]},{title:"WebSocket",headers:[{level:2,title:"WebSocketObject",slug:"websocketobject",link:"#websocketobject",children:[]},{level:2,title:"Browser Dialer",slug:"browser-dialer",link:"#browser-dialer",children:[]}],path:"/config/transports/websocket.html",pathLocale:"/",extraFields:[]},{title:"小小白白话文",headers:[],path:"/document/level-0/",pathLocale:"/",extraFields:[]},{title:"【第 1 章】 小小白白话文",headers:[{level:2,title:"1.1 这篇文档是写给谁的?",slug:"_1-1-这篇文档是写给谁的",link:"#_1-1-这篇文档是写给谁的",children:[]},{level:2,title:"1.2 这篇文档不是写给谁的?",slug:"_1-2-这篇文档不是写给谁的",link:"#_1-2-这篇文档不是写给谁的",children:[]},{level:2,title:"1.3 郑重声明及其他声明",slug:"_1-3-郑重声明及其他声明",link:"#_1-3-郑重声明及其他声明",children:[]},{level:2,title:"1.4 为什么自建是个难题?",slug:"_1-4-为什么自建是个难题",link:"#_1-4-为什么自建是个难题",children:[]},{level:2,title:"1.5 “用机场不就行了?”",slug:"_1-5-用机场不就行了",link:"#_1-5-用机场不就行了",children:[]},{level:2,title:"1.6 那么你到底要不要自建呢?",slug:"_1-6-那么你到底要不要自建呢",link:"#_1-6-那么你到底要不要自建呢",children:[]},{level:2,title:"1.7 题外啰嗦几句",slug:"_1-7-题外啰嗦几句",link:"#_1-7-题外啰嗦几句",children:[]},{level:2,title:"1.8 你的进度",slug:"_1-8-你的进度",link:"#_1-8-你的进度",children:[]}],path:"/document/level-0/ch01-preface.html",pathLocale:"/",extraFields:[]},{title:"【第 2 章】原料准备篇",headers:[{level:2,title:"2.1 获取一台 VPS",slug:"_2-1-获取一台-vps",link:"#_2-1-获取一台-vps",children:[]},{level:2,title:"2.2 获取一个心仪的域名",slug:"_2-2-获取一个心仪的域名",link:"#_2-2-获取一个心仪的域名",children:[]},{level:2,title:"2.3 你本地电脑上需要安装的软件",slug:"_2-3-你本地电脑上需要安装的软件",link:"#_2-3-你本地电脑上需要安装的软件",children:[]},{level:2,title:"2.4 你的进度",slug:"_2-4-你的进度",link:"#_2-4-你的进度",children:[]}],path:"/document/level-0/ch02-preparation.html",pathLocale:"/",extraFields:[]},{title:"【第 3 章】远程登录篇",headers:[{level:2,title:"3.1 远程登录 VPS (PuTTY)",slug:"_3-1-远程登录-vps-putty",link:"#_3-1-远程登录-vps-putty",children:[]},{level:2,title:"3.2 成功登录 SSH!初识命令行界面!",slug:"_3-2-成功登录-ssh-初识命令行界面",link:"#_3-2-成功登录-ssh-初识命令行界面",children:[]},{level:2,title:"3.3 第一次更新 Linux 的软件!",slug:"_3-3-第一次更新-linux-的软件",link:"#_3-3-第一次更新-linux-的软件",children:[]},{level:2,title:"3.4 你的进度",slug:"_3-4-你的进度",link:"#_3-4-你的进度",children:[]}],path:"/document/level-0/ch03-ssh.html",pathLocale:"/",extraFields:[]},{title:"【第 4 章】安全防护篇",headers:[{level:2,title:"4.1 为什么要做安全防护",slug:"_4-1-为什么要做安全防护",link:"#_4-1-为什么要做安全防护",children:[]},{level:2,title:"4.2 具体的风险到底是什么",slug:"_4-2-具体的风险到底是什么",link:"#_4-2-具体的风险到底是什么",children:[]},{level:2,title:"4.3 我们要做的安全防护有哪些",slug:"_4-3-我们要做的安全防护有哪些",link:"#_4-3-我们要做的安全防护有哪些",children:[]},{level:2,title:"4.4 将 SSH 远程登录端口修改为非 22 端口",slug:"_4-4-将-ssh-远程登录端口修改为非-22-端口",link:"#_4-4-将-ssh-远程登录端口修改为非-22-端口",children:[]},{level:2,title:"4.5 建立非 root 的新用户",slug:"_4-5-建立非-root-的新用户",link:"#_4-5-建立非-root-的新用户",children:[]},{level:2,title:"4.6 禁用 root 用户 SSH 远程登录",slug:"_4-6-禁用-root-用户-ssh-远程登录",link:"#_4-6-禁用-root-用户-ssh-远程登录",children:[]},{level:2,title:"4.7 使用 RSA 密钥登录并禁用密码登录",slug:"_4-7-使用-rsa-密钥登录并禁用密码登录",link:"#_4-7-使用-rsa-密钥登录并禁用密码登录",children:[]},{level:2,title:"4.8 你的进度",slug:"_4-8-你的进度",link:"#_4-8-你的进度",children:[]}],path:"/document/level-0/ch04-security.html",pathLocale:"/",extraFields:[]},{title:"【第 5 章】网站建设篇",headers:[{level:2,title:"5.1 为什么要做一个网站?",slug:"_5-1-为什么要做一个网站",link:"#_5-1-为什么要做一个网站",children:[]},{level:2,title:"5.2 登录 VPS、安装运行 Nginx",slug:"_5-2-登录-vps、安装运行-nginx",link:"#_5-2-登录-vps、安装运行-nginx",children:[]},{level:2,title:"5.3 创建一个最简单的网页",slug:"_5-3-创建一个最简单的网页",link:"#_5-3-创建一个最简单的网页",children:[]},{level:2,title:"5.4 常见错误的说明",slug:"_5-4-常见错误的说明",link:"#_5-4-常见错误的说明",children:[]},{level:2,title:"5.5 你的进度",slug:"_5-5-你的进度",link:"#_5-5-你的进度",children:[]}],path:"/document/level-0/ch05-webpage.html",pathLocale:"/",extraFields:[]},{title:"【第 6 章】证书管理篇",headers:[{level:2,title:"6.1 申请 TLS 证书",slug:"_6-1-申请-tls-证书",link:"#_6-1-申请-tls-证书",children:[]},{level:2,title:"6.2 安装 acme.sh",slug:"_6-2-安装-acme-sh",link:"#_6-2-安装-acme-sh",children:[]},{level:2,title:"6.3 测试证书申请",slug:"_6-3-测试证书申请",link:"#_6-3-测试证书申请",children:[]},{level:2,title:"6.4 正式证书申请",slug:"_6-4-正式证书申请",link:"#_6-4-正式证书申请",children:[]},{level:2,title:"6.5 证书安装",slug:"_6-5-证书安装",link:"#_6-5-证书安装",children:[]},{level:2,title:"6.6 你的进度",slug:"_6-6-你的进度",link:"#_6-6-你的进度",children:[]}],path:"/document/level-0/ch06-certificates.html",pathLocale:"/",extraFields:[]},{title:"【第 7 章】Xray 服务器篇",headers:[{level:2,title:"7.1 博观而约取,厚积而薄发",slug:"_7-1-博观而约取-厚积而薄发",link:"#_7-1-博观而约取-厚积而薄发",children:[]},{level:2,title:"7.2 安装 Xray",slug:"_7-2-安装-xray",link:"#_7-2-安装-xray",children:[]},{level:2,title:"7.3 给 Xray 配置 TLS 证书",slug:"_7-3-给-xray-配置-tls-证书",link:"#_7-3-给-xray-配置-tls-证书",children:[]},{level:2,title:"7.4 配置 Xray",slug:"_7-4-配置-xray",link:"#_7-4-配置-xray",children:[]},{level:2,title:"7.5 启动 Xray 服务!!(并查看服务状态)",slug:"_7-5-启动-xray-服务-并查看服务状态",link:"#_7-5-启动-xray-服务-并查看服务状态",children:[]},{level:2,title:"7.6 回顾 systemd 进行基本的服务管理",slug:"_7-6-回顾-systemd-进行基本的服务管理",link:"#_7-6-回顾-systemd-进行基本的服务管理",children:[]},{level:2,title:"7.7 服务器优化之一:开启 BBR",slug:"_7-7-服务器优化之一-开启-bbr",link:"#_7-7-服务器优化之一-开启-bbr",children:[]},{level:2,title:"7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS",slug:"_7-8-服务器优化之二-开启-http-自动跳转-https",link:"#_7-8-服务器优化之二-开启-http-自动跳转-https",children:[]},{level:2,title:"7.9 服务器优化之三:更丰富的回落",slug:"_7-9-服务器优化之三-更丰富的回落",link:"#_7-9-服务器优化之三-更丰富的回落",children:[]},{level:2,title:"7.10 你的进度",slug:"_7-10-你的进度",link:"#_7-10-你的进度",children:[]},{level:2,title:"7.11 重要勘误",slug:"_7-11-重要勘误",link:"#_7-11-重要勘误",children:[]}],path:"/document/level-0/ch07-xray-server.html",pathLocale:"/",extraFields:[]},{title:"【第 8 章】Xray 客户端篇",headers:[{level:2,title:"8.1 Xray 的工作原理简述",slug:"_8-1-xray-的工作原理简述",link:"#_8-1-xray-的工作原理简述",children:[]},{level:2,title:"8.2 客户端与服务器端正确连接",slug:"_8-2-客户端与服务器端正确连接",link:"#_8-2-客户端与服务器端正确连接",children:[]},{level:2,title:"8.3 附加题 1:在 PC 端手工配置 xray-core",slug:"_8-3-附加题-1-在-pc-端手工配置-xray-core",link:"#_8-3-附加题-1-在-pc-端手工配置-xray-core",children:[]},{level:2,title:"8.4 附加题 2:在 PC 端手工运行 xray-core",slug:"_8-4-附加题-2-在-pc-端手工运行-xray-core",link:"#_8-4-附加题-2-在-pc-端手工运行-xray-core",children:[]},{level:2,title:"8.5 附加题 3:在 PC 端开机自动运行 xray-core",slug:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",link:"#_8-5-附加题-3-在-pc-端开机自动运行-xray-core",children:[]},{level:2,title:"8.6 圆满完成!",slug:"_8-6-圆满完成",link:"#_8-6-圆满完成",children:[]},{level:2,title:"8.7 TO INFINITY AND BEYOND!",slug:"_8-7-to-infinity-and-beyond",link:"#_8-7-to-infinity-and-beyond",children:[]}],path:"/document/level-0/ch08-xray-clients.html",pathLocale:"/",extraFields:[]},{title:"【第 9 章】附录",headers:[{level:2,title:"1. 小小白白 Linux 基础命令索引",slug:"_1-小小白白-linux-基础命令索引",link:"#_1-小小白白-linux-基础命令索引",children:[]},{level:2,title:"2. 小小白白 Linux 重要配置文件索引",slug:"_2-小小白白-linux-重要配置文件索引",link:"#_2-小小白白-linux-重要配置文件索引",children:[]},{level:2,title:"3. 小小白白 Xray 重要文件索引",slug:"_3-小小白白-xray-重要文件索引",link:"#_3-小小白白-xray-重要文件索引",children:[]}],path:"/document/level-0/ch09-appendix.html",pathLocale:"/",extraFields:[]},{title:"入门技巧",headers:[],path:"/document/level-1/",pathLocale:"/",extraFields:[]},{title:"回落 (fallbacks) 功能简析",headers:[{level:2,title:"1. 回顾《小小白白话文》中的回落",slug:"_1-回顾《小小白白话文》中的回落",link:"#_1-回顾《小小白白话文》中的回落",children:[]},{level:2,title:"2. 重新认识回落 (WHAT, HOW v1)",slug:"_2-重新认识回落-what-how-v1",link:"#_2-重新认识回落-what-how-v1",children:[]},{level:2,title:"3. 为什么要回落 (WHY v1)",slug:"_3-为什么要回落-why-v1",link:"#_3-为什么要回落-why-v1",children:[]},{level:2,title:"4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)",slug:"_4-重新认识【回落の完全体】-what-why-how-v2",link:"#_4-重新认识【回落の完全体】-what-why-how-v2",children:[]},{level:2,title:"5. 多层回落示例及解读",slug:"_5-多层回落示例及解读",link:"#_5-多层回落示例及解读",children:[{level:3,title:"5.1 首先,我将服务器端配置的 443 监听段摘抄如下:",slug:"_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",link:"#_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",children:[]},{level:3,title:"5.2 后续监听处理的配置段摘抄如下:",slug:"_5-2-后续监听处理的配置段摘抄如下",link:"#_5-2-后续监听处理的配置段摘抄如下",children:[]}]},{level:2,title:"6. 结语",slug:"_6-结语",link:"#_6-结语",children:[]},{level:2,title:"7. 附加题",slug:"_7-附加题",link:"#_7-附加题",children:[]}],path:"/document/level-1/fallbacks-lv1.html",pathLocale:"/",extraFields:[]},{title:"SNI 回落",headers:[{level:2,title:"应用情景",slug:"应用情景",link:"#应用情景",children:[]},{level:2,title:"SNI 简介",slug:"sni-简介",link:"#sni-简介",children:[]},{level:2,title:"思路",slug:"思路",link:"#思路",children:[]},{level:2,title:"添加 DNS 记录",slug:"添加-dns-记录",link:"#添加-dns-记录",children:[]},{level:2,title:"申请 TLS 证书",slug:"申请-tls-证书",link:"#申请-tls-证书",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",link:"#xray-配置",children:[]},{level:2,title:"Nginx 配置",slug:"nginx-配置",link:"#nginx-配置",children:[]},{level:2,title:"Caddy 配置",slug:"caddy-配置",link:"#caddy-配置",children:[]},{level:2,title:"参考",slug:"参考",link:"#参考",children:[]},{level:2,title:"引用",slug:"引用",link:"#引用",children:[]}],path:"/document/level-1/fallbacks-with-sni.html",pathLocale:"/",extraFields:[]},{title:"路由 (routing) 功能简析(上)",headers:[{level:2,title:"1. 初识【路由】三兄弟",slug:"_1-初识【路由】三兄弟",link:"#_1-初识【路由】三兄弟",children:[]},{level:2,title:"2. 基本功: “兄弟一条心”",slug:"_2-基本功-兄弟一条心",link:"#_2-基本功-兄弟一条心",children:[{level:3,title:"2.1 入站",slug:"_2-1-入站",link:"#_2-1-入站",children:[]},{level:3,title:"2.3 路由",slug:"_2-3-路由",link:"#_2-3-路由",children:[]},{level:3,title:"2.4 路由配置项解析之一:流量筛选的依据",slug:"_2-4-路由配置项解析之一-流量筛选的依据",link:"#_2-4-路由配置项解析之一-流量筛选的依据",children:[]}]},{level:2,title:"3. 小试牛刀: “三分天下” 之 “域名分流”",slug:"_3-小试牛刀-三分天下-之-域名分流",link:"#_3-小试牛刀-三分天下-之-域名分流",children:[{level:3,title:"3.1 入站",slug:"_3-1-入站",link:"#_3-1-入站",children:[]},{level:3,title:"3.2 出站",slug:"_3-2-出站",link:"#_3-2-出站",children:[]},{level:3,title:"3.3 路由",slug:"_3-3-路由",link:"#_3-3-路由",children:[]},{level:3,title:"3.4 简析域名文件: geosite.dat",slug:"_3-4-简析域名文件-geosite-dat",link:"#_3-4-简析域名文件-geosite-dat",children:[]},{level:3,title:"3.5 所以 geosite.dat 到底是什么?不是有个 GFWList 吗?",slug:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",link:"#_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",children:[]},{level:3,title:"3.6 军师锦囊藏奇兵:一条隐藏的路由规则",slug:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",link:"#_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",children:[]},{level:3,title:"3.7 再看“三分天下”的大地图",slug:"_3-7-再看-三分天下-的大地图",link:"#_3-7-再看-三分天下-的大地图",children:[]}]},{level:2,title:"4. “三分天下” 之 “蜀魏争雄”",slug:"_4-三分天下-之-蜀魏争雄",link:"#_4-三分天下-之-蜀魏争雄",children:[]},{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",link:"#_5-攻城略池-多种路由匹配条件",children:[]}],path:"/document/level-1/routing-lv1-part1.html",pathLocale:"/",extraFields:[]},{title:"路由 (routing) 功能简析(下)",headers:[{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",link:"#_5-攻城略池-多种路由匹配条件",children:[{level:3,title:"5.1 基于指定域名分流:[domain], [full] 等",slug:"_5-1-基于指定域名分流-domain-full-等",link:"#_5-1-基于指定域名分流-domain-full-等",children:[]},{level:3,title:"5.2 基于 IP 文件分流:geoip.dat",slug:"_5-2-基于-ip-文件分流-geoip-dat",link:"#_5-2-基于-ip-文件分流-geoip-dat",children:[]},{level:3,title:"5.3 基于指定 IP 地址分流",slug:"_5-3-基于指定-ip-地址分流",link:"#_5-3-基于指定-ip-地址分流",children:[]},{level:3,title:"5.4 基于协议类型分流:[protocol] 等",slug:"_5-4-基于协议类型分流-protocol-等",link:"#_5-4-基于协议类型分流-protocol-等",children:[]},{level:3,title:"5.5 基于更多条件的分流",slug:"_5-5-基于更多条件的分流",link:"#_5-5-基于更多条件的分流",children:[]}]},{level:2,title:"6. “霸业初定”:路由规则整体回顾",slug:"_6-霸业初定-路由规则整体回顾",link:"#_6-霸业初定-路由规则整体回顾",children:[]},{level:2,title:"7. 路由配置常见错误",slug:"_7-路由配置常见错误",link:"#_7-路由配置常见错误",children:[{level:3,title:"7.1 错误示范",slug:"_7-1-错误示范",link:"#_7-1-错误示范",children:[]},{level:3,title:"7.2 正确示范",slug:"_7-2-正确示范",link:"#_7-2-正确示范",children:[]}]},{level:2,title:"8. 明修栈道、暗渡陈仓",slug:"_8-明修栈道、暗渡陈仓",link:"#_8-明修栈道、暗渡陈仓",children:[{level:3,title:'8.1 域名策略: "AsIs"',slug:"_8-1-域名策略-asis",link:"#_8-1-域名策略-asis",children:[]},{level:3,title:'8.2 域名策略: "IPIfNonMatch"',slug:"_8-2-域名策略-ipifnonmatch",link:"#_8-2-域名策略-ipifnonmatch",children:[]},{level:3,title:'8.3 域名策略: "IPOnDemand"',slug:"_8-3-域名策略-ipondemand",link:"#_8-3-域名策略-ipondemand",children:[]}]},{level:2,title:"9. 思考题",slug:"_9-思考题",link:"#_9-思考题",children:[]},{level:2,title:"10. 结语",slug:"_10-结语",link:"#_10-结语",children:[]},{level:2,title:"11. 尾注",slug:"_11-尾注",link:"#_11-尾注",children:[]}],path:"/document/level-1/routing-lv1-part2.html",pathLocale:"/",extraFields:[]},{title:"Xray 的工作模式",headers:[{level:2,title:"单服务器模式",slug:"单服务器模式",link:"#单服务器模式",children:[]},{level:2,title:"桥接模式",slug:"桥接模式",link:"#桥接模式",children:[]},{level:2,title:"工作原理",slug:"工作原理",link:"#工作原理",children:[]}],path:"/document/level-1/work.html",pathLocale:"/",extraFields:[]},{title:"进阶文档",headers:[],path:"/document/level-2/",pathLocale:"/",extraFields:[]},{title:"GID 透明代理",headers:[{level:2,title:"思路",slug:"思路",link:"#思路",children:[]},{level:2,title:"配置过程",slug:"配置过程",link:"#配置过程",children:[{level:3,title:"1. 前期准备",slug:"_1-前期准备",link:"#_1-前期准备",children:[]},{level:3,title:"2. 添加用户(安卓用户请忽略)",slug:"_2-添加用户-安卓用户请忽略",link:"#_2-添加用户-安卓用户请忽略",children:[]},{level:3,title:"3. 配置运行 Xray,配置 iptables 规则",slug:"_3-配置运行-xray-配置-iptables-规则",link:"#_3-配置运行-xray-配置-iptables-规则",children:[]}]},{level:2,title:"下面提供一个实现 tproxy 全局代理的完整配置过程",slug:"下面提供一个实现-tproxy-全局代理的完整配置过程",link:"#下面提供一个实现-tproxy-全局代理的完整配置过程",children:[{level:3,title:"1. 完成 前期准备 和 添加用户",slug:"_1-完成-前期准备-和-添加用户",link:"#_1-完成-前期准备-和-添加用户",children:[]},{level:3,title:"2. 准备 Xray 配置文件",slug:"_2-准备-xray-配置文件",link:"#_2-准备-xray-配置文件",children:[]},{level:3,title:"3. 配置最大文件打开数&运行 Xray 客户端",slug:"_3-配置最大文件打开数-运行-xray-客户端",link:"#_3-配置最大文件打开数-运行-xray-客户端",children:[]},{level:3,title:"4. 设置 iptables 规则",slug:"_4-设置-iptables-规则",link:"#_4-设置-iptables-规则",children:[]}]}],path:"/document/level-2/iptables_gid.html",pathLocale:"/",extraFields:[]},{title:"Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹",headers:[{level:2,title:"编译 nginx --with-stream",slug:"编译-nginx-with-stream",link:"#编译-nginx-with-stream",children:[]},{level:2,title:"配置 nginx",slug:"配置-nginx",link:"#配置-nginx",children:[]},{level:2,title:"xray 配置",slug:"xray-配置",link:"#xray-配置",children:[]},{level:2,title:"客户端及服务端启动服务",slug:"客户端及服务端启动服务",link:"#客户端及服务端启动服务",children:[]},{level:2,title:"结束",slug:"结束",link:"#结束",children:[]},{level:2,title:"HTTPS 隧道",slug:"https-隧道",link:"#https-隧道",children:[{level:3,title:"haproxy_client 配置 (运行前去掉注释)",slug:"haproxy-client-配置-运行前去掉注释",link:"#haproxy-client-配置-运行前去掉注释",children:[]},{level:3,title:"haproxy_server 配置 (运行前去掉注释)",slug:"haproxy-server-配置-运行前去掉注释",link:"#haproxy-server-配置-运行前去掉注释",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-1",link:"#xray-配置-1",children:[]}]},{level:2,title:"WebSocket over HTTP/2",slug:"websocket-over-http-2",link:"#websocket-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置",link:"#haproxy-client-配置",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置",link:"#haproxy-server-配置",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-2",link:"#xray-配置-2",children:[]}]},{level:2,title:"gRPC over HTTP/2",slug:"grpc-over-http-2",link:"#grpc-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-1",link:"#haproxy-client-配置-1",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-1",link:"#haproxy-server-配置-1",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-3",link:"#xray-配置-3",children:[]},{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-2",link:"#haproxy-client-配置-2",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-2",link:"#haproxy-server-配置-2",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-4",link:"#xray-配置-4",children:[]}]}],path:"/document/level-2/nginx_or_haproxy_tls_tunnel.html",pathLocale:"/",extraFields:[]},{title:"出站流量重定向",headers:[{level:2,title:"前言",slug:"前言",link:"#前言",children:[]},{level:2,title:"1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)",slug:"_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",link:"#_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",children:[]},{level:2,title:"2、编辑 VPN 配置文件(以 WireGuard 为例)",slug:"_2、编辑-vpn-配置文件-以-wireguard-为例",link:"#_2、编辑-vpn-配置文件-以-wireguard-为例",children:[]},{level:2,title:"3、启用 WireGuard 网络接口",slug:"_3、启用-wireguard-网络接口",link:"#_3、启用-wireguard-网络接口",children:[]},{level:2,title:"4、Xray-core 配置文件修改",slug:"_4、xray-core-配置文件修改",link:"#_4、xray-core-配置文件修改",children:[]},{level:2,title:"5、系统设置配置",slug:"_5、系统设置配置",link:"#_5、系统设置配置",children:[]},{level:2,title:"6、完成 WireGuard 相关设置",slug:"_6、完成-wireguard-相关设置",link:"#_6、完成-wireguard-相关设置",children:[]},{level:2,title:"后记",slug:"后记",link:"#后记",children:[]},{level:2,title:"感谢",slug:"感谢",link:"#感谢",children:[]}],path:"/document/level-2/redirect.html",pathLocale:"/",extraFields:[]},{title:"TProxy 透明代理",headers:[{level:2,title:"开始之前",slug:"开始之前",link:"#开始之前",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",link:"#xray-配置",children:[]},{level:2,title:"策略路由配置",slug:"策略路由配置",link:"#策略路由配置",children:[]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",link:"#netfilter-配置",children:[]},{level:2,title:"配置永久化与开机自启",slug:"配置永久化与开机自启",link:"#配置永久化与开机自启",children:[]}],path:"/document/level-2/tproxy.html",pathLocale:"/",extraFields:[]},{title:"TProxy 透明代理 (ipv4 and ipv6)",headers:[{level:2,title:"Xray 配置",slug:"xray-配置",link:"#xray-配置",children:[{level:3,title:"客户端配置",slug:"客户端配置",link:"#客户端配置",children:[]},{level:3,title:"服务端配置",slug:"服务端配置",link:"#服务端配置",children:[]}]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",link:"#netfilter-配置",children:[{level:3,title:"首先设置策略路由",slug:"首先设置策略路由",link:"#首先设置策略路由",children:[]},{level:3,title:"使用 iptables",slug:"使用-iptables",link:"#使用-iptables",children:[]},{level:3,title:"使用 nftables",slug:"使用-nftables",link:"#使用-nftables",children:[]},{level:3,title:"开机自动运行 Netfilter 配置",slug:"开机自动运行-netfilter-配置",link:"#开机自动运行-netfilter-配置",children:[]}]},{level:2,title:"局域网设备上网设置",slug:"局域网设备上网设置",link:"#局域网设备上网设置",children:[{level:3,title:"方法一",slug:"方法一",link:"#方法一",children:[]},{level:3,title:"方法二",slug:"方法二",link:"#方法二",children:[]}]},{level:2,title:"Finally",slug:"finally",link:"#finally",children:[]},{level:2,title:"写在最后",slug:"写在最后",link:"#写在最后",children:[]}],path:"/document/level-2/tproxy_ipv4_and_ipv6.html",pathLocale:"/",extraFields:[]},{title:"流量统计",headers:[{level:2,title:"查看流量信息",slug:"查看流量信息",link:"#查看流量信息",children:[]},{level:2,title:"流量信息的处理",slug:"流量信息的处理",link:"#流量信息的处理",children:[]}],path:"/document/level-2/traffic_stats.html",pathLocale:"/",extraFields:[]},{title:"通过 Cloudflare Warp 增强代理安全性",headers:[{level:2,title:"申请 Warp 账户",slug:"申请-warp-账户",link:"#申请-warp-账户",children:[{level:3,title:"感谢 Cloudflare 推动自由的互联网,现在你可以免费使用 Warp 服务,连接的时候会根据出口自动选择最近的服务器",slug:"感谢-cloudflare-推动自由的互联网-现在你可以免费使用-warp-服务-连接的时候会根据出口自动选择最近的服务器",link:"#感谢-cloudflare-推动自由的互联网-现在你可以免费使用-warp-服务-连接的时候会根据出口自动选择最近的服务器",children:[]}]},{level:2,title:"在服务端分流回国流量至 warp",slug:"在服务端分流回国流量至-warp",link:"#在服务端分流回国流量至-warp",children:[]},{level:2,title:"客户端使用 warp 链式代理",slug:"客户端使用-warp-链式代理",link:"#客户端使用-warp-链式代理",children:[]}],path:"/document/level-2/warp.html",pathLocale:"/",extraFields:[]},{title:"大史记",headers:[{level:2,title:"2021.4.6",slug:"_2021-4-6",link:"#_2021-4-6",children:[]},{level:2,title:"2021.4.4",slug:"_2021-4-4",link:"#_2021-4-4",children:[]},{level:2,title:"2021.4.1 v1.4.2",slug:"_2021-4-1-v1-4-2",link:"#_2021-4-1-v1-4-2",children:[]},{level:2,title:"2021.3.25",slug:"_2021-3-25",link:"#_2021-3-25",children:[]},{level:2,title:"2021.3.15",slug:"_2021-3-15",link:"#_2021-3-15",children:[]},{level:2,title:"2021.3.14 v1.4.0",slug:"_2021-3-14-v1-4-0",link:"#_2021-3-14-v1-4-0",children:[]},{level:2,title:"2021.3.3 1.3.1",slug:"_2021-3-3-1-3-1",link:"#_2021-3-3-1-3-1",children:[]},{level:2,title:"2021.2.14 1.3.0",slug:"_2021-2-14-1-3-0",link:"#_2021-2-14-1-3-0",children:[]},{level:2,title:"2021.01.31 1.2.4",slug:"_2021-01-31-1-2-4",link:"#_2021-01-31-1-2-4",children:[]},{level:2,title:"2021.01.25",slug:"_2021-01-25",link:"#_2021-01-25",children:[]},{level:2,title:"2021.01.22 1.2.3",slug:"_2021-01-22-1-2-3",link:"#_2021-01-22-1-2-3",children:[]},{level:2,title:"2021.01.19",slug:"_2021-01-19",link:"#_2021-01-19",children:[]},{level:2,title:"2021.01.17",slug:"_2021-01-17",link:"#_2021-01-17",children:[]},{level:2,title:"2021.01.15 1.2.2",slug:"_2021-01-15-1-2-2",link:"#_2021-01-15-1-2-2",children:[]},{level:2,title:"2021.01.12",slug:"_2021-01-12",link:"#_2021-01-12",children:[]},{level:2,title:"2021.01.10 1.2.1",slug:"_2021-01-10-1-2-1",link:"#_2021-01-10-1-2-1",children:[]},{level:2,title:"2021.01.07",slug:"_2021-01-07",link:"#_2021-01-07",children:[]},{level:2,title:"2021.01.05",slug:"_2021-01-05",link:"#_2021-01-05",children:[]},{level:2,title:"2021.01.03",slug:"_2021-01-03",link:"#_2021-01-03",children:[]},{level:2,title:"2021.01.01",slug:"_2021-01-01",link:"#_2021-01-01",children:[]},{level:2,title:"2020.12.29",slug:"_2020-12-29",link:"#_2020-12-29",children:[]},{level:2,title:"2020.12.25 1.1.5",slug:"_2020-12-25-1-1-5",link:"#_2020-12-25-1-1-5",children:[]},{level:2,title:"2020.12.24",slug:"_2020-12-24",link:"#_2020-12-24",children:[]},{level:2,title:"2020.12.23",slug:"_2020-12-23",link:"#_2020-12-23",children:[]},{level:2,title:"2020.12.21",slug:"_2020-12-21",link:"#_2020-12-21",children:[]},{level:2,title:"2020.12.18 1.1.4",slug:"_2020-12-18-1-1-4",link:"#_2020-12-18-1-1-4",children:[]},{level:2,title:"2020.12.17",slug:"_2020-12-17",link:"#_2020-12-17",children:[]},{level:2,title:"2020.12.15",slug:"_2020-12-15",link:"#_2020-12-15",children:[]},{level:2,title:"2020.12.11 1.1.3",slug:"_2020-12-11-1-1-3",link:"#_2020-12-11-1-1-3",children:[]},{level:2,title:"2020.12.06 1.1.2",slug:"_2020-12-06-1-1-2",link:"#_2020-12-06-1-1-2",children:[]},{level:2,title:"2020.12.04",slug:"_2020-12-04",link:"#_2020-12-04",children:[]},{level:2,title:"2020.11.27",slug:"_2020-11-27",link:"#_2020-11-27",children:[]},{level:2,title:"2020.11.25 1.0.0",slug:"_2020-11-25-1-0-0",link:"#_2020-11-25-1-0-0",children:[]},{level:2,title:"2020.11.23",slug:"_2020-11-23",link:"#_2020-11-23",children:[]}],path:"/en/about/news.html",pathLocale:"/en/",extraFields:[]},{title:"Configurations",headers:[{level:2,title:"Overview",slug:"overview",link:"#overview",children:[]},{level:2,title:"Basic Configuration Modules",slug:"basic-configuration-modules",link:"#basic-configuration-modules",children:[]}],path:"/en/config/",pathLocale:"/en/",extraFields:[]},{title:"API Interface",headers:[{level:2,title:"ApiObject",slug:"apiobject",link:"#apiobject",children:[]},{level:2,title:"Related Configuration",slug:"related-configuration",link:"#related-configuration",children:[]},{level:2,title:"Supported API List",slug:"supported-api-list",link:"#supported-api-list",children:[{level:3,title:"HandlerService",slug:"handlerservice",link:"#handlerservice",children:[]},{level:3,title:"LoggerService",slug:"loggerservice",link:"#loggerservice",children:[]},{level:3,title:"StatsService",slug:"statsservice",link:"#statsservice",children:[]},{level:3,title:"ReflectionService",slug:"reflectionservice",link:"#reflectionservice",children:[]}]},{level:2,title:"API Calling Example",slug:"api-calling-example",link:"#api-calling-example",children:[]}],path:"/en/config/api.html",pathLocale:"/en/",extraFields:[]},{title:"Built-in DNS Server",headers:[{level:2,title:"DNS Server",slug:"dns-server",link:"#dns-server",children:[]},{level:2,title:"DNS Processing Flow",slug:"dns-processing-flow",link:"#dns-processing-flow",children:[]},{level:2,title:"DnsObject",slug:"dnsobject",link:"#dnsobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/dns.html",pathLocale:"/en/",extraFields:[]},{title:"FakeDNS",headers:[{level:2,title:"FakeDNSObject",slug:"fakednsobject",link:"#fakednsobject",children:[{level:3,title:"How to use?",slug:"how-to-use",link:"#how-to-use",children:[]},{level:3,title:"Using with other types of DNS",slug:"using-with-other-types-of-dns",link:"#using-with-other-types-of-dns",children:[]}]}],path:"/en/config/fakedns.html",pathLocale:"/en/",extraFields:[]},{title:"Inbound Proxy",headers:[{level:2,title:"InboundObject",slug:"inboundobject",link:"#inboundobject",children:[{level:3,title:"SniffingObject",slug:"sniffingobject",link:"#sniffingobject",children:[]},{level:3,title:"AllocateObject",slug:"allocateobject",link:"#allocateobject",children:[]}]}],path:"/en/config/inbound.html",pathLocale:"/en/",extraFields:[]},{title:"Log Configuration",headers:[{level:2,title:"LogObject",slug:"logobject",link:"#logobject",children:[]}],path:"/en/config/log.html",pathLocale:"/en/",extraFields:[]},{title:"Metrics",headers:[{level:2,title:"Related configurations",slug:"related-configurations",link:"#related-configurations",children:[]},{level:2,title:"Usage",slug:"usage",link:"#usage",children:[{level:3,title:"pprof",slug:"pprof",link:"#pprof",children:[]},{level:3,title:"expvars",slug:"expvars",link:"#expvars",children:[]},{level:3,title:"Additional",slug:"additional",link:"#additional",children:[]}]}],path:"/en/config/metrics.html",pathLocale:"/en/",extraFields:[]},{title:"Outbound Proxies",headers:[{level:2,title:"OutboundObject",slug:"outboundobject",link:"#outboundobject",children:[{level:3,title:"ProxySettingsObject",slug:"proxysettingsobject",link:"#proxysettingsobject",children:[]},{level:3,title:"MuxObject",slug:"muxobject",link:"#muxobject",children:[]}]}],path:"/en/config/outbound.html",pathLocale:"/en/",extraFields:[]},{title:"Local Policy",headers:[{level:2,title:"PolicyObject",slug:"policyobject",link:"#policyobject",children:[{level:3,title:"LevelPolicyObject",slug:"levelpolicyobject",link:"#levelpolicyobject",children:[]},{level:3,title:"SystemPolicyObject",slug:"systempolicyobject",link:"#systempolicyobject",children:[]}]}],path:"/en/config/policy.html",pathLocale:"/en/",extraFields:[]},{title:"Reverse Proxy",headers:[{level:2,title:"ReverseObject",slug:"reverseobject",link:"#reverseobject",children:[{level:3,title:"BridgeObject",slug:"bridgeobject",link:"#bridgeobject",children:[]},{level:3,title:"PortalObject",slug:"portalobject",link:"#portalobject",children:[]}]},{level:2,title:"Complete Configuration Example",slug:"complete-configuration-example",link:"#complete-configuration-example",children:[{level:3,title:"Bridge Configuration",slug:"bridge-configuration",link:"#bridge-configuration",children:[]},{level:3,title:"Portal Configuration",slug:"portal-configuration",link:"#portal-configuration",children:[]}]}],path:"/en/config/reverse.html",pathLocale:"/en/",extraFields:[]},{title:"Routing",headers:[{level:2,title:"RoutingObject",slug:"routingobject",link:"#routingobject",children:[{level:3,title:"RuleObject",slug:"ruleobject",link:"#ruleobject",children:[]},{level:3,title:"BalancerObject",slug:"balancerobject",link:"#balancerobject",children:[]},{level:3,title:"Predefined Domain Lists",slug:"predefined-domain-lists",link:"#predefined-domain-lists",children:[]}]}],path:"/en/config/routing.html",pathLocale:"/en/",extraFields:[]},{title:"Traffic Statistics",headers:[{level:2,title:"StatsObject",slug:"statsobject",link:"#statsobject",children:[]},{level:2,title:"Retrieving Traffic Statistics",slug:"retrieving-traffic-statistics",link:"#retrieving-traffic-statistics",children:[]}],path:"/en/config/stats.html",pathLocale:"/en/",extraFields:[]},{title:"Transport",headers:[{level:2,title:"TransportObject",slug:"transportobject",link:"#transportobject",children:[]},{level:2,title:"StreamSettingsObject",slug:"streamsettingsobject",link:"#streamsettingsobject",children:[{level:3,title:"TLSObject",slug:"tlsobject",link:"#tlsobject",children:[]},{level:3,title:"SockoptObject",slug:"sockoptobject",link:"#sockoptobject",children:[]}]}],path:"/en/config/transport.html",pathLocale:"/en/",extraFields:[]},{title:"Development Guide",headers:[{level:2,title:"Compile Documentation",slug:"compile-documentation",link:"#compile-documentation",children:[]},{level:2,title:"Design Concept",slug:"design-concept",link:"#design-concept",children:[]},{level:2,title:"Development Standards",slug:"development-standards",link:"#development-standards",children:[]},{level:2,title:"Protocol Details",slug:"protocol-details",link:"#protocol-details",children:[{level:3,title:"VLESS Protocol",slug:"vless-protocol",link:"#vless-protocol",children:[]},{level:3,title:"VMess Protocol",slug:"vmess-protocol",link:"#vmess-protocol",children:[]},{level:3,title:"Mux.Cool Protocol",slug:"mux-cool-protocol",link:"#mux-cool-protocol",children:[]},{level:3,title:"mKCP Protocol",slug:"mkcp-protocol",link:"#mkcp-protocol",children:[]}]}],path:"/en/development/",pathLocale:"/en/",extraFields:[]},{title:"Quick Start",headers:[{level:2,title:"Download and Install",slug:"download-and-install",link:"#download-and-install",children:[]},{level:2,title:"Configure and Run",slug:"configure-and-run",link:"#configure-and-run",children:[]},{level:2,title:"Command Parameters",slug:"command-parameters",link:"#command-parameters",children:[]},{level:2,title:"Improve Documents",slug:"improve-documents",link:"#improve-documents",children:[]},{level:2,title:"Beginner Tutorial",slug:"beginner-tutorial",link:"#beginner-tutorial",children:[]},{level:2,title:"Getting Started Tips",slug:"getting-started-tips",link:"#getting-started-tips",children:[]},{level:2,title:"Advanced Documentation",slug:"advanced-documentation",link:"#advanced-documentation",children:[]}],path:"/en/document/",pathLocale:"/en/",extraFields:[]},{title:"Command Parameters",headers:[{level:2,title:"Get Basic Commands",slug:"get-basic-commands",link:"#get-basic-commands",children:[{level:3,title:"xray run",slug:"xray-run",link:"#xray-run",children:[]},{level:3,title:"xray version",slug:"xray-version",link:"#xray-version",children:[]},{level:3,title:"xray api",slug:"xray-api",link:"#xray-api",children:[]},{level:3,title:"xray tls",slug:"xray-tls",link:"#xray-tls",children:[]},{level:3,title:"xray uuid",slug:"xray-uuid",link:"#xray-uuid",children:[]},{level:3,title:"xray x25519",slug:"xray-x25519",link:"#xray-x25519",children:[]},{level:3,title:"xray wg",slug:"xray-wg",link:"#xray-wg",children:[]}]}],path:"/en/document/command.html",pathLocale:"/en/",extraFields:[]},{title:"Configure and Run",headers:[{level:2,title:"Server Configuration",slug:"server-configuration",link:"#server-configuration",children:[]},{level:2,title:"Client Configuration",slug:"client-configuration",link:"#client-configuration",children:[]},{level:2,title:"Run",slug:"run",link:"#run",children:[]}],path:"/en/document/config.html",pathLocale:"/en/",extraFields:[]},{title:"Contribute to Project X's Document",headers:[{level:2,title:"Improve Document",slug:"improve-document",link:"#improve-document",children:[]},{level:2,title:"Found Problems?",slug:"found-problems",link:"#found-problems",children:[]}],path:"/en/document/document.html",pathLocale:"/en/",extraFields:[]},{title:"Download and Install",headers:[{level:2,title:"Platform Support",slug:"platform-support",link:"#platform-support",children:[]},{level:2,title:"Download Xray",slug:"download-xray",link:"#download-xray",children:[]},{level:2,title:"Verify the Installation Package",slug:"verify-the-installation-package",link:"#verify-the-installation-package",children:[]},{level:2,title:"Install on Windows",slug:"install-on-windows",link:"#install-on-windows",children:[]},{level:2,title:"Install on macOS",slug:"install-on-macos",link:"#install-on-macos",children:[]},{level:2,title:"Install on Linux",slug:"install-on-linux",link:"#install-on-linux",children:[{level:3,title:"Install Script",slug:"install-script",link:"#install-script",children:[]},{level:3,title:"Arch Linux",slug:"arch-linux",link:"#arch-linux",children:[]},{level:3,title:"Linuxbrew",slug:"linuxbrew",link:"#linuxbrew",children:[]},{level:3,title:"Debian",slug:"debian",link:"#debian",children:[]}]},{level:2,title:"Install via Docker",slug:"install-via-docker",link:"#install-via-docker",children:[{level:3,title:"The File Structure of the Docker Image",slug:"the-file-structure-of-the-docker-image",link:"#the-file-structure-of-the-docker-image",children:[]}]}],path:"/en/document/install.html",pathLocale:"/en/",extraFields:[]},{title:"透明代理入门",headers:[{level:2,title:"什么是透明代理",slug:"什么是透明代理",link:"#什么是透明代理",children:[]},{level:2,title:"透明代理的实现",slug:"透明代理的实现",link:"#透明代理的实现",children:[{level:3,title:"tun2socks",slug:"tun2socks",link:"#tun2socks",children:[]},{level:3,title:"iptables/nftables",slug:"iptables-nftables",link:"#iptables-nftables",children:[]}]},{level:2,title:"iptables 实现透明代理原理",slug:"iptables-实现透明代理原理",link:"#iptables-实现透明代理原理",children:[]},{level:2,title:"透明代理难在哪里",slug:"透明代理难在哪里",link:"#透明代理难在哪里",children:[]},{level:2,title:"从零开始一步步实现基于 iptables-tproxy 的透明代理",slug:"从零开始一步步实现基于-iptables-tproxy-的透明代理",link:"#从零开始一步步实现基于-iptables-tproxy-的透明代理",children:[{level:3,title:"在开始之前,你需要有一定的基础知识:",slug:"在开始之前-你需要有一定的基础知识",link:"#在开始之前-你需要有一定的基础知识",children:[]},{level:3,title:"前期准备工作",slug:"前期准备工作",link:"#前期准备工作",children:[]},{level:3,title:"首先,我们先试试做到第一阶段",slug:"首先-我们先试试做到第一阶段",link:"#首先-我们先试试做到第一阶段",children:[]},{level:3,title:"第二阶段",slug:"第二阶段",link:"#第二阶段",children:[]},{level:3,title:"第三阶段",slug:"第三阶段",link:"#第三阶段",children:[]},{level:3,title:"第四阶段",slug:"第四阶段",link:"#第四阶段",children:[]},{level:3,title:"代理 ipv6",slug:"代理-ipv6",link:"#代理-ipv6",children:[]}]}],path:"/document/level-2/transparent_proxy/transparent_proxy.html",pathLocale:"/",extraFields:[]},{title:"Browser Dialer",headers:[{level:2,title:"Background",slug:"background",link:"#background",children:[]},{level:2,title:"Xray & JS",slug:"xray-js",link:"#xray-js",children:[]},{level:2,title:"Early data",slug:"early-data",link:"#early-data",children:[]},{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[]}],path:"/en/config/features/browser_dialer.html",pathLocale:"/en/",extraFields:[]},{title:"Environment Variables",headers:[{level:2,title:"Xray Asset Location",slug:"xray-asset-location",link:"#xray-asset-location",children:[]},{level:2,title:"Configuration File Location",slug:"configuration-file-location",link:"#configuration-file-location",children:[]},{level:2,title:"Multiple Configuration Directories",slug:"multiple-configuration-directories",link:"#multiple-configuration-directories",children:[]}],path:"/en/config/features/env.html",pathLocale:"/en/",extraFields:[]},{title:"Fallback",headers:[{level:2,title:"fallbacks configuration",slug:"fallbacks-configuration",link:"#fallbacks-configuration",children:[{level:3,title:"FallbackObject",slug:"fallbackobject",link:"#fallbackobject",children:[]},{level:3,title:"Additional Information",slug:"additional-information",link:"#additional-information",children:[]}]},{level:2,title:"Fallbacks design theory",slug:"fallbacks-design-theory",link:"#fallbacks-design-theory",children:[]}],path:"/en/config/features/fallback.html",pathLocale:"/en/",extraFields:[]},{title:"Multi-file configuration",headers:[{level:2,title:"Multi-file startup",slug:"multi-file-startup",link:"#multi-file-startup",children:[]},{level:2,title:"Rule Explaination",slug:"rule-explaination",link:"#rule-explaination",children:[{level:3,title:"Normal Objects({})",slug:"normal-objects",link:"#normal-objects",children:[]},{level:3,title:"Arrays([])",slug:"arrays",link:"#arrays",children:[]}]},{level:2,title:"Recommended Multi-file List",slug:"recommended-multi-file-list",link:"#recommended-multi-file-list",children:[]}],path:"/en/config/features/multiple.html",pathLocale:"/en/",extraFields:[]},{title:"Deep analysis of XTLS",headers:[],path:"/en/config/features/xtls.html",pathLocale:"/en/",extraFields:[]},{title:"Dokodemo-Door",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[]},{level:2,title:"Transparent Proxy Configuration Example",slug:"transparent-proxy-configuration-example",link:"#transparent-proxy-configuration-example",children:[]}],path:"/en/config/inbounds/dokodemo.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP",headers:[{level:3,title:"AccountObject",slug:"accountobject",link:"#accountobject",children:[]}],path:"/en/config/inbounds/http.html",pathLocale:"/en/",extraFields:[]},{title:"Shadowsocks",headers:[{level:3,title:"Supported Encryption Methods",slug:"supported-encryption-methods",link:"#supported-encryption-methods",children:[]},{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[]},{level:2,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}],path:"/en/config/inbounds/shadowsocks.html",pathLocale:"/en/",extraFields:[]},{title:"SOCKS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",link:"#accountobject",children:[]}]}],path:"/en/config/inbounds/socks.html",pathLocale:"/en/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}]}],path:"/en/config/inbounds/trojan.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}]}],path:"/en/config/inbounds/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}]}],path:"/en/config/inbounds/vmess.html",pathLocale:"/en/",extraFields:[]},{title:"Blackhole",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ResponseObject",slug:"responseobject",link:"#responseobject",children:[]}]}],path:"/en/config/outbounds/blackhole.html",pathLocale:"/en/",extraFields:[]},{title:"DNS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[]},{level:2,title:"DNS Configuration Example",slug:"dns-configuration-example",link:"#dns-configuration-example",children:[]}],path:"/en/config/outbounds/dns.html",pathLocale:"/en/",extraFields:[]},{title:"Freedom",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[]}],path:"/en/config/outbounds/freedom.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/outbounds/http.html",pathLocale:"/en/",extraFields:[]},{title:"Loopback",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"How to use?",slug:"how-to-use",link:"#how-to-use",children:[]}]}],path:"/en/config/outbounds/loopback.html",pathLocale:"/en/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/outbounds/shadowsocks.html",pathLocale:"/en/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/outbounds/socks.html",pathLocale:"/en/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/outbounds/trojan.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]},{level:3,title:"UserObject",slug:"userobject",link:"#userobject",children:[]}]}],path:"/en/config/outbounds/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/outbounds/vmess.html",pathLocale:"/en/",extraFields:[]},{title:"Wireguard",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"Peers",slug:"peers",link:"#peers",children:[]}]}],path:"/en/config/outbounds/wireguard.html",pathLocale:"/en/",extraFields:[]},{title:"Domain Socket",headers:[{level:2,title:"DomainSocketObject",slug:"domainsocketobject",link:"#domainsocketobject",children:[]}],path:"/en/config/transports/domainsocket.html",pathLocale:"/en/",extraFields:[]},{title:"gRPC",headers:[{level:2,title:"GRPCObject",slug:"grpcobject",link:"#grpcobject",children:[]}],path:"/en/config/transports/grpc.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP/2",headers:[{level:2,title:"HttpObject",slug:"httpobject",link:"#httpobject",children:[]}],path:"/en/config/transports/h2.html",pathLocale:"/en/",extraFields:[]},{title:"HTTPUpgrade",headers:[{level:2,title:"HttpUpgradeObject",slug:"httpupgradeobject",link:"#httpupgradeobject",children:[]}],path:"/en/config/transports/httpupgrade.html",pathLocale:"/en/",extraFields:[]},{title:"mKCP",headers:[{level:2,title:"KcpObject",slug:"kcpobject",link:"#kcpobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",link:"#headerobject",children:[]}]},{level:2,title:"Special Thanks",slug:"special-thanks",link:"#special-thanks",children:[]},{level:2,title:"Improvements to the KCP protocol",slug:"improvements-to-the-kcp-protocol",link:"#improvements-to-the-kcp-protocol",children:[{level:3,title:"smaller protocol header",slug:"smaller-protocol-header",link:"#smaller-protocol-header",children:[]},{level:3,title:"ACK packet retransmission",slug:"ack-packet-retransmission",link:"#ack-packet-retransmission",children:[]},{level:3,title:"Connection state control",slug:"connection-state-control",link:"#connection-state-control",children:[]}]}],path:"/en/config/transports/mkcp.html",pathLocale:"/en/",extraFields:[]},{title:"QUIC",headers:[{level:2,title:"QuicObject",slug:"quicobject",link:"#quicobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",link:"#headerobject",children:[]}]}],path:"/en/config/transports/quic.html",pathLocale:"/en/",extraFields:[]},{title:"TCP",headers:[{level:2,title:"TcpObject",slug:"tcpobject",link:"#tcpobject",children:[{level:3,title:"NoneHeaderObject",slug:"noneheaderobject",link:"#noneheaderobject",children:[]},{level:3,title:"HttpHeaderObject",slug:"httpheaderobject",link:"#httpheaderobject",children:[]}]}],path:"/en/config/transports/tcp.html",pathLocale:"/en/",extraFields:[]},{title:"WebSocket",headers:[{level:2,title:"WebSocketObject",slug:"websocketobject",link:"#websocketobject",children:[]},{level:2,title:"Browser Dialer",slug:"browser-dialer",link:"#browser-dialer",children:[]}],path:"/en/config/transports/websocket.html",pathLocale:"/en/",extraFields:[]},{title:"Compile the document",headers:[{level:2,title:"Preparatory Work",slug:"preparatory-work",link:"#preparatory-work",children:[]},{level:2,title:"Pull Xray source code",slug:"pull-xray-source-code",link:"#pull-xray-source-code",children:[]},{level:2,title:"Build Binary",slug:"build-binary",link:"#build-binary",children:[{level:3,title:"Windows(Powershell):",slug:"windows-powershell",link:"#windows-powershell",children:[]},{level:3,title:"macOS, Linux:",slug:"macos-linux",link:"#macos-linux",children:[]}]},{level:2,title:"Reproducible Build:",slug:"reproducible-build",link:"#reproducible-build",children:[]}],path:"/en/development/intro/compile.html",pathLocale:"/en/",extraFields:[]},{title:"Design Objectives",headers:[{level:2,title:"Architecture",slug:"architecture",link:"#architecture",children:[{level:3,title:"Application Layer",slug:"application-layer",link:"#application-layer",children:[]},{level:3,title:"Proxy Layer",slug:"proxy-layer",link:"#proxy-layer",children:[]},{level:3,title:"Transport Layer",slug:"transport-layer",link:"#transport-layer",children:[]}]}],path:"/en/development/intro/design.html",pathLocale:"/en/",extraFields:[]},{title:"Development Standards",headers:[{level:2,title:"Basic",slug:"basic",link:"#basic",children:[{level:3,title:"Version Control",slug:"version-control",link:"#version-control",children:[]},{level:3,title:"Branch",slug:"branch",link:"#branch",children:[]},{level:3,title:"Release",slug:"release",link:"#release",children:[]},{level:3,title:"Citing other projects",slug:"citing-other-projects",link:"#citing-other-projects",children:[]}]},{level:2,title:"Development Process",slug:"development-process",link:"#development-process",children:[{level:3,title:"Before Writing Code",slug:"before-writing-code",link:"#before-writing-code",children:[]},{level:3,title:"Modify the code",slug:"modify-the-code",link:"#modify-the-code",children:[]},{level:3,title:"Pull Request",slug:"pull-request",link:"#pull-request",children:[]},{level:3,title:"Modifying Code",slug:"modifying-code",link:"#modifying-code",children:[]}]},{level:2,title:"Xray Coding Guidelines",slug:"xray-coding-guidelines",link:"#xray-coding-guidelines",children:[{level:3,title:"Code Structure",slug:"code-structure",link:"#code-structure",children:[]},{level:3,title:"Coding Standards",slug:"coding-standards",link:"#coding-standards",children:[]}]}],path:"/en/development/intro/guide.html",pathLocale:"/en/",extraFields:[]},{title:"mKCP Protocol",headers:[{level:2,title:"Version",slug:"version",link:"#version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",link:"#dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",link:"#underlying-protocol",children:[]},{level:3,title:"Functions",slug:"functions",link:"#functions",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",link:"#communication-process",children:[]},{level:2,title:"Data Format",slug:"data-format",link:"#data-format",children:[{level:3,title:"Data Packet",slug:"data-packet",link:"#data-packet",children:[]},{level:3,title:"Data snippet",slug:"data-snippet",link:"#data-snippet",children:[]},{level:3,title:"Confirmation snippet",slug:"confirmation-snippet",link:"#confirmation-snippet",children:[]},{level:3,title:"Heartbeat Fragments",slug:"heartbeat-fragments",link:"#heartbeat-fragments",children:[]}]}],path:"/en/development/protocols/mkcp.html",pathLocale:"/en/",extraFields:[]},{title:"Mux.Cool Protocol",headers:[{level:2,title:"Version",slug:"version",link:"#version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",link:"#dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",link:"#underlying-protocol",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",link:"#communication-process",children:[{level:3,title:"Client behavior",slug:"client-behavior",link:"#client-behavior",children:[]},{level:3,title:"Server-side behavior",slug:"server-side-behavior",link:"#server-side-behavior",children:[]}]},{level:2,title:"Data Format",slug:"data-format",link:"#data-format",children:[{level:3,title:"Frame Format",slug:"frame-format",link:"#frame-format",children:[]},{level:3,title:"Metadata",slug:"metadata",link:"#metadata",children:[]},{level:3,title:"New Sublink (New)",slug:"new-sublink-new",link:"#new-sublink-new",children:[]},{level:3,title:"Keep sub-connections",slug:"keep-sub-connections",link:"#keep-sub-connections",children:[]},{level:3,title:"End",slug:"end",link:"#end",children:[]},{level:3,title:"KeepAlive",slug:"keepalive",link:"#keepalive",children:[]}]},{level:2,title:"Application",slug:"application",link:"#application",children:[]}],path:"/en/development/protocols/muxcool.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS Protocol",headers:[{level:2,title:"Request & Response",slug:"request-response",link:"#request-response",children:[]},{level:2,title:"ProtoBuf",slug:"protobuf",link:"#protobuf",children:[]},{level:2,title:"Flow",slug:"flow",link:"#flow",children:[{level:3,title:"Flow Control (Formerly Traffic Scheduler)",slug:"flow-control-formerly-traffic-scheduler",link:"#flow-control-formerly-traffic-scheduler",children:[]}]},{level:2,title:"Encryption",slug:"encryption",link:"#encryption",children:[]},{level:2,title:"UDP issues",slug:"udp-issues",link:"#udp-issues",children:[]},{level:2,title:"Client Development Guide",slug:"client-development-guide",link:"#client-development-guide",children:[]},{level:2,title:"VLESS Sharing Link Standard",slug:"vless-sharing-link-standard",link:"#vless-sharing-link-standard",children:[]}],path:"/en/development/protocols/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess Protocol",headers:[{level:2,title:"Version",slug:"version",link:"#version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",link:"#dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",link:"#underlying-protocol",children:[]},{level:3,title:"User ID",slug:"user-id",link:"#user-id",children:[]},{level:3,title:"Functions",slug:"functions",link:"#functions",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",link:"#communication-process",children:[]},{level:2,title:"Client Request",slug:"client-request",link:"#client-request",children:[{level:3,title:"Authentication Information",slug:"authentication-information",link:"#authentication-information",children:[]},{level:3,title:"Command Section",slug:"command-section",link:"#command-section",children:[]},{level:3,title:"Data Section",slug:"data-section",link:"#data-section",children:[]}]},{level:2,title:"Server Response",slug:"server-response",link:"#server-response",children:[{level:3,title:"Dynamic Port Instructions",slug:"dynamic-port-instructions",link:"#dynamic-port-instructions",children:[]}]},{level:2,title:"Comment",slug:"comment",link:"#comment",children:[]}],path:"/en/development/protocols/vmess.html",pathLocale:"/en/",extraFields:[]},{title:"Plain and Simple Language",headers:[],path:"/en/document/level-0/",pathLocale:"/en/",extraFields:[]},{title:"[Chapter 1] Simple and Plain Language",headers:[{level:2,title:"1.1 Who is this document written for?",slug:"_1-1-who-is-this-document-written-for",link:"#_1-1-who-is-this-document-written-for",children:[]},{level:2,title:"1.2 Who is this document not written for?",slug:"_1-2-who-is-this-document-not-written-for",link:"#_1-2-who-is-this-document-not-written-for",children:[]},{level:2,title:"1.3 Declaration and Other Statements",slug:"_1-3-declaration-and-other-statements",link:"#_1-3-declaration-and-other-statements",children:[]},{level:2,title:"1.4 Why is self-hosting a challenge?",slug:"_1-4-why-is-self-hosting-a-challenge",link:"#_1-4-why-is-self-hosting-a-challenge",children:[]},{level:2,title:'1.5 "Why not just use the airport?"',slug:"_1-5-why-not-just-use-the-airport",link:"#_1-5-why-not-just-use-the-airport",children:[]},{level:2,title:"1.6 So should you build your own website?",slug:"_1-6-so-should-you-build-your-own-website",link:"#_1-6-so-should-you-build-your-own-website",children:[]},{level:2,title:"1.7 Some digressions",slug:"_1-7-some-digressions",link:"#_1-7-some-digressions",children:[]},{level:2,title:"1.8 Your Progress",slug:"_1-8-your-progress",link:"#_1-8-your-progress",children:[]}],path:"/en/document/level-0/ch01-preface.html",pathLocale:"/en/",extraFields:[]},{title:"[Chapter 2] Preparation of Raw Materials",headers:[{level:2,title:"2.1 Acquiring a VPS",slug:"_2-1-acquiring-a-vps",link:"#_2-1-acquiring-a-vps",children:[]},{level:2,title:"2.2 Obtaining a Desired Domain Name",slug:"_2-2-obtaining-a-desired-domain-name",link:"#_2-2-obtaining-a-desired-domain-name",children:[]},{level:2,title:"2.3 Software you need to install on your local computer",slug:"_2-3-software-you-need-to-install-on-your-local-computer",link:"#_2-3-software-you-need-to-install-on-your-local-computer",children:[]},{level:2,title:"2.4 Your Progress",slug:"_2-4-your-progress",link:"#_2-4-your-progress",children:[]}],path:"/en/document/level-0/ch02-preparation.html",pathLocale:"/en/",extraFields:[]},{title:"[Chapter 3] Remote Login",headers:[{level:2,title:"3.1 Remote Login to VPS (PuTTY)",slug:"_3-1-remote-login-to-vps-putty",link:"#_3-1-remote-login-to-vps-putty",children:[]},{level:2,title:"3.2 Successfully Logging in SSH! Introduction to Command Line Interface!",slug:"_3-2-successfully-logging-in-ssh-introduction-to-command-line-interface",link:"#_3-2-successfully-logging-in-ssh-introduction-to-command-line-interface",children:[]},{level:2,title:"3.3 Updating software on Linux for the first time!",slug:"_3-3-updating-software-on-linux-for-the-first-time",link:"#_3-3-updating-software-on-linux-for-the-first-time",children:[]},{level:2,title:"3.4 Your Progress",slug:"_3-4-your-progress",link:"#_3-4-your-progress",children:[]}],path:"/en/document/level-0/ch03-ssh.html",pathLocale:"/en/",extraFields:[]},{title:"[Chapter 4] Security and Protection",headers:[{level:2,title:"4.1 Why Do We Need Security Protection?",slug:"_4-1-why-do-we-need-security-protection",link:"#_4-1-why-do-we-need-security-protection",children:[]},{level:2,title:"4.2 What are the specific risks",slug:"_4-2-what-are-the-specific-risks",link:"#_4-2-what-are-the-specific-risks",children:[]},{level:2,title:"4.3 What security measures do we need to take",slug:"_4-3-what-security-measures-do-we-need-to-take",link:"#_4-3-what-security-measures-do-we-need-to-take",children:[]},{level:2,title:"4.4 Change the SSH Remote Login Port to a Non-22 Port",slug:"_4-4-change-the-ssh-remote-login-port-to-a-non-22-port",link:"#_4-4-change-the-ssh-remote-login-port-to-a-non-22-port",children:[]},{level:2,title:"4.5 Creating a New User Without Root Access",slug:"_4-5-creating-a-new-user-without-root-access",link:"#_4-5-creating-a-new-user-without-root-access",children:[]},{level:2,title:"4.8 Your Progress",slug:"_4-8-your-progress",link:"#_4-8-your-progress",children:[]}],path:"/en/document/level-0/ch04-security.html",pathLocale:"/en/",extraFields:[]},{title:"Chapter 5: Website Building",headers:[{level:2,title:"5.1 Why should you create a website?",slug:"_5-1-why-should-you-create-a-website",link:"#_5-1-why-should-you-create-a-website",children:[]},{level:2,title:"5.2 Log in to VPS, install and run Nginx",slug:"_5-2-log-in-to-vps-install-and-run-nginx",link:"#_5-2-log-in-to-vps-install-and-run-nginx",children:[]},{level:2,title:"5.3 Create the simplest web page",slug:"_5-3-create-the-simplest-web-page",link:"#_5-3-create-the-simplest-web-page",children:[]},{level:2,title:"5.4 Common error explanations",slug:"_5-4-common-error-explanations",link:"#_5-4-common-error-explanations",children:[]}],path:"/en/document/level-0/ch05-webpage.html",pathLocale:"/en/",extraFields:[]},{title:"[Chapter 6] Certificate Management",headers:[{level:2,title:"6.1 Applying for a TLS Certificate",slug:"_6-1-applying-for-a-tls-certificate",link:"#_6-1-applying-for-a-tls-certificate",children:[]},{level:2,title:"6.2 Install acme.sh",slug:"_6-2-install-acme-sh",link:"#_6-2-install-acme-sh",children:[]},{level:2,title:"6.3 Testing Certificate Application",slug:"_6-3-testing-certificate-application",link:"#_6-3-testing-certificate-application",children:[]},{level:2,title:"6.5 Certificate Installation",slug:"_6-5-certificate-installation",link:"#_6-5-certificate-installation",children:[]},{level:2,title:"6.6 Your Progress",slug:"_6-6-your-progress",link:"#_6-6-your-progress",children:[]}],path:"/en/document/level-0/ch06-certificates.html",pathLocale:"/en/",extraFields:[]},{title:"【第 7 章】Xray 服务器篇",headers:[{level:2,title:"7.1 博观而约取,厚积而薄发",slug:"_7-1-博观而约取-厚积而薄发",link:"#_7-1-博观而约取-厚积而薄发",children:[]},{level:2,title:"7.2 安装 Xray",slug:"_7-2-安装-xray",link:"#_7-2-安装-xray",children:[]},{level:2,title:"7.3 给 Xray 配置 TLS 证书",slug:"_7-3-给-xray-配置-tls-证书",link:"#_7-3-给-xray-配置-tls-证书",children:[]},{level:2,title:"7.4 配置 Xray",slug:"_7-4-配置-xray",link:"#_7-4-配置-xray",children:[]},{level:2,title:"7.5 启动 Xray 服务!!(并查看服务状态)",slug:"_7-5-启动-xray-服务-并查看服务状态",link:"#_7-5-启动-xray-服务-并查看服务状态",children:[]},{level:2,title:"7.6 回顾 systemd 进行基本的服务管理",slug:"_7-6-回顾-systemd-进行基本的服务管理",link:"#_7-6-回顾-systemd-进行基本的服务管理",children:[]},{level:2,title:"7.7 服务器优化之一:开启 BBR",slug:"_7-7-服务器优化之一-开启-bbr",link:"#_7-7-服务器优化之一-开启-bbr",children:[]},{level:2,title:"7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS",slug:"_7-8-服务器优化之二-开启-http-自动跳转-https",link:"#_7-8-服务器优化之二-开启-http-自动跳转-https",children:[]},{level:2,title:"7.9 服务器优化之三:更丰富的回落",slug:"_7-9-服务器优化之三-更丰富的回落",link:"#_7-9-服务器优化之三-更丰富的回落",children:[]},{level:2,title:"7.10 你的进度",slug:"_7-10-你的进度",link:"#_7-10-你的进度",children:[]},{level:2,title:"7.11 重要勘误",slug:"_7-11-重要勘误",link:"#_7-11-重要勘误",children:[]}],path:"/en/document/level-0/ch07-xray-server.html",pathLocale:"/en/",extraFields:[]},{title:"【第 8 章】Xray 客户端篇",headers:[{level:2,title:"8.1 Xray 的工作原理简述",slug:"_8-1-xray-的工作原理简述",link:"#_8-1-xray-的工作原理简述",children:[]},{level:2,title:"8.2 客户端与服务器端正确连接",slug:"_8-2-客户端与服务器端正确连接",link:"#_8-2-客户端与服务器端正确连接",children:[]},{level:2,title:"8.3 附加题 1:在 PC 端手工配置 xray-core",slug:"_8-3-附加题-1-在-pc-端手工配置-xray-core",link:"#_8-3-附加题-1-在-pc-端手工配置-xray-core",children:[]},{level:2,title:"8.4 附加题 2:在 PC 端手工运行 xray-core",slug:"_8-4-附加题-2-在-pc-端手工运行-xray-core",link:"#_8-4-附加题-2-在-pc-端手工运行-xray-core",children:[]},{level:2,title:"8.5 附加题 3:在 PC 端开机自动运行 xray-core",slug:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",link:"#_8-5-附加题-3-在-pc-端开机自动运行-xray-core",children:[]},{level:2,title:"8.6 圆满完成!",slug:"_8-6-圆满完成",link:"#_8-6-圆满完成",children:[]},{level:2,title:"8.7 TO INFINITY AND BEYOND!",slug:"_8-7-to-infinity-and-beyond",link:"#_8-7-to-infinity-and-beyond",children:[]}],path:"/en/document/level-0/ch08-xray-clients.html",pathLocale:"/en/",extraFields:[]},{title:"【第 9 章】附录",headers:[{level:2,title:"1. 小小白白 Linux 基础命令索引",slug:"_1-小小白白-linux-基础命令索引",link:"#_1-小小白白-linux-基础命令索引",children:[]},{level:2,title:"2. 小小白白 Linux 重要配置文件索引",slug:"_2-小小白白-linux-重要配置文件索引",link:"#_2-小小白白-linux-重要配置文件索引",children:[]},{level:2,title:"3. 小小白白 Xray 重要文件索引",slug:"_3-小小白白-xray-重要文件索引",link:"#_3-小小白白-xray-重要文件索引",children:[]}],path:"/en/document/level-0/ch09-appendix.html",pathLocale:"/en/",extraFields:[]},{title:"Beginner's Tips",headers:[],path:"/en/document/level-1/",pathLocale:"/en/",extraFields:[]},{title:"回落 (fallbacks) 功能简析",headers:[{level:2,title:"1. 回顾《小小白白话文》中的回落",slug:"_1-回顾《小小白白话文》中的回落",link:"#_1-回顾《小小白白话文》中的回落",children:[]},{level:2,title:"2. 重新认识回落 (WHAT, HOW v1)",slug:"_2-重新认识回落-what-how-v1",link:"#_2-重新认识回落-what-how-v1",children:[]},{level:2,title:"3. 为什么要回落 (WHY v1)",slug:"_3-为什么要回落-why-v1",link:"#_3-为什么要回落-why-v1",children:[]},{level:2,title:"4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)",slug:"_4-重新认识【回落の完全体】-what-why-how-v2",link:"#_4-重新认识【回落の完全体】-what-why-how-v2",children:[]},{level:2,title:"5. 多层回落示例及解读",slug:"_5-多层回落示例及解读",link:"#_5-多层回落示例及解读",children:[{level:3,title:"5.1 首先,我将服务器端配置的 443 监听段摘抄如下:",slug:"_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",link:"#_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",children:[]},{level:3,title:"5.2 后续监听处理的配置段摘抄如下:",slug:"_5-2-后续监听处理的配置段摘抄如下",link:"#_5-2-后续监听处理的配置段摘抄如下",children:[]}]},{level:2,title:"6. 结语",slug:"_6-结语",link:"#_6-结语",children:[]},{level:2,title:"7. 附加题",slug:"_7-附加题",link:"#_7-附加题",children:[]}],path:"/en/document/level-1/fallbacks-lv1.html",pathLocale:"/en/",extraFields:[]},{title:"SNI fallback",headers:[{level:2,title:"Application Scenarios",slug:"application-scenarios",link:"#application-scenarios",children:[]},{level:2,title:"Introduction to SNI",slug:"introduction-to-sni",link:"#introduction-to-sni",children:[]},{level:2,title:"Idea",slug:"idea",link:"#idea",children:[]},{level:2,title:"Adding DNS Records",slug:"adding-dns-records",link:"#adding-dns-records",children:[]},{level:2,title:"Applying for TLS Certificate",slug:"applying-for-tls-certificate",link:"#applying-for-tls-certificate",children:[]},{level:2,title:"Xray Configuration",slug:"xray-configuration",link:"#xray-configuration",children:[]},{level:2,title:"Nginx Configuration",slug:"nginx-configuration",link:"#nginx-configuration",children:[]},{level:2,title:"Caddy Configuration",slug:"caddy-configuration",link:"#caddy-configuration",children:[]},{level:2,title:"Reference",slug:"reference",link:"#reference",children:[]},{level:2,title:"Quotation",slug:"quotation",link:"#quotation",children:[]}],path:"/en/document/level-1/fallbacks-with-sni.html",pathLocale:"/en/",extraFields:[]},{title:"路由 (routing) 功能简析(上)",headers:[{level:2,title:"1. 初识【路由】三兄弟",slug:"_1-初识【路由】三兄弟",link:"#_1-初识【路由】三兄弟",children:[]},{level:2,title:"2. 基本功: “兄弟一条心”",slug:"_2-基本功-兄弟一条心",link:"#_2-基本功-兄弟一条心",children:[{level:3,title:"2.1 入站",slug:"_2-1-入站",link:"#_2-1-入站",children:[]},{level:3,title:"2.3 路由",slug:"_2-3-路由",link:"#_2-3-路由",children:[]},{level:3,title:"2.4 路由配置项解析之一:流量筛选的依据",slug:"_2-4-路由配置项解析之一-流量筛选的依据",link:"#_2-4-路由配置项解析之一-流量筛选的依据",children:[]}]},{level:2,title:"3. 小试牛刀: “三分天下” 之 “域名分流”",slug:"_3-小试牛刀-三分天下-之-域名分流",link:"#_3-小试牛刀-三分天下-之-域名分流",children:[{level:3,title:"3.1 入站",slug:"_3-1-入站",link:"#_3-1-入站",children:[]},{level:3,title:"3.2 出站",slug:"_3-2-出站",link:"#_3-2-出站",children:[]},{level:3,title:"3.3 路由",slug:"_3-3-路由",link:"#_3-3-路由",children:[]},{level:3,title:"3.4 简析域名文件: geosite.dat",slug:"_3-4-简析域名文件-geosite-dat",link:"#_3-4-简析域名文件-geosite-dat",children:[]},{level:3,title:"3.5 所以 geosite.dat 到底是什么?不是有个 GFWList 吗?",slug:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",link:"#_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",children:[]},{level:3,title:"3.6 军师锦囊藏奇兵:一条隐藏的路由规则",slug:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",link:"#_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",children:[]},{level:3,title:"3.7 再看“三分天下”的大地图",slug:"_3-7-再看-三分天下-的大地图",link:"#_3-7-再看-三分天下-的大地图",children:[]}]},{level:2,title:"4. “三分天下” 之 “蜀魏争雄”",slug:"_4-三分天下-之-蜀魏争雄",link:"#_4-三分天下-之-蜀魏争雄",children:[]},{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",link:"#_5-攻城略池-多种路由匹配条件",children:[]}],path:"/en/document/level-1/routing-lv1-part1.html",pathLocale:"/en/",extraFields:[]},{title:"路由 (routing) 功能简析(下)",headers:[{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",link:"#_5-攻城略池-多种路由匹配条件",children:[{level:3,title:"5.1 基于指定域名分流:[domain], [full] 等",slug:"_5-1-基于指定域名分流-domain-full-等",link:"#_5-1-基于指定域名分流-domain-full-等",children:[]},{level:3,title:"5.2 基于 IP 文件分流:geoip.dat",slug:"_5-2-基于-ip-文件分流-geoip-dat",link:"#_5-2-基于-ip-文件分流-geoip-dat",children:[]},{level:3,title:"5.3 基于指定 IP 地址分流",slug:"_5-3-基于指定-ip-地址分流",link:"#_5-3-基于指定-ip-地址分流",children:[]},{level:3,title:"5.4 基于协议类型分流:[protocol] 等",slug:"_5-4-基于协议类型分流-protocol-等",link:"#_5-4-基于协议类型分流-protocol-等",children:[]},{level:3,title:"5.5 基于更多条件的分流",slug:"_5-5-基于更多条件的分流",link:"#_5-5-基于更多条件的分流",children:[]}]},{level:2,title:"6. “霸业初定”:路由规则整体回顾",slug:"_6-霸业初定-路由规则整体回顾",link:"#_6-霸业初定-路由规则整体回顾",children:[]},{level:2,title:"7. 路由配置常见错误",slug:"_7-路由配置常见错误",link:"#_7-路由配置常见错误",children:[{level:3,title:"7.1 错误示范",slug:"_7-1-错误示范",link:"#_7-1-错误示范",children:[]},{level:3,title:"7.2 正确示范",slug:"_7-2-正确示范",link:"#_7-2-正确示范",children:[]}]},{level:2,title:"8. 明修栈道、暗渡陈仓",slug:"_8-明修栈道、暗渡陈仓",link:"#_8-明修栈道、暗渡陈仓",children:[{level:3,title:'8.1 域名策略: "AsIs"',slug:"_8-1-域名策略-asis",link:"#_8-1-域名策略-asis",children:[]},{level:3,title:'8.2 域名策略: "IPIfNonMatch"',slug:"_8-2-域名策略-ipifnonmatch",link:"#_8-2-域名策略-ipifnonmatch",children:[]},{level:3,title:'8.3 域名策略: "IPOnDemand"',slug:"_8-3-域名策略-ipondemand",link:"#_8-3-域名策略-ipondemand",children:[]}]},{level:2,title:"9. 思考题",slug:"_9-思考题",link:"#_9-思考题",children:[]},{level:2,title:"10. 结语",slug:"_10-结语",link:"#_10-结语",children:[]},{level:2,title:"11. 尾注",slug:"_11-尾注",link:"#_11-尾注",children:[]}],path:"/en/document/level-1/routing-lv1-part2.html",pathLocale:"/en/",extraFields:[]},{title:"Xray 的工作模式",headers:[{level:2,title:"单服务器模式",slug:"单服务器模式",link:"#单服务器模式",children:[]},{level:2,title:"桥接模式",slug:"桥接模式",link:"#桥接模式",children:[]},{level:2,title:"工作原理",slug:"工作原理",link:"#工作原理",children:[]}],path:"/en/document/level-1/work.html",pathLocale:"/en/",extraFields:[]},{title:"Advanced Documentation",headers:[],path:"/en/document/level-2/",pathLocale:"/en/",extraFields:[]},{title:"Transparent proxy via GID",headers:[{level:2,title:"Ideas",slug:"ideas",link:"#ideas",children:[]},{level:2,title:"Configuration Procedure",slug:"configuration-procedure",link:"#configuration-procedure",children:[{level:3,title:"1. Preliminary preparation",slug:"_1-preliminary-preparation",link:"#_1-preliminary-preparation",children:[]},{level:3,title:"2. Add user (Android users please ignore this section)",slug:"_2-add-user-android-users-please-ignore-this-section",link:"#_2-add-user-android-users-please-ignore-this-section",children:[]},{level:3,title:"3. Configure and run Xray, and configure iptables rules",slug:"_3-configure-and-run-xray-and-configure-iptables-rules",link:"#_3-configure-and-run-xray-and-configure-iptables-rules",children:[]}]},{level:2,title:"Steps",slug:"steps",link:"#steps",children:[{level:3,title:"1. Finish Preliminary preparation and Add user",slug:"_1-finish-preliminary-preparation-and-add-user",link:"#_1-finish-preliminary-preparation-and-add-user",children:[]},{level:3,title:"2. Preparing Xray profiles",slug:"_2-preparing-xray-profiles",link:"#_2-preparing-xray-profiles",children:[]},{level:3,title:"3. Configuring the maximum number of open files and run the Xray client",slug:"_3-configuring-the-maximum-number-of-open-files-and-run-the-xray-client",link:"#_3-configuring-the-maximum-number-of-open-files-and-run-the-xray-client",children:[]},{level:3,title:"4. Setting up iptables rules",slug:"_4-setting-up-iptables-rules",link:"#_4-setting-up-iptables-rules",children:[]}]}],path:"/en/document/level-2/iptables_gid.html",pathLocale:"/en/",extraFields:[]},{title:"Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹",headers:[{level:2,title:"编译 nginx --with-stream",slug:"编译-nginx-with-stream",link:"#编译-nginx-with-stream",children:[]},{level:2,title:"配置 nginx",slug:"配置-nginx",link:"#配置-nginx",children:[]},{level:2,title:"xray 配置",slug:"xray-配置",link:"#xray-配置",children:[]},{level:2,title:"客户端及服务端启动服务",slug:"客户端及服务端启动服务",link:"#客户端及服务端启动服务",children:[]},{level:2,title:"结束",slug:"结束",link:"#结束",children:[]},{level:2,title:"HTTPS 隧道",slug:"https-隧道",link:"#https-隧道",children:[{level:3,title:"haproxy_client 配置 (运行前去掉注释)",slug:"haproxy-client-配置-运行前去掉注释",link:"#haproxy-client-配置-运行前去掉注释",children:[]},{level:3,title:"haproxy_server 配置 (运行前去掉注释)",slug:"haproxy-server-配置-运行前去掉注释",link:"#haproxy-server-配置-运行前去掉注释",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-1",link:"#xray-配置-1",children:[]}]},{level:2,title:"WebSocket over HTTP/2",slug:"websocket-over-http-2",link:"#websocket-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置",link:"#haproxy-client-配置",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置",link:"#haproxy-server-配置",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-2",link:"#xray-配置-2",children:[]}]},{level:2,title:"gRPC over HTTP/2",slug:"grpc-over-http-2",link:"#grpc-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-1",link:"#haproxy-client-配置-1",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-1",link:"#haproxy-server-配置-1",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-3",link:"#xray-配置-3",children:[]},{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-2",link:"#haproxy-client-配置-2",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-2",link:"#haproxy-server-配置-2",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-4",link:"#xray-配置-4",children:[]}]}],path:"/en/document/level-2/nginx_or_haproxy_tls_tunnel.html",pathLocale:"/en/",extraFields:[]},{title:"出站流量重定向",headers:[{level:2,title:"前言",slug:"前言",link:"#前言",children:[]},{level:2,title:"1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)",slug:"_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",link:"#_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",children:[]},{level:2,title:"2、编辑 VPN 配置文件(以 WireGuard 为例)",slug:"_2、编辑-vpn-配置文件-以-wireguard-为例",link:"#_2、编辑-vpn-配置文件-以-wireguard-为例",children:[]},{level:2,title:"3、启用 WireGuard 网络接口",slug:"_3、启用-wireguard-网络接口",link:"#_3、启用-wireguard-网络接口",children:[]},{level:2,title:"4、Xray-core 配置文件修改",slug:"_4、xray-core-配置文件修改",link:"#_4、xray-core-配置文件修改",children:[]},{level:2,title:"5、系统设置配置",slug:"_5、系统设置配置",link:"#_5、系统设置配置",children:[]},{level:2,title:"6、完成 WireGuard 相关设置",slug:"_6、完成-wireguard-相关设置",link:"#_6、完成-wireguard-相关设置",children:[]},{level:2,title:"后记",slug:"后记",link:"#后记",children:[]},{level:2,title:"感谢",slug:"感谢",link:"#感谢",children:[]}],path:"/en/document/level-2/redirect.html",pathLocale:"/en/",extraFields:[]},{title:"TProxy 透明代理",headers:[{level:2,title:"开始之前",slug:"开始之前",link:"#开始之前",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",link:"#xray-配置",children:[]},{level:2,title:"策略路由配置",slug:"策略路由配置",link:"#策略路由配置",children:[]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",link:"#netfilter-配置",children:[]},{level:2,title:"配置永久化与开机自启",slug:"配置永久化与开机自启",link:"#配置永久化与开机自启",children:[]}],path:"/en/document/level-2/tproxy.html",pathLocale:"/en/",extraFields:[]},{title:"TProxy 透明代理 (ipv4 and ipv6)",headers:[{level:2,title:"Xray 配置",slug:"xray-配置",link:"#xray-配置",children:[{level:3,title:"客户端配置",slug:"客户端配置",link:"#客户端配置",children:[]},{level:3,title:"服务端配置",slug:"服务端配置",link:"#服务端配置",children:[]}]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",link:"#netfilter-配置",children:[{level:3,title:"首先设置策略路由",slug:"首先设置策略路由",link:"#首先设置策略路由",children:[]},{level:3,title:"使用 iptables",slug:"使用-iptables",link:"#使用-iptables",children:[]},{level:3,title:"使用 nftables",slug:"使用-nftables",link:"#使用-nftables",children:[]},{level:3,title:"开机自动运行 Netfilter 配置",slug:"开机自动运行-netfilter-配置",link:"#开机自动运行-netfilter-配置",children:[]}]},{level:2,title:"局域网设备上网设置",slug:"局域网设备上网设置",link:"#局域网设备上网设置",children:[{level:3,title:"方法一",slug:"方法一",link:"#方法一",children:[]},{level:3,title:"方法二",slug:"方法二",link:"#方法二",children:[]}]},{level:2,title:"Finally",slug:"finally",link:"#finally",children:[]},{level:2,title:"写在最后",slug:"写在最后",link:"#写在最后",children:[]}],path:"/en/document/level-2/tproxy_ipv4_and_ipv6.html",pathLocale:"/en/",extraFields:[]},{title:"流量统计",headers:[{level:2,title:"查看流量信息",slug:"查看流量信息",link:"#查看流量信息",children:[]},{level:2,title:"流量信息的处理",slug:"流量信息的处理",link:"#流量信息的处理",children:[]}],path:"/en/document/level-2/traffic_stats.html",pathLocale:"/en/",extraFields:[]},{title:"Enhancing Proxy Security with Cloudflare Warp",headers:[{level:2,title:"Applying for a Warp Account",slug:"applying-for-a-warp-account",link:"#applying-for-a-warp-account",children:[]},{level:2,title:"Diverting inbound traffic to warp on the server side",slug:"diverting-inbound-traffic-to-warp-on-the-server-side",link:"#diverting-inbound-traffic-to-warp-on-the-server-side",children:[]},{level:2,title:"Using Warp Chain Proxy on the Client Side",slug:"using-warp-chain-proxy-on-the-client-side",link:"#using-warp-chain-proxy-on-the-client-side",children:[]}],path:"/en/document/level-2/warp.html",pathLocale:"/en/",extraFields:[]},{title:"透明代理入门",headers:[{level:2,title:"什么是透明代理",slug:"什么是透明代理",link:"#什么是透明代理",children:[]},{level:2,title:"透明代理的实现",slug:"透明代理的实现",link:"#透明代理的实现",children:[{level:3,title:"tun2socks",slug:"tun2socks",link:"#tun2socks",children:[]},{level:3,title:"iptables/nftables",slug:"iptables-nftables",link:"#iptables-nftables",children:[]}]},{level:2,title:"iptables 实现透明代理原理",slug:"iptables-实现透明代理原理",link:"#iptables-实现透明代理原理",children:[]},{level:2,title:"透明代理难在哪里",slug:"透明代理难在哪里",link:"#透明代理难在哪里",children:[]},{level:2,title:"从零开始一步步实现基于 iptables-tproxy 的透明代理",slug:"从零开始一步步实现基于-iptables-tproxy-的透明代理",link:"#从零开始一步步实现基于-iptables-tproxy-的透明代理",children:[{level:3,title:"在开始之前,你需要有一定的基础知识:",slug:"在开始之前-你需要有一定的基础知识",link:"#在开始之前-你需要有一定的基础知识",children:[]},{level:3,title:"前期准备工作",slug:"前期准备工作",link:"#前期准备工作",children:[]},{level:3,title:"首先,我们先试试做到第一阶段",slug:"首先-我们先试试做到第一阶段",link:"#首先-我们先试试做到第一阶段",children:[]},{level:3,title:"第二阶段",slug:"第二阶段",link:"#第二阶段",children:[]},{level:3,title:"第三阶段",slug:"第三阶段",link:"#第三阶段",children:[]},{level:3,title:"第四阶段",slug:"第四阶段",link:"#第四阶段",children:[]},{level:3,title:"代理 ipv6",slug:"代理-ipv6",link:"#代理-ipv6",children:[]}]}],path:"/en/document/level-2/transparent_proxy/transparent_proxy.html",pathLocale:"/en/",extraFields:[]},{title:"",headers:[],path:"/404.html",pathLocale:"/",extraFields:[]}],up=ge(cp),dp=()=>up,hp=({searchIndex:e,routeLocale:t,query:l,maxSuggestions:n})=>{const i=H(()=>e.value.filter(r=>r.pathLocale===t.value));return H(()=>{const r=l.value.trim().toLowerCase();if(!r)return[];const o=[],s=(a,c)=>{uo(r,[c.title])&&o.push({link:`${a.path}#${c.slug}`,title:a.title,header:c.title});for(const d of c.children){if(o.length>=n.value)return;s(a,d)}};for(const a of i.value){if(o.length>=n.value)break;if(uo(r,[a.title,...a.extraFields])){o.push({link:a.path,title:a.title});continue}for(const c of a.headers){if(o.length>=n.value)break;s(a,c)}}return o})},fp=e=>{const t=ge(0);return{focusIndex:t,focusNext:()=>{t.value{t.value>0?t.value-=1:t.value=e.value.length-1}}},vp=pe({name:"SearchBox",props:{locales:{type:Object,required:!1,default:()=>({})},hotKeys:{type:Array,required:!1,default:()=>[]},maxSuggestions:{type:Number,required:!1,default:5}},setup(e){const{locales:t,hotKeys:l,maxSuggestions:n}=In(e),i=yt(),r=Gl(),o=dp(),s=ge(null),a=ge(!1),c=ge(""),d=H(()=>t.value[r.value]??{}),h=hp({searchIndex:o,routeLocale:r,query:c,maxSuggestions:n}),{focusIndex:f,focusNext:m,focusPrev:k}=fp(h);ap({input:s,hotKeys:l});const T=H(()=>a.value&&!!h.value.length),w=()=>{T.value&&k()},I=()=>{T.value&&m()},R=b=>{if(!T.value)return;const E=h.value[b];E&&i.push(E.link).then(()=>{c.value="",f.value=0})};return()=>fe("form",{class:"search-box",role:"search"},[fe("input",{ref:s,type:"search",placeholder:d.value.placeholder,autocomplete:"off",spellcheck:!1,value:c.value,onFocus:()=>a.value=!0,onBlur:()=>a.value=!1,onInput:b=>c.value=b.target.value,onKeydown:b=>{switch(b.key){case"ArrowUp":{w();break}case"ArrowDown":{I();break}case"Enter":{b.preventDefault(),R(f.value);break}}}}),T.value&&fe("ul",{class:"suggestions",onMouseleave:()=>f.value=-1},h.value.map(({link:b,title:E,header:F},G)=>fe("li",{class:["suggestion",{focus:f.value===G}],onMouseenter:()=>f.value=G,onMousedown:()=>R(G)},fe("a",{href:b,onClick:N=>N.preventDefault()},[fe("span",{class:"page-title"},E),F&&fe("span",{class:"page-header"},`> ${F}`)]))))])}});var pp=["s","/"],mp={"/":{placeholder:"搜索"}};const gp=mp,_p=pp,bp=5,kp=Nt({enhance({app:e}){e.component("SearchBox",t=>fe(vp,{locales:gp,hotKeys:_p,maxSuggestions:bp,...t}))}}),yp={enhance:({app:e})=>{e.component("Mermaid",g(()=>u(()=>import("./Mermaid-AwfEy8fz.js"),__vite__mapDeps([])))),e.component("Tab",g(()=>u(()=>import("./Tab-zEFzyfPv.js"),__vite__mapDeps([])))),e.component("Tabs",g(()=>u(()=>import("./Tabs-coEt0t4G.js"),__vite__mapDeps([]))))}},un=[Zd,lh,sh,bh,xh,Oh,np,kp,yp],Ep=[["v-8daa1a0e","/",{title:""},["/README.md"]],["v-aad48c6a","/about/news.html",{title:"大史记"},[":md"]],["v-f7496066","/development/",{title:"开发指南"},["/development/README.md"]],["v-ba934fd8","/config/",{title:"配置文件"},["/config/README.md"]],["v-41ade9da","/config/api.html",{title:"API 接口"},[":md"]],["v-83dedd38","/config/dns.html",{title:"内置 DNS 服务器"},[":md"]],["v-192a19b9","/config/fakedns.html",{title:"FakeDNS"},[":md"]],["v-7f6279d8","/config/inbound.html",{title:"入站代理"},[":md"]],["v-1d860c29","/config/log.html",{title:"日志配置"},[":md"]],["v-fbaf47ec","/config/metrics.html",{title:"Metrics"},[":md"]],["v-2367d756","/config/outbound.html",{title:"出站代理"},[":md"]],["v-4ebec35a","/config/policy.html",{title:"本地策略"},[":md"]],["v-31b7756a","/config/reverse.html",{title:"反向代理"},[":md"]],["v-70677432","/config/routing.html",{title:"路由"},[":md"]],["v-7e21d6ae","/config/stats.html",{title:"统计信息"},[":md"]],["v-e3dfff38","/config/transport.html",{title:"传输方式"},[":md"]],["v-36b1a79b","/document/",{title:"快速入门"},["/document/README.md"]],["v-09a64f89","/document/command.html",{title:"命令参数"},[":md"]],["v-2b1adf48","/document/config.html",{title:"配置运行"},[":md"]],["v-86ee963a","/document/document.html",{title:"为 Project X 的文档贡献"},[":md"]],["v-0e5d7b39","/document/install.html",{title:"下载安装"},[":md"]],["v-2d0a870d","/en/",{title:""},["/en/README.md"]],["v-6a9e8054","/development/intro/compile.html",{title:"编译文档"},[":md"]],["v-95e3eaea","/development/intro/design.html",{title:"设计目标"},[":md"]],["v-61e7eea6","/development/intro/guide.html",{title:"开发规范"},[":md"]],["v-6e6c37e6","/development/protocols/mkcp.html",{title:"mKCP 协议"},[":md"]],["v-13168a21","/development/protocols/muxcool.html",{title:"Mux.Cool 协议"},[":md"]],["v-5c48c82b","/development/protocols/vless.html",{title:"VLESS 协议"},[":md"]],["v-1ee591a8","/development/protocols/vmess.html",{title:"VMess 协议"},[":md"]],["v-0d714d87","/config/features/browser_dialer.html",{title:"Browser Dialer"},[":md"]],["v-0da7880a","/config/features/env.html",{title:"环境变量"},[":md"]],["v-2aeb21f9","/config/features/fallback.html",{title:"Fallback 回落"},[":md"]],["v-3acf20ea","/config/features/multiple.html",{title:"多文件配置"},[":md"]],["v-792e28f8","/config/features/xtls.html",{title:"XTLS 深度剖析"},[":md"]],["v-b50d2334","/config/inbounds/dokodemo.html",{title:"Dokodemo-Door"},[":md"]],["v-593408b0","/config/inbounds/http.html",{title:"HTTP"},[":md"]],["v-802a842a","/config/inbounds/shadowsocks.html",{title:"Shadowsocks"},[":md"]],["v-29995cea","/config/inbounds/socks.html",{title:"Socks"},[":md"]],["v-2a1b3d72","/config/inbounds/trojan.html",{title:"Trojan"},[":md"]],["v-fb92e8aa","/config/inbounds/vless.html",{title:"VLESS"},[":md"]],["v-167afaac","/config/inbounds/vmess.html",{title:"VMess"},[":md"]],["v-749ad71a","/config/outbounds/blackhole.html",{title:"Blackhole"},[":md"]],["v-6d39b970","/config/outbounds/dns.html",{title:"DNS"},[":md"]],["v-d76e893a","/config/outbounds/freedom.html",{title:"Freedom"},[":md"]],["v-c6b4b59e","/config/outbounds/http.html",{title:"HTTP"},[":md"]],["v-41ec0e0e","/config/outbounds/loopback.html",{title:"Loopback"},[":md"]],["v-7b293e4a","/config/outbounds/shadowsocks.html",{title:"Shadowsocks"},[":md"]],["v-15f5452a","/config/outbounds/socks.html",{title:"Socks"},[":md"]],["v-5797bdb3","/config/outbounds/trojan.html",{title:"Trojan"},[":md"]],["v-a60f016c","/config/outbounds/vless.html",{title:"VLESS"},[":md"]],["v-413cee4b","/config/outbounds/vmess.html",{title:"VMess"},[":md"]],["v-208ca3b9","/config/outbounds/wireguard.html",{title:"Wireguard"},[":md"]],["v-775db7b1","/config/transports/domainsocket.html",{title:"Domain Socket"},[":md"]],["v-2877542a","/config/transports/grpc.html",{title:"gRPC"},[":md"]],["v-03a28284","/config/transports/h2.html",{title:"HTTP/2"},[":md"]],["v-04158536","/config/transports/httpupgrade.html",{title:"HTTPUpgrade"},[":md"]],["v-3167b1dd","/config/transports/mkcp.html",{title:"mKCP"},[":md"]],["v-8f08dbec","/config/transports/quic.html",{title:"QUIC"},[":md"]],["v-33b1b709","/config/transports/tcp.html",{title:"TCP"},[":md"]],["v-1ff57bba","/config/transports/websocket.html",{title:"WebSocket"},[":md"]],["v-3f09dcfa","/document/level-0/",{title:"小小白白话文"},["/document/level-0/README.md"]],["v-fb444906","/document/level-0/ch01-preface.html",{title:"【第 1 章】 小小白白话文"},[":md"]],["v-075f3ae5","/document/level-0/ch02-preparation.html",{title:"【第 2 章】原料准备篇"},[":md"]],["v-726d0633","/document/level-0/ch03-ssh.html",{title:"【第 3 章】远程登录篇"},[":md"]],["v-430c6ab8","/document/level-0/ch04-security.html",{title:"【第 4 章】安全防护篇"},[":md"]],["v-717c6376","/document/level-0/ch05-webpage.html",{title:"【第 5 章】网站建设篇"},[":md"]],["v-278039be","/document/level-0/ch06-certificates.html",{title:"【第 6 章】证书管理篇"},[":md"]],["v-a0c7f88e","/document/level-0/ch07-xray-server.html",{title:"【第 7 章】Xray 服务器篇"},[":md"]],["v-86586ca2","/document/level-0/ch08-xray-clients.html",{title:"【第 8 章】Xray 客户端篇"},[":md"]],["v-3eb62514","/document/level-0/ch09-appendix.html",{title:"【第 9 章】附录"},[":md"]],["v-3f09dcbc","/document/level-1/",{title:"入门技巧"},["/document/level-1/README.md"]],["v-b21a2a20","/document/level-1/fallbacks-lv1.html",{title:"回落 (fallbacks) 功能简析"},[":md"]],["v-da623318","/document/level-1/fallbacks-with-sni.html",{title:"SNI 回落"},[":md"]],["v-fdd722ac","/document/level-1/routing-lv1-part1.html",{title:"路由 (routing) 功能简析(上)"},[":md"]],["v-fa6d716e","/document/level-1/routing-lv1-part2.html",{title:"路由 (routing) 功能简析(下)"},[":md"]],["v-2f29e106","/document/level-1/work.html",{title:"Xray 的工作模式"},[":md"]],["v-3f09dc7e","/document/level-2/",{title:"进阶文档"},["/document/level-2/README.md"]],["v-1c17916e","/document/level-2/iptables_gid.html",{title:"GID 透明代理"},[":md"]],["v-a001cfa6","/document/level-2/nginx_or_haproxy_tls_tunnel.html",{title:"Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹"},[":md"]],["v-46333b48","/document/level-2/redirect.html",{title:"出站流量重定向"},[":md"]],["v-338bc63e","/document/level-2/tproxy.html",{title:"TProxy 透明代理"},[":md"]],["v-d68f7d58","/document/level-2/tproxy_ipv4_and_ipv6.html",{title:"TProxy 透明代理 (ipv4 and ipv6)"},[":md"]],["v-e533e2c6","/document/level-2/traffic_stats.html",{title:"流量统计"},[":md"]],["v-1e465ab0","/document/level-2/warp.html",{title:"通过 Cloudflare Warp 增强代理安全性"},[":md"]],["v-1080fb37","/en/about/news.html",{title:"大史记"},[":md"]],["v-317fc580","/en/config/",{title:"Configurations"},["/en/config/README.md"]],["v-45144c7f","/en/config/api.html",{title:"API Interface"},[":md"]],["v-23fbd2d0","/en/config/dns.html",{title:"Built-in DNS Server"},[":md"]],["v-2b7ec525","/en/config/fakedns.html",{title:"FakeDNS"},[":md"]],["v-5ab92300","/en/config/inbound.html",{title:"Inbound Proxy"},[":md"]],["v-f91d64d6","/en/config/log.html",{title:"Log Configuration"},[":md"]],["v-d705f114","/en/config/metrics.html",{title:"Metrics"},[":md"]],["v-268cd669","/en/config/outbound.html",{title:"Outbound Proxies"},[":md"]],["v-4492d567","/en/config/policy.html",{title:"Local Policy"},[":md"]],["v-0d0e1e92","/en/config/reverse.html",{title:"Reverse Proxy"},[":md"]],["v-4bbe1d5a","/en/config/routing.html",{title:"Routing"},[":md"]],["v-16426d1a","/en/config/stats.html",{title:"Traffic Statistics"},[":md"]],["v-5de780d0","/en/config/transport.html",{title:"Transport"},[":md"]],["v-f88d343e","/en/development/",{title:"Development Guide"},["/en/development/README.md"]],["v-38d56a07","/en/document/",{title:"Quick Start"},["/en/document/README.md"]],["v-4d046016","/en/document/command.html",{title:"Command Parameters"},[":md"]],["v-22b35270","/en/document/config.html",{title:"Configure and Run"},[":md"]],["v-30bd7c12","/en/document/document.html",{title:"Contribute to Project X's Document"},[":md"]],["v-439608b6","/en/document/install.html",{title:"Download and Install"},[":md"]],["v-51a51d87","/document/level-2/transparent_proxy/transparent_proxy.html",{title:"透明代理入门"},[":md"]],["v-76b9a0f3","/en/config/features/browser_dialer.html",{title:"Browser Dialer"},[":md"]],["v-565dbfc4","/en/config/features/env.html",{title:"Environment Variables"},[":md"]],["v-0fbd1336","/en/config/features/fallback.html",{title:"Fallback"},[":md"]],["v-a0627812","/en/config/features/multiple.html",{title:"Multi-file configuration"},[":md"]],["v-d190d938","/en/config/features/xtls.html",{title:"Deep analysis of XTLS"},[":md"]],["v-72afc2d2","/en/config/inbounds/dokodemo.html",{title:"Dokodemo-Door"},[":md"]],["v-773d731c","/en/config/inbounds/http.html",{title:"HTTP"},[":md"]],["v-f555fc02","/en/config/inbounds/shadowsocks.html",{title:"Shadowsocks"},[":md"]],["v-e35196c2","/en/config/inbounds/socks.html",{title:"SOCKS"},[":md"]],["v-29188644","/en/config/inbounds/trojan.html",{title:"Trojan"},[":md"]],["v-255a6ebf","/en/config/inbounds/vless.html",{title:"VLESS"},[":md"]],["v-8cc24480","/en/config/inbounds/vmess.html",{title:"VMess"},[":md"]],["v-64e47ef4","/en/config/outbounds/blackhole.html",{title:"Blackhole"},[":md"]],["v-e979b848","/en/config/outbounds/dns.html",{title:"DNS"},[":md"]],["v-617f0fcf","/en/config/outbounds/freedom.html",{title:"Freedom"},[":md"]],["v-3fc98845","/en/config/outbounds/http.html",{title:"HTTP"},[":md"]],["v-1b804722","/en/config/outbounds/loopback.html",{title:"Loopback"},[":md"]],["v-63077cb6","/en/config/outbounds/shadowsocks.html",{title:"Shadowsocks"},[":md"]],["v-516476d4","/en/config/outbounds/socks.html",{title:"Socks"},[":md"]],["v-7d61a872","/en/config/outbounds/trojan.html",{title:"Trojan"},[":md"]],["v-6e50feb6","/en/config/outbounds/vless.html",{title:"VLESS"},[":md"]],["v-02956db7","/en/config/outbounds/vmess.html",{title:"VMess"},[":md"]],["v-797f8d25","/en/config/outbounds/wireguard.html",{title:"Wireguard"},[":md"]],["v-3eb3e9c6","/en/config/transports/domainsocket.html",{title:"Domain Socket"},[":md"]],["v-2c6058d4","/en/config/transports/grpc.html",{title:"gRPC"},[":md"]],["v-1c38292a","/en/config/transports/h2.html",{title:"HTTP/2"},[":md"]],["v-17ff144a","/en/config/transports/httpupgrade.html",{title:"HTTPUpgrade"},[":md"]],["v-1a7f9d6e","/en/config/transports/mkcp.html",{title:"mKCP"},[":md"]],["v-79d41176","/en/config/transports/quic.html",{title:"QUIC"},[":md"]],["v-5254cbc6","/en/config/transports/tcp.html",{title:"TCP"},[":md"]],["v-9520f392","/en/config/transports/websocket.html",{title:"WebSocket"},[":md"]],["v-b7760e2c","/en/development/intro/compile.html",{title:"Compile the document"},[":md"]],["v-fb774212","/en/development/intro/design.html",{title:"Design Objectives"},[":md"]],["v-38c376c1","/en/development/intro/guide.html",{title:"Development Standards"},[":md"]],["v-21bccd79","/en/development/protocols/mkcp.html",{title:"mKCP Protocol"},[":md"]],["v-27001935","/en/development/protocols/muxcool.html",{title:"Mux.Cool Protocol"},[":md"]],["v-21b30c3f","/en/development/protocols/vless.html",{title:"VLESS Protocol"},[":md"]],["v-94110980","/en/development/protocols/vmess.html",{title:"VMess Protocol"},[":md"]],["v-789ba7ef","/en/document/level-0/",{title:"Plain and Simple Language"},["/en/document/level-0/README.md"]],["v-d3712ade","/en/document/level-0/ch01-preface.html",{title:"[Chapter 1] Simple and Plain Language"},[":md"]],["v-41f9c00e","/en/document/level-0/ch02-preparation.html",{title:"[Chapter 2] Preparation of Raw Materials"},[":md"]],["v-4c013f47","/en/document/level-0/ch03-ssh.html",{title:"[Chapter 3] Remote Login"},[":md"]],["v-a75683b8","/en/document/level-0/ch04-security.html",{title:"[Chapter 4] Security and Protection"},[":md"]],["v-f5341aec","/en/document/level-0/ch05-webpage.html",{title:"Chapter 5: Website Building"},[":md"]],["v-4458f72a","/en/document/level-0/ch06-certificates.html",{title:"[Chapter 6] Certificate Management"},[":md"]],["v-f1802e66","/en/document/level-0/ch07-xray-server.html",{title:"【第 7 章】Xray 服务器篇"},[":md"]],["v-4ca6f1ca","/en/document/level-0/ch08-xray-clients.html",{title:"【第 8 章】Xray 客户端篇"},[":md"]],["v-b0030f00","/en/document/level-0/ch09-appendix.html",{title:"【第 9 章】附录"},[":md"]],["v-789ba80e","/en/document/level-1/",{title:"Beginner's Tips"},["/en/document/level-1/README.md"]],["v-103b3e5c","/en/document/level-1/fallbacks-lv1.html",{title:"回落 (fallbacks) 功能简析"},[":md"]],["v-110dd688","/en/document/level-1/fallbacks-with-sni.html",{title:"SNI fallback"},[":md"]],["v-c425a7d4","/en/document/level-1/routing-lv1-part1.html",{title:"路由 (routing) 功能简析(上)"},[":md"]],["v-c0bbf696","/en/document/level-1/routing-lv1-part2.html",{title:"路由 (routing) 功能简析(下)"},[":md"]],["v-5b6477cc","/en/document/level-1/work.html",{title:"Xray 的工作模式"},[":md"]],["v-789ba82d","/en/document/level-2/",{title:"Advanced Documentation"},["/en/document/level-2/README.md"]],["v-05ddc65d","/en/document/level-2/iptables_gid.html",{title:"Transparent proxy via GID"},[":md"]],["v-474afe99","/en/document/level-2/nginx_or_haproxy_tls_tunnel.html",{title:"Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹"},[":md"]],["v-930ac920","/en/document/level-2/redirect.html",{title:"出站流量重定向"},[":md"]],["v-c579975c","/en/document/level-2/tproxy.html",{title:"TProxy 透明代理"},[":md"]],["v-7efb7c68","/en/document/level-2/tproxy_ipv4_and_ipv6.html",{title:"TProxy 透明代理 (ipv4 and ipv6)"},[":md"]],["v-12a33bee","/en/document/level-2/traffic_stats.html",{title:"流量统计"},[":md"]],["v-7d2b8478","/en/document/level-2/warp.html",{title:"Enhancing Proxy Security with Cloudflare Warp"},[":md"]],["v-7689d7f3","/en/document/level-2/transparent_proxy/transparent_proxy.html",{title:"透明代理入门"},[":md"]],["v-3706649a","/404.html",{title:""},[]]];var ho=pe({name:"Vuepress",setup(){const e=Hu();return()=>fe(e.value)}}),xp=()=>Ep.reduce((e,[t,l,n,i])=>(e.push({name:t,path:l,component:ho,meta:n},{path:l.endsWith("/")?l+"index.html":l.substring(0,l.length-5),redirect:l},...i.map(r=>({path:r===":md"?l.substring(0,l.length-5)+".md":r,redirect:l}))),e),[{name:"404",path:"/:catchAll(.*)",component:ho}]),Lp=cd,Tp=()=>{const e=Kd({history:Lp(ds("/")),routes:xp(),scrollBehavior:(t,l,n)=>n||(t.hash?{el:t.hash}:{top:0})});return e.beforeResolve(async(t,l)=>{var n;(t.path!==l.path||l===pt)&&([t.meta._data]=await Promise.all([vt.resolvePageData(t.name),(n=vs[t.name])==null?void 0:n.__asyncLoader()]))}),e},Pp=e=>{e.component("ClientOnly",$i),e.component("Content",Uu)},wp=(e,t,l)=>{const n=H(()=>t.currentRoute.value.path),i=Ih(n,()=>t.currentRoute.value.meta._data),r=H(()=>vt.resolveLayouts(l)),o=H(()=>vt.resolveRouteLocale(ll.value.locales,n.value)),s=H(()=>vt.resolveSiteLocaleData(ll.value,o.value)),a=H(()=>vt.resolvePageFrontmatter(i.value)),c=H(()=>vt.resolvePageHeadTitle(i.value,s.value)),d=H(()=>vt.resolvePageHead(c.value,a.value,s.value)),h=H(()=>vt.resolvePageLang(i.value,s.value)),f=H(()=>vt.resolvePageLayout(i.value,r.value));return e.provide(Cu,r),e.provide(ps,i),e.provide(ms,a),e.provide(Nu,c),e.provide(gs,d),e.provide(_s,h),e.provide(bs,f),e.provide(Mi,o),e.provide(ys,s),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>a.value},$head:{get:()=>d.value},$headTitle:{get:()=>c.value},$lang:{get:()=>h.value},$page:{get:()=>i.value},$routeLocale:{get:()=>o.value},$site:{get:()=>ll.value},$siteLocale:{get:()=>s.value},$withBase:{get:()=>Bi}}),{layouts:r,pageData:i,pageFrontmatter:a,pageHead:d,pageHeadTitle:c,pageLang:h,pageLayout:f,routeLocale:o,siteData:ll,siteLocaleData:s}},Op=()=>{const e=Fu(),t=Mu();let l=[];const n=()=>{e.value.forEach(o=>{const s=Ap(o);s&&l.push(s)})},i=()=>{const o=[];return e.value.forEach(s=>{const a=Rp(s);a&&o.push(a)}),o},r=()=>{document.documentElement.lang=t.value;const o=i();l.forEach((s,a)=>{const c=o.findIndex(d=>s.isEqualNode(d));c===-1?(s.remove(),delete l[a]):o.splice(c,1)}),o.forEach(s=>document.head.appendChild(s)),l=[...l.filter(s=>!!s),...o]};Xt(Bu,r),ze(()=>{n(),Ye(e,r,{immediate:!1})})},Ap=([e,t,l=""])=>{const n=Object.entries(t).map(([s,a])=>rt(a)?`[${s}=${JSON.stringify(a)}]`:a===!0?`[${s}]`:"").join(""),i=`head > ${e}${n}`;return Array.from(document.querySelectorAll(i)).find(s=>s.innerText===l)||null},Rp=([e,t,l])=>{if(!rt(e))return null;const n=document.createElement(e);return Ni(t)&&Object.entries(t).forEach(([i,r])=>{rt(r)?n.setAttribute(i,r):r===!0&&n.setAttribute(i,"")}),rt(l)&&n.appendChild(document.createTextNode(l)),n},Ip=xu,Dp=async()=>{var l;const e=Ip({name:"VuepressApp",setup(){var n;Op();for(const i of un)(n=i.setup)==null||n.call(i);return()=>[fe(Ss),...un.flatMap(({rootComponents:i=[]})=>i.map(r=>fe(r)))]}}),t=Tp();Pp(e),wp(e,t,un);for(const n of un)await((l=n.enhance)==null?void 0:l.call(n,{app:e,router:t,siteData:ll}));return e.use(t),{app:e,router:t}};Dp().then(({app:e,router:t})=>{t.isReady().then(()=>{e.mount("#app")})});export{ye as F,Le as _,he as a,Ft as b,ee as c,Dp as createVueApp,ie as d,Fc as e,ha as f,ko as g,H as h,Ye as i,ge as j,ze as k,Ci as l,pe as m,Bl as n,z as o,Wl as p,u as q,kt as r,ke as s,Sp as t,te as u,Ct as v,Ve as w,Ie as x}; + */const ue={settings:{minimum:.08,easing:"ease",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,barSelector:'[role="bar"]',parent:"body",template:'
'},status:null,set:e=>{const t=ue.isStarted();e=ei(e,ue.settings.minimum,1),ue.status=e===1?null:e;const l=ue.render(!t),n=l.querySelector(ue.settings.barSelector),i=ue.settings.speed,r=ue.settings.easing;return l.offsetWidth,kh(o=>{sn(n,{transform:"translate3d("+no(e)+"%,0,0)",transition:"all "+i+"ms "+r}),e===1?(sn(l,{transition:"none",opacity:"1"}),l.offsetWidth,setTimeout(function(){sn(l,{transition:"all "+i+"ms linear",opacity:"0"}),setTimeout(function(){ue.remove(),o()},i)},i)):setTimeout(()=>o(),i)}),ue},isStarted:()=>typeof ue.status=="number",start:()=>{ue.status||ue.set(0);const e=()=>{setTimeout(()=>{ue.status&&(ue.trickle(),e())},ue.settings.trickleSpeed)};return ue.settings.trickle&&e(),ue},done:e=>!e&&!ue.status?ue:ue.inc(.3+.5*Math.random()).set(1),inc:e=>{let t=ue.status;return t?(typeof e!="number"&&(e=(1-t)*ei(Math.random()*t,.1,.95)),t=ei(t+e,0,.994),ue.set(t)):ue.start()},trickle:()=>ue.inc(Math.random()*ue.settings.trickleRate),render:e=>{if(ue.isRendered())return document.getElementById("nprogress");io(document.documentElement,"nprogress-busy");const t=document.createElement("div");t.id="nprogress",t.innerHTML=ue.settings.template;const l=t.querySelector(ue.settings.barSelector),n=e?"-100":no(ue.status||0),i=document.querySelector(ue.settings.parent);return sn(l,{transition:"all 0 linear",transform:"translate3d("+n+"%,0,0)"}),i!==document.body&&io(i,"nprogress-custom-parent"),i==null||i.appendChild(t),t},remove:()=>{ro(document.documentElement,"nprogress-busy"),ro(document.querySelector(ue.settings.parent),"nprogress-custom-parent");const e=document.getElementById("nprogress");e&&yh(e)},isRendered:()=>!!document.getElementById("nprogress")},ei=(e,t,l)=>el?l:e,no=e=>(-1+e)*100,kh=function(){const e=[];function t(){const l=e.shift();l&&l(t)}return function(l){e.push(l),e.length===1&&t()}}(),sn=function(){const e=["Webkit","O","Moz","ms"],t={};function l(o){return o.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(s,a){return a.toUpperCase()})}function n(o){const s=document.body.style;if(o in s)return o;let a=e.length;const c=o.charAt(0).toUpperCase()+o.slice(1);let d;for(;a--;)if(d=e[a]+c,d in s)return d;return o}function i(o){return o=l(o),t[o]??(t[o]=n(o))}function r(o,s,a){s=i(s),o.style[s]=a}return function(o,s){for(const a in s){const c=s[a];c!==void 0&&Object.prototype.hasOwnProperty.call(s,a)&&r(o,a,c)}}}(),js=(e,t)=>(typeof e=="string"?e:Ui(e)).indexOf(" "+t+" ")>=0,io=(e,t)=>{const l=Ui(e),n=l+t;js(l,t)||(e.className=n.substring(1))},ro=(e,t)=>{const l=Ui(e);if(!js(e,t))return;const n=l.replace(" "+t+" "," ");e.className=n.substring(1,n.length-1)},Ui=e=>(" "+(e.className||"")+" ").replace(/\s+/gi," "),yh=e=>{e&&e.parentNode&&e.parentNode.removeChild(e)},Eh=()=>{ze(()=>{const e=yt(),t=new Set;t.add(e.currentRoute.value.path),e.beforeEach(l=>{t.has(l.path)||ue.start()}),e.afterEach(l=>{t.add(l.path),ue.done()})})},xh=Nt({setup(){Eh()}}),Lh=JSON.parse(`{"name":"vuepress-theme-xray","smoothScroll":true,"repo":"xtls/xray-core","docsDir":"docs","docsRepo":"xtls/Xray-docs-next","docsBranch":"main","editLinks":true,"enableToggle":true,"locales":{"/":{"navbar":[{"text":"首页","link":"/"},{"text":"大史记","link":"/about/news.md"},{"text":"配置指南","link":"/config/"},{"text":"开发指南","link":"/development/"},{"text":"使用指南","link":"/document/"}],"sidebar":{"/config/":[{"text":"特性详解","children":["/config/features/xtls.md","/config/features/fallback.md","/config/features/browser_dialer.md","/config/features/env.md","/config/features/multiple.md"]},{"text":"基础配置","children":["/config/README.md","/config/log.md","/config/api.md","/config/dns.md","/config/fakedns.md","/config/inbound.md","/config/outbound.md","/config/policy.md","/config/reverse.md","/config/routing.md","/config/stats.md","/config/transport.md","/config/metrics.md"]},{"text":"入站代理","children":["/config/inbounds/dokodemo.md","/config/inbounds/http.md","/config/inbounds/shadowsocks.md","/config/inbounds/socks.md","/config/inbounds/trojan.md","/config/inbounds/vless.md","/config/inbounds/vmess.md"]},{"text":"出站代理","children":["/config/outbounds/blackhole.md","/config/outbounds/dns.md","/config/outbounds/freedom.md","/config/outbounds/http.md","/config/outbounds/loopback.md","/config/outbounds/shadowsocks.md","/config/outbounds/socks.md","/config/outbounds/trojan.md","/config/outbounds/vless.md","/config/outbounds/vmess.md","/config/outbounds/wireguard.md"]},{"text":"底层传输","children":["/config/transports/domainsocket.md","/config/transports/grpc.md","/config/transports/h2.md","/config/transports/mkcp.md","/config/transports/quic.md","/config/transports/tcp.md","/config/transports/websocket.md","/config/transports/httpupgrade.md"]}],"/document/":[{"text":"快速入门文档","children":["/document/README.md","/document/install.md","/document/config.md","/document/command.md","/document/document.md"]},{"text":"小小白白话文","children":["/document/level-0/README.md","/document/level-0/ch01-preface.md","/document/level-0/ch02-preparation.md","/document/level-0/ch03-ssh.md","/document/level-0/ch04-security.md","/document/level-0/ch05-webpage.md","/document/level-0/ch06-certificates.md","/document/level-0/ch07-xray-server.md","/document/level-0/ch08-xray-clients.md","/document/level-0/ch09-appendix.md"]},{"text":"入门技巧","children":["/document/level-1/README.md","/document/level-1/fallbacks-lv1.md","/document/level-1/routing-lv1-part1.md","/document/level-1/routing-lv1-part2.md","/document/level-1/work.md","/document/level-1/fallbacks-with-sni.md"]},{"text":"进阶技巧","children":["/document/level-2/README.md","/document/level-2/transparent_proxy/transparent_proxy.md","/document/level-2/tproxy.md","/document/level-2/tproxy_ipv4_and_ipv6.md","/document/level-2/nginx_or_haproxy_tls_tunnel.md","/document/level-2/iptables_gid.md","/document/level-2/redirect.md","/document/level-2/warp.md","/document/level-2/traffic_stats.md"]}],"/development/":[{"text":"开发指南","children":["/development/README.md","/development/intro/compile.md","/development/intro/design.md","/development/intro/guide.md"]},{"text":"协议详解","children":["/development/protocols/vless.md","/development/protocols/vmess.md","/development/protocols/muxcool.md","/development/protocols/mkcp.md"]}]},"repoLabel":"查看源码","editLinkText":"帮助我们改善此页面!","tip":"提示","warning":"注意","danger":"警告","lastUpdatedText":"最近更改","selectLanguageName":"简体中文","selectLanguageText":"多语言","selectLanguageAriaLabel":"多语言","docsDir":"docs","backToHome":"back to home","openInNewWindow":"open in new tag","toggleColorMode":"toggle color mode","toggleSidebar":"toggle side bar"},"/en/":{"sidebar":{"/en/config/":[{"text":"feature","children":["/en/config/features/xtls.md","/en/config/features/fallback.md","/en/config/features/browser_dialer.md","/en/config/features/env.md","/en/config/features/multiple.md"]},{"text":"config","children":["/en/config/README.md","/en/config/log.md","/en/config/api.md","/en/config/dns.md","/en/config/fakedns.md","/en/config/inbound.md","/en/config/outbound.md","/en/config/policy.md","/en/config/reverse.md","/en/config/routing.md","/en/config/stats.md","/en/config/transport.md","/en/config/metrics.md"]},{"text":"inbound","children":["/en/config/inbounds/dokodemo.md","/en/config/inbounds/http.md","/en/config/inbounds/shadowsocks.md","/en/config/inbounds/socks.md","/en/config/inbounds/trojan.md","/en/config/inbounds/vless.md","/en/config/inbounds/vmess.md"]},{"text":"outbound","children":["/en/config/outbounds/blackhole.md","/en/config/outbounds/dns.md","/en/config/outbounds/freedom.md","/en/config/outbounds/http.md","/en/config/outbounds/loopback.md","/en/config/outbounds/shadowsocks.md","/en/config/outbounds/socks.md","/en/config/outbounds/trojan.md","/en/config/outbounds/vless.md","/en/config/outbounds/vmess.md","/en/config/outbounds/wireguard.md"]},{"text":"transport","children":["/en/config/transports/domainsocket.md","/en/config/transports/grpc.md","/en/config/transports/h2.md","/en/config/transports/mkcp.md","/en/config/transports/quic.md","/en/config/transports/tcp.md","/en/config/transports/websocket.md","/en/config/transports/httpupgrade.md"]}],"/en/document/":[{"text":"Quick Start","children":["/en/document/README.md","/en/document/install.md","/en/document/config.md","/en/document/command.md","/en/document/document.md"]},{"text":"Beginner Tutorial","children":["/en/document/level-0/README.md","/en/document/level-0/ch01-preface.md","/en/document/level-0/ch02-preparation.md","/en/document/level-0/ch03-ssh.md","/en/document/level-0/ch04-security.md","/en/document/level-0/ch05-webpage.md","/en/document/level-0/ch06-certificates.md","/en/document/level-0/ch07-xray-server.md","/en/document/level-0/ch08-xray-clients.md","/en/document/level-0/ch09-appendix.md"]},{"text":"Getting Started Tips","children":["/en/document/level-1/README.md","/en/document/level-1/fallbacks-lv1.md","/en/document/level-1/routing-lv1-part1.md","/en/document/level-1/routing-lv1-part2.md","/en/document/level-1/work.md","/en/document/level-1/fallbacks-with-sni.md"]},{"text":"Advanced Documentation","children":["/en/document/level-2/README.md","/en/document/level-2/transparent_proxy/transparent_proxy.md","/en/document/level-2/tproxy.md","/en/document/level-2/tproxy_ipv4_and_ipv6.md","/en/document/level-2/nginx_or_haproxy_tls_tunnel.md","/en/document/level-2/iptables_gid.md","/en/document/level-2/redirect.md","/en/document/level-2/warp.md","/en/document/level-2/traffic_stats.md"]}],"/en/development/":[{"text":"Developer Guide","children":["/en/development/README.md","/en/development/intro/compile.md","/en/development/intro/design.md","/en/development/intro/guide.md"]},{"text":"Protocol Details","children":["/en/development/protocols/vless.md","/en/development/protocols/vmess.md","/en/development/protocols/muxcool.md","/en/development/protocols/mkcp.md"]}]},"navbar":[{"text":"Homepage","link":"/en"},{"text":"Website History","link":"/en/about/news.md"},{"text":"Config Reference","link":"/en/config/"},{"text":"Developer Guide","link":"/en/development/"},{"text":"Quick Start","link":"/en/document/"}],"selectLanguageName":"English (WIP)","selectLanguageText":"Multiple language","selectLanguageAriaLabel":"Multiple language","editLinkText":"Help us improve this page on GitHub!","lastUpdatedText":"Last Updated","contributorsText":"contributors","tip":"Tip","warning":"Warning","danger":"Danger","notFound":["这里什么都没有","我们怎么到这来了?","这是一个 404 页面","看起来我们进入了错误的链接"],"backToHome":"back to home","openInNewWindow":"open in new tag","toggleColorMode":"toggle color mode","toggleSidebar":"toggle side bar"},"themePlugins":{"git":true}},"colorMode":"auto","colorModeSwitch":true,"navbar":[],"logo":null,"selectLanguageText":"Languages","selectLanguageAriaLabel":"Select language","sidebar":"auto","sidebarDepth":2,"editLink":true,"editLinkText":"Edit this page","lastUpdated":true,"lastUpdatedText":"Last Updated","contributors":true,"contributorsText":"Contributors","notFound":["There's nothing here.","How did we get here?","That's a Four-Oh-Four.","Looks like we've got some broken links."],"backToHome":"Take me home","openInNewWindow":"open in new window","toggleColorMode":"toggle color mode","toggleSidebar":"toggle sidebar"}`),Th=ge(Lh),Cs=()=>Th,Vs=Symbol(""),Ph=()=>{const e=Te(Vs);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e},wh=(e,t)=>{const{locales:l,...n}=e;return{...n,...l==null?void 0:l[t]}},Oh=Nt({enhance({app:e}){const t=Cs(),l=e._context.provides[Mi],n=H(()=>wh(t.value,l.value));e.provide(Vs,n),Object.defineProperties(e.config.globalProperties,{$theme:{get(){return t.value}},$themeLocale:{get(){return n.value}}})}}),Ah=pe({__name:"Badge",props:{type:{type:String,required:!1,default:"tip"},text:{type:String,required:!1,default:""},vertical:{type:String,required:!1,default:void 0}},setup(e){return(t,l)=>(z(),ee("span",{class:Ke(["badge",e.type]),style:$l({verticalAlign:e.vertical})},[ke(t.$slots,"default",{},()=>[Ft(Ie(e.text),1)])],6))}}),Le=(e,t)=>{const l=e.__vccOpts||e;for(const[n,i]of t)l[n]=i;return l},Rh=Le(Ah,[["__file","Badge.vue"]]);function Ih(e,t){let l,n,i;const r=ge(!0),o=()=>{r.value=!0,i()};Ye(e,o,{flush:"sync"});const s=typeof t=="function"?t:t.get,a=typeof t=="function"?void 0:t.set,c=Fa((d,h)=>(n=d,i=h,{get(){return r.value&&(l=s(),r.value=!1),n(),l},set(f){a==null||a(f)}}));return Object.isExtensible(c)&&(c.trigger=o),c}function Fs(e){return ko()?(ha(e),!0):!1}function pl(e){return typeof e=="function"?e():te(e)}const Dh=typeof window<"u"&&typeof document<"u";typeof WorkerGlobalScope<"u"&&globalThis instanceof WorkerGlobalScope;const Sh=Object.prototype.toString,jh=e=>Sh.call(e)==="[object Object]",Ch=()=>{};function Vh(e,t){function l(...n){return new Promise((i,r)=>{Promise.resolve(e(()=>t.apply(this,n),{fn:t,thisArg:this,args:n})).then(i).catch(r)})}return l}const Ns=e=>e();function Fh(e=Ns){const t=ge(!0);function l(){t.value=!1}function n(){t.value=!0}const i=(...r)=>{t.value&&e(...r)};return{isActive:Rn(t),pause:l,resume:n,eventFilter:i}}function Nh(e){return e||Ci()}function Mh(e,t,l={}){const{eventFilter:n=Ns,...i}=l;return Ye(e,Vh(n,t),i)}function Hh(e,t,l={}){const{eventFilter:n,...i}=l,{eventFilter:r,pause:o,resume:s,isActive:a}=Fh(n);return{stop:Mh(e,t,{...i,eventFilter:r}),pause:o,resume:s,isActive:a}}function $h(e,t=!0,l){Nh()?ze(e,l):t?e():Wl(e)}function Bh(e=!1,t={}){const{truthyValue:l=!0,falsyValue:n=!1}=t,i=Me(e),r=ge(e);function o(s){if(arguments.length)return r.value=s,r.value;{const a=pl(l);return r.value=r.value===a?pl(n):a,r.value}}return i?o:[r,o]}function zh(e){var t;const l=pl(e);return(t=l==null?void 0:l.$el)!=null?t:l}const Tn=Dh?window:void 0;function oo(...e){let t,l,n,i;if(typeof e[0]=="string"||Array.isArray(e[0])?([l,n,i]=e,t=Tn):[t,l,n,i]=e,!t)return Ch;Array.isArray(l)||(l=[l]),Array.isArray(n)||(n=[n]);const r=[],o=()=>{r.forEach(d=>d()),r.length=0},s=(d,h,f,m)=>(d.addEventListener(h,f,m),()=>d.removeEventListener(h,f,m)),a=Ye(()=>[zh(t),pl(i)],([d,h])=>{if(o(),!d)return;const f=jh(h)?{...h}:h;r.push(...l.flatMap(m=>n.map(k=>s(d,m,k,f))))},{immediate:!0,flush:"post"}),c=()=>{a(),o()};return Fs(c),c}function Wh(){const e=ge(!1),t=Ci();return t&&ze(()=>{e.value=!0},t),e}function Uh(e){const t=Wh();return H(()=>(t.value,!!e()))}function Kh(e,t={}){const{window:l=Tn}=t,n=Uh(()=>l&&"matchMedia"in l&&typeof l.matchMedia=="function");let i;const r=ge(!1),o=c=>{r.value=c.matches},s=()=>{i&&("removeEventListener"in i?i.removeEventListener("change",o):i.removeListener(o))},a=tc(()=>{n.value&&(s(),i=l.matchMedia(pl(e)),"addEventListener"in i?i.addEventListener("change",o):i.addListener(o),r.value=i.matches)});return Fs(()=>{a(),s(),i=void 0}),r}const an=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},cn="__vueuse_ssr_handlers__",qh=Xh();function Xh(){return cn in an||(an[cn]=an[cn]||{}),an[cn]}function Gh(e,t){return qh[e]||t}function Yh(e){return e==null?"any":e instanceof Set?"set":e instanceof Map?"map":e instanceof Date?"date":typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="object"?"object":Number.isNaN(e)?"any":"number"}const Qh={boolean:{read:e=>e==="true",write:e=>String(e)},object:{read:e=>JSON.parse(e),write:e=>JSON.stringify(e)},number:{read:e=>Number.parseFloat(e),write:e=>String(e)},any:{read:e=>e,write:e=>String(e)},string:{read:e=>e,write:e=>String(e)},map:{read:e=>new Map(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e.entries()))},set:{read:e=>new Set(JSON.parse(e)),write:e=>JSON.stringify(Array.from(e))},date:{read:e=>new Date(e),write:e=>e.toISOString()}},so="vueuse-storage";function Ms(e,t,l,n={}){var i;const{flush:r="pre",deep:o=!0,listenToStorageChanges:s=!0,writeDefaults:a=!0,mergeDefaults:c=!1,shallow:d,window:h=Tn,eventFilter:f,onError:m=O=>{console.error(O)},initOnMounted:k}=n,T=(d?jo:ge)(typeof t=="function"?t():t);if(!l)try{l=Gh("getDefaultStorage",()=>{var O;return(O=Tn)==null?void 0:O.localStorage})()}catch(O){m(O)}if(!l)return T;const w=pl(t),I=Yh(w),R=(i=n.serializer)!=null?i:Qh[I],{pause:b,resume:E}=Hh(T,()=>G(T.value),{flush:r,deep:o,eventFilter:f});h&&s&&$h(()=>{oo(h,"storage",y),oo(h,so,q),k&&y()}),k||y();function F(O,W){h&&h.dispatchEvent(new CustomEvent(so,{detail:{key:e,oldValue:O,newValue:W,storageArea:l}}))}function G(O){try{const W=l.getItem(e);if(O==null)F(W,null),l.removeItem(e);else{const x=R.write(O);W!==x&&(l.setItem(e,x),F(W,x))}}catch(W){m(W)}}function N(O){const W=O?O.newValue:l.getItem(e);if(W==null)return a&&w!=null&&l.setItem(e,R.write(w)),w;if(!O&&c){const x=R.read(W);return typeof c=="function"?c(x,w):I==="object"&&!Array.isArray(x)?{...w,...x}:x}else return typeof W!="string"?W:R.read(W)}function y(O){if(!(O&&O.storageArea!==l)){if(O&&O.key==null){T.value=w;return}if(!(O&&O.key!==e)){b();try{(O==null?void 0:O.newValue)!==R.write(T.value)&&(T.value=N(O))}catch(W){m(W)}finally{O?Wl(E):E()}}}}function q(O){y(O.detail)}return T}function Jh(e){return Kh("(prefers-color-scheme: dark)",e)}const Zh=pe({name:"CodeGroup",slots:Object,setup(e,{slots:t}){const l=ge([]),n=ge(-1),i=Ms("vuepress-code-group",{}),r=H(()=>l.value.map(c=>c.innerText).join(","));ze(()=>{Ye(()=>i.value[r.value],(c=-1)=>{n.value!==c&&(n.value=c)},{immediate:!0}),Ye(n,c=>{i.value[r.value]!==c&&(i.value[r.value]=c)})});const o=(c=n.value)=>{c{c>0?n.value=c-1:n.value=l.value.length-1,l.value[n.value].focus()},a=(c,d)=>{c.key===" "||c.key==="Enter"?(c.preventDefault(),n.value=d):c.key==="ArrowRight"?(c.preventDefault(),o(d)):c.key==="ArrowLeft"&&(c.preventDefault(),s(d))};return()=>{var d;const c=(((d=t.default)==null?void 0:d.call(t))||[]).filter(h=>h.type.name==="CodeGroupItem").map(h=>(h.props===null&&(h.props={}),h));return c.length===0?null:(n.value<0||n.value>c.length-1?(n.value=c.findIndex(h=>h.props.active===""||h.props.active===!0),n.value===-1&&(n.value=0)):c.forEach((h,f)=>{h.props.active=f===n.value}),fe("div",{class:"code-group"},[fe("div",{class:"code-group__nav",role:"tablist"},c.map((h,f)=>{const m=f===n.value;return fe("button",{ref:k=>{k&&(l.value[f]=k)},class:{"code-group__nav-tab":!0,"code-group__nav-tab-active":m},role:"tab",ariaSelected:m,onClick:()=>n.value=f,onKeydown:k=>a(k,f)},h.props.title)})),c]))}}}),ef=pe({name:"CodeGroupItem",__name:"CodeGroupItem",props:{title:{type:String,required:!0},active:{type:Boolean,required:!1,default:!1}},setup(e){return(t,l)=>(z(),ee("div",{class:Ke(["code-group-item",{"code-group-item__active":e.active}]),role:"tabpanel"},[ke(t.$slots,"default")],2))}}),tf=Le(ef,[["__file","CodeGroupItem.vue"]]),lf=()=>Cs(),Ne=()=>Ph(),Hs=Symbol(""),Ki=()=>{const e=Te(Hs);if(!e)throw new Error("useDarkMode() is called without provider.");return e},nf=()=>{const e=Ne(),t=Jh(),l=Ms("vuepress-color-scheme",e.value.colorMode),n=H({get(){return e.value.colorModeSwitch?l.value==="auto"?t.value:l.value==="dark":e.value.colorMode==="dark"},set(i){i===t.value?l.value="auto":l.value=i?"dark":"light"}});Xt(Hs,n),rf(n)},rf=e=>{const t=(l=e.value)=>{const n=window==null?void 0:window.document.querySelector("html");n==null||n.classList.toggle("dark",l)};ze(()=>{Ye(e,t,{immediate:!0})}),Cn(()=>t())};let ti=null,Ll=null;const of={wait:()=>ti,pending:()=>{ti=new Promise(e=>Ll=e)},resolve:()=>{Ll==null||Ll(),ti=null,Ll=null}},$s=()=>of,Bs=(e,...t)=>{const l=e.resolve(...t),n=l.matched[l.matched.length-1];if(!(n!=null&&n.redirect))return l;const{redirect:i}=n,r=ju(i)?i(l):i,o=rt(r)?{path:r}:r;return Bs(e,{hash:l.hash,query:l.query,params:l.params,...o})},qi=(e,t)=>{const l=Bs(e,encodeURI(t));return{text:l.meta.title||t,link:l.name==="404"?t:l.fullPath}},ao=e=>decodeURI(e).replace(/#.*$/,"").replace(/(index)?\.(md|html)$/,""),sf=(e,t)=>{if(t.hash===e)return!0;const l=ao(t.path),n=ao(e);return l===n},zs=(e,t)=>e.link&&sf(e.link,t)?!0:e.children?e.children.some(l=>zs(l,t)):!1,Ws=e=>!Xl(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,af={GitHub:":repo/edit/:branch/:path",GitLab:":repo/-/edit/:branch/:path",Gitee:":repo/edit/:branch/:path",Bitbucket:":repo/src/:branch/:path?mode=edit&spa=0&at=:branch&fileviewer=file-view-default"},cf=({docsRepo:e,editLinkPattern:t})=>{if(t)return t;const l=Ws(e);return l!==null?af[l]:null},uf=({docsRepo:e,docsBranch:t,docsDir:l,filePathRelative:n,editLinkPattern:i})=>{if(!n)return null;const r=cf({docsRepo:e,editLinkPattern:i});return r?r.replace(/:repo/,Xl(e)?e:`https://github.com/${e}`).replace(/:branch/,t).replace(/:path/,hs(`${ds(l)}/${n}`)):null},Us=Symbol("sidebarItems"),Xi=()=>{const e=Te(Us);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},df=()=>{const e=Ne(),t=_t(),l=al(),n=bl(),i=yt(),r=H(()=>hf(t.value,e.value,l.value,i,n.path));Xt(Us,r)},hf=(e,t,l,n,i)=>{const r=e.sidebar??t.sidebar??"auto",o=e.sidebarDepth??t.sidebarDepth??2;return e.home||r===!1?[]:r==="auto"?Ks(l,o):Array.isArray(r)?qs(l,n,i,r,o):Ni(r)?vf(l,n,i,r,o):[]},ff=(e,t)=>({text:e.title,link:e.link,children:Gi(e.children,t)}),Gi=(e,t)=>t>0?e.map(l=>ff(l,t-1)):[],Ks=(e,t)=>[{text:e.title,children:Gi(e.headers,t)}],qs=(e,t,l,n,i)=>{const r=o=>{var a;let s;if(rt(o)?s=qi(t,o):s=o,s.children)return{...s,children:s.children.map(c=>r(c))};if(s.link===l){const c=((a=e.headers[0])==null?void 0:a.level)===1?e.headers[0].children:e.headers;return{...s,children:Gi(c,i)}}return s};return n.map(o=>r(o))},vf=(e,t,l,n,i)=>{const r=fs(n,l),o=n[r]??[];return o==="heading"?Ks(e,i):qs(e,t,l,o,i)},pf="719px",mf={mobile:pf};var Ml;(function(e){e.MOBILE="mobile"})(Ml||(Ml={}));var fo;const gf={[Ml.MOBILE]:Number.parseInt((fo=mf.mobile)==null?void 0:fo.replace("px",""),10)},Xs=(e,t)=>{const l=gf[e];Number.isInteger(l)&&ze(()=>{t(l),window.addEventListener("resize",()=>t(l),!1),window.addEventListener("orientationchange",()=>t(l),!1)})},_f={},bf={class:"theme-default-content"};function kf(e,t){const l=kt("Content");return z(),ee("div",bf,[ie(l)])}const yf=Le(_f,[["render",kf],["__file","HomeContent.vue"]]),Ef={key:0,class:"features"},xf=pe({__name:"HomeFeatures",setup(e){const t=_t(),l=H(()=>Array.isArray(t.value.features)?t.value.features:[]);return(n,i)=>l.value.length?(z(),ee("div",Ef,[(z(!0),ee(ye,null,Ct(l.value,r=>(z(),ee("div",{key:r.title,class:"feature"},[he("h2",null,Ie(r.title),1),he("p",null,Ie(r.details),1)]))),128))])):Oe("",!0)}}),Lf=Le(xf,[["__file","HomeFeatures.vue"]]),Tf=["innerHTML"],Pf=["textContent"],wf=pe({__name:"HomeFooter",setup(e){const t=_t(),l=H(()=>t.value.footer),n=H(()=>t.value.footerHtml);return(i,r)=>l.value?(z(),ee(ye,{key:0},[n.value?(z(),ee("div",{key:0,class:"footer",innerHTML:l.value},null,8,Tf)):(z(),ee("div",{key:1,class:"footer",textContent:Ie(l.value)},null,8,Pf))],64)):Oe("",!0)}}),Of=Le(wf,[["__file","HomeFooter.vue"]]),Af=["href","rel","target","aria-label"],Rf=pe({inheritAttrs:!1,__name:"AutoLink",props:{item:{type:Object,required:!0}},setup(e){const t=e,l=bl(),n=ks(),{item:i}=In(t),r=H(()=>Xl(i.value.link)),o=H(()=>!r.value&&Su(i.value.link)),s=H(()=>{if(!o.value){if(i.value.target)return i.value.target;if(r.value)return"_blank"}}),a=H(()=>s.value==="_blank"),c=H(()=>!r.value&&!o.value&&!a.value),d=H(()=>{if(!o.value){if(i.value.rel)return i.value.rel;if(a.value)return"noopener noreferrer"}}),h=H(()=>i.value.ariaLabel||i.value.text),f=H(()=>{const T=Object.keys(n.value.locales);return T.length?!T.some(w=>w===i.value.link):i.value.link!=="/"}),m=H(()=>f.value?l.path.startsWith(i.value.link):!1),k=H(()=>c.value?i.value.activeMatch?new RegExp(i.value.activeMatch).test(l.path):m.value:!1);return(T,w)=>{const I=kt("RouterLink"),R=kt("AutoLinkExternalIcon");return c.value?(z(),we(I,fi({key:0,class:{"router-link-active":k.value},to:te(i).link,"aria-label":h.value},T.$attrs),{default:Ve(()=>[ke(T.$slots,"before"),Ft(" "+Ie(te(i).text)+" ",1),ke(T.$slots,"after")]),_:3},16,["class","to","aria-label"])):(z(),ee("a",fi({key:1,class:"external-link",href:te(i).link,rel:d.value,target:s.value,"aria-label":h.value},T.$attrs),[ke(T.$slots,"before"),Ft(" "+Ie(te(i).text)+" ",1),a.value?(z(),we(R,{key:0})):Oe("",!0),ke(T.$slots,"after")],16,Af))}}}),bt=Le(Rf,[["__file","AutoLink.vue"]]),If={class:"hero"},Df={key:0,id:"main-title"},Sf={key:1,class:"description"},jf={key:2,class:"actions"},Cf=pe({__name:"HomeHero",setup(e){const t=_t(),l=Hi(),n=Ki(),i=H(()=>n.value&&t.value.heroImageDark!==void 0?t.value.heroImageDark:t.value.heroImage),r=H(()=>t.value.heroAlt||s.value||"hero"),o=H(()=>t.value.heroHeight||280),s=H(()=>t.value.heroText===null?null:t.value.heroText||l.value.title||"Hello"),a=H(()=>t.value.tagline===null?null:t.value.tagline||l.value.description||"Welcome to your VuePress site"),c=H(()=>Array.isArray(t.value.actions)?t.value.actions.map(({text:h,link:f,type:m="primary"})=>({text:h,link:f,type:m})):[]),d=()=>{if(!i.value)return null;const h=fe("img",{src:Bi(i.value),alt:r.value,height:o.value});return t.value.heroImageDark===void 0?h:fe($i,()=>h)};return(h,f)=>(z(),ee("header",If,[ie(d),s.value?(z(),ee("h1",Df,Ie(s.value),1)):Oe("",!0),a.value?(z(),ee("p",Sf,Ie(a.value),1)):Oe("",!0),c.value.length?(z(),ee("p",jf,[(z(!0),ee(ye,null,Ct(c.value,m=>(z(),we(bt,{key:m.text,class:Ke(["action-button",[m.type]]),item:m},null,8,["class","item"]))),128))])):Oe("",!0)]))}}),Vf=Le(Cf,[["__file","HomeHero.vue"]]),Ff={class:"home"},Nf=pe({__name:"Home",setup(e){return(t,l)=>(z(),ee("main",Ff,[ie(Vf),ie(Lf),ie(yf),ie(Of)]))}}),Mf=Le(Nf,[["__file","Home.vue"]]),Hf=["aria-hidden"],$f=pe({__name:"NavbarBrand",setup(e){const t=Gl(),l=Hi(),n=Ne(),i=Ki(),r=H(()=>n.value.home||t.value),o=H(()=>l.value.title),s=H(()=>i.value&&n.value.logoDark!==void 0?n.value.logoDark:n.value.logo),a=H(()=>n.value.logoAlt??o.value),c=H(()=>o.value.toLocaleUpperCase().trim()===a.value.toLocaleUpperCase().trim()),d=()=>{if(!s.value)return null;const h=fe("img",{class:"logo",src:Bi(s.value),alt:a.value});return n.value.logoDark===void 0?h:fe($i,()=>h)};return(h,f)=>{const m=kt("RouterLink");return z(),we(m,{to:r.value},{default:Ve(()=>[ie(d),o.value?(z(),ee("span",{key:0,class:Ke(["site-name",{"can-hide":s.value}]),"aria-hidden":c.value},Ie(o.value),11,Hf)):Oe("",!0)]),_:1},8,["to"])}}}),Bf=Le($f,[["__file","NavbarBrand.vue"]]),zf=pe({__name:"DropdownTransition",setup(e){const t=n=>{n.style.height=n.scrollHeight+"px"},l=n=>{n.style.height=""};return(n,i)=>(z(),we(ql,{name:"dropdown",onEnter:t,onAfterEnter:l,onBeforeLeave:t},{default:Ve(()=>[ke(n.$slots,"default")]),_:3}))}}),Gs=Le(zf,[["__file","DropdownTransition.vue"]]),Wf=["aria-label"],Uf={class:"title"},Kf=he("span",{class:"arrow down"},null,-1),qf=["aria-label"],Xf={class:"title"},Gf={class:"navbar-dropdown"},Yf={class:"navbar-dropdown-subtitle"},Qf={key:1},Jf={class:"navbar-dropdown-subitem-wrapper"},Zf=pe({__name:"NavbarDropdown",props:{item:{type:Object,required:!0}},setup(e){const t=e,{item:l}=In(t),n=H(()=>l.value.ariaLabel||l.value.text),i=ge(!1),r=bl();Ye(()=>r.path,()=>{i.value=!1});const o=a=>{a.detail===0?i.value=!i.value:i.value=!1},s=(a,c)=>c[c.length-1]===a;return(a,c)=>(z(),ee("div",{class:Ke(["navbar-dropdown-wrapper",{open:i.value}])},[he("button",{class:"navbar-dropdown-title",type:"button","aria-label":n.value,onClick:o},[he("span",Uf,Ie(te(l).text),1),Kf],8,Wf),he("button",{class:"navbar-dropdown-title-mobile",type:"button","aria-label":n.value,onClick:c[0]||(c[0]=d=>i.value=!i.value)},[he("span",Xf,Ie(te(l).text),1),he("span",{class:Ke(["arrow",i.value?"down":"right"])},null,2)],8,qf),ie(Gs,null,{default:Ve(()=>[_n(he("ul",Gf,[(z(!0),ee(ye,null,Ct(te(l).children,d=>(z(),ee("li",{key:d.text,class:"navbar-dropdown-item"},[d.children?(z(),ee(ye,{key:0},[he("h4",Yf,[d.link?(z(),we(bt,{key:0,item:d,onFocusout:h=>s(d,te(l).children)&&d.children.length===0&&(i.value=!1)},null,8,["item","onFocusout"])):(z(),ee("span",Qf,Ie(d.text),1))]),he("ul",Jf,[(z(!0),ee(ye,null,Ct(d.children,h=>(z(),ee("li",{key:h.link,class:"navbar-dropdown-subitem"},[ie(bt,{item:h,onFocusout:f=>s(h,d.children)&&s(d,te(l).children)&&(i.value=!1)},null,8,["item","onFocusout"])]))),128))])],64)):(z(),we(bt,{key:1,item:d,onFocusout:h=>s(d,te(l).children)&&(i.value=!1)},null,8,["item","onFocusout"]))]))),128))],512),[[xn,i.value]])]),_:1})],2))}}),ev=Le(Zf,[["__file","NavbarDropdown.vue"]]),tv=["aria-label"],lv=pe({__name:"NavbarItems",setup(e){const t=()=>{const h=yt(),f=Gl(),m=ks(),k=Hi(),T=lf(),w=Ne();return H(()=>{const I=Object.keys(m.value.locales);if(I.length<2)return[];const R=h.currentRoute.value.path,b=h.currentRoute.value.fullPath;return[{text:`${w.value.selectLanguageText}`,ariaLabel:`${w.value.selectLanguageAriaLabel??w.value.selectLanguageText}`,children:I.map(F=>{var W,x;const G=((W=m.value.locales)==null?void 0:W[F])??{},N=((x=T.value.locales)==null?void 0:x[F])??{},y=`${G.lang}`,q=N.selectLanguageName??y;let O;if(y===k.value.lang)O=b;else{const C=R.replace(f.value,F);h.getRoutes().some(ne=>ne.path===C)?O=b.replace(R,C):O=N.home??F}return{text:q,link:O}})}]})},l=()=>{const h=Ne(),f=H(()=>h.value.repo),m=H(()=>f.value?Ws(f.value):null),k=H(()=>f.value&&!Xl(f.value)?`https://github.com/${f.value}`:f.value),T=H(()=>k.value?h.value.repoLabel?h.value.repoLabel:m.value===null?"Source":m.value:null);return H(()=>!k.value||!T.value?[]:[{text:T.value,link:k.value}])},n=(h,f)=>rt(f)?qi(h,f):f.children?{...f,children:f.children.map(m=>n(h,m))}:f,i=()=>{const h=yt(),f=Ne();return H(()=>(f.value.navbar||[]).map(m=>n(h,m)))},r=ge(!1),o=i(),s=t(),a=l(),c=H(()=>[...o.value,...s.value,...a.value]);Xs(Ml.MOBILE,h=>{window.innerWidthNe().value.navbarLabel??"site navigation");return(h,f)=>c.value.length?(z(),ee("nav",{key:0,class:"navbar-items","aria-label":d.value},[(z(!0),ee(ye,null,Ct(c.value,m=>(z(),ee("div",{key:m.text,class:"navbar-item"},[m.children?(z(),we(ev,{key:0,item:m,class:Ke(r.value?"mobile":"")},null,8,["item","class"])):(z(),we(bt,{key:1,item:m},null,8,["item"]))]))),128))],8,tv)):Oe("",!0)}}),Ys=Le(lv,[["__file","NavbarItems.vue"]]),nv=["title"],iv={class:"icon",focusable:"false",viewBox:"0 0 32 32"},rv=Fc('',9),ov=[rv],sv={class:"icon",focusable:"false",viewBox:"0 0 32 32"},av=he("path",{d:"M13.502 5.414a15.075 15.075 0 0 0 11.594 18.194a11.113 11.113 0 0 1-7.975 3.39c-.138 0-.278.005-.418 0a11.094 11.094 0 0 1-3.2-21.584M14.98 3a1.002 1.002 0 0 0-.175.016a13.096 13.096 0 0 0 1.825 25.981c.164.006.328 0 .49 0a13.072 13.072 0 0 0 10.703-5.555a1.01 1.01 0 0 0-.783-1.565A13.08 13.08 0 0 1 15.89 4.38A1.015 1.015 0 0 0 14.98 3z",fill:"currentColor"},null,-1),cv=[av],uv=pe({__name:"ToggleColorModeButton",setup(e){const t=Ne(),l=Ki(),n=()=>{l.value=!l.value};return(i,r)=>(z(),ee("button",{class:"toggle-color-mode-button",title:te(t).toggleColorMode,onClick:n},[_n((z(),ee("svg",iv,ov,512)),[[xn,!te(l)]]),_n((z(),ee("svg",sv,cv,512)),[[xn,te(l)]])],8,nv))}}),dv=Le(uv,[["__file","ToggleColorModeButton.vue"]]),hv=["title"],fv=he("div",{class:"icon","aria-hidden":"true"},[he("span"),he("span"),he("span")],-1),vv=[fv],pv=pe({__name:"ToggleSidebarButton",emits:["toggle"],setup(e){const t=Ne();return(l,n)=>(z(),ee("div",{class:"toggle-sidebar-button",title:te(t).toggleSidebar,"aria-expanded":"false",role:"button",tabindex:"0",onClick:n[0]||(n[0]=i=>l.$emit("toggle"))},vv,8,hv))}}),mv=Le(pv,[["__file","ToggleSidebarButton.vue"]]),gv=pe({__name:"Navbar",emits:["toggle-sidebar"],setup(e){const t=Ne(),l=ge(null),n=ge(null),i=ge(0),r=H(()=>i.value?{maxWidth:i.value+"px"}:{});Xs(Ml.MOBILE,s=>{var c;const a=o(l.value,"paddingLeft")+o(l.value,"paddingRight");window.innerWidth{const c=kt("NavbarSearch");return z(),ee("header",{ref_key:"navbar",ref:l,class:"navbar"},[ie(mv,{onToggle:a[0]||(a[0]=d=>s.$emit("toggle-sidebar"))}),he("span",{ref_key:"navbarBrand",ref:n},[ie(Bf)],512),he("div",{class:"navbar-items-wrapper",style:$l(r.value)},[ke(s.$slots,"before"),ie(Ys,{class:"can-hide"}),ke(s.$slots,"after"),te(t).colorModeSwitch?(z(),we(dv,{key:0})):Oe("",!0),ie(c)],4)],512)}}}),_v=Le(gv,[["__file","Navbar.vue"]]),bv={class:"page-meta"},kv={key:0,class:"meta-item edit-link"},yv={key:1,class:"meta-item last-updated"},Ev={class:"meta-item-label"},xv={class:"meta-item-info"},Lv={key:2,class:"meta-item contributors"},Tv={class:"meta-item-label"},Pv={class:"meta-item-info"},wv=["title"],Ov=pe({__name:"PageMeta",setup(e){const t=()=>{const a=Ne(),c=al(),d=_t();return H(()=>{if(!(d.value.editLink??a.value.editLink??!0))return null;const{repo:f,docsRepo:m=f,docsBranch:k="main",docsDir:T="",editLinkText:w}=a.value;if(!m)return null;const I=uf({docsRepo:m,docsBranch:k,docsDir:T,filePathRelative:c.value.filePathRelative,editLinkPattern:d.value.editLinkPattern??a.value.editLinkPattern});return I?{text:w??"Edit this page",link:I}:null})},l=()=>{const a=Ne(),c=al(),d=_t();return H(()=>{var m,k;return!(d.value.lastUpdated??a.value.lastUpdated??!0)||!((m=c.value.git)!=null&&m.updatedTime)?null:new Date((k=c.value.git)==null?void 0:k.updatedTime).toLocaleString()})},n=()=>{const a=Ne(),c=al(),d=_t();return H(()=>{var f;return d.value.contributors??a.value.contributors??!0?((f=c.value.git)==null?void 0:f.contributors)??null:null})},i=Ne(),r=t(),o=l(),s=n();return(a,c)=>{const d=kt("ClientOnly");return z(),ee("footer",bv,[te(r)?(z(),ee("div",kv,[ie(bt,{class:"meta-item-label",item:te(r)},null,8,["item"])])):Oe("",!0),te(o)?(z(),ee("div",yv,[he("span",Ev,Ie(te(i).lastUpdatedText)+": ",1),ie(d,null,{default:Ve(()=>[he("span",xv,Ie(te(o)),1)]),_:1})])):Oe("",!0),te(s)&&te(s).length?(z(),ee("div",Lv,[he("span",Tv,Ie(te(i).contributorsText)+": ",1),he("span",Pv,[(z(!0),ee(ye,null,Ct(te(s),(h,f)=>(z(),ee(ye,{key:f},[he("span",{class:"contributor",title:`email: ${h.email}`},Ie(h.name),9,wv),f!==te(s).length-1?(z(),ee(ye,{key:0},[Ft(", ")],64)):Oe("",!0)],64))),128))])])):Oe("",!0)])}}}),Av=Le(Ov,[["__file","PageMeta.vue"]]),Rv=["aria-label"],Iv={class:"inner"},Dv={key:0,class:"prev"},Sv={key:1,class:"next"},jv=pe({__name:"PageNav",setup(e){const t=(d,h)=>h===!1?null:rt(h)?qi(d,h):Ni(h)?h:!1,l=(d,h,f)=>{const m=d.findIndex(k=>k.link===h);if(m!==-1){const k=d[m+f];return k!=null&&k.link?k:null}for(const k of d)if(k.children){const T=l(k.children,h,f);if(T)return T}return null},n=_t(),i=Xi(),r=bl(),o=yt(),s=H(()=>{const d=t(o,n.value.prev);return d!==!1?d:l(i.value,r.path,-1)}),a=H(()=>{const d=t(o,n.value.next);return d!==!1?d:l(i.value,r.path,1)}),c=H(()=>Ne().value.pageNavbarLabel??"page navigation");return(d,h)=>s.value||a.value?(z(),ee("nav",{key:0,class:"page-nav","aria-label":c.value},[he("p",Iv,[s.value?(z(),ee("span",Dv,[ie(bt,{item:s.value},null,8,["item"])])):Oe("",!0),a.value?(z(),ee("span",Sv,[ie(bt,{item:a.value},null,8,["item"])])):Oe("",!0)])],8,Rv)):Oe("",!0)}}),Cv=Le(jv,[["__file","PageNav.vue"]]),Vv={class:"page"},Fv={class:"theme-default-content"},Nv=pe({__name:"Page",setup(e){return(t,l)=>{const n=kt("Content");return z(),ee("main",Vv,[ke(t.$slots,"top"),he("div",Fv,[ke(t.$slots,"content-top"),ie(n),ke(t.$slots,"content-bottom")]),ie(Av),ie(Cv),ke(t.$slots,"bottom")])}}}),Mv=Le(Nv,[["__file","Page.vue"]]),Hv={class:"sidebar-item-children"},$v=pe({__name:"SidebarItem",props:{item:{type:Object,required:!0},depth:{type:Number,required:!1,default:0}},setup(e){const t=e,{item:l,depth:n}=In(t),i=bl(),r=yt(),o=H(()=>zs(l.value,i)),s=H(()=>({"sidebar-item":!0,"sidebar-heading":n.value===0,active:o.value,collapsible:l.value.collapsible})),a=H(()=>l.value.collapsible?o.value:!0),[c,d]=Bh(a.value),h=m=>{l.value.collapsible&&(m.preventDefault(),d())},f=r.afterEach(m=>{Wl(()=>{c.value=a.value})});return Kl(()=>{f()}),(m,k)=>{var w;const T=kt("SidebarItem",!0);return z(),ee("li",null,[te(l).link?(z(),we(bt,{key:0,class:Ke(s.value),item:te(l)},null,8,["class","item"])):(z(),ee("p",{key:1,tabindex:"0",class:Ke(s.value),onClick:h,onKeydown:ku(h,["enter"])},[Ft(Ie(te(l).text)+" ",1),te(l).collapsible?(z(),ee("span",{key:0,class:Ke(["arrow",te(c)?"down":"right"])},null,2)):Oe("",!0)],34)),(w=te(l).children)!=null&&w.length?(z(),we(Gs,{key:2},{default:Ve(()=>[_n(he("ul",Hv,[(z(!0),ee(ye,null,Ct(te(l).children,I=>(z(),we(T,{key:`${te(n)}${I.text}${I.link}`,item:I,depth:te(n)+1},null,8,["item","depth"]))),128))],512),[[xn,te(c)]])]),_:1})):Oe("",!0)])}}}),Bv=Le($v,[["__file","SidebarItem.vue"]]),zv={key:0,class:"sidebar-items"},Wv=pe({__name:"SidebarItems",setup(e){const t=bl(),l=Xi();return ze(()=>{Ye(()=>t.hash,n=>{const i=document.querySelector(".sidebar");if(!i)return;const r=document.querySelector(`.sidebar a.sidebar-item[href="${t.path}${n}"]`);if(!r)return;const{top:o,height:s}=i.getBoundingClientRect(),{top:a,height:c}=r.getBoundingClientRect();ao+s&&r.scrollIntoView(!1)})}),(n,i)=>te(l).length?(z(),ee("ul",zv,[(z(!0),ee(ye,null,Ct(te(l),r=>(z(),we(Bv,{key:`${r.text}${r.link}`,item:r},null,8,["item"]))),128))])):Oe("",!0)}}),Uv=Le(Wv,[["__file","SidebarItems.vue"]]),Kv={class:"sidebar"},qv=pe({__name:"Sidebar",setup(e){return(t,l)=>(z(),ee("aside",Kv,[ie(Ys),ke(t.$slots,"top"),ie(Uv),ke(t.$slots,"bottom")]))}}),Xv=Le(qv,[["__file","Sidebar.vue"]]),Gv=pe({__name:"Layout",setup(e){const t=al(),l=_t(),n=Ne(),i=H(()=>l.value.navbar!==!1&&n.value.navbar!==!1),r=Xi(),o=ge(!1),s=w=>{o.value=typeof w=="boolean"?w:!o.value},a={x:0,y:0},c=w=>{a.x=w.changedTouches[0].clientX,a.y=w.changedTouches[0].clientY},d=w=>{const I=w.changedTouches[0].clientX-a.x,R=w.changedTouches[0].clientY-a.y;Math.abs(I)>Math.abs(R)&&Math.abs(I)>40&&(I>0&&a.x<=80?s(!0):s(!1))},h=H(()=>[{"no-navbar":!i.value,"no-sidebar":!r.value.length,"sidebar-open":o.value},l.value.pageClass]);let f;ze(()=>{f=yt().afterEach(()=>{s(!1)})}),Cn(()=>{f()});const m=$s(),k=m.resolve,T=m.pending;return(w,I)=>(z(),ee("div",{class:Ke(["theme-container",h.value]),onTouchstart:c,onTouchend:d},[ke(w.$slots,"navbar",{},()=>[i.value?(z(),we(_v,{key:0,onToggleSidebar:s},{before:Ve(()=>[ke(w.$slots,"navbar-before")]),after:Ve(()=>[ke(w.$slots,"navbar-after")]),_:3})):Oe("",!0)]),he("div",{class:"sidebar-mask",onClick:I[0]||(I[0]=R=>s(!1))}),ke(w.$slots,"sidebar",{},()=>[ie(Xv,null,{top:Ve(()=>[ke(w.$slots,"sidebar-top")]),bottom:Ve(()=>[ke(w.$slots,"sidebar-bottom")]),_:3})]),ke(w.$slots,"page",{},()=>[te(l).home?(z(),we(Mf,{key:0})):(z(),we(ql,{key:1,name:"fade-slide-y",mode:"out-in",onBeforeEnter:te(k),onBeforeLeave:te(T)},{default:Ve(()=>[(z(),we(Mv,{key:te(t).path},{top:Ve(()=>[ke(w.$slots,"page-top")]),"content-top":Ve(()=>[ke(w.$slots,"page-content-top")]),"content-bottom":Ve(()=>[ke(w.$slots,"page-content-bottom")]),bottom:Ve(()=>[ke(w.$slots,"page-bottom")]),_:3}))]),_:3},8,["onBeforeEnter","onBeforeLeave"]))])],34))}}),Yv=Le(Gv,[["__file","Layout.vue"]]),Qv={class:"theme-container"},Jv={class:"page"},Zv={class:"theme-default-content"},ep=he("h1",null,"404",-1),tp=pe({__name:"NotFound",setup(e){const t=Gl(),l=Ne(),n=l.value.notFound??["Not Found"],i=()=>n[Math.floor(Math.random()*n.length)],r=l.value.home??t.value,o=l.value.backToHome??"Back to home";return(s,a)=>{const c=kt("RouterLink");return z(),ee("div",Qv,[he("main",Jv,[he("div",Zv,[ep,he("blockquote",null,Ie(i()),1),ie(c,{to:te(r)},{default:Ve(()=>[Ft(Ie(te(o)),1)]),_:1},8,["to"])])])])}}}),lp=Le(tp,[["__file","NotFound.vue"]]),np=Nt({enhance({app:e,router:t}){e.component("Badge",Rh),e.component("CodeGroup",Zh),e.component("CodeGroupItem",tf),e.component("AutoLinkExternalIcon",()=>{const n=e.component("ExternalLinkIcon");return n?fe(n):null}),e.component("NavbarSearch",()=>{const n=e.component("Docsearch")||e.component("SearchBox");return n?fe(n):null});const l=t.options.scrollBehavior;t.options.scrollBehavior=async(...n)=>(await $s().wait(),l(...n))},setup(){nf(),df()},layouts:{Layout:Yv,NotFound:lp}}),ip=e=>e instanceof Element?document.activeElement===e&&(["TEXTAREA","SELECT","INPUT"].includes(e.tagName)||e.hasAttribute("contenteditable")):!1,rp=(e,t)=>t.some(l=>{if(rt(l))return l===e.key;const{key:n,ctrl:i=!1,shift:r=!1,alt:o=!1}=l;return n===e.key&&i===e.ctrlKey&&r===e.shiftKey&&o===e.altKey}),op=/[^\x00-\x7F]/,sp=e=>e.split(/\s+/g).map(t=>t.trim()).filter(t=>!!t),co=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),uo=(e,t)=>{const l=t.join(" "),n=sp(e);if(op.test(e))return n.some(o=>l.toLowerCase().indexOf(o)>-1);const i=e.endsWith(" ");return new RegExp(n.map((o,s)=>n.length===s+1&&!i?`(?=.*\\b${co(o)})`:`(?=.*\\b${co(o)}\\b)`).join("")+".+","gi").test(l)},ap=({input:e,hotKeys:t})=>{if(t.value.length===0)return;const l=n=>{e.value&&rp(n,t.value)&&!ip(n.target)&&(n.preventDefault(),e.value.focus())};ze(()=>{document.addEventListener("keydown",l)}),Kl(()=>{document.removeEventListener("keydown",l)})},cp=[{title:"",headers:[{level:2,title:"XTLS ? Xray ? V2Ray ?",slug:"xtls-xray-v2ray",link:"#xtls-xray-v2ray",children:[{level:3,title:"我们是谁?",slug:"我们是谁",link:"#我们是谁",children:[]},{level:3,title:"帮助 Xray 变得更强",slug:"帮助-xray-变得更强",link:"#帮助-xray-变得更强",children:[]},{level:3,title:"Telegram",slug:"telegram",link:"#telegram",children:[]},{level:3,title:"致谢",slug:"致谢",link:"#致谢",children:[]},{level:3,title:"更多关于 Project X",slug:"更多关于-project-x",link:"#更多关于-project-x",children:[]},{level:3,title:"License",slug:"license",link:"#license",children:[]},{level:3,title:"Stargazers over time",slug:"stargazers-over-time",link:"#stargazers-over-time",children:[]}]}],path:"/",pathLocale:"/",extraFields:[]},{title:"大史记",headers:[{level:2,title:"2021.4.6",slug:"_2021-4-6",link:"#_2021-4-6",children:[]},{level:2,title:"2021.4.4",slug:"_2021-4-4",link:"#_2021-4-4",children:[]},{level:2,title:"2021.4.1 v1.4.2",slug:"_2021-4-1-v1-4-2",link:"#_2021-4-1-v1-4-2",children:[]},{level:2,title:"2021.3.25",slug:"_2021-3-25",link:"#_2021-3-25",children:[]},{level:2,title:"2021.3.15",slug:"_2021-3-15",link:"#_2021-3-15",children:[]},{level:2,title:"2021.3.14 v1.4.0",slug:"_2021-3-14-v1-4-0",link:"#_2021-3-14-v1-4-0",children:[]},{level:2,title:"2021.3.3 1.3.1",slug:"_2021-3-3-1-3-1",link:"#_2021-3-3-1-3-1",children:[]},{level:2,title:"2021.2.14 1.3.0",slug:"_2021-2-14-1-3-0",link:"#_2021-2-14-1-3-0",children:[]},{level:2,title:"2021.01.31 1.2.4",slug:"_2021-01-31-1-2-4",link:"#_2021-01-31-1-2-4",children:[]},{level:2,title:"2021.01.25",slug:"_2021-01-25",link:"#_2021-01-25",children:[]},{level:2,title:"2021.01.22 1.2.3",slug:"_2021-01-22-1-2-3",link:"#_2021-01-22-1-2-3",children:[]},{level:2,title:"2021.01.19",slug:"_2021-01-19",link:"#_2021-01-19",children:[]},{level:2,title:"2021.01.17",slug:"_2021-01-17",link:"#_2021-01-17",children:[]},{level:2,title:"2021.01.15 1.2.2",slug:"_2021-01-15-1-2-2",link:"#_2021-01-15-1-2-2",children:[]},{level:2,title:"2021.01.12",slug:"_2021-01-12",link:"#_2021-01-12",children:[]},{level:2,title:"2021.01.10 1.2.1",slug:"_2021-01-10-1-2-1",link:"#_2021-01-10-1-2-1",children:[]},{level:2,title:"2021.01.07",slug:"_2021-01-07",link:"#_2021-01-07",children:[]},{level:2,title:"2021.01.05",slug:"_2021-01-05",link:"#_2021-01-05",children:[]},{level:2,title:"2021.01.03",slug:"_2021-01-03",link:"#_2021-01-03",children:[]},{level:2,title:"2021.01.01",slug:"_2021-01-01",link:"#_2021-01-01",children:[]},{level:2,title:"2020.12.29",slug:"_2020-12-29",link:"#_2020-12-29",children:[]},{level:2,title:"2020.12.25 1.1.5",slug:"_2020-12-25-1-1-5",link:"#_2020-12-25-1-1-5",children:[]},{level:2,title:"2020.12.24",slug:"_2020-12-24",link:"#_2020-12-24",children:[]},{level:2,title:"2020.12.23",slug:"_2020-12-23",link:"#_2020-12-23",children:[]},{level:2,title:"2020.12.21",slug:"_2020-12-21",link:"#_2020-12-21",children:[]},{level:2,title:"2020.12.18 1.1.4",slug:"_2020-12-18-1-1-4",link:"#_2020-12-18-1-1-4",children:[]},{level:2,title:"2020.12.17",slug:"_2020-12-17",link:"#_2020-12-17",children:[]},{level:2,title:"2020.12.15",slug:"_2020-12-15",link:"#_2020-12-15",children:[]},{level:2,title:"2020.12.11 1.1.3",slug:"_2020-12-11-1-1-3",link:"#_2020-12-11-1-1-3",children:[]},{level:2,title:"2020.12.06 1.1.2",slug:"_2020-12-06-1-1-2",link:"#_2020-12-06-1-1-2",children:[]},{level:2,title:"2020.12.04",slug:"_2020-12-04",link:"#_2020-12-04",children:[]},{level:2,title:"2020.11.27",slug:"_2020-11-27",link:"#_2020-11-27",children:[]},{level:2,title:"2020.11.25 1.0.0",slug:"_2020-11-25-1-0-0",link:"#_2020-11-25-1-0-0",children:[]},{level:2,title:"2020.11.23",slug:"_2020-11-23",link:"#_2020-11-23",children:[]}],path:"/about/news.html",pathLocale:"/",extraFields:[]},{title:"配置文件",headers:[{level:2,title:"概述",slug:"概述",link:"#概述",children:[]},{level:2,title:"基础配置模块",slug:"基础配置模块",link:"#基础配置模块",children:[]}],path:"/config/",pathLocale:"/",extraFields:[]},{title:"API 接口",headers:[{level:2,title:"ApiObject",slug:"apiobject",link:"#apiobject",children:[]},{level:2,title:"相关配置",slug:"相关配置",link:"#相关配置",children:[]},{level:2,title:"支持的 API 列表",slug:"支持的-api-列表",link:"#支持的-api-列表",children:[{level:3,title:"HandlerService",slug:"handlerservice",link:"#handlerservice",children:[]},{level:3,title:"LoggerService",slug:"loggerservice",link:"#loggerservice",children:[]},{level:3,title:"StatsService",slug:"statsservice",link:"#statsservice",children:[]},{level:3,title:"ReflectionService",slug:"reflectionservice",link:"#reflectionservice",children:[]}]},{level:2,title:"API 调用示例",slug:"api-调用示例",link:"#api-调用示例",children:[]}],path:"/config/api.html",pathLocale:"/",extraFields:[]},{title:"内置 DNS 服务器",headers:[{level:2,title:"DNS 服务器",slug:"dns-服务器",link:"#dns-服务器",children:[]},{level:2,title:"DNS 处理流程",slug:"dns-处理流程",link:"#dns-处理流程",children:[]},{level:2,title:"DnsObject",slug:"dnsobject",link:"#dnsobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/dns.html",pathLocale:"/",extraFields:[]},{title:"FakeDNS",headers:[{level:2,title:"FakeDNSObject",slug:"fakednsobject",link:"#fakednsobject",children:[{level:3,title:"如何使用?",slug:"如何使用",link:"#如何使用",children:[]},{level:3,title:"与其它类型 DNS 搭配使用",slug:"与其它类型-dns-搭配使用",link:"#与其它类型-dns-搭配使用",children:[]}]}],path:"/config/fakedns.html",pathLocale:"/",extraFields:[]},{title:"入站代理",headers:[{level:2,title:"InboundObject",slug:"inboundobject",link:"#inboundobject",children:[{level:3,title:"SniffingObject",slug:"sniffingobject",link:"#sniffingobject",children:[]},{level:3,title:"AllocateObject",slug:"allocateobject",link:"#allocateobject",children:[]}]}],path:"/config/inbound.html",pathLocale:"/",extraFields:[]},{title:"日志配置",headers:[{level:2,title:"LogObject",slug:"logobject",link:"#logobject",children:[]}],path:"/config/log.html",pathLocale:"/",extraFields:[]},{title:"Metrics",headers:[{level:2,title:"相关配置",slug:"相关配置",link:"#相关配置",children:[]},{level:2,title:"使用方法",slug:"使用方法",link:"#使用方法",children:[{level:3,title:"pprof",slug:"pprof",link:"#pprof",children:[]},{level:3,title:"expvars",slug:"expvars",link:"#expvars",children:[]},{level:3,title:"Additional",slug:"additional",link:"#additional",children:[]}]}],path:"/config/metrics.html",pathLocale:"/",extraFields:[]},{title:"出站代理",headers:[{level:2,title:"OutboundObject",slug:"outboundobject",link:"#outboundobject",children:[{level:3,title:"ProxySettingsObject",slug:"proxysettingsobject",link:"#proxysettingsobject",children:[]},{level:3,title:"MuxObject",slug:"muxobject",link:"#muxobject",children:[]}]}],path:"/config/outbound.html",pathLocale:"/",extraFields:[]},{title:"本地策略",headers:[{level:2,title:"PolicyObject",slug:"policyobject",link:"#policyobject",children:[{level:3,title:"LevelPolicyObject",slug:"levelpolicyobject",link:"#levelpolicyobject",children:[]},{level:3,title:"SystemPolicyObject",slug:"systempolicyobject",link:"#systempolicyobject",children:[]}]}],path:"/config/policy.html",pathLocale:"/",extraFields:[]},{title:"反向代理",headers:[{level:2,title:"ReverseObject",slug:"reverseobject",link:"#reverseobject",children:[{level:3,title:"BridgeObject",slug:"bridgeobject",link:"#bridgeobject",children:[]},{level:3,title:"PortalObject",slug:"portalobject",link:"#portalobject",children:[]}]},{level:2,title:"完整配置样例",slug:"完整配置样例",link:"#完整配置样例",children:[{level:3,title:"bridge 配置",slug:"bridge-配置",link:"#bridge-配置",children:[]},{level:3,title:"portal 配置",slug:"portal-配置",link:"#portal-配置",children:[]}]}],path:"/config/reverse.html",pathLocale:"/",extraFields:[]},{title:"路由",headers:[{level:2,title:"RoutingObject",slug:"routingobject",link:"#routingobject",children:[{level:3,title:"RuleObject",slug:"ruleobject",link:"#ruleobject",children:[]},{level:3,title:"BalancerObject",slug:"balancerobject",link:"#balancerobject",children:[]},{level:3,title:"预定义域名列表",slug:"预定义域名列表",link:"#预定义域名列表",children:[]}]}],path:"/config/routing.html",pathLocale:"/",extraFields:[]},{title:"统计信息",headers:[{level:2,title:"StatsObject",slug:"statsobject",link:"#statsobject",children:[]},{level:2,title:"获取统计信息",slug:"获取统计信息",link:"#获取统计信息",children:[]}],path:"/config/stats.html",pathLocale:"/",extraFields:[]},{title:"传输方式",headers:[{level:2,title:"TransportObject",slug:"transportobject",link:"#transportobject",children:[]},{level:2,title:"StreamSettingsObject",slug:"streamsettingsobject",link:"#streamsettingsobject",children:[{level:3,title:"TLSObject",slug:"tlsobject",link:"#tlsobject",children:[]},{level:3,title:"RealityObject",slug:"realityobject",link:"#realityobject",children:[]},{level:3,title:"SockoptObject",slug:"sockoptobject",link:"#sockoptobject",children:[]}]}],path:"/config/transport.html",pathLocale:"/",extraFields:[]},{title:"开发指南",headers:[{level:2,title:"编译文档",slug:"编译文档",link:"#编译文档",children:[]},{level:2,title:"设计思路",slug:"设计思路",link:"#设计思路",children:[]},{level:2,title:"开发规范",slug:"开发规范",link:"#开发规范",children:[]},{level:2,title:"协议详解",slug:"协议详解",link:"#协议详解",children:[{level:3,title:"VLESS 协议",slug:"vless-协议",link:"#vless-协议",children:[]},{level:3,title:"VMess 协议",slug:"vmess-协议",link:"#vmess-协议",children:[]},{level:3,title:"Mux.Cool 协议",slug:"mux-cool-协议",link:"#mux-cool-协议",children:[]},{level:3,title:"mKCP 协议",slug:"mkcp-协议",link:"#mkcp-协议",children:[]}]}],path:"/development/",pathLocale:"/",extraFields:[]},{title:"快速入门",headers:[{level:2,title:"下载安装",slug:"下载安装",link:"#下载安装",children:[]},{level:2,title:"配置运行",slug:"配置运行",link:"#配置运行",children:[]},{level:2,title:"命令参数",slug:"命令参数",link:"#命令参数",children:[]},{level:2,title:"改进文档",slug:"改进文档",link:"#改进文档",children:[]},{level:2,title:"小小白白话文",slug:"小小白白话文",link:"#小小白白话文",children:[]},{level:2,title:"入门技巧",slug:"入门技巧",link:"#入门技巧",children:[]},{level:2,title:"进阶文档",slug:"进阶文档",link:"#进阶文档",children:[]}],path:"/document/",pathLocale:"/",extraFields:[]},{title:"命令参数",headers:[{level:2,title:"获取基本命令",slug:"获取基本命令",link:"#获取基本命令",children:[{level:3,title:"xray run",slug:"xray-run",link:"#xray-run",children:[]},{level:3,title:"xray version",slug:"xray-version",link:"#xray-version",children:[]},{level:3,title:"xray api",slug:"xray-api",link:"#xray-api",children:[]},{level:3,title:"xray tls",slug:"xray-tls",link:"#xray-tls",children:[]},{level:3,title:"xray uuid",slug:"xray-uuid",link:"#xray-uuid",children:[]},{level:3,title:"xray x25519",slug:"xray-x25519",link:"#xray-x25519",children:[]},{level:3,title:"xray wg",slug:"xray-wg",link:"#xray-wg",children:[]}]}],path:"/document/command.html",pathLocale:"/",extraFields:[]},{title:"配置运行",headers:[{level:2,title:"服务端配置",slug:"服务端配置",link:"#服务端配置",children:[]},{level:2,title:"客户端配置",slug:"客户端配置",link:"#客户端配置",children:[]},{level:2,title:"运行",slug:"运行",link:"#运行",children:[]}],path:"/document/config.html",pathLocale:"/",extraFields:[]},{title:"为 Project X 的文档贡献",headers:[{level:2,title:"改进文档",slug:"改进文档",link:"#改进文档",children:[]},{level:2,title:"发现问题?",slug:"发现问题",link:"#发现问题",children:[]}],path:"/document/document.html",pathLocale:"/",extraFields:[]},{title:"下载安装",headers:[{level:2,title:"平台支持",slug:"平台支持",link:"#平台支持",children:[]},{level:2,title:"下载 Xray",slug:"下载-xray",link:"#下载-xray",children:[]},{level:2,title:"验证安装包",slug:"验证安装包",link:"#验证安装包",children:[]},{level:2,title:"Windows 安装方式",slug:"windows-安装方式",link:"#windows-安装方式",children:[]},{level:2,title:"macOS 安装方式",slug:"macos-安装方式",link:"#macos-安装方式",children:[]},{level:2,title:"Linux 安装方式",slug:"linux-安装方式",link:"#linux-安装方式",children:[{level:3,title:"安装脚本",slug:"安装脚本",link:"#安装脚本",children:[]},{level:3,title:"Arch Linux",slug:"arch-linux",link:"#arch-linux",children:[]},{level:3,title:"Linuxbrew",slug:"linuxbrew",link:"#linuxbrew",children:[]},{level:3,title:"Debian",slug:"debian",link:"#debian",children:[]},{level:3,title:"Gentoo",slug:"gentoo",link:"#gentoo",children:[]}]},{level:2,title:"Docker 安装方式",slug:"docker-安装方式",link:"#docker-安装方式",children:[{level:3,title:"Docker image 的文件结构",slug:"docker-image-的文件结构",link:"#docker-image-的文件结构",children:[]}]}],path:"/document/install.html",pathLocale:"/",extraFields:[]},{title:"",headers:[{level:2,title:"XTLS? Xray? V2Ray?",slug:"xtls-xray-v2ray",link:"#xtls-xray-v2ray",children:[{level:3,title:"Who are we?",slug:"who-are-we",link:"#who-are-we",children:[]},{level:3,title:"Help Xray become stronger",slug:"help-xray-become-stronger",link:"#help-xray-become-stronger",children:[]},{level:3,title:"Telegram",slug:"telegram",link:"#telegram",children:[]},{level:3,title:"Thanks",slug:"thanks",link:"#thanks",children:[]},{level:3,title:"More about project X",slug:"more-about-project-x",link:"#more-about-project-x",children:[]},{level:3,title:"License",slug:"license",link:"#license",children:[]},{level:3,title:"Stargazers over time",slug:"stargazers-over-time",link:"#stargazers-over-time",children:[]}]}],path:"/en/",pathLocale:"/en/",extraFields:[]},{title:"Browser Dialer",headers:[{level:2,title:"Background",slug:"background",link:"#background",children:[]},{level:2,title:"Xray & JS",slug:"xray-js",link:"#xray-js",children:[]},{level:2,title:"Early data",slug:"early-data",link:"#early-data",children:[]},{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[]}],path:"/config/features/browser_dialer.html",pathLocale:"/",extraFields:[]},{title:"环境变量",headers:[{level:2,title:"资源文件路径",slug:"资源文件路径",link:"#资源文件路径",children:[]},{level:2,title:"配置文件位置",slug:"配置文件位置",link:"#配置文件位置",children:[]},{level:2,title:"多配置目录",slug:"多配置目录",link:"#多配置目录",children:[]}],path:"/config/features/env.html",pathLocale:"/",extraFields:[]},{title:"Fallback 回落",headers:[{level:2,title:"fallbacks 配置",slug:"fallbacks-配置",link:"#fallbacks-配置",children:[{level:3,title:"FallbackObject",slug:"fallbackobject",link:"#fallbackobject",children:[]},{level:3,title:"补充说明",slug:"补充说明",link:"#补充说明",children:[]}]},{level:2,title:"Fallbacks 设计理论",slug:"fallbacks-设计理论",link:"#fallbacks-设计理论",children:[]}],path:"/config/features/fallback.html",pathLocale:"/",extraFields:[]},{title:"多文件配置",headers:[{level:2,title:"多文件启动",slug:"多文件启动",link:"#多文件启动",children:[]},{level:2,title:"规则说明",slug:"规则说明",link:"#规则说明",children:[{level:3,title:"普通对象({})",slug:"普通对象",link:"#普通对象",children:[]},{level:3,title:"数组([])",slug:"数组",link:"#数组",children:[]}]},{level:2,title:"配置例子",slug:"配置例子",link:"#配置例子",children:[]}],path:"/config/features/multiple.html",pathLocale:"/",extraFields:[]},{title:"XTLS 深度剖析",headers:[],path:"/config/features/xtls.html",pathLocale:"/",extraFields:[]},{title:"Dokodemo-Door",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[]},{level:2,title:"透明代理配置样例",slug:"透明代理配置样例",link:"#透明代理配置样例",children:[]}],path:"/config/inbounds/dokodemo.html",pathLocale:"/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",link:"#accountobject",children:[]}]}],path:"/config/inbounds/http.html",pathLocale:"/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[]},{level:2,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}],path:"/config/inbounds/shadowsocks.html",pathLocale:"/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",link:"#accountobject",children:[]}]}],path:"/config/inbounds/socks.html",pathLocale:"/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}]}],path:"/config/inbounds/trojan.html",pathLocale:"/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}]}],path:"/config/inbounds/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]},{level:3,title:"DetourObject",slug:"detourobject",link:"#detourobject",children:[]},{level:3,title:"DefaultObject",slug:"defaultobject",link:"#defaultobject",children:[]}]}],path:"/config/inbounds/vmess.html",pathLocale:"/",extraFields:[]},{title:"Blackhole",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ResponseObject",slug:"responseobject",link:"#responseobject",children:[]}]}],path:"/config/outbounds/blackhole.html",pathLocale:"/",extraFields:[]},{title:"DNS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[]},{level:2,title:"DNS 配置实例",slug:"dns-配置实例",link:"#dns-配置实例",children:[]}],path:"/config/outbounds/dns.html",pathLocale:"/",extraFields:[]},{title:"Freedom",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[]}],path:"/config/outbounds/freedom.html",pathLocale:"/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/outbounds/http.html",pathLocale:"/",extraFields:[]},{title:"Loopback",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"如何使用?",slug:"如何使用",link:"#如何使用",children:[]}]}],path:"/config/outbounds/loopback.html",pathLocale:"/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/outbounds/shadowsocks.html",pathLocale:"/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/outbounds/socks.html",pathLocale:"/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/outbounds/trojan.html",pathLocale:"/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]},{level:3,title:"UserObject",slug:"userobject",link:"#userobject",children:[]}]}],path:"/config/outbounds/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/config/outbounds/vmess.html",pathLocale:"/",extraFields:[]},{title:"Wireguard",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"Peers",slug:"peers",link:"#peers",children:[]}]}],path:"/config/outbounds/wireguard.html",pathLocale:"/",extraFields:[]},{title:"Domain Socket",headers:[{level:2,title:"DomainSocketObject",slug:"domainsocketobject",link:"#domainsocketobject",children:[]}],path:"/config/transports/domainsocket.html",pathLocale:"/",extraFields:[]},{title:"gRPC",headers:[{level:2,title:"GRPCObject",slug:"grpcobject",link:"#grpcobject",children:[]}],path:"/config/transports/grpc.html",pathLocale:"/",extraFields:[]},{title:"HTTP/2",headers:[{level:2,title:"HttpObject",slug:"httpobject",link:"#httpobject",children:[]}],path:"/config/transports/h2.html",pathLocale:"/",extraFields:[]},{title:"HTTPUpgrade",headers:[{level:2,title:"HttpUpgradeObject",slug:"httpupgradeobject",link:"#httpupgradeobject",children:[]}],path:"/config/transports/httpupgrade.html",pathLocale:"/",extraFields:[]},{title:"mKCP",headers:[{level:2,title:"KcpObject",slug:"kcpobject",link:"#kcpobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",link:"#headerobject",children:[]}]},{level:2,title:"鸣谢",slug:"鸣谢",link:"#鸣谢",children:[]},{level:2,title:"对 KCP 协议的改进",slug:"对-kcp-协议的改进",link:"#对-kcp-协议的改进",children:[{level:3,title:"更小的协议头",slug:"更小的协议头",link:"#更小的协议头",children:[]},{level:3,title:"确认包重传",slug:"确认包重传",link:"#确认包重传",children:[]},{level:3,title:"连接状态控制",slug:"连接状态控制",link:"#连接状态控制",children:[]}]}],path:"/config/transports/mkcp.html",pathLocale:"/",extraFields:[]},{title:"QUIC",headers:[{level:2,title:"QuicObject",slug:"quicobject",link:"#quicobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",link:"#headerobject",children:[]}]}],path:"/config/transports/quic.html",pathLocale:"/",extraFields:[]},{title:"TCP",headers:[{level:2,title:"TcpObject",slug:"tcpobject",link:"#tcpobject",children:[{level:3,title:"NoneHeaderObject",slug:"noneheaderobject",link:"#noneheaderobject",children:[]},{level:3,title:"HttpHeaderObject",slug:"httpheaderobject",link:"#httpheaderobject",children:[]}]}],path:"/config/transports/tcp.html",pathLocale:"/",extraFields:[]},{title:"WebSocket",headers:[{level:2,title:"WebSocketObject",slug:"websocketobject",link:"#websocketobject",children:[]},{level:2,title:"Browser Dialer",slug:"browser-dialer",link:"#browser-dialer",children:[]}],path:"/config/transports/websocket.html",pathLocale:"/",extraFields:[]},{title:"编译文档",headers:[{level:2,title:"前序工作",slug:"前序工作",link:"#前序工作",children:[]},{level:2,title:"拉取 Xray 源代码",slug:"拉取-xray-源代码",link:"#拉取-xray-源代码",children:[]},{level:2,title:"构建二进制",slug:"构建二进制",link:"#构建二进制",children:[{level:3,title:"Windows(Powershell):",slug:"windows-powershell",link:"#windows-powershell",children:[]},{level:3,title:"macOS, Linux:",slug:"macos-linux",link:"#macos-linux",children:[]}]},{level:2,title:"交叉编译:",slug:"交叉编译",link:"#交叉编译",children:[]},{level:2,title:"可复现构建:",slug:"可复现构建",link:"#可复现构建",children:[]}],path:"/development/intro/compile.html",pathLocale:"/",extraFields:[]},{title:"设计目标",headers:[{level:2,title:"架构",slug:"架构",link:"#架构",children:[{level:3,title:"应用层",slug:"应用层",link:"#应用层",children:[]},{level:3,title:"代理层",slug:"代理层",link:"#代理层",children:[]},{level:3,title:"传输层",slug:"传输层",link:"#传输层",children:[]}]}],path:"/development/intro/design.html",pathLocale:"/",extraFields:[]},{title:"开发规范",headers:[{level:2,title:"基本",slug:"基本",link:"#基本",children:[{level:3,title:"版本控制",slug:"版本控制",link:"#版本控制",children:[]},{level:3,title:"分支(Branch)",slug:"分支-branch",link:"#分支-branch",children:[]},{level:3,title:"发布(Release)",slug:"发布-release",link:"#发布-release",children:[]},{level:3,title:"引用其它项目",slug:"引用其它项目",link:"#引用其它项目",children:[]}]},{level:2,title:"开发流程",slug:"开发流程",link:"#开发流程",children:[{level:3,title:"写代码之前",slug:"写代码之前",link:"#写代码之前",children:[]},{level:3,title:"修改代码",slug:"修改代码",link:"#修改代码",children:[]},{level:3,title:"Pull Request",slug:"pull-request",link:"#pull-request",children:[]},{level:3,title:"对代码的修改",slug:"对代码的修改",link:"#对代码的修改",children:[]}]},{level:2,title:"Xray 编码规范",slug:"xray-编码规范",link:"#xray-编码规范",children:[{level:3,title:"代码结构",slug:"代码结构",link:"#代码结构",children:[]},{level:3,title:"编码规范",slug:"编码规范",link:"#编码规范",children:[]}]}],path:"/development/intro/guide.html",pathLocale:"/",extraFields:[]},{title:"mKCP 协议",headers:[{level:2,title:"版本",slug:"版本",link:"#版本",children:[]},{level:2,title:"依赖",slug:"依赖",link:"#依赖",children:[{level:3,title:"底层协议",slug:"底层协议",link:"#底层协议",children:[]},{level:3,title:"函数",slug:"函数",link:"#函数",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",link:"#通讯过程",children:[]},{level:2,title:"数据格式",slug:"数据格式",link:"#数据格式",children:[{level:3,title:"数据包",slug:"数据包",link:"#数据包",children:[]},{level:3,title:"数据片段",slug:"数据片段",link:"#数据片段",children:[]},{level:3,title:"确认片段",slug:"确认片段",link:"#确认片段",children:[]},{level:3,title:"心跳片段",slug:"心跳片段",link:"#心跳片段",children:[]}]}],path:"/development/protocols/mkcp.html",pathLocale:"/",extraFields:[]},{title:"Mux.Cool 协议",headers:[{level:2,title:"版本",slug:"版本",link:"#版本",children:[]},{level:2,title:"依赖",slug:"依赖",link:"#依赖",children:[{level:3,title:"底层协议",slug:"底层协议",link:"#底层协议",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",link:"#通讯过程",children:[{level:3,title:"客户端行为",slug:"客户端行为",link:"#客户端行为",children:[]},{level:3,title:"服务器端行为",slug:"服务器端行为",link:"#服务器端行为",children:[]}]},{level:2,title:"传输格式",slug:"传输格式",link:"#传输格式",children:[{level:3,title:"帧格式",slug:"帧格式",link:"#帧格式",children:[]},{level:3,title:"元数据",slug:"元数据",link:"#元数据",children:[]},{level:3,title:"新建子连接 (New)",slug:"新建子连接-new",link:"#新建子连接-new",children:[]},{level:3,title:"保持子连接 (Keep)",slug:"保持子连接-keep",link:"#保持子连接-keep",children:[]},{level:3,title:"关闭子连接 (End)",slug:"关闭子连接-end",link:"#关闭子连接-end",children:[]},{level:3,title:"保持连接 (KeepAlive)",slug:"保持连接-keepalive",link:"#保持连接-keepalive",children:[]}]},{level:2,title:"应用",slug:"应用",link:"#应用",children:[]}],path:"/development/protocols/muxcool.html",pathLocale:"/",extraFields:[]},{title:"VLESS 协议",headers:[{level:2,title:"Request & Response",slug:"request-response",link:"#request-response",children:[]},{level:2,title:"ProtoBuf",slug:"protobuf",link:"#protobuf",children:[]},{level:2,title:"Schedulers Flow",slug:"schedulers-flow",link:"#schedulers-flow",children:[]},{level:2,title:"Encryption",slug:"encryption",link:"#encryption",children:[]},{level:2,title:"UDP issues",slug:"udp-issues",link:"#udp-issues",children:[]},{level:2,title:"客户端开发指引",slug:"客户端开发指引",link:"#客户端开发指引",children:[]},{level:2,title:"VLESS 分享链接标准",slug:"vless-分享链接标准",link:"#vless-分享链接标准",children:[]}],path:"/development/protocols/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess 协议",headers:[{level:2,title:"版本",slug:"版本",link:"#版本",children:[]},{level:2,title:"依赖",slug:"依赖",link:"#依赖",children:[{level:3,title:"底层协议",slug:"底层协议",link:"#底层协议",children:[]},{level:3,title:"用户 ID",slug:"用户-id",link:"#用户-id",children:[]},{level:3,title:"函数",slug:"函数",link:"#函数",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",link:"#通讯过程",children:[]},{level:2,title:"客户端请求",slug:"客户端请求",link:"#客户端请求",children:[{level:3,title:"认证信息",slug:"认证信息",link:"#认证信息",children:[]},{level:3,title:"指令部分",slug:"指令部分",link:"#指令部分",children:[]},{level:3,title:"数据部分",slug:"数据部分",link:"#数据部分",children:[]}]},{level:2,title:"服务器应答",slug:"服务器应答",link:"#服务器应答",children:[{level:3,title:"动态端口指令",slug:"动态端口指令",link:"#动态端口指令",children:[]}]},{level:2,title:"注释",slug:"注释",link:"#注释",children:[]}],path:"/development/protocols/vmess.html",pathLocale:"/",extraFields:[]},{title:"小小白白话文",headers:[],path:"/document/level-0/",pathLocale:"/",extraFields:[]},{title:"【第 1 章】 小小白白话文",headers:[{level:2,title:"1.1 这篇文档是写给谁的?",slug:"_1-1-这篇文档是写给谁的",link:"#_1-1-这篇文档是写给谁的",children:[]},{level:2,title:"1.2 这篇文档不是写给谁的?",slug:"_1-2-这篇文档不是写给谁的",link:"#_1-2-这篇文档不是写给谁的",children:[]},{level:2,title:"1.3 郑重声明及其他声明",slug:"_1-3-郑重声明及其他声明",link:"#_1-3-郑重声明及其他声明",children:[]},{level:2,title:"1.4 为什么自建是个难题?",slug:"_1-4-为什么自建是个难题",link:"#_1-4-为什么自建是个难题",children:[]},{level:2,title:"1.5 “用机场不就行了?”",slug:"_1-5-用机场不就行了",link:"#_1-5-用机场不就行了",children:[]},{level:2,title:"1.6 那么你到底要不要自建呢?",slug:"_1-6-那么你到底要不要自建呢",link:"#_1-6-那么你到底要不要自建呢",children:[]},{level:2,title:"1.7 题外啰嗦几句",slug:"_1-7-题外啰嗦几句",link:"#_1-7-题外啰嗦几句",children:[]},{level:2,title:"1.8 你的进度",slug:"_1-8-你的进度",link:"#_1-8-你的进度",children:[]}],path:"/document/level-0/ch01-preface.html",pathLocale:"/",extraFields:[]},{title:"【第 2 章】原料准备篇",headers:[{level:2,title:"2.1 获取一台 VPS",slug:"_2-1-获取一台-vps",link:"#_2-1-获取一台-vps",children:[]},{level:2,title:"2.2 获取一个心仪的域名",slug:"_2-2-获取一个心仪的域名",link:"#_2-2-获取一个心仪的域名",children:[]},{level:2,title:"2.3 你本地电脑上需要安装的软件",slug:"_2-3-你本地电脑上需要安装的软件",link:"#_2-3-你本地电脑上需要安装的软件",children:[]},{level:2,title:"2.4 你的进度",slug:"_2-4-你的进度",link:"#_2-4-你的进度",children:[]}],path:"/document/level-0/ch02-preparation.html",pathLocale:"/",extraFields:[]},{title:"【第 3 章】远程登录篇",headers:[{level:2,title:"3.1 远程登录 VPS (PuTTY)",slug:"_3-1-远程登录-vps-putty",link:"#_3-1-远程登录-vps-putty",children:[]},{level:2,title:"3.2 成功登录 SSH!初识命令行界面!",slug:"_3-2-成功登录-ssh-初识命令行界面",link:"#_3-2-成功登录-ssh-初识命令行界面",children:[]},{level:2,title:"3.3 第一次更新 Linux 的软件!",slug:"_3-3-第一次更新-linux-的软件",link:"#_3-3-第一次更新-linux-的软件",children:[]},{level:2,title:"3.4 你的进度",slug:"_3-4-你的进度",link:"#_3-4-你的进度",children:[]}],path:"/document/level-0/ch03-ssh.html",pathLocale:"/",extraFields:[]},{title:"【第 4 章】安全防护篇",headers:[{level:2,title:"4.1 为什么要做安全防护",slug:"_4-1-为什么要做安全防护",link:"#_4-1-为什么要做安全防护",children:[]},{level:2,title:"4.2 具体的风险到底是什么",slug:"_4-2-具体的风险到底是什么",link:"#_4-2-具体的风险到底是什么",children:[]},{level:2,title:"4.3 我们要做的安全防护有哪些",slug:"_4-3-我们要做的安全防护有哪些",link:"#_4-3-我们要做的安全防护有哪些",children:[]},{level:2,title:"4.4 将 SSH 远程登录端口修改为非 22 端口",slug:"_4-4-将-ssh-远程登录端口修改为非-22-端口",link:"#_4-4-将-ssh-远程登录端口修改为非-22-端口",children:[]},{level:2,title:"4.5 建立非 root 的新用户",slug:"_4-5-建立非-root-的新用户",link:"#_4-5-建立非-root-的新用户",children:[]},{level:2,title:"4.6 禁用 root 用户 SSH 远程登录",slug:"_4-6-禁用-root-用户-ssh-远程登录",link:"#_4-6-禁用-root-用户-ssh-远程登录",children:[]},{level:2,title:"4.7 使用 RSA 密钥登录并禁用密码登录",slug:"_4-7-使用-rsa-密钥登录并禁用密码登录",link:"#_4-7-使用-rsa-密钥登录并禁用密码登录",children:[]},{level:2,title:"4.8 你的进度",slug:"_4-8-你的进度",link:"#_4-8-你的进度",children:[]}],path:"/document/level-0/ch04-security.html",pathLocale:"/",extraFields:[]},{title:"【第 5 章】网站建设篇",headers:[{level:2,title:"5.1 为什么要做一个网站?",slug:"_5-1-为什么要做一个网站",link:"#_5-1-为什么要做一个网站",children:[]},{level:2,title:"5.2 登录 VPS、安装运行 Nginx",slug:"_5-2-登录-vps、安装运行-nginx",link:"#_5-2-登录-vps、安装运行-nginx",children:[]},{level:2,title:"5.3 创建一个最简单的网页",slug:"_5-3-创建一个最简单的网页",link:"#_5-3-创建一个最简单的网页",children:[]},{level:2,title:"5.4 常见错误的说明",slug:"_5-4-常见错误的说明",link:"#_5-4-常见错误的说明",children:[]},{level:2,title:"5.5 你的进度",slug:"_5-5-你的进度",link:"#_5-5-你的进度",children:[]}],path:"/document/level-0/ch05-webpage.html",pathLocale:"/",extraFields:[]},{title:"【第 6 章】证书管理篇",headers:[{level:2,title:"6.1 申请 TLS 证书",slug:"_6-1-申请-tls-证书",link:"#_6-1-申请-tls-证书",children:[]},{level:2,title:"6.2 安装 acme.sh",slug:"_6-2-安装-acme-sh",link:"#_6-2-安装-acme-sh",children:[]},{level:2,title:"6.3 测试证书申请",slug:"_6-3-测试证书申请",link:"#_6-3-测试证书申请",children:[]},{level:2,title:"6.4 正式证书申请",slug:"_6-4-正式证书申请",link:"#_6-4-正式证书申请",children:[]},{level:2,title:"6.5 证书安装",slug:"_6-5-证书安装",link:"#_6-5-证书安装",children:[]},{level:2,title:"6.6 你的进度",slug:"_6-6-你的进度",link:"#_6-6-你的进度",children:[]}],path:"/document/level-0/ch06-certificates.html",pathLocale:"/",extraFields:[]},{title:"【第 7 章】Xray 服务器篇",headers:[{level:2,title:"7.1 博观而约取,厚积而薄发",slug:"_7-1-博观而约取-厚积而薄发",link:"#_7-1-博观而约取-厚积而薄发",children:[]},{level:2,title:"7.2 安装 Xray",slug:"_7-2-安装-xray",link:"#_7-2-安装-xray",children:[]},{level:2,title:"7.3 给 Xray 配置 TLS 证书",slug:"_7-3-给-xray-配置-tls-证书",link:"#_7-3-给-xray-配置-tls-证书",children:[]},{level:2,title:"7.4 配置 Xray",slug:"_7-4-配置-xray",link:"#_7-4-配置-xray",children:[]},{level:2,title:"7.5 启动 Xray 服务!!(并查看服务状态)",slug:"_7-5-启动-xray-服务-并查看服务状态",link:"#_7-5-启动-xray-服务-并查看服务状态",children:[]},{level:2,title:"7.6 回顾 systemd 进行基本的服务管理",slug:"_7-6-回顾-systemd-进行基本的服务管理",link:"#_7-6-回顾-systemd-进行基本的服务管理",children:[]},{level:2,title:"7.7 服务器优化之一:开启 BBR",slug:"_7-7-服务器优化之一-开启-bbr",link:"#_7-7-服务器优化之一-开启-bbr",children:[]},{level:2,title:"7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS",slug:"_7-8-服务器优化之二-开启-http-自动跳转-https",link:"#_7-8-服务器优化之二-开启-http-自动跳转-https",children:[]},{level:2,title:"7.9 服务器优化之三:更丰富的回落",slug:"_7-9-服务器优化之三-更丰富的回落",link:"#_7-9-服务器优化之三-更丰富的回落",children:[]},{level:2,title:"7.10 你的进度",slug:"_7-10-你的进度",link:"#_7-10-你的进度",children:[]},{level:2,title:"7.11 重要勘误",slug:"_7-11-重要勘误",link:"#_7-11-重要勘误",children:[]}],path:"/document/level-0/ch07-xray-server.html",pathLocale:"/",extraFields:[]},{title:"【第 8 章】Xray 客户端篇",headers:[{level:2,title:"8.1 Xray 的工作原理简述",slug:"_8-1-xray-的工作原理简述",link:"#_8-1-xray-的工作原理简述",children:[]},{level:2,title:"8.2 客户端与服务器端正确连接",slug:"_8-2-客户端与服务器端正确连接",link:"#_8-2-客户端与服务器端正确连接",children:[]},{level:2,title:"8.3 附加题 1:在 PC 端手工配置 xray-core",slug:"_8-3-附加题-1-在-pc-端手工配置-xray-core",link:"#_8-3-附加题-1-在-pc-端手工配置-xray-core",children:[]},{level:2,title:"8.4 附加题 2:在 PC 端手工运行 xray-core",slug:"_8-4-附加题-2-在-pc-端手工运行-xray-core",link:"#_8-4-附加题-2-在-pc-端手工运行-xray-core",children:[]},{level:2,title:"8.5 附加题 3:在 PC 端开机自动运行 xray-core",slug:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",link:"#_8-5-附加题-3-在-pc-端开机自动运行-xray-core",children:[]},{level:2,title:"8.6 圆满完成!",slug:"_8-6-圆满完成",link:"#_8-6-圆满完成",children:[]},{level:2,title:"8.7 TO INFINITY AND BEYOND!",slug:"_8-7-to-infinity-and-beyond",link:"#_8-7-to-infinity-and-beyond",children:[]}],path:"/document/level-0/ch08-xray-clients.html",pathLocale:"/",extraFields:[]},{title:"【第 9 章】附录",headers:[{level:2,title:"1. 小小白白 Linux 基础命令索引",slug:"_1-小小白白-linux-基础命令索引",link:"#_1-小小白白-linux-基础命令索引",children:[]},{level:2,title:"2. 小小白白 Linux 重要配置文件索引",slug:"_2-小小白白-linux-重要配置文件索引",link:"#_2-小小白白-linux-重要配置文件索引",children:[]},{level:2,title:"3. 小小白白 Xray 重要文件索引",slug:"_3-小小白白-xray-重要文件索引",link:"#_3-小小白白-xray-重要文件索引",children:[]}],path:"/document/level-0/ch09-appendix.html",pathLocale:"/",extraFields:[]},{title:"入门技巧",headers:[],path:"/document/level-1/",pathLocale:"/",extraFields:[]},{title:"回落 (fallbacks) 功能简析",headers:[{level:2,title:"1. 回顾《小小白白话文》中的回落",slug:"_1-回顾《小小白白话文》中的回落",link:"#_1-回顾《小小白白话文》中的回落",children:[]},{level:2,title:"2. 重新认识回落 (WHAT, HOW v1)",slug:"_2-重新认识回落-what-how-v1",link:"#_2-重新认识回落-what-how-v1",children:[]},{level:2,title:"3. 为什么要回落 (WHY v1)",slug:"_3-为什么要回落-why-v1",link:"#_3-为什么要回落-why-v1",children:[]},{level:2,title:"4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)",slug:"_4-重新认识【回落の完全体】-what-why-how-v2",link:"#_4-重新认识【回落の完全体】-what-why-how-v2",children:[]},{level:2,title:"5. 多层回落示例及解读",slug:"_5-多层回落示例及解读",link:"#_5-多层回落示例及解读",children:[{level:3,title:"5.1 首先,我将服务器端配置的 443 监听段摘抄如下:",slug:"_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",link:"#_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",children:[]},{level:3,title:"5.2 后续监听处理的配置段摘抄如下:",slug:"_5-2-后续监听处理的配置段摘抄如下",link:"#_5-2-后续监听处理的配置段摘抄如下",children:[]}]},{level:2,title:"6. 结语",slug:"_6-结语",link:"#_6-结语",children:[]},{level:2,title:"7. 附加题",slug:"_7-附加题",link:"#_7-附加题",children:[]}],path:"/document/level-1/fallbacks-lv1.html",pathLocale:"/",extraFields:[]},{title:"SNI 回落",headers:[{level:2,title:"应用情景",slug:"应用情景",link:"#应用情景",children:[]},{level:2,title:"SNI 简介",slug:"sni-简介",link:"#sni-简介",children:[]},{level:2,title:"思路",slug:"思路",link:"#思路",children:[]},{level:2,title:"添加 DNS 记录",slug:"添加-dns-记录",link:"#添加-dns-记录",children:[]},{level:2,title:"申请 TLS 证书",slug:"申请-tls-证书",link:"#申请-tls-证书",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",link:"#xray-配置",children:[]},{level:2,title:"Nginx 配置",slug:"nginx-配置",link:"#nginx-配置",children:[]},{level:2,title:"Caddy 配置",slug:"caddy-配置",link:"#caddy-配置",children:[]},{level:2,title:"参考",slug:"参考",link:"#参考",children:[]},{level:2,title:"引用",slug:"引用",link:"#引用",children:[]}],path:"/document/level-1/fallbacks-with-sni.html",pathLocale:"/",extraFields:[]},{title:"路由 (routing) 功能简析(上)",headers:[{level:2,title:"1. 初识【路由】三兄弟",slug:"_1-初识【路由】三兄弟",link:"#_1-初识【路由】三兄弟",children:[]},{level:2,title:"2. 基本功: “兄弟一条心”",slug:"_2-基本功-兄弟一条心",link:"#_2-基本功-兄弟一条心",children:[{level:3,title:"2.1 入站",slug:"_2-1-入站",link:"#_2-1-入站",children:[]},{level:3,title:"2.3 路由",slug:"_2-3-路由",link:"#_2-3-路由",children:[]},{level:3,title:"2.4 路由配置项解析之一:流量筛选的依据",slug:"_2-4-路由配置项解析之一-流量筛选的依据",link:"#_2-4-路由配置项解析之一-流量筛选的依据",children:[]}]},{level:2,title:"3. 小试牛刀: “三分天下” 之 “域名分流”",slug:"_3-小试牛刀-三分天下-之-域名分流",link:"#_3-小试牛刀-三分天下-之-域名分流",children:[{level:3,title:"3.1 入站",slug:"_3-1-入站",link:"#_3-1-入站",children:[]},{level:3,title:"3.2 出站",slug:"_3-2-出站",link:"#_3-2-出站",children:[]},{level:3,title:"3.3 路由",slug:"_3-3-路由",link:"#_3-3-路由",children:[]},{level:3,title:"3.4 简析域名文件: geosite.dat",slug:"_3-4-简析域名文件-geosite-dat",link:"#_3-4-简析域名文件-geosite-dat",children:[]},{level:3,title:"3.5 所以 geosite.dat 到底是什么?不是有个 GFWList 吗?",slug:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",link:"#_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",children:[]},{level:3,title:"3.6 军师锦囊藏奇兵:一条隐藏的路由规则",slug:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",link:"#_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",children:[]},{level:3,title:"3.7 再看“三分天下”的大地图",slug:"_3-7-再看-三分天下-的大地图",link:"#_3-7-再看-三分天下-的大地图",children:[]}]},{level:2,title:"4. “三分天下” 之 “蜀魏争雄”",slug:"_4-三分天下-之-蜀魏争雄",link:"#_4-三分天下-之-蜀魏争雄",children:[]},{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",link:"#_5-攻城略池-多种路由匹配条件",children:[]}],path:"/document/level-1/routing-lv1-part1.html",pathLocale:"/",extraFields:[]},{title:"路由 (routing) 功能简析(下)",headers:[{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",link:"#_5-攻城略池-多种路由匹配条件",children:[{level:3,title:"5.1 基于指定域名分流:[domain], [full] 等",slug:"_5-1-基于指定域名分流-domain-full-等",link:"#_5-1-基于指定域名分流-domain-full-等",children:[]},{level:3,title:"5.2 基于 IP 文件分流:geoip.dat",slug:"_5-2-基于-ip-文件分流-geoip-dat",link:"#_5-2-基于-ip-文件分流-geoip-dat",children:[]},{level:3,title:"5.3 基于指定 IP 地址分流",slug:"_5-3-基于指定-ip-地址分流",link:"#_5-3-基于指定-ip-地址分流",children:[]},{level:3,title:"5.4 基于协议类型分流:[protocol] 等",slug:"_5-4-基于协议类型分流-protocol-等",link:"#_5-4-基于协议类型分流-protocol-等",children:[]},{level:3,title:"5.5 基于更多条件的分流",slug:"_5-5-基于更多条件的分流",link:"#_5-5-基于更多条件的分流",children:[]}]},{level:2,title:"6. “霸业初定”:路由规则整体回顾",slug:"_6-霸业初定-路由规则整体回顾",link:"#_6-霸业初定-路由规则整体回顾",children:[]},{level:2,title:"7. 路由配置常见错误",slug:"_7-路由配置常见错误",link:"#_7-路由配置常见错误",children:[{level:3,title:"7.1 错误示范",slug:"_7-1-错误示范",link:"#_7-1-错误示范",children:[]},{level:3,title:"7.2 正确示范",slug:"_7-2-正确示范",link:"#_7-2-正确示范",children:[]}]},{level:2,title:"8. 明修栈道、暗渡陈仓",slug:"_8-明修栈道、暗渡陈仓",link:"#_8-明修栈道、暗渡陈仓",children:[{level:3,title:'8.1 域名策略: "AsIs"',slug:"_8-1-域名策略-asis",link:"#_8-1-域名策略-asis",children:[]},{level:3,title:'8.2 域名策略: "IPIfNonMatch"',slug:"_8-2-域名策略-ipifnonmatch",link:"#_8-2-域名策略-ipifnonmatch",children:[]},{level:3,title:'8.3 域名策略: "IPOnDemand"',slug:"_8-3-域名策略-ipondemand",link:"#_8-3-域名策略-ipondemand",children:[]}]},{level:2,title:"9. 思考题",slug:"_9-思考题",link:"#_9-思考题",children:[]},{level:2,title:"10. 结语",slug:"_10-结语",link:"#_10-结语",children:[]},{level:2,title:"11. 尾注",slug:"_11-尾注",link:"#_11-尾注",children:[]}],path:"/document/level-1/routing-lv1-part2.html",pathLocale:"/",extraFields:[]},{title:"Xray 的工作模式",headers:[{level:2,title:"单服务器模式",slug:"单服务器模式",link:"#单服务器模式",children:[]},{level:2,title:"桥接模式",slug:"桥接模式",link:"#桥接模式",children:[]},{level:2,title:"工作原理",slug:"工作原理",link:"#工作原理",children:[]}],path:"/document/level-1/work.html",pathLocale:"/",extraFields:[]},{title:"进阶文档",headers:[],path:"/document/level-2/",pathLocale:"/",extraFields:[]},{title:"GID 透明代理",headers:[{level:2,title:"思路",slug:"思路",link:"#思路",children:[]},{level:2,title:"配置过程",slug:"配置过程",link:"#配置过程",children:[{level:3,title:"1. 前期准备",slug:"_1-前期准备",link:"#_1-前期准备",children:[]},{level:3,title:"2. 添加用户(安卓用户请忽略)",slug:"_2-添加用户-安卓用户请忽略",link:"#_2-添加用户-安卓用户请忽略",children:[]},{level:3,title:"3. 配置运行 Xray,配置 iptables 规则",slug:"_3-配置运行-xray-配置-iptables-规则",link:"#_3-配置运行-xray-配置-iptables-规则",children:[]}]},{level:2,title:"下面提供一个实现 tproxy 全局代理的完整配置过程",slug:"下面提供一个实现-tproxy-全局代理的完整配置过程",link:"#下面提供一个实现-tproxy-全局代理的完整配置过程",children:[{level:3,title:"1. 完成 前期准备 和 添加用户",slug:"_1-完成-前期准备-和-添加用户",link:"#_1-完成-前期准备-和-添加用户",children:[]},{level:3,title:"2. 准备 Xray 配置文件",slug:"_2-准备-xray-配置文件",link:"#_2-准备-xray-配置文件",children:[]},{level:3,title:"3. 配置最大文件打开数&运行 Xray 客户端",slug:"_3-配置最大文件打开数-运行-xray-客户端",link:"#_3-配置最大文件打开数-运行-xray-客户端",children:[]},{level:3,title:"4. 设置 iptables 规则",slug:"_4-设置-iptables-规则",link:"#_4-设置-iptables-规则",children:[]}]}],path:"/document/level-2/iptables_gid.html",pathLocale:"/",extraFields:[]},{title:"Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹",headers:[{level:2,title:"编译 nginx --with-stream",slug:"编译-nginx-with-stream",link:"#编译-nginx-with-stream",children:[]},{level:2,title:"配置 nginx",slug:"配置-nginx",link:"#配置-nginx",children:[]},{level:2,title:"xray 配置",slug:"xray-配置",link:"#xray-配置",children:[]},{level:2,title:"客户端及服务端启动服务",slug:"客户端及服务端启动服务",link:"#客户端及服务端启动服务",children:[]},{level:2,title:"结束",slug:"结束",link:"#结束",children:[]},{level:2,title:"HTTPS 隧道",slug:"https-隧道",link:"#https-隧道",children:[{level:3,title:"haproxy_client 配置 (运行前去掉注释)",slug:"haproxy-client-配置-运行前去掉注释",link:"#haproxy-client-配置-运行前去掉注释",children:[]},{level:3,title:"haproxy_server 配置 (运行前去掉注释)",slug:"haproxy-server-配置-运行前去掉注释",link:"#haproxy-server-配置-运行前去掉注释",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-1",link:"#xray-配置-1",children:[]}]},{level:2,title:"WebSocket over HTTP/2",slug:"websocket-over-http-2",link:"#websocket-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置",link:"#haproxy-client-配置",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置",link:"#haproxy-server-配置",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-2",link:"#xray-配置-2",children:[]}]},{level:2,title:"gRPC over HTTP/2",slug:"grpc-over-http-2",link:"#grpc-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-1",link:"#haproxy-client-配置-1",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-1",link:"#haproxy-server-配置-1",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-3",link:"#xray-配置-3",children:[]},{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-2",link:"#haproxy-client-配置-2",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-2",link:"#haproxy-server-配置-2",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-4",link:"#xray-配置-4",children:[]}]}],path:"/document/level-2/nginx_or_haproxy_tls_tunnel.html",pathLocale:"/",extraFields:[]},{title:"出站流量重定向",headers:[{level:2,title:"前言",slug:"前言",link:"#前言",children:[]},{level:2,title:"1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)",slug:"_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",link:"#_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",children:[]},{level:2,title:"2、编辑 VPN 配置文件(以 WireGuard 为例)",slug:"_2、编辑-vpn-配置文件-以-wireguard-为例",link:"#_2、编辑-vpn-配置文件-以-wireguard-为例",children:[]},{level:2,title:"3、启用 WireGuard 网络接口",slug:"_3、启用-wireguard-网络接口",link:"#_3、启用-wireguard-网络接口",children:[]},{level:2,title:"4、Xray-core 配置文件修改",slug:"_4、xray-core-配置文件修改",link:"#_4、xray-core-配置文件修改",children:[]},{level:2,title:"5、系统设置配置",slug:"_5、系统设置配置",link:"#_5、系统设置配置",children:[]},{level:2,title:"6、完成 WireGuard 相关设置",slug:"_6、完成-wireguard-相关设置",link:"#_6、完成-wireguard-相关设置",children:[]},{level:2,title:"后记",slug:"后记",link:"#后记",children:[]},{level:2,title:"感谢",slug:"感谢",link:"#感谢",children:[]}],path:"/document/level-2/redirect.html",pathLocale:"/",extraFields:[]},{title:"TProxy 透明代理",headers:[{level:2,title:"开始之前",slug:"开始之前",link:"#开始之前",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",link:"#xray-配置",children:[]},{level:2,title:"策略路由配置",slug:"策略路由配置",link:"#策略路由配置",children:[]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",link:"#netfilter-配置",children:[]},{level:2,title:"配置永久化与开机自启",slug:"配置永久化与开机自启",link:"#配置永久化与开机自启",children:[]}],path:"/document/level-2/tproxy.html",pathLocale:"/",extraFields:[]},{title:"TProxy 透明代理 (ipv4 and ipv6)",headers:[{level:2,title:"Xray 配置",slug:"xray-配置",link:"#xray-配置",children:[{level:3,title:"客户端配置",slug:"客户端配置",link:"#客户端配置",children:[]},{level:3,title:"服务端配置",slug:"服务端配置",link:"#服务端配置",children:[]}]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",link:"#netfilter-配置",children:[{level:3,title:"首先设置策略路由",slug:"首先设置策略路由",link:"#首先设置策略路由",children:[]},{level:3,title:"使用 iptables",slug:"使用-iptables",link:"#使用-iptables",children:[]},{level:3,title:"使用 nftables",slug:"使用-nftables",link:"#使用-nftables",children:[]},{level:3,title:"开机自动运行 Netfilter 配置",slug:"开机自动运行-netfilter-配置",link:"#开机自动运行-netfilter-配置",children:[]}]},{level:2,title:"局域网设备上网设置",slug:"局域网设备上网设置",link:"#局域网设备上网设置",children:[{level:3,title:"方法一",slug:"方法一",link:"#方法一",children:[]},{level:3,title:"方法二",slug:"方法二",link:"#方法二",children:[]}]},{level:2,title:"Finally",slug:"finally",link:"#finally",children:[]},{level:2,title:"写在最后",slug:"写在最后",link:"#写在最后",children:[]}],path:"/document/level-2/tproxy_ipv4_and_ipv6.html",pathLocale:"/",extraFields:[]},{title:"流量统计",headers:[{level:2,title:"查看流量信息",slug:"查看流量信息",link:"#查看流量信息",children:[]},{level:2,title:"流量信息的处理",slug:"流量信息的处理",link:"#流量信息的处理",children:[]}],path:"/document/level-2/traffic_stats.html",pathLocale:"/",extraFields:[]},{title:"通过 Cloudflare Warp 增强代理安全性",headers:[{level:2,title:"申请 Warp 账户",slug:"申请-warp-账户",link:"#申请-warp-账户",children:[{level:3,title:"感谢 Cloudflare 推动自由的互联网,现在你可以免费使用 Warp 服务,连接的时候会根据出口自动选择最近的服务器",slug:"感谢-cloudflare-推动自由的互联网-现在你可以免费使用-warp-服务-连接的时候会根据出口自动选择最近的服务器",link:"#感谢-cloudflare-推动自由的互联网-现在你可以免费使用-warp-服务-连接的时候会根据出口自动选择最近的服务器",children:[]}]},{level:2,title:"在服务端分流回国流量至 warp",slug:"在服务端分流回国流量至-warp",link:"#在服务端分流回国流量至-warp",children:[]},{level:2,title:"客户端使用 warp 链式代理",slug:"客户端使用-warp-链式代理",link:"#客户端使用-warp-链式代理",children:[]}],path:"/document/level-2/warp.html",pathLocale:"/",extraFields:[]},{title:"大史记",headers:[{level:2,title:"2021.4.6",slug:"_2021-4-6",link:"#_2021-4-6",children:[]},{level:2,title:"2021.4.4",slug:"_2021-4-4",link:"#_2021-4-4",children:[]},{level:2,title:"2021.4.1 v1.4.2",slug:"_2021-4-1-v1-4-2",link:"#_2021-4-1-v1-4-2",children:[]},{level:2,title:"2021.3.25",slug:"_2021-3-25",link:"#_2021-3-25",children:[]},{level:2,title:"2021.3.15",slug:"_2021-3-15",link:"#_2021-3-15",children:[]},{level:2,title:"2021.3.14 v1.4.0",slug:"_2021-3-14-v1-4-0",link:"#_2021-3-14-v1-4-0",children:[]},{level:2,title:"2021.3.3 1.3.1",slug:"_2021-3-3-1-3-1",link:"#_2021-3-3-1-3-1",children:[]},{level:2,title:"2021.2.14 1.3.0",slug:"_2021-2-14-1-3-0",link:"#_2021-2-14-1-3-0",children:[]},{level:2,title:"2021.01.31 1.2.4",slug:"_2021-01-31-1-2-4",link:"#_2021-01-31-1-2-4",children:[]},{level:2,title:"2021.01.25",slug:"_2021-01-25",link:"#_2021-01-25",children:[]},{level:2,title:"2021.01.22 1.2.3",slug:"_2021-01-22-1-2-3",link:"#_2021-01-22-1-2-3",children:[]},{level:2,title:"2021.01.19",slug:"_2021-01-19",link:"#_2021-01-19",children:[]},{level:2,title:"2021.01.17",slug:"_2021-01-17",link:"#_2021-01-17",children:[]},{level:2,title:"2021.01.15 1.2.2",slug:"_2021-01-15-1-2-2",link:"#_2021-01-15-1-2-2",children:[]},{level:2,title:"2021.01.12",slug:"_2021-01-12",link:"#_2021-01-12",children:[]},{level:2,title:"2021.01.10 1.2.1",slug:"_2021-01-10-1-2-1",link:"#_2021-01-10-1-2-1",children:[]},{level:2,title:"2021.01.07",slug:"_2021-01-07",link:"#_2021-01-07",children:[]},{level:2,title:"2021.01.05",slug:"_2021-01-05",link:"#_2021-01-05",children:[]},{level:2,title:"2021.01.03",slug:"_2021-01-03",link:"#_2021-01-03",children:[]},{level:2,title:"2021.01.01",slug:"_2021-01-01",link:"#_2021-01-01",children:[]},{level:2,title:"2020.12.29",slug:"_2020-12-29",link:"#_2020-12-29",children:[]},{level:2,title:"2020.12.25 1.1.5",slug:"_2020-12-25-1-1-5",link:"#_2020-12-25-1-1-5",children:[]},{level:2,title:"2020.12.24",slug:"_2020-12-24",link:"#_2020-12-24",children:[]},{level:2,title:"2020.12.23",slug:"_2020-12-23",link:"#_2020-12-23",children:[]},{level:2,title:"2020.12.21",slug:"_2020-12-21",link:"#_2020-12-21",children:[]},{level:2,title:"2020.12.18 1.1.4",slug:"_2020-12-18-1-1-4",link:"#_2020-12-18-1-1-4",children:[]},{level:2,title:"2020.12.17",slug:"_2020-12-17",link:"#_2020-12-17",children:[]},{level:2,title:"2020.12.15",slug:"_2020-12-15",link:"#_2020-12-15",children:[]},{level:2,title:"2020.12.11 1.1.3",slug:"_2020-12-11-1-1-3",link:"#_2020-12-11-1-1-3",children:[]},{level:2,title:"2020.12.06 1.1.2",slug:"_2020-12-06-1-1-2",link:"#_2020-12-06-1-1-2",children:[]},{level:2,title:"2020.12.04",slug:"_2020-12-04",link:"#_2020-12-04",children:[]},{level:2,title:"2020.11.27",slug:"_2020-11-27",link:"#_2020-11-27",children:[]},{level:2,title:"2020.11.25 1.0.0",slug:"_2020-11-25-1-0-0",link:"#_2020-11-25-1-0-0",children:[]},{level:2,title:"2020.11.23",slug:"_2020-11-23",link:"#_2020-11-23",children:[]}],path:"/en/about/news.html",pathLocale:"/en/",extraFields:[]},{title:"Configurations",headers:[{level:2,title:"Overview",slug:"overview",link:"#overview",children:[]},{level:2,title:"Basic Configuration Modules",slug:"basic-configuration-modules",link:"#basic-configuration-modules",children:[]}],path:"/en/config/",pathLocale:"/en/",extraFields:[]},{title:"API Interface",headers:[{level:2,title:"ApiObject",slug:"apiobject",link:"#apiobject",children:[]},{level:2,title:"Related Configuration",slug:"related-configuration",link:"#related-configuration",children:[]},{level:2,title:"Supported API List",slug:"supported-api-list",link:"#supported-api-list",children:[{level:3,title:"HandlerService",slug:"handlerservice",link:"#handlerservice",children:[]},{level:3,title:"LoggerService",slug:"loggerservice",link:"#loggerservice",children:[]},{level:3,title:"StatsService",slug:"statsservice",link:"#statsservice",children:[]},{level:3,title:"ReflectionService",slug:"reflectionservice",link:"#reflectionservice",children:[]}]},{level:2,title:"API Calling Example",slug:"api-calling-example",link:"#api-calling-example",children:[]}],path:"/en/config/api.html",pathLocale:"/en/",extraFields:[]},{title:"Built-in DNS Server",headers:[{level:2,title:"DNS Server",slug:"dns-server",link:"#dns-server",children:[]},{level:2,title:"DNS Processing Flow",slug:"dns-processing-flow",link:"#dns-processing-flow",children:[]},{level:2,title:"DnsObject",slug:"dnsobject",link:"#dnsobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/dns.html",pathLocale:"/en/",extraFields:[]},{title:"FakeDNS",headers:[{level:2,title:"FakeDNSObject",slug:"fakednsobject",link:"#fakednsobject",children:[{level:3,title:"How to use?",slug:"how-to-use",link:"#how-to-use",children:[]},{level:3,title:"Using with other types of DNS",slug:"using-with-other-types-of-dns",link:"#using-with-other-types-of-dns",children:[]}]}],path:"/en/config/fakedns.html",pathLocale:"/en/",extraFields:[]},{title:"Inbound Proxy",headers:[{level:2,title:"InboundObject",slug:"inboundobject",link:"#inboundobject",children:[{level:3,title:"SniffingObject",slug:"sniffingobject",link:"#sniffingobject",children:[]},{level:3,title:"AllocateObject",slug:"allocateobject",link:"#allocateobject",children:[]}]}],path:"/en/config/inbound.html",pathLocale:"/en/",extraFields:[]},{title:"Log Configuration",headers:[{level:2,title:"LogObject",slug:"logobject",link:"#logobject",children:[]}],path:"/en/config/log.html",pathLocale:"/en/",extraFields:[]},{title:"Metrics",headers:[{level:2,title:"Related configurations",slug:"related-configurations",link:"#related-configurations",children:[]},{level:2,title:"Usage",slug:"usage",link:"#usage",children:[{level:3,title:"pprof",slug:"pprof",link:"#pprof",children:[]},{level:3,title:"expvars",slug:"expvars",link:"#expvars",children:[]},{level:3,title:"Additional",slug:"additional",link:"#additional",children:[]}]}],path:"/en/config/metrics.html",pathLocale:"/en/",extraFields:[]},{title:"Outbound Proxies",headers:[{level:2,title:"OutboundObject",slug:"outboundobject",link:"#outboundobject",children:[{level:3,title:"ProxySettingsObject",slug:"proxysettingsobject",link:"#proxysettingsobject",children:[]},{level:3,title:"MuxObject",slug:"muxobject",link:"#muxobject",children:[]}]}],path:"/en/config/outbound.html",pathLocale:"/en/",extraFields:[]},{title:"Local Policy",headers:[{level:2,title:"PolicyObject",slug:"policyobject",link:"#policyobject",children:[{level:3,title:"LevelPolicyObject",slug:"levelpolicyobject",link:"#levelpolicyobject",children:[]},{level:3,title:"SystemPolicyObject",slug:"systempolicyobject",link:"#systempolicyobject",children:[]}]}],path:"/en/config/policy.html",pathLocale:"/en/",extraFields:[]},{title:"Reverse Proxy",headers:[{level:2,title:"ReverseObject",slug:"reverseobject",link:"#reverseobject",children:[{level:3,title:"BridgeObject",slug:"bridgeobject",link:"#bridgeobject",children:[]},{level:3,title:"PortalObject",slug:"portalobject",link:"#portalobject",children:[]}]},{level:2,title:"Complete Configuration Example",slug:"complete-configuration-example",link:"#complete-configuration-example",children:[{level:3,title:"Bridge Configuration",slug:"bridge-configuration",link:"#bridge-configuration",children:[]},{level:3,title:"Portal Configuration",slug:"portal-configuration",link:"#portal-configuration",children:[]}]}],path:"/en/config/reverse.html",pathLocale:"/en/",extraFields:[]},{title:"Routing",headers:[{level:2,title:"RoutingObject",slug:"routingobject",link:"#routingobject",children:[{level:3,title:"RuleObject",slug:"ruleobject",link:"#ruleobject",children:[]},{level:3,title:"BalancerObject",slug:"balancerobject",link:"#balancerobject",children:[]},{level:3,title:"Predefined Domain Lists",slug:"predefined-domain-lists",link:"#predefined-domain-lists",children:[]}]}],path:"/en/config/routing.html",pathLocale:"/en/",extraFields:[]},{title:"Traffic Statistics",headers:[{level:2,title:"StatsObject",slug:"statsobject",link:"#statsobject",children:[]},{level:2,title:"Retrieving Traffic Statistics",slug:"retrieving-traffic-statistics",link:"#retrieving-traffic-statistics",children:[]}],path:"/en/config/stats.html",pathLocale:"/en/",extraFields:[]},{title:"Transport",headers:[{level:2,title:"TransportObject",slug:"transportobject",link:"#transportobject",children:[]},{level:2,title:"StreamSettingsObject",slug:"streamsettingsobject",link:"#streamsettingsobject",children:[{level:3,title:"TLSObject",slug:"tlsobject",link:"#tlsobject",children:[]},{level:3,title:"SockoptObject",slug:"sockoptobject",link:"#sockoptobject",children:[]}]}],path:"/en/config/transport.html",pathLocale:"/en/",extraFields:[]},{title:"Development Guide",headers:[{level:2,title:"Compile Documentation",slug:"compile-documentation",link:"#compile-documentation",children:[]},{level:2,title:"Design Concept",slug:"design-concept",link:"#design-concept",children:[]},{level:2,title:"Development Standards",slug:"development-standards",link:"#development-standards",children:[]},{level:2,title:"Protocol Details",slug:"protocol-details",link:"#protocol-details",children:[{level:3,title:"VLESS Protocol",slug:"vless-protocol",link:"#vless-protocol",children:[]},{level:3,title:"VMess Protocol",slug:"vmess-protocol",link:"#vmess-protocol",children:[]},{level:3,title:"Mux.Cool Protocol",slug:"mux-cool-protocol",link:"#mux-cool-protocol",children:[]},{level:3,title:"mKCP Protocol",slug:"mkcp-protocol",link:"#mkcp-protocol",children:[]}]}],path:"/en/development/",pathLocale:"/en/",extraFields:[]},{title:"Quick Start",headers:[{level:2,title:"Download and Install",slug:"download-and-install",link:"#download-and-install",children:[]},{level:2,title:"Configure and Run",slug:"configure-and-run",link:"#configure-and-run",children:[]},{level:2,title:"Command Parameters",slug:"command-parameters",link:"#command-parameters",children:[]},{level:2,title:"Improve Documents",slug:"improve-documents",link:"#improve-documents",children:[]},{level:2,title:"Beginner Tutorial",slug:"beginner-tutorial",link:"#beginner-tutorial",children:[]},{level:2,title:"Getting Started Tips",slug:"getting-started-tips",link:"#getting-started-tips",children:[]},{level:2,title:"Advanced Documentation",slug:"advanced-documentation",link:"#advanced-documentation",children:[]}],path:"/en/document/",pathLocale:"/en/",extraFields:[]},{title:"Command Parameters",headers:[{level:2,title:"Get Basic Commands",slug:"get-basic-commands",link:"#get-basic-commands",children:[{level:3,title:"xray run",slug:"xray-run",link:"#xray-run",children:[]},{level:3,title:"xray version",slug:"xray-version",link:"#xray-version",children:[]},{level:3,title:"xray api",slug:"xray-api",link:"#xray-api",children:[]},{level:3,title:"xray tls",slug:"xray-tls",link:"#xray-tls",children:[]},{level:3,title:"xray uuid",slug:"xray-uuid",link:"#xray-uuid",children:[]},{level:3,title:"xray x25519",slug:"xray-x25519",link:"#xray-x25519",children:[]},{level:3,title:"xray wg",slug:"xray-wg",link:"#xray-wg",children:[]}]}],path:"/en/document/command.html",pathLocale:"/en/",extraFields:[]},{title:"Configure and Run",headers:[{level:2,title:"Server Configuration",slug:"server-configuration",link:"#server-configuration",children:[]},{level:2,title:"Client Configuration",slug:"client-configuration",link:"#client-configuration",children:[]},{level:2,title:"Run",slug:"run",link:"#run",children:[]}],path:"/en/document/config.html",pathLocale:"/en/",extraFields:[]},{title:"Contribute to Project X's Document",headers:[{level:2,title:"Improve Document",slug:"improve-document",link:"#improve-document",children:[]},{level:2,title:"Found Problems?",slug:"found-problems",link:"#found-problems",children:[]}],path:"/en/document/document.html",pathLocale:"/en/",extraFields:[]},{title:"Download and Install",headers:[{level:2,title:"Platform Support",slug:"platform-support",link:"#platform-support",children:[]},{level:2,title:"Download Xray",slug:"download-xray",link:"#download-xray",children:[]},{level:2,title:"Verify the Installation Package",slug:"verify-the-installation-package",link:"#verify-the-installation-package",children:[]},{level:2,title:"Install on Windows",slug:"install-on-windows",link:"#install-on-windows",children:[]},{level:2,title:"Install on macOS",slug:"install-on-macos",link:"#install-on-macos",children:[]},{level:2,title:"Install on Linux",slug:"install-on-linux",link:"#install-on-linux",children:[{level:3,title:"Install Script",slug:"install-script",link:"#install-script",children:[]},{level:3,title:"Arch Linux",slug:"arch-linux",link:"#arch-linux",children:[]},{level:3,title:"Linuxbrew",slug:"linuxbrew",link:"#linuxbrew",children:[]},{level:3,title:"Debian",slug:"debian",link:"#debian",children:[]}]},{level:2,title:"Install via Docker",slug:"install-via-docker",link:"#install-via-docker",children:[{level:3,title:"The File Structure of the Docker Image",slug:"the-file-structure-of-the-docker-image",link:"#the-file-structure-of-the-docker-image",children:[]}]}],path:"/en/document/install.html",pathLocale:"/en/",extraFields:[]},{title:"透明代理入门",headers:[{level:2,title:"什么是透明代理",slug:"什么是透明代理",link:"#什么是透明代理",children:[]},{level:2,title:"透明代理的实现",slug:"透明代理的实现",link:"#透明代理的实现",children:[{level:3,title:"tun2socks",slug:"tun2socks",link:"#tun2socks",children:[]},{level:3,title:"iptables/nftables",slug:"iptables-nftables",link:"#iptables-nftables",children:[]}]},{level:2,title:"iptables 实现透明代理原理",slug:"iptables-实现透明代理原理",link:"#iptables-实现透明代理原理",children:[]},{level:2,title:"透明代理难在哪里",slug:"透明代理难在哪里",link:"#透明代理难在哪里",children:[]},{level:2,title:"从零开始一步步实现基于 iptables-tproxy 的透明代理",slug:"从零开始一步步实现基于-iptables-tproxy-的透明代理",link:"#从零开始一步步实现基于-iptables-tproxy-的透明代理",children:[{level:3,title:"在开始之前,你需要有一定的基础知识:",slug:"在开始之前-你需要有一定的基础知识",link:"#在开始之前-你需要有一定的基础知识",children:[]},{level:3,title:"前期准备工作",slug:"前期准备工作",link:"#前期准备工作",children:[]},{level:3,title:"首先,我们先试试做到第一阶段",slug:"首先-我们先试试做到第一阶段",link:"#首先-我们先试试做到第一阶段",children:[]},{level:3,title:"第二阶段",slug:"第二阶段",link:"#第二阶段",children:[]},{level:3,title:"第三阶段",slug:"第三阶段",link:"#第三阶段",children:[]},{level:3,title:"第四阶段",slug:"第四阶段",link:"#第四阶段",children:[]},{level:3,title:"代理 ipv6",slug:"代理-ipv6",link:"#代理-ipv6",children:[]}]}],path:"/document/level-2/transparent_proxy/transparent_proxy.html",pathLocale:"/",extraFields:[]},{title:"Browser Dialer",headers:[{level:2,title:"Background",slug:"background",link:"#background",children:[]},{level:2,title:"Xray & JS",slug:"xray-js",link:"#xray-js",children:[]},{level:2,title:"Early data",slug:"early-data",link:"#early-data",children:[]},{level:2,title:"Configuration",slug:"configuration",link:"#configuration",children:[]}],path:"/en/config/features/browser_dialer.html",pathLocale:"/en/",extraFields:[]},{title:"Environment Variables",headers:[{level:2,title:"Xray Asset Location",slug:"xray-asset-location",link:"#xray-asset-location",children:[]},{level:2,title:"Configuration File Location",slug:"configuration-file-location",link:"#configuration-file-location",children:[]},{level:2,title:"Multiple Configuration Directories",slug:"multiple-configuration-directories",link:"#multiple-configuration-directories",children:[]}],path:"/en/config/features/env.html",pathLocale:"/en/",extraFields:[]},{title:"Fallback",headers:[{level:2,title:"fallbacks configuration",slug:"fallbacks-configuration",link:"#fallbacks-configuration",children:[{level:3,title:"FallbackObject",slug:"fallbackobject",link:"#fallbackobject",children:[]},{level:3,title:"Additional Information",slug:"additional-information",link:"#additional-information",children:[]}]},{level:2,title:"Fallbacks design theory",slug:"fallbacks-design-theory",link:"#fallbacks-design-theory",children:[]}],path:"/en/config/features/fallback.html",pathLocale:"/en/",extraFields:[]},{title:"Multi-file configuration",headers:[{level:2,title:"Multi-file startup",slug:"multi-file-startup",link:"#multi-file-startup",children:[]},{level:2,title:"Rule Explaination",slug:"rule-explaination",link:"#rule-explaination",children:[{level:3,title:"Normal Objects({})",slug:"normal-objects",link:"#normal-objects",children:[]},{level:3,title:"Arrays([])",slug:"arrays",link:"#arrays",children:[]}]},{level:2,title:"Recommended Multi-file List",slug:"recommended-multi-file-list",link:"#recommended-multi-file-list",children:[]}],path:"/en/config/features/multiple.html",pathLocale:"/en/",extraFields:[]},{title:"Deep analysis of XTLS",headers:[],path:"/en/config/features/xtls.html",pathLocale:"/en/",extraFields:[]},{title:"Dokodemo-Door",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[]},{level:2,title:"Transparent Proxy Configuration Example",slug:"transparent-proxy-configuration-example",link:"#transparent-proxy-configuration-example",children:[]}],path:"/en/config/inbounds/dokodemo.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP",headers:[{level:3,title:"AccountObject",slug:"accountobject",link:"#accountobject",children:[]}],path:"/en/config/inbounds/http.html",pathLocale:"/en/",extraFields:[]},{title:"Shadowsocks",headers:[{level:3,title:"Supported Encryption Methods",slug:"supported-encryption-methods",link:"#supported-encryption-methods",children:[]},{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[]},{level:2,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}],path:"/en/config/inbounds/shadowsocks.html",pathLocale:"/en/",extraFields:[]},{title:"SOCKS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",link:"#accountobject",children:[]}]}],path:"/en/config/inbounds/socks.html",pathLocale:"/en/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}]}],path:"/en/config/inbounds/trojan.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}]}],path:"/en/config/inbounds/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",link:"#inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",link:"#clientobject",children:[]}]}],path:"/en/config/inbounds/vmess.html",pathLocale:"/en/",extraFields:[]},{title:"Blackhole",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ResponseObject",slug:"responseobject",link:"#responseobject",children:[]}]}],path:"/en/config/outbounds/blackhole.html",pathLocale:"/en/",extraFields:[]},{title:"DNS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[]},{level:2,title:"DNS Configuration Example",slug:"dns-configuration-example",link:"#dns-configuration-example",children:[]}],path:"/en/config/outbounds/dns.html",pathLocale:"/en/",extraFields:[]},{title:"Freedom",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[]}],path:"/en/config/outbounds/freedom.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/outbounds/http.html",pathLocale:"/en/",extraFields:[]},{title:"Loopback",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"How to use?",slug:"how-to-use",link:"#how-to-use",children:[]}]}],path:"/en/config/outbounds/loopback.html",pathLocale:"/en/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/outbounds/shadowsocks.html",pathLocale:"/en/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/outbounds/socks.html",pathLocale:"/en/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/outbounds/trojan.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]},{level:3,title:"UserObject",slug:"userobject",link:"#userobject",children:[]}]}],path:"/en/config/outbounds/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",link:"#serverobject",children:[]}]}],path:"/en/config/outbounds/vmess.html",pathLocale:"/en/",extraFields:[]},{title:"Wireguard",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",link:"#outboundconfigurationobject",children:[{level:3,title:"Peers",slug:"peers",link:"#peers",children:[]}]}],path:"/en/config/outbounds/wireguard.html",pathLocale:"/en/",extraFields:[]},{title:"Domain Socket",headers:[{level:2,title:"DomainSocketObject",slug:"domainsocketobject",link:"#domainsocketobject",children:[]}],path:"/en/config/transports/domainsocket.html",pathLocale:"/en/",extraFields:[]},{title:"gRPC",headers:[{level:2,title:"GRPCObject",slug:"grpcobject",link:"#grpcobject",children:[]}],path:"/en/config/transports/grpc.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP/2",headers:[{level:2,title:"HttpObject",slug:"httpobject",link:"#httpobject",children:[]}],path:"/en/config/transports/h2.html",pathLocale:"/en/",extraFields:[]},{title:"HTTPUpgrade",headers:[{level:2,title:"HttpUpgradeObject",slug:"httpupgradeobject",link:"#httpupgradeobject",children:[]}],path:"/en/config/transports/httpupgrade.html",pathLocale:"/en/",extraFields:[]},{title:"mKCP",headers:[{level:2,title:"KcpObject",slug:"kcpobject",link:"#kcpobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",link:"#headerobject",children:[]}]},{level:2,title:"Special Thanks",slug:"special-thanks",link:"#special-thanks",children:[]},{level:2,title:"Improvements to the KCP protocol",slug:"improvements-to-the-kcp-protocol",link:"#improvements-to-the-kcp-protocol",children:[{level:3,title:"smaller protocol header",slug:"smaller-protocol-header",link:"#smaller-protocol-header",children:[]},{level:3,title:"ACK packet retransmission",slug:"ack-packet-retransmission",link:"#ack-packet-retransmission",children:[]},{level:3,title:"Connection state control",slug:"connection-state-control",link:"#connection-state-control",children:[]}]}],path:"/en/config/transports/mkcp.html",pathLocale:"/en/",extraFields:[]},{title:"QUIC",headers:[{level:2,title:"QuicObject",slug:"quicobject",link:"#quicobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",link:"#headerobject",children:[]}]}],path:"/en/config/transports/quic.html",pathLocale:"/en/",extraFields:[]},{title:"TCP",headers:[{level:2,title:"TcpObject",slug:"tcpobject",link:"#tcpobject",children:[{level:3,title:"NoneHeaderObject",slug:"noneheaderobject",link:"#noneheaderobject",children:[]},{level:3,title:"HttpHeaderObject",slug:"httpheaderobject",link:"#httpheaderobject",children:[]}]}],path:"/en/config/transports/tcp.html",pathLocale:"/en/",extraFields:[]},{title:"WebSocket",headers:[{level:2,title:"WebSocketObject",slug:"websocketobject",link:"#websocketobject",children:[]},{level:2,title:"Browser Dialer",slug:"browser-dialer",link:"#browser-dialer",children:[]}],path:"/en/config/transports/websocket.html",pathLocale:"/en/",extraFields:[]},{title:"Compile the document",headers:[{level:2,title:"Preparatory Work",slug:"preparatory-work",link:"#preparatory-work",children:[]},{level:2,title:"Pull Xray source code",slug:"pull-xray-source-code",link:"#pull-xray-source-code",children:[]},{level:2,title:"Build Binary",slug:"build-binary",link:"#build-binary",children:[{level:3,title:"Windows(Powershell):",slug:"windows-powershell",link:"#windows-powershell",children:[]},{level:3,title:"macOS, Linux:",slug:"macos-linux",link:"#macos-linux",children:[]}]},{level:2,title:"Reproducible Build:",slug:"reproducible-build",link:"#reproducible-build",children:[]}],path:"/en/development/intro/compile.html",pathLocale:"/en/",extraFields:[]},{title:"Design Objectives",headers:[{level:2,title:"Architecture",slug:"architecture",link:"#architecture",children:[{level:3,title:"Application Layer",slug:"application-layer",link:"#application-layer",children:[]},{level:3,title:"Proxy Layer",slug:"proxy-layer",link:"#proxy-layer",children:[]},{level:3,title:"Transport Layer",slug:"transport-layer",link:"#transport-layer",children:[]}]}],path:"/en/development/intro/design.html",pathLocale:"/en/",extraFields:[]},{title:"Development Standards",headers:[{level:2,title:"Basic",slug:"basic",link:"#basic",children:[{level:3,title:"Version Control",slug:"version-control",link:"#version-control",children:[]},{level:3,title:"Branch",slug:"branch",link:"#branch",children:[]},{level:3,title:"Release",slug:"release",link:"#release",children:[]},{level:3,title:"Citing other projects",slug:"citing-other-projects",link:"#citing-other-projects",children:[]}]},{level:2,title:"Development Process",slug:"development-process",link:"#development-process",children:[{level:3,title:"Before Writing Code",slug:"before-writing-code",link:"#before-writing-code",children:[]},{level:3,title:"Modify the code",slug:"modify-the-code",link:"#modify-the-code",children:[]},{level:3,title:"Pull Request",slug:"pull-request",link:"#pull-request",children:[]},{level:3,title:"Modifying Code",slug:"modifying-code",link:"#modifying-code",children:[]}]},{level:2,title:"Xray Coding Guidelines",slug:"xray-coding-guidelines",link:"#xray-coding-guidelines",children:[{level:3,title:"Code Structure",slug:"code-structure",link:"#code-structure",children:[]},{level:3,title:"Coding Standards",slug:"coding-standards",link:"#coding-standards",children:[]}]}],path:"/en/development/intro/guide.html",pathLocale:"/en/",extraFields:[]},{title:"mKCP Protocol",headers:[{level:2,title:"Version",slug:"version",link:"#version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",link:"#dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",link:"#underlying-protocol",children:[]},{level:3,title:"Functions",slug:"functions",link:"#functions",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",link:"#communication-process",children:[]},{level:2,title:"Data Format",slug:"data-format",link:"#data-format",children:[{level:3,title:"Data Packet",slug:"data-packet",link:"#data-packet",children:[]},{level:3,title:"Data snippet",slug:"data-snippet",link:"#data-snippet",children:[]},{level:3,title:"Confirmation snippet",slug:"confirmation-snippet",link:"#confirmation-snippet",children:[]},{level:3,title:"Heartbeat Fragments",slug:"heartbeat-fragments",link:"#heartbeat-fragments",children:[]}]}],path:"/en/development/protocols/mkcp.html",pathLocale:"/en/",extraFields:[]},{title:"Mux.Cool Protocol",headers:[{level:2,title:"Version",slug:"version",link:"#version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",link:"#dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",link:"#underlying-protocol",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",link:"#communication-process",children:[{level:3,title:"Client behavior",slug:"client-behavior",link:"#client-behavior",children:[]},{level:3,title:"Server-side behavior",slug:"server-side-behavior",link:"#server-side-behavior",children:[]}]},{level:2,title:"Data Format",slug:"data-format",link:"#data-format",children:[{level:3,title:"Frame Format",slug:"frame-format",link:"#frame-format",children:[]},{level:3,title:"Metadata",slug:"metadata",link:"#metadata",children:[]},{level:3,title:"New Sublink (New)",slug:"new-sublink-new",link:"#new-sublink-new",children:[]},{level:3,title:"Keep sub-connections",slug:"keep-sub-connections",link:"#keep-sub-connections",children:[]},{level:3,title:"End",slug:"end",link:"#end",children:[]},{level:3,title:"KeepAlive",slug:"keepalive",link:"#keepalive",children:[]}]},{level:2,title:"Application",slug:"application",link:"#application",children:[]}],path:"/en/development/protocols/muxcool.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS Protocol",headers:[{level:2,title:"Request & Response",slug:"request-response",link:"#request-response",children:[]},{level:2,title:"ProtoBuf",slug:"protobuf",link:"#protobuf",children:[]},{level:2,title:"Flow",slug:"flow",link:"#flow",children:[{level:3,title:"Flow Control (Formerly Traffic Scheduler)",slug:"flow-control-formerly-traffic-scheduler",link:"#flow-control-formerly-traffic-scheduler",children:[]}]},{level:2,title:"Encryption",slug:"encryption",link:"#encryption",children:[]},{level:2,title:"UDP issues",slug:"udp-issues",link:"#udp-issues",children:[]},{level:2,title:"Client Development Guide",slug:"client-development-guide",link:"#client-development-guide",children:[]},{level:2,title:"VLESS Sharing Link Standard",slug:"vless-sharing-link-standard",link:"#vless-sharing-link-standard",children:[]}],path:"/en/development/protocols/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess Protocol",headers:[{level:2,title:"Version",slug:"version",link:"#version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",link:"#dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",link:"#underlying-protocol",children:[]},{level:3,title:"User ID",slug:"user-id",link:"#user-id",children:[]},{level:3,title:"Functions",slug:"functions",link:"#functions",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",link:"#communication-process",children:[]},{level:2,title:"Client Request",slug:"client-request",link:"#client-request",children:[{level:3,title:"Authentication Information",slug:"authentication-information",link:"#authentication-information",children:[]},{level:3,title:"Command Section",slug:"command-section",link:"#command-section",children:[]},{level:3,title:"Data Section",slug:"data-section",link:"#data-section",children:[]}]},{level:2,title:"Server Response",slug:"server-response",link:"#server-response",children:[{level:3,title:"Dynamic Port Instructions",slug:"dynamic-port-instructions",link:"#dynamic-port-instructions",children:[]}]},{level:2,title:"Comment",slug:"comment",link:"#comment",children:[]}],path:"/en/development/protocols/vmess.html",pathLocale:"/en/",extraFields:[]},{title:"Plain and Simple Language",headers:[],path:"/en/document/level-0/",pathLocale:"/en/",extraFields:[]},{title:"[Chapter 1] Simple and Plain Language",headers:[{level:2,title:"1.1 Who is this document written for?",slug:"_1-1-who-is-this-document-written-for",link:"#_1-1-who-is-this-document-written-for",children:[]},{level:2,title:"1.2 Who is this document not written for?",slug:"_1-2-who-is-this-document-not-written-for",link:"#_1-2-who-is-this-document-not-written-for",children:[]},{level:2,title:"1.3 Declaration and Other Statements",slug:"_1-3-declaration-and-other-statements",link:"#_1-3-declaration-and-other-statements",children:[]},{level:2,title:"1.4 Why is self-hosting a challenge?",slug:"_1-4-why-is-self-hosting-a-challenge",link:"#_1-4-why-is-self-hosting-a-challenge",children:[]},{level:2,title:'1.5 "Why not just use the airport?"',slug:"_1-5-why-not-just-use-the-airport",link:"#_1-5-why-not-just-use-the-airport",children:[]},{level:2,title:"1.6 So should you build your own website?",slug:"_1-6-so-should-you-build-your-own-website",link:"#_1-6-so-should-you-build-your-own-website",children:[]},{level:2,title:"1.7 Some digressions",slug:"_1-7-some-digressions",link:"#_1-7-some-digressions",children:[]},{level:2,title:"1.8 Your Progress",slug:"_1-8-your-progress",link:"#_1-8-your-progress",children:[]}],path:"/en/document/level-0/ch01-preface.html",pathLocale:"/en/",extraFields:[]},{title:"[Chapter 2] Preparation of Raw Materials",headers:[{level:2,title:"2.1 Acquiring a VPS",slug:"_2-1-acquiring-a-vps",link:"#_2-1-acquiring-a-vps",children:[]},{level:2,title:"2.2 Obtaining a Desired Domain Name",slug:"_2-2-obtaining-a-desired-domain-name",link:"#_2-2-obtaining-a-desired-domain-name",children:[]},{level:2,title:"2.3 Software you need to install on your local computer",slug:"_2-3-software-you-need-to-install-on-your-local-computer",link:"#_2-3-software-you-need-to-install-on-your-local-computer",children:[]},{level:2,title:"2.4 Your Progress",slug:"_2-4-your-progress",link:"#_2-4-your-progress",children:[]}],path:"/en/document/level-0/ch02-preparation.html",pathLocale:"/en/",extraFields:[]},{title:"[Chapter 3] Remote Login",headers:[{level:2,title:"3.1 Remote Login to VPS (PuTTY)",slug:"_3-1-remote-login-to-vps-putty",link:"#_3-1-remote-login-to-vps-putty",children:[]},{level:2,title:"3.2 Successfully Logging in SSH! Introduction to Command Line Interface!",slug:"_3-2-successfully-logging-in-ssh-introduction-to-command-line-interface",link:"#_3-2-successfully-logging-in-ssh-introduction-to-command-line-interface",children:[]},{level:2,title:"3.3 Updating software on Linux for the first time!",slug:"_3-3-updating-software-on-linux-for-the-first-time",link:"#_3-3-updating-software-on-linux-for-the-first-time",children:[]},{level:2,title:"3.4 Your Progress",slug:"_3-4-your-progress",link:"#_3-4-your-progress",children:[]}],path:"/en/document/level-0/ch03-ssh.html",pathLocale:"/en/",extraFields:[]},{title:"[Chapter 4] Security and Protection",headers:[{level:2,title:"4.1 Why Do We Need Security Protection?",slug:"_4-1-why-do-we-need-security-protection",link:"#_4-1-why-do-we-need-security-protection",children:[]},{level:2,title:"4.2 What are the specific risks",slug:"_4-2-what-are-the-specific-risks",link:"#_4-2-what-are-the-specific-risks",children:[]},{level:2,title:"4.3 What security measures do we need to take",slug:"_4-3-what-security-measures-do-we-need-to-take",link:"#_4-3-what-security-measures-do-we-need-to-take",children:[]},{level:2,title:"4.4 Change the SSH Remote Login Port to a Non-22 Port",slug:"_4-4-change-the-ssh-remote-login-port-to-a-non-22-port",link:"#_4-4-change-the-ssh-remote-login-port-to-a-non-22-port",children:[]},{level:2,title:"4.5 Creating a New User Without Root Access",slug:"_4-5-creating-a-new-user-without-root-access",link:"#_4-5-creating-a-new-user-without-root-access",children:[]},{level:2,title:"4.8 Your Progress",slug:"_4-8-your-progress",link:"#_4-8-your-progress",children:[]}],path:"/en/document/level-0/ch04-security.html",pathLocale:"/en/",extraFields:[]},{title:"Chapter 5: Website Building",headers:[{level:2,title:"5.1 Why should you create a website?",slug:"_5-1-why-should-you-create-a-website",link:"#_5-1-why-should-you-create-a-website",children:[]},{level:2,title:"5.2 Log in to VPS, install and run Nginx",slug:"_5-2-log-in-to-vps-install-and-run-nginx",link:"#_5-2-log-in-to-vps-install-and-run-nginx",children:[]},{level:2,title:"5.3 Create the simplest web page",slug:"_5-3-create-the-simplest-web-page",link:"#_5-3-create-the-simplest-web-page",children:[]},{level:2,title:"5.4 Common error explanations",slug:"_5-4-common-error-explanations",link:"#_5-4-common-error-explanations",children:[]}],path:"/en/document/level-0/ch05-webpage.html",pathLocale:"/en/",extraFields:[]},{title:"[Chapter 6] Certificate Management",headers:[{level:2,title:"6.1 Applying for a TLS Certificate",slug:"_6-1-applying-for-a-tls-certificate",link:"#_6-1-applying-for-a-tls-certificate",children:[]},{level:2,title:"6.2 Install acme.sh",slug:"_6-2-install-acme-sh",link:"#_6-2-install-acme-sh",children:[]},{level:2,title:"6.3 Testing Certificate Application",slug:"_6-3-testing-certificate-application",link:"#_6-3-testing-certificate-application",children:[]},{level:2,title:"6.5 Certificate Installation",slug:"_6-5-certificate-installation",link:"#_6-5-certificate-installation",children:[]},{level:2,title:"6.6 Your Progress",slug:"_6-6-your-progress",link:"#_6-6-your-progress",children:[]}],path:"/en/document/level-0/ch06-certificates.html",pathLocale:"/en/",extraFields:[]},{title:"【第 7 章】Xray 服务器篇",headers:[{level:2,title:"7.1 博观而约取,厚积而薄发",slug:"_7-1-博观而约取-厚积而薄发",link:"#_7-1-博观而约取-厚积而薄发",children:[]},{level:2,title:"7.2 安装 Xray",slug:"_7-2-安装-xray",link:"#_7-2-安装-xray",children:[]},{level:2,title:"7.3 给 Xray 配置 TLS 证书",slug:"_7-3-给-xray-配置-tls-证书",link:"#_7-3-给-xray-配置-tls-证书",children:[]},{level:2,title:"7.4 配置 Xray",slug:"_7-4-配置-xray",link:"#_7-4-配置-xray",children:[]},{level:2,title:"7.5 启动 Xray 服务!!(并查看服务状态)",slug:"_7-5-启动-xray-服务-并查看服务状态",link:"#_7-5-启动-xray-服务-并查看服务状态",children:[]},{level:2,title:"7.6 回顾 systemd 进行基本的服务管理",slug:"_7-6-回顾-systemd-进行基本的服务管理",link:"#_7-6-回顾-systemd-进行基本的服务管理",children:[]},{level:2,title:"7.7 服务器优化之一:开启 BBR",slug:"_7-7-服务器优化之一-开启-bbr",link:"#_7-7-服务器优化之一-开启-bbr",children:[]},{level:2,title:"7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS",slug:"_7-8-服务器优化之二-开启-http-自动跳转-https",link:"#_7-8-服务器优化之二-开启-http-自动跳转-https",children:[]},{level:2,title:"7.9 服务器优化之三:更丰富的回落",slug:"_7-9-服务器优化之三-更丰富的回落",link:"#_7-9-服务器优化之三-更丰富的回落",children:[]},{level:2,title:"7.10 你的进度",slug:"_7-10-你的进度",link:"#_7-10-你的进度",children:[]},{level:2,title:"7.11 重要勘误",slug:"_7-11-重要勘误",link:"#_7-11-重要勘误",children:[]}],path:"/en/document/level-0/ch07-xray-server.html",pathLocale:"/en/",extraFields:[]},{title:"【第 8 章】Xray 客户端篇",headers:[{level:2,title:"8.1 Xray 的工作原理简述",slug:"_8-1-xray-的工作原理简述",link:"#_8-1-xray-的工作原理简述",children:[]},{level:2,title:"8.2 客户端与服务器端正确连接",slug:"_8-2-客户端与服务器端正确连接",link:"#_8-2-客户端与服务器端正确连接",children:[]},{level:2,title:"8.3 附加题 1:在 PC 端手工配置 xray-core",slug:"_8-3-附加题-1-在-pc-端手工配置-xray-core",link:"#_8-3-附加题-1-在-pc-端手工配置-xray-core",children:[]},{level:2,title:"8.4 附加题 2:在 PC 端手工运行 xray-core",slug:"_8-4-附加题-2-在-pc-端手工运行-xray-core",link:"#_8-4-附加题-2-在-pc-端手工运行-xray-core",children:[]},{level:2,title:"8.5 附加题 3:在 PC 端开机自动运行 xray-core",slug:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",link:"#_8-5-附加题-3-在-pc-端开机自动运行-xray-core",children:[]},{level:2,title:"8.6 圆满完成!",slug:"_8-6-圆满完成",link:"#_8-6-圆满完成",children:[]},{level:2,title:"8.7 TO INFINITY AND BEYOND!",slug:"_8-7-to-infinity-and-beyond",link:"#_8-7-to-infinity-and-beyond",children:[]}],path:"/en/document/level-0/ch08-xray-clients.html",pathLocale:"/en/",extraFields:[]},{title:"【第 9 章】附录",headers:[{level:2,title:"1. 小小白白 Linux 基础命令索引",slug:"_1-小小白白-linux-基础命令索引",link:"#_1-小小白白-linux-基础命令索引",children:[]},{level:2,title:"2. 小小白白 Linux 重要配置文件索引",slug:"_2-小小白白-linux-重要配置文件索引",link:"#_2-小小白白-linux-重要配置文件索引",children:[]},{level:2,title:"3. 小小白白 Xray 重要文件索引",slug:"_3-小小白白-xray-重要文件索引",link:"#_3-小小白白-xray-重要文件索引",children:[]}],path:"/en/document/level-0/ch09-appendix.html",pathLocale:"/en/",extraFields:[]},{title:"Beginner's Tips",headers:[],path:"/en/document/level-1/",pathLocale:"/en/",extraFields:[]},{title:"回落 (fallbacks) 功能简析",headers:[{level:2,title:"1. 回顾《小小白白话文》中的回落",slug:"_1-回顾《小小白白话文》中的回落",link:"#_1-回顾《小小白白话文》中的回落",children:[]},{level:2,title:"2. 重新认识回落 (WHAT, HOW v1)",slug:"_2-重新认识回落-what-how-v1",link:"#_2-重新认识回落-what-how-v1",children:[]},{level:2,title:"3. 为什么要回落 (WHY v1)",slug:"_3-为什么要回落-why-v1",link:"#_3-为什么要回落-why-v1",children:[]},{level:2,title:"4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)",slug:"_4-重新认识【回落の完全体】-what-why-how-v2",link:"#_4-重新认识【回落の完全体】-what-why-how-v2",children:[]},{level:2,title:"5. 多层回落示例及解读",slug:"_5-多层回落示例及解读",link:"#_5-多层回落示例及解读",children:[{level:3,title:"5.1 首先,我将服务器端配置的 443 监听段摘抄如下:",slug:"_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",link:"#_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",children:[]},{level:3,title:"5.2 后续监听处理的配置段摘抄如下:",slug:"_5-2-后续监听处理的配置段摘抄如下",link:"#_5-2-后续监听处理的配置段摘抄如下",children:[]}]},{level:2,title:"6. 结语",slug:"_6-结语",link:"#_6-结语",children:[]},{level:2,title:"7. 附加题",slug:"_7-附加题",link:"#_7-附加题",children:[]}],path:"/en/document/level-1/fallbacks-lv1.html",pathLocale:"/en/",extraFields:[]},{title:"SNI fallback",headers:[{level:2,title:"Application Scenarios",slug:"application-scenarios",link:"#application-scenarios",children:[]},{level:2,title:"Introduction to SNI",slug:"introduction-to-sni",link:"#introduction-to-sni",children:[]},{level:2,title:"Idea",slug:"idea",link:"#idea",children:[]},{level:2,title:"Adding DNS Records",slug:"adding-dns-records",link:"#adding-dns-records",children:[]},{level:2,title:"Applying for TLS Certificate",slug:"applying-for-tls-certificate",link:"#applying-for-tls-certificate",children:[]},{level:2,title:"Xray Configuration",slug:"xray-configuration",link:"#xray-configuration",children:[]},{level:2,title:"Nginx Configuration",slug:"nginx-configuration",link:"#nginx-configuration",children:[]},{level:2,title:"Caddy Configuration",slug:"caddy-configuration",link:"#caddy-configuration",children:[]},{level:2,title:"Reference",slug:"reference",link:"#reference",children:[]},{level:2,title:"Quotation",slug:"quotation",link:"#quotation",children:[]}],path:"/en/document/level-1/fallbacks-with-sni.html",pathLocale:"/en/",extraFields:[]},{title:"路由 (routing) 功能简析(上)",headers:[{level:2,title:"1. 初识【路由】三兄弟",slug:"_1-初识【路由】三兄弟",link:"#_1-初识【路由】三兄弟",children:[]},{level:2,title:"2. 基本功: “兄弟一条心”",slug:"_2-基本功-兄弟一条心",link:"#_2-基本功-兄弟一条心",children:[{level:3,title:"2.1 入站",slug:"_2-1-入站",link:"#_2-1-入站",children:[]},{level:3,title:"2.3 路由",slug:"_2-3-路由",link:"#_2-3-路由",children:[]},{level:3,title:"2.4 路由配置项解析之一:流量筛选的依据",slug:"_2-4-路由配置项解析之一-流量筛选的依据",link:"#_2-4-路由配置项解析之一-流量筛选的依据",children:[]}]},{level:2,title:"3. 小试牛刀: “三分天下” 之 “域名分流”",slug:"_3-小试牛刀-三分天下-之-域名分流",link:"#_3-小试牛刀-三分天下-之-域名分流",children:[{level:3,title:"3.1 入站",slug:"_3-1-入站",link:"#_3-1-入站",children:[]},{level:3,title:"3.2 出站",slug:"_3-2-出站",link:"#_3-2-出站",children:[]},{level:3,title:"3.3 路由",slug:"_3-3-路由",link:"#_3-3-路由",children:[]},{level:3,title:"3.4 简析域名文件: geosite.dat",slug:"_3-4-简析域名文件-geosite-dat",link:"#_3-4-简析域名文件-geosite-dat",children:[]},{level:3,title:"3.5 所以 geosite.dat 到底是什么?不是有个 GFWList 吗?",slug:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",link:"#_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",children:[]},{level:3,title:"3.6 军师锦囊藏奇兵:一条隐藏的路由规则",slug:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",link:"#_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",children:[]},{level:3,title:"3.7 再看“三分天下”的大地图",slug:"_3-7-再看-三分天下-的大地图",link:"#_3-7-再看-三分天下-的大地图",children:[]}]},{level:2,title:"4. “三分天下” 之 “蜀魏争雄”",slug:"_4-三分天下-之-蜀魏争雄",link:"#_4-三分天下-之-蜀魏争雄",children:[]},{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",link:"#_5-攻城略池-多种路由匹配条件",children:[]}],path:"/en/document/level-1/routing-lv1-part1.html",pathLocale:"/en/",extraFields:[]},{title:"路由 (routing) 功能简析(下)",headers:[{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",link:"#_5-攻城略池-多种路由匹配条件",children:[{level:3,title:"5.1 基于指定域名分流:[domain], [full] 等",slug:"_5-1-基于指定域名分流-domain-full-等",link:"#_5-1-基于指定域名分流-domain-full-等",children:[]},{level:3,title:"5.2 基于 IP 文件分流:geoip.dat",slug:"_5-2-基于-ip-文件分流-geoip-dat",link:"#_5-2-基于-ip-文件分流-geoip-dat",children:[]},{level:3,title:"5.3 基于指定 IP 地址分流",slug:"_5-3-基于指定-ip-地址分流",link:"#_5-3-基于指定-ip-地址分流",children:[]},{level:3,title:"5.4 基于协议类型分流:[protocol] 等",slug:"_5-4-基于协议类型分流-protocol-等",link:"#_5-4-基于协议类型分流-protocol-等",children:[]},{level:3,title:"5.5 基于更多条件的分流",slug:"_5-5-基于更多条件的分流",link:"#_5-5-基于更多条件的分流",children:[]}]},{level:2,title:"6. “霸业初定”:路由规则整体回顾",slug:"_6-霸业初定-路由规则整体回顾",link:"#_6-霸业初定-路由规则整体回顾",children:[]},{level:2,title:"7. 路由配置常见错误",slug:"_7-路由配置常见错误",link:"#_7-路由配置常见错误",children:[{level:3,title:"7.1 错误示范",slug:"_7-1-错误示范",link:"#_7-1-错误示范",children:[]},{level:3,title:"7.2 正确示范",slug:"_7-2-正确示范",link:"#_7-2-正确示范",children:[]}]},{level:2,title:"8. 明修栈道、暗渡陈仓",slug:"_8-明修栈道、暗渡陈仓",link:"#_8-明修栈道、暗渡陈仓",children:[{level:3,title:'8.1 域名策略: "AsIs"',slug:"_8-1-域名策略-asis",link:"#_8-1-域名策略-asis",children:[]},{level:3,title:'8.2 域名策略: "IPIfNonMatch"',slug:"_8-2-域名策略-ipifnonmatch",link:"#_8-2-域名策略-ipifnonmatch",children:[]},{level:3,title:'8.3 域名策略: "IPOnDemand"',slug:"_8-3-域名策略-ipondemand",link:"#_8-3-域名策略-ipondemand",children:[]}]},{level:2,title:"9. 思考题",slug:"_9-思考题",link:"#_9-思考题",children:[]},{level:2,title:"10. 结语",slug:"_10-结语",link:"#_10-结语",children:[]},{level:2,title:"11. 尾注",slug:"_11-尾注",link:"#_11-尾注",children:[]}],path:"/en/document/level-1/routing-lv1-part2.html",pathLocale:"/en/",extraFields:[]},{title:"Xray 的工作模式",headers:[{level:2,title:"单服务器模式",slug:"单服务器模式",link:"#单服务器模式",children:[]},{level:2,title:"桥接模式",slug:"桥接模式",link:"#桥接模式",children:[]},{level:2,title:"工作原理",slug:"工作原理",link:"#工作原理",children:[]}],path:"/en/document/level-1/work.html",pathLocale:"/en/",extraFields:[]},{title:"Advanced Documentation",headers:[],path:"/en/document/level-2/",pathLocale:"/en/",extraFields:[]},{title:"Transparent proxy via GID",headers:[{level:2,title:"Ideas",slug:"ideas",link:"#ideas",children:[]},{level:2,title:"Configuration Procedure",slug:"configuration-procedure",link:"#configuration-procedure",children:[{level:3,title:"1. Preliminary preparation",slug:"_1-preliminary-preparation",link:"#_1-preliminary-preparation",children:[]},{level:3,title:"2. Add user (Android users please ignore this section)",slug:"_2-add-user-android-users-please-ignore-this-section",link:"#_2-add-user-android-users-please-ignore-this-section",children:[]},{level:3,title:"3. Configure and run Xray, and configure iptables rules",slug:"_3-configure-and-run-xray-and-configure-iptables-rules",link:"#_3-configure-and-run-xray-and-configure-iptables-rules",children:[]}]},{level:2,title:"Steps",slug:"steps",link:"#steps",children:[{level:3,title:"1. Finish Preliminary preparation and Add user",slug:"_1-finish-preliminary-preparation-and-add-user",link:"#_1-finish-preliminary-preparation-and-add-user",children:[]},{level:3,title:"2. Preparing Xray profiles",slug:"_2-preparing-xray-profiles",link:"#_2-preparing-xray-profiles",children:[]},{level:3,title:"3. Configuring the maximum number of open files and run the Xray client",slug:"_3-configuring-the-maximum-number-of-open-files-and-run-the-xray-client",link:"#_3-configuring-the-maximum-number-of-open-files-and-run-the-xray-client",children:[]},{level:3,title:"4. Setting up iptables rules",slug:"_4-setting-up-iptables-rules",link:"#_4-setting-up-iptables-rules",children:[]}]}],path:"/en/document/level-2/iptables_gid.html",pathLocale:"/en/",extraFields:[]},{title:"Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹",headers:[{level:2,title:"编译 nginx --with-stream",slug:"编译-nginx-with-stream",link:"#编译-nginx-with-stream",children:[]},{level:2,title:"配置 nginx",slug:"配置-nginx",link:"#配置-nginx",children:[]},{level:2,title:"xray 配置",slug:"xray-配置",link:"#xray-配置",children:[]},{level:2,title:"客户端及服务端启动服务",slug:"客户端及服务端启动服务",link:"#客户端及服务端启动服务",children:[]},{level:2,title:"结束",slug:"结束",link:"#结束",children:[]},{level:2,title:"HTTPS 隧道",slug:"https-隧道",link:"#https-隧道",children:[{level:3,title:"haproxy_client 配置 (运行前去掉注释)",slug:"haproxy-client-配置-运行前去掉注释",link:"#haproxy-client-配置-运行前去掉注释",children:[]},{level:3,title:"haproxy_server 配置 (运行前去掉注释)",slug:"haproxy-server-配置-运行前去掉注释",link:"#haproxy-server-配置-运行前去掉注释",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-1",link:"#xray-配置-1",children:[]}]},{level:2,title:"WebSocket over HTTP/2",slug:"websocket-over-http-2",link:"#websocket-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置",link:"#haproxy-client-配置",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置",link:"#haproxy-server-配置",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-2",link:"#xray-配置-2",children:[]}]},{level:2,title:"gRPC over HTTP/2",slug:"grpc-over-http-2",link:"#grpc-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-1",link:"#haproxy-client-配置-1",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-1",link:"#haproxy-server-配置-1",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-3",link:"#xray-配置-3",children:[]},{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-2",link:"#haproxy-client-配置-2",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-2",link:"#haproxy-server-配置-2",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-4",link:"#xray-配置-4",children:[]}]}],path:"/en/document/level-2/nginx_or_haproxy_tls_tunnel.html",pathLocale:"/en/",extraFields:[]},{title:"出站流量重定向",headers:[{level:2,title:"前言",slug:"前言",link:"#前言",children:[]},{level:2,title:"1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)",slug:"_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",link:"#_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",children:[]},{level:2,title:"2、编辑 VPN 配置文件(以 WireGuard 为例)",slug:"_2、编辑-vpn-配置文件-以-wireguard-为例",link:"#_2、编辑-vpn-配置文件-以-wireguard-为例",children:[]},{level:2,title:"3、启用 WireGuard 网络接口",slug:"_3、启用-wireguard-网络接口",link:"#_3、启用-wireguard-网络接口",children:[]},{level:2,title:"4、Xray-core 配置文件修改",slug:"_4、xray-core-配置文件修改",link:"#_4、xray-core-配置文件修改",children:[]},{level:2,title:"5、系统设置配置",slug:"_5、系统设置配置",link:"#_5、系统设置配置",children:[]},{level:2,title:"6、完成 WireGuard 相关设置",slug:"_6、完成-wireguard-相关设置",link:"#_6、完成-wireguard-相关设置",children:[]},{level:2,title:"后记",slug:"后记",link:"#后记",children:[]},{level:2,title:"感谢",slug:"感谢",link:"#感谢",children:[]}],path:"/en/document/level-2/redirect.html",pathLocale:"/en/",extraFields:[]},{title:"TProxy 透明代理",headers:[{level:2,title:"开始之前",slug:"开始之前",link:"#开始之前",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",link:"#xray-配置",children:[]},{level:2,title:"策略路由配置",slug:"策略路由配置",link:"#策略路由配置",children:[]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",link:"#netfilter-配置",children:[]},{level:2,title:"配置永久化与开机自启",slug:"配置永久化与开机自启",link:"#配置永久化与开机自启",children:[]}],path:"/en/document/level-2/tproxy.html",pathLocale:"/en/",extraFields:[]},{title:"TProxy 透明代理 (ipv4 and ipv6)",headers:[{level:2,title:"Xray 配置",slug:"xray-配置",link:"#xray-配置",children:[{level:3,title:"客户端配置",slug:"客户端配置",link:"#客户端配置",children:[]},{level:3,title:"服务端配置",slug:"服务端配置",link:"#服务端配置",children:[]}]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",link:"#netfilter-配置",children:[{level:3,title:"首先设置策略路由",slug:"首先设置策略路由",link:"#首先设置策略路由",children:[]},{level:3,title:"使用 iptables",slug:"使用-iptables",link:"#使用-iptables",children:[]},{level:3,title:"使用 nftables",slug:"使用-nftables",link:"#使用-nftables",children:[]},{level:3,title:"开机自动运行 Netfilter 配置",slug:"开机自动运行-netfilter-配置",link:"#开机自动运行-netfilter-配置",children:[]}]},{level:2,title:"局域网设备上网设置",slug:"局域网设备上网设置",link:"#局域网设备上网设置",children:[{level:3,title:"方法一",slug:"方法一",link:"#方法一",children:[]},{level:3,title:"方法二",slug:"方法二",link:"#方法二",children:[]}]},{level:2,title:"Finally",slug:"finally",link:"#finally",children:[]},{level:2,title:"写在最后",slug:"写在最后",link:"#写在最后",children:[]}],path:"/en/document/level-2/tproxy_ipv4_and_ipv6.html",pathLocale:"/en/",extraFields:[]},{title:"流量统计",headers:[{level:2,title:"查看流量信息",slug:"查看流量信息",link:"#查看流量信息",children:[]},{level:2,title:"流量信息的处理",slug:"流量信息的处理",link:"#流量信息的处理",children:[]}],path:"/en/document/level-2/traffic_stats.html",pathLocale:"/en/",extraFields:[]},{title:"Enhancing Proxy Security with Cloudflare Warp",headers:[{level:2,title:"Applying for a Warp Account",slug:"applying-for-a-warp-account",link:"#applying-for-a-warp-account",children:[]},{level:2,title:"Diverting inbound traffic to warp on the server side",slug:"diverting-inbound-traffic-to-warp-on-the-server-side",link:"#diverting-inbound-traffic-to-warp-on-the-server-side",children:[]},{level:2,title:"Using Warp Chain Proxy on the Client Side",slug:"using-warp-chain-proxy-on-the-client-side",link:"#using-warp-chain-proxy-on-the-client-side",children:[]}],path:"/en/document/level-2/warp.html",pathLocale:"/en/",extraFields:[]},{title:"透明代理入门",headers:[{level:2,title:"什么是透明代理",slug:"什么是透明代理",link:"#什么是透明代理",children:[]},{level:2,title:"透明代理的实现",slug:"透明代理的实现",link:"#透明代理的实现",children:[{level:3,title:"tun2socks",slug:"tun2socks",link:"#tun2socks",children:[]},{level:3,title:"iptables/nftables",slug:"iptables-nftables",link:"#iptables-nftables",children:[]}]},{level:2,title:"iptables 实现透明代理原理",slug:"iptables-实现透明代理原理",link:"#iptables-实现透明代理原理",children:[]},{level:2,title:"透明代理难在哪里",slug:"透明代理难在哪里",link:"#透明代理难在哪里",children:[]},{level:2,title:"从零开始一步步实现基于 iptables-tproxy 的透明代理",slug:"从零开始一步步实现基于-iptables-tproxy-的透明代理",link:"#从零开始一步步实现基于-iptables-tproxy-的透明代理",children:[{level:3,title:"在开始之前,你需要有一定的基础知识:",slug:"在开始之前-你需要有一定的基础知识",link:"#在开始之前-你需要有一定的基础知识",children:[]},{level:3,title:"前期准备工作",slug:"前期准备工作",link:"#前期准备工作",children:[]},{level:3,title:"首先,我们先试试做到第一阶段",slug:"首先-我们先试试做到第一阶段",link:"#首先-我们先试试做到第一阶段",children:[]},{level:3,title:"第二阶段",slug:"第二阶段",link:"#第二阶段",children:[]},{level:3,title:"第三阶段",slug:"第三阶段",link:"#第三阶段",children:[]},{level:3,title:"第四阶段",slug:"第四阶段",link:"#第四阶段",children:[]},{level:3,title:"代理 ipv6",slug:"代理-ipv6",link:"#代理-ipv6",children:[]}]}],path:"/en/document/level-2/transparent_proxy/transparent_proxy.html",pathLocale:"/en/",extraFields:[]},{title:"",headers:[],path:"/404.html",pathLocale:"/",extraFields:[]}],up=ge(cp),dp=()=>up,hp=({searchIndex:e,routeLocale:t,query:l,maxSuggestions:n})=>{const i=H(()=>e.value.filter(r=>r.pathLocale===t.value));return H(()=>{const r=l.value.trim().toLowerCase();if(!r)return[];const o=[],s=(a,c)=>{uo(r,[c.title])&&o.push({link:`${a.path}#${c.slug}`,title:a.title,header:c.title});for(const d of c.children){if(o.length>=n.value)return;s(a,d)}};for(const a of i.value){if(o.length>=n.value)break;if(uo(r,[a.title,...a.extraFields])){o.push({link:a.path,title:a.title});continue}for(const c of a.headers){if(o.length>=n.value)break;s(a,c)}}return o})},fp=e=>{const t=ge(0);return{focusIndex:t,focusNext:()=>{t.value{t.value>0?t.value-=1:t.value=e.value.length-1}}},vp=pe({name:"SearchBox",props:{locales:{type:Object,required:!1,default:()=>({})},hotKeys:{type:Array,required:!1,default:()=>[]},maxSuggestions:{type:Number,required:!1,default:5}},setup(e){const{locales:t,hotKeys:l,maxSuggestions:n}=In(e),i=yt(),r=Gl(),o=dp(),s=ge(null),a=ge(!1),c=ge(""),d=H(()=>t.value[r.value]??{}),h=hp({searchIndex:o,routeLocale:r,query:c,maxSuggestions:n}),{focusIndex:f,focusNext:m,focusPrev:k}=fp(h);ap({input:s,hotKeys:l});const T=H(()=>a.value&&!!h.value.length),w=()=>{T.value&&k()},I=()=>{T.value&&m()},R=b=>{if(!T.value)return;const E=h.value[b];E&&i.push(E.link).then(()=>{c.value="",f.value=0})};return()=>fe("form",{class:"search-box",role:"search"},[fe("input",{ref:s,type:"search",placeholder:d.value.placeholder,autocomplete:"off",spellcheck:!1,value:c.value,onFocus:()=>a.value=!0,onBlur:()=>a.value=!1,onInput:b=>c.value=b.target.value,onKeydown:b=>{switch(b.key){case"ArrowUp":{w();break}case"ArrowDown":{I();break}case"Enter":{b.preventDefault(),R(f.value);break}}}}),T.value&&fe("ul",{class:"suggestions",onMouseleave:()=>f.value=-1},h.value.map(({link:b,title:E,header:F},G)=>fe("li",{class:["suggestion",{focus:f.value===G}],onMouseenter:()=>f.value=G,onMousedown:()=>R(G)},fe("a",{href:b,onClick:N=>N.preventDefault()},[fe("span",{class:"page-title"},E),F&&fe("span",{class:"page-header"},`> ${F}`)]))))])}});var pp=["s","/"],mp={"/":{placeholder:"搜索"}};const gp=mp,_p=pp,bp=5,kp=Nt({enhance({app:e}){e.component("SearchBox",t=>fe(vp,{locales:gp,hotKeys:_p,maxSuggestions:bp,...t}))}}),yp={enhance:({app:e})=>{e.component("Mermaid",g(()=>u(()=>import("./Mermaid-IzGpoWNz.js"),__vite__mapDeps([])))),e.component("Tab",g(()=>u(()=>import("./Tab-7BB5fVJi.js"),__vite__mapDeps([])))),e.component("Tabs",g(()=>u(()=>import("./Tabs--CmfscRM.js"),__vite__mapDeps([]))))}},un=[Zd,lh,sh,bh,xh,Oh,np,kp,yp],Ep=[["v-8daa1a0e","/",{title:""},["/README.md"]],["v-aad48c6a","/about/news.html",{title:"大史记"},[":md"]],["v-ba934fd8","/config/",{title:"配置文件"},["/config/README.md"]],["v-41ade9da","/config/api.html",{title:"API 接口"},[":md"]],["v-83dedd38","/config/dns.html",{title:"内置 DNS 服务器"},[":md"]],["v-192a19b9","/config/fakedns.html",{title:"FakeDNS"},[":md"]],["v-7f6279d8","/config/inbound.html",{title:"入站代理"},[":md"]],["v-1d860c29","/config/log.html",{title:"日志配置"},[":md"]],["v-fbaf47ec","/config/metrics.html",{title:"Metrics"},[":md"]],["v-2367d756","/config/outbound.html",{title:"出站代理"},[":md"]],["v-4ebec35a","/config/policy.html",{title:"本地策略"},[":md"]],["v-31b7756a","/config/reverse.html",{title:"反向代理"},[":md"]],["v-70677432","/config/routing.html",{title:"路由"},[":md"]],["v-7e21d6ae","/config/stats.html",{title:"统计信息"},[":md"]],["v-e3dfff38","/config/transport.html",{title:"传输方式"},[":md"]],["v-f7496066","/development/",{title:"开发指南"},["/development/README.md"]],["v-36b1a79b","/document/",{title:"快速入门"},["/document/README.md"]],["v-09a64f89","/document/command.html",{title:"命令参数"},[":md"]],["v-2b1adf48","/document/config.html",{title:"配置运行"},[":md"]],["v-86ee963a","/document/document.html",{title:"为 Project X 的文档贡献"},[":md"]],["v-0e5d7b39","/document/install.html",{title:"下载安装"},[":md"]],["v-2d0a870d","/en/",{title:""},["/en/README.md"]],["v-0d714d87","/config/features/browser_dialer.html",{title:"Browser Dialer"},[":md"]],["v-0da7880a","/config/features/env.html",{title:"环境变量"},[":md"]],["v-2aeb21f9","/config/features/fallback.html",{title:"Fallback 回落"},[":md"]],["v-3acf20ea","/config/features/multiple.html",{title:"多文件配置"},[":md"]],["v-792e28f8","/config/features/xtls.html",{title:"XTLS 深度剖析"},[":md"]],["v-b50d2334","/config/inbounds/dokodemo.html",{title:"Dokodemo-Door"},[":md"]],["v-593408b0","/config/inbounds/http.html",{title:"HTTP"},[":md"]],["v-802a842a","/config/inbounds/shadowsocks.html",{title:"Shadowsocks"},[":md"]],["v-29995cea","/config/inbounds/socks.html",{title:"Socks"},[":md"]],["v-2a1b3d72","/config/inbounds/trojan.html",{title:"Trojan"},[":md"]],["v-fb92e8aa","/config/inbounds/vless.html",{title:"VLESS"},[":md"]],["v-167afaac","/config/inbounds/vmess.html",{title:"VMess"},[":md"]],["v-749ad71a","/config/outbounds/blackhole.html",{title:"Blackhole"},[":md"]],["v-6d39b970","/config/outbounds/dns.html",{title:"DNS"},[":md"]],["v-d76e893a","/config/outbounds/freedom.html",{title:"Freedom"},[":md"]],["v-c6b4b59e","/config/outbounds/http.html",{title:"HTTP"},[":md"]],["v-41ec0e0e","/config/outbounds/loopback.html",{title:"Loopback"},[":md"]],["v-7b293e4a","/config/outbounds/shadowsocks.html",{title:"Shadowsocks"},[":md"]],["v-15f5452a","/config/outbounds/socks.html",{title:"Socks"},[":md"]],["v-5797bdb3","/config/outbounds/trojan.html",{title:"Trojan"},[":md"]],["v-a60f016c","/config/outbounds/vless.html",{title:"VLESS"},[":md"]],["v-413cee4b","/config/outbounds/vmess.html",{title:"VMess"},[":md"]],["v-208ca3b9","/config/outbounds/wireguard.html",{title:"Wireguard"},[":md"]],["v-775db7b1","/config/transports/domainsocket.html",{title:"Domain Socket"},[":md"]],["v-2877542a","/config/transports/grpc.html",{title:"gRPC"},[":md"]],["v-03a28284","/config/transports/h2.html",{title:"HTTP/2"},[":md"]],["v-04158536","/config/transports/httpupgrade.html",{title:"HTTPUpgrade"},[":md"]],["v-3167b1dd","/config/transports/mkcp.html",{title:"mKCP"},[":md"]],["v-8f08dbec","/config/transports/quic.html",{title:"QUIC"},[":md"]],["v-33b1b709","/config/transports/tcp.html",{title:"TCP"},[":md"]],["v-1ff57bba","/config/transports/websocket.html",{title:"WebSocket"},[":md"]],["v-6a9e8054","/development/intro/compile.html",{title:"编译文档"},[":md"]],["v-95e3eaea","/development/intro/design.html",{title:"设计目标"},[":md"]],["v-61e7eea6","/development/intro/guide.html",{title:"开发规范"},[":md"]],["v-6e6c37e6","/development/protocols/mkcp.html",{title:"mKCP 协议"},[":md"]],["v-13168a21","/development/protocols/muxcool.html",{title:"Mux.Cool 协议"},[":md"]],["v-5c48c82b","/development/protocols/vless.html",{title:"VLESS 协议"},[":md"]],["v-1ee591a8","/development/protocols/vmess.html",{title:"VMess 协议"},[":md"]],["v-3f09dcfa","/document/level-0/",{title:"小小白白话文"},["/document/level-0/README.md"]],["v-fb444906","/document/level-0/ch01-preface.html",{title:"【第 1 章】 小小白白话文"},[":md"]],["v-075f3ae5","/document/level-0/ch02-preparation.html",{title:"【第 2 章】原料准备篇"},[":md"]],["v-726d0633","/document/level-0/ch03-ssh.html",{title:"【第 3 章】远程登录篇"},[":md"]],["v-430c6ab8","/document/level-0/ch04-security.html",{title:"【第 4 章】安全防护篇"},[":md"]],["v-717c6376","/document/level-0/ch05-webpage.html",{title:"【第 5 章】网站建设篇"},[":md"]],["v-278039be","/document/level-0/ch06-certificates.html",{title:"【第 6 章】证书管理篇"},[":md"]],["v-a0c7f88e","/document/level-0/ch07-xray-server.html",{title:"【第 7 章】Xray 服务器篇"},[":md"]],["v-86586ca2","/document/level-0/ch08-xray-clients.html",{title:"【第 8 章】Xray 客户端篇"},[":md"]],["v-3eb62514","/document/level-0/ch09-appendix.html",{title:"【第 9 章】附录"},[":md"]],["v-3f09dcbc","/document/level-1/",{title:"入门技巧"},["/document/level-1/README.md"]],["v-b21a2a20","/document/level-1/fallbacks-lv1.html",{title:"回落 (fallbacks) 功能简析"},[":md"]],["v-da623318","/document/level-1/fallbacks-with-sni.html",{title:"SNI 回落"},[":md"]],["v-fdd722ac","/document/level-1/routing-lv1-part1.html",{title:"路由 (routing) 功能简析(上)"},[":md"]],["v-fa6d716e","/document/level-1/routing-lv1-part2.html",{title:"路由 (routing) 功能简析(下)"},[":md"]],["v-2f29e106","/document/level-1/work.html",{title:"Xray 的工作模式"},[":md"]],["v-3f09dc7e","/document/level-2/",{title:"进阶文档"},["/document/level-2/README.md"]],["v-1c17916e","/document/level-2/iptables_gid.html",{title:"GID 透明代理"},[":md"]],["v-a001cfa6","/document/level-2/nginx_or_haproxy_tls_tunnel.html",{title:"Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹"},[":md"]],["v-46333b48","/document/level-2/redirect.html",{title:"出站流量重定向"},[":md"]],["v-338bc63e","/document/level-2/tproxy.html",{title:"TProxy 透明代理"},[":md"]],["v-d68f7d58","/document/level-2/tproxy_ipv4_and_ipv6.html",{title:"TProxy 透明代理 (ipv4 and ipv6)"},[":md"]],["v-e533e2c6","/document/level-2/traffic_stats.html",{title:"流量统计"},[":md"]],["v-1e465ab0","/document/level-2/warp.html",{title:"通过 Cloudflare Warp 增强代理安全性"},[":md"]],["v-1080fb37","/en/about/news.html",{title:"大史记"},[":md"]],["v-317fc580","/en/config/",{title:"Configurations"},["/en/config/README.md"]],["v-45144c7f","/en/config/api.html",{title:"API Interface"},[":md"]],["v-23fbd2d0","/en/config/dns.html",{title:"Built-in DNS Server"},[":md"]],["v-2b7ec525","/en/config/fakedns.html",{title:"FakeDNS"},[":md"]],["v-5ab92300","/en/config/inbound.html",{title:"Inbound Proxy"},[":md"]],["v-f91d64d6","/en/config/log.html",{title:"Log Configuration"},[":md"]],["v-d705f114","/en/config/metrics.html",{title:"Metrics"},[":md"]],["v-268cd669","/en/config/outbound.html",{title:"Outbound Proxies"},[":md"]],["v-4492d567","/en/config/policy.html",{title:"Local Policy"},[":md"]],["v-0d0e1e92","/en/config/reverse.html",{title:"Reverse Proxy"},[":md"]],["v-4bbe1d5a","/en/config/routing.html",{title:"Routing"},[":md"]],["v-16426d1a","/en/config/stats.html",{title:"Traffic Statistics"},[":md"]],["v-5de780d0","/en/config/transport.html",{title:"Transport"},[":md"]],["v-f88d343e","/en/development/",{title:"Development Guide"},["/en/development/README.md"]],["v-38d56a07","/en/document/",{title:"Quick Start"},["/en/document/README.md"]],["v-4d046016","/en/document/command.html",{title:"Command Parameters"},[":md"]],["v-22b35270","/en/document/config.html",{title:"Configure and Run"},[":md"]],["v-30bd7c12","/en/document/document.html",{title:"Contribute to Project X's Document"},[":md"]],["v-439608b6","/en/document/install.html",{title:"Download and Install"},[":md"]],["v-51a51d87","/document/level-2/transparent_proxy/transparent_proxy.html",{title:"透明代理入门"},[":md"]],["v-76b9a0f3","/en/config/features/browser_dialer.html",{title:"Browser Dialer"},[":md"]],["v-565dbfc4","/en/config/features/env.html",{title:"Environment Variables"},[":md"]],["v-0fbd1336","/en/config/features/fallback.html",{title:"Fallback"},[":md"]],["v-a0627812","/en/config/features/multiple.html",{title:"Multi-file configuration"},[":md"]],["v-d190d938","/en/config/features/xtls.html",{title:"Deep analysis of XTLS"},[":md"]],["v-72afc2d2","/en/config/inbounds/dokodemo.html",{title:"Dokodemo-Door"},[":md"]],["v-773d731c","/en/config/inbounds/http.html",{title:"HTTP"},[":md"]],["v-f555fc02","/en/config/inbounds/shadowsocks.html",{title:"Shadowsocks"},[":md"]],["v-e35196c2","/en/config/inbounds/socks.html",{title:"SOCKS"},[":md"]],["v-29188644","/en/config/inbounds/trojan.html",{title:"Trojan"},[":md"]],["v-255a6ebf","/en/config/inbounds/vless.html",{title:"VLESS"},[":md"]],["v-8cc24480","/en/config/inbounds/vmess.html",{title:"VMess"},[":md"]],["v-64e47ef4","/en/config/outbounds/blackhole.html",{title:"Blackhole"},[":md"]],["v-e979b848","/en/config/outbounds/dns.html",{title:"DNS"},[":md"]],["v-617f0fcf","/en/config/outbounds/freedom.html",{title:"Freedom"},[":md"]],["v-3fc98845","/en/config/outbounds/http.html",{title:"HTTP"},[":md"]],["v-1b804722","/en/config/outbounds/loopback.html",{title:"Loopback"},[":md"]],["v-63077cb6","/en/config/outbounds/shadowsocks.html",{title:"Shadowsocks"},[":md"]],["v-516476d4","/en/config/outbounds/socks.html",{title:"Socks"},[":md"]],["v-7d61a872","/en/config/outbounds/trojan.html",{title:"Trojan"},[":md"]],["v-6e50feb6","/en/config/outbounds/vless.html",{title:"VLESS"},[":md"]],["v-02956db7","/en/config/outbounds/vmess.html",{title:"VMess"},[":md"]],["v-797f8d25","/en/config/outbounds/wireguard.html",{title:"Wireguard"},[":md"]],["v-3eb3e9c6","/en/config/transports/domainsocket.html",{title:"Domain Socket"},[":md"]],["v-2c6058d4","/en/config/transports/grpc.html",{title:"gRPC"},[":md"]],["v-1c38292a","/en/config/transports/h2.html",{title:"HTTP/2"},[":md"]],["v-17ff144a","/en/config/transports/httpupgrade.html",{title:"HTTPUpgrade"},[":md"]],["v-1a7f9d6e","/en/config/transports/mkcp.html",{title:"mKCP"},[":md"]],["v-79d41176","/en/config/transports/quic.html",{title:"QUIC"},[":md"]],["v-5254cbc6","/en/config/transports/tcp.html",{title:"TCP"},[":md"]],["v-9520f392","/en/config/transports/websocket.html",{title:"WebSocket"},[":md"]],["v-b7760e2c","/en/development/intro/compile.html",{title:"Compile the document"},[":md"]],["v-fb774212","/en/development/intro/design.html",{title:"Design Objectives"},[":md"]],["v-38c376c1","/en/development/intro/guide.html",{title:"Development Standards"},[":md"]],["v-21bccd79","/en/development/protocols/mkcp.html",{title:"mKCP Protocol"},[":md"]],["v-27001935","/en/development/protocols/muxcool.html",{title:"Mux.Cool Protocol"},[":md"]],["v-21b30c3f","/en/development/protocols/vless.html",{title:"VLESS Protocol"},[":md"]],["v-94110980","/en/development/protocols/vmess.html",{title:"VMess Protocol"},[":md"]],["v-789ba7ef","/en/document/level-0/",{title:"Plain and Simple Language"},["/en/document/level-0/README.md"]],["v-d3712ade","/en/document/level-0/ch01-preface.html",{title:"[Chapter 1] Simple and Plain Language"},[":md"]],["v-41f9c00e","/en/document/level-0/ch02-preparation.html",{title:"[Chapter 2] Preparation of Raw Materials"},[":md"]],["v-4c013f47","/en/document/level-0/ch03-ssh.html",{title:"[Chapter 3] Remote Login"},[":md"]],["v-a75683b8","/en/document/level-0/ch04-security.html",{title:"[Chapter 4] Security and Protection"},[":md"]],["v-f5341aec","/en/document/level-0/ch05-webpage.html",{title:"Chapter 5: Website Building"},[":md"]],["v-4458f72a","/en/document/level-0/ch06-certificates.html",{title:"[Chapter 6] Certificate Management"},[":md"]],["v-f1802e66","/en/document/level-0/ch07-xray-server.html",{title:"【第 7 章】Xray 服务器篇"},[":md"]],["v-4ca6f1ca","/en/document/level-0/ch08-xray-clients.html",{title:"【第 8 章】Xray 客户端篇"},[":md"]],["v-b0030f00","/en/document/level-0/ch09-appendix.html",{title:"【第 9 章】附录"},[":md"]],["v-789ba80e","/en/document/level-1/",{title:"Beginner's Tips"},["/en/document/level-1/README.md"]],["v-103b3e5c","/en/document/level-1/fallbacks-lv1.html",{title:"回落 (fallbacks) 功能简析"},[":md"]],["v-110dd688","/en/document/level-1/fallbacks-with-sni.html",{title:"SNI fallback"},[":md"]],["v-c425a7d4","/en/document/level-1/routing-lv1-part1.html",{title:"路由 (routing) 功能简析(上)"},[":md"]],["v-c0bbf696","/en/document/level-1/routing-lv1-part2.html",{title:"路由 (routing) 功能简析(下)"},[":md"]],["v-5b6477cc","/en/document/level-1/work.html",{title:"Xray 的工作模式"},[":md"]],["v-789ba82d","/en/document/level-2/",{title:"Advanced Documentation"},["/en/document/level-2/README.md"]],["v-05ddc65d","/en/document/level-2/iptables_gid.html",{title:"Transparent proxy via GID"},[":md"]],["v-474afe99","/en/document/level-2/nginx_or_haproxy_tls_tunnel.html",{title:"Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹"},[":md"]],["v-930ac920","/en/document/level-2/redirect.html",{title:"出站流量重定向"},[":md"]],["v-c579975c","/en/document/level-2/tproxy.html",{title:"TProxy 透明代理"},[":md"]],["v-7efb7c68","/en/document/level-2/tproxy_ipv4_and_ipv6.html",{title:"TProxy 透明代理 (ipv4 and ipv6)"},[":md"]],["v-12a33bee","/en/document/level-2/traffic_stats.html",{title:"流量统计"},[":md"]],["v-7d2b8478","/en/document/level-2/warp.html",{title:"Enhancing Proxy Security with Cloudflare Warp"},[":md"]],["v-7689d7f3","/en/document/level-2/transparent_proxy/transparent_proxy.html",{title:"透明代理入门"},[":md"]],["v-3706649a","/404.html",{title:""},[]]];var ho=pe({name:"Vuepress",setup(){const e=Hu();return()=>fe(e.value)}}),xp=()=>Ep.reduce((e,[t,l,n,i])=>(e.push({name:t,path:l,component:ho,meta:n},{path:l.endsWith("/")?l+"index.html":l.substring(0,l.length-5),redirect:l},...i.map(r=>({path:r===":md"?l.substring(0,l.length-5)+".md":r,redirect:l}))),e),[{name:"404",path:"/:catchAll(.*)",component:ho}]),Lp=cd,Tp=()=>{const e=Kd({history:Lp(ds("/")),routes:xp(),scrollBehavior:(t,l,n)=>n||(t.hash?{el:t.hash}:{top:0})});return e.beforeResolve(async(t,l)=>{var n;(t.path!==l.path||l===pt)&&([t.meta._data]=await Promise.all([vt.resolvePageData(t.name),(n=vs[t.name])==null?void 0:n.__asyncLoader()]))}),e},Pp=e=>{e.component("ClientOnly",$i),e.component("Content",Uu)},wp=(e,t,l)=>{const n=H(()=>t.currentRoute.value.path),i=Ih(n,()=>t.currentRoute.value.meta._data),r=H(()=>vt.resolveLayouts(l)),o=H(()=>vt.resolveRouteLocale(ll.value.locales,n.value)),s=H(()=>vt.resolveSiteLocaleData(ll.value,o.value)),a=H(()=>vt.resolvePageFrontmatter(i.value)),c=H(()=>vt.resolvePageHeadTitle(i.value,s.value)),d=H(()=>vt.resolvePageHead(c.value,a.value,s.value)),h=H(()=>vt.resolvePageLang(i.value,s.value)),f=H(()=>vt.resolvePageLayout(i.value,r.value));return e.provide(Cu,r),e.provide(ps,i),e.provide(ms,a),e.provide(Nu,c),e.provide(gs,d),e.provide(_s,h),e.provide(bs,f),e.provide(Mi,o),e.provide(ys,s),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>a.value},$head:{get:()=>d.value},$headTitle:{get:()=>c.value},$lang:{get:()=>h.value},$page:{get:()=>i.value},$routeLocale:{get:()=>o.value},$site:{get:()=>ll.value},$siteLocale:{get:()=>s.value},$withBase:{get:()=>Bi}}),{layouts:r,pageData:i,pageFrontmatter:a,pageHead:d,pageHeadTitle:c,pageLang:h,pageLayout:f,routeLocale:o,siteData:ll,siteLocaleData:s}},Op=()=>{const e=Fu(),t=Mu();let l=[];const n=()=>{e.value.forEach(o=>{const s=Ap(o);s&&l.push(s)})},i=()=>{const o=[];return e.value.forEach(s=>{const a=Rp(s);a&&o.push(a)}),o},r=()=>{document.documentElement.lang=t.value;const o=i();l.forEach((s,a)=>{const c=o.findIndex(d=>s.isEqualNode(d));c===-1?(s.remove(),delete l[a]):o.splice(c,1)}),o.forEach(s=>document.head.appendChild(s)),l=[...l.filter(s=>!!s),...o]};Xt(Bu,r),ze(()=>{n(),Ye(e,r,{immediate:!1})})},Ap=([e,t,l=""])=>{const n=Object.entries(t).map(([s,a])=>rt(a)?`[${s}=${JSON.stringify(a)}]`:a===!0?`[${s}]`:"").join(""),i=`head > ${e}${n}`;return Array.from(document.querySelectorAll(i)).find(s=>s.innerText===l)||null},Rp=([e,t,l])=>{if(!rt(e))return null;const n=document.createElement(e);return Ni(t)&&Object.entries(t).forEach(([i,r])=>{rt(r)?n.setAttribute(i,r):r===!0&&n.setAttribute(i,"")}),rt(l)&&n.appendChild(document.createTextNode(l)),n},Ip=xu,Dp=async()=>{var l;const e=Ip({name:"VuepressApp",setup(){var n;Op();for(const i of un)(n=i.setup)==null||n.call(i);return()=>[fe(Ss),...un.flatMap(({rootComponents:i=[]})=>i.map(r=>fe(r)))]}}),t=Tp();Pp(e),wp(e,t,un);for(const n of un)await((l=n.enhance)==null?void 0:l.call(n,{app:e,router:t,siteData:ll}));return e.use(t),{app:e,router:t}};Dp().then(({app:e,router:t})=>{t.isReady().then(()=>{e.mount("#app")})});export{ye as F,Le as _,he as a,Ft as b,ee as c,Dp as createVueApp,ie as d,Fc as e,ha as f,ko as g,H as h,Ye as i,ge as j,ze as k,Ci as l,pe as m,Bl as n,z as o,Wl as p,u as q,kt as r,ke as s,Sp as t,te as u,Ct as v,Ve as w,Ie as x}; function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { __vite__mapDeps.viteFileDeps = [] diff --git a/assets/arc-XT00965o.js b/assets/arc-5GdQY_kf.js similarity index 96% rename from assets/arc-XT00965o.js rename to assets/arc-5GdQY_kf.js index f38a3639a7..59b1dc8e70 100644 --- a/assets/arc-XT00965o.js +++ b/assets/arc-5GdQY_kf.js @@ -1 +1 @@ -import{w as ln,c as U}from"./path-aUcfwwLI.js";import{aP as an,aQ as Y,aR as S,aS as rn,aT as y,aL as on,aU as z,aV as _,aW as un,aX as t,aY as sn,aZ as tn,a_ as fn}from"./mermaid.core-95b3ca__.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function mn(l){return l.endAngle}function pn(l){return l&&l.padAngle}function dn(l,h,E,q,v,R,V,a){var I=E-l,i=q-h,n=V-v,m=a-R,r=m*I-n*i;if(!(r*ru*u+X*X&&(O=w,Q=d),{cx:O,cy:Q,x01:-n,y01:-m,x11:O*(v/T-1),y11:Q*(v/T-1)}}function vn(){var l=cn,h=yn,E=U(0),q=null,v=gn,R=mn,V=pn,a=null,I=ln(i);function i(){var n,m,r=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-rn,c=R.apply(this,arguments)-rn,W=un(c-f),o=c>f;if(a||(a=n=I()),sy))a.moveTo(0,0);else if(W>on-y)a.moveTo(s*Y(f),s*S(f)),a.arc(0,0,s,f,c,!o),r>y&&(a.moveTo(r*Y(c),r*S(c)),a.arc(0,0,r,c,f,o));else{var p=f,g=c,A=f,T=c,P=W,L=W,O=V.apply(this,arguments)/2,Q=O>y&&(q?+q.apply(this,arguments):z(r*r+s*s)),w=_(un(s-r)/2,+E.apply(this,arguments)),d=w,x=w,e,u;if(Q>y){var X=sn(Q/r*S(O)),B=sn(Q/s*S(O));(P-=X*2)>y?(X*=o?1:-1,A+=X,T-=X):(P=0,A=T=(f+c)/2),(L-=B*2)>y?(B*=o?1:-1,p+=B,g-=B):(L=0,p=g=(f+c)/2)}var Z=s*Y(p),j=s*S(p),C=r*Y(T),F=r*S(T);if(w>y){var G=s*Y(g),H=s*S(g),K=r*Y(A),M=r*S(A),D;if(Wy?x>y?(e=J(K,M,Z,j,s,x,o),u=J(G,H,C,F,s,x,o),a.moveTo(e.cx+e.x01,e.cy+e.y01),xy)||!(P>y)?a.lineTo(C,F):d>y?(e=J(C,F,G,H,r,-d,o),u=J(Z,j,K,M,r,-d,o),a.lineTo(e.cx+e.x01,e.cy+e.y01),du*u+X*X&&(O=w,Q=d),{cx:O,cy:Q,x01:-n,y01:-m,x11:O*(v/T-1),y11:Q*(v/T-1)}}function vn(){var l=cn,h=yn,E=U(0),q=null,v=gn,R=mn,V=pn,a=null,I=ln(i);function i(){var n,m,r=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-rn,c=R.apply(this,arguments)-rn,W=un(c-f),o=c>f;if(a||(a=n=I()),sy))a.moveTo(0,0);else if(W>on-y)a.moveTo(s*Y(f),s*S(f)),a.arc(0,0,s,f,c,!o),r>y&&(a.moveTo(r*Y(c),r*S(c)),a.arc(0,0,r,c,f,o));else{var p=f,g=c,A=f,T=c,P=W,L=W,O=V.apply(this,arguments)/2,Q=O>y&&(q?+q.apply(this,arguments):z(r*r+s*s)),w=_(un(s-r)/2,+E.apply(this,arguments)),d=w,x=w,e,u;if(Q>y){var X=sn(Q/r*S(O)),B=sn(Q/s*S(O));(P-=X*2)>y?(X*=o?1:-1,A+=X,T-=X):(P=0,A=T=(f+c)/2),(L-=B*2)>y?(B*=o?1:-1,p+=B,g-=B):(L=0,p=g=(f+c)/2)}var Z=s*Y(p),j=s*S(p),C=r*Y(T),F=r*S(T);if(w>y){var G=s*Y(g),H=s*S(g),K=r*Y(A),M=r*S(A),D;if(Wy?x>y?(e=J(K,M,Z,j,s,x,o),u=J(G,H,C,F,s,x,o),a.moveTo(e.cx+e.x01,e.cy+e.y01),xy)||!(P>y)?a.lineTo(C,F):d>y?(e=J(C,F,G,H,r,-d,o),u=J(Z,j,K,M,r,-d,o),a.lineTo(e.cx+e.x01,e.cy+e.y01),dOutboundConfigurationObject
{
+import{_ as s,r as a,o as t,c,a as e,b as n,d as l,w as p,e as i}from"./app-UOvWaKji.js";const d={},r=e("h1",{id:"blackhole",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#blackhole"},[e("span",null,"Blackhole")])],-1),u=i(`

OutboundConfigurationObject

{
   "response": {
     "type": "none"
   }
diff --git a/assets/blackhole.html-_QMN6sZq.js b/assets/blackhole.html-MeysKqPJ.js
similarity index 97%
rename from assets/blackhole.html-_QMN6sZq.js
rename to assets/blackhole.html-MeysKqPJ.js
index ac2bdb65bc..49e34b89c6 100644
--- a/assets/blackhole.html-_QMN6sZq.js
+++ b/assets/blackhole.html-MeysKqPJ.js
@@ -1,4 +1,4 @@
-import{_ as s,r as t,o as a,c,a as e,b as n,d as l,w as i,e as d}from"./app-PDrbPfzp.js";const p={},r=e("h1",{id:"blackhole",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#blackhole"},[e("span",null,"Blackhole")])],-1),u=d(`

OutboundConfigurationObject

{
+import{_ as s,r as t,o as a,c,a as e,b as n,d as l,w as i,e as d}from"./app-UOvWaKji.js";const p={},r=e("h1",{id:"blackhole",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#blackhole"},[e("span",null,"Blackhole")])],-1),u=d(`

OutboundConfigurationObject

{
   "response": {
     "type": "none"
   }
diff --git a/assets/blockDiagram-91b80b7a-W38ApPQ6.js b/assets/blockDiagram-91b80b7a-6EYGTs6T.js
similarity index 98%
rename from assets/blockDiagram-91b80b7a-W38ApPQ6.js
rename to assets/blockDiagram-91b80b7a-6EYGTs6T.js
index bb044e9847..8a016a3b29 100644
--- a/assets/blockDiagram-91b80b7a-W38ApPQ6.js
+++ b/assets/blockDiagram-91b80b7a-6EYGTs6T.js
@@ -1,4 +1,4 @@
-import{c as _e,b0 as se,h as H,i as ye,l as S,A as Ee,af as we,p as De}from"./mermaid.core-95b3ca__.js";import{c as ve}from"./clone-jETecP85.js";import{i as Ne,c as ke,b as Ie,d as Oe,a as he,p as Te}from"./edges-d32062c0-iT1MEq_Y.js";import{G as ze}from"./graph-cZfODKa1.js";import{o as Ce}from"./ordinal-wXG5obU4.js";import{c as Ae}from"./channel-GQnHP4O7.js";import{s as Re}from"./Tableau10-Fgclqpgn.js";import"./app-PDrbPfzp.js";import"./createText-6b48ae7d-9AoX5zU9.js";import"./line-_nnM_7ZX.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";import"./init-Hi12RPRh.js";var le,oe,ee=function(){var e=function(D,o,s,i){for(s=s||{},i=D.length;i--;s[D[i]]=o);return s},a=[1,7],d=[1,13],c=[1,14],n=[1,15],g=[1,19],l=[1,16],f=[1,17],b=[1,18],p=[8,30],x=[8,21,28,29,30,31,32,40,44,47],y=[1,23],T=[1,24],v=[8,15,16,21,28,29,30,31,32,40,44,47],N=[8,15,16,21,27,28,29,30,31,32,40,44,47],E=[1,49],L={trace:function(){},yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,block:31,NODE_ID:32,nodeShapeNLabel:33,dirList:34,DIR:35,NODE_DSTART:36,NODE_DEND:37,BLOCK_ARROW_START:38,BLOCK_ARROW_END:39,classDef:40,CLASSDEF_ID:41,CLASSDEF_STYLEOPTS:42,DEFAULT:43,class:44,CLASSENTITY_IDS:45,STYLECLASS:46,style:47,STYLE_ENTITY_IDS:48,STYLE_DEFINITION_DATA:49,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"block",32:"NODE_ID",35:"DIR",36:"NODE_DSTART",37:"NODE_DEND",38:"BLOCK_ARROW_START",39:"BLOCK_ARROW_END",40:"classDef",41:"CLASSDEF_ID",42:"CLASSDEF_STYLEOPTS",43:"DEFAULT",44:"class",45:"CLASSENTITY_IDS",46:"STYLECLASS",47:"style",48:"STYLE_ENTITY_IDS",49:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[34,1],[34,2],[33,3],[33,4],[23,3],[23,3],[24,3],[25,3]],performAction:function(o,s,i,u,h,t,m){var r=t.length-1;switch(h){case 4:u.getLogger().debug("Rule: separator (NL) ");break;case 5:u.getLogger().debug("Rule: separator (Space) ");break;case 6:u.getLogger().debug("Rule: separator (EOF) ");break;case 7:u.getLogger().debug("Rule: hierarchy: ",t[r-1]),u.setHierarchy(t[r-1]);break;case 8:u.getLogger().debug("Stop NL ");break;case 9:u.getLogger().debug("Stop EOF ");break;case 10:u.getLogger().debug("Stop NL2 ");break;case 11:u.getLogger().debug("Stop EOF2 ");break;case 12:u.getLogger().debug("Rule: statement: ",t[r]),typeof t[r].length=="number"?this.$=t[r]:this.$=[t[r]];break;case 13:u.getLogger().debug("Rule: statement #2: ",t[r-1]),this.$=[t[r-1]].concat(t[r]);break;case 14:u.getLogger().debug("Rule: link: ",t[r],o),this.$={edgeTypeStr:t[r],label:""};break;case 15:u.getLogger().debug("Rule: LABEL link: ",t[r-3],t[r-1],t[r]),this.$={edgeTypeStr:t[r],label:t[r-1]};break;case 18:const R=parseInt(t[r]),Y=u.generateId();this.$={id:Y,type:"space",label:"",width:R,children:[]};break;case 23:u.getLogger().debug("Rule: (nodeStatement link node) ",t[r-2],t[r-1],t[r]," typestr: ",t[r-1].edgeTypeStr);const F=u.edgeStrToEdgeData(t[r-1].edgeTypeStr);this.$=[{id:t[r-2].id,label:t[r-2].label,type:t[r-2].type,directions:t[r-2].directions},{id:t[r-2].id+"-"+t[r].id,start:t[r-2].id,end:t[r].id,label:t[r-1].label,type:"edge",directions:t[r].directions,arrowTypeEnd:F,arrowTypeStart:"arrow_open"},{id:t[r].id,label:t[r].label,type:u.typeStr2Type(t[r].typeStr),directions:t[r].directions}];break;case 24:u.getLogger().debug("Rule: nodeStatement (abc88 node size) ",t[r-1],t[r]),this.$={id:t[r-1].id,label:t[r-1].label,type:u.typeStr2Type(t[r-1].typeStr),directions:t[r-1].directions,widthInColumns:parseInt(t[r],10)};break;case 25:u.getLogger().debug("Rule: nodeStatement (node) ",t[r]),this.$={id:t[r].id,label:t[r].label,type:u.typeStr2Type(t[r].typeStr),directions:t[r].directions,widthInColumns:1};break;case 26:u.getLogger().debug("APA123",this?this:"na"),u.getLogger().debug("COLUMNS: ",t[r]),this.$={type:"column-setting",columns:t[r]==="auto"?-1:parseInt(t[r])};break;case 27:u.getLogger().debug("Rule: id-block statement : ",t[r-2],t[r-1]),u.generateId(),this.$={...t[r-2],type:"composite",children:t[r-1]};break;case 28:u.getLogger().debug("Rule: blockStatement : ",t[r-2],t[r-1],t[r]);const C=u.generateId();this.$={id:C,type:"composite",label:"",children:t[r-1]};break;case 29:u.getLogger().debug("Rule: node (NODE_ID separator): ",t[r]),this.$={id:t[r]};break;case 30:u.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",t[r-1],t[r]),this.$={id:t[r-1],label:t[r].label,typeStr:t[r].typeStr,directions:t[r].directions};break;case 31:u.getLogger().debug("Rule: dirList: ",t[r]),this.$=[t[r]];break;case 32:u.getLogger().debug("Rule: dirList: ",t[r-1],t[r]),this.$=[t[r-1]].concat(t[r]);break;case 33:u.getLogger().debug("Rule: nodeShapeNLabel: ",t[r-2],t[r-1],t[r]),this.$={typeStr:t[r-2]+t[r],label:t[r-1]};break;case 34:u.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",t[r-3],t[r-2]," #3:",t[r-1],t[r]),this.$={typeStr:t[r-3]+t[r],label:t[r-2],directions:t[r-1]};break;case 35:case 36:this.$={type:"classDef",id:t[r-1].trim(),css:t[r].trim()};break;case 37:this.$={type:"applyClass",id:t[r-1].trim(),styleClass:t[r].trim()};break;case 38:this.$={type:"applyStyles",id:t[r-1].trim(),stylesStr:t[r].trim()};break}},table:[{9:1,10:[1,2]},{1:[3]},{11:3,13:4,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:d,29:c,31:n,32:g,40:l,44:f,47:b},{8:[1,20]},e(p,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,21:a,28:d,29:c,31:n,32:g,40:l,44:f,47:b}),e(x,[2,16],{14:22,15:y,16:T}),e(x,[2,17]),e(x,[2,18]),e(x,[2,19]),e(x,[2,20]),e(x,[2,21]),e(x,[2,22]),e(v,[2,25],{27:[1,25]}),e(x,[2,26]),{19:26,26:12,32:g},{11:27,13:4,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:d,29:c,31:n,32:g,40:l,44:f,47:b},{41:[1,28],43:[1,29]},{45:[1,30]},{48:[1,31]},e(N,[2,29],{33:32,36:[1,33],38:[1,34]}),{1:[2,7]},e(p,[2,13]),{26:35,32:g},{32:[2,14]},{17:[1,36]},e(v,[2,24]),{11:37,13:4,14:22,15:y,16:T,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:d,29:c,31:n,32:g,40:l,44:f,47:b},{30:[1,38]},{42:[1,39]},{42:[1,40]},{46:[1,41]},{49:[1,42]},e(N,[2,30]),{18:[1,43]},{18:[1,44]},e(v,[2,23]),{18:[1,45]},{30:[1,46]},e(x,[2,28]),e(x,[2,35]),e(x,[2,36]),e(x,[2,37]),e(x,[2,38]),{37:[1,47]},{34:48,35:E},{15:[1,50]},e(x,[2,27]),e(N,[2,33]),{39:[1,51]},{34:52,35:E,39:[2,31]},{32:[2,15]},e(N,[2,34]),{39:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:function(o,s){if(s.recoverable)this.trace(o);else{var i=new Error(o);throw i.hash=s,i}},parse:function(o){var s=this,i=[0],u=[],h=[null],t=[],m=this.table,r="",R=0,Y=0,F=2,C=1,Se=t.slice.call(arguments,1),w=Object.create(this.lexer),K={yy:{}};for(var Z in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Z)&&(K.yy[Z]=this.yy[Z]);w.setInput(o,K.yy),K.yy.lexer=w,K.yy.parser=this,typeof w.yylloc>"u"&&(w.yylloc={});var J=w.yylloc;t.push(J);var Le=w.options&&w.options.ranges;typeof K.yy.parseError=="function"?this.parseError=K.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function me(){var P;return P=u.pop()||w.lex()||C,typeof P!="number"&&(P instanceof Array&&(u=P,P=u.pop()),P=s.symbols_[P]||P),P}for(var I,M,z,Q,W={},X,B,ae,G;;){if(M=i[i.length-1],this.defaultActions[M]?z=this.defaultActions[M]:((I===null||typeof I>"u")&&(I=me()),z=m[M]&&m[M][I]),typeof z>"u"||!z.length||!z[0]){var $="";G=[];for(X in m[M])this.terminals_[X]&&X>F&&G.push("'"+this.terminals_[X]+"'");w.showPosition?$="Parse error on line "+(R+1)+`:
+import{c as _e,b0 as se,h as H,i as ye,l as S,A as Ee,af as we,p as De}from"./mermaid.core-Q3WVcjPF.js";import{c as ve}from"./clone-bRwIupqN.js";import{i as Ne,c as ke,b as Ie,d as Oe,a as he,p as Te}from"./edges-d32062c0-DdP-jtfh.js";import{G as ze}from"./graph-yVkSecXb.js";import{o as Ce}from"./ordinal-wXG5obU4.js";import{c as Ae}from"./channel-hMLbS6Zi.js";import{s as Re}from"./Tableau10-Fgclqpgn.js";import"./app-UOvWaKji.js";import"./createText-6b48ae7d-yUX1YD6G.js";import"./line-3Gyevr9q.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";import"./init-Hi12RPRh.js";var le,oe,ee=function(){var e=function(D,o,s,i){for(s=s||{},i=D.length;i--;s[D[i]]=o);return s},a=[1,7],d=[1,13],c=[1,14],n=[1,15],g=[1,19],l=[1,16],f=[1,17],b=[1,18],p=[8,30],x=[8,21,28,29,30,31,32,40,44,47],y=[1,23],T=[1,24],v=[8,15,16,21,28,29,30,31,32,40,44,47],N=[8,15,16,21,27,28,29,30,31,32,40,44,47],E=[1,49],L={trace:function(){},yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,block:31,NODE_ID:32,nodeShapeNLabel:33,dirList:34,DIR:35,NODE_DSTART:36,NODE_DEND:37,BLOCK_ARROW_START:38,BLOCK_ARROW_END:39,classDef:40,CLASSDEF_ID:41,CLASSDEF_STYLEOPTS:42,DEFAULT:43,class:44,CLASSENTITY_IDS:45,STYLECLASS:46,style:47,STYLE_ENTITY_IDS:48,STYLE_DEFINITION_DATA:49,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"block",32:"NODE_ID",35:"DIR",36:"NODE_DSTART",37:"NODE_DEND",38:"BLOCK_ARROW_START",39:"BLOCK_ARROW_END",40:"classDef",41:"CLASSDEF_ID",42:"CLASSDEF_STYLEOPTS",43:"DEFAULT",44:"class",45:"CLASSENTITY_IDS",46:"STYLECLASS",47:"style",48:"STYLE_ENTITY_IDS",49:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[34,1],[34,2],[33,3],[33,4],[23,3],[23,3],[24,3],[25,3]],performAction:function(o,s,i,u,h,t,m){var r=t.length-1;switch(h){case 4:u.getLogger().debug("Rule: separator (NL) ");break;case 5:u.getLogger().debug("Rule: separator (Space) ");break;case 6:u.getLogger().debug("Rule: separator (EOF) ");break;case 7:u.getLogger().debug("Rule: hierarchy: ",t[r-1]),u.setHierarchy(t[r-1]);break;case 8:u.getLogger().debug("Stop NL ");break;case 9:u.getLogger().debug("Stop EOF ");break;case 10:u.getLogger().debug("Stop NL2 ");break;case 11:u.getLogger().debug("Stop EOF2 ");break;case 12:u.getLogger().debug("Rule: statement: ",t[r]),typeof t[r].length=="number"?this.$=t[r]:this.$=[t[r]];break;case 13:u.getLogger().debug("Rule: statement #2: ",t[r-1]),this.$=[t[r-1]].concat(t[r]);break;case 14:u.getLogger().debug("Rule: link: ",t[r],o),this.$={edgeTypeStr:t[r],label:""};break;case 15:u.getLogger().debug("Rule: LABEL link: ",t[r-3],t[r-1],t[r]),this.$={edgeTypeStr:t[r],label:t[r-1]};break;case 18:const R=parseInt(t[r]),Y=u.generateId();this.$={id:Y,type:"space",label:"",width:R,children:[]};break;case 23:u.getLogger().debug("Rule: (nodeStatement link node) ",t[r-2],t[r-1],t[r]," typestr: ",t[r-1].edgeTypeStr);const F=u.edgeStrToEdgeData(t[r-1].edgeTypeStr);this.$=[{id:t[r-2].id,label:t[r-2].label,type:t[r-2].type,directions:t[r-2].directions},{id:t[r-2].id+"-"+t[r].id,start:t[r-2].id,end:t[r].id,label:t[r-1].label,type:"edge",directions:t[r].directions,arrowTypeEnd:F,arrowTypeStart:"arrow_open"},{id:t[r].id,label:t[r].label,type:u.typeStr2Type(t[r].typeStr),directions:t[r].directions}];break;case 24:u.getLogger().debug("Rule: nodeStatement (abc88 node size) ",t[r-1],t[r]),this.$={id:t[r-1].id,label:t[r-1].label,type:u.typeStr2Type(t[r-1].typeStr),directions:t[r-1].directions,widthInColumns:parseInt(t[r],10)};break;case 25:u.getLogger().debug("Rule: nodeStatement (node) ",t[r]),this.$={id:t[r].id,label:t[r].label,type:u.typeStr2Type(t[r].typeStr),directions:t[r].directions,widthInColumns:1};break;case 26:u.getLogger().debug("APA123",this?this:"na"),u.getLogger().debug("COLUMNS: ",t[r]),this.$={type:"column-setting",columns:t[r]==="auto"?-1:parseInt(t[r])};break;case 27:u.getLogger().debug("Rule: id-block statement : ",t[r-2],t[r-1]),u.generateId(),this.$={...t[r-2],type:"composite",children:t[r-1]};break;case 28:u.getLogger().debug("Rule: blockStatement : ",t[r-2],t[r-1],t[r]);const C=u.generateId();this.$={id:C,type:"composite",label:"",children:t[r-1]};break;case 29:u.getLogger().debug("Rule: node (NODE_ID separator): ",t[r]),this.$={id:t[r]};break;case 30:u.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",t[r-1],t[r]),this.$={id:t[r-1],label:t[r].label,typeStr:t[r].typeStr,directions:t[r].directions};break;case 31:u.getLogger().debug("Rule: dirList: ",t[r]),this.$=[t[r]];break;case 32:u.getLogger().debug("Rule: dirList: ",t[r-1],t[r]),this.$=[t[r-1]].concat(t[r]);break;case 33:u.getLogger().debug("Rule: nodeShapeNLabel: ",t[r-2],t[r-1],t[r]),this.$={typeStr:t[r-2]+t[r],label:t[r-1]};break;case 34:u.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",t[r-3],t[r-2]," #3:",t[r-1],t[r]),this.$={typeStr:t[r-3]+t[r],label:t[r-2],directions:t[r-1]};break;case 35:case 36:this.$={type:"classDef",id:t[r-1].trim(),css:t[r].trim()};break;case 37:this.$={type:"applyClass",id:t[r-1].trim(),styleClass:t[r].trim()};break;case 38:this.$={type:"applyStyles",id:t[r-1].trim(),stylesStr:t[r].trim()};break}},table:[{9:1,10:[1,2]},{1:[3]},{11:3,13:4,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:d,29:c,31:n,32:g,40:l,44:f,47:b},{8:[1,20]},e(p,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,21:a,28:d,29:c,31:n,32:g,40:l,44:f,47:b}),e(x,[2,16],{14:22,15:y,16:T}),e(x,[2,17]),e(x,[2,18]),e(x,[2,19]),e(x,[2,20]),e(x,[2,21]),e(x,[2,22]),e(v,[2,25],{27:[1,25]}),e(x,[2,26]),{19:26,26:12,32:g},{11:27,13:4,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:d,29:c,31:n,32:g,40:l,44:f,47:b},{41:[1,28],43:[1,29]},{45:[1,30]},{48:[1,31]},e(N,[2,29],{33:32,36:[1,33],38:[1,34]}),{1:[2,7]},e(p,[2,13]),{26:35,32:g},{32:[2,14]},{17:[1,36]},e(v,[2,24]),{11:37,13:4,14:22,15:y,16:T,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:d,29:c,31:n,32:g,40:l,44:f,47:b},{30:[1,38]},{42:[1,39]},{42:[1,40]},{46:[1,41]},{49:[1,42]},e(N,[2,30]),{18:[1,43]},{18:[1,44]},e(v,[2,23]),{18:[1,45]},{30:[1,46]},e(x,[2,28]),e(x,[2,35]),e(x,[2,36]),e(x,[2,37]),e(x,[2,38]),{37:[1,47]},{34:48,35:E},{15:[1,50]},e(x,[2,27]),e(N,[2,33]),{39:[1,51]},{34:52,35:E,39:[2,31]},{32:[2,15]},e(N,[2,34]),{39:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:function(o,s){if(s.recoverable)this.trace(o);else{var i=new Error(o);throw i.hash=s,i}},parse:function(o){var s=this,i=[0],u=[],h=[null],t=[],m=this.table,r="",R=0,Y=0,F=2,C=1,Se=t.slice.call(arguments,1),w=Object.create(this.lexer),K={yy:{}};for(var Z in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Z)&&(K.yy[Z]=this.yy[Z]);w.setInput(o,K.yy),K.yy.lexer=w,K.yy.parser=this,typeof w.yylloc>"u"&&(w.yylloc={});var J=w.yylloc;t.push(J);var Le=w.options&&w.options.ranges;typeof K.yy.parseError=="function"?this.parseError=K.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function me(){var P;return P=u.pop()||w.lex()||C,typeof P!="number"&&(P instanceof Array&&(u=P,P=u.pop()),P=s.symbols_[P]||P),P}for(var I,M,z,Q,W={},X,B,ae,G;;){if(M=i[i.length-1],this.defaultActions[M]?z=this.defaultActions[M]:((I===null||typeof I>"u")&&(I=me()),z=m[M]&&m[M][I]),typeof z>"u"||!z.length||!z[0]){var $="";G=[];for(X in m[M])this.terminals_[X]&&X>F&&G.push("'"+this.terminals_[X]+"'");w.showPosition?$="Parse error on line "+(R+1)+`:
 `+w.showPosition()+`
 Expecting `+G.join(", ")+", got '"+(this.terminals_[I]||I)+"'":$="Parse error on line "+(R+1)+": Unexpected "+(I==C?"end of input":"'"+(this.terminals_[I]||I)+"'"),this.parseError($,{text:w.match,token:this.terminals_[I]||I,line:w.yylineno,loc:J,expected:G})}if(z[0]instanceof Array&&z.length>1)throw new Error("Parse Error: multiple actions possible at state: "+M+", token: "+I);switch(z[0]){case 1:i.push(I),h.push(w.yytext),t.push(w.yylloc),i.push(z[1]),I=null,Y=w.yyleng,r=w.yytext,R=w.yylineno,J=w.yylloc;break;case 2:if(B=this.productions_[z[1]][1],W.$=h[h.length-B],W._$={first_line:t[t.length-(B||1)].first_line,last_line:t[t.length-1].last_line,first_column:t[t.length-(B||1)].first_column,last_column:t[t.length-1].last_column},Le&&(W._$.range=[t[t.length-(B||1)].range[0],t[t.length-1].range[1]]),Q=this.performAction.apply(W,[r,Y,R,K.yy,z[1],h,t].concat(Se)),typeof Q<"u")return Q;B&&(i=i.slice(0,-1*B*2),h=h.slice(0,-1*B),t=t.slice(0,-1*B)),i.push(this.productions_[z[1]][0]),h.push(W.$),t.push(W._$),ae=m[i[i.length-2]][i[i.length-1]],i.push(ae);break;case 3:return!0}}return!0}},A=function(){var D={EOF:1,parseError:function(s,i){if(this.yy.parser)this.yy.parser.parseError(s,i);else throw new Error(s)},setInput:function(o,s){return this.yy=s||this.yy||{},this._input=o,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var o=this._input[0];this.yytext+=o,this.yyleng++,this.offset++,this.match+=o,this.matched+=o;var s=o.match(/(?:\r\n?|\n).*/g);return s?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),o},unput:function(o){var s=o.length,i=o.split(/(?:\r\n?|\n)/g);this._input=o+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-s),this.offset-=s;var u=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var h=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===u.length?this.yylloc.first_column:0)+u[u.length-i.length].length-i[0].length:this.yylloc.first_column-s},this.options.ranges&&(this.yylloc.range=[h[0],h[0]+this.yyleng-s]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
 `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(o){this.unput(this.match.slice(o))},pastInput:function(){var o=this.matched.substr(0,this.matched.length-this.match.length);return(o.length>20?"...":"")+o.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var o=this.match;return o.length<20&&(o+=this._input.substr(0,20-o.length)),(o.substr(0,20)+(o.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var o=this.pastInput(),s=new Array(o.length+1).join("-");return o+this.upcomingInput()+`
diff --git a/assets/browser_dialer.html-oocymKeb.js b/assets/browser_dialer.html-ioRP4mhn.js
similarity index 98%
rename from assets/browser_dialer.html-oocymKeb.js
rename to assets/browser_dialer.html-ioRP4mhn.js
index 6a5aa3793a..cc3fc1a0a9 100644
--- a/assets/browser_dialer.html-oocymKeb.js
+++ b/assets/browser_dialer.html-ioRP4mhn.js
@@ -1 +1 @@
-import{_ as c,r as l,o as s,c as d,d as a,b as o,a as e,e as t}from"./app-PDrbPfzp.js";const i={},_=e("h1",{id:"browser-dialer",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#browser-dialer"},[e("span",null,"Browser Dialer")])],-1),h=e("h2",{id:"background",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#background"},[e("span",null,"Background")])],-1),u={href:"https://github.com/v2ray/discussion/issues/754#issuecomment-647934994",target:"_blank",rel:"noopener noreferrer"},p=t('

不过 WSS 仍存在 ALPN 明显的问题,所以下一步是浏览器转发 HTTP/2,QUIC

Xray & JS

创造了一个非常简单、巧妙的通信机制:

  • Xray 监听地址端口 A,作为 HTTP 服务,浏览器访问 A,加载网页中的 JS。
  • JS 主动向 A 建立 WebSocket 连接,成功后,Xray 将连接发给 channel。
  • 需要建立连接时,Xray 从 channel 接收一个可用的连接,并发送目标 URL 和可选的 early data。
  • JS 成功连接到目标后告知 Xray,并继续用这个 conn 全双工双向转发数据,连接关闭行为同步。
  • 连接使用后就会被关闭,但 JS 会确保始终有新空闲连接可用。

Early data

根据浏览器的需求,对 early data 机制进行了如下调整:

',6),S=e("li",null,[o("服务端响应头会带有请求的 "),e("code",null,"Sec-WebSocket-Protocol"),o(",这也初步混淆了 WSS 握手响应的长度特征。")],-1),y=e("li",null,[o("用于浏览器的 early data 编码是 "),e("code",null,"base64.RawURLEncoding"),o(" 而不是 "),e("code",null,"StdEncoding"),o(",服务端做了兼容。")],-1),b={href:"https://github.com/XTLS/Xray-core/pull/375",target:"_blank",rel:"noopener noreferrer"},f=e("code",null,"?ed=2048",-1),x=e("code",null,"MaxHeaderBytes",-1),g=e("s",null,"(虽然好像不改也没问题)",-1),m={id:"configuration",tabindex:"-1"},k={class:"header-anchor",href:"#configuration"},X=t("

这是一个探索的过程,目前两边都是 Xray-core v1.4.1 时的配置方式:

  • 准备一份可用的 WSS 配置,注意 address 必须填域名,若需要指定 IP,请配置 DNS 或系统 hosts。
  • 若浏览器的流量也会经过 Xray-core,务必将这个域名设为直连,否则会造成流量回环。
  • 设置环境变量指定要监听的地址端口,比如 XRAY_BROWSER_DIALER = 127.0.0.1:8080
  • 先运行 Xray-core,再用任意浏览器访问上面指定的地址端口,还可以 F12ConsoleNetwork
  • 浏览器会限制 WebSocket 连接数,所以建议开启 Mux.Cool
",2);function w(B,E){const n=l("Badge"),r=l("ExternalLinkIcon");return s(),d("div",null,[_,a(n,{text:"BETA",type:"warning"}),o(),a(n,{text:"v1.4.1+",type:"warning"}),h,e("p",null,[o("基于 "),e("a",u,[o("一年前的想法"),a(r)]),o(" ,利用原生 JS 实现了简洁的 WSS Browser Dialer,达到了真实浏览器的 TLS 指纹、行为特征。")]),p,e("ul",null,[S,y,e("li",null,[o("此外,由于 "),e("a",b,[o("Xray-core#375"),a(r)]),o(" 推荐 "),f,o(",这个 PR 顺便将服务端一处 "),x,o(" 扩至了 4096。 "),g])]),e("h2",m,[e("a",k,[e("span",null,[o("Configuration "),a(n,{text:"v1.4.1",type:"warning"})])])]),X])}const R=c(i,[["render",w],["__file","browser_dialer.html.vue"]]);export{R as default}; +import{_ as c,r as l,o as s,c as d,d as a,b as o,a as e,e as t}from"./app-UOvWaKji.js";const i={},_=e("h1",{id:"browser-dialer",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#browser-dialer"},[e("span",null,"Browser Dialer")])],-1),h=e("h2",{id:"background",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#background"},[e("span",null,"Background")])],-1),u={href:"https://github.com/v2ray/discussion/issues/754#issuecomment-647934994",target:"_blank",rel:"noopener noreferrer"},p=t('

不过 WSS 仍存在 ALPN 明显的问题,所以下一步是浏览器转发 HTTP/2,QUIC

Xray & JS

创造了一个非常简单、巧妙的通信机制:

  • Xray 监听地址端口 A,作为 HTTP 服务,浏览器访问 A,加载网页中的 JS。
  • JS 主动向 A 建立 WebSocket 连接,成功后,Xray 将连接发给 channel。
  • 需要建立连接时,Xray 从 channel 接收一个可用的连接,并发送目标 URL 和可选的 early data。
  • JS 成功连接到目标后告知 Xray,并继续用这个 conn 全双工双向转发数据,连接关闭行为同步。
  • 连接使用后就会被关闭,但 JS 会确保始终有新空闲连接可用。

Early data

根据浏览器的需求,对 early data 机制进行了如下调整:

',6),S=e("li",null,[o("服务端响应头会带有请求的 "),e("code",null,"Sec-WebSocket-Protocol"),o(",这也初步混淆了 WSS 握手响应的长度特征。")],-1),y=e("li",null,[o("用于浏览器的 early data 编码是 "),e("code",null,"base64.RawURLEncoding"),o(" 而不是 "),e("code",null,"StdEncoding"),o(",服务端做了兼容。")],-1),b={href:"https://github.com/XTLS/Xray-core/pull/375",target:"_blank",rel:"noopener noreferrer"},f=e("code",null,"?ed=2048",-1),x=e("code",null,"MaxHeaderBytes",-1),g=e("s",null,"(虽然好像不改也没问题)",-1),m={id:"configuration",tabindex:"-1"},k={class:"header-anchor",href:"#configuration"},X=t("

这是一个探索的过程,目前两边都是 Xray-core v1.4.1 时的配置方式:

  • 准备一份可用的 WSS 配置,注意 address 必须填域名,若需要指定 IP,请配置 DNS 或系统 hosts。
  • 若浏览器的流量也会经过 Xray-core,务必将这个域名设为直连,否则会造成流量回环。
  • 设置环境变量指定要监听的地址端口,比如 XRAY_BROWSER_DIALER = 127.0.0.1:8080
  • 先运行 Xray-core,再用任意浏览器访问上面指定的地址端口,还可以 F12ConsoleNetwork
  • 浏览器会限制 WebSocket 连接数,所以建议开启 Mux.Cool
",2);function w(B,E){const n=l("Badge"),r=l("ExternalLinkIcon");return s(),d("div",null,[_,a(n,{text:"BETA",type:"warning"}),o(),a(n,{text:"v1.4.1+",type:"warning"}),h,e("p",null,[o("基于 "),e("a",u,[o("一年前的想法"),a(r)]),o(" ,利用原生 JS 实现了简洁的 WSS Browser Dialer,达到了真实浏览器的 TLS 指纹、行为特征。")]),p,e("ul",null,[S,y,e("li",null,[o("此外,由于 "),e("a",b,[o("Xray-core#375"),a(r)]),o(" 推荐 "),f,o(",这个 PR 顺便将服务端一处 "),x,o(" 扩至了 4096。 "),g])]),e("h2",m,[e("a",k,[e("span",null,[o("Configuration "),a(n,{text:"v1.4.1",type:"warning"})])])]),X])}const R=c(i,[["render",w],["__file","browser_dialer.html.vue"]]);export{R as default}; diff --git a/assets/browser_dialer.html-xSfDwx9j.js b/assets/browser_dialer.html-oLr7tN0I.js similarity index 98% rename from assets/browser_dialer.html-xSfDwx9j.js rename to assets/browser_dialer.html-oLr7tN0I.js index 946c141385..70e7bb5dbc 100644 --- a/assets/browser_dialer.html-xSfDwx9j.js +++ b/assets/browser_dialer.html-oLr7tN0I.js @@ -1 +1 @@ -import{_ as r,r as a,o as c,c as l,d as n,b as o,a as e,e as i}from"./app-PDrbPfzp.js";const d={},h=e("h1",{id:"browser-dialer",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#browser-dialer"},[e("span",null,"Browser Dialer")])],-1),u=e("h2",{id:"background",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#background"},[e("span",null,"Background")])],-1),_={href:"https://github.com/v2ray/discussion/issues/754#issuecomment-647934994",target:"_blank",rel:"noopener noreferrer"},f=e("code",null,"WSS Browser Dialer",-1),b=e("code",null,"JS",-1),p=e("code",null,"WSS",-1),m=e("code",null,"ALPN",-1),w=e("code",null,"HTTP/2",-1),y=e("code",null,"QUIC",-1),g=i('

Xray & JS

A very simple and clever communication mechanism has been created:

  • Xray listens on address port A as an HTTP service, and the browser accesses A to load the JS in the webpage.
  • The JS actively establishes a WebSocket connection to A. After a successful connection, Xray sends the connection to the channel.
  • When a connection needs to be established, Xray receives an available connection from the channel and sends the target URL and optional early data.
  • Once the JS successfully connects to the target, it informs Xray and continues to use this conn to bi-directionally forward data. Connection closing behavior is synchronized.
  • After the connection is used, it will be closed, but the JS ensures that there is always a new idle connection available."

Early data

According to the browser's needs, the early data mechanism has been adjusted as follows:

',5),S=e("li",null,[o("The server response header will contain the requested "),e("code",null,"Sec-WebSocket-Protocol"),o(", which also initially obfuscates the length characteristic of the WSS handshake response.")],-1),v=e("li",null,[o("The encoding used for early data for browsers is "),e("code",null,"base64.RawURLEncoding"),o(" instead of "),e("code",null,"StdEncoding"),o(", and the server has made it compatible.")],-1),x={href:"https://github.com/XTLS/Xray-core/pull/375",target:"_blank",rel:"noopener noreferrer"},k=e("code",null,"?ed=2048",-1),T=e("code",null,"MaxHeaderBytes",-1),A=e("s",null,"(Although it seems like it would work without modification.)",-1),B={id:"configuration",tabindex:"-1"},X={class:"header-anchor",href:"#configuration"},E=i("

This is an exploratory process, and the configuration method used when both sides are Xray-core v1.4.1 is as follows:

  • Prepare a usable WSS configuration, making sure to fill in the domain name for the address. If you need to specify an IP address, configure DNS or system hosts.
  • If browser traffic will also pass through Xray-core, be sure to set this domain name as a direct connection, otherwise it will cause traffic looping.
  • Set the environment variable to specify the address port to listen on, such as XRAY_BROWSER_DIALER = 127.0.0.1:8080.
  • First run Xray-core, then use any browser to access the specified address port, and you can also check Console and Network with F12.
  • The browser will limit the number of WebSocket connections, so it is recommended to enable Mux.Cool.
",2);function W(I,L){const t=a("Badge"),s=a("ExternalLinkIcon");return c(),l("div",null,[h,n(t,{text:"BETA",type:"warning"}),o(),n(t,{text:"v1.4.1+",type:"warning"}),u,e("p",null,[o("Based on "),e("a",_,[o("an idea from 2020"),n(s)]),o(", a concise "),f,o(" has been implemented using native "),b,o(", achieving true browser TLS fingerprints and behavioral characteristics. However, "),p,o(" still has significant issues with "),m,o(", so the next step is to forward "),w,o(" and "),y,o(' through the browser."')]),g,e("ul",null,[S,v,e("li",null,[o("In addition, due to "),e("a",x,[o("Xray-core#375"),n(s)]),o(" recommendations for "),k,o(", this PR also increased server "),T,o(" by 4096. "),A])]),e("h2",B,[e("a",X,[e("span",null,[o("Configuration "),n(t,{text:"v1.4.1",type:"warning"})])])]),E])}const N=r(d,[["render",W],["__file","browser_dialer.html.vue"]]);export{N as default}; +import{_ as r,r as a,o as c,c as l,d as n,b as o,a as e,e as i}from"./app-UOvWaKji.js";const d={},h=e("h1",{id:"browser-dialer",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#browser-dialer"},[e("span",null,"Browser Dialer")])],-1),u=e("h2",{id:"background",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#background"},[e("span",null,"Background")])],-1),_={href:"https://github.com/v2ray/discussion/issues/754#issuecomment-647934994",target:"_blank",rel:"noopener noreferrer"},f=e("code",null,"WSS Browser Dialer",-1),b=e("code",null,"JS",-1),p=e("code",null,"WSS",-1),m=e("code",null,"ALPN",-1),w=e("code",null,"HTTP/2",-1),y=e("code",null,"QUIC",-1),g=i('

Xray & JS

A very simple and clever communication mechanism has been created:

  • Xray listens on address port A as an HTTP service, and the browser accesses A to load the JS in the webpage.
  • The JS actively establishes a WebSocket connection to A. After a successful connection, Xray sends the connection to the channel.
  • When a connection needs to be established, Xray receives an available connection from the channel and sends the target URL and optional early data.
  • Once the JS successfully connects to the target, it informs Xray and continues to use this conn to bi-directionally forward data. Connection closing behavior is synchronized.
  • After the connection is used, it will be closed, but the JS ensures that there is always a new idle connection available."

Early data

According to the browser's needs, the early data mechanism has been adjusted as follows:

',5),S=e("li",null,[o("The server response header will contain the requested "),e("code",null,"Sec-WebSocket-Protocol"),o(", which also initially obfuscates the length characteristic of the WSS handshake response.")],-1),v=e("li",null,[o("The encoding used for early data for browsers is "),e("code",null,"base64.RawURLEncoding"),o(" instead of "),e("code",null,"StdEncoding"),o(", and the server has made it compatible.")],-1),x={href:"https://github.com/XTLS/Xray-core/pull/375",target:"_blank",rel:"noopener noreferrer"},k=e("code",null,"?ed=2048",-1),T=e("code",null,"MaxHeaderBytes",-1),A=e("s",null,"(Although it seems like it would work without modification.)",-1),B={id:"configuration",tabindex:"-1"},X={class:"header-anchor",href:"#configuration"},E=i("

This is an exploratory process, and the configuration method used when both sides are Xray-core v1.4.1 is as follows:

  • Prepare a usable WSS configuration, making sure to fill in the domain name for the address. If you need to specify an IP address, configure DNS or system hosts.
  • If browser traffic will also pass through Xray-core, be sure to set this domain name as a direct connection, otherwise it will cause traffic looping.
  • Set the environment variable to specify the address port to listen on, such as XRAY_BROWSER_DIALER = 127.0.0.1:8080.
  • First run Xray-core, then use any browser to access the specified address port, and you can also check Console and Network with F12.
  • The browser will limit the number of WebSocket connections, so it is recommended to enable Mux.Cool.
",2);function W(I,L){const t=a("Badge"),s=a("ExternalLinkIcon");return c(),l("div",null,[h,n(t,{text:"BETA",type:"warning"}),o(),n(t,{text:"v1.4.1+",type:"warning"}),u,e("p",null,[o("Based on "),e("a",_,[o("an idea from 2020"),n(s)]),o(", a concise "),f,o(" has been implemented using native "),b,o(", achieving true browser TLS fingerprints and behavioral characteristics. However, "),p,o(" still has significant issues with "),m,o(", so the next step is to forward "),w,o(" and "),y,o(' through the browser."')]),g,e("ul",null,[S,v,e("li",null,[o("In addition, due to "),e("a",x,[o("Xray-core#375"),n(s)]),o(" recommendations for "),k,o(", this PR also increased server "),T,o(" by 4096. "),A])]),e("h2",B,[e("a",X,[e("span",null,[o("Configuration "),n(t,{text:"v1.4.1",type:"warning"})])])]),E])}const N=r(d,[["render",W],["__file","browser_dialer.html.vue"]]);export{N as default}; diff --git a/assets/c4Diagram-b2a90758-61jLNFqu.js b/assets/c4Diagram-b2a90758-Ozn2CEAW.js similarity index 99% rename from assets/c4Diagram-b2a90758-61jLNFqu.js rename to assets/c4Diagram-b2a90758-Ozn2CEAW.js index d5e1af8f37..58fee6f971 100644 --- a/assets/c4Diagram-b2a90758-61jLNFqu.js +++ b/assets/c4Diagram-b2a90758-Ozn2CEAW.js @@ -1,4 +1,4 @@ -import{s as we,g as Oe,a as Te,b as Re,c as Dt,d as ue,e as De,f as wt,h as Nt,l as le,i as Se,w as Pe,j as Kt,k as oe,m as Me}from"./mermaid.core-95b3ca__.js";import{d as Le,g as Ne}from"./svgDrawCommon-5ccd53ef-iJa2TVTb.js";import"./app-PDrbPfzp.js";var Yt=function(){var e=function(bt,_,x,m){for(x=x||{},m=bt.length;m--;x[bt[m]]=_);return x},t=[1,24],a=[1,25],o=[1,26],l=[1,27],i=[1,28],s=[1,63],r=[1,64],n=[1,65],h=[1,66],f=[1,67],d=[1,68],p=[1,69],E=[1,29],O=[1,30],R=[1,31],S=[1,32],L=[1,33],Y=[1,34],Q=[1,35],H=[1,36],q=[1,37],G=[1,38],K=[1,39],J=[1,40],Z=[1,41],$=[1,42],tt=[1,43],et=[1,44],it=[1,45],nt=[1,46],st=[1,47],at=[1,48],rt=[1,50],lt=[1,51],ot=[1,52],ct=[1,53],ht=[1,54],ut=[1,55],dt=[1,56],ft=[1,57],pt=[1,58],yt=[1,59],gt=[1,60],At=[14,42],Vt=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],Ot=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],v=[1,82],k=[1,83],A=[1,84],C=[1,85],w=[12,14,42],ne=[12,14,33,42],Pt=[12,14,33,42,76,77,79,80],mt=[12,33],zt=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],Xt={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:function(_,x,m,g,T,u,Tt){var y=u.length-1;switch(T){case 3:g.setDirection("TB");break;case 4:g.setDirection("BT");break;case 5:g.setDirection("RL");break;case 6:g.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:g.setC4Type(u[y-3]);break;case 19:g.setTitle(u[y].substring(6)),this.$=u[y].substring(6);break;case 20:g.setAccDescription(u[y].substring(15)),this.$=u[y].substring(15);break;case 21:this.$=u[y].trim(),g.setTitle(this.$);break;case 22:case 23:this.$=u[y].trim(),g.setAccDescription(this.$);break;case 28:case 29:u[y].splice(2,0,"ENTERPRISE"),g.addPersonOrSystemBoundary(...u[y]),this.$=u[y];break;case 30:g.addPersonOrSystemBoundary(...u[y]),this.$=u[y];break;case 31:u[y].splice(2,0,"CONTAINER"),g.addContainerBoundary(...u[y]),this.$=u[y];break;case 32:g.addDeploymentNode("node",...u[y]),this.$=u[y];break;case 33:g.addDeploymentNode("nodeL",...u[y]),this.$=u[y];break;case 34:g.addDeploymentNode("nodeR",...u[y]),this.$=u[y];break;case 35:g.popBoundaryParseStack();break;case 39:g.addPersonOrSystem("person",...u[y]),this.$=u[y];break;case 40:g.addPersonOrSystem("external_person",...u[y]),this.$=u[y];break;case 41:g.addPersonOrSystem("system",...u[y]),this.$=u[y];break;case 42:g.addPersonOrSystem("system_db",...u[y]),this.$=u[y];break;case 43:g.addPersonOrSystem("system_queue",...u[y]),this.$=u[y];break;case 44:g.addPersonOrSystem("external_system",...u[y]),this.$=u[y];break;case 45:g.addPersonOrSystem("external_system_db",...u[y]),this.$=u[y];break;case 46:g.addPersonOrSystem("external_system_queue",...u[y]),this.$=u[y];break;case 47:g.addContainer("container",...u[y]),this.$=u[y];break;case 48:g.addContainer("container_db",...u[y]),this.$=u[y];break;case 49:g.addContainer("container_queue",...u[y]),this.$=u[y];break;case 50:g.addContainer("external_container",...u[y]),this.$=u[y];break;case 51:g.addContainer("external_container_db",...u[y]),this.$=u[y];break;case 52:g.addContainer("external_container_queue",...u[y]),this.$=u[y];break;case 53:g.addComponent("component",...u[y]),this.$=u[y];break;case 54:g.addComponent("component_db",...u[y]),this.$=u[y];break;case 55:g.addComponent("component_queue",...u[y]),this.$=u[y];break;case 56:g.addComponent("external_component",...u[y]),this.$=u[y];break;case 57:g.addComponent("external_component_db",...u[y]),this.$=u[y];break;case 58:g.addComponent("external_component_queue",...u[y]),this.$=u[y];break;case 60:g.addRel("rel",...u[y]),this.$=u[y];break;case 61:g.addRel("birel",...u[y]),this.$=u[y];break;case 62:g.addRel("rel_u",...u[y]),this.$=u[y];break;case 63:g.addRel("rel_d",...u[y]),this.$=u[y];break;case 64:g.addRel("rel_l",...u[y]),this.$=u[y];break;case 65:g.addRel("rel_r",...u[y]),this.$=u[y];break;case 66:g.addRel("rel_b",...u[y]),this.$=u[y];break;case 67:u[y].splice(0,1),g.addRel("rel",...u[y]),this.$=u[y];break;case 68:g.updateElStyle("update_el_style",...u[y]),this.$=u[y];break;case 69:g.updateRelStyle("update_rel_style",...u[y]),this.$=u[y];break;case 70:g.updateLayoutConfig("update_layout_config",...u[y]),this.$=u[y];break;case 71:this.$=[u[y]];break;case 72:u[y].unshift(u[y-1]),this.$=u[y];break;case 73:case 75:this.$=u[y].trim();break;case 74:let Et={};Et[u[y-1].trim()]=u[y].trim(),this.$=Et;break;case 76:this.$="";break}},table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:t,23:a,24:o,26:l,28:i,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{13:70,19:20,20:21,21:22,22:t,23:a,24:o,26:l,28:i,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{13:71,19:20,20:21,21:22,22:t,23:a,24:o,26:l,28:i,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{13:72,19:20,20:21,21:22,22:t,23:a,24:o,26:l,28:i,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{13:73,19:20,20:21,21:22,22:t,23:a,24:o,26:l,28:i,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{14:[1,74]},e(At,[2,13],{43:23,29:49,30:61,32:62,20:75,34:s,36:r,37:n,38:h,39:f,40:d,41:p,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt}),e(At,[2,14]),e(Vt,[2,16],{12:[1,76]}),e(At,[2,36],{12:[1,77]}),e(Ot,[2,19]),e(Ot,[2,20]),{25:[1,78]},{27:[1,79]},e(Ot,[2,23]),{35:80,75:81,76:v,77:k,79:A,80:C},{35:86,75:81,76:v,77:k,79:A,80:C},{35:87,75:81,76:v,77:k,79:A,80:C},{35:88,75:81,76:v,77:k,79:A,80:C},{35:89,75:81,76:v,77:k,79:A,80:C},{35:90,75:81,76:v,77:k,79:A,80:C},{35:91,75:81,76:v,77:k,79:A,80:C},{35:92,75:81,76:v,77:k,79:A,80:C},{35:93,75:81,76:v,77:k,79:A,80:C},{35:94,75:81,76:v,77:k,79:A,80:C},{35:95,75:81,76:v,77:k,79:A,80:C},{35:96,75:81,76:v,77:k,79:A,80:C},{35:97,75:81,76:v,77:k,79:A,80:C},{35:98,75:81,76:v,77:k,79:A,80:C},{35:99,75:81,76:v,77:k,79:A,80:C},{35:100,75:81,76:v,77:k,79:A,80:C},{35:101,75:81,76:v,77:k,79:A,80:C},{35:102,75:81,76:v,77:k,79:A,80:C},{35:103,75:81,76:v,77:k,79:A,80:C},{35:104,75:81,76:v,77:k,79:A,80:C},e(w,[2,59]),{35:105,75:81,76:v,77:k,79:A,80:C},{35:106,75:81,76:v,77:k,79:A,80:C},{35:107,75:81,76:v,77:k,79:A,80:C},{35:108,75:81,76:v,77:k,79:A,80:C},{35:109,75:81,76:v,77:k,79:A,80:C},{35:110,75:81,76:v,77:k,79:A,80:C},{35:111,75:81,76:v,77:k,79:A,80:C},{35:112,75:81,76:v,77:k,79:A,80:C},{35:113,75:81,76:v,77:k,79:A,80:C},{35:114,75:81,76:v,77:k,79:A,80:C},{35:115,75:81,76:v,77:k,79:A,80:C},{20:116,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{12:[1,118],33:[1,117]},{35:119,75:81,76:v,77:k,79:A,80:C},{35:120,75:81,76:v,77:k,79:A,80:C},{35:121,75:81,76:v,77:k,79:A,80:C},{35:122,75:81,76:v,77:k,79:A,80:C},{35:123,75:81,76:v,77:k,79:A,80:C},{35:124,75:81,76:v,77:k,79:A,80:C},{35:125,75:81,76:v,77:k,79:A,80:C},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},e(At,[2,15]),e(Vt,[2,17],{21:22,19:130,22:t,23:a,24:o,26:l,28:i}),e(At,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:t,23:a,24:o,26:l,28:i,34:s,36:r,37:n,38:h,39:f,40:d,41:p,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt}),e(Ot,[2,21]),e(Ot,[2,22]),e(w,[2,39]),e(ne,[2,71],{75:81,35:132,76:v,77:k,79:A,80:C}),e(Pt,[2,73]),{78:[1,133]},e(Pt,[2,75]),e(Pt,[2,76]),e(w,[2,40]),e(w,[2,41]),e(w,[2,42]),e(w,[2,43]),e(w,[2,44]),e(w,[2,45]),e(w,[2,46]),e(w,[2,47]),e(w,[2,48]),e(w,[2,49]),e(w,[2,50]),e(w,[2,51]),e(w,[2,52]),e(w,[2,53]),e(w,[2,54]),e(w,[2,55]),e(w,[2,56]),e(w,[2,57]),e(w,[2,58]),e(w,[2,60]),e(w,[2,61]),e(w,[2,62]),e(w,[2,63]),e(w,[2,64]),e(w,[2,65]),e(w,[2,66]),e(w,[2,67]),e(w,[2,68]),e(w,[2,69]),e(w,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},e(mt,[2,28]),e(mt,[2,29]),e(mt,[2,30]),e(mt,[2,31]),e(mt,[2,32]),e(mt,[2,33]),e(mt,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},e(Vt,[2,18]),e(At,[2,38]),e(ne,[2,72]),e(Pt,[2,74]),e(w,[2,24]),e(w,[2,35]),e(zt,[2,25]),e(zt,[2,26],{12:[1,138]}),e(zt,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:function(_,x){if(x.recoverable)this.trace(_);else{var m=new Error(_);throw m.hash=x,m}},parse:function(_){var x=this,m=[0],g=[],T=[null],u=[],Tt=this.table,y="",Et=0,se=0,ve=2,ae=1,ke=u.slice.call(arguments,1),D=Object.create(this.lexer),vt={yy:{}};for(var Qt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Qt)&&(vt.yy[Qt]=this.yy[Qt]);D.setInput(_,vt.yy),vt.yy.lexer=D,vt.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var Ht=D.yylloc;u.push(Ht);var Ae=D.options&&D.options.ranges;typeof vt.yy.parseError=="function"?this.parseError=vt.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ce(){var X;return X=g.pop()||D.lex()||ae,typeof X!="number"&&(X instanceof Array&&(g=X,X=g.pop()),X=x.symbols_[X]||X),X}for(var M,kt,N,qt,Ct={},Mt,z,re,Lt;;){if(kt=m[m.length-1],this.defaultActions[kt]?N=this.defaultActions[kt]:((M===null||typeof M>"u")&&(M=Ce()),N=Tt[kt]&&Tt[kt][M]),typeof N>"u"||!N.length||!N[0]){var Gt="";Lt=[];for(Mt in Tt[kt])this.terminals_[Mt]&&Mt>ve&&Lt.push("'"+this.terminals_[Mt]+"'");D.showPosition?Gt="Parse error on line "+(Et+1)+`: +import{s as we,g as Oe,a as Te,b as Re,c as Dt,d as ue,e as De,f as wt,h as Nt,l as le,i as Se,w as Pe,j as Kt,k as oe,m as Me}from"./mermaid.core-Q3WVcjPF.js";import{d as Le,g as Ne}from"./svgDrawCommon-5ccd53ef-wBNBFr7n.js";import"./app-UOvWaKji.js";var Yt=function(){var e=function(bt,_,x,m){for(x=x||{},m=bt.length;m--;x[bt[m]]=_);return x},t=[1,24],a=[1,25],o=[1,26],l=[1,27],i=[1,28],s=[1,63],r=[1,64],n=[1,65],h=[1,66],f=[1,67],d=[1,68],p=[1,69],E=[1,29],O=[1,30],R=[1,31],S=[1,32],L=[1,33],Y=[1,34],Q=[1,35],H=[1,36],q=[1,37],G=[1,38],K=[1,39],J=[1,40],Z=[1,41],$=[1,42],tt=[1,43],et=[1,44],it=[1,45],nt=[1,46],st=[1,47],at=[1,48],rt=[1,50],lt=[1,51],ot=[1,52],ct=[1,53],ht=[1,54],ut=[1,55],dt=[1,56],ft=[1,57],pt=[1,58],yt=[1,59],gt=[1,60],At=[14,42],Vt=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],Ot=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],v=[1,82],k=[1,83],A=[1,84],C=[1,85],w=[12,14,42],ne=[12,14,33,42],Pt=[12,14,33,42,76,77,79,80],mt=[12,33],zt=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],Xt={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:function(_,x,m,g,T,u,Tt){var y=u.length-1;switch(T){case 3:g.setDirection("TB");break;case 4:g.setDirection("BT");break;case 5:g.setDirection("RL");break;case 6:g.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:g.setC4Type(u[y-3]);break;case 19:g.setTitle(u[y].substring(6)),this.$=u[y].substring(6);break;case 20:g.setAccDescription(u[y].substring(15)),this.$=u[y].substring(15);break;case 21:this.$=u[y].trim(),g.setTitle(this.$);break;case 22:case 23:this.$=u[y].trim(),g.setAccDescription(this.$);break;case 28:case 29:u[y].splice(2,0,"ENTERPRISE"),g.addPersonOrSystemBoundary(...u[y]),this.$=u[y];break;case 30:g.addPersonOrSystemBoundary(...u[y]),this.$=u[y];break;case 31:u[y].splice(2,0,"CONTAINER"),g.addContainerBoundary(...u[y]),this.$=u[y];break;case 32:g.addDeploymentNode("node",...u[y]),this.$=u[y];break;case 33:g.addDeploymentNode("nodeL",...u[y]),this.$=u[y];break;case 34:g.addDeploymentNode("nodeR",...u[y]),this.$=u[y];break;case 35:g.popBoundaryParseStack();break;case 39:g.addPersonOrSystem("person",...u[y]),this.$=u[y];break;case 40:g.addPersonOrSystem("external_person",...u[y]),this.$=u[y];break;case 41:g.addPersonOrSystem("system",...u[y]),this.$=u[y];break;case 42:g.addPersonOrSystem("system_db",...u[y]),this.$=u[y];break;case 43:g.addPersonOrSystem("system_queue",...u[y]),this.$=u[y];break;case 44:g.addPersonOrSystem("external_system",...u[y]),this.$=u[y];break;case 45:g.addPersonOrSystem("external_system_db",...u[y]),this.$=u[y];break;case 46:g.addPersonOrSystem("external_system_queue",...u[y]),this.$=u[y];break;case 47:g.addContainer("container",...u[y]),this.$=u[y];break;case 48:g.addContainer("container_db",...u[y]),this.$=u[y];break;case 49:g.addContainer("container_queue",...u[y]),this.$=u[y];break;case 50:g.addContainer("external_container",...u[y]),this.$=u[y];break;case 51:g.addContainer("external_container_db",...u[y]),this.$=u[y];break;case 52:g.addContainer("external_container_queue",...u[y]),this.$=u[y];break;case 53:g.addComponent("component",...u[y]),this.$=u[y];break;case 54:g.addComponent("component_db",...u[y]),this.$=u[y];break;case 55:g.addComponent("component_queue",...u[y]),this.$=u[y];break;case 56:g.addComponent("external_component",...u[y]),this.$=u[y];break;case 57:g.addComponent("external_component_db",...u[y]),this.$=u[y];break;case 58:g.addComponent("external_component_queue",...u[y]),this.$=u[y];break;case 60:g.addRel("rel",...u[y]),this.$=u[y];break;case 61:g.addRel("birel",...u[y]),this.$=u[y];break;case 62:g.addRel("rel_u",...u[y]),this.$=u[y];break;case 63:g.addRel("rel_d",...u[y]),this.$=u[y];break;case 64:g.addRel("rel_l",...u[y]),this.$=u[y];break;case 65:g.addRel("rel_r",...u[y]),this.$=u[y];break;case 66:g.addRel("rel_b",...u[y]),this.$=u[y];break;case 67:u[y].splice(0,1),g.addRel("rel",...u[y]),this.$=u[y];break;case 68:g.updateElStyle("update_el_style",...u[y]),this.$=u[y];break;case 69:g.updateRelStyle("update_rel_style",...u[y]),this.$=u[y];break;case 70:g.updateLayoutConfig("update_layout_config",...u[y]),this.$=u[y];break;case 71:this.$=[u[y]];break;case 72:u[y].unshift(u[y-1]),this.$=u[y];break;case 73:case 75:this.$=u[y].trim();break;case 74:let Et={};Et[u[y-1].trim()]=u[y].trim(),this.$=Et;break;case 76:this.$="";break}},table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:t,23:a,24:o,26:l,28:i,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{13:70,19:20,20:21,21:22,22:t,23:a,24:o,26:l,28:i,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{13:71,19:20,20:21,21:22,22:t,23:a,24:o,26:l,28:i,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{13:72,19:20,20:21,21:22,22:t,23:a,24:o,26:l,28:i,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{13:73,19:20,20:21,21:22,22:t,23:a,24:o,26:l,28:i,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{14:[1,74]},e(At,[2,13],{43:23,29:49,30:61,32:62,20:75,34:s,36:r,37:n,38:h,39:f,40:d,41:p,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt}),e(At,[2,14]),e(Vt,[2,16],{12:[1,76]}),e(At,[2,36],{12:[1,77]}),e(Ot,[2,19]),e(Ot,[2,20]),{25:[1,78]},{27:[1,79]},e(Ot,[2,23]),{35:80,75:81,76:v,77:k,79:A,80:C},{35:86,75:81,76:v,77:k,79:A,80:C},{35:87,75:81,76:v,77:k,79:A,80:C},{35:88,75:81,76:v,77:k,79:A,80:C},{35:89,75:81,76:v,77:k,79:A,80:C},{35:90,75:81,76:v,77:k,79:A,80:C},{35:91,75:81,76:v,77:k,79:A,80:C},{35:92,75:81,76:v,77:k,79:A,80:C},{35:93,75:81,76:v,77:k,79:A,80:C},{35:94,75:81,76:v,77:k,79:A,80:C},{35:95,75:81,76:v,77:k,79:A,80:C},{35:96,75:81,76:v,77:k,79:A,80:C},{35:97,75:81,76:v,77:k,79:A,80:C},{35:98,75:81,76:v,77:k,79:A,80:C},{35:99,75:81,76:v,77:k,79:A,80:C},{35:100,75:81,76:v,77:k,79:A,80:C},{35:101,75:81,76:v,77:k,79:A,80:C},{35:102,75:81,76:v,77:k,79:A,80:C},{35:103,75:81,76:v,77:k,79:A,80:C},{35:104,75:81,76:v,77:k,79:A,80:C},e(w,[2,59]),{35:105,75:81,76:v,77:k,79:A,80:C},{35:106,75:81,76:v,77:k,79:A,80:C},{35:107,75:81,76:v,77:k,79:A,80:C},{35:108,75:81,76:v,77:k,79:A,80:C},{35:109,75:81,76:v,77:k,79:A,80:C},{35:110,75:81,76:v,77:k,79:A,80:C},{35:111,75:81,76:v,77:k,79:A,80:C},{35:112,75:81,76:v,77:k,79:A,80:C},{35:113,75:81,76:v,77:k,79:A,80:C},{35:114,75:81,76:v,77:k,79:A,80:C},{35:115,75:81,76:v,77:k,79:A,80:C},{20:116,29:49,30:61,32:62,34:s,36:r,37:n,38:h,39:f,40:d,41:p,43:23,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt},{12:[1,118],33:[1,117]},{35:119,75:81,76:v,77:k,79:A,80:C},{35:120,75:81,76:v,77:k,79:A,80:C},{35:121,75:81,76:v,77:k,79:A,80:C},{35:122,75:81,76:v,77:k,79:A,80:C},{35:123,75:81,76:v,77:k,79:A,80:C},{35:124,75:81,76:v,77:k,79:A,80:C},{35:125,75:81,76:v,77:k,79:A,80:C},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},e(At,[2,15]),e(Vt,[2,17],{21:22,19:130,22:t,23:a,24:o,26:l,28:i}),e(At,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:t,23:a,24:o,26:l,28:i,34:s,36:r,37:n,38:h,39:f,40:d,41:p,44:E,45:O,46:R,47:S,48:L,49:Y,50:Q,51:H,52:q,53:G,54:K,55:J,56:Z,57:$,58:tt,59:et,60:it,61:nt,62:st,63:at,64:rt,65:lt,66:ot,67:ct,68:ht,69:ut,70:dt,71:ft,72:pt,73:yt,74:gt}),e(Ot,[2,21]),e(Ot,[2,22]),e(w,[2,39]),e(ne,[2,71],{75:81,35:132,76:v,77:k,79:A,80:C}),e(Pt,[2,73]),{78:[1,133]},e(Pt,[2,75]),e(Pt,[2,76]),e(w,[2,40]),e(w,[2,41]),e(w,[2,42]),e(w,[2,43]),e(w,[2,44]),e(w,[2,45]),e(w,[2,46]),e(w,[2,47]),e(w,[2,48]),e(w,[2,49]),e(w,[2,50]),e(w,[2,51]),e(w,[2,52]),e(w,[2,53]),e(w,[2,54]),e(w,[2,55]),e(w,[2,56]),e(w,[2,57]),e(w,[2,58]),e(w,[2,60]),e(w,[2,61]),e(w,[2,62]),e(w,[2,63]),e(w,[2,64]),e(w,[2,65]),e(w,[2,66]),e(w,[2,67]),e(w,[2,68]),e(w,[2,69]),e(w,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},e(mt,[2,28]),e(mt,[2,29]),e(mt,[2,30]),e(mt,[2,31]),e(mt,[2,32]),e(mt,[2,33]),e(mt,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},e(Vt,[2,18]),e(At,[2,38]),e(ne,[2,72]),e(Pt,[2,74]),e(w,[2,24]),e(w,[2,35]),e(zt,[2,25]),e(zt,[2,26],{12:[1,138]}),e(zt,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:function(_,x){if(x.recoverable)this.trace(_);else{var m=new Error(_);throw m.hash=x,m}},parse:function(_){var x=this,m=[0],g=[],T=[null],u=[],Tt=this.table,y="",Et=0,se=0,ve=2,ae=1,ke=u.slice.call(arguments,1),D=Object.create(this.lexer),vt={yy:{}};for(var Qt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Qt)&&(vt.yy[Qt]=this.yy[Qt]);D.setInput(_,vt.yy),vt.yy.lexer=D,vt.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var Ht=D.yylloc;u.push(Ht);var Ae=D.options&&D.options.ranges;typeof vt.yy.parseError=="function"?this.parseError=vt.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ce(){var X;return X=g.pop()||D.lex()||ae,typeof X!="number"&&(X instanceof Array&&(g=X,X=g.pop()),X=x.symbols_[X]||X),X}for(var M,kt,N,qt,Ct={},Mt,z,re,Lt;;){if(kt=m[m.length-1],this.defaultActions[kt]?N=this.defaultActions[kt]:((M===null||typeof M>"u")&&(M=Ce()),N=Tt[kt]&&Tt[kt][M]),typeof N>"u"||!N.length||!N[0]){var Gt="";Lt=[];for(Mt in Tt[kt])this.terminals_[Mt]&&Mt>ve&&Lt.push("'"+this.terminals_[Mt]+"'");D.showPosition?Gt="Parse error on line "+(Et+1)+`: `+D.showPosition()+` Expecting `+Lt.join(", ")+", got '"+(this.terminals_[M]||M)+"'":Gt="Parse error on line "+(Et+1)+": Unexpected "+(M==ae?"end of input":"'"+(this.terminals_[M]||M)+"'"),this.parseError(Gt,{text:D.match,token:this.terminals_[M]||M,line:D.yylineno,loc:Ht,expected:Lt})}if(N[0]instanceof Array&&N.length>1)throw new Error("Parse Error: multiple actions possible at state: "+kt+", token: "+M);switch(N[0]){case 1:m.push(M),T.push(D.yytext),u.push(D.yylloc),m.push(N[1]),M=null,se=D.yyleng,y=D.yytext,Et=D.yylineno,Ht=D.yylloc;break;case 2:if(z=this.productions_[N[1]][1],Ct.$=T[T.length-z],Ct._$={first_line:u[u.length-(z||1)].first_line,last_line:u[u.length-1].last_line,first_column:u[u.length-(z||1)].first_column,last_column:u[u.length-1].last_column},Ae&&(Ct._$.range=[u[u.length-(z||1)].range[0],u[u.length-1].range[1]]),qt=this.performAction.apply(Ct,[y,se,Et,vt.yy,N[1],T,u].concat(ke)),typeof qt<"u")return qt;z&&(m=m.slice(0,-1*z*2),T=T.slice(0,-1*z),u=u.slice(0,-1*z)),m.push(this.productions_[N[1]][0]),T.push(Ct.$),u.push(Ct._$),re=Tt[m[m.length-2]][m[m.length-1]],m.push(re);break;case 3:return!0}}return!0}},Ee=function(){var bt={EOF:1,parseError:function(x,m){if(this.yy.parser)this.yy.parser.parseError(x,m);else throw new Error(x)},setInput:function(_,x){return this.yy=x||this.yy||{},this._input=_,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var _=this._input[0];this.yytext+=_,this.yyleng++,this.offset++,this.match+=_,this.matched+=_;var x=_.match(/(?:\r\n?|\n).*/g);return x?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),_},unput:function(_){var x=_.length,m=_.split(/(?:\r\n?|\n)/g);this._input=_+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-x),this.offset-=x;var g=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),m.length-1&&(this.yylineno-=m.length-1);var T=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:m?(m.length===g.length?this.yylloc.first_column:0)+g[g.length-m.length].length-m[0].length:this.yylloc.first_column-x},this.options.ranges&&(this.yylloc.range=[T[0],T[0]+this.yyleng-x]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(_){this.unput(this.match.slice(_))},pastInput:function(){var _=this.matched.substr(0,this.matched.length-this.match.length);return(_.length>20?"...":"")+_.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var _=this.match;return _.length<20&&(_+=this._input.substr(0,20-_.length)),(_.substr(0,20)+(_.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var _=this.pastInput(),x=new Array(_.length+1).join("-");return _+this.upcomingInput()+` diff --git a/assets/ch01-preface.html-ltnruxaH.js b/assets/ch01-preface.html-Xp85YRwD.js similarity index 99% rename from assets/ch01-preface.html-ltnruxaH.js rename to assets/ch01-preface.html-Xp85YRwD.js index f22633f93d..8509696925 100644 --- a/assets/ch01-preface.html-ltnruxaH.js +++ b/assets/ch01-preface.html-Xp85YRwD.js @@ -1 +1 @@ -import{_ as e,o as t,c as o,e as i}from"./app-PDrbPfzp.js";const n="/assets/ch01-img01-choice-6xQtSwmI.png",a={},s=i('

[Chapter 1] Simple and Plain Language

1.1 Who is this document written for?

One sentence: Written for newbies who are (1) absolute beginners and (2) interested in learning how to build their own VPS.

1.2 Who is this document not written for?

Including but not limited to: experts and professionals, beginners who are too lazy to tinker on their own, advanced users who already know how to tinker, wealthy users who insist on using airport services, and those who prefer using one-click scripts. In short, if you have a technical background or don't want to build it yourself, you can close this article directly, because this article may not be suitable for you and may even make you upset.

1.3 Declaration and Other Statements

Declaration:

My technical skills are extremely limited, so this article is inevitably full of errors and flaws. If you find any problems, please kindly point them out and don't be too harsh on me.

Disclaimer:

Please judge the reliability and usability of the content of this article by yourself. If you encounter any problems or negative results when establishing and using a VPS server based on the content of this article, I am not responsible for it.

Verbose statement:

Considering the target audience of this article, which is "users with zero experience", many details will be explained in great detail, so the language may be verbose. Please be mentally prepared for this.

1.4 Why is self-hosting a challenge?

To answer this question, we need to provide a little more background information.

  1. On the matter of accessing the internet through scientific means

The act of accessing the internet using scientific methods has been around for almost 20 years (shocking!!!.jpg). Initially, one could do it with a little effort (changing the host file, using SSH), then one had to find a web proxy, and later, one had to develop a private protocol (such as Shadowsocks) and so on.

With the continuous iteration and upgrade of GFW technology over the past decade, to achieve the goal of [building your own scientific Internet access], the things that need to be done include but are not limited to:

  • Understand basic Linux commands
  • Understand network transmission protocols
  • Have the technical and financial ability to purchase and manage a VPS
  • Have the technical and financial ability to purchase and manage a domain name
  • Have the technical ability to apply for a TLS certificate, and so on.

This has turned the once simple act of [setting up a self-built VPS for accessing the internet in a secure and unrestricted manner] into a daunting challenge that intimidates newcomers.

  1. Helplessness of Zero-based Users

For non-technical users with zero foundation, if they complete the above series of operations, they will inevitably need to learn a lot of knowledge. However, after a little searching, newbies are likely to become even more confused: a large amount of information is scattered in various corners of the Internet: blogs, Q&A sites, groups, forums, GitHub, Telegram, YouTube, and so on. These pieces of information are chaotic and complex, with varying levels of quality, and may even contradict each other. Basically, they won't stop until they completely confuse the newcomer.

Faced with such chaotic information, newcomers suddenly shift from [information scarcity] to [information overload]. If they fail after several attempts of groping and guessing (which is highly probable), their enthusiasm is bound to be greatly frustrated. In this process, if they happen to seek help in some unfriendly places, they may be ridiculed even more: "You're so inexperienced, just use the airport, why bother messing around!" "Go learn Linux first before coming back to ask."

At this moment, probably only an "hehe" can express the mood.

1.5 "Why not just use the airport?"

First of all, I would like to respond to those who ridicule and criticize by asking a question: Is using the airport really a panacea?

Secondly, I believe that there is a fundamental difference between "not understanding" and "not wanting to understand". The bad attitude of some people who just want handouts is naturally annoying, but those who sincerely want to learn but don't know how should not be subject to unjustified contempt and discrimination. It is precisely this kind of bad community atmosphere that does not distinguish between newcomers that prompted me to write this article. So without further ado, let's take a look at the advantages and disadvantages of the airport:

  1. 稳定性高:机场节点数量多,分布广泛,避免了单点故障的风险,保证了整个网络的稳定性。
  2. 速度快:机场的节点通常采用高速服务器和优化的网络架构,网络速度较快,能够满足用户的高速上网需求。
  3. 安全性高:机场通常会采用严格的安全措施,如流量加密、防火墙等,保护用户数据的安全性。
  4. 稳定性高:机场通常采用专业的运维团队进行管理和维护,保证了服务的稳定性和可靠性。
  5. 服务质量高:机场通常会提供完善的客户服务,及时解决用户的问题和反馈,提升用户的满意度。

The so-called "airport" refers to the "line provider". They are responsible for completing the technical operations and management mentioned in section 1.4, while users pay for the right to use the service. Therefore, its advantages include at least:

  1. Simple User Operation: Scan code operation, one-click rule addition, etc.
  2. Multiple Line Options: Can unlock network services in different countries and regions, such as iplc dedicated line services, game acceleration services, etc.
  3. Multiple Access Nodes: Therefore, it has a stronger ability to resist node blocking, if one is blocked, just switch to another one.
  • Risks of "Airport"

"The other side of the coin of 'convenience' is 'risk'. Based on the technical characteristics and market conditions of the 'airport', its risks include at least:"

  1. "Airport" can fully obtain user information: All the traces left by users online will inevitably and very likely be stored on their servers for a long time. These records cannot be restricted by any legally binding user privacy agreement. ("Snooping and recording your every move")
  2. "Airport" lacks market management: There are inevitably malicious merchants who target fraud. ("Actively run away")
  3. "Airport" faces regulatory pressure: While large airports are relatively secure, they cannot avoid attracting attention. In 2020, several large airports experienced shutdowns and runaways, seriously disrupting users' normal usage. ("Passively run away")
  4. "Airport" technical level is difficult to determine: The quality of the line varies greatly, and the phenomenon of falsely advertising quality services is common. ("Slow speed, frequent disconnections, unable to connect")

1.6 So should you build your own website?

Now that you have seen the advantages and risks of the airport, please think carefully and make your own decision on what to use. After all, the best plan is the one that suits you best.

It's Your Choice!

  1. If you decide to use the airport, you can close this article now.

  2. If you decide to build it yourself, please continue reading the following chapters!

In short, the goal of this article is to serve as a starting point for users with zero experience, providing thorough explanations and demonstrations for each step, even if it may seem overly detailed or repetitive. The aim is to assist beginners in completing the entire process of deploying a VPS server from the first command input to successfully accessing the internet via the client, and gradually introducing them to basic Linux operations, laying a foundation for further self-learning.

1.7 Some digressions

  1. There is a wealth of information outside of the wall, so please learn to think rationally and independently. Don't take sides easily and don't believe in sensational information.

  2. We sincerely hope that with a smoother internet, everyone can access fresher knowledge, richer entertainment, experience a better world, and make more like-minded friends, but do not become a scapegoat for anyone with ulterior motives.

  3. Your internet identity is still your identity, and achieving absolute anonymity is extremely difficult. Therefore, please be sure to comply with the relevant laws and regulations in your personal location and the location of your IP address. Self-protection is always the most basic bottom line.

1.8 Your Progress

⬛⬜⬜⬜⬜⬜⬜⬜ 12.5%

',41),r=[s];function l(h,c){return t(),o("div",null,r)}const u=e(a,[["render",l],["__file","ch01-preface.html.vue"]]);export{u as default}; +import{_ as e,o as t,c as o,e as i}from"./app-UOvWaKji.js";const n="/assets/ch01-img01-choice-6xQtSwmI.png",a={},s=i('

[Chapter 1] Simple and Plain Language

1.1 Who is this document written for?

One sentence: Written for newbies who are (1) absolute beginners and (2) interested in learning how to build their own VPS.

1.2 Who is this document not written for?

Including but not limited to: experts and professionals, beginners who are too lazy to tinker on their own, advanced users who already know how to tinker, wealthy users who insist on using airport services, and those who prefer using one-click scripts. In short, if you have a technical background or don't want to build it yourself, you can close this article directly, because this article may not be suitable for you and may even make you upset.

1.3 Declaration and Other Statements

Declaration:

My technical skills are extremely limited, so this article is inevitably full of errors and flaws. If you find any problems, please kindly point them out and don't be too harsh on me.

Disclaimer:

Please judge the reliability and usability of the content of this article by yourself. If you encounter any problems or negative results when establishing and using a VPS server based on the content of this article, I am not responsible for it.

Verbose statement:

Considering the target audience of this article, which is "users with zero experience", many details will be explained in great detail, so the language may be verbose. Please be mentally prepared for this.

1.4 Why is self-hosting a challenge?

To answer this question, we need to provide a little more background information.

  1. On the matter of accessing the internet through scientific means

The act of accessing the internet using scientific methods has been around for almost 20 years (shocking!!!.jpg). Initially, one could do it with a little effort (changing the host file, using SSH), then one had to find a web proxy, and later, one had to develop a private protocol (such as Shadowsocks) and so on.

With the continuous iteration and upgrade of GFW technology over the past decade, to achieve the goal of [building your own scientific Internet access], the things that need to be done include but are not limited to:

  • Understand basic Linux commands
  • Understand network transmission protocols
  • Have the technical and financial ability to purchase and manage a VPS
  • Have the technical and financial ability to purchase and manage a domain name
  • Have the technical ability to apply for a TLS certificate, and so on.

This has turned the once simple act of [setting up a self-built VPS for accessing the internet in a secure and unrestricted manner] into a daunting challenge that intimidates newcomers.

  1. Helplessness of Zero-based Users

For non-technical users with zero foundation, if they complete the above series of operations, they will inevitably need to learn a lot of knowledge. However, after a little searching, newbies are likely to become even more confused: a large amount of information is scattered in various corners of the Internet: blogs, Q&A sites, groups, forums, GitHub, Telegram, YouTube, and so on. These pieces of information are chaotic and complex, with varying levels of quality, and may even contradict each other. Basically, they won't stop until they completely confuse the newcomer.

Faced with such chaotic information, newcomers suddenly shift from [information scarcity] to [information overload]. If they fail after several attempts of groping and guessing (which is highly probable), their enthusiasm is bound to be greatly frustrated. In this process, if they happen to seek help in some unfriendly places, they may be ridiculed even more: "You're so inexperienced, just use the airport, why bother messing around!" "Go learn Linux first before coming back to ask."

At this moment, probably only an "hehe" can express the mood.

1.5 "Why not just use the airport?"

First of all, I would like to respond to those who ridicule and criticize by asking a question: Is using the airport really a panacea?

Secondly, I believe that there is a fundamental difference between "not understanding" and "not wanting to understand". The bad attitude of some people who just want handouts is naturally annoying, but those who sincerely want to learn but don't know how should not be subject to unjustified contempt and discrimination. It is precisely this kind of bad community atmosphere that does not distinguish between newcomers that prompted me to write this article. So without further ado, let's take a look at the advantages and disadvantages of the airport:

  1. 稳定性高:机场节点数量多,分布广泛,避免了单点故障的风险,保证了整个网络的稳定性。
  2. 速度快:机场的节点通常采用高速服务器和优化的网络架构,网络速度较快,能够满足用户的高速上网需求。
  3. 安全性高:机场通常会采用严格的安全措施,如流量加密、防火墙等,保护用户数据的安全性。
  4. 稳定性高:机场通常采用专业的运维团队进行管理和维护,保证了服务的稳定性和可靠性。
  5. 服务质量高:机场通常会提供完善的客户服务,及时解决用户的问题和反馈,提升用户的满意度。

The so-called "airport" refers to the "line provider". They are responsible for completing the technical operations and management mentioned in section 1.4, while users pay for the right to use the service. Therefore, its advantages include at least:

  1. Simple User Operation: Scan code operation, one-click rule addition, etc.
  2. Multiple Line Options: Can unlock network services in different countries and regions, such as iplc dedicated line services, game acceleration services, etc.
  3. Multiple Access Nodes: Therefore, it has a stronger ability to resist node blocking, if one is blocked, just switch to another one.
  • Risks of "Airport"

"The other side of the coin of 'convenience' is 'risk'. Based on the technical characteristics and market conditions of the 'airport', its risks include at least:"

  1. "Airport" can fully obtain user information: All the traces left by users online will inevitably and very likely be stored on their servers for a long time. These records cannot be restricted by any legally binding user privacy agreement. ("Snooping and recording your every move")
  2. "Airport" lacks market management: There are inevitably malicious merchants who target fraud. ("Actively run away")
  3. "Airport" faces regulatory pressure: While large airports are relatively secure, they cannot avoid attracting attention. In 2020, several large airports experienced shutdowns and runaways, seriously disrupting users' normal usage. ("Passively run away")
  4. "Airport" technical level is difficult to determine: The quality of the line varies greatly, and the phenomenon of falsely advertising quality services is common. ("Slow speed, frequent disconnections, unable to connect")

1.6 So should you build your own website?

Now that you have seen the advantages and risks of the airport, please think carefully and make your own decision on what to use. After all, the best plan is the one that suits you best.

It's Your Choice!

  1. If you decide to use the airport, you can close this article now.

  2. If you decide to build it yourself, please continue reading the following chapters!

In short, the goal of this article is to serve as a starting point for users with zero experience, providing thorough explanations and demonstrations for each step, even if it may seem overly detailed or repetitive. The aim is to assist beginners in completing the entire process of deploying a VPS server from the first command input to successfully accessing the internet via the client, and gradually introducing them to basic Linux operations, laying a foundation for further self-learning.

1.7 Some digressions

  1. There is a wealth of information outside of the wall, so please learn to think rationally and independently. Don't take sides easily and don't believe in sensational information.

  2. We sincerely hope that with a smoother internet, everyone can access fresher knowledge, richer entertainment, experience a better world, and make more like-minded friends, but do not become a scapegoat for anyone with ulterior motives.

  3. Your internet identity is still your identity, and achieving absolute anonymity is extremely difficult. Therefore, please be sure to comply with the relevant laws and regulations in your personal location and the location of your IP address. Self-protection is always the most basic bottom line.

1.8 Your Progress

⬛⬜⬜⬜⬜⬜⬜⬜ 12.5%

',41),r=[s];function l(h,c){return t(),o("div",null,r)}const u=e(a,[["render",l],["__file","ch01-preface.html.vue"]]);export{u as default}; diff --git a/assets/ch01-preface.html-h3OWqh8J.js b/assets/ch01-preface.html-bIl_Km3k.js similarity index 99% rename from assets/ch01-preface.html-h3OWqh8J.js rename to assets/ch01-preface.html-bIl_Km3k.js index e128730238..c14db68a82 100644 --- a/assets/ch01-preface.html-h3OWqh8J.js +++ b/assets/ch01-preface.html-bIl_Km3k.js @@ -1 +1 @@ -import{_ as s,o as p,c as a,e as n}from"./app-PDrbPfzp.js";const o="/assets/ch01-img01-choice-6xQtSwmI.png",r={},e=n('

【第 1 章】 小小白白话文

1.1 这篇文档是写给谁的?

一句话:写给 ① 零基础 ② 希望学习自建 VPS 的新人。

1.2 这篇文档不是写给谁的?

包括但不限于:各路大神大能、懒得自己折腾的小白、已经会折腾的高手、确定要用机场的土豪、确定要用一键脚本的逍遥派...... 总之只要有技术基础、或不愿不想自建的同学,您直接关闭本文即可,因为这篇文章大概是入不了您的法眼的,更可能会让您生一肚子闲气,那多划不来。

1.3 郑重声明及其他声明

郑重声明:

鄙人技术奇菜无比,故本文必然挂一漏万破绽百出。您若发现问题还请温柔提醒,莫要人参公鸡。

免责声明:

本文内容请您自行判断是否可信可靠可用,若您根据本文内容建立和使用 VPS 服务器时出了任何问题和不良结果,鄙人概不负责。

啰嗦声明:

基于本文【零基础用户】的目标受众,许多内容会尽力详尽说明,所以语言偏啰嗦,请做好心理准备。

1.4 为什么自建是个难题?

要回答这个问题,就需要稍微多说一点背景信息了。

一、科学上网这件事

科学上网这件事情,说来已经发展了近二十年(震惊!!!.jpg)。最初,自己稍微动动手即可(改改 host、连一下 ssh)、后来需要找一个网页代理,再后来需要写一个私有协议(比如 Shadowsocks)等等。

随着 GFW 技术这十几年来不断的迭代升级,若要完成【自己动手科学上网】这个目标,需要做的事情已经包括但不限于:

  • 了解 Linux 系统基本命令
  • 了解网络传输协议
  • 有技术和经济能力完成 VPS 购买及管理
  • 有技术和经济能力完成域名购买及管理
  • 有技术能力完成 TLS 证书申请 等等。

这就让【自建 VPS 科学上网】这个曾经简单的行为逐渐变成了令新人望而生畏的挑战。

二、零基础用户的无奈

零基础的非技术用户,如果完成上面这一连串的操作,势必要学习大量的知识,但稍微搜索之后,新人只怕会更加迷茫:大量的信息散布在互联网的各个角落:博客、问答网站、群组、论坛、GitHub、Telegram、YouTube 等等等等)。这些信息纷乱复杂、水平良莠不齐、甚至可能互相矛盾。基本上就是不把新人彻底弄晕誓不罢休。

面对这些杂乱无章的信息,新人突然就从【信息匮乏】变成了【信息过剩】。若是几番连蒙带猜的折腾以失败告终(大概率如此)的话,他的积极性势必大受挫折。在这个过程中,若他又恰好去了一些不太友好的地方去求助,恐怕还要雪上加霜的被嘲讽一番:“这么菜,用机场不就行了,瞎折腾什么啊!”、“先去学会 Linux 再回来问吧”。

这时候,大概也只有一声“呵呵”可以表达心情了。

1.5 “用机场不就行了?”

首先,我想反问一下那些冷嘲热讽的人:“用机场”真的就是万灵药吗?

其次,我认为“不懂”和“不想懂”是有本质区别的。态度恶劣的巨婴伸手党自然惹人厌烦,但真心自学却不得要领的人不该受到无端的白眼和歧视,也正是这种对新人不加区分的恶劣社区氛围促使我写下本文。那么闲话少说,我们来看看机场的优势与劣势究竟如何:

一、“机场“的优势

所谓“机场”,就是“线路提供商”。他负责完成 1.4 提到的那一串技术操作和管理,用户则付费获得使用权。所以,它的优点至少有:

  1. 用户操作简单:扫码操作、一键添加规则等
  2. 线路选择多:可解锁不同国家、地区的网络服务;比如 iplc 等专线服务、游戏加速服务等
  3. 接入节点多:所以抵抗节点封锁的能力强一些,封了一个就换下一个

二、“机场”的风险

“方便”这枚硬币的另一面就是“风险”,基于“机场”的技术特点和市场情况,它的风险至少有:

  1. “机场”可完全获得用户信息:用户在网上的所有痕迹,都【必然】经过且【非常可能】长期存储在其服务器上,这些记录无法受到任何具备法律效力的用户隐私协议的约束(窥视、记录你的一举一动
  2. “机场”缺乏市场管理:不可避免存在着以欺诈为目标的恶意商家(主动跑路
  3. “机场”面临监管压力:大机场相对有保障的同时,也无法避免树大招风。2020 年间,已经有几个大机场停运、跑路的事件发生,用户的正常使用受到严重干扰(被动跑路
  4. “机场”技术水平难以确定:线路质量良莠不齐,挂羊头卖狗肉的现象屡见不鲜(速度慢、掉线多、连不上

1.6 那么你到底要不要自建呢?

现在,你已经看到了机场的优势和风险,要用什么,就请各位充分思考并自行决定。毕竟,最适合你的方案才是最好的方案。

It's Your Choice!

  1. 如果决定使用机场的话,现在,你可以关闭本文了。

  2. 如果你决定自建,那就请继续阅读后面的章节吧!!

总之,本文的目标就是成为零基础用户的知识起点,提供对每一步充分的讲解和演示,清清楚楚(甚至婆婆妈妈、絮絮叨叨、啰啰嗦嗦)的协助新人完成【从输入第一条命令开始,完成 VPS 服务器部署,并成功在客户端完成科学上网】的全程。并在这个过程中帮助新人逐步接触和熟悉 Linux 的基础操作,为之后的进一步自学打下基础。

1.7 题外啰嗦几句

  1. 墙外的信息泥沙俱下,请务必学会理性、独立的思辨,不要随意站队,不要轻信猎奇的信息。

  2. 衷心希望大家获得更顺畅的网络后,可以获取更新鲜的知识、更丰富的娱乐、接触更美好的世界、结交更多志同道合的朋友,但不要成为任何有不可告人目的之人的替罪羊。

  3. 你的互联网身份依然是你的身份,绝对的匿名化是极为困难的,所以请务必遵守你个人所在地区和 IP 所在地区的相关法律法规。无论何时,自我保护都是最基本的底线。

1.8 你的进度

⬛⬜⬜⬜⬜⬜⬜⬜ 12.5%

',41),i=[e];function t(l,h){return p(),a("div",null,i)}const d=s(r,[["render",t],["__file","ch01-preface.html.vue"]]);export{d as default}; +import{_ as s,o as p,c as a,e as n}from"./app-UOvWaKji.js";const o="/assets/ch01-img01-choice-6xQtSwmI.png",r={},e=n('

【第 1 章】 小小白白话文

1.1 这篇文档是写给谁的?

一句话:写给 ① 零基础 ② 希望学习自建 VPS 的新人。

1.2 这篇文档不是写给谁的?

包括但不限于:各路大神大能、懒得自己折腾的小白、已经会折腾的高手、确定要用机场的土豪、确定要用一键脚本的逍遥派...... 总之只要有技术基础、或不愿不想自建的同学,您直接关闭本文即可,因为这篇文章大概是入不了您的法眼的,更可能会让您生一肚子闲气,那多划不来。

1.3 郑重声明及其他声明

郑重声明:

鄙人技术奇菜无比,故本文必然挂一漏万破绽百出。您若发现问题还请温柔提醒,莫要人参公鸡。

免责声明:

本文内容请您自行判断是否可信可靠可用,若您根据本文内容建立和使用 VPS 服务器时出了任何问题和不良结果,鄙人概不负责。

啰嗦声明:

基于本文【零基础用户】的目标受众,许多内容会尽力详尽说明,所以语言偏啰嗦,请做好心理准备。

1.4 为什么自建是个难题?

要回答这个问题,就需要稍微多说一点背景信息了。

一、科学上网这件事

科学上网这件事情,说来已经发展了近二十年(震惊!!!.jpg)。最初,自己稍微动动手即可(改改 host、连一下 ssh)、后来需要找一个网页代理,再后来需要写一个私有协议(比如 Shadowsocks)等等。

随着 GFW 技术这十几年来不断的迭代升级,若要完成【自己动手科学上网】这个目标,需要做的事情已经包括但不限于:

  • 了解 Linux 系统基本命令
  • 了解网络传输协议
  • 有技术和经济能力完成 VPS 购买及管理
  • 有技术和经济能力完成域名购买及管理
  • 有技术能力完成 TLS 证书申请 等等。

这就让【自建 VPS 科学上网】这个曾经简单的行为逐渐变成了令新人望而生畏的挑战。

二、零基础用户的无奈

零基础的非技术用户,如果完成上面这一连串的操作,势必要学习大量的知识,但稍微搜索之后,新人只怕会更加迷茫:大量的信息散布在互联网的各个角落:博客、问答网站、群组、论坛、GitHub、Telegram、YouTube 等等等等)。这些信息纷乱复杂、水平良莠不齐、甚至可能互相矛盾。基本上就是不把新人彻底弄晕誓不罢休。

面对这些杂乱无章的信息,新人突然就从【信息匮乏】变成了【信息过剩】。若是几番连蒙带猜的折腾以失败告终(大概率如此)的话,他的积极性势必大受挫折。在这个过程中,若他又恰好去了一些不太友好的地方去求助,恐怕还要雪上加霜的被嘲讽一番:“这么菜,用机场不就行了,瞎折腾什么啊!”、“先去学会 Linux 再回来问吧”。

这时候,大概也只有一声“呵呵”可以表达心情了。

1.5 “用机场不就行了?”

首先,我想反问一下那些冷嘲热讽的人:“用机场”真的就是万灵药吗?

其次,我认为“不懂”和“不想懂”是有本质区别的。态度恶劣的巨婴伸手党自然惹人厌烦,但真心自学却不得要领的人不该受到无端的白眼和歧视,也正是这种对新人不加区分的恶劣社区氛围促使我写下本文。那么闲话少说,我们来看看机场的优势与劣势究竟如何:

一、“机场“的优势

所谓“机场”,就是“线路提供商”。他负责完成 1.4 提到的那一串技术操作和管理,用户则付费获得使用权。所以,它的优点至少有:

  1. 用户操作简单:扫码操作、一键添加规则等
  2. 线路选择多:可解锁不同国家、地区的网络服务;比如 iplc 等专线服务、游戏加速服务等
  3. 接入节点多:所以抵抗节点封锁的能力强一些,封了一个就换下一个

二、“机场”的风险

“方便”这枚硬币的另一面就是“风险”,基于“机场”的技术特点和市场情况,它的风险至少有:

  1. “机场”可完全获得用户信息:用户在网上的所有痕迹,都【必然】经过且【非常可能】长期存储在其服务器上,这些记录无法受到任何具备法律效力的用户隐私协议的约束(窥视、记录你的一举一动
  2. “机场”缺乏市场管理:不可避免存在着以欺诈为目标的恶意商家(主动跑路
  3. “机场”面临监管压力:大机场相对有保障的同时,也无法避免树大招风。2020 年间,已经有几个大机场停运、跑路的事件发生,用户的正常使用受到严重干扰(被动跑路
  4. “机场”技术水平难以确定:线路质量良莠不齐,挂羊头卖狗肉的现象屡见不鲜(速度慢、掉线多、连不上

1.6 那么你到底要不要自建呢?

现在,你已经看到了机场的优势和风险,要用什么,就请各位充分思考并自行决定。毕竟,最适合你的方案才是最好的方案。

It's Your Choice!

  1. 如果决定使用机场的话,现在,你可以关闭本文了。

  2. 如果你决定自建,那就请继续阅读后面的章节吧!!

总之,本文的目标就是成为零基础用户的知识起点,提供对每一步充分的讲解和演示,清清楚楚(甚至婆婆妈妈、絮絮叨叨、啰啰嗦嗦)的协助新人完成【从输入第一条命令开始,完成 VPS 服务器部署,并成功在客户端完成科学上网】的全程。并在这个过程中帮助新人逐步接触和熟悉 Linux 的基础操作,为之后的进一步自学打下基础。

1.7 题外啰嗦几句

  1. 墙外的信息泥沙俱下,请务必学会理性、独立的思辨,不要随意站队,不要轻信猎奇的信息。

  2. 衷心希望大家获得更顺畅的网络后,可以获取更新鲜的知识、更丰富的娱乐、接触更美好的世界、结交更多志同道合的朋友,但不要成为任何有不可告人目的之人的替罪羊。

  3. 你的互联网身份依然是你的身份,绝对的匿名化是极为困难的,所以请务必遵守你个人所在地区和 IP 所在地区的相关法律法规。无论何时,自我保护都是最基本的底线。

1.8 你的进度

⬛⬜⬜⬜⬜⬜⬜⬜ 12.5%

',41),i=[e];function t(l,h){return p(),a("div",null,i)}const d=s(r,[["render",t],["__file","ch01-preface.html.vue"]]);export{d as default}; diff --git a/assets/ch02-preparation.html-7bycodSz.js b/assets/ch02-preparation.html-flUUoP_1.js similarity index 98% rename from assets/ch02-preparation.html-7bycodSz.js rename to assets/ch02-preparation.html-flUUoP_1.js index 5b6270b5f7..07c65224c3 100644 --- a/assets/ch02-preparation.html-7bycodSz.js +++ b/assets/ch02-preparation.html-flUUoP_1.js @@ -1 +1 @@ -import{_ as n,r as i,o as r,c as s,a as e,b as o,d as t,e as l}from"./app-PDrbPfzp.js";const c="/assets/ch02-img01-a-name-YcPasChp.png",d={},h=l('

[Chapter 2] Preparation of Raw Materials

This chapter is rather special because it involves monetary transactions. This article takes a neutral stance on the project and does not make specific recommendations. What I can do is to tell you what you need to prepare.

2.1 Acquiring a VPS

You need to obtain a healthy VPS with an unblocked IP, and perform the following basic preparations in the management console:

  1. Install Debian 10 64-bit system in the backend of VPS.
  2. Write down the IP address of VPS in a notebook (this article will use "100.200.300.400" as an example, which is an intentionally incorrect and illegal IP address. Please replace it with your real IP address).
  3. Write down the SSH remote login port of VPS in a notebook.
  4. Write down the username and password for SSH remote login in a notebook.

Buying a VPS is a relatively complex matter. It is recommended to first learn the relevant knowledge and choose one that suits your own economic ability and line requirements. In addition, you can choose to take advantage of some benefits offered by international giants (such as permanent free or limited-time free packages offered by Oracle and Google). In any case, you must act within your means.

Explanation

Regarding the choice of Debian 10 as the operating system, let me elaborate a bit: No matter what you have heard online, no matter which guru has told you that XXX version of Linux is better or XXX version of Linux is more powerful, these sectarian disputes have nothing to do with you right now! Using Debian 10 is enough to optimize your VPS server for security, stability, and performance (such as using cloud-optimized kernel, timely support of BBR, etc.). After you become familiar with Linux, you can try other Linux distributions.

2.2 Obtaining a Desired Domain Name

You need to obtain a domain name and add an A record in the DNS settings, pointing to the IP address of your VPS.

  1. Please choose a reliable international domain name service provider. Choose some common domain name suffixes, and make sure not to use the .cn suffix.
  2. In the DNS settings, add an A record pointing to the IP address of your VPS (the name of the A record can be anything, and in this article, it will be represented by "a-name"). The complete domain name will be represented by "subdomain.yourdomain.com" or "a-name.yourdomain.com". The effect is as shown in the picture below:

Add A Record

Tip

This is not a real usable website. Please replace it with your real website URL.

2.3 Software you need to install on your local computer

  1. SSH remote login tool
',14),u={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},p=e("ul",null,[e("li",null,"macOS/Linux: Terminal")],-1),m=e("ol",{start:"2"},[e("li",null,"Remote file copying tool")],-1),f={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},g=e("ul",null,[e("li",null,"macOS/Linux: Terminal")],-1),y={start:"3"},b={href:"https://code.visualstudio.com",target:"_blank",rel:"noopener noreferrer"},_=e("h2",{id:"_2-4-your-progress",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-4-your-progress"},[e("span",null,"2.4 Your Progress")])],-1),w=e("p",null,"If you have all the raw materials ready as mentioned above, you have already obtained the key to unlocking the door to a new world. So, what are you waiting for? Let's quickly move on to the next chapter and step through this door!",-1),v=e("blockquote",null,[e("p",null,"⬛⬛⬜⬜⬜⬜⬜⬜ 25%")],-1);function x(k,S){const a=i("ExternalLinkIcon");return r(),s("div",null,[h,e("ul",null,[e("li",null,[o("Windows: "),e("a",u,[o("PuTTY"),t(a)]),p])]),m,e("ul",null,[e("li",null,[o("Windows: "),e("a",f,[o("WinSCP"),t(a)]),g])]),e("ol",y,[e("li",null,[o("Reliable text editor "),e("ul",null,[e("li",null,[o("Windows/macOS/Linux: "),e("a",b,[o("VSCode"),t(a)])])])])]),_,w,v])}const I=n(d,[["render",x],["__file","ch02-preparation.html.vue"]]);export{I as default}; +import{_ as n,r as i,o as r,c as s,a as e,b as o,d as t,e as l}from"./app-UOvWaKji.js";const c="/assets/ch02-img01-a-name-YcPasChp.png",d={},h=l('

[Chapter 2] Preparation of Raw Materials

This chapter is rather special because it involves monetary transactions. This article takes a neutral stance on the project and does not make specific recommendations. What I can do is to tell you what you need to prepare.

2.1 Acquiring a VPS

You need to obtain a healthy VPS with an unblocked IP, and perform the following basic preparations in the management console:

  1. Install Debian 10 64-bit system in the backend of VPS.
  2. Write down the IP address of VPS in a notebook (this article will use "100.200.300.400" as an example, which is an intentionally incorrect and illegal IP address. Please replace it with your real IP address).
  3. Write down the SSH remote login port of VPS in a notebook.
  4. Write down the username and password for SSH remote login in a notebook.

Buying a VPS is a relatively complex matter. It is recommended to first learn the relevant knowledge and choose one that suits your own economic ability and line requirements. In addition, you can choose to take advantage of some benefits offered by international giants (such as permanent free or limited-time free packages offered by Oracle and Google). In any case, you must act within your means.

Explanation

Regarding the choice of Debian 10 as the operating system, let me elaborate a bit: No matter what you have heard online, no matter which guru has told you that XXX version of Linux is better or XXX version of Linux is more powerful, these sectarian disputes have nothing to do with you right now! Using Debian 10 is enough to optimize your VPS server for security, stability, and performance (such as using cloud-optimized kernel, timely support of BBR, etc.). After you become familiar with Linux, you can try other Linux distributions.

2.2 Obtaining a Desired Domain Name

You need to obtain a domain name and add an A record in the DNS settings, pointing to the IP address of your VPS.

  1. Please choose a reliable international domain name service provider. Choose some common domain name suffixes, and make sure not to use the .cn suffix.
  2. In the DNS settings, add an A record pointing to the IP address of your VPS (the name of the A record can be anything, and in this article, it will be represented by "a-name"). The complete domain name will be represented by "subdomain.yourdomain.com" or "a-name.yourdomain.com". The effect is as shown in the picture below:

Add A Record

Tip

This is not a real usable website. Please replace it with your real website URL.

2.3 Software you need to install on your local computer

  1. SSH remote login tool
',14),u={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},p=e("ul",null,[e("li",null,"macOS/Linux: Terminal")],-1),m=e("ol",{start:"2"},[e("li",null,"Remote file copying tool")],-1),f={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},g=e("ul",null,[e("li",null,"macOS/Linux: Terminal")],-1),y={start:"3"},b={href:"https://code.visualstudio.com",target:"_blank",rel:"noopener noreferrer"},_=e("h2",{id:"_2-4-your-progress",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-4-your-progress"},[e("span",null,"2.4 Your Progress")])],-1),w=e("p",null,"If you have all the raw materials ready as mentioned above, you have already obtained the key to unlocking the door to a new world. So, what are you waiting for? Let's quickly move on to the next chapter and step through this door!",-1),v=e("blockquote",null,[e("p",null,"⬛⬛⬜⬜⬜⬜⬜⬜ 25%")],-1);function x(k,S){const a=i("ExternalLinkIcon");return r(),s("div",null,[h,e("ul",null,[e("li",null,[o("Windows: "),e("a",u,[o("PuTTY"),t(a)]),p])]),m,e("ul",null,[e("li",null,[o("Windows: "),e("a",f,[o("WinSCP"),t(a)]),g])]),e("ol",y,[e("li",null,[o("Reliable text editor "),e("ul",null,[e("li",null,[o("Windows/macOS/Linux: "),e("a",b,[o("VSCode"),t(a)])])])])]),_,w,v])}const I=n(d,[["render",x],["__file","ch02-preparation.html.vue"]]);export{I as default}; diff --git a/assets/ch02-preparation.html-nUCvuwbW.js b/assets/ch02-preparation.html-lZJv5DvE.js similarity index 98% rename from assets/ch02-preparation.html-nUCvuwbW.js rename to assets/ch02-preparation.html-lZJv5DvE.js index 1d5f6af48e..ada4e2c6db 100644 --- a/assets/ch02-preparation.html-nUCvuwbW.js +++ b/assets/ch02-preparation.html-lZJv5DvE.js @@ -1 +1 @@ -import{_ as a,r as l,o as s,c as i,a as e,b as n,d as t,e as c}from"./app-PDrbPfzp.js";const r="/assets/ch02-img01-a-name-YcPasChp.png",p={},d=c('

【第 2 章】原料准备篇

这一章比较特殊,因为涉及到金钱交易行为,本文基于项目的中立立场,不做具体的推荐。我能做的,是告诉你需要准备哪些东西。

2.1 获取一台 VPS

你需要获取一台健康的、IP 没有被墙的 VPS,并在管理后台做下面这些基础准备:

  1. 在 VPS 的后台安装 Debian 10 64bit 系统
  2. 小本本记下 VPS 的 IP 地址(本文会用 "100.200.300.400" 来表示)

    提示

    这是一个故意写错的非法 IP,请替换成你的真实 IP)

  3. 小本本记下 VPS 的 SSH 远程登陆端口(Port)
  4. 小本本记下 SSH 远程登录的用户名和密码

购买 VPS 是一个比较复杂的事情,建议先去学习一下相关知识,选择适合自己的经济能力和线路需求的即可。另外可以选择薅一些国际大厂的羊毛(比如甲骨文和谷歌提供的永久免费或限时免费的套餐)。总之,务必量力而行。

说明

关于选择 Debian 10 作为操作系统,这里稍微多说一句:不管你在网上听说了什么,不管哪个大神告诉你 XXX 版的 Linux 更好、XXX 版的 Linux 更牛,这些 Linux 的派系之争跟现在的你半毛钱关系也没有!使用 Debian 10 足以让你的 VPS 服务器在安全、稳健运行的同时得到足够的优化(如 cloud 专用内核、及时的 bbr 支持等)。等你对 Linux 熟悉之后,再回头去尝试其他的 Linux 发行版也不迟。

2.2 获取一个心仪的域名

你需要获取一个域名、并在 DNS 设置中添加一条 A 记录,指向你 VPS 的 IP 地址

  1. 请选择靠谱的国际域名服务商。选择一些常见的域名后缀就行,注意不要用 .cn 后缀。
  2. 在 DNS 设置中,添加一条指向你 VPS 的 IP 地址的 A 记录(A 记录的名字可以随便起,本文会用 "a-name" 来表示。完整的域名则会用 "二级域名.你的域名.com" 或者 "a-name.yourdomain.com" 来表示)。效果如下图:

添加A记录

提示

不是一个真实可用的网址,请替换成你的真实网址

2.3 你本地电脑上需要安装的软件

',13),u=e("p",null,"SSH 远程登录工具",-1),h={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},_=e("li",null,"macOS/Linux: Terminal",-1),m=e("p",null,"远程文件拷贝工具",-1),S={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},x=e("li",null,"macOS/Linux: Terminal",-1),P=e("p",null,"靠谱的文本编辑器",-1),f={href:"https://code.visualstudio.com",target:"_blank",rel:"noopener noreferrer"},b=e("h2",{id:"_2-4-你的进度",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-4-你的进度"},[e("span",null,"2.4 你的进度")])],-1),g=e("p",null,"如果上面的原材料你都准备好了的话,你已经拿到了开启新世界大门的钥匙。那还等什么,让我们快点进入下一章,走进这扇门吧!",-1),V=e("blockquote",null,[e("p",null,"⬛⬛⬜⬜⬜⬜⬜⬜ 25%")],-1);function v(k,L){const o=l("ExternalLinkIcon");return s(),i("div",null,[d,e("ol",null,[e("li",null,[u,e("ul",null,[e("li",null,[n("Windows: "),e("a",h,[n("PuTTY"),t(o)])]),_])]),e("li",null,[m,e("ul",null,[e("li",null,[n("Windows: "),e("a",S,[n("WinSCP"),t(o)])]),x])]),e("li",null,[P,e("ul",null,[e("li",null,[n("Windows/macOS/Linux: "),e("a",f,[n("VSCode"),t(o)])])])])]),b,g,V])}const I=a(p,[["render",v],["__file","ch02-preparation.html.vue"]]);export{I as default}; +import{_ as a,r as l,o as s,c as i,a as e,b as n,d as t,e as c}from"./app-UOvWaKji.js";const r="/assets/ch02-img01-a-name-YcPasChp.png",p={},d=c('

【第 2 章】原料准备篇

这一章比较特殊,因为涉及到金钱交易行为,本文基于项目的中立立场,不做具体的推荐。我能做的,是告诉你需要准备哪些东西。

2.1 获取一台 VPS

你需要获取一台健康的、IP 没有被墙的 VPS,并在管理后台做下面这些基础准备:

  1. 在 VPS 的后台安装 Debian 10 64bit 系统
  2. 小本本记下 VPS 的 IP 地址(本文会用 "100.200.300.400" 来表示)

    提示

    这是一个故意写错的非法 IP,请替换成你的真实 IP)

  3. 小本本记下 VPS 的 SSH 远程登陆端口(Port)
  4. 小本本记下 SSH 远程登录的用户名和密码

购买 VPS 是一个比较复杂的事情,建议先去学习一下相关知识,选择适合自己的经济能力和线路需求的即可。另外可以选择薅一些国际大厂的羊毛(比如甲骨文和谷歌提供的永久免费或限时免费的套餐)。总之,务必量力而行。

说明

关于选择 Debian 10 作为操作系统,这里稍微多说一句:不管你在网上听说了什么,不管哪个大神告诉你 XXX 版的 Linux 更好、XXX 版的 Linux 更牛,这些 Linux 的派系之争跟现在的你半毛钱关系也没有!使用 Debian 10 足以让你的 VPS 服务器在安全、稳健运行的同时得到足够的优化(如 cloud 专用内核、及时的 bbr 支持等)。等你对 Linux 熟悉之后,再回头去尝试其他的 Linux 发行版也不迟。

2.2 获取一个心仪的域名

你需要获取一个域名、并在 DNS 设置中添加一条 A 记录,指向你 VPS 的 IP 地址

  1. 请选择靠谱的国际域名服务商。选择一些常见的域名后缀就行,注意不要用 .cn 后缀。
  2. 在 DNS 设置中,添加一条指向你 VPS 的 IP 地址的 A 记录(A 记录的名字可以随便起,本文会用 "a-name" 来表示。完整的域名则会用 "二级域名.你的域名.com" 或者 "a-name.yourdomain.com" 来表示)。效果如下图:

添加A记录

提示

不是一个真实可用的网址,请替换成你的真实网址

2.3 你本地电脑上需要安装的软件

',13),u=e("p",null,"SSH 远程登录工具",-1),h={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},_=e("li",null,"macOS/Linux: Terminal",-1),m=e("p",null,"远程文件拷贝工具",-1),S={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},x=e("li",null,"macOS/Linux: Terminal",-1),P=e("p",null,"靠谱的文本编辑器",-1),f={href:"https://code.visualstudio.com",target:"_blank",rel:"noopener noreferrer"},b=e("h2",{id:"_2-4-你的进度",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-4-你的进度"},[e("span",null,"2.4 你的进度")])],-1),g=e("p",null,"如果上面的原材料你都准备好了的话,你已经拿到了开启新世界大门的钥匙。那还等什么,让我们快点进入下一章,走进这扇门吧!",-1),V=e("blockquote",null,[e("p",null,"⬛⬛⬜⬜⬜⬜⬜⬜ 25%")],-1);function v(k,L){const o=l("ExternalLinkIcon");return s(),i("div",null,[d,e("ol",null,[e("li",null,[u,e("ul",null,[e("li",null,[n("Windows: "),e("a",h,[n("PuTTY"),t(o)])]),_])]),e("li",null,[m,e("ul",null,[e("li",null,[n("Windows: "),e("a",S,[n("WinSCP"),t(o)])]),x])]),e("li",null,[P,e("ul",null,[e("li",null,[n("Windows/macOS/Linux: "),e("a",f,[n("VSCode"),t(o)])])])])]),b,g,V])}const I=a(p,[["render",v],["__file","ch02-preparation.html.vue"]]);export{I as default}; diff --git a/assets/ch03-ssh.html-kdsftrBp.js b/assets/ch03-ssh.html-PreKlYZo.js similarity index 99% rename from assets/ch03-ssh.html-kdsftrBp.js rename to assets/ch03-ssh.html-PreKlYZo.js index 883eb4f3f3..2e7c51b0f1 100644 --- a/assets/ch03-ssh.html-kdsftrBp.js +++ b/assets/ch03-ssh.html-PreKlYZo.js @@ -1,3 +1,3 @@ -import{_ as n,r as s,o as a,c as i,a as e,b as t,d as r,e as l}from"./app-PDrbPfzp.js";const d="/assets/ch03-img01-putty-download-gVwywNaM.png",c="/assets/ch03-img02-putty-settings-9F25dGfD.png",h="/assets/ch03-img03-putty-keepalive-dggTHgup.png",u="/assets/ch03-img04-ssh-login-8MrxOwy-.png",p="/assets/ch03-img05-ssh-login-success-bpTQqXTk.png",m="/assets/ch03-img06-apt-upgrade-full-PsNwQRq8.gif",g={},f=e("h1",{id:"chapter-3-remote-login",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#chapter-3-remote-login"},[e("span",null,"[Chapter 3] Remote Login")])],-1),y=e("h2",{id:"_3-1-remote-login-to-vps-putty",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-1-remote-login-to-vps-putty"},[e("span",null,"3.1 Remote Login to VPS (PuTTY)")])],-1),w=e("p",null,"First of all, considering that the user base of Windows is the largest among the zero-based population, this article uses Windows as an example for demonstration.",-1),v=e("p",null,"Secondly, although PowerShell and WSL after Windows 10 can also achieve a good SSH operation experience, not all versions of Windows have the latest components. Therefore, this article uses the classic PuTTY as an example to provide a detailed explanation of SSH remote login operation. (If you use other tools, the operations after the SSH login are the same.)",-1),b=e("p",null,"Follow me step by step and let's start the operation.",-1),_={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},x=l('

Download PuTTY

  1. After installation and running, you will see the main interface of PuTTY. Now please take out your notebook from the previous chapter where you wrote down the IP address (VPS IP) and port (VPS PORT) of your VPS in the corresponding positions of the following figure. In order to save time and avoid repeatedly entering these details in the future, we can save the session (Saved Sessions), and simply load it in the future with one click.

PuTTY Settings

  1. I suggest setting keepalive to 60 seconds in the Connection to prevent SSH from automatically disconnecting after a period of inactivity. Be sure to save the settings again.

Prevent frequent disconnection

Attention

Any update to the PuTTY configuration needs to be manually saved to the session again. Otherwise, it will be lost after closing.

  1. Click on Open to enter the SSH connection window, then enter the username and password corresponding to the following figure to establish a connection with your VPS remote host. (This article assumes that the default username is root. Also, when entering a password in the Linux system, there will be no prompt like ******, which can avoid password length leakage. It's not that your keyboard is broken!)

SSH Remote Login

3.2 Successfully Logging in SSH! Introduction to Command Line Interface!

  1. If you have filled in your information correctly, you will see a similar interface as the picture below, indicating that you have successfully logged in:

Logging in to VPS for the first time

This interface is equivalent to the "desktop" of a remote server, but it does not have familiar icons and a mouse, nor does it have colorful graphics. Instead, all you see is simple text. This is the "Command Line Interface" - shortened as CLI.

All the following operations require you to act like a hacker in a movie and complete them in this command-line interface. Maybe you will feel unfamiliar, but please believe me, using the command-line interface is neither scary nor mysterious. In the end, it just turns your familiar mouse operations into textual commands, you say it, it does it.

  1. Now, you can observe and familiarize yourself with the command line environment a little bit. This interface has actually provided you with some useful information, such as the system kernel version (e.g. 4.19.37-5 in the picture), last login time and IP address. Of course, depending on the VPS, the interface you see may be slightly different.

  2. Please pay attention to the line at the bottom of the command line, to the left of the flashing cursor, there is a string of characters. The one shown in the figure is root@vps-server:~#. How to understand this string? It's very simple:

  • The current user is root
  • The server where root is located is vps-server
  • The current directory where root is located is ~
  • After # is the place where you can input commands.

The first two are pretty straightforward, no need to explain further. The third one is about the folder system in Linux. You don't need to go too deep into it for now. Just know that "~" represents the home directory of the current user. As for the fourth one, the prompt symbol "#", you don't need to worry about it either. Just know that in future articles, there will be some commands that you need to input, and they will be preceded by "#" or "$" to indicate where you should input the command. (So when you copy the command, just copy the content after the prompt symbol and don't copy the prompt symbol itself.)

3.3 Updating software on Linux for the first time!

  1. Just like your phone, whether it's Android or iPhone, in order to keep your apps up-to-date (to get security patches and new features), you will occasionally receive update notifications from the app store, telling you how many apps need to be updated. Linux systems also have a similar update mechanism that works logically. So as long as you know how to update phone apps, you can learn how to update Linux software!

  2. In Linux, each application is called a "package". The program that manages the applications is naturally called a "package manager". You can use it to install, update, and uninstall various software, and even update the Linux system itself. Package managers in Linux are very powerful, but we won't go into details here. For now, you only need to know that the package manager for the Debian system is called apt. Next, we will first use apt to do a comprehensive update of the software to familiarize you with its basic operations.

  3. Tiny White Linux Basic Commands:

NumberCommand NameCommand Description
cmd-01apt updateQuery software updates
cmd-02apt upgradePerform software updates
  1. Now, please enter the first command to get update information.
apt update
+import{_ as n,r as s,o as a,c as i,a as e,b as t,d as r,e as l}from"./app-UOvWaKji.js";const d="/assets/ch03-img01-putty-download-gVwywNaM.png",c="/assets/ch03-img02-putty-settings-9F25dGfD.png",h="/assets/ch03-img03-putty-keepalive-dggTHgup.png",u="/assets/ch03-img04-ssh-login-8MrxOwy-.png",p="/assets/ch03-img05-ssh-login-success-bpTQqXTk.png",m="/assets/ch03-img06-apt-upgrade-full-PsNwQRq8.gif",g={},f=e("h1",{id:"chapter-3-remote-login",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#chapter-3-remote-login"},[e("span",null,"[Chapter 3] Remote Login")])],-1),y=e("h2",{id:"_3-1-remote-login-to-vps-putty",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-1-remote-login-to-vps-putty"},[e("span",null,"3.1 Remote Login to VPS (PuTTY)")])],-1),w=e("p",null,"First of all, considering that the user base of Windows is the largest among the zero-based population, this article uses Windows as an example for demonstration.",-1),v=e("p",null,"Secondly, although PowerShell and WSL after Windows 10 can also achieve a good SSH operation experience, not all versions of Windows have the latest components. Therefore, this article uses the classic PuTTY as an example to provide a detailed explanation of SSH remote login operation. (If you use other tools, the operations after the SSH login are the same.)",-1),b=e("p",null,"Follow me step by step and let's start the operation.",-1),_={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},x=l('

Download PuTTY

  1. After installation and running, you will see the main interface of PuTTY. Now please take out your notebook from the previous chapter where you wrote down the IP address (VPS IP) and port (VPS PORT) of your VPS in the corresponding positions of the following figure. In order to save time and avoid repeatedly entering these details in the future, we can save the session (Saved Sessions), and simply load it in the future with one click.

PuTTY Settings

  1. I suggest setting keepalive to 60 seconds in the Connection to prevent SSH from automatically disconnecting after a period of inactivity. Be sure to save the settings again.

Prevent frequent disconnection

Attention

Any update to the PuTTY configuration needs to be manually saved to the session again. Otherwise, it will be lost after closing.

  1. Click on Open to enter the SSH connection window, then enter the username and password corresponding to the following figure to establish a connection with your VPS remote host. (This article assumes that the default username is root. Also, when entering a password in the Linux system, there will be no prompt like ******, which can avoid password length leakage. It's not that your keyboard is broken!)

SSH Remote Login

3.2 Successfully Logging in SSH! Introduction to Command Line Interface!

  1. If you have filled in your information correctly, you will see a similar interface as the picture below, indicating that you have successfully logged in:

Logging in to VPS for the first time

This interface is equivalent to the "desktop" of a remote server, but it does not have familiar icons and a mouse, nor does it have colorful graphics. Instead, all you see is simple text. This is the "Command Line Interface" - shortened as CLI.

All the following operations require you to act like a hacker in a movie and complete them in this command-line interface. Maybe you will feel unfamiliar, but please believe me, using the command-line interface is neither scary nor mysterious. In the end, it just turns your familiar mouse operations into textual commands, you say it, it does it.

  1. Now, you can observe and familiarize yourself with the command line environment a little bit. This interface has actually provided you with some useful information, such as the system kernel version (e.g. 4.19.37-5 in the picture), last login time and IP address. Of course, depending on the VPS, the interface you see may be slightly different.

  2. Please pay attention to the line at the bottom of the command line, to the left of the flashing cursor, there is a string of characters. The one shown in the figure is root@vps-server:~#. How to understand this string? It's very simple:

  • The current user is root
  • The server where root is located is vps-server
  • The current directory where root is located is ~
  • After # is the place where you can input commands.

The first two are pretty straightforward, no need to explain further. The third one is about the folder system in Linux. You don't need to go too deep into it for now. Just know that "~" represents the home directory of the current user. As for the fourth one, the prompt symbol "#", you don't need to worry about it either. Just know that in future articles, there will be some commands that you need to input, and they will be preceded by "#" or "$" to indicate where you should input the command. (So when you copy the command, just copy the content after the prompt symbol and don't copy the prompt symbol itself.)

3.3 Updating software on Linux for the first time!

  1. Just like your phone, whether it's Android or iPhone, in order to keep your apps up-to-date (to get security patches and new features), you will occasionally receive update notifications from the app store, telling you how many apps need to be updated. Linux systems also have a similar update mechanism that works logically. So as long as you know how to update phone apps, you can learn how to update Linux software!

  2. In Linux, each application is called a "package". The program that manages the applications is naturally called a "package manager". You can use it to install, update, and uninstall various software, and even update the Linux system itself. Package managers in Linux are very powerful, but we won't go into details here. For now, you only need to know that the package manager for the Debian system is called apt. Next, we will first use apt to do a comprehensive update of the software to familiarize you with its basic operations.

  3. Tiny White Linux Basic Commands:

NumberCommand NameCommand Description
cmd-01apt updateQuery software updates
cmd-02apt upgradePerform software updates
  1. Now, please enter the first command to get update information.
apt update
 

This is a command used in a Linux terminal to update the package list from the repositories configured on the system.

  1. Then enter the second command, and when asked if you want to continue installing (Y/n), type y and press enter to confirm and start the installation.
apt upgrade
 

This is a command in the shell terminal to upgrade the installed packages on a Debian or Ubuntu Linux system.

  1. The complete demonstration of the process is as follows:

Demonstration of the software update process for the first time

3.4 Your Progress

Congratulations on taking another solid step! Now, you can log in to your remote server via SSH! After logging in, besides upgrading the software, what else should you do? Please enter the next chapter to find out!

⬛⬛⬛⬜⬜⬜⬜⬜ 37.5%

',30);function k(T,S){const o=s("ExternalLinkIcon");return a(),i("div",null,[f,y,w,v,b,e("ol",null,[e("li",null,[t("Go to the "),e("a",_,[t("official website"),r(o)]),t(" of PuTTY and download the version that suits your operating system (this article uses the 64-bit version as an example).")])]),x])}const q=n(g,[["render",k],["__file","ch03-ssh.html.vue"]]);export{q as default}; diff --git a/assets/ch03-ssh.html-34HWUQzq.js b/assets/ch03-ssh.html-ZqJB8vGA.js similarity index 99% rename from assets/ch03-ssh.html-34HWUQzq.js rename to assets/ch03-ssh.html-ZqJB8vGA.js index 3713bd825d..43aca11fc4 100644 --- a/assets/ch03-ssh.html-34HWUQzq.js +++ b/assets/ch03-ssh.html-ZqJB8vGA.js @@ -1,3 +1,3 @@ -import{_ as a,r as o,o as c,c as d,a as e,b as t,d as s,w as i,e as r}from"./app-PDrbPfzp.js";const p="/assets/ch03-img01-putty-download-gVwywNaM.png",u="/assets/ch03-img02-putty-settings-9F25dGfD.png",h="/assets/ch03-img03-putty-keepalive-dggTHgup.png",g="/assets/ch03-img04-ssh-login-8MrxOwy-.png",_="/assets/ch03-img05-ssh-login-success-bpTQqXTk.png",m="/assets/ch03-img06-apt-upgrade-full-PsNwQRq8.gif",x={},P=e("h1",{id:"【第-3-章】远程登录篇",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#【第-3-章】远程登录篇"},[e("span",null,"【第 3 章】远程登录篇")])],-1),S=e("h2",{id:"_3-1-远程登录-vps-putty",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-1-远程登录-vps-putty"},[e("span",null,"3.1 远程登录 VPS (PuTTY)")])],-1),v=e("p",null,"首先,鉴于零基础人群中 Windows 的用户基数最大,所以本文以 Windows 为例进行展示。",-1),b=e("p",null,"其次,虽然 Windows 10 之后的 PowerShell 和 WSL 也可以达到很好的 SSH 操作体验。但是因为并非所有版本的 Windows 都有最新的组件,故本文还是以老牌的 PuTTY 为例,进行 SSH 远程登录的操作详解。(使用其他工具的话、在 SSH 登陆之后的操作都是一样的)",-1),f=e("p",null,"下面就跟我一步步操作吧。",-1),y={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},T=e("p",null,[e("img",{src:p,alt:"下载PuTTY"})],-1),k=e("strong",null,[t("IP 地址(VPS IP)"),e("strong",null,"和"),t("端口(VPS PORT)")],-1),L=e("p",null,[e("img",{src:u,alt:"设置PuTTY"})],-1),w=e("li",null,[e("p",null,[t("我建议将 "),e("code",null,"Connection"),t(" 中的 "),e("code",null,"keepalive"),t(" 设置为 "),e("code",null,"60"),t(" 秒,防止你一段时间没有操作之后 SSH 自动断线。另外务必再次保存设置。")]),e("p",null,[e("img",{src:h,alt:"防止频繁断线"})])],-1),V=r('

注意

对 PuTTY 的任何设置更新都要再次手动保存 Session,不然关闭后就会丢失

  1. 点击 Open 就会进入 SSH 连接窗口,对应下图输入用户名与密码,与你的 VPS 远程主机建立连接。(本文假设默认用户名是 root,另外,在 Linux 系统输入密码的时候,是不会出现 ****** 这种提示符的,这样可以避免密码长度泄漏,不是你的键盘坏掉了哦!)

    SSH远程登录

3.2 成功登录 SSH!初识命令行界面!

  1. 如果你的信息都填写正确,你将会看到类似下图的界面,说明已登录成功:

    初次登录VPS

    这个界面,就等于远程服务器的【桌面】,但它没有你熟悉的图标和鼠标,没有绚丽的色彩,有的只是简单文字,这就是【命令行界面】- Command Line Interface,或者缩写为 CLI

    接下来的所有操作,都需要你像电影里的黑客一样,在这个命令行界面中完成。也许你会觉得陌生,但请相信我,使用命令行既不可怕,也不神秘。说到底,它只不过是把你习惯的鼠标操作变成了文字指令而已,你说一句,它做一句

  2. 现在,你可以稍微观察并熟悉一下命令行环境,这个界面其实已经告诉了你一些有用的信息了,比如系统内核版本(比如图内是 4.19.37-5)、上次登录时间及 IP 等。当然根据 VPS 的不同,你看到的界面可能会略有不同。

  3. 请注意命令行最下面一行,闪动的光标左边,有一串字符。图中显示的是root@vps-server:~#,这一串要怎么理解呢?很简单:

    • 现在的用户是 root
    • root 所在的服务器是 vps-server
    • root 现在所在的文件夹是 ~
    • # 之后是你可以输入命令的地方

    前两个很直观,无需多说。第三个是关于 Linux 的文件夹系统,现在也不需要过于深入,你只需要知道,"~"就是【当前用户的大本营】。第四个,提示符#,你也不用管,只需要知道,未来文章中会写一些需要你输入的命令,都会以 "#" 或者 "$" 开头,提示你后面是你输入命令的地方。(所以你复制命令的时候,只需要复制后面的内容,不要复制提示符)

3.3 第一次更新 Linux 的软件!

  1. 正如你的手机,无论安卓还是 iPhone,为了 APP 及时更新(获取安全补丁和新功能),都会时不时从应用商店获得更新信息,并且提示你有多少个 APP 可更新。Linux 系统也有逻辑十分类似的更新机制。所以只要你会更新手机 APP,就能学会更新 Linux 软件!

  2. Linux 下,每个 APP 都叫做一个“包” (package)。管理 APP 的程序自然就叫做“包管理器”(Package Manager)。你可以通过它安装、更新、卸载各种软件、甚至更新 Linux 系统本身。Linux 下的包管理器非常强大,此处按下不表,现在你只需要知道 Debian 系统的包管理器叫做 apt 即可。接下来,我们就先使用 apt 做一次软件的全面更新,让你熟悉它的基本操作。

  3. 小小白白 Linux 基础命令:

    编号命令名称命令说明
    cmd-01apt update查询软件更新
    cmd-02apt upgrade执行软件更新
  4. 现在请输入第一条命令,获取更新信息

    apt update
    +import{_ as a,r as o,o as c,c as d,a as e,b as t,d as s,w as i,e as r}from"./app-UOvWaKji.js";const p="/assets/ch03-img01-putty-download-gVwywNaM.png",u="/assets/ch03-img02-putty-settings-9F25dGfD.png",h="/assets/ch03-img03-putty-keepalive-dggTHgup.png",g="/assets/ch03-img04-ssh-login-8MrxOwy-.png",_="/assets/ch03-img05-ssh-login-success-bpTQqXTk.png",m="/assets/ch03-img06-apt-upgrade-full-PsNwQRq8.gif",x={},P=e("h1",{id:"【第-3-章】远程登录篇",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#【第-3-章】远程登录篇"},[e("span",null,"【第 3 章】远程登录篇")])],-1),S=e("h2",{id:"_3-1-远程登录-vps-putty",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-1-远程登录-vps-putty"},[e("span",null,"3.1 远程登录 VPS (PuTTY)")])],-1),v=e("p",null,"首先,鉴于零基础人群中 Windows 的用户基数最大,所以本文以 Windows 为例进行展示。",-1),b=e("p",null,"其次,虽然 Windows 10 之后的 PowerShell 和 WSL 也可以达到很好的 SSH 操作体验。但是因为并非所有版本的 Windows 都有最新的组件,故本文还是以老牌的 PuTTY 为例,进行 SSH 远程登录的操作详解。(使用其他工具的话、在 SSH 登陆之后的操作都是一样的)",-1),f=e("p",null,"下面就跟我一步步操作吧。",-1),y={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},T=e("p",null,[e("img",{src:p,alt:"下载PuTTY"})],-1),k=e("strong",null,[t("IP 地址(VPS IP)"),e("strong",null,"和"),t("端口(VPS PORT)")],-1),L=e("p",null,[e("img",{src:u,alt:"设置PuTTY"})],-1),w=e("li",null,[e("p",null,[t("我建议将 "),e("code",null,"Connection"),t(" 中的 "),e("code",null,"keepalive"),t(" 设置为 "),e("code",null,"60"),t(" 秒,防止你一段时间没有操作之后 SSH 自动断线。另外务必再次保存设置。")]),e("p",null,[e("img",{src:h,alt:"防止频繁断线"})])],-1),V=r('

    注意

    对 PuTTY 的任何设置更新都要再次手动保存 Session,不然关闭后就会丢失

    1. 点击 Open 就会进入 SSH 连接窗口,对应下图输入用户名与密码,与你的 VPS 远程主机建立连接。(本文假设默认用户名是 root,另外,在 Linux 系统输入密码的时候,是不会出现 ****** 这种提示符的,这样可以避免密码长度泄漏,不是你的键盘坏掉了哦!)

      SSH远程登录

    3.2 成功登录 SSH!初识命令行界面!

    1. 如果你的信息都填写正确,你将会看到类似下图的界面,说明已登录成功:

      初次登录VPS

      这个界面,就等于远程服务器的【桌面】,但它没有你熟悉的图标和鼠标,没有绚丽的色彩,有的只是简单文字,这就是【命令行界面】- Command Line Interface,或者缩写为 CLI

      接下来的所有操作,都需要你像电影里的黑客一样,在这个命令行界面中完成。也许你会觉得陌生,但请相信我,使用命令行既不可怕,也不神秘。说到底,它只不过是把你习惯的鼠标操作变成了文字指令而已,你说一句,它做一句

    2. 现在,你可以稍微观察并熟悉一下命令行环境,这个界面其实已经告诉了你一些有用的信息了,比如系统内核版本(比如图内是 4.19.37-5)、上次登录时间及 IP 等。当然根据 VPS 的不同,你看到的界面可能会略有不同。

    3. 请注意命令行最下面一行,闪动的光标左边,有一串字符。图中显示的是root@vps-server:~#,这一串要怎么理解呢?很简单:

      • 现在的用户是 root
      • root 所在的服务器是 vps-server
      • root 现在所在的文件夹是 ~
      • # 之后是你可以输入命令的地方

      前两个很直观,无需多说。第三个是关于 Linux 的文件夹系统,现在也不需要过于深入,你只需要知道,"~"就是【当前用户的大本营】。第四个,提示符#,你也不用管,只需要知道,未来文章中会写一些需要你输入的命令,都会以 "#" 或者 "$" 开头,提示你后面是你输入命令的地方。(所以你复制命令的时候,只需要复制后面的内容,不要复制提示符)

    3.3 第一次更新 Linux 的软件!

    1. 正如你的手机,无论安卓还是 iPhone,为了 APP 及时更新(获取安全补丁和新功能),都会时不时从应用商店获得更新信息,并且提示你有多少个 APP 可更新。Linux 系统也有逻辑十分类似的更新机制。所以只要你会更新手机 APP,就能学会更新 Linux 软件!

    2. Linux 下,每个 APP 都叫做一个“包” (package)。管理 APP 的程序自然就叫做“包管理器”(Package Manager)。你可以通过它安装、更新、卸载各种软件、甚至更新 Linux 系统本身。Linux 下的包管理器非常强大,此处按下不表,现在你只需要知道 Debian 系统的包管理器叫做 apt 即可。接下来,我们就先使用 apt 做一次软件的全面更新,让你熟悉它的基本操作。

    3. 小小白白 Linux 基础命令:

      编号命令名称命令说明
      cmd-01apt update查询软件更新
      cmd-02apt upgrade执行软件更新
    4. 现在请输入第一条命令,获取更新信息

      apt update
       
    5. 然后请输入第二条命令,并在询问是否继续安装 (Y/n) 时输入 y 并回车确认,开始安装

      apt upgrade
       
    6. 完整流程演示如下:

      初次软件更新流程演示

    3.4 你的进度

    恭喜你又迈出了坚实的一步! 现在,你已经可以通过 SSH 来登录你的远程服务器了!那登录进去之后,除了升级软件之外,应该再做点什么呢?敬请进入下一章一探究竟吧!

    ⬛⬛⬛⬜⬜⬜⬜⬜ 37.5%

    ',9);function q(H,E){const n=o("ExternalLinkIcon"),l=o("RouterLink");return c(),d("div",null,[P,S,v,b,f,e("ol",null,[e("li",null,[e("p",null,[t("进入 PuTTY 的"),e("a",y,[t("官网"),s(n)]),t(",选择适合你操作系统的版本下载。(本文以 64 位版本为例)")]),T]),e("li",null,[e("p",null,[t("安装运行后,将会看到 PuTTY 的主界面。现在请拿出你上一章记东西的"),s(l,{to:"/document/level-0/ch02-preparation.html#21-%E8%8E%B7%E5%8F%96%E4%B8%80%E5%8F%B0vps"},{default:i(()=>[t("小本本")]),_:1}),t(",在下图的对应位置填入你 VPS 的"),k,t("。为了方便以后使用时不用重复输入,我们可以保存会话 (Saved Sessions),未来使用时只要按 Load 即可一键载入设置。")]),L]),w]),V])}const I=a(x,[["render",q],["__file","ch03-ssh.html.vue"]]);export{I as default}; diff --git a/assets/ch04-security.html-tFoBShHh.js b/assets/ch04-security.html-33MaGmAV.js similarity index 99% rename from assets/ch04-security.html-tFoBShHh.js rename to assets/ch04-security.html-33MaGmAV.js index 28cbac8642..d5401bdf1d 100644 --- a/assets/ch04-security.html-tFoBShHh.js +++ b/assets/ch04-security.html-33MaGmAV.js @@ -1,4 +1,4 @@ -import{_ as c,r as d,o as i,c as l,a as e,b as t,d as n,e as o}from"./app-PDrbPfzp.js";const a="/assets/ch04-img01-nano-ui-Oo4HU2KZ.png",p="/assets/ch04-img02-sshd-conf-full-7_JFMwvi.gif",r="/assets/ch04-img03-adduser-opG_7XzM.png",h="/assets/ch04-img04-adduser-full-4A5I1bZl.gif",u="/assets/ch04-img05-sudo-full-3iorC9_U.gif",g="/assets/ch04-img06-ssh-no-root-full-2Xke7pLI.gif",m="/assets/ch04-img07-putty-default-user-Uz6ByXtY.png",_="/assets/ch04-img08-puttygen-save-trq9BjLs.png",v="/assets/ch04-img09-puttygen-save-keys-vLMRFWc3.png",S="/assets/ch04-img10-winscp-import-session-XcebKiQh.png",b="/assets/ch04-img11-winscp-ui-qpe61gpr.png",x="/assets/ch04-img12-winscp-locations-LVSFx0Gv.png",y="/assets/ch04-img13-winscp-newfolder-key-LCGlJF7z.png",P="/assets/ch04-img14-winscp-upload-key-cYDbKigI.png",f="/assets/ch04-img15-winscp-rename-key-0HbKMEUe.png",k="/assets/ch04-img16-winscp-full-f89kJTvj.gif",T="/assets/ch04-img17-rsa-login-full-mcrVWcK9.gif",L="/assets/ch04-img18-putty-privatekey-location-IFasU6Lo.png",V="/assets/ch04-img19-putty-privatekey-passphrase-gyNqeCHk.png",A="/assets/ch04-img20-winscp-privatekey-location-sNcUjGIT.png",w={},H=o(`

    【第 4 章】安全防护篇

    4.1 为什么要做安全防护

    Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的网站、APP、服务、甚至线下基础设施都建立在 Linux 的基石之上,这背后牵涉到巨大的经济利益和商业价值,当然也就就意味着黑灰产有巨大的攻击动力。但是这些服务是如此重要、根本不允许出现重大的安全漏洞。于是无数的运维专业人员都在安全攻防的战场上拼搏努力,这才让大家能享受到基本稳定的现代化数字生活。

    现在,你拥有了一台 VPS,并且将会敞开他的数据访问渠道来达到流量转发的目标,那就相当于你已经置身于安全攻防战场的第一线、直面所有风险。但与此同时,新人由于知识和信息的不足,看待安全问题是总是难免两极分化:要么觉得轻如鸿毛和自己没有半点关系,要么觉得重于泰山甚至惶惶不可终日。

    • 对于前者,我的建议是:安全无小事,尽量多查一些安全方面的信息,免得自己真的受了损失才后悔莫及

    • 对于后者,我的建议是:不用紧张,我们的服务器仍不具有太高的价值、一般不会吸引到高水平的攻击,需要面对的基本都是一些自动化脚本的恶意扫描和登录尝试,跟着本文做一些基础的防护即可

    4.2 具体的风险到底是什么

    就像我们在《远程登录篇》配置的一样,任何人只需要知道【IP 地址】+【端口】+【用户名】+【密码】这四个要素,就能登录你的 VPS 服务器。那很显然,这四要素的安全就是我们要防护的底线。我们来逐一分析:

    1. 【IP 地址】:恶意脚本会随机尝试和扫描 IP 段,可以简单认为是公开信息、无法隐藏

    2. 【端口】:如果使用默认端口,那么【端口 = 22

    3. 【用户名】:如果使用默认用户,那么【用户名 = root

    4. 【密码】:密码不存在默认值,一定是由 VPS 后台随机生成或由你自行设置的。也就是说,如果你的服务器都是默认设置,则四要素中的三个已经是已知的,那么你整个服务器的安全,就全部寄托在一串小小的密码上了。这时有几种情况:

      • 如果你用了 VPS 管理后台随机生成密码,它一般包含随机的十几个大小写混杂的字母和符号,相对比较安全

      • 如果你为了好记、把密码改成了类似123456这种超弱的密码,破解你的 VPS 服务器可谓不费吹灰之力

      • 如果你为了好记、把密码改成了比较复杂、但在别的地方用过的密码,其实也并不安全。你要明白黑客手里有作弊器,比如说密码表,包含数万、数十万、数百万甚至更多曾经泄漏的真实密码)

    5. 但你要明白,没有哪个黑客真的要坐在电脑前一次一次的尝试你的密码,全部的攻击尝试都是恶意脚本自动进行的,它会 24 小时不眠不休的工作。也许每天你酣睡之时,你的服务器都在经受着一轮又一轮的冲击。

      一旦密码被成功撞破,意味着你的四要素全部被攻击者掌握,恶意脚本就会快速登录服务器、获取服务器的最高 root 控制权、安装部署它的恶意服务,然后就可以用你的服务器来 24 小时做各种坏事(比如挖矿、传播病毒、发送垃圾邮件、欺诈邮件、做 BT 中继、甚至暗网公众节点等等等等)。如果恶意脚本比较克制,其实可以做到相当的隐蔽性。而新人一般也不会去观察留意 VPS 的登录记录、进程变化、CPU 占用变化、流量变化等指标,你其实就很难发现自己被黑了。直到你的 VPS 服务商封禁你的账号、或者收到律师函为止。

    6. 别忘了,你获得 VPS 时大概率需要使用真实的支付信息,你登录各种网站、社交平台时也会留下你的 IP 地址,这些都与你的身份有直接或者间接的关系。于是,一旦这些坏事发生,它们就不可避免的与你产生了关联。

    4.3 我们要做的安全防护有哪些

    基于上述分析,我们要做的,自然就是对【端口】、【用户名】、【密码】这三要素进行加强,来降低被攻破的风险:

    1. 【端口】:将 SSH 远程登录端口修改为【非 22 端口】 (4.4)
    2. 【用户名】:建立【非 root】的新用户、并禁用 root 用户 SSH 远程登录 (4.5、4.6)
    3. 【密码】:SSH 启用 RSA 密钥验证登录、同时禁用密码验证登录 (4.7)

    记得按顺序来,别把自己锁在门外了。

    4.4 将 SSH 远程登录端口修改为非 22 端口

    现在,我们来解决【端口 = 22】的问题。(注意:有些 VPS 服务商,默认的端口已经是非 22 端口,那么你可以忽略这一步,当然也可以跟着本文改成别的端口)

    1. 小小白白 Linux 基础命令:

      编号命令名称命令说明
      cmd-03nano文本编辑器
      cmd-04systemctl restart重启某个服务
    2. 小小白白 Linux 基础配置文件

      编号配置文件位置文件说明
      conf-01/etc/ssh/sshd_configSSH 远程登录程序设置
    3. 我们要做的第一件事,当然就是【用nano这个文本编辑器打开SSH远程登录程序设置】,在 Windows 下,你会【找到文件并双击】,在 Linux 下该怎么办呢?仔细看看上面的命令说明,是不是就很简单了?没错,就是:

      nano /etc/ssh/sshd_config
      +import{_ as c,r as d,o as i,c as l,a as e,b as t,d as n,e as o}from"./app-UOvWaKji.js";const a="/assets/ch04-img01-nano-ui-Oo4HU2KZ.png",p="/assets/ch04-img02-sshd-conf-full-7_JFMwvi.gif",r="/assets/ch04-img03-adduser-opG_7XzM.png",h="/assets/ch04-img04-adduser-full-4A5I1bZl.gif",u="/assets/ch04-img05-sudo-full-3iorC9_U.gif",g="/assets/ch04-img06-ssh-no-root-full-2Xke7pLI.gif",m="/assets/ch04-img07-putty-default-user-Uz6ByXtY.png",_="/assets/ch04-img08-puttygen-save-trq9BjLs.png",v="/assets/ch04-img09-puttygen-save-keys-vLMRFWc3.png",S="/assets/ch04-img10-winscp-import-session-XcebKiQh.png",b="/assets/ch04-img11-winscp-ui-qpe61gpr.png",x="/assets/ch04-img12-winscp-locations-LVSFx0Gv.png",y="/assets/ch04-img13-winscp-newfolder-key-LCGlJF7z.png",P="/assets/ch04-img14-winscp-upload-key-cYDbKigI.png",f="/assets/ch04-img15-winscp-rename-key-0HbKMEUe.png",k="/assets/ch04-img16-winscp-full-f89kJTvj.gif",T="/assets/ch04-img17-rsa-login-full-mcrVWcK9.gif",L="/assets/ch04-img18-putty-privatekey-location-IFasU6Lo.png",V="/assets/ch04-img19-putty-privatekey-passphrase-gyNqeCHk.png",A="/assets/ch04-img20-winscp-privatekey-location-sNcUjGIT.png",w={},H=o(`

      【第 4 章】安全防护篇

      4.1 为什么要做安全防护

      Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的网站、APP、服务、甚至线下基础设施都建立在 Linux 的基石之上,这背后牵涉到巨大的经济利益和商业价值,当然也就就意味着黑灰产有巨大的攻击动力。但是这些服务是如此重要、根本不允许出现重大的安全漏洞。于是无数的运维专业人员都在安全攻防的战场上拼搏努力,这才让大家能享受到基本稳定的现代化数字生活。

      现在,你拥有了一台 VPS,并且将会敞开他的数据访问渠道来达到流量转发的目标,那就相当于你已经置身于安全攻防战场的第一线、直面所有风险。但与此同时,新人由于知识和信息的不足,看待安全问题是总是难免两极分化:要么觉得轻如鸿毛和自己没有半点关系,要么觉得重于泰山甚至惶惶不可终日。

      • 对于前者,我的建议是:安全无小事,尽量多查一些安全方面的信息,免得自己真的受了损失才后悔莫及

      • 对于后者,我的建议是:不用紧张,我们的服务器仍不具有太高的价值、一般不会吸引到高水平的攻击,需要面对的基本都是一些自动化脚本的恶意扫描和登录尝试,跟着本文做一些基础的防护即可

      4.2 具体的风险到底是什么

      就像我们在《远程登录篇》配置的一样,任何人只需要知道【IP 地址】+【端口】+【用户名】+【密码】这四个要素,就能登录你的 VPS 服务器。那很显然,这四要素的安全就是我们要防护的底线。我们来逐一分析:

      1. 【IP 地址】:恶意脚本会随机尝试和扫描 IP 段,可以简单认为是公开信息、无法隐藏

      2. 【端口】:如果使用默认端口,那么【端口 = 22

      3. 【用户名】:如果使用默认用户,那么【用户名 = root

      4. 【密码】:密码不存在默认值,一定是由 VPS 后台随机生成或由你自行设置的。也就是说,如果你的服务器都是默认设置,则四要素中的三个已经是已知的,那么你整个服务器的安全,就全部寄托在一串小小的密码上了。这时有几种情况:

        • 如果你用了 VPS 管理后台随机生成密码,它一般包含随机的十几个大小写混杂的字母和符号,相对比较安全

        • 如果你为了好记、把密码改成了类似123456这种超弱的密码,破解你的 VPS 服务器可谓不费吹灰之力

        • 如果你为了好记、把密码改成了比较复杂、但在别的地方用过的密码,其实也并不安全。你要明白黑客手里有作弊器,比如说密码表,包含数万、数十万、数百万甚至更多曾经泄漏的真实密码)

      5. 但你要明白,没有哪个黑客真的要坐在电脑前一次一次的尝试你的密码,全部的攻击尝试都是恶意脚本自动进行的,它会 24 小时不眠不休的工作。也许每天你酣睡之时,你的服务器都在经受着一轮又一轮的冲击。

        一旦密码被成功撞破,意味着你的四要素全部被攻击者掌握,恶意脚本就会快速登录服务器、获取服务器的最高 root 控制权、安装部署它的恶意服务,然后就可以用你的服务器来 24 小时做各种坏事(比如挖矿、传播病毒、发送垃圾邮件、欺诈邮件、做 BT 中继、甚至暗网公众节点等等等等)。如果恶意脚本比较克制,其实可以做到相当的隐蔽性。而新人一般也不会去观察留意 VPS 的登录记录、进程变化、CPU 占用变化、流量变化等指标,你其实就很难发现自己被黑了。直到你的 VPS 服务商封禁你的账号、或者收到律师函为止。

      6. 别忘了,你获得 VPS 时大概率需要使用真实的支付信息,你登录各种网站、社交平台时也会留下你的 IP 地址,这些都与你的身份有直接或者间接的关系。于是,一旦这些坏事发生,它们就不可避免的与你产生了关联。

      4.3 我们要做的安全防护有哪些

      基于上述分析,我们要做的,自然就是对【端口】、【用户名】、【密码】这三要素进行加强,来降低被攻破的风险:

      1. 【端口】:将 SSH 远程登录端口修改为【非 22 端口】 (4.4)
      2. 【用户名】:建立【非 root】的新用户、并禁用 root 用户 SSH 远程登录 (4.5、4.6)
      3. 【密码】:SSH 启用 RSA 密钥验证登录、同时禁用密码验证登录 (4.7)

      记得按顺序来,别把自己锁在门外了。

      4.4 将 SSH 远程登录端口修改为非 22 端口

      现在,我们来解决【端口 = 22】的问题。(注意:有些 VPS 服务商,默认的端口已经是非 22 端口,那么你可以忽略这一步,当然也可以跟着本文改成别的端口)

      1. 小小白白 Linux 基础命令:

        编号命令名称命令说明
        cmd-03nano文本编辑器
        cmd-04systemctl restart重启某个服务
      2. 小小白白 Linux 基础配置文件

        编号配置文件位置文件说明
        conf-01/etc/ssh/sshd_configSSH 远程登录程序设置
      3. 我们要做的第一件事,当然就是【用nano这个文本编辑器打开SSH远程登录程序设置】,在 Windows 下,你会【找到文件并双击】,在 Linux 下该怎么办呢?仔细看看上面的命令说明,是不是就很简单了?没错,就是:

        nano /etc/ssh/sshd_config
         
      4. 文件打开后,你就进入了nano的界面,稍微观察一下,你会发现,它把重要的快捷键都显示在屏幕下方了(下图红框内),直接开卷考试、不用死记硬背,是不是很贴心呢?

        nano的界面

      1. 我们要做的第二件事,是【在打开的文件中找到Port这一项,并修改它的端口】。Port 后面的数字就是 SSH 的端口,一般建议把它改成一个大于1024小于65535的整数(本文以9753为例)。请结合nano的快捷键,想一下该怎么操作呢?果然,你又说对了!就是:

        • 使用 ctrl+w 进入搜索模式,然后输入 Port 22 并回车
        • 删除 22 并改成 9753
        • 说明:如果这一行开头有个#,证明这一行【不生效】(被注释掉了),你可像我一样在文件最后写一个不带#的,或者把#删掉就好。

        注意

        本文以9753为例,就意味着随着本文的发布,这个端口会变成一个不大不小的特征,也许会被攻击者优先尝试、也许被 GFW 干扰、阻断。所以我强烈建议你用一个自己想到的其他端口,毕竟,你有 6 万多个端口可以自由选择。

      1. 我们要做的第三件事,是【保存文件并退出】

        • 如果第 3 步你有仔细观察,就会发现保存并不是常见的 ctrl+s
        • 正确的快捷键:保存是 ctrl+o + 回车,退出是 ctrl+x
      2. 我们最后要做的事,是【重启 ssh 服务,使变更生效】

        systemctl restart ssh
         
      3. 完整流程演示如下:

        修改非22端口演示

      4. 修改 PuTTY 配置

        现在新的端口已经生效,下次使用 PuTTY 登录时就要用9753了。所以现在请到 PuTTY 的设置中修改端口号码,然后保存 Session。嗯,你应该知道去哪里改了吧?(如果不知道的话,要重读前面的内容了哦!)

      4.5 建立非 root 的新用户

      第二步,我们来解决【用户名 = root】的问题。

      首先你要理解, Linux 系统中的root,不仅仅是一个管理员账号那么简单。它是整个系统的【根基】、是系统的主宰、至高无上的神。一旦root账号出现安全问题,整个系统都只能任人鱼肉、无处可逃。那么就跟随我进行操作吧:

      1. 小小白白 Linux 基础命令:

        编号命令名称命令说明
        cmd-05adduser给系统新增用户
        cmd-06apt install安装某个软件
        cmd-07visudo修改 sudo 权限设置专用编辑器
      2. 我们要做的第一件事,是【新增一个用户并设定登录密码】,名字你可以随便起,我这里以vpsadmin为例:

        adduser vpsadmin
         

        执行命令后,根据提示操作即可。请务必设置一个用户密码(别忘记设置密码时你时看不到 ****** 的)。之后系统会询问你一些用户的附加信息,这些就可以无视,一路回车即可。

        建立新用户

        注意

        本文以vpsadmin为例,就意味着随着本文的发布,这个用户名也会变成一个不大不小的特征,也许会被攻击者优先尝试。所以和端口一样,我强烈建议你用一个自己想到的其他用户名。

      3. 完整流程演示如下:

        建立新用户

      4. 我们要做的第二件事,是【安装sudo功能】(sudo 就是在关键时刻,让普通账户临时获得 root 的神力,战力全开拯救世界)

        apt update && apt install sudo
        diff --git a/assets/ch04-security.html-fCxnbCda.js b/assets/ch04-security.html-zUuYrXhG.js
        similarity index 99%
        rename from assets/ch04-security.html-fCxnbCda.js
        rename to assets/ch04-security.html-zUuYrXhG.js
        index 9075c5e960..262c77d999 100644
        --- a/assets/ch04-security.html-fCxnbCda.js
        +++ b/assets/ch04-security.html-zUuYrXhG.js
        @@ -1,4 +1,4 @@
        -import{_ as a,r as i,o as n,c as r,a as t,b as e,d as c,e as o}from"./app-PDrbPfzp.js";const l="/assets/ch04-img01-nano-ui-Oo4HU2KZ.png",d="/assets/ch04-img02-sshd-conf-full-7_JFMwvi.gif",h="/assets/ch04-img03-adduser-opG_7XzM.png",u="/assets/ch04-img04-adduser-full-4A5I1bZl.gif",p="/assets/ch04-img05-sudo-full-3iorC9_U.gif",m="/assets/ch04-img06-ssh-no-root-full-2Xke7pLI.gif",g="/assets/ch04-img07-putty-default-user-Uz6ByXtY.png",y="/assets/ch04-img08-puttygen-save-trq9BjLs.png",f="/assets/ch04-img09-puttygen-save-keys-vLMRFWc3.png",w="/assets/ch04-img10-winscp-import-session-XcebKiQh.png",v="/assets/ch04-img11-winscp-ui-qpe61gpr.png",b="/assets/ch04-img12-winscp-locations-LVSFx0Gv.png",k="/assets/ch04-img13-winscp-newfolder-key-LCGlJF7z.png",S="/assets/ch04-img14-winscp-upload-key-cYDbKigI.png",x="/assets/ch04-img15-winscp-rename-key-0HbKMEUe.png",T="/assets/ch04-img16-winscp-full-f89kJTvj.gif",_="/assets/ch04-img17-rsa-login-full-mcrVWcK9.gif",P="/assets/ch04-img18-putty-privatekey-location-IFasU6Lo.png",I="/assets/ch04-img19-putty-privatekey-passphrase-gyNqeCHk.png",L="/assets/ch04-img20-winscp-privatekey-location-sNcUjGIT.png",C={},A=o(`

        [Chapter 4] Security and Protection

        4.1 Why Do We Need Security Protection?

        Security protection for Linux servers is a complex and huge subject. Countless websites, apps, services, and even offline infrastructure are built on the foundation of Linux, which involves huge economic benefits and commercial value. This also means that there is a huge motivation for black and gray industries to launch attacks. However, these services are so important that major security vulnerabilities are not allowed. Therefore, countless operation and maintenance professionals are working hard on the battlefield of security attacks and defense, which enables us to enjoy a basic stable modern digital life.

        Now, you have a VPS and will open its data access channel to achieve the goal of traffic forwarding, which means you are now on the front line of the security battle and face all risks. However, at the same time, newcomers tend to have a polarized view of security issues due to lack of knowledge and information: either they feel it is as light as a feather and has nothing to do with them, or they feel it is as heavy as Mount Tai and feel anxious all day long.

        • For the former, my suggestion is: safety is of utmost importance. Try to gather more information on safety issues to avoid regretting after experiencing losses.

        • For the latter, my suggestion is: don't worry too much, our servers still don't have too much value and generally won't attract high-level attacks. The basic threats we need to face are mostly malicious scans and login attempts from some automated scripts. Just follow this article to do some basic protection.

        4.2 What are the specific risks

        Just like the configuration we did in the "Remote Login" section, anyone who knows the four elements of [IP address] + [port] + [username] + [password] can log in to your VPS server. So obviously, the security of these four elements is the bottom line that we need to protect. Let's analyze them one by one:

        1. [IP Address]: Malicious scripts randomly attempt to scan IP ranges, which can be regarded as public information and cannot be hidden.

        2. [Port]: If you are using the default port, then [Port = 22].

        3. [Username]: If using the default user, then [Username = root]

        4. [Password]: There is no default value for the password. It must be randomly generated by the VPS backend or set by you. In other words, if all the settings of your server are default, then three of the four elements are already known. Therefore, the security of your entire server relies on a small password. In this case, there are several situations:

        • If you use a VPS management background to generate passwords randomly, it usually contains random uppercase and lowercase letters, symbols, and is relatively secure.

        • If you changed your password to something super weak like 123456 just for the sake of easy memorization, hacking into your VPS server would be a piece of cake.

        • If you change your password to a more complex one that you have used elsewhere just for the sake of easy memory, it is not really safe. You should understand that hackers have cheats in their hands, such as password tables, which contain tens of thousands, hundreds of thousands, millions, or even more real leaked passwords.

        1. But you should understand that no hacker really sits in front of a computer and tries your password repeatedly. All attack attempts are carried out automatically by malicious scripts, which work tirelessly for 24 hours. Perhaps while you are sleeping soundly every night, your server is enduring round after round of attacks.

        Once the password is successfully cracked, it means that all four of your elements have been mastered by the attacker. The malicious script will quickly log in to the server, obtain the highest root control of the server, install and deploy its malicious services, and then use your server to do all kinds of bad things 24 hours a day (such as mining, spreading viruses, sending spam emails, fraudulent emails, acting as a BT relay, and even dark web public nodes, and so on). If the malicious script is relatively restrained, it can actually achieve considerable concealment. Generally, newcomers will not observe and pay attention to indicators such as login records, process changes, CPU usage changes, and traffic changes of the VPS, so it is difficult for you to discover that you have been hacked. Until your VPS service provider blocks your account or you receive a lawyer's letter.

        1. Don't forget that when you obtain a VPS, you probably need to use your real payment information, and when you log in to various websites and social platforms, your IP address will also be recorded, which has a direct or indirect relationship with your identity. Therefore, once these bad things happen, they will inevitably be associated with you.

        4.3 What security measures do we need to take

        Based on the above analysis, what we need to do is to strengthen the three elements of [port], [username], and [password] to reduce the risk of being hacked.

        1. [Port]: Modify the SSH remote login port to a [non-22 port] (4.4).
        2. [Username]: Create a [non-root] new user and disable root user SSH remote login (4.5, 4.6).
        3. [Password]: Enable RSA key verification for SSH login and disable password verification login (4.7).

        Remember to follow the order and don't lock yourself out.

        4.4 Change the SSH Remote Login Port to a Non-22 Port

        Now, let's solve the problem of "port = 22". (Note: some VPS service providers have non-22 ports set as default, so you can ignore this step if that's the case. Of course, you can also follow this article to change it to another port.)

        1. Basic commands of Little White Linux:
        IDCommand NameDescription
        cmd-03nanoText editor
        cmd-04systemctl restartRestart a service
        1. Basic Configuration Files of Little White Linux
        NumberConfiguration File LocationFile Description
        conf-01/etc/ssh/sshd_configSSH Remote Login Program Settings
        1. The first thing we need to do, of course, is to [open the SSH remote login program settings with the text editor nano]. In Windows, you will [find the file and double-click] it. What should you do in Linux? Take a close look at the command instructions above, isn't it simple? Yes, it is:
        nano /etc/ssh/sshd_config
        +import{_ as a,r as i,o as n,c as r,a as t,b as e,d as c,e as o}from"./app-UOvWaKji.js";const l="/assets/ch04-img01-nano-ui-Oo4HU2KZ.png",d="/assets/ch04-img02-sshd-conf-full-7_JFMwvi.gif",h="/assets/ch04-img03-adduser-opG_7XzM.png",u="/assets/ch04-img04-adduser-full-4A5I1bZl.gif",p="/assets/ch04-img05-sudo-full-3iorC9_U.gif",m="/assets/ch04-img06-ssh-no-root-full-2Xke7pLI.gif",g="/assets/ch04-img07-putty-default-user-Uz6ByXtY.png",y="/assets/ch04-img08-puttygen-save-trq9BjLs.png",f="/assets/ch04-img09-puttygen-save-keys-vLMRFWc3.png",w="/assets/ch04-img10-winscp-import-session-XcebKiQh.png",v="/assets/ch04-img11-winscp-ui-qpe61gpr.png",b="/assets/ch04-img12-winscp-locations-LVSFx0Gv.png",k="/assets/ch04-img13-winscp-newfolder-key-LCGlJF7z.png",S="/assets/ch04-img14-winscp-upload-key-cYDbKigI.png",x="/assets/ch04-img15-winscp-rename-key-0HbKMEUe.png",T="/assets/ch04-img16-winscp-full-f89kJTvj.gif",_="/assets/ch04-img17-rsa-login-full-mcrVWcK9.gif",P="/assets/ch04-img18-putty-privatekey-location-IFasU6Lo.png",I="/assets/ch04-img19-putty-privatekey-passphrase-gyNqeCHk.png",L="/assets/ch04-img20-winscp-privatekey-location-sNcUjGIT.png",C={},A=o(`

        [Chapter 4] Security and Protection

        4.1 Why Do We Need Security Protection?

        Security protection for Linux servers is a complex and huge subject. Countless websites, apps, services, and even offline infrastructure are built on the foundation of Linux, which involves huge economic benefits and commercial value. This also means that there is a huge motivation for black and gray industries to launch attacks. However, these services are so important that major security vulnerabilities are not allowed. Therefore, countless operation and maintenance professionals are working hard on the battlefield of security attacks and defense, which enables us to enjoy a basic stable modern digital life.

        Now, you have a VPS and will open its data access channel to achieve the goal of traffic forwarding, which means you are now on the front line of the security battle and face all risks. However, at the same time, newcomers tend to have a polarized view of security issues due to lack of knowledge and information: either they feel it is as light as a feather and has nothing to do with them, or they feel it is as heavy as Mount Tai and feel anxious all day long.

        • For the former, my suggestion is: safety is of utmost importance. Try to gather more information on safety issues to avoid regretting after experiencing losses.

        • For the latter, my suggestion is: don't worry too much, our servers still don't have too much value and generally won't attract high-level attacks. The basic threats we need to face are mostly malicious scans and login attempts from some automated scripts. Just follow this article to do some basic protection.

        4.2 What are the specific risks

        Just like the configuration we did in the "Remote Login" section, anyone who knows the four elements of [IP address] + [port] + [username] + [password] can log in to your VPS server. So obviously, the security of these four elements is the bottom line that we need to protect. Let's analyze them one by one:

        1. [IP Address]: Malicious scripts randomly attempt to scan IP ranges, which can be regarded as public information and cannot be hidden.

        2. [Port]: If you are using the default port, then [Port = 22].

        3. [Username]: If using the default user, then [Username = root]

        4. [Password]: There is no default value for the password. It must be randomly generated by the VPS backend or set by you. In other words, if all the settings of your server are default, then three of the four elements are already known. Therefore, the security of your entire server relies on a small password. In this case, there are several situations:

        • If you use a VPS management background to generate passwords randomly, it usually contains random uppercase and lowercase letters, symbols, and is relatively secure.

        • If you changed your password to something super weak like 123456 just for the sake of easy memorization, hacking into your VPS server would be a piece of cake.

        • If you change your password to a more complex one that you have used elsewhere just for the sake of easy memory, it is not really safe. You should understand that hackers have cheats in their hands, such as password tables, which contain tens of thousands, hundreds of thousands, millions, or even more real leaked passwords.

        1. But you should understand that no hacker really sits in front of a computer and tries your password repeatedly. All attack attempts are carried out automatically by malicious scripts, which work tirelessly for 24 hours. Perhaps while you are sleeping soundly every night, your server is enduring round after round of attacks.

        Once the password is successfully cracked, it means that all four of your elements have been mastered by the attacker. The malicious script will quickly log in to the server, obtain the highest root control of the server, install and deploy its malicious services, and then use your server to do all kinds of bad things 24 hours a day (such as mining, spreading viruses, sending spam emails, fraudulent emails, acting as a BT relay, and even dark web public nodes, and so on). If the malicious script is relatively restrained, it can actually achieve considerable concealment. Generally, newcomers will not observe and pay attention to indicators such as login records, process changes, CPU usage changes, and traffic changes of the VPS, so it is difficult for you to discover that you have been hacked. Until your VPS service provider blocks your account or you receive a lawyer's letter.

        1. Don't forget that when you obtain a VPS, you probably need to use your real payment information, and when you log in to various websites and social platforms, your IP address will also be recorded, which has a direct or indirect relationship with your identity. Therefore, once these bad things happen, they will inevitably be associated with you.

        4.3 What security measures do we need to take

        Based on the above analysis, what we need to do is to strengthen the three elements of [port], [username], and [password] to reduce the risk of being hacked.

        1. [Port]: Modify the SSH remote login port to a [non-22 port] (4.4).
        2. [Username]: Create a [non-root] new user and disable root user SSH remote login (4.5, 4.6).
        3. [Password]: Enable RSA key verification for SSH login and disable password verification login (4.7).

        Remember to follow the order and don't lock yourself out.

        4.4 Change the SSH Remote Login Port to a Non-22 Port

        Now, let's solve the problem of "port = 22". (Note: some VPS service providers have non-22 ports set as default, so you can ignore this step if that's the case. Of course, you can also follow this article to change it to another port.)

        1. Basic commands of Little White Linux:
        IDCommand NameDescription
        cmd-03nanoText editor
        cmd-04systemctl restartRestart a service
        1. Basic Configuration Files of Little White Linux
        NumberConfiguration File LocationFile Description
        conf-01/etc/ssh/sshd_configSSH Remote Login Program Settings
        1. The first thing we need to do, of course, is to [open the SSH remote login program settings with the text editor nano]. In Windows, you will [find the file and double-click] it. What should you do in Linux? Take a close look at the command instructions above, isn't it simple? Yes, it is:
        nano /etc/ssh/sshd_config
         

        This is a command in the shell terminal to open the sshd_config file located in the /etc/ssh/ directory using the nano text editor.

        1. Once the file is opened, you will enter the interface of nano. After observing for a while, you will find that it displays important shortcut keys at the bottom of the screen (enclosed in a red box in the figure below). You can take the exam directly without memorizing them, which is very user-friendly, isn't it?

        Interface of nano

        1. The second thing we need to do is to find the Port item in the opened file and modify its port. The number after Port is the SSH port. It is generally recommended to change it to an integer greater than 1024 and less than 65535 (this article takes 9753 as an example). Please think about how to operate it with the shortcut keys of nano. You are right again! It is:
        • Use ctrl+w to enter search mode, then type Port 22 and press Enter
        • Delete 22 and replace it with 9753
        • Note: If this line starts with #, it means that this line is [commented out] and [does not take effect]. You can write a new line at the end of the file without #, or delete the # to enable this line.

        Warning

        This article uses 9753 as an example, which means that with the release of this article, this port will become a feature that may be prioritized or blocked by attackers or the Great Firewall of China. Therefore, I strongly recommend that you use another port that you come up with yourself, after all, you have over 60,000 ports to choose from freely.

        1. The third thing we need to do is to [save the file and exit].
        • If you observed carefully in step 3, you would have noticed that saving is not done by the common ctrl+s.
        • The correct shortcut keys: save is ctrl+o + enter, and exit is ctrl+x.
        1. The last thing we need to do is to [restart the SSH service to make the changes take effect].
        systemctl restart ssh
         

        This is a shell command to restart the SSH service.

        1. The complete process demonstration is as follows:

        Demonstration of modifying non-22 port

        1. Modify PuTTY Configuration

        "Now that the new port is in effect, you will need to use 9753 the next time you log in with PuTTY. So please go to the PuTTY settings to change the port number and save the session. Well, you should know where to change it, right? (If you don't know, you need to reread the previous content!)"

        4.5 Creating a New User Without Root Access

        In the second step, let's solve the issue of the username being root.

        Firstly, you need to understand that root in Linux system is not just a simple administrator account. It is the foundation of the entire system, the ruler and the supreme god of the system. Once the root account has security issues, the entire system will be vulnerable and there will be nowhere to hide. So, let's follow me to carry out the operations:

        1. Little White Linux Basic Commands:
        NumberCommand NameCommand Description
        cmd-05adduserAdd new user to the system
        cmd-06apt installInstall a software package
        cmd-07visudoSpecial editor to modify sudo permission settings
        1. The first thing we need to do is to [add a new user and set a login password]. You can choose any name you want, here I will use vpsadmin as an example:
        adduser vpsadmin
         

        This is a command in the shell terminal to add a new user named "vpsadmin".

        After executing the command, follow the prompts to operate. Be sure to set a user password (remember that you won't see ****** when setting the password). Afterwards, the system will ask you for some additional user information, which can be ignored by pressing Enter all the way.

        Creating a new user

        Warning

        This article takes "vpsadmin" as an example, which means that with the release of this article, this username will also become a significant feature, and may be the first choice for attackers to try. Therefore, just like ports, I strongly recommend that you use another username that you come up with yourself.

        1. The complete process demonstration is as follows:

        Creating a new user

        1. The second thing we need to do is to install the sudo function (which allows ordinary accounts to temporarily obtain the power of root at critical moments and unleash their full power to save the world).
        apt update && apt install sudo
        diff --git a/assets/ch05-webpage.html-XwVGqU2C.js b/assets/ch05-webpage.html-H5TsNIcu.js
        similarity index 99%
        rename from assets/ch05-webpage.html-XwVGqU2C.js
        rename to assets/ch05-webpage.html-H5TsNIcu.js
        index 8efa881c2b..42d0d9bf65 100644
        --- a/assets/ch05-webpage.html-XwVGqU2C.js
        +++ b/assets/ch05-webpage.html-H5TsNIcu.js
        @@ -1,4 +1,4 @@
        -import{_ as n,o as a,c as s,e as t}from"./app-PDrbPfzp.js";const e="/assets/ch05-img01-nginx-default-running-gZQeEn-L.png",o="/assets/ch05-img02-nginx-conf-full-v03jv5Nl.gif",i="/assets/ch05-img03-nginx-http-running-pMqjJEDb.png",p={},l=t(`

        Chapter 5: Website Building

        5.1 Why should you create a website?

        Some newcomers may be confused: why do I need to build a website for securing an open digital environment? I don't know how to code! Isn't it very complicated?

        First, let's answer the first question. The reasons for building a website are:

        1. Apply for a legitimate TLS certificate (very important)
        2. Provide reasonable fallback to prevent active probing attacks and improve security
        3. Set up a camouflage site (such as a blog, private cloud storage, multimedia site, game site, etc.) with a reasonable frontend when directly accessed, making traffic usage look more legitimate.

        Now let's answer the second question:

        1. As a demonstration, this article uses only the simplest "single-file HTML page + Nginx" setup to achieve the above objectives, so it is very easy.
        2. This website can not only be used for camouflage but also for real development and growth. The complexity depends entirely on you.
        3. For the goals of "camouflage" and "website operation", uniqueness and personalization are needed. Students who need this can search and learn by themselves. This content has completely deviated from scientific online access, so this article will not go into depth.

        5.2 Log in to VPS, install and run Nginx

        1. Here we use commands that have been explained in detail before, so they won't be repeated. If you don't understand, please refer to the previous chapters.

          sudo apt update && sudo apt install nginx
          +import{_ as n,o as a,c as s,e as t}from"./app-UOvWaKji.js";const e="/assets/ch05-img01-nginx-default-running-gZQeEn-L.png",o="/assets/ch05-img02-nginx-conf-full-v03jv5Nl.gif",i="/assets/ch05-img03-nginx-http-running-pMqjJEDb.png",p={},l=t(`

          Chapter 5: Website Building

          5.1 Why should you create a website?

          Some newcomers may be confused: why do I need to build a website for securing an open digital environment? I don't know how to code! Isn't it very complicated?

          First, let's answer the first question. The reasons for building a website are:

          1. Apply for a legitimate TLS certificate (very important)
          2. Provide reasonable fallback to prevent active probing attacks and improve security
          3. Set up a camouflage site (such as a blog, private cloud storage, multimedia site, game site, etc.) with a reasonable frontend when directly accessed, making traffic usage look more legitimate.

          Now let's answer the second question:

          1. As a demonstration, this article uses only the simplest "single-file HTML page + Nginx" setup to achieve the above objectives, so it is very easy.
          2. This website can not only be used for camouflage but also for real development and growth. The complexity depends entirely on you.
          3. For the goals of "camouflage" and "website operation", uniqueness and personalization are needed. Students who need this can search and learn by themselves. This content has completely deviated from scientific online access, so this article will not go into depth.

          5.2 Log in to VPS, install and run Nginx

          1. Here we use commands that have been explained in detail before, so they won't be repeated. If you don't understand, please refer to the previous chapters.

            sudo apt update && sudo apt install nginx
             
          2. After completion, Nginx will automatically run. Open the browser on Windows and enter http://100.200.300.400:80. If you see the interface shown below, it means Nginx is running normally.

            Nginx default interface

          5.3 Create the simplest web page

          1. Basic Linux commands for beginners:

            No.Command NameCommand Description
            cmd-10mkdirCreate a new folder
            cmd-11systemctl reloadReload a specific service
          2. Basic Linux configuration files for beginners:

            No.Configuration File LocationFile Description
            conf-02/etc/nginx/nginx.confNginx program settings
          3. Create a dedicated folder /home/vpsadmin/www/webpage/ for the website and create the web page file index.html

            mkdir -p ~/www/webpage/ && nano ~/www/webpage/index.html
             

          Warning

          If you are not using the username vpsadmin, please be sure to understand the meaning of the "~" symbol in this command (this is related to Step 5 content):

          • If it is a non-root user, "~" is equivalent to /home/username
          • If it is a root user, "~" is equivalent to /root
          1. Copy the entire content below, save (ctrl+o) and exit (ctrl+x).

            <html lang="">
               <!-- Text between angle brackets is an HTML tag and is not displayed.
            diff --git a/assets/ch05-webpage.html-lik4PY0o.js b/assets/ch05-webpage.html-lTr31Joi.js
            similarity index 99%
            rename from assets/ch05-webpage.html-lik4PY0o.js
            rename to assets/ch05-webpage.html-lTr31Joi.js
            index 56bf67c8c8..bce9452a70 100644
            --- a/assets/ch05-webpage.html-lik4PY0o.js
            +++ b/assets/ch05-webpage.html-lTr31Joi.js
            @@ -1,4 +1,4 @@
            -import{_ as n,o as a,c as s,e as t}from"./app-PDrbPfzp.js";const e="/assets/ch05-img01-nginx-default-running-gZQeEn-L.png",p="/assets/ch05-img02-nginx-conf-full-v03jv5Nl.gif",l="/assets/ch05-img03-nginx-http-running-pMqjJEDb.png",c={},i=t(`

            【第 5 章】网站建设篇

            5.1 为什么要做一个网站?

            新人也许会迷惑,为什么科学上网还要建一个网站?我不会编程啊,是不是特别麻烦?

            先回答第一个问题,建网站的原因有:

            1. 申请合法的 TLS 证书(非常重要)
            2. 提供合理的回落,防止主动探测攻击,提高安全性
            3. 建设一个伪装站(如博客、私人网盘、多媒体网站、游戏网站等),直接访问时有合理的前台,使流量使用看上去更合理。

            再回答第二个问题:

            1. 本文作为演示,仅仅使用了一个最简单的【单文件 html 页面 + Nginx】来搭建,以此完成上面的目标,所以【非常简单】
            2. 这个网站完全可以不仅仅是伪装,而是真的做大做强,这个复杂性就完全取决于你了
            3. 对于“伪装”和“网站运营”这个目标,需要的就是各不相同、秀出真我,需要的同学可以自行搜索学习。这个内容已经完全偏离了科学上网,本文就不深入解析了。

            5.2 登录 VPS、安装运行 Nginx

            1. 这里用到的,都是之前已经详解过的命令,所以就不重复讲解了。看不懂的同学可以看看前面的章节哦。

              sudo apt update && sudo apt install nginx
              +import{_ as n,o as a,c as s,e as t}from"./app-UOvWaKji.js";const e="/assets/ch05-img01-nginx-default-running-gZQeEn-L.png",p="/assets/ch05-img02-nginx-conf-full-v03jv5Nl.gif",l="/assets/ch05-img03-nginx-http-running-pMqjJEDb.png",c={},i=t(`

              【第 5 章】网站建设篇

              5.1 为什么要做一个网站?

              新人也许会迷惑,为什么科学上网还要建一个网站?我不会编程啊,是不是特别麻烦?

              先回答第一个问题,建网站的原因有:

              1. 申请合法的 TLS 证书(非常重要)
              2. 提供合理的回落,防止主动探测攻击,提高安全性
              3. 建设一个伪装站(如博客、私人网盘、多媒体网站、游戏网站等),直接访问时有合理的前台,使流量使用看上去更合理。

              再回答第二个问题:

              1. 本文作为演示,仅仅使用了一个最简单的【单文件 html 页面 + Nginx】来搭建,以此完成上面的目标,所以【非常简单】
              2. 这个网站完全可以不仅仅是伪装,而是真的做大做强,这个复杂性就完全取决于你了
              3. 对于“伪装”和“网站运营”这个目标,需要的就是各不相同、秀出真我,需要的同学可以自行搜索学习。这个内容已经完全偏离了科学上网,本文就不深入解析了。

              5.2 登录 VPS、安装运行 Nginx

              1. 这里用到的,都是之前已经详解过的命令,所以就不重复讲解了。看不懂的同学可以看看前面的章节哦。

                sudo apt update && sudo apt install nginx
                 
              2. 完成后,Nginx 已经自动运行。此时打开 Windows 上的浏览器并输入 http://100.200.300.400:80,若看到下图的界面就说明 Nginx 已经正常在运行了。

                Nginx默认界面

              3. 如果无法看到上述Nginx默认页面,可能是需要配置Debian系统上默认的防火墙组件Uncomplicated Firewall (UFW),以便启用 HTTP (80) 和 HTTPS (443) 端口流量。

                a. 验证方法,输入:

                sudo ufw status
                 

                b. 如果输出如下,表明80和433端口未开启,需要执行c步骤

                Status: active
                 To                         Action      From
                diff --git a/assets/ch06-certificates.html-kGI8p0zP.js b/assets/ch06-certificates.html-vKtVQYmc.js
                similarity index 99%
                rename from assets/ch06-certificates.html-kGI8p0zP.js
                rename to assets/ch06-certificates.html-vKtVQYmc.js
                index 7c236403ec..cd3872fb0f 100644
                --- a/assets/ch06-certificates.html-kGI8p0zP.js
                +++ b/assets/ch06-certificates.html-vKtVQYmc.js
                @@ -1,4 +1,4 @@
                -import{_ as t,r as i,o,c,a as n,b as s,d as p,e as a}from"./app-PDrbPfzp.js";const l="/assets/ch06-img01-acme-install-6MHbN7VN.gif",r={},d=a('

                [Chapter 6] Certificate Management

                6.1 Applying for a TLS Certificate

                Next, we need to apply for a real TLS certificate for our domain name, so that the website has the ability to encrypt with standard TLS and the ability to access via HTTPS. This is the most important tool for Xray and other current security proxy tools to ensure fully encrypted traffic.

                Warning

                Please do not use self-signed certificates lightly. It does not make the operation much simpler, but adds unnecessary risks (such as man-in-the-middle attacks).

                ',4),u={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},m=n("code",null,"acme.sh",-1),b=a(`

                In addition, I believe that you have gradually become familiar with the basic operations of Linux. Therefore, from this chapter on, commands that have appeared multiple times will no longer have screenshots and will only be briefly described. If you really can't remember how to use them, just review the previous chapters.

                6.2 Install acme.sh

                1. Basic Linux commands for beginners:

                  NumberCommandDescription
                  cmd-12wgetRetrieve (or download) a webpage file
                  cmd-13acme.shCommands related to acme.sh certificate management
                2. Run the installation script.

                wget -O - https://get.acme.sh | sh
                +import{_ as t,r as i,o,c,a as n,b as s,d as p,e as a}from"./app-UOvWaKji.js";const l="/assets/ch06-img01-acme-install-6MHbN7VN.gif",r={},d=a('

                [Chapter 6] Certificate Management

                6.1 Applying for a TLS Certificate

                Next, we need to apply for a real TLS certificate for our domain name, so that the website has the ability to encrypt with standard TLS and the ability to access via HTTPS. This is the most important tool for Xray and other current security proxy tools to ensure fully encrypted traffic.

                Warning

                Please do not use self-signed certificates lightly. It does not make the operation much simpler, but adds unnecessary risks (such as man-in-the-middle attacks).

                ',4),u={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},m=n("code",null,"acme.sh",-1),b=a(`

                In addition, I believe that you have gradually become familiar with the basic operations of Linux. Therefore, from this chapter on, commands that have appeared multiple times will no longer have screenshots and will only be briefly described. If you really can't remember how to use them, just review the previous chapters.

                6.2 Install acme.sh

                1. Basic Linux commands for beginners:

                  NumberCommandDescription
                  cmd-12wgetRetrieve (or download) a webpage file
                  cmd-13acme.shCommands related to acme.sh certificate management
                2. Run the installation script.

                wget -O - https://get.acme.sh | sh
                 
                1. Make the acme.sh command effective.
                . .bashrc
                 

                (Note: This command is used to source (load) the .bashrc file in the shell environment.)

                1. Enable acme.sh automatic upgrade.
                acme.sh --upgrade --auto-upgrade
                 
                1. The complete process up to this point is shown in the following diagram:

                acme.sh installation demo

                6.3 Testing Certificate Application

                Before officially applying for the certificate, we use the testing command (--issue --test) to verify if the application can be successfully submitted. This can avoid repeated failures in applying for a certificate due to incorrect local configuration, exceeding the frequency limit of Let's Encrypt (such as a maximum of 5 failures per hour, per domain, or per user), which may prevent the subsequent steps from being carried out.

                1. The command to apply for a test certificate is as follows (this article uses ECC certificate as an example, because there is really no reason not to use it nowadays):
                acme.sh --issue --server letsencrypt --test -d subdomain.yourdomain.com -w /home/vpsadmin/www/webpage --keylength ec-256
                diff --git a/assets/ch06-certificates.html-3Wj6Kppi.js b/assets/ch06-certificates.html-vz4TPMTq.js
                similarity index 99%
                rename from assets/ch06-certificates.html-3Wj6Kppi.js
                rename to assets/ch06-certificates.html-vz4TPMTq.js
                index 15642f5158..ca7d07e102 100644
                --- a/assets/ch06-certificates.html-3Wj6Kppi.js
                +++ b/assets/ch06-certificates.html-vz4TPMTq.js
                @@ -1,4 +1,4 @@
                -import{_ as t,r as p,o as c,c as i,a as n,b as s,d as l,e as a}from"./app-PDrbPfzp.js";const o="/assets/ch06-img01-acme-install-6MHbN7VN.gif",r={},d=a('

                【第 6 章】证书管理篇

                6.1 申请 TLS 证书

                接下来我们要做的,是为我们的域名申请一个真实的 TLS 证书,使网站具备标准 TLS 加密的能力及 HTTPS 访问的能力。这就是 Xray 等现阶段安全代理工具确保流量充分加密最重要的工具。

                注意

                请不要轻易使用自签证书。它并没有让操作简单太多,但增加了无谓的风险(如中间人攻击)。

                ',4),u={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},m=n("code",null,"acme.sh",-1),k=a(`

                另外,我相信,现在你已经逐渐熟悉了 Linux 的基础操作,所以已经多次出现的命令从本章开始不再重复截图、只做简单的描述。如果实在想不起来怎么用的话,就稍微复习一下前面的章节吧。

                6.2 安装 acme.sh

                1. 小小白白 Linux 基础命令:

                  编号命令名称命令说明
                  cmd-12wget访问(或下载)某个网页文件
                  cmd-13acme.shacme.sh 证书管理相关的命令
                2. 运行安装脚本

                  wget -O -  https://get.acme.sh | sh
                  +import{_ as t,r as p,o as c,c as i,a as n,b as s,d as l,e as a}from"./app-UOvWaKji.js";const o="/assets/ch06-img01-acme-install-6MHbN7VN.gif",r={},d=a('

                  【第 6 章】证书管理篇

                  6.1 申请 TLS 证书

                  接下来我们要做的,是为我们的域名申请一个真实的 TLS 证书,使网站具备标准 TLS 加密的能力及 HTTPS 访问的能力。这就是 Xray 等现阶段安全代理工具确保流量充分加密最重要的工具。

                  注意

                  请不要轻易使用自签证书。它并没有让操作简单太多,但增加了无谓的风险(如中间人攻击)。

                  ',4),u={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},m=n("code",null,"acme.sh",-1),k=a(`

                  另外,我相信,现在你已经逐渐熟悉了 Linux 的基础操作,所以已经多次出现的命令从本章开始不再重复截图、只做简单的描述。如果实在想不起来怎么用的话,就稍微复习一下前面的章节吧。

                  6.2 安装 acme.sh

                  1. 小小白白 Linux 基础命令:

                    编号命令名称命令说明
                    cmd-12wget访问(或下载)某个网页文件
                    cmd-13acme.shacme.sh 证书管理相关的命令
                  2. 运行安装脚本

                    wget -O -  https://get.acme.sh | sh
                     
                  3. acme.sh 命令生效

                    . .bashrc
                     
                  4. 开启 acme.sh 的自动升级

                    acme.sh --upgrade --auto-upgrade
                     
                  5. 到这一步的完整流程如下图:

                    acme.sh安装演示

                  6.3 测试证书申请

                  在正式申请证书之前,我们先用测试命令(--issue --test)来验证是否可以成功申请,这样可以避免在本地配置有误时,反复申请证书失败,超过 Let's Encrypt 的频率上限(比如,每小时、每个域名、每个用户失败最多 5 次),导致后面的步骤无法进行。

                  1. 测试证书申请的命令如下(本文均以 ECC 证书为例,因为时至今日,实在没什么理由不用它):

                    acme.sh --issue --server letsencrypt --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256
                    diff --git a/assets/ch07-xray-server.html-vH8VA1RO.js b/assets/ch07-xray-server.html-M88Oyw5u.js
                    similarity index 99%
                    rename from assets/ch07-xray-server.html-vH8VA1RO.js
                    rename to assets/ch07-xray-server.html-M88Oyw5u.js
                    index e84372d3bc..51880c4174 100644
                    --- a/assets/ch07-xray-server.html-vH8VA1RO.js
                    +++ b/assets/ch07-xray-server.html-M88Oyw5u.js
                    @@ -1,4 +1,4 @@
                    -import{_ as i,r as o,o as c,c as d,a as s,b as n,d as e,w as p,e as a}from"./app-PDrbPfzp.js";const r="/assets/ch07-img01-xray-install-OkVIrYZ6.gif",u="/assets/ch07-img02-xray-cert-install-cipxwXde.png",v="/assets/ch07-img03-crontab-cert-renew-f3cEi7YH.gif",m="/assets/ch07-img04-xray-log-and-config-T-XHGfJD.gif",b="/assets/ch07-img05-xray-start-and-status-pesim605.gif",h="/assets/ch07-img06-bbr-proper-ac36RTK5.gif",g="/assets/ch07-img07-http-to-https-EGCHHf4D.gif",k="/assets/ch07-img08-http-to-https-check-5driAI71.png",y={},x=a('

                    【第 7 章】Xray 服务器篇

                    7.1 博观而约取,厚积而薄发

                    本文撰写过程中,大佬开玩笑的吐槽到:你这教程,居然连载了 6 章都还没到 Xray,不知道的还以为你是“手把手教你建网站”教程呢。(我竟无法反驳.jpg!)

                    其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连nano都无法正确使用,也不会用WinSCP,远程手写编辑出来的config.json自然错误百出,连查错也变得举步维艰。

                    Warning

                    经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray 时会有一种【水到渠成】的轻快感觉。

                    后面要做的事情非常简单:

                    1. 安装
                    2. 配置(如安装 TLS 证书、config.json
                    3. 运行
                    4. 优化(如更新内核、开启bbr、网站http访问自动跳转https等)

                    7.2 安装 Xray

                    ',8),q={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},_=s("code",null,"MPL 2.0",-1),f={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},X=s("strong",null,"本文使用的是【非 root 用户】安装模式",-1),B=a(`

                    写本文时,安装脚本在使用非 root 账户时有一些小 bug,所以我决定正好把这几步分开操作,可以顺便说明一下 Linux 下的删除命令。

                    1. 小小白白 Linux 基础命令:

                      编号命令名称命令说明
                      cmd-14rm删除命令
                    2. 将安装脚本下载至本地:

                      wget https://github.com/XTLS/Xray-install/raw/main/install-release.sh
                      +import{_ as i,r as o,o as c,c as d,a as s,b as n,d as e,w as p,e as a}from"./app-UOvWaKji.js";const r="/assets/ch07-img01-xray-install-OkVIrYZ6.gif",u="/assets/ch07-img02-xray-cert-install-cipxwXde.png",v="/assets/ch07-img03-crontab-cert-renew-f3cEi7YH.gif",m="/assets/ch07-img04-xray-log-and-config-T-XHGfJD.gif",b="/assets/ch07-img05-xray-start-and-status-pesim605.gif",h="/assets/ch07-img06-bbr-proper-ac36RTK5.gif",g="/assets/ch07-img07-http-to-https-EGCHHf4D.gif",k="/assets/ch07-img08-http-to-https-check-5driAI71.png",y={},x=a('

                      【第 7 章】Xray 服务器篇

                      7.1 博观而约取,厚积而薄发

                      本文撰写过程中,大佬开玩笑的吐槽到:你这教程,居然连载了 6 章都还没到 Xray,不知道的还以为你是“手把手教你建网站”教程呢。(我竟无法反驳.jpg!)

                      其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连nano都无法正确使用,也不会用WinSCP,远程手写编辑出来的config.json自然错误百出,连查错也变得举步维艰。

                      Warning

                      经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray 时会有一种【水到渠成】的轻快感觉。

                      后面要做的事情非常简单:

                      1. 安装
                      2. 配置(如安装 TLS 证书、config.json
                      3. 运行
                      4. 优化(如更新内核、开启bbr、网站http访问自动跳转https等)

                      7.2 安装 Xray

                      ',8),q={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},_=s("code",null,"MPL 2.0",-1),f={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},X=s("strong",null,"本文使用的是【非 root 用户】安装模式",-1),B=a(`

                      写本文时,安装脚本在使用非 root 账户时有一些小 bug,所以我决定正好把这几步分开操作,可以顺便说明一下 Linux 下的删除命令。

                      1. 小小白白 Linux 基础命令:

                        编号命令名称命令说明
                        cmd-14rm删除命令
                      2. 将安装脚本下载至本地:

                        wget https://github.com/XTLS/Xray-install/raw/main/install-release.sh
                         
                      3. 执行安装命令

                        sudo bash install-release.sh
                         
                      4. 使用完成之后可以删除该脚本

                        rm ~/install-release.sh
                         

                        Warning

                        使用 rm 命令删除文件的时候,默认其实就是删除现在所在的文件夹下的文件。但是,我依然写了完整的路径~/install-release.sh,这是我使用 rm 时的一个安全习惯、也是我把安装分成几步之后想强调一下的内容。如果你听过一些“程序员从删库到跑路”之类的段子,大概就知道为什么了。

                      5. 完整流程演示如下:

                        Xray服务器端安装流程演示

                      7.3 给 Xray 配置 TLS 证书

                      ',3),w={href:"https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E#3-copy%E5%AE%89%E8%A3%85-%E8%AF%81%E4%B9%A6",target:"_blank",rel:"noopener noreferrer"},S=s("code",null,"acme.sh",-1),L=s("code",null,"--install-cert",-1),R=s("code",null,"xray-core",-1),T=a(`
                    3. 为了规避非 root 账户的各种潜在的权限困扰,我们在 vpsadmin 账户下建立一个证书文件夹

                      mkdir ~/xray_cert
                      diff --git a/assets/ch07-xray-server.html-Cs4sLfUv.js b/assets/ch07-xray-server.html-TVGmVR8g.js
                      similarity index 99%
                      rename from assets/ch07-xray-server.html-Cs4sLfUv.js
                      rename to assets/ch07-xray-server.html-TVGmVR8g.js
                      index b8771db066..8ead085050 100644
                      --- a/assets/ch07-xray-server.html-Cs4sLfUv.js
                      +++ b/assets/ch07-xray-server.html-TVGmVR8g.js
                      @@ -1,4 +1,4 @@
                      -import{_ as i,r as o,o as c,c as d,a as s,b as n,d as e,w as p,e as a}from"./app-PDrbPfzp.js";const r="/assets/ch07-img01-xray-install-OkVIrYZ6.gif",u="/assets/ch07-img02-xray-cert-install-cipxwXde.png",v="/assets/ch07-img03-crontab-cert-renew-f3cEi7YH.gif",m="/assets/ch07-img04-xray-log-and-config-T-XHGfJD.gif",b="/assets/ch07-img05-xray-start-and-status-pesim605.gif",h="/assets/ch07-img06-bbr-proper-ac36RTK5.gif",g="/assets/ch07-img07-http-to-https-EGCHHf4D.gif",k="/assets/ch07-img08-http-to-https-check-5driAI71.png",y={},x=a('

                      【第 7 章】Xray 服务器篇

                      7.1 博观而约取,厚积而薄发

                      本文撰写过程中,大佬开玩笑的吐槽到:你这教程,居然连载了 6 章都还没到 Xray,不知道的还以为你是“手把手教你建网站”教程呢。(我竟无法反驳.jpg!)

                      其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连nano都无法正确使用,也不会用WinSCP,远程手写编辑出来的config.json自然错误百出,连查错也变得举步维艰。

                      注意

                      经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray 时会有一种【水到渠成】的轻快感觉。

                      后面要做的事情非常简单:

                      1. 安装
                      2. 配置(如安装 TLS 证书、config.json
                      3. 运行
                      4. 优化(如更新内核、开启bbr、网站http访问自动跳转https等)

                      7.2 安装 Xray

                      ',8),q={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},_=s("code",null,"MPL 2.0",-1),f={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},X=s("strong",null,"本文使用的是【非 root 用户】安装模式",-1),B=a(`

                      写本文时,安装脚本在使用非 root 账户时有一些小 bug,所以我决定正好把这几步分开操作,可以顺便说明一下 Linux 下的删除命令。

                      1. 小小白白 Linux 基础命令:

                        编号命令名称命令说明
                        cmd-14rm删除命令
                      2. 将安装脚本下载至本地:

                        wget https://github.com/XTLS/Xray-install/raw/main/install-release.sh
                        +import{_ as i,r as o,o as c,c as d,a as s,b as n,d as e,w as p,e as a}from"./app-UOvWaKji.js";const r="/assets/ch07-img01-xray-install-OkVIrYZ6.gif",u="/assets/ch07-img02-xray-cert-install-cipxwXde.png",v="/assets/ch07-img03-crontab-cert-renew-f3cEi7YH.gif",m="/assets/ch07-img04-xray-log-and-config-T-XHGfJD.gif",b="/assets/ch07-img05-xray-start-and-status-pesim605.gif",h="/assets/ch07-img06-bbr-proper-ac36RTK5.gif",g="/assets/ch07-img07-http-to-https-EGCHHf4D.gif",k="/assets/ch07-img08-http-to-https-check-5driAI71.png",y={},x=a('

                        【第 7 章】Xray 服务器篇

                        7.1 博观而约取,厚积而薄发

                        本文撰写过程中,大佬开玩笑的吐槽到:你这教程,居然连载了 6 章都还没到 Xray,不知道的还以为你是“手把手教你建网站”教程呢。(我竟无法反驳.jpg!)

                        其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连nano都无法正确使用,也不会用WinSCP,远程手写编辑出来的config.json自然错误百出,连查错也变得举步维艰。

                        注意

                        经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray 时会有一种【水到渠成】的轻快感觉。

                        后面要做的事情非常简单:

                        1. 安装
                        2. 配置(如安装 TLS 证书、config.json
                        3. 运行
                        4. 优化(如更新内核、开启bbr、网站http访问自动跳转https等)

                        7.2 安装 Xray

                        ',8),q={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},_=s("code",null,"MPL 2.0",-1),f={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},X=s("strong",null,"本文使用的是【非 root 用户】安装模式",-1),B=a(`

                        写本文时,安装脚本在使用非 root 账户时有一些小 bug,所以我决定正好把这几步分开操作,可以顺便说明一下 Linux 下的删除命令。

                        1. 小小白白 Linux 基础命令:

                          编号命令名称命令说明
                          cmd-14rm删除命令
                        2. 将安装脚本下载至本地:

                          wget https://github.com/XTLS/Xray-install/raw/main/install-release.sh
                           
                        3. 执行安装命令

                          sudo bash install-release.sh
                           
                        4. 使用完成之后可以删除该脚本

                          rm ~/install-release.sh
                           

                          注意

                          使用 rm 命令删除文件的时候,默认其实就是删除现在所在的文件夹下的文件。但是,我依然写了完整的路径~/install-release.sh,这是我使用 rm 时的一个安全习惯、也是我把安装分成几步之后想强调一下的内容。如果你听过一些“程序员从删库到跑路”之类的段子,大概就知道为什么了。

                        5. 完整流程演示如下:

                          Xray服务器端安装流程演示

                        7.3 给 Xray 配置 TLS 证书

                        ',3),w={href:"https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E#3-copy%E5%AE%89%E8%A3%85-%E8%AF%81%E4%B9%A6",target:"_blank",rel:"noopener noreferrer"},S=s("code",null,"acme.sh",-1),L=s("code",null,"--install-cert",-1),R=s("code",null,"xray-core",-1),T=a(`
                      3. 为了规避非 root 账户的各种潜在的权限困扰,我们在 vpsadmin 账户下建立一个证书文件夹

                        mkdir ~/xray_cert
                        diff --git a/assets/ch08-xray-clients.html-6ijP-wsT.js b/assets/ch08-xray-clients.html-VmriEsh2.js
                        similarity index 99%
                        rename from assets/ch08-xray-clients.html-6ijP-wsT.js
                        rename to assets/ch08-xray-clients.html-VmriEsh2.js
                        index 57ae42868d..d5b8d66df1 100644
                        --- a/assets/ch08-xray-clients.html-6ijP-wsT.js
                        +++ b/assets/ch08-xray-clients.html-VmriEsh2.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as p,o as i,c as u,a as n,b as s,d as a,w as l,e as t}from"./app-PDrbPfzp.js";const r="/assets/ch08-img01-flow-Nus5m8Xg.png",d="/assets/ch08-img02-buzz-BMkpbZbZ.png",k={},v=t('

                        【第 8 章】Xray 客户端篇

                        8.1 Xray 的工作原理简述

                        要正确的配置和使用Xray,就需要正确的理解其工作原理,对于新人,可以先看看下面简化的示意图(省略了许多复杂的设置):

                        Xray数据流向

                        这其中的关键点是:

                        1. APP 要主动或借助转发工具,将数据【流入(inbounds)】Xray 客户端

                        2. 流量进入客户端后,会被【客户端路由(routing)】按规则处理后,向不同方向【流出(outbounds)Xray 客户端。比如:

                          1. 国内流量直连(direct
                          2. 国外流量转发 VPS(proxy
                          3. 广告流量屏蔽(block
                        3. 向 VPS 转发的国外流量,会跨过防火墙,【流入(inbounds)】 Xray 服务器端

                        4. 流量进入服务器端后,与客户端一样,会被【服务器端路由(routing)】按规则处理后,向不同方向【流出(outbounds)】:

                          1. 因为已经在防火墙之外,所以流量默认直连,你就可以访问到不存在网站们了(direct
                          2. 如果需要在不同的 VPS 之间做链式转发,就可以继续配置转发规则(proxy
                          3. 你可以在服务器端继续禁用各种你想禁用的流量,如广告、BT 下载等(block
                        ',6),m={class:"custom-container warning"},q=n("p",{class:"custom-container-title"},"注意",-1),b=n("p",null,[s("请务必记得,"),n("code",null,"Xray"),s(" 的路由配置非常灵活,上面的说明只是无限可能性中的一种。")],-1),g=n("p",null,[s("借助 "),n("code",null,"geosite.dat"),s(" 和 "),n("code",null,"geoip.dat"),s(" 这两个文件,可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 "),n("code",null,"GFWList"),s(" 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)")],-1),y=n("h2",{id:"_8-2-客户端与服务器端正确连接",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_8-2-客户端与服务器端正确连接"},[n("span",null,"8.2 客户端与服务器端正确连接")])],-1),h=n("p",null,[s("现在你已经理解了 "),n("code",null,"Xray"),s(" 的工作原理,那么接下来的配置,其实就是【告诉你的客户端如何连接 VPS 服务器】。这和你已经很熟悉的、告诉"),n("code",null,"PuTTY"),s("如何远程连接服务器是一样的。只不过 Xray 连接时的要素不止是【IP 地址】+【端口】+【用户名】+【密码】这四要素了。")],-1),_=n("code",null,"Xray",-1),x=n("code",null,"config.json",-1),f=n("code",null,"Xray",-1),S=n("code",null,"VLESS",-1),X=n("code",null,"XTLS",-1),N=t('
                        • 服务器【地址】: a-name.yourdomain.com
                        • 服务器【端口】: 443
                        • 连接的【协议】: vless
                        • 连接的【流控】: xtls-rprx-vision (vision 模式适合全平台)
                        • 连接的【验证】: uuiduuid-uuid-uuid-uuiduuiduuid
                        • 连接的【安全】: "allowInsecure": false

                        鉴于新人一般都会使用手机 APP 或者电脑的 GUI 客户端,我就把常用的客户端罗列在下面。每个客户端都有自己独特的配置界面,逐一截图展示并不现实,所以请你务必仔细阅读这些客户端的说明、然后把上述要素填入合适的地方即可。

                        注意

                        许多工具其实是同时支持 xray-corev2fly-core 的,但默认内置的不一定是哪个,所以别忘记检查一下是否是你想要的那个在工作哦!

                        ',3),P=n("p",null,[n("strong",null,"v2rayN - 适用于 Windows 平台")],-1),w={href:"https://github.com/2dust/v2rayN/releases",target:"_blank",rel:"noopener noreferrer"},I=n("li",null,"请根据该客户端的说明进行设置",-1),T=n("p",null,[n("strong",null,"v2rayNG - 适用于 Android 平台")],-1),L={href:"https://github.com/2dust/v2rayNG/releases",target:"_blank",rel:"noopener noreferrer"},V=n("li",null,"请根据该客户端的说明进行设置",-1),C=n("li",null,[n("p",null,[n("strong",null,"Shadowrocket - 适用于 iOS, 基于苹果 M 芯片的 macOS")]),n("ul",null,[n("li",null,"你需要注册一个【非中国区】的 iCloud 账户"),n("li",null,"你需要通过 App Store 搜索并购买"),n("li",null,"请根据该客户端的说明进行设置")])],-1),D=n("p",null,[n("strong",null,"Qv2ray - 跨平台图形界面,适用于 Linux, Windows, macOS")],-1),j={href:"https://github.com/Qv2ray/Qv2ray/releases",target:"_blank",rel:"noopener noreferrer"},E={href:"https://github.com/Qv2ray/Qv2ray/actions",target:"_blank",rel:"noopener noreferrer"},G={href:"https://qv2ray.net/",target:"_blank",rel:"noopener noreferrer"},A=n("li",null,"请根据该客户端的说明进行设置",-1),O=n("p",null,[n("strong",null,"V2RayXS - 基于 V2RayX 开发的一款使用 xray-core 的 macOS 客户端")],-1),R={href:"https://github.com/tzmax/v2rayXS/releases",target:"_blank",rel:"noopener noreferrer"},B={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},H=n("li",null,"请根据该客户端的说明进行设置",-1),Q=t('

                        到这一步,你的全套配置就已经可以正常使用啦!

                        8.3 附加题 1:在 PC 端手工配置 xray-core

                        虽然到上面一步已经可以结束了,但是如果你是个好奇心强、记忆力好的的同学,一定会想起来我在上一章说过,你把xray-core 的二进制文件“放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。” 那究竟要怎样直接使用 xray-core 做客户端呢?

                        为了回答这个问题,我加入了附加题章节,有一点点超纲,有一点点麻烦,但费这个笔墨是因为这个方式有它的优势:

                        • 第一时间获得最新版而无需等待 APP 升级适配

                        • 灵活自由的路由配置能力(当然 GUI 客户端中 Qv2ray 的高级路由编辑器非常强大,也可以完整实现 xray-core 的路由配置功能)

                        • 节约系统资源 (GUI 界面一定会有资源消耗,消耗的多少则取决于客户端的实现)

                        它的劣势应该就是【需要手写配置文件】有点麻烦了。但其实,你想想,服务器上你已经成功的写过一次了,现在又有什么区别呢?接下来,还是老样子,我们分解一下步骤:

                        ',6),W={href:"https://github.com/XTLS/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},F=t(`
                      4. 在合适的文件夹建立空白配置文件:config.json (自己常用平台下新建文件大家肯定都会,这就真不用啰嗦了)

                      5. 至于什么是“合适的文件夹”?这就取决于具体的平台了~

                      6. 填写客户端配置

                        • 我就以 8.1 原理说明里展示的基本三类分流(国内流量直连、国际流量转发 VPS、广告流量屏蔽),结合 8.2 的连接要素,写成一个配置文件
                        • 请将 uuid 替换成与你服务器一致的 uuid
                        • 请将 address 替换成你的真实域名
                        • 请将 serverName 替换成你的真实域名
                        • 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
                        // REFERENCE:
                        +import{_ as c,r as p,o as i,c as u,a as n,b as s,d as a,w as l,e as t}from"./app-UOvWaKji.js";const r="/assets/ch08-img01-flow-Nus5m8Xg.png",d="/assets/ch08-img02-buzz-BMkpbZbZ.png",k={},v=t('

                        【第 8 章】Xray 客户端篇

                        8.1 Xray 的工作原理简述

                        要正确的配置和使用Xray,就需要正确的理解其工作原理,对于新人,可以先看看下面简化的示意图(省略了许多复杂的设置):

                        Xray数据流向

                        这其中的关键点是:

                        1. APP 要主动或借助转发工具,将数据【流入(inbounds)】Xray 客户端

                        2. 流量进入客户端后,会被【客户端路由(routing)】按规则处理后,向不同方向【流出(outbounds)Xray 客户端。比如:

                          1. 国内流量直连(direct
                          2. 国外流量转发 VPS(proxy
                          3. 广告流量屏蔽(block
                        3. 向 VPS 转发的国外流量,会跨过防火墙,【流入(inbounds)】 Xray 服务器端

                        4. 流量进入服务器端后,与客户端一样,会被【服务器端路由(routing)】按规则处理后,向不同方向【流出(outbounds)】:

                          1. 因为已经在防火墙之外,所以流量默认直连,你就可以访问到不存在网站们了(direct
                          2. 如果需要在不同的 VPS 之间做链式转发,就可以继续配置转发规则(proxy
                          3. 你可以在服务器端继续禁用各种你想禁用的流量,如广告、BT 下载等(block
                        ',6),m={class:"custom-container warning"},q=n("p",{class:"custom-container-title"},"注意",-1),b=n("p",null,[s("请务必记得,"),n("code",null,"Xray"),s(" 的路由配置非常灵活,上面的说明只是无限可能性中的一种。")],-1),g=n("p",null,[s("借助 "),n("code",null,"geosite.dat"),s(" 和 "),n("code",null,"geoip.dat"),s(" 这两个文件,可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 "),n("code",null,"GFWList"),s(" 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)")],-1),y=n("h2",{id:"_8-2-客户端与服务器端正确连接",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_8-2-客户端与服务器端正确连接"},[n("span",null,"8.2 客户端与服务器端正确连接")])],-1),h=n("p",null,[s("现在你已经理解了 "),n("code",null,"Xray"),s(" 的工作原理,那么接下来的配置,其实就是【告诉你的客户端如何连接 VPS 服务器】。这和你已经很熟悉的、告诉"),n("code",null,"PuTTY"),s("如何远程连接服务器是一样的。只不过 Xray 连接时的要素不止是【IP 地址】+【端口】+【用户名】+【密码】这四要素了。")],-1),_=n("code",null,"Xray",-1),x=n("code",null,"config.json",-1),f=n("code",null,"Xray",-1),S=n("code",null,"VLESS",-1),X=n("code",null,"XTLS",-1),N=t('
                        • 服务器【地址】: a-name.yourdomain.com
                        • 服务器【端口】: 443
                        • 连接的【协议】: vless
                        • 连接的【流控】: xtls-rprx-vision (vision 模式适合全平台)
                        • 连接的【验证】: uuiduuid-uuid-uuid-uuiduuiduuid
                        • 连接的【安全】: "allowInsecure": false

                        鉴于新人一般都会使用手机 APP 或者电脑的 GUI 客户端,我就把常用的客户端罗列在下面。每个客户端都有自己独特的配置界面,逐一截图展示并不现实,所以请你务必仔细阅读这些客户端的说明、然后把上述要素填入合适的地方即可。

                        注意

                        许多工具其实是同时支持 xray-corev2fly-core 的,但默认内置的不一定是哪个,所以别忘记检查一下是否是你想要的那个在工作哦!

                        ',3),P=n("p",null,[n("strong",null,"v2rayN - 适用于 Windows 平台")],-1),w={href:"https://github.com/2dust/v2rayN/releases",target:"_blank",rel:"noopener noreferrer"},I=n("li",null,"请根据该客户端的说明进行设置",-1),T=n("p",null,[n("strong",null,"v2rayNG - 适用于 Android 平台")],-1),L={href:"https://github.com/2dust/v2rayNG/releases",target:"_blank",rel:"noopener noreferrer"},V=n("li",null,"请根据该客户端的说明进行设置",-1),C=n("li",null,[n("p",null,[n("strong",null,"Shadowrocket - 适用于 iOS, 基于苹果 M 芯片的 macOS")]),n("ul",null,[n("li",null,"你需要注册一个【非中国区】的 iCloud 账户"),n("li",null,"你需要通过 App Store 搜索并购买"),n("li",null,"请根据该客户端的说明进行设置")])],-1),D=n("p",null,[n("strong",null,"Qv2ray - 跨平台图形界面,适用于 Linux, Windows, macOS")],-1),j={href:"https://github.com/Qv2ray/Qv2ray/releases",target:"_blank",rel:"noopener noreferrer"},E={href:"https://github.com/Qv2ray/Qv2ray/actions",target:"_blank",rel:"noopener noreferrer"},G={href:"https://qv2ray.net/",target:"_blank",rel:"noopener noreferrer"},A=n("li",null,"请根据该客户端的说明进行设置",-1),O=n("p",null,[n("strong",null,"V2RayXS - 基于 V2RayX 开发的一款使用 xray-core 的 macOS 客户端")],-1),R={href:"https://github.com/tzmax/v2rayXS/releases",target:"_blank",rel:"noopener noreferrer"},B={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},H=n("li",null,"请根据该客户端的说明进行设置",-1),Q=t('

                        到这一步,你的全套配置就已经可以正常使用啦!

                        8.3 附加题 1:在 PC 端手工配置 xray-core

                        虽然到上面一步已经可以结束了,但是如果你是个好奇心强、记忆力好的的同学,一定会想起来我在上一章说过,你把xray-core 的二进制文件“放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。” 那究竟要怎样直接使用 xray-core 做客户端呢?

                        为了回答这个问题,我加入了附加题章节,有一点点超纲,有一点点麻烦,但费这个笔墨是因为这个方式有它的优势:

                        • 第一时间获得最新版而无需等待 APP 升级适配

                        • 灵活自由的路由配置能力(当然 GUI 客户端中 Qv2ray 的高级路由编辑器非常强大,也可以完整实现 xray-core 的路由配置功能)

                        • 节约系统资源 (GUI 界面一定会有资源消耗,消耗的多少则取决于客户端的实现)

                        它的劣势应该就是【需要手写配置文件】有点麻烦了。但其实,你想想,服务器上你已经成功的写过一次了,现在又有什么区别呢?接下来,还是老样子,我们分解一下步骤:

                        ',6),W={href:"https://github.com/XTLS/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},F=t(`
                      7. 在合适的文件夹建立空白配置文件:config.json (自己常用平台下新建文件大家肯定都会,这就真不用啰嗦了)

                      8. 至于什么是“合适的文件夹”?这就取决于具体的平台了~

                      9. 填写客户端配置

                        • 我就以 8.1 原理说明里展示的基本三类分流(国内流量直连、国际流量转发 VPS、广告流量屏蔽),结合 8.2 的连接要素,写成一个配置文件
                        • 请将 uuid 替换成与你服务器一致的 uuid
                        • 请将 address 替换成你的真实域名
                        • 请将 serverName 替换成你的真实域名
                        • 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
                        // REFERENCE:
                         // https://github.com/XTLS/Xray-examples
                         // https://xtls.github.io/config/
                         
                        diff --git a/assets/ch08-xray-clients.html-w9IqqavR.js b/assets/ch08-xray-clients.html-s9iITOvA.js
                        similarity index 99%
                        rename from assets/ch08-xray-clients.html-w9IqqavR.js
                        rename to assets/ch08-xray-clients.html-s9iITOvA.js
                        index 5fa315092a..d3577f8b6a 100644
                        --- a/assets/ch08-xray-clients.html-w9IqqavR.js
                        +++ b/assets/ch08-xray-clients.html-s9iITOvA.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as p,o as i,c as u,a as n,b as s,d as a,w as l,e as t}from"./app-PDrbPfzp.js";const r="/assets/ch08-img01-flow-Nus5m8Xg.png",d="/assets/ch08-img02-buzz-BMkpbZbZ.png",k={},v=t('

                        【第 8 章】Xray 客户端篇

                        8.1 Xray 的工作原理简述

                        要正确的配置和使用Xray,就需要正确的理解其工作原理,对于新人,可以先看看下面简化的示意图(省略了许多复杂的设置):

                        Xray数据流向

                        这其中的关键点是:

                        1. APP 要主动或借助转发工具,将数据【流入(inbounds)】Xray 客户端

                        2. 流量进入客户端后,会被【客户端路由(routing)】按规则处理后,向不同方向【流出(outbounds)Xray 客户端。比如:

                          1. 国内流量直连(direct
                          2. 国外流量转发 VPS(proxy
                          3. 广告流量屏蔽(block
                        3. 向 VPS 转发的国外流量,会跨过防火墙,【流入(inbounds)】 Xray 服务器端

                        4. 流量进入服务器端后,与客户端一样,会被【服务器端路由(routing)】按规则处理后,向不同方向【流出(outbounds)】:

                          1. 因为已经在防火墙之外,所以流量默认直连,你就可以访问到不存在网站们了(direct
                          2. 如果需要在不同的 VPS 之间做链式转发,就可以继续配置转发规则(proxy
                          3. 你可以在服务器端继续禁用各种你想禁用的流量,如广告、BT 下载等(block
                        ',6),m={class:"custom-container warning"},q=n("p",{class:"custom-container-title"},"注意",-1),b=n("p",null,[s("请务必记得,"),n("code",null,"Xray"),s(" 的路由配置非常灵活,上面的说明只是无限可能性中的一种。")],-1),g=n("p",null,[s("借助 "),n("code",null,"geosite.dat"),s(" 和 "),n("code",null,"geoip.dat"),s(" 这两个文件,可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 "),n("code",null,"GFWList"),s(" 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)")],-1),y=n("h2",{id:"_8-2-客户端与服务器端正确连接",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_8-2-客户端与服务器端正确连接"},[n("span",null,"8.2 客户端与服务器端正确连接")])],-1),h=n("p",null,[s("现在你已经理解了 "),n("code",null,"Xray"),s(" 的工作原理,那么接下来的配置,其实就是【告诉你的客户端如何连接 VPS 服务器】。这和你已经很熟悉的、告诉"),n("code",null,"PuTTY"),s("如何远程连接服务器是一样的。只不过 Xray 连接时的要素不止是【IP 地址】+【端口】+【用户名】+【密码】这四要素了。")],-1),_=n("code",null,"Xray",-1),x=n("code",null,"config.json",-1),f=n("code",null,"Xray",-1),S=n("code",null,"VLESS",-1),X=n("code",null,"XTLS",-1),N=t('
                        • 服务器【地址】: a-name.yourdomain.com
                        • 服务器【端口】: 443
                        • 连接的【协议】: vless
                        • 连接的【流控】: xtls-rprx-vision (vision 模式适合全平台)
                        • 连接的【验证】: uuiduuid-uuid-uuid-uuiduuiduuid
                        • 连接的【安全】: "allowInsecure": false

                        鉴于新人一般都会使用手机 APP 或者电脑的 GUI 客户端,我就把常用的客户端罗列在下面。每个客户端都有自己独特的配置界面,逐一截图展示并不现实,所以请你务必仔细阅读这些客户端的说明、然后把上述要素填入合适的地方即可。

                        注意

                        许多工具其实是同时支持 xray-corev2fly-core 的,但默认内置的不一定是哪个,所以别忘记检查一下是否是你想要的那个在工作哦!

                        ',3),P=n("p",null,[n("strong",null,"v2rayN - 适用于 Windows 平台")],-1),w={href:"https://github.com/2dust/v2rayN/releases",target:"_blank",rel:"noopener noreferrer"},I=n("li",null,"请根据该客户端的说明进行设置",-1),T=n("p",null,[n("strong",null,"v2rayNG - 适用于 Android 平台")],-1),L={href:"https://github.com/2dust/v2rayNG/releases",target:"_blank",rel:"noopener noreferrer"},V=n("li",null,"请根据该客户端的说明进行设置",-1),C=n("li",null,[n("p",null,[n("strong",null,"Shadowrocket - 适用于 iOS, 基于苹果 M 芯片的 macOS")]),n("ul",null,[n("li",null,"你需要注册一个【非中国区】的 iCloud 账户"),n("li",null,"你需要通过 App Store 搜索并购买"),n("li",null,"请根据该客户端的说明进行设置")])],-1),D=n("p",null,[n("strong",null,"Qv2ray - 跨平台图形界面,适用于 Linux, Windows, macOS")],-1),j={href:"https://github.com/Qv2ray/Qv2ray/releases",target:"_blank",rel:"noopener noreferrer"},E={href:"https://github.com/Qv2ray/Qv2ray/actions",target:"_blank",rel:"noopener noreferrer"},G={href:"https://qv2ray.net/",target:"_blank",rel:"noopener noreferrer"},A=n("li",null,"请根据该客户端的说明进行设置",-1),O=n("p",null,[n("strong",null,"V2RayXS - 基于 V2RayX 开发的一款使用 xray-core 的 macOS 客户端")],-1),R={href:"https://github.com/tzmax/v2rayXS/releases",target:"_blank",rel:"noopener noreferrer"},B={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},H=n("li",null,"请根据该客户端的说明进行设置",-1),Q=t('

                        到这一步,你的全套配置就已经可以正常使用啦!

                        8.3 附加题 1:在 PC 端手工配置 xray-core

                        虽然到上面一步已经可以结束了,但是如果你是个好奇心强、记忆力好的的同学,一定会想起来我在上一章说过,你把xray-core 的二进制文件“放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。” 那究竟要怎样直接使用 xray-core 做客户端呢?

                        为了回答这个问题,我加入了附加题章节,有一点点超纲,有一点点麻烦,但费这个笔墨是因为这个方式有它的优势:

                        • 第一时间获得最新版而无需等待 APP 升级适配

                        • 灵活自由的路由配置能力(当然 GUI 客户端中 Qv2ray 的高级路由编辑器非常强大,也可以完整实现 xray-core 的路由配置功能)

                        • 节约系统资源 (GUI 界面一定会有资源消耗,消耗的多少则取决于客户端的实现)

                        它的劣势应该就是【需要手写配置文件】有点麻烦了。但其实,你想想,服务器上你已经成功的写过一次了,现在又有什么区别呢?接下来,还是老样子,我们分解一下步骤:

                        ',6),W={href:"https://github.com/XTLS/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},F=t(`
                      10. 在合适的文件夹建立空白配置文件:config.json (自己常用平台下新建文件大家肯定都会,这就真不用啰嗦了)

                      11. 至于什么是“合适的文件夹”?这就取决于具体的平台了~

                      12. 填写客户端配置

                        • 我就以 8.1 原理说明里展示的基本三类分流(国内流量直连、国际流量转发 VPS、广告流量屏蔽),结合 8.2 的连接要素,写成一个配置文件
                        • 请将 uuid 替换成与你服务器一致的 uuid
                        • 请将 address 替换成你的真实域名
                        • 请将 serverName 替换成你的真实域名
                        • 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
                        // REFERENCE:
                        +import{_ as c,r as p,o as i,c as u,a as n,b as s,d as a,w as l,e as t}from"./app-UOvWaKji.js";const r="/assets/ch08-img01-flow-Nus5m8Xg.png",d="/assets/ch08-img02-buzz-BMkpbZbZ.png",k={},v=t('

                        【第 8 章】Xray 客户端篇

                        8.1 Xray 的工作原理简述

                        要正确的配置和使用Xray,就需要正确的理解其工作原理,对于新人,可以先看看下面简化的示意图(省略了许多复杂的设置):

                        Xray数据流向

                        这其中的关键点是:

                        1. APP 要主动或借助转发工具,将数据【流入(inbounds)】Xray 客户端

                        2. 流量进入客户端后,会被【客户端路由(routing)】按规则处理后,向不同方向【流出(outbounds)Xray 客户端。比如:

                          1. 国内流量直连(direct
                          2. 国外流量转发 VPS(proxy
                          3. 广告流量屏蔽(block
                        3. 向 VPS 转发的国外流量,会跨过防火墙,【流入(inbounds)】 Xray 服务器端

                        4. 流量进入服务器端后,与客户端一样,会被【服务器端路由(routing)】按规则处理后,向不同方向【流出(outbounds)】:

                          1. 因为已经在防火墙之外,所以流量默认直连,你就可以访问到不存在网站们了(direct
                          2. 如果需要在不同的 VPS 之间做链式转发,就可以继续配置转发规则(proxy
                          3. 你可以在服务器端继续禁用各种你想禁用的流量,如广告、BT 下载等(block
                        ',6),m={class:"custom-container warning"},q=n("p",{class:"custom-container-title"},"注意",-1),b=n("p",null,[s("请务必记得,"),n("code",null,"Xray"),s(" 的路由配置非常灵活,上面的说明只是无限可能性中的一种。")],-1),g=n("p",null,[s("借助 "),n("code",null,"geosite.dat"),s(" 和 "),n("code",null,"geoip.dat"),s(" 这两个文件,可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 "),n("code",null,"GFWList"),s(" 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)")],-1),y=n("h2",{id:"_8-2-客户端与服务器端正确连接",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_8-2-客户端与服务器端正确连接"},[n("span",null,"8.2 客户端与服务器端正确连接")])],-1),h=n("p",null,[s("现在你已经理解了 "),n("code",null,"Xray"),s(" 的工作原理,那么接下来的配置,其实就是【告诉你的客户端如何连接 VPS 服务器】。这和你已经很熟悉的、告诉"),n("code",null,"PuTTY"),s("如何远程连接服务器是一样的。只不过 Xray 连接时的要素不止是【IP 地址】+【端口】+【用户名】+【密码】这四要素了。")],-1),_=n("code",null,"Xray",-1),x=n("code",null,"config.json",-1),f=n("code",null,"Xray",-1),S=n("code",null,"VLESS",-1),X=n("code",null,"XTLS",-1),N=t('
                        • 服务器【地址】: a-name.yourdomain.com
                        • 服务器【端口】: 443
                        • 连接的【协议】: vless
                        • 连接的【流控】: xtls-rprx-vision (vision 模式适合全平台)
                        • 连接的【验证】: uuiduuid-uuid-uuid-uuiduuiduuid
                        • 连接的【安全】: "allowInsecure": false

                        鉴于新人一般都会使用手机 APP 或者电脑的 GUI 客户端,我就把常用的客户端罗列在下面。每个客户端都有自己独特的配置界面,逐一截图展示并不现实,所以请你务必仔细阅读这些客户端的说明、然后把上述要素填入合适的地方即可。

                        注意

                        许多工具其实是同时支持 xray-corev2fly-core 的,但默认内置的不一定是哪个,所以别忘记检查一下是否是你想要的那个在工作哦!

                        ',3),P=n("p",null,[n("strong",null,"v2rayN - 适用于 Windows 平台")],-1),w={href:"https://github.com/2dust/v2rayN/releases",target:"_blank",rel:"noopener noreferrer"},I=n("li",null,"请根据该客户端的说明进行设置",-1),T=n("p",null,[n("strong",null,"v2rayNG - 适用于 Android 平台")],-1),L={href:"https://github.com/2dust/v2rayNG/releases",target:"_blank",rel:"noopener noreferrer"},V=n("li",null,"请根据该客户端的说明进行设置",-1),C=n("li",null,[n("p",null,[n("strong",null,"Shadowrocket - 适用于 iOS, 基于苹果 M 芯片的 macOS")]),n("ul",null,[n("li",null,"你需要注册一个【非中国区】的 iCloud 账户"),n("li",null,"你需要通过 App Store 搜索并购买"),n("li",null,"请根据该客户端的说明进行设置")])],-1),D=n("p",null,[n("strong",null,"Qv2ray - 跨平台图形界面,适用于 Linux, Windows, macOS")],-1),j={href:"https://github.com/Qv2ray/Qv2ray/releases",target:"_blank",rel:"noopener noreferrer"},E={href:"https://github.com/Qv2ray/Qv2ray/actions",target:"_blank",rel:"noopener noreferrer"},G={href:"https://qv2ray.net/",target:"_blank",rel:"noopener noreferrer"},A=n("li",null,"请根据该客户端的说明进行设置",-1),O=n("p",null,[n("strong",null,"V2RayXS - 基于 V2RayX 开发的一款使用 xray-core 的 macOS 客户端")],-1),R={href:"https://github.com/tzmax/v2rayXS/releases",target:"_blank",rel:"noopener noreferrer"},B={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},H=n("li",null,"请根据该客户端的说明进行设置",-1),Q=t('

                        到这一步,你的全套配置就已经可以正常使用啦!

                        8.3 附加题 1:在 PC 端手工配置 xray-core

                        虽然到上面一步已经可以结束了,但是如果你是个好奇心强、记忆力好的的同学,一定会想起来我在上一章说过,你把xray-core 的二进制文件“放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。” 那究竟要怎样直接使用 xray-core 做客户端呢?

                        为了回答这个问题,我加入了附加题章节,有一点点超纲,有一点点麻烦,但费这个笔墨是因为这个方式有它的优势:

                        • 第一时间获得最新版而无需等待 APP 升级适配

                        • 灵活自由的路由配置能力(当然 GUI 客户端中 Qv2ray 的高级路由编辑器非常强大,也可以完整实现 xray-core 的路由配置功能)

                        • 节约系统资源 (GUI 界面一定会有资源消耗,消耗的多少则取决于客户端的实现)

                        它的劣势应该就是【需要手写配置文件】有点麻烦了。但其实,你想想,服务器上你已经成功的写过一次了,现在又有什么区别呢?接下来,还是老样子,我们分解一下步骤:

                        ',6),W={href:"https://github.com/XTLS/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},F=t(`
                      13. 在合适的文件夹建立空白配置文件:config.json (自己常用平台下新建文件大家肯定都会,这就真不用啰嗦了)

                      14. 至于什么是“合适的文件夹”?这就取决于具体的平台了~

                      15. 填写客户端配置

                        • 我就以 8.1 原理说明里展示的基本三类分流(国内流量直连、国际流量转发 VPS、广告流量屏蔽),结合 8.2 的连接要素,写成一个配置文件
                        • 请将 uuid 替换成与你服务器一致的 uuid
                        • 请将 address 替换成你的真实域名
                        • 请将 serverName 替换成你的真实域名
                        • 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
                        // REFERENCE:
                         // https://github.com/XTLS/Xray-examples
                         // https://xtls.github.io/config/
                         
                        diff --git a/assets/ch09-appendix.html-eMozPKr6.js b/assets/ch09-appendix.html-BpoURQUR.js
                        similarity index 99%
                        rename from assets/ch09-appendix.html-eMozPKr6.js
                        rename to assets/ch09-appendix.html-BpoURQUR.js
                        index b423f6e9c0..864aea099e 100644
                        --- a/assets/ch09-appendix.html-eMozPKr6.js
                        +++ b/assets/ch09-appendix.html-BpoURQUR.js
                        @@ -1 +1 @@
                        -import{_ as o,r as d,o as c,c as i,a as t,d as n,w as s,b as e}from"./app-PDrbPfzp.js";const _={},a=t("h1",{id:"【第-9-章】附录",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#【第-9-章】附录"},[t("span",null,"【第 9 章】附录")])],-1),r=t("h2",{id:"_1-小小白白-linux-基础命令索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_1-小小白白-linux-基础命令索引"},[t("span",null,"1. 小小白白 Linux 基础命令索引")])],-1),h=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"命令名称"),t("th",{style:{"text-align":"left"}},"命令说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),u=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-01")],-1),y=t("td",{style:{"text-align":"left"}},[t("code",null,"apt update")],-1),x=t("td",{style:{"text-align":"left"}},"查询软件更新",-1),g={style:{"text-align":"center"}},f=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-02")],-1),m=t("td",{style:{"text-align":"left"}},[t("code",null,"apt upgrade")],-1),v=t("td",{style:{"text-align":"left"}},"执行软件更新",-1),p={style:{"text-align":"center"}},X=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-03")],-1),b=t("td",{style:{"text-align":"left"}},[t("code",null,"nano")],-1),k=t("td",{style:{"text-align":"left"}},"文本编辑器",-1),L={style:{"text-align":"center"}},w=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-04")],-1),N=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl restart")],-1),S=t("td",{style:{"text-align":"left"}},"重启某个服务",-1),B={style:{"text-align":"center"}},T=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-05")],-1),V=t("td",{style:{"text-align":"left"}},[t("code",null,"adduser")],-1),C=t("td",{style:{"text-align":"left"}},"给系统新增用户",-1),R={style:{"text-align":"center"}},j=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-06")],-1),A=t("td",{style:{"text-align":"left"}},[t("code",null,"apt install")],-1),E=t("td",{style:{"text-align":"left"}},"安装某个软件",-1),H={style:{"text-align":"center"}},q=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-07")],-1),z=t("td",{style:{"text-align":"left"}},[t("code",null,"visudo")],-1),D=t("td",{style:{"text-align":"left"}},"修改 sudo 权限设置专用编辑器",-1),F={style:{"text-align":"center"}},G=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-08")],-1),I=t("td",{style:{"text-align":"left"}},[t("code",null,"sudo")],-1),J=t("td",{style:{"text-align":"left"}},[e("用"),t("code",null,"root"),e("权限运行某个命令")],-1),K={style:{"text-align":"center"}},M=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-09")],-1),O=t("td",{style:{"text-align":"left"}},[t("code",null,"chmod")],-1),P=t("td",{style:{"text-align":"left"}},"修改目标文件/文件夹的权限",-1),Q={style:{"text-align":"center"}},U=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-10")],-1),W=t("td",{style:{"text-align":"left"}},[t("code",null,"mkdir")],-1),Y=t("td",{style:{"text-align":"left"}},"新建文件夹",-1),Z={style:{"text-align":"center"}},$=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-11")],-1),tt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl reload")],-1),et=t("td",{style:{"text-align":"left"}},"重新加载某个服务",-1),lt={style:{"text-align":"center"}},nt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-12")],-1),st=t("td",{style:{"text-align":"left"}},[t("code",null,"wget")],-1),ot=t("td",{style:{"text-align":"left"}},"访问(或下载)某个网页文件",-1),dt={style:{"text-align":"center"}},ct=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-13")],-1),it=t("td",{style:{"text-align":"left"}},[t("code",null,"acme.sh")],-1),_t=t("td",{style:{"text-align":"left"}},"acme.sh 证书管理相关的命令",-1),at={style:{"text-align":"center"}},rt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-14")],-1),ht=t("td",{style:{"text-align":"left"}},[t("code",null,"rm")],-1),ut=t("td",{style:{"text-align":"left"}},"删除命令",-1),yt={style:{"text-align":"center"}},xt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-15")],-1),gt=t("td",{style:{"text-align":"left"}},[t("code",null,"crontab -e")],-1),ft=t("td",{style:{"text-align":"left"}},"编辑当前用户的定时任务",-1),mt={style:{"text-align":"center"}},vt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-16")],-1),pt=t("td",{style:{"text-align":"left"}},[t("code",null,"touch")],-1),Xt=t("td",{style:{"text-align":"left"}},"建立空白文件",-1),bt={style:{"text-align":"center"}},kt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-17")],-1),Lt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl")],-1),wt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemd"),e("基本服务管理命令")],-1),Nt={style:{"text-align":"center"}},St=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-18")],-1),Bt=t("td",{style:{"text-align":"left"}},[t("code",null,"reboot")],-1),Tt=t("td",{style:{"text-align":"left"}},"重启 Linux 系统",-1),Vt={style:{"text-align":"center"}},Ct=t("h2",{id:"_2-小小白白-linux-重要配置文件索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_2-小小白白-linux-重要配置文件索引"},[t("span",null,"2. 小小白白 Linux 重要配置文件索引")])],-1),Rt=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"配置文件位置"),t("th",{style:{"text-align":"left"}},"文件说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),jt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-01")],-1),At=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/ssh/sshd_config")],-1),Et=t("td",{style:{"text-align":"left"}},"SSH 远程登录程序设置",-1),Ht={style:{"text-align":"center"}},qt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-02")],-1),zt=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/nginx/nginx.conf")],-1),Dt=t("td",{style:{"text-align":"left"}},"Nginx 程序设置",-1),Ft={style:{"text-align":"center"}},Gt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-03")],-1),It=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/apt/sources.list")],-1),Jt=t("td",{style:{"text-align":"left"}},"apt 软件源列表",-1),Kt={style:{"text-align":"center"}},Mt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-04")],-1),Ot=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/apt/sources.list.d/vpsadmin.list")],-1),Pt=t("td",{style:{"text-align":"left"}},"用户自定义软件源列表列表",-1),Qt={style:{"text-align":"center"}},Ut=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-05")],-1),Wt=t("td",{style:{"text-align":"left"}},[t("code",null,"crontab -e")],-1),Yt=t("td",{style:{"text-align":"left"}},"当前用户的定时任务",-1),Zt={style:{"text-align":"center"}},$t=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-06")],-1),te=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/sysctl.conf")],-1),ee=t("td",{style:{"text-align":"left"}},"手动设置 kernel 参数",-1),le={style:{"text-align":"center"}},ne=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-07")],-1),se=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/sysctl.d/vpsadmin.conf")],-1),oe=t("td",{style:{"text-align":"left"}},"用户自定义 kernel 参数配置文件",-1),de={style:{"text-align":"center"}},ce=t("h2",{id:"_3-小小白白-xray-重要文件索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-小小白白-xray-重要文件索引"},[t("span",null,"3. 小小白白 Xray 重要文件索引")])],-1),ie=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"配置文件位置"),t("th",{style:{"text-align":"left"}},"文件说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),_e=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-01")],-1),ae=t("td",{style:{"text-align":"left"}},[t("code",null,"/usr/local/etc/xray/config.json")],-1),re=t("td",{style:{"text-align":"left"}},"Xray 程序设置",-1),he={style:{"text-align":"center"}},ue=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-02")],-1),ye=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_cert/xray.cert")],-1),xe=t("td",{style:{"text-align":"left"}},"TLS 证书",-1),ge={style:{"text-align":"center"}},fe=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-03")],-1),me=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_cert/xray.key")],-1),ve=t("td",{style:{"text-align":"left"}},"TLS 私钥",-1),pe={style:{"text-align":"center"}},Xe=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-04")],-1),be=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_log/access.log")],-1),ke=t("td",{style:{"text-align":"left"}},"Xray 访问日志",-1),Le={style:{"text-align":"center"}},we=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-05")],-1),Ne=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_log/error.log")],-1),Se=t("td",{style:{"text-align":"left"}},"Xray 错误日志",-1),Be={style:{"text-align":"center"}};function Te(Ve,Ce){const l=d("RouterLink");return c(),i("div",null,[a,r,t("table",null,[h,t("tbody",null,[t("tr",null,[u,y,x,t("td",g,[n(l,{to:"/en/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[f,m,v,t("td",p,[n(l,{to:"/en/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[X,b,k,t("td",L,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[w,N,S,t("td",B,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[T,V,C,t("td",R,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[j,A,E,t("td",H,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[q,z,D,t("td",F,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[G,I,J,t("td",K,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[M,O,P,t("td",Q,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[U,W,Y,t("td",Z,[n(l,{to:"/en/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[$,tt,et,t("td",lt,[n(l,{to:"/en/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[nt,st,ot,t("td",dt,[n(l,{to:"/en/document/level-0/ch06-certificates.html"},{default:s(()=>[e("《证书管理篇》")]),_:1})])]),t("tr",null,[ct,it,_t,t("td",at,[n(l,{to:"/en/document/level-0/ch06-certificates.html"},{default:s(()=>[e("《证书管理篇》")]),_:1})])]),t("tr",null,[rt,ht,ut,t("td",yt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[xt,gt,ft,t("td",mt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[vt,pt,Xt,t("td",bt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[kt,Lt,wt,t("td",Nt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[St,Bt,Tt,t("td",Vt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])]),Ct,t("table",null,[Rt,t("tbody",null,[t("tr",null,[jt,At,Et,t("td",Ht,[n(l,{to:"/en/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[qt,zt,Dt,t("td",Ft,[n(l,{to:"/en/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[Gt,It,Jt,t("td",Kt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Mt,Ot,Pt,t("td",Qt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Ut,Wt,Yt,t("td",Zt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[$t,te,ee,t("td",le,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[ne,se,oe,t("td",de,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])]),ce,t("table",null,[ie,t("tbody",null,[t("tr",null,[_e,ae,re,t("td",he,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[ue,ye,xe,t("td",ge,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[fe,me,ve,t("td",pe,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Xe,be,ke,t("td",Le,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[we,Ne,Se,t("td",Be,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])])])}const je=o(_,[["render",Te],["__file","ch09-appendix.html.vue"]]);export{je as default};
                        +import{_ as o,r as d,o as c,c as i,a as t,d as n,w as s,b as e}from"./app-UOvWaKji.js";const _={},a=t("h1",{id:"【第-9-章】附录",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#【第-9-章】附录"},[t("span",null,"【第 9 章】附录")])],-1),r=t("h2",{id:"_1-小小白白-linux-基础命令索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_1-小小白白-linux-基础命令索引"},[t("span",null,"1. 小小白白 Linux 基础命令索引")])],-1),h=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"命令名称"),t("th",{style:{"text-align":"left"}},"命令说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),u=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-01")],-1),y=t("td",{style:{"text-align":"left"}},[t("code",null,"apt update")],-1),x=t("td",{style:{"text-align":"left"}},"查询软件更新",-1),g={style:{"text-align":"center"}},f=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-02")],-1),m=t("td",{style:{"text-align":"left"}},[t("code",null,"apt upgrade")],-1),v=t("td",{style:{"text-align":"left"}},"执行软件更新",-1),p={style:{"text-align":"center"}},X=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-03")],-1),b=t("td",{style:{"text-align":"left"}},[t("code",null,"nano")],-1),k=t("td",{style:{"text-align":"left"}},"文本编辑器",-1),L={style:{"text-align":"center"}},w=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-04")],-1),N=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl restart")],-1),S=t("td",{style:{"text-align":"left"}},"重启某个服务",-1),B={style:{"text-align":"center"}},T=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-05")],-1),V=t("td",{style:{"text-align":"left"}},[t("code",null,"adduser")],-1),C=t("td",{style:{"text-align":"left"}},"给系统新增用户",-1),R={style:{"text-align":"center"}},j=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-06")],-1),A=t("td",{style:{"text-align":"left"}},[t("code",null,"apt install")],-1),E=t("td",{style:{"text-align":"left"}},"安装某个软件",-1),H={style:{"text-align":"center"}},q=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-07")],-1),z=t("td",{style:{"text-align":"left"}},[t("code",null,"visudo")],-1),D=t("td",{style:{"text-align":"left"}},"修改 sudo 权限设置专用编辑器",-1),F={style:{"text-align":"center"}},G=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-08")],-1),I=t("td",{style:{"text-align":"left"}},[t("code",null,"sudo")],-1),J=t("td",{style:{"text-align":"left"}},[e("用"),t("code",null,"root"),e("权限运行某个命令")],-1),K={style:{"text-align":"center"}},M=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-09")],-1),O=t("td",{style:{"text-align":"left"}},[t("code",null,"chmod")],-1),P=t("td",{style:{"text-align":"left"}},"修改目标文件/文件夹的权限",-1),Q={style:{"text-align":"center"}},U=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-10")],-1),W=t("td",{style:{"text-align":"left"}},[t("code",null,"mkdir")],-1),Y=t("td",{style:{"text-align":"left"}},"新建文件夹",-1),Z={style:{"text-align":"center"}},$=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-11")],-1),tt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl reload")],-1),et=t("td",{style:{"text-align":"left"}},"重新加载某个服务",-1),lt={style:{"text-align":"center"}},nt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-12")],-1),st=t("td",{style:{"text-align":"left"}},[t("code",null,"wget")],-1),ot=t("td",{style:{"text-align":"left"}},"访问(或下载)某个网页文件",-1),dt={style:{"text-align":"center"}},ct=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-13")],-1),it=t("td",{style:{"text-align":"left"}},[t("code",null,"acme.sh")],-1),_t=t("td",{style:{"text-align":"left"}},"acme.sh 证书管理相关的命令",-1),at={style:{"text-align":"center"}},rt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-14")],-1),ht=t("td",{style:{"text-align":"left"}},[t("code",null,"rm")],-1),ut=t("td",{style:{"text-align":"left"}},"删除命令",-1),yt={style:{"text-align":"center"}},xt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-15")],-1),gt=t("td",{style:{"text-align":"left"}},[t("code",null,"crontab -e")],-1),ft=t("td",{style:{"text-align":"left"}},"编辑当前用户的定时任务",-1),mt={style:{"text-align":"center"}},vt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-16")],-1),pt=t("td",{style:{"text-align":"left"}},[t("code",null,"touch")],-1),Xt=t("td",{style:{"text-align":"left"}},"建立空白文件",-1),bt={style:{"text-align":"center"}},kt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-17")],-1),Lt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl")],-1),wt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemd"),e("基本服务管理命令")],-1),Nt={style:{"text-align":"center"}},St=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-18")],-1),Bt=t("td",{style:{"text-align":"left"}},[t("code",null,"reboot")],-1),Tt=t("td",{style:{"text-align":"left"}},"重启 Linux 系统",-1),Vt={style:{"text-align":"center"}},Ct=t("h2",{id:"_2-小小白白-linux-重要配置文件索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_2-小小白白-linux-重要配置文件索引"},[t("span",null,"2. 小小白白 Linux 重要配置文件索引")])],-1),Rt=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"配置文件位置"),t("th",{style:{"text-align":"left"}},"文件说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),jt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-01")],-1),At=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/ssh/sshd_config")],-1),Et=t("td",{style:{"text-align":"left"}},"SSH 远程登录程序设置",-1),Ht={style:{"text-align":"center"}},qt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-02")],-1),zt=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/nginx/nginx.conf")],-1),Dt=t("td",{style:{"text-align":"left"}},"Nginx 程序设置",-1),Ft={style:{"text-align":"center"}},Gt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-03")],-1),It=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/apt/sources.list")],-1),Jt=t("td",{style:{"text-align":"left"}},"apt 软件源列表",-1),Kt={style:{"text-align":"center"}},Mt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-04")],-1),Ot=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/apt/sources.list.d/vpsadmin.list")],-1),Pt=t("td",{style:{"text-align":"left"}},"用户自定义软件源列表列表",-1),Qt={style:{"text-align":"center"}},Ut=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-05")],-1),Wt=t("td",{style:{"text-align":"left"}},[t("code",null,"crontab -e")],-1),Yt=t("td",{style:{"text-align":"left"}},"当前用户的定时任务",-1),Zt={style:{"text-align":"center"}},$t=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-06")],-1),te=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/sysctl.conf")],-1),ee=t("td",{style:{"text-align":"left"}},"手动设置 kernel 参数",-1),le={style:{"text-align":"center"}},ne=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-07")],-1),se=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/sysctl.d/vpsadmin.conf")],-1),oe=t("td",{style:{"text-align":"left"}},"用户自定义 kernel 参数配置文件",-1),de={style:{"text-align":"center"}},ce=t("h2",{id:"_3-小小白白-xray-重要文件索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-小小白白-xray-重要文件索引"},[t("span",null,"3. 小小白白 Xray 重要文件索引")])],-1),ie=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"配置文件位置"),t("th",{style:{"text-align":"left"}},"文件说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),_e=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-01")],-1),ae=t("td",{style:{"text-align":"left"}},[t("code",null,"/usr/local/etc/xray/config.json")],-1),re=t("td",{style:{"text-align":"left"}},"Xray 程序设置",-1),he={style:{"text-align":"center"}},ue=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-02")],-1),ye=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_cert/xray.cert")],-1),xe=t("td",{style:{"text-align":"left"}},"TLS 证书",-1),ge={style:{"text-align":"center"}},fe=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-03")],-1),me=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_cert/xray.key")],-1),ve=t("td",{style:{"text-align":"left"}},"TLS 私钥",-1),pe={style:{"text-align":"center"}},Xe=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-04")],-1),be=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_log/access.log")],-1),ke=t("td",{style:{"text-align":"left"}},"Xray 访问日志",-1),Le={style:{"text-align":"center"}},we=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-05")],-1),Ne=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_log/error.log")],-1),Se=t("td",{style:{"text-align":"left"}},"Xray 错误日志",-1),Be={style:{"text-align":"center"}};function Te(Ve,Ce){const l=d("RouterLink");return c(),i("div",null,[a,r,t("table",null,[h,t("tbody",null,[t("tr",null,[u,y,x,t("td",g,[n(l,{to:"/en/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[f,m,v,t("td",p,[n(l,{to:"/en/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[X,b,k,t("td",L,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[w,N,S,t("td",B,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[T,V,C,t("td",R,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[j,A,E,t("td",H,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[q,z,D,t("td",F,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[G,I,J,t("td",K,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[M,O,P,t("td",Q,[n(l,{to:"/en/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[U,W,Y,t("td",Z,[n(l,{to:"/en/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[$,tt,et,t("td",lt,[n(l,{to:"/en/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[nt,st,ot,t("td",dt,[n(l,{to:"/en/document/level-0/ch06-certificates.html"},{default:s(()=>[e("《证书管理篇》")]),_:1})])]),t("tr",null,[ct,it,_t,t("td",at,[n(l,{to:"/en/document/level-0/ch06-certificates.html"},{default:s(()=>[e("《证书管理篇》")]),_:1})])]),t("tr",null,[rt,ht,ut,t("td",yt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[xt,gt,ft,t("td",mt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[vt,pt,Xt,t("td",bt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[kt,Lt,wt,t("td",Nt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[St,Bt,Tt,t("td",Vt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])]),Ct,t("table",null,[Rt,t("tbody",null,[t("tr",null,[jt,At,Et,t("td",Ht,[n(l,{to:"/en/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[qt,zt,Dt,t("td",Ft,[n(l,{to:"/en/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[Gt,It,Jt,t("td",Kt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Mt,Ot,Pt,t("td",Qt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Ut,Wt,Yt,t("td",Zt,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[$t,te,ee,t("td",le,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[ne,se,oe,t("td",de,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])]),ce,t("table",null,[ie,t("tbody",null,[t("tr",null,[_e,ae,re,t("td",he,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[ue,ye,xe,t("td",ge,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[fe,me,ve,t("td",pe,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Xe,be,ke,t("td",Le,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[we,Ne,Se,t("td",Be,[n(l,{to:"/en/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])])])}const je=o(_,[["render",Te],["__file","ch09-appendix.html.vue"]]);export{je as default};
                        diff --git a/assets/ch09-appendix.html-XGC3J-AJ.js b/assets/ch09-appendix.html-Ouutf7uu.js
                        similarity index 99%
                        rename from assets/ch09-appendix.html-XGC3J-AJ.js
                        rename to assets/ch09-appendix.html-Ouutf7uu.js
                        index 7e719c9200..d7bbb4c27e 100644
                        --- a/assets/ch09-appendix.html-XGC3J-AJ.js
                        +++ b/assets/ch09-appendix.html-Ouutf7uu.js
                        @@ -1 +1 @@
                        -import{_ as o,r as d,o as c,c as i,a as t,d as n,w as s,b as e}from"./app-PDrbPfzp.js";const _={},a=t("h1",{id:"【第-9-章】附录",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#【第-9-章】附录"},[t("span",null,"【第 9 章】附录")])],-1),r=t("h2",{id:"_1-小小白白-linux-基础命令索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_1-小小白白-linux-基础命令索引"},[t("span",null,"1. 小小白白 Linux 基础命令索引")])],-1),h=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"命令名称"),t("th",{style:{"text-align":"left"}},"命令说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),u=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-01")],-1),y=t("td",{style:{"text-align":"left"}},[t("code",null,"apt update")],-1),x=t("td",{style:{"text-align":"left"}},"查询软件更新",-1),g={style:{"text-align":"center"}},f=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-02")],-1),m=t("td",{style:{"text-align":"left"}},[t("code",null,"apt upgrade")],-1),v=t("td",{style:{"text-align":"left"}},"执行软件更新",-1),p={style:{"text-align":"center"}},X=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-03")],-1),b=t("td",{style:{"text-align":"left"}},[t("code",null,"nano")],-1),k=t("td",{style:{"text-align":"left"}},"文本编辑器",-1),L={style:{"text-align":"center"}},w=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-04")],-1),N=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl restart")],-1),S=t("td",{style:{"text-align":"left"}},"重启某个服务",-1),B={style:{"text-align":"center"}},T=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-05")],-1),V=t("td",{style:{"text-align":"left"}},[t("code",null,"adduser")],-1),C=t("td",{style:{"text-align":"left"}},"给系统新增用户",-1),R={style:{"text-align":"center"}},j=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-06")],-1),A=t("td",{style:{"text-align":"left"}},[t("code",null,"apt install")],-1),E=t("td",{style:{"text-align":"left"}},"安装某个软件",-1),H={style:{"text-align":"center"}},q=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-07")],-1),z=t("td",{style:{"text-align":"left"}},[t("code",null,"visudo")],-1),D=t("td",{style:{"text-align":"left"}},"修改 sudo 权限设置专用编辑器",-1),F={style:{"text-align":"center"}},G=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-08")],-1),I=t("td",{style:{"text-align":"left"}},[t("code",null,"sudo")],-1),J=t("td",{style:{"text-align":"left"}},[e("用"),t("code",null,"root"),e("权限运行某个命令")],-1),K={style:{"text-align":"center"}},M=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-09")],-1),O=t("td",{style:{"text-align":"left"}},[t("code",null,"chmod")],-1),P=t("td",{style:{"text-align":"left"}},"修改目标文件/文件夹的权限",-1),Q={style:{"text-align":"center"}},U=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-10")],-1),W=t("td",{style:{"text-align":"left"}},[t("code",null,"mkdir")],-1),Y=t("td",{style:{"text-align":"left"}},"新建文件夹",-1),Z={style:{"text-align":"center"}},$=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-11")],-1),tt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl reload")],-1),et=t("td",{style:{"text-align":"left"}},"重新加载某个服务",-1),lt={style:{"text-align":"center"}},nt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-12")],-1),st=t("td",{style:{"text-align":"left"}},[t("code",null,"wget")],-1),ot=t("td",{style:{"text-align":"left"}},"访问(或下载)某个网页文件",-1),dt={style:{"text-align":"center"}},ct=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-13")],-1),it=t("td",{style:{"text-align":"left"}},[t("code",null,"acme.sh")],-1),_t=t("td",{style:{"text-align":"left"}},"acme.sh 证书管理相关的命令",-1),at={style:{"text-align":"center"}},rt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-14")],-1),ht=t("td",{style:{"text-align":"left"}},[t("code",null,"rm")],-1),ut=t("td",{style:{"text-align":"left"}},"删除命令",-1),yt={style:{"text-align":"center"}},xt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-15")],-1),gt=t("td",{style:{"text-align":"left"}},[t("code",null,"crontab -e")],-1),ft=t("td",{style:{"text-align":"left"}},"编辑当前用户的定时任务",-1),mt={style:{"text-align":"center"}},vt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-16")],-1),pt=t("td",{style:{"text-align":"left"}},[t("code",null,"touch")],-1),Xt=t("td",{style:{"text-align":"left"}},"建立空白文件",-1),bt={style:{"text-align":"center"}},kt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-17")],-1),Lt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl")],-1),wt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemd"),e("基本服务管理命令")],-1),Nt={style:{"text-align":"center"}},St=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-18")],-1),Bt=t("td",{style:{"text-align":"left"}},[t("code",null,"reboot")],-1),Tt=t("td",{style:{"text-align":"left"}},"重启 Linux 系统",-1),Vt={style:{"text-align":"center"}},Ct=t("h2",{id:"_2-小小白白-linux-重要配置文件索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_2-小小白白-linux-重要配置文件索引"},[t("span",null,"2. 小小白白 Linux 重要配置文件索引")])],-1),Rt=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"配置文件位置"),t("th",{style:{"text-align":"left"}},"文件说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),jt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-01")],-1),At=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/ssh/sshd_config")],-1),Et=t("td",{style:{"text-align":"left"}},"SSH 远程登录程序设置",-1),Ht={style:{"text-align":"center"}},qt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-02")],-1),zt=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/nginx/nginx.conf")],-1),Dt=t("td",{style:{"text-align":"left"}},"Nginx 程序设置",-1),Ft={style:{"text-align":"center"}},Gt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-03")],-1),It=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/apt/sources.list")],-1),Jt=t("td",{style:{"text-align":"left"}},"apt 软件源列表",-1),Kt={style:{"text-align":"center"}},Mt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-04")],-1),Ot=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/apt/sources.list.d/vpsadmin.list")],-1),Pt=t("td",{style:{"text-align":"left"}},"用户自定义软件源列表列表",-1),Qt={style:{"text-align":"center"}},Ut=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-05")],-1),Wt=t("td",{style:{"text-align":"left"}},[t("code",null,"crontab -e")],-1),Yt=t("td",{style:{"text-align":"left"}},"当前用户的定时任务",-1),Zt={style:{"text-align":"center"}},$t=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-06")],-1),te=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/sysctl.conf")],-1),ee=t("td",{style:{"text-align":"left"}},"手动设置 kernel 参数",-1),le={style:{"text-align":"center"}},ne=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-07")],-1),se=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/sysctl.d/vpsadmin.conf")],-1),oe=t("td",{style:{"text-align":"left"}},"用户自定义 kernel 参数配置文件",-1),de={style:{"text-align":"center"}},ce=t("h2",{id:"_3-小小白白-xray-重要文件索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-小小白白-xray-重要文件索引"},[t("span",null,"3. 小小白白 Xray 重要文件索引")])],-1),ie=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"配置文件位置"),t("th",{style:{"text-align":"left"}},"文件说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),_e=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-01")],-1),ae=t("td",{style:{"text-align":"left"}},[t("code",null,"/usr/local/etc/xray/config.json")],-1),re=t("td",{style:{"text-align":"left"}},"Xray 程序设置",-1),he={style:{"text-align":"center"}},ue=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-02")],-1),ye=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_cert/xray.cert")],-1),xe=t("td",{style:{"text-align":"left"}},"TLS 证书",-1),ge={style:{"text-align":"center"}},fe=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-03")],-1),me=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_cert/xray.key")],-1),ve=t("td",{style:{"text-align":"left"}},"TLS 私钥",-1),pe={style:{"text-align":"center"}},Xe=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-04")],-1),be=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_log/access.log")],-1),ke=t("td",{style:{"text-align":"left"}},"Xray 访问日志",-1),Le={style:{"text-align":"center"}},we=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-05")],-1),Ne=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_log/error.log")],-1),Se=t("td",{style:{"text-align":"left"}},"Xray 错误日志",-1),Be={style:{"text-align":"center"}};function Te(Ve,Ce){const l=d("RouterLink");return c(),i("div",null,[a,r,t("table",null,[h,t("tbody",null,[t("tr",null,[u,y,x,t("td",g,[n(l,{to:"/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[f,m,v,t("td",p,[n(l,{to:"/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[X,b,k,t("td",L,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[w,N,S,t("td",B,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[T,V,C,t("td",R,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[j,A,E,t("td",H,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[q,z,D,t("td",F,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[G,I,J,t("td",K,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[M,O,P,t("td",Q,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[U,W,Y,t("td",Z,[n(l,{to:"/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[$,tt,et,t("td",lt,[n(l,{to:"/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[nt,st,ot,t("td",dt,[n(l,{to:"/document/level-0/ch06-certificates.html"},{default:s(()=>[e("《证书管理篇》")]),_:1})])]),t("tr",null,[ct,it,_t,t("td",at,[n(l,{to:"/document/level-0/ch06-certificates.html"},{default:s(()=>[e("《证书管理篇》")]),_:1})])]),t("tr",null,[rt,ht,ut,t("td",yt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[xt,gt,ft,t("td",mt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[vt,pt,Xt,t("td",bt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[kt,Lt,wt,t("td",Nt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[St,Bt,Tt,t("td",Vt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])]),Ct,t("table",null,[Rt,t("tbody",null,[t("tr",null,[jt,At,Et,t("td",Ht,[n(l,{to:"/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[qt,zt,Dt,t("td",Ft,[n(l,{to:"/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[Gt,It,Jt,t("td",Kt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Mt,Ot,Pt,t("td",Qt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Ut,Wt,Yt,t("td",Zt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[$t,te,ee,t("td",le,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[ne,se,oe,t("td",de,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])]),ce,t("table",null,[ie,t("tbody",null,[t("tr",null,[_e,ae,re,t("td",he,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[ue,ye,xe,t("td",ge,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[fe,me,ve,t("td",pe,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Xe,be,ke,t("td",Le,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[we,Ne,Se,t("td",Be,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])])])}const je=o(_,[["render",Te],["__file","ch09-appendix.html.vue"]]);export{je as default};
                        +import{_ as o,r as d,o as c,c as i,a as t,d as n,w as s,b as e}from"./app-UOvWaKji.js";const _={},a=t("h1",{id:"【第-9-章】附录",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#【第-9-章】附录"},[t("span",null,"【第 9 章】附录")])],-1),r=t("h2",{id:"_1-小小白白-linux-基础命令索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_1-小小白白-linux-基础命令索引"},[t("span",null,"1. 小小白白 Linux 基础命令索引")])],-1),h=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"命令名称"),t("th",{style:{"text-align":"left"}},"命令说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),u=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-01")],-1),y=t("td",{style:{"text-align":"left"}},[t("code",null,"apt update")],-1),x=t("td",{style:{"text-align":"left"}},"查询软件更新",-1),g={style:{"text-align":"center"}},f=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-02")],-1),m=t("td",{style:{"text-align":"left"}},[t("code",null,"apt upgrade")],-1),v=t("td",{style:{"text-align":"left"}},"执行软件更新",-1),p={style:{"text-align":"center"}},X=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-03")],-1),b=t("td",{style:{"text-align":"left"}},[t("code",null,"nano")],-1),k=t("td",{style:{"text-align":"left"}},"文本编辑器",-1),L={style:{"text-align":"center"}},w=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-04")],-1),N=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl restart")],-1),S=t("td",{style:{"text-align":"left"}},"重启某个服务",-1),B={style:{"text-align":"center"}},T=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-05")],-1),V=t("td",{style:{"text-align":"left"}},[t("code",null,"adduser")],-1),C=t("td",{style:{"text-align":"left"}},"给系统新增用户",-1),R={style:{"text-align":"center"}},j=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-06")],-1),A=t("td",{style:{"text-align":"left"}},[t("code",null,"apt install")],-1),E=t("td",{style:{"text-align":"left"}},"安装某个软件",-1),H={style:{"text-align":"center"}},q=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-07")],-1),z=t("td",{style:{"text-align":"left"}},[t("code",null,"visudo")],-1),D=t("td",{style:{"text-align":"left"}},"修改 sudo 权限设置专用编辑器",-1),F={style:{"text-align":"center"}},G=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-08")],-1),I=t("td",{style:{"text-align":"left"}},[t("code",null,"sudo")],-1),J=t("td",{style:{"text-align":"left"}},[e("用"),t("code",null,"root"),e("权限运行某个命令")],-1),K={style:{"text-align":"center"}},M=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-09")],-1),O=t("td",{style:{"text-align":"left"}},[t("code",null,"chmod")],-1),P=t("td",{style:{"text-align":"left"}},"修改目标文件/文件夹的权限",-1),Q={style:{"text-align":"center"}},U=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-10")],-1),W=t("td",{style:{"text-align":"left"}},[t("code",null,"mkdir")],-1),Y=t("td",{style:{"text-align":"left"}},"新建文件夹",-1),Z={style:{"text-align":"center"}},$=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-11")],-1),tt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl reload")],-1),et=t("td",{style:{"text-align":"left"}},"重新加载某个服务",-1),lt={style:{"text-align":"center"}},nt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-12")],-1),st=t("td",{style:{"text-align":"left"}},[t("code",null,"wget")],-1),ot=t("td",{style:{"text-align":"left"}},"访问(或下载)某个网页文件",-1),dt={style:{"text-align":"center"}},ct=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-13")],-1),it=t("td",{style:{"text-align":"left"}},[t("code",null,"acme.sh")],-1),_t=t("td",{style:{"text-align":"left"}},"acme.sh 证书管理相关的命令",-1),at={style:{"text-align":"center"}},rt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-14")],-1),ht=t("td",{style:{"text-align":"left"}},[t("code",null,"rm")],-1),ut=t("td",{style:{"text-align":"left"}},"删除命令",-1),yt={style:{"text-align":"center"}},xt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-15")],-1),gt=t("td",{style:{"text-align":"left"}},[t("code",null,"crontab -e")],-1),ft=t("td",{style:{"text-align":"left"}},"编辑当前用户的定时任务",-1),mt={style:{"text-align":"center"}},vt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-16")],-1),pt=t("td",{style:{"text-align":"left"}},[t("code",null,"touch")],-1),Xt=t("td",{style:{"text-align":"left"}},"建立空白文件",-1),bt={style:{"text-align":"center"}},kt=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-17")],-1),Lt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemctl")],-1),wt=t("td",{style:{"text-align":"left"}},[t("code",null,"systemd"),e("基本服务管理命令")],-1),Nt={style:{"text-align":"center"}},St=t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-18")],-1),Bt=t("td",{style:{"text-align":"left"}},[t("code",null,"reboot")],-1),Tt=t("td",{style:{"text-align":"left"}},"重启 Linux 系统",-1),Vt={style:{"text-align":"center"}},Ct=t("h2",{id:"_2-小小白白-linux-重要配置文件索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_2-小小白白-linux-重要配置文件索引"},[t("span",null,"2. 小小白白 Linux 重要配置文件索引")])],-1),Rt=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"配置文件位置"),t("th",{style:{"text-align":"left"}},"文件说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),jt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-01")],-1),At=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/ssh/sshd_config")],-1),Et=t("td",{style:{"text-align":"left"}},"SSH 远程登录程序设置",-1),Ht={style:{"text-align":"center"}},qt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-02")],-1),zt=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/nginx/nginx.conf")],-1),Dt=t("td",{style:{"text-align":"left"}},"Nginx 程序设置",-1),Ft={style:{"text-align":"center"}},Gt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-03")],-1),It=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/apt/sources.list")],-1),Jt=t("td",{style:{"text-align":"left"}},"apt 软件源列表",-1),Kt={style:{"text-align":"center"}},Mt=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-04")],-1),Ot=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/apt/sources.list.d/vpsadmin.list")],-1),Pt=t("td",{style:{"text-align":"left"}},"用户自定义软件源列表列表",-1),Qt={style:{"text-align":"center"}},Ut=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-05")],-1),Wt=t("td",{style:{"text-align":"left"}},[t("code",null,"crontab -e")],-1),Yt=t("td",{style:{"text-align":"left"}},"当前用户的定时任务",-1),Zt={style:{"text-align":"center"}},$t=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-06")],-1),te=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/sysctl.conf")],-1),ee=t("td",{style:{"text-align":"left"}},"手动设置 kernel 参数",-1),le={style:{"text-align":"center"}},ne=t("td",{style:{"text-align":"center"}},[t("code",null,"conf-07")],-1),se=t("td",{style:{"text-align":"left"}},[t("code",null,"/etc/sysctl.d/vpsadmin.conf")],-1),oe=t("td",{style:{"text-align":"left"}},"用户自定义 kernel 参数配置文件",-1),de={style:{"text-align":"center"}},ce=t("h2",{id:"_3-小小白白-xray-重要文件索引",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-小小白白-xray-重要文件索引"},[t("span",null,"3. 小小白白 Xray 重要文件索引")])],-1),ie=t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"left"}},"配置文件位置"),t("th",{style:{"text-align":"left"}},"文件说明"),t("th",{style:{"text-align":"center"}},"出现篇章")])],-1),_e=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-01")],-1),ae=t("td",{style:{"text-align":"left"}},[t("code",null,"/usr/local/etc/xray/config.json")],-1),re=t("td",{style:{"text-align":"left"}},"Xray 程序设置",-1),he={style:{"text-align":"center"}},ue=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-02")],-1),ye=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_cert/xray.cert")],-1),xe=t("td",{style:{"text-align":"left"}},"TLS 证书",-1),ge={style:{"text-align":"center"}},fe=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-03")],-1),me=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_cert/xray.key")],-1),ve=t("td",{style:{"text-align":"left"}},"TLS 私钥",-1),pe={style:{"text-align":"center"}},Xe=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-04")],-1),be=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_log/access.log")],-1),ke=t("td",{style:{"text-align":"left"}},"Xray 访问日志",-1),Le={style:{"text-align":"center"}},we=t("td",{style:{"text-align":"center"}},[t("code",null,"xray-05")],-1),Ne=t("td",{style:{"text-align":"left"}},[t("code",null,"/home/vpsadmin/xray_log/error.log")],-1),Se=t("td",{style:{"text-align":"left"}},"Xray 错误日志",-1),Be={style:{"text-align":"center"}};function Te(Ve,Ce){const l=d("RouterLink");return c(),i("div",null,[a,r,t("table",null,[h,t("tbody",null,[t("tr",null,[u,y,x,t("td",g,[n(l,{to:"/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[f,m,v,t("td",p,[n(l,{to:"/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[X,b,k,t("td",L,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[w,N,S,t("td",B,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[T,V,C,t("td",R,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[j,A,E,t("td",H,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[q,z,D,t("td",F,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[G,I,J,t("td",K,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[M,O,P,t("td",Q,[n(l,{to:"/document/level-0/ch04-security.html"},{default:s(()=>[e("《安全防护篇》")]),_:1})])]),t("tr",null,[U,W,Y,t("td",Z,[n(l,{to:"/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[$,tt,et,t("td",lt,[n(l,{to:"/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[nt,st,ot,t("td",dt,[n(l,{to:"/document/level-0/ch06-certificates.html"},{default:s(()=>[e("《证书管理篇》")]),_:1})])]),t("tr",null,[ct,it,_t,t("td",at,[n(l,{to:"/document/level-0/ch06-certificates.html"},{default:s(()=>[e("《证书管理篇》")]),_:1})])]),t("tr",null,[rt,ht,ut,t("td",yt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[xt,gt,ft,t("td",mt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[vt,pt,Xt,t("td",bt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[kt,Lt,wt,t("td",Nt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[St,Bt,Tt,t("td",Vt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])]),Ct,t("table",null,[Rt,t("tbody",null,[t("tr",null,[jt,At,Et,t("td",Ht,[n(l,{to:"/document/level-0/ch03-ssh.html"},{default:s(()=>[e("《远程登录篇》")]),_:1})])]),t("tr",null,[qt,zt,Dt,t("td",Ft,[n(l,{to:"/document/level-0/ch05-webpage.html"},{default:s(()=>[e("《网站建设篇》")]),_:1})])]),t("tr",null,[Gt,It,Jt,t("td",Kt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Mt,Ot,Pt,t("td",Qt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Ut,Wt,Yt,t("td",Zt,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[$t,te,ee,t("td",le,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[ne,se,oe,t("td",de,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])]),ce,t("table",null,[ie,t("tbody",null,[t("tr",null,[_e,ae,re,t("td",he,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[ue,ye,xe,t("td",ge,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[fe,me,ve,t("td",pe,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[Xe,be,ke,t("td",Le,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])]),t("tr",null,[we,Ne,Se,t("td",Be,[n(l,{to:"/document/level-0/ch07-xray-server.html"},{default:s(()=>[e("《Xray 服务器篇》")]),_:1})])])])])])}const je=o(_,[["render",Te],["__file","ch09-appendix.html.vue"]]);export{je as default};
                        diff --git a/assets/channel-GQnHP4O7.js b/assets/channel-GQnHP4O7.js
                        deleted file mode 100644
                        index 4dfb11e47c..0000000000
                        --- a/assets/channel-GQnHP4O7.js
                        +++ /dev/null
                        @@ -1 +0,0 @@
                        -import{am as n,an as o}from"./mermaid.core-95b3ca__.js";const t=(a,r)=>n.lang.round(o.parse(a)[r]);export{t as c};
                        diff --git a/assets/channel-hMLbS6Zi.js b/assets/channel-hMLbS6Zi.js
                        new file mode 100644
                        index 0000000000..647c428a86
                        --- /dev/null
                        +++ b/assets/channel-hMLbS6Zi.js
                        @@ -0,0 +1 @@
                        +import{am as n,an as o}from"./mermaid.core-Q3WVcjPF.js";const t=(a,r)=>n.lang.round(o.parse(a)[r]);export{t as c};
                        diff --git a/assets/classDiagram-30eddba6-OAikPNdt.js b/assets/classDiagram-30eddba6-LzAW2Y3L.js
                        similarity index 97%
                        rename from assets/classDiagram-30eddba6-OAikPNdt.js
                        rename to assets/classDiagram-30eddba6-LzAW2Y3L.js
                        index f6bc479dfa..9f1ef9e999 100644
                        --- a/assets/classDiagram-30eddba6-OAikPNdt.js
                        +++ b/assets/classDiagram-30eddba6-LzAW2Y3L.js
                        @@ -1,2 +1,2 @@
                        -import{p as A,d as S,s as G}from"./styles-991ebdfc-vHdkyrCb.js";import{c as v,l as y,h as B,i as W,ap as $,z as M,as as I}from"./mermaid.core-95b3ca__.js";import{G as O}from"./graph-cZfODKa1.js";import{l as P}from"./layout-konkdG3Z.js";import{l as X}from"./line-_nnM_7ZX.js";import"./app-PDrbPfzp.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";let H=0;const Y=function(i,a,t,o,p){const g=function(e){switch(e){case p.db.relationType.AGGREGATION:return"aggregation";case p.db.relationType.EXTENSION:return"extension";case p.db.relationType.COMPOSITION:return"composition";case p.db.relationType.DEPENDENCY:return"dependency";case p.db.relationType.LOLLIPOP:return"lollipop"}};a.points=a.points.filter(e=>!Number.isNaN(e.y));const s=a.points,c=X().x(function(e){return e.x}).y(function(e){return e.y}).curve($),n=i.append("path").attr("d",c(s)).attr("id","edge"+H).attr("class","relation");let r="";o.arrowMarkerAbsolute&&(r=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,r=r.replace(/\(/g,"\\("),r=r.replace(/\)/g,"\\)")),t.relation.lineType==1&&n.attr("class","relation dashed-line"),t.relation.lineType==10&&n.attr("class","relation dotted-line"),t.relation.type1!=="none"&&n.attr("marker-start","url("+r+"#"+g(t.relation.type1)+"Start)"),t.relation.type2!=="none"&&n.attr("marker-end","url("+r+"#"+g(t.relation.type2)+"End)");let f,h;const x=a.points.length;let b=M.calcLabelPosition(a.points);f=b.x,h=b.y;let u,m,w,k;if(x%2!==0&&x>1){let e=M.calcCardinalityPosition(t.relation.type1!=="none",a.points,a.points[0]),d=M.calcCardinalityPosition(t.relation.type2!=="none",a.points,a.points[x-1]);y.debug("cardinality_1_point "+JSON.stringify(e)),y.debug("cardinality_2_point "+JSON.stringify(d)),u=e.x,m=e.y,w=d.x,k=d.y}if(t.title!==void 0){const e=i.append("g").attr("class","classLabel"),d=e.append("text").attr("class","label").attr("x",f).attr("y",h).attr("fill","red").attr("text-anchor","middle").text(t.title);window.label=d;const l=d.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",l.x-o.padding/2).attr("y",l.y-o.padding/2).attr("width",l.width+o.padding).attr("height",l.height+o.padding)}y.info("Rendering relation "+JSON.stringify(t)),t.relationTitle1!==void 0&&t.relationTitle1!=="none"&&i.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",u).attr("y",m).attr("fill","black").attr("font-size","6").text(t.relationTitle1),t.relationTitle2!==void 0&&t.relationTitle2!=="none"&&i.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",w).attr("y",k).attr("fill","black").attr("font-size","6").text(t.relationTitle2),H++},J=function(i,a,t,o){y.debug("Rendering class ",a,t);const p=a.id,g={id:p,label:a.id,width:0,height:0},s=i.append("g").attr("id",o.db.lookUpDomId(p)).attr("class","classGroup");let c;a.link?c=s.append("svg:a").attr("xlink:href",a.link).attr("target",a.linkTarget).append("text").attr("y",t.textHeight+t.padding).attr("x",0):c=s.append("text").attr("y",t.textHeight+t.padding).attr("x",0);let n=!0;a.annotations.forEach(function(d){const l=c.append("tspan").text("«"+d+"»");n||l.attr("dy",t.textHeight),n=!1});let r=C(a);const f=c.append("tspan").text(r).attr("class","title");n||f.attr("dy",t.textHeight);const h=c.node().getBBox().height;let x,b,u;if(a.members.length>0){x=s.append("line").attr("x1",0).attr("y1",t.padding+h+t.dividerMargin/2).attr("y2",t.padding+h+t.dividerMargin/2);const d=s.append("text").attr("x",t.padding).attr("y",h+t.dividerMargin+t.textHeight).attr("fill","white").attr("class","classText");n=!0,a.members.forEach(function(l){_(d,l,n,t),n=!1}),b=d.node().getBBox()}if(a.methods.length>0){u=s.append("line").attr("x1",0).attr("y1",t.padding+h+t.dividerMargin+b.height).attr("y2",t.padding+h+t.dividerMargin+b.height);const d=s.append("text").attr("x",t.padding).attr("y",h+2*t.dividerMargin+b.height+t.textHeight).attr("fill","white").attr("class","classText");n=!0,a.methods.forEach(function(l){_(d,l,n,t),n=!1})}const m=s.node().getBBox();var w=" ";a.cssClasses.length>0&&(w=w+a.cssClasses.join(" "));const e=s.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",m.width+2*t.padding).attr("height",m.height+t.padding+.5*t.dividerMargin).attr("class",w).node().getBBox().width;return c.node().childNodes.forEach(function(d){d.setAttribute("x",(e-d.getBBox().width)/2)}),a.tooltip&&c.insert("title").text(a.tooltip),x&&x.attr("x2",e),u&&u.attr("x2",e),g.width=e,g.height=m.height+t.padding+.5*t.dividerMargin,g},C=function(i){let a=i.id;return i.type&&(a+="<"+I(i.type)+">"),a},Z=function(i,a,t,o){y.debug("Rendering note ",a,t);const p=a.id,g={id:p,text:a.text,width:0,height:0},s=i.append("g").attr("id",p).attr("class","classGroup");let c=s.append("text").attr("y",t.textHeight+t.padding).attr("x",0);const n=JSON.parse(`"${a.text}"`).split(`
                        +import{p as A,d as S,s as G}from"./styles-991ebdfc-6jesWoI2.js";import{c as v,l as y,h as B,i as W,ap as $,z as M,as as I}from"./mermaid.core-Q3WVcjPF.js";import{G as O}from"./graph-yVkSecXb.js";import{l as P}from"./layout-2f_iGf4E.js";import{l as X}from"./line-3Gyevr9q.js";import"./app-UOvWaKji.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";let H=0;const Y=function(i,a,t,o,p){const g=function(e){switch(e){case p.db.relationType.AGGREGATION:return"aggregation";case p.db.relationType.EXTENSION:return"extension";case p.db.relationType.COMPOSITION:return"composition";case p.db.relationType.DEPENDENCY:return"dependency";case p.db.relationType.LOLLIPOP:return"lollipop"}};a.points=a.points.filter(e=>!Number.isNaN(e.y));const s=a.points,c=X().x(function(e){return e.x}).y(function(e){return e.y}).curve($),n=i.append("path").attr("d",c(s)).attr("id","edge"+H).attr("class","relation");let r="";o.arrowMarkerAbsolute&&(r=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,r=r.replace(/\(/g,"\\("),r=r.replace(/\)/g,"\\)")),t.relation.lineType==1&&n.attr("class","relation dashed-line"),t.relation.lineType==10&&n.attr("class","relation dotted-line"),t.relation.type1!=="none"&&n.attr("marker-start","url("+r+"#"+g(t.relation.type1)+"Start)"),t.relation.type2!=="none"&&n.attr("marker-end","url("+r+"#"+g(t.relation.type2)+"End)");let f,h;const x=a.points.length;let b=M.calcLabelPosition(a.points);f=b.x,h=b.y;let u,m,w,k;if(x%2!==0&&x>1){let e=M.calcCardinalityPosition(t.relation.type1!=="none",a.points,a.points[0]),d=M.calcCardinalityPosition(t.relation.type2!=="none",a.points,a.points[x-1]);y.debug("cardinality_1_point "+JSON.stringify(e)),y.debug("cardinality_2_point "+JSON.stringify(d)),u=e.x,m=e.y,w=d.x,k=d.y}if(t.title!==void 0){const e=i.append("g").attr("class","classLabel"),d=e.append("text").attr("class","label").attr("x",f).attr("y",h).attr("fill","red").attr("text-anchor","middle").text(t.title);window.label=d;const l=d.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",l.x-o.padding/2).attr("y",l.y-o.padding/2).attr("width",l.width+o.padding).attr("height",l.height+o.padding)}y.info("Rendering relation "+JSON.stringify(t)),t.relationTitle1!==void 0&&t.relationTitle1!=="none"&&i.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",u).attr("y",m).attr("fill","black").attr("font-size","6").text(t.relationTitle1),t.relationTitle2!==void 0&&t.relationTitle2!=="none"&&i.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",w).attr("y",k).attr("fill","black").attr("font-size","6").text(t.relationTitle2),H++},J=function(i,a,t,o){y.debug("Rendering class ",a,t);const p=a.id,g={id:p,label:a.id,width:0,height:0},s=i.append("g").attr("id",o.db.lookUpDomId(p)).attr("class","classGroup");let c;a.link?c=s.append("svg:a").attr("xlink:href",a.link).attr("target",a.linkTarget).append("text").attr("y",t.textHeight+t.padding).attr("x",0):c=s.append("text").attr("y",t.textHeight+t.padding).attr("x",0);let n=!0;a.annotations.forEach(function(d){const l=c.append("tspan").text("«"+d+"»");n||l.attr("dy",t.textHeight),n=!1});let r=C(a);const f=c.append("tspan").text(r).attr("class","title");n||f.attr("dy",t.textHeight);const h=c.node().getBBox().height;let x,b,u;if(a.members.length>0){x=s.append("line").attr("x1",0).attr("y1",t.padding+h+t.dividerMargin/2).attr("y2",t.padding+h+t.dividerMargin/2);const d=s.append("text").attr("x",t.padding).attr("y",h+t.dividerMargin+t.textHeight).attr("fill","white").attr("class","classText");n=!0,a.members.forEach(function(l){_(d,l,n,t),n=!1}),b=d.node().getBBox()}if(a.methods.length>0){u=s.append("line").attr("x1",0).attr("y1",t.padding+h+t.dividerMargin+b.height).attr("y2",t.padding+h+t.dividerMargin+b.height);const d=s.append("text").attr("x",t.padding).attr("y",h+2*t.dividerMargin+b.height+t.textHeight).attr("fill","white").attr("class","classText");n=!0,a.methods.forEach(function(l){_(d,l,n,t),n=!1})}const m=s.node().getBBox();var w=" ";a.cssClasses.length>0&&(w=w+a.cssClasses.join(" "));const e=s.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",m.width+2*t.padding).attr("height",m.height+t.padding+.5*t.dividerMargin).attr("class",w).node().getBBox().width;return c.node().childNodes.forEach(function(d){d.setAttribute("x",(e-d.getBBox().width)/2)}),a.tooltip&&c.insert("title").text(a.tooltip),x&&x.attr("x2",e),u&&u.attr("x2",e),g.width=e,g.height=m.height+t.padding+.5*t.dividerMargin,g},C=function(i){let a=i.id;return i.type&&(a+="<"+I(i.type)+">"),a},Z=function(i,a,t,o){y.debug("Rendering note ",a,t);const p=a.id,g={id:p,text:a.text,width:0,height:0},s=i.append("g").attr("id",p).attr("class","classGroup");let c=s.append("text").attr("y",t.textHeight+t.padding).attr("x",0);const n=JSON.parse(`"${a.text}"`).split(`
                         `);n.forEach(function(x){y.debug(`Adding line: ${x}`),c.append("tspan").text(x).attr("class","title").attr("dy",t.textHeight)});const r=s.node().getBBox(),h=s.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",r.width+2*t.padding).attr("height",r.height+n.length*t.textHeight+t.padding+.5*t.dividerMargin).node().getBBox().width;return c.node().childNodes.forEach(function(x){x.setAttribute("x",(h-x.getBBox().width)/2)}),g.width=h,g.height=r.height+n.length*t.textHeight+t.padding+.5*t.dividerMargin,g},_=function(i,a,t,o){const{displayText:p,cssStyle:g}=a.getDisplayDetails(),s=i.append("tspan").attr("x",o.padding).text(p);g!==""&&s.attr("style",a.cssStyle),t||s.attr("dy",o.textHeight)},N={getClassTitleString:C,drawClass:J,drawEdge:Y,drawNote:Z};let T={};const E=20,L=function(i){const a=Object.entries(T).find(t=>t[1].label===i);if(a)return a[0]},R=function(i){i.append("defs").append("marker").attr("id","extensionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),i.append("defs").append("marker").attr("id","extensionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z"),i.append("defs").append("marker").attr("id","compositionStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),i.append("defs").append("marker").attr("id","compositionEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),i.append("defs").append("marker").attr("id","aggregationStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),i.append("defs").append("marker").attr("id","aggregationEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),i.append("defs").append("marker").attr("id","dependencyStart").attr("class","extension").attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),i.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},z=function(i,a,t,o){const p=v().class;T={},y.info("Rendering diagram "+i);const g=v().securityLevel;let s;g==="sandbox"&&(s=B("#i"+a));const c=g==="sandbox"?B(s.nodes()[0].contentDocument.body):B("body"),n=c.select(`[id='${a}']`);R(n);const r=new O({multigraph:!0});r.setGraph({isMultiGraph:!0}),r.setDefaultEdgeLabel(function(){return{}});const f=o.db.getClasses(),h=Object.keys(f);for(const e of h){const d=f[e],l=N.drawClass(n,d,p,o);T[l.id]=l,r.setNode(l.id,l),y.info("Org height: "+l.height)}o.db.getRelations().forEach(function(e){y.info("tjoho"+L(e.id1)+L(e.id2)+JSON.stringify(e)),r.setEdge(L(e.id1),L(e.id2),{relation:e},e.title||"DEFAULT")}),o.db.getNotes().forEach(function(e){y.debug(`Adding note: ${JSON.stringify(e)}`);const d=N.drawNote(n,e,p,o);T[d.id]=d,r.setNode(d.id,d),e.class&&e.class in f&&r.setEdge(e.id,L(e.class),{relation:{id1:e.id,id2:e.class,relation:{type1:"none",type2:"none",lineType:10}}},"DEFAULT")}),P(r),r.nodes().forEach(function(e){e!==void 0&&r.node(e)!==void 0&&(y.debug("Node "+e+": "+JSON.stringify(r.node(e))),c.select("#"+(o.db.lookUpDomId(e)||e)).attr("transform","translate("+(r.node(e).x-r.node(e).width/2)+","+(r.node(e).y-r.node(e).height/2)+" )"))}),r.edges().forEach(function(e){e!==void 0&&r.edge(e)!==void 0&&(y.debug("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(r.edge(e))),N.drawEdge(n,r.edge(e),r.edge(e).relation,p,o))});const u=n.node().getBBox(),m=u.width+E*2,w=u.height+E*2;W(n,w,m,p.useMaxWidth);const k=`${u.x-E} ${u.y-E} ${m} ${w}`;y.debug(`viewBox ${k}`),n.attr("viewBox",k)},F={draw:z},et={parser:A,db:S,renderer:F,styles:G,init:i=>{i.class||(i.class={}),i.class.arrowMarkerAbsolute=i.arrowMarkerAbsolute,S.clear()}};export{et as diagram};
                        diff --git a/assets/classDiagram-v2-f2df5561-yJMOQ1KK.js b/assets/classDiagram-v2-f2df5561-L_-CRfCF.js
                        similarity index 92%
                        rename from assets/classDiagram-v2-f2df5561-yJMOQ1KK.js
                        rename to assets/classDiagram-v2-f2df5561-L_-CRfCF.js
                        index 9e510f532f..82308d755f 100644
                        --- a/assets/classDiagram-v2-f2df5561-yJMOQ1KK.js
                        +++ b/assets/classDiagram-v2-f2df5561-L_-CRfCF.js
                        @@ -1,2 +1,2 @@
                        -import{p as M,d as _,s as R}from"./styles-991ebdfc-vHdkyrCb.js";import{l as d,c,h as w,z as B,u as G,p as D,t as E,o as C,j as A}from"./mermaid.core-95b3ca__.js";import{G as z}from"./graph-cZfODKa1.js";import{r as P}from"./index-fc10efb0-knA-ZLJ0.js";import"./layout-konkdG3Z.js";import"./app-PDrbPfzp.js";import"./clone-jETecP85.js";import"./edges-d32062c0-iT1MEq_Y.js";import"./createText-6b48ae7d-9AoX5zU9.js";import"./line-_nnM_7ZX.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";const S=s=>A.sanitizeText(s,c());let k={dividerMargin:10,padding:5,textHeight:10,curve:void 0};const q=function(s,t,y,a){const e=Object.keys(s);d.info("keys:",e),d.info(s),e.forEach(function(i){var o,r;const l=s[i],p={shape:"rect",id:l.id,domId:l.domId,labelText:S(l.id),labelStyle:"",style:"fill: none; stroke: black",padding:((o=c().flowchart)==null?void 0:o.padding)??((r=c().class)==null?void 0:r.padding)};t.setNode(l.id,p),$(l.classes,t,y,a,l.id),d.info("setNode",p)})},$=function(s,t,y,a,e){const i=Object.keys(s);d.info("keys:",i),d.info(s),i.filter(o=>s[o].parent==e).forEach(function(o){var r,l;const n=s[o],p=n.cssClasses.join(" "),f=D(n.styles),h=n.label??n.id,u=0,b={labelStyle:f.labelStyle,shape:"class_box",labelText:S(h),classData:n,rx:u,ry:u,class:p,style:f.style,id:n.id,domId:n.domId,tooltip:a.db.getTooltip(n.id,e)||"",haveCallback:n.haveCallback,link:n.link,width:n.type==="group"?500:void 0,type:n.type,padding:((r=c().flowchart)==null?void 0:r.padding)??((l=c().class)==null?void 0:l.padding)};t.setNode(n.id,b),e&&t.setParent(n.id,e),d.info("setNode",b)})},F=function(s,t,y,a){d.info(s),s.forEach(function(e,i){var o,r;const l=e,n="",p={labelStyle:"",style:""},f=l.text,h=0,m={labelStyle:p.labelStyle,shape:"note",labelText:S(f),noteData:l,rx:h,ry:h,class:n,style:p.style,id:l.id,domId:l.id,tooltip:"",type:"note",padding:((o=c().flowchart)==null?void 0:o.padding)??((r=c().class)==null?void 0:r.padding)};if(t.setNode(l.id,m),d.info("setNode",m),!l.class||!(l.class in a))return;const b=y+i,x={id:`edgeNote${b}`,classes:"relation",pattern:"dotted",arrowhead:"none",startLabelRight:"",endLabelLeft:"",arrowTypeStart:"none",arrowTypeEnd:"none",style:"fill:none",labelStyle:"",curve:E(k.curve,C)};t.setEdge(l.id,l.class,x,b)})},H=function(s,t){const y=c().flowchart;let a=0;s.forEach(function(e){var i;a++;const o={classes:"relation",pattern:e.relation.lineType==1?"dashed":"solid",id:`id_${e.id1}_${e.id2}_${a}`,arrowhead:e.type==="arrow_open"?"none":"normal",startLabelRight:e.relationTitle1==="none"?"":e.relationTitle1,endLabelLeft:e.relationTitle2==="none"?"":e.relationTitle2,arrowTypeStart:N(e.relation.type1),arrowTypeEnd:N(e.relation.type2),style:"fill:none",labelStyle:"",curve:E(y==null?void 0:y.curve,C)};if(d.info(o,e),e.style!==void 0){const r=D(e.style);o.style=r.style,o.labelStyle=r.labelStyle}e.text=e.title,e.text===void 0?e.style!==void 0&&(o.arrowheadStyle="fill: #333"):(o.arrowheadStyle="fill: #333",o.labelpos="c",((i=c().flowchart)==null?void 0:i.htmlLabels)??c().htmlLabels?(o.labelType="html",o.label=''+e.text+""):(o.labelType="text",o.label=e.text.replace(A.lineBreakRegex,`
                        +import{p as M,d as _,s as R}from"./styles-991ebdfc-6jesWoI2.js";import{l as d,c,h as w,z as B,u as G,p as D,t as E,o as C,j as A}from"./mermaid.core-Q3WVcjPF.js";import{G as z}from"./graph-yVkSecXb.js";import{r as P}from"./index-fc10efb0-cfY4JypU.js";import"./layout-2f_iGf4E.js";import"./app-UOvWaKji.js";import"./clone-bRwIupqN.js";import"./edges-d32062c0-DdP-jtfh.js";import"./createText-6b48ae7d-yUX1YD6G.js";import"./line-3Gyevr9q.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";const S=s=>A.sanitizeText(s,c());let k={dividerMargin:10,padding:5,textHeight:10,curve:void 0};const q=function(s,t,y,a){const e=Object.keys(s);d.info("keys:",e),d.info(s),e.forEach(function(i){var o,r;const l=s[i],p={shape:"rect",id:l.id,domId:l.domId,labelText:S(l.id),labelStyle:"",style:"fill: none; stroke: black",padding:((o=c().flowchart)==null?void 0:o.padding)??((r=c().class)==null?void 0:r.padding)};t.setNode(l.id,p),$(l.classes,t,y,a,l.id),d.info("setNode",p)})},$=function(s,t,y,a,e){const i=Object.keys(s);d.info("keys:",i),d.info(s),i.filter(o=>s[o].parent==e).forEach(function(o){var r,l;const n=s[o],p=n.cssClasses.join(" "),f=D(n.styles),h=n.label??n.id,u=0,b={labelStyle:f.labelStyle,shape:"class_box",labelText:S(h),classData:n,rx:u,ry:u,class:p,style:f.style,id:n.id,domId:n.domId,tooltip:a.db.getTooltip(n.id,e)||"",haveCallback:n.haveCallback,link:n.link,width:n.type==="group"?500:void 0,type:n.type,padding:((r=c().flowchart)==null?void 0:r.padding)??((l=c().class)==null?void 0:l.padding)};t.setNode(n.id,b),e&&t.setParent(n.id,e),d.info("setNode",b)})},F=function(s,t,y,a){d.info(s),s.forEach(function(e,i){var o,r;const l=e,n="",p={labelStyle:"",style:""},f=l.text,h=0,m={labelStyle:p.labelStyle,shape:"note",labelText:S(f),noteData:l,rx:h,ry:h,class:n,style:p.style,id:l.id,domId:l.id,tooltip:"",type:"note",padding:((o=c().flowchart)==null?void 0:o.padding)??((r=c().class)==null?void 0:r.padding)};if(t.setNode(l.id,m),d.info("setNode",m),!l.class||!(l.class in a))return;const b=y+i,x={id:`edgeNote${b}`,classes:"relation",pattern:"dotted",arrowhead:"none",startLabelRight:"",endLabelLeft:"",arrowTypeStart:"none",arrowTypeEnd:"none",style:"fill:none",labelStyle:"",curve:E(k.curve,C)};t.setEdge(l.id,l.class,x,b)})},H=function(s,t){const y=c().flowchart;let a=0;s.forEach(function(e){var i;a++;const o={classes:"relation",pattern:e.relation.lineType==1?"dashed":"solid",id:`id_${e.id1}_${e.id2}_${a}`,arrowhead:e.type==="arrow_open"?"none":"normal",startLabelRight:e.relationTitle1==="none"?"":e.relationTitle1,endLabelLeft:e.relationTitle2==="none"?"":e.relationTitle2,arrowTypeStart:N(e.relation.type1),arrowTypeEnd:N(e.relation.type2),style:"fill:none",labelStyle:"",curve:E(y==null?void 0:y.curve,C)};if(d.info(o,e),e.style!==void 0){const r=D(e.style);o.style=r.style,o.labelStyle=r.labelStyle}e.text=e.title,e.text===void 0?e.style!==void 0&&(o.arrowheadStyle="fill: #333"):(o.arrowheadStyle="fill: #333",o.labelpos="c",((i=c().flowchart)==null?void 0:i.htmlLabels)??c().htmlLabels?(o.labelType="html",o.label=''+e.text+""):(o.labelType="text",o.label=e.text.replace(A.lineBreakRegex,`
                         `),e.style===void 0&&(o.style=o.style||"stroke: #333; stroke-width: 1.5px;fill:none"),o.labelStyle=o.labelStyle.replace("color:","fill:"))),t.setEdge(e.id1,e.id2,o,a)})},V=function(s){k={...k,...s}},W=async function(s,t,y,a){d.info("Drawing class - ",t);const e=c().flowchart??c().class,i=c().securityLevel;d.info("config:",e);const o=(e==null?void 0:e.nodeSpacing)??50,r=(e==null?void 0:e.rankSpacing)??50,l=new z({multigraph:!0,compound:!0}).setGraph({rankdir:a.db.getDirection(),nodesep:o,ranksep:r,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}}),n=a.db.getNamespaces(),p=a.db.getClasses(),f=a.db.getRelations(),h=a.db.getNotes();d.info(f),q(n,l,t,a),$(p,l,t,a),H(f,l),F(h,l,f.length+1,p);let u;i==="sandbox"&&(u=w("#i"+t));const m=i==="sandbox"?w(u.nodes()[0].contentDocument.body):w("body"),b=m.select(`[id="${t}"]`),x=m.select("#"+t+" g");if(await P(x,l,["aggregation","extension","composition","dependency","lollipop"],"classDiagram",t),B.insertTitle(b,"classTitleText",(e==null?void 0:e.titleTopMargin)??5,a.db.getDiagramTitle()),G(l,b,e==null?void 0:e.diagramPadding,e==null?void 0:e.useMaxWidth),!(e!=null&&e.htmlLabels)){const T=i==="sandbox"?u.nodes()[0].contentDocument:document,I=T.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const g of I){const L=g.getBBox(),v=T.createElementNS("http://www.w3.org/2000/svg","rect");v.setAttribute("rx",0),v.setAttribute("ry",0),v.setAttribute("width",L.width),v.setAttribute("height",L.height),g.insertBefore(v,g.firstChild)}}};function N(s){let t;switch(s){case 0:t="aggregation";break;case 1:t="extension";break;case 2:t="composition";break;case 3:t="dependency";break;case 4:t="lollipop";break;default:t="none"}return t}const J={setConf:V,draw:W},se={parser:M,db:_,renderer:J,styles:R,init:s=>{s.class||(s.class={}),s.class.arrowMarkerAbsolute=s.arrowMarkerAbsolute,_.clear()}};export{se as diagram};
                        diff --git a/assets/clone-bRwIupqN.js b/assets/clone-bRwIupqN.js
                        new file mode 100644
                        index 0000000000..da28d2cd2a
                        --- /dev/null
                        +++ b/assets/clone-bRwIupqN.js
                        @@ -0,0 +1 @@
                        +import{a as r}from"./graph-yVkSecXb.js";var a=4;function n(o){return r(o,a)}export{n as c};
                        diff --git a/assets/clone-jETecP85.js b/assets/clone-jETecP85.js
                        deleted file mode 100644
                        index 4b5f6d1f77..0000000000
                        --- a/assets/clone-jETecP85.js
                        +++ /dev/null
                        @@ -1 +0,0 @@
                        -import{a as r}from"./graph-cZfODKa1.js";var a=4;function n(o){return r(o,a)}export{n as c};
                        diff --git a/assets/command.html-MQnx7SGt.js b/assets/command.html-GmQWX7Oz.js
                        similarity index 99%
                        rename from assets/command.html-MQnx7SGt.js
                        rename to assets/command.html-GmQWX7Oz.js
                        index 39ce109a13..b5a47b19f5 100644
                        --- a/assets/command.html-MQnx7SGt.js
                        +++ b/assets/command.html-GmQWX7Oz.js
                        @@ -1,4 +1,4 @@
                        -import{_ as n,r as s,o as t,c as d,a as e,d as l,w as r,b as a,e as c}from"./app-PDrbPfzp.js";const o={},u=c(`

                        命令参数

                        提示

                        Xray 使用 Go 风格的命令及参数

                        获取基本命令

                        您可以运行 xray help 来获得所有 xray 最基础的用法, 以及可用的命令及说明。

                        Xray is a platform for building proxies.
                        +import{_ as n,r as s,o as t,c as d,a as e,d as l,w as r,b as a,e as c}from"./app-UOvWaKji.js";const o={},u=c(`

                        命令参数

                        提示

                        Xray 使用 Go 风格的命令及参数

                        获取基本命令

                        您可以运行 xray help 来获得所有 xray 最基础的用法, 以及可用的命令及说明。

                        Xray is a platform for building proxies.
                         
                         Usage:
                         
                        diff --git a/assets/command.html-Q2_pBtQX.js b/assets/command.html-Pk9D3c6o.js
                        similarity index 99%
                        rename from assets/command.html-Q2_pBtQX.js
                        rename to assets/command.html-Pk9D3c6o.js
                        index b38737b9c6..b93346f5f2 100644
                        --- a/assets/command.html-Q2_pBtQX.js
                        +++ b/assets/command.html-Pk9D3c6o.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as s,o as t,c as d,a as e,b as a,d as r,w as l,e as c}from"./app-PDrbPfzp.js";const o={},u=c(`

                        Command Parameters

                        Tip

                        Xray uses Go-style commands and parameters

                        Get Basic Commands

                        You can run xray helpto get the most basic usage of all xray, as well as available commands and instructions.

                        Xray is a platform for building proxies.
                        +import{_ as i,r as s,o as t,c as d,a as e,b as a,d as r,w as l,e as c}from"./app-UOvWaKji.js";const o={},u=c(`

                        Command Parameters

                        Tip

                        Xray uses Go-style commands and parameters

                        Get Basic Commands

                        You can run xray helpto get the most basic usage of all xray, as well as available commands and instructions.

                        Xray is a platform for building proxies.
                         
                         Usage:
                         
                        diff --git a/assets/compile.html-QZoJ6y29.js b/assets/compile.html-B6Lx1oYG.js
                        similarity index 99%
                        rename from assets/compile.html-QZoJ6y29.js
                        rename to assets/compile.html-B6Lx1oYG.js
                        index 3f151e3c21..cbc1b43460 100644
                        --- a/assets/compile.html-QZoJ6y29.js
                        +++ b/assets/compile.html-B6Lx1oYG.js
                        @@ -1,4 +1,4 @@
                        -import{_ as o,r as t,o as i,c as l,a as e,b as a,d as n,e as r}from"./app-PDrbPfzp.js";const c={},d=e("h1",{id:"compile-the-document",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#compile-the-document"},[e("span",null,"Compile the document")])],-1),p=e("h2",{id:"preparatory-work",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#preparatory-work"},[e("span",null,"Preparatory Work")])],-1),u={href:"https://golang.org/",target:"_blank",rel:"noopener noreferrer"},h={class:"custom-container tip"},m=e("p",{class:"custom-container-title"},"TIP",-1),g={href:"https://golang.org/doc/install",target:"_blank",rel:"noopener noreferrer"},b=r(`

                        If you happen to use Windows, please make sure to use Powershell.

                        Pull Xray source code

                        git clone https://github.com/XTLS/Xray-core.git
                        +import{_ as o,r as t,o as i,c as l,a as e,b as a,d as n,e as r}from"./app-UOvWaKji.js";const c={},d=e("h1",{id:"compile-the-document",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#compile-the-document"},[e("span",null,"Compile the document")])],-1),p=e("h2",{id:"preparatory-work",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#preparatory-work"},[e("span",null,"Preparatory Work")])],-1),u={href:"https://golang.org/",target:"_blank",rel:"noopener noreferrer"},h={class:"custom-container tip"},m=e("p",{class:"custom-container-title"},"TIP",-1),g={href:"https://golang.org/doc/install",target:"_blank",rel:"noopener noreferrer"},b=r(`

                        If you happen to use Windows, please make sure to use Powershell.

                        Pull Xray source code

                        git clone https://github.com/XTLS/Xray-core.git
                         cd Xray-core && go mod download
                         

                        If you have free time, you can try GitHub's official tool: gh repo clone XTLS/Xray-core

                        Note: In a network environment where Google cannot be accessed normally, dependencies cannot be pulled normally, and GOPROXY needs to be set first:

                        go env -w GOPROXY=https://goproxy.io,direct
                         

                        Build Binary

                        Warning

                        This command needs to be executed within Xray root directory.

                        Windows(Powershell):

                        $env:CGO_ENABLED=0
                        diff --git a/assets/compile.html-t_m_hch4.js b/assets/compile.html-p25837Gy.js
                        similarity index 98%
                        rename from assets/compile.html-t_m_hch4.js
                        rename to assets/compile.html-p25837Gy.js
                        index 7db0e2ba10..795f6fc826 100644
                        --- a/assets/compile.html-t_m_hch4.js
                        +++ b/assets/compile.html-p25837Gy.js
                        @@ -1,4 +1,4 @@
                        -import{_ as o,r as l,o as t,c as i,a,b as s,d as n,e as r}from"./app-PDrbPfzp.js";const c={},p=a("h1",{id:"编译文档",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#编译文档"},[a("span",null,"编译文档")])],-1),d=a("h2",{id:"前序工作",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#前序工作"},[a("span",null,"前序工作")])],-1),u={href:"https://golang.org/",target:"_blank",rel:"noopener noreferrer"},h={class:"custom-container tip"},v=a("p",{class:"custom-container-title"},"TIP",-1),m={href:"https://golang.org/doc/install",target:"_blank",rel:"noopener noreferrer"},b=r(`

                        如果你不幸使用 Windows, 请 务必 使用 Powershell

                        拉取 Xray 源代码

                        git clone https://github.com/XTLS/Xray-core.git
                        +import{_ as o,r as l,o as t,c as i,a,b as s,d as n,e as r}from"./app-UOvWaKji.js";const c={},p=a("h1",{id:"编译文档",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#编译文档"},[a("span",null,"编译文档")])],-1),d=a("h2",{id:"前序工作",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#前序工作"},[a("span",null,"前序工作")])],-1),u={href:"https://golang.org/",target:"_blank",rel:"noopener noreferrer"},h={class:"custom-container tip"},v=a("p",{class:"custom-container-title"},"TIP",-1),m={href:"https://golang.org/doc/install",target:"_blank",rel:"noopener noreferrer"},b=r(`

                        如果你不幸使用 Windows, 请 务必 使用 Powershell

                        拉取 Xray 源代码

                        git clone https://github.com/XTLS/Xray-core.git
                         cd Xray-core && go mod download
                         

                        如果你闲的没事干,可以试试 GitHub 官方工具: gh repo clone XTLS/Xray-core

                        注意:在无法正常访问 Google 的网络环境,依赖无法被正常拉取,需要先设置 GOPROXY

                        go env -w GOPROXY=https://goproxy.io,direct
                         

                        构建二进制

                        注意

                        本小节的命令需要在 Xray 根目录内运行。

                        Windows(Powershell):

                        $env:CGO_ENABLED=0
                        diff --git a/assets/config.html-Hj3P0-iE.js b/assets/config.html-FFB6YdOZ.js
                        similarity index 99%
                        rename from assets/config.html-Hj3P0-iE.js
                        rename to assets/config.html-FFB6YdOZ.js
                        index a322bfb8bb..f8187180ba 100644
                        --- a/assets/config.html-Hj3P0-iE.js
                        +++ b/assets/config.html-FFB6YdOZ.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as e,o as i,c as l,a as s,b as n,d as a,w as o,e as u}from"./app-PDrbPfzp.js";const r={},d=s("h1",{id:"配置运行",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#配置运行"},[s("span",null,"配置运行")])],-1),k=s("p",null,[s("a",{href:"./install"},"下载并安装"),n(" 了 Xray 之后,您需要对它进行一下配置。")],-1),v={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},m=u(`

                        警告

                        为了避免你的流量被解密,
                        你应该使用 xray uuiduuidgen 生成一个独一无二的uuid
                        在服务端上,放入 inbounds[0].settings.clients[0].id
                        在客户端内,放入 outbounds[0].settings.vnext[0].users[0].id

                        服务端配置

                        你需要一台防火墙外的服务器,来运行服务器端的 Xray。配置如下:

                        {
                        +import{_ as c,r as e,o as i,c as l,a as s,b as n,d as a,w as o,e as u}from"./app-UOvWaKji.js";const r={},d=s("h1",{id:"配置运行",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#配置运行"},[s("span",null,"配置运行")])],-1),k=s("p",null,[s("a",{href:"./install"},"下载并安装"),n(" 了 Xray 之后,您需要对它进行一下配置。")],-1),v={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},m=u(`

                        警告

                        为了避免你的流量被解密,
                        你应该使用 xray uuiduuidgen 生成一个独一无二的uuid
                        在服务端上,放入 inbounds[0].settings.clients[0].id
                        在客户端内,放入 outbounds[0].settings.vnext[0].users[0].id

                        服务端配置

                        你需要一台防火墙外的服务器,来运行服务器端的 Xray。配置如下:

                        {
                           "inbounds": [
                             {
                               "port": 10086, // 服务器监听端口
                        diff --git a/assets/config.html-862ghCov.js b/assets/config.html-RkLhbZyp.js
                        similarity index 99%
                        rename from assets/config.html-862ghCov.js
                        rename to assets/config.html-RkLhbZyp.js
                        index f92d7b53f6..44e90a3b09 100644
                        --- a/assets/config.html-862ghCov.js
                        +++ b/assets/config.html-RkLhbZyp.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as o,o as c,c as l,a as s,b as n,d as a,w as e,e as r}from"./app-PDrbPfzp.js";const u={},d=s("h1",{id:"configure-and-run",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#configure-and-run"},[s("span",null,"Configure and Run")])],-1),v={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},k=r(`

                        Server Configuration

                        You need a server outside the firewall to run server-side Xray. The configuration is as follows:

                        {
                        +import{_ as i,r as o,o as c,c as l,a as s,b as n,d as a,w as e,e as r}from"./app-UOvWaKji.js";const u={},d=s("h1",{id:"configure-and-run",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#configure-and-run"},[s("span",null,"Configure and Run")])],-1),v={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},k=r(`

                        Server Configuration

                        You need a server outside the firewall to run server-side Xray. The configuration is as follows:

                        {
                           "inbounds": [
                             {
                               "port": 10086, // The port on which the server is listening
                        diff --git a/assets/createText-6b48ae7d-9AoX5zU9.js b/assets/createText-6b48ae7d-yUX1YD6G.js
                        similarity index 99%
                        rename from assets/createText-6b48ae7d-9AoX5zU9.js
                        rename to assets/createText-6b48ae7d-yUX1YD6G.js
                        index 6b5234c797..eff4865539 100644
                        --- a/assets/createText-6b48ae7d-9AoX5zU9.js
                        +++ b/assets/createText-6b48ae7d-yUX1YD6G.js
                        @@ -1,4 +1,4 @@
                        -import{l as At,ao as zt,aq as It}from"./mermaid.core-95b3ca__.js";const Tt={};function Bt(n,r){const t=r||Tt,e=typeof t.includeImageAlt=="boolean"?t.includeImageAlt:!0,u=typeof t.includeHtml=="boolean"?t.includeHtml:!0;return et(n,e,u)}function et(n,r,t){if(Lt(n)){if("value"in n)return n.type==="html"&&!t?"":n.value;if(r&&"alt"in n&&n.alt)return n.alt;if("children"in n)return Vn(n.children,r,t)}return Array.isArray(n)?Vn(n,r,t):""}function Vn(n,r,t){const e=[];let u=-1;for(;++uu?0:u+r:r=r>u?u:r,t=t>0?t:0,e.length<1e4)l=Array.from(e),l.unshift(r,t),n.splice(...l);else for(t&&n.splice(r,t);i0?(tn(n,n.length,0,r),n):r}const Wn={}.hasOwnProperty;function Ot(n){const r={};let t=-1;for(;++tl))return;const T=r.events.length;let H=T,N,V;for(;H--;)if(r.events[H][0]==="exit"&&r.events[H][1].type==="chunkFlow"){if(N){V=r.events[H][1].end;break}N=!0}for(b(e),k=T;kF;){const _=t[D];r.containerState=_[1],_[0].exit.call(r,n)}t.length=F}function j(){u.write([null]),i=void 0,u=void 0,r.containerState._closeFlow=void 0}}function Ut(n,r,t){return O(n,n.attempt(this.parser.constructs.document,r,t),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function Un(n){if(n===null||Z(n)||Ht(n))return 1;if(qt(n))return 2}function Ln(n,r,t){const e=[];let u=-1;for(;++u1&&n[t][1].end.offset-n[t][1].start.offset>1?2:1;const f=Object.assign({},n[e][1].end),x=Object.assign({},n[t][1].start);$n(f,-m),$n(x,m),l={type:m>1?"strongSequence":"emphasisSequence",start:f,end:Object.assign({},n[e][1].end)},a={type:m>1?"strongSequence":"emphasisSequence",start:Object.assign({},n[t][1].start),end:x},i={type:m>1?"strongText":"emphasisText",start:Object.assign({},n[e][1].end),end:Object.assign({},n[t][1].start)},u={type:m>1?"strong":"emphasis",start:Object.assign({},l.start),end:Object.assign({},a.end)},n[e][1].end=Object.assign({},l.start),n[t][1].start=Object.assign({},a.end),c=[],n[e][1].end.offset-n[e][1].start.offset&&(c=Y(c,[["enter",n[e][1],r],["exit",n[e][1],r]])),c=Y(c,[["enter",u,r],["enter",l,r],["exit",l,r],["enter",i,r]]),c=Y(c,Ln(r.parser.constructs.insideSpan.null,n.slice(e+1,t),r)),c=Y(c,[["exit",i,r],["enter",a,r],["exit",a,r],["exit",u,r]]),n[t][1].end.offset-n[t][1].start.offset?(p=2,c=Y(c,[["enter",n[t][1],r],["exit",n[t][1],r]])):p=0,tn(n,e-1,t-e+3,c),t=e+c.length-p-2;break}}for(t=-1;++t0&&z(k)?O(n,j,"linePrefix",i+1)(k):j(k)}function j(k){return k===null||C(k)?n.check(Yn,I,D)(k):(n.enter("codeFlowValue"),F(k))}function F(k){return k===null||C(k)?(n.exit("codeFlowValue"),j(k)):(n.consume(k),F)}function D(k){return n.exit("codeFenced"),r(k)}function _(k,T,H){let N=0;return V;function V(w){return k.enter("lineEnding"),k.consume(w),k.exit("lineEnding"),y}function y(w){return k.enter("codeFencedFence"),z(w)?O(k,S,"linePrefix",e.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(w):S(w)}function S(w){return w===a?(k.enter("codeFencedFenceSequence"),P(w)):H(w)}function P(w){return w===a?(N++,k.consume(w),P):N>=l?(k.exit("codeFencedFenceSequence"),z(w)?O(k,R,"whitespace")(w):R(w)):H(w)}function R(w){return w===null||C(w)?(k.exit("codeFencedFence"),T(w)):H(w)}}}function re(n,r,t){const e=this;return u;function u(l){return l===null?t(l):(n.enter("lineEnding"),n.consume(l),n.exit("lineEnding"),i)}function i(l){return e.parser.lazy[e.now().line]?t(l):r(l)}}const Cn={name:"codeIndented",tokenize:ue},ie={tokenize:le,partial:!0};function ue(n,r,t){const e=this;return u;function u(c){return n.enter("codeIndented"),O(n,i,"linePrefix",5)(c)}function i(c){const p=e.events[e.events.length-1];return p&&p[1].type==="linePrefix"&&p[2].sliceSerialize(p[1],!0).length>=4?l(c):t(c)}function l(c){return c===null?m(c):C(c)?n.attempt(ie,l,m)(c):(n.enter("codeFlowValue"),a(c))}function a(c){return c===null||C(c)?(n.exit("codeFlowValue"),l(c)):(n.consume(c),a)}function m(c){return n.exit("codeIndented"),r(c)}}function le(n,r,t){const e=this;return u;function u(l){return e.parser.lazy[e.now().line]?t(l):C(l)?(n.enter("lineEnding"),n.consume(l),n.exit("lineEnding"),u):O(n,i,"linePrefix",5)(l)}function i(l){const a=e.events[e.events.length-1];return a&&a[1].type==="linePrefix"&&a[2].sliceSerialize(a[1],!0).length>=4?r(l):C(l)?u(l):t(l)}}const ae={name:"codeText",tokenize:ce,resolve:oe,previous:se};function oe(n){let r=n.length-4,t=3,e,u;if((n[t][1].type==="lineEnding"||n[t][1].type==="space")&&(n[r][1].type==="lineEnding"||n[r][1].type==="space")){for(e=t;++e=4?r(l):n.interrupt(e.parser.constructs.flow,t,r)(l)}}function at(n,r,t,e,u,i,l,a,m){const c=m||Number.POSITIVE_INFINITY;let p=0;return f;function f(b){return b===60?(n.enter(e),n.enter(u),n.enter(i),n.consume(b),n.exit(i),x):b===null||b===32||b===41||An(b)?t(b):(n.enter(e),n.enter(l),n.enter(a),n.enter("chunkString",{contentType:"string"}),I(b))}function x(b){return b===62?(n.enter(i),n.consume(b),n.exit(i),n.exit(u),n.exit(e),r):(n.enter(a),n.enter("chunkString",{contentType:"string"}),h(b))}function h(b){return b===62?(n.exit("chunkString"),n.exit(a),x(b)):b===null||b===60||C(b)?t(b):(n.consume(b),b===92?A:h)}function A(b){return b===60||b===62||b===92?(n.consume(b),h):h(b)}function I(b){return!p&&(b===null||b===41||Z(b))?(n.exit("chunkString"),n.exit(a),n.exit(l),n.exit(e),r(b)):p999||h===null||h===91||h===93&&!m||h===94&&!a&&"_hiddenFootnoteSupport"in l.parser.constructs?t(h):h===93?(n.exit(i),n.enter(u),n.consume(h),n.exit(u),n.exit(e),r):C(h)?(n.enter("lineEnding"),n.consume(h),n.exit("lineEnding"),p):(n.enter("chunkString",{contentType:"string"}),f(h))}function f(h){return h===null||h===91||h===93||C(h)||a++>999?(n.exit("chunkString"),p(h)):(n.consume(h),m||(m=!z(h)),h===92?x:f)}function x(h){return h===91||h===92||h===93?(n.consume(h),a++,f):f(h)}}function st(n,r,t,e,u,i){let l;return a;function a(x){return x===34||x===39||x===40?(n.enter(e),n.enter(u),n.consume(x),n.exit(u),l=x===40?41:x,m):t(x)}function m(x){return x===l?(n.enter(u),n.consume(x),n.exit(u),n.exit(e),r):(n.enter(i),c(x))}function c(x){return x===l?(n.exit(i),m(l)):x===null?t(x):C(x)?(n.enter("lineEnding"),n.consume(x),n.exit("lineEnding"),O(n,c,"linePrefix")):(n.enter("chunkString",{contentType:"string"}),p(x))}function p(x){return x===l||x===null||C(x)?(n.exit("chunkString"),c(x)):(n.consume(x),x===92?f:p)}function f(x){return x===l||x===92?(n.consume(x),p):p(x)}}function dn(n,r){let t;return e;function e(u){return C(u)?(n.enter("lineEnding"),n.consume(u),n.exit("lineEnding"),t=!0,e):z(u)?O(n,e,t?"linePrefix":"lineSuffix")(u):r(u)}}function xn(n){return n.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const ke={name:"definition",tokenize:be},de={tokenize:ye,partial:!0};function be(n,r,t){const e=this;let u;return i;function i(h){return n.enter("definition"),l(h)}function l(h){return ot.call(e,n,a,t,"definitionLabel","definitionLabelMarker","definitionLabelString")(h)}function a(h){return u=xn(e.sliceSerialize(e.events[e.events.length-1][1]).slice(1,-1)),h===58?(n.enter("definitionMarker"),n.consume(h),n.exit("definitionMarker"),m):t(h)}function m(h){return Z(h)?dn(n,c)(h):c(h)}function c(h){return at(n,p,t,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(h)}function p(h){return n.attempt(de,f,f)(h)}function f(h){return z(h)?O(n,x,"whitespace")(h):x(h)}function x(h){return h===null||C(h)?(n.exit("definition"),e.parser.defined.push(u),r(h)):t(h)}}function ye(n,r,t){return e;function e(a){return Z(a)?dn(n,u)(a):t(a)}function u(a){return st(n,i,t,"definitionTitle","definitionTitleMarker","definitionTitleString")(a)}function i(a){return z(a)?O(n,l,"whitespace")(a):l(a)}function l(a){return a===null||C(a)?r(a):t(a)}}const Se={name:"hardBreakEscape",tokenize:Fe};function Fe(n,r,t){return e;function e(i){return n.enter("hardBreakEscape"),n.consume(i),u}function u(i){return C(i)?(n.exit("hardBreakEscape"),r(i)):t(i)}}const Ee={name:"headingAtx",tokenize:we,resolve:Ce};function Ce(n,r){let t=n.length-2,e=3,u,i;return n[e][1].type==="whitespace"&&(e+=2),t-2>e&&n[t][1].type==="whitespace"&&(t-=2),n[t][1].type==="atxHeadingSequence"&&(e===t-1||t-4>e&&n[t-2][1].type==="whitespace")&&(t-=e+1===t?2:4),t>e&&(u={type:"atxHeadingText",start:n[e][1].start,end:n[t][1].end},i={type:"chunkText",start:n[e][1].start,end:n[t][1].end,contentType:"text"},tn(n,e,t-e+1,[["enter",u,r],["enter",i,r],["exit",i,r],["exit",u,r]])),n}function we(n,r,t){let e=0;return u;function u(p){return n.enter("atxHeading"),i(p)}function i(p){return n.enter("atxHeadingSequence"),l(p)}function l(p){return p===35&&e++<6?(n.consume(p),l):p===null||Z(p)?(n.exit("atxHeadingSequence"),a(p)):t(p)}function a(p){return p===35?(n.enter("atxHeadingSequence"),m(p)):p===null||C(p)?(n.exit("atxHeading"),r(p)):z(p)?O(n,a,"whitespace")(p):(n.enter("atxHeadingText"),c(p))}function m(p){return p===35?(n.consume(p),m):(n.exit("atxHeadingSequence"),a(p))}function c(p){return p===null||p===35||Z(p)?(n.exit("atxHeadingText"),a(p)):(n.consume(p),c)}}const Ae=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],Jn=["pre","script","style","textarea"],ze={name:"htmlFlow",tokenize:Le,resolveTo:Be,concrete:!0},Ie={tokenize:De,partial:!0},Te={tokenize:Oe,partial:!0};function Be(n){let r=n.length;for(;r--&&!(n[r][0]==="enter"&&n[r][1].type==="htmlFlow"););return r>1&&n[r-2][1].type==="linePrefix"&&(n[r][1].start=n[r-2][1].start,n[r+1][1].start=n[r-2][1].start,n.splice(r-2,2)),n}function Le(n,r,t){const e=this;let u,i,l,a,m;return c;function c(s){return p(s)}function p(s){return n.enter("htmlFlow"),n.enter("htmlFlowData"),n.consume(s),f}function f(s){return s===33?(n.consume(s),x):s===47?(n.consume(s),i=!0,I):s===63?(n.consume(s),u=3,e.interrupt?r:o):nn(s)?(n.consume(s),l=String.fromCharCode(s),M):t(s)}function x(s){return s===45?(n.consume(s),u=2,h):s===91?(n.consume(s),u=5,a=0,A):nn(s)?(n.consume(s),u=4,e.interrupt?r:o):t(s)}function h(s){return s===45?(n.consume(s),e.interrupt?r:o):t(s)}function A(s){const K="CDATA[";return s===K.charCodeAt(a++)?(n.consume(s),a===K.length?e.interrupt?r:S:A):t(s)}function I(s){return nn(s)?(n.consume(s),l=String.fromCharCode(s),M):t(s)}function M(s){if(s===null||s===47||s===62||Z(s)){const K=s===47,hn=l.toLowerCase();return!K&&!i&&Jn.includes(hn)?(u=1,e.interrupt?r(s):S(s)):Ae.includes(l.toLowerCase())?(u=6,K?(n.consume(s),b):e.interrupt?r(s):S(s)):(u=7,e.interrupt&&!e.parser.lazy[e.now().line]?t(s):i?j(s):F(s))}return s===45||v(s)?(n.consume(s),l+=String.fromCharCode(s),M):t(s)}function b(s){return s===62?(n.consume(s),e.interrupt?r:S):t(s)}function j(s){return z(s)?(n.consume(s),j):V(s)}function F(s){return s===47?(n.consume(s),V):s===58||s===95||nn(s)?(n.consume(s),D):z(s)?(n.consume(s),F):V(s)}function D(s){return s===45||s===46||s===58||s===95||v(s)?(n.consume(s),D):_(s)}function _(s){return s===61?(n.consume(s),k):z(s)?(n.consume(s),_):F(s)}function k(s){return s===null||s===60||s===61||s===62||s===96?t(s):s===34||s===39?(n.consume(s),m=s,T):z(s)?(n.consume(s),k):H(s)}function T(s){return s===m?(n.consume(s),m=null,N):s===null||C(s)?t(s):(n.consume(s),T)}function H(s){return s===null||s===34||s===39||s===47||s===60||s===61||s===62||s===96||Z(s)?_(s):(n.consume(s),H)}function N(s){return s===47||s===62||z(s)?F(s):t(s)}function V(s){return s===62?(n.consume(s),y):t(s)}function y(s){return s===null||C(s)?S(s):z(s)?(n.consume(s),y):t(s)}function S(s){return s===45&&u===2?(n.consume(s),U):s===60&&u===1?(n.consume(s),W):s===62&&u===4?(n.consume(s),J):s===63&&u===3?(n.consume(s),o):s===93&&u===5?(n.consume(s),en):C(s)&&(u===6||u===7)?(n.exit("htmlFlowData"),n.check(Ie,rn,P)(s)):s===null||C(s)?(n.exit("htmlFlowData"),P(s)):(n.consume(s),S)}function P(s){return n.check(Te,R,rn)(s)}function R(s){return n.enter("lineEnding"),n.consume(s),n.exit("lineEnding"),w}function w(s){return s===null||C(s)?P(s):(n.enter("htmlFlowData"),S(s))}function U(s){return s===45?(n.consume(s),o):S(s)}function W(s){return s===47?(n.consume(s),l="",G):S(s)}function G(s){if(s===62){const K=l.toLowerCase();return Jn.includes(K)?(n.consume(s),J):S(s)}return nn(s)&&l.length<8?(n.consume(s),l+=String.fromCharCode(s),G):S(s)}function en(s){return s===93?(n.consume(s),o):S(s)}function o(s){return s===62?(n.consume(s),J):s===45&&u===2?(n.consume(s),o):S(s)}function J(s){return s===null||C(s)?(n.exit("htmlFlowData"),rn(s)):(n.consume(s),J)}function rn(s){return n.exit("htmlFlow"),r(s)}}function Oe(n,r,t){const e=this;return u;function u(l){return C(l)?(n.enter("lineEnding"),n.consume(l),n.exit("lineEnding"),i):t(l)}function i(l){return e.parser.lazy[e.now().line]?t(l):r(l)}}function De(n,r,t){return e;function e(u){return n.enter("lineEnding"),n.consume(u),n.exit("lineEnding"),n.attempt(Sn,r,t)}}const Pe={name:"htmlText",tokenize:_e};function _e(n,r,t){const e=this;let u,i,l;return a;function a(o){return n.enter("htmlText"),n.enter("htmlTextData"),n.consume(o),m}function m(o){return o===33?(n.consume(o),c):o===47?(n.consume(o),_):o===63?(n.consume(o),F):nn(o)?(n.consume(o),H):t(o)}function c(o){return o===45?(n.consume(o),p):o===91?(n.consume(o),i=0,A):nn(o)?(n.consume(o),j):t(o)}function p(o){return o===45?(n.consume(o),h):t(o)}function f(o){return o===null?t(o):o===45?(n.consume(o),x):C(o)?(l=f,W(o)):(n.consume(o),f)}function x(o){return o===45?(n.consume(o),h):f(o)}function h(o){return o===62?U(o):o===45?x(o):f(o)}function A(o){const J="CDATA[";return o===J.charCodeAt(i++)?(n.consume(o),i===J.length?I:A):t(o)}function I(o){return o===null?t(o):o===93?(n.consume(o),M):C(o)?(l=I,W(o)):(n.consume(o),I)}function M(o){return o===93?(n.consume(o),b):I(o)}function b(o){return o===62?U(o):o===93?(n.consume(o),b):I(o)}function j(o){return o===null||o===62?U(o):C(o)?(l=j,W(o)):(n.consume(o),j)}function F(o){return o===null?t(o):o===63?(n.consume(o),D):C(o)?(l=F,W(o)):(n.consume(o),F)}function D(o){return o===62?U(o):F(o)}function _(o){return nn(o)?(n.consume(o),k):t(o)}function k(o){return o===45||v(o)?(n.consume(o),k):T(o)}function T(o){return C(o)?(l=T,W(o)):z(o)?(n.consume(o),T):U(o)}function H(o){return o===45||v(o)?(n.consume(o),H):o===47||o===62||Z(o)?N(o):t(o)}function N(o){return o===47?(n.consume(o),U):o===58||o===95||nn(o)?(n.consume(o),V):C(o)?(l=N,W(o)):z(o)?(n.consume(o),N):U(o)}function V(o){return o===45||o===46||o===58||o===95||v(o)?(n.consume(o),V):y(o)}function y(o){return o===61?(n.consume(o),S):C(o)?(l=y,W(o)):z(o)?(n.consume(o),y):N(o)}function S(o){return o===null||o===60||o===61||o===62||o===96?t(o):o===34||o===39?(n.consume(o),u=o,P):C(o)?(l=S,W(o)):z(o)?(n.consume(o),S):(n.consume(o),R)}function P(o){return o===u?(n.consume(o),u=void 0,w):o===null?t(o):C(o)?(l=P,W(o)):(n.consume(o),P)}function R(o){return o===null||o===34||o===39||o===60||o===61||o===96?t(o):o===47||o===62||Z(o)?N(o):(n.consume(o),R)}function w(o){return o===47||o===62||Z(o)?N(o):t(o)}function U(o){return o===62?(n.consume(o),n.exit("htmlTextData"),n.exit("htmlText"),r):t(o)}function W(o){return n.exit("htmlTextData"),n.enter("lineEnding"),n.consume(o),n.exit("lineEnding"),G}function G(o){return z(o)?O(n,en,"linePrefix",e.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(o):en(o)}function en(o){return n.enter("htmlTextData"),l(o)}}const Dn={name:"labelEnd",tokenize:Ne,resolveTo:He,resolveAll:qe},Me={tokenize:Ve},je={tokenize:We},Re={tokenize:Qe};function qe(n){let r=-1;for(;++r=3&&(c===null||C(c))?(n.exit("thematicBreak"),r(c)):t(c)}function m(c){return c===u?(n.consume(c),e++,m):(n.exit("thematicBreakSequence"),z(c)?O(n,a,"whitespace")(c):a(c))}}const $={name:"list",tokenize:ve,continuation:{tokenize:nr},exit:er},Ke={tokenize:rr,partial:!0},Xe={tokenize:tr,partial:!0};function ve(n,r,t){const e=this,u=e.events[e.events.length-1];let i=u&&u[1].type==="linePrefix"?u[2].sliceSerialize(u[1],!0).length:0,l=0;return a;function a(h){const A=e.containerState.type||(h===42||h===43||h===45?"listUnordered":"listOrdered");if(A==="listUnordered"?!e.containerState.marker||h===e.containerState.marker:zn(h)){if(e.containerState.type||(e.containerState.type=A,n.enter(A,{_container:!0})),A==="listUnordered")return n.enter("listItemPrefix"),h===42||h===45?n.check(bn,t,c)(h):c(h);if(!e.interrupt||h===49)return n.enter("listItemPrefix"),n.enter("listItemValue"),m(h)}return t(h)}function m(h){return zn(h)&&++l<10?(n.consume(h),m):(!e.interrupt||l<2)&&(e.containerState.marker?h===e.containerState.marker:h===41||h===46)?(n.exit("listItemValue"),c(h)):t(h)}function c(h){return n.enter("listItemMarker"),n.consume(h),n.exit("listItemMarker"),e.containerState.marker=e.containerState.marker||h,n.check(Sn,e.interrupt?t:p,n.attempt(Ke,x,f))}function p(h){return e.containerState.initialBlankLine=!0,i++,x(h)}function f(h){return z(h)?(n.enter("listItemPrefixWhitespace"),n.consume(h),n.exit("listItemPrefixWhitespace"),x):t(h)}function x(h){return e.containerState.size=i+e.sliceSerialize(n.exit("listItemPrefix"),!0).length,r(h)}}function nr(n,r,t){const e=this;return e.containerState._closeFlow=void 0,n.check(Sn,u,i);function u(a){return e.containerState.furtherBlankLines=e.containerState.furtherBlankLines||e.containerState.initialBlankLine,O(n,r,"listItemIndent",e.containerState.size+1)(a)}function i(a){return e.containerState.furtherBlankLines||!z(a)?(e.containerState.furtherBlankLines=void 0,e.containerState.initialBlankLine=void 0,l(a)):(e.containerState.furtherBlankLines=void 0,e.containerState.initialBlankLine=void 0,n.attempt(Xe,r,l)(a))}function l(a){return e.containerState._closeFlow=!0,e.interrupt=void 0,O(n,n.attempt($,r,t),"linePrefix",e.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(a)}}function tr(n,r,t){const e=this;return O(n,u,"listItemIndent",e.containerState.size+1);function u(i){const l=e.events[e.events.length-1];return l&&l[1].type==="listItemIndent"&&l[2].sliceSerialize(l[1],!0).length===e.containerState.size?r(i):t(i)}}function er(n){n.exit(this.containerState.type)}function rr(n,r,t){const e=this;return O(n,u,"listItemPrefixWhitespace",e.parser.constructs.disable.null.includes("codeIndented")?void 0:5);function u(i){const l=e.events[e.events.length-1];return!z(i)&&l&&l[1].type==="listItemPrefixWhitespace"?r(i):t(i)}}const Kn={name:"setextUnderline",tokenize:ur,resolveTo:ir};function ir(n,r){let t=n.length,e,u,i;for(;t--;)if(n[t][0]==="enter"){if(n[t][1].type==="content"){e=t;break}n[t][1].type==="paragraph"&&(u=t)}else n[t][1].type==="content"&&n.splice(t,1),!i&&n[t][1].type==="definition"&&(i=t);const l={type:"setextHeading",start:Object.assign({},n[u][1].start),end:Object.assign({},n[n.length-1][1].end)};return n[u][1].type="setextHeadingText",i?(n.splice(u,0,["enter",l,r]),n.splice(i+1,0,["exit",n[e][1],r]),n[e][1].end=Object.assign({},n[i][1].end)):n[e][1]=l,n.push(["exit",l,r]),n}function ur(n,r,t){const e=this;let u;return i;function i(c){let p=e.events.length,f;for(;p--;)if(e.events[p][1].type!=="lineEnding"&&e.events[p][1].type!=="linePrefix"&&e.events[p][1].type!=="content"){f=e.events[p][1].type==="paragraph";break}return!e.parser.lazy[e.now().line]&&(e.interrupt||f)?(n.enter("setextHeadingLine"),u=c,l(c)):t(c)}function l(c){return n.enter("setextHeadingLineSequence"),a(c)}function a(c){return c===u?(n.consume(c),a):(n.exit("setextHeadingLineSequence"),z(c)?O(n,m,"lineSuffix")(c):m(c))}function m(c){return c===null||C(c)?(n.exit("setextHeadingLine"),r(c)):t(c)}}const lr={tokenize:ar};function ar(n){const r=this,t=n.attempt(Sn,e,n.attempt(this.parser.constructs.flowInitial,u,O(n,n.attempt(this.parser.constructs.flow,u,n.attempt(pe,u)),"linePrefix")));return t;function e(i){if(i===null){n.consume(i);return}return n.enter("lineEndingBlank"),n.consume(i),n.exit("lineEndingBlank"),r.currentConstruct=void 0,t}function u(i){if(i===null){n.consume(i);return}return n.enter("lineEnding"),n.consume(i),n.exit("lineEnding"),r.currentConstruct=void 0,t}}const or={resolveAll:ht()},sr=ct("string"),cr=ct("text");function ct(n){return{tokenize:r,resolveAll:ht(n==="text"?hr:void 0)};function r(t){const e=this,u=this.parser.constructs[n],i=t.attempt(u,l,a);return l;function l(p){return c(p)?i(p):a(p)}function a(p){if(p===null){t.consume(p);return}return t.enter("data"),t.consume(p),m}function m(p){return c(p)?(t.exit("data"),i(p)):(t.consume(p),m)}function c(p){if(p===null)return!0;const f=u[p];let x=-1;if(f)for(;++x-1){const a=l[0];typeof a=="string"?l[0]=a.slice(e):l.shift()}i>0&&l.push(n[u].slice(0,i))}return l}function mr(n,r){let t=-1;const e=[];let u;for(;++tu?0:u+r:r=r>u?u:r,t=t>0?t:0,e.length<1e4)l=Array.from(e),l.unshift(r,t),n.splice(...l);else for(t&&n.splice(r,t);i0?(tn(n,n.length,0,r),n):r}const Wn={}.hasOwnProperty;function Ot(n){const r={};let t=-1;for(;++tl))return;const T=r.events.length;let H=T,N,V;for(;H--;)if(r.events[H][0]==="exit"&&r.events[H][1].type==="chunkFlow"){if(N){V=r.events[H][1].end;break}N=!0}for(b(e),k=T;kF;){const _=t[D];r.containerState=_[1],_[0].exit.call(r,n)}t.length=F}function j(){u.write([null]),i=void 0,u=void 0,r.containerState._closeFlow=void 0}}function Ut(n,r,t){return O(n,n.attempt(this.parser.constructs.document,r,t),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function Un(n){if(n===null||Z(n)||Ht(n))return 1;if(qt(n))return 2}function Ln(n,r,t){const e=[];let u=-1;for(;++u1&&n[t][1].end.offset-n[t][1].start.offset>1?2:1;const f=Object.assign({},n[e][1].end),x=Object.assign({},n[t][1].start);$n(f,-m),$n(x,m),l={type:m>1?"strongSequence":"emphasisSequence",start:f,end:Object.assign({},n[e][1].end)},a={type:m>1?"strongSequence":"emphasisSequence",start:Object.assign({},n[t][1].start),end:x},i={type:m>1?"strongText":"emphasisText",start:Object.assign({},n[e][1].end),end:Object.assign({},n[t][1].start)},u={type:m>1?"strong":"emphasis",start:Object.assign({},l.start),end:Object.assign({},a.end)},n[e][1].end=Object.assign({},l.start),n[t][1].start=Object.assign({},a.end),c=[],n[e][1].end.offset-n[e][1].start.offset&&(c=Y(c,[["enter",n[e][1],r],["exit",n[e][1],r]])),c=Y(c,[["enter",u,r],["enter",l,r],["exit",l,r],["enter",i,r]]),c=Y(c,Ln(r.parser.constructs.insideSpan.null,n.slice(e+1,t),r)),c=Y(c,[["exit",i,r],["enter",a,r],["exit",a,r],["exit",u,r]]),n[t][1].end.offset-n[t][1].start.offset?(p=2,c=Y(c,[["enter",n[t][1],r],["exit",n[t][1],r]])):p=0,tn(n,e-1,t-e+3,c),t=e+c.length-p-2;break}}for(t=-1;++t0&&z(k)?O(n,j,"linePrefix",i+1)(k):j(k)}function j(k){return k===null||C(k)?n.check(Yn,I,D)(k):(n.enter("codeFlowValue"),F(k))}function F(k){return k===null||C(k)?(n.exit("codeFlowValue"),j(k)):(n.consume(k),F)}function D(k){return n.exit("codeFenced"),r(k)}function _(k,T,H){let N=0;return V;function V(w){return k.enter("lineEnding"),k.consume(w),k.exit("lineEnding"),y}function y(w){return k.enter("codeFencedFence"),z(w)?O(k,S,"linePrefix",e.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(w):S(w)}function S(w){return w===a?(k.enter("codeFencedFenceSequence"),P(w)):H(w)}function P(w){return w===a?(N++,k.consume(w),P):N>=l?(k.exit("codeFencedFenceSequence"),z(w)?O(k,R,"whitespace")(w):R(w)):H(w)}function R(w){return w===null||C(w)?(k.exit("codeFencedFence"),T(w)):H(w)}}}function re(n,r,t){const e=this;return u;function u(l){return l===null?t(l):(n.enter("lineEnding"),n.consume(l),n.exit("lineEnding"),i)}function i(l){return e.parser.lazy[e.now().line]?t(l):r(l)}}const Cn={name:"codeIndented",tokenize:ue},ie={tokenize:le,partial:!0};function ue(n,r,t){const e=this;return u;function u(c){return n.enter("codeIndented"),O(n,i,"linePrefix",5)(c)}function i(c){const p=e.events[e.events.length-1];return p&&p[1].type==="linePrefix"&&p[2].sliceSerialize(p[1],!0).length>=4?l(c):t(c)}function l(c){return c===null?m(c):C(c)?n.attempt(ie,l,m)(c):(n.enter("codeFlowValue"),a(c))}function a(c){return c===null||C(c)?(n.exit("codeFlowValue"),l(c)):(n.consume(c),a)}function m(c){return n.exit("codeIndented"),r(c)}}function le(n,r,t){const e=this;return u;function u(l){return e.parser.lazy[e.now().line]?t(l):C(l)?(n.enter("lineEnding"),n.consume(l),n.exit("lineEnding"),u):O(n,i,"linePrefix",5)(l)}function i(l){const a=e.events[e.events.length-1];return a&&a[1].type==="linePrefix"&&a[2].sliceSerialize(a[1],!0).length>=4?r(l):C(l)?u(l):t(l)}}const ae={name:"codeText",tokenize:ce,resolve:oe,previous:se};function oe(n){let r=n.length-4,t=3,e,u;if((n[t][1].type==="lineEnding"||n[t][1].type==="space")&&(n[r][1].type==="lineEnding"||n[r][1].type==="space")){for(e=t;++e=4?r(l):n.interrupt(e.parser.constructs.flow,t,r)(l)}}function at(n,r,t,e,u,i,l,a,m){const c=m||Number.POSITIVE_INFINITY;let p=0;return f;function f(b){return b===60?(n.enter(e),n.enter(u),n.enter(i),n.consume(b),n.exit(i),x):b===null||b===32||b===41||An(b)?t(b):(n.enter(e),n.enter(l),n.enter(a),n.enter("chunkString",{contentType:"string"}),I(b))}function x(b){return b===62?(n.enter(i),n.consume(b),n.exit(i),n.exit(u),n.exit(e),r):(n.enter(a),n.enter("chunkString",{contentType:"string"}),h(b))}function h(b){return b===62?(n.exit("chunkString"),n.exit(a),x(b)):b===null||b===60||C(b)?t(b):(n.consume(b),b===92?A:h)}function A(b){return b===60||b===62||b===92?(n.consume(b),h):h(b)}function I(b){return!p&&(b===null||b===41||Z(b))?(n.exit("chunkString"),n.exit(a),n.exit(l),n.exit(e),r(b)):p999||h===null||h===91||h===93&&!m||h===94&&!a&&"_hiddenFootnoteSupport"in l.parser.constructs?t(h):h===93?(n.exit(i),n.enter(u),n.consume(h),n.exit(u),n.exit(e),r):C(h)?(n.enter("lineEnding"),n.consume(h),n.exit("lineEnding"),p):(n.enter("chunkString",{contentType:"string"}),f(h))}function f(h){return h===null||h===91||h===93||C(h)||a++>999?(n.exit("chunkString"),p(h)):(n.consume(h),m||(m=!z(h)),h===92?x:f)}function x(h){return h===91||h===92||h===93?(n.consume(h),a++,f):f(h)}}function st(n,r,t,e,u,i){let l;return a;function a(x){return x===34||x===39||x===40?(n.enter(e),n.enter(u),n.consume(x),n.exit(u),l=x===40?41:x,m):t(x)}function m(x){return x===l?(n.enter(u),n.consume(x),n.exit(u),n.exit(e),r):(n.enter(i),c(x))}function c(x){return x===l?(n.exit(i),m(l)):x===null?t(x):C(x)?(n.enter("lineEnding"),n.consume(x),n.exit("lineEnding"),O(n,c,"linePrefix")):(n.enter("chunkString",{contentType:"string"}),p(x))}function p(x){return x===l||x===null||C(x)?(n.exit("chunkString"),c(x)):(n.consume(x),x===92?f:p)}function f(x){return x===l||x===92?(n.consume(x),p):p(x)}}function dn(n,r){let t;return e;function e(u){return C(u)?(n.enter("lineEnding"),n.consume(u),n.exit("lineEnding"),t=!0,e):z(u)?O(n,e,t?"linePrefix":"lineSuffix")(u):r(u)}}function xn(n){return n.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const ke={name:"definition",tokenize:be},de={tokenize:ye,partial:!0};function be(n,r,t){const e=this;let u;return i;function i(h){return n.enter("definition"),l(h)}function l(h){return ot.call(e,n,a,t,"definitionLabel","definitionLabelMarker","definitionLabelString")(h)}function a(h){return u=xn(e.sliceSerialize(e.events[e.events.length-1][1]).slice(1,-1)),h===58?(n.enter("definitionMarker"),n.consume(h),n.exit("definitionMarker"),m):t(h)}function m(h){return Z(h)?dn(n,c)(h):c(h)}function c(h){return at(n,p,t,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(h)}function p(h){return n.attempt(de,f,f)(h)}function f(h){return z(h)?O(n,x,"whitespace")(h):x(h)}function x(h){return h===null||C(h)?(n.exit("definition"),e.parser.defined.push(u),r(h)):t(h)}}function ye(n,r,t){return e;function e(a){return Z(a)?dn(n,u)(a):t(a)}function u(a){return st(n,i,t,"definitionTitle","definitionTitleMarker","definitionTitleString")(a)}function i(a){return z(a)?O(n,l,"whitespace")(a):l(a)}function l(a){return a===null||C(a)?r(a):t(a)}}const Se={name:"hardBreakEscape",tokenize:Fe};function Fe(n,r,t){return e;function e(i){return n.enter("hardBreakEscape"),n.consume(i),u}function u(i){return C(i)?(n.exit("hardBreakEscape"),r(i)):t(i)}}const Ee={name:"headingAtx",tokenize:we,resolve:Ce};function Ce(n,r){let t=n.length-2,e=3,u,i;return n[e][1].type==="whitespace"&&(e+=2),t-2>e&&n[t][1].type==="whitespace"&&(t-=2),n[t][1].type==="atxHeadingSequence"&&(e===t-1||t-4>e&&n[t-2][1].type==="whitespace")&&(t-=e+1===t?2:4),t>e&&(u={type:"atxHeadingText",start:n[e][1].start,end:n[t][1].end},i={type:"chunkText",start:n[e][1].start,end:n[t][1].end,contentType:"text"},tn(n,e,t-e+1,[["enter",u,r],["enter",i,r],["exit",i,r],["exit",u,r]])),n}function we(n,r,t){let e=0;return u;function u(p){return n.enter("atxHeading"),i(p)}function i(p){return n.enter("atxHeadingSequence"),l(p)}function l(p){return p===35&&e++<6?(n.consume(p),l):p===null||Z(p)?(n.exit("atxHeadingSequence"),a(p)):t(p)}function a(p){return p===35?(n.enter("atxHeadingSequence"),m(p)):p===null||C(p)?(n.exit("atxHeading"),r(p)):z(p)?O(n,a,"whitespace")(p):(n.enter("atxHeadingText"),c(p))}function m(p){return p===35?(n.consume(p),m):(n.exit("atxHeadingSequence"),a(p))}function c(p){return p===null||p===35||Z(p)?(n.exit("atxHeadingText"),a(p)):(n.consume(p),c)}}const Ae=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],Jn=["pre","script","style","textarea"],ze={name:"htmlFlow",tokenize:Le,resolveTo:Be,concrete:!0},Ie={tokenize:De,partial:!0},Te={tokenize:Oe,partial:!0};function Be(n){let r=n.length;for(;r--&&!(n[r][0]==="enter"&&n[r][1].type==="htmlFlow"););return r>1&&n[r-2][1].type==="linePrefix"&&(n[r][1].start=n[r-2][1].start,n[r+1][1].start=n[r-2][1].start,n.splice(r-2,2)),n}function Le(n,r,t){const e=this;let u,i,l,a,m;return c;function c(s){return p(s)}function p(s){return n.enter("htmlFlow"),n.enter("htmlFlowData"),n.consume(s),f}function f(s){return s===33?(n.consume(s),x):s===47?(n.consume(s),i=!0,I):s===63?(n.consume(s),u=3,e.interrupt?r:o):nn(s)?(n.consume(s),l=String.fromCharCode(s),M):t(s)}function x(s){return s===45?(n.consume(s),u=2,h):s===91?(n.consume(s),u=5,a=0,A):nn(s)?(n.consume(s),u=4,e.interrupt?r:o):t(s)}function h(s){return s===45?(n.consume(s),e.interrupt?r:o):t(s)}function A(s){const K="CDATA[";return s===K.charCodeAt(a++)?(n.consume(s),a===K.length?e.interrupt?r:S:A):t(s)}function I(s){return nn(s)?(n.consume(s),l=String.fromCharCode(s),M):t(s)}function M(s){if(s===null||s===47||s===62||Z(s)){const K=s===47,hn=l.toLowerCase();return!K&&!i&&Jn.includes(hn)?(u=1,e.interrupt?r(s):S(s)):Ae.includes(l.toLowerCase())?(u=6,K?(n.consume(s),b):e.interrupt?r(s):S(s)):(u=7,e.interrupt&&!e.parser.lazy[e.now().line]?t(s):i?j(s):F(s))}return s===45||v(s)?(n.consume(s),l+=String.fromCharCode(s),M):t(s)}function b(s){return s===62?(n.consume(s),e.interrupt?r:S):t(s)}function j(s){return z(s)?(n.consume(s),j):V(s)}function F(s){return s===47?(n.consume(s),V):s===58||s===95||nn(s)?(n.consume(s),D):z(s)?(n.consume(s),F):V(s)}function D(s){return s===45||s===46||s===58||s===95||v(s)?(n.consume(s),D):_(s)}function _(s){return s===61?(n.consume(s),k):z(s)?(n.consume(s),_):F(s)}function k(s){return s===null||s===60||s===61||s===62||s===96?t(s):s===34||s===39?(n.consume(s),m=s,T):z(s)?(n.consume(s),k):H(s)}function T(s){return s===m?(n.consume(s),m=null,N):s===null||C(s)?t(s):(n.consume(s),T)}function H(s){return s===null||s===34||s===39||s===47||s===60||s===61||s===62||s===96||Z(s)?_(s):(n.consume(s),H)}function N(s){return s===47||s===62||z(s)?F(s):t(s)}function V(s){return s===62?(n.consume(s),y):t(s)}function y(s){return s===null||C(s)?S(s):z(s)?(n.consume(s),y):t(s)}function S(s){return s===45&&u===2?(n.consume(s),U):s===60&&u===1?(n.consume(s),W):s===62&&u===4?(n.consume(s),J):s===63&&u===3?(n.consume(s),o):s===93&&u===5?(n.consume(s),en):C(s)&&(u===6||u===7)?(n.exit("htmlFlowData"),n.check(Ie,rn,P)(s)):s===null||C(s)?(n.exit("htmlFlowData"),P(s)):(n.consume(s),S)}function P(s){return n.check(Te,R,rn)(s)}function R(s){return n.enter("lineEnding"),n.consume(s),n.exit("lineEnding"),w}function w(s){return s===null||C(s)?P(s):(n.enter("htmlFlowData"),S(s))}function U(s){return s===45?(n.consume(s),o):S(s)}function W(s){return s===47?(n.consume(s),l="",G):S(s)}function G(s){if(s===62){const K=l.toLowerCase();return Jn.includes(K)?(n.consume(s),J):S(s)}return nn(s)&&l.length<8?(n.consume(s),l+=String.fromCharCode(s),G):S(s)}function en(s){return s===93?(n.consume(s),o):S(s)}function o(s){return s===62?(n.consume(s),J):s===45&&u===2?(n.consume(s),o):S(s)}function J(s){return s===null||C(s)?(n.exit("htmlFlowData"),rn(s)):(n.consume(s),J)}function rn(s){return n.exit("htmlFlow"),r(s)}}function Oe(n,r,t){const e=this;return u;function u(l){return C(l)?(n.enter("lineEnding"),n.consume(l),n.exit("lineEnding"),i):t(l)}function i(l){return e.parser.lazy[e.now().line]?t(l):r(l)}}function De(n,r,t){return e;function e(u){return n.enter("lineEnding"),n.consume(u),n.exit("lineEnding"),n.attempt(Sn,r,t)}}const Pe={name:"htmlText",tokenize:_e};function _e(n,r,t){const e=this;let u,i,l;return a;function a(o){return n.enter("htmlText"),n.enter("htmlTextData"),n.consume(o),m}function m(o){return o===33?(n.consume(o),c):o===47?(n.consume(o),_):o===63?(n.consume(o),F):nn(o)?(n.consume(o),H):t(o)}function c(o){return o===45?(n.consume(o),p):o===91?(n.consume(o),i=0,A):nn(o)?(n.consume(o),j):t(o)}function p(o){return o===45?(n.consume(o),h):t(o)}function f(o){return o===null?t(o):o===45?(n.consume(o),x):C(o)?(l=f,W(o)):(n.consume(o),f)}function x(o){return o===45?(n.consume(o),h):f(o)}function h(o){return o===62?U(o):o===45?x(o):f(o)}function A(o){const J="CDATA[";return o===J.charCodeAt(i++)?(n.consume(o),i===J.length?I:A):t(o)}function I(o){return o===null?t(o):o===93?(n.consume(o),M):C(o)?(l=I,W(o)):(n.consume(o),I)}function M(o){return o===93?(n.consume(o),b):I(o)}function b(o){return o===62?U(o):o===93?(n.consume(o),b):I(o)}function j(o){return o===null||o===62?U(o):C(o)?(l=j,W(o)):(n.consume(o),j)}function F(o){return o===null?t(o):o===63?(n.consume(o),D):C(o)?(l=F,W(o)):(n.consume(o),F)}function D(o){return o===62?U(o):F(o)}function _(o){return nn(o)?(n.consume(o),k):t(o)}function k(o){return o===45||v(o)?(n.consume(o),k):T(o)}function T(o){return C(o)?(l=T,W(o)):z(o)?(n.consume(o),T):U(o)}function H(o){return o===45||v(o)?(n.consume(o),H):o===47||o===62||Z(o)?N(o):t(o)}function N(o){return o===47?(n.consume(o),U):o===58||o===95||nn(o)?(n.consume(o),V):C(o)?(l=N,W(o)):z(o)?(n.consume(o),N):U(o)}function V(o){return o===45||o===46||o===58||o===95||v(o)?(n.consume(o),V):y(o)}function y(o){return o===61?(n.consume(o),S):C(o)?(l=y,W(o)):z(o)?(n.consume(o),y):N(o)}function S(o){return o===null||o===60||o===61||o===62||o===96?t(o):o===34||o===39?(n.consume(o),u=o,P):C(o)?(l=S,W(o)):z(o)?(n.consume(o),S):(n.consume(o),R)}function P(o){return o===u?(n.consume(o),u=void 0,w):o===null?t(o):C(o)?(l=P,W(o)):(n.consume(o),P)}function R(o){return o===null||o===34||o===39||o===60||o===61||o===96?t(o):o===47||o===62||Z(o)?N(o):(n.consume(o),R)}function w(o){return o===47||o===62||Z(o)?N(o):t(o)}function U(o){return o===62?(n.consume(o),n.exit("htmlTextData"),n.exit("htmlText"),r):t(o)}function W(o){return n.exit("htmlTextData"),n.enter("lineEnding"),n.consume(o),n.exit("lineEnding"),G}function G(o){return z(o)?O(n,en,"linePrefix",e.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(o):en(o)}function en(o){return n.enter("htmlTextData"),l(o)}}const Dn={name:"labelEnd",tokenize:Ne,resolveTo:He,resolveAll:qe},Me={tokenize:Ve},je={tokenize:We},Re={tokenize:Qe};function qe(n){let r=-1;for(;++r=3&&(c===null||C(c))?(n.exit("thematicBreak"),r(c)):t(c)}function m(c){return c===u?(n.consume(c),e++,m):(n.exit("thematicBreakSequence"),z(c)?O(n,a,"whitespace")(c):a(c))}}const $={name:"list",tokenize:ve,continuation:{tokenize:nr},exit:er},Ke={tokenize:rr,partial:!0},Xe={tokenize:tr,partial:!0};function ve(n,r,t){const e=this,u=e.events[e.events.length-1];let i=u&&u[1].type==="linePrefix"?u[2].sliceSerialize(u[1],!0).length:0,l=0;return a;function a(h){const A=e.containerState.type||(h===42||h===43||h===45?"listUnordered":"listOrdered");if(A==="listUnordered"?!e.containerState.marker||h===e.containerState.marker:zn(h)){if(e.containerState.type||(e.containerState.type=A,n.enter(A,{_container:!0})),A==="listUnordered")return n.enter("listItemPrefix"),h===42||h===45?n.check(bn,t,c)(h):c(h);if(!e.interrupt||h===49)return n.enter("listItemPrefix"),n.enter("listItemValue"),m(h)}return t(h)}function m(h){return zn(h)&&++l<10?(n.consume(h),m):(!e.interrupt||l<2)&&(e.containerState.marker?h===e.containerState.marker:h===41||h===46)?(n.exit("listItemValue"),c(h)):t(h)}function c(h){return n.enter("listItemMarker"),n.consume(h),n.exit("listItemMarker"),e.containerState.marker=e.containerState.marker||h,n.check(Sn,e.interrupt?t:p,n.attempt(Ke,x,f))}function p(h){return e.containerState.initialBlankLine=!0,i++,x(h)}function f(h){return z(h)?(n.enter("listItemPrefixWhitespace"),n.consume(h),n.exit("listItemPrefixWhitespace"),x):t(h)}function x(h){return e.containerState.size=i+e.sliceSerialize(n.exit("listItemPrefix"),!0).length,r(h)}}function nr(n,r,t){const e=this;return e.containerState._closeFlow=void 0,n.check(Sn,u,i);function u(a){return e.containerState.furtherBlankLines=e.containerState.furtherBlankLines||e.containerState.initialBlankLine,O(n,r,"listItemIndent",e.containerState.size+1)(a)}function i(a){return e.containerState.furtherBlankLines||!z(a)?(e.containerState.furtherBlankLines=void 0,e.containerState.initialBlankLine=void 0,l(a)):(e.containerState.furtherBlankLines=void 0,e.containerState.initialBlankLine=void 0,n.attempt(Xe,r,l)(a))}function l(a){return e.containerState._closeFlow=!0,e.interrupt=void 0,O(n,n.attempt($,r,t),"linePrefix",e.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(a)}}function tr(n,r,t){const e=this;return O(n,u,"listItemIndent",e.containerState.size+1);function u(i){const l=e.events[e.events.length-1];return l&&l[1].type==="listItemIndent"&&l[2].sliceSerialize(l[1],!0).length===e.containerState.size?r(i):t(i)}}function er(n){n.exit(this.containerState.type)}function rr(n,r,t){const e=this;return O(n,u,"listItemPrefixWhitespace",e.parser.constructs.disable.null.includes("codeIndented")?void 0:5);function u(i){const l=e.events[e.events.length-1];return!z(i)&&l&&l[1].type==="listItemPrefixWhitespace"?r(i):t(i)}}const Kn={name:"setextUnderline",tokenize:ur,resolveTo:ir};function ir(n,r){let t=n.length,e,u,i;for(;t--;)if(n[t][0]==="enter"){if(n[t][1].type==="content"){e=t;break}n[t][1].type==="paragraph"&&(u=t)}else n[t][1].type==="content"&&n.splice(t,1),!i&&n[t][1].type==="definition"&&(i=t);const l={type:"setextHeading",start:Object.assign({},n[u][1].start),end:Object.assign({},n[n.length-1][1].end)};return n[u][1].type="setextHeadingText",i?(n.splice(u,0,["enter",l,r]),n.splice(i+1,0,["exit",n[e][1],r]),n[e][1].end=Object.assign({},n[i][1].end)):n[e][1]=l,n.push(["exit",l,r]),n}function ur(n,r,t){const e=this;let u;return i;function i(c){let p=e.events.length,f;for(;p--;)if(e.events[p][1].type!=="lineEnding"&&e.events[p][1].type!=="linePrefix"&&e.events[p][1].type!=="content"){f=e.events[p][1].type==="paragraph";break}return!e.parser.lazy[e.now().line]&&(e.interrupt||f)?(n.enter("setextHeadingLine"),u=c,l(c)):t(c)}function l(c){return n.enter("setextHeadingLineSequence"),a(c)}function a(c){return c===u?(n.consume(c),a):(n.exit("setextHeadingLineSequence"),z(c)?O(n,m,"lineSuffix")(c):m(c))}function m(c){return c===null||C(c)?(n.exit("setextHeadingLine"),r(c)):t(c)}}const lr={tokenize:ar};function ar(n){const r=this,t=n.attempt(Sn,e,n.attempt(this.parser.constructs.flowInitial,u,O(n,n.attempt(this.parser.constructs.flow,u,n.attempt(pe,u)),"linePrefix")));return t;function e(i){if(i===null){n.consume(i);return}return n.enter("lineEndingBlank"),n.consume(i),n.exit("lineEndingBlank"),r.currentConstruct=void 0,t}function u(i){if(i===null){n.consume(i);return}return n.enter("lineEnding"),n.consume(i),n.exit("lineEnding"),r.currentConstruct=void 0,t}}const or={resolveAll:ht()},sr=ct("string"),cr=ct("text");function ct(n){return{tokenize:r,resolveAll:ht(n==="text"?hr:void 0)};function r(t){const e=this,u=this.parser.constructs[n],i=t.attempt(u,l,a);return l;function l(p){return c(p)?i(p):a(p)}function a(p){if(p===null){t.consume(p);return}return t.enter("data"),t.consume(p),m}function m(p){return c(p)?(t.exit("data"),i(p)):(t.consume(p),m)}function c(p){if(p===null)return!0;const f=u[p];let x=-1;if(f)for(;++x-1){const a=l[0];typeof a=="string"?l[0]=a.slice(e):l.shift()}i>0&&l.push(n[u].slice(0,i))}return l}function mr(n,r){let t=-1;const e=[];let u;for(;++t13&&t<32||t>126&&t<160||t>55295&&t<57344||t>64975&&t<65008||(t&65535)===65535||(t&65535)===65534||t>1114111?"�":String.fromCharCode(t)}const Ir=/\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi;function Tr(n){return n.replace(Ir,Br)}function Br(n,r,t){if(r)return r;if(t.charCodeAt(0)===35){const u=t.charCodeAt(1),i=u===120||u===88;return pt(t.slice(i?2:1),i?16:10)}return On(t)||n}function yn(n){return!n||typeof n!="object"?"":"position"in n||"type"in n?vn(n.position):"start"in n||"end"in n?vn(n):"line"in n||"column"in n?Tn(n):""}function Tn(n){return nt(n&&n.line)+":"+nt(n&&n.column)}function vn(n){return Tn(n&&n.start)+"-"+Tn(n&&n.end)}function nt(n){return n&&typeof n=="number"?n:1}const ft={}.hasOwnProperty,mt=function(n,r,t){return typeof r!="string"&&(t=r,r=void 0),Lr(t)(zr(wr(t).document().write(Ar()(n,r,!0))))};function Lr(n){const r={transforms:[],canContainEols:["emphasis","fragment","heading","paragraph","strong"],enter:{autolink:a(Hn),autolinkProtocol:y,autolinkEmail:y,atxHeading:a(jn),blockQuote:a(Fn),characterEscape:y,characterReference:y,codeFenced:a(Mn),codeFencedFenceInfo:m,codeFencedFenceMeta:m,codeIndented:a(Mn,m),codeText:a(kt,m),codeTextData:y,data:y,codeFlowValue:y,definition:a(dt),definitionDestinationString:m,definitionLabelString:m,definitionTitleString:m,emphasis:a(bt),hardBreakEscape:a(Rn),hardBreakTrailing:a(Rn),htmlFlow:a(qn,m),htmlFlowData:y,htmlText:a(qn,m),htmlTextData:y,image:a(yt),label:m,link:a(Hn),listItem:a(St),listItemValue:A,listOrdered:a(Nn,h),listUnordered:a(Nn),paragraph:a(Ft),reference:hn,referenceString:m,resourceDestinationString:m,resourceTitleString:m,setextHeading:a(jn),strong:a(Et),thematicBreak:a(wt)},exit:{atxHeading:p(),atxHeadingSequence:T,autolink:p(),autolinkEmail:mn,autolinkProtocol:fn,blockQuote:p(),characterEscapeValue:S,characterReferenceMarkerHexadecimal:pn,characterReferenceMarkerNumeric:pn,characterReferenceValue:an,codeFenced:p(j),codeFencedFence:b,codeFencedFenceInfo:I,codeFencedFenceMeta:M,codeFlowValue:S,codeIndented:p(F),codeText:p(W),codeTextData:S,data:S,definition:p(),definitionDestinationString:k,definitionLabelString:D,definitionTitleString:_,emphasis:p(),hardBreakEscape:p(R),hardBreakTrailing:p(R),htmlFlow:p(w),htmlFlowData:S,htmlText:p(U),htmlTextData:S,image:p(en),label:J,labelText:o,lineEnding:P,link:p(G),listItem:p(),listOrdered:p(),listUnordered:p(),paragraph:p(),referenceString:Q,resourceDestinationString:rn,resourceTitleString:s,resource:K,setextHeading:p(V),setextHeadingLineSequence:N,setextHeadingText:H,strong:p(),thematicBreak:p()}};xt(r,(n||{}).mdastExtensions||[]);const t={};return e;function e(g){let d={type:"root",children:[]};const E={stack:[d],tokenStack:[],config:r,enter:c,exit:f,buffer:m,resume:x,setData:i,getData:l},B=[];let L=-1;for(;++L0){const X=E.tokenStack[E.tokenStack.length-1];(X[1]||tt).call(E,void 0,X[0])}for(d.position={start:sn(g.length>0?g[0][1].start:{line:1,column:1,offset:0}),end:sn(g.length>0?g[g.length-2][1].end:{line:1,column:1,offset:0})},L=-1;++LDesign Objectives
                        • Xray Kernel provides a platform that supports essential network proxy functions and can be developed upon to provide a better user experience.
                        • Cross-platform is the primary principle to reduce the cost of secondary development.

                        Architecture

                        Architecture

                        The kernel is divided into three layers: the application layer, the proxy layer, and the transport layer.

                        Each layer contains several modules, which are independent of each other. Modules of the same type can be seamlessly replaced.

                        Application Layer

                        The application layer contains some commonly used functions in proxy layers, which are abstracted for reuse in different proxy modules.

                        The modules at the application layer should be implemented purely in software and should not be dependent on hardware or platform-related technologies.

                        List of Important Modules:

                        ',10),y=e("li",null,"Dispatcher: Used to transfer data received by the inbound agent to the outbound agent;",-1),_=e("li",null,"DNS: Built-in DNS server module;",-1),f=e("li",null,"Proxy Manager: Proxy manager;",-1),m=e("h3",{id:"proxy-layer",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#proxy-layer"},[e("span",null,"Proxy Layer")])],-1),x=e("p",null,"The proxy layer is divided into two parts: Inbound Proxy and Outbound Proxy.",-1),b=e("p",null,"The two parts are independent of each other, where the inbound proxy does not rely on a specific outbound proxy, and vice versa.",-1),g=e("h4",{id:"inbound-proxy",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#inbound-proxy"},[e("span",null,"Inbound Proxy")])],-1),v={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},k=e("h4",{id:"outbound-proxy",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#outbound-proxy"},[e("span",null,"Outbound Proxy")])],-1),w={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},T=e("h3",{id:"transport-layer",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#transport-layer"},[e("span",null,"Transport Layer")])],-1),I=e("p",null,"The transport layer provides a set of tools and modules related to network data transmission.",-1);function L(P,N){const a=r("RouterLink"),n=r("ExternalLinkIcon");return l(),i("div",null,[u,e("ul",null,[y,e("li",null,[o("Router: Routing module, see "),t(a,{to:"/en/config/routing.html"},{default:d(()=>[o("Routing Configuration")]),_:1}),o(" for details;")]),_,f]),m,x,b,g,e("ul",null,[e("li",null,[o("Implement the "),e("a",v,[o("proxy.Inbound"),t(n)]),o(" interface;")])]),k,e("ul",null,[e("li",null,[o("Implement the "),e("a",w,[o("proxy.Outbound"),t(n)]),o(" interface;")])]),T,I])}const B=s(h,[["render",L],["__file","design.html.vue"]]);export{B as default}; +import{_ as s,r,o as l,c as i,a as e,b as o,d as t,w as d,e as p}from"./app-UOvWaKji.js";const c="/assets/framework-fWbTmHWQ.png",h={},u=p('

                        Design Objectives

                        • Xray Kernel provides a platform that supports essential network proxy functions and can be developed upon to provide a better user experience.
                        • Cross-platform is the primary principle to reduce the cost of secondary development.

                        Architecture

                        Architecture

                        The kernel is divided into three layers: the application layer, the proxy layer, and the transport layer.

                        Each layer contains several modules, which are independent of each other. Modules of the same type can be seamlessly replaced.

                        Application Layer

                        The application layer contains some commonly used functions in proxy layers, which are abstracted for reuse in different proxy modules.

                        The modules at the application layer should be implemented purely in software and should not be dependent on hardware or platform-related technologies.

                        List of Important Modules:

                        ',10),y=e("li",null,"Dispatcher: Used to transfer data received by the inbound agent to the outbound agent;",-1),_=e("li",null,"DNS: Built-in DNS server module;",-1),f=e("li",null,"Proxy Manager: Proxy manager;",-1),m=e("h3",{id:"proxy-layer",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#proxy-layer"},[e("span",null,"Proxy Layer")])],-1),x=e("p",null,"The proxy layer is divided into two parts: Inbound Proxy and Outbound Proxy.",-1),b=e("p",null,"The two parts are independent of each other, where the inbound proxy does not rely on a specific outbound proxy, and vice versa.",-1),g=e("h4",{id:"inbound-proxy",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#inbound-proxy"},[e("span",null,"Inbound Proxy")])],-1),v={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},k=e("h4",{id:"outbound-proxy",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#outbound-proxy"},[e("span",null,"Outbound Proxy")])],-1),w={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},T=e("h3",{id:"transport-layer",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#transport-layer"},[e("span",null,"Transport Layer")])],-1),I=e("p",null,"The transport layer provides a set of tools and modules related to network data transmission.",-1);function L(P,N){const a=r("RouterLink"),n=r("ExternalLinkIcon");return l(),i("div",null,[u,e("ul",null,[y,e("li",null,[o("Router: Routing module, see "),t(a,{to:"/en/config/routing.html"},{default:d(()=>[o("Routing Configuration")]),_:1}),o(" for details;")]),_,f]),m,x,b,g,e("ul",null,[e("li",null,[o("Implement the "),e("a",v,[o("proxy.Inbound"),t(n)]),o(" interface;")])]),k,e("ul",null,[e("li",null,[o("Implement the "),e("a",w,[o("proxy.Outbound"),t(n)]),o(" interface;")])]),T,I])}const B=s(h,[["render",L],["__file","design.html.vue"]]);export{B as default}; diff --git a/assets/design.html-oldCFeI5.js b/assets/design.html-fPrl8l20.js similarity index 97% rename from assets/design.html-oldCFeI5.js rename to assets/design.html-fPrl8l20.js index 4949043ddb..dd5be05a5d 100644 --- a/assets/design.html-oldCFeI5.js +++ b/assets/design.html-fPrl8l20.js @@ -1 +1 @@ -import{_ as s,r as a,o as l,c,a as e,b as n,d as o,w as i,e as h}from"./app-PDrbPfzp.js";const d="/assets/framework-fWbTmHWQ.png",_={},p=h('

                        设计目标

                        • Xray 内核提供了一个平台,支持必要的网络代理功能,在其之上可以进二次开发,以提供更好的用户体验;
                        • 以跨平台为首要原则,以减少二次开发的成本;

                        架构

                        Architecture

                        内核分为三层:应用层、代理层和传输层。

                        每一层内包含数个模块,模块间互相独立,同类型的模块可无缝替换。

                        应用层

                        应用层包含一些代理层中常用的功能,这些功能被抽象出来,以便在不同的代理模块中复用。

                        应用层的模块应为纯软件实现,与硬件或平台相关的技术无关。

                        重要模块列表:

                        ',10),u=e("li",null,"Dispatcher: 用于把入站代理所接收到的数据,传送给出站代理;",-1),x=e("li",null,"DNS: 内置的 DNS 服务器模块;",-1),f=e("li",null,"Proxy Manager: 代理管理器;",-1),b=e("h3",{id:"代理层",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#代理层"},[e("span",null,"代理层")])],-1),m=e("p",null,"代理层分为两部分:入站代理(Inbound Proxy)和出站代理(Outbound Proxy)。",-1),g=e("p",null,"两部分相互独立,入站代理不依赖于某个特定的出站代理,反之亦然。",-1),y=e("h4",{id:"入站代理",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#入站代理"},[e("span",null,"入站代理")])],-1),k={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},N=e("h4",{id:"出站代理",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#出站代理"},[e("span",null,"出站代理")])],-1),I={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},L=e("h3",{id:"传输层",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#传输层"},[e("span",null,"传输层")])],-1),V=e("p",null,"传输层提供一些网络数据传输相关的工具模块。",-1);function v(w,B){const r=a("RouterLink"),t=a("ExternalLinkIcon");return l(),c("div",null,[p,e("ul",null,[u,e("li",null,[n("Router: 路由模块,详见 "),o(r,{to:"/config/routing.html"},{default:i(()=>[n("路由配置")]),_:1}),n(";")]),x,f]),b,m,g,y,e("ul",null,[e("li",null,[n("实现 "),e("a",k,[n("proxy.Inbound"),o(t)]),n(" 接口;")])]),N,e("ul",null,[e("li",null,[n("实现 "),e("a",I,[n("proxy.Outbound"),o(t)]),n(" 接口;")])]),L,V])}const E=s(_,[["render",v],["__file","design.html.vue"]]);export{E as default}; +import{_ as s,r as a,o as l,c,a as e,b as n,d as o,w as i,e as h}from"./app-UOvWaKji.js";const d="/assets/framework-fWbTmHWQ.png",_={},p=h('

                        设计目标

                        • Xray 内核提供了一个平台,支持必要的网络代理功能,在其之上可以进二次开发,以提供更好的用户体验;
                        • 以跨平台为首要原则,以减少二次开发的成本;

                        架构

                        Architecture

                        内核分为三层:应用层、代理层和传输层。

                        每一层内包含数个模块,模块间互相独立,同类型的模块可无缝替换。

                        应用层

                        应用层包含一些代理层中常用的功能,这些功能被抽象出来,以便在不同的代理模块中复用。

                        应用层的模块应为纯软件实现,与硬件或平台相关的技术无关。

                        重要模块列表:

                        ',10),u=e("li",null,"Dispatcher: 用于把入站代理所接收到的数据,传送给出站代理;",-1),x=e("li",null,"DNS: 内置的 DNS 服务器模块;",-1),f=e("li",null,"Proxy Manager: 代理管理器;",-1),b=e("h3",{id:"代理层",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#代理层"},[e("span",null,"代理层")])],-1),m=e("p",null,"代理层分为两部分:入站代理(Inbound Proxy)和出站代理(Outbound Proxy)。",-1),g=e("p",null,"两部分相互独立,入站代理不依赖于某个特定的出站代理,反之亦然。",-1),y=e("h4",{id:"入站代理",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#入站代理"},[e("span",null,"入站代理")])],-1),k={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},N=e("h4",{id:"出站代理",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#出站代理"},[e("span",null,"出站代理")])],-1),I={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},L=e("h3",{id:"传输层",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#传输层"},[e("span",null,"传输层")])],-1),V=e("p",null,"传输层提供一些网络数据传输相关的工具模块。",-1);function v(w,B){const r=a("RouterLink"),t=a("ExternalLinkIcon");return l(),c("div",null,[p,e("ul",null,[u,e("li",null,[n("Router: 路由模块,详见 "),o(r,{to:"/config/routing.html"},{default:i(()=>[n("路由配置")]),_:1}),n(";")]),x,f]),b,m,g,y,e("ul",null,[e("li",null,[n("实现 "),e("a",k,[n("proxy.Inbound"),o(t)]),n(" 接口;")])]),N,e("ul",null,[e("li",null,[n("实现 "),e("a",I,[n("proxy.Outbound"),o(t)]),n(" 接口;")])]),L,V])}const E=s(_,[["render",v],["__file","design.html.vue"]]);export{E as default}; diff --git a/assets/dns.html-KHoheVAl.js b/assets/dns.html-C2aGNNlR.js similarity index 99% rename from assets/dns.html-KHoheVAl.js rename to assets/dns.html-C2aGNNlR.js index 40c91f70d8..7c24b6073b 100644 --- a/assets/dns.html-KHoheVAl.js +++ b/assets/dns.html-C2aGNNlR.js @@ -1,4 +1,4 @@ -import{_ as i,r,o as u,c,a as e,b as s,d as o,w as n,e as a}from"./app-PDrbPfzp.js";const l={},d=a(`

                        Built-in DNS Server

                        DNS Server

                        The DNS module built into Xray has two main purposes:

                        • During the routing phase, it resolves domain names to IP addresses and performs traffic splitting based on the results of domain name resolution and the value of domainStrategy in the routing configuration module. The built-in DNS server is only used for DNS queries when either of the following values is set:
                          • "IPIfNonMatch": When a domain name is requested, it first tries to match it against the domain entries in the routing configuration. If no match is found, the built-in DNS server is used to perform a DNS query for the domain name, and the returned IP address is used to perform IP routing matching again.
                          • "IPOnDemand": When a domain name is matched against any IP-based rule, it is immediately resolved to an IP address for matching.
                        • It resolves the target address for connection.
                          • In the freedom outbound setting, if domainStrategy is set to UseIP, requests made through the outbound proxy will first resolve the domain name to an IP address using the built-in server before making the connection.
                          • In the sockopt setting, if domainStrategy is set to UseIP, system connections initiated through the outbound proxy will first be resolved to an IP address using the built-in server before making the connection.

                        TIP 1

                        DNS queries sent by the built-in DNS server are automatically forwarded based on the routing configuration.

                        TIP 2

                        Only basic IP queries (A and AAAA records) are supported. CNAME records will be queried repeatedly until an A/AAAA record is returned. Other queries will not enter the built-in DNS server.

                        DNS Processing Flow

                        If the domain name to be queried:

                        • Matches the mapping of "domain name - IP" or "domain name - IP array" in the hosts, then the IP or IP array will be returned as the DNS resolution result.

                        • Matches the mapping of "domain name - domain name" in the hosts, then the value of this mapping (another domain name) will be used as the domain name to be queried, and enter the DNS processing flow until an IP is resolved and returned, or an empty resolution is returned.

                        • Does not match hosts, but matches the domains list in one or more DNS servers, then according to the priority of the matching rule, use the DNS server corresponding to the rule to perform the query in sequence. If the DNS server that is hit fails to query or expectIPs does not match, then use the next hit DNS server to perform the query. Otherwise, return the resolved IP. If all hit DNS servers fail to query or expectIPs does not match, then the DNS component:

                          • By default, it will perform "DNS fallback query": use the "DNS server that has not been used in the last failed query and has a default value of false for skipFallback" to perform the query in sequence. If the query fails or expectIPs does not match, return an empty resolution; otherwise, return the resolved IP.
                          • If disableFallback is set to true, "DNS fallback query" will not be performed.
                        • If neither hosts nor the domains list in DNS servers matches, then:

                          • By default, use the "DNS server that has a default value of false for skipFallback" to perform the query in sequence. If the first selected DNS server fails to query or expectIPs does not match, then use the next selected DNS server to perform the query. Otherwise, return the resolved IP. If all selected DNS servers fail to query or expectIPs does not match, return an empty resolution.
                          • If the number of "DNS servers that have a default value of false for skipFallback" is 0 or disableFallback is set to true, use the first DNS server in the DNS configuration to perform the query. If the query fails or expectIPs does not match, return an empty resolution; otherwise, return the resolved IP.

                        DnsObject

                        DnsObject corresponds to the dns section in the configuration file.

                        {
                        +import{_ as i,r,o as u,c,a as e,b as s,d as o,w as n,e as a}from"./app-UOvWaKji.js";const l={},d=a(`

                        Built-in DNS Server

                        DNS Server

                        The DNS module built into Xray has two main purposes:

                        • During the routing phase, it resolves domain names to IP addresses and performs traffic splitting based on the results of domain name resolution and the value of domainStrategy in the routing configuration module. The built-in DNS server is only used for DNS queries when either of the following values is set:
                          • "IPIfNonMatch": When a domain name is requested, it first tries to match it against the domain entries in the routing configuration. If no match is found, the built-in DNS server is used to perform a DNS query for the domain name, and the returned IP address is used to perform IP routing matching again.
                          • "IPOnDemand": When a domain name is matched against any IP-based rule, it is immediately resolved to an IP address for matching.
                        • It resolves the target address for connection.
                          • In the freedom outbound setting, if domainStrategy is set to UseIP, requests made through the outbound proxy will first resolve the domain name to an IP address using the built-in server before making the connection.
                          • In the sockopt setting, if domainStrategy is set to UseIP, system connections initiated through the outbound proxy will first be resolved to an IP address using the built-in server before making the connection.

                        TIP 1

                        DNS queries sent by the built-in DNS server are automatically forwarded based on the routing configuration.

                        TIP 2

                        Only basic IP queries (A and AAAA records) are supported. CNAME records will be queried repeatedly until an A/AAAA record is returned. Other queries will not enter the built-in DNS server.

                        DNS Processing Flow

                        If the domain name to be queried:

                        • Matches the mapping of "domain name - IP" or "domain name - IP array" in the hosts, then the IP or IP array will be returned as the DNS resolution result.

                        • Matches the mapping of "domain name - domain name" in the hosts, then the value of this mapping (another domain name) will be used as the domain name to be queried, and enter the DNS processing flow until an IP is resolved and returned, or an empty resolution is returned.

                        • Does not match hosts, but matches the domains list in one or more DNS servers, then according to the priority of the matching rule, use the DNS server corresponding to the rule to perform the query in sequence. If the DNS server that is hit fails to query or expectIPs does not match, then use the next hit DNS server to perform the query. Otherwise, return the resolved IP. If all hit DNS servers fail to query or expectIPs does not match, then the DNS component:

                          • By default, it will perform "DNS fallback query": use the "DNS server that has not been used in the last failed query and has a default value of false for skipFallback" to perform the query in sequence. If the query fails or expectIPs does not match, return an empty resolution; otherwise, return the resolved IP.
                          • If disableFallback is set to true, "DNS fallback query" will not be performed.
                        • If neither hosts nor the domains list in DNS servers matches, then:

                          • By default, use the "DNS server that has a default value of false for skipFallback" to perform the query in sequence. If the first selected DNS server fails to query or expectIPs does not match, then use the next selected DNS server to perform the query. Otherwise, return the resolved IP. If all selected DNS servers fail to query or expectIPs does not match, return an empty resolution.
                          • If the number of "DNS servers that have a default value of false for skipFallback" is 0 or disableFallback is set to true, use the first DNS server in the DNS configuration to perform the query. If the query fails or expectIPs does not match, return an empty resolution; otherwise, return the resolved IP.

                        DnsObject

                        DnsObject corresponds to the dns section in the configuration file.

                        {
                           "dns": {
                             "hosts": {
                               "baidu.com": "127.0.0.1",
                        diff --git a/assets/dns.html-VxRYmR2X.js b/assets/dns.html-nzh_mzUH.js
                        similarity index 99%
                        rename from assets/dns.html-VxRYmR2X.js
                        rename to assets/dns.html-nzh_mzUH.js
                        index 9322b39c3a..ab10245704 100644
                        --- a/assets/dns.html-VxRYmR2X.js
                        +++ b/assets/dns.html-nzh_mzUH.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as c,o as u,c as l,a as s,b as n,d as a,w as e,e as t}from"./app-PDrbPfzp.js";const d={},i=t(`

                        内置 DNS 服务器

                        DNS 服务器

                        Xray 内置的 DNS 模块,主要有两大用途:

                        • 在路由阶段, 解析域名为 IP, 并且根据域名解析得到的 IP 进行规则匹配以分流. 是否解析域名及分流和路由配置模块中 domainStrategy 的值有关, 只有在设置以下两种值时,才会使用内置 DNS 服务器进行 DNS 查询:

                          • "IPIfNonMatch", 请求一个域名时,进行路由里面的 domain 进行匹配,若无法匹配到结果,则对这个域名使用内置 DNS 服务器进行 DNS 查询,并且使用查询返回的 IP 地址再重新进行 IP 路由匹配。
                          • "IPOnDemand", 当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配。
                        • 解析目标地址进行连接。

                          • 如 在 freedom 出站中,将 domainStrategy 设置为 UseIP, 由此出站发出的请求, 会先将域名通过内置服务器解析成 IP, 然后进行连接。
                          • 如 在 sockopt 中,将 domainStrategy 设置为 UseIP, 此出站发起的系统连接,将先由内置服务器解析为 IP, 然后进行连接。

                        TIP 1

                        内置 DNS 服务器所发出的 DNS 查询请求,会自动根据路由配置进行转发。

                        TIP 2

                        只支持最基本的 IP 查询(A 和 AAAA 记录),CNAME 记录将会重复查询直至返回 A/AAAA 记录为止。其他查询不会进入内置 DNS 服务器。

                        DNS 处理流程

                        若当前要查询的域名:

                        • 命中了 hosts 中的「域名 - IP」、「域名 - IP 数组」映射,则将该 IP 或 IP 数组作为 DNS 解析结果返回。
                        • 命中了 hosts 中的「域名 - 域名」映射,则该映射的值(另一个域名)将作为当前要查询的域名,进入 DNS 处理流程,直到解析出 IP 后返回,或返回空解析。
                        • 没有命中 hosts,但命中了某(几)个 DNS 服务器中的 domains 域名列表,则按照命中的规则的优先级,依次使用该规则对应的 DNS 服务器进行查询。若命中的 DNS 服务器查询失败或 expectIPs 不匹配,则使用下一个命中的 DNS 服务器进行查询;否则返回解析得到的 IP。若所有命中的 DNS 服务器均查询失败或 expectIPs 不匹配,此时 DNS 组件:
                          • 默认会进行 「DNS 回退(fallback)查询」:使用「上一轮失败查询中未被使用的、且 skipFallback 为默认值 false 的 DNS 服务器」依次查询。若查询失败或 expectIPs 不匹配,返回空解析;否则返回解析得到的 IP。
                          • disableFallback 设置为 true,则不会进行「DNS 回退(fallback)查询」。
                        • 既没有命中 hosts,又没有命中 DNS 服务器中的 domains 域名列表,则:
                          • 默认使用「skipFallback 为默认值 false 的 DNS 服务器」依次查询。若第一个被选中的 DNS 服务器查询失败或 expectIPs 不匹配,则使用下一个被选中的 DNS 服务器进行查询;否则返回解析得到的 IP。若所有被选中的 DNS 服务器均查询失败或 expectIPs 不匹配,返回空解析。
                          • 若「skipFallback 为默认值 false 的 DNS 服务器」数量为 0 或 disableFallback 设置为 true,则使用 DNS 配置中的第一个 DNS 服务器进行查询。查询失败或 expectIPs 不匹配,返回空解析;否则返回解析得到的 IP。

                        DnsObject

                        DnsObject 对应配置文件的 dns 项。

                        {
                        +import{_ as p,r as c,o as u,c as l,a as s,b as n,d as a,w as e,e as t}from"./app-UOvWaKji.js";const d={},i=t(`

                        内置 DNS 服务器

                        DNS 服务器

                        Xray 内置的 DNS 模块,主要有两大用途:

                        • 在路由阶段, 解析域名为 IP, 并且根据域名解析得到的 IP 进行规则匹配以分流. 是否解析域名及分流和路由配置模块中 domainStrategy 的值有关, 只有在设置以下两种值时,才会使用内置 DNS 服务器进行 DNS 查询:

                          • "IPIfNonMatch", 请求一个域名时,进行路由里面的 domain 进行匹配,若无法匹配到结果,则对这个域名使用内置 DNS 服务器进行 DNS 查询,并且使用查询返回的 IP 地址再重新进行 IP 路由匹配。
                          • "IPOnDemand", 当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配。
                        • 解析目标地址进行连接。

                          • 如 在 freedom 出站中,将 domainStrategy 设置为 UseIP, 由此出站发出的请求, 会先将域名通过内置服务器解析成 IP, 然后进行连接。
                          • 如 在 sockopt 中,将 domainStrategy 设置为 UseIP, 此出站发起的系统连接,将先由内置服务器解析为 IP, 然后进行连接。

                        TIP 1

                        内置 DNS 服务器所发出的 DNS 查询请求,会自动根据路由配置进行转发。

                        TIP 2

                        只支持最基本的 IP 查询(A 和 AAAA 记录),CNAME 记录将会重复查询直至返回 A/AAAA 记录为止。其他查询不会进入内置 DNS 服务器。

                        DNS 处理流程

                        若当前要查询的域名:

                        • 命中了 hosts 中的「域名 - IP」、「域名 - IP 数组」映射,则将该 IP 或 IP 数组作为 DNS 解析结果返回。
                        • 命中了 hosts 中的「域名 - 域名」映射,则该映射的值(另一个域名)将作为当前要查询的域名,进入 DNS 处理流程,直到解析出 IP 后返回,或返回空解析。
                        • 没有命中 hosts,但命中了某(几)个 DNS 服务器中的 domains 域名列表,则按照命中的规则的优先级,依次使用该规则对应的 DNS 服务器进行查询。若命中的 DNS 服务器查询失败或 expectIPs 不匹配,则使用下一个命中的 DNS 服务器进行查询;否则返回解析得到的 IP。若所有命中的 DNS 服务器均查询失败或 expectIPs 不匹配,此时 DNS 组件:
                          • 默认会进行 「DNS 回退(fallback)查询」:使用「上一轮失败查询中未被使用的、且 skipFallback 为默认值 false 的 DNS 服务器」依次查询。若查询失败或 expectIPs 不匹配,返回空解析;否则返回解析得到的 IP。
                          • disableFallback 设置为 true,则不会进行「DNS 回退(fallback)查询」。
                        • 既没有命中 hosts,又没有命中 DNS 服务器中的 domains 域名列表,则:
                          • 默认使用「skipFallback 为默认值 false 的 DNS 服务器」依次查询。若第一个被选中的 DNS 服务器查询失败或 expectIPs 不匹配,则使用下一个被选中的 DNS 服务器进行查询;否则返回解析得到的 IP。若所有被选中的 DNS 服务器均查询失败或 expectIPs 不匹配,返回空解析。
                          • 若「skipFallback 为默认值 false 的 DNS 服务器」数量为 0 或 disableFallback 设置为 true,则使用 DNS 配置中的第一个 DNS 服务器进行查询。查询失败或 expectIPs 不匹配,返回空解析;否则返回解析得到的 IP。

                        DnsObject

                        DnsObject 对应配置文件的 dns 项。

                        {
                           "dns": {
                             "hosts": {
                               "baidu.com": "127.0.0.1",
                        diff --git a/assets/dns.html-k6tvDtjK.js b/assets/dns.html-qUo2_myA.js
                        similarity index 98%
                        rename from assets/dns.html-k6tvDtjK.js
                        rename to assets/dns.html-qUo2_myA.js
                        index be0e163782..bd53c8b069 100644
                        --- a/assets/dns.html-k6tvDtjK.js
                        +++ b/assets/dns.html-qUo2_myA.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as e,o as p,c as d,a as o,b as n,d as s,w as u,e as r}from"./app-PDrbPfzp.js";const l={},i=o("h1",{id:"dns",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#dns"},[o("span",null,"DNS")])],-1),q=o("p",null,"DNS 是一个出站协议,主要用于拦截和转发 DNS 查询。",-1),k=o("p",null,"此出站协议只能接收 DNS 流量(包含基于 UDP 和 TCP 协议的查询),其它类型的流量会导致错误。",-1),_=r(`

                        OutboundConfigurationObject

                        {
                        +import{_ as c,r as e,o as p,c as d,a as o,b as n,d as s,w as u,e as r}from"./app-UOvWaKji.js";const l={},i=o("h1",{id:"dns",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#dns"},[o("span",null,"DNS")])],-1),q=o("p",null,"DNS 是一个出站协议,主要用于拦截和转发 DNS 查询。",-1),k=o("p",null,"此出站协议只能接收 DNS 流量(包含基于 UDP 和 TCP 协议的查询),其它类型的流量会导致错误。",-1),_=r(`

                        OutboundConfigurationObject

                        {
                           "network": "tcp",
                           "address": "1.1.1.1",
                           "port": 53,
                        diff --git a/assets/dns.html-FvK6oEVD.js b/assets/dns.html-s7z_7JTn.js
                        similarity index 98%
                        rename from assets/dns.html-FvK6oEVD.js
                        rename to assets/dns.html-s7z_7JTn.js
                        index 1302247e78..6417cb8e1d 100644
                        --- a/assets/dns.html-FvK6oEVD.js
                        +++ b/assets/dns.html-s7z_7JTn.js
                        @@ -1,4 +1,4 @@
                        -import{_ as r,r as n,o as i,c as d,a as e,b as o,d as t,w as c,e as p}from"./app-PDrbPfzp.js";const u={},l=e("h1",{id:"dns",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#dns"},[e("span",null,"DNS")])],-1),h=e("p",null,"DNS is an outbound protocol used for intercepting and forwarding DNS queries.",-1),q=e("p",null,"This outbound protocol can only handle DNS traffic, including queries based on UDP and TCP protocols. Other types of traffic will result in an error.",-1),f=p(`

                        OutboundConfigurationObject

                        {
                        +import{_ as r,r as n,o as i,c as d,a as e,b as o,d as t,w as c,e as p}from"./app-UOvWaKji.js";const u={},l=e("h1",{id:"dns",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#dns"},[e("span",null,"DNS")])],-1),h=e("p",null,"DNS is an outbound protocol used for intercepting and forwarding DNS queries.",-1),q=e("p",null,"This outbound protocol can only handle DNS traffic, including queries based on UDP and TCP protocols. Other types of traffic will result in an error.",-1),f=p(`

                        OutboundConfigurationObject

                        {
                           "network": "tcp",
                           "address": "1.1.1.1",
                           "port": 53,
                        diff --git a/assets/document.html-tw05mdL_.js b/assets/document.html-OTBh_E9Y.js
                        similarity index 98%
                        rename from assets/document.html-tw05mdL_.js
                        rename to assets/document.html-OTBh_E9Y.js
                        index 1b0b790520..badf05fd20 100644
                        --- a/assets/document.html-tw05mdL_.js
                        +++ b/assets/document.html-OTBh_E9Y.js
                        @@ -1,4 +1,4 @@
                        -import{_ as r,r as s,o as l,c as i,a as e,b as t,d as n,e as a}from"./app-PDrbPfzp.js";const c={},u=e("h1",{id:"contribute-to-project-x-s-document",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#contribute-to-project-x-s-document"},[e("span",null,"Contribute to Project X's Document")])],-1),d=e("p",null,"Contributions to Project X's Document are welcome, and we appreciate every Contributor's contribution! You guys make Xray stronger!",-1),h=e("h2",{id:"improve-document",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#improve-document"},[e("span",null,"Improve Document")])],-1),p={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},m=e("p",null,"You can submit your changes to the Document by following these steps:",-1),_={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},b=e("li",null,[e("p",null,"Get a clone of the docs from the repository you cloned using whatever tool you like, like:")],-1),g=a(`
                        git clone https://github.com/XTLS/Xray-docs-next.git
                        +import{_ as r,r as s,o as l,c as i,a as e,b as t,d as n,e as a}from"./app-UOvWaKji.js";const c={},u=e("h1",{id:"contribute-to-project-x-s-document",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#contribute-to-project-x-s-document"},[e("span",null,"Contribute to Project X's Document")])],-1),d=e("p",null,"Contributions to Project X's Document are welcome, and we appreciate every Contributor's contribution! You guys make Xray stronger!",-1),h=e("h2",{id:"improve-document",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#improve-document"},[e("span",null,"Improve Document")])],-1),p={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},m=e("p",null,"You can submit your changes to the Document by following these steps:",-1),_={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},b=e("li",null,[e("p",null,"Get a clone of the docs from the repository you cloned using whatever tool you like, like:")],-1),g=a(`
                        git clone https://github.com/XTLS/Xray-docs-next.git
                         
                        1. Create a new branch based on the main branch, such as:
                        git checkout -b your-branch
                         
                        `,3),f={start:"4"},x=e("li",null,[e("p",null,"Make changes on the new branch.")],-1),y={href:"https://prettier.io/docs/en/install.html",target:"_blank",rel:"noopener noreferrer"},v=e("p",null,"Note: Pull requests with formatting issues may be rejected.",-1),k=e("li",null,[e("p",null,"Submit the changes and push them to your repository")],-1),X=e("div",{class:"language-text line-numbers-mode","data-ext":"text","data-title":"text"},[e("pre",{class:"language-text"},[e("code",null,`git push -u origin your-branch `)]),e("div",{class:"line-numbers","aria-hidden":"true"},[e("div",{class:"line-number"})])],-1),P={start:"6"},w={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},j=e("li",null,[e("p",null,"Please outline the new/modified content of this pull request in the title and body of the pull request;")],-1),D={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},q=e("h2",{id:"found-problems",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#found-problems"},[e("span",null,"Found Problems?")])],-1),L=e("p",null,"If you find an error in the document, you can improve the documentation or submit an issue.",-1);function S(C,N){const o=s("ExternalLinkIcon");return l(),i("div",null,[u,d,h,e("p",null,[t("Document for Project X is hosted on "),e("a",p,[t("GitHub"),n(o)]),t(".")]),m,e("ol",null,[e("li",null,[e("p",null,[t("Open the repository from "),e("a",_,[t("Project X Document"),n(o)]),t(", click fork in the upper right corner, fork a mirror image of the document repository to your own GitHub repository.")])]),b]),g,e("ol",f,[x,e("li",null,[e("p",null,[t("After modification, please use "),e("a",y,[t("Prettier"),n(o)]),t("Format your changes.")]),v]),k]),X,e("ol",P,[e("li",null,[e("p",null,[t("Open GitHub, click 'Pull request' to submit a pull request to "),e("a",w,[t("Project X Document"),n(o)]),t(".")])]),j,e("li",null,[e("p",null,[t("Waiting for a response, if the pull request is merged, your changes will be directly displayed on "),e("a",D,[t("Project X Document Website"),n(o)]),t(".")])])]),q,L])}const G=r(c,[["render",S],["__file","document.html.vue"]]);export{G as default}; diff --git a/assets/document.html-IBOddkUf.js b/assets/document.html-WKG-xpF1.js similarity index 98% rename from assets/document.html-IBOddkUf.js rename to assets/document.html-WKG-xpF1.js index de1049306d..da4dce7b89 100644 --- a/assets/document.html-IBOddkUf.js +++ b/assets/document.html-WKG-xpF1.js @@ -1,4 +1,4 @@ -import{_ as o,r,o as s,c as a,a as e,b as t,d as l,e as i}from"./app-PDrbPfzp.js";const c={},d=e("h1",{id:"为-project-x-的文档贡献",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#为-project-x-的文档贡献"},[e("span",null,"为 Project X 的文档贡献")])],-1),u=e("p",null,"欢迎您为 Project X 的文档做出贡献,我们感谢每一位 Contributor 的贡献!是你们让 Xray 更加强大!",-1),h=e("h2",{id:"改进文档",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#改进文档"},[e("span",null,"改进文档")])],-1),_={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},p=e("p",null,"您可以通过以下步骤, 提交您对文档的改动:",-1),g={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},b=e("li",null,[e("p",null,"使用任何您喜欢的工具, 从您克隆的仓库获得文档的克隆, 如:")],-1),x=i(`
                        git clone https://github.com/XTLS/Xray-docs-next.git
                        +import{_ as o,r,o as s,c as a,a as e,b as t,d as l,e as i}from"./app-UOvWaKji.js";const c={},d=e("h1",{id:"为-project-x-的文档贡献",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#为-project-x-的文档贡献"},[e("span",null,"为 Project X 的文档贡献")])],-1),u=e("p",null,"欢迎您为 Project X 的文档做出贡献,我们感谢每一位 Contributor 的贡献!是你们让 Xray 更加强大!",-1),h=e("h2",{id:"改进文档",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#改进文档"},[e("span",null,"改进文档")])],-1),_={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},p=e("p",null,"您可以通过以下步骤, 提交您对文档的改动:",-1),g={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},b=e("li",null,[e("p",null,"使用任何您喜欢的工具, 从您克隆的仓库获得文档的克隆, 如:")],-1),x=i(`
                        git clone https://github.com/XTLS/Xray-docs-next.git
                         
                        1. 基于 main 分支创建新的分支, 如:
                        git checkout -b your-branch
                         
                        `,3),m={start:"4"},f=e("p",null,"在新分支上做修改。",-1),v={href:"https://github.com/sparanoid/chinese-copywriting-guidelines",target:"_blank",rel:"noopener noreferrer"},X={href:"https://prettier.io/docs/en/install.html",target:"_blank",rel:"noopener noreferrer"},k=e("p",null,"注:存在格式问题的 PR,将有可能被拒绝。",-1),P=e("li",null,[e("p",null,"提交修改,并推送到您的仓库中")],-1),j=e("div",{class:"language-text line-numbers-mode","data-ext":"text","data-title":"text"},[e("pre",{class:"language-text"},[e("code",null,`git push -u origin your-branch `)]),e("div",{class:"line-numbers","aria-hidden":"true"},[e("div",{class:"line-number"})])],-1),y={start:"6"},L={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},R=e("li",null,[e("p",null,"请在 PR 的标题和正文中,概述此次 PR 新增/修改的内容等;")],-1),S={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},T=e("h2",{id:"发现问题",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#发现问题"},[e("span",null,"发现问题?")])],-1),N=e("p",null,"如果您发现文档出错,可以改进文档或提交一个 Issue。",-1);function V(B,E){const n=r("ExternalLinkIcon");return s(),a("div",null,[d,u,h,e("p",null,[t("Project X 的文档托管在 "),e("a",_,[t("GitHub"),l(n)]),t(" 上.")]),p,e("ol",null,[e("li",null,[e("p",null,[t("从 "),e("a",g,[t("Project X 文档仓库"),l(n)]),t(" 打开仓库, 点击右上角的 fork, fork 一份文档仓库的镜像到您自己的 github 仓库.")])]),b]),x,e("ol",m,[e("li",null,[f,e("p",null,[t("注:推荐 "),e("a",v,[t("中文文案排版指北"),l(n)])])]),e("li",null,[e("p",null,[t("修改完成后,请使用 "),e("a",X,[t("Prettier"),l(n)]),t(" 格式化您的更改。")]),k]),P]),j,e("ol",y,[e("li",null,[e("p",null,[t("打开 GitHub, 点击 'Pull request' 向 "),e("a",L,[t("Project X 文档仓库"),l(n)]),t(" 提交 PR。")])]),R,e("li",null,[e("p",null,[t("等待回应, 如果 PR 被 merge, 您做的修改将直接呈现在 "),e("a",S,[t("Project X 文档网站"),l(n)]),t("。")])])]),T,N])}const C=o(c,[["render",V],["__file","document.html.vue"]]);export{C as default}; diff --git a/assets/dokodemo.html-p5Zz9pNk.js b/assets/dokodemo.html-9tXE84yJ.js similarity index 98% rename from assets/dokodemo.html-p5Zz9pNk.js rename to assets/dokodemo.html-9tXE84yJ.js index 4a4a41b4ff..2a1db31728 100644 --- a/assets/dokodemo.html-p5Zz9pNk.js +++ b/assets/dokodemo.html-9tXE84yJ.js @@ -1,4 +1,4 @@ -import{_ as s,r,o as c,c as p,a as o,b as e,d as n,w as a,e as i}from"./app-PDrbPfzp.js";const l={},d=i(`

                        Dokodemo-Door

                        Dokodemo door (Anywhere Door) can listen to a local port and forward all incoming data on this port to a specified server's port, achieving the effect of port mapping.

                        InboundConfigurationObject

                        {
                        +import{_ as s,r,o as c,c as p,a as o,b as e,d as n,w as a,e as i}from"./app-UOvWaKji.js";const l={},d=i(`

                        Dokodemo-Door

                        Dokodemo door (Anywhere Door) can listen to a local port and forward all incoming data on this port to a specified server's port, achieving the effect of port mapping.

                        InboundConfigurationObject

                        {
                           "address": "8.8.8.8",
                           "port": 53,
                           "network": "tcp",
                        diff --git a/assets/dokodemo.html-m7ra4W8c.js b/assets/dokodemo.html-s_SNa9En.js
                        similarity index 98%
                        rename from assets/dokodemo.html-m7ra4W8c.js
                        rename to assets/dokodemo.html-s_SNa9En.js
                        index 52bafc3f14..53d09a1e2e 100644
                        --- a/assets/dokodemo.html-m7ra4W8c.js
                        +++ b/assets/dokodemo.html-s_SNa9En.js
                        @@ -1,4 +1,4 @@
                        -import{_ as a,r as c,o as p,c as l,a as e,b as o,d as t,w as s,e as d}from"./app-PDrbPfzp.js";const u={},r=d(`

                        Dokodemo-Door

                        Dokodemo door(任意门)可以监听一个本地端口,并把所有进入此端口的数据发送至指定服务器的一个端口,从而达到端口映射的效果。

                        InboundConfigurationObject

                        {
                        +import{_ as a,r as c,o as p,c as l,a as e,b as o,d as t,w as s,e as d}from"./app-UOvWaKji.js";const u={},r=d(`

                        Dokodemo-Door

                        Dokodemo door(任意门)可以监听一个本地端口,并把所有进入此端口的数据发送至指定服务器的一个端口,从而达到端口映射的效果。

                        InboundConfigurationObject

                        {
                           "address": "8.8.8.8",
                           "port": 53,
                           "network": "tcp",
                        diff --git a/assets/domainsocket.html-VOdJhZlD.js b/assets/domainsocket.html-fCTWcn10.js
                        similarity index 97%
                        rename from assets/domainsocket.html-VOdJhZlD.js
                        rename to assets/domainsocket.html-fCTWcn10.js
                        index db2c14bb9f..951e283c8f 100644
                        --- a/assets/domainsocket.html-VOdJhZlD.js
                        +++ b/assets/domainsocket.html-fCTWcn10.js
                        @@ -1,4 +1,4 @@
                        -import{_ as o,r as n,o as s,c,a as e,b as t,d as i,w as d,e as l}from"./app-PDrbPfzp.js";const p={},r=e("h1",{id:"domain-socket",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#domain-socket"},[e("span",null,"Domain Socket")])],-1),u={class:"custom-container danger"},h=e("p",{class:"custom-container-title"},"Danger",-1),m=e("code",null,"listen",-1),k=e("p",null,"Note that the DomainSocket option here may be deprecated in the future.",-1),b=l(`

                        Domain Socket uses standard Unix domain sockets to transmit data.

                        The advantage of using DomainSocket is that it uses the built-in transport channel of the operating system and does not occupy the network cache. Theoretically, it is slightly faster than local loopback networks.

                        Currently, it can only be used on platforms that support Unix domain sockets, such as Linux and macOS. It is not available until Windows 10 Build 17036.

                        If DomainSocket is specified as the transport mode, the ports and IP addresses configured in the inbound and outbound proxies will be invalidated, and all transports will be replaced by DomainSocket.

                        DomainSocketObject

                        DomainSocketObject corresponds to the dsSettings item.

                        {
                        +import{_ as o,r as n,o as s,c,a as e,b as t,d as i,w as d,e as l}from"./app-UOvWaKji.js";const p={},r=e("h1",{id:"domain-socket",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#domain-socket"},[e("span",null,"Domain Socket")])],-1),u={class:"custom-container danger"},h=e("p",{class:"custom-container-title"},"Danger",-1),m=e("code",null,"listen",-1),k=e("p",null,"Note that the DomainSocket option here may be deprecated in the future.",-1),b=l(`

                        Domain Socket uses standard Unix domain sockets to transmit data.

                        The advantage of using DomainSocket is that it uses the built-in transport channel of the operating system and does not occupy the network cache. Theoretically, it is slightly faster than local loopback networks.

                        Currently, it can only be used on platforms that support Unix domain sockets, such as Linux and macOS. It is not available until Windows 10 Build 17036.

                        If DomainSocket is specified as the transport mode, the ports and IP addresses configured in the inbound and outbound proxies will be invalidated, and all transports will be replaced by DomainSocket.

                        DomainSocketObject

                        DomainSocketObject corresponds to the dsSettings item.

                        {
                           "path": "/path/to/ds/file",
                           "abstract": false,
                           "padding": false
                        diff --git a/assets/domainsocket.html-o3wuPmBS.js b/assets/domainsocket.html-zhkqh_tc.js
                        similarity index 97%
                        rename from assets/domainsocket.html-o3wuPmBS.js
                        rename to assets/domainsocket.html-zhkqh_tc.js
                        index 7030888e0b..90254f590e 100644
                        --- a/assets/domainsocket.html-o3wuPmBS.js
                        +++ b/assets/domainsocket.html-zhkqh_tc.js
                        @@ -1,4 +1,4 @@
                        -import{_ as n,r as s,o as t,c,a as o,b as e,d as i,w as d,e as p}from"./app-PDrbPfzp.js";const l={},r=o("h1",{id:"domain-socket",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#domain-socket"},[o("span",null,"Domain Socket")])],-1),u={class:"custom-container danger"},k=o("p",{class:"custom-container-title"},"警告",-1),m=o("code",null,"listen",-1),b=p(`

                        Domain Socket 使用标准的 Unix domain socket 来传输数据。

                        它的优势是使用了操作系统内建的传输通道,而不会占用网络缓存。 理论上相比起本地环回网络(local loopback)来说,Domain socket 速度略快一些。

                        目前仅可用于支持 Unix domain socket 的平台,如 Linux 和 macOS。在 Windows 10 Build 17036 前不可用。

                        如果指定了 domain socket 作为传输方式,在入站出站代理中配置的端口和 IP 地址将会失效,所有的传输由 domain socket 取代。

                        DomainSocketObject

                        DomainSocketObject 对应传输配置的 dsSettings 项。

                        {
                        +import{_ as n,r as s,o as t,c,a as o,b as e,d as i,w as d,e as p}from"./app-UOvWaKji.js";const l={},r=o("h1",{id:"domain-socket",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#domain-socket"},[o("span",null,"Domain Socket")])],-1),u={class:"custom-container danger"},k=o("p",{class:"custom-container-title"},"警告",-1),m=o("code",null,"listen",-1),b=p(`

                        Domain Socket 使用标准的 Unix domain socket 来传输数据。

                        它的优势是使用了操作系统内建的传输通道,而不会占用网络缓存。 理论上相比起本地环回网络(local loopback)来说,Domain socket 速度略快一些。

                        目前仅可用于支持 Unix domain socket 的平台,如 Linux 和 macOS。在 Windows 10 Build 17036 前不可用。

                        如果指定了 domain socket 作为传输方式,在入站出站代理中配置的端口和 IP 地址将会失效,所有的传输由 domain socket 取代。

                        DomainSocketObject

                        DomainSocketObject 对应传输配置的 dsSettings 项。

                        {
                           "path": "/path/to/ds/file",
                           "abstract": false,
                           "padding": false
                        diff --git a/assets/edges-d32062c0-iT1MEq_Y.js b/assets/edges-d32062c0-DdP-jtfh.js
                        similarity index 99%
                        rename from assets/edges-d32062c0-iT1MEq_Y.js
                        rename to assets/edges-d32062c0-DdP-jtfh.js
                        index 3d29ac38f8..cb3cd69044 100644
                        --- a/assets/edges-d32062c0-iT1MEq_Y.js
                        +++ b/assets/edges-d32062c0-DdP-jtfh.js
                        @@ -1,4 +1,4 @@
                        -import{q as H,c as b,d as V,ao as q,h as E,l as g,z as j,ap as lt}from"./mermaid.core-95b3ca__.js";import{c as st}from"./createText-6b48ae7d-9AoX5zU9.js";import{l as ct}from"./line-_nnM_7ZX.js";const ht=(e,t,a,i)=>{t.forEach(l=>{wt[l](e,a,i)})},ot=(e,t,a)=>{g.trace("Making markers for ",a),e.append("defs").append("marker").attr("id",a+"_"+t+"-extensionStart").attr("class","marker extension "+t).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-extensionEnd").attr("class","marker extension "+t).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},yt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-compositionStart").attr("class","marker composition "+t).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-compositionEnd").attr("class","marker composition "+t).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},pt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-aggregationStart").attr("class","marker aggregation "+t).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-aggregationEnd").attr("class","marker aggregation "+t).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},ft=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-dependencyStart").attr("class","marker dependency "+t).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-dependencyEnd").attr("class","marker dependency "+t).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},xt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-lollipopStart").attr("class","marker lollipop "+t).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),e.append("defs").append("marker").attr("id",a+"_"+t+"-lollipopEnd").attr("class","marker lollipop "+t).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},dt=(e,t,a)=>{e.append("marker").attr("id",a+"_"+t+"-pointEnd").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),e.append("marker").attr("id",a+"_"+t+"-pointStart").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},gt=(e,t,a)=>{e.append("marker").attr("id",a+"_"+t+"-circleEnd").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),e.append("marker").attr("id",a+"_"+t+"-circleStart").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},ut=(e,t,a)=>{e.append("marker").attr("id",a+"_"+t+"-crossEnd").attr("class","marker cross "+t).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),e.append("marker").attr("id",a+"_"+t+"-crossStart").attr("class","marker cross "+t).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},bt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},wt={extension:ot,composition:yt,aggregation:pt,dependency:ft,lollipop:xt,point:dt,circle:gt,cross:ut,barb:bt},hr=ht;function mt(e,t){t&&e.attr("style",t)}function kt(e){const t=E(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),a=t.append("xhtml:div"),i=e.label,l=e.isNode?"nodeLabel":"edgeLabel";return a.html('"+i+""),mt(a,e.labelStyle),a.style("display","inline-block"),a.style("white-space","nowrap"),a.attr("xmlns","http://www.w3.org/1999/xhtml"),t.node()}const vt=(e,t,a,i)=>{let l=e||"";if(typeof l=="object"&&(l=l[0]),H(b().flowchart.htmlLabels)){l=l.replace(/\\n|\n/g,"
                        "),g.debug("vertexText"+l);const r={isNode:i,label:q(l).replace(/fa[blrs]?:fa-[\w-]+/g,n=>``),labelStyle:t.replace("fill:","color:")};return kt(r)}else{const r=document.createElementNS("http://www.w3.org/2000/svg","text");r.setAttribute("style",t.replace("color:","fill:"));let s=[];typeof l=="string"?s=l.split(/\\n|\n|/gi):Array.isArray(l)?s=l:s=[];for(const n of s){const c=document.createElementNS("http://www.w3.org/2000/svg","tspan");c.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),c.setAttribute("dy","1em"),c.setAttribute("x","0"),a?c.setAttribute("class","title-row"):c.setAttribute("class","row"),c.textContent=n.trim(),r.appendChild(c)}return r}},R=vt,M=async(e,t,a,i)=>{let l;const r=t.useHtmlLabels||H(b().flowchart.htmlLabels);a?l=a:l="node default";const s=e.insert("g").attr("class",l).attr("id",t.domId||t.id),n=s.insert("g").attr("class","label").attr("style",t.labelStyle);let c;t.labelText===void 0?c="":c=typeof t.labelText=="string"?t.labelText:t.labelText[0];const o=n.node();let h;t.labelType==="markdown"?h=st(n,V(q(c),b()),{useHtmlLabels:r,width:t.width||b().flowchart.wrappingWidth,classes:"markdown-node-label"}):h=o.appendChild(R(V(q(c),b()),t.labelStyle,!1,i));let y=h.getBBox();const f=t.padding/2;if(H(b().flowchart.htmlLabels)){const p=h.children[0],d=E(h),k=p.getElementsByTagName("img");if(k){const x=c.replace(/]*>/g,"").trim()==="";await Promise.all([...k].map(u=>new Promise(S=>{function B(){if(u.style.display="flex",u.style.flexDirection="column",x){const C=b().fontSize?b().fontSize:window.getComputedStyle(document.body).fontSize,D=parseInt(C,10)*5+"px";u.style.minWidth=D,u.style.maxWidth=D}else u.style.width="100%";S(u)}setTimeout(()=>{u.complete&&B()}),u.addEventListener("error",B),u.addEventListener("load",B)})))}y=p.getBoundingClientRect(),d.attr("width",y.width),d.attr("height",y.height)}return r?n.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"):n.attr("transform","translate(0, "+-y.height/2+")"),t.centerLabel&&n.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),n.insert("rect",":first-child"),{shapeSvg:s,bbox:y,halfPadding:f,label:n}},m=(e,t)=>{const a=t.node().getBBox();e.width=a.width,e.height=a.height};function I(e,t,a,i){return e.insert("polygon",":first-child").attr("points",i.map(function(l){return l.x+","+l.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-t/2+","+a/2+")")}function Lt(e,t){return e.intersect(t)}function it(e,t,a,i){var l=e.x,r=e.y,s=l-i.x,n=r-i.y,c=Math.sqrt(t*t*n*n+a*a*s*s),o=Math.abs(t*a*s/c);i.x0}function Tt(e,t,a){var i=e.x,l=e.y,r=[],s=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY;typeof t.forEach=="function"?t.forEach(function(d){s=Math.min(s,d.x),n=Math.min(n,d.y)}):(s=Math.min(s,t.x),n=Math.min(n,t.y));for(var c=i-e.width/2-s,o=l-e.height/2-n,h=0;h1&&r.sort(function(d,k){var x=d.x-a.x,u=d.y-a.y,S=Math.sqrt(x*x+u*u),B=k.x-a.x,C=k.y-a.y,X=Math.sqrt(B*B+C*C);return S{var a=e.x,i=e.y,l=t.x-a,r=t.y-i,s=e.width/2,n=e.height/2,c,o;return Math.abs(r)*s>Math.abs(l)*n?(r<0&&(n=-n),c=r===0?0:n*l/r,o=n):(l<0&&(s=-s),c=s,o=l===0?0:s*r/l),{x:a+c,y:i+o}},Et=Bt,w={node:Lt,circle:St,ellipse:it,polygon:Tt,rect:Et},Ct=async(e,t)=>{t.useHtmlLabels||b().flowchart.htmlLabels||(t.centerLabel=!0);const{shapeSvg:i,bbox:l,halfPadding:r}=await M(e,t,"node "+t.classes,!0);g.info("Classes = ",t.classes);const s=i.insert("rect",":first-child");return s.attr("rx",t.rx).attr("ry",t.ry).attr("x",-l.width/2-r).attr("y",-l.height/2-r).attr("width",l.width+t.padding).attr("height",l.height+t.padding),m(t,s),t.intersect=function(n){return w.rect(t,n)},i},$t=Ct,_t=e=>{const t=new Set;for(const a of e)switch(a){case"x":t.add("right"),t.add("left");break;case"y":t.add("up"),t.add("down");break;default:t.add(a);break}return t},Rt=(e,t,a)=>{const i=_t(e),l=2,r=t.height+2*a.padding,s=r/l,n=t.width+2*s+a.padding,c=a.padding/2;return i.has("right")&&i.has("left")&&i.has("up")&&i.has("down")?[{x:0,y:0},{x:s,y:0},{x:n/2,y:2*c},{x:n-s,y:0},{x:n,y:0},{x:n,y:-r/3},{x:n+2*c,y:-r/2},{x:n,y:-2*r/3},{x:n,y:-r},{x:n-s,y:-r},{x:n/2,y:-r-2*c},{x:s,y:-r},{x:0,y:-r},{x:0,y:-2*r/3},{x:-2*c,y:-r/2},{x:0,y:-r/3}]:i.has("right")&&i.has("left")&&i.has("up")?[{x:s,y:0},{x:n-s,y:0},{x:n,y:-r/2},{x:n-s,y:-r},{x:s,y:-r},{x:0,y:-r/2}]:i.has("right")&&i.has("left")&&i.has("down")?[{x:0,y:0},{x:s,y:-r},{x:n-s,y:-r},{x:n,y:0}]:i.has("right")&&i.has("up")&&i.has("down")?[{x:0,y:0},{x:n,y:-s},{x:n,y:-r+s},{x:0,y:-r}]:i.has("left")&&i.has("up")&&i.has("down")?[{x:n,y:0},{x:0,y:-s},{x:0,y:-r+s},{x:n,y:-r}]:i.has("right")&&i.has("left")?[{x:s,y:0},{x:s,y:-c},{x:n-s,y:-c},{x:n-s,y:0},{x:n,y:-r/2},{x:n-s,y:-r},{x:n-s,y:-r+c},{x:s,y:-r+c},{x:s,y:-r},{x:0,y:-r/2}]:i.has("up")&&i.has("down")?[{x:n/2,y:0},{x:0,y:-c},{x:s,y:-c},{x:s,y:-r+c},{x:0,y:-r+c},{x:n/2,y:-r},{x:n,y:-r+c},{x:n-s,y:-r+c},{x:n-s,y:-c},{x:n,y:-c}]:i.has("right")&&i.has("up")?[{x:0,y:0},{x:n,y:-s},{x:0,y:-r}]:i.has("right")&&i.has("down")?[{x:0,y:0},{x:n,y:0},{x:0,y:-r}]:i.has("left")&&i.has("up")?[{x:n,y:0},{x:0,y:-s},{x:n,y:-r}]:i.has("left")&&i.has("down")?[{x:n,y:0},{x:0,y:0},{x:n,y:-r}]:i.has("right")?[{x:s,y:-c},{x:s,y:-c},{x:n-s,y:-c},{x:n-s,y:0},{x:n,y:-r/2},{x:n-s,y:-r},{x:n-s,y:-r+c},{x:s,y:-r+c},{x:s,y:-r+c}]:i.has("left")?[{x:s,y:0},{x:s,y:-c},{x:n-s,y:-c},{x:n-s,y:-r+c},{x:s,y:-r+c},{x:s,y:-r},{x:0,y:-r/2}]:i.has("up")?[{x:s,y:-c},{x:s,y:-r+c},{x:0,y:-r+c},{x:n/2,y:-r},{x:n,y:-r+c},{x:n-s,y:-r+c},{x:n-s,y:-c}]:i.has("down")?[{x:n/2,y:0},{x:0,y:-c},{x:s,y:-c},{x:s,y:-r+c},{x:n-s,y:-r+c},{x:n-s,y:-c},{x:n,y:-c}]:[{x:0,y:0}]},K=e=>e?" "+e:"",_=(e,t)=>`${t||"node default"}${K(e.classes)} ${K(e.class)}`,P=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=l+r,n=[{x:s/2,y:0},{x:s,y:-s/2},{x:s/2,y:-s},{x:0,y:-s/2}];g.info("Question main (Circle)");const c=I(a,s,s,n);return c.attr("style",t.style),m(t,c),t.intersect=function(o){return g.warn("Intersect called"),w.polygon(t,n,o)},a},Ht=(e,t)=>{const a=e.insert("g").attr("class","node default").attr("id",t.domId||t.id),i=28,l=[{x:0,y:i/2},{x:i/2,y:0},{x:0,y:-i/2},{x:-i/2,y:0}];return a.insert("polygon",":first-child").attr("points",l.map(function(s){return s.x+","+s.y}).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),t.width=28,t.height=28,t.intersect=function(s){return w.circle(t,14,s)},a},It=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=4,r=i.height+t.padding,s=r/l,n=i.width+2*s+t.padding,c=[{x:s,y:0},{x:n-s,y:0},{x:n,y:-r/2},{x:n-s,y:-r},{x:s,y:-r},{x:0,y:-r/2}],o=I(a,n,r,c);return o.attr("style",t.style),m(t,o),t.intersect=function(h){return w.polygon(t,c,h)},a},Nt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,void 0,!0),l=2,r=i.height+2*t.padding,s=r/l,n=i.width+2*s+t.padding,c=Rt(t.directions,i,t),o=I(a,n,r,c);return o.attr("style",t.style),m(t,o),t.intersect=function(h){return w.polygon(t,c,h)},a},Ot=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:-r/2,y:0},{x:l,y:0},{x:l,y:-r},{x:-r/2,y:-r},{x:0,y:-r/2}];return I(a,l,r,s).attr("style",t.style),t.width=l+r,t.height=r,t.intersect=function(c){return w.polygon(t,s,c)},a},Wt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:-2*r/6,y:0},{x:l-r/6,y:0},{x:l+2*r/6,y:-r},{x:r/6,y:-r}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},Xt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:2*r/6,y:0},{x:l+r/6,y:0},{x:l-2*r/6,y:-r},{x:-r/6,y:-r}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},Yt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:-2*r/6,y:0},{x:l+2*r/6,y:0},{x:l-r/6,y:-r},{x:r/6,y:-r}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},Dt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:r/6,y:0},{x:l-r/6,y:0},{x:l+2*r/6,y:-r},{x:-2*r/6,y:-r}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},At=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:0,y:0},{x:l+r/2,y:0},{x:l,y:-r/2},{x:l+r/2,y:-r},{x:0,y:-r}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},jt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=l/2,s=r/(2.5+l/50),n=i.height+s+t.padding,c="M 0,"+s+" a "+r+","+s+" 0,0,0 "+l+" 0 a "+r+","+s+" 0,0,0 "+-l+" 0 l 0,"+n+" a "+r+","+s+" 0,0,0 "+l+" 0 l 0,"+-n,o=a.attr("label-offset-y",s).insert("path",":first-child").attr("style",t.style).attr("d",c).attr("transform","translate("+-l/2+","+-(n/2+s)+")");return m(t,o),t.intersect=function(h){const y=w.rect(t,h),f=y.x-t.x;if(r!=0&&(Math.abs(f)t.height/2-s)){let p=s*s*(1-f*f/(r*r));p!=0&&(p=Math.sqrt(p)),p=s-p,h.y-t.y>0&&(p=-p),y.y+=p}return y},a},Ut=async(e,t)=>{const{shapeSvg:a,bbox:i,halfPadding:l}=await M(e,t,"node "+t.classes+" "+t.class,!0),r=a.insert("rect",":first-child"),s=t.positioned?t.width:i.width+t.padding,n=t.positioned?t.height:i.height+t.padding,c=t.positioned?-s/2:-i.width/2-l,o=t.positioned?-n/2:-i.height/2-l;if(r.attr("class","basic label-container").attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",c).attr("y",o).attr("width",s).attr("height",n),t.props){const h=new Set(Object.keys(t.props));t.props.borders&&(Q(r,t.props.borders,s,n),h.delete("borders")),h.forEach(y=>{g.warn(`Unknown node property ${y}`)})}return m(t,r),t.intersect=function(h){return w.rect(t,h)},a},zt=async(e,t)=>{const{shapeSvg:a,bbox:i,halfPadding:l}=await M(e,t,"node "+t.classes,!0),r=a.insert("rect",":first-child"),s=t.positioned?t.width:i.width+t.padding,n=t.positioned?t.height:i.height+t.padding,c=t.positioned?-s/2:-i.width/2-l,o=t.positioned?-n/2:-i.height/2-l;if(r.attr("class","basic cluster composite label-container").attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",c).attr("y",o).attr("width",s).attr("height",n),t.props){const h=new Set(Object.keys(t.props));t.props.borders&&(Q(r,t.props.borders,s,n),h.delete("borders")),h.forEach(y=>{g.warn(`Unknown node property ${y}`)})}return m(t,r),t.intersect=function(h){return w.rect(t,h)},a},Zt=async(e,t)=>{const{shapeSvg:a}=await M(e,t,"label",!0);g.trace("Classes = ",t.class);const i=a.insert("rect",":first-child"),l=0,r=0;if(i.attr("width",l).attr("height",r),a.attr("class","label edgeLabel"),t.props){const s=new Set(Object.keys(t.props));t.props.borders&&(Q(i,t.props.borders,l,r),s.delete("borders")),s.forEach(n=>{g.warn(`Unknown node property ${n}`)})}return m(t,i),t.intersect=function(s){return w.rect(t,s)},a};function Q(e,t,a,i){const l=[],r=n=>{l.push(n,0)},s=n=>{l.push(0,n)};t.includes("t")?(g.debug("add top border"),r(a)):s(a),t.includes("r")?(g.debug("add right border"),r(i)):s(i),t.includes("b")?(g.debug("add bottom border"),r(a)):s(a),t.includes("l")?(g.debug("add left border"),r(i)):s(i),e.attr("stroke-dasharray",l.join(" "))}const Gt=(e,t)=>{let a;t.classes?a="node "+t.classes:a="node default";const i=e.insert("g").attr("class",a).attr("id",t.domId||t.id),l=i.insert("rect",":first-child"),r=i.insert("line"),s=i.insert("g").attr("class","label"),n=t.labelText.flat?t.labelText.flat():t.labelText;let c="";typeof n=="object"?c=n[0]:c=n,g.info("Label text abc79",c,n,typeof n=="object");const o=s.node().appendChild(R(c,t.labelStyle,!0,!0));let h={width:0,height:0};if(H(b().flowchart.htmlLabels)){const k=o.children[0],x=E(o);h=k.getBoundingClientRect(),x.attr("width",h.width),x.attr("height",h.height)}g.info("Text 2",n);const y=n.slice(1,n.length);let f=o.getBBox();const p=s.node().appendChild(R(y.join?y.join("
                        "):y,t.labelStyle,!0,!0));if(H(b().flowchart.htmlLabels)){const k=p.children[0],x=E(p);h=k.getBoundingClientRect(),x.attr("width",h.width),x.attr("height",h.height)}const d=t.padding/2;return E(p).attr("transform","translate( "+(h.width>f.width?0:(f.width-h.width)/2)+", "+(f.height+d+5)+")"),E(o).attr("transform","translate( "+(h.width{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.height+t.padding,r=i.width+l/4+t.padding,s=a.insert("rect",":first-child").attr("style",t.style).attr("rx",l/2).attr("ry",l/2).attr("x",-r/2).attr("y",-l/2).attr("width",r).attr("height",l);return m(t,s),t.intersect=function(n){return w.rect(t,n)},a},qt=async(e,t)=>{const{shapeSvg:a,bbox:i,halfPadding:l}=await M(e,t,_(t,void 0),!0),r=a.insert("circle",":first-child");return r.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("r",i.width/2+l).attr("width",i.width+t.padding).attr("height",i.height+t.padding),g.info("Circle main"),m(t,r),t.intersect=function(s){return g.info("Circle intersect",t,i.width/2+l,s),w.circle(t,i.width/2+l,s)},a},Qt=async(e,t)=>{const{shapeSvg:a,bbox:i,halfPadding:l}=await M(e,t,_(t,void 0),!0),r=5,s=a.insert("g",":first-child"),n=s.insert("circle"),c=s.insert("circle");return s.attr("class",t.class),n.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("r",i.width/2+l+r).attr("width",i.width+t.padding+r*2).attr("height",i.height+t.padding+r*2),c.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("r",i.width/2+l).attr("width",i.width+t.padding).attr("height",i.height+t.padding),g.info("DoubleCircle main"),m(t,n),t.intersect=function(o){return g.info("DoubleCircle intersect",t,i.width/2+l+r,o),w.circle(t,i.width/2+l+r,o)},a},Vt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:0,y:0},{x:l,y:0},{x:l,y:-r},{x:0,y:-r},{x:0,y:0},{x:-8,y:0},{x:l+8,y:0},{x:l+8,y:-r},{x:-8,y:-r},{x:-8,y:0}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},Jt=(e,t)=>{const a=e.insert("g").attr("class","node default").attr("id",t.domId||t.id),i=a.insert("circle",":first-child");return i.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),m(t,i),t.intersect=function(l){return w.circle(t,7,l)},a},tt=(e,t,a)=>{const i=e.insert("g").attr("class","node default").attr("id",t.domId||t.id);let l=70,r=10;a==="LR"&&(l=10,r=70);const s=i.append("rect").attr("x",-1*l/2).attr("y",-1*r/2).attr("width",l).attr("height",r).attr("class","fork-join");return m(t,s),t.height=t.height+t.padding/2,t.width=t.width+t.padding/2,t.intersect=function(n){return w.rect(t,n)},i},Kt=(e,t)=>{const a=e.insert("g").attr("class","node default").attr("id",t.domId||t.id),i=a.insert("circle",":first-child"),l=a.insert("circle",":first-child");return l.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),i.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),m(t,l),t.intersect=function(r){return w.circle(t,7,r)},a},Pt=(e,t)=>{const a=t.padding/2,i=4,l=8;let r;t.classes?r="node "+t.classes:r="node default";const s=e.insert("g").attr("class",r).attr("id",t.domId||t.id),n=s.insert("rect",":first-child"),c=s.insert("line"),o=s.insert("line");let h=0,y=i;const f=s.insert("g").attr("class","label");let p=0;const d=t.classData.annotations&&t.classData.annotations[0],k=t.classData.annotations[0]?"«"+t.classData.annotations[0]+"»":"",x=f.node().appendChild(R(k,t.labelStyle,!0,!0));let u=x.getBBox();if(H(b().flowchart.htmlLabels)){const v=x.children[0],L=E(x);u=v.getBoundingClientRect(),L.attr("width",u.width),L.attr("height",u.height)}t.classData.annotations[0]&&(y+=u.height+i,h+=u.width);let S=t.classData.label;t.classData.type!==void 0&&t.classData.type!==""&&(b().flowchart.htmlLabels?S+="<"+t.classData.type+">":S+="<"+t.classData.type+">");const B=f.node().appendChild(R(S,t.labelStyle,!0,!0));E(B).attr("class","classTitle");let C=B.getBBox();if(H(b().flowchart.htmlLabels)){const v=B.children[0],L=E(B);C=v.getBoundingClientRect(),L.attr("width",C.width),L.attr("height",C.height)}y+=C.height+i,C.width>h&&(h=C.width);const X=[];t.classData.members.forEach(v=>{const L=v.getDisplayDetails();let W=L.displayText;b().flowchart.htmlLabels&&(W=W.replace(//g,">"));const N=f.node().appendChild(R(W,L.cssStyle?L.cssStyle:t.labelStyle,!0,!0));let $=N.getBBox();if(H(b().flowchart.htmlLabels)){const F=N.children[0],A=E(N);$=F.getBoundingClientRect(),A.attr("width",$.width),A.attr("height",$.height)}$.width>h&&(h=$.width),y+=$.height+i,X.push(N)}),y+=l;const D=[];if(t.classData.methods.forEach(v=>{const L=v.getDisplayDetails();let W=L.displayText;b().flowchart.htmlLabels&&(W=W.replace(//g,">"));const N=f.node().appendChild(R(W,L.cssStyle?L.cssStyle:t.labelStyle,!0,!0));let $=N.getBBox();if(H(b().flowchart.htmlLabels)){const F=N.children[0],A=E(N);$=F.getBoundingClientRect(),A.attr("width",$.width),A.attr("height",$.height)}$.width>h&&(h=$.width),y+=$.height+i,D.push(N)}),y+=l,d){let v=(h-u.width)/2;E(x).attr("transform","translate( "+(-1*h/2+v)+", "+-1*y/2+")"),p=u.height+i}let nt=(h-C.width)/2;return E(B).attr("transform","translate( "+(-1*h/2+nt)+", "+(-1*y/2+p)+")"),p+=C.height+i,c.attr("class","divider").attr("x1",-h/2-a).attr("x2",h/2+a).attr("y1",-y/2-a+l+p).attr("y2",-y/2-a+l+p),p+=l,X.forEach(v=>{E(v).attr("transform","translate( "+-h/2+", "+(-1*y/2+p+l/2)+")");const L=v==null?void 0:v.getBBox();p+=((L==null?void 0:L.height)??0)+i}),p+=l,o.attr("class","divider").attr("x1",-h/2-a).attr("x2",h/2+a).attr("y1",-y/2-a+l+p).attr("y2",-y/2-a+l+p),p+=l,D.forEach(v=>{E(v).attr("transform","translate( "+-h/2+", "+(-1*y/2+p)+")");const L=v==null?void 0:v.getBBox();p+=((L==null?void 0:L.height)??0)+i}),n.attr("style",t.style).attr("class","outer title-state").attr("x",-h/2-a).attr("y",-(y/2)-a).attr("width",h+t.padding).attr("height",y+t.padding),m(t,n),t.intersect=function(v){return w.rect(t,v)},s},rt={rhombus:P,composite:zt,question:P,rect:Ut,labelRect:Zt,rectWithTitle:Gt,choice:Ht,circle:qt,doublecircle:Qt,stadium:Ft,hexagon:It,block_arrow:Nt,rect_left_inv_arrow:Ot,lean_right:Wt,lean_left:Xt,trapezoid:Yt,inv_trapezoid:Dt,rect_right_inv_arrow:At,cylinder:jt,start:Jt,end:Kt,note:$t,subroutine:Vt,fork:tt,join:tt,class_box:Pt};let Y={};const or=async(e,t,a)=>{let i,l;if(t.link){let r;b().securityLevel==="sandbox"?r="_top":t.linkTarget&&(r=t.linkTarget||"_blank"),i=e.insert("svg:a").attr("xlink:href",t.link).attr("target",r),l=await rt[t.shape](i,t,a)}else l=await rt[t.shape](e,t,a),i=l;return t.tooltip&&l.attr("title",t.tooltip),t.class&&l.attr("class","node default "+t.class),i.attr("data-node","true"),i.attr("data-id",t.id),Y[t.id]=i,t.haveCallback&&Y[t.id].attr("class",Y[t.id].attr("class")+" clickable"),i},yr=(e,t)=>{Y[t.id]=e},pr=()=>{Y={}},fr=e=>{const t=Y[e.id];g.trace("Transforming node",e.diff,e,"translate("+(e.x-e.width/2-5)+", "+e.width/2+")");const a=8,i=e.diff||0;return e.clusterNode?t.attr("transform","translate("+(e.x+i-e.width/2)+", "+(e.y-e.height/2-a)+")"):t.attr("transform","translate("+e.x+", "+e.y+")"),i},tr=({flowchart:e})=>{var t,a;const i=((t=e==null?void 0:e.subGraphTitleMargin)==null?void 0:t.top)??0,l=((a=e==null?void 0:e.subGraphTitleMargin)==null?void 0:a.bottom)??0,r=i+l;return{subGraphTitleTopMargin:i,subGraphTitleBottomMargin:l,subGraphTitleTotalMargin:r}},O={aggregation:18,extension:18,composition:18,dependency:6,lollipop:13.5,arrow_point:5.3};function U(e,t){if(e===void 0||t===void 0)return{angle:0,deltaX:0,deltaY:0};e=Z(e),t=Z(t);const[a,i]=[e.x,e.y],[l,r]=[t.x,t.y],s=l-a,n=r-i;return{angle:Math.atan(n/s),deltaX:s,deltaY:n}}const Z=e=>Array.isArray(e)?{x:e[0],y:e[1]}:e,rr=e=>({x:function(t,a,i){let l=0;if(a===0&&Object.hasOwn(O,e.arrowTypeStart)){const{angle:r,deltaX:s}=U(i[0],i[1]);l=O[e.arrowTypeStart]*Math.cos(r)*(s>=0?1:-1)}else if(a===i.length-1&&Object.hasOwn(O,e.arrowTypeEnd)){const{angle:r,deltaX:s}=U(i[i.length-1],i[i.length-2]);l=O[e.arrowTypeEnd]*Math.cos(r)*(s>=0?1:-1)}return Z(t).x+l},y:function(t,a,i){let l=0;if(a===0&&Object.hasOwn(O,e.arrowTypeStart)){const{angle:r,deltaY:s}=U(i[0],i[1]);l=O[e.arrowTypeStart]*Math.abs(Math.sin(r))*(s>=0?1:-1)}else if(a===i.length-1&&Object.hasOwn(O,e.arrowTypeEnd)){const{angle:r,deltaY:s}=U(i[i.length-1],i[i.length-2]);l=O[e.arrowTypeEnd]*Math.abs(Math.sin(r))*(s>=0?1:-1)}return Z(t).y+l}}),ar=(e,t,a,i,l)=>{t.arrowTypeStart&&at(e,"start",t.arrowTypeStart,a,i,l),t.arrowTypeEnd&&at(e,"end",t.arrowTypeEnd,a,i,l)},er={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},at=(e,t,a,i,l,r)=>{const s=er[a];if(!s){g.warn(`Unknown arrow type: ${a}`);return}const n=t==="start"?"Start":"End";e.attr(`marker-${t}`,`url(${i}#${l}_${r}-${s}${n})`)};let G={},T={};const xr=()=>{G={},T={}},dr=(e,t)=>{const a=H(b().flowchart.htmlLabels),i=t.labelType==="markdown"?st(e,t.label,{style:t.labelStyle,useHtmlLabels:a,addSvgBackground:!0}):R(t.label,t.labelStyle),l=e.insert("g").attr("class","edgeLabel"),r=l.insert("g").attr("class","label");r.node().appendChild(i);let s=i.getBBox();if(a){const c=i.children[0],o=E(i);s=c.getBoundingClientRect(),o.attr("width",s.width),o.attr("height",s.height)}r.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),G[t.id]=l,t.width=s.width,t.height=s.height;let n;if(t.startLabelLeft){const c=R(t.startLabelLeft,t.labelStyle),o=e.insert("g").attr("class","edgeTerminals"),h=o.insert("g").attr("class","inner");n=h.node().appendChild(c);const y=c.getBBox();h.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),T[t.id]||(T[t.id]={}),T[t.id].startLeft=o,z(n,t.startLabelLeft)}if(t.startLabelRight){const c=R(t.startLabelRight,t.labelStyle),o=e.insert("g").attr("class","edgeTerminals"),h=o.insert("g").attr("class","inner");n=o.node().appendChild(c),h.node().appendChild(c);const y=c.getBBox();h.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),T[t.id]||(T[t.id]={}),T[t.id].startRight=o,z(n,t.startLabelRight)}if(t.endLabelLeft){const c=R(t.endLabelLeft,t.labelStyle),o=e.insert("g").attr("class","edgeTerminals"),h=o.insert("g").attr("class","inner");n=h.node().appendChild(c);const y=c.getBBox();h.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),o.node().appendChild(c),T[t.id]||(T[t.id]={}),T[t.id].endLeft=o,z(n,t.endLabelLeft)}if(t.endLabelRight){const c=R(t.endLabelRight,t.labelStyle),o=e.insert("g").attr("class","edgeTerminals"),h=o.insert("g").attr("class","inner");n=h.node().appendChild(c);const y=c.getBBox();h.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),o.node().appendChild(c),T[t.id]||(T[t.id]={}),T[t.id].endRight=o,z(n,t.endLabelRight)}return i};function z(e,t){b().flowchart.htmlLabels&&e&&(e.style.width=t.length*9+"px",e.style.height="12px")}const gr=(e,t)=>{g.debug("Moving label abc88 ",e.id,e.label,G[e.id],t);let a=t.updatedPath?t.updatedPath:t.originalPath;const i=b(),{subGraphTitleTotalMargin:l}=tr(i);if(e.label){const r=G[e.id];let s=e.x,n=e.y;if(a){const c=j.calcLabelPosition(a);g.debug("Moving label "+e.label+" from (",s,",",n,") to (",c.x,",",c.y,") abc88"),t.updatedPath&&(s=c.x,n=c.y)}r.attr("transform",`translate(${s}, ${n+l/2})`)}if(e.startLabelLeft){const r=T[e.id].startLeft;let s=e.x,n=e.y;if(a){const c=j.calcTerminalLabelPosition(e.arrowTypeStart?10:0,"start_left",a);s=c.x,n=c.y}r.attr("transform",`translate(${s}, ${n})`)}if(e.startLabelRight){const r=T[e.id].startRight;let s=e.x,n=e.y;if(a){const c=j.calcTerminalLabelPosition(e.arrowTypeStart?10:0,"start_right",a);s=c.x,n=c.y}r.attr("transform",`translate(${s}, ${n})`)}if(e.endLabelLeft){const r=T[e.id].endLeft;let s=e.x,n=e.y;if(a){const c=j.calcTerminalLabelPosition(e.arrowTypeEnd?10:0,"end_left",a);s=c.x,n=c.y}r.attr("transform",`translate(${s}, ${n})`)}if(e.endLabelRight){const r=T[e.id].endRight;let s=e.x,n=e.y;if(a){const c=j.calcTerminalLabelPosition(e.arrowTypeEnd?10:0,"end_right",a);s=c.x,n=c.y}r.attr("transform",`translate(${s}, ${n})`)}},sr=(e,t)=>{const a=e.x,i=e.y,l=Math.abs(t.x-a),r=Math.abs(t.y-i),s=e.width/2,n=e.height/2;return l>=s||r>=n},ir=(e,t,a)=>{g.debug(`intersection calc abc89: +import{q as H,c as b,d as V,ao as q,h as E,l as g,z as j,ap as lt}from"./mermaid.core-Q3WVcjPF.js";import{c as st}from"./createText-6b48ae7d-yUX1YD6G.js";import{l as ct}from"./line-3Gyevr9q.js";const ht=(e,t,a,i)=>{t.forEach(l=>{wt[l](e,a,i)})},ot=(e,t,a)=>{g.trace("Making markers for ",a),e.append("defs").append("marker").attr("id",a+"_"+t+"-extensionStart").attr("class","marker extension "+t).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-extensionEnd").attr("class","marker extension "+t).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")},yt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-compositionStart").attr("class","marker composition "+t).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-compositionEnd").attr("class","marker composition "+t).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},pt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-aggregationStart").attr("class","marker aggregation "+t).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-aggregationEnd").attr("class","marker aggregation "+t).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")},ft=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-dependencyStart").attr("class","marker dependency "+t).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),e.append("defs").append("marker").attr("id",a+"_"+t+"-dependencyEnd").attr("class","marker dependency "+t).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")},xt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-lollipopStart").attr("class","marker lollipop "+t).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),e.append("defs").append("marker").attr("id",a+"_"+t+"-lollipopEnd").attr("class","marker lollipop "+t).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)},dt=(e,t,a)=>{e.append("marker").attr("id",a+"_"+t+"-pointEnd").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),e.append("marker").attr("id",a+"_"+t+"-pointStart").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},gt=(e,t,a)=>{e.append("marker").attr("id",a+"_"+t+"-circleEnd").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),e.append("marker").attr("id",a+"_"+t+"-circleStart").attr("class","marker "+t).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")},ut=(e,t,a)=>{e.append("marker").attr("id",a+"_"+t+"-crossEnd").attr("class","marker cross "+t).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),e.append("marker").attr("id",a+"_"+t+"-crossStart").attr("class","marker cross "+t).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")},bt=(e,t,a)=>{e.append("defs").append("marker").attr("id",a+"_"+t+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},wt={extension:ot,composition:yt,aggregation:pt,dependency:ft,lollipop:xt,point:dt,circle:gt,cross:ut,barb:bt},hr=ht;function mt(e,t){t&&e.attr("style",t)}function kt(e){const t=E(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),a=t.append("xhtml:div"),i=e.label,l=e.isNode?"nodeLabel":"edgeLabel";return a.html('"+i+""),mt(a,e.labelStyle),a.style("display","inline-block"),a.style("white-space","nowrap"),a.attr("xmlns","http://www.w3.org/1999/xhtml"),t.node()}const vt=(e,t,a,i)=>{let l=e||"";if(typeof l=="object"&&(l=l[0]),H(b().flowchart.htmlLabels)){l=l.replace(/\\n|\n/g,"
                        "),g.debug("vertexText"+l);const r={isNode:i,label:q(l).replace(/fa[blrs]?:fa-[\w-]+/g,n=>``),labelStyle:t.replace("fill:","color:")};return kt(r)}else{const r=document.createElementNS("http://www.w3.org/2000/svg","text");r.setAttribute("style",t.replace("color:","fill:"));let s=[];typeof l=="string"?s=l.split(/\\n|\n|/gi):Array.isArray(l)?s=l:s=[];for(const n of s){const c=document.createElementNS("http://www.w3.org/2000/svg","tspan");c.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),c.setAttribute("dy","1em"),c.setAttribute("x","0"),a?c.setAttribute("class","title-row"):c.setAttribute("class","row"),c.textContent=n.trim(),r.appendChild(c)}return r}},R=vt,M=async(e,t,a,i)=>{let l;const r=t.useHtmlLabels||H(b().flowchart.htmlLabels);a?l=a:l="node default";const s=e.insert("g").attr("class",l).attr("id",t.domId||t.id),n=s.insert("g").attr("class","label").attr("style",t.labelStyle);let c;t.labelText===void 0?c="":c=typeof t.labelText=="string"?t.labelText:t.labelText[0];const o=n.node();let h;t.labelType==="markdown"?h=st(n,V(q(c),b()),{useHtmlLabels:r,width:t.width||b().flowchart.wrappingWidth,classes:"markdown-node-label"}):h=o.appendChild(R(V(q(c),b()),t.labelStyle,!1,i));let y=h.getBBox();const f=t.padding/2;if(H(b().flowchart.htmlLabels)){const p=h.children[0],d=E(h),k=p.getElementsByTagName("img");if(k){const x=c.replace(/]*>/g,"").trim()==="";await Promise.all([...k].map(u=>new Promise(S=>{function B(){if(u.style.display="flex",u.style.flexDirection="column",x){const C=b().fontSize?b().fontSize:window.getComputedStyle(document.body).fontSize,D=parseInt(C,10)*5+"px";u.style.minWidth=D,u.style.maxWidth=D}else u.style.width="100%";S(u)}setTimeout(()=>{u.complete&&B()}),u.addEventListener("error",B),u.addEventListener("load",B)})))}y=p.getBoundingClientRect(),d.attr("width",y.width),d.attr("height",y.height)}return r?n.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"):n.attr("transform","translate(0, "+-y.height/2+")"),t.centerLabel&&n.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),n.insert("rect",":first-child"),{shapeSvg:s,bbox:y,halfPadding:f,label:n}},m=(e,t)=>{const a=t.node().getBBox();e.width=a.width,e.height=a.height};function I(e,t,a,i){return e.insert("polygon",":first-child").attr("points",i.map(function(l){return l.x+","+l.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-t/2+","+a/2+")")}function Lt(e,t){return e.intersect(t)}function it(e,t,a,i){var l=e.x,r=e.y,s=l-i.x,n=r-i.y,c=Math.sqrt(t*t*n*n+a*a*s*s),o=Math.abs(t*a*s/c);i.x0}function Tt(e,t,a){var i=e.x,l=e.y,r=[],s=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY;typeof t.forEach=="function"?t.forEach(function(d){s=Math.min(s,d.x),n=Math.min(n,d.y)}):(s=Math.min(s,t.x),n=Math.min(n,t.y));for(var c=i-e.width/2-s,o=l-e.height/2-n,h=0;h1&&r.sort(function(d,k){var x=d.x-a.x,u=d.y-a.y,S=Math.sqrt(x*x+u*u),B=k.x-a.x,C=k.y-a.y,X=Math.sqrt(B*B+C*C);return S{var a=e.x,i=e.y,l=t.x-a,r=t.y-i,s=e.width/2,n=e.height/2,c,o;return Math.abs(r)*s>Math.abs(l)*n?(r<0&&(n=-n),c=r===0?0:n*l/r,o=n):(l<0&&(s=-s),c=s,o=l===0?0:s*r/l),{x:a+c,y:i+o}},Et=Bt,w={node:Lt,circle:St,ellipse:it,polygon:Tt,rect:Et},Ct=async(e,t)=>{t.useHtmlLabels||b().flowchart.htmlLabels||(t.centerLabel=!0);const{shapeSvg:i,bbox:l,halfPadding:r}=await M(e,t,"node "+t.classes,!0);g.info("Classes = ",t.classes);const s=i.insert("rect",":first-child");return s.attr("rx",t.rx).attr("ry",t.ry).attr("x",-l.width/2-r).attr("y",-l.height/2-r).attr("width",l.width+t.padding).attr("height",l.height+t.padding),m(t,s),t.intersect=function(n){return w.rect(t,n)},i},$t=Ct,_t=e=>{const t=new Set;for(const a of e)switch(a){case"x":t.add("right"),t.add("left");break;case"y":t.add("up"),t.add("down");break;default:t.add(a);break}return t},Rt=(e,t,a)=>{const i=_t(e),l=2,r=t.height+2*a.padding,s=r/l,n=t.width+2*s+a.padding,c=a.padding/2;return i.has("right")&&i.has("left")&&i.has("up")&&i.has("down")?[{x:0,y:0},{x:s,y:0},{x:n/2,y:2*c},{x:n-s,y:0},{x:n,y:0},{x:n,y:-r/3},{x:n+2*c,y:-r/2},{x:n,y:-2*r/3},{x:n,y:-r},{x:n-s,y:-r},{x:n/2,y:-r-2*c},{x:s,y:-r},{x:0,y:-r},{x:0,y:-2*r/3},{x:-2*c,y:-r/2},{x:0,y:-r/3}]:i.has("right")&&i.has("left")&&i.has("up")?[{x:s,y:0},{x:n-s,y:0},{x:n,y:-r/2},{x:n-s,y:-r},{x:s,y:-r},{x:0,y:-r/2}]:i.has("right")&&i.has("left")&&i.has("down")?[{x:0,y:0},{x:s,y:-r},{x:n-s,y:-r},{x:n,y:0}]:i.has("right")&&i.has("up")&&i.has("down")?[{x:0,y:0},{x:n,y:-s},{x:n,y:-r+s},{x:0,y:-r}]:i.has("left")&&i.has("up")&&i.has("down")?[{x:n,y:0},{x:0,y:-s},{x:0,y:-r+s},{x:n,y:-r}]:i.has("right")&&i.has("left")?[{x:s,y:0},{x:s,y:-c},{x:n-s,y:-c},{x:n-s,y:0},{x:n,y:-r/2},{x:n-s,y:-r},{x:n-s,y:-r+c},{x:s,y:-r+c},{x:s,y:-r},{x:0,y:-r/2}]:i.has("up")&&i.has("down")?[{x:n/2,y:0},{x:0,y:-c},{x:s,y:-c},{x:s,y:-r+c},{x:0,y:-r+c},{x:n/2,y:-r},{x:n,y:-r+c},{x:n-s,y:-r+c},{x:n-s,y:-c},{x:n,y:-c}]:i.has("right")&&i.has("up")?[{x:0,y:0},{x:n,y:-s},{x:0,y:-r}]:i.has("right")&&i.has("down")?[{x:0,y:0},{x:n,y:0},{x:0,y:-r}]:i.has("left")&&i.has("up")?[{x:n,y:0},{x:0,y:-s},{x:n,y:-r}]:i.has("left")&&i.has("down")?[{x:n,y:0},{x:0,y:0},{x:n,y:-r}]:i.has("right")?[{x:s,y:-c},{x:s,y:-c},{x:n-s,y:-c},{x:n-s,y:0},{x:n,y:-r/2},{x:n-s,y:-r},{x:n-s,y:-r+c},{x:s,y:-r+c},{x:s,y:-r+c}]:i.has("left")?[{x:s,y:0},{x:s,y:-c},{x:n-s,y:-c},{x:n-s,y:-r+c},{x:s,y:-r+c},{x:s,y:-r},{x:0,y:-r/2}]:i.has("up")?[{x:s,y:-c},{x:s,y:-r+c},{x:0,y:-r+c},{x:n/2,y:-r},{x:n,y:-r+c},{x:n-s,y:-r+c},{x:n-s,y:-c}]:i.has("down")?[{x:n/2,y:0},{x:0,y:-c},{x:s,y:-c},{x:s,y:-r+c},{x:n-s,y:-r+c},{x:n-s,y:-c},{x:n,y:-c}]:[{x:0,y:0}]},K=e=>e?" "+e:"",_=(e,t)=>`${t||"node default"}${K(e.classes)} ${K(e.class)}`,P=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=l+r,n=[{x:s/2,y:0},{x:s,y:-s/2},{x:s/2,y:-s},{x:0,y:-s/2}];g.info("Question main (Circle)");const c=I(a,s,s,n);return c.attr("style",t.style),m(t,c),t.intersect=function(o){return g.warn("Intersect called"),w.polygon(t,n,o)},a},Ht=(e,t)=>{const a=e.insert("g").attr("class","node default").attr("id",t.domId||t.id),i=28,l=[{x:0,y:i/2},{x:i/2,y:0},{x:0,y:-i/2},{x:-i/2,y:0}];return a.insert("polygon",":first-child").attr("points",l.map(function(s){return s.x+","+s.y}).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),t.width=28,t.height=28,t.intersect=function(s){return w.circle(t,14,s)},a},It=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=4,r=i.height+t.padding,s=r/l,n=i.width+2*s+t.padding,c=[{x:s,y:0},{x:n-s,y:0},{x:n,y:-r/2},{x:n-s,y:-r},{x:s,y:-r},{x:0,y:-r/2}],o=I(a,n,r,c);return o.attr("style",t.style),m(t,o),t.intersect=function(h){return w.polygon(t,c,h)},a},Nt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,void 0,!0),l=2,r=i.height+2*t.padding,s=r/l,n=i.width+2*s+t.padding,c=Rt(t.directions,i,t),o=I(a,n,r,c);return o.attr("style",t.style),m(t,o),t.intersect=function(h){return w.polygon(t,c,h)},a},Ot=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:-r/2,y:0},{x:l,y:0},{x:l,y:-r},{x:-r/2,y:-r},{x:0,y:-r/2}];return I(a,l,r,s).attr("style",t.style),t.width=l+r,t.height=r,t.intersect=function(c){return w.polygon(t,s,c)},a},Wt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:-2*r/6,y:0},{x:l-r/6,y:0},{x:l+2*r/6,y:-r},{x:r/6,y:-r}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},Xt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:2*r/6,y:0},{x:l+r/6,y:0},{x:l-2*r/6,y:-r},{x:-r/6,y:-r}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},Yt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:-2*r/6,y:0},{x:l+2*r/6,y:0},{x:l-r/6,y:-r},{x:r/6,y:-r}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},Dt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:r/6,y:0},{x:l-r/6,y:0},{x:l+2*r/6,y:-r},{x:-2*r/6,y:-r}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},At=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:0,y:0},{x:l+r/2,y:0},{x:l,y:-r/2},{x:l+r/2,y:-r},{x:0,y:-r}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},jt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=l/2,s=r/(2.5+l/50),n=i.height+s+t.padding,c="M 0,"+s+" a "+r+","+s+" 0,0,0 "+l+" 0 a "+r+","+s+" 0,0,0 "+-l+" 0 l 0,"+n+" a "+r+","+s+" 0,0,0 "+l+" 0 l 0,"+-n,o=a.attr("label-offset-y",s).insert("path",":first-child").attr("style",t.style).attr("d",c).attr("transform","translate("+-l/2+","+-(n/2+s)+")");return m(t,o),t.intersect=function(h){const y=w.rect(t,h),f=y.x-t.x;if(r!=0&&(Math.abs(f)t.height/2-s)){let p=s*s*(1-f*f/(r*r));p!=0&&(p=Math.sqrt(p)),p=s-p,h.y-t.y>0&&(p=-p),y.y+=p}return y},a},Ut=async(e,t)=>{const{shapeSvg:a,bbox:i,halfPadding:l}=await M(e,t,"node "+t.classes+" "+t.class,!0),r=a.insert("rect",":first-child"),s=t.positioned?t.width:i.width+t.padding,n=t.positioned?t.height:i.height+t.padding,c=t.positioned?-s/2:-i.width/2-l,o=t.positioned?-n/2:-i.height/2-l;if(r.attr("class","basic label-container").attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",c).attr("y",o).attr("width",s).attr("height",n),t.props){const h=new Set(Object.keys(t.props));t.props.borders&&(Q(r,t.props.borders,s,n),h.delete("borders")),h.forEach(y=>{g.warn(`Unknown node property ${y}`)})}return m(t,r),t.intersect=function(h){return w.rect(t,h)},a},zt=async(e,t)=>{const{shapeSvg:a,bbox:i,halfPadding:l}=await M(e,t,"node "+t.classes,!0),r=a.insert("rect",":first-child"),s=t.positioned?t.width:i.width+t.padding,n=t.positioned?t.height:i.height+t.padding,c=t.positioned?-s/2:-i.width/2-l,o=t.positioned?-n/2:-i.height/2-l;if(r.attr("class","basic cluster composite label-container").attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",c).attr("y",o).attr("width",s).attr("height",n),t.props){const h=new Set(Object.keys(t.props));t.props.borders&&(Q(r,t.props.borders,s,n),h.delete("borders")),h.forEach(y=>{g.warn(`Unknown node property ${y}`)})}return m(t,r),t.intersect=function(h){return w.rect(t,h)},a},Zt=async(e,t)=>{const{shapeSvg:a}=await M(e,t,"label",!0);g.trace("Classes = ",t.class);const i=a.insert("rect",":first-child"),l=0,r=0;if(i.attr("width",l).attr("height",r),a.attr("class","label edgeLabel"),t.props){const s=new Set(Object.keys(t.props));t.props.borders&&(Q(i,t.props.borders,l,r),s.delete("borders")),s.forEach(n=>{g.warn(`Unknown node property ${n}`)})}return m(t,i),t.intersect=function(s){return w.rect(t,s)},a};function Q(e,t,a,i){const l=[],r=n=>{l.push(n,0)},s=n=>{l.push(0,n)};t.includes("t")?(g.debug("add top border"),r(a)):s(a),t.includes("r")?(g.debug("add right border"),r(i)):s(i),t.includes("b")?(g.debug("add bottom border"),r(a)):s(a),t.includes("l")?(g.debug("add left border"),r(i)):s(i),e.attr("stroke-dasharray",l.join(" "))}const Gt=(e,t)=>{let a;t.classes?a="node "+t.classes:a="node default";const i=e.insert("g").attr("class",a).attr("id",t.domId||t.id),l=i.insert("rect",":first-child"),r=i.insert("line"),s=i.insert("g").attr("class","label"),n=t.labelText.flat?t.labelText.flat():t.labelText;let c="";typeof n=="object"?c=n[0]:c=n,g.info("Label text abc79",c,n,typeof n=="object");const o=s.node().appendChild(R(c,t.labelStyle,!0,!0));let h={width:0,height:0};if(H(b().flowchart.htmlLabels)){const k=o.children[0],x=E(o);h=k.getBoundingClientRect(),x.attr("width",h.width),x.attr("height",h.height)}g.info("Text 2",n);const y=n.slice(1,n.length);let f=o.getBBox();const p=s.node().appendChild(R(y.join?y.join("
                        "):y,t.labelStyle,!0,!0));if(H(b().flowchart.htmlLabels)){const k=p.children[0],x=E(p);h=k.getBoundingClientRect(),x.attr("width",h.width),x.attr("height",h.height)}const d=t.padding/2;return E(p).attr("transform","translate( "+(h.width>f.width?0:(f.width-h.width)/2)+", "+(f.height+d+5)+")"),E(o).attr("transform","translate( "+(h.width{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.height+t.padding,r=i.width+l/4+t.padding,s=a.insert("rect",":first-child").attr("style",t.style).attr("rx",l/2).attr("ry",l/2).attr("x",-r/2).attr("y",-l/2).attr("width",r).attr("height",l);return m(t,s),t.intersect=function(n){return w.rect(t,n)},a},qt=async(e,t)=>{const{shapeSvg:a,bbox:i,halfPadding:l}=await M(e,t,_(t,void 0),!0),r=a.insert("circle",":first-child");return r.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("r",i.width/2+l).attr("width",i.width+t.padding).attr("height",i.height+t.padding),g.info("Circle main"),m(t,r),t.intersect=function(s){return g.info("Circle intersect",t,i.width/2+l,s),w.circle(t,i.width/2+l,s)},a},Qt=async(e,t)=>{const{shapeSvg:a,bbox:i,halfPadding:l}=await M(e,t,_(t,void 0),!0),r=5,s=a.insert("g",":first-child"),n=s.insert("circle"),c=s.insert("circle");return s.attr("class",t.class),n.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("r",i.width/2+l+r).attr("width",i.width+t.padding+r*2).attr("height",i.height+t.padding+r*2),c.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("r",i.width/2+l).attr("width",i.width+t.padding).attr("height",i.height+t.padding),g.info("DoubleCircle main"),m(t,n),t.intersect=function(o){return g.info("DoubleCircle intersect",t,i.width/2+l+r,o),w.circle(t,i.width/2+l+r,o)},a},Vt=async(e,t)=>{const{shapeSvg:a,bbox:i}=await M(e,t,_(t,void 0),!0),l=i.width+t.padding,r=i.height+t.padding,s=[{x:0,y:0},{x:l,y:0},{x:l,y:-r},{x:0,y:-r},{x:0,y:0},{x:-8,y:0},{x:l+8,y:0},{x:l+8,y:-r},{x:-8,y:-r},{x:-8,y:0}],n=I(a,l,r,s);return n.attr("style",t.style),m(t,n),t.intersect=function(c){return w.polygon(t,s,c)},a},Jt=(e,t)=>{const a=e.insert("g").attr("class","node default").attr("id",t.domId||t.id),i=a.insert("circle",":first-child");return i.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),m(t,i),t.intersect=function(l){return w.circle(t,7,l)},a},tt=(e,t,a)=>{const i=e.insert("g").attr("class","node default").attr("id",t.domId||t.id);let l=70,r=10;a==="LR"&&(l=10,r=70);const s=i.append("rect").attr("x",-1*l/2).attr("y",-1*r/2).attr("width",l).attr("height",r).attr("class","fork-join");return m(t,s),t.height=t.height+t.padding/2,t.width=t.width+t.padding/2,t.intersect=function(n){return w.rect(t,n)},i},Kt=(e,t)=>{const a=e.insert("g").attr("class","node default").attr("id",t.domId||t.id),i=a.insert("circle",":first-child"),l=a.insert("circle",":first-child");return l.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),i.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),m(t,l),t.intersect=function(r){return w.circle(t,7,r)},a},Pt=(e,t)=>{const a=t.padding/2,i=4,l=8;let r;t.classes?r="node "+t.classes:r="node default";const s=e.insert("g").attr("class",r).attr("id",t.domId||t.id),n=s.insert("rect",":first-child"),c=s.insert("line"),o=s.insert("line");let h=0,y=i;const f=s.insert("g").attr("class","label");let p=0;const d=t.classData.annotations&&t.classData.annotations[0],k=t.classData.annotations[0]?"«"+t.classData.annotations[0]+"»":"",x=f.node().appendChild(R(k,t.labelStyle,!0,!0));let u=x.getBBox();if(H(b().flowchart.htmlLabels)){const v=x.children[0],L=E(x);u=v.getBoundingClientRect(),L.attr("width",u.width),L.attr("height",u.height)}t.classData.annotations[0]&&(y+=u.height+i,h+=u.width);let S=t.classData.label;t.classData.type!==void 0&&t.classData.type!==""&&(b().flowchart.htmlLabels?S+="<"+t.classData.type+">":S+="<"+t.classData.type+">");const B=f.node().appendChild(R(S,t.labelStyle,!0,!0));E(B).attr("class","classTitle");let C=B.getBBox();if(H(b().flowchart.htmlLabels)){const v=B.children[0],L=E(B);C=v.getBoundingClientRect(),L.attr("width",C.width),L.attr("height",C.height)}y+=C.height+i,C.width>h&&(h=C.width);const X=[];t.classData.members.forEach(v=>{const L=v.getDisplayDetails();let W=L.displayText;b().flowchart.htmlLabels&&(W=W.replace(//g,">"));const N=f.node().appendChild(R(W,L.cssStyle?L.cssStyle:t.labelStyle,!0,!0));let $=N.getBBox();if(H(b().flowchart.htmlLabels)){const F=N.children[0],A=E(N);$=F.getBoundingClientRect(),A.attr("width",$.width),A.attr("height",$.height)}$.width>h&&(h=$.width),y+=$.height+i,X.push(N)}),y+=l;const D=[];if(t.classData.methods.forEach(v=>{const L=v.getDisplayDetails();let W=L.displayText;b().flowchart.htmlLabels&&(W=W.replace(//g,">"));const N=f.node().appendChild(R(W,L.cssStyle?L.cssStyle:t.labelStyle,!0,!0));let $=N.getBBox();if(H(b().flowchart.htmlLabels)){const F=N.children[0],A=E(N);$=F.getBoundingClientRect(),A.attr("width",$.width),A.attr("height",$.height)}$.width>h&&(h=$.width),y+=$.height+i,D.push(N)}),y+=l,d){let v=(h-u.width)/2;E(x).attr("transform","translate( "+(-1*h/2+v)+", "+-1*y/2+")"),p=u.height+i}let nt=(h-C.width)/2;return E(B).attr("transform","translate( "+(-1*h/2+nt)+", "+(-1*y/2+p)+")"),p+=C.height+i,c.attr("class","divider").attr("x1",-h/2-a).attr("x2",h/2+a).attr("y1",-y/2-a+l+p).attr("y2",-y/2-a+l+p),p+=l,X.forEach(v=>{E(v).attr("transform","translate( "+-h/2+", "+(-1*y/2+p+l/2)+")");const L=v==null?void 0:v.getBBox();p+=((L==null?void 0:L.height)??0)+i}),p+=l,o.attr("class","divider").attr("x1",-h/2-a).attr("x2",h/2+a).attr("y1",-y/2-a+l+p).attr("y2",-y/2-a+l+p),p+=l,D.forEach(v=>{E(v).attr("transform","translate( "+-h/2+", "+(-1*y/2+p)+")");const L=v==null?void 0:v.getBBox();p+=((L==null?void 0:L.height)??0)+i}),n.attr("style",t.style).attr("class","outer title-state").attr("x",-h/2-a).attr("y",-(y/2)-a).attr("width",h+t.padding).attr("height",y+t.padding),m(t,n),t.intersect=function(v){return w.rect(t,v)},s},rt={rhombus:P,composite:zt,question:P,rect:Ut,labelRect:Zt,rectWithTitle:Gt,choice:Ht,circle:qt,doublecircle:Qt,stadium:Ft,hexagon:It,block_arrow:Nt,rect_left_inv_arrow:Ot,lean_right:Wt,lean_left:Xt,trapezoid:Yt,inv_trapezoid:Dt,rect_right_inv_arrow:At,cylinder:jt,start:Jt,end:Kt,note:$t,subroutine:Vt,fork:tt,join:tt,class_box:Pt};let Y={};const or=async(e,t,a)=>{let i,l;if(t.link){let r;b().securityLevel==="sandbox"?r="_top":t.linkTarget&&(r=t.linkTarget||"_blank"),i=e.insert("svg:a").attr("xlink:href",t.link).attr("target",r),l=await rt[t.shape](i,t,a)}else l=await rt[t.shape](e,t,a),i=l;return t.tooltip&&l.attr("title",t.tooltip),t.class&&l.attr("class","node default "+t.class),i.attr("data-node","true"),i.attr("data-id",t.id),Y[t.id]=i,t.haveCallback&&Y[t.id].attr("class",Y[t.id].attr("class")+" clickable"),i},yr=(e,t)=>{Y[t.id]=e},pr=()=>{Y={}},fr=e=>{const t=Y[e.id];g.trace("Transforming node",e.diff,e,"translate("+(e.x-e.width/2-5)+", "+e.width/2+")");const a=8,i=e.diff||0;return e.clusterNode?t.attr("transform","translate("+(e.x+i-e.width/2)+", "+(e.y-e.height/2-a)+")"):t.attr("transform","translate("+e.x+", "+e.y+")"),i},tr=({flowchart:e})=>{var t,a;const i=((t=e==null?void 0:e.subGraphTitleMargin)==null?void 0:t.top)??0,l=((a=e==null?void 0:e.subGraphTitleMargin)==null?void 0:a.bottom)??0,r=i+l;return{subGraphTitleTopMargin:i,subGraphTitleBottomMargin:l,subGraphTitleTotalMargin:r}},O={aggregation:18,extension:18,composition:18,dependency:6,lollipop:13.5,arrow_point:5.3};function U(e,t){if(e===void 0||t===void 0)return{angle:0,deltaX:0,deltaY:0};e=Z(e),t=Z(t);const[a,i]=[e.x,e.y],[l,r]=[t.x,t.y],s=l-a,n=r-i;return{angle:Math.atan(n/s),deltaX:s,deltaY:n}}const Z=e=>Array.isArray(e)?{x:e[0],y:e[1]}:e,rr=e=>({x:function(t,a,i){let l=0;if(a===0&&Object.hasOwn(O,e.arrowTypeStart)){const{angle:r,deltaX:s}=U(i[0],i[1]);l=O[e.arrowTypeStart]*Math.cos(r)*(s>=0?1:-1)}else if(a===i.length-1&&Object.hasOwn(O,e.arrowTypeEnd)){const{angle:r,deltaX:s}=U(i[i.length-1],i[i.length-2]);l=O[e.arrowTypeEnd]*Math.cos(r)*(s>=0?1:-1)}return Z(t).x+l},y:function(t,a,i){let l=0;if(a===0&&Object.hasOwn(O,e.arrowTypeStart)){const{angle:r,deltaY:s}=U(i[0],i[1]);l=O[e.arrowTypeStart]*Math.abs(Math.sin(r))*(s>=0?1:-1)}else if(a===i.length-1&&Object.hasOwn(O,e.arrowTypeEnd)){const{angle:r,deltaY:s}=U(i[i.length-1],i[i.length-2]);l=O[e.arrowTypeEnd]*Math.abs(Math.sin(r))*(s>=0?1:-1)}return Z(t).y+l}}),ar=(e,t,a,i,l)=>{t.arrowTypeStart&&at(e,"start",t.arrowTypeStart,a,i,l),t.arrowTypeEnd&&at(e,"end",t.arrowTypeEnd,a,i,l)},er={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},at=(e,t,a,i,l,r)=>{const s=er[a];if(!s){g.warn(`Unknown arrow type: ${a}`);return}const n=t==="start"?"Start":"End";e.attr(`marker-${t}`,`url(${i}#${l}_${r}-${s}${n})`)};let G={},T={};const xr=()=>{G={},T={}},dr=(e,t)=>{const a=H(b().flowchart.htmlLabels),i=t.labelType==="markdown"?st(e,t.label,{style:t.labelStyle,useHtmlLabels:a,addSvgBackground:!0}):R(t.label,t.labelStyle),l=e.insert("g").attr("class","edgeLabel"),r=l.insert("g").attr("class","label");r.node().appendChild(i);let s=i.getBBox();if(a){const c=i.children[0],o=E(i);s=c.getBoundingClientRect(),o.attr("width",s.width),o.attr("height",s.height)}r.attr("transform","translate("+-s.width/2+", "+-s.height/2+")"),G[t.id]=l,t.width=s.width,t.height=s.height;let n;if(t.startLabelLeft){const c=R(t.startLabelLeft,t.labelStyle),o=e.insert("g").attr("class","edgeTerminals"),h=o.insert("g").attr("class","inner");n=h.node().appendChild(c);const y=c.getBBox();h.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),T[t.id]||(T[t.id]={}),T[t.id].startLeft=o,z(n,t.startLabelLeft)}if(t.startLabelRight){const c=R(t.startLabelRight,t.labelStyle),o=e.insert("g").attr("class","edgeTerminals"),h=o.insert("g").attr("class","inner");n=o.node().appendChild(c),h.node().appendChild(c);const y=c.getBBox();h.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),T[t.id]||(T[t.id]={}),T[t.id].startRight=o,z(n,t.startLabelRight)}if(t.endLabelLeft){const c=R(t.endLabelLeft,t.labelStyle),o=e.insert("g").attr("class","edgeTerminals"),h=o.insert("g").attr("class","inner");n=h.node().appendChild(c);const y=c.getBBox();h.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),o.node().appendChild(c),T[t.id]||(T[t.id]={}),T[t.id].endLeft=o,z(n,t.endLabelLeft)}if(t.endLabelRight){const c=R(t.endLabelRight,t.labelStyle),o=e.insert("g").attr("class","edgeTerminals"),h=o.insert("g").attr("class","inner");n=h.node().appendChild(c);const y=c.getBBox();h.attr("transform","translate("+-y.width/2+", "+-y.height/2+")"),o.node().appendChild(c),T[t.id]||(T[t.id]={}),T[t.id].endRight=o,z(n,t.endLabelRight)}return i};function z(e,t){b().flowchart.htmlLabels&&e&&(e.style.width=t.length*9+"px",e.style.height="12px")}const gr=(e,t)=>{g.debug("Moving label abc88 ",e.id,e.label,G[e.id],t);let a=t.updatedPath?t.updatedPath:t.originalPath;const i=b(),{subGraphTitleTotalMargin:l}=tr(i);if(e.label){const r=G[e.id];let s=e.x,n=e.y;if(a){const c=j.calcLabelPosition(a);g.debug("Moving label "+e.label+" from (",s,",",n,") to (",c.x,",",c.y,") abc88"),t.updatedPath&&(s=c.x,n=c.y)}r.attr("transform",`translate(${s}, ${n+l/2})`)}if(e.startLabelLeft){const r=T[e.id].startLeft;let s=e.x,n=e.y;if(a){const c=j.calcTerminalLabelPosition(e.arrowTypeStart?10:0,"start_left",a);s=c.x,n=c.y}r.attr("transform",`translate(${s}, ${n})`)}if(e.startLabelRight){const r=T[e.id].startRight;let s=e.x,n=e.y;if(a){const c=j.calcTerminalLabelPosition(e.arrowTypeStart?10:0,"start_right",a);s=c.x,n=c.y}r.attr("transform",`translate(${s}, ${n})`)}if(e.endLabelLeft){const r=T[e.id].endLeft;let s=e.x,n=e.y;if(a){const c=j.calcTerminalLabelPosition(e.arrowTypeEnd?10:0,"end_left",a);s=c.x,n=c.y}r.attr("transform",`translate(${s}, ${n})`)}if(e.endLabelRight){const r=T[e.id].endRight;let s=e.x,n=e.y;if(a){const c=j.calcTerminalLabelPosition(e.arrowTypeEnd?10:0,"end_right",a);s=c.x,n=c.y}r.attr("transform",`translate(${s}, ${n})`)}},sr=(e,t)=>{const a=e.x,i=e.y,l=Math.abs(t.x-a),r=Math.abs(t.y-i),s=e.width/2,n=e.height/2;return l>=s||r>=n},ir=(e,t,a)=>{g.debug(`intersection calc abc89: outsidePoint: ${JSON.stringify(t)} insidePoint : ${JSON.stringify(a)} node : x:${e.x} y:${e.y} w:${e.width} h:${e.height}`);const i=e.x,l=e.y,r=Math.abs(i-a.x),s=e.width/2;let n=a.xMath.abs(i-t.x)*c){let y=a.y{g.debug("abc88 cutPathAtIntersect",e,t);let a=[],i=e[0],l=!1;return e.forEach(r=>{if(!sr(t,r)&&!l){const s=ir(t,i,r);let n=!1;a.forEach(c=>{n=n||c.x===s.x&&c.y===s.y}),a.some(c=>c.x===s.x&&c.y===s.y)||a.push(s),l=!0}else i=r,l||a.push(r)}),a},ur=function(e,t,a,i,l,r,s){let n=a.points;g.debug("abc88 InsertEdge: edge=",a,"e=",t);let c=!1;const o=r.node(t.v);var h=r.node(t.w);h!=null&&h.intersect&&(o!=null&&o.intersect)&&(n=n.slice(1,a.points.length-1),n.unshift(o.intersect(n[0])),n.push(h.intersect(n[n.length-1]))),a.toCluster&&(g.debug("to cluster abc88",i[a.toCluster]),n=et(a.points,i[a.toCluster].node),c=!0),a.fromCluster&&(g.debug("from cluster abc88",i[a.fromCluster]),n=et(n.reverse(),i[a.fromCluster].node).reverse(),c=!0);const y=n.filter(C=>!Number.isNaN(C.y));let f=lt;a.curve&&(l==="graph"||l==="flowchart")&&(f=a.curve);const{x:p,y:d}=rr(a),k=ct().x(p).y(d).curve(f);let x;switch(a.thickness){case"normal":x="edge-thickness-normal";break;case"thick":x="edge-thickness-thick";break;case"invisible":x="edge-thickness-thick";break;default:x=""}switch(a.pattern){case"solid":x+=" edge-pattern-solid";break;case"dotted":x+=" edge-pattern-dotted";break;case"dashed":x+=" edge-pattern-dashed";break}const u=e.append("path").attr("d",k(y)).attr("id",a.id).attr("class"," "+x+(a.classes?" "+a.classes:"")).attr("style",a.style);let S="";(b().flowchart.arrowMarkerAbsolute||b().state.arrowMarkerAbsolute)&&(S=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,S=S.replace(/\(/g,"\\("),S=S.replace(/\)/g,"\\)")),ar(u,a,S,s,l);let B={};return c&&(B.updatedPath=n),B.originalPath=a.points,B};export{or as a,dr as b,ur as c,gr as d,pr as e,xr as f,tr as g,R as h,hr as i,Et as j,rr as k,M as l,ar as m,fr as p,yr as s,m as u}; diff --git a/assets/env.html-UjH5T2XA.js b/assets/env.html-98sQ-YHZ.js similarity index 97% rename from assets/env.html-UjH5T2XA.js rename to assets/env.html-98sQ-YHZ.js index 13a38c1506..bf5e9b36b6 100644 --- a/assets/env.html-UjH5T2XA.js +++ b/assets/env.html-98sQ-YHZ.js @@ -1,4 +1,4 @@ -import{_ as o,r as t,o as l,c as s,a as e,b as a,d as c,e as r}from"./app-PDrbPfzp.js";const i={},d=e("h1",{id:"环境变量",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#环境变量"},[e("span",null,"环境变量")])],-1),_=e("p",null,"Xray 提供以下环境变量以供修改 Xray 的一些底层配置。",-1),h=e("h2",{id:"资源文件路径",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#资源文件路径"},[e("span",null,"资源文件路径")])],-1),u=e("li",null,[a("名称:"),e("code",null,"xray.location.asset"),a(" 或 "),e("code",null,"XRAY_LOCATION_ASSET"),a("。")],-1),p={href:"https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard",target:"_blank",rel:"noopener noreferrer"},x=r(`

                        这个环境变量指定了一个文件夹位置,这个文件夹应当包含 geoip.dat 和 geosite.dat 文件。 若无指定变量值,程序将会按以下顺序寻找资源文件:

                        ./
                        +import{_ as o,r as t,o as l,c as s,a as e,b as a,d as c,e as r}from"./app-UOvWaKji.js";const i={},d=e("h1",{id:"环境变量",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#环境变量"},[e("span",null,"环境变量")])],-1),_=e("p",null,"Xray 提供以下环境变量以供修改 Xray 的一些底层配置。",-1),h=e("h2",{id:"资源文件路径",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#资源文件路径"},[e("span",null,"资源文件路径")])],-1),u=e("li",null,[a("名称:"),e("code",null,"xray.location.asset"),a(" 或 "),e("code",null,"XRAY_LOCATION_ASSET"),a("。")],-1),p={href:"https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard",target:"_blank",rel:"noopener noreferrer"},x=r(`

                        这个环境变量指定了一个文件夹位置,这个文件夹应当包含 geoip.dat 和 geosite.dat 文件。 若无指定变量值,程序将会按以下顺序寻找资源文件:

                        ./
                         /usr/local/share/xray
                         /usr/share/xray
                         

                        配置文件位置

                        • 名称:xray.location.configXRAY_LOCATION_CONFIG
                        • 默认值:和 Xray 文件同路径。

                        这个环境变量指定了一个文件夹位置,这个文件夹应当包含 config.json 文件。

                        多配置目录

                        • 名称:xray.location.confdirXRAY_LOCATION_CONFDIR
                        • 默认值:""

                        这个目录内的 .json 文件会按文件名顺序读取,作为多配置选项。

                        `,8);function f(m,v){const n=t("ExternalLinkIcon");return l(),s("div",null,[d,_,h,e("ul",null,[u,e("li",null,[a("默认值:特定 "),e("a",p,[a("FHS"),c(n)]),a(" 目录或 Xray 文件同路径。")])]),x])}const y=o(i,[["render",f],["__file","env.html.vue"]]);export{y as default}; diff --git a/assets/env.html-sFYt-_pK.js b/assets/env.html-Wh-9-BVt.js similarity index 97% rename from assets/env.html-sFYt-_pK.js rename to assets/env.html-Wh-9-BVt.js index 1035a64021..131b45e7f4 100644 --- a/assets/env.html-sFYt-_pK.js +++ b/assets/env.html-Wh-9-BVt.js @@ -1,4 +1,4 @@ -import{_ as i,r as n,o as t,c as l,a as e,b as a,d as r,e as s}from"./app-PDrbPfzp.js";const c={},d=e("h1",{id:"environment-variables",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#environment-variables"},[e("span",null,"Environment Variables")])],-1),u=e("p",null,"Xray provides the following environment variables for modifying some of its underlying configurations.",-1),h=e("h2",{id:"xray-asset-location",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#xray-asset-location"},[e("span",null,"Xray Asset Location")])],-1),f=e("li",null,[a("Name:"),e("code",null,"xray.location.asset"),a(" or "),e("code",null,"XRAY_LOCATION_ASSET"),a("。")],-1),p={href:"https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard",target:"_blank",rel:"noopener noreferrer"},_=s(`

                        This environment variable specifies a folder location that should contain the geoip.dat and geosite.dat files. If no variable value is specified, the program will search for resource files in the following order:

                        ./
                        +import{_ as i,r as n,o as t,c as l,a as e,b as a,d as r,e as s}from"./app-UOvWaKji.js";const c={},d=e("h1",{id:"environment-variables",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#environment-variables"},[e("span",null,"Environment Variables")])],-1),u=e("p",null,"Xray provides the following environment variables for modifying some of its underlying configurations.",-1),h=e("h2",{id:"xray-asset-location",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#xray-asset-location"},[e("span",null,"Xray Asset Location")])],-1),f=e("li",null,[a("Name:"),e("code",null,"xray.location.asset"),a(" or "),e("code",null,"XRAY_LOCATION_ASSET"),a("。")],-1),p={href:"https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard",target:"_blank",rel:"noopener noreferrer"},_=s(`

                        This environment variable specifies a folder location that should contain the geoip.dat and geosite.dat files. If no variable value is specified, the program will search for resource files in the following order:

                        ./
                         /usr/local/share/xray
                         /usr/share/xray
                         

                        Configuration File Location

                        • Name:xray.location.config or XRAY_LOCATION_CONFIG
                        • Default value: Same path as the Xray file.

                        This environment variable specifies a folder location that should contain the config.json file.

                        Multiple Configuration Directories

                        • Name:xray.location.confdir or XRAY_LOCATION_CONFDIR
                        • Default value:""

                        The .json files in this directory will be read in alphabetical order by filename and used as options for multiple configurations.

                        `,8);function m(v,g){const o=n("ExternalLinkIcon");return t(),l("div",null,[d,u,h,e("ul",null,[f,e("li",null,[a("Default value:specified "),e("a",p,[a("FHS"),r(o)]),a(" directory or the same path as the Xray file.")])]),_])}const b=i(c,[["render",m],["__file","env.html.vue"]]);export{b as default}; diff --git a/assets/erDiagram-47591fe2-CbfSLOL9.js b/assets/erDiagram-47591fe2-RWR6JLP0.js similarity index 99% rename from assets/erDiagram-47591fe2-CbfSLOL9.js rename to assets/erDiagram-47591fe2-RWR6JLP0.js index c25c4daf8c..bdfe101423 100644 --- a/assets/erDiagram-47591fe2-CbfSLOL9.js +++ b/assets/erDiagram-47591fe2-RWR6JLP0.js @@ -1,4 +1,4 @@ -import{c as Z,s as Et,g as mt,b as gt,a as kt,x as xt,y as Rt,l as V,A as Ot,h as rt,z as bt,i as Nt,ap as Tt,as as At}from"./mermaid.core-95b3ca__.js";import{G as Mt}from"./graph-cZfODKa1.js";import{l as St}from"./layout-konkdG3Z.js";import{l as wt}from"./line-_nnM_7ZX.js";import"./app-PDrbPfzp.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";const It=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function Dt(t){return typeof t=="string"&&It.test(t)}const A=[];for(let t=0;t<256;++t)A.push((t+256).toString(16).slice(1));function vt(t,e=0){return A[t[e+0]]+A[t[e+1]]+A[t[e+2]]+A[t[e+3]]+"-"+A[t[e+4]]+A[t[e+5]]+"-"+A[t[e+6]]+A[t[e+7]]+"-"+A[t[e+8]]+A[t[e+9]]+"-"+A[t[e+10]]+A[t[e+11]]+A[t[e+12]]+A[t[e+13]]+A[t[e+14]]+A[t[e+15]]}function Lt(t){if(!Dt(t))throw TypeError("Invalid UUID");let e;const r=new Uint8Array(16);return r[0]=(e=parseInt(t.slice(0,8),16))>>>24,r[1]=e>>>16&255,r[2]=e>>>8&255,r[3]=e&255,r[4]=(e=parseInt(t.slice(9,13),16))>>>8,r[5]=e&255,r[6]=(e=parseInt(t.slice(14,18),16))>>>8,r[7]=e&255,r[8]=(e=parseInt(t.slice(19,23),16))>>>8,r[9]=e&255,r[10]=(e=parseInt(t.slice(24,36),16))/1099511627776&255,r[11]=e/4294967296&255,r[12]=e>>>24&255,r[13]=e>>>16&255,r[14]=e>>>8&255,r[15]=e&255,r}function Bt(t){t=unescape(encodeURIComponent(t));const e=[];for(let r=0;r>>32-e}function Ft(t){const e=[1518500249,1859775393,2400959708,3395469782],r=[1732584193,4023233417,2562383102,271733878,3285377520];if(typeof t=="string"){const f=unescape(encodeURIComponent(t));t=[];for(let o=0;o>>0;x=g,g=m,m=it(_,30)>>>0,_=h,h=I}r[0]=r[0]+h>>>0,r[1]=r[1]+_>>>0,r[2]=r[2]+m>>>0,r[3]=r[3]+g>>>0,r[4]=r[4]+x>>>0}return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,r[0]&255,r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,r[1]&255,r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,r[2]&255,r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,r[3]&255,r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,r[4]&255]}const Wt=Yt("v5",80,Ft);var at=function(){var t=function(S,a,n,c){for(n=n||{},c=S.length;c--;n[S[c]]=a);return n},e=[6,8,10,20,22,24,26,27,28],r=[1,10],u=[1,11],l=[1,12],p=[1,13],f=[1,14],o=[1,15],h=[1,21],_=[1,22],m=[1,23],g=[1,24],x=[1,25],y=[6,8,10,13,15,18,19,20,22,24,26,27,28,41,42,43,44,45],N=[1,34],I=[27,28,46,47],F=[41,42,43,44,45],W=[17,34],C=[1,54],T=[1,53],M=[17,34,36,38],R={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,":":13,role:14,BLOCK_START:15,attributes:16,BLOCK_STOP:17,SQS:18,SQE:19,title:20,title_value:21,acc_title:22,acc_title_value:23,acc_descr:24,acc_descr_value:25,acc_descr_multiline_value:26,ALPHANUM:27,ENTITY_NAME:28,attribute:29,attributeType:30,attributeName:31,attributeKeyTypeList:32,attributeComment:33,ATTRIBUTE_WORD:34,attributeKeyType:35,COMMA:36,ATTRIBUTE_KEY:37,COMMENT:38,cardinality:39,relType:40,ZERO_OR_ONE:41,ZERO_OR_MORE:42,ONE_OR_MORE:43,ONLY_ONE:44,MD_PARENT:45,NON_IDENTIFYING:46,IDENTIFYING:47,WORD:48,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:":",15:"BLOCK_START",17:"BLOCK_STOP",18:"SQS",19:"SQE",20:"title",21:"title_value",22:"acc_title",23:"acc_title_value",24:"acc_descr",25:"acc_descr_value",26:"acc_descr_multiline_value",27:"ALPHANUM",28:"ENTITY_NAME",34:"ATTRIBUTE_WORD",36:"COMMA",37:"ATTRIBUTE_KEY",38:"COMMENT",41:"ZERO_OR_ONE",42:"ZERO_OR_MORE",43:"ONE_OR_MORE",44:"ONLY_ONE",45:"MD_PARENT",46:"NON_IDENTIFYING",47:"IDENTIFYING",48:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,4],[9,3],[9,1],[9,7],[9,6],[9,4],[9,2],[9,2],[9,2],[9,1],[11,1],[11,1],[16,1],[16,2],[29,2],[29,3],[29,3],[29,4],[30,1],[31,1],[32,1],[32,3],[35,1],[33,1],[12,3],[39,1],[39,1],[39,1],[39,1],[39,1],[40,1],[40,1],[14,1],[14,1],[14,1]],performAction:function(a,n,c,d,E,i,K){var s=i.length-1;switch(E){case 1:break;case 2:this.$=[];break;case 3:i[s-1].push(i[s]),this.$=i[s-1];break;case 4:case 5:this.$=i[s];break;case 6:case 7:this.$=[];break;case 8:d.addEntity(i[s-4]),d.addEntity(i[s-2]),d.addRelationship(i[s-4],i[s],i[s-2],i[s-3]);break;case 9:d.addEntity(i[s-3]),d.addAttributes(i[s-3],i[s-1]);break;case 10:d.addEntity(i[s-2]);break;case 11:d.addEntity(i[s]);break;case 12:d.addEntity(i[s-6],i[s-4]),d.addAttributes(i[s-6],i[s-1]);break;case 13:d.addEntity(i[s-5],i[s-3]);break;case 14:d.addEntity(i[s-3],i[s-1]);break;case 15:case 16:this.$=i[s].trim(),d.setAccTitle(this.$);break;case 17:case 18:this.$=i[s].trim(),d.setAccDescription(this.$);break;case 19:case 43:this.$=i[s];break;case 20:case 41:case 42:this.$=i[s].replace(/"/g,"");break;case 21:case 29:this.$=[i[s]];break;case 22:i[s].push(i[s-1]),this.$=i[s];break;case 23:this.$={attributeType:i[s-1],attributeName:i[s]};break;case 24:this.$={attributeType:i[s-2],attributeName:i[s-1],attributeKeyTypeList:i[s]};break;case 25:this.$={attributeType:i[s-2],attributeName:i[s-1],attributeComment:i[s]};break;case 26:this.$={attributeType:i[s-3],attributeName:i[s-2],attributeKeyTypeList:i[s-1],attributeComment:i[s]};break;case 27:case 28:case 31:this.$=i[s];break;case 30:i[s-2].push(i[s]),this.$=i[s-2];break;case 32:this.$=i[s].replace(/"/g,"");break;case 33:this.$={cardA:i[s],relType:i[s-1],cardB:i[s-2]};break;case 34:this.$=d.Cardinality.ZERO_OR_ONE;break;case 35:this.$=d.Cardinality.ZERO_OR_MORE;break;case 36:this.$=d.Cardinality.ONE_OR_MORE;break;case 37:this.$=d.Cardinality.ONLY_ONE;break;case 38:this.$=d.Cardinality.MD_PARENT;break;case 39:this.$=d.Identification.NON_IDENTIFYING;break;case 40:this.$=d.Identification.IDENTIFYING;break}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,20:r,22:u,24:l,26:p,27:f,28:o},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:16,11:9,20:r,22:u,24:l,26:p,27:f,28:o},t(e,[2,5]),t(e,[2,6]),t(e,[2,11],{12:17,39:20,15:[1,18],18:[1,19],41:h,42:_,43:m,44:g,45:x}),{21:[1,26]},{23:[1,27]},{25:[1,28]},t(e,[2,18]),t(y,[2,19]),t(y,[2,20]),t(e,[2,4]),{11:29,27:f,28:o},{16:30,17:[1,31],29:32,30:33,34:N},{11:35,27:f,28:o},{40:36,46:[1,37],47:[1,38]},t(I,[2,34]),t(I,[2,35]),t(I,[2,36]),t(I,[2,37]),t(I,[2,38]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),{13:[1,39]},{17:[1,40]},t(e,[2,10]),{16:41,17:[2,21],29:32,30:33,34:N},{31:42,34:[1,43]},{34:[2,27]},{19:[1,44]},{39:45,41:h,42:_,43:m,44:g,45:x},t(F,[2,39]),t(F,[2,40]),{14:46,27:[1,49],28:[1,48],48:[1,47]},t(e,[2,9]),{17:[2,22]},t(W,[2,23],{32:50,33:51,35:52,37:C,38:T}),t([17,34,37,38],[2,28]),t(e,[2,14],{15:[1,55]}),t([27,28],[2,33]),t(e,[2,8]),t(e,[2,41]),t(e,[2,42]),t(e,[2,43]),t(W,[2,24],{33:56,36:[1,57],38:T}),t(W,[2,25]),t(M,[2,29]),t(W,[2,32]),t(M,[2,31]),{16:58,17:[1,59],29:32,30:33,34:N},t(W,[2,26]),{35:60,37:C},{17:[1,61]},t(e,[2,13]),t(M,[2,30]),t(e,[2,12])],defaultActions:{34:[2,27],41:[2,22]},parseError:function(a,n){if(n.recoverable)this.trace(a);else{var c=new Error(a);throw c.hash=n,c}},parse:function(a){var n=this,c=[0],d=[],E=[null],i=[],K=this.table,s="",Q=0,st=0,ft=2,ot=1,yt=i.slice.call(arguments,1),b=Object.create(this.lexer),z={yy:{}};for(var J in this.yy)Object.prototype.hasOwnProperty.call(this.yy,J)&&(z.yy[J]=this.yy[J]);b.setInput(a,z.yy),z.yy.lexer=b,z.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var $=b.yylloc;i.push($);var pt=b.options&&b.options.ranges;typeof z.yy.parseError=="function"?this.parseError=z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function _t(){var Y;return Y=d.pop()||b.lex()||ot,typeof Y!="number"&&(Y instanceof Array&&(d=Y,Y=d.pop()),Y=n.symbols_[Y]||Y),Y}for(var w,H,D,tt,G={},j,P,lt,q;;){if(H=c[c.length-1],this.defaultActions[H]?D=this.defaultActions[H]:((w===null||typeof w>"u")&&(w=_t()),D=K[H]&&K[H][w]),typeof D>"u"||!D.length||!D[0]){var et="";q=[];for(j in K[H])this.terminals_[j]&&j>ft&&q.push("'"+this.terminals_[j]+"'");b.showPosition?et="Parse error on line "+(Q+1)+`: +import{c as Z,s as Et,g as mt,b as gt,a as kt,x as xt,y as Rt,l as V,A as Ot,h as rt,z as bt,i as Nt,ap as Tt,as as At}from"./mermaid.core-Q3WVcjPF.js";import{G as Mt}from"./graph-yVkSecXb.js";import{l as St}from"./layout-2f_iGf4E.js";import{l as wt}from"./line-3Gyevr9q.js";import"./app-UOvWaKji.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";const It=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function Dt(t){return typeof t=="string"&&It.test(t)}const A=[];for(let t=0;t<256;++t)A.push((t+256).toString(16).slice(1));function vt(t,e=0){return A[t[e+0]]+A[t[e+1]]+A[t[e+2]]+A[t[e+3]]+"-"+A[t[e+4]]+A[t[e+5]]+"-"+A[t[e+6]]+A[t[e+7]]+"-"+A[t[e+8]]+A[t[e+9]]+"-"+A[t[e+10]]+A[t[e+11]]+A[t[e+12]]+A[t[e+13]]+A[t[e+14]]+A[t[e+15]]}function Lt(t){if(!Dt(t))throw TypeError("Invalid UUID");let e;const r=new Uint8Array(16);return r[0]=(e=parseInt(t.slice(0,8),16))>>>24,r[1]=e>>>16&255,r[2]=e>>>8&255,r[3]=e&255,r[4]=(e=parseInt(t.slice(9,13),16))>>>8,r[5]=e&255,r[6]=(e=parseInt(t.slice(14,18),16))>>>8,r[7]=e&255,r[8]=(e=parseInt(t.slice(19,23),16))>>>8,r[9]=e&255,r[10]=(e=parseInt(t.slice(24,36),16))/1099511627776&255,r[11]=e/4294967296&255,r[12]=e>>>24&255,r[13]=e>>>16&255,r[14]=e>>>8&255,r[15]=e&255,r}function Bt(t){t=unescape(encodeURIComponent(t));const e=[];for(let r=0;r>>32-e}function Ft(t){const e=[1518500249,1859775393,2400959708,3395469782],r=[1732584193,4023233417,2562383102,271733878,3285377520];if(typeof t=="string"){const f=unescape(encodeURIComponent(t));t=[];for(let o=0;o>>0;x=g,g=m,m=it(_,30)>>>0,_=h,h=I}r[0]=r[0]+h>>>0,r[1]=r[1]+_>>>0,r[2]=r[2]+m>>>0,r[3]=r[3]+g>>>0,r[4]=r[4]+x>>>0}return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,r[0]&255,r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,r[1]&255,r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,r[2]&255,r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,r[3]&255,r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,r[4]&255]}const Wt=Yt("v5",80,Ft);var at=function(){var t=function(S,a,n,c){for(n=n||{},c=S.length;c--;n[S[c]]=a);return n},e=[6,8,10,20,22,24,26,27,28],r=[1,10],u=[1,11],l=[1,12],p=[1,13],f=[1,14],o=[1,15],h=[1,21],_=[1,22],m=[1,23],g=[1,24],x=[1,25],y=[6,8,10,13,15,18,19,20,22,24,26,27,28,41,42,43,44,45],N=[1,34],I=[27,28,46,47],F=[41,42,43,44,45],W=[17,34],C=[1,54],T=[1,53],M=[17,34,36,38],R={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,":":13,role:14,BLOCK_START:15,attributes:16,BLOCK_STOP:17,SQS:18,SQE:19,title:20,title_value:21,acc_title:22,acc_title_value:23,acc_descr:24,acc_descr_value:25,acc_descr_multiline_value:26,ALPHANUM:27,ENTITY_NAME:28,attribute:29,attributeType:30,attributeName:31,attributeKeyTypeList:32,attributeComment:33,ATTRIBUTE_WORD:34,attributeKeyType:35,COMMA:36,ATTRIBUTE_KEY:37,COMMENT:38,cardinality:39,relType:40,ZERO_OR_ONE:41,ZERO_OR_MORE:42,ONE_OR_MORE:43,ONLY_ONE:44,MD_PARENT:45,NON_IDENTIFYING:46,IDENTIFYING:47,WORD:48,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:":",15:"BLOCK_START",17:"BLOCK_STOP",18:"SQS",19:"SQE",20:"title",21:"title_value",22:"acc_title",23:"acc_title_value",24:"acc_descr",25:"acc_descr_value",26:"acc_descr_multiline_value",27:"ALPHANUM",28:"ENTITY_NAME",34:"ATTRIBUTE_WORD",36:"COMMA",37:"ATTRIBUTE_KEY",38:"COMMENT",41:"ZERO_OR_ONE",42:"ZERO_OR_MORE",43:"ONE_OR_MORE",44:"ONLY_ONE",45:"MD_PARENT",46:"NON_IDENTIFYING",47:"IDENTIFYING",48:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,4],[9,3],[9,1],[9,7],[9,6],[9,4],[9,2],[9,2],[9,2],[9,1],[11,1],[11,1],[16,1],[16,2],[29,2],[29,3],[29,3],[29,4],[30,1],[31,1],[32,1],[32,3],[35,1],[33,1],[12,3],[39,1],[39,1],[39,1],[39,1],[39,1],[40,1],[40,1],[14,1],[14,1],[14,1]],performAction:function(a,n,c,d,E,i,K){var s=i.length-1;switch(E){case 1:break;case 2:this.$=[];break;case 3:i[s-1].push(i[s]),this.$=i[s-1];break;case 4:case 5:this.$=i[s];break;case 6:case 7:this.$=[];break;case 8:d.addEntity(i[s-4]),d.addEntity(i[s-2]),d.addRelationship(i[s-4],i[s],i[s-2],i[s-3]);break;case 9:d.addEntity(i[s-3]),d.addAttributes(i[s-3],i[s-1]);break;case 10:d.addEntity(i[s-2]);break;case 11:d.addEntity(i[s]);break;case 12:d.addEntity(i[s-6],i[s-4]),d.addAttributes(i[s-6],i[s-1]);break;case 13:d.addEntity(i[s-5],i[s-3]);break;case 14:d.addEntity(i[s-3],i[s-1]);break;case 15:case 16:this.$=i[s].trim(),d.setAccTitle(this.$);break;case 17:case 18:this.$=i[s].trim(),d.setAccDescription(this.$);break;case 19:case 43:this.$=i[s];break;case 20:case 41:case 42:this.$=i[s].replace(/"/g,"");break;case 21:case 29:this.$=[i[s]];break;case 22:i[s].push(i[s-1]),this.$=i[s];break;case 23:this.$={attributeType:i[s-1],attributeName:i[s]};break;case 24:this.$={attributeType:i[s-2],attributeName:i[s-1],attributeKeyTypeList:i[s]};break;case 25:this.$={attributeType:i[s-2],attributeName:i[s-1],attributeComment:i[s]};break;case 26:this.$={attributeType:i[s-3],attributeName:i[s-2],attributeKeyTypeList:i[s-1],attributeComment:i[s]};break;case 27:case 28:case 31:this.$=i[s];break;case 30:i[s-2].push(i[s]),this.$=i[s-2];break;case 32:this.$=i[s].replace(/"/g,"");break;case 33:this.$={cardA:i[s],relType:i[s-1],cardB:i[s-2]};break;case 34:this.$=d.Cardinality.ZERO_OR_ONE;break;case 35:this.$=d.Cardinality.ZERO_OR_MORE;break;case 36:this.$=d.Cardinality.ONE_OR_MORE;break;case 37:this.$=d.Cardinality.ONLY_ONE;break;case 38:this.$=d.Cardinality.MD_PARENT;break;case 39:this.$=d.Identification.NON_IDENTIFYING;break;case 40:this.$=d.Identification.IDENTIFYING;break}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,20:r,22:u,24:l,26:p,27:f,28:o},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:16,11:9,20:r,22:u,24:l,26:p,27:f,28:o},t(e,[2,5]),t(e,[2,6]),t(e,[2,11],{12:17,39:20,15:[1,18],18:[1,19],41:h,42:_,43:m,44:g,45:x}),{21:[1,26]},{23:[1,27]},{25:[1,28]},t(e,[2,18]),t(y,[2,19]),t(y,[2,20]),t(e,[2,4]),{11:29,27:f,28:o},{16:30,17:[1,31],29:32,30:33,34:N},{11:35,27:f,28:o},{40:36,46:[1,37],47:[1,38]},t(I,[2,34]),t(I,[2,35]),t(I,[2,36]),t(I,[2,37]),t(I,[2,38]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),{13:[1,39]},{17:[1,40]},t(e,[2,10]),{16:41,17:[2,21],29:32,30:33,34:N},{31:42,34:[1,43]},{34:[2,27]},{19:[1,44]},{39:45,41:h,42:_,43:m,44:g,45:x},t(F,[2,39]),t(F,[2,40]),{14:46,27:[1,49],28:[1,48],48:[1,47]},t(e,[2,9]),{17:[2,22]},t(W,[2,23],{32:50,33:51,35:52,37:C,38:T}),t([17,34,37,38],[2,28]),t(e,[2,14],{15:[1,55]}),t([27,28],[2,33]),t(e,[2,8]),t(e,[2,41]),t(e,[2,42]),t(e,[2,43]),t(W,[2,24],{33:56,36:[1,57],38:T}),t(W,[2,25]),t(M,[2,29]),t(W,[2,32]),t(M,[2,31]),{16:58,17:[1,59],29:32,30:33,34:N},t(W,[2,26]),{35:60,37:C},{17:[1,61]},t(e,[2,13]),t(M,[2,30]),t(e,[2,12])],defaultActions:{34:[2,27],41:[2,22]},parseError:function(a,n){if(n.recoverable)this.trace(a);else{var c=new Error(a);throw c.hash=n,c}},parse:function(a){var n=this,c=[0],d=[],E=[null],i=[],K=this.table,s="",Q=0,st=0,ft=2,ot=1,yt=i.slice.call(arguments,1),b=Object.create(this.lexer),z={yy:{}};for(var J in this.yy)Object.prototype.hasOwnProperty.call(this.yy,J)&&(z.yy[J]=this.yy[J]);b.setInput(a,z.yy),z.yy.lexer=b,z.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var $=b.yylloc;i.push($);var pt=b.options&&b.options.ranges;typeof z.yy.parseError=="function"?this.parseError=z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function _t(){var Y;return Y=d.pop()||b.lex()||ot,typeof Y!="number"&&(Y instanceof Array&&(d=Y,Y=d.pop()),Y=n.symbols_[Y]||Y),Y}for(var w,H,D,tt,G={},j,P,lt,q;;){if(H=c[c.length-1],this.defaultActions[H]?D=this.defaultActions[H]:((w===null||typeof w>"u")&&(w=_t()),D=K[H]&&K[H][w]),typeof D>"u"||!D.length||!D[0]){var et="";q=[];for(j in K[H])this.terminals_[j]&&j>ft&&q.push("'"+this.terminals_[j]+"'");b.showPosition?et="Parse error on line "+(Q+1)+`: `+b.showPosition()+` Expecting `+q.join(", ")+", got '"+(this.terminals_[w]||w)+"'":et="Parse error on line "+(Q+1)+": Unexpected "+(w==ot?"end of input":"'"+(this.terminals_[w]||w)+"'"),this.parseError(et,{text:b.match,token:this.terminals_[w]||w,line:b.yylineno,loc:$,expected:q})}if(D[0]instanceof Array&&D.length>1)throw new Error("Parse Error: multiple actions possible at state: "+H+", token: "+w);switch(D[0]){case 1:c.push(w),E.push(b.yytext),i.push(b.yylloc),c.push(D[1]),w=null,st=b.yyleng,s=b.yytext,Q=b.yylineno,$=b.yylloc;break;case 2:if(P=this.productions_[D[1]][1],G.$=E[E.length-P],G._$={first_line:i[i.length-(P||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(P||1)].first_column,last_column:i[i.length-1].last_column},pt&&(G._$.range=[i[i.length-(P||1)].range[0],i[i.length-1].range[1]]),tt=this.performAction.apply(G,[s,st,Q,z.yy,D[1],E,i].concat(yt)),typeof tt<"u")return tt;P&&(c=c.slice(0,-1*P*2),E=E.slice(0,-1*P),i=i.slice(0,-1*P)),c.push(this.productions_[D[1]][0]),E.push(G.$),i.push(G._$),lt=K[c[c.length-2]][c[c.length-1]],c.push(lt);break;case 3:return!0}}return!0}},O=function(){var S={EOF:1,parseError:function(n,c){if(this.yy.parser)this.yy.parser.parseError(n,c);else throw new Error(n)},setInput:function(a,n){return this.yy=n||this.yy||{},this._input=a,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.offset++,this.match+=a,this.matched+=a;var n=a.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),a},unput:function(a){var n=a.length,c=a.split(/(?:\r\n?|\n)/g);this._input=a+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var E=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===d.length?this.yylloc.first_column:0)+d[d.length-c.length].length-c[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[E[0],E[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(a){this.unput(this.match.slice(a))},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),n=new Array(a.length+1).join("-");return a+this.upcomingInput()+` diff --git a/assets/fakedns.html-usFdfR00.js b/assets/fakedns.html-7yy_Hwj4.js similarity index 99% rename from assets/fakedns.html-usFdfR00.js rename to assets/fakedns.html-7yy_Hwj4.js index 0a22d3a0b6..938221df10 100644 --- a/assets/fakedns.html-usFdfR00.js +++ b/assets/fakedns.html-7yy_Hwj4.js @@ -1,4 +1,4 @@ -import{_ as e,r as o,o as t,c as p,a as c,b as n,d as i,w as l,e as s}from"./app-PDrbPfzp.js";const u={},d=s(`

                        FakeDNS

                        FakeDNS 通过伪造 DNS 以获取目标域名,能够降低 DNS 查询时的延迟、配合透明代理获取目标域名。

                        注意

                        FakeDNS 有可能会污染本地 DNS,导致 Xray 关闭后“无法访问网络”。

                        FakeDNSObject

                        FakeDNSObject 对应配置文件的 fakedns 项。

                        {
                        +import{_ as e,r as o,o as t,c as p,a as c,b as n,d as i,w as l,e as s}from"./app-UOvWaKji.js";const u={},d=s(`

                        FakeDNS

                        FakeDNS 通过伪造 DNS 以获取目标域名,能够降低 DNS 查询时的延迟、配合透明代理获取目标域名。

                        注意

                        FakeDNS 有可能会污染本地 DNS,导致 Xray 关闭后“无法访问网络”。

                        FakeDNSObject

                        FakeDNSObject 对应配置文件的 fakedns 项。

                        {
                           "ipPool": "198.18.0.0/16",
                           "poolSize": 65535
                         }
                        diff --git a/assets/fakedns.html-aUN-NotP.js b/assets/fakedns.html-jPUstbOM.js
                        similarity index 99%
                        rename from assets/fakedns.html-aUN-NotP.js
                        rename to assets/fakedns.html-jPUstbOM.js
                        index 10b2ec4d69..df78b26777 100644
                        --- a/assets/fakedns.html-aUN-NotP.js
                        +++ b/assets/fakedns.html-jPUstbOM.js
                        @@ -1,4 +1,4 @@
                        -import{_ as e,r as t,o,c as p,a as i,b as n,d as c,w as l,e as s}from"./app-PDrbPfzp.js";const u={},r=s(`

                        FakeDNS

                        FakeDNS is used to obtain target domain names by forging DNS, which can reduce the delay in DNS queries and work with transparent proxies to obtain target domain names.

                        Warning

                        FakeDNS may contaminate the local DNS and cause "network unreachable" after Xray is closed.

                        FakeDNSObject

                        FakeDNSObject corresponds to the fakedns item in the configuration file.

                        {
                        +import{_ as e,r as t,o,c as p,a as i,b as n,d as c,w as l,e as s}from"./app-UOvWaKji.js";const u={},r=s(`

                        FakeDNS

                        FakeDNS is used to obtain target domain names by forging DNS, which can reduce the delay in DNS queries and work with transparent proxies to obtain target domain names.

                        Warning

                        FakeDNS may contaminate the local DNS and cause "network unreachable" after Xray is closed.

                        FakeDNSObject

                        FakeDNSObject corresponds to the fakedns item in the configuration file.

                        {
                           "ipPool": "198.18.0.0/16",
                           "poolSize": 65535
                         }
                        diff --git a/assets/fallback.html-1NLLtTvN.js b/assets/fallback.html-GSgUfNDP.js
                        similarity index 99%
                        rename from assets/fallback.html-1NLLtTvN.js
                        rename to assets/fallback.html-GSgUfNDP.js
                        index ef3cc7fe00..d29053367c 100644
                        --- a/assets/fallback.html-1NLLtTvN.js
                        +++ b/assets/fallback.html-GSgUfNDP.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as s,o as r,c as d,a as e,b as t,d as o,w as p,e as n}from"./app-PDrbPfzp.js";const u={},h=n(`

                        Fallback

                        Fallback is one of the most powerful features of Xray, which can effectively prevent active probing and allows you to use one port for multiple services

                        Fallback provides Xray with high-strength anti-active probing capabilities and has a unique first-packet fallback mechanism.

                        Fallback can also divide traffic of different types based on path for multi-service sharing on a single port.

                        Currently, you can use the fallback feature by configuring fallbacks when using VLESS or Trojan protocols, thus creating an unimaginable combo of services becomes REALITY.

                        fallbacks configuration

                          "fallbacks": [
                        +import{_ as c,r as s,o as r,c as d,a as e,b as t,d as o,w as p,e as n}from"./app-UOvWaKji.js";const u={},h=n(`

                        Fallback

                        Fallback is one of the most powerful features of Xray, which can effectively prevent active probing and allows you to use one port for multiple services

                        Fallback provides Xray with high-strength anti-active probing capabilities and has a unique first-packet fallback mechanism.

                        Fallback can also divide traffic of different types based on path for multi-service sharing on a single port.

                        Currently, you can use the fallback feature by configuring fallbacks when using VLESS or Trojan protocols, thus creating an unimaginable combo of services becomes REALITY.

                        fallbacks configuration

                          "fallbacks": [
                             {
                               "dest": 80
                             }
                        diff --git a/assets/fallback.html-j-WsWvnI.js b/assets/fallback.html-SRUkF-k8.js
                        similarity index 99%
                        rename from assets/fallback.html-j-WsWvnI.js
                        rename to assets/fallback.html-SRUkF-k8.js
                        index 2100ad3d15..6b23bb7590 100644
                        --- a/assets/fallback.html-j-WsWvnI.js
                        +++ b/assets/fallback.html-SRUkF-k8.js
                        @@ -1,4 +1,4 @@
                        -import{_ as r,r as s,o as d,c as i,a as n,b as a,d as o,w as c,e as t}from"./app-PDrbPfzp.js";const u={},b=t(`

                        Fallback 回落

                        Fallback 是 Xray 的最强大功能之一, 可有效防止主动探测, 自由配置常用端口多服务共享

                        fallback 为 Xray 提供了高强度的防主动探测性, 并且具有独创的首包回落机制.

                        fallback 也可以将不同类型的流量根据 path 进行分流, 从而实现一个端口, 多种服务共享.

                        目前您可以在使用 VLESS 或者 trojan 协议时, 通过配置 fallbacks 来使用回落这一特性, 并且创造出非常丰富的组合玩法.

                        fallbacks 配置

                          "fallbacks": [
                        +import{_ as r,r as s,o as d,c as i,a as n,b as a,d as o,w as c,e as t}from"./app-UOvWaKji.js";const u={},b=t(`

                        Fallback 回落

                        Fallback 是 Xray 的最强大功能之一, 可有效防止主动探测, 自由配置常用端口多服务共享

                        fallback 为 Xray 提供了高强度的防主动探测性, 并且具有独创的首包回落机制.

                        fallback 也可以将不同类型的流量根据 path 进行分流, 从而实现一个端口, 多种服务共享.

                        目前您可以在使用 VLESS 或者 trojan 协议时, 通过配置 fallbacks 来使用回落这一特性, 并且创造出非常丰富的组合玩法.

                        fallbacks 配置

                          "fallbacks": [
                             {
                               "dest": 80
                             }
                        diff --git a/assets/fallbacks-lv1.html-LXNm8itW.js b/assets/fallbacks-lv1.html--wD9yMzq.js
                        similarity index 99%
                        rename from assets/fallbacks-lv1.html-LXNm8itW.js
                        rename to assets/fallbacks-lv1.html--wD9yMzq.js
                        index 68f5e8a2e6..573346dec9 100644
                        --- a/assets/fallbacks-lv1.html-LXNm8itW.js
                        +++ b/assets/fallbacks-lv1.html--wD9yMzq.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as e,o as u,c as r,a as n,b as s,d as a,w as l,e as o}from"./app-PDrbPfzp.js";const d={},k=n("h1",{id:"回落-fallbacks-功能简析",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#回落-fallbacks-功能简析"},[n("span",null,"回落 (fallbacks) 功能简析")])],-1),v=n("p",null,"在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),m=n("h2",{id:"_1-回顾《小小白白话文》中的回落",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_1-回顾《小小白白话文》中的回落"},[n("span",null,"1. 回顾《小小白白话文》中的回落")])],-1),q=n("code",null,"VLESS",-1),b=o(`
                        {
                        +import{_ as i,r as e,o as u,c as r,a as n,b as s,d as a,w as l,e as o}from"./app-UOvWaKji.js";const d={},k=n("h1",{id:"回落-fallbacks-功能简析",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#回落-fallbacks-功能简析"},[n("span",null,"回落 (fallbacks) 功能简析")])],-1),v=n("p",null,"在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),m=n("h2",{id:"_1-回顾《小小白白话文》中的回落",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_1-回顾《小小白白话文》中的回落"},[n("span",null,"1. 回顾《小小白白话文》中的回落")])],-1),q=n("code",null,"VLESS",-1),b=o(`
                        {
                           "inbounds": [
                             {
                               "port": 443,
                        diff --git a/assets/fallbacks-lv1.html-o6nPP3Lr.js b/assets/fallbacks-lv1.html-SBMi_sxl.js
                        similarity index 99%
                        rename from assets/fallbacks-lv1.html-o6nPP3Lr.js
                        rename to assets/fallbacks-lv1.html-SBMi_sxl.js
                        index 04ba3e3f45..f9851eb709 100644
                        --- a/assets/fallbacks-lv1.html-o6nPP3Lr.js
                        +++ b/assets/fallbacks-lv1.html-SBMi_sxl.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as p,o as u,c as r,a as n,b as s,d as a,w as l,e as o}from"./app-PDrbPfzp.js";const d={},k=n("h1",{id:"回落-fallbacks-功能简析",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#回落-fallbacks-功能简析"},[n("span",null,"回落 (fallbacks) 功能简析")])],-1),v=n("p",null,"在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),m=n("h2",{id:"_1-回顾《小小白白话文》中的回落",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_1-回顾《小小白白话文》中的回落"},[n("span",null,"1. 回顾《小小白白话文》中的回落")])],-1),q=n("code",null,"VLESS",-1),b=o(`
                        {
                        +import{_ as i,r as p,o as u,c as r,a as n,b as s,d as a,w as l,e as o}from"./app-UOvWaKji.js";const d={},k=n("h1",{id:"回落-fallbacks-功能简析",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#回落-fallbacks-功能简析"},[n("span",null,"回落 (fallbacks) 功能简析")])],-1),v=n("p",null,"在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),m=n("h2",{id:"_1-回顾《小小白白话文》中的回落",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_1-回顾《小小白白话文》中的回落"},[n("span",null,"1. 回顾《小小白白话文》中的回落")])],-1),q=n("code",null,"VLESS",-1),b=o(`
                        {
                           "inbounds": [
                             {
                               "port": 443,
                        diff --git a/assets/fallbacks-with-sni.html-_rwOIQFb.js b/assets/fallbacks-with-sni.html-EwR1fYMf.js
                        similarity index 99%
                        rename from assets/fallbacks-with-sni.html-_rwOIQFb.js
                        rename to assets/fallbacks-with-sni.html-EwR1fYMf.js
                        index 56cef1d36e..034a82c4b4 100644
                        --- a/assets/fallbacks-with-sni.html-_rwOIQFb.js
                        +++ b/assets/fallbacks-with-sni.html-EwR1fYMf.js
                        @@ -1,4 +1,4 @@
                        -import{_ as o,r as i,o as p,c as r,a as n,b as s,d as e,e as t}from"./app-PDrbPfzp.js";const l="/assets/xray-fallbacks-IC5ujKgM.svg",c="/assets/xray-dns-records-JaWruCUz.webp",d="/assets/cf-api-token-permissions-for-acme-Zhny1POg.webp",u={},v=t(`

                        Implementing camouflage and domain-based routing through SNI fallback function

                        VLESS is a lightweight protocol that, like Trojan, does not perform complex encryption and obfuscation on traffic. Instead, it is encrypted through the TLS protocol and mixed in with other HTTPS traffic, making it difficult to detect. In order to better disguise itself and respond to active probing, the fallback function appeared with VLESS at the same time. This tutorial will demonstrate how to use the fallback function of VLESS inbound protocol in Xray, combined with Nginx or Caddy, to achieve domain name-based traffic routing while ensuring complete disguise.

                        Application Scenarios

                        Due to XTLS, Xray needs to listen on port 443, which means that if there is a website running on the server, it cannot run or needs to run on another port, which is obviously unreasonable. There are three solutions to this problem:

                        • Xray monitors other commonly used ports (such as 22, 3389, 8443).

                        This plan is the simplest, but not perfect enough.

                        • Nginx or HAProxy listens on port 443, uses SNI for L4 load balancing, and achieves port multiplexing through reverse proxy.

                        This plan is relatively complicated and requires some understanding of using Nginx or HAProxy. We will not explain it in too much detail here.

                        • Xray listens on port 443, and uses Fallbacks feature to split website traffic based on SNI and fallbacks it to Nginx or Caddy.

                        This plan has a moderate level of difficulty and is the scheme that this tutorial will demonstrate next.

                        Introduction to SNI

                        Server Name Indication (SNI) is an extension protocol of TLS. Friends who are familiar with reverse proxies know that the following configuration is required if you want to proxy traffic to the correct content through a domain name:

                        proxy_set_header Host hostname;
                        +import{_ as o,r as i,o as p,c as r,a as n,b as s,d as e,e as t}from"./app-UOvWaKji.js";const l="/assets/xray-fallbacks-IC5ujKgM.svg",c="/assets/xray-dns-records-JaWruCUz.webp",d="/assets/cf-api-token-permissions-for-acme-Zhny1POg.webp",u={},v=t(`

                        Implementing camouflage and domain-based routing through SNI fallback function

                        VLESS is a lightweight protocol that, like Trojan, does not perform complex encryption and obfuscation on traffic. Instead, it is encrypted through the TLS protocol and mixed in with other HTTPS traffic, making it difficult to detect. In order to better disguise itself and respond to active probing, the fallback function appeared with VLESS at the same time. This tutorial will demonstrate how to use the fallback function of VLESS inbound protocol in Xray, combined with Nginx or Caddy, to achieve domain name-based traffic routing while ensuring complete disguise.

                        Application Scenarios

                        Due to XTLS, Xray needs to listen on port 443, which means that if there is a website running on the server, it cannot run or needs to run on another port, which is obviously unreasonable. There are three solutions to this problem:

                        • Xray monitors other commonly used ports (such as 22, 3389, 8443).

                        This plan is the simplest, but not perfect enough.

                        • Nginx or HAProxy listens on port 443, uses SNI for L4 load balancing, and achieves port multiplexing through reverse proxy.

                        This plan is relatively complicated and requires some understanding of using Nginx or HAProxy. We will not explain it in too much detail here.

                        • Xray listens on port 443, and uses Fallbacks feature to split website traffic based on SNI and fallbacks it to Nginx or Caddy.

                        This plan has a moderate level of difficulty and is the scheme that this tutorial will demonstrate next.

                        Introduction to SNI

                        Server Name Indication (SNI) is an extension protocol of TLS. Friends who are familiar with reverse proxies know that the following configuration is required if you want to proxy traffic to the correct content through a domain name:

                        proxy_set_header Host hostname;
                         

                        (Note: "hostname" should be replaced with the actual hostname.)

                        This sentence sets the HTTP Header named "Host" to a certain hostname. Why do we need to do this? Generally, one server corresponds to one IP address, but it runs multiple websites. Visitors access the server by querying the IP address via domain name to visit the website. Then the question arises, how to determine which website the visitor wants to access? This requires "name-based virtual hosting".

                        When a Web server receives a request, it looks at the host header to direct the visitor to the correct website. However, this simple method cannot be used when HTTP protocol is encrypted by TLS protocol. This is because the TLS handshake occurs before the server sees any HTTP headers, so the server cannot use the information in the HTTP host header to determine which certificate to present or which destination the visitor wants to access.

                        The principle of SNI is also very simple. It solves the problem by allowing the client to send the hostname as part of the TLS negotiation. Therefore, when using Nginx to reverse proxy the HTTPS protocol, you need to add proxy_ssl_server_name on; to the configuration. At this time, Nginx will send SNI information to the proxied server, solving the problem of virtual host failure under the HTTPS protocol. In addition, when using SNI, even if the host header is not specified, the website can be accessed correctly.

                        Idea

                        Xray Fallback Process

                        After receiving traffic from port 443, Xray will decrypt the TLS and forward the traffic that has a first packet length < 18, invalid protocol version, or failed authentication through matching name, path, and alpn to the address specified by dest.

                        Adding DNS Records

                        DNS Records

                        Please modify the domain name and IP according to the actual situation.

                        Applying for TLS Certificate

                        ',24),h=n("code",null,"*.example.com",-1),m=n("code",null,"example.com",-1),k=n("code",null,"*.*.example.com",-1),b={href:"https://en.wikipedia.org/wiki/Subject_Alternative_Name",target:"_blank",rel:"noopener noreferrer"},f={href:"https://acme.sh",target:"_blank",rel:"noopener noreferrer"},g={href:"https://github.com/acmesh-official/acme.sh/wiki/dnsapi",target:"_blank",rel:"noopener noreferrer"},y={href:"https://dash.cloudflare.com/profile/api-tokens",target:"_blank",rel:"noopener noreferrer"},q=t('

                        API Token permission settings

                        The permission part is crucial, while other parts are optional.

                        After creating, you will receive a mysterious string of characters. Please keep it safe in a secure and non-losing place, as it will not be displayed again. This string of characters is the CF_Token that will be used soon.

                        Note

                        The following operations need to be performed under the root user. Using sudo will result in errors.

                        curl https://get.acme.sh | sh # Install acme.sh
                         export CF_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" # Set API Token variable
                         acme.sh --issue -d example.com -d *.example.com --dns dns_cf # Apply for a certificate using DNS-01 validation method
                        diff --git a/assets/fallbacks-with-sni.html-Hu3dL1kT.js b/assets/fallbacks-with-sni.html-bYbXLNvx.js
                        similarity index 99%
                        rename from assets/fallbacks-with-sni.html-Hu3dL1kT.js
                        rename to assets/fallbacks-with-sni.html-bYbXLNvx.js
                        index b1bf26536a..a566a3a145 100644
                        --- a/assets/fallbacks-with-sni.html-Hu3dL1kT.js
                        +++ b/assets/fallbacks-with-sni.html-bYbXLNvx.js
                        @@ -1,4 +1,4 @@
                        -import{_ as o,r as p,o as l,c as i,a as n,b as s,d as e,e as t}from"./app-PDrbPfzp.js";const c="/assets/xray-fallbacks-IC5ujKgM.svg",r="/assets/xray-dns-records-JaWruCUz.webp",u="/assets/cf-api-token-permissions-for-acme-Zhny1POg.webp",d={},v=t(`

                        通过 SNI 回落功能实现伪装与按域名分流

                        VLESS 是一种很轻的协议,和 Trojan 一样,不对流量进行复杂的加密和混淆,而是大隐隐于市,通过 TLS 协议加密,混杂在其他 HTTPS 流量中,在墙内外穿进穿出。为了更好的伪装以应对主动探测,Fallbacks 回落功能随 VLESS 同时出现。这篇教程将演示如何使用 Xray 中 VLESS 入站协议的回落功能配合 Nginx 或 Caddy 在保证伪装完全的前提下实现按域名分流。

                        应用情景

                        由于 XTLS,Xray 需要监听 443 端口,这导致如果之前有网站运行在服务器上,那么此时网站无法运行或需要运行在其他端口上,这显然是不合理的。有以下三种方案可以解决这个问题:

                        • Xray 监听其他常用端口(如 22、3389、8443)

                          这个方案是最简单的,但不够完美。

                        • Nginx 或 HAProxy 监听 443 端口,通过 SNI 分流做 L4 反向代理,实现端口复用

                          这个方案比较复杂,需要对 Nginx 或 HAProxy 的使用有一定了解,此处不作过多解释。

                        • Xray 监听 443 端口,通过 Fallbacks 功能 SNI 分流将网站流量回落到 Nginx 或 Caddy

                          这个方案难度适中,也是此教程接下来想要演示的方案。

                        SNI 简介

                        服务器名称指示(英语:Server Name Indication,缩写:SNI)是 TLS 的一个扩展协议。熟悉反向代理的朋友都知道,如果想要通过域名将流量代理到正确的内容上,需要以下配置:

                        proxy_set_header Host 主机名;
                        +import{_ as o,r as p,o as l,c as i,a as n,b as s,d as e,e as t}from"./app-UOvWaKji.js";const c="/assets/xray-fallbacks-IC5ujKgM.svg",r="/assets/xray-dns-records-JaWruCUz.webp",u="/assets/cf-api-token-permissions-for-acme-Zhny1POg.webp",d={},v=t(`

                        通过 SNI 回落功能实现伪装与按域名分流

                        VLESS 是一种很轻的协议,和 Trojan 一样,不对流量进行复杂的加密和混淆,而是大隐隐于市,通过 TLS 协议加密,混杂在其他 HTTPS 流量中,在墙内外穿进穿出。为了更好的伪装以应对主动探测,Fallbacks 回落功能随 VLESS 同时出现。这篇教程将演示如何使用 Xray 中 VLESS 入站协议的回落功能配合 Nginx 或 Caddy 在保证伪装完全的前提下实现按域名分流。

                        应用情景

                        由于 XTLS,Xray 需要监听 443 端口,这导致如果之前有网站运行在服务器上,那么此时网站无法运行或需要运行在其他端口上,这显然是不合理的。有以下三种方案可以解决这个问题:

                        • Xray 监听其他常用端口(如 22、3389、8443)

                          这个方案是最简单的,但不够完美。

                        • Nginx 或 HAProxy 监听 443 端口,通过 SNI 分流做 L4 反向代理,实现端口复用

                          这个方案比较复杂,需要对 Nginx 或 HAProxy 的使用有一定了解,此处不作过多解释。

                        • Xray 监听 443 端口,通过 Fallbacks 功能 SNI 分流将网站流量回落到 Nginx 或 Caddy

                          这个方案难度适中,也是此教程接下来想要演示的方案。

                        SNI 简介

                        服务器名称指示(英语:Server Name Indication,缩写:SNI)是 TLS 的一个扩展协议。熟悉反向代理的朋友都知道,如果想要通过域名将流量代理到正确的内容上,需要以下配置:

                        proxy_set_header Host 主机名;
                         

                        这句的作用是将名为 “Host” 的 HTTP Header 设定为某个主机名。为什么要这样做?一般而言,一台服务器对应一个 IP,但却运行多个网站,访问者通过域名查询到 IP 以访问服务器,那么问题来了,如何确定访问者想要访问的是哪一个网站?这需要“基于名称的虚拟主机”。

                        当 Web 服务器收到访问请求后,它会查看请求的主机头,使访问者访问正确的网站。然而当 HTTP 协议被 TLS 协议加密后,这种简单的方法就无法实现了。因为 TLS 握手发生在服务器看到任何 HTTP 头之前,因此,服务器不可能使用 HTTP 主机头中的信息来决定呈现哪个证书,更无法决定访问者的访问目标。

                        SNI 的原理也很简单,它通过让客户端发送主机名作为 TLS 协商的一部分来解决此问题。所以在使用 Nginx 对 HTTPS 协议进行反向代理时,需要在配置中加入 proxy_ssl_server_name on;,此时 Nginx 会向被代理的服务器发送 SNI 信息,解决了 HTTPS 协议下虚拟主机失效的问题。另外,使用 SNI 时,即使不指定主机头,也可以正确访问网站。

                        思路

                        Xray 回落流程

                        从 443 端口接收到流量后,Xray 会把 TLS 解密后首包长度 < 18、协议版本无效或身份认证失败的流量通过对 name、path、alpn 的匹配转发到 dest 指定的地址。

                        添加 DNS 记录

                        DNS 记录

                        请按实际情况修改域名和 IP。

                        申请 TLS 证书

                        ',18),k=n("code",null,"*.example.com",-1),m=n("code",null,"example.com",-1),b=n("code",null,"*.*.example.com",-1),h={href:"https://zh.wikipedia.org/wiki/%E4%B8%BB%E9%A2%98%E5%A4%87%E7%94%A8%E5%90%8D%E7%A7%B0",target:"_blank",rel:"noopener noreferrer"},q=n("sup",{class:"footnote-ref"},[n("a",{href:"#fn1",id:"fnref1"},"[1]")],-1),f={href:"https://acme.sh",target:"_blank",rel:"noopener noreferrer"},y={href:"https://github.com/acmesh-official/acme.sh/wiki/dnsapi",target:"_blank",rel:"noopener noreferrer"},g={href:"https://dash.cloudflare.com/profile/api-tokens",target:"_blank",rel:"noopener noreferrer"},_=t('

                        API Token 的权限设置

                        权限部分至关重要,其他部分任意。

                        创建完毕后,你会得到一串神秘字符,请将其妥善保管到安全且不会丢失的地方,因为它不再会显示。这串字符就是即将用到的 CF_Token

                        注意

                        以下操作需要在 root 用户下进行,使用 sudo 会出现错误。

                        curl https://get.acme.sh | sh # 安装 acme.sh
                         export CF_Token="sdfsdfsdfljlbjkljlkjsdfoiwje" # 设定 API Token 变量
                         acme.sh --issue -d example.com -d *.example.com --dns dns_cf # 使用 DNS-01 验证方式申请证书
                        diff --git a/assets/flowDb-4b19a42f-sAhi6J2v.js b/assets/flowDb-4b19a42f-e0bq62ON.js
                        similarity index 99%
                        rename from assets/flowDb-4b19a42f-sAhi6J2v.js
                        rename to assets/flowDb-4b19a42f-e0bq62ON.js
                        index 28f82a93eb..d6611e4c8f 100644
                        --- a/assets/flowDb-4b19a42f-sAhi6J2v.js
                        +++ b/assets/flowDb-4b19a42f-e0bq62ON.js
                        @@ -1,4 +1,4 @@
                        -import{c as et,v as me,s as ye,g as ve,a as Ve,b as Le,x as Ie,y as Re,l as J1,z as dt,A as Ne,j as we,h as w1}from"./mermaid.core-95b3ca__.js";var pt=function(){var e=function(f1,a,o,f){for(o=o||{},f=f1.length;f--;o[f1[f]]=a);return o},u=[1,4],i=[1,3],n=[1,5],c=[1,8,9,10,11,27,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],l=[2,2],h=[1,13],U=[1,14],F=[1,15],w=[1,16],X=[1,23],o1=[1,25],p1=[1,26],A1=[1,27],C=[1,49],k=[1,48],l1=[1,29],U1=[1,30],G1=[1,31],M1=[1,32],K1=[1,33],x=[1,44],B=[1,46],m=[1,42],y=[1,47],v=[1,43],V=[1,50],L=[1,45],I=[1,51],R=[1,52],Y1=[1,34],j1=[1,35],z1=[1,36],X1=[1,37],I1=[1,57],b=[1,8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],q=[1,61],Q=[1,60],Z=[1,62],H1=[8,9,11,73,75],k1=[1,88],b1=[1,93],g1=[1,92],D1=[1,89],F1=[1,85],T1=[1,91],S1=[1,87],C1=[1,94],_1=[1,90],x1=[1,95],B1=[1,86],W1=[8,9,10,11,73,75],N=[8,9,10,11,44,73,75],M=[8,9,10,11,29,42,44,46,48,50,52,54,56,58,61,63,65,66,68,73,75,86,99,102,103,106,108,111,112,113],Et=[8,9,11,42,58,73,75,86,99,102,103,106,108,111,112,113],R1=[42,58,86,99,102,103,106,108,111,112,113],kt=[1,121],bt=[1,120],gt=[1,128],Dt=[1,142],Ft=[1,143],Tt=[1,144],St=[1,145],Ct=[1,130],_t=[1,132],xt=[1,136],Bt=[1,137],mt=[1,138],yt=[1,139],vt=[1,140],Vt=[1,141],Lt=[1,146],It=[1,147],Rt=[1,126],Nt=[1,127],wt=[1,134],Ot=[1,129],Pt=[1,133],Ut=[1,131],nt=[8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],Gt=[1,149],T=[8,9,11],K=[8,9,10,11,14,42,58,86,102,103,106,108,111,112,113],p=[1,169],O=[1,165],P=[1,166],A=[1,170],d=[1,167],E=[1,168],m1=[75,113,116],g=[8,9,10,11,12,14,27,29,32,42,58,73,81,82,83,84,85,86,87,102,106,108,111,112,113],Mt=[10,103],h1=[31,47,49,51,53,55,60,62,64,65,67,69,113,114,115],J=[1,235],$=[1,233],t1=[1,237],e1=[1,231],s1=[1,232],u1=[1,234],i1=[1,236],r1=[1,238],y1=[1,255],Kt=[8,9,11,103],W=[8,9,10,11,58,81,102,103,106,107,108,109],at={trace:function(){},yy:{},symbols_:{error:2,start:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,NODIR:13,DIR:14,FirstStmtSeparator:15,ending:16,endToken:17,spaceList:18,spaceListNewline:19,vertexStatement:20,separator:21,styleStatement:22,linkStyleStatement:23,classDefStatement:24,classStatement:25,clickStatement:26,subgraph:27,textNoTags:28,SQS:29,text:30,SQE:31,end:32,direction:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,link:39,node:40,styledVertex:41,AMP:42,vertex:43,STYLE_SEPARATOR:44,idString:45,DOUBLECIRCLESTART:46,DOUBLECIRCLEEND:47,PS:48,PE:49,"(-":50,"-)":51,STADIUMSTART:52,STADIUMEND:53,SUBROUTINESTART:54,SUBROUTINEEND:55,VERTEX_WITH_PROPS_START:56,"NODE_STRING[field]":57,COLON:58,"NODE_STRING[value]":59,PIPE:60,CYLINDERSTART:61,CYLINDEREND:62,DIAMOND_START:63,DIAMOND_STOP:64,TAGEND:65,TRAPSTART:66,TRAPEND:67,INVTRAPSTART:68,INVTRAPEND:69,linkStatement:70,arrowText:71,TESTSTR:72,START_LINK:73,edgeText:74,LINK:75,edgeTextToken:76,STR:77,MD_STR:78,textToken:79,keywords:80,STYLE:81,LINKSTYLE:82,CLASSDEF:83,CLASS:84,CLICK:85,DOWN:86,UP:87,textNoTagsToken:88,stylesOpt:89,"idString[vertex]":90,"idString[class]":91,CALLBACKNAME:92,CALLBACKARGS:93,HREF:94,LINK_TARGET:95,"STR[link]":96,"STR[tooltip]":97,alphaNum:98,DEFAULT:99,numList:100,INTERPOLATE:101,NUM:102,COMMA:103,style:104,styleComponent:105,NODE_STRING:106,UNIT:107,BRKT:108,PCT:109,idStringToken:110,MINUS:111,MULT:112,UNICODE_TEXT:113,TEXT:114,TAGSTART:115,EDGE_TEXT:116,alphaNumToken:117,direction_tb:118,direction_bt:119,direction_rl:120,direction_lr:121,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"NODIR",14:"DIR",27:"subgraph",29:"SQS",31:"SQE",32:"end",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",42:"AMP",44:"STYLE_SEPARATOR",46:"DOUBLECIRCLESTART",47:"DOUBLECIRCLEEND",48:"PS",49:"PE",50:"(-",51:"-)",52:"STADIUMSTART",53:"STADIUMEND",54:"SUBROUTINESTART",55:"SUBROUTINEEND",56:"VERTEX_WITH_PROPS_START",57:"NODE_STRING[field]",58:"COLON",59:"NODE_STRING[value]",60:"PIPE",61:"CYLINDERSTART",62:"CYLINDEREND",63:"DIAMOND_START",64:"DIAMOND_STOP",65:"TAGEND",66:"TRAPSTART",67:"TRAPEND",68:"INVTRAPSTART",69:"INVTRAPEND",72:"TESTSTR",73:"START_LINK",75:"LINK",77:"STR",78:"MD_STR",81:"STYLE",82:"LINKSTYLE",83:"CLASSDEF",84:"CLASS",85:"CLICK",86:"DOWN",87:"UP",90:"idString[vertex]",91:"idString[class]",92:"CALLBACKNAME",93:"CALLBACKARGS",94:"HREF",95:"LINK_TARGET",96:"STR[link]",97:"STR[tooltip]",99:"DEFAULT",101:"INTERPOLATE",102:"NUM",103:"COMMA",106:"NODE_STRING",107:"UNIT",108:"BRKT",109:"PCT",111:"MINUS",112:"MULT",113:"UNICODE_TEXT",114:"TEXT",115:"TAGSTART",116:"EDGE_TEXT",118:"direction_tb",119:"direction_bt",120:"direction_rl",121:"direction_lr"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,2],[4,3],[16,2],[16,1],[17,1],[17,1],[17,1],[15,1],[15,1],[15,2],[19,2],[19,2],[19,1],[19,1],[18,2],[18,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,9],[7,6],[7,4],[7,1],[7,2],[7,2],[7,1],[21,1],[21,1],[21,1],[20,3],[20,4],[20,2],[20,1],[40,1],[40,5],[41,1],[41,3],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,8],[43,4],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,4],[43,4],[43,1],[39,2],[39,3],[39,3],[39,1],[39,3],[74,1],[74,2],[74,1],[74,1],[70,1],[71,3],[30,1],[30,2],[30,1],[30,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[28,1],[28,2],[28,1],[28,1],[24,5],[25,5],[26,2],[26,4],[26,3],[26,5],[26,3],[26,5],[26,5],[26,7],[26,2],[26,4],[26,2],[26,4],[26,4],[26,6],[22,5],[23,5],[23,5],[23,9],[23,9],[23,7],[23,7],[100,1],[100,3],[89,1],[89,3],[104,1],[104,2],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[79,1],[79,1],[79,1],[79,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[76,1],[76,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[45,1],[45,2],[98,1],[98,2],[33,1],[33,1],[33,1],[33,1]],performAction:function(a,o,f,r,S,t,N1){var s=t.length-1;switch(S){case 2:this.$=[];break;case 3:(!Array.isArray(t[s])||t[s].length>0)&&t[s-1].push(t[s]),this.$=t[s-1];break;case 4:case 176:this.$=t[s];break;case 11:r.setDirection("TB"),this.$="TB";break;case 12:r.setDirection(t[s-1]),this.$=t[s-1];break;case 27:this.$=t[s-1].nodes;break;case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 33:this.$=r.addSubGraph(t[s-6],t[s-1],t[s-4]);break;case 34:this.$=r.addSubGraph(t[s-3],t[s-1],t[s-3]);break;case 35:this.$=r.addSubGraph(void 0,t[s-1],void 0);break;case 37:this.$=t[s].trim(),r.setAccTitle(this.$);break;case 38:case 39:this.$=t[s].trim(),r.setAccDescription(this.$);break;case 43:r.addLink(t[s-2].stmt,t[s],t[s-1]),this.$={stmt:t[s],nodes:t[s].concat(t[s-2].nodes)};break;case 44:r.addLink(t[s-3].stmt,t[s-1],t[s-2]),this.$={stmt:t[s-1],nodes:t[s-1].concat(t[s-3].nodes)};break;case 45:this.$={stmt:t[s-1],nodes:t[s-1]};break;case 46:this.$={stmt:t[s],nodes:t[s]};break;case 47:this.$=[t[s]];break;case 48:this.$=t[s-4].concat(t[s]);break;case 49:this.$=t[s];break;case 50:this.$=t[s-2],r.setClass(t[s-2],t[s]);break;case 51:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"square");break;case 52:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"doublecircle");break;case 53:this.$=t[s-5],r.addVertex(t[s-5],t[s-2],"circle");break;case 54:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"ellipse");break;case 55:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"stadium");break;case 56:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"subroutine");break;case 57:this.$=t[s-7],r.addVertex(t[s-7],t[s-1],"rect",void 0,void 0,void 0,Object.fromEntries([[t[s-5],t[s-3]]]));break;case 58:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"cylinder");break;case 59:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"round");break;case 60:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"diamond");break;case 61:this.$=t[s-5],r.addVertex(t[s-5],t[s-2],"hexagon");break;case 62:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"odd");break;case 63:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"trapezoid");break;case 64:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"inv_trapezoid");break;case 65:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"lean_right");break;case 66:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"lean_left");break;case 67:this.$=t[s],r.addVertex(t[s]);break;case 68:t[s-1].text=t[s],this.$=t[s-1];break;case 69:case 70:t[s-2].text=t[s-1],this.$=t[s-2];break;case 71:this.$=t[s];break;case 72:var Y=r.destructLink(t[s],t[s-2]);this.$={type:Y.type,stroke:Y.stroke,length:Y.length,text:t[s-1]};break;case 73:this.$={text:t[s],type:"text"};break;case 74:this.$={text:t[s-1].text+""+t[s],type:t[s-1].type};break;case 75:this.$={text:t[s],type:"string"};break;case 76:this.$={text:t[s],type:"markdown"};break;case 77:var Y=r.destructLink(t[s]);this.$={type:Y.type,stroke:Y.stroke,length:Y.length};break;case 78:this.$=t[s-1];break;case 79:this.$={text:t[s],type:"text"};break;case 80:this.$={text:t[s-1].text+""+t[s],type:t[s-1].type};break;case 81:this.$={text:t[s],type:"string"};break;case 82:case 97:this.$={text:t[s],type:"markdown"};break;case 94:this.$={text:t[s],type:"text"};break;case 95:this.$={text:t[s-1].text+""+t[s],type:t[s-1].type};break;case 96:this.$={text:t[s],type:"text"};break;case 98:this.$=t[s-4],r.addClass(t[s-2],t[s]);break;case 99:this.$=t[s-4],r.setClass(t[s-2],t[s]);break;case 100:case 108:this.$=t[s-1],r.setClickEvent(t[s-1],t[s]);break;case 101:case 109:this.$=t[s-3],r.setClickEvent(t[s-3],t[s-2]),r.setTooltip(t[s-3],t[s]);break;case 102:this.$=t[s-2],r.setClickEvent(t[s-2],t[s-1],t[s]);break;case 103:this.$=t[s-4],r.setClickEvent(t[s-4],t[s-3],t[s-2]),r.setTooltip(t[s-4],t[s]);break;case 104:this.$=t[s-2],r.setLink(t[s-2],t[s]);break;case 105:this.$=t[s-4],r.setLink(t[s-4],t[s-2]),r.setTooltip(t[s-4],t[s]);break;case 106:this.$=t[s-4],r.setLink(t[s-4],t[s-2],t[s]);break;case 107:this.$=t[s-6],r.setLink(t[s-6],t[s-4],t[s]),r.setTooltip(t[s-6],t[s-2]);break;case 110:this.$=t[s-1],r.setLink(t[s-1],t[s]);break;case 111:this.$=t[s-3],r.setLink(t[s-3],t[s-2]),r.setTooltip(t[s-3],t[s]);break;case 112:this.$=t[s-3],r.setLink(t[s-3],t[s-2],t[s]);break;case 113:this.$=t[s-5],r.setLink(t[s-5],t[s-4],t[s]),r.setTooltip(t[s-5],t[s-2]);break;case 114:this.$=t[s-4],r.addVertex(t[s-2],void 0,void 0,t[s]);break;case 115:this.$=t[s-4],r.updateLink([t[s-2]],t[s]);break;case 116:this.$=t[s-4],r.updateLink(t[s-2],t[s]);break;case 117:this.$=t[s-8],r.updateLinkInterpolate([t[s-6]],t[s-2]),r.updateLink([t[s-6]],t[s]);break;case 118:this.$=t[s-8],r.updateLinkInterpolate(t[s-6],t[s-2]),r.updateLink(t[s-6],t[s]);break;case 119:this.$=t[s-6],r.updateLinkInterpolate([t[s-4]],t[s]);break;case 120:this.$=t[s-6],r.updateLinkInterpolate(t[s-4],t[s]);break;case 121:case 123:this.$=[t[s]];break;case 122:case 124:t[s-2].push(t[s]),this.$=t[s-2];break;case 126:this.$=t[s-1]+t[s];break;case 174:this.$=t[s];break;case 175:this.$=t[s-1]+""+t[s];break;case 177:this.$=t[s-1]+""+t[s];break;case 178:this.$={stmt:"dir",value:"TB"};break;case 179:this.$={stmt:"dir",value:"BT"};break;case 180:this.$={stmt:"dir",value:"RL"};break;case 181:this.$={stmt:"dir",value:"LR"};break}},table:[{3:1,4:2,9:u,10:i,12:n},{1:[3]},e(c,l,{5:6}),{4:7,9:u,10:i,12:n},{4:8,9:u,10:i,12:n},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:h,9:U,10:F,11:w,20:17,22:18,23:19,24:20,25:21,26:22,27:X,33:24,34:o1,36:p1,38:A1,40:28,41:38,42:C,43:39,45:40,58:k,81:l1,82:U1,83:G1,84:M1,85:K1,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R,118:Y1,119:j1,120:z1,121:X1},e(c,[2,9]),e(c,[2,10]),e(c,[2,11]),{8:[1,54],9:[1,55],10:I1,15:53,18:56},e(b,[2,3]),e(b,[2,4]),e(b,[2,5]),e(b,[2,6]),e(b,[2,7]),e(b,[2,8]),{8:q,9:Q,11:Z,21:58,39:59,70:63,73:[1,64],75:[1,65]},{8:q,9:Q,11:Z,21:66},{8:q,9:Q,11:Z,21:67},{8:q,9:Q,11:Z,21:68},{8:q,9:Q,11:Z,21:69},{8:q,9:Q,11:Z,21:70},{8:q,9:Q,10:[1,71],11:Z,21:72},e(b,[2,36]),{35:[1,73]},{37:[1,74]},e(b,[2,39]),e(H1,[2,46],{18:75,10:I1}),{10:[1,76]},{10:[1,77]},{10:[1,78]},{10:[1,79]},{14:k1,42:b1,58:g1,77:[1,83],86:D1,92:[1,80],94:[1,81],98:82,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1,117:84},e(b,[2,178]),e(b,[2,179]),e(b,[2,180]),e(b,[2,181]),e(W1,[2,47]),e(W1,[2,49],{44:[1,96]}),e(N,[2,67],{110:109,29:[1,97],42:C,46:[1,98],48:[1,99],50:[1,100],52:[1,101],54:[1,102],56:[1,103],58:k,61:[1,104],63:[1,105],65:[1,106],66:[1,107],68:[1,108],86:x,99:B,102:m,103:y,106:v,108:V,111:L,112:I,113:R}),e(M,[2,174]),e(M,[2,135]),e(M,[2,136]),e(M,[2,137]),e(M,[2,138]),e(M,[2,139]),e(M,[2,140]),e(M,[2,141]),e(M,[2,142]),e(M,[2,143]),e(M,[2,144]),e(M,[2,145]),e(c,[2,12]),e(c,[2,18]),e(c,[2,19]),{9:[1,110]},e(Et,[2,26],{18:111,10:I1}),e(b,[2,27]),{40:112,41:38,42:C,43:39,45:40,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},e(b,[2,40]),e(b,[2,41]),e(b,[2,42]),e(R1,[2,71],{71:113,60:[1,115],72:[1,114]}),{74:116,76:117,77:[1,118],78:[1,119],113:kt,116:bt},e([42,58,60,72,86,99,102,103,106,108,111,112,113],[2,77]),e(b,[2,28]),e(b,[2,29]),e(b,[2,30]),e(b,[2,31]),e(b,[2,32]),{10:gt,12:Dt,14:Ft,27:Tt,28:122,32:St,42:Ct,58:_t,73:xt,77:[1,124],78:[1,125],80:135,81:Bt,82:mt,83:yt,84:vt,85:Vt,86:Lt,87:It,88:123,102:Rt,106:Nt,108:wt,111:Ot,112:Pt,113:Ut},e(nt,l,{5:148}),e(b,[2,37]),e(b,[2,38]),e(H1,[2,45],{42:Gt}),{42:C,45:150,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},{99:[1,151],100:152,102:[1,153]},{42:C,45:154,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},{42:C,45:155,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},e(T,[2,100],{10:[1,156],93:[1,157]}),{77:[1,158]},e(T,[2,108],{117:160,10:[1,159],14:k1,42:b1,58:g1,86:D1,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1}),e(T,[2,110],{10:[1,161]}),e(K,[2,176]),e(K,[2,163]),e(K,[2,164]),e(K,[2,165]),e(K,[2,166]),e(K,[2,167]),e(K,[2,168]),e(K,[2,169]),e(K,[2,170]),e(K,[2,171]),e(K,[2,172]),e(K,[2,173]),{42:C,45:162,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},{30:163,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:171,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:173,48:[1,172],65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:174,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:175,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:176,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{106:[1,177]},{30:178,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:179,63:[1,180],65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:181,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:182,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:183,65:p,77:O,78:P,79:164,113:A,114:d,115:E},e(M,[2,175]),e(c,[2,20]),e(Et,[2,25]),e(H1,[2,43],{18:184,10:I1}),e(R1,[2,68],{10:[1,185]}),{10:[1,186]},{30:187,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{75:[1,188],76:189,113:kt,116:bt},e(m1,[2,73]),e(m1,[2,75]),e(m1,[2,76]),e(m1,[2,161]),e(m1,[2,162]),{8:q,9:Q,10:gt,11:Z,12:Dt,14:Ft,21:191,27:Tt,29:[1,190],32:St,42:Ct,58:_t,73:xt,80:135,81:Bt,82:mt,83:yt,84:vt,85:Vt,86:Lt,87:It,88:192,102:Rt,106:Nt,108:wt,111:Ot,112:Pt,113:Ut},e(g,[2,94]),e(g,[2,96]),e(g,[2,97]),e(g,[2,150]),e(g,[2,151]),e(g,[2,152]),e(g,[2,153]),e(g,[2,154]),e(g,[2,155]),e(g,[2,156]),e(g,[2,157]),e(g,[2,158]),e(g,[2,159]),e(g,[2,160]),e(g,[2,83]),e(g,[2,84]),e(g,[2,85]),e(g,[2,86]),e(g,[2,87]),e(g,[2,88]),e(g,[2,89]),e(g,[2,90]),e(g,[2,91]),e(g,[2,92]),e(g,[2,93]),{6:11,7:12,8:h,9:U,10:F,11:w,20:17,22:18,23:19,24:20,25:21,26:22,27:X,32:[1,193],33:24,34:o1,36:p1,38:A1,40:28,41:38,42:C,43:39,45:40,58:k,81:l1,82:U1,83:G1,84:M1,85:K1,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R,118:Y1,119:j1,120:z1,121:X1},{10:I1,18:194},{10:[1,195],42:C,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:109,111:L,112:I,113:R},{10:[1,196]},{10:[1,197],103:[1,198]},e(Mt,[2,121]),{10:[1,199],42:C,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:109,111:L,112:I,113:R},{10:[1,200],42:C,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:109,111:L,112:I,113:R},{77:[1,201]},e(T,[2,102],{10:[1,202]}),e(T,[2,104],{10:[1,203]}),{77:[1,204]},e(K,[2,177]),{77:[1,205],95:[1,206]},e(W1,[2,50],{110:109,42:C,58:k,86:x,99:B,102:m,103:y,106:v,108:V,111:L,112:I,113:R}),{31:[1,207],65:p,79:208,113:A,114:d,115:E},e(h1,[2,79]),e(h1,[2,81]),e(h1,[2,82]),e(h1,[2,146]),e(h1,[2,147]),e(h1,[2,148]),e(h1,[2,149]),{47:[1,209],65:p,79:208,113:A,114:d,115:E},{30:210,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{49:[1,211],65:p,79:208,113:A,114:d,115:E},{51:[1,212],65:p,79:208,113:A,114:d,115:E},{53:[1,213],65:p,79:208,113:A,114:d,115:E},{55:[1,214],65:p,79:208,113:A,114:d,115:E},{58:[1,215]},{62:[1,216],65:p,79:208,113:A,114:d,115:E},{64:[1,217],65:p,79:208,113:A,114:d,115:E},{30:218,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{31:[1,219],65:p,79:208,113:A,114:d,115:E},{65:p,67:[1,220],69:[1,221],79:208,113:A,114:d,115:E},{65:p,67:[1,223],69:[1,222],79:208,113:A,114:d,115:E},e(H1,[2,44],{42:Gt}),e(R1,[2,70]),e(R1,[2,69]),{60:[1,224],65:p,79:208,113:A,114:d,115:E},e(R1,[2,72]),e(m1,[2,74]),{30:225,65:p,77:O,78:P,79:164,113:A,114:d,115:E},e(nt,l,{5:226}),e(g,[2,95]),e(b,[2,35]),{41:227,42:C,43:39,45:40,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},{10:J,58:$,81:t1,89:228,102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},{10:J,58:$,81:t1,89:239,101:[1,240],102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},{10:J,58:$,81:t1,89:241,101:[1,242],102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},{102:[1,243]},{10:J,58:$,81:t1,89:244,102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},{42:C,45:245,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},e(T,[2,101]),{77:[1,246]},{77:[1,247],95:[1,248]},e(T,[2,109]),e(T,[2,111],{10:[1,249]}),e(T,[2,112]),e(N,[2,51]),e(h1,[2,80]),e(N,[2,52]),{49:[1,250],65:p,79:208,113:A,114:d,115:E},e(N,[2,59]),e(N,[2,54]),e(N,[2,55]),e(N,[2,56]),{106:[1,251]},e(N,[2,58]),e(N,[2,60]),{64:[1,252],65:p,79:208,113:A,114:d,115:E},e(N,[2,62]),e(N,[2,63]),e(N,[2,65]),e(N,[2,64]),e(N,[2,66]),e([10,42,58,86,99,102,103,106,108,111,112,113],[2,78]),{31:[1,253],65:p,79:208,113:A,114:d,115:E},{6:11,7:12,8:h,9:U,10:F,11:w,20:17,22:18,23:19,24:20,25:21,26:22,27:X,32:[1,254],33:24,34:o1,36:p1,38:A1,40:28,41:38,42:C,43:39,45:40,58:k,81:l1,82:U1,83:G1,84:M1,85:K1,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R,118:Y1,119:j1,120:z1,121:X1},e(W1,[2,48]),e(T,[2,114],{103:y1}),e(Kt,[2,123],{105:256,10:J,58:$,81:t1,102:e1,106:s1,107:u1,108:i1,109:r1}),e(W,[2,125]),e(W,[2,127]),e(W,[2,128]),e(W,[2,129]),e(W,[2,130]),e(W,[2,131]),e(W,[2,132]),e(W,[2,133]),e(W,[2,134]),e(T,[2,115],{103:y1}),{10:[1,257]},e(T,[2,116],{103:y1}),{10:[1,258]},e(Mt,[2,122]),e(T,[2,98],{103:y1}),e(T,[2,99],{110:109,42:C,58:k,86:x,99:B,102:m,103:y,106:v,108:V,111:L,112:I,113:R}),e(T,[2,103]),e(T,[2,105],{10:[1,259]}),e(T,[2,106]),{95:[1,260]},{49:[1,261]},{60:[1,262]},{64:[1,263]},{8:q,9:Q,11:Z,21:264},e(b,[2,34]),{10:J,58:$,81:t1,102:e1,104:265,105:230,106:s1,107:u1,108:i1,109:r1},e(W,[2,126]),{14:k1,42:b1,58:g1,86:D1,98:266,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1,117:84},{14:k1,42:b1,58:g1,86:D1,98:267,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1,117:84},{95:[1,268]},e(T,[2,113]),e(N,[2,53]),{30:269,65:p,77:O,78:P,79:164,113:A,114:d,115:E},e(N,[2,61]),e(nt,l,{5:270}),e(Kt,[2,124],{105:256,10:J,58:$,81:t1,102:e1,106:s1,107:u1,108:i1,109:r1}),e(T,[2,119],{117:160,10:[1,271],14:k1,42:b1,58:g1,86:D1,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1}),e(T,[2,120],{117:160,10:[1,272],14:k1,42:b1,58:g1,86:D1,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1}),e(T,[2,107]),{31:[1,273],65:p,79:208,113:A,114:d,115:E},{6:11,7:12,8:h,9:U,10:F,11:w,20:17,22:18,23:19,24:20,25:21,26:22,27:X,32:[1,274],33:24,34:o1,36:p1,38:A1,40:28,41:38,42:C,43:39,45:40,58:k,81:l1,82:U1,83:G1,84:M1,85:K1,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R,118:Y1,119:j1,120:z1,121:X1},{10:J,58:$,81:t1,89:275,102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},{10:J,58:$,81:t1,89:276,102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},e(N,[2,57]),e(b,[2,33]),e(T,[2,117],{103:y1}),e(T,[2,118],{103:y1})],defaultActions:{},parseError:function(a,o){if(o.recoverable)this.trace(a);else{var f=new Error(a);throw f.hash=o,f}},parse:function(a){var o=this,f=[0],r=[],S=[null],t=[],N1=this.table,s="",Y=0,Yt=0,Ce=2,jt=1,_e=t.slice.call(arguments,1),_=Object.create(this.lexer),d1={yy:{}};for(var ot in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ot)&&(d1.yy[ot]=this.yy[ot]);_.setInput(a,d1.yy),d1.yy.lexer=_,d1.yy.parser=this,typeof _.yylloc>"u"&&(_.yylloc={});var lt=_.yylloc;t.push(lt);var xe=_.options&&_.options.ranges;typeof d1.yy.parseError=="function"?this.parseError=d1.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Be(){var a1;return a1=r.pop()||_.lex()||jt,typeof a1!="number"&&(a1 instanceof Array&&(r=a1,a1=r.pop()),a1=o.symbols_[a1]||a1),a1}for(var G,E1,j,ht,v1={},q1,n1,zt,Q1;;){if(E1=f[f.length-1],this.defaultActions[E1]?j=this.defaultActions[E1]:((G===null||typeof G>"u")&&(G=Be()),j=N1[E1]&&N1[E1][G]),typeof j>"u"||!j.length||!j[0]){var ft="";Q1=[];for(q1 in N1[E1])this.terminals_[q1]&&q1>Ce&&Q1.push("'"+this.terminals_[q1]+"'");_.showPosition?ft="Parse error on line "+(Y+1)+`:
                        +import{c as et,v as me,s as ye,g as ve,a as Ve,b as Le,x as Ie,y as Re,l as J1,z as dt,A as Ne,j as we,h as w1}from"./mermaid.core-Q3WVcjPF.js";var pt=function(){var e=function(f1,a,o,f){for(o=o||{},f=f1.length;f--;o[f1[f]]=a);return o},u=[1,4],i=[1,3],n=[1,5],c=[1,8,9,10,11,27,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],l=[2,2],h=[1,13],U=[1,14],F=[1,15],w=[1,16],X=[1,23],o1=[1,25],p1=[1,26],A1=[1,27],C=[1,49],k=[1,48],l1=[1,29],U1=[1,30],G1=[1,31],M1=[1,32],K1=[1,33],x=[1,44],B=[1,46],m=[1,42],y=[1,47],v=[1,43],V=[1,50],L=[1,45],I=[1,51],R=[1,52],Y1=[1,34],j1=[1,35],z1=[1,36],X1=[1,37],I1=[1,57],b=[1,8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],q=[1,61],Q=[1,60],Z=[1,62],H1=[8,9,11,73,75],k1=[1,88],b1=[1,93],g1=[1,92],D1=[1,89],F1=[1,85],T1=[1,91],S1=[1,87],C1=[1,94],_1=[1,90],x1=[1,95],B1=[1,86],W1=[8,9,10,11,73,75],N=[8,9,10,11,44,73,75],M=[8,9,10,11,29,42,44,46,48,50,52,54,56,58,61,63,65,66,68,73,75,86,99,102,103,106,108,111,112,113],Et=[8,9,11,42,58,73,75,86,99,102,103,106,108,111,112,113],R1=[42,58,86,99,102,103,106,108,111,112,113],kt=[1,121],bt=[1,120],gt=[1,128],Dt=[1,142],Ft=[1,143],Tt=[1,144],St=[1,145],Ct=[1,130],_t=[1,132],xt=[1,136],Bt=[1,137],mt=[1,138],yt=[1,139],vt=[1,140],Vt=[1,141],Lt=[1,146],It=[1,147],Rt=[1,126],Nt=[1,127],wt=[1,134],Ot=[1,129],Pt=[1,133],Ut=[1,131],nt=[8,9,10,11,27,32,34,36,38,42,58,81,82,83,84,85,86,99,102,103,106,108,111,112,113,118,119,120,121],Gt=[1,149],T=[8,9,11],K=[8,9,10,11,14,42,58,86,102,103,106,108,111,112,113],p=[1,169],O=[1,165],P=[1,166],A=[1,170],d=[1,167],E=[1,168],m1=[75,113,116],g=[8,9,10,11,12,14,27,29,32,42,58,73,81,82,83,84,85,86,87,102,106,108,111,112,113],Mt=[10,103],h1=[31,47,49,51,53,55,60,62,64,65,67,69,113,114,115],J=[1,235],$=[1,233],t1=[1,237],e1=[1,231],s1=[1,232],u1=[1,234],i1=[1,236],r1=[1,238],y1=[1,255],Kt=[8,9,11,103],W=[8,9,10,11,58,81,102,103,106,107,108,109],at={trace:function(){},yy:{},symbols_:{error:2,start:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,NODIR:13,DIR:14,FirstStmtSeparator:15,ending:16,endToken:17,spaceList:18,spaceListNewline:19,vertexStatement:20,separator:21,styleStatement:22,linkStyleStatement:23,classDefStatement:24,classStatement:25,clickStatement:26,subgraph:27,textNoTags:28,SQS:29,text:30,SQE:31,end:32,direction:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,link:39,node:40,styledVertex:41,AMP:42,vertex:43,STYLE_SEPARATOR:44,idString:45,DOUBLECIRCLESTART:46,DOUBLECIRCLEEND:47,PS:48,PE:49,"(-":50,"-)":51,STADIUMSTART:52,STADIUMEND:53,SUBROUTINESTART:54,SUBROUTINEEND:55,VERTEX_WITH_PROPS_START:56,"NODE_STRING[field]":57,COLON:58,"NODE_STRING[value]":59,PIPE:60,CYLINDERSTART:61,CYLINDEREND:62,DIAMOND_START:63,DIAMOND_STOP:64,TAGEND:65,TRAPSTART:66,TRAPEND:67,INVTRAPSTART:68,INVTRAPEND:69,linkStatement:70,arrowText:71,TESTSTR:72,START_LINK:73,edgeText:74,LINK:75,edgeTextToken:76,STR:77,MD_STR:78,textToken:79,keywords:80,STYLE:81,LINKSTYLE:82,CLASSDEF:83,CLASS:84,CLICK:85,DOWN:86,UP:87,textNoTagsToken:88,stylesOpt:89,"idString[vertex]":90,"idString[class]":91,CALLBACKNAME:92,CALLBACKARGS:93,HREF:94,LINK_TARGET:95,"STR[link]":96,"STR[tooltip]":97,alphaNum:98,DEFAULT:99,numList:100,INTERPOLATE:101,NUM:102,COMMA:103,style:104,styleComponent:105,NODE_STRING:106,UNIT:107,BRKT:108,PCT:109,idStringToken:110,MINUS:111,MULT:112,UNICODE_TEXT:113,TEXT:114,TAGSTART:115,EDGE_TEXT:116,alphaNumToken:117,direction_tb:118,direction_bt:119,direction_rl:120,direction_lr:121,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"NODIR",14:"DIR",27:"subgraph",29:"SQS",31:"SQE",32:"end",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",42:"AMP",44:"STYLE_SEPARATOR",46:"DOUBLECIRCLESTART",47:"DOUBLECIRCLEEND",48:"PS",49:"PE",50:"(-",51:"-)",52:"STADIUMSTART",53:"STADIUMEND",54:"SUBROUTINESTART",55:"SUBROUTINEEND",56:"VERTEX_WITH_PROPS_START",57:"NODE_STRING[field]",58:"COLON",59:"NODE_STRING[value]",60:"PIPE",61:"CYLINDERSTART",62:"CYLINDEREND",63:"DIAMOND_START",64:"DIAMOND_STOP",65:"TAGEND",66:"TRAPSTART",67:"TRAPEND",68:"INVTRAPSTART",69:"INVTRAPEND",72:"TESTSTR",73:"START_LINK",75:"LINK",77:"STR",78:"MD_STR",81:"STYLE",82:"LINKSTYLE",83:"CLASSDEF",84:"CLASS",85:"CLICK",86:"DOWN",87:"UP",90:"idString[vertex]",91:"idString[class]",92:"CALLBACKNAME",93:"CALLBACKARGS",94:"HREF",95:"LINK_TARGET",96:"STR[link]",97:"STR[tooltip]",99:"DEFAULT",101:"INTERPOLATE",102:"NUM",103:"COMMA",106:"NODE_STRING",107:"UNIT",108:"BRKT",109:"PCT",111:"MINUS",112:"MULT",113:"UNICODE_TEXT",114:"TEXT",115:"TAGSTART",116:"EDGE_TEXT",118:"direction_tb",119:"direction_bt",120:"direction_rl",121:"direction_lr"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,2],[4,3],[16,2],[16,1],[17,1],[17,1],[17,1],[15,1],[15,1],[15,2],[19,2],[19,2],[19,1],[19,1],[18,2],[18,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,9],[7,6],[7,4],[7,1],[7,2],[7,2],[7,1],[21,1],[21,1],[21,1],[20,3],[20,4],[20,2],[20,1],[40,1],[40,5],[41,1],[41,3],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,8],[43,4],[43,4],[43,4],[43,6],[43,4],[43,4],[43,4],[43,4],[43,4],[43,1],[39,2],[39,3],[39,3],[39,1],[39,3],[74,1],[74,2],[74,1],[74,1],[70,1],[71,3],[30,1],[30,2],[30,1],[30,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[80,1],[28,1],[28,2],[28,1],[28,1],[24,5],[25,5],[26,2],[26,4],[26,3],[26,5],[26,3],[26,5],[26,5],[26,7],[26,2],[26,4],[26,2],[26,4],[26,4],[26,6],[22,5],[23,5],[23,5],[23,9],[23,9],[23,7],[23,7],[100,1],[100,3],[89,1],[89,3],[104,1],[104,2],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[105,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[110,1],[79,1],[79,1],[79,1],[79,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[88,1],[76,1],[76,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[45,1],[45,2],[98,1],[98,2],[33,1],[33,1],[33,1],[33,1]],performAction:function(a,o,f,r,S,t,N1){var s=t.length-1;switch(S){case 2:this.$=[];break;case 3:(!Array.isArray(t[s])||t[s].length>0)&&t[s-1].push(t[s]),this.$=t[s-1];break;case 4:case 176:this.$=t[s];break;case 11:r.setDirection("TB"),this.$="TB";break;case 12:r.setDirection(t[s-1]),this.$=t[s-1];break;case 27:this.$=t[s-1].nodes;break;case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 33:this.$=r.addSubGraph(t[s-6],t[s-1],t[s-4]);break;case 34:this.$=r.addSubGraph(t[s-3],t[s-1],t[s-3]);break;case 35:this.$=r.addSubGraph(void 0,t[s-1],void 0);break;case 37:this.$=t[s].trim(),r.setAccTitle(this.$);break;case 38:case 39:this.$=t[s].trim(),r.setAccDescription(this.$);break;case 43:r.addLink(t[s-2].stmt,t[s],t[s-1]),this.$={stmt:t[s],nodes:t[s].concat(t[s-2].nodes)};break;case 44:r.addLink(t[s-3].stmt,t[s-1],t[s-2]),this.$={stmt:t[s-1],nodes:t[s-1].concat(t[s-3].nodes)};break;case 45:this.$={stmt:t[s-1],nodes:t[s-1]};break;case 46:this.$={stmt:t[s],nodes:t[s]};break;case 47:this.$=[t[s]];break;case 48:this.$=t[s-4].concat(t[s]);break;case 49:this.$=t[s];break;case 50:this.$=t[s-2],r.setClass(t[s-2],t[s]);break;case 51:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"square");break;case 52:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"doublecircle");break;case 53:this.$=t[s-5],r.addVertex(t[s-5],t[s-2],"circle");break;case 54:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"ellipse");break;case 55:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"stadium");break;case 56:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"subroutine");break;case 57:this.$=t[s-7],r.addVertex(t[s-7],t[s-1],"rect",void 0,void 0,void 0,Object.fromEntries([[t[s-5],t[s-3]]]));break;case 58:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"cylinder");break;case 59:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"round");break;case 60:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"diamond");break;case 61:this.$=t[s-5],r.addVertex(t[s-5],t[s-2],"hexagon");break;case 62:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"odd");break;case 63:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"trapezoid");break;case 64:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"inv_trapezoid");break;case 65:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"lean_right");break;case 66:this.$=t[s-3],r.addVertex(t[s-3],t[s-1],"lean_left");break;case 67:this.$=t[s],r.addVertex(t[s]);break;case 68:t[s-1].text=t[s],this.$=t[s-1];break;case 69:case 70:t[s-2].text=t[s-1],this.$=t[s-2];break;case 71:this.$=t[s];break;case 72:var Y=r.destructLink(t[s],t[s-2]);this.$={type:Y.type,stroke:Y.stroke,length:Y.length,text:t[s-1]};break;case 73:this.$={text:t[s],type:"text"};break;case 74:this.$={text:t[s-1].text+""+t[s],type:t[s-1].type};break;case 75:this.$={text:t[s],type:"string"};break;case 76:this.$={text:t[s],type:"markdown"};break;case 77:var Y=r.destructLink(t[s]);this.$={type:Y.type,stroke:Y.stroke,length:Y.length};break;case 78:this.$=t[s-1];break;case 79:this.$={text:t[s],type:"text"};break;case 80:this.$={text:t[s-1].text+""+t[s],type:t[s-1].type};break;case 81:this.$={text:t[s],type:"string"};break;case 82:case 97:this.$={text:t[s],type:"markdown"};break;case 94:this.$={text:t[s],type:"text"};break;case 95:this.$={text:t[s-1].text+""+t[s],type:t[s-1].type};break;case 96:this.$={text:t[s],type:"text"};break;case 98:this.$=t[s-4],r.addClass(t[s-2],t[s]);break;case 99:this.$=t[s-4],r.setClass(t[s-2],t[s]);break;case 100:case 108:this.$=t[s-1],r.setClickEvent(t[s-1],t[s]);break;case 101:case 109:this.$=t[s-3],r.setClickEvent(t[s-3],t[s-2]),r.setTooltip(t[s-3],t[s]);break;case 102:this.$=t[s-2],r.setClickEvent(t[s-2],t[s-1],t[s]);break;case 103:this.$=t[s-4],r.setClickEvent(t[s-4],t[s-3],t[s-2]),r.setTooltip(t[s-4],t[s]);break;case 104:this.$=t[s-2],r.setLink(t[s-2],t[s]);break;case 105:this.$=t[s-4],r.setLink(t[s-4],t[s-2]),r.setTooltip(t[s-4],t[s]);break;case 106:this.$=t[s-4],r.setLink(t[s-4],t[s-2],t[s]);break;case 107:this.$=t[s-6],r.setLink(t[s-6],t[s-4],t[s]),r.setTooltip(t[s-6],t[s-2]);break;case 110:this.$=t[s-1],r.setLink(t[s-1],t[s]);break;case 111:this.$=t[s-3],r.setLink(t[s-3],t[s-2]),r.setTooltip(t[s-3],t[s]);break;case 112:this.$=t[s-3],r.setLink(t[s-3],t[s-2],t[s]);break;case 113:this.$=t[s-5],r.setLink(t[s-5],t[s-4],t[s]),r.setTooltip(t[s-5],t[s-2]);break;case 114:this.$=t[s-4],r.addVertex(t[s-2],void 0,void 0,t[s]);break;case 115:this.$=t[s-4],r.updateLink([t[s-2]],t[s]);break;case 116:this.$=t[s-4],r.updateLink(t[s-2],t[s]);break;case 117:this.$=t[s-8],r.updateLinkInterpolate([t[s-6]],t[s-2]),r.updateLink([t[s-6]],t[s]);break;case 118:this.$=t[s-8],r.updateLinkInterpolate(t[s-6],t[s-2]),r.updateLink(t[s-6],t[s]);break;case 119:this.$=t[s-6],r.updateLinkInterpolate([t[s-4]],t[s]);break;case 120:this.$=t[s-6],r.updateLinkInterpolate(t[s-4],t[s]);break;case 121:case 123:this.$=[t[s]];break;case 122:case 124:t[s-2].push(t[s]),this.$=t[s-2];break;case 126:this.$=t[s-1]+t[s];break;case 174:this.$=t[s];break;case 175:this.$=t[s-1]+""+t[s];break;case 177:this.$=t[s-1]+""+t[s];break;case 178:this.$={stmt:"dir",value:"TB"};break;case 179:this.$={stmt:"dir",value:"BT"};break;case 180:this.$={stmt:"dir",value:"RL"};break;case 181:this.$={stmt:"dir",value:"LR"};break}},table:[{3:1,4:2,9:u,10:i,12:n},{1:[3]},e(c,l,{5:6}),{4:7,9:u,10:i,12:n},{4:8,9:u,10:i,12:n},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:h,9:U,10:F,11:w,20:17,22:18,23:19,24:20,25:21,26:22,27:X,33:24,34:o1,36:p1,38:A1,40:28,41:38,42:C,43:39,45:40,58:k,81:l1,82:U1,83:G1,84:M1,85:K1,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R,118:Y1,119:j1,120:z1,121:X1},e(c,[2,9]),e(c,[2,10]),e(c,[2,11]),{8:[1,54],9:[1,55],10:I1,15:53,18:56},e(b,[2,3]),e(b,[2,4]),e(b,[2,5]),e(b,[2,6]),e(b,[2,7]),e(b,[2,8]),{8:q,9:Q,11:Z,21:58,39:59,70:63,73:[1,64],75:[1,65]},{8:q,9:Q,11:Z,21:66},{8:q,9:Q,11:Z,21:67},{8:q,9:Q,11:Z,21:68},{8:q,9:Q,11:Z,21:69},{8:q,9:Q,11:Z,21:70},{8:q,9:Q,10:[1,71],11:Z,21:72},e(b,[2,36]),{35:[1,73]},{37:[1,74]},e(b,[2,39]),e(H1,[2,46],{18:75,10:I1}),{10:[1,76]},{10:[1,77]},{10:[1,78]},{10:[1,79]},{14:k1,42:b1,58:g1,77:[1,83],86:D1,92:[1,80],94:[1,81],98:82,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1,117:84},e(b,[2,178]),e(b,[2,179]),e(b,[2,180]),e(b,[2,181]),e(W1,[2,47]),e(W1,[2,49],{44:[1,96]}),e(N,[2,67],{110:109,29:[1,97],42:C,46:[1,98],48:[1,99],50:[1,100],52:[1,101],54:[1,102],56:[1,103],58:k,61:[1,104],63:[1,105],65:[1,106],66:[1,107],68:[1,108],86:x,99:B,102:m,103:y,106:v,108:V,111:L,112:I,113:R}),e(M,[2,174]),e(M,[2,135]),e(M,[2,136]),e(M,[2,137]),e(M,[2,138]),e(M,[2,139]),e(M,[2,140]),e(M,[2,141]),e(M,[2,142]),e(M,[2,143]),e(M,[2,144]),e(M,[2,145]),e(c,[2,12]),e(c,[2,18]),e(c,[2,19]),{9:[1,110]},e(Et,[2,26],{18:111,10:I1}),e(b,[2,27]),{40:112,41:38,42:C,43:39,45:40,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},e(b,[2,40]),e(b,[2,41]),e(b,[2,42]),e(R1,[2,71],{71:113,60:[1,115],72:[1,114]}),{74:116,76:117,77:[1,118],78:[1,119],113:kt,116:bt},e([42,58,60,72,86,99,102,103,106,108,111,112,113],[2,77]),e(b,[2,28]),e(b,[2,29]),e(b,[2,30]),e(b,[2,31]),e(b,[2,32]),{10:gt,12:Dt,14:Ft,27:Tt,28:122,32:St,42:Ct,58:_t,73:xt,77:[1,124],78:[1,125],80:135,81:Bt,82:mt,83:yt,84:vt,85:Vt,86:Lt,87:It,88:123,102:Rt,106:Nt,108:wt,111:Ot,112:Pt,113:Ut},e(nt,l,{5:148}),e(b,[2,37]),e(b,[2,38]),e(H1,[2,45],{42:Gt}),{42:C,45:150,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},{99:[1,151],100:152,102:[1,153]},{42:C,45:154,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},{42:C,45:155,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},e(T,[2,100],{10:[1,156],93:[1,157]}),{77:[1,158]},e(T,[2,108],{117:160,10:[1,159],14:k1,42:b1,58:g1,86:D1,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1}),e(T,[2,110],{10:[1,161]}),e(K,[2,176]),e(K,[2,163]),e(K,[2,164]),e(K,[2,165]),e(K,[2,166]),e(K,[2,167]),e(K,[2,168]),e(K,[2,169]),e(K,[2,170]),e(K,[2,171]),e(K,[2,172]),e(K,[2,173]),{42:C,45:162,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},{30:163,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:171,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:173,48:[1,172],65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:174,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:175,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:176,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{106:[1,177]},{30:178,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:179,63:[1,180],65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:181,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:182,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{30:183,65:p,77:O,78:P,79:164,113:A,114:d,115:E},e(M,[2,175]),e(c,[2,20]),e(Et,[2,25]),e(H1,[2,43],{18:184,10:I1}),e(R1,[2,68],{10:[1,185]}),{10:[1,186]},{30:187,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{75:[1,188],76:189,113:kt,116:bt},e(m1,[2,73]),e(m1,[2,75]),e(m1,[2,76]),e(m1,[2,161]),e(m1,[2,162]),{8:q,9:Q,10:gt,11:Z,12:Dt,14:Ft,21:191,27:Tt,29:[1,190],32:St,42:Ct,58:_t,73:xt,80:135,81:Bt,82:mt,83:yt,84:vt,85:Vt,86:Lt,87:It,88:192,102:Rt,106:Nt,108:wt,111:Ot,112:Pt,113:Ut},e(g,[2,94]),e(g,[2,96]),e(g,[2,97]),e(g,[2,150]),e(g,[2,151]),e(g,[2,152]),e(g,[2,153]),e(g,[2,154]),e(g,[2,155]),e(g,[2,156]),e(g,[2,157]),e(g,[2,158]),e(g,[2,159]),e(g,[2,160]),e(g,[2,83]),e(g,[2,84]),e(g,[2,85]),e(g,[2,86]),e(g,[2,87]),e(g,[2,88]),e(g,[2,89]),e(g,[2,90]),e(g,[2,91]),e(g,[2,92]),e(g,[2,93]),{6:11,7:12,8:h,9:U,10:F,11:w,20:17,22:18,23:19,24:20,25:21,26:22,27:X,32:[1,193],33:24,34:o1,36:p1,38:A1,40:28,41:38,42:C,43:39,45:40,58:k,81:l1,82:U1,83:G1,84:M1,85:K1,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R,118:Y1,119:j1,120:z1,121:X1},{10:I1,18:194},{10:[1,195],42:C,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:109,111:L,112:I,113:R},{10:[1,196]},{10:[1,197],103:[1,198]},e(Mt,[2,121]),{10:[1,199],42:C,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:109,111:L,112:I,113:R},{10:[1,200],42:C,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:109,111:L,112:I,113:R},{77:[1,201]},e(T,[2,102],{10:[1,202]}),e(T,[2,104],{10:[1,203]}),{77:[1,204]},e(K,[2,177]),{77:[1,205],95:[1,206]},e(W1,[2,50],{110:109,42:C,58:k,86:x,99:B,102:m,103:y,106:v,108:V,111:L,112:I,113:R}),{31:[1,207],65:p,79:208,113:A,114:d,115:E},e(h1,[2,79]),e(h1,[2,81]),e(h1,[2,82]),e(h1,[2,146]),e(h1,[2,147]),e(h1,[2,148]),e(h1,[2,149]),{47:[1,209],65:p,79:208,113:A,114:d,115:E},{30:210,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{49:[1,211],65:p,79:208,113:A,114:d,115:E},{51:[1,212],65:p,79:208,113:A,114:d,115:E},{53:[1,213],65:p,79:208,113:A,114:d,115:E},{55:[1,214],65:p,79:208,113:A,114:d,115:E},{58:[1,215]},{62:[1,216],65:p,79:208,113:A,114:d,115:E},{64:[1,217],65:p,79:208,113:A,114:d,115:E},{30:218,65:p,77:O,78:P,79:164,113:A,114:d,115:E},{31:[1,219],65:p,79:208,113:A,114:d,115:E},{65:p,67:[1,220],69:[1,221],79:208,113:A,114:d,115:E},{65:p,67:[1,223],69:[1,222],79:208,113:A,114:d,115:E},e(H1,[2,44],{42:Gt}),e(R1,[2,70]),e(R1,[2,69]),{60:[1,224],65:p,79:208,113:A,114:d,115:E},e(R1,[2,72]),e(m1,[2,74]),{30:225,65:p,77:O,78:P,79:164,113:A,114:d,115:E},e(nt,l,{5:226}),e(g,[2,95]),e(b,[2,35]),{41:227,42:C,43:39,45:40,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},{10:J,58:$,81:t1,89:228,102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},{10:J,58:$,81:t1,89:239,101:[1,240],102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},{10:J,58:$,81:t1,89:241,101:[1,242],102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},{102:[1,243]},{10:J,58:$,81:t1,89:244,102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},{42:C,45:245,58:k,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R},e(T,[2,101]),{77:[1,246]},{77:[1,247],95:[1,248]},e(T,[2,109]),e(T,[2,111],{10:[1,249]}),e(T,[2,112]),e(N,[2,51]),e(h1,[2,80]),e(N,[2,52]),{49:[1,250],65:p,79:208,113:A,114:d,115:E},e(N,[2,59]),e(N,[2,54]),e(N,[2,55]),e(N,[2,56]),{106:[1,251]},e(N,[2,58]),e(N,[2,60]),{64:[1,252],65:p,79:208,113:A,114:d,115:E},e(N,[2,62]),e(N,[2,63]),e(N,[2,65]),e(N,[2,64]),e(N,[2,66]),e([10,42,58,86,99,102,103,106,108,111,112,113],[2,78]),{31:[1,253],65:p,79:208,113:A,114:d,115:E},{6:11,7:12,8:h,9:U,10:F,11:w,20:17,22:18,23:19,24:20,25:21,26:22,27:X,32:[1,254],33:24,34:o1,36:p1,38:A1,40:28,41:38,42:C,43:39,45:40,58:k,81:l1,82:U1,83:G1,84:M1,85:K1,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R,118:Y1,119:j1,120:z1,121:X1},e(W1,[2,48]),e(T,[2,114],{103:y1}),e(Kt,[2,123],{105:256,10:J,58:$,81:t1,102:e1,106:s1,107:u1,108:i1,109:r1}),e(W,[2,125]),e(W,[2,127]),e(W,[2,128]),e(W,[2,129]),e(W,[2,130]),e(W,[2,131]),e(W,[2,132]),e(W,[2,133]),e(W,[2,134]),e(T,[2,115],{103:y1}),{10:[1,257]},e(T,[2,116],{103:y1}),{10:[1,258]},e(Mt,[2,122]),e(T,[2,98],{103:y1}),e(T,[2,99],{110:109,42:C,58:k,86:x,99:B,102:m,103:y,106:v,108:V,111:L,112:I,113:R}),e(T,[2,103]),e(T,[2,105],{10:[1,259]}),e(T,[2,106]),{95:[1,260]},{49:[1,261]},{60:[1,262]},{64:[1,263]},{8:q,9:Q,11:Z,21:264},e(b,[2,34]),{10:J,58:$,81:t1,102:e1,104:265,105:230,106:s1,107:u1,108:i1,109:r1},e(W,[2,126]),{14:k1,42:b1,58:g1,86:D1,98:266,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1,117:84},{14:k1,42:b1,58:g1,86:D1,98:267,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1,117:84},{95:[1,268]},e(T,[2,113]),e(N,[2,53]),{30:269,65:p,77:O,78:P,79:164,113:A,114:d,115:E},e(N,[2,61]),e(nt,l,{5:270}),e(Kt,[2,124],{105:256,10:J,58:$,81:t1,102:e1,106:s1,107:u1,108:i1,109:r1}),e(T,[2,119],{117:160,10:[1,271],14:k1,42:b1,58:g1,86:D1,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1}),e(T,[2,120],{117:160,10:[1,272],14:k1,42:b1,58:g1,86:D1,102:F1,103:T1,106:S1,108:C1,111:_1,112:x1,113:B1}),e(T,[2,107]),{31:[1,273],65:p,79:208,113:A,114:d,115:E},{6:11,7:12,8:h,9:U,10:F,11:w,20:17,22:18,23:19,24:20,25:21,26:22,27:X,32:[1,274],33:24,34:o1,36:p1,38:A1,40:28,41:38,42:C,43:39,45:40,58:k,81:l1,82:U1,83:G1,84:M1,85:K1,86:x,99:B,102:m,103:y,106:v,108:V,110:41,111:L,112:I,113:R,118:Y1,119:j1,120:z1,121:X1},{10:J,58:$,81:t1,89:275,102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},{10:J,58:$,81:t1,89:276,102:e1,104:229,105:230,106:s1,107:u1,108:i1,109:r1},e(N,[2,57]),e(b,[2,33]),e(T,[2,117],{103:y1}),e(T,[2,118],{103:y1})],defaultActions:{},parseError:function(a,o){if(o.recoverable)this.trace(a);else{var f=new Error(a);throw f.hash=o,f}},parse:function(a){var o=this,f=[0],r=[],S=[null],t=[],N1=this.table,s="",Y=0,Yt=0,Ce=2,jt=1,_e=t.slice.call(arguments,1),_=Object.create(this.lexer),d1={yy:{}};for(var ot in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ot)&&(d1.yy[ot]=this.yy[ot]);_.setInput(a,d1.yy),d1.yy.lexer=_,d1.yy.parser=this,typeof _.yylloc>"u"&&(_.yylloc={});var lt=_.yylloc;t.push(lt);var xe=_.options&&_.options.ranges;typeof d1.yy.parseError=="function"?this.parseError=d1.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Be(){var a1;return a1=r.pop()||_.lex()||jt,typeof a1!="number"&&(a1 instanceof Array&&(r=a1,a1=r.pop()),a1=o.symbols_[a1]||a1),a1}for(var G,E1,j,ht,v1={},q1,n1,zt,Q1;;){if(E1=f[f.length-1],this.defaultActions[E1]?j=this.defaultActions[E1]:((G===null||typeof G>"u")&&(G=Be()),j=N1[E1]&&N1[E1][G]),typeof j>"u"||!j.length||!j[0]){var ft="";Q1=[];for(q1 in N1[E1])this.terminals_[q1]&&q1>Ce&&Q1.push("'"+this.terminals_[q1]+"'");_.showPosition?ft="Parse error on line "+(Y+1)+`:
                         `+_.showPosition()+`
                         Expecting `+Q1.join(", ")+", got '"+(this.terminals_[G]||G)+"'":ft="Parse error on line "+(Y+1)+": Unexpected "+(G==jt?"end of input":"'"+(this.terminals_[G]||G)+"'"),this.parseError(ft,{text:_.match,token:this.terminals_[G]||G,line:_.yylineno,loc:lt,expected:Q1})}if(j[0]instanceof Array&&j.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E1+", token: "+G);switch(j[0]){case 1:f.push(G),S.push(_.yytext),t.push(_.yylloc),f.push(j[1]),G=null,Yt=_.yyleng,s=_.yytext,Y=_.yylineno,lt=_.yylloc;break;case 2:if(n1=this.productions_[j[1]][1],v1.$=S[S.length-n1],v1._$={first_line:t[t.length-(n1||1)].first_line,last_line:t[t.length-1].last_line,first_column:t[t.length-(n1||1)].first_column,last_column:t[t.length-1].last_column},xe&&(v1._$.range=[t[t.length-(n1||1)].range[0],t[t.length-1].range[1]]),ht=this.performAction.apply(v1,[s,Yt,Y,d1.yy,j[1],S,t].concat(_e)),typeof ht<"u")return ht;n1&&(f=f.slice(0,-1*n1*2),S=S.slice(0,-1*n1),t=t.slice(0,-1*n1)),f.push(this.productions_[j[1]][0]),S.push(v1.$),t.push(v1._$),zt=N1[f[f.length-2]][f[f.length-1]],f.push(zt);break;case 3:return!0}}return!0}},Se=function(){var f1={EOF:1,parseError:function(o,f){if(this.yy.parser)this.yy.parser.parseError(o,f);else throw new Error(o)},setInput:function(a,o){return this.yy=o||this.yy||{},this._input=a,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.offset++,this.match+=a,this.matched+=a;var o=a.match(/(?:\r\n?|\n).*/g);return o?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),a},unput:function(a){var o=a.length,f=a.split(/(?:\r\n?|\n)/g);this._input=a+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-o),this.offset-=o;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),f.length-1&&(this.yylineno-=f.length-1);var S=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:f?(f.length===r.length?this.yylloc.first_column:0)+r[r.length-f.length].length-f[0].length:this.yylloc.first_column-o},this.options.ranges&&(this.yylloc.range=[S[0],S[0]+this.yyleng-o]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
                         `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(a){this.unput(this.match.slice(a))},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),o=new Array(a.length+1).join("-");return a+this.upcomingInput()+`
                        diff --git a/assets/flowDiagram-5540d9b9-XEePSu7I.js b/assets/flowDiagram-5540d9b9-mp-41puG.js
                        similarity index 97%
                        rename from assets/flowDiagram-5540d9b9-XEePSu7I.js
                        rename to assets/flowDiagram-5540d9b9-mp-41puG.js
                        index 03217b28e2..f3e39feaa9 100644
                        --- a/assets/flowDiagram-5540d9b9-XEePSu7I.js
                        +++ b/assets/flowDiagram-5540d9b9-mp-41puG.js
                        @@ -1,4 +1,4 @@
                        -import{p as Lt,f as V}from"./flowDb-4b19a42f-sAhi6J2v.js";import{h as S,f as tt,G as _t}from"./graph-cZfODKa1.js";import{h as x,o as U,p as Y,q as et,c as G,r as rt,j as at,l as R,t as z,u as Et}from"./mermaid.core-95b3ca__.js";import{u as Tt,r as Nt,p as At,l as Ct,d as M}from"./layout-konkdG3Z.js";import{a as N,b as nt,i as st,c as E,e as it,d as ot,f as It,g as Bt,s as Mt}from"./styles-3ed67cfa-FBozeukd.js";import{l as Dt}from"./line-_nnM_7ZX.js";import"./app-PDrbPfzp.js";import"./index-fc10efb0-knA-ZLJ0.js";import"./clone-jETecP85.js";import"./edges-d32062c0-iT1MEq_Y.js";import"./createText-6b48ae7d-9AoX5zU9.js";import"./channel-GQnHP4O7.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";function Rt(r){if(!r.ok)throw new Error(r.status+" "+r.statusText);return r.text()}function Gt(r,e){return fetch(r,e).then(Rt)}function Pt(r){return(e,t)=>Gt(e,t).then(n=>new DOMParser().parseFromString(n,r))}var Ut=Pt("image/svg+xml"),H={normal:Wt,vee:Vt,undirected:zt};function $t(r){H=r}function Wt(r,e,t,n){var a=r.append("marker").attr("id",e).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto"),s=a.append("path").attr("d","M 0 0 L 10 5 L 0 10 z").style("stroke-width",1).style("stroke-dasharray","1,0");N(s,t[n+"Style"]),t[n+"Class"]&&s.attr("class",t[n+"Class"])}function Vt(r,e,t,n){var a=r.append("marker").attr("id",e).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto"),s=a.append("path").attr("d","M 0 0 L 10 5 L 0 10 L 4 5 z").style("stroke-width",1).style("stroke-dasharray","1,0");N(s,t[n+"Style"]),t[n+"Class"]&&s.attr("class",t[n+"Class"])}function zt(r,e,t,n){var a=r.append("marker").attr("id",e).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto"),s=a.append("path").attr("d","M 0 5 L 10 5").style("stroke-width",1).style("stroke-dasharray","1,0");N(s,t[n+"Style"]),t[n+"Class"]&&s.attr("class",t[n+"Class"])}function Yt(r,e){var t=r;return t.node().appendChild(e.label),N(t,e.labelStyle),t}function Ht(r,e){for(var t=r.append("text"),n=Xt(e.label).split(`
                        +import{p as Lt,f as V}from"./flowDb-4b19a42f-e0bq62ON.js";import{h as S,f as tt,G as _t}from"./graph-yVkSecXb.js";import{h as x,o as U,p as Y,q as et,c as G,r as rt,j as at,l as R,t as z,u as Et}from"./mermaid.core-Q3WVcjPF.js";import{u as Tt,r as Nt,p as At,l as Ct,d as M}from"./layout-2f_iGf4E.js";import{a as N,b as nt,i as st,c as E,e as it,d as ot,f as It,g as Bt,s as Mt}from"./styles-3ed67cfa-xu8Odik1.js";import{l as Dt}from"./line-3Gyevr9q.js";import"./app-UOvWaKji.js";import"./index-fc10efb0-cfY4JypU.js";import"./clone-bRwIupqN.js";import"./edges-d32062c0-DdP-jtfh.js";import"./createText-6b48ae7d-yUX1YD6G.js";import"./channel-hMLbS6Zi.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";function Rt(r){if(!r.ok)throw new Error(r.status+" "+r.statusText);return r.text()}function Gt(r,e){return fetch(r,e).then(Rt)}function Pt(r){return(e,t)=>Gt(e,t).then(n=>new DOMParser().parseFromString(n,r))}var Ut=Pt("image/svg+xml"),H={normal:Wt,vee:Vt,undirected:zt};function $t(r){H=r}function Wt(r,e,t,n){var a=r.append("marker").attr("id",e).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto"),s=a.append("path").attr("d","M 0 0 L 10 5 L 0 10 z").style("stroke-width",1).style("stroke-dasharray","1,0");N(s,t[n+"Style"]),t[n+"Class"]&&s.attr("class",t[n+"Class"])}function Vt(r,e,t,n){var a=r.append("marker").attr("id",e).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto"),s=a.append("path").attr("d","M 0 0 L 10 5 L 0 10 L 4 5 z").style("stroke-width",1).style("stroke-dasharray","1,0");N(s,t[n+"Style"]),t[n+"Class"]&&s.attr("class",t[n+"Class"])}function zt(r,e,t,n){var a=r.append("marker").attr("id",e).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerUnits","strokeWidth").attr("markerWidth",8).attr("markerHeight",6).attr("orient","auto"),s=a.append("path").attr("d","M 0 5 L 10 5").style("stroke-width",1).style("stroke-dasharray","1,0");N(s,t[n+"Style"]),t[n+"Class"]&&s.attr("class",t[n+"Class"])}function Yt(r,e){var t=r;return t.node().appendChild(e.label),N(t,e.labelStyle),t}function Ht(r,e){for(var t=r.append("text"),n=Xt(e.label).split(`
                         `),a=0;a0}function T(r,e,t){var n=r.x,a=r.y,s=[],i=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY;e.forEach(function(p){i=Math.min(i,p.x),o=Math.min(o,p.y)});for(var c=n-r.width/2-i,d=a-r.height/2-o,l=0;l1&&s.sort(function(p,y){var f=p.x-t.x,g=p.y-t.y,k=Math.sqrt(f*f+g*g),I=y.x-t.x,_=y.y-t.y,$=Math.sqrt(I*I+_*_);return k<$?-1:k===$?0:1}),s[0]):(console.log("NO INTERSECTION FOUND, RETURN NODE CENTER",r),r)}function Z(r,e){var t=r.x,n=r.y,a=e.x-t,s=e.y-n,i=r.width/2,o=r.height/2,c,d;return Math.abs(s)*i>Math.abs(a)*o?(s<0&&(o=-o),c=s===0?0:o*a/s,d=o):(a<0&&(i=-i),c=i,d=a===0?0:i*s/a),{x:t+c,y:n+d}}var K={rect:oe,ellipse:le,circle:ce,diamond:de};function ie(r){K=r}function oe(r,e,t){var n=r.insert("rect",":first-child").attr("rx",t.rx).attr("ry",t.ry).attr("x",-e.width/2).attr("y",-e.height/2).attr("width",e.width).attr("height",e.height);return t.intersect=function(a){return Z(t,a)},n}function le(r,e,t){var n=e.width/2,a=e.height/2,s=r.insert("ellipse",":first-child").attr("x",-e.width/2).attr("y",-e.height/2).attr("rx",n).attr("ry",a);return t.intersect=function(i){return ct(t,n,a,i)},s}function ce(r,e,t){var n=Math.max(e.width,e.height)/2,a=r.insert("circle",":first-child").attr("x",-e.width/2).attr("y",-e.height/2).attr("r",n);return t.intersect=function(s){return ne(t,n,s)},a}function de(r,e,t){var n=e.width*Math.SQRT2/2,a=e.height*Math.SQRT2/2,s=[{x:0,y:-a},{x:-n,y:0},{x:0,y:a},{x:n,y:0}],i=r.insert("polygon",":first-child").attr("points",s.map(function(o){return o.x+","+o.y}).join(" "));return t.intersect=function(o){return T(t,s,o)},i}function he(){var r=function(e,t){pe(t);var n=D(e,"output"),a=D(n,"clusters"),s=D(n,"edgePaths"),i=F(D(n,"edgeLabels"),t),o=Q(D(n,"nodes"),t,K);Ct(t),ae(o,t),re(i,t),q(s,t,H);var c=X(a,t);ee(c,t),ve(t)};return r.createNodes=function(e){return arguments.length?(te(e),r):Q},r.createClusters=function(e){return arguments.length?(Ft(e),r):X},r.createEdgeLabels=function(e){return arguments.length?(qt(e),r):F},r.createEdgePaths=function(e){return arguments.length?(Qt(e),r):q},r.shapes=function(e){return arguments.length?(ie(e),r):K},r.arrows=function(e){return arguments.length?($t(e),r):H},r}var ue={paddingLeft:10,paddingRight:10,paddingTop:10,paddingBottom:10,rx:0,ry:0,shape:"rect"},fe={arrowhead:"normal",curve:U};function pe(r){r.nodes().forEach(function(e){var t=r.node(e);!S(t,"label")&&!r.children(e).length&&(t.label=e),S(t,"paddingX")&&M(t,{paddingLeft:t.paddingX,paddingRight:t.paddingX}),S(t,"paddingY")&&M(t,{paddingTop:t.paddingY,paddingBottom:t.paddingY}),S(t,"padding")&&M(t,{paddingLeft:t.padding,paddingRight:t.padding,paddingTop:t.padding,paddingBottom:t.padding}),M(t,ue),tt(["paddingLeft","paddingRight","paddingTop","paddingBottom"],function(n){t[n]=Number(t[n])}),S(t,"width")&&(t._prevWidth=t.width),S(t,"height")&&(t._prevHeight=t.height)}),r.edges().forEach(function(e){var t=r.edge(e);S(t,"label")||(t.label=""),M(t,fe)})}function ve(r){tt(r.nodes(),function(e){var t=r.node(e);S(t,"_prevWidth")?t.width=t._prevWidth:delete t.width,S(t,"_prevHeight")?t.height=t._prevHeight:delete t.height,delete t._prevWidth,delete t._prevHeight})}function D(r,e){var t=r.select("g."+e);return t.empty()&&(t=r.append("g").attr("class",e)),t}function dt(r,e,t){const n=e.width,a=e.height,s=(n+a)*.9,i=[{x:s/2,y:0},{x:s,y:-s/2},{x:s/2,y:-s},{x:0,y:-s/2}],o=A(r,s,s,i);return t.intersect=function(c){return T(t,i,c)},o}function ht(r,e,t){const a=e.height,s=a/4,i=e.width+2*s,o=[{x:s,y:0},{x:i-s,y:0},{x:i,y:-a/2},{x:i-s,y:-a},{x:s,y:-a},{x:0,y:-a/2}],c=A(r,i,a,o);return t.intersect=function(d){return T(t,o,d)},c}function ut(r,e,t){const n=e.width,a=e.height,s=[{x:-a/2,y:0},{x:n,y:0},{x:n,y:-a},{x:-a/2,y:-a},{x:0,y:-a/2}],i=A(r,n,a,s);return t.intersect=function(o){return T(t,s,o)},i}function ft(r,e,t){const n=e.width,a=e.height,s=[{x:-2*a/6,y:0},{x:n-a/6,y:0},{x:n+2*a/6,y:-a},{x:a/6,y:-a}],i=A(r,n,a,s);return t.intersect=function(o){return T(t,s,o)},i}function pt(r,e,t){const n=e.width,a=e.height,s=[{x:2*a/6,y:0},{x:n+a/6,y:0},{x:n-2*a/6,y:-a},{x:-a/6,y:-a}],i=A(r,n,a,s);return t.intersect=function(o){return T(t,s,o)},i}function vt(r,e,t){const n=e.width,a=e.height,s=[{x:-2*a/6,y:0},{x:n+2*a/6,y:0},{x:n-a/6,y:-a},{x:a/6,y:-a}],i=A(r,n,a,s);return t.intersect=function(o){return T(t,s,o)},i}function gt(r,e,t){const n=e.width,a=e.height,s=[{x:a/6,y:0},{x:n-a/6,y:0},{x:n+2*a/6,y:-a},{x:-2*a/6,y:-a}],i=A(r,n,a,s);return t.intersect=function(o){return T(t,s,o)},i}function yt(r,e,t){const n=e.width,a=e.height,s=[{x:0,y:0},{x:n+a/2,y:0},{x:n,y:-a/2},{x:n+a/2,y:-a},{x:0,y:-a}],i=A(r,n,a,s);return t.intersect=function(o){return T(t,s,o)},i}function wt(r,e,t){const n=e.height,a=e.width+n/4,s=r.insert("rect",":first-child").attr("rx",n/2).attr("ry",n/2).attr("x",-a/2).attr("y",-n/2).attr("width",a).attr("height",n);return t.intersect=function(i){return Z(t,i)},s}function mt(r,e,t){const n=e.width,a=e.height,s=[{x:0,y:0},{x:n,y:0},{x:n,y:-a},{x:0,y:-a},{x:0,y:0},{x:-8,y:0},{x:n+8,y:0},{x:n+8,y:-a},{x:-8,y:-a},{x:-8,y:0}],i=A(r,n,a,s);return t.intersect=function(o){return T(t,s,o)},i}function xt(r,e,t){const n=e.width,a=n/2,s=a/(2.5+n/50),i=e.height+s,o="M 0,"+s+" a "+a+","+s+" 0,0,0 "+n+" 0 a "+a+","+s+" 0,0,0 "+-n+" 0 l 0,"+i+" a "+a+","+s+" 0,0,0 "+n+" 0 l 0,"+-i,c=r.attr("label-offset-y",s).insert("path",":first-child").attr("d",o).attr("transform","translate("+-n/2+","+-(i/2+s)+")");return t.intersect=function(d){const l=Z(t,d),v=l.x-t.x;if(a!=0&&(Math.abs(v)t.height/2-s)){let h=s*s*(1-v*v/(a*a));h!=0&&(h=Math.sqrt(h)),h=s-h,d.y-t.y>0&&(h=-h),l.y+=h}return l},c}function ge(r){r.shapes().question=dt,r.shapes().hexagon=ht,r.shapes().stadium=wt,r.shapes().subroutine=mt,r.shapes().cylinder=xt,r.shapes().rect_left_inv_arrow=ut,r.shapes().lean_right=ft,r.shapes().lean_left=pt,r.shapes().trapezoid=vt,r.shapes().inv_trapezoid=gt,r.shapes().rect_right_inv_arrow=yt}function ye(r){r({question:dt}),r({hexagon:ht}),r({stadium:wt}),r({subroutine:mt}),r({cylinder:xt}),r({rect_left_inv_arrow:ut}),r({lean_right:ft}),r({lean_left:pt}),r({trapezoid:vt}),r({inv_trapezoid:gt}),r({rect_right_inv_arrow:yt})}function A(r,e,t,n){return r.insert("polygon",":first-child").attr("points",n.map(function(a){return a.x+","+a.y}).join(" ")).attr("transform","translate("+-e/2+","+t/2+")")}const we={addToRender:ge,addToRenderV2:ye},bt={},me=function(r){const e=Object.keys(r);for(const t of e)bt[t]=r[t]},kt=async function(r,e,t,n,a,s){const i=n?n.select(`[id="${t}"]`):x(`[id="${t}"]`),o=a||document,c=Object.keys(r);for(const d of c){const l=r[d];let v="default";l.classes.length>0&&(v=l.classes.join(" "));const h=Y(l.styles);let u=l.text!==void 0?l.text:l.id,p;if(et(G().flowchart.htmlLabels)){const g={label:await rt(u.replace(/fa[blrs]?:fa-[\w-]+/g,k=>``),G())};p=nt(i,g).node(),p.parentNode.removeChild(p)}else{const g=o.createElementNS("http://www.w3.org/2000/svg","text");g.setAttribute("style",h.labelStyle.replace("color:","fill:"));const k=u.split(at.lineBreakRegex);for(const I of k){const _=o.createElementNS("http://www.w3.org/2000/svg","tspan");_.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),_.setAttribute("dy","1em"),_.setAttribute("x","1"),_.textContent=I,g.appendChild(_)}p=g}let y=0,f="";switch(l.type){case"round":y=5,f="rect";break;case"square":f="rect";break;case"diamond":f="question";break;case"hexagon":f="hexagon";break;case"odd":f="rect_left_inv_arrow";break;case"lean_right":f="lean_right";break;case"lean_left":f="lean_left";break;case"trapezoid":f="trapezoid";break;case"inv_trapezoid":f="inv_trapezoid";break;case"odd_right":f="rect_left_inv_arrow";break;case"circle":f="circle";break;case"ellipse":f="ellipse";break;case"stadium":f="stadium";break;case"subroutine":f="subroutine";break;case"cylinder":f="cylinder";break;case"group":f="rect";break;default:f="rect"}R.warn("Adding node",l.id,l.domId),e.setNode(s.db.lookUpDomId(l.id),{labelType:"svg",labelStyle:h.labelStyle,shape:f,label:p,rx:y,ry:y,class:v,style:h.style,id:s.db.lookUpDomId(l.id)})}},St=async function(r,e,t){let n=0,a,s;if(r.defaultStyle!==void 0){const i=Y(r.defaultStyle);a=i.style,s=i.labelStyle}for(const i of r){n++;const o="L-"+i.start+"-"+i.end,c="LS-"+i.start,d="LE-"+i.end,l={};i.type==="arrow_open"?l.arrowhead="none":l.arrowhead="normal";let v="",h="";if(i.style!==void 0){const u=Y(i.style);v=u.style,h=u.labelStyle}else switch(i.stroke){case"normal":v="fill:none",a!==void 0&&(v=a),s!==void 0&&(h=s);break;case"dotted":v="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":v=" stroke-width: 3.5px;fill:none";break}l.style=v,l.labelStyle=h,i.interpolate!==void 0?l.curve=z(i.interpolate,U):r.defaultInterpolate!==void 0?l.curve=z(r.defaultInterpolate,U):l.curve=z(bt.curve,U),i.text===void 0?i.style!==void 0&&(l.arrowheadStyle="fill: #333"):(l.arrowheadStyle="fill: #333",l.labelpos="c",et(G().flowchart.htmlLabels)?(l.labelType="html",l.label=`${await rt(i.text.replace(/fa[blrs]?:fa-[\w-]+/g,u=>``),G())}`):(l.labelType="text",l.label=i.text.replace(at.lineBreakRegex,`
                         `),i.style===void 0&&(l.style=l.style||"stroke: #333; stroke-width: 1.5px;fill:none"),l.labelStyle=l.labelStyle.replace("color:","fill:"))),l.id=o,l.class=c+" "+d,l.minlen=i.length||1,e.setEdge(t.db.lookUpDomId(i.start),t.db.lookUpDomId(i.end),l,n)}},xe=function(r,e){return R.info("Extracting classes"),e.db.getClasses()},be=async function(r,e,t,n){R.info("Drawing flowchart");const{securityLevel:a,flowchart:s}=G();let i;a==="sandbox"&&(i=x("#i"+e));const o=a==="sandbox"?x(i.nodes()[0].contentDocument.body):x("body"),c=a==="sandbox"?i.nodes()[0].contentDocument:document;let d=n.db.getDirection();d===void 0&&(d="TD");const l=s.nodeSpacing||50,v=s.rankSpacing||50,h=new _t({multigraph:!0,compound:!0}).setGraph({rankdir:d,nodesep:l,ranksep:v,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});let u;const p=n.db.getSubGraphs();for(let w=p.length-1;w>=0;w--)u=p[w],n.db.addVertex(u.id,u.title,"group",void 0,u.classes);const y=n.db.getVertices();R.warn("Get vertices",y);const f=n.db.getEdges();let g=0;for(g=p.length-1;g>=0;g--){u=p[g],Mt("cluster").append("text");for(let w=0;w{r.flowchart||(r.flowchart={}),r.flowchart.arrowMarkerAbsolute=r.arrowMarkerAbsolute,ke.setConf(r.flowchart),V.clear(),V.setGen("gen-1")}};export{Pe as diagram};
                        diff --git a/assets/flowDiagram-v2-3b53844e-Cs1ZpX_T.js b/assets/flowDiagram-v2-3b53844e-Cs1ZpX_T.js
                        new file mode 100644
                        index 0000000000..c9848d5278
                        --- /dev/null
                        +++ b/assets/flowDiagram-v2-3b53844e-Cs1ZpX_T.js
                        @@ -0,0 +1 @@
                        +import{p as e,f as o}from"./flowDb-4b19a42f-e0bq62ON.js";import{f as t,g as a}from"./styles-3ed67cfa-xu8Odik1.js";import{ar as i}from"./mermaid.core-Q3WVcjPF.js";import"./graph-yVkSecXb.js";import"./layout-2f_iGf4E.js";import"./index-fc10efb0-cfY4JypU.js";import"./clone-bRwIupqN.js";import"./edges-d32062c0-DdP-jtfh.js";import"./createText-6b48ae7d-yUX1YD6G.js";import"./line-3Gyevr9q.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";import"./channel-hMLbS6Zi.js";import"./app-UOvWaKji.js";const n={parser:e,db:o,renderer:t,styles:a,init:r=>{r.flowchart||(r.flowchart={}),r.flowchart.arrowMarkerAbsolute=r.arrowMarkerAbsolute,i({flowchart:{arrowMarkerAbsolute:r.arrowMarkerAbsolute}}),t.setConf(r.flowchart),o.clear(),o.setGen("gen-2")}};export{n as diagram};
                        diff --git a/assets/flowDiagram-v2-3b53844e-VJ0ZCiud.js b/assets/flowDiagram-v2-3b53844e-VJ0ZCiud.js
                        deleted file mode 100644
                        index ad2bde0b99..0000000000
                        --- a/assets/flowDiagram-v2-3b53844e-VJ0ZCiud.js
                        +++ /dev/null
                        @@ -1 +0,0 @@
                        -import{p as e,f as o}from"./flowDb-4b19a42f-sAhi6J2v.js";import{f as t,g as a}from"./styles-3ed67cfa-FBozeukd.js";import{ar as i}from"./mermaid.core-95b3ca__.js";import"./graph-cZfODKa1.js";import"./layout-konkdG3Z.js";import"./index-fc10efb0-knA-ZLJ0.js";import"./clone-jETecP85.js";import"./edges-d32062c0-iT1MEq_Y.js";import"./createText-6b48ae7d-9AoX5zU9.js";import"./line-_nnM_7ZX.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";import"./channel-GQnHP4O7.js";import"./app-PDrbPfzp.js";const n={parser:e,db:o,renderer:t,styles:a,init:r=>{r.flowchart||(r.flowchart={}),r.flowchart.arrowMarkerAbsolute=r.arrowMarkerAbsolute,i({flowchart:{arrowMarkerAbsolute:r.arrowMarkerAbsolute}}),t.setConf(r.flowchart),o.clear(),o.setGen("gen-2")}};export{n as diagram};
                        diff --git a/assets/flowchart-elk-definition-5fe447d6-2wwBOAT6.js b/assets/flowchart-elk-definition-5fe447d6-pCydUlJz.js
                        similarity index 99%
                        rename from assets/flowchart-elk-definition-5fe447d6-2wwBOAT6.js
                        rename to assets/flowchart-elk-definition-5fe447d6-pCydUlJz.js
                        index 771c6ac666..00ef1dcd3b 100644
                        --- a/assets/flowchart-elk-definition-5fe447d6-2wwBOAT6.js
                        +++ b/assets/flowchart-elk-definition-5fe447d6-pCydUlJz.js
                        @@ -1,4 +1,4 @@
                        -import{d as xNe,p as FNe}from"./flowDb-4b19a42f-sAhi6J2v.js";import{aC as Nse,aD as BNe,l as Ra,h as IO,b0 as $U,u as RNe,p as j0n,t as y0n,o as NU,j as KNe}from"./mermaid.core-95b3ca__.js";import{i as _Ne,a as HNe,l as qNe,b as UNe,k as GNe,m as zNe}from"./edges-d32062c0-iT1MEq_Y.js";import{l as XNe}from"./line-_nnM_7ZX.js";import"./app-PDrbPfzp.js";import"./createText-6b48ae7d-9AoX5zU9.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";function LU(ct){throw new Error('Could not dynamically require "'+ct+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var Bse={exports:{}};(function(ct,_t){(function(Xt){ct.exports=Xt()})(function(){return function(){function Xt(gt,Sr,Di){function y(Ht,Jt){if(!Sr[Ht]){if(!gt[Ht]){var Xe=typeof LU=="function"&&LU;if(!Jt&&Xe)return Xe(Ht,!0);if(Wt)return Wt(Ht,!0);var Yi=new Error("Cannot find module '"+Ht+"'");throw Yi.code="MODULE_NOT_FOUND",Yi}var Ri=Sr[Ht]={exports:{}};gt[Ht][0].call(Ri.exports,function(En){var hu=gt[Ht][1][En];return y(hu||En)},Ri,Ri.exports,Xt,gt,Sr,Di)}return Sr[Ht].exports}for(var Wt=typeof LU=="function"&&LU,Bu=0;Bu0&&arguments[0]!==void 0?arguments[0]:{},Yi=Xe.defaultLayoutOptions,Ri=Yi===void 0?{}:Yi,En=Xe.algorithms,hu=En===void 0?["layered","stress","mrtree","radial","force","disco","sporeOverlap","sporeCompaction","rectpacking"]:En,Qc=Xe.workerFactory,Ru=Xe.workerUrl;if(y(this,Ht),this.defaultLayoutOptions=Ri,this.initialized=!1,typeof Ru>"u"&&typeof Qc>"u")throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");var Pr=Qc;typeof Ru<"u"&&typeof Qc>"u"&&(Pr=function(N1){return new Worker(N1)});var Mf=Pr(Ru);if(typeof Mf.postMessage!="function")throw new TypeError("Created worker does not provide the required 'postMessage' function.");this.worker=new Bu(Mf),this.worker.postMessage({cmd:"register",algorithms:hu}).then(function(L1){return Jt.initialized=!0}).catch(console.err)}return Di(Ht,[{key:"layout",value:function(Xe){var Yi=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},Ri=Yi.layoutOptions,En=Ri===void 0?this.defaultLayoutOptions:Ri,hu=Yi.logging,Qc=hu===void 0?!1:hu,Ru=Yi.measureExecutionTime,Pr=Ru===void 0?!1:Ru;return Xe?this.worker.postMessage({cmd:"layout",graph:Xe,layoutOptions:En,options:{logging:Qc,measureExecutionTime:Pr}}):Promise.reject(new Error("Missing mandatory parameter 'graph'."))}},{key:"knownLayoutAlgorithms",value:function(){return this.worker.postMessage({cmd:"algorithms"})}},{key:"knownLayoutOptions",value:function(){return this.worker.postMessage({cmd:"options"})}},{key:"knownLayoutCategories",value:function(){return this.worker.postMessage({cmd:"categories"})}},{key:"terminateWorker",value:function(){this.worker.terminate()}}]),Ht}();Sr.default=Wt;var Bu=function(){function Ht(Jt){var Xe=this;if(y(this,Ht),Jt===void 0)throw new Error("Missing mandatory parameter 'worker'.");this.resolvers={},this.worker=Jt,this.worker.onmessage=function(Yi){setTimeout(function(){Xe.receive(Xe,Yi)},0)}}return Di(Ht,[{key:"postMessage",value:function(Xe){var Yi=this.id||0;this.id=Yi+1,Xe.id=Yi;var Ri=this;return new Promise(function(En,hu){Ri.resolvers[Yi]=function(Qc,Ru){Qc?(Ri.convertGwtStyleError(Qc),hu(Qc)):En(Ru)},Ri.worker.postMessage(Xe)})}},{key:"receive",value:function(Xe,Yi){var Ri=Yi.data,En=Xe.resolvers[Ri.id];En&&(delete Xe.resolvers[Ri.id],Ri.error?En(Ri.error):En(null,Ri.data))}},{key:"terminate",value:function(){this.worker.terminate&&this.worker.terminate()}},{key:"convertGwtStyleError",value:function(Xe){if(Xe){var Yi=Xe.__java$exception;Yi&&(Yi.cause&&Yi.cause.backingJsObject&&(Xe.cause=Yi.cause.backingJsObject,this.convertGwtStyleError(Xe.cause)),delete Xe.__java$exception)}}}]),Ht}()},{}],2:[function(Xt,gt,Sr){(function(Di){(function(){var y;typeof window<"u"?y=window:typeof Di<"u"?y=Di:typeof self<"u"&&(y=self);var Wt;function Bu(){}function Ht(){}function Jt(){}function Xe(){}function Yi(){}function Ri(){}function En(){}function hu(){}function Qc(){}function Ru(){}function Pr(){}function Mf(){}function L1(){}function N1(){}function og(){}function X3(){}function $1(){}function ul(){}function E0n(){}function C0n(){}function Q2(){}function F(){}function M0n(){}function pE(){}function T0n(){}function A0n(){}function S0n(){}function P0n(){}function I0n(){}function xU(){}function O0n(){}function D0n(){}function L0n(){}function OO(){}function N0n(){}function $0n(){}function x0n(){}function DO(){}function F0n(){}function B0n(){}function FU(){}function R0n(){}function K0n(){}function yu(){}function ju(){}function Y2(){}function Z2(){}function _0n(){}function H0n(){}function q0n(){}function U0n(){}function BU(){}function Eu(){}function np(){}function ep(){}function G0n(){}function z0n(){}function LO(){}function X0n(){}function V0n(){}function W0n(){}function J0n(){}function Q0n(){}function Y0n(){}function Z0n(){}function nbn(){}function ebn(){}function tbn(){}function ibn(){}function rbn(){}function cbn(){}function ubn(){}function obn(){}function sbn(){}function fbn(){}function hbn(){}function lbn(){}function abn(){}function dbn(){}function bbn(){}function wbn(){}function gbn(){}function pbn(){}function mbn(){}function vbn(){}function kbn(){}function ybn(){}function jbn(){}function Ebn(){}function Cbn(){}function Mbn(){}function RU(){}function Tbn(){}function Abn(){}function Sbn(){}function Pbn(){}function NO(){}function $O(){}function mE(){}function Ibn(){}function Obn(){}function xO(){}function Dbn(){}function Lbn(){}function Nbn(){}function vE(){}function $bn(){}function xbn(){}function Fbn(){}function Bbn(){}function Rbn(){}function Kbn(){}function _bn(){}function Hbn(){}function qbn(){}function KU(){}function Ubn(){}function Gbn(){}function _U(){}function zbn(){}function Xbn(){}function Vbn(){}function Wbn(){}function Jbn(){}function Qbn(){}function Ybn(){}function Zbn(){}function nwn(){}function ewn(){}function twn(){}function iwn(){}function rwn(){}function FO(){}function cwn(){}function uwn(){}function own(){}function swn(){}function fwn(){}function hwn(){}function lwn(){}function awn(){}function dwn(){}function HU(){}function qU(){}function bwn(){}function wwn(){}function gwn(){}function pwn(){}function mwn(){}function vwn(){}function kwn(){}function ywn(){}function jwn(){}function Ewn(){}function Cwn(){}function Mwn(){}function Twn(){}function Awn(){}function Swn(){}function Pwn(){}function Iwn(){}function Own(){}function Dwn(){}function Lwn(){}function Nwn(){}function $wn(){}function xwn(){}function Fwn(){}function Bwn(){}function Rwn(){}function Kwn(){}function _wn(){}function Hwn(){}function qwn(){}function Uwn(){}function Gwn(){}function zwn(){}function Xwn(){}function Vwn(){}function Wwn(){}function Jwn(){}function Qwn(){}function Ywn(){}function Zwn(){}function ngn(){}function egn(){}function tgn(){}function ign(){}function rgn(){}function cgn(){}function ugn(){}function ogn(){}function sgn(){}function fgn(){}function hgn(){}function lgn(){}function agn(){}function dgn(){}function bgn(){}function wgn(){}function ggn(){}function pgn(){}function mgn(){}function vgn(){}function kgn(){}function ygn(){}function jgn(){}function Egn(){}function Cgn(){}function Mgn(){}function Tgn(){}function Agn(){}function Sgn(){}function Pgn(){}function Ign(){}function Ogn(){}function Dgn(){}function Lgn(){}function Ngn(){}function $gn(){}function xgn(){}function Fgn(){}function Bgn(){}function Rgn(){}function Kgn(){}function _gn(){}function Hgn(){}function qgn(){}function Ugn(){}function Ggn(){}function zgn(){}function Xgn(){}function Vgn(){}function Wgn(){}function Jgn(){}function Qgn(){}function Ygn(){}function Zgn(){}function n2n(){}function e2n(){}function t2n(){}function i2n(){}function r2n(){}function c2n(){}function UU(){}function u2n(){}function o2n(){}function s2n(){}function f2n(){}function h2n(){}function l2n(){}function a2n(){}function d2n(){}function b2n(){}function w2n(){}function g2n(){}function p2n(){}function m2n(){}function v2n(){}function k2n(){}function y2n(){}function j2n(){}function E2n(){}function C2n(){}function M2n(){}function T2n(){}function A2n(){}function S2n(){}function P2n(){}function I2n(){}function O2n(){}function D2n(){}function L2n(){}function N2n(){}function $2n(){}function x2n(){}function F2n(){}function B2n(){}function R2n(){}function K2n(){}function _2n(){}function H2n(){}function q2n(){}function U2n(){}function G2n(){}function z2n(){}function X2n(){}function V2n(){}function W2n(){}function J2n(){}function Q2n(){}function Y2n(){}function Z2n(){}function npn(){}function epn(){}function tpn(){}function ipn(){}function rpn(){}function cpn(){}function upn(){}function opn(){}function spn(){}function fpn(){}function hpn(){}function lpn(){}function apn(){}function dpn(){}function bpn(){}function wpn(){}function gpn(){}function ppn(){}function mpn(){}function vpn(){}function kpn(){}function ypn(){}function jpn(){}function Epn(){}function Cpn(){}function GU(){}function Mpn(){}function Tpn(){}function Apn(){}function Spn(){}function Ppn(){}function Ipn(){}function Opn(){}function Dpn(){}function Lpn(){}function Npn(){}function zU(){}function $pn(){}function xpn(){}function Fpn(){}function Bpn(){}function Rpn(){}function Kpn(){}function XU(){}function VU(){}function _pn(){}function WU(){}function JU(){}function Hpn(){}function qpn(){}function Upn(){}function Gpn(){}function zpn(){}function Xpn(){}function Vpn(){}function Wpn(){}function Jpn(){}function Qpn(){}function Ypn(){}function QU(){}function Zpn(){}function n3n(){}function e3n(){}function t3n(){}function i3n(){}function r3n(){}function c3n(){}function u3n(){}function o3n(){}function s3n(){}function f3n(){}function h3n(){}function l3n(){}function a3n(){}function d3n(){}function b3n(){}function w3n(){}function g3n(){}function p3n(){}function m3n(){}function v3n(){}function k3n(){}function y3n(){}function j3n(){}function E3n(){}function C3n(){}function M3n(){}function T3n(){}function A3n(){}function S3n(){}function P3n(){}function I3n(){}function O3n(){}function D3n(){}function L3n(){}function N3n(){}function $3n(){}function x3n(){}function F3n(){}function B3n(){}function R3n(){}function K3n(){}function _3n(){}function H3n(){}function q3n(){}function U3n(){}function G3n(){}function z3n(){}function X3n(){}function V3n(){}function W3n(){}function J3n(){}function Q3n(){}function Y3n(){}function Z3n(){}function n4n(){}function e4n(){}function t4n(){}function i4n(){}function r4n(){}function c4n(){}function u4n(){}function o4n(){}function s4n(){}function f4n(){}function h4n(){}function l4n(){}function a4n(){}function d4n(){}function b4n(){}function w4n(){}function g4n(){}function p4n(){}function m4n(){}function v4n(){}function k4n(){}function y4n(){}function j4n(){}function E4n(){}function C4n(){}function M4n(){}function T4n(){}function A4n(){}function S4n(){}function P4n(){}function I4n(){}function _se(){}function O4n(){}function D4n(){}function L4n(){}function N4n(){}function $4n(){}function x4n(){}function F4n(){}function B4n(){}function R4n(){}function K4n(){}function _4n(){}function H4n(){}function q4n(){}function U4n(){}function G4n(){}function z4n(){}function X4n(){}function V4n(){}function W4n(){}function J4n(){}function Q4n(){}function Y4n(){}function Z4n(){}function nmn(){}function emn(){}function tmn(){}function imn(){}function BO(){}function RO(){}function rmn(){}function KO(){}function cmn(){}function umn(){}function omn(){}function smn(){}function fmn(){}function hmn(){}function lmn(){}function amn(){}function dmn(){}function bmn(){}function YU(){}function wmn(){}function gmn(){}function pmn(){}function Hse(){}function mmn(){}function vmn(){}function kmn(){}function ymn(){}function jmn(){}function Emn(){}function Cmn(){}function Ka(){}function Mmn(){}function tp(){}function ZU(){}function Tmn(){}function Amn(){}function Smn(){}function Pmn(){}function Imn(){}function Omn(){}function Dmn(){}function Lmn(){}function Nmn(){}function $mn(){}function xmn(){}function Fmn(){}function Bmn(){}function Rmn(){}function Kmn(){}function _mn(){}function Hmn(){}function qmn(){}function Umn(){}function hn(){}function Gmn(){}function zmn(){}function Xmn(){}function Vmn(){}function Wmn(){}function Jmn(){}function Qmn(){}function Ymn(){}function Zmn(){}function nvn(){}function evn(){}function tvn(){}function ivn(){}function _O(){}function rvn(){}function cvn(){}function uvn(){}function kE(){}function ovn(){}function HO(){}function yE(){}function svn(){}function nG(){}function fvn(){}function hvn(){}function lvn(){}function avn(){}function dvn(){}function bvn(){}function jE(){}function wvn(){}function gvn(){}function EE(){}function pvn(){}function CE(){}function mvn(){}function eG(){}function vvn(){}function qO(){}function tG(){}function kvn(){}function yvn(){}function jvn(){}function Evn(){}function qse(){}function Cvn(){}function Mvn(){}function Tvn(){}function Avn(){}function Svn(){}function Pvn(){}function Ivn(){}function Ovn(){}function Dvn(){}function Lvn(){}function V3(){}function UO(){}function Nvn(){}function $vn(){}function xvn(){}function Fvn(){}function Bvn(){}function Rvn(){}function Kvn(){}function _vn(){}function Hvn(){}function qvn(){}function Uvn(){}function Gvn(){}function zvn(){}function Xvn(){}function Vvn(){}function Wvn(){}function Jvn(){}function Qvn(){}function Yvn(){}function Zvn(){}function n6n(){}function e6n(){}function t6n(){}function i6n(){}function r6n(){}function c6n(){}function u6n(){}function o6n(){}function s6n(){}function f6n(){}function h6n(){}function l6n(){}function a6n(){}function d6n(){}function b6n(){}function w6n(){}function g6n(){}function p6n(){}function m6n(){}function v6n(){}function k6n(){}function y6n(){}function j6n(){}function E6n(){}function C6n(){}function M6n(){}function T6n(){}function A6n(){}function S6n(){}function P6n(){}function I6n(){}function O6n(){}function D6n(){}function L6n(){}function N6n(){}function $6n(){}function x6n(){}function F6n(){}function B6n(){}function R6n(){}function K6n(){}function _6n(){}function H6n(){}function q6n(){}function U6n(){}function G6n(){}function z6n(){}function X6n(){}function V6n(){}function W6n(){}function J6n(){}function Q6n(){}function Y6n(){}function Z6n(){}function n5n(){}function e5n(){}function t5n(){}function i5n(){}function r5n(){}function c5n(){}function u5n(){}function o5n(){}function s5n(){}function f5n(){}function h5n(){}function l5n(){}function a5n(){}function d5n(){}function b5n(){}function w5n(){}function g5n(){}function p5n(){}function m5n(){}function v5n(){}function k5n(){}function y5n(){}function j5n(){}function E5n(){}function C5n(){}function M5n(){}function T5n(){}function iG(){}function A5n(){}function S5n(){}function GO(){Qv()}function P5n(){r7()}function I5n(){aA()}function O5n(){Q$()}function D5n(){j5()}function L5n(){lnn()}function N5n(){Us()}function $5n(){yZ()}function x5n(){qk()}function F5n(){c7()}function B5n(){L7()}function R5n(){lCn()}function K5n(){Hp()}function _5n(){RLn()}function H5n(){kQ()}function q5n(){AOn()}function U5n(){yQ()}function G5n(){gNn()}function z5n(){TOn()}function X5n(){rm()}function V5n(){Z$n()}function W5n(){Y$n()}function J5n(){jDn()}function Q5n(){nxn()}function Y5n(){ua()}function Z5n(){YE()}function n8n(){ftn()}function e8n(){cn()}function t8n(){exn()}function i8n(){Sxn()}function r8n(){SOn()}function c8n(){ZRn()}function u8n(){POn()}function o8n(){bUn()}function s8n(){_nn()}function f8n(){kl()}function h8n(){bBn()}function l8n(){lc()}function a8n(){BOn()}function d8n(){_p()}function b8n(){Een()}function w8n(){oa()}function g8n(){Cen()}function p8n(){Rf()}function m8n(){Vk()}function v8n(){EF()}function k8n(){Dx()}function uf(){bSn()}function y8n(){YM()}function j8n(){mA()}function rG(){He()}function E8n(){NT()}function C8n(){QY()}function cG(){D$()}function uG(){KA()}function M8n(){$en()}function oG(n){Jn(n)}function T8n(n){this.a=n}function ME(n){this.a=n}function A8n(n){this.a=n}function S8n(n){this.a=n}function P8n(n){this.a=n}function I8n(n){this.a=n}function O8n(n){this.a=n}function D8n(n){this.a=n}function sG(n){this.a=n}function fG(n){this.a=n}function L8n(n){this.a=n}function N8n(n){this.a=n}function zO(n){this.a=n}function $8n(n){this.a=n}function x8n(n){this.a=n}function XO(n){this.a=n}function VO(n){this.a=n}function F8n(n){this.a=n}function WO(n){this.a=n}function B8n(n){this.a=n}function R8n(n){this.a=n}function K8n(n){this.a=n}function hG(n){this.b=n}function _8n(n){this.c=n}function H8n(n){this.a=n}function q8n(n){this.a=n}function U8n(n){this.a=n}function G8n(n){this.a=n}function z8n(n){this.a=n}function X8n(n){this.a=n}function V8n(n){this.a=n}function W8n(n){this.a=n}function J8n(n){this.a=n}function Q8n(n){this.a=n}function Y8n(n){this.a=n}function Z8n(n){this.a=n}function n9n(n){this.a=n}function lG(n){this.a=n}function aG(n){this.a=n}function TE(n){this.a=n}function q9(n){this.a=n}function _a(){this.a=[]}function e9n(n,e){n.a=e}function Use(n,e){n.a=e}function Gse(n,e){n.b=e}function zse(n,e){n.b=e}function Xse(n,e){n.b=e}function dG(n,e){n.j=e}function Vse(n,e){n.g=e}function Wse(n,e){n.i=e}function Jse(n,e){n.c=e}function Qse(n,e){n.c=e}function Yse(n,e){n.d=e}function Zse(n,e){n.d=e}function Ha(n,e){n.k=e}function nfe(n,e){n.c=e}function bG(n,e){n.c=e}function wG(n,e){n.a=e}function efe(n,e){n.a=e}function tfe(n,e){n.f=e}function ife(n,e){n.a=e}function rfe(n,e){n.b=e}function JO(n,e){n.d=e}function AE(n,e){n.i=e}function gG(n,e){n.o=e}function cfe(n,e){n.r=e}function ufe(n,e){n.a=e}function ofe(n,e){n.b=e}function t9n(n,e){n.e=e}function sfe(n,e){n.f=e}function pG(n,e){n.g=e}function ffe(n,e){n.e=e}function hfe(n,e){n.f=e}function lfe(n,e){n.f=e}function QO(n,e){n.a=e}function YO(n,e){n.b=e}function afe(n,e){n.n=e}function dfe(n,e){n.a=e}function bfe(n,e){n.c=e}function wfe(n,e){n.c=e}function gfe(n,e){n.c=e}function pfe(n,e){n.a=e}function mfe(n,e){n.a=e}function vfe(n,e){n.d=e}function kfe(n,e){n.d=e}function yfe(n,e){n.e=e}function jfe(n,e){n.e=e}function Efe(n,e){n.g=e}function Cfe(n,e){n.f=e}function Mfe(n,e){n.j=e}function Tfe(n,e){n.a=e}function Afe(n,e){n.a=e}function Sfe(n,e){n.b=e}function i9n(n){n.b=n.a}function r9n(n){n.c=n.d.d}function mG(n){this.a=n}function vG(n){this.a=n}function kG(n){this.a=n}function qa(n){this.a=n}function Ua(n){this.a=n}function U9(n){this.a=n}function c9n(n){this.a=n}function yG(n){this.a=n}function G9(n){this.a=n}function SE(n){this.a=n}function ol(n){this.a=n}function Tb(n){this.a=n}function u9n(n){this.a=n}function o9n(n){this.a=n}function ZO(n){this.b=n}function W3(n){this.b=n}function J3(n){this.b=n}function nD(n){this.a=n}function s9n(n){this.a=n}function eD(n){this.c=n}function C(n){this.c=n}function f9n(n){this.c=n}function Gv(n){this.d=n}function jG(n){this.a=n}function Te(n){this.a=n}function h9n(n){this.a=n}function EG(n){this.a=n}function CG(n){this.a=n}function MG(n){this.a=n}function TG(n){this.a=n}function AG(n){this.a=n}function SG(n){this.a=n}function Q3(n){this.a=n}function l9n(n){this.a=n}function a9n(n){this.a=n}function Y3(n){this.a=n}function d9n(n){this.a=n}function b9n(n){this.a=n}function w9n(n){this.a=n}function g9n(n){this.a=n}function p9n(n){this.a=n}function m9n(n){this.a=n}function v9n(n){this.a=n}function k9n(n){this.a=n}function y9n(n){this.a=n}function j9n(n){this.a=n}function E9n(n){this.a=n}function C9n(n){this.a=n}function M9n(n){this.a=n}function T9n(n){this.a=n}function A9n(n){this.a=n}function z9(n){this.a=n}function S9n(n){this.a=n}function P9n(n){this.a=n}function I9n(n){this.a=n}function O9n(n){this.a=n}function PE(n){this.a=n}function D9n(n){this.a=n}function L9n(n){this.a=n}function Z3(n){this.a=n}function PG(n){this.a=n}function N9n(n){this.a=n}function $9n(n){this.a=n}function x9n(n){this.a=n}function F9n(n){this.a=n}function B9n(n){this.a=n}function R9n(n){this.a=n}function IG(n){this.a=n}function OG(n){this.a=n}function DG(n){this.a=n}function zv(n){this.a=n}function IE(n){this.e=n}function n4(n){this.a=n}function K9n(n){this.a=n}function ip(n){this.a=n}function LG(n){this.a=n}function _9n(n){this.a=n}function H9n(n){this.a=n}function q9n(n){this.a=n}function U9n(n){this.a=n}function G9n(n){this.a=n}function z9n(n){this.a=n}function X9n(n){this.a=n}function V9n(n){this.a=n}function W9n(n){this.a=n}function J9n(n){this.a=n}function Q9n(n){this.a=n}function NG(n){this.a=n}function Y9n(n){this.a=n}function Z9n(n){this.a=n}function n7n(n){this.a=n}function e7n(n){this.a=n}function t7n(n){this.a=n}function i7n(n){this.a=n}function r7n(n){this.a=n}function c7n(n){this.a=n}function u7n(n){this.a=n}function o7n(n){this.a=n}function s7n(n){this.a=n}function f7n(n){this.a=n}function h7n(n){this.a=n}function l7n(n){this.a=n}function a7n(n){this.a=n}function d7n(n){this.a=n}function b7n(n){this.a=n}function w7n(n){this.a=n}function g7n(n){this.a=n}function p7n(n){this.a=n}function m7n(n){this.a=n}function v7n(n){this.a=n}function k7n(n){this.a=n}function y7n(n){this.a=n}function j7n(n){this.a=n}function E7n(n){this.a=n}function C7n(n){this.a=n}function M7n(n){this.a=n}function T7n(n){this.a=n}function A7n(n){this.a=n}function S7n(n){this.a=n}function P7n(n){this.a=n}function I7n(n){this.a=n}function O7n(n){this.a=n}function D7n(n){this.a=n}function L7n(n){this.a=n}function N7n(n){this.a=n}function $7n(n){this.a=n}function x7n(n){this.c=n}function F7n(n){this.b=n}function B7n(n){this.a=n}function R7n(n){this.a=n}function K7n(n){this.a=n}function _7n(n){this.a=n}function H7n(n){this.a=n}function q7n(n){this.a=n}function U7n(n){this.a=n}function G7n(n){this.a=n}function z7n(n){this.a=n}function X7n(n){this.a=n}function V7n(n){this.a=n}function W7n(n){this.a=n}function J7n(n){this.a=n}function Q7n(n){this.a=n}function Y7n(n){this.a=n}function Z7n(n){this.a=n}function nkn(n){this.a=n}function ekn(n){this.a=n}function tkn(n){this.a=n}function ikn(n){this.a=n}function rkn(n){this.a=n}function ckn(n){this.a=n}function ukn(n){this.a=n}function okn(n){this.a=n}function skn(n){this.a=n}function fkn(n){this.a=n}function hkn(n){this.a=n}function sl(n){this.a=n}function sg(n){this.a=n}function lkn(n){this.a=n}function akn(n){this.a=n}function dkn(n){this.a=n}function bkn(n){this.a=n}function wkn(n){this.a=n}function gkn(n){this.a=n}function pkn(n){this.a=n}function mkn(n){this.a=n}function vkn(n){this.a=n}function kkn(n){this.a=n}function ykn(n){this.a=n}function jkn(n){this.a=n}function Ekn(n){this.a=n}function Ckn(n){this.a=n}function Mkn(n){this.a=n}function Tkn(n){this.a=n}function Akn(n){this.a=n}function Skn(n){this.a=n}function Pkn(n){this.a=n}function Ikn(n){this.a=n}function Okn(n){this.a=n}function Dkn(n){this.a=n}function Lkn(n){this.a=n}function Nkn(n){this.a=n}function $kn(n){this.a=n}function xkn(n){this.a=n}function OE(n){this.a=n}function Fkn(n){this.f=n}function Bkn(n){this.a=n}function Rkn(n){this.a=n}function Kkn(n){this.a=n}function _kn(n){this.a=n}function Hkn(n){this.a=n}function qkn(n){this.a=n}function Ukn(n){this.a=n}function Gkn(n){this.a=n}function zkn(n){this.a=n}function Xkn(n){this.a=n}function Vkn(n){this.a=n}function Wkn(n){this.a=n}function Jkn(n){this.a=n}function Qkn(n){this.a=n}function Ykn(n){this.a=n}function Zkn(n){this.a=n}function nyn(n){this.a=n}function eyn(n){this.a=n}function tyn(n){this.a=n}function iyn(n){this.a=n}function ryn(n){this.a=n}function cyn(n){this.a=n}function uyn(n){this.a=n}function oyn(n){this.a=n}function syn(n){this.a=n}function fyn(n){this.a=n}function hyn(n){this.a=n}function lyn(n){this.a=n}function tD(n){this.a=n}function $G(n){this.a=n}function lt(n){this.b=n}function ayn(n){this.a=n}function dyn(n){this.a=n}function byn(n){this.a=n}function wyn(n){this.a=n}function gyn(n){this.a=n}function pyn(n){this.a=n}function myn(n){this.a=n}function vyn(n){this.b=n}function kyn(n){this.a=n}function X9(n){this.a=n}function yyn(n){this.a=n}function jyn(n){this.a=n}function xG(n){this.c=n}function DE(n){this.e=n}function LE(n){this.a=n}function NE(n){this.a=n}function iD(n){this.a=n}function Eyn(n){this.d=n}function Cyn(n){this.a=n}function FG(n){this.a=n}function BG(n){this.a=n}function Wd(n){this.e=n}function Pfe(){this.a=0}function de(){Hu(this)}function Z(){pL(this)}function rD(){oIn(this)}function Myn(){}function Jd(){this.c=Udn}function Tyn(n,e){n.b+=e}function Ife(n,e){e.Wb(n)}function Ofe(n){return n.a}function Dfe(n){return n.a}function Lfe(n){return n.a}function Nfe(n){return n.a}function $fe(n){return n.a}function M(n){return n.e}function xfe(){return null}function Ffe(){return null}function Bfe(){Ez(),pLe()}function Rfe(n){n.b.Of(n.e)}function Ayn(n){n.b=new CD}function Xv(n,e){n.b=e-n.b}function Vv(n,e){n.a=e-n.a}function Rn(n,e){n.push(e)}function Syn(n,e){n.sort(e)}function Pyn(n,e){e.jd(n.a)}function Kfe(n,e){gi(e,n)}function _fe(n,e,t){n.Yd(t,e)}function V9(n,e){n.e=e,e.b=n}function RG(n){oh(),this.a=n}function Iyn(n){oh(),this.a=n}function Oyn(n){oh(),this.a=n}function cD(n){g0(),this.a=n}function Dyn(n){I4(),VK.le(n)}function KG(){KG=F,new de}function Ga(){QTn.call(this)}function _G(){QTn.call(this)}function HG(){Ga.call(this)}function uD(){Ga.call(this)}function Lyn(){Ga.call(this)}function W9(){Ga.call(this)}function Cu(){Ga.call(this)}function rp(){Ga.call(this)}function Pe(){Ga.call(this)}function Bo(){Ga.call(this)}function Nyn(){Ga.call(this)}function nc(){Ga.call(this)}function $yn(){Ga.call(this)}function xyn(){this.a=this}function $E(){this.Bb|=256}function Fyn(){this.b=new UMn}function Ab(n,e){n.length=e}function xE(n,e){nn(n.a,e)}function Hfe(n,e){dnn(n.c,e)}function qfe(n,e){fi(n.b,e)}function Ufe(n,e){uA(n.a,e)}function Gfe(n,e){cx(n.a,e)}function e4(n,e){it(n.e,e)}function cp(n){jA(n.c,n.b)}function zfe(n,e){n.kc().Nb(e)}function qG(n){this.a=B5e(n)}function ni(){this.a=new de}function Byn(){this.a=new de}function UG(){this.a=new iCn}function FE(){this.a=new Z}function oD(){this.a=new Z}function GG(){this.a=new Z}function hs(){this.a=new rbn}function za(){this.a=new LLn}function zG(){this.a=new KU}function XG(){this.a=new MOn}function VG(){this.a=new FAn}function Ryn(){this.a=new Z}function Kyn(){this.a=new Z}function _yn(){this.a=new Z}function WG(){this.a=new Z}function Hyn(){this.d=new Z}function qyn(){this.a=new GOn}function Uyn(){this.a=new ni}function Gyn(){this.a=new de}function zyn(){this.b=new de}function Xyn(){this.b=new Z}function JG(){this.e=new Z}function Vyn(){this.a=new Y5n}function Wyn(){this.d=new Z}function Jyn(){JIn.call(this)}function Qyn(){JIn.call(this)}function Yyn(){Z.call(this)}function QG(){HG.call(this)}function YG(){FE.call(this)}function Zyn(){HC.call(this)}function njn(){WG.call(this)}function Wv(){Myn.call(this)}function sD(){Wv.call(this)}function up(){Myn.call(this)}function ZG(){up.call(this)}function ejn(){iz.call(this)}function tjn(){iz.call(this)}function ijn(){iz.call(this)}function rjn(){rz.call(this)}function Jv(){ovn.call(this)}function nz(){ovn.call(this)}function Mu(){Ct.call(this)}function cjn(){kjn.call(this)}function ujn(){kjn.call(this)}function ojn(){de.call(this)}function sjn(){de.call(this)}function fjn(){de.call(this)}function fD(){rxn.call(this)}function hjn(){ni.call(this)}function ljn(){$E.call(this)}function hD(){FX.call(this)}function ez(){de.call(this)}function lD(){FX.call(this)}function aD(){de.call(this)}function ajn(){de.call(this)}function tz(){CE.call(this)}function djn(){tz.call(this)}function bjn(){CE.call(this)}function wjn(){iG.call(this)}function iz(){this.a=new ni}function gjn(){this.a=new de}function pjn(){this.a=new Z}function rz(){this.a=new de}function op(){this.a=new Ct}function mjn(){this.j=new Z}function vjn(){this.a=new pEn}function kjn(){this.a=new pvn}function cz(){this.a=new Y4n}function Qv(){Qv=F,KK=new Ht}function dD(){dD=F,_K=new jjn}function bD(){bD=F,HK=new yjn}function yjn(){XO.call(this,"")}function jjn(){XO.call(this,"")}function Ejn(n){A$n.call(this,n)}function Cjn(n){A$n.call(this,n)}function uz(n){sG.call(this,n)}function oz(n){zEn.call(this,n)}function Xfe(n){zEn.call(this,n)}function Vfe(n){oz.call(this,n)}function Wfe(n){oz.call(this,n)}function Jfe(n){oz.call(this,n)}function Mjn(n){zN.call(this,n)}function Tjn(n){zN.call(this,n)}function Ajn(n){cSn.call(this,n)}function Sjn(n){Iz.call(this,n)}function Yv(n){VE.call(this,n)}function sz(n){VE.call(this,n)}function Pjn(n){VE.call(this,n)}function fz(n){mje.call(this,n)}function hz(n){fz.call(this,n)}function ec(n){TPn.call(this,n)}function Ijn(n){ec.call(this,n)}function sp(){q9.call(this,{})}function Ojn(){Ojn=F,dQn=new C0n}function BE(){BE=F,GK=new ATn}function Djn(){Djn=F,cun=new Bu}function lz(){lz=F,uun=new N1}function RE(){RE=F,C8=new $1}function wD(n){d4(),this.a=n}function gD(n){BQ(),this.a=n}function Sb(n){nN(),this.f=n}function pD(n){nN(),this.f=n}function Ljn(n){dSn(),this.a=n}function Njn(n){n.b=null,n.c=0}function Qfe(n,e){n.e=e,bqn(n,e)}function Yfe(n,e){n.a=e,cEe(n)}function mD(n,e,t){n.a[e.g]=t}function Zfe(n,e,t){kke(t,n,e)}function nhe(n,e){Wae(e.i,n.n)}function $jn(n,e){v6e(n).Cd(e)}function ehe(n,e){n.a.ec().Mc(e)}function xjn(n,e){return n.g-e.g}function the(n,e){return n*n/e}function on(n){return Jn(n),n}function $(n){return Jn(n),n}function J9(n){return Jn(n),n}function ihe(n){return new TE(n)}function rhe(n){return new qb(n)}function az(n){return Jn(n),n}function che(n){return Jn(n),n}function KE(n){ec.call(this,n)}function Ir(n){ec.call(this,n)}function Fjn(n){ec.call(this,n)}function vD(n){TPn.call(this,n)}function t4(n){ec.call(this,n)}function Gn(n){ec.call(this,n)}function Or(n){ec.call(this,n)}function Bjn(n){ec.call(this,n)}function fp(n){ec.call(this,n)}function Kl(n){ec.call(this,n)}function _l(n){ec.call(this,n)}function hp(n){ec.call(this,n)}function eh(n){ec.call(this,n)}function kD(n){ec.call(this,n)}function Le(n){ec.call(this,n)}function Ku(n){Jn(n),this.a=n}function dz(n){return ld(n),n}function Zv(n){MW(n,n.length)}function n6(n){return n.b==n.c}function Pb(n){return!!n&&n.b}function uhe(n){return!!n&&n.k}function ohe(n){return!!n&&n.j}function she(n,e,t){n.c.Ef(e,t)}function Rjn(n,e){n.be(e),e.ae(n)}function lp(n){oh(),this.a=Se(n)}function yD(){this.a=Oe(Se(ur))}function Kjn(){throw M(new Pe)}function fhe(){throw M(new Pe)}function bz(){throw M(new Pe)}function _jn(){throw M(new Pe)}function hhe(){throw M(new Pe)}function lhe(){throw M(new Pe)}function _E(){_E=F,I4()}function Hl(){U9.call(this,"")}function e6(){U9.call(this,"")}function x1(){U9.call(this,"")}function fg(){U9.call(this,"")}function wz(n){Ir.call(this,n)}function gz(n){Ir.call(this,n)}function th(n){Gn.call(this,n)}function i4(n){J3.call(this,n)}function Hjn(n){i4.call(this,n)}function jD(n){FC.call(this,n)}function ED(n){WX.call(this,n,0)}function CD(){oJ.call(this,12,3)}function T(n,e){return vOn(n,e)}function HE(n,e){return o$(n,e)}function ahe(n,e){return n.a-e.a}function dhe(n,e){return n.a-e.a}function bhe(n,e){return n.a-e.a}function whe(n,e){return e in n.a}function qjn(n){return n.a?n.b:0}function ghe(n){return n.a?n.b:0}function phe(n,e,t){e.Cd(n.a[t])}function mhe(n,e,t){e.Pe(n.a[t])}function vhe(n,e){n.b=new rr(e)}function khe(n,e){return n.b=e,n}function Ujn(n,e){return n.c=e,n}function Gjn(n,e){return n.f=e,n}function yhe(n,e){return n.g=e,n}function pz(n,e){return n.a=e,n}function mz(n,e){return n.f=e,n}function jhe(n,e){return n.k=e,n}function vz(n,e){return n.a=e,n}function Ehe(n,e){return n.e=e,n}function kz(n,e){return n.e=e,n}function Che(n,e){return n.f=e,n}function Mhe(n,e){n.b=!0,n.d=e}function The(n,e){return n.b-e.b}function Ahe(n,e){return n.g-e.g}function She(n,e){return n?0:e-1}function zjn(n,e){return n?0:e-1}function Phe(n,e){return n?e-1:0}function Ihe(n,e){return n.s-e.s}function Ohe(n,e){return e.rg(n)}function Qd(n,e){return n.b=e,n}function qE(n,e){return n.a=e,n}function Yd(n,e){return n.c=e,n}function Zd(n,e){return n.d=e,n}function n0(n,e){return n.e=e,n}function yz(n,e){return n.f=e,n}function t6(n,e){return n.a=e,n}function r4(n,e){return n.b=e,n}function c4(n,e){return n.c=e,n}function an(n,e){return n.c=e,n}function Sn(n,e){return n.b=e,n}function dn(n,e){return n.d=e,n}function bn(n,e){return n.e=e,n}function Dhe(n,e){return n.f=e,n}function wn(n,e){return n.g=e,n}function gn(n,e){return n.a=e,n}function pn(n,e){return n.i=e,n}function mn(n,e){return n.j=e,n}function Lhe(n,e){ua(),ic(e,n)}function Nhe(n,e,t){Jbe(n.a,e,t)}function UE(n){$L.call(this,n)}function Xjn(n){Z5e.call(this,n)}function Vjn(n){AIn.call(this,n)}function jz(n){AIn.call(this,n)}function F1(n){T0.call(this,n)}function Wjn(n){CN.call(this,n)}function Jjn(n){CN.call(this,n)}function Qjn(){OX.call(this,"")}function Li(){this.a=0,this.b=0}function Yjn(){this.b=0,this.a=0}function Zjn(n,e){n.b=0,Zb(n,e)}function nEn(n,e){return n.k=e,n}function $he(n,e){return n.j=e,n}function xhe(n,e){n.c=e,n.b=!0}function eEn(){eEn=F,TQn=Xke()}function B1(){B1=F,voe=rke()}function tEn(){tEn=F,Ti=gye()}function Ez(){Ez=F,Da=G4()}function u4(){u4=F,qdn=cke()}function iEn(){iEn=F,ise=uke()}function Cz(){Cz=F,yc=tEe()}function of(n){return n.e&&n.e()}function rEn(n){return n.l|n.m<<22}function cEn(n,e){return n.c._b(e)}function uEn(n,e){return iBn(n.b,e)}function MD(n){return n?n.d:null}function Fhe(n){return n?n.g:null}function Bhe(n){return n?n.i:null}function Xa(n){return ll(n),n.o}function hg(n,e){return n.a+=e,n}function TD(n,e){return n.a+=e,n}function ql(n,e){return n.a+=e,n}function e0(n,e){return n.a+=e,n}function Mz(n,e){for(;n.Bd(e););}function GE(n){this.a=new ap(n)}function oEn(){throw M(new Pe)}function sEn(){throw M(new Pe)}function fEn(){throw M(new Pe)}function hEn(){throw M(new Pe)}function lEn(){throw M(new Pe)}function aEn(){throw M(new Pe)}function Ul(n){this.a=new iN(n)}function dEn(){this.a=new $5(Fln)}function bEn(){this.b=new $5(tln)}function wEn(){this.a=new $5(o1n)}function gEn(){this.b=new $5(xq)}function pEn(){this.b=new $5(xq)}function zE(n){this.a=0,this.b=n}function Tz(n){zGn(),ILe(this,n)}function o4(n){return X1(n),n.a}function Q9(n){return n.b!=n.d.c}function Az(n,e){return n.d[e.p]}function mEn(n,e){return XTe(n,e)}function Sz(n,e,t){n.splice(e,t)}function lg(n,e){for(;n.Re(e););}function vEn(n){n.c?Dqn(n):Lqn(n)}function kEn(){throw M(new Pe)}function yEn(){throw M(new Pe)}function jEn(){throw M(new Pe)}function EEn(){throw M(new Pe)}function CEn(){throw M(new Pe)}function MEn(){throw M(new Pe)}function TEn(){throw M(new Pe)}function AEn(){throw M(new Pe)}function SEn(){throw M(new Pe)}function PEn(){throw M(new Pe)}function Rhe(){throw M(new nc)}function Khe(){throw M(new nc)}function Y9(n){this.a=new IEn(n)}function IEn(n){Ume(this,n,jje())}function Z9(n){return!n||uIn(n)}function n7(n){return nh[n]!=-1}function _he(){cP!=0&&(cP=0),uP=-1}function OEn(){RK==null&&(RK=[])}function e7(n,e){Mg.call(this,n,e)}function s4(n,e){e7.call(this,n,e)}function DEn(n,e){this.a=n,this.b=e}function LEn(n,e){this.a=n,this.b=e}function NEn(n,e){this.a=n,this.b=e}function $En(n,e){this.a=n,this.b=e}function xEn(n,e){this.a=n,this.b=e}function FEn(n,e){this.a=n,this.b=e}function BEn(n,e){this.a=n,this.b=e}function f4(n,e){this.e=n,this.d=e}function Pz(n,e){this.b=n,this.c=e}function REn(n,e){this.b=n,this.a=e}function KEn(n,e){this.b=n,this.a=e}function _En(n,e){this.b=n,this.a=e}function HEn(n,e){this.b=n,this.a=e}function qEn(n,e){this.a=n,this.b=e}function AD(n,e){this.a=n,this.b=e}function UEn(n,e){this.a=n,this.f=e}function t0(n,e){this.g=n,this.i=e}function je(n,e){this.f=n,this.g=e}function GEn(n,e){this.b=n,this.c=e}function zEn(n){RX(n.dc()),this.c=n}function Hhe(n,e){this.a=n,this.b=e}function XEn(n,e){this.a=n,this.b=e}function VEn(n){this.a=u(Se(n),15)}function Iz(n){this.a=u(Se(n),15)}function WEn(n){this.a=u(Se(n),85)}function XE(n){this.b=u(Se(n),85)}function VE(n){this.b=u(Se(n),51)}function WE(){this.q=new y.Date}function SD(n,e){this.a=n,this.b=e}function JEn(n,e){return Zc(n.b,e)}function t7(n,e){return n.b.Hc(e)}function QEn(n,e){return n.b.Ic(e)}function YEn(n,e){return n.b.Qc(e)}function ZEn(n,e){return n.b.Hc(e)}function nCn(n,e){return n.c.uc(e)}function eCn(n,e){return rt(n.c,e)}function sf(n,e){return n.a._b(e)}function tCn(n,e){return n>e&&e0}function ND(n,e){return Ec(n,e)<0}function mCn(n,e){return JL(n.a,e)}function ole(n,e){kOn.call(this,n,e)}function Fz(n){wN(),cSn.call(this,n)}function Bz(n,e){dPn(n,n.length,e)}function u7(n,e){_Pn(n,n.length,e)}function h6(n,e){return n.a.get(e)}function vCn(n,e){return Zc(n.e,e)}function Rz(n){return Jn(n),!1}function Kz(n){this.a=u(Se(n),229)}function rC(n){In.call(this,n,21)}function cC(n,e){je.call(this,n,e)}function $D(n,e){je.call(this,n,e)}function kCn(n,e){this.b=n,this.a=e}function uC(n,e){this.d=n,this.e=e}function yCn(n,e){this.a=n,this.b=e}function jCn(n,e){this.a=n,this.b=e}function ECn(n,e){this.a=n,this.b=e}function CCn(n,e){this.a=n,this.b=e}function bp(n,e){this.a=n,this.b=e}function MCn(n,e){this.b=n,this.a=e}function _z(n,e){this.b=n,this.a=e}function Hz(n,e){je.call(this,n,e)}function qz(n,e){je.call(this,n,e)}function ag(n,e){je.call(this,n,e)}function xD(n,e){je.call(this,n,e)}function FD(n,e){je.call(this,n,e)}function BD(n,e){je.call(this,n,e)}function oC(n,e){je.call(this,n,e)}function Uz(n,e){this.b=n,this.a=e}function sC(n,e){je.call(this,n,e)}function Gz(n,e){this.b=n,this.a=e}function fC(n,e){je.call(this,n,e)}function TCn(n,e){this.b=n,this.a=e}function zz(n,e){je.call(this,n,e)}function RD(n,e){je.call(this,n,e)}function o7(n,e){je.call(this,n,e)}function l6(n,e,t){n.splice(e,0,t)}function sle(n,e,t){n.Mb(t)&&e.Cd(t)}function fle(n,e,t){e.Pe(n.a.Ye(t))}function hle(n,e,t){e.Dd(n.a.Ze(t))}function lle(n,e,t){e.Cd(n.a.Kb(t))}function ale(n,e){return Au(n.c,e)}function dle(n,e){return Au(n.e,e)}function hC(n,e){je.call(this,n,e)}function lC(n,e){je.call(this,n,e)}function a6(n,e){je.call(this,n,e)}function Xz(n,e){je.call(this,n,e)}function ei(n,e){je.call(this,n,e)}function aC(n,e){je.call(this,n,e)}function ACn(n,e){this.a=n,this.b=e}function SCn(n,e){this.a=n,this.b=e}function PCn(n,e){this.a=n,this.b=e}function ICn(n,e){this.a=n,this.b=e}function OCn(n,e){this.a=n,this.b=e}function DCn(n,e){this.a=n,this.b=e}function LCn(n,e){this.b=n,this.a=e}function NCn(n,e){this.b=n,this.a=e}function Vz(n,e){this.b=n,this.a=e}function a4(n,e){this.c=n,this.d=e}function $Cn(n,e){this.e=n,this.d=e}function xCn(n,e){this.a=n,this.b=e}function FCn(n,e){this.a=n,this.b=e}function BCn(n,e){this.a=n,this.b=e}function RCn(n,e){this.b=n,this.a=e}function KCn(n,e){this.b=e,this.c=n}function dC(n,e){je.call(this,n,e)}function s7(n,e){je.call(this,n,e)}function KD(n,e){je.call(this,n,e)}function Wz(n,e){je.call(this,n,e)}function d6(n,e){je.call(this,n,e)}function _D(n,e){je.call(this,n,e)}function HD(n,e){je.call(this,n,e)}function f7(n,e){je.call(this,n,e)}function Jz(n,e){je.call(this,n,e)}function qD(n,e){je.call(this,n,e)}function b6(n,e){je.call(this,n,e)}function Qz(n,e){je.call(this,n,e)}function w6(n,e){je.call(this,n,e)}function g6(n,e){je.call(this,n,e)}function Db(n,e){je.call(this,n,e)}function UD(n,e){je.call(this,n,e)}function GD(n,e){je.call(this,n,e)}function Yz(n,e){je.call(this,n,e)}function h7(n,e){je.call(this,n,e)}function dg(n,e){je.call(this,n,e)}function zD(n,e){je.call(this,n,e)}function bC(n,e){je.call(this,n,e)}function l7(n,e){je.call(this,n,e)}function Lb(n,e){je.call(this,n,e)}function wC(n,e){je.call(this,n,e)}function Zz(n,e){je.call(this,n,e)}function XD(n,e){je.call(this,n,e)}function VD(n,e){je.call(this,n,e)}function WD(n,e){je.call(this,n,e)}function JD(n,e){je.call(this,n,e)}function QD(n,e){je.call(this,n,e)}function YD(n,e){je.call(this,n,e)}function ZD(n,e){je.call(this,n,e)}function _Cn(n,e){this.b=n,this.a=e}function nX(n,e){je.call(this,n,e)}function HCn(n,e){this.a=n,this.b=e}function qCn(n,e){this.a=n,this.b=e}function UCn(n,e){this.a=n,this.b=e}function eX(n,e){je.call(this,n,e)}function tX(n,e){je.call(this,n,e)}function GCn(n,e){this.a=n,this.b=e}function ble(n,e){return v4(),e!=n}function a7(n){return oe(n.a),n.b}function nL(n){return yCe(n,n.c),n}function zCn(){return eEn(),new TQn}function XCn(){XC(),this.a=new vV}function VCn(){OA(),this.a=new ni}function WCn(){NN(),this.b=new ni}function JCn(n,e){this.b=n,this.d=e}function QCn(n,e){this.a=n,this.b=e}function YCn(n,e){this.a=n,this.b=e}function ZCn(n,e){this.a=n,this.b=e}function nMn(n,e){this.b=n,this.a=e}function iX(n,e){je.call(this,n,e)}function rX(n,e){je.call(this,n,e)}function gC(n,e){je.call(this,n,e)}function r0(n,e){je.call(this,n,e)}function eL(n,e){je.call(this,n,e)}function pC(n,e){je.call(this,n,e)}function cX(n,e){je.call(this,n,e)}function uX(n,e){je.call(this,n,e)}function d7(n,e){je.call(this,n,e)}function oX(n,e){je.call(this,n,e)}function tL(n,e){je.call(this,n,e)}function mC(n,e){je.call(this,n,e)}function iL(n,e){je.call(this,n,e)}function rL(n,e){je.call(this,n,e)}function cL(n,e){je.call(this,n,e)}function uL(n,e){je.call(this,n,e)}function sX(n,e){je.call(this,n,e)}function oL(n,e){je.call(this,n,e)}function fX(n,e){je.call(this,n,e)}function b7(n,e){je.call(this,n,e)}function sL(n,e){je.call(this,n,e)}function hX(n,e){je.call(this,n,e)}function w7(n,e){je.call(this,n,e)}function lX(n,e){je.call(this,n,e)}function eMn(n,e){this.b=n,this.a=e}function tMn(n,e){this.b=n,this.a=e}function iMn(n,e){this.b=n,this.a=e}function rMn(n,e){this.b=n,this.a=e}function aX(n,e){this.a=n,this.b=e}function cMn(n,e){this.a=n,this.b=e}function uMn(n,e){this.a=n,this.b=e}function V(n,e){this.a=n,this.b=e}function p6(n,e){je.call(this,n,e)}function g7(n,e){je.call(this,n,e)}function wp(n,e){je.call(this,n,e)}function m6(n,e){je.call(this,n,e)}function p7(n,e){je.call(this,n,e)}function fL(n,e){je.call(this,n,e)}function vC(n,e){je.call(this,n,e)}function v6(n,e){je.call(this,n,e)}function hL(n,e){je.call(this,n,e)}function kC(n,e){je.call(this,n,e)}function bg(n,e){je.call(this,n,e)}function m7(n,e){je.call(this,n,e)}function k6(n,e){je.call(this,n,e)}function y6(n,e){je.call(this,n,e)}function v7(n,e){je.call(this,n,e)}function yC(n,e){je.call(this,n,e)}function wg(n,e){je.call(this,n,e)}function lL(n,e){je.call(this,n,e)}function oMn(n,e){je.call(this,n,e)}function jC(n,e){je.call(this,n,e)}function sMn(n,e){this.a=n,this.b=e}function fMn(n,e){this.a=n,this.b=e}function hMn(n,e){this.a=n,this.b=e}function lMn(n,e){this.a=n,this.b=e}function aMn(n,e){this.a=n,this.b=e}function dMn(n,e){this.a=n,this.b=e}function bi(n,e){this.a=n,this.b=e}function bMn(n,e){this.a=n,this.b=e}function wMn(n,e){this.a=n,this.b=e}function gMn(n,e){this.a=n,this.b=e}function pMn(n,e){this.a=n,this.b=e}function mMn(n,e){this.a=n,this.b=e}function vMn(n,e){this.a=n,this.b=e}function kMn(n,e){this.b=n,this.a=e}function yMn(n,e){this.b=n,this.a=e}function jMn(n,e){this.b=n,this.a=e}function EMn(n,e){this.b=n,this.a=e}function CMn(n,e){this.a=n,this.b=e}function MMn(n,e){this.a=n,this.b=e}function EC(n,e){je.call(this,n,e)}function TMn(n,e){this.a=n,this.b=e}function AMn(n,e){this.a=n,this.b=e}function gp(n,e){je.call(this,n,e)}function SMn(n,e){this.f=n,this.c=e}function dX(n,e){return Au(n.g,e)}function wle(n,e){return Au(e.b,n)}function PMn(n,e){return wx(n.a,e)}function gle(n,e){return-n.b.af(e)}function ple(n,e){n&&Ve(fE,n,e)}function bX(n,e){n.i=null,kT(n,e)}function mle(n,e,t){kKn(e,oF(n,t))}function vle(n,e,t){kKn(e,oF(n,t))}function kle(n,e){VMe(n.a,u(e,58))}function IMn(n,e){U4e(n.a,u(e,12))}function CC(n,e){this.a=n,this.b=e}function OMn(n,e){this.a=n,this.b=e}function DMn(n,e){this.a=n,this.b=e}function LMn(n,e){this.a=n,this.b=e}function NMn(n,e){this.a=n,this.b=e}function $Mn(n,e){this.d=n,this.b=e}function xMn(n,e){this.e=n,this.a=e}function k7(n,e){this.b=n,this.c=e}function wX(n,e){this.i=n,this.g=e}function gX(n,e){this.d=n,this.e=e}function yle(n,e){cme(new ne(n),e)}function MC(n){return xk(n.c,n.b)}function Kr(n){return n?n.md():null}function x(n){return n??null}function Ai(n){return typeof n===nB}function Nb(n){return typeof n===i3}function $b(n){return typeof n===ltn}function c0(n,e){return Ec(n,e)==0}function TC(n,e){return Ec(n,e)>=0}function j6(n,e){return Ec(n,e)!=0}function AC(n,e){return jve(n.Kc(),e)}function _1(n,e){return n.Rd().Xb(e)}function FMn(n){return eo(n),n.d.gc()}function SC(n){return N6(n==null),n}function E6(n,e){return n.a+=""+e,n}function Er(n,e){return n.a+=""+e,n}function C6(n,e){return n.a+=""+e,n}function Dc(n,e){return n.a+=""+e,n}function Re(n,e){return n.a+=""+e,n}function pX(n,e){return n.a+=""+e,n}function jle(n){return""+(Jn(n),n)}function BMn(n){Hu(this),u5(this,n)}function RMn(){uJ(),aW.call(this)}function KMn(n,e){pW.call(this,n,e)}function _Mn(n,e){pW.call(this,n,e)}function PC(n,e){pW.call(this,n,e)}function ir(n,e){xt(n,e,n.c.b,n.c)}function gg(n,e){xt(n,e,n.a,n.a.a)}function mX(n){return Ln(n,0),null}function HMn(){this.b=0,this.a=!1}function qMn(){this.b=0,this.a=!1}function UMn(){this.b=new ap(Qb(12))}function GMn(){GMn=F,kYn=Ce(jx())}function zMn(){zMn=F,HZn=Ce(iqn())}function XMn(){XMn=F,lre=Ce($xn())}function vX(){vX=F,KG(),oun=new de}function ff(n){return n.a=0,n.b=0,n}function VMn(n,e){return n.a=e.g+1,n}function aL(n,e){Kb.call(this,n,e)}function Mn(n,e){Dt.call(this,n,e)}function pg(n,e){wX.call(this,n,e)}function WMn(n,e){C7.call(this,n,e)}function dL(n,e){Q4.call(this,n,e)}function Ge(n,e){tC(),Ve(yO,n,e)}function JMn(n,e){n.q.setTime(id(e))}function Ele(n){y.clearTimeout(n)}function Cle(n){return Se(n),new M6(n)}function QMn(n,e){return x(n)===x(e)}function YMn(n,e){return n.a.a.a.cc(e)}function bL(n,e){return qo(n.a,0,e)}function kX(n){return Awe(u(n,74))}function pp(n){return wi((Jn(n),n))}function Mle(n){return wi((Jn(n),n))}function ZMn(n){return Yc(n.l,n.m,n.h)}function yX(n,e){return jc(n.a,e.a)}function Tle(n,e){return RPn(n.a,e.a)}function Ale(n,e){return bt(n.a,e.a)}function ih(n,e){return n.indexOf(e)}function Sle(n,e){return n.j[e.p]==2}function u0(n,e){return n==e?0:n?1:-1}function IC(n){return n<10?"0"+n:""+n}function Vr(n){return typeof n===ltn}function Ple(n){return n==tb||n==Iw}function Ile(n){return n==tb||n==Pw}function nTn(n,e){return jc(n.g,e.g)}function jX(n){return qr(n.b.b,n,0)}function eTn(){iM.call(this,0,0,0,0)}function rh(){EG.call(this,new Ql)}function EX(n,e){x4(n,0,n.length,e)}function Ole(n,e){return nn(n.a,e),e}function Dle(n,e){return Fs(),e.a+=n}function Lle(n,e){return Fs(),e.a+=n}function Nle(n,e){return Fs(),e.c+=n}function $le(n,e){return nn(n.c,e),n}function CX(n,e){return Mo(n.a,e),n}function tTn(n){this.a=zCn(),this.b=n}function iTn(n){this.a=zCn(),this.b=n}function rr(n){this.a=n.a,this.b=n.b}function M6(n){this.a=n,GO.call(this)}function rTn(n){this.a=n,GO.call(this)}function mp(){Ho.call(this,0,0,0,0)}function OC(n){return Mo(new ii,n)}function cTn(n){return yM(u(n,123))}function fo(n){return n.vh()&&n.wh()}function mg(n){return n!=Qf&&n!=Pa}function hl(n){return n==Br||n==Xr}function vg(n){return n==us||n==Wf}function uTn(n){return n==P2||n==S2}function xle(n,e){return jc(n.g,e.g)}function oTn(n,e){return new Q4(e,n)}function Fle(n,e){return new Q4(e,n)}function MX(n){return rbe(n.b.Kc(),n.a)}function wL(n,e){cm(n,e),U4(n,n.D)}function gL(n,e,t){aT(n,e),lT(n,t)}function kg(n,e,t){S0(n,e),A0(n,t)}function Ro(n,e,t){eu(n,e),tu(n,t)}function y7(n,e,t){K4(n,e),H4(n,t)}function j7(n,e,t){_4(n,e),q4(n,t)}function sTn(n,e,t){oV.call(this,n,e,t)}function TX(n){SMn.call(this,n,!0)}function fTn(){cC.call(this,"Tail",3)}function hTn(){cC.call(this,"Head",1)}function H1(n){dh(),mve.call(this,n)}function o0(n){iM.call(this,n,n,n,n)}function pL(n){n.c=K(ki,Fn,1,0,5,1)}function AX(n){return n.b&&xF(n),n.a}function SX(n){return n.b&&xF(n),n.c}function Ble(n,e){Uf||(n.b=e)}function Rle(n,e){return n[n.length]=e}function Kle(n,e){return n[n.length]=e}function _le(n,e){return Yb(e,Sf(n))}function Hle(n,e){return Yb(e,Sf(n))}function qle(n,e){return pT(dN(n.d),e)}function Ule(n,e){return pT(dN(n.g),e)}function Gle(n,e){return pT(dN(n.j),e)}function Ni(n,e){Dt.call(this,n.b,e)}function zle(n,e){ve(Sc(n.a),OOn(e))}function Xle(n,e){ve(no(n.a),DOn(e))}function Vle(n,e,t){Ro(t,t.i+n,t.j+e)}function lTn(n,e,t){$t(n.c[e.g],e.g,t)}function Wle(n,e,t){u(n.c,71).Gi(e,t)}function mL(n,e,t){return $t(n,e,t),t}function aTn(n){nu(n.Sf(),new O9n(n))}function yg(n){return n!=null?mt(n):0}function Jle(n){return n==null?0:mt(n)}function T6(n){nt(),Wd.call(this,n)}function dTn(n){this.a=n,HV.call(this,n)}function Tf(){Tf=F,y.Math.log(2)}function Ko(){Ko=F,rl=(gCn(),Moe)}function bTn(){bTn=F,YH=new v5(lU)}function Ie(){Ie=F,new wTn,new Z}function wTn(){new de,new de,new de}function Qle(){throw M(new Kl(QJn))}function Yle(){throw M(new Kl(QJn))}function Zle(){throw M(new Kl(YJn))}function n1e(){throw M(new Kl(YJn))}function vL(n){this.a=n,XE.call(this,n)}function kL(n){this.a=n,XE.call(this,n)}function gTn(n,e){g0(),this.a=n,this.b=e}function e1e(n,e){Se(e),Ag(n).Jc(new Ru)}function Yt(n,e){QL(n.c,n.c.length,e)}function tc(n){return n.ae?1:0}function IX(n,e){return Ec(n,e)>0?n:e}function Yc(n,e,t){return{l:n,m:e,h:t}}function t1e(n,e){n.a!=null&&IMn(e,n.a)}function i1e(n){Zi(n,null),Ii(n,null)}function r1e(n,e,t){return Ve(n.g,t,e)}function jg(n,e,t){return ZY(e,t,n.c)}function c1e(n,e,t){return Ve(n.k,t,e)}function u1e(n,e,t){return GOe(n,e,t),t}function o1e(n,e){return ko(),e.n.b+=n}function mTn(n){ZW.call(this),this.b=n}function OX(n){mV.call(this),this.a=n}function vTn(){cC.call(this,"Range",2)}function DC(n){this.b=n,this.a=new Z}function kTn(n){this.b=new Nbn,this.a=n}function yTn(n){n.a=new OO,n.c=new OO}function jTn(n){n.a=new de,n.d=new de}function ETn(n){$N(n,null),xN(n,null)}function CTn(n,e){return XOe(n.a,e,null)}function s1e(n,e){return Ve(n.a,e.a,e)}function Ki(n){return new V(n.a,n.b)}function DX(n){return new V(n.c,n.d)}function f1e(n){return new V(n.c,n.d)}function A6(n,e){return cOe(n.c,n.b,e)}function D(n,e){return n!=null&&Tx(n,e)}function yL(n,e){return Yve(n.Kc(),e)!=-1}function LC(n){return n.Ob()?n.Pb():null}function h1e(n){this.b=(Dn(),new eD(n))}function LX(n){this.a=n,de.call(this)}function MTn(){C7.call(this,null,null)}function TTn(){KC.call(this,null,null)}function ATn(){je.call(this,"INSTANCE",0)}function STn(){DZ(),this.a=new $5(Son)}function PTn(n){return ws(n,0,n.length)}function l1e(n,e){return new XTn(n.Kc(),e)}function NX(n,e){return n.a.Bc(e)!=null}function ITn(n,e){me(n),n.Gc(u(e,15))}function a1e(n,e,t){n.c.bd(e,u(t,136))}function d1e(n,e,t){n.c.Ui(e,u(t,136))}function OTn(n,e){n.c&&(eW(e),iOn(e))}function b1e(n,e){n.q.setHours(e),K5(n,e)}function w1e(n,e){h0(e,n.a.a.a,n.a.a.b)}function g1e(n,e,t,i){$t(n.a[e.g],t.g,i)}function jL(n,e,t){return n.a[e.g][t.g]}function p1e(n,e){return n.e[e.c.p][e.p]}function m1e(n,e){return n.c[e.c.p][e.p]}function Af(n,e){return n.a[e.c.p][e.p]}function v1e(n,e){return n.j[e.p]=IMe(e)}function EL(n,e){return n.a.Bc(e)!=null}function k1e(n,e){return $(R(e.a))<=n}function y1e(n,e){return $(R(e.a))>=n}function j1e(n,e){return BJ(n.f,e.Pg())}function vp(n,e){return n.a*e.a+n.b*e.b}function E1e(n,e){return n.a0?e/(n*n):e*100}function V1e(n,e){return n>0?e*e/n:e*e*100}function xb(n,e){return u(Nf(n.a,e),34)}function W1e(n,e){return ua(),Pn(n,e.e,e)}function J1e(n,e,t){return ZE(),t.Mg(n,e)}function Q1e(n){return kl(),n.e.a+n.f.a/2}function Y1e(n,e,t){return kl(),t.e.a-n*e}function Z1e(n){return kl(),n.e.b+n.f.b/2}function nae(n,e,t){return kl(),t.e.b-n*e}function oAn(n){n.d=new rAn(n),n.e=new de}function sAn(){this.a=new j0,this.b=new j0}function fAn(n){this.c=n,this.a=1,this.b=1}function hAn(n){YF(),Ayn(this),this.Ff(n)}function eae(n,e,t){YM(),n.pf(e)&&t.Cd(n)}function tae(n,e,t){return nn(e,yBn(n,t))}function h0(n,e,t){return n.a+=e,n.b+=t,n}function iae(n,e,t){return n.a*=e,n.b*=t,n}function YX(n,e){return n.a=e.a,n.b=e.b,n}function _C(n){return n.a=-n.a,n.b=-n.b,n}function O6(n,e,t){return n.a-=e,n.b-=t,n}function lAn(n){Ct.call(this),t5(this,n)}function aAn(){je.call(this,"GROW_TREE",0)}function dAn(){je.call(this,"POLYOMINO",0)}function lo(n,e,t){Iu.call(this,n,e,t,2)}function rae(n,e,t){p5(Sc(n.a),e,OOn(t))}function bAn(n,e){f6(),C7.call(this,n,e)}function ZX(n,e){Gl(),KC.call(this,n,e)}function wAn(n,e){Gl(),ZX.call(this,n,e)}function gAn(n,e){Gl(),KC.call(this,n,e)}function cae(n,e){return n.c.Fc(u(e,136))}function uae(n,e,t){p5(no(n.a),e,DOn(t))}function pAn(n){this.c=n,eu(n,0),tu(n,0)}function PL(n,e){Ko(),uM.call(this,n,e)}function mAn(n,e){Ko(),PL.call(this,n,e)}function nV(n,e){Ko(),PL.call(this,n,e)}function eV(n,e){Ko(),uM.call(this,n,e)}function vAn(n,e){Ko(),nV.call(this,n,e)}function kAn(n,e){Ko(),eV.call(this,n,e)}function yAn(n,e){Ko(),uM.call(this,n,e)}function oae(n,e,t){return e.zl(n.e,n.c,t)}function sae(n,e,t){return e.Al(n.e,n.c,t)}function tV(n,e,t){return qA(fk(n,e),t)}function IL(n,e){return ea(n.e,u(e,54))}function fae(n){return n==null?null:NDe(n)}function hae(n){return n==null?null:Aje(n)}function lae(n){return n==null?null:Jr(n)}function aae(n){return n==null?null:Jr(n)}function un(n){return N6(n==null||Nb(n)),n}function R(n){return N6(n==null||$b(n)),n}function Oe(n){return N6(n==null||Ai(n)),n}function ll(n){n.o==null&&cMe(n)}function iV(n){if(!n)throw M(new W9)}function dae(n){if(!n)throw M(new uD)}function oe(n){if(!n)throw M(new nc)}function Fb(n){if(!n)throw M(new Cu)}function jAn(n){if(!n)throw M(new Bo)}function p4(){p4=F,lE=new cjn,new ujn}function Tg(){Tg=F,D2=new lt("root")}function rV(){rxn.call(this),this.Bb|=hr}function bae(n,e){this.d=n,r9n(this),this.b=e}function cV(n,e){i$.call(this,n),this.a=e}function uV(n,e){i$.call(this,n),this.a=e}function oV(n,e,t){VM.call(this,n,e,t,null)}function EAn(n,e,t){VM.call(this,n,e,t,null)}function A7(n,e){this.c=n,f4.call(this,n,e)}function D6(n,e){this.a=n,A7.call(this,n,e)}function sV(n){this.q=new y.Date(id(n))}function CAn(n){return n>8?0:n+1}function MAn(n,e){Uf||nn(n.a,e)}function wae(n,e){return c7(),J4(e.d.i,n)}function gae(n,e){return Hp(),new tUn(e,n)}function pae(n,e,t){return n.Ne(e,t)<=0?t:e}function mae(n,e,t){return n.Ne(e,t)<=0?e:t}function vae(n,e){return u(Nf(n.b,e),143)}function kae(n,e){return u(Nf(n.c,e),233)}function OL(n){return u(sn(n.a,n.b),293)}function TAn(n){return new V(n.c,n.d+n.a)}function AAn(n){return Jn(n),n?1231:1237}function SAn(n){return ko(),uTn(u(n,203))}function Bb(){Bb=F,ton=yn((go(),Gd))}function yae(n,e){e.a?MCe(n,e):EL(n.a,e.b)}function S7(n,e,t){++n.j,n.tj(),t$(n,e,t)}function PAn(n,e,t){++n.j,n.qj(e,n.Zi(e,t))}function IAn(n,e,t){var i;i=n.fd(e),i.Rb(t)}function fV(n,e,t){return t=So(n,e,6,t),t}function hV(n,e,t){return t=So(n,e,3,t),t}function lV(n,e,t){return t=So(n,e,9,t),t}function uh(n,e){return G7(e,Ntn),n.f=e,n}function aV(n,e){return(e&et)%n.d.length}function OAn(n,e,t){return Uen(n.c,n.b,e,t)}function DAn(n,e){this.c=n,T0.call(this,e)}function LAn(n,e){this.a=n,vyn.call(this,e)}function P7(n,e){this.a=n,vyn.call(this,e)}function Dt(n,e){lt.call(this,n),this.a=e}function dV(n,e){xG.call(this,n),this.a=e}function DL(n,e){xG.call(this,n),this.a=e}function jae(n){XY.call(this,0,0),this.f=n}function NAn(n,e,t){return n.a+=ws(e,0,t),n}function I7(n){return!n.a&&(n.a=new E0n),n.a}function bV(n,e){var t;return t=n.e,n.e=e,t}function wV(n,e){var t;return t=e,!!n.Fe(t)}function Eae(n,e){return _n(),n==e?0:n?1:-1}function Rb(n,e){n.a.bd(n.b,e),++n.b,n.c=-1}function O7(n){n.b?O7(n.b):n.f.c.zc(n.e,n.d)}function $An(n){Hu(n.e),n.d.b=n.d,n.d.a=n.d}function Cae(n,e,t){Va(),e9n(n,e.Ve(n.a,t))}function gV(n,e,t){return Pp(n,u(e,22),t)}function xs(n,e){return HE(new Array(e),n)}function Mae(n){return Ae(U1(n,32))^Ae(n)}function LL(n){return String.fromCharCode(n)}function Tae(n){return n==null?null:n.message}function Aae(n,e,t){return n.apply(e,t)}function Sae(n,e){var t;t=n[DB],t.call(n,e)}function Pae(n,e){var t;t=n[DB],t.call(n,e)}function Iae(n,e){return c7(),!J4(e.d.i,n)}function pV(n,e,t,i){iM.call(this,n,e,t,i)}function xAn(){HC.call(this),this.a=new Li}function mV(){this.n=new Li,this.o=new Li}function FAn(){this.b=new Li,this.c=new Z}function BAn(){this.a=new Z,this.b=new Z}function RAn(){this.a=new KU,this.b=new Fyn}function vV(){this.b=new Ql,this.a=new Ql}function KAn(){this.b=new ni,this.a=new ni}function _An(){this.b=new de,this.a=new de}function HAn(){this.b=new bEn,this.a=new _3n}function qAn(){this.a=new Z5n,this.b=new Dpn}function UAn(){this.a=new Z,this.d=new Z}function HC(){this.n=new up,this.i=new mp}function GAn(n){this.a=(Co(n,mw),new Gc(n))}function zAn(n){this.a=(Co(n,mw),new Gc(n))}function Oae(n){return n<100?null:new F1(n)}function Dae(n,e){return n.n.a=(Jn(e),e+10)}function Lae(n,e){return n.n.a=(Jn(e),e+10)}function Nae(n,e){return e==n||vm(TA(e),n)}function XAn(n,e){return Ve(n.a,e,"")==null}function $ae(n,e){var t;return t=e.qi(n.a),t}function tt(n,e){return n.a+=e.a,n.b+=e.b,n}function mi(n,e){return n.a-=e.a,n.b-=e.b,n}function xae(n){return Ab(n.j.c,0),n.a=-1,n}function kV(n,e,t){return t=So(n,e,11,t),t}function Fae(n,e,t){t!=null&&mT(e,Fx(n,t))}function Bae(n,e,t){t!=null&&vT(e,Fx(n,t))}function jp(n,e,t,i){q.call(this,n,e,t,i)}function yV(n,e,t,i){q.call(this,n,e,t,i)}function VAn(n,e,t,i){yV.call(this,n,e,t,i)}function WAn(n,e,t,i){dM.call(this,n,e,t,i)}function NL(n,e,t,i){dM.call(this,n,e,t,i)}function jV(n,e,t,i){dM.call(this,n,e,t,i)}function JAn(n,e,t,i){NL.call(this,n,e,t,i)}function EV(n,e,t,i){NL.call(this,n,e,t,i)}function Nn(n,e,t,i){jV.call(this,n,e,t,i)}function QAn(n,e,t,i){EV.call(this,n,e,t,i)}function YAn(n,e,t,i){yW.call(this,n,e,t,i)}function Kb(n,e){Ir.call(this,w8+n+Td+e)}function CV(n,e){return n.jk().wi().ri(n,e)}function MV(n,e){return n.jk().wi().ti(n,e)}function ZAn(n,e){return Jn(n),x(n)===x(e)}function An(n,e){return Jn(n),x(n)===x(e)}function Rae(n,e){return n.b.Bd(new jCn(n,e))}function Kae(n,e){return n.b.Bd(new ECn(n,e))}function nSn(n,e){return n.b.Bd(new CCn(n,e))}function _ae(n,e){return n.e=u(n.d.Kb(e),159)}function TV(n,e,t){return n.lastIndexOf(e,t)}function Hae(n,e,t){return bt(n[e.a],n[t.a])}function qae(n,e){return U(e,(cn(),Ej),n)}function Uae(n,e){return jc(e.a.d.p,n.a.d.p)}function Gae(n,e){return jc(n.a.d.p,e.a.d.p)}function zae(n,e){return bt(n.c-n.s,e.c-e.s)}function Xae(n,e){return bt(n.b.e.a,e.b.e.a)}function Vae(n,e){return bt(n.c.e.a,e.c.e.a)}function eSn(n){return n.c?qr(n.c.a,n,0):-1}function Ep(n){return n==Ud||n==tl||n==qc}function AV(n,e){this.c=n,oN.call(this,n,e)}function tSn(n,e,t){this.a=n,WX.call(this,e,t)}function iSn(n){this.c=n,PC.call(this,jy,0)}function rSn(n,e,t){this.c=e,this.b=t,this.a=n}function D7(n){v4(),this.d=n,this.a=new Cg}function cSn(n){oh(),this.a=(Dn(),new i4(n))}function Wae(n,e){hl(n.f)?QCe(n,e):Sye(n,e)}function uSn(n,e){sbe.call(this,n,n.length,e)}function Jae(n,e){Uf||e&&(n.d=e)}function oSn(n,e){return D(e,15)&&xqn(n.c,e)}function Qae(n,e,t){return u(n.c,71).Wk(e,t)}function qC(n,e,t){return u(n.c,71).Xk(e,t)}function Yae(n,e,t){return oae(n,u(e,343),t)}function SV(n,e,t){return sae(n,u(e,343),t)}function Zae(n,e,t){return SKn(n,u(e,343),t)}function sSn(n,e,t){return _ye(n,u(e,343),t)}function L6(n,e){return e==null?null:tw(n.b,e)}function PV(n){return $b(n)?(Jn(n),n):n.ue()}function UC(n){return!isNaN(n)&&!isFinite(n)}function $L(n){yTn(this),vo(this),Bi(this,n)}function _u(n){pL(this),GV(this.c,0,n.Pc())}function _o(n,e,t){this.a=n,this.b=e,this.c=t}function fSn(n,e,t){this.a=n,this.b=e,this.c=t}function hSn(n,e,t){this.d=n,this.b=t,this.a=e}function lSn(n){this.a=n,fl(),vc(Date.now())}function aSn(n){bo(n.a),UJ(n.c,n.b),n.b=null}function xL(){xL=F,Pun=new N0n,AQn=new $0n}function dSn(){dSn=F,Ioe=K(ki,Fn,1,0,5,1)}function bSn(){bSn=F,Voe=K(ki,Fn,1,0,5,1)}function IV(){IV=F,Woe=K(ki,Fn,1,0,5,1)}function oh(){oh=F,new RG((Dn(),Dn(),sr))}function nde(n){return F4(),Ee((kNn(),IQn),n)}function ede(n){return Gu(),Ee((hNn(),xQn),n)}function tde(n){return YT(),Ee((WDn(),HQn),n)}function ide(n){return cT(),Ee((JDn(),qQn),n)}function rde(n){return NA(),Ee((Wxn(),UQn),n)}function cde(n){return wf(),Ee((sNn(),XQn),n)}function ude(n){return Uu(),Ee((oNn(),WQn),n)}function ode(n){return bu(),Ee((fNn(),QQn),n)}function sde(n){return VA(),Ee((GMn(),kYn),n)}function fde(n){return D0(),Ee((jNn(),jYn),n)}function hde(n){return Vp(),Ee((CNn(),CYn),n)}function lde(n){return C5(),Ee((ENn(),AYn),n)}function ade(n){return QE(),Ee((yDn(),SYn),n)}function dde(n){return uT(),Ee((QDn(),GYn),n)}function bde(n){return n5(),Ee((lNn(),pZn),n)}function wde(n){return Vi(),Ee((c$n(),yZn),n)}function gde(n){return Z4(),Ee((TNn(),TZn),n)}function pde(n){return dd(),Ee((MNn(),DZn),n)}function OV(n,e){if(!n)throw M(new Gn(e))}function m4(n){if(!n)throw M(new Or(atn))}function FL(n,e){if(n!=e)throw M(new Bo)}function wSn(n,e,t){this.a=n,this.b=e,this.c=t}function DV(n,e,t){this.a=n,this.b=e,this.c=t}function gSn(n,e,t){this.a=n,this.b=e,this.c=t}function GC(n,e,t){this.b=n,this.a=e,this.c=t}function LV(n,e,t){this.b=n,this.c=e,this.a=t}function NV(n,e,t){this.a=n,this.b=e,this.c=t}function zC(n,e,t){this.e=e,this.b=n,this.d=t}function pSn(n,e,t){this.b=n,this.a=e,this.c=t}function mde(n,e,t){return Va(),n.a.Yd(e,t),e}function BL(n){var e;return e=new cbn,e.e=n,e}function $V(n){var e;return e=new Hyn,e.b=n,e}function L7(){L7=F,CP=new ogn,MP=new sgn}function XC(){XC=F,XZn=new $gn,zZn=new xgn}function Fs(){Fs=F,YZn=new U2n,ZZn=new G2n}function vde(n){return I0(),Ee((qLn(),fne),n)}function kde(n){return tr(),Ee((zMn(),HZn),n)}function yde(n){return OT(),Ee((SNn(),GZn),n)}function jde(n){return xf(),Ee((ANn(),tne),n)}function Ede(n){return ow(),Ee((u$n(),rne),n)}function Cde(n){return DA(),Ee((Nxn(),hne),n)}function Mde(n){return Yp(),Ee((O$n(),lne),n)}function Tde(n){return QM(),Ee((eLn(),ane),n)}function Ade(n){return i5(),Ee((KLn(),dne),n)}function Sde(n){return bT(),Ee((_Ln(),bne),n)}function Pde(n){return o1(),Ee((o$n(),wne),n)}function Ide(n){return bk(),Ee((nLn(),gne),n)}function Ode(n){return ym(),Ee((N$n(),jne),n)}function Dde(n){return pr(),Ee((lFn(),Ene),n)}function Lde(n){return Y4(),Ee((GLn(),Cne),n)}function Nde(n){return vl(),Ee((ULn(),Tne),n)}function $de(n){return KM(),Ee((oLn(),Ane),n)}function xde(n){return Xk(),Ee((L$n(),yne),n)}function Fde(n){return hd(),Ee((HLn(),mne),n)}function Bde(n){return vA(),Ee((D$n(),vne),n)}function Rde(n){return ok(),Ee((ZDn(),kne),n)}function Kde(n){return Yo(),Ee((f$n(),Sne),n)}function _de(n){return a1(),Ee((zxn(),Yte),n)}function Hde(n){return d5(),Ee((zLn(),Zte),n)}function qde(n){return cw(),Ee((PNn(),nie),n)}function Ude(n){return E5(),Ee((s$n(),eie),n)}function Gde(n){return ps(),Ee((aFn(),tie),n)}function zde(n){return lh(),Ee((INn(),iie),n)}function Xde(n){return ak(),Ee((tLn(),rie),n)}function Vde(n){return gr(),Ee((WLn(),uie),n)}function Wde(n){return ST(),Ee((XLn(),oie),n)}function Jde(n){return h5(),Ee((VLn(),sie),n)}function Qde(n){return um(),Ee((QLn(),fie),n)}function Yde(n){return dT(),Ee((JLn(),hie),n)}function Zde(n){return DT(),Ee((YLn(),lie),n)}function n0e(n){return P0(),Ee((uNn(),Aie),n)}function e0e(n){return Q6(),Ee((iLn(),Die),n)}function t0e(n){return fh(),Ee((rLn(),Rie),n)}function i0e(n){return Pf(),Ee((cLn(),_ie),n)}function r0e(n){return af(),Ee((uLn(),tre),n)}function c0e(n){return E0(),Ee((sLn(),fre),n)}function u0e(n){return Qp(),Ee((FNn(),hre),n)}function o0e(n){return B5(),Ee((XMn(),lre),n)}function s0e(n){return l5(),Ee((ZLn(),are),n)}function f0e(n){return a5(),Ee((xNn(),$re),n)}function h0e(n){return FM(),Ee((hLn(),xre),n)}function l0e(n){return yT(),Ee((lLn(),_re),n)}function a0e(n){return wA(),Ee((h$n(),qre),n)}function d0e(n){return Sk(),Ee((nNn(),Gre),n)}function b0e(n){return ZM(),Ee((fLn(),Ure),n)}function w0e(n){return sA(),Ee(($Nn(),lce),n)}function g0e(n){return AT(),Ee((eNn(),ace),n)}function p0e(n){return XT(),Ee((tNn(),dce),n)}function m0e(n){return rA(),Ee((iNn(),wce),n)}function v0e(n){return _T(),Ee((rNn(),mce),n)}function k0e(n){return GM(),Ee((aLn(),Rce),n)}function y0e(n){return X4(),Ee((YDn(),_Zn),n)}function j0e(n){return Vn(),Ee(($$n(),xZn),n)}function E0e(n){return nT(),Ee((cNn(),Kce),n)}function C0e(n){return N$(),Ee((dLn(),_ce),n)}function M0e(n){return N5(),Ee((l$n(),qce),n)}function T0e(n){return nC(),Ee((PDn(),Gce),n)}function A0e(n){return Nk(),Ee((dNn(),Uce),n)}function S0e(n){return eC(),Ee((IDn(),Xce),n)}function P0e(n){return tk(),Ee((bLn(),Vce),n)}function I0e(n){return Wk(),Ee((a$n(),Wce),n)}function O0e(n){return u6(),Ee((ODn(),lue),n)}function D0e(n){return Ck(),Ee((wLn(),aue),n)}function L0e(n){return pf(),Ee((b$n(),mue),n)}function N0e(n){return l1(),Ee((Dxn(),kue),n)}function $0e(n){return Rh(),Ee((x$n(),yue),n)}function x0e(n){return wd(),Ee((F$n(),Aue),n)}function F0e(n){return ci(),Ee((d$n(),zue),n)}function B0e(n){return $f(),Ee((bNn(),Xue),n)}function R0e(n){return El(),Ee((BNn(),Vue),n)}function K0e(n){return pA(),Ee((B$n(),Wue),n)}function _0e(n){return jl(),Ee((aNn(),Que),n)}function H0e(n){return To(),Ee((RNn(),Zue),n)}function q0e(n){return lw(),Ee((Vxn(),noe),n)}function U0e(n){return Bg(),Ee((w$n(),eoe),n)}function G0e(n){return Oi(),Ee((R$n(),toe),n)}function z0e(n){return zu(),Ee((K$n(),ioe),n)}function X0e(n){return en(),Ee((g$n(),roe),n)}function V0e(n){return go(),Ee((KNn(),foe),n)}function W0e(n){return io(),Ee((Xxn(),hoe),n)}function J0e(n){return Gp(),Ee((wNn(),loe),n)}function Q0e(n,e){return Jn(n),n+(Jn(e),e)}function Y0e(n){return RL(),Ee((gLn(),aoe),n)}function Z0e(n){return qT(),Ee((_Nn(),doe),n)}function nbe(n){return LT(),Ee((HNn(),goe),n)}function v4(){v4=F,nln=(en(),Wn),II=Zn}function RL(){RL=F,mdn=new XSn,vdn=new DPn}function ebe(n){return!n.e&&(n.e=new Z),n.e}function KL(n,e){this.c=n,this.a=e,this.b=e-n}function mSn(n,e,t){this.a=n,this.b=e,this.c=t}function _L(n,e,t){this.a=n,this.b=e,this.c=t}function xV(n,e,t){this.a=n,this.b=e,this.c=t}function FV(n,e,t){this.a=n,this.b=e,this.c=t}function vSn(n,e,t){this.a=n,this.b=e,this.c=t}function kSn(n,e,t){this.a=n,this.b=e,this.c=t}function Xl(n,e,t){this.e=n,this.a=e,this.c=t}function ySn(n,e,t){Ko(),eJ.call(this,n,e,t)}function HL(n,e,t){Ko(),BW.call(this,n,e,t)}function BV(n,e,t){Ko(),BW.call(this,n,e,t)}function RV(n,e,t){Ko(),BW.call(this,n,e,t)}function jSn(n,e,t){Ko(),HL.call(this,n,e,t)}function KV(n,e,t){Ko(),HL.call(this,n,e,t)}function ESn(n,e,t){Ko(),KV.call(this,n,e,t)}function CSn(n,e,t){Ko(),BV.call(this,n,e,t)}function MSn(n,e,t){Ko(),RV.call(this,n,e,t)}function qL(n){iM.call(this,n.d,n.c,n.a,n.b)}function _V(n){iM.call(this,n.d,n.c,n.a,n.b)}function HV(n){this.d=n,r9n(this),this.b=nwe(n.d)}function tbe(n){return Em(),Ee((Lxn(),Poe),n)}function N7(n,e){return Se(n),Se(e),new LEn(n,e)}function Cp(n,e){return Se(n),Se(e),new BSn(n,e)}function ibe(n,e){return Se(n),Se(e),new RSn(n,e)}function rbe(n,e){return Se(n),Se(e),new HEn(n,e)}function UL(n){return oe(n.b!=0),Xo(n,n.a.a)}function cbe(n){return oe(n.b!=0),Xo(n,n.c.b)}function ube(n){return!n.c&&(n.c=new V3),n.c}function k4(n){var e;return e=new Z,b$(e,n),e}function obe(n){var e;return e=new ni,b$(e,n),e}function TSn(n){var e;return e=new UG,A$(e,n),e}function $7(n){var e;return e=new Ct,A$(e,n),e}function u(n,e){return N6(n==null||Tx(n,e)),n}function sbe(n,e,t){MPn.call(this,e,t),this.a=n}function ASn(n,e){this.c=n,this.b=e,this.a=!1}function SSn(){this.a=";,;",this.b="",this.c=""}function PSn(n,e,t){this.b=n,KMn.call(this,e,t)}function qV(n,e,t){this.c=n,uC.call(this,e,t)}function UV(n,e,t){a4.call(this,n,e),this.b=t}function GV(n,e,t){xnn(t,0,n,e,t.length,!1)}function Lh(n,e,t,i,r){n.b=e,n.c=t,n.d=i,n.a=r}function zV(n,e,t,i,r){n.d=e,n.c=t,n.a=i,n.b=r}function fbe(n,e){e&&(n.b=e,n.a=(X1(e),e.a))}function x7(n,e){if(!n)throw M(new Gn(e))}function Mp(n,e){if(!n)throw M(new Or(e))}function XV(n,e){if(!n)throw M(new Fjn(e))}function hbe(n,e){return YE(),jc(n.d.p,e.d.p)}function lbe(n,e){return kl(),bt(n.e.b,e.e.b)}function abe(n,e){return kl(),bt(n.e.a,e.e.a)}function dbe(n,e){return jc(USn(n.d),USn(e.d))}function VC(n,e){return e&&mM(n,e.d)?e:null}function bbe(n,e){return e==(en(),Wn)?n.c:n.d}function VV(n){return Y1(dwe(Vr(n)?ds(n):n))}function wbe(n){return new V(n.c+n.b,n.d+n.a)}function ISn(n){return n!=null&&!lx(n,O9,D9)}function gbe(n,e){return(sBn(n)<<4|sBn(e))&ui}function OSn(n,e,t,i,r){n.c=e,n.d=t,n.b=i,n.a=r}function WV(n){var e,t;e=n.b,t=n.c,n.b=t,n.c=e}function JV(n){var e,t;t=n.d,e=n.a,n.d=e,n.a=t}function pbe(n,e){var t;return t=n.c,SQ(n,e),t}function QV(n,e){return e<0?n.g=-1:n.g=e,n}function WC(n,e){return Mme(n),n.a*=e,n.b*=e,n}function DSn(n,e,t){T$n.call(this,e,t),this.d=n}function F7(n,e,t){gX.call(this,n,e),this.c=t}function JC(n,e,t){gX.call(this,n,e),this.c=t}function YV(n){IV(),CE.call(this),this.ci(n)}function LSn(){N4(),Bwe.call(this,(R1(),Ps))}function NSn(n){return nt(),new Nh(0,n)}function $Sn(){$Sn=F,TU=(Dn(),new nD(IK))}function QC(){QC=F,new fZ((bD(),HK),(dD(),_K))}function xSn(){xSn=F,wun=K(Gi,J,17,256,0,1)}function FSn(){this.b=$(R(rn((Us(),y_))))}function GL(n){this.b=n,this.a=Ja(this.b.a).Od()}function BSn(n,e){this.b=n,this.a=e,GO.call(this)}function RSn(n,e){this.a=n,this.b=e,GO.call(this)}function KSn(n,e,t){this.a=n,pg.call(this,e,t)}function _Sn(n,e,t){this.a=n,pg.call(this,e,t)}function y4(n,e,t){var i;i=new qb(t),bf(n,e,i)}function ZV(n,e,t){var i;return i=n[e],n[e]=t,i}function YC(n){var e;return e=n.slice(),o$(e,n)}function ZC(n){var e;return e=n.n,n.a.b+e.d+e.a}function HSn(n){var e;return e=n.n,n.e.b+e.d+e.a}function nW(n){var e;return e=n.n,n.e.a+e.b+e.c}function eW(n){n.a.b=n.b,n.b.a=n.a,n.a=n.b=null}function Fe(n,e){return xt(n,e,n.c.b,n.c),!0}function mbe(n){return n.a?n.a:vN(n)}function vbe(n){return Lp(),Kh(n)==At(ra(n))}function kbe(n){return Lp(),ra(n)==At(Kh(n))}function l0(n,e){return S5(n,new a4(e.a,e.b))}function ybe(n,e){return kM(),Nx(n,e),new hIn(n,e)}function jbe(n,e){return n.c=e)throw M(new QG)}function _b(n,e){return Dk(n,(Jn(e),new l9n(e)))}function Ap(n,e){return Dk(n,(Jn(e),new a9n(e)))}function APn(n,e,t){return VLe(n,u(e,12),u(t,12))}function SPn(n){return Ou(),u(n,12).g.c.length!=0}function PPn(n){return Ou(),u(n,12).e.c.length!=0}function uwe(n,e){return Hp(),bt(e.a.o.a,n.a.o.a)}function owe(n,e){e.Bb&kc&&!n.a.o&&(n.a.o=e)}function swe(n,e){e.Ug("General 'Rotator",1),jDe(n)}function fwe(n,e,t){e.qf(t,$(R(ee(n.b,t)))*n.a)}function IPn(n,e,t){return Vg(),V4(n,e)&&V4(n,t)}function B6(n){return zu(),!n.Hc(Fl)&&!n.Hc(Ia)}function hwe(n){return n.e?HJ(n.e):null}function R6(n){return Vr(n)?""+n:$qn(n)}function kW(n){var e;for(e=n;e.f;)e=e.f;return e}function lwe(n,e,t){return $t(e,0,uW(e[0],t[0])),e}function Vl(n,e,t,i){var r;r=n.i,r.i=e,r.a=t,r.b=i}function q(n,e,t,i){ti.call(this,n,e,t),this.b=i}function Ci(n,e,t,i,r){c$.call(this,n,e,t,i,r,-1)}function K6(n,e,t,i,r){rk.call(this,n,e,t,i,r,-1)}function dM(n,e,t,i){F7.call(this,n,e,t),this.b=i}function OPn(n){SMn.call(this,n,!1),this.a=!1}function DPn(){oMn.call(this,"LOOKAHEAD_LAYOUT",1)}function LPn(n){this.b=n,kp.call(this,n),BTn(this)}function NPn(n){this.b=n,M7.call(this,n),RTn(this)}function Hb(n,e,t){this.a=n,jp.call(this,e,t,5,6)}function yW(n,e,t,i){this.b=n,ti.call(this,e,t,i)}function $Pn(n,e){this.b=n,_8n.call(this,n.b),this.a=e}function xPn(n){this.a=vRn(n.a),this.b=new _u(n.b)}function jW(n,e){g0(),Hhe.call(this,n,FT(new Ku(e)))}function bM(n,e){return nt(),new FW(n,e,0)}function rN(n,e){return nt(),new FW(6,n,e)}function _i(n,e){for(Jn(e);n.Ob();)e.Cd(n.Pb())}function Zc(n,e){return Ai(e)?AN(n,e):!!wr(n.f,e)}function cN(n,e){return e.Vh()?ea(n.b,u(e,54)):e}function awe(n,e){return An(n.substr(0,e.length),e)}function $h(n){return new ie(new qX(n.a.length,n.a))}function wM(n){return new V(n.c+n.b/2,n.d+n.a/2)}function dwe(n){return Yc(~n.l&ro,~n.m&ro,~n.h&Il)}function uN(n){return typeof n===my||typeof n===eB}function Hu(n){n.f=new tTn(n),n.i=new iTn(n),++n.g}function FPn(n){if(!n)throw M(new nc);return n.d}function Sp(n){var e;return e=f5(n),oe(e!=null),e}function bwe(n){var e;return e=I5e(n),oe(e!=null),e}function E4(n,e){var t;return t=n.a.gc(),FJ(e,t),t-e}function fi(n,e){var t;return t=n.a.zc(e,n),t==null}function R7(n,e){return n.a.zc(e,(_n(),ga))==null}function EW(n){return new Tn(null,vwe(n,n.length))}function CW(n,e,t){return cGn(n,u(e,42),u(t,176))}function Pp(n,e,t){return _s(n.a,e),ZV(n.b,e.g,t)}function wwe(n,e,t){j4(t,n.a.c.length),Go(n.a,t,e)}function B(n,e,t,i){$Fn(e,t,n.length),gwe(n,e,t,i)}function gwe(n,e,t,i){var r;for(r=e;r0?y.Math.log(n/e):-100}function RPn(n,e){return Ec(n,e)<0?-1:Ec(n,e)>0?1:0}function K7(n,e){ITn(n,D(e,160)?e:u(e,2036).Rl())}function SW(n,e){if(n==null)throw M(new fp(e))}function vwe(n,e){return yme(e,n.length),new zSn(n,e)}function PW(n,e){return e?Bi(n,e):!1}function kwe(){return BE(),A(T(uQn,1),G,549,0,[GK])}function H6(n){return n.e==0?n:new Ya(-n.e,n.d,n.a)}function ywe(n,e){return bt(n.c.c+n.c.b,e.c.c+e.c.b)}function _7(n,e){xt(n.d,e,n.b.b,n.b),++n.a,n.c=null}function KPn(n,e){return n.c?KPn(n.c,e):nn(n.b,e),n}function jwe(n,e,t){var i;return i=Jb(n,e),qN(n,e,t),i}function _Pn(n,e,t){var i;for(i=0;i=n.g}function $t(n,e,t){return dae(t==null||sPe(n,t)),n[e]=t}function NW(n,e){return zn(e,n.length+1),n.substr(e)}function gN(n,e){for(Jn(e);n.c=n?new Oz:Gme(n-1)}function Hi(n){return!n.a&&n.c?n.c.b:n.a}function RW(n){return D(n,616)?n:new uOn(n)}function X1(n){n.c?X1(n.c):(ta(n),n.d=!0)}function G6(n){n.c?n.c.$e():(n.d=!0,fTe(n))}function oIn(n){n.b=!1,n.c=!1,n.d=!1,n.a=!1}function sIn(n){var e,t;return e=n.c.i.c,t=n.d.i.c,e==t}function _we(n,e){var t;t=n.Ih(e),t>=0?n.ki(t):Ann(n,e)}function fIn(n,e){n.c<0||n.b.b0;)n=n<<1|(n<0?1:0);return n}function pIn(n,e){var t;return t=new Lc(n),Rn(e.c,t),t}function mIn(n,e){n.u.Hc((zu(),Fl))&&zEe(n,e),h4e(n,e)}function mc(n,e){return x(n)===x(e)||n!=null&&rt(n,e)}function Cr(n,e){return JL(n.a,e)?n.b[u(e,22).g]:null}function nge(){return QE(),A(T(con,1),G,488,0,[b_])}function ege(){return nC(),A(T(N1n,1),G,489,0,[Fq])}function tge(){return eC(),A(T(zce,1),G,558,0,[Bq])}function ige(){return u6(),A(T(ean,1),G,539,0,[_j])}function yM(n){return!n.n&&(n.n=new q(Ar,n,1,7)),n.n}function mN(n){return!n.c&&(n.c=new q(Qu,n,9,9)),n.c}function qW(n){return!n.c&&(n.c=new Nn(he,n,5,8)),n.c}function rge(n){return!n.b&&(n.b=new Nn(he,n,4,7)),n.b}function H7(n){return n.j.c.length=0,GW(n.c),xae(n.a),n}function S4(n){return n.e==iv&&jfe(n,Y8e(n.g,n.b)),n.e}function q7(n){return n.f==iv&&Cfe(n,q7e(n.g,n.b)),n.f}function We(n,e,t,i){return _xn(n,e,t,!1),BT(n,i),n}function vIn(n,e){this.b=n,oN.call(this,n,e),BTn(this)}function kIn(n,e){this.b=n,AV.call(this,n,e),RTn(this)}function z6(n){this.d=n,this.a=this.d.b,this.b=this.d.c}function UW(n,e){this.b=n,this.c=e,this.a=new dp(this.b)}function Xi(n,e){return zn(e,n.length),n.charCodeAt(e)}function cge(n,e){OY(n,$(yl(e,"x")),$(yl(e,"y")))}function uge(n,e){OY(n,$(yl(e,"x")),$(yl(e,"y")))}function ut(n,e){return ta(n),new Tn(n,new eQ(e,n.a))}function _r(n,e){return ta(n),new Tn(n,new KJ(e,n.a))}function Ub(n,e){return ta(n),new cV(n,new PLn(e,n.a))}function jM(n,e){return ta(n),new uV(n,new ILn(e,n.a))}function oge(n,e){return new UIn(u(Se(n),50),u(Se(e),50))}function sge(n,e){return bt(n.d.c+n.d.b/2,e.d.c+e.d.b/2)}function yIn(n,e,t){t.a?tu(n,e.b-n.f/2):eu(n,e.a-n.g/2)}function fge(n,e){return bt(n.g.c+n.g.b/2,e.g.c+e.g.b/2)}function hge(n,e){return Nz(),bt((Jn(n),n),(Jn(e),e))}function lge(n){return n!=null&&t7(jO,n.toLowerCase())}function GW(n){var e;for(e=n.Kc();e.Ob();)e.Pb(),e.Qb()}function Ag(n){var e;return e=n.b,!e&&(n.b=e=new L8n(n)),e}function vN(n){var e;return e=Wme(n),e||null}function jIn(n,e){var t,i;return t=n/e,i=wi(t),t>i&&++i,i}function age(n,e,t){var i;i=u(n.d.Kb(t),159),i&&i.Nb(e)}function dge(n,e,t){wIe(n.a,t),zve(t),xCe(n.b,t),xIe(e,t)}function EM(n,e,t,i){this.a=n,this.c=e,this.b=t,this.d=i}function zW(n,e,t,i){this.c=n,this.b=e,this.a=t,this.d=i}function EIn(n,e,t,i){this.c=n,this.b=e,this.d=t,this.a=i}function Ho(n,e,t,i){this.c=n,this.d=e,this.b=t,this.a=i}function CIn(n,e,t,i){this.a=n,this.d=e,this.c=t,this.b=i}function kN(n,e,t,i){this.a=n,this.e=e,this.d=t,this.c=i}function MIn(n,e,t,i){this.a=n,this.c=e,this.d=t,this.b=i}function yN(n,e,t){this.a=mtn,this.d=n,this.b=e,this.c=t}function Op(n,e,t,i){je.call(this,n,e),this.a=t,this.b=i}function TIn(n,e){this.d=(Jn(n),n),this.a=16449,this.c=e}function AIn(n){this.a=new Z,this.e=K(ye,J,53,n,0,2)}function bge(n){n.Ug("No crossing minimization",1),n.Vg()}function SIn(){ec.call(this,"There is no more element.")}function PIn(n,e,t,i){this.a=n,this.b=e,this.c=t,this.d=i}function IIn(n,e,t,i){this.a=n,this.b=e,this.c=t,this.d=i}function Za(n,e,t,i){this.e=n,this.a=e,this.c=t,this.d=i}function OIn(n,e,t,i){this.a=n,this.c=e,this.d=t,this.b=i}function DIn(n,e,t,i){Ko(),OLn.call(this,e,t,i),this.a=n}function LIn(n,e,t,i){Ko(),OLn.call(this,e,t,i),this.a=n}function jN(n,e,t){var i,r;return i=rtn(n),r=e.ti(t,i),r}function al(n){var e,t;return t=(e=new Jd,e),R4(t,n),t}function EN(n){var e,t;return t=(e=new Jd,e),snn(t,n),t}function wge(n,e){var t;return t=ee(n.f,e),_Q(e,t),null}function NIn(n){return!n.b&&(n.b=new q(Vt,n,12,3)),n.b}function $In(n){return N6(n==null||uN(n)&&n.Tm!==Q2),n}function CM(n){return n.n&&(n.e!==Fzn&&n.je(),n.j=null),n}function P4(n){if(eo(n.d),n.d.d!=n.c)throw M(new Bo)}function XW(n){return oe(n.b0&&dKn(this)}function xIn(n,e){this.a=n,bae.call(this,n,u(n.d,15).fd(e))}function gge(n,e){return bt(Su(n)*ao(n),Su(e)*ao(e))}function pge(n,e){return bt(Su(n)*ao(n),Su(e)*ao(e))}function mge(n){return R0(n)&&on(un(z(n,(cn(),Nd))))}function vge(n,e){return Pn(n,u(v(e,(cn(),Ev)),17),e)}function kge(n,e){return u(v(n,(W(),T3)),15).Fc(e),e}function VW(n,e){return n.b=e.b,n.c=e.c,n.d=e.d,n.a=e.a,n}function FIn(n,e,t,i){this.b=n,this.c=i,PC.call(this,e,t)}function yge(n,e,t){n.i=0,n.e=0,e!=t&&kFn(n,e,t)}function jge(n,e,t){n.i=0,n.e=0,e!=t&&yFn(n,e,t)}function Ege(n,e,t){return c6(),J5e(u(ee(n.e,e),529),t)}function Dp(n){var e;return e=n.f,e||(n.f=new f4(n,n.c))}function BIn(n,e){return Fg(n.j,e.s,e.c)+Fg(e.e,n.s,n.c)}function RIn(n,e){n.e&&!n.e.a&&(Tyn(n.e,e),RIn(n.e,e))}function KIn(n,e){n.d&&!n.d.a&&(Tyn(n.d,e),KIn(n.d,e))}function Cge(n,e){return-bt(Su(n)*ao(n),Su(e)*ao(e))}function Mge(n){return u(n.ld(),149).Pg()+":"+Jr(n.md())}function _In(){tF(this,new uG),this.wb=(G1(),Hn),u4()}function HIn(n){this.b=new Z,hi(this.b,this.b),this.a=n}function WW(n,e){new Ct,this.a=new Mu,this.b=n,this.c=e}function k0(){k0=F,Aun=new xU,ZK=new xU,Sun=new O0n}function Dn(){Dn=F,sr=new T0n,Wh=new S0n,hP=new P0n}function JW(){JW=F,RQn=new Z0n,_Qn=new lW,KQn=new nbn}function Lp(){Lp=F,mP=new Z,m_=new de,p_=new Z}function MM(n,e){if(n==null)throw M(new fp(e));return n}function TM(n){return!n.a&&(n.a=new q(Ye,n,10,11)),n.a}function ft(n){return!n.q&&(n.q=new q(Ss,n,11,10)),n.q}function H(n){return!n.s&&(n.s=new q(ku,n,21,17)),n.s}function Tge(n){return Se(n),PRn(new ie(ce(n.a.Kc(),new En)))}function Age(n,e){return wo(n),wo(e),xjn(u(n,22),u(e,22))}function nd(n,e,t){var i,r;i=PV(t),r=new TE(i),bf(n,e,r)}function MN(n,e,t,i,r,c){rk.call(this,n,e,t,i,r,c?-2:-1)}function qIn(n,e,t,i){gX.call(this,e,t),this.b=n,this.a=i}function UIn(n,e){Vfe.call(this,new iN(n)),this.a=n,this.b=e}function QW(n){this.b=n,this.c=n,n.e=null,n.c=null,this.a=1}function Sge(n){Fs();var e;e=u(n.g,10),e.n.a=n.d.c+e.d.b}function I4(){I4=F;var n,e;e=!$8e(),n=new X3,VK=e?new og:n}function TN(n){return Dn(),D(n,59)?new jD(n):new FC(n)}function AM(n){return D(n,16)?new $6(u(n,16)):obe(n.Kc())}function Pge(n){return new _Tn(n,n.e.Rd().gc()*n.c.Rd().gc())}function Ige(n){return new HTn(n,n.e.Rd().gc()*n.c.Rd().gc())}function YW(n){return n&&n.hashCode?n.hashCode():f0(n)}function AN(n,e){return e==null?!!wr(n.f,null):zbe(n.i,e)}function Oge(n,e){var t;return t=NX(n.a,e),t&&(e.d=null),t}function GIn(n,e,t){return n.f?n.f.ef(e,t):!1}function U7(n,e,t,i){$t(n.c[e.g],t.g,i),$t(n.c[t.g],e.g,i)}function SN(n,e,t,i){$t(n.c[e.g],e.g,t),$t(n.b[e.g],e.g,i)}function Dge(n,e,t){return $(R(t.a))<=n&&$(R(t.b))>=e}function zIn(n,e){this.g=n,this.d=A(T(Qh,1),b1,10,0,[e])}function XIn(n){this.c=n,this.b=new Ul(u(Se(new ebn),50))}function VIn(n){this.c=n,this.b=new Ul(u(Se(new nwn),50))}function WIn(n){this.b=n,this.a=new Ul(u(Se(new Lbn),50))}function JIn(){this.b=new ni,this.d=new Ct,this.e=new YG}function ZW(){this.c=new Li,this.d=new Li,this.e=new Li}function y0(){this.a=new Mu,this.b=(Co(3,mw),new Gc(3))}function Wl(n,e){this.e=n,this.a=ki,this.b=Qqn(e),this.c=e}function SM(n){this.c=n.c,this.d=n.d,this.b=n.b,this.a=n.a}function QIn(n,e,t,i,r,c){this.a=n,k$.call(this,e,t,i,r,c)}function YIn(n,e,t,i,r,c){this.a=n,k$.call(this,e,t,i,r,c)}function V1(n,e,t,i,r,c,s){return new GN(n.e,e,t,i,r,c,s)}function Lge(n,e,t){return t>=0&&An(n.substr(t,e.length),e)}function ZIn(n,e){return D(e,149)&&An(n.b,u(e,149).Pg())}function Nge(n,e){return n.a?e.Gh().Kc():u(e.Gh(),71).Ii()}function nOn(n,e){var t;return t=n.b.Qc(e),VDn(t,n.b.gc()),t}function G7(n,e){if(n==null)throw M(new fp(e));return n}function Hr(n){return n.u||(Zu(n),n.u=new LAn(n,n)),n.u}function PN(n){this.a=(Dn(),D(n,59)?new jD(n):new FC(n))}function au(n){var e;return e=u(Un(n,16),29),e||n.ii()}function PM(n,e){var t;return t=Xa(n.Rm),e==null?t:t+": "+e}function qo(n,e,t){return Fi(e,t,n.length),n.substr(e,t-e)}function eOn(n,e){HC.call(this),hQ(this),this.a=n,this.c=e}function $ge(n){n&&PM(n,n.ie())}function xge(n){_E(),y.setTimeout(function(){throw n},0)}function Fge(){return YT(),A(T(xun,1),G,436,0,[o_,$un])}function Bge(){return cT(),A(T(Bun,1),G,435,0,[Fun,s_])}function Rge(){return uT(),A(T(aon,1),G,432,0,[v_,vP])}function Kge(){return X4(),A(T(KZn,1),G,517,0,[aj,L_])}function _ge(){return ok(),A(T(xsn,1),G,487,0,[$sn,QP])}function Hge(){return bk(),A(T(Lsn,1),G,428,0,[WP,Dsn])}function qge(){return QM(),A(T(Msn,1),G,431,0,[Csn,V_])}function Uge(){return ak(),A(T(_hn,1),G,430,0,[UH,GH])}function Gge(){return Q6(),A(T(Oie,1),G,531,0,[Z8,Y8])}function zge(){return fh(),A(T(Bie,1),G,523,0,[gb,y1])}function Xge(){return Pf(),A(T(Kie,1),G,522,0,[Rd,Xf])}function Vge(){return af(),A(T(ere,1),G,528,0,[zw,Ea])}function Wge(){return KM(),A(T(Wsn,1),G,429,0,[fH,Vsn])}function Jge(){return GM(),A(T(A1n,1),G,490,0,[Nq,T1n])}function Qge(){return N$(),A(T(L1n,1),G,491,0,[O1n,D1n])}function Yge(){return FM(),A(T(xln,1),G,433,0,[dq,$ln])}function Zge(){return ZM(),A(T(Rln,1),G,434,0,[Bln,vq])}function n2e(){return E0(),A(T(sre,1),G,464,0,[Ca,I2])}function e2e(){return yT(),A(T(Fln,1),G,500,0,[RI,L2])}function t2e(){return tk(),A(T($1n,1),G,438,0,[Rq,JI])}function i2e(){return Ck(),A(T(ian,1),G,437,0,[YI,tan])}function r2e(){return RL(),A(T(dO,1),G,347,0,[mdn,vdn])}function IM(n,e,t,i){return t>=0?n.Uh(e,t,i):n.Ch(null,t,i)}function z7(n){return n.b.b==0?n.a.sf():UL(n.b)}function c2e(n){if(n.p!=5)throw M(new Cu);return Ae(n.f)}function u2e(n){if(n.p!=5)throw M(new Cu);return Ae(n.k)}function nJ(n){return x(n.a)===x((D$(),EU))&&rOe(n),n.a}function o2e(n,e){n.b=e,n.c>0&&n.b>0&&(n.g=rM(n.c,n.b,n.a))}function s2e(n,e){n.c=e,n.c>0&&n.b>0&&(n.g=rM(n.c,n.b,n.a))}function tOn(n,e){ufe(this,new V(n.a,n.b)),ofe(this,$7(e))}function j0(){Wfe.call(this,new ap(Qb(12))),RX(!0),this.a=2}function IN(n,e,t){nt(),Wd.call(this,n),this.b=e,this.a=t}function eJ(n,e,t){Ko(),DE.call(this,e),this.a=n,this.b=t}function iOn(n){var e;e=n.c.d.b,n.b=e,n.a=n.c.d,e.a=n.c.d.b=n}function f2e(n){return n.b==0?null:(oe(n.b!=0),Xo(n,n.a.a))}function Nc(n,e){return e==null?Kr(wr(n.f,null)):h6(n.i,e)}function rOn(n,e,t,i,r){return new rF(n,(F4(),i_),e,t,i,r)}function OM(n,e){return GDn(e),Lme(n,K(ye,_e,28,e,15,1),e)}function DM(n,e){return MM(n,"set1"),MM(e,"set2"),new XEn(n,e)}function h2e(n,e){var t=XK[n.charCodeAt(0)];return t??n}function cOn(n,e){var t,i;return t=e,i=new DO,LGn(n,t,i),i.d}function ON(n,e,t,i){var r;r=new xAn,e.a[t.g]=r,Pp(n.b,i,r)}function l2e(n,e){var t;return t=Ime(n.f,e),tt(_C(t),n.f.d)}function LM(n){var e;_me(n.a),aTn(n.a),e=new PE(n.a),_Y(e)}function a2e(n,e){_qn(n,!0),nu(n.e.Rf(),new LV(n,!0,e))}function d2e(n,e){return Lp(),n==At(Kh(e))||n==At(ra(e))}function b2e(n,e){return kl(),u(v(e,(lc(),Sh)),17).a==n}function wi(n){return Math.max(Math.min(n,et),-2147483648)|0}function uOn(n){this.a=u(Se(n),277),this.b=(Dn(),new zX(n))}function oOn(n,e,t){this.i=new Z,this.b=n,this.g=e,this.a=t}function tJ(n,e,t){this.a=new Z,this.e=n,this.f=e,this.c=t}function NM(n,e,t){this.c=new Z,this.e=n,this.f=e,this.b=t}function sOn(n){HC.call(this),hQ(this),this.a=n,this.c=!0}function w2e(n){function e(){}return e.prototype=n||{},new e}function g2e(n){if(n.Ae())return null;var e=n.n;return rP[e]}function X7(n){return n.Db>>16!=3?null:u(n.Cb,27)}function Sf(n){return n.Db>>16!=9?null:u(n.Cb,27)}function fOn(n){return n.Db>>16!=6?null:u(n.Cb,74)}function E0(){E0=F,Ca=new rX(s3,0),I2=new rX(f3,1)}function fh(){fh=F,gb=new eX(f3,0),y1=new eX(s3,1)}function Pf(){Pf=F,Rd=new tX(_B,0),Xf=new tX("UP",1)}function hOn(){hOn=F,oQn=Ce((BE(),A(T(uQn,1),G,549,0,[GK])))}function lOn(n){var e;return e=new GE(Qb(n.length)),nY(e,n),e}function aOn(n,e){return n.b+=e.b,n.c+=e.c,n.d+=e.d,n.a+=e.a,n}function p2e(n,e){return Yxn(n,e)?(V$n(n),!0):!1}function dl(n,e){if(e==null)throw M(new rp);return F8e(n,e)}function V7(n,e){var t;t=n.q.getHours(),n.q.setDate(e),K5(n,t)}function iJ(n,e,t){var i;i=n.Ih(e),i>=0?n.bi(i,t):nen(n,e,t)}function dOn(n,e){var t;return t=n.Ih(e),t>=0?n.Wh(t):hF(n,e)}function bOn(n,e){var t;for(Se(e),t=n.a;t;t=t.c)e.Yd(t.g,t.i)}function DN(n,e,t){var i;i=mFn(n,e,t),n.b=new ET(i.c.length)}function Sg(n,e,t){$M(),n&&Ve(kU,n,e),n&&Ve(fE,n,t)}function m2e(n,e){return XC(),_n(),u(e.a,17).a0}function rJ(n){var e;return e=n.d,e=n.bj(n.f),ve(n,e),e.Ob()}function wOn(n,e){var t;return t=new sW(e),KKn(t,n),new _u(t)}function y2e(n){if(n.p!=0)throw M(new Cu);return j6(n.f,0)}function j2e(n){if(n.p!=0)throw M(new Cu);return j6(n.k,0)}function gOn(n){return n.Db>>16!=7?null:u(n.Cb,241)}function O4(n){return n.Db>>16!=6?null:u(n.Cb,241)}function pOn(n){return n.Db>>16!=7?null:u(n.Cb,167)}function At(n){return n.Db>>16!=11?null:u(n.Cb,27)}function Gb(n){return n.Db>>16!=17?null:u(n.Cb,29)}function mOn(n){return n.Db>>16!=3?null:u(n.Cb,155)}function cJ(n){var e;return ta(n),e=new ni,ut(n,new C9n(e))}function vOn(n,e){var t=n.a=n.a||[];return t[e]||(t[e]=n.ve(e))}function E2e(n,e){var t;t=n.q.getHours(),n.q.setMonth(e),K5(n,t)}function kOn(n,e){$C(this),this.f=e,this.g=n,CM(this),this.je()}function yOn(n,e){this.a=n,this.c=Ki(this.a),this.b=new SM(e)}function jOn(n,e,t){this.a=e,this.c=n,this.b=(Se(t),new _u(t))}function EOn(n,e,t){this.a=e,this.c=n,this.b=(Se(t),new _u(t))}function COn(n){this.a=n,this.b=K(Sie,J,2043,n.e.length,0,2)}function MOn(){this.a=new rh,this.e=new ni,this.g=0,this.i=0}function $M(){$M=F,kU=new de,fE=new de,ple(MQn,new bvn)}function TOn(){TOn=F,aie=Pu(new ii,(Vi(),zr),(tr(),dj))}function uJ(){uJ=F,die=Pu(new ii,(Vi(),zr),(tr(),dj))}function AOn(){AOn=F,wie=Pu(new ii,(Vi(),zr),(tr(),dj))}function SOn(){SOn=F,Lie=Ke(new ii,(Vi(),zr),(tr(),O8))}function ko(){ko=F,xie=Ke(new ii,(Vi(),zr),(tr(),O8))}function POn(){POn=F,Fie=Ke(new ii,(Vi(),zr),(tr(),O8))}function NN(){NN=F,Hie=Ke(new ii,(Vi(),zr),(tr(),O8))}function X6(n,e,t,i,r,c){return new ml(n.e,e,n.Lj(),t,i,r,c)}function Dr(n,e,t){return e==null?Vc(n.f,null,t):L0(n.i,e,t)}function Zi(n,e){n.c&&du(n.c.g,n),n.c=e,n.c&&nn(n.c.g,n)}function $i(n,e){n.c&&du(n.c.a,n),n.c=e,n.c&&nn(n.c.a,n)}function ic(n,e){n.i&&du(n.i.j,n),n.i=e,n.i&&nn(n.i.j,n)}function Ii(n,e){n.d&&du(n.d.e,n),n.d=e,n.d&&nn(n.d.e,n)}function $N(n,e){n.a&&du(n.a.k,n),n.a=e,n.a&&nn(n.a.k,n)}function xN(n,e){n.b&&du(n.b.f,n),n.b=e,n.b&&nn(n.b.f,n)}function IOn(n,e){$we(n,n.b,n.c),u(n.b.b,68),e&&u(e.b,68).b}function C2e(n,e){return bt(u(n.c,65).c.e.b,u(e.c,65).c.e.b)}function M2e(n,e){return bt(u(n.c,65).c.e.a,u(e.c,65).c.e.a)}function T2e(n){return Y$(),_n(),u(n.a,86).d.e!=0}function xM(n,e){D(n.Cb,184)&&(u(n.Cb,184).tb=null),zc(n,e)}function FN(n,e){D(n.Cb,90)&&hw(Zu(u(n.Cb,90)),4),zc(n,e)}function A2e(n,e){DY(n,e),D(n.Cb,90)&&hw(Zu(u(n.Cb,90)),2)}function S2e(n,e){var t,i;t=e.c,i=t!=null,i&&Ip(n,new qb(e.c))}function OOn(n){var e,t;return t=(u4(),e=new Jd,e),R4(t,n),t}function DOn(n){var e,t;return t=(u4(),e=new Jd,e),R4(t,n),t}function LOn(n){for(var e;;)if(e=n.Pb(),!n.Ob())return e}function P2e(n,e,t){return nn(n.a,(kM(),Nx(e,t),new t0(e,t))),n}function $c(n,e){return dr(),a$(e)?new nM(e,n):new k7(e,n)}function W7(n){return dh(),Ec(n,0)>=0?ia(n):H6(ia(n1(n)))}function I2e(n){var e;return e=u(YC(n.b),9),new _o(n.a,e,n.c)}function NOn(n,e){var t;return t=u(tw(Dp(n.a),e),16),t?t.gc():0}function $On(n,e,t){var i;uBn(e,t,n.c.length),i=t-e,Sz(n.c,e,i)}function Jl(n,e,t){uBn(e,t,n.gc()),this.c=n,this.a=e,this.b=t-e}function Np(n){this.c=new Ct,this.b=n.b,this.d=n.c,this.a=n.a}function BN(n){this.a=y.Math.cos(n),this.b=y.Math.sin(n)}function ed(n,e,t,i){this.c=n,this.d=i,$N(this,e),xN(this,t)}function oJ(n,e){Xfe.call(this,new ap(Qb(n))),Co(e,Ozn),this.a=e}function xOn(n,e,t){return new rF(n,(F4(),t_),null,!1,e,t)}function FOn(n,e,t){return new rF(n,(F4(),r_),e,t,null,!1)}function O2e(){return Gu(),A(T(xr,1),G,108,0,[Nun,Yr,Aw])}function D2e(){return bu(),A(T(JQn,1),G,471,0,[kf,ma,Xs])}function L2e(){return Uu(),A(T(VQn,1),G,470,0,[Mh,pa,zs])}function N2e(){return wf(),A(T(Sw,1),G,237,0,[bc,Wc,wc])}function $2e(){return n5(),A(T(Aon,1),G,391,0,[E_,j_,C_])}function x2e(){return I0(),A(T(R_,1),G,372,0,[rb,va,ib])}function F2e(){return i5(),A(T(Asn,1),G,322,0,[L8,gj,Tsn])}function B2e(){return bT(),A(T(Psn,1),G,351,0,[Ssn,VP,W_])}function R2e(){return hd(),A(T(pne,1),G,459,0,[Y_,pv,m2])}function K2e(){return Y4(),A(T(sH,1),G,298,0,[uH,oH,pj])}function _2e(){return vl(),A(T(Mne,1),G,311,0,[mj,k2,E3])}function H2e(){return d5(),A(T(Ohn,1),G,390,0,[FH,Ihn,MI])}function q2e(){return gr(),A(T(cie,1),G,462,0,[W8,Vu,Jc])}function U2e(){return ST(),A(T(Uhn,1),G,387,0,[Hhn,zH,qhn])}function G2e(){return h5(),A(T(Ghn,1),G,349,0,[VH,XH,Pj])}function z2e(){return um(),A(T(Xhn,1),G,350,0,[WH,zhn,J8])}function X2e(){return dT(),A(T(Jhn,1),G,352,0,[Whn,JH,Vhn])}function V2e(){return DT(),A(T(Qhn,1),G,388,0,[QH,Iv,Gw])}function W2e(){return P0(),A(T(Tie,1),G,463,0,[Ij,Q8,PI])}function If(n){return cc(A(T(Ei,1),J,8,0,[n.i.n,n.n,n.a]))}function J2e(){return l5(),A(T(bln,1),G,392,0,[dln,nq,Dj])}function BOn(){BOn=F,Fre=Pu(new ii,(Qp(),e9),(B5(),rln))}function FM(){FM=F,dq=new cX("DFS",0),$ln=new cX("BFS",1)}function ROn(n,e,t){var i;i=new j3n,i.b=e,i.a=t,++e.b,nn(n.d,i)}function Q2e(n,e,t){var i;i=new rr(t.d),tt(i,n),OY(e,i.a,i.b)}function Y2e(n,e){DTn(n,Ae(vi(d0(e,24),YA)),Ae(vi(e,YA)))}function zb(n,e){if(n<0||n>e)throw M(new Ir(Atn+n+Stn+e))}function Ln(n,e){if(n<0||n>=e)throw M(new Ir(Atn+n+Stn+e))}function zn(n,e){if(n<0||n>=e)throw M(new wz(Atn+n+Stn+e))}function In(n,e){this.b=(Jn(n),n),this.a=e&vw?e:e|64|wh}function sJ(n){var e;return ta(n),e=(k0(),k0(),ZK),fT(n,e)}function Z2e(n,e,t){var i;return i=q5(n,e,!1),i.b<=e&&i.a<=t}function npe(){return nT(),A(T(I1n,1),G,439,0,[$q,P1n,S1n])}function epe(){return _T(),A(T(h1n,1),G,394,0,[f1n,Oq,s1n])}function tpe(){return XT(),A(T(o1n,1),G,445,0,[Fj,qI,Mq])}function ipe(){return rA(),A(T(bce,1),G,455,0,[Tq,Sq,Aq])}function rpe(){return Sk(),A(T(Hln,1),G,393,0,[KI,Kln,_ln])}function cpe(){return AT(),A(T(u1n,1),G,299,0,[Cq,c1n,r1n])}function upe(){return $f(),A(T(Yan,1),G,278,0,[xv,Jw,Fv])}function ope(){return Gp(),A(T(pdn,1),G,280,0,[gdn,Yw,aO])}function spe(){return jl(),A(T(hdn,1),G,346,0,[uO,M1,j9])}function fpe(){return Nk(),A(T(xq,1),G,444,0,[XI,VI,WI])}function C0(n){return Se(n),D(n,16)?new _u(u(n,16)):k4(n.Kc())}function fJ(n,e){return n&&n.equals?n.equals(e):x(n)===x(e)}function vi(n,e){return Y1(ewe(Vr(n)?ds(n):n,Vr(e)?ds(e):e))}function lf(n,e){return Y1(twe(Vr(n)?ds(n):n,Vr(e)?ds(e):e))}function RN(n,e){return Y1(iwe(Vr(n)?ds(n):n,Vr(e)?ds(e):e))}function hpe(n,e){var t;return t=(Jn(n),n).g,iV(!!t),Jn(e),t(e)}function KOn(n,e){var t,i;return i=E4(n,e),t=n.a.fd(i),new GEn(n,t)}function lpe(n){return n.Db>>16!=6?null:u(dF(n),241)}function ape(n){if(n.p!=2)throw M(new Cu);return Ae(n.f)&ui}function dpe(n){if(n.p!=2)throw M(new Cu);return Ae(n.k)&ui}function E(n){return oe(n.ai?1:0}function UOn(n,e){var t,i;return t=s$(e),i=t,u(ee(n.c,i),17).a}function KN(n,e,t){var i;i=n.d[e.p],n.d[e.p]=n.d[t.p],n.d[t.p]=i}function Cpe(n,e,t){var i;n.n&&e&&t&&(i=new cvn,nn(n.e,i))}function _N(n,e){if(fi(n.a,e),e.d)throw M(new ec(nXn));e.d=n}function aJ(n,e){this.a=new Z,this.d=new Z,this.f=n,this.c=e}function GOn(){this.c=new STn,this.a=new NLn,this.b=new zyn,hCn()}function zOn(){qp(),this.b=new de,this.a=new de,this.c=new Z}function XOn(n,e,t){this.d=n,this.j=e,this.e=t,this.o=-1,this.p=3}function VOn(n,e,t){this.d=n,this.k=e,this.f=t,this.o=-1,this.p=5}function WOn(n,e,t,i,r,c){aQ.call(this,n,e,t,i,r),c&&(this.o=-2)}function JOn(n,e,t,i,r,c){dQ.call(this,n,e,t,i,r),c&&(this.o=-2)}function QOn(n,e,t,i,r,c){IJ.call(this,n,e,t,i,r),c&&(this.o=-2)}function YOn(n,e,t,i,r,c){gQ.call(this,n,e,t,i,r),c&&(this.o=-2)}function ZOn(n,e,t,i,r,c){OJ.call(this,n,e,t,i,r),c&&(this.o=-2)}function nDn(n,e,t,i,r,c){bQ.call(this,n,e,t,i,r),c&&(this.o=-2)}function eDn(n,e,t,i,r,c){wQ.call(this,n,e,t,i,r),c&&(this.o=-2)}function tDn(n,e,t,i,r,c){DJ.call(this,n,e,t,i,r),c&&(this.o=-2)}function iDn(n,e,t,i){DE.call(this,t),this.b=n,this.c=e,this.d=i}function rDn(n,e){this.f=n,this.a=(N4(),MO),this.c=MO,this.b=e}function cDn(n,e){this.g=n,this.d=(N4(),TO),this.a=TO,this.b=e}function dJ(n,e){!n.c&&(n.c=new Rt(n,0)),HA(n.c,(at(),N9),e)}function Mpe(n,e){return oMe(n,e,D(e,102)&&(u(e,19).Bb&hr)!=0)}function Tpe(n,e){return RPn(vc(n.q.getTime()),vc(e.q.getTime()))}function uDn(n){return XL(n.e.Rd().gc()*n.c.Rd().gc(),16,new I8n(n))}function Ape(n){return!!n.u&&Sc(n.u.a).i!=0&&!(n.n&&Ix(n.n))}function Spe(n){return!!n.a&&no(n.a.a).i!=0&&!(n.b&&Ox(n.b))}function bJ(n,e){return e==0?!!n.o&&n.o.f!=0:Cx(n,e)}function Ppe(n,e,t){var i;return i=u(n.Zb().xc(e),16),!!i&&i.Hc(t)}function oDn(n,e,t){var i;return i=u(n.Zb().xc(e),16),!!i&&i.Mc(t)}function sDn(n,e){var t;return t=1-e,n.a[t]=jT(n.a[t],t),jT(n,e)}function fDn(n,e){var t,i;return i=vi(n,mr),t=Bs(e,32),lf(t,i)}function hDn(n,e,t){var i;i=(Se(n),new _u(n)),O7e(new jOn(i,e,t))}function J7(n,e,t){var i;i=(Se(n),new _u(n)),D7e(new EOn(i,e,t))}function fc(n,e,t,i,r,c){return _xn(n,e,t,c),EY(n,i),CY(n,r),n}function lDn(n,e,t,i){return n.a+=""+qo(e==null?gu:Jr(e),t,i),n}function xi(n,e){this.a=n,Gv.call(this,n),zb(e,n.gc()),this.b=e}function aDn(n){this.a=K(ki,Fn,1,JQ(y.Math.max(8,n))<<1,5,1)}function Q7(n){return u(Ff(n,K(Qh,b1,10,n.c.length,0,1)),199)}function hh(n){return u(Ff(n,K(O_,rR,18,n.c.length,0,1)),482)}function dDn(n){return n.a?n.e.length==0?n.a.a:n.a.a+(""+n.e):n.c}function V6(n){for(;n.d>0&&n.a[--n.d]==0;);n.a[n.d++]==0&&(n.e=0)}function bDn(n){return oe(n.b.b!=n.d.a),n.c=n.b=n.b.b,--n.a,n.c.c}function Ipe(n,e,t){n.a=e,n.c=t,n.b.a.$b(),vo(n.d),Ab(n.e.a.c,0)}function wDn(n,e){var t;n.e=new cz,t=aw(e),Yt(t,n.c),Iqn(n,t,0)}function ri(n,e,t,i){var r;r=new ZU,r.a=e,r.b=t,r.c=i,Fe(n.a,r)}function Q(n,e,t,i){var r;r=new ZU,r.a=e,r.b=t,r.c=i,Fe(n.b,r)}function gDn(n,e,t){if(n<0||et)throw M(new Ir(qje(n,e,t)))}function Y7(n,e){if(n<0||n>=e)throw M(new Ir(kEe(n,e)));return n}function Ope(n){if(!("stack"in n))try{throw n}catch{}return n}function Pg(n){return c6(),D(n.g,10)?u(n.g,10):null}function Dpe(n){return Ag(n).dc()?!1:(e1e(n,new Pr),!0)}function id(n){var e;return Vr(n)?(e=n,e==-0?0:e):X4e(n)}function pDn(n,e){return D(e,44)?xx(n.a,u(e,44)):!1}function mDn(n,e){return D(e,44)?xx(n.a,u(e,44)):!1}function vDn(n,e){return D(e,44)?xx(n.a,u(e,44)):!1}function wJ(n){var e;return X1(n),e=new D0n,lg(n.a,new y9n(e)),e}function gJ(){var n,e,t;return e=(t=(n=new Jd,n),t),nn(Zdn,e),e}function BM(n){var e;return X1(n),e=new L0n,lg(n.a,new j9n(e)),e}function Lpe(n,e){return n.a<=n.b?(e.Dd(n.a++),!0):!1}function kDn(n){P$.call(this,n,(F4(),e_),null,!1,null,!1)}function yDn(){yDn=F,SYn=Ce((QE(),A(T(con,1),G,488,0,[b_])))}function jDn(){jDn=F,Zhn=bIn(Y(1),Y(4)),Yhn=bIn(Y(1),Y(2))}function Npe(n,e){return new _L(e,O6(Ki(e.e),n,n),(_n(),!0))}function RM(n){return new Gc((Co(n,cB),oT(nr(nr(5,n),n/10|0))))}function $pe(n){return XL(n.e.Rd().gc()*n.c.Rd().gc(),273,new P8n(n))}function EDn(n){return u(Ff(n,K(FZn,DXn,12,n.c.length,0,1)),2042)}function xpe(n){return ko(),!fr(n)&&!(!fr(n)&&n.c.i.c==n.d.i.c)}function Fpe(n,e){return _p(),u(v(e,(lc(),O2)),17).a>=n.gc()}function W6(n,e){vLe(e,n),WV(n.d),WV(u(v(n,(cn(),mI)),214))}function HN(n,e){kLe(e,n),JV(n.d),JV(u(v(n,(cn(),mI)),214))}function Bpe(n,e,t){n.d&&du(n.d.e,n),n.d=e,n.d&&a0(n.d.e,t,n)}function Rpe(n,e,t){return t.f.c.length>0?CW(n.a,e,t):CW(n.b,e,t)}function Kpe(n,e,t){var i;i=i9e();try{return Aae(n,e,t)}finally{D3e(i)}}function M0(n,e){var t,i;return t=dl(n,e),i=null,t&&(i=t.pe()),i}function J6(n,e){var t,i;return t=dl(n,e),i=null,t&&(i=t.se()),i}function D4(n,e){var t,i;return t=Jb(n,e),i=null,t&&(i=t.se()),i}function bl(n,e){var t,i;return t=dl(n,e),i=null,t&&(i=wnn(t)),i}function _pe(n,e,t){var i;return i=bm(t),FA(n.g,i,e),FA(n.i,e,t),e}function pJ(n,e,t){this.d=new N7n(this),this.e=n,this.i=e,this.f=t}function CDn(n,e,t,i){this.e=null,this.c=n,this.d=e,this.a=t,this.b=i}function MDn(n,e,t,i){jTn(this),this.c=n,this.e=e,this.f=t,this.b=i}function mJ(n,e,t,i){this.d=n,this.n=e,this.g=t,this.o=i,this.p=-1}function TDn(n,e,t,i){return D(t,59)?new tAn(n,e,t,i):new mW(n,e,t,i)}function L4(n){return D(n,16)?u(n,16).dc():!n.Kc().Ob()}function ADn(n){if(n.e.g!=n.b)throw M(new Bo);return!!n.c&&n.d>0}function be(n){return oe(n.b!=n.d.c),n.c=n.b,n.b=n.b.a,++n.a,n.c.c}function vJ(n,e){Jn(e),$t(n.a,n.c,e),n.c=n.c+1&n.a.length-1,WRn(n)}function W1(n,e){Jn(e),n.b=n.b-1&n.a.length-1,$t(n.a,n.b,e),WRn(n)}function SDn(n){var e;e=n.Gh(),this.a=D(e,71)?u(e,71).Ii():e.Kc()}function Hpe(n){return new In(Ame(u(n.a.md(),16).gc(),n.a.ld()),16)}function PDn(){PDn=F,Gce=Ce((nC(),A(T(N1n,1),G,489,0,[Fq])))}function IDn(){IDn=F,Xce=Ce((eC(),A(T(zce,1),G,558,0,[Bq])))}function ODn(){ODn=F,lue=Ce((u6(),A(T(ean,1),G,539,0,[_j])))}function qpe(){return dd(),A(T(Oon,1),G,389,0,[Ow,Ion,P_,I_])}function Upe(){return F4(),A(T(lP,1),G,303,0,[e_,t_,i_,r_])}function Gpe(){return Vp(),A(T(EYn,1),G,332,0,[cj,rj,uj,oj])}function zpe(){return C5(),A(T(TYn,1),G,406,0,[sj,wP,gP,fj])}function Xpe(){return D0(),A(T(yYn,1),G,417,0,[ij,tj,a_,d_])}function Vpe(){return Z4(),A(T(MZn,1),G,416,0,[tb,Iw,Pw,d2])}function Wpe(){return xf(),A(T(ene,1),G,421,0,[j3,hv,lv,B_])}function Jpe(){return OT(),A(T(UZn,1),G,371,0,[F_,HP,qP,bj])}function Qpe(){return cw(),A(T(RH,1),G,203,0,[TI,BH,P2,S2])}function Ype(){return lh(),A(T(Khn,1),G,284,0,[k1,Rhn,HH,qH])}function Zpe(n){var e;return n.j==(en(),ae)&&(e=mHn(n),Au(e,Zn))}function n3e(n,e){var t;t=e.a,Zi(t,e.c.d),Ii(t,e.d.d),nw(t.a,n.n)}function kJ(n,e){var t;return t=u(Nf(n.b,e),67),!t&&(t=new Ct),t}function xp(n){return c6(),D(n.g,154)?u(n.g,154):null}function e3e(n){n.a=null,n.e=null,Ab(n.b.c,0),Ab(n.f.c,0),n.c=null}function KM(){KM=F,fH=new Yz(Hm,0),Vsn=new Yz("TOP_LEFT",1)}function Q6(){Q6=F,Z8=new nX("UPPER",0),Y8=new nX("LOWER",1)}function t3e(n,e){return vp(new V(e.e.a+e.f.a/2,e.e.b+e.f.b/2),n)}function DDn(n,e){return u(ho(_b(u(ot(n.k,e),15).Oc(),w2)),113)}function LDn(n,e){return u(ho(Ap(u(ot(n.k,e),15).Oc(),w2)),113)}function i3e(){return Qp(),A(T(tln,1),G,405,0,[LI,n9,e9,t9])}function r3e(){return a5(),A(T(Nln,1),G,353,0,[aq,BI,lq,hq])}function c3e(){return sA(),A(T(i1n,1),G,354,0,[Eq,e1n,t1n,n1n])}function u3e(){return go(),A(T(A9,1),G,386,0,[iE,Gd,tE,Qw])}function o3e(){return To(),A(T(Yue,1),G,290,0,[Zj,nl,Aa,Yj])}function s3e(){return El(),A(T(lU,1),G,223,0,[hU,Qj,Bv,x3])}function f3e(){return qT(),A(T(Edn,1),G,320,0,[bU,kdn,jdn,ydn])}function h3e(){return LT(),A(T(woe,1),G,415,0,[wU,Mdn,Cdn,Tdn])}function l3e(n){return $M(),Zc(kU,n)?u(ee(kU,n),341).Qg():null}function Uo(n,e,t){return e<0?hF(n,t):u(t,69).wk().Bk(n,n.hi(),e)}function a3e(n,e,t){var i;return i=bm(t),FA(n.j,i,e),Ve(n.k,e,t),e}function d3e(n,e,t){var i;return i=bm(t),FA(n.d,i,e),Ve(n.e,e,t),e}function NDn(n){var e,t;return e=(B1(),t=new HO,t),n&&AA(e,n),e}function yJ(n){var e;return e=n.aj(n.i),n.i>0&&Ic(n.g,0,e,0,n.i),e}function $Dn(n,e){var t;for(t=n.j.c.length;t>24}function w3e(n){if(n.p!=1)throw M(new Cu);return Ae(n.k)<<24>>24}function g3e(n){if(n.p!=7)throw M(new Cu);return Ae(n.k)<<16>>16}function p3e(n){if(n.p!=7)throw M(new Cu);return Ae(n.f)<<16>>16}function Ig(n,e){return e.e==0||n.e==0?T8:(Tm(),vF(n,e))}function BDn(n,e){return x(e)===x(n)?"(this Map)":e==null?gu:Jr(e)}function m3e(n,e,t){return tN(R(Kr(wr(n.f,e))),R(Kr(wr(n.f,t))))}function v3e(n,e,t){var i;i=u(ee(n.g,t),60),nn(n.a.c,new bi(e,i))}function RDn(n,e,t){n.i=0,n.e=0,e!=t&&(yFn(n,e,t),kFn(n,e,t))}function k3e(n,e,t,i,r){var c;c=yMe(r,t,i),nn(e,dEe(r,c)),rje(n,r,e)}function jJ(n,e,t,i,r){this.i=n,this.a=e,this.e=t,this.j=i,this.f=r}function KDn(n,e){ZW.call(this),this.a=n,this.b=e,nn(this.a.b,this)}function _Dn(n){this.b=new de,this.c=new de,this.d=new de,this.a=n}function HDn(n,e){var t;return t=new fg,n.Gd(t),t.a+="..",e.Hd(t),t.a}function qDn(n,e){var t;for(t=e;t;)h0(n,t.i,t.j),t=At(t);return n}function UDn(n,e,t){var i;return i=bm(t),Ve(n.b,i,e),Ve(n.c,e,t),e}function wl(n){var e;for(e=0;n.Ob();)n.Pb(),e=nr(e,1);return oT(e)}function Fh(n,e){dr();var t;return t=u(n,69).vk(),kje(t,e),t.xl(e)}function y3e(n,e,t){if(t){var i=t.oe();n.a[e]=i(t)}else delete n.a[e]}function EJ(n,e){var t;t=n.q.getHours(),n.q.setFullYear(e+ha),K5(n,t)}function j3e(n,e){return u(e==null?Kr(wr(n.f,null)):h6(n.i,e),288)}function CJ(n,e){return n==(Vn(),zt)&&e==zt?4:n==zt||e==zt?8:32}function _M(n,e,t){return RA(n,e,t,D(e,102)&&(u(e,19).Bb&hr)!=0)}function E3e(n,e,t){return Im(n,e,t,D(e,102)&&(u(e,19).Bb&hr)!=0)}function C3e(n,e,t){return bMe(n,e,t,D(e,102)&&(u(e,19).Bb&hr)!=0)}function MJ(n){n.b!=n.c&&(n.a=K(ki,Fn,1,8,5,1),n.b=0,n.c=0)}function Y6(n){return oe(n.a=0&&n.a[t]===e[t];t--);return t<0}function HM(n){var e;return n?new sW(n):(e=new rh,A$(e,n),e)}function O3e(n,e){var t,i;i=!1;do t=hFn(n,e),i=i|t;while(t);return i}function D3e(n){n&&rme((lz(),uun)),--cP,n&&uP!=-1&&(Ele(uP),uP=-1)}function qM(n){ZZ(),DTn(this,Ae(vi(d0(n,24),YA)),Ae(vi(n,YA)))}function WDn(){WDn=F,HQn=Ce((YT(),A(T(xun,1),G,436,0,[o_,$un])))}function JDn(){JDn=F,qQn=Ce((cT(),A(T(Bun,1),G,435,0,[Fun,s_])))}function QDn(){QDn=F,GYn=Ce((uT(),A(T(aon,1),G,432,0,[v_,vP])))}function YDn(){YDn=F,_Zn=Ce((X4(),A(T(KZn,1),G,517,0,[aj,L_])))}function ZDn(){ZDn=F,kne=Ce((ok(),A(T(xsn,1),G,487,0,[$sn,QP])))}function nLn(){nLn=F,gne=Ce((bk(),A(T(Lsn,1),G,428,0,[WP,Dsn])))}function eLn(){eLn=F,ane=Ce((QM(),A(T(Msn,1),G,431,0,[Csn,V_])))}function tLn(){tLn=F,rie=Ce((ak(),A(T(_hn,1),G,430,0,[UH,GH])))}function iLn(){iLn=F,Die=Ce((Q6(),A(T(Oie,1),G,531,0,[Z8,Y8])))}function rLn(){rLn=F,Rie=Ce((fh(),A(T(Bie,1),G,523,0,[gb,y1])))}function cLn(){cLn=F,_ie=Ce((Pf(),A(T(Kie,1),G,522,0,[Rd,Xf])))}function uLn(){uLn=F,tre=Ce((af(),A(T(ere,1),G,528,0,[zw,Ea])))}function oLn(){oLn=F,Ane=Ce((KM(),A(T(Wsn,1),G,429,0,[fH,Vsn])))}function sLn(){sLn=F,fre=Ce((E0(),A(T(sre,1),G,464,0,[Ca,I2])))}function fLn(){fLn=F,Ure=Ce((ZM(),A(T(Rln,1),G,434,0,[Bln,vq])))}function hLn(){hLn=F,xre=Ce((FM(),A(T(xln,1),G,433,0,[dq,$ln])))}function lLn(){lLn=F,_re=Ce((yT(),A(T(Fln,1),G,500,0,[RI,L2])))}function aLn(){aLn=F,Rce=Ce((GM(),A(T(A1n,1),G,490,0,[Nq,T1n])))}function dLn(){dLn=F,_ce=Ce((N$(),A(T(L1n,1),G,491,0,[O1n,D1n])))}function bLn(){bLn=F,Vce=Ce((tk(),A(T($1n,1),G,438,0,[Rq,JI])))}function wLn(){wLn=F,aue=Ce((Ck(),A(T(ian,1),G,437,0,[YI,tan])))}function gLn(){gLn=F,aoe=Ce((RL(),A(T(dO,1),G,347,0,[mdn,vdn])))}function L3e(){return ci(),A(T(k9,1),G,88,0,[Jf,Xr,Br,Wf,us])}function N3e(){return en(),A(T(lr,1),Mc,64,0,[sc,Xn,Zn,ae,Wn])}function $3e(n,e,t){return u(e==null?Vc(n.f,null,t):L0(n.i,e,t),288)}function x3e(n){return(n.k==(Vn(),zt)||n.k==Zt)&&kt(n,(W(),F8))}function XN(n){return n.c&&n.d?lJ(n.c)+"->"+lJ(n.d):"e_"+f0(n)}function qi(n,e){var t,i;for(Jn(e),i=n.Kc();i.Ob();)t=i.Pb(),e.Cd(t)}function F3e(n,e){var t;t=new sp,nd(t,"x",e.a),nd(t,"y",e.b),Ip(n,t)}function B3e(n,e){var t;t=new sp,nd(t,"x",e.a),nd(t,"y",e.b),Ip(n,t)}function pLn(n,e){var t;for(t=e;t;)h0(n,-t.i,-t.j),t=At(t);return n}function AJ(n,e){var t,i;for(t=e,i=0;t>0;)i+=n.a[t],t-=t&-t;return i}function Go(n,e,t){var i;return i=(Ln(e,n.c.length),n.c[e]),n.c[e]=t,i}function SJ(n,e,t){n.a.c.length=0,fOe(n,e,t),n.a.c.length==0||FSe(n,e)}function Z7(n){n.i=0,u7(n.b,null),u7(n.c,null),n.a=null,n.e=null,++n.g}function UM(){UM=F,Uf=!0,DQn=!1,LQn=!1,$Qn=!1,NQn=!1}function VN(n){UM(),!Uf&&(this.c=n,this.e=!0,this.a=new Z)}function mLn(n,e){this.c=0,this.b=e,_Mn.call(this,n,17493),this.a=this.c}function vLn(n){jzn(),Ayn(this),this.a=new Ct,oY(this,n),Fe(this.a,n)}function kLn(){pL(this),this.b=new V(St,St),this.a=new V(li,li)}function GM(){GM=F,Nq=new sX(iin,0),T1n=new sX("TARGET_WIDTH",1)}function Og(n,e){return(ta(n),o4(new Tn(n,new eQ(e,n.a)))).Bd(v3)}function R3e(){return Vi(),A(T(Son,1),G,367,0,[Vs,Jh,Oc,Kc,zr])}function K3e(){return ow(),A(T(ine,1),G,375,0,[wj,zP,XP,GP,UP])}function _3e(){return o1(),A(T(Osn,1),G,348,0,[J_,Isn,Q_,gv,wv])}function H3e(){return E5(),A(T(Lhn,1),G,323,0,[Dhn,KH,_H,X8,V8])}function q3e(){return Yo(),A(T(sfn,1),G,171,0,[jj,R8,ya,K8,xw])}function U3e(){return wA(),A(T(Hre,1),G,368,0,[pq,bq,mq,wq,gq])}function G3e(){return N5(),A(T(Hce,1),G,373,0,[N2,O3,a9,l9,Kj])}function z3e(){return Wk(),A(T(R1n,1),G,324,0,[x1n,Kq,B1n,_q,F1n])}function X3e(){return pf(),A(T(Zh,1),G,170,0,[xn,pi,Ph,Kd,E1])}function V3e(){return Bg(),A(T(C9,1),G,256,0,[Sa,nE,ldn,E9,adn])}function W3e(n){return _E(),function(){return Kpe(n,this,arguments)}}function fr(n){return!n.c||!n.d?!1:!!n.c.i&&n.c.i==n.d.i}function PJ(n,e){return D(e,143)?An(n.c,u(e,143).c):!1}function Zu(n){return n.t||(n.t=new pyn(n),p5(new Ljn(n),0,n.t)),n.t}function yLn(n){this.b=n,ne.call(this,n),this.a=u(Un(this.b.a,4),129)}function jLn(n){this.b=n,yp.call(this,n),this.a=u(Un(this.b.a,4),129)}function Rs(n,e,t,i,r){DLn.call(this,e,i,r),this.c=n,this.b=t}function IJ(n,e,t,i,r){XOn.call(this,e,i,r),this.c=n,this.a=t}function OJ(n,e,t,i,r){VOn.call(this,e,i,r),this.c=n,this.a=t}function DJ(n,e,t,i,r){DLn.call(this,e,i,r),this.c=n,this.a=t}function WN(n,e){var t;return t=u(Nf(n.d,e),23),t||u(Nf(n.e,e),23)}function ELn(n,e){var t,i;return t=e.ld(),i=n.Fe(t),!!i&&mc(i.e,e.md())}function CLn(n,e){var t;return t=e.ld(),new t0(t,n.e.pc(t,u(e.md(),16)))}function J3e(n,e){var t;return t=n.a.get(e),t??K(ki,Fn,1,0,5,1)}function MLn(n){var e;return e=n.length,An(Yn.substr(Yn.length-e,e),n)}function fe(n){if(pe(n))return n.c=n.a,n.a.Pb();throw M(new nc)}function LJ(n,e){return e==0||n.e==0?n:e>0?wqn(n,e):BBn(n,-e)}function Fp(n,e){return e==0||n.e==0?n:e>0?BBn(n,e):wqn(n,-e)}function NJ(n){ole.call(this,n==null?gu:Jr(n),D(n,82)?u(n,82):null)}function TLn(n){var e;return n.c||(e=n.r,D(e,90)&&(n.c=u(e,29))),n.c}function JN(n){var e;return e=new y0,Ur(e,n),U(e,(cn(),Fr),null),e}function ALn(n){var e,t;return e=n.c.i,t=n.d.i,e.k==(Vn(),Zt)&&t.k==Zt}function QN(n){var e,t,i;return e=n&ro,t=n>>22&ro,i=n<0?Il:0,Yc(e,t,i)}function Q3e(n){var e,t,i,r;for(t=n,i=0,r=t.length;i=0?n.Lh(i,t,!0):K0(n,e,t)}function Z3e(n,e,t){return bt(vp(gm(n),Ki(e.b)),vp(gm(n),Ki(t.b)))}function n4e(n,e,t){return bt(vp(gm(n),Ki(e.e)),vp(gm(n),Ki(t.e)))}function e4e(n,e){return y.Math.min(J1(e.a,n.d.d.c),J1(e.b,n.d.d.c))}function nk(n,e){n._i(n.i+1),S6(n,n.i,n.Zi(n.i,e)),n.Mi(n.i++,e),n.Ni()}function Z6(n){var e,t;++n.j,e=n.g,t=n.i,n.g=null,n.i=0,n.Oi(t,e),n.Ni()}function SLn(n,e,t){var i;i=new LX(n.a),u5(i,n.a.a),Vc(i.f,e,t),n.a.a=i}function $J(n,e,t,i){var r;for(r=0;re)throw M(new Ir(Enn(n,e,"index")));return n}function Yl(n,e){var t;return t=(Ln(e,n.c.length),n.c[e]),Sz(n.c,e,1),t}function BJ(n,e){var t,i;return t=(Jn(n),n),i=(Jn(e),e),t==i?0:te.p?-1:0}function xLn(n){var e;return n.a||(e=n.r,D(e,156)&&(n.a=u(e,156))),n.a}function o4e(n,e,t){var i;return++n.e,--n.f,i=u(n.d[e].gd(t),136),i.md()}function s4e(n){var e,t;return e=n.ld(),t=u(n.md(),16),N7(t.Nc(),new D8n(e))}function FLn(n,e){return Zc(n.a,e)?(Bp(n.a,e),!0):!1}function Rp(n,e,t){return Y7(e,n.e.Rd().gc()),Y7(t,n.c.Rd().gc()),n.a[e][t]}function XM(n,e,t){this.a=n,this.b=e,this.c=t,nn(n.t,this),nn(e.i,this)}function VM(n,e,t,i){this.f=n,this.e=e,this.d=t,this.b=i,this.c=i?i.d:null}function ek(){this.b=new Ct,this.a=new Ct,this.b=new Ct,this.a=new Ct}function N4(){N4=F;var n,e;MO=(u4(),e=new $E,e),TO=(n=new fD,n)}function f4e(n){var e;return ta(n),e=new PSn(n,n.a.e,n.a.d|4),new cV(n,e)}function BLn(n){var e;for(X1(n),e=0;n.a.Bd(new V0n);)e=nr(e,1);return e}function WM(n,e){return Jn(e),n.c=0,"Initial capacity must not be negative")}function JM(){JM=F,d9=new lt("org.eclipse.elk.labels.labelManager")}function RLn(){RLn=F,vsn=new Dt("separateLayerConnections",(OT(),F_))}function af(){af=F,zw=new iX("REGULAR",0),Ea=new iX("CRITICAL",1)}function tk(){tk=F,Rq=new hX("FIXED",0),JI=new hX("CENTER_NODE",1)}function QM(){QM=F,Csn=new Wz("QUADRATIC",0),V_=new Wz("SCANLINE",1)}function KLn(){KLn=F,dne=Ce((i5(),A(T(Asn,1),G,322,0,[L8,gj,Tsn])))}function _Ln(){_Ln=F,bne=Ce((bT(),A(T(Psn,1),G,351,0,[Ssn,VP,W_])))}function HLn(){HLn=F,mne=Ce((hd(),A(T(pne,1),G,459,0,[Y_,pv,m2])))}function qLn(){qLn=F,fne=Ce((I0(),A(T(R_,1),G,372,0,[rb,va,ib])))}function ULn(){ULn=F,Tne=Ce((vl(),A(T(Mne,1),G,311,0,[mj,k2,E3])))}function GLn(){GLn=F,Cne=Ce((Y4(),A(T(sH,1),G,298,0,[uH,oH,pj])))}function zLn(){zLn=F,Zte=Ce((d5(),A(T(Ohn,1),G,390,0,[FH,Ihn,MI])))}function XLn(){XLn=F,oie=Ce((ST(),A(T(Uhn,1),G,387,0,[Hhn,zH,qhn])))}function VLn(){VLn=F,sie=Ce((h5(),A(T(Ghn,1),G,349,0,[VH,XH,Pj])))}function WLn(){WLn=F,uie=Ce((gr(),A(T(cie,1),G,462,0,[W8,Vu,Jc])))}function JLn(){JLn=F,hie=Ce((dT(),A(T(Jhn,1),G,352,0,[Whn,JH,Vhn])))}function QLn(){QLn=F,fie=Ce((um(),A(T(Xhn,1),G,350,0,[WH,zhn,J8])))}function YLn(){YLn=F,lie=Ce((DT(),A(T(Qhn,1),G,388,0,[QH,Iv,Gw])))}function ZLn(){ZLn=F,are=Ce((l5(),A(T(bln,1),G,392,0,[dln,nq,Dj])))}function nNn(){nNn=F,Gre=Ce((Sk(),A(T(Hln,1),G,393,0,[KI,Kln,_ln])))}function eNn(){eNn=F,ace=Ce((AT(),A(T(u1n,1),G,299,0,[Cq,c1n,r1n])))}function tNn(){tNn=F,dce=Ce((XT(),A(T(o1n,1),G,445,0,[Fj,qI,Mq])))}function iNn(){iNn=F,wce=Ce((rA(),A(T(bce,1),G,455,0,[Tq,Sq,Aq])))}function rNn(){rNn=F,mce=Ce((_T(),A(T(h1n,1),G,394,0,[f1n,Oq,s1n])))}function cNn(){cNn=F,Kce=Ce((nT(),A(T(I1n,1),G,439,0,[$q,P1n,S1n])))}function uNn(){uNn=F,Aie=Ce((P0(),A(T(Tie,1),G,463,0,[Ij,Q8,PI])))}function oNn(){oNn=F,WQn=Ce((Uu(),A(T(VQn,1),G,470,0,[Mh,pa,zs])))}function sNn(){sNn=F,XQn=Ce((wf(),A(T(Sw,1),G,237,0,[bc,Wc,wc])))}function fNn(){fNn=F,QQn=Ce((bu(),A(T(JQn,1),G,471,0,[kf,ma,Xs])))}function hNn(){hNn=F,xQn=Ce((Gu(),A(T(xr,1),G,108,0,[Nun,Yr,Aw])))}function lNn(){lNn=F,pZn=Ce((n5(),A(T(Aon,1),G,391,0,[E_,j_,C_])))}function aNn(){aNn=F,Que=Ce((jl(),A(T(hdn,1),G,346,0,[uO,M1,j9])))}function dNn(){dNn=F,Uce=Ce((Nk(),A(T(xq,1),G,444,0,[XI,VI,WI])))}function bNn(){bNn=F,Xue=Ce(($f(),A(T(Yan,1),G,278,0,[xv,Jw,Fv])))}function wNn(){wNn=F,loe=Ce((Gp(),A(T(pdn,1),G,280,0,[gdn,Yw,aO])))}function Lf(n,e){return!n.o&&(n.o=new Iu((Cc(),il),T1,n,0)),wx(n.o,e)}function h4e(n,e){var t;n.C&&(t=u(Cr(n.b,e),127).n,t.d=n.C.d,t.a=n.C.a)}function qJ(n){var e,t,i,r;r=n.d,e=n.a,t=n.b,i=n.c,n.d=t,n.a=i,n.b=r,n.c=e}function l4e(n){return!n.g&&(n.g=new EE),!n.g.b&&(n.g.b=new dyn(n)),n.g.b}function ik(n){return!n.g&&(n.g=new EE),!n.g.c&&(n.g.c=new gyn(n)),n.g.c}function a4e(n){return!n.g&&(n.g=new EE),!n.g.d&&(n.g.d=new byn(n)),n.g.d}function d4e(n){return!n.g&&(n.g=new EE),!n.g.a&&(n.g.a=new wyn(n)),n.g.a}function b4e(n,e,t,i){return t&&(i=t.Rh(e,Ot(t.Dh(),n.c.uk()),null,i)),i}function w4e(n,e,t,i){return t&&(i=t.Th(e,Ot(t.Dh(),n.c.uk()),null,i)),i}function e$(n,e,t,i){var r;return r=K(ye,_e,28,e+1,15,1),vPe(r,n,e,t,i),r}function K(n,e,t,i,r,c){var s;return s=KRn(r,i),r!=10&&A(T(n,c),e,t,r,s),s}function g4e(n,e,t){var i,r;for(r=new Q4(e,n),i=0;it||e=0?n.Lh(t,!0,!0):K0(n,e,!0)}function L4e(n,e,t){var i;return i=mFn(n,e,t),n.b=new ET(i.c.length),len(n,i)}function N4e(n){if(n.b<=0)throw M(new nc);return--n.b,n.a-=n.c.c,Y(n.a)}function $4e(n){var e;if(!n.a)throw M(new SIn);return e=n.a,n.a=At(n.a),e}function x4e(n){for(;!n.a;)if(!nSn(n.c,new E9n(n)))return!1;return!0}function Kp(n){var e;return Se(n),D(n,204)?(e=u(n,204),e):new K8n(n)}function F4e(n){YM(),u(n.of((He(),Ww)),181).Fc((zu(),eE)),n.qf(oU,null)}function YM(){YM=F,wue=new jmn,pue=new Emn,gue=M6e((He(),oU),wue,Ta,pue)}function ZM(){ZM=F,Bln=new oX("LEAF_NUMBER",0),vq=new oX("NODE_SIZE",1)}function u$(n){n.a=K(ye,_e,28,n.b+1,15,1),n.c=K(ye,_e,28,n.b,15,1),n.d=0}function B4e(n,e){n.a.Ne(e.d,n.b)>0&&(nn(n.c,new UV(e.c,e.d,n.d)),n.b=e.d)}function ZJ(n,e){if(n.g==null||e>=n.i)throw M(new aL(e,n.i));return n.g[e]}function vNn(n,e,t){if(im(n,t),t!=null&&!n.fk(t))throw M(new uD);return t}function o$(n,e){return dk(e)!=10&&A(wo(e),e.Sm,e.__elementTypeId$,dk(e),n),n}function x4(n,e,t,i){var r;i=(k0(),i||Aun),r=n.slice(e,t),Cnn(r,n,e,t,-e,i)}function zo(n,e,t,i,r){return e<0?K0(n,t,i):u(t,69).wk().yk(n,n.hi(),e,i,r)}function R4e(n,e){return bt($(R(v(n,(W(),ob)))),$(R(v(e,ob))))}function kNn(){kNn=F,IQn=Ce((F4(),A(T(lP,1),G,303,0,[e_,t_,i_,r_])))}function F4(){F4=F,e_=new cC("All",0),t_=new hTn,i_=new vTn,r_=new fTn}function Uu(){Uu=F,Mh=new FD(s3,0),pa=new FD(Hm,1),zs=new FD(f3,2)}function yNn(){yNn=F,KA(),o0n=St,mse=li,s0n=new G9(St),vse=new G9(li)}function jNn(){jNn=F,jYn=Ce((D0(),A(T(yYn,1),G,417,0,[ij,tj,a_,d_])))}function ENn(){ENn=F,AYn=Ce((C5(),A(T(TYn,1),G,406,0,[sj,wP,gP,fj])))}function CNn(){CNn=F,CYn=Ce((Vp(),A(T(EYn,1),G,332,0,[cj,rj,uj,oj])))}function MNn(){MNn=F,DZn=Ce((dd(),A(T(Oon,1),G,389,0,[Ow,Ion,P_,I_])))}function TNn(){TNn=F,TZn=Ce((Z4(),A(T(MZn,1),G,416,0,[tb,Iw,Pw,d2])))}function ANn(){ANn=F,tne=Ce((xf(),A(T(ene,1),G,421,0,[j3,hv,lv,B_])))}function SNn(){SNn=F,GZn=Ce((OT(),A(T(UZn,1),G,371,0,[F_,HP,qP,bj])))}function PNn(){PNn=F,nie=Ce((cw(),A(T(RH,1),G,203,0,[TI,BH,P2,S2])))}function INn(){INn=F,iie=Ce((lh(),A(T(Khn,1),G,284,0,[k1,Rhn,HH,qH])))}function ok(){ok=F,$sn=new Qz(kh,0),QP=new Qz("IMPROVE_STRAIGHTNESS",1)}function ONn(n,e){var t,i;return i=e/n.c.Rd().gc()|0,t=e%n.c.Rd().gc(),Rp(n,i,t)}function DNn(n){var e;if(n.nl())for(e=n.i-1;e>=0;--e)L(n,e);return yJ(n)}function nQ(n){var e,t;if(!n.b)return null;for(t=n.b;e=t.a[0];)t=e;return t}function LNn(n){var e,t;if(!n.b)return null;for(t=n.b;e=t.a[1];)t=e;return t}function K4e(n){return D(n,180)?""+u(n,180).a:n==null?null:Jr(n)}function _4e(n){return D(n,180)?""+u(n,180).a:n==null?null:Jr(n)}function NNn(n,e){if(e.a)throw M(new ec(nXn));fi(n.a,e),e.a=n,!n.j&&(n.j=e)}function eQ(n,e){PC.call(this,e.zd(),e.yd()&-16449),Jn(n),this.a=n,this.c=e}function H4e(n,e){return new _L(e,h0(Ki(e.e),e.f.a+n,e.f.b+n),(_n(),!1))}function q4e(n,e){return v4(),nn(n,new bi(e,Y(e.e.c.length+e.g.c.length)))}function U4e(n,e){return v4(),nn(n,new bi(e,Y(e.e.c.length+e.g.c.length)))}function $Nn(){$Nn=F,lce=Ce((sA(),A(T(i1n,1),G,354,0,[Eq,e1n,t1n,n1n])))}function xNn(){xNn=F,$re=Ce((a5(),A(T(Nln,1),G,353,0,[aq,BI,lq,hq])))}function FNn(){FNn=F,hre=Ce((Qp(),A(T(tln,1),G,405,0,[LI,n9,e9,t9])))}function BNn(){BNn=F,Vue=Ce((El(),A(T(lU,1),G,223,0,[hU,Qj,Bv,x3])))}function RNn(){RNn=F,Zue=Ce((To(),A(T(Yue,1),G,290,0,[Zj,nl,Aa,Yj])))}function KNn(){KNn=F,foe=Ce((go(),A(T(A9,1),G,386,0,[iE,Gd,tE,Qw])))}function _Nn(){_Nn=F,doe=Ce((qT(),A(T(Edn,1),G,320,0,[bU,kdn,jdn,ydn])))}function HNn(){HNn=F,goe=Ce((LT(),A(T(woe,1),G,415,0,[wU,Mdn,Cdn,Tdn])))}function nT(){nT=F,$q=new oL(mVn,0),P1n=new oL(jrn,1),S1n=new oL(kh,2)}function Wb(n,e,t,i,r){return Jn(n),Jn(e),Jn(t),Jn(i),Jn(r),new TW(n,e,i)}function qNn(n,e){var t;return t=u(Bp(n.e,e),400),t?(eW(t),t.e):null}function du(n,e){var t;return t=qr(n,e,0),t==-1?!1:(Yl(n,t),!0)}function UNn(n,e,t){var i;return X1(n),i=new LO,i.a=e,n.a.Nb(new MCn(i,t)),i.a}function G4e(n){var e;return X1(n),e=K(Pi,Tr,28,0,15,1),lg(n.a,new k9n(e)),e}function tQ(n){var e;if(!E$(n))throw M(new nc);return n.e=1,e=n.d,n.d=null,e}function n1(n){var e;return Vr(n)&&(e=0-n,!isNaN(e))?e:Y1(em(n))}function qr(n,e,t){for(;t=0?tA(n,t,!0,!0):K0(n,e,!0)}function rQ(n){var e;return e=cd(Un(n,32)),e==null&&(iu(n),e=cd(Un(n,32))),e}function cQ(n){var e;return n.Oh()||(e=se(n.Dh())-n.ji(),n.$h().Mk(e)),n.zh()}function JNn(n,e){ion=new vE,MYn=e,S8=n,u(S8.b,68),zJ(S8,ion,null),aGn(S8)}function n5(){n5=F,E_=new RD("XY",0),j_=new RD("X",1),C_=new RD("Y",2)}function bu(){bu=F,kf=new BD("TOP",0),ma=new BD(Hm,1),Xs=new BD($tn,2)}function vl(){vl=F,mj=new GD(kh,0),k2=new GD("TOP",1),E3=new GD($tn,2)}function ak(){ak=F,UH=new Zz("INPUT_ORDER",0),GH=new Zz("PORT_DEGREE",1)}function B4(){B4=F,sun=Yc(ro,ro,524287),bQn=Yc(0,0,My),fun=QN(1),QN(2),hun=QN(0)}function a$(n){var e;return n.d!=n.r&&(e=gs(n),n.e=!!e&&e.lk()==bJn,n.d=e),n.e}function d$(n,e,t){var i;return i=n.g[e],S6(n,e,n.Zi(e,t)),n.Ri(e,t,i),n.Ni(),i}function rT(n,e){var t;return t=n.dd(e),t>=0?(n.gd(t),!0):!1}function b$(n,e){var t;for(Se(n),Se(e),t=!1;e.Ob();)t=t|n.Fc(e.Pb());return t}function Nf(n,e){var t;return t=u(ee(n.e,e),400),t?(OTn(n,t),t.e):null}function QNn(n){var e,t;return e=n/60|0,t=n%60,t==0?""+e:""+e+":"+(""+t)}function Jb(n,e){var t=n.a[e],i=(K$(),WK)[typeof t];return i?i(t):bY(typeof t)}function rc(n,e){var t,i;return ta(n),i=new KJ(e,n.a),t=new iSn(i),new Tn(n,t)}function w$(n){var e;return e=n.b.c.length==0?null:sn(n.b,0),e!=null&&M$(n,0),e}function W4e(n,e){var t,i,r;r=e.c.i,t=u(ee(n.f,r),60),i=t.d.c-t.e.c,FQ(e.a,i,0)}function uQ(n,e){var t;for(++n.d,++n.c[e],t=e+1;t0&&arguments[0]!==void 0?arguments[0]:{},Yi=Xe.defaultLayoutOptions,Ri=Yi===void 0?{}:Yi,En=Xe.algorithms,hu=En===void 0?["layered","stress","mrtree","radial","force","disco","sporeOverlap","sporeCompaction","rectpacking"]:En,Qc=Xe.workerFactory,Ru=Xe.workerUrl;if(y(this,Ht),this.defaultLayoutOptions=Ri,this.initialized=!1,typeof Ru>"u"&&typeof Qc>"u")throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");var Pr=Qc;typeof Ru<"u"&&typeof Qc>"u"&&(Pr=function(N1){return new Worker(N1)});var Mf=Pr(Ru);if(typeof Mf.postMessage!="function")throw new TypeError("Created worker does not provide the required 'postMessage' function.");this.worker=new Bu(Mf),this.worker.postMessage({cmd:"register",algorithms:hu}).then(function(L1){return Jt.initialized=!0}).catch(console.err)}return Di(Ht,[{key:"layout",value:function(Xe){var Yi=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},Ri=Yi.layoutOptions,En=Ri===void 0?this.defaultLayoutOptions:Ri,hu=Yi.logging,Qc=hu===void 0?!1:hu,Ru=Yi.measureExecutionTime,Pr=Ru===void 0?!1:Ru;return Xe?this.worker.postMessage({cmd:"layout",graph:Xe,layoutOptions:En,options:{logging:Qc,measureExecutionTime:Pr}}):Promise.reject(new Error("Missing mandatory parameter 'graph'."))}},{key:"knownLayoutAlgorithms",value:function(){return this.worker.postMessage({cmd:"algorithms"})}},{key:"knownLayoutOptions",value:function(){return this.worker.postMessage({cmd:"options"})}},{key:"knownLayoutCategories",value:function(){return this.worker.postMessage({cmd:"categories"})}},{key:"terminateWorker",value:function(){this.worker.terminate()}}]),Ht}();Sr.default=Wt;var Bu=function(){function Ht(Jt){var Xe=this;if(y(this,Ht),Jt===void 0)throw new Error("Missing mandatory parameter 'worker'.");this.resolvers={},this.worker=Jt,this.worker.onmessage=function(Yi){setTimeout(function(){Xe.receive(Xe,Yi)},0)}}return Di(Ht,[{key:"postMessage",value:function(Xe){var Yi=this.id||0;this.id=Yi+1,Xe.id=Yi;var Ri=this;return new Promise(function(En,hu){Ri.resolvers[Yi]=function(Qc,Ru){Qc?(Ri.convertGwtStyleError(Qc),hu(Qc)):En(Ru)},Ri.worker.postMessage(Xe)})}},{key:"receive",value:function(Xe,Yi){var Ri=Yi.data,En=Xe.resolvers[Ri.id];En&&(delete Xe.resolvers[Ri.id],Ri.error?En(Ri.error):En(null,Ri.data))}},{key:"terminate",value:function(){this.worker.terminate&&this.worker.terminate()}},{key:"convertGwtStyleError",value:function(Xe){if(Xe){var Yi=Xe.__java$exception;Yi&&(Yi.cause&&Yi.cause.backingJsObject&&(Xe.cause=Yi.cause.backingJsObject,this.convertGwtStyleError(Xe.cause)),delete Xe.__java$exception)}}}]),Ht}()},{}],2:[function(Xt,gt,Sr){(function(Di){(function(){var y;typeof window<"u"?y=window:typeof Di<"u"?y=Di:typeof self<"u"&&(y=self);var Wt;function Bu(){}function Ht(){}function Jt(){}function Xe(){}function Yi(){}function Ri(){}function En(){}function hu(){}function Qc(){}function Ru(){}function Pr(){}function Mf(){}function L1(){}function N1(){}function og(){}function X3(){}function $1(){}function ul(){}function E0n(){}function C0n(){}function Q2(){}function F(){}function M0n(){}function pE(){}function T0n(){}function A0n(){}function S0n(){}function P0n(){}function I0n(){}function xU(){}function O0n(){}function D0n(){}function L0n(){}function OO(){}function N0n(){}function $0n(){}function x0n(){}function DO(){}function F0n(){}function B0n(){}function FU(){}function R0n(){}function K0n(){}function yu(){}function ju(){}function Y2(){}function Z2(){}function _0n(){}function H0n(){}function q0n(){}function U0n(){}function BU(){}function Eu(){}function np(){}function ep(){}function G0n(){}function z0n(){}function LO(){}function X0n(){}function V0n(){}function W0n(){}function J0n(){}function Q0n(){}function Y0n(){}function Z0n(){}function nbn(){}function ebn(){}function tbn(){}function ibn(){}function rbn(){}function cbn(){}function ubn(){}function obn(){}function sbn(){}function fbn(){}function hbn(){}function lbn(){}function abn(){}function dbn(){}function bbn(){}function wbn(){}function gbn(){}function pbn(){}function mbn(){}function vbn(){}function kbn(){}function ybn(){}function jbn(){}function Ebn(){}function Cbn(){}function Mbn(){}function RU(){}function Tbn(){}function Abn(){}function Sbn(){}function Pbn(){}function NO(){}function $O(){}function mE(){}function Ibn(){}function Obn(){}function xO(){}function Dbn(){}function Lbn(){}function Nbn(){}function vE(){}function $bn(){}function xbn(){}function Fbn(){}function Bbn(){}function Rbn(){}function Kbn(){}function _bn(){}function Hbn(){}function qbn(){}function KU(){}function Ubn(){}function Gbn(){}function _U(){}function zbn(){}function Xbn(){}function Vbn(){}function Wbn(){}function Jbn(){}function Qbn(){}function Ybn(){}function Zbn(){}function nwn(){}function ewn(){}function twn(){}function iwn(){}function rwn(){}function FO(){}function cwn(){}function uwn(){}function own(){}function swn(){}function fwn(){}function hwn(){}function lwn(){}function awn(){}function dwn(){}function HU(){}function qU(){}function bwn(){}function wwn(){}function gwn(){}function pwn(){}function mwn(){}function vwn(){}function kwn(){}function ywn(){}function jwn(){}function Ewn(){}function Cwn(){}function Mwn(){}function Twn(){}function Awn(){}function Swn(){}function Pwn(){}function Iwn(){}function Own(){}function Dwn(){}function Lwn(){}function Nwn(){}function $wn(){}function xwn(){}function Fwn(){}function Bwn(){}function Rwn(){}function Kwn(){}function _wn(){}function Hwn(){}function qwn(){}function Uwn(){}function Gwn(){}function zwn(){}function Xwn(){}function Vwn(){}function Wwn(){}function Jwn(){}function Qwn(){}function Ywn(){}function Zwn(){}function ngn(){}function egn(){}function tgn(){}function ign(){}function rgn(){}function cgn(){}function ugn(){}function ogn(){}function sgn(){}function fgn(){}function hgn(){}function lgn(){}function agn(){}function dgn(){}function bgn(){}function wgn(){}function ggn(){}function pgn(){}function mgn(){}function vgn(){}function kgn(){}function ygn(){}function jgn(){}function Egn(){}function Cgn(){}function Mgn(){}function Tgn(){}function Agn(){}function Sgn(){}function Pgn(){}function Ign(){}function Ogn(){}function Dgn(){}function Lgn(){}function Ngn(){}function $gn(){}function xgn(){}function Fgn(){}function Bgn(){}function Rgn(){}function Kgn(){}function _gn(){}function Hgn(){}function qgn(){}function Ugn(){}function Ggn(){}function zgn(){}function Xgn(){}function Vgn(){}function Wgn(){}function Jgn(){}function Qgn(){}function Ygn(){}function Zgn(){}function n2n(){}function e2n(){}function t2n(){}function i2n(){}function r2n(){}function c2n(){}function UU(){}function u2n(){}function o2n(){}function s2n(){}function f2n(){}function h2n(){}function l2n(){}function a2n(){}function d2n(){}function b2n(){}function w2n(){}function g2n(){}function p2n(){}function m2n(){}function v2n(){}function k2n(){}function y2n(){}function j2n(){}function E2n(){}function C2n(){}function M2n(){}function T2n(){}function A2n(){}function S2n(){}function P2n(){}function I2n(){}function O2n(){}function D2n(){}function L2n(){}function N2n(){}function $2n(){}function x2n(){}function F2n(){}function B2n(){}function R2n(){}function K2n(){}function _2n(){}function H2n(){}function q2n(){}function U2n(){}function G2n(){}function z2n(){}function X2n(){}function V2n(){}function W2n(){}function J2n(){}function Q2n(){}function Y2n(){}function Z2n(){}function npn(){}function epn(){}function tpn(){}function ipn(){}function rpn(){}function cpn(){}function upn(){}function opn(){}function spn(){}function fpn(){}function hpn(){}function lpn(){}function apn(){}function dpn(){}function bpn(){}function wpn(){}function gpn(){}function ppn(){}function mpn(){}function vpn(){}function kpn(){}function ypn(){}function jpn(){}function Epn(){}function Cpn(){}function GU(){}function Mpn(){}function Tpn(){}function Apn(){}function Spn(){}function Ppn(){}function Ipn(){}function Opn(){}function Dpn(){}function Lpn(){}function Npn(){}function zU(){}function $pn(){}function xpn(){}function Fpn(){}function Bpn(){}function Rpn(){}function Kpn(){}function XU(){}function VU(){}function _pn(){}function WU(){}function JU(){}function Hpn(){}function qpn(){}function Upn(){}function Gpn(){}function zpn(){}function Xpn(){}function Vpn(){}function Wpn(){}function Jpn(){}function Qpn(){}function Ypn(){}function QU(){}function Zpn(){}function n3n(){}function e3n(){}function t3n(){}function i3n(){}function r3n(){}function c3n(){}function u3n(){}function o3n(){}function s3n(){}function f3n(){}function h3n(){}function l3n(){}function a3n(){}function d3n(){}function b3n(){}function w3n(){}function g3n(){}function p3n(){}function m3n(){}function v3n(){}function k3n(){}function y3n(){}function j3n(){}function E3n(){}function C3n(){}function M3n(){}function T3n(){}function A3n(){}function S3n(){}function P3n(){}function I3n(){}function O3n(){}function D3n(){}function L3n(){}function N3n(){}function $3n(){}function x3n(){}function F3n(){}function B3n(){}function R3n(){}function K3n(){}function _3n(){}function H3n(){}function q3n(){}function U3n(){}function G3n(){}function z3n(){}function X3n(){}function V3n(){}function W3n(){}function J3n(){}function Q3n(){}function Y3n(){}function Z3n(){}function n4n(){}function e4n(){}function t4n(){}function i4n(){}function r4n(){}function c4n(){}function u4n(){}function o4n(){}function s4n(){}function f4n(){}function h4n(){}function l4n(){}function a4n(){}function d4n(){}function b4n(){}function w4n(){}function g4n(){}function p4n(){}function m4n(){}function v4n(){}function k4n(){}function y4n(){}function j4n(){}function E4n(){}function C4n(){}function M4n(){}function T4n(){}function A4n(){}function S4n(){}function P4n(){}function I4n(){}function _se(){}function O4n(){}function D4n(){}function L4n(){}function N4n(){}function $4n(){}function x4n(){}function F4n(){}function B4n(){}function R4n(){}function K4n(){}function _4n(){}function H4n(){}function q4n(){}function U4n(){}function G4n(){}function z4n(){}function X4n(){}function V4n(){}function W4n(){}function J4n(){}function Q4n(){}function Y4n(){}function Z4n(){}function nmn(){}function emn(){}function tmn(){}function imn(){}function BO(){}function RO(){}function rmn(){}function KO(){}function cmn(){}function umn(){}function omn(){}function smn(){}function fmn(){}function hmn(){}function lmn(){}function amn(){}function dmn(){}function bmn(){}function YU(){}function wmn(){}function gmn(){}function pmn(){}function Hse(){}function mmn(){}function vmn(){}function kmn(){}function ymn(){}function jmn(){}function Emn(){}function Cmn(){}function Ka(){}function Mmn(){}function tp(){}function ZU(){}function Tmn(){}function Amn(){}function Smn(){}function Pmn(){}function Imn(){}function Omn(){}function Dmn(){}function Lmn(){}function Nmn(){}function $mn(){}function xmn(){}function Fmn(){}function Bmn(){}function Rmn(){}function Kmn(){}function _mn(){}function Hmn(){}function qmn(){}function Umn(){}function hn(){}function Gmn(){}function zmn(){}function Xmn(){}function Vmn(){}function Wmn(){}function Jmn(){}function Qmn(){}function Ymn(){}function Zmn(){}function nvn(){}function evn(){}function tvn(){}function ivn(){}function _O(){}function rvn(){}function cvn(){}function uvn(){}function kE(){}function ovn(){}function HO(){}function yE(){}function svn(){}function nG(){}function fvn(){}function hvn(){}function lvn(){}function avn(){}function dvn(){}function bvn(){}function jE(){}function wvn(){}function gvn(){}function EE(){}function pvn(){}function CE(){}function mvn(){}function eG(){}function vvn(){}function qO(){}function tG(){}function kvn(){}function yvn(){}function jvn(){}function Evn(){}function qse(){}function Cvn(){}function Mvn(){}function Tvn(){}function Avn(){}function Svn(){}function Pvn(){}function Ivn(){}function Ovn(){}function Dvn(){}function Lvn(){}function V3(){}function UO(){}function Nvn(){}function $vn(){}function xvn(){}function Fvn(){}function Bvn(){}function Rvn(){}function Kvn(){}function _vn(){}function Hvn(){}function qvn(){}function Uvn(){}function Gvn(){}function zvn(){}function Xvn(){}function Vvn(){}function Wvn(){}function Jvn(){}function Qvn(){}function Yvn(){}function Zvn(){}function n6n(){}function e6n(){}function t6n(){}function i6n(){}function r6n(){}function c6n(){}function u6n(){}function o6n(){}function s6n(){}function f6n(){}function h6n(){}function l6n(){}function a6n(){}function d6n(){}function b6n(){}function w6n(){}function g6n(){}function p6n(){}function m6n(){}function v6n(){}function k6n(){}function y6n(){}function j6n(){}function E6n(){}function C6n(){}function M6n(){}function T6n(){}function A6n(){}function S6n(){}function P6n(){}function I6n(){}function O6n(){}function D6n(){}function L6n(){}function N6n(){}function $6n(){}function x6n(){}function F6n(){}function B6n(){}function R6n(){}function K6n(){}function _6n(){}function H6n(){}function q6n(){}function U6n(){}function G6n(){}function z6n(){}function X6n(){}function V6n(){}function W6n(){}function J6n(){}function Q6n(){}function Y6n(){}function Z6n(){}function n5n(){}function e5n(){}function t5n(){}function i5n(){}function r5n(){}function c5n(){}function u5n(){}function o5n(){}function s5n(){}function f5n(){}function h5n(){}function l5n(){}function a5n(){}function d5n(){}function b5n(){}function w5n(){}function g5n(){}function p5n(){}function m5n(){}function v5n(){}function k5n(){}function y5n(){}function j5n(){}function E5n(){}function C5n(){}function M5n(){}function T5n(){}function iG(){}function A5n(){}function S5n(){}function GO(){Qv()}function P5n(){r7()}function I5n(){aA()}function O5n(){Q$()}function D5n(){j5()}function L5n(){lnn()}function N5n(){Us()}function $5n(){yZ()}function x5n(){qk()}function F5n(){c7()}function B5n(){L7()}function R5n(){lCn()}function K5n(){Hp()}function _5n(){RLn()}function H5n(){kQ()}function q5n(){AOn()}function U5n(){yQ()}function G5n(){gNn()}function z5n(){TOn()}function X5n(){rm()}function V5n(){Z$n()}function W5n(){Y$n()}function J5n(){jDn()}function Q5n(){nxn()}function Y5n(){ua()}function Z5n(){YE()}function n8n(){ftn()}function e8n(){cn()}function t8n(){exn()}function i8n(){Sxn()}function r8n(){SOn()}function c8n(){ZRn()}function u8n(){POn()}function o8n(){bUn()}function s8n(){_nn()}function f8n(){kl()}function h8n(){bBn()}function l8n(){lc()}function a8n(){BOn()}function d8n(){_p()}function b8n(){Een()}function w8n(){oa()}function g8n(){Cen()}function p8n(){Rf()}function m8n(){Vk()}function v8n(){EF()}function k8n(){Dx()}function uf(){bSn()}function y8n(){YM()}function j8n(){mA()}function rG(){He()}function E8n(){NT()}function C8n(){QY()}function cG(){D$()}function uG(){KA()}function M8n(){$en()}function oG(n){Jn(n)}function T8n(n){this.a=n}function ME(n){this.a=n}function A8n(n){this.a=n}function S8n(n){this.a=n}function P8n(n){this.a=n}function I8n(n){this.a=n}function O8n(n){this.a=n}function D8n(n){this.a=n}function sG(n){this.a=n}function fG(n){this.a=n}function L8n(n){this.a=n}function N8n(n){this.a=n}function zO(n){this.a=n}function $8n(n){this.a=n}function x8n(n){this.a=n}function XO(n){this.a=n}function VO(n){this.a=n}function F8n(n){this.a=n}function WO(n){this.a=n}function B8n(n){this.a=n}function R8n(n){this.a=n}function K8n(n){this.a=n}function hG(n){this.b=n}function _8n(n){this.c=n}function H8n(n){this.a=n}function q8n(n){this.a=n}function U8n(n){this.a=n}function G8n(n){this.a=n}function z8n(n){this.a=n}function X8n(n){this.a=n}function V8n(n){this.a=n}function W8n(n){this.a=n}function J8n(n){this.a=n}function Q8n(n){this.a=n}function Y8n(n){this.a=n}function Z8n(n){this.a=n}function n9n(n){this.a=n}function lG(n){this.a=n}function aG(n){this.a=n}function TE(n){this.a=n}function q9(n){this.a=n}function _a(){this.a=[]}function e9n(n,e){n.a=e}function Use(n,e){n.a=e}function Gse(n,e){n.b=e}function zse(n,e){n.b=e}function Xse(n,e){n.b=e}function dG(n,e){n.j=e}function Vse(n,e){n.g=e}function Wse(n,e){n.i=e}function Jse(n,e){n.c=e}function Qse(n,e){n.c=e}function Yse(n,e){n.d=e}function Zse(n,e){n.d=e}function Ha(n,e){n.k=e}function nfe(n,e){n.c=e}function bG(n,e){n.c=e}function wG(n,e){n.a=e}function efe(n,e){n.a=e}function tfe(n,e){n.f=e}function ife(n,e){n.a=e}function rfe(n,e){n.b=e}function JO(n,e){n.d=e}function AE(n,e){n.i=e}function gG(n,e){n.o=e}function cfe(n,e){n.r=e}function ufe(n,e){n.a=e}function ofe(n,e){n.b=e}function t9n(n,e){n.e=e}function sfe(n,e){n.f=e}function pG(n,e){n.g=e}function ffe(n,e){n.e=e}function hfe(n,e){n.f=e}function lfe(n,e){n.f=e}function QO(n,e){n.a=e}function YO(n,e){n.b=e}function afe(n,e){n.n=e}function dfe(n,e){n.a=e}function bfe(n,e){n.c=e}function wfe(n,e){n.c=e}function gfe(n,e){n.c=e}function pfe(n,e){n.a=e}function mfe(n,e){n.a=e}function vfe(n,e){n.d=e}function kfe(n,e){n.d=e}function yfe(n,e){n.e=e}function jfe(n,e){n.e=e}function Efe(n,e){n.g=e}function Cfe(n,e){n.f=e}function Mfe(n,e){n.j=e}function Tfe(n,e){n.a=e}function Afe(n,e){n.a=e}function Sfe(n,e){n.b=e}function i9n(n){n.b=n.a}function r9n(n){n.c=n.d.d}function mG(n){this.a=n}function vG(n){this.a=n}function kG(n){this.a=n}function qa(n){this.a=n}function Ua(n){this.a=n}function U9(n){this.a=n}function c9n(n){this.a=n}function yG(n){this.a=n}function G9(n){this.a=n}function SE(n){this.a=n}function ol(n){this.a=n}function Tb(n){this.a=n}function u9n(n){this.a=n}function o9n(n){this.a=n}function ZO(n){this.b=n}function W3(n){this.b=n}function J3(n){this.b=n}function nD(n){this.a=n}function s9n(n){this.a=n}function eD(n){this.c=n}function C(n){this.c=n}function f9n(n){this.c=n}function Gv(n){this.d=n}function jG(n){this.a=n}function Te(n){this.a=n}function h9n(n){this.a=n}function EG(n){this.a=n}function CG(n){this.a=n}function MG(n){this.a=n}function TG(n){this.a=n}function AG(n){this.a=n}function SG(n){this.a=n}function Q3(n){this.a=n}function l9n(n){this.a=n}function a9n(n){this.a=n}function Y3(n){this.a=n}function d9n(n){this.a=n}function b9n(n){this.a=n}function w9n(n){this.a=n}function g9n(n){this.a=n}function p9n(n){this.a=n}function m9n(n){this.a=n}function v9n(n){this.a=n}function k9n(n){this.a=n}function y9n(n){this.a=n}function j9n(n){this.a=n}function E9n(n){this.a=n}function C9n(n){this.a=n}function M9n(n){this.a=n}function T9n(n){this.a=n}function A9n(n){this.a=n}function z9(n){this.a=n}function S9n(n){this.a=n}function P9n(n){this.a=n}function I9n(n){this.a=n}function O9n(n){this.a=n}function PE(n){this.a=n}function D9n(n){this.a=n}function L9n(n){this.a=n}function Z3(n){this.a=n}function PG(n){this.a=n}function N9n(n){this.a=n}function $9n(n){this.a=n}function x9n(n){this.a=n}function F9n(n){this.a=n}function B9n(n){this.a=n}function R9n(n){this.a=n}function IG(n){this.a=n}function OG(n){this.a=n}function DG(n){this.a=n}function zv(n){this.a=n}function IE(n){this.e=n}function n4(n){this.a=n}function K9n(n){this.a=n}function ip(n){this.a=n}function LG(n){this.a=n}function _9n(n){this.a=n}function H9n(n){this.a=n}function q9n(n){this.a=n}function U9n(n){this.a=n}function G9n(n){this.a=n}function z9n(n){this.a=n}function X9n(n){this.a=n}function V9n(n){this.a=n}function W9n(n){this.a=n}function J9n(n){this.a=n}function Q9n(n){this.a=n}function NG(n){this.a=n}function Y9n(n){this.a=n}function Z9n(n){this.a=n}function n7n(n){this.a=n}function e7n(n){this.a=n}function t7n(n){this.a=n}function i7n(n){this.a=n}function r7n(n){this.a=n}function c7n(n){this.a=n}function u7n(n){this.a=n}function o7n(n){this.a=n}function s7n(n){this.a=n}function f7n(n){this.a=n}function h7n(n){this.a=n}function l7n(n){this.a=n}function a7n(n){this.a=n}function d7n(n){this.a=n}function b7n(n){this.a=n}function w7n(n){this.a=n}function g7n(n){this.a=n}function p7n(n){this.a=n}function m7n(n){this.a=n}function v7n(n){this.a=n}function k7n(n){this.a=n}function y7n(n){this.a=n}function j7n(n){this.a=n}function E7n(n){this.a=n}function C7n(n){this.a=n}function M7n(n){this.a=n}function T7n(n){this.a=n}function A7n(n){this.a=n}function S7n(n){this.a=n}function P7n(n){this.a=n}function I7n(n){this.a=n}function O7n(n){this.a=n}function D7n(n){this.a=n}function L7n(n){this.a=n}function N7n(n){this.a=n}function $7n(n){this.a=n}function x7n(n){this.c=n}function F7n(n){this.b=n}function B7n(n){this.a=n}function R7n(n){this.a=n}function K7n(n){this.a=n}function _7n(n){this.a=n}function H7n(n){this.a=n}function q7n(n){this.a=n}function U7n(n){this.a=n}function G7n(n){this.a=n}function z7n(n){this.a=n}function X7n(n){this.a=n}function V7n(n){this.a=n}function W7n(n){this.a=n}function J7n(n){this.a=n}function Q7n(n){this.a=n}function Y7n(n){this.a=n}function Z7n(n){this.a=n}function nkn(n){this.a=n}function ekn(n){this.a=n}function tkn(n){this.a=n}function ikn(n){this.a=n}function rkn(n){this.a=n}function ckn(n){this.a=n}function ukn(n){this.a=n}function okn(n){this.a=n}function skn(n){this.a=n}function fkn(n){this.a=n}function hkn(n){this.a=n}function sl(n){this.a=n}function sg(n){this.a=n}function lkn(n){this.a=n}function akn(n){this.a=n}function dkn(n){this.a=n}function bkn(n){this.a=n}function wkn(n){this.a=n}function gkn(n){this.a=n}function pkn(n){this.a=n}function mkn(n){this.a=n}function vkn(n){this.a=n}function kkn(n){this.a=n}function ykn(n){this.a=n}function jkn(n){this.a=n}function Ekn(n){this.a=n}function Ckn(n){this.a=n}function Mkn(n){this.a=n}function Tkn(n){this.a=n}function Akn(n){this.a=n}function Skn(n){this.a=n}function Pkn(n){this.a=n}function Ikn(n){this.a=n}function Okn(n){this.a=n}function Dkn(n){this.a=n}function Lkn(n){this.a=n}function Nkn(n){this.a=n}function $kn(n){this.a=n}function xkn(n){this.a=n}function OE(n){this.a=n}function Fkn(n){this.f=n}function Bkn(n){this.a=n}function Rkn(n){this.a=n}function Kkn(n){this.a=n}function _kn(n){this.a=n}function Hkn(n){this.a=n}function qkn(n){this.a=n}function Ukn(n){this.a=n}function Gkn(n){this.a=n}function zkn(n){this.a=n}function Xkn(n){this.a=n}function Vkn(n){this.a=n}function Wkn(n){this.a=n}function Jkn(n){this.a=n}function Qkn(n){this.a=n}function Ykn(n){this.a=n}function Zkn(n){this.a=n}function nyn(n){this.a=n}function eyn(n){this.a=n}function tyn(n){this.a=n}function iyn(n){this.a=n}function ryn(n){this.a=n}function cyn(n){this.a=n}function uyn(n){this.a=n}function oyn(n){this.a=n}function syn(n){this.a=n}function fyn(n){this.a=n}function hyn(n){this.a=n}function lyn(n){this.a=n}function tD(n){this.a=n}function $G(n){this.a=n}function lt(n){this.b=n}function ayn(n){this.a=n}function dyn(n){this.a=n}function byn(n){this.a=n}function wyn(n){this.a=n}function gyn(n){this.a=n}function pyn(n){this.a=n}function myn(n){this.a=n}function vyn(n){this.b=n}function kyn(n){this.a=n}function X9(n){this.a=n}function yyn(n){this.a=n}function jyn(n){this.a=n}function xG(n){this.c=n}function DE(n){this.e=n}function LE(n){this.a=n}function NE(n){this.a=n}function iD(n){this.a=n}function Eyn(n){this.d=n}function Cyn(n){this.a=n}function FG(n){this.a=n}function BG(n){this.a=n}function Wd(n){this.e=n}function Pfe(){this.a=0}function de(){Hu(this)}function Z(){pL(this)}function rD(){oIn(this)}function Myn(){}function Jd(){this.c=Udn}function Tyn(n,e){n.b+=e}function Ife(n,e){e.Wb(n)}function Ofe(n){return n.a}function Dfe(n){return n.a}function Lfe(n){return n.a}function Nfe(n){return n.a}function $fe(n){return n.a}function M(n){return n.e}function xfe(){return null}function Ffe(){return null}function Bfe(){Ez(),pLe()}function Rfe(n){n.b.Of(n.e)}function Ayn(n){n.b=new CD}function Xv(n,e){n.b=e-n.b}function Vv(n,e){n.a=e-n.a}function Rn(n,e){n.push(e)}function Syn(n,e){n.sort(e)}function Pyn(n,e){e.jd(n.a)}function Kfe(n,e){gi(e,n)}function _fe(n,e,t){n.Yd(t,e)}function V9(n,e){n.e=e,e.b=n}function RG(n){oh(),this.a=n}function Iyn(n){oh(),this.a=n}function Oyn(n){oh(),this.a=n}function cD(n){g0(),this.a=n}function Dyn(n){I4(),VK.le(n)}function KG(){KG=F,new de}function Ga(){QTn.call(this)}function _G(){QTn.call(this)}function HG(){Ga.call(this)}function uD(){Ga.call(this)}function Lyn(){Ga.call(this)}function W9(){Ga.call(this)}function Cu(){Ga.call(this)}function rp(){Ga.call(this)}function Pe(){Ga.call(this)}function Bo(){Ga.call(this)}function Nyn(){Ga.call(this)}function nc(){Ga.call(this)}function $yn(){Ga.call(this)}function xyn(){this.a=this}function $E(){this.Bb|=256}function Fyn(){this.b=new UMn}function Ab(n,e){n.length=e}function xE(n,e){nn(n.a,e)}function Hfe(n,e){dnn(n.c,e)}function qfe(n,e){fi(n.b,e)}function Ufe(n,e){uA(n.a,e)}function Gfe(n,e){cx(n.a,e)}function e4(n,e){it(n.e,e)}function cp(n){jA(n.c,n.b)}function zfe(n,e){n.kc().Nb(e)}function qG(n){this.a=B5e(n)}function ni(){this.a=new de}function Byn(){this.a=new de}function UG(){this.a=new iCn}function FE(){this.a=new Z}function oD(){this.a=new Z}function GG(){this.a=new Z}function hs(){this.a=new rbn}function za(){this.a=new LLn}function zG(){this.a=new KU}function XG(){this.a=new MOn}function VG(){this.a=new FAn}function Ryn(){this.a=new Z}function Kyn(){this.a=new Z}function _yn(){this.a=new Z}function WG(){this.a=new Z}function Hyn(){this.d=new Z}function qyn(){this.a=new GOn}function Uyn(){this.a=new ni}function Gyn(){this.a=new de}function zyn(){this.b=new de}function Xyn(){this.b=new Z}function JG(){this.e=new Z}function Vyn(){this.a=new Y5n}function Wyn(){this.d=new Z}function Jyn(){JIn.call(this)}function Qyn(){JIn.call(this)}function Yyn(){Z.call(this)}function QG(){HG.call(this)}function YG(){FE.call(this)}function Zyn(){HC.call(this)}function njn(){WG.call(this)}function Wv(){Myn.call(this)}function sD(){Wv.call(this)}function up(){Myn.call(this)}function ZG(){up.call(this)}function ejn(){iz.call(this)}function tjn(){iz.call(this)}function ijn(){iz.call(this)}function rjn(){rz.call(this)}function Jv(){ovn.call(this)}function nz(){ovn.call(this)}function Mu(){Ct.call(this)}function cjn(){kjn.call(this)}function ujn(){kjn.call(this)}function ojn(){de.call(this)}function sjn(){de.call(this)}function fjn(){de.call(this)}function fD(){rxn.call(this)}function hjn(){ni.call(this)}function ljn(){$E.call(this)}function hD(){FX.call(this)}function ez(){de.call(this)}function lD(){FX.call(this)}function aD(){de.call(this)}function ajn(){de.call(this)}function tz(){CE.call(this)}function djn(){tz.call(this)}function bjn(){CE.call(this)}function wjn(){iG.call(this)}function iz(){this.a=new ni}function gjn(){this.a=new de}function pjn(){this.a=new Z}function rz(){this.a=new de}function op(){this.a=new Ct}function mjn(){this.j=new Z}function vjn(){this.a=new pEn}function kjn(){this.a=new pvn}function cz(){this.a=new Y4n}function Qv(){Qv=F,KK=new Ht}function dD(){dD=F,_K=new jjn}function bD(){bD=F,HK=new yjn}function yjn(){XO.call(this,"")}function jjn(){XO.call(this,"")}function Ejn(n){A$n.call(this,n)}function Cjn(n){A$n.call(this,n)}function uz(n){sG.call(this,n)}function oz(n){zEn.call(this,n)}function Xfe(n){zEn.call(this,n)}function Vfe(n){oz.call(this,n)}function Wfe(n){oz.call(this,n)}function Jfe(n){oz.call(this,n)}function Mjn(n){zN.call(this,n)}function Tjn(n){zN.call(this,n)}function Ajn(n){cSn.call(this,n)}function Sjn(n){Iz.call(this,n)}function Yv(n){VE.call(this,n)}function sz(n){VE.call(this,n)}function Pjn(n){VE.call(this,n)}function fz(n){mje.call(this,n)}function hz(n){fz.call(this,n)}function ec(n){TPn.call(this,n)}function Ijn(n){ec.call(this,n)}function sp(){q9.call(this,{})}function Ojn(){Ojn=F,dQn=new C0n}function BE(){BE=F,GK=new ATn}function Djn(){Djn=F,cun=new Bu}function lz(){lz=F,uun=new N1}function RE(){RE=F,C8=new $1}function wD(n){d4(),this.a=n}function gD(n){BQ(),this.a=n}function Sb(n){nN(),this.f=n}function pD(n){nN(),this.f=n}function Ljn(n){dSn(),this.a=n}function Njn(n){n.b=null,n.c=0}function Qfe(n,e){n.e=e,bqn(n,e)}function Yfe(n,e){n.a=e,cEe(n)}function mD(n,e,t){n.a[e.g]=t}function Zfe(n,e,t){kke(t,n,e)}function nhe(n,e){Wae(e.i,n.n)}function $jn(n,e){v6e(n).Cd(e)}function ehe(n,e){n.a.ec().Mc(e)}function xjn(n,e){return n.g-e.g}function the(n,e){return n*n/e}function on(n){return Jn(n),n}function $(n){return Jn(n),n}function J9(n){return Jn(n),n}function ihe(n){return new TE(n)}function rhe(n){return new qb(n)}function az(n){return Jn(n),n}function che(n){return Jn(n),n}function KE(n){ec.call(this,n)}function Ir(n){ec.call(this,n)}function Fjn(n){ec.call(this,n)}function vD(n){TPn.call(this,n)}function t4(n){ec.call(this,n)}function Gn(n){ec.call(this,n)}function Or(n){ec.call(this,n)}function Bjn(n){ec.call(this,n)}function fp(n){ec.call(this,n)}function Kl(n){ec.call(this,n)}function _l(n){ec.call(this,n)}function hp(n){ec.call(this,n)}function eh(n){ec.call(this,n)}function kD(n){ec.call(this,n)}function Le(n){ec.call(this,n)}function Ku(n){Jn(n),this.a=n}function dz(n){return ld(n),n}function Zv(n){MW(n,n.length)}function n6(n){return n.b==n.c}function Pb(n){return!!n&&n.b}function uhe(n){return!!n&&n.k}function ohe(n){return!!n&&n.j}function she(n,e,t){n.c.Ef(e,t)}function Rjn(n,e){n.be(e),e.ae(n)}function lp(n){oh(),this.a=Se(n)}function yD(){this.a=Oe(Se(ur))}function Kjn(){throw M(new Pe)}function fhe(){throw M(new Pe)}function bz(){throw M(new Pe)}function _jn(){throw M(new Pe)}function hhe(){throw M(new Pe)}function lhe(){throw M(new Pe)}function _E(){_E=F,I4()}function Hl(){U9.call(this,"")}function e6(){U9.call(this,"")}function x1(){U9.call(this,"")}function fg(){U9.call(this,"")}function wz(n){Ir.call(this,n)}function gz(n){Ir.call(this,n)}function th(n){Gn.call(this,n)}function i4(n){J3.call(this,n)}function Hjn(n){i4.call(this,n)}function jD(n){FC.call(this,n)}function ED(n){WX.call(this,n,0)}function CD(){oJ.call(this,12,3)}function T(n,e){return vOn(n,e)}function HE(n,e){return o$(n,e)}function ahe(n,e){return n.a-e.a}function dhe(n,e){return n.a-e.a}function bhe(n,e){return n.a-e.a}function whe(n,e){return e in n.a}function qjn(n){return n.a?n.b:0}function ghe(n){return n.a?n.b:0}function phe(n,e,t){e.Cd(n.a[t])}function mhe(n,e,t){e.Pe(n.a[t])}function vhe(n,e){n.b=new rr(e)}function khe(n,e){return n.b=e,n}function Ujn(n,e){return n.c=e,n}function Gjn(n,e){return n.f=e,n}function yhe(n,e){return n.g=e,n}function pz(n,e){return n.a=e,n}function mz(n,e){return n.f=e,n}function jhe(n,e){return n.k=e,n}function vz(n,e){return n.a=e,n}function Ehe(n,e){return n.e=e,n}function kz(n,e){return n.e=e,n}function Che(n,e){return n.f=e,n}function Mhe(n,e){n.b=!0,n.d=e}function The(n,e){return n.b-e.b}function Ahe(n,e){return n.g-e.g}function She(n,e){return n?0:e-1}function zjn(n,e){return n?0:e-1}function Phe(n,e){return n?e-1:0}function Ihe(n,e){return n.s-e.s}function Ohe(n,e){return e.rg(n)}function Qd(n,e){return n.b=e,n}function qE(n,e){return n.a=e,n}function Yd(n,e){return n.c=e,n}function Zd(n,e){return n.d=e,n}function n0(n,e){return n.e=e,n}function yz(n,e){return n.f=e,n}function t6(n,e){return n.a=e,n}function r4(n,e){return n.b=e,n}function c4(n,e){return n.c=e,n}function an(n,e){return n.c=e,n}function Sn(n,e){return n.b=e,n}function dn(n,e){return n.d=e,n}function bn(n,e){return n.e=e,n}function Dhe(n,e){return n.f=e,n}function wn(n,e){return n.g=e,n}function gn(n,e){return n.a=e,n}function pn(n,e){return n.i=e,n}function mn(n,e){return n.j=e,n}function Lhe(n,e){ua(),ic(e,n)}function Nhe(n,e,t){Jbe(n.a,e,t)}function UE(n){$L.call(this,n)}function Xjn(n){Z5e.call(this,n)}function Vjn(n){AIn.call(this,n)}function jz(n){AIn.call(this,n)}function F1(n){T0.call(this,n)}function Wjn(n){CN.call(this,n)}function Jjn(n){CN.call(this,n)}function Qjn(){OX.call(this,"")}function Li(){this.a=0,this.b=0}function Yjn(){this.b=0,this.a=0}function Zjn(n,e){n.b=0,Zb(n,e)}function nEn(n,e){return n.k=e,n}function $he(n,e){return n.j=e,n}function xhe(n,e){n.c=e,n.b=!0}function eEn(){eEn=F,TQn=Xke()}function B1(){B1=F,voe=rke()}function tEn(){tEn=F,Ti=gye()}function Ez(){Ez=F,Da=G4()}function u4(){u4=F,qdn=cke()}function iEn(){iEn=F,ise=uke()}function Cz(){Cz=F,yc=tEe()}function of(n){return n.e&&n.e()}function rEn(n){return n.l|n.m<<22}function cEn(n,e){return n.c._b(e)}function uEn(n,e){return iBn(n.b,e)}function MD(n){return n?n.d:null}function Fhe(n){return n?n.g:null}function Bhe(n){return n?n.i:null}function Xa(n){return ll(n),n.o}function hg(n,e){return n.a+=e,n}function TD(n,e){return n.a+=e,n}function ql(n,e){return n.a+=e,n}function e0(n,e){return n.a+=e,n}function Mz(n,e){for(;n.Bd(e););}function GE(n){this.a=new ap(n)}function oEn(){throw M(new Pe)}function sEn(){throw M(new Pe)}function fEn(){throw M(new Pe)}function hEn(){throw M(new Pe)}function lEn(){throw M(new Pe)}function aEn(){throw M(new Pe)}function Ul(n){this.a=new iN(n)}function dEn(){this.a=new $5(Fln)}function bEn(){this.b=new $5(tln)}function wEn(){this.a=new $5(o1n)}function gEn(){this.b=new $5(xq)}function pEn(){this.b=new $5(xq)}function zE(n){this.a=0,this.b=n}function Tz(n){zGn(),ILe(this,n)}function o4(n){return X1(n),n.a}function Q9(n){return n.b!=n.d.c}function Az(n,e){return n.d[e.p]}function mEn(n,e){return XTe(n,e)}function Sz(n,e,t){n.splice(e,t)}function lg(n,e){for(;n.Re(e););}function vEn(n){n.c?Dqn(n):Lqn(n)}function kEn(){throw M(new Pe)}function yEn(){throw M(new Pe)}function jEn(){throw M(new Pe)}function EEn(){throw M(new Pe)}function CEn(){throw M(new Pe)}function MEn(){throw M(new Pe)}function TEn(){throw M(new Pe)}function AEn(){throw M(new Pe)}function SEn(){throw M(new Pe)}function PEn(){throw M(new Pe)}function Rhe(){throw M(new nc)}function Khe(){throw M(new nc)}function Y9(n){this.a=new IEn(n)}function IEn(n){Ume(this,n,jje())}function Z9(n){return!n||uIn(n)}function n7(n){return nh[n]!=-1}function _he(){cP!=0&&(cP=0),uP=-1}function OEn(){RK==null&&(RK=[])}function e7(n,e){Mg.call(this,n,e)}function s4(n,e){e7.call(this,n,e)}function DEn(n,e){this.a=n,this.b=e}function LEn(n,e){this.a=n,this.b=e}function NEn(n,e){this.a=n,this.b=e}function $En(n,e){this.a=n,this.b=e}function xEn(n,e){this.a=n,this.b=e}function FEn(n,e){this.a=n,this.b=e}function BEn(n,e){this.a=n,this.b=e}function f4(n,e){this.e=n,this.d=e}function Pz(n,e){this.b=n,this.c=e}function REn(n,e){this.b=n,this.a=e}function KEn(n,e){this.b=n,this.a=e}function _En(n,e){this.b=n,this.a=e}function HEn(n,e){this.b=n,this.a=e}function qEn(n,e){this.a=n,this.b=e}function AD(n,e){this.a=n,this.b=e}function UEn(n,e){this.a=n,this.f=e}function t0(n,e){this.g=n,this.i=e}function je(n,e){this.f=n,this.g=e}function GEn(n,e){this.b=n,this.c=e}function zEn(n){RX(n.dc()),this.c=n}function Hhe(n,e){this.a=n,this.b=e}function XEn(n,e){this.a=n,this.b=e}function VEn(n){this.a=u(Se(n),15)}function Iz(n){this.a=u(Se(n),15)}function WEn(n){this.a=u(Se(n),85)}function XE(n){this.b=u(Se(n),85)}function VE(n){this.b=u(Se(n),51)}function WE(){this.q=new y.Date}function SD(n,e){this.a=n,this.b=e}function JEn(n,e){return Zc(n.b,e)}function t7(n,e){return n.b.Hc(e)}function QEn(n,e){return n.b.Ic(e)}function YEn(n,e){return n.b.Qc(e)}function ZEn(n,e){return n.b.Hc(e)}function nCn(n,e){return n.c.uc(e)}function eCn(n,e){return rt(n.c,e)}function sf(n,e){return n.a._b(e)}function tCn(n,e){return n>e&&e0}function ND(n,e){return Ec(n,e)<0}function mCn(n,e){return JL(n.a,e)}function ole(n,e){kOn.call(this,n,e)}function Fz(n){wN(),cSn.call(this,n)}function Bz(n,e){dPn(n,n.length,e)}function u7(n,e){_Pn(n,n.length,e)}function h6(n,e){return n.a.get(e)}function vCn(n,e){return Zc(n.e,e)}function Rz(n){return Jn(n),!1}function Kz(n){this.a=u(Se(n),229)}function rC(n){In.call(this,n,21)}function cC(n,e){je.call(this,n,e)}function $D(n,e){je.call(this,n,e)}function kCn(n,e){this.b=n,this.a=e}function uC(n,e){this.d=n,this.e=e}function yCn(n,e){this.a=n,this.b=e}function jCn(n,e){this.a=n,this.b=e}function ECn(n,e){this.a=n,this.b=e}function CCn(n,e){this.a=n,this.b=e}function bp(n,e){this.a=n,this.b=e}function MCn(n,e){this.b=n,this.a=e}function _z(n,e){this.b=n,this.a=e}function Hz(n,e){je.call(this,n,e)}function qz(n,e){je.call(this,n,e)}function ag(n,e){je.call(this,n,e)}function xD(n,e){je.call(this,n,e)}function FD(n,e){je.call(this,n,e)}function BD(n,e){je.call(this,n,e)}function oC(n,e){je.call(this,n,e)}function Uz(n,e){this.b=n,this.a=e}function sC(n,e){je.call(this,n,e)}function Gz(n,e){this.b=n,this.a=e}function fC(n,e){je.call(this,n,e)}function TCn(n,e){this.b=n,this.a=e}function zz(n,e){je.call(this,n,e)}function RD(n,e){je.call(this,n,e)}function o7(n,e){je.call(this,n,e)}function l6(n,e,t){n.splice(e,0,t)}function sle(n,e,t){n.Mb(t)&&e.Cd(t)}function fle(n,e,t){e.Pe(n.a.Ye(t))}function hle(n,e,t){e.Dd(n.a.Ze(t))}function lle(n,e,t){e.Cd(n.a.Kb(t))}function ale(n,e){return Au(n.c,e)}function dle(n,e){return Au(n.e,e)}function hC(n,e){je.call(this,n,e)}function lC(n,e){je.call(this,n,e)}function a6(n,e){je.call(this,n,e)}function Xz(n,e){je.call(this,n,e)}function ei(n,e){je.call(this,n,e)}function aC(n,e){je.call(this,n,e)}function ACn(n,e){this.a=n,this.b=e}function SCn(n,e){this.a=n,this.b=e}function PCn(n,e){this.a=n,this.b=e}function ICn(n,e){this.a=n,this.b=e}function OCn(n,e){this.a=n,this.b=e}function DCn(n,e){this.a=n,this.b=e}function LCn(n,e){this.b=n,this.a=e}function NCn(n,e){this.b=n,this.a=e}function Vz(n,e){this.b=n,this.a=e}function a4(n,e){this.c=n,this.d=e}function $Cn(n,e){this.e=n,this.d=e}function xCn(n,e){this.a=n,this.b=e}function FCn(n,e){this.a=n,this.b=e}function BCn(n,e){this.a=n,this.b=e}function RCn(n,e){this.b=n,this.a=e}function KCn(n,e){this.b=e,this.c=n}function dC(n,e){je.call(this,n,e)}function s7(n,e){je.call(this,n,e)}function KD(n,e){je.call(this,n,e)}function Wz(n,e){je.call(this,n,e)}function d6(n,e){je.call(this,n,e)}function _D(n,e){je.call(this,n,e)}function HD(n,e){je.call(this,n,e)}function f7(n,e){je.call(this,n,e)}function Jz(n,e){je.call(this,n,e)}function qD(n,e){je.call(this,n,e)}function b6(n,e){je.call(this,n,e)}function Qz(n,e){je.call(this,n,e)}function w6(n,e){je.call(this,n,e)}function g6(n,e){je.call(this,n,e)}function Db(n,e){je.call(this,n,e)}function UD(n,e){je.call(this,n,e)}function GD(n,e){je.call(this,n,e)}function Yz(n,e){je.call(this,n,e)}function h7(n,e){je.call(this,n,e)}function dg(n,e){je.call(this,n,e)}function zD(n,e){je.call(this,n,e)}function bC(n,e){je.call(this,n,e)}function l7(n,e){je.call(this,n,e)}function Lb(n,e){je.call(this,n,e)}function wC(n,e){je.call(this,n,e)}function Zz(n,e){je.call(this,n,e)}function XD(n,e){je.call(this,n,e)}function VD(n,e){je.call(this,n,e)}function WD(n,e){je.call(this,n,e)}function JD(n,e){je.call(this,n,e)}function QD(n,e){je.call(this,n,e)}function YD(n,e){je.call(this,n,e)}function ZD(n,e){je.call(this,n,e)}function _Cn(n,e){this.b=n,this.a=e}function nX(n,e){je.call(this,n,e)}function HCn(n,e){this.a=n,this.b=e}function qCn(n,e){this.a=n,this.b=e}function UCn(n,e){this.a=n,this.b=e}function eX(n,e){je.call(this,n,e)}function tX(n,e){je.call(this,n,e)}function GCn(n,e){this.a=n,this.b=e}function ble(n,e){return v4(),e!=n}function a7(n){return oe(n.a),n.b}function nL(n){return yCe(n,n.c),n}function zCn(){return eEn(),new TQn}function XCn(){XC(),this.a=new vV}function VCn(){OA(),this.a=new ni}function WCn(){NN(),this.b=new ni}function JCn(n,e){this.b=n,this.d=e}function QCn(n,e){this.a=n,this.b=e}function YCn(n,e){this.a=n,this.b=e}function ZCn(n,e){this.a=n,this.b=e}function nMn(n,e){this.b=n,this.a=e}function iX(n,e){je.call(this,n,e)}function rX(n,e){je.call(this,n,e)}function gC(n,e){je.call(this,n,e)}function r0(n,e){je.call(this,n,e)}function eL(n,e){je.call(this,n,e)}function pC(n,e){je.call(this,n,e)}function cX(n,e){je.call(this,n,e)}function uX(n,e){je.call(this,n,e)}function d7(n,e){je.call(this,n,e)}function oX(n,e){je.call(this,n,e)}function tL(n,e){je.call(this,n,e)}function mC(n,e){je.call(this,n,e)}function iL(n,e){je.call(this,n,e)}function rL(n,e){je.call(this,n,e)}function cL(n,e){je.call(this,n,e)}function uL(n,e){je.call(this,n,e)}function sX(n,e){je.call(this,n,e)}function oL(n,e){je.call(this,n,e)}function fX(n,e){je.call(this,n,e)}function b7(n,e){je.call(this,n,e)}function sL(n,e){je.call(this,n,e)}function hX(n,e){je.call(this,n,e)}function w7(n,e){je.call(this,n,e)}function lX(n,e){je.call(this,n,e)}function eMn(n,e){this.b=n,this.a=e}function tMn(n,e){this.b=n,this.a=e}function iMn(n,e){this.b=n,this.a=e}function rMn(n,e){this.b=n,this.a=e}function aX(n,e){this.a=n,this.b=e}function cMn(n,e){this.a=n,this.b=e}function uMn(n,e){this.a=n,this.b=e}function V(n,e){this.a=n,this.b=e}function p6(n,e){je.call(this,n,e)}function g7(n,e){je.call(this,n,e)}function wp(n,e){je.call(this,n,e)}function m6(n,e){je.call(this,n,e)}function p7(n,e){je.call(this,n,e)}function fL(n,e){je.call(this,n,e)}function vC(n,e){je.call(this,n,e)}function v6(n,e){je.call(this,n,e)}function hL(n,e){je.call(this,n,e)}function kC(n,e){je.call(this,n,e)}function bg(n,e){je.call(this,n,e)}function m7(n,e){je.call(this,n,e)}function k6(n,e){je.call(this,n,e)}function y6(n,e){je.call(this,n,e)}function v7(n,e){je.call(this,n,e)}function yC(n,e){je.call(this,n,e)}function wg(n,e){je.call(this,n,e)}function lL(n,e){je.call(this,n,e)}function oMn(n,e){je.call(this,n,e)}function jC(n,e){je.call(this,n,e)}function sMn(n,e){this.a=n,this.b=e}function fMn(n,e){this.a=n,this.b=e}function hMn(n,e){this.a=n,this.b=e}function lMn(n,e){this.a=n,this.b=e}function aMn(n,e){this.a=n,this.b=e}function dMn(n,e){this.a=n,this.b=e}function bi(n,e){this.a=n,this.b=e}function bMn(n,e){this.a=n,this.b=e}function wMn(n,e){this.a=n,this.b=e}function gMn(n,e){this.a=n,this.b=e}function pMn(n,e){this.a=n,this.b=e}function mMn(n,e){this.a=n,this.b=e}function vMn(n,e){this.a=n,this.b=e}function kMn(n,e){this.b=n,this.a=e}function yMn(n,e){this.b=n,this.a=e}function jMn(n,e){this.b=n,this.a=e}function EMn(n,e){this.b=n,this.a=e}function CMn(n,e){this.a=n,this.b=e}function MMn(n,e){this.a=n,this.b=e}function EC(n,e){je.call(this,n,e)}function TMn(n,e){this.a=n,this.b=e}function AMn(n,e){this.a=n,this.b=e}function gp(n,e){je.call(this,n,e)}function SMn(n,e){this.f=n,this.c=e}function dX(n,e){return Au(n.g,e)}function wle(n,e){return Au(e.b,n)}function PMn(n,e){return wx(n.a,e)}function gle(n,e){return-n.b.af(e)}function ple(n,e){n&&Ve(fE,n,e)}function bX(n,e){n.i=null,kT(n,e)}function mle(n,e,t){kKn(e,oF(n,t))}function vle(n,e,t){kKn(e,oF(n,t))}function kle(n,e){VMe(n.a,u(e,58))}function IMn(n,e){U4e(n.a,u(e,12))}function CC(n,e){this.a=n,this.b=e}function OMn(n,e){this.a=n,this.b=e}function DMn(n,e){this.a=n,this.b=e}function LMn(n,e){this.a=n,this.b=e}function NMn(n,e){this.a=n,this.b=e}function $Mn(n,e){this.d=n,this.b=e}function xMn(n,e){this.e=n,this.a=e}function k7(n,e){this.b=n,this.c=e}function wX(n,e){this.i=n,this.g=e}function gX(n,e){this.d=n,this.e=e}function yle(n,e){cme(new ne(n),e)}function MC(n){return xk(n.c,n.b)}function Kr(n){return n?n.md():null}function x(n){return n??null}function Ai(n){return typeof n===nB}function Nb(n){return typeof n===i3}function $b(n){return typeof n===ltn}function c0(n,e){return Ec(n,e)==0}function TC(n,e){return Ec(n,e)>=0}function j6(n,e){return Ec(n,e)!=0}function AC(n,e){return jve(n.Kc(),e)}function _1(n,e){return n.Rd().Xb(e)}function FMn(n){return eo(n),n.d.gc()}function SC(n){return N6(n==null),n}function E6(n,e){return n.a+=""+e,n}function Er(n,e){return n.a+=""+e,n}function C6(n,e){return n.a+=""+e,n}function Dc(n,e){return n.a+=""+e,n}function Re(n,e){return n.a+=""+e,n}function pX(n,e){return n.a+=""+e,n}function jle(n){return""+(Jn(n),n)}function BMn(n){Hu(this),u5(this,n)}function RMn(){uJ(),aW.call(this)}function KMn(n,e){pW.call(this,n,e)}function _Mn(n,e){pW.call(this,n,e)}function PC(n,e){pW.call(this,n,e)}function ir(n,e){xt(n,e,n.c.b,n.c)}function gg(n,e){xt(n,e,n.a,n.a.a)}function mX(n){return Ln(n,0),null}function HMn(){this.b=0,this.a=!1}function qMn(){this.b=0,this.a=!1}function UMn(){this.b=new ap(Qb(12))}function GMn(){GMn=F,kYn=Ce(jx())}function zMn(){zMn=F,HZn=Ce(iqn())}function XMn(){XMn=F,lre=Ce($xn())}function vX(){vX=F,KG(),oun=new de}function ff(n){return n.a=0,n.b=0,n}function VMn(n,e){return n.a=e.g+1,n}function aL(n,e){Kb.call(this,n,e)}function Mn(n,e){Dt.call(this,n,e)}function pg(n,e){wX.call(this,n,e)}function WMn(n,e){C7.call(this,n,e)}function dL(n,e){Q4.call(this,n,e)}function Ge(n,e){tC(),Ve(yO,n,e)}function JMn(n,e){n.q.setTime(id(e))}function Ele(n){y.clearTimeout(n)}function Cle(n){return Se(n),new M6(n)}function QMn(n,e){return x(n)===x(e)}function YMn(n,e){return n.a.a.a.cc(e)}function bL(n,e){return qo(n.a,0,e)}function kX(n){return Awe(u(n,74))}function pp(n){return wi((Jn(n),n))}function Mle(n){return wi((Jn(n),n))}function ZMn(n){return Yc(n.l,n.m,n.h)}function yX(n,e){return jc(n.a,e.a)}function Tle(n,e){return RPn(n.a,e.a)}function Ale(n,e){return bt(n.a,e.a)}function ih(n,e){return n.indexOf(e)}function Sle(n,e){return n.j[e.p]==2}function u0(n,e){return n==e?0:n?1:-1}function IC(n){return n<10?"0"+n:""+n}function Vr(n){return typeof n===ltn}function Ple(n){return n==tb||n==Iw}function Ile(n){return n==tb||n==Pw}function nTn(n,e){return jc(n.g,e.g)}function jX(n){return qr(n.b.b,n,0)}function eTn(){iM.call(this,0,0,0,0)}function rh(){EG.call(this,new Ql)}function EX(n,e){x4(n,0,n.length,e)}function Ole(n,e){return nn(n.a,e),e}function Dle(n,e){return Fs(),e.a+=n}function Lle(n,e){return Fs(),e.a+=n}function Nle(n,e){return Fs(),e.c+=n}function $le(n,e){return nn(n.c,e),n}function CX(n,e){return Mo(n.a,e),n}function tTn(n){this.a=zCn(),this.b=n}function iTn(n){this.a=zCn(),this.b=n}function rr(n){this.a=n.a,this.b=n.b}function M6(n){this.a=n,GO.call(this)}function rTn(n){this.a=n,GO.call(this)}function mp(){Ho.call(this,0,0,0,0)}function OC(n){return Mo(new ii,n)}function cTn(n){return yM(u(n,123))}function fo(n){return n.vh()&&n.wh()}function mg(n){return n!=Qf&&n!=Pa}function hl(n){return n==Br||n==Xr}function vg(n){return n==us||n==Wf}function uTn(n){return n==P2||n==S2}function xle(n,e){return jc(n.g,e.g)}function oTn(n,e){return new Q4(e,n)}function Fle(n,e){return new Q4(e,n)}function MX(n){return rbe(n.b.Kc(),n.a)}function wL(n,e){cm(n,e),U4(n,n.D)}function gL(n,e,t){aT(n,e),lT(n,t)}function kg(n,e,t){S0(n,e),A0(n,t)}function Ro(n,e,t){eu(n,e),tu(n,t)}function y7(n,e,t){K4(n,e),H4(n,t)}function j7(n,e,t){_4(n,e),q4(n,t)}function sTn(n,e,t){oV.call(this,n,e,t)}function TX(n){SMn.call(this,n,!0)}function fTn(){cC.call(this,"Tail",3)}function hTn(){cC.call(this,"Head",1)}function H1(n){dh(),mve.call(this,n)}function o0(n){iM.call(this,n,n,n,n)}function pL(n){n.c=K(ki,Fn,1,0,5,1)}function AX(n){return n.b&&xF(n),n.a}function SX(n){return n.b&&xF(n),n.c}function Ble(n,e){Uf||(n.b=e)}function Rle(n,e){return n[n.length]=e}function Kle(n,e){return n[n.length]=e}function _le(n,e){return Yb(e,Sf(n))}function Hle(n,e){return Yb(e,Sf(n))}function qle(n,e){return pT(dN(n.d),e)}function Ule(n,e){return pT(dN(n.g),e)}function Gle(n,e){return pT(dN(n.j),e)}function Ni(n,e){Dt.call(this,n.b,e)}function zle(n,e){ve(Sc(n.a),OOn(e))}function Xle(n,e){ve(no(n.a),DOn(e))}function Vle(n,e,t){Ro(t,t.i+n,t.j+e)}function lTn(n,e,t){$t(n.c[e.g],e.g,t)}function Wle(n,e,t){u(n.c,71).Gi(e,t)}function mL(n,e,t){return $t(n,e,t),t}function aTn(n){nu(n.Sf(),new O9n(n))}function yg(n){return n!=null?mt(n):0}function Jle(n){return n==null?0:mt(n)}function T6(n){nt(),Wd.call(this,n)}function dTn(n){this.a=n,HV.call(this,n)}function Tf(){Tf=F,y.Math.log(2)}function Ko(){Ko=F,rl=(gCn(),Moe)}function bTn(){bTn=F,YH=new v5(lU)}function Ie(){Ie=F,new wTn,new Z}function wTn(){new de,new de,new de}function Qle(){throw M(new Kl(QJn))}function Yle(){throw M(new Kl(QJn))}function Zle(){throw M(new Kl(YJn))}function n1e(){throw M(new Kl(YJn))}function vL(n){this.a=n,XE.call(this,n)}function kL(n){this.a=n,XE.call(this,n)}function gTn(n,e){g0(),this.a=n,this.b=e}function e1e(n,e){Se(e),Ag(n).Jc(new Ru)}function Yt(n,e){QL(n.c,n.c.length,e)}function tc(n){return n.ae?1:0}function IX(n,e){return Ec(n,e)>0?n:e}function Yc(n,e,t){return{l:n,m:e,h:t}}function t1e(n,e){n.a!=null&&IMn(e,n.a)}function i1e(n){Zi(n,null),Ii(n,null)}function r1e(n,e,t){return Ve(n.g,t,e)}function jg(n,e,t){return ZY(e,t,n.c)}function c1e(n,e,t){return Ve(n.k,t,e)}function u1e(n,e,t){return GOe(n,e,t),t}function o1e(n,e){return ko(),e.n.b+=n}function mTn(n){ZW.call(this),this.b=n}function OX(n){mV.call(this),this.a=n}function vTn(){cC.call(this,"Range",2)}function DC(n){this.b=n,this.a=new Z}function kTn(n){this.b=new Nbn,this.a=n}function yTn(n){n.a=new OO,n.c=new OO}function jTn(n){n.a=new de,n.d=new de}function ETn(n){$N(n,null),xN(n,null)}function CTn(n,e){return XOe(n.a,e,null)}function s1e(n,e){return Ve(n.a,e.a,e)}function Ki(n){return new V(n.a,n.b)}function DX(n){return new V(n.c,n.d)}function f1e(n){return new V(n.c,n.d)}function A6(n,e){return cOe(n.c,n.b,e)}function D(n,e){return n!=null&&Tx(n,e)}function yL(n,e){return Yve(n.Kc(),e)!=-1}function LC(n){return n.Ob()?n.Pb():null}function h1e(n){this.b=(Dn(),new eD(n))}function LX(n){this.a=n,de.call(this)}function MTn(){C7.call(this,null,null)}function TTn(){KC.call(this,null,null)}function ATn(){je.call(this,"INSTANCE",0)}function STn(){DZ(),this.a=new $5(Son)}function PTn(n){return ws(n,0,n.length)}function l1e(n,e){return new XTn(n.Kc(),e)}function NX(n,e){return n.a.Bc(e)!=null}function ITn(n,e){me(n),n.Gc(u(e,15))}function a1e(n,e,t){n.c.bd(e,u(t,136))}function d1e(n,e,t){n.c.Ui(e,u(t,136))}function OTn(n,e){n.c&&(eW(e),iOn(e))}function b1e(n,e){n.q.setHours(e),K5(n,e)}function w1e(n,e){h0(e,n.a.a.a,n.a.a.b)}function g1e(n,e,t,i){$t(n.a[e.g],t.g,i)}function jL(n,e,t){return n.a[e.g][t.g]}function p1e(n,e){return n.e[e.c.p][e.p]}function m1e(n,e){return n.c[e.c.p][e.p]}function Af(n,e){return n.a[e.c.p][e.p]}function v1e(n,e){return n.j[e.p]=IMe(e)}function EL(n,e){return n.a.Bc(e)!=null}function k1e(n,e){return $(R(e.a))<=n}function y1e(n,e){return $(R(e.a))>=n}function j1e(n,e){return BJ(n.f,e.Pg())}function vp(n,e){return n.a*e.a+n.b*e.b}function E1e(n,e){return n.a0?e/(n*n):e*100}function V1e(n,e){return n>0?e*e/n:e*e*100}function xb(n,e){return u(Nf(n.a,e),34)}function W1e(n,e){return ua(),Pn(n,e.e,e)}function J1e(n,e,t){return ZE(),t.Mg(n,e)}function Q1e(n){return kl(),n.e.a+n.f.a/2}function Y1e(n,e,t){return kl(),t.e.a-n*e}function Z1e(n){return kl(),n.e.b+n.f.b/2}function nae(n,e,t){return kl(),t.e.b-n*e}function oAn(n){n.d=new rAn(n),n.e=new de}function sAn(){this.a=new j0,this.b=new j0}function fAn(n){this.c=n,this.a=1,this.b=1}function hAn(n){YF(),Ayn(this),this.Ff(n)}function eae(n,e,t){YM(),n.pf(e)&&t.Cd(n)}function tae(n,e,t){return nn(e,yBn(n,t))}function h0(n,e,t){return n.a+=e,n.b+=t,n}function iae(n,e,t){return n.a*=e,n.b*=t,n}function YX(n,e){return n.a=e.a,n.b=e.b,n}function _C(n){return n.a=-n.a,n.b=-n.b,n}function O6(n,e,t){return n.a-=e,n.b-=t,n}function lAn(n){Ct.call(this),t5(this,n)}function aAn(){je.call(this,"GROW_TREE",0)}function dAn(){je.call(this,"POLYOMINO",0)}function lo(n,e,t){Iu.call(this,n,e,t,2)}function rae(n,e,t){p5(Sc(n.a),e,OOn(t))}function bAn(n,e){f6(),C7.call(this,n,e)}function ZX(n,e){Gl(),KC.call(this,n,e)}function wAn(n,e){Gl(),ZX.call(this,n,e)}function gAn(n,e){Gl(),KC.call(this,n,e)}function cae(n,e){return n.c.Fc(u(e,136))}function uae(n,e,t){p5(no(n.a),e,DOn(t))}function pAn(n){this.c=n,eu(n,0),tu(n,0)}function PL(n,e){Ko(),uM.call(this,n,e)}function mAn(n,e){Ko(),PL.call(this,n,e)}function nV(n,e){Ko(),PL.call(this,n,e)}function eV(n,e){Ko(),uM.call(this,n,e)}function vAn(n,e){Ko(),nV.call(this,n,e)}function kAn(n,e){Ko(),eV.call(this,n,e)}function yAn(n,e){Ko(),uM.call(this,n,e)}function oae(n,e,t){return e.zl(n.e,n.c,t)}function sae(n,e,t){return e.Al(n.e,n.c,t)}function tV(n,e,t){return qA(fk(n,e),t)}function IL(n,e){return ea(n.e,u(e,54))}function fae(n){return n==null?null:NDe(n)}function hae(n){return n==null?null:Aje(n)}function lae(n){return n==null?null:Jr(n)}function aae(n){return n==null?null:Jr(n)}function un(n){return N6(n==null||Nb(n)),n}function R(n){return N6(n==null||$b(n)),n}function Oe(n){return N6(n==null||Ai(n)),n}function ll(n){n.o==null&&cMe(n)}function iV(n){if(!n)throw M(new W9)}function dae(n){if(!n)throw M(new uD)}function oe(n){if(!n)throw M(new nc)}function Fb(n){if(!n)throw M(new Cu)}function jAn(n){if(!n)throw M(new Bo)}function p4(){p4=F,lE=new cjn,new ujn}function Tg(){Tg=F,D2=new lt("root")}function rV(){rxn.call(this),this.Bb|=hr}function bae(n,e){this.d=n,r9n(this),this.b=e}function cV(n,e){i$.call(this,n),this.a=e}function uV(n,e){i$.call(this,n),this.a=e}function oV(n,e,t){VM.call(this,n,e,t,null)}function EAn(n,e,t){VM.call(this,n,e,t,null)}function A7(n,e){this.c=n,f4.call(this,n,e)}function D6(n,e){this.a=n,A7.call(this,n,e)}function sV(n){this.q=new y.Date(id(n))}function CAn(n){return n>8?0:n+1}function MAn(n,e){Uf||nn(n.a,e)}function wae(n,e){return c7(),J4(e.d.i,n)}function gae(n,e){return Hp(),new tUn(e,n)}function pae(n,e,t){return n.Ne(e,t)<=0?t:e}function mae(n,e,t){return n.Ne(e,t)<=0?e:t}function vae(n,e){return u(Nf(n.b,e),143)}function kae(n,e){return u(Nf(n.c,e),233)}function OL(n){return u(sn(n.a,n.b),293)}function TAn(n){return new V(n.c,n.d+n.a)}function AAn(n){return Jn(n),n?1231:1237}function SAn(n){return ko(),uTn(u(n,203))}function Bb(){Bb=F,ton=yn((go(),Gd))}function yae(n,e){e.a?MCe(n,e):EL(n.a,e.b)}function S7(n,e,t){++n.j,n.tj(),t$(n,e,t)}function PAn(n,e,t){++n.j,n.qj(e,n.Zi(e,t))}function IAn(n,e,t){var i;i=n.fd(e),i.Rb(t)}function fV(n,e,t){return t=So(n,e,6,t),t}function hV(n,e,t){return t=So(n,e,3,t),t}function lV(n,e,t){return t=So(n,e,9,t),t}function uh(n,e){return G7(e,Ntn),n.f=e,n}function aV(n,e){return(e&et)%n.d.length}function OAn(n,e,t){return Uen(n.c,n.b,e,t)}function DAn(n,e){this.c=n,T0.call(this,e)}function LAn(n,e){this.a=n,vyn.call(this,e)}function P7(n,e){this.a=n,vyn.call(this,e)}function Dt(n,e){lt.call(this,n),this.a=e}function dV(n,e){xG.call(this,n),this.a=e}function DL(n,e){xG.call(this,n),this.a=e}function jae(n){XY.call(this,0,0),this.f=n}function NAn(n,e,t){return n.a+=ws(e,0,t),n}function I7(n){return!n.a&&(n.a=new E0n),n.a}function bV(n,e){var t;return t=n.e,n.e=e,t}function wV(n,e){var t;return t=e,!!n.Fe(t)}function Eae(n,e){return _n(),n==e?0:n?1:-1}function Rb(n,e){n.a.bd(n.b,e),++n.b,n.c=-1}function O7(n){n.b?O7(n.b):n.f.c.zc(n.e,n.d)}function $An(n){Hu(n.e),n.d.b=n.d,n.d.a=n.d}function Cae(n,e,t){Va(),e9n(n,e.Ve(n.a,t))}function gV(n,e,t){return Pp(n,u(e,22),t)}function xs(n,e){return HE(new Array(e),n)}function Mae(n){return Ae(U1(n,32))^Ae(n)}function LL(n){return String.fromCharCode(n)}function Tae(n){return n==null?null:n.message}function Aae(n,e,t){return n.apply(e,t)}function Sae(n,e){var t;t=n[DB],t.call(n,e)}function Pae(n,e){var t;t=n[DB],t.call(n,e)}function Iae(n,e){return c7(),!J4(e.d.i,n)}function pV(n,e,t,i){iM.call(this,n,e,t,i)}function xAn(){HC.call(this),this.a=new Li}function mV(){this.n=new Li,this.o=new Li}function FAn(){this.b=new Li,this.c=new Z}function BAn(){this.a=new Z,this.b=new Z}function RAn(){this.a=new KU,this.b=new Fyn}function vV(){this.b=new Ql,this.a=new Ql}function KAn(){this.b=new ni,this.a=new ni}function _An(){this.b=new de,this.a=new de}function HAn(){this.b=new bEn,this.a=new _3n}function qAn(){this.a=new Z5n,this.b=new Dpn}function UAn(){this.a=new Z,this.d=new Z}function HC(){this.n=new up,this.i=new mp}function GAn(n){this.a=(Co(n,mw),new Gc(n))}function zAn(n){this.a=(Co(n,mw),new Gc(n))}function Oae(n){return n<100?null:new F1(n)}function Dae(n,e){return n.n.a=(Jn(e),e+10)}function Lae(n,e){return n.n.a=(Jn(e),e+10)}function Nae(n,e){return e==n||vm(TA(e),n)}function XAn(n,e){return Ve(n.a,e,"")==null}function $ae(n,e){var t;return t=e.qi(n.a),t}function tt(n,e){return n.a+=e.a,n.b+=e.b,n}function mi(n,e){return n.a-=e.a,n.b-=e.b,n}function xae(n){return Ab(n.j.c,0),n.a=-1,n}function kV(n,e,t){return t=So(n,e,11,t),t}function Fae(n,e,t){t!=null&&mT(e,Fx(n,t))}function Bae(n,e,t){t!=null&&vT(e,Fx(n,t))}function jp(n,e,t,i){q.call(this,n,e,t,i)}function yV(n,e,t,i){q.call(this,n,e,t,i)}function VAn(n,e,t,i){yV.call(this,n,e,t,i)}function WAn(n,e,t,i){dM.call(this,n,e,t,i)}function NL(n,e,t,i){dM.call(this,n,e,t,i)}function jV(n,e,t,i){dM.call(this,n,e,t,i)}function JAn(n,e,t,i){NL.call(this,n,e,t,i)}function EV(n,e,t,i){NL.call(this,n,e,t,i)}function Nn(n,e,t,i){jV.call(this,n,e,t,i)}function QAn(n,e,t,i){EV.call(this,n,e,t,i)}function YAn(n,e,t,i){yW.call(this,n,e,t,i)}function Kb(n,e){Ir.call(this,w8+n+Td+e)}function CV(n,e){return n.jk().wi().ri(n,e)}function MV(n,e){return n.jk().wi().ti(n,e)}function ZAn(n,e){return Jn(n),x(n)===x(e)}function An(n,e){return Jn(n),x(n)===x(e)}function Rae(n,e){return n.b.Bd(new jCn(n,e))}function Kae(n,e){return n.b.Bd(new ECn(n,e))}function nSn(n,e){return n.b.Bd(new CCn(n,e))}function _ae(n,e){return n.e=u(n.d.Kb(e),159)}function TV(n,e,t){return n.lastIndexOf(e,t)}function Hae(n,e,t){return bt(n[e.a],n[t.a])}function qae(n,e){return U(e,(cn(),Ej),n)}function Uae(n,e){return jc(e.a.d.p,n.a.d.p)}function Gae(n,e){return jc(n.a.d.p,e.a.d.p)}function zae(n,e){return bt(n.c-n.s,e.c-e.s)}function Xae(n,e){return bt(n.b.e.a,e.b.e.a)}function Vae(n,e){return bt(n.c.e.a,e.c.e.a)}function eSn(n){return n.c?qr(n.c.a,n,0):-1}function Ep(n){return n==Ud||n==tl||n==qc}function AV(n,e){this.c=n,oN.call(this,n,e)}function tSn(n,e,t){this.a=n,WX.call(this,e,t)}function iSn(n){this.c=n,PC.call(this,jy,0)}function rSn(n,e,t){this.c=e,this.b=t,this.a=n}function D7(n){v4(),this.d=n,this.a=new Cg}function cSn(n){oh(),this.a=(Dn(),new i4(n))}function Wae(n,e){hl(n.f)?QCe(n,e):Sye(n,e)}function uSn(n,e){sbe.call(this,n,n.length,e)}function Jae(n,e){Uf||e&&(n.d=e)}function oSn(n,e){return D(e,15)&&xqn(n.c,e)}function Qae(n,e,t){return u(n.c,71).Wk(e,t)}function qC(n,e,t){return u(n.c,71).Xk(e,t)}function Yae(n,e,t){return oae(n,u(e,343),t)}function SV(n,e,t){return sae(n,u(e,343),t)}function Zae(n,e,t){return SKn(n,u(e,343),t)}function sSn(n,e,t){return _ye(n,u(e,343),t)}function L6(n,e){return e==null?null:tw(n.b,e)}function PV(n){return $b(n)?(Jn(n),n):n.ue()}function UC(n){return!isNaN(n)&&!isFinite(n)}function $L(n){yTn(this),vo(this),Bi(this,n)}function _u(n){pL(this),GV(this.c,0,n.Pc())}function _o(n,e,t){this.a=n,this.b=e,this.c=t}function fSn(n,e,t){this.a=n,this.b=e,this.c=t}function hSn(n,e,t){this.d=n,this.b=t,this.a=e}function lSn(n){this.a=n,fl(),vc(Date.now())}function aSn(n){bo(n.a),UJ(n.c,n.b),n.b=null}function xL(){xL=F,Pun=new N0n,AQn=new $0n}function dSn(){dSn=F,Ioe=K(ki,Fn,1,0,5,1)}function bSn(){bSn=F,Voe=K(ki,Fn,1,0,5,1)}function IV(){IV=F,Woe=K(ki,Fn,1,0,5,1)}function oh(){oh=F,new RG((Dn(),Dn(),sr))}function nde(n){return F4(),Ee((kNn(),IQn),n)}function ede(n){return Gu(),Ee((hNn(),xQn),n)}function tde(n){return YT(),Ee((WDn(),HQn),n)}function ide(n){return cT(),Ee((JDn(),qQn),n)}function rde(n){return NA(),Ee((Wxn(),UQn),n)}function cde(n){return wf(),Ee((sNn(),XQn),n)}function ude(n){return Uu(),Ee((oNn(),WQn),n)}function ode(n){return bu(),Ee((fNn(),QQn),n)}function sde(n){return VA(),Ee((GMn(),kYn),n)}function fde(n){return D0(),Ee((jNn(),jYn),n)}function hde(n){return Vp(),Ee((CNn(),CYn),n)}function lde(n){return C5(),Ee((ENn(),AYn),n)}function ade(n){return QE(),Ee((yDn(),SYn),n)}function dde(n){return uT(),Ee((QDn(),GYn),n)}function bde(n){return n5(),Ee((lNn(),pZn),n)}function wde(n){return Vi(),Ee((c$n(),yZn),n)}function gde(n){return Z4(),Ee((TNn(),TZn),n)}function pde(n){return dd(),Ee((MNn(),DZn),n)}function OV(n,e){if(!n)throw M(new Gn(e))}function m4(n){if(!n)throw M(new Or(atn))}function FL(n,e){if(n!=e)throw M(new Bo)}function wSn(n,e,t){this.a=n,this.b=e,this.c=t}function DV(n,e,t){this.a=n,this.b=e,this.c=t}function gSn(n,e,t){this.a=n,this.b=e,this.c=t}function GC(n,e,t){this.b=n,this.a=e,this.c=t}function LV(n,e,t){this.b=n,this.c=e,this.a=t}function NV(n,e,t){this.a=n,this.b=e,this.c=t}function zC(n,e,t){this.e=e,this.b=n,this.d=t}function pSn(n,e,t){this.b=n,this.a=e,this.c=t}function mde(n,e,t){return Va(),n.a.Yd(e,t),e}function BL(n){var e;return e=new cbn,e.e=n,e}function $V(n){var e;return e=new Hyn,e.b=n,e}function L7(){L7=F,CP=new ogn,MP=new sgn}function XC(){XC=F,XZn=new $gn,zZn=new xgn}function Fs(){Fs=F,YZn=new U2n,ZZn=new G2n}function vde(n){return I0(),Ee((qLn(),fne),n)}function kde(n){return tr(),Ee((zMn(),HZn),n)}function yde(n){return OT(),Ee((SNn(),GZn),n)}function jde(n){return xf(),Ee((ANn(),tne),n)}function Ede(n){return ow(),Ee((u$n(),rne),n)}function Cde(n){return DA(),Ee((Nxn(),hne),n)}function Mde(n){return Yp(),Ee((O$n(),lne),n)}function Tde(n){return QM(),Ee((eLn(),ane),n)}function Ade(n){return i5(),Ee((KLn(),dne),n)}function Sde(n){return bT(),Ee((_Ln(),bne),n)}function Pde(n){return o1(),Ee((o$n(),wne),n)}function Ide(n){return bk(),Ee((nLn(),gne),n)}function Ode(n){return ym(),Ee((N$n(),jne),n)}function Dde(n){return pr(),Ee((lFn(),Ene),n)}function Lde(n){return Y4(),Ee((GLn(),Cne),n)}function Nde(n){return vl(),Ee((ULn(),Tne),n)}function $de(n){return KM(),Ee((oLn(),Ane),n)}function xde(n){return Xk(),Ee((L$n(),yne),n)}function Fde(n){return hd(),Ee((HLn(),mne),n)}function Bde(n){return vA(),Ee((D$n(),vne),n)}function Rde(n){return ok(),Ee((ZDn(),kne),n)}function Kde(n){return Yo(),Ee((f$n(),Sne),n)}function _de(n){return a1(),Ee((zxn(),Yte),n)}function Hde(n){return d5(),Ee((zLn(),Zte),n)}function qde(n){return cw(),Ee((PNn(),nie),n)}function Ude(n){return E5(),Ee((s$n(),eie),n)}function Gde(n){return ps(),Ee((aFn(),tie),n)}function zde(n){return lh(),Ee((INn(),iie),n)}function Xde(n){return ak(),Ee((tLn(),rie),n)}function Vde(n){return gr(),Ee((WLn(),uie),n)}function Wde(n){return ST(),Ee((XLn(),oie),n)}function Jde(n){return h5(),Ee((VLn(),sie),n)}function Qde(n){return um(),Ee((QLn(),fie),n)}function Yde(n){return dT(),Ee((JLn(),hie),n)}function Zde(n){return DT(),Ee((YLn(),lie),n)}function n0e(n){return P0(),Ee((uNn(),Aie),n)}function e0e(n){return Q6(),Ee((iLn(),Die),n)}function t0e(n){return fh(),Ee((rLn(),Rie),n)}function i0e(n){return Pf(),Ee((cLn(),_ie),n)}function r0e(n){return af(),Ee((uLn(),tre),n)}function c0e(n){return E0(),Ee((sLn(),fre),n)}function u0e(n){return Qp(),Ee((FNn(),hre),n)}function o0e(n){return B5(),Ee((XMn(),lre),n)}function s0e(n){return l5(),Ee((ZLn(),are),n)}function f0e(n){return a5(),Ee((xNn(),$re),n)}function h0e(n){return FM(),Ee((hLn(),xre),n)}function l0e(n){return yT(),Ee((lLn(),_re),n)}function a0e(n){return wA(),Ee((h$n(),qre),n)}function d0e(n){return Sk(),Ee((nNn(),Gre),n)}function b0e(n){return ZM(),Ee((fLn(),Ure),n)}function w0e(n){return sA(),Ee(($Nn(),lce),n)}function g0e(n){return AT(),Ee((eNn(),ace),n)}function p0e(n){return XT(),Ee((tNn(),dce),n)}function m0e(n){return rA(),Ee((iNn(),wce),n)}function v0e(n){return _T(),Ee((rNn(),mce),n)}function k0e(n){return GM(),Ee((aLn(),Rce),n)}function y0e(n){return X4(),Ee((YDn(),_Zn),n)}function j0e(n){return Vn(),Ee(($$n(),xZn),n)}function E0e(n){return nT(),Ee((cNn(),Kce),n)}function C0e(n){return N$(),Ee((dLn(),_ce),n)}function M0e(n){return N5(),Ee((l$n(),qce),n)}function T0e(n){return nC(),Ee((PDn(),Gce),n)}function A0e(n){return Nk(),Ee((dNn(),Uce),n)}function S0e(n){return eC(),Ee((IDn(),Xce),n)}function P0e(n){return tk(),Ee((bLn(),Vce),n)}function I0e(n){return Wk(),Ee((a$n(),Wce),n)}function O0e(n){return u6(),Ee((ODn(),lue),n)}function D0e(n){return Ck(),Ee((wLn(),aue),n)}function L0e(n){return pf(),Ee((b$n(),mue),n)}function N0e(n){return l1(),Ee((Dxn(),kue),n)}function $0e(n){return Rh(),Ee((x$n(),yue),n)}function x0e(n){return wd(),Ee((F$n(),Aue),n)}function F0e(n){return ci(),Ee((d$n(),zue),n)}function B0e(n){return $f(),Ee((bNn(),Xue),n)}function R0e(n){return El(),Ee((BNn(),Vue),n)}function K0e(n){return pA(),Ee((B$n(),Wue),n)}function _0e(n){return jl(),Ee((aNn(),Que),n)}function H0e(n){return To(),Ee((RNn(),Zue),n)}function q0e(n){return lw(),Ee((Vxn(),noe),n)}function U0e(n){return Bg(),Ee((w$n(),eoe),n)}function G0e(n){return Oi(),Ee((R$n(),toe),n)}function z0e(n){return zu(),Ee((K$n(),ioe),n)}function X0e(n){return en(),Ee((g$n(),roe),n)}function V0e(n){return go(),Ee((KNn(),foe),n)}function W0e(n){return io(),Ee((Xxn(),hoe),n)}function J0e(n){return Gp(),Ee((wNn(),loe),n)}function Q0e(n,e){return Jn(n),n+(Jn(e),e)}function Y0e(n){return RL(),Ee((gLn(),aoe),n)}function Z0e(n){return qT(),Ee((_Nn(),doe),n)}function nbe(n){return LT(),Ee((HNn(),goe),n)}function v4(){v4=F,nln=(en(),Wn),II=Zn}function RL(){RL=F,mdn=new XSn,vdn=new DPn}function ebe(n){return!n.e&&(n.e=new Z),n.e}function KL(n,e){this.c=n,this.a=e,this.b=e-n}function mSn(n,e,t){this.a=n,this.b=e,this.c=t}function _L(n,e,t){this.a=n,this.b=e,this.c=t}function xV(n,e,t){this.a=n,this.b=e,this.c=t}function FV(n,e,t){this.a=n,this.b=e,this.c=t}function vSn(n,e,t){this.a=n,this.b=e,this.c=t}function kSn(n,e,t){this.a=n,this.b=e,this.c=t}function Xl(n,e,t){this.e=n,this.a=e,this.c=t}function ySn(n,e,t){Ko(),eJ.call(this,n,e,t)}function HL(n,e,t){Ko(),BW.call(this,n,e,t)}function BV(n,e,t){Ko(),BW.call(this,n,e,t)}function RV(n,e,t){Ko(),BW.call(this,n,e,t)}function jSn(n,e,t){Ko(),HL.call(this,n,e,t)}function KV(n,e,t){Ko(),HL.call(this,n,e,t)}function ESn(n,e,t){Ko(),KV.call(this,n,e,t)}function CSn(n,e,t){Ko(),BV.call(this,n,e,t)}function MSn(n,e,t){Ko(),RV.call(this,n,e,t)}function qL(n){iM.call(this,n.d,n.c,n.a,n.b)}function _V(n){iM.call(this,n.d,n.c,n.a,n.b)}function HV(n){this.d=n,r9n(this),this.b=nwe(n.d)}function tbe(n){return Em(),Ee((Lxn(),Poe),n)}function N7(n,e){return Se(n),Se(e),new LEn(n,e)}function Cp(n,e){return Se(n),Se(e),new BSn(n,e)}function ibe(n,e){return Se(n),Se(e),new RSn(n,e)}function rbe(n,e){return Se(n),Se(e),new HEn(n,e)}function UL(n){return oe(n.b!=0),Xo(n,n.a.a)}function cbe(n){return oe(n.b!=0),Xo(n,n.c.b)}function ube(n){return!n.c&&(n.c=new V3),n.c}function k4(n){var e;return e=new Z,b$(e,n),e}function obe(n){var e;return e=new ni,b$(e,n),e}function TSn(n){var e;return e=new UG,A$(e,n),e}function $7(n){var e;return e=new Ct,A$(e,n),e}function u(n,e){return N6(n==null||Tx(n,e)),n}function sbe(n,e,t){MPn.call(this,e,t),this.a=n}function ASn(n,e){this.c=n,this.b=e,this.a=!1}function SSn(){this.a=";,;",this.b="",this.c=""}function PSn(n,e,t){this.b=n,KMn.call(this,e,t)}function qV(n,e,t){this.c=n,uC.call(this,e,t)}function UV(n,e,t){a4.call(this,n,e),this.b=t}function GV(n,e,t){xnn(t,0,n,e,t.length,!1)}function Lh(n,e,t,i,r){n.b=e,n.c=t,n.d=i,n.a=r}function zV(n,e,t,i,r){n.d=e,n.c=t,n.a=i,n.b=r}function fbe(n,e){e&&(n.b=e,n.a=(X1(e),e.a))}function x7(n,e){if(!n)throw M(new Gn(e))}function Mp(n,e){if(!n)throw M(new Or(e))}function XV(n,e){if(!n)throw M(new Fjn(e))}function hbe(n,e){return YE(),jc(n.d.p,e.d.p)}function lbe(n,e){return kl(),bt(n.e.b,e.e.b)}function abe(n,e){return kl(),bt(n.e.a,e.e.a)}function dbe(n,e){return jc(USn(n.d),USn(e.d))}function VC(n,e){return e&&mM(n,e.d)?e:null}function bbe(n,e){return e==(en(),Wn)?n.c:n.d}function VV(n){return Y1(dwe(Vr(n)?ds(n):n))}function wbe(n){return new V(n.c+n.b,n.d+n.a)}function ISn(n){return n!=null&&!lx(n,O9,D9)}function gbe(n,e){return(sBn(n)<<4|sBn(e))&ui}function OSn(n,e,t,i,r){n.c=e,n.d=t,n.b=i,n.a=r}function WV(n){var e,t;e=n.b,t=n.c,n.b=t,n.c=e}function JV(n){var e,t;t=n.d,e=n.a,n.d=e,n.a=t}function pbe(n,e){var t;return t=n.c,SQ(n,e),t}function QV(n,e){return e<0?n.g=-1:n.g=e,n}function WC(n,e){return Mme(n),n.a*=e,n.b*=e,n}function DSn(n,e,t){T$n.call(this,e,t),this.d=n}function F7(n,e,t){gX.call(this,n,e),this.c=t}function JC(n,e,t){gX.call(this,n,e),this.c=t}function YV(n){IV(),CE.call(this),this.ci(n)}function LSn(){N4(),Bwe.call(this,(R1(),Ps))}function NSn(n){return nt(),new Nh(0,n)}function $Sn(){$Sn=F,TU=(Dn(),new nD(IK))}function QC(){QC=F,new fZ((bD(),HK),(dD(),_K))}function xSn(){xSn=F,wun=K(Gi,J,17,256,0,1)}function FSn(){this.b=$(R(rn((Us(),y_))))}function GL(n){this.b=n,this.a=Ja(this.b.a).Od()}function BSn(n,e){this.b=n,this.a=e,GO.call(this)}function RSn(n,e){this.a=n,this.b=e,GO.call(this)}function KSn(n,e,t){this.a=n,pg.call(this,e,t)}function _Sn(n,e,t){this.a=n,pg.call(this,e,t)}function y4(n,e,t){var i;i=new qb(t),bf(n,e,i)}function ZV(n,e,t){var i;return i=n[e],n[e]=t,i}function YC(n){var e;return e=n.slice(),o$(e,n)}function ZC(n){var e;return e=n.n,n.a.b+e.d+e.a}function HSn(n){var e;return e=n.n,n.e.b+e.d+e.a}function nW(n){var e;return e=n.n,n.e.a+e.b+e.c}function eW(n){n.a.b=n.b,n.b.a=n.a,n.a=n.b=null}function Fe(n,e){return xt(n,e,n.c.b,n.c),!0}function mbe(n){return n.a?n.a:vN(n)}function vbe(n){return Lp(),Kh(n)==At(ra(n))}function kbe(n){return Lp(),ra(n)==At(Kh(n))}function l0(n,e){return S5(n,new a4(e.a,e.b))}function ybe(n,e){return kM(),Nx(n,e),new hIn(n,e)}function jbe(n,e){return n.c=e)throw M(new QG)}function _b(n,e){return Dk(n,(Jn(e),new l9n(e)))}function Ap(n,e){return Dk(n,(Jn(e),new a9n(e)))}function APn(n,e,t){return VLe(n,u(e,12),u(t,12))}function SPn(n){return Ou(),u(n,12).g.c.length!=0}function PPn(n){return Ou(),u(n,12).e.c.length!=0}function uwe(n,e){return Hp(),bt(e.a.o.a,n.a.o.a)}function owe(n,e){e.Bb&kc&&!n.a.o&&(n.a.o=e)}function swe(n,e){e.Ug("General 'Rotator",1),jDe(n)}function fwe(n,e,t){e.qf(t,$(R(ee(n.b,t)))*n.a)}function IPn(n,e,t){return Vg(),V4(n,e)&&V4(n,t)}function B6(n){return zu(),!n.Hc(Fl)&&!n.Hc(Ia)}function hwe(n){return n.e?HJ(n.e):null}function R6(n){return Vr(n)?""+n:$qn(n)}function kW(n){var e;for(e=n;e.f;)e=e.f;return e}function lwe(n,e,t){return $t(e,0,uW(e[0],t[0])),e}function Vl(n,e,t,i){var r;r=n.i,r.i=e,r.a=t,r.b=i}function q(n,e,t,i){ti.call(this,n,e,t),this.b=i}function Ci(n,e,t,i,r){c$.call(this,n,e,t,i,r,-1)}function K6(n,e,t,i,r){rk.call(this,n,e,t,i,r,-1)}function dM(n,e,t,i){F7.call(this,n,e,t),this.b=i}function OPn(n){SMn.call(this,n,!1),this.a=!1}function DPn(){oMn.call(this,"LOOKAHEAD_LAYOUT",1)}function LPn(n){this.b=n,kp.call(this,n),BTn(this)}function NPn(n){this.b=n,M7.call(this,n),RTn(this)}function Hb(n,e,t){this.a=n,jp.call(this,e,t,5,6)}function yW(n,e,t,i){this.b=n,ti.call(this,e,t,i)}function $Pn(n,e){this.b=n,_8n.call(this,n.b),this.a=e}function xPn(n){this.a=vRn(n.a),this.b=new _u(n.b)}function jW(n,e){g0(),Hhe.call(this,n,FT(new Ku(e)))}function bM(n,e){return nt(),new FW(n,e,0)}function rN(n,e){return nt(),new FW(6,n,e)}function _i(n,e){for(Jn(e);n.Ob();)e.Cd(n.Pb())}function Zc(n,e){return Ai(e)?AN(n,e):!!wr(n.f,e)}function cN(n,e){return e.Vh()?ea(n.b,u(e,54)):e}function awe(n,e){return An(n.substr(0,e.length),e)}function $h(n){return new ie(new qX(n.a.length,n.a))}function wM(n){return new V(n.c+n.b/2,n.d+n.a/2)}function dwe(n){return Yc(~n.l&ro,~n.m&ro,~n.h&Il)}function uN(n){return typeof n===my||typeof n===eB}function Hu(n){n.f=new tTn(n),n.i=new iTn(n),++n.g}function FPn(n){if(!n)throw M(new nc);return n.d}function Sp(n){var e;return e=f5(n),oe(e!=null),e}function bwe(n){var e;return e=I5e(n),oe(e!=null),e}function E4(n,e){var t;return t=n.a.gc(),FJ(e,t),t-e}function fi(n,e){var t;return t=n.a.zc(e,n),t==null}function R7(n,e){return n.a.zc(e,(_n(),ga))==null}function EW(n){return new Tn(null,vwe(n,n.length))}function CW(n,e,t){return cGn(n,u(e,42),u(t,176))}function Pp(n,e,t){return _s(n.a,e),ZV(n.b,e.g,t)}function wwe(n,e,t){j4(t,n.a.c.length),Go(n.a,t,e)}function B(n,e,t,i){$Fn(e,t,n.length),gwe(n,e,t,i)}function gwe(n,e,t,i){var r;for(r=e;r0?y.Math.log(n/e):-100}function RPn(n,e){return Ec(n,e)<0?-1:Ec(n,e)>0?1:0}function K7(n,e){ITn(n,D(e,160)?e:u(e,2036).Rl())}function SW(n,e){if(n==null)throw M(new fp(e))}function vwe(n,e){return yme(e,n.length),new zSn(n,e)}function PW(n,e){return e?Bi(n,e):!1}function kwe(){return BE(),A(T(uQn,1),G,549,0,[GK])}function H6(n){return n.e==0?n:new Ya(-n.e,n.d,n.a)}function ywe(n,e){return bt(n.c.c+n.c.b,e.c.c+e.c.b)}function _7(n,e){xt(n.d,e,n.b.b,n.b),++n.a,n.c=null}function KPn(n,e){return n.c?KPn(n.c,e):nn(n.b,e),n}function jwe(n,e,t){var i;return i=Jb(n,e),qN(n,e,t),i}function _Pn(n,e,t){var i;for(i=0;i=n.g}function $t(n,e,t){return dae(t==null||sPe(n,t)),n[e]=t}function NW(n,e){return zn(e,n.length+1),n.substr(e)}function gN(n,e){for(Jn(e);n.c=n?new Oz:Gme(n-1)}function Hi(n){return!n.a&&n.c?n.c.b:n.a}function RW(n){return D(n,616)?n:new uOn(n)}function X1(n){n.c?X1(n.c):(ta(n),n.d=!0)}function G6(n){n.c?n.c.$e():(n.d=!0,fTe(n))}function oIn(n){n.b=!1,n.c=!1,n.d=!1,n.a=!1}function sIn(n){var e,t;return e=n.c.i.c,t=n.d.i.c,e==t}function _we(n,e){var t;t=n.Ih(e),t>=0?n.ki(t):Ann(n,e)}function fIn(n,e){n.c<0||n.b.b0;)n=n<<1|(n<0?1:0);return n}function pIn(n,e){var t;return t=new Lc(n),Rn(e.c,t),t}function mIn(n,e){n.u.Hc((zu(),Fl))&&zEe(n,e),h4e(n,e)}function mc(n,e){return x(n)===x(e)||n!=null&&rt(n,e)}function Cr(n,e){return JL(n.a,e)?n.b[u(e,22).g]:null}function nge(){return QE(),A(T(con,1),G,488,0,[b_])}function ege(){return nC(),A(T(N1n,1),G,489,0,[Fq])}function tge(){return eC(),A(T(zce,1),G,558,0,[Bq])}function ige(){return u6(),A(T(ean,1),G,539,0,[_j])}function yM(n){return!n.n&&(n.n=new q(Ar,n,1,7)),n.n}function mN(n){return!n.c&&(n.c=new q(Qu,n,9,9)),n.c}function qW(n){return!n.c&&(n.c=new Nn(he,n,5,8)),n.c}function rge(n){return!n.b&&(n.b=new Nn(he,n,4,7)),n.b}function H7(n){return n.j.c.length=0,GW(n.c),xae(n.a),n}function S4(n){return n.e==iv&&jfe(n,Y8e(n.g,n.b)),n.e}function q7(n){return n.f==iv&&Cfe(n,q7e(n.g,n.b)),n.f}function We(n,e,t,i){return _xn(n,e,t,!1),BT(n,i),n}function vIn(n,e){this.b=n,oN.call(this,n,e),BTn(this)}function kIn(n,e){this.b=n,AV.call(this,n,e),RTn(this)}function z6(n){this.d=n,this.a=this.d.b,this.b=this.d.c}function UW(n,e){this.b=n,this.c=e,this.a=new dp(this.b)}function Xi(n,e){return zn(e,n.length),n.charCodeAt(e)}function cge(n,e){OY(n,$(yl(e,"x")),$(yl(e,"y")))}function uge(n,e){OY(n,$(yl(e,"x")),$(yl(e,"y")))}function ut(n,e){return ta(n),new Tn(n,new eQ(e,n.a))}function _r(n,e){return ta(n),new Tn(n,new KJ(e,n.a))}function Ub(n,e){return ta(n),new cV(n,new PLn(e,n.a))}function jM(n,e){return ta(n),new uV(n,new ILn(e,n.a))}function oge(n,e){return new UIn(u(Se(n),50),u(Se(e),50))}function sge(n,e){return bt(n.d.c+n.d.b/2,e.d.c+e.d.b/2)}function yIn(n,e,t){t.a?tu(n,e.b-n.f/2):eu(n,e.a-n.g/2)}function fge(n,e){return bt(n.g.c+n.g.b/2,e.g.c+e.g.b/2)}function hge(n,e){return Nz(),bt((Jn(n),n),(Jn(e),e))}function lge(n){return n!=null&&t7(jO,n.toLowerCase())}function GW(n){var e;for(e=n.Kc();e.Ob();)e.Pb(),e.Qb()}function Ag(n){var e;return e=n.b,!e&&(n.b=e=new L8n(n)),e}function vN(n){var e;return e=Wme(n),e||null}function jIn(n,e){var t,i;return t=n/e,i=wi(t),t>i&&++i,i}function age(n,e,t){var i;i=u(n.d.Kb(t),159),i&&i.Nb(e)}function dge(n,e,t){wIe(n.a,t),zve(t),xCe(n.b,t),xIe(e,t)}function EM(n,e,t,i){this.a=n,this.c=e,this.b=t,this.d=i}function zW(n,e,t,i){this.c=n,this.b=e,this.a=t,this.d=i}function EIn(n,e,t,i){this.c=n,this.b=e,this.d=t,this.a=i}function Ho(n,e,t,i){this.c=n,this.d=e,this.b=t,this.a=i}function CIn(n,e,t,i){this.a=n,this.d=e,this.c=t,this.b=i}function kN(n,e,t,i){this.a=n,this.e=e,this.d=t,this.c=i}function MIn(n,e,t,i){this.a=n,this.c=e,this.d=t,this.b=i}function yN(n,e,t){this.a=mtn,this.d=n,this.b=e,this.c=t}function Op(n,e,t,i){je.call(this,n,e),this.a=t,this.b=i}function TIn(n,e){this.d=(Jn(n),n),this.a=16449,this.c=e}function AIn(n){this.a=new Z,this.e=K(ye,J,53,n,0,2)}function bge(n){n.Ug("No crossing minimization",1),n.Vg()}function SIn(){ec.call(this,"There is no more element.")}function PIn(n,e,t,i){this.a=n,this.b=e,this.c=t,this.d=i}function IIn(n,e,t,i){this.a=n,this.b=e,this.c=t,this.d=i}function Za(n,e,t,i){this.e=n,this.a=e,this.c=t,this.d=i}function OIn(n,e,t,i){this.a=n,this.c=e,this.d=t,this.b=i}function DIn(n,e,t,i){Ko(),OLn.call(this,e,t,i),this.a=n}function LIn(n,e,t,i){Ko(),OLn.call(this,e,t,i),this.a=n}function jN(n,e,t){var i,r;return i=rtn(n),r=e.ti(t,i),r}function al(n){var e,t;return t=(e=new Jd,e),R4(t,n),t}function EN(n){var e,t;return t=(e=new Jd,e),snn(t,n),t}function wge(n,e){var t;return t=ee(n.f,e),_Q(e,t),null}function NIn(n){return!n.b&&(n.b=new q(Vt,n,12,3)),n.b}function $In(n){return N6(n==null||uN(n)&&n.Tm!==Q2),n}function CM(n){return n.n&&(n.e!==Fzn&&n.je(),n.j=null),n}function P4(n){if(eo(n.d),n.d.d!=n.c)throw M(new Bo)}function XW(n){return oe(n.b0&&dKn(this)}function xIn(n,e){this.a=n,bae.call(this,n,u(n.d,15).fd(e))}function gge(n,e){return bt(Su(n)*ao(n),Su(e)*ao(e))}function pge(n,e){return bt(Su(n)*ao(n),Su(e)*ao(e))}function mge(n){return R0(n)&&on(un(z(n,(cn(),Nd))))}function vge(n,e){return Pn(n,u(v(e,(cn(),Ev)),17),e)}function kge(n,e){return u(v(n,(W(),T3)),15).Fc(e),e}function VW(n,e){return n.b=e.b,n.c=e.c,n.d=e.d,n.a=e.a,n}function FIn(n,e,t,i){this.b=n,this.c=i,PC.call(this,e,t)}function yge(n,e,t){n.i=0,n.e=0,e!=t&&kFn(n,e,t)}function jge(n,e,t){n.i=0,n.e=0,e!=t&&yFn(n,e,t)}function Ege(n,e,t){return c6(),J5e(u(ee(n.e,e),529),t)}function Dp(n){var e;return e=n.f,e||(n.f=new f4(n,n.c))}function BIn(n,e){return Fg(n.j,e.s,e.c)+Fg(e.e,n.s,n.c)}function RIn(n,e){n.e&&!n.e.a&&(Tyn(n.e,e),RIn(n.e,e))}function KIn(n,e){n.d&&!n.d.a&&(Tyn(n.d,e),KIn(n.d,e))}function Cge(n,e){return-bt(Su(n)*ao(n),Su(e)*ao(e))}function Mge(n){return u(n.ld(),149).Pg()+":"+Jr(n.md())}function _In(){tF(this,new uG),this.wb=(G1(),Hn),u4()}function HIn(n){this.b=new Z,hi(this.b,this.b),this.a=n}function WW(n,e){new Ct,this.a=new Mu,this.b=n,this.c=e}function k0(){k0=F,Aun=new xU,ZK=new xU,Sun=new O0n}function Dn(){Dn=F,sr=new T0n,Wh=new S0n,hP=new P0n}function JW(){JW=F,RQn=new Z0n,_Qn=new lW,KQn=new nbn}function Lp(){Lp=F,mP=new Z,m_=new de,p_=new Z}function MM(n,e){if(n==null)throw M(new fp(e));return n}function TM(n){return!n.a&&(n.a=new q(Ye,n,10,11)),n.a}function ft(n){return!n.q&&(n.q=new q(Ss,n,11,10)),n.q}function H(n){return!n.s&&(n.s=new q(ku,n,21,17)),n.s}function Tge(n){return Se(n),PRn(new ie(ce(n.a.Kc(),new En)))}function Age(n,e){return wo(n),wo(e),xjn(u(n,22),u(e,22))}function nd(n,e,t){var i,r;i=PV(t),r=new TE(i),bf(n,e,r)}function MN(n,e,t,i,r,c){rk.call(this,n,e,t,i,r,c?-2:-1)}function qIn(n,e,t,i){gX.call(this,e,t),this.b=n,this.a=i}function UIn(n,e){Vfe.call(this,new iN(n)),this.a=n,this.b=e}function QW(n){this.b=n,this.c=n,n.e=null,n.c=null,this.a=1}function Sge(n){Fs();var e;e=u(n.g,10),e.n.a=n.d.c+e.d.b}function I4(){I4=F;var n,e;e=!$8e(),n=new X3,VK=e?new og:n}function TN(n){return Dn(),D(n,59)?new jD(n):new FC(n)}function AM(n){return D(n,16)?new $6(u(n,16)):obe(n.Kc())}function Pge(n){return new _Tn(n,n.e.Rd().gc()*n.c.Rd().gc())}function Ige(n){return new HTn(n,n.e.Rd().gc()*n.c.Rd().gc())}function YW(n){return n&&n.hashCode?n.hashCode():f0(n)}function AN(n,e){return e==null?!!wr(n.f,null):zbe(n.i,e)}function Oge(n,e){var t;return t=NX(n.a,e),t&&(e.d=null),t}function GIn(n,e,t){return n.f?n.f.ef(e,t):!1}function U7(n,e,t,i){$t(n.c[e.g],t.g,i),$t(n.c[t.g],e.g,i)}function SN(n,e,t,i){$t(n.c[e.g],e.g,t),$t(n.b[e.g],e.g,i)}function Dge(n,e,t){return $(R(t.a))<=n&&$(R(t.b))>=e}function zIn(n,e){this.g=n,this.d=A(T(Qh,1),b1,10,0,[e])}function XIn(n){this.c=n,this.b=new Ul(u(Se(new ebn),50))}function VIn(n){this.c=n,this.b=new Ul(u(Se(new nwn),50))}function WIn(n){this.b=n,this.a=new Ul(u(Se(new Lbn),50))}function JIn(){this.b=new ni,this.d=new Ct,this.e=new YG}function ZW(){this.c=new Li,this.d=new Li,this.e=new Li}function y0(){this.a=new Mu,this.b=(Co(3,mw),new Gc(3))}function Wl(n,e){this.e=n,this.a=ki,this.b=Qqn(e),this.c=e}function SM(n){this.c=n.c,this.d=n.d,this.b=n.b,this.a=n.a}function QIn(n,e,t,i,r,c){this.a=n,k$.call(this,e,t,i,r,c)}function YIn(n,e,t,i,r,c){this.a=n,k$.call(this,e,t,i,r,c)}function V1(n,e,t,i,r,c,s){return new GN(n.e,e,t,i,r,c,s)}function Lge(n,e,t){return t>=0&&An(n.substr(t,e.length),e)}function ZIn(n,e){return D(e,149)&&An(n.b,u(e,149).Pg())}function Nge(n,e){return n.a?e.Gh().Kc():u(e.Gh(),71).Ii()}function nOn(n,e){var t;return t=n.b.Qc(e),VDn(t,n.b.gc()),t}function G7(n,e){if(n==null)throw M(new fp(e));return n}function Hr(n){return n.u||(Zu(n),n.u=new LAn(n,n)),n.u}function PN(n){this.a=(Dn(),D(n,59)?new jD(n):new FC(n))}function au(n){var e;return e=u(Un(n,16),29),e||n.ii()}function PM(n,e){var t;return t=Xa(n.Rm),e==null?t:t+": "+e}function qo(n,e,t){return Fi(e,t,n.length),n.substr(e,t-e)}function eOn(n,e){HC.call(this),hQ(this),this.a=n,this.c=e}function $ge(n){n&&PM(n,n.ie())}function xge(n){_E(),y.setTimeout(function(){throw n},0)}function Fge(){return YT(),A(T(xun,1),G,436,0,[o_,$un])}function Bge(){return cT(),A(T(Bun,1),G,435,0,[Fun,s_])}function Rge(){return uT(),A(T(aon,1),G,432,0,[v_,vP])}function Kge(){return X4(),A(T(KZn,1),G,517,0,[aj,L_])}function _ge(){return ok(),A(T(xsn,1),G,487,0,[$sn,QP])}function Hge(){return bk(),A(T(Lsn,1),G,428,0,[WP,Dsn])}function qge(){return QM(),A(T(Msn,1),G,431,0,[Csn,V_])}function Uge(){return ak(),A(T(_hn,1),G,430,0,[UH,GH])}function Gge(){return Q6(),A(T(Oie,1),G,531,0,[Z8,Y8])}function zge(){return fh(),A(T(Bie,1),G,523,0,[gb,y1])}function Xge(){return Pf(),A(T(Kie,1),G,522,0,[Rd,Xf])}function Vge(){return af(),A(T(ere,1),G,528,0,[zw,Ea])}function Wge(){return KM(),A(T(Wsn,1),G,429,0,[fH,Vsn])}function Jge(){return GM(),A(T(A1n,1),G,490,0,[Nq,T1n])}function Qge(){return N$(),A(T(L1n,1),G,491,0,[O1n,D1n])}function Yge(){return FM(),A(T(xln,1),G,433,0,[dq,$ln])}function Zge(){return ZM(),A(T(Rln,1),G,434,0,[Bln,vq])}function n2e(){return E0(),A(T(sre,1),G,464,0,[Ca,I2])}function e2e(){return yT(),A(T(Fln,1),G,500,0,[RI,L2])}function t2e(){return tk(),A(T($1n,1),G,438,0,[Rq,JI])}function i2e(){return Ck(),A(T(ian,1),G,437,0,[YI,tan])}function r2e(){return RL(),A(T(dO,1),G,347,0,[mdn,vdn])}function IM(n,e,t,i){return t>=0?n.Uh(e,t,i):n.Ch(null,t,i)}function z7(n){return n.b.b==0?n.a.sf():UL(n.b)}function c2e(n){if(n.p!=5)throw M(new Cu);return Ae(n.f)}function u2e(n){if(n.p!=5)throw M(new Cu);return Ae(n.k)}function nJ(n){return x(n.a)===x((D$(),EU))&&rOe(n),n.a}function o2e(n,e){n.b=e,n.c>0&&n.b>0&&(n.g=rM(n.c,n.b,n.a))}function s2e(n,e){n.c=e,n.c>0&&n.b>0&&(n.g=rM(n.c,n.b,n.a))}function tOn(n,e){ufe(this,new V(n.a,n.b)),ofe(this,$7(e))}function j0(){Wfe.call(this,new ap(Qb(12))),RX(!0),this.a=2}function IN(n,e,t){nt(),Wd.call(this,n),this.b=e,this.a=t}function eJ(n,e,t){Ko(),DE.call(this,e),this.a=n,this.b=t}function iOn(n){var e;e=n.c.d.b,n.b=e,n.a=n.c.d,e.a=n.c.d.b=n}function f2e(n){return n.b==0?null:(oe(n.b!=0),Xo(n,n.a.a))}function Nc(n,e){return e==null?Kr(wr(n.f,null)):h6(n.i,e)}function rOn(n,e,t,i,r){return new rF(n,(F4(),i_),e,t,i,r)}function OM(n,e){return GDn(e),Lme(n,K(ye,_e,28,e,15,1),e)}function DM(n,e){return MM(n,"set1"),MM(e,"set2"),new XEn(n,e)}function h2e(n,e){var t=XK[n.charCodeAt(0)];return t??n}function cOn(n,e){var t,i;return t=e,i=new DO,LGn(n,t,i),i.d}function ON(n,e,t,i){var r;r=new xAn,e.a[t.g]=r,Pp(n.b,i,r)}function l2e(n,e){var t;return t=Ime(n.f,e),tt(_C(t),n.f.d)}function LM(n){var e;_me(n.a),aTn(n.a),e=new PE(n.a),_Y(e)}function a2e(n,e){_qn(n,!0),nu(n.e.Rf(),new LV(n,!0,e))}function d2e(n,e){return Lp(),n==At(Kh(e))||n==At(ra(e))}function b2e(n,e){return kl(),u(v(e,(lc(),Sh)),17).a==n}function wi(n){return Math.max(Math.min(n,et),-2147483648)|0}function uOn(n){this.a=u(Se(n),277),this.b=(Dn(),new zX(n))}function oOn(n,e,t){this.i=new Z,this.b=n,this.g=e,this.a=t}function tJ(n,e,t){this.a=new Z,this.e=n,this.f=e,this.c=t}function NM(n,e,t){this.c=new Z,this.e=n,this.f=e,this.b=t}function sOn(n){HC.call(this),hQ(this),this.a=n,this.c=!0}function w2e(n){function e(){}return e.prototype=n||{},new e}function g2e(n){if(n.Ae())return null;var e=n.n;return rP[e]}function X7(n){return n.Db>>16!=3?null:u(n.Cb,27)}function Sf(n){return n.Db>>16!=9?null:u(n.Cb,27)}function fOn(n){return n.Db>>16!=6?null:u(n.Cb,74)}function E0(){E0=F,Ca=new rX(s3,0),I2=new rX(f3,1)}function fh(){fh=F,gb=new eX(f3,0),y1=new eX(s3,1)}function Pf(){Pf=F,Rd=new tX(_B,0),Xf=new tX("UP",1)}function hOn(){hOn=F,oQn=Ce((BE(),A(T(uQn,1),G,549,0,[GK])))}function lOn(n){var e;return e=new GE(Qb(n.length)),nY(e,n),e}function aOn(n,e){return n.b+=e.b,n.c+=e.c,n.d+=e.d,n.a+=e.a,n}function p2e(n,e){return Yxn(n,e)?(V$n(n),!0):!1}function dl(n,e){if(e==null)throw M(new rp);return F8e(n,e)}function V7(n,e){var t;t=n.q.getHours(),n.q.setDate(e),K5(n,t)}function iJ(n,e,t){var i;i=n.Ih(e),i>=0?n.bi(i,t):nen(n,e,t)}function dOn(n,e){var t;return t=n.Ih(e),t>=0?n.Wh(t):hF(n,e)}function bOn(n,e){var t;for(Se(e),t=n.a;t;t=t.c)e.Yd(t.g,t.i)}function DN(n,e,t){var i;i=mFn(n,e,t),n.b=new ET(i.c.length)}function Sg(n,e,t){$M(),n&&Ve(kU,n,e),n&&Ve(fE,n,t)}function m2e(n,e){return XC(),_n(),u(e.a,17).a0}function rJ(n){var e;return e=n.d,e=n.bj(n.f),ve(n,e),e.Ob()}function wOn(n,e){var t;return t=new sW(e),KKn(t,n),new _u(t)}function y2e(n){if(n.p!=0)throw M(new Cu);return j6(n.f,0)}function j2e(n){if(n.p!=0)throw M(new Cu);return j6(n.k,0)}function gOn(n){return n.Db>>16!=7?null:u(n.Cb,241)}function O4(n){return n.Db>>16!=6?null:u(n.Cb,241)}function pOn(n){return n.Db>>16!=7?null:u(n.Cb,167)}function At(n){return n.Db>>16!=11?null:u(n.Cb,27)}function Gb(n){return n.Db>>16!=17?null:u(n.Cb,29)}function mOn(n){return n.Db>>16!=3?null:u(n.Cb,155)}function cJ(n){var e;return ta(n),e=new ni,ut(n,new C9n(e))}function vOn(n,e){var t=n.a=n.a||[];return t[e]||(t[e]=n.ve(e))}function E2e(n,e){var t;t=n.q.getHours(),n.q.setMonth(e),K5(n,t)}function kOn(n,e){$C(this),this.f=e,this.g=n,CM(this),this.je()}function yOn(n,e){this.a=n,this.c=Ki(this.a),this.b=new SM(e)}function jOn(n,e,t){this.a=e,this.c=n,this.b=(Se(t),new _u(t))}function EOn(n,e,t){this.a=e,this.c=n,this.b=(Se(t),new _u(t))}function COn(n){this.a=n,this.b=K(Sie,J,2043,n.e.length,0,2)}function MOn(){this.a=new rh,this.e=new ni,this.g=0,this.i=0}function $M(){$M=F,kU=new de,fE=new de,ple(MQn,new bvn)}function TOn(){TOn=F,aie=Pu(new ii,(Vi(),zr),(tr(),dj))}function uJ(){uJ=F,die=Pu(new ii,(Vi(),zr),(tr(),dj))}function AOn(){AOn=F,wie=Pu(new ii,(Vi(),zr),(tr(),dj))}function SOn(){SOn=F,Lie=Ke(new ii,(Vi(),zr),(tr(),O8))}function ko(){ko=F,xie=Ke(new ii,(Vi(),zr),(tr(),O8))}function POn(){POn=F,Fie=Ke(new ii,(Vi(),zr),(tr(),O8))}function NN(){NN=F,Hie=Ke(new ii,(Vi(),zr),(tr(),O8))}function X6(n,e,t,i,r,c){return new ml(n.e,e,n.Lj(),t,i,r,c)}function Dr(n,e,t){return e==null?Vc(n.f,null,t):L0(n.i,e,t)}function Zi(n,e){n.c&&du(n.c.g,n),n.c=e,n.c&&nn(n.c.g,n)}function $i(n,e){n.c&&du(n.c.a,n),n.c=e,n.c&&nn(n.c.a,n)}function ic(n,e){n.i&&du(n.i.j,n),n.i=e,n.i&&nn(n.i.j,n)}function Ii(n,e){n.d&&du(n.d.e,n),n.d=e,n.d&&nn(n.d.e,n)}function $N(n,e){n.a&&du(n.a.k,n),n.a=e,n.a&&nn(n.a.k,n)}function xN(n,e){n.b&&du(n.b.f,n),n.b=e,n.b&&nn(n.b.f,n)}function IOn(n,e){$we(n,n.b,n.c),u(n.b.b,68),e&&u(e.b,68).b}function C2e(n,e){return bt(u(n.c,65).c.e.b,u(e.c,65).c.e.b)}function M2e(n,e){return bt(u(n.c,65).c.e.a,u(e.c,65).c.e.a)}function T2e(n){return Y$(),_n(),u(n.a,86).d.e!=0}function xM(n,e){D(n.Cb,184)&&(u(n.Cb,184).tb=null),zc(n,e)}function FN(n,e){D(n.Cb,90)&&hw(Zu(u(n.Cb,90)),4),zc(n,e)}function A2e(n,e){DY(n,e),D(n.Cb,90)&&hw(Zu(u(n.Cb,90)),2)}function S2e(n,e){var t,i;t=e.c,i=t!=null,i&&Ip(n,new qb(e.c))}function OOn(n){var e,t;return t=(u4(),e=new Jd,e),R4(t,n),t}function DOn(n){var e,t;return t=(u4(),e=new Jd,e),R4(t,n),t}function LOn(n){for(var e;;)if(e=n.Pb(),!n.Ob())return e}function P2e(n,e,t){return nn(n.a,(kM(),Nx(e,t),new t0(e,t))),n}function $c(n,e){return dr(),a$(e)?new nM(e,n):new k7(e,n)}function W7(n){return dh(),Ec(n,0)>=0?ia(n):H6(ia(n1(n)))}function I2e(n){var e;return e=u(YC(n.b),9),new _o(n.a,e,n.c)}function NOn(n,e){var t;return t=u(tw(Dp(n.a),e),16),t?t.gc():0}function $On(n,e,t){var i;uBn(e,t,n.c.length),i=t-e,Sz(n.c,e,i)}function Jl(n,e,t){uBn(e,t,n.gc()),this.c=n,this.a=e,this.b=t-e}function Np(n){this.c=new Ct,this.b=n.b,this.d=n.c,this.a=n.a}function BN(n){this.a=y.Math.cos(n),this.b=y.Math.sin(n)}function ed(n,e,t,i){this.c=n,this.d=i,$N(this,e),xN(this,t)}function oJ(n,e){Xfe.call(this,new ap(Qb(n))),Co(e,Ozn),this.a=e}function xOn(n,e,t){return new rF(n,(F4(),t_),null,!1,e,t)}function FOn(n,e,t){return new rF(n,(F4(),r_),e,t,null,!1)}function O2e(){return Gu(),A(T(xr,1),G,108,0,[Nun,Yr,Aw])}function D2e(){return bu(),A(T(JQn,1),G,471,0,[kf,ma,Xs])}function L2e(){return Uu(),A(T(VQn,1),G,470,0,[Mh,pa,zs])}function N2e(){return wf(),A(T(Sw,1),G,237,0,[bc,Wc,wc])}function $2e(){return n5(),A(T(Aon,1),G,391,0,[E_,j_,C_])}function x2e(){return I0(),A(T(R_,1),G,372,0,[rb,va,ib])}function F2e(){return i5(),A(T(Asn,1),G,322,0,[L8,gj,Tsn])}function B2e(){return bT(),A(T(Psn,1),G,351,0,[Ssn,VP,W_])}function R2e(){return hd(),A(T(pne,1),G,459,0,[Y_,pv,m2])}function K2e(){return Y4(),A(T(sH,1),G,298,0,[uH,oH,pj])}function _2e(){return vl(),A(T(Mne,1),G,311,0,[mj,k2,E3])}function H2e(){return d5(),A(T(Ohn,1),G,390,0,[FH,Ihn,MI])}function q2e(){return gr(),A(T(cie,1),G,462,0,[W8,Vu,Jc])}function U2e(){return ST(),A(T(Uhn,1),G,387,0,[Hhn,zH,qhn])}function G2e(){return h5(),A(T(Ghn,1),G,349,0,[VH,XH,Pj])}function z2e(){return um(),A(T(Xhn,1),G,350,0,[WH,zhn,J8])}function X2e(){return dT(),A(T(Jhn,1),G,352,0,[Whn,JH,Vhn])}function V2e(){return DT(),A(T(Qhn,1),G,388,0,[QH,Iv,Gw])}function W2e(){return P0(),A(T(Tie,1),G,463,0,[Ij,Q8,PI])}function If(n){return cc(A(T(Ei,1),J,8,0,[n.i.n,n.n,n.a]))}function J2e(){return l5(),A(T(bln,1),G,392,0,[dln,nq,Dj])}function BOn(){BOn=F,Fre=Pu(new ii,(Qp(),e9),(B5(),rln))}function FM(){FM=F,dq=new cX("DFS",0),$ln=new cX("BFS",1)}function ROn(n,e,t){var i;i=new j3n,i.b=e,i.a=t,++e.b,nn(n.d,i)}function Q2e(n,e,t){var i;i=new rr(t.d),tt(i,n),OY(e,i.a,i.b)}function Y2e(n,e){DTn(n,Ae(vi(d0(e,24),YA)),Ae(vi(e,YA)))}function zb(n,e){if(n<0||n>e)throw M(new Ir(Atn+n+Stn+e))}function Ln(n,e){if(n<0||n>=e)throw M(new Ir(Atn+n+Stn+e))}function zn(n,e){if(n<0||n>=e)throw M(new wz(Atn+n+Stn+e))}function In(n,e){this.b=(Jn(n),n),this.a=e&vw?e:e|64|wh}function sJ(n){var e;return ta(n),e=(k0(),k0(),ZK),fT(n,e)}function Z2e(n,e,t){var i;return i=q5(n,e,!1),i.b<=e&&i.a<=t}function npe(){return nT(),A(T(I1n,1),G,439,0,[$q,P1n,S1n])}function epe(){return _T(),A(T(h1n,1),G,394,0,[f1n,Oq,s1n])}function tpe(){return XT(),A(T(o1n,1),G,445,0,[Fj,qI,Mq])}function ipe(){return rA(),A(T(bce,1),G,455,0,[Tq,Sq,Aq])}function rpe(){return Sk(),A(T(Hln,1),G,393,0,[KI,Kln,_ln])}function cpe(){return AT(),A(T(u1n,1),G,299,0,[Cq,c1n,r1n])}function upe(){return $f(),A(T(Yan,1),G,278,0,[xv,Jw,Fv])}function ope(){return Gp(),A(T(pdn,1),G,280,0,[gdn,Yw,aO])}function spe(){return jl(),A(T(hdn,1),G,346,0,[uO,M1,j9])}function fpe(){return Nk(),A(T(xq,1),G,444,0,[XI,VI,WI])}function C0(n){return Se(n),D(n,16)?new _u(u(n,16)):k4(n.Kc())}function fJ(n,e){return n&&n.equals?n.equals(e):x(n)===x(e)}function vi(n,e){return Y1(ewe(Vr(n)?ds(n):n,Vr(e)?ds(e):e))}function lf(n,e){return Y1(twe(Vr(n)?ds(n):n,Vr(e)?ds(e):e))}function RN(n,e){return Y1(iwe(Vr(n)?ds(n):n,Vr(e)?ds(e):e))}function hpe(n,e){var t;return t=(Jn(n),n).g,iV(!!t),Jn(e),t(e)}function KOn(n,e){var t,i;return i=E4(n,e),t=n.a.fd(i),new GEn(n,t)}function lpe(n){return n.Db>>16!=6?null:u(dF(n),241)}function ape(n){if(n.p!=2)throw M(new Cu);return Ae(n.f)&ui}function dpe(n){if(n.p!=2)throw M(new Cu);return Ae(n.k)&ui}function E(n){return oe(n.ai?1:0}function UOn(n,e){var t,i;return t=s$(e),i=t,u(ee(n.c,i),17).a}function KN(n,e,t){var i;i=n.d[e.p],n.d[e.p]=n.d[t.p],n.d[t.p]=i}function Cpe(n,e,t){var i;n.n&&e&&t&&(i=new cvn,nn(n.e,i))}function _N(n,e){if(fi(n.a,e),e.d)throw M(new ec(nXn));e.d=n}function aJ(n,e){this.a=new Z,this.d=new Z,this.f=n,this.c=e}function GOn(){this.c=new STn,this.a=new NLn,this.b=new zyn,hCn()}function zOn(){qp(),this.b=new de,this.a=new de,this.c=new Z}function XOn(n,e,t){this.d=n,this.j=e,this.e=t,this.o=-1,this.p=3}function VOn(n,e,t){this.d=n,this.k=e,this.f=t,this.o=-1,this.p=5}function WOn(n,e,t,i,r,c){aQ.call(this,n,e,t,i,r),c&&(this.o=-2)}function JOn(n,e,t,i,r,c){dQ.call(this,n,e,t,i,r),c&&(this.o=-2)}function QOn(n,e,t,i,r,c){IJ.call(this,n,e,t,i,r),c&&(this.o=-2)}function YOn(n,e,t,i,r,c){gQ.call(this,n,e,t,i,r),c&&(this.o=-2)}function ZOn(n,e,t,i,r,c){OJ.call(this,n,e,t,i,r),c&&(this.o=-2)}function nDn(n,e,t,i,r,c){bQ.call(this,n,e,t,i,r),c&&(this.o=-2)}function eDn(n,e,t,i,r,c){wQ.call(this,n,e,t,i,r),c&&(this.o=-2)}function tDn(n,e,t,i,r,c){DJ.call(this,n,e,t,i,r),c&&(this.o=-2)}function iDn(n,e,t,i){DE.call(this,t),this.b=n,this.c=e,this.d=i}function rDn(n,e){this.f=n,this.a=(N4(),MO),this.c=MO,this.b=e}function cDn(n,e){this.g=n,this.d=(N4(),TO),this.a=TO,this.b=e}function dJ(n,e){!n.c&&(n.c=new Rt(n,0)),HA(n.c,(at(),N9),e)}function Mpe(n,e){return oMe(n,e,D(e,102)&&(u(e,19).Bb&hr)!=0)}function Tpe(n,e){return RPn(vc(n.q.getTime()),vc(e.q.getTime()))}function uDn(n){return XL(n.e.Rd().gc()*n.c.Rd().gc(),16,new I8n(n))}function Ape(n){return!!n.u&&Sc(n.u.a).i!=0&&!(n.n&&Ix(n.n))}function Spe(n){return!!n.a&&no(n.a.a).i!=0&&!(n.b&&Ox(n.b))}function bJ(n,e){return e==0?!!n.o&&n.o.f!=0:Cx(n,e)}function Ppe(n,e,t){var i;return i=u(n.Zb().xc(e),16),!!i&&i.Hc(t)}function oDn(n,e,t){var i;return i=u(n.Zb().xc(e),16),!!i&&i.Mc(t)}function sDn(n,e){var t;return t=1-e,n.a[t]=jT(n.a[t],t),jT(n,e)}function fDn(n,e){var t,i;return i=vi(n,mr),t=Bs(e,32),lf(t,i)}function hDn(n,e,t){var i;i=(Se(n),new _u(n)),O7e(new jOn(i,e,t))}function J7(n,e,t){var i;i=(Se(n),new _u(n)),D7e(new EOn(i,e,t))}function fc(n,e,t,i,r,c){return _xn(n,e,t,c),EY(n,i),CY(n,r),n}function lDn(n,e,t,i){return n.a+=""+qo(e==null?gu:Jr(e),t,i),n}function xi(n,e){this.a=n,Gv.call(this,n),zb(e,n.gc()),this.b=e}function aDn(n){this.a=K(ki,Fn,1,JQ(y.Math.max(8,n))<<1,5,1)}function Q7(n){return u(Ff(n,K(Qh,b1,10,n.c.length,0,1)),199)}function hh(n){return u(Ff(n,K(O_,rR,18,n.c.length,0,1)),482)}function dDn(n){return n.a?n.e.length==0?n.a.a:n.a.a+(""+n.e):n.c}function V6(n){for(;n.d>0&&n.a[--n.d]==0;);n.a[n.d++]==0&&(n.e=0)}function bDn(n){return oe(n.b.b!=n.d.a),n.c=n.b=n.b.b,--n.a,n.c.c}function Ipe(n,e,t){n.a=e,n.c=t,n.b.a.$b(),vo(n.d),Ab(n.e.a.c,0)}function wDn(n,e){var t;n.e=new cz,t=aw(e),Yt(t,n.c),Iqn(n,t,0)}function ri(n,e,t,i){var r;r=new ZU,r.a=e,r.b=t,r.c=i,Fe(n.a,r)}function Q(n,e,t,i){var r;r=new ZU,r.a=e,r.b=t,r.c=i,Fe(n.b,r)}function gDn(n,e,t){if(n<0||et)throw M(new Ir(qje(n,e,t)))}function Y7(n,e){if(n<0||n>=e)throw M(new Ir(kEe(n,e)));return n}function Ope(n){if(!("stack"in n))try{throw n}catch{}return n}function Pg(n){return c6(),D(n.g,10)?u(n.g,10):null}function Dpe(n){return Ag(n).dc()?!1:(e1e(n,new Pr),!0)}function id(n){var e;return Vr(n)?(e=n,e==-0?0:e):X4e(n)}function pDn(n,e){return D(e,44)?xx(n.a,u(e,44)):!1}function mDn(n,e){return D(e,44)?xx(n.a,u(e,44)):!1}function vDn(n,e){return D(e,44)?xx(n.a,u(e,44)):!1}function wJ(n){var e;return X1(n),e=new D0n,lg(n.a,new y9n(e)),e}function gJ(){var n,e,t;return e=(t=(n=new Jd,n),t),nn(Zdn,e),e}function BM(n){var e;return X1(n),e=new L0n,lg(n.a,new j9n(e)),e}function Lpe(n,e){return n.a<=n.b?(e.Dd(n.a++),!0):!1}function kDn(n){P$.call(this,n,(F4(),e_),null,!1,null,!1)}function yDn(){yDn=F,SYn=Ce((QE(),A(T(con,1),G,488,0,[b_])))}function jDn(){jDn=F,Zhn=bIn(Y(1),Y(4)),Yhn=bIn(Y(1),Y(2))}function Npe(n,e){return new _L(e,O6(Ki(e.e),n,n),(_n(),!0))}function RM(n){return new Gc((Co(n,cB),oT(nr(nr(5,n),n/10|0))))}function $pe(n){return XL(n.e.Rd().gc()*n.c.Rd().gc(),273,new P8n(n))}function EDn(n){return u(Ff(n,K(FZn,DXn,12,n.c.length,0,1)),2042)}function xpe(n){return ko(),!fr(n)&&!(!fr(n)&&n.c.i.c==n.d.i.c)}function Fpe(n,e){return _p(),u(v(e,(lc(),O2)),17).a>=n.gc()}function W6(n,e){vLe(e,n),WV(n.d),WV(u(v(n,(cn(),mI)),214))}function HN(n,e){kLe(e,n),JV(n.d),JV(u(v(n,(cn(),mI)),214))}function Bpe(n,e,t){n.d&&du(n.d.e,n),n.d=e,n.d&&a0(n.d.e,t,n)}function Rpe(n,e,t){return t.f.c.length>0?CW(n.a,e,t):CW(n.b,e,t)}function Kpe(n,e,t){var i;i=i9e();try{return Aae(n,e,t)}finally{D3e(i)}}function M0(n,e){var t,i;return t=dl(n,e),i=null,t&&(i=t.pe()),i}function J6(n,e){var t,i;return t=dl(n,e),i=null,t&&(i=t.se()),i}function D4(n,e){var t,i;return t=Jb(n,e),i=null,t&&(i=t.se()),i}function bl(n,e){var t,i;return t=dl(n,e),i=null,t&&(i=wnn(t)),i}function _pe(n,e,t){var i;return i=bm(t),FA(n.g,i,e),FA(n.i,e,t),e}function pJ(n,e,t){this.d=new N7n(this),this.e=n,this.i=e,this.f=t}function CDn(n,e,t,i){this.e=null,this.c=n,this.d=e,this.a=t,this.b=i}function MDn(n,e,t,i){jTn(this),this.c=n,this.e=e,this.f=t,this.b=i}function mJ(n,e,t,i){this.d=n,this.n=e,this.g=t,this.o=i,this.p=-1}function TDn(n,e,t,i){return D(t,59)?new tAn(n,e,t,i):new mW(n,e,t,i)}function L4(n){return D(n,16)?u(n,16).dc():!n.Kc().Ob()}function ADn(n){if(n.e.g!=n.b)throw M(new Bo);return!!n.c&&n.d>0}function be(n){return oe(n.b!=n.d.c),n.c=n.b,n.b=n.b.a,++n.a,n.c.c}function vJ(n,e){Jn(e),$t(n.a,n.c,e),n.c=n.c+1&n.a.length-1,WRn(n)}function W1(n,e){Jn(e),n.b=n.b-1&n.a.length-1,$t(n.a,n.b,e),WRn(n)}function SDn(n){var e;e=n.Gh(),this.a=D(e,71)?u(e,71).Ii():e.Kc()}function Hpe(n){return new In(Ame(u(n.a.md(),16).gc(),n.a.ld()),16)}function PDn(){PDn=F,Gce=Ce((nC(),A(T(N1n,1),G,489,0,[Fq])))}function IDn(){IDn=F,Xce=Ce((eC(),A(T(zce,1),G,558,0,[Bq])))}function ODn(){ODn=F,lue=Ce((u6(),A(T(ean,1),G,539,0,[_j])))}function qpe(){return dd(),A(T(Oon,1),G,389,0,[Ow,Ion,P_,I_])}function Upe(){return F4(),A(T(lP,1),G,303,0,[e_,t_,i_,r_])}function Gpe(){return Vp(),A(T(EYn,1),G,332,0,[cj,rj,uj,oj])}function zpe(){return C5(),A(T(TYn,1),G,406,0,[sj,wP,gP,fj])}function Xpe(){return D0(),A(T(yYn,1),G,417,0,[ij,tj,a_,d_])}function Vpe(){return Z4(),A(T(MZn,1),G,416,0,[tb,Iw,Pw,d2])}function Wpe(){return xf(),A(T(ene,1),G,421,0,[j3,hv,lv,B_])}function Jpe(){return OT(),A(T(UZn,1),G,371,0,[F_,HP,qP,bj])}function Qpe(){return cw(),A(T(RH,1),G,203,0,[TI,BH,P2,S2])}function Ype(){return lh(),A(T(Khn,1),G,284,0,[k1,Rhn,HH,qH])}function Zpe(n){var e;return n.j==(en(),ae)&&(e=mHn(n),Au(e,Zn))}function n3e(n,e){var t;t=e.a,Zi(t,e.c.d),Ii(t,e.d.d),nw(t.a,n.n)}function kJ(n,e){var t;return t=u(Nf(n.b,e),67),!t&&(t=new Ct),t}function xp(n){return c6(),D(n.g,154)?u(n.g,154):null}function e3e(n){n.a=null,n.e=null,Ab(n.b.c,0),Ab(n.f.c,0),n.c=null}function KM(){KM=F,fH=new Yz(Hm,0),Vsn=new Yz("TOP_LEFT",1)}function Q6(){Q6=F,Z8=new nX("UPPER",0),Y8=new nX("LOWER",1)}function t3e(n,e){return vp(new V(e.e.a+e.f.a/2,e.e.b+e.f.b/2),n)}function DDn(n,e){return u(ho(_b(u(ot(n.k,e),15).Oc(),w2)),113)}function LDn(n,e){return u(ho(Ap(u(ot(n.k,e),15).Oc(),w2)),113)}function i3e(){return Qp(),A(T(tln,1),G,405,0,[LI,n9,e9,t9])}function r3e(){return a5(),A(T(Nln,1),G,353,0,[aq,BI,lq,hq])}function c3e(){return sA(),A(T(i1n,1),G,354,0,[Eq,e1n,t1n,n1n])}function u3e(){return go(),A(T(A9,1),G,386,0,[iE,Gd,tE,Qw])}function o3e(){return To(),A(T(Yue,1),G,290,0,[Zj,nl,Aa,Yj])}function s3e(){return El(),A(T(lU,1),G,223,0,[hU,Qj,Bv,x3])}function f3e(){return qT(),A(T(Edn,1),G,320,0,[bU,kdn,jdn,ydn])}function h3e(){return LT(),A(T(woe,1),G,415,0,[wU,Mdn,Cdn,Tdn])}function l3e(n){return $M(),Zc(kU,n)?u(ee(kU,n),341).Qg():null}function Uo(n,e,t){return e<0?hF(n,t):u(t,69).wk().Bk(n,n.hi(),e)}function a3e(n,e,t){var i;return i=bm(t),FA(n.j,i,e),Ve(n.k,e,t),e}function d3e(n,e,t){var i;return i=bm(t),FA(n.d,i,e),Ve(n.e,e,t),e}function NDn(n){var e,t;return e=(B1(),t=new HO,t),n&&AA(e,n),e}function yJ(n){var e;return e=n.aj(n.i),n.i>0&&Ic(n.g,0,e,0,n.i),e}function $Dn(n,e){var t;for(t=n.j.c.length;t>24}function w3e(n){if(n.p!=1)throw M(new Cu);return Ae(n.k)<<24>>24}function g3e(n){if(n.p!=7)throw M(new Cu);return Ae(n.k)<<16>>16}function p3e(n){if(n.p!=7)throw M(new Cu);return Ae(n.f)<<16>>16}function Ig(n,e){return e.e==0||n.e==0?T8:(Tm(),vF(n,e))}function BDn(n,e){return x(e)===x(n)?"(this Map)":e==null?gu:Jr(e)}function m3e(n,e,t){return tN(R(Kr(wr(n.f,e))),R(Kr(wr(n.f,t))))}function v3e(n,e,t){var i;i=u(ee(n.g,t),60),nn(n.a.c,new bi(e,i))}function RDn(n,e,t){n.i=0,n.e=0,e!=t&&(yFn(n,e,t),kFn(n,e,t))}function k3e(n,e,t,i,r){var c;c=yMe(r,t,i),nn(e,dEe(r,c)),rje(n,r,e)}function jJ(n,e,t,i,r){this.i=n,this.a=e,this.e=t,this.j=i,this.f=r}function KDn(n,e){ZW.call(this),this.a=n,this.b=e,nn(this.a.b,this)}function _Dn(n){this.b=new de,this.c=new de,this.d=new de,this.a=n}function HDn(n,e){var t;return t=new fg,n.Gd(t),t.a+="..",e.Hd(t),t.a}function qDn(n,e){var t;for(t=e;t;)h0(n,t.i,t.j),t=At(t);return n}function UDn(n,e,t){var i;return i=bm(t),Ve(n.b,i,e),Ve(n.c,e,t),e}function wl(n){var e;for(e=0;n.Ob();)n.Pb(),e=nr(e,1);return oT(e)}function Fh(n,e){dr();var t;return t=u(n,69).vk(),kje(t,e),t.xl(e)}function y3e(n,e,t){if(t){var i=t.oe();n.a[e]=i(t)}else delete n.a[e]}function EJ(n,e){var t;t=n.q.getHours(),n.q.setFullYear(e+ha),K5(n,t)}function j3e(n,e){return u(e==null?Kr(wr(n.f,null)):h6(n.i,e),288)}function CJ(n,e){return n==(Vn(),zt)&&e==zt?4:n==zt||e==zt?8:32}function _M(n,e,t){return RA(n,e,t,D(e,102)&&(u(e,19).Bb&hr)!=0)}function E3e(n,e,t){return Im(n,e,t,D(e,102)&&(u(e,19).Bb&hr)!=0)}function C3e(n,e,t){return bMe(n,e,t,D(e,102)&&(u(e,19).Bb&hr)!=0)}function MJ(n){n.b!=n.c&&(n.a=K(ki,Fn,1,8,5,1),n.b=0,n.c=0)}function Y6(n){return oe(n.a=0&&n.a[t]===e[t];t--);return t<0}function HM(n){var e;return n?new sW(n):(e=new rh,A$(e,n),e)}function O3e(n,e){var t,i;i=!1;do t=hFn(n,e),i=i|t;while(t);return i}function D3e(n){n&&rme((lz(),uun)),--cP,n&&uP!=-1&&(Ele(uP),uP=-1)}function qM(n){ZZ(),DTn(this,Ae(vi(d0(n,24),YA)),Ae(vi(n,YA)))}function WDn(){WDn=F,HQn=Ce((YT(),A(T(xun,1),G,436,0,[o_,$un])))}function JDn(){JDn=F,qQn=Ce((cT(),A(T(Bun,1),G,435,0,[Fun,s_])))}function QDn(){QDn=F,GYn=Ce((uT(),A(T(aon,1),G,432,0,[v_,vP])))}function YDn(){YDn=F,_Zn=Ce((X4(),A(T(KZn,1),G,517,0,[aj,L_])))}function ZDn(){ZDn=F,kne=Ce((ok(),A(T(xsn,1),G,487,0,[$sn,QP])))}function nLn(){nLn=F,gne=Ce((bk(),A(T(Lsn,1),G,428,0,[WP,Dsn])))}function eLn(){eLn=F,ane=Ce((QM(),A(T(Msn,1),G,431,0,[Csn,V_])))}function tLn(){tLn=F,rie=Ce((ak(),A(T(_hn,1),G,430,0,[UH,GH])))}function iLn(){iLn=F,Die=Ce((Q6(),A(T(Oie,1),G,531,0,[Z8,Y8])))}function rLn(){rLn=F,Rie=Ce((fh(),A(T(Bie,1),G,523,0,[gb,y1])))}function cLn(){cLn=F,_ie=Ce((Pf(),A(T(Kie,1),G,522,0,[Rd,Xf])))}function uLn(){uLn=F,tre=Ce((af(),A(T(ere,1),G,528,0,[zw,Ea])))}function oLn(){oLn=F,Ane=Ce((KM(),A(T(Wsn,1),G,429,0,[fH,Vsn])))}function sLn(){sLn=F,fre=Ce((E0(),A(T(sre,1),G,464,0,[Ca,I2])))}function fLn(){fLn=F,Ure=Ce((ZM(),A(T(Rln,1),G,434,0,[Bln,vq])))}function hLn(){hLn=F,xre=Ce((FM(),A(T(xln,1),G,433,0,[dq,$ln])))}function lLn(){lLn=F,_re=Ce((yT(),A(T(Fln,1),G,500,0,[RI,L2])))}function aLn(){aLn=F,Rce=Ce((GM(),A(T(A1n,1),G,490,0,[Nq,T1n])))}function dLn(){dLn=F,_ce=Ce((N$(),A(T(L1n,1),G,491,0,[O1n,D1n])))}function bLn(){bLn=F,Vce=Ce((tk(),A(T($1n,1),G,438,0,[Rq,JI])))}function wLn(){wLn=F,aue=Ce((Ck(),A(T(ian,1),G,437,0,[YI,tan])))}function gLn(){gLn=F,aoe=Ce((RL(),A(T(dO,1),G,347,0,[mdn,vdn])))}function L3e(){return ci(),A(T(k9,1),G,88,0,[Jf,Xr,Br,Wf,us])}function N3e(){return en(),A(T(lr,1),Mc,64,0,[sc,Xn,Zn,ae,Wn])}function $3e(n,e,t){return u(e==null?Vc(n.f,null,t):L0(n.i,e,t),288)}function x3e(n){return(n.k==(Vn(),zt)||n.k==Zt)&&kt(n,(W(),F8))}function XN(n){return n.c&&n.d?lJ(n.c)+"->"+lJ(n.d):"e_"+f0(n)}function qi(n,e){var t,i;for(Jn(e),i=n.Kc();i.Ob();)t=i.Pb(),e.Cd(t)}function F3e(n,e){var t;t=new sp,nd(t,"x",e.a),nd(t,"y",e.b),Ip(n,t)}function B3e(n,e){var t;t=new sp,nd(t,"x",e.a),nd(t,"y",e.b),Ip(n,t)}function pLn(n,e){var t;for(t=e;t;)h0(n,-t.i,-t.j),t=At(t);return n}function AJ(n,e){var t,i;for(t=e,i=0;t>0;)i+=n.a[t],t-=t&-t;return i}function Go(n,e,t){var i;return i=(Ln(e,n.c.length),n.c[e]),n.c[e]=t,i}function SJ(n,e,t){n.a.c.length=0,fOe(n,e,t),n.a.c.length==0||FSe(n,e)}function Z7(n){n.i=0,u7(n.b,null),u7(n.c,null),n.a=null,n.e=null,++n.g}function UM(){UM=F,Uf=!0,DQn=!1,LQn=!1,$Qn=!1,NQn=!1}function VN(n){UM(),!Uf&&(this.c=n,this.e=!0,this.a=new Z)}function mLn(n,e){this.c=0,this.b=e,_Mn.call(this,n,17493),this.a=this.c}function vLn(n){jzn(),Ayn(this),this.a=new Ct,oY(this,n),Fe(this.a,n)}function kLn(){pL(this),this.b=new V(St,St),this.a=new V(li,li)}function GM(){GM=F,Nq=new sX(iin,0),T1n=new sX("TARGET_WIDTH",1)}function Og(n,e){return(ta(n),o4(new Tn(n,new eQ(e,n.a)))).Bd(v3)}function R3e(){return Vi(),A(T(Son,1),G,367,0,[Vs,Jh,Oc,Kc,zr])}function K3e(){return ow(),A(T(ine,1),G,375,0,[wj,zP,XP,GP,UP])}function _3e(){return o1(),A(T(Osn,1),G,348,0,[J_,Isn,Q_,gv,wv])}function H3e(){return E5(),A(T(Lhn,1),G,323,0,[Dhn,KH,_H,X8,V8])}function q3e(){return Yo(),A(T(sfn,1),G,171,0,[jj,R8,ya,K8,xw])}function U3e(){return wA(),A(T(Hre,1),G,368,0,[pq,bq,mq,wq,gq])}function G3e(){return N5(),A(T(Hce,1),G,373,0,[N2,O3,a9,l9,Kj])}function z3e(){return Wk(),A(T(R1n,1),G,324,0,[x1n,Kq,B1n,_q,F1n])}function X3e(){return pf(),A(T(Zh,1),G,170,0,[xn,pi,Ph,Kd,E1])}function V3e(){return Bg(),A(T(C9,1),G,256,0,[Sa,nE,ldn,E9,adn])}function W3e(n){return _E(),function(){return Kpe(n,this,arguments)}}function fr(n){return!n.c||!n.d?!1:!!n.c.i&&n.c.i==n.d.i}function PJ(n,e){return D(e,143)?An(n.c,u(e,143).c):!1}function Zu(n){return n.t||(n.t=new pyn(n),p5(new Ljn(n),0,n.t)),n.t}function yLn(n){this.b=n,ne.call(this,n),this.a=u(Un(this.b.a,4),129)}function jLn(n){this.b=n,yp.call(this,n),this.a=u(Un(this.b.a,4),129)}function Rs(n,e,t,i,r){DLn.call(this,e,i,r),this.c=n,this.b=t}function IJ(n,e,t,i,r){XOn.call(this,e,i,r),this.c=n,this.a=t}function OJ(n,e,t,i,r){VOn.call(this,e,i,r),this.c=n,this.a=t}function DJ(n,e,t,i,r){DLn.call(this,e,i,r),this.c=n,this.a=t}function WN(n,e){var t;return t=u(Nf(n.d,e),23),t||u(Nf(n.e,e),23)}function ELn(n,e){var t,i;return t=e.ld(),i=n.Fe(t),!!i&&mc(i.e,e.md())}function CLn(n,e){var t;return t=e.ld(),new t0(t,n.e.pc(t,u(e.md(),16)))}function J3e(n,e){var t;return t=n.a.get(e),t??K(ki,Fn,1,0,5,1)}function MLn(n){var e;return e=n.length,An(Yn.substr(Yn.length-e,e),n)}function fe(n){if(pe(n))return n.c=n.a,n.a.Pb();throw M(new nc)}function LJ(n,e){return e==0||n.e==0?n:e>0?wqn(n,e):BBn(n,-e)}function Fp(n,e){return e==0||n.e==0?n:e>0?BBn(n,e):wqn(n,-e)}function NJ(n){ole.call(this,n==null?gu:Jr(n),D(n,82)?u(n,82):null)}function TLn(n){var e;return n.c||(e=n.r,D(e,90)&&(n.c=u(e,29))),n.c}function JN(n){var e;return e=new y0,Ur(e,n),U(e,(cn(),Fr),null),e}function ALn(n){var e,t;return e=n.c.i,t=n.d.i,e.k==(Vn(),Zt)&&t.k==Zt}function QN(n){var e,t,i;return e=n&ro,t=n>>22&ro,i=n<0?Il:0,Yc(e,t,i)}function Q3e(n){var e,t,i,r;for(t=n,i=0,r=t.length;i=0?n.Lh(i,t,!0):K0(n,e,t)}function Z3e(n,e,t){return bt(vp(gm(n),Ki(e.b)),vp(gm(n),Ki(t.b)))}function n4e(n,e,t){return bt(vp(gm(n),Ki(e.e)),vp(gm(n),Ki(t.e)))}function e4e(n,e){return y.Math.min(J1(e.a,n.d.d.c),J1(e.b,n.d.d.c))}function nk(n,e){n._i(n.i+1),S6(n,n.i,n.Zi(n.i,e)),n.Mi(n.i++,e),n.Ni()}function Z6(n){var e,t;++n.j,e=n.g,t=n.i,n.g=null,n.i=0,n.Oi(t,e),n.Ni()}function SLn(n,e,t){var i;i=new LX(n.a),u5(i,n.a.a),Vc(i.f,e,t),n.a.a=i}function $J(n,e,t,i){var r;for(r=0;re)throw M(new Ir(Enn(n,e,"index")));return n}function Yl(n,e){var t;return t=(Ln(e,n.c.length),n.c[e]),Sz(n.c,e,1),t}function BJ(n,e){var t,i;return t=(Jn(n),n),i=(Jn(e),e),t==i?0:te.p?-1:0}function xLn(n){var e;return n.a||(e=n.r,D(e,156)&&(n.a=u(e,156))),n.a}function o4e(n,e,t){var i;return++n.e,--n.f,i=u(n.d[e].gd(t),136),i.md()}function s4e(n){var e,t;return e=n.ld(),t=u(n.md(),16),N7(t.Nc(),new D8n(e))}function FLn(n,e){return Zc(n.a,e)?(Bp(n.a,e),!0):!1}function Rp(n,e,t){return Y7(e,n.e.Rd().gc()),Y7(t,n.c.Rd().gc()),n.a[e][t]}function XM(n,e,t){this.a=n,this.b=e,this.c=t,nn(n.t,this),nn(e.i,this)}function VM(n,e,t,i){this.f=n,this.e=e,this.d=t,this.b=i,this.c=i?i.d:null}function ek(){this.b=new Ct,this.a=new Ct,this.b=new Ct,this.a=new Ct}function N4(){N4=F;var n,e;MO=(u4(),e=new $E,e),TO=(n=new fD,n)}function f4e(n){var e;return ta(n),e=new PSn(n,n.a.e,n.a.d|4),new cV(n,e)}function BLn(n){var e;for(X1(n),e=0;n.a.Bd(new V0n);)e=nr(e,1);return e}function WM(n,e){return Jn(e),n.c=0,"Initial capacity must not be negative")}function JM(){JM=F,d9=new lt("org.eclipse.elk.labels.labelManager")}function RLn(){RLn=F,vsn=new Dt("separateLayerConnections",(OT(),F_))}function af(){af=F,zw=new iX("REGULAR",0),Ea=new iX("CRITICAL",1)}function tk(){tk=F,Rq=new hX("FIXED",0),JI=new hX("CENTER_NODE",1)}function QM(){QM=F,Csn=new Wz("QUADRATIC",0),V_=new Wz("SCANLINE",1)}function KLn(){KLn=F,dne=Ce((i5(),A(T(Asn,1),G,322,0,[L8,gj,Tsn])))}function _Ln(){_Ln=F,bne=Ce((bT(),A(T(Psn,1),G,351,0,[Ssn,VP,W_])))}function HLn(){HLn=F,mne=Ce((hd(),A(T(pne,1),G,459,0,[Y_,pv,m2])))}function qLn(){qLn=F,fne=Ce((I0(),A(T(R_,1),G,372,0,[rb,va,ib])))}function ULn(){ULn=F,Tne=Ce((vl(),A(T(Mne,1),G,311,0,[mj,k2,E3])))}function GLn(){GLn=F,Cne=Ce((Y4(),A(T(sH,1),G,298,0,[uH,oH,pj])))}function zLn(){zLn=F,Zte=Ce((d5(),A(T(Ohn,1),G,390,0,[FH,Ihn,MI])))}function XLn(){XLn=F,oie=Ce((ST(),A(T(Uhn,1),G,387,0,[Hhn,zH,qhn])))}function VLn(){VLn=F,sie=Ce((h5(),A(T(Ghn,1),G,349,0,[VH,XH,Pj])))}function WLn(){WLn=F,uie=Ce((gr(),A(T(cie,1),G,462,0,[W8,Vu,Jc])))}function JLn(){JLn=F,hie=Ce((dT(),A(T(Jhn,1),G,352,0,[Whn,JH,Vhn])))}function QLn(){QLn=F,fie=Ce((um(),A(T(Xhn,1),G,350,0,[WH,zhn,J8])))}function YLn(){YLn=F,lie=Ce((DT(),A(T(Qhn,1),G,388,0,[QH,Iv,Gw])))}function ZLn(){ZLn=F,are=Ce((l5(),A(T(bln,1),G,392,0,[dln,nq,Dj])))}function nNn(){nNn=F,Gre=Ce((Sk(),A(T(Hln,1),G,393,0,[KI,Kln,_ln])))}function eNn(){eNn=F,ace=Ce((AT(),A(T(u1n,1),G,299,0,[Cq,c1n,r1n])))}function tNn(){tNn=F,dce=Ce((XT(),A(T(o1n,1),G,445,0,[Fj,qI,Mq])))}function iNn(){iNn=F,wce=Ce((rA(),A(T(bce,1),G,455,0,[Tq,Sq,Aq])))}function rNn(){rNn=F,mce=Ce((_T(),A(T(h1n,1),G,394,0,[f1n,Oq,s1n])))}function cNn(){cNn=F,Kce=Ce((nT(),A(T(I1n,1),G,439,0,[$q,P1n,S1n])))}function uNn(){uNn=F,Aie=Ce((P0(),A(T(Tie,1),G,463,0,[Ij,Q8,PI])))}function oNn(){oNn=F,WQn=Ce((Uu(),A(T(VQn,1),G,470,0,[Mh,pa,zs])))}function sNn(){sNn=F,XQn=Ce((wf(),A(T(Sw,1),G,237,0,[bc,Wc,wc])))}function fNn(){fNn=F,QQn=Ce((bu(),A(T(JQn,1),G,471,0,[kf,ma,Xs])))}function hNn(){hNn=F,xQn=Ce((Gu(),A(T(xr,1),G,108,0,[Nun,Yr,Aw])))}function lNn(){lNn=F,pZn=Ce((n5(),A(T(Aon,1),G,391,0,[E_,j_,C_])))}function aNn(){aNn=F,Que=Ce((jl(),A(T(hdn,1),G,346,0,[uO,M1,j9])))}function dNn(){dNn=F,Uce=Ce((Nk(),A(T(xq,1),G,444,0,[XI,VI,WI])))}function bNn(){bNn=F,Xue=Ce(($f(),A(T(Yan,1),G,278,0,[xv,Jw,Fv])))}function wNn(){wNn=F,loe=Ce((Gp(),A(T(pdn,1),G,280,0,[gdn,Yw,aO])))}function Lf(n,e){return!n.o&&(n.o=new Iu((Cc(),il),T1,n,0)),wx(n.o,e)}function h4e(n,e){var t;n.C&&(t=u(Cr(n.b,e),127).n,t.d=n.C.d,t.a=n.C.a)}function qJ(n){var e,t,i,r;r=n.d,e=n.a,t=n.b,i=n.c,n.d=t,n.a=i,n.b=r,n.c=e}function l4e(n){return!n.g&&(n.g=new EE),!n.g.b&&(n.g.b=new dyn(n)),n.g.b}function ik(n){return!n.g&&(n.g=new EE),!n.g.c&&(n.g.c=new gyn(n)),n.g.c}function a4e(n){return!n.g&&(n.g=new EE),!n.g.d&&(n.g.d=new byn(n)),n.g.d}function d4e(n){return!n.g&&(n.g=new EE),!n.g.a&&(n.g.a=new wyn(n)),n.g.a}function b4e(n,e,t,i){return t&&(i=t.Rh(e,Ot(t.Dh(),n.c.uk()),null,i)),i}function w4e(n,e,t,i){return t&&(i=t.Th(e,Ot(t.Dh(),n.c.uk()),null,i)),i}function e$(n,e,t,i){var r;return r=K(ye,_e,28,e+1,15,1),vPe(r,n,e,t,i),r}function K(n,e,t,i,r,c){var s;return s=KRn(r,i),r!=10&&A(T(n,c),e,t,r,s),s}function g4e(n,e,t){var i,r;for(r=new Q4(e,n),i=0;it||e=0?n.Lh(t,!0,!0):K0(n,e,!0)}function L4e(n,e,t){var i;return i=mFn(n,e,t),n.b=new ET(i.c.length),len(n,i)}function N4e(n){if(n.b<=0)throw M(new nc);return--n.b,n.a-=n.c.c,Y(n.a)}function $4e(n){var e;if(!n.a)throw M(new SIn);return e=n.a,n.a=At(n.a),e}function x4e(n){for(;!n.a;)if(!nSn(n.c,new E9n(n)))return!1;return!0}function Kp(n){var e;return Se(n),D(n,204)?(e=u(n,204),e):new K8n(n)}function F4e(n){YM(),u(n.of((He(),Ww)),181).Fc((zu(),eE)),n.qf(oU,null)}function YM(){YM=F,wue=new jmn,pue=new Emn,gue=M6e((He(),oU),wue,Ta,pue)}function ZM(){ZM=F,Bln=new oX("LEAF_NUMBER",0),vq=new oX("NODE_SIZE",1)}function u$(n){n.a=K(ye,_e,28,n.b+1,15,1),n.c=K(ye,_e,28,n.b,15,1),n.d=0}function B4e(n,e){n.a.Ne(e.d,n.b)>0&&(nn(n.c,new UV(e.c,e.d,n.d)),n.b=e.d)}function ZJ(n,e){if(n.g==null||e>=n.i)throw M(new aL(e,n.i));return n.g[e]}function vNn(n,e,t){if(im(n,t),t!=null&&!n.fk(t))throw M(new uD);return t}function o$(n,e){return dk(e)!=10&&A(wo(e),e.Sm,e.__elementTypeId$,dk(e),n),n}function x4(n,e,t,i){var r;i=(k0(),i||Aun),r=n.slice(e,t),Cnn(r,n,e,t,-e,i)}function zo(n,e,t,i,r){return e<0?K0(n,t,i):u(t,69).wk().yk(n,n.hi(),e,i,r)}function R4e(n,e){return bt($(R(v(n,(W(),ob)))),$(R(v(e,ob))))}function kNn(){kNn=F,IQn=Ce((F4(),A(T(lP,1),G,303,0,[e_,t_,i_,r_])))}function F4(){F4=F,e_=new cC("All",0),t_=new hTn,i_=new vTn,r_=new fTn}function Uu(){Uu=F,Mh=new FD(s3,0),pa=new FD(Hm,1),zs=new FD(f3,2)}function yNn(){yNn=F,KA(),o0n=St,mse=li,s0n=new G9(St),vse=new G9(li)}function jNn(){jNn=F,jYn=Ce((D0(),A(T(yYn,1),G,417,0,[ij,tj,a_,d_])))}function ENn(){ENn=F,AYn=Ce((C5(),A(T(TYn,1),G,406,0,[sj,wP,gP,fj])))}function CNn(){CNn=F,CYn=Ce((Vp(),A(T(EYn,1),G,332,0,[cj,rj,uj,oj])))}function MNn(){MNn=F,DZn=Ce((dd(),A(T(Oon,1),G,389,0,[Ow,Ion,P_,I_])))}function TNn(){TNn=F,TZn=Ce((Z4(),A(T(MZn,1),G,416,0,[tb,Iw,Pw,d2])))}function ANn(){ANn=F,tne=Ce((xf(),A(T(ene,1),G,421,0,[j3,hv,lv,B_])))}function SNn(){SNn=F,GZn=Ce((OT(),A(T(UZn,1),G,371,0,[F_,HP,qP,bj])))}function PNn(){PNn=F,nie=Ce((cw(),A(T(RH,1),G,203,0,[TI,BH,P2,S2])))}function INn(){INn=F,iie=Ce((lh(),A(T(Khn,1),G,284,0,[k1,Rhn,HH,qH])))}function ok(){ok=F,$sn=new Qz(kh,0),QP=new Qz("IMPROVE_STRAIGHTNESS",1)}function ONn(n,e){var t,i;return i=e/n.c.Rd().gc()|0,t=e%n.c.Rd().gc(),Rp(n,i,t)}function DNn(n){var e;if(n.nl())for(e=n.i-1;e>=0;--e)L(n,e);return yJ(n)}function nQ(n){var e,t;if(!n.b)return null;for(t=n.b;e=t.a[0];)t=e;return t}function LNn(n){var e,t;if(!n.b)return null;for(t=n.b;e=t.a[1];)t=e;return t}function K4e(n){return D(n,180)?""+u(n,180).a:n==null?null:Jr(n)}function _4e(n){return D(n,180)?""+u(n,180).a:n==null?null:Jr(n)}function NNn(n,e){if(e.a)throw M(new ec(nXn));fi(n.a,e),e.a=n,!n.j&&(n.j=e)}function eQ(n,e){PC.call(this,e.zd(),e.yd()&-16449),Jn(n),this.a=n,this.c=e}function H4e(n,e){return new _L(e,h0(Ki(e.e),e.f.a+n,e.f.b+n),(_n(),!1))}function q4e(n,e){return v4(),nn(n,new bi(e,Y(e.e.c.length+e.g.c.length)))}function U4e(n,e){return v4(),nn(n,new bi(e,Y(e.e.c.length+e.g.c.length)))}function $Nn(){$Nn=F,lce=Ce((sA(),A(T(i1n,1),G,354,0,[Eq,e1n,t1n,n1n])))}function xNn(){xNn=F,$re=Ce((a5(),A(T(Nln,1),G,353,0,[aq,BI,lq,hq])))}function FNn(){FNn=F,hre=Ce((Qp(),A(T(tln,1),G,405,0,[LI,n9,e9,t9])))}function BNn(){BNn=F,Vue=Ce((El(),A(T(lU,1),G,223,0,[hU,Qj,Bv,x3])))}function RNn(){RNn=F,Zue=Ce((To(),A(T(Yue,1),G,290,0,[Zj,nl,Aa,Yj])))}function KNn(){KNn=F,foe=Ce((go(),A(T(A9,1),G,386,0,[iE,Gd,tE,Qw])))}function _Nn(){_Nn=F,doe=Ce((qT(),A(T(Edn,1),G,320,0,[bU,kdn,jdn,ydn])))}function HNn(){HNn=F,goe=Ce((LT(),A(T(woe,1),G,415,0,[wU,Mdn,Cdn,Tdn])))}function nT(){nT=F,$q=new oL(mVn,0),P1n=new oL(jrn,1),S1n=new oL(kh,2)}function Wb(n,e,t,i,r){return Jn(n),Jn(e),Jn(t),Jn(i),Jn(r),new TW(n,e,i)}function qNn(n,e){var t;return t=u(Bp(n.e,e),400),t?(eW(t),t.e):null}function du(n,e){var t;return t=qr(n,e,0),t==-1?!1:(Yl(n,t),!0)}function UNn(n,e,t){var i;return X1(n),i=new LO,i.a=e,n.a.Nb(new MCn(i,t)),i.a}function G4e(n){var e;return X1(n),e=K(Pi,Tr,28,0,15,1),lg(n.a,new k9n(e)),e}function tQ(n){var e;if(!E$(n))throw M(new nc);return n.e=1,e=n.d,n.d=null,e}function n1(n){var e;return Vr(n)&&(e=0-n,!isNaN(e))?e:Y1(em(n))}function qr(n,e,t){for(;t=0?tA(n,t,!0,!0):K0(n,e,!0)}function rQ(n){var e;return e=cd(Un(n,32)),e==null&&(iu(n),e=cd(Un(n,32))),e}function cQ(n){var e;return n.Oh()||(e=se(n.Dh())-n.ji(),n.$h().Mk(e)),n.zh()}function JNn(n,e){ion=new vE,MYn=e,S8=n,u(S8.b,68),zJ(S8,ion,null),aGn(S8)}function n5(){n5=F,E_=new RD("XY",0),j_=new RD("X",1),C_=new RD("Y",2)}function bu(){bu=F,kf=new BD("TOP",0),ma=new BD(Hm,1),Xs=new BD($tn,2)}function vl(){vl=F,mj=new GD(kh,0),k2=new GD("TOP",1),E3=new GD($tn,2)}function ak(){ak=F,UH=new Zz("INPUT_ORDER",0),GH=new Zz("PORT_DEGREE",1)}function B4(){B4=F,sun=Yc(ro,ro,524287),bQn=Yc(0,0,My),fun=QN(1),QN(2),hun=QN(0)}function a$(n){var e;return n.d!=n.r&&(e=gs(n),n.e=!!e&&e.lk()==bJn,n.d=e),n.e}function d$(n,e,t){var i;return i=n.g[e],S6(n,e,n.Zi(e,t)),n.Ri(e,t,i),n.Ni(),i}function rT(n,e){var t;return t=n.dd(e),t>=0?(n.gd(t),!0):!1}function b$(n,e){var t;for(Se(n),Se(e),t=!1;e.Ob();)t=t|n.Fc(e.Pb());return t}function Nf(n,e){var t;return t=u(ee(n.e,e),400),t?(OTn(n,t),t.e):null}function QNn(n){var e,t;return e=n/60|0,t=n%60,t==0?""+e:""+e+":"+(""+t)}function Jb(n,e){var t=n.a[e],i=(K$(),WK)[typeof t];return i?i(t):bY(typeof t)}function rc(n,e){var t,i;return ta(n),i=new KJ(e,n.a),t=new iSn(i),new Tn(n,t)}function w$(n){var e;return e=n.b.c.length==0?null:sn(n.b,0),e!=null&&M$(n,0),e}function W4e(n,e){var t,i,r;r=e.c.i,t=u(ee(n.f,r),60),i=t.d.c-t.e.c,FQ(e.a,i,0)}function uQ(n,e){var t;for(++n.d,++n.c[e],t=e+1;t=0;)++e[0]}function J4e(n,e){eu(n,e==null||UC((Jn(e),e))||isNaN((Jn(e),e))?0:(Jn(e),e))}function Q4e(n,e){tu(n,e==null||UC((Jn(e),e))||isNaN((Jn(e),e))?0:(Jn(e),e))}function Y4e(n,e){S0(n,e==null||UC((Jn(e),e))||isNaN((Jn(e),e))?0:(Jn(e),e))}function Z4e(n,e){A0(n,e==null||UC((Jn(e),e))||isNaN((Jn(e),e))?0:(Jn(e),e))}function nme(n,e,t){return vp(new V(t.e.a+t.f.a/2,t.e.b+t.f.b/2),n)==(Jn(e),e)}function eme(n,e){return D(e,102)&&u(e,19).Bb&hr?new dL(e,n):new Q4(e,n)}function tme(n,e){return D(e,102)&&u(e,19).Bb&hr?new dL(e,n):new Q4(e,n)}function dk(n){return n.__elementTypeCategory$==null?10:n.__elementTypeCategory$}function n$n(n,e){return e==(xL(),xL(),AQn)?n.toLocaleLowerCase():n.toLowerCase()}function e$n(n){if(!n.e)throw M(new nc);return n.c=n.a=n.e,n.e=n.e.e,--n.d,n.a.f}function oQ(n){if(!n.c)throw M(new nc);return n.e=n.a=n.c,n.c=n.c.c,++n.d,n.a.f}function t$n(n){var e;for(++n.a,e=n.c.a.length;n.an.a[i]&&(i=t);return i}function i$n(n){var e;return e=u(v(n,(W(),cb)),313),e?e.a==n:!1}function r$n(n){var e;return e=u(v(n,(W(),cb)),313),e?e.i==n:!1}function c$n(){c$n=F,yZn=Ce((Vi(),A(T(Son,1),G,367,0,[Vs,Jh,Oc,Kc,zr])))}function u$n(){u$n=F,rne=Ce((ow(),A(T(ine,1),G,375,0,[wj,zP,XP,GP,UP])))}function o$n(){o$n=F,wne=Ce((o1(),A(T(Osn,1),G,348,0,[J_,Isn,Q_,gv,wv])))}function s$n(){s$n=F,eie=Ce((E5(),A(T(Lhn,1),G,323,0,[Dhn,KH,_H,X8,V8])))}function f$n(){f$n=F,Sne=Ce((Yo(),A(T(sfn,1),G,171,0,[jj,R8,ya,K8,xw])))}function h$n(){h$n=F,qre=Ce((wA(),A(T(Hre,1),G,368,0,[pq,bq,mq,wq,gq])))}function l$n(){l$n=F,qce=Ce((N5(),A(T(Hce,1),G,373,0,[N2,O3,a9,l9,Kj])))}function a$n(){a$n=F,Wce=Ce((Wk(),A(T(R1n,1),G,324,0,[x1n,Kq,B1n,_q,F1n])))}function d$n(){d$n=F,zue=Ce((ci(),A(T(k9,1),G,88,0,[Jf,Xr,Br,Wf,us])))}function b$n(){b$n=F,mue=Ce((pf(),A(T(Zh,1),G,170,0,[xn,pi,Ph,Kd,E1])))}function w$n(){w$n=F,eoe=Ce((Bg(),A(T(C9,1),G,256,0,[Sa,nE,ldn,E9,adn])))}function g$n(){g$n=F,roe=Ce((en(),A(T(lr,1),Mc,64,0,[sc,Xn,Zn,ae,Wn])))}function cT(){cT=F,Fun=new qz("BY_SIZE",0),s_=new qz("BY_SIZE_AND_SHAPE",1)}function uT(){uT=F,v_=new zz("EADES",0),vP=new zz("FRUCHTERMAN_REINGOLD",1)}function bk(){bk=F,WP=new Jz("READING_DIRECTION",0),Dsn=new Jz("ROTATION",1)}function e5(){e5=F,PZn=new iwn,IZn=new uwn,AZn=new own,SZn=new cwn,OZn=new swn}function p$n(n){this.b=new Z,this.a=new Z,this.c=new Z,this.d=new Z,this.e=n}function m$n(n){this.g=n,this.f=new Z,this.a=y.Math.min(this.g.c.c,this.g.d.c)}function v$n(n,e,t){HC.call(this),hQ(this),this.a=n,this.c=t,this.b=e.d,this.f=e.e}function sme(n,e,t){var i,r;for(r=new C(t);r.a=0&&e0?e-1:e,nEn($he(q$n(QV(new op,t),n.n),n.j),n.k)}function Nr(n){var e,t;t=(e=new hD,e),ve((!n.q&&(n.q=new q(Ss,n,11,10)),n.q),t)}function sQ(n){return(n.i&2?"interface ":n.i&1?"":"class ")+(ll(n),n.o)}function oT(n){return Ec(n,et)>0?et:Ec(n,Wi)<0?Wi:Ae(n)}function Qb(n){return n<3?(Co(n,$zn),n+1):n=-.01&&n.a<=_f&&(n.a=0),n.b>=-.01&&n.b<=_f&&(n.b=0),n}function Dg(n){Vg();var e,t;for(t=Mrn,e=0;et&&(t=n[e]);return t}function E$n(n,e){var t;if(t=uy(n.Dh(),e),!t)throw M(new Gn(ba+e+sK));return t}function Yb(n,e){var t;for(t=n;At(t);)if(t=At(t),t==e)return!0;return!1}function vme(n,e){var t,i,r;for(i=e.a.ld(),t=u(e.a.md(),16).gc(),r=0;rn||n>e)throw M(new gz("fromIndex: 0, toIndex: "+n+Etn+e))}function T0(n){if(n<0)throw M(new Gn("Illegal Capacity: "+n));this.g=this.aj(n)}function fQ(n,e){return Tf(),Ks(fa),y.Math.abs(n-e)<=fa||n==e||isNaN(n)&&isNaN(e)}function m$(n,e){var t,i,r,c;for(i=n.d,r=0,c=i.length;r0&&(n.a/=e,n.b/=e),n}function jo(n){var e;return n.w?n.w:(e=lpe(n),e&&!e.Vh()&&(n.w=e),e)}function R4(n,e){var t,i;i=n.a,t=w5e(n,e,null),i!=e&&!n.e&&(t=Lm(n,e,t)),t&&t.oj()}function S$n(n,e,t){var i,r;i=e;do r=$(n.p[i.p])+t,n.p[i.p]=r,i=n.a[i.p];while(i!=e)}function P$n(n,e,t){var i=function(){return n.apply(i,arguments)};return e.apply(i,t),i}function Tme(n){var e;return n==null?null:(e=u(n,195),Bye(e,e.length))}function L(n,e){if(n.g==null||e>=n.i)throw M(new aL(e,n.i));return n.Wi(e,n.g[e])}function Ame(n,e){Dn();var t,i;for(i=new Z,t=0;t=14&&e<=16))),n}function Ee(n,e){var t;return Jn(e),t=n[":"+e],x7(!!t,"Enum constant undefined: "+e),t}function we(n,e,t,i,r,c){var s;return s=bN(n,e),U$n(t,s),s.i=r?8:0,s.f=i,s.e=r,s.g=c,s}function aQ(n,e,t,i,r){this.d=e,this.k=i,this.f=r,this.o=-1,this.p=1,this.c=n,this.a=t}function dQ(n,e,t,i,r){this.d=e,this.k=i,this.f=r,this.o=-1,this.p=2,this.c=n,this.a=t}function bQ(n,e,t,i,r){this.d=e,this.k=i,this.f=r,this.o=-1,this.p=6,this.c=n,this.a=t}function wQ(n,e,t,i,r){this.d=e,this.k=i,this.f=r,this.o=-1,this.p=7,this.c=n,this.a=t}function gQ(n,e,t,i,r){this.d=e,this.j=i,this.e=r,this.o=-1,this.p=4,this.c=n,this.a=t}function G$n(n,e){var t,i,r,c;for(i=e,r=0,c=i.length;r=0))throw M(new Gn("tolerance ("+n+") must be >= 0"));return n}function X$n(n,e){var t;return D(e,44)?n.c.Mc(e):(t=wx(n,e),VT(n,e),t)}function Mr(n,e,t){return ad(n,e),zc(n,t),e1(n,0),Zb(n,1),u1(n,!0),c1(n,!0),n}function gk(n,e){var t;if(t=n.gc(),e<0||e>t)throw M(new Kb(e,t));return new AV(n,e)}function wT(n,e){n.b=y.Math.max(n.b,e.d),n.e+=e.r+(n.a.c.length==0?0:n.c),nn(n.a,e)}function V$n(n){Fb(n.c>=0),_8e(n.d,n.c)<0&&(n.a=n.a-1&n.d.a.length-1,n.b=n.d.c),n.c=-1}function gT(n){var e,t;for(t=n.c.Cc().Kc();t.Ob();)e=u(t.Pb(),16),e.$b();n.c.$b(),n.d=0}function Fme(n){var e,t,i,r;for(t=n.a,i=0,r=t.length;i=0}function EQ(n,e){n.r>0&&n.c0&&n.g!=0&&EQ(n.i,e/n.r*n.i.d))}function CQ(n,e){var t;t=n.c,n.c=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,1,t,n.c))}function y$(n,e){var t;t=n.c,n.c=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,4,t,n.c))}function z4(n,e){var t;t=n.k,n.k=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,2,t,n.k))}function j$(n,e){var t;t=n.D,n.D=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,2,t,n.D))}function mT(n,e){var t;t=n.f,n.f=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,8,t,n.f))}function vT(n,e){var t;t=n.i,n.i=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,7,t,n.i))}function MQ(n,e){var t;t=n.a,n.a=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,8,t,n.a))}function TQ(n,e){var t;t=n.b,n.b=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,0,t,n.b))}function AQ(n,e){var t;t=n.b,n.b=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,0,t,n.b))}function SQ(n,e){var t;t=n.c,n.c=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,1,t,n.c))}function PQ(n,e){var t;t=n.d,n.d=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,1,t,n.d))}function Ume(n,e,t){var i;n.b=e,n.a=t,i=(n.a&512)==512?new wjn:new iG,n.c=rAe(i,n.b,n.a)}function uxn(n,e){return Sl(n.e,e)?(dr(),a$(e)?new nM(e,n):new k7(e,n)):new NMn(e,n)}function Gme(n){var e,t;return 0>n?new Oz:(e=n+1,t=new mLn(e,n),new uV(null,t))}function zme(n,e){Dn();var t;return t=new ap(1),Ai(n)?Dr(t,n,e):Vc(t.f,n,e),new eD(t)}function Xme(n,e){var t,i;return t=n.c,i=e.e[n.p],i>0?u(sn(t.a,i-1),10):null}function Vme(n,e){var t,i;return t=n.o+n.p,i=e.o+e.p,te?(e<<=1,e>0?e:X5):e}function E$(n){switch(KX(n.e!=3),n.e){case 2:return!1;case 0:return!0}return i4e(n)}function sxn(n,e){var t;return D(e,8)?(t=u(e,8),n.a==t.a&&n.b==t.b):!1}function Jme(n,e){var t;t=new vE,u(e.b,68),u(e.b,68),u(e.b,68),nu(e.a,new FV(n,t,e))}function fxn(n,e){var t,i;for(i=e.vc().Kc();i.Ob();)t=u(i.Pb(),44),Gk(n,t.ld(),t.md())}function IQ(n,e){var t;t=n.d,n.d=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,11,t,n.d))}function kT(n,e){var t;t=n.j,n.j=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,13,t,n.j))}function OQ(n,e){var t;t=n.b,n.b=e,n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,1,21,t,n.b))}function Qme(n,e){(UM(),Uf?null:e.c).length==0&&MAn(e,new FU),Dr(n.a,Uf?null:e.c,e)}function Yme(n,e){e.Ug("Hierarchical port constraint processing",1),g9e(n),xLe(n),e.Vg()}function I0(){I0=F,rb=new KD("START",0),va=new KD("MIDDLE",1),ib=new KD("END",2)}function yT(){yT=F,RI=new uX("P1_NODE_PLACEMENT",0),L2=new uX("P2_EDGE_ROUTING",1)}function Q1(){Q1=F,y3=new lt(Vtn),jP=new lt(MXn),I8=new lt(TXn),hj=new lt(AXn)}function O0(n){var e;return FL(n.f.g,n.d),oe(n.b),n.c=n.a,e=u(n.a.Pb(),44),n.b=UQ(n),e}function DQ(n){var e;return n.b==null?(Gl(),Gl(),aE):(e=n.ul()?n.tl():n.sl(),e)}function hxn(n,e){var t;return t=e==null?-1:qr(n.b,e,0),t<0?!1:(M$(n,t),!0)}function _s(n,e){var t;return Jn(e),t=e.g,n.b[t]?!1:($t(n.b,t,e),++n.c,!0)}function jT(n,e){var t,i;return t=1-e,i=n.a[t],n.a[t]=i.a[e],i.a[e]=n,n.b=!0,i.b=!1,i}function Zme(n,e){var t,i;for(i=e.Kc();i.Ob();)t=u(i.Pb(),272),n.b=!0,fi(n.e,t),t.b=n}function nve(n,e){var t,i;return t=u(v(n,(cn(),Hw)),8),i=u(v(e,Hw),8),bt(t.b,i.b)}function C$(n,e,t){var i,r,c;return c=e>>5,r=e&31,i=vi(U1(n.n[t][c],Ae(Bs(r,1))),3),i}function lxn(n,e,t){var i,r,c;for(c=n.a.length-1,r=n.b,i=0;i0?1:0:(!n.c&&(n.c=W7(vc(n.f))),n.c).e}function kxn(n,e){e?n.B==null&&(n.B=n.D,n.D=null):n.B!=null&&(n.D=n.B,n.B=null)}function rve(n,e){return Z4(),n==tb&&e==Iw||n==Iw&&e==tb||n==d2&&e==Pw||n==Pw&&e==d2}function cve(n,e){return Z4(),n==tb&&e==Pw||n==tb&&e==d2||n==Iw&&e==d2||n==Iw&&e==Pw}function yxn(n,e){return Tf(),Ks(_f),y.Math.abs(0-e)<=_f||e==0||isNaN(0)&&isNaN(e)?0:n/e}function jxn(n,e){return $(R(ho(Dk(_r(new Tn(null,new In(n.c.b,16)),new P7n(n)),e))))}function xQ(n,e){return $(R(ho(Dk(_r(new Tn(null,new In(n.c.b,16)),new S7n(n)),e))))}function uve(){return pr(),A(T(cH,1),G,259,0,[ZP,cs,$8,nI,kv,v2,x8,mv,vv,eI])}function ove(){return ps(),A(T(Bhn,1),G,243,0,[AI,Aj,Sj,$hn,xhn,Nhn,Fhn,SI,wb,Uw])}function sve(n,e){var t;e.Ug("General Compactor",1),t=d8e(u(z(n,(oa(),yq)),393)),t.Cg(n)}function fve(n,e){var t,i;return t=u(z(n,(oa(),_I)),17),i=u(z(e,_I),17),jc(t.a,i.a)}function FQ(n,e,t){var i,r;for(r=ge(n,0);r.b!=r.d.c;)i=u(be(r),8),i.a+=e,i.b+=t;return n}function r5(n,e,t){var i;for(i=n.b[t&n.f];i;i=i.b)if(t==i.a&&sh(e,i.g))return i;return null}function c5(n,e,t){var i;for(i=n.c[t&n.f];i;i=i.d)if(t==i.f&&sh(e,i.i))return i;return null}function hve(n,e,t){var i,r,c;for(i=0,r=0;r>>31;i!=0&&(n[t]=i)}function P$(n,e,t,i,r,c){var s;this.c=n,s=new Z,gZ(n,s,e,n.b,t,i,r,c),this.a=new xi(s,0)}function Exn(){this.c=new zE(0),this.b=new zE(Crn),this.d=new zE(lVn),this.a=new zE(QB)}function Vo(n,e,t,i,r,c,s){je.call(this,n,e),this.d=t,this.e=i,this.c=r,this.b=c,this.a=Of(s)}function Ut(n,e,t,i,r,c,s,f,h,l,a,d,g){return P_n(n,e,t,i,r,c,s,f,h,l,a,d,g),sx(n,!1),n}function lve(n){return n.b.c.i.k==(Vn(),Zt)?u(v(n.b.c.i,(W(),st)),12):n.b.c}function Cxn(n){return n.b.d.i.k==(Vn(),Zt)?u(v(n.b.d.i,(W(),st)),12):n.b.d}function ave(n){var e;return e=BM(n),c0(e.a,0)?(JE(),JE(),SQn):(JE(),new cAn(e.b))}function I$(n){var e;return e=wJ(n),c0(e.a,0)?(Ib(),Ib(),n_):(Ib(),new AL(e.b))}function O$(n){var e;return e=wJ(n),c0(e.a,0)?(Ib(),Ib(),n_):(Ib(),new AL(e.c))}function Mxn(n){switch(n.g){case 2:return en(),Wn;case 4:return en(),Zn;default:return n}}function Txn(n){switch(n.g){case 1:return en(),ae;case 3:return en(),Xn;default:return n}}function Axn(n){switch(n.g){case 0:return new fmn;case 1:return new hmn;default:return null}}function Hp(){Hp=F,x_=new Dt("edgelabelcenterednessanalysis.includelabel",(_n(),ga))}function BQ(){BQ=F,Mie=ah(VMn(Ke(Ke(new ii,(Vi(),Oc),(tr(),NP)),Kc,PP),zr),LP)}function Sxn(){Sxn=F,Pie=ah(VMn(Ke(Ke(new ii,(Vi(),Oc),(tr(),NP)),Kc,PP),zr),LP)}function D$(){D$=F,L9=new hjn,EU=A(T(ku,1),f2,179,0,[]),Joe=A(T(Ss,1),qcn,62,0,[])}function X4(){X4=F,aj=new Xz("TO_INTERNAL_LTR",0),L_=new Xz("TO_INPUT_DIRECTION",1)}function Ou(){Ou=F,Fon=new bwn,$on=new wwn,xon=new gwn,Non=new pwn,Bon=new mwn,Ron=new vwn}function dve(n,e){e.Ug(HXn,1),_Y(Qhe(new PE((r6(),new kN(n,!1,!1,new HU))))),e.Vg()}function bve(n,e,t){t.Ug("DFS Treeifying phase",1),O8e(n,e),PTe(n,e),n.a=null,n.b=null,t.Vg()}function pk(n,e){return _n(),Ai(n)?BJ(n,Oe(e)):$b(n)?tN(n,R(e)):Nb(n)?rwe(n,un(e)):n.Fd(e)}function u5(n,e){var t,i;for(Jn(e),i=e.vc().Kc();i.Ob();)t=u(i.Pb(),44),n.zc(t.ld(),t.md())}function wve(n,e,t){var i;for(i=t.Kc();i.Ob();)if(!_M(n,e,i.Pb()))return!1;return!0}function gve(n,e,t,i,r){var c;return t&&(c=Ot(e.Dh(),n.c),r=t.Rh(e,-1-(c==-1?i:c),null,r)),r}function pve(n,e,t,i,r){var c;return t&&(c=Ot(e.Dh(),n.c),r=t.Th(e,-1-(c==-1?i:c),null,r)),r}function Pxn(n){var e;if(n.b==-2){if(n.e==0)e=-1;else for(e=0;n.a[e]==0;e++);n.b=e}return n.b}function mve(n){if(Jn(n),n.length==0)throw M(new th("Zero length BigInteger"));CSe(this,n)}function RQ(n){this.i=n.gc(),this.i>0&&(this.g=this.aj(this.i+(this.i/8|0)+1),n.Qc(this.g))}function Ixn(n,e,t){this.g=n,this.d=e,this.e=t,this.a=new Z,IEe(this),Dn(),Yt(this.a,null)}function KQ(n,e){e.q=n,n.d=y.Math.max(n.d,e.r),n.b+=e.d+(n.a.c.length==0?0:n.c),nn(n.a,e)}function V4(n,e){var t,i,r,c;return r=n.c,t=n.c+n.b,c=n.d,i=n.d+n.a,e.a>r&&e.ac&&e.br?t=r:zn(e,t+1),n.a=qo(n.a,0,e)+(""+i)+NW(n.a,t)}function Rxn(n,e){n.a=nr(n.a,1),n.c=y.Math.min(n.c,e),n.b=y.Math.max(n.b,e),n.d=nr(n.d,e)}function Mve(n,e){return e1||n.Ob())return++n.a,n.g=0,e=n.i,n.Ob(),e;throw M(new nc)}function qxn(n){switch(n.a.g){case 1:return new VCn;case 3:return new VRn;default:return new o8n}}function HQ(n,e){switch(e){case 1:return!!n.n&&n.n.i!=0;case 2:return n.k!=null}return bJ(n,e)}function vc(n){return Ty>22),r=n.h+e.h+(i>>22),Yc(t&ro,i&ro,r&Il)}function Qxn(n,e){var t,i,r;return t=n.l-e.l,i=n.m-e.m+(t>>22),r=n.h-e.h+(i>>22),Yc(t&ro,i&ro,r&Il)}function zve(n){var e,t;for(RDe(n),t=new C(n.d);t.ai)throw M(new Kb(e,i));return n.Si()&&(t=wOn(n,t)),n.Ei(e,t)}function nm(n,e,t,i,r){var c,s;for(s=t;s<=r;s++)for(c=e;c<=i;c++)Kg(n,c,s)||xA(n,c,s,!0,!1)}function u6e(n){Vg();var e,t,i;for(t=K(Ei,J,8,2,0,1),i=0,e=0;e<2;e++)i+=.5,t[e]=Z9e(i,n);return t}function em(n){var e,t,i;return e=~n.l+1&ro,t=~n.m+(e==0?1:0)&ro,i=~n.h+(e==0&&t==0?1:0)&Il,Yc(e,t,i)}function JQ(n){var e;if(n<0)return Wi;if(n==0)return 0;for(e=X5;!(e&n);e>>=1);return e}function R$(n,e,t){return n>=128?!1:n<64?j6(vi(Bs(1,n),t),0):j6(vi(Bs(1,n-64),e),0)}function Tk(n,e,t){return t==null?(!n.q&&(n.q=new de),Bp(n.q,e)):(!n.q&&(n.q=new de),Ve(n.q,e,t)),n}function U(n,e,t){return t==null?(!n.q&&(n.q=new de),Bp(n.q,e)):(!n.q&&(n.q=new de),Ve(n.q,e,t)),n}function sFn(n){var e,t;return t=new zM,Ur(t,n),U(t,(Q1(),y3),n),e=new de,$Pe(n,t,e),fDe(n,t,e),t}function fFn(n){var e,t;return e=n.t-n.k[n.o.p]*n.d+n.j[n.o.p]>n.f,t=n.u+n.e[n.o.p]*n.d>n.f*n.s*n.d,e||t}function hFn(n,e){var t,i,r,c;for(t=!1,i=n.a[e].length,c=0;c=0,"Negative initial capacity"),x7(e>=0,"Non-positive load factor"),Hu(this)}function s6e(n,e,t,i,r){var c,s;if(s=n.length,c=t.length,e<0||i<0||r<0||e+r>s||i+r>c)throw M(new HG)}function nY(n,e){Dn();var t,i,r,c,s;for(s=!1,i=e,r=0,c=i.length;r1||e>=0&&n.b<3)}function H$(n){var e,t,i;e=~n.l+1&ro,t=~n.m+(e==0?1:0)&ro,i=~n.h+(e==0&&t==0?1:0)&Il,n.l=e,n.m=t,n.h=i}function iY(n){Dn();var e,t,i;for(i=1,t=n.Kc();t.Ob();)e=t.Pb(),i=31*i+(e!=null?mt(e):0),i=i|0;return i}function d6e(n,e,t,i,r){var c;return c=Gnn(n,e),t&&H$(c),r&&(n=u7e(n,e),i?wa=em(n):wa=Yc(n.l,n.m,n.h)),c}function kFn(n,e,t){n.g=uF(n,e,(en(),Zn),n.b),n.d=uF(n,t,Zn,n.b),!(n.g.c==0||n.d.c==0)&&QKn(n)}function yFn(n,e,t){n.g=uF(n,e,(en(),Wn),n.j),n.d=uF(n,t,Wn,n.j),!(n.g.c==0||n.d.c==0)&&QKn(n)}function rY(n,e){switch(e){case 7:return!!n.e&&n.e.i!=0;case 8:return!!n.d&&n.d.i!=0}return HY(n,e)}function b6e(n,e){switch(e.g){case 0:D(n.b,641)||(n.b=new Bxn);break;case 1:D(n.b,642)||(n.b=new FSn)}}function jFn(n){switch(n.g){case 0:return new wmn;default:throw M(new Gn(xS+(n.f!=null?n.f:""+n.g)))}}function EFn(n){switch(n.g){case 0:return new bmn;default:throw M(new Gn(xS+(n.f!=null?n.f:""+n.g)))}}function w6e(n,e,t){return!o4(ut(new Tn(null,new In(n.c,16)),new Y3(new fMn(e,t)))).Bd((Va(),v3))}function CFn(n,e){return vp(gm(u(v(e,(lc(),pb)),88)),new V(n.c.e.a-n.b.e.a,n.c.e.b-n.b.e.b))<=0}function g6e(n,e){for(;n.g==null&&!n.c?rJ(n):n.g==null||n.i!=0&&u(n.g[n.i-1],51).Ob();)kle(e,CA(n))}function ld(n){var e,t;for(t=new C(n.a.b);t.ai?1:0}function v6e(n){return nn(n.c,(qp(),bue)),fQ(n.a,$(R(rn((bx(),EI)))))?new evn:new Nkn(n)}function k6e(n){for(;!n.d||!n.d.Ob();)if(n.b&&!n6(n.b))n.d=u(Sp(n.b),51);else return null;return n.d}function uY(n){switch(n.g){case 1:return lVn;default:case 2:return 0;case 3:return QB;case 4:return Crn}}function y6e(){nt();var n;return PU||(n=_1e(sa("M",!0)),n=cM(sa("M",!1),n),PU=n,PU)}function LT(){LT=F,wU=new EC("ELK",0),Mdn=new EC("JSON",1),Cdn=new EC("DOT",2),Tdn=new EC("SVG",3)}function h5(){h5=F,VH=new WD("STACKED",0),XH=new WD("REVERSE_STACKED",1),Pj=new WD("SEQUENCED",2)}function l5(){l5=F,dln=new eL(kh,0),nq=new eL("MIDDLE_TO_MIDDLE",1),Dj=new eL("AVOID_OVERLAP",2)}function rm(){rm=F,ysn=new Qgn,jsn=new Ygn,JZn=new Wgn,WZn=new Zgn,VZn=new Jgn,ksn=(Jn(VZn),new I0n)}function NT(){NT=F,fdn=new o0(15),Jue=new Ni((He(),C1),fdn),y9=L3,cdn=Pue,udn=Hd,sdn=_2,odn=Vw}function Ng(n,e){var t,i,r,c,s;for(i=e,r=0,c=i.length;r=n.b.c.length||(sY(n,2*e+1),t=2*e+2,t0&&(e.Cd(t),t.i&&E5e(t))}function fY(n,e,t){var i;for(i=t-1;i>=0&&n[i]===e[i];i--);return i<0?0:ND(vi(n[i],mr),vi(e[i],mr))?-1:1}function AFn(n,e,t){var i,r;this.g=n,this.c=e,this.a=this,this.d=this,r=oxn(t),i=K(sQn,Ey,227,r,0,1),this.b=i}function X$(n,e,t,i,r){var c,s;for(s=t;s<=r;s++)for(c=e;c<=i;c++)if(Kg(n,c,s))return!0;return!1}function A6e(n,e){var t,i;for(i=n.Zb().Cc().Kc();i.Ob();)if(t=u(i.Pb(),16),t.Hc(e))return!0;return!1}function SFn(n,e,t){var i,r,c,s;for(Jn(t),s=!1,c=n.fd(e),r=t.Kc();r.Ob();)i=r.Pb(),c.Rb(i),s=!0;return s}function V$(n,e){var t,i;return i=u(Un(n.a,4),129),t=K(yU,MK,424,e,0,1),i!=null&&Ic(i,0,t,0,i.length),t}function PFn(n,e){var t;return t=new jF((n.f&256)!=0,n.i,n.a,n.d,(n.f&16)!=0,n.j,n.g,e),n.e!=null||(t.c=n),t}function S6e(n,e){var t;return n===e?!0:D(e,85)?(t=u(e,85),ann(Ja(n),t.vc())):!1}function IFn(n,e,t){var i,r;for(r=t.Kc();r.Ob();)if(i=u(r.Pb(),44),n.Be(e,i.md()))return!0;return!1}function OFn(n,e,t){return n.d[e.p][t.p]||(O9e(n,e,t),n.d[e.p][t.p]=!0,n.d[t.p][e.p]=!0),n.a[e.p][t.p]}function P6e(n,e){var t;return!n||n==e||!kt(e,(W(),ub))?!1:(t=u(v(e,(W(),ub)),10),t!=n)}function W$(n){switch(n.i){case 2:return!0;case 1:return!1;case-1:++n.c;default:return n.$l()}}function DFn(n){switch(n.i){case-2:return!0;case-1:return!1;case 1:--n.c;default:return n._l()}}function LFn(n){kOn.call(this,"The given string does not match the expected format for individual spacings.",n)}function I6e(n,e){var t;e.Ug("Min Size Preprocessing",1),t=ynn(n),ht(n,(_h(),s9),t.a),ht(n,UI,t.b),e.Vg()}function O6e(n){var e,t,i;for(e=0,i=K(Ei,J,8,n.b,0,1),t=ge(n,0);t.b!=t.d.c;)i[e++]=u(be(t),8);return i}function J$(n,e,t){var i,r,c;for(i=new Ct,c=ge(t,0);c.b!=c.d.c;)r=u(be(c),8),Fe(i,new rr(r));SFn(n,e,i)}function D6e(n,e){var t;return t=nr(n,e),ND(RN(n,e),0)|TC(RN(n,t),0)?t:nr(jy,RN(U1(t,63),1))}function L6e(n,e){var t,i;return t=u(n.d.Bc(e),16),t?(i=n.e.hc(),i.Gc(t),n.e.d-=t.gc(),t.$b(),i):null}function NFn(n){var e;if(e=n.a.c.length,e>0)return j4(e-1,n.a.c.length),Yl(n.a,e-1);throw M(new Nyn)}function $Fn(n,e,t){if(n>e)throw M(new Gn(ZA+n+Qzn+e));if(n<0||e>t)throw M(new gz(ZA+n+Ttn+e+Etn+t))}function cm(n,e){n.D==null&&n.B!=null&&(n.D=n.B,n.B=null),j$(n,e==null?null:(Jn(e),e)),n.C&&n.hl(null)}function N6e(n,e){var t;t=rn((bx(),EI))!=null&&e.Sg()!=null?$(R(e.Sg()))/$(R(rn(EI))):1,Ve(n.b,e,t)}function hY(n,e){var t,i;if(i=n.c[e],i!=0)for(n.c[e]=0,n.d-=i,t=e+1;tPS?n-t>PS:t-n>PS}function zFn(n,e){var t;for(t=0;tr&&(jKn(e.q,r),i=t!=e.q.d)),i}function XFn(n,e){var t,i,r,c,s,f,h,l;return h=e.i,l=e.j,i=n.f,r=i.i,c=i.j,s=h-r,f=l-c,t=y.Math.sqrt(s*s+f*f),t}function gY(n,e){var t,i;return i=WT(n),i||(t=(UF(),$Hn(e)),i=new Eyn(t),ve(i.El(),n)),i}function Ik(n,e){var t,i;return t=u(n.c.Bc(e),16),t?(i=n.hc(),i.Gc(t),n.d-=t.gc(),t.$b(),n.mc(i)):n.jc()}function G6e(n,e){var t,i;for(i=to(n.d,1)!=0,t=!0;t;)t=!1,t=e.c.mg(e.e,i),t=t|oy(n,e,i,!1),i=!i;NQ(n)}function VFn(n,e,t,i){var r,c;n.a=e,c=i?0:1,n.f=(r=new o_n(n.c,n.a,t,c),new Kqn(t,n.a,r,n.e,n.b,n.c==(P0(),Q8)))}function xT(n){var e;return oe(n.a!=n.b),e=n.d.a[n.a],jAn(n.b==n.d.c&&e!=null),n.c=n.a,n.a=n.a+1&n.d.a.length-1,e}function WFn(n){var e;if(n.c!=0)return n.c;for(e=0;e=n.c.b:n.a<=n.c.b))throw M(new nc);return e=n.a,n.a+=n.c.c,++n.b,Y(e)}function ex(n){var e;return e=new OX(n.a),Ur(e,n),U(e,(W(),st),n),e.o.a=n.g,e.o.b=n.f,e.n.a=n.i,e.n.b=n.j,e}function tx(n){return(en(),mu).Hc(n.j)?$(R(v(n,(W(),yv)))):cc(A(T(Ei,1),J,8,0,[n.i.n,n.n,n.a])).b}function X6e(n){var e;return e=OC(Cie),u(v(n,(W(),Hc)),21).Hc((pr(),kv))&&Ke(e,(Vi(),Oc),(tr(),FP)),e}function V6e(n){var e,t,i,r;for(r=new ni,i=new C(n);i.a=0?e:-e;i>0;)i%2==0?(t*=t,i=i/2|0):(r*=t,i-=1);return e<0?1/r:r}function Z6e(n,e){var t,i,r;for(r=1,t=n,i=e>=0?e:-e;i>0;)i%2==0?(t*=t,i=i/2|0):(r*=t,i-=1);return e<0?1/r:r}function ea(n,e){var t,i,r,c;return c=(r=n?WT(n):null,O_n((i=e,r&&r.Gl(),i))),c==e&&(t=WT(n),t&&t.Gl()),c}function JFn(n,e,t){var i,r;return r=n.f,n.f=e,n.Db&4&&!(n.Db&1)&&(i=new Ci(n,1,0,r,e),t?t.nj(i):t=i),t}function QFn(n,e,t){var i,r;return r=n.b,n.b=e,n.Db&4&&!(n.Db&1)&&(i=new Ci(n,1,3,r,e),t?t.nj(i):t=i),t}function mY(n,e,t){var i,r;return r=n.a,n.a=e,n.Db&4&&!(n.Db&1)&&(i=new Ci(n,1,1,r,e),t?t.nj(i):t=i),t}function YFn(n){var e,t;if(n!=null)for(t=0;t=i||e-129&&n<128?(xSn(),e=n+128,t=wun[e],!t&&(t=wun[e]=new mG(n)),t):new mG(n)}function om(n){var e,t;return n>-129&&n<128?(ZSn(),e=n+128,t=vun[e],!t&&(t=vun[e]=new kG(n)),t):new kG(n)}function eBn(n,e){var t;n.a.c.length>0&&(t=u(sn(n.a,n.a.c.length-1),579),oY(t,e))||nn(n.a,new vLn(e))}function c5e(n){Fs();var e,t;e=n.d.c-n.e.c,t=u(n.g,154),nu(t.b,new g7n(e)),nu(t.c,new p7n(e)),qi(t.i,new m7n(e))}function tBn(n){var e;return e=new x1,e.a+="VerticalSegment ",Dc(e,n.e),e.a+=" ",Re(e,BX(new yD,new C(n.k))),e.a}function ix(n,e){var t,i,r;for(t=0,r=uc(n,e).Kc();r.Ob();)i=u(r.Pb(),12),t+=v(i,(W(),Xu))!=null?1:0;return t}function Fg(n,e,t){var i,r,c;for(i=0,c=ge(n,0);c.b!=c.d.c&&(r=$(R(be(c))),!(r>t));)r>=e&&++i;return i}function iBn(n,e){Se(n);try{return n._b(e)}catch(t){if(t=It(t),D(t,212)||D(t,169))return!1;throw M(t)}}function kY(n,e){Se(n);try{return n.Hc(e)}catch(t){if(t=It(t),D(t,212)||D(t,169))return!1;throw M(t)}}function u5e(n,e){Se(n);try{return n.Mc(e)}catch(t){if(t=It(t),D(t,212)||D(t,169))return!1;throw M(t)}}function tw(n,e){Se(n);try{return n.xc(e)}catch(t){if(t=It(t),D(t,212)||D(t,169))return null;throw M(t)}}function o5e(n,e){Se(n);try{return n.Bc(e)}catch(t){if(t=It(t),D(t,212)||D(t,169))return null;throw M(t)}}function b5(n,e){switch(e.g){case 2:case 1:return uc(n,e);case 3:case 4:return Qo(uc(n,e))}return Dn(),Dn(),sr}function w5(n){var e;return n.Db&64?Hs(n):(e=new ls(Hs(n)),e.a+=" (name: ",Er(e,n.zb),e.a+=")",e.a)}function s5e(n){var e;return e=u(Nf(n.c.c,""),233),e||(e=new Np(c4(r4(new tp,""),"Other")),s1(n.c.c,"",e)),e}function yY(n,e,t){var i,r;return r=n.sb,n.sb=e,n.Db&4&&!(n.Db&1)&&(i=new Ci(n,1,4,r,e),t?t.nj(i):t=i),t}function jY(n,e,t){var i,r;return r=n.r,n.r=e,n.Db&4&&!(n.Db&1)&&(i=new Ci(n,1,8,r,n.r),t?t.nj(i):t=i),t}function f5e(n,e,t){var i,r;return i=new ml(n.e,4,13,(r=e.c,r||(On(),Zf)),null,f1(n,e),!1),t?t.nj(i):t=i,t}function h5e(n,e,t){var i,r;return i=new ml(n.e,3,13,null,(r=e.c,r||(On(),Zf)),f1(n,e),!1),t?t.nj(i):t=i,t}function r1(n,e){var t,i;return t=u(e,691),i=t.el(),!i&&t.fl(i=D(e,90)?new $Mn(n,u(e,29)):new rDn(n,u(e,156))),i}function Ok(n,e,t){var i;n._i(n.i+1),i=n.Zi(e,t),e!=n.i&&Ic(n.g,e,n.g,e+1,n.i-e),$t(n.g,e,i),++n.i,n.Mi(e,t),n.Ni()}function l5e(n,e){var t;return e.a&&(t=e.a.a.length,n.a?Re(n.a,n.b):n.a=new mo(n.d),lDn(n.a,e.a,e.d.length,t)),n}function a5e(n,e){var t;n.c=e,n.a=p8e(e),n.a<54&&(n.f=(t=e.d>1?fDn(e.a[0],e.a[1]):fDn(e.a[0],0),id(e.e>0?t:n1(t))))}function Dk(n,e){var t;return t=new LO,n.a.Bd(t)?(d4(),new wD(Jn(UNn(n,t.a,e)))):(X1(n),d4(),d4(),Iun)}function rBn(n,e){var t;n.c.length!=0&&(t=u(Ff(n,K(Qh,b1,10,n.c.length,0,1)),199),EX(t,new ign),Y_n(t,e))}function cBn(n,e){var t;n.c.length!=0&&(t=u(Ff(n,K(Qh,b1,10,n.c.length,0,1)),199),EX(t,new rgn),Y_n(t,e))}function rt(n,e){return Ai(n)?An(n,e):$b(n)?ZAn(n,e):Nb(n)?(Jn(n),x(n)===x(e)):gW(n)?n.Fb(e):fW(n)?QMn(n,e):fJ(n,e)}function Wo(n,e,t){if(e<0)Ann(n,t);else{if(!t.rk())throw M(new Gn(ba+t.xe()+a8));u(t,69).wk().Ek(n,n.hi(),e)}}function uBn(n,e,t){if(n<0||e>t)throw M(new Ir(ZA+n+Ttn+e+", size: "+t));if(n>e)throw M(new Gn(ZA+n+Qzn+e))}function oBn(n){var e;return n.Db&64?Hs(n):(e=new ls(Hs(n)),e.a+=" (source: ",Er(e,n.d),e.a+=")",e.a)}function sBn(n){return n>=65&&n<=70?n-65+10:n>=97&&n<=102?n-97+10:n>=48&&n<=57?n-48:0}function d5e(n){VA();var e,t,i,r;for(t=jx(),i=0,r=t.length;i=0?ia(n):H6(ia(n1(n))))}function lBn(n,e,t,i,r,c){this.e=new Z,this.f=(gr(),W8),nn(this.e,n),this.d=e,this.a=t,this.b=i,this.f=r,this.c=c}function g5e(n,e,t){n.n=Wa(Fa,[J,SB],[376,28],14,[t,wi(y.Math.ceil(e/32))],2),n.o=e,n.p=t,n.j=e-1>>1,n.k=t-1>>1}function aBn(n){return n-=n>>1&1431655765,n=(n>>2&858993459)+(n&858993459),n=(n>>4)+n&252645135,n+=n>>8,n+=n>>16,n&63}function dBn(n,e){var t,i;for(i=new ne(n);i.e!=i.i.gc();)if(t=u(ue(i),142),x(e)===x(t))return!0;return!1}function p5e(n,e,t){var i,r,c;return c=(r=Cm(n.b,e),r),c&&(i=u(qA(fk(n,c),""),29),i)?Wnn(n,i,e,t):null}function rx(n,e,t){var i,r,c;return c=(r=Cm(n.b,e),r),c&&(i=u(qA(fk(n,c),""),29),i)?Jnn(n,i,e,t):null}function m5e(n,e){var t;if(t=Lg(n.i,e),t==null)throw M(new eh("Node did not exist in input."));return _Q(e,t),null}function v5e(n,e){var t;if(t=uy(n,e),D(t,331))return u(t,35);throw M(new Gn(ba+e+"' is not a valid attribute"))}function p5(n,e,t){var i;if(i=n.gc(),e>i)throw M(new Kb(e,i));if(n.Si()&&n.Hc(t))throw M(new Gn(Xy));n.Gi(e,t)}function k5e(n,e){e.Ug("Sort end labels",1),qt(ut(rc(new Tn(null,new In(n.b,16)),new _wn),new Hwn),new qwn),e.Vg()}function ci(){ci=F,Jf=new p7(Y5,0),Xr=new p7(f3,1),Br=new p7(s3,2),Wf=new p7(_B,3),us=new p7("UP",4)}function Nk(){Nk=F,XI=new sL("P1_STRUCTURE",0),VI=new sL("P2_PROCESSING_ORDER",1),WI=new sL("P3_EXECUTION",2)}function bBn(){bBn=F,Rre=ah(ah(s6(ah(ah(s6(Ke(new ii,(Qp(),n9),(B5(),ZH)),e9),fln),lln),t9),cln),aln)}function y5e(n){switch(u(v(n,(W(),Od)),311).g){case 1:U(n,Od,(vl(),E3));break;case 2:U(n,Od,(vl(),k2))}}function j5e(n){switch(n){case 0:return new ijn;case 1:return new ejn;case 2:return new tjn;default:throw M(new W9)}}function wBn(n){switch(n.g){case 2:return Xr;case 1:return Br;case 4:return Wf;case 3:return us;default:return Jf}}function TY(n,e){switch(n.b.g){case 0:case 1:return e;case 2:case 3:return new Ho(e.d,0,e.a,e.b);default:return null}}function AY(n){switch(n.g){case 1:return Wn;case 2:return Xn;case 3:return Zn;case 4:return ae;default:return sc}}function $k(n){switch(n.g){case 1:return ae;case 2:return Wn;case 3:return Xn;case 4:return Zn;default:return sc}}function RT(n){switch(n.g){case 1:return Zn;case 2:return ae;case 3:return Wn;case 4:return Xn;default:return sc}}function SY(n,e,t,i){switch(e){case 1:return!n.n&&(n.n=new q(Ar,n,1,7)),n.n;case 2:return n.k}return kZ(n,e,t,i)}function m5(n,e,t){var i,r;return n.Pj()?(r=n.Qj(),i=lF(n,e,t),n.Jj(n.Ij(7,Y(t),i,e,r)),i):lF(n,e,t)}function cx(n,e){var t,i,r;n.d==null?(++n.e,--n.f):(r=e.ld(),t=e.Bi(),i=(t&et)%n.d.length,o4e(n,i,RHn(n,i,t,r)))}function sm(n,e){var t;t=(n.Bb&Gs)!=0,e?n.Bb|=Gs:n.Bb&=-1025,n.Db&4&&!(n.Db&1)&&it(n,new Rs(n,1,10,t,e))}function fm(n,e){var t;t=(n.Bb&vw)!=0,e?n.Bb|=vw:n.Bb&=-4097,n.Db&4&&!(n.Db&1)&&it(n,new Rs(n,1,12,t,e))}function hm(n,e){var t;t=(n.Bb&$u)!=0,e?n.Bb|=$u:n.Bb&=-8193,n.Db&4&&!(n.Db&1)&&it(n,new Rs(n,1,15,t,e))}function lm(n,e){var t;t=(n.Bb&Tw)!=0,e?n.Bb|=Tw:n.Bb&=-2049,n.Db&4&&!(n.Db&1)&&it(n,new Rs(n,1,11,t,e))}function E5e(n){var e;n.g&&(e=n.c.kg()?n.f:n.a,fen(e.a,n.o,!0),fen(e.a,n.o,!1),U(n.o,(cn(),Kt),(Oi(),Ud)))}function C5e(n){var e;if(!n.a)throw M(new Or("Cannot offset an unassigned cut."));e=n.c-n.b,n.b+=e,KIn(n,e),RIn(n,e)}function M5e(n,e){var t;if(t=ee(n.k,e),t==null)throw M(new eh("Port did not exist in input."));return _Q(e,t),null}function T5e(n){var e,t;for(t=xHn(jo(n)).Kc();t.Ob();)if(e=Oe(t.Pb()),R5(n,e))return A3e((pCn(),Boe),e);return null}function gBn(n){var e,t;for(t=n.p.a.ec().Kc();t.Ob();)if(e=u(t.Pb(),218),e.f&&n.b[e.c]<-1e-10)return e;return null}function A5e(n){var e,t;for(t=z1(new x1,91),e=!0;n.Ob();)e||(t.a+=ur),e=!1,Dc(t,n.Pb());return(t.a+="]",t).a}function S5e(n){var e,t,i;for(e=new Z,i=new C(n.b);i.ae?1:n==e?n==0?bt(1/n,1/e):0:isNaN(n)?isNaN(e)?0:1:-1}function I5e(n){var e;return e=n.a[n.c-1&n.a.length-1],e==null?null:(n.c=n.c-1&n.a.length-1,$t(n.a,n.c,null),e)}function O5e(n){var e,t,i;for(i=0,t=n.length,e=0;e=1?Xr:Wf):t}function $5e(n){switch(u(v(n,(cn(),$l)),223).g){case 1:return new Spn;case 3:return new Lpn;default:return new Apn}}function ta(n){if(n.c)ta(n.c);else if(n.d)throw M(new Or("Stream already terminated, can't be modified or used"))}function L0(n,e,t){var i;return i=n.a.get(e),n.a.set(e,t===void 0?null:t),i===void 0?(++n.c,++n.b.g):++n.d,i}function x5e(n,e,t){var i,r;for(r=n.a.ec().Kc();r.Ob();)if(i=u(r.Pb(),10),jk(t,u(sn(e,i.p),16)))return i;return null}function IY(n,e,t){var i;return i=0,e&&(vg(n.a)?i+=e.f.a/2:i+=e.f.b/2),t&&(vg(n.a)?i+=t.f.a/2:i+=t.f.b/2),i}function F5e(n,e,t){var i;i=t,!i&&(i=QV(new op,0)),i.Ug(PXn,2),yRn(n.b,e,i.eh(1)),YIe(n,e,i.eh(1)),eLe(e,i.eh(1)),i.Vg()}function OY(n,e,t){var i,r;return i=(B1(),r=new kE,r),aT(i,e),lT(i,t),n&&ve((!n.a&&(n.a=new ti(xo,n,5)),n.a),i),i}function ox(n){var e;return n.Db&64?Hs(n):(e=new ls(Hs(n)),e.a+=" (identifier: ",Er(e,n.k),e.a+=")",e.a)}function sx(n,e){var t;t=(n.Bb&kc)!=0,e?n.Bb|=kc:n.Bb&=-32769,n.Db&4&&!(n.Db&1)&&it(n,new Rs(n,1,18,t,e))}function DY(n,e){var t;t=(n.Bb&kc)!=0,e?n.Bb|=kc:n.Bb&=-32769,n.Db&4&&!(n.Db&1)&&it(n,new Rs(n,1,18,t,e))}function am(n,e){var t;t=(n.Bb&wh)!=0,e?n.Bb|=wh:n.Bb&=-16385,n.Db&4&&!(n.Db&1)&&it(n,new Rs(n,1,16,t,e))}function LY(n,e){var t;t=(n.Bb&hr)!=0,e?n.Bb|=hr:n.Bb&=-65537,n.Db&4&&!(n.Db&1)&&it(n,new Rs(n,1,20,t,e))}function NY(n){var e;return e=K(fs,gh,28,2,15,1),n-=hr,e[0]=(n>>10)+Ay&ui,e[1]=(n&1023)+56320&ui,ws(e,0,e.length)}function B5e(n){var e;return e=sw(n),e>34028234663852886e22?St:e<-34028234663852886e22?li:e}function nr(n,e){var t;return Vr(n)&&Vr(e)&&(t=n+e,Ty"+td(e.c):"e_"+mt(e),n.b&&n.c?td(n.b)+"->"+td(n.c):"e_"+mt(n))}function _5e(n,e){return An(e.b&&e.c?td(e.b)+"->"+td(e.c):"e_"+mt(e),n.b&&n.c?td(n.b)+"->"+td(n.c):"e_"+mt(n))}function N0(n,e){return Tf(),Ks(fa),y.Math.abs(n-e)<=fa||n==e||isNaN(n)&&isNaN(e)?0:ne?1:u0(isNaN(n),isNaN(e))}function El(){El=F,hU=new vC(Y5,0),Qj=new vC("POLYLINE",1),Bv=new vC("ORTHOGONAL",2),x3=new vC("SPLINES",3)}function _T(){_T=F,f1n=new uL("ASPECT_RATIO_DRIVEN",0),Oq=new uL("MAX_SCALE_DRIVEN",1),s1n=new uL("AREA_DRIVEN",2)}function H5e(n,e,t){var i;try{l6e(n,e,t)}catch(r){throw r=It(r),D(r,606)?(i=r,M(new NJ(i))):M(r)}return e}function q5e(n){var e,t,i;for(t=0,i=n.length;te&&i.Ne(n[c-1],n[c])>0;--c)s=n[c],$t(n,c,n[c-1]),$t(n,c-1,s)}function vn(n,e){var t,i,r,c,s;if(t=e.f,s1(n.c.d,t,e),e.g!=null)for(r=e.g,c=0,s=r.length;ce){bDn(t);break}}_7(t,e)}function X5e(n,e){var t,i,r;i=Pg(e),r=$(R(rw(i,(cn(),Ws)))),t=y.Math.max(0,r/2-.5),A5(e,t,1),nn(n,new LCn(e,t))}function V5e(n,e,t){var i;t.Ug("Straight Line Edge Routing",1),t.dh(e,Nrn),i=u(z(e,(Tg(),D2)),27),iGn(n,i),t.dh(e,DS)}function $Y(n,e){n.n.c.length==0&&nn(n.n,new NM(n.s,n.t,n.i)),nn(n.b,e),wZ(u(sn(n.n,n.n.c.length-1),209),e),RUn(n,e)}function v5(n){var e;this.a=(e=u(n.e&&n.e(),9),new _o(e,u(xs(e,e.length),9),0)),this.b=K(ki,Fn,1,this.a.a.length,5,1)}function Jr(n){var e;return Array.isArray(n)&&n.Tm===Q2?Xa(wo(n))+"@"+(e=mt(n)>>>0,e.toString(16)):n.toString()}function W5e(n,e){return n.h==My&&n.m==0&&n.l==0?(e&&(wa=Yc(0,0,0)),ZMn((B4(),fun))):(e&&(wa=Yc(n.l,n.m,n.h)),Yc(0,0,0))}function J5e(n,e){switch(e.g){case 2:return n.b;case 1:return n.c;case 4:return n.d;case 3:return n.a;default:return!1}}function kBn(n,e){switch(e.g){case 2:return n.b;case 1:return n.c;case 4:return n.d;case 3:return n.a;default:return!1}}function xY(n,e,t,i){switch(e){case 3:return n.f;case 4:return n.g;case 5:return n.i;case 6:return n.j}return SY(n,e,t,i)}function HT(n,e){if(e==n.d)return n.e;if(e==n.e)return n.d;throw M(new Gn("Node "+e+" not part of edge "+n))}function Q5e(n,e){var t;if(t=uy(n.Dh(),e),D(t,102))return u(t,19);throw M(new Gn(ba+e+"' is not a valid reference"))}function Jo(n,e,t,i){if(e<0)nen(n,t,i);else{if(!t.rk())throw M(new Gn(ba+t.xe()+a8));u(t,69).wk().Ck(n,n.hi(),e,i)}}function eo(n){var e;if(n.b){if(eo(n.b),n.b.d!=n.c)throw M(new Bo)}else n.d.dc()&&(e=u(n.f.c.xc(n.e),16),e&&(n.d=e))}function Y5e(n){Bb();var e,t,i,r;for(e=n.o.b,i=u(u(ot(n.r,(en(),ae)),21),87).Kc();i.Ob();)t=u(i.Pb(),117),r=t.e,r.b+=e}function Z5e(n){var e,t,i;for(this.a=new rh,i=new C(n);i.a=r)return e.c+t;return e.c+e.b.gc()}function e8e(n,e){p4();var t,i,r,c;for(i=DNn(n),r=e,x4(i,0,i.length,r),t=0;t0&&(i+=r,++t);return t>1&&(i+=n.d*(t-1)),i}function i8e(n){var e,t,i,r,c;return c=nnn(n),t=Z9(n.c),i=!t,i&&(r=new _a,bf(c,"knownLayouters",r),e=new hyn(r),qi(n.c,e)),c}function RY(n){var e,t,i;for(i=new Hl,i.a+="[",e=0,t=n.gc();e0&&(zn(e-1,n.length),n.charCodeAt(e-1)==58)&&!lx(n,O9,D9))}function KY(n,e){var t;return x(n)===x(e)?!0:D(e,92)?(t=u(e,92),n.e==t.e&&n.d==t.d&&I3e(n,t.a)):!1}function zp(n){switch(en(),n.g){case 4:return Xn;case 1:return Zn;case 3:return ae;case 2:return Wn;default:return sc}}function o8e(n){var e,t;if(n.b)return n.b;for(t=Uf?null:n.d;t;){if(e=Uf?null:t.b,e)return e;t=Uf?null:t.d}return l4(),Lun}function _Y(n){var e,t,i;for(i=$(R(n.a.of((He(),iO)))),t=new C(n.a.Sf());t.a>5,e=n&31,i=K(ye,_e,28,t+1,15,1),i[t]=1<3;)r*=10,--c;n=(n+(r>>1))/r|0}return i.i=n,!0}function Ot(n,e){var t,i,r;if(t=(n.i==null&&bh(n),n.i),i=e.Lj(),i!=-1){for(r=t.length;i=0;--i)for(e=t[i],r=0;r>1,this.k=e-1>>1}function j8e(n){YM(),u(n.of((He(),Ta)),181).Hc((io(),hO))&&(u(n.of(Ww),181).Fc((zu(),F3)),u(n.of(Ta),181).Mc(hO))}function ABn(n){var e,t;e=n.d==(Yp(),av),t=UZ(n),e&&!t||!e&&t?U(n.a,(cn(),Th),(Rh(),qj)):U(n.a,(cn(),Th),(Rh(),Hj))}function bx(){bx=F,ZE(),EI=(cn(),bb),Qte=Of(A(T(zq,1),yrn,149,0,[Mj,Ws,T2,db,qw,IH,Tv,Av,OH,G8,M2,Bd,A2]))}function E8e(n,e){var t;return t=u(Wr(n,qu(new ju,new yu,new Eu,A(T(xr,1),G,108,0,[(Gu(),Yr)]))),15),t.Qc(VSn(t.gc()))}function SBn(n,e){var t,i;if(i=new Q3(n.a.ad(e,!0)),i.a.gc()<=1)throw M(new rp);return t=i.a.ec().Kc(),t.Pb(),u(t.Pb(),39)}function C8e(n,e,t){var i,r;return i=$(n.p[e.i.p])+$(n.d[e.i.p])+e.n.b+e.a.b,r=$(n.p[t.i.p])+$(n.d[t.i.p])+t.n.b+t.a.b,r-i}function VY(n,e){var t;return n.i>0&&(e.lengthn.i&&$t(e,n.i,null),e}function UT(n){var e;return n.Db&64?w5(n):(e=new ls(w5(n)),e.a+=" (instanceClassName: ",Er(e,n.D),e.a+=")",e.a)}function GT(n){var e,t,i,r;for(r=0,t=0,i=n.length;t0?(n._j(),i=e==null?0:mt(e),r=(i&et)%n.d.length,t=RHn(n,r,i,e),t!=-1):!1}function PBn(n,e){var t,i;n.a=nr(n.a,1),n.c=y.Math.min(n.c,e),n.b=y.Math.max(n.b,e),n.d+=e,t=e-n.f,i=n.e+t,n.f=i-n.e-t,n.e=i}function WY(n,e){switch(e){case 3:A0(n,0);return;case 4:S0(n,0);return;case 5:eu(n,0);return;case 6:tu(n,0);return}vY(n,e)}function $0(n,e){switch(e.g){case 1:return Cp(n.j,(Ou(),$on));case 2:return Cp(n.j,(Ou(),Fon));default:return Dn(),Dn(),sr}}function JY(n){g0();var e;switch(e=n.Pc(),e.length){case 0:return qK;case 1:return new VL(Se(e[0]));default:return new PN(q5e(e))}}function IBn(n,e){n.Xj();try{n.d.bd(n.e++,e),n.f=n.d.j,n.g=-1}catch(t){throw t=It(t),D(t,77)?M(new Bo):M(t)}}function gx(){gx=F,MU=new Mvn,Gdn=new Tvn,zdn=new Avn,Xdn=new Svn,Vdn=new Pvn,Wdn=new Ivn,Jdn=new Ovn,Qdn=new Dvn,Ydn=new Lvn}function zT(n,e){vX();var t,i;return t=I7((RE(),RE(),C8)),i=null,e==t&&(i=u(Nc(oun,n),624)),i||(i=new WPn(n),e==t&&Dr(oun,n,i)),i}function OBn(n){cw();var e;return(n.q?n.q:(Dn(),Dn(),Wh))._b((cn(),lb))?e=u(v(n,lb),203):e=u(v(Hi(n),U8),203),e}function rw(n,e){var t,i;return i=null,kt(n,(cn(),yI))&&(t=u(v(n,yI),96),t.pf(e)&&(i=t.of(e))),i==null&&(i=v(Hi(n),e)),i}function DBn(n,e){var t,i,r;return D(e,44)?(t=u(e,44),i=t.ld(),r=tw(n.Rc(),i),sh(r,t.md())&&(r!=null||n.Rc()._b(i))):!1}function gf(n,e){var t,i,r;return n.f>0&&(n._j(),i=e==null?0:mt(e),r=(i&et)%n.d.length,t=Nnn(n,r,i,e),t)?t.md():null}function Xc(n,e,t){var i,r,c;return n.Pj()?(i=n.i,c=n.Qj(),Ok(n,i,e),r=n.Ij(3,null,e,i,c),t?t.nj(r):t=r):Ok(n,n.i,e),t}function T8e(n,e,t){var i,r;return i=new ml(n.e,4,10,(r=e.c,D(r,90)?u(r,29):(On(),Is)),null,f1(n,e),!1),t?t.nj(i):t=i,t}function A8e(n,e,t){var i,r;return i=new ml(n.e,3,10,null,(r=e.c,D(r,90)?u(r,29):(On(),Is)),f1(n,e),!1),t?t.nj(i):t=i,t}function LBn(n){Bb();var e;return e=new rr(u(n.e.of((He(),_2)),8)),n.B.Hc((io(),Kv))&&(e.a<=0&&(e.a=20),e.b<=0&&(e.b=20)),e}function ia(n){dh();var e,t;return t=Ae(n),e=Ae(U1(n,32)),e!=0?new _On(t,e):t>10||t<0?new gl(1,t):kQn[t]}function Fk(n,e){var t;return Vr(n)&&Vr(e)&&(t=n%e,Ty=0?c=c.a[1]:(r=c,c=c.a[0])}return r}function Rk(n,e,t){var i,r,c;for(r=null,c=n.b;c;){if(i=n.a.Ne(e,c.d),t&&i==0)return c;i<=0?c=c.a[0]:(r=c,c=c.a[1])}return r}function L8e(n,e,t,i){var r,c,s;return r=!1,xOe(n.f,t,i)&&(e9e(n.f,n.a[e][t],n.a[e][i]),c=n.a[e],s=c[i],c[i]=c[t],c[t]=s,r=!0),r}function FBn(n,e,t){var i,r,c,s;for(r=u(ee(n.b,t),183),i=0,s=new C(e.j);s.a>5,e&=31,r=n.d+t+(e==0?0:1),i=K(ye,_e,28,r,15,1),Oye(i,n.a,t,e),c=new Ya(n.e,r,i),V6(c),c}function N8e(n,e){var t,i,r;for(i=new ie(ce(Qt(n).a.Kc(),new En));pe(i);)if(t=u(fe(i),18),r=t.d.i,r.c==e)return!1;return!0}function ZY(n,e,t){var i,r,c,s,f;return s=n.k,f=e.k,i=t[s.g][f.g],r=R(rw(n,i)),c=R(rw(e,i)),y.Math.max((Jn(r),r),(Jn(c),c))}function $8e(){return Error.stackTraceLimit>0?(y.Error.stackTraceLimit=Error.stackTraceLimit=64,!0):"stack"in new Error}function x8e(n,e){return Tf(),Tf(),Ks(fa),(y.Math.abs(n-e)<=fa||n==e||isNaN(n)&&isNaN(e)?0:ne?1:u0(isNaN(n),isNaN(e)))>0}function nZ(n,e){return Tf(),Tf(),Ks(fa),(y.Math.abs(n-e)<=fa||n==e||isNaN(n)&&isNaN(e)?0:ne?1:u0(isNaN(n),isNaN(e)))<0}function RBn(n,e){return Tf(),Tf(),Ks(fa),(y.Math.abs(n-e)<=fa||n==e||isNaN(n)&&isNaN(e)?0:ne?1:u0(isNaN(n),isNaN(e)))<=0}function mx(n,e){for(var t=0;!e[t]||e[t]=="";)t++;for(var i=e[t++];t0&&this.b>0&&(this.g=rM(this.c,this.b,this.a))}function F8e(n,e){var t=n.a,i;e=String(e),t.hasOwnProperty(e)&&(i=t[e]);var r=(K$(),WK)[typeof i],c=r?r(i):bY(typeof i);return c}function bm(n){var e,t,i;if(i=null,e=Eh in n.a,t=!e,t)throw M(new eh("Every element must have an id."));return i=Zp(dl(n,Eh)),i}function x0(n){var e,t;for(t=l_n(n),e=null;n.c==2;)Ze(n),e||(e=(nt(),nt(),new T6(2)),pd(e,t),t=e),t.Jm(l_n(n));return t}function VT(n,e){var t,i,r;return n._j(),i=e==null?0:mt(e),r=(i&et)%n.d.length,t=Nnn(n,r,i,e),t?(X$n(n,t),t.md()):null}function zBn(n,e){return n.e>e.e?1:n.ee.d?n.e:n.d=48&&n<48+y.Math.min(10,10)?n-48:n>=97&&n<97?n-97+10:n>=65&&n<65?n-65+10:-1}function B8e(n,e){if(e.c==n)return e.d;if(e.d==n)return e.c;throw M(new Gn("Input edge is not connected to the input port."))}function R8e(n){if(JT(Zm,n))return _n(),uv;if(JT(cK,n))return _n(),ga;throw M(new Gn("Expecting true or false"))}function iZ(n){switch(typeof n){case nB:return t1(n);case ltn:return pp(n);case i3:return AAn(n);default:return n==null?0:f0(n)}}function ah(n,e){if(n.a<0)throw M(new Or("Did not call before(...) or after(...) before calling add(...)."));return QX(n,n.a,e),n}function rZ(n){return $M(),D(n,162)?u(ee(fE,MQn),294).Rg(n):Zc(fE,wo(n))?u(ee(fE,wo(n)),294).Rg(n):null}function iu(n){var e,t;return n.Db&32||(t=(e=u(Un(n,16),29),se(e||n.ii())-se(n.ii())),t!=0&&Xp(n,32,K(ki,Fn,1,t,5,1))),n}function Xp(n,e,t){var i;n.Db&e?t==null?jCe(n,e):(i=Rx(n,e),i==-1?n.Eb=t:$t(cd(n.Eb),i,t)):t!=null&>e(n,e,t)}function K8e(n,e,t,i){var r,c;e.c.length!=0&&(r=$Me(t,i),c=xEe(e),qt(fT(new Tn(null,new In(c,1)),new D3n),new CIn(n,t,r,i)))}function _8e(n,e){var t,i,r,c;return i=n.a.length-1,t=e-n.b&i,c=n.c-e&i,r=n.c-n.b&i,jAn(t=c?(R6e(n,e),-1):(B6e(n,e),1)}function WT(n){var e,t,i;if(i=n.Jh(),!i)for(e=0,t=n.Ph();t;t=t.Ph()){if(++e>PB)return t.Qh();if(i=t.Jh(),i||t==n)break}return i}function VBn(n,e){var t;return x(e)===x(n)?!0:!D(e,21)||(t=u(e,21),t.gc()!=n.gc())?!1:n.Ic(t)}function H8e(n,e){return n.ee.e?1:n.fe.f?1:mt(n)-mt(e)}function JT(n,e){return Jn(n),e==null?!1:An(n,e)?!0:n.length==e.length&&An(n.toLowerCase(),e.toLowerCase())}function Ml(n){var e,t;return Ec(n,-129)>0&&Ec(n,128)<0?(YSn(),e=Ae(n)+128,t=gun[e],!t&&(t=gun[e]=new vG(n)),t):new vG(n)}function dd(){dd=F,Ow=new lC(kh,0),Ion=new lC("INSIDE_PORT_SIDE_GROUPS",1),P_=new lC("GROUP_MODEL_ORDER",2),I_=new lC(nin,3)}function q8e(n){var e;return n.b||xhe(n,(e=$ae(n.e,n.a),!e||!An(cK,gf((!e.b&&(e.b=new lo((On(),ar),pc,e)),e.b),"qualified")))),n.c}function U8e(n,e){var t,i;for(t=(zn(e,n.length),n.charCodeAt(e)),i=e+1;i2e3&&(hQn=n,uP=y.setTimeout(_he,10))),cP++==0?(ime((lz(),uun)),!0):!1}function r9e(n,e,t){var i;(DQn?(o8e(n),!0):LQn||$Qn?(l4(),!0):NQn&&(l4(),!1))&&(i=new lSn(e),i.b=t,aje(n,i))}function kx(n,e){var t;t=!n.A.Hc((go(),Gd))||n.q==(Oi(),qc),n.u.Hc((zu(),Fl))?t?XDe(n,e):UGn(n,e):n.u.Hc(Ia)&&(t?dDe(n,e):czn(n,e))}function nRn(n){var e;x(z(n,(He(),R2)))===x((jl(),uO))&&(At(n)?(e=u(z(At(n),R2),346),ht(n,R2,e)):ht(n,R2,j9))}function c9e(n){var e,t;return kt(n.d.i,(cn(),Ev))?(e=u(v(n.c.i,Ev),17),t=u(v(n.d.i,Ev),17),jc(e.a,t.a)>0):!1}function eRn(n,e,t){return new Ho(y.Math.min(n.a,e.a)-t/2,y.Math.min(n.b,e.b)-t/2,y.Math.abs(n.a-e.a)+t,y.Math.abs(n.b-e.b)+t)}function tRn(n){var e;this.d=new Z,this.j=new Li,this.g=new Li,e=n.g.b,this.f=u(v(Hi(e),(cn(),Do)),88),this.e=$(R(nA(e,qw)))}function iRn(n){this.d=new Z,this.e=new Ql,this.c=K(ye,_e,28,(en(),A(T(lr,1),Mc,64,0,[sc,Xn,Zn,ae,Wn])).length,15,1),this.b=n}function oZ(n,e,t){var i;switch(i=t[n.g][e],n.g){case 1:case 3:return new V(0,i);case 2:case 4:return new V(i,0);default:return null}}function rRn(n,e,t){var i,r;r=u(z7(e.f),205);try{r.rf(n,t),fIn(e.f,r)}catch(c){throw c=It(c),D(c,103)?(i=c,M(i)):M(c)}}function cRn(n,e,t){var i,r,c,s,f,h;return i=null,f=Qen(G4(),e),c=null,f&&(r=null,h=Wen(f,t),s=null,h!=null&&(s=n.qf(f,h)),r=s,c=r),i=c,i}function yx(n,e,t,i){var r;if(r=n.length,e>=r)return r;for(e=e>0?e:0;ei&&$t(e,i,null),e}function uRn(n,e){var t,i;for(i=n.a.length,e.lengthi&&$t(e,i,null),e}function wm(n,e){var t,i;if(++n.j,e!=null&&(t=(i=n.a.Cb,D(i,99)?u(i,99).th():null),hCe(e,t))){Xp(n.a,4,t);return}Xp(n.a,4,u(e,129))}function u9e(n){var e;if(n==null)return null;if(e=lMe(Fc(n,!0)),e==null)throw M(new kD("Invalid hexBinary value: '"+n+"'"));return e}function QT(n,e,t){var i;e.a.length>0&&(nn(n.b,new ASn(e.a,t)),i=e.a.length,0i&&(e.a+=PTn(K(fs,gh,28,-i,15,1))))}function oRn(n,e,t){var i,r,c;if(!t[e.d])for(t[e.d]=!0,r=new C(xg(e));r.a=n.b>>1)for(i=n.c,t=n.b;t>e;--t)i=i.b;else for(i=n.a.a,t=0;t=0?n.Wh(r):hF(n,i)):t<0?hF(n,i):u(i,69).wk().Bk(n,n.hi(),t)}function lRn(n){var e,t,i;for(i=(!n.o&&(n.o=new Iu((Cc(),il),T1,n,0)),n.o),t=i.c.Kc();t.e!=t.i.gc();)e=u(t.Yj(),44),e.md();return ik(i)}function rn(n){var e;if(D(n.a,4)){if(e=rZ(n.a),e==null)throw M(new Or(NVn+n.b+"'. "+LVn+(ll(hE),hE.k)+acn));return e}else return n.a}function b9e(n,e){var t,i;if(n.j.length!=e.j.length)return!1;for(t=0,i=n.j.length;t=64&&e<128&&(r=lf(r,Bs(1,e-64)));return r}function nA(n,e){var t,i;return i=null,kt(n,(He(),N3))&&(t=u(v(n,N3),96),t.pf(e)&&(i=t.of(e))),i==null&&Hi(n)&&(i=v(Hi(n),e)),i}function w9e(n,e){var t;return t=u(v(n,(cn(),Fr)),75),yL(e,LZn)?t?vo(t):(t=new Mu,U(n,Fr,t)):t&&U(n,Fr,null),t}function j5(){j5=F,hon=(He(),Han),g_=jan,DYn=x2,fon=C1,xYn=(aA(),Hun),$Yn=Kun,FYn=Uun,NYn=Run,LYn=(Q$(),uon),w_=PYn,son=IYn,pP=OYn}function eA(n){switch(Nz(),this.c=new Z,this.d=n,n.g){case 0:case 2:this.a=HW(Pon),this.b=St;break;case 3:case 1:this.a=Pon,this.b=li}}function g9e(n){var e;Ep(u(v(n,(cn(),Kt)),101))&&(e=n.b,nHn((Ln(0,e.c.length),u(e.c[0],30))),nHn(u(sn(e,e.c.length-1),30)))}function p9e(n,e){e.Ug("Self-Loop post-processing",1),qt(ut(ut(rc(new Tn(null,new In(n.b,16)),new o2n),new s2n),new f2n),new h2n),e.Vg()}function aRn(n,e,t){var i,r;if(n.c)eu(n.c,n.c.i+e),tu(n.c,n.c.j+t);else for(r=new C(n.b);r.a=0&&(t.d=n.t);break;case 3:n.t>=0&&(t.a=n.t)}n.C&&(t.b=n.C.b,t.c=n.C.c)}function E5(){E5=F,Dhn=new l7(jrn,0),KH=new l7(sR,1),_H=new l7("LINEAR_SEGMENTS",2),X8=new l7("BRANDES_KOEPF",3),V8=new l7(sVn,4)}function C5(){C5=F,sj=new fC(eS,0),wP=new fC(HB,1),gP=new fC(qB,2),fj=new fC(UB,3),sj.a=!1,wP.a=!0,gP.a=!1,fj.a=!0}function Vp(){Vp=F,cj=new sC(eS,0),rj=new sC(HB,1),uj=new sC(qB,2),oj=new sC(UB,3),cj.a=!1,rj.a=!0,uj.a=!1,oj.a=!0}function Wp(n,e,t,i){var r;return t>=0?n.Sh(e,t,i):(n.Ph()&&(i=(r=n.Fh(),r>=0?n.Ah(i):n.Ph().Th(n,-1-r,null,i))),n.Ch(e,t,i))}function sZ(n,e){switch(e){case 7:!n.e&&(n.e=new Nn(Vt,n,7,4)),me(n.e);return;case 8:!n.d&&(n.d=new Nn(Vt,n,8,5)),me(n.d);return}WY(n,e)}function ht(n,e,t){return t==null?(!n.o&&(n.o=new Iu((Cc(),il),T1,n,0)),VT(n.o,e)):(!n.o&&(n.o=new Iu((Cc(),il),T1,n,0)),Gk(n.o,e,t)),n}function gRn(n,e){Dn();var t,i,r,c;for(t=n,c=e,D(n,21)&&!D(e,21)&&(t=e,c=n),r=t.Kc();r.Ob();)if(i=r.Pb(),c.Hc(i))return!1;return!0}function j9e(n,e,t,i){if(e.at.b)return!0}return!1}function Tx(n,e){return Ai(n)?!!iQn[e]:n.Sm?!!n.Sm[e]:$b(n)?!!tQn[e]:Nb(n)?!!eQn[e]:!1}function E9e(n){var e;e=n.a;do e=u(fe(new ie(ce(ji(e).a.Kc(),new En))),18).c.i,e.k==(Vn(),Mi)&&n.b.Fc(e);while(e.k==(Vn(),Mi));n.b=Qo(n.b)}function pRn(n,e){var t,i,r;for(r=n,i=new ie(ce(ji(e).a.Kc(),new En));pe(i);)t=u(fe(i),18),t.c.i.c&&(r=y.Math.max(r,t.c.i.c.p));return r}function C9e(n,e){var t,i,r;for(r=0,i=u(u(ot(n.r,e),21),87).Kc();i.Ob();)t=u(i.Pb(),117),r+=t.d.d+t.b.Mf().b+t.d.a,i.Ob()&&(r+=n.w);return r}function M9e(n,e){var t,i,r;for(r=0,i=u(u(ot(n.r,e),21),87).Kc();i.Ob();)t=u(i.Pb(),117),r+=t.d.b+t.b.Mf().a+t.d.c,i.Ob()&&(r+=n.w);return r}function mRn(n){var e,t,i,r;if(i=0,r=aw(n),r.c.length==0)return 1;for(t=new C(r);t.a=0?n.Lh(s,t,!0):K0(n,c,t)):u(c,69).wk().yk(n,n.hi(),r,t,i)}function P9e(n,e,t,i){var r,c;c=e.pf((He(),K2))?u(e.of(K2),21):n.j,r=d5e(c),r!=(VA(),l_)&&(t&&!eZ(r)||dnn(aMe(n,r,i),e))}function I9e(n){switch(n.g){case 1:return D0(),ij;case 3:return D0(),tj;case 2:return D0(),d_;case 4:return D0(),a_;default:return null}}function O9e(n,e,t){if(n.e)switch(n.b){case 1:yge(n.c,e,t);break;case 0:jge(n.c,e,t)}else RDn(n.c,e,t);n.a[e.p][t.p]=n.c.i,n.a[t.p][e.p]=n.c.e}function vRn(n){var e,t;if(n==null)return null;for(t=K(Qh,J,199,n.length,0,2),e=0;e=0)return r;if(n.ol()){for(i=0;i=r)throw M(new Kb(e,r));if(n.Si()&&(i=n.dd(t),i>=0&&i!=e))throw M(new Gn(Xy));return n.Xi(e,t)}function fZ(n,e){if(this.a=u(Se(n),253),this.b=u(Se(e),253),n.Ed(e)>0||n==(dD(),_K)||e==(bD(),HK))throw M(new Gn("Invalid range: "+HDn(n,e)))}function kRn(n){var e,t;for(this.b=new Z,this.c=n,this.a=!1,t=new C(n.a);t.a0),(e&-e)==e)return wi(e*to(n,31)*4656612873077393e-25);do t=to(n,31),i=t%e;while(t-i+(e-1)<0);return wi(i)}function F9e(n,e,t){switch(t.g){case 1:n.a=e.a/2,n.b=0;break;case 2:n.a=e.a,n.b=e.b/2;break;case 3:n.a=e.a/2,n.b=e.b;break;case 4:n.a=0,n.b=e.b/2}}function Kk(n,e,t,i){var r,c;for(r=e;r1&&(c=L9e(n,e)),c}function ERn(n){var e;return e=$(R(z(n,(He(),Jj))))*y.Math.sqrt((!n.a&&(n.a=new q(Ye,n,10,11)),n.a).i),new V(e,e/$(R(z(n,rO))))}function Sx(n){var e;return n.f&&n.f.Vh()&&(e=u(n.f,54),n.f=u(ea(n,e),84),n.f!=e&&n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,9,8,e,n.f))),n.f}function Px(n){var e;return n.i&&n.i.Vh()&&(e=u(n.i,54),n.i=u(ea(n,e),84),n.i!=e&&n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,9,7,e,n.i))),n.i}function br(n){var e;return n.b&&n.b.Db&64&&(e=n.b,n.b=u(ea(n,e),19),n.b!=e&&n.Db&4&&!(n.Db&1)&&it(n,new Ci(n,9,21,e,n.b))),n.b}function uA(n,e){var t,i,r;n.d==null?(++n.e,++n.f):(i=e.Bi(),uTe(n,n.f+1),r=(i&et)%n.d.length,t=n.d[r],!t&&(t=n.d[r]=n.dk()),t.Fc(e),++n.f)}function aZ(n,e,t){var i;return e.tk()?!1:e.Ik()!=-2?(i=e.ik(),i==null?t==null:rt(i,t)):e.qk()==n.e.Dh()&&t==null}function oA(){var n;Co(16,$zn),n=oxn(16),this.b=K(UK,Ey,302,n,0,1),this.c=K(UK,Ey,302,n,0,1),this.a=null,this.e=null,this.i=0,this.f=n-1,this.g=0}function Tl(n){mV.call(this),this.k=(Vn(),zt),this.j=(Co(6,mw),new Gc(6)),this.b=(Co(2,mw),new Gc(2)),this.d=new sD,this.f=new ZG,this.a=n}function R9e(n){var e,t;n.c.length<=1||(e=Sqn(n,(en(),ae)),b_n(n,u(e.a,17).a,u(e.b,17).a),t=Sqn(n,Wn),b_n(n,u(t.a,17).a,u(t.b,17).a))}function K9e(n,e,t){var i,r;for(r=n.a.b,i=r.c.length;i102?-1:n<=57?n-48:n<65?-1:n<=70?n-65+10:n<97?-1:n-97+10}function Nx(n,e){if(n==null)throw M(new fp("null key in entry: null="+e));if(e==null)throw M(new fp("null value in entry: "+n+"=null"))}function q9e(n,e){for(var t,i;n.Ob();)if(!e.Ob()||(t=n.Pb(),i=e.Pb(),!(x(t)===x(i)||t!=null&&rt(t,i))))return!1;return!e.Ob()}function TRn(n,e){var t;return t=A(T(Pi,1),Tr,28,15,[Z$(n.a[0],e),Z$(n.a[1],e),Z$(n.a[2],e)]),n.d&&(t[0]=y.Math.max(t[0],t[2]),t[2]=t[0]),t}function ARn(n,e){var t;return t=A(T(Pi,1),Tr,28,15,[$T(n.a[0],e),$T(n.a[1],e),$T(n.a[2],e)]),n.d&&(t[0]=y.Math.max(t[0],t[2]),t[2]=t[0]),t}function bZ(n,e,t){Ep(u(v(e,(cn(),Kt)),101))||(SJ(n,e,h1(e,t)),SJ(n,e,h1(e,(en(),ae))),SJ(n,e,h1(e,Xn)),Dn(),Yt(e.j,new L7n(n)))}function SRn(n){var e,t;for(n.c||sOe(n),t=new Mu,e=new C(n.a),E(e);e.a0&&(zn(0,e.length),e.charCodeAt(0)==43)?(zn(1,e.length+1),e.substr(1)):e))}function i7e(n){var e;return n==null?null:new H1((e=Fc(n,!0),e.length>0&&(zn(0,e.length),e.charCodeAt(0)==43)?(zn(1,e.length+1),e.substr(1)):e))}function gZ(n,e,t,i,r,c,s,f){var h,l;i&&(h=i.a[0],h&&gZ(n,e,t,h,r,c,s,f),qx(n,t,i.d,r,c,s,f)&&e.Fc(i),l=i.a[1],l&&gZ(n,e,t,l,r,c,s,f))}function Kg(n,e,t){try{return c0(C$(n,e,t),1)}catch(i){throw i=It(i),D(i,333)?M(new Ir(GB+n.o+"*"+n.p+zB+e+ur+t+XB)):M(i)}}function LRn(n,e,t){try{return c0(C$(n,e,t),0)}catch(i){throw i=It(i),D(i,333)?M(new Ir(GB+n.o+"*"+n.p+zB+e+ur+t+XB)):M(i)}}function NRn(n,e,t){try{return c0(C$(n,e,t),2)}catch(i){throw i=It(i),D(i,333)?M(new Ir(GB+n.o+"*"+n.p+zB+e+ur+t+XB)):M(i)}}function $Rn(n,e){if(n.g==-1)throw M(new Cu);n.Xj();try{n.d.hd(n.g,e),n.f=n.d.j}catch(t){throw t=It(t),D(t,77)?M(new Bo):M(t)}}function r7e(n){var e,t,i,r,c;for(i=new C(n.b);i.ac&&$t(e,c,null),e}function c7e(n,e){var t,i;if(i=n.gc(),e==null){for(t=0;t0&&(h+=r),l[a]=s,s+=f*(h+i)}function FRn(n){var e,t,i;for(i=n.f,n.n=K(Pi,Tr,28,i,15,1),n.d=K(Pi,Tr,28,i,15,1),e=0;e0?n.c:0),++r;n.b=i,n.d=c}function HRn(n,e){var t;return t=A(T(Pi,1),Tr,28,15,[lZ(n,(wf(),bc),e),lZ(n,Wc,e),lZ(n,wc,e)]),n.f&&(t[0]=y.Math.max(t[0],t[2]),t[2]=t[0]),t}function d7e(n,e,t){var i;try{xA(n,e+n.j,t+n.k,!1,!0)}catch(r){throw r=It(r),D(r,77)?(i=r,M(new Ir(i.g+iS+e+ur+t+")."))):M(r)}}function b7e(n,e,t){var i;try{xA(n,e+n.j,t+n.k,!0,!1)}catch(r){throw r=It(r),D(r,77)?(i=r,M(new Ir(i.g+iS+e+ur+t+")."))):M(r)}}function qRn(n){var e;kt(n,(cn(),hb))&&(e=u(v(n,hb),21),e.Hc((lw(),Qs))?(e.Mc(Qs),e.Fc(Ys)):e.Hc(Ys)&&(e.Mc(Ys),e.Fc(Qs)))}function URn(n){var e;kt(n,(cn(),hb))&&(e=u(v(n,hb),21),e.Hc((lw(),nf))?(e.Mc(nf),e.Fc(Ms)):e.Hc(Ms)&&(e.Mc(Ms),e.Fc(nf)))}function Kx(n,e,t,i){var r,c,s,f;return n.a==null&&gje(n,e),s=e.b.j.c.length,c=t.d.p,f=i.d.p,r=f-1,r<0&&(r=s-1),c<=r?n.a[r]-n.a[c]:n.a[s-1]-n.a[c]+n.a[r]}function w7e(n){var e,t;if(!n.b)for(n.b=RM(u(n.f,27).kh().i),t=new ne(u(n.f,27).kh());t.e!=t.i.gc();)e=u(ue(t),135),nn(n.b,new pD(e));return n.b}function g7e(n){var e,t;if(!n.e)for(n.e=RM(mN(u(n.f,27)).i),t=new ne(mN(u(n.f,27)));t.e!=t.i.gc();)e=u(ue(t),123),nn(n.e,new Fkn(e));return n.e}function GRn(n){var e,t;if(!n.a)for(n.a=RM(TM(u(n.f,27)).i),t=new ne(TM(u(n.f,27)));t.e!=t.i.gc();)e=u(ue(t),27),nn(n.a,new ML(n,e));return n.a}function B0(n){var e;if(!n.C&&(n.D!=null||n.B!=null))if(e=iDe(n),e)n.hl(e);else try{n.hl(null)}catch(t){if(t=It(t),!D(t,63))throw M(t)}return n.C}function p7e(n){switch(n.q.g){case 5:wKn(n,(en(),Xn)),wKn(n,ae);break;case 4:mGn(n,(en(),Xn)),mGn(n,ae);break;default:k_n(n,(en(),Xn)),k_n(n,ae)}}function m7e(n){switch(n.q.g){case 5:gKn(n,(en(),Zn)),gKn(n,Wn);break;case 4:vGn(n,(en(),Zn)),vGn(n,Wn);break;default:y_n(n,(en(),Zn)),y_n(n,Wn)}}function _g(n,e){var t,i,r;for(r=new Li,i=n.Kc();i.Ob();)t=u(i.Pb(),36),Am(t,r.a,0),r.a+=t.f.a+e,r.b=y.Math.max(r.b,t.f.b);return r.b>0&&(r.b+=e),r}function hA(n,e){var t,i,r;for(r=new Li,i=n.Kc();i.Ob();)t=u(i.Pb(),36),Am(t,0,r.b),r.b+=t.f.b+e,r.a=y.Math.max(r.a,t.f.a);return r.a>0&&(r.a+=e),r}function zRn(n){var e,t,i;for(i=et,t=new C(n.a);t.a>16==6?n.Cb.Th(n,5,Ef,e):(i=br(u($n((t=u(Un(n,16),29),t||n.ii()),n.Db>>16),19)),n.Cb.Th(n,i.n,i.f,e))}function v7e(n){I4();var e=n.e;if(e&&e.stack){var t=e.stack,i=e+`
                         `;return t.substring(0,i.length)==i&&(t=t.substring(i.length)),t.split(`
                        diff --git a/assets/freedom.html-Br08NJvS.js b/assets/freedom.html-IBZ61bfy.js
                        similarity index 99%
                        rename from assets/freedom.html-Br08NJvS.js
                        rename to assets/freedom.html-IBZ61bfy.js
                        index 43e9092304..fde4e0328a 100644
                        --- a/assets/freedom.html-Br08NJvS.js
                        +++ b/assets/freedom.html-IBZ61bfy.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as u,o as p,c as l,a as e,b as o,d as s,w as n,e as a}from"./app-PDrbPfzp.js";const d={},r=a(`

                        Freedom

                        Freedom 是一个出站协议,可以用来向任意网络发送(正常的) TCP 或 UDP 数据。

                        OutboundConfigurationObject

                        {
                        +import{_ as c,r as u,o as p,c as l,a as e,b as o,d as s,w as n,e as a}from"./app-UOvWaKji.js";const d={},r=a(`

                        Freedom

                        Freedom 是一个出站协议,可以用来向任意网络发送(正常的) TCP 或 UDP 数据。

                        OutboundConfigurationObject

                        {
                           "domainStrategy": "AsIs",
                           "redirect": "127.0.0.1:3366",
                           "userLevel": 0,
                        diff --git a/assets/freedom.html-uApcqWvy.js b/assets/freedom.html-vLTb4l01.js
                        similarity index 98%
                        rename from assets/freedom.html-uApcqWvy.js
                        rename to assets/freedom.html-vLTb4l01.js
                        index 96456407d0..e93f46f86e 100644
                        --- a/assets/freedom.html-uApcqWvy.js
                        +++ b/assets/freedom.html-vLTb4l01.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as l,o as i,c as d,a as o,b as e,d as n,w as s,e as a}from"./app-PDrbPfzp.js";const u={},r=a(`

                        Freedom

                        Freedom is an outbound protocol that can be used to send (normal) TCP or UDP data to any network.

                        OutboundConfigurationObject

                        {
                        +import{_ as c,r as l,o as i,c as d,a as o,b as e,d as n,w as s,e as a}from"./app-UOvWaKji.js";const u={},r=a(`

                        Freedom

                        Freedom is an outbound protocol that can be used to send (normal) TCP or UDP data to any network.

                        OutboundConfigurationObject

                        {
                           "domainStrategy": "AsIs",
                           "redirect": "127.0.0.1:3366",
                           "userLevel": 0,
                        diff --git a/assets/ganttDiagram-9a3bba1f-Mk83ufVS.js b/assets/ganttDiagram-9a3bba1f-KGvD9HhD.js
                        similarity index 99%
                        rename from assets/ganttDiagram-9a3bba1f-Mk83ufVS.js
                        rename to assets/ganttDiagram-9a3bba1f-KGvD9HhD.js
                        index f8d143cda4..c62115c2b5 100644
                        --- a/assets/ganttDiagram-9a3bba1f-Mk83ufVS.js
                        +++ b/assets/ganttDiagram-9a3bba1f-KGvD9HhD.js
                        @@ -1,4 +1,4 @@
                        -import{av as Be,aw as Ze,ax as Xe,ay as qe,az as Dn,aA as Kt,aB as Mn,aC as ye,aD as ke,aE as nt,c as wt,s as Sn,g as _n,x as Un,y as Yn,b as Fn,a as Ln,A as En,m as An,l as qt,h as Pt,i as In,j as Wn,z as On}from"./mermaid.core-95b3ca__.js";import{b as Hn,t as Ue,c as Nn,a as Vn,l as zn}from"./linear-yB98X29G.js";import{i as Pn}from"./init-Hi12RPRh.js";import"./app-PDrbPfzp.js";function Rn(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n=i)&&(n=i)}return n}function Bn(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n>r||n===void 0&&r>=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n>i||n===void 0&&i>=i)&&(n=i)}return n}function Zn(t){return t}var Bt=1,te=2,ue=3,Rt=4,Ye=1e-6;function Xn(t){return"translate("+t+",0)"}function qn(t){return"translate(0,"+t+")"}function Gn(t){return e=>+t(e)}function jn(t,e){return e=Math.max(0,t.bandwidth()-e*2)/2,t.round()&&(e=Math.round(e)),n=>+t(n)+e}function Qn(){return!this.__axis}function Ge(t,e){var n=[],r=null,i=null,s=6,a=6,k=3,Y=typeof window<"u"&&window.devicePixelRatio>1?0:.5,g=t===Bt||t===Rt?-1:1,b=t===Rt||t===te?"x":"y",U=t===Bt||t===ue?Xn:qn;function C(v){var q=r??(e.ticks?e.ticks.apply(e,n):e.domain()),y=i??(e.tickFormat?e.tickFormat.apply(e,n):Zn),L=Math.max(s,0)+k,O=e.range(),W=+O[0]+Y,B=+O[O.length-1]+Y,Z=(e.bandwidth?jn:Gn)(e.copy(),Y),Q=v.selection?v.selection():v,x=Q.selectAll(".domain").data([null]),A=Q.selectAll(".tick").data(q,e).order(),T=A.exit(),F=A.enter().append("g").attr("class","tick"),D=A.select("line"),w=A.select("text");x=x.merge(x.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),A=A.merge(F),D=D.merge(F.append("line").attr("stroke","currentColor").attr(b+"2",g*s)),w=w.merge(F.append("text").attr("fill","currentColor").attr(b,g*L).attr("dy",t===Bt?"0em":t===ue?"0.71em":"0.32em")),v!==Q&&(x=x.transition(v),A=A.transition(v),D=D.transition(v),w=w.transition(v),T=T.transition(v).attr("opacity",Ye).attr("transform",function(o){return isFinite(o=Z(o))?U(o+Y):this.getAttribute("transform")}),F.attr("opacity",Ye).attr("transform",function(o){var d=this.parentNode.__axis;return U((d&&isFinite(d=d(o))?d:Z(o))+Y)})),T.remove(),x.attr("d",t===Rt||t===te?a?"M"+g*a+","+W+"H"+Y+"V"+B+"H"+g*a:"M"+Y+","+W+"V"+B:a?"M"+W+","+g*a+"V"+Y+"H"+B+"V"+g*a:"M"+W+","+Y+"H"+B),A.attr("opacity",1).attr("transform",function(o){return U(Z(o)+Y)}),D.attr(b+"2",g*s),w.attr(b,g*L).text(y),Q.filter(Qn).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===te?"start":t===Rt?"end":"middle"),Q.each(function(){this.__axis=Z})}return C.scale=function(v){return arguments.length?(e=v,C):e},C.ticks=function(){return n=Array.from(arguments),C},C.tickArguments=function(v){return arguments.length?(n=v==null?[]:Array.from(v),C):n.slice()},C.tickValues=function(v){return arguments.length?(r=v==null?null:Array.from(v),C):r&&r.slice()},C.tickFormat=function(v){return arguments.length?(i=v,C):i},C.tickSize=function(v){return arguments.length?(s=a=+v,C):s},C.tickSizeInner=function(v){return arguments.length?(s=+v,C):s},C.tickSizeOuter=function(v){return arguments.length?(a=+v,C):a},C.tickPadding=function(v){return arguments.length?(k=+v,C):k},C.offset=function(v){return arguments.length?(Y=+v,C):Y},C}function Jn(t){return Ge(Bt,t)}function $n(t){return Ge(ue,t)}const Kn=Math.PI/180,tr=180/Math.PI,Gt=18,je=.96422,Qe=1,Je=.82521,$e=4/29,Ct=6/29,Ke=3*Ct*Ct,er=Ct*Ct*Ct;function tn(t){if(t instanceof ot)return new ot(t.l,t.a,t.b,t.opacity);if(t instanceof ut)return en(t);t instanceof Xe||(t=Dn(t));var e=ie(t.r),n=ie(t.g),r=ie(t.b),i=ee((.2225045*e+.7168786*n+.0606169*r)/Qe),s,a;return e===n&&n===r?s=a=i:(s=ee((.4360747*e+.3850649*n+.1430804*r)/je),a=ee((.0139322*e+.0971045*n+.7141733*r)/Je)),new ot(116*i-16,500*(s-i),200*(i-a),t.opacity)}function nr(t,e,n,r){return arguments.length===1?tn(t):new ot(t,e,n,r??1)}function ot(t,e,n,r){this.l=+t,this.a=+e,this.b=+n,this.opacity=+r}Be(ot,nr,Ze(qe,{brighter(t){return new ot(this.l+Gt*(t??1),this.a,this.b,this.opacity)},darker(t){return new ot(this.l-Gt*(t??1),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,n=isNaN(this.b)?t:t-this.b/200;return e=je*ne(e),t=Qe*ne(t),n=Je*ne(n),new Xe(re(3.1338561*e-1.6168667*t-.4906146*n),re(-.9787684*e+1.9161415*t+.033454*n),re(.0719453*e-.2289914*t+1.4052427*n),this.opacity)}}));function ee(t){return t>er?Math.pow(t,1/3):t/Ke+$e}function ne(t){return t>Ct?t*t*t:Ke*(t-$e)}function re(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function ie(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function rr(t){if(t instanceof ut)return new ut(t.h,t.c,t.l,t.opacity);if(t instanceof ot||(t=tn(t)),t.a===0&&t.b===0)return new ut(NaN,0(t(s=new Date(+s)),s),i.ceil=s=>(t(s=new Date(s-1)),e(s,1),t(s),s),i.round=s=>{const a=i(s),k=i.ceil(s);return s-a(e(s=new Date(+s),a==null?1:Math.floor(a)),s),i.range=(s,a,k)=>{const Y=[];if(s=i.ceil(s),k=k==null?1:Math.floor(k),!(s0))return Y;let g;do Y.push(g=new Date(+s)),e(s,k),t(s);while(gK(a=>{if(a>=a)for(;t(a),!s(a);)a.setTime(a-1)},(a,k)=>{if(a>=a)if(k<0)for(;++k<=0;)for(;e(a,-1),!s(a););else for(;--k>=0;)for(;e(a,1),!s(a););}),n&&(i.count=(s,a)=>(se.setTime(+s),ae.setTime(+a),t(se),t(ae),Math.floor(n(se,ae))),i.every=s=>(s=Math.floor(s),!isFinite(s)||!(s>0)?null:s>1?i.filter(r?a=>r(a)%s===0:a=>i.count(0,a)%s===0):i)),i}const Mt=K(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);Mt.every=t=>(t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?K(e=>{e.setTime(Math.floor(e/t)*t)},(e,n)=>{e.setTime(+e+n*t)},(e,n)=>(n-e)/t):Mt);Mt.range;const ft=1e3,rt=ft*60,ht=rt*60,dt=ht*24,pe=dt*7,Fe=dt*30,oe=dt*365,gt=K(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+e*ft)},(t,e)=>(e-t)/ft,t=>t.getUTCSeconds());gt.range;const Et=K(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*ft)},(t,e)=>{t.setTime(+t+e*rt)},(t,e)=>(e-t)/rt,t=>t.getMinutes());Et.range;const or=K(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+e*rt)},(t,e)=>(e-t)/rt,t=>t.getUTCMinutes());or.range;const At=K(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*ft-t.getMinutes()*rt)},(t,e)=>{t.setTime(+t+e*ht)},(t,e)=>(e-t)/ht,t=>t.getHours());At.range;const cr=K(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+e*ht)},(t,e)=>(e-t)/ht,t=>t.getUTCHours());cr.range;const yt=K(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*rt)/dt,t=>t.getDate()-1);yt.range;const Te=K(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/dt,t=>t.getUTCDate()-1);Te.range;const lr=K(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/dt,t=>Math.floor(t/dt));lr.range;function Tt(t){return K(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(e,n)=>{e.setDate(e.getDate()+n*7)},(e,n)=>(n-e-(n.getTimezoneOffset()-e.getTimezoneOffset())*rt)/pe)}const Ot=Tt(0),It=Tt(1),nn=Tt(2),rn=Tt(3),kt=Tt(4),sn=Tt(5),an=Tt(6);Ot.range;It.range;nn.range;rn.range;kt.range;sn.range;an.range;function vt(t){return K(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(e,n)=>{e.setUTCDate(e.getUTCDate()+n*7)},(e,n)=>(n-e)/pe)}const on=vt(0),jt=vt(1),ur=vt(2),fr=vt(3),St=vt(4),hr=vt(5),dr=vt(6);on.range;jt.range;ur.range;fr.range;St.range;hr.range;dr.range;const Wt=K(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth());Wt.range;const mr=K(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth());mr.range;const mt=K(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());mt.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:K(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,n)=>{e.setFullYear(e.getFullYear()+n*t)});mt.range;const pt=K(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());pt.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:K(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,n)=>{e.setUTCFullYear(e.getUTCFullYear()+n*t)});pt.range;function gr(t,e,n,r,i,s){const a=[[gt,1,ft],[gt,5,5*ft],[gt,15,15*ft],[gt,30,30*ft],[s,1,rt],[s,5,5*rt],[s,15,15*rt],[s,30,30*rt],[i,1,ht],[i,3,3*ht],[i,6,6*ht],[i,12,12*ht],[r,1,dt],[r,2,2*dt],[n,1,pe],[e,1,Fe],[e,3,3*Fe],[t,1,oe]];function k(g,b,U){const C=bL).right(a,C);if(v===a.length)return t.every(Ue(g/oe,b/oe,U));if(v===0)return Mt.every(Math.max(Ue(g,b,U),1));const[q,y]=a[C/a[v-1][2]53)return null;"w"in l||(l.w=1),"Z"in l?(N=le(Yt(l.y,0,1)),j=N.getUTCDay(),N=j>4||j===0?jt.ceil(N):jt(N),N=Te.offset(N,(l.V-1)*7),l.y=N.getUTCFullYear(),l.m=N.getUTCMonth(),l.d=N.getUTCDate()+(l.w+6)%7):(N=ce(Yt(l.y,0,1)),j=N.getDay(),N=j>4||j===0?It.ceil(N):It(N),N=yt.offset(N,(l.V-1)*7),l.y=N.getFullYear(),l.m=N.getMonth(),l.d=N.getDate()+(l.w+6)%7)}else("W"in l||"U"in l)&&("w"in l||(l.w="u"in l?l.u%7:"W"in l?1:0),j="Z"in l?le(Yt(l.y,0,1)).getUTCDay():ce(Yt(l.y,0,1)).getDay(),l.m=0,l.d="W"in l?(l.w+6)%7+l.W*7-(j+5)%7:l.w+l.U*7-(j+6)%7);return"Z"in l?(l.H+=l.Z/100|0,l.M+=l.Z%100,le(l)):ce(l)}}function T(p,E,M,l){for(var R=0,N=E.length,j=M.length,J,et;R=j)return-1;if(J=E.charCodeAt(R++),J===37){if(J=E.charAt(R++),et=Q[J in Le?E.charAt(R++):J],!et||(l=et(p,M,l))<0)return-1}else if(J!=M.charCodeAt(l++))return-1}return l}function F(p,E,M){var l=g.exec(E.slice(M));return l?(p.p=b.get(l[0].toLowerCase()),M+l[0].length):-1}function D(p,E,M){var l=v.exec(E.slice(M));return l?(p.w=q.get(l[0].toLowerCase()),M+l[0].length):-1}function w(p,E,M){var l=U.exec(E.slice(M));return l?(p.w=C.get(l[0].toLowerCase()),M+l[0].length):-1}function o(p,E,M){var l=O.exec(E.slice(M));return l?(p.m=W.get(l[0].toLowerCase()),M+l[0].length):-1}function d(p,E,M){var l=y.exec(E.slice(M));return l?(p.m=L.get(l[0].toLowerCase()),M+l[0].length):-1}function m(p,E,M){return T(p,e,E,M)}function u(p,E,M){return T(p,n,E,M)}function S(p,E,M){return T(p,r,E,M)}function c(p){return a[p.getDay()]}function X(p){return s[p.getDay()]}function f(p){return Y[p.getMonth()]}function h(p){return k[p.getMonth()]}function _(p){return i[+(p.getHours()>=12)]}function G(p){return 1+~~(p.getMonth()/3)}function H(p){return a[p.getUTCDay()]}function V(p){return s[p.getUTCDay()]}function I(p){return Y[p.getUTCMonth()]}function z(p){return k[p.getUTCMonth()]}function st(p){return i[+(p.getUTCHours()>=12)]}function it(p){return 1+~~(p.getUTCMonth()/3)}return{format:function(p){var E=x(p+="",B);return E.toString=function(){return p},E},parse:function(p){var E=A(p+="",!1);return E.toString=function(){return p},E},utcFormat:function(p){var E=x(p+="",Z);return E.toString=function(){return p},E},utcParse:function(p){var E=A(p+="",!0);return E.toString=function(){return p},E}}}var Le={"-":"",_:" ",0:"0"},tt=/^\s*\d+/,Tr=/^%/,vr=/[\\^$*+?|[\]().{}]/g;function P(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",s=i.length;return r+(s[e.toLowerCase(),n]))}function xr(t,e,n){var r=tt.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function wr(t,e,n){var r=tt.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function Cr(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function Dr(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function Mr(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function Ee(t,e,n){var r=tt.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function Ae(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function Sr(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function _r(t,e,n){var r=tt.exec(e.slice(n,n+1));return r?(t.q=r[0]*3-3,n+r[0].length):-1}function Ur(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Ie(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Yr(t,e,n){var r=tt.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function We(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function Fr(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function Lr(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Er(t,e,n){var r=tt.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function Ar(t,e,n){var r=tt.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Ir(t,e,n){var r=Tr.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function Wr(t,e,n){var r=tt.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function Or(t,e,n){var r=tt.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function Oe(t,e){return P(t.getDate(),e,2)}function Hr(t,e){return P(t.getHours(),e,2)}function Nr(t,e){return P(t.getHours()%12||12,e,2)}function Vr(t,e){return P(1+yt.count(mt(t),t),e,3)}function cn(t,e){return P(t.getMilliseconds(),e,3)}function zr(t,e){return cn(t,e)+"000"}function Pr(t,e){return P(t.getMonth()+1,e,2)}function Rr(t,e){return P(t.getMinutes(),e,2)}function Br(t,e){return P(t.getSeconds(),e,2)}function Zr(t){var e=t.getDay();return e===0?7:e}function Xr(t,e){return P(Ot.count(mt(t)-1,t),e,2)}function ln(t){var e=t.getDay();return e>=4||e===0?kt(t):kt.ceil(t)}function qr(t,e){return t=ln(t),P(kt.count(mt(t),t)+(mt(t).getDay()===4),e,2)}function Gr(t){return t.getDay()}function jr(t,e){return P(It.count(mt(t)-1,t),e,2)}function Qr(t,e){return P(t.getFullYear()%100,e,2)}function Jr(t,e){return t=ln(t),P(t.getFullYear()%100,e,2)}function $r(t,e){return P(t.getFullYear()%1e4,e,4)}function Kr(t,e){var n=t.getDay();return t=n>=4||n===0?kt(t):kt.ceil(t),P(t.getFullYear()%1e4,e,4)}function ti(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+P(e/60|0,"0",2)+P(e%60,"0",2)}function He(t,e){return P(t.getUTCDate(),e,2)}function ei(t,e){return P(t.getUTCHours(),e,2)}function ni(t,e){return P(t.getUTCHours()%12||12,e,2)}function ri(t,e){return P(1+Te.count(pt(t),t),e,3)}function un(t,e){return P(t.getUTCMilliseconds(),e,3)}function ii(t,e){return un(t,e)+"000"}function si(t,e){return P(t.getUTCMonth()+1,e,2)}function ai(t,e){return P(t.getUTCMinutes(),e,2)}function oi(t,e){return P(t.getUTCSeconds(),e,2)}function ci(t){var e=t.getUTCDay();return e===0?7:e}function li(t,e){return P(on.count(pt(t)-1,t),e,2)}function fn(t){var e=t.getUTCDay();return e>=4||e===0?St(t):St.ceil(t)}function ui(t,e){return t=fn(t),P(St.count(pt(t),t)+(pt(t).getUTCDay()===4),e,2)}function fi(t){return t.getUTCDay()}function hi(t,e){return P(jt.count(pt(t)-1,t),e,2)}function di(t,e){return P(t.getUTCFullYear()%100,e,2)}function mi(t,e){return t=fn(t),P(t.getUTCFullYear()%100,e,2)}function gi(t,e){return P(t.getUTCFullYear()%1e4,e,4)}function yi(t,e){var n=t.getUTCDay();return t=n>=4||n===0?St(t):St.ceil(t),P(t.getUTCFullYear()%1e4,e,4)}function ki(){return"+0000"}function Ne(){return"%"}function Ve(t){return+t}function ze(t){return Math.floor(+t/1e3)}var xt,Qt;pi({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function pi(t){return xt=pr(t),Qt=xt.format,xt.parse,xt.utcFormat,xt.utcParse,xt}function Ti(t){return new Date(t)}function vi(t){return t instanceof Date?+t:+new Date(+t)}function hn(t,e,n,r,i,s,a,k,Y,g){var b=Nn(),U=b.invert,C=b.domain,v=g(".%L"),q=g(":%S"),y=g("%I:%M"),L=g("%I %p"),O=g("%a %d"),W=g("%b %d"),B=g("%B"),Z=g("%Y");function Q(x){return(Y(x)4&&(v+=7),C.add(v,n));return q.diff(y,"week")+1},k.isoWeekday=function(g){return this.$utils().u(g)?this.day()||7:this.day(this.day()%7?g:g-7)};var Y=k.startOf;k.startOf=function(g,b){var U=this.$utils(),C=!!U.u(b)||b;return U.p(g)==="isoweek"?C?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):Y.bind(this)(g,b)}}})})(dn);var xi=dn.exports;const wi=ke(xi);var mn={exports:{}};(function(t,e){(function(n,r){t.exports=r()})(ye,function(){var n={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},r=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,i=/\d\d/,s=/\d\d?/,a=/\d*[^-_:/,()\s\d]+/,k={},Y=function(y){return(y=+y)+(y>68?1900:2e3)},g=function(y){return function(L){this[y]=+L}},b=[/[+-]\d\d:?(\d\d)?|Z/,function(y){(this.zone||(this.zone={})).offset=function(L){if(!L||L==="Z")return 0;var O=L.match(/([+-]|\d\d)/g),W=60*O[1]+(+O[2]||0);return W===0?0:O[0]==="+"?-W:W}(y)}],U=function(y){var L=k[y];return L&&(L.indexOf?L:L.s.concat(L.f))},C=function(y,L){var O,W=k.meridiem;if(W){for(var B=1;B<=24;B+=1)if(y.indexOf(W(B,0,L))>-1){O=B>12;break}}else O=y===(L?"pm":"PM");return O},v={A:[a,function(y){this.afternoon=C(y,!1)}],a:[a,function(y){this.afternoon=C(y,!0)}],S:[/\d/,function(y){this.milliseconds=100*+y}],SS:[i,function(y){this.milliseconds=10*+y}],SSS:[/\d{3}/,function(y){this.milliseconds=+y}],s:[s,g("seconds")],ss:[s,g("seconds")],m:[s,g("minutes")],mm:[s,g("minutes")],H:[s,g("hours")],h:[s,g("hours")],HH:[s,g("hours")],hh:[s,g("hours")],D:[s,g("day")],DD:[i,g("day")],Do:[a,function(y){var L=k.ordinal,O=y.match(/\d+/);if(this.day=O[0],L)for(var W=1;W<=31;W+=1)L(W).replace(/\[|\]/g,"")===y&&(this.day=W)}],M:[s,g("month")],MM:[i,g("month")],MMM:[a,function(y){var L=U("months"),O=(U("monthsShort")||L.map(function(W){return W.slice(0,3)})).indexOf(y)+1;if(O<1)throw new Error;this.month=O%12||O}],MMMM:[a,function(y){var L=U("months").indexOf(y)+1;if(L<1)throw new Error;this.month=L%12||L}],Y:[/[+-]?\d+/,g("year")],YY:[i,function(y){this.year=Y(y)}],YYYY:[/\d{4}/,g("year")],Z:b,ZZ:b};function q(y){var L,O;L=y,O=k&&k.formats;for(var W=(y=L.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(F,D,w){var o=w&&w.toUpperCase();return D||O[w]||n[w]||O[o].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(d,m,u){return m||u.slice(1)})})).match(r),B=W.length,Z=0;Z-1)return new Date((c==="X"?1e3:1)*S);var f=q(c)(S),h=f.year,_=f.month,G=f.day,H=f.hours,V=f.minutes,I=f.seconds,z=f.milliseconds,st=f.zone,it=new Date,p=G||(h||_?1:it.getDate()),E=h||it.getFullYear(),M=0;h&&!_||(M=_>0?_-1:it.getMonth());var l=H||0,R=V||0,N=I||0,j=z||0;return st?new Date(Date.UTC(E,M,p,l,R,N,j+60*st.offset*1e3)):X?new Date(Date.UTC(E,M,p,l,R,N,j)):new Date(E,M,p,l,R,N,j)}catch{return new Date("")}}(Q,T,x),this.init(),o&&o!==!0&&(this.$L=this.locale(o).$L),w&&Q!=this.format(T)&&(this.$d=new Date("")),k={}}else if(T instanceof Array)for(var d=T.length,m=1;m<=d;m+=1){A[1]=T[m-1];var u=O.apply(this,A);if(u.isValid()){this.$d=u.$d,this.$L=u.$L,this.init();break}m===d&&(this.$d=new Date(""))}else B.call(this,Z)}}})})(mn);var Ci=mn.exports;const Di=ke(Ci);var gn={exports:{}};(function(t,e){(function(n,r){t.exports=r()})(ye,function(){return function(n,r){var i=r.prototype,s=i.format;i.format=function(a){var k=this,Y=this.$locale();if(!this.isValid())return s.bind(this)(a);var g=this.$utils(),b=(a||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(U){switch(U){case"Q":return Math.ceil((k.$M+1)/3);case"Do":return Y.ordinal(k.$D);case"gggg":return k.weekYear();case"GGGG":return k.isoWeekYear();case"wo":return Y.ordinal(k.week(),"W");case"w":case"ww":return g.s(k.week(),U==="w"?1:2,"0");case"W":case"WW":return g.s(k.isoWeek(),U==="W"?1:2,"0");case"k":case"kk":return g.s(String(k.$H===0?24:k.$H),U==="k"?1:2,"0");case"X":return Math.floor(k.$d.getTime()/1e3);case"x":return k.$d.getTime();case"z":return"["+k.offsetName()+"]";case"zzz":return"["+k.offsetName("long")+"]";default:return U}});return s.bind(this)(b)}}})})(gn);var Mi=gn.exports;const Si=ke(Mi);var he=function(){var t=function(w,o,d,m){for(d=d||{},m=w.length;m--;d[w[m]]=o);return d},e=[6,8,10,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,30,32,33,35,37],n=[1,25],r=[1,26],i=[1,27],s=[1,28],a=[1,29],k=[1,30],Y=[1,31],g=[1,9],b=[1,10],U=[1,11],C=[1,12],v=[1,13],q=[1,14],y=[1,15],L=[1,16],O=[1,18],W=[1,19],B=[1,20],Z=[1,21],Q=[1,22],x=[1,24],A=[1,32],T={trace:function(){},yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,dateFormat:19,inclusiveEndDates:20,topAxis:21,axisFormat:22,tickInterval:23,excludes:24,includes:25,todayMarker:26,title:27,acc_title:28,acc_title_value:29,acc_descr:30,acc_descr_value:31,acc_descr_multiline_value:32,section:33,clickStatement:34,taskTxt:35,taskData:36,click:37,callbackname:38,callbackargs:39,href:40,clickStatementDebug:41,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",19:"dateFormat",20:"inclusiveEndDates",21:"topAxis",22:"axisFormat",23:"tickInterval",24:"excludes",25:"includes",26:"todayMarker",27:"title",28:"acc_title",29:"acc_title_value",30:"acc_descr",31:"acc_descr_value",32:"acc_descr_multiline_value",33:"section",35:"taskTxt",36:"taskData",37:"click",38:"callbackname",39:"callbackargs",40:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[34,2],[34,3],[34,3],[34,4],[34,3],[34,4],[34,2],[41,2],[41,3],[41,3],[41,4],[41,3],[41,4],[41,2]],performAction:function(o,d,m,u,S,c,X){var f=c.length-1;switch(S){case 1:return c[f-1];case 2:this.$=[];break;case 3:c[f-1].push(c[f]),this.$=c[f-1];break;case 4:case 5:this.$=c[f];break;case 6:case 7:this.$=[];break;case 8:u.setWeekday("monday");break;case 9:u.setWeekday("tuesday");break;case 10:u.setWeekday("wednesday");break;case 11:u.setWeekday("thursday");break;case 12:u.setWeekday("friday");break;case 13:u.setWeekday("saturday");break;case 14:u.setWeekday("sunday");break;case 15:u.setDateFormat(c[f].substr(11)),this.$=c[f].substr(11);break;case 16:u.enableInclusiveEndDates(),this.$=c[f].substr(18);break;case 17:u.TopAxis(),this.$=c[f].substr(8);break;case 18:u.setAxisFormat(c[f].substr(11)),this.$=c[f].substr(11);break;case 19:u.setTickInterval(c[f].substr(13)),this.$=c[f].substr(13);break;case 20:u.setExcludes(c[f].substr(9)),this.$=c[f].substr(9);break;case 21:u.setIncludes(c[f].substr(9)),this.$=c[f].substr(9);break;case 22:u.setTodayMarker(c[f].substr(12)),this.$=c[f].substr(12);break;case 24:u.setDiagramTitle(c[f].substr(6)),this.$=c[f].substr(6);break;case 25:this.$=c[f].trim(),u.setAccTitle(this.$);break;case 26:case 27:this.$=c[f].trim(),u.setAccDescription(this.$);break;case 28:u.addSection(c[f].substr(8)),this.$=c[f].substr(8);break;case 30:u.addTask(c[f-1],c[f]),this.$="task";break;case 31:this.$=c[f-1],u.setClickEvent(c[f-1],c[f],null);break;case 32:this.$=c[f-2],u.setClickEvent(c[f-2],c[f-1],c[f]);break;case 33:this.$=c[f-2],u.setClickEvent(c[f-2],c[f-1],null),u.setLink(c[f-2],c[f]);break;case 34:this.$=c[f-3],u.setClickEvent(c[f-3],c[f-2],c[f-1]),u.setLink(c[f-3],c[f]);break;case 35:this.$=c[f-2],u.setClickEvent(c[f-2],c[f],null),u.setLink(c[f-2],c[f-1]);break;case 36:this.$=c[f-3],u.setClickEvent(c[f-3],c[f-1],c[f]),u.setLink(c[f-3],c[f-2]);break;case 37:this.$=c[f-1],u.setLink(c[f-1],c[f]);break;case 38:case 44:this.$=c[f-1]+" "+c[f];break;case 39:case 40:case 42:this.$=c[f-2]+" "+c[f-1]+" "+c[f];break;case 41:case 43:this.$=c[f-3]+" "+c[f-2]+" "+c[f-1]+" "+c[f];break}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:n,13:r,14:i,15:s,16:a,17:k,18:Y,19:g,20:b,21:U,22:C,23:v,24:q,25:y,26:L,27:O,28:W,30:B,32:Z,33:Q,34:23,35:x,37:A},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:33,11:17,12:n,13:r,14:i,15:s,16:a,17:k,18:Y,19:g,20:b,21:U,22:C,23:v,24:q,25:y,26:L,27:O,28:W,30:B,32:Z,33:Q,34:23,35:x,37:A},t(e,[2,5]),t(e,[2,6]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),{29:[1,34]},{31:[1,35]},t(e,[2,27]),t(e,[2,28]),t(e,[2,29]),{36:[1,36]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),{38:[1,37],40:[1,38]},t(e,[2,4]),t(e,[2,25]),t(e,[2,26]),t(e,[2,30]),t(e,[2,31],{39:[1,39],40:[1,40]}),t(e,[2,37],{38:[1,41]}),t(e,[2,32],{40:[1,42]}),t(e,[2,33]),t(e,[2,35],{39:[1,43]}),t(e,[2,34]),t(e,[2,36])],defaultActions:{},parseError:function(o,d){if(d.recoverable)this.trace(o);else{var m=new Error(o);throw m.hash=d,m}},parse:function(o){var d=this,m=[0],u=[],S=[null],c=[],X=this.table,f="",h=0,_=0,G=2,H=1,V=c.slice.call(arguments,1),I=Object.create(this.lexer),z={yy:{}};for(var st in this.yy)Object.prototype.hasOwnProperty.call(this.yy,st)&&(z.yy[st]=this.yy[st]);I.setInput(o,z.yy),z.yy.lexer=I,z.yy.parser=this,typeof I.yylloc>"u"&&(I.yylloc={});var it=I.yylloc;c.push(it);var p=I.options&&I.options.ranges;typeof z.yy.parseError=="function"?this.parseError=z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function E(){var ct;return ct=u.pop()||I.lex()||H,typeof ct!="number"&&(ct instanceof Array&&(u=ct,ct=u.pop()),ct=d.symbols_[ct]||ct),ct}for(var M,l,R,N,j={},J,et,Ut,zt;;){if(l=m[m.length-1],this.defaultActions[l]?R=this.defaultActions[l]:((M===null||typeof M>"u")&&(M=E()),R=X[l]&&X[l][M]),typeof R>"u"||!R.length||!R[0]){var $t="";zt=[];for(J in X[l])this.terminals_[J]&&J>G&&zt.push("'"+this.terminals_[J]+"'");I.showPosition?$t="Parse error on line "+(h+1)+`:
                        +import{av as Be,aw as Ze,ax as Xe,ay as qe,az as Dn,aA as Kt,aB as Mn,aC as ye,aD as ke,aE as nt,c as wt,s as Sn,g as _n,x as Un,y as Yn,b as Fn,a as Ln,A as En,m as An,l as qt,h as Pt,i as In,j as Wn,z as On}from"./mermaid.core-Q3WVcjPF.js";import{b as Hn,t as Ue,c as Nn,a as Vn,l as zn}from"./linear-eA8J8eJ4.js";import{i as Pn}from"./init-Hi12RPRh.js";import"./app-UOvWaKji.js";function Rn(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n=i)&&(n=i)}return n}function Bn(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n>r||n===void 0&&r>=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n>i||n===void 0&&i>=i)&&(n=i)}return n}function Zn(t){return t}var Bt=1,te=2,ue=3,Rt=4,Ye=1e-6;function Xn(t){return"translate("+t+",0)"}function qn(t){return"translate(0,"+t+")"}function Gn(t){return e=>+t(e)}function jn(t,e){return e=Math.max(0,t.bandwidth()-e*2)/2,t.round()&&(e=Math.round(e)),n=>+t(n)+e}function Qn(){return!this.__axis}function Ge(t,e){var n=[],r=null,i=null,s=6,a=6,k=3,Y=typeof window<"u"&&window.devicePixelRatio>1?0:.5,g=t===Bt||t===Rt?-1:1,b=t===Rt||t===te?"x":"y",U=t===Bt||t===ue?Xn:qn;function C(v){var q=r??(e.ticks?e.ticks.apply(e,n):e.domain()),y=i??(e.tickFormat?e.tickFormat.apply(e,n):Zn),L=Math.max(s,0)+k,O=e.range(),W=+O[0]+Y,B=+O[O.length-1]+Y,Z=(e.bandwidth?jn:Gn)(e.copy(),Y),Q=v.selection?v.selection():v,x=Q.selectAll(".domain").data([null]),A=Q.selectAll(".tick").data(q,e).order(),T=A.exit(),F=A.enter().append("g").attr("class","tick"),D=A.select("line"),w=A.select("text");x=x.merge(x.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),A=A.merge(F),D=D.merge(F.append("line").attr("stroke","currentColor").attr(b+"2",g*s)),w=w.merge(F.append("text").attr("fill","currentColor").attr(b,g*L).attr("dy",t===Bt?"0em":t===ue?"0.71em":"0.32em")),v!==Q&&(x=x.transition(v),A=A.transition(v),D=D.transition(v),w=w.transition(v),T=T.transition(v).attr("opacity",Ye).attr("transform",function(o){return isFinite(o=Z(o))?U(o+Y):this.getAttribute("transform")}),F.attr("opacity",Ye).attr("transform",function(o){var d=this.parentNode.__axis;return U((d&&isFinite(d=d(o))?d:Z(o))+Y)})),T.remove(),x.attr("d",t===Rt||t===te?a?"M"+g*a+","+W+"H"+Y+"V"+B+"H"+g*a:"M"+Y+","+W+"V"+B:a?"M"+W+","+g*a+"V"+Y+"H"+B+"V"+g*a:"M"+W+","+Y+"H"+B),A.attr("opacity",1).attr("transform",function(o){return U(Z(o)+Y)}),D.attr(b+"2",g*s),w.attr(b,g*L).text(y),Q.filter(Qn).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===te?"start":t===Rt?"end":"middle"),Q.each(function(){this.__axis=Z})}return C.scale=function(v){return arguments.length?(e=v,C):e},C.ticks=function(){return n=Array.from(arguments),C},C.tickArguments=function(v){return arguments.length?(n=v==null?[]:Array.from(v),C):n.slice()},C.tickValues=function(v){return arguments.length?(r=v==null?null:Array.from(v),C):r&&r.slice()},C.tickFormat=function(v){return arguments.length?(i=v,C):i},C.tickSize=function(v){return arguments.length?(s=a=+v,C):s},C.tickSizeInner=function(v){return arguments.length?(s=+v,C):s},C.tickSizeOuter=function(v){return arguments.length?(a=+v,C):a},C.tickPadding=function(v){return arguments.length?(k=+v,C):k},C.offset=function(v){return arguments.length?(Y=+v,C):Y},C}function Jn(t){return Ge(Bt,t)}function $n(t){return Ge(ue,t)}const Kn=Math.PI/180,tr=180/Math.PI,Gt=18,je=.96422,Qe=1,Je=.82521,$e=4/29,Ct=6/29,Ke=3*Ct*Ct,er=Ct*Ct*Ct;function tn(t){if(t instanceof ot)return new ot(t.l,t.a,t.b,t.opacity);if(t instanceof ut)return en(t);t instanceof Xe||(t=Dn(t));var e=ie(t.r),n=ie(t.g),r=ie(t.b),i=ee((.2225045*e+.7168786*n+.0606169*r)/Qe),s,a;return e===n&&n===r?s=a=i:(s=ee((.4360747*e+.3850649*n+.1430804*r)/je),a=ee((.0139322*e+.0971045*n+.7141733*r)/Je)),new ot(116*i-16,500*(s-i),200*(i-a),t.opacity)}function nr(t,e,n,r){return arguments.length===1?tn(t):new ot(t,e,n,r??1)}function ot(t,e,n,r){this.l=+t,this.a=+e,this.b=+n,this.opacity=+r}Be(ot,nr,Ze(qe,{brighter(t){return new ot(this.l+Gt*(t??1),this.a,this.b,this.opacity)},darker(t){return new ot(this.l-Gt*(t??1),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,n=isNaN(this.b)?t:t-this.b/200;return e=je*ne(e),t=Qe*ne(t),n=Je*ne(n),new Xe(re(3.1338561*e-1.6168667*t-.4906146*n),re(-.9787684*e+1.9161415*t+.033454*n),re(.0719453*e-.2289914*t+1.4052427*n),this.opacity)}}));function ee(t){return t>er?Math.pow(t,1/3):t/Ke+$e}function ne(t){return t>Ct?t*t*t:Ke*(t-$e)}function re(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function ie(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function rr(t){if(t instanceof ut)return new ut(t.h,t.c,t.l,t.opacity);if(t instanceof ot||(t=tn(t)),t.a===0&&t.b===0)return new ut(NaN,0(t(s=new Date(+s)),s),i.ceil=s=>(t(s=new Date(s-1)),e(s,1),t(s),s),i.round=s=>{const a=i(s),k=i.ceil(s);return s-a(e(s=new Date(+s),a==null?1:Math.floor(a)),s),i.range=(s,a,k)=>{const Y=[];if(s=i.ceil(s),k=k==null?1:Math.floor(k),!(s0))return Y;let g;do Y.push(g=new Date(+s)),e(s,k),t(s);while(gK(a=>{if(a>=a)for(;t(a),!s(a);)a.setTime(a-1)},(a,k)=>{if(a>=a)if(k<0)for(;++k<=0;)for(;e(a,-1),!s(a););else for(;--k>=0;)for(;e(a,1),!s(a););}),n&&(i.count=(s,a)=>(se.setTime(+s),ae.setTime(+a),t(se),t(ae),Math.floor(n(se,ae))),i.every=s=>(s=Math.floor(s),!isFinite(s)||!(s>0)?null:s>1?i.filter(r?a=>r(a)%s===0:a=>i.count(0,a)%s===0):i)),i}const Mt=K(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);Mt.every=t=>(t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?K(e=>{e.setTime(Math.floor(e/t)*t)},(e,n)=>{e.setTime(+e+n*t)},(e,n)=>(n-e)/t):Mt);Mt.range;const ft=1e3,rt=ft*60,ht=rt*60,dt=ht*24,pe=dt*7,Fe=dt*30,oe=dt*365,gt=K(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+e*ft)},(t,e)=>(e-t)/ft,t=>t.getUTCSeconds());gt.range;const Et=K(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*ft)},(t,e)=>{t.setTime(+t+e*rt)},(t,e)=>(e-t)/rt,t=>t.getMinutes());Et.range;const or=K(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+e*rt)},(t,e)=>(e-t)/rt,t=>t.getUTCMinutes());or.range;const At=K(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*ft-t.getMinutes()*rt)},(t,e)=>{t.setTime(+t+e*ht)},(t,e)=>(e-t)/ht,t=>t.getHours());At.range;const cr=K(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+e*ht)},(t,e)=>(e-t)/ht,t=>t.getUTCHours());cr.range;const yt=K(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*rt)/dt,t=>t.getDate()-1);yt.range;const Te=K(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/dt,t=>t.getUTCDate()-1);Te.range;const lr=K(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/dt,t=>Math.floor(t/dt));lr.range;function Tt(t){return K(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(e,n)=>{e.setDate(e.getDate()+n*7)},(e,n)=>(n-e-(n.getTimezoneOffset()-e.getTimezoneOffset())*rt)/pe)}const Ot=Tt(0),It=Tt(1),nn=Tt(2),rn=Tt(3),kt=Tt(4),sn=Tt(5),an=Tt(6);Ot.range;It.range;nn.range;rn.range;kt.range;sn.range;an.range;function vt(t){return K(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(e,n)=>{e.setUTCDate(e.getUTCDate()+n*7)},(e,n)=>(n-e)/pe)}const on=vt(0),jt=vt(1),ur=vt(2),fr=vt(3),St=vt(4),hr=vt(5),dr=vt(6);on.range;jt.range;ur.range;fr.range;St.range;hr.range;dr.range;const Wt=K(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth());Wt.range;const mr=K(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth());mr.range;const mt=K(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());mt.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:K(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,n)=>{e.setFullYear(e.getFullYear()+n*t)});mt.range;const pt=K(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());pt.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:K(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,n)=>{e.setUTCFullYear(e.getUTCFullYear()+n*t)});pt.range;function gr(t,e,n,r,i,s){const a=[[gt,1,ft],[gt,5,5*ft],[gt,15,15*ft],[gt,30,30*ft],[s,1,rt],[s,5,5*rt],[s,15,15*rt],[s,30,30*rt],[i,1,ht],[i,3,3*ht],[i,6,6*ht],[i,12,12*ht],[r,1,dt],[r,2,2*dt],[n,1,pe],[e,1,Fe],[e,3,3*Fe],[t,1,oe]];function k(g,b,U){const C=bL).right(a,C);if(v===a.length)return t.every(Ue(g/oe,b/oe,U));if(v===0)return Mt.every(Math.max(Ue(g,b,U),1));const[q,y]=a[C/a[v-1][2]53)return null;"w"in l||(l.w=1),"Z"in l?(N=le(Yt(l.y,0,1)),j=N.getUTCDay(),N=j>4||j===0?jt.ceil(N):jt(N),N=Te.offset(N,(l.V-1)*7),l.y=N.getUTCFullYear(),l.m=N.getUTCMonth(),l.d=N.getUTCDate()+(l.w+6)%7):(N=ce(Yt(l.y,0,1)),j=N.getDay(),N=j>4||j===0?It.ceil(N):It(N),N=yt.offset(N,(l.V-1)*7),l.y=N.getFullYear(),l.m=N.getMonth(),l.d=N.getDate()+(l.w+6)%7)}else("W"in l||"U"in l)&&("w"in l||(l.w="u"in l?l.u%7:"W"in l?1:0),j="Z"in l?le(Yt(l.y,0,1)).getUTCDay():ce(Yt(l.y,0,1)).getDay(),l.m=0,l.d="W"in l?(l.w+6)%7+l.W*7-(j+5)%7:l.w+l.U*7-(j+6)%7);return"Z"in l?(l.H+=l.Z/100|0,l.M+=l.Z%100,le(l)):ce(l)}}function T(p,E,M,l){for(var R=0,N=E.length,j=M.length,J,et;R=j)return-1;if(J=E.charCodeAt(R++),J===37){if(J=E.charAt(R++),et=Q[J in Le?E.charAt(R++):J],!et||(l=et(p,M,l))<0)return-1}else if(J!=M.charCodeAt(l++))return-1}return l}function F(p,E,M){var l=g.exec(E.slice(M));return l?(p.p=b.get(l[0].toLowerCase()),M+l[0].length):-1}function D(p,E,M){var l=v.exec(E.slice(M));return l?(p.w=q.get(l[0].toLowerCase()),M+l[0].length):-1}function w(p,E,M){var l=U.exec(E.slice(M));return l?(p.w=C.get(l[0].toLowerCase()),M+l[0].length):-1}function o(p,E,M){var l=O.exec(E.slice(M));return l?(p.m=W.get(l[0].toLowerCase()),M+l[0].length):-1}function d(p,E,M){var l=y.exec(E.slice(M));return l?(p.m=L.get(l[0].toLowerCase()),M+l[0].length):-1}function m(p,E,M){return T(p,e,E,M)}function u(p,E,M){return T(p,n,E,M)}function S(p,E,M){return T(p,r,E,M)}function c(p){return a[p.getDay()]}function X(p){return s[p.getDay()]}function f(p){return Y[p.getMonth()]}function h(p){return k[p.getMonth()]}function _(p){return i[+(p.getHours()>=12)]}function G(p){return 1+~~(p.getMonth()/3)}function H(p){return a[p.getUTCDay()]}function V(p){return s[p.getUTCDay()]}function I(p){return Y[p.getUTCMonth()]}function z(p){return k[p.getUTCMonth()]}function st(p){return i[+(p.getUTCHours()>=12)]}function it(p){return 1+~~(p.getUTCMonth()/3)}return{format:function(p){var E=x(p+="",B);return E.toString=function(){return p},E},parse:function(p){var E=A(p+="",!1);return E.toString=function(){return p},E},utcFormat:function(p){var E=x(p+="",Z);return E.toString=function(){return p},E},utcParse:function(p){var E=A(p+="",!0);return E.toString=function(){return p},E}}}var Le={"-":"",_:" ",0:"0"},tt=/^\s*\d+/,Tr=/^%/,vr=/[\\^$*+?|[\]().{}]/g;function P(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",s=i.length;return r+(s[e.toLowerCase(),n]))}function xr(t,e,n){var r=tt.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function wr(t,e,n){var r=tt.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function Cr(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function Dr(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function Mr(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function Ee(t,e,n){var r=tt.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function Ae(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function Sr(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function _r(t,e,n){var r=tt.exec(e.slice(n,n+1));return r?(t.q=r[0]*3-3,n+r[0].length):-1}function Ur(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Ie(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Yr(t,e,n){var r=tt.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function We(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function Fr(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function Lr(t,e,n){var r=tt.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Er(t,e,n){var r=tt.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function Ar(t,e,n){var r=tt.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Ir(t,e,n){var r=Tr.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function Wr(t,e,n){var r=tt.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function Or(t,e,n){var r=tt.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function Oe(t,e){return P(t.getDate(),e,2)}function Hr(t,e){return P(t.getHours(),e,2)}function Nr(t,e){return P(t.getHours()%12||12,e,2)}function Vr(t,e){return P(1+yt.count(mt(t),t),e,3)}function cn(t,e){return P(t.getMilliseconds(),e,3)}function zr(t,e){return cn(t,e)+"000"}function Pr(t,e){return P(t.getMonth()+1,e,2)}function Rr(t,e){return P(t.getMinutes(),e,2)}function Br(t,e){return P(t.getSeconds(),e,2)}function Zr(t){var e=t.getDay();return e===0?7:e}function Xr(t,e){return P(Ot.count(mt(t)-1,t),e,2)}function ln(t){var e=t.getDay();return e>=4||e===0?kt(t):kt.ceil(t)}function qr(t,e){return t=ln(t),P(kt.count(mt(t),t)+(mt(t).getDay()===4),e,2)}function Gr(t){return t.getDay()}function jr(t,e){return P(It.count(mt(t)-1,t),e,2)}function Qr(t,e){return P(t.getFullYear()%100,e,2)}function Jr(t,e){return t=ln(t),P(t.getFullYear()%100,e,2)}function $r(t,e){return P(t.getFullYear()%1e4,e,4)}function Kr(t,e){var n=t.getDay();return t=n>=4||n===0?kt(t):kt.ceil(t),P(t.getFullYear()%1e4,e,4)}function ti(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+P(e/60|0,"0",2)+P(e%60,"0",2)}function He(t,e){return P(t.getUTCDate(),e,2)}function ei(t,e){return P(t.getUTCHours(),e,2)}function ni(t,e){return P(t.getUTCHours()%12||12,e,2)}function ri(t,e){return P(1+Te.count(pt(t),t),e,3)}function un(t,e){return P(t.getUTCMilliseconds(),e,3)}function ii(t,e){return un(t,e)+"000"}function si(t,e){return P(t.getUTCMonth()+1,e,2)}function ai(t,e){return P(t.getUTCMinutes(),e,2)}function oi(t,e){return P(t.getUTCSeconds(),e,2)}function ci(t){var e=t.getUTCDay();return e===0?7:e}function li(t,e){return P(on.count(pt(t)-1,t),e,2)}function fn(t){var e=t.getUTCDay();return e>=4||e===0?St(t):St.ceil(t)}function ui(t,e){return t=fn(t),P(St.count(pt(t),t)+(pt(t).getUTCDay()===4),e,2)}function fi(t){return t.getUTCDay()}function hi(t,e){return P(jt.count(pt(t)-1,t),e,2)}function di(t,e){return P(t.getUTCFullYear()%100,e,2)}function mi(t,e){return t=fn(t),P(t.getUTCFullYear()%100,e,2)}function gi(t,e){return P(t.getUTCFullYear()%1e4,e,4)}function yi(t,e){var n=t.getUTCDay();return t=n>=4||n===0?St(t):St.ceil(t),P(t.getUTCFullYear()%1e4,e,4)}function ki(){return"+0000"}function Ne(){return"%"}function Ve(t){return+t}function ze(t){return Math.floor(+t/1e3)}var xt,Qt;pi({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function pi(t){return xt=pr(t),Qt=xt.format,xt.parse,xt.utcFormat,xt.utcParse,xt}function Ti(t){return new Date(t)}function vi(t){return t instanceof Date?+t:+new Date(+t)}function hn(t,e,n,r,i,s,a,k,Y,g){var b=Nn(),U=b.invert,C=b.domain,v=g(".%L"),q=g(":%S"),y=g("%I:%M"),L=g("%I %p"),O=g("%a %d"),W=g("%b %d"),B=g("%B"),Z=g("%Y");function Q(x){return(Y(x)4&&(v+=7),C.add(v,n));return q.diff(y,"week")+1},k.isoWeekday=function(g){return this.$utils().u(g)?this.day()||7:this.day(this.day()%7?g:g-7)};var Y=k.startOf;k.startOf=function(g,b){var U=this.$utils(),C=!!U.u(b)||b;return U.p(g)==="isoweek"?C?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):Y.bind(this)(g,b)}}})})(dn);var xi=dn.exports;const wi=ke(xi);var mn={exports:{}};(function(t,e){(function(n,r){t.exports=r()})(ye,function(){var n={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},r=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,i=/\d\d/,s=/\d\d?/,a=/\d*[^-_:/,()\s\d]+/,k={},Y=function(y){return(y=+y)+(y>68?1900:2e3)},g=function(y){return function(L){this[y]=+L}},b=[/[+-]\d\d:?(\d\d)?|Z/,function(y){(this.zone||(this.zone={})).offset=function(L){if(!L||L==="Z")return 0;var O=L.match(/([+-]|\d\d)/g),W=60*O[1]+(+O[2]||0);return W===0?0:O[0]==="+"?-W:W}(y)}],U=function(y){var L=k[y];return L&&(L.indexOf?L:L.s.concat(L.f))},C=function(y,L){var O,W=k.meridiem;if(W){for(var B=1;B<=24;B+=1)if(y.indexOf(W(B,0,L))>-1){O=B>12;break}}else O=y===(L?"pm":"PM");return O},v={A:[a,function(y){this.afternoon=C(y,!1)}],a:[a,function(y){this.afternoon=C(y,!0)}],S:[/\d/,function(y){this.milliseconds=100*+y}],SS:[i,function(y){this.milliseconds=10*+y}],SSS:[/\d{3}/,function(y){this.milliseconds=+y}],s:[s,g("seconds")],ss:[s,g("seconds")],m:[s,g("minutes")],mm:[s,g("minutes")],H:[s,g("hours")],h:[s,g("hours")],HH:[s,g("hours")],hh:[s,g("hours")],D:[s,g("day")],DD:[i,g("day")],Do:[a,function(y){var L=k.ordinal,O=y.match(/\d+/);if(this.day=O[0],L)for(var W=1;W<=31;W+=1)L(W).replace(/\[|\]/g,"")===y&&(this.day=W)}],M:[s,g("month")],MM:[i,g("month")],MMM:[a,function(y){var L=U("months"),O=(U("monthsShort")||L.map(function(W){return W.slice(0,3)})).indexOf(y)+1;if(O<1)throw new Error;this.month=O%12||O}],MMMM:[a,function(y){var L=U("months").indexOf(y)+1;if(L<1)throw new Error;this.month=L%12||L}],Y:[/[+-]?\d+/,g("year")],YY:[i,function(y){this.year=Y(y)}],YYYY:[/\d{4}/,g("year")],Z:b,ZZ:b};function q(y){var L,O;L=y,O=k&&k.formats;for(var W=(y=L.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,function(F,D,w){var o=w&&w.toUpperCase();return D||O[w]||n[w]||O[o].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,function(d,m,u){return m||u.slice(1)})})).match(r),B=W.length,Z=0;Z-1)return new Date((c==="X"?1e3:1)*S);var f=q(c)(S),h=f.year,_=f.month,G=f.day,H=f.hours,V=f.minutes,I=f.seconds,z=f.milliseconds,st=f.zone,it=new Date,p=G||(h||_?1:it.getDate()),E=h||it.getFullYear(),M=0;h&&!_||(M=_>0?_-1:it.getMonth());var l=H||0,R=V||0,N=I||0,j=z||0;return st?new Date(Date.UTC(E,M,p,l,R,N,j+60*st.offset*1e3)):X?new Date(Date.UTC(E,M,p,l,R,N,j)):new Date(E,M,p,l,R,N,j)}catch{return new Date("")}}(Q,T,x),this.init(),o&&o!==!0&&(this.$L=this.locale(o).$L),w&&Q!=this.format(T)&&(this.$d=new Date("")),k={}}else if(T instanceof Array)for(var d=T.length,m=1;m<=d;m+=1){A[1]=T[m-1];var u=O.apply(this,A);if(u.isValid()){this.$d=u.$d,this.$L=u.$L,this.init();break}m===d&&(this.$d=new Date(""))}else B.call(this,Z)}}})})(mn);var Ci=mn.exports;const Di=ke(Ci);var gn={exports:{}};(function(t,e){(function(n,r){t.exports=r()})(ye,function(){return function(n,r){var i=r.prototype,s=i.format;i.format=function(a){var k=this,Y=this.$locale();if(!this.isValid())return s.bind(this)(a);var g=this.$utils(),b=(a||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,function(U){switch(U){case"Q":return Math.ceil((k.$M+1)/3);case"Do":return Y.ordinal(k.$D);case"gggg":return k.weekYear();case"GGGG":return k.isoWeekYear();case"wo":return Y.ordinal(k.week(),"W");case"w":case"ww":return g.s(k.week(),U==="w"?1:2,"0");case"W":case"WW":return g.s(k.isoWeek(),U==="W"?1:2,"0");case"k":case"kk":return g.s(String(k.$H===0?24:k.$H),U==="k"?1:2,"0");case"X":return Math.floor(k.$d.getTime()/1e3);case"x":return k.$d.getTime();case"z":return"["+k.offsetName()+"]";case"zzz":return"["+k.offsetName("long")+"]";default:return U}});return s.bind(this)(b)}}})})(gn);var Mi=gn.exports;const Si=ke(Mi);var he=function(){var t=function(w,o,d,m){for(d=d||{},m=w.length;m--;d[w[m]]=o);return d},e=[6,8,10,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,30,32,33,35,37],n=[1,25],r=[1,26],i=[1,27],s=[1,28],a=[1,29],k=[1,30],Y=[1,31],g=[1,9],b=[1,10],U=[1,11],C=[1,12],v=[1,13],q=[1,14],y=[1,15],L=[1,16],O=[1,18],W=[1,19],B=[1,20],Z=[1,21],Q=[1,22],x=[1,24],A=[1,32],T={trace:function(){},yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,dateFormat:19,inclusiveEndDates:20,topAxis:21,axisFormat:22,tickInterval:23,excludes:24,includes:25,todayMarker:26,title:27,acc_title:28,acc_title_value:29,acc_descr:30,acc_descr_value:31,acc_descr_multiline_value:32,section:33,clickStatement:34,taskTxt:35,taskData:36,click:37,callbackname:38,callbackargs:39,href:40,clickStatementDebug:41,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",19:"dateFormat",20:"inclusiveEndDates",21:"topAxis",22:"axisFormat",23:"tickInterval",24:"excludes",25:"includes",26:"todayMarker",27:"title",28:"acc_title",29:"acc_title_value",30:"acc_descr",31:"acc_descr_value",32:"acc_descr_multiline_value",33:"section",35:"taskTxt",36:"taskData",37:"click",38:"callbackname",39:"callbackargs",40:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[34,2],[34,3],[34,3],[34,4],[34,3],[34,4],[34,2],[41,2],[41,3],[41,3],[41,4],[41,3],[41,4],[41,2]],performAction:function(o,d,m,u,S,c,X){var f=c.length-1;switch(S){case 1:return c[f-1];case 2:this.$=[];break;case 3:c[f-1].push(c[f]),this.$=c[f-1];break;case 4:case 5:this.$=c[f];break;case 6:case 7:this.$=[];break;case 8:u.setWeekday("monday");break;case 9:u.setWeekday("tuesday");break;case 10:u.setWeekday("wednesday");break;case 11:u.setWeekday("thursday");break;case 12:u.setWeekday("friday");break;case 13:u.setWeekday("saturday");break;case 14:u.setWeekday("sunday");break;case 15:u.setDateFormat(c[f].substr(11)),this.$=c[f].substr(11);break;case 16:u.enableInclusiveEndDates(),this.$=c[f].substr(18);break;case 17:u.TopAxis(),this.$=c[f].substr(8);break;case 18:u.setAxisFormat(c[f].substr(11)),this.$=c[f].substr(11);break;case 19:u.setTickInterval(c[f].substr(13)),this.$=c[f].substr(13);break;case 20:u.setExcludes(c[f].substr(9)),this.$=c[f].substr(9);break;case 21:u.setIncludes(c[f].substr(9)),this.$=c[f].substr(9);break;case 22:u.setTodayMarker(c[f].substr(12)),this.$=c[f].substr(12);break;case 24:u.setDiagramTitle(c[f].substr(6)),this.$=c[f].substr(6);break;case 25:this.$=c[f].trim(),u.setAccTitle(this.$);break;case 26:case 27:this.$=c[f].trim(),u.setAccDescription(this.$);break;case 28:u.addSection(c[f].substr(8)),this.$=c[f].substr(8);break;case 30:u.addTask(c[f-1],c[f]),this.$="task";break;case 31:this.$=c[f-1],u.setClickEvent(c[f-1],c[f],null);break;case 32:this.$=c[f-2],u.setClickEvent(c[f-2],c[f-1],c[f]);break;case 33:this.$=c[f-2],u.setClickEvent(c[f-2],c[f-1],null),u.setLink(c[f-2],c[f]);break;case 34:this.$=c[f-3],u.setClickEvent(c[f-3],c[f-2],c[f-1]),u.setLink(c[f-3],c[f]);break;case 35:this.$=c[f-2],u.setClickEvent(c[f-2],c[f],null),u.setLink(c[f-2],c[f-1]);break;case 36:this.$=c[f-3],u.setClickEvent(c[f-3],c[f-1],c[f]),u.setLink(c[f-3],c[f-2]);break;case 37:this.$=c[f-1],u.setLink(c[f-1],c[f]);break;case 38:case 44:this.$=c[f-1]+" "+c[f];break;case 39:case 40:case 42:this.$=c[f-2]+" "+c[f-1]+" "+c[f];break;case 41:case 43:this.$=c[f-3]+" "+c[f-2]+" "+c[f-1]+" "+c[f];break}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:n,13:r,14:i,15:s,16:a,17:k,18:Y,19:g,20:b,21:U,22:C,23:v,24:q,25:y,26:L,27:O,28:W,30:B,32:Z,33:Q,34:23,35:x,37:A},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:33,11:17,12:n,13:r,14:i,15:s,16:a,17:k,18:Y,19:g,20:b,21:U,22:C,23:v,24:q,25:y,26:L,27:O,28:W,30:B,32:Z,33:Q,34:23,35:x,37:A},t(e,[2,5]),t(e,[2,6]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),{29:[1,34]},{31:[1,35]},t(e,[2,27]),t(e,[2,28]),t(e,[2,29]),{36:[1,36]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),{38:[1,37],40:[1,38]},t(e,[2,4]),t(e,[2,25]),t(e,[2,26]),t(e,[2,30]),t(e,[2,31],{39:[1,39],40:[1,40]}),t(e,[2,37],{38:[1,41]}),t(e,[2,32],{40:[1,42]}),t(e,[2,33]),t(e,[2,35],{39:[1,43]}),t(e,[2,34]),t(e,[2,36])],defaultActions:{},parseError:function(o,d){if(d.recoverable)this.trace(o);else{var m=new Error(o);throw m.hash=d,m}},parse:function(o){var d=this,m=[0],u=[],S=[null],c=[],X=this.table,f="",h=0,_=0,G=2,H=1,V=c.slice.call(arguments,1),I=Object.create(this.lexer),z={yy:{}};for(var st in this.yy)Object.prototype.hasOwnProperty.call(this.yy,st)&&(z.yy[st]=this.yy[st]);I.setInput(o,z.yy),z.yy.lexer=I,z.yy.parser=this,typeof I.yylloc>"u"&&(I.yylloc={});var it=I.yylloc;c.push(it);var p=I.options&&I.options.ranges;typeof z.yy.parseError=="function"?this.parseError=z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function E(){var ct;return ct=u.pop()||I.lex()||H,typeof ct!="number"&&(ct instanceof Array&&(u=ct,ct=u.pop()),ct=d.symbols_[ct]||ct),ct}for(var M,l,R,N,j={},J,et,Ut,zt;;){if(l=m[m.length-1],this.defaultActions[l]?R=this.defaultActions[l]:((M===null||typeof M>"u")&&(M=E()),R=X[l]&&X[l][M]),typeof R>"u"||!R.length||!R[0]){var $t="";zt=[];for(J in X[l])this.terminals_[J]&&J>G&&zt.push("'"+this.terminals_[J]+"'");I.showPosition?$t="Parse error on line "+(h+1)+`:
                         `+I.showPosition()+`
                         Expecting `+zt.join(", ")+", got '"+(this.terminals_[M]||M)+"'":$t="Parse error on line "+(h+1)+": Unexpected "+(M==H?"end of input":"'"+(this.terminals_[M]||M)+"'"),this.parseError($t,{text:I.match,token:this.terminals_[M]||M,line:I.yylineno,loc:it,expected:zt})}if(R[0]instanceof Array&&R.length>1)throw new Error("Parse Error: multiple actions possible at state: "+l+", token: "+M);switch(R[0]){case 1:m.push(M),S.push(I.yytext),c.push(I.yylloc),m.push(R[1]),M=null,_=I.yyleng,f=I.yytext,h=I.yylineno,it=I.yylloc;break;case 2:if(et=this.productions_[R[1]][1],j.$=S[S.length-et],j._$={first_line:c[c.length-(et||1)].first_line,last_line:c[c.length-1].last_line,first_column:c[c.length-(et||1)].first_column,last_column:c[c.length-1].last_column},p&&(j._$.range=[c[c.length-(et||1)].range[0],c[c.length-1].range[1]]),N=this.performAction.apply(j,[f,_,h,z.yy,R[1],S,c].concat(V)),typeof N<"u")return N;et&&(m=m.slice(0,-1*et*2),S=S.slice(0,-1*et),c=c.slice(0,-1*et)),m.push(this.productions_[R[1]][0]),S.push(j.$),c.push(j._$),Ut=X[m[m.length-2]][m[m.length-1]],m.push(Ut);break;case 3:return!0}}return!0}},F=function(){var w={EOF:1,parseError:function(d,m){if(this.yy.parser)this.yy.parser.parseError(d,m);else throw new Error(d)},setInput:function(o,d){return this.yy=d||this.yy||{},this._input=o,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var o=this._input[0];this.yytext+=o,this.yyleng++,this.offset++,this.match+=o,this.matched+=o;var d=o.match(/(?:\r\n?|\n).*/g);return d?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),o},unput:function(o){var d=o.length,m=o.split(/(?:\r\n?|\n)/g);this._input=o+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-d),this.offset-=d;var u=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),m.length-1&&(this.yylineno-=m.length-1);var S=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:m?(m.length===u.length?this.yylloc.first_column:0)+u[u.length-m.length].length-m[0].length:this.yylloc.first_column-d},this.options.ranges&&(this.yylloc.range=[S[0],S[0]+this.yyleng-d]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
                         `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(o){this.unput(this.match.slice(o))},pastInput:function(){var o=this.matched.substr(0,this.matched.length-this.match.length);return(o.length>20?"...":"")+o.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var o=this.match;return o.length<20&&(o+=this._input.substr(0,20-o.length)),(o.substr(0,20)+(o.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var o=this.pastInput(),d=new Array(o.length+1).join("-");return o+this.upcomingInput()+`
                        diff --git a/assets/gitGraphDiagram-96e6b4ee-Sl4MCJL1.js b/assets/gitGraphDiagram-96e6b4ee-kyRwI9Lw.js
                        similarity index 99%
                        rename from assets/gitGraphDiagram-96e6b4ee-Sl4MCJL1.js
                        rename to assets/gitGraphDiagram-96e6b4ee-kyRwI9Lw.js
                        index 54ca18ce64..9d0cd29430 100644
                        --- a/assets/gitGraphDiagram-96e6b4ee-Sl4MCJL1.js
                        +++ b/assets/gitGraphDiagram-96e6b4ee-kyRwI9Lw.js
                        @@ -1,4 +1,4 @@
                        -import{c as C,s as vt,g as Ct,a as Ot,b as Pt,x as At,y as Gt,l as B,j as D,A as St,h as It,z as Nt,at as Ht,au as Bt}from"./mermaid.core-95b3ca__.js";import"./app-PDrbPfzp.js";var mt=function(){var r=function(G,o,u,d){for(u=u||{},d=G.length;d--;u[G[d]]=o);return u},n=[1,3],l=[1,6],h=[1,4],i=[1,5],c=[2,5],p=[1,12],m=[5,7,13,19,21,23,24,26,28,31,37,40,47],x=[7,13,19,21,23,24,26,28,31,37,40],y=[7,12,13,19,21,23,24,26,28,31,37,40],a=[7,13,47],R=[1,42],_=[1,41],b=[7,13,29,32,35,38,47],f=[1,55],k=[1,56],g=[1,57],E=[7,13,32,35,42,47],z={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,GG:5,document:6,EOF:7,":":8,DIR:9,options:10,body:11,OPT:12,NL:13,line:14,statement:15,commitStatement:16,mergeStatement:17,cherryPickStatement:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,section:24,branchStatement:25,CHECKOUT:26,ref:27,BRANCH:28,ORDER:29,NUM:30,CHERRY_PICK:31,COMMIT_ID:32,STR:33,PARENT_COMMIT:34,COMMIT_TAG:35,EMPTYSTR:36,MERGE:37,COMMIT_TYPE:38,commitType:39,COMMIT:40,commit_arg:41,COMMIT_MSG:42,NORMAL:43,REVERSE:44,HIGHLIGHT:45,ID:46,";":47,$accept:0,$end:1},terminals_:{2:"error",5:"GG",7:"EOF",8:":",9:"DIR",12:"OPT",13:"NL",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"section",26:"CHECKOUT",28:"BRANCH",29:"ORDER",30:"NUM",31:"CHERRY_PICK",32:"COMMIT_ID",33:"STR",34:"PARENT_COMMIT",35:"COMMIT_TAG",36:"EMPTYSTR",37:"MERGE",38:"COMMIT_TYPE",40:"COMMIT",42:"COMMIT_MSG",43:"NORMAL",44:"REVERSE",45:"HIGHLIGHT",46:"ID",47:";"},productions_:[0,[3,2],[3,3],[3,4],[3,5],[6,0],[6,2],[10,2],[10,1],[11,0],[11,2],[14,2],[14,1],[15,1],[15,1],[15,1],[15,2],[15,2],[15,1],[15,1],[15,1],[15,2],[25,2],[25,4],[18,3],[18,5],[18,5],[18,7],[18,7],[18,5],[18,5],[18,5],[18,7],[18,7],[18,7],[18,7],[17,2],[17,4],[17,4],[17,4],[17,6],[17,6],[17,6],[17,6],[17,6],[17,6],[17,8],[17,8],[17,8],[17,8],[17,8],[17,8],[16,2],[16,3],[16,3],[16,5],[16,5],[16,3],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,3],[16,5],[16,5],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[41,0],[41,1],[39,1],[39,1],[39,1],[27,1],[27,1],[4,1],[4,1],[4,1]],performAction:function(o,u,d,s,T,t,X){var e=t.length-1;switch(T){case 2:return t[e];case 3:return t[e-1];case 4:return s.setDirection(t[e-3]),t[e-1];case 6:s.setOptions(t[e-1]),this.$=t[e];break;case 7:t[e-1]+=t[e],this.$=t[e-1];break;case 9:this.$=[];break;case 10:t[e-1].push(t[e]),this.$=t[e-1];break;case 11:this.$=t[e-1];break;case 16:this.$=t[e].trim(),s.setAccTitle(this.$);break;case 17:case 18:this.$=t[e].trim(),s.setAccDescription(this.$);break;case 19:s.addSection(t[e].substr(8)),this.$=t[e].substr(8);break;case 21:s.checkout(t[e]);break;case 22:s.branch(t[e]);break;case 23:s.branch(t[e-2],t[e]);break;case 24:s.cherryPick(t[e],"",void 0);break;case 25:s.cherryPick(t[e-2],"",void 0,t[e]);break;case 26:s.cherryPick(t[e-2],"",t[e]);break;case 27:s.cherryPick(t[e-4],"",t[e],t[e-2]);break;case 28:s.cherryPick(t[e-4],"",t[e-2],t[e]);break;case 29:s.cherryPick(t[e],"",t[e-2]);break;case 30:s.cherryPick(t[e],"","");break;case 31:s.cherryPick(t[e-2],"","");break;case 32:s.cherryPick(t[e-4],"","",t[e-2]);break;case 33:s.cherryPick(t[e-4],"","",t[e]);break;case 34:s.cherryPick(t[e-2],"",t[e-4],t[e]);break;case 35:s.cherryPick(t[e-2],"","",t[e]);break;case 36:s.merge(t[e],"","","");break;case 37:s.merge(t[e-2],t[e],"","");break;case 38:s.merge(t[e-2],"",t[e],"");break;case 39:s.merge(t[e-2],"","",t[e]);break;case 40:s.merge(t[e-4],t[e],"",t[e-2]);break;case 41:s.merge(t[e-4],"",t[e],t[e-2]);break;case 42:s.merge(t[e-4],"",t[e-2],t[e]);break;case 43:s.merge(t[e-4],t[e-2],t[e],"");break;case 44:s.merge(t[e-4],t[e-2],"",t[e]);break;case 45:s.merge(t[e-4],t[e],t[e-2],"");break;case 46:s.merge(t[e-6],t[e-4],t[e-2],t[e]);break;case 47:s.merge(t[e-6],t[e],t[e-4],t[e-2]);break;case 48:s.merge(t[e-6],t[e-4],t[e],t[e-2]);break;case 49:s.merge(t[e-6],t[e-2],t[e-4],t[e]);break;case 50:s.merge(t[e-6],t[e],t[e-2],t[e-4]);break;case 51:s.merge(t[e-6],t[e-2],t[e],t[e-4]);break;case 52:s.commit(t[e]);break;case 53:s.commit("","",s.commitType.NORMAL,t[e]);break;case 54:s.commit("","",t[e],"");break;case 55:s.commit("","",t[e],t[e-2]);break;case 56:s.commit("","",t[e-2],t[e]);break;case 57:s.commit("",t[e],s.commitType.NORMAL,"");break;case 58:s.commit("",t[e-2],s.commitType.NORMAL,t[e]);break;case 59:s.commit("",t[e],s.commitType.NORMAL,t[e-2]);break;case 60:s.commit("",t[e-2],t[e],"");break;case 61:s.commit("",t[e],t[e-2],"");break;case 62:s.commit("",t[e-4],t[e-2],t[e]);break;case 63:s.commit("",t[e-4],t[e],t[e-2]);break;case 64:s.commit("",t[e-2],t[e-4],t[e]);break;case 65:s.commit("",t[e],t[e-4],t[e-2]);break;case 66:s.commit("",t[e],t[e-2],t[e-4]);break;case 67:s.commit("",t[e-2],t[e],t[e-4]);break;case 68:s.commit(t[e],"",s.commitType.NORMAL,"");break;case 69:s.commit(t[e],"",s.commitType.NORMAL,t[e-2]);break;case 70:s.commit(t[e-2],"",s.commitType.NORMAL,t[e]);break;case 71:s.commit(t[e-2],"",t[e],"");break;case 72:s.commit(t[e],"",t[e-2],"");break;case 73:s.commit(t[e],t[e-2],s.commitType.NORMAL,"");break;case 74:s.commit(t[e-2],t[e],s.commitType.NORMAL,"");break;case 75:s.commit(t[e-4],"",t[e-2],t[e]);break;case 76:s.commit(t[e-4],"",t[e],t[e-2]);break;case 77:s.commit(t[e-2],"",t[e-4],t[e]);break;case 78:s.commit(t[e],"",t[e-4],t[e-2]);break;case 79:s.commit(t[e],"",t[e-2],t[e-4]);break;case 80:s.commit(t[e-2],"",t[e],t[e-4]);break;case 81:s.commit(t[e-4],t[e],t[e-2],"");break;case 82:s.commit(t[e-4],t[e-2],t[e],"");break;case 83:s.commit(t[e-2],t[e],t[e-4],"");break;case 84:s.commit(t[e],t[e-2],t[e-4],"");break;case 85:s.commit(t[e],t[e-4],t[e-2],"");break;case 86:s.commit(t[e-2],t[e-4],t[e],"");break;case 87:s.commit(t[e-4],t[e],s.commitType.NORMAL,t[e-2]);break;case 88:s.commit(t[e-4],t[e-2],s.commitType.NORMAL,t[e]);break;case 89:s.commit(t[e-2],t[e],s.commitType.NORMAL,t[e-4]);break;case 90:s.commit(t[e],t[e-2],s.commitType.NORMAL,t[e-4]);break;case 91:s.commit(t[e],t[e-4],s.commitType.NORMAL,t[e-2]);break;case 92:s.commit(t[e-2],t[e-4],s.commitType.NORMAL,t[e]);break;case 93:s.commit(t[e-6],t[e-4],t[e-2],t[e]);break;case 94:s.commit(t[e-6],t[e-4],t[e],t[e-2]);break;case 95:s.commit(t[e-6],t[e-2],t[e-4],t[e]);break;case 96:s.commit(t[e-6],t[e],t[e-4],t[e-2]);break;case 97:s.commit(t[e-6],t[e-2],t[e],t[e-4]);break;case 98:s.commit(t[e-6],t[e],t[e-2],t[e-4]);break;case 99:s.commit(t[e-4],t[e-6],t[e-2],t[e]);break;case 100:s.commit(t[e-4],t[e-6],t[e],t[e-2]);break;case 101:s.commit(t[e-2],t[e-6],t[e-4],t[e]);break;case 102:s.commit(t[e],t[e-6],t[e-4],t[e-2]);break;case 103:s.commit(t[e-2],t[e-6],t[e],t[e-4]);break;case 104:s.commit(t[e],t[e-6],t[e-2],t[e-4]);break;case 105:s.commit(t[e],t[e-4],t[e-2],t[e-6]);break;case 106:s.commit(t[e-2],t[e-4],t[e],t[e-6]);break;case 107:s.commit(t[e],t[e-2],t[e-4],t[e-6]);break;case 108:s.commit(t[e-2],t[e],t[e-4],t[e-6]);break;case 109:s.commit(t[e-4],t[e-2],t[e],t[e-6]);break;case 110:s.commit(t[e-4],t[e],t[e-2],t[e-6]);break;case 111:s.commit(t[e-2],t[e-4],t[e-6],t[e]);break;case 112:s.commit(t[e],t[e-4],t[e-6],t[e-2]);break;case 113:s.commit(t[e-2],t[e],t[e-6],t[e-4]);break;case 114:s.commit(t[e],t[e-2],t[e-6],t[e-4]);break;case 115:s.commit(t[e-4],t[e-2],t[e-6],t[e]);break;case 116:s.commit(t[e-4],t[e],t[e-6],t[e-2]);break;case 117:this.$="";break;case 118:this.$=t[e];break;case 119:this.$=s.commitType.NORMAL;break;case 120:this.$=s.commitType.REVERSE;break;case 121:this.$=s.commitType.HIGHLIGHT;break}},table:[{3:1,4:2,5:n,7:l,13:h,47:i},{1:[3]},{3:7,4:2,5:n,7:l,13:h,47:i},{6:8,7:c,8:[1,9],9:[1,10],10:11,13:p},r(m,[2,124]),r(m,[2,125]),r(m,[2,126]),{1:[2,1]},{7:[1,13]},{6:14,7:c,10:11,13:p},{8:[1,15]},r(x,[2,9],{11:16,12:[1,17]}),r(y,[2,8]),{1:[2,2]},{7:[1,18]},{6:19,7:c,10:11,13:p},{7:[2,6],13:[1,22],14:20,15:21,16:23,17:24,18:25,19:[1,26],21:[1,27],23:[1,28],24:[1,29],25:30,26:[1,31],28:[1,35],31:[1,34],37:[1,33],40:[1,32]},r(y,[2,7]),{1:[2,3]},{7:[1,36]},r(x,[2,10]),{4:37,7:l,13:h,47:i},r(x,[2,12]),r(a,[2,13]),r(a,[2,14]),r(a,[2,15]),{20:[1,38]},{22:[1,39]},r(a,[2,18]),r(a,[2,19]),r(a,[2,20]),{27:40,33:R,46:_},r(a,[2,117],{41:43,32:[1,46],33:[1,48],35:[1,44],38:[1,45],42:[1,47]}),{27:49,33:R,46:_},{32:[1,50],35:[1,51]},{27:52,33:R,46:_},{1:[2,4]},r(x,[2,11]),r(a,[2,16]),r(a,[2,17]),r(a,[2,21]),r(b,[2,122]),r(b,[2,123]),r(a,[2,52]),{33:[1,53]},{39:54,43:f,44:k,45:g},{33:[1,58]},{33:[1,59]},r(a,[2,118]),r(a,[2,36],{32:[1,60],35:[1,62],38:[1,61]}),{33:[1,63]},{33:[1,64],36:[1,65]},r(a,[2,22],{29:[1,66]}),r(a,[2,53],{32:[1,68],38:[1,67],42:[1,69]}),r(a,[2,54],{32:[1,71],35:[1,70],42:[1,72]}),r(E,[2,119]),r(E,[2,120]),r(E,[2,121]),r(a,[2,57],{35:[1,73],38:[1,74],42:[1,75]}),r(a,[2,68],{32:[1,78],35:[1,76],38:[1,77]}),{33:[1,79]},{39:80,43:f,44:k,45:g},{33:[1,81]},r(a,[2,24],{34:[1,82],35:[1,83]}),{32:[1,84]},{32:[1,85]},{30:[1,86]},{39:87,43:f,44:k,45:g},{33:[1,88]},{33:[1,89]},{33:[1,90]},{33:[1,91]},{33:[1,92]},{33:[1,93]},{39:94,43:f,44:k,45:g},{33:[1,95]},{33:[1,96]},{39:97,43:f,44:k,45:g},{33:[1,98]},r(a,[2,37],{35:[1,100],38:[1,99]}),r(a,[2,38],{32:[1,102],35:[1,101]}),r(a,[2,39],{32:[1,103],38:[1,104]}),{33:[1,105]},{33:[1,106],36:[1,107]},{33:[1,108]},{33:[1,109]},r(a,[2,23]),r(a,[2,55],{32:[1,110],42:[1,111]}),r(a,[2,59],{38:[1,112],42:[1,113]}),r(a,[2,69],{32:[1,115],38:[1,114]}),r(a,[2,56],{32:[1,116],42:[1,117]}),r(a,[2,61],{35:[1,118],42:[1,119]}),r(a,[2,72],{32:[1,121],35:[1,120]}),r(a,[2,58],{38:[1,122],42:[1,123]}),r(a,[2,60],{35:[1,124],42:[1,125]}),r(a,[2,73],{35:[1,127],38:[1,126]}),r(a,[2,70],{32:[1,129],38:[1,128]}),r(a,[2,71],{32:[1,131],35:[1,130]}),r(a,[2,74],{35:[1,133],38:[1,132]}),{39:134,43:f,44:k,45:g},{33:[1,135]},{33:[1,136]},{33:[1,137]},{33:[1,138]},{39:139,43:f,44:k,45:g},r(a,[2,25],{35:[1,140]}),r(a,[2,26],{34:[1,141]}),r(a,[2,31],{34:[1,142]}),r(a,[2,29],{34:[1,143]}),r(a,[2,30],{34:[1,144]}),{33:[1,145]},{33:[1,146]},{39:147,43:f,44:k,45:g},{33:[1,148]},{39:149,43:f,44:k,45:g},{33:[1,150]},{33:[1,151]},{33:[1,152]},{33:[1,153]},{33:[1,154]},{33:[1,155]},{33:[1,156]},{39:157,43:f,44:k,45:g},{33:[1,158]},{33:[1,159]},{33:[1,160]},{39:161,43:f,44:k,45:g},{33:[1,162]},{39:163,43:f,44:k,45:g},{33:[1,164]},{33:[1,165]},{33:[1,166]},{39:167,43:f,44:k,45:g},{33:[1,168]},r(a,[2,43],{35:[1,169]}),r(a,[2,44],{38:[1,170]}),r(a,[2,42],{32:[1,171]}),r(a,[2,45],{35:[1,172]}),r(a,[2,40],{38:[1,173]}),r(a,[2,41],{32:[1,174]}),{33:[1,175],36:[1,176]},{33:[1,177]},{33:[1,178]},{33:[1,179]},{33:[1,180]},r(a,[2,66],{42:[1,181]}),r(a,[2,79],{32:[1,182]}),r(a,[2,67],{42:[1,183]}),r(a,[2,90],{38:[1,184]}),r(a,[2,80],{32:[1,185]}),r(a,[2,89],{38:[1,186]}),r(a,[2,65],{42:[1,187]}),r(a,[2,78],{32:[1,188]}),r(a,[2,64],{42:[1,189]}),r(a,[2,84],{35:[1,190]}),r(a,[2,77],{32:[1,191]}),r(a,[2,83],{35:[1,192]}),r(a,[2,63],{42:[1,193]}),r(a,[2,91],{38:[1,194]}),r(a,[2,62],{42:[1,195]}),r(a,[2,85],{35:[1,196]}),r(a,[2,86],{35:[1,197]}),r(a,[2,92],{38:[1,198]}),r(a,[2,76],{32:[1,199]}),r(a,[2,87],{38:[1,200]}),r(a,[2,75],{32:[1,201]}),r(a,[2,81],{35:[1,202]}),r(a,[2,82],{35:[1,203]}),r(a,[2,88],{38:[1,204]}),{33:[1,205]},{39:206,43:f,44:k,45:g},{33:[1,207]},{33:[1,208]},{39:209,43:f,44:k,45:g},{33:[1,210]},r(a,[2,27]),r(a,[2,32]),r(a,[2,28]),r(a,[2,33]),r(a,[2,34]),r(a,[2,35]),{33:[1,211]},{33:[1,212]},{33:[1,213]},{39:214,43:f,44:k,45:g},{33:[1,215]},{39:216,43:f,44:k,45:g},{33:[1,217]},{33:[1,218]},{33:[1,219]},{33:[1,220]},{33:[1,221]},{33:[1,222]},{33:[1,223]},{39:224,43:f,44:k,45:g},{33:[1,225]},{33:[1,226]},{33:[1,227]},{39:228,43:f,44:k,45:g},{33:[1,229]},{39:230,43:f,44:k,45:g},{33:[1,231]},{33:[1,232]},{33:[1,233]},{39:234,43:f,44:k,45:g},r(a,[2,46]),r(a,[2,48]),r(a,[2,47]),r(a,[2,49]),r(a,[2,51]),r(a,[2,50]),r(a,[2,107]),r(a,[2,108]),r(a,[2,105]),r(a,[2,106]),r(a,[2,110]),r(a,[2,109]),r(a,[2,114]),r(a,[2,113]),r(a,[2,112]),r(a,[2,111]),r(a,[2,116]),r(a,[2,115]),r(a,[2,104]),r(a,[2,103]),r(a,[2,102]),r(a,[2,101]),r(a,[2,99]),r(a,[2,100]),r(a,[2,98]),r(a,[2,97]),r(a,[2,96]),r(a,[2,95]),r(a,[2,93]),r(a,[2,94])],defaultActions:{7:[2,1],13:[2,2],18:[2,3],36:[2,4]},parseError:function(o,u){if(u.recoverable)this.trace(o);else{var d=new Error(o);throw d.hash=u,d}},parse:function(o){var u=this,d=[0],s=[],T=[null],t=[],X=this.table,e="",rt=0,ft=0,wt=2,pt=1,Lt=t.slice.call(arguments,1),O=Object.create(this.lexer),F={yy:{}};for(var ct in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ct)&&(F.yy[ct]=this.yy[ct]);O.setInput(o,F.yy),F.yy.lexer=O,F.yy.parser=this,typeof O.yylloc>"u"&&(O.yylloc={});var ot=O.yylloc;t.push(ot);var Rt=O.options&&O.options.ranges;typeof F.yy.parseError=="function"?this.parseError=F.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Mt(){var q;return q=s.pop()||O.lex()||pt,typeof q!="number"&&(q instanceof Array&&(s=q,q=s.pop()),q=u.symbols_[q]||q),q}for(var N,K,V,lt,J={},it,j,bt,st;;){if(K=d[d.length-1],this.defaultActions[K]?V=this.defaultActions[K]:((N===null||typeof N>"u")&&(N=Mt()),V=X[K]&&X[K][N]),typeof V>"u"||!V.length||!V[0]){var ht="";st=[];for(it in X[K])this.terminals_[it]&&it>wt&&st.push("'"+this.terminals_[it]+"'");O.showPosition?ht="Parse error on line "+(rt+1)+`:
                        +import{c as C,s as vt,g as Ct,a as Ot,b as Pt,x as At,y as Gt,l as B,j as D,A as St,h as It,z as Nt,at as Ht,au as Bt}from"./mermaid.core-Q3WVcjPF.js";import"./app-UOvWaKji.js";var mt=function(){var r=function(G,o,u,d){for(u=u||{},d=G.length;d--;u[G[d]]=o);return u},n=[1,3],l=[1,6],h=[1,4],i=[1,5],c=[2,5],p=[1,12],m=[5,7,13,19,21,23,24,26,28,31,37,40,47],x=[7,13,19,21,23,24,26,28,31,37,40],y=[7,12,13,19,21,23,24,26,28,31,37,40],a=[7,13,47],R=[1,42],_=[1,41],b=[7,13,29,32,35,38,47],f=[1,55],k=[1,56],g=[1,57],E=[7,13,32,35,42,47],z={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,GG:5,document:6,EOF:7,":":8,DIR:9,options:10,body:11,OPT:12,NL:13,line:14,statement:15,commitStatement:16,mergeStatement:17,cherryPickStatement:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,section:24,branchStatement:25,CHECKOUT:26,ref:27,BRANCH:28,ORDER:29,NUM:30,CHERRY_PICK:31,COMMIT_ID:32,STR:33,PARENT_COMMIT:34,COMMIT_TAG:35,EMPTYSTR:36,MERGE:37,COMMIT_TYPE:38,commitType:39,COMMIT:40,commit_arg:41,COMMIT_MSG:42,NORMAL:43,REVERSE:44,HIGHLIGHT:45,ID:46,";":47,$accept:0,$end:1},terminals_:{2:"error",5:"GG",7:"EOF",8:":",9:"DIR",12:"OPT",13:"NL",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"section",26:"CHECKOUT",28:"BRANCH",29:"ORDER",30:"NUM",31:"CHERRY_PICK",32:"COMMIT_ID",33:"STR",34:"PARENT_COMMIT",35:"COMMIT_TAG",36:"EMPTYSTR",37:"MERGE",38:"COMMIT_TYPE",40:"COMMIT",42:"COMMIT_MSG",43:"NORMAL",44:"REVERSE",45:"HIGHLIGHT",46:"ID",47:";"},productions_:[0,[3,2],[3,3],[3,4],[3,5],[6,0],[6,2],[10,2],[10,1],[11,0],[11,2],[14,2],[14,1],[15,1],[15,1],[15,1],[15,2],[15,2],[15,1],[15,1],[15,1],[15,2],[25,2],[25,4],[18,3],[18,5],[18,5],[18,7],[18,7],[18,5],[18,5],[18,5],[18,7],[18,7],[18,7],[18,7],[17,2],[17,4],[17,4],[17,4],[17,6],[17,6],[17,6],[17,6],[17,6],[17,6],[17,8],[17,8],[17,8],[17,8],[17,8],[17,8],[16,2],[16,3],[16,3],[16,5],[16,5],[16,3],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,3],[16,5],[16,5],[16,5],[16,5],[16,5],[16,5],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,7],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[16,9],[41,0],[41,1],[39,1],[39,1],[39,1],[27,1],[27,1],[4,1],[4,1],[4,1]],performAction:function(o,u,d,s,T,t,X){var e=t.length-1;switch(T){case 2:return t[e];case 3:return t[e-1];case 4:return s.setDirection(t[e-3]),t[e-1];case 6:s.setOptions(t[e-1]),this.$=t[e];break;case 7:t[e-1]+=t[e],this.$=t[e-1];break;case 9:this.$=[];break;case 10:t[e-1].push(t[e]),this.$=t[e-1];break;case 11:this.$=t[e-1];break;case 16:this.$=t[e].trim(),s.setAccTitle(this.$);break;case 17:case 18:this.$=t[e].trim(),s.setAccDescription(this.$);break;case 19:s.addSection(t[e].substr(8)),this.$=t[e].substr(8);break;case 21:s.checkout(t[e]);break;case 22:s.branch(t[e]);break;case 23:s.branch(t[e-2],t[e]);break;case 24:s.cherryPick(t[e],"",void 0);break;case 25:s.cherryPick(t[e-2],"",void 0,t[e]);break;case 26:s.cherryPick(t[e-2],"",t[e]);break;case 27:s.cherryPick(t[e-4],"",t[e],t[e-2]);break;case 28:s.cherryPick(t[e-4],"",t[e-2],t[e]);break;case 29:s.cherryPick(t[e],"",t[e-2]);break;case 30:s.cherryPick(t[e],"","");break;case 31:s.cherryPick(t[e-2],"","");break;case 32:s.cherryPick(t[e-4],"","",t[e-2]);break;case 33:s.cherryPick(t[e-4],"","",t[e]);break;case 34:s.cherryPick(t[e-2],"",t[e-4],t[e]);break;case 35:s.cherryPick(t[e-2],"","",t[e]);break;case 36:s.merge(t[e],"","","");break;case 37:s.merge(t[e-2],t[e],"","");break;case 38:s.merge(t[e-2],"",t[e],"");break;case 39:s.merge(t[e-2],"","",t[e]);break;case 40:s.merge(t[e-4],t[e],"",t[e-2]);break;case 41:s.merge(t[e-4],"",t[e],t[e-2]);break;case 42:s.merge(t[e-4],"",t[e-2],t[e]);break;case 43:s.merge(t[e-4],t[e-2],t[e],"");break;case 44:s.merge(t[e-4],t[e-2],"",t[e]);break;case 45:s.merge(t[e-4],t[e],t[e-2],"");break;case 46:s.merge(t[e-6],t[e-4],t[e-2],t[e]);break;case 47:s.merge(t[e-6],t[e],t[e-4],t[e-2]);break;case 48:s.merge(t[e-6],t[e-4],t[e],t[e-2]);break;case 49:s.merge(t[e-6],t[e-2],t[e-4],t[e]);break;case 50:s.merge(t[e-6],t[e],t[e-2],t[e-4]);break;case 51:s.merge(t[e-6],t[e-2],t[e],t[e-4]);break;case 52:s.commit(t[e]);break;case 53:s.commit("","",s.commitType.NORMAL,t[e]);break;case 54:s.commit("","",t[e],"");break;case 55:s.commit("","",t[e],t[e-2]);break;case 56:s.commit("","",t[e-2],t[e]);break;case 57:s.commit("",t[e],s.commitType.NORMAL,"");break;case 58:s.commit("",t[e-2],s.commitType.NORMAL,t[e]);break;case 59:s.commit("",t[e],s.commitType.NORMAL,t[e-2]);break;case 60:s.commit("",t[e-2],t[e],"");break;case 61:s.commit("",t[e],t[e-2],"");break;case 62:s.commit("",t[e-4],t[e-2],t[e]);break;case 63:s.commit("",t[e-4],t[e],t[e-2]);break;case 64:s.commit("",t[e-2],t[e-4],t[e]);break;case 65:s.commit("",t[e],t[e-4],t[e-2]);break;case 66:s.commit("",t[e],t[e-2],t[e-4]);break;case 67:s.commit("",t[e-2],t[e],t[e-4]);break;case 68:s.commit(t[e],"",s.commitType.NORMAL,"");break;case 69:s.commit(t[e],"",s.commitType.NORMAL,t[e-2]);break;case 70:s.commit(t[e-2],"",s.commitType.NORMAL,t[e]);break;case 71:s.commit(t[e-2],"",t[e],"");break;case 72:s.commit(t[e],"",t[e-2],"");break;case 73:s.commit(t[e],t[e-2],s.commitType.NORMAL,"");break;case 74:s.commit(t[e-2],t[e],s.commitType.NORMAL,"");break;case 75:s.commit(t[e-4],"",t[e-2],t[e]);break;case 76:s.commit(t[e-4],"",t[e],t[e-2]);break;case 77:s.commit(t[e-2],"",t[e-4],t[e]);break;case 78:s.commit(t[e],"",t[e-4],t[e-2]);break;case 79:s.commit(t[e],"",t[e-2],t[e-4]);break;case 80:s.commit(t[e-2],"",t[e],t[e-4]);break;case 81:s.commit(t[e-4],t[e],t[e-2],"");break;case 82:s.commit(t[e-4],t[e-2],t[e],"");break;case 83:s.commit(t[e-2],t[e],t[e-4],"");break;case 84:s.commit(t[e],t[e-2],t[e-4],"");break;case 85:s.commit(t[e],t[e-4],t[e-2],"");break;case 86:s.commit(t[e-2],t[e-4],t[e],"");break;case 87:s.commit(t[e-4],t[e],s.commitType.NORMAL,t[e-2]);break;case 88:s.commit(t[e-4],t[e-2],s.commitType.NORMAL,t[e]);break;case 89:s.commit(t[e-2],t[e],s.commitType.NORMAL,t[e-4]);break;case 90:s.commit(t[e],t[e-2],s.commitType.NORMAL,t[e-4]);break;case 91:s.commit(t[e],t[e-4],s.commitType.NORMAL,t[e-2]);break;case 92:s.commit(t[e-2],t[e-4],s.commitType.NORMAL,t[e]);break;case 93:s.commit(t[e-6],t[e-4],t[e-2],t[e]);break;case 94:s.commit(t[e-6],t[e-4],t[e],t[e-2]);break;case 95:s.commit(t[e-6],t[e-2],t[e-4],t[e]);break;case 96:s.commit(t[e-6],t[e],t[e-4],t[e-2]);break;case 97:s.commit(t[e-6],t[e-2],t[e],t[e-4]);break;case 98:s.commit(t[e-6],t[e],t[e-2],t[e-4]);break;case 99:s.commit(t[e-4],t[e-6],t[e-2],t[e]);break;case 100:s.commit(t[e-4],t[e-6],t[e],t[e-2]);break;case 101:s.commit(t[e-2],t[e-6],t[e-4],t[e]);break;case 102:s.commit(t[e],t[e-6],t[e-4],t[e-2]);break;case 103:s.commit(t[e-2],t[e-6],t[e],t[e-4]);break;case 104:s.commit(t[e],t[e-6],t[e-2],t[e-4]);break;case 105:s.commit(t[e],t[e-4],t[e-2],t[e-6]);break;case 106:s.commit(t[e-2],t[e-4],t[e],t[e-6]);break;case 107:s.commit(t[e],t[e-2],t[e-4],t[e-6]);break;case 108:s.commit(t[e-2],t[e],t[e-4],t[e-6]);break;case 109:s.commit(t[e-4],t[e-2],t[e],t[e-6]);break;case 110:s.commit(t[e-4],t[e],t[e-2],t[e-6]);break;case 111:s.commit(t[e-2],t[e-4],t[e-6],t[e]);break;case 112:s.commit(t[e],t[e-4],t[e-6],t[e-2]);break;case 113:s.commit(t[e-2],t[e],t[e-6],t[e-4]);break;case 114:s.commit(t[e],t[e-2],t[e-6],t[e-4]);break;case 115:s.commit(t[e-4],t[e-2],t[e-6],t[e]);break;case 116:s.commit(t[e-4],t[e],t[e-6],t[e-2]);break;case 117:this.$="";break;case 118:this.$=t[e];break;case 119:this.$=s.commitType.NORMAL;break;case 120:this.$=s.commitType.REVERSE;break;case 121:this.$=s.commitType.HIGHLIGHT;break}},table:[{3:1,4:2,5:n,7:l,13:h,47:i},{1:[3]},{3:7,4:2,5:n,7:l,13:h,47:i},{6:8,7:c,8:[1,9],9:[1,10],10:11,13:p},r(m,[2,124]),r(m,[2,125]),r(m,[2,126]),{1:[2,1]},{7:[1,13]},{6:14,7:c,10:11,13:p},{8:[1,15]},r(x,[2,9],{11:16,12:[1,17]}),r(y,[2,8]),{1:[2,2]},{7:[1,18]},{6:19,7:c,10:11,13:p},{7:[2,6],13:[1,22],14:20,15:21,16:23,17:24,18:25,19:[1,26],21:[1,27],23:[1,28],24:[1,29],25:30,26:[1,31],28:[1,35],31:[1,34],37:[1,33],40:[1,32]},r(y,[2,7]),{1:[2,3]},{7:[1,36]},r(x,[2,10]),{4:37,7:l,13:h,47:i},r(x,[2,12]),r(a,[2,13]),r(a,[2,14]),r(a,[2,15]),{20:[1,38]},{22:[1,39]},r(a,[2,18]),r(a,[2,19]),r(a,[2,20]),{27:40,33:R,46:_},r(a,[2,117],{41:43,32:[1,46],33:[1,48],35:[1,44],38:[1,45],42:[1,47]}),{27:49,33:R,46:_},{32:[1,50],35:[1,51]},{27:52,33:R,46:_},{1:[2,4]},r(x,[2,11]),r(a,[2,16]),r(a,[2,17]),r(a,[2,21]),r(b,[2,122]),r(b,[2,123]),r(a,[2,52]),{33:[1,53]},{39:54,43:f,44:k,45:g},{33:[1,58]},{33:[1,59]},r(a,[2,118]),r(a,[2,36],{32:[1,60],35:[1,62],38:[1,61]}),{33:[1,63]},{33:[1,64],36:[1,65]},r(a,[2,22],{29:[1,66]}),r(a,[2,53],{32:[1,68],38:[1,67],42:[1,69]}),r(a,[2,54],{32:[1,71],35:[1,70],42:[1,72]}),r(E,[2,119]),r(E,[2,120]),r(E,[2,121]),r(a,[2,57],{35:[1,73],38:[1,74],42:[1,75]}),r(a,[2,68],{32:[1,78],35:[1,76],38:[1,77]}),{33:[1,79]},{39:80,43:f,44:k,45:g},{33:[1,81]},r(a,[2,24],{34:[1,82],35:[1,83]}),{32:[1,84]},{32:[1,85]},{30:[1,86]},{39:87,43:f,44:k,45:g},{33:[1,88]},{33:[1,89]},{33:[1,90]},{33:[1,91]},{33:[1,92]},{33:[1,93]},{39:94,43:f,44:k,45:g},{33:[1,95]},{33:[1,96]},{39:97,43:f,44:k,45:g},{33:[1,98]},r(a,[2,37],{35:[1,100],38:[1,99]}),r(a,[2,38],{32:[1,102],35:[1,101]}),r(a,[2,39],{32:[1,103],38:[1,104]}),{33:[1,105]},{33:[1,106],36:[1,107]},{33:[1,108]},{33:[1,109]},r(a,[2,23]),r(a,[2,55],{32:[1,110],42:[1,111]}),r(a,[2,59],{38:[1,112],42:[1,113]}),r(a,[2,69],{32:[1,115],38:[1,114]}),r(a,[2,56],{32:[1,116],42:[1,117]}),r(a,[2,61],{35:[1,118],42:[1,119]}),r(a,[2,72],{32:[1,121],35:[1,120]}),r(a,[2,58],{38:[1,122],42:[1,123]}),r(a,[2,60],{35:[1,124],42:[1,125]}),r(a,[2,73],{35:[1,127],38:[1,126]}),r(a,[2,70],{32:[1,129],38:[1,128]}),r(a,[2,71],{32:[1,131],35:[1,130]}),r(a,[2,74],{35:[1,133],38:[1,132]}),{39:134,43:f,44:k,45:g},{33:[1,135]},{33:[1,136]},{33:[1,137]},{33:[1,138]},{39:139,43:f,44:k,45:g},r(a,[2,25],{35:[1,140]}),r(a,[2,26],{34:[1,141]}),r(a,[2,31],{34:[1,142]}),r(a,[2,29],{34:[1,143]}),r(a,[2,30],{34:[1,144]}),{33:[1,145]},{33:[1,146]},{39:147,43:f,44:k,45:g},{33:[1,148]},{39:149,43:f,44:k,45:g},{33:[1,150]},{33:[1,151]},{33:[1,152]},{33:[1,153]},{33:[1,154]},{33:[1,155]},{33:[1,156]},{39:157,43:f,44:k,45:g},{33:[1,158]},{33:[1,159]},{33:[1,160]},{39:161,43:f,44:k,45:g},{33:[1,162]},{39:163,43:f,44:k,45:g},{33:[1,164]},{33:[1,165]},{33:[1,166]},{39:167,43:f,44:k,45:g},{33:[1,168]},r(a,[2,43],{35:[1,169]}),r(a,[2,44],{38:[1,170]}),r(a,[2,42],{32:[1,171]}),r(a,[2,45],{35:[1,172]}),r(a,[2,40],{38:[1,173]}),r(a,[2,41],{32:[1,174]}),{33:[1,175],36:[1,176]},{33:[1,177]},{33:[1,178]},{33:[1,179]},{33:[1,180]},r(a,[2,66],{42:[1,181]}),r(a,[2,79],{32:[1,182]}),r(a,[2,67],{42:[1,183]}),r(a,[2,90],{38:[1,184]}),r(a,[2,80],{32:[1,185]}),r(a,[2,89],{38:[1,186]}),r(a,[2,65],{42:[1,187]}),r(a,[2,78],{32:[1,188]}),r(a,[2,64],{42:[1,189]}),r(a,[2,84],{35:[1,190]}),r(a,[2,77],{32:[1,191]}),r(a,[2,83],{35:[1,192]}),r(a,[2,63],{42:[1,193]}),r(a,[2,91],{38:[1,194]}),r(a,[2,62],{42:[1,195]}),r(a,[2,85],{35:[1,196]}),r(a,[2,86],{35:[1,197]}),r(a,[2,92],{38:[1,198]}),r(a,[2,76],{32:[1,199]}),r(a,[2,87],{38:[1,200]}),r(a,[2,75],{32:[1,201]}),r(a,[2,81],{35:[1,202]}),r(a,[2,82],{35:[1,203]}),r(a,[2,88],{38:[1,204]}),{33:[1,205]},{39:206,43:f,44:k,45:g},{33:[1,207]},{33:[1,208]},{39:209,43:f,44:k,45:g},{33:[1,210]},r(a,[2,27]),r(a,[2,32]),r(a,[2,28]),r(a,[2,33]),r(a,[2,34]),r(a,[2,35]),{33:[1,211]},{33:[1,212]},{33:[1,213]},{39:214,43:f,44:k,45:g},{33:[1,215]},{39:216,43:f,44:k,45:g},{33:[1,217]},{33:[1,218]},{33:[1,219]},{33:[1,220]},{33:[1,221]},{33:[1,222]},{33:[1,223]},{39:224,43:f,44:k,45:g},{33:[1,225]},{33:[1,226]},{33:[1,227]},{39:228,43:f,44:k,45:g},{33:[1,229]},{39:230,43:f,44:k,45:g},{33:[1,231]},{33:[1,232]},{33:[1,233]},{39:234,43:f,44:k,45:g},r(a,[2,46]),r(a,[2,48]),r(a,[2,47]),r(a,[2,49]),r(a,[2,51]),r(a,[2,50]),r(a,[2,107]),r(a,[2,108]),r(a,[2,105]),r(a,[2,106]),r(a,[2,110]),r(a,[2,109]),r(a,[2,114]),r(a,[2,113]),r(a,[2,112]),r(a,[2,111]),r(a,[2,116]),r(a,[2,115]),r(a,[2,104]),r(a,[2,103]),r(a,[2,102]),r(a,[2,101]),r(a,[2,99]),r(a,[2,100]),r(a,[2,98]),r(a,[2,97]),r(a,[2,96]),r(a,[2,95]),r(a,[2,93]),r(a,[2,94])],defaultActions:{7:[2,1],13:[2,2],18:[2,3],36:[2,4]},parseError:function(o,u){if(u.recoverable)this.trace(o);else{var d=new Error(o);throw d.hash=u,d}},parse:function(o){var u=this,d=[0],s=[],T=[null],t=[],X=this.table,e="",rt=0,ft=0,wt=2,pt=1,Lt=t.slice.call(arguments,1),O=Object.create(this.lexer),F={yy:{}};for(var ct in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ct)&&(F.yy[ct]=this.yy[ct]);O.setInput(o,F.yy),F.yy.lexer=O,F.yy.parser=this,typeof O.yylloc>"u"&&(O.yylloc={});var ot=O.yylloc;t.push(ot);var Rt=O.options&&O.options.ranges;typeof F.yy.parseError=="function"?this.parseError=F.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Mt(){var q;return q=s.pop()||O.lex()||pt,typeof q!="number"&&(q instanceof Array&&(s=q,q=s.pop()),q=u.symbols_[q]||q),q}for(var N,K,V,lt,J={},it,j,bt,st;;){if(K=d[d.length-1],this.defaultActions[K]?V=this.defaultActions[K]:((N===null||typeof N>"u")&&(N=Mt()),V=X[K]&&X[K][N]),typeof V>"u"||!V.length||!V[0]){var ht="";st=[];for(it in X[K])this.terminals_[it]&&it>wt&&st.push("'"+this.terminals_[it]+"'");O.showPosition?ht="Parse error on line "+(rt+1)+`:
                         `+O.showPosition()+`
                         Expecting `+st.join(", ")+", got '"+(this.terminals_[N]||N)+"'":ht="Parse error on line "+(rt+1)+": Unexpected "+(N==pt?"end of input":"'"+(this.terminals_[N]||N)+"'"),this.parseError(ht,{text:O.match,token:this.terminals_[N]||N,line:O.yylineno,loc:ot,expected:st})}if(V[0]instanceof Array&&V.length>1)throw new Error("Parse Error: multiple actions possible at state: "+K+", token: "+N);switch(V[0]){case 1:d.push(N),T.push(O.yytext),t.push(O.yylloc),d.push(V[1]),N=null,ft=O.yyleng,e=O.yytext,rt=O.yylineno,ot=O.yylloc;break;case 2:if(j=this.productions_[V[1]][1],J.$=T[T.length-j],J._$={first_line:t[t.length-(j||1)].first_line,last_line:t[t.length-1].last_line,first_column:t[t.length-(j||1)].first_column,last_column:t[t.length-1].last_column},Rt&&(J._$.range=[t[t.length-(j||1)].range[0],t[t.length-1].range[1]]),lt=this.performAction.apply(J,[e,ft,rt,F.yy,V[1],T,t].concat(Lt)),typeof lt<"u")return lt;j&&(d=d.slice(0,-1*j*2),T=T.slice(0,-1*j),t=t.slice(0,-1*j)),d.push(this.productions_[V[1]][0]),T.push(J.$),t.push(J._$),bt=X[d[d.length-2]][d[d.length-1]],d.push(bt);break;case 3:return!0}}return!0}},M=function(){var G={EOF:1,parseError:function(u,d){if(this.yy.parser)this.yy.parser.parseError(u,d);else throw new Error(u)},setInput:function(o,u){return this.yy=u||this.yy||{},this._input=o,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var o=this._input[0];this.yytext+=o,this.yyleng++,this.offset++,this.match+=o,this.matched+=o;var u=o.match(/(?:\r\n?|\n).*/g);return u?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),o},unput:function(o){var u=o.length,d=o.split(/(?:\r\n?|\n)/g);this._input=o+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-u),this.offset-=u;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),d.length-1&&(this.yylineno-=d.length-1);var T=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:d?(d.length===s.length?this.yylloc.first_column:0)+s[s.length-d.length].length-d[0].length:this.yylloc.first_column-u},this.options.ranges&&(this.yylloc.range=[T[0],T[0]+this.yyleng-u]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
                         `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(o){this.unput(this.match.slice(o))},pastInput:function(){var o=this.matched.substr(0,this.matched.length-this.match.length);return(o.length>20?"...":"")+o.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var o=this.match;return o.length<20&&(o+=this._input.substr(0,20-o.length)),(o.substr(0,20)+(o.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var o=this.pastInput(),u=new Array(o.length+1).join("-");return o+this.upcomingInput()+`
                        diff --git a/assets/graph-cZfODKa1.js b/assets/graph-yVkSecXb.js
                        similarity index 99%
                        rename from assets/graph-cZfODKa1.js
                        rename to assets/graph-yVkSecXb.js
                        index 3b00e822e6..0e62386d76 100644
                        --- a/assets/graph-cZfODKa1.js
                        +++ b/assets/graph-yVkSecXb.js
                        @@ -1 +1 @@
                        -import{B as I,C as qe,S as O,D as A,E as Te,F as Xe,G as Je,H as Qe,I as Ee,J as G,K as X,L as We,M as Oe,N as ze,O as C,P as R,Q as we,R as me,T as Ve,U as Z,V as ke,W as en,X as P,Y as nn,Z as rn,_ as tn,$ as re,a0 as sn,a1 as an,a2 as un,a3 as ve,a4 as fn,a5 as B,a6 as on,a7 as dn,a8 as M,a9 as te,aa as ie}from"./mermaid.core-95b3ca__.js";var hn="[object Symbol]";function J(e){return typeof e=="symbol"||I(e)&&qe(e)==hn}function $e(e,n){for(var r=-1,t=e==null?0:e.length,i=Array(t);++r-1}function T(e){return Te(e)?Xe(e):Je(e)}var yn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Tn=/^\w*$/;function Q(e,n){if(A(e))return!1;var r=typeof e;return r=="number"||r=="symbol"||r=="boolean"||e==null||J(e)?!0:Tn.test(e)||!yn.test(e)||n!=null&&e in Object(n)}var En=500;function On(e){var n=Qe(e,function(t){return r.size===En&&r.clear(),t}),r=n.cache;return n}var wn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,mn=/\\(\\)?/g,vn=On(function(e){var n=[];return e.charCodeAt(0)===46&&n.push(""),e.replace(wn,function(r,t,i,s){n.push(i?s.replace(mn,"$1"):t||r)}),n});function $n(e){return e==null?"":Le(e)}function Ie(e,n){return A(e)?e:Q(e,n)?[e]:vn($n(e))}var Ln=1/0;function U(e){if(typeof e=="string"||J(e))return e;var n=e+"";return n=="0"&&1/e==-Ln?"-0":n}function Ce(e,n){n=Ie(n,e);for(var r=0,t=n.length;e!=null&&r0&&r(u)?n>1?Se(u,n-1,r,t,i):W(i,u):t||(i[i.length]=u)}return i}function Cn(e,n,r,t){var i=-1,s=e==null?0:e.length;for(t&&s&&(r=e[++i]);++iu))return!1;var g=s.get(e),l=s.get(n);if(g&&l)return g==n&&l==e;var o=-1,d=!0,y=r&Qr?new S:void 0;for(s.set(e,n),s.set(n,e);++o=Zt){var g=n?null:Yt(e);if(g)return V(g);a=!1,i=Ue,f=new S}else f=n?[]:u;e:for(;++t1?i.setNode(s,r):i.setNode(s)}),this}setNode(n,r){return E(this._nodes,n)?(arguments.length>1&&(this._nodes[n]=r),this):(this._nodes[n]=arguments.length>1?r:this._defaultNodeLabelFn(n),this._isCompound&&(this._parent[n]=v,this._children[n]={},this._children[v][n]=!0),this._in[n]={},this._preds[n]={},this._out[n]={},this._sucs[n]={},++this._nodeCount,this)}node(n){return this._nodes[n]}hasNode(n){return E(this._nodes,n)}removeNode(n){var r=this;if(E(this._nodes,n)){var t=function(i){r.removeEdge(r._edgeObjs[i])};delete this._nodes[n],this._isCompound&&(this._removeFromParentsChildList(n),delete this._parent[n],m(this.children(n),function(i){r.setParent(i)}),delete this._children[n]),m(T(this._in[n]),t),delete this._in[n],delete this._preds[n],m(T(this._out[n]),t),delete this._out[n],delete this._sucs[n],--this._nodeCount}return this}setParent(n,r){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if($(r))r=v;else{r+="";for(var t=r;!$(t);t=this.parent(t))if(t===n)throw new Error("Setting "+r+" as parent of "+n+" would create a cycle");this.setNode(r)}return this.setNode(n),this._removeFromParentsChildList(n),this._parent[n]=r,this._children[r][n]=!0,this}_removeFromParentsChildList(n){delete this._children[this._parent[n]][n]}parent(n){if(this._isCompound){var r=this._parent[n];if(r!==v)return r}}children(n){if($(n)&&(n=v),this._isCompound){var r=this._children[n];if(r)return T(r)}else{if(n===v)return this.nodes();if(this.hasNode(n))return[]}}predecessors(n){var r=this._preds[n];if(r)return T(r)}successors(n){var r=this._sucs[n];if(r)return T(r)}neighbors(n){var r=this.predecessors(n);if(r)return Xt(r,this.successors(n))}isLeaf(n){var r;return this.isDirected()?r=this.successors(n):r=this.neighbors(n),r.length===0}filterNodes(n){var r=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});r.setGraph(this.graph());var t=this;m(this._nodes,function(a,u){n(u)&&r.setNode(u,a)}),m(this._edgeObjs,function(a){r.hasNode(a.v)&&r.hasNode(a.w)&&r.setEdge(a,t.edge(a))});var i={};function s(a){var u=t.parent(a);return u===void 0||r.hasNode(u)?(i[a]=u,u):u in i?i[u]:s(u)}return this._isCompound&&m(r.nodes(),function(a){r.setParent(a,s(a))}),r}setDefaultEdgeLabel(n){return te(n)||(n=M(n)),this._defaultEdgeLabelFn=n,this}edgeCount(){return this._edgeCount}edges(){return H(this._edgeObjs)}setPath(n,r){var t=this,i=arguments;return Kt(n,function(s,a){return i.length>1?t.setEdge(s,a,r):t.setEdge(s,a),a}),this}setEdge(){var n,r,t,i,s=!1,a=arguments[0];typeof a=="object"&&a!==null&&"v"in a?(n=a.v,r=a.w,t=a.name,arguments.length===2&&(i=arguments[1],s=!0)):(n=a,r=arguments[1],t=arguments[3],arguments.length>2&&(i=arguments[2],s=!0)),n=""+n,r=""+r,$(t)||(t=""+t);var u=L(this._isDirected,n,r,t);if(E(this._edgeLabels,u))return s&&(this._edgeLabels[u]=i),this;if(!$(t)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(n),this.setNode(r),this._edgeLabels[u]=s?i:this._defaultEdgeLabelFn(n,r,t);var f=Qt(this._isDirected,n,r,t);return n=f.v,r=f.w,Object.freeze(f),this._edgeObjs[u]=f,Ae(this._preds[r],n),Ae(this._sucs[n],r),this._in[r][u]=f,this._out[n][u]=f,this._edgeCount++,this}edge(n,r,t){var i=arguments.length===1?Y(this._isDirected,arguments[0]):L(this._isDirected,n,r,t);return this._edgeLabels[i]}hasEdge(n,r,t){var i=arguments.length===1?Y(this._isDirected,arguments[0]):L(this._isDirected,n,r,t);return E(this._edgeLabels,i)}removeEdge(n,r,t){var i=arguments.length===1?Y(this._isDirected,arguments[0]):L(this._isDirected,n,r,t),s=this._edgeObjs[i];return s&&(n=s.v,r=s.w,delete this._edgeLabels[i],delete this._edgeObjs[i],ye(this._preds[r],n),ye(this._sucs[n],r),delete this._in[r][i],delete this._out[n][i],this._edgeCount--),this}inEdges(n,r){var t=this._in[n];if(t){var i=H(t);return r?D(i,function(s){return s.v===r}):i}}outEdges(n,r){var t=this._out[n];if(t){var i=H(t);return r?D(i,function(s){return s.w===r}):i}}nodeEdges(n,r){var t=this.inEdges(n,r);if(t)return t.concat(this.outEdges(n,r))}}Ze.prototype._nodeCount=0;Ze.prototype._edgeCount=0;function Ae(e,n){e[n]?e[n]++:e[n]=1}function ye(e,n){--e[n]||delete e[n]}function L(e,n,r,t){var i=""+n,s=""+r;if(!e&&i>s){var a=i;i=s,s=a}return i+be+s+be+($(t)?Jt:t)}function Qt(e,n,r,t){var i=""+n,s=""+r;if(!e&&i>s){var a=i;i=s,s=a}var u={v:i,w:s};return t&&(u.name=t),u}function Y(e,n){return L(e,n.v,n.w,n.name)}export{Ze as G,j as a,Se as b,Ye as c,cn as d,ee as e,m as f,$e as g,E as h,J as i,xt as j,T as k,St as l,Ie as m,Ce as n,mt as o,$n as p,$ as q,D as r,Kt as s,U as t,H as v};
                        +import{B as I,C as qe,S as O,D as A,E as Te,F as Xe,G as Je,H as Qe,I as Ee,J as G,K as X,L as We,M as Oe,N as ze,O as C,P as R,Q as we,R as me,T as Ve,U as Z,V as ke,W as en,X as P,Y as nn,Z as rn,_ as tn,$ as re,a0 as sn,a1 as an,a2 as un,a3 as ve,a4 as fn,a5 as B,a6 as on,a7 as dn,a8 as M,a9 as te,aa as ie}from"./mermaid.core-Q3WVcjPF.js";var hn="[object Symbol]";function J(e){return typeof e=="symbol"||I(e)&&qe(e)==hn}function $e(e,n){for(var r=-1,t=e==null?0:e.length,i=Array(t);++r-1}function T(e){return Te(e)?Xe(e):Je(e)}var yn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,Tn=/^\w*$/;function Q(e,n){if(A(e))return!1;var r=typeof e;return r=="number"||r=="symbol"||r=="boolean"||e==null||J(e)?!0:Tn.test(e)||!yn.test(e)||n!=null&&e in Object(n)}var En=500;function On(e){var n=Qe(e,function(t){return r.size===En&&r.clear(),t}),r=n.cache;return n}var wn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,mn=/\\(\\)?/g,vn=On(function(e){var n=[];return e.charCodeAt(0)===46&&n.push(""),e.replace(wn,function(r,t,i,s){n.push(i?s.replace(mn,"$1"):t||r)}),n});function $n(e){return e==null?"":Le(e)}function Ie(e,n){return A(e)?e:Q(e,n)?[e]:vn($n(e))}var Ln=1/0;function U(e){if(typeof e=="string"||J(e))return e;var n=e+"";return n=="0"&&1/e==-Ln?"-0":n}function Ce(e,n){n=Ie(n,e);for(var r=0,t=n.length;e!=null&&r0&&r(u)?n>1?Se(u,n-1,r,t,i):W(i,u):t||(i[i.length]=u)}return i}function Cn(e,n,r,t){var i=-1,s=e==null?0:e.length;for(t&&s&&(r=e[++i]);++iu))return!1;var g=s.get(e),l=s.get(n);if(g&&l)return g==n&&l==e;var o=-1,d=!0,y=r&Qr?new S:void 0;for(s.set(e,n),s.set(n,e);++o=Zt){var g=n?null:Yt(e);if(g)return V(g);a=!1,i=Ue,f=new S}else f=n?[]:u;e:for(;++t1?i.setNode(s,r):i.setNode(s)}),this}setNode(n,r){return E(this._nodes,n)?(arguments.length>1&&(this._nodes[n]=r),this):(this._nodes[n]=arguments.length>1?r:this._defaultNodeLabelFn(n),this._isCompound&&(this._parent[n]=v,this._children[n]={},this._children[v][n]=!0),this._in[n]={},this._preds[n]={},this._out[n]={},this._sucs[n]={},++this._nodeCount,this)}node(n){return this._nodes[n]}hasNode(n){return E(this._nodes,n)}removeNode(n){var r=this;if(E(this._nodes,n)){var t=function(i){r.removeEdge(r._edgeObjs[i])};delete this._nodes[n],this._isCompound&&(this._removeFromParentsChildList(n),delete this._parent[n],m(this.children(n),function(i){r.setParent(i)}),delete this._children[n]),m(T(this._in[n]),t),delete this._in[n],delete this._preds[n],m(T(this._out[n]),t),delete this._out[n],delete this._sucs[n],--this._nodeCount}return this}setParent(n,r){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if($(r))r=v;else{r+="";for(var t=r;!$(t);t=this.parent(t))if(t===n)throw new Error("Setting "+r+" as parent of "+n+" would create a cycle");this.setNode(r)}return this.setNode(n),this._removeFromParentsChildList(n),this._parent[n]=r,this._children[r][n]=!0,this}_removeFromParentsChildList(n){delete this._children[this._parent[n]][n]}parent(n){if(this._isCompound){var r=this._parent[n];if(r!==v)return r}}children(n){if($(n)&&(n=v),this._isCompound){var r=this._children[n];if(r)return T(r)}else{if(n===v)return this.nodes();if(this.hasNode(n))return[]}}predecessors(n){var r=this._preds[n];if(r)return T(r)}successors(n){var r=this._sucs[n];if(r)return T(r)}neighbors(n){var r=this.predecessors(n);if(r)return Xt(r,this.successors(n))}isLeaf(n){var r;return this.isDirected()?r=this.successors(n):r=this.neighbors(n),r.length===0}filterNodes(n){var r=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});r.setGraph(this.graph());var t=this;m(this._nodes,function(a,u){n(u)&&r.setNode(u,a)}),m(this._edgeObjs,function(a){r.hasNode(a.v)&&r.hasNode(a.w)&&r.setEdge(a,t.edge(a))});var i={};function s(a){var u=t.parent(a);return u===void 0||r.hasNode(u)?(i[a]=u,u):u in i?i[u]:s(u)}return this._isCompound&&m(r.nodes(),function(a){r.setParent(a,s(a))}),r}setDefaultEdgeLabel(n){return te(n)||(n=M(n)),this._defaultEdgeLabelFn=n,this}edgeCount(){return this._edgeCount}edges(){return H(this._edgeObjs)}setPath(n,r){var t=this,i=arguments;return Kt(n,function(s,a){return i.length>1?t.setEdge(s,a,r):t.setEdge(s,a),a}),this}setEdge(){var n,r,t,i,s=!1,a=arguments[0];typeof a=="object"&&a!==null&&"v"in a?(n=a.v,r=a.w,t=a.name,arguments.length===2&&(i=arguments[1],s=!0)):(n=a,r=arguments[1],t=arguments[3],arguments.length>2&&(i=arguments[2],s=!0)),n=""+n,r=""+r,$(t)||(t=""+t);var u=L(this._isDirected,n,r,t);if(E(this._edgeLabels,u))return s&&(this._edgeLabels[u]=i),this;if(!$(t)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(n),this.setNode(r),this._edgeLabels[u]=s?i:this._defaultEdgeLabelFn(n,r,t);var f=Qt(this._isDirected,n,r,t);return n=f.v,r=f.w,Object.freeze(f),this._edgeObjs[u]=f,Ae(this._preds[r],n),Ae(this._sucs[n],r),this._in[r][u]=f,this._out[n][u]=f,this._edgeCount++,this}edge(n,r,t){var i=arguments.length===1?Y(this._isDirected,arguments[0]):L(this._isDirected,n,r,t);return this._edgeLabels[i]}hasEdge(n,r,t){var i=arguments.length===1?Y(this._isDirected,arguments[0]):L(this._isDirected,n,r,t);return E(this._edgeLabels,i)}removeEdge(n,r,t){var i=arguments.length===1?Y(this._isDirected,arguments[0]):L(this._isDirected,n,r,t),s=this._edgeObjs[i];return s&&(n=s.v,r=s.w,delete this._edgeLabels[i],delete this._edgeObjs[i],ye(this._preds[r],n),ye(this._sucs[n],r),delete this._in[r][i],delete this._out[n][i],this._edgeCount--),this}inEdges(n,r){var t=this._in[n];if(t){var i=H(t);return r?D(i,function(s){return s.v===r}):i}}outEdges(n,r){var t=this._out[n];if(t){var i=H(t);return r?D(i,function(s){return s.w===r}):i}}nodeEdges(n,r){var t=this.inEdges(n,r);if(t)return t.concat(this.outEdges(n,r))}}Ze.prototype._nodeCount=0;Ze.prototype._edgeCount=0;function Ae(e,n){e[n]?e[n]++:e[n]=1}function ye(e,n){--e[n]||delete e[n]}function L(e,n,r,t){var i=""+n,s=""+r;if(!e&&i>s){var a=i;i=s,s=a}return i+be+s+be+($(t)?Jt:t)}function Qt(e,n,r,t){var i=""+n,s=""+r;if(!e&&i>s){var a=i;i=s,s=a}var u={v:i,w:s};return t&&(u.name=t),u}function Y(e,n){return L(e,n.v,n.w,n.name)}export{Ze as G,j as a,Se as b,Ye as c,cn as d,ee as e,m as f,$e as g,E as h,J as i,xt as j,T as k,St as l,Ie as m,Ce as n,mt as o,$n as p,$ as q,D as r,Kt as s,U as t,H as v};
                        diff --git a/assets/grpc.html-XKtsy_pl.js b/assets/grpc.html-m78M3EJR.js
                        similarity index 99%
                        rename from assets/grpc.html-XKtsy_pl.js
                        rename to assets/grpc.html-m78M3EJR.js
                        index fb88b09e16..7320b5b682 100644
                        --- a/assets/grpc.html-XKtsy_pl.js
                        +++ b/assets/grpc.html-m78M3EJR.js
                        @@ -1,4 +1,4 @@
                        -import{_ as s,r as n,o as a,c as i,a as e,b as c,d as r,e as t}from"./app-PDrbPfzp.js";const l={},d=t(`

                        gRPC

                        An modified transport protocol based on gRPC.

                        gRPC is based on the HTTP/2 protocol and can theoretically be relayed by other servers that support HTTP/2, such as Nginx.

                        gRPC and HTTP/2 has built-in multiplexing, so it is not recommended to enable mux.cool when using gRPC or HTTP/2.

                        ⚠⚠⚠

                        • gRPC doesn't support specifying the Host. Please enter the correct domain name in the outbound proxy address, or fill in ServerName in (x)tlsSettings, otherwise connection cannot be established.
                        • gRPC doesn't support fallback to other services.
                        • gRPC services are at risk of being actively probed. It is recommended to use reverse proxy tools such as Caddy or Nginx to perform path-based routing.

                        Tip

                        If you are using a reverse proxy such as Caddy or Nginx, please note the following:

                        • Make sure that the reverse proxy server has enabled HTTP/2.
                        • Use HTTP/2 or h2c (Caddy), grpc_pass (Nginx) to connect to Xray.
                        • The path for regular mode is /\${serviceName}/Tun, and for Multi mode it is /\${serviceName}/TunMulti.
                        • If you need to receive the client IP address, you can use the X-Real-IP header sent by Caddy / Nginx to pass the client IP.

                        Tip

                        If you are using fallback, please note the following:

                        • Fallback to gRPC is not recommended, as there is a risk of being actively probed.
                        • Please make sure that h2 is the first priority in (x)tlsSettings.alpn, otherwise gRPC (HTTP/2) may not be able to complete TLS handshake.
                        • gRPC cannot perform path-based routing by Xray.

                        GRPCObject

                        GRPCObject corresponds to the grpcSettings item.

                        {
                        +import{_ as s,r as n,o as a,c as i,a as e,b as c,d as r,e as t}from"./app-UOvWaKji.js";const l={},d=t(`

                        gRPC

                        An modified transport protocol based on gRPC.

                        gRPC is based on the HTTP/2 protocol and can theoretically be relayed by other servers that support HTTP/2, such as Nginx.

                        gRPC and HTTP/2 has built-in multiplexing, so it is not recommended to enable mux.cool when using gRPC or HTTP/2.

                        ⚠⚠⚠

                        • gRPC doesn't support specifying the Host. Please enter the correct domain name in the outbound proxy address, or fill in ServerName in (x)tlsSettings, otherwise connection cannot be established.
                        • gRPC doesn't support fallback to other services.
                        • gRPC services are at risk of being actively probed. It is recommended to use reverse proxy tools such as Caddy or Nginx to perform path-based routing.

                        Tip

                        If you are using a reverse proxy such as Caddy or Nginx, please note the following:

                        • Make sure that the reverse proxy server has enabled HTTP/2.
                        • Use HTTP/2 or h2c (Caddy), grpc_pass (Nginx) to connect to Xray.
                        • The path for regular mode is /\${serviceName}/Tun, and for Multi mode it is /\${serviceName}/TunMulti.
                        • If you need to receive the client IP address, you can use the X-Real-IP header sent by Caddy / Nginx to pass the client IP.

                        Tip

                        If you are using fallback, please note the following:

                        • Fallback to gRPC is not recommended, as there is a risk of being actively probed.
                        • Please make sure that h2 is the first priority in (x)tlsSettings.alpn, otherwise gRPC (HTTP/2) may not be able to complete TLS handshake.
                        • gRPC cannot perform path-based routing by Xray.

                        GRPCObject

                        GRPCObject corresponds to the grpcSettings item.

                        {
                           "serviceName": "name",
                           "multiMode": false,
                           "idle_timeout": 60,
                        diff --git a/assets/grpc.html-owthEglu.js b/assets/grpc.html-wuI--JNX.js
                        similarity index 99%
                        rename from assets/grpc.html-owthEglu.js
                        rename to assets/grpc.html-wuI--JNX.js
                        index 37243ecb9d..d59bf7cff3 100644
                        --- a/assets/grpc.html-owthEglu.js
                        +++ b/assets/grpc.html-wuI--JNX.js
                        @@ -1,4 +1,4 @@
                        -import{_ as e,r as n,o as a,c,a as s,b as p,d as i,e as t}from"./app-PDrbPfzp.js";const r={},l=t(`

                        gRPC

                        基于 gRPC 的传输方式。

                        它基于 HTTP/2 协议,理论上可以通过其它支持 HTTP/2 的服务器(如 Nginx)进行中转。 gRPC(HTTP/2)内置多路复用,不建议使用 gRPC 与 HTTP/2 时启用 mux.cool。

                        ⚠⚠⚠

                        • gRPC 不支持指定 Host。请在出站代理地址中填写 正确的域名 ,或在 (x)tlsSettings 中填写 ServerName,否则无法连接。
                        • gRPC 不支持回落到其他服务。
                        • gRPC 服务存在被主动探测的风险。建议使用 Caddy 或 Nginx 等反向代理工具,通过 Path 前置分流。

                        提示

                        如果您使用 Caddy 或 Nginx 等反向代理,请注意下列事项:

                        • 请确定反向代理服务器开启了 HTTP/2
                        • 请使用 HTTP/2 或 h2c (Caddy),grpc_pass (Nginx) 连接到 Xray。
                        • 普通模式的 Path 为 /\${serviceName}/Tun, Multi 模式为 /\${serviceName}/TunMulti
                        • 如果需要接收客户端 IP,可以通过由 Caddy / Nginx 发送 X-Real-IP header 来传递客户端 IP。

                        提示

                        如果你正在使用回落,请注意下列事项:

                        • 不建议回落到 gRPC,存在被主动探测的风险。
                        • 请确认h2 位于 (x)tlsSettings.alpn 中的第一顺位,否则 gRPC(HTTP/2)可能无法完成 TLS 握手。
                        • gRPC 无法通过进行 Path 分流。

                        GRPCObject

                        GRPCObject 对应传输配置的 grpcSettings 项。

                        {
                        +import{_ as e,r as n,o as a,c,a as s,b as p,d as i,e as t}from"./app-UOvWaKji.js";const r={},l=t(`

                        gRPC

                        基于 gRPC 的传输方式。

                        它基于 HTTP/2 协议,理论上可以通过其它支持 HTTP/2 的服务器(如 Nginx)进行中转。 gRPC(HTTP/2)内置多路复用,不建议使用 gRPC 与 HTTP/2 时启用 mux.cool。

                        ⚠⚠⚠

                        • gRPC 不支持指定 Host。请在出站代理地址中填写 正确的域名 ,或在 (x)tlsSettings 中填写 ServerName,否则无法连接。
                        • gRPC 不支持回落到其他服务。
                        • gRPC 服务存在被主动探测的风险。建议使用 Caddy 或 Nginx 等反向代理工具,通过 Path 前置分流。

                        提示

                        如果您使用 Caddy 或 Nginx 等反向代理,请注意下列事项:

                        • 请确定反向代理服务器开启了 HTTP/2
                        • 请使用 HTTP/2 或 h2c (Caddy),grpc_pass (Nginx) 连接到 Xray。
                        • 普通模式的 Path 为 /\${serviceName}/Tun, Multi 模式为 /\${serviceName}/TunMulti
                        • 如果需要接收客户端 IP,可以通过由 Caddy / Nginx 发送 X-Real-IP header 来传递客户端 IP。

                        提示

                        如果你正在使用回落,请注意下列事项:

                        • 不建议回落到 gRPC,存在被主动探测的风险。
                        • 请确认h2 位于 (x)tlsSettings.alpn 中的第一顺位,否则 gRPC(HTTP/2)可能无法完成 TLS 握手。
                        • gRPC 无法通过进行 Path 分流。

                        GRPCObject

                        GRPCObject 对应传输配置的 grpcSettings 项。

                        {
                           "authority": "grpc.example.com",
                           "serviceName": "name",
                           "multiMode": false,
                        diff --git a/assets/guide.html-C5_iWVEd.js b/assets/guide.html-rhDtidv8.js
                        similarity index 99%
                        rename from assets/guide.html-C5_iWVEd.js
                        rename to assets/guide.html-rhDtidv8.js
                        index 231f0fc90e..6c371d3f70 100644
                        --- a/assets/guide.html-C5_iWVEd.js
                        +++ b/assets/guide.html-rhDtidv8.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as t,o as l,c,a as e,b as o,d as n,e as r}from"./app-PDrbPfzp.js";const d={},h=r('

                        Development Standards

                        Basic

                        Version Control

                        Project X's code is hosted on GitHub:

                        ',4),u={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},p={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},f={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},m={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},g={href:"https://git-scm.com/",target:"_blank",rel:"noopener noreferrer"},b=e("h3",{id:"branch",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#branch"},[e("span",null,"Branch")])],-1),y=e("ul",null,[e("li",null,"The main branch is the backbone of this project."),e("li",null,"The main branch is also the release branch of this project."),e("li",null,"It is necessary to ensure that main can be compiled and used normally at any time."),e("li",null,"If you need to develop new features, please create a new branch for development. After development and sufficient testing, merge it back to the main branch."),e("li",null,"Please delete branches that have been merged into the main branch and are no longer necessary.")],-1),_=e("h3",{id:"release",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#release"},[e("span",null,"Release")])],-1),v=e("ul",null,[e("li",null,[o("Create two release channels: one for the beta version and another for the stable version. "),e("ul",null,[e("li",null,"The beta version, also known as the daily build, is mainly used for specific testing, experimentation, and instant feedback and improvement."),e("li",null,"The stable version, updated regularly (e.g. monthly), merges stable modifications and releases them.")])])],-1),x=e("h3",{id:"citing-other-projects",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#citing-other-projects"},[e("span",null,"Citing other projects")])],-1),w={href:"https://pkg.go.dev/search?q=golang.org%2Fx",target:"_blank",rel:"noopener noreferrer"},k=e("li",null,"If you need to reference other projects, please create an issue for discussion beforehand;",-1),P=e("li",null,[o("Other "),e("ul",null,[e("li",null,"Tools that do not violate the agreement of both parties and are helpful to the project can be used.")])],-1),X=e("h2",{id:"development-process",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#development-process"},[e("span",null,"Development Process")])],-1),C=e("h3",{id:"before-writing-code",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#before-writing-code"},[e("span",null,"Before Writing Code")])],-1),I={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},T=e("h3",{id:"modify-the-code",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#modify-the-code"},[e("span",null,"Modify the code")])],-1),j={href:"https://golang.org/doc/effective_go.html",target:"_blank",rel:"noopener noreferrer"},G=e("li",null,[o("Run "),e("code",null,"go generate core/format.go"),o(" before each push;")],-1),R=e("li",null,[o("If you need to modify protobuf, such as adding new configuration items, please run: "),e("code",null,"go generate core/proto.go"),o(";")],-1),B=e("li",null,[o("It is recommended to pass the test before submitting a pull request: "),e("code",null,"go test ./..."),o(";")],-1),S=e("li",null,"It is recommended to have more than 70% code coverage for newly added code before submitting pull requests.",-1),L=e("li",null,[o("Other "),e("ul",null,[e("li",null,"Please pay attention to the readability of the code.")])],-1),q=r(`

                        Pull Request

                        • Before submitting a PR, please run git pull https://github.com/xray/xray-core.git to ensure that the merge can proceed smoothly;
                        • One PR only does one thing. If there are fixes for multiple bugs, please submit a PR for each bug;
                        • Due to Golang's special requirements (Package path), the PR process for Go projects is different from other projects. The recommended process is as follows:
                          1. Fork this project first and create your own github.com/<your_name>/Xray-core.git repository;
                          2. Clone your own Xray repository to your local machine: git clone https://github.com/<your_name>/Xray-core.git;
                          3. Create a new branch based on the main branch, for example git branch issue24 main;
                          4. Make changes on the new branch and commit the changes;
                          5. Before pushing the modified branch to your own repository, switch to the main branch, and run git pull https://github.com/xray/xray-core.git to pull the latest remote code;
                          6. If new remote code is obtained in the previous step, switch to the branch you created earlier and run git rebase main to perform branch merging. If there is a file conflict, you need to resolve the conflict;
                          7. After the previous step is completed, you can push the branch you created to your own repository: git push -u origin your-branch
                          8. Finally, send a PR from your new pushed branch in your own repository to the main branch of xtls/Xray-core;
                          9. Please fully describe the purpose of this PR, including the problem solved, the new feature added, or the modifications made in the title and body of the PR;
                          10. Please be patient and wait for the developer's response.

                        Modifying Code

                        Functional issue

                        Please submit at least one test case to verify changes to existing functionality.

                        Please provide the necessary test data to demonstrate performance issues in existing code or performance improvements in new code.

                        New Feature

                        • If the new feature does not affect the existing functionality, please provide a toggle (such as a flag) that can be turned on/off, and keep the new feature disabled by default.
                        • For major new features (such as adding a new protocol), please submit an issue for discussion before development.

                        Other

                        It depends on the specific situation.

                        Xray Coding Guidelines

                        The following content is applicable to Golang code in Xray.

                        Code Structure

                        Xray-core
                        +import{_ as i,r as t,o as l,c,a as e,b as o,d as n,e as r}from"./app-UOvWaKji.js";const d={},h=r('

                        Development Standards

                        Basic

                        Version Control

                        Project X's code is hosted on GitHub:

                        ',4),u={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},p={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},f={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},m={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},g={href:"https://git-scm.com/",target:"_blank",rel:"noopener noreferrer"},b=e("h3",{id:"branch",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#branch"},[e("span",null,"Branch")])],-1),y=e("ul",null,[e("li",null,"The main branch is the backbone of this project."),e("li",null,"The main branch is also the release branch of this project."),e("li",null,"It is necessary to ensure that main can be compiled and used normally at any time."),e("li",null,"If you need to develop new features, please create a new branch for development. After development and sufficient testing, merge it back to the main branch."),e("li",null,"Please delete branches that have been merged into the main branch and are no longer necessary.")],-1),_=e("h3",{id:"release",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#release"},[e("span",null,"Release")])],-1),v=e("ul",null,[e("li",null,[o("Create two release channels: one for the beta version and another for the stable version. "),e("ul",null,[e("li",null,"The beta version, also known as the daily build, is mainly used for specific testing, experimentation, and instant feedback and improvement."),e("li",null,"The stable version, updated regularly (e.g. monthly), merges stable modifications and releases them.")])])],-1),x=e("h3",{id:"citing-other-projects",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#citing-other-projects"},[e("span",null,"Citing other projects")])],-1),w={href:"https://pkg.go.dev/search?q=golang.org%2Fx",target:"_blank",rel:"noopener noreferrer"},k=e("li",null,"If you need to reference other projects, please create an issue for discussion beforehand;",-1),P=e("li",null,[o("Other "),e("ul",null,[e("li",null,"Tools that do not violate the agreement of both parties and are helpful to the project can be used.")])],-1),X=e("h2",{id:"development-process",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#development-process"},[e("span",null,"Development Process")])],-1),C=e("h3",{id:"before-writing-code",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#before-writing-code"},[e("span",null,"Before Writing Code")])],-1),I={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},T=e("h3",{id:"modify-the-code",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#modify-the-code"},[e("span",null,"Modify the code")])],-1),j={href:"https://golang.org/doc/effective_go.html",target:"_blank",rel:"noopener noreferrer"},G=e("li",null,[o("Run "),e("code",null,"go generate core/format.go"),o(" before each push;")],-1),R=e("li",null,[o("If you need to modify protobuf, such as adding new configuration items, please run: "),e("code",null,"go generate core/proto.go"),o(";")],-1),B=e("li",null,[o("It is recommended to pass the test before submitting a pull request: "),e("code",null,"go test ./..."),o(";")],-1),S=e("li",null,"It is recommended to have more than 70% code coverage for newly added code before submitting pull requests.",-1),L=e("li",null,[o("Other "),e("ul",null,[e("li",null,"Please pay attention to the readability of the code.")])],-1),q=r(`

                        Pull Request

                        • Before submitting a PR, please run git pull https://github.com/xray/xray-core.git to ensure that the merge can proceed smoothly;
                        • One PR only does one thing. If there are fixes for multiple bugs, please submit a PR for each bug;
                        • Due to Golang's special requirements (Package path), the PR process for Go projects is different from other projects. The recommended process is as follows:
                          1. Fork this project first and create your own github.com/<your_name>/Xray-core.git repository;
                          2. Clone your own Xray repository to your local machine: git clone https://github.com/<your_name>/Xray-core.git;
                          3. Create a new branch based on the main branch, for example git branch issue24 main;
                          4. Make changes on the new branch and commit the changes;
                          5. Before pushing the modified branch to your own repository, switch to the main branch, and run git pull https://github.com/xray/xray-core.git to pull the latest remote code;
                          6. If new remote code is obtained in the previous step, switch to the branch you created earlier and run git rebase main to perform branch merging. If there is a file conflict, you need to resolve the conflict;
                          7. After the previous step is completed, you can push the branch you created to your own repository: git push -u origin your-branch
                          8. Finally, send a PR from your new pushed branch in your own repository to the main branch of xtls/Xray-core;
                          9. Please fully describe the purpose of this PR, including the problem solved, the new feature added, or the modifications made in the title and body of the PR;
                          10. Please be patient and wait for the developer's response.

                        Modifying Code

                        Functional issue

                        Please submit at least one test case to verify changes to existing functionality.

                        Please provide the necessary test data to demonstrate performance issues in existing code or performance improvements in new code.

                        New Feature

                        • If the new feature does not affect the existing functionality, please provide a toggle (such as a flag) that can be turned on/off, and keep the new feature disabled by default.
                        • For major new features (such as adding a new protocol), please submit an issue for discussion before development.

                        Other

                        It depends on the specific situation.

                        Xray Coding Guidelines

                        The following content is applicable to Golang code in Xray.

                        Code Structure

                        Xray-core
                         ├── app        // Application module
                         │   ├── router // Router
                         ├── common     // Common code
                        diff --git a/assets/guide.html-K0U2knuj.js b/assets/guide.html-yvvDMK2K.js
                        similarity index 99%
                        rename from assets/guide.html-K0U2knuj.js
                        rename to assets/guide.html-yvvDMK2K.js
                        index c0d3899daa..fa60982300 100644
                        --- a/assets/guide.html-K0U2knuj.js
                        +++ b/assets/guide.html-yvvDMK2K.js
                        @@ -1,4 +1,4 @@
                        -import{_ as s,r as o,o as t,c,a as e,b as l,d as n,e as i}from"./app-PDrbPfzp.js";const d={},h=i('

                        开发规范

                        基本

                        版本控制

                        Project X 的代码被托管在 github 上:

                        ',4),u={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},p={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},_={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},g={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},b={href:"https://git-scm.com/",target:"_blank",rel:"noopener noreferrer"},m=e("h3",{id:"分支-branch",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#分支-branch"},[e("span",null,"分支(Branch)")])],-1),f=e("ul",null,[e("li",null,"本项目的主干分支为 main,"),e("li",null,"本项目的发布主分支同为 main,"),e("li",null,"需要确保 main 在任一时刻都是可编译,且可正常使用的。"),e("li",null,"如果需要开发新的功能,请新建分支进行开发,在开发完成并且经过充分测试后,合并回主干分支。"),e("li",null,"已经合并入主干且没有必要存在的分支,请删除。")],-1),x=e("h3",{id:"发布-release",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#发布-release"},[e("span",null,"发布(Release)")])],-1),v=e("ul",null,[e("li",null,[l("建立尝鲜版本和稳定版本两个发布通道 "),e("ul",null,[e("li",null,"尝鲜版本,可以为 daily build,主要用于特定情况的测试,尝鲜和获得即时反馈和再改进。"),e("li",null,"稳定版本,为定时更新(比如月更),合并稳定的修改并发布。")])])],-1),X=e("h3",{id:"引用其它项目",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#引用其它项目"},[e("span",null,"引用其它项目")])],-1),y={href:"https://pkg.go.dev/search?limit=25&m=package&q=golang.org%2Fx",target:"_blank",rel:"noopener noreferrer"},k=e("li",null,"如需引用其它项目,请事先创建 issue 讨论;",-1),P=e("li",null,[l("其它 "),e("ul",null,[e("li",null,"不违反双方的协议,且对项目有帮助的工具,都可以使用。")])],-1),B=e("h2",{id:"开发流程",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#开发流程"},[e("span",null,"开发流程")])],-1),L=e("h3",{id:"写代码之前",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#写代码之前"},[e("span",null,"写代码之前")])],-1),T={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},E=e("h3",{id:"修改代码",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#修改代码"},[e("span",null,"修改代码")])],-1),G={href:"https://golang.org/doc/effective_go.html",target:"_blank",rel:"noopener noreferrer"},R=e("li",null,[l("每一次 push 之前,请运行:"),e("code",null,"go generate core/format.go"),l(";")],-1),S=e("li",null,[l("如果需要修改 protobuf,例如增加新配置项,请运行:"),e("code",null,"go generate core/proto.go"),l(";")],-1),q=e("li",null,[l("提交 pull request 之前,建议测试通过:"),e("code",null,"go test ./..."),l(";")],-1),A=e("li",null,"提交 pull request 之前,建议新增代码有超过 70% 的代码覆盖率(code coverage);",-1),F=e("li",null,[l("其它 "),e("ul",null,[e("li",null,"请注意代码的可读性。")])],-1),w=i(`

                        Pull Request

                        • 提交 PR 之前,请先运行 git pull https://github.com/XTLS/Xray-core.git 以确保 merge 可顺利进行;
                        • 一个 PR 只做一件事,如有对多个 bug 的修复,请对每一个 bug 提交一个 PR;
                        • 由于 Golang 的特殊需求(Package path),Go 项目的 PR 流程和其它项目有所不同,建议流程如下:
                          1. 先 Fork 本项目,创建你自己的 github.com/<your_name>/Xray-core.git 仓库;
                          2. 克隆你自己的 Xray 仓库到本地:git clone https://github.com/<your_name>/Xray-core.git
                          3. 基于 main 分支创建新的分支,例如 git branch issue24 main
                          4. 在新创建的分支上作修改并提交修改(commit);
                          5. 在推送(push)修改完成的分支到自己的仓库前,先切换到 main 分支,运行 git pull https://github.com/XTLS/Xray-core.git 拉取最新的远端代码;
                          6. 如果上一步拉取得到了新的远端代码,则切换到之前自己创建的分支,运行 git rebase main 执行分支合并操作。如遇到文件冲突,则需要解决冲突;
                          7. 上一步处理完毕后,就可以把自己创建的分支推送到自己的仓库:git push -u origin your-branch
                          8. 最后,把自己仓库的新推送的分支往 XTLS/Xray-coremain 分支发 PR 即可;
                          9. 请在 PR 的标题和正文中,完整表述此次 PR 解决的问题 / 新增的功能 / 代码所做的修改的用意等;
                          10. 耐心等待开发者的回应。

                        对代码的修改

                        功能性问题

                        请提交至少一个测试用例(Test Case)来验证对现有功能的改动。

                        性能相关

                        请提交必要的测试数据来证明现有代码的性能缺陷,或是新增代码的性能提升。

                        新功能

                        • 如果新增功能对已有功能不影响,请提供可以开启/关闭的开关(如 flag),并使新功能保持默认关闭的状态;
                        • 大型新功能(比如增加一个新的协议)开发之前,请先提交一个 issue,讨论完毕之后再进行开发。

                        其它

                        视具体情况而定。

                        Xray 编码规范

                        以下内容适用于 Xray 中的 Golang 代码。

                        代码结构

                        Xray-core
                        +import{_ as s,r as o,o as t,c,a as e,b as l,d as n,e as i}from"./app-UOvWaKji.js";const d={},h=i('

                        开发规范

                        基本

                        版本控制

                        Project X 的代码被托管在 github 上:

                        ',4),u={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},p={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},_={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},g={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},b={href:"https://git-scm.com/",target:"_blank",rel:"noopener noreferrer"},m=e("h3",{id:"分支-branch",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#分支-branch"},[e("span",null,"分支(Branch)")])],-1),f=e("ul",null,[e("li",null,"本项目的主干分支为 main,"),e("li",null,"本项目的发布主分支同为 main,"),e("li",null,"需要确保 main 在任一时刻都是可编译,且可正常使用的。"),e("li",null,"如果需要开发新的功能,请新建分支进行开发,在开发完成并且经过充分测试后,合并回主干分支。"),e("li",null,"已经合并入主干且没有必要存在的分支,请删除。")],-1),x=e("h3",{id:"发布-release",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#发布-release"},[e("span",null,"发布(Release)")])],-1),v=e("ul",null,[e("li",null,[l("建立尝鲜版本和稳定版本两个发布通道 "),e("ul",null,[e("li",null,"尝鲜版本,可以为 daily build,主要用于特定情况的测试,尝鲜和获得即时反馈和再改进。"),e("li",null,"稳定版本,为定时更新(比如月更),合并稳定的修改并发布。")])])],-1),X=e("h3",{id:"引用其它项目",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#引用其它项目"},[e("span",null,"引用其它项目")])],-1),y={href:"https://pkg.go.dev/search?limit=25&m=package&q=golang.org%2Fx",target:"_blank",rel:"noopener noreferrer"},k=e("li",null,"如需引用其它项目,请事先创建 issue 讨论;",-1),P=e("li",null,[l("其它 "),e("ul",null,[e("li",null,"不违反双方的协议,且对项目有帮助的工具,都可以使用。")])],-1),B=e("h2",{id:"开发流程",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#开发流程"},[e("span",null,"开发流程")])],-1),L=e("h3",{id:"写代码之前",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#写代码之前"},[e("span",null,"写代码之前")])],-1),T={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},E=e("h3",{id:"修改代码",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#修改代码"},[e("span",null,"修改代码")])],-1),G={href:"https://golang.org/doc/effective_go.html",target:"_blank",rel:"noopener noreferrer"},R=e("li",null,[l("每一次 push 之前,请运行:"),e("code",null,"go generate core/format.go"),l(";")],-1),S=e("li",null,[l("如果需要修改 protobuf,例如增加新配置项,请运行:"),e("code",null,"go generate core/proto.go"),l(";")],-1),q=e("li",null,[l("提交 pull request 之前,建议测试通过:"),e("code",null,"go test ./..."),l(";")],-1),A=e("li",null,"提交 pull request 之前,建议新增代码有超过 70% 的代码覆盖率(code coverage);",-1),F=e("li",null,[l("其它 "),e("ul",null,[e("li",null,"请注意代码的可读性。")])],-1),w=i(`

                        Pull Request

                        • 提交 PR 之前,请先运行 git pull https://github.com/XTLS/Xray-core.git 以确保 merge 可顺利进行;
                        • 一个 PR 只做一件事,如有对多个 bug 的修复,请对每一个 bug 提交一个 PR;
                        • 由于 Golang 的特殊需求(Package path),Go 项目的 PR 流程和其它项目有所不同,建议流程如下:
                          1. 先 Fork 本项目,创建你自己的 github.com/<your_name>/Xray-core.git 仓库;
                          2. 克隆你自己的 Xray 仓库到本地:git clone https://github.com/<your_name>/Xray-core.git
                          3. 基于 main 分支创建新的分支,例如 git branch issue24 main
                          4. 在新创建的分支上作修改并提交修改(commit);
                          5. 在推送(push)修改完成的分支到自己的仓库前,先切换到 main 分支,运行 git pull https://github.com/XTLS/Xray-core.git 拉取最新的远端代码;
                          6. 如果上一步拉取得到了新的远端代码,则切换到之前自己创建的分支,运行 git rebase main 执行分支合并操作。如遇到文件冲突,则需要解决冲突;
                          7. 上一步处理完毕后,就可以把自己创建的分支推送到自己的仓库:git push -u origin your-branch
                          8. 最后,把自己仓库的新推送的分支往 XTLS/Xray-coremain 分支发 PR 即可;
                          9. 请在 PR 的标题和正文中,完整表述此次 PR 解决的问题 / 新增的功能 / 代码所做的修改的用意等;
                          10. 耐心等待开发者的回应。

                        对代码的修改

                        功能性问题

                        请提交至少一个测试用例(Test Case)来验证对现有功能的改动。

                        性能相关

                        请提交必要的测试数据来证明现有代码的性能缺陷,或是新增代码的性能提升。

                        新功能

                        • 如果新增功能对已有功能不影响,请提供可以开启/关闭的开关(如 flag),并使新功能保持默认关闭的状态;
                        • 大型新功能(比如增加一个新的协议)开发之前,请先提交一个 issue,讨论完毕之后再进行开发。

                        其它

                        视具体情况而定。

                        Xray 编码规范

                        以下内容适用于 Xray 中的 Golang 代码。

                        代码结构

                        Xray-core
                         ├── app        // 应用模块
                         │   ├── router // 路由
                         ├── common     // 公用代码
                        diff --git a/assets/h2.html-GaXRW7zG.js b/assets/h2.html-8klqPb9j.js
                        similarity index 98%
                        rename from assets/h2.html-GaXRW7zG.js
                        rename to assets/h2.html-8klqPb9j.js
                        index ab8160579f..7f78190016 100644
                        --- a/assets/h2.html-GaXRW7zG.js
                        +++ b/assets/h2.html-8klqPb9j.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as t,o as p,c as r,a as e,b as n,d as s,w as l,e as o}from"./app-PDrbPfzp.js";const d={},u=o('

                        HTTP/2

                        The transmission mode based on HTTP/2 fully implements the HTTP/2 standard and can be relayed by other HTTP servers (such as Nginx).

                        Based on the recommendations of HTTP/2, both the client and server must enable TLS to use this transmission mode normally.

                        HTTP/2 has built-in multiplexing, so it is not recommended to enable mux.cool when using HTTP/2.

                        Tip

                        The current version of the transmission mode based on HTTP/2 does not require TLS configuration for inbound (server-side).

                        This makes it possible to use a plaintext HTTP/2 protocol called h2c for communication between the gateway and Xray, with external gateway components handling the TLS layer conversation in special-purpose load-balancing deployment environments.

                        Warning

                        ⚠️ If you are using fallback, please note the following:

                        • Please make sure that h2 is included in (x)tlsSettings.alpn, otherwise HTTP/2 cannot complete TLS handshake.
                        • HTTP/2 cannot perform path-based routing, so it is recommended to use SNI-based routing.

                        HttpObject

                        ',7),h=e("code",null,"HttpObject",-1),m=e("code",null,"httpSettings",-1),k=o(`
                        {
                        +import{_ as c,r as t,o as p,c as r,a as e,b as n,d as s,w as l,e as o}from"./app-UOvWaKji.js";const d={},u=o('

                        HTTP/2

                        The transmission mode based on HTTP/2 fully implements the HTTP/2 standard and can be relayed by other HTTP servers (such as Nginx).

                        Based on the recommendations of HTTP/2, both the client and server must enable TLS to use this transmission mode normally.

                        HTTP/2 has built-in multiplexing, so it is not recommended to enable mux.cool when using HTTP/2.

                        Tip

                        The current version of the transmission mode based on HTTP/2 does not require TLS configuration for inbound (server-side).

                        This makes it possible to use a plaintext HTTP/2 protocol called h2c for communication between the gateway and Xray, with external gateway components handling the TLS layer conversation in special-purpose load-balancing deployment environments.

                        Warning

                        ⚠️ If you are using fallback, please note the following:

                        • Please make sure that h2 is included in (x)tlsSettings.alpn, otherwise HTTP/2 cannot complete TLS handshake.
                        • HTTP/2 cannot perform path-based routing, so it is recommended to use SNI-based routing.

                        HttpObject

                        ',7),h=e("code",null,"HttpObject",-1),m=e("code",null,"httpSettings",-1),k=o(`
                        {
                           "host": ["xray.com"],
                           "path": "/random/path",
                           "read_idle_timeout": 10,
                        diff --git a/assets/h2.html-Qs5yO4Vz.js b/assets/h2.html-XhOE9s1o.js
                        similarity index 98%
                        rename from assets/h2.html-Qs5yO4Vz.js
                        rename to assets/h2.html-XhOE9s1o.js
                        index 80dfc37a62..aea5ca9ecb 100644
                        --- a/assets/h2.html-Qs5yO4Vz.js
                        +++ b/assets/h2.html-XhOE9s1o.js
                        @@ -1,4 +1,4 @@
                        -import{_ as o,r as e,o as a,c as p,a as t,b as s,d as c,e as l}from"./app-PDrbPfzp.js";const r={},i=l(`

                        HTTP/2

                        基于 HTTP/2 的传输方式。

                        它完整按照 HTTP/2 标准实现,可以通过其它的 HTTP 服务器(如 Nginx)进行中转。

                        由 HTTP/2 的建议,客户端和服务器必须同时开启 TLS 才可以正常使用这个传输方式。

                        HTTP/2 内置多路复用,不建议使用 HTTP/2 时启用 mux.cool。

                        提示

                        当前版本的 HTTP/2 的传输方式并不强制要求入站服务端)有 TLS 配置. 这使得可以在特殊用途的分流部署环境中,由外部网关组件完成 TLS 层对话,Xray 作为后端应用,网关和 Xray 间使用称为 h2c 的明文 http/2 进行通讯。

                        注意

                        ⚠️ 如果你正在使用回落,请注意下列事项:

                        • 请确认 (x)tlsSettings.alpn 中包含 h2,否则 HTTP/2 无法完成 TLS 握手。
                        • HTTP/2 无法通过 Path 进行分流,建议使用 SNI 分流。

                        HttpObject

                        HttpObject 对应传输配置的 httpSettings 项。

                        {
                        +import{_ as o,r as e,o as a,c as p,a as t,b as s,d as c,e as l}from"./app-UOvWaKji.js";const r={},i=l(`

                        HTTP/2

                        基于 HTTP/2 的传输方式。

                        它完整按照 HTTP/2 标准实现,可以通过其它的 HTTP 服务器(如 Nginx)进行中转。

                        由 HTTP/2 的建议,客户端和服务器必须同时开启 TLS 才可以正常使用这个传输方式。

                        HTTP/2 内置多路复用,不建议使用 HTTP/2 时启用 mux.cool。

                        提示

                        当前版本的 HTTP/2 的传输方式并不强制要求入站服务端)有 TLS 配置. 这使得可以在特殊用途的分流部署环境中,由外部网关组件完成 TLS 层对话,Xray 作为后端应用,网关和 Xray 间使用称为 h2c 的明文 http/2 进行通讯。

                        注意

                        ⚠️ 如果你正在使用回落,请注意下列事项:

                        • 请确认 (x)tlsSettings.alpn 中包含 h2,否则 HTTP/2 无法完成 TLS 握手。
                        • HTTP/2 无法通过 Path 进行分流,建议使用 SNI 分流。

                        HttpObject

                        HttpObject 对应传输配置的 httpSettings 项。

                        {
                           "host": ["xray.com"],
                           "path": "/random/path",
                           "read_idle_timeout": 10,
                        diff --git a/assets/http.html-FQ-Y96ef.js b/assets/http.html-FEDggO-p.js
                        similarity index 99%
                        rename from assets/http.html-FQ-Y96ef.js
                        rename to assets/http.html-FEDggO-p.js
                        index df99771264..2dd8c6b6ff 100644
                        --- a/assets/http.html-FQ-Y96ef.js
                        +++ b/assets/http.html-FEDggO-p.js
                        @@ -1,4 +1,4 @@
                        -import{_ as s,o as n,c as a,e}from"./app-PDrbPfzp.js";const t={},o=e(`

                        HTTP

                        HTTP 协议。

                        警告

                        http 协议没有对传输加密,不适宜经公网中传输,更容易成为被人用作攻击的肉鸡。

                        提示

                        http 只能代理 tcp 协议,udp 系的协议均不能通过。

                        OutboundConfigurationObject

                        {
                        +import{_ as s,o as n,c as a,e}from"./app-UOvWaKji.js";const t={},o=e(`

                        HTTP

                        HTTP 协议。

                        警告

                        http 协议没有对传输加密,不适宜经公网中传输,更容易成为被人用作攻击的肉鸡。

                        提示

                        http 只能代理 tcp 协议,udp 系的协议均不能通过。

                        OutboundConfigurationObject

                        {
                           "servers": [
                             {
                               "address": "192.168.108.1",
                        diff --git a/assets/http.html-TnUHA5fS.js b/assets/http.html-PUYLTCZT.js
                        similarity index 98%
                        rename from assets/http.html-TnUHA5fS.js
                        rename to assets/http.html-PUYLTCZT.js
                        index 99d0b36dc6..0e103de94f 100644
                        --- a/assets/http.html-TnUHA5fS.js
                        +++ b/assets/http.html-PUYLTCZT.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as i,o as p,c as r,a as e,b as n,d as s,w as t,e as a}from"./app-PDrbPfzp.js";const l={},u=a(`

                        HTTP

                        HTTP protocol.

                        Warning

                        The HTTP protocol does not provide encryption for transmission and is not suitable for transmission over public networks, as it can easily be used as a target for attacks.

                        The more meaningful use of http inbound is to listen in a local network or on the local machine to provide local services for other programs.

                        TIP 1

                        http proxy can only proxy the TCP protocol and cannot handle protocols based on UDP.

                        TIP 2

                        In Linux, you can use the following environment variables to enable global HTTP proxy for the current session (many software support this setting, but some may not).

                        • export http_proxy=http://127.0.0.1:8080/ (Change the address to the configured inbound HTTP proxy address)
                        • export https_proxy=$http_proxy
                        • :::

                        InboundConfigurationObject

                        {
                        +import{_ as c,r as i,o as p,c as r,a as e,b as n,d as s,w as t,e as a}from"./app-UOvWaKji.js";const l={},u=a(`

                        HTTP

                        HTTP protocol.

                        Warning

                        The HTTP protocol does not provide encryption for transmission and is not suitable for transmission over public networks, as it can easily be used as a target for attacks.

                        The more meaningful use of http inbound is to listen in a local network or on the local machine to provide local services for other programs.

                        TIP 1

                        http proxy can only proxy the TCP protocol and cannot handle protocols based on UDP.

                        TIP 2

                        In Linux, you can use the following environment variables to enable global HTTP proxy for the current session (many software support this setting, but some may not).

                        • export http_proxy=http://127.0.0.1:8080/ (Change the address to the configured inbound HTTP proxy address)
                        • export https_proxy=$http_proxy
                        • :::

                        InboundConfigurationObject

                        {
                           "timeout": 0,
                           "accounts": [
                             {
                        diff --git a/assets/http.html-WXAZvIym.js b/assets/http.html-_yXVXvnY.js
                        similarity index 99%
                        rename from assets/http.html-WXAZvIym.js
                        rename to assets/http.html-_yXVXvnY.js
                        index d807c01589..a4e31d1f48 100644
                        --- a/assets/http.html-WXAZvIym.js
                        +++ b/assets/http.html-_yXVXvnY.js
                        @@ -1,4 +1,4 @@
                        -import{_ as s,o as n,c as a,e}from"./app-PDrbPfzp.js";const t={},o=e(`

                        HTTP

                        HTTP is a protocol that is used for communication over the internet. Please note that HTTP does not provide encryption for data transmission and is not suitable for transmitting sensitive information over public networks, as it can be easily targeted for attacks.

                        Danger

                        The HTTP protocol does not provide encryption for transmission, making it unsuitable for transmitting over public networks and more susceptible to being used as a compromised host for attacks.

                        Tip

                        HTTP can only proxy TCP protocols, and cannot handle UDP-based protocols.

                        OutboundConfigurationObject

                        {
                        +import{_ as s,o as n,c as a,e}from"./app-UOvWaKji.js";const t={},o=e(`

                        HTTP

                        HTTP is a protocol that is used for communication over the internet. Please note that HTTP does not provide encryption for data transmission and is not suitable for transmitting sensitive information over public networks, as it can be easily targeted for attacks.

                        Danger

                        The HTTP protocol does not provide encryption for transmission, making it unsuitable for transmitting over public networks and more susceptible to being used as a compromised host for attacks.

                        Tip

                        HTTP can only proxy TCP protocols, and cannot handle UDP-based protocols.

                        OutboundConfigurationObject

                        {
                           "servers": [
                             {
                               "address": "192.168.108.1",
                        diff --git a/assets/http.html-bLJEWSqs.js b/assets/http.html-gFUfd4hn.js
                        similarity index 98%
                        rename from assets/http.html-bLJEWSqs.js
                        rename to assets/http.html-gFUfd4hn.js
                        index 0ecfda3bbc..db9c18dfcf 100644
                        --- a/assets/http.html-bLJEWSqs.js
                        +++ b/assets/http.html-gFUfd4hn.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as c,o as l,c as i,a as s,b as n,d as o,w as a,e as t}from"./app-PDrbPfzp.js";const u={},r=t(`

                        HTTP

                        HTTP 协议。

                        警告

                        http 协议没有对传输加密,不适宜经公网中传输,更容易成为被人用作攻击的肉鸡。

                        http 入站更有意义的用法是在局域网或本机环境下监听,为其他程序提供本地服务。

                        TIP 1

                        http proxy 只能代理 tcp 协议,udp 系的协议均不能通过。

                        TIP 2

                        在 Linux 中使用以下环境变量即可在当前 session 使用全局 HTTP 代理(很多软件都支持这一设置,也有不支持的)。

                        • export http_proxy=http://127.0.0.1:8080/ (地址须改成你配置的 HTTP 入站代理地址)
                        • export https_proxy=$http_proxy

                        InboundConfigurationObject

                        {
                        +import{_ as p,r as c,o as l,c as i,a as s,b as n,d as o,w as a,e as t}from"./app-UOvWaKji.js";const u={},r=t(`

                        HTTP

                        HTTP 协议。

                        警告

                        http 协议没有对传输加密,不适宜经公网中传输,更容易成为被人用作攻击的肉鸡。

                        http 入站更有意义的用法是在局域网或本机环境下监听,为其他程序提供本地服务。

                        TIP 1

                        http proxy 只能代理 tcp 协议,udp 系的协议均不能通过。

                        TIP 2

                        在 Linux 中使用以下环境变量即可在当前 session 使用全局 HTTP 代理(很多软件都支持这一设置,也有不支持的)。

                        • export http_proxy=http://127.0.0.1:8080/ (地址须改成你配置的 HTTP 入站代理地址)
                        • export https_proxy=$http_proxy

                        InboundConfigurationObject

                        {
                           "timeout": 0,
                           "accounts": [
                             {
                        diff --git a/assets/httpupgrade.html-nQrMkERg.js b/assets/httpupgrade.html-8y62ZYsJ.js
                        similarity index 98%
                        rename from assets/httpupgrade.html-nQrMkERg.js
                        rename to assets/httpupgrade.html-8y62ZYsJ.js
                        index 90d8986e39..5e451cca50 100644
                        --- a/assets/httpupgrade.html-nQrMkERg.js
                        +++ b/assets/httpupgrade.html-8y62ZYsJ.js
                        @@ -1,4 +1,4 @@
                        -import{_ as s,r as n,o as p,c,a as o,b as e,d as r,e as t}from"./app-PDrbPfzp.js";const d={},l=t(`

                        HTTPUpgrade

                        一个实现了类似于 WebSocket 进行 HTTP 1.1 升级请求和响应的协议,这使得它可以像 WebSocket 一样可以被CDN或者Nginx进行反代,但无需实现 WebSocket 协议的其他部分,所以具有更高的效率。 其设计不推荐单独使用,而是和TLS等安全协议一起工作。

                        HttpUpgradeObject

                        HttpUpgradeObject 对应传输配置的 httpupgradeSettings 项。

                        {
                        +import{_ as s,r as n,o as p,c,a as o,b as e,d as r,e as t}from"./app-UOvWaKji.js";const d={},l=t(`

                        HTTPUpgrade

                        一个实现了类似于 WebSocket 进行 HTTP 1.1 升级请求和响应的协议,这使得它可以像 WebSocket 一样可以被CDN或者Nginx进行反代,但无需实现 WebSocket 协议的其他部分,所以具有更高的效率。 其设计不推荐单独使用,而是和TLS等安全协议一起工作。

                        HttpUpgradeObject

                        HttpUpgradeObject 对应传输配置的 httpupgradeSettings 项。

                        {
                           "acceptProxyProtocol": false,
                           "path": "/",
                           "host": "xray.com",
                        diff --git a/assets/httpupgrade.html-KlUuHOb_.js b/assets/httpupgrade.html-HCGGfbXe.js
                        similarity index 98%
                        rename from assets/httpupgrade.html-KlUuHOb_.js
                        rename to assets/httpupgrade.html-HCGGfbXe.js
                        index 42b4ec912e..4506e6eeaa 100644
                        --- a/assets/httpupgrade.html-KlUuHOb_.js
                        +++ b/assets/httpupgrade.html-HCGGfbXe.js
                        @@ -1,4 +1,4 @@
                        -import{_ as s,r as a,o as r,c as p,a as t,b as e,d as c,e as o}from"./app-PDrbPfzp.js";const d={},i=o(`

                        HTTPUpgrade

                        A WebSocket-like transport protocol implementing the HTTP/1.1 upgrade and response, allowing it to be reverse proxied by web servers or CDNs just like WebSocket, but without the need to implement the remaining portions of the WebSocket protocol, yielding better performance.

                        Standalone usage is not recommended, but rather in conjunction with other security protocols like TLS.

                        HttpUpgradeObject

                        The HttpUpgradeObject corresponds to the httpupgradeSettings section under transport configurations.

                        {
                        +import{_ as s,r as a,o as r,c as p,a as t,b as e,d as c,e as o}from"./app-UOvWaKji.js";const d={},i=o(`

                        HTTPUpgrade

                        A WebSocket-like transport protocol implementing the HTTP/1.1 upgrade and response, allowing it to be reverse proxied by web servers or CDNs just like WebSocket, but without the need to implement the remaining portions of the WebSocket protocol, yielding better performance.

                        Standalone usage is not recommended, but rather in conjunction with other security protocols like TLS.

                        HttpUpgradeObject

                        The HttpUpgradeObject corresponds to the httpupgradeSettings section under transport configurations.

                        {
                           "acceptProxyProtocol": false,
                           "path": "/",
                           "host": "xray.com",
                        diff --git a/assets/inbound.html-xA8fmFfL.js b/assets/inbound.html-LOzJibnU.js
                        similarity index 99%
                        rename from assets/inbound.html-xA8fmFfL.js
                        rename to assets/inbound.html-LOzJibnU.js
                        index e98dbf4886..e237b89006 100644
                        --- a/assets/inbound.html-xA8fmFfL.js
                        +++ b/assets/inbound.html-LOzJibnU.js
                        @@ -1,4 +1,4 @@
                        -import{_ as u,r as t,o as i,c as d,a as n,b as s,d as o,w as c,e}from"./app-PDrbPfzp.js";const r={},k=n("h1",{id:"入站代理",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#入站代理"},[n("span",null,"入站代理")])],-1),q=e(`

                        InboundObject

                        InboundObject 对应配置文件中 inbounds 项的一个子元素。

                        {
                        +import{_ as u,r as t,o as i,c as d,a as n,b as s,d as o,w as c,e}from"./app-UOvWaKji.js";const r={},k=n("h1",{id:"入站代理",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#入站代理"},[n("span",null,"入站代理")])],-1),q=e(`

                        InboundObject

                        InboundObject 对应配置文件中 inbounds 项的一个子元素。

                        {
                           "inbounds": [
                             {
                               "listen": "127.0.0.1",
                        diff --git a/assets/inbound.html-7sY9D7Up.js b/assets/inbound.html-fVeoUFmr.js
                        similarity index 99%
                        rename from assets/inbound.html-7sY9D7Up.js
                        rename to assets/inbound.html-fVeoUFmr.js
                        index f08bb746ba..f70e3b65b7 100644
                        --- a/assets/inbound.html-7sY9D7Up.js
                        +++ b/assets/inbound.html-fVeoUFmr.js
                        @@ -1,4 +1,4 @@
                        -import{_ as r,r as a,o as l,c as d,a as e,b as n,d as o,w as c,e as t}from"./app-PDrbPfzp.js";const u={},h=e("h1",{id:"inbound-proxy",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#inbound-proxy"},[e("span",null,"Inbound Proxy")])],-1),b=t(`

                        InboundObject

                        The InboundObject corresponds to a subelement of the inbounds item in the configuration file.

                        {
                        +import{_ as r,r as a,o as l,c as d,a as e,b as n,d as o,w as c,e as t}from"./app-UOvWaKji.js";const u={},h=e("h1",{id:"inbound-proxy",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#inbound-proxy"},[e("span",null,"Inbound Proxy")])],-1),b=t(`

                        InboundObject

                        The InboundObject corresponds to a subelement of the inbounds item in the configuration file.

                        {
                           "inbounds": [
                             {
                               "listen": "127.0.0.1",
                        diff --git a/assets/index-fc10efb0-knA-ZLJ0.js b/assets/index-fc10efb0-cfY4JypU.js
                        similarity index 96%
                        rename from assets/index-fc10efb0-knA-ZLJ0.js
                        rename to assets/index-fc10efb0-cfY4JypU.js
                        index 618b53f12b..4c37eebebf 100644
                        --- a/assets/index-fc10efb0-knA-ZLJ0.js
                        +++ b/assets/index-fc10efb0-cfY4JypU.js
                        @@ -1 +1 @@
                        -import{q as N,G as A}from"./graph-cZfODKa1.js";import{m as $,l as q}from"./layout-konkdG3Z.js";import{c as H}from"./clone-jETecP85.js";import{i as V,u as U,s as W,a as _,b as z,g as D,p as O,c as K,d as Q,e as Y,f as Z,h as J,j as p}from"./edges-d32062c0-iT1MEq_Y.js";import{l as s,c as T,q as S,h as L}from"./mermaid.core-95b3ca__.js";import{c as I}from"./createText-6b48ae7d-9AoX5zU9.js";function m(e){var t={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:tt(e),edges:et(e)};return N(e.graph())||(t.value=H(e.graph())),t}function tt(e){return $(e.nodes(),function(t){var n=e.node(t),r=e.parent(t),i={v:t};return N(n)||(i.value=n),N(r)||(i.parent=r),i})}function et(e){return $(e.edges(),function(t){var n=e.edge(t),r={v:t.v,w:t.w};return N(t.name)||(r.name=t.name),N(n)||(r.value=n),r})}let l={},g={},R={};const nt=()=>{g={},R={},l={}},B=(e,t)=>(s.trace("In isDescendant",t," ",e," = ",g[t].includes(e)),!!g[t].includes(e)),it=(e,t)=>(s.info("Descendants of ",t," is ",g[t]),s.info("Edge is ",e),e.v===t||e.w===t?!1:g[t]?g[t].includes(e.v)||B(e.v,t)||B(e.w,t)||g[t].includes(e.w):(s.debug("Tilt, ",t,",not in descendants"),!1)),P=(e,t,n,r)=>{s.warn("Copying children of ",e,"root",r,"data",t.node(e),r);const i=t.children(e)||[];e!==r&&i.push(e),s.warn("Copying (nodes) clusterId",e,"nodes",i),i.forEach(a=>{if(t.children(a).length>0)P(a,t,n,r);else{const d=t.node(a);s.info("cp ",a," to ",r," with parent ",e),n.setNode(a,d),r!==t.parent(a)&&(s.warn("Setting parent",a,t.parent(a)),n.setParent(a,t.parent(a))),e!==r&&a!==e?(s.debug("Setting parent",a,e),n.setParent(a,e)):(s.info("In copy ",e,"root",r,"data",t.node(e),r),s.debug("Not Setting parent for node=",a,"cluster!==rootId",e!==r,"node!==clusterId",a!==e));const u=t.edges(a);s.debug("Copying Edges",u),u.forEach(f=>{s.info("Edge",f);const h=t.edge(f.v,f.w,f.name);s.info("Edge data",h,r);try{it(f,r)?(s.info("Copying as ",f.v,f.w,h,f.name),n.setEdge(f.v,f.w,h,f.name),s.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]))):s.info("Skipping copy of edge ",f.v,"-->",f.w," rootId: ",r," clusterId:",e)}catch(w){s.error(w)}})}s.debug("Removing node",a),t.removeNode(a)})},k=(e,t)=>{const n=t.children(e);let r=[...n];for(const i of n)R[i]=e,r=[...r,...k(i,t)];return r},C=(e,t)=>{s.trace("Searching",e);const n=t.children(e);if(s.trace("Searching children of id ",e,n),n.length<1)return s.trace("This is a valid node",e),e;for(const r of n){const i=C(r,t);if(i)return s.trace("Found replacement for",e," => ",i),i}},X=e=>!l[e]||!l[e].externalConnections?e:l[e]?l[e].id:e,st=(e,t)=>{if(!e||t>10){s.debug("Opting out, no graph ");return}else s.debug("Opting in, graph ");e.nodes().forEach(function(n){e.children(n).length>0&&(s.warn("Cluster identified",n," Replacement id in edges: ",C(n,e)),g[n]=k(n,e),l[n]={id:C(n,e),clusterData:e.node(n)})}),e.nodes().forEach(function(n){const r=e.children(n),i=e.edges();r.length>0?(s.debug("Cluster identified",n,g),i.forEach(a=>{if(a.v!==n&&a.w!==n){const d=B(a.v,n),u=B(a.w,n);d^u&&(s.warn("Edge: ",a," leaves cluster ",n),s.warn("Descendants of XXX ",n,": ",g[n]),l[n].externalConnections=!0)}})):s.debug("Not a cluster ",n,g)});for(let n of Object.keys(l)){const r=l[n].id,i=e.parent(r);i!==n&&l[i]&&!l[i].externalConnections&&(l[n].id=i)}e.edges().forEach(function(n){const r=e.edge(n);s.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(n)),s.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(e.edge(n)));let i=n.v,a=n.w;if(s.warn("Fix XXX",l,"ids:",n.v,n.w,"Translating: ",l[n.v]," --- ",l[n.w]),l[n.v]&&l[n.w]&&l[n.v]===l[n.w]){s.warn("Fixing and trixing link to self - removing XXX",n.v,n.w,n.name),s.warn("Fixing and trixing - removing XXX",n.v,n.w,n.name),i=X(n.v),a=X(n.w),e.removeEdge(n.v,n.w,n.name);const d=n.w+"---"+n.v;e.setNode(d,{domId:d,id:d,labelStyle:"",labelText:r.label,padding:0,shape:"labelRect",style:""});const u=structuredClone(r),f=structuredClone(r);u.label="",u.arrowTypeEnd="none",f.label="",u.fromCluster=n.v,f.toCluster=n.v,e.setEdge(i,d,u,n.name+"-cyclic-special"),e.setEdge(d,a,f,n.name+"-cyclic-special")}else if(l[n.v]||l[n.w]){if(s.warn("Fixing and trixing - removing XXX",n.v,n.w,n.name),i=X(n.v),a=X(n.w),e.removeEdge(n.v,n.w,n.name),i!==n.v){const d=e.parent(i);l[d].externalConnections=!0,r.fromCluster=n.v}if(a!==n.w){const d=e.parent(a);l[d].externalConnections=!0,r.toCluster=n.w}s.warn("Fix Replacing with XXX",i,a,n.name),e.setEdge(i,a,r,n.name)}}),s.warn("Adjusted Graph",m(e)),F(e,0),s.trace(l)},F=(e,t)=>{if(s.warn("extractor - ",t,m(e),e.children("D")),t>10){s.error("Bailing out");return}let n=e.nodes(),r=!1;for(const i of n){const a=e.children(i);r=r||a.length>0}if(!r){s.debug("Done, no node has children",e.nodes());return}s.debug("Nodes = ",n,t);for(const i of n)if(s.debug("Extracting node",i,l,l[i]&&!l[i].externalConnections,!e.parent(i),e.node(i),e.children("D")," Depth ",t),!l[i])s.debug("Not a cluster",i,t);else if(!l[i].externalConnections&&e.children(i)&&e.children(i).length>0){s.warn("Cluster without external connections, without a parent and with children",i,t);let d=e.graph().rankdir==="TB"?"LR":"TB";l[i]&&l[i].clusterData&&l[i].clusterData.dir&&(d=l[i].clusterData.dir,s.warn("Fixing dir",l[i].clusterData.dir,d));const u=new A({multigraph:!0,compound:!0}).setGraph({rankdir:d,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});s.warn("Old graph before copy",m(e)),P(i,e,u,i),e.setNode(i,{clusterNode:!0,id:i,clusterData:l[i].clusterData,labelText:l[i].labelText,graph:u}),s.warn("New graph after copy node: (",i,")",m(u)),s.debug("Old graph after copy",m(e))}else s.warn("Cluster ** ",i," **not meeting the criteria !externalConnections:",!l[i].externalConnections," no parent: ",!e.parent(i)," children ",e.children(i)&&e.children(i).length>0,e.children("D"),t),s.debug(l);n=e.nodes(),s.warn("New list of nodes",n);for(const i of n){const a=e.node(i);s.warn(" Now next level",i,a),a.clusterNode&&F(a.graph,t+1)}},G=(e,t)=>{if(t.length===0)return[];let n=Object.assign(t);return t.forEach(r=>{const i=e.children(r),a=G(e,i);n=[...n,...a]}),n},rt=e=>G(e,e.children()),at=(e,t)=>{s.info("Creating subgraph rect for ",t.id,t);const n=T(),r=e.insert("g").attr("class","cluster"+(t.class?" "+t.class:"")).attr("id",t.id),i=r.insert("rect",":first-child"),a=S(n.flowchart.htmlLabels),d=r.insert("g").attr("class","cluster-label"),u=t.labelType==="markdown"?I(d,t.labelText,{style:t.labelStyle,useHtmlLabels:a}):d.node().appendChild(J(t.labelText,t.labelStyle,void 0,!0));let f=u.getBBox();if(S(n.flowchart.htmlLabels)){const c=u.children[0],o=L(u);f=c.getBoundingClientRect(),o.attr("width",f.width),o.attr("height",f.height)}const h=0*t.padding,w=h/2,x=t.width<=f.width+h?f.width+h:t.width;t.width<=f.width+h?t.diff=(f.width-t.width)/2-t.padding/2:t.diff=-t.padding/2,s.trace("Data ",t,JSON.stringify(t)),i.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-x/2).attr("y",t.y-t.height/2-w).attr("width",x).attr("height",t.height+h);const{subGraphTitleTopMargin:v}=D(n);a?d.attr("transform",`translate(${t.x-f.width/2}, ${t.y-t.height/2+v})`):d.attr("transform",`translate(${t.x}, ${t.y-t.height/2+v})`);const y=i.node().getBBox();return t.width=y.width,t.height=y.height,t.intersect=function(c){return p(t,c)},r},ct=(e,t)=>{const n=e.insert("g").attr("class","note-cluster").attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,a=i/2;r.attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-t.width/2-a).attr("y",t.y-t.height/2-a).attr("width",t.width+i).attr("height",t.height+i).attr("fill","none");const d=r.node().getBBox();return t.width=d.width,t.height=d.height,t.intersect=function(u){return p(t,u)},n},ot=(e,t)=>{const n=T(),r=e.insert("g").attr("class",t.classes).attr("id",t.id),i=r.insert("rect",":first-child"),a=r.insert("g").attr("class","cluster-label"),d=r.append("rect"),u=a.node().appendChild(J(t.labelText,t.labelStyle,void 0,!0));let f=u.getBBox();if(S(n.flowchart.htmlLabels)){const c=u.children[0],o=L(u);f=c.getBoundingClientRect(),o.attr("width",f.width),o.attr("height",f.height)}f=u.getBBox();const h=0*t.padding,w=h/2,x=t.width<=f.width+t.padding?f.width+t.padding:t.width;t.width<=f.width+t.padding?t.diff=(f.width+t.padding*0-t.width)/2:t.diff=-t.padding/2,i.attr("class","outer").attr("x",t.x-x/2-w).attr("y",t.y-t.height/2-w).attr("width",x+h).attr("height",t.height+h),d.attr("class","inner").attr("x",t.x-x/2-w).attr("y",t.y-t.height/2-w+f.height-1).attr("width",x+h).attr("height",t.height+h-f.height-3);const{subGraphTitleTopMargin:v}=D(n);a.attr("transform",`translate(${t.x-f.width/2}, ${t.y-t.height/2-t.padding/3+(S(n.flowchart.htmlLabels)?5:3)+v})`);const y=i.node().getBBox();return t.height=y.height,t.intersect=function(c){return p(t,c)},r},lt=(e,t)=>{const n=e.insert("g").attr("class",t.classes).attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,a=i/2;r.attr("class","divider").attr("x",t.x-t.width/2-a).attr("y",t.y-t.height/2).attr("width",t.width+i).attr("height",t.height+i);const d=r.node().getBBox();return t.width=d.width,t.height=d.height,t.diff=-t.padding/2,t.intersect=function(u){return p(t,u)},n},ft={rect:at,roundedWithTitle:ot,noteGroup:ct,divider:lt};let j={};const dt=(e,t)=>{s.trace("Inserting cluster");const n=t.shape||"rect";j[t.id]=ft[n](e,t)},ut=()=>{j={}},M=async(e,t,n,r,i,a)=>{s.info("Graph in recursive render: XXX",m(t),i);const d=t.graph().rankdir;s.trace("Dir in recursive render - dir:",d);const u=e.insert("g").attr("class","root");t.nodes()?s.info("Recursive render XXX",t.nodes()):s.info("No nodes found for",t),t.edges().length>0&&s.trace("Recursive edges",t.edge(t.edges()[0]));const f=u.insert("g").attr("class","clusters"),h=u.insert("g").attr("class","edgePaths"),w=u.insert("g").attr("class","edgeLabels"),x=u.insert("g").attr("class","nodes");await Promise.all(t.nodes().map(async function(c){const o=t.node(c);if(i!==void 0){const b=JSON.parse(JSON.stringify(i.clusterData));s.info("Setting data for cluster XXX (",c,") ",b,i),t.setNode(i.id,b),t.parent(c)||(s.trace("Setting parent",c,i.id),t.setParent(c,i.id,b))}if(s.info("(Insert) Node XXX"+c+": "+JSON.stringify(t.node(c))),o&&o.clusterNode){s.info("Cluster identified",c,o.width,t.node(c));const b=await M(x,o.graph,n,r,t.node(c),a),E=b.elem;U(o,E),o.diff=b.diff||0,s.info("Node bounds (abc123)",c,o,o.width,o.x,o.y),W(E,o),s.warn("Recursive render complete ",E,o)}else t.children(c).length>0?(s.info("Cluster - the non recursive path XXX",c,o.id,o,t),s.info(C(o.id,t)),l[o.id]={id:C(o.id,t),node:o}):(s.info("Node - the non recursive path",c,o.id,o),await _(x,t.node(c),d))})),t.edges().forEach(function(c){const o=t.edge(c.v,c.w,c.name);s.info("Edge "+c.v+" -> "+c.w+": "+JSON.stringify(c)),s.info("Edge "+c.v+" -> "+c.w+": ",c," ",JSON.stringify(t.edge(c))),s.info("Fix",l,"ids:",c.v,c.w,"Translating: ",l[c.v],l[c.w]),z(w,o)}),t.edges().forEach(function(c){s.info("Edge "+c.v+" -> "+c.w+": "+JSON.stringify(c))}),s.info("#############################################"),s.info("###                Layout                 ###"),s.info("#############################################"),s.info(t),q(t),s.info("Graph after layout:",m(t));let v=0;const{subGraphTitleTotalMargin:y}=D(a);return rt(t).forEach(function(c){const o=t.node(c);s.info("Position "+c+": "+JSON.stringify(t.node(c))),s.info("Position "+c+": ("+o.x,","+o.y,") width: ",o.width," height: ",o.height),o&&o.clusterNode?(o.y+=y,O(o)):t.children(c).length>0?(o.height+=y,dt(f,o),l[o.id].node=o):(o.y+=y/2,O(o))}),t.edges().forEach(function(c){const o=t.edge(c);s.info("Edge "+c.v+" -> "+c.w+": "+JSON.stringify(o),o),o.points.forEach(E=>E.y+=y/2);const b=K(h,c,o,l,n,t,r);Q(o,b)}),t.nodes().forEach(function(c){const o=t.node(c);s.info(c,o.type,o.diff),o.type==="group"&&(v=o.diff)}),{elem:u,diff:v}},bt=async(e,t,n,r,i)=>{V(e,n,r,i),Y(),Z(),ut(),nt(),s.warn("Graph at first:",JSON.stringify(m(t))),st(t),s.warn("Graph after:",JSON.stringify(m(t)));const a=T();await M(e,t,r,i,void 0,a)};export{bt as r};
                        +import{q as N,G as A}from"./graph-yVkSecXb.js";import{m as $,l as q}from"./layout-2f_iGf4E.js";import{c as H}from"./clone-bRwIupqN.js";import{i as V,u as U,s as W,a as _,b as z,g as D,p as O,c as K,d as Q,e as Y,f as Z,h as J,j as p}from"./edges-d32062c0-DdP-jtfh.js";import{l as s,c as T,q as S,h as L}from"./mermaid.core-Q3WVcjPF.js";import{c as I}from"./createText-6b48ae7d-yUX1YD6G.js";function m(e){var t={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:tt(e),edges:et(e)};return N(e.graph())||(t.value=H(e.graph())),t}function tt(e){return $(e.nodes(),function(t){var n=e.node(t),r=e.parent(t),i={v:t};return N(n)||(i.value=n),N(r)||(i.parent=r),i})}function et(e){return $(e.edges(),function(t){var n=e.edge(t),r={v:t.v,w:t.w};return N(t.name)||(r.name=t.name),N(n)||(r.value=n),r})}let l={},g={},R={};const nt=()=>{g={},R={},l={}},B=(e,t)=>(s.trace("In isDescendant",t," ",e," = ",g[t].includes(e)),!!g[t].includes(e)),it=(e,t)=>(s.info("Descendants of ",t," is ",g[t]),s.info("Edge is ",e),e.v===t||e.w===t?!1:g[t]?g[t].includes(e.v)||B(e.v,t)||B(e.w,t)||g[t].includes(e.w):(s.debug("Tilt, ",t,",not in descendants"),!1)),P=(e,t,n,r)=>{s.warn("Copying children of ",e,"root",r,"data",t.node(e),r);const i=t.children(e)||[];e!==r&&i.push(e),s.warn("Copying (nodes) clusterId",e,"nodes",i),i.forEach(a=>{if(t.children(a).length>0)P(a,t,n,r);else{const d=t.node(a);s.info("cp ",a," to ",r," with parent ",e),n.setNode(a,d),r!==t.parent(a)&&(s.warn("Setting parent",a,t.parent(a)),n.setParent(a,t.parent(a))),e!==r&&a!==e?(s.debug("Setting parent",a,e),n.setParent(a,e)):(s.info("In copy ",e,"root",r,"data",t.node(e),r),s.debug("Not Setting parent for node=",a,"cluster!==rootId",e!==r,"node!==clusterId",a!==e));const u=t.edges(a);s.debug("Copying Edges",u),u.forEach(f=>{s.info("Edge",f);const h=t.edge(f.v,f.w,f.name);s.info("Edge data",h,r);try{it(f,r)?(s.info("Copying as ",f.v,f.w,h,f.name),n.setEdge(f.v,f.w,h,f.name),s.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]))):s.info("Skipping copy of edge ",f.v,"-->",f.w," rootId: ",r," clusterId:",e)}catch(w){s.error(w)}})}s.debug("Removing node",a),t.removeNode(a)})},k=(e,t)=>{const n=t.children(e);let r=[...n];for(const i of n)R[i]=e,r=[...r,...k(i,t)];return r},C=(e,t)=>{s.trace("Searching",e);const n=t.children(e);if(s.trace("Searching children of id ",e,n),n.length<1)return s.trace("This is a valid node",e),e;for(const r of n){const i=C(r,t);if(i)return s.trace("Found replacement for",e," => ",i),i}},X=e=>!l[e]||!l[e].externalConnections?e:l[e]?l[e].id:e,st=(e,t)=>{if(!e||t>10){s.debug("Opting out, no graph ");return}else s.debug("Opting in, graph ");e.nodes().forEach(function(n){e.children(n).length>0&&(s.warn("Cluster identified",n," Replacement id in edges: ",C(n,e)),g[n]=k(n,e),l[n]={id:C(n,e),clusterData:e.node(n)})}),e.nodes().forEach(function(n){const r=e.children(n),i=e.edges();r.length>0?(s.debug("Cluster identified",n,g),i.forEach(a=>{if(a.v!==n&&a.w!==n){const d=B(a.v,n),u=B(a.w,n);d^u&&(s.warn("Edge: ",a," leaves cluster ",n),s.warn("Descendants of XXX ",n,": ",g[n]),l[n].externalConnections=!0)}})):s.debug("Not a cluster ",n,g)});for(let n of Object.keys(l)){const r=l[n].id,i=e.parent(r);i!==n&&l[i]&&!l[i].externalConnections&&(l[n].id=i)}e.edges().forEach(function(n){const r=e.edge(n);s.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(n)),s.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(e.edge(n)));let i=n.v,a=n.w;if(s.warn("Fix XXX",l,"ids:",n.v,n.w,"Translating: ",l[n.v]," --- ",l[n.w]),l[n.v]&&l[n.w]&&l[n.v]===l[n.w]){s.warn("Fixing and trixing link to self - removing XXX",n.v,n.w,n.name),s.warn("Fixing and trixing - removing XXX",n.v,n.w,n.name),i=X(n.v),a=X(n.w),e.removeEdge(n.v,n.w,n.name);const d=n.w+"---"+n.v;e.setNode(d,{domId:d,id:d,labelStyle:"",labelText:r.label,padding:0,shape:"labelRect",style:""});const u=structuredClone(r),f=structuredClone(r);u.label="",u.arrowTypeEnd="none",f.label="",u.fromCluster=n.v,f.toCluster=n.v,e.setEdge(i,d,u,n.name+"-cyclic-special"),e.setEdge(d,a,f,n.name+"-cyclic-special")}else if(l[n.v]||l[n.w]){if(s.warn("Fixing and trixing - removing XXX",n.v,n.w,n.name),i=X(n.v),a=X(n.w),e.removeEdge(n.v,n.w,n.name),i!==n.v){const d=e.parent(i);l[d].externalConnections=!0,r.fromCluster=n.v}if(a!==n.w){const d=e.parent(a);l[d].externalConnections=!0,r.toCluster=n.w}s.warn("Fix Replacing with XXX",i,a,n.name),e.setEdge(i,a,r,n.name)}}),s.warn("Adjusted Graph",m(e)),F(e,0),s.trace(l)},F=(e,t)=>{if(s.warn("extractor - ",t,m(e),e.children("D")),t>10){s.error("Bailing out");return}let n=e.nodes(),r=!1;for(const i of n){const a=e.children(i);r=r||a.length>0}if(!r){s.debug("Done, no node has children",e.nodes());return}s.debug("Nodes = ",n,t);for(const i of n)if(s.debug("Extracting node",i,l,l[i]&&!l[i].externalConnections,!e.parent(i),e.node(i),e.children("D")," Depth ",t),!l[i])s.debug("Not a cluster",i,t);else if(!l[i].externalConnections&&e.children(i)&&e.children(i).length>0){s.warn("Cluster without external connections, without a parent and with children",i,t);let d=e.graph().rankdir==="TB"?"LR":"TB";l[i]&&l[i].clusterData&&l[i].clusterData.dir&&(d=l[i].clusterData.dir,s.warn("Fixing dir",l[i].clusterData.dir,d));const u=new A({multigraph:!0,compound:!0}).setGraph({rankdir:d,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});s.warn("Old graph before copy",m(e)),P(i,e,u,i),e.setNode(i,{clusterNode:!0,id:i,clusterData:l[i].clusterData,labelText:l[i].labelText,graph:u}),s.warn("New graph after copy node: (",i,")",m(u)),s.debug("Old graph after copy",m(e))}else s.warn("Cluster ** ",i," **not meeting the criteria !externalConnections:",!l[i].externalConnections," no parent: ",!e.parent(i)," children ",e.children(i)&&e.children(i).length>0,e.children("D"),t),s.debug(l);n=e.nodes(),s.warn("New list of nodes",n);for(const i of n){const a=e.node(i);s.warn(" Now next level",i,a),a.clusterNode&&F(a.graph,t+1)}},G=(e,t)=>{if(t.length===0)return[];let n=Object.assign(t);return t.forEach(r=>{const i=e.children(r),a=G(e,i);n=[...n,...a]}),n},rt=e=>G(e,e.children()),at=(e,t)=>{s.info("Creating subgraph rect for ",t.id,t);const n=T(),r=e.insert("g").attr("class","cluster"+(t.class?" "+t.class:"")).attr("id",t.id),i=r.insert("rect",":first-child"),a=S(n.flowchart.htmlLabels),d=r.insert("g").attr("class","cluster-label"),u=t.labelType==="markdown"?I(d,t.labelText,{style:t.labelStyle,useHtmlLabels:a}):d.node().appendChild(J(t.labelText,t.labelStyle,void 0,!0));let f=u.getBBox();if(S(n.flowchart.htmlLabels)){const c=u.children[0],o=L(u);f=c.getBoundingClientRect(),o.attr("width",f.width),o.attr("height",f.height)}const h=0*t.padding,w=h/2,x=t.width<=f.width+h?f.width+h:t.width;t.width<=f.width+h?t.diff=(f.width-t.width)/2-t.padding/2:t.diff=-t.padding/2,s.trace("Data ",t,JSON.stringify(t)),i.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-x/2).attr("y",t.y-t.height/2-w).attr("width",x).attr("height",t.height+h);const{subGraphTitleTopMargin:v}=D(n);a?d.attr("transform",`translate(${t.x-f.width/2}, ${t.y-t.height/2+v})`):d.attr("transform",`translate(${t.x}, ${t.y-t.height/2+v})`);const y=i.node().getBBox();return t.width=y.width,t.height=y.height,t.intersect=function(c){return p(t,c)},r},ct=(e,t)=>{const n=e.insert("g").attr("class","note-cluster").attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,a=i/2;r.attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-t.width/2-a).attr("y",t.y-t.height/2-a).attr("width",t.width+i).attr("height",t.height+i).attr("fill","none");const d=r.node().getBBox();return t.width=d.width,t.height=d.height,t.intersect=function(u){return p(t,u)},n},ot=(e,t)=>{const n=T(),r=e.insert("g").attr("class",t.classes).attr("id",t.id),i=r.insert("rect",":first-child"),a=r.insert("g").attr("class","cluster-label"),d=r.append("rect"),u=a.node().appendChild(J(t.labelText,t.labelStyle,void 0,!0));let f=u.getBBox();if(S(n.flowchart.htmlLabels)){const c=u.children[0],o=L(u);f=c.getBoundingClientRect(),o.attr("width",f.width),o.attr("height",f.height)}f=u.getBBox();const h=0*t.padding,w=h/2,x=t.width<=f.width+t.padding?f.width+t.padding:t.width;t.width<=f.width+t.padding?t.diff=(f.width+t.padding*0-t.width)/2:t.diff=-t.padding/2,i.attr("class","outer").attr("x",t.x-x/2-w).attr("y",t.y-t.height/2-w).attr("width",x+h).attr("height",t.height+h),d.attr("class","inner").attr("x",t.x-x/2-w).attr("y",t.y-t.height/2-w+f.height-1).attr("width",x+h).attr("height",t.height+h-f.height-3);const{subGraphTitleTopMargin:v}=D(n);a.attr("transform",`translate(${t.x-f.width/2}, ${t.y-t.height/2-t.padding/3+(S(n.flowchart.htmlLabels)?5:3)+v})`);const y=i.node().getBBox();return t.height=y.height,t.intersect=function(c){return p(t,c)},r},lt=(e,t)=>{const n=e.insert("g").attr("class",t.classes).attr("id",t.id),r=n.insert("rect",":first-child"),i=0*t.padding,a=i/2;r.attr("class","divider").attr("x",t.x-t.width/2-a).attr("y",t.y-t.height/2).attr("width",t.width+i).attr("height",t.height+i);const d=r.node().getBBox();return t.width=d.width,t.height=d.height,t.diff=-t.padding/2,t.intersect=function(u){return p(t,u)},n},ft={rect:at,roundedWithTitle:ot,noteGroup:ct,divider:lt};let j={};const dt=(e,t)=>{s.trace("Inserting cluster");const n=t.shape||"rect";j[t.id]=ft[n](e,t)},ut=()=>{j={}},M=async(e,t,n,r,i,a)=>{s.info("Graph in recursive render: XXX",m(t),i);const d=t.graph().rankdir;s.trace("Dir in recursive render - dir:",d);const u=e.insert("g").attr("class","root");t.nodes()?s.info("Recursive render XXX",t.nodes()):s.info("No nodes found for",t),t.edges().length>0&&s.trace("Recursive edges",t.edge(t.edges()[0]));const f=u.insert("g").attr("class","clusters"),h=u.insert("g").attr("class","edgePaths"),w=u.insert("g").attr("class","edgeLabels"),x=u.insert("g").attr("class","nodes");await Promise.all(t.nodes().map(async function(c){const o=t.node(c);if(i!==void 0){const b=JSON.parse(JSON.stringify(i.clusterData));s.info("Setting data for cluster XXX (",c,") ",b,i),t.setNode(i.id,b),t.parent(c)||(s.trace("Setting parent",c,i.id),t.setParent(c,i.id,b))}if(s.info("(Insert) Node XXX"+c+": "+JSON.stringify(t.node(c))),o&&o.clusterNode){s.info("Cluster identified",c,o.width,t.node(c));const b=await M(x,o.graph,n,r,t.node(c),a),E=b.elem;U(o,E),o.diff=b.diff||0,s.info("Node bounds (abc123)",c,o,o.width,o.x,o.y),W(E,o),s.warn("Recursive render complete ",E,o)}else t.children(c).length>0?(s.info("Cluster - the non recursive path XXX",c,o.id,o,t),s.info(C(o.id,t)),l[o.id]={id:C(o.id,t),node:o}):(s.info("Node - the non recursive path",c,o.id,o),await _(x,t.node(c),d))})),t.edges().forEach(function(c){const o=t.edge(c.v,c.w,c.name);s.info("Edge "+c.v+" -> "+c.w+": "+JSON.stringify(c)),s.info("Edge "+c.v+" -> "+c.w+": ",c," ",JSON.stringify(t.edge(c))),s.info("Fix",l,"ids:",c.v,c.w,"Translating: ",l[c.v],l[c.w]),z(w,o)}),t.edges().forEach(function(c){s.info("Edge "+c.v+" -> "+c.w+": "+JSON.stringify(c))}),s.info("#############################################"),s.info("###                Layout                 ###"),s.info("#############################################"),s.info(t),q(t),s.info("Graph after layout:",m(t));let v=0;const{subGraphTitleTotalMargin:y}=D(a);return rt(t).forEach(function(c){const o=t.node(c);s.info("Position "+c+": "+JSON.stringify(t.node(c))),s.info("Position "+c+": ("+o.x,","+o.y,") width: ",o.width," height: ",o.height),o&&o.clusterNode?(o.y+=y,O(o)):t.children(c).length>0?(o.height+=y,dt(f,o),l[o.id].node=o):(o.y+=y/2,O(o))}),t.edges().forEach(function(c){const o=t.edge(c);s.info("Edge "+c.v+" -> "+c.w+": "+JSON.stringify(o),o),o.points.forEach(E=>E.y+=y/2);const b=K(h,c,o,l,n,t,r);Q(o,b)}),t.nodes().forEach(function(c){const o=t.node(c);s.info(c,o.type,o.diff),o.type==="group"&&(v=o.diff)}),{elem:u,diff:v}},bt=async(e,t,n,r,i)=>{V(e,n,r,i),Y(),Z(),ut(),nt(),s.warn("Graph at first:",JSON.stringify(m(t))),st(t),s.warn("Graph after:",JSON.stringify(m(t)));const a=T();await M(e,t,r,i,void 0,a)};export{bt as r};
                        diff --git a/assets/index.html-9pCVMb8K.js b/assets/index.html-GzgMAJYU.js
                        similarity index 98%
                        rename from assets/index.html-9pCVMb8K.js
                        rename to assets/index.html-GzgMAJYU.js
                        index ea69d94776..6f2c5e6840 100644
                        --- a/assets/index.html-9pCVMb8K.js
                        +++ b/assets/index.html-GzgMAJYU.js
                        @@ -1 +1 @@
                        -import{_ as l,r as a,o as i,c as h,a as t,d as n,w as s,b as e}from"./app-PDrbPfzp.js";const _={},c=t("h1",{id:"进阶文档",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#进阶文档"},[t("span",null,"进阶文档")])],-1),u=t("p",null,[t("strong",null,"这个章节包含进阶级的 Xray 使用心得分享, 如果您已经熟悉 Xray, 那么这里的经验可以让您更加发挥 Xray 的威力")],-1),d=t("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),p={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},m=t("p",null,"透明代理的入门篇章。",-1),g=t("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32",height:"32",alt:"a"},null,-1),f={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},b=t("p",null,"基于 Xray 的透明代理(TProxy)配置完整教程。",-1),y=t("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),v={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},x=t("p",null,"基于 Xray 的 TProxy 透明代理(ipv4 and ipv6)配置教程",-1),k=t("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),w={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},X=t("p",null,"双端使用 Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹",-1),L=t("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),T={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},S=t("p",null,"在 iptables/nftables 实现的透明代理中,一种新的规避 Xray 流量的方式。",-1),B=t("img",{src:"https://avatars.githubusercontent.com/u/28607089?s=32",width:"32",height:"32",alt:"a"},null,-1),C={href:"https://github.com/Zzz3m",target:"_blank",rel:"noopener noreferrer"},N=t("p",null,"将 Xray 玩出花:基于 fwmark 、 sendThrough 或 sockopt.interface 方式实现“分流”。",-1),z=t("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),P={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},Q=t("p",null,"Xray v1.6.5 新增 WireGuard 出站的使用介绍。",-1),E=t("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),V={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},H=t("p",null,"适配 Xray 的流量统计和脚本。",-1);function I(R,W){const o=a("RouterLink"),r=a("ExternalLinkIcon");return i(),h("div",null,[c,u,t("p",null,[n(o,{to:"/document/level-2/transparent_proxy/transparent_proxy.html"},{default:s(()=>[e("透明代理入门")]),_:1}),e(" by "),d,e(),t("a",p,[e("@kirin"),n(r)])]),m,t("p",null,[n(o,{to:"/document/level-2/tproxy.html"},{default:s(()=>[e("透明代理(TProxy)配置教程 ")]),_:1}),e(" by "),g,e(),t("a",f,[e("@BioniCosmos"),n(r)])]),b,t("p",null,[n(o,{to:"/document/level-2/tproxy_ipv4_and_ipv6.html"},{default:s(()=>[e("TProxy 透明代理(ipv4 and ipv6)配置教程")]),_:1}),e(" by "),y,e(),t("a",v,[e("@SQLimit"),n(r)])]),x,t("p",null,[n(o,{to:"/document/level-2/nginx_or_haproxy_tls_tunnel.html"},{default:s(()=>[e("Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹")]),_:1}),e(" by "),k,e(),t("a",w,[e("@SQLimit"),n(r)])]),X,t("p",null,[n(o,{to:"/document/level-2/iptables_gid.html"},{default:s(()=>[e("[透明代理]通过 gid 规避 Xray 流量")]),_:1}),e(" by "),L,e(),t("a",T,[e("@kirin"),n(r)])]),S,t("p",null,[n(o,{to:"/document/level-2/redirect.html"},{default:s(()=>[e("通过 Xray 将特定的流量指向特定出口,实现全局路由“分流”")]),_:1}),e(" by "),B,e(),t("a",C,[e("@Zzz3m"),n(r)])]),N,t("p",null,[n(o,{to:"/document/level-2/warp.html"},{default:s(()=>[e("通过 Cloudflare Warp 增强代理安全性")]),_:1}),e(" by "),z,e(),t("a",P,[e("@yuhan6665"),n(r)])]),Q,t("p",null,[n(o,{to:"/document/level-2/traffic_stats.html"},{default:s(()=>[e("Xray 流量统计")]),_:1}),e(" by "),E,e(),t("a",V,[e("@yuhan6665"),n(r)])]),H])}const G=l(_,[["render",I],["__file","index.html.vue"]]);export{G as default};
                        +import{_ as l,r as a,o as i,c as h,a as t,d as n,w as s,b as e}from"./app-UOvWaKji.js";const _={},c=t("h1",{id:"进阶文档",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#进阶文档"},[t("span",null,"进阶文档")])],-1),u=t("p",null,[t("strong",null,"这个章节包含进阶级的 Xray 使用心得分享, 如果您已经熟悉 Xray, 那么这里的经验可以让您更加发挥 Xray 的威力")],-1),d=t("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),p={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},m=t("p",null,"透明代理的入门篇章。",-1),g=t("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32",height:"32",alt:"a"},null,-1),f={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},b=t("p",null,"基于 Xray 的透明代理(TProxy)配置完整教程。",-1),y=t("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),v={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},x=t("p",null,"基于 Xray 的 TProxy 透明代理(ipv4 and ipv6)配置教程",-1),k=t("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),w={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},X=t("p",null,"双端使用 Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹",-1),L=t("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),T={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},S=t("p",null,"在 iptables/nftables 实现的透明代理中,一种新的规避 Xray 流量的方式。",-1),B=t("img",{src:"https://avatars.githubusercontent.com/u/28607089?s=32",width:"32",height:"32",alt:"a"},null,-1),C={href:"https://github.com/Zzz3m",target:"_blank",rel:"noopener noreferrer"},N=t("p",null,"将 Xray 玩出花:基于 fwmark 、 sendThrough 或 sockopt.interface 方式实现“分流”。",-1),z=t("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),P={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},Q=t("p",null,"Xray v1.6.5 新增 WireGuard 出站的使用介绍。",-1),E=t("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),V={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},H=t("p",null,"适配 Xray 的流量统计和脚本。",-1);function I(R,W){const o=a("RouterLink"),r=a("ExternalLinkIcon");return i(),h("div",null,[c,u,t("p",null,[n(o,{to:"/document/level-2/transparent_proxy/transparent_proxy.html"},{default:s(()=>[e("透明代理入门")]),_:1}),e(" by "),d,e(),t("a",p,[e("@kirin"),n(r)])]),m,t("p",null,[n(o,{to:"/document/level-2/tproxy.html"},{default:s(()=>[e("透明代理(TProxy)配置教程 ")]),_:1}),e(" by "),g,e(),t("a",f,[e("@BioniCosmos"),n(r)])]),b,t("p",null,[n(o,{to:"/document/level-2/tproxy_ipv4_and_ipv6.html"},{default:s(()=>[e("TProxy 透明代理(ipv4 and ipv6)配置教程")]),_:1}),e(" by "),y,e(),t("a",v,[e("@SQLimit"),n(r)])]),x,t("p",null,[n(o,{to:"/document/level-2/nginx_or_haproxy_tls_tunnel.html"},{default:s(()=>[e("Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹")]),_:1}),e(" by "),k,e(),t("a",w,[e("@SQLimit"),n(r)])]),X,t("p",null,[n(o,{to:"/document/level-2/iptables_gid.html"},{default:s(()=>[e("[透明代理]通过 gid 规避 Xray 流量")]),_:1}),e(" by "),L,e(),t("a",T,[e("@kirin"),n(r)])]),S,t("p",null,[n(o,{to:"/document/level-2/redirect.html"},{default:s(()=>[e("通过 Xray 将特定的流量指向特定出口,实现全局路由“分流”")]),_:1}),e(" by "),B,e(),t("a",C,[e("@Zzz3m"),n(r)])]),N,t("p",null,[n(o,{to:"/document/level-2/warp.html"},{default:s(()=>[e("通过 Cloudflare Warp 增强代理安全性")]),_:1}),e(" by "),z,e(),t("a",P,[e("@yuhan6665"),n(r)])]),Q,t("p",null,[n(o,{to:"/document/level-2/traffic_stats.html"},{default:s(()=>[e("Xray 流量统计")]),_:1}),e(" by "),E,e(),t("a",V,[e("@yuhan6665"),n(r)])]),H])}const G=l(_,[["render",I],["__file","index.html.vue"]]);export{G as default};
                        diff --git a/assets/index.html-OGTuF_nH.js b/assets/index.html-JMYPbZuF.js
                        similarity index 97%
                        rename from assets/index.html-OGTuF_nH.js
                        rename to assets/index.html-JMYPbZuF.js
                        index 12a49c214c..97b0abafbc 100644
                        --- a/assets/index.html-OGTuF_nH.js
                        +++ b/assets/index.html-JMYPbZuF.js
                        @@ -1 +1 @@
                        -import{_ as r,r as c,o as s,c as u,a as t,b as e,d as l,w as o}from"./app-PDrbPfzp.js";const d={},h=t("h1",{id:"小小白白话文",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#小小白白话文"},[t("span",null,"小小白白话文")])],-1),_=t("p",null,[t("strong",null,"这个章节是【从零开始】的基础课,新来的同学好好看好好学哦")],-1),i={class:"custom-container tip"},m=t("p",{class:"custom-container-title"},"提示",-1),p={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"};function f(v,x){const a=c("ExternalLinkIcon"),n=c("RouterLink");return s(),u("div",null,[h,_,t("div",i,[m,t("p",null,[e("Made with ❤️ by "),t("a",p,[e("@ricuhkaen"),l(a)])])]),t("p",null,[l(n,{to:"/document/level-0/ch01-preface.html"},{default:o(()=>[e("【第 1 章】 前言罗嗦篇")]),_:1}),e(" - 机场还是自建?这是个问题")]),t("p",null,[l(n,{to:"/document/level-0/ch02-preparation.html"},{default:o(()=>[e("【第 2 章】 原料准备篇")]),_:1}),e(" - 工欲善其事,必先利其器")]),t("p",null,[l(n,{to:"/document/level-0/ch03-ssh.html"},{default:o(()=>[e("【第 3 章】 远程登录篇")]),_:1}),e(" - 一桥飞架南北,天堑变通途")]),t("p",null,[l(n,{to:"/document/level-0/ch04-security.html"},{default:o(()=>[e("【第 4 章】 安全防护篇")]),_:1}),e(" - 安全不注意,亲人两行泪")]),t("p",null,[l(n,{to:"/document/level-0/ch05-webpage.html"},{default:o(()=>[e("【第 5 章】 网站建设篇")]),_:1}),e(" - 秀出你的美")]),t("p",null,[l(n,{to:"/document/level-0/ch06-certificates.html"},{default:o(()=>[e("【第 6 章】 证书管理篇")]),_:1}),e(" - 领证的才是合法的")]),t("p",null,[l(n,{to:"/document/level-0/ch07-xray-server.html"},{default:o(()=>[e("【第 7 章】 Xray 服务器篇")]),_:1}),e(" - 终于等到你")]),t("p",null,[l(n,{to:"/document/level-0/ch08-xray-clients.html"},{default:o(()=>[e("【第 8 章】 Xray 客户端篇")]),_:1}),e(" - 新的开始")]),t("p",null,[l(n,{to:"/document/level-0/ch09-appendix.html"},{default:o(()=>[e("【第 9 章】 附录")]),_:1}),e(" - 考点都在这里")])])}const b=r(d,[["render",f],["__file","index.html.vue"]]);export{b as default};
                        +import{_ as r,r as c,o as s,c as u,a as t,b as e,d as l,w as o}from"./app-UOvWaKji.js";const d={},h=t("h1",{id:"小小白白话文",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#小小白白话文"},[t("span",null,"小小白白话文")])],-1),_=t("p",null,[t("strong",null,"这个章节是【从零开始】的基础课,新来的同学好好看好好学哦")],-1),i={class:"custom-container tip"},m=t("p",{class:"custom-container-title"},"提示",-1),p={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"};function f(v,x){const a=c("ExternalLinkIcon"),n=c("RouterLink");return s(),u("div",null,[h,_,t("div",i,[m,t("p",null,[e("Made with ❤️ by "),t("a",p,[e("@ricuhkaen"),l(a)])])]),t("p",null,[l(n,{to:"/document/level-0/ch01-preface.html"},{default:o(()=>[e("【第 1 章】 前言罗嗦篇")]),_:1}),e(" - 机场还是自建?这是个问题")]),t("p",null,[l(n,{to:"/document/level-0/ch02-preparation.html"},{default:o(()=>[e("【第 2 章】 原料准备篇")]),_:1}),e(" - 工欲善其事,必先利其器")]),t("p",null,[l(n,{to:"/document/level-0/ch03-ssh.html"},{default:o(()=>[e("【第 3 章】 远程登录篇")]),_:1}),e(" - 一桥飞架南北,天堑变通途")]),t("p",null,[l(n,{to:"/document/level-0/ch04-security.html"},{default:o(()=>[e("【第 4 章】 安全防护篇")]),_:1}),e(" - 安全不注意,亲人两行泪")]),t("p",null,[l(n,{to:"/document/level-0/ch05-webpage.html"},{default:o(()=>[e("【第 5 章】 网站建设篇")]),_:1}),e(" - 秀出你的美")]),t("p",null,[l(n,{to:"/document/level-0/ch06-certificates.html"},{default:o(()=>[e("【第 6 章】 证书管理篇")]),_:1}),e(" - 领证的才是合法的")]),t("p",null,[l(n,{to:"/document/level-0/ch07-xray-server.html"},{default:o(()=>[e("【第 7 章】 Xray 服务器篇")]),_:1}),e(" - 终于等到你")]),t("p",null,[l(n,{to:"/document/level-0/ch08-xray-clients.html"},{default:o(()=>[e("【第 8 章】 Xray 客户端篇")]),_:1}),e(" - 新的开始")]),t("p",null,[l(n,{to:"/document/level-0/ch09-appendix.html"},{default:o(()=>[e("【第 9 章】 附录")]),_:1}),e(" - 考点都在这里")])])}const b=r(d,[["render",f],["__file","index.html.vue"]]);export{b as default};
                        diff --git a/assets/index.html-glFsxwLj.js b/assets/index.html-RZwWF3O4.js
                        similarity index 98%
                        rename from assets/index.html-glFsxwLj.js
                        rename to assets/index.html-RZwWF3O4.js
                        index 77282e97dc..fdca50b4b1 100644
                        --- a/assets/index.html-glFsxwLj.js
                        +++ b/assets/index.html-RZwWF3O4.js
                        @@ -1 +1 @@
                        -import{_ as r,r as a,o as i,c,a as e,b as o,d as t,w as s}from"./app-PDrbPfzp.js";const d={},p=e("h1",{id:"development-guide",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#development-guide"},[e("span",null,"Development Guide")])],-1),h=e("h2",{id:"compile-documentation",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#compile-documentation"},[e("span",null,"Compile Documentation")])],-1),m=e("p",null,"Xray supports multiple platforms, and you can perform cross-compilation on various platforms by yourself.",-1),u=e("h2",{id:"design-concept",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#design-concept"},[e("span",null,"Design Concept")])],-1),_=e("p",null,"Xray kernel provides a platform for secondary development.",-1),f=e("p",null,"This section explains the design goals and architecture of Xray.",-1),v=e("h2",{id:"development-standards",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#development-standards"},[e("span",null,"Development Standards")])],-1),g=e("p",null,"This section outlines the guidelines to follow when obtaining code, developing, submitting PRs, as well as the relevant coding standards.",-1),x=e("h2",{id:"protocol-details",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#protocol-details"},[e("span",null,"Protocol Details")])],-1),b=e("p",null,"Xray uses many protocols, and you can obtain a detailed description of each protocol through various means.",-1),y={id:"vless-protocol",tabindex:"-1"},k={class:"header-anchor",href:"#vless-protocol"},w=e("p",null,"VLESS is a stateless lightweight transport protocol that can serve as a bridge between Xray clients and servers.",-1),P={id:"vmess-protocol",tabindex:"-1"},C={class:"header-anchor",href:"#vmess-protocol"},D=e("p",null,"VMess is an encrypted transport protocol that can act as a bridge between Xray clients and servers.",-1),X={id:"mux-cool-protocol",tabindex:"-1"},V={class:"header-anchor",href:"#mux-cool-protocol"},L=e("p",null,"Mux.Cool protocol is a multiplexing transport protocol used to transmit multiple independent data streams within an established data stream.",-1),S={id:"mkcp-protocol",tabindex:"-1"},E={class:"header-anchor",href:"#mkcp-protocol"},M={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"};function B(K,N){const n=a("RouterLink"),l=a("ExternalLinkIcon");return i(),c("div",null,[p,h,m,e("p",null,[o("Please click "),t(n,{to:"/en/development/intro/compile.html"},{default:s(()=>[o("Compile Documentation")]),_:1}),o(" to view specific compile-related content.")]),u,_,f,e("p",null,[o("Please click "),t(n,{to:"/en/development/intro/design.html"},{default:s(()=>[o("Design Principles")]),_:1}),o(" to learn about the design goals and architecture of Xray.")]),v,g,e("p",null,[o("Please click "),t(n,{to:"/en/development/intro/guide.html"},{default:s(()=>[o("Development Specification")]),_:1}),o(" to view the guidelines that should be followed during Xray development.")]),x,b,e("h3",y,[e("a",k,[e("span",null,[t(n,{to:"/en/development/protocols/vless.html"},{default:s(()=>[o("VLESS Protocol")]),_:1})])])]),w,e("h3",P,[e("a",C,[e("span",null,[t(n,{to:"/en/development/protocols/vmess.html"},{default:s(()=>[o("VMess Protocol")]),_:1})])])]),D,e("h3",X,[e("a",V,[e("span",null,[t(n,{to:"/en/development/protocols/muxcool.html"},{default:s(()=>[o("Mux.Cool Protocol")]),_:1})])])]),L,e("h3",S,[e("a",E,[e("span",null,[t(n,{to:"/en/development/protocols/mkcp.html"},{default:s(()=>[o("mKCP Protocol")]),_:1})])])]),e("p",null,[o("mKCP is a stream transmission protocol modified from the "),e("a",M,[o("KCP protocol"),t(l)]),o(" that can transmit arbitrary data streams in order.")])])}const T=r(d,[["render",B],["__file","index.html.vue"]]);export{T as default};
                        +import{_ as r,r as a,o as i,c,a as e,b as o,d as t,w as s}from"./app-UOvWaKji.js";const d={},p=e("h1",{id:"development-guide",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#development-guide"},[e("span",null,"Development Guide")])],-1),h=e("h2",{id:"compile-documentation",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#compile-documentation"},[e("span",null,"Compile Documentation")])],-1),m=e("p",null,"Xray supports multiple platforms, and you can perform cross-compilation on various platforms by yourself.",-1),u=e("h2",{id:"design-concept",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#design-concept"},[e("span",null,"Design Concept")])],-1),_=e("p",null,"Xray kernel provides a platform for secondary development.",-1),f=e("p",null,"This section explains the design goals and architecture of Xray.",-1),v=e("h2",{id:"development-standards",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#development-standards"},[e("span",null,"Development Standards")])],-1),g=e("p",null,"This section outlines the guidelines to follow when obtaining code, developing, submitting PRs, as well as the relevant coding standards.",-1),x=e("h2",{id:"protocol-details",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#protocol-details"},[e("span",null,"Protocol Details")])],-1),b=e("p",null,"Xray uses many protocols, and you can obtain a detailed description of each protocol through various means.",-1),y={id:"vless-protocol",tabindex:"-1"},k={class:"header-anchor",href:"#vless-protocol"},w=e("p",null,"VLESS is a stateless lightweight transport protocol that can serve as a bridge between Xray clients and servers.",-1),P={id:"vmess-protocol",tabindex:"-1"},C={class:"header-anchor",href:"#vmess-protocol"},D=e("p",null,"VMess is an encrypted transport protocol that can act as a bridge between Xray clients and servers.",-1),X={id:"mux-cool-protocol",tabindex:"-1"},V={class:"header-anchor",href:"#mux-cool-protocol"},L=e("p",null,"Mux.Cool protocol is a multiplexing transport protocol used to transmit multiple independent data streams within an established data stream.",-1),S={id:"mkcp-protocol",tabindex:"-1"},E={class:"header-anchor",href:"#mkcp-protocol"},M={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"};function B(K,N){const n=a("RouterLink"),l=a("ExternalLinkIcon");return i(),c("div",null,[p,h,m,e("p",null,[o("Please click "),t(n,{to:"/en/development/intro/compile.html"},{default:s(()=>[o("Compile Documentation")]),_:1}),o(" to view specific compile-related content.")]),u,_,f,e("p",null,[o("Please click "),t(n,{to:"/en/development/intro/design.html"},{default:s(()=>[o("Design Principles")]),_:1}),o(" to learn about the design goals and architecture of Xray.")]),v,g,e("p",null,[o("Please click "),t(n,{to:"/en/development/intro/guide.html"},{default:s(()=>[o("Development Specification")]),_:1}),o(" to view the guidelines that should be followed during Xray development.")]),x,b,e("h3",y,[e("a",k,[e("span",null,[t(n,{to:"/en/development/protocols/vless.html"},{default:s(()=>[o("VLESS Protocol")]),_:1})])])]),w,e("h3",P,[e("a",C,[e("span",null,[t(n,{to:"/en/development/protocols/vmess.html"},{default:s(()=>[o("VMess Protocol")]),_:1})])])]),D,e("h3",X,[e("a",V,[e("span",null,[t(n,{to:"/en/development/protocols/muxcool.html"},{default:s(()=>[o("Mux.Cool Protocol")]),_:1})])])]),L,e("h3",S,[e("a",E,[e("span",null,[t(n,{to:"/en/development/protocols/mkcp.html"},{default:s(()=>[o("mKCP Protocol")]),_:1})])])]),e("p",null,[o("mKCP is a stream transmission protocol modified from the "),e("a",M,[o("KCP protocol"),t(l)]),o(" that can transmit arbitrary data streams in order.")])])}const T=r(d,[["render",B],["__file","index.html.vue"]]);export{T as default};
                        diff --git a/assets/index.html-DEQtxzNJ.js b/assets/index.html-W0PzUpCJ.js
                        similarity index 98%
                        rename from assets/index.html-DEQtxzNJ.js
                        rename to assets/index.html-W0PzUpCJ.js
                        index b0c8669a8b..29b1ae3171 100644
                        --- a/assets/index.html-DEQtxzNJ.js
                        +++ b/assets/index.html-W0PzUpCJ.js
                        @@ -1 +1 @@
                        -import{_ as d,r as l,o as c,c as h,a as e,b as o,d as t,w as s}from"./app-PDrbPfzp.js";const r={},_=e("h1",{id:"开发指南",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#开发指南"},[e("span",null,"开发指南")])],-1),i=e("h2",{id:"编译文档",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#编译文档"},[e("span",null,"编译文档")])],-1),p=e("p",null,"Xray 支持各种平台, 您可以在多种平台上自行进行交叉编译。",-1),u=e("h2",{id:"设计思路",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#设计思路"},[e("span",null,"设计思路")])],-1),m=e("p",null,"Xray 内核提供了一个平台,在其之上可以进二次开发。",-1),f=e("p",null,"这个章节阐述了 Xray 的设计目标和架构。",-1),x=e("h2",{id:"开发规范",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#开发规范"},[e("span",null,"开发规范")])],-1),v=e("p",null,"这个章节阐述了获取代码,进行开发,提交 PR 的流程中需要遵循的准则, 以及相关的编码规范。",-1),b=e("h2",{id:"协议详解",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#协议详解"},[e("span",null,"协议详解")])],-1),k=e("p",null,"Xray 用到了很多种协议, 您可以通过各种途径获得协议的详细描述。",-1),y={id:"vless-协议",tabindex:"-1"},X={class:"header-anchor",href:"#vless-协议"},C=e("p",null,"VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。",-1),V={id:"vmess-协议",tabindex:"-1"},L={class:"header-anchor",href:"#vmess-协议"},E=e("p",null,"VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。",-1),g={id:"mux-cool-协议",tabindex:"-1"},M={class:"header-anchor",href:"#mux-cool-协议"},P=e("p",null,"Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。",-1),S={id:"mkcp-协议",tabindex:"-1"},w={class:"header-anchor",href:"#mkcp-协议"},B={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"};function K(N,R){const n=l("RouterLink"),a=l("ExternalLinkIcon");return c(),h("div",null,[_,i,p,e("p",null,[o("请点击"),t(n,{to:"/development/intro/compile.html"},{default:s(()=>[o("编译文档")]),_:1}),o("以查看具体编译相关内容。")]),u,m,f,e("p",null,[o("请点击"),t(n,{to:"/development/intro/design.html"},{default:s(()=>[o("设计思路")]),_:1}),o("以了解 Xray 的设计目标和架构。")]),x,v,e("p",null,[o("请点击"),t(n,{to:"/development/intro/guide.html"},{default:s(()=>[o("开发规范")]),_:1}),o("查看 Xray 开发中应遵循的准则。")]),b,k,e("h3",y,[e("a",X,[e("span",null,[t(n,{to:"/development/protocols/vless.html"},{default:s(()=>[o("VLESS 协议")]),_:1})])])]),C,e("h3",V,[e("a",L,[e("span",null,[t(n,{to:"/development/protocols/vmess.html"},{default:s(()=>[o("VMess 协议")]),_:1})])])]),E,e("h3",g,[e("a",M,[e("span",null,[t(n,{to:"/development/protocols/muxcool.html"},{default:s(()=>[o("Mux.Cool 协议")]),_:1})])])]),P,e("h3",S,[e("a",w,[e("span",null,[t(n,{to:"/development/protocols/mkcp.html"},{default:s(()=>[o("mKCP 协议")]),_:1})])])]),e("p",null,[o("mKCP 是流式传输协议,由 "),e("a",B,[o("KCP 协议"),t(a)]),o("修改而来,可以按顺序传输任意的数据流。")])])}const T=d(r,[["render",K],["__file","index.html.vue"]]);export{T as default};
                        +import{_ as d,r as l,o as c,c as h,a as e,b as o,d as t,w as s}from"./app-UOvWaKji.js";const r={},_=e("h1",{id:"开发指南",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#开发指南"},[e("span",null,"开发指南")])],-1),i=e("h2",{id:"编译文档",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#编译文档"},[e("span",null,"编译文档")])],-1),p=e("p",null,"Xray 支持各种平台, 您可以在多种平台上自行进行交叉编译。",-1),u=e("h2",{id:"设计思路",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#设计思路"},[e("span",null,"设计思路")])],-1),m=e("p",null,"Xray 内核提供了一个平台,在其之上可以进二次开发。",-1),f=e("p",null,"这个章节阐述了 Xray 的设计目标和架构。",-1),x=e("h2",{id:"开发规范",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#开发规范"},[e("span",null,"开发规范")])],-1),v=e("p",null,"这个章节阐述了获取代码,进行开发,提交 PR 的流程中需要遵循的准则, 以及相关的编码规范。",-1),b=e("h2",{id:"协议详解",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#协议详解"},[e("span",null,"协议详解")])],-1),k=e("p",null,"Xray 用到了很多种协议, 您可以通过各种途径获得协议的详细描述。",-1),y={id:"vless-协议",tabindex:"-1"},X={class:"header-anchor",href:"#vless-协议"},C=e("p",null,"VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。",-1),V={id:"vmess-协议",tabindex:"-1"},L={class:"header-anchor",href:"#vmess-协议"},E=e("p",null,"VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。",-1),g={id:"mux-cool-协议",tabindex:"-1"},M={class:"header-anchor",href:"#mux-cool-协议"},P=e("p",null,"Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。",-1),S={id:"mkcp-协议",tabindex:"-1"},w={class:"header-anchor",href:"#mkcp-协议"},B={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"};function K(N,R){const n=l("RouterLink"),a=l("ExternalLinkIcon");return c(),h("div",null,[_,i,p,e("p",null,[o("请点击"),t(n,{to:"/development/intro/compile.html"},{default:s(()=>[o("编译文档")]),_:1}),o("以查看具体编译相关内容。")]),u,m,f,e("p",null,[o("请点击"),t(n,{to:"/development/intro/design.html"},{default:s(()=>[o("设计思路")]),_:1}),o("以了解 Xray 的设计目标和架构。")]),x,v,e("p",null,[o("请点击"),t(n,{to:"/development/intro/guide.html"},{default:s(()=>[o("开发规范")]),_:1}),o("查看 Xray 开发中应遵循的准则。")]),b,k,e("h3",y,[e("a",X,[e("span",null,[t(n,{to:"/development/protocols/vless.html"},{default:s(()=>[o("VLESS 协议")]),_:1})])])]),C,e("h3",V,[e("a",L,[e("span",null,[t(n,{to:"/development/protocols/vmess.html"},{default:s(()=>[o("VMess 协议")]),_:1})])])]),E,e("h3",g,[e("a",M,[e("span",null,[t(n,{to:"/development/protocols/muxcool.html"},{default:s(()=>[o("Mux.Cool 协议")]),_:1})])])]),P,e("h3",S,[e("a",w,[e("span",null,[t(n,{to:"/development/protocols/mkcp.html"},{default:s(()=>[o("mKCP 协议")]),_:1})])])]),e("p",null,[o("mKCP 是流式传输协议,由 "),e("a",B,[o("KCP 协议"),t(a)]),o("修改而来,可以按顺序传输任意的数据流。")])])}const T=d(r,[["render",K],["__file","index.html.vue"]]);export{T as default};
                        diff --git a/assets/index.html-_vJQzZ80.js b/assets/index.html-cm8hOcNA.js
                        similarity index 99%
                        rename from assets/index.html-_vJQzZ80.js
                        rename to assets/index.html-cm8hOcNA.js
                        index 9921d4df3d..e1904ff82f 100644
                        --- a/assets/index.html-_vJQzZ80.js
                        +++ b/assets/index.html-cm8hOcNA.js
                        @@ -1,4 +1,4 @@
                        -import{_ as e,r as p,o as l,c,a as n,b as s,d as a,w as o,e as u}from"./app-PDrbPfzp.js";const i={},r=u(`

                        这个章节将告诉您所有的 Xray 配置细节,掌握这些内容,在您手中 Xray 将发挥更大威力。

                        概述

                        Xray 的配置文件为 json 格式, 客户端和服务端的配置格式没有区别, 只是实际的配置内容不一样。
                        形式如下:

                        {
                        +import{_ as e,r as p,o as l,c,a as n,b as s,d as a,w as o,e as u}from"./app-UOvWaKji.js";const i={},r=u(`

                        这个章节将告诉您所有的 Xray 配置细节,掌握这些内容,在您手中 Xray 将发挥更大威力。

                        概述

                        Xray 的配置文件为 json 格式, 客户端和服务端的配置格式没有区别, 只是实际的配置内容不一样。
                        形式如下:

                        {
                           "log": {},
                           "api": {},
                           "dns": {},
                        diff --git a/assets/index.html-Mbhofp-W.js b/assets/index.html-ecj8aV3P.js
                        similarity index 98%
                        rename from assets/index.html-Mbhofp-W.js
                        rename to assets/index.html-ecj8aV3P.js
                        index 7dff5aec01..dd1810171f 100644
                        --- a/assets/index.html-Mbhofp-W.js
                        +++ b/assets/index.html-ecj8aV3P.js
                        @@ -1 +1 @@
                        -import{_ as s,r as i,o as l,c as h,a as t,d as n,w as a,b as e}from"./app-PDrbPfzp.js";const c={},u=t("h1",{id:"advanced-documentation",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#advanced-documentation"},[t("span",null,"Advanced Documentation")])],-1),d=t("p",null,[t("strong",null,"This chapter contains experience sharing of using Xray at an advanced level. If you are already familiar with Xray, the experience shared here can help you unleash the full power of Xray.")],-1),_=t("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),p={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},m=t("p",null,"An Introduction to Transparent Proxies.",-1),g=t("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32",height:"32",alt:"a"},null,-1),f={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},y=t("p",null,"Complete tutorial on configuring transparent proxy (TProxy) based on Xray.",-1),b=t("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),v={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},x=t("p",null,"Xray-based TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial",-1),T=t("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),k={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},w=t("p",null,"Use Nginx_TLS tunnel on both ends to hide the fingerprint.",-1),P=t("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),X={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},L=t("p",null,"A new way of bypassing Xray traffic in transparent proxy implemented by iptables/nftables.",-1),I=t("img",{src:"https://avatars.githubusercontent.com/u/28607089?s=32",width:"32",height:"32",alt:"a"},null,-1),S={href:"https://github.com/Zzz3m",target:"_blank",rel:"noopener noreferrer"},C=t("p",null,'Play Xray to the fullest: Implement "load balancing" based on fwmark or sendThrough.',-1),B=t("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),A={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},N=t("p",null,"Introduction to using WireGuard for outbound traffic added in Xray v1.6.5.",-1),z=t("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),E={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},G=t("p",null,"Adapt traffic statistics and scripts compatible with Xray.",-1);function Q(R,V){const o=i("RouterLink"),r=i("ExternalLinkIcon");return l(),h("div",null,[u,d,t("p",null,[n(o,{to:"/en/document/level-2/transparent_proxy/transparent_proxy.html"},{default:a(()=>[e("Beginner's Guide to Transparent Proxies")]),_:1}),e(" by "),_,e(),t("a",p,[e("@kirin"),n(r)])]),m,t("p",null,[n(o,{to:"/en/document/level-2/tproxy.html"},{default:a(()=>[e("TProxy Configuration Tutorial")]),_:1}),e(" by "),g,e(),t("a",f,[e("@BioniCosmos"),n(r)])]),y,t("p",null,[n(o,{to:"/en/document/level-2/tproxy_ipv4_and_ipv6.html"},{default:a(()=>[e("TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial")]),_:1}),e(" by "),b,e(),t("a",v,[e("@SQLimit"),n(r)])]),x,t("p",null,[n(o,{to:"/en/document/level-2/nginx_or_haproxy_tls_tunnel.html"},{default:a(()=>[e("Nginx_TLS Tunnel Hidden Fingerprint")]),_:1}),e(" by "),T,e(),t("a",k,[e("@SQLimit"),n(r)])]),w,t("p",null,[n(o,{to:"/en/document/level-2/iptables_gid.html"},{default:a(()=>[e("[Transparent Proxy] Avoiding Xray Traffic Through gid")]),_:1}),e(" by "),P,e(),t("a",X,[e("@kirin"),n(r)])]),L,t("p",null,[n(o,{to:"/en/document/level-2/redirect.html"},{default:a(()=>[e('Redirect Specific Traffic to Specific Gateway using Xray to Achieve Global Routing "Load Balancing"')]),_:1}),e(" by "),I,e(),t("a",S,[e("@Zzz3m"),n(r)])]),C,t("p",null,[n(o,{to:"/en/document/level-2/warp.html"},{default:a(()=>[e("Enhancing Proxy Security with Cloudflare Warp")]),_:1}),e(" by "),B,e(),t("a",A,[e("@yuhan6665"),n(r)])]),N,t("p",null,[n(o,{to:"/en/document/level-2/traffic_stats.html"},{default:a(()=>[e("Xray Traffic Statistics")]),_:1}),e(" by "),z,e(),t("a",E,[e("@yuhan6665"),n(r)])]),G])}const Z=s(c,[["render",Q],["__file","index.html.vue"]]);export{Z as default};
                        +import{_ as s,r as i,o as l,c as h,a as t,d as n,w as a,b as e}from"./app-UOvWaKji.js";const c={},u=t("h1",{id:"advanced-documentation",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#advanced-documentation"},[t("span",null,"Advanced Documentation")])],-1),d=t("p",null,[t("strong",null,"This chapter contains experience sharing of using Xray at an advanced level. If you are already familiar with Xray, the experience shared here can help you unleash the full power of Xray.")],-1),_=t("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),p={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},m=t("p",null,"An Introduction to Transparent Proxies.",-1),g=t("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32",height:"32",alt:"a"},null,-1),f={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},y=t("p",null,"Complete tutorial on configuring transparent proxy (TProxy) based on Xray.",-1),b=t("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),v={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},x=t("p",null,"Xray-based TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial",-1),T=t("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),k={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},w=t("p",null,"Use Nginx_TLS tunnel on both ends to hide the fingerprint.",-1),P=t("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),X={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},L=t("p",null,"A new way of bypassing Xray traffic in transparent proxy implemented by iptables/nftables.",-1),I=t("img",{src:"https://avatars.githubusercontent.com/u/28607089?s=32",width:"32",height:"32",alt:"a"},null,-1),S={href:"https://github.com/Zzz3m",target:"_blank",rel:"noopener noreferrer"},C=t("p",null,'Play Xray to the fullest: Implement "load balancing" based on fwmark or sendThrough.',-1),B=t("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),A={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},N=t("p",null,"Introduction to using WireGuard for outbound traffic added in Xray v1.6.5.",-1),z=t("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),E={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},G=t("p",null,"Adapt traffic statistics and scripts compatible with Xray.",-1);function Q(R,V){const o=i("RouterLink"),r=i("ExternalLinkIcon");return l(),h("div",null,[u,d,t("p",null,[n(o,{to:"/en/document/level-2/transparent_proxy/transparent_proxy.html"},{default:a(()=>[e("Beginner's Guide to Transparent Proxies")]),_:1}),e(" by "),_,e(),t("a",p,[e("@kirin"),n(r)])]),m,t("p",null,[n(o,{to:"/en/document/level-2/tproxy.html"},{default:a(()=>[e("TProxy Configuration Tutorial")]),_:1}),e(" by "),g,e(),t("a",f,[e("@BioniCosmos"),n(r)])]),y,t("p",null,[n(o,{to:"/en/document/level-2/tproxy_ipv4_and_ipv6.html"},{default:a(()=>[e("TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial")]),_:1}),e(" by "),b,e(),t("a",v,[e("@SQLimit"),n(r)])]),x,t("p",null,[n(o,{to:"/en/document/level-2/nginx_or_haproxy_tls_tunnel.html"},{default:a(()=>[e("Nginx_TLS Tunnel Hidden Fingerprint")]),_:1}),e(" by "),T,e(),t("a",k,[e("@SQLimit"),n(r)])]),w,t("p",null,[n(o,{to:"/en/document/level-2/iptables_gid.html"},{default:a(()=>[e("[Transparent Proxy] Avoiding Xray Traffic Through gid")]),_:1}),e(" by "),P,e(),t("a",X,[e("@kirin"),n(r)])]),L,t("p",null,[n(o,{to:"/en/document/level-2/redirect.html"},{default:a(()=>[e('Redirect Specific Traffic to Specific Gateway using Xray to Achieve Global Routing "Load Balancing"')]),_:1}),e(" by "),I,e(),t("a",S,[e("@Zzz3m"),n(r)])]),C,t("p",null,[n(o,{to:"/en/document/level-2/warp.html"},{default:a(()=>[e("Enhancing Proxy Security with Cloudflare Warp")]),_:1}),e(" by "),B,e(),t("a",A,[e("@yuhan6665"),n(r)])]),N,t("p",null,[n(o,{to:"/en/document/level-2/traffic_stats.html"},{default:a(()=>[e("Xray Traffic Statistics")]),_:1}),e(" by "),z,e(),t("a",E,[e("@yuhan6665"),n(r)])]),G])}const Z=s(c,[["render",Q],["__file","index.html.vue"]]);export{Z as default};
                        diff --git a/assets/index.html-UNm3UMUZ.js b/assets/index.html-gKKe0Pu1.js
                        similarity index 98%
                        rename from assets/index.html-UNm3UMUZ.js
                        rename to assets/index.html-gKKe0Pu1.js
                        index 0d21257e09..138c97340f 100644
                        --- a/assets/index.html-UNm3UMUZ.js
                        +++ b/assets/index.html-gKKe0Pu1.js
                        @@ -1 +1 @@
                        -import{_ as s,r as l,o as r,c as i,a as e,b as t,d as a,w as o}from"./app-PDrbPfzp.js";const d={},c=e("h1",{id:"quick-start",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#quick-start"},[e("span",null,"Quick Start")])],-1),u=e("blockquote",null,[e("p",null,[e("strong",null,"This chapter will tell you how to get Xray in the easiest way and start using Xray.")])],-1),h=e("h2",{id:"download-and-install",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#download-and-install"},[e("span",null,"Download and Install")])],-1),m=e("p",null,"Xray supports various platforms, and you can get various versions of Xray from various sources and methods.",-1),p=e("h2",{id:"configure-and-run",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configure-and-run"},[e("span",null,"Configure and Run")])],-1),_=e("p",null,"After downloading and installing Xray, you need to configure it.",-1),f=e("h2",{id:"command-parameters",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#command-parameters"},[e("span",null,"Command Parameters")])],-1),g=e("p",null,"Xray has a variety of commands and parameters available, making it flexible and powerful.",-1),v=e("h2",{id:"improve-documents",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#improve-documents"},[e("span",null,"Improve Documents")])],-1),y=e("code",null,"Help us improve this page!",-1),k=e("p",null,"We are very grateful to every Contributor for their contribution! You guys make Project X even stronger!",-1),w=e("h2",{id:"beginner-tutorial",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#beginner-tutorial"},[e("span",null,"Beginner Tutorial")])],-1),b=e("p",null,"A easy tutorial for beginner.",-1),x=e("h2",{id:"getting-started-tips",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#getting-started-tips"},[e("span",null,"Getting Started Tips")])],-1),X=e("h2",{id:"advanced-documentation",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#advanced-documentation"},[e("span",null,"Advanced Documentation")])],-1),C=e("p",null,"Tips for advanced user guidance",-1),P=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"Appreciations"),e("p",null,"Thank you very much for your selfless sharing of usage skills and experience, which makes Xray more and more powerful.")],-1);function T(A,D){const n=l("RouterLink");return r(),i("div",null,[c,u,h,m,e("p",null,[t("Please click "),a(n,{to:"/en/document/install.html"},{default:o(()=>[t("How to Download and Install Xray")]),_:1}),t(" to get Xray")]),p,_,e("p",null,[t("Please click "),a(n,{to:"/en/document/config.html"},{default:o(()=>[t("How to Configure and Run Xray")]),_:1}),t(" to learn the easiest way to configure Xray.")]),f,g,e("p",null,[t("Please click "),a(n,{to:"/en/document/command.html"},{default:o(()=>[t("Command Parameters for Xray")]),_:1}),t(" to view more commands and parameters usages.")]),v,e("p",null,[t("If you're interested, please click "),a(n,{to:"/en/document/document.html"},{default:o(()=>[t("Documents")]),_:1}),t(" to help us improve the documents, or click the"),y]),k,w,b,e("p",null,[t("Please click "),a(n,{to:"/en/document/level-0/"},{default:o(()=>[t("小小白白话文")]),_:1}),t(" to view it.")]),x,e("p",null,[t("After you have the basics, you can explore more ways to use them through "),a(n,{to:"/en/document/level-1/"},{default:o(()=>[t("Getting Started Tips")]),_:1}),t(".")]),X,C,e("p",null,[t("Click on "),a(n,{to:"/en/document/level-2/"},{default:o(()=>[t("Advanced Documentation")]),_:1}),t(" to view it")]),P])}const I=s(d,[["render",T],["__file","index.html.vue"]]);export{I as default};
                        +import{_ as s,r as l,o as r,c as i,a as e,b as t,d as a,w as o}from"./app-UOvWaKji.js";const d={},c=e("h1",{id:"quick-start",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#quick-start"},[e("span",null,"Quick Start")])],-1),u=e("blockquote",null,[e("p",null,[e("strong",null,"This chapter will tell you how to get Xray in the easiest way and start using Xray.")])],-1),h=e("h2",{id:"download-and-install",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#download-and-install"},[e("span",null,"Download and Install")])],-1),m=e("p",null,"Xray supports various platforms, and you can get various versions of Xray from various sources and methods.",-1),p=e("h2",{id:"configure-and-run",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#configure-and-run"},[e("span",null,"Configure and Run")])],-1),_=e("p",null,"After downloading and installing Xray, you need to configure it.",-1),f=e("h2",{id:"command-parameters",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#command-parameters"},[e("span",null,"Command Parameters")])],-1),g=e("p",null,"Xray has a variety of commands and parameters available, making it flexible and powerful.",-1),v=e("h2",{id:"improve-documents",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#improve-documents"},[e("span",null,"Improve Documents")])],-1),y=e("code",null,"Help us improve this page!",-1),k=e("p",null,"We are very grateful to every Contributor for their contribution! You guys make Project X even stronger!",-1),w=e("h2",{id:"beginner-tutorial",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#beginner-tutorial"},[e("span",null,"Beginner Tutorial")])],-1),b=e("p",null,"A easy tutorial for beginner.",-1),x=e("h2",{id:"getting-started-tips",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#getting-started-tips"},[e("span",null,"Getting Started Tips")])],-1),X=e("h2",{id:"advanced-documentation",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#advanced-documentation"},[e("span",null,"Advanced Documentation")])],-1),C=e("p",null,"Tips for advanced user guidance",-1),P=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"Appreciations"),e("p",null,"Thank you very much for your selfless sharing of usage skills and experience, which makes Xray more and more powerful.")],-1);function T(A,D){const n=l("RouterLink");return r(),i("div",null,[c,u,h,m,e("p",null,[t("Please click "),a(n,{to:"/en/document/install.html"},{default:o(()=>[t("How to Download and Install Xray")]),_:1}),t(" to get Xray")]),p,_,e("p",null,[t("Please click "),a(n,{to:"/en/document/config.html"},{default:o(()=>[t("How to Configure and Run Xray")]),_:1}),t(" to learn the easiest way to configure Xray.")]),f,g,e("p",null,[t("Please click "),a(n,{to:"/en/document/command.html"},{default:o(()=>[t("Command Parameters for Xray")]),_:1}),t(" to view more commands and parameters usages.")]),v,e("p",null,[t("If you're interested, please click "),a(n,{to:"/en/document/document.html"},{default:o(()=>[t("Documents")]),_:1}),t(" to help us improve the documents, or click the"),y]),k,w,b,e("p",null,[t("Please click "),a(n,{to:"/en/document/level-0/"},{default:o(()=>[t("小小白白话文")]),_:1}),t(" to view it.")]),x,e("p",null,[t("After you have the basics, you can explore more ways to use them through "),a(n,{to:"/en/document/level-1/"},{default:o(()=>[t("Getting Started Tips")]),_:1}),t(".")]),X,C,e("p",null,[t("Click on "),a(n,{to:"/en/document/level-2/"},{default:o(()=>[t("Advanced Documentation")]),_:1}),t(" to view it")]),P])}const I=s(d,[["render",T],["__file","index.html.vue"]]);export{I as default};
                        diff --git a/assets/index.html-xynTfTar.js b/assets/index.html-l5bGGUL1.js
                        similarity index 94%
                        rename from assets/index.html-xynTfTar.js
                        rename to assets/index.html-l5bGGUL1.js
                        index 37812eb5bd..f4eaba3f84 100644
                        --- a/assets/index.html-xynTfTar.js
                        +++ b/assets/index.html-l5bGGUL1.js
                        @@ -1 +1 @@
                        -import{_ as a,r,o as c,c as s,a as e,d as l,w as n,b as o}from"./app-PDrbPfzp.js";const u={},d=e("h1",{id:"入门技巧",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#入门技巧"},[e("span",null,"入门技巧")])],-1),_=e("p",null,[e("strong",null,"这个章节是入门级的 Xray 使用心得分享,主要分享一些 Xray 常用功能模块的原理说明。")],-1);function i(m,f){const t=r("RouterLink");return c(),s("div",null,[d,_,e("p",null,[l(t,{to:"/document/level-1/fallbacks-lv1.html"},{default:n(()=>[o("回落 (fallbacks) 功能简析")]),_:1})]),e("p",null,[l(t,{to:"/document/level-1/routing-lv1-part1.html"},{default:n(()=>[o("路由 (routing) 功能简析(上)")]),_:1})]),e("p",null,[l(t,{to:"/document/level-1/routing-lv1-part2.html"},{default:n(()=>[o("路由 (routing) 功能简析(下)")]),_:1})]),e("p",null,[l(t,{to:"/document/level-1/work.html"},{default:n(()=>[o("Xray 的工作模式简析")]),_:1})]),e("p",null,[l(t,{to:"/document/level-1/fallbacks-with-sni.html"},{default:n(()=>[o("通过 SNI 回落功能实现伪装与按域名分流")]),_:1})])])}const p=a(u,[["render",i],["__file","index.html.vue"]]);export{p as default};
                        +import{_ as a,r,o as c,c as s,a as e,d as l,w as n,b as o}from"./app-UOvWaKji.js";const u={},d=e("h1",{id:"入门技巧",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#入门技巧"},[e("span",null,"入门技巧")])],-1),_=e("p",null,[e("strong",null,"这个章节是入门级的 Xray 使用心得分享,主要分享一些 Xray 常用功能模块的原理说明。")],-1);function i(m,f){const t=r("RouterLink");return c(),s("div",null,[d,_,e("p",null,[l(t,{to:"/document/level-1/fallbacks-lv1.html"},{default:n(()=>[o("回落 (fallbacks) 功能简析")]),_:1})]),e("p",null,[l(t,{to:"/document/level-1/routing-lv1-part1.html"},{default:n(()=>[o("路由 (routing) 功能简析(上)")]),_:1})]),e("p",null,[l(t,{to:"/document/level-1/routing-lv1-part2.html"},{default:n(()=>[o("路由 (routing) 功能简析(下)")]),_:1})]),e("p",null,[l(t,{to:"/document/level-1/work.html"},{default:n(()=>[o("Xray 的工作模式简析")]),_:1})]),e("p",null,[l(t,{to:"/document/level-1/fallbacks-with-sni.html"},{default:n(()=>[o("通过 SNI 回落功能实现伪装与按域名分流")]),_:1})])])}const p=a(u,[["render",i],["__file","index.html.vue"]]);export{p as default};
                        diff --git a/assets/index.html-ihOMAxW0.js b/assets/index.html-p2MYx25S.js
                        similarity index 94%
                        rename from assets/index.html-ihOMAxW0.js
                        rename to assets/index.html-p2MYx25S.js
                        index 7e156c897a..b306c1c7de 100644
                        --- a/assets/index.html-ihOMAxW0.js
                        +++ b/assets/index.html-p2MYx25S.js
                        @@ -1 +1 @@
                        -import{_ as a,r as s,o as i,c as r,a as e,d as t,w as l,b as o}from"./app-PDrbPfzp.js";const u={},c=e("h1",{id:"beginner-s-tips",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#beginner-s-tips"},[e("span",null,"Beginner's Tips")])],-1),d=e("p",null,[e("strong",null,"This chapter is an introductory level guide on using Xray, mainly sharing the principles of some commonly used functional modules in Xray.")],-1);function m(_,f){const n=s("RouterLink");return i(),r("div",null,[c,d,e("p",null,[t(n,{to:"/en/document/level-1/fallbacks-lv1.html"},{default:l(()=>[o("Analysis of Fallbacks Function")]),_:1})]),e("p",null,[t(n,{to:"/en/document/level-1/routing-lv1-part1.html"},{default:l(()=>[o("Analysis of Routing Function (Part 1)")]),_:1})]),e("p",null,[t(n,{to:"/en/document/level-1/routing-lv1-part2.html"},{default:l(()=>[o("Analysis of Routing Function (Part 2)")]),_:1})]),e("p",null,[t(n,{to:"/en/document/level-1/work.html"},{default:l(()=>[o("Analysis of Xray's Working Mode")]),_:1})]),e("p",null,[t(n,{to:"/en/document/level-1/fallbacks-with-sni.html"},{default:l(()=>[o("Fallbacks with SNI for Disguising and Domain-based Routing")]),_:1})])])}const p=a(u,[["render",m],["__file","index.html.vue"]]);export{p as default};
                        +import{_ as a,r as s,o as i,c as r,a as e,d as t,w as l,b as o}from"./app-UOvWaKji.js";const u={},c=e("h1",{id:"beginner-s-tips",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#beginner-s-tips"},[e("span",null,"Beginner's Tips")])],-1),d=e("p",null,[e("strong",null,"This chapter is an introductory level guide on using Xray, mainly sharing the principles of some commonly used functional modules in Xray.")],-1);function m(_,f){const n=s("RouterLink");return i(),r("div",null,[c,d,e("p",null,[t(n,{to:"/en/document/level-1/fallbacks-lv1.html"},{default:l(()=>[o("Analysis of Fallbacks Function")]),_:1})]),e("p",null,[t(n,{to:"/en/document/level-1/routing-lv1-part1.html"},{default:l(()=>[o("Analysis of Routing Function (Part 1)")]),_:1})]),e("p",null,[t(n,{to:"/en/document/level-1/routing-lv1-part2.html"},{default:l(()=>[o("Analysis of Routing Function (Part 2)")]),_:1})]),e("p",null,[t(n,{to:"/en/document/level-1/work.html"},{default:l(()=>[o("Analysis of Xray's Working Mode")]),_:1})]),e("p",null,[t(n,{to:"/en/document/level-1/fallbacks-with-sni.html"},{default:l(()=>[o("Fallbacks with SNI for Disguising and Domain-based Routing")]),_:1})])])}const p=a(u,[["render",m],["__file","index.html.vue"]]);export{p as default};
                        diff --git a/assets/index.html-1LatBnTC.js b/assets/index.html-qxx9ljxd.js
                        similarity index 97%
                        rename from assets/index.html-1LatBnTC.js
                        rename to assets/index.html-qxx9ljxd.js
                        index 43a64fc9eb..8dc910b2dd 100644
                        --- a/assets/index.html-1LatBnTC.js
                        +++ b/assets/index.html-qxx9ljxd.js
                        @@ -1 +1 @@
                        -import{_ as i,r as l,o as c,c as s,a as e,b as t,d as n,w as o}from"./app-PDrbPfzp.js";const h={},u=e("h1",{id:"plain-and-simple-language",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#plain-and-simple-language"},[e("span",null,"Plain and Simple Language")])],-1),d=e("p",null,[e("strong",null,"This chapter is a basic lesson of [Starting from Scratch]. New students, please watch and learn carefully.")],-1),p={class:"custom-container tip"},_=e("p",{class:"custom-container-title"},"Tip",-1),m={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},f=e("p",null,"[【Chapter 5】Website Construction] - Show Your Beauty (Link to webpage.md file)",-1),g=e("p",null,"[Chapter 9] Appendix - All the exam points are here.",-1);function y(b,v){const r=l("ExternalLinkIcon"),a=l("RouterLink");return c(),s("div",null,[u,d,e("div",p,[_,e("p",null,[t("Made with ❤️ by "),e("a",m,[t("@ricuhkaen"),n(r)])])]),e("p",null,[n(a,{to:"/en/document/level-0/ch01-preface.html"},{default:o(()=>[t("【Chapter 1】 Preface: Rambling")]),_:1}),t(" - Airport or Self-built? That is the question.")]),e("p",null,[n(a,{to:"/en/document/level-0/ch02-preparation.html"},{default:o(()=>[t("Chapter 2: Preparation of Raw Materials")]),_:1}),t(" - Tools must be sharpened before they can be used proficiently.")]),e("p",null,[n(a,{to:"/en/document/level-0/ch03-ssh.html"},{default:o(()=>[t("Chapter 3: Remote Login")]),_:1}),t(" - A bridge connecting the north and south, turning a natural obstacle into a thoroughfare.")]),e("p",null,[n(a,{to:"/en/document/level-0/ch04-security.html"},{default:o(()=>[t("【Chapter 4】Security Protection")]),_:1}),t(" - If you don't pay attention to security, you will shed tears for your loved ones.")]),f,e("p",null,[n(a,{to:"/en/document/level-0/ch06-certificates.html"},{default:o(()=>[t("Chapter 6: Certificate Management")]),_:1}),t(" - Only those who obtain certificates are considered legitimate.")]),e("p",null,[n(a,{to:"/en/document/level-0/ch07-xray-server.html"},{default:o(()=>[t("Chapter 7: Xray Server")]),_:1}),t(" - Finally, waited for you.")]),e("p",null,[n(a,{to:"/en/document/level-0/ch08-xray-clients.html"},{default:o(()=>[t("Chapter 8: Xray Client")]),_:1}),t(" - A New Beginning.")]),g])}const C=i(h,[["render",y],["__file","index.html.vue"]]);export{C as default};
                        +import{_ as i,r as l,o as c,c as s,a as e,b as t,d as n,w as o}from"./app-UOvWaKji.js";const h={},u=e("h1",{id:"plain-and-simple-language",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#plain-and-simple-language"},[e("span",null,"Plain and Simple Language")])],-1),d=e("p",null,[e("strong",null,"This chapter is a basic lesson of [Starting from Scratch]. New students, please watch and learn carefully.")],-1),p={class:"custom-container tip"},_=e("p",{class:"custom-container-title"},"Tip",-1),m={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},f=e("p",null,"[【Chapter 5】Website Construction] - Show Your Beauty (Link to webpage.md file)",-1),g=e("p",null,"[Chapter 9] Appendix - All the exam points are here.",-1);function y(b,v){const r=l("ExternalLinkIcon"),a=l("RouterLink");return c(),s("div",null,[u,d,e("div",p,[_,e("p",null,[t("Made with ❤️ by "),e("a",m,[t("@ricuhkaen"),n(r)])])]),e("p",null,[n(a,{to:"/en/document/level-0/ch01-preface.html"},{default:o(()=>[t("【Chapter 1】 Preface: Rambling")]),_:1}),t(" - Airport or Self-built? That is the question.")]),e("p",null,[n(a,{to:"/en/document/level-0/ch02-preparation.html"},{default:o(()=>[t("Chapter 2: Preparation of Raw Materials")]),_:1}),t(" - Tools must be sharpened before they can be used proficiently.")]),e("p",null,[n(a,{to:"/en/document/level-0/ch03-ssh.html"},{default:o(()=>[t("Chapter 3: Remote Login")]),_:1}),t(" - A bridge connecting the north and south, turning a natural obstacle into a thoroughfare.")]),e("p",null,[n(a,{to:"/en/document/level-0/ch04-security.html"},{default:o(()=>[t("【Chapter 4】Security Protection")]),_:1}),t(" - If you don't pay attention to security, you will shed tears for your loved ones.")]),f,e("p",null,[n(a,{to:"/en/document/level-0/ch06-certificates.html"},{default:o(()=>[t("Chapter 6: Certificate Management")]),_:1}),t(" - Only those who obtain certificates are considered legitimate.")]),e("p",null,[n(a,{to:"/en/document/level-0/ch07-xray-server.html"},{default:o(()=>[t("Chapter 7: Xray Server")]),_:1}),t(" - Finally, waited for you.")]),e("p",null,[n(a,{to:"/en/document/level-0/ch08-xray-clients.html"},{default:o(()=>[t("Chapter 8: Xray Client")]),_:1}),t(" - A New Beginning.")]),g])}const C=i(h,[["render",y],["__file","index.html.vue"]]);export{C as default};
                        diff --git a/assets/index.html-AMhQDD2G.js b/assets/index.html-sJo1M-Sj.js
                        similarity index 98%
                        rename from assets/index.html-AMhQDD2G.js
                        rename to assets/index.html-sJo1M-Sj.js
                        index 1827a40ce2..c2ddaa7aad 100644
                        --- a/assets/index.html-AMhQDD2G.js
                        +++ b/assets/index.html-sJo1M-Sj.js
                        @@ -1 +1 @@
                        -import{_ as o,r as a,o as s,c as i,a as e,b as r,d as t,w as c,e as h}from"./app-PDrbPfzp.js";const u={},d=h('

                        XTLS ? Xray ? V2Ray ?

                        XTLS are brilliant ideas for TLS we study, while Xray is the best practice we maintain.

                        • Xray-core 是 v2ray-core 的超集,含更好的整体性能和 XTLS 等一系列增强,且完全兼容 v2ray-core 的功能及配置。
                          • 只有一个可执行文件,含 ctl 的功能,run 为默认指令
                          • 配置上完全兼容,环境变量和 API 对应要改为以 XRAY_ 开头
                          • 全平台开放了裸协议的 ReadV
                          • 提供完整的 VLESS & Trojan XTLS 支持,均有 ReadV
                          • 提供了 XTLS 多种流控模式, 性能一骑绝尘!

                        “配置兼容,整体更好”

                        我们是谁?

                        It doesn't matter who we are. What matters is that we will keep riding and never look back.

                        帮助 Xray 变得更强

                        欢迎帮助 Xray 变得更强!

                        ',8),_=e("li",null,"🖥️ 帮助开发和测试 Xray, 提交高质量的 Pull request.",-1),p={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},X={href:"https://github.com/XTLS/Xray-core/discussions",target:"_blank",rel:"noopener noreferrer"},b={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},f=e("li",null,"💬 在 Telegram 群帮助群友/灌水.",-1),m=e("li",null,[e("strong",null,"...事实上,每一份对 Xray 的支持都会让 Xray 变得更强大")],-1),g=e("h3",{id:"telegram",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#telegram"},[e("span",null,"Telegram")])],-1),y={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},x=e("ul",null,[e("li",null,"交流群可在底线之上随便水,不要撕逼,没有滥权。"),e("li",null,"有问题尽管随便问,知道的尽量回答。"),e("li",null,"禁政治,禁 NSFW")],-1),k={href:"https://t.me/projectXtls",target:"_blank",rel:"noopener noreferrer"},L=e("ul",null,[e("li",null,"发布 Project X 的最新资讯")],-1),S=e("h3",{id:"致谢",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#致谢"},[e("span",null,"致谢")])],-1),T=e("ul",null,[e("li",null,"感谢所有人的支持!"),e("li",null,"感谢各类脚本、Docker 镜像、客户端支持...感谢所有帮忙完善生态的大佬们!"),e("li",null,"感谢为 Xray 网站和文档添砖加瓦的朋友们."),e("li",null,"感谢提出有意义的建议和意见的朋友们."),e("li",null,"感谢 Telegram 群每一位帮助群友的朋友.")],-1),v=e("h3",{id:"更多关于-project-x",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#更多关于-project-x"},[e("span",null,"更多关于 Project X")])],-1),j=e("h3",{id:"license",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#license"},[e("span",null,"License")])],-1),w={href:"https://github.com/XTLS/Xray-core/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"},V=e("h3",{id:"stargazers-over-time",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#stargazers-over-time"},[e("span",null,"Stargazers over time")])],-1),P={href:"https://starchart.cc/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},E=e("img",{src:"https://starchart.cc/XTLS/Xray-core.svg",alt:"Stargazers over time"},null,-1);function I(N,R){const l=a("ExternalLinkIcon"),n=a("RouterLink");return s(),i("div",null,[d,e("ul",null,[_,e("li",null,[r("📩 在 "),e("a",p,[r("GitHub Issues"),t(l)]),r(" 或 "),e("a",X,[r("讨论区"),t(l)]),r("发起建设性或有意义的 issue 与 discussion.")]),e("li",null,[r("📝 写下您的使用心得并提交至 Xray 的 "),e("a",b,[r("文档网站"),t(l)]),r(".")]),f,m]),g,e("ul",null,[e("li",null,[e("p",null,[e("a",y,[r("Project X 交流群"),t(l)])]),x]),e("li",null,[e("p",null,[e("a",k,[r("Project X 频道"),t(l)])]),L])]),S,T,v,e("ul",null,[e("li",null,[r("如果你想知道更多关于 Project X 的足迹与成长, 请点击"),t(n,{to:"/about/news.html"},{default:c(()=>[r("这里")]),_:1})])]),j,e("p",null,[e("a",w,[r("Mozilla Public License Version 2.0"),t(l)])]),V,e("p",null,[e("a",P,[E,t(l)])])])}const z=o(u,[["render",I],["__file","index.html.vue"]]);export{z as default}; +import{_ as o,r as a,o as s,c as i,a as e,b as r,d as t,w as c,e as h}from"./app-UOvWaKji.js";const u={},d=h('

                        XTLS ? Xray ? V2Ray ?

                        XTLS are brilliant ideas for TLS we study, while Xray is the best practice we maintain.

                        • Xray-core 是 v2ray-core 的超集,含更好的整体性能和 XTLS 等一系列增强,且完全兼容 v2ray-core 的功能及配置。
                          • 只有一个可执行文件,含 ctl 的功能,run 为默认指令
                          • 配置上完全兼容,环境变量和 API 对应要改为以 XRAY_ 开头
                          • 全平台开放了裸协议的 ReadV
                          • 提供完整的 VLESS & Trojan XTLS 支持,均有 ReadV
                          • 提供了 XTLS 多种流控模式, 性能一骑绝尘!

                        “配置兼容,整体更好”

                        我们是谁?

                        It doesn't matter who we are. What matters is that we will keep riding and never look back.

                        帮助 Xray 变得更强

                        欢迎帮助 Xray 变得更强!

                        ',8),_=e("li",null,"🖥️ 帮助开发和测试 Xray, 提交高质量的 Pull request.",-1),p={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},X={href:"https://github.com/XTLS/Xray-core/discussions",target:"_blank",rel:"noopener noreferrer"},b={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},f=e("li",null,"💬 在 Telegram 群帮助群友/灌水.",-1),m=e("li",null,[e("strong",null,"...事实上,每一份对 Xray 的支持都会让 Xray 变得更强大")],-1),g=e("h3",{id:"telegram",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#telegram"},[e("span",null,"Telegram")])],-1),y={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},x=e("ul",null,[e("li",null,"交流群可在底线之上随便水,不要撕逼,没有滥权。"),e("li",null,"有问题尽管随便问,知道的尽量回答。"),e("li",null,"禁政治,禁 NSFW")],-1),k={href:"https://t.me/projectXtls",target:"_blank",rel:"noopener noreferrer"},L=e("ul",null,[e("li",null,"发布 Project X 的最新资讯")],-1),S=e("h3",{id:"致谢",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#致谢"},[e("span",null,"致谢")])],-1),T=e("ul",null,[e("li",null,"感谢所有人的支持!"),e("li",null,"感谢各类脚本、Docker 镜像、客户端支持...感谢所有帮忙完善生态的大佬们!"),e("li",null,"感谢为 Xray 网站和文档添砖加瓦的朋友们."),e("li",null,"感谢提出有意义的建议和意见的朋友们."),e("li",null,"感谢 Telegram 群每一位帮助群友的朋友.")],-1),v=e("h3",{id:"更多关于-project-x",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#更多关于-project-x"},[e("span",null,"更多关于 Project X")])],-1),j=e("h3",{id:"license",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#license"},[e("span",null,"License")])],-1),w={href:"https://github.com/XTLS/Xray-core/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"},V=e("h3",{id:"stargazers-over-time",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#stargazers-over-time"},[e("span",null,"Stargazers over time")])],-1),P={href:"https://starchart.cc/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},E=e("img",{src:"https://starchart.cc/XTLS/Xray-core.svg",alt:"Stargazers over time"},null,-1);function I(N,R){const l=a("ExternalLinkIcon"),n=a("RouterLink");return s(),i("div",null,[d,e("ul",null,[_,e("li",null,[r("📩 在 "),e("a",p,[r("GitHub Issues"),t(l)]),r(" 或 "),e("a",X,[r("讨论区"),t(l)]),r("发起建设性或有意义的 issue 与 discussion.")]),e("li",null,[r("📝 写下您的使用心得并提交至 Xray 的 "),e("a",b,[r("文档网站"),t(l)]),r(".")]),f,m]),g,e("ul",null,[e("li",null,[e("p",null,[e("a",y,[r("Project X 交流群"),t(l)])]),x]),e("li",null,[e("p",null,[e("a",k,[r("Project X 频道"),t(l)])]),L])]),S,T,v,e("ul",null,[e("li",null,[r("如果你想知道更多关于 Project X 的足迹与成长, 请点击"),t(n,{to:"/about/news.html"},{default:c(()=>[r("这里")]),_:1})])]),j,e("p",null,[e("a",w,[r("Mozilla Public License Version 2.0"),t(l)])]),V,e("p",null,[e("a",P,[E,t(l)])])])}const z=o(u,[["render",I],["__file","index.html.vue"]]);export{z as default}; diff --git a/assets/index.html-h67PRaMY.js b/assets/index.html-uM2EqCct.js similarity index 99% rename from assets/index.html-h67PRaMY.js rename to assets/index.html-uM2EqCct.js index 2075a2c665..b00ee1187a 100644 --- a/assets/index.html-h67PRaMY.js +++ b/assets/index.html-uM2EqCct.js @@ -1,4 +1,4 @@ -import{_ as e,r as l,o as c,c as i,a as n,b as t,d as o,w as a,e as u}from"./app-PDrbPfzp.js";const p={},r=u(`

                        This section will tell you all the details of Xray configuration. By mastering these contents, Xray will unleash its full power in your hands.

                        Overview

                        The configuration file of Xray is in JSON format, and the configuration format for the client and server is the same, except for the actual configuration content. It takes the following form:

                        {
                        +import{_ as e,r as l,o as c,c as i,a as n,b as t,d as o,w as a,e as u}from"./app-UOvWaKji.js";const p={},r=u(`

                        This section will tell you all the details of Xray configuration. By mastering these contents, Xray will unleash its full power in your hands.

                        Overview

                        The configuration file of Xray is in JSON format, and the configuration format for the client and server is the same, except for the actual configuration content. It takes the following form:

                        {
                           "log": {},
                           "api": {},
                           "dns": {},
                        diff --git a/assets/index.html-kLtDZulC.js b/assets/index.html-x0joMVfy.js
                        similarity index 98%
                        rename from assets/index.html-kLtDZulC.js
                        rename to assets/index.html-x0joMVfy.js
                        index 5bd9c412a1..84b3b4f2fd 100644
                        --- a/assets/index.html-kLtDZulC.js
                        +++ b/assets/index.html-x0joMVfy.js
                        @@ -1 +1 @@
                        -import{_ as a,r as s,o as c,c as d,a as e,b as t,d as l,w as o}from"./app-PDrbPfzp.js";const h={},r=e("h1",{id:"快速入门",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#快速入门"},[e("span",null,"快速入门")])],-1),_=e("blockquote",null,[e("p",null,[e("strong",null,"这个章节将告诉您如何用最简单的方式获得 Xray,并且开始使用 Xray。")])],-1),u=e("h2",{id:"下载安装",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#下载安装"},[e("span",null,"下载安装")])],-1),i=e("p",null,"Xray 支持各种平台,并且您可以从多种渠道和方式获得 Xray 的各种版本。",-1),p=e("h2",{id:"配置运行",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#配置运行"},[e("span",null,"配置运行")])],-1),m=e("p",null,"下载并安装 Xray 后,只需对他进行配置即可使用。",-1),f=e("h2",{id:"命令参数",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#命令参数"},[e("span",null,"命令参数")])],-1),x=e("p",null,"Xray 有多种命令和参数可用,因此变得灵活和强大。",-1),b=e("h2",{id:"改进文档",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#改进文档"},[e("span",null,"改进文档")])],-1),X=e("code",null,"帮助我们改善此页面!",-1),y=e("p",null,"我们十分感谢每一位 Contributor 作出的贡献!是你们让 Project X 变得更加强大!",-1),v=e("h2",{id:"小小白白话文",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#小小白白话文"},[e("span",null,"小小白白话文")])],-1),k=e("p",null,"给予新手指导的使用心得",-1),B=e("h2",{id:"入门技巧",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#入门技巧"},[e("span",null,"入门技巧")])],-1),C=e("h2",{id:"进阶文档",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#进阶文档"},[e("span",null,"进阶文档")])],-1),N=e("p",null,"给予进阶用户指导的使用技巧",-1),V=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"感谢"),e("p",null,"非常感谢大家无私分享使用技巧和心得, 使得 Xray 日益强大。")],-1);function g(w,L){const n=s("RouterLink");return c(),d("div",null,[r,_,u,i,e("p",null,[t("请点击 "),l(n,{to:"/document/install.html"},{default:o(()=>[t("下载安装")]),_:1}),t(" 以获取 Xray")]),p,m,e("p",null,[t("请点击 "),l(n,{to:"/document/config.html"},{default:o(()=>[t("配置运行")]),_:1}),t(" 以学习最简单的配置方式。")]),f,x,e("p",null,[t("请点击 "),l(n,{to:"/document/command.html"},{default:o(()=>[t("命令参数")]),_:1}),t(" 查看 Xray 的更多命令和参数用法。")]),b,e("p",null,[t("如果你有兴趣,请点击 "),l(n,{to:"/document/document.html"},{default:o(()=>[t("使用文档")]),_:1}),t(" 帮助我们改进文档,或者点击页面下方的 "),X]),y,v,k,e("p",null,[t("请点击 "),l(n,{to:"/document/level-0/"},{default:o(()=>[t("小小白白话文")]),_:1}),t(" 以进行查看。")]),B,e("p",null,[t("具备了基础之后,你就可以通过 "),l(n,{to:"/document/level-1/"},{default:o(()=>[t("入门技巧")]),_:1}),t(" 来探索更多的使用方式了。")]),C,N,e("p",null,[t("点击 "),l(n,{to:"/document/level-2/"},{default:o(()=>[t("进阶文档")]),_:1}),t(" 以进行查看")]),V])}const j=a(h,[["render",g],["__file","index.html.vue"]]);export{j as default};
                        +import{_ as a,r as s,o as c,c as d,a as e,b as t,d as l,w as o}from"./app-UOvWaKji.js";const h={},r=e("h1",{id:"快速入门",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#快速入门"},[e("span",null,"快速入门")])],-1),_=e("blockquote",null,[e("p",null,[e("strong",null,"这个章节将告诉您如何用最简单的方式获得 Xray,并且开始使用 Xray。")])],-1),u=e("h2",{id:"下载安装",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#下载安装"},[e("span",null,"下载安装")])],-1),i=e("p",null,"Xray 支持各种平台,并且您可以从多种渠道和方式获得 Xray 的各种版本。",-1),p=e("h2",{id:"配置运行",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#配置运行"},[e("span",null,"配置运行")])],-1),m=e("p",null,"下载并安装 Xray 后,只需对他进行配置即可使用。",-1),f=e("h2",{id:"命令参数",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#命令参数"},[e("span",null,"命令参数")])],-1),x=e("p",null,"Xray 有多种命令和参数可用,因此变得灵活和强大。",-1),b=e("h2",{id:"改进文档",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#改进文档"},[e("span",null,"改进文档")])],-1),X=e("code",null,"帮助我们改善此页面!",-1),y=e("p",null,"我们十分感谢每一位 Contributor 作出的贡献!是你们让 Project X 变得更加强大!",-1),v=e("h2",{id:"小小白白话文",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#小小白白话文"},[e("span",null,"小小白白话文")])],-1),k=e("p",null,"给予新手指导的使用心得",-1),B=e("h2",{id:"入门技巧",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#入门技巧"},[e("span",null,"入门技巧")])],-1),C=e("h2",{id:"进阶文档",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#进阶文档"},[e("span",null,"进阶文档")])],-1),N=e("p",null,"给予进阶用户指导的使用技巧",-1),V=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"感谢"),e("p",null,"非常感谢大家无私分享使用技巧和心得, 使得 Xray 日益强大。")],-1);function g(w,L){const n=s("RouterLink");return c(),d("div",null,[r,_,u,i,e("p",null,[t("请点击 "),l(n,{to:"/document/install.html"},{default:o(()=>[t("下载安装")]),_:1}),t(" 以获取 Xray")]),p,m,e("p",null,[t("请点击 "),l(n,{to:"/document/config.html"},{default:o(()=>[t("配置运行")]),_:1}),t(" 以学习最简单的配置方式。")]),f,x,e("p",null,[t("请点击 "),l(n,{to:"/document/command.html"},{default:o(()=>[t("命令参数")]),_:1}),t(" 查看 Xray 的更多命令和参数用法。")]),b,e("p",null,[t("如果你有兴趣,请点击 "),l(n,{to:"/document/document.html"},{default:o(()=>[t("使用文档")]),_:1}),t(" 帮助我们改进文档,或者点击页面下方的 "),X]),y,v,k,e("p",null,[t("请点击 "),l(n,{to:"/document/level-0/"},{default:o(()=>[t("小小白白话文")]),_:1}),t(" 以进行查看。")]),B,e("p",null,[t("具备了基础之后,你就可以通过 "),l(n,{to:"/document/level-1/"},{default:o(()=>[t("入门技巧")]),_:1}),t(" 来探索更多的使用方式了。")]),C,N,e("p",null,[t("点击 "),l(n,{to:"/document/level-2/"},{default:o(()=>[t("进阶文档")]),_:1}),t(" 以进行查看")]),V])}const j=a(h,[["render",g],["__file","index.html.vue"]]);export{j as default};
                        diff --git a/assets/index.html-e3Eb14uc.js b/assets/index.html-xbzqWGZe.js
                        similarity index 98%
                        rename from assets/index.html-e3Eb14uc.js
                        rename to assets/index.html-xbzqWGZe.js
                        index 36a799ea29..82dd88b522 100644
                        --- a/assets/index.html-e3Eb14uc.js
                        +++ b/assets/index.html-xbzqWGZe.js
                        @@ -1 +1 @@
                        -import{_ as l,r as n,o as s,c as i,a as e,b as t,d as o,w as c,e as h}from"./app-PDrbPfzp.js";const u={},d=h('

                        XTLS? Xray? V2Ray?

                        XTLS are brilliant ideas for TLS we study, while Xray is the best practice we maintain.

                        • Xray-core is a superset of v2ray-core, with better overall performance and enhancements such as XTLS, and it'scompletelycompatible with v2ray-core functionality and configuration.
                          • Only one executable file, including ctl functionality, run is the default command
                          • Configuration iscompletelycompatible, environment variables and API calls need to be changed to start with XRAY_
                          • Exposed raw protocol's ReadV on all platforms
                          • Provides complete VLESS & Trojan XTLS support, both with ReadV
                          • Provides multiple XTLS flow control modes, unrivaled performance!

                        "Configuration compatible, overall better"

                        Who are we?

                        It doesn't matter who we are. What matters is that we will keep riding and never look back.

                        Help Xray become stronger

                        Welcome to help Xray become stronger!

                        ',8),p=e("li",null,"🖥️ Help develop and test Xray, submit high-quality Pull requests.",-1),m={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},_={href:"https://github.com/XTLS/Xray-core/discussions",target:"_blank",rel:"noopener noreferrer"},b={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},f=e("li",null,"💬 Help group members/chat in Telegram group.",-1),g=e("li",null,[e("strong",null,"...In fact, every support for Xray will make Xray stronger")],-1),y=e("h3",{id:"telegram",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#telegram"},[e("span",null,"Telegram")])],-1),k={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},w=e("ul",null,[e("li",null,"You can chat freely above the bottom line in the discussion group, don't fight, no abuse of power."),e("li",null,"Feel free to ask questions, and try to answer those you know."),e("li",null,"No politics, No NSFW")],-1),X={href:"https://t.me/projectXtls",target:"_blank",rel:"noopener noreferrer"},v=e("ul",null,[e("li",null,"Publish the latest news of Project X")],-1),x=e("h3",{id:"thanks",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#thanks"},[e("span",null,"Thanks")])],-1),T=e("ul",null,[e("li",null,"Thanks to everyone for their support!"),e("li",null,"Thanks to all kinds of scripts, Docker images, client support... Thanks to all the big guys who helped improve the ecosystem!"),e("li",null,"Thanks to friends who have contributed to the Xray website and documentation."),e("li",null,"Thanks to friends who have made meaningful suggestions and comments."),e("li",null,"Thanks to every friend in the Telegram group who helps others.")],-1),L=e("h3",{id:"more-about-project-x",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#more-about-project-x"},[e("span",null,"More about project X")])],-1),S=e("h3",{id:"license",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#license"},[e("span",null,"License")])],-1),j={href:"https://github.com/XTLS/Xray-core/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"},q=e("h3",{id:"stargazers-over-time",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#stargazers-over-time"},[e("span",null,"Stargazers over time")])],-1),I={href:"https://starchart.cc/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},P=e("img",{src:"https://starchart.cc/XTLS/Xray-core.svg",alt:"Stargazers over time"},null,-1);function V(N,E){const r=n("ExternalLinkIcon"),a=n("RouterLink");return s(),i("div",null,[d,e("ul",null,[p,e("li",null,[t("📩 Initiate constructive or meaningful issues and discussions in "),e("a",m,[t("GitHub Issues"),o(r)]),t(" or "),e("a",_,[t("Discussion area"),o(r)]),t(".")]),e("li",null,[t("📝 Write down your usage experience and submit it to Xray's "),e("a",b,[t("documentation website"),o(r)]),t(".")]),f,g]),y,e("ul",null,[e("li",null,[e("p",null,[e("a",k,[t("Project X Discussion Group"),o(r)])]),w]),e("li",null,[e("p",null,[e("a",X,[t("Project X Channel"),o(r)])]),v])]),x,T,L,e("ul",null,[e("li",null,[t("If you would like to learn more about project X's history and growth, please click "),o(a,{to:"/en/about/news.html"},{default:c(()=>[t("here")]),_:1})])]),S,e("p",null,[e("a",j,[t("Mozilla Public License Version 2.0"),o(r)])]),q,e("p",null,[e("a",I,[P,o(r)])])])}const R=l(u,[["render",V],["__file","index.html.vue"]]);export{R as default}; +import{_ as l,r as n,o as s,c as i,a as e,b as t,d as o,w as c,e as h}from"./app-UOvWaKji.js";const u={},d=h('

                        XTLS? Xray? V2Ray?

                        XTLS are brilliant ideas for TLS we study, while Xray is the best practice we maintain.

                        • Xray-core is a superset of v2ray-core, with better overall performance and enhancements such as XTLS, and it'scompletelycompatible with v2ray-core functionality and configuration.
                          • Only one executable file, including ctl functionality, run is the default command
                          • Configuration iscompletelycompatible, environment variables and API calls need to be changed to start with XRAY_
                          • Exposed raw protocol's ReadV on all platforms
                          • Provides complete VLESS & Trojan XTLS support, both with ReadV
                          • Provides multiple XTLS flow control modes, unrivaled performance!

                        "Configuration compatible, overall better"

                        Who are we?

                        It doesn't matter who we are. What matters is that we will keep riding and never look back.

                        Help Xray become stronger

                        Welcome to help Xray become stronger!

                        ',8),p=e("li",null,"🖥️ Help develop and test Xray, submit high-quality Pull requests.",-1),m={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},_={href:"https://github.com/XTLS/Xray-core/discussions",target:"_blank",rel:"noopener noreferrer"},b={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},f=e("li",null,"💬 Help group members/chat in Telegram group.",-1),g=e("li",null,[e("strong",null,"...In fact, every support for Xray will make Xray stronger")],-1),y=e("h3",{id:"telegram",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#telegram"},[e("span",null,"Telegram")])],-1),k={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},w=e("ul",null,[e("li",null,"You can chat freely above the bottom line in the discussion group, don't fight, no abuse of power."),e("li",null,"Feel free to ask questions, and try to answer those you know."),e("li",null,"No politics, No NSFW")],-1),X={href:"https://t.me/projectXtls",target:"_blank",rel:"noopener noreferrer"},v=e("ul",null,[e("li",null,"Publish the latest news of Project X")],-1),x=e("h3",{id:"thanks",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#thanks"},[e("span",null,"Thanks")])],-1),T=e("ul",null,[e("li",null,"Thanks to everyone for their support!"),e("li",null,"Thanks to all kinds of scripts, Docker images, client support... Thanks to all the big guys who helped improve the ecosystem!"),e("li",null,"Thanks to friends who have contributed to the Xray website and documentation."),e("li",null,"Thanks to friends who have made meaningful suggestions and comments."),e("li",null,"Thanks to every friend in the Telegram group who helps others.")],-1),L=e("h3",{id:"more-about-project-x",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#more-about-project-x"},[e("span",null,"More about project X")])],-1),S=e("h3",{id:"license",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#license"},[e("span",null,"License")])],-1),j={href:"https://github.com/XTLS/Xray-core/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"},q=e("h3",{id:"stargazers-over-time",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#stargazers-over-time"},[e("span",null,"Stargazers over time")])],-1),I={href:"https://starchart.cc/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},P=e("img",{src:"https://starchart.cc/XTLS/Xray-core.svg",alt:"Stargazers over time"},null,-1);function V(N,E){const r=n("ExternalLinkIcon"),a=n("RouterLink");return s(),i("div",null,[d,e("ul",null,[p,e("li",null,[t("📩 Initiate constructive or meaningful issues and discussions in "),e("a",m,[t("GitHub Issues"),o(r)]),t(" or "),e("a",_,[t("Discussion area"),o(r)]),t(".")]),e("li",null,[t("📝 Write down your usage experience and submit it to Xray's "),e("a",b,[t("documentation website"),o(r)]),t(".")]),f,g]),y,e("ul",null,[e("li",null,[e("p",null,[e("a",k,[t("Project X Discussion Group"),o(r)])]),w]),e("li",null,[e("p",null,[e("a",X,[t("Project X Channel"),o(r)])]),v])]),x,T,L,e("ul",null,[e("li",null,[t("If you would like to learn more about project X's history and growth, please click "),o(a,{to:"/en/about/news.html"},{default:c(()=>[t("here")]),_:1})])]),S,e("p",null,[e("a",j,[t("Mozilla Public License Version 2.0"),o(r)])]),q,e("p",null,[e("a",I,[P,o(r)])])])}const R=l(u,[["render",V],["__file","index.html.vue"]]);export{R as default}; diff --git a/assets/infoDiagram-bcd20f53-aQsUByZm.js b/assets/infoDiagram-bcd20f53-qNUwp2oi.js similarity index 98% rename from assets/infoDiagram-bcd20f53-aQsUByZm.js rename to assets/infoDiagram-bcd20f53-qNUwp2oi.js index 90f34333c4..9a6d48988f 100644 --- a/assets/infoDiagram-bcd20f53-aQsUByZm.js +++ b/assets/infoDiagram-bcd20f53-qNUwp2oi.js @@ -1,4 +1,4 @@ -import{l as Y,aK as D,i as M}from"./mermaid.core-95b3ca__.js";import"./app-PDrbPfzp.js";var O=function(){var a=function(u,t,e,n){for(e=e||{},n=u.length;n--;e[u[n]]=t);return e},f=[6,9,10],m={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(t,e,n,s,r,i,d){switch(i.length-1,r){case 1:return s;case 4:break;case 6:s.setInfo(!0);break}},table:[{3:1,4:[1,2]},{1:[3]},a(f,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},a(f,[2,3]),a(f,[2,4]),a(f,[2,5]),a(f,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,e){if(e.recoverable)this.trace(t);else{var n=new Error(t);throw n.hash=e,n}},parse:function(t){var e=this,n=[0],s=[],r=[null],i=[],d=this.table,P="",v=0,L=0,N=2,T=1,R=i.slice.call(arguments,1),o=Object.create(this.lexer),p={yy:{}};for(var E in this.yy)Object.prototype.hasOwnProperty.call(this.yy,E)&&(p.yy[E]=this.yy[E]);o.setInput(t,p.yy),p.yy.lexer=o,p.yy.parser=this,typeof o.yylloc>"u"&&(o.yylloc={});var I=o.yylloc;i.push(I);var z=o.options&&o.options.ranges;typeof p.yy.parseError=="function"?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function U(){var y;return y=s.pop()||o.lex()||T,typeof y!="number"&&(y instanceof Array&&(s=y,y=s.pop()),y=e.symbols_[y]||y),y}for(var l,g,h,w,_={},b,c,F,S;;){if(g=n[n.length-1],this.defaultActions[g]?h=this.defaultActions[g]:((l===null||typeof l>"u")&&(l=U()),h=d[g]&&d[g][l]),typeof h>"u"||!h.length||!h[0]){var A="";S=[];for(b in d[g])this.terminals_[b]&&b>N&&S.push("'"+this.terminals_[b]+"'");o.showPosition?A="Parse error on line "+(v+1)+`: +import{l as Y,aK as D,i as M}from"./mermaid.core-Q3WVcjPF.js";import"./app-UOvWaKji.js";var O=function(){var a=function(u,t,e,n){for(e=e||{},n=u.length;n--;e[u[n]]=t);return e},f=[6,9,10],m={trace:function(){},yy:{},symbols_:{error:2,start:3,info:4,document:5,EOF:6,line:7,statement:8,NL:9,showInfo:10,$accept:0,$end:1},terminals_:{2:"error",4:"info",6:"EOF",9:"NL",10:"showInfo"},productions_:[0,[3,3],[5,0],[5,2],[7,1],[7,1],[8,1]],performAction:function(t,e,n,s,r,i,d){switch(i.length-1,r){case 1:return s;case 4:break;case 6:s.setInfo(!0);break}},table:[{3:1,4:[1,2]},{1:[3]},a(f,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},a(f,[2,3]),a(f,[2,4]),a(f,[2,5]),a(f,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,e){if(e.recoverable)this.trace(t);else{var n=new Error(t);throw n.hash=e,n}},parse:function(t){var e=this,n=[0],s=[],r=[null],i=[],d=this.table,P="",v=0,L=0,N=2,T=1,R=i.slice.call(arguments,1),o=Object.create(this.lexer),p={yy:{}};for(var E in this.yy)Object.prototype.hasOwnProperty.call(this.yy,E)&&(p.yy[E]=this.yy[E]);o.setInput(t,p.yy),p.yy.lexer=o,p.yy.parser=this,typeof o.yylloc>"u"&&(o.yylloc={});var I=o.yylloc;i.push(I);var z=o.options&&o.options.ranges;typeof p.yy.parseError=="function"?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function U(){var y;return y=s.pop()||o.lex()||T,typeof y!="number"&&(y instanceof Array&&(s=y,y=s.pop()),y=e.symbols_[y]||y),y}for(var l,g,h,w,_={},b,c,F,S;;){if(g=n[n.length-1],this.defaultActions[g]?h=this.defaultActions[g]:((l===null||typeof l>"u")&&(l=U()),h=d[g]&&d[g][l]),typeof h>"u"||!h.length||!h[0]){var A="";S=[];for(b in d[g])this.terminals_[b]&&b>N&&S.push("'"+this.terminals_[b]+"'");o.showPosition?A="Parse error on line "+(v+1)+`: `+o.showPosition()+` Expecting `+S.join(", ")+", got '"+(this.terminals_[l]||l)+"'":A="Parse error on line "+(v+1)+": Unexpected "+(l==T?"end of input":"'"+(this.terminals_[l]||l)+"'"),this.parseError(A,{text:o.match,token:this.terminals_[l]||l,line:o.yylineno,loc:I,expected:S})}if(h[0]instanceof Array&&h.length>1)throw new Error("Parse Error: multiple actions possible at state: "+g+", token: "+l);switch(h[0]){case 1:n.push(l),r.push(o.yytext),i.push(o.yylloc),n.push(h[1]),l=null,L=o.yyleng,P=o.yytext,v=o.yylineno,I=o.yylloc;break;case 2:if(c=this.productions_[h[1]][1],_.$=r[r.length-c],_._$={first_line:i[i.length-(c||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(c||1)].first_column,last_column:i[i.length-1].last_column},z&&(_._$.range=[i[i.length-(c||1)].range[0],i[i.length-1].range[1]]),w=this.performAction.apply(_,[P,L,v,p.yy,h[1],r,i].concat(R)),typeof w<"u")return w;c&&(n=n.slice(0,-1*c*2),r=r.slice(0,-1*c),i=i.slice(0,-1*c)),n.push(this.productions_[h[1]][0]),r.push(_.$),i.push(_._$),F=d[n[n.length-2]][n[n.length-1]],n.push(F);break;case 3:return!0}}return!0}},k=function(){var u={EOF:1,parseError:function(e,n){if(this.yy.parser)this.yy.parser.parseError(e,n);else throw new Error(e)},setInput:function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t;var e=t.match(/(?:\r\n?|\n).*/g);return e?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===s.length?this.yylloc.first_column:0)+s[s.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+` diff --git a/assets/install.html-Q9rZTV_2.js b/assets/install.html-H_t1fqr8.js similarity index 99% rename from assets/install.html-Q9rZTV_2.js rename to assets/install.html-H_t1fqr8.js index 913036c9f5..010c6d318a 100644 --- a/assets/install.html-Q9rZTV_2.js +++ b/assets/install.html-H_t1fqr8.js @@ -1 +1 @@ -import{_ as h,r as o,o as c,c as u,a as e,b as r,d as n,w as a,e as s}from"./app-PDrbPfzp.js";const _={},d=s('

                        下载安装

                        平台支持

                        Xray 在以下平台中可用:

                        • Windows 7 及之后版本(x86 / amd64 / arm32 / arm64);
                        • macOS 10.10 Yosemite 及之后版本(amd64 / arm64);
                        • Linux 2.6.23 及之后版本(x86 / amd64 / arm / arm64 / mips64 / mips / ppc64 / s390x / riscv64);
                          • 包括但不限于 Debian 7 / 8、Ubuntu 12.04 / 14.04 及后续版本、CentOS 7 / 8、Arch Linux 等;
                        • FreeBSD (x86 / amd64);
                        • OpenBSD (x86 / amd64);
                        • Dragonfly BSD (amd64);

                        下载 Xray

                        ',5),p={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},b=e("p",null,"下载对应平台的压缩包,解压后即可使用。",-1),f=e("h2",{id:"验证安装包",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#验证安装包"},[e("span",null,"验证安装包")])],-1),g=e("p",null,"Xray 提供两种验证方式:",-1),m=e("li",null,"ZIP 压缩包的 SHA1 / SHA256 摘要",-1),y=e("h2",{id:"windows-安装方式",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#windows-安装方式"},[e("span",null,"Windows 安装方式")])],-1),x={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},k=e("code",null,"xray.exe",-1),w=e("a",{href:"./command"},"通过命令行带参数运行",-1),X={href:"https://scoop.sh",target:"_blank",rel:"noopener noreferrer"},S={href:"https://github.com/Qv2ray/mochi",target:"_blank",rel:"noopener noreferrer"},v=e("h2",{id:"macos-安装方式",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#macos-安装方式"},[e("span",null,"macOS 安装方式")])],-1),N={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},A=e("code",null,"xray",-1),R={href:"https://brew.sh",target:"_blank",rel:"noopener noreferrer"},L=e("code",null,"brew install xray",-1),O={href:"https://github.com/N4FA/homebrew-xray",target:"_blank",rel:"noopener noreferrer"},C={href:"https://github.com/N4FA",target:"_blank",rel:"noopener noreferrer"},D=e("h2",{id:"linux-安装方式",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#linux-安装方式"},[e("span",null,"Linux 安装方式")])],-1),P=e("h3",{id:"安装脚本",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#安装脚本"},[e("span",null,"安装脚本")])],-1),U=e("p",null,"Linux Script",-1),I={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},M=e("p",null,"One Click",-1),B={href:"https://github.com/kirin10000/Xray-script",target:"_blank",rel:"noopener noreferrer"},W={href:"https://github.com/proxysu/ProxySU",target:"_blank",rel:"noopener noreferrer"},F={href:"https://github.com/reeceyng/v2ray-agent",target:"_blank",rel:"noopener noreferrer"},G={href:"https://github.com/mack-a",target:"_blank",rel:"noopener noreferrer"},Q={href:"https://github.com/reeceyng",target:"_blank",rel:"noopener noreferrer"},H={href:"https://github.com/jiuqi9997/Xray-yes",target:"_blank",rel:"noopener noreferrer"},V={href:"https://github.com/wulabing/Xray_onekey",target:"_blank",rel:"noopener noreferrer"},j=e("p",null,"Magisk",-1),E={href:"https://github.com/CerteKim/Xray4Magisk",target:"_blank",rel:"noopener noreferrer"},K={href:"https://github.com/E7KMbb/Xray_For_Magisk",target:"_blank",rel:"noopener noreferrer"},T=e("h3",{id:"arch-linux",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-linux"},[e("span",null,"Arch Linux")])],-1),Z=e("h4",{id:"arch-user-repository",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-user-repository"},[e("span",null,"Arch User Repository")])],-1),z={href:"https://wiki.archlinux.org/index.php/AUR_helpers",target:"_blank",rel:"noopener noreferrer"},J={href:"https://github.com/Jguer/yay",target:"_blank",rel:"noopener noreferrer"},q=e("code",null,"yay -S xray",-1),Y=e("h4",{id:"arch-linux-cn",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-linux-cn"},[e("span",null,"Arch Linux CN")])],-1),$={href:"https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/",target:"_blank",rel:"noopener noreferrer"},ee=e("code",null,"pacman -S xray",-1),re=e("h3",{id:"linuxbrew",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#linuxbrew"},[e("span",null,"Linuxbrew")])],-1),ne=e("p",null,[r("Linuxbrew 包管理器的使用方式与 Homebrew 一致:"),e("code",null,"brew install xray")],-1),te={id:"debian",tabindex:"-1"},oe={class:"header-anchor",href:"#debian"},le=e("h3",{id:"gentoo",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#gentoo"},[e("span",null,"Gentoo")])],-1),ae=e("p",null,"目前有三个第三方 Overlay 提供 Portage 安装脚本:",-1),se={href:"https://github.com/gentoo-mirror/touchfish-os/tree/master/net-proxy/Xray",target:"_blank",rel:"noopener noreferrer"},ie={href:"https://github.com/microcai/gentoo-zh",target:"_blank",rel:"noopener noreferrer"},he={href:"https://github.com/JuanCldCmt/Xray-Overlay",target:"_blank",rel:"noopener noreferrer"},ce=e("p",null,"使用 layman 或 eselect-repository 添加 Overlay 至本地,然后即可安装。",-1),ue=e("h2",{id:"docker-安装方式",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#docker-安装方式"},[e("span",null,"Docker 安装方式")])],-1),_e={href:"https://hub.docker.com/r/teddysun/xray",target:"_blank",rel:"noopener noreferrer"},de=s('

                        Docker image 的文件结构

                        • /etc/xray/config.json:配置文件
                        • /usr/bin/xray:Xray 主程序
                        • /usr/share/xray/geoip.dat:IP 数据文件
                        • /usr/share/xray/geosite.dat:域名数据文件

                        图形化客户端

                        ',3),pe={href:"https://github.com/xiaorouji/openwrt-passwall",target:"_blank",rel:"noopener noreferrer"},be={href:"https://github.com/jerrykuku/luci-app-vssr",target:"_blank",rel:"noopener noreferrer"},fe={href:"https://github.com/fw876/helloworld",target:"_blank",rel:"noopener noreferrer"},ge={href:"https://github.com/yichya/luci-app-xray",target:"_blank",rel:"noopener noreferrer"},me={href:"https://github.com/yichya/openwrt-xray",target:"_blank",rel:"noopener noreferrer"},ye={href:"https://github.com/2dust/v2rayN",target:"_blank",rel:"noopener noreferrer"},xe={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},ke={href:"https://github.com/NetchX/Netch",target:"_blank",rel:"noopener noreferrer"},we={href:"https://github.com/2dust/v2rayNG",target:"_blank",rel:"noopener noreferrer"},Xe={href:"https://github.com/rurirei/Kitsunebi/tree/release_xtls",target:"_blank",rel:"noopener noreferrer"},Se={href:"https://apps.apple.com/app/shadowrocket/id932747118",target:"_blank",rel:"noopener noreferrer"},ve={href:"https://apps.apple.com/app/stash/id1596063349",target:"_blank",rel:"noopener noreferrer"},Ne={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},Ae={href:"https://github.com/tzmax/V2RayXS",target:"_blank",rel:"noopener noreferrer"},Re=e("h1",{id:"uuid-生成器",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#uuid-生成器"},[e("span",null,"UUID 生成器")])],-1),Le={href:"https://www.uuidgenerator.net",target:"_blank",rel:"noopener noreferrer"};function Oe(Ce,De){const t=o("ExternalLinkIcon"),l=o("RouterLink"),i=o("Badge");return c(),u("div",null,[d,e("p",null,[r("预编译的二进制 ZIP 格式压缩包可在 "),e("a",p,[r("Github Releases"),n(t)]),r(" 中找到。")]),b,f,g,e("ul",null,[m,e("li",null,[r("可复现构建:请参照 "),n(l,{to:"/development/intro/compile.html"},{default:a(()=>[r("编译 Xray")]),_:1})])]),y,e("ul",null,[e("li",null,[r("在 "),e("a",x,[r("Github Releases"),n(t)]),r(" 下载适用于 Windows 平台的 ZIP 压缩包,解压后可得到可执行文件 "),k,r(" ,然后"),w,r(" 即可")]),e("li",null,[r("通过 "),e("a",X,[r("Scoop"),n(t)]),r(" 包管理器安装:Xray 已经被添加到 "),e("a",S,[r("Mochi"),n(t)]),r("。")])]),v,e("ul",null,[e("li",null,[r("在 "),e("a",N,[r("Github Releases"),n(t)]),r(" 下载适用于 macOS 平台的 ZIP 压缩包,解压后可得到可执行文件 "),A,r(" ,然后"),n(l,{to:"/document/command.html"},{default:a(()=>[r("通过命令行带参数运行")]),_:1}),r(" 即可")]),e("li",null,[r("通过 "),e("a",R,[r("Homebrew"),n(t)]),r(" 包管理器安装:"),L]),e("li",null,[e("a",O,[r("homebrew-xray"),n(t)]),r(" 感谢"),e("a",C,[r("@N4FA"),n(t)])])]),D,P,e("ul",null,[e("li",null,[U,e("ul",null,[e("li",null,[e("a",I,[r("Xray-install"),n(t)])])])])]),e("ul",null,[e("li",null,[M,e("ul",null,[e("li",null,[e("a",B,[r("Xray-script"),n(t)])]),e("li",null,[e("a",W,[r("ProxySU"),n(t)])]),e("li",null,[e("a",F,[r("v2ray-agent"),n(t)]),r(" 感谢"),e("a",G,[r("@mack-a"),n(t)]),r(),e("a",Q,[r("@Reece"),n(t)])]),e("li",null,[e("a",H,[r("Xray-yes"),n(t)])]),e("li",null,[e("a",V,[r("Xray-onekey"),n(t)])])])]),e("li",null,[j,e("ul",null,[e("li",null,[e("a",E,[r("Xray4Magisk"),n(t)])]),e("li",null,[e("a",K,[r("Xray_For_Magisk"),n(t)])])])])]),T,Z,e("p",null,[r("需要使用 "),e("a",z,[r("AUR helpers"),n(t)]),r(",以 "),e("a",J,[r("yay"),n(t)]),r(" 为例,可通过 "),q,r(" 安装。")]),Y,e("p",null,[r("首先添加 "),e("a",$,[r("Arch Linux CN 仓库"),n(t)]),r(",然后在 root 用户下使用 "),ee,r(" 安装。")]),re,ne,e("h3",te,[e("a",oe,[e("span",null,[r("Debian "),n(i,{text:"WIP",type:"warning"})])])]),le,ae,e("ul",null,[e("li",null,[e("a",se,[r("CHN-beta/touchfish-os"),n(t)]),r(": 个人维护,适用于 systemD 系统")]),e("li",null,[e("a",ie,[r("Gentoo-zh"),n(t)]),r(": 社区维护,适用于 systemD 系统")]),e("li",null,[e("a",he,[r("JuanCldCmt/Xray-Overlay"),n(t)]),r(":个人维护,适用于 openRC 系统,同时使用 xray 用户组运行以提高安全性")])]),ce,ue,e("ul",null,[e("li",null,[e("a",_e,[r("teddysun/xray"),n(t)])])]),de,e("ul",null,[e("li",null,[r("OpenWrt "),e("ul",null,[e("li",null,[e("a",pe,[r("PassWall"),n(t)])]),e("li",null,[e("a",be,[r("Hello World"),n(t)])]),e("li",null,[e("a",fe,[r("ShadowSocksR Plus+"),n(t)])]),e("li",null,[e("a",ge,[r("luci-app-xray"),n(t)]),r(" ("),e("a",me,[r("openwrt-xray"),n(t)]),r(")")])])]),e("li",null,[r("Windows "),e("ul",null,[e("li",null,[e("a",ye,[r("v2rayN"),n(t)])]),e("li",null,[e("a",xe,[r("Qv2ray"),n(t)]),r(" (该项目已冻结存档)")]),e("li",null,[e("a",ke,[r("Netch (NetFilter & TUN/TAP)"),n(t)]),r(" (该项目已冻结存档)")])])]),e("li",null,[r("Android "),e("ul",null,[e("li",null,[e("a",we,[r("v2rayNG"),n(t)])]),e("li",null,[e("a",Xe,[r("Kitsunebi"),n(t)])])])]),e("li",null,[r("iOS / macOS(使用 ARM 芯片) "),e("ul",null,[e("li",null,[e("a",Se,[r("Shadowrocket"),n(t)])]),e("li",null,[e("a",ve,[r("Stash"),n(t)])])])]),e("li",null,[r("macOS(X86 芯片 / ARM 芯片) "),e("ul",null,[e("li",null,[e("a",Ne,[r("Qv2ray"),n(t)]),r(" (该项目已冻结存档)")]),e("li",null,[e("a",Ae,[r("V2RayXS"),n(t)])])])])]),Re,e("p",null,[r("第三方的 UUID 生成器 "),e("a",Le,[r("uuidgenerator.net"),n(t)])])])}const Ue=h(_,[["render",Oe],["__file","install.html.vue"]]);export{Ue as default}; +import{_ as h,r as o,o as c,c as u,a as e,b as r,d as n,w as a,e as s}from"./app-UOvWaKji.js";const _={},d=s('

                        下载安装

                        平台支持

                        Xray 在以下平台中可用:

                        • Windows 7 及之后版本(x86 / amd64 / arm32 / arm64);
                        • macOS 10.10 Yosemite 及之后版本(amd64 / arm64);
                        • Linux 2.6.23 及之后版本(x86 / amd64 / arm / arm64 / mips64 / mips / ppc64 / s390x / riscv64);
                          • 包括但不限于 Debian 7 / 8、Ubuntu 12.04 / 14.04 及后续版本、CentOS 7 / 8、Arch Linux 等;
                        • FreeBSD (x86 / amd64);
                        • OpenBSD (x86 / amd64);
                        • Dragonfly BSD (amd64);

                        下载 Xray

                        ',5),p={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},b=e("p",null,"下载对应平台的压缩包,解压后即可使用。",-1),f=e("h2",{id:"验证安装包",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#验证安装包"},[e("span",null,"验证安装包")])],-1),g=e("p",null,"Xray 提供两种验证方式:",-1),m=e("li",null,"ZIP 压缩包的 SHA1 / SHA256 摘要",-1),y=e("h2",{id:"windows-安装方式",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#windows-安装方式"},[e("span",null,"Windows 安装方式")])],-1),x={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},k=e("code",null,"xray.exe",-1),w=e("a",{href:"./command"},"通过命令行带参数运行",-1),X={href:"https://scoop.sh",target:"_blank",rel:"noopener noreferrer"},S={href:"https://github.com/Qv2ray/mochi",target:"_blank",rel:"noopener noreferrer"},v=e("h2",{id:"macos-安装方式",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#macos-安装方式"},[e("span",null,"macOS 安装方式")])],-1),N={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},A=e("code",null,"xray",-1),R={href:"https://brew.sh",target:"_blank",rel:"noopener noreferrer"},L=e("code",null,"brew install xray",-1),O={href:"https://github.com/N4FA/homebrew-xray",target:"_blank",rel:"noopener noreferrer"},C={href:"https://github.com/N4FA",target:"_blank",rel:"noopener noreferrer"},D=e("h2",{id:"linux-安装方式",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#linux-安装方式"},[e("span",null,"Linux 安装方式")])],-1),P=e("h3",{id:"安装脚本",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#安装脚本"},[e("span",null,"安装脚本")])],-1),U=e("p",null,"Linux Script",-1),I={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},M=e("p",null,"One Click",-1),B={href:"https://github.com/kirin10000/Xray-script",target:"_blank",rel:"noopener noreferrer"},W={href:"https://github.com/proxysu/ProxySU",target:"_blank",rel:"noopener noreferrer"},F={href:"https://github.com/reeceyng/v2ray-agent",target:"_blank",rel:"noopener noreferrer"},G={href:"https://github.com/mack-a",target:"_blank",rel:"noopener noreferrer"},Q={href:"https://github.com/reeceyng",target:"_blank",rel:"noopener noreferrer"},H={href:"https://github.com/jiuqi9997/Xray-yes",target:"_blank",rel:"noopener noreferrer"},V={href:"https://github.com/wulabing/Xray_onekey",target:"_blank",rel:"noopener noreferrer"},j=e("p",null,"Magisk",-1),E={href:"https://github.com/CerteKim/Xray4Magisk",target:"_blank",rel:"noopener noreferrer"},K={href:"https://github.com/E7KMbb/Xray_For_Magisk",target:"_blank",rel:"noopener noreferrer"},T=e("h3",{id:"arch-linux",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-linux"},[e("span",null,"Arch Linux")])],-1),Z=e("h4",{id:"arch-user-repository",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-user-repository"},[e("span",null,"Arch User Repository")])],-1),z={href:"https://wiki.archlinux.org/index.php/AUR_helpers",target:"_blank",rel:"noopener noreferrer"},J={href:"https://github.com/Jguer/yay",target:"_blank",rel:"noopener noreferrer"},q=e("code",null,"yay -S xray",-1),Y=e("h4",{id:"arch-linux-cn",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-linux-cn"},[e("span",null,"Arch Linux CN")])],-1),$={href:"https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/",target:"_blank",rel:"noopener noreferrer"},ee=e("code",null,"pacman -S xray",-1),re=e("h3",{id:"linuxbrew",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#linuxbrew"},[e("span",null,"Linuxbrew")])],-1),ne=e("p",null,[r("Linuxbrew 包管理器的使用方式与 Homebrew 一致:"),e("code",null,"brew install xray")],-1),te={id:"debian",tabindex:"-1"},oe={class:"header-anchor",href:"#debian"},le=e("h3",{id:"gentoo",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#gentoo"},[e("span",null,"Gentoo")])],-1),ae=e("p",null,"目前有三个第三方 Overlay 提供 Portage 安装脚本:",-1),se={href:"https://github.com/gentoo-mirror/touchfish-os/tree/master/net-proxy/Xray",target:"_blank",rel:"noopener noreferrer"},ie={href:"https://github.com/microcai/gentoo-zh",target:"_blank",rel:"noopener noreferrer"},he={href:"https://github.com/JuanCldCmt/Xray-Overlay",target:"_blank",rel:"noopener noreferrer"},ce=e("p",null,"使用 layman 或 eselect-repository 添加 Overlay 至本地,然后即可安装。",-1),ue=e("h2",{id:"docker-安装方式",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#docker-安装方式"},[e("span",null,"Docker 安装方式")])],-1),_e={href:"https://hub.docker.com/r/teddysun/xray",target:"_blank",rel:"noopener noreferrer"},de=s('

                        Docker image 的文件结构

                        • /etc/xray/config.json:配置文件
                        • /usr/bin/xray:Xray 主程序
                        • /usr/share/xray/geoip.dat:IP 数据文件
                        • /usr/share/xray/geosite.dat:域名数据文件

                        图形化客户端

                        ',3),pe={href:"https://github.com/xiaorouji/openwrt-passwall",target:"_blank",rel:"noopener noreferrer"},be={href:"https://github.com/jerrykuku/luci-app-vssr",target:"_blank",rel:"noopener noreferrer"},fe={href:"https://github.com/fw876/helloworld",target:"_blank",rel:"noopener noreferrer"},ge={href:"https://github.com/yichya/luci-app-xray",target:"_blank",rel:"noopener noreferrer"},me={href:"https://github.com/yichya/openwrt-xray",target:"_blank",rel:"noopener noreferrer"},ye={href:"https://github.com/2dust/v2rayN",target:"_blank",rel:"noopener noreferrer"},xe={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},ke={href:"https://github.com/NetchX/Netch",target:"_blank",rel:"noopener noreferrer"},we={href:"https://github.com/2dust/v2rayNG",target:"_blank",rel:"noopener noreferrer"},Xe={href:"https://github.com/rurirei/Kitsunebi/tree/release_xtls",target:"_blank",rel:"noopener noreferrer"},Se={href:"https://apps.apple.com/app/shadowrocket/id932747118",target:"_blank",rel:"noopener noreferrer"},ve={href:"https://apps.apple.com/app/stash/id1596063349",target:"_blank",rel:"noopener noreferrer"},Ne={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},Ae={href:"https://github.com/tzmax/V2RayXS",target:"_blank",rel:"noopener noreferrer"},Re=e("h1",{id:"uuid-生成器",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#uuid-生成器"},[e("span",null,"UUID 生成器")])],-1),Le={href:"https://www.uuidgenerator.net",target:"_blank",rel:"noopener noreferrer"};function Oe(Ce,De){const t=o("ExternalLinkIcon"),l=o("RouterLink"),i=o("Badge");return c(),u("div",null,[d,e("p",null,[r("预编译的二进制 ZIP 格式压缩包可在 "),e("a",p,[r("Github Releases"),n(t)]),r(" 中找到。")]),b,f,g,e("ul",null,[m,e("li",null,[r("可复现构建:请参照 "),n(l,{to:"/development/intro/compile.html"},{default:a(()=>[r("编译 Xray")]),_:1})])]),y,e("ul",null,[e("li",null,[r("在 "),e("a",x,[r("Github Releases"),n(t)]),r(" 下载适用于 Windows 平台的 ZIP 压缩包,解压后可得到可执行文件 "),k,r(" ,然后"),w,r(" 即可")]),e("li",null,[r("通过 "),e("a",X,[r("Scoop"),n(t)]),r(" 包管理器安装:Xray 已经被添加到 "),e("a",S,[r("Mochi"),n(t)]),r("。")])]),v,e("ul",null,[e("li",null,[r("在 "),e("a",N,[r("Github Releases"),n(t)]),r(" 下载适用于 macOS 平台的 ZIP 压缩包,解压后可得到可执行文件 "),A,r(" ,然后"),n(l,{to:"/document/command.html"},{default:a(()=>[r("通过命令行带参数运行")]),_:1}),r(" 即可")]),e("li",null,[r("通过 "),e("a",R,[r("Homebrew"),n(t)]),r(" 包管理器安装:"),L]),e("li",null,[e("a",O,[r("homebrew-xray"),n(t)]),r(" 感谢"),e("a",C,[r("@N4FA"),n(t)])])]),D,P,e("ul",null,[e("li",null,[U,e("ul",null,[e("li",null,[e("a",I,[r("Xray-install"),n(t)])])])])]),e("ul",null,[e("li",null,[M,e("ul",null,[e("li",null,[e("a",B,[r("Xray-script"),n(t)])]),e("li",null,[e("a",W,[r("ProxySU"),n(t)])]),e("li",null,[e("a",F,[r("v2ray-agent"),n(t)]),r(" 感谢"),e("a",G,[r("@mack-a"),n(t)]),r(),e("a",Q,[r("@Reece"),n(t)])]),e("li",null,[e("a",H,[r("Xray-yes"),n(t)])]),e("li",null,[e("a",V,[r("Xray-onekey"),n(t)])])])]),e("li",null,[j,e("ul",null,[e("li",null,[e("a",E,[r("Xray4Magisk"),n(t)])]),e("li",null,[e("a",K,[r("Xray_For_Magisk"),n(t)])])])])]),T,Z,e("p",null,[r("需要使用 "),e("a",z,[r("AUR helpers"),n(t)]),r(",以 "),e("a",J,[r("yay"),n(t)]),r(" 为例,可通过 "),q,r(" 安装。")]),Y,e("p",null,[r("首先添加 "),e("a",$,[r("Arch Linux CN 仓库"),n(t)]),r(",然后在 root 用户下使用 "),ee,r(" 安装。")]),re,ne,e("h3",te,[e("a",oe,[e("span",null,[r("Debian "),n(i,{text:"WIP",type:"warning"})])])]),le,ae,e("ul",null,[e("li",null,[e("a",se,[r("CHN-beta/touchfish-os"),n(t)]),r(": 个人维护,适用于 systemD 系统")]),e("li",null,[e("a",ie,[r("Gentoo-zh"),n(t)]),r(": 社区维护,适用于 systemD 系统")]),e("li",null,[e("a",he,[r("JuanCldCmt/Xray-Overlay"),n(t)]),r(":个人维护,适用于 openRC 系统,同时使用 xray 用户组运行以提高安全性")])]),ce,ue,e("ul",null,[e("li",null,[e("a",_e,[r("teddysun/xray"),n(t)])])]),de,e("ul",null,[e("li",null,[r("OpenWrt "),e("ul",null,[e("li",null,[e("a",pe,[r("PassWall"),n(t)])]),e("li",null,[e("a",be,[r("Hello World"),n(t)])]),e("li",null,[e("a",fe,[r("ShadowSocksR Plus+"),n(t)])]),e("li",null,[e("a",ge,[r("luci-app-xray"),n(t)]),r(" ("),e("a",me,[r("openwrt-xray"),n(t)]),r(")")])])]),e("li",null,[r("Windows "),e("ul",null,[e("li",null,[e("a",ye,[r("v2rayN"),n(t)])]),e("li",null,[e("a",xe,[r("Qv2ray"),n(t)]),r(" (该项目已冻结存档)")]),e("li",null,[e("a",ke,[r("Netch (NetFilter & TUN/TAP)"),n(t)]),r(" (该项目已冻结存档)")])])]),e("li",null,[r("Android "),e("ul",null,[e("li",null,[e("a",we,[r("v2rayNG"),n(t)])]),e("li",null,[e("a",Xe,[r("Kitsunebi"),n(t)])])])]),e("li",null,[r("iOS / macOS(使用 ARM 芯片) "),e("ul",null,[e("li",null,[e("a",Se,[r("Shadowrocket"),n(t)])]),e("li",null,[e("a",ve,[r("Stash"),n(t)])])])]),e("li",null,[r("macOS(X86 芯片 / ARM 芯片) "),e("ul",null,[e("li",null,[e("a",Ne,[r("Qv2ray"),n(t)]),r(" (该项目已冻结存档)")]),e("li",null,[e("a",Ae,[r("V2RayXS"),n(t)])])])])]),Re,e("p",null,[r("第三方的 UUID 生成器 "),e("a",Le,[r("uuidgenerator.net"),n(t)])])])}const Ue=h(_,[["render",Oe],["__file","install.html.vue"]]);export{Ue as default}; diff --git a/assets/install.html-C76Ht-N3.js b/assets/install.html-VE-T3hko.js similarity index 99% rename from assets/install.html-C76Ht-N3.js rename to assets/install.html-VE-T3hko.js index ce3381a120..5ae647e54a 100644 --- a/assets/install.html-C76Ht-N3.js +++ b/assets/install.html-VE-T3hko.js @@ -1 +1 @@ -import{_ as s,r as t,o as i,c as h,a as e,b as r,d as n,e as l}from"./app-PDrbPfzp.js";const c={},d=l('

                        Download and Install

                        Platform Support

                        • Xray is available on the following platforms:
                          • Windows 7 and later (x86 / amd64 / arm32 / arm64);
                          • macOS 10.10 Yosemite and later (amd64 / arm64);
                          • Linux 2.6.23 and later (x86 / amd64 / arm / arm64 / mips64 / mips / ppc64 / s390x / riscv64);
                            • Including but not limited to Debian 7 / 8, Ubuntu 12.04 / 14.04 and subsequent versions, CentOS 7 / 8, Arch Linux, etc.;
                          • FreeBSD (x86 / amd64);
                          • OpenBSD (x86 / amd64);
                          • Dragonfly BSD (amd64);

                        Download Xray

                        ',4),u={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},p=e("p",null,"Download the compressed package of the corresponding platform, and use it after decompression.",-1),_=e("h2",{id:"verify-the-installation-package",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#verify-the-installation-package"},[e("span",null,"Verify the Installation Package")])],-1),f=e("p",null,"Xray provides two verification methods:",-1),b=e("li",null,"SHA1/SHA256 digest of the ZIP archive",-1),g={href:"https://xtls.github.io/development/intro/compile.html",target:"_blank",rel:"noopener noreferrer"},m=e("h2",{id:"install-on-windows",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#install-on-windows"},[e("span",null,"Install on Windows")])],-1),y={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},x=e("code",null,"xray.exe",-1),k=e("a",{href:"./command"},"parameters",-1),w={href:"https://scoop.sh/",target:"_blank",rel:"noopener noreferrer"},v={href:"https://github.com/Qv2ray/mochi",target:"_blank",rel:"noopener noreferrer"},S=e("h2",{id:"install-on-macos",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#install-on-macos"},[e("span",null,"Install on macOS")])],-1),X={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},I=e("code",null,"xray",-1),N=e("a",{href:"./command"},"parameters",-1),A={href:"https://brew.sh/",target:"_blank",rel:"noopener noreferrer"},P=e("code",null,"brew install xray",-1),D={href:"https://github.com/N4FA/homebrew-xray",target:"_blank",rel:"noopener noreferrer"},R={href:"https://github.com/N4FA",target:"_blank",rel:"noopener noreferrer"},L=e("h2",{id:"install-on-linux",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#install-on-linux"},[e("span",null,"Install on Linux")])],-1),T=e("h3",{id:"install-script",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#install-script"},[e("span",null,"Install Script")])],-1),U=e("p",null,"Linux Script",-1),B={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},O=e("p",null,"One Click",-1),F={href:"https://github.com/kirin10000/Xray-script",target:"_blank",rel:"noopener noreferrer"},M={href:"https://github.com/proxysu/ProxySU",target:"_blank",rel:"noopener noreferrer"},C={href:"https://github.com/reeceyng/v2ray-agent",target:"_blank",rel:"noopener noreferrer"},W={href:"https://github.com/mack-a",target:"_blank",rel:"noopener noreferrer"},G={href:"https://github.com/reeceyng",target:"_blank",rel:"noopener noreferrer"},Q=e("p",null,"Magisk",-1),V={href:"https://github.com/CerteKim/Xray4Magisk",target:"_blank",rel:"noopener noreferrer"},j={href:"https://github.com/E7KMbb/Xray_For_Magisk",target:"_blank",rel:"noopener noreferrer"},H=e("h3",{id:"arch-linux",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-linux"},[e("span",null,"Arch Linux")])],-1),E=e("h4",{id:"arch-user-repository",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-user-repository"},[e("span",null,"Arch User Repository")])],-1),K={href:"https://wiki.archlinux.org/index.php/AUR_helpers",target:"_blank",rel:"noopener noreferrer"},Z={href:"https://github.com/Jguer/yay",target:"_blank",rel:"noopener noreferrer"},q=e("code",null,"yay -S xray",-1),z=e("h4",{id:"arch-linux-cn",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-linux-cn"},[e("span",null,"Arch Linux CN")])],-1),J={href:"https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/",target:"_blank",rel:"noopener noreferrer"},Y=e("code",null,"pacman -S xray",-1),$=e("h3",{id:"linuxbrew",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#linuxbrew"},[e("span",null,"Linuxbrew")])],-1),ee=e("p",null,[r("The Linuxbrew package manager is used in the same way as Homebrew: "),e("code",null,"brew install xray")],-1),re={id:"debian",tabindex:"-1"},ne={class:"header-anchor",href:"#debian"},ae=e("h2",{id:"install-via-docker",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#install-via-docker"},[e("span",null,"Install via Docker")])],-1),te={href:"https://hub.docker.com/r/teddysun/xray",target:"_blank",rel:"noopener noreferrer"},le=l('

                        The File Structure of the Docker Image

                        • /etc/xray/config.json: configuration file
                        • /usr/bin/xray: Xray main program
                        • /usr/local/share/xray/geoip.dat: IP data file
                        • /usr/local/share/xray/geosite.dat: domain name data file

                        GUI Client

                        ',3),oe={href:"https://github.com/xiaorouji/openwrt-passwall",target:"_blank",rel:"noopener noreferrer"},se={href:"https://github.com/jerrykuku/luci-app-vssr",target:"_blank",rel:"noopener noreferrer"},ie={href:"https://github.com/fw876/helloworld",target:"_blank",rel:"noopener noreferrer"},he={href:"https://github.com/yichya/luci-app-xray",target:"_blank",rel:"noopener noreferrer"},ce={href:"https://github.com/yichya/openwrt-xray",target:"_blank",rel:"noopener noreferrer"},de={href:"https://github.com/2dust/v2rayN",target:"_blank",rel:"noopener noreferrer"},ue={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},pe={href:"https://github.com/NetchX/Netch",target:"_blank",rel:"noopener noreferrer"},_e={href:"https://github.com/2dust/v2rayNG",target:"_blank",rel:"noopener noreferrer"},fe={href:"https://github.com/rurirei/Kitsunebi/tree/release_xtls",target:"_blank",rel:"noopener noreferrer"},be={href:"https://apps.apple.com/app/shadowrocket/id932747118",target:"_blank",rel:"noopener noreferrer"},ge={href:"https://apps.apple.com/app/stash/id1596063349",target:"_blank",rel:"noopener noreferrer"},me={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},ye={href:"https://github.com/tzmax/V2RayXS",target:"_blank",rel:"noopener noreferrer"},xe=e("h1",{id:"uuid-generator",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#uuid-generator"},[e("span",null,"UUID Generator")])],-1),ke={href:"https://www.uuidgenerator.net",target:"_blank",rel:"noopener noreferrer"};function we(ve,Se){const a=t("ExternalLinkIcon"),o=t("Badge");return i(),h("div",null,[d,e("p",null,[r("Precompiled binaries in ZIP format are available at "),e("a",u,[r("GitHub Releases"),n(a)]),r(" found in.")]),p,_,f,e("ul",null,[b,e("li",null,[r("Reproducible build: Please refer to "),e("a",g,[r("Compile Xray"),n(a)])])]),m,e("ul",null,[e("li",null,[r("Download the ZIP archive suitable for the Windows platform on "),e("a",y,[r("Github Releases"),n(a)]),r(". After decompression, you can get an executable file "),x,r(", and then run it with "),k,r(" through the command line.")]),e("li",null,[r("By "),e("a",w,[r("Scoop"),n(a)]),r(" Package manager installation: Xray has been added to "),e("a",v,[r("Mochi"),n(a)]),r(".")])]),S,e("ul",null,[e("li",null,[r("Download the ZIP archive suitable for the macOS platform on "),e("a",X,[r("Github Releases"),n(a)]),r(". After decompression, you can get an executable file "),I,r(", and then run it with "),N,r(" through the command line.")]),e("li",null,[r("By "),e("a",A,[r("Homebrew"),n(a)]),r(" Package manager installation: "),P]),e("li",null,[e("a",D,[r("homebrew-xray"),n(a)]),r(": Thanks "),e("a",R,[r("@N4FA"),n(a)])])]),L,T,e("ul",null,[e("li",null,[U,e("ul",null,[e("li",null,[e("a",B,[r("Xray-install"),n(a)])])])])]),e("ul",null,[e("li",null,[O,e("ul",null,[e("li",null,[e("a",F,[r("Xray-script"),n(a)])]),e("li",null,[e("a",M,[r("ProxySU"),n(a)])]),e("li",null,[e("a",C,[r("Xray-agent"),n(a)]),r(" Thanks "),e("a",W,[r("@mack-a"),n(a)]),r(),e("a",G,[r("@Reece"),n(a)])])])]),e("li",null,[Q,e("ul",null,[e("li",null,[e("a",V,[r("Xray4Magisk"),n(a)])]),e("li",null,[e("a",j,[r("Xray_For_Magisk"),n(a)])])])])]),H,E,e("p",null,[r("Need to use "),e("a",K,[r("AUR helpers"),n(a)]),r(", "),e("a",Z,[r("yay"),n(a)]),r(" as an example, it can be installed via "),q,r(".")]),z,e("p",null,[r("First add "),e("a",J,[r("Arch Linux CN"),n(a)]),r(" repository, and then use the root user "),Y,r("to install.")]),$,ee,e("h3",re,[e("a",ne,[e("span",null,[r("Debian "),n(o,{text:"WIP",type:"warning"})])])]),ae,e("ul",null,[e("li",null,[e("a",te,[r("teddysun/xray"),n(a)])])]),le,e("ul",null,[e("li",null,[r("OpenWrt "),e("ul",null,[e("li",null,[e("a",oe,[r("PassWall"),n(a)])]),e("li",null,[e("a",se,[r("Hello World"),n(a)])]),e("li",null,[e("a",ie,[r("ShadowSocksR Plus+"),n(a)])]),e("li",null,[e("a",he,[r("luci-app-xray"),n(a)]),r(" ("),e("a",ce,[r("openwrt-xray"),n(a)]),r(")")])])]),e("li",null,[r("Windows "),e("ul",null,[e("li",null,[e("a",de,[r("v2rayN"),n(a)])]),e("li",null,[e("a",ue,[r("Qv2ray"),n(a)]),r(" (This project has been and archived)")]),e("li",null,[e("a",pe,[r("Netch (NetFilter & TUN/TAP)"),n(a)]),r(" (This project has been and archived)")])])]),e("li",null,[r("Android "),e("ul",null,[e("li",null,[e("a",_e,[r("v2rayNG"),n(a)])]),e("li",null,[e("a",fe,[r("Kitsunebi"),n(a)])])])]),e("li",null,[r("iOS / macOS (ARM) "),e("ul",null,[e("li",null,[e("a",be,[r("Shadowrocket"),n(a)])]),e("li",null,[e("a",ge,[r("Stash"),n(a)])])])]),e("li",null,[r("macOS (X86/ARM) "),e("ul",null,[e("li",null,[e("a",me,[r("Qv2ray"),n(a)]),r(" (This project has been and archived)")]),e("li",null,[e("a",ye,[r("V2RayXS"),n(a)])])])])]),xe,e("p",null,[r("Third-party UUID generator "),e("a",ke,[r("uuidgenerator.net"),n(a)])])])}const Ie=s(c,[["render",we],["__file","install.html.vue"]]);export{Ie as default}; +import{_ as s,r as t,o as i,c as h,a as e,b as r,d as n,e as l}from"./app-UOvWaKji.js";const c={},d=l('

                        Download and Install

                        Platform Support

                        • Xray is available on the following platforms:
                          • Windows 7 and later (x86 / amd64 / arm32 / arm64);
                          • macOS 10.10 Yosemite and later (amd64 / arm64);
                          • Linux 2.6.23 and later (x86 / amd64 / arm / arm64 / mips64 / mips / ppc64 / s390x / riscv64);
                            • Including but not limited to Debian 7 / 8, Ubuntu 12.04 / 14.04 and subsequent versions, CentOS 7 / 8, Arch Linux, etc.;
                          • FreeBSD (x86 / amd64);
                          • OpenBSD (x86 / amd64);
                          • Dragonfly BSD (amd64);

                        Download Xray

                        ',4),u={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},p=e("p",null,"Download the compressed package of the corresponding platform, and use it after decompression.",-1),_=e("h2",{id:"verify-the-installation-package",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#verify-the-installation-package"},[e("span",null,"Verify the Installation Package")])],-1),f=e("p",null,"Xray provides two verification methods:",-1),b=e("li",null,"SHA1/SHA256 digest of the ZIP archive",-1),g={href:"https://xtls.github.io/development/intro/compile.html",target:"_blank",rel:"noopener noreferrer"},m=e("h2",{id:"install-on-windows",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#install-on-windows"},[e("span",null,"Install on Windows")])],-1),y={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},x=e("code",null,"xray.exe",-1),k=e("a",{href:"./command"},"parameters",-1),w={href:"https://scoop.sh/",target:"_blank",rel:"noopener noreferrer"},v={href:"https://github.com/Qv2ray/mochi",target:"_blank",rel:"noopener noreferrer"},S=e("h2",{id:"install-on-macos",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#install-on-macos"},[e("span",null,"Install on macOS")])],-1),X={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},I=e("code",null,"xray",-1),N=e("a",{href:"./command"},"parameters",-1),A={href:"https://brew.sh/",target:"_blank",rel:"noopener noreferrer"},P=e("code",null,"brew install xray",-1),D={href:"https://github.com/N4FA/homebrew-xray",target:"_blank",rel:"noopener noreferrer"},R={href:"https://github.com/N4FA",target:"_blank",rel:"noopener noreferrer"},L=e("h2",{id:"install-on-linux",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#install-on-linux"},[e("span",null,"Install on Linux")])],-1),T=e("h3",{id:"install-script",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#install-script"},[e("span",null,"Install Script")])],-1),U=e("p",null,"Linux Script",-1),B={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},O=e("p",null,"One Click",-1),F={href:"https://github.com/kirin10000/Xray-script",target:"_blank",rel:"noopener noreferrer"},M={href:"https://github.com/proxysu/ProxySU",target:"_blank",rel:"noopener noreferrer"},C={href:"https://github.com/reeceyng/v2ray-agent",target:"_blank",rel:"noopener noreferrer"},W={href:"https://github.com/mack-a",target:"_blank",rel:"noopener noreferrer"},G={href:"https://github.com/reeceyng",target:"_blank",rel:"noopener noreferrer"},Q=e("p",null,"Magisk",-1),V={href:"https://github.com/CerteKim/Xray4Magisk",target:"_blank",rel:"noopener noreferrer"},j={href:"https://github.com/E7KMbb/Xray_For_Magisk",target:"_blank",rel:"noopener noreferrer"},H=e("h3",{id:"arch-linux",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-linux"},[e("span",null,"Arch Linux")])],-1),E=e("h4",{id:"arch-user-repository",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-user-repository"},[e("span",null,"Arch User Repository")])],-1),K={href:"https://wiki.archlinux.org/index.php/AUR_helpers",target:"_blank",rel:"noopener noreferrer"},Z={href:"https://github.com/Jguer/yay",target:"_blank",rel:"noopener noreferrer"},q=e("code",null,"yay -S xray",-1),z=e("h4",{id:"arch-linux-cn",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#arch-linux-cn"},[e("span",null,"Arch Linux CN")])],-1),J={href:"https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/",target:"_blank",rel:"noopener noreferrer"},Y=e("code",null,"pacman -S xray",-1),$=e("h3",{id:"linuxbrew",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#linuxbrew"},[e("span",null,"Linuxbrew")])],-1),ee=e("p",null,[r("The Linuxbrew package manager is used in the same way as Homebrew: "),e("code",null,"brew install xray")],-1),re={id:"debian",tabindex:"-1"},ne={class:"header-anchor",href:"#debian"},ae=e("h2",{id:"install-via-docker",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#install-via-docker"},[e("span",null,"Install via Docker")])],-1),te={href:"https://hub.docker.com/r/teddysun/xray",target:"_blank",rel:"noopener noreferrer"},le=l('

                        The File Structure of the Docker Image

                        • /etc/xray/config.json: configuration file
                        • /usr/bin/xray: Xray main program
                        • /usr/local/share/xray/geoip.dat: IP data file
                        • /usr/local/share/xray/geosite.dat: domain name data file

                        GUI Client

                        ',3),oe={href:"https://github.com/xiaorouji/openwrt-passwall",target:"_blank",rel:"noopener noreferrer"},se={href:"https://github.com/jerrykuku/luci-app-vssr",target:"_blank",rel:"noopener noreferrer"},ie={href:"https://github.com/fw876/helloworld",target:"_blank",rel:"noopener noreferrer"},he={href:"https://github.com/yichya/luci-app-xray",target:"_blank",rel:"noopener noreferrer"},ce={href:"https://github.com/yichya/openwrt-xray",target:"_blank",rel:"noopener noreferrer"},de={href:"https://github.com/2dust/v2rayN",target:"_blank",rel:"noopener noreferrer"},ue={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},pe={href:"https://github.com/NetchX/Netch",target:"_blank",rel:"noopener noreferrer"},_e={href:"https://github.com/2dust/v2rayNG",target:"_blank",rel:"noopener noreferrer"},fe={href:"https://github.com/rurirei/Kitsunebi/tree/release_xtls",target:"_blank",rel:"noopener noreferrer"},be={href:"https://apps.apple.com/app/shadowrocket/id932747118",target:"_blank",rel:"noopener noreferrer"},ge={href:"https://apps.apple.com/app/stash/id1596063349",target:"_blank",rel:"noopener noreferrer"},me={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},ye={href:"https://github.com/tzmax/V2RayXS",target:"_blank",rel:"noopener noreferrer"},xe=e("h1",{id:"uuid-generator",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#uuid-generator"},[e("span",null,"UUID Generator")])],-1),ke={href:"https://www.uuidgenerator.net",target:"_blank",rel:"noopener noreferrer"};function we(ve,Se){const a=t("ExternalLinkIcon"),o=t("Badge");return i(),h("div",null,[d,e("p",null,[r("Precompiled binaries in ZIP format are available at "),e("a",u,[r("GitHub Releases"),n(a)]),r(" found in.")]),p,_,f,e("ul",null,[b,e("li",null,[r("Reproducible build: Please refer to "),e("a",g,[r("Compile Xray"),n(a)])])]),m,e("ul",null,[e("li",null,[r("Download the ZIP archive suitable for the Windows platform on "),e("a",y,[r("Github Releases"),n(a)]),r(". After decompression, you can get an executable file "),x,r(", and then run it with "),k,r(" through the command line.")]),e("li",null,[r("By "),e("a",w,[r("Scoop"),n(a)]),r(" Package manager installation: Xray has been added to "),e("a",v,[r("Mochi"),n(a)]),r(".")])]),S,e("ul",null,[e("li",null,[r("Download the ZIP archive suitable for the macOS platform on "),e("a",X,[r("Github Releases"),n(a)]),r(". After decompression, you can get an executable file "),I,r(", and then run it with "),N,r(" through the command line.")]),e("li",null,[r("By "),e("a",A,[r("Homebrew"),n(a)]),r(" Package manager installation: "),P]),e("li",null,[e("a",D,[r("homebrew-xray"),n(a)]),r(": Thanks "),e("a",R,[r("@N4FA"),n(a)])])]),L,T,e("ul",null,[e("li",null,[U,e("ul",null,[e("li",null,[e("a",B,[r("Xray-install"),n(a)])])])])]),e("ul",null,[e("li",null,[O,e("ul",null,[e("li",null,[e("a",F,[r("Xray-script"),n(a)])]),e("li",null,[e("a",M,[r("ProxySU"),n(a)])]),e("li",null,[e("a",C,[r("Xray-agent"),n(a)]),r(" Thanks "),e("a",W,[r("@mack-a"),n(a)]),r(),e("a",G,[r("@Reece"),n(a)])])])]),e("li",null,[Q,e("ul",null,[e("li",null,[e("a",V,[r("Xray4Magisk"),n(a)])]),e("li",null,[e("a",j,[r("Xray_For_Magisk"),n(a)])])])])]),H,E,e("p",null,[r("Need to use "),e("a",K,[r("AUR helpers"),n(a)]),r(", "),e("a",Z,[r("yay"),n(a)]),r(" as an example, it can be installed via "),q,r(".")]),z,e("p",null,[r("First add "),e("a",J,[r("Arch Linux CN"),n(a)]),r(" repository, and then use the root user "),Y,r("to install.")]),$,ee,e("h3",re,[e("a",ne,[e("span",null,[r("Debian "),n(o,{text:"WIP",type:"warning"})])])]),ae,e("ul",null,[e("li",null,[e("a",te,[r("teddysun/xray"),n(a)])])]),le,e("ul",null,[e("li",null,[r("OpenWrt "),e("ul",null,[e("li",null,[e("a",oe,[r("PassWall"),n(a)])]),e("li",null,[e("a",se,[r("Hello World"),n(a)])]),e("li",null,[e("a",ie,[r("ShadowSocksR Plus+"),n(a)])]),e("li",null,[e("a",he,[r("luci-app-xray"),n(a)]),r(" ("),e("a",ce,[r("openwrt-xray"),n(a)]),r(")")])])]),e("li",null,[r("Windows "),e("ul",null,[e("li",null,[e("a",de,[r("v2rayN"),n(a)])]),e("li",null,[e("a",ue,[r("Qv2ray"),n(a)]),r(" (This project has been and archived)")]),e("li",null,[e("a",pe,[r("Netch (NetFilter & TUN/TAP)"),n(a)]),r(" (This project has been and archived)")])])]),e("li",null,[r("Android "),e("ul",null,[e("li",null,[e("a",_e,[r("v2rayNG"),n(a)])]),e("li",null,[e("a",fe,[r("Kitsunebi"),n(a)])])])]),e("li",null,[r("iOS / macOS (ARM) "),e("ul",null,[e("li",null,[e("a",be,[r("Shadowrocket"),n(a)])]),e("li",null,[e("a",ge,[r("Stash"),n(a)])])])]),e("li",null,[r("macOS (X86/ARM) "),e("ul",null,[e("li",null,[e("a",me,[r("Qv2ray"),n(a)]),r(" (This project has been and archived)")]),e("li",null,[e("a",ye,[r("V2RayXS"),n(a)])])])])]),xe,e("p",null,[r("Third-party UUID generator "),e("a",ke,[r("uuidgenerator.net"),n(a)])])])}const Ie=s(c,[["render",we],["__file","install.html.vue"]]);export{Ie as default}; diff --git a/assets/iptables_gid.html-dUUEZycZ.js b/assets/iptables_gid.html-XKlKifPE.js similarity index 99% rename from assets/iptables_gid.html-dUUEZycZ.js rename to assets/iptables_gid.html-XKlKifPE.js index 687259875c..75696c2349 100644 --- a/assets/iptables_gid.html-dUUEZycZ.js +++ b/assets/iptables_gid.html-XKlKifPE.js @@ -1,4 +1,4 @@ -import{_ as i,r,o,c as l,a,b as e,d as n,w as c,e as t}from"./app-PDrbPfzp.js";const d={},u=a("h1",{id:"transparent-proxy-to-circumvent-xray-traffic-via-gid",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#transparent-proxy-to-circumvent-xray-traffic-via-gid"},[a("span",null,"Transparent proxy to circumvent Xray traffic via GID")])],-1),m={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},b={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},v=a("p",null,"There are several problems with this method:",-1),h={href:"https://github.com/v2ray/v2ray-core/issues/2621",target:"_blank",rel:"noopener noreferrer"},k=a("li",null,[a("p",null,"Android has its own mark mechanism and this solution is not available on Android")],-1),g=t('

                        The solution in this tutorial does not require a mark setting and has a higher theoretical performance, as well as not having the problems mentioned above.

                        Ideas

                        TProxy traffic can only be received by users with root privileges (uid==0) or other users with CAP_NET_ADMIN privileges.

                        The iptables rules can separate network traffic by uid (user id) and gid (user group id). Let Xray run on a user with uid==0 but gid!=0. Set the iptables rule to not proxy traffic for that gid to circumvent Xray traffic.

                        Configuration Procedure

                        1. Preliminary preparation

                        Android

                        ',7),f=a("li",null,[a("p",null,"System has root privilege.")],-1),y={href:"https://play.google.com/store/apps/details?id=stericson.busybox",target:"_blank",rel:"noopener noreferrer"},x=a("li",null,[a("p",null,"There is a terminal that can execute commands, you can use adb shell, termux etc.")],-1),_=t(`

                        Other Linux system

                        Need sudo, iptables-tproxy module and iptables-extra module。

                        Usually the system comes with these functions. If you are using openwrt, you will need to run the following command:

                        opkg install sudo iptables-mod-tproxy iptables-mod-extra
                        +import{_ as i,r,o,c as l,a,b as e,d as n,w as c,e as t}from"./app-UOvWaKji.js";const d={},u=a("h1",{id:"transparent-proxy-to-circumvent-xray-traffic-via-gid",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#transparent-proxy-to-circumvent-xray-traffic-via-gid"},[a("span",null,"Transparent proxy to circumvent Xray traffic via GID")])],-1),m={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},b={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},v=a("p",null,"There are several problems with this method:",-1),h={href:"https://github.com/v2ray/v2ray-core/issues/2621",target:"_blank",rel:"noopener noreferrer"},k=a("li",null,[a("p",null,"Android has its own mark mechanism and this solution is not available on Android")],-1),g=t('

                        The solution in this tutorial does not require a mark setting and has a higher theoretical performance, as well as not having the problems mentioned above.

                        Ideas

                        TProxy traffic can only be received by users with root privileges (uid==0) or other users with CAP_NET_ADMIN privileges.

                        The iptables rules can separate network traffic by uid (user id) and gid (user group id). Let Xray run on a user with uid==0 but gid!=0. Set the iptables rule to not proxy traffic for that gid to circumvent Xray traffic.

                        Configuration Procedure

                        1. Preliminary preparation

                        Android

                        ',7),f=a("li",null,[a("p",null,"System has root privilege.")],-1),y={href:"https://play.google.com/store/apps/details?id=stericson.busybox",target:"_blank",rel:"noopener noreferrer"},x=a("li",null,[a("p",null,"There is a terminal that can execute commands, you can use adb shell, termux etc.")],-1),_=t(`

                        Other Linux system

                        Need sudo, iptables-tproxy module and iptables-extra module。

                        Usually the system comes with these functions. If you are using openwrt, you will need to run the following command:

                        opkg install sudo iptables-mod-tproxy iptables-mod-extra
                         

                        Also attached are some common dependencies for openwrt, the lack of which may prevent Xray from running

                        opkg install libopenssl ca-certificates
                         

                        2. Add user (Android users please ignore this section)

                        Android does not support managing users by modifying the /etc/passwd file, please ignore it and go straight to the next step.

                        grep -qw xray_tproxy /etc/passwd || echo "xray_tproxy:x:0:23333:::" >> /etc/passwd
                         

                        where xray_tproxy is the username, 0 is the uid and 23333 is the gid, the username and gid can be set by yourself, the uid must be 0. To check if the user was added successfully, run

                        sudo -u xray_tproxy id
                        diff --git a/assets/iptables_gid.html-PN1dGUsZ.js b/assets/iptables_gid.html-f-TyOGt0.js
                        similarity index 99%
                        rename from assets/iptables_gid.html-PN1dGUsZ.js
                        rename to assets/iptables_gid.html-f-TyOGt0.js
                        index 39ee8ac98b..c16068e7e0 100644
                        --- a/assets/iptables_gid.html-PN1dGUsZ.js
                        +++ b/assets/iptables_gid.html-f-TyOGt0.js
                        @@ -1,4 +1,4 @@
                        -import{_ as t,r,o as l,c as i,a,b as s,d as e,e as p}from"./app-PDrbPfzp.js";const o={},c=a("h1",{id:"透明代理通过-gid-规避-xray-流量",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理通过-gid-规避-xray-流量"},[a("span",null,"透明代理通过 gid 规避 Xray 流量")])],-1),d={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},m={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},v=a("strong",null,[a("a",{href:"./tproxy"},"透明代理(TProxy)配置教程")],-1),u=a("p",null,"这么做有以下几个问题:",-1),b={href:"https://github.com/v2ray/v2ray-core/issues/2621",target:"_blank",rel:"noopener noreferrer"},k=a("li",null,[a("p",null,"安卓系统有自己的 mark 机制,该方案在安卓上不可用")],-1),g=p('

                        本教程的方案不需要设置 mark,理论性能更高,同时也不存在上述问题。

                        思路

                        tproxy 流量只能被 root 权限用户(uid==0)或其他有 CAP_NET_ADMIN 权限的用户接收。

                        iptables 规则可以通过 uid(用户 id)和 gid(用户组 id)分流。

                        让 Xray 运行在一个 uid==0 但 gid!=0 的用户上,设置 iptables 规则不代理该 gid 的流量来规避 Xray 流量。

                        配置过程

                        1. 前期准备

                        安卓系统

                        ',8),h=a("li",null,[a("p",null,"系统已 root")],-1),_={href:"https://play.google.com/store/apps/details?id=stericson.busybox",target:"_blank",rel:"noopener noreferrer"},A=a("li",null,[a("p",null,"有一个可以执行命令的终端,可以使用 adb shell,termux 等。")],-1),y=p(`

                        其它 Linux 系统

                        需要依赖 sudo,iptables 的 tproxy 模块和 extra 模块。

                        一般系统都有自带,openwrt 运行:

                        opkg install sudo iptables-mod-tproxy iptables-mod-extra
                        +import{_ as t,r,o as l,c as i,a,b as s,d as e,e as p}from"./app-UOvWaKji.js";const o={},c=a("h1",{id:"透明代理通过-gid-规避-xray-流量",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理通过-gid-规避-xray-流量"},[a("span",null,"透明代理通过 gid 规避 Xray 流量")])],-1),d={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},m={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},v=a("strong",null,[a("a",{href:"./tproxy"},"透明代理(TProxy)配置教程")],-1),u=a("p",null,"这么做有以下几个问题:",-1),b={href:"https://github.com/v2ray/v2ray-core/issues/2621",target:"_blank",rel:"noopener noreferrer"},k=a("li",null,[a("p",null,"安卓系统有自己的 mark 机制,该方案在安卓上不可用")],-1),g=p('

                        本教程的方案不需要设置 mark,理论性能更高,同时也不存在上述问题。

                        思路

                        tproxy 流量只能被 root 权限用户(uid==0)或其他有 CAP_NET_ADMIN 权限的用户接收。

                        iptables 规则可以通过 uid(用户 id)和 gid(用户组 id)分流。

                        让 Xray 运行在一个 uid==0 但 gid!=0 的用户上,设置 iptables 规则不代理该 gid 的流量来规避 Xray 流量。

                        配置过程

                        1. 前期准备

                        安卓系统

                        ',8),h=a("li",null,[a("p",null,"系统已 root")],-1),_={href:"https://play.google.com/store/apps/details?id=stericson.busybox",target:"_blank",rel:"noopener noreferrer"},A=a("li",null,[a("p",null,"有一个可以执行命令的终端,可以使用 adb shell,termux 等。")],-1),y=p(`

                        其它 Linux 系统

                        需要依赖 sudo,iptables 的 tproxy 模块和 extra 模块。

                        一般系统都有自带,openwrt 运行:

                        opkg install sudo iptables-mod-tproxy iptables-mod-extra
                         

                        另附上一些 openwrt 常用的依赖,缺少可能导致 Xray 无法运行

                        opkg install libopenssl ca-certificates
                         

                        2. 添加用户(安卓用户请忽略)

                        安卓系统不支持/etc/passwd 文件来管理用户,请忽略,直接下一步。

                        grep -qw xray_tproxy /etc/passwd || echo "xray_tproxy:x:0:23333:::" >> /etc/passwd
                         

                        其中 xray_tproxy 是用户名,0 是 uid,23333 是 gid,用户名和 gid 可以自己定,uid 必须为 0。 检查用户是否添加成功,运行

                        sudo -u xray_tproxy id
                        diff --git a/assets/journeyDiagram-4fe6b3dc-5Up4aSjD.js b/assets/journeyDiagram-4fe6b3dc-v7Caieti.js
                        similarity index 98%
                        rename from assets/journeyDiagram-4fe6b3dc-5Up4aSjD.js
                        rename to assets/journeyDiagram-4fe6b3dc-v7Caieti.js
                        index d53aac27e0..68dc07f7e2 100644
                        --- a/assets/journeyDiagram-4fe6b3dc-5Up4aSjD.js
                        +++ b/assets/journeyDiagram-4fe6b3dc-v7Caieti.js
                        @@ -1,4 +1,4 @@
                        -import{c as A,x as yt,y as ft,s as dt,g as pt,b as gt,a as mt,A as xt,h as W,i as kt}from"./mermaid.core-95b3ca__.js";import{d as _t,f as bt,a as vt,g as it}from"./svgDrawCommon-5ccd53ef-iJa2TVTb.js";import{a as Q}from"./arc-XT00965o.js";import"./app-PDrbPfzp.js";import"./path-aUcfwwLI.js";var G=function(){var t=function(p,s,r,a){for(r=r||{},a=p.length;a--;r[p[a]]=s);return r},e=[6,8,10,11,12,14,16,17,18],i=[1,9],l=[1,10],n=[1,11],h=[1,12],c=[1,13],f=[1,14],y={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:function(s,r,a,u,d,o,w){var k=o.length-1;switch(d){case 1:return o[k-1];case 2:this.$=[];break;case 3:o[k-1].push(o[k]),this.$=o[k-1];break;case 4:case 5:this.$=o[k];break;case 6:case 7:this.$=[];break;case 8:u.setDiagramTitle(o[k].substr(6)),this.$=o[k].substr(6);break;case 9:this.$=o[k].trim(),u.setAccTitle(this.$);break;case 10:case 11:this.$=o[k].trim(),u.setAccDescription(this.$);break;case 12:u.addSection(o[k].substr(8)),this.$=o[k].substr(8);break;case 13:u.addTask(o[k-1],o[k]),this.$="task";break}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:i,12:l,14:n,16:h,17:c,18:f},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:i,12:l,14:n,16:h,17:c,18:f},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:function(s,r){if(r.recoverable)this.trace(s);else{var a=new Error(s);throw a.hash=r,a}},parse:function(s){var r=this,a=[0],u=[],d=[null],o=[],w=this.table,k="",R=0,Z=0,lt=2,J=1,ct=o.slice.call(arguments,1),x=Object.create(this.lexer),S={yy:{}};for(var z in this.yy)Object.prototype.hasOwnProperty.call(this.yy,z)&&(S.yy[z]=this.yy[z]);x.setInput(s,S.yy),S.yy.lexer=x,S.yy.parser=this,typeof x.yylloc>"u"&&(x.yylloc={});var Y=x.yylloc;o.push(Y);var ht=x.options&&x.options.ranges;typeof S.yy.parseError=="function"?this.parseError=S.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ut(){var T;return T=u.pop()||x.lex()||J,typeof T!="number"&&(T instanceof Array&&(u=T,T=u.pop()),T=r.symbols_[T]||T),T}for(var _,E,b,O,I={},N,$,K,B;;){if(E=a[a.length-1],this.defaultActions[E]?b=this.defaultActions[E]:((_===null||typeof _>"u")&&(_=ut()),b=w[E]&&w[E][_]),typeof b>"u"||!b.length||!b[0]){var q="";B=[];for(N in w[E])this.terminals_[N]&&N>lt&&B.push("'"+this.terminals_[N]+"'");x.showPosition?q="Parse error on line "+(R+1)+`:
                        +import{c as A,x as yt,y as ft,s as dt,g as pt,b as gt,a as mt,A as xt,h as W,i as kt}from"./mermaid.core-Q3WVcjPF.js";import{d as _t,f as bt,a as vt,g as it}from"./svgDrawCommon-5ccd53ef-wBNBFr7n.js";import{a as Q}from"./arc-5GdQY_kf.js";import"./app-UOvWaKji.js";import"./path-aUcfwwLI.js";var G=function(){var t=function(p,s,r,a){for(r=r||{},a=p.length;a--;r[p[a]]=s);return r},e=[6,8,10,11,12,14,16,17,18],i=[1,9],l=[1,10],n=[1,11],h=[1,12],c=[1,13],f=[1,14],y={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:function(s,r,a,u,d,o,w){var k=o.length-1;switch(d){case 1:return o[k-1];case 2:this.$=[];break;case 3:o[k-1].push(o[k]),this.$=o[k-1];break;case 4:case 5:this.$=o[k];break;case 6:case 7:this.$=[];break;case 8:u.setDiagramTitle(o[k].substr(6)),this.$=o[k].substr(6);break;case 9:this.$=o[k].trim(),u.setAccTitle(this.$);break;case 10:case 11:this.$=o[k].trim(),u.setAccDescription(this.$);break;case 12:u.addSection(o[k].substr(8)),this.$=o[k].substr(8);break;case 13:u.addTask(o[k-1],o[k]),this.$="task";break}},table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:i,12:l,14:n,16:h,17:c,18:f},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:i,12:l,14:n,16:h,17:c,18:f},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:function(s,r){if(r.recoverable)this.trace(s);else{var a=new Error(s);throw a.hash=r,a}},parse:function(s){var r=this,a=[0],u=[],d=[null],o=[],w=this.table,k="",R=0,Z=0,lt=2,J=1,ct=o.slice.call(arguments,1),x=Object.create(this.lexer),S={yy:{}};for(var z in this.yy)Object.prototype.hasOwnProperty.call(this.yy,z)&&(S.yy[z]=this.yy[z]);x.setInput(s,S.yy),S.yy.lexer=x,S.yy.parser=this,typeof x.yylloc>"u"&&(x.yylloc={});var Y=x.yylloc;o.push(Y);var ht=x.options&&x.options.ranges;typeof S.yy.parseError=="function"?this.parseError=S.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ut(){var T;return T=u.pop()||x.lex()||J,typeof T!="number"&&(T instanceof Array&&(u=T,T=u.pop()),T=r.symbols_[T]||T),T}for(var _,E,b,O,I={},N,$,K,B;;){if(E=a[a.length-1],this.defaultActions[E]?b=this.defaultActions[E]:((_===null||typeof _>"u")&&(_=ut()),b=w[E]&&w[E][_]),typeof b>"u"||!b.length||!b[0]){var q="";B=[];for(N in w[E])this.terminals_[N]&&N>lt&&B.push("'"+this.terminals_[N]+"'");x.showPosition?q="Parse error on line "+(R+1)+`:
                         `+x.showPosition()+`
                         Expecting `+B.join(", ")+", got '"+(this.terminals_[_]||_)+"'":q="Parse error on line "+(R+1)+": Unexpected "+(_==J?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(q,{text:x.match,token:this.terminals_[_]||_,line:x.yylineno,loc:Y,expected:B})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+_);switch(b[0]){case 1:a.push(_),d.push(x.yytext),o.push(x.yylloc),a.push(b[1]),_=null,Z=x.yyleng,k=x.yytext,R=x.yylineno,Y=x.yylloc;break;case 2:if($=this.productions_[b[1]][1],I.$=d[d.length-$],I._$={first_line:o[o.length-($||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-($||1)].first_column,last_column:o[o.length-1].last_column},ht&&(I._$.range=[o[o.length-($||1)].range[0],o[o.length-1].range[1]]),O=this.performAction.apply(I,[k,Z,R,S.yy,b[1],d,o].concat(ct)),typeof O<"u")return O;$&&(a=a.slice(0,-1*$*2),d=d.slice(0,-1*$),o=o.slice(0,-1*$)),a.push(this.productions_[b[1]][0]),d.push(I.$),o.push(I._$),K=w[a[a.length-2]][a[a.length-1]],a.push(K);break;case 3:return!0}}return!0}},m=function(){var p={EOF:1,parseError:function(r,a){if(this.yy.parser)this.yy.parser.parseError(r,a);else throw new Error(r)},setInput:function(s,r){return this.yy=r||this.yy||{},this._input=s,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var s=this._input[0];this.yytext+=s,this.yyleng++,this.offset++,this.match+=s,this.matched+=s;var r=s.match(/(?:\r\n?|\n).*/g);return r?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),s},unput:function(s){var r=s.length,a=s.split(/(?:\r\n?|\n)/g);this._input=s+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-r),this.offset-=r;var u=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var d=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===u.length?this.yylloc.first_column:0)+u[u.length-a.length].length-a[0].length:this.yylloc.first_column-r},this.options.ranges&&(this.yylloc.range=[d[0],d[0]+this.yyleng-r]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
                         `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(s){this.unput(this.match.slice(s))},pastInput:function(){var s=this.matched.substr(0,this.matched.length-this.match.length);return(s.length>20?"...":"")+s.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var s=this.match;return s.length<20&&(s+=this._input.substr(0,20-s.length)),(s.substr(0,20)+(s.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var s=this.pastInput(),r=new Array(s.length+1).join("-");return s+this.upcomingInput()+`
                        diff --git a/assets/layout-konkdG3Z.js b/assets/layout-2f_iGf4E.js
                        similarity index 99%
                        rename from assets/layout-konkdG3Z.js
                        rename to assets/layout-2f_iGf4E.js
                        index 20bd80fda1..f5f4a8c2dc 100644
                        --- a/assets/layout-konkdG3Z.js
                        +++ b/assets/layout-2f_iGf4E.js
                        @@ -1 +1 @@
                        -import{i as F,b as xn,a as zn,c as L,k as Un,d as Hn,e as Kn,g as P,j as En,l as kn,m as yn,t as jn,n as Nn,o as Jn,p as Qn,f as s,G as x,h as w,q as g,r as M,v as y,s as V}from"./graph-cZfODKa1.js";import{R as A,ag as Zn,ah as ne,ai as ee,a6 as Ln,aj as B,K as _n,_ as re,E as Cn,D as j,a4 as te,ak as ie,a3 as J,a2 as ae,Y as In,Q as oe,a8 as ue,al as H}from"./mermaid.core-95b3ca__.js";var de=/\s/;function fe(n){for(var e=n.length;e--&&de.test(n.charAt(e)););return e}var se=/^\s+/;function ce(n){return n&&n.slice(0,fe(n)+1).replace(se,"")}var un=NaN,he=/^[-+]0x[0-9a-f]+$/i,le=/^0b[01]+$/i,ve=/^0o[0-7]+$/i,pe=parseInt;function we(n){if(typeof n=="number")return n;if(F(n))return un;if(A(n)){var e=typeof n.valueOf=="function"?n.valueOf():n;n=A(e)?e+"":e}if(typeof n!="string")return n===0?n:+n;n=ce(n);var r=le.test(n);return r||ve.test(n)?pe(n.slice(2),r?2:8):he.test(n)?un:+n}var dn=1/0,me=17976931348623157e292;function S(n){if(!n)return n===0?n:0;if(n=we(n),n===dn||n===-dn){var e=n<0?-1:1;return e*me}return n===n?n:0}function be(n){var e=S(n),r=e%1;return e===e?r?e-r:e:0}function _(n){var e=n==null?0:n.length;return e?xn(n,1):[]}function ge(n){return Zn(ne(n,void 0,_),n+"")}var xe=1,Ee=4;function ke(n){return zn(n,xe|Ee)}var fn=function(){return ee.Date.now()},Rn=Object.prototype,ye=Rn.hasOwnProperty,Ne=Ln(function(n,e){n=Object(n);var r=-1,t=e.length,i=t>2?e[2]:void 0;for(i&&B(e[0],e[1],i)&&(t=1);++r-1?i[o?e[a]:a]:void 0}}var Ce=Math.max;function Ie(n,e,r){var t=n==null?0:n.length;if(!t)return-1;var i=r==null?0:be(r);return i<0&&(i=Ce(t+i,0)),Hn(n,L(e),i)}var Q=_e(Ie);function Tn(n,e){var r=-1,t=Cn(n)?Array(n.length):[];return Kn(n,function(i,o,a){t[++r]=e(i,o,a)}),t}function m(n,e){var r=j(n)?P:Tn;return r(n,L(e))}function Re(n,e){return n==null?n:te(n,En(e),_n)}function Te(n,e){return n&&kn(n,En(e))}function Me(n,e){return n>e}function Mn(n,e){return ne||o&&a&&d&&!u&&!f||t&&a&&d||!r&&d||!i)return 1;if(!t&&!o&&!f&&n=u)return d;var f=r[t];return d*(f=="desc"?-1:1)}}return n.index-e.index}function Be(n,e,r){e.length?e=P(e,function(o){return j(o)?function(a){return Nn(a,o.length===1?o[0]:o)}:o}):e=[J];var t=-1;e=P(e,oe(L));var i=Tn(n,function(o,a,u){var d=P(e,function(f){return f(o)});return{criteria:d,index:++t,value:o}});return Se(i,function(o,a){return Ae(o,a,r)})}function Ge(n,e){return Pe(n,e,function(r,t){return Jn(n,t)})}var Y=ge(function(n,e){return n==null?{}:Ge(n,e)}),Ye=Math.ceil,Ve=Math.max;function $e(n,e,r,t){for(var i=-1,o=Ve(Ye((e-n)/(r||1)),0),a=Array(o);o--;)a[t?o:++i]=n,n+=r;return a}function De(n){return function(e,r,t){return t&&typeof t!="number"&&B(e,r,t)&&(r=t=void 0),e=S(e),r===void 0?(r=e,e=0):r=S(r),t=t===void 0?e1&&B(n,e[0],e[1])?e=[]:r>2&&B(e[0],e[1],e[2])&&(e=[e[0]]),Be(n,xn(e,1),[])}),qe=0;function en(n){var e=++qe;return Qn(n)+e}function We(n,e,r){for(var t=-1,i=n.length,o=e.length,a={};++t0;--u)if(a=e[u].dequeue(),a){t=t.concat(q(n,e,r,a,!0));break}}}return t}function q(n,e,r,t,i){var o=i?[]:void 0;return s(n.inEdges(t.v),function(a){var u=n.edge(a),d=n.node(a.v);i&&o.push({v:a.v,w:a.w}),d.out-=u,K(e,r,d)}),s(n.outEdges(t.v),function(a){var u=n.edge(a),d=a.w,f=n.node(d);f.in-=u,K(e,r,f)}),n.removeNode(t.v),o}function Je(n,e){var r=new x,t=0,i=0;s(n.nodes(),function(u){r.setNode(u,{v:u,in:0,out:0})}),s(n.edges(),function(u){var d=r.edge(u.v,u.w)||0,f=e(u),c=d+f;r.setEdge(u.v,u.w,c),i=Math.max(i,r.node(u.v).out+=f),t=Math.max(t,r.node(u.w).in+=f)});var o=N(i+t+3).map(function(){return new ze}),a=t+1;return s(r.nodes(),function(u){K(o,a,r.node(u))}),{graph:r,buckets:o,zeroIdx:a}}function K(n,e,r){r.out?r.in?n[r.out-r.in+e].enqueue(r):n[n.length-1].enqueue(r):n[0].enqueue(r)}function Qe(n){var e=n.graph().acyclicer==="greedy"?Ke(n,r(n)):Ze(n);s(e,function(t){var i=n.edge(t);n.removeEdge(t),i.forwardName=t.name,i.reversed=!0,n.setEdge(t.w,t.v,i,en("rev"))});function r(t){return function(i){return t.edge(i).weight}}}function Ze(n){var e=[],r={},t={};function i(o){w(t,o)||(t[o]=!0,r[o]=!0,s(n.outEdges(o),function(a){w(r,a.w)?e.push(a):i(a.w)}),delete r[o])}return s(n.nodes(),i),e}function nr(n){s(n.edges(),function(e){var r=n.edge(e);if(r.reversed){n.removeEdge(e);var t=r.forwardName;delete r.reversed,delete r.forwardName,n.setEdge(e.w,e.v,r,t)}})}function C(n,e,r,t){var i;do i=en(t);while(n.hasNode(i));return r.dummy=e,n.setNode(i,r),i}function er(n){var e=new x().setGraph(n.graph());return s(n.nodes(),function(r){e.setNode(r,n.node(r))}),s(n.edges(),function(r){var t=e.edge(r.v,r.w)||{weight:0,minlen:1},i=n.edge(r);e.setEdge(r.v,r.w,{weight:t.weight+i.weight,minlen:Math.max(t.minlen,i.minlen)})}),e}function On(n){var e=new x({multigraph:n.isMultigraph()}).setGraph(n.graph());return s(n.nodes(),function(r){n.children(r).length||e.setNode(r,n.node(r))}),s(n.edges(),function(r){e.setEdge(r,n.edge(r))}),e}function cn(n,e){var r=n.x,t=n.y,i=e.x-r,o=e.y-t,a=n.width/2,u=n.height/2;if(!i&&!o)throw new Error("Not possible to find intersection inside of the rectangle");var d,f;return Math.abs(o)*a>Math.abs(i)*u?(o<0&&(u=-u),d=u*i/o,f=u):(i<0&&(a=-a),d=a,f=a*o/i),{x:r+d,y:t+f}}function D(n){var e=m(N(Pn(n)+1),function(){return[]});return s(n.nodes(),function(r){var t=n.node(r),i=t.rank;g(i)||(e[i][t.order]=r)}),e}function rr(n){var e=R(m(n.nodes(),function(r){return n.node(r).rank}));s(n.nodes(),function(r){var t=n.node(r);w(t,"rank")&&(t.rank-=e)})}function tr(n){var e=R(m(n.nodes(),function(o){return n.node(o).rank})),r=[];s(n.nodes(),function(o){var a=n.node(o).rank-e;r[a]||(r[a]=[]),r[a].push(o)});var t=0,i=n.graph().nodeRankFactor;s(r,function(o,a){g(o)&&a%i!==0?--t:t&&s(o,function(u){n.node(u).rank+=t})})}function hn(n,e,r,t){var i={width:0,height:0};return arguments.length>=4&&(i.rank=r,i.order=t),C(n,"border",i,e)}function Pn(n){return E(m(n.nodes(),function(e){var r=n.node(e).rank;if(!g(r))return r}))}function ir(n,e){var r={lhs:[],rhs:[]};return s(n,function(t){e(t)?r.lhs.push(t):r.rhs.push(t)}),r}function ar(n,e){var r=fn();try{return e()}finally{console.log(n+" time: "+(fn()-r)+"ms")}}function or(n,e){return e()}function ur(n){function e(r){var t=n.children(r),i=n.node(r);if(t.length&&s(t,e),w(i,"minRank")){i.borderLeft=[],i.borderRight=[];for(var o=i.minRank,a=i.maxRank+1;oa.lim&&(u=a,d=!0);var f=M(e.edges(),function(c){return d===pn(n,n.node(c.v),u)&&d!==pn(n,n.node(c.w),u)});return nn(f,function(c){return T(e,c)})}function Dn(n,e,r,t){var i=r.v,o=r.w;n.removeEdge(i,o),n.setEdge(t.v,t.w,{}),an(n),tn(n,e),kr(n,e)}function kr(n,e){var r=Q(n.nodes(),function(i){return!e.node(i).parent}),t=xr(n,r);t=t.slice(1),s(t,function(i){var o=n.node(i).parent,a=e.edge(i,o),u=!1;a||(a=e.edge(o,i),u=!0),e.node(i).rank=e.node(o).rank+(u?a.minlen:-a.minlen)})}function yr(n,e,r){return n.hasEdge(e,r)}function pn(n,e,r){return r.low<=e.lim&&e.lim<=r.lim}function Nr(n){switch(n.graph().ranker){case"network-simplex":wn(n);break;case"tight-tree":_r(n);break;case"longest-path":Lr(n);break;default:wn(n)}}var Lr=rn;function _r(n){rn(n),Fn(n)}function wn(n){k(n)}function Cr(n){var e=C(n,"root",{},"_root"),r=Ir(n),t=E(y(r))-1,i=2*t+1;n.graph().nestingRoot=e,s(n.edges(),function(a){n.edge(a).minlen*=i});var o=Rr(n)+1;s(n.children(),function(a){qn(n,e,i,o,t,r,a)}),n.graph().nodeRankFactor=i}function qn(n,e,r,t,i,o,a){var u=n.children(a);if(!u.length){a!==e&&n.setEdge(e,a,{weight:0,minlen:r});return}var d=hn(n,"_bt"),f=hn(n,"_bb"),c=n.node(a);n.setParent(d,a),c.borderTop=d,n.setParent(f,a),c.borderBottom=f,s(u,function(h){qn(n,e,r,t,i,o,h);var l=n.node(h),v=l.borderTop?l.borderTop:h,p=l.borderBottom?l.borderBottom:h,b=l.borderTop?t:2*t,I=v!==p?1:i-o[a]+1;n.setEdge(d,v,{weight:b,minlen:I,nestingEdge:!0}),n.setEdge(p,f,{weight:b,minlen:I,nestingEdge:!0})}),n.parent(a)||n.setEdge(e,d,{weight:0,minlen:i+o[a]})}function Ir(n){var e={};function r(t,i){var o=n.children(t);o&&o.length&&s(o,function(a){r(a,i+1)}),e[t]=i}return s(n.children(),function(t){r(t,1)}),e}function Rr(n){return V(n.edges(),function(e,r){return e+n.edge(r).weight},0)}function Tr(n){var e=n.graph();n.removeNode(e.nestingRoot),delete e.nestingRoot,s(n.edges(),function(r){var t=n.edge(r);t.nestingEdge&&n.removeEdge(r)})}function Mr(n,e,r){var t={},i;s(r,function(o){for(var a=n.parent(o),u,d;a;){if(u=n.parent(a),u?(d=t[u],t[u]=a):(d=i,i=a),d&&d!==a){e.setEdge(d,a);return}a=u}})}function Or(n,e,r){var t=Pr(n),i=new x({compound:!0}).setGraph({root:t}).setDefaultNodeLabel(function(o){return n.node(o)});return s(n.nodes(),function(o){var a=n.node(o),u=n.parent(o);(a.rank===e||a.minRank<=e&&e<=a.maxRank)&&(i.setNode(o),i.setParent(o,u||t),s(n[r](o),function(d){var f=d.v===o?d.w:d.v,c=i.edge(f,o),h=g(c)?0:c.weight;i.setEdge(f,o,{weight:n.edge(d).weight+h})}),w(a,"minRank")&&i.setNode(o,{borderLeft:a.borderLeft[e],borderRight:a.borderRight[e]}))}),i}function Pr(n){for(var e;n.hasNode(e=en("_root")););return e}function Sr(n,e){for(var r=0,t=1;t0;)c%2&&(h+=u[c+1]),c=c-1>>1,u[c]+=f.weight;d+=f.weight*h})),d}function Ar(n){var e={},r=M(n.nodes(),function(u){return!n.children(u).length}),t=E(m(r,function(u){return n.node(u).rank})),i=m(N(t+1),function(){return[]});function o(u){if(!w(e,u)){e[u]=!0;var d=n.node(u);i[d.rank].push(u),s(n.successors(u),o)}}var a=O(r,function(u){return n.node(u).rank});return s(a,o),i}function Br(n,e){return m(e,function(r){var t=n.inEdges(r);if(t.length){var i=V(t,function(o,a){var u=n.edge(a),d=n.node(a.v);return{sum:o.sum+u.weight*d.order,weight:o.weight+u.weight}},{sum:0,weight:0});return{v:r,barycenter:i.sum/i.weight,weight:i.weight}}else return{v:r}})}function Gr(n,e){var r={};s(n,function(i,o){var a=r[i.v]={indegree:0,in:[],out:[],vs:[i.v],i:o};g(i.barycenter)||(a.barycenter=i.barycenter,a.weight=i.weight)}),s(e.edges(),function(i){var o=r[i.v],a=r[i.w];!g(o)&&!g(a)&&(a.indegree++,o.out.push(r[i.w]))});var t=M(r,function(i){return!i.indegree});return Yr(t)}function Yr(n){var e=[];function r(o){return function(a){a.merged||(g(a.barycenter)||g(o.barycenter)||a.barycenter>=o.barycenter)&&Vr(o,a)}}function t(o){return function(a){a.in.push(o),--a.indegree===0&&n.push(a)}}for(;n.length;){var i=n.pop();e.push(i),s(i.in.reverse(),r(i)),s(i.out,t(i))}return m(M(e,function(o){return!o.merged}),function(o){return Y(o,["vs","i","barycenter","weight"])})}function Vr(n,e){var r=0,t=0;n.weight&&(r+=n.barycenter*n.weight,t+=n.weight),e.weight&&(r+=e.barycenter*e.weight,t+=e.weight),n.vs=e.vs.concat(n.vs),n.barycenter=r/t,n.weight=t,n.i=Math.min(e.i,n.i),e.merged=!0}function $r(n,e){var r=ir(n,function(c){return w(c,"barycenter")}),t=r.lhs,i=O(r.rhs,function(c){return-c.i}),o=[],a=0,u=0,d=0;t.sort(Dr(!!e)),d=mn(o,i,d),s(t,function(c){d+=c.vs.length,o.push(c.vs),a+=c.barycenter*c.weight,u+=c.weight,d=mn(o,i,d)});var f={vs:_(o)};return u&&(f.barycenter=a/u,f.weight=u),f}function mn(n,e,r){for(var t;e.length&&(t=G(e)).i<=r;)e.pop(),n.push(t.vs),r++;return r}function Dr(n){return function(e,r){return e.barycenterr.barycenter?1:n?r.i-e.i:e.i-r.i}}function Wn(n,e,r,t){var i=n.children(e),o=n.node(e),a=o?o.borderLeft:void 0,u=o?o.borderRight:void 0,d={};a&&(i=M(i,function(p){return p!==a&&p!==u}));var f=Br(n,i);s(f,function(p){if(n.children(p.v).length){var b=Wn(n,p.v,r,t);d[p.v]=b,w(b,"barycenter")&&Wr(p,b)}});var c=Gr(f,r);qr(c,d);var h=$r(c,t);if(a&&(h.vs=_([a,h.vs,u]),n.predecessors(a).length)){var l=n.node(n.predecessors(a)[0]),v=n.node(n.predecessors(u)[0]);w(h,"barycenter")||(h.barycenter=0,h.weight=0),h.barycenter=(h.barycenter*h.weight+l.order+v.order)/(h.weight+2),h.weight+=2}return h}function qr(n,e){s(n,function(r){r.vs=_(r.vs.map(function(t){return e[t]?e[t].vs:t}))})}function Wr(n,e){g(n.barycenter)?(n.barycenter=e.barycenter,n.weight=e.weight):(n.barycenter=(n.barycenter*n.weight+e.barycenter*e.weight)/(n.weight+e.weight),n.weight+=e.weight)}function Xr(n){var e=Pn(n),r=bn(n,N(1,e+1),"inEdges"),t=bn(n,N(e-1,-1,-1),"outEdges"),i=Ar(n);gn(n,i);for(var o=Number.POSITIVE_INFINITY,a,u=0,d=0;d<4;++u,++d){zr(u%2?r:t,u%4>=2),i=D(n);var f=Sr(n,i);fa||u>e[d].lim));for(f=d,d=t;(d=n.parent(d))!==f;)o.push(d);return{path:i.concat(o.reverse()),lca:f}}function Kr(n){var e={},r=0;function t(i){var o=r;s(n.children(i),t),e[i]={low:o,lim:r++}}return s(n.children(),t),e}function jr(n,e){var r={};function t(i,o){var a=0,u=0,d=i.length,f=G(o);return s(o,function(c,h){var l=Qr(n,c),v=l?n.node(l).order:d;(l||c===f)&&(s(o.slice(u,h+1),function(p){s(n.predecessors(p),function(b){var I=n.node(b),on=I.order;(onf)&&Xn(r,l,c)})})}function i(o,a){var u=-1,d,f=0;return s(a,function(c,h){if(n.node(c).dummy==="border"){var l=n.predecessors(c);l.length&&(d=n.node(l[0]).order,t(a,f,h,u,d),f=h,u=d)}t(a,f,a.length,d,o.length)}),a}return V(e,i),r}function Qr(n,e){if(n.node(e).dummy)return Q(n.predecessors(e),function(r){return n.node(r).dummy})}function Xn(n,e,r){if(e>r){var t=e;e=r,r=t}var i=n[e];i||(n[e]=i={}),i[r]=!0}function Zr(n,e,r){if(e>r){var t=e;e=r,r=t}return w(n[e],r)}function nt(n,e,r,t){var i={},o={},a={};return s(e,function(u){s(u,function(d,f){i[d]=d,o[d]=d,a[d]=f})}),s(e,function(u){var d=-1;s(u,function(f){var c=t(f);if(c.length){c=O(c,function(b){return a[b]});for(var h=(c.length-1)/2,l=Math.floor(h),v=Math.ceil(h);l<=v;++l){var p=c[l];o[f]===f&&d2?e[2]:void 0;for(i&&B(e[0],e[1],i)&&(t=1);++r-1?i[o?e[a]:a]:void 0}}var Ce=Math.max;function Ie(n,e,r){var t=n==null?0:n.length;if(!t)return-1;var i=r==null?0:be(r);return i<0&&(i=Ce(t+i,0)),Hn(n,L(e),i)}var Q=_e(Ie);function Tn(n,e){var r=-1,t=Cn(n)?Array(n.length):[];return Kn(n,function(i,o,a){t[++r]=e(i,o,a)}),t}function m(n,e){var r=j(n)?P:Tn;return r(n,L(e))}function Re(n,e){return n==null?n:te(n,En(e),_n)}function Te(n,e){return n&&kn(n,En(e))}function Me(n,e){return n>e}function Mn(n,e){return ne||o&&a&&d&&!u&&!f||t&&a&&d||!r&&d||!i)return 1;if(!t&&!o&&!f&&n=u)return d;var f=r[t];return d*(f=="desc"?-1:1)}}return n.index-e.index}function Be(n,e,r){e.length?e=P(e,function(o){return j(o)?function(a){return Nn(a,o.length===1?o[0]:o)}:o}):e=[J];var t=-1;e=P(e,oe(L));var i=Tn(n,function(o,a,u){var d=P(e,function(f){return f(o)});return{criteria:d,index:++t,value:o}});return Se(i,function(o,a){return Ae(o,a,r)})}function Ge(n,e){return Pe(n,e,function(r,t){return Jn(n,t)})}var Y=ge(function(n,e){return n==null?{}:Ge(n,e)}),Ye=Math.ceil,Ve=Math.max;function $e(n,e,r,t){for(var i=-1,o=Ve(Ye((e-n)/(r||1)),0),a=Array(o);o--;)a[t?o:++i]=n,n+=r;return a}function De(n){return function(e,r,t){return t&&typeof t!="number"&&B(e,r,t)&&(r=t=void 0),e=S(e),r===void 0?(r=e,e=0):r=S(r),t=t===void 0?e1&&B(n,e[0],e[1])?e=[]:r>2&&B(e[0],e[1],e[2])&&(e=[e[0]]),Be(n,xn(e,1),[])}),qe=0;function en(n){var e=++qe;return Qn(n)+e}function We(n,e,r){for(var t=-1,i=n.length,o=e.length,a={};++t0;--u)if(a=e[u].dequeue(),a){t=t.concat(q(n,e,r,a,!0));break}}}return t}function q(n,e,r,t,i){var o=i?[]:void 0;return s(n.inEdges(t.v),function(a){var u=n.edge(a),d=n.node(a.v);i&&o.push({v:a.v,w:a.w}),d.out-=u,K(e,r,d)}),s(n.outEdges(t.v),function(a){var u=n.edge(a),d=a.w,f=n.node(d);f.in-=u,K(e,r,f)}),n.removeNode(t.v),o}function Je(n,e){var r=new x,t=0,i=0;s(n.nodes(),function(u){r.setNode(u,{v:u,in:0,out:0})}),s(n.edges(),function(u){var d=r.edge(u.v,u.w)||0,f=e(u),c=d+f;r.setEdge(u.v,u.w,c),i=Math.max(i,r.node(u.v).out+=f),t=Math.max(t,r.node(u.w).in+=f)});var o=N(i+t+3).map(function(){return new ze}),a=t+1;return s(r.nodes(),function(u){K(o,a,r.node(u))}),{graph:r,buckets:o,zeroIdx:a}}function K(n,e,r){r.out?r.in?n[r.out-r.in+e].enqueue(r):n[n.length-1].enqueue(r):n[0].enqueue(r)}function Qe(n){var e=n.graph().acyclicer==="greedy"?Ke(n,r(n)):Ze(n);s(e,function(t){var i=n.edge(t);n.removeEdge(t),i.forwardName=t.name,i.reversed=!0,n.setEdge(t.w,t.v,i,en("rev"))});function r(t){return function(i){return t.edge(i).weight}}}function Ze(n){var e=[],r={},t={};function i(o){w(t,o)||(t[o]=!0,r[o]=!0,s(n.outEdges(o),function(a){w(r,a.w)?e.push(a):i(a.w)}),delete r[o])}return s(n.nodes(),i),e}function nr(n){s(n.edges(),function(e){var r=n.edge(e);if(r.reversed){n.removeEdge(e);var t=r.forwardName;delete r.reversed,delete r.forwardName,n.setEdge(e.w,e.v,r,t)}})}function C(n,e,r,t){var i;do i=en(t);while(n.hasNode(i));return r.dummy=e,n.setNode(i,r),i}function er(n){var e=new x().setGraph(n.graph());return s(n.nodes(),function(r){e.setNode(r,n.node(r))}),s(n.edges(),function(r){var t=e.edge(r.v,r.w)||{weight:0,minlen:1},i=n.edge(r);e.setEdge(r.v,r.w,{weight:t.weight+i.weight,minlen:Math.max(t.minlen,i.minlen)})}),e}function On(n){var e=new x({multigraph:n.isMultigraph()}).setGraph(n.graph());return s(n.nodes(),function(r){n.children(r).length||e.setNode(r,n.node(r))}),s(n.edges(),function(r){e.setEdge(r,n.edge(r))}),e}function cn(n,e){var r=n.x,t=n.y,i=e.x-r,o=e.y-t,a=n.width/2,u=n.height/2;if(!i&&!o)throw new Error("Not possible to find intersection inside of the rectangle");var d,f;return Math.abs(o)*a>Math.abs(i)*u?(o<0&&(u=-u),d=u*i/o,f=u):(i<0&&(a=-a),d=a,f=a*o/i),{x:r+d,y:t+f}}function D(n){var e=m(N(Pn(n)+1),function(){return[]});return s(n.nodes(),function(r){var t=n.node(r),i=t.rank;g(i)||(e[i][t.order]=r)}),e}function rr(n){var e=R(m(n.nodes(),function(r){return n.node(r).rank}));s(n.nodes(),function(r){var t=n.node(r);w(t,"rank")&&(t.rank-=e)})}function tr(n){var e=R(m(n.nodes(),function(o){return n.node(o).rank})),r=[];s(n.nodes(),function(o){var a=n.node(o).rank-e;r[a]||(r[a]=[]),r[a].push(o)});var t=0,i=n.graph().nodeRankFactor;s(r,function(o,a){g(o)&&a%i!==0?--t:t&&s(o,function(u){n.node(u).rank+=t})})}function hn(n,e,r,t){var i={width:0,height:0};return arguments.length>=4&&(i.rank=r,i.order=t),C(n,"border",i,e)}function Pn(n){return E(m(n.nodes(),function(e){var r=n.node(e).rank;if(!g(r))return r}))}function ir(n,e){var r={lhs:[],rhs:[]};return s(n,function(t){e(t)?r.lhs.push(t):r.rhs.push(t)}),r}function ar(n,e){var r=fn();try{return e()}finally{console.log(n+" time: "+(fn()-r)+"ms")}}function or(n,e){return e()}function ur(n){function e(r){var t=n.children(r),i=n.node(r);if(t.length&&s(t,e),w(i,"minRank")){i.borderLeft=[],i.borderRight=[];for(var o=i.minRank,a=i.maxRank+1;oa.lim&&(u=a,d=!0);var f=M(e.edges(),function(c){return d===pn(n,n.node(c.v),u)&&d!==pn(n,n.node(c.w),u)});return nn(f,function(c){return T(e,c)})}function Dn(n,e,r,t){var i=r.v,o=r.w;n.removeEdge(i,o),n.setEdge(t.v,t.w,{}),an(n),tn(n,e),kr(n,e)}function kr(n,e){var r=Q(n.nodes(),function(i){return!e.node(i).parent}),t=xr(n,r);t=t.slice(1),s(t,function(i){var o=n.node(i).parent,a=e.edge(i,o),u=!1;a||(a=e.edge(o,i),u=!0),e.node(i).rank=e.node(o).rank+(u?a.minlen:-a.minlen)})}function yr(n,e,r){return n.hasEdge(e,r)}function pn(n,e,r){return r.low<=e.lim&&e.lim<=r.lim}function Nr(n){switch(n.graph().ranker){case"network-simplex":wn(n);break;case"tight-tree":_r(n);break;case"longest-path":Lr(n);break;default:wn(n)}}var Lr=rn;function _r(n){rn(n),Fn(n)}function wn(n){k(n)}function Cr(n){var e=C(n,"root",{},"_root"),r=Ir(n),t=E(y(r))-1,i=2*t+1;n.graph().nestingRoot=e,s(n.edges(),function(a){n.edge(a).minlen*=i});var o=Rr(n)+1;s(n.children(),function(a){qn(n,e,i,o,t,r,a)}),n.graph().nodeRankFactor=i}function qn(n,e,r,t,i,o,a){var u=n.children(a);if(!u.length){a!==e&&n.setEdge(e,a,{weight:0,minlen:r});return}var d=hn(n,"_bt"),f=hn(n,"_bb"),c=n.node(a);n.setParent(d,a),c.borderTop=d,n.setParent(f,a),c.borderBottom=f,s(u,function(h){qn(n,e,r,t,i,o,h);var l=n.node(h),v=l.borderTop?l.borderTop:h,p=l.borderBottom?l.borderBottom:h,b=l.borderTop?t:2*t,I=v!==p?1:i-o[a]+1;n.setEdge(d,v,{weight:b,minlen:I,nestingEdge:!0}),n.setEdge(p,f,{weight:b,minlen:I,nestingEdge:!0})}),n.parent(a)||n.setEdge(e,d,{weight:0,minlen:i+o[a]})}function Ir(n){var e={};function r(t,i){var o=n.children(t);o&&o.length&&s(o,function(a){r(a,i+1)}),e[t]=i}return s(n.children(),function(t){r(t,1)}),e}function Rr(n){return V(n.edges(),function(e,r){return e+n.edge(r).weight},0)}function Tr(n){var e=n.graph();n.removeNode(e.nestingRoot),delete e.nestingRoot,s(n.edges(),function(r){var t=n.edge(r);t.nestingEdge&&n.removeEdge(r)})}function Mr(n,e,r){var t={},i;s(r,function(o){for(var a=n.parent(o),u,d;a;){if(u=n.parent(a),u?(d=t[u],t[u]=a):(d=i,i=a),d&&d!==a){e.setEdge(d,a);return}a=u}})}function Or(n,e,r){var t=Pr(n),i=new x({compound:!0}).setGraph({root:t}).setDefaultNodeLabel(function(o){return n.node(o)});return s(n.nodes(),function(o){var a=n.node(o),u=n.parent(o);(a.rank===e||a.minRank<=e&&e<=a.maxRank)&&(i.setNode(o),i.setParent(o,u||t),s(n[r](o),function(d){var f=d.v===o?d.w:d.v,c=i.edge(f,o),h=g(c)?0:c.weight;i.setEdge(f,o,{weight:n.edge(d).weight+h})}),w(a,"minRank")&&i.setNode(o,{borderLeft:a.borderLeft[e],borderRight:a.borderRight[e]}))}),i}function Pr(n){for(var e;n.hasNode(e=en("_root")););return e}function Sr(n,e){for(var r=0,t=1;t0;)c%2&&(h+=u[c+1]),c=c-1>>1,u[c]+=f.weight;d+=f.weight*h})),d}function Ar(n){var e={},r=M(n.nodes(),function(u){return!n.children(u).length}),t=E(m(r,function(u){return n.node(u).rank})),i=m(N(t+1),function(){return[]});function o(u){if(!w(e,u)){e[u]=!0;var d=n.node(u);i[d.rank].push(u),s(n.successors(u),o)}}var a=O(r,function(u){return n.node(u).rank});return s(a,o),i}function Br(n,e){return m(e,function(r){var t=n.inEdges(r);if(t.length){var i=V(t,function(o,a){var u=n.edge(a),d=n.node(a.v);return{sum:o.sum+u.weight*d.order,weight:o.weight+u.weight}},{sum:0,weight:0});return{v:r,barycenter:i.sum/i.weight,weight:i.weight}}else return{v:r}})}function Gr(n,e){var r={};s(n,function(i,o){var a=r[i.v]={indegree:0,in:[],out:[],vs:[i.v],i:o};g(i.barycenter)||(a.barycenter=i.barycenter,a.weight=i.weight)}),s(e.edges(),function(i){var o=r[i.v],a=r[i.w];!g(o)&&!g(a)&&(a.indegree++,o.out.push(r[i.w]))});var t=M(r,function(i){return!i.indegree});return Yr(t)}function Yr(n){var e=[];function r(o){return function(a){a.merged||(g(a.barycenter)||g(o.barycenter)||a.barycenter>=o.barycenter)&&Vr(o,a)}}function t(o){return function(a){a.in.push(o),--a.indegree===0&&n.push(a)}}for(;n.length;){var i=n.pop();e.push(i),s(i.in.reverse(),r(i)),s(i.out,t(i))}return m(M(e,function(o){return!o.merged}),function(o){return Y(o,["vs","i","barycenter","weight"])})}function Vr(n,e){var r=0,t=0;n.weight&&(r+=n.barycenter*n.weight,t+=n.weight),e.weight&&(r+=e.barycenter*e.weight,t+=e.weight),n.vs=e.vs.concat(n.vs),n.barycenter=r/t,n.weight=t,n.i=Math.min(e.i,n.i),e.merged=!0}function $r(n,e){var r=ir(n,function(c){return w(c,"barycenter")}),t=r.lhs,i=O(r.rhs,function(c){return-c.i}),o=[],a=0,u=0,d=0;t.sort(Dr(!!e)),d=mn(o,i,d),s(t,function(c){d+=c.vs.length,o.push(c.vs),a+=c.barycenter*c.weight,u+=c.weight,d=mn(o,i,d)});var f={vs:_(o)};return u&&(f.barycenter=a/u,f.weight=u),f}function mn(n,e,r){for(var t;e.length&&(t=G(e)).i<=r;)e.pop(),n.push(t.vs),r++;return r}function Dr(n){return function(e,r){return e.barycenterr.barycenter?1:n?r.i-e.i:e.i-r.i}}function Wn(n,e,r,t){var i=n.children(e),o=n.node(e),a=o?o.borderLeft:void 0,u=o?o.borderRight:void 0,d={};a&&(i=M(i,function(p){return p!==a&&p!==u}));var f=Br(n,i);s(f,function(p){if(n.children(p.v).length){var b=Wn(n,p.v,r,t);d[p.v]=b,w(b,"barycenter")&&Wr(p,b)}});var c=Gr(f,r);qr(c,d);var h=$r(c,t);if(a&&(h.vs=_([a,h.vs,u]),n.predecessors(a).length)){var l=n.node(n.predecessors(a)[0]),v=n.node(n.predecessors(u)[0]);w(h,"barycenter")||(h.barycenter=0,h.weight=0),h.barycenter=(h.barycenter*h.weight+l.order+v.order)/(h.weight+2),h.weight+=2}return h}function qr(n,e){s(n,function(r){r.vs=_(r.vs.map(function(t){return e[t]?e[t].vs:t}))})}function Wr(n,e){g(n.barycenter)?(n.barycenter=e.barycenter,n.weight=e.weight):(n.barycenter=(n.barycenter*n.weight+e.barycenter*e.weight)/(n.weight+e.weight),n.weight+=e.weight)}function Xr(n){var e=Pn(n),r=bn(n,N(1,e+1),"inEdges"),t=bn(n,N(e-1,-1,-1),"outEdges"),i=Ar(n);gn(n,i);for(var o=Number.POSITIVE_INFINITY,a,u=0,d=0;d<4;++u,++d){zr(u%2?r:t,u%4>=2),i=D(n);var f=Sr(n,i);fa||u>e[d].lim));for(f=d,d=t;(d=n.parent(d))!==f;)o.push(d);return{path:i.concat(o.reverse()),lca:f}}function Kr(n){var e={},r=0;function t(i){var o=r;s(n.children(i),t),e[i]={low:o,lim:r++}}return s(n.children(),t),e}function jr(n,e){var r={};function t(i,o){var a=0,u=0,d=i.length,f=G(o);return s(o,function(c,h){var l=Qr(n,c),v=l?n.node(l).order:d;(l||c===f)&&(s(o.slice(u,h+1),function(p){s(n.predecessors(p),function(b){var I=n.node(b),on=I.order;(onf)&&Xn(r,l,c)})})}function i(o,a){var u=-1,d,f=0;return s(a,function(c,h){if(n.node(c).dummy==="border"){var l=n.predecessors(c);l.length&&(d=n.node(l[0]).order,t(a,f,h,u,d),f=h,u=d)}t(a,f,a.length,d,o.length)}),a}return V(e,i),r}function Qr(n,e){if(n.node(e).dummy)return Q(n.predecessors(e),function(r){return n.node(r).dummy})}function Xn(n,e,r){if(e>r){var t=e;e=r,r=t}var i=n[e];i||(n[e]=i={}),i[r]=!0}function Zr(n,e,r){if(e>r){var t=e;e=r,r=t}return w(n[e],r)}function nt(n,e,r,t){var i={},o={},a={};return s(e,function(u){s(u,function(d,f){i[d]=d,o[d]=d,a[d]=f})}),s(e,function(u){var d=-1;s(u,function(f){var c=t(f);if(c.length){c=O(c,function(b){return a[b]});for(var h=(c.length-1)/2,l=Math.floor(h),v=Math.ceil(h);l<=v;++l){var p=c[l];o[f]===f&&dt?1:n>=t?0:NaN}function hn(n,t){return n==null||t==null?NaN:tn?1:t>=n?0:NaN}function _(n){let t,e,r;n.length!==2?(t=$,e=(u,c)=>$(n(u),c),r=(u,c)=>n(u)-c):(t=n===$||n===hn?n:mn,e=n,r=n);function i(u,c,o=0,s=u.length){if(o>>1;e(u[h],c)<0?o=h+1:s=h}while(o>>1;e(u[h],c)<=0?o=h+1:s=h}while(oo&&r(u[h-1],c)>-r(u[h],c)?h-1:h}return{left:i,center:a,right:f}}function mn(){return 0}function ln(n){return n===null?NaN:+n}const sn=_($),dn=sn.right;_(ln).center;const gn=Math.sqrt(50),yn=Math.sqrt(10),Mn=Math.sqrt(2);function R(n,t,e){const r=(t-n)/Math.max(0,e),i=Math.floor(Math.log10(r)),f=r/Math.pow(10,i),a=f>=gn?10:f>=yn?5:f>=Mn?2:1;let u,c,o;return i<0?(o=Math.pow(10,-i)/a,u=Math.round(n*o),c=Math.round(t*o),u/ot&&--c,o=-o):(o=Math.pow(10,i)*a,u=Math.round(n/o),c=Math.round(t/o),u*ot&&--c),c0))return[];if(n===t)return[n];const r=t=i))return[];const u=f-i+1,c=new Array(u);if(r)if(a<0)for(let o=0;o=1e21?n.toLocaleString("en").replace(/,/g,""):n.toString(10)}function E(n,t){if((e=(n=t?n.toExponential(t-1):n.toExponential()).indexOf("e"))<0)return null;var e,r=n.slice(0,e);return[r.length>1?r[0]+r.slice(2):r,+n.slice(e+1)]}function v(n){return n=E(Math.abs(n)),n?n[1]:NaN}function jn(n,t){return function(e,r){for(var i=e.length,f=[],a=0,u=n[0],c=0;i>0&&u>0&&(c+u+1>r&&(u=Math.max(1,r-c)),f.push(e.substring(i-=u,i+u)),!((c+=u+1)>r));)u=n[a=(a+1)%n.length];return f.reverse().join(t)}}function Pn(n){return function(t){return t.replace(/[0-9]/g,function(e){return n[+e]})}}var zn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function D(n){if(!(t=zn.exec(n)))throw new Error("invalid format: "+n);var t;return new G({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}D.prototype=G.prototype;function G(n){this.fill=n.fill===void 0?" ":n.fill+"",this.align=n.align===void 0?">":n.align+"",this.sign=n.sign===void 0?"-":n.sign+"",this.symbol=n.symbol===void 0?"":n.symbol+"",this.zero=!!n.zero,this.width=n.width===void 0?void 0:+n.width,this.comma=!!n.comma,this.precision=n.precision===void 0?void 0:+n.precision,this.trim=!!n.trim,this.type=n.type===void 0?"":n.type+""}G.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function Fn(n){n:for(var t=n.length,e=1,r=-1,i;e0&&(r=0);break}return r>0?n.slice(0,r)+n.slice(i+1):n}var nn;function $n(n,t){var e=E(n,t);if(!e)return n+"";var r=e[0],i=e[1],f=i-(nn=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,a=r.length;return f===a?r:f>a?r+new Array(f-a+1).join("0"):f>0?r.slice(0,f)+"."+r.slice(f):"0."+new Array(1-f).join("0")+E(n,Math.max(0,t+f-1))[0]}function U(n,t){var e=E(n,t);if(!e)return n+"";var r=e[0],i=e[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}const Y={"%":(n,t)=>(n*100).toFixed(t),b:n=>Math.round(n).toString(2),c:n=>n+"",d:bn,e:(n,t)=>n.toExponential(t),f:(n,t)=>n.toFixed(t),g:(n,t)=>n.toPrecision(t),o:n=>Math.round(n).toString(8),p:(n,t)=>U(n*100,t),r:U,s:$n,X:n=>Math.round(n).toString(16).toUpperCase(),x:n=>Math.round(n).toString(16)};function Z(n){return n}var K=Array.prototype.map,Q=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function Rn(n){var t=n.grouping===void 0||n.thousands===void 0?Z:jn(K.call(n.grouping,Number),n.thousands+""),e=n.currency===void 0?"":n.currency[0]+"",r=n.currency===void 0?"":n.currency[1]+"",i=n.decimal===void 0?".":n.decimal+"",f=n.numerals===void 0?Z:Pn(K.call(n.numerals,String)),a=n.percent===void 0?"%":n.percent+"",u=n.minus===void 0?"−":n.minus+"",c=n.nan===void 0?"NaN":n.nan+"";function o(h){h=D(h);var l=h.fill,p=h.align,y=h.sign,S=h.symbol,k=h.zero,b=h.width,I=h.comma,w=h.precision,B=h.trim,d=h.type;d==="n"?(I=!0,d="g"):Y[d]||(w===void 0&&(w=12),B=!0,d="g"),(k||l==="0"&&p==="=")&&(k=!0,l="0",p="=");var en=S==="$"?e:S==="#"&&/[boxX]/.test(d)?"0"+d.toLowerCase():"",on=S==="$"?r:/[%p]/.test(d)?a:"",O=Y[d],an=/[defgprs%]/.test(d);w=w===void 0?6:/[gprs]/.test(d)?Math.max(1,Math.min(21,w)):Math.max(0,Math.min(20,w));function V(m){var N=en,g=on,x,X,j;if(d==="c")g=O(m)+g,m="";else{m=+m;var P=m<0||1/m<0;if(m=isNaN(m)?c:O(Math.abs(m),w),B&&(m=Fn(m)),P&&+m==0&&y!=="+"&&(P=!1),N=(P?y==="("?y:u:y==="-"||y==="("?"":y)+N,g=(d==="s"?Q[8+nn/3]:"")+g+(P&&y==="("?")":""),an){for(x=-1,X=m.length;++xj||j>57){g=(j===46?i+m.slice(x+1):m.slice(x))+g,m=m.slice(0,x);break}}}I&&!k&&(m=t(m,1/0));var z=N.length+m.length+g.length,M=z>1)+N+m+g+M.slice(z);break;default:m=M+N+m+g;break}return f(m)}return V.toString=function(){return h+""},V}function s(h,l){var p=o((h=D(h),h.type="f",h)),y=Math.max(-8,Math.min(8,Math.floor(v(l)/3)))*3,S=Math.pow(10,-y),k=Q[8+y/3];return function(b){return p(S*b)+k}}return{format:o,formatPrefix:s}}var F,tn,rn;En({thousands:",",grouping:[3],currency:["$",""]});function En(n){return F=Rn(n),tn=F.format,rn=F.formatPrefix,F}function Dn(n){return Math.max(0,-v(Math.abs(n)))}function In(n,t){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(v(t)/3)))*3-v(Math.abs(n)))}function Tn(n,t){return n=Math.abs(n),t=Math.abs(t)-n,Math.max(0,v(t)-v(n))+1}function Ln(n){return function(){return n}}function qn(n){return+n}var W=[0,1];function A(n){return n}function q(n,t){return(t-=n=+n)?function(e){return(e-n)/t}:Ln(isNaN(t)?NaN:.5)}function Cn(n,t){var e;return n>t&&(e=n,n=t,t=e),function(r){return Math.max(n,Math.min(t,r))}}function Gn(n,t,e){var r=n[0],i=n[1],f=t[0],a=t[1];return i2?Bn:Gn,c=o=null,h}function h(l){return l==null||isNaN(l=+l)?f:(c||(c=u(n.map(r),t,e)))(r(a(l)))}return h.invert=function(l){return a(i((o||(o=u(t,n.map(r),T)))(l)))},h.domain=function(l){return arguments.length?(n=Array.from(l,qn),s()):n.slice()},h.range=function(l){return arguments.length?(t=Array.from(l),s()):t.slice()},h.rangeRound=function(l){return t=Array.from(l),e=Sn,s()},h.clamp=function(l){return arguments.length?(a=l?!0:A,s()):a!==A},h.interpolate=function(l){return arguments.length?(e=l,s()):e},h.unknown=function(l){return arguments.length?(f=l,h):f},function(l,p){return r=l,i=p,s()}}function Xn(){return Vn()(A,A)}function Hn(n,t,e,r){var i=wn(n,t,e),f;switch(r=D(r??",f"),r.type){case"s":{var a=Math.max(Math.abs(n),Math.abs(t));return r.precision==null&&!isNaN(f=In(i,a))&&(r.precision=f),rn(r,a)}case"":case"e":case"g":case"p":case"r":{r.precision==null&&!isNaN(f=Tn(i,Math.max(Math.abs(n),Math.abs(t))))&&(r.precision=f-(r.type==="e"));break}case"f":case"%":{r.precision==null&&!isNaN(f=Dn(i))&&(r.precision=f-(r.type==="%")*2);break}}return tn(r)}function Jn(n){var t=n.domain;return n.ticks=function(e){var r=t();return pn(r[0],r[r.length-1],e??10)},n.tickFormat=function(e,r){var i=t();return Hn(i[0],i[i.length-1],e??10,r)},n.nice=function(e){e==null&&(e=10);var r=t(),i=0,f=r.length-1,a=r[i],u=r[f],c,o,s=10;for(u0;){if(o=L(a,u,e),o===c)return r[i]=a,r[f]=u,t(r);if(o>0)a=Math.floor(a/o)*o,u=Math.ceil(u/o)*o;else if(o<0)a=Math.ceil(a*o)/o,u=Math.floor(u*o)/o;else break;c=o}return n},n}function Un(){var n=Xn();return n.copy=function(){return On(n,Un())},cn.apply(n,arguments),Jn(n)}export{On as a,_ as b,Xn as c,Un as l,wn as t};
                        +import{aF as un,aG as T,aH as H,aI as J,aJ as fn}from"./mermaid.core-Q3WVcjPF.js";import{i as cn}from"./init-Hi12RPRh.js";function $(n,t){return n==null||t==null?NaN:nt?1:n>=t?0:NaN}function hn(n,t){return n==null||t==null?NaN:tn?1:t>=n?0:NaN}function _(n){let t,e,r;n.length!==2?(t=$,e=(u,c)=>$(n(u),c),r=(u,c)=>n(u)-c):(t=n===$||n===hn?n:mn,e=n,r=n);function i(u,c,o=0,s=u.length){if(o>>1;e(u[h],c)<0?o=h+1:s=h}while(o>>1;e(u[h],c)<=0?o=h+1:s=h}while(oo&&r(u[h-1],c)>-r(u[h],c)?h-1:h}return{left:i,center:a,right:f}}function mn(){return 0}function ln(n){return n===null?NaN:+n}const sn=_($),dn=sn.right;_(ln).center;const gn=Math.sqrt(50),yn=Math.sqrt(10),Mn=Math.sqrt(2);function R(n,t,e){const r=(t-n)/Math.max(0,e),i=Math.floor(Math.log10(r)),f=r/Math.pow(10,i),a=f>=gn?10:f>=yn?5:f>=Mn?2:1;let u,c,o;return i<0?(o=Math.pow(10,-i)/a,u=Math.round(n*o),c=Math.round(t*o),u/ot&&--c,o=-o):(o=Math.pow(10,i)*a,u=Math.round(n/o),c=Math.round(t/o),u*ot&&--c),c0))return[];if(n===t)return[n];const r=t=i))return[];const u=f-i+1,c=new Array(u);if(r)if(a<0)for(let o=0;o=1e21?n.toLocaleString("en").replace(/,/g,""):n.toString(10)}function E(n,t){if((e=(n=t?n.toExponential(t-1):n.toExponential()).indexOf("e"))<0)return null;var e,r=n.slice(0,e);return[r.length>1?r[0]+r.slice(2):r,+n.slice(e+1)]}function v(n){return n=E(Math.abs(n)),n?n[1]:NaN}function jn(n,t){return function(e,r){for(var i=e.length,f=[],a=0,u=n[0],c=0;i>0&&u>0&&(c+u+1>r&&(u=Math.max(1,r-c)),f.push(e.substring(i-=u,i+u)),!((c+=u+1)>r));)u=n[a=(a+1)%n.length];return f.reverse().join(t)}}function Pn(n){return function(t){return t.replace(/[0-9]/g,function(e){return n[+e]})}}var zn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function D(n){if(!(t=zn.exec(n)))throw new Error("invalid format: "+n);var t;return new G({fill:t[1],align:t[2],sign:t[3],symbol:t[4],zero:t[5],width:t[6],comma:t[7],precision:t[8]&&t[8].slice(1),trim:t[9],type:t[10]})}D.prototype=G.prototype;function G(n){this.fill=n.fill===void 0?" ":n.fill+"",this.align=n.align===void 0?">":n.align+"",this.sign=n.sign===void 0?"-":n.sign+"",this.symbol=n.symbol===void 0?"":n.symbol+"",this.zero=!!n.zero,this.width=n.width===void 0?void 0:+n.width,this.comma=!!n.comma,this.precision=n.precision===void 0?void 0:+n.precision,this.trim=!!n.trim,this.type=n.type===void 0?"":n.type+""}G.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(this.width===void 0?"":Math.max(1,this.width|0))+(this.comma?",":"")+(this.precision===void 0?"":"."+Math.max(0,this.precision|0))+(this.trim?"~":"")+this.type};function Fn(n){n:for(var t=n.length,e=1,r=-1,i;e0&&(r=0);break}return r>0?n.slice(0,r)+n.slice(i+1):n}var nn;function $n(n,t){var e=E(n,t);if(!e)return n+"";var r=e[0],i=e[1],f=i-(nn=Math.max(-8,Math.min(8,Math.floor(i/3)))*3)+1,a=r.length;return f===a?r:f>a?r+new Array(f-a+1).join("0"):f>0?r.slice(0,f)+"."+r.slice(f):"0."+new Array(1-f).join("0")+E(n,Math.max(0,t+f-1))[0]}function U(n,t){var e=E(n,t);if(!e)return n+"";var r=e[0],i=e[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")}const Y={"%":(n,t)=>(n*100).toFixed(t),b:n=>Math.round(n).toString(2),c:n=>n+"",d:bn,e:(n,t)=>n.toExponential(t),f:(n,t)=>n.toFixed(t),g:(n,t)=>n.toPrecision(t),o:n=>Math.round(n).toString(8),p:(n,t)=>U(n*100,t),r:U,s:$n,X:n=>Math.round(n).toString(16).toUpperCase(),x:n=>Math.round(n).toString(16)};function Z(n){return n}var K=Array.prototype.map,Q=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];function Rn(n){var t=n.grouping===void 0||n.thousands===void 0?Z:jn(K.call(n.grouping,Number),n.thousands+""),e=n.currency===void 0?"":n.currency[0]+"",r=n.currency===void 0?"":n.currency[1]+"",i=n.decimal===void 0?".":n.decimal+"",f=n.numerals===void 0?Z:Pn(K.call(n.numerals,String)),a=n.percent===void 0?"%":n.percent+"",u=n.minus===void 0?"−":n.minus+"",c=n.nan===void 0?"NaN":n.nan+"";function o(h){h=D(h);var l=h.fill,p=h.align,y=h.sign,S=h.symbol,k=h.zero,b=h.width,I=h.comma,w=h.precision,B=h.trim,d=h.type;d==="n"?(I=!0,d="g"):Y[d]||(w===void 0&&(w=12),B=!0,d="g"),(k||l==="0"&&p==="=")&&(k=!0,l="0",p="=");var en=S==="$"?e:S==="#"&&/[boxX]/.test(d)?"0"+d.toLowerCase():"",on=S==="$"?r:/[%p]/.test(d)?a:"",O=Y[d],an=/[defgprs%]/.test(d);w=w===void 0?6:/[gprs]/.test(d)?Math.max(1,Math.min(21,w)):Math.max(0,Math.min(20,w));function V(m){var N=en,g=on,x,X,j;if(d==="c")g=O(m)+g,m="";else{m=+m;var P=m<0||1/m<0;if(m=isNaN(m)?c:O(Math.abs(m),w),B&&(m=Fn(m)),P&&+m==0&&y!=="+"&&(P=!1),N=(P?y==="("?y:u:y==="-"||y==="("?"":y)+N,g=(d==="s"?Q[8+nn/3]:"")+g+(P&&y==="("?")":""),an){for(x=-1,X=m.length;++xj||j>57){g=(j===46?i+m.slice(x+1):m.slice(x))+g,m=m.slice(0,x);break}}}I&&!k&&(m=t(m,1/0));var z=N.length+m.length+g.length,M=z>1)+N+m+g+M.slice(z);break;default:m=M+N+m+g;break}return f(m)}return V.toString=function(){return h+""},V}function s(h,l){var p=o((h=D(h),h.type="f",h)),y=Math.max(-8,Math.min(8,Math.floor(v(l)/3)))*3,S=Math.pow(10,-y),k=Q[8+y/3];return function(b){return p(S*b)+k}}return{format:o,formatPrefix:s}}var F,tn,rn;En({thousands:",",grouping:[3],currency:["$",""]});function En(n){return F=Rn(n),tn=F.format,rn=F.formatPrefix,F}function Dn(n){return Math.max(0,-v(Math.abs(n)))}function In(n,t){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(v(t)/3)))*3-v(Math.abs(n)))}function Tn(n,t){return n=Math.abs(n),t=Math.abs(t)-n,Math.max(0,v(t)-v(n))+1}function Ln(n){return function(){return n}}function qn(n){return+n}var W=[0,1];function A(n){return n}function q(n,t){return(t-=n=+n)?function(e){return(e-n)/t}:Ln(isNaN(t)?NaN:.5)}function Cn(n,t){var e;return n>t&&(e=n,n=t,t=e),function(r){return Math.max(n,Math.min(t,r))}}function Gn(n,t,e){var r=n[0],i=n[1],f=t[0],a=t[1];return i2?Bn:Gn,c=o=null,h}function h(l){return l==null||isNaN(l=+l)?f:(c||(c=u(n.map(r),t,e)))(r(a(l)))}return h.invert=function(l){return a(i((o||(o=u(t,n.map(r),T)))(l)))},h.domain=function(l){return arguments.length?(n=Array.from(l,qn),s()):n.slice()},h.range=function(l){return arguments.length?(t=Array.from(l),s()):t.slice()},h.rangeRound=function(l){return t=Array.from(l),e=Sn,s()},h.clamp=function(l){return arguments.length?(a=l?!0:A,s()):a!==A},h.interpolate=function(l){return arguments.length?(e=l,s()):e},h.unknown=function(l){return arguments.length?(f=l,h):f},function(l,p){return r=l,i=p,s()}}function Xn(){return Vn()(A,A)}function Hn(n,t,e,r){var i=wn(n,t,e),f;switch(r=D(r??",f"),r.type){case"s":{var a=Math.max(Math.abs(n),Math.abs(t));return r.precision==null&&!isNaN(f=In(i,a))&&(r.precision=f),rn(r,a)}case"":case"e":case"g":case"p":case"r":{r.precision==null&&!isNaN(f=Tn(i,Math.max(Math.abs(n),Math.abs(t))))&&(r.precision=f-(r.type==="e"));break}case"f":case"%":{r.precision==null&&!isNaN(f=Dn(i))&&(r.precision=f-(r.type==="%")*2);break}}return tn(r)}function Jn(n){var t=n.domain;return n.ticks=function(e){var r=t();return pn(r[0],r[r.length-1],e??10)},n.tickFormat=function(e,r){var i=t();return Hn(i[0],i[i.length-1],e??10,r)},n.nice=function(e){e==null&&(e=10);var r=t(),i=0,f=r.length-1,a=r[i],u=r[f],c,o,s=10;for(u0;){if(o=L(a,u,e),o===c)return r[i]=a,r[f]=u,t(r);if(o>0)a=Math.floor(a/o)*o,u=Math.ceil(u/o)*o;else if(o<0)a=Math.ceil(a*o)/o,u=Math.floor(u*o)/o;else break;c=o}return n},n}function Un(){var n=Xn();return n.copy=function(){return On(n,Un())},cn.apply(n,arguments),Jn(n)}export{On as a,_ as b,Xn as c,Un as l,wn as t};
                        diff --git a/assets/log.html-6VYWlh7_.js b/assets/log.html-7A6BNzqC.js
                        similarity index 98%
                        rename from assets/log.html-6VYWlh7_.js
                        rename to assets/log.html-7A6BNzqC.js
                        index 0ffbc5bfa2..37cc954bc7 100644
                        --- a/assets/log.html-6VYWlh7_.js
                        +++ b/assets/log.html-7A6BNzqC.js
                        @@ -1,4 +1,4 @@
                        -import{_ as o,o as e,c as n,e as s}from"./app-PDrbPfzp.js";const t={},a=s(`

                        日志配置

                        日志配置,控制 Xray 输出日志的方式.

                        Xray 有两种日志, 访问日志和错误日志, 你可以分别配置两种日志的输出方式.

                        LogObject

                        LogObject 对应配置文件的 log 项。

                        {
                        +import{_ as o,o as e,c as n,e as s}from"./app-UOvWaKji.js";const t={},a=s(`

                        日志配置

                        日志配置,控制 Xray 输出日志的方式.

                        Xray 有两种日志, 访问日志和错误日志, 你可以分别配置两种日志的输出方式.

                        LogObject

                        LogObject 对应配置文件的 log 项。

                        {
                           "log": {
                             "access": "文件地址",
                             "error": "文件地址",
                        diff --git a/assets/log.html-CNcmi473.js b/assets/log.html-NTUL9-8j.js
                        similarity index 98%
                        rename from assets/log.html-CNcmi473.js
                        rename to assets/log.html-NTUL9-8j.js
                        index b684ab461e..08807ab015 100644
                        --- a/assets/log.html-CNcmi473.js
                        +++ b/assets/log.html-NTUL9-8j.js
                        @@ -1,4 +1,4 @@
                        -import{_ as o,o as e,c as t,e as n}from"./app-PDrbPfzp.js";const s={},a=n(`

                        Log Configuration

                        Log configuration controls how Xray outputs logs.

                        Xray has two types of logs: access logs and error logs. You can configure the output method for each type of log separately.

                        LogObject

                        LogObject corresponds to the log item in the configuration file.

                        {
                        +import{_ as o,o as e,c as t,e as n}from"./app-UOvWaKji.js";const s={},a=n(`

                        Log Configuration

                        Log configuration controls how Xray outputs logs.

                        Xray has two types of logs: access logs and error logs. You can configure the output method for each type of log separately.

                        LogObject

                        LogObject corresponds to the log item in the configuration file.

                        {
                           "log": {
                             "access": "file_path",
                             "error": "file_path",
                        diff --git a/assets/loopback.html--hPilBz9.js b/assets/loopback.html-Bzq00ZYC.js
                        similarity index 98%
                        rename from assets/loopback.html--hPilBz9.js
                        rename to assets/loopback.html-Bzq00ZYC.js
                        index 18bd62b193..f8611d7e83 100644
                        --- a/assets/loopback.html--hPilBz9.js
                        +++ b/assets/loopback.html-Bzq00ZYC.js
                        @@ -1,4 +1,4 @@
                        -import{_ as n,o,c as t,e}from"./app-PDrbPfzp.js";const i={},s=e(`

                        Loopback

                        Loopback is an outbound protocol. It can send traffics through corresponding outbound to routing inbound, thus rerouting traffics to other routing rules without leaving Xray-core.

                        OutboundConfigurationObject

                        {
                        +import{_ as n,o,c as t,e}from"./app-UOvWaKji.js";const i={},s=e(`

                        Loopback

                        Loopback is an outbound protocol. It can send traffics through corresponding outbound to routing inbound, thus rerouting traffics to other routing rules without leaving Xray-core.

                        OutboundConfigurationObject

                        {
                           "inboundTag": "TagUseAsInbound"
                         }
                         

                        inboundTag: string

                        Use as an inbound tag for routing.

                        This tag can be used as inboundTag in routing rules, all traffics going through this outbound can be rerouted with routing rules with corresponding inbound tag.

                        How to use?

                        If you need to do some more detailed routing for traffics that have been routed by routing rules, like splitting routed traffics to TCP traffics and UDP traffics and send them to different outbounds, this can be done with loopback outbound.

                        {
                        diff --git a/assets/loopback.html-4ZKd-9LO.js b/assets/loopback.html-hvdhvF1l.js
                        similarity index 99%
                        rename from assets/loopback.html-4ZKd-9LO.js
                        rename to assets/loopback.html-hvdhvF1l.js
                        index d8d38f9bfe..988b39a7b8 100644
                        --- a/assets/loopback.html-4ZKd-9LO.js
                        +++ b/assets/loopback.html-hvdhvF1l.js
                        @@ -1,4 +1,4 @@
                        -import{_ as n,o as s,c as a,e as t}from"./app-PDrbPfzp.js";const o={},p=t(`

                        Loopback

                        Loopback 是个出站数据协议,其作用为将经该出站传出的数据重新送入路由入站,以达到数据无需离开 Xray-core 即可再次被路由处理的效果。

                        OutboundConfigurationObject

                        {
                        +import{_ as n,o as s,c as a,e as t}from"./app-UOvWaKji.js";const o={},p=t(`

                        Loopback

                        Loopback 是个出站数据协议,其作用为将经该出站传出的数据重新送入路由入站,以达到数据无需离开 Xray-core 即可再次被路由处理的效果。

                        OutboundConfigurationObject

                        {
                           "inboundTag": "TagUseAsInbound"
                         }
                         

                        inboundTag: string

                        用于重新路由的入站协议标识。

                        该标识可以在路由中用于 inboundTag ,表示该出站中的数据可以被对应的路由规则再次处理。

                        如何使用?

                        如果需要将已经通过路由规则分流过的流量再由其它路由规则做更细致的分流,比如由同一组路由规则分流后的 TCP 流量和 UDP 要走不同的出站,则可以使用 loopback 出站完成。

                        {
                        diff --git a/assets/mermaid.core-95b3ca__.js b/assets/mermaid.core-Q3WVcjPF.js
                        similarity index 98%
                        rename from assets/mermaid.core-95b3ca__.js
                        rename to assets/mermaid.core-Q3WVcjPF.js
                        index a87b09317e..7ecfa91867 100644
                        --- a/assets/mermaid.core-95b3ca__.js
                        +++ b/assets/mermaid.core-Q3WVcjPF.js
                        @@ -1,4 +1,4 @@
                        -import{q as X}from"./app-PDrbPfzp.js";function dh(t){for(var e=[],i=1;i
                                   `:`
                        ${r}
                        `).join("").replace(_n,(r,n)=>i.renderToString(n,{throwOnError:!0,displayMode:!0,output:ys()?"mathml":"htmlAndMathml"}).replace(/\n/g," ").replace(//g,""))},qn={getRows:Rm,sanitizeText:pi,sanitizeTextOrArray:zm,hasBreaks:Wm,splitBreaks:Hm,lineBreakRegex:bi,removeScript:Xa,getUrl:Um,evaluate:Za,getMax:Ym,getMin:Vm},ct=(t,e)=>e?g(t,{s:-40,l:10}):g(t,{s:-40,l:-10}),kr="#ffffff",Sr="#f2f2f2";let Zm=class{constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){var e,i,r,n,o,s,a,l,h,u,f;if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||g(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||g(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||ct(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||ct(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||ct(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||ct(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||C(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||C(this.tertiaryColor),this.lineColor=this.lineColor||C(this.background),this.arrowheadColor=this.arrowheadColor||C(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?O(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||"grey",this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||O(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||C(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||L(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||g(this.primaryColor,{h:30}),this.cScale4=this.cScale4||g(this.primaryColor,{h:60}),this.cScale5=this.cScale5||g(this.primaryColor,{h:90}),this.cScale6=this.cScale6||g(this.primaryColor,{h:120}),this.cScale7=this.cScale7||g(this.primaryColor,{h:150}),this.cScale8=this.cScale8||g(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||g(this.primaryColor,{h:270}),this.cScale10=this.cScale10||g(this.primaryColor,{h:300}),this.cScale11=this.cScale11||g(this.primaryColor,{h:330}),this.darkMode)for(let d=0;d{this[r]=e[r]}),this.updateColors(),i.forEach(r=>{this[r]=e[r]})}};const Jm=t=>{const e=new Zm;return e.calculate(t),e};let Qm=class{constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=L(this.primaryColor,16),this.tertiaryColor=g(this.primaryColor,{h:-160}),this.primaryBorderColor=C(this.background),this.secondaryBorderColor=ct(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=ct(this.tertiaryColor,this.darkMode),this.primaryTextColor=C(this.primaryColor),this.secondaryTextColor=C(this.secondaryColor),this.tertiaryTextColor=C(this.tertiaryColor),this.lineColor=C(this.background),this.textColor=C(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=L(C("#323D47"),10),this.lineColor="calculated",this.border1="#81B1DB",this.border2=ei(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=O("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=O(this.sectionBkgColor,10),this.taskBorderColor=ei(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=ei(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){var e,i,r,n,o,s,a,l,h,u,f;this.secondBkg=L(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=L(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.mainContrastColor,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=L(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=g(this.primaryColor,{h:64}),this.fillType3=g(this.secondaryColor,{h:64}),this.fillType4=g(this.primaryColor,{h:-64}),this.fillType5=g(this.secondaryColor,{h:-64}),this.fillType6=g(this.primaryColor,{h:128}),this.fillType7=g(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||g(this.primaryColor,{h:30}),this.cScale4=this.cScale4||g(this.primaryColor,{h:60}),this.cScale5=this.cScale5||g(this.primaryColor,{h:90}),this.cScale6=this.cScale6||g(this.primaryColor,{h:120}),this.cScale7=this.cScale7||g(this.primaryColor,{h:150}),this.cScale8=this.cScale8||g(this.primaryColor,{h:210}),this.cScale9=this.cScale9||g(this.primaryColor,{h:270}),this.cScale10=this.cScale10||g(this.primaryColor,{h:300}),this.cScale11=this.cScale11||g(this.primaryColor,{h:330});for(let c=0;c{this[r]=e[r]}),this.updateColors(),i.forEach(r=>{this[r]=e[r]})}};const t0=t=>{const e=new Qm;return e.calculate(t),e};let e0=class{constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=g(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=g(this.primaryColor,{h:-160}),this.primaryBorderColor=ct(this.primaryColor,this.darkMode),this.secondaryBorderColor=ct(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=ct(this.tertiaryColor,this.darkMode),this.primaryTextColor=C(this.primaryColor),this.secondaryTextColor=C(this.secondaryColor),this.tertiaryTextColor=C(this.tertiaryColor),this.lineColor=C(this.background),this.textColor=C(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#e8e8e8",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.sectionBkgColor=ei(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){var e,i,r,n,o,s,a,l,h,u,f;this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||g(this.primaryColor,{h:30}),this.cScale4=this.cScale4||g(this.primaryColor,{h:60}),this.cScale5=this.cScale5||g(this.primaryColor,{h:90}),this.cScale6=this.cScale6||g(this.primaryColor,{h:120}),this.cScale7=this.cScale7||g(this.primaryColor,{h:150}),this.cScale8=this.cScale8||g(this.primaryColor,{h:210}),this.cScale9=this.cScale9||g(this.primaryColor,{h:270}),this.cScale10=this.cScale10||g(this.primaryColor,{h:300}),this.cScale11=this.cScale11||g(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||O(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||O(this.tertiaryColor,40);for(let c=0;c{this[r]=e[r]}),this.updateColors(),i.forEach(r=>{this[r]=e[r]})}};const i0=t=>{const e=new e0;return e.calculate(t),e};let r0=class{constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=L("#cde498",10),this.primaryBorderColor=ct(this.primaryColor,this.darkMode),this.secondaryBorderColor=ct(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=ct(this.tertiaryColor,this.darkMode),this.primaryTextColor=C(this.primaryColor),this.secondaryTextColor=C(this.secondaryColor),this.tertiaryTextColor=C(this.primaryColor),this.lineColor=C(this.background),this.textColor=C(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="grey",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){var e,i,r,n,o,s,a,l,h,u,f;this.actorBorder=O(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||g(this.primaryColor,{h:30}),this.cScale4=this.cScale4||g(this.primaryColor,{h:60}),this.cScale5=this.cScale5||g(this.primaryColor,{h:90}),this.cScale6=this.cScale6||g(this.primaryColor,{h:120}),this.cScale7=this.cScale7||g(this.primaryColor,{h:150}),this.cScale8=this.cScale8||g(this.primaryColor,{h:210}),this.cScale9=this.cScale9||g(this.primaryColor,{h:270}),this.cScale10=this.cScale10||g(this.primaryColor,{h:300}),this.cScale11=this.cScale11||g(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||O(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||O(this.tertiaryColor,40);for(let c=0;c{this[r]=e[r]}),this.updateColors(),i.forEach(r=>{this[r]=e[r]})}};const n0=t=>{const e=new r0;return e.calculate(t),e};class o0{constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=L(this.contrast,55),this.background="#ffffff",this.tertiaryColor=g(this.primaryColor,{h:-160}),this.primaryBorderColor=ct(this.primaryColor,this.darkMode),this.secondaryBorderColor=ct(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=ct(this.tertiaryColor,this.darkMode),this.primaryTextColor=C(this.primaryColor),this.secondaryTextColor=C(this.secondaryColor),this.tertiaryTextColor=C(this.tertiaryColor),this.lineColor=C(this.background),this.textColor=C(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){var e,i,r,n,o,s,a,l,h,u,f;this.secondBkg=L(this.contrast,55),this.border2=this.contrast,this.actorBorder=L(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.lineColor,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let c=0;c{this[r]=e[r]}),this.updateColors(),i.forEach(r=>{this[r]=e[r]})}}const s0=t=>{const e=new o0;return e.calculate(t),e},Yt={base:{getThemeVariables:Jm},dark:{getThemeVariables:t0},default:{getThemeVariables:i0},forest:{getThemeVariables:n0},neutral:{getThemeVariables:s0}},Ht={flowchart:{useMaxWidth:!0,titleTopMargin:25,subGraphTitleMargin:{top:0,bottom:0},diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"]},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},xyChart:{useMaxWidth:!0,width:700,height:500,titleFontSize:20,titlePadding:10,showTitle:!0,xAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},yAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},chartOrientation:"vertical",plotReservedSpacePercent:50},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,parallelCommits:!1,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:""},block:{useMaxWidth:!0,padding:8},theme:"default",maxTextSize:5e4,maxEdges:500,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize","maxEdges"],legacyMathML:!1,deterministicIds:!1,fontSize:16},Ja={...Ht,deterministicIDSeed:void 0,themeCSS:void 0,themeVariables:Yt.default.getThemeVariables(),sequence:{...Ht.sequence,messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},noteFont:function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},actorFont:function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}}},gantt:{...Ht.gantt,tickInterval:void 0,useWidth:void 0},c4:{...Ht.c4,useWidth:void 0,personFont:function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},external_personFont:function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},systemFont:function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},external_systemFont:function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},system_dbFont:function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},external_system_dbFont:function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},system_queueFont:function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},external_system_queueFont:function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},containerFont:function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},external_containerFont:function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},container_dbFont:function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},external_container_dbFont:function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},container_queueFont:function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},external_container_queueFont:function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},componentFont:function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},external_componentFont:function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},component_dbFont:function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},external_component_dbFont:function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},component_queueFont:function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},external_component_queueFont:function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},boundaryFont:function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},messageFont:function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}}},pie:{...Ht.pie,useWidth:984},xyChart:{...Ht.xyChart,useWidth:void 0},requirement:{...Ht.requirement,useWidth:void 0},gitGraph:{...Ht.gitGraph,useMaxWidth:!1},sankey:{...Ht.sankey,useMaxWidth:!1}},Qa=(t,e="")=>Object.keys(t).reduce((i,r)=>Array.isArray(t[r])?i:typeof t[r]=="object"&&t[r]!==null?[...i,e+r,...Qa(t[r],"")]:[...i,e+r],[]),a0=new Set(Qa(Ja,"")),l0=Ja,ir=t=>{if(E.debug("sanitizeDirective called with",t),!(typeof t!="object"||t==null)){if(Array.isArray(t)){t.forEach(e=>ir(e));return}for(const e of Object.keys(t)){if(E.debug("Checking key",e),e.startsWith("__")||e.includes("proto")||e.includes("constr")||!a0.has(e)||t[e]==null){E.debug("sanitize deleting key: ",e),delete t[e];continue}if(typeof t[e]=="object"){E.debug("sanitizing object",e),ir(t[e]);continue}const i=["themeCSS","fontFamily","altFontFamily"];for(const r of i)e.includes(r)&&(E.debug("sanitizing css option",e),t[e]=h0(t[e]))}if(t.themeVariables)for(const e of Object.keys(t.themeVariables)){const i=t.themeVariables[e];i!=null&&i.match&&!i.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[e]="")}E.debug("After sanitization",t)}},h0=t=>{let e=0,i=0;for(const r of t){if(e{for(const{id:e,detector:i,loader:r}of t)rl(e,i,r)},rl=(t,e,i)=>{$e[t]?E.error(`Detector with key ${t} already exists`):$e[t]={detector:e,loader:i},E.debug(`Detector with key ${t} added${i?" with loader":""}`)},u0=t=>$e[t].loader,yn=(t,e,{depth:i=2,clobber:r=!1}={})=>{const n={depth:i,clobber:r};return Array.isArray(e)&&!Array.isArray(t)?(e.forEach(o=>yn(t,o,n)),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach(o=>{t.includes(o)||t.push(o)}),t):t===void 0||i<=0?t!=null&&typeof t=="object"&&typeof e=="object"?Object.assign(t,e):e:(e!==void 0&&typeof t=="object"&&typeof e=="object"&&Object.keys(e).forEach(o=>{typeof e[o]=="object"&&(t[o]===void 0||typeof t[o]=="object")?(t[o]===void 0&&(t[o]=Array.isArray(e[o])?[]:{}),t[o]=yn(t[o],e[o],{depth:i-1,clobber:r})):(r||typeof t[o]!="object"&&typeof e[o]!="object")&&(t[o]=e[o])}),t)},at=yn,f0="​",d0={curveBasis:Df,curveBasisClosed:Nf,curveBasisOpen:Rf,curveBumpX:If,curveBumpY:$f,curveBundle:Pf,curveCardinalClosed:zf,curveCardinalOpen:Wf,curveCardinal:qf,curveCatmullRomClosed:jf,curveCatmullRomOpen:Uf,curveCatmullRom:Hf,curveLinear:Mf,curveLinearClosed:Yf,curveMonotoneX:Vf,curveMonotoneY:Gf,curveNatural:Xf,curveStep:Kf,curveStepAfter:Jf,curveStepBefore:Zf},p0=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,g0=function(t,e){const i=nl(t,/(?:init\b)|(?:initialize\b)/);let r={};if(Array.isArray(i)){const s=i.map(a=>a.args);ir(s),r=at(r,[...s])}else r=i.args;if(!r)return;let n=wr(t,e);const o="config";return r[o]!==void 0&&(n==="flowchart-v2"&&(n="flowchart"),r[n]=r[o],delete r[o]),r},nl=function(t,e=null){try{const i=new RegExp(`[%]{2}(?![{]${p0.source})(?=[}][%]{2}).* -`,"ig");t=t.trim().replace(i,"").replace(/'/gm,'"'),E.debug(`Detecting diagram directive${e!==null?" type:"+e:""} based on the text:${t}`);let r;const n=[];for(;(r=ri.exec(t))!==null;)if(r.index===ri.lastIndex&&ri.lastIndex++,r&&!e||e&&r[1]&&r[1].match(e)||e&&r[2]&&r[2].match(e)){const o=r[1]?r[1]:r[2],s=r[3]?r[3].trim():r[4]?JSON.parse(r[4].trim()):null;n.push({type:o,args:s})}return n.length===0?{type:t,args:null}:n.length===1?n[0]:n}catch(i){return E.error(`ERROR: ${i.message} - Unable to parse directive type: '${e}' based on the text: '${t}'`),{type:void 0,args:null}}},m0=function(t){return t.replace(ri,"")},_0=function(t,e){for(const[i,r]of e.entries())if(r.match(t))return i;return-1};function y0(t,e){if(!t)return e;const i=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return d0[i]??e}function C0(t,e){const i=t.trim();if(i)return e.securityLevel!=="loose"?Ns.sanitizeUrl(i):i}const x0=(t,...e)=>{const i=t.split("."),r=i.length-1,n=i[r];let o=window;for(let s=0;s{i+=ol(n,e),e=n});const r=i/2;return zn(t,r)}function T0(t){return t.length===1?t[0]:b0(t)}const xs=(t,e=2)=>{const i=Math.pow(10,e);return Math.round(t*i)/i},zn=(t,e)=>{let i,r=e;for(const n of t){if(i){const o=ol(n,i);if(o=1)return{x:n.x,y:n.y};if(s>0&&s<1)return{x:xs((1-s)*i.x+s*n.x,5),y:xs((1-s)*i.y+s*n.y,5)}}}i=n}throw new Error("Could not find a suitable point for the given distance")},v0=(t,e,i)=>{E.info(`our points ${JSON.stringify(e)}`),e[0]!==i&&(e=e.reverse());const n=zn(e,25),o=t?10:5,s=Math.atan2(e[0].y-n.y,e[0].x-n.x),a={x:0,y:0};return a.x=Math.sin(s)*o+(e[0].x+n.x)/2,a.y=-Math.cos(s)*o+(e[0].y+n.y)/2,a};function k0(t,e,i){const r=structuredClone(i);E.info("our points",r),e!=="start_left"&&e!=="start_right"&&r.reverse();const n=25+t,o=zn(r,n),s=10+t*.5,a=Math.atan2(r[0].y-o.y,r[0].x-o.x),l={x:0,y:0};return e==="start_left"?(l.x=Math.sin(a+Math.PI)*s+(r[0].x+o.x)/2,l.y=-Math.cos(a+Math.PI)*s+(r[0].y+o.y)/2):e==="end_right"?(l.x=Math.sin(a-Math.PI)*s+(r[0].x+o.x)/2-5,l.y=-Math.cos(a-Math.PI)*s+(r[0].y+o.y)/2-5):e==="end_left"?(l.x=Math.sin(a)*s+(r[0].x+o.x)/2-5,l.y=-Math.cos(a)*s+(r[0].y+o.y)/2-5):(l.x=Math.sin(a)*s+(r[0].x+o.x)/2,l.y=-Math.cos(a)*s+(r[0].y+o.y)/2),l}function S0(t){let e="",i="";for(const r of t)r!==void 0&&(r.startsWith("color:")||r.startsWith("text-align:")?i=i+r+";":e=e+r+";");return{style:e,labelStyle:i}}let bs=0;const w0=()=>(bs++,"id-"+Math.random().toString(36).substr(2,12)+"-"+bs);function B0(t){let e="";const i="0123456789abcdef",r=i.length;for(let n=0;nB0(t.length),L0=function(){return{x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0,text:""}},F0=function(t,e){const i=e.text.replace(qn.lineBreakRegex," "),[,r]=Hn(e.fontSize),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.style("text-anchor",e.anchor),n.style("font-family",e.fontFamily),n.style("font-size",r),n.style("font-weight",e.fontWeight),n.attr("fill",e.fill),e.class!==void 0&&n.attr("class",e.class);const o=n.append("tspan");return o.attr("x",e.x+e.textMargin*2),o.attr("fill",e.fill),o.text(i),n},E0=Ci((t,e,i)=>{if(!t||(i=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"
                        "},i),qn.lineBreakRegex.test(t)))return t;const r=t.split(" "),n=[];let o="";return r.forEach((s,a)=>{const l=rr(`${s} `,i),h=rr(o,i);if(l>e){const{hyphenatedStrings:c,remainingWord:d}=O0(s,e,"-",i);n.push(o,...c),o=d}else h+l>=e?(n.push(o),o=s):o=[o,s].filter(Boolean).join(" ");a+1===r.length&&n.push(o)}),n.filter(s=>s!=="").join(i.joinWith)},(t,e,i)=>`${t}${e}${i.fontSize}${i.fontWeight}${i.fontFamily}${i.joinWith}`),O0=Ci((t,e,i="-",r)=>{r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},r);const n=[...t],o=[];let s="";return n.forEach((a,l)=>{const h=`${s}${a}`;if(rr(h,r)>=e){const f=l+1,c=n.length===f,d=`${h}${i}`;o.push(c?h:d),s=""}else s=h}),{hyphenatedStrings:o,remainingWord:s}},(t,e,i="-",r)=>`${t}${e}${i}${r.fontSize}${r.fontWeight}${r.fontFamily}`);function M0(t,e){return Wn(t,e).height}function rr(t,e){return Wn(t,e).width}const Wn=Ci((t,e)=>{const{fontSize:i=12,fontFamily:r="Arial",fontWeight:n=400}=e;if(!t)return{width:0,height:0};const[,o]=Hn(i),s=["sans-serif",r],a=t.split(qn.lineBreakRegex),l=[],h=xt("body");if(!h.remove)return{width:0,height:0,lineHeight:0};const u=h.append("svg");for(const c of s){let d=0;const _={width:0,height:0,lineHeight:0};for(const k of a){const S=L0();S.text=k||f0;const R=F0(u,S).style("font-size",o).style("font-weight",n).style("font-family",c),T=(R._groups||R)[0][0].getBBox();if(T.width===0&&T.height===0)throw new Error("svg element not in render tree");_.width=Math.round(Math.max(_.width,T.width)),d=Math.round(T.height),_.height+=d,_.lineHeight=Math.round(Math.max(_.lineHeight,d))}l.push(_)}u.remove();const f=isNaN(l[1].height)||isNaN(l[1].width)||isNaN(l[1].lineHeight)||l[0].height>l[1].height&&l[0].width>l[1].width&&l[0].lineHeight>l[1].lineHeight?0:1;return l[f]},(t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`);class I0{constructor(e=!1,i){this.count=0,this.count=i?i.length:0,this.next=e?()=>this.count++:()=>Date.now()}}let Mi;const $0=function(t){return Mi=Mi||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),Mi.innerHTML=t,unescape(Mi.textContent)};function sl(t){return"str"in t}const D0=(t,e,i,r)=>{var n;if(!r)return;const o=(n=t.node())==null?void 0:n.getBBox();o&&t.append("text").text(r).attr("x",o.x+o.width/2).attr("y",-i).attr("class",e)},Hn=t=>{if(typeof t=="number")return[t,t+"px"];const e=parseInt(t??"",10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]};function al(t,e){return sm({},t,e)}const ni={assignWithDepth:at,wrapLabel:E0,calculateTextHeight:M0,calculateTextWidth:rr,calculateTextDimensions:Wn,cleanAndMerge:al,detectInit:g0,detectDirective:nl,isSubstringInArray:_0,interpolateToCurve:y0,calcLabelPosition:T0,calcCardinalityPosition:v0,calcTerminalLabelPosition:k0,formatUrl:C0,getStylesFromArray:S0,generateId:w0,random:A0,runFunc:x0,entityDecode:$0,insertTitle:D0,parseFontSize:Hn,InitIDGenerator:I0},N0=function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,function(i){return i.substring(0,i.length-1)}),e=e.replace(/classDef.*:\S*#.*;/g,function(i){return i.substring(0,i.length-1)}),e=e.replace(/#\w+;/g,function(i){const r=i.substring(1,i.length-1);return/^\+?\d+$/.test(r)?"fl°°"+r+"¶ß":"fl°"+r+"¶ß"}),e},R0=function(t){return t.replace(/fl°°/g,"&#").replace(/fl°/g,"&").replace(/¶ß/g,";")},Ts="10.9.0",De=Object.freeze(l0);let pt=at({},De),ll,Ne=[],oi=at({},De);const Br=(t,e)=>{let i=at({},t),r={};for(const n of e)ul(n),r=at(r,n);if(i=at(i,r),r.theme&&r.theme in Yt){const n=at({},ll),o=at(n.themeVariables||{},r.themeVariables);i.theme&&i.theme in Yt&&(i.themeVariables=Yt[i.theme].getThemeVariables(o))}return oi=i,fl(oi),oi},P0=t=>(pt=at({},De),pt=at(pt,t),t.theme&&Yt[t.theme]&&(pt.themeVariables=Yt[t.theme].getThemeVariables(t.themeVariables)),Br(pt,Ne),pt),q0=t=>{ll=at({},t)},z0=t=>(pt=at(pt,t),Br(pt,Ne),pt),hl=()=>at({},pt),cl=t=>(fl(t),at(oi,t),It()),It=()=>at({},oi),ul=t=>{t&&(["secure",...pt.secure??[]].forEach(e=>{Object.hasOwn(t,e)&&(E.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])}),Object.keys(t).forEach(e=>{e.startsWith("__")&&delete t[e]}),Object.keys(t).forEach(e=>{typeof t[e]=="string"&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],typeof t[e]=="object"&&ul(t[e])}))},W0=t=>{ir(t),t.fontFamily&&(!t.themeVariables||!t.themeVariables.fontFamily)&&(t.themeVariables={fontFamily:t.fontFamily}),Ne.push(t),Br(pt,Ne)},nr=(t=pt)=>{Ne=[],Br(t,Ne)},H0={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},vs={},j0=t=>{vs[t]||(E.warn(H0[t]),vs[t]=!0)},fl=t=>{t&&(t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&j0("LAZY_LOAD_DEPRECATED")},dl="c4",U0=t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t),Y0=async()=>{const{diagram:t}=await X(()=>import("./c4Diagram-b2a90758-61jLNFqu.js"),__vite__mapDeps([0,1,2]));return{id:dl,diagram:t}},V0={id:dl,detector:U0,loader:Y0},G0=V0,pl="flowchart",X0=(t,e)=>{var i,r;return((i=e==null?void 0:e.flowchart)==null?void 0:i.defaultRenderer)==="dagre-wrapper"||((r=e==null?void 0:e.flowchart)==null?void 0:r.defaultRenderer)==="elk"?!1:/^\s*graph/.test(t)},K0=async()=>{const{diagram:t}=await X(()=>import("./flowDiagram-5540d9b9-XEePSu7I.js"),__vite__mapDeps([3,4,5,6,7,8,9,10,11,12,13,14,15,2]));return{id:pl,diagram:t}},Z0={id:pl,detector:X0,loader:K0},J0=Z0,gl="flowchart-v2",Q0=(t,e)=>{var i,r,n;return((i=e==null?void 0:e.flowchart)==null?void 0:i.defaultRenderer)==="dagre-d3"||((r=e==null?void 0:e.flowchart)==null?void 0:r.defaultRenderer)==="elk"?!1:/^\s*graph/.test(t)&&((n=e==null?void 0:e.flowchart)==null?void 0:n.defaultRenderer)==="dagre-wrapper"?!0:/^\s*flowchart/.test(t)},t_=async()=>{const{diagram:t}=await X(()=>import("./flowDiagram-v2-3b53844e-VJ0ZCiud.js"),__vite__mapDeps([16,4,7,5,8,6,9,10,11,12,13,14,15,2]));return{id:gl,diagram:t}},e_={id:gl,detector:Q0,loader:t_},i_=e_,ml="er",r_=t=>/^\s*erDiagram/.test(t),n_=async()=>{const{diagram:t}=await X(()=>import("./erDiagram-47591fe2-CbfSLOL9.js"),__vite__mapDeps([17,5,6,12,13,14,2]));return{id:ml,diagram:t}},o_={id:ml,detector:r_,loader:n_},s_=o_,_l="gitGraph",a_=t=>/^\s*gitGraph/.test(t),l_=async()=>{const{diagram:t}=await X(()=>import("./gitGraphDiagram-96e6b4ee-Sl4MCJL1.js"),__vite__mapDeps([18,2]));return{id:_l,diagram:t}},h_={id:_l,detector:a_,loader:l_},c_=h_,yl="gantt",u_=t=>/^\s*gantt/.test(t),f_=async()=>{const{diagram:t}=await X(()=>import("./ganttDiagram-9a3bba1f-Mk83ufVS.js"),__vite__mapDeps([19,20,21,2]));return{id:yl,diagram:t}},d_={id:yl,detector:u_,loader:f_},p_=d_,Cl="info",g_=t=>/^\s*info/.test(t),m_=async()=>{const{diagram:t}=await X(()=>import("./infoDiagram-bcd20f53-aQsUByZm.js"),__vite__mapDeps([22,2]));return{id:Cl,diagram:t}},__={id:Cl,detector:g_,loader:m_},xl="pie",y_=t=>/^\s*pie/.test(t),C_=async()=>{const{diagram:t}=await X(()=>import("./pieDiagram-79897490-axGt9ShQ.js"),__vite__mapDeps([23,24,14,25,21,13,2]));return{id:xl,diagram:t}},x_={id:xl,detector:y_,loader:C_},bl="quadrantChart",b_=t=>/^\s*quadrantChart/.test(t),T_=async()=>{const{diagram:t}=await X(()=>import("./quadrantDiagram-62f64e94-DSAXizG6.js"),__vite__mapDeps([26,20,21,2]));return{id:bl,diagram:t}},v_={id:bl,detector:b_,loader:T_},k_=v_,Tl="xychart",S_=t=>/^\s*xychart-beta/.test(t),w_=async()=>{const{diagram:t}=await X(()=>import("./xychartDiagram-ab372869-NbNQWlrD.js"),__vite__mapDeps([27,11,21,25,20,12,13,14,2]));return{id:Tl,diagram:t}},B_={id:Tl,detector:S_,loader:w_},A_=B_,vl="requirement",L_=t=>/^\s*requirement(Diagram)?/.test(t),F_=async()=>{const{diagram:t}=await X(()=>import("./requirementDiagram-05bf5f74--Z92gB8m.js"),__vite__mapDeps([28,5,6,12,13,14,2]));return{id:vl,diagram:t}},E_={id:vl,detector:L_,loader:F_},O_=E_,kl="sequence",M_=t=>/^\s*sequenceDiagram/.test(t),I_=async()=>{const{diagram:t}=await X(()=>import("./sequenceDiagram-acc0e65c-TzfkGb4D.js"),__vite__mapDeps([29,1,2]));return{id:kl,diagram:t}},$_={id:kl,detector:M_,loader:I_},D_=$_,Sl="class",N_=(t,e)=>{var i;return((i=e==null?void 0:e.class)==null?void 0:i.defaultRenderer)==="dagre-wrapper"?!1:/^\s*classDiagram/.test(t)},R_=async()=>{const{diagram:t}=await X(()=>import("./classDiagram-30eddba6-OAikPNdt.js"),__vite__mapDeps([30,31,5,6,12,13,14,2]));return{id:Sl,diagram:t}},P_={id:Sl,detector:N_,loader:R_},q_=P_,wl="classDiagram",z_=(t,e)=>{var i;return/^\s*classDiagram/.test(t)&&((i=e==null?void 0:e.class)==null?void 0:i.defaultRenderer)==="dagre-wrapper"?!0:/^\s*classDiagram-v2/.test(t)},W_=async()=>{const{diagram:t}=await X(()=>import("./classDiagram-v2-f2df5561-yJMOQ1KK.js"),__vite__mapDeps([32,31,5,8,6,9,10,11,12,13,14,2]));return{id:wl,diagram:t}},H_={id:wl,detector:z_,loader:W_},j_=H_,Bl="state",U_=(t,e)=>{var i;return((i=e==null?void 0:e.state)==null?void 0:i.defaultRenderer)==="dagre-wrapper"?!1:/^\s*stateDiagram/.test(t)},Y_=async()=>{const{diagram:t}=await X(()=>import("./stateDiagram-0ff1cf1a-sl2QinQH.js"),__vite__mapDeps([33,34,5,6,12,13,14,2]));return{id:Bl,diagram:t}},V_={id:Bl,detector:U_,loader:Y_},G_=V_,Al="stateDiagram",X_=(t,e)=>{var i;return!!(/^\s*stateDiagram-v2/.test(t)||/^\s*stateDiagram/.test(t)&&((i=e==null?void 0:e.state)==null?void 0:i.defaultRenderer)==="dagre-wrapper")},K_=async()=>{const{diagram:t}=await X(()=>import("./stateDiagram-v2-9a9d610d-sZSBWe92.js"),__vite__mapDeps([35,34,5,8,6,9,10,11,12,13,14,2]));return{id:Al,diagram:t}},Z_={id:Al,detector:X_,loader:K_},J_=Z_,Ll="journey",Q_=t=>/^\s*journey/.test(t),ty=async()=>{const{diagram:t}=await X(()=>import("./journeyDiagram-4fe6b3dc-5Up4aSjD.js"),__vite__mapDeps([36,1,24,14,2]));return{id:Ll,diagram:t}},ey={id:Ll,detector:Q_,loader:ty},iy=ey,ry=function(t,e){for(let i of e)t.attr(i[0],i[1])},ny=function(t,e,i){let r=new Map;return i?(r.set("width","100%"),r.set("style",`max-width: ${e}px;`)):(r.set("height",t),r.set("width",e)),r},Fl=function(t,e,i,r){const n=ny(e,i,r);ry(t,n)},oy=function(t,e,i,r){const n=e.node().getBBox(),o=n.width,s=n.height;E.info(`SVG bounds: ${o}x${s}`,n);let a=0,l=0;E.info(`Graph bounds: ${a}x${l}`,t),a=o+i*2,l=s+i*2,E.info(`Calculated bounds: ${a}x${l}`),Fl(e,l,a,r);const h=`${n.x-i} ${n.y-i} ${n.width+2*i} ${n.height+2*i}`;e.attr("viewBox",h)},Wi={},sy=(t,e,i)=>{let r="";return t in Wi&&Wi[t]?r=Wi[t](i):E.warn(`No theme found for ${t}`),` & { +`,"ig");t=t.trim().replace(i,"").replace(/'/gm,'"'),E.debug(`Detecting diagram directive${e!==null?" type:"+e:""} based on the text:${t}`);let r;const n=[];for(;(r=ri.exec(t))!==null;)if(r.index===ri.lastIndex&&ri.lastIndex++,r&&!e||e&&r[1]&&r[1].match(e)||e&&r[2]&&r[2].match(e)){const o=r[1]?r[1]:r[2],s=r[3]?r[3].trim():r[4]?JSON.parse(r[4].trim()):null;n.push({type:o,args:s})}return n.length===0?{type:t,args:null}:n.length===1?n[0]:n}catch(i){return E.error(`ERROR: ${i.message} - Unable to parse directive type: '${e}' based on the text: '${t}'`),{type:void 0,args:null}}},m0=function(t){return t.replace(ri,"")},_0=function(t,e){for(const[i,r]of e.entries())if(r.match(t))return i;return-1};function y0(t,e){if(!t)return e;const i=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return d0[i]??e}function C0(t,e){const i=t.trim();if(i)return e.securityLevel!=="loose"?Ns.sanitizeUrl(i):i}const x0=(t,...e)=>{const i=t.split("."),r=i.length-1,n=i[r];let o=window;for(let s=0;s{i+=ol(n,e),e=n});const r=i/2;return zn(t,r)}function T0(t){return t.length===1?t[0]:b0(t)}const xs=(t,e=2)=>{const i=Math.pow(10,e);return Math.round(t*i)/i},zn=(t,e)=>{let i,r=e;for(const n of t){if(i){const o=ol(n,i);if(o=1)return{x:n.x,y:n.y};if(s>0&&s<1)return{x:xs((1-s)*i.x+s*n.x,5),y:xs((1-s)*i.y+s*n.y,5)}}}i=n}throw new Error("Could not find a suitable point for the given distance")},v0=(t,e,i)=>{E.info(`our points ${JSON.stringify(e)}`),e[0]!==i&&(e=e.reverse());const n=zn(e,25),o=t?10:5,s=Math.atan2(e[0].y-n.y,e[0].x-n.x),a={x:0,y:0};return a.x=Math.sin(s)*o+(e[0].x+n.x)/2,a.y=-Math.cos(s)*o+(e[0].y+n.y)/2,a};function k0(t,e,i){const r=structuredClone(i);E.info("our points",r),e!=="start_left"&&e!=="start_right"&&r.reverse();const n=25+t,o=zn(r,n),s=10+t*.5,a=Math.atan2(r[0].y-o.y,r[0].x-o.x),l={x:0,y:0};return e==="start_left"?(l.x=Math.sin(a+Math.PI)*s+(r[0].x+o.x)/2,l.y=-Math.cos(a+Math.PI)*s+(r[0].y+o.y)/2):e==="end_right"?(l.x=Math.sin(a-Math.PI)*s+(r[0].x+o.x)/2-5,l.y=-Math.cos(a-Math.PI)*s+(r[0].y+o.y)/2-5):e==="end_left"?(l.x=Math.sin(a)*s+(r[0].x+o.x)/2-5,l.y=-Math.cos(a)*s+(r[0].y+o.y)/2-5):(l.x=Math.sin(a)*s+(r[0].x+o.x)/2,l.y=-Math.cos(a)*s+(r[0].y+o.y)/2),l}function S0(t){let e="",i="";for(const r of t)r!==void 0&&(r.startsWith("color:")||r.startsWith("text-align:")?i=i+r+";":e=e+r+";");return{style:e,labelStyle:i}}let bs=0;const w0=()=>(bs++,"id-"+Math.random().toString(36).substr(2,12)+"-"+bs);function B0(t){let e="";const i="0123456789abcdef",r=i.length;for(let n=0;nB0(t.length),L0=function(){return{x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0,text:""}},F0=function(t,e){const i=e.text.replace(qn.lineBreakRegex," "),[,r]=Hn(e.fontSize),n=t.append("text");n.attr("x",e.x),n.attr("y",e.y),n.style("text-anchor",e.anchor),n.style("font-family",e.fontFamily),n.style("font-size",r),n.style("font-weight",e.fontWeight),n.attr("fill",e.fill),e.class!==void 0&&n.attr("class",e.class);const o=n.append("tspan");return o.attr("x",e.x+e.textMargin*2),o.attr("fill",e.fill),o.text(i),n},E0=Ci((t,e,i)=>{if(!t||(i=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"
                        "},i),qn.lineBreakRegex.test(t)))return t;const r=t.split(" "),n=[];let o="";return r.forEach((s,a)=>{const l=rr(`${s} `,i),h=rr(o,i);if(l>e){const{hyphenatedStrings:c,remainingWord:d}=O0(s,e,"-",i);n.push(o,...c),o=d}else h+l>=e?(n.push(o),o=s):o=[o,s].filter(Boolean).join(" ");a+1===r.length&&n.push(o)}),n.filter(s=>s!=="").join(i.joinWith)},(t,e,i)=>`${t}${e}${i.fontSize}${i.fontWeight}${i.fontFamily}${i.joinWith}`),O0=Ci((t,e,i="-",r)=>{r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},r);const n=[...t],o=[];let s="";return n.forEach((a,l)=>{const h=`${s}${a}`;if(rr(h,r)>=e){const f=l+1,c=n.length===f,d=`${h}${i}`;o.push(c?h:d),s=""}else s=h}),{hyphenatedStrings:o,remainingWord:s}},(t,e,i="-",r)=>`${t}${e}${i}${r.fontSize}${r.fontWeight}${r.fontFamily}`);function M0(t,e){return Wn(t,e).height}function rr(t,e){return Wn(t,e).width}const Wn=Ci((t,e)=>{const{fontSize:i=12,fontFamily:r="Arial",fontWeight:n=400}=e;if(!t)return{width:0,height:0};const[,o]=Hn(i),s=["sans-serif",r],a=t.split(qn.lineBreakRegex),l=[],h=xt("body");if(!h.remove)return{width:0,height:0,lineHeight:0};const u=h.append("svg");for(const c of s){let d=0;const _={width:0,height:0,lineHeight:0};for(const k of a){const S=L0();S.text=k||f0;const R=F0(u,S).style("font-size",o).style("font-weight",n).style("font-family",c),T=(R._groups||R)[0][0].getBBox();if(T.width===0&&T.height===0)throw new Error("svg element not in render tree");_.width=Math.round(Math.max(_.width,T.width)),d=Math.round(T.height),_.height+=d,_.lineHeight=Math.round(Math.max(_.lineHeight,d))}l.push(_)}u.remove();const f=isNaN(l[1].height)||isNaN(l[1].width)||isNaN(l[1].lineHeight)||l[0].height>l[1].height&&l[0].width>l[1].width&&l[0].lineHeight>l[1].lineHeight?0:1;return l[f]},(t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`);class I0{constructor(e=!1,i){this.count=0,this.count=i?i.length:0,this.next=e?()=>this.count++:()=>Date.now()}}let Mi;const $0=function(t){return Mi=Mi||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),Mi.innerHTML=t,unescape(Mi.textContent)};function sl(t){return"str"in t}const D0=(t,e,i,r)=>{var n;if(!r)return;const o=(n=t.node())==null?void 0:n.getBBox();o&&t.append("text").text(r).attr("x",o.x+o.width/2).attr("y",-i).attr("class",e)},Hn=t=>{if(typeof t=="number")return[t,t+"px"];const e=parseInt(t??"",10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]};function al(t,e){return sm({},t,e)}const ni={assignWithDepth:at,wrapLabel:E0,calculateTextHeight:M0,calculateTextWidth:rr,calculateTextDimensions:Wn,cleanAndMerge:al,detectInit:g0,detectDirective:nl,isSubstringInArray:_0,interpolateToCurve:y0,calcLabelPosition:T0,calcCardinalityPosition:v0,calcTerminalLabelPosition:k0,formatUrl:C0,getStylesFromArray:S0,generateId:w0,random:A0,runFunc:x0,entityDecode:$0,insertTitle:D0,parseFontSize:Hn,InitIDGenerator:I0},N0=function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,function(i){return i.substring(0,i.length-1)}),e=e.replace(/classDef.*:\S*#.*;/g,function(i){return i.substring(0,i.length-1)}),e=e.replace(/#\w+;/g,function(i){const r=i.substring(1,i.length-1);return/^\+?\d+$/.test(r)?"fl°°"+r+"¶ß":"fl°"+r+"¶ß"}),e},R0=function(t){return t.replace(/fl°°/g,"&#").replace(/fl°/g,"&").replace(/¶ß/g,";")},Ts="10.9.0",De=Object.freeze(l0);let pt=at({},De),ll,Ne=[],oi=at({},De);const Br=(t,e)=>{let i=at({},t),r={};for(const n of e)ul(n),r=at(r,n);if(i=at(i,r),r.theme&&r.theme in Yt){const n=at({},ll),o=at(n.themeVariables||{},r.themeVariables);i.theme&&i.theme in Yt&&(i.themeVariables=Yt[i.theme].getThemeVariables(o))}return oi=i,fl(oi),oi},P0=t=>(pt=at({},De),pt=at(pt,t),t.theme&&Yt[t.theme]&&(pt.themeVariables=Yt[t.theme].getThemeVariables(t.themeVariables)),Br(pt,Ne),pt),q0=t=>{ll=at({},t)},z0=t=>(pt=at(pt,t),Br(pt,Ne),pt),hl=()=>at({},pt),cl=t=>(fl(t),at(oi,t),It()),It=()=>at({},oi),ul=t=>{t&&(["secure",...pt.secure??[]].forEach(e=>{Object.hasOwn(t,e)&&(E.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])}),Object.keys(t).forEach(e=>{e.startsWith("__")&&delete t[e]}),Object.keys(t).forEach(e=>{typeof t[e]=="string"&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],typeof t[e]=="object"&&ul(t[e])}))},W0=t=>{ir(t),t.fontFamily&&(!t.themeVariables||!t.themeVariables.fontFamily)&&(t.themeVariables={fontFamily:t.fontFamily}),Ne.push(t),Br(pt,Ne)},nr=(t=pt)=>{Ne=[],Br(t,Ne)},H0={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},vs={},j0=t=>{vs[t]||(E.warn(H0[t]),vs[t]=!0)},fl=t=>{t&&(t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&j0("LAZY_LOAD_DEPRECATED")},dl="c4",U0=t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t),Y0=async()=>{const{diagram:t}=await X(()=>import("./c4Diagram-b2a90758-Ozn2CEAW.js"),__vite__mapDeps([0,1,2]));return{id:dl,diagram:t}},V0={id:dl,detector:U0,loader:Y0},G0=V0,pl="flowchart",X0=(t,e)=>{var i,r;return((i=e==null?void 0:e.flowchart)==null?void 0:i.defaultRenderer)==="dagre-wrapper"||((r=e==null?void 0:e.flowchart)==null?void 0:r.defaultRenderer)==="elk"?!1:/^\s*graph/.test(t)},K0=async()=>{const{diagram:t}=await X(()=>import("./flowDiagram-5540d9b9-mp-41puG.js"),__vite__mapDeps([3,4,5,6,7,8,9,10,11,12,13,14,15,2]));return{id:pl,diagram:t}},Z0={id:pl,detector:X0,loader:K0},J0=Z0,gl="flowchart-v2",Q0=(t,e)=>{var i,r,n;return((i=e==null?void 0:e.flowchart)==null?void 0:i.defaultRenderer)==="dagre-d3"||((r=e==null?void 0:e.flowchart)==null?void 0:r.defaultRenderer)==="elk"?!1:/^\s*graph/.test(t)&&((n=e==null?void 0:e.flowchart)==null?void 0:n.defaultRenderer)==="dagre-wrapper"?!0:/^\s*flowchart/.test(t)},t_=async()=>{const{diagram:t}=await X(()=>import("./flowDiagram-v2-3b53844e-Cs1ZpX_T.js"),__vite__mapDeps([16,4,7,5,8,6,9,10,11,12,13,14,15,2]));return{id:gl,diagram:t}},e_={id:gl,detector:Q0,loader:t_},i_=e_,ml="er",r_=t=>/^\s*erDiagram/.test(t),n_=async()=>{const{diagram:t}=await X(()=>import("./erDiagram-47591fe2-RWR6JLP0.js"),__vite__mapDeps([17,5,6,12,13,14,2]));return{id:ml,diagram:t}},o_={id:ml,detector:r_,loader:n_},s_=o_,_l="gitGraph",a_=t=>/^\s*gitGraph/.test(t),l_=async()=>{const{diagram:t}=await X(()=>import("./gitGraphDiagram-96e6b4ee-kyRwI9Lw.js"),__vite__mapDeps([18,2]));return{id:_l,diagram:t}},h_={id:_l,detector:a_,loader:l_},c_=h_,yl="gantt",u_=t=>/^\s*gantt/.test(t),f_=async()=>{const{diagram:t}=await X(()=>import("./ganttDiagram-9a3bba1f-KGvD9HhD.js"),__vite__mapDeps([19,20,21,2]));return{id:yl,diagram:t}},d_={id:yl,detector:u_,loader:f_},p_=d_,Cl="info",g_=t=>/^\s*info/.test(t),m_=async()=>{const{diagram:t}=await X(()=>import("./infoDiagram-bcd20f53-qNUwp2oi.js"),__vite__mapDeps([22,2]));return{id:Cl,diagram:t}},__={id:Cl,detector:g_,loader:m_},xl="pie",y_=t=>/^\s*pie/.test(t),C_=async()=>{const{diagram:t}=await X(()=>import("./pieDiagram-79897490-xf0NxzxJ.js"),__vite__mapDeps([23,24,14,25,21,13,2]));return{id:xl,diagram:t}},x_={id:xl,detector:y_,loader:C_},bl="quadrantChart",b_=t=>/^\s*quadrantChart/.test(t),T_=async()=>{const{diagram:t}=await X(()=>import("./quadrantDiagram-62f64e94-cAAwIO1z.js"),__vite__mapDeps([26,20,21,2]));return{id:bl,diagram:t}},v_={id:bl,detector:b_,loader:T_},k_=v_,Tl="xychart",S_=t=>/^\s*xychart-beta/.test(t),w_=async()=>{const{diagram:t}=await X(()=>import("./xychartDiagram-ab372869-zbSuzsOs.js"),__vite__mapDeps([27,11,21,25,20,12,13,14,2]));return{id:Tl,diagram:t}},B_={id:Tl,detector:S_,loader:w_},A_=B_,vl="requirement",L_=t=>/^\s*requirement(Diagram)?/.test(t),F_=async()=>{const{diagram:t}=await X(()=>import("./requirementDiagram-05bf5f74-HkrjUmOA.js"),__vite__mapDeps([28,5,6,12,13,14,2]));return{id:vl,diagram:t}},E_={id:vl,detector:L_,loader:F_},O_=E_,kl="sequence",M_=t=>/^\s*sequenceDiagram/.test(t),I_=async()=>{const{diagram:t}=await X(()=>import("./sequenceDiagram-acc0e65c-So47ZKCj.js"),__vite__mapDeps([29,1,2]));return{id:kl,diagram:t}},$_={id:kl,detector:M_,loader:I_},D_=$_,Sl="class",N_=(t,e)=>{var i;return((i=e==null?void 0:e.class)==null?void 0:i.defaultRenderer)==="dagre-wrapper"?!1:/^\s*classDiagram/.test(t)},R_=async()=>{const{diagram:t}=await X(()=>import("./classDiagram-30eddba6-LzAW2Y3L.js"),__vite__mapDeps([30,31,5,6,12,13,14,2]));return{id:Sl,diagram:t}},P_={id:Sl,detector:N_,loader:R_},q_=P_,wl="classDiagram",z_=(t,e)=>{var i;return/^\s*classDiagram/.test(t)&&((i=e==null?void 0:e.class)==null?void 0:i.defaultRenderer)==="dagre-wrapper"?!0:/^\s*classDiagram-v2/.test(t)},W_=async()=>{const{diagram:t}=await X(()=>import("./classDiagram-v2-f2df5561-L_-CRfCF.js"),__vite__mapDeps([32,31,5,8,6,9,10,11,12,13,14,2]));return{id:wl,diagram:t}},H_={id:wl,detector:z_,loader:W_},j_=H_,Bl="state",U_=(t,e)=>{var i;return((i=e==null?void 0:e.state)==null?void 0:i.defaultRenderer)==="dagre-wrapper"?!1:/^\s*stateDiagram/.test(t)},Y_=async()=>{const{diagram:t}=await X(()=>import("./stateDiagram-0ff1cf1a-Rh0IBuDT.js"),__vite__mapDeps([33,34,5,6,12,13,14,2]));return{id:Bl,diagram:t}},V_={id:Bl,detector:U_,loader:Y_},G_=V_,Al="stateDiagram",X_=(t,e)=>{var i;return!!(/^\s*stateDiagram-v2/.test(t)||/^\s*stateDiagram/.test(t)&&((i=e==null?void 0:e.state)==null?void 0:i.defaultRenderer)==="dagre-wrapper")},K_=async()=>{const{diagram:t}=await X(()=>import("./stateDiagram-v2-9a9d610d-Gp1zKQgn.js"),__vite__mapDeps([35,34,5,8,6,9,10,11,12,13,14,2]));return{id:Al,diagram:t}},Z_={id:Al,detector:X_,loader:K_},J_=Z_,Ll="journey",Q_=t=>/^\s*journey/.test(t),ty=async()=>{const{diagram:t}=await X(()=>import("./journeyDiagram-4fe6b3dc-v7Caieti.js"),__vite__mapDeps([36,1,24,14,2]));return{id:Ll,diagram:t}},ey={id:Ll,detector:Q_,loader:ty},iy=ey,ry=function(t,e){for(let i of e)t.attr(i[0],i[1])},ny=function(t,e,i){let r=new Map;return i?(r.set("width","100%"),r.set("style",`max-width: ${e}px;`)):(r.set("height",t),r.set("width",e)),r},Fl=function(t,e,i,r){const n=ny(e,i,r);ry(t,n)},oy=function(t,e,i,r){const n=e.node().getBBox(),o=n.width,s=n.height;E.info(`SVG bounds: ${o}x${s}`,n);let a=0,l=0;E.info(`Graph bounds: ${a}x${l}`,t),a=o+i*2,l=s+i*2,E.info(`Calculated bounds: ${a}x${l}`),Fl(e,l,a,r);const h=`${n.x-i} ${n.y-i} ${n.width+2*i} ${n.height+2*i}`;e.attr("viewBox",h)},Wi={},sy=(t,e,i)=>{let r="";return t in Wi&&Wi[t]?r=Wi[t](i):E.warn(`No theme found for ${t}`),` & { font-family: ${i.fontFamily}; font-size: ${i.fontSize}; fill: ${i.textColor} @@ -61,7 +61,7 @@ import{q as X}from"./app-PDrbPfzp.js";function dh(t){for(var e=[],i=1;i{e!==void 0&&(Wi[t]=e)},ly=sy;let jn="",Un="",Yn="";const Vn=t=>pi(t,It()),hy=()=>{jn="",Yn="",Un=""},cy=t=>{jn=Vn(t).replace(/^\s+/g,"")},uy=()=>jn,fy=t=>{Yn=Vn(t).replace(/\n\s+/g,` `)},dy=()=>Yn,py=t=>{Un=Vn(t)},gy=()=>Un,my=Object.freeze(Object.defineProperty({__proto__:null,clear:hy,getAccDescription:dy,getAccTitle:uy,getDiagramTitle:gy,setAccDescription:fy,setAccTitle:cy,setDiagramTitle:py},Symbol.toStringTag,{value:"Module"})),_y=E,yy=Pn,Gn=It,Wb=cl,Hb=De,Cy=t=>pi(t,Gn()),xy=oy,by=()=>my,or={},sr=(t,e,i)=>{var r;if(or[t])throw new Error(`Diagram ${t} already registered.`);or[t]=e,i&&rl(t,i),ay(t,e.styles),(r=e.injectUtils)==null||r.call(e,_y,yy,Gn,Cy,xy,by(),()=>{})},Xn=t=>{if(t in or)return or[t];throw new Ty(t)};class Ty extends Error{constructor(e){super(`Diagram ${e} not found.`)}}const vy=t=>{var e;const{securityLevel:i}=Gn();let r=xt("body");if(i==="sandbox"){const s=((e=xt(`#i${t}`).node())==null?void 0:e.contentDocument)??document;r=xt(s.body)}return r.select(`#${t}`)},ky=(t,e,i)=>{E.debug(`rendering svg for syntax error -`);const r=vy(e),n=r.append("g");r.attr("viewBox","0 0 2412 512"),Fl(r,100,512,!0),n.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),n.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),n.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),n.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),n.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),n.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),n.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),n.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${i}`)},El={draw:ky},Sy=El,wy={db:{},renderer:El,parser:{parser:{yy:{}},parse:()=>{}}},By=wy,Ol="flowchart-elk",Ay=(t,e)=>{var i;return!!(/^\s*flowchart-elk/.test(t)||/^\s*flowchart|graph/.test(t)&&((i=e==null?void 0:e.flowchart)==null?void 0:i.defaultRenderer)==="elk")},Ly=async()=>{const{diagram:t}=await X(()=>import("./flowchart-elk-definition-5fe447d6-2wwBOAT6.js"),__vite__mapDeps([37,4,10,11,12,13,14,2]));return{id:Ol,diagram:t}},Fy={id:Ol,detector:Ay,loader:Ly},Ey=Fy,Ml="timeline",Oy=t=>/^\s*timeline/.test(t),My=async()=>{const{diagram:t}=await X(()=>import("./timeline-definition-fea2a41d-4QeTlQgD.js"),__vite__mapDeps([38,24,14,2]));return{id:Ml,diagram:t}},Iy={id:Ml,detector:Oy,loader:My},$y=Iy,Il="mindmap",Dy=t=>/^\s*mindmap/.test(t),Ny=async()=>{const{diagram:t}=await X(()=>import("./mindmap-definition-f354de21-iPbIx-mR.js"),__vite__mapDeps([39,11,2]));return{id:Il,diagram:t}},Ry={id:Il,detector:Dy,loader:Ny},Py=Ry,$l="sankey",qy=t=>/^\s*sankey-beta/.test(t),zy=async()=>{const{diagram:t}=await X(()=>import("./sankeyDiagram-97764748-A3D0wPEg.js"),__vite__mapDeps([40,25,21,41,2]));return{id:$l,diagram:t}},Wy={id:$l,detector:qy,loader:zy},Hy=Wy,Dl="block",jy=t=>/^\s*block-beta/.test(t),Uy=async()=>{const{diagram:t}=await X(()=>import("./blockDiagram-91b80b7a-W38ApPQ6.js"),__vite__mapDeps([42,9,5,10,11,12,13,14,25,21,15,41,2]));return{id:Dl,diagram:t}},Yy={id:Dl,detector:jy,loader:Uy},Vy=Yy;let ks=!1;const Kn=()=>{ks||(ks=!0,sr("error",By,t=>t.toLowerCase().trim()==="error"),sr("---",{db:{clear:()=>{}},styles:{},renderer:{draw:()=>{}},parser:{parser:{yy:{}},parse:()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")}},init:()=>null},t=>t.toLowerCase().trimStart().startsWith("---")),il(G0,j_,q_,s_,p_,__,x_,O_,D_,Ey,i_,J0,Py,$y,c_,J_,G_,iy,k_,Hy,A_,Vy))};class Nl{constructor(e,i={}){this.text=e,this.metadata=i,this.type="graph",this.text=N0(e),this.text+=` +`);const r=vy(e),n=r.append("g");r.attr("viewBox","0 0 2412 512"),Fl(r,100,512,!0),n.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),n.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),n.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),n.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),n.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),n.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),n.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),n.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${i}`)},El={draw:ky},Sy=El,wy={db:{},renderer:El,parser:{parser:{yy:{}},parse:()=>{}}},By=wy,Ol="flowchart-elk",Ay=(t,e)=>{var i;return!!(/^\s*flowchart-elk/.test(t)||/^\s*flowchart|graph/.test(t)&&((i=e==null?void 0:e.flowchart)==null?void 0:i.defaultRenderer)==="elk")},Ly=async()=>{const{diagram:t}=await X(()=>import("./flowchart-elk-definition-5fe447d6-pCydUlJz.js"),__vite__mapDeps([37,4,10,11,12,13,14,2]));return{id:Ol,diagram:t}},Fy={id:Ol,detector:Ay,loader:Ly},Ey=Fy,Ml="timeline",Oy=t=>/^\s*timeline/.test(t),My=async()=>{const{diagram:t}=await X(()=>import("./timeline-definition-fea2a41d-Scl62dAd.js"),__vite__mapDeps([38,24,14,2]));return{id:Ml,diagram:t}},Iy={id:Ml,detector:Oy,loader:My},$y=Iy,Il="mindmap",Dy=t=>/^\s*mindmap/.test(t),Ny=async()=>{const{diagram:t}=await X(()=>import("./mindmap-definition-f354de21-llC7ZqOF.js"),__vite__mapDeps([39,11,2]));return{id:Il,diagram:t}},Ry={id:Il,detector:Dy,loader:Ny},Py=Ry,$l="sankey",qy=t=>/^\s*sankey-beta/.test(t),zy=async()=>{const{diagram:t}=await X(()=>import("./sankeyDiagram-97764748-XP-AU6IQ.js"),__vite__mapDeps([40,25,21,41,2]));return{id:$l,diagram:t}},Wy={id:$l,detector:qy,loader:zy},Hy=Wy,Dl="block",jy=t=>/^\s*block-beta/.test(t),Uy=async()=>{const{diagram:t}=await X(()=>import("./blockDiagram-91b80b7a-6EYGTs6T.js"),__vite__mapDeps([42,9,5,10,11,12,13,14,25,21,15,41,2]));return{id:Dl,diagram:t}},Yy={id:Dl,detector:jy,loader:Uy},Vy=Yy;let ks=!1;const Kn=()=>{ks||(ks=!0,sr("error",By,t=>t.toLowerCase().trim()==="error"),sr("---",{db:{clear:()=>{}},styles:{},renderer:{draw:()=>{}},parser:{parser:{yy:{}},parse:()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")}},init:()=>null},t=>t.toLowerCase().trimStart().startsWith("---")),il(G0,j_,q_,s_,p_,__,x_,O_,D_,Ey,i_,J0,Py,$y,c_,J_,G_,iy,k_,Hy,A_,Vy))};class Nl{constructor(e,i={}){this.text=e,this.metadata=i,this.type="graph",this.text=N0(e),this.text+=` `;const r=It();try{this.type=wr(e,r)}catch(o){this.type="error",this.detectError=o}const n=Xn(this.type);E.debug("Type "+this.type),this.db=n.db,this.renderer=n.renderer,this.parser=n.parser,this.parser.parser.yy=this.db,this.init=n.init,this.parse()}parse(){var e,i,r,n,o;if(this.detectError)throw this.detectError;(i=(e=this.db).clear)==null||i.call(e);const s=It();(r=this.init)==null||r.call(this,s),this.metadata.title&&((o=(n=this.db).setDiagramTitle)==null||o.call(n,this.metadata.title)),this.parser.parse(this.text)}async render(e,i){await this.renderer.draw(this.text,e,i,this)}getParser(){return this.parser}getType(){return this.type}}const Gy=async(t,e={})=>{const i=wr(t,It());try{Xn(i)}catch{const n=u0(i);if(!n)throw new el(`Diagram ${i} not found.`);const{id:o,diagram:s}=await n();sr(o,s)}return new Nl(t,e)};let Ss=[];const Xy=()=>{Ss.forEach(t=>{t()}),Ss=[]},Ky="graphics-document document";function Zy(t,e){t.attr("role",Ky),e!==""&&t.attr("aria-roledescription",e)}function Jy(t,e,i,r){if(t.insert!==void 0){if(i){const n=`chart-desc-${r}`;t.attr("aria-describedby",n),t.insert("desc",":first-child").attr("id",n).text(i)}if(e){const n=`chart-title-${r}`;t.attr("aria-labelledby",n),t.insert("title",":first-child").attr("id",n).text(e)}}}const Qy=t=>t.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart();/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */function Rl(t){return typeof t>"u"||t===null}function tC(t){return typeof t=="object"&&t!==null}function eC(t){return Array.isArray(t)?t:Rl(t)?[]:[t]}function iC(t,e){var i,r,n,o;if(e)for(o=Object.keys(e),i=0,r=o.length;ia&&(o=" ... ",e=r-a+o.length),i-r>a&&(s=" ...",i=r+a-s.length),{str:o+t.slice(e,i).replace(/\t/g,"→")+s,pos:r-e+o.length}}function Gr(t,e){return ht.repeat(" ",e-t.length)+t}function uC(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),typeof e.indent!="number"&&(e.indent=1),typeof e.linesBefore!="number"&&(e.linesBefore=3),typeof e.linesAfter!="number"&&(e.linesAfter=2);for(var i=/\r?\n|\r|\0/g,r=[0],n=[],o,s=-1;o=i.exec(t.buffer);)n.push(o.index),r.push(o.index+o[0].length),t.position<=o.index&&s<0&&(s=r.length-2);s<0&&(s=r.length-1);var a="",l,h,u=Math.min(t.line+e.linesAfter,n.length).toString().length,f=e.maxLength-(e.indent+u+3);for(l=1;l<=e.linesBefore&&!(s-l<0);l++)h=Vr(t.buffer,r[s-l],n[s-l],t.position-(r[s]-r[s-l]),f),a=ht.repeat(" ",e.indent)+Gr((t.line-l+1).toString(),u)+" | "+h.str+` @@ -90,7 +90,7 @@ ${t.themeCSS}`),t.fontFamily!==void 0&&(r+=` */window.addEventListener("load",eh,!1)}const Tb=function(t){At.parseError=t},cr=[];let Kr=!1;const ih=async()=>{if(!Kr){for(Kr=!0;cr.length>0;){const t=cr.shift();if(t)try{await t()}catch(e){E.error("Error executing queue",e)}}Kr=!1}},vb=async(t,e)=>new Promise((i,r)=>{const n=()=>new Promise((o,s)=>{_e.parse(t,e).then(a=>{o(a),i(a)},a=>{var l;E.error("Error parsing",a),(l=At.parseError)==null||l.call(At,a),s(a),r(a)})});cr.push(n),ih().catch(r)}),rh=(t,e,i)=>new Promise((r,n)=>{const o=()=>new Promise((s,a)=>{_e.render(t,e,i).then(l=>{s(l),r(l)},l=>{var h;E.error("Error parsing",l),(h=At.parseError)==null||h.call(At,l),a(l),n(l)})});cr.push(o),ih().catch(n)}),At={startOnLoad:!0,mermaidAPI:_e,parse:vb,render:rh,init:xb,run:Ql,registerExternalDiagrams:bb,initialize:th,parseError:void 0,contentLoaded:eh,setParseErrorHandler:Tb,detectType:wr},jb=Object.freeze(Object.defineProperty({__proto__:null,default:At},Symbol.toStringTag,{value:"Module"}));export{is as $,hy as A,xi as B,Pe as C,er as D,br as E,qg as F,wm as G,Ci as H,tr as I,Ig as J,qa as K,Ma as L,Ip as M,$p as N,Mm as O,as as P,Ag as Q,ye as R,Ji as S,Dp as T,$n as U,Mp as V,qp as W,qe as X,Mg as Y,oe as Z,_r as _,dy as a,i0 as a$,Dn as a0,$a as a1,Pa as a2,Wa as a3,Ep as a4,pn as a5,rm as a6,Yp as a7,Xg as a8,Mn as a9,ta as aA,Sb as aB,ph as aC,gh as aD,_h as aE,vn as aF,ee as aG,li as aH,Oo as aI,gu as aJ,vy as aK,Mb as aL,l0 as aM,al as aN,Hn as aO,Bn as aP,Ab as aQ,Eb as aR,Po as aS,Ro as aT,Ob as aU,Fb as aV,wb as aW,Bb as aX,$b as aY,Ib as aZ,Lb as a_,Yr as aa,yt as ab,Ks as ac,Sh as ad,ig as ae,ei as af,im as ag,Gg as ah,Dt as ai,nm as aj,In as ak,sm as al,I as am,Mt as an,R0 as ao,Df as ap,dh as aq,Wb as ar,Db as as,xy as at,A0 as au,Tn as av,Zs as aw,gt as ax,_i as ay,lu as az,fy as b,It as b0,Cs as b1,Nb as b2,f0 as b3,w0 as b4,my as b5,yi as b6,L as b7,O as b8,jb as b9,Gn as c,pi as d,at as e,rr as f,uy as g,xt as h,Fl as i,qn as j,M0 as k,E as l,Ns as m,bi as n,Mf as o,S0 as p,Za as q,Km as r,cy as s,y0 as t,oy as u,Hb as v,E0 as w,py as x,gy as y,ni as z}; function __vite__mapDeps(indexes) { if (!__vite__mapDeps.viteFileDeps) { - __vite__mapDeps.viteFileDeps = ["assets/c4Diagram-b2a90758-61jLNFqu.js","assets/svgDrawCommon-5ccd53ef-iJa2TVTb.js","assets/app-PDrbPfzp.js","assets/flowDiagram-5540d9b9-XEePSu7I.js","assets/flowDb-4b19a42f-sAhi6J2v.js","assets/graph-cZfODKa1.js","assets/layout-konkdG3Z.js","assets/styles-3ed67cfa-FBozeukd.js","assets/index-fc10efb0-knA-ZLJ0.js","assets/clone-jETecP85.js","assets/edges-d32062c0-iT1MEq_Y.js","assets/createText-6b48ae7d-9AoX5zU9.js","assets/line-_nnM_7ZX.js","assets/array-Nw74a44z.js","assets/path-aUcfwwLI.js","assets/channel-GQnHP4O7.js","assets/flowDiagram-v2-3b53844e-VJ0ZCiud.js","assets/erDiagram-47591fe2-CbfSLOL9.js","assets/gitGraphDiagram-96e6b4ee-Sl4MCJL1.js","assets/ganttDiagram-9a3bba1f-Mk83ufVS.js","assets/linear-yB98X29G.js","assets/init-Hi12RPRh.js","assets/infoDiagram-bcd20f53-aQsUByZm.js","assets/pieDiagram-79897490-axGt9ShQ.js","assets/arc-XT00965o.js","assets/ordinal-wXG5obU4.js","assets/quadrantDiagram-62f64e94-DSAXizG6.js","assets/xychartDiagram-ab372869-NbNQWlrD.js","assets/requirementDiagram-05bf5f74--Z92gB8m.js","assets/sequenceDiagram-acc0e65c-TzfkGb4D.js","assets/classDiagram-30eddba6-OAikPNdt.js","assets/styles-991ebdfc-vHdkyrCb.js","assets/classDiagram-v2-f2df5561-yJMOQ1KK.js","assets/stateDiagram-0ff1cf1a-sl2QinQH.js","assets/styles-d20c7d72-JW20WKkm.js","assets/stateDiagram-v2-9a9d610d-sZSBWe92.js","assets/journeyDiagram-4fe6b3dc-5Up4aSjD.js","assets/flowchart-elk-definition-5fe447d6-2wwBOAT6.js","assets/timeline-definition-fea2a41d-4QeTlQgD.js","assets/mindmap-definition-f354de21-iPbIx-mR.js","assets/sankeyDiagram-97764748-A3D0wPEg.js","assets/Tableau10-Fgclqpgn.js","assets/blockDiagram-91b80b7a-W38ApPQ6.js"] + __vite__mapDeps.viteFileDeps = ["assets/c4Diagram-b2a90758-Ozn2CEAW.js","assets/svgDrawCommon-5ccd53ef-wBNBFr7n.js","assets/app-UOvWaKji.js","assets/flowDiagram-5540d9b9-mp-41puG.js","assets/flowDb-4b19a42f-e0bq62ON.js","assets/graph-yVkSecXb.js","assets/layout-2f_iGf4E.js","assets/styles-3ed67cfa-xu8Odik1.js","assets/index-fc10efb0-cfY4JypU.js","assets/clone-bRwIupqN.js","assets/edges-d32062c0-DdP-jtfh.js","assets/createText-6b48ae7d-yUX1YD6G.js","assets/line-3Gyevr9q.js","assets/array-Nw74a44z.js","assets/path-aUcfwwLI.js","assets/channel-hMLbS6Zi.js","assets/flowDiagram-v2-3b53844e-Cs1ZpX_T.js","assets/erDiagram-47591fe2-RWR6JLP0.js","assets/gitGraphDiagram-96e6b4ee-kyRwI9Lw.js","assets/ganttDiagram-9a3bba1f-KGvD9HhD.js","assets/linear-eA8J8eJ4.js","assets/init-Hi12RPRh.js","assets/infoDiagram-bcd20f53-qNUwp2oi.js","assets/pieDiagram-79897490-xf0NxzxJ.js","assets/arc-5GdQY_kf.js","assets/ordinal-wXG5obU4.js","assets/quadrantDiagram-62f64e94-cAAwIO1z.js","assets/xychartDiagram-ab372869-zbSuzsOs.js","assets/requirementDiagram-05bf5f74-HkrjUmOA.js","assets/sequenceDiagram-acc0e65c-So47ZKCj.js","assets/classDiagram-30eddba6-LzAW2Y3L.js","assets/styles-991ebdfc-6jesWoI2.js","assets/classDiagram-v2-f2df5561-L_-CRfCF.js","assets/stateDiagram-0ff1cf1a-Rh0IBuDT.js","assets/styles-d20c7d72-fXd0DLOZ.js","assets/stateDiagram-v2-9a9d610d-Gp1zKQgn.js","assets/journeyDiagram-4fe6b3dc-v7Caieti.js","assets/flowchart-elk-definition-5fe447d6-pCydUlJz.js","assets/timeline-definition-fea2a41d-Scl62dAd.js","assets/mindmap-definition-f354de21-llC7ZqOF.js","assets/sankeyDiagram-97764748-XP-AU6IQ.js","assets/Tableau10-Fgclqpgn.js","assets/blockDiagram-91b80b7a-6EYGTs6T.js"] } return indexes.map((i) => __vite__mapDeps.viteFileDeps[i]) } diff --git a/assets/metrics.html-M_EKpCet.js b/assets/metrics.html-ebI0OPa_.js similarity index 99% rename from assets/metrics.html-M_EKpCet.js rename to assets/metrics.html-ebI0OPa_.js index 2fad29bc00..754cf79671 100644 --- a/assets/metrics.html-M_EKpCet.js +++ b/assets/metrics.html-ebI0OPa_.js @@ -1,4 +1,4 @@ -import{_ as p,r as o,o as i,c as l,a as s,b as n,d as t,e as a}from"./app-PDrbPfzp.js";const u={},r=a(`

                        Metrics

                        更直接(希望更好)的统计导出方式。

                        相关配置

                        可以在 inbounds 配置中增加一个 metrics 的 inbound

                            "inbounds": [
                        +import{_ as p,r as o,o as i,c as l,a as s,b as n,d as t,e as a}from"./app-UOvWaKji.js";const u={},r=a(`

                        Metrics

                        更直接(希望更好)的统计导出方式。

                        相关配置

                        可以在 inbounds 配置中增加一个 metrics 的 inbound

                            "inbounds": [
                                 {
                                     "listen": "127.0.0.1",
                                     "port": 11111,
                        diff --git a/assets/metrics.html-O2MdDQGJ.js b/assets/metrics.html-mI5FrxlZ.js
                        similarity index 99%
                        rename from assets/metrics.html-O2MdDQGJ.js
                        rename to assets/metrics.html-mI5FrxlZ.js
                        index 3cee12901d..19e843d4df 100644
                        --- a/assets/metrics.html-O2MdDQGJ.js
                        +++ b/assets/metrics.html-mI5FrxlZ.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as o,o as i,c as l,a as s,b as n,d as t,e as a}from"./app-PDrbPfzp.js";const u={},r=a(`

                        Metrics

                        A more straightforward (and hopefully better) way to export metrics.

                        It's possible to add a metrics inbound among inbounds.

                            "inbounds": [
                        +import{_ as p,r as o,o as i,c as l,a as s,b as n,d as t,e as a}from"./app-UOvWaKji.js";const u={},r=a(`

                        Metrics

                        A more straightforward (and hopefully better) way to export metrics.

                        It's possible to add a metrics inbound among inbounds.

                            "inbounds": [
                                 {
                                     "listen": "127.0.0.1",
                                     "port": 11111,
                        diff --git a/assets/mindmap-definition-f354de21-iPbIx-mR.js b/assets/mindmap-definition-f354de21-llC7ZqOF.js
                        similarity index 99%
                        rename from assets/mindmap-definition-f354de21-iPbIx-mR.js
                        rename to assets/mindmap-definition-f354de21-llC7ZqOF.js
                        index c1d1dc710c..d44a02beb6 100644
                        --- a/assets/mindmap-definition-f354de21-iPbIx-mR.js
                        +++ b/assets/mindmap-definition-f354de21-llC7ZqOF.js
                        @@ -1,4 +1,4 @@
                        -import{aC as Vt,aD as Ys,l as ur,c as Qn,aK as _l,u as Ul,aM as _a,d as Ua,h as Hl,b6 as Yl,b7 as Xl,b8 as Wl,aO as ql}from"./mermaid.core-95b3ca__.js";import{c as Kl}from"./createText-6b48ae7d-9AoX5zU9.js";import"./app-PDrbPfzp.js";function Zl(t){var e=typeof t;return t!=null&&(e=="object"||e=="function")}var la=Zl,Ql=typeof Vt=="object"&&Vt&&Vt.Object===Object&&Vt,Jl=Ql,jl=Jl,eu=typeof self=="object"&&self&&self.Object===Object&&self,tu=jl||eu||Function("return this")(),tn=tu,ru=tn,au=function(){return ru.Date.now()},nu=au,iu=/\s/;function su(t){for(var e=t.length;e--&&iu.test(t.charAt(e)););return e}var ou=su,lu=ou,uu=/^\s+/;function fu(t){return t&&t.slice(0,lu(t)+1).replace(uu,"")}var hu=fu,vu=tn,cu=vu.Symbol,Jn=cu,Li=Jn,Xs=Object.prototype,du=Xs.hasOwnProperty,gu=Xs.toString,Vr=Li?Li.toStringTag:void 0;function pu(t){var e=du.call(t,Vr),r=t[Vr];try{t[Vr]=void 0;var a=!0}catch{}var n=gu.call(t);return a&&(e?t[Vr]=r:delete t[Vr]),n}var yu=pu,mu=Object.prototype,bu=mu.toString;function Eu(t){return bu.call(t)}var wu=Eu,Ai=Jn,xu=yu,Tu=wu,Cu="[object Null]",Du="[object Undefined]",Oi=Ai?Ai.toStringTag:void 0;function Su(t){return t==null?t===void 0?Du:Cu:Oi&&Oi in Object(t)?xu(t):Tu(t)}var Ws=Su;function Lu(t){return t!=null&&typeof t=="object"}var Au=Lu,Ou=Ws,Nu=Au,Iu="[object Symbol]";function Mu(t){return typeof t=="symbol"||Nu(t)&&Ou(t)==Iu}var ua=Mu,Ru=hu,Ni=la,ku=ua,Ii=NaN,Pu=/^[-+]0x[0-9a-f]+$/i,Bu=/^0b[01]+$/i,Fu=/^0o[0-7]+$/i,Gu=parseInt;function zu(t){if(typeof t=="number")return t;if(ku(t))return Ii;if(Ni(t)){var e=typeof t.valueOf=="function"?t.valueOf():t;t=Ni(e)?e+"":e}if(typeof t!="string")return t===0?t:+t;t=Ru(t);var r=Bu.test(t);return r||Fu.test(t)?Gu(t.slice(2),r?2:8):Pu.test(t)?Ii:+t}var $u=zu,Vu=la,Tn=nu,Mi=$u,_u="Expected a function",Uu=Math.max,Hu=Math.min;function Yu(t,e,r){var a,n,i,s,o,l,u=0,f=!1,h=!1,c=!0;if(typeof t!="function")throw new TypeError(_u);e=Mi(e)||0,Vu(r)&&(f=!!r.leading,h="maxWait"in r,i=h?Uu(Mi(r.maxWait)||0,e):i,c="trailing"in r?!!r.trailing:c);function v(S){var b=a,x=n;return a=n=void 0,u=S,s=t.apply(x,b),s}function d(S){return u=S,o=setTimeout(y,e),f?v(S):s}function g(S){var b=S-l,x=S-u,w=e-b;return h?Hu(w,i-x):w}function p(S){var b=S-l,x=S-u;return l===void 0||b>=e||b<0||h&&x>=i}function y(){var S=Tn();if(p(S))return E(S);o=setTimeout(y,g(S))}function E(S){return o=void 0,c&&a?v(S):(a=n=void 0,s)}function m(){o!==void 0&&clearTimeout(o),u=0,a=l=n=o=void 0}function T(){return o===void 0?s:E(Tn())}function C(){var S=Tn(),b=p(S);if(a=arguments,n=this,l=S,b){if(o===void 0)return d(l);if(h)return clearTimeout(o),o=setTimeout(y,e),v(l)}return o===void 0&&(o=setTimeout(y,e)),s}return C.cancel=m,C.flush=T,C}var Xu=Yu,qs={exports:{}};(function(t,e){(function(){var r,a,n,i,s,o,l,u,f,h,c,v,d,g,p;n=Math.floor,h=Math.min,a=function(y,E){return yE?1:0},f=function(y,E,m,T,C){var S;if(m==null&&(m=0),C==null&&(C=a),m<0)throw new Error("lo must be non-negative");for(T==null&&(T=y.length);mD;0<=D?w++:w--)x.push(w);return x}).apply(this).reverse(),b=[],T=0,C=S.length;TA;0<=A?++x:--x)L.push(s(y,m));return L},g=function(y,E,m,T){var C,S,b;for(T==null&&(T=a),C=y[m];m>E;){if(b=m-1>>1,S=y[b],T(C,S)<0){y[m]=S,m=b;continue}break}return y[m]=C},p=function(y,E,m){var T,C,S,b,x;for(m==null&&(m=a),C=y.length,x=E,S=y[E],T=2*E+1;T-1}var Sh=Dh,Lh=nn;function Ah(t,e){var r=this.__data__,a=Lh(r,t);return a<0?(++this.size,r.push([t,e])):r[a][1]=e,this}var Oh=Ah,Nh=vh,Ih=Eh,Mh=Th,Rh=Sh,kh=Oh;function Nr(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e-1&&t%1==0&&tt.length)&&(e=t.length);for(var r=0,a=new Array(e);r=e||b<0||h&&x>=i}function y(){var S=Tn();if(p(S))return E(S);o=setTimeout(y,g(S))}function E(S){return o=void 0,c&&a?v(S):(a=n=void 0,s)}function m(){o!==void 0&&clearTimeout(o),u=0,a=l=n=o=void 0}function T(){return o===void 0?s:E(Tn())}function C(){var S=Tn(),b=p(S);if(a=arguments,n=this,l=S,b){if(o===void 0)return d(l);if(h)return clearTimeout(o),o=setTimeout(y,e),v(l)}return o===void 0&&(o=setTimeout(y,e)),s}return C.cancel=m,C.flush=T,C}var Xu=Yu,qs={exports:{}};(function(t,e){(function(){var r,a,n,i,s,o,l,u,f,h,c,v,d,g,p;n=Math.floor,h=Math.min,a=function(y,E){return yE?1:0},f=function(y,E,m,T,C){var S;if(m==null&&(m=0),C==null&&(C=a),m<0)throw new Error("lo must be non-negative");for(T==null&&(T=y.length);mD;0<=D?w++:w--)x.push(w);return x}).apply(this).reverse(),b=[],T=0,C=S.length;TA;0<=A?++x:--x)L.push(s(y,m));return L},g=function(y,E,m,T){var C,S,b;for(T==null&&(T=a),C=y[m];m>E;){if(b=m-1>>1,S=y[b],T(C,S)<0){y[m]=S,m=b;continue}break}return y[m]=C},p=function(y,E,m){var T,C,S,b,x;for(m==null&&(m=a),C=y.length,x=E,S=y[E],T=2*E+1;T-1}var Sh=Dh,Lh=nn;function Ah(t,e){var r=this.__data__,a=Lh(r,t);return a<0?(++this.size,r.push([t,e])):r[a][1]=e,this}var Oh=Ah,Nh=vh,Ih=Eh,Mh=Th,Rh=Sh,kh=Oh;function Nr(t){var e=-1,r=t==null?0:t.length;for(this.clear();++e-1&&t%1==0&&tt.length)&&(e=t.length);for(var r=0,a=new Array(e);r"u"?null:window,Ui=$e?$e.navigator:null;$e&&$e.document;var Gc=Ue(""),ao=Ue({}),zc=Ue(function(){}),$c=typeof HTMLElement>"u"?"undefined":Ue(HTMLElement),va=function(e){return e&&e.instanceString&&Be(e.instanceString)?e.instanceString():null},ve=function(e){return e!=null&&Ue(e)==Gc},Be=function(e){return e!=null&&Ue(e)===zc},Me=function(e){return!ht(e)&&(Array.isArray?Array.isArray(e):e!=null&&e instanceof Array)},De=function(e){return e!=null&&Ue(e)===ao&&!Me(e)&&e.constructor===Object},Vc=function(e){return e!=null&&Ue(e)===ao},ae=function(e){return e!=null&&Ue(e)===Ue(1)&&!isNaN(e)},_c=function(e){return ae(e)&&Math.floor(e)===e},Ha=function(e){if($c!=="undefined")return e!=null&&e instanceof HTMLElement},ht=function(e){return ca(e)||no(e)},ca=function(e){return va(e)==="collection"&&e._private.single},no=function(e){return va(e)==="collection"&&!e._private.single},ni=function(e){return va(e)==="core"},io=function(e){return va(e)==="stylesheet"},Uc=function(e){return va(e)==="event"},Yt=function(e){return e==null?!0:!!(e===""||e.match(/^\s+$/))},Hc=function(e){return typeof HTMLElement>"u"?!1:e instanceof HTMLElement},Yc=function(e){return De(e)&&ae(e.x1)&&ae(e.x2)&&ae(e.y1)&&ae(e.y2)},Xc=function(e){return Vc(e)&&Be(e.then)},Wc=function(){return Ui&&Ui.userAgent.match(/msie|trident|edge/i)},Jr=function(e,r){r||(r=function(){if(arguments.length===1)return arguments[0];if(arguments.length===0)return"undefined";for(var i=[],s=0;sr?1:0},ed=function(e,r){return-1*oo(e,r)},de=Object.assign!=null?Object.assign.bind(Object):function(t){for(var e=arguments,r=1;r1&&(p-=1),p<1/6?d+(g-d)*6*p:p<1/2?g:p<2/3?d+(g-d)*(2/3-p)*6:d}var h=new RegExp("^"+Zc+"$").exec(e);if(h){if(a=parseInt(h[1]),a<0?a=(360- -1*a%360)%360:a>360&&(a=a%360),a/=360,n=parseFloat(h[2]),n<0||n>100||(n=n/100,i=parseFloat(h[3]),i<0||i>100)||(i=i/100,s=h[4],s!==void 0&&(s=parseFloat(s),s<0||s>1)))return;if(n===0)o=l=u=Math.round(i*255);else{var c=i<.5?i*(1+n):i+n-i*n,v=2*i-c;o=Math.round(255*f(v,c,a+1/3)),l=Math.round(255*f(v,c,a)),u=Math.round(255*f(v,c,a-1/3))}r=[o,l,u,s]}return r},ad=function(e){var r,a=new RegExp("^"+qc+"$").exec(e);if(a){r=[];for(var n=[],i=1;i<=3;i++){var s=a[i];if(s[s.length-1]==="%"&&(n[i]=!0),s=parseFloat(s),n[i]&&(s=s/100*255),s<0||s>255)return;r.push(Math.floor(s))}var o=n[1]||n[2]||n[3],l=n[1]&&n[2]&&n[3];if(o&&!l)return;var u=a[4];if(u!==void 0){if(u=parseFloat(u),u<0||u>1)return;r.push(u)}}return r},nd=function(e){return sd[e.toLowerCase()]},id=function(e){return(Me(e)?e:null)||nd(e)||td(e)||ad(e)||rd(e)},sd={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},lo=function(e){for(var r=e.map,a=e.keys,n=a.length,i=0;i1&&arguments[1]!==void 0?arguments[1]:br,a=r,n;n=e.next(),!n.done;)a=a*ho+n.value|0;return a},jr=function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:br;return r*ho+e|0},ea=function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Xr;return(r<<5)+r+e|0},ld=function(e,r){return e*2097152+r},Gt=function(e){return e[0]*2097152+e[1]},Ta=function(e,r){return[jr(e[0],r[0]),ea(e[1],r[1])]},ud=function(e,r){var a={value:0,done:!1},n=0,i=e.length,s={next:function(){return n=0&&!(e[n]===r&&(e.splice(n,1),a));n--);},li=function(e){e.splice(0,e.length)},pd=function(e,r){for(var a=0;a"u"?"undefined":Ue(Set))!==md?Set:bd,un=function(e,r){var a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:!0;if(e===void 0||r===void 0||!ni(e)){Ge("An element must have a core reference and parameters set");return}var n=r.group;if(n==null&&(r.data&&r.data.source!=null&&r.data.target!=null?n="edges":n="nodes"),n!=="nodes"&&n!=="edges"){Ge("An element must be of type `nodes` or `edges`; you specified `"+n+"`");return}this.length=1,this[0]=this;var i=this._private={cy:e,single:!0,data:r.data||{},position:r.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:n,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!r.selected,selectable:r.selectable===void 0?!0:!!r.selectable,locked:!!r.locked,grabbed:!1,grabbable:r.grabbable===void 0?!0:!!r.grabbable,pannable:r.pannable===void 0?n==="edges":!!r.pannable,active:!1,classes:new Mr,animation:{current:[],queue:[]},rscratch:{},scratch:r.scratch||{},edges:[],children:[],parent:r.parent&&r.parent.isNode()?r.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(i.position.x==null&&(i.position.x=0),i.position.y==null&&(i.position.y=0),r.renderedPosition){var s=r.renderedPosition,o=e.pan(),l=e.zoom();i.position={x:(s.x-o.x)/l,y:(s.y-o.y)/l}}var u=[];Me(r.classes)?u=r.classes:ve(r.classes)&&(u=r.classes.split(/\s+/));for(var f=0,h=u.length;f0;){var S=E.pop(),b=p(S),x=S.id();if(c[x]=b,b!==1/0)for(var w=S.neighborhood().intersect(d),D=0;D0)for(k.unshift(M);h[G];){var F=h[G];k.unshift(F.edge),k.unshift(F.node),B=F.node,G=B.id()}return o.spawn(k)}}}},xd={kruskal:function(e){e=e||function(m){return 1};for(var r=this.byGroup(),a=r.nodes,n=r.edges,i=a.length,s=new Array(i),o=a,l=function(T){for(var C=0;C0;){if(C(),b++,T===f){for(var x=[],w=i,D=f,A=y[D];x.unshift(w),A!=null&&x.unshift(A),w=p[D],w!=null;)D=w.id(),A=y[D];return{found:!0,distance:h[T],path:this.spawn(x),steps:b}}v[T]=!0;for(var L=m._private.edges,I=0;IA&&(d[D]=A,E[D]=w,m[D]=C),!i){var L=w*f+x;!i&&d[L]>A&&(d[L]=A,E[L]=x,m[L]=C)}}}for(var I=0;I1&&arguments[1]!==void 0?arguments[1]:s,xe=m(se),Ee=[],ge=xe;;){if(ge==null)return r.spawn();var we=E(ge),H=we.edge,N=we.pred;if(Ee.unshift(ge[0]),ge.same(fe)&&Ee.length>0)break;H!=null&&Ee.unshift(H),ge=N}return l.spawn(Ee)},S=0;S=0;f--){var h=u[f],c=h[1],v=h[2];(r[c]===o&&r[v]===l||r[c]===l&&r[v]===o)&&u.splice(f,1)}for(var d=0;dn;){var i=Math.floor(Math.random()*r.length);r=Nd(i,e,r),a--}return r},Id={kargerStein:function(){var e=this,r=this.byGroup(),a=r.nodes,n=r.edges;n.unmergeBy(function(k){return k.isLoop()});var i=a.length,s=n.length,o=Math.ceil(Math.pow(Math.log(i)/Math.LN2,2)),l=Math.floor(i/Od);if(i<2){Ge("At least 2 nodes are required for Karger-Stein algorithm");return}for(var u=[],f=0;f1&&arguments[1]!==void 0?arguments[1]:0,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,n=1/0,i=r;i1&&arguments[1]!==void 0?arguments[1]:0,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,n=-1/0,i=r;i1&&arguments[1]!==void 0?arguments[1]:0,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,n=0,i=0,s=r;s1&&arguments[1]!==void 0?arguments[1]:0,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,s=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0;n?e=e.slice(r,a):(a0&&e.splice(0,r));for(var o=0,l=e.length-1;l>=0;l--){var u=e[l];s?isFinite(u)||(e[l]=-1/0,o++):e.splice(l,1)}i&&e.sort(function(c,v){return c-v});var f=e.length,h=Math.floor(f/2);return f%2!==0?e[h+1+o]:(e[h-1+o]+e[h+o])/2},Fd=function(e){return Math.PI*e/180},Ca=function(e,r){return Math.atan2(r,e)-Math.PI/2},ui=Math.log2||function(t){return Math.log(t)/Math.log(2)},Eo=function(e){return e>0?1:e<0?-1:0},nr=function(e,r){return Math.sqrt(er(e,r))},er=function(e,r){var a=r.x-e.x,n=r.y-e.y;return a*a+n*n},Gd=function(e){for(var r=e.length,a=0,n=0;n=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(e.w!=null&&e.h!=null&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},$d=function(e){return{x1:e.x1,x2:e.x2,w:e.w,y1:e.y1,y2:e.y2,h:e.h}},Vd=function(e){e.x1=1/0,e.y1=1/0,e.x2=-1/0,e.y2=-1/0,e.w=0,e.h=0},_d=function(e,r,a){return{x1:e.x1+r,x2:e.x2+r,y1:e.y1+a,y2:e.y2+a,w:e.w,h:e.h}},wo=function(e,r){e.x1=Math.min(e.x1,r.x1),e.x2=Math.max(e.x2,r.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,r.y1),e.y2=Math.max(e.y2,r.y2),e.h=e.y2-e.y1},Ud=function(e,r,a){e.x1=Math.min(e.x1,r),e.x2=Math.max(e.x2,r),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,a),e.y2=Math.max(e.y2,a),e.h=e.y2-e.y1},ka=function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;return e.x1-=r,e.x2+=r,e.y1-=r,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},Pa=function(e){var r=arguments.length>1&&arguments[1]!==void 0?arguments[1]:[0],a,n,i,s;if(r.length===1)a=n=i=s=r[0];else if(r.length===2)a=i=r[0],s=n=r[1];else if(r.length===4){var o=Et(r,4);a=o[0],n=o[1],i=o[2],s=o[3]}return e.x1-=s,e.x2+=n,e.y1-=a,e.y2+=i,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},qi=function(e,r){e.x1=r.x1,e.y1=r.y1,e.x2=r.x2,e.y2=r.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},fi=function(e,r){return!(e.x1>r.x2||r.x1>e.x2||e.x2r.y2||r.y1>e.y2)},Sr=function(e,r,a){return e.x1<=r&&r<=e.x2&&e.y1<=a&&a<=e.y2},Hd=function(e,r){return Sr(e,r.x,r.y)},xo=function(e,r){return Sr(e,r.x1,r.y1)&&Sr(e,r.x2,r.y2)},To=function(e,r,a,n,i,s,o){var l=da(i,s),u=i/2,f=s/2,h;{var c=a-u+l-o,v=n-f-o,d=a+u-l+o,g=v;if(h=_t(e,r,a,n,c,v,d,g,!1),h.length>0)return h}{var p=a+u+o,y=n-f+l-o,E=p,m=n+f-l+o;if(h=_t(e,r,a,n,p,y,E,m,!1),h.length>0)return h}{var T=a-u+l-o,C=n+f+o,S=a+u-l+o,b=C;if(h=_t(e,r,a,n,T,C,S,b,!1),h.length>0)return h}{var x=a-u-o,w=n-f+l-o,D=x,A=n+f-l+o;if(h=_t(e,r,a,n,x,w,D,A,!1),h.length>0)return h}var L;{var I=a-u+l,O=n-f+l;if(L=Wr(e,r,a,n,I,O,l+o),L.length>0&&L[0]<=I&&L[1]<=O)return[L[0],L[1]]}{var P=a+u-l,R=n-f+l;if(L=Wr(e,r,a,n,P,R,l+o),L.length>0&&L[0]>=P&&L[1]<=R)return[L[0],L[1]]}{var M=a+u-l,k=n+f-l;if(L=Wr(e,r,a,n,M,k,l+o),L.length>0&&L[0]>=M&&L[1]>=k)return[L[0],L[1]]}{var B=a-u+l,G=n+f-l;if(L=Wr(e,r,a,n,B,G,l+o),L.length>0&&L[0]<=B&&L[1]>=G)return[L[0],L[1]]}return[]},Yd=function(e,r,a,n,i,s,o){var l=o,u=Math.min(a,i),f=Math.max(a,i),h=Math.min(n,s),c=Math.max(n,s);return u-l<=e&&e<=f+l&&h-l<=r&&r<=c+l},Xd=function(e,r,a,n,i,s,o,l,u){var f={x1:Math.min(a,o,i)-u,x2:Math.max(a,o,i)+u,y1:Math.min(n,l,s)-u,y2:Math.max(n,l,s)+u};return!(ef.x2||rf.y2)},Wd=function(e,r,a,n){a-=n;var i=r*r-4*e*a;if(i<0)return[];var s=Math.sqrt(i),o=2*e,l=(-r+s)/o,u=(-r-s)/o;return[l,u]},qd=function(e,r,a,n,i){var s=1e-5;e===0&&(e=s),r/=e,a/=e,n/=e;var o,l,u,f,h,c,v,d;if(l=(3*a-r*r)/9,u=-(27*n)+r*(9*a-2*(r*r)),u/=54,o=l*l*l+u*u,i[1]=0,v=r/3,o>0){h=u+Math.sqrt(o),h=h<0?-Math.pow(-h,1/3):Math.pow(h,1/3),c=u-Math.sqrt(o),c=c<0?-Math.pow(-c,1/3):Math.pow(c,1/3),i[0]=-v+h+c,v+=(h+c)/2,i[4]=i[2]=-v,v=Math.sqrt(3)*(-c+h)/2,i[3]=v,i[5]=-v;return}if(i[5]=i[3]=0,o===0){d=u<0?-Math.pow(-u,1/3):Math.pow(u,1/3),i[0]=-v+2*d,i[4]=i[2]=-(d+v);return}l=-l,f=l*l*l,f=Math.acos(u/Math.sqrt(f)),d=2*Math.sqrt(l),i[0]=-v+d*Math.cos(f/3),i[2]=-v+d*Math.cos((f+2*Math.PI)/3),i[4]=-v+d*Math.cos((f+4*Math.PI)/3)},Kd=function(e,r,a,n,i,s,o,l){var u=1*a*a-4*a*i+2*a*o+4*i*i-4*i*o+o*o+n*n-4*n*s+2*n*l+4*s*s-4*s*l+l*l,f=1*9*a*i-3*a*a-3*a*o-6*i*i+3*i*o+9*n*s-3*n*n-3*n*l-6*s*s+3*s*l,h=1*3*a*a-6*a*i+a*o-a*e+2*i*i+2*i*e-o*e+3*n*n-6*n*s+n*l-n*r+2*s*s+2*s*r-l*r,c=1*a*i-a*a+a*e-i*e+n*s-n*n+n*r-s*r,v=[];qd(u,f,h,c,v);for(var d=1e-7,g=[],p=0;p<6;p+=2)Math.abs(v[p+1])=0&&v[p]<=1&&g.push(v[p]);g.push(1),g.push(0);for(var y=-1,E,m,T,C=0;C=0?Tu?(e-i)*(e-i)+(r-s)*(r-s):f-c},ut=function(e,r,a){for(var n,i,s,o,l,u=0,f=0;f=e&&e>=s||n<=e&&e<=s)l=(e-n)/(s-n)*(o-i)+i,l>r&&u++;else continue;return u%2!==0},Rt=function(e,r,a,n,i,s,o,l,u){var f=new Array(a.length),h;l[0]!=null?(h=Math.atan(l[1]/l[0]),l[0]<0?h=h+Math.PI/2:h=-h-Math.PI/2):h=l;for(var c=Math.cos(-h),v=Math.sin(-h),d=0;d0){var p=qa(f,-u);g=Wa(p)}else g=f;return ut(e,r,g)},Qd=function(e,r,a,n,i,s,o){for(var l=new Array(a.length),u=s/2,f=o/2,h=hi(s,o),c=h*h,v=0;v=0&&p<=1&&E.push(p),y>=0&&y<=1&&E.push(y),E.length===0)return[];var m=E[0]*l[0]+e,T=E[0]*l[1]+r;if(E.length>1){if(E[0]==E[1])return[m,T];var C=E[1]*l[0]+e,S=E[1]*l[1]+r;return[m,T,C,S]}else return[m,T]},Ln=function(e,r,a){return r<=e&&e<=a||a<=e&&e<=r?e:e<=r&&r<=a||a<=r&&r<=e?r:a},_t=function(e,r,a,n,i,s,o,l,u){var f=e-i,h=a-e,c=o-i,v=r-s,d=n-r,g=l-s,p=c*v-g*f,y=h*v-d*f,E=g*h-c*d;if(E!==0){var m=p/E,T=y/E,C=.001,S=0-C,b=1+C;return S<=m&&m<=b&&S<=T&&T<=b?[e+m*h,r+m*d]:u?[e+m*h,r+m*d]:[]}else return p===0||y===0?Ln(e,a,o)===o?[o,l]:Ln(e,a,i)===i?[i,s]:Ln(i,o,a)===a?[a,n]:[]:[]},aa=function(e,r,a,n,i,s,o,l){var u=[],f,h=new Array(a.length),c=!0;s==null&&(c=!1);var v;if(c){for(var d=0;d0){var g=qa(h,-l);v=Wa(g)}else v=h}else v=a;for(var p,y,E,m,T=0;T2){for(var R=[u[0],u[1]],M=Math.pow(R[0]-e,2)+Math.pow(R[1]-r,2),k=1;kf&&(f=T)},get:function(m){return u[m]}},c=0;c0?R=P.edgesTo(O)[0]:R=O.edgesTo(P)[0];var M=n(R);O=O.id(),x[O]>x[L]+M&&(x[O]=x[L]+M,w.nodes.indexOf(O)<0?w.push(O):w.updateItem(O),b[O]=0,S[O]=[]),x[O]==x[L]+M&&(b[O]=b[O]+b[L],S[O].push(L))}else for(var k=0;k0;){for(var $=C.pop(),U=0;U0&&o.push(a[l]);o.length!==0&&i.push(n.collection(o))}return i},cg=function(e,r){for(var a=0;a5&&arguments[5]!==void 0?arguments[5]:pg,o=n,l,u,f=0;f=2?_r(e,r,a,0,ji,yg):_r(e,r,a,0,Ji)},squaredEuclidean:function(e,r,a){return _r(e,r,a,0,ji)},manhattan:function(e,r,a){return _r(e,r,a,0,Ji)},max:function(e,r,a){return _r(e,r,a,-1/0,mg)}};Lr["squared-euclidean"]=Lr.squaredEuclidean;Lr.squaredeuclidean=Lr.squaredEuclidean;function hn(t,e,r,a,n,i){var s;return Be(t)?s=t:s=Lr[t]||Lr.euclidean,e===0&&Be(t)?s(n,i):s(e,r,a,n,i)}var bg=Qe({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),vi=function(e){return bg(e)},Ka=function(e,r,a,n,i){var s=i!=="kMedoids",o=s?function(h){return a[h]}:function(h){return n[h](a)},l=function(c){return n[c](r)},u=a,f=r;return hn(e,n.length,o,l,u,f)},An=function(e,r,a){for(var n=a.length,i=new Array(n),s=new Array(n),o=new Array(r),l=null,u=0;ua)return!1}return!0},xg=function(e,r,a){for(var n=0;no&&(o=r[u][f],l=f);i[l].push(e[u])}for(var h=0;h=i.threshold||i.mode==="dendrogram"&&e.length===1)return!1;var d=r[s],g=r[n[s]],p;i.mode==="dendrogram"?p={left:d,right:g,key:d.key}:p={value:d.value.concat(g.value),key:d.key},e[d.index]=p,e.splice(g.index,1),r[d.key]=p;for(var y=0;ya[g.key][E.key]&&(l=a[g.key][E.key])):i.linkage==="max"?(l=a[d.key][E.key],a[d.key][E.key]0&&n.push(i);return n},is=function(e,r,a){for(var n=[],i=0;io&&(s=u,o=r[i*e+u])}s>0&&n.push(s)}for(var f=0;fu&&(l=f,u=h)}a[i]=s[l]}return n=is(e,r,a),n},ss=function(e){for(var r=this.cy(),a=this.nodes(),n=Bg(e),i={},s=0;s=A?(L=A,A=O,I=P):O>L&&(L=O);for(var R=0;R0?1:0;b[w%n.minIterations*o+$]=U,F+=U}if(F>0&&(w>=n.minIterations-1||w==n.maxIterations-1)){for(var _=0,Y=0;Y1||S>1)&&(o=!0),h[m]=[],E.outgoers().forEach(function(x){x.isEdge()&&h[m].push(x.id())})}else c[m]=[void 0,E.target().id()]}):s.forEach(function(E){var m=E.id();if(E.isNode()){var T=E.degree(!0);T%2&&(l?u?o=!0:u=m:l=m),h[m]=[],E.connectedEdges().forEach(function(C){return h[m].push(C.id())})}else c[m]=[E.source().id(),E.target().id()]});var v={found:!1,trail:void 0};if(o)return v;if(u&&l)if(i){if(f&&u!=f)return v;f=u}else{if(f&&u!=f&&l!=f)return v;f||(f=u)}else f||(f=s[0].id());var d=function(m){for(var T=m,C=[m],S,b,x;h[T].length;)S=h[T].shift(),b=c[S][0],x=c[S][1],T!=x?(h[x]=h[x].filter(function(w){return w!=S}),T=x):!i&&T!=b&&(h[b]=h[b].filter(function(w){return w!=S}),T=b),C.unshift(S),C.unshift(T);return C},g=[],p=[];for(p=d(f);p.length!=1;)h[p[0]].length==0?(g.unshift(s.getElementById(p.shift())),g.unshift(s.getElementById(p.shift()))):p=d(p.shift()).concat(p);g.unshift(s.getElementById(p.shift()));for(var y in h)if(h[y].length)return v;return v.found=!0,v.trail=this.spawn(g,!0),v}},La=function(){var e=this,r={},a=0,n=0,i=[],s=[],o={},l=function(c,v){for(var d=s.length-1,g=[],p=e.spawn();s[d].x!=c||s[d].y!=v;)g.push(s.pop().edge),d--;g.push(s.pop().edge),g.forEach(function(y){var E=y.connectedNodes().intersection(e);p.merge(y),E.forEach(function(m){var T=m.id(),C=m.connectedEdges().intersection(e);p.merge(m),r[T].cutVertex?p.merge(C.filter(function(S){return S.isLoop()})):p.merge(C)})}),i.push(p)},u=function h(c,v,d){c===d&&(n+=1),r[v]={id:a,low:a++,cutVertex:!1};var g=e.getElementById(v).connectedEdges().intersection(e);if(g.size()===0)i.push(e.spawn(e.getElementById(v)));else{var p,y,E,m;g.forEach(function(T){p=T.source().id(),y=T.target().id(),E=p===v?y:p,E!==d&&(m=T.id(),o[m]||(o[m]=!0,s.push({x:v,y:E,edge:T})),E in r?r[v].low=Math.min(r[v].low,r[E].id):(h(c,E,v),r[v].low=Math.min(r[v].low,r[E].low),r[v].id<=r[E].low&&(r[v].cutVertex=!0,l(v,E))))})}};e.forEach(function(h){if(h.isNode()){var c=h.id();c in r||(n=0,u(c,c),r[c].cutVertex=n>1)}});var f=Object.keys(r).filter(function(h){return r[h].cutVertex}).map(function(h){return e.getElementById(h)});return{cut:e.spawn(f),components:i}},Hg={hopcroftTarjanBiconnected:La,htbc:La,htb:La,hopcroftTarjanBiconnectedComponents:La},Aa=function(){var e=this,r={},a=0,n=[],i=[],s=e.spawn(e),o=function l(u){i.push(u),r[u]={index:a,low:a++,explored:!1};var f=e.getElementById(u).connectedEdges().intersection(e);if(f.forEach(function(g){var p=g.target().id();p!==u&&(p in r||l(p),r[p].explored||(r[u].low=Math.min(r[u].low,r[p].low)))}),r[u].index===r[u].low){for(var h=e.spawn();;){var c=i.pop();if(h.merge(e.getElementById(c)),r[c].low=r[u].index,r[c].explored=!0,c===u)break}var v=h.edgesWith(h),d=h.merge(v);n.push(d),s=s.difference(d)}};return e.forEach(function(l){if(l.isNode()){var u=l.id();u in r||o(u)}}),{cut:s,components:n}},Yg={tarjanStronglyConnected:Aa,tsc:Aa,tscc:Aa,tarjanStronglyConnectedComponents:Aa},No={};[ta,wd,xd,Cd,Sd,Ad,Id,rg,Tr,Cr,$n,gg,Ag,kg,Vg,Ug,Hg,Yg].forEach(function(t){de(No,t)});/*!
                         Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable
                         Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com)
                        diff --git a/assets/mkcp.html-oWZkTGfJ.js b/assets/mkcp.html-DONGnnA_.js
                        similarity index 99%
                        rename from assets/mkcp.html-oWZkTGfJ.js
                        rename to assets/mkcp.html-DONGnnA_.js
                        index 4a4071aa37..560a154514 100644
                        --- a/assets/mkcp.html-oWZkTGfJ.js
                        +++ b/assets/mkcp.html-DONGnnA_.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as s,o as r,c as p,a as t,b as e,d as n,w as d,e as o}from"./app-PDrbPfzp.js";const l={},u=o('

                        mKCP

                        mKCP uses UDP to emulate TCP connections.

                        mKCP sacrifices bandwidth to reduce latency. To transmit the same content, mKCP generally consumes more data than TCP.

                        Tip

                        Make sure the firewall on the host is configured correctly.

                        KcpObject

                        ',5),h=t("code",null,"KcpObject",-1),m=t("code",null,"kcpSettings",-1),b=o(`
                        {
                        +import{_ as c,r as s,o as r,c as p,a as t,b as e,d as n,w as d,e as o}from"./app-UOvWaKji.js";const l={},u=o('

                        mKCP

                        mKCP uses UDP to emulate TCP connections.

                        mKCP sacrifices bandwidth to reduce latency. To transmit the same content, mKCP generally consumes more data than TCP.

                        Tip

                        Make sure the firewall on the host is configured correctly.

                        KcpObject

                        ',5),h=t("code",null,"KcpObject",-1),m=t("code",null,"kcpSettings",-1),b=o(`
                        {
                           "mtu": 1350,
                           "tti": 20,
                           "uplinkCapacity": 5,
                        diff --git a/assets/mkcp.html-KvSr11eW.js b/assets/mkcp.html-P3j-P5YO.js
                        similarity index 98%
                        rename from assets/mkcp.html-KvSr11eW.js
                        rename to assets/mkcp.html-P3j-P5YO.js
                        index 541e494616..d08331f743 100644
                        --- a/assets/mkcp.html-KvSr11eW.js
                        +++ b/assets/mkcp.html-P3j-P5YO.js
                        @@ -1 +1 @@
                        -import{_ as d,r as n,o as i,c as r,a as t,b as a,d as e,e as h}from"./app-PDrbPfzp.js";const s={},o=t("h1",{id:"mkcp-协议",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#mkcp-协议"},[t("span",null,"mKCP 协议")])],-1),p={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},c=h('

                        版本

                        mKCP 没有版本号,不保证版本之间兼容性。

                        依赖

                        底层协议

                        mKCP 是一个基于 UDP 的协议,所有通讯使用 UDP 传输。

                        函数

                        ',6),b={href:"https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function",target:"_blank",rel:"noopener noreferrer"},u=t("ul",null,[t("li",null,"输入参数为任意长度的字符串;"),t("li",null,"输入出一个 32 位无符号整数;")],-1),_=h('

                        通讯过程

                        1. mKCP 将数据流拆成若干个数据包进行发送。一个数据流有一个唯一标识,用以区分不同的数据流。数据流中的每一个数据包都携带了同样的标识。
                        2. mKCP 没有握手过程,当收到一个数据包时,根据其携带的数据流的标识来判断是否为新的通话,或是正在进行中的通话。
                        3. 每一个数据包中包含若干个片段(Segment),片段分为三类:数据(Data)、确认(ACK)、心跳(Ping)。每个片段需要单独处理。

                        数据格式

                        数据包

                        4 字节2 字节L 字节
                        认证信息 A数据长度 L片段部分

                        其中:

                        • 认证信息 A = fnv(片段部分),big endian;
                        • 片段部分可能包含多个片段;

                        数据片段

                        2 字节1 字节1 字节4 字节4 字节4 字节2 字节Len 字节
                        标识 Conv指令 Cmd选项 Opt时间戳 Ts序列号 Sn未确认序列号 Una长度 Len数据

                        其中:

                        • 标识 Conv: mKCP 数据流的标识
                        • 指令 Cmd: 常量 0x01
                        • 选项 Opt: 可选的值有:
                          • 0x00: 空选项
                          • 0x01: 对方已发出所有数据
                        • 时间戳 Ts: 当前片段从远端发送出来时的时间,big endian
                        • 序列号 Sn: 该数据片段时数据流中的位置,起始片段的序列号为 0,之后每个新片段按顺序加 1
                        • 未确认序列号 Una: 远端主机正在发送的,且尚未收到确认的最小的 Sn

                        确认片段

                        2 字节1 字节1 字节4 字节4 字节4 字节2 字节Len * 4 字节
                        标识 Conv指令 Cmd选项 Opt窗口 Wnd下一接收序列号 Sn时间戳 Ts长度 Len已收到的序列号

                        其中:

                        • 标识 Conv: mKCP 数据流的标识
                        • 指令 Cmd: 常量 0x00
                        • 选项 Opt: 同上
                        • 窗口 Wnd: 远端主机可以接收的最大序列号
                        • 下一接收序列号 Sn: 远端主机未收到的数据片段中的最小序列号
                        • 时间戳 Ts: 远端主机最新收到的数据片段的时间戳,可用于计算延迟
                        • 已收到的序列号: 每个 4 字节,表示此序列号的数据已经确认收到

                        注释:

                        • 远程主机期待收到序列号 [Sn, Wnd) 范围内的数据

                        心跳片段

                        2 字节1 字节1 字节4 字节4 字节4 字节
                        标识 Conv指令 Cmd选项 Opt未确认序列号 Una下一接收序列号 Sn延迟 Rto

                        其中:

                        • 标识 Conv: mKCP 数据流的标识
                        • 指令 Cmd: 可选的值有
                          • 0x02: 远端主机强行终止会话
                          • 0x03: 正常心跳
                        • 选项 Opt: 同上
                        • 未确认序列号 Una: 同数据片段的 Una
                        • 下一接收序列号 Sn: 同确认片段的 Sn
                        • 延迟 Rto: 远端主机自己计算出的延迟
                        ',21);function m(f,C){const l=n("ExternalLinkIcon");return i(),r("div",null,[o,t("p",null,[a("mKCP 是流式传输协议,由 "),t("a",p,[a("KCP 协议"),e(l)]),a(" 修改而来,可以按顺序传输任意的数据流。")]),c,t("ul",null,[t("li",null,[a("fnv: "),t("a",b,[a("FNV-1a"),e(l)]),a(" 哈希函数 "),u])]),_])}const k=d(s,[["render",m],["__file","mkcp.html.vue"]]);export{k as default}; +import{_ as d,r as n,o as i,c as r,a as t,b as a,d as e,e as h}from"./app-UOvWaKji.js";const s={},o=t("h1",{id:"mkcp-协议",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#mkcp-协议"},[t("span",null,"mKCP 协议")])],-1),p={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},c=h('

                        版本

                        mKCP 没有版本号,不保证版本之间兼容性。

                        依赖

                        底层协议

                        mKCP 是一个基于 UDP 的协议,所有通讯使用 UDP 传输。

                        函数

                        ',6),b={href:"https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function",target:"_blank",rel:"noopener noreferrer"},u=t("ul",null,[t("li",null,"输入参数为任意长度的字符串;"),t("li",null,"输入出一个 32 位无符号整数;")],-1),_=h('

                        通讯过程

                        1. mKCP 将数据流拆成若干个数据包进行发送。一个数据流有一个唯一标识,用以区分不同的数据流。数据流中的每一个数据包都携带了同样的标识。
                        2. mKCP 没有握手过程,当收到一个数据包时,根据其携带的数据流的标识来判断是否为新的通话,或是正在进行中的通话。
                        3. 每一个数据包中包含若干个片段(Segment),片段分为三类:数据(Data)、确认(ACK)、心跳(Ping)。每个片段需要单独处理。

                        数据格式

                        数据包

                        4 字节2 字节L 字节
                        认证信息 A数据长度 L片段部分

                        其中:

                        • 认证信息 A = fnv(片段部分),big endian;
                        • 片段部分可能包含多个片段;

                        数据片段

                        2 字节1 字节1 字节4 字节4 字节4 字节2 字节Len 字节
                        标识 Conv指令 Cmd选项 Opt时间戳 Ts序列号 Sn未确认序列号 Una长度 Len数据

                        其中:

                        • 标识 Conv: mKCP 数据流的标识
                        • 指令 Cmd: 常量 0x01
                        • 选项 Opt: 可选的值有:
                          • 0x00: 空选项
                          • 0x01: 对方已发出所有数据
                        • 时间戳 Ts: 当前片段从远端发送出来时的时间,big endian
                        • 序列号 Sn: 该数据片段时数据流中的位置,起始片段的序列号为 0,之后每个新片段按顺序加 1
                        • 未确认序列号 Una: 远端主机正在发送的,且尚未收到确认的最小的 Sn

                        确认片段

                        2 字节1 字节1 字节4 字节4 字节4 字节2 字节Len * 4 字节
                        标识 Conv指令 Cmd选项 Opt窗口 Wnd下一接收序列号 Sn时间戳 Ts长度 Len已收到的序列号

                        其中:

                        • 标识 Conv: mKCP 数据流的标识
                        • 指令 Cmd: 常量 0x00
                        • 选项 Opt: 同上
                        • 窗口 Wnd: 远端主机可以接收的最大序列号
                        • 下一接收序列号 Sn: 远端主机未收到的数据片段中的最小序列号
                        • 时间戳 Ts: 远端主机最新收到的数据片段的时间戳,可用于计算延迟
                        • 已收到的序列号: 每个 4 字节,表示此序列号的数据已经确认收到

                        注释:

                        • 远程主机期待收到序列号 [Sn, Wnd) 范围内的数据

                        心跳片段

                        2 字节1 字节1 字节4 字节4 字节4 字节
                        标识 Conv指令 Cmd选项 Opt未确认序列号 Una下一接收序列号 Sn延迟 Rto

                        其中:

                        • 标识 Conv: mKCP 数据流的标识
                        • 指令 Cmd: 可选的值有
                          • 0x02: 远端主机强行终止会话
                          • 0x03: 正常心跳
                        • 选项 Opt: 同上
                        • 未确认序列号 Una: 同数据片段的 Una
                        • 下一接收序列号 Sn: 同确认片段的 Sn
                        • 延迟 Rto: 远端主机自己计算出的延迟
                        ',21);function m(f,C){const l=n("ExternalLinkIcon");return i(),r("div",null,[o,t("p",null,[a("mKCP 是流式传输协议,由 "),t("a",p,[a("KCP 协议"),e(l)]),a(" 修改而来,可以按顺序传输任意的数据流。")]),c,t("ul",null,[t("li",null,[a("fnv: "),t("a",b,[a("FNV-1a"),e(l)]),a(" 哈希函数 "),u])]),_])}const k=d(s,[["render",m],["__file","mkcp.html.vue"]]);export{k as default}; diff --git a/assets/mkcp.html-z0TX3kIH.js b/assets/mkcp.html-censPzO_.js similarity index 99% rename from assets/mkcp.html-z0TX3kIH.js rename to assets/mkcp.html-censPzO_.js index b6459728ac..e713a24848 100644 --- a/assets/mkcp.html-z0TX3kIH.js +++ b/assets/mkcp.html-censPzO_.js @@ -1,4 +1,4 @@ -import{_ as t,r as p,o as c,c as i,a as e,b as n,d as o,e as s}from"./app-PDrbPfzp.js";const d={},r=s(`

                        mKCP

                        mKCP 使用 UDP 来模拟 TCP 连接。

                        mKCP 牺牲带宽来降低延迟。传输同样的内容,mKCP 一般比 TCP 消耗更多的流量。

                        提示

                        请确定主机上的防火墙配置正确

                        KcpObject

                        KcpObject 对应传输配置的 kcpSettings 项。

                        {
                        +import{_ as t,r as p,o as c,c as i,a as e,b as n,d as o,e as s}from"./app-UOvWaKji.js";const d={},r=s(`

                        mKCP

                        mKCP 使用 UDP 来模拟 TCP 连接。

                        mKCP 牺牲带宽来降低延迟。传输同样的内容,mKCP 一般比 TCP 消耗更多的流量。

                        提示

                        请确定主机上的防火墙配置正确

                        KcpObject

                        KcpObject 对应传输配置的 kcpSettings 项。

                        {
                           "mtu": 1350,
                           "tti": 20,
                           "uplinkCapacity": 5,
                        diff --git a/assets/mkcp.html-8I8osN8v.js b/assets/mkcp.html-i8OOkSjS.js
                        similarity index 98%
                        rename from assets/mkcp.html-8I8osN8v.js
                        rename to assets/mkcp.html-i8OOkSjS.js
                        index 89b5cc8b01..dc737a02d0 100644
                        --- a/assets/mkcp.html-8I8osN8v.js
                        +++ b/assets/mkcp.html-i8OOkSjS.js
                        @@ -1 +1 @@
                        -import{_ as s,r as o,o as d,c as h,a as e,b as t,d as n,e as i}from"./app-PDrbPfzp.js";const r={},l=e("h1",{id:"mkcp-protocol",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#mkcp-protocol"},[e("span",null,"mKCP Protocol")])],-1),c={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},m=i('

                        Version

                        mKCP has no version number and does not guarantee compatibility between versions.

                        Dependencies

                        Underlying Protocol

                        mKCP is a protocol based on UDP, and all communication uses UDP transmission.

                        Functions

                        ',6),p={href:"https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function",target:"_blank",rel:"noopener noreferrer"},u=e("ul",null,[e("li",null,"Takes a string of arbitrary length as input parameter;"),e("li",null,"Outputs a 32-bit unsigned integer.")],-1),b=i('

                        Communication Process

                        1. mKCP splits data streams into several data packets for transmission. Each data stream has a unique identifier to distinguish it from other data streams. Each data packet in the data stream carries the same identifier.
                        2. mKCP does not have a handshake process. When receiving a data packet, it determines whether it is a new call or an ongoing call based on the identifier of the data stream it carries.
                        3. Each data packet contains several segments (Segment), which are divided into three types: data (Data), acknowledgment (ACK), and heartbeat (Ping). Each segment needs to be processed separately.

                        Data Format

                        Data Packet

                        4 Bytes2 BytesL Bytes
                        Auth AData Len LFragment

                        as which:

                        • Authentication information A = fnv(fragment), big endian;
                        • The fragment may contain multiple sections.

                        Data snippet

                        2 bytes1 byte1 byte4 bytes4 bytes4 bytes2 bytesLen bytes
                        Conv flagCmd flagOpt flagTimestampSequenceUnacknowledgedLen flagData

                        as which:

                        • Identifier Conv: Identifier for mKCP data stream
                        • Command Cmd: Constant 0x01
                        • Option Opt: Optional values include:
                          • 0x00: Empty option
                          • 0x01: Opposite party has sent all data
                        • Timestamp Ts: Time when the current segment was sent from the remote end, big endian
                        • Sequence Number Sn: The position of the data segment in the data stream, the sequence number of the starting segment is 0, and each new segment is sequentially added by 1
                        • Unacknowledged Sequence Number Una: The minimum Sn that the remote host is sending and has not yet received confirmation.

                        Confirmation snippet

                        2 bytes1 byte1 byte4 bytes4 bytes4 bytes2 bytesLen * 4 bytes
                        Conv IDCmdOptWndNext Seq NumberTimestampLengthReceived Seq Number

                        as which:

                        • Identifier Conv: Identifier of the mKCP data stream
                        • Command Cmd: Constant 0x00
                        • Option Opt: Same as above
                        • Window Wnd: The maximum sequence number that the remote host can receive
                        • Next receive sequence number Sn: The smallest sequence number of the data segment that the remote host has not received
                        • Timestamp Ts: The timestamp of the latest received data segment by the remote host, which can be used to calculate the delay
                        • Received sequence numbers: Each 4 bytes, indicating that the data of this sequence number has been confirmed received.

                        as which:

                        • The remote host expects to receive data within the serial number [Sn, Wnd) range.

                        Heartbeat Fragments

                        2 Bytes1 Byte1 Byte4 Bytes4 Bytes4 Bytes
                        Conv IDCmdOptUnacknowledged Seq NoNext Receive Seq NoRto

                        as which:

                        • Identifier Conv: Identifier for the mKCP data stream
                        • Command Cmd: Optional values include:
                          • 0x02: Remote host forcibly terminates the session
                          • 0x03: Normal heartbeat
                        • Option Opt: Same as above
                        • Unacknowledged sequence number Una: Same as the Una of the data fragment
                        • Next receive sequence number Sn: Same as the Sn of the acknowledgement fragment
                        • Delay Rto: Delay calculated by the remote host itself
                        ',21);function f(y,g){const a=o("ExternalLinkIcon");return d(),h("div",null,[l,e("p",null,[t("mKCP is a stream transfer protocol, modified from the "),e("a",c,[t("KCP protocol"),n(a)]),t(", which can transmit any data stream in order.")]),m,e("ul",null,[e("li",null,[t("fnv: "),e("a",p,[t("FNV-1a"),n(a)]),t(" hash function "),u])]),b])}const C=s(r,[["render",f],["__file","mkcp.html.vue"]]);export{C as default}; +import{_ as s,r as o,o as d,c as h,a as e,b as t,d as n,e as i}from"./app-UOvWaKji.js";const r={},l=e("h1",{id:"mkcp-protocol",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#mkcp-protocol"},[e("span",null,"mKCP Protocol")])],-1),c={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},m=i('

                        Version

                        mKCP has no version number and does not guarantee compatibility between versions.

                        Dependencies

                        Underlying Protocol

                        mKCP is a protocol based on UDP, and all communication uses UDP transmission.

                        Functions

                        ',6),p={href:"https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function",target:"_blank",rel:"noopener noreferrer"},u=e("ul",null,[e("li",null,"Takes a string of arbitrary length as input parameter;"),e("li",null,"Outputs a 32-bit unsigned integer.")],-1),b=i('

                        Communication Process

                        1. mKCP splits data streams into several data packets for transmission. Each data stream has a unique identifier to distinguish it from other data streams. Each data packet in the data stream carries the same identifier.
                        2. mKCP does not have a handshake process. When receiving a data packet, it determines whether it is a new call or an ongoing call based on the identifier of the data stream it carries.
                        3. Each data packet contains several segments (Segment), which are divided into three types: data (Data), acknowledgment (ACK), and heartbeat (Ping). Each segment needs to be processed separately.

                        Data Format

                        Data Packet

                        4 Bytes2 BytesL Bytes
                        Auth AData Len LFragment

                        as which:

                        • Authentication information A = fnv(fragment), big endian;
                        • The fragment may contain multiple sections.

                        Data snippet

                        2 bytes1 byte1 byte4 bytes4 bytes4 bytes2 bytesLen bytes
                        Conv flagCmd flagOpt flagTimestampSequenceUnacknowledgedLen flagData

                        as which:

                        • Identifier Conv: Identifier for mKCP data stream
                        • Command Cmd: Constant 0x01
                        • Option Opt: Optional values include:
                          • 0x00: Empty option
                          • 0x01: Opposite party has sent all data
                        • Timestamp Ts: Time when the current segment was sent from the remote end, big endian
                        • Sequence Number Sn: The position of the data segment in the data stream, the sequence number of the starting segment is 0, and each new segment is sequentially added by 1
                        • Unacknowledged Sequence Number Una: The minimum Sn that the remote host is sending and has not yet received confirmation.

                        Confirmation snippet

                        2 bytes1 byte1 byte4 bytes4 bytes4 bytes2 bytesLen * 4 bytes
                        Conv IDCmdOptWndNext Seq NumberTimestampLengthReceived Seq Number

                        as which:

                        • Identifier Conv: Identifier of the mKCP data stream
                        • Command Cmd: Constant 0x00
                        • Option Opt: Same as above
                        • Window Wnd: The maximum sequence number that the remote host can receive
                        • Next receive sequence number Sn: The smallest sequence number of the data segment that the remote host has not received
                        • Timestamp Ts: The timestamp of the latest received data segment by the remote host, which can be used to calculate the delay
                        • Received sequence numbers: Each 4 bytes, indicating that the data of this sequence number has been confirmed received.

                        as which:

                        • The remote host expects to receive data within the serial number [Sn, Wnd) range.

                        Heartbeat Fragments

                        2 Bytes1 Byte1 Byte4 Bytes4 Bytes4 Bytes
                        Conv IDCmdOptUnacknowledged Seq NoNext Receive Seq NoRto

                        as which:

                        • Identifier Conv: Identifier for the mKCP data stream
                        • Command Cmd: Optional values include:
                          • 0x02: Remote host forcibly terminates the session
                          • 0x03: Normal heartbeat
                        • Option Opt: Same as above
                        • Unacknowledged sequence number Una: Same as the Una of the data fragment
                        • Next receive sequence number Sn: Same as the Sn of the acknowledgement fragment
                        • Delay Rto: Delay calculated by the remote host itself
                        ',21);function f(y,g){const a=o("ExternalLinkIcon");return d(),h("div",null,[l,e("p",null,[t("mKCP is a stream transfer protocol, modified from the "),e("a",c,[t("KCP protocol"),n(a)]),t(", which can transmit any data stream in order.")]),m,e("ul",null,[e("li",null,[t("fnv: "),e("a",p,[t("FNV-1a"),n(a)]),t(" hash function "),u])]),b])}const C=s(r,[["render",f],["__file","mkcp.html.vue"]]);export{C as default}; diff --git a/assets/multiple.html-TLF_RZel.js b/assets/multiple.html-TLF_RZel.js deleted file mode 100644 index 937566cf71..0000000000 --- a/assets/multiple.html-TLF_RZel.js +++ /dev/null @@ -1,87 +0,0 @@ -import{_ as n,o as s,c as a,e as o}from"./app-PDrbPfzp.js";const e={},t=o(`

                        多文件配置

                        Xray 程序支持使用多个配置文件。

                        多配置文件的主要作用在于分散不同作用模块配置,便于管理和维护。

                        该功能主要考虑是为了丰富 Xray 的生态链,比如对于 GUI 的客户端,一般只实现节点选择等固定的功能,对于太复杂的配置难以图形化实现;只需留一个 confdir 的自定义配置目录供配置复杂的功能;对于服务器的部署脚本,只需往 confdir 添加文件即可实现配置多种协议。

                        多文件启动

                        提示

                        启动信息中会提示依次读入的每个配置文件,留意启动信息是否符合你预设的顺序。

                        $ xray run -confdir /etc/xray/confs
                        -

                        也可使用 Xray.location.confdirXray_LOCATION_CONFDIR 指定 confdir

                        参数 -confdir 的作用优先于环境变量,如果参数指定了有效的目录则不再读取环境变量中的路径。

                        规则说明

                        普通对象({}

                        在 json 的顶级对象当中,后者覆盖或补充前者。

                        比如:

                        • base.json
                        {
                        -  "log": {},
                        -  "api": {},
                        -  "dns": {},
                        -  "stats": {},
                        -  "policy": {},
                        -  "transport": {},
                        -  "routing": {},
                        -  "inbounds": []
                        -}
                        -
                        • outbounds.json
                        {
                        -  "outbounds": []
                        -}
                        -

                        以多配置启动 Xray:

                        # 路径 /etc/xray/confs 为多文件存放目录
                        -$ xray run -confdir /etc/xray/confs
                        -

                        base.jsonoutbounds.json 这两个配置文件的效果之和等效于单文件配置的效果, 如下方所示:

                        {
                        -  "log": {},
                        -  "api": {},
                        -  "dns": {},
                        -  "stats": {},
                        -  "policy": {},
                        -  "transport": {},
                        -  "routing": {},
                        -  "inbounds": [],
                        -  "outbounds": []
                        -}
                        -

                        当需要修改出口节点,只需要修改 outbounds.json 的内容。

                        如果需要改变日志 log 的级别,也不需要改 base.json,只需后续增加一个配置:

                        • debuglog.json
                        {
                        -  "log": {
                        -    "loglevel": "debug"
                        -  }
                        -}
                        -

                        启动顺序放置在 base 后,即可输出 debug 级别的日志。

                        提示

                        文件启动顺序是通过在每个文件名前面增加前缀数字的方式实现的,如 00_文件名, 01_文件名。 数字越大排序越靠后。

                        数组([]

                        在 json 配置中的inboundsoutbounds是数组结构,他们有特殊的规则:

                        • 当配置中的数组元素有 2 个或以上,则后者覆盖前者的 inbounds/oubounds 的内容,详情看下方的【接近可用配置的例子】;
                        • 当配置中的数组元素只有 1 个时,查找原有tag相同的元素进行覆盖;若无法找到:
                          • 对于 inbounds,添加至最后(inbounds 内元素顺序无关)
                          • 对于 outbounds,添加至最前(outbounds 默认首选出口);但如果文件名含有 tail(大小写均可),添加至最后。

                        借助多配置,可以很方便为原有的配置添加不同协议的 inbound,而不必修改原有配置。

                        接近可用配置的例子

                        以下例子不是有效配置,只为展示上述规则。

                        • 00.json
                        {
                        -  "inbounds": [
                        -    {
                        -      "protocol": "socks",
                        -      "tag": "socks",
                        -      "port": 1234
                        -    }
                        -  ]
                        -}
                        -
                        • 01.json
                        {
                        -  "inbounds": [
                        -    {
                        -      "protocol": "http",
                        -      "tag": "http"
                        -    }
                        -  ]
                        -}
                        -
                        • 02.json
                        {
                        -  "inbounds": [
                        -    {
                        -      "protocol": "socks",
                        -      "tag": "socks",
                        -      "port": 4321
                        -    }
                        -  ]
                        -}
                        -

                        三个配置将会合并为:

                        {
                        -  "inbounds": [
                        -    {
                        -      "protocol": "socks",
                        -      "tag": "socks",
                        -      "port": 4321 // < 02.json顺序在00.json后,因此覆盖tag为socks的inbound端口为4321
                        -    },
                        -    {
                        -      "protocol": "http",
                        -      "tag": "http"
                        -    }
                        -  ]
                        -}
                        -

                        推荐的多文件列表

                        执行:

                        for BASE in 00_log 01_api 02_dns 03_routing 04_policy 05_inbounds 06_outbounds 07_transport 08_stats 09_reverse; do echo '{}' > "/etc/Xray/$BASE.json"; done
                        -

                        for BASE in 00_log 01_api 02_dns 03_routing 04_policy 05_inbounds 06_outbounds 07_transport 08_stats 09_reverse; do echo '{}' > "/usr/local/etc/Xray/$BASE.json"; done
                        -
                        .
                        -├── 00_log.json
                        -├── 01_api.json
                        -├── 02_dns.json
                        -├── 03_routing.json
                        -├── 04_policy.json
                        -├── 05_inbounds.json
                        -├── 06_outbounds.json
                        -├── 07_transport.json
                        -├── 08_stats.json
                        -└── 09_reverse.json
                        -
                        -0 directories, 10 files
                        -
                        `,47),p=[t];function i(l,c){return s(),a("div",null,p)}const r=n(e,[["render",i],["__file","multiple.html.vue"]]);export{r as default}; diff --git a/assets/multiple.html-g48N6K0K.js b/assets/multiple.html-g48N6K0K.js deleted file mode 100644 index d0ea93f5a7..0000000000 --- a/assets/multiple.html-g48N6K0K.js +++ /dev/null @@ -1 +0,0 @@ -const e=JSON.parse('{"key":"v-3acf20ea","path":"/config/features/multiple.html","title":"多文件配置","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"多文件启动","slug":"多文件启动","link":"#多文件启动","children":[]},{"level":2,"title":"规则说明","slug":"规则说明","link":"#规则说明","children":[{"level":3,"title":"普通对象({})","slug":"普通对象","link":"#普通对象","children":[]},{"level":3,"title":"数组([])","slug":"数组","link":"#数组","children":[]}]},{"level":2,"title":"接近可用配置的例子","slug":"接近可用配置的例子","link":"#接近可用配置的例子","children":[]},{"level":2,"title":"推荐的多文件列表","slug":"推荐的多文件列表","link":"#推荐的多文件列表","children":[]}],"git":{"updatedTime":1705787431000,"contributors":[{"name":"JimhHan","email":"50871214+JimhHan@users.noreply.github.com","commits":2},{"name":"Aoleou Tubby","email":"124496859+aoleou@users.noreply.github.com","commits":1}]},"filePathRelative":"config/features/multiple.md"}');export{e as data}; diff --git a/assets/multiple.html-1mvnHAHO.js b/assets/multiple.html-iAO2Lnc3.js similarity index 99% rename from assets/multiple.html-1mvnHAHO.js rename to assets/multiple.html-iAO2Lnc3.js index 6ba89c8e33..dd3703ebfc 100644 --- a/assets/multiple.html-1mvnHAHO.js +++ b/assets/multiple.html-iAO2Lnc3.js @@ -1,4 +1,4 @@ -import{_ as n,o as s,c as a,e}from"./app-PDrbPfzp.js";const o={},t=e(`

                        Multi-file configuration

                        The Xray program supports the use of multiple configuration files.

                        The main purpose of using multiple configuration files is to distribute different module configurations, making it easier to manage and maintain.

                        This feature is mainly designed to enrich the Xray ecosystem. For example, for GUI-based clients, only fixed functions such as node selection are usually implemented, and complex configurations are difficult to implement graphically. By leaving a custom confdir configuration directory for complex functions, server deployment scripts can simply add files to confdir to implement multiple protocol configurations.

                        Multi-file startup

                        Tip

                        The startup information will indicate each configuration file being read in sequence. Please pay attention to whether the startup information matches the order you have set.

                        $ xray run -confdir /etc/xray/confs
                        +import{_ as n,o as s,c as a,e}from"./app-UOvWaKji.js";const o={},t=e(`

                        Multi-file configuration

                        The Xray program supports the use of multiple configuration files.

                        The main purpose of using multiple configuration files is to distribute different module configurations, making it easier to manage and maintain.

                        This feature is mainly designed to enrich the Xray ecosystem. For example, for GUI-based clients, only fixed functions such as node selection are usually implemented, and complex configurations are difficult to implement graphically. By leaving a custom confdir configuration directory for complex functions, server deployment scripts can simply add files to confdir to implement multiple protocol configurations.

                        Multi-file startup

                        Tip

                        The startup information will indicate each configuration file being read in sequence. Please pay attention to whether the startup information matches the order you have set.

                        $ xray run -confdir /etc/xray/confs
                         

                        You can also use Xray.location.confdir or Xray_LOCATION_CONFDIR to specify the confdir.

                        The -confdir parameter takes precedence over the environment variable. If a valid directory is specified by the parameter, the path in the environment variable will not be read.

                        Rule Explaination

                        Normal Objects({}

                        In the top-level object of JSON, the latter overrides or supplements the former.

                        For ecample:

                        • base.json
                        {
                           "log": {},
                           "api": {},
                        diff --git a/assets/multiple.html-lXhmxiM0.js b/assets/multiple.html-lXhmxiM0.js
                        new file mode 100644
                        index 0000000000..b1470a3776
                        --- /dev/null
                        +++ b/assets/multiple.html-lXhmxiM0.js
                        @@ -0,0 +1 @@
                        +const e=JSON.parse('{"key":"v-3acf20ea","path":"/config/features/multiple.html","title":"多文件配置","lang":"zh-CN","frontmatter":{},"headers":[{"level":2,"title":"多文件启动","slug":"多文件启动","link":"#多文件启动","children":[]},{"level":2,"title":"规则说明","slug":"规则说明","link":"#规则说明","children":[{"level":3,"title":"普通对象({})","slug":"普通对象","link":"#普通对象","children":[]},{"level":3,"title":"数组([])","slug":"数组","link":"#数组","children":[]}]},{"level":2,"title":"配置例子","slug":"配置例子","link":"#配置例子","children":[]}],"git":{"updatedTime":1714813723000,"contributors":[{"name":"JimhHan","email":"50871214+JimhHan@users.noreply.github.com","commits":2},{"name":"Aoleou Tubby","email":"124496859+aoleou@users.noreply.github.com","commits":1},{"name":"nobody","email":"nobody@nowhere.mars","commits":1}]},"filePathRelative":"config/features/multiple.md"}');export{e as data};
                        diff --git a/assets/multiple.html-zE8J70pG.js b/assets/multiple.html-zE8J70pG.js
                        new file mode 100644
                        index 0000000000..c4f2670ecd
                        --- /dev/null
                        +++ b/assets/multiple.html-zE8J70pG.js
                        @@ -0,0 +1,75 @@
                        +import{_ as n,o as s,c as a,e as o}from"./app-UOvWaKji.js";const t={},p=o(`

                        多文件配置

                        Xray 程序支持使用多个配置文件。

                        多配置文件的主要作用在于分散不同作用模块配置,便于管理和维护。

                        该功能主要考虑是为了丰富 Xray 的生态链,比如对于 GUI 的客户端,一般只实现节点选择等固定的功能,对于太复杂的配置难以图形化实现;只需留一个 confdir 的自定义配置目录供配置复杂的功能;对于服务器的部署脚本,只需往 confdir 添加文件即可实现配置多种协议。

                        多文件启动

                        提示

                        启动信息中会提示依次读入的每个配置文件,留意启动信息是否符合你预设的顺序。可以在每个文件名前面增加前缀数字的方式控制顺序。如 01_文件名, 02_文件名,数字越大排序越靠后。

                        $ xray run -confdir /etc/xray/confs
                        +

                        也可使用 Xray.location.confdirXray_LOCATION_CONFDIR 指定 confdir

                        参数 -confdir 的作用优先于环境变量,如果参数指定了有效的目录则不再读取环境变量中的路径。

                        规则说明

                        普通对象({}

                        顶级对象后者覆盖或补充前者

                        数组([]

                        在 json 配置中的 inboundsoutbounds 是数组结构,他们有特殊的规则:

                        • 查找原有 tag 相同的元素进行覆盖;若无法找到:
                          • 对于 inbounds,添加至最后(inbounds 内元素顺序无关)
                          • 对于 outbounds,添加至最前(outbounds 默认首选出口);但如果文件名含有 tail(大小写均可),添加至最后。

                        配置例子

                        假设 confs 文件夹下有以下三个配置文件。

                        • 01.json
                        {
                        +  "log": {
                        +    "loglevel": "warning"
                        +  },
                        +  "inbounds": [
                        +    {
                        +      "tag": "socks",
                        +      "protocol": "socks",
                        +      "listen": "0.0.0.0",
                        +      "port": 8888
                        +    }
                        +  ],
                        +  "outbounds": [
                        +    {
                        +      "tag": "direct",
                        +      "protocol": "freedom"
                        +    }
                        +  ]
                        +}
                        +
                        • 02.json
                        {
                        +  "log": {
                        +    "loglevel": "debug"
                        +  },
                        +  "inbounds": [
                        +    {
                        +      "tag": "socks",
                        +      "protocol": "socks",
                        +      "listen": "127.0.0.1",
                        +      "port": 1080
                        +    }
                        +  ],
                        +  "outbounds": [
                        +    {
                        +      "tag": "block",
                        +      "protocol": "blackhole"
                        +    }
                        +  ]
                        +}
                        +
                        • 03_tail.json
                        {
                        +  "outbounds": [
                        +    {
                        +      "tag": "direct2",
                        +      "protocol": "freedom"
                        +    }
                        +  ]
                        +}
                        +

                        三个配置将会合并为:

                        {
                        +  "log": {
                        +    "loglevel": "debug"  // 顶级对象覆盖前者
                        +  },
                        +  "inbounds": [
                        +    {
                        +      "tag": "socks", // tag 相同时覆盖前者
                        +      "protocol": "socks",
                        +      "listen": "127.0.0.1",
                        +      "port": 1080 
                        +    }
                        +  ],
                        +  "outbounds": [
                        +    {
                        +      "tag": "block",  // outbounds 添加至最前
                        +      "protocol": "blackhole"
                        +    },
                        +    {
                        +      "tag": "direct",
                        +      "protocol": "freedom"
                        +    },
                        +    {
                        +      "tag": "direct2", // 03_tail.json 文件名中包含 tail 关键字,添加至最后
                        +      "protocol": "freedom"
                        +    }
                        +  ]
                        +}
                        +

                        提示

                        可以使用 xray run -confdir=./confs -dump 命令查看合并后的配置。但是因为 core 内部使用 protobuf 数据格式,所以 -dump 选项输出的配置格式会有所不同。

                        `,26),e=[p];function c(l,i){return s(),a("div",null,e)}const r=n(t,[["render",c],["__file","multiple.html.vue"]]);export{r as default}; diff --git a/assets/muxcool.html-evEdSRWg.js b/assets/muxcool.html-_Q_MClhY.js similarity index 99% rename from assets/muxcool.html-evEdSRWg.js rename to assets/muxcool.html-_Q_MClhY.js index bd2cb373de..488015e5cb 100644 --- a/assets/muxcool.html-evEdSRWg.js +++ b/assets/muxcool.html-_Q_MClhY.js @@ -1 +1 @@ -import{_ as h,r as l,o,c as n,a as t,b as a,d as i,e}from"./app-PDrbPfzp.js";const r={},p=e('

                        Mux.Cool 协议

                        Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。

                        版本

                        当前版本是 1 Beta。

                        依赖

                        底层协议

                        Mux.Cool 必须运行在一个已建立的可靠数据流之上。

                        通讯过程

                        一个 Mux.Cool 连接中可传输若干个子连接,每个子连接有一个独立的 ID 和状态。传输过程由帧(Frame)组成,每一帧用于传输一个特定的子连接的数据。

                        客户端行为

                        当有连接需求时并且没有现有可用的连接时,客户端向服务器发起一个新连接,以下称为“主连接”。

                        1. 一个主连接可用于发送若干个子连接。客户端可自主决定主连接可承载的子连接数量。
                        2. 对于一个新的子连接,客户端必须发送状态New以通知服务器建立子连接,然后使用状态Keep来传送数据。
                        3. 当子连接结束时,客户端发送End状态来通知服务器关闭子连接。
                        4. 客户端可自行决定何时关闭主连接,但必须确定服务器也同时保持连接。
                        5. 客户端可使用 KeepAlive 状态来避免服务器关闭主连接。

                        服务器端行为

                        当服务器端接收到新的子连接时,服务器应当按正常的连接来处理。

                        1. 当收到状态End时,服务器端可以关闭对目标地址的上行连接。
                        2. 在服务器的响应中,必须使用与请求相同的 ID 来传输子连接的数据。
                        3. 服务器不能使用New状态。
                        4. 服务器可使用 KeepAlive 状态来避免客户端关闭主连接。

                        传输格式

                        Mux.Cool 使用对称传输格式,即客户端和服务器发送和接收相同格式的数据。

                        帧格式

                        2 字节L 字节X 字节
                        元数据长度 L元数据额外数据

                        元数据

                        元数据有若干种类型。所有类型的元数据都包含 ID 和 Opt 两项,其含义为:

                        ',21),s=t("li",null,"对于一般 Mux 子连接,ID 由 1 开始累加",-1),c={href:"https://github.com/XTLS/Xray-core/blob/main/common/xudp/xudp.go",target:"_blank",rel:"noopener noreferrer"},x=t("li",null,[a("Opt: "),t("ul",null,[t("li",null,"D(0x01): 有额外数据")])],-1),b=e('

                        当选项 Opt(D) 开启时,额外数据格式如下:

                        2 字节X-2 字节
                        长度 X-2数据

                        新建子连接 (New)

                        2 字节1 字节1 字节1 字节2 字节1 字节A 字节8 字节
                        ID0x01选项 Opt网络类型 N端口地址类型 T地址 AGlobal ID (XUDP)

                        其中:

                        • 网络类型 N:
                          • 0x01:TCP,表示当前子连接的流量应当以 TCP 的方式发送至目标。
                          • 0x02:UDP,表示当前子连接的流量应当以 UDP 的方式发送至目标。
                        • 地址类型 T:
                          • 0x01:IPv4
                          • 0x02:域名
                          • 0x03:IPv6
                        • 地址 A:
                          • 当 T = 0x01 时,A 为 4 字节 IPv4 地址;
                          • 当 T = 0x02 时,A 为 1 字节长度(L) + L 字节域名;
                          • 当 T = 0x03 时,A 为 16 字节 IPv6 地址;
                        • Global ID (XUDP):
                          • 客户端计算出 UDP 来源二元组的全局独特 ID,服务端用以确保当 XUDP 断线重连时,仍使用同一个端口与目标通信。

                        在新建子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。

                        保持子连接 (Keep)

                        TCP

                        2 字节1 字节1 字节
                        ID0x02选项 Opt

                        UDP

                        2 字节1 字节1 字节1 字节2 字节1 字节A 字节
                        ID0x02选项 Opt网络类型 N端口地址类型 T地址 A

                        在保持子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。 XUDP 在 Opt(D) 之后加 UDP 地址,格式同新建子连接,但没有 Global ID。

                        关闭子连接 (End)

                        2 字节1 字节1 字节
                        ID0x03选项 Opt

                        在保持子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。

                        保持连接 (KeepAlive)

                        2 字节1 字节1 字节
                        ID0x04选项 Opt

                        在保持连接时:

                        • 若 Opt(D) 开启,则这一帧所带的数据必须被丢弃。
                        • ID 可为随机值。

                        应用

                        Mux.Cool 协议与底层协议无关,理论上可以使用任何可靠的流式连接来传输 Mux.Cool 的协议数据。

                        在目标导向的协议如 Shadowsocks 和 VMess 协议中,连接建立时必须包含一个指定的地址。 为了保持兼容性,Mux.Cool 协议指定地址为“v1.mux.cool”。即当主连接的目标地址与之匹配时,则进行 Mux.Cool 方式的转发,否则按传统方式进行转发。(注:这是一个程序内的标记,VMess 和 VLESS 并不会在数据包中发送“v1.mux.cool”地址)

                        ',23);function u(D,_){const d=l("ExternalLinkIcon");return o(),n("div",null,[p,t("ul",null,[t("li",null,[a("ID: 子连接的唯一标识 "),t("ul",null,[s,t("li",null,[a("对于 Xray 实现的 "),t("a",c,[a("Single XUDP"),i(d)]),a(",ID 始终为 0")])])]),x]),b])}const I=h(r,[["render",u],["__file","muxcool.html.vue"]]);export{I as default}; +import{_ as h,r as l,o,c as n,a as t,b as a,d as i,e}from"./app-UOvWaKji.js";const r={},p=e('

                        Mux.Cool 协议

                        Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。

                        版本

                        当前版本是 1 Beta。

                        依赖

                        底层协议

                        Mux.Cool 必须运行在一个已建立的可靠数据流之上。

                        通讯过程

                        一个 Mux.Cool 连接中可传输若干个子连接,每个子连接有一个独立的 ID 和状态。传输过程由帧(Frame)组成,每一帧用于传输一个特定的子连接的数据。

                        客户端行为

                        当有连接需求时并且没有现有可用的连接时,客户端向服务器发起一个新连接,以下称为“主连接”。

                        1. 一个主连接可用于发送若干个子连接。客户端可自主决定主连接可承载的子连接数量。
                        2. 对于一个新的子连接,客户端必须发送状态New以通知服务器建立子连接,然后使用状态Keep来传送数据。
                        3. 当子连接结束时,客户端发送End状态来通知服务器关闭子连接。
                        4. 客户端可自行决定何时关闭主连接,但必须确定服务器也同时保持连接。
                        5. 客户端可使用 KeepAlive 状态来避免服务器关闭主连接。

                        服务器端行为

                        当服务器端接收到新的子连接时,服务器应当按正常的连接来处理。

                        1. 当收到状态End时,服务器端可以关闭对目标地址的上行连接。
                        2. 在服务器的响应中,必须使用与请求相同的 ID 来传输子连接的数据。
                        3. 服务器不能使用New状态。
                        4. 服务器可使用 KeepAlive 状态来避免客户端关闭主连接。

                        传输格式

                        Mux.Cool 使用对称传输格式,即客户端和服务器发送和接收相同格式的数据。

                        帧格式

                        2 字节L 字节X 字节
                        元数据长度 L元数据额外数据

                        元数据

                        元数据有若干种类型。所有类型的元数据都包含 ID 和 Opt 两项,其含义为:

                        ',21),s=t("li",null,"对于一般 Mux 子连接,ID 由 1 开始累加",-1),c={href:"https://github.com/XTLS/Xray-core/blob/main/common/xudp/xudp.go",target:"_blank",rel:"noopener noreferrer"},x=t("li",null,[a("Opt: "),t("ul",null,[t("li",null,"D(0x01): 有额外数据")])],-1),b=e('

                        当选项 Opt(D) 开启时,额外数据格式如下:

                        2 字节X-2 字节
                        长度 X-2数据

                        新建子连接 (New)

                        2 字节1 字节1 字节1 字节2 字节1 字节A 字节8 字节
                        ID0x01选项 Opt网络类型 N端口地址类型 T地址 AGlobal ID (XUDP)

                        其中:

                        • 网络类型 N:
                          • 0x01:TCP,表示当前子连接的流量应当以 TCP 的方式发送至目标。
                          • 0x02:UDP,表示当前子连接的流量应当以 UDP 的方式发送至目标。
                        • 地址类型 T:
                          • 0x01:IPv4
                          • 0x02:域名
                          • 0x03:IPv6
                        • 地址 A:
                          • 当 T = 0x01 时,A 为 4 字节 IPv4 地址;
                          • 当 T = 0x02 时,A 为 1 字节长度(L) + L 字节域名;
                          • 当 T = 0x03 时,A 为 16 字节 IPv6 地址;
                        • Global ID (XUDP):
                          • 客户端计算出 UDP 来源二元组的全局独特 ID,服务端用以确保当 XUDP 断线重连时,仍使用同一个端口与目标通信。

                        在新建子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。

                        保持子连接 (Keep)

                        TCP

                        2 字节1 字节1 字节
                        ID0x02选项 Opt

                        UDP

                        2 字节1 字节1 字节1 字节2 字节1 字节A 字节
                        ID0x02选项 Opt网络类型 N端口地址类型 T地址 A

                        在保持子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。 XUDP 在 Opt(D) 之后加 UDP 地址,格式同新建子连接,但没有 Global ID。

                        关闭子连接 (End)

                        2 字节1 字节1 字节
                        ID0x03选项 Opt

                        在保持子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。

                        保持连接 (KeepAlive)

                        2 字节1 字节1 字节
                        ID0x04选项 Opt

                        在保持连接时:

                        • 若 Opt(D) 开启,则这一帧所带的数据必须被丢弃。
                        • ID 可为随机值。

                        应用

                        Mux.Cool 协议与底层协议无关,理论上可以使用任何可靠的流式连接来传输 Mux.Cool 的协议数据。

                        在目标导向的协议如 Shadowsocks 和 VMess 协议中,连接建立时必须包含一个指定的地址。 为了保持兼容性,Mux.Cool 协议指定地址为“v1.mux.cool”。即当主连接的目标地址与之匹配时,则进行 Mux.Cool 方式的转发,否则按传统方式进行转发。(注:这是一个程序内的标记,VMess 和 VLESS 并不会在数据包中发送“v1.mux.cool”地址)

                        ',23);function u(D,_){const d=l("ExternalLinkIcon");return o(),n("div",null,[p,t("ul",null,[t("li",null,[a("ID: 子连接的唯一标识 "),t("ul",null,[s,t("li",null,[a("对于 Xray 实现的 "),t("a",c,[a("Single XUDP"),i(d)]),a(",ID 始终为 0")])])]),x]),b])}const I=h(r,[["render",u],["__file","muxcool.html.vue"]]);export{I as default}; diff --git a/assets/muxcool.html-Qf6P8rXo.js b/assets/muxcool.html-mWlirYUy.js similarity index 99% rename from assets/muxcool.html-Qf6P8rXo.js rename to assets/muxcool.html-mWlirYUy.js index f7b737e098..3741a52be1 100644 --- a/assets/muxcool.html-Qf6P8rXo.js +++ b/assets/muxcool.html-mWlirYUy.js @@ -1 +1 @@ -import{_ as e,o as t,c as a,e as n}from"./app-PDrbPfzp.js";const i={},o=n('

                        Mux.Cool Protocol

                        Mux.Cool protocol is a multiplexing transport protocol that is used to transmit multiple independent data streams within an established data stream.

                        Version

                        The current version is 1 Beta.

                        Dependencies

                        Underlying Protocol

                        Mux.Cool must run on top of a reliable established data stream.

                        Communication Process

                        Within a Mux.Cool connection, multiple sub-connections can be transmitted, each with a unique ID and status. The transmission process consists of frames, with each frame used to transmit data for a specific sub-connection.

                        Client behavior

                        When there is a need for a connection and there are no existing available connections, the client initiates a new connection to the server, referred to as the "main connection".

                        1. One main connection can be used to send several sub-connections. The client can decide independently how many sub-connections the main connection can handle.
                        2. For a new sub-connection, the client must send the New status to notify the server to establish the sub-connection, and then use the Keep status to transmit data.
                        3. When the sub-connection ends, the client sends the End status to notify the server to close the sub-connection.
                        4. The client can decide when to close the main connection, but must ensure that the server also maintains the connection.
                        5. The client can use the KeepAlive status to prevent the server from closing the main connection.

                        Server-side behavior

                        When a new sub-connection is received on the server side, the server should handle it as a normal connection.

                        1. When the status "End" is received, the server can close the upstream connection to the target address.
                        2. The same ID used in the request must be used to transfer sub-connection data in the server response.
                        3. The server cannot use the "New" status.
                        4. The server can use the KeepAlive status to avoid the client closing the main connection.

                        Data Format

                        Mux.Cool uses symmetric transmission format, where the client and server send and receive data in the same format.

                        Frame Format

                        2 BytesL BytesX Bytes
                        Metadata Length LMetadataAdditional Data

                        Metadata

                        There are several types of metadata. All types of metadata contain two items, ID and Opt, with the following meanings:

                        • ID: Unique identifier of the sub-connection
                          • For general MUX sub-connections, the ID is accumulated starting from 1
                          • For XUDP, the ID is always 0
                        • Opt:
                          • D(0x01): Additional data is available

                        When option Opt(D) is enabled, the additional data format is as follows:

                        2 BytesX-2 Bytes
                        Length X-2Data
                        2 Bytes1 Byte1 Byte1 Byte2 Bytes1 ByteA Bytes
                        ID0x01OptionNetwork NPortType TAddress

                        where:

                        • Network type N:
                          • 0x01: TCP, indicating that the traffic of the current sub-connection should be sent to the destination in the way of TCP.
                          • 0x02: UDP, indicating that the traffic of the current sub-connection should be sent to the destination in the way of UDP.
                        • Address type T:
                          • 0x01: IPv4
                          • 0x02: Domain name
                          • 0x03: IPv6
                        • Address A:
                          • When T = 0x01, A is a 4-byte IPv4 address;
                          • When T = 0x02, A is a 1-byte length (L) + L-byte domain name;
                          • When T = 0x03, A is a 16-byte IPv6 address;

                        If Opt(D) is enabled when creating a sub-connection, the data carried by this frame needs to be sent to the target host.

                        Keep sub-connections

                        2 Bytes1 Byte1 Byte
                        ID0x02Option

                        If Opt(D) is enabled while maintaining sub-connections, the data carried by this frame needs to be sent to the target host. XUDP adds the UDP address after Opt(D), and the format is the same as creating a new sub-connection.

                        End

                        2 Bytes1 Byte1 Byte
                        ID0x03Option

                        If Opt(D) is enabled while maintaining sub-connections, the data carried by this frame needs to be sent to the target host.

                        KeepAlive

                        2 Bytes1 Byte1 Byte
                        ID0x04Option Opt

                        While staying connected:

                        • If Opt(D) is enabled, the data carried by this frame must be discarded.
                        • ID can be a random value.

                        Application

                        The Mux.Cool protocol is agnostic to the underlying protocol and can theoretically use any reliable streaming connection to transmit Mux.Cool protocol data.

                        In target-oriented protocols such as Shadowsocks and VMess, a specified address must be included when establishing a connection. To maintain compatibility, the Mux.Cool protocol specifies the address as "v1.mux.cool". When the target address of the main connection matches this address, the Mux.Cool forwarding method is used. Otherwise, forwarding is done in the traditional way. (Note: This is an internal tag in the program, and VMess and VLESS do not send the "v1.mux.cool" address in data packets.)

                        ',42),s=[o];function d(h,r){return t(),a("div",null,s)}const l=e(i,[["render",d],["__file","muxcool.html.vue"]]);export{l as default}; +import{_ as e,o as t,c as a,e as n}from"./app-UOvWaKji.js";const i={},o=n('

                        Mux.Cool Protocol

                        Mux.Cool protocol is a multiplexing transport protocol that is used to transmit multiple independent data streams within an established data stream.

                        Version

                        The current version is 1 Beta.

                        Dependencies

                        Underlying Protocol

                        Mux.Cool must run on top of a reliable established data stream.

                        Communication Process

                        Within a Mux.Cool connection, multiple sub-connections can be transmitted, each with a unique ID and status. The transmission process consists of frames, with each frame used to transmit data for a specific sub-connection.

                        Client behavior

                        When there is a need for a connection and there are no existing available connections, the client initiates a new connection to the server, referred to as the "main connection".

                        1. One main connection can be used to send several sub-connections. The client can decide independently how many sub-connections the main connection can handle.
                        2. For a new sub-connection, the client must send the New status to notify the server to establish the sub-connection, and then use the Keep status to transmit data.
                        3. When the sub-connection ends, the client sends the End status to notify the server to close the sub-connection.
                        4. The client can decide when to close the main connection, but must ensure that the server also maintains the connection.
                        5. The client can use the KeepAlive status to prevent the server from closing the main connection.

                        Server-side behavior

                        When a new sub-connection is received on the server side, the server should handle it as a normal connection.

                        1. When the status "End" is received, the server can close the upstream connection to the target address.
                        2. The same ID used in the request must be used to transfer sub-connection data in the server response.
                        3. The server cannot use the "New" status.
                        4. The server can use the KeepAlive status to avoid the client closing the main connection.

                        Data Format

                        Mux.Cool uses symmetric transmission format, where the client and server send and receive data in the same format.

                        Frame Format

                        2 BytesL BytesX Bytes
                        Metadata Length LMetadataAdditional Data

                        Metadata

                        There are several types of metadata. All types of metadata contain two items, ID and Opt, with the following meanings:

                        • ID: Unique identifier of the sub-connection
                          • For general MUX sub-connections, the ID is accumulated starting from 1
                          • For XUDP, the ID is always 0
                        • Opt:
                          • D(0x01): Additional data is available

                        When option Opt(D) is enabled, the additional data format is as follows:

                        2 BytesX-2 Bytes
                        Length X-2Data
                        2 Bytes1 Byte1 Byte1 Byte2 Bytes1 ByteA Bytes
                        ID0x01OptionNetwork NPortType TAddress

                        where:

                        • Network type N:
                          • 0x01: TCP, indicating that the traffic of the current sub-connection should be sent to the destination in the way of TCP.
                          • 0x02: UDP, indicating that the traffic of the current sub-connection should be sent to the destination in the way of UDP.
                        • Address type T:
                          • 0x01: IPv4
                          • 0x02: Domain name
                          • 0x03: IPv6
                        • Address A:
                          • When T = 0x01, A is a 4-byte IPv4 address;
                          • When T = 0x02, A is a 1-byte length (L) + L-byte domain name;
                          • When T = 0x03, A is a 16-byte IPv6 address;

                        If Opt(D) is enabled when creating a sub-connection, the data carried by this frame needs to be sent to the target host.

                        Keep sub-connections

                        2 Bytes1 Byte1 Byte
                        ID0x02Option

                        If Opt(D) is enabled while maintaining sub-connections, the data carried by this frame needs to be sent to the target host. XUDP adds the UDP address after Opt(D), and the format is the same as creating a new sub-connection.

                        End

                        2 Bytes1 Byte1 Byte
                        ID0x03Option

                        If Opt(D) is enabled while maintaining sub-connections, the data carried by this frame needs to be sent to the target host.

                        KeepAlive

                        2 Bytes1 Byte1 Byte
                        ID0x04Option Opt

                        While staying connected:

                        • If Opt(D) is enabled, the data carried by this frame must be discarded.
                        • ID can be a random value.

                        Application

                        The Mux.Cool protocol is agnostic to the underlying protocol and can theoretically use any reliable streaming connection to transmit Mux.Cool protocol data.

                        In target-oriented protocols such as Shadowsocks and VMess, a specified address must be included when establishing a connection. To maintain compatibility, the Mux.Cool protocol specifies the address as "v1.mux.cool". When the target address of the main connection matches this address, the Mux.Cool forwarding method is used. Otherwise, forwarding is done in the traditional way. (Note: This is an internal tag in the program, and VMess and VLESS do not send the "v1.mux.cool" address in data packets.)

                        ',42),s=[o];function d(h,r){return t(),a("div",null,s)}const l=e(i,[["render",d],["__file","muxcool.html.vue"]]);export{l as default}; diff --git a/assets/news.html-KjqE-CJP.js b/assets/news.html--Ypfy9X2.js similarity index 99% rename from assets/news.html-KjqE-CJP.js rename to assets/news.html--Ypfy9X2.js index bad5d35cb2..3791b0ad27 100644 --- a/assets/news.html-KjqE-CJP.js +++ b/assets/news.html--Ypfy9X2.js @@ -1 +1 @@ -import{_ as h,r as i,o as _,c,a as e,b as l,d as n,w as o,e as r}from"./app-PDrbPfzp.js";const u={},d=r('

                        大史记

                        2021.4.6

                        • VuePress Next.
                        • With Dark Mode.

                        2021.4.4

                        • 本文档迎来的新的首页。
                        • 本文档迎来了暗黑模式。
                        • 当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。
                        • 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
                        • 🎉🎉🎉
                        ',5),p={id:"_2021-4-1-v1-4-2",tabindex:"-1"},f={class:"header-anchor",href:"#_2021-4-1-v1-4-2"},b={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.2",target:"_blank",rel:"noopener noreferrer"},g=r('
                        • 不是愚人节玩笑,今天更新。
                        • 加入 Browser Dialer,用与改变 TLS 指纹与行为。
                        • 加入 uTLS,用与改变 TLS Client Hello 的指纹。
                        • 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。

                        2021.3.25

                        没错还在变。 -_-

                        2021.3.15

                        文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

                        ',5),m={id:"_2021-3-14-v1-4-0",tabindex:"-1"},x={class:"header-anchor",href:"#_2021-3-14-v1-4-0"},X={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.0",target:"_blank",rel:"noopener noreferrer"},S=r("
                        • Happy Pi-Day!
                        • 这次是个大更新:
                          • 为链式代理引入了传输层支持。
                          • 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
                          • 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
                          • 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
                          • 添加了 FakeDNS。
                          • 还修复了系列的问题,添加了各类功能,详情请见更新日志。
                        • 还是 VuePress 比较爽啊(
                        ",1),k={id:"_2021-3-3-1-3-1",tabindex:"-1"},y={class:"header-anchor",href:"#_2021-3-3-1-3-1"},v={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.1",target:"_blank",rel:"noopener noreferrer"},T=e("ul",null,[e("li",null,"这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。"),e("li",null,[l("同时修复了一个会导致 Panic 的 bug。"),e("s",null,"Holmium_认为这是在骗、在偷袭。")]),e("li",null,"修复了几个遗留问题。")],-1),L={id:"_2021-2-14-1-3-0",tabindex:"-1"},D={class:"header-anchor",href:"#_2021-2-14-1-3-0"},P={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.0",target:"_blank",rel:"noopener noreferrer"},U=e("ul",null,[e("li",null,"Happy 🐮 Year 🎉!"),e("li",null,"v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。"),e("li",null,"OHHHHHHHHHHHH!")],-1),H={id:"_2021-01-31-1-2-4",tabindex:"-1"},C={class:"header-anchor",href:"#_2021-01-31-1-2-4"},j={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.4",target:"_blank",rel:"noopener noreferrer"},B=e("ul",null,[e("li",null,"解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。"),e("li",null,"似乎这个版本没有什么改变,但这只是暴风雨前的宁静。"),e("li",null,[l("(没错我就是先知) "),e("blockquote",null,[e("p",null,"你个傻子,你拿的是 UNO 牌。")])])],-1),N=e("h2",{id:"_2021-01-25",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2021-01-25"},[e("span",null,"2021.01.25")])],-1),E=e("li",null,[e("a",{href:"../en"},"英文版文档网站"),l("逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!")],-1),I={id:"_2021-01-22-1-2-3",tabindex:"-1"},V={class:"header-anchor",href:"#_2021-01-22-1-2-3"},w={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.3",target:"_blank",rel:"noopener noreferrer"},G=e("li",null,[l("对 SS 协议的支持"),e("strong",null,"又"),l("变强了, 支持单端口多用户!")],-1),R=e("li",null,[l("对 trojan 协议的支持也"),e("strong",null,"又"),l("变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!")],-1),O=e("li",null,[e("em",null,"(VLESS: 嘤嘤嘤)")],-1),F=e("li",null,'UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".',-1),M=e("li",null,"嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.",-1),A=e("img",{src:"https://avatars2.githubusercontent.com/u/8384161?s=32",width:"32px",height:"32px",alt:"a"},null,-1),q={href:"https://github.com/bohanyang",target:"_blank",rel:"noopener noreferrer"},W=e("li",null,"其他美味小樱桃, 惯例更新品尝就对啦.",-1),Q=r('

                        2021.01.19

                        • 一些数字
                          • 版本发布了 10   个 tag
                          • 解决掉了 100  个 issue
                          • 复刻了 300  个 fork
                          • 点了 2000 个 star
                          • 群 3000 个 人

                        2021.01.17

                        ',3),Y=e("img",{src:"https://avatars2.githubusercontent.com/u/60207794?s=32",width:"32px",height:"32px",alt:"a"},null,-1),J={href:"https://github.com/jiuqi9997",target:"_blank",rel:"noopener noreferrer"},z={href:"https://xtls.github.io/en/",target:"_blank",rel:"noopener noreferrer"},K={id:"_2021-01-15-1-2-2",tabindex:"-1"},Z={class:"header-anchor",href:"#_2021-01-15-1-2-2"},$={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.2",target:"_blank",rel:"noopener noreferrer"},ee=r('
                        • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
                        • 之前预告的 UUID 修改正式上线.(往下看往下看)
                        • 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
                        • 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
                        • 当然还有其他各种小糖果.(更新品尝就对了)
                        • 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE

                        2021.01.12

                        ',2),le=e("li",null,[l("将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户. "),e("ul",null,[e("li",null,'客户端写 "id": "我爱 🍉 老师 1314",'),e("li",null,[l('服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 '),e("code",null,"我爱🍉老师1314"),l(" 的 UUID 映射)")])])],-1),ne={id:"_2021-01-10-1-2-1",tabindex:"-1"},te={class:"header-anchor",href:"#_2021-01-10-1-2-1"},oe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.1",target:"_blank",rel:"noopener noreferrer"},ae=e("li",null,"(可能是整个互联网上, 最详细最有耐心的教你从 0 开始配置的教程)",-1),re=e("li",null,"还有很多细节修改, 文档将会越来越规范!",-1),se={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},ie={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},he={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},_e=r('
                        • 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
                        • Google Voice 应该也可以正常使用 v2rayNG 拨打了.
                        • 日志现在看起来更顺眼.

                        2021.01.07

                        • 礼貌和尊重本应是社区不需要明说的准则之一。

                        2021.01.05

                        • 文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

                        2021.01.03

                        ',6),ce=e("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ue={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},de=e("li",null,"tg 群突破 2500。",-1),pe=e("h2",{id:"_2021-01-01",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2021-01-01"},[e("span",null,"2021.01.01")])],-1),fe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},be=e("p",null,"🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!",-1),ge=r('
                      16. 圣诞礼物v1.1.5后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
                      17. (UDP 还会继续增强!)
                      18. 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
                      19. (不,下面不是广告,是里程碑。)
                      20. Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
                        • 一人扛起了所有!支持各大主流协议!
                        • 一骑绝尘的性能!
                        • 日趋完善的功能!
                        • 可怕的生命力与社区亲和力!
                      21. ',5),me={href:"https://github.com/XTLS/Xray-core/discussions/56",target:"_blank",rel:"noopener noreferrer"},xe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},Xe=e("s",null,"(啊,有人敲门...我一会和你们说)",-1),Se=e("h2",{id:"_2020-12-29",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-29"},[e("span",null,"2020.12.29")])],-1),ke={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},ye={id:"_2020-12-25-1-1-5",tabindex:"-1"},ve={class:"header-anchor",href:"#_2020-12-25-1-1-5"},Te={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.5",target:"_blank",rel:"noopener noreferrer"},Le=e("p",null,"圣诞节快乐!",-1),De=e("li",null,"游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone",-1),Pe=e("li",null,"你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...",-1),Ue=e("li",null,"(VLESS 的 UDP fullcone 和更多增强很快就到!)",-1),He=e("li",null,"无须再担心证书验证被墙,OCSP stapling 已经上线!",-1),Ce={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},je=e("li",null,"还有更多美味小樱桃!(不用问,更新品尝就对了)",-1),Be=e("h2",{id:"_2020-12-24",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-24"},[e("span",null,"2020.12.24")])],-1),Ne={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},Ee=e("p",null,"大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)",-1),Ie={href:"https://github.com/XTLS/XTLS.github.io",target:"_blank",rel:"noopener noreferrer"},Ve=e("p",null,"仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站. 欢迎大家查看,纠错,修改,增加心得。",-1),we=e("h2",{id:"_2020-12-23",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-23"},[e("span",null,"2020.12.23")])],-1),Ge={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Re=e("h2",{id:"_2020-12-21",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-21"},[e("span",null,"2020.12.21")])],-1),Oe=e("ul",null,[e("li",null,"Project X 群人数 2000+"),e("li",null,"群消息(含游戏群) 日均破万")],-1),Fe={id:"_2020-12-18-1-1-4",tabindex:"-1"},Me={class:"header-anchor",href:"#_2020-12-18-1-1-4"},Ae={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.4",target:"_blank",rel:"noopener noreferrer"},qe=e("ul",null,[e("li",null,"更低的启动内占用和内存使用优化"),e("li",null,"随意定制的 TLS 提高你的 SSL 评级"),e("li",null,"支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS"),e("li",null,"还有在您路由器上使用的 Splice 最佳使用模式建议")],-1),We=e("h2",{id:"_2020-12-17",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-17"},[e("span",null,"2020.12.17")])],-1),Qe={href:"https://t.me/joinchat/UO4NixbB_XDQJOUjS6mHEQ",target:"_blank",rel:"noopener noreferrer"},Ye=e("h2",{id:"_2020-12-15",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-15"},[e("span",null,"2020.12.15")])],-1),Je={href:"https://github.com/XTLS/Xray-install/tree/dev",target:"_blank",rel:"noopener noreferrer"},ze={id:"_2020-12-11-1-1-3",tabindex:"-1"},Ke={class:"header-anchor",href:"#_2020-12-11-1-1-3"},Ze={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.3",target:"_blank",rel:"noopener noreferrer"},$e=e("ul",null,[e("li",null,"完整版本的 REDIRECT 透明代理模式."),e("li",null,"软路由 splice 流控模式的优化建议.")],-1),el={id:"_2020-12-06-1-1-2",tabindex:"-1"},ll={class:"header-anchor",href:"#_2020-12-06-1-1-2"},nl={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.2",target:"_blank",rel:"noopener noreferrer"},tl=r('
                        • 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
                        • 增强了 API 兼容

                        2020.12.04

                        增加 splice 模式

                        2020.11.27

                        • Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
                        • 登上了 GitHub Trending
                        • Project X 群人数破千,频道订阅数 500+
                        ',5),ol={id:"_2020-11-25-1-0-0",tabindex:"-1"},al={class:"header-anchor",href:"#_2020-11-25-1-0-0"},rl={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.0.0",target:"_blank",rel:"noopener noreferrer"},sl=e("p",null,"Xray 的第一个版本.",-1),il=e("ul",null,[e("li",null,"基于 v2ray-core 修改而来,改动较大"),e("li",null,"全面增强, 性能卓越, 完全兼容")],-1),hl=e("h2",{id:"_2020-11-23",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-11-23"},[e("span",null,"2020.11.23")])],-1),_l=e("p",null,"project X start",-1),cl=e("blockquote",null,[e("p",null,[e("s",null,"梦开始的时候")])],-1);function ul(dl,pl){const t=i("ExternalLinkIcon"),a=i("Badge"),s=i("RouterLink");return _(),c("div",null,[d,e("h2",p,[e("a",f,[e("span",null,[l("2021.4.1 "),n(a,null,{default:o(()=>[e("a",b,[l("v1.4.2"),n(t)])]),_:1})])])]),g,e("h2",m,[e("a",x,[e("span",null,[l("2021.3.14 "),n(a,null,{default:o(()=>[e("a",X,[l("v1.4.0"),n(t)])]),_:1})])])]),S,e("h2",k,[e("a",y,[e("span",null,[l("2021.3.3 "),n(a,null,{default:o(()=>[e("a",v,[l("1.3.1"),n(t)])]),_:1})])])]),T,e("h2",L,[e("a",D,[e("span",null,[l("2021.2.14 "),n(a,null,{default:o(()=>[e("a",P,[l("1.3.0"),n(t)])]),_:1})])])]),U,e("h2",H,[e("a",C,[e("span",null,[l("2021.01.31 "),n(a,null,{default:o(()=>[e("a",j,[l("1.2.4"),n(t)])]),_:1})])])]),B,N,e("ul",null,[e("li",null,[l("全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载"),n(s,{to:"/en/document/level-1/"},{default:o(()=>[l("秘籍第一层")]),_:1}),l("咯...")]),E]),e("h2",I,[e("a",V,[e("span",null,[l("2021.01.22 "),n(a,null,{default:o(()=>[e("a",w,[l("1.2.3"),n(t)])]),_:1})])])]),e("ul",null,[G,R,O,F,M,e("li",null,[l("向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 "),A,l(),e("a",q,[l("@Bohan Yang"),n(t)]),l(" 致敬!")]),W]),Q,e("ul",null,[e("li",null,[l("辛苦的翻译工作开始了, 感谢"),Y,l(),e("a",J,[l("@玖柒 Max"),n(t)]),l("和其他所有的翻译大佬们.")]),e("li",null,[e("a",z,[l("English version"),n(t)])])]),e("h2",K,[e("a",Z,[e("span",null,[l("2021.01.15 "),n(a,null,{default:o(()=>[e("a",$,[l("1.2.2"),n(t)])]),_:1})])])]),ee,e("ul",null,[le,e("li",null,[l("🍉 老师的"),n(s,{to:"/en/document/level-0/"},{default:o(()=>[l("小小白白话文")]),_:1}),l("大结局, 撒花.")])]),e("h2",ne,[e("a",te,[e("span",null,[l("2021.01.10 "),n(a,null,{default:o(()=>[e("a",oe,[l("1.2.1"),n(t)])]),_:1})])])]),e("ul",null,[e("li",null,[n(s,{to:"/en/document/level-0/"},{default:o(()=>[l("小小白白话文")]),_:1}),l("连载上线啦,🍉 老师呕心沥血之作, 手把手教你从什么都不会到熟练配置 Xray!")]),ae,e("li",null,[n(s,{to:"/en/document/level-2/"},{default:o(()=>[l("透明代理")]),_:1}),l("也增加了更多文章.")]),re,e("li",null,[l("感谢 "),e("a",se,[l("@ricuhkaen"),n(t)]),l(" , "),e("a",ie,[l("@BioniCosmos"),n(t)]),l(", "),e("a",he,[l("@kirin"),n(t)])])]),_e,e("ul",null,[e("li",null,[l("文档仓库第一个 PR。🎉 "),n(s,{to:"/en/document/level-2/tproxy.html"},{default:o(()=>[l("透明代理(TProxy)配置教程 ")]),_:1}),l(" ,感谢"),ce,l(),e("a",ue,[l("@BioniCosmos"),n(t)])]),de]),pe,e("p",null,[l("【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 "),n(a,null,{default:o(()=>[e("a",fe,[l("1.2.0"),n(t)])]),_:1})]),be,e("ul",null,[ge,e("li",null,[l("Xray 将继续保持前行! 因此 "),e("a",me,[l("Xray 需要更多的英雄!!"),n(t)]),l("!")]),e("li",null,[l("PS:请品,请细品"),e("a",xe,[l("release notes"),n(t)]),l("每一句。似乎有一个小秘密小彩蛋 "),Xe])]),Se,e("p",null,[l("透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, "),e("a",ke,[l("TG 群"),n(t)]),l("火热测试中")]),e("h2",ye,[e("a",ve,[e("span",null,[l("2020.12.25 "),n(a,null,{default:o(()=>[e("a",Te,[l("1.1.5"),n(t)])]),_:1})])])]),Le,e("ul",null,[De,Pe,Ue,He,e("li",null,[l("kirin 带来了一大波 脚本更新."),e("a",Ce,[l("脚本在此"),n(t)])]),je]),Be,e("p",null,[l("因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。 网址为:"),e("a",Ne,[l("没错你正在看的就是"),n(t)])]),Ee,e("p",null,[l("文档网站需要不断完善和增加内容,以及完善设计。 因此更欢迎大家一起为文档建设添砖加瓦。 "),e("a",Ie,[l("文档的仓库"),n(t)])]),Ve,we,e("p",null,[l("Xray-core Shadowsocks UDP FullCone 测试版, "),e("a",Ge,[l("TG 群"),n(t)]),l("火热测试中")]),Re,Oe,e("h2",Fe,[e("a",Me,[e("span",null,[l("2020.12.18 "),n(a,null,{default:o(()=>[e("a",Ae,[l("1.1.4"),n(t)])]),_:1})])])]),qe,We,e("p",null,[l("鉴于日益增长群人数和游戏需求, 开启了"),e("a",Qe,[l("TG 游戏群"),n(t)])]),Ye,e("p",null,[e("a",Je,[l("安装脚本 dev 分支"),n(t)]),l("开启, 持续更新功能中.")]),e("h2",ze,[e("a",Ke,[e("span",null,[l("2020.12.11 "),n(a,null,{default:o(()=>[e("a",Ze,[l("1.1.3"),n(t)])]),_:1})])])]),$e,e("h2",el,[e("a",ll,[e("span",null,[l("2020.12.06 "),n(a,null,{default:o(()=>[e("a",nl,[l("1.1.2"),n(t)])]),_:1})])])]),tl,e("h2",ol,[e("a",al,[e("span",null,[l("2020.11.25 "),n(a,null,{default:o(()=>[e("a",rl,[l("1.0.0"),n(t)])]),_:1})])])]),sl,il,hl,_l,cl])}const bl=h(u,[["render",ul],["__file","news.html.vue"]]);export{bl as default}; +import{_ as h,r as i,o as _,c,a as e,b as l,d as n,w as o,e as r}from"./app-UOvWaKji.js";const u={},d=r('

                        大史记

                        2021.4.6

                        • VuePress Next.
                        • With Dark Mode.

                        2021.4.4

                        • 本文档迎来的新的首页。
                        • 本文档迎来了暗黑模式。
                        • 当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。
                        • 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
                        • 🎉🎉🎉
                        ',5),p={id:"_2021-4-1-v1-4-2",tabindex:"-1"},f={class:"header-anchor",href:"#_2021-4-1-v1-4-2"},b={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.2",target:"_blank",rel:"noopener noreferrer"},g=r('
                        • 不是愚人节玩笑,今天更新。
                        • 加入 Browser Dialer,用与改变 TLS 指纹与行为。
                        • 加入 uTLS,用与改变 TLS Client Hello 的指纹。
                        • 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。

                        2021.3.25

                        没错还在变。 -_-

                        2021.3.15

                        文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

                        ',5),m={id:"_2021-3-14-v1-4-0",tabindex:"-1"},x={class:"header-anchor",href:"#_2021-3-14-v1-4-0"},X={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.0",target:"_blank",rel:"noopener noreferrer"},S=r("
                        • Happy Pi-Day!
                        • 这次是个大更新:
                          • 为链式代理引入了传输层支持。
                          • 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
                          • 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
                          • 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
                          • 添加了 FakeDNS。
                          • 还修复了系列的问题,添加了各类功能,详情请见更新日志。
                        • 还是 VuePress 比较爽啊(
                        ",1),k={id:"_2021-3-3-1-3-1",tabindex:"-1"},y={class:"header-anchor",href:"#_2021-3-3-1-3-1"},v={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.1",target:"_blank",rel:"noopener noreferrer"},T=e("ul",null,[e("li",null,"这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。"),e("li",null,[l("同时修复了一个会导致 Panic 的 bug。"),e("s",null,"Holmium_认为这是在骗、在偷袭。")]),e("li",null,"修复了几个遗留问题。")],-1),L={id:"_2021-2-14-1-3-0",tabindex:"-1"},D={class:"header-anchor",href:"#_2021-2-14-1-3-0"},P={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.0",target:"_blank",rel:"noopener noreferrer"},U=e("ul",null,[e("li",null,"Happy 🐮 Year 🎉!"),e("li",null,"v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。"),e("li",null,"OHHHHHHHHHHHH!")],-1),H={id:"_2021-01-31-1-2-4",tabindex:"-1"},C={class:"header-anchor",href:"#_2021-01-31-1-2-4"},j={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.4",target:"_blank",rel:"noopener noreferrer"},B=e("ul",null,[e("li",null,"解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。"),e("li",null,"似乎这个版本没有什么改变,但这只是暴风雨前的宁静。"),e("li",null,[l("(没错我就是先知) "),e("blockquote",null,[e("p",null,"你个傻子,你拿的是 UNO 牌。")])])],-1),N=e("h2",{id:"_2021-01-25",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2021-01-25"},[e("span",null,"2021.01.25")])],-1),E=e("li",null,[e("a",{href:"../en"},"英文版文档网站"),l("逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!")],-1),I={id:"_2021-01-22-1-2-3",tabindex:"-1"},V={class:"header-anchor",href:"#_2021-01-22-1-2-3"},w={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.3",target:"_blank",rel:"noopener noreferrer"},G=e("li",null,[l("对 SS 协议的支持"),e("strong",null,"又"),l("变强了, 支持单端口多用户!")],-1),R=e("li",null,[l("对 trojan 协议的支持也"),e("strong",null,"又"),l("变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!")],-1),O=e("li",null,[e("em",null,"(VLESS: 嘤嘤嘤)")],-1),F=e("li",null,'UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".',-1),M=e("li",null,"嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.",-1),A=e("img",{src:"https://avatars2.githubusercontent.com/u/8384161?s=32",width:"32px",height:"32px",alt:"a"},null,-1),q={href:"https://github.com/bohanyang",target:"_blank",rel:"noopener noreferrer"},W=e("li",null,"其他美味小樱桃, 惯例更新品尝就对啦.",-1),Q=r('

                        2021.01.19

                        • 一些数字
                          • 版本发布了 10   个 tag
                          • 解决掉了 100  个 issue
                          • 复刻了 300  个 fork
                          • 点了 2000 个 star
                          • 群 3000 个 人

                        2021.01.17

                        ',3),Y=e("img",{src:"https://avatars2.githubusercontent.com/u/60207794?s=32",width:"32px",height:"32px",alt:"a"},null,-1),J={href:"https://github.com/jiuqi9997",target:"_blank",rel:"noopener noreferrer"},z={href:"https://xtls.github.io/en/",target:"_blank",rel:"noopener noreferrer"},K={id:"_2021-01-15-1-2-2",tabindex:"-1"},Z={class:"header-anchor",href:"#_2021-01-15-1-2-2"},$={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.2",target:"_blank",rel:"noopener noreferrer"},ee=r('
                        • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
                        • 之前预告的 UUID 修改正式上线.(往下看往下看)
                        • 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
                        • 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
                        • 当然还有其他各种小糖果.(更新品尝就对了)
                        • 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE

                        2021.01.12

                        ',2),le=e("li",null,[l("将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户. "),e("ul",null,[e("li",null,'客户端写 "id": "我爱 🍉 老师 1314",'),e("li",null,[l('服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 '),e("code",null,"我爱🍉老师1314"),l(" 的 UUID 映射)")])])],-1),ne={id:"_2021-01-10-1-2-1",tabindex:"-1"},te={class:"header-anchor",href:"#_2021-01-10-1-2-1"},oe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.1",target:"_blank",rel:"noopener noreferrer"},ae=e("li",null,"(可能是整个互联网上, 最详细最有耐心的教你从 0 开始配置的教程)",-1),re=e("li",null,"还有很多细节修改, 文档将会越来越规范!",-1),se={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},ie={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},he={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},_e=r('
                        • 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
                        • Google Voice 应该也可以正常使用 v2rayNG 拨打了.
                        • 日志现在看起来更顺眼.

                        2021.01.07

                        • 礼貌和尊重本应是社区不需要明说的准则之一。

                        2021.01.05

                        • 文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

                        2021.01.03

                        ',6),ce=e("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ue={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},de=e("li",null,"tg 群突破 2500。",-1),pe=e("h2",{id:"_2021-01-01",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2021-01-01"},[e("span",null,"2021.01.01")])],-1),fe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},be=e("p",null,"🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!",-1),ge=r('
                      22. 圣诞礼物v1.1.5后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
                      23. (UDP 还会继续增强!)
                      24. 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
                      25. (不,下面不是广告,是里程碑。)
                      26. Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
                        • 一人扛起了所有!支持各大主流协议!
                        • 一骑绝尘的性能!
                        • 日趋完善的功能!
                        • 可怕的生命力与社区亲和力!
                      27. ',5),me={href:"https://github.com/XTLS/Xray-core/discussions/56",target:"_blank",rel:"noopener noreferrer"},xe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},Xe=e("s",null,"(啊,有人敲门...我一会和你们说)",-1),Se=e("h2",{id:"_2020-12-29",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-29"},[e("span",null,"2020.12.29")])],-1),ke={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},ye={id:"_2020-12-25-1-1-5",tabindex:"-1"},ve={class:"header-anchor",href:"#_2020-12-25-1-1-5"},Te={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.5",target:"_blank",rel:"noopener noreferrer"},Le=e("p",null,"圣诞节快乐!",-1),De=e("li",null,"游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone",-1),Pe=e("li",null,"你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...",-1),Ue=e("li",null,"(VLESS 的 UDP fullcone 和更多增强很快就到!)",-1),He=e("li",null,"无须再担心证书验证被墙,OCSP stapling 已经上线!",-1),Ce={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},je=e("li",null,"还有更多美味小樱桃!(不用问,更新品尝就对了)",-1),Be=e("h2",{id:"_2020-12-24",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-24"},[e("span",null,"2020.12.24")])],-1),Ne={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},Ee=e("p",null,"大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)",-1),Ie={href:"https://github.com/XTLS/XTLS.github.io",target:"_blank",rel:"noopener noreferrer"},Ve=e("p",null,"仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站. 欢迎大家查看,纠错,修改,增加心得。",-1),we=e("h2",{id:"_2020-12-23",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-23"},[e("span",null,"2020.12.23")])],-1),Ge={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Re=e("h2",{id:"_2020-12-21",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-21"},[e("span",null,"2020.12.21")])],-1),Oe=e("ul",null,[e("li",null,"Project X 群人数 2000+"),e("li",null,"群消息(含游戏群) 日均破万")],-1),Fe={id:"_2020-12-18-1-1-4",tabindex:"-1"},Me={class:"header-anchor",href:"#_2020-12-18-1-1-4"},Ae={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.4",target:"_blank",rel:"noopener noreferrer"},qe=e("ul",null,[e("li",null,"更低的启动内占用和内存使用优化"),e("li",null,"随意定制的 TLS 提高你的 SSL 评级"),e("li",null,"支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS"),e("li",null,"还有在您路由器上使用的 Splice 最佳使用模式建议")],-1),We=e("h2",{id:"_2020-12-17",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-17"},[e("span",null,"2020.12.17")])],-1),Qe={href:"https://t.me/joinchat/UO4NixbB_XDQJOUjS6mHEQ",target:"_blank",rel:"noopener noreferrer"},Ye=e("h2",{id:"_2020-12-15",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-15"},[e("span",null,"2020.12.15")])],-1),Je={href:"https://github.com/XTLS/Xray-install/tree/dev",target:"_blank",rel:"noopener noreferrer"},ze={id:"_2020-12-11-1-1-3",tabindex:"-1"},Ke={class:"header-anchor",href:"#_2020-12-11-1-1-3"},Ze={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.3",target:"_blank",rel:"noopener noreferrer"},$e=e("ul",null,[e("li",null,"完整版本的 REDIRECT 透明代理模式."),e("li",null,"软路由 splice 流控模式的优化建议.")],-1),el={id:"_2020-12-06-1-1-2",tabindex:"-1"},ll={class:"header-anchor",href:"#_2020-12-06-1-1-2"},nl={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.2",target:"_blank",rel:"noopener noreferrer"},tl=r('
                        • 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
                        • 增强了 API 兼容

                        2020.12.04

                        增加 splice 模式

                        2020.11.27

                        • Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
                        • 登上了 GitHub Trending
                        • Project X 群人数破千,频道订阅数 500+
                        ',5),ol={id:"_2020-11-25-1-0-0",tabindex:"-1"},al={class:"header-anchor",href:"#_2020-11-25-1-0-0"},rl={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.0.0",target:"_blank",rel:"noopener noreferrer"},sl=e("p",null,"Xray 的第一个版本.",-1),il=e("ul",null,[e("li",null,"基于 v2ray-core 修改而来,改动较大"),e("li",null,"全面增强, 性能卓越, 完全兼容")],-1),hl=e("h2",{id:"_2020-11-23",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-11-23"},[e("span",null,"2020.11.23")])],-1),_l=e("p",null,"project X start",-1),cl=e("blockquote",null,[e("p",null,[e("s",null,"梦开始的时候")])],-1);function ul(dl,pl){const t=i("ExternalLinkIcon"),a=i("Badge"),s=i("RouterLink");return _(),c("div",null,[d,e("h2",p,[e("a",f,[e("span",null,[l("2021.4.1 "),n(a,null,{default:o(()=>[e("a",b,[l("v1.4.2"),n(t)])]),_:1})])])]),g,e("h2",m,[e("a",x,[e("span",null,[l("2021.3.14 "),n(a,null,{default:o(()=>[e("a",X,[l("v1.4.0"),n(t)])]),_:1})])])]),S,e("h2",k,[e("a",y,[e("span",null,[l("2021.3.3 "),n(a,null,{default:o(()=>[e("a",v,[l("1.3.1"),n(t)])]),_:1})])])]),T,e("h2",L,[e("a",D,[e("span",null,[l("2021.2.14 "),n(a,null,{default:o(()=>[e("a",P,[l("1.3.0"),n(t)])]),_:1})])])]),U,e("h2",H,[e("a",C,[e("span",null,[l("2021.01.31 "),n(a,null,{default:o(()=>[e("a",j,[l("1.2.4"),n(t)])]),_:1})])])]),B,N,e("ul",null,[e("li",null,[l("全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载"),n(s,{to:"/en/document/level-1/"},{default:o(()=>[l("秘籍第一层")]),_:1}),l("咯...")]),E]),e("h2",I,[e("a",V,[e("span",null,[l("2021.01.22 "),n(a,null,{default:o(()=>[e("a",w,[l("1.2.3"),n(t)])]),_:1})])])]),e("ul",null,[G,R,O,F,M,e("li",null,[l("向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 "),A,l(),e("a",q,[l("@Bohan Yang"),n(t)]),l(" 致敬!")]),W]),Q,e("ul",null,[e("li",null,[l("辛苦的翻译工作开始了, 感谢"),Y,l(),e("a",J,[l("@玖柒 Max"),n(t)]),l("和其他所有的翻译大佬们.")]),e("li",null,[e("a",z,[l("English version"),n(t)])])]),e("h2",K,[e("a",Z,[e("span",null,[l("2021.01.15 "),n(a,null,{default:o(()=>[e("a",$,[l("1.2.2"),n(t)])]),_:1})])])]),ee,e("ul",null,[le,e("li",null,[l("🍉 老师的"),n(s,{to:"/en/document/level-0/"},{default:o(()=>[l("小小白白话文")]),_:1}),l("大结局, 撒花.")])]),e("h2",ne,[e("a",te,[e("span",null,[l("2021.01.10 "),n(a,null,{default:o(()=>[e("a",oe,[l("1.2.1"),n(t)])]),_:1})])])]),e("ul",null,[e("li",null,[n(s,{to:"/en/document/level-0/"},{default:o(()=>[l("小小白白话文")]),_:1}),l("连载上线啦,🍉 老师呕心沥血之作, 手把手教你从什么都不会到熟练配置 Xray!")]),ae,e("li",null,[n(s,{to:"/en/document/level-2/"},{default:o(()=>[l("透明代理")]),_:1}),l("也增加了更多文章.")]),re,e("li",null,[l("感谢 "),e("a",se,[l("@ricuhkaen"),n(t)]),l(" , "),e("a",ie,[l("@BioniCosmos"),n(t)]),l(", "),e("a",he,[l("@kirin"),n(t)])])]),_e,e("ul",null,[e("li",null,[l("文档仓库第一个 PR。🎉 "),n(s,{to:"/en/document/level-2/tproxy.html"},{default:o(()=>[l("透明代理(TProxy)配置教程 ")]),_:1}),l(" ,感谢"),ce,l(),e("a",ue,[l("@BioniCosmos"),n(t)])]),de]),pe,e("p",null,[l("【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 "),n(a,null,{default:o(()=>[e("a",fe,[l("1.2.0"),n(t)])]),_:1})]),be,e("ul",null,[ge,e("li",null,[l("Xray 将继续保持前行! 因此 "),e("a",me,[l("Xray 需要更多的英雄!!"),n(t)]),l("!")]),e("li",null,[l("PS:请品,请细品"),e("a",xe,[l("release notes"),n(t)]),l("每一句。似乎有一个小秘密小彩蛋 "),Xe])]),Se,e("p",null,[l("透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, "),e("a",ke,[l("TG 群"),n(t)]),l("火热测试中")]),e("h2",ye,[e("a",ve,[e("span",null,[l("2020.12.25 "),n(a,null,{default:o(()=>[e("a",Te,[l("1.1.5"),n(t)])]),_:1})])])]),Le,e("ul",null,[De,Pe,Ue,He,e("li",null,[l("kirin 带来了一大波 脚本更新."),e("a",Ce,[l("脚本在此"),n(t)])]),je]),Be,e("p",null,[l("因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。 网址为:"),e("a",Ne,[l("没错你正在看的就是"),n(t)])]),Ee,e("p",null,[l("文档网站需要不断完善和增加内容,以及完善设计。 因此更欢迎大家一起为文档建设添砖加瓦。 "),e("a",Ie,[l("文档的仓库"),n(t)])]),Ve,we,e("p",null,[l("Xray-core Shadowsocks UDP FullCone 测试版, "),e("a",Ge,[l("TG 群"),n(t)]),l("火热测试中")]),Re,Oe,e("h2",Fe,[e("a",Me,[e("span",null,[l("2020.12.18 "),n(a,null,{default:o(()=>[e("a",Ae,[l("1.1.4"),n(t)])]),_:1})])])]),qe,We,e("p",null,[l("鉴于日益增长群人数和游戏需求, 开启了"),e("a",Qe,[l("TG 游戏群"),n(t)])]),Ye,e("p",null,[e("a",Je,[l("安装脚本 dev 分支"),n(t)]),l("开启, 持续更新功能中.")]),e("h2",ze,[e("a",Ke,[e("span",null,[l("2020.12.11 "),n(a,null,{default:o(()=>[e("a",Ze,[l("1.1.3"),n(t)])]),_:1})])])]),$e,e("h2",el,[e("a",ll,[e("span",null,[l("2020.12.06 "),n(a,null,{default:o(()=>[e("a",nl,[l("1.1.2"),n(t)])]),_:1})])])]),tl,e("h2",ol,[e("a",al,[e("span",null,[l("2020.11.25 "),n(a,null,{default:o(()=>[e("a",rl,[l("1.0.0"),n(t)])]),_:1})])])]),sl,il,hl,_l,cl])}const bl=h(u,[["render",ul],["__file","news.html.vue"]]);export{bl as default}; diff --git a/assets/news.html-Symbtc2m.js b/assets/news.html-ayZea3Z8.js similarity index 99% rename from assets/news.html-Symbtc2m.js rename to assets/news.html-ayZea3Z8.js index affc938522..e5fd73acf0 100644 --- a/assets/news.html-Symbtc2m.js +++ b/assets/news.html-ayZea3Z8.js @@ -1 +1 @@ -import{_ as h,r as i,o as _,c,a as e,b as l,d as n,w as o,e as r}from"./app-PDrbPfzp.js";const u={},d=r('

                        大史记

                        2021.4.6

                        • VuePress Next.
                        • With Dark Mode.

                        2021.4.4

                        • 本文档迎来的新的首页。
                        • 本文档迎来了暗黑模式。
                        • 当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。
                        • 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
                        • 🎉🎉🎉
                        ',5),p={id:"_2021-4-1-v1-4-2",tabindex:"-1"},f={class:"header-anchor",href:"#_2021-4-1-v1-4-2"},b={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.2",target:"_blank",rel:"noopener noreferrer"},g=r('
                        • 不是愚人节玩笑,今天更新。
                        • 加入 Browser Dialer,用与改变 TLS 指纹与行为。
                        • 加入 uTLS,用与改变 TLS Client Hello 的指纹。
                        • 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。

                        2021.3.25

                        没错还在变。 -_-

                        2021.3.15

                        文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

                        ',5),m={id:"_2021-3-14-v1-4-0",tabindex:"-1"},x={class:"header-anchor",href:"#_2021-3-14-v1-4-0"},X={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.0",target:"_blank",rel:"noopener noreferrer"},S=r("
                        • Happy Pi-Day!
                        • 这次是个大更新:
                          • 为链式代理引入了传输层支持。
                          • 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
                          • 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
                          • 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
                          • 添加了 FakeDNS。
                          • 还修复了系列的问题,添加了各类功能,详情请见更新日志。
                        • 还是 VuePress 比较爽啊(
                        ",1),k={id:"_2021-3-3-1-3-1",tabindex:"-1"},y={class:"header-anchor",href:"#_2021-3-3-1-3-1"},v={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.1",target:"_blank",rel:"noopener noreferrer"},T=e("ul",null,[e("li",null,"这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。"),e("li",null,[l("同时修复了一个会导致 Panic 的 bug。"),e("s",null,"Holmium_认为这是在骗、在偷袭。")]),e("li",null,"修复了几个遗留问题。")],-1),L={id:"_2021-2-14-1-3-0",tabindex:"-1"},D={class:"header-anchor",href:"#_2021-2-14-1-3-0"},P={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.0",target:"_blank",rel:"noopener noreferrer"},U=e("ul",null,[e("li",null,"Happy 🐮 Year 🎉!"),e("li",null,"v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。"),e("li",null,"OHHHHHHHHHHHH!")],-1),H={id:"_2021-01-31-1-2-4",tabindex:"-1"},C={class:"header-anchor",href:"#_2021-01-31-1-2-4"},j={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.4",target:"_blank",rel:"noopener noreferrer"},B=e("ul",null,[e("li",null,"解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。"),e("li",null,"似乎这个版本没有什么改变,但这只是暴风雨前的宁静。"),e("li",null,[l("(没错我就是先知) "),e("blockquote",null,[e("p",null,"你个傻子,你拿的是 UNO 牌。")])])],-1),N=e("h2",{id:"_2021-01-25",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2021-01-25"},[e("span",null,"2021.01.25")])],-1),E=e("li",null,[e("a",{href:"../en"},"英文版文档网站"),l("逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!")],-1),I={id:"_2021-01-22-1-2-3",tabindex:"-1"},V={class:"header-anchor",href:"#_2021-01-22-1-2-3"},w={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.3",target:"_blank",rel:"noopener noreferrer"},G=e("li",null,[l("对 SS 协议的支持"),e("strong",null,"又"),l("变强了, 支持单端口多用户!")],-1),R=e("li",null,[l("对 trojan 协议的支持也"),e("strong",null,"又"),l("变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!")],-1),O=e("li",null,[e("em",null,"(VLESS: 嘤嘤嘤)")],-1),F=e("li",null,'UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".',-1),M=e("li",null,"嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.",-1),A=e("img",{src:"https://avatars2.githubusercontent.com/u/8384161?s=32",width:"32px",height:"32px",alt:"a"},null,-1),q={href:"https://github.com/bohanyang",target:"_blank",rel:"noopener noreferrer"},W=e("li",null,"其他美味小樱桃, 惯例更新品尝就对啦.",-1),Q=r('

                        2021.01.19

                        • 一些数字
                          • 版本发布了 10   个 tag
                          • 解决掉了 100  个 issue
                          • 复刻了 300  个 fork
                          • 点了 2000 个 star
                          • 群 3000 个 人

                        2021.01.17

                        ',3),Y=e("img",{src:"https://avatars2.githubusercontent.com/u/60207794?s=32",width:"32px",height:"32px",alt:"a"},null,-1),J={href:"https://github.com/jiuqi9997",target:"_blank",rel:"noopener noreferrer"},z={href:"https://xtls.github.io/en/",target:"_blank",rel:"noopener noreferrer"},K={id:"_2021-01-15-1-2-2",tabindex:"-1"},Z={class:"header-anchor",href:"#_2021-01-15-1-2-2"},$={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.2",target:"_blank",rel:"noopener noreferrer"},ee=r('
                        • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
                        • 之前预告的 UUID 修改正式上线.(往下看往下看)
                        • 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
                        • 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
                        • 当然还有其他各种小糖果.(更新品尝就对了)
                        • 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE

                        2021.01.12

                        ',2),le=e("li",null,[l("将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户. "),e("ul",null,[e("li",null,'客户端写 "id": "我爱 🍉 老师 1314",'),e("li",null,[l('服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 '),e("code",null,"我爱🍉老师1314"),l(" 的 UUID 映射)")])])],-1),ne={id:"_2021-01-10-1-2-1",tabindex:"-1"},te={class:"header-anchor",href:"#_2021-01-10-1-2-1"},oe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.1",target:"_blank",rel:"noopener noreferrer"},ae=e("li",null,"(可能是整个互联网上, 最详细最有耐心的教你从 0 开始配置的教程)",-1),re=e("li",null,"还有很多细节修改, 文档将会越来越规范!",-1),se={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},ie={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},he={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},_e=r('
                        • 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
                        • Google Voice 应该也可以正常使用 v2rayNG 拨打了.
                        • 日志现在看起来更顺眼.

                        2021.01.07

                        • 礼貌和尊重本应是社区不需要明说的准则之一。

                        2021.01.05

                        • 文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

                        2021.01.03

                        ',6),ce=e("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ue={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},de=e("li",null,"tg 群突破 2500。",-1),pe=e("h2",{id:"_2021-01-01",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2021-01-01"},[e("span",null,"2021.01.01")])],-1),fe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},be=e("p",null,"🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!",-1),ge=r('
                      28. 圣诞礼物v1.1.5后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
                      29. (UDP 还会继续增强!)
                      30. 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
                      31. (不,下面不是广告,是里程碑。)
                      32. Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
                        • 一人扛起了所有!支持各大主流协议!
                        • 一骑绝尘的性能!
                        • 日趋完善的功能!
                        • 可怕的生命力与社区亲和力!
                      33. ',5),me={href:"https://github.com/XTLS/Xray-core/discussions/56",target:"_blank",rel:"noopener noreferrer"},xe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},Xe=e("s",null,"(啊,有人敲门...我一会和你们说)",-1),Se=e("h2",{id:"_2020-12-29",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-29"},[e("span",null,"2020.12.29")])],-1),ke={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},ye={id:"_2020-12-25-1-1-5",tabindex:"-1"},ve={class:"header-anchor",href:"#_2020-12-25-1-1-5"},Te={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.5",target:"_blank",rel:"noopener noreferrer"},Le=e("p",null,"圣诞节快乐!",-1),De=e("li",null,"游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone",-1),Pe=e("li",null,"你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...",-1),Ue=e("li",null,"(VLESS 的 UDP fullcone 和更多增强很快就到!)",-1),He=e("li",null,"无须再担心证书验证被墙,OCSP stapling 已经上线!",-1),Ce={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},je=e("li",null,"还有更多美味小樱桃!(不用问,更新品尝就对了)",-1),Be=e("h2",{id:"_2020-12-24",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-24"},[e("span",null,"2020.12.24")])],-1),Ne={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},Ee=e("p",null,"大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)",-1),Ie={href:"https://github.com/XTLS/XTLS.github.io",target:"_blank",rel:"noopener noreferrer"},Ve=e("p",null,"仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站. 欢迎大家查看,纠错,修改,增加心得。",-1),we=e("h2",{id:"_2020-12-23",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-23"},[e("span",null,"2020.12.23")])],-1),Ge={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Re=e("h2",{id:"_2020-12-21",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-21"},[e("span",null,"2020.12.21")])],-1),Oe=e("ul",null,[e("li",null,"Project X 群人数 2000+"),e("li",null,"群消息(含游戏群) 日均破万")],-1),Fe={id:"_2020-12-18-1-1-4",tabindex:"-1"},Me={class:"header-anchor",href:"#_2020-12-18-1-1-4"},Ae={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.4",target:"_blank",rel:"noopener noreferrer"},qe=e("ul",null,[e("li",null,"更低的启动内占用和内存使用优化"),e("li",null,"随意定制的 TLS 提高你的 SSL 评级"),e("li",null,"支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS"),e("li",null,"还有在您路由器上使用的 Splice 最佳使用模式建议")],-1),We=e("h2",{id:"_2020-12-17",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-17"},[e("span",null,"2020.12.17")])],-1),Qe={href:"https://t.me/joinchat/UO4NixbB_XDQJOUjS6mHEQ",target:"_blank",rel:"noopener noreferrer"},Ye=e("h2",{id:"_2020-12-15",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-15"},[e("span",null,"2020.12.15")])],-1),Je={href:"https://github.com/XTLS/Xray-install/tree/dev",target:"_blank",rel:"noopener noreferrer"},ze={id:"_2020-12-11-1-1-3",tabindex:"-1"},Ke={class:"header-anchor",href:"#_2020-12-11-1-1-3"},Ze={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.3",target:"_blank",rel:"noopener noreferrer"},$e=e("ul",null,[e("li",null,"完整版本的 REDIRECT 透明代理模式."),e("li",null,"软路由 splice 流控模式的优化建议.")],-1),el={id:"_2020-12-06-1-1-2",tabindex:"-1"},ll={class:"header-anchor",href:"#_2020-12-06-1-1-2"},nl={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.2",target:"_blank",rel:"noopener noreferrer"},tl=r('
                        • 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
                        • 增强了 API 兼容

                        2020.12.04

                        增加 splice 模式

                        2020.11.27

                        • Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
                        • 登上了 GitHub Trending
                        • Project X 群人数破千,频道订阅数 500+
                        ',5),ol={id:"_2020-11-25-1-0-0",tabindex:"-1"},al={class:"header-anchor",href:"#_2020-11-25-1-0-0"},rl={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.0.0",target:"_blank",rel:"noopener noreferrer"},sl=e("p",null,"Xray 的第一个版本.",-1),il=e("ul",null,[e("li",null,"基于 v2ray-core 修改而来,改动较大"),e("li",null,"全面增强, 性能卓越, 完全兼容")],-1),hl=e("h2",{id:"_2020-11-23",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-11-23"},[e("span",null,"2020.11.23")])],-1),_l=e("p",null,"project X start",-1),cl=e("blockquote",null,[e("p",null,[e("s",null,"梦开始的时候")])],-1);function ul(dl,pl){const t=i("ExternalLinkIcon"),a=i("Badge"),s=i("RouterLink");return _(),c("div",null,[d,e("h2",p,[e("a",f,[e("span",null,[l("2021.4.1 "),n(a,null,{default:o(()=>[e("a",b,[l("v1.4.2"),n(t)])]),_:1})])])]),g,e("h2",m,[e("a",x,[e("span",null,[l("2021.3.14 "),n(a,null,{default:o(()=>[e("a",X,[l("v1.4.0"),n(t)])]),_:1})])])]),S,e("h2",k,[e("a",y,[e("span",null,[l("2021.3.3 "),n(a,null,{default:o(()=>[e("a",v,[l("1.3.1"),n(t)])]),_:1})])])]),T,e("h2",L,[e("a",D,[e("span",null,[l("2021.2.14 "),n(a,null,{default:o(()=>[e("a",P,[l("1.3.0"),n(t)])]),_:1})])])]),U,e("h2",H,[e("a",C,[e("span",null,[l("2021.01.31 "),n(a,null,{default:o(()=>[e("a",j,[l("1.2.4"),n(t)])]),_:1})])])]),B,N,e("ul",null,[e("li",null,[l("全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载"),n(s,{to:"/document/level-1/"},{default:o(()=>[l("秘籍第一层")]),_:1}),l("咯...")]),E]),e("h2",I,[e("a",V,[e("span",null,[l("2021.01.22 "),n(a,null,{default:o(()=>[e("a",w,[l("1.2.3"),n(t)])]),_:1})])])]),e("ul",null,[G,R,O,F,M,e("li",null,[l("向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 "),A,l(),e("a",q,[l("@Bohan Yang"),n(t)]),l(" 致敬!")]),W]),Q,e("ul",null,[e("li",null,[l("辛苦的翻译工作开始了, 感谢"),Y,l(),e("a",J,[l("@玖柒 Max"),n(t)]),l("和其他所有的翻译大佬们.")]),e("li",null,[e("a",z,[l("English version"),n(t)])])]),e("h2",K,[e("a",Z,[e("span",null,[l("2021.01.15 "),n(a,null,{default:o(()=>[e("a",$,[l("1.2.2"),n(t)])]),_:1})])])]),ee,e("ul",null,[le,e("li",null,[l("🍉 老师的"),n(s,{to:"/document/level-0/"},{default:o(()=>[l("小小白白话文")]),_:1}),l("大结局, 撒花.")])]),e("h2",ne,[e("a",te,[e("span",null,[l("2021.01.10 "),n(a,null,{default:o(()=>[e("a",oe,[l("1.2.1"),n(t)])]),_:1})])])]),e("ul",null,[e("li",null,[n(s,{to:"/document/level-0/"},{default:o(()=>[l("小小白白话文")]),_:1}),l("连载上线啦,🍉 老师呕心沥血之作, 手把手教你从什么都不会到熟练配置 Xray!")]),ae,e("li",null,[n(s,{to:"/document/level-2/"},{default:o(()=>[l("透明代理")]),_:1}),l("也增加了更多文章.")]),re,e("li",null,[l("感谢 "),e("a",se,[l("@ricuhkaen"),n(t)]),l(" , "),e("a",ie,[l("@BioniCosmos"),n(t)]),l(", "),e("a",he,[l("@kirin"),n(t)])])]),_e,e("ul",null,[e("li",null,[l("文档仓库第一个 PR。🎉 "),n(s,{to:"/document/level-2/tproxy.html"},{default:o(()=>[l("透明代理(TProxy)配置教程 ")]),_:1}),l(" ,感谢"),ce,l(),e("a",ue,[l("@BioniCosmos"),n(t)])]),de]),pe,e("p",null,[l("【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 "),n(a,null,{default:o(()=>[e("a",fe,[l("1.2.0"),n(t)])]),_:1})]),be,e("ul",null,[ge,e("li",null,[l("Xray 将继续保持前行! 因此 "),e("a",me,[l("Xray 需要更多的英雄!!"),n(t)]),l("!")]),e("li",null,[l("PS:请品,请细品"),e("a",xe,[l("release notes"),n(t)]),l("每一句。似乎有一个小秘密小彩蛋 "),Xe])]),Se,e("p",null,[l("透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, "),e("a",ke,[l("TG 群"),n(t)]),l("火热测试中")]),e("h2",ye,[e("a",ve,[e("span",null,[l("2020.12.25 "),n(a,null,{default:o(()=>[e("a",Te,[l("1.1.5"),n(t)])]),_:1})])])]),Le,e("ul",null,[De,Pe,Ue,He,e("li",null,[l("kirin 带来了一大波 脚本更新."),e("a",Ce,[l("脚本在此"),n(t)])]),je]),Be,e("p",null,[l("因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。 网址为:"),e("a",Ne,[l("没错你正在看的就是"),n(t)])]),Ee,e("p",null,[l("文档网站需要不断完善和增加内容,以及完善设计。 因此更欢迎大家一起为文档建设添砖加瓦。 "),e("a",Ie,[l("文档的仓库"),n(t)])]),Ve,we,e("p",null,[l("Xray-core Shadowsocks UDP FullCone 测试版, "),e("a",Ge,[l("TG 群"),n(t)]),l("火热测试中")]),Re,Oe,e("h2",Fe,[e("a",Me,[e("span",null,[l("2020.12.18 "),n(a,null,{default:o(()=>[e("a",Ae,[l("1.1.4"),n(t)])]),_:1})])])]),qe,We,e("p",null,[l("鉴于日益增长群人数和游戏需求, 开启了"),e("a",Qe,[l("TG 游戏群"),n(t)])]),Ye,e("p",null,[e("a",Je,[l("安装脚本 dev 分支"),n(t)]),l("开启, 持续更新功能中.")]),e("h2",ze,[e("a",Ke,[e("span",null,[l("2020.12.11 "),n(a,null,{default:o(()=>[e("a",Ze,[l("1.1.3"),n(t)])]),_:1})])])]),$e,e("h2",el,[e("a",ll,[e("span",null,[l("2020.12.06 "),n(a,null,{default:o(()=>[e("a",nl,[l("1.1.2"),n(t)])]),_:1})])])]),tl,e("h2",ol,[e("a",al,[e("span",null,[l("2020.11.25 "),n(a,null,{default:o(()=>[e("a",rl,[l("1.0.0"),n(t)])]),_:1})])])]),sl,il,hl,_l,cl])}const bl=h(u,[["render",ul],["__file","news.html.vue"]]);export{bl as default}; +import{_ as h,r as i,o as _,c,a as e,b as l,d as n,w as o,e as r}from"./app-UOvWaKji.js";const u={},d=r('

                        大史记

                        2021.4.6

                        • VuePress Next.
                        • With Dark Mode.

                        2021.4.4

                        • 本文档迎来的新的首页。
                        • 本文档迎来了暗黑模式。
                        • 当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。
                        • 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
                        • 🎉🎉🎉
                        ',5),p={id:"_2021-4-1-v1-4-2",tabindex:"-1"},f={class:"header-anchor",href:"#_2021-4-1-v1-4-2"},b={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.2",target:"_blank",rel:"noopener noreferrer"},g=r('
                        • 不是愚人节玩笑,今天更新。
                        • 加入 Browser Dialer,用与改变 TLS 指纹与行为。
                        • 加入 uTLS,用与改变 TLS Client Hello 的指纹。
                        • 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。

                        2021.3.25

                        没错还在变。 -_-

                        2021.3.15

                        文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

                        ',5),m={id:"_2021-3-14-v1-4-0",tabindex:"-1"},x={class:"header-anchor",href:"#_2021-3-14-v1-4-0"},X={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.0",target:"_blank",rel:"noopener noreferrer"},S=r("
                        • Happy Pi-Day!
                        • 这次是个大更新:
                          • 为链式代理引入了传输层支持。
                          • 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
                          • 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
                          • 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
                          • 添加了 FakeDNS。
                          • 还修复了系列的问题,添加了各类功能,详情请见更新日志。
                        • 还是 VuePress 比较爽啊(
                        ",1),k={id:"_2021-3-3-1-3-1",tabindex:"-1"},y={class:"header-anchor",href:"#_2021-3-3-1-3-1"},v={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.1",target:"_blank",rel:"noopener noreferrer"},T=e("ul",null,[e("li",null,"这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。"),e("li",null,[l("同时修复了一个会导致 Panic 的 bug。"),e("s",null,"Holmium_认为这是在骗、在偷袭。")]),e("li",null,"修复了几个遗留问题。")],-1),L={id:"_2021-2-14-1-3-0",tabindex:"-1"},D={class:"header-anchor",href:"#_2021-2-14-1-3-0"},P={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.0",target:"_blank",rel:"noopener noreferrer"},U=e("ul",null,[e("li",null,"Happy 🐮 Year 🎉!"),e("li",null,"v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。"),e("li",null,"OHHHHHHHHHHHH!")],-1),H={id:"_2021-01-31-1-2-4",tabindex:"-1"},C={class:"header-anchor",href:"#_2021-01-31-1-2-4"},j={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.4",target:"_blank",rel:"noopener noreferrer"},B=e("ul",null,[e("li",null,"解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。"),e("li",null,"似乎这个版本没有什么改变,但这只是暴风雨前的宁静。"),e("li",null,[l("(没错我就是先知) "),e("blockquote",null,[e("p",null,"你个傻子,你拿的是 UNO 牌。")])])],-1),N=e("h2",{id:"_2021-01-25",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2021-01-25"},[e("span",null,"2021.01.25")])],-1),E=e("li",null,[e("a",{href:"../en"},"英文版文档网站"),l("逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!")],-1),I={id:"_2021-01-22-1-2-3",tabindex:"-1"},V={class:"header-anchor",href:"#_2021-01-22-1-2-3"},w={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.3",target:"_blank",rel:"noopener noreferrer"},G=e("li",null,[l("对 SS 协议的支持"),e("strong",null,"又"),l("变强了, 支持单端口多用户!")],-1),R=e("li",null,[l("对 trojan 协议的支持也"),e("strong",null,"又"),l("变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!")],-1),O=e("li",null,[e("em",null,"(VLESS: 嘤嘤嘤)")],-1),F=e("li",null,'UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".',-1),M=e("li",null,"嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.",-1),A=e("img",{src:"https://avatars2.githubusercontent.com/u/8384161?s=32",width:"32px",height:"32px",alt:"a"},null,-1),q={href:"https://github.com/bohanyang",target:"_blank",rel:"noopener noreferrer"},W=e("li",null,"其他美味小樱桃, 惯例更新品尝就对啦.",-1),Q=r('

                        2021.01.19

                        • 一些数字
                          • 版本发布了 10   个 tag
                          • 解决掉了 100  个 issue
                          • 复刻了 300  个 fork
                          • 点了 2000 个 star
                          • 群 3000 个 人

                        2021.01.17

                        ',3),Y=e("img",{src:"https://avatars2.githubusercontent.com/u/60207794?s=32",width:"32px",height:"32px",alt:"a"},null,-1),J={href:"https://github.com/jiuqi9997",target:"_blank",rel:"noopener noreferrer"},z={href:"https://xtls.github.io/en/",target:"_blank",rel:"noopener noreferrer"},K={id:"_2021-01-15-1-2-2",tabindex:"-1"},Z={class:"header-anchor",href:"#_2021-01-15-1-2-2"},$={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.2",target:"_blank",rel:"noopener noreferrer"},ee=r('
                        • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
                        • 之前预告的 UUID 修改正式上线.(往下看往下看)
                        • 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
                        • 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
                        • 当然还有其他各种小糖果.(更新品尝就对了)
                        • 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE

                        2021.01.12

                        ',2),le=e("li",null,[l("将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户. "),e("ul",null,[e("li",null,'客户端写 "id": "我爱 🍉 老师 1314",'),e("li",null,[l('服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 '),e("code",null,"我爱🍉老师1314"),l(" 的 UUID 映射)")])])],-1),ne={id:"_2021-01-10-1-2-1",tabindex:"-1"},te={class:"header-anchor",href:"#_2021-01-10-1-2-1"},oe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.1",target:"_blank",rel:"noopener noreferrer"},ae=e("li",null,"(可能是整个互联网上, 最详细最有耐心的教你从 0 开始配置的教程)",-1),re=e("li",null,"还有很多细节修改, 文档将会越来越规范!",-1),se={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},ie={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},he={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},_e=r('
                        • 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
                        • Google Voice 应该也可以正常使用 v2rayNG 拨打了.
                        • 日志现在看起来更顺眼.

                        2021.01.07

                        • 礼貌和尊重本应是社区不需要明说的准则之一。

                        2021.01.05

                        • 文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

                        2021.01.03

                        ',6),ce=e("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ue={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},de=e("li",null,"tg 群突破 2500。",-1),pe=e("h2",{id:"_2021-01-01",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2021-01-01"},[e("span",null,"2021.01.01")])],-1),fe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},be=e("p",null,"🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!",-1),ge=r('
                      34. 圣诞礼物v1.1.5后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
                      35. (UDP 还会继续增强!)
                      36. 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
                      37. (不,下面不是广告,是里程碑。)
                      38. Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
                        • 一人扛起了所有!支持各大主流协议!
                        • 一骑绝尘的性能!
                        • 日趋完善的功能!
                        • 可怕的生命力与社区亲和力!
                      39. ',5),me={href:"https://github.com/XTLS/Xray-core/discussions/56",target:"_blank",rel:"noopener noreferrer"},xe={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},Xe=e("s",null,"(啊,有人敲门...我一会和你们说)",-1),Se=e("h2",{id:"_2020-12-29",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-29"},[e("span",null,"2020.12.29")])],-1),ke={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},ye={id:"_2020-12-25-1-1-5",tabindex:"-1"},ve={class:"header-anchor",href:"#_2020-12-25-1-1-5"},Te={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.5",target:"_blank",rel:"noopener noreferrer"},Le=e("p",null,"圣诞节快乐!",-1),De=e("li",null,"游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone",-1),Pe=e("li",null,"你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...",-1),Ue=e("li",null,"(VLESS 的 UDP fullcone 和更多增强很快就到!)",-1),He=e("li",null,"无须再担心证书验证被墙,OCSP stapling 已经上线!",-1),Ce={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},je=e("li",null,"还有更多美味小樱桃!(不用问,更新品尝就对了)",-1),Be=e("h2",{id:"_2020-12-24",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-24"},[e("span",null,"2020.12.24")])],-1),Ne={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},Ee=e("p",null,"大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)",-1),Ie={href:"https://github.com/XTLS/XTLS.github.io",target:"_blank",rel:"noopener noreferrer"},Ve=e("p",null,"仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站. 欢迎大家查看,纠错,修改,增加心得。",-1),we=e("h2",{id:"_2020-12-23",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-23"},[e("span",null,"2020.12.23")])],-1),Ge={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Re=e("h2",{id:"_2020-12-21",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-21"},[e("span",null,"2020.12.21")])],-1),Oe=e("ul",null,[e("li",null,"Project X 群人数 2000+"),e("li",null,"群消息(含游戏群) 日均破万")],-1),Fe={id:"_2020-12-18-1-1-4",tabindex:"-1"},Me={class:"header-anchor",href:"#_2020-12-18-1-1-4"},Ae={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.4",target:"_blank",rel:"noopener noreferrer"},qe=e("ul",null,[e("li",null,"更低的启动内占用和内存使用优化"),e("li",null,"随意定制的 TLS 提高你的 SSL 评级"),e("li",null,"支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS"),e("li",null,"还有在您路由器上使用的 Splice 最佳使用模式建议")],-1),We=e("h2",{id:"_2020-12-17",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-17"},[e("span",null,"2020.12.17")])],-1),Qe={href:"https://t.me/joinchat/UO4NixbB_XDQJOUjS6mHEQ",target:"_blank",rel:"noopener noreferrer"},Ye=e("h2",{id:"_2020-12-15",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-12-15"},[e("span",null,"2020.12.15")])],-1),Je={href:"https://github.com/XTLS/Xray-install/tree/dev",target:"_blank",rel:"noopener noreferrer"},ze={id:"_2020-12-11-1-1-3",tabindex:"-1"},Ke={class:"header-anchor",href:"#_2020-12-11-1-1-3"},Ze={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.3",target:"_blank",rel:"noopener noreferrer"},$e=e("ul",null,[e("li",null,"完整版本的 REDIRECT 透明代理模式."),e("li",null,"软路由 splice 流控模式的优化建议.")],-1),el={id:"_2020-12-06-1-1-2",tabindex:"-1"},ll={class:"header-anchor",href:"#_2020-12-06-1-1-2"},nl={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.2",target:"_blank",rel:"noopener noreferrer"},tl=r('
                        • 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
                        • 增强了 API 兼容

                        2020.12.04

                        增加 splice 模式

                        2020.11.27

                        • Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
                        • 登上了 GitHub Trending
                        • Project X 群人数破千,频道订阅数 500+
                        ',5),ol={id:"_2020-11-25-1-0-0",tabindex:"-1"},al={class:"header-anchor",href:"#_2020-11-25-1-0-0"},rl={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.0.0",target:"_blank",rel:"noopener noreferrer"},sl=e("p",null,"Xray 的第一个版本.",-1),il=e("ul",null,[e("li",null,"基于 v2ray-core 修改而来,改动较大"),e("li",null,"全面增强, 性能卓越, 完全兼容")],-1),hl=e("h2",{id:"_2020-11-23",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2020-11-23"},[e("span",null,"2020.11.23")])],-1),_l=e("p",null,"project X start",-1),cl=e("blockquote",null,[e("p",null,[e("s",null,"梦开始的时候")])],-1);function ul(dl,pl){const t=i("ExternalLinkIcon"),a=i("Badge"),s=i("RouterLink");return _(),c("div",null,[d,e("h2",p,[e("a",f,[e("span",null,[l("2021.4.1 "),n(a,null,{default:o(()=>[e("a",b,[l("v1.4.2"),n(t)])]),_:1})])])]),g,e("h2",m,[e("a",x,[e("span",null,[l("2021.3.14 "),n(a,null,{default:o(()=>[e("a",X,[l("v1.4.0"),n(t)])]),_:1})])])]),S,e("h2",k,[e("a",y,[e("span",null,[l("2021.3.3 "),n(a,null,{default:o(()=>[e("a",v,[l("1.3.1"),n(t)])]),_:1})])])]),T,e("h2",L,[e("a",D,[e("span",null,[l("2021.2.14 "),n(a,null,{default:o(()=>[e("a",P,[l("1.3.0"),n(t)])]),_:1})])])]),U,e("h2",H,[e("a",C,[e("span",null,[l("2021.01.31 "),n(a,null,{default:o(()=>[e("a",j,[l("1.2.4"),n(t)])]),_:1})])])]),B,N,e("ul",null,[e("li",null,[l("全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载"),n(s,{to:"/document/level-1/"},{default:o(()=>[l("秘籍第一层")]),_:1}),l("咯...")]),E]),e("h2",I,[e("a",V,[e("span",null,[l("2021.01.22 "),n(a,null,{default:o(()=>[e("a",w,[l("1.2.3"),n(t)])]),_:1})])])]),e("ul",null,[G,R,O,F,M,e("li",null,[l("向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 "),A,l(),e("a",q,[l("@Bohan Yang"),n(t)]),l(" 致敬!")]),W]),Q,e("ul",null,[e("li",null,[l("辛苦的翻译工作开始了, 感谢"),Y,l(),e("a",J,[l("@玖柒 Max"),n(t)]),l("和其他所有的翻译大佬们.")]),e("li",null,[e("a",z,[l("English version"),n(t)])])]),e("h2",K,[e("a",Z,[e("span",null,[l("2021.01.15 "),n(a,null,{default:o(()=>[e("a",$,[l("1.2.2"),n(t)])]),_:1})])])]),ee,e("ul",null,[le,e("li",null,[l("🍉 老师的"),n(s,{to:"/document/level-0/"},{default:o(()=>[l("小小白白话文")]),_:1}),l("大结局, 撒花.")])]),e("h2",ne,[e("a",te,[e("span",null,[l("2021.01.10 "),n(a,null,{default:o(()=>[e("a",oe,[l("1.2.1"),n(t)])]),_:1})])])]),e("ul",null,[e("li",null,[n(s,{to:"/document/level-0/"},{default:o(()=>[l("小小白白话文")]),_:1}),l("连载上线啦,🍉 老师呕心沥血之作, 手把手教你从什么都不会到熟练配置 Xray!")]),ae,e("li",null,[n(s,{to:"/document/level-2/"},{default:o(()=>[l("透明代理")]),_:1}),l("也增加了更多文章.")]),re,e("li",null,[l("感谢 "),e("a",se,[l("@ricuhkaen"),n(t)]),l(" , "),e("a",ie,[l("@BioniCosmos"),n(t)]),l(", "),e("a",he,[l("@kirin"),n(t)])])]),_e,e("ul",null,[e("li",null,[l("文档仓库第一个 PR。🎉 "),n(s,{to:"/document/level-2/tproxy.html"},{default:o(()=>[l("透明代理(TProxy)配置教程 ")]),_:1}),l(" ,感谢"),ce,l(),e("a",ue,[l("@BioniCosmos"),n(t)])]),de]),pe,e("p",null,[l("【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 "),n(a,null,{default:o(()=>[e("a",fe,[l("1.2.0"),n(t)])]),_:1})]),be,e("ul",null,[ge,e("li",null,[l("Xray 将继续保持前行! 因此 "),e("a",me,[l("Xray 需要更多的英雄!!"),n(t)]),l("!")]),e("li",null,[l("PS:请品,请细品"),e("a",xe,[l("release notes"),n(t)]),l("每一句。似乎有一个小秘密小彩蛋 "),Xe])]),Se,e("p",null,[l("透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, "),e("a",ke,[l("TG 群"),n(t)]),l("火热测试中")]),e("h2",ye,[e("a",ve,[e("span",null,[l("2020.12.25 "),n(a,null,{default:o(()=>[e("a",Te,[l("1.1.5"),n(t)])]),_:1})])])]),Le,e("ul",null,[De,Pe,Ue,He,e("li",null,[l("kirin 带来了一大波 脚本更新."),e("a",Ce,[l("脚本在此"),n(t)])]),je]),Be,e("p",null,[l("因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。 网址为:"),e("a",Ne,[l("没错你正在看的就是"),n(t)])]),Ee,e("p",null,[l("文档网站需要不断完善和增加内容,以及完善设计。 因此更欢迎大家一起为文档建设添砖加瓦。 "),e("a",Ie,[l("文档的仓库"),n(t)])]),Ve,we,e("p",null,[l("Xray-core Shadowsocks UDP FullCone 测试版, "),e("a",Ge,[l("TG 群"),n(t)]),l("火热测试中")]),Re,Oe,e("h2",Fe,[e("a",Me,[e("span",null,[l("2020.12.18 "),n(a,null,{default:o(()=>[e("a",Ae,[l("1.1.4"),n(t)])]),_:1})])])]),qe,We,e("p",null,[l("鉴于日益增长群人数和游戏需求, 开启了"),e("a",Qe,[l("TG 游戏群"),n(t)])]),Ye,e("p",null,[e("a",Je,[l("安装脚本 dev 分支"),n(t)]),l("开启, 持续更新功能中.")]),e("h2",ze,[e("a",Ke,[e("span",null,[l("2020.12.11 "),n(a,null,{default:o(()=>[e("a",Ze,[l("1.1.3"),n(t)])]),_:1})])])]),$e,e("h2",el,[e("a",ll,[e("span",null,[l("2020.12.06 "),n(a,null,{default:o(()=>[e("a",nl,[l("1.1.2"),n(t)])]),_:1})])])]),tl,e("h2",ol,[e("a",al,[e("span",null,[l("2020.11.25 "),n(a,null,{default:o(()=>[e("a",rl,[l("1.0.0"),n(t)])]),_:1})])])]),sl,il,hl,_l,cl])}const bl=h(u,[["render",ul],["__file","news.html.vue"]]);export{bl as default}; diff --git a/assets/nginx_or_haproxy_tls_tunnel.html-2rfRu13n.js b/assets/nginx_or_haproxy_tls_tunnel.html-1_qLmdh0.js similarity index 99% rename from assets/nginx_or_haproxy_tls_tunnel.html-2rfRu13n.js rename to assets/nginx_or_haproxy_tls_tunnel.html-1_qLmdh0.js index e10f0cf118..7af2bda73f 100644 --- a/assets/nginx_or_haproxy_tls_tunnel.html-2rfRu13n.js +++ b/assets/nginx_or_haproxy_tls_tunnel.html-1_qLmdh0.js @@ -1,4 +1,4 @@ -import{_ as l,r as d,o as a,c as t,a as e,b as n,d as r,e as i}from"./app-PDrbPfzp.js";const v={},u=i('

                        Nginx 或 Haproxy 实现的 HTTPS 隧道、HTTP/2 over HTTPS 隧道、WebSocket over HTTP/2 over HTTPS 隧道、gRPC over HTTP/2 over HTTPS 隧道以及自签证书双端认证的 gRPC over HTTP/2 over HTTPS 隧道

                        客户端服务端 Nginx 构建 HTPPS 隧道隐藏指纹

                        网路结构:

                        xray_client ---tcp--- nginx_client ---HTTPS--- nginx_sever ---tcp--- xray_server

                        编译 nginx --with-stream

                        在客户端及服务端均编译

                        curl -O -L http://nginx.org/download/nginx-1.22.1.tar.gz

                        tar -zxvf nginx-1.22.1.tar.gz

                        cd nginx-1.22.1

                        apt install gcc make //编译依赖 gcc 以及 make

                        ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-stream --with-stream_ssl_module //此步需要依赖一些库,根据报错安装相应 lib

                        make && make install

                        编译之后 nginx 文件夹位于 /usr/local/nginx

                        配置 nginx

                        编辑 nginx 配置文件 nginx.conf

                        vim /usr/local/nginx/conf/nginx.conf

                        服务端加入如下配置

                        ',17),c={href:"https://xtls.github.io/document/level-0/ch06-certificates.html",target:"_blank",rel:"noopener noreferrer"},o=i(`
                        stream {
                        +import{_ as l,r as d,o as a,c as t,a as e,b as n,d as r,e as i}from"./app-UOvWaKji.js";const v={},u=i('

                        Nginx 或 Haproxy 实现的 HTTPS 隧道、HTTP/2 over HTTPS 隧道、WebSocket over HTTP/2 over HTTPS 隧道、gRPC over HTTP/2 over HTTPS 隧道以及自签证书双端认证的 gRPC over HTTP/2 over HTTPS 隧道

                        客户端服务端 Nginx 构建 HTPPS 隧道隐藏指纹

                        网路结构:

                        xray_client ---tcp--- nginx_client ---HTTPS--- nginx_sever ---tcp--- xray_server

                        编译 nginx --with-stream

                        在客户端及服务端均编译

                        curl -O -L http://nginx.org/download/nginx-1.22.1.tar.gz

                        tar -zxvf nginx-1.22.1.tar.gz

                        cd nginx-1.22.1

                        apt install gcc make //编译依赖 gcc 以及 make

                        ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-stream --with-stream_ssl_module //此步需要依赖一些库,根据报错安装相应 lib

                        make && make install

                        编译之后 nginx 文件夹位于 /usr/local/nginx

                        配置 nginx

                        编辑 nginx 配置文件 nginx.conf

                        vim /usr/local/nginx/conf/nginx.conf

                        服务端加入如下配置

                        ',17),c={href:"https://xtls.github.io/document/level-0/ch06-certificates.html",target:"_blank",rel:"noopener noreferrer"},o=i(`
                        stream {
                             server {
                                 listen 443 ssl;
                                 listen [::]:443 ssl;
                        diff --git a/assets/nginx_or_haproxy_tls_tunnel.html-L37cuaZc.js b/assets/nginx_or_haproxy_tls_tunnel.html-J7GQDlYh.js
                        similarity index 99%
                        rename from assets/nginx_or_haproxy_tls_tunnel.html-L37cuaZc.js
                        rename to assets/nginx_or_haproxy_tls_tunnel.html-J7GQDlYh.js
                        index e10f0cf118..7af2bda73f 100644
                        --- a/assets/nginx_or_haproxy_tls_tunnel.html-L37cuaZc.js
                        +++ b/assets/nginx_or_haproxy_tls_tunnel.html-J7GQDlYh.js
                        @@ -1,4 +1,4 @@
                        -import{_ as l,r as d,o as a,c as t,a as e,b as n,d as r,e as i}from"./app-PDrbPfzp.js";const v={},u=i('

                        Nginx 或 Haproxy 实现的 HTTPS 隧道、HTTP/2 over HTTPS 隧道、WebSocket over HTTP/2 over HTTPS 隧道、gRPC over HTTP/2 over HTTPS 隧道以及自签证书双端认证的 gRPC over HTTP/2 over HTTPS 隧道

                        客户端服务端 Nginx 构建 HTPPS 隧道隐藏指纹

                        网路结构:

                        xray_client ---tcp--- nginx_client ---HTTPS--- nginx_sever ---tcp--- xray_server

                        编译 nginx --with-stream

                        在客户端及服务端均编译

                        curl -O -L http://nginx.org/download/nginx-1.22.1.tar.gz

                        tar -zxvf nginx-1.22.1.tar.gz

                        cd nginx-1.22.1

                        apt install gcc make //编译依赖 gcc 以及 make

                        ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-stream --with-stream_ssl_module //此步需要依赖一些库,根据报错安装相应 lib

                        make && make install

                        编译之后 nginx 文件夹位于 /usr/local/nginx

                        配置 nginx

                        编辑 nginx 配置文件 nginx.conf

                        vim /usr/local/nginx/conf/nginx.conf

                        服务端加入如下配置

                        ',17),c={href:"https://xtls.github.io/document/level-0/ch06-certificates.html",target:"_blank",rel:"noopener noreferrer"},o=i(`
                        stream {
                        +import{_ as l,r as d,o as a,c as t,a as e,b as n,d as r,e as i}from"./app-UOvWaKji.js";const v={},u=i('

                        Nginx 或 Haproxy 实现的 HTTPS 隧道、HTTP/2 over HTTPS 隧道、WebSocket over HTTP/2 over HTTPS 隧道、gRPC over HTTP/2 over HTTPS 隧道以及自签证书双端认证的 gRPC over HTTP/2 over HTTPS 隧道

                        客户端服务端 Nginx 构建 HTPPS 隧道隐藏指纹

                        网路结构:

                        xray_client ---tcp--- nginx_client ---HTTPS--- nginx_sever ---tcp--- xray_server

                        编译 nginx --with-stream

                        在客户端及服务端均编译

                        curl -O -L http://nginx.org/download/nginx-1.22.1.tar.gz

                        tar -zxvf nginx-1.22.1.tar.gz

                        cd nginx-1.22.1

                        apt install gcc make //编译依赖 gcc 以及 make

                        ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-stream --with-stream_ssl_module //此步需要依赖一些库,根据报错安装相应 lib

                        make && make install

                        编译之后 nginx 文件夹位于 /usr/local/nginx

                        配置 nginx

                        编辑 nginx 配置文件 nginx.conf

                        vim /usr/local/nginx/conf/nginx.conf

                        服务端加入如下配置

                        ',17),c={href:"https://xtls.github.io/document/level-0/ch06-certificates.html",target:"_blank",rel:"noopener noreferrer"},o=i(`
                        stream {
                             server {
                                 listen 443 ssl;
                                 listen [::]:443 ssl;
                        diff --git a/assets/outbound.html-pTrUMPv-.js b/assets/outbound.html-c9chlcYi.js
                        similarity index 99%
                        rename from assets/outbound.html-pTrUMPv-.js
                        rename to assets/outbound.html-c9chlcYi.js
                        index 9efa98fc49..cf8a524976 100644
                        --- a/assets/outbound.html-pTrUMPv-.js
                        +++ b/assets/outbound.html-c9chlcYi.js
                        @@ -1,4 +1,4 @@
                        -import{_ as u,r as c,o as p,c as r,a as n,b as e,d as o,w as s,e as a}from"./app-PDrbPfzp.js";const l={},d=n("h1",{id:"outbound-proxies",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#outbound-proxies"},[n("span",null,"Outbound Proxies")])],-1),h=a(`

                        OutboundObject

                        The OutboundObject corresponds to a sub-element of the outbounds item in the configuration file.

                        Tip

                        The first element in the list serves as the main outbound. When there is no match or no successful match for the routing, the traffic is sent out by the main outbound.

                        {
                        +import{_ as u,r as c,o as p,c as r,a as n,b as e,d as o,w as s,e as a}from"./app-UOvWaKji.js";const l={},d=n("h1",{id:"outbound-proxies",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#outbound-proxies"},[n("span",null,"Outbound Proxies")])],-1),h=a(`

                        OutboundObject

                        The OutboundObject corresponds to a sub-element of the outbounds item in the configuration file.

                        Tip

                        The first element in the list serves as the main outbound. When there is no match or no successful match for the routing, the traffic is sent out by the main outbound.

                        {
                           "outbounds": [
                             {
                               "sendThrough": "0.0.0.0",
                        diff --git a/assets/outbound.html-Uyme5CaQ.js b/assets/outbound.html-nhfh9iOW.js
                        similarity index 99%
                        rename from assets/outbound.html-Uyme5CaQ.js
                        rename to assets/outbound.html-nhfh9iOW.js
                        index d7b02d9df7..5ea2d0899f 100644
                        --- a/assets/outbound.html-Uyme5CaQ.js
                        +++ b/assets/outbound.html-nhfh9iOW.js
                        @@ -1,4 +1,4 @@
                        -import{_ as u,r as c,o as l,c as d,a as n,b as o,d as s,w as e,e as a}from"./app-PDrbPfzp.js";const i={},r=n("h1",{id:"出站代理",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#出站代理"},[n("span",null,"出站代理")])],-1),b=a(`

                        OutboundObject

                        OutboundObject 对应配置文件中 outbounds 项的一个子元素。

                        提示

                        列表中的第一个元素作为主 outbound。当路由匹配不存在或没有匹配成功时,流量由主 outbound 发出。

                        {
                        +import{_ as u,r as c,o as l,c as d,a as n,b as o,d as s,w as e,e as a}from"./app-UOvWaKji.js";const i={},r=n("h1",{id:"出站代理",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#出站代理"},[n("span",null,"出站代理")])],-1),b=a(`

                        OutboundObject

                        OutboundObject 对应配置文件中 outbounds 项的一个子元素。

                        提示

                        列表中的第一个元素作为主 outbound。当路由匹配不存在或没有匹配成功时,流量由主 outbound 发出。

                        {
                           "outbounds": [
                             {
                               "sendThrough": "0.0.0.0",
                        diff --git a/assets/pieDiagram-79897490-axGt9ShQ.js b/assets/pieDiagram-79897490-xf0NxzxJ.js
                        similarity index 98%
                        rename from assets/pieDiagram-79897490-axGt9ShQ.js
                        rename to assets/pieDiagram-79897490-xf0NxzxJ.js
                        index ef88ef5242..0be6533806 100644
                        --- a/assets/pieDiagram-79897490-axGt9ShQ.js
                        +++ b/assets/pieDiagram-79897490-xf0NxzxJ.js
                        @@ -1,4 +1,4 @@
                        -import{aL as H,aM as at,x as lt,y as ot,s as ct,g as ht,b as ut,a as yt,A as ft,d as pt,c as et,l as it,aN as gt,aK as dt,aO as mt,i as _t}from"./mermaid.core-95b3ca__.js";import{a as tt}from"./arc-XT00965o.js";import{o as xt}from"./ordinal-wXG5obU4.js";import{a as kt}from"./array-Nw74a44z.js";import{c as F}from"./path-aUcfwwLI.js";import"./app-PDrbPfzp.js";import"./init-Hi12RPRh.js";function vt(e,u){return ue?1:u>=e?0:NaN}function bt(e){return e}function St(){var e=bt,u=vt,$=null,p=F(0),g=F(H),A=F(0);function y(a){var l,d=(a=kt(a)).length,m,I,T=0,_=new Array(d),v=new Array(d),c=+p.apply(this,arguments),E=Math.min(H,Math.max(-H,g.apply(this,arguments)-c)),O,w=Math.min(Math.abs(E)/d,A.apply(this,arguments)),b=w*(E<0?-1:1),t;for(l=0;l0&&(T+=t);for(u!=null?_.sort(function(i,n){return u(v[i],v[n])}):$!=null&&_.sort(function(i,n){return $(a[i],a[n])}),l=0,I=T?(E-d*b)/T:0;l0?t*I:0)+b,v[m]={data:a[m],index:l,value:t,startAngle:c,endAngle:O,padAngle:w};return v}return y.value=function(a){return arguments.length?(e=typeof a=="function"?a:F(+a),y):e},y.sortValues=function(a){return arguments.length?(u=a,$=null,y):u},y.sort=function(a){return arguments.length?($=a,u=null,y):$},y.startAngle=function(a){return arguments.length?(p=typeof a=="function"?a:F(+a),y):p},y.endAngle=function(a){return arguments.length?(g=typeof a=="function"?a:F(+a),y):g},y.padAngle=function(a){return arguments.length?(A=typeof a=="function"?a:F(+a),y):A},y}var J=function(){var e=function(b,t,i,n){for(i=i||{},n=b.length;n--;i[b[n]]=t);return i},u=[1,3],$=[1,4],p=[1,5],g=[1,6],A=[1,10,12,14,16,18,19,20,21,22],y=[2,4],a=[1,5,10,12,14,16,18,19,20,21,22],l=[20,21,22],d=[2,7],m=[1,12],I=[1,13],T=[1,14],_=[1,15],v=[1,16],c=[1,17],E={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,PIE:5,document:6,showData:7,line:8,statement:9,txt:10,value:11,title:12,title_value:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,section:19,NEWLINE:20,";":21,EOF:22,$accept:0,$end:1},terminals_:{2:"error",5:"PIE",7:"showData",10:"txt",11:"value",12:"title",13:"title_value",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"section",20:"NEWLINE",21:";",22:"EOF"},productions_:[0,[3,2],[3,2],[3,3],[6,0],[6,2],[8,2],[9,0],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[4,1],[4,1],[4,1]],performAction:function(t,i,n,r,o,s,P){var x=s.length-1;switch(o){case 3:r.setShowData(!0);break;case 6:this.$=s[x-1];break;case 8:r.addSection(s[x-1],r.cleanupValue(s[x]));break;case 9:this.$=s[x].trim(),r.setDiagramTitle(this.$);break;case 10:this.$=s[x].trim(),r.setAccTitle(this.$);break;case 11:case 12:this.$=s[x].trim(),r.setAccDescription(this.$);break;case 13:r.addSection(s[x].substr(8)),this.$=s[x].substr(8);break}},table:[{3:1,4:2,5:u,20:$,21:p,22:g},{1:[3]},{3:7,4:2,5:u,20:$,21:p,22:g},e(A,y,{6:8,7:[1,9]}),e(a,[2,14]),e(a,[2,15]),e(a,[2,16]),{1:[2,1]},e(l,d,{8:10,9:11,1:[2,2],10:m,12:I,14:T,16:_,18:v,19:c}),e(A,y,{6:18}),e(A,[2,5]),{4:19,20:$,21:p,22:g},{11:[1,20]},{13:[1,21]},{15:[1,22]},{17:[1,23]},e(l,[2,12]),e(l,[2,13]),e(l,d,{8:10,9:11,1:[2,3],10:m,12:I,14:T,16:_,18:v,19:c}),e(A,[2,6]),e(l,[2,8]),e(l,[2,9]),e(l,[2,10]),e(l,[2,11])],defaultActions:{7:[2,1]},parseError:function(t,i){if(i.recoverable)this.trace(t);else{var n=new Error(t);throw n.hash=i,n}},parse:function(t){var i=this,n=[0],r=[],o=[null],s=[],P=this.table,x="",f=0,V=0,R=2,M=1,B=s.slice.call(arguments,1),h=Object.create(this.lexer),N={yy:{}};for(var Y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Y)&&(N.yy[Y]=this.yy[Y]);h.setInput(t,N.yy),N.yy.lexer=h,N.yy.parser=this,typeof h.yylloc>"u"&&(h.yylloc={});var K=h.yylloc;s.push(K);var st=h.options&&h.options.ranges;typeof N.yy.parseError=="function"?this.parseError=N.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function rt(){var C;return C=r.pop()||h.lex()||M,typeof C!="number"&&(C instanceof Array&&(r=C,C=r.pop()),C=i.symbols_[C]||C),C}for(var k,L,S,Z,z={},j,D,X,W;;){if(L=n[n.length-1],this.defaultActions[L]?S=this.defaultActions[L]:((k===null||typeof k>"u")&&(k=rt()),S=P[L]&&P[L][k]),typeof S>"u"||!S.length||!S[0]){var q="";W=[];for(j in P[L])this.terminals_[j]&&j>R&&W.push("'"+this.terminals_[j]+"'");h.showPosition?q="Parse error on line "+(f+1)+`:
                        +import{aL as H,aM as at,x as lt,y as ot,s as ct,g as ht,b as ut,a as yt,A as ft,d as pt,c as et,l as it,aN as gt,aK as dt,aO as mt,i as _t}from"./mermaid.core-Q3WVcjPF.js";import{a as tt}from"./arc-5GdQY_kf.js";import{o as xt}from"./ordinal-wXG5obU4.js";import{a as kt}from"./array-Nw74a44z.js";import{c as F}from"./path-aUcfwwLI.js";import"./app-UOvWaKji.js";import"./init-Hi12RPRh.js";function vt(e,u){return ue?1:u>=e?0:NaN}function bt(e){return e}function St(){var e=bt,u=vt,$=null,p=F(0),g=F(H),A=F(0);function y(a){var l,d=(a=kt(a)).length,m,I,T=0,_=new Array(d),v=new Array(d),c=+p.apply(this,arguments),E=Math.min(H,Math.max(-H,g.apply(this,arguments)-c)),O,w=Math.min(Math.abs(E)/d,A.apply(this,arguments)),b=w*(E<0?-1:1),t;for(l=0;l0&&(T+=t);for(u!=null?_.sort(function(i,n){return u(v[i],v[n])}):$!=null&&_.sort(function(i,n){return $(a[i],a[n])}),l=0,I=T?(E-d*b)/T:0;l0?t*I:0)+b,v[m]={data:a[m],index:l,value:t,startAngle:c,endAngle:O,padAngle:w};return v}return y.value=function(a){return arguments.length?(e=typeof a=="function"?a:F(+a),y):e},y.sortValues=function(a){return arguments.length?(u=a,$=null,y):u},y.sort=function(a){return arguments.length?($=a,u=null,y):$},y.startAngle=function(a){return arguments.length?(p=typeof a=="function"?a:F(+a),y):p},y.endAngle=function(a){return arguments.length?(g=typeof a=="function"?a:F(+a),y):g},y.padAngle=function(a){return arguments.length?(A=typeof a=="function"?a:F(+a),y):A},y}var J=function(){var e=function(b,t,i,n){for(i=i||{},n=b.length;n--;i[b[n]]=t);return i},u=[1,3],$=[1,4],p=[1,5],g=[1,6],A=[1,10,12,14,16,18,19,20,21,22],y=[2,4],a=[1,5,10,12,14,16,18,19,20,21,22],l=[20,21,22],d=[2,7],m=[1,12],I=[1,13],T=[1,14],_=[1,15],v=[1,16],c=[1,17],E={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,PIE:5,document:6,showData:7,line:8,statement:9,txt:10,value:11,title:12,title_value:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,section:19,NEWLINE:20,";":21,EOF:22,$accept:0,$end:1},terminals_:{2:"error",5:"PIE",7:"showData",10:"txt",11:"value",12:"title",13:"title_value",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"section",20:"NEWLINE",21:";",22:"EOF"},productions_:[0,[3,2],[3,2],[3,3],[6,0],[6,2],[8,2],[9,0],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[4,1],[4,1],[4,1]],performAction:function(t,i,n,r,o,s,P){var x=s.length-1;switch(o){case 3:r.setShowData(!0);break;case 6:this.$=s[x-1];break;case 8:r.addSection(s[x-1],r.cleanupValue(s[x]));break;case 9:this.$=s[x].trim(),r.setDiagramTitle(this.$);break;case 10:this.$=s[x].trim(),r.setAccTitle(this.$);break;case 11:case 12:this.$=s[x].trim(),r.setAccDescription(this.$);break;case 13:r.addSection(s[x].substr(8)),this.$=s[x].substr(8);break}},table:[{3:1,4:2,5:u,20:$,21:p,22:g},{1:[3]},{3:7,4:2,5:u,20:$,21:p,22:g},e(A,y,{6:8,7:[1,9]}),e(a,[2,14]),e(a,[2,15]),e(a,[2,16]),{1:[2,1]},e(l,d,{8:10,9:11,1:[2,2],10:m,12:I,14:T,16:_,18:v,19:c}),e(A,y,{6:18}),e(A,[2,5]),{4:19,20:$,21:p,22:g},{11:[1,20]},{13:[1,21]},{15:[1,22]},{17:[1,23]},e(l,[2,12]),e(l,[2,13]),e(l,d,{8:10,9:11,1:[2,3],10:m,12:I,14:T,16:_,18:v,19:c}),e(A,[2,6]),e(l,[2,8]),e(l,[2,9]),e(l,[2,10]),e(l,[2,11])],defaultActions:{7:[2,1]},parseError:function(t,i){if(i.recoverable)this.trace(t);else{var n=new Error(t);throw n.hash=i,n}},parse:function(t){var i=this,n=[0],r=[],o=[null],s=[],P=this.table,x="",f=0,V=0,R=2,M=1,B=s.slice.call(arguments,1),h=Object.create(this.lexer),N={yy:{}};for(var Y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Y)&&(N.yy[Y]=this.yy[Y]);h.setInput(t,N.yy),N.yy.lexer=h,N.yy.parser=this,typeof h.yylloc>"u"&&(h.yylloc={});var K=h.yylloc;s.push(K);var st=h.options&&h.options.ranges;typeof N.yy.parseError=="function"?this.parseError=N.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function rt(){var C;return C=r.pop()||h.lex()||M,typeof C!="number"&&(C instanceof Array&&(r=C,C=r.pop()),C=i.symbols_[C]||C),C}for(var k,L,S,Z,z={},j,D,X,W;;){if(L=n[n.length-1],this.defaultActions[L]?S=this.defaultActions[L]:((k===null||typeof k>"u")&&(k=rt()),S=P[L]&&P[L][k]),typeof S>"u"||!S.length||!S[0]){var q="";W=[];for(j in P[L])this.terminals_[j]&&j>R&&W.push("'"+this.terminals_[j]+"'");h.showPosition?q="Parse error on line "+(f+1)+`:
                         `+h.showPosition()+`
                         Expecting `+W.join(", ")+", got '"+(this.terminals_[k]||k)+"'":q="Parse error on line "+(f+1)+": Unexpected "+(k==M?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(q,{text:h.match,token:this.terminals_[k]||k,line:h.yylineno,loc:K,expected:W})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+L+", token: "+k);switch(S[0]){case 1:n.push(k),o.push(h.yytext),s.push(h.yylloc),n.push(S[1]),k=null,V=h.yyleng,x=h.yytext,f=h.yylineno,K=h.yylloc;break;case 2:if(D=this.productions_[S[1]][1],z.$=o[o.length-D],z._$={first_line:s[s.length-(D||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(D||1)].first_column,last_column:s[s.length-1].last_column},st&&(z._$.range=[s[s.length-(D||1)].range[0],s[s.length-1].range[1]]),Z=this.performAction.apply(z,[x,V,f,N.yy,S[1],o,s].concat(B)),typeof Z<"u")return Z;D&&(n=n.slice(0,-1*D*2),o=o.slice(0,-1*D),s=s.slice(0,-1*D)),n.push(this.productions_[S[1]][0]),o.push(z.$),s.push(z._$),X=P[n[n.length-2]][n[n.length-1]],n.push(X);break;case 3:return!0}}return!0}},O=function(){var b={EOF:1,parseError:function(i,n){if(this.yy.parser)this.yy.parser.parseError(i,n);else throw new Error(i)},setInput:function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var t=this._input[0];this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t;var i=t.match(/(?:\r\n?|\n).*/g);return i?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t},unput:function(t){var i=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var o=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===r.length?this.yylloc.first_column:0)+r[r.length-n.length].length-n[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[o[0],o[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
                         `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(t){this.unput(this.match.slice(t))},pastInput:function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+`
                        diff --git a/assets/policy.html-nFbqdJoW.js b/assets/policy.html-60KZMSiW.js
                        similarity index 99%
                        rename from assets/policy.html-nFbqdJoW.js
                        rename to assets/policy.html-60KZMSiW.js
                        index 878ad3e342..bcf551fe9f 100644
                        --- a/assets/policy.html-nFbqdJoW.js
                        +++ b/assets/policy.html-60KZMSiW.js
                        @@ -1,4 +1,4 @@
                        -import{_ as n,o as s,c as e,e as a}from"./app-PDrbPfzp.js";const o={},t=a(`

                        Local Policy

                        Local policy can be used to set different policy settings for different user levels, such as connection timeout settings. Each connection handled by Xray corresponds to a user, and different policies are applied based on the user's level.

                        PolicyObject

                        PolicyObject corresponds to the policy field in the configuration file.

                        {
                        +import{_ as n,o as s,c as e,e as a}from"./app-UOvWaKji.js";const o={},t=a(`

                        Local Policy

                        Local policy can be used to set different policy settings for different user levels, such as connection timeout settings. Each connection handled by Xray corresponds to a user, and different policies are applied based on the user's level.

                        PolicyObject

                        PolicyObject corresponds to the policy field in the configuration file.

                        {
                           "policy": {
                             "levels": {
                               "0": {
                        diff --git a/assets/policy.html-yO5cVi3O.js b/assets/policy.html-RrAD2wsU.js
                        similarity index 99%
                        rename from assets/policy.html-yO5cVi3O.js
                        rename to assets/policy.html-RrAD2wsU.js
                        index 398f1cbe37..90227bc5e7 100644
                        --- a/assets/policy.html-yO5cVi3O.js
                        +++ b/assets/policy.html-RrAD2wsU.js
                        @@ -1,4 +1,4 @@
                        -import{_ as n,o as s,c as a,e}from"./app-PDrbPfzp.js";const o={},t=e(`

                        本地策略

                        本地策略,可以设置不同的用户等级和对应的策略设置,比如连接超时设置。Xray 处理的每一个连接都对应一个用户,按照用户的等级(level)应用不同的策略。

                        PolicyObject

                        PolicyObject 对应配置文件的 policy 项。

                        {
                        +import{_ as n,o as s,c as a,e}from"./app-UOvWaKji.js";const o={},t=e(`

                        本地策略

                        本地策略,可以设置不同的用户等级和对应的策略设置,比如连接超时设置。Xray 处理的每一个连接都对应一个用户,按照用户的等级(level)应用不同的策略。

                        PolicyObject

                        PolicyObject 对应配置文件的 policy 项。

                        {
                           "policy": {
                             "levels": {
                               "0": {
                        diff --git a/assets/quadrantDiagram-62f64e94-DSAXizG6.js b/assets/quadrantDiagram-62f64e94-cAAwIO1z.js
                        similarity index 99%
                        rename from assets/quadrantDiagram-62f64e94-DSAXizG6.js
                        rename to assets/quadrantDiagram-62f64e94-cAAwIO1z.js
                        index dc32eb49bd..04c9f3ce5c 100644
                        --- a/assets/quadrantDiagram-62f64e94-DSAXizG6.js
                        +++ b/assets/quadrantDiagram-62f64e94-cAAwIO1z.js
                        @@ -1,4 +1,4 @@
                        -import{a$ as vt,c as yt,aM as D,l as ot,s as Lt,g as Ct,x as zt,y as bt,a as Et,b as Dt,A as It,h as gt,i as Bt,d as wt}from"./mermaid.core-95b3ca__.js";import{l as mt}from"./linear-yB98X29G.js";import"./app-PDrbPfzp.js";import"./init-Hi12RPRh.js";var pt=function(){var e=function(K,n,r,l){for(r=r||{},l=K.length;l--;r[K[l]]=n);return r},s=[1,3],h=[1,4],x=[1,5],f=[1,6],d=[1,7],c=[1,5,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],g=[1,5,6,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],i=[32,33,34],y=[2,7],p=[1,13],B=[1,17],N=[1,18],V=[1,19],I=[1,20],b=[1,21],M=[1,22],X=[1,23],C=[1,24],it=[1,25],at=[1,26],nt=[1,27],U=[1,30],Q=[1,31],T=[1,32],m=[1,33],_=[1,34],t=[1,35],A=[1,36],S=[1,37],k=[1,38],F=[1,39],P=[1,40],v=[1,41],L=[1,42],O=[1,57],Y=[1,58],z=[5,22,26,32,33,34,40,41,42,43,44,45,46,47,48,49,50,51],ht={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,SPACE:5,QUADRANT:6,document:7,line:8,statement:9,axisDetails:10,quadrantDetails:11,points:12,title:13,title_value:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,text:21,point_start:22,point_x:23,point_y:24,"X-AXIS":25,"AXIS-TEXT-DELIMITER":26,"Y-AXIS":27,QUADRANT_1:28,QUADRANT_2:29,QUADRANT_3:30,QUADRANT_4:31,NEWLINE:32,SEMI:33,EOF:34,alphaNumToken:35,textNoTagsToken:36,STR:37,MD_STR:38,alphaNum:39,PUNCTUATION:40,AMP:41,NUM:42,ALPHA:43,COMMA:44,PLUS:45,EQUALS:46,MULT:47,DOT:48,BRKT:49,UNDERSCORE:50,MINUS:51,$accept:0,$end:1},terminals_:{2:"error",5:"SPACE",6:"QUADRANT",13:"title",14:"title_value",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",22:"point_start",23:"point_x",24:"point_y",25:"X-AXIS",26:"AXIS-TEXT-DELIMITER",27:"Y-AXIS",28:"QUADRANT_1",29:"QUADRANT_2",30:"QUADRANT_3",31:"QUADRANT_4",32:"NEWLINE",33:"SEMI",34:"EOF",37:"STR",38:"MD_STR",40:"PUNCTUATION",41:"AMP",42:"NUM",43:"ALPHA",44:"COMMA",45:"PLUS",46:"EQUALS",47:"MULT",48:"DOT",49:"BRKT",50:"UNDERSCORE",51:"MINUS"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[9,0],[9,2],[9,1],[9,1],[9,1],[9,2],[9,2],[9,2],[9,1],[9,1],[12,4],[10,4],[10,3],[10,2],[10,4],[10,3],[10,2],[11,2],[11,2],[11,2],[11,2],[4,1],[4,1],[4,1],[21,1],[21,2],[21,1],[21,1],[39,1],[39,2],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[36,1],[36,1],[36,1]],performAction:function(n,r,l,o,q,a,et){var u=a.length-1;switch(q){case 12:this.$=a[u].trim(),o.setDiagramTitle(this.$);break;case 13:this.$=a[u].trim(),o.setAccTitle(this.$);break;case 14:case 15:this.$=a[u].trim(),o.setAccDescription(this.$);break;case 16:o.addSection(a[u].substr(8)),this.$=a[u].substr(8);break;case 17:o.addPoint(a[u-3],a[u-1],a[u]);break;case 18:o.setXAxisLeftText(a[u-2]),o.setXAxisRightText(a[u]);break;case 19:a[u-1].text+=" ⟶ ",o.setXAxisLeftText(a[u-1]);break;case 20:o.setXAxisLeftText(a[u]);break;case 21:o.setYAxisBottomText(a[u-2]),o.setYAxisTopText(a[u]);break;case 22:a[u-1].text+=" ⟶ ",o.setYAxisBottomText(a[u-1]);break;case 23:o.setYAxisBottomText(a[u]);break;case 24:o.setQuadrant1Text(a[u]);break;case 25:o.setQuadrant2Text(a[u]);break;case 26:o.setQuadrant3Text(a[u]);break;case 27:o.setQuadrant4Text(a[u]);break;case 31:this.$={text:a[u],type:"text"};break;case 32:this.$={text:a[u-1].text+""+a[u],type:a[u-1].type};break;case 33:this.$={text:a[u],type:"text"};break;case 34:this.$={text:a[u],type:"markdown"};break;case 35:this.$=a[u];break;case 36:this.$=a[u-1]+""+a[u];break}},table:[{3:1,4:2,5:s,6:h,32:x,33:f,34:d},{1:[3]},{3:8,4:2,5:s,6:h,32:x,33:f,34:d},{3:9,4:2,5:s,6:h,32:x,33:f,34:d},e(c,[2,4],{7:10}),e(g,[2,28]),e(g,[2,29]),e(g,[2,30]),{1:[2,1]},{1:[2,2]},e(i,y,{8:11,9:12,10:14,11:15,12:16,21:28,35:29,1:[2,3],5:p,13:B,15:N,17:V,19:I,20:b,25:M,27:X,28:C,29:it,30:at,31:nt,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L}),e(c,[2,5]),{4:43,32:x,33:f,34:d},e(i,y,{10:14,11:15,12:16,21:28,35:29,9:44,5:p,13:B,15:N,17:V,19:I,20:b,25:M,27:X,28:C,29:it,30:at,31:nt,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L}),e(i,[2,9]),e(i,[2,10]),e(i,[2,11]),{14:[1,45]},{16:[1,46]},{18:[1,47]},e(i,[2,15]),e(i,[2,16]),{21:48,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{21:49,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{21:50,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{21:51,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{21:52,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{21:53,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{5:O,22:[1,54],35:56,36:55,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y},e(z,[2,31]),e(z,[2,33]),e(z,[2,34]),e(z,[2,37]),e(z,[2,38]),e(z,[2,39]),e(z,[2,40]),e(z,[2,41]),e(z,[2,42]),e(z,[2,43]),e(z,[2,44]),e(z,[2,45]),e(z,[2,46]),e(z,[2,47]),e(c,[2,6]),e(i,[2,8]),e(i,[2,12]),e(i,[2,13]),e(i,[2,14]),e(i,[2,20],{36:55,35:56,5:O,26:[1,59],40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,23],{36:55,35:56,5:O,26:[1,60],40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,24],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,25],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,26],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,27],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),{23:[1,61]},e(z,[2,32]),e(z,[2,48]),e(z,[2,49]),e(z,[2,50]),e(i,[2,19],{35:29,21:62,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L}),e(i,[2,22],{35:29,21:63,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L}),{24:[1,64]},e(i,[2,18],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,21],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,17])],defaultActions:{8:[2,1],9:[2,2]},parseError:function(n,r){if(r.recoverable)this.trace(n);else{var l=new Error(n);throw l.hash=r,l}},parse:function(n){var r=this,l=[0],o=[],q=[null],a=[],et=this.table,u="",st=0,qt=0,St=2,Tt=1,kt=a.slice.call(arguments,1),E=Object.create(this.lexer),Z={yy:{}};for(var dt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,dt)&&(Z.yy[dt]=this.yy[dt]);E.setInput(n,Z.yy),Z.yy.lexer=E,Z.yy.parser=this,typeof E.yylloc>"u"&&(E.yylloc={});var ut=E.yylloc;a.push(ut);var Ft=E.options&&E.options.ranges;typeof Z.yy.parseError=="function"?this.parseError=Z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Pt(){var j;return j=o.pop()||E.lex()||Tt,typeof j!="number"&&(j instanceof Array&&(o=j,j=o.pop()),j=r.symbols_[j]||j),j}for(var W,J,H,xt,tt={},rt,$,_t,lt;;){if(J=l[l.length-1],this.defaultActions[J]?H=this.defaultActions[J]:((W===null||typeof W>"u")&&(W=Pt()),H=et[J]&&et[J][W]),typeof H>"u"||!H.length||!H[0]){var ft="";lt=[];for(rt in et[J])this.terminals_[rt]&&rt>St&<.push("'"+this.terminals_[rt]+"'");E.showPosition?ft="Parse error on line "+(st+1)+`:
                        +import{a$ as vt,c as yt,aM as D,l as ot,s as Lt,g as Ct,x as zt,y as bt,a as Et,b as Dt,A as It,h as gt,i as Bt,d as wt}from"./mermaid.core-Q3WVcjPF.js";import{l as mt}from"./linear-eA8J8eJ4.js";import"./app-UOvWaKji.js";import"./init-Hi12RPRh.js";var pt=function(){var e=function(K,n,r,l){for(r=r||{},l=K.length;l--;r[K[l]]=n);return r},s=[1,3],h=[1,4],x=[1,5],f=[1,6],d=[1,7],c=[1,5,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],g=[1,5,6,13,15,17,19,20,25,27,28,29,30,31,32,33,34,37,38,40,41,42,43,44,45,46,47,48,49,50],i=[32,33,34],y=[2,7],p=[1,13],B=[1,17],N=[1,18],V=[1,19],I=[1,20],b=[1,21],M=[1,22],X=[1,23],C=[1,24],it=[1,25],at=[1,26],nt=[1,27],U=[1,30],Q=[1,31],T=[1,32],m=[1,33],_=[1,34],t=[1,35],A=[1,36],S=[1,37],k=[1,38],F=[1,39],P=[1,40],v=[1,41],L=[1,42],O=[1,57],Y=[1,58],z=[5,22,26,32,33,34,40,41,42,43,44,45,46,47,48,49,50,51],ht={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,SPACE:5,QUADRANT:6,document:7,line:8,statement:9,axisDetails:10,quadrantDetails:11,points:12,title:13,title_value:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,text:21,point_start:22,point_x:23,point_y:24,"X-AXIS":25,"AXIS-TEXT-DELIMITER":26,"Y-AXIS":27,QUADRANT_1:28,QUADRANT_2:29,QUADRANT_3:30,QUADRANT_4:31,NEWLINE:32,SEMI:33,EOF:34,alphaNumToken:35,textNoTagsToken:36,STR:37,MD_STR:38,alphaNum:39,PUNCTUATION:40,AMP:41,NUM:42,ALPHA:43,COMMA:44,PLUS:45,EQUALS:46,MULT:47,DOT:48,BRKT:49,UNDERSCORE:50,MINUS:51,$accept:0,$end:1},terminals_:{2:"error",5:"SPACE",6:"QUADRANT",13:"title",14:"title_value",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",22:"point_start",23:"point_x",24:"point_y",25:"X-AXIS",26:"AXIS-TEXT-DELIMITER",27:"Y-AXIS",28:"QUADRANT_1",29:"QUADRANT_2",30:"QUADRANT_3",31:"QUADRANT_4",32:"NEWLINE",33:"SEMI",34:"EOF",37:"STR",38:"MD_STR",40:"PUNCTUATION",41:"AMP",42:"NUM",43:"ALPHA",44:"COMMA",45:"PLUS",46:"EQUALS",47:"MULT",48:"DOT",49:"BRKT",50:"UNDERSCORE",51:"MINUS"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[9,0],[9,2],[9,1],[9,1],[9,1],[9,2],[9,2],[9,2],[9,1],[9,1],[12,4],[10,4],[10,3],[10,2],[10,4],[10,3],[10,2],[11,2],[11,2],[11,2],[11,2],[4,1],[4,1],[4,1],[21,1],[21,2],[21,1],[21,1],[39,1],[39,2],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[35,1],[36,1],[36,1],[36,1]],performAction:function(n,r,l,o,q,a,et){var u=a.length-1;switch(q){case 12:this.$=a[u].trim(),o.setDiagramTitle(this.$);break;case 13:this.$=a[u].trim(),o.setAccTitle(this.$);break;case 14:case 15:this.$=a[u].trim(),o.setAccDescription(this.$);break;case 16:o.addSection(a[u].substr(8)),this.$=a[u].substr(8);break;case 17:o.addPoint(a[u-3],a[u-1],a[u]);break;case 18:o.setXAxisLeftText(a[u-2]),o.setXAxisRightText(a[u]);break;case 19:a[u-1].text+=" ⟶ ",o.setXAxisLeftText(a[u-1]);break;case 20:o.setXAxisLeftText(a[u]);break;case 21:o.setYAxisBottomText(a[u-2]),o.setYAxisTopText(a[u]);break;case 22:a[u-1].text+=" ⟶ ",o.setYAxisBottomText(a[u-1]);break;case 23:o.setYAxisBottomText(a[u]);break;case 24:o.setQuadrant1Text(a[u]);break;case 25:o.setQuadrant2Text(a[u]);break;case 26:o.setQuadrant3Text(a[u]);break;case 27:o.setQuadrant4Text(a[u]);break;case 31:this.$={text:a[u],type:"text"};break;case 32:this.$={text:a[u-1].text+""+a[u],type:a[u-1].type};break;case 33:this.$={text:a[u],type:"text"};break;case 34:this.$={text:a[u],type:"markdown"};break;case 35:this.$=a[u];break;case 36:this.$=a[u-1]+""+a[u];break}},table:[{3:1,4:2,5:s,6:h,32:x,33:f,34:d},{1:[3]},{3:8,4:2,5:s,6:h,32:x,33:f,34:d},{3:9,4:2,5:s,6:h,32:x,33:f,34:d},e(c,[2,4],{7:10}),e(g,[2,28]),e(g,[2,29]),e(g,[2,30]),{1:[2,1]},{1:[2,2]},e(i,y,{8:11,9:12,10:14,11:15,12:16,21:28,35:29,1:[2,3],5:p,13:B,15:N,17:V,19:I,20:b,25:M,27:X,28:C,29:it,30:at,31:nt,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L}),e(c,[2,5]),{4:43,32:x,33:f,34:d},e(i,y,{10:14,11:15,12:16,21:28,35:29,9:44,5:p,13:B,15:N,17:V,19:I,20:b,25:M,27:X,28:C,29:it,30:at,31:nt,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L}),e(i,[2,9]),e(i,[2,10]),e(i,[2,11]),{14:[1,45]},{16:[1,46]},{18:[1,47]},e(i,[2,15]),e(i,[2,16]),{21:48,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{21:49,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{21:50,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{21:51,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{21:52,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{21:53,35:29,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L},{5:O,22:[1,54],35:56,36:55,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y},e(z,[2,31]),e(z,[2,33]),e(z,[2,34]),e(z,[2,37]),e(z,[2,38]),e(z,[2,39]),e(z,[2,40]),e(z,[2,41]),e(z,[2,42]),e(z,[2,43]),e(z,[2,44]),e(z,[2,45]),e(z,[2,46]),e(z,[2,47]),e(c,[2,6]),e(i,[2,8]),e(i,[2,12]),e(i,[2,13]),e(i,[2,14]),e(i,[2,20],{36:55,35:56,5:O,26:[1,59],40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,23],{36:55,35:56,5:O,26:[1,60],40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,24],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,25],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,26],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,27],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),{23:[1,61]},e(z,[2,32]),e(z,[2,48]),e(z,[2,49]),e(z,[2,50]),e(i,[2,19],{35:29,21:62,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L}),e(i,[2,22],{35:29,21:63,37:U,38:Q,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L}),{24:[1,64]},e(i,[2,18],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,21],{36:55,35:56,5:O,40:T,41:m,42:_,43:t,44:A,45:S,46:k,47:F,48:P,49:v,50:L,51:Y}),e(i,[2,17])],defaultActions:{8:[2,1],9:[2,2]},parseError:function(n,r){if(r.recoverable)this.trace(n);else{var l=new Error(n);throw l.hash=r,l}},parse:function(n){var r=this,l=[0],o=[],q=[null],a=[],et=this.table,u="",st=0,qt=0,St=2,Tt=1,kt=a.slice.call(arguments,1),E=Object.create(this.lexer),Z={yy:{}};for(var dt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,dt)&&(Z.yy[dt]=this.yy[dt]);E.setInput(n,Z.yy),Z.yy.lexer=E,Z.yy.parser=this,typeof E.yylloc>"u"&&(E.yylloc={});var ut=E.yylloc;a.push(ut);var Ft=E.options&&E.options.ranges;typeof Z.yy.parseError=="function"?this.parseError=Z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Pt(){var j;return j=o.pop()||E.lex()||Tt,typeof j!="number"&&(j instanceof Array&&(o=j,j=o.pop()),j=r.symbols_[j]||j),j}for(var W,J,H,xt,tt={},rt,$,_t,lt;;){if(J=l[l.length-1],this.defaultActions[J]?H=this.defaultActions[J]:((W===null||typeof W>"u")&&(W=Pt()),H=et[J]&&et[J][W]),typeof H>"u"||!H.length||!H[0]){var ft="";lt=[];for(rt in et[J])this.terminals_[rt]&&rt>St&<.push("'"+this.terminals_[rt]+"'");E.showPosition?ft="Parse error on line "+(st+1)+`:
                         `+E.showPosition()+`
                         Expecting `+lt.join(", ")+", got '"+(this.terminals_[W]||W)+"'":ft="Parse error on line "+(st+1)+": Unexpected "+(W==Tt?"end of input":"'"+(this.terminals_[W]||W)+"'"),this.parseError(ft,{text:E.match,token:this.terminals_[W]||W,line:E.yylineno,loc:ut,expected:lt})}if(H[0]instanceof Array&&H.length>1)throw new Error("Parse Error: multiple actions possible at state: "+J+", token: "+W);switch(H[0]){case 1:l.push(W),q.push(E.yytext),a.push(E.yylloc),l.push(H[1]),W=null,qt=E.yyleng,u=E.yytext,st=E.yylineno,ut=E.yylloc;break;case 2:if($=this.productions_[H[1]][1],tt.$=q[q.length-$],tt._$={first_line:a[a.length-($||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-($||1)].first_column,last_column:a[a.length-1].last_column},Ft&&(tt._$.range=[a[a.length-($||1)].range[0],a[a.length-1].range[1]]),xt=this.performAction.apply(tt,[u,qt,st,Z.yy,H[1],q,a].concat(kt)),typeof xt<"u")return xt;$&&(l=l.slice(0,-1*$*2),q=q.slice(0,-1*$),a=a.slice(0,-1*$)),l.push(this.productions_[H[1]][0]),q.push(tt.$),a.push(tt._$),_t=et[l[l.length-2]][l[l.length-1]],l.push(_t);break;case 3:return!0}}return!0}},At=function(){var K={EOF:1,parseError:function(r,l){if(this.yy.parser)this.yy.parser.parseError(r,l);else throw new Error(r)},setInput:function(n,r){return this.yy=r||this.yy||{},this._input=n,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var n=this._input[0];this.yytext+=n,this.yyleng++,this.offset++,this.match+=n,this.matched+=n;var r=n.match(/(?:\r\n?|\n).*/g);return r?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),n},unput:function(n){var r=n.length,l=n.split(/(?:\r\n?|\n)/g);this._input=n+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-r),this.offset-=r;var o=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),l.length-1&&(this.yylineno-=l.length-1);var q=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:l?(l.length===o.length?this.yylloc.first_column:0)+o[o.length-l.length].length-l[0].length:this.yylloc.first_column-r},this.options.ranges&&(this.yylloc.range=[q[0],q[0]+this.yyleng-r]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
                         `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(n){this.unput(this.match.slice(n))},pastInput:function(){var n=this.matched.substr(0,this.matched.length-this.match.length);return(n.length>20?"...":"")+n.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var n=this.match;return n.length<20&&(n+=this._input.substr(0,20-n.length)),(n.substr(0,20)+(n.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var n=this.pastInput(),r=new Array(n.length+1).join("-");return n+this.upcomingInput()+`
                        diff --git a/assets/quic.html-ES7-n1_Y.js b/assets/quic.html-2dnyw5D-.js
                        similarity index 98%
                        rename from assets/quic.html-ES7-n1_Y.js
                        rename to assets/quic.html-2dnyw5D-.js
                        index f14fe2e769..7af2a82aa7 100644
                        --- a/assets/quic.html-ES7-n1_Y.js
                        +++ b/assets/quic.html-2dnyw5D-.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as a,o as l,c as r,a as e,b as n,d as t,w as i,e as u}from"./app-PDrbPfzp.js";const d={},p=e("h1",{id:"quic",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#quic"},[e("span",null,"QUIC")])],-1),h=e("p",null,"QUIC (Quick UDP Internet Connection) is a protocol proposed by Google for multiplexed and concurrent transmission using UDP. Its main advantages are:",-1),b=e("li",null,"Reduced number of roundtrips in handshake phase. (1-RTT or 0-RTT)",-1),f={href:"https://calendar.perfplanet.com/2020/head-of-line-blocking-in-quic-and-http-3-the-details/",target:"_blank",rel:"noopener noreferrer"},m=e("li",null,"Connection migration, (mainly on the client side) when switching from Wifi to 4G, the connection will not be interrupted.",-1),q=e("p",null,"QUIC is currently in the experimental phase and uses IETF implementation that is still being standardized, so compatibility with the final version cannot be guaranteed.",-1),k=e("li",null,"12-byte Connection ID",-1),_={href:"https://en.wikipedia.org/wiki/HTTP_persistent_connection",target:"_blank",rel:"noopener noreferrer"},v=e("h2",{id:"quicobject",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#quicobject"},[e("span",null,"QuicObject")])],-1),g=e("code",null,"QuicObject",-1),y=e("code",null,"quicSettings",-1),T={class:"custom-container danger"},w=e("p",{class:"custom-container-title"},"Danger",-1),I=e("p",null,"The configurations of both endpoints must be identical, otherwise the connection will fail.",-1),j=u(`
                        {
                        +import{_ as c,r as a,o as l,c as r,a as e,b as n,d as t,w as i,e as u}from"./app-UOvWaKji.js";const d={},p=e("h1",{id:"quic",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#quic"},[e("span",null,"QUIC")])],-1),h=e("p",null,"QUIC (Quick UDP Internet Connection) is a protocol proposed by Google for multiplexed and concurrent transmission using UDP. Its main advantages are:",-1),b=e("li",null,"Reduced number of roundtrips in handshake phase. (1-RTT or 0-RTT)",-1),f={href:"https://calendar.perfplanet.com/2020/head-of-line-blocking-in-quic-and-http-3-the-details/",target:"_blank",rel:"noopener noreferrer"},m=e("li",null,"Connection migration, (mainly on the client side) when switching from Wifi to 4G, the connection will not be interrupted.",-1),q=e("p",null,"QUIC is currently in the experimental phase and uses IETF implementation that is still being standardized, so compatibility with the final version cannot be guaranteed.",-1),k=e("li",null,"12-byte Connection ID",-1),_={href:"https://en.wikipedia.org/wiki/HTTP_persistent_connection",target:"_blank",rel:"noopener noreferrer"},v=e("h2",{id:"quicobject",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#quicobject"},[e("span",null,"QuicObject")])],-1),g=e("code",null,"QuicObject",-1),y=e("code",null,"quicSettings",-1),T={class:"custom-container danger"},w=e("p",{class:"custom-container-title"},"Danger",-1),I=e("p",null,"The configurations of both endpoints must be identical, otherwise the connection will fail.",-1),j=u(`
                        {
                           "security": "none",
                           "key": "",
                           "header": {
                        diff --git a/assets/quic.html-tieiwfcI.js b/assets/quic.html-WnhipFbM.js
                        similarity index 98%
                        rename from assets/quic.html-tieiwfcI.js
                        rename to assets/quic.html-WnhipFbM.js
                        index 08ce181acb..ad562bb836 100644
                        --- a/assets/quic.html-tieiwfcI.js
                        +++ b/assets/quic.html-WnhipFbM.js
                        @@ -1,4 +1,4 @@
                        -import{_ as e,o as n,c as o,e as s}from"./app-PDrbPfzp.js";const a={},t=s(`

                        QUIC

                        QUIC 全称 Quick UDP Internet Connection,是由 Google 提出的使用 UDP 进行多路并发传输的协议。其主要优势是:

                        1. 减少了握手的延迟(1-RTT 或 0-RTT)
                        2. 多路复用,并且没有 TCP 的阻塞问题
                        3. 连接迁移,(主要是在客户端)当由 Wifi 转移到 4G 时,连接不会被断开。

                        QUIC 目前处于实验期,使用了正在标准化过程中的 IETF 实现,不能保证与最终版本的兼容性。

                        • 默认设定:
                          • 12 字节的 Connection ID
                          • 30 秒没有数据通过时自动断开连接 (可能会影响一些长连接的使用)

                        QuicObject

                        QuicObject 对应传输配置的 quicSettings 项。

                        警告

                        对接的两端的配置必须完全一致,否则连接失败。 QUIC 强制要求开启 TLS,在传输配置中没有开启 TLS 时,Xray 会自行签发一个证书进行 TLS 通讯。

                        {
                        +import{_ as e,o as n,c as o,e as s}from"./app-UOvWaKji.js";const a={},t=s(`

                        QUIC

                        QUIC 全称 Quick UDP Internet Connection,是由 Google 提出的使用 UDP 进行多路并发传输的协议。其主要优势是:

                        1. 减少了握手的延迟(1-RTT 或 0-RTT)
                        2. 多路复用,并且没有 TCP 的阻塞问题
                        3. 连接迁移,(主要是在客户端)当由 Wifi 转移到 4G 时,连接不会被断开。

                        QUIC 目前处于实验期,使用了正在标准化过程中的 IETF 实现,不能保证与最终版本的兼容性。

                        • 默认设定:
                          • 12 字节的 Connection ID
                          • 30 秒没有数据通过时自动断开连接 (可能会影响一些长连接的使用)

                        QuicObject

                        QuicObject 对应传输配置的 quicSettings 项。

                        警告

                        对接的两端的配置必须完全一致,否则连接失败。 QUIC 强制要求开启 TLS,在传输配置中没有开启 TLS 时,Xray 会自行签发一个证书进行 TLS 通讯。

                        {
                           "security": "none",
                           "key": "",
                           "header": {
                        diff --git a/assets/redirect.html-Z0rUViRJ.js b/assets/redirect.html-Fo5Y5X-S.js
                        similarity index 99%
                        rename from assets/redirect.html-Z0rUViRJ.js
                        rename to assets/redirect.html-Fo5Y5X-S.js
                        index 86bdc95513..4b4507bcc3 100644
                        --- a/assets/redirect.html-Z0rUViRJ.js
                        +++ b/assets/redirect.html-Fo5Y5X-S.js
                        @@ -1,4 +1,4 @@
                        -import{_ as e,r as p,o,c as l,a as s,b as n,d as t,e as i}from"./app-PDrbPfzp.js";const c={},u=i(`

                        基于 fwmark 或 sendThrough 的流量重定向

                        通过 Xray 将特定的流量指向特定出口,实现全局路由“分流”

                        前言

                        之前在网络上看到许多代理或者 VPN 会接管全局路由,如果与 Xray 同时安装,会导致 Xray 失效。参考了网络上许多教程,及时分流,也是通过维护一张或者多张 CIDR 路由表来实现的。这种情况下并不优雅,如果我想可以任意替换,实现按需分流,那有没有更好的办法呢?有!

                        通过 fwmark 或 Xray 的 sendThrough/sockopt.interface,再简单配合路由表功能即可实现:

                        1. Xray 可设置指定的 Tag、域名等走指定接口。如果您的接口是双栈的,可以指定 IPV4 或者 IPV6
                        2. 其余用户则走原 IPV4 或者 IPV6

                        具体设置如下(以 Debian10 为例):

                        1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)

                        根据不同系统和不同软件,请参考官方安装方法

                        2、编辑 VPN 配置文件(以 WireGuard 为例)

                        原始文件:

                        [Interface]
                        +import{_ as e,r as p,o,c as l,a as s,b as n,d as t,e as i}from"./app-UOvWaKji.js";const c={},u=i(`

                        基于 fwmark 或 sendThrough 的流量重定向

                        通过 Xray 将特定的流量指向特定出口,实现全局路由“分流”

                        前言

                        之前在网络上看到许多代理或者 VPN 会接管全局路由,如果与 Xray 同时安装,会导致 Xray 失效。参考了网络上许多教程,及时分流,也是通过维护一张或者多张 CIDR 路由表来实现的。这种情况下并不优雅,如果我想可以任意替换,实现按需分流,那有没有更好的办法呢?有!

                        通过 fwmark 或 Xray 的 sendThrough/sockopt.interface,再简单配合路由表功能即可实现:

                        1. Xray 可设置指定的 Tag、域名等走指定接口。如果您的接口是双栈的,可以指定 IPV4 或者 IPV6
                        2. 其余用户则走原 IPV4 或者 IPV6

                        具体设置如下(以 Debian10 为例):

                        1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)

                        根据不同系统和不同软件,请参考官方安装方法

                        2、编辑 VPN 配置文件(以 WireGuard 为例)

                        原始文件:

                        [Interface]
                         PrivateKey = <PriKey>
                         Address = <IPv4>
                         Address = <IPv6>
                        diff --git a/assets/redirect.html-J60JFiXJ.js b/assets/redirect.html-b2j-2sFY.js
                        similarity index 99%
                        rename from assets/redirect.html-J60JFiXJ.js
                        rename to assets/redirect.html-b2j-2sFY.js
                        index 39d4ba0d9f..c2f555f4c6 100644
                        --- a/assets/redirect.html-J60JFiXJ.js
                        +++ b/assets/redirect.html-b2j-2sFY.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as p,o as i,c as r,d as a,w as e,e as l,a as n,b as s}from"./app-PDrbPfzp.js";const u={},k=l('

                        基于 fwmark 或 sendThrough 的流量重定向

                        通过 Xray 将特定的流量指向特定出口,实现全局路由“分流”

                        前言

                        之前在网络上看到许多代理或者 VPN 会接管全局路由,如果与 Xray 同时安装,会导致 Xray 失效。参考了网络上许多教程,及时分流,也是通过维护一张或者多张 CIDR 路由表来实现的。这种情况下并不优雅,如果我想可以任意替换,实现按需分流,那有没有更好的办法呢?有!

                        通过 fwmark 或 Xray 的 sendThrough,再简单配合路由表功能即可实现:

                        1. Xray 可设置指定的 Tag、域名等走指定接口。如果您的接口是双栈的,可以指定 IPV4 或者 IPV6
                        2. 其余用户则走原 IPV4 或者 IPV6

                        具体设置如下(以 Debian10 为例):

                        1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)

                        根据不同系统和不同软件,请参考官方安装方法

                        2、编辑 VPN 配置文件(以 WireGuard 为例)

                        原始文件:

                        ',11),d=n("div",{class:"language-ini line-numbers-mode","data-ext":"ini","data-title":"ini"},[n("pre",{class:"language-ini"},[n("code",null,[n("span",{class:"token section"},[n("span",{class:"token punctuation"},"["),n("span",{class:"token section-name selector"},"Interface"),n("span",{class:"token punctuation"},"]")]),s(` +import{_ as c,r as p,o as i,c as r,d as a,w as e,e as l,a as n,b as s}from"./app-UOvWaKji.js";const u={},k=l('

                        基于 fwmark 或 sendThrough 的流量重定向

                        通过 Xray 将特定的流量指向特定出口,实现全局路由“分流”

                        前言

                        之前在网络上看到许多代理或者 VPN 会接管全局路由,如果与 Xray 同时安装,会导致 Xray 失效。参考了网络上许多教程,及时分流,也是通过维护一张或者多张 CIDR 路由表来实现的。这种情况下并不优雅,如果我想可以任意替换,实现按需分流,那有没有更好的办法呢?有!

                        通过 fwmark 或 Xray 的 sendThrough,再简单配合路由表功能即可实现:

                        1. Xray 可设置指定的 Tag、域名等走指定接口。如果您的接口是双栈的,可以指定 IPV4 或者 IPV6
                        2. 其余用户则走原 IPV4 或者 IPV6

                        具体设置如下(以 Debian10 为例):

                        1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)

                        根据不同系统和不同软件,请参考官方安装方法

                        2、编辑 VPN 配置文件(以 WireGuard 为例)

                        原始文件:

                        ',11),d=n("div",{class:"language-ini line-numbers-mode","data-ext":"ini","data-title":"ini"},[n("pre",{class:"language-ini"},[n("code",null,[n("span",{class:"token section"},[n("span",{class:"token punctuation"},"["),n("span",{class:"token section-name selector"},"Interface"),n("span",{class:"token punctuation"},"]")]),s(` `),n("span",{class:"token key attr-name"},"PrivateKey"),s(),n("span",{class:"token punctuation"},"="),s(),n("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxx"),s(` `),n("span",{class:"token key attr-name"},"Address"),s(),n("span",{class:"token punctuation"},"="),s(),n("span",{class:"token value attr-value"},[s('"'),n("span",{class:"token inner-value"},"your wg0 v4 address"),s('"')]),s(` `),n("span",{class:"token key attr-name"},"Address"),s(),n("span",{class:"token punctuation"},"="),s(),n("span",{class:"token value attr-value"},[s('"'),n("span",{class:"token inner-value"},"your wg0 v6 address"),s('"')]),s(` diff --git a/assets/requirementDiagram-05bf5f74--Z92gB8m.js b/assets/requirementDiagram-05bf5f74-HkrjUmOA.js similarity index 98% rename from assets/requirementDiagram-05bf5f74--Z92gB8m.js rename to assets/requirementDiagram-05bf5f74-HkrjUmOA.js index 4fa5784f6f..2cc0c177c8 100644 --- a/assets/requirementDiagram-05bf5f74--Z92gB8m.js +++ b/assets/requirementDiagram-05bf5f74-HkrjUmOA.js @@ -1,4 +1,4 @@ -import{c as Te,s as Ce,g as Fe,b as Me,a as De,l as Ne,A as Pe,h as oe,i as Ye,j as ke}from"./mermaid.core-95b3ca__.js";import{G as Ue}from"./graph-cZfODKa1.js";import{l as Be}from"./layout-konkdG3Z.js";import{l as Qe}from"./line-_nnM_7ZX.js";import"./app-PDrbPfzp.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";var ce=function(){var e=function(V,i,n,a){for(n=n||{},a=V.length;a--;n[V[a]]=i);return n},t=[1,3],l=[1,4],c=[1,5],u=[1,6],d=[5,6,8,9,11,13,31,32,33,34,35,36,44,62,63],p=[1,18],h=[2,7],o=[1,22],g=[1,23],R=[1,24],A=[1,25],T=[1,26],N=[1,27],v=[1,20],k=[1,28],x=[1,29],F=[62,63],de=[5,8,9,11,13,31,32,33,34,35,36,44,51,53,62,63],pe=[1,47],fe=[1,48],ye=[1,49],_e=[1,50],ge=[1,51],Ee=[1,52],Re=[1,53],O=[53,54],M=[1,64],D=[1,60],P=[1,61],Y=[1,62],U=[1,63],B=[1,65],j=[1,69],z=[1,70],X=[1,67],J=[1,68],m=[5,8,9,11,13,31,32,33,34,35,36,44,62,63],ie={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,requirementType:17,requirementName:18,STRUCT_START:19,requirementBody:20,ID:21,COLONSEP:22,id:23,TEXT:24,text:25,RISK:26,riskLevel:27,VERIFYMTHD:28,verifyType:29,STRUCT_STOP:30,REQUIREMENT:31,FUNCTIONAL_REQUIREMENT:32,INTERFACE_REQUIREMENT:33,PERFORMANCE_REQUIREMENT:34,PHYSICAL_REQUIREMENT:35,DESIGN_CONSTRAINT:36,LOW_RISK:37,MED_RISK:38,HIGH_RISK:39,VERIFY_ANALYSIS:40,VERIFY_DEMONSTRATION:41,VERIFY_INSPECTION:42,VERIFY_TEST:43,ELEMENT:44,elementName:45,elementBody:46,TYPE:47,type:48,DOCREF:49,ref:50,END_ARROW_L:51,relationship:52,LINE:53,END_ARROW_R:54,CONTAINS:55,COPIES:56,DERIVES:57,SATISFIES:58,VERIFIES:59,REFINES:60,TRACES:61,unqString:62,qString:63,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",19:"STRUCT_START",21:"ID",22:"COLONSEP",24:"TEXT",26:"RISK",28:"VERIFYMTHD",30:"STRUCT_STOP",31:"REQUIREMENT",32:"FUNCTIONAL_REQUIREMENT",33:"INTERFACE_REQUIREMENT",34:"PERFORMANCE_REQUIREMENT",35:"PHYSICAL_REQUIREMENT",36:"DESIGN_CONSTRAINT",37:"LOW_RISK",38:"MED_RISK",39:"HIGH_RISK",40:"VERIFY_ANALYSIS",41:"VERIFY_DEMONSTRATION",42:"VERIFY_INSPECTION",43:"VERIFY_TEST",44:"ELEMENT",47:"TYPE",49:"DOCREF",51:"END_ARROW_L",53:"LINE",54:"END_ARROW_R",55:"CONTAINS",56:"COPIES",57:"DERIVES",58:"SATISFIES",59:"VERIFIES",60:"REFINES",61:"TRACES",62:"unqString",63:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[14,5],[20,5],[20,5],[20,5],[20,5],[20,2],[20,1],[17,1],[17,1],[17,1],[17,1],[17,1],[17,1],[27,1],[27,1],[27,1],[29,1],[29,1],[29,1],[29,1],[15,5],[46,5],[46,5],[46,2],[46,1],[16,5],[16,5],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[18,1],[18,1],[23,1],[23,1],[25,1],[25,1],[45,1],[45,1],[48,1],[48,1],[50,1],[50,1]],performAction:function(i,n,a,r,f,s,W){var _=s.length-1;switch(f){case 4:this.$=s[_].trim(),r.setAccTitle(this.$);break;case 5:case 6:this.$=s[_].trim(),r.setAccDescription(this.$);break;case 7:this.$=[];break;case 13:r.addRequirement(s[_-3],s[_-4]);break;case 14:r.setNewReqId(s[_-2]);break;case 15:r.setNewReqText(s[_-2]);break;case 16:r.setNewReqRisk(s[_-2]);break;case 17:r.setNewReqVerifyMethod(s[_-2]);break;case 20:this.$=r.RequirementType.REQUIREMENT;break;case 21:this.$=r.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 22:this.$=r.RequirementType.INTERFACE_REQUIREMENT;break;case 23:this.$=r.RequirementType.PERFORMANCE_REQUIREMENT;break;case 24:this.$=r.RequirementType.PHYSICAL_REQUIREMENT;break;case 25:this.$=r.RequirementType.DESIGN_CONSTRAINT;break;case 26:this.$=r.RiskLevel.LOW_RISK;break;case 27:this.$=r.RiskLevel.MED_RISK;break;case 28:this.$=r.RiskLevel.HIGH_RISK;break;case 29:this.$=r.VerifyType.VERIFY_ANALYSIS;break;case 30:this.$=r.VerifyType.VERIFY_DEMONSTRATION;break;case 31:this.$=r.VerifyType.VERIFY_INSPECTION;break;case 32:this.$=r.VerifyType.VERIFY_TEST;break;case 33:r.addElement(s[_-3]);break;case 34:r.setNewElementType(s[_-2]);break;case 35:r.setNewElementDocRef(s[_-2]);break;case 38:r.addRelationship(s[_-2],s[_],s[_-4]);break;case 39:r.addRelationship(s[_-2],s[_-4],s[_]);break;case 40:this.$=r.Relationships.CONTAINS;break;case 41:this.$=r.Relationships.COPIES;break;case 42:this.$=r.Relationships.DERIVES;break;case 43:this.$=r.Relationships.SATISFIES;break;case 44:this.$=r.Relationships.VERIFIES;break;case 45:this.$=r.Relationships.REFINES;break;case 46:this.$=r.Relationships.TRACES;break}},table:[{3:1,4:2,6:t,9:l,11:c,13:u},{1:[3]},{3:8,4:2,5:[1,7],6:t,9:l,11:c,13:u},{5:[1,9]},{10:[1,10]},{12:[1,11]},e(d,[2,6]),{3:12,4:2,6:t,9:l,11:c,13:u},{1:[2,2]},{4:17,5:p,7:13,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},e(d,[2,4]),e(d,[2,5]),{1:[2,1]},{8:[1,30]},{4:17,5:p,7:31,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},{4:17,5:p,7:32,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},{4:17,5:p,7:33,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},{4:17,5:p,7:34,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},{4:17,5:p,7:35,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},{18:36,62:[1,37],63:[1,38]},{45:39,62:[1,40],63:[1,41]},{51:[1,42],53:[1,43]},e(F,[2,20]),e(F,[2,21]),e(F,[2,22]),e(F,[2,23]),e(F,[2,24]),e(F,[2,25]),e(de,[2,49]),e(de,[2,50]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{19:[1,44]},{19:[2,47]},{19:[2,48]},{19:[1,45]},{19:[2,53]},{19:[2,54]},{52:46,55:pe,56:fe,57:ye,58:_e,59:ge,60:Ee,61:Re},{52:54,55:pe,56:fe,57:ye,58:_e,59:ge,60:Ee,61:Re},{5:[1,55]},{5:[1,56]},{53:[1,57]},e(O,[2,40]),e(O,[2,41]),e(O,[2,42]),e(O,[2,43]),e(O,[2,44]),e(O,[2,45]),e(O,[2,46]),{54:[1,58]},{5:M,20:59,21:D,24:P,26:Y,28:U,30:B},{5:j,30:z,46:66,47:X,49:J},{23:71,62:k,63:x},{23:72,62:k,63:x},e(m,[2,13]),{22:[1,73]},{22:[1,74]},{22:[1,75]},{22:[1,76]},{5:M,20:77,21:D,24:P,26:Y,28:U,30:B},e(m,[2,19]),e(m,[2,33]),{22:[1,78]},{22:[1,79]},{5:j,30:z,46:80,47:X,49:J},e(m,[2,37]),e(m,[2,38]),e(m,[2,39]),{23:81,62:k,63:x},{25:82,62:[1,83],63:[1,84]},{27:85,37:[1,86],38:[1,87],39:[1,88]},{29:89,40:[1,90],41:[1,91],42:[1,92],43:[1,93]},e(m,[2,18]),{48:94,62:[1,95],63:[1,96]},{50:97,62:[1,98],63:[1,99]},e(m,[2,36]),{5:[1,100]},{5:[1,101]},{5:[2,51]},{5:[2,52]},{5:[1,102]},{5:[2,26]},{5:[2,27]},{5:[2,28]},{5:[1,103]},{5:[2,29]},{5:[2,30]},{5:[2,31]},{5:[2,32]},{5:[1,104]},{5:[2,55]},{5:[2,56]},{5:[1,105]},{5:[2,57]},{5:[2,58]},{5:M,20:106,21:D,24:P,26:Y,28:U,30:B},{5:M,20:107,21:D,24:P,26:Y,28:U,30:B},{5:M,20:108,21:D,24:P,26:Y,28:U,30:B},{5:M,20:109,21:D,24:P,26:Y,28:U,30:B},{5:j,30:z,46:110,47:X,49:J},{5:j,30:z,46:111,47:X,49:J},e(m,[2,14]),e(m,[2,15]),e(m,[2,16]),e(m,[2,17]),e(m,[2,34]),e(m,[2,35])],defaultActions:{8:[2,2],12:[2,1],30:[2,3],31:[2,8],32:[2,9],33:[2,10],34:[2,11],35:[2,12],37:[2,47],38:[2,48],40:[2,53],41:[2,54],83:[2,51],84:[2,52],86:[2,26],87:[2,27],88:[2,28],90:[2,29],91:[2,30],92:[2,31],93:[2,32],95:[2,55],96:[2,56],98:[2,57],99:[2,58]},parseError:function(i,n){if(n.recoverable)this.trace(i);else{var a=new Error(i);throw a.hash=n,a}},parse:function(i){var n=this,a=[0],r=[],f=[null],s=[],W=this.table,_="",Z=0,me=0,Ve=2,Ie=1,qe=s.slice.call(arguments,1),E=Object.create(this.lexer),L={yy:{}};for(var ne in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ne)&&(L.yy[ne]=this.yy[ne]);E.setInput(i,L.yy),L.yy.lexer=E,L.yy.parser=this,typeof E.yylloc>"u"&&(E.yylloc={});var se=E.yylloc;s.push(se);var Oe=E.options&&E.options.ranges;typeof L.yy.parseError=="function"?this.parseError=L.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Le(){var $;return $=r.pop()||E.lex()||Ie,typeof $!="number"&&($ instanceof Array&&(r=$,$=r.pop()),$=n.symbols_[$]||$),$}for(var I,C,S,ae,Q={},ee,w,be,te;;){if(C=a[a.length-1],this.defaultActions[C]?S=this.defaultActions[C]:((I===null||typeof I>"u")&&(I=Le()),S=W[C]&&W[C][I]),typeof S>"u"||!S.length||!S[0]){var le="";te=[];for(ee in W[C])this.terminals_[ee]&&ee>Ve&&te.push("'"+this.terminals_[ee]+"'");E.showPosition?le="Parse error on line "+(Z+1)+`: +import{c as Te,s as Ce,g as Fe,b as Me,a as De,l as Ne,A as Pe,h as oe,i as Ye,j as ke}from"./mermaid.core-Q3WVcjPF.js";import{G as Ue}from"./graph-yVkSecXb.js";import{l as Be}from"./layout-2f_iGf4E.js";import{l as Qe}from"./line-3Gyevr9q.js";import"./app-UOvWaKji.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";var ce=function(){var e=function(V,i,n,a){for(n=n||{},a=V.length;a--;n[V[a]]=i);return n},t=[1,3],l=[1,4],c=[1,5],u=[1,6],d=[5,6,8,9,11,13,31,32,33,34,35,36,44,62,63],p=[1,18],h=[2,7],o=[1,22],g=[1,23],R=[1,24],A=[1,25],T=[1,26],N=[1,27],v=[1,20],k=[1,28],x=[1,29],F=[62,63],de=[5,8,9,11,13,31,32,33,34,35,36,44,51,53,62,63],pe=[1,47],fe=[1,48],ye=[1,49],_e=[1,50],ge=[1,51],Ee=[1,52],Re=[1,53],O=[53,54],M=[1,64],D=[1,60],P=[1,61],Y=[1,62],U=[1,63],B=[1,65],j=[1,69],z=[1,70],X=[1,67],J=[1,68],m=[5,8,9,11,13,31,32,33,34,35,36,44,62,63],ie={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,requirementType:17,requirementName:18,STRUCT_START:19,requirementBody:20,ID:21,COLONSEP:22,id:23,TEXT:24,text:25,RISK:26,riskLevel:27,VERIFYMTHD:28,verifyType:29,STRUCT_STOP:30,REQUIREMENT:31,FUNCTIONAL_REQUIREMENT:32,INTERFACE_REQUIREMENT:33,PERFORMANCE_REQUIREMENT:34,PHYSICAL_REQUIREMENT:35,DESIGN_CONSTRAINT:36,LOW_RISK:37,MED_RISK:38,HIGH_RISK:39,VERIFY_ANALYSIS:40,VERIFY_DEMONSTRATION:41,VERIFY_INSPECTION:42,VERIFY_TEST:43,ELEMENT:44,elementName:45,elementBody:46,TYPE:47,type:48,DOCREF:49,ref:50,END_ARROW_L:51,relationship:52,LINE:53,END_ARROW_R:54,CONTAINS:55,COPIES:56,DERIVES:57,SATISFIES:58,VERIFIES:59,REFINES:60,TRACES:61,unqString:62,qString:63,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",19:"STRUCT_START",21:"ID",22:"COLONSEP",24:"TEXT",26:"RISK",28:"VERIFYMTHD",30:"STRUCT_STOP",31:"REQUIREMENT",32:"FUNCTIONAL_REQUIREMENT",33:"INTERFACE_REQUIREMENT",34:"PERFORMANCE_REQUIREMENT",35:"PHYSICAL_REQUIREMENT",36:"DESIGN_CONSTRAINT",37:"LOW_RISK",38:"MED_RISK",39:"HIGH_RISK",40:"VERIFY_ANALYSIS",41:"VERIFY_DEMONSTRATION",42:"VERIFY_INSPECTION",43:"VERIFY_TEST",44:"ELEMENT",47:"TYPE",49:"DOCREF",51:"END_ARROW_L",53:"LINE",54:"END_ARROW_R",55:"CONTAINS",56:"COPIES",57:"DERIVES",58:"SATISFIES",59:"VERIFIES",60:"REFINES",61:"TRACES",62:"unqString",63:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[14,5],[20,5],[20,5],[20,5],[20,5],[20,2],[20,1],[17,1],[17,1],[17,1],[17,1],[17,1],[17,1],[27,1],[27,1],[27,1],[29,1],[29,1],[29,1],[29,1],[15,5],[46,5],[46,5],[46,2],[46,1],[16,5],[16,5],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[18,1],[18,1],[23,1],[23,1],[25,1],[25,1],[45,1],[45,1],[48,1],[48,1],[50,1],[50,1]],performAction:function(i,n,a,r,f,s,W){var _=s.length-1;switch(f){case 4:this.$=s[_].trim(),r.setAccTitle(this.$);break;case 5:case 6:this.$=s[_].trim(),r.setAccDescription(this.$);break;case 7:this.$=[];break;case 13:r.addRequirement(s[_-3],s[_-4]);break;case 14:r.setNewReqId(s[_-2]);break;case 15:r.setNewReqText(s[_-2]);break;case 16:r.setNewReqRisk(s[_-2]);break;case 17:r.setNewReqVerifyMethod(s[_-2]);break;case 20:this.$=r.RequirementType.REQUIREMENT;break;case 21:this.$=r.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 22:this.$=r.RequirementType.INTERFACE_REQUIREMENT;break;case 23:this.$=r.RequirementType.PERFORMANCE_REQUIREMENT;break;case 24:this.$=r.RequirementType.PHYSICAL_REQUIREMENT;break;case 25:this.$=r.RequirementType.DESIGN_CONSTRAINT;break;case 26:this.$=r.RiskLevel.LOW_RISK;break;case 27:this.$=r.RiskLevel.MED_RISK;break;case 28:this.$=r.RiskLevel.HIGH_RISK;break;case 29:this.$=r.VerifyType.VERIFY_ANALYSIS;break;case 30:this.$=r.VerifyType.VERIFY_DEMONSTRATION;break;case 31:this.$=r.VerifyType.VERIFY_INSPECTION;break;case 32:this.$=r.VerifyType.VERIFY_TEST;break;case 33:r.addElement(s[_-3]);break;case 34:r.setNewElementType(s[_-2]);break;case 35:r.setNewElementDocRef(s[_-2]);break;case 38:r.addRelationship(s[_-2],s[_],s[_-4]);break;case 39:r.addRelationship(s[_-2],s[_-4],s[_]);break;case 40:this.$=r.Relationships.CONTAINS;break;case 41:this.$=r.Relationships.COPIES;break;case 42:this.$=r.Relationships.DERIVES;break;case 43:this.$=r.Relationships.SATISFIES;break;case 44:this.$=r.Relationships.VERIFIES;break;case 45:this.$=r.Relationships.REFINES;break;case 46:this.$=r.Relationships.TRACES;break}},table:[{3:1,4:2,6:t,9:l,11:c,13:u},{1:[3]},{3:8,4:2,5:[1,7],6:t,9:l,11:c,13:u},{5:[1,9]},{10:[1,10]},{12:[1,11]},e(d,[2,6]),{3:12,4:2,6:t,9:l,11:c,13:u},{1:[2,2]},{4:17,5:p,7:13,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},e(d,[2,4]),e(d,[2,5]),{1:[2,1]},{8:[1,30]},{4:17,5:p,7:31,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},{4:17,5:p,7:32,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},{4:17,5:p,7:33,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},{4:17,5:p,7:34,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},{4:17,5:p,7:35,8:h,9:l,11:c,13:u,14:14,15:15,16:16,17:19,23:21,31:o,32:g,33:R,34:A,35:T,36:N,44:v,62:k,63:x},{18:36,62:[1,37],63:[1,38]},{45:39,62:[1,40],63:[1,41]},{51:[1,42],53:[1,43]},e(F,[2,20]),e(F,[2,21]),e(F,[2,22]),e(F,[2,23]),e(F,[2,24]),e(F,[2,25]),e(de,[2,49]),e(de,[2,50]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{19:[1,44]},{19:[2,47]},{19:[2,48]},{19:[1,45]},{19:[2,53]},{19:[2,54]},{52:46,55:pe,56:fe,57:ye,58:_e,59:ge,60:Ee,61:Re},{52:54,55:pe,56:fe,57:ye,58:_e,59:ge,60:Ee,61:Re},{5:[1,55]},{5:[1,56]},{53:[1,57]},e(O,[2,40]),e(O,[2,41]),e(O,[2,42]),e(O,[2,43]),e(O,[2,44]),e(O,[2,45]),e(O,[2,46]),{54:[1,58]},{5:M,20:59,21:D,24:P,26:Y,28:U,30:B},{5:j,30:z,46:66,47:X,49:J},{23:71,62:k,63:x},{23:72,62:k,63:x},e(m,[2,13]),{22:[1,73]},{22:[1,74]},{22:[1,75]},{22:[1,76]},{5:M,20:77,21:D,24:P,26:Y,28:U,30:B},e(m,[2,19]),e(m,[2,33]),{22:[1,78]},{22:[1,79]},{5:j,30:z,46:80,47:X,49:J},e(m,[2,37]),e(m,[2,38]),e(m,[2,39]),{23:81,62:k,63:x},{25:82,62:[1,83],63:[1,84]},{27:85,37:[1,86],38:[1,87],39:[1,88]},{29:89,40:[1,90],41:[1,91],42:[1,92],43:[1,93]},e(m,[2,18]),{48:94,62:[1,95],63:[1,96]},{50:97,62:[1,98],63:[1,99]},e(m,[2,36]),{5:[1,100]},{5:[1,101]},{5:[2,51]},{5:[2,52]},{5:[1,102]},{5:[2,26]},{5:[2,27]},{5:[2,28]},{5:[1,103]},{5:[2,29]},{5:[2,30]},{5:[2,31]},{5:[2,32]},{5:[1,104]},{5:[2,55]},{5:[2,56]},{5:[1,105]},{5:[2,57]},{5:[2,58]},{5:M,20:106,21:D,24:P,26:Y,28:U,30:B},{5:M,20:107,21:D,24:P,26:Y,28:U,30:B},{5:M,20:108,21:D,24:P,26:Y,28:U,30:B},{5:M,20:109,21:D,24:P,26:Y,28:U,30:B},{5:j,30:z,46:110,47:X,49:J},{5:j,30:z,46:111,47:X,49:J},e(m,[2,14]),e(m,[2,15]),e(m,[2,16]),e(m,[2,17]),e(m,[2,34]),e(m,[2,35])],defaultActions:{8:[2,2],12:[2,1],30:[2,3],31:[2,8],32:[2,9],33:[2,10],34:[2,11],35:[2,12],37:[2,47],38:[2,48],40:[2,53],41:[2,54],83:[2,51],84:[2,52],86:[2,26],87:[2,27],88:[2,28],90:[2,29],91:[2,30],92:[2,31],93:[2,32],95:[2,55],96:[2,56],98:[2,57],99:[2,58]},parseError:function(i,n){if(n.recoverable)this.trace(i);else{var a=new Error(i);throw a.hash=n,a}},parse:function(i){var n=this,a=[0],r=[],f=[null],s=[],W=this.table,_="",Z=0,me=0,Ve=2,Ie=1,qe=s.slice.call(arguments,1),E=Object.create(this.lexer),L={yy:{}};for(var ne in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ne)&&(L.yy[ne]=this.yy[ne]);E.setInput(i,L.yy),L.yy.lexer=E,L.yy.parser=this,typeof E.yylloc>"u"&&(E.yylloc={});var se=E.yylloc;s.push(se);var Oe=E.options&&E.options.ranges;typeof L.yy.parseError=="function"?this.parseError=L.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Le(){var $;return $=r.pop()||E.lex()||Ie,typeof $!="number"&&($ instanceof Array&&(r=$,$=r.pop()),$=n.symbols_[$]||$),$}for(var I,C,S,ae,Q={},ee,w,be,te;;){if(C=a[a.length-1],this.defaultActions[C]?S=this.defaultActions[C]:((I===null||typeof I>"u")&&(I=Le()),S=W[C]&&W[C][I]),typeof S>"u"||!S.length||!S[0]){var le="";te=[];for(ee in W[C])this.terminals_[ee]&&ee>Ve&&te.push("'"+this.terminals_[ee]+"'");E.showPosition?le="Parse error on line "+(Z+1)+`: `+E.showPosition()+` Expecting `+te.join(", ")+", got '"+(this.terminals_[I]||I)+"'":le="Parse error on line "+(Z+1)+": Unexpected "+(I==Ie?"end of input":"'"+(this.terminals_[I]||I)+"'"),this.parseError(le,{text:E.match,token:this.terminals_[I]||I,line:E.yylineno,loc:se,expected:te})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+C+", token: "+I);switch(S[0]){case 1:a.push(I),f.push(E.yytext),s.push(E.yylloc),a.push(S[1]),I=null,me=E.yyleng,_=E.yytext,Z=E.yylineno,se=E.yylloc;break;case 2:if(w=this.productions_[S[1]][1],Q.$=f[f.length-w],Q._$={first_line:s[s.length-(w||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(w||1)].first_column,last_column:s[s.length-1].last_column},Oe&&(Q._$.range=[s[s.length-(w||1)].range[0],s[s.length-1].range[1]]),ae=this.performAction.apply(Q,[_,me,Z,L.yy,S[1],f,s].concat(qe)),typeof ae<"u")return ae;w&&(a=a.slice(0,-1*w*2),f=f.slice(0,-1*w),s=s.slice(0,-1*w)),a.push(this.productions_[S[1]][0]),f.push(Q.$),s.push(Q._$),be=W[a[a.length-2]][a[a.length-1]],a.push(be);break;case 3:return!0}}return!0}},$e=function(){var V={EOF:1,parseError:function(n,a){if(this.yy.parser)this.yy.parser.parseError(n,a);else throw new Error(n)},setInput:function(i,n){return this.yy=n||this.yy||{},this._input=i,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var i=this._input[0];this.yytext+=i,this.yyleng++,this.offset++,this.match+=i,this.matched+=i;var n=i.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),i},unput:function(i){var n=i.length,a=i.split(/(?:\r\n?|\n)/g);this._input=i+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var f=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===r.length?this.yylloc.first_column:0)+r[r.length-a.length].length-a[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[f[0],f[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(i){this.unput(this.match.slice(i))},pastInput:function(){var i=this.matched.substr(0,this.matched.length-this.match.length);return(i.length>20?"...":"")+i.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var i=this.match;return i.length<20&&(i+=this._input.substr(0,20-i.length)),(i.substr(0,20)+(i.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var i=this.pastInput(),n=new Array(i.length+1).join("-");return i+this.upcomingInput()+` diff --git a/assets/reverse.html-kt-Xsscv.js b/assets/reverse.html-pdrvooXr.js similarity index 99% rename from assets/reverse.html-kt-Xsscv.js rename to assets/reverse.html-pdrvooXr.js index edb536bbc1..b234ddb771 100644 --- a/assets/reverse.html-kt-Xsscv.js +++ b/assets/reverse.html-pdrvooXr.js @@ -1,4 +1,4 @@ -import{_ as p,r as c,o as i,c as l,a as s,b as n,d as o,w as e,e as a}from"./app-PDrbPfzp.js";const u={},r=a('

                        反向代理

                        反向代理可以把服务器端的流量向客户端转发,即逆向流量转发。

                        反向代理的大致工作原理如下:

                        • 假设在主机 A 中有一个网页服务器,这台主机没有公网 IP,无法在公网上直接访问。另有一台主机 B,它可以由公网访问。现在我们需要把 B 作为入口,把流量从 B 转发到 A。
                        • 在主机 A 中配置 Xray,称为bridge,在 B 中也配置 Xray,称为 portal
                        • bridge 会向 portal 主动建立连接,此连接的目标地址可以自行设定。portal 会收到两种连接,一是由 bridge 发来的连接,二是公网用户发来的连接。portal 会自动将两类连接合并。于是 bridge 就可以收到公网流量了。
                        • bridge 在收到公网流量之后,会将其原封不动地发给主机 A 中的网页服务器。当然,这一步需要路由的协作。
                        • bridge 会根据流量的大小进行动态的负载均衡。
                        ',4),d={class:"custom-container tip"},v=s("p",{class:"custom-container-title"},"提示",-1),k=a(`

                        注意

                        反向代理功能尚处于测试阶段,可能会有一些问题。

                        ReverseObject

                        ReverseObject 对应配置文件的 reverse 项。

                        {
                        +import{_ as p,r as c,o as i,c as l,a as s,b as n,d as o,w as e,e as a}from"./app-UOvWaKji.js";const u={},r=a('

                        反向代理

                        反向代理可以把服务器端的流量向客户端转发,即逆向流量转发。

                        反向代理的大致工作原理如下:

                        • 假设在主机 A 中有一个网页服务器,这台主机没有公网 IP,无法在公网上直接访问。另有一台主机 B,它可以由公网访问。现在我们需要把 B 作为入口,把流量从 B 转发到 A。
                        • 在主机 A 中配置 Xray,称为bridge,在 B 中也配置 Xray,称为 portal
                        • bridge 会向 portal 主动建立连接,此连接的目标地址可以自行设定。portal 会收到两种连接,一是由 bridge 发来的连接,二是公网用户发来的连接。portal 会自动将两类连接合并。于是 bridge 就可以收到公网流量了。
                        • bridge 在收到公网流量之后,会将其原封不动地发给主机 A 中的网页服务器。当然,这一步需要路由的协作。
                        • bridge 会根据流量的大小进行动态的负载均衡。
                        ',4),d={class:"custom-container tip"},v=s("p",{class:"custom-container-title"},"提示",-1),k=a(`

                        注意

                        反向代理功能尚处于测试阶段,可能会有一些问题。

                        ReverseObject

                        ReverseObject 对应配置文件的 reverse 项。

                        {
                           "reverse": {
                             "bridges": [
                               {
                        diff --git a/assets/reverse.html-wshR1As_.js b/assets/reverse.html-w7txkdmv.js
                        similarity index 99%
                        rename from assets/reverse.html-wshR1As_.js
                        rename to assets/reverse.html-w7txkdmv.js
                        index b35cd866ac..e3f0455f52 100644
                        --- a/assets/reverse.html-wshR1As_.js
                        +++ b/assets/reverse.html-w7txkdmv.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as i,o as c,c as r,a as s,b as n,d as t,w as o,e as a}from"./app-PDrbPfzp.js";const l={},u=a(`

                        Reverse Proxy

                        A reverse proxy forwards traffic from a server to a client, which is known as reverse traffic forwarding.

                        Here's how a reverse proxy generally works:

                        • Suppose there is a web server in host A, which does not have a public IP address and cannot be accessed directly on the Internet. There is another host B that can be accessed via the public network. Now we need to use B as the entry point to forward traffic from B to A.
                        • Configure Xray in host A as a bridge, and also configure Xray in B as a portal.
                        • Bridge will actively establish a connection to portal, and the destination address of this connection can be set by itself. Portal will receive two types of connections: one is the connection sent by bridge, and the other is the connection sent by public network users. Portal will automatically merge the two types of connections. So bridge can receive public network traffic.
                        • After receiving the public network traffic, bridge will forward it unchanged to the web server in host A. Of course, this step requires the cooperation of routing.
                        • Bridge will dynamically load balance according to the size of the traffic.

                        Tip

                        Reverse proxy has Mux enabled by default, so please do not enable Mux again on the outbound it uses.

                        Warning

                        The reverse proxy function is still in the testing phase and may have some issues.

                        ReverseObject

                        ReverseObject corresponds to the reverse field in the configuration file.

                        {
                        +import{_ as p,r as i,o as c,c as r,a as s,b as n,d as t,w as o,e as a}from"./app-UOvWaKji.js";const l={},u=a(`

                        Reverse Proxy

                        A reverse proxy forwards traffic from a server to a client, which is known as reverse traffic forwarding.

                        Here's how a reverse proxy generally works:

                        • Suppose there is a web server in host A, which does not have a public IP address and cannot be accessed directly on the Internet. There is another host B that can be accessed via the public network. Now we need to use B as the entry point to forward traffic from B to A.
                        • Configure Xray in host A as a bridge, and also configure Xray in B as a portal.
                        • Bridge will actively establish a connection to portal, and the destination address of this connection can be set by itself. Portal will receive two types of connections: one is the connection sent by bridge, and the other is the connection sent by public network users. Portal will automatically merge the two types of connections. So bridge can receive public network traffic.
                        • After receiving the public network traffic, bridge will forward it unchanged to the web server in host A. Of course, this step requires the cooperation of routing.
                        • Bridge will dynamically load balance according to the size of the traffic.

                        Tip

                        Reverse proxy has Mux enabled by default, so please do not enable Mux again on the outbound it uses.

                        Warning

                        The reverse proxy function is still in the testing phase and may have some issues.

                        ReverseObject

                        ReverseObject corresponds to the reverse field in the configuration file.

                        {
                           "reverse": {
                             "bridges": [
                               {
                        diff --git a/assets/routing-lv1-part1.html-aK2Ox0S3.js b/assets/routing-lv1-part1.html-WHpw4v1x.js
                        similarity index 99%
                        rename from assets/routing-lv1-part1.html-aK2Ox0S3.js
                        rename to assets/routing-lv1-part1.html-WHpw4v1x.js
                        index 54ab93a5d7..4be409b24e 100644
                        --- a/assets/routing-lv1-part1.html-aK2Ox0S3.js
                        +++ b/assets/routing-lv1-part1.html-WHpw4v1x.js
                        @@ -1,4 +1,4 @@
                        -import{_ as l,r as p,o as i,c as u,d as a,a as n,b as s,w as r,e as t}from"./app-PDrbPfzp.js";const d="/assets/routing-lv1-img01-trio-Wh5zre5M.png",k={},v=t('

                        路由 (routing) 功能简析(上)

                        如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。

                        1. 初识【路由】三兄弟

                        要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. 入站;2. 路由;3. 出站

                        路由三兄弟

                        三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。

                        所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。

                        因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。

                        啰嗦君

                        路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。

                        2. 基本功: “兄弟一条心”

                        下图的示例,就是在客户端的 Xray 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。

                        ',11),g=t(`

                        下面我们来逐个分析:

                        2.1 入站

                        Tip

                        入站: 就是流量如何流入 Xray

                        下面的入站配置示例,用大白话说就是:数据按照 socks 协议,通过 10808 端口,从本机 127.0.0.1 流入Xray。同时,Xray 将这个入站用 [tag] 命名为 inbound-10808

                        {
                        +import{_ as l,r as p,o as i,c as u,d as a,a as n,b as s,w as r,e as t}from"./app-UOvWaKji.js";const d="/assets/routing-lv1-img01-trio-Wh5zre5M.png",k={},v=t('

                        路由 (routing) 功能简析(上)

                        如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。

                        1. 初识【路由】三兄弟

                        要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. 入站;2. 路由;3. 出站

                        路由三兄弟

                        三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。

                        所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。

                        因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。

                        啰嗦君

                        路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。

                        2. 基本功: “兄弟一条心”

                        下图的示例,就是在客户端的 Xray 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。

                        ',11),g=t(`

                        下面我们来逐个分析:

                        2.1 入站

                        Tip

                        入站: 就是流量如何流入 Xray

                        下面的入站配置示例,用大白话说就是:数据按照 socks 协议,通过 10808 端口,从本机 127.0.0.1 流入Xray。同时,Xray 将这个入站用 [tag] 命名为 inbound-10808

                        {
                           "inbounds": [
                             {
                               "tag": "inbound-10808",
                        diff --git a/assets/routing-lv1-part1.html-XHZo4O7q.js b/assets/routing-lv1-part1.html-s_m1VGph.js
                        similarity index 99%
                        rename from assets/routing-lv1-part1.html-XHZo4O7q.js
                        rename to assets/routing-lv1-part1.html-s_m1VGph.js
                        index 7043dd6c55..b667afc8c9 100644
                        --- a/assets/routing-lv1-part1.html-XHZo4O7q.js
                        +++ b/assets/routing-lv1-part1.html-s_m1VGph.js
                        @@ -1,4 +1,4 @@
                        -import{_ as l,r as p,o as i,c as u,d as a,a as n,b as s,w as r,e as t}from"./app-PDrbPfzp.js";const d="/assets/routing-lv1-img01-trio-Wh5zre5M.png",k={},v=t('

                        路由 (routing) 功能简析(上)

                        如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。

                        1. 初识【路由】三兄弟

                        要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. 入站;2. 路由;3. 出站

                        路由三兄弟

                        三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。

                        所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。

                        因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。

                        啰嗦君

                        路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。

                        2. 基本功: “兄弟一条心”

                        下图的示例,就是在客户端的 Xray 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。

                        ',11),g=t(`

                        下面我们来逐个分析:

                        2.1 入站

                        提示

                        入站: 就是流量如何流入 Xray

                        下面的入站配置示例,用大白话说就是:数据按照 socks 协议,通过 10808 端口,从本机 127.0.0.1 流入Xray。同时,Xray 将这个入站用 [tag] 命名为 inbound-10808

                        {
                        +import{_ as l,r as p,o as i,c as u,d as a,a as n,b as s,w as r,e as t}from"./app-UOvWaKji.js";const d="/assets/routing-lv1-img01-trio-Wh5zre5M.png",k={},v=t('

                        路由 (routing) 功能简析(上)

                        如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。

                        1. 初识【路由】三兄弟

                        要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. 入站;2. 路由;3. 出站

                        路由三兄弟

                        三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。

                        所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。

                        因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。

                        啰嗦君

                        路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。

                        2. 基本功: “兄弟一条心”

                        下图的示例,就是在客户端的 Xray 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。

                        ',11),g=t(`

                        下面我们来逐个分析:

                        2.1 入站

                        提示

                        入站: 就是流量如何流入 Xray

                        下面的入站配置示例,用大白话说就是:数据按照 socks 协议,通过 10808 端口,从本机 127.0.0.1 流入Xray。同时,Xray 将这个入站用 [tag] 命名为 inbound-10808

                        {
                           "inbounds": [
                             {
                               "tag": "inbound-10808",
                        diff --git a/assets/routing-lv1-part2.html-tkJjuuVl.js b/assets/routing-lv1-part2.html-FFYQ14md.js
                        similarity index 99%
                        rename from assets/routing-lv1-part2.html-tkJjuuVl.js
                        rename to assets/routing-lv1-part2.html-FFYQ14md.js
                        index c552c5fd81..29a2c3aeb1 100644
                        --- a/assets/routing-lv1-part2.html-tkJjuuVl.js
                        +++ b/assets/routing-lv1-part2.html-FFYQ14md.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as p,o as l,c as u,a as s,b as n,d as a,w as e,e as o}from"./app-PDrbPfzp.js";const d={},r=s("h1",{id:"路由-routing-功能简析-下",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#路由-routing-功能简析-下"},[s("span",null,"路由 (routing) 功能简析(下)")])],-1),k=s("p",null,[n("欢迎继续学习 "),s("code",null,"Xray"),n(" 的【路由】功能!")],-1),v=s("code",null,"geosite.dat",-1),m=o('

                        如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!

                        5. 攻城略池 - 多种路由匹配条件

                        [域名], [IP], [协议], etc.

                        基于域名的分流,已经可以让我们对网络流量进行基本合理的分流。为什么说【基本合理】呢?

                        因为【三分天下】虽然是正确的战略方向,但如果只用【域名】来实现这个战略,其实漏洞百出,比如:

                        1. 我读了《小小白白话文》后,给 VPS 新申请了一个 proxy.yourdomain.com 的域名, 我希望它无论如何都代理,geosite.dat 里面有吗?
                        2. 如果我还有个 direct.yourdomain.com 的域名,我希望它无论如何都直连, geosite.dat 里面有吗?
                        3. 本机 127.0.0.1 的内部流量,是否正确直连了?(比如 docker 等)
                        4. 路由器、本地局域网 192.168.*.* 的流量,是否正确直连了?(比如路由器、群晖等)
                        5. 我的国内 DNS 查询(如 223.5.5.5)是否正确直连了?
                        6. 我的国外 DNS 查询(如 1.1.1.1)是否正确代理了?
                        7. 其他类似国内公共 DNS 一样没有域名、只有 IP 地址的国内网站,是否正确直连了?
                        8. 其他类似国外公共 DNS 一样没有域名、只有 IP 地址的国外网站,是否正确代理了?
                        9. BT 下载的流量,虽然来源是国外,但如果通过 VPS 下载很可能导致违规使用被封,这该如何强制直连?
                        10. ......

                        我之所以说只用【域名分流】会漏洞百出,是因为 geosite.dat 文件内只包含了一部分常用的域名。换言之,仅仅依赖它,则会:

                        • 无法匹配文件里没有的新域名
                        • 无法匹配基于 IP 地址的规则
                        • 无法匹配基于网络协议的规则

                        啰嗦君

                        那我们来复习一下,当上面这些情况无法匹配时,会发生什么?对了,会触发隐藏路由规则,即【转发给第一个出站 】。这其实就是说:

                        • 当你的第一个出站是 [direct-out] 时:需要直连的都正确了,但需要代理的则都错误
                        • 当你的第一个出站是 [proxy-out-vless] 时:需要代理的都正确了,但需要直连的则都错误

                        所以,我们需要一个办法,让我们鱼与熊掌兼得。这样的办法是否存在呢?当然存在! 我们需要的只是【域名】之外更多的【分流判断依据】而已。

                        5.1 基于指定域名分流:[domain], [full]

                        ',11),q=o("
                      40. 如果需要匹配某个子域名,如 a-name.yourdomain.com,我们使用 full: "a-name.yourdomain.com"
                      41. 前面的 问题1问题2,就可以通过给 proxy.yourdomain.com 指定 [proxy-out-vless] 出站,给 direct.yourdomain.com 指定 [direct-out] 出站来解决
                      42. 如果需要匹配 yourdomain.com 的所有子域名,我们使用 domain: "yourdomain.com" 实现
                      43. 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
                      44. ",4),b=s("code",null,"[domain]",-1),g=o(`

                        上述配置如下:

                        {
                        +import{_ as i,r as p,o as l,c as u,a as s,b as n,d as a,w as e,e as o}from"./app-UOvWaKji.js";const d={},r=s("h1",{id:"路由-routing-功能简析-下",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#路由-routing-功能简析-下"},[s("span",null,"路由 (routing) 功能简析(下)")])],-1),k=s("p",null,[n("欢迎继续学习 "),s("code",null,"Xray"),n(" 的【路由】功能!")],-1),v=s("code",null,"geosite.dat",-1),m=o('

                        如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!

                        5. 攻城略池 - 多种路由匹配条件

                        [域名], [IP], [协议], etc.

                        基于域名的分流,已经可以让我们对网络流量进行基本合理的分流。为什么说【基本合理】呢?

                        因为【三分天下】虽然是正确的战略方向,但如果只用【域名】来实现这个战略,其实漏洞百出,比如:

                        1. 我读了《小小白白话文》后,给 VPS 新申请了一个 proxy.yourdomain.com 的域名, 我希望它无论如何都代理,geosite.dat 里面有吗?
                        2. 如果我还有个 direct.yourdomain.com 的域名,我希望它无论如何都直连, geosite.dat 里面有吗?
                        3. 本机 127.0.0.1 的内部流量,是否正确直连了?(比如 docker 等)
                        4. 路由器、本地局域网 192.168.*.* 的流量,是否正确直连了?(比如路由器、群晖等)
                        5. 我的国内 DNS 查询(如 223.5.5.5)是否正确直连了?
                        6. 我的国外 DNS 查询(如 1.1.1.1)是否正确代理了?
                        7. 其他类似国内公共 DNS 一样没有域名、只有 IP 地址的国内网站,是否正确直连了?
                        8. 其他类似国外公共 DNS 一样没有域名、只有 IP 地址的国外网站,是否正确代理了?
                        9. BT 下载的流量,虽然来源是国外,但如果通过 VPS 下载很可能导致违规使用被封,这该如何强制直连?
                        10. ......

                        我之所以说只用【域名分流】会漏洞百出,是因为 geosite.dat 文件内只包含了一部分常用的域名。换言之,仅仅依赖它,则会:

                        • 无法匹配文件里没有的新域名
                        • 无法匹配基于 IP 地址的规则
                        • 无法匹配基于网络协议的规则

                        啰嗦君

                        那我们来复习一下,当上面这些情况无法匹配时,会发生什么?对了,会触发隐藏路由规则,即【转发给第一个出站 】。这其实就是说:

                        • 当你的第一个出站是 [direct-out] 时:需要直连的都正确了,但需要代理的则都错误
                        • 当你的第一个出站是 [proxy-out-vless] 时:需要代理的都正确了,但需要直连的则都错误

                        所以,我们需要一个办法,让我们鱼与熊掌兼得。这样的办法是否存在呢?当然存在! 我们需要的只是【域名】之外更多的【分流判断依据】而已。

                        5.1 基于指定域名分流:[domain], [full]

                        ',11),q=o("
                      45. 如果需要匹配某个子域名,如 a-name.yourdomain.com,我们使用 full: "a-name.yourdomain.com"
                      46. 前面的 问题1问题2,就可以通过给 proxy.yourdomain.com 指定 [proxy-out-vless] 出站,给 direct.yourdomain.com 指定 [direct-out] 出站来解决
                      47. 如果需要匹配 yourdomain.com 的所有子域名,我们使用 domain: "yourdomain.com" 实现
                      48. 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
                      49. ",4),b=s("code",null,"[domain]",-1),g=o(`

                        上述配置如下:

                        {
                           "routing": {
                             "domainStrategy": "AsIs",
                             "rules": [
                        diff --git a/assets/routing-lv1-part2.html-JpbPk6FW.js b/assets/routing-lv1-part2.html-J8wCOEnV.js
                        similarity index 99%
                        rename from assets/routing-lv1-part2.html-JpbPk6FW.js
                        rename to assets/routing-lv1-part2.html-J8wCOEnV.js
                        index e63c327da9..1a9d41e541 100644
                        --- a/assets/routing-lv1-part2.html-JpbPk6FW.js
                        +++ b/assets/routing-lv1-part2.html-J8wCOEnV.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as p,o as l,c as u,a as s,b as n,d as a,w as e,e as o}from"./app-PDrbPfzp.js";const d={},r=s("h1",{id:"路由-routing-功能简析-下",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#路由-routing-功能简析-下"},[s("span",null,"路由 (routing) 功能简析(下)")])],-1),k=s("p",null,[n("欢迎继续学习 "),s("code",null,"Xray"),n(" 的【路由】功能!")],-1),v=s("code",null,"geosite.dat",-1),m=o('

                        如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!

                        5. 攻城略池 - 多种路由匹配条件

                        [域名], [IP], [协议], etc.

                        基于域名的分流,已经可以让我们对网络流量进行基本合理的分流。为什么说【基本合理】呢?

                        因为【三分天下】虽然是正确的战略方向,但如果只用【域名】来实现这个战略,其实漏洞百出,比如:

                        1. 我读了《小小白白话文》后,给 VPS 新申请了一个 proxy.yourdomain.com 的域名, 我希望它无论如何都代理,geosite.dat 里面有吗?
                        2. 如果我还有个 direct.yourdomain.com 的域名,我希望它无论如何都直连, geosite.dat 里面有吗?
                        3. 本机 127.0.0.1 的内部流量,是否正确直连了?(比如 docker 等)
                        4. 路由器、本地局域网 192.168.*.* 的流量,是否正确直连了?(比如路由器、群晖等)
                        5. 我的国内 DNS 查询(如 223.5.5.5)是否正确直连了?
                        6. 我的国外 DNS 查询(如 1.1.1.1)是否正确代理了?
                        7. 其他类似国内公共 DNS 一样没有域名、只有 IP 地址的国内网站,是否正确直连了?
                        8. 其他类似国外公共 DNS 一样没有域名、只有 IP 地址的国外网站,是否正确代理了?
                        9. BT 下载的流量,虽然来源是国外,但如果通过 VPS 下载很可能导致违规使用被封,这该如何强制直连?
                        10. ......

                        我之所以说只用【域名分流】会漏洞百出,是因为 geosite.dat 文件内只包含了一部分常用的域名。换言之,仅仅依赖它,则会:

                        • 无法匹配文件里没有的新域名
                        • 无法匹配基于 IP 地址的规则
                        • 无法匹配基于网络协议的规则

                        啰嗦君

                        那我们来复习一下,当上面这些情况无法匹配时,会发生什么?对了,会触发隐藏路由规则,即【转发给第一个出站 】。这其实就是说:

                        • 当你的第一个出站是 [direct-out] 时:需要直连的都正确了,但需要代理的则都错误
                        • 当你的第一个出站是 [proxy-out-vless] 时:需要代理的都正确了,但需要直连的则都错误

                        所以,我们需要一个办法,让我们鱼与熊掌兼得。这样的办法是否存在呢?当然存在! 我们需要的只是【域名】之外更多的【分流判断依据】而已。

                        5.1 基于指定域名分流:[domain], [full]

                        ',11),q=o("
                      50. 如果需要匹配某个子域名,如 a-name.yourdomain.com,我们使用 full: "a-name.yourdomain.com"
                      51. 前面的 问题1问题2,就可以通过给 proxy.yourdomain.com 指定 [proxy-out-vless] 出站,给 direct.yourdomain.com 指定 [direct-out] 出站来解决
                      52. 如果需要匹配 yourdomain.com 的所有子域名,我们使用 domain: "yourdomain.com" 实现
                      53. 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
                      54. ",4),b=s("code",null,"[domain]",-1),g=o(`

                        上述配置如下:

                        {
                        +import{_ as i,r as p,o as l,c as u,a as s,b as n,d as a,w as e,e as o}from"./app-UOvWaKji.js";const d={},r=s("h1",{id:"路由-routing-功能简析-下",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#路由-routing-功能简析-下"},[s("span",null,"路由 (routing) 功能简析(下)")])],-1),k=s("p",null,[n("欢迎继续学习 "),s("code",null,"Xray"),n(" 的【路由】功能!")],-1),v=s("code",null,"geosite.dat",-1),m=o('

                        如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!

                        5. 攻城略池 - 多种路由匹配条件

                        [域名], [IP], [协议], etc.

                        基于域名的分流,已经可以让我们对网络流量进行基本合理的分流。为什么说【基本合理】呢?

                        因为【三分天下】虽然是正确的战略方向,但如果只用【域名】来实现这个战略,其实漏洞百出,比如:

                        1. 我读了《小小白白话文》后,给 VPS 新申请了一个 proxy.yourdomain.com 的域名, 我希望它无论如何都代理,geosite.dat 里面有吗?
                        2. 如果我还有个 direct.yourdomain.com 的域名,我希望它无论如何都直连, geosite.dat 里面有吗?
                        3. 本机 127.0.0.1 的内部流量,是否正确直连了?(比如 docker 等)
                        4. 路由器、本地局域网 192.168.*.* 的流量,是否正确直连了?(比如路由器、群晖等)
                        5. 我的国内 DNS 查询(如 223.5.5.5)是否正确直连了?
                        6. 我的国外 DNS 查询(如 1.1.1.1)是否正确代理了?
                        7. 其他类似国内公共 DNS 一样没有域名、只有 IP 地址的国内网站,是否正确直连了?
                        8. 其他类似国外公共 DNS 一样没有域名、只有 IP 地址的国外网站,是否正确代理了?
                        9. BT 下载的流量,虽然来源是国外,但如果通过 VPS 下载很可能导致违规使用被封,这该如何强制直连?
                        10. ......

                        我之所以说只用【域名分流】会漏洞百出,是因为 geosite.dat 文件内只包含了一部分常用的域名。换言之,仅仅依赖它,则会:

                        • 无法匹配文件里没有的新域名
                        • 无法匹配基于 IP 地址的规则
                        • 无法匹配基于网络协议的规则

                        啰嗦君

                        那我们来复习一下,当上面这些情况无法匹配时,会发生什么?对了,会触发隐藏路由规则,即【转发给第一个出站 】。这其实就是说:

                        • 当你的第一个出站是 [direct-out] 时:需要直连的都正确了,但需要代理的则都错误
                        • 当你的第一个出站是 [proxy-out-vless] 时:需要代理的都正确了,但需要直连的则都错误

                        所以,我们需要一个办法,让我们鱼与熊掌兼得。这样的办法是否存在呢?当然存在! 我们需要的只是【域名】之外更多的【分流判断依据】而已。

                        5.1 基于指定域名分流:[domain], [full]

                        ',11),q=o("
                      55. 如果需要匹配某个子域名,如 a-name.yourdomain.com,我们使用 full: "a-name.yourdomain.com"
                      56. 前面的 问题1问题2,就可以通过给 proxy.yourdomain.com 指定 [proxy-out-vless] 出站,给 direct.yourdomain.com 指定 [direct-out] 出站来解决
                      57. 如果需要匹配 yourdomain.com 的所有子域名,我们使用 domain: "yourdomain.com" 实现
                      58. 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
                      59. ",4),b=s("code",null,"[domain]",-1),g=o(`

                        上述配置如下:

                        {
                           "routing": {
                             "domainStrategy": "AsIs",
                             "rules": [
                        diff --git a/assets/routing.html-h85eQ1aY.js b/assets/routing.html-mmvuVaFi.js
                        similarity index 99%
                        rename from assets/routing.html-h85eQ1aY.js
                        rename to assets/routing.html-mmvuVaFi.js
                        index 09b7f18268..bf77257a02 100644
                        --- a/assets/routing.html-h85eQ1aY.js
                        +++ b/assets/routing.html-mmvuVaFi.js
                        @@ -1,4 +1,4 @@
                        -import{_ as u,r as c,o as l,c as i,a as n,b as o,d as s,w as p,e as t}from"./app-PDrbPfzp.js";const d={},r=n("h1",{id:"路由",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#路由"},[n("span",null,"路由")])],-1),q=n("p",null,"路由功能模块可以将入站数据按不同规则由不同的出站连接发出,以达到按需代理的目的。",-1),k=n("p",null,"如常见用法是分流国内外流量,Xray 可以通过内部机制判断不同地区的流量,然后将它们发送到不同的出站代理。",-1),b={href:"https://xtls.github.io/document/level-1/routing-lv1-part1.html",target:"_blank",rel:"noopener noreferrer"},v=t(`

                        RoutingObject

                        RoutingObject 对应配置文件的 routing 项。

                        {
                        +import{_ as u,r as c,o as l,c as i,a as n,b as o,d as s,w as p,e as t}from"./app-UOvWaKji.js";const d={},r=n("h1",{id:"路由",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#路由"},[n("span",null,"路由")])],-1),q=n("p",null,"路由功能模块可以将入站数据按不同规则由不同的出站连接发出,以达到按需代理的目的。",-1),k=n("p",null,"如常见用法是分流国内外流量,Xray 可以通过内部机制判断不同地区的流量,然后将它们发送到不同的出站代理。",-1),b={href:"https://xtls.github.io/document/level-1/routing-lv1-part1.html",target:"_blank",rel:"noopener noreferrer"},v=t(`

                        RoutingObject

                        RoutingObject 对应配置文件的 routing 项。

                        {
                           "routing": {
                             "domainStrategy": "AsIs",
                             "domainMatcher": "hybrid",
                        diff --git a/assets/routing.html-xothq4nq.js b/assets/routing.html-oysaUhpj.js
                        similarity index 99%
                        rename from assets/routing.html-xothq4nq.js
                        rename to assets/routing.html-oysaUhpj.js
                        index 11c376de0a..994f3bd71d 100644
                        --- a/assets/routing.html-xothq4nq.js
                        +++ b/assets/routing.html-oysaUhpj.js
                        @@ -1,4 +1,4 @@
                        -import{_ as l,r as i,o as r,c as u,a as e,b as o,d as t,w as c,e as n}from"./app-PDrbPfzp.js";const d={},p=e("h1",{id:"routing",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#routing"},[e("span",null,"Routing")])],-1),h=e("p",null,"The routing module can send inbound data through different outbound connections according to different rules to achieve on-demand proxying.",-1),m=e("p",null,"A common use case is to split domestic and foreign traffic. Xray can use its internal mechanisms to determine the traffic from different regions and then send them to different outbound proxies.",-1),q={href:"https://xtls.github.io/document/level-1/routing-lv1-part1.html",target:"_blank",rel:"noopener noreferrer"},f=n(`

                        RoutingObject

                        RoutingObject corresponds to the routing item in the configuration file.

                        {
                        +import{_ as l,r as i,o as r,c as u,a as e,b as o,d as t,w as c,e as n}from"./app-UOvWaKji.js";const d={},p=e("h1",{id:"routing",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#routing"},[e("span",null,"Routing")])],-1),h=e("p",null,"The routing module can send inbound data through different outbound connections according to different rules to achieve on-demand proxying.",-1),m=e("p",null,"A common use case is to split domestic and foreign traffic. Xray can use its internal mechanisms to determine the traffic from different regions and then send them to different outbound proxies.",-1),q={href:"https://xtls.github.io/document/level-1/routing-lv1-part1.html",target:"_blank",rel:"noopener noreferrer"},f=n(`

                        RoutingObject

                        RoutingObject corresponds to the routing item in the configuration file.

                        {
                           "routing": {
                             "domainStrategy": "AsIs",
                             "domainMatcher": "hybrid",
                        diff --git a/assets/sankeyDiagram-97764748-A3D0wPEg.js b/assets/sankeyDiagram-97764748-XP-AU6IQ.js
                        similarity index 99%
                        rename from assets/sankeyDiagram-97764748-A3D0wPEg.js
                        rename to assets/sankeyDiagram-97764748-XP-AU6IQ.js
                        index 24f2ff2131..e5e18c3da6 100644
                        --- a/assets/sankeyDiagram-97764748-A3D0wPEg.js
                        +++ b/assets/sankeyDiagram-97764748-XP-AU6IQ.js
                        @@ -1,4 +1,4 @@
                        -import{c as rt,g as mt,s as kt,a as _t,b as xt,y as vt,x as bt,A as wt,j as St,v as Lt,h as G,u as Et}from"./mermaid.core-95b3ca__.js";import{o as At}from"./ordinal-wXG5obU4.js";import{s as Tt}from"./Tableau10-Fgclqpgn.js";import"./app-PDrbPfzp.js";import"./init-Hi12RPRh.js";function ot(t,n){let s;if(n===void 0)for(const a of t)a!=null&&(s=a)&&(s=a);else{let a=-1;for(let u of t)(u=n(u,++a,t))!=null&&(s=u)&&(s=u)}return s}function yt(t,n){let s;if(n===void 0)for(const a of t)a!=null&&(s>a||s===void 0&&a>=a)&&(s=a);else{let a=-1;for(let u of t)(u=n(u,++a,t))!=null&&(s>u||s===void 0&&u>=u)&&(s=u)}return s}function Z(t,n){let s=0;if(n===void 0)for(let a of t)(a=+a)&&(s+=a);else{let a=-1;for(let u of t)(u=+n(u,++a,t))&&(s+=u)}return s}function Mt(t){return t.target.depth}function Nt(t){return t.depth}function Pt(t,n){return n-1-t.height}function dt(t,n){return t.sourceLinks.length?t.depth:n-1}function Ct(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?yt(t.sourceLinks,Mt)-1:0}function Y(t){return function(){return t}}function lt(t,n){return H(t.source,n.source)||t.index-n.index}function at(t,n){return H(t.target,n.target)||t.index-n.index}function H(t,n){return t.y0-n.y0}function J(t){return t.value}function It(t){return t.index}function $t(t){return t.nodes}function Ot(t){return t.links}function ct(t,n){const s=t.get(n);if(!s)throw new Error("missing: "+n);return s}function ut({nodes:t}){for(const n of t){let s=n.y0,a=s;for(const u of n.sourceLinks)u.y0=s+u.width/2,s+=u.width;for(const u of n.targetLinks)u.y1=a+u.width/2,a+=u.width}}function jt(){let t=0,n=0,s=1,a=1,u=24,_=8,g,p=It,i=dt,o,c,m=$t,b=Ot,y=6;function x(){const e={nodes:m.apply(null,arguments),links:b.apply(null,arguments)};return E(e),L(e),A(e),N(e),S(e),ut(e),e}x.update=function(e){return ut(e),e},x.nodeId=function(e){return arguments.length?(p=typeof e=="function"?e:Y(e),x):p},x.nodeAlign=function(e){return arguments.length?(i=typeof e=="function"?e:Y(e),x):i},x.nodeSort=function(e){return arguments.length?(o=e,x):o},x.nodeWidth=function(e){return arguments.length?(u=+e,x):u},x.nodePadding=function(e){return arguments.length?(_=g=+e,x):_},x.nodes=function(e){return arguments.length?(m=typeof e=="function"?e:Y(e),x):m},x.links=function(e){return arguments.length?(b=typeof e=="function"?e:Y(e),x):b},x.linkSort=function(e){return arguments.length?(c=e,x):c},x.size=function(e){return arguments.length?(t=n=0,s=+e[0],a=+e[1],x):[s-t,a-n]},x.extent=function(e){return arguments.length?(t=+e[0][0],s=+e[1][0],n=+e[0][1],a=+e[1][1],x):[[t,n],[s,a]]},x.iterations=function(e){return arguments.length?(y=+e,x):y};function E({nodes:e,links:f}){for(const[h,r]of e.entries())r.index=h,r.sourceLinks=[],r.targetLinks=[];const l=new Map(e.map((h,r)=>[p(h,r,e),h]));for(const[h,r]of f.entries()){r.index=h;let{source:k,target:v}=r;typeof k!="object"&&(k=r.source=ct(l,k)),typeof v!="object"&&(v=r.target=ct(l,v)),k.sourceLinks.push(r),v.targetLinks.push(r)}if(c!=null)for(const{sourceLinks:h,targetLinks:r}of e)h.sort(c),r.sort(c)}function L({nodes:e}){for(const f of e)f.value=f.fixedValue===void 0?Math.max(Z(f.sourceLinks,J),Z(f.targetLinks,J)):f.fixedValue}function A({nodes:e}){const f=e.length;let l=new Set(e),h=new Set,r=0;for(;l.size;){for(const k of l){k.depth=r;for(const{target:v}of k.sourceLinks)h.add(v)}if(++r>f)throw new Error("circular link");l=h,h=new Set}}function N({nodes:e}){const f=e.length;let l=new Set(e),h=new Set,r=0;for(;l.size;){for(const k of l){k.height=r;for(const{source:v}of k.targetLinks)h.add(v)}if(++r>f)throw new Error("circular link");l=h,h=new Set}}function I({nodes:e}){const f=ot(e,r=>r.depth)+1,l=(s-t-u)/(f-1),h=new Array(f);for(const r of e){const k=Math.max(0,Math.min(f-1,Math.floor(i.call(null,r,f))));r.layer=k,r.x0=t+k*l,r.x1=r.x0+u,h[k]?h[k].push(r):h[k]=[r]}if(o)for(const r of h)r.sort(o);return h}function j(e){const f=yt(e,l=>(a-n-(l.length-1)*g)/Z(l,J));for(const l of e){let h=n;for(const r of l){r.y0=h,r.y1=h+r.value*f,h=r.y1+g;for(const k of r.sourceLinks)k.width=k.value*f}h=(a-h+g)/(l.length+1);for(let r=0;rl.length)-1)),j(f);for(let l=0;l0))continue;let U=(R/z-v.y0)*f;v.y0+=U,v.y1+=U,w(v)}o===void 0&&k.sort(H),P(k,l)}}function O(e,f,l){for(let h=e.length,r=h-2;r>=0;--r){const k=e[r];for(const v of k){let R=0,z=0;for(const{target:W,value:K}of v.sourceLinks){let F=K*(W.layer-v.layer);R+=V(v,W)*F,z+=F}if(!(z>0))continue;let U=(R/z-v.y0)*f;v.y0+=U,v.y1+=U,w(v)}o===void 0&&k.sort(H),P(k,l)}}function P(e,f){const l=e.length>>1,h=e[l];d(e,h.y0-g,l-1,f),C(e,h.y1+g,l+1,f),d(e,a,e.length-1,f),C(e,n,0,f)}function C(e,f,l,h){for(;l1e-6&&(r.y0+=k,r.y1+=k),f=r.y1+g}}function d(e,f,l,h){for(;l>=0;--l){const r=e[l],k=(r.y1-f)*h;k>1e-6&&(r.y0-=k,r.y1-=k),f=r.y0-g}}function w({sourceLinks:e,targetLinks:f}){if(c===void 0){for(const{source:{sourceLinks:l}}of f)l.sort(at);for(const{target:{targetLinks:l}}of e)l.sort(lt)}}function $(e){if(c===void 0)for(const{sourceLinks:f,targetLinks:l}of e)f.sort(at),l.sort(lt)}function T(e,f){let l=e.y0-(e.sourceLinks.length-1)*g/2;for(const{target:h,width:r}of e.sourceLinks){if(h===f)break;l+=r+g}for(const{source:h,width:r}of f.targetLinks){if(h===e)break;l-=r}return l}function V(e,f){let l=f.y0-(f.targetLinks.length-1)*g/2;for(const{source:h,width:r}of f.targetLinks){if(h===e)break;l+=r+g}for(const{target:h,width:r}of e.sourceLinks){if(h===f)break;l-=r}return l}return x}var tt=Math.PI,et=2*tt,D=1e-6,zt=et-D;function nt(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function gt(){return new nt}nt.prototype=gt.prototype={constructor:nt,moveTo:function(t,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)},closePath:function(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,n){this._+="L"+(this._x1=+t)+","+(this._y1=+n)},quadraticCurveTo:function(t,n,s,a){this._+="Q"+ +t+","+ +n+","+(this._x1=+s)+","+(this._y1=+a)},bezierCurveTo:function(t,n,s,a,u,_){this._+="C"+ +t+","+ +n+","+ +s+","+ +a+","+(this._x1=+u)+","+(this._y1=+_)},arcTo:function(t,n,s,a,u){t=+t,n=+n,s=+s,a=+a,u=+u;var _=this._x1,g=this._y1,p=s-t,i=a-n,o=_-t,c=g-n,m=o*o+c*c;if(u<0)throw new Error("negative radius: "+u);if(this._x1===null)this._+="M"+(this._x1=t)+","+(this._y1=n);else if(m>D)if(!(Math.abs(c*p-i*o)>D)||!u)this._+="L"+(this._x1=t)+","+(this._y1=n);else{var b=s-_,y=a-g,x=p*p+i*i,E=b*b+y*y,L=Math.sqrt(x),A=Math.sqrt(m),N=u*Math.tan((tt-Math.acos((x+m-E)/(2*L*A)))/2),I=N/A,j=N/L;Math.abs(I-1)>D&&(this._+="L"+(t+I*o)+","+(n+I*c)),this._+="A"+u+","+u+",0,0,"+ +(c*b>o*y)+","+(this._x1=t+j*p)+","+(this._y1=n+j*i)}},arc:function(t,n,s,a,u,_){t=+t,n=+n,s=+s,_=!!_;var g=s*Math.cos(a),p=s*Math.sin(a),i=t+g,o=n+p,c=1^_,m=_?a-u:u-a;if(s<0)throw new Error("negative radius: "+s);this._x1===null?this._+="M"+i+","+o:(Math.abs(this._x1-i)>D||Math.abs(this._y1-o)>D)&&(this._+="L"+i+","+o),s&&(m<0&&(m=m%et+et),m>zt?this._+="A"+s+","+s+",0,1,"+c+","+(t-g)+","+(n-p)+"A"+s+","+s+",0,1,"+c+","+(this._x1=i)+","+(this._y1=o):m>D&&(this._+="A"+s+","+s+",0,"+ +(m>=tt)+","+c+","+(this._x1=t+s*Math.cos(u))+","+(this._y1=n+s*Math.sin(u))))},rect:function(t,n,s,a){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)+"h"+ +s+"v"+ +a+"h"+-s+"Z"},toString:function(){return this._}};function ht(t){return function(){return t}}function Dt(t){return t[0]}function Bt(t){return t[1]}var Vt=Array.prototype.slice;function Rt(t){return t.source}function Ut(t){return t.target}function Wt(t){var n=Rt,s=Ut,a=Dt,u=Bt,_=null;function g(){var p,i=Vt.call(arguments),o=n.apply(this,i),c=s.apply(this,i);if(_||(_=p=gt()),t(_,+a.apply(this,(i[0]=o,i)),+u.apply(this,i),+a.apply(this,(i[0]=c,i)),+u.apply(this,i)),p)return _=null,p+""||null}return g.source=function(p){return arguments.length?(n=p,g):n},g.target=function(p){return arguments.length?(s=p,g):s},g.x=function(p){return arguments.length?(a=typeof p=="function"?p:ht(+p),g):a},g.y=function(p){return arguments.length?(u=typeof p=="function"?p:ht(+p),g):u},g.context=function(p){return arguments.length?(_=p??null,g):_},g}function Ft(t,n,s,a,u){t.moveTo(n,s),t.bezierCurveTo(n=(n+a)/2,s,n,u,a,u)}function Gt(){return Wt(Ft)}function Yt(t){return[t.source.x1,t.y0]}function Ht(t){return[t.target.x0,t.y1]}function Xt(){return Gt().source(Yt).target(Ht)}var it=function(){var t=function(p,i,o,c){for(o=o||{},c=p.length;c--;o[p[c]]=i);return o},n=[1,9],s=[1,10],a=[1,5,10,12],u={trace:function(){},yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:function(i,o,c,m,b,y,x){var E=y.length-1;switch(b){case 7:const L=m.findOrCreateNode(y[E-4].trim().replaceAll('""','"')),A=m.findOrCreateNode(y[E-2].trim().replaceAll('""','"')),N=parseFloat(y[E].trim());m.addLink(L,A,N);break;case 8:case 9:case 11:this.$=y[E];break;case 10:this.$=y[E-1];break}},table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:n,20:s},{1:[2,6],7:11,10:[1,12]},t(s,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(a,[2,8]),t(a,[2,9]),{19:[1,16]},t(a,[2,11]),{1:[2,1]},{1:[2,5]},t(s,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:n,20:s},{15:18,16:7,17:8,18:n,20:s},{18:[1,19]},t(s,[2,3]),{12:[1,20]},t(a,[2,10]),{15:21,16:7,17:8,18:n,20:s},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:function(i,o){if(o.recoverable)this.trace(i);else{var c=new Error(i);throw c.hash=o,c}},parse:function(i){var o=this,c=[0],m=[],b=[null],y=[],x=this.table,E="",L=0,A=0,N=2,I=1,j=y.slice.call(arguments,1),S=Object.create(this.lexer),M={yy:{}};for(var O in this.yy)Object.prototype.hasOwnProperty.call(this.yy,O)&&(M.yy[O]=this.yy[O]);S.setInput(i,M.yy),M.yy.lexer=S,M.yy.parser=this,typeof S.yylloc>"u"&&(S.yylloc={});var P=S.yylloc;y.push(P);var C=S.options&&S.options.ranges;typeof M.yy.parseError=="function"?this.parseError=M.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function d(){var v;return v=m.pop()||S.lex()||I,typeof v!="number"&&(v instanceof Array&&(m=v,v=m.pop()),v=o.symbols_[v]||v),v}for(var w,$,T,V,e={},f,l,h,r;;){if($=c[c.length-1],this.defaultActions[$]?T=this.defaultActions[$]:((w===null||typeof w>"u")&&(w=d()),T=x[$]&&x[$][w]),typeof T>"u"||!T.length||!T[0]){var k="";r=[];for(f in x[$])this.terminals_[f]&&f>N&&r.push("'"+this.terminals_[f]+"'");S.showPosition?k="Parse error on line "+(L+1)+`:
                        +import{c as rt,g as mt,s as kt,a as _t,b as xt,y as vt,x as bt,A as wt,j as St,v as Lt,h as G,u as Et}from"./mermaid.core-Q3WVcjPF.js";import{o as At}from"./ordinal-wXG5obU4.js";import{s as Tt}from"./Tableau10-Fgclqpgn.js";import"./app-UOvWaKji.js";import"./init-Hi12RPRh.js";function ot(t,n){let s;if(n===void 0)for(const a of t)a!=null&&(s=a)&&(s=a);else{let a=-1;for(let u of t)(u=n(u,++a,t))!=null&&(s=u)&&(s=u)}return s}function yt(t,n){let s;if(n===void 0)for(const a of t)a!=null&&(s>a||s===void 0&&a>=a)&&(s=a);else{let a=-1;for(let u of t)(u=n(u,++a,t))!=null&&(s>u||s===void 0&&u>=u)&&(s=u)}return s}function Z(t,n){let s=0;if(n===void 0)for(let a of t)(a=+a)&&(s+=a);else{let a=-1;for(let u of t)(u=+n(u,++a,t))&&(s+=u)}return s}function Mt(t){return t.target.depth}function Nt(t){return t.depth}function Pt(t,n){return n-1-t.height}function dt(t,n){return t.sourceLinks.length?t.depth:n-1}function Ct(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?yt(t.sourceLinks,Mt)-1:0}function Y(t){return function(){return t}}function lt(t,n){return H(t.source,n.source)||t.index-n.index}function at(t,n){return H(t.target,n.target)||t.index-n.index}function H(t,n){return t.y0-n.y0}function J(t){return t.value}function It(t){return t.index}function $t(t){return t.nodes}function Ot(t){return t.links}function ct(t,n){const s=t.get(n);if(!s)throw new Error("missing: "+n);return s}function ut({nodes:t}){for(const n of t){let s=n.y0,a=s;for(const u of n.sourceLinks)u.y0=s+u.width/2,s+=u.width;for(const u of n.targetLinks)u.y1=a+u.width/2,a+=u.width}}function jt(){let t=0,n=0,s=1,a=1,u=24,_=8,g,p=It,i=dt,o,c,m=$t,b=Ot,y=6;function x(){const e={nodes:m.apply(null,arguments),links:b.apply(null,arguments)};return E(e),L(e),A(e),N(e),S(e),ut(e),e}x.update=function(e){return ut(e),e},x.nodeId=function(e){return arguments.length?(p=typeof e=="function"?e:Y(e),x):p},x.nodeAlign=function(e){return arguments.length?(i=typeof e=="function"?e:Y(e),x):i},x.nodeSort=function(e){return arguments.length?(o=e,x):o},x.nodeWidth=function(e){return arguments.length?(u=+e,x):u},x.nodePadding=function(e){return arguments.length?(_=g=+e,x):_},x.nodes=function(e){return arguments.length?(m=typeof e=="function"?e:Y(e),x):m},x.links=function(e){return arguments.length?(b=typeof e=="function"?e:Y(e),x):b},x.linkSort=function(e){return arguments.length?(c=e,x):c},x.size=function(e){return arguments.length?(t=n=0,s=+e[0],a=+e[1],x):[s-t,a-n]},x.extent=function(e){return arguments.length?(t=+e[0][0],s=+e[1][0],n=+e[0][1],a=+e[1][1],x):[[t,n],[s,a]]},x.iterations=function(e){return arguments.length?(y=+e,x):y};function E({nodes:e,links:f}){for(const[h,r]of e.entries())r.index=h,r.sourceLinks=[],r.targetLinks=[];const l=new Map(e.map((h,r)=>[p(h,r,e),h]));for(const[h,r]of f.entries()){r.index=h;let{source:k,target:v}=r;typeof k!="object"&&(k=r.source=ct(l,k)),typeof v!="object"&&(v=r.target=ct(l,v)),k.sourceLinks.push(r),v.targetLinks.push(r)}if(c!=null)for(const{sourceLinks:h,targetLinks:r}of e)h.sort(c),r.sort(c)}function L({nodes:e}){for(const f of e)f.value=f.fixedValue===void 0?Math.max(Z(f.sourceLinks,J),Z(f.targetLinks,J)):f.fixedValue}function A({nodes:e}){const f=e.length;let l=new Set(e),h=new Set,r=0;for(;l.size;){for(const k of l){k.depth=r;for(const{target:v}of k.sourceLinks)h.add(v)}if(++r>f)throw new Error("circular link");l=h,h=new Set}}function N({nodes:e}){const f=e.length;let l=new Set(e),h=new Set,r=0;for(;l.size;){for(const k of l){k.height=r;for(const{source:v}of k.targetLinks)h.add(v)}if(++r>f)throw new Error("circular link");l=h,h=new Set}}function I({nodes:e}){const f=ot(e,r=>r.depth)+1,l=(s-t-u)/(f-1),h=new Array(f);for(const r of e){const k=Math.max(0,Math.min(f-1,Math.floor(i.call(null,r,f))));r.layer=k,r.x0=t+k*l,r.x1=r.x0+u,h[k]?h[k].push(r):h[k]=[r]}if(o)for(const r of h)r.sort(o);return h}function j(e){const f=yt(e,l=>(a-n-(l.length-1)*g)/Z(l,J));for(const l of e){let h=n;for(const r of l){r.y0=h,r.y1=h+r.value*f,h=r.y1+g;for(const k of r.sourceLinks)k.width=k.value*f}h=(a-h+g)/(l.length+1);for(let r=0;rl.length)-1)),j(f);for(let l=0;l0))continue;let U=(R/z-v.y0)*f;v.y0+=U,v.y1+=U,w(v)}o===void 0&&k.sort(H),P(k,l)}}function O(e,f,l){for(let h=e.length,r=h-2;r>=0;--r){const k=e[r];for(const v of k){let R=0,z=0;for(const{target:W,value:K}of v.sourceLinks){let F=K*(W.layer-v.layer);R+=V(v,W)*F,z+=F}if(!(z>0))continue;let U=(R/z-v.y0)*f;v.y0+=U,v.y1+=U,w(v)}o===void 0&&k.sort(H),P(k,l)}}function P(e,f){const l=e.length>>1,h=e[l];d(e,h.y0-g,l-1,f),C(e,h.y1+g,l+1,f),d(e,a,e.length-1,f),C(e,n,0,f)}function C(e,f,l,h){for(;l1e-6&&(r.y0+=k,r.y1+=k),f=r.y1+g}}function d(e,f,l,h){for(;l>=0;--l){const r=e[l],k=(r.y1-f)*h;k>1e-6&&(r.y0-=k,r.y1-=k),f=r.y0-g}}function w({sourceLinks:e,targetLinks:f}){if(c===void 0){for(const{source:{sourceLinks:l}}of f)l.sort(at);for(const{target:{targetLinks:l}}of e)l.sort(lt)}}function $(e){if(c===void 0)for(const{sourceLinks:f,targetLinks:l}of e)f.sort(at),l.sort(lt)}function T(e,f){let l=e.y0-(e.sourceLinks.length-1)*g/2;for(const{target:h,width:r}of e.sourceLinks){if(h===f)break;l+=r+g}for(const{source:h,width:r}of f.targetLinks){if(h===e)break;l-=r}return l}function V(e,f){let l=f.y0-(f.targetLinks.length-1)*g/2;for(const{source:h,width:r}of f.targetLinks){if(h===e)break;l+=r+g}for(const{target:h,width:r}of e.sourceLinks){if(h===f)break;l-=r}return l}return x}var tt=Math.PI,et=2*tt,D=1e-6,zt=et-D;function nt(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function gt(){return new nt}nt.prototype=gt.prototype={constructor:nt,moveTo:function(t,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)},closePath:function(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,n){this._+="L"+(this._x1=+t)+","+(this._y1=+n)},quadraticCurveTo:function(t,n,s,a){this._+="Q"+ +t+","+ +n+","+(this._x1=+s)+","+(this._y1=+a)},bezierCurveTo:function(t,n,s,a,u,_){this._+="C"+ +t+","+ +n+","+ +s+","+ +a+","+(this._x1=+u)+","+(this._y1=+_)},arcTo:function(t,n,s,a,u){t=+t,n=+n,s=+s,a=+a,u=+u;var _=this._x1,g=this._y1,p=s-t,i=a-n,o=_-t,c=g-n,m=o*o+c*c;if(u<0)throw new Error("negative radius: "+u);if(this._x1===null)this._+="M"+(this._x1=t)+","+(this._y1=n);else if(m>D)if(!(Math.abs(c*p-i*o)>D)||!u)this._+="L"+(this._x1=t)+","+(this._y1=n);else{var b=s-_,y=a-g,x=p*p+i*i,E=b*b+y*y,L=Math.sqrt(x),A=Math.sqrt(m),N=u*Math.tan((tt-Math.acos((x+m-E)/(2*L*A)))/2),I=N/A,j=N/L;Math.abs(I-1)>D&&(this._+="L"+(t+I*o)+","+(n+I*c)),this._+="A"+u+","+u+",0,0,"+ +(c*b>o*y)+","+(this._x1=t+j*p)+","+(this._y1=n+j*i)}},arc:function(t,n,s,a,u,_){t=+t,n=+n,s=+s,_=!!_;var g=s*Math.cos(a),p=s*Math.sin(a),i=t+g,o=n+p,c=1^_,m=_?a-u:u-a;if(s<0)throw new Error("negative radius: "+s);this._x1===null?this._+="M"+i+","+o:(Math.abs(this._x1-i)>D||Math.abs(this._y1-o)>D)&&(this._+="L"+i+","+o),s&&(m<0&&(m=m%et+et),m>zt?this._+="A"+s+","+s+",0,1,"+c+","+(t-g)+","+(n-p)+"A"+s+","+s+",0,1,"+c+","+(this._x1=i)+","+(this._y1=o):m>D&&(this._+="A"+s+","+s+",0,"+ +(m>=tt)+","+c+","+(this._x1=t+s*Math.cos(u))+","+(this._y1=n+s*Math.sin(u))))},rect:function(t,n,s,a){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)+"h"+ +s+"v"+ +a+"h"+-s+"Z"},toString:function(){return this._}};function ht(t){return function(){return t}}function Dt(t){return t[0]}function Bt(t){return t[1]}var Vt=Array.prototype.slice;function Rt(t){return t.source}function Ut(t){return t.target}function Wt(t){var n=Rt,s=Ut,a=Dt,u=Bt,_=null;function g(){var p,i=Vt.call(arguments),o=n.apply(this,i),c=s.apply(this,i);if(_||(_=p=gt()),t(_,+a.apply(this,(i[0]=o,i)),+u.apply(this,i),+a.apply(this,(i[0]=c,i)),+u.apply(this,i)),p)return _=null,p+""||null}return g.source=function(p){return arguments.length?(n=p,g):n},g.target=function(p){return arguments.length?(s=p,g):s},g.x=function(p){return arguments.length?(a=typeof p=="function"?p:ht(+p),g):a},g.y=function(p){return arguments.length?(u=typeof p=="function"?p:ht(+p),g):u},g.context=function(p){return arguments.length?(_=p??null,g):_},g}function Ft(t,n,s,a,u){t.moveTo(n,s),t.bezierCurveTo(n=(n+a)/2,s,n,u,a,u)}function Gt(){return Wt(Ft)}function Yt(t){return[t.source.x1,t.y0]}function Ht(t){return[t.target.x0,t.y1]}function Xt(){return Gt().source(Yt).target(Ht)}var it=function(){var t=function(p,i,o,c){for(o=o||{},c=p.length;c--;o[p[c]]=i);return o},n=[1,9],s=[1,10],a=[1,5,10,12],u={trace:function(){},yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:function(i,o,c,m,b,y,x){var E=y.length-1;switch(b){case 7:const L=m.findOrCreateNode(y[E-4].trim().replaceAll('""','"')),A=m.findOrCreateNode(y[E-2].trim().replaceAll('""','"')),N=parseFloat(y[E].trim());m.addLink(L,A,N);break;case 8:case 9:case 11:this.$=y[E];break;case 10:this.$=y[E-1];break}},table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:n,20:s},{1:[2,6],7:11,10:[1,12]},t(s,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(a,[2,8]),t(a,[2,9]),{19:[1,16]},t(a,[2,11]),{1:[2,1]},{1:[2,5]},t(s,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:n,20:s},{15:18,16:7,17:8,18:n,20:s},{18:[1,19]},t(s,[2,3]),{12:[1,20]},t(a,[2,10]),{15:21,16:7,17:8,18:n,20:s},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:function(i,o){if(o.recoverable)this.trace(i);else{var c=new Error(i);throw c.hash=o,c}},parse:function(i){var o=this,c=[0],m=[],b=[null],y=[],x=this.table,E="",L=0,A=0,N=2,I=1,j=y.slice.call(arguments,1),S=Object.create(this.lexer),M={yy:{}};for(var O in this.yy)Object.prototype.hasOwnProperty.call(this.yy,O)&&(M.yy[O]=this.yy[O]);S.setInput(i,M.yy),M.yy.lexer=S,M.yy.parser=this,typeof S.yylloc>"u"&&(S.yylloc={});var P=S.yylloc;y.push(P);var C=S.options&&S.options.ranges;typeof M.yy.parseError=="function"?this.parseError=M.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function d(){var v;return v=m.pop()||S.lex()||I,typeof v!="number"&&(v instanceof Array&&(m=v,v=m.pop()),v=o.symbols_[v]||v),v}for(var w,$,T,V,e={},f,l,h,r;;){if($=c[c.length-1],this.defaultActions[$]?T=this.defaultActions[$]:((w===null||typeof w>"u")&&(w=d()),T=x[$]&&x[$][w]),typeof T>"u"||!T.length||!T[0]){var k="";r=[];for(f in x[$])this.terminals_[f]&&f>N&&r.push("'"+this.terminals_[f]+"'");S.showPosition?k="Parse error on line "+(L+1)+`:
                         `+S.showPosition()+`
                         Expecting `+r.join(", ")+", got '"+(this.terminals_[w]||w)+"'":k="Parse error on line "+(L+1)+": Unexpected "+(w==I?"end of input":"'"+(this.terminals_[w]||w)+"'"),this.parseError(k,{text:S.match,token:this.terminals_[w]||w,line:S.yylineno,loc:P,expected:r})}if(T[0]instanceof Array&&T.length>1)throw new Error("Parse Error: multiple actions possible at state: "+$+", token: "+w);switch(T[0]){case 1:c.push(w),b.push(S.yytext),y.push(S.yylloc),c.push(T[1]),w=null,A=S.yyleng,E=S.yytext,L=S.yylineno,P=S.yylloc;break;case 2:if(l=this.productions_[T[1]][1],e.$=b[b.length-l],e._$={first_line:y[y.length-(l||1)].first_line,last_line:y[y.length-1].last_line,first_column:y[y.length-(l||1)].first_column,last_column:y[y.length-1].last_column},C&&(e._$.range=[y[y.length-(l||1)].range[0],y[y.length-1].range[1]]),V=this.performAction.apply(e,[E,A,L,M.yy,T[1],b,y].concat(j)),typeof V<"u")return V;l&&(c=c.slice(0,-1*l*2),b=b.slice(0,-1*l),y=y.slice(0,-1*l)),c.push(this.productions_[T[1]][0]),b.push(e.$),y.push(e._$),h=x[c[c.length-2]][c[c.length-1]],c.push(h);break;case 3:return!0}}return!0}},_=function(){var p={EOF:1,parseError:function(o,c){if(this.yy.parser)this.yy.parser.parseError(o,c);else throw new Error(o)},setInput:function(i,o){return this.yy=o||this.yy||{},this._input=i,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var i=this._input[0];this.yytext+=i,this.yyleng++,this.offset++,this.match+=i,this.matched+=i;var o=i.match(/(?:\r\n?|\n).*/g);return o?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),i},unput:function(i){var o=i.length,c=i.split(/(?:\r\n?|\n)/g);this._input=i+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-o),this.offset-=o;var m=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var b=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===m.length?this.yylloc.first_column:0)+m[m.length-c.length].length-c[0].length:this.yylloc.first_column-o},this.options.ranges&&(this.yylloc.range=[b[0],b[0]+this.yyleng-o]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
                         `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(i){this.unput(this.match.slice(i))},pastInput:function(){var i=this.matched.substr(0,this.matched.length-this.match.length);return(i.length>20?"...":"")+i.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var i=this.match;return i.length<20&&(i+=this._input.substr(0,20-i.length)),(i.substr(0,20)+(i.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var i=this.pastInput(),o=new Array(i.length+1).join("-");return i+this.upcomingInput()+`
                        diff --git a/assets/sequenceDiagram-acc0e65c-TzfkGb4D.js b/assets/sequenceDiagram-acc0e65c-So47ZKCj.js
                        similarity index 99%
                        rename from assets/sequenceDiagram-acc0e65c-TzfkGb4D.js
                        rename to assets/sequenceDiagram-acc0e65c-So47ZKCj.js
                        index 21716af7e7..a3fe2bd543 100644
                        --- a/assets/sequenceDiagram-acc0e65c-TzfkGb4D.js
                        +++ b/assets/sequenceDiagram-acc0e65c-So47ZKCj.js
                        @@ -1,4 +1,4 @@
                        -import{g as we,y as ve,x as _e,c as st,s as $t,b as ke,a as Pe,A as Le,l as X,d as At,j as v,e as Ie,h as Lt,i as Ae,z as B,b1 as nt,b2 as wt,m as te,r as ee,b0 as Bt,aO as se,b3 as Ne}from"./mermaid.core-95b3ca__.js";import{d as Se,a as Me,g as Nt,b as zt,c as Re,e as Ce}from"./svgDrawCommon-5ccd53ef-iJa2TVTb.js";import"./app-PDrbPfzp.js";var Yt=function(){var t=function(dt,w,k,L){for(k=k||{},L=dt.length;L--;k[dt[L]]=w);return k},e=[1,2],c=[1,3],s=[1,4],i=[2,4],a=[1,9],o=[1,11],l=[1,13],p=[1,14],r=[1,16],x=[1,17],T=[1,18],u=[1,24],g=[1,25],m=[1,26],_=[1,27],I=[1,28],V=[1,29],S=[1,30],O=[1,31],R=[1,32],q=[1,33],z=[1,34],J=[1,35],$=[1,36],H=[1,37],U=[1,38],F=[1,39],W=[1,41],Z=[1,42],K=[1,43],Q=[1,44],tt=[1,45],N=[1,46],y=[1,4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,48,49,50,52,53,54,59,60,61,62,70],P=[4,5,16,50,52,53],j=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],rt=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,49,50,52,53,54,59,60,61,62,70],A=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,48,50,52,53,54,59,60,61,62,70],Gt=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,50,52,53,54,59,60,61,62,70],ht=[68,69,70],ot=[1,120],Mt={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,box_section:10,box_line:11,participant_statement:12,create:13,box:14,restOfLine:15,end:16,signal:17,autonumber:18,NUM:19,off:20,activate:21,actor:22,deactivate:23,note_statement:24,links_statement:25,link_statement:26,properties_statement:27,details_statement:28,title:29,legacy_title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,loop:36,rect:37,opt:38,alt:39,else_sections:40,par:41,par_sections:42,par_over:43,critical:44,option_sections:45,break:46,option:47,and:48,else:49,participant:50,AS:51,participant_actor:52,destroy:53,note:54,placement:55,text2:56,over:57,actor_pair:58,links:59,link:60,properties:61,details:62,spaceList:63,",":64,left_of:65,right_of:66,signaltype:67,"+":68,"-":69,ACTOR:70,SOLID_OPEN_ARROW:71,DOTTED_OPEN_ARROW:72,SOLID_ARROW:73,DOTTED_ARROW:74,SOLID_CROSS:75,DOTTED_CROSS:76,SOLID_POINT:77,DOTTED_POINT:78,TXT:79,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",13:"create",14:"box",15:"restOfLine",16:"end",18:"autonumber",19:"NUM",20:"off",21:"activate",23:"deactivate",29:"title",30:"legacy_title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"loop",37:"rect",38:"opt",39:"alt",41:"par",43:"par_over",44:"critical",46:"break",47:"option",48:"and",49:"else",50:"participant",51:"AS",52:"participant_actor",53:"destroy",54:"note",57:"over",59:"links",60:"link",61:"properties",62:"details",64:",",65:"left_of",66:"right_of",68:"+",69:"-",70:"ACTOR",71:"SOLID_OPEN_ARROW",72:"DOTTED_OPEN_ARROW",73:"SOLID_ARROW",74:"DOTTED_ARROW",75:"SOLID_CROSS",76:"DOTTED_CROSS",77:"SOLID_POINT",78:"DOTTED_POINT",79:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[10,0],[10,2],[11,2],[11,1],[11,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[45,1],[45,4],[42,1],[42,4],[40,1],[40,4],[12,5],[12,3],[12,5],[12,3],[12,3],[24,4],[24,4],[25,3],[26,3],[27,3],[28,3],[63,2],[63,1],[58,3],[58,1],[55,1],[55,1],[17,5],[17,5],[17,4],[22,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[56,1]],performAction:function(w,k,L,b,M,h,Et){var d=h.length-1;switch(M){case 3:return b.apply(h[d]),h[d];case 4:case 9:this.$=[];break;case 5:case 10:h[d-1].push(h[d]),this.$=h[d-1];break;case 6:case 7:case 11:case 12:this.$=h[d];break;case 8:case 13:this.$=[];break;case 15:h[d].type="createParticipant",this.$=h[d];break;case 16:h[d-1].unshift({type:"boxStart",boxData:b.parseBoxData(h[d-2])}),h[d-1].push({type:"boxEnd",boxText:h[d-2]}),this.$=h[d-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(h[d-2]),sequenceIndexStep:Number(h[d-1]),sequenceVisible:!0,signalType:b.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(h[d-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:b.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:b.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:b.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:b.LINETYPE.ACTIVE_START,actor:h[d-1]};break;case 23:this.$={type:"activeEnd",signalType:b.LINETYPE.ACTIVE_END,actor:h[d-1]};break;case 29:b.setDiagramTitle(h[d].substring(6)),this.$=h[d].substring(6);break;case 30:b.setDiagramTitle(h[d].substring(7)),this.$=h[d].substring(7);break;case 31:this.$=h[d].trim(),b.setAccTitle(this.$);break;case 32:case 33:this.$=h[d].trim(),b.setAccDescription(this.$);break;case 34:h[d-1].unshift({type:"loopStart",loopText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.LOOP_START}),h[d-1].push({type:"loopEnd",loopText:h[d-2],signalType:b.LINETYPE.LOOP_END}),this.$=h[d-1];break;case 35:h[d-1].unshift({type:"rectStart",color:b.parseMessage(h[d-2]),signalType:b.LINETYPE.RECT_START}),h[d-1].push({type:"rectEnd",color:b.parseMessage(h[d-2]),signalType:b.LINETYPE.RECT_END}),this.$=h[d-1];break;case 36:h[d-1].unshift({type:"optStart",optText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.OPT_START}),h[d-1].push({type:"optEnd",optText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.OPT_END}),this.$=h[d-1];break;case 37:h[d-1].unshift({type:"altStart",altText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.ALT_START}),h[d-1].push({type:"altEnd",signalType:b.LINETYPE.ALT_END}),this.$=h[d-1];break;case 38:h[d-1].unshift({type:"parStart",parText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.PAR_START}),h[d-1].push({type:"parEnd",signalType:b.LINETYPE.PAR_END}),this.$=h[d-1];break;case 39:h[d-1].unshift({type:"parStart",parText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.PAR_OVER_START}),h[d-1].push({type:"parEnd",signalType:b.LINETYPE.PAR_END}),this.$=h[d-1];break;case 40:h[d-1].unshift({type:"criticalStart",criticalText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.CRITICAL_START}),h[d-1].push({type:"criticalEnd",signalType:b.LINETYPE.CRITICAL_END}),this.$=h[d-1];break;case 41:h[d-1].unshift({type:"breakStart",breakText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.BREAK_START}),h[d-1].push({type:"breakEnd",optText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.BREAK_END}),this.$=h[d-1];break;case 43:this.$=h[d-3].concat([{type:"option",optionText:b.parseMessage(h[d-1]),signalType:b.LINETYPE.CRITICAL_OPTION},h[d]]);break;case 45:this.$=h[d-3].concat([{type:"and",parText:b.parseMessage(h[d-1]),signalType:b.LINETYPE.PAR_AND},h[d]]);break;case 47:this.$=h[d-3].concat([{type:"else",altText:b.parseMessage(h[d-1]),signalType:b.LINETYPE.ALT_ELSE},h[d]]);break;case 48:h[d-3].draw="participant",h[d-3].type="addParticipant",h[d-3].description=b.parseMessage(h[d-1]),this.$=h[d-3];break;case 49:h[d-1].draw="participant",h[d-1].type="addParticipant",this.$=h[d-1];break;case 50:h[d-3].draw="actor",h[d-3].type="addParticipant",h[d-3].description=b.parseMessage(h[d-1]),this.$=h[d-3];break;case 51:h[d-1].draw="actor",h[d-1].type="addParticipant",this.$=h[d-1];break;case 52:h[d-1].type="destroyParticipant",this.$=h[d-1];break;case 53:this.$=[h[d-1],{type:"addNote",placement:h[d-2],actor:h[d-1].actor,text:h[d]}];break;case 54:h[d-2]=[].concat(h[d-1],h[d-1]).slice(0,2),h[d-2][0]=h[d-2][0].actor,h[d-2][1]=h[d-2][1].actor,this.$=[h[d-1],{type:"addNote",placement:b.PLACEMENT.OVER,actor:h[d-2].slice(0,2),text:h[d]}];break;case 55:this.$=[h[d-1],{type:"addLinks",actor:h[d-1].actor,text:h[d]}];break;case 56:this.$=[h[d-1],{type:"addALink",actor:h[d-1].actor,text:h[d]}];break;case 57:this.$=[h[d-1],{type:"addProperties",actor:h[d-1].actor,text:h[d]}];break;case 58:this.$=[h[d-1],{type:"addDetails",actor:h[d-1].actor,text:h[d]}];break;case 61:this.$=[h[d-2],h[d]];break;case 62:this.$=h[d];break;case 63:this.$=b.PLACEMENT.LEFTOF;break;case 64:this.$=b.PLACEMENT.RIGHTOF;break;case 65:this.$=[h[d-4],h[d-1],{type:"addMessage",from:h[d-4].actor,to:h[d-1].actor,signalType:h[d-3],msg:h[d],activate:!0},{type:"activeStart",signalType:b.LINETYPE.ACTIVE_START,actor:h[d-1]}];break;case 66:this.$=[h[d-4],h[d-1],{type:"addMessage",from:h[d-4].actor,to:h[d-1].actor,signalType:h[d-3],msg:h[d]},{type:"activeEnd",signalType:b.LINETYPE.ACTIVE_END,actor:h[d-4]}];break;case 67:this.$=[h[d-3],h[d-1],{type:"addMessage",from:h[d-3].actor,to:h[d-1].actor,signalType:h[d-2],msg:h[d]}];break;case 68:this.$={type:"addParticipant",actor:h[d]};break;case 69:this.$=b.LINETYPE.SOLID_OPEN;break;case 70:this.$=b.LINETYPE.DOTTED_OPEN;break;case 71:this.$=b.LINETYPE.SOLID;break;case 72:this.$=b.LINETYPE.DOTTED;break;case 73:this.$=b.LINETYPE.SOLID_CROSS;break;case 74:this.$=b.LINETYPE.DOTTED_CROSS;break;case 75:this.$=b.LINETYPE.SOLID_POINT;break;case 76:this.$=b.LINETYPE.DOTTED_POINT;break;case 77:this.$=b.parseMessage(h[d].trim().substring(1));break}},table:[{3:1,4:e,5:c,6:s},{1:[3]},{3:5,4:e,5:c,6:s},{3:6,4:e,5:c,6:s},t([1,4,5,13,14,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:a,5:o,8:8,9:10,12:12,13:l,14:p,17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},t(y,[2,5]),{9:47,12:12,13:l,14:p,17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},t(y,[2,7]),t(y,[2,8]),t(y,[2,14]),{12:48,50:H,52:U,53:F},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,70:N},{22:55,70:N},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},t(y,[2,29]),t(y,[2,30]),{32:[1,61]},{34:[1,62]},t(y,[2,33]),{15:[1,63]},{15:[1,64]},{15:[1,65]},{15:[1,66]},{15:[1,67]},{15:[1,68]},{15:[1,69]},{15:[1,70]},{22:71,70:N},{22:72,70:N},{22:73,70:N},{67:74,71:[1,75],72:[1,76],73:[1,77],74:[1,78],75:[1,79],76:[1,80],77:[1,81],78:[1,82]},{55:83,57:[1,84],65:[1,85],66:[1,86]},{22:87,70:N},{22:88,70:N},{22:89,70:N},{22:90,70:N},t([5,51,64,71,72,73,74,75,76,77,78,79],[2,68]),t(y,[2,6]),t(y,[2,15]),t(P,[2,9],{10:91}),t(y,[2,17]),{5:[1,93],19:[1,92]},{5:[1,94]},t(y,[2,21]),{5:[1,95]},{5:[1,96]},t(y,[2,24]),t(y,[2,25]),t(y,[2,26]),t(y,[2,27]),t(y,[2,28]),t(y,[2,31]),t(y,[2,32]),t(j,i,{7:97}),t(j,i,{7:98}),t(j,i,{7:99}),t(rt,i,{40:100,7:101}),t(A,i,{42:102,7:103}),t(A,i,{7:103,42:104}),t(Gt,i,{45:105,7:106}),t(j,i,{7:107}),{5:[1,109],51:[1,108]},{5:[1,111],51:[1,110]},{5:[1,112]},{22:115,68:[1,113],69:[1,114],70:N},t(ht,[2,69]),t(ht,[2,70]),t(ht,[2,71]),t(ht,[2,72]),t(ht,[2,73]),t(ht,[2,74]),t(ht,[2,75]),t(ht,[2,76]),{22:116,70:N},{22:118,58:117,70:N},{70:[2,63]},{70:[2,64]},{56:119,79:ot},{56:121,79:ot},{56:122,79:ot},{56:123,79:ot},{4:[1,126],5:[1,128],11:125,12:127,16:[1,124],50:H,52:U,53:F},{5:[1,129]},t(y,[2,19]),t(y,[2,20]),t(y,[2,22]),t(y,[2,23]),{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[1,130],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[1,131],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[1,132],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{16:[1,133]},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[2,46],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,49:[1,134],50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{16:[1,135]},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[2,44],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,48:[1,136],50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{16:[1,137]},{16:[1,138]},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[2,42],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,47:[1,139],50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[1,140],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{15:[1,141]},t(y,[2,49]),{15:[1,142]},t(y,[2,51]),t(y,[2,52]),{22:143,70:N},{22:144,70:N},{56:145,79:ot},{56:146,79:ot},{56:147,79:ot},{64:[1,148],79:[2,62]},{5:[2,55]},{5:[2,77]},{5:[2,56]},{5:[2,57]},{5:[2,58]},t(y,[2,16]),t(P,[2,10]),{12:149,50:H,52:U,53:F},t(P,[2,12]),t(P,[2,13]),t(y,[2,18]),t(y,[2,34]),t(y,[2,35]),t(y,[2,36]),t(y,[2,37]),{15:[1,150]},t(y,[2,38]),{15:[1,151]},t(y,[2,39]),t(y,[2,40]),{15:[1,152]},t(y,[2,41]),{5:[1,153]},{5:[1,154]},{56:155,79:ot},{56:156,79:ot},{5:[2,67]},{5:[2,53]},{5:[2,54]},{22:157,70:N},t(P,[2,11]),t(rt,i,{7:101,40:158}),t(A,i,{7:103,42:159}),t(Gt,i,{7:106,45:160}),t(y,[2,48]),t(y,[2,50]),{5:[2,65]},{5:[2,66]},{79:[2,61]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],85:[2,63],86:[2,64],119:[2,55],120:[2,77],121:[2,56],122:[2,57],123:[2,58],145:[2,67],146:[2,53],147:[2,54],155:[2,65],156:[2,66],157:[2,61],158:[2,47],159:[2,45],160:[2,43]},parseError:function(w,k){if(k.recoverable)this.trace(w);else{var L=new Error(w);throw L.hash=k,L}},parse:function(w){var k=this,L=[0],b=[],M=[null],h=[],Et=this.table,d="",_t=0,Xt=0,Te=2,Jt=1,be=h.slice.call(arguments,1),Y=Object.create(this.lexer),pt={yy:{}};for(var Ct in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Ct)&&(pt.yy[Ct]=this.yy[Ct]);Y.setInput(w,pt.yy),pt.yy.lexer=Y,pt.yy.parser=this,typeof Y.yylloc>"u"&&(Y.yylloc={});var Dt=Y.yylloc;h.push(Dt);var Ee=Y.options&&Y.options.ranges;typeof pt.yy.parseError=="function"?this.parseError=pt.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function me(){var lt;return lt=b.pop()||Y.lex()||Jt,typeof lt!="number"&&(lt instanceof Array&&(b=lt,lt=b.pop()),lt=k.symbols_[lt]||lt),lt}for(var G,ut,et,Vt,yt={},kt,ct,Zt,Pt;;){if(ut=L[L.length-1],this.defaultActions[ut]?et=this.defaultActions[ut]:((G===null||typeof G>"u")&&(G=me()),et=Et[ut]&&Et[ut][G]),typeof et>"u"||!et.length||!et[0]){var Ot="";Pt=[];for(kt in Et[ut])this.terminals_[kt]&&kt>Te&&Pt.push("'"+this.terminals_[kt]+"'");Y.showPosition?Ot="Parse error on line "+(_t+1)+`:
                        +import{g as we,y as ve,x as _e,c as st,s as $t,b as ke,a as Pe,A as Le,l as X,d as At,j as v,e as Ie,h as Lt,i as Ae,z as B,b1 as nt,b2 as wt,m as te,r as ee,b0 as Bt,aO as se,b3 as Ne}from"./mermaid.core-Q3WVcjPF.js";import{d as Se,a as Me,g as Nt,b as zt,c as Re,e as Ce}from"./svgDrawCommon-5ccd53ef-wBNBFr7n.js";import"./app-UOvWaKji.js";var Yt=function(){var t=function(dt,w,k,L){for(k=k||{},L=dt.length;L--;k[dt[L]]=w);return k},e=[1,2],c=[1,3],s=[1,4],i=[2,4],a=[1,9],o=[1,11],l=[1,13],p=[1,14],r=[1,16],x=[1,17],T=[1,18],u=[1,24],g=[1,25],m=[1,26],_=[1,27],I=[1,28],V=[1,29],S=[1,30],O=[1,31],R=[1,32],q=[1,33],z=[1,34],J=[1,35],$=[1,36],H=[1,37],U=[1,38],F=[1,39],W=[1,41],Z=[1,42],K=[1,43],Q=[1,44],tt=[1,45],N=[1,46],y=[1,4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,48,49,50,52,53,54,59,60,61,62,70],P=[4,5,16,50,52,53],j=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],rt=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,49,50,52,53,54,59,60,61,62,70],A=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,48,50,52,53,54,59,60,61,62,70],Gt=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,50,52,53,54,59,60,61,62,70],ht=[68,69,70],ot=[1,120],Mt={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,box_section:10,box_line:11,participant_statement:12,create:13,box:14,restOfLine:15,end:16,signal:17,autonumber:18,NUM:19,off:20,activate:21,actor:22,deactivate:23,note_statement:24,links_statement:25,link_statement:26,properties_statement:27,details_statement:28,title:29,legacy_title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,loop:36,rect:37,opt:38,alt:39,else_sections:40,par:41,par_sections:42,par_over:43,critical:44,option_sections:45,break:46,option:47,and:48,else:49,participant:50,AS:51,participant_actor:52,destroy:53,note:54,placement:55,text2:56,over:57,actor_pair:58,links:59,link:60,properties:61,details:62,spaceList:63,",":64,left_of:65,right_of:66,signaltype:67,"+":68,"-":69,ACTOR:70,SOLID_OPEN_ARROW:71,DOTTED_OPEN_ARROW:72,SOLID_ARROW:73,DOTTED_ARROW:74,SOLID_CROSS:75,DOTTED_CROSS:76,SOLID_POINT:77,DOTTED_POINT:78,TXT:79,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",13:"create",14:"box",15:"restOfLine",16:"end",18:"autonumber",19:"NUM",20:"off",21:"activate",23:"deactivate",29:"title",30:"legacy_title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"loop",37:"rect",38:"opt",39:"alt",41:"par",43:"par_over",44:"critical",46:"break",47:"option",48:"and",49:"else",50:"participant",51:"AS",52:"participant_actor",53:"destroy",54:"note",57:"over",59:"links",60:"link",61:"properties",62:"details",64:",",65:"left_of",66:"right_of",68:"+",69:"-",70:"ACTOR",71:"SOLID_OPEN_ARROW",72:"DOTTED_OPEN_ARROW",73:"SOLID_ARROW",74:"DOTTED_ARROW",75:"SOLID_CROSS",76:"DOTTED_CROSS",77:"SOLID_POINT",78:"DOTTED_POINT",79:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[10,0],[10,2],[11,2],[11,1],[11,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[45,1],[45,4],[42,1],[42,4],[40,1],[40,4],[12,5],[12,3],[12,5],[12,3],[12,3],[24,4],[24,4],[25,3],[26,3],[27,3],[28,3],[63,2],[63,1],[58,3],[58,1],[55,1],[55,1],[17,5],[17,5],[17,4],[22,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[56,1]],performAction:function(w,k,L,b,M,h,Et){var d=h.length-1;switch(M){case 3:return b.apply(h[d]),h[d];case 4:case 9:this.$=[];break;case 5:case 10:h[d-1].push(h[d]),this.$=h[d-1];break;case 6:case 7:case 11:case 12:this.$=h[d];break;case 8:case 13:this.$=[];break;case 15:h[d].type="createParticipant",this.$=h[d];break;case 16:h[d-1].unshift({type:"boxStart",boxData:b.parseBoxData(h[d-2])}),h[d-1].push({type:"boxEnd",boxText:h[d-2]}),this.$=h[d-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(h[d-2]),sequenceIndexStep:Number(h[d-1]),sequenceVisible:!0,signalType:b.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(h[d-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:b.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:b.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:b.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:b.LINETYPE.ACTIVE_START,actor:h[d-1]};break;case 23:this.$={type:"activeEnd",signalType:b.LINETYPE.ACTIVE_END,actor:h[d-1]};break;case 29:b.setDiagramTitle(h[d].substring(6)),this.$=h[d].substring(6);break;case 30:b.setDiagramTitle(h[d].substring(7)),this.$=h[d].substring(7);break;case 31:this.$=h[d].trim(),b.setAccTitle(this.$);break;case 32:case 33:this.$=h[d].trim(),b.setAccDescription(this.$);break;case 34:h[d-1].unshift({type:"loopStart",loopText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.LOOP_START}),h[d-1].push({type:"loopEnd",loopText:h[d-2],signalType:b.LINETYPE.LOOP_END}),this.$=h[d-1];break;case 35:h[d-1].unshift({type:"rectStart",color:b.parseMessage(h[d-2]),signalType:b.LINETYPE.RECT_START}),h[d-1].push({type:"rectEnd",color:b.parseMessage(h[d-2]),signalType:b.LINETYPE.RECT_END}),this.$=h[d-1];break;case 36:h[d-1].unshift({type:"optStart",optText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.OPT_START}),h[d-1].push({type:"optEnd",optText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.OPT_END}),this.$=h[d-1];break;case 37:h[d-1].unshift({type:"altStart",altText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.ALT_START}),h[d-1].push({type:"altEnd",signalType:b.LINETYPE.ALT_END}),this.$=h[d-1];break;case 38:h[d-1].unshift({type:"parStart",parText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.PAR_START}),h[d-1].push({type:"parEnd",signalType:b.LINETYPE.PAR_END}),this.$=h[d-1];break;case 39:h[d-1].unshift({type:"parStart",parText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.PAR_OVER_START}),h[d-1].push({type:"parEnd",signalType:b.LINETYPE.PAR_END}),this.$=h[d-1];break;case 40:h[d-1].unshift({type:"criticalStart",criticalText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.CRITICAL_START}),h[d-1].push({type:"criticalEnd",signalType:b.LINETYPE.CRITICAL_END}),this.$=h[d-1];break;case 41:h[d-1].unshift({type:"breakStart",breakText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.BREAK_START}),h[d-1].push({type:"breakEnd",optText:b.parseMessage(h[d-2]),signalType:b.LINETYPE.BREAK_END}),this.$=h[d-1];break;case 43:this.$=h[d-3].concat([{type:"option",optionText:b.parseMessage(h[d-1]),signalType:b.LINETYPE.CRITICAL_OPTION},h[d]]);break;case 45:this.$=h[d-3].concat([{type:"and",parText:b.parseMessage(h[d-1]),signalType:b.LINETYPE.PAR_AND},h[d]]);break;case 47:this.$=h[d-3].concat([{type:"else",altText:b.parseMessage(h[d-1]),signalType:b.LINETYPE.ALT_ELSE},h[d]]);break;case 48:h[d-3].draw="participant",h[d-3].type="addParticipant",h[d-3].description=b.parseMessage(h[d-1]),this.$=h[d-3];break;case 49:h[d-1].draw="participant",h[d-1].type="addParticipant",this.$=h[d-1];break;case 50:h[d-3].draw="actor",h[d-3].type="addParticipant",h[d-3].description=b.parseMessage(h[d-1]),this.$=h[d-3];break;case 51:h[d-1].draw="actor",h[d-1].type="addParticipant",this.$=h[d-1];break;case 52:h[d-1].type="destroyParticipant",this.$=h[d-1];break;case 53:this.$=[h[d-1],{type:"addNote",placement:h[d-2],actor:h[d-1].actor,text:h[d]}];break;case 54:h[d-2]=[].concat(h[d-1],h[d-1]).slice(0,2),h[d-2][0]=h[d-2][0].actor,h[d-2][1]=h[d-2][1].actor,this.$=[h[d-1],{type:"addNote",placement:b.PLACEMENT.OVER,actor:h[d-2].slice(0,2),text:h[d]}];break;case 55:this.$=[h[d-1],{type:"addLinks",actor:h[d-1].actor,text:h[d]}];break;case 56:this.$=[h[d-1],{type:"addALink",actor:h[d-1].actor,text:h[d]}];break;case 57:this.$=[h[d-1],{type:"addProperties",actor:h[d-1].actor,text:h[d]}];break;case 58:this.$=[h[d-1],{type:"addDetails",actor:h[d-1].actor,text:h[d]}];break;case 61:this.$=[h[d-2],h[d]];break;case 62:this.$=h[d];break;case 63:this.$=b.PLACEMENT.LEFTOF;break;case 64:this.$=b.PLACEMENT.RIGHTOF;break;case 65:this.$=[h[d-4],h[d-1],{type:"addMessage",from:h[d-4].actor,to:h[d-1].actor,signalType:h[d-3],msg:h[d],activate:!0},{type:"activeStart",signalType:b.LINETYPE.ACTIVE_START,actor:h[d-1]}];break;case 66:this.$=[h[d-4],h[d-1],{type:"addMessage",from:h[d-4].actor,to:h[d-1].actor,signalType:h[d-3],msg:h[d]},{type:"activeEnd",signalType:b.LINETYPE.ACTIVE_END,actor:h[d-4]}];break;case 67:this.$=[h[d-3],h[d-1],{type:"addMessage",from:h[d-3].actor,to:h[d-1].actor,signalType:h[d-2],msg:h[d]}];break;case 68:this.$={type:"addParticipant",actor:h[d]};break;case 69:this.$=b.LINETYPE.SOLID_OPEN;break;case 70:this.$=b.LINETYPE.DOTTED_OPEN;break;case 71:this.$=b.LINETYPE.SOLID;break;case 72:this.$=b.LINETYPE.DOTTED;break;case 73:this.$=b.LINETYPE.SOLID_CROSS;break;case 74:this.$=b.LINETYPE.DOTTED_CROSS;break;case 75:this.$=b.LINETYPE.SOLID_POINT;break;case 76:this.$=b.LINETYPE.DOTTED_POINT;break;case 77:this.$=b.parseMessage(h[d].trim().substring(1));break}},table:[{3:1,4:e,5:c,6:s},{1:[3]},{3:5,4:e,5:c,6:s},{3:6,4:e,5:c,6:s},t([1,4,5,13,14,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:a,5:o,8:8,9:10,12:12,13:l,14:p,17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},t(y,[2,5]),{9:47,12:12,13:l,14:p,17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},t(y,[2,7]),t(y,[2,8]),t(y,[2,14]),{12:48,50:H,52:U,53:F},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,70:N},{22:55,70:N},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},t(y,[2,29]),t(y,[2,30]),{32:[1,61]},{34:[1,62]},t(y,[2,33]),{15:[1,63]},{15:[1,64]},{15:[1,65]},{15:[1,66]},{15:[1,67]},{15:[1,68]},{15:[1,69]},{15:[1,70]},{22:71,70:N},{22:72,70:N},{22:73,70:N},{67:74,71:[1,75],72:[1,76],73:[1,77],74:[1,78],75:[1,79],76:[1,80],77:[1,81],78:[1,82]},{55:83,57:[1,84],65:[1,85],66:[1,86]},{22:87,70:N},{22:88,70:N},{22:89,70:N},{22:90,70:N},t([5,51,64,71,72,73,74,75,76,77,78,79],[2,68]),t(y,[2,6]),t(y,[2,15]),t(P,[2,9],{10:91}),t(y,[2,17]),{5:[1,93],19:[1,92]},{5:[1,94]},t(y,[2,21]),{5:[1,95]},{5:[1,96]},t(y,[2,24]),t(y,[2,25]),t(y,[2,26]),t(y,[2,27]),t(y,[2,28]),t(y,[2,31]),t(y,[2,32]),t(j,i,{7:97}),t(j,i,{7:98}),t(j,i,{7:99}),t(rt,i,{40:100,7:101}),t(A,i,{42:102,7:103}),t(A,i,{7:103,42:104}),t(Gt,i,{45:105,7:106}),t(j,i,{7:107}),{5:[1,109],51:[1,108]},{5:[1,111],51:[1,110]},{5:[1,112]},{22:115,68:[1,113],69:[1,114],70:N},t(ht,[2,69]),t(ht,[2,70]),t(ht,[2,71]),t(ht,[2,72]),t(ht,[2,73]),t(ht,[2,74]),t(ht,[2,75]),t(ht,[2,76]),{22:116,70:N},{22:118,58:117,70:N},{70:[2,63]},{70:[2,64]},{56:119,79:ot},{56:121,79:ot},{56:122,79:ot},{56:123,79:ot},{4:[1,126],5:[1,128],11:125,12:127,16:[1,124],50:H,52:U,53:F},{5:[1,129]},t(y,[2,19]),t(y,[2,20]),t(y,[2,22]),t(y,[2,23]),{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[1,130],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[1,131],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[1,132],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{16:[1,133]},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[2,46],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,49:[1,134],50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{16:[1,135]},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[2,44],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,48:[1,136],50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{16:[1,137]},{16:[1,138]},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[2,42],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,47:[1,139],50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{4:a,5:o,8:8,9:10,12:12,13:l,14:p,16:[1,140],17:15,18:r,21:x,22:40,23:T,24:19,25:20,26:21,27:22,28:23,29:u,30:g,31:m,33:_,35:I,36:V,37:S,38:O,39:R,41:q,43:z,44:J,46:$,50:H,52:U,53:F,54:W,59:Z,60:K,61:Q,62:tt,70:N},{15:[1,141]},t(y,[2,49]),{15:[1,142]},t(y,[2,51]),t(y,[2,52]),{22:143,70:N},{22:144,70:N},{56:145,79:ot},{56:146,79:ot},{56:147,79:ot},{64:[1,148],79:[2,62]},{5:[2,55]},{5:[2,77]},{5:[2,56]},{5:[2,57]},{5:[2,58]},t(y,[2,16]),t(P,[2,10]),{12:149,50:H,52:U,53:F},t(P,[2,12]),t(P,[2,13]),t(y,[2,18]),t(y,[2,34]),t(y,[2,35]),t(y,[2,36]),t(y,[2,37]),{15:[1,150]},t(y,[2,38]),{15:[1,151]},t(y,[2,39]),t(y,[2,40]),{15:[1,152]},t(y,[2,41]),{5:[1,153]},{5:[1,154]},{56:155,79:ot},{56:156,79:ot},{5:[2,67]},{5:[2,53]},{5:[2,54]},{22:157,70:N},t(P,[2,11]),t(rt,i,{7:101,40:158}),t(A,i,{7:103,42:159}),t(Gt,i,{7:106,45:160}),t(y,[2,48]),t(y,[2,50]),{5:[2,65]},{5:[2,66]},{79:[2,61]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],85:[2,63],86:[2,64],119:[2,55],120:[2,77],121:[2,56],122:[2,57],123:[2,58],145:[2,67],146:[2,53],147:[2,54],155:[2,65],156:[2,66],157:[2,61],158:[2,47],159:[2,45],160:[2,43]},parseError:function(w,k){if(k.recoverable)this.trace(w);else{var L=new Error(w);throw L.hash=k,L}},parse:function(w){var k=this,L=[0],b=[],M=[null],h=[],Et=this.table,d="",_t=0,Xt=0,Te=2,Jt=1,be=h.slice.call(arguments,1),Y=Object.create(this.lexer),pt={yy:{}};for(var Ct in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Ct)&&(pt.yy[Ct]=this.yy[Ct]);Y.setInput(w,pt.yy),pt.yy.lexer=Y,pt.yy.parser=this,typeof Y.yylloc>"u"&&(Y.yylloc={});var Dt=Y.yylloc;h.push(Dt);var Ee=Y.options&&Y.options.ranges;typeof pt.yy.parseError=="function"?this.parseError=pt.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function me(){var lt;return lt=b.pop()||Y.lex()||Jt,typeof lt!="number"&&(lt instanceof Array&&(b=lt,lt=b.pop()),lt=k.symbols_[lt]||lt),lt}for(var G,ut,et,Vt,yt={},kt,ct,Zt,Pt;;){if(ut=L[L.length-1],this.defaultActions[ut]?et=this.defaultActions[ut]:((G===null||typeof G>"u")&&(G=me()),et=Et[ut]&&Et[ut][G]),typeof et>"u"||!et.length||!et[0]){var Ot="";Pt=[];for(kt in Et[ut])this.terminals_[kt]&&kt>Te&&Pt.push("'"+this.terminals_[kt]+"'");Y.showPosition?Ot="Parse error on line "+(_t+1)+`:
                         `+Y.showPosition()+`
                         Expecting `+Pt.join(", ")+", got '"+(this.terminals_[G]||G)+"'":Ot="Parse error on line "+(_t+1)+": Unexpected "+(G==Jt?"end of input":"'"+(this.terminals_[G]||G)+"'"),this.parseError(Ot,{text:Y.match,token:this.terminals_[G]||G,line:Y.yylineno,loc:Dt,expected:Pt})}if(et[0]instanceof Array&&et.length>1)throw new Error("Parse Error: multiple actions possible at state: "+ut+", token: "+G);switch(et[0]){case 1:L.push(G),M.push(Y.yytext),h.push(Y.yylloc),L.push(et[1]),G=null,Xt=Y.yyleng,d=Y.yytext,_t=Y.yylineno,Dt=Y.yylloc;break;case 2:if(ct=this.productions_[et[1]][1],yt.$=M[M.length-ct],yt._$={first_line:h[h.length-(ct||1)].first_line,last_line:h[h.length-1].last_line,first_column:h[h.length-(ct||1)].first_column,last_column:h[h.length-1].last_column},Ee&&(yt._$.range=[h[h.length-(ct||1)].range[0],h[h.length-1].range[1]]),Vt=this.performAction.apply(yt,[d,Xt,_t,pt.yy,et[1],M,h].concat(be)),typeof Vt<"u")return Vt;ct&&(L=L.slice(0,-1*ct*2),M=M.slice(0,-1*ct),h=h.slice(0,-1*ct)),L.push(this.productions_[et[1]][0]),M.push(yt.$),h.push(yt._$),Zt=Et[L[L.length-2]][L[L.length-1]],L.push(Zt);break;case 3:return!0}}return!0}},ye=function(){var dt={EOF:1,parseError:function(k,L){if(this.yy.parser)this.yy.parser.parseError(k,L);else throw new Error(k)},setInput:function(w,k){return this.yy=k||this.yy||{},this._input=w,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var w=this._input[0];this.yytext+=w,this.yyleng++,this.offset++,this.match+=w,this.matched+=w;var k=w.match(/(?:\r\n?|\n).*/g);return k?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),w},unput:function(w){var k=w.length,L=w.split(/(?:\r\n?|\n)/g);this._input=w+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-k),this.offset-=k;var b=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),L.length-1&&(this.yylineno-=L.length-1);var M=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:L?(L.length===b.length?this.yylloc.first_column:0)+b[b.length-L.length].length-L[0].length:this.yylloc.first_column-k},this.options.ranges&&(this.yylloc.range=[M[0],M[0]+this.yyleng-k]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
                         `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(w){this.unput(this.match.slice(w))},pastInput:function(){var w=this.matched.substr(0,this.matched.length-this.match.length);return(w.length>20?"...":"")+w.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var w=this.match;return w.length<20&&(w+=this._input.substr(0,20-w.length)),(w.substr(0,20)+(w.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var w=this.pastInput(),k=new Array(w.length+1).join("-");return w+this.upcomingInput()+`
                        diff --git a/assets/shadowsocks.html--KkJPTtP.js b/assets/shadowsocks.html-2sZeanJM.js
                        similarity index 99%
                        rename from assets/shadowsocks.html--KkJPTtP.js
                        rename to assets/shadowsocks.html-2sZeanJM.js
                        index bf90df03a2..4e49f2807c 100644
                        --- a/assets/shadowsocks.html--KkJPTtP.js
                        +++ b/assets/shadowsocks.html-2sZeanJM.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as a,o as p,c as r,a as e,b as s,d as n,w as c,e as l}from"./app-PDrbPfzp.js";const d={},u=e("h1",{id:"shadowsocks",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#shadowsocks"},[e("span",null,"Shadowsocks")])],-1),h={href:"https://en.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},k=l('

                        Supported Encryption Methods

                        The currently supported methods are following:

                        • Recommended encryption methods:
                          • 2022-blake3-aes-128-gcm
                          • 2022-blake3-aes-256-gcm
                          • 2022-blake3-chacha20-poly1305
                        • Other encryption methods:
                          • aes-256-gcm
                          • aes-128-gcm
                          • chacha20-poly1305/chacha20-ietf-poly1305
                          • xchacha20-poly1305/xchacha20-ietf-poly1305
                          • none/plain

                        The Shadowsocks 2022 new protocol format improves performance and includes complete replay protection, addressing the following security issues in the old protocol:

                        ',4),m={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},b=e("li",null,"Increasing false positive rate of the original TCP replay filter over time",-1),g=e("li",null,"Lack of UDP replay protection",-1),v=e("li",null,"TCP behaviors that can be used for active probing",-1),f=l(`

                        Danger

                        Traffic transmitted without encryption using the "none" method will be in plain text. Do not use it on public networks for security reasons.

                        InboundConfigurationObject

                        {
                        +import{_ as i,r as a,o as p,c as r,a as e,b as s,d as n,w as c,e as l}from"./app-UOvWaKji.js";const d={},u=e("h1",{id:"shadowsocks",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#shadowsocks"},[e("span",null,"Shadowsocks")])],-1),h={href:"https://en.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},k=l('

                        Supported Encryption Methods

                        The currently supported methods are following:

                        • Recommended encryption methods:
                          • 2022-blake3-aes-128-gcm
                          • 2022-blake3-aes-256-gcm
                          • 2022-blake3-chacha20-poly1305
                        • Other encryption methods:
                          • aes-256-gcm
                          • aes-128-gcm
                          • chacha20-poly1305/chacha20-ietf-poly1305
                          • xchacha20-poly1305/xchacha20-ietf-poly1305
                          • none/plain

                        The Shadowsocks 2022 new protocol format improves performance and includes complete replay protection, addressing the following security issues in the old protocol:

                        ',4),m={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},b=e("li",null,"Increasing false positive rate of the original TCP replay filter over time",-1),g=e("li",null,"Lack of UDP replay protection",-1),v=e("li",null,"TCP behaviors that can be used for active probing",-1),f=l(`

                        Danger

                        Traffic transmitted without encryption using the "none" method will be in plain text. Do not use it on public networks for security reasons.

                        InboundConfigurationObject

                        {
                           "settings": {
                             "clients": [],
                             "password": "password",
                        diff --git a/assets/shadowsocks.html-P4_uET28.js b/assets/shadowsocks.html-CX52is5W.js
                        similarity index 99%
                        rename from assets/shadowsocks.html-P4_uET28.js
                        rename to assets/shadowsocks.html-CX52is5W.js
                        index 04b77ec120..de889f1067 100644
                        --- a/assets/shadowsocks.html-P4_uET28.js
                        +++ b/assets/shadowsocks.html-CX52is5W.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as e,o as i,c as u,a as s,b as n,d as o,w as l,e as c}from"./app-PDrbPfzp.js";const r={},d=s("h1",{id:"shadowsocks",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#shadowsocks"},[s("span",null,"Shadowsocks")])],-1),k={href:"https://zh.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},h=c("

                        目前兼容性如下:

                        • 支持 TCP 和 UDP 数据包转发,其中 UDP 可选择性关闭;
                        • 推荐的加密方式:
                          • 2022-blake3-aes-128-gcm
                          • 2022-blake3-aes-256-gcm
                          • 2022-blake3-chacha20-poly1305
                        • 其他加密方式
                          • aes-256-gcm
                          • aes-128-gcm
                          • chacha20-poly1305 或称 chacha20-ietf-poly1305
                          • xchacha20-poly1305 或称 xchacha20-ietf-poly1305
                          • none 或 plain

                        Shadowsocks 2022 新协议格式提升了性能并带有完整的重放保护,解决了旧协议的以下安全问题:

                        ",3),b={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},q=s("li",null,"原有 TCP 重放过滤器误报率随时间增加",-1),m=s("li",null,"没有 UDP 重放保护",-1),v=s("li",null,"可用于主动探测的 TCP 行为",-1),g=c(`

                        警告

                        "none" 不加密方式下流量将明文传输。为确保安全性, 不要在公共网络上使用。

                        InboundConfigurationObject

                        {
                        +import{_ as p,r as e,o as i,c as u,a as s,b as n,d as o,w as l,e as c}from"./app-UOvWaKji.js";const r={},d=s("h1",{id:"shadowsocks",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#shadowsocks"},[s("span",null,"Shadowsocks")])],-1),k={href:"https://zh.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},h=c("

                        目前兼容性如下:

                        • 支持 TCP 和 UDP 数据包转发,其中 UDP 可选择性关闭;
                        • 推荐的加密方式:
                          • 2022-blake3-aes-128-gcm
                          • 2022-blake3-aes-256-gcm
                          • 2022-blake3-chacha20-poly1305
                        • 其他加密方式
                          • aes-256-gcm
                          • aes-128-gcm
                          • chacha20-poly1305 或称 chacha20-ietf-poly1305
                          • xchacha20-poly1305 或称 xchacha20-ietf-poly1305
                          • none 或 plain

                        Shadowsocks 2022 新协议格式提升了性能并带有完整的重放保护,解决了旧协议的以下安全问题:

                        ",3),b={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},q=s("li",null,"原有 TCP 重放过滤器误报率随时间增加",-1),m=s("li",null,"没有 UDP 重放保护",-1),v=s("li",null,"可用于主动探测的 TCP 行为",-1),g=c(`

                        警告

                        "none" 不加密方式下流量将明文传输。为确保安全性, 不要在公共网络上使用。

                        InboundConfigurationObject

                        {
                           "settings": {
                             "password": "密码",
                             "method": "aes-256-gcm",
                        diff --git a/assets/shadowsocks.html-gizaiMQX.js b/assets/shadowsocks.html-U6pVq6AU.js
                        similarity index 99%
                        rename from assets/shadowsocks.html-gizaiMQX.js
                        rename to assets/shadowsocks.html-U6pVq6AU.js
                        index 1295b09960..ad0b708fbd 100644
                        --- a/assets/shadowsocks.html-gizaiMQX.js
                        +++ b/assets/shadowsocks.html-U6pVq6AU.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as t,o as r,c as i,a as s,b as n,d as o,w as p,e as l}from"./app-PDrbPfzp.js";const u={},d=s("h1",{id:"shadowsocks",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#shadowsocks"},[s("span",null,"Shadowsocks")])],-1),k={href:"https://zh.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},b=l("

                        目前兼容性如下:

                        • 支持 TCP 和 UDP 数据包转发,其中 UDP 可选择性关闭;
                        • 推荐的加密方式:
                          • 2022-blake3-aes-128-gcm
                          • 2022-blake3-aes-256-gcm
                          • 2022-blake3-chacha20-poly1305
                        • 其他加密方式
                          • aes-256-gcm
                          • aes-128-gcm
                          • chacha20-poly1305 或称 chacha20-ietf-poly1305
                          • xchacha20-poly1305 或称 xchacha20-ietf-poly1305
                          • none 或 plain

                        Shadowsocks 2022 新协议格式提升了性能并带有完整的重放保护,解决了旧协议的以下安全问题:

                        ",3),v={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},h=s("li",null,"原有 TCP 重放过滤器误报率随时间增加",-1),q=s("li",null,"没有 UDP 重放保护",-1),m=s("li",null,"可用于主动探测的 TCP 行为",-1),g=l(`

                        警告

                        "none" 不加密方式下流量将明文传输。为确保安全性, 不要在公共网络上使用。

                        OutboundConfigurationObject

                        {
                        +import{_ as c,r as t,o as r,c as i,a as s,b as n,d as o,w as p,e as l}from"./app-UOvWaKji.js";const u={},d=s("h1",{id:"shadowsocks",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#shadowsocks"},[s("span",null,"Shadowsocks")])],-1),k={href:"https://zh.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},b=l("

                        目前兼容性如下:

                        • 支持 TCP 和 UDP 数据包转发,其中 UDP 可选择性关闭;
                        • 推荐的加密方式:
                          • 2022-blake3-aes-128-gcm
                          • 2022-blake3-aes-256-gcm
                          • 2022-blake3-chacha20-poly1305
                        • 其他加密方式
                          • aes-256-gcm
                          • aes-128-gcm
                          • chacha20-poly1305 或称 chacha20-ietf-poly1305
                          • xchacha20-poly1305 或称 xchacha20-ietf-poly1305
                          • none 或 plain

                        Shadowsocks 2022 新协议格式提升了性能并带有完整的重放保护,解决了旧协议的以下安全问题:

                        ",3),v={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},h=s("li",null,"原有 TCP 重放过滤器误报率随时间增加",-1),q=s("li",null,"没有 UDP 重放保护",-1),m=s("li",null,"可用于主动探测的 TCP 行为",-1),g=l(`

                        警告

                        "none" 不加密方式下流量将明文传输。为确保安全性, 不要在公共网络上使用。

                        OutboundConfigurationObject

                        {
                           "servers": [
                             {
                               "email": "love@xray.com",
                        diff --git a/assets/shadowsocks.html-2vwGKt2T.js b/assets/shadowsocks.html-qiN3SGfm.js
                        similarity index 99%
                        rename from assets/shadowsocks.html-2vwGKt2T.js
                        rename to assets/shadowsocks.html-qiN3SGfm.js
                        index 85b120aa77..6e431855a4 100644
                        --- a/assets/shadowsocks.html-2vwGKt2T.js
                        +++ b/assets/shadowsocks.html-qiN3SGfm.js
                        @@ -1,4 +1,4 @@
                        -import{_ as r,r as a,o as i,c,a as e,b as s,d as n,w as p,e as l}from"./app-PDrbPfzp.js";const d={},u=e("h1",{id:"shadowsocks",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#shadowsocks"},[e("span",null,"Shadowsocks")])],-1),h={href:"https://en.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},k=l("

                        Here are the features and compatibility of Shadowsocks:

                        • It supports TCP and UDP packet forwarding, with the option to disable UDP.
                        • Recommended encryption methods:
                          • 2022-blake3-aes-128-gcm
                          • 2022-blake3-aes-256-gcm
                          • 2022-blake3-chacha20-poly1305
                        • Other encryption methods:
                          • aes-256-gcm
                          • aes-128-gcm
                          • chacha20-poly1305 (also known as chacha20-ietf-poly1305)
                          • none or plain

                        The new protocol format of Shadowsocks 2022 improves performance and includes full replay protection, addressing security issues present in the old protocol:

                        ",3),m={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},b=e("li",null,"Increasing false-positive rate of TCP replay filters over time",-1),v=e("li",null,"Lack of replay protection for UDP",-1),q=e("li",null,"TCP behaviors that can be used for active probing",-1),g=l(`

                        Danger

                        Using the "none" encryption method will transmit traffic in plaintext. It is not recommended to use "none" encryption on public networks to ensure security.

                        OutboundConfigurationObject

                        {
                        +import{_ as r,r as a,o as i,c,a as e,b as s,d as n,w as p,e as l}from"./app-UOvWaKji.js";const d={},u=e("h1",{id:"shadowsocks",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#shadowsocks"},[e("span",null,"Shadowsocks")])],-1),h={href:"https://en.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},k=l("

                        Here are the features and compatibility of Shadowsocks:

                        • It supports TCP and UDP packet forwarding, with the option to disable UDP.
                        • Recommended encryption methods:
                          • 2022-blake3-aes-128-gcm
                          • 2022-blake3-aes-256-gcm
                          • 2022-blake3-chacha20-poly1305
                        • Other encryption methods:
                          • aes-256-gcm
                          • aes-128-gcm
                          • chacha20-poly1305 (also known as chacha20-ietf-poly1305)
                          • none or plain

                        The new protocol format of Shadowsocks 2022 improves performance and includes full replay protection, addressing security issues present in the old protocol:

                        ",3),m={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},b=e("li",null,"Increasing false-positive rate of TCP replay filters over time",-1),v=e("li",null,"Lack of replay protection for UDP",-1),q=e("li",null,"TCP behaviors that can be used for active probing",-1),g=l(`

                        Danger

                        Using the "none" encryption method will transmit traffic in plaintext. It is not recommended to use "none" encryption on public networks to ensure security.

                        OutboundConfigurationObject

                        {
                           "servers": [
                             {
                               "email": "love@xray.com",
                        diff --git a/assets/socks.html-BHL_zNqv.js b/assets/socks.html-AQ8z9yrR.js
                        similarity index 98%
                        rename from assets/socks.html-BHL_zNqv.js
                        rename to assets/socks.html-AQ8z9yrR.js
                        index ecfefe745b..de8bd2ceed 100644
                        --- a/assets/socks.html-BHL_zNqv.js
                        +++ b/assets/socks.html-AQ8z9yrR.js
                        @@ -1,4 +1,4 @@
                        -import{_ as l,r as t,o as r,c as u,a as o,b as e,d as n,w as c,e as p}from"./app-PDrbPfzp.js";const i={},d=o("h1",{id:"socks",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#socks"},[o("span",null,"SOCKS")])],-1),k={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},h={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},v=p(`

                        Danger

                        The SOCKS protocol does not provide encryption for transport and is not suitable for transmitting data over public networks.

                        The use of SOCKS inbound is more meaningful in a local area network or local environment, where it can be used to listen for incoming connections and provide local services to other programs.

                        InboundConfigurationObject

                        {
                        +import{_ as l,r as t,o as r,c as u,a as o,b as e,d as n,w as c,e as p}from"./app-UOvWaKji.js";const i={},d=o("h1",{id:"socks",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#socks"},[o("span",null,"SOCKS")])],-1),k={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},h={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},v=p(`

                        Danger

                        The SOCKS protocol does not provide encryption for transport and is not suitable for transmitting data over public networks.

                        The use of SOCKS inbound is more meaningful in a local area network or local environment, where it can be used to listen for incoming connections and provide local services to other programs.

                        InboundConfigurationObject

                        {
                           "auth": "noauth",
                           "accounts": [
                             {
                        diff --git a/assets/socks.html-NHy_YtOR.js b/assets/socks.html-RHePOH-J.js
                        similarity index 98%
                        rename from assets/socks.html-NHy_YtOR.js
                        rename to assets/socks.html-RHePOH-J.js
                        index 5a36ea6d8a..530a707978 100644
                        --- a/assets/socks.html-NHy_YtOR.js
                        +++ b/assets/socks.html-RHePOH-J.js
                        @@ -1,4 +1,4 @@
                        -import{_ as u,r as t,o as l,c as r,a as n,b as s,d as o,w as c,e as p}from"./app-PDrbPfzp.js";const i={},d=n("h1",{id:"socks",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#socks"},[n("span",null,"Socks")])],-1),k={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},b={href:"https://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4A.protocol",target:"_blank",rel:"noopener noreferrer"},q=p(`

                        警告

                        Socks 协议没有对传输加密,不适宜经公网中传输

                        Socks 入站更有意义的用法是在局域网或本机环境下监听,为其他程序提供本地服务。

                        InboundConfigurationObject

                        {
                        +import{_ as u,r as t,o as l,c as r,a as n,b as s,d as o,w as c,e as p}from"./app-UOvWaKji.js";const i={},d=n("h1",{id:"socks",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#socks"},[n("span",null,"Socks")])],-1),k={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},b={href:"https://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4A.protocol",target:"_blank",rel:"noopener noreferrer"},q=p(`

                        警告

                        Socks 协议没有对传输加密,不适宜经公网中传输

                        Socks 入站更有意义的用法是在局域网或本机环境下监听,为其他程序提供本地服务。

                        InboundConfigurationObject

                        {
                           "auth": "noauth",
                           "accounts": [
                             {
                        diff --git a/assets/socks.html-0nKX1rUP.js b/assets/socks.html-SJq0hqhp.js
                        similarity index 99%
                        rename from assets/socks.html-0nKX1rUP.js
                        rename to assets/socks.html-SJq0hqhp.js
                        index 810e7f4ee1..2db684cfdb 100644
                        --- a/assets/socks.html-0nKX1rUP.js
                        +++ b/assets/socks.html-SJq0hqhp.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as t,o as r,c as i,a as n,b as s,d as e,w as o,e as l}from"./app-PDrbPfzp.js";const u={},d=n("h1",{id:"socks",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#socks"},[n("span",null,"Socks")])],-1),k={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},v=l(`

                        Danger

                        The Socks protocol does not provide encryption for transmission and is not suitable for transmitting data over public networks.

                        OutboundConfigurationObject

                        {
                        +import{_ as c,r as t,o as r,c as i,a as n,b as s,d as e,w as o,e as l}from"./app-UOvWaKji.js";const u={},d=n("h1",{id:"socks",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#socks"},[n("span",null,"Socks")])],-1),k={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},v=l(`

                        Danger

                        The Socks protocol does not provide encryption for transmission and is not suitable for transmitting data over public networks.

                        OutboundConfigurationObject

                        {
                           "servers": [
                             {
                               "address": "127.0.0.1",
                        diff --git a/assets/socks.html-hTp9HjkK.js b/assets/socks.html-_F9IwK5H.js
                        similarity index 99%
                        rename from assets/socks.html-hTp9HjkK.js
                        rename to assets/socks.html-_F9IwK5H.js
                        index c0e340bc11..c73cec0dbb 100644
                        --- a/assets/socks.html-hTp9HjkK.js
                        +++ b/assets/socks.html-_F9IwK5H.js
                        @@ -1,4 +1,4 @@
                        -import{_ as t,r as p,o as c,c as l,a as n,b as s,d as e,w as o,e as r}from"./app-PDrbPfzp.js";const u={},i=r(`

                        Socks

                        标准 Socks 协议实现,兼容 Socks 5。

                        警告

                        Socks 协议没有对传输加密,不适宜经公网中传输

                        OutboundConfigurationObject

                        {
                        +import{_ as t,r as p,o as c,c as l,a as n,b as s,d as e,w as o,e as r}from"./app-UOvWaKji.js";const u={},i=r(`

                        Socks

                        标准 Socks 协议实现,兼容 Socks 5。

                        警告

                        Socks 协议没有对传输加密,不适宜经公网中传输

                        OutboundConfigurationObject

                        {
                           "servers": [
                             {
                               "address": "127.0.0.1",
                        diff --git a/assets/stateDiagram-0ff1cf1a-sl2QinQH.js b/assets/stateDiagram-0ff1cf1a-Rh0IBuDT.js
                        similarity index 97%
                        rename from assets/stateDiagram-0ff1cf1a-sl2QinQH.js
                        rename to assets/stateDiagram-0ff1cf1a-Rh0IBuDT.js
                        index ec114add79..3c9adc3e81 100644
                        --- a/assets/stateDiagram-0ff1cf1a-sl2QinQH.js
                        +++ b/assets/stateDiagram-0ff1cf1a-Rh0IBuDT.js
                        @@ -1 +1 @@
                        -import{p as P,d as N,s as W}from"./styles-d20c7d72-JW20WKkm.js";import{c as t,h as H,l as b,i as R,j as T,ap as v,z as U}from"./mermaid.core-95b3ca__.js";import{G as C}from"./graph-cZfODKa1.js";import{l as F}from"./layout-konkdG3Z.js";import{l as $}from"./line-_nnM_7ZX.js";import"./app-PDrbPfzp.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";const O=e=>e.append("circle").attr("class","start-state").attr("r",t().state.sizeUnit).attr("cx",t().state.padding+t().state.sizeUnit).attr("cy",t().state.padding+t().state.sizeUnit),X=e=>e.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",t().state.textHeight).attr("class","divider").attr("x2",t().state.textHeight*2).attr("y1",0).attr("y2",0),J=(e,i)=>{const o=e.append("text").attr("x",2*t().state.padding).attr("y",t().state.textHeight+2*t().state.padding).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.id),c=o.node().getBBox();return e.insert("rect",":first-child").attr("x",t().state.padding).attr("y",t().state.padding).attr("width",c.width+2*t().state.padding).attr("height",c.height+2*t().state.padding).attr("rx",t().state.radius),o},Y=(e,i)=>{const o=function(l,m,w){const E=l.append("tspan").attr("x",2*t().state.padding).text(m);w||E.attr("dy",t().state.textHeight)},s=e.append("text").attr("x",2*t().state.padding).attr("y",t().state.textHeight+1.3*t().state.padding).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.descriptions[0]).node().getBBox(),g=s.height,p=e.append("text").attr("x",t().state.padding).attr("y",g+t().state.padding*.4+t().state.dividerMargin+t().state.textHeight).attr("class","state-description");let a=!0,r=!0;i.descriptions.forEach(function(l){a||(o(p,l,r),r=!1),a=!1});const y=e.append("line").attr("x1",t().state.padding).attr("y1",t().state.padding+g+t().state.dividerMargin/2).attr("y2",t().state.padding+g+t().state.dividerMargin/2).attr("class","descr-divider"),x=p.node().getBBox(),d=Math.max(x.width,s.width);return y.attr("x2",d+3*t().state.padding),e.insert("rect",":first-child").attr("x",t().state.padding).attr("y",t().state.padding).attr("width",d+2*t().state.padding).attr("height",x.height+g+2*t().state.padding).attr("rx",t().state.radius),e},I=(e,i,o)=>{const c=t().state.padding,s=2*t().state.padding,g=e.node().getBBox(),p=g.width,a=g.x,r=e.append("text").attr("x",0).attr("y",t().state.titleShift).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.id),x=r.node().getBBox().width+s;let d=Math.max(x,p);d===p&&(d=d+s);let l;const m=e.node().getBBox();i.doc,l=a-c,x>p&&(l=(p-d)/2+c),Math.abs(a-m.x)p&&(l=a-(x-p)/2);const w=1-t().state.textHeight;return e.insert("rect",":first-child").attr("x",l).attr("y",w).attr("class",o?"alt-composit":"composit").attr("width",d).attr("height",m.height+t().state.textHeight+t().state.titleShift+1).attr("rx","0"),r.attr("x",l+c),x<=p&&r.attr("x",a+(d-s)/2-x/2+c),e.insert("rect",":first-child").attr("x",l).attr("y",t().state.titleShift-t().state.textHeight-t().state.padding).attr("width",d).attr("height",t().state.textHeight*3).attr("rx",t().state.radius),e.insert("rect",":first-child").attr("x",l).attr("y",t().state.titleShift-t().state.textHeight-t().state.padding).attr("width",d).attr("height",m.height+3+2*t().state.textHeight).attr("rx",t().state.radius),e},_=e=>(e.append("circle").attr("class","end-state-outer").attr("r",t().state.sizeUnit+t().state.miniPadding).attr("cx",t().state.padding+t().state.sizeUnit+t().state.miniPadding).attr("cy",t().state.padding+t().state.sizeUnit+t().state.miniPadding),e.append("circle").attr("class","end-state-inner").attr("r",t().state.sizeUnit).attr("cx",t().state.padding+t().state.sizeUnit+2).attr("cy",t().state.padding+t().state.sizeUnit+2)),q=(e,i)=>{let o=t().state.forkWidth,c=t().state.forkHeight;if(i.parentId){let s=o;o=c,c=s}return e.append("rect").style("stroke","black").style("fill","black").attr("width",o).attr("height",c).attr("x",t().state.padding).attr("y",t().state.padding)},Z=(e,i,o,c)=>{let s=0;const g=c.append("text");g.style("text-anchor","start"),g.attr("class","noteText");let p=e.replace(/\r\n/g,"
                        ");p=p.replace(/\n/g,"
                        ");const a=p.split(T.lineBreakRegex);let r=1.25*t().state.noteMargin;for(const y of a){const x=y.trim();if(x.length>0){const d=g.append("tspan");if(d.text(x),r===0){const l=d.node().getBBox();r+=l.height}s+=r,d.attr("x",i+t().state.noteMargin),d.attr("y",o+s+1.25*t().state.noteMargin)}}return{textWidth:g.node().getBBox().width,textHeight:s}},j=(e,i)=>{i.attr("class","state-note");const o=i.append("rect").attr("x",0).attr("y",t().state.padding),c=i.append("g"),{textWidth:s,textHeight:g}=Z(e,0,0,c);return o.attr("height",g+2*t().state.noteMargin),o.attr("width",s+t().state.noteMargin*2),o},L=function(e,i){const o=i.id,c={id:o,label:i.id,width:0,height:0},s=e.append("g").attr("id",o).attr("class","stateGroup");i.type==="start"&&O(s),i.type==="end"&&_(s),(i.type==="fork"||i.type==="join")&&q(s,i),i.type==="note"&&j(i.note.text,s),i.type==="divider"&&X(s),i.type==="default"&&i.descriptions.length===0&&J(s,i),i.type==="default"&&i.descriptions.length>0&&Y(s,i);const g=s.node().getBBox();return c.width=g.width+2*t().state.padding,c.height=g.height+2*t().state.padding,c};let G=0;const K=function(e,i,o){const c=function(r){switch(r){case N.relationType.AGGREGATION:return"aggregation";case N.relationType.EXTENSION:return"extension";case N.relationType.COMPOSITION:return"composition";case N.relationType.DEPENDENCY:return"dependency"}};i.points=i.points.filter(r=>!Number.isNaN(r.y));const s=i.points,g=$().x(function(r){return r.x}).y(function(r){return r.y}).curve(v),p=e.append("path").attr("d",g(s)).attr("id","edge"+G).attr("class","transition");let a="";if(t().state.arrowMarkerAbsolute&&(a=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,a=a.replace(/\(/g,"\\("),a=a.replace(/\)/g,"\\)")),p.attr("marker-end","url("+a+"#"+c(N.relationType.DEPENDENCY)+"End)"),o.title!==void 0){const r=e.append("g").attr("class","stateLabel"),{x:y,y:x}=U.calcLabelPosition(i.points),d=T.getRows(o.title);let l=0;const m=[];let w=0,E=0;for(let u=0;u<=d.length;u++){const h=r.append("text").attr("text-anchor","middle").text(d[u]).attr("x",y).attr("y",x+l),f=h.node().getBBox();w=Math.max(w,f.width),E=Math.min(E,f.x),b.info(f.x,y,x+l),l===0&&(l=h.node().getBBox().height,b.info("Title height",l,x)),m.push(h)}let k=l*d.length;if(d.length>1){const u=(d.length-1)*l*.5;m.forEach((h,f)=>h.attr("y",x+f*l-u)),k=l*d.length}const n=r.node().getBBox();r.insert("rect",":first-child").attr("class","box").attr("x",y-w/2-t().state.padding/2).attr("y",x-k/2-t().state.padding/2-3.5).attr("width",w+t().state.padding).attr("height",k+t().state.padding),b.info(n)}G++};let B;const z={},Q=function(){},V=function(e){e.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},D=function(e,i,o,c){B=t().state;const s=t().securityLevel;let g;s==="sandbox"&&(g=H("#i"+i));const p=s==="sandbox"?H(g.nodes()[0].contentDocument.body):H("body"),a=s==="sandbox"?g.nodes()[0].contentDocument:document;b.debug("Rendering diagram "+e);const r=p.select(`[id='${i}']`);V(r);const y=c.db.getRootDoc();A(y,r,void 0,!1,p,a,c);const x=B.padding,d=r.node().getBBox(),l=d.width+x*2,m=d.height+x*2,w=l*1.75;R(r,m,w,B.useMaxWidth),r.attr("viewBox",`${d.x-B.padding} ${d.y-B.padding} `+l+" "+m)},tt=e=>e?e.length*B.fontSizeFactor:1,A=(e,i,o,c,s,g,p)=>{const a=new C({compound:!0,multigraph:!0});let r,y=!0;for(r=0;r{const f=h.parentElement;let S=0,M=0;f&&(f.parentElement&&(S=f.parentElement.getBBox().width),M=parseInt(f.getAttribute("data-x-shift"),10),Number.isNaN(M)&&(M=0)),h.setAttribute("x1",0-M+8),h.setAttribute("x2",S-M-8)})):b.debug("No Node "+n+": "+JSON.stringify(a.node(n)))});let E=w.getBBox();a.edges().forEach(function(n){n!==void 0&&a.edge(n)!==void 0&&(b.debug("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(a.edge(n))),K(i,a.edge(n),a.edge(n).relation))}),E=w.getBBox();const k={id:o||"root",label:o||"root",width:0,height:0};return k.width=E.width+2*B.padding,k.height=E.height+2*B.padding,b.debug("Doc rendered",k,a),k},et={setConf:Q,draw:D},lt={parser:P,db:N,renderer:et,styles:W,init:e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute,N.clear()}};export{lt as diagram}; +import{p as P,d as N,s as W}from"./styles-d20c7d72-fXd0DLOZ.js";import{c as t,h as H,l as b,i as R,j as T,ap as v,z as U}from"./mermaid.core-Q3WVcjPF.js";import{G as C}from"./graph-yVkSecXb.js";import{l as F}from"./layout-2f_iGf4E.js";import{l as $}from"./line-3Gyevr9q.js";import"./app-UOvWaKji.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";const O=e=>e.append("circle").attr("class","start-state").attr("r",t().state.sizeUnit).attr("cx",t().state.padding+t().state.sizeUnit).attr("cy",t().state.padding+t().state.sizeUnit),X=e=>e.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",t().state.textHeight).attr("class","divider").attr("x2",t().state.textHeight*2).attr("y1",0).attr("y2",0),J=(e,i)=>{const o=e.append("text").attr("x",2*t().state.padding).attr("y",t().state.textHeight+2*t().state.padding).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.id),c=o.node().getBBox();return e.insert("rect",":first-child").attr("x",t().state.padding).attr("y",t().state.padding).attr("width",c.width+2*t().state.padding).attr("height",c.height+2*t().state.padding).attr("rx",t().state.radius),o},Y=(e,i)=>{const o=function(l,m,w){const E=l.append("tspan").attr("x",2*t().state.padding).text(m);w||E.attr("dy",t().state.textHeight)},s=e.append("text").attr("x",2*t().state.padding).attr("y",t().state.textHeight+1.3*t().state.padding).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.descriptions[0]).node().getBBox(),g=s.height,p=e.append("text").attr("x",t().state.padding).attr("y",g+t().state.padding*.4+t().state.dividerMargin+t().state.textHeight).attr("class","state-description");let a=!0,r=!0;i.descriptions.forEach(function(l){a||(o(p,l,r),r=!1),a=!1});const y=e.append("line").attr("x1",t().state.padding).attr("y1",t().state.padding+g+t().state.dividerMargin/2).attr("y2",t().state.padding+g+t().state.dividerMargin/2).attr("class","descr-divider"),x=p.node().getBBox(),d=Math.max(x.width,s.width);return y.attr("x2",d+3*t().state.padding),e.insert("rect",":first-child").attr("x",t().state.padding).attr("y",t().state.padding).attr("width",d+2*t().state.padding).attr("height",x.height+g+2*t().state.padding).attr("rx",t().state.radius),e},I=(e,i,o)=>{const c=t().state.padding,s=2*t().state.padding,g=e.node().getBBox(),p=g.width,a=g.x,r=e.append("text").attr("x",0).attr("y",t().state.titleShift).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.id),x=r.node().getBBox().width+s;let d=Math.max(x,p);d===p&&(d=d+s);let l;const m=e.node().getBBox();i.doc,l=a-c,x>p&&(l=(p-d)/2+c),Math.abs(a-m.x)p&&(l=a-(x-p)/2);const w=1-t().state.textHeight;return e.insert("rect",":first-child").attr("x",l).attr("y",w).attr("class",o?"alt-composit":"composit").attr("width",d).attr("height",m.height+t().state.textHeight+t().state.titleShift+1).attr("rx","0"),r.attr("x",l+c),x<=p&&r.attr("x",a+(d-s)/2-x/2+c),e.insert("rect",":first-child").attr("x",l).attr("y",t().state.titleShift-t().state.textHeight-t().state.padding).attr("width",d).attr("height",t().state.textHeight*3).attr("rx",t().state.radius),e.insert("rect",":first-child").attr("x",l).attr("y",t().state.titleShift-t().state.textHeight-t().state.padding).attr("width",d).attr("height",m.height+3+2*t().state.textHeight).attr("rx",t().state.radius),e},_=e=>(e.append("circle").attr("class","end-state-outer").attr("r",t().state.sizeUnit+t().state.miniPadding).attr("cx",t().state.padding+t().state.sizeUnit+t().state.miniPadding).attr("cy",t().state.padding+t().state.sizeUnit+t().state.miniPadding),e.append("circle").attr("class","end-state-inner").attr("r",t().state.sizeUnit).attr("cx",t().state.padding+t().state.sizeUnit+2).attr("cy",t().state.padding+t().state.sizeUnit+2)),q=(e,i)=>{let o=t().state.forkWidth,c=t().state.forkHeight;if(i.parentId){let s=o;o=c,c=s}return e.append("rect").style("stroke","black").style("fill","black").attr("width",o).attr("height",c).attr("x",t().state.padding).attr("y",t().state.padding)},Z=(e,i,o,c)=>{let s=0;const g=c.append("text");g.style("text-anchor","start"),g.attr("class","noteText");let p=e.replace(/\r\n/g,"
                        ");p=p.replace(/\n/g,"
                        ");const a=p.split(T.lineBreakRegex);let r=1.25*t().state.noteMargin;for(const y of a){const x=y.trim();if(x.length>0){const d=g.append("tspan");if(d.text(x),r===0){const l=d.node().getBBox();r+=l.height}s+=r,d.attr("x",i+t().state.noteMargin),d.attr("y",o+s+1.25*t().state.noteMargin)}}return{textWidth:g.node().getBBox().width,textHeight:s}},j=(e,i)=>{i.attr("class","state-note");const o=i.append("rect").attr("x",0).attr("y",t().state.padding),c=i.append("g"),{textWidth:s,textHeight:g}=Z(e,0,0,c);return o.attr("height",g+2*t().state.noteMargin),o.attr("width",s+t().state.noteMargin*2),o},L=function(e,i){const o=i.id,c={id:o,label:i.id,width:0,height:0},s=e.append("g").attr("id",o).attr("class","stateGroup");i.type==="start"&&O(s),i.type==="end"&&_(s),(i.type==="fork"||i.type==="join")&&q(s,i),i.type==="note"&&j(i.note.text,s),i.type==="divider"&&X(s),i.type==="default"&&i.descriptions.length===0&&J(s,i),i.type==="default"&&i.descriptions.length>0&&Y(s,i);const g=s.node().getBBox();return c.width=g.width+2*t().state.padding,c.height=g.height+2*t().state.padding,c};let G=0;const K=function(e,i,o){const c=function(r){switch(r){case N.relationType.AGGREGATION:return"aggregation";case N.relationType.EXTENSION:return"extension";case N.relationType.COMPOSITION:return"composition";case N.relationType.DEPENDENCY:return"dependency"}};i.points=i.points.filter(r=>!Number.isNaN(r.y));const s=i.points,g=$().x(function(r){return r.x}).y(function(r){return r.y}).curve(v),p=e.append("path").attr("d",g(s)).attr("id","edge"+G).attr("class","transition");let a="";if(t().state.arrowMarkerAbsolute&&(a=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,a=a.replace(/\(/g,"\\("),a=a.replace(/\)/g,"\\)")),p.attr("marker-end","url("+a+"#"+c(N.relationType.DEPENDENCY)+"End)"),o.title!==void 0){const r=e.append("g").attr("class","stateLabel"),{x:y,y:x}=U.calcLabelPosition(i.points),d=T.getRows(o.title);let l=0;const m=[];let w=0,E=0;for(let u=0;u<=d.length;u++){const h=r.append("text").attr("text-anchor","middle").text(d[u]).attr("x",y).attr("y",x+l),f=h.node().getBBox();w=Math.max(w,f.width),E=Math.min(E,f.x),b.info(f.x,y,x+l),l===0&&(l=h.node().getBBox().height,b.info("Title height",l,x)),m.push(h)}let k=l*d.length;if(d.length>1){const u=(d.length-1)*l*.5;m.forEach((h,f)=>h.attr("y",x+f*l-u)),k=l*d.length}const n=r.node().getBBox();r.insert("rect",":first-child").attr("class","box").attr("x",y-w/2-t().state.padding/2).attr("y",x-k/2-t().state.padding/2-3.5).attr("width",w+t().state.padding).attr("height",k+t().state.padding),b.info(n)}G++};let B;const z={},Q=function(){},V=function(e){e.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},D=function(e,i,o,c){B=t().state;const s=t().securityLevel;let g;s==="sandbox"&&(g=H("#i"+i));const p=s==="sandbox"?H(g.nodes()[0].contentDocument.body):H("body"),a=s==="sandbox"?g.nodes()[0].contentDocument:document;b.debug("Rendering diagram "+e);const r=p.select(`[id='${i}']`);V(r);const y=c.db.getRootDoc();A(y,r,void 0,!1,p,a,c);const x=B.padding,d=r.node().getBBox(),l=d.width+x*2,m=d.height+x*2,w=l*1.75;R(r,m,w,B.useMaxWidth),r.attr("viewBox",`${d.x-B.padding} ${d.y-B.padding} `+l+" "+m)},tt=e=>e?e.length*B.fontSizeFactor:1,A=(e,i,o,c,s,g,p)=>{const a=new C({compound:!0,multigraph:!0});let r,y=!0;for(r=0;r{const f=h.parentElement;let S=0,M=0;f&&(f.parentElement&&(S=f.parentElement.getBBox().width),M=parseInt(f.getAttribute("data-x-shift"),10),Number.isNaN(M)&&(M=0)),h.setAttribute("x1",0-M+8),h.setAttribute("x2",S-M-8)})):b.debug("No Node "+n+": "+JSON.stringify(a.node(n)))});let E=w.getBBox();a.edges().forEach(function(n){n!==void 0&&a.edge(n)!==void 0&&(b.debug("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(a.edge(n))),K(i,a.edge(n),a.edge(n).relation))}),E=w.getBBox();const k={id:o||"root",label:o||"root",width:0,height:0};return k.width=E.width+2*B.padding,k.height=E.height+2*B.padding,b.debug("Doc rendered",k,a),k},et={setConf:Q,draw:D},lt={parser:P,db:N,renderer:et,styles:W,init:e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute,N.clear()}};export{lt as diagram}; diff --git a/assets/stateDiagram-v2-9a9d610d-sZSBWe92.js b/assets/stateDiagram-v2-9a9d610d-Gp1zKQgn.js similarity index 90% rename from assets/stateDiagram-v2-9a9d610d-sZSBWe92.js rename to assets/stateDiagram-v2-9a9d610d-Gp1zKQgn.js index 03cab5fd4c..9898e14ec1 100644 --- a/assets/stateDiagram-v2-9a9d610d-sZSBWe92.js +++ b/assets/stateDiagram-v2-9a9d610d-Gp1zKQgn.js @@ -1 +1 @@ -import{p as J,d as B,s as Q,D as H,a as X,S as Z,b as F,c as I}from"./styles-d20c7d72-JW20WKkm.js";import{G as tt}from"./graph-cZfODKa1.js";import{l as E,c as g,h as x,z as et,i as ot,j as w}from"./mermaid.core-95b3ca__.js";import{r as st}from"./index-fc10efb0-knA-ZLJ0.js";import"./layout-konkdG3Z.js";import"./app-PDrbPfzp.js";import"./clone-jETecP85.js";import"./edges-d32062c0-iT1MEq_Y.js";import"./createText-6b48ae7d-9AoX5zU9.js";import"./line-_nnM_7ZX.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";const h="rect",C="rectWithTitle",nt="start",it="end",ct="divider",rt="roundedWithTitle",lt="note",at="noteGroup",_="statediagram",dt="state",Et=`${_}-${dt}`,U="transition",St="note",Tt="note-edge",pt=`${U} ${Tt}`,_t=`${_}-${St}`,ut="cluster",Dt=`${_}-${ut}`,bt="cluster-alt",ft=`${_}-${bt}`,V="parent",Y="note",At="state",N="----",ht=`${N}${Y}`,M=`${N}${V}`,m="fill:none",z="fill: #333",W="c",j="text",q="normal";let y={},d=0;const yt=function(t){const n=Object.keys(t);for(const e of n)t[e]},gt=function(t,n){return n.db.extract(n.db.getRootDocV2()),n.db.getClasses()};function $t(t){return t==null?"":t.classes?t.classes.join(" "):""}function R(t="",n=0,e="",i=N){const c=e!==null&&e.length>0?`${i}${e}`:"";return`${At}-${t}${c}-${n}`}const A=(t,n,e,i,c,r)=>{const o=e.id,u=$t(i[o]);if(o!=="root"){let T=h;e.start===!0&&(T=nt),e.start===!1&&(T=it),e.type!==H&&(T=e.type),y[o]||(y[o]={id:o,shape:T,description:w.sanitizeText(o,g()),classes:`${u} ${Et}`});const s=y[o];e.description&&(Array.isArray(s.description)?(s.shape=C,s.description.push(e.description)):s.description.length>0?(s.shape=C,s.description===o?s.description=[e.description]:s.description=[s.description,e.description]):(s.shape=h,s.description=e.description),s.description=w.sanitizeTextOrArray(s.description,g())),s.description.length===1&&s.shape===C&&(s.shape=h),!s.type&&e.doc&&(E.info("Setting cluster for ",o,G(e)),s.type="group",s.dir=G(e),s.shape=e.type===X?ct:rt,s.classes=s.classes+" "+Dt+" "+(r?ft:""));const p={labelStyle:"",shape:s.shape,labelText:s.description,classes:s.classes,style:"",id:o,dir:s.dir,domId:R(o,d),type:s.type,padding:15};if(p.centerLabel=!0,e.note){const l={labelStyle:"",shape:lt,labelText:e.note.text,classes:_t,style:"",id:o+ht+"-"+d,domId:R(o,d,Y),type:s.type,padding:15},a={labelStyle:"",shape:at,labelText:e.note.text,classes:s.classes,style:"",id:o+M,domId:R(o,d,V),type:"group",padding:0};d++;const D=o+M;t.setNode(D,a),t.setNode(l.id,l),t.setNode(o,p),t.setParent(o,D),t.setParent(l.id,D);let S=o,b=l.id;e.note.position==="left of"&&(S=l.id,b=o),t.setEdge(S,b,{arrowhead:"none",arrowType:"",style:m,labelStyle:"",classes:pt,arrowheadStyle:z,labelpos:W,labelType:j,thickness:q})}else t.setNode(o,p)}n&&n.id!=="root"&&(E.trace("Setting node ",o," to be child of its parent ",n.id),t.setParent(o,n.id)),e.doc&&(E.trace("Adding nodes children "),xt(t,e,e.doc,i,c,!r))},xt=(t,n,e,i,c,r)=>{E.trace("items",e),e.forEach(o=>{switch(o.stmt){case F:A(t,n,o,i,c,r);break;case H:A(t,n,o,i,c,r);break;case Z:{A(t,n,o.state1,i,c,r),A(t,n,o.state2,i,c,r);const u={id:"edge"+d,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:m,labelStyle:"",label:w.sanitizeText(o.description,g()),arrowheadStyle:z,labelpos:W,labelType:j,thickness:q,classes:U};t.setEdge(o.state1.id,o.state2.id,u,d),d++}break}})},G=(t,n=I)=>{let e=n;if(t.doc)for(let i=0;i{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,B.clear()}};export{Vt as diagram}; +import{p as J,d as B,s as Q,D as H,a as X,S as Z,b as F,c as I}from"./styles-d20c7d72-fXd0DLOZ.js";import{G as tt}from"./graph-yVkSecXb.js";import{l as E,c as g,h as x,z as et,i as ot,j as w}from"./mermaid.core-Q3WVcjPF.js";import{r as st}from"./index-fc10efb0-cfY4JypU.js";import"./layout-2f_iGf4E.js";import"./app-UOvWaKji.js";import"./clone-bRwIupqN.js";import"./edges-d32062c0-DdP-jtfh.js";import"./createText-6b48ae7d-yUX1YD6G.js";import"./line-3Gyevr9q.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";const h="rect",C="rectWithTitle",nt="start",it="end",ct="divider",rt="roundedWithTitle",lt="note",at="noteGroup",_="statediagram",dt="state",Et=`${_}-${dt}`,U="transition",St="note",Tt="note-edge",pt=`${U} ${Tt}`,_t=`${_}-${St}`,ut="cluster",Dt=`${_}-${ut}`,bt="cluster-alt",ft=`${_}-${bt}`,V="parent",Y="note",At="state",N="----",ht=`${N}${Y}`,M=`${N}${V}`,m="fill:none",z="fill: #333",W="c",j="text",q="normal";let y={},d=0;const yt=function(t){const n=Object.keys(t);for(const e of n)t[e]},gt=function(t,n){return n.db.extract(n.db.getRootDocV2()),n.db.getClasses()};function $t(t){return t==null?"":t.classes?t.classes.join(" "):""}function R(t="",n=0,e="",i=N){const c=e!==null&&e.length>0?`${i}${e}`:"";return`${At}-${t}${c}-${n}`}const A=(t,n,e,i,c,r)=>{const o=e.id,u=$t(i[o]);if(o!=="root"){let T=h;e.start===!0&&(T=nt),e.start===!1&&(T=it),e.type!==H&&(T=e.type),y[o]||(y[o]={id:o,shape:T,description:w.sanitizeText(o,g()),classes:`${u} ${Et}`});const s=y[o];e.description&&(Array.isArray(s.description)?(s.shape=C,s.description.push(e.description)):s.description.length>0?(s.shape=C,s.description===o?s.description=[e.description]:s.description=[s.description,e.description]):(s.shape=h,s.description=e.description),s.description=w.sanitizeTextOrArray(s.description,g())),s.description.length===1&&s.shape===C&&(s.shape=h),!s.type&&e.doc&&(E.info("Setting cluster for ",o,G(e)),s.type="group",s.dir=G(e),s.shape=e.type===X?ct:rt,s.classes=s.classes+" "+Dt+" "+(r?ft:""));const p={labelStyle:"",shape:s.shape,labelText:s.description,classes:s.classes,style:"",id:o,dir:s.dir,domId:R(o,d),type:s.type,padding:15};if(p.centerLabel=!0,e.note){const l={labelStyle:"",shape:lt,labelText:e.note.text,classes:_t,style:"",id:o+ht+"-"+d,domId:R(o,d,Y),type:s.type,padding:15},a={labelStyle:"",shape:at,labelText:e.note.text,classes:s.classes,style:"",id:o+M,domId:R(o,d,V),type:"group",padding:0};d++;const D=o+M;t.setNode(D,a),t.setNode(l.id,l),t.setNode(o,p),t.setParent(o,D),t.setParent(l.id,D);let S=o,b=l.id;e.note.position==="left of"&&(S=l.id,b=o),t.setEdge(S,b,{arrowhead:"none",arrowType:"",style:m,labelStyle:"",classes:pt,arrowheadStyle:z,labelpos:W,labelType:j,thickness:q})}else t.setNode(o,p)}n&&n.id!=="root"&&(E.trace("Setting node ",o," to be child of its parent ",n.id),t.setParent(o,n.id)),e.doc&&(E.trace("Adding nodes children "),xt(t,e,e.doc,i,c,!r))},xt=(t,n,e,i,c,r)=>{E.trace("items",e),e.forEach(o=>{switch(o.stmt){case F:A(t,n,o,i,c,r);break;case H:A(t,n,o,i,c,r);break;case Z:{A(t,n,o.state1,i,c,r),A(t,n,o.state2,i,c,r);const u={id:"edge"+d,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:m,labelStyle:"",label:w.sanitizeText(o.description,g()),arrowheadStyle:z,labelpos:W,labelType:j,thickness:q,classes:U};t.setEdge(o.state1.id,o.state2.id,u,d),d++}break}})},G=(t,n=I)=>{let e=n;if(t.doc)for(let i=0;i{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,B.clear()}};export{Vt as diagram}; diff --git a/assets/stats.html-oDAoa3xt.js b/assets/stats.html-Ev72Xnyf.js similarity index 97% rename from assets/stats.html-oDAoa3xt.js rename to assets/stats.html-Ev72Xnyf.js index 5c398762a9..b46d10317d 100644 --- a/assets/stats.html-oDAoa3xt.js +++ b/assets/stats.html-Ev72Xnyf.js @@ -1,4 +1,4 @@ -import{_ as a,r as s,o as n,c,a as o,b as t,d as r,w as l,e}from"./app-PDrbPfzp.js";const p={},d=e(`

                        Traffic Statistics

                        Used to configure traffic statistics for Xray.

                        StatsObject

                        The StatsObject corresponds to the stats item in the configuration file.

                        {
                        +import{_ as a,r as s,o as n,c,a as o,b as t,d as r,w as l,e}from"./app-UOvWaKji.js";const p={},d=e(`

                        Traffic Statistics

                        Used to configure traffic statistics for Xray.

                        StatsObject

                        The StatsObject corresponds to the stats item in the configuration file.

                        {
                           "stats": {}
                         }
                         

                        Currently, no parameters are required for traffic statistics, and internal statistics will be enabled as long as the StatsObject item exists.

                        `,6),f=e('

                        Retrieving Traffic Statistics

                        You can use the xray api command to retrieve traffic statistics.

                        The current traffic statistics are as follows:

                        • User Data

                          • user>>>[email]>>>traffic>>>uplink

                            The uplink traffic of a specific user, in bytes.

                          • user>>>[email]>>>traffic>>>downlink

                            The downlink traffic of a specific user, in bytes.

                        Tip

                        If the corresponding user does not have an email specified, statistics will not be enabled.

                        • Global Data

                          • inbound>>>[tag]>>>traffic>>>uplink

                            The uplink traffic of a specific inbound, in bytes.

                          • inbound>>>[tag]>>>traffic>>>downlink

                            The downlink traffic of a specific inbound, in bytes.

                          • outbound>>>[tag]>>>traffic>>>uplink

                            The uplink traffic of a specific outbound, in bytes.

                          • outbound>>>[tag]>>>traffic>>>downlink

                            The downlink traffic of a specific outbound, in bytes.

                        ',6);function g(u,h){const i=s("RouterLink");return n(),c("div",null,[d,o("p",null,[t("After statistics are enabled, you only need to enable the corresponding items in the "),r(i,{to:"/en/config/policy.html"},{default:l(()=>[t("Policy")]),_:1}),t(" to collect the corresponding data.")]),f])}const m=a(p,[["render",g],["__file","stats.html.vue"]]);export{m as default}; diff --git a/assets/stats.html-N9FgSeRj.js b/assets/stats.html-hOtiN8ks.js similarity index 97% rename from assets/stats.html-N9FgSeRj.js rename to assets/stats.html-hOtiN8ks.js index 8505d0b274..4c34aa2996 100644 --- a/assets/stats.html-N9FgSeRj.js +++ b/assets/stats.html-hOtiN8ks.js @@ -1,4 +1,4 @@ -import{_ as n,r as s,o,c,a as i,b as t,d as p,w as l,e as a}from"./app-PDrbPfzp.js";const d={},g=a(`

                        统计信息

                        用于配置 Xray 流量数据的统计。

                        StatsObject

                        StatsObject 对应配置文件的 stats 项。

                        {
                        +import{_ as n,r as s,o,c,a as i,b as t,d as p,w as l,e as a}from"./app-UOvWaKji.js";const d={},g=a(`

                        统计信息

                        用于配置 Xray 流量数据的统计。

                        StatsObject

                        StatsObject 对应配置文件的 stats 项。

                        {
                           "stats": {}
                         }
                         

                        目前统计信息不需要任何参数,只要 StatsObject 项存在,内部的统计即会开启。

                        `,6),u=a('

                        获取统计信息

                        可以用 xray api 的相关命令获取统计信息.

                        目前已有的统计信息如下:

                        • 用户数据

                          • user>>>[email]>>>traffic>>>uplink

                            特定用户的上行流量,单位字节。

                          • user>>>[email]>>>traffic>>>downlink

                            特定用户的下行流量,单位字节。

                        提示

                        如果对应用户没有指定 Email,则不会开启统计。

                        • 全局数据

                          • inbound>>>[tag]>>>traffic>>>uplink

                            特定 inbound 的上行流量,单位字节。

                          • inbound>>>[tag]>>>traffic>>>downlink

                            特定 inbound 的下行流量,单位字节。

                          • outbound>>>[tag]>>>traffic>>>uplink

                            特定 outbound 的上行流量,单位字节。

                          • outbound>>>[tag]>>>traffic>>>downlink

                            特定 outbound 的下行流量,单位字节。

                        ',6);function r(f,h){const e=s("RouterLink");return o(),c("div",null,[g,i("p",null,[t("开启了统计以后, 只需在 "),p(e,{to:"/config/policy.html"},{default:l(()=>[t("Policy")]),_:1}),t(" 中开启对应的项,就可以统计对应的数据。")]),u])}const m=n(d,[["render",r],["__file","stats.html.vue"]]);export{m as default}; diff --git a/assets/styles-3ed67cfa-FBozeukd.js b/assets/styles-3ed67cfa-xu8Odik1.js similarity index 98% rename from assets/styles-3ed67cfa-FBozeukd.js rename to assets/styles-3ed67cfa-xu8Odik1.js index 777eeac738..828c5afb50 100644 --- a/assets/styles-3ed67cfa-FBozeukd.js +++ b/assets/styles-3ed67cfa-xu8Odik1.js @@ -1,4 +1,4 @@ -import{G as R}from"./graph-cZfODKa1.js";import{ab as z,ac as F,ad as j,ae as U,a9 as H,p as A,l as g,q as K,c as S,j as G,r as q,t as E,o as L,h as C,z as W,u as X,af as J}from"./mermaid.core-95b3ca__.js";import{r as Q}from"./index-fc10efb0-knA-ZLJ0.js";import{c as Y}from"./channel-GQnHP4O7.js";function Z(e){return typeof e=="string"?new z([document.querySelectorAll(e)],[document.documentElement]):new z([j(e)],F)}function pe(e,l){return!!e.children(l).length}function be(e){return N(e.v)+":"+N(e.w)+":"+N(e.name)}var O=/:/g;function N(e){return e?String(e).replace(O,"\\:"):""}function ee(e,l){l&&e.attr("style",l)}function fe(e,l,c){l&&e.attr("class",l).attr("class",c+" "+e.attr("class"))}function ue(e,l){var c=l.graph();if(U(c)){var a=c.transition;if(H(a))return a(e)}return e}function te(e,l){var c=e.append("foreignObject").attr("width","100000"),a=c.append("xhtml:div");a.attr("xmlns","http://www.w3.org/1999/xhtml");var i=l.label;switch(typeof i){case"function":a.insert(i);break;case"object":a.insert(function(){return i});break;default:a.html(i)}ee(a,l.labelStyle),a.style("display","inline-block"),a.style("white-space","nowrap");var d=a.node().getBoundingClientRect();return c.attr("width",d.width).attr("height",d.height),c}const P={},re=function(e){const l=Object.keys(e);for(const c of l)P[c]=e[c]},V=async function(e,l,c,a,i,d){const u=a.select(`[id="${c}"]`),n=Object.keys(e);for(const p of n){const r=e[p];let y="default";r.classes.length>0&&(y=r.classes.join(" ")),y=y+" flowchart-label";const w=A(r.styles);let t=r.text!==void 0?r.text:r.id,s;if(g.info("vertex",r,r.labelType),r.labelType==="markdown")g.info("vertex",r,r.labelType);else if(K(S().flowchart.htmlLabels))s=te(u,{label:t}).node(),s.parentNode.removeChild(s);else{const k=i.createElementNS("http://www.w3.org/2000/svg","text");k.setAttribute("style",w.labelStyle.replace("color:","fill:"));const _=t.split(G.lineBreakRegex);for(const $ of _){const v=i.createElementNS("http://www.w3.org/2000/svg","tspan");v.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),v.setAttribute("dy","1em"),v.setAttribute("x","1"),v.textContent=$,k.appendChild(v)}s=k}let b=0,o="";switch(r.type){case"round":b=5,o="rect";break;case"square":o="rect";break;case"diamond":o="question";break;case"hexagon":o="hexagon";break;case"odd":o="rect_left_inv_arrow";break;case"lean_right":o="lean_right";break;case"lean_left":o="lean_left";break;case"trapezoid":o="trapezoid";break;case"inv_trapezoid":o="inv_trapezoid";break;case"odd_right":o="rect_left_inv_arrow";break;case"circle":o="circle";break;case"ellipse":o="ellipse";break;case"stadium":o="stadium";break;case"subroutine":o="subroutine";break;case"cylinder":o="cylinder";break;case"group":o="rect";break;case"doublecircle":o="doublecircle";break;default:o="rect"}const T=await q(t,S());l.setNode(r.id,{labelStyle:w.labelStyle,shape:o,labelText:T,labelType:r.labelType,rx:b,ry:b,class:y,style:w.style,id:r.id,link:r.link,linkTarget:r.linkTarget,tooltip:d.db.getTooltip(r.id)||"",domId:d.db.lookUpDomId(r.id),haveCallback:r.haveCallback,width:r.type==="group"?500:void 0,dir:r.dir,type:r.type,props:r.props,padding:S().flowchart.padding}),g.info("setNode",{labelStyle:w.labelStyle,labelType:r.labelType,shape:o,labelText:T,rx:b,ry:b,class:y,style:w.style,id:r.id,domId:d.db.lookUpDomId(r.id),width:r.type==="group"?500:void 0,type:r.type,dir:r.dir,props:r.props,padding:S().flowchart.padding})}},M=async function(e,l,c){g.info("abc78 edges = ",e);let a=0,i={},d,u;if(e.defaultStyle!==void 0){const n=A(e.defaultStyle);d=n.style,u=n.labelStyle}for(const n of e){a++;const p="L-"+n.start+"-"+n.end;i[p]===void 0?(i[p]=0,g.info("abc78 new entry",p,i[p])):(i[p]++,g.info("abc78 new entry",p,i[p]));let r=p+"-"+i[p];g.info("abc78 new link id to be used is",p,r,i[p]);const y="LS-"+n.start,w="LE-"+n.end,t={style:"",labelStyle:""};switch(t.minlen=n.length||1,n.type==="arrow_open"?t.arrowhead="none":t.arrowhead="normal",t.arrowTypeStart="arrow_open",t.arrowTypeEnd="arrow_open",n.type){case"double_arrow_cross":t.arrowTypeStart="arrow_cross";case"arrow_cross":t.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":t.arrowTypeStart="arrow_point";case"arrow_point":t.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":t.arrowTypeStart="arrow_circle";case"arrow_circle":t.arrowTypeEnd="arrow_circle";break}let s="",b="";switch(n.stroke){case"normal":s="fill:none;",d!==void 0&&(s=d),u!==void 0&&(b=u),t.thickness="normal",t.pattern="solid";break;case"dotted":t.thickness="normal",t.pattern="dotted",t.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":t.thickness="thick",t.pattern="solid",t.style="stroke-width: 3.5px;fill:none;";break;case"invisible":t.thickness="invisible",t.pattern="solid",t.style="stroke-width: 0;fill:none;";break}if(n.style!==void 0){const o=A(n.style);s=o.style,b=o.labelStyle}t.style=t.style+=s,t.labelStyle=t.labelStyle+=b,n.interpolate!==void 0?t.curve=E(n.interpolate,L):e.defaultInterpolate!==void 0?t.curve=E(e.defaultInterpolate,L):t.curve=E(P.curve,L),n.text===void 0?n.style!==void 0&&(t.arrowheadStyle="fill: #333"):(t.arrowheadStyle="fill: #333",t.labelpos="c"),t.labelType=n.labelType,t.label=await q(n.text.replace(G.lineBreakRegex,` +import{G as R}from"./graph-yVkSecXb.js";import{ab as z,ac as F,ad as j,ae as U,a9 as H,p as A,l as g,q as K,c as S,j as G,r as q,t as E,o as L,h as C,z as W,u as X,af as J}from"./mermaid.core-Q3WVcjPF.js";import{r as Q}from"./index-fc10efb0-cfY4JypU.js";import{c as Y}from"./channel-hMLbS6Zi.js";function Z(e){return typeof e=="string"?new z([document.querySelectorAll(e)],[document.documentElement]):new z([j(e)],F)}function pe(e,l){return!!e.children(l).length}function be(e){return N(e.v)+":"+N(e.w)+":"+N(e.name)}var O=/:/g;function N(e){return e?String(e).replace(O,"\\:"):""}function ee(e,l){l&&e.attr("style",l)}function fe(e,l,c){l&&e.attr("class",l).attr("class",c+" "+e.attr("class"))}function ue(e,l){var c=l.graph();if(U(c)){var a=c.transition;if(H(a))return a(e)}return e}function te(e,l){var c=e.append("foreignObject").attr("width","100000"),a=c.append("xhtml:div");a.attr("xmlns","http://www.w3.org/1999/xhtml");var i=l.label;switch(typeof i){case"function":a.insert(i);break;case"object":a.insert(function(){return i});break;default:a.html(i)}ee(a,l.labelStyle),a.style("display","inline-block"),a.style("white-space","nowrap");var d=a.node().getBoundingClientRect();return c.attr("width",d.width).attr("height",d.height),c}const P={},re=function(e){const l=Object.keys(e);for(const c of l)P[c]=e[c]},V=async function(e,l,c,a,i,d){const u=a.select(`[id="${c}"]`),n=Object.keys(e);for(const p of n){const r=e[p];let y="default";r.classes.length>0&&(y=r.classes.join(" ")),y=y+" flowchart-label";const w=A(r.styles);let t=r.text!==void 0?r.text:r.id,s;if(g.info("vertex",r,r.labelType),r.labelType==="markdown")g.info("vertex",r,r.labelType);else if(K(S().flowchart.htmlLabels))s=te(u,{label:t}).node(),s.parentNode.removeChild(s);else{const k=i.createElementNS("http://www.w3.org/2000/svg","text");k.setAttribute("style",w.labelStyle.replace("color:","fill:"));const _=t.split(G.lineBreakRegex);for(const $ of _){const v=i.createElementNS("http://www.w3.org/2000/svg","tspan");v.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),v.setAttribute("dy","1em"),v.setAttribute("x","1"),v.textContent=$,k.appendChild(v)}s=k}let b=0,o="";switch(r.type){case"round":b=5,o="rect";break;case"square":o="rect";break;case"diamond":o="question";break;case"hexagon":o="hexagon";break;case"odd":o="rect_left_inv_arrow";break;case"lean_right":o="lean_right";break;case"lean_left":o="lean_left";break;case"trapezoid":o="trapezoid";break;case"inv_trapezoid":o="inv_trapezoid";break;case"odd_right":o="rect_left_inv_arrow";break;case"circle":o="circle";break;case"ellipse":o="ellipse";break;case"stadium":o="stadium";break;case"subroutine":o="subroutine";break;case"cylinder":o="cylinder";break;case"group":o="rect";break;case"doublecircle":o="doublecircle";break;default:o="rect"}const T=await q(t,S());l.setNode(r.id,{labelStyle:w.labelStyle,shape:o,labelText:T,labelType:r.labelType,rx:b,ry:b,class:y,style:w.style,id:r.id,link:r.link,linkTarget:r.linkTarget,tooltip:d.db.getTooltip(r.id)||"",domId:d.db.lookUpDomId(r.id),haveCallback:r.haveCallback,width:r.type==="group"?500:void 0,dir:r.dir,type:r.type,props:r.props,padding:S().flowchart.padding}),g.info("setNode",{labelStyle:w.labelStyle,labelType:r.labelType,shape:o,labelText:T,rx:b,ry:b,class:y,style:w.style,id:r.id,domId:d.db.lookUpDomId(r.id),width:r.type==="group"?500:void 0,type:r.type,dir:r.dir,props:r.props,padding:S().flowchart.padding})}},M=async function(e,l,c){g.info("abc78 edges = ",e);let a=0,i={},d,u;if(e.defaultStyle!==void 0){const n=A(e.defaultStyle);d=n.style,u=n.labelStyle}for(const n of e){a++;const p="L-"+n.start+"-"+n.end;i[p]===void 0?(i[p]=0,g.info("abc78 new entry",p,i[p])):(i[p]++,g.info("abc78 new entry",p,i[p]));let r=p+"-"+i[p];g.info("abc78 new link id to be used is",p,r,i[p]);const y="LS-"+n.start,w="LE-"+n.end,t={style:"",labelStyle:""};switch(t.minlen=n.length||1,n.type==="arrow_open"?t.arrowhead="none":t.arrowhead="normal",t.arrowTypeStart="arrow_open",t.arrowTypeEnd="arrow_open",n.type){case"double_arrow_cross":t.arrowTypeStart="arrow_cross";case"arrow_cross":t.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":t.arrowTypeStart="arrow_point";case"arrow_point":t.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":t.arrowTypeStart="arrow_circle";case"arrow_circle":t.arrowTypeEnd="arrow_circle";break}let s="",b="";switch(n.stroke){case"normal":s="fill:none;",d!==void 0&&(s=d),u!==void 0&&(b=u),t.thickness="normal",t.pattern="solid";break;case"dotted":t.thickness="normal",t.pattern="dotted",t.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":t.thickness="thick",t.pattern="solid",t.style="stroke-width: 3.5px;fill:none;";break;case"invisible":t.thickness="invisible",t.pattern="solid",t.style="stroke-width: 0;fill:none;";break}if(n.style!==void 0){const o=A(n.style);s=o.style,b=o.labelStyle}t.style=t.style+=s,t.labelStyle=t.labelStyle+=b,n.interpolate!==void 0?t.curve=E(n.interpolate,L):e.defaultInterpolate!==void 0?t.curve=E(e.defaultInterpolate,L):t.curve=E(P.curve,L),n.text===void 0?n.style!==void 0&&(t.arrowheadStyle="fill: #333"):(t.arrowheadStyle="fill: #333",t.labelpos="c"),t.labelType=n.labelType,t.label=await q(n.text.replace(G.lineBreakRegex,` `),S()),n.style===void 0&&(t.style=t.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),t.labelStyle=t.labelStyle.replace("color:","fill:"),t.id=r,t.classes="flowchart-link "+y+" "+w,l.setEdge(n.start,n.end,t,a)}},le=function(e,l){return l.db.getClasses()},ae=async function(e,l,c,a){g.info("Drawing flowchart");let i=a.db.getDirection();i===void 0&&(i="TD");const{securityLevel:d,flowchart:u}=S(),n=u.nodeSpacing||50,p=u.rankSpacing||50;let r;d==="sandbox"&&(r=C("#i"+l));const y=d==="sandbox"?C(r.nodes()[0].contentDocument.body):C("body"),w=d==="sandbox"?r.nodes()[0].contentDocument:document,t=new R({multigraph:!0,compound:!0}).setGraph({rankdir:i,nodesep:n,ranksep:p,marginx:0,marginy:0}).setDefaultEdgeLabel(function(){return{}});let s;const b=a.db.getSubGraphs();g.info("Subgraphs - ",b);for(let f=b.length-1;f>=0;f--)s=b[f],g.info("Subgraph - ",s),a.db.addVertex(s.id,{text:s.title,type:s.labelType},"group",void 0,s.classes,s.dir);const o=a.db.getVertices(),T=a.db.getEdges();g.info("Edges",T);let k=0;for(k=b.length-1;k>=0;k--){s=b[k],Z("cluster").append("text");for(let f=0;f{const c=Y,a=c(e,"r"),i=c(e,"g"),d=c(e,"b");return J(a,i,d,l)},ne=e=>`.label { font-family: ${e.fontFamily}; color: ${e.nodeTextColor||e.textColor}; diff --git a/assets/styles-991ebdfc-vHdkyrCb.js b/assets/styles-991ebdfc-6jesWoI2.js similarity index 99% rename from assets/styles-991ebdfc-vHdkyrCb.js rename to assets/styles-991ebdfc-6jesWoI2.js index a7ec556aa9..f42bb1b95a 100644 --- a/assets/styles-991ebdfc-vHdkyrCb.js +++ b/assets/styles-991ebdfc-6jesWoI2.js @@ -1,4 +1,4 @@ -import{s as ut,g as rt,a as at,b as lt,c as F,x as ct,y as ot,j as v,A as ht,l as At,z as We,h as z,d as pt,as as Re}from"./mermaid.core-95b3ca__.js";var Ve=function(){var e=function(x,u,a,h){for(a=a||{},h=x.length;h--;a[x[h]]=u);return a},i=[1,17],r=[1,18],l=[1,19],o=[1,39],A=[1,40],g=[1,25],D=[1,23],B=[1,24],_=[1,31],fe=[1,32],de=[1,33],Ee=[1,34],Ce=[1,35],me=[1,36],be=[1,26],ge=[1,27],ke=[1,28],Te=[1,29],d=[1,43],Fe=[1,30],E=[1,42],C=[1,44],m=[1,41],k=[1,45],ye=[1,9],c=[1,8,9],Y=[1,56],j=[1,57],Q=[1,58],X=[1,59],H=[1,60],De=[1,61],Be=[1,62],W=[1,8,9,39],Ge=[1,74],M=[1,8,9,12,13,21,37,39,42,59,60,61,62,63,64,65,70,72],q=[1,8,9,12,13,19,21,37,39,42,46,59,60,61,62,63,64,65,70,72,74,80,95,97,98],J=[13,74,80,95,97,98],G=[13,64,65,74,80,95,97,98],Ue=[13,59,60,61,62,63,74,80,95,97,98],_e=[1,93],Z=[1,110],$=[1,108],ee=[1,102],te=[1,103],se=[1,104],ie=[1,105],ne=[1,106],ue=[1,107],re=[1,109],Se=[1,8,9,37,39,42],ae=[1,8,9,21],ze=[1,8,9,78],S=[1,8,9,21,73,74,78,80,81,82,83,84,85],Ne={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,className:17,classLiteralName:18,GENERICTYPE:19,relationStatement:20,LABEL:21,namespaceStatement:22,classStatement:23,memberStatement:24,annotationStatement:25,clickStatement:26,styleStatement:27,cssClassStatement:28,noteStatement:29,direction:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,namespaceIdentifier:36,STRUCT_START:37,classStatements:38,STRUCT_STOP:39,NAMESPACE:40,classIdentifier:41,STYLE_SEPARATOR:42,members:43,CLASS:44,ANNOTATION_START:45,ANNOTATION_END:46,MEMBER:47,SEPARATOR:48,relation:49,NOTE_FOR:50,noteText:51,NOTE:52,direction_tb:53,direction_bt:54,direction_rl:55,direction_lr:56,relationType:57,lineType:58,AGGREGATION:59,EXTENSION:60,COMPOSITION:61,DEPENDENCY:62,LOLLIPOP:63,LINE:64,DOTTED_LINE:65,CALLBACK:66,LINK:67,LINK_TARGET:68,CLICK:69,CALLBACK_NAME:70,CALLBACK_ARGS:71,HREF:72,STYLE:73,ALPHA:74,stylesOpt:75,CSSCLASS:76,style:77,COMMA:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,commentToken:86,textToken:87,graphCodeTokens:88,textNoTagsToken:89,TAGSTART:90,TAGEND:91,"==":92,"--":93,DEFAULT:94,MINUS:95,keywords:96,UNICODE_TEXT:97,BQUOTE_STR:98,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",19:"GENERICTYPE",21:"LABEL",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",37:"STRUCT_START",39:"STRUCT_STOP",40:"NAMESPACE",42:"STYLE_SEPARATOR",44:"CLASS",45:"ANNOTATION_START",46:"ANNOTATION_END",47:"MEMBER",48:"SEPARATOR",50:"NOTE_FOR",52:"NOTE",53:"direction_tb",54:"direction_bt",55:"direction_rl",56:"direction_lr",59:"AGGREGATION",60:"EXTENSION",61:"COMPOSITION",62:"DEPENDENCY",63:"LOLLIPOP",64:"LINE",65:"DOTTED_LINE",66:"CALLBACK",67:"LINK",68:"LINK_TARGET",69:"CLICK",70:"CALLBACK_NAME",71:"CALLBACK_ARGS",72:"HREF",73:"STYLE",74:"ALPHA",76:"CSSCLASS",78:"COMMA",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",88:"graphCodeTokens",90:"TAGSTART",91:"TAGEND",92:"==",93:"--",94:"DEFAULT",95:"MINUS",96:"keywords",97:"UNICODE_TEXT",98:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,2],[17,1],[17,1],[17,2],[17,2],[17,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[22,4],[22,5],[36,2],[38,1],[38,2],[38,3],[23,1],[23,3],[23,4],[23,6],[41,2],[41,3],[25,4],[43,1],[43,2],[24,1],[24,2],[24,1],[24,1],[20,3],[20,4],[20,4],[20,5],[29,3],[29,2],[30,1],[30,1],[30,1],[30,1],[49,3],[49,2],[49,2],[49,1],[57,1],[57,1],[57,1],[57,1],[57,1],[58,1],[58,1],[26,3],[26,4],[26,3],[26,4],[26,4],[26,5],[26,3],[26,4],[26,4],[26,5],[26,4],[26,5],[26,5],[26,6],[27,3],[28,3],[75,1],[75,3],[77,1],[77,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[86,1],[86,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[89,1],[89,1],[89,1],[89,1],[16,1],[16,1],[16,1],[16,1],[18,1],[51,1]],performAction:function(u,a,h,n,f,t,U){var s=t.length-1;switch(f){case 8:this.$=t[s-1];break;case 9:case 11:case 12:this.$=t[s];break;case 10:case 13:this.$=t[s-1]+t[s];break;case 14:case 15:this.$=t[s-1]+"~"+t[s]+"~";break;case 16:n.addRelation(t[s]);break;case 17:t[s-1].title=n.cleanupLabel(t[s]),n.addRelation(t[s-1]);break;case 27:this.$=t[s].trim(),n.setAccTitle(this.$);break;case 28:case 29:this.$=t[s].trim(),n.setAccDescription(this.$);break;case 30:n.addClassesToNamespace(t[s-3],t[s-1]);break;case 31:n.addClassesToNamespace(t[s-4],t[s-1]);break;case 32:this.$=t[s],n.addNamespace(t[s]);break;case 33:this.$=[t[s]];break;case 34:this.$=[t[s-1]];break;case 35:t[s].unshift(t[s-2]),this.$=t[s];break;case 37:n.setCssClass(t[s-2],t[s]);break;case 38:n.addMembers(t[s-3],t[s-1]);break;case 39:n.setCssClass(t[s-5],t[s-3]),n.addMembers(t[s-5],t[s-1]);break;case 40:this.$=t[s],n.addClass(t[s]);break;case 41:this.$=t[s-1],n.addClass(t[s-1]),n.setClassLabel(t[s-1],t[s]);break;case 42:n.addAnnotation(t[s],t[s-2]);break;case 43:this.$=[t[s]];break;case 44:t[s].push(t[s-1]),this.$=t[s];break;case 45:break;case 46:n.addMember(t[s-1],n.cleanupLabel(t[s]));break;case 47:break;case 48:break;case 49:this.$={id1:t[s-2],id2:t[s],relation:t[s-1],relationTitle1:"none",relationTitle2:"none"};break;case 50:this.$={id1:t[s-3],id2:t[s],relation:t[s-1],relationTitle1:t[s-2],relationTitle2:"none"};break;case 51:this.$={id1:t[s-3],id2:t[s],relation:t[s-2],relationTitle1:"none",relationTitle2:t[s-1]};break;case 52:this.$={id1:t[s-4],id2:t[s],relation:t[s-2],relationTitle1:t[s-3],relationTitle2:t[s-1]};break;case 53:n.addNote(t[s],t[s-1]);break;case 54:n.addNote(t[s]);break;case 55:n.setDirection("TB");break;case 56:n.setDirection("BT");break;case 57:n.setDirection("RL");break;case 58:n.setDirection("LR");break;case 59:this.$={type1:t[s-2],type2:t[s],lineType:t[s-1]};break;case 60:this.$={type1:"none",type2:t[s],lineType:t[s-1]};break;case 61:this.$={type1:t[s-1],type2:"none",lineType:t[s]};break;case 62:this.$={type1:"none",type2:"none",lineType:t[s]};break;case 63:this.$=n.relationType.AGGREGATION;break;case 64:this.$=n.relationType.EXTENSION;break;case 65:this.$=n.relationType.COMPOSITION;break;case 66:this.$=n.relationType.DEPENDENCY;break;case 67:this.$=n.relationType.LOLLIPOP;break;case 68:this.$=n.lineType.LINE;break;case 69:this.$=n.lineType.DOTTED_LINE;break;case 70:case 76:this.$=t[s-2],n.setClickEvent(t[s-1],t[s]);break;case 71:case 77:this.$=t[s-3],n.setClickEvent(t[s-2],t[s-1]),n.setTooltip(t[s-2],t[s]);break;case 72:this.$=t[s-2],n.setLink(t[s-1],t[s]);break;case 73:this.$=t[s-3],n.setLink(t[s-2],t[s-1],t[s]);break;case 74:this.$=t[s-3],n.setLink(t[s-2],t[s-1]),n.setTooltip(t[s-2],t[s]);break;case 75:this.$=t[s-4],n.setLink(t[s-3],t[s-2],t[s]),n.setTooltip(t[s-3],t[s-1]);break;case 78:this.$=t[s-3],n.setClickEvent(t[s-2],t[s-1],t[s]);break;case 79:this.$=t[s-4],n.setClickEvent(t[s-3],t[s-2],t[s-1]),n.setTooltip(t[s-3],t[s]);break;case 80:this.$=t[s-3],n.setLink(t[s-2],t[s]);break;case 81:this.$=t[s-4],n.setLink(t[s-3],t[s-1],t[s]);break;case 82:this.$=t[s-4],n.setLink(t[s-3],t[s-1]),n.setTooltip(t[s-3],t[s]);break;case 83:this.$=t[s-5],n.setLink(t[s-4],t[s-2],t[s]),n.setTooltip(t[s-4],t[s-1]);break;case 84:this.$=t[s-2],n.setCssStyle(t[s-1],t[s]);break;case 85:n.setCssClass(t[s-1],t[s]);break;case 86:this.$=[t[s]];break;case 87:t[s-2].push(t[s]),this.$=t[s-2];break;case 89:this.$=t[s-1]+t[s];break}},table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:37,17:20,18:38,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,31:i,33:r,35:l,36:21,40:o,41:22,44:A,45:g,47:D,48:B,50:_,52:fe,53:de,54:Ee,55:Ce,56:me,66:be,67:ge,69:ke,73:Te,74:d,76:Fe,80:E,95:C,97:m,98:k},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},e(ye,[2,5],{8:[1,46]}),{8:[1,47]},e(c,[2,16],{21:[1,48]}),e(c,[2,18]),e(c,[2,19]),e(c,[2,20]),e(c,[2,21]),e(c,[2,22]),e(c,[2,23]),e(c,[2,24]),e(c,[2,25]),e(c,[2,26]),{32:[1,49]},{34:[1,50]},e(c,[2,29]),e(c,[2,45],{49:51,57:54,58:55,13:[1,52],21:[1,53],59:Y,60:j,61:Q,62:X,63:H,64:De,65:Be}),{37:[1,63]},e(W,[2,36],{37:[1,65],42:[1,64]}),e(c,[2,47]),e(c,[2,48]),{16:66,74:d,80:E,95:C,97:m},{16:37,17:67,18:38,74:d,80:E,95:C,97:m,98:k},{16:37,17:68,18:38,74:d,80:E,95:C,97:m,98:k},{16:37,17:69,18:38,74:d,80:E,95:C,97:m,98:k},{74:[1,70]},{13:[1,71]},{16:37,17:72,18:38,74:d,80:E,95:C,97:m,98:k},{13:Ge,51:73},e(c,[2,55]),e(c,[2,56]),e(c,[2,57]),e(c,[2,58]),e(M,[2,11],{16:37,18:38,17:75,19:[1,76],74:d,80:E,95:C,97:m,98:k}),e(M,[2,12],{19:[1,77]}),{15:78,16:79,74:d,80:E,95:C,97:m},{16:37,17:80,18:38,74:d,80:E,95:C,97:m,98:k},e(q,[2,112]),e(q,[2,113]),e(q,[2,114]),e(q,[2,115]),e([1,8,9,12,13,19,21,37,39,42,59,60,61,62,63,64,65,70,72],[2,116]),e(ye,[2,6],{10:5,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,17:20,36:21,41:22,16:37,18:38,5:81,31:i,33:r,35:l,40:o,44:A,45:g,47:D,48:B,50:_,52:fe,53:de,54:Ee,55:Ce,56:me,66:be,67:ge,69:ke,73:Te,74:d,76:Fe,80:E,95:C,97:m,98:k}),{5:82,10:5,16:37,17:20,18:38,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,31:i,33:r,35:l,36:21,40:o,41:22,44:A,45:g,47:D,48:B,50:_,52:fe,53:de,54:Ee,55:Ce,56:me,66:be,67:ge,69:ke,73:Te,74:d,76:Fe,80:E,95:C,97:m,98:k},e(c,[2,17]),e(c,[2,27]),e(c,[2,28]),{13:[1,84],16:37,17:83,18:38,74:d,80:E,95:C,97:m,98:k},{49:85,57:54,58:55,59:Y,60:j,61:Q,62:X,63:H,64:De,65:Be},e(c,[2,46]),{58:86,64:De,65:Be},e(J,[2,62],{57:87,59:Y,60:j,61:Q,62:X,63:H}),e(G,[2,63]),e(G,[2,64]),e(G,[2,65]),e(G,[2,66]),e(G,[2,67]),e(Ue,[2,68]),e(Ue,[2,69]),{8:[1,89],23:90,38:88,41:22,44:A},{16:91,74:d,80:E,95:C,97:m},{43:92,47:_e},{46:[1,94]},{13:[1,95]},{13:[1,96]},{70:[1,97],72:[1,98]},{21:Z,73:$,74:ee,75:99,77:100,79:101,80:te,81:se,82:ie,83:ne,84:ue,85:re},{74:[1,111]},{13:Ge,51:112},e(c,[2,54]),e(c,[2,117]),e(M,[2,13]),e(M,[2,14]),e(M,[2,15]),{37:[2,32]},{15:113,16:79,37:[2,9],74:d,80:E,95:C,97:m},e(Se,[2,40],{11:114,12:[1,115]}),e(ye,[2,7]),{9:[1,116]},e(ae,[2,49]),{16:37,17:117,18:38,74:d,80:E,95:C,97:m,98:k},{13:[1,119],16:37,17:118,18:38,74:d,80:E,95:C,97:m,98:k},e(J,[2,61],{57:120,59:Y,60:j,61:Q,62:X,63:H}),e(J,[2,60]),{39:[1,121]},{23:90,38:122,41:22,44:A},{8:[1,123],39:[2,33]},e(W,[2,37],{37:[1,124]}),{39:[1,125]},{39:[2,43],43:126,47:_e},{16:37,17:127,18:38,74:d,80:E,95:C,97:m,98:k},e(c,[2,70],{13:[1,128]}),e(c,[2,72],{13:[1,130],68:[1,129]}),e(c,[2,76],{13:[1,131],71:[1,132]}),{13:[1,133]},e(c,[2,84],{78:[1,134]}),e(ze,[2,86],{79:135,21:Z,73:$,74:ee,80:te,81:se,82:ie,83:ne,84:ue,85:re}),e(S,[2,88]),e(S,[2,90]),e(S,[2,91]),e(S,[2,92]),e(S,[2,93]),e(S,[2,94]),e(S,[2,95]),e(S,[2,96]),e(S,[2,97]),e(S,[2,98]),e(c,[2,85]),e(c,[2,53]),{37:[2,10]},e(Se,[2,41]),{13:[1,136]},{1:[2,4]},e(ae,[2,51]),e(ae,[2,50]),{16:37,17:137,18:38,74:d,80:E,95:C,97:m,98:k},e(J,[2,59]),e(c,[2,30]),{39:[1,138]},{23:90,38:139,39:[2,34],41:22,44:A},{43:140,47:_e},e(W,[2,38]),{39:[2,44]},e(c,[2,42]),e(c,[2,71]),e(c,[2,73]),e(c,[2,74],{68:[1,141]}),e(c,[2,77]),e(c,[2,78],{13:[1,142]}),e(c,[2,80],{13:[1,144],68:[1,143]}),{21:Z,73:$,74:ee,77:145,79:101,80:te,81:se,82:ie,83:ne,84:ue,85:re},e(S,[2,89]),{14:[1,146]},e(ae,[2,52]),e(c,[2,31]),{39:[2,35]},{39:[1,147]},e(c,[2,75]),e(c,[2,79]),e(c,[2,81]),e(c,[2,82],{68:[1,148]}),e(ze,[2,87],{79:135,21:Z,73:$,74:ee,80:te,81:se,82:ie,83:ne,84:ue,85:re}),e(Se,[2,8]),e(W,[2,39]),e(c,[2,83])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],78:[2,32],113:[2,10],116:[2,4],126:[2,44],139:[2,35]},parseError:function(u,a){if(a.recoverable)this.trace(u);else{var h=new Error(u);throw h.hash=a,h}},parse:function(u){var a=this,h=[0],n=[],f=[null],t=[],U=this.table,s="",le=0,Ke=0,tt=2,Ye=1,st=t.slice.call(arguments,1),b=Object.create(this.lexer),I={yy:{}};for(var ve in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ve)&&(I.yy[ve]=this.yy[ve]);b.setInput(u,I.yy),I.yy.lexer=b,I.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var xe=b.yylloc;t.push(xe);var it=b.options&&b.options.ranges;typeof I.yy.parseError=="function"?this.parseError=I.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function nt(){var L;return L=n.pop()||b.lex()||Ye,typeof L!="number"&&(L instanceof Array&&(n=L,L=n.pop()),L=a.symbols_[L]||L),L}for(var T,R,y,Oe,P={},ce,N,je,oe;;){if(R=h[h.length-1],this.defaultActions[R]?y=this.defaultActions[R]:((T===null||typeof T>"u")&&(T=nt()),y=U[R]&&U[R][T]),typeof y>"u"||!y.length||!y[0]){var Ie="";oe=[];for(ce in U[R])this.terminals_[ce]&&ce>tt&&oe.push("'"+this.terminals_[ce]+"'");b.showPosition?Ie="Parse error on line "+(le+1)+`: +import{s as ut,g as rt,a as at,b as lt,c as F,x as ct,y as ot,j as v,A as ht,l as At,z as We,h as z,d as pt,as as Re}from"./mermaid.core-Q3WVcjPF.js";var Ve=function(){var e=function(x,u,a,h){for(a=a||{},h=x.length;h--;a[x[h]]=u);return a},i=[1,17],r=[1,18],l=[1,19],o=[1,39],A=[1,40],g=[1,25],D=[1,23],B=[1,24],_=[1,31],fe=[1,32],de=[1,33],Ee=[1,34],Ce=[1,35],me=[1,36],be=[1,26],ge=[1,27],ke=[1,28],Te=[1,29],d=[1,43],Fe=[1,30],E=[1,42],C=[1,44],m=[1,41],k=[1,45],ye=[1,9],c=[1,8,9],Y=[1,56],j=[1,57],Q=[1,58],X=[1,59],H=[1,60],De=[1,61],Be=[1,62],W=[1,8,9,39],Ge=[1,74],M=[1,8,9,12,13,21,37,39,42,59,60,61,62,63,64,65,70,72],q=[1,8,9,12,13,19,21,37,39,42,46,59,60,61,62,63,64,65,70,72,74,80,95,97,98],J=[13,74,80,95,97,98],G=[13,64,65,74,80,95,97,98],Ue=[13,59,60,61,62,63,74,80,95,97,98],_e=[1,93],Z=[1,110],$=[1,108],ee=[1,102],te=[1,103],se=[1,104],ie=[1,105],ne=[1,106],ue=[1,107],re=[1,109],Se=[1,8,9,37,39,42],ae=[1,8,9,21],ze=[1,8,9,78],S=[1,8,9,21,73,74,78,80,81,82,83,84,85],Ne={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,className:17,classLiteralName:18,GENERICTYPE:19,relationStatement:20,LABEL:21,namespaceStatement:22,classStatement:23,memberStatement:24,annotationStatement:25,clickStatement:26,styleStatement:27,cssClassStatement:28,noteStatement:29,direction:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,namespaceIdentifier:36,STRUCT_START:37,classStatements:38,STRUCT_STOP:39,NAMESPACE:40,classIdentifier:41,STYLE_SEPARATOR:42,members:43,CLASS:44,ANNOTATION_START:45,ANNOTATION_END:46,MEMBER:47,SEPARATOR:48,relation:49,NOTE_FOR:50,noteText:51,NOTE:52,direction_tb:53,direction_bt:54,direction_rl:55,direction_lr:56,relationType:57,lineType:58,AGGREGATION:59,EXTENSION:60,COMPOSITION:61,DEPENDENCY:62,LOLLIPOP:63,LINE:64,DOTTED_LINE:65,CALLBACK:66,LINK:67,LINK_TARGET:68,CLICK:69,CALLBACK_NAME:70,CALLBACK_ARGS:71,HREF:72,STYLE:73,ALPHA:74,stylesOpt:75,CSSCLASS:76,style:77,COMMA:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,commentToken:86,textToken:87,graphCodeTokens:88,textNoTagsToken:89,TAGSTART:90,TAGEND:91,"==":92,"--":93,DEFAULT:94,MINUS:95,keywords:96,UNICODE_TEXT:97,BQUOTE_STR:98,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",19:"GENERICTYPE",21:"LABEL",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",37:"STRUCT_START",39:"STRUCT_STOP",40:"NAMESPACE",42:"STYLE_SEPARATOR",44:"CLASS",45:"ANNOTATION_START",46:"ANNOTATION_END",47:"MEMBER",48:"SEPARATOR",50:"NOTE_FOR",52:"NOTE",53:"direction_tb",54:"direction_bt",55:"direction_rl",56:"direction_lr",59:"AGGREGATION",60:"EXTENSION",61:"COMPOSITION",62:"DEPENDENCY",63:"LOLLIPOP",64:"LINE",65:"DOTTED_LINE",66:"CALLBACK",67:"LINK",68:"LINK_TARGET",69:"CLICK",70:"CALLBACK_NAME",71:"CALLBACK_ARGS",72:"HREF",73:"STYLE",74:"ALPHA",76:"CSSCLASS",78:"COMMA",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",88:"graphCodeTokens",90:"TAGSTART",91:"TAGEND",92:"==",93:"--",94:"DEFAULT",95:"MINUS",96:"keywords",97:"UNICODE_TEXT",98:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,2],[17,1],[17,1],[17,2],[17,2],[17,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[22,4],[22,5],[36,2],[38,1],[38,2],[38,3],[23,1],[23,3],[23,4],[23,6],[41,2],[41,3],[25,4],[43,1],[43,2],[24,1],[24,2],[24,1],[24,1],[20,3],[20,4],[20,4],[20,5],[29,3],[29,2],[30,1],[30,1],[30,1],[30,1],[49,3],[49,2],[49,2],[49,1],[57,1],[57,1],[57,1],[57,1],[57,1],[58,1],[58,1],[26,3],[26,4],[26,3],[26,4],[26,4],[26,5],[26,3],[26,4],[26,4],[26,5],[26,4],[26,5],[26,5],[26,6],[27,3],[28,3],[75,1],[75,3],[77,1],[77,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[86,1],[86,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[87,1],[89,1],[89,1],[89,1],[89,1],[16,1],[16,1],[16,1],[16,1],[18,1],[51,1]],performAction:function(u,a,h,n,f,t,U){var s=t.length-1;switch(f){case 8:this.$=t[s-1];break;case 9:case 11:case 12:this.$=t[s];break;case 10:case 13:this.$=t[s-1]+t[s];break;case 14:case 15:this.$=t[s-1]+"~"+t[s]+"~";break;case 16:n.addRelation(t[s]);break;case 17:t[s-1].title=n.cleanupLabel(t[s]),n.addRelation(t[s-1]);break;case 27:this.$=t[s].trim(),n.setAccTitle(this.$);break;case 28:case 29:this.$=t[s].trim(),n.setAccDescription(this.$);break;case 30:n.addClassesToNamespace(t[s-3],t[s-1]);break;case 31:n.addClassesToNamespace(t[s-4],t[s-1]);break;case 32:this.$=t[s],n.addNamespace(t[s]);break;case 33:this.$=[t[s]];break;case 34:this.$=[t[s-1]];break;case 35:t[s].unshift(t[s-2]),this.$=t[s];break;case 37:n.setCssClass(t[s-2],t[s]);break;case 38:n.addMembers(t[s-3],t[s-1]);break;case 39:n.setCssClass(t[s-5],t[s-3]),n.addMembers(t[s-5],t[s-1]);break;case 40:this.$=t[s],n.addClass(t[s]);break;case 41:this.$=t[s-1],n.addClass(t[s-1]),n.setClassLabel(t[s-1],t[s]);break;case 42:n.addAnnotation(t[s],t[s-2]);break;case 43:this.$=[t[s]];break;case 44:t[s].push(t[s-1]),this.$=t[s];break;case 45:break;case 46:n.addMember(t[s-1],n.cleanupLabel(t[s]));break;case 47:break;case 48:break;case 49:this.$={id1:t[s-2],id2:t[s],relation:t[s-1],relationTitle1:"none",relationTitle2:"none"};break;case 50:this.$={id1:t[s-3],id2:t[s],relation:t[s-1],relationTitle1:t[s-2],relationTitle2:"none"};break;case 51:this.$={id1:t[s-3],id2:t[s],relation:t[s-2],relationTitle1:"none",relationTitle2:t[s-1]};break;case 52:this.$={id1:t[s-4],id2:t[s],relation:t[s-2],relationTitle1:t[s-3],relationTitle2:t[s-1]};break;case 53:n.addNote(t[s],t[s-1]);break;case 54:n.addNote(t[s]);break;case 55:n.setDirection("TB");break;case 56:n.setDirection("BT");break;case 57:n.setDirection("RL");break;case 58:n.setDirection("LR");break;case 59:this.$={type1:t[s-2],type2:t[s],lineType:t[s-1]};break;case 60:this.$={type1:"none",type2:t[s],lineType:t[s-1]};break;case 61:this.$={type1:t[s-1],type2:"none",lineType:t[s]};break;case 62:this.$={type1:"none",type2:"none",lineType:t[s]};break;case 63:this.$=n.relationType.AGGREGATION;break;case 64:this.$=n.relationType.EXTENSION;break;case 65:this.$=n.relationType.COMPOSITION;break;case 66:this.$=n.relationType.DEPENDENCY;break;case 67:this.$=n.relationType.LOLLIPOP;break;case 68:this.$=n.lineType.LINE;break;case 69:this.$=n.lineType.DOTTED_LINE;break;case 70:case 76:this.$=t[s-2],n.setClickEvent(t[s-1],t[s]);break;case 71:case 77:this.$=t[s-3],n.setClickEvent(t[s-2],t[s-1]),n.setTooltip(t[s-2],t[s]);break;case 72:this.$=t[s-2],n.setLink(t[s-1],t[s]);break;case 73:this.$=t[s-3],n.setLink(t[s-2],t[s-1],t[s]);break;case 74:this.$=t[s-3],n.setLink(t[s-2],t[s-1]),n.setTooltip(t[s-2],t[s]);break;case 75:this.$=t[s-4],n.setLink(t[s-3],t[s-2],t[s]),n.setTooltip(t[s-3],t[s-1]);break;case 78:this.$=t[s-3],n.setClickEvent(t[s-2],t[s-1],t[s]);break;case 79:this.$=t[s-4],n.setClickEvent(t[s-3],t[s-2],t[s-1]),n.setTooltip(t[s-3],t[s]);break;case 80:this.$=t[s-3],n.setLink(t[s-2],t[s]);break;case 81:this.$=t[s-4],n.setLink(t[s-3],t[s-1],t[s]);break;case 82:this.$=t[s-4],n.setLink(t[s-3],t[s-1]),n.setTooltip(t[s-3],t[s]);break;case 83:this.$=t[s-5],n.setLink(t[s-4],t[s-2],t[s]),n.setTooltip(t[s-4],t[s-1]);break;case 84:this.$=t[s-2],n.setCssStyle(t[s-1],t[s]);break;case 85:n.setCssClass(t[s-1],t[s]);break;case 86:this.$=[t[s]];break;case 87:t[s-2].push(t[s]),this.$=t[s-2];break;case 89:this.$=t[s-1]+t[s];break}},table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:37,17:20,18:38,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,31:i,33:r,35:l,36:21,40:o,41:22,44:A,45:g,47:D,48:B,50:_,52:fe,53:de,54:Ee,55:Ce,56:me,66:be,67:ge,69:ke,73:Te,74:d,76:Fe,80:E,95:C,97:m,98:k},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},e(ye,[2,5],{8:[1,46]}),{8:[1,47]},e(c,[2,16],{21:[1,48]}),e(c,[2,18]),e(c,[2,19]),e(c,[2,20]),e(c,[2,21]),e(c,[2,22]),e(c,[2,23]),e(c,[2,24]),e(c,[2,25]),e(c,[2,26]),{32:[1,49]},{34:[1,50]},e(c,[2,29]),e(c,[2,45],{49:51,57:54,58:55,13:[1,52],21:[1,53],59:Y,60:j,61:Q,62:X,63:H,64:De,65:Be}),{37:[1,63]},e(W,[2,36],{37:[1,65],42:[1,64]}),e(c,[2,47]),e(c,[2,48]),{16:66,74:d,80:E,95:C,97:m},{16:37,17:67,18:38,74:d,80:E,95:C,97:m,98:k},{16:37,17:68,18:38,74:d,80:E,95:C,97:m,98:k},{16:37,17:69,18:38,74:d,80:E,95:C,97:m,98:k},{74:[1,70]},{13:[1,71]},{16:37,17:72,18:38,74:d,80:E,95:C,97:m,98:k},{13:Ge,51:73},e(c,[2,55]),e(c,[2,56]),e(c,[2,57]),e(c,[2,58]),e(M,[2,11],{16:37,18:38,17:75,19:[1,76],74:d,80:E,95:C,97:m,98:k}),e(M,[2,12],{19:[1,77]}),{15:78,16:79,74:d,80:E,95:C,97:m},{16:37,17:80,18:38,74:d,80:E,95:C,97:m,98:k},e(q,[2,112]),e(q,[2,113]),e(q,[2,114]),e(q,[2,115]),e([1,8,9,12,13,19,21,37,39,42,59,60,61,62,63,64,65,70,72],[2,116]),e(ye,[2,6],{10:5,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,17:20,36:21,41:22,16:37,18:38,5:81,31:i,33:r,35:l,40:o,44:A,45:g,47:D,48:B,50:_,52:fe,53:de,54:Ee,55:Ce,56:me,66:be,67:ge,69:ke,73:Te,74:d,76:Fe,80:E,95:C,97:m,98:k}),{5:82,10:5,16:37,17:20,18:38,20:7,22:8,23:9,24:10,25:11,26:12,27:13,28:14,29:15,30:16,31:i,33:r,35:l,36:21,40:o,41:22,44:A,45:g,47:D,48:B,50:_,52:fe,53:de,54:Ee,55:Ce,56:me,66:be,67:ge,69:ke,73:Te,74:d,76:Fe,80:E,95:C,97:m,98:k},e(c,[2,17]),e(c,[2,27]),e(c,[2,28]),{13:[1,84],16:37,17:83,18:38,74:d,80:E,95:C,97:m,98:k},{49:85,57:54,58:55,59:Y,60:j,61:Q,62:X,63:H,64:De,65:Be},e(c,[2,46]),{58:86,64:De,65:Be},e(J,[2,62],{57:87,59:Y,60:j,61:Q,62:X,63:H}),e(G,[2,63]),e(G,[2,64]),e(G,[2,65]),e(G,[2,66]),e(G,[2,67]),e(Ue,[2,68]),e(Ue,[2,69]),{8:[1,89],23:90,38:88,41:22,44:A},{16:91,74:d,80:E,95:C,97:m},{43:92,47:_e},{46:[1,94]},{13:[1,95]},{13:[1,96]},{70:[1,97],72:[1,98]},{21:Z,73:$,74:ee,75:99,77:100,79:101,80:te,81:se,82:ie,83:ne,84:ue,85:re},{74:[1,111]},{13:Ge,51:112},e(c,[2,54]),e(c,[2,117]),e(M,[2,13]),e(M,[2,14]),e(M,[2,15]),{37:[2,32]},{15:113,16:79,37:[2,9],74:d,80:E,95:C,97:m},e(Se,[2,40],{11:114,12:[1,115]}),e(ye,[2,7]),{9:[1,116]},e(ae,[2,49]),{16:37,17:117,18:38,74:d,80:E,95:C,97:m,98:k},{13:[1,119],16:37,17:118,18:38,74:d,80:E,95:C,97:m,98:k},e(J,[2,61],{57:120,59:Y,60:j,61:Q,62:X,63:H}),e(J,[2,60]),{39:[1,121]},{23:90,38:122,41:22,44:A},{8:[1,123],39:[2,33]},e(W,[2,37],{37:[1,124]}),{39:[1,125]},{39:[2,43],43:126,47:_e},{16:37,17:127,18:38,74:d,80:E,95:C,97:m,98:k},e(c,[2,70],{13:[1,128]}),e(c,[2,72],{13:[1,130],68:[1,129]}),e(c,[2,76],{13:[1,131],71:[1,132]}),{13:[1,133]},e(c,[2,84],{78:[1,134]}),e(ze,[2,86],{79:135,21:Z,73:$,74:ee,80:te,81:se,82:ie,83:ne,84:ue,85:re}),e(S,[2,88]),e(S,[2,90]),e(S,[2,91]),e(S,[2,92]),e(S,[2,93]),e(S,[2,94]),e(S,[2,95]),e(S,[2,96]),e(S,[2,97]),e(S,[2,98]),e(c,[2,85]),e(c,[2,53]),{37:[2,10]},e(Se,[2,41]),{13:[1,136]},{1:[2,4]},e(ae,[2,51]),e(ae,[2,50]),{16:37,17:137,18:38,74:d,80:E,95:C,97:m,98:k},e(J,[2,59]),e(c,[2,30]),{39:[1,138]},{23:90,38:139,39:[2,34],41:22,44:A},{43:140,47:_e},e(W,[2,38]),{39:[2,44]},e(c,[2,42]),e(c,[2,71]),e(c,[2,73]),e(c,[2,74],{68:[1,141]}),e(c,[2,77]),e(c,[2,78],{13:[1,142]}),e(c,[2,80],{13:[1,144],68:[1,143]}),{21:Z,73:$,74:ee,77:145,79:101,80:te,81:se,82:ie,83:ne,84:ue,85:re},e(S,[2,89]),{14:[1,146]},e(ae,[2,52]),e(c,[2,31]),{39:[2,35]},{39:[1,147]},e(c,[2,75]),e(c,[2,79]),e(c,[2,81]),e(c,[2,82],{68:[1,148]}),e(ze,[2,87],{79:135,21:Z,73:$,74:ee,80:te,81:se,82:ie,83:ne,84:ue,85:re}),e(Se,[2,8]),e(W,[2,39]),e(c,[2,83])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],78:[2,32],113:[2,10],116:[2,4],126:[2,44],139:[2,35]},parseError:function(u,a){if(a.recoverable)this.trace(u);else{var h=new Error(u);throw h.hash=a,h}},parse:function(u){var a=this,h=[0],n=[],f=[null],t=[],U=this.table,s="",le=0,Ke=0,tt=2,Ye=1,st=t.slice.call(arguments,1),b=Object.create(this.lexer),I={yy:{}};for(var ve in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ve)&&(I.yy[ve]=this.yy[ve]);b.setInput(u,I.yy),I.yy.lexer=b,I.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var xe=b.yylloc;t.push(xe);var it=b.options&&b.options.ranges;typeof I.yy.parseError=="function"?this.parseError=I.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function nt(){var L;return L=n.pop()||b.lex()||Ye,typeof L!="number"&&(L instanceof Array&&(n=L,L=n.pop()),L=a.symbols_[L]||L),L}for(var T,R,y,Oe,P={},ce,N,je,oe;;){if(R=h[h.length-1],this.defaultActions[R]?y=this.defaultActions[R]:((T===null||typeof T>"u")&&(T=nt()),y=U[R]&&U[R][T]),typeof y>"u"||!y.length||!y[0]){var Ie="";oe=[];for(ce in U[R])this.terminals_[ce]&&ce>tt&&oe.push("'"+this.terminals_[ce]+"'");b.showPosition?Ie="Parse error on line "+(le+1)+`: `+b.showPosition()+` Expecting `+oe.join(", ")+", got '"+(this.terminals_[T]||T)+"'":Ie="Parse error on line "+(le+1)+": Unexpected "+(T==Ye?"end of input":"'"+(this.terminals_[T]||T)+"'"),this.parseError(Ie,{text:b.match,token:this.terminals_[T]||T,line:b.yylineno,loc:xe,expected:oe})}if(y[0]instanceof Array&&y.length>1)throw new Error("Parse Error: multiple actions possible at state: "+R+", token: "+T);switch(y[0]){case 1:h.push(T),f.push(b.yytext),t.push(b.yylloc),h.push(y[1]),T=null,Ke=b.yyleng,s=b.yytext,le=b.yylineno,xe=b.yylloc;break;case 2:if(N=this.productions_[y[1]][1],P.$=f[f.length-N],P._$={first_line:t[t.length-(N||1)].first_line,last_line:t[t.length-1].last_line,first_column:t[t.length-(N||1)].first_column,last_column:t[t.length-1].last_column},it&&(P._$.range=[t[t.length-(N||1)].range[0],t[t.length-1].range[1]]),Oe=this.performAction.apply(P,[s,Ke,le,I.yy,y[1],f,t].concat(st)),typeof Oe<"u")return Oe;N&&(h=h.slice(0,-1*N*2),f=f.slice(0,-1*N),t=t.slice(0,-1*N)),h.push(this.productions_[y[1]][0]),f.push(P.$),t.push(P._$),je=U[h[h.length-2]][h[h.length-1]],h.push(je);break;case 3:return!0}}return!0}},et=function(){var x={EOF:1,parseError:function(a,h){if(this.yy.parser)this.yy.parser.parseError(a,h);else throw new Error(a)},setInput:function(u,a){return this.yy=a||this.yy||{},this._input=u,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var u=this._input[0];this.yytext+=u,this.yyleng++,this.offset++,this.match+=u,this.matched+=u;var a=u.match(/(?:\r\n?|\n).*/g);return a?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),u},unput:function(u){var a=u.length,h=u.split(/(?:\r\n?|\n)/g);this._input=u+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-a),this.offset-=a;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),h.length-1&&(this.yylineno-=h.length-1);var f=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:h?(h.length===n.length?this.yylloc.first_column:0)+n[n.length-h.length].length-h[0].length:this.yylloc.first_column-a},this.options.ranges&&(this.yylloc.range=[f[0],f[0]+this.yyleng-a]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(u){this.unput(this.match.slice(u))},pastInput:function(){var u=this.matched.substr(0,this.matched.length-this.match.length);return(u.length>20?"...":"")+u.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var u=this.match;return u.length<20&&(u+=this._input.substr(0,20-u.length)),(u.substr(0,20)+(u.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var u=this.pastInput(),a=new Array(u.length+1).join("-");return u+this.upcomingInput()+` diff --git a/assets/styles-d20c7d72-JW20WKkm.js b/assets/styles-d20c7d72-fXd0DLOZ.js similarity index 99% rename from assets/styles-d20c7d72-JW20WKkm.js rename to assets/styles-d20c7d72-fXd0DLOZ.js index 6e698353d0..ff665c7545 100644 --- a/assets/styles-d20c7d72-JW20WKkm.js +++ b/assets/styles-d20c7d72-fXd0DLOZ.js @@ -1,4 +1,4 @@ -import{c as Y,g as Ut,s as zt,a as Mt,b as Ht,x as Xt,y as Kt,l as D,j as ot,A as Wt,b4 as Jt}from"./mermaid.core-95b3ca__.js";var gt=function(){var t=function(C,r,n,i){for(n=n||{},i=C.length;i--;n[C[i]]=r);return n},s=[1,2],a=[1,3],h=[1,4],f=[2,4],d=[1,9],y=[1,11],k=[1,15],u=[1,16],E=[1,17],T=[1,18],R=[1,30],G=[1,19],j=[1,20],U=[1,21],z=[1,22],M=[1,23],H=[1,25],X=[1,26],K=[1,27],W=[1,28],J=[1,29],q=[1,32],Q=[1,33],Z=[1,34],tt=[1,35],w=[1,31],c=[1,4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],et=[1,4,5,13,14,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],Dt=[4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],ht={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,cssClassStatement:11,idStatement:12,DESCR:13,"-->":14,HIDE_EMPTY:15,scale:16,WIDTH:17,COMPOSIT_STATE:18,STRUCT_START:19,STRUCT_STOP:20,STATE_DESCR:21,AS:22,ID:23,FORK:24,JOIN:25,CHOICE:26,CONCURRENT:27,note:28,notePosition:29,NOTE_TEXT:30,direction:31,acc_title:32,acc_title_value:33,acc_descr:34,acc_descr_value:35,acc_descr_multiline_value:36,classDef:37,CLASSDEF_ID:38,CLASSDEF_STYLEOPTS:39,DEFAULT:40,class:41,CLASSENTITY_IDS:42,STYLECLASS:43,direction_tb:44,direction_bt:45,direction_rl:46,direction_lr:47,eol:48,";":49,EDGE_STATE:50,STYLE_SEPARATOR:51,left_of:52,right_of:53,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",13:"DESCR",14:"-->",15:"HIDE_EMPTY",16:"scale",17:"WIDTH",18:"COMPOSIT_STATE",19:"STRUCT_START",20:"STRUCT_STOP",21:"STATE_DESCR",22:"AS",23:"ID",24:"FORK",25:"JOIN",26:"CHOICE",27:"CONCURRENT",28:"note",30:"NOTE_TEXT",32:"acc_title",33:"acc_title_value",34:"acc_descr",35:"acc_descr_value",36:"acc_descr_multiline_value",37:"classDef",38:"CLASSDEF_ID",39:"CLASSDEF_STYLEOPTS",40:"DEFAULT",41:"class",42:"CLASSENTITY_IDS",43:"STYLECLASS",44:"direction_tb",45:"direction_bt",46:"direction_rl",47:"direction_lr",49:";",50:"EDGE_STATE",51:"STYLE_SEPARATOR",52:"left_of",53:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[10,3],[10,3],[11,3],[31,1],[31,1],[31,1],[31,1],[48,1],[48,1],[12,1],[12,1],[12,3],[12,3],[29,1],[29,1]],performAction:function(r,n,i,o,p,e,$){var l=e.length-1;switch(p){case 3:return o.setRootDoc(e[l]),e[l];case 4:this.$=[];break;case 5:e[l]!="nl"&&(e[l-1].push(e[l]),this.$=e[l-1]);break;case 6:case 7:this.$=e[l];break;case 8:this.$="nl";break;case 11:this.$=e[l];break;case 12:const B=e[l-1];B.description=o.trimColon(e[l]),this.$=B;break;case 13:this.$={stmt:"relation",state1:e[l-2],state2:e[l]};break;case 14:const ft=o.trimColon(e[l]);this.$={stmt:"relation",state1:e[l-3],state2:e[l-1],description:ft};break;case 18:this.$={stmt:"state",id:e[l-3],type:"default",description:"",doc:e[l-1]};break;case 19:var A=e[l],O=e[l-2].trim();if(e[l].match(":")){var st=e[l].split(":");A=st[0],O=[O,st[1]]}this.$={stmt:"state",id:A,type:"default",description:O};break;case 20:this.$={stmt:"state",id:e[l-3],type:"default",description:e[l-5],doc:e[l-1]};break;case 21:this.$={stmt:"state",id:e[l],type:"fork"};break;case 22:this.$={stmt:"state",id:e[l],type:"join"};break;case 23:this.$={stmt:"state",id:e[l],type:"choice"};break;case 24:this.$={stmt:"state",id:o.getDividerId(),type:"divider"};break;case 25:this.$={stmt:"state",id:e[l-1].trim(),note:{position:e[l-2].trim(),text:e[l].trim()}};break;case 28:this.$=e[l].trim(),o.setAccTitle(this.$);break;case 29:case 30:this.$=e[l].trim(),o.setAccDescription(this.$);break;case 31:case 32:this.$={stmt:"classDef",id:e[l-1].trim(),classes:e[l].trim()};break;case 33:this.$={stmt:"applyClass",id:e[l-1].trim(),styleClass:e[l].trim()};break;case 34:o.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 35:o.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 36:o.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 37:o.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 40:case 41:this.$={stmt:"state",id:e[l].trim(),type:"default",description:""};break;case 42:this.$={stmt:"state",id:e[l-2].trim(),classes:[e[l].trim()],type:"default",description:""};break;case 43:this.$={stmt:"state",id:e[l-2].trim(),classes:[e[l].trim()],type:"default",description:""};break}},table:[{3:1,4:s,5:a,6:h},{1:[3]},{3:5,4:s,5:a,6:h},{3:6,4:s,5:a,6:h},t([1,4,5,15,16,18,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],f,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:d,5:y,8:8,9:10,10:12,11:13,12:14,15:k,16:u,18:E,21:T,23:R,24:G,25:j,26:U,27:z,28:M,31:24,32:H,34:X,36:K,37:W,41:J,44:q,45:Q,46:Z,47:tt,50:w},t(c,[2,5]),{9:36,10:12,11:13,12:14,15:k,16:u,18:E,21:T,23:R,24:G,25:j,26:U,27:z,28:M,31:24,32:H,34:X,36:K,37:W,41:J,44:q,45:Q,46:Z,47:tt,50:w},t(c,[2,7]),t(c,[2,8]),t(c,[2,9]),t(c,[2,10]),t(c,[2,11],{13:[1,37],14:[1,38]}),t(c,[2,15]),{17:[1,39]},t(c,[2,17],{19:[1,40]}),{22:[1,41]},t(c,[2,21]),t(c,[2,22]),t(c,[2,23]),t(c,[2,24]),{29:42,30:[1,43],52:[1,44],53:[1,45]},t(c,[2,27]),{33:[1,46]},{35:[1,47]},t(c,[2,30]),{38:[1,48],40:[1,49]},{42:[1,50]},t(et,[2,40],{51:[1,51]}),t(et,[2,41],{51:[1,52]}),t(c,[2,34]),t(c,[2,35]),t(c,[2,36]),t(c,[2,37]),t(c,[2,6]),t(c,[2,12]),{12:53,23:R,50:w},t(c,[2,16]),t(Dt,f,{7:54}),{23:[1,55]},{23:[1,56]},{22:[1,57]},{23:[2,44]},{23:[2,45]},t(c,[2,28]),t(c,[2,29]),{39:[1,58]},{39:[1,59]},{43:[1,60]},{23:[1,61]},{23:[1,62]},t(c,[2,13],{13:[1,63]}),{4:d,5:y,8:8,9:10,10:12,11:13,12:14,15:k,16:u,18:E,20:[1,64],21:T,23:R,24:G,25:j,26:U,27:z,28:M,31:24,32:H,34:X,36:K,37:W,41:J,44:q,45:Q,46:Z,47:tt,50:w},t(c,[2,19],{19:[1,65]}),{30:[1,66]},{23:[1,67]},t(c,[2,31]),t(c,[2,32]),t(c,[2,33]),t(et,[2,42]),t(et,[2,43]),t(c,[2,14]),t(c,[2,18]),t(Dt,f,{7:68}),t(c,[2,25]),t(c,[2,26]),{4:d,5:y,8:8,9:10,10:12,11:13,12:14,15:k,16:u,18:E,20:[1,69],21:T,23:R,24:G,25:j,26:U,27:z,28:M,31:24,32:H,34:X,36:K,37:W,41:J,44:q,45:Q,46:Z,47:tt,50:w},t(c,[2,20])],defaultActions:{5:[2,1],6:[2,2],44:[2,44],45:[2,45]},parseError:function(r,n){if(n.recoverable)this.trace(r);else{var i=new Error(r);throw i.hash=n,i}},parse:function(r){var n=this,i=[0],o=[],p=[null],e=[],$=this.table,l="",A=0,O=0,st=2,B=1,ft=e.slice.call(arguments,1),S=Object.create(this.lexer),v={yy:{}};for(var dt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,dt)&&(v.yy[dt]=this.yy[dt]);S.setInput(r,v.yy),v.yy.lexer=S,v.yy.parser=this,typeof S.yylloc>"u"&&(S.yylloc={});var yt=S.yylloc;e.push(yt);var Gt=S.options&&S.options.ranges;typeof v.yy.parseError=="function"?this.parseError=v.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function jt(){var x;return x=o.pop()||S.lex()||B,typeof x!="number"&&(x instanceof Array&&(o=x,x=o.pop()),x=n.symbols_[x]||x),x}for(var _,L,m,pt,N={},it,b,Ct,rt;;){if(L=i[i.length-1],this.defaultActions[L]?m=this.defaultActions[L]:((_===null||typeof _>"u")&&(_=jt()),m=$[L]&&$[L][_]),typeof m>"u"||!m.length||!m[0]){var St="";rt=[];for(it in $[L])this.terminals_[it]&&it>st&&rt.push("'"+this.terminals_[it]+"'");S.showPosition?St="Parse error on line "+(A+1)+`: +import{c as Y,g as Ut,s as zt,a as Mt,b as Ht,x as Xt,y as Kt,l as D,j as ot,A as Wt,b4 as Jt}from"./mermaid.core-Q3WVcjPF.js";var gt=function(){var t=function(C,r,n,i){for(n=n||{},i=C.length;i--;n[C[i]]=r);return n},s=[1,2],a=[1,3],h=[1,4],f=[2,4],d=[1,9],y=[1,11],k=[1,15],u=[1,16],E=[1,17],T=[1,18],R=[1,30],G=[1,19],j=[1,20],U=[1,21],z=[1,22],M=[1,23],H=[1,25],X=[1,26],K=[1,27],W=[1,28],J=[1,29],q=[1,32],Q=[1,33],Z=[1,34],tt=[1,35],w=[1,31],c=[1,4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],et=[1,4,5,13,14,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],Dt=[4,5,15,16,18,20,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],ht={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,cssClassStatement:11,idStatement:12,DESCR:13,"-->":14,HIDE_EMPTY:15,scale:16,WIDTH:17,COMPOSIT_STATE:18,STRUCT_START:19,STRUCT_STOP:20,STATE_DESCR:21,AS:22,ID:23,FORK:24,JOIN:25,CHOICE:26,CONCURRENT:27,note:28,notePosition:29,NOTE_TEXT:30,direction:31,acc_title:32,acc_title_value:33,acc_descr:34,acc_descr_value:35,acc_descr_multiline_value:36,classDef:37,CLASSDEF_ID:38,CLASSDEF_STYLEOPTS:39,DEFAULT:40,class:41,CLASSENTITY_IDS:42,STYLECLASS:43,direction_tb:44,direction_bt:45,direction_rl:46,direction_lr:47,eol:48,";":49,EDGE_STATE:50,STYLE_SEPARATOR:51,left_of:52,right_of:53,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",13:"DESCR",14:"-->",15:"HIDE_EMPTY",16:"scale",17:"WIDTH",18:"COMPOSIT_STATE",19:"STRUCT_START",20:"STRUCT_STOP",21:"STATE_DESCR",22:"AS",23:"ID",24:"FORK",25:"JOIN",26:"CHOICE",27:"CONCURRENT",28:"note",30:"NOTE_TEXT",32:"acc_title",33:"acc_title_value",34:"acc_descr",35:"acc_descr_value",36:"acc_descr_multiline_value",37:"classDef",38:"CLASSDEF_ID",39:"CLASSDEF_STYLEOPTS",40:"DEFAULT",41:"class",42:"CLASSENTITY_IDS",43:"STYLECLASS",44:"direction_tb",45:"direction_bt",46:"direction_rl",47:"direction_lr",49:";",50:"EDGE_STATE",51:"STYLE_SEPARATOR",52:"left_of",53:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[10,3],[10,3],[11,3],[31,1],[31,1],[31,1],[31,1],[48,1],[48,1],[12,1],[12,1],[12,3],[12,3],[29,1],[29,1]],performAction:function(r,n,i,o,p,e,$){var l=e.length-1;switch(p){case 3:return o.setRootDoc(e[l]),e[l];case 4:this.$=[];break;case 5:e[l]!="nl"&&(e[l-1].push(e[l]),this.$=e[l-1]);break;case 6:case 7:this.$=e[l];break;case 8:this.$="nl";break;case 11:this.$=e[l];break;case 12:const B=e[l-1];B.description=o.trimColon(e[l]),this.$=B;break;case 13:this.$={stmt:"relation",state1:e[l-2],state2:e[l]};break;case 14:const ft=o.trimColon(e[l]);this.$={stmt:"relation",state1:e[l-3],state2:e[l-1],description:ft};break;case 18:this.$={stmt:"state",id:e[l-3],type:"default",description:"",doc:e[l-1]};break;case 19:var A=e[l],O=e[l-2].trim();if(e[l].match(":")){var st=e[l].split(":");A=st[0],O=[O,st[1]]}this.$={stmt:"state",id:A,type:"default",description:O};break;case 20:this.$={stmt:"state",id:e[l-3],type:"default",description:e[l-5],doc:e[l-1]};break;case 21:this.$={stmt:"state",id:e[l],type:"fork"};break;case 22:this.$={stmt:"state",id:e[l],type:"join"};break;case 23:this.$={stmt:"state",id:e[l],type:"choice"};break;case 24:this.$={stmt:"state",id:o.getDividerId(),type:"divider"};break;case 25:this.$={stmt:"state",id:e[l-1].trim(),note:{position:e[l-2].trim(),text:e[l].trim()}};break;case 28:this.$=e[l].trim(),o.setAccTitle(this.$);break;case 29:case 30:this.$=e[l].trim(),o.setAccDescription(this.$);break;case 31:case 32:this.$={stmt:"classDef",id:e[l-1].trim(),classes:e[l].trim()};break;case 33:this.$={stmt:"applyClass",id:e[l-1].trim(),styleClass:e[l].trim()};break;case 34:o.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 35:o.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 36:o.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 37:o.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 40:case 41:this.$={stmt:"state",id:e[l].trim(),type:"default",description:""};break;case 42:this.$={stmt:"state",id:e[l-2].trim(),classes:[e[l].trim()],type:"default",description:""};break;case 43:this.$={stmt:"state",id:e[l-2].trim(),classes:[e[l].trim()],type:"default",description:""};break}},table:[{3:1,4:s,5:a,6:h},{1:[3]},{3:5,4:s,5:a,6:h},{3:6,4:s,5:a,6:h},t([1,4,5,15,16,18,21,23,24,25,26,27,28,32,34,36,37,41,44,45,46,47,50],f,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:d,5:y,8:8,9:10,10:12,11:13,12:14,15:k,16:u,18:E,21:T,23:R,24:G,25:j,26:U,27:z,28:M,31:24,32:H,34:X,36:K,37:W,41:J,44:q,45:Q,46:Z,47:tt,50:w},t(c,[2,5]),{9:36,10:12,11:13,12:14,15:k,16:u,18:E,21:T,23:R,24:G,25:j,26:U,27:z,28:M,31:24,32:H,34:X,36:K,37:W,41:J,44:q,45:Q,46:Z,47:tt,50:w},t(c,[2,7]),t(c,[2,8]),t(c,[2,9]),t(c,[2,10]),t(c,[2,11],{13:[1,37],14:[1,38]}),t(c,[2,15]),{17:[1,39]},t(c,[2,17],{19:[1,40]}),{22:[1,41]},t(c,[2,21]),t(c,[2,22]),t(c,[2,23]),t(c,[2,24]),{29:42,30:[1,43],52:[1,44],53:[1,45]},t(c,[2,27]),{33:[1,46]},{35:[1,47]},t(c,[2,30]),{38:[1,48],40:[1,49]},{42:[1,50]},t(et,[2,40],{51:[1,51]}),t(et,[2,41],{51:[1,52]}),t(c,[2,34]),t(c,[2,35]),t(c,[2,36]),t(c,[2,37]),t(c,[2,6]),t(c,[2,12]),{12:53,23:R,50:w},t(c,[2,16]),t(Dt,f,{7:54}),{23:[1,55]},{23:[1,56]},{22:[1,57]},{23:[2,44]},{23:[2,45]},t(c,[2,28]),t(c,[2,29]),{39:[1,58]},{39:[1,59]},{43:[1,60]},{23:[1,61]},{23:[1,62]},t(c,[2,13],{13:[1,63]}),{4:d,5:y,8:8,9:10,10:12,11:13,12:14,15:k,16:u,18:E,20:[1,64],21:T,23:R,24:G,25:j,26:U,27:z,28:M,31:24,32:H,34:X,36:K,37:W,41:J,44:q,45:Q,46:Z,47:tt,50:w},t(c,[2,19],{19:[1,65]}),{30:[1,66]},{23:[1,67]},t(c,[2,31]),t(c,[2,32]),t(c,[2,33]),t(et,[2,42]),t(et,[2,43]),t(c,[2,14]),t(c,[2,18]),t(Dt,f,{7:68}),t(c,[2,25]),t(c,[2,26]),{4:d,5:y,8:8,9:10,10:12,11:13,12:14,15:k,16:u,18:E,20:[1,69],21:T,23:R,24:G,25:j,26:U,27:z,28:M,31:24,32:H,34:X,36:K,37:W,41:J,44:q,45:Q,46:Z,47:tt,50:w},t(c,[2,20])],defaultActions:{5:[2,1],6:[2,2],44:[2,44],45:[2,45]},parseError:function(r,n){if(n.recoverable)this.trace(r);else{var i=new Error(r);throw i.hash=n,i}},parse:function(r){var n=this,i=[0],o=[],p=[null],e=[],$=this.table,l="",A=0,O=0,st=2,B=1,ft=e.slice.call(arguments,1),S=Object.create(this.lexer),v={yy:{}};for(var dt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,dt)&&(v.yy[dt]=this.yy[dt]);S.setInput(r,v.yy),v.yy.lexer=S,v.yy.parser=this,typeof S.yylloc>"u"&&(S.yylloc={});var yt=S.yylloc;e.push(yt);var Gt=S.options&&S.options.ranges;typeof v.yy.parseError=="function"?this.parseError=v.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function jt(){var x;return x=o.pop()||S.lex()||B,typeof x!="number"&&(x instanceof Array&&(o=x,x=o.pop()),x=n.symbols_[x]||x),x}for(var _,L,m,pt,N={},it,b,Ct,rt;;){if(L=i[i.length-1],this.defaultActions[L]?m=this.defaultActions[L]:((_===null||typeof _>"u")&&(_=jt()),m=$[L]&&$[L][_]),typeof m>"u"||!m.length||!m[0]){var St="";rt=[];for(it in $[L])this.terminals_[it]&&it>st&&rt.push("'"+this.terminals_[it]+"'");S.showPosition?St="Parse error on line "+(A+1)+`: `+S.showPosition()+` Expecting `+rt.join(", ")+", got '"+(this.terminals_[_]||_)+"'":St="Parse error on line "+(A+1)+": Unexpected "+(_==B?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(St,{text:S.match,token:this.terminals_[_]||_,line:S.yylineno,loc:yt,expected:rt})}if(m[0]instanceof Array&&m.length>1)throw new Error("Parse Error: multiple actions possible at state: "+L+", token: "+_);switch(m[0]){case 1:i.push(_),p.push(S.yytext),e.push(S.yylloc),i.push(m[1]),_=null,O=S.yyleng,l=S.yytext,A=S.yylineno,yt=S.yylloc;break;case 2:if(b=this.productions_[m[1]][1],N.$=p[p.length-b],N._$={first_line:e[e.length-(b||1)].first_line,last_line:e[e.length-1].last_line,first_column:e[e.length-(b||1)].first_column,last_column:e[e.length-1].last_column},Gt&&(N._$.range=[e[e.length-(b||1)].range[0],e[e.length-1].range[1]]),pt=this.performAction.apply(N,[l,O,A,v.yy,m[1],p,e].concat(ft)),typeof pt<"u")return pt;b&&(i=i.slice(0,-1*b*2),p=p.slice(0,-1*b),e=e.slice(0,-1*b)),i.push(this.productions_[m[1]][0]),p.push(N.$),e.push(N._$),Ct=$[i[i.length-2]][i[i.length-1]],i.push(Ct);break;case 3:return!0}}return!0}},Yt=function(){var C={EOF:1,parseError:function(n,i){if(this.yy.parser)this.yy.parser.parseError(n,i);else throw new Error(n)},setInput:function(r,n){return this.yy=n||this.yy||{},this._input=r,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var r=this._input[0];this.yytext+=r,this.yyleng++,this.offset++,this.match+=r,this.matched+=r;var n=r.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),r},unput:function(r){var n=r.length,i=r.split(/(?:\r\n?|\n)/g);this._input=r+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var o=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var p=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===o.length?this.yylloc.first_column:0)+o[o.length-i.length].length-i[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[p[0],p[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(r){this.unput(this.match.slice(r))},pastInput:function(){var r=this.matched.substr(0,this.matched.length-this.match.length);return(r.length>20?"...":"")+r.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var r=this.match;return r.length<20&&(r+=this._input.substr(0,20-r.length)),(r.substr(0,20)+(r.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var r=this.pastInput(),n=new Array(r.length+1).join("-");return r+this.upcomingInput()+` diff --git a/assets/svgDrawCommon-5ccd53ef-iJa2TVTb.js b/assets/svgDrawCommon-5ccd53ef-wBNBFr7n.js similarity index 95% rename from assets/svgDrawCommon-5ccd53ef-iJa2TVTb.js rename to assets/svgDrawCommon-5ccd53ef-wBNBFr7n.js index 690cc12f93..93b05c14d4 100644 --- a/assets/svgDrawCommon-5ccd53ef-iJa2TVTb.js +++ b/assets/svgDrawCommon-5ccd53ef-wBNBFr7n.js @@ -1 +1 @@ -import{n as o,m as i}from"./mermaid.core-95b3ca__.js";const l=(s,t)=>{const e=s.append("rect");if(e.attr("x",t.x),e.attr("y",t.y),e.attr("fill",t.fill),e.attr("stroke",t.stroke),e.attr("width",t.width),e.attr("height",t.height),t.name&&e.attr("name",t.name),t.rx!==void 0&&e.attr("rx",t.rx),t.ry!==void 0&&e.attr("ry",t.ry),t.attrs!==void 0)for(const r in t.attrs)e.attr(r,t.attrs[r]);return t.class!==void 0&&e.attr("class",t.class),e},x=(s,t)=>{const e={x:t.startx,y:t.starty,width:t.stopx-t.startx,height:t.stopy-t.starty,fill:t.fill,stroke:t.stroke,class:"rect"};l(s,e).lower()},d=(s,t)=>{const e=t.text.replace(o," "),r=s.append("text");r.attr("x",t.x),r.attr("y",t.y),r.attr("class","legend"),r.style("text-anchor",t.anchor),t.class!==void 0&&r.attr("class",t.class);const n=r.append("tspan");return n.attr("x",t.x+t.textMargin*2),n.text(e),r},h=(s,t,e,r)=>{const n=s.append("image");n.attr("x",t),n.attr("y",e);const a=i.sanitizeUrl(r);n.attr("xlink:href",a)},y=(s,t,e,r)=>{const n=s.append("use");n.attr("x",t),n.attr("y",e);const a=i.sanitizeUrl(r);n.attr("xlink:href",`#${a}`)},g=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),m=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0});export{x as a,m as b,y as c,l as d,h as e,d as f,g}; +import{n as o,m as i}from"./mermaid.core-Q3WVcjPF.js";const l=(s,t)=>{const e=s.append("rect");if(e.attr("x",t.x),e.attr("y",t.y),e.attr("fill",t.fill),e.attr("stroke",t.stroke),e.attr("width",t.width),e.attr("height",t.height),t.name&&e.attr("name",t.name),t.rx!==void 0&&e.attr("rx",t.rx),t.ry!==void 0&&e.attr("ry",t.ry),t.attrs!==void 0)for(const r in t.attrs)e.attr(r,t.attrs[r]);return t.class!==void 0&&e.attr("class",t.class),e},x=(s,t)=>{const e={x:t.startx,y:t.starty,width:t.stopx-t.startx,height:t.stopy-t.starty,fill:t.fill,stroke:t.stroke,class:"rect"};l(s,e).lower()},d=(s,t)=>{const e=t.text.replace(o," "),r=s.append("text");r.attr("x",t.x),r.attr("y",t.y),r.attr("class","legend"),r.style("text-anchor",t.anchor),t.class!==void 0&&r.attr("class",t.class);const n=r.append("tspan");return n.attr("x",t.x+t.textMargin*2),n.text(e),r},h=(s,t,e,r)=>{const n=s.append("image");n.attr("x",t),n.attr("y",e);const a=i.sanitizeUrl(r);n.attr("xlink:href",a)},y=(s,t,e,r)=>{const n=s.append("use");n.attr("x",t),n.attr("y",e);const a=i.sanitizeUrl(r);n.attr("xlink:href",`#${a}`)},g=()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),m=()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0});export{x as a,m as b,y as c,l as d,h as e,d as f,g}; diff --git a/assets/tcp.html-3jgF7WlU.js b/assets/tcp.html-A1382ftf.js similarity index 99% rename from assets/tcp.html-3jgF7WlU.js rename to assets/tcp.html-A1382ftf.js index f3882de739..59dec8ca36 100644 --- a/assets/tcp.html-3jgF7WlU.js +++ b/assets/tcp.html-A1382ftf.js @@ -1,4 +1,4 @@ -import{_ as o,r as t,o as p,c,a as s,b as n,d as u,e as a}from"./app-PDrbPfzp.js";const l={},i=a(`

                        TCP

                        TCP 传输模式是目前推荐使用的传输模式之一.

                        可以和各种协议有多种组合模式.

                        TcpObject

                        TcpObject 对应传输配置的 tcpSettings 项。

                        {
                        +import{_ as o,r as t,o as p,c,a as s,b as n,d as u,e as a}from"./app-UOvWaKji.js";const l={},i=a(`

                        TCP

                        TCP 传输模式是目前推荐使用的传输模式之一.

                        可以和各种协议有多种组合模式.

                        TcpObject

                        TcpObject 对应传输配置的 tcpSettings 项。

                        {
                           "acceptProxyProtocol": false,
                           "header": {
                             "type": "none"
                        diff --git a/assets/tcp.html-boyh_9AY.js b/assets/tcp.html-ZlB-8N_8.js
                        similarity index 99%
                        rename from assets/tcp.html-boyh_9AY.js
                        rename to assets/tcp.html-ZlB-8N_8.js
                        index ce322ce3db..707b756c5e 100644
                        --- a/assets/tcp.html-boyh_9AY.js
                        +++ b/assets/tcp.html-ZlB-8N_8.js
                        @@ -1,4 +1,4 @@
                        -import{_ as t,r as o,o as p,c,a as s,b as n,d as r,e}from"./app-PDrbPfzp.js";const l={},i=e(`

                        TCP

                        TCP (Transmission Control Protocol) is currently one of the recommended transport protocols

                        It can be combined with various protocols in multiple ways.

                        TcpObject

                        TcpObject corresponds to the tcpSettings item in the Transport Protocol.

                        {
                        +import{_ as t,r as o,o as p,c,a as s,b as n,d as r,e}from"./app-UOvWaKji.js";const l={},i=e(`

                        TCP

                        TCP (Transmission Control Protocol) is currently one of the recommended transport protocols

                        It can be combined with various protocols in multiple ways.

                        TcpObject

                        TcpObject corresponds to the tcpSettings item in the Transport Protocol.

                        {
                           "acceptProxyProtocol": false,
                           "header": {
                             "type": "none"
                        diff --git a/assets/timeline-definition-fea2a41d-4QeTlQgD.js b/assets/timeline-definition-fea2a41d-Scl62dAd.js
                        similarity index 99%
                        rename from assets/timeline-definition-fea2a41d-4QeTlQgD.js
                        rename to assets/timeline-definition-fea2a41d-Scl62dAd.js
                        index e1beb9237b..602180ea50 100644
                        --- a/assets/timeline-definition-fea2a41d-4QeTlQgD.js
                        +++ b/assets/timeline-definition-fea2a41d-Scl62dAd.js
                        @@ -1,4 +1,4 @@
                        -import{b5 as ft,A as gt,c as mt,l as E,h as G,u as xt,b6 as bt,b7 as _t,b8 as kt}from"./mermaid.core-95b3ca__.js";import{a as D}from"./arc-XT00965o.js";import"./app-PDrbPfzp.js";import"./path-aUcfwwLI.js";var K=function(){var n=function(g,i,r,c){for(r=r||{},c=g.length;c--;r[g[c]]=i);return r},t=[6,8,10,11,12,14,16,17,20,21],e=[1,9],a=[1,10],s=[1,11],h=[1,12],l=[1,13],p=[1,16],y=[1,17],f={trace:function(){},yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:function(i,r,c,d,u,o,$){var x=o.length-1;switch(u){case 1:return o[x-1];case 2:this.$=[];break;case 3:o[x-1].push(o[x]),this.$=o[x-1];break;case 4:case 5:this.$=o[x];break;case 6:case 7:this.$=[];break;case 8:d.getCommonDb().setDiagramTitle(o[x].substr(6)),this.$=o[x].substr(6);break;case 9:this.$=o[x].trim(),d.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=o[x].trim(),d.getCommonDb().setAccDescription(this.$);break;case 12:d.addSection(o[x].substr(8)),this.$=o[x].substr(8);break;case 15:d.addTask(o[x],0,""),this.$=o[x];break;case 16:d.addEvent(o[x].substr(2)),this.$=o[x];break}},table:[{3:1,4:[1,2]},{1:[3]},n(t,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:e,12:a,14:s,16:h,17:l,18:14,19:15,20:p,21:y},n(t,[2,7],{1:[2,1]}),n(t,[2,3]),{9:18,11:e,12:a,14:s,16:h,17:l,18:14,19:15,20:p,21:y},n(t,[2,5]),n(t,[2,6]),n(t,[2,8]),{13:[1,19]},{15:[1,20]},n(t,[2,11]),n(t,[2,12]),n(t,[2,13]),n(t,[2,14]),n(t,[2,15]),n(t,[2,16]),n(t,[2,4]),n(t,[2,9]),n(t,[2,10])],defaultActions:{},parseError:function(i,r){if(r.recoverable)this.trace(i);else{var c=new Error(i);throw c.hash=r,c}},parse:function(i){var r=this,c=[0],d=[],u=[null],o=[],$=this.table,x="",T=0,W=0,C=2,A=1,B=o.slice.call(arguments,1),k=Object.create(this.lexer),w={yy:{}};for(var v in this.yy)Object.prototype.hasOwnProperty.call(this.yy,v)&&(w.yy[v]=this.yy[v]);k.setInput(i,w.yy),w.yy.lexer=k,w.yy.parser=this,typeof k.yylloc>"u"&&(k.yylloc={});var I=k.yylloc;o.push(I);var P=k.options&&k.options.ranges;typeof w.yy.parseError=="function"?this.parseError=w.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function z(){var M;return M=d.pop()||k.lex()||A,typeof M!="number"&&(M instanceof Array&&(d=M,M=d.pop()),M=r.symbols_[M]||M),M}for(var _,L,S,Z,R={},O,N,Y,j;;){if(L=c[c.length-1],this.defaultActions[L]?S=this.defaultActions[L]:((_===null||typeof _>"u")&&(_=z()),S=$[L]&&$[L][_]),typeof S>"u"||!S.length||!S[0]){var J="";j=[];for(O in $[L])this.terminals_[O]&&O>C&&j.push("'"+this.terminals_[O]+"'");k.showPosition?J="Parse error on line "+(T+1)+`:
                        +import{b5 as ft,A as gt,c as mt,l as E,h as G,u as xt,b6 as bt,b7 as _t,b8 as kt}from"./mermaid.core-Q3WVcjPF.js";import{a as D}from"./arc-5GdQY_kf.js";import"./app-UOvWaKji.js";import"./path-aUcfwwLI.js";var K=function(){var n=function(g,i,r,c){for(r=r||{},c=g.length;c--;r[g[c]]=i);return r},t=[6,8,10,11,12,14,16,17,20,21],e=[1,9],a=[1,10],s=[1,11],h=[1,12],l=[1,13],p=[1,16],y=[1,17],f={trace:function(){},yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:function(i,r,c,d,u,o,$){var x=o.length-1;switch(u){case 1:return o[x-1];case 2:this.$=[];break;case 3:o[x-1].push(o[x]),this.$=o[x-1];break;case 4:case 5:this.$=o[x];break;case 6:case 7:this.$=[];break;case 8:d.getCommonDb().setDiagramTitle(o[x].substr(6)),this.$=o[x].substr(6);break;case 9:this.$=o[x].trim(),d.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=o[x].trim(),d.getCommonDb().setAccDescription(this.$);break;case 12:d.addSection(o[x].substr(8)),this.$=o[x].substr(8);break;case 15:d.addTask(o[x],0,""),this.$=o[x];break;case 16:d.addEvent(o[x].substr(2)),this.$=o[x];break}},table:[{3:1,4:[1,2]},{1:[3]},n(t,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:e,12:a,14:s,16:h,17:l,18:14,19:15,20:p,21:y},n(t,[2,7],{1:[2,1]}),n(t,[2,3]),{9:18,11:e,12:a,14:s,16:h,17:l,18:14,19:15,20:p,21:y},n(t,[2,5]),n(t,[2,6]),n(t,[2,8]),{13:[1,19]},{15:[1,20]},n(t,[2,11]),n(t,[2,12]),n(t,[2,13]),n(t,[2,14]),n(t,[2,15]),n(t,[2,16]),n(t,[2,4]),n(t,[2,9]),n(t,[2,10])],defaultActions:{},parseError:function(i,r){if(r.recoverable)this.trace(i);else{var c=new Error(i);throw c.hash=r,c}},parse:function(i){var r=this,c=[0],d=[],u=[null],o=[],$=this.table,x="",T=0,W=0,C=2,A=1,B=o.slice.call(arguments,1),k=Object.create(this.lexer),w={yy:{}};for(var v in this.yy)Object.prototype.hasOwnProperty.call(this.yy,v)&&(w.yy[v]=this.yy[v]);k.setInput(i,w.yy),w.yy.lexer=k,w.yy.parser=this,typeof k.yylloc>"u"&&(k.yylloc={});var I=k.yylloc;o.push(I);var P=k.options&&k.options.ranges;typeof w.yy.parseError=="function"?this.parseError=w.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function z(){var M;return M=d.pop()||k.lex()||A,typeof M!="number"&&(M instanceof Array&&(d=M,M=d.pop()),M=r.symbols_[M]||M),M}for(var _,L,S,Z,R={},O,N,Y,j;;){if(L=c[c.length-1],this.defaultActions[L]?S=this.defaultActions[L]:((_===null||typeof _>"u")&&(_=z()),S=$[L]&&$[L][_]),typeof S>"u"||!S.length||!S[0]){var J="";j=[];for(O in $[L])this.terminals_[O]&&O>C&&j.push("'"+this.terminals_[O]+"'");k.showPosition?J="Parse error on line "+(T+1)+`:
                         `+k.showPosition()+`
                         Expecting `+j.join(", ")+", got '"+(this.terminals_[_]||_)+"'":J="Parse error on line "+(T+1)+": Unexpected "+(_==A?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(J,{text:k.match,token:this.terminals_[_]||_,line:k.yylineno,loc:I,expected:j})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+L+", token: "+_);switch(S[0]){case 1:c.push(_),u.push(k.yytext),o.push(k.yylloc),c.push(S[1]),_=null,W=k.yyleng,x=k.yytext,T=k.yylineno,I=k.yylloc;break;case 2:if(N=this.productions_[S[1]][1],R.$=u[u.length-N],R._$={first_line:o[o.length-(N||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(N||1)].first_column,last_column:o[o.length-1].last_column},P&&(R._$.range=[o[o.length-(N||1)].range[0],o[o.length-1].range[1]]),Z=this.performAction.apply(R,[x,W,T,w.yy,S[1],u,o].concat(B)),typeof Z<"u")return Z;N&&(c=c.slice(0,-1*N*2),u=u.slice(0,-1*N),o=o.slice(0,-1*N)),c.push(this.productions_[S[1]][0]),u.push(R.$),o.push(R._$),Y=$[c[c.length-2]][c[c.length-1]],c.push(Y);break;case 3:return!0}}return!0}},b=function(){var g={EOF:1,parseError:function(r,c){if(this.yy.parser)this.yy.parser.parseError(r,c);else throw new Error(r)},setInput:function(i,r){return this.yy=r||this.yy||{},this._input=i,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var i=this._input[0];this.yytext+=i,this.yyleng++,this.offset++,this.match+=i,this.matched+=i;var r=i.match(/(?:\r\n?|\n).*/g);return r?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),i},unput:function(i){var r=i.length,c=i.split(/(?:\r\n?|\n)/g);this._input=i+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-r),this.offset-=r;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var u=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===d.length?this.yylloc.first_column:0)+d[d.length-c.length].length-c[0].length:this.yylloc.first_column-r},this.options.ranges&&(this.yylloc.range=[u[0],u[0]+this.yyleng-r]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
                         `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(i){this.unput(this.match.slice(i))},pastInput:function(){var i=this.matched.substr(0,this.matched.length-this.match.length);return(i.length>20?"...":"")+i.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var i=this.match;return i.length<20&&(i+=this._input.substr(0,20-i.length)),(i.substr(0,20)+(i.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var i=this.pastInput(),r=new Array(i.length+1).join("-");return i+this.upcomingInput()+`
                        diff --git a/assets/tproxy.html-lyGaCi6Q.js b/assets/tproxy.html-VWEtc--I.js
                        similarity index 99%
                        rename from assets/tproxy.html-lyGaCi6Q.js
                        rename to assets/tproxy.html-VWEtc--I.js
                        index d481c1840b..1f1379b503 100644
                        --- a/assets/tproxy.html-lyGaCi6Q.js
                        +++ b/assets/tproxy.html-VWEtc--I.js
                        @@ -1,4 +1,4 @@
                        -import{_ as r,r as o,o as i,c,a as n,b as s,d as a,w as e,e as u}from"./app-PDrbPfzp.js";const k={},d=n("h1",{id:"透明代理-tproxy-配置教程",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#透明代理-tproxy-配置教程"},[n("span",null,"透明代理(TProxy)配置教程")])],-1),v={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},m=n("p",null,"本文中所有配置已在 Raspberry Pi 2B、Ubuntu 20.04 环境下测试成功,如在其它环境中使用请自行调整配置。",-1),b=n("h2",{id:"开始之前",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#开始之前"},[n("span",null,"开始之前")])],-1),q=n("p",null,"请检查您的设备是否有可用的网络连接,且服务端已经配置成功,客户端已经安装完毕。",-1),g={href:"https://github.com/XTLS/Xray-core/discussions/59",target:"_blank",rel:"noopener noreferrer"},y=n("p",null,"这里我想要补充的是,很多透明代理教程会使用 Netfilter 进行分流,使直连流量直接发出而不经过 Xray,这时必须开启 IP 转发;也有的教程,如本文,会将所有流量导入 Xray 之中,由 Xray 的路由模块进行分流,这时无需开启 IP 转发。",-1),f=n("h2",{id:"xray-配置",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#xray-配置"},[n("span",null,"Xray 配置")])],-1),h={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},R=u(`
                        sudo curl -oL /usr/local/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
                        +import{_ as r,r as o,o as i,c,a as n,b as s,d as a,w as e,e as u}from"./app-UOvWaKji.js";const k={},d=n("h1",{id:"透明代理-tproxy-配置教程",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#透明代理-tproxy-配置教程"},[n("span",null,"透明代理(TProxy)配置教程")])],-1),v={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},m=n("p",null,"本文中所有配置已在 Raspberry Pi 2B、Ubuntu 20.04 环境下测试成功,如在其它环境中使用请自行调整配置。",-1),b=n("h2",{id:"开始之前",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#开始之前"},[n("span",null,"开始之前")])],-1),q=n("p",null,"请检查您的设备是否有可用的网络连接,且服务端已经配置成功,客户端已经安装完毕。",-1),g={href:"https://github.com/XTLS/Xray-core/discussions/59",target:"_blank",rel:"noopener noreferrer"},y=n("p",null,"这里我想要补充的是,很多透明代理教程会使用 Netfilter 进行分流,使直连流量直接发出而不经过 Xray,这时必须开启 IP 转发;也有的教程,如本文,会将所有流量导入 Xray 之中,由 Xray 的路由模块进行分流,这时无需开启 IP 转发。",-1),f=n("h2",{id:"xray-配置",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#xray-配置"},[n("span",null,"Xray 配置")])],-1),h={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},R=u(`
                        sudo curl -oL /usr/local/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
                         sudo curl -oL /usr/local/share/xray/geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
                         
                        {
                           "log": {
                        diff --git a/assets/tproxy.html-9M3-wGDd.js b/assets/tproxy.html-nklfTqvg.js
                        similarity index 99%
                        rename from assets/tproxy.html-9M3-wGDd.js
                        rename to assets/tproxy.html-nklfTqvg.js
                        index d481c1840b..1f1379b503 100644
                        --- a/assets/tproxy.html-9M3-wGDd.js
                        +++ b/assets/tproxy.html-nklfTqvg.js
                        @@ -1,4 +1,4 @@
                        -import{_ as r,r as o,o as i,c,a as n,b as s,d as a,w as e,e as u}from"./app-PDrbPfzp.js";const k={},d=n("h1",{id:"透明代理-tproxy-配置教程",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#透明代理-tproxy-配置教程"},[n("span",null,"透明代理(TProxy)配置教程")])],-1),v={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},m=n("p",null,"本文中所有配置已在 Raspberry Pi 2B、Ubuntu 20.04 环境下测试成功,如在其它环境中使用请自行调整配置。",-1),b=n("h2",{id:"开始之前",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#开始之前"},[n("span",null,"开始之前")])],-1),q=n("p",null,"请检查您的设备是否有可用的网络连接,且服务端已经配置成功,客户端已经安装完毕。",-1),g={href:"https://github.com/XTLS/Xray-core/discussions/59",target:"_blank",rel:"noopener noreferrer"},y=n("p",null,"这里我想要补充的是,很多透明代理教程会使用 Netfilter 进行分流,使直连流量直接发出而不经过 Xray,这时必须开启 IP 转发;也有的教程,如本文,会将所有流量导入 Xray 之中,由 Xray 的路由模块进行分流,这时无需开启 IP 转发。",-1),f=n("h2",{id:"xray-配置",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#xray-配置"},[n("span",null,"Xray 配置")])],-1),h={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},R=u(`
                        sudo curl -oL /usr/local/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
                        +import{_ as r,r as o,o as i,c,a as n,b as s,d as a,w as e,e as u}from"./app-UOvWaKji.js";const k={},d=n("h1",{id:"透明代理-tproxy-配置教程",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#透明代理-tproxy-配置教程"},[n("span",null,"透明代理(TProxy)配置教程")])],-1),v={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},m=n("p",null,"本文中所有配置已在 Raspberry Pi 2B、Ubuntu 20.04 环境下测试成功,如在其它环境中使用请自行调整配置。",-1),b=n("h2",{id:"开始之前",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#开始之前"},[n("span",null,"开始之前")])],-1),q=n("p",null,"请检查您的设备是否有可用的网络连接,且服务端已经配置成功,客户端已经安装完毕。",-1),g={href:"https://github.com/XTLS/Xray-core/discussions/59",target:"_blank",rel:"noopener noreferrer"},y=n("p",null,"这里我想要补充的是,很多透明代理教程会使用 Netfilter 进行分流,使直连流量直接发出而不经过 Xray,这时必须开启 IP 转发;也有的教程,如本文,会将所有流量导入 Xray 之中,由 Xray 的路由模块进行分流,这时无需开启 IP 转发。",-1),f=n("h2",{id:"xray-配置",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#xray-配置"},[n("span",null,"Xray 配置")])],-1),h={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},R=u(`
                        sudo curl -oL /usr/local/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
                         sudo curl -oL /usr/local/share/xray/geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat
                         
                        {
                           "log": {
                        diff --git a/assets/tproxy_ipv4_and_ipv6.html-IOus2e7D.js b/assets/tproxy_ipv4_and_ipv6.html-YTH3X_7C.js
                        similarity index 99%
                        rename from assets/tproxy_ipv4_and_ipv6.html-IOus2e7D.js
                        rename to assets/tproxy_ipv4_and_ipv6.html-YTH3X_7C.js
                        index dd1ba581b5..08c7886a04 100644
                        --- a/assets/tproxy_ipv4_and_ipv6.html-IOus2e7D.js
                        +++ b/assets/tproxy_ipv4_and_ipv6.html-YTH3X_7C.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as o,o as l,c as i,a as s,b as n,d as e,e as t}from"./app-PDrbPfzp.js";const r={},c=s("h1",{id:"tproxy-透明代理-ipv4-and-ipv6-配置教程",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#tproxy-透明代理-ipv4-and-ipv6-配置教程"},[s("span",null,"TProxy 透明代理(ipv4 and ipv6)配置教程")])],-1),u={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},d={href:"https://xtls.github.io/document/level-2/tproxy.html#%E5%BC%80%E5%A7%8B%E4%B9%8B%E5%89%8D",target:"_blank",rel:"noopener noreferrer"},v={href:"https://xtls.github.io/document/level-2/iptables_gid.html",target:"_blank",rel:"noopener noreferrer"},k={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},m={href:"https://github.com/chika0801/Xray-examples",target:"_blank",rel:"noopener noreferrer"},b={href:"https://github.com/lxhao61/integrated-examples",target:"_blank",rel:"noopener noreferrer"},q=t('

                        注意

                        若使用其他配置,你需要着重注意客户端配置中 outboundtagproxy 的部分,其他部分不变

                        服务端配置也要同时改变

                        此配置意在解决例如 Netflix 等默认使用 ipv6 连接的网站无法通过旁路由进行代理的问题,或对 ipv6 代理有需要。

                        本文网络结构为单臂旁路由

                        本文中所有配置已在 Arch Linux (Kernel: 6.0.10) 环境下测试成功,如在其它环境中同理

                        注意安装相应程序 # sudo apt install iptables ip6tables# sudo apt install nftables

                        ',5),g={href:"https://github.com/XTLS/Xray-core/releases/download/v1.7.0/Xray-linux-64.zip",target:"_blank",rel:"noopener noreferrer"},y={href:"https://github.com/XTLS/Xray-install/blob/main/install-release.sh",target:"_blank",rel:"noopener noreferrer"},h=s("code",null,"# chmod 700 install-release.sh",-1),f=s("code",null,"# ./install-release.sh --local Xray-linux-64.zip",-1),x=t(`

                        Xray 配置

                        客户端配置

                        {
                        +import{_ as p,r as o,o as l,c as i,a as s,b as n,d as e,e as t}from"./app-UOvWaKji.js";const r={},c=s("h1",{id:"tproxy-透明代理-ipv4-and-ipv6-配置教程",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#tproxy-透明代理-ipv4-and-ipv6-配置教程"},[s("span",null,"TProxy 透明代理(ipv4 and ipv6)配置教程")])],-1),u={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},d={href:"https://xtls.github.io/document/level-2/tproxy.html#%E5%BC%80%E5%A7%8B%E4%B9%8B%E5%89%8D",target:"_blank",rel:"noopener noreferrer"},v={href:"https://xtls.github.io/document/level-2/iptables_gid.html",target:"_blank",rel:"noopener noreferrer"},k={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},m={href:"https://github.com/chika0801/Xray-examples",target:"_blank",rel:"noopener noreferrer"},b={href:"https://github.com/lxhao61/integrated-examples",target:"_blank",rel:"noopener noreferrer"},q=t('

                        注意

                        若使用其他配置,你需要着重注意客户端配置中 outboundtagproxy 的部分,其他部分不变

                        服务端配置也要同时改变

                        此配置意在解决例如 Netflix 等默认使用 ipv6 连接的网站无法通过旁路由进行代理的问题,或对 ipv6 代理有需要。

                        本文网络结构为单臂旁路由

                        本文中所有配置已在 Arch Linux (Kernel: 6.0.10) 环境下测试成功,如在其它环境中同理

                        注意安装相应程序 # sudo apt install iptables ip6tables# sudo apt install nftables

                        ',5),g={href:"https://github.com/XTLS/Xray-core/releases/download/v1.7.0/Xray-linux-64.zip",target:"_blank",rel:"noopener noreferrer"},y={href:"https://github.com/XTLS/Xray-install/blob/main/install-release.sh",target:"_blank",rel:"noopener noreferrer"},h=s("code",null,"# chmod 700 install-release.sh",-1),f=s("code",null,"# ./install-release.sh --local Xray-linux-64.zip",-1),x=t(`

                        Xray 配置

                        客户端配置

                        {
                           "log": {
                             "loglevel": "warning"
                           },
                        diff --git a/assets/tproxy_ipv4_and_ipv6.html-dQ2QtiC-.js b/assets/tproxy_ipv4_and_ipv6.html-mtR0hhvb.js
                        similarity index 99%
                        rename from assets/tproxy_ipv4_and_ipv6.html-dQ2QtiC-.js
                        rename to assets/tproxy_ipv4_and_ipv6.html-mtR0hhvb.js
                        index a17a99fe07..e12da26b18 100644
                        --- a/assets/tproxy_ipv4_and_ipv6.html-dQ2QtiC-.js
                        +++ b/assets/tproxy_ipv4_and_ipv6.html-mtR0hhvb.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as o,o as l,c as i,a as s,b as n,d as e,e as t}from"./app-PDrbPfzp.js";const r={},c=s("h1",{id:"tproxy-透明代理-ipv4-and-ipv6-配置教程",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#tproxy-透明代理-ipv4-and-ipv6-配置教程"},[s("span",null,"TProxy 透明代理(ipv4 and ipv6)配置教程")])],-1),u={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},d={href:"https://xtls.github.io/document/level-2/tproxy.html#%E5%BC%80%E5%A7%8B%E4%B9%8B%E5%89%8D",target:"_blank",rel:"noopener noreferrer"},v={href:"https://xtls.github.io/document/level-2/iptables_gid.html",target:"_blank",rel:"noopener noreferrer"},k={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},m={href:"https://github.com/chika0801/Xray-examples",target:"_blank",rel:"noopener noreferrer"},b={href:"https://github.com/lxhao61/integrated-examples",target:"_blank",rel:"noopener noreferrer"},q=t('

                        注意

                        若使用其他配置,你需要着重注意客户端配置中 outboundtagproxy 的部分,其他部分不变

                        服务端配置也要同时改变

                        此配置意在解决例如 Netflix 等默认使用 ipv6 连接的网站无法通过旁路由进行代理的问题,或对 ipv6 代理有需要。

                        本文网络结构为单臂旁路由

                        本文中所有配置已在 Arch Linux (Kernel: 6.0.10) 环境下测试成功,如在其它环境中同理

                        注意安装相应程序 # sudo apt install iptables ip6tables# sudo apt install nftables

                        ',5),g={href:"https://github.com/XTLS/Xray-core/releases/download/v1.7.0/Xray-linux-64.zip",target:"_blank",rel:"noopener noreferrer"},y={href:"https://github.com/XTLS/Xray-install/blob/main/install-release.sh",target:"_blank",rel:"noopener noreferrer"},h=s("code",null,"# chmod 700 install-release.sh",-1),f=s("code",null,"# ./install-release.sh --local Xray-linux-64.zip",-1),x=t(`

                        Xray 配置

                        客户端配置

                        {
                        +import{_ as p,r as o,o as l,c as i,a as s,b as n,d as e,e as t}from"./app-UOvWaKji.js";const r={},c=s("h1",{id:"tproxy-透明代理-ipv4-and-ipv6-配置教程",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#tproxy-透明代理-ipv4-and-ipv6-配置教程"},[s("span",null,"TProxy 透明代理(ipv4 and ipv6)配置教程")])],-1),u={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},d={href:"https://xtls.github.io/document/level-2/tproxy.html#%E5%BC%80%E5%A7%8B%E4%B9%8B%E5%89%8D",target:"_blank",rel:"noopener noreferrer"},v={href:"https://xtls.github.io/document/level-2/iptables_gid.html",target:"_blank",rel:"noopener noreferrer"},k={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},m={href:"https://github.com/chika0801/Xray-examples",target:"_blank",rel:"noopener noreferrer"},b={href:"https://github.com/lxhao61/integrated-examples",target:"_blank",rel:"noopener noreferrer"},q=t('

                        注意

                        若使用其他配置,你需要着重注意客户端配置中 outboundtagproxy 的部分,其他部分不变

                        服务端配置也要同时改变

                        此配置意在解决例如 Netflix 等默认使用 ipv6 连接的网站无法通过旁路由进行代理的问题,或对 ipv6 代理有需要。

                        本文网络结构为单臂旁路由

                        本文中所有配置已在 Arch Linux (Kernel: 6.0.10) 环境下测试成功,如在其它环境中同理

                        注意安装相应程序 # sudo apt install iptables ip6tables# sudo apt install nftables

                        ',5),g={href:"https://github.com/XTLS/Xray-core/releases/download/v1.7.0/Xray-linux-64.zip",target:"_blank",rel:"noopener noreferrer"},y={href:"https://github.com/XTLS/Xray-install/blob/main/install-release.sh",target:"_blank",rel:"noopener noreferrer"},h=s("code",null,"# chmod 700 install-release.sh",-1),f=s("code",null,"# ./install-release.sh --local Xray-linux-64.zip",-1),x=t(`

                        Xray 配置

                        客户端配置

                        {
                           "log": {
                             "loglevel": "warning"
                           },
                        diff --git a/assets/traffic_stats.html-vi4G-DEd.js b/assets/traffic_stats.html-HWyX5twA.js
                        similarity index 99%
                        rename from assets/traffic_stats.html-vi4G-DEd.js
                        rename to assets/traffic_stats.html-HWyX5twA.js
                        index 843c59fa1d..28e8f83d7b 100644
                        --- a/assets/traffic_stats.html-vi4G-DEd.js
                        +++ b/assets/traffic_stats.html-HWyX5twA.js
                        @@ -1,4 +1,4 @@
                        -import{_ as t,r as e,o as p,c as o,a as s,b as n,d as l,e as i}from"./app-PDrbPfzp.js";const c={},u=s("h1",{id:"流量统计配置教程",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#流量统计配置教程"},[s("span",null,"流量统计配置教程")])],-1),r={href:"https://guide.v2fly.org/advanced/traffic.html",target:"_blank",rel:"noopener noreferrer"},d=i(`

                        查看流量信息

                        配置方法与 v2fly 一致。 查看流量信息是 xray 命令行的其中一个功能。配置内设置的 api dokodemo-door 端口,即为 --server 参数的端口。

                        xray api statsquery --server=127.0.0.1:10085 #查看所有流量
                        +import{_ as t,r as e,o as p,c as o,a as s,b as n,d as l,e as i}from"./app-UOvWaKji.js";const c={},u=s("h1",{id:"流量统计配置教程",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#流量统计配置教程"},[s("span",null,"流量统计配置教程")])],-1),r={href:"https://guide.v2fly.org/advanced/traffic.html",target:"_blank",rel:"noopener noreferrer"},d=i(`

                        查看流量信息

                        配置方法与 v2fly 一致。 查看流量信息是 xray 命令行的其中一个功能。配置内设置的 api dokodemo-door 端口,即为 --server 参数的端口。

                        xray api statsquery --server=127.0.0.1:10085 #查看所有流量
                         xray help api statsquery #statsquery 查询匹配的记录
                         xray help api stats #stats 查询一个记录
                         

                        输出例子:

                        {
                        diff --git a/assets/traffic_stats.html-BjBI1-3n.js b/assets/traffic_stats.html-qY70pWXT.js
                        similarity index 99%
                        rename from assets/traffic_stats.html-BjBI1-3n.js
                        rename to assets/traffic_stats.html-qY70pWXT.js
                        index 843c59fa1d..28e8f83d7b 100644
                        --- a/assets/traffic_stats.html-BjBI1-3n.js
                        +++ b/assets/traffic_stats.html-qY70pWXT.js
                        @@ -1,4 +1,4 @@
                        -import{_ as t,r as e,o as p,c as o,a as s,b as n,d as l,e as i}from"./app-PDrbPfzp.js";const c={},u=s("h1",{id:"流量统计配置教程",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#流量统计配置教程"},[s("span",null,"流量统计配置教程")])],-1),r={href:"https://guide.v2fly.org/advanced/traffic.html",target:"_blank",rel:"noopener noreferrer"},d=i(`

                        查看流量信息

                        配置方法与 v2fly 一致。 查看流量信息是 xray 命令行的其中一个功能。配置内设置的 api dokodemo-door 端口,即为 --server 参数的端口。

                        xray api statsquery --server=127.0.0.1:10085 #查看所有流量
                        +import{_ as t,r as e,o as p,c as o,a as s,b as n,d as l,e as i}from"./app-UOvWaKji.js";const c={},u=s("h1",{id:"流量统计配置教程",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#流量统计配置教程"},[s("span",null,"流量统计配置教程")])],-1),r={href:"https://guide.v2fly.org/advanced/traffic.html",target:"_blank",rel:"noopener noreferrer"},d=i(`

                        查看流量信息

                        配置方法与 v2fly 一致。 查看流量信息是 xray 命令行的其中一个功能。配置内设置的 api dokodemo-door 端口,即为 --server 参数的端口。

                        xray api statsquery --server=127.0.0.1:10085 #查看所有流量
                         xray help api statsquery #statsquery 查询匹配的记录
                         xray help api stats #stats 查询一个记录
                         

                        输出例子:

                        {
                        diff --git a/assets/transparent_proxy.html-D-ct__hG.js b/assets/transparent_proxy.html-RiPSpqp_.js
                        similarity index 99%
                        rename from assets/transparent_proxy.html-D-ct__hG.js
                        rename to assets/transparent_proxy.html-RiPSpqp_.js
                        index 2b7e2687f9..42f63a3605 100644
                        --- a/assets/transparent_proxy.html-D-ct__hG.js
                        +++ b/assets/transparent_proxy.html-RiPSpqp_.js
                        @@ -1,4 +1,4 @@
                        -import{_ as o,r,o as i,c,a,b as s,d as n,w as l,e as p}from"./app-PDrbPfzp.js";const d="/assets/netfilter-3mRQhe-K.png",u={},b=p('

                        透明代理入门

                        什么是透明代理

                        透明代理简单地说就是不让被代理的设备感觉到自己被代理了。简单地说就是,被代理的设备上不需要运行任何代理软件(比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。

                        这也意味着,代理的软件运行在别的地方,比如运行在路由器中,通过路由器上网的设备就自动被代理了。

                        透明代理的实现

                        透明代理的实现目前主要有两种方式:

                        tun2socks

                        可用 Windows/Linux(包括安卓)实现。因为实现过程比较简单,很少有教程,我这里简单描述一下。

                        Windows

                        ',9),m={href:"https://github.com/NetchX/Netch/releases",target:"_blank",rel:"noopener noreferrer"},v=a("code",null,"[3] [TUN/TAP] 绕过局域网",-1),k=p("
                      60. 开启热点

                      61. 打开控制面板->网络和 Internet->网络和共享中心->更改适配器设置,找到TAP-Windows AdapterMicrosoft Wi-Fi Direct Virtual Adapter

                      62. 鼠标右键点击TAP-Windows Adapter属性->共享,勾选允许其他网络用户通过此计算机的 Internet 连接来连接,在家庭网络连接中选择Microsoft Wi-Fi Direct Virtual Adapter的那个网络连接,点击确定。

                      63. ",3),h=p('

                        Android

                        1. 配置连接 V2RayNG

                        2. 开启热点

                        3. 热点设置 -> 允许热点使用 VPN(部分安卓系统可能没有这个选项)

                        iptables/nftables

                        iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。

                        基于 iptables 的透明代理实现只能用于 Linux 系统(包括 openwrt/安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而广泛使用。

                        ',5),g={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},R={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},A=p('

                        iptables 实现透明代理原理

                        Linux 使用Netfilter来管理网络,Netfilter模型如下:

                        Netfilter

                        假设使用路由器作为网关(即我们平时的上网方式),那么:

                        局域网设备通过路由器访问互联网的流量方向:

                        PREROUTING链->FORWARD链->POSTINGROUTING链

                        局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:

                        PREROUTING链->INPUT链->网关本机

                        路由器访问互联网的流量方向:

                        网关本机->OUTPUT链->POSTINGROUTING链

                        通过使用 iptables 操控PREROUTING链OUTPUT链的流量走向,转发到 Xray,就可以代理局域网设备和网关本机。

                        透明代理难在哪里

                        透明代理的难点就在于路由,所谓路由,就是区分哪些流量是直连的,哪些该被代理,所以我个人认为叫做分流更加合适。

                        我们可以把路由由易到难分为以下几个阶段:

                        1. 代理全部请求

                        2. 本地局域网 IP/组播 IP 请求直连,其它请求代理

                        3. 在 2 的基础上直连 Xray 发起的连接请求

                        4. 在 3 的基础上直连指向中国大陆 IP 的连接请求,并对国内外域名选择国内外 DNS 服务器解析。

                        上面说的三篇教程,都是在第四阶段。所以新手直接阅读可能显得有点难懂。

                        从零开始一步步实现基于 iptables-tproxy 的透明代理

                        在开始之前,你需要有一定的基础知识:

                        1. 大概知道什么是 TCP/IP 协议、域名和 DNS 服务器

                        2. 知道什么是 WAN 口,LAN 口,LAN_IP,WAN_IP 以及 DHCP 服务器。对于旁路由,只有一个网口,这里称其为 LAN 口

                        3. 对 Linux 系统有最基础的了解(知道怎么运行命令)

                        4. 能够手写客户端 json 文件配置,至少要能看懂

                        前期准备工作

                        1. 准备一个运行 Linux 系统的网关

                        比如,刷了 OpenWRT 的路由器

                        2. 在网关(路由器)准备好 Xray 可执行文件以及配置文件

                        配置文件监听 12345 端口,开启 tproxy:

                        {
                        +import{_ as o,r,o as i,c,a,b as s,d as n,w as l,e as p}from"./app-UOvWaKji.js";const d="/assets/netfilter-3mRQhe-K.png",u={},b=p('

                        透明代理入门

                        什么是透明代理

                        透明代理简单地说就是不让被代理的设备感觉到自己被代理了。简单地说就是,被代理的设备上不需要运行任何代理软件(比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。

                        这也意味着,代理的软件运行在别的地方,比如运行在路由器中,通过路由器上网的设备就自动被代理了。

                        透明代理的实现

                        透明代理的实现目前主要有两种方式:

                        tun2socks

                        可用 Windows/Linux(包括安卓)实现。因为实现过程比较简单,很少有教程,我这里简单描述一下。

                        Windows

                        ',9),m={href:"https://github.com/NetchX/Netch/releases",target:"_blank",rel:"noopener noreferrer"},v=a("code",null,"[3] [TUN/TAP] 绕过局域网",-1),k=p("
                      64. 开启热点

                      65. 打开控制面板->网络和 Internet->网络和共享中心->更改适配器设置,找到TAP-Windows AdapterMicrosoft Wi-Fi Direct Virtual Adapter

                      66. 鼠标右键点击TAP-Windows Adapter属性->共享,勾选允许其他网络用户通过此计算机的 Internet 连接来连接,在家庭网络连接中选择Microsoft Wi-Fi Direct Virtual Adapter的那个网络连接,点击确定。

                      67. ",3),h=p('

                        Android

                        1. 配置连接 V2RayNG

                        2. 开启热点

                        3. 热点设置 -> 允许热点使用 VPN(部分安卓系统可能没有这个选项)

                        iptables/nftables

                        iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。

                        基于 iptables 的透明代理实现只能用于 Linux 系统(包括 openwrt/安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而广泛使用。

                        ',5),g={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},R={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},A=p('

                        iptables 实现透明代理原理

                        Linux 使用Netfilter来管理网络,Netfilter模型如下:

                        Netfilter

                        假设使用路由器作为网关(即我们平时的上网方式),那么:

                        局域网设备通过路由器访问互联网的流量方向:

                        PREROUTING链->FORWARD链->POSTINGROUTING链

                        局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:

                        PREROUTING链->INPUT链->网关本机

                        路由器访问互联网的流量方向:

                        网关本机->OUTPUT链->POSTINGROUTING链

                        通过使用 iptables 操控PREROUTING链OUTPUT链的流量走向,转发到 Xray,就可以代理局域网设备和网关本机。

                        透明代理难在哪里

                        透明代理的难点就在于路由,所谓路由,就是区分哪些流量是直连的,哪些该被代理,所以我个人认为叫做分流更加合适。

                        我们可以把路由由易到难分为以下几个阶段:

                        1. 代理全部请求

                        2. 本地局域网 IP/组播 IP 请求直连,其它请求代理

                        3. 在 2 的基础上直连 Xray 发起的连接请求

                        4. 在 3 的基础上直连指向中国大陆 IP 的连接请求,并对国内外域名选择国内外 DNS 服务器解析。

                        上面说的三篇教程,都是在第四阶段。所以新手直接阅读可能显得有点难懂。

                        从零开始一步步实现基于 iptables-tproxy 的透明代理

                        在开始之前,你需要有一定的基础知识:

                        1. 大概知道什么是 TCP/IP 协议、域名和 DNS 服务器

                        2. 知道什么是 WAN 口,LAN 口,LAN_IP,WAN_IP 以及 DHCP 服务器。对于旁路由,只有一个网口,这里称其为 LAN 口

                        3. 对 Linux 系统有最基础的了解(知道怎么运行命令)

                        4. 能够手写客户端 json 文件配置,至少要能看懂

                        前期准备工作

                        1. 准备一个运行 Linux 系统的网关

                        比如,刷了 OpenWRT 的路由器

                        2. 在网关(路由器)准备好 Xray 可执行文件以及配置文件

                        配置文件监听 12345 端口,开启 tproxy:

                        {
                           "log": {
                             "loglevel": "warning"
                           },
                        diff --git a/assets/transparent_proxy.html-oZsJizmp.js b/assets/transparent_proxy.html-bIbjewZt.js
                        similarity index 99%
                        rename from assets/transparent_proxy.html-oZsJizmp.js
                        rename to assets/transparent_proxy.html-bIbjewZt.js
                        index d19071aca0..68a828daf9 100644
                        --- a/assets/transparent_proxy.html-oZsJizmp.js
                        +++ b/assets/transparent_proxy.html-bIbjewZt.js
                        @@ -1,4 +1,4 @@
                        -import{_ as o,r,o as i,c,a,b as s,d as n,w as l,e as p}from"./app-PDrbPfzp.js";const d="/assets/netfilter-3mRQhe-K.png",u={},b=p('

                        透明代理入门

                        什么是透明代理

                        透明代理简单地说就是不让被代理的设备感觉到自己被代理了。简单地说就是,被代理的设备上不需要运行任何代理软件(比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。

                        这也意味着,代理的软件运行在别的地方,比如运行在路由器中,通过路由器上网的设备就自动被代理了。

                        透明代理的实现

                        透明代理的实现目前主要有两种方式:

                        tun2socks

                        可用 Windows/Linux(包括安卓)实现。因为实现过程比较简单,很少有教程,我这里简单描述一下。

                        Windows

                        ',9),m={href:"https://github.com/NetchX/Netch/releases",target:"_blank",rel:"noopener noreferrer"},v=a("code",null,"[3] [TUN/TAP] 绕过局域网",-1),k=p("
                      68. 开启热点

                      69. 打开控制面板->网络和 Internet->网络和共享中心->更改适配器设置,找到TAP-Windows AdapterMicrosoft Wi-Fi Direct Virtual Adapter

                      70. 鼠标右键点击TAP-Windows Adapter属性->共享,勾选允许其他网络用户通过此计算机的 Internet 连接来连接,在家庭网络连接中选择Microsoft Wi-Fi Direct Virtual Adapter的那个网络连接,点击确定。

                      71. ",3),h=p('

                        Android

                        1. 配置连接 V2RayNG

                        2. 开启热点

                        3. 热点设置 -> 允许热点使用 VPN(部分安卓系统可能没有这个选项)

                        iptables/nftables

                        iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。

                        基于 iptables 的透明代理实现只能用于 Linux 系统(包括 openwrt/安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而广泛使用。

                        ',5),g={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},R={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},A=p('

                        iptables 实现透明代理原理

                        Linux 使用Netfilter来管理网络,Netfilter模型如下:

                        Netfilter

                        假设使用路由器作为网关(即我们平时的上网方式),那么:

                        局域网设备通过路由器访问互联网的流量方向:

                        PREROUTING链->FORWARD链->POSTINGROUTING链

                        局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:

                        PREROUTING链->INPUT链->网关本机

                        路由器访问互联网的流量方向:

                        网关本机->OUTPUT链->POSTINGROUTING链

                        通过使用 iptables 操控PREROUTING链OUTPUT链的流量走向,转发到 Xray,就可以代理局域网设备和网关本机。

                        透明代理难在哪里

                        透明代理的难点就在于路由,所谓路由,就是区分哪些流量是直连的,哪些该被代理,所以我个人认为叫做分流更加合适。

                        我们可以把路由由易到难分为以下几个阶段:

                        1. 代理全部请求

                        2. 本地局域网 IP/组播 IP 请求直连,其它请求代理

                        3. 在 2 的基础上直连 Xray 发起的连接请求

                        4. 在 3 的基础上直连指向中国大陆 IP 的连接请求,并对国内外域名选择国内外 DNS 服务器解析。

                        上面说的三篇教程,都是在第四阶段。所以新手直接阅读可能显得有点难懂。

                        从零开始一步步实现基于 iptables-tproxy 的透明代理

                        在开始之前,你需要有一定的基础知识:

                        1. 大概知道什么是 TCP/IP 协议、域名和 DNS 服务器

                        2. 知道什么是 WAN 口,LAN 口,LAN_IP,WAN_IP 以及 DHCP 服务器。对于旁路由,只有一个网口,这里称其为 LAN 口

                        3. 对 Linux 系统有最基础的了解(知道怎么运行命令)

                        4. 能够手写客户端 json 文件配置,至少要能看懂

                        前期准备工作

                        注意

                        在开始操作前,记得使用 sysctl -w net.ipv4.ip_forward=1 打开linux ipv4封包转发

                        1. 准备一个运行 Linux 系统的网关

                        比如,刷了 OpenWRT 的路由器

                        2. 在网关(路由器)准备好 Xray 可执行文件以及配置文件

                        配置文件监听 12345 端口,开启 tproxy:

                        {
                        +import{_ as o,r,o as i,c,a,b as s,d as n,w as l,e as p}from"./app-UOvWaKji.js";const d="/assets/netfilter-3mRQhe-K.png",u={},b=p('

                        透明代理入门

                        什么是透明代理

                        透明代理简单地说就是不让被代理的设备感觉到自己被代理了。简单地说就是,被代理的设备上不需要运行任何代理软件(比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。

                        这也意味着,代理的软件运行在别的地方,比如运行在路由器中,通过路由器上网的设备就自动被代理了。

                        透明代理的实现

                        透明代理的实现目前主要有两种方式:

                        tun2socks

                        可用 Windows/Linux(包括安卓)实现。因为实现过程比较简单,很少有教程,我这里简单描述一下。

                        Windows

                        ',9),m={href:"https://github.com/NetchX/Netch/releases",target:"_blank",rel:"noopener noreferrer"},v=a("code",null,"[3] [TUN/TAP] 绕过局域网",-1),k=p("
                      72. 开启热点

                      73. 打开控制面板->网络和 Internet->网络和共享中心->更改适配器设置,找到TAP-Windows AdapterMicrosoft Wi-Fi Direct Virtual Adapter

                      74. 鼠标右键点击TAP-Windows Adapter属性->共享,勾选允许其他网络用户通过此计算机的 Internet 连接来连接,在家庭网络连接中选择Microsoft Wi-Fi Direct Virtual Adapter的那个网络连接,点击确定。

                      75. ",3),h=p('

                        Android

                        1. 配置连接 V2RayNG

                        2. 开启热点

                        3. 热点设置 -> 允许热点使用 VPN(部分安卓系统可能没有这个选项)

                        iptables/nftables

                        iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。

                        基于 iptables 的透明代理实现只能用于 Linux 系统(包括 openwrt/安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而广泛使用。

                        ',5),g={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},R={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},A=p('

                        iptables 实现透明代理原理

                        Linux 使用Netfilter来管理网络,Netfilter模型如下:

                        Netfilter

                        假设使用路由器作为网关(即我们平时的上网方式),那么:

                        局域网设备通过路由器访问互联网的流量方向:

                        PREROUTING链->FORWARD链->POSTINGROUTING链

                        局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:

                        PREROUTING链->INPUT链->网关本机

                        路由器访问互联网的流量方向:

                        网关本机->OUTPUT链->POSTINGROUTING链

                        通过使用 iptables 操控PREROUTING链OUTPUT链的流量走向,转发到 Xray,就可以代理局域网设备和网关本机。

                        透明代理难在哪里

                        透明代理的难点就在于路由,所谓路由,就是区分哪些流量是直连的,哪些该被代理,所以我个人认为叫做分流更加合适。

                        我们可以把路由由易到难分为以下几个阶段:

                        1. 代理全部请求

                        2. 本地局域网 IP/组播 IP 请求直连,其它请求代理

                        3. 在 2 的基础上直连 Xray 发起的连接请求

                        4. 在 3 的基础上直连指向中国大陆 IP 的连接请求,并对国内外域名选择国内外 DNS 服务器解析。

                        上面说的三篇教程,都是在第四阶段。所以新手直接阅读可能显得有点难懂。

                        从零开始一步步实现基于 iptables-tproxy 的透明代理

                        在开始之前,你需要有一定的基础知识:

                        1. 大概知道什么是 TCP/IP 协议、域名和 DNS 服务器

                        2. 知道什么是 WAN 口,LAN 口,LAN_IP,WAN_IP 以及 DHCP 服务器。对于旁路由,只有一个网口,这里称其为 LAN 口

                        3. 对 Linux 系统有最基础的了解(知道怎么运行命令)

                        4. 能够手写客户端 json 文件配置,至少要能看懂

                        前期准备工作

                        注意

                        在开始操作前,记得使用 sysctl -w net.ipv4.ip_forward=1 打开linux ipv4封包转发

                        1. 准备一个运行 Linux 系统的网关

                        比如,刷了 OpenWRT 的路由器

                        2. 在网关(路由器)准备好 Xray 可执行文件以及配置文件

                        配置文件监听 12345 端口,开启 tproxy:

                        {
                           "log": {
                             "loglevel": "warning"
                           },
                        diff --git a/assets/transport.html-w0GXOLfO.js b/assets/transport.html-mYn2VrkQ.js
                        similarity index 99%
                        rename from assets/transport.html-w0GXOLfO.js
                        rename to assets/transport.html-mYn2VrkQ.js
                        index bbaf3dd5b1..146ec46922 100644
                        --- a/assets/transport.html-w0GXOLfO.js
                        +++ b/assets/transport.html-mYn2VrkQ.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as c,o as l,c as r,a as e,b as n,d as t,w as o,e as a}from"./app-PDrbPfzp.js";const u={},d=a(`

                        Transport

                        Transports specify how Xray communicates with peers.

                        Transports specify how to achieve stable data transmission. Both ends of a connection often need to specify the same transport protocol to successfully establish a connection. Like, if one end uses WebSocket, the other end must also use WebSocket, or else the connection cannot be established.

                        Transport configuration consists of two parts:

                        1. Global config (TransportObject)
                        2. Local config (StreamSettingsObject).
                        • When locally configured, you can specify how each inbound or outbound connection is transmitted individually.
                        • Server inbounds and client outbounds often need to use the same transport protocol. When a transport protocol is specified without local configs, the transport will fall back to global transport configs.

                        TransportObject

                        The TransportObject corresponds to the transport property in the config root.

                        {
                        +import{_ as p,r as c,o as l,c as r,a as e,b as n,d as t,w as o,e as a}from"./app-UOvWaKji.js";const u={},d=a(`

                        Transport

                        Transports specify how Xray communicates with peers.

                        Transports specify how to achieve stable data transmission. Both ends of a connection often need to specify the same transport protocol to successfully establish a connection. Like, if one end uses WebSocket, the other end must also use WebSocket, or else the connection cannot be established.

                        Transport configuration consists of two parts:

                        1. Global config (TransportObject)
                        2. Local config (StreamSettingsObject).
                        • When locally configured, you can specify how each inbound or outbound connection is transmitted individually.
                        • Server inbounds and client outbounds often need to use the same transport protocol. When a transport protocol is specified without local configs, the transport will fall back to global transport configs.

                        TransportObject

                        The TransportObject corresponds to the transport property in the config root.

                        {
                           "transport": {
                             "tcpSettings": {},
                             "kcpSettings": {},
                        diff --git a/assets/transport.html-fjf1PegS.js b/assets/transport.html-yVjoGdDV.js
                        similarity index 99%
                        rename from assets/transport.html-fjf1PegS.js
                        rename to assets/transport.html-yVjoGdDV.js
                        index b92380a4a3..a1253f09d9 100644
                        --- a/assets/transport.html-fjf1PegS.js
                        +++ b/assets/transport.html-yVjoGdDV.js
                        @@ -1,4 +1,4 @@
                        -import{_ as l,r as c,o as u,c as i,a as n,b as s,d as t,w as e,e as a}from"./app-PDrbPfzp.js";const r={},d=a(`

                        传输方式

                        传输方式(transport)是当前 Xray 节点和其它节点对接的方式。

                        传输方式指定了稳定的数据传输的方式。通常来说,一个网络连接的两端需要有对称的传输方式。比如一端用了 WebSocket,那么另一个端也必须使用 WebSocket,否则无法建立连接。

                        传输方式(transport)配置有两部分:

                        1. 全局配置(TransportObject
                        2. 局部配置(StreamSettingsObject)。
                        • 局部配置时,可以指定每个单独的入站或出站用怎样的方式传输。
                        • 通常来说客户端和服务器对应的入站和出站需要使用同样的传输方式。当其配置指定了一种传输方式,但没有填写具体设置时,此传输方式会使用全局配置中的设置。

                        TransportObject

                        TransportObject 对应配置文件的 transport 项。

                        {
                        +import{_ as l,r as c,o as u,c as i,a as n,b as s,d as t,w as e,e as a}from"./app-UOvWaKji.js";const r={},d=a(`

                        传输方式

                        传输方式(transport)是当前 Xray 节点和其它节点对接的方式。

                        传输方式指定了稳定的数据传输的方式。通常来说,一个网络连接的两端需要有对称的传输方式。比如一端用了 WebSocket,那么另一个端也必须使用 WebSocket,否则无法建立连接。

                        传输方式(transport)配置有两部分:

                        1. 全局配置(TransportObject
                        2. 局部配置(StreamSettingsObject)。
                        • 局部配置时,可以指定每个单独的入站或出站用怎样的方式传输。
                        • 通常来说客户端和服务器对应的入站和出站需要使用同样的传输方式。当其配置指定了一种传输方式,但没有填写具体设置时,此传输方式会使用全局配置中的设置。

                        TransportObject

                        TransportObject 对应配置文件的 transport 项。

                        {
                           "transport": {
                             "tcpSettings": {},
                             "kcpSettings": {},
                        diff --git a/assets/trojan.html-LeKVwimm.js b/assets/trojan.html-5IABW9eX.js
                        similarity index 98%
                        rename from assets/trojan.html-LeKVwimm.js
                        rename to assets/trojan.html-5IABW9eX.js
                        index 9e78aece48..38f3da4ebe 100644
                        --- a/assets/trojan.html-LeKVwimm.js
                        +++ b/assets/trojan.html-5IABW9eX.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as o,o as p,c as r,a as e,b as n,d as a,w as t,e as l}from"./app-PDrbPfzp.js";const u={},d=e("h1",{id:"trojan",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trojan"},[e("span",null,"Trojan")])],-1),b={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},k=l(`

                        Danger

                        Trojan is designed to work with correctly configured encrypted TLS tunnels.

                        InboundConfigurationObject

                        {
                        +import{_ as i,r as o,o as p,c as r,a as e,b as n,d as a,w as t,e as l}from"./app-UOvWaKji.js";const u={},d=e("h1",{id:"trojan",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trojan"},[e("span",null,"Trojan")])],-1),b={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},k=l(`

                        Danger

                        Trojan is designed to work with correctly configured encrypted TLS tunnels.

                        InboundConfigurationObject

                        {
                           "clients": [
                             {
                               "password": "password",
                        diff --git a/assets/trojan.html-8Xtn_ZhO.js b/assets/trojan.html-MDx9UVlc.js
                        similarity index 98%
                        rename from assets/trojan.html-8Xtn_ZhO.js
                        rename to assets/trojan.html-MDx9UVlc.js
                        index c76e9252ef..a9443896f9 100644
                        --- a/assets/trojan.html-8Xtn_ZhO.js
                        +++ b/assets/trojan.html-MDx9UVlc.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as t,o as i,c as r,a as s,b as n,d as a,w as o,e as l}from"./app-PDrbPfzp.js";const u={},d=s("h1",{id:"trojan",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#trojan"},[s("span",null,"Trojan")])],-1),b={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},k=l(`

                        警告

                        Trojan 被设计工作在正确配置的加密 TLS 隧道

                        InboundConfigurationObject

                        {
                        +import{_ as p,r as t,o as i,c as r,a as s,b as n,d as a,w as o,e as l}from"./app-UOvWaKji.js";const u={},d=s("h1",{id:"trojan",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#trojan"},[s("span",null,"Trojan")])],-1),b={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},k=l(`

                        警告

                        Trojan 被设计工作在正确配置的加密 TLS 隧道

                        InboundConfigurationObject

                        {
                           "clients": [
                             {
                               "password": "password",
                        diff --git a/assets/trojan.html-ID_eR97m.js b/assets/trojan.html-O_FJql5l.js
                        similarity index 98%
                        rename from assets/trojan.html-ID_eR97m.js
                        rename to assets/trojan.html-O_FJql5l.js
                        index 21e04e1878..e647618ab2 100644
                        --- a/assets/trojan.html-ID_eR97m.js
                        +++ b/assets/trojan.html-O_FJql5l.js
                        @@ -1,4 +1,4 @@
                        -import{_ as r,r as o,o as c,c as l,a as s,b as n,d as e,w as t,e as i}from"./app-PDrbPfzp.js";const u={},d=s("h1",{id:"trojan",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#trojan"},[s("span",null,"Trojan")])],-1),v={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},k=i(`

                        Danger

                        Trojan is designed to work with correctly configured encrypted TLS tunnels.

                        OutboundConfigurationObject

                        {
                        +import{_ as r,r as o,o as c,c as l,a as s,b as n,d as e,w as t,e as i}from"./app-UOvWaKji.js";const u={},d=s("h1",{id:"trojan",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#trojan"},[s("span",null,"Trojan")])],-1),v={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},k=i(`

                        Danger

                        Trojan is designed to work with correctly configured encrypted TLS tunnels.

                        OutboundConfigurationObject

                        {
                           "servers": [
                             {
                               "address": "127.0.0.1",
                        diff --git a/assets/trojan.html-qii0knEl.js b/assets/trojan.html-zN8km5_s.js
                        similarity index 98%
                        rename from assets/trojan.html-qii0knEl.js
                        rename to assets/trojan.html-zN8km5_s.js
                        index 30e5e9f4e5..087617f664 100644
                        --- a/assets/trojan.html-qii0knEl.js
                        +++ b/assets/trojan.html-zN8km5_s.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as o,o as r,c as l,a as s,b as n,d as a,w as t,e as i}from"./app-PDrbPfzp.js";const u={},d=s("h1",{id:"trojan",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#trojan"},[s("span",null,"Trojan")])],-1),v={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},k=i(`

                        警告

                        Trojan 被设计工作在正确配置的加密 TLS 隧道

                        OutboundConfigurationObject

                        {
                        +import{_ as c,r as o,o as r,c as l,a as s,b as n,d as a,w as t,e as i}from"./app-UOvWaKji.js";const u={},d=s("h1",{id:"trojan",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#trojan"},[s("span",null,"Trojan")])],-1),v={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},k=i(`

                        警告

                        Trojan 被设计工作在正确配置的加密 TLS 隧道

                        OutboundConfigurationObject

                        {
                           "servers": [
                             {
                               "address": "127.0.0.1",
                        diff --git a/assets/vless.html-atmKcdJ9.js b/assets/vless.html--6fAlyfP.js
                        similarity index 99%
                        rename from assets/vless.html-atmKcdJ9.js
                        rename to assets/vless.html--6fAlyfP.js
                        index eb7c08c9f6..d773e897f8 100644
                        --- a/assets/vless.html-atmKcdJ9.js
                        +++ b/assets/vless.html--6fAlyfP.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as l,o as i,c as u,a as n,b as s,d as e,w as a,e as t}from"./app-PDrbPfzp.js";const r={},d=n("h1",{id:"vless",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#vless"},[n("span",null,"VLESS")])],-1),k=n("div",{class:"custom-container danger"},[n("p",{class:"custom-container-title"},"警告"),n("p",null,"目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。")],-1),b=n("p",null,"VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。",-1),v=t(`

                        InboundConfigurationObject

                        {
                        +import{_ as p,r as l,o as i,c as u,a as n,b as s,d as e,w as a,e as t}from"./app-UOvWaKji.js";const r={},d=n("h1",{id:"vless",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#vless"},[n("span",null,"VLESS")])],-1),k=n("div",{class:"custom-container danger"},[n("p",{class:"custom-container-title"},"警告"),n("p",null,"目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。")],-1),b=n("p",null,"VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。",-1),v=t(`

                        InboundConfigurationObject

                        {
                           "clients": [
                             {
                               "id": "5783a3e7-e373-51cd-8642-c83782b807c5",
                        diff --git a/assets/vless.html-462FM1ut.js b/assets/vless.html-62T-Q8OK.js
                        similarity index 99%
                        rename from assets/vless.html-462FM1ut.js
                        rename to assets/vless.html-62T-Q8OK.js
                        index 9a6b07b7de..f01fcb69eb 100644
                        --- a/assets/vless.html-462FM1ut.js
                        +++ b/assets/vless.html-62T-Q8OK.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as a,o as r,c as l,a as n,b as e,d as s,w as t,e as i}from"./app-PDrbPfzp.js";const u={},d=n("h1",{id:"vless",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#vless"},[n("span",null,"VLESS")])],-1),v=n("div",{class:"custom-container danger"},[n("p",{class:"custom-container-title"},"Danger"),n("p",null,"Currently, VLESS does not have built-in encryption, please use it on a reliable channel, such as TLS.")],-1),h=n("p",null,"VLESS is a stateless lightweight transport protocol, which is divided into inbound and outbound parts, and can be used as a bridge between Xray clients and servers.",-1),m=i(`

                        OutboundConfigurationObject

                        {
                        +import{_ as c,r as a,o as r,c as l,a as n,b as e,d as s,w as t,e as i}from"./app-UOvWaKji.js";const u={},d=n("h1",{id:"vless",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#vless"},[n("span",null,"VLESS")])],-1),v=n("div",{class:"custom-container danger"},[n("p",{class:"custom-container-title"},"Danger"),n("p",null,"Currently, VLESS does not have built-in encryption, please use it on a reliable channel, such as TLS.")],-1),h=n("p",null,"VLESS is a stateless lightweight transport protocol, which is divided into inbound and outbound parts, and can be used as a bridge between Xray clients and servers.",-1),m=i(`

                        OutboundConfigurationObject

                        {
                           "vnext": [
                             {
                               "address": "example.com",
                        diff --git a/assets/vless.html-ydRLwf6Z.js b/assets/vless.html-K1mymGPl.js
                        similarity index 99%
                        rename from assets/vless.html-ydRLwf6Z.js
                        rename to assets/vless.html-K1mymGPl.js
                        index 006e54788e..e3d49d7236 100644
                        --- a/assets/vless.html-ydRLwf6Z.js
                        +++ b/assets/vless.html-K1mymGPl.js
                        @@ -1,4 +1,4 @@
                        -import{_ as l,r as t,o as i,c as u,a as n,b as s,d as e,w as a,e as p}from"./app-PDrbPfzp.js";const r={},d=n("h1",{id:"vless",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#vless"},[n("span",null,"VLESS")])],-1),v=n("div",{class:"custom-container danger"},[n("p",{class:"custom-container-title"},"警告"),n("p",null,"目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。")],-1),k=n("p",null,"VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。",-1),b=p(`

                        OutboundConfigurationObject

                        {
                        +import{_ as l,r as t,o as i,c as u,a as n,b as s,d as e,w as a,e as p}from"./app-UOvWaKji.js";const r={},d=n("h1",{id:"vless",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#vless"},[n("span",null,"VLESS")])],-1),v=n("div",{class:"custom-container danger"},[n("p",{class:"custom-container-title"},"警告"),n("p",null,"目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。")],-1),k=n("p",null,"VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。",-1),b=p(`

                        OutboundConfigurationObject

                        {
                           "vnext": [
                             {
                               "address": "example.com",
                        diff --git a/assets/vless.html-3H2ueBQw.js b/assets/vless.html-RePhqH5Q.js
                        similarity index 99%
                        rename from assets/vless.html-3H2ueBQw.js
                        rename to assets/vless.html-RePhqH5Q.js
                        index ff61e2bedf..b031f7c3d0 100644
                        --- a/assets/vless.html-3H2ueBQw.js
                        +++ b/assets/vless.html-RePhqH5Q.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as l,o as r,c as p,a as n,b as e,d as s,w as t,e as a}from"./app-PDrbPfzp.js";const u={},d=n("h1",{id:"vless",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#vless"},[n("span",null,"VLESS")])],-1),h=n("div",{class:"custom-container danger"},[n("p",{class:"custom-container-title"},"Danger"),n("p",null,"Currently, VLESS does not provide built-in encryption. Please use it with a reliable channel, such as TLS.")],-1),b=n("p",null,"VLESS is a stateless lightweight transport protocol that consists of inbound and outbound parts. It can serve as a bridge between Xray clients and servers.",-1),m=a(`

                        InboundConfigurationObject

                        {
                        +import{_ as i,r as l,o as r,c as p,a as n,b as e,d as s,w as t,e as a}from"./app-UOvWaKji.js";const u={},d=n("h1",{id:"vless",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#vless"},[n("span",null,"VLESS")])],-1),h=n("div",{class:"custom-container danger"},[n("p",{class:"custom-container-title"},"Danger"),n("p",null,"Currently, VLESS does not provide built-in encryption. Please use it with a reliable channel, such as TLS.")],-1),b=n("p",null,"VLESS is a stateless lightweight transport protocol that consists of inbound and outbound parts. It can serve as a bridge between Xray clients and servers.",-1),m=a(`

                        InboundConfigurationObject

                        {
                           "clients": [
                             {
                               "id": "5783a3e7-e373-51cd-8642-c83782b807c5",
                        diff --git a/assets/vless.html-hLM6-o-1.js b/assets/vless.html-TuQcbXVI.js
                        similarity index 99%
                        rename from assets/vless.html-hLM6-o-1.js
                        rename to assets/vless.html-TuQcbXVI.js
                        index 65222ccd61..191fc4691f 100644
                        --- a/assets/vless.html-hLM6-o-1.js
                        +++ b/assets/vless.html-TuQcbXVI.js
                        @@ -1 +1 @@
                        -import{_ as i,r as s,o as r,c as d,a as e,b as t,d as n,e as a}from"./app-PDrbPfzp.js";const h={},l=a('

                        VLESS Protocol

                        VLESS is a stateless lightweight transmission protocol that can be used as a bridge between Xray clients and servers.

                        Request & Response

                        1 byte16 bytes1 byteM bytes1 byte2 bytes1 byteS bytesX bytes
                        Protocol VersionEquivalent UUIDAdditional Information Length MAdditional Information ProtoBufInstructionPortAddress TypeAddressRequest Data
                        1 Byte1 ByteN BytesY Bytes
                        Protocol Version, consistent with the requestLength of additional information NAdditional information in ProtoBufResponse data

                        VLESS had the aforementioned structure as early as the second alpha test version (ALPHA 2), with BETA being the fifth test version.

                        ',6),c=e("code",null,"Response authentication",-1),p=e("code",null,"Protocol version",-1),u=e("code",null,"Additional information",-1),f={href:"https://github.com/gogo/protobuf",target:"_blank",rel:"noopener noreferrer"},m=e("p",null,'I always thought that "response authentication" was not necessary, and ALPHA replaced crypto/rand with math/rand in order to improve the performance of random number generation, which is no longer needed.',-1),y=e("p",null,'The "Protocol Version" not only serves as "Response Authentication", but also gives VLESS the ability to upgrade the protocol structure seamlessly, bringing infinite possibilities. The "Protocol Version" is 0 in the test version and 1 in the official version. If there are any incompatible protocol structural changes in the future, the version should be upgraded.',-1),b=e("p",null,"The design of VLESS server is switch version, which supports all VLESS versions at the same time. If you need to upgrade the protocol version (which may not happen), it is recommended that the server support it one month in advance, and then change the client after one month. VMess requests also have protocol versions, but their authentication information is outside, and the instruction part is highly coupled and has fixed encryption, which makes the protocol version meaningless inside. The server does not judge it, and the response does not have a protocol version. Trojan's protocol structure does not have a protocol version.",-1),g=e("p",null,"The following is a UUID. I used to think that 16 bytes were a bit long and considered shortening it. However, I later saw that Trojan used 56 printable characters (56 bytes), which completely dispelled this idea. The server needs to verify the UUID every time, so performance is also very important: VLESS's Validator has undergone multiple refactoring/upgrades. Compared with VMess, it is very concise and consumes very few resources. It can support a large number of users at the same time, and its performance is also very strong. The verification speed is extremely fast (sync.Map). API dynamically adds and deletes users, making it more efficient and smooth. https://github.com/XTLS/Xray-core/issues/158",-1),v=e("p",null,'Introducing ProtoBuf is an innovation, which will be explained in detail later. The structure from "instruction" to "address" is currently identical to VMess and also supports Mux.',-1),w={href:"https://github.com/rprx/v2ray-vless/releases",target:"_blank",rel:"noopener noreferrer"},S=a('

                        ProtoBuf

                        It seems that only VLESS supports embedding ProtoBuf, which is a data exchange format that encodes information tightly into binary TLV (Tag Length Value) structures.

                        The reason is that I saw an article that said that SS has some drawbacks, such as the lack of a design error reporting mechanism, and the client cannot take further action based on different errors. (But I don't agree that all errors should be reported, otherwise it can't prevent active probing. In the next beta version, the server can return a custom string of information.) So I think a scalable structure is important, and in the future, it can also carry dynamic port instructions. Not only the response, but the request also needs a similar structure. I originally planned to design TLV by myself, but then I found that ProtoBuf is the structure, ready-made, and it is completely suitable for this purpose, and the support for various languages is also good.

                        Currently, "Additional Information" only has Scheduler and SchedulerV, which are substitutes for MessName and MessSeed. When you don't need them, the "Additional Information Length" is 0, so there is no ProtoBuf serialization/deserialization overhead. Actually, I prefer to call this process "concatenation" because that's all pb does in principle, and the related overhead is minimal. The concatenated bytes are very compact, similar to ALPHA's solution, and those who are interested can output and compare them separately.

                        To indicate different levels of support for additional information (Addons, which can be understood as plugins and can have many plugins in the future), the next beta version will add "Addon Version" before "Addon Length". 256-1 = 255 bytes is enough and reasonable (65535 is too much and there may be malicious padding), and only one-tenth of the existing space is used. In the future, there will not be so many addons at the same time, and most of the time there will be no addons at all. If it is not enough, you can upgrade to a newer version of VLESS.

                        To reduce logical judgment and other expenses, it is temporarily decided that Addons will not use a multi-level structure. A month ago, there was an idea of "variable protocol format". PB can shuffle the order, but it is not necessary because the design of modern encryption will not allow bystanders to see that the headers of the two transmissions are the same.

                        Below is an introduction to the concepts of Schedulers and Encryption, both of which are optional. One is designed to address issues related to traffic timing, while the other is designed to address cryptographic issues.

                        Flow

                        Flow Control (Formerly Traffic Scheduler)

                        The Flow Control command is carried by ProtoBuf and manages the data section.

                        I previously discovered that VMess's original "metadata obfuscation" feature didn't provide any meaningful changes in TLS but only decreased performance. Consequently, VLESS has abandoned this feature. Moreover, the term "obfuscation" is often misinterpreted as camouflage, so it has been discarded.

                        As for camouflage, if it can't be an exact match, wouldn't it be a noticeable characteristic? If it could be an exact match, why not use the intended target for camouflage directly? Initially, I used SSR but found it only provided superficial disguises, fooling operators. Thus, I stopped using it.

                        Purpose of Flow Control

                        Flow Control influences macro traffic temporal characteristics rather than micro characteristics addressed by encryption. Traffic temporal characteristics can be:

                        1. Protocol-based, e.g., Socks5 handshake when using Socks5 over TLS. Different traits on TLS are considered different protocols for monitors. Infinite schedulers equate to infinite protocols (reallocating data sent each time).
                        2. Behavior-based, e.g., loading files, their order, and size when accessing Google's homepage. Adding another encryption layer cannot effectively conceal this information.

                        Schedulers don't require wrapping like encryption since the header data's tiny amount is negligible compared to the remaining data.

                        BETA 2 is anticipated to introduce two basic schedulers: Zstd compression and dynamic data expansion. Advanced operations will control and distribute at a macro level, but for now, these remain under development.

                        Encryption

                        Unlike VMess, which is highly coupled, VLESS allows the server and client to pre-agree on an encryption method, which is only encrypted with an outer layer. This is somewhat similar to using TLS, which does not affect any of the data carried, and can be understood as replacing TLS with pre-agreed encryption at the bottom. Compared with high coupling, this approach is more reasonable and flexible: if there is a security issue with one encryption method, it can be discarded and another one can be used directly, which is very convenient. The VLESS server also allows for different encryption methods to coexist.

                        Compared with VMess, VLESS replaces security with encryption and disableInsecureEncryption with decryption, which solves all the problems. Currently, encryption and decryption only accept "none" and cannot be left blank (even if there are connection security checks in the future), as detailed in the VLESS configuration document. Encryption does not need to be moved out one level, firstly because it cannot reuse a lot of code, and secondly because it will affect the control granularity, which will be understood by looking at future applications.

                        Encryption supports two types of forms. One type is completely independent and requires an additional password, suitable for private use. The other type combines with the existing UUID for encryption, which is suitable for public use.

                        (If the first type of encryption is used and the password is publicly available in some form, such as multiple people sharing it, then a man-in-the-middle attack is not far away.)

                        A redesigned dynamic port may be released simultaneously with encryption, and the command is carried by ProtoBuf. The specific implementation and the dynamic port of VMess will also have many differences.

                        It is very easy to cash out encrypted currency, which adds an extra layer of writer & reader. BETA 3 is expected to support SS's aes-128-gcm and chacha20-ietf-poly1305:

                        The encryption on the client-side can be filled with "auto: ss_aes-128-gcm_0_123456, ss_chacha20-ietf-poly1305_0_987654". Auto will choose the most suitable one for the current machine, 0 represents the beta version, and the last one is the password. The decryption on the server-side is also filled in a similar way, and each decryption attempt will be made when the request is received.

                        Not all combinations need to be tried one by one: VMess encryption is divided into three parts. The first part is the authentication information, which combines UUID, alterId, and time factors. The second part is the instruction part, which is encrypted using a fixed algorithm. The instruction contains the encryption algorithm used in the data part. The third part is the important data part. It can be seen that the VMess encryption and decryption method is actually many-to-one (adapted by the server), not just combining UUID. However, it is also a relatively difficult thing to encrypt only by combining UUID. It will not be available in a short time. Considering that we now have VMessAEAD available, there is no need to rush. If VLESS introduces an encryption method that combines UUID, it is equivalent to reconstructing the entire VMess.

                        UDP issues

                        ',27),_={href:"https://github.com/XTLS/Xray-core/discussions/252",target:"_blank",rel:"noopener noreferrer"},T=a('

                        Client Development Guide

                        1. The VLESS protocol itself may have incompatible upgrades, but the parameters in the client configuration file are basically only increased and not decreased. The protocol implementation of the iOS client needs to keep up with the upgrade.
                        2. Visual standard: Please use VLESS as the UI identifier uniformly, instead of VLess / Vless / vless. The configuration file is not affected, and the code should follow naturally.
                        3. Encryption should be made into an input box instead of a selection box. The default value of the new configuration should be none, and if the user leaves it blank, it should be filled in with none.
                        ',3),V={href:"https://github.com/DuckSoft",target:"_blank",rel:"noopener noreferrer"},I={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"};function L(A,x){const o=s("ExternalLinkIcon");return r(),d("div",null,[l,e("p",null,[t('"'),c,t('" has been replaced with "'),p,t('" and moved to the front, allowing VLESS to upgrade and eliminate the overhead of generating pseudo-random numbers. The obfuscation-related structure has been replaced with "'),u,t('" (ProtoBuf) and moved forward, giving the protocol itself scalability, with minimal overhead ('),e("a",f,[t("gogo/protobuf"),n(o)]),t("). If there is no additional information, there is no relevant overhead.")]),m,y,b,g,v,e("p",null,[t("Overall, ALPHA 2 to BETA mainly includes: structural evolution, cleaning and integration, performance improvement, and more completeness. All of these are incremental improvements, please refer to "),e("a",w,[t("VLESS Changes"),n(o)]),t(" for details.")]),S,e("p",null,[e("a",_,[t("XUDP: VLESS & VMess & Mux UDP FullCone NAT"),n(o)])]),T,e("p",null,[t("Thank you to "),e("a",V,[t("@DuckSoft"),n(o)]),t(" for the proposal!")]),e("p",null,[t("Please see "),e("a",I,[t("VMessAEAD/VLESS Sharing Link Standard Proposal"),n(o)]),t(" for more details.")])])}const k=i(h,[["render",L],["__file","vless.html.vue"]]);export{k as default}; +import{_ as i,r as s,o as r,c as d,a as e,b as t,d as n,e as a}from"./app-UOvWaKji.js";const h={},l=a('

                        VLESS Protocol

                        VLESS is a stateless lightweight transmission protocol that can be used as a bridge between Xray clients and servers.

                        Request & Response

                        1 byte16 bytes1 byteM bytes1 byte2 bytes1 byteS bytesX bytes
                        Protocol VersionEquivalent UUIDAdditional Information Length MAdditional Information ProtoBufInstructionPortAddress TypeAddressRequest Data
                        1 Byte1 ByteN BytesY Bytes
                        Protocol Version, consistent with the requestLength of additional information NAdditional information in ProtoBufResponse data

                        VLESS had the aforementioned structure as early as the second alpha test version (ALPHA 2), with BETA being the fifth test version.

                        ',6),c=e("code",null,"Response authentication",-1),p=e("code",null,"Protocol version",-1),u=e("code",null,"Additional information",-1),f={href:"https://github.com/gogo/protobuf",target:"_blank",rel:"noopener noreferrer"},m=e("p",null,'I always thought that "response authentication" was not necessary, and ALPHA replaced crypto/rand with math/rand in order to improve the performance of random number generation, which is no longer needed.',-1),y=e("p",null,'The "Protocol Version" not only serves as "Response Authentication", but also gives VLESS the ability to upgrade the protocol structure seamlessly, bringing infinite possibilities. The "Protocol Version" is 0 in the test version and 1 in the official version. If there are any incompatible protocol structural changes in the future, the version should be upgraded.',-1),b=e("p",null,"The design of VLESS server is switch version, which supports all VLESS versions at the same time. If you need to upgrade the protocol version (which may not happen), it is recommended that the server support it one month in advance, and then change the client after one month. VMess requests also have protocol versions, but their authentication information is outside, and the instruction part is highly coupled and has fixed encryption, which makes the protocol version meaningless inside. The server does not judge it, and the response does not have a protocol version. Trojan's protocol structure does not have a protocol version.",-1),g=e("p",null,"The following is a UUID. I used to think that 16 bytes were a bit long and considered shortening it. However, I later saw that Trojan used 56 printable characters (56 bytes), which completely dispelled this idea. The server needs to verify the UUID every time, so performance is also very important: VLESS's Validator has undergone multiple refactoring/upgrades. Compared with VMess, it is very concise and consumes very few resources. It can support a large number of users at the same time, and its performance is also very strong. The verification speed is extremely fast (sync.Map). API dynamically adds and deletes users, making it more efficient and smooth. https://github.com/XTLS/Xray-core/issues/158",-1),v=e("p",null,'Introducing ProtoBuf is an innovation, which will be explained in detail later. The structure from "instruction" to "address" is currently identical to VMess and also supports Mux.',-1),w={href:"https://github.com/rprx/v2ray-vless/releases",target:"_blank",rel:"noopener noreferrer"},S=a('

                        ProtoBuf

                        It seems that only VLESS supports embedding ProtoBuf, which is a data exchange format that encodes information tightly into binary TLV (Tag Length Value) structures.

                        The reason is that I saw an article that said that SS has some drawbacks, such as the lack of a design error reporting mechanism, and the client cannot take further action based on different errors. (But I don't agree that all errors should be reported, otherwise it can't prevent active probing. In the next beta version, the server can return a custom string of information.) So I think a scalable structure is important, and in the future, it can also carry dynamic port instructions. Not only the response, but the request also needs a similar structure. I originally planned to design TLV by myself, but then I found that ProtoBuf is the structure, ready-made, and it is completely suitable for this purpose, and the support for various languages is also good.

                        Currently, "Additional Information" only has Scheduler and SchedulerV, which are substitutes for MessName and MessSeed. When you don't need them, the "Additional Information Length" is 0, so there is no ProtoBuf serialization/deserialization overhead. Actually, I prefer to call this process "concatenation" because that's all pb does in principle, and the related overhead is minimal. The concatenated bytes are very compact, similar to ALPHA's solution, and those who are interested can output and compare them separately.

                        To indicate different levels of support for additional information (Addons, which can be understood as plugins and can have many plugins in the future), the next beta version will add "Addon Version" before "Addon Length". 256-1 = 255 bytes is enough and reasonable (65535 is too much and there may be malicious padding), and only one-tenth of the existing space is used. In the future, there will not be so many addons at the same time, and most of the time there will be no addons at all. If it is not enough, you can upgrade to a newer version of VLESS.

                        To reduce logical judgment and other expenses, it is temporarily decided that Addons will not use a multi-level structure. A month ago, there was an idea of "variable protocol format". PB can shuffle the order, but it is not necessary because the design of modern encryption will not allow bystanders to see that the headers of the two transmissions are the same.

                        Below is an introduction to the concepts of Schedulers and Encryption, both of which are optional. One is designed to address issues related to traffic timing, while the other is designed to address cryptographic issues.

                        Flow

                        Flow Control (Formerly Traffic Scheduler)

                        The Flow Control command is carried by ProtoBuf and manages the data section.

                        I previously discovered that VMess's original "metadata obfuscation" feature didn't provide any meaningful changes in TLS but only decreased performance. Consequently, VLESS has abandoned this feature. Moreover, the term "obfuscation" is often misinterpreted as camouflage, so it has been discarded.

                        As for camouflage, if it can't be an exact match, wouldn't it be a noticeable characteristic? If it could be an exact match, why not use the intended target for camouflage directly? Initially, I used SSR but found it only provided superficial disguises, fooling operators. Thus, I stopped using it.

                        Purpose of Flow Control

                        Flow Control influences macro traffic temporal characteristics rather than micro characteristics addressed by encryption. Traffic temporal characteristics can be:

                        1. Protocol-based, e.g., Socks5 handshake when using Socks5 over TLS. Different traits on TLS are considered different protocols for monitors. Infinite schedulers equate to infinite protocols (reallocating data sent each time).
                        2. Behavior-based, e.g., loading files, their order, and size when accessing Google's homepage. Adding another encryption layer cannot effectively conceal this information.

                        Schedulers don't require wrapping like encryption since the header data's tiny amount is negligible compared to the remaining data.

                        BETA 2 is anticipated to introduce two basic schedulers: Zstd compression and dynamic data expansion. Advanced operations will control and distribute at a macro level, but for now, these remain under development.

                        Encryption

                        Unlike VMess, which is highly coupled, VLESS allows the server and client to pre-agree on an encryption method, which is only encrypted with an outer layer. This is somewhat similar to using TLS, which does not affect any of the data carried, and can be understood as replacing TLS with pre-agreed encryption at the bottom. Compared with high coupling, this approach is more reasonable and flexible: if there is a security issue with one encryption method, it can be discarded and another one can be used directly, which is very convenient. The VLESS server also allows for different encryption methods to coexist.

                        Compared with VMess, VLESS replaces security with encryption and disableInsecureEncryption with decryption, which solves all the problems. Currently, encryption and decryption only accept "none" and cannot be left blank (even if there are connection security checks in the future), as detailed in the VLESS configuration document. Encryption does not need to be moved out one level, firstly because it cannot reuse a lot of code, and secondly because it will affect the control granularity, which will be understood by looking at future applications.

                        Encryption supports two types of forms. One type is completely independent and requires an additional password, suitable for private use. The other type combines with the existing UUID for encryption, which is suitable for public use.

                        (If the first type of encryption is used and the password is publicly available in some form, such as multiple people sharing it, then a man-in-the-middle attack is not far away.)

                        A redesigned dynamic port may be released simultaneously with encryption, and the command is carried by ProtoBuf. The specific implementation and the dynamic port of VMess will also have many differences.

                        It is very easy to cash out encrypted currency, which adds an extra layer of writer & reader. BETA 3 is expected to support SS's aes-128-gcm and chacha20-ietf-poly1305:

                        The encryption on the client-side can be filled with "auto: ss_aes-128-gcm_0_123456, ss_chacha20-ietf-poly1305_0_987654". Auto will choose the most suitable one for the current machine, 0 represents the beta version, and the last one is the password. The decryption on the server-side is also filled in a similar way, and each decryption attempt will be made when the request is received.

                        Not all combinations need to be tried one by one: VMess encryption is divided into three parts. The first part is the authentication information, which combines UUID, alterId, and time factors. The second part is the instruction part, which is encrypted using a fixed algorithm. The instruction contains the encryption algorithm used in the data part. The third part is the important data part. It can be seen that the VMess encryption and decryption method is actually many-to-one (adapted by the server), not just combining UUID. However, it is also a relatively difficult thing to encrypt only by combining UUID. It will not be available in a short time. Considering that we now have VMessAEAD available, there is no need to rush. If VLESS introduces an encryption method that combines UUID, it is equivalent to reconstructing the entire VMess.

                        UDP issues

                        ',27),_={href:"https://github.com/XTLS/Xray-core/discussions/252",target:"_blank",rel:"noopener noreferrer"},T=a('

                        Client Development Guide

                        1. The VLESS protocol itself may have incompatible upgrades, but the parameters in the client configuration file are basically only increased and not decreased. The protocol implementation of the iOS client needs to keep up with the upgrade.
                        2. Visual standard: Please use VLESS as the UI identifier uniformly, instead of VLess / Vless / vless. The configuration file is not affected, and the code should follow naturally.
                        3. Encryption should be made into an input box instead of a selection box. The default value of the new configuration should be none, and if the user leaves it blank, it should be filled in with none.
                        ',3),V={href:"https://github.com/DuckSoft",target:"_blank",rel:"noopener noreferrer"},I={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"};function L(A,x){const o=s("ExternalLinkIcon");return r(),d("div",null,[l,e("p",null,[t('"'),c,t('" has been replaced with "'),p,t('" and moved to the front, allowing VLESS to upgrade and eliminate the overhead of generating pseudo-random numbers. The obfuscation-related structure has been replaced with "'),u,t('" (ProtoBuf) and moved forward, giving the protocol itself scalability, with minimal overhead ('),e("a",f,[t("gogo/protobuf"),n(o)]),t("). If there is no additional information, there is no relevant overhead.")]),m,y,b,g,v,e("p",null,[t("Overall, ALPHA 2 to BETA mainly includes: structural evolution, cleaning and integration, performance improvement, and more completeness. All of these are incremental improvements, please refer to "),e("a",w,[t("VLESS Changes"),n(o)]),t(" for details.")]),S,e("p",null,[e("a",_,[t("XUDP: VLESS & VMess & Mux UDP FullCone NAT"),n(o)])]),T,e("p",null,[t("Thank you to "),e("a",V,[t("@DuckSoft"),n(o)]),t(" for the proposal!")]),e("p",null,[t("Please see "),e("a",I,[t("VMessAEAD/VLESS Sharing Link Standard Proposal"),n(o)]),t(" for more details.")])])}const k=i(h,[["render",L],["__file","vless.html.vue"]]);export{k as default}; diff --git a/assets/vless.html-BeDExndi.js b/assets/vless.html-w-KHS2qb.js similarity index 99% rename from assets/vless.html-BeDExndi.js rename to assets/vless.html-w-KHS2qb.js index ea710599b4..e2cf6cae82 100644 --- a/assets/vless.html-BeDExndi.js +++ b/assets/vless.html-w-KHS2qb.js @@ -1 +1 @@ -import{_ as n,r as a,o as h,c as d,a as e,b as t,d as o,e as r}from"./app-PDrbPfzp.js";const c={},l=r('

                        VLESS 协议

                        VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

                        Request & Response

                        1 字节16 字节1 字节M 字节1 字节2 字节1 字节S 字节X 字节
                        协议版本等价 UUID附加信息长度 M附加信息 ProtoBuf指令端口地址类型地址请求数据
                        1 字节1 字节N 字节Y 字节
                        协议版本,与请求的一致附加信息长度 N附加信息 ProtoBuf响应数据

                        VLESS 早在第二个测试版 ALPHA 2 时就已经是上述结构了(BETA 是第五个测试版):

                        ',6),p={href:"https://github.com/gogo/protobuf",target:"_blank",rel:"noopener noreferrer"},i=e("p",null,"我一直觉得“响应认证”不是必要的,ALPHA 时为了提升生成随机数的性能,还用 math/rand 替换 crypto/rand,而现在都不需要了。",-1),u=e("p",null,"“协议版本”不仅能起到“响应认证”的作用,还赋予了 VLESS 无痛升级协议结构的能力,带来无限的可能性。 “协议版本”在测试版本中均为 0,正式版本中为 1,以后若有不兼容的协议结构变更则应升级版本。",-1),S=e("p",null,"VLESS 服务端的设计是 switch version,即同时支持所有 VLESS 版本。若需要升级协议版本(可能到不了这一步),推荐的做法是服务端提前一个月支持,一个月后再改客户端。VMess 请求也有协议版本,但它的认证信息在外面,指令部分则高度耦合且有固定加密,导致里面的协议版本毫无意义,服务端也没有进行判断,响应则没有协议版本。Trojan 的协议结构中没有协议版本。",-1),_=e("p",null,"接下来是 UUID,我本来觉得 16 字节有点长,曾经考虑过缩短它,但后来看到 Trojan 用了 56 个可打印字符(56 字节),就彻底打消了这个念头。服务端每次都要验证 UUID,所以性能也很重要:VLESS 的 Validator 经历了多次重构/升级,相较于 VMess,它十分简洁且耗资源很少,可以同时支持非常多的用户,性能也十分强悍,验证速度极快(sync.Map)。API 动态增删用户则更高效顺滑。 https://github.com/XTLS/Xray-core/issues/158",-1),f=e("p",null,"引入 ProtoBuf 是一个创举,等下会详细讲解。“指令”到“地址”的结构目前与 VMess 完全相同,同样支持 Mux。",-1),V={href:"https://github.com/rprx/v2ray-vless/releases",target:"_blank",rel:"noopener noreferrer"},b=r('

                        ProtoBuf

                        似乎只有 VLESS 可选内嵌 ProtoBuf,它是一种数据交换格式,信息被紧密编码成二进制,TLV 结构(Tag Length Value)。

                        起因是我看到一篇文章称 SS 有一些缺点,如没有设计错误回报机制,客户端没办法根据不同的错误采取进一步的动作。 (但我并不认同所有错误都要回报,不然防不了主动探测。下一个测试版中,服务器可以返回一串自定义信息。) 于是想到一个可扩展的结构是很重要的,未来它也可以承载如动态端口指令。不止响应,请求也需要类似的结构。 本来打算自己设计 TLV,接着发觉 ProtoBuf 就是此结构、现成的轮子,完全适合用来做这件事,各语言支持等也不错。

                        目前“附加信息”只有 Scheduler 和 SchedulerV,它们是 MessName 和 MessSeed 的替代者,当你不需要它们时,“附加信息长度”为 0,也就不会有 ProtoBuf 序列化/反序列化的开销。其实我更愿意称这个过程为“拼接”,因为 pb 实际原理上也只是这么做而已,相关开销极小。拼接后的 bytes 十分紧凑,和 ALPHA 的方案相差无几,有兴趣的可以分别输出并对比。

                        为了指示对附加信息(Addons,也可以理解成插件,以后可以有很多个插件)的不同支持程度,下个测试版会在“附加信息长度”前新增“附加信息版本”。256 - 1 = 255 字节是够用且合理的(65535 就太多了,还可能有人恶意填充),现有的只用了十分之一,以后也不会同时有那么多附加信息,且大多数情况下是完全没有附加信息的。真不够用的话,可以升级 VLESS 版本。

                        为了减少逻辑判断等开销,暂定 Addons 不使用多级结构。一个月前出现过“可变协议格式”的想法,pb 是可以做到打乱顺序,但没必要,因为现代加密的设计不会让旁观者看出两次传输的头部相同。

                        下面介绍 Schedulers 和 Encryption 的构想,它们都是可选的,一个应对流量时序特征问题,一个应对密码学上的问题。

                        Schedulers Flow

                        中文名暂称:流量调度器(2020-09-03 更新:中文名确定为“流控”),指令由 ProtoBuf 承载,控制的是数据部分。

                        我之前发现,VMess 原有的 shake “元数据混淆”在 TLS 上完全不会带来有意义的改变,只会降低性能,所以 VLESS 弃用了它。并且,“混淆”这个表述容易被误解成伪装,也弃用了。顺便一提,我一直是不看好伪装的:做不到完全一样,那不就是强特征吗?做得到完全一样,那为什么不直接用伪装目标?我一开始用的是 SSR,后来发现它只是表面伪装骗运营商,就再也没用过了。

                        那么,“流量调度器”要解决什么问题?它影响的是宏观流量时序特征,而不是微观特征,后者是加密要解决的事情。流量时序特征可以是协议带来的,比如 Socks5 over TLS 时的 Socks5 握手 ,TLS 上不同的这种特征对于监测者来说就是不同的协议,此时无限 Schedulers 就相当于无限协议(重新分配每次发送的数据量大小等)。流量时序特征也可以是行为带来的,比如访问 Google 首页时加载了多少文件、顺序、每个文件的大小,多套一层加密并不能有效掩盖这些信息。

                        Schedulers 没必要像下面的 Encryption 一样整个套在外面,因为头部的一丁点数据相对于后面的数据量来说太微不足道了。

                        BETA 2 预计推出两个初级的 Scheduler:Zstd 压缩、数据量动态扩充。进阶操作才是从宏观层面来控制、分配,暂时咕咕。

                        Encryption

                        与 VMess 的高度耦合不同,VLESS 的服务端、客户端不久后可以提前约定好加密方式,仅在外面套一层加密。这有点类似于使用 TLS,不影响承载的任何数据,也可以理解成底层就是从 TLS 换成预设约定加密。相对于高度耦合,这种方式更合理且灵活:一种加密方式出了安全性问题,直接扔掉并换用其它的就行了,十分方便。VLESS 服务端还会允许不同的加密方式共存。

                        ',15),L={href:"https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md",target:"_blank",rel:"noopener noreferrer"},E=e("p",null,"加密支持两类形式,一类是加密完全独立,需要额外密码,适合私用,另一类是结合已有的 UUID 来加密,适合公用。 (若用第一类加密形式,且密码是以某种形式公开的,比如多人共用,那么中间人攻击就不远了) 重新设计的动态端口可能会随加密同时推出,指令由 ProtoBuf 承载,具体实现和 VMess 的动态端口也会有很多不同。",-1),g=e("p",null,"套现成加密是件很简单的事情,也就多一层 writer & reader。BETA 3 预计支持 SS 的 aes-128-gcm 和 chacha20-ietf-poly1305: 客户端的 encryption 可以填 “auto: ss_aes-128-gcm_0_123456, ss_chacha20-ietf-poly1305_0_987654”,auto 会选择最适合当前机器的,0 代表测试版,最后的是密码。服务端的 decryption 也是类似填法,收到请求时会逐一尝试解密。",-1),y=e("p",null,"并不是所有组合都需逐一尝试:VMess 的加密分为三段,第一段是认证信息,结合了 UUID、alterId、时间因素,第二段是指令部分,以固定算法加密,指令中含有数据部分使用的加密算法,第三段才是重要的数据部分。可以看出,VMess 的加解密方式实际上是多对一(服务端适配),而不仅是结合 UUID。但仅是结合 UUID 来加密也是件相对麻烦的事情,短时间内不会出,鉴于我们现在有 VMessAEAD 可用,也并不着急。若 VLESS 推出了结合 UUID 的加密方式,相当于重构了整个 VMess。",-1),m=e("h2",{id:"udp-issues",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#udp-issues"},[e("span",null,"UDP issues")])],-1),x={href:"https://github.com/XTLS/Xray-core/discussions/252",target:"_blank",rel:"noopener noreferrer"},A=r('

                        客户端开发指引

                        1. VLESS 协议本身还会有不兼容升级,但客户端配置文件参数基本上是只增不减的。iOS 客户端的协议实现则需紧跟升级。
                        2. 视觉标准:UI 标识请统一用 VLESS,而不是 VLess / Vless / vless,配置文件不受影响,代码内则顺其自然。
                        3. encryption 应做成输入框而不是选择框,新配置的默认值应为 none,若用户置空则应代填 none

                        VLESS 分享链接标准

                        ',3),M=e("img",{src:"https://avatars2.githubusercontent.com/u/7822648?s=32",width:"32px",height:"32px",alt:"a"},null,-1),U={href:"https://github.com/DuckSoft",target:"_blank",rel:"noopener noreferrer"},T={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"};function P(v,B){const s=a("ExternalLinkIcon");return h(),d("div",null,[l,e("blockquote",null,[e("p",null,[t("“响应认证”被替换为“协议版本”并移至最前,使 VLESS 可以升级换代,同时消除了生成伪随机数的开销。混淆相关结构被替换为附加信息(ProtoBuf)并前移,赋予协议本身可扩展性,相关开销也极小("),e("a",p,[t("gogo/protobuf"),o(s)]),t("),若无附加信息则无相关开销。")])]),i,u,S,_,f,e("p",null,[t("总体上,ALPHA 2 到 BETA 主要是:结构进化、清理整合、性能提升、更加完善。这些都是一点一滴的,详见 "),e("a",V,[t("VLESS Changes"),o(s)]),t("。")]),b,e("p",null,[t('对比 VMess,VLESS 相当于把 security 换成 encryption,把 disableInsecureEncryption 换成 decryption,就解决了所有问题。目前 encryption 和 decryption 只接受 "none" 且不能留空(即使以后有连接安全性检查),详见 '),e("a",L,[t("VLESS 配置文档"),o(s)]),t("。encryption 并不需要往外移一级,一是因为无法复用很多代码,二是因为会影响控制粒度,看未来的应用就明白了。")]),E,g,y,m,e("p",null,[e("a",x,[t("XUDP:VLESS & VMess & Mux UDP FullCone NAT"),o(s)])]),A,e("p",null,[t("感谢 "),M,t(),e("a",U,[t("@DuckSoft"),o(s)]),t(" 的提案!")]),e("p",null,[t("详情请见 "),e("a",T,[t("VMessAEAD / VLESS 分享链接标准提案"),o(s)])])])}const D=n(c,[["render",P],["__file","vless.html.vue"]]);export{D as default}; +import{_ as n,r as a,o as h,c as d,a as e,b as t,d as o,e as r}from"./app-UOvWaKji.js";const c={},l=r('

                        VLESS 协议

                        VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

                        Request & Response

                        1 字节16 字节1 字节M 字节1 字节2 字节1 字节S 字节X 字节
                        协议版本等价 UUID附加信息长度 M附加信息 ProtoBuf指令端口地址类型地址请求数据
                        1 字节1 字节N 字节Y 字节
                        协议版本,与请求的一致附加信息长度 N附加信息 ProtoBuf响应数据

                        VLESS 早在第二个测试版 ALPHA 2 时就已经是上述结构了(BETA 是第五个测试版):

                        ',6),p={href:"https://github.com/gogo/protobuf",target:"_blank",rel:"noopener noreferrer"},i=e("p",null,"我一直觉得“响应认证”不是必要的,ALPHA 时为了提升生成随机数的性能,还用 math/rand 替换 crypto/rand,而现在都不需要了。",-1),u=e("p",null,"“协议版本”不仅能起到“响应认证”的作用,还赋予了 VLESS 无痛升级协议结构的能力,带来无限的可能性。 “协议版本”在测试版本中均为 0,正式版本中为 1,以后若有不兼容的协议结构变更则应升级版本。",-1),S=e("p",null,"VLESS 服务端的设计是 switch version,即同时支持所有 VLESS 版本。若需要升级协议版本(可能到不了这一步),推荐的做法是服务端提前一个月支持,一个月后再改客户端。VMess 请求也有协议版本,但它的认证信息在外面,指令部分则高度耦合且有固定加密,导致里面的协议版本毫无意义,服务端也没有进行判断,响应则没有协议版本。Trojan 的协议结构中没有协议版本。",-1),_=e("p",null,"接下来是 UUID,我本来觉得 16 字节有点长,曾经考虑过缩短它,但后来看到 Trojan 用了 56 个可打印字符(56 字节),就彻底打消了这个念头。服务端每次都要验证 UUID,所以性能也很重要:VLESS 的 Validator 经历了多次重构/升级,相较于 VMess,它十分简洁且耗资源很少,可以同时支持非常多的用户,性能也十分强悍,验证速度极快(sync.Map)。API 动态增删用户则更高效顺滑。 https://github.com/XTLS/Xray-core/issues/158",-1),f=e("p",null,"引入 ProtoBuf 是一个创举,等下会详细讲解。“指令”到“地址”的结构目前与 VMess 完全相同,同样支持 Mux。",-1),V={href:"https://github.com/rprx/v2ray-vless/releases",target:"_blank",rel:"noopener noreferrer"},b=r('

                        ProtoBuf

                        似乎只有 VLESS 可选内嵌 ProtoBuf,它是一种数据交换格式,信息被紧密编码成二进制,TLV 结构(Tag Length Value)。

                        起因是我看到一篇文章称 SS 有一些缺点,如没有设计错误回报机制,客户端没办法根据不同的错误采取进一步的动作。 (但我并不认同所有错误都要回报,不然防不了主动探测。下一个测试版中,服务器可以返回一串自定义信息。) 于是想到一个可扩展的结构是很重要的,未来它也可以承载如动态端口指令。不止响应,请求也需要类似的结构。 本来打算自己设计 TLV,接着发觉 ProtoBuf 就是此结构、现成的轮子,完全适合用来做这件事,各语言支持等也不错。

                        目前“附加信息”只有 Scheduler 和 SchedulerV,它们是 MessName 和 MessSeed 的替代者,当你不需要它们时,“附加信息长度”为 0,也就不会有 ProtoBuf 序列化/反序列化的开销。其实我更愿意称这个过程为“拼接”,因为 pb 实际原理上也只是这么做而已,相关开销极小。拼接后的 bytes 十分紧凑,和 ALPHA 的方案相差无几,有兴趣的可以分别输出并对比。

                        为了指示对附加信息(Addons,也可以理解成插件,以后可以有很多个插件)的不同支持程度,下个测试版会在“附加信息长度”前新增“附加信息版本”。256 - 1 = 255 字节是够用且合理的(65535 就太多了,还可能有人恶意填充),现有的只用了十分之一,以后也不会同时有那么多附加信息,且大多数情况下是完全没有附加信息的。真不够用的话,可以升级 VLESS 版本。

                        为了减少逻辑判断等开销,暂定 Addons 不使用多级结构。一个月前出现过“可变协议格式”的想法,pb 是可以做到打乱顺序,但没必要,因为现代加密的设计不会让旁观者看出两次传输的头部相同。

                        下面介绍 Schedulers 和 Encryption 的构想,它们都是可选的,一个应对流量时序特征问题,一个应对密码学上的问题。

                        Schedulers Flow

                        中文名暂称:流量调度器(2020-09-03 更新:中文名确定为“流控”),指令由 ProtoBuf 承载,控制的是数据部分。

                        我之前发现,VMess 原有的 shake “元数据混淆”在 TLS 上完全不会带来有意义的改变,只会降低性能,所以 VLESS 弃用了它。并且,“混淆”这个表述容易被误解成伪装,也弃用了。顺便一提,我一直是不看好伪装的:做不到完全一样,那不就是强特征吗?做得到完全一样,那为什么不直接用伪装目标?我一开始用的是 SSR,后来发现它只是表面伪装骗运营商,就再也没用过了。

                        那么,“流量调度器”要解决什么问题?它影响的是宏观流量时序特征,而不是微观特征,后者是加密要解决的事情。流量时序特征可以是协议带来的,比如 Socks5 over TLS 时的 Socks5 握手 ,TLS 上不同的这种特征对于监测者来说就是不同的协议,此时无限 Schedulers 就相当于无限协议(重新分配每次发送的数据量大小等)。流量时序特征也可以是行为带来的,比如访问 Google 首页时加载了多少文件、顺序、每个文件的大小,多套一层加密并不能有效掩盖这些信息。

                        Schedulers 没必要像下面的 Encryption 一样整个套在外面,因为头部的一丁点数据相对于后面的数据量来说太微不足道了。

                        BETA 2 预计推出两个初级的 Scheduler:Zstd 压缩、数据量动态扩充。进阶操作才是从宏观层面来控制、分配,暂时咕咕。

                        Encryption

                        与 VMess 的高度耦合不同,VLESS 的服务端、客户端不久后可以提前约定好加密方式,仅在外面套一层加密。这有点类似于使用 TLS,不影响承载的任何数据,也可以理解成底层就是从 TLS 换成预设约定加密。相对于高度耦合,这种方式更合理且灵活:一种加密方式出了安全性问题,直接扔掉并换用其它的就行了,十分方便。VLESS 服务端还会允许不同的加密方式共存。

                        ',15),L={href:"https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md",target:"_blank",rel:"noopener noreferrer"},E=e("p",null,"加密支持两类形式,一类是加密完全独立,需要额外密码,适合私用,另一类是结合已有的 UUID 来加密,适合公用。 (若用第一类加密形式,且密码是以某种形式公开的,比如多人共用,那么中间人攻击就不远了) 重新设计的动态端口可能会随加密同时推出,指令由 ProtoBuf 承载,具体实现和 VMess 的动态端口也会有很多不同。",-1),g=e("p",null,"套现成加密是件很简单的事情,也就多一层 writer & reader。BETA 3 预计支持 SS 的 aes-128-gcm 和 chacha20-ietf-poly1305: 客户端的 encryption 可以填 “auto: ss_aes-128-gcm_0_123456, ss_chacha20-ietf-poly1305_0_987654”,auto 会选择最适合当前机器的,0 代表测试版,最后的是密码。服务端的 decryption 也是类似填法,收到请求时会逐一尝试解密。",-1),y=e("p",null,"并不是所有组合都需逐一尝试:VMess 的加密分为三段,第一段是认证信息,结合了 UUID、alterId、时间因素,第二段是指令部分,以固定算法加密,指令中含有数据部分使用的加密算法,第三段才是重要的数据部分。可以看出,VMess 的加解密方式实际上是多对一(服务端适配),而不仅是结合 UUID。但仅是结合 UUID 来加密也是件相对麻烦的事情,短时间内不会出,鉴于我们现在有 VMessAEAD 可用,也并不着急。若 VLESS 推出了结合 UUID 的加密方式,相当于重构了整个 VMess。",-1),m=e("h2",{id:"udp-issues",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#udp-issues"},[e("span",null,"UDP issues")])],-1),x={href:"https://github.com/XTLS/Xray-core/discussions/252",target:"_blank",rel:"noopener noreferrer"},A=r('

                        客户端开发指引

                        1. VLESS 协议本身还会有不兼容升级,但客户端配置文件参数基本上是只增不减的。iOS 客户端的协议实现则需紧跟升级。
                        2. 视觉标准:UI 标识请统一用 VLESS,而不是 VLess / Vless / vless,配置文件不受影响,代码内则顺其自然。
                        3. encryption 应做成输入框而不是选择框,新配置的默认值应为 none,若用户置空则应代填 none

                        VLESS 分享链接标准

                        ',3),M=e("img",{src:"https://avatars2.githubusercontent.com/u/7822648?s=32",width:"32px",height:"32px",alt:"a"},null,-1),U={href:"https://github.com/DuckSoft",target:"_blank",rel:"noopener noreferrer"},T={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"};function P(v,B){const s=a("ExternalLinkIcon");return h(),d("div",null,[l,e("blockquote",null,[e("p",null,[t("“响应认证”被替换为“协议版本”并移至最前,使 VLESS 可以升级换代,同时消除了生成伪随机数的开销。混淆相关结构被替换为附加信息(ProtoBuf)并前移,赋予协议本身可扩展性,相关开销也极小("),e("a",p,[t("gogo/protobuf"),o(s)]),t("),若无附加信息则无相关开销。")])]),i,u,S,_,f,e("p",null,[t("总体上,ALPHA 2 到 BETA 主要是:结构进化、清理整合、性能提升、更加完善。这些都是一点一滴的,详见 "),e("a",V,[t("VLESS Changes"),o(s)]),t("。")]),b,e("p",null,[t('对比 VMess,VLESS 相当于把 security 换成 encryption,把 disableInsecureEncryption 换成 decryption,就解决了所有问题。目前 encryption 和 decryption 只接受 "none" 且不能留空(即使以后有连接安全性检查),详见 '),e("a",L,[t("VLESS 配置文档"),o(s)]),t("。encryption 并不需要往外移一级,一是因为无法复用很多代码,二是因为会影响控制粒度,看未来的应用就明白了。")]),E,g,y,m,e("p",null,[e("a",x,[t("XUDP:VLESS & VMess & Mux UDP FullCone NAT"),o(s)])]),A,e("p",null,[t("感谢 "),M,t(),e("a",U,[t("@DuckSoft"),o(s)]),t(" 的提案!")]),e("p",null,[t("详情请见 "),e("a",T,[t("VMessAEAD / VLESS 分享链接标准提案"),o(s)])])])}const D=n(c,[["render",P],["__file","vless.html.vue"]]);export{D as default}; diff --git a/assets/vmess.html-3hG8mFqR.js b/assets/vmess.html-14n3YBGD.js similarity index 99% rename from assets/vmess.html-3hG8mFqR.js rename to assets/vmess.html-14n3YBGD.js index 3774af6c87..549afdab01 100644 --- a/assets/vmess.html-3hG8mFqR.js +++ b/assets/vmess.html-14n3YBGD.js @@ -1 +1 @@ -import{_ as n,r as h,o as s,c as r,a as t,b as e,d as i,e as a}from"./app-PDrbPfzp.js";const d={},c=a('

                        VMess 协议

                        VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

                        版本

                        当前版本号为 1。

                        依赖

                        底层协议

                        VMess 是一个基于 TCP 的协议,所有数据使用 TCP 传输。

                        用户 ID

                        ',8),o={href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",target:"_blank",rel:"noopener noreferrer"},p={href:"https://www.uuidgenerator.net/",target:"_blank",rel:"noopener noreferrer"},x=t("p",null,[e("用户 ID 可在"),t("a",{href:"../../config"},"配置文件"),e("中指定。")],-1),u=t("h3",{id:"函数",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#函数"},[t("span",null,"函数")])],-1),y={href:"https://en.wikipedia.org/wiki/MD5",target:"_blank",rel:"noopener noreferrer"},g=t("ul",null,[t("li",null,"输入参数为任意长度的 byte 数组"),t("li",null,"输出为一个 16 byte 的数组")],-1),b={href:"https://en.wikipedia.org/wiki/Hash-based_message_authentication_code",target:"_blank",rel:"noopener noreferrer"},_=t("ul",null,[t("li",null,[e("输入参数为: "),t("ul",null,[t("li",null,"H:散列函数"),t("li",null,"K:密钥,任意长度的 byte 数组"),t("li",null,"M:消息,任意长度的 byte 数组")])])],-1),M={href:"https://en.wikipedia.org/wiki/SHA-3",target:"_blank",rel:"noopener noreferrer"},f=t("ul",null,[t("li",null,"输入参数为任意长度的字符串"),t("li",null,"输出为任意长度的字符串")],-1),V=a('

                        通讯过程

                        VMess 是一个无状态协议,即客户端和服务器之间不需要握手即可直接传输数据,每一次数据传输对之前和之后的其它数据传输没有影响。

                        VMess 的客户端发起一次请求,服务器判断该请求是否来自一个合法的客户端。如验证通过,则转发该请求,并把获得的响应发回给客户端。

                        VMess 使用非对称格式,即客户端发出的请求和服务器端的响应使用了不同的格式。

                        客户端请求

                        16 字节X 字节余下部分
                        认证信息指令部分数据部分

                        认证信息

                        认证信息是一个 16 字节的哈希(hash)值,它的计算方式如下:

                        • H = MD5
                        • K = 用户 ID (16 字节)
                        • M = UTC 时间,精确到秒,取值为当前时间的前后 30 秒随机值(8 字节, Big Endian)
                        • Hash = HMAC(H, K, M)

                        指令部分

                        指令部分经过 AES-128-CFB 加密:

                        • Key:MD5(用户 ID + []byte('c48619fe-8f02-49e0-b9e9-edf763e17e21'))
                        • IV:MD5(X + X + X + X),X = []byte(认证信息生成的时间) (8 字节, Big Endian)
                        1 字节16 字节16 字节1 字节1 字节4 位4 位1 字节1 字节2 字节1 字节N 字节P 字节4 字节
                        版本号 Ver数据加密 IV数据加密 Key响应认证 V选项 Opt余量 P加密方式 Sec保留指令 Cmd端口 Port地址类型 T地址 A随机值校验 F

                        选项 Opt 细节:(当某一位为 1 时,表示该选项启用)

                        01234567
                        XXXXXMRS

                        其中:

                        • 版本号 Ver:始终为 1;
                        • 数据加密 IV:随机值;
                        • 数据加密 Key:随机值;
                        • 响应认证 V:随机值;
                        • 选项 Opt:
                          • S (0x01):标准格式的数据流(建议开启);
                          • R (0x02):客户端期待重用 TCP 连接(Xray 2.23+ 弃用);
                            • 只有当 S 开启时,这一项才有效;
                          • M (0x04):开启元数据混淆(建议开启);
                            • 只有当 S 开启时,这一项才有效;
                            • 当其项开启时,客户端和服务器端需要分别构造两个 Shake 实例,分别为 RequestMask = Shake(请求数据 IV), ResponseMask = Shake(响应数据 IV)。
                          • X:保留
                        • 余量 P:在校验值之前加入 P 字节的随机值;
                        • 加密方式:指定数据部分的加密方式,可选的值有:
                          • 0x00:AES-128-CFB;
                          • 0x01:不加密;
                          • 0x02:AES-128-GCM;
                          • 0x03:ChaCha20-Poly1305;
                        • 指令 Cmd:
                          • 0x01:TCP 数据;
                          • 0x02:UDP 数据;
                        • 端口 Port:Big Endian 格式的整型端口号;
                        • 地址类型 T:
                          • 0x01:IPv4
                          • 0x02:域名
                          • 0x03:IPv6
                        • 地址 A:
                          • 当 T = 0x01 时,A 为 4 字节 IPv4 地址;
                          • 当 T = 0x02 时,A 为 1 字节长度(L) + L 字节域名;
                          • 当 T = 0x03 时,A 为 16 字节 IPv6 地址;
                        • 校验 F:指令部分除 F 外所有内容的 FNV1a hash;

                        数据部分

                        当 Opt(S) 开启时,数据部分使用此格式。实际的请求数据被分割为若干个小块,每个小块的格式如下。服务器校验完所有的小块之后,再按基本格式的方式进行转发。

                        2 字节L 字节
                        长度 L数据包

                        其中:

                        • 长度 L:Big Endian 格式的整型,最大值为 2^14;
                          • 当 Opt(M) 开启时,L 的值 = 真实值 xor Mask。Mask = (RequestMask.NextByte() << 8) + RequestMask.NextByte();
                        • 数据包:由指定的加密方式加密过的数据包;

                        在传输结束之前,数据包中必须有实际数据,即除了长度和认证数据之外的数据。当传输结束时,客户端必须发送一个空的数据包,即 L = 0(不加密) 或认证数据长度(有加密),来表示传输结束。

                        按加密方式不同,数据包的格式如下:

                        • 不加密:
                          • L 字节:实际数据;
                        • AES-128-CFB:整个数据部分使用 AES-128-CFB 加密
                          • 4 字节:实际数据的 FNV1a hash;
                          • L - 4 字节:实际数据;
                        • AES-128-GCM:Key 为指令部分的 Key,IV = count (2 字节) + IV (10 字节)。count 从 0 开始递增,每个数据包加 1;IV 为 指令部分 IV 的第 3 至第 12 字节。
                          • L - 16 字节:实际数据;
                          • 16 字节:GCM 认证信息
                        • ChaCha20-Poly1305:Key = MD5(指令部分 Key) + MD5(MD5(指令部分 Key)),IV = count (2 字节) + IV (10 字节)。count 从 0 开始递增,每个数据包加 1;IV 为 指令部分 IV 的第 3 至第 12 字节。
                          • L - 16 字节:实际数据;
                          • 16 字节:Poly1305 认证信息

                        服务器应答

                        应答头部数据使用 AES-128-CFB 加密,IV 为 MD5(数据加密 IV),Key 为 MD5(数据加密 Key)。实际应答数据视加密设置不同而不同。

                        1 字节1 字节1 字节1 字节M 字节余下部分
                        响应认证 V选项 Opt指令 Cmd指令长度 M指令内容实际应答数据

                        其中:

                        • 响应认证 V:必须和客户端请求中的响应认证 V 一致;
                        • 选项 Opt:
                          • 0x01:服务器端准备重用 TCP 连接(Xray 2.23+ 弃用);
                        • 指令 Cmd:
                          • 0x01:动态端口指令
                        • 实际应答数据:
                          • 如果请求中的 Opt(S) 开启,则使用标准格式,否则使用基本格式。
                          • 格式均和请求数据相同。
                            • 当 Opt(M) 开启时,长度 L 的值 = 真实值 xor Mask。Mask = (ResponseMask.NextByte() << 8) + ResponseMask.NextByte();

                        动态端口指令

                        1 字节2 字节16 字节2 字节1 字节1 字节
                        保留端口 Port用户 IDAlterID用户等级有效时间 T

                        其中:

                        • 端口 Port:Big Endian 格式的整型端口号;
                        • 有效时间 T:分钟数;

                        客户端在收到动态端口指令时,服务器已开放新的端口用于通信,这时客户端可以将数据发往新的端口。在 T 分钟之后,这个端口将失效,客户端必须重新使用主端口进行通信。

                        注释

                        • 为确保向前兼容性,所有保留字段的值必须为 0。
                        ',37);function k(I,C){const l=h("ExternalLinkIcon");return s(),r("div",null,[c,t("p",null,[e("ID 等价于 "),t("a",o,[e("UUID"),i(l)]),e(",是一个 16 字节长的随机数,它的作用相当于一个令牌(Token)。 一个 ID 形如:de305d54-75b4-431b-adb2-eb6b9e546014,几乎完全随机,可以使用任何的 UUID 生成器来生成,比如"),t("a",p,[e("这个"),i(l)]),e("。")]),x,u,t("ul",null,[t("li",null,[e("MD5: "),t("a",y,[e("MD5 函数"),i(l)]),g]),t("li",null,[e("HMAC: "),t("a",b,[e("HMAC 函数"),i(l)]),_]),t("li",null,[e("Shake: "),t("a",M,[e("SHA3-Shake128 函数"),i(l)]),f])]),V])}const S=n(d,[["render",k],["__file","vmess.html.vue"]]);export{S as default}; +import{_ as n,r as h,o as s,c as r,a as t,b as e,d as i,e as a}from"./app-UOvWaKji.js";const d={},c=a('

                        VMess 协议

                        VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

                        版本

                        当前版本号为 1。

                        依赖

                        底层协议

                        VMess 是一个基于 TCP 的协议,所有数据使用 TCP 传输。

                        用户 ID

                        ',8),o={href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",target:"_blank",rel:"noopener noreferrer"},p={href:"https://www.uuidgenerator.net/",target:"_blank",rel:"noopener noreferrer"},x=t("p",null,[e("用户 ID 可在"),t("a",{href:"../../config"},"配置文件"),e("中指定。")],-1),u=t("h3",{id:"函数",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#函数"},[t("span",null,"函数")])],-1),y={href:"https://en.wikipedia.org/wiki/MD5",target:"_blank",rel:"noopener noreferrer"},g=t("ul",null,[t("li",null,"输入参数为任意长度的 byte 数组"),t("li",null,"输出为一个 16 byte 的数组")],-1),b={href:"https://en.wikipedia.org/wiki/Hash-based_message_authentication_code",target:"_blank",rel:"noopener noreferrer"},_=t("ul",null,[t("li",null,[e("输入参数为: "),t("ul",null,[t("li",null,"H:散列函数"),t("li",null,"K:密钥,任意长度的 byte 数组"),t("li",null,"M:消息,任意长度的 byte 数组")])])],-1),M={href:"https://en.wikipedia.org/wiki/SHA-3",target:"_blank",rel:"noopener noreferrer"},f=t("ul",null,[t("li",null,"输入参数为任意长度的字符串"),t("li",null,"输出为任意长度的字符串")],-1),V=a('

                        通讯过程

                        VMess 是一个无状态协议,即客户端和服务器之间不需要握手即可直接传输数据,每一次数据传输对之前和之后的其它数据传输没有影响。

                        VMess 的客户端发起一次请求,服务器判断该请求是否来自一个合法的客户端。如验证通过,则转发该请求,并把获得的响应发回给客户端。

                        VMess 使用非对称格式,即客户端发出的请求和服务器端的响应使用了不同的格式。

                        客户端请求

                        16 字节X 字节余下部分
                        认证信息指令部分数据部分

                        认证信息

                        认证信息是一个 16 字节的哈希(hash)值,它的计算方式如下:

                        • H = MD5
                        • K = 用户 ID (16 字节)
                        • M = UTC 时间,精确到秒,取值为当前时间的前后 30 秒随机值(8 字节, Big Endian)
                        • Hash = HMAC(H, K, M)

                        指令部分

                        指令部分经过 AES-128-CFB 加密:

                        • Key:MD5(用户 ID + []byte('c48619fe-8f02-49e0-b9e9-edf763e17e21'))
                        • IV:MD5(X + X + X + X),X = []byte(认证信息生成的时间) (8 字节, Big Endian)
                        1 字节16 字节16 字节1 字节1 字节4 位4 位1 字节1 字节2 字节1 字节N 字节P 字节4 字节
                        版本号 Ver数据加密 IV数据加密 Key响应认证 V选项 Opt余量 P加密方式 Sec保留指令 Cmd端口 Port地址类型 T地址 A随机值校验 F

                        选项 Opt 细节:(当某一位为 1 时,表示该选项启用)

                        01234567
                        XXXXXMRS

                        其中:

                        • 版本号 Ver:始终为 1;
                        • 数据加密 IV:随机值;
                        • 数据加密 Key:随机值;
                        • 响应认证 V:随机值;
                        • 选项 Opt:
                          • S (0x01):标准格式的数据流(建议开启);
                          • R (0x02):客户端期待重用 TCP 连接(Xray 2.23+ 弃用);
                            • 只有当 S 开启时,这一项才有效;
                          • M (0x04):开启元数据混淆(建议开启);
                            • 只有当 S 开启时,这一项才有效;
                            • 当其项开启时,客户端和服务器端需要分别构造两个 Shake 实例,分别为 RequestMask = Shake(请求数据 IV), ResponseMask = Shake(响应数据 IV)。
                          • X:保留
                        • 余量 P:在校验值之前加入 P 字节的随机值;
                        • 加密方式:指定数据部分的加密方式,可选的值有:
                          • 0x00:AES-128-CFB;
                          • 0x01:不加密;
                          • 0x02:AES-128-GCM;
                          • 0x03:ChaCha20-Poly1305;
                        • 指令 Cmd:
                          • 0x01:TCP 数据;
                          • 0x02:UDP 数据;
                        • 端口 Port:Big Endian 格式的整型端口号;
                        • 地址类型 T:
                          • 0x01:IPv4
                          • 0x02:域名
                          • 0x03:IPv6
                        • 地址 A:
                          • 当 T = 0x01 时,A 为 4 字节 IPv4 地址;
                          • 当 T = 0x02 时,A 为 1 字节长度(L) + L 字节域名;
                          • 当 T = 0x03 时,A 为 16 字节 IPv6 地址;
                        • 校验 F:指令部分除 F 外所有内容的 FNV1a hash;

                        数据部分

                        当 Opt(S) 开启时,数据部分使用此格式。实际的请求数据被分割为若干个小块,每个小块的格式如下。服务器校验完所有的小块之后,再按基本格式的方式进行转发。

                        2 字节L 字节
                        长度 L数据包

                        其中:

                        • 长度 L:Big Endian 格式的整型,最大值为 2^14;
                          • 当 Opt(M) 开启时,L 的值 = 真实值 xor Mask。Mask = (RequestMask.NextByte() << 8) + RequestMask.NextByte();
                        • 数据包:由指定的加密方式加密过的数据包;

                        在传输结束之前,数据包中必须有实际数据,即除了长度和认证数据之外的数据。当传输结束时,客户端必须发送一个空的数据包,即 L = 0(不加密) 或认证数据长度(有加密),来表示传输结束。

                        按加密方式不同,数据包的格式如下:

                        • 不加密:
                          • L 字节:实际数据;
                        • AES-128-CFB:整个数据部分使用 AES-128-CFB 加密
                          • 4 字节:实际数据的 FNV1a hash;
                          • L - 4 字节:实际数据;
                        • AES-128-GCM:Key 为指令部分的 Key,IV = count (2 字节) + IV (10 字节)。count 从 0 开始递增,每个数据包加 1;IV 为 指令部分 IV 的第 3 至第 12 字节。
                          • L - 16 字节:实际数据;
                          • 16 字节:GCM 认证信息
                        • ChaCha20-Poly1305:Key = MD5(指令部分 Key) + MD5(MD5(指令部分 Key)),IV = count (2 字节) + IV (10 字节)。count 从 0 开始递增,每个数据包加 1;IV 为 指令部分 IV 的第 3 至第 12 字节。
                          • L - 16 字节:实际数据;
                          • 16 字节:Poly1305 认证信息

                        服务器应答

                        应答头部数据使用 AES-128-CFB 加密,IV 为 MD5(数据加密 IV),Key 为 MD5(数据加密 Key)。实际应答数据视加密设置不同而不同。

                        1 字节1 字节1 字节1 字节M 字节余下部分
                        响应认证 V选项 Opt指令 Cmd指令长度 M指令内容实际应答数据

                        其中:

                        • 响应认证 V:必须和客户端请求中的响应认证 V 一致;
                        • 选项 Opt:
                          • 0x01:服务器端准备重用 TCP 连接(Xray 2.23+ 弃用);
                        • 指令 Cmd:
                          • 0x01:动态端口指令
                        • 实际应答数据:
                          • 如果请求中的 Opt(S) 开启,则使用标准格式,否则使用基本格式。
                          • 格式均和请求数据相同。
                            • 当 Opt(M) 开启时,长度 L 的值 = 真实值 xor Mask。Mask = (ResponseMask.NextByte() << 8) + ResponseMask.NextByte();

                        动态端口指令

                        1 字节2 字节16 字节2 字节1 字节1 字节
                        保留端口 Port用户 IDAlterID用户等级有效时间 T

                        其中:

                        • 端口 Port:Big Endian 格式的整型端口号;
                        • 有效时间 T:分钟数;

                        客户端在收到动态端口指令时,服务器已开放新的端口用于通信,这时客户端可以将数据发往新的端口。在 T 分钟之后,这个端口将失效,客户端必须重新使用主端口进行通信。

                        注释

                        • 为确保向前兼容性,所有保留字段的值必须为 0。
                        ',37);function k(I,C){const l=h("ExternalLinkIcon");return s(),r("div",null,[c,t("p",null,[e("ID 等价于 "),t("a",o,[e("UUID"),i(l)]),e(",是一个 16 字节长的随机数,它的作用相当于一个令牌(Token)。 一个 ID 形如:de305d54-75b4-431b-adb2-eb6b9e546014,几乎完全随机,可以使用任何的 UUID 生成器来生成,比如"),t("a",p,[e("这个"),i(l)]),e("。")]),x,u,t("ul",null,[t("li",null,[e("MD5: "),t("a",y,[e("MD5 函数"),i(l)]),g]),t("li",null,[e("HMAC: "),t("a",b,[e("HMAC 函数"),i(l)]),_]),t("li",null,[e("Shake: "),t("a",M,[e("SHA3-Shake128 函数"),i(l)]),f])]),V])}const S=n(d,[["render",k],["__file","vmess.html.vue"]]);export{S as default}; diff --git a/assets/vmess.html-MOyi84fJ.js b/assets/vmess.html-5Z4DWDCo.js similarity index 99% rename from assets/vmess.html-MOyi84fJ.js rename to assets/vmess.html-5Z4DWDCo.js index b063778c99..19841c023f 100644 --- a/assets/vmess.html-MOyi84fJ.js +++ b/assets/vmess.html-5Z4DWDCo.js @@ -1,4 +1,4 @@ -import{_ as u,r as t,o as l,c as i,a as s,d as e,w as a,b as n,e as c}from"./app-PDrbPfzp.js";const r={},d=s("h1",{id:"vmess",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#vmess"},[s("span",null,"VMess")])],-1),q=c(`

                        警告

                        VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 120 秒之内,时区无关。在 Linux 系统中可以安装ntp服务来自动同步系统时间。

                        OutboundConfigurationObject

                        {
                        +import{_ as u,r as t,o as l,c as i,a as s,d as e,w as a,b as n,e as c}from"./app-UOvWaKji.js";const r={},d=s("h1",{id:"vmess",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#vmess"},[s("span",null,"VMess")])],-1),q=c(`

                        警告

                        VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 120 秒之内,时区无关。在 Linux 系统中可以安装ntp服务来自动同步系统时间。

                        OutboundConfigurationObject

                        {
                           "vnext": [
                             {
                               "address": "127.0.0.1",
                        diff --git a/assets/vmess.html-Ajbfrx88.js b/assets/vmess.html-BwXqJ3Vn.js
                        similarity index 99%
                        rename from assets/vmess.html-Ajbfrx88.js
                        rename to assets/vmess.html-BwXqJ3Vn.js
                        index 25a59aa659..f46fc46af0 100644
                        --- a/assets/vmess.html-Ajbfrx88.js
                        +++ b/assets/vmess.html-BwXqJ3Vn.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as o,o as p,c as r,a as e,d as s,w as a,b as n,e as l}from"./app-PDrbPfzp.js";const u={},d=e("h1",{id:"vmess",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vmess"},[e("span",null,"VMess")])],-1),h=l(`

                        Danger

                        VMess relies on system time. Please ensure that the system UTC time used by Xray is within 120 seconds of the actual time, regardless of time zone. On Linux systems, you can install the ntp service to automatically synchronize the system time.

                        InboundConfigurationObject

                        {
                        +import{_ as i,r as o,o as p,c as r,a as e,d as s,w as a,b as n,e as l}from"./app-UOvWaKji.js";const u={},d=e("h1",{id:"vmess",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vmess"},[e("span",null,"VMess")])],-1),h=l(`

                        Danger

                        VMess relies on system time. Please ensure that the system UTC time used by Xray is within 120 seconds of the actual time, regardless of time zone. On Linux systems, you can install the ntp service to automatically synchronize the system time.

                        InboundConfigurationObject

                        {
                           "clients": [
                             {
                               "id": "5783a3e7-e373-51cd-8642-c83782b807c5",
                        diff --git a/assets/vmess.html-gVQqtA6f.js b/assets/vmess.html-Q9QMl6ca.js
                        similarity index 99%
                        rename from assets/vmess.html-gVQqtA6f.js
                        rename to assets/vmess.html-Q9QMl6ca.js
                        index 50be69a05b..73f96ffb0f 100644
                        --- a/assets/vmess.html-gVQqtA6f.js
                        +++ b/assets/vmess.html-Q9QMl6ca.js
                        @@ -1 +1 @@
                        -import{_ as s,r as l,o as r,c as o,a as t,b as e,d as a,e as i}from"./app-PDrbPfzp.js";const h={},d=i('

                        VMess Protocol

                        VMess is an encrypted transmission protocol that can serve as a bridge between the Xray client and server.

                        Version

                        The current version number is 1.

                        Dependencies

                        Underlying Protocol

                        VMess is a TCP-based protocol where all data is transmitted over TCP.

                        User ID

                        ',8),c={href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",target:"_blank",rel:"noopener noreferrer"},u=t("code",null,"de305d54-75b4-431b-adb2-eb6b9e546014",-1),p={href:"https://www.uuidgenerator.net/",target:"_blank",rel:"noopener noreferrer"},y=t("p",null,[e("User ID can be specified in the "),t("a",{href:"../../config"},"configuration file"),e(".")],-1),m=t("h3",{id:"functions",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#functions"},[t("span",null,"Functions")])],-1),b={href:"https://en.wikipedia.org/wiki/MD5",target:"_blank",rel:"noopener noreferrer"},f=t("ul",null,[t("li",null,"Input parameter is any length byte array"),t("li",null,"Output is a 16-byte array")],-1),g={href:"https://en.wikipedia.org/wiki/Hash-based_message_authentication_code",target:"_blank",rel:"noopener noreferrer"},x=t("ul",null,[t("li",null,[e("Input parameters are: "),t("ul",null,[t("li",null,"H: Hash function"),t("li",null,"K: Key, any length byte array"),t("li",null,"M: Message, any length byte array")])])],-1),v={href:"https://en.wikipedia.org/wiki/SHA-3",target:"_blank",rel:"noopener noreferrer"},k=t("ul",null,[t("li",null,"Input parameter is any length string"),t("li",null,"Output is any length string")],-1),_=i('

                        Communication Process

                        VMess is a stateless protocol, which means that data can be transmitted directly between the client and the server without the need for a handshake. Each data transmission has no impact on other data transmissions before or after it.

                        When a VMess client initiates a request, the server checks whether the request comes from a legitimate client. If the validation passes, the server forwards the request and sends the obtained response back to the client.

                        VMess uses an asymmetric format, meaning that the requests sent by the client and the responses from the server use different formats.

                        Client Request

                        16 BytesX BytesRemaining
                        Authentication InformationInstruction PartData Part

                        Authentication Information

                        The authentication information is a 16-byte hash (hash) value, which is calculated as follows:

                        • H = MD5
                        • K = User ID (16 bytes)
                        • M = UTC time accurate to seconds, with a random value of ±30 seconds from the current time (8 bytes, Big Endian)
                        • Hash = HMAC(H, K, M)

                        Command Section

                        The instruction part is encrypted using AES-128-CFB.

                        • Key: MD5(user ID + []byte('c48619fe-8f02-49e0-b9e9-edf763e17e21'))
                        • IV: MD5(X + X + X + X), X = []byte(time generated by authentication information) (8 bytes, Big Endian)
                        1 Byte16 Bytes16 Bytes1 Byte1 Byte4 bits4 bits1 Byte1 Byte2 Bytes1 ByteN BytesP Bytes4 Bytes
                        VersionData Encryption IVData Encryption KeyResponse Authentication ValueOptionsReservedEncryption MethodReservedCommandPortAddress TypeAddressRandom ValueChecksum

                        Options Opt Details: (When a bit is 1, it means the option is enabled)

                        01234567
                        XXXXXMRS

                        of which:

                        • Version Number Ver: Always 1;
                        • Data Encryption IV: Random value;
                        • Data Encryption Key: Random value;
                        • Response Authentication V: Random value;
                        • Option Opt:
                          • S (0x01): Standard format data stream (recommended);
                          • R (0x02): Client expects to reuse TCP connection (deprecated in Xray 2.23+);
                            • This item only takes effect when S is enabled;
                          • M (0x04): Enable metadata obfuscation (recommended);
                            • This item only takes effect when S is enabled;
                            • When this item is enabled, the client and server need to construct two Shake instances respectively, RequestMask = Shake (request data IV), ResponseMask = Shake (response data IV).
                          • X: Reserved
                        • Redundancy P: Random value added before checksum value;
                        • Encryption Method: Specify the encryption method for the data part, and the optional values are:
                          • 0x00: AES-128-CFB;
                          • 0x01: No encryption;
                          • 0x02: AES-128-GCM;
                          • 0x03: ChaCha20-Poly1305;
                        • Instruction Cmd:
                          • 0x01: TCP data;
                          • 0x02: UDP data;
                        • Port Port: Integer port number in Big Endian format;
                        • Address Type T:
                          • 0x01: IPv4
                          • 0x02: Domain name
                          • 0x03: IPv6
                        • Address A:
                          • When T = 0x01, A is a 4-byte IPv4 address;
                          • When T = 0x02, A is a 1-byte length (L) + L-byte domain name;
                          • When T = 0x03, A is a 16-byte IPv6 address;
                        • Check F: FNV1a hash of all content in the instruction except F.

                        Data Section

                        When Opt(S) is enabled, this format is used for the data section. The actual request data is divided into several small chunks, and each chunk has the following format. After the server verifies all the small chunks, it will be forwarded in the basic format.

                        2 BytesL Bytes
                        Length LData Packet

                        in which:

                        • Length L: A big-endian integer with a maximum value of 2^14.
                          • When Opt(M) is enabled, the value of L is equal to the true value xor Mask. Mask = (RequestMask.NextByte() << 8) + RequestMask.NextByte();
                        • Packet: A data packet encrypted by the specified encryption method.

                        Before the transmission is completed, the data packet must contain actual data, in addition to the length and authentication data. When the transmission is complete, the client must send an empty data packet, that is, L = 0 (unencrypted) or the length of the authentication data (encrypted), to indicate the end of the transmission.

                        The packets are formatted as follows, depending on the encryption method:

                        • Unencrypted:   - L bytes: actual data;
                        • AES-128-CFB: The entire data section is encrypted using AES-128-CFB.   - 4 bytes: FNV1a hash of actual data;   - L - 4 bytes: actual data;
                        • AES-128-GCM: Key is the Key of the instruction section, IV = count (2 bytes) + IV (10 bytes). count starts at 0 and increases by 1 for each packet; IV is the 3rd to 12th byte of the instruction section IV.   - L - 16 bytes: actual data;   - 16 bytes: GCM authentication information
                        • ChaCha20-Poly1305: Key = MD5 (instruction part Key) + MD5 (MD5 (instruction part Key)), IV = count (2 bytes) + IV (10 bytes). count starts at 0 and increases by 1 for each packet; IV is the 3rd to 12th byte of the instruction section IV.   - L - 16 bytes: actual data;   - 16 bytes: Poly1305 authentication information

                        Server Response

                        The header data is encrypted using AES-128-CFB encryption. The IV is MD5 of the data encryption IV, and the Key is MD5 of the data encryption Key. The actual response data varies depending on the encryption settings.

                        1 Byte1 Byte1 Byte1 ByteM BytesRemaining Part
                        Response Authentication VOption OptCommand CmdCommand Length MCommand ContentActual Response Data

                        in which:

                        • Response Authentication V: must match the response authentication V in the client request.
                        • Option Opt:
                          • 0x01: server prepares to reuse TCP connections (deprecated in Xray 2.23+).
                        • Command Cmd:
                          • 0x01: dynamic port command.
                        • Actual response data:
                          • If Opt(S) in the request is enabled, the standard format is used. Otherwise, the basic format is used.
                          • Both formats are identical to the request data.
                            • When Opt(M) is enabled, the value of length L is equal to the true value XOR Mask. Mask = (ResponseMask.NextByte() << 8) + ResponseMask.NextByte().

                        Dynamic Port Instructions

                        1 Byte2 Bytes16 Bytes2 Bytes1 Byte1 Byte
                        ReservedPortUser IDAlterIDUser levelValidity period T

                        in which:

                        • Port: Integer port number in Big Endian format
                        • T: Number of minutes as integer value.

                        When the client receives a dynamic port command, the server opens a new port for communication. The client can then send data to the new port. After T minutes, the port will expire, and the client must use the main port to communicate again.

                        Comment

                        • To ensure forward compatibility, the values of all reserved fields must be 0.
                        ',37);function B(M,I){const n=l("ExternalLinkIcon");return r(),o("div",null,[d,t("p",null,[e("An ID is equivalent to a "),t("a",c,[e("UUID"),a(n)]),e(", which is a 16-byte long random number. Its function is similar to a token. An ID looks like: "),u,e(", it is almost entirely random and can be generated using any UUID generator, such as "),t("a",p,[e("this one"),a(n)]),e(".")]),y,m,t("ul",null,[t("li",null,[e("MD5: "),t("a",b,[e("MD5 Function"),a(n)]),f]),t("li",null,[e("HMAC: "),t("a",g,[e("HMAC Function"),a(n)]),x]),t("li",null,[e("Shake: "),t("a",v,[e("SHA3-Shake128 Function"),a(n)]),k])]),_])}const C=s(h,[["render",B],["__file","vmess.html.vue"]]);export{C as default}; +import{_ as s,r as l,o as r,c as o,a as t,b as e,d as a,e as i}from"./app-UOvWaKji.js";const h={},d=i('

                        VMess Protocol

                        VMess is an encrypted transmission protocol that can serve as a bridge between the Xray client and server.

                        Version

                        The current version number is 1.

                        Dependencies

                        Underlying Protocol

                        VMess is a TCP-based protocol where all data is transmitted over TCP.

                        User ID

                        ',8),c={href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",target:"_blank",rel:"noopener noreferrer"},u=t("code",null,"de305d54-75b4-431b-adb2-eb6b9e546014",-1),p={href:"https://www.uuidgenerator.net/",target:"_blank",rel:"noopener noreferrer"},y=t("p",null,[e("User ID can be specified in the "),t("a",{href:"../../config"},"configuration file"),e(".")],-1),m=t("h3",{id:"functions",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#functions"},[t("span",null,"Functions")])],-1),b={href:"https://en.wikipedia.org/wiki/MD5",target:"_blank",rel:"noopener noreferrer"},f=t("ul",null,[t("li",null,"Input parameter is any length byte array"),t("li",null,"Output is a 16-byte array")],-1),g={href:"https://en.wikipedia.org/wiki/Hash-based_message_authentication_code",target:"_blank",rel:"noopener noreferrer"},x=t("ul",null,[t("li",null,[e("Input parameters are: "),t("ul",null,[t("li",null,"H: Hash function"),t("li",null,"K: Key, any length byte array"),t("li",null,"M: Message, any length byte array")])])],-1),v={href:"https://en.wikipedia.org/wiki/SHA-3",target:"_blank",rel:"noopener noreferrer"},k=t("ul",null,[t("li",null,"Input parameter is any length string"),t("li",null,"Output is any length string")],-1),_=i('

                        Communication Process

                        VMess is a stateless protocol, which means that data can be transmitted directly between the client and the server without the need for a handshake. Each data transmission has no impact on other data transmissions before or after it.

                        When a VMess client initiates a request, the server checks whether the request comes from a legitimate client. If the validation passes, the server forwards the request and sends the obtained response back to the client.

                        VMess uses an asymmetric format, meaning that the requests sent by the client and the responses from the server use different formats.

                        Client Request

                        16 BytesX BytesRemaining
                        Authentication InformationInstruction PartData Part

                        Authentication Information

                        The authentication information is a 16-byte hash (hash) value, which is calculated as follows:

                        • H = MD5
                        • K = User ID (16 bytes)
                        • M = UTC time accurate to seconds, with a random value of ±30 seconds from the current time (8 bytes, Big Endian)
                        • Hash = HMAC(H, K, M)

                        Command Section

                        The instruction part is encrypted using AES-128-CFB.

                        • Key: MD5(user ID + []byte('c48619fe-8f02-49e0-b9e9-edf763e17e21'))
                        • IV: MD5(X + X + X + X), X = []byte(time generated by authentication information) (8 bytes, Big Endian)
                        1 Byte16 Bytes16 Bytes1 Byte1 Byte4 bits4 bits1 Byte1 Byte2 Bytes1 ByteN BytesP Bytes4 Bytes
                        VersionData Encryption IVData Encryption KeyResponse Authentication ValueOptionsReservedEncryption MethodReservedCommandPortAddress TypeAddressRandom ValueChecksum

                        Options Opt Details: (When a bit is 1, it means the option is enabled)

                        01234567
                        XXXXXMRS

                        of which:

                        • Version Number Ver: Always 1;
                        • Data Encryption IV: Random value;
                        • Data Encryption Key: Random value;
                        • Response Authentication V: Random value;
                        • Option Opt:
                          • S (0x01): Standard format data stream (recommended);
                          • R (0x02): Client expects to reuse TCP connection (deprecated in Xray 2.23+);
                            • This item only takes effect when S is enabled;
                          • M (0x04): Enable metadata obfuscation (recommended);
                            • This item only takes effect when S is enabled;
                            • When this item is enabled, the client and server need to construct two Shake instances respectively, RequestMask = Shake (request data IV), ResponseMask = Shake (response data IV).
                          • X: Reserved
                        • Redundancy P: Random value added before checksum value;
                        • Encryption Method: Specify the encryption method for the data part, and the optional values are:
                          • 0x00: AES-128-CFB;
                          • 0x01: No encryption;
                          • 0x02: AES-128-GCM;
                          • 0x03: ChaCha20-Poly1305;
                        • Instruction Cmd:
                          • 0x01: TCP data;
                          • 0x02: UDP data;
                        • Port Port: Integer port number in Big Endian format;
                        • Address Type T:
                          • 0x01: IPv4
                          • 0x02: Domain name
                          • 0x03: IPv6
                        • Address A:
                          • When T = 0x01, A is a 4-byte IPv4 address;
                          • When T = 0x02, A is a 1-byte length (L) + L-byte domain name;
                          • When T = 0x03, A is a 16-byte IPv6 address;
                        • Check F: FNV1a hash of all content in the instruction except F.

                        Data Section

                        When Opt(S) is enabled, this format is used for the data section. The actual request data is divided into several small chunks, and each chunk has the following format. After the server verifies all the small chunks, it will be forwarded in the basic format.

                        2 BytesL Bytes
                        Length LData Packet

                        in which:

                        • Length L: A big-endian integer with a maximum value of 2^14.
                          • When Opt(M) is enabled, the value of L is equal to the true value xor Mask. Mask = (RequestMask.NextByte() << 8) + RequestMask.NextByte();
                        • Packet: A data packet encrypted by the specified encryption method.

                        Before the transmission is completed, the data packet must contain actual data, in addition to the length and authentication data. When the transmission is complete, the client must send an empty data packet, that is, L = 0 (unencrypted) or the length of the authentication data (encrypted), to indicate the end of the transmission.

                        The packets are formatted as follows, depending on the encryption method:

                        • Unencrypted:   - L bytes: actual data;
                        • AES-128-CFB: The entire data section is encrypted using AES-128-CFB.   - 4 bytes: FNV1a hash of actual data;   - L - 4 bytes: actual data;
                        • AES-128-GCM: Key is the Key of the instruction section, IV = count (2 bytes) + IV (10 bytes). count starts at 0 and increases by 1 for each packet; IV is the 3rd to 12th byte of the instruction section IV.   - L - 16 bytes: actual data;   - 16 bytes: GCM authentication information
                        • ChaCha20-Poly1305: Key = MD5 (instruction part Key) + MD5 (MD5 (instruction part Key)), IV = count (2 bytes) + IV (10 bytes). count starts at 0 and increases by 1 for each packet; IV is the 3rd to 12th byte of the instruction section IV.   - L - 16 bytes: actual data;   - 16 bytes: Poly1305 authentication information

                        Server Response

                        The header data is encrypted using AES-128-CFB encryption. The IV is MD5 of the data encryption IV, and the Key is MD5 of the data encryption Key. The actual response data varies depending on the encryption settings.

                        1 Byte1 Byte1 Byte1 ByteM BytesRemaining Part
                        Response Authentication VOption OptCommand CmdCommand Length MCommand ContentActual Response Data

                        in which:

                        • Response Authentication V: must match the response authentication V in the client request.
                        • Option Opt:
                          • 0x01: server prepares to reuse TCP connections (deprecated in Xray 2.23+).
                        • Command Cmd:
                          • 0x01: dynamic port command.
                        • Actual response data:
                          • If Opt(S) in the request is enabled, the standard format is used. Otherwise, the basic format is used.
                          • Both formats are identical to the request data.
                            • When Opt(M) is enabled, the value of length L is equal to the true value XOR Mask. Mask = (ResponseMask.NextByte() << 8) + ResponseMask.NextByte().

                        Dynamic Port Instructions

                        1 Byte2 Bytes16 Bytes2 Bytes1 Byte1 Byte
                        ReservedPortUser IDAlterIDUser levelValidity period T

                        in which:

                        • Port: Integer port number in Big Endian format
                        • T: Number of minutes as integer value.

                        When the client receives a dynamic port command, the server opens a new port for communication. The client can then send data to the new port. After T minutes, the port will expire, and the client must use the main port to communicate again.

                        Comment

                        • To ensure forward compatibility, the values of all reserved fields must be 0.
                        ',37);function B(M,I){const n=l("ExternalLinkIcon");return r(),o("div",null,[d,t("p",null,[e("An ID is equivalent to a "),t("a",c,[e("UUID"),a(n)]),e(", which is a 16-byte long random number. Its function is similar to a token. An ID looks like: "),u,e(", it is almost entirely random and can be generated using any UUID generator, such as "),t("a",p,[e("this one"),a(n)]),e(".")]),y,m,t("ul",null,[t("li",null,[e("MD5: "),t("a",b,[e("MD5 Function"),a(n)]),f]),t("li",null,[e("HMAC: "),t("a",g,[e("HMAC Function"),a(n)]),x]),t("li",null,[e("Shake: "),t("a",v,[e("SHA3-Shake128 Function"),a(n)]),k])]),_])}const C=s(h,[["render",B],["__file","vmess.html.vue"]]);export{C as default}; diff --git a/assets/vmess.html-wh0ZrbYC.js b/assets/vmess.html-XpONl2yo.js similarity index 99% rename from assets/vmess.html-wh0ZrbYC.js rename to assets/vmess.html-XpONl2yo.js index d1120224b1..dfee8eb9b1 100644 --- a/assets/vmess.html-wh0ZrbYC.js +++ b/assets/vmess.html-XpONl2yo.js @@ -1,4 +1,4 @@ -import{_ as p,r as t,o as i,c as u,a as e,d as s,w as o,b as n,e as l}from"./app-PDrbPfzp.js";const d={},r=e("h1",{id:"vmess",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vmess"},[e("span",null,"VMess")])],-1),b=l(`

                        警告

                        VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 120 秒之内,时区无关。在 Linux 系统中可以安装ntp服务来自动同步系统时间。

                        InboundConfigurationObject

                        {
                        +import{_ as p,r as t,o as i,c as u,a as e,d as s,w as o,b as n,e as l}from"./app-UOvWaKji.js";const d={},r=e("h1",{id:"vmess",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vmess"},[e("span",null,"VMess")])],-1),b=l(`

                        警告

                        VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 120 秒之内,时区无关。在 Linux 系统中可以安装ntp服务来自动同步系统时间。

                        InboundConfigurationObject

                        {
                           "clients": [
                             {
                               "id": "5783a3e7-e373-51cd-8642-c83782b807c5",
                        diff --git a/assets/vmess.html-mxEzZ4Nm.js b/assets/vmess.html-bWXrud15.js
                        similarity index 99%
                        rename from assets/vmess.html-mxEzZ4Nm.js
                        rename to assets/vmess.html-bWXrud15.js
                        index 662cb15100..205f22a75c 100644
                        --- a/assets/vmess.html-mxEzZ4Nm.js
                        +++ b/assets/vmess.html-bWXrud15.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as a,o as u,c as p,a as n,d as s,w as t,b as e,e as c}from"./app-PDrbPfzp.js";const l={},d=n("h1",{id:"vmess",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#vmess"},[n("span",null,"VMess")])],-1),h=c(`

                        Danger

                        VMess relies on system time. Please ensure that the UTC time of your system, when using Xray, has an error within 120 seconds, regardless of the time zone. On Linux systems, you can install the ntp service to automatically synchronize the system time.

                        OutboundConfigurationObject

                        {
                        +import{_ as i,r as a,o as u,c as p,a as n,d as s,w as t,b as e,e as c}from"./app-UOvWaKji.js";const l={},d=n("h1",{id:"vmess",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#vmess"},[n("span",null,"VMess")])],-1),h=c(`

                        Danger

                        VMess relies on system time. Please ensure that the UTC time of your system, when using Xray, has an error within 120 seconds, regardless of the time zone. On Linux systems, you can install the ntp service to automatically synchronize the system time.

                        OutboundConfigurationObject

                        {
                           "vnext": [
                             {
                               "address": "127.0.0.1",
                        diff --git a/assets/warp.html-co4A2qJl.js b/assets/warp.html-InWQqDIT.js
                        similarity index 99%
                        rename from assets/warp.html-co4A2qJl.js
                        rename to assets/warp.html-InWQqDIT.js
                        index 22e150c2ef..720cce5236 100644
                        --- a/assets/warp.html-co4A2qJl.js
                        +++ b/assets/warp.html-InWQqDIT.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as o,o as l,c,a as n,b as s,d as t,e}from"./app-PDrbPfzp.js";const u={},i=n("h1",{id:"通过-cloudflare-warp-增强代理安全性",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#通过-cloudflare-warp-增强代理安全性"},[n("span",null,"通过 Cloudflare Warp 增强代理安全性")])],-1),r=n("p",null,"Xray(1.6.5+)新加入了 WireGuard 出站,虽然增加的代码和依赖会增大 core 体积,但是我们认为这是一个很有必要的新功能,原因有三:",-1),d={href:"https://github.com/net4people/bbs/issues/129#issuecomment-1308102504",target:"_blank",rel:"noopener noreferrer"},k=n("li",null,"众所周知,大部分机场会记录用户访问域名的日志,某些机场还会审计和阻断一些用户流量。保护用户私密性的一个方法,就是在客户端使用链式代理。 Warp 使用的 WireGuard 轻量级 VPN 协议会在代理层内增加一层加密。对于机场而言,用户所有流量的目标都是 Warp,从而最大程度保护自己的隐私。",-1),v=n("li",null,"方便使用,只需要一个 core 即可完成分流,Wireguard Tun,链式代理的设置。",-1),q=e('

                        申请 Warp 账户

                        感谢 Cloudflare 推动自由的互联网,现在你可以免费使用 Warp 服务,连接的时候会根据出口自动选择最近的服务器

                        方法 1:

                        ',3),m={href:"https://github.com/ViRb3/wgcf/releases",target:"_blank",rel:"noopener noreferrer"},b=n("li",null,[s("运行 "),n("code",null,"wgcf register"),s(" 生成 "),n("code",null,"wgcf-account.toml")],-1),g=n("li",null,[s("运行 "),n("code",null,"wgcf generate"),s(" 生成 "),n("code",null,"wgcf-profile.conf"),s(" 拷贝内容如下:")],-1),y=e(`
                        [Interface]
                        +import{_ as p,r as o,o as l,c,a as n,b as s,d as t,e}from"./app-UOvWaKji.js";const u={},i=n("h1",{id:"通过-cloudflare-warp-增强代理安全性",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#通过-cloudflare-warp-增强代理安全性"},[n("span",null,"通过 Cloudflare Warp 增强代理安全性")])],-1),r=n("p",null,"Xray(1.6.5+)新加入了 WireGuard 出站,虽然增加的代码和依赖会增大 core 体积,但是我们认为这是一个很有必要的新功能,原因有三:",-1),d={href:"https://github.com/net4people/bbs/issues/129#issuecomment-1308102504",target:"_blank",rel:"noopener noreferrer"},k=n("li",null,"众所周知,大部分机场会记录用户访问域名的日志,某些机场还会审计和阻断一些用户流量。保护用户私密性的一个方法,就是在客户端使用链式代理。 Warp 使用的 WireGuard 轻量级 VPN 协议会在代理层内增加一层加密。对于机场而言,用户所有流量的目标都是 Warp,从而最大程度保护自己的隐私。",-1),v=n("li",null,"方便使用,只需要一个 core 即可完成分流,Wireguard Tun,链式代理的设置。",-1),q=e('

                        申请 Warp 账户

                        感谢 Cloudflare 推动自由的互联网,现在你可以免费使用 Warp 服务,连接的时候会根据出口自动选择最近的服务器

                        方法 1:

                        ',3),m={href:"https://github.com/ViRb3/wgcf/releases",target:"_blank",rel:"noopener noreferrer"},b=n("li",null,[s("运行 "),n("code",null,"wgcf register"),s(" 生成 "),n("code",null,"wgcf-account.toml")],-1),g=n("li",null,[s("运行 "),n("code",null,"wgcf generate"),s(" 生成 "),n("code",null,"wgcf-profile.conf"),s(" 拷贝内容如下:")],-1),y=e(`
                        [Interface]
                         PrivateKey = 我的私钥
                         Address = 172.16.0.2/32
                         Address = 2606:4700:110:8949:fed8:2642:a640:c8e1/128
                        diff --git a/assets/warp.html-A8L2N42a.js b/assets/warp.html-Nyf1dpD9.js
                        similarity index 99%
                        rename from assets/warp.html-A8L2N42a.js
                        rename to assets/warp.html-Nyf1dpD9.js
                        index c82c51578f..97f5c26d79 100644
                        --- a/assets/warp.html-A8L2N42a.js
                        +++ b/assets/warp.html-Nyf1dpD9.js
                        @@ -1,4 +1,4 @@
                        -import{_ as t,r as o,o as p,c as i,a as n,b as s,d as e,e as l}from"./app-PDrbPfzp.js";const c={},r=n("h1",{id:"enhancing-proxy-security-with-cloudflare-warp",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#enhancing-proxy-security-with-cloudflare-warp"},[n("span",null,"Enhancing Proxy Security with Cloudflare Warp")])],-1),u=n("p",null,"Xray (1.6.5+) has added outbound WireGuard support. Although the added code and dependencies will increase the core size, we believe that this is a necessary new feature for three reasons:",-1),d={href:"https://github.com/net4people/bbs/issues/129#issuecomment-1308102504",target:"_blank",rel:"noopener noreferrer"},v=n("li",null,"As we all know, most airports will log the domain names visited by users, and some airports will even audit and block some user traffic. One way to protect user privacy is to use chain proxies on the client side. The WireGuard lightweight VPN protocol used by Warp adds an extra layer of encryption within the proxy layer. For airports, the target of all user traffic is Warp, thereby maximizing privacy protection.",-1),k=n("li",null,"It is easy to use, and only one core is needed to complete the split, Wireguard Tun, and chain proxy settings.",-1),m=n("h2",{id:"applying-for-a-warp-account",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#applying-for-a-warp-account"},[n("span",null,"Applying for a Warp Account")])],-1),b=n("li",null,"Thank you Cloudflare for promoting a free internet. Now you can use the Warp service for free, and the nearest server will be automatically selected based on the exit.",-1),q={href:"https://github.com/ViRb3/wgcf/releases",target:"_blank",rel:"noopener noreferrer"},h=n("li",null,[s("Run "),n("code",null,"wgcf register"),s(" to generate "),n("code",null,"wgcf-account.toml"),s(".")],-1),g=n("li",null,[s("Run "),n("code",null,"wgcf generate"),s(" to generate "),n("code",null,"wgcf-profile.conf"),s(". Copy the following content:")],-1),y=l(`
                        [Interface]
                        +import{_ as t,r as o,o as p,c as i,a as n,b as s,d as e,e as l}from"./app-UOvWaKji.js";const c={},r=n("h1",{id:"enhancing-proxy-security-with-cloudflare-warp",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#enhancing-proxy-security-with-cloudflare-warp"},[n("span",null,"Enhancing Proxy Security with Cloudflare Warp")])],-1),u=n("p",null,"Xray (1.6.5+) has added outbound WireGuard support. Although the added code and dependencies will increase the core size, we believe that this is a necessary new feature for three reasons:",-1),d={href:"https://github.com/net4people/bbs/issues/129#issuecomment-1308102504",target:"_blank",rel:"noopener noreferrer"},v=n("li",null,"As we all know, most airports will log the domain names visited by users, and some airports will even audit and block some user traffic. One way to protect user privacy is to use chain proxies on the client side. The WireGuard lightweight VPN protocol used by Warp adds an extra layer of encryption within the proxy layer. For airports, the target of all user traffic is Warp, thereby maximizing privacy protection.",-1),k=n("li",null,"It is easy to use, and only one core is needed to complete the split, Wireguard Tun, and chain proxy settings.",-1),m=n("h2",{id:"applying-for-a-warp-account",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#applying-for-a-warp-account"},[n("span",null,"Applying for a Warp Account")])],-1),b=n("li",null,"Thank you Cloudflare for promoting a free internet. Now you can use the Warp service for free, and the nearest server will be automatically selected based on the exit.",-1),q={href:"https://github.com/ViRb3/wgcf/releases",target:"_blank",rel:"noopener noreferrer"},h=n("li",null,[s("Run "),n("code",null,"wgcf register"),s(" to generate "),n("code",null,"wgcf-account.toml"),s(".")],-1),g=n("li",null,[s("Run "),n("code",null,"wgcf generate"),s(" to generate "),n("code",null,"wgcf-profile.conf"),s(". Copy the following content:")],-1),y=l(`
                        [Interface]
                         PrivateKey = my private key
                         Address = 172.16.0.2/32
                         Address = 2606:4700:110:8949:fed8:2642:a640:c8e1/128
                        diff --git a/assets/websocket.html-5im3Rtj5.js b/assets/websocket.html-G4eliqnC.js
                        similarity index 98%
                        rename from assets/websocket.html-5im3Rtj5.js
                        rename to assets/websocket.html-G4eliqnC.js
                        index 9dd7bd1cb3..f926af5b61 100644
                        --- a/assets/websocket.html-5im3Rtj5.js
                        +++ b/assets/websocket.html-G4eliqnC.js
                        @@ -1,4 +1,4 @@
                        -import{_ as p,r as s,o as r,c as l,a as o,b as e,d as t,w as d,e as a}from"./app-PDrbPfzp.js";const i={},u=a(`

                        WebSocket

                        使用标准的 WebSocket 来传输数据。

                        WebSocket 连接可以被其它 HTTP 服务器(如 Nginx)分流,也可以被 VLESS fallbacks path 分流。

                        提示

                        Websocket 会识别 HTTP 请求的 X-Forwarded-For 头来覆写流量的源地址,优先级高于 PROXY protocol。

                        WebSocketObject

                        WebSocketObject 对应传输配置的 wsSettings 项。

                        {
                        +import{_ as p,r as s,o as r,c as l,a as o,b as e,d as t,w as d,e as a}from"./app-UOvWaKji.js";const i={},u=a(`

                        WebSocket

                        使用标准的 WebSocket 来传输数据。

                        WebSocket 连接可以被其它 HTTP 服务器(如 Nginx)分流,也可以被 VLESS fallbacks path 分流。

                        提示

                        Websocket 会识别 HTTP 请求的 X-Forwarded-For 头来覆写流量的源地址,优先级高于 PROXY protocol。

                        WebSocketObject

                        WebSocketObject 对应传输配置的 wsSettings 项。

                        {
                           "acceptProxyProtocol": false,
                           "path": "/",
                           "host": "xray.com",
                        diff --git a/assets/websocket.html-YSPsZ2_H.js b/assets/websocket.html-fT5fCDqV.js
                        similarity index 98%
                        rename from assets/websocket.html-YSPsZ2_H.js
                        rename to assets/websocket.html-fT5fCDqV.js
                        index ad2a7e911c..32f7265c61 100644
                        --- a/assets/websocket.html-YSPsZ2_H.js
                        +++ b/assets/websocket.html-fT5fCDqV.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as t,o as d,c as p,a as o,b as e,d as s,w as i,e as n}from"./app-PDrbPfzp.js";const l={},h=n(`

                        WebSocket

                        Uses standard WebSocket for data transmission.

                        WebSocket connections can be proxied by other web servers (like NGINX) or by VLESS fallback paths.

                        Tip

                        WebSocket inbounds will parse the X-Forwarded-For header received, overriding the source address with a higher priority than the source address got from PROXY protocol.

                        WebSocketObject

                        WebSocketObject corresponds to the wsSettings property of the transport configs.

                        {
                        +import{_ as c,r as t,o as d,c as p,a as o,b as e,d as s,w as i,e as n}from"./app-UOvWaKji.js";const l={},h=n(`

                        WebSocket

                        Uses standard WebSocket for data transmission.

                        WebSocket connections can be proxied by other web servers (like NGINX) or by VLESS fallback paths.

                        Tip

                        WebSocket inbounds will parse the X-Forwarded-For header received, overriding the source address with a higher priority than the source address got from PROXY protocol.

                        WebSocketObject

                        WebSocketObject corresponds to the wsSettings property of the transport configs.

                        {
                           "acceptProxyProtocol": false,
                           "path": "/",
                           "host": "xray.com",
                        diff --git a/assets/wireguard.html-OyUeeF20.js b/assets/wireguard.html-BCZ3AkFH.js
                        similarity index 99%
                        rename from assets/wireguard.html-OyUeeF20.js
                        rename to assets/wireguard.html-BCZ3AkFH.js
                        index f995a97e20..10ddfa7ad6 100644
                        --- a/assets/wireguard.html-OyUeeF20.js
                        +++ b/assets/wireguard.html-BCZ3AkFH.js
                        @@ -1,4 +1,4 @@
                        -import{_ as c,r as t,o as u,c as r,a as s,b as n,d as e,w as i,e as a}from"./app-PDrbPfzp.js";const l={},d=a(`

                        Wireguard

                        标准 Wireguard 协议实现。

                        警告

                        Wireguard 协议并非专门为翻墙而设计,若在最外层过墙,存在特征可能导致服务器被封锁

                        OutboundConfigurationObject

                        {
                        +import{_ as c,r as t,o as u,c as r,a as s,b as n,d as e,w as i,e as a}from"./app-UOvWaKji.js";const l={},d=a(`

                        Wireguard

                        标准 Wireguard 协议实现。

                        警告

                        Wireguard 协议并非专门为翻墙而设计,若在最外层过墙,存在特征可能导致服务器被封锁

                        OutboundConfigurationObject

                        {
                           "secretKey": "PRIVATE_KEY",
                           "address": [
                             // optional, default ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"]
                        diff --git a/assets/wireguard.html-yFYoQrs2.js b/assets/wireguard.html-K_sm3lda.js
                        similarity index 99%
                        rename from assets/wireguard.html-yFYoQrs2.js
                        rename to assets/wireguard.html-K_sm3lda.js
                        index 89c9ba579f..d7bd03c9da 100644
                        --- a/assets/wireguard.html-yFYoQrs2.js
                        +++ b/assets/wireguard.html-K_sm3lda.js
                        @@ -1,4 +1,4 @@
                        -import{_ as i,r as a,o as c,c as l,a as t,b as e,d as n,w as u,e as s}from"./app-PDrbPfzp.js";const p={},d=s(`

                        Wireguard

                        Wireguard is a standard implementation of the Wireguard protocol.

                        Danger

                        The Wireguard protocol is not specifically designed for circumvention purposes. If used as the outer layer for circumvention, its characteristics may lead to server blocking.

                        OutboundConfigurationObject

                        {
                        +import{_ as i,r as a,o as c,c as l,a as t,b as e,d as n,w as u,e as s}from"./app-UOvWaKji.js";const p={},d=s(`

                        Wireguard

                        Wireguard is a standard implementation of the Wireguard protocol.

                        Danger

                        The Wireguard protocol is not specifically designed for circumvention purposes. If used as the outer layer for circumvention, its characteristics may lead to server blocking.

                        OutboundConfigurationObject

                        {
                           "secretKey": "PRIVATE_KEY",
                           "address": [
                             // optional, default ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"]
                        diff --git a/assets/work.html-5iU00aiu.js b/assets/work.html-HxgjsHti.js
                        similarity index 96%
                        rename from assets/work.html-5iU00aiu.js
                        rename to assets/work.html-HxgjsHti.js
                        index 02ccca109b..cf0435a04d 100644
                        --- a/assets/work.html-5iU00aiu.js
                        +++ b/assets/work.html-HxgjsHti.js
                        @@ -1 +1 @@
                        -import{_ as o,r,o as t,c as d,d as a,a as n,b as l}from"./app-PDrbPfzp.js";const s={},A=n("h1",{id:"xray-的工作模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#xray-的工作模式"},[n("span",null,"Xray 的工作模式")])],-1),E=n("h2",{id:"单服务器模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#单服务器模式"},[n("span",null,"单服务器模式")])],-1),u=n("p",null,"与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。",-1),i=n("p",null,"一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。",-1),c=n("h2",{id:"桥接模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#桥接模式"},[n("span",null,"桥接模式")])],-1),h=n("p",null,"如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。",-1),_=n("h2",{id:"工作原理",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#工作原理"},[n("span",null,"工作原理")])],-1),B=n("p",null,"在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。",-1),D=n("ul",null,[n("li",null,[l("需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。 "),n("ul",null,[n("li",null,[l("入站连接负责与客户端(如浏览器)通信: "),n("ul",null,[n("li",null,"入站连接通常可以配置用户认证,如 ID 和密码等;"),n("li",null,"入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;")])]),n("li",null,"出站连接负责将数据发给服务器,如另一台主机上的 Xray。")])]),n("li",null,[l("当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。 "),n("ul",null,[n("li",null,"路由会在必要时查询 DNS 以获取更多信息来进行判断。")])])],-1);function p(m,b){const e=r("Mermaid");return t(),d("div",null,[A,E,u,a(e,{id:"mermaid-9",code:"graph%20LR;%0AA(PC)%20-.-%20B(%E9%98%B2%E7%81%AB%E5%A2%99);%0AB%20-.-%3E%20C(%E5%A2%99%E5%A4%96%E7%BD%91%E7%AB%99);%0AA%20--%3E%20D(Xray/VPS);%0AD%20--%3E%20C;%0AA%20--%3E%20E(%E5%A2%99%E5%86%85%E7%BD%91%E7%AB%99);%0A"}),i,c,h,a(e,{id:"mermaid-19",code:"graph%20LR;%0AA(PC)%20-.-%3E%20B(%E9%98%B2%E7%81%AB%E5%A2%99);%0AB%20-.-%3E%20C(%E5%A2%99%E5%A4%96%E7%BD%91%E7%AB%99);%0AA%20--%3E%20D(%E5%A2%99%E5%86%85%20VPS);%0AD%20--%3E%20E(%E5%A2%99%E5%A4%96%20VPS);%0AE%20--%3E%20C;%0AD%20--%3E%20F(%E5%A2%99%E5%86%85%E7%BD%91%E7%AB%99);%0A"}),_,B,a(e,{id:"mermaid-26",code:"graph%20LR;%0AA1(inbound)%20--%3E%20D(Dispatcher%20/%20Router%20/%20DNS);%0AA2(inbound)%20--%3E%20D;%0AA3(inbound)%20--%3E%20D;%0AA4(inbound)%20--%3E%20D;%0AD%20--%3E%20B1(outbound);%0AD%20--%3E%20B2(outbound);%0AD%20--%3E%20B3(outbound);%0AD%20--%3E%20B4(outbound);%0A"}),D])}const f=o(s,[["render",p],["__file","work.html.vue"]]);export{f as default};
                        +import{_ as o,r,o as t,c as d,d as a,a as n,b as l}from"./app-UOvWaKji.js";const s={},A=n("h1",{id:"xray-的工作模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#xray-的工作模式"},[n("span",null,"Xray 的工作模式")])],-1),E=n("h2",{id:"单服务器模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#单服务器模式"},[n("span",null,"单服务器模式")])],-1),u=n("p",null,"与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。",-1),i=n("p",null,"一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。",-1),c=n("h2",{id:"桥接模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#桥接模式"},[n("span",null,"桥接模式")])],-1),h=n("p",null,"如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。",-1),_=n("h2",{id:"工作原理",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#工作原理"},[n("span",null,"工作原理")])],-1),B=n("p",null,"在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。",-1),D=n("ul",null,[n("li",null,[l("需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。 "),n("ul",null,[n("li",null,[l("入站连接负责与客户端(如浏览器)通信: "),n("ul",null,[n("li",null,"入站连接通常可以配置用户认证,如 ID 和密码等;"),n("li",null,"入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;")])]),n("li",null,"出站连接负责将数据发给服务器,如另一台主机上的 Xray。")])]),n("li",null,[l("当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。 "),n("ul",null,[n("li",null,"路由会在必要时查询 DNS 以获取更多信息来进行判断。")])])],-1);function p(m,b){const e=r("Mermaid");return t(),d("div",null,[A,E,u,a(e,{id:"mermaid-9",code:"graph%20LR;%0AA(PC)%20-.-%20B(%E9%98%B2%E7%81%AB%E5%A2%99);%0AB%20-.-%3E%20C(%E5%A2%99%E5%A4%96%E7%BD%91%E7%AB%99);%0AA%20--%3E%20D(Xray/VPS);%0AD%20--%3E%20C;%0AA%20--%3E%20E(%E5%A2%99%E5%86%85%E7%BD%91%E7%AB%99);%0A"}),i,c,h,a(e,{id:"mermaid-19",code:"graph%20LR;%0AA(PC)%20-.-%3E%20B(%E9%98%B2%E7%81%AB%E5%A2%99);%0AB%20-.-%3E%20C(%E5%A2%99%E5%A4%96%E7%BD%91%E7%AB%99);%0AA%20--%3E%20D(%E5%A2%99%E5%86%85%20VPS);%0AD%20--%3E%20E(%E5%A2%99%E5%A4%96%20VPS);%0AE%20--%3E%20C;%0AD%20--%3E%20F(%E5%A2%99%E5%86%85%E7%BD%91%E7%AB%99);%0A"}),_,B,a(e,{id:"mermaid-26",code:"graph%20LR;%0AA1(inbound)%20--%3E%20D(Dispatcher%20/%20Router%20/%20DNS);%0AA2(inbound)%20--%3E%20D;%0AA3(inbound)%20--%3E%20D;%0AA4(inbound)%20--%3E%20D;%0AD%20--%3E%20B1(outbound);%0AD%20--%3E%20B2(outbound);%0AD%20--%3E%20B3(outbound);%0AD%20--%3E%20B4(outbound);%0A"}),D])}const f=o(s,[["render",p],["__file","work.html.vue"]]);export{f as default};
                        diff --git a/assets/work.html-rHkxptVO.js b/assets/work.html-fccvP5Wo.js
                        similarity index 96%
                        rename from assets/work.html-rHkxptVO.js
                        rename to assets/work.html-fccvP5Wo.js
                        index 02ccca109b..cf0435a04d 100644
                        --- a/assets/work.html-rHkxptVO.js
                        +++ b/assets/work.html-fccvP5Wo.js
                        @@ -1 +1 @@
                        -import{_ as o,r,o as t,c as d,d as a,a as n,b as l}from"./app-PDrbPfzp.js";const s={},A=n("h1",{id:"xray-的工作模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#xray-的工作模式"},[n("span",null,"Xray 的工作模式")])],-1),E=n("h2",{id:"单服务器模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#单服务器模式"},[n("span",null,"单服务器模式")])],-1),u=n("p",null,"与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。",-1),i=n("p",null,"一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。",-1),c=n("h2",{id:"桥接模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#桥接模式"},[n("span",null,"桥接模式")])],-1),h=n("p",null,"如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。",-1),_=n("h2",{id:"工作原理",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#工作原理"},[n("span",null,"工作原理")])],-1),B=n("p",null,"在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。",-1),D=n("ul",null,[n("li",null,[l("需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。 "),n("ul",null,[n("li",null,[l("入站连接负责与客户端(如浏览器)通信: "),n("ul",null,[n("li",null,"入站连接通常可以配置用户认证,如 ID 和密码等;"),n("li",null,"入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;")])]),n("li",null,"出站连接负责将数据发给服务器,如另一台主机上的 Xray。")])]),n("li",null,[l("当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。 "),n("ul",null,[n("li",null,"路由会在必要时查询 DNS 以获取更多信息来进行判断。")])])],-1);function p(m,b){const e=r("Mermaid");return t(),d("div",null,[A,E,u,a(e,{id:"mermaid-9",code:"graph%20LR;%0AA(PC)%20-.-%20B(%E9%98%B2%E7%81%AB%E5%A2%99);%0AB%20-.-%3E%20C(%E5%A2%99%E5%A4%96%E7%BD%91%E7%AB%99);%0AA%20--%3E%20D(Xray/VPS);%0AD%20--%3E%20C;%0AA%20--%3E%20E(%E5%A2%99%E5%86%85%E7%BD%91%E7%AB%99);%0A"}),i,c,h,a(e,{id:"mermaid-19",code:"graph%20LR;%0AA(PC)%20-.-%3E%20B(%E9%98%B2%E7%81%AB%E5%A2%99);%0AB%20-.-%3E%20C(%E5%A2%99%E5%A4%96%E7%BD%91%E7%AB%99);%0AA%20--%3E%20D(%E5%A2%99%E5%86%85%20VPS);%0AD%20--%3E%20E(%E5%A2%99%E5%A4%96%20VPS);%0AE%20--%3E%20C;%0AD%20--%3E%20F(%E5%A2%99%E5%86%85%E7%BD%91%E7%AB%99);%0A"}),_,B,a(e,{id:"mermaid-26",code:"graph%20LR;%0AA1(inbound)%20--%3E%20D(Dispatcher%20/%20Router%20/%20DNS);%0AA2(inbound)%20--%3E%20D;%0AA3(inbound)%20--%3E%20D;%0AA4(inbound)%20--%3E%20D;%0AD%20--%3E%20B1(outbound);%0AD%20--%3E%20B2(outbound);%0AD%20--%3E%20B3(outbound);%0AD%20--%3E%20B4(outbound);%0A"}),D])}const f=o(s,[["render",p],["__file","work.html.vue"]]);export{f as default};
                        +import{_ as o,r,o as t,c as d,d as a,a as n,b as l}from"./app-UOvWaKji.js";const s={},A=n("h1",{id:"xray-的工作模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#xray-的工作模式"},[n("span",null,"Xray 的工作模式")])],-1),E=n("h2",{id:"单服务器模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#单服务器模式"},[n("span",null,"单服务器模式")])],-1),u=n("p",null,"与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。",-1),i=n("p",null,"一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。",-1),c=n("h2",{id:"桥接模式",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#桥接模式"},[n("span",null,"桥接模式")])],-1),h=n("p",null,"如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。",-1),_=n("h2",{id:"工作原理",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#工作原理"},[n("span",null,"工作原理")])],-1),B=n("p",null,"在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。",-1),D=n("ul",null,[n("li",null,[l("需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。 "),n("ul",null,[n("li",null,[l("入站连接负责与客户端(如浏览器)通信: "),n("ul",null,[n("li",null,"入站连接通常可以配置用户认证,如 ID 和密码等;"),n("li",null,"入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;")])]),n("li",null,"出站连接负责将数据发给服务器,如另一台主机上的 Xray。")])]),n("li",null,[l("当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。 "),n("ul",null,[n("li",null,"路由会在必要时查询 DNS 以获取更多信息来进行判断。")])])],-1);function p(m,b){const e=r("Mermaid");return t(),d("div",null,[A,E,u,a(e,{id:"mermaid-9",code:"graph%20LR;%0AA(PC)%20-.-%20B(%E9%98%B2%E7%81%AB%E5%A2%99);%0AB%20-.-%3E%20C(%E5%A2%99%E5%A4%96%E7%BD%91%E7%AB%99);%0AA%20--%3E%20D(Xray/VPS);%0AD%20--%3E%20C;%0AA%20--%3E%20E(%E5%A2%99%E5%86%85%E7%BD%91%E7%AB%99);%0A"}),i,c,h,a(e,{id:"mermaid-19",code:"graph%20LR;%0AA(PC)%20-.-%3E%20B(%E9%98%B2%E7%81%AB%E5%A2%99);%0AB%20-.-%3E%20C(%E5%A2%99%E5%A4%96%E7%BD%91%E7%AB%99);%0AA%20--%3E%20D(%E5%A2%99%E5%86%85%20VPS);%0AD%20--%3E%20E(%E5%A2%99%E5%A4%96%20VPS);%0AE%20--%3E%20C;%0AD%20--%3E%20F(%E5%A2%99%E5%86%85%E7%BD%91%E7%AB%99);%0A"}),_,B,a(e,{id:"mermaid-26",code:"graph%20LR;%0AA1(inbound)%20--%3E%20D(Dispatcher%20/%20Router%20/%20DNS);%0AA2(inbound)%20--%3E%20D;%0AA3(inbound)%20--%3E%20D;%0AA4(inbound)%20--%3E%20D;%0AD%20--%3E%20B1(outbound);%0AD%20--%3E%20B2(outbound);%0AD%20--%3E%20B3(outbound);%0AD%20--%3E%20B4(outbound);%0A"}),D])}const f=o(s,[["render",p],["__file","work.html.vue"]]);export{f as default};
                        diff --git a/assets/xtls.html-vMAM7WFy.js b/assets/xtls.html-5PMkSJTh.js
                        similarity index 78%
                        rename from assets/xtls.html-vMAM7WFy.js
                        rename to assets/xtls.html-5PMkSJTh.js
                        index fb5253d9ee..62a44e4b1c 100644
                        --- a/assets/xtls.html-vMAM7WFy.js
                        +++ b/assets/xtls.html-5PMkSJTh.js
                        @@ -1 +1 @@
                        -import{_ as o,r as s,o as t,c as n,d as l,a as e}from"./app-PDrbPfzp.js";const r={},c=e("h1",{id:"deep-analysis-of-xtls",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#deep-analysis-of-xtls"},[e("span",null,"Deep analysis of XTLS")])],-1),i=e("blockquote",null,[e("p",null,[e("strong",null,`"XTLS is the original black technology of Xray, and also the core driving force that makes Xray's performance far superior."`)])],-1);function d(_,f){const a=s("Badge");return t(),n("div",null,[c,i,l(a,{text:"WIP",type:"warning"})])}const h=o(r,[["render",d],["__file","xtls.html.vue"]]);export{h as default};
                        +import{_ as o,r as s,o as t,c as n,d as l,a as e}from"./app-UOvWaKji.js";const r={},c=e("h1",{id:"deep-analysis-of-xtls",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#deep-analysis-of-xtls"},[e("span",null,"Deep analysis of XTLS")])],-1),i=e("blockquote",null,[e("p",null,[e("strong",null,`"XTLS is the original black technology of Xray, and also the core driving force that makes Xray's performance far superior."`)])],-1);function d(_,f){const a=s("Badge");return t(),n("div",null,[c,i,l(a,{text:"WIP",type:"warning"})])}const h=o(r,[["render",d],["__file","xtls.html.vue"]]);export{h as default};
                        diff --git a/assets/xtls.html--f-cdwuj.js b/assets/xtls.html-6RQbZOas.js
                        similarity index 76%
                        rename from assets/xtls.html--f-cdwuj.js
                        rename to assets/xtls.html-6RQbZOas.js
                        index 45a1ddef66..7d3ca6c279 100644
                        --- a/assets/xtls.html--f-cdwuj.js
                        +++ b/assets/xtls.html-6RQbZOas.js
                        @@ -1 +1 @@
                        -import{_ as n,r as o,o as s,c as a,d as l,a as e}from"./app-PDrbPfzp.js";const c={},r=e("h1",{id:"xtls-深度剖析",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#xtls-深度剖析"},[e("span",null,"XTLS 深度剖析")])],-1),_=e("blockquote",null,[e("p",null,[e("strong",null,"XTLS 是 Xray 的原创黑科技, 也是使 Xray 性能一骑绝尘的核心动力")])],-1);function d(i,u){const t=o("Badge");return s(),a("div",null,[r,_,l(t,{text:"WIP",type:"warning"})])}const p=n(c,[["render",d],["__file","xtls.html.vue"]]);export{p as default};
                        +import{_ as n,r as o,o as s,c as a,d as l,a as e}from"./app-UOvWaKji.js";const c={},r=e("h1",{id:"xtls-深度剖析",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#xtls-深度剖析"},[e("span",null,"XTLS 深度剖析")])],-1),_=e("blockquote",null,[e("p",null,[e("strong",null,"XTLS 是 Xray 的原创黑科技, 也是使 Xray 性能一骑绝尘的核心动力")])],-1);function d(i,u){const t=o("Badge");return s(),a("div",null,[r,_,l(t,{text:"WIP",type:"warning"})])}const p=n(c,[["render",d],["__file","xtls.html.vue"]]);export{p as default};
                        diff --git a/assets/xychartDiagram-ab372869-NbNQWlrD.js b/assets/xychartDiagram-ab372869-zbSuzsOs.js
                        similarity index 99%
                        rename from assets/xychartDiagram-ab372869-NbNQWlrD.js
                        rename to assets/xychartDiagram-ab372869-zbSuzsOs.js
                        index dd29a9283d..502799ced5 100644
                        --- a/assets/xychartDiagram-ab372869-NbNQWlrD.js
                        +++ b/assets/xychartDiagram-ab372869-zbSuzsOs.js
                        @@ -1,4 +1,4 @@
                        -import{a$ as zt,b0 as ot,aN as wt,aM as Ft,s as Nt,g as Xt,x as Yt,y as St,a as Ht,b as $t,A as Ut,l as Ct,aK as qt,i as jt,d as Gt}from"./mermaid.core-95b3ca__.js";import{a as Qt}from"./createText-6b48ae7d-9AoX5zU9.js";import{i as Kt}from"./init-Hi12RPRh.js";import{o as Zt}from"./ordinal-wXG5obU4.js";import{l as ft}from"./linear-yB98X29G.js";import{l as pt}from"./line-_nnM_7ZX.js";import"./app-PDrbPfzp.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";function Jt(e,t,i){e=+e,t=+t,i=(n=arguments.length)<2?(t=e,e=0,1):n<3?1:+i;for(var s=-1,n=Math.max(0,Math.ceil((t-e)/i))|0,o=new Array(n);++s"u"&&(k.yylloc={});var tt=k.yylloc;a.push(tt);var Wt=k.options&&k.options.ranges;typeof B.yy.parseError=="function"?this.parseError=B.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ot(){var I;return I=g.pop()||k.lex()||xt,typeof I!="number"&&(I instanceof Array&&(g=I,I=g.pop()),I=l.symbols_[I]||I),I}for(var D,W,v,it,O={},q,M,dt,j;;){if(W=u[u.length-1],this.defaultActions[W]?v=this.defaultActions[W]:((D===null||typeof D>"u")&&(D=Ot()),v=F[W]&&F[W][D]),typeof v>"u"||!v.length||!v[0]){var et="";j=[];for(q in F[W])this.terminals_[q]&&q>Vt&&j.push("'"+this.terminals_[q]+"'");k.showPosition?et="Parse error on line "+(U+1)+`:
                        +import{a$ as zt,b0 as ot,aN as wt,aM as Ft,s as Nt,g as Xt,x as Yt,y as St,a as Ht,b as $t,A as Ut,l as Ct,aK as qt,i as jt,d as Gt}from"./mermaid.core-Q3WVcjPF.js";import{a as Qt}from"./createText-6b48ae7d-yUX1YD6G.js";import{i as Kt}from"./init-Hi12RPRh.js";import{o as Zt}from"./ordinal-wXG5obU4.js";import{l as ft}from"./linear-eA8J8eJ4.js";import{l as pt}from"./line-3Gyevr9q.js";import"./app-UOvWaKji.js";import"./array-Nw74a44z.js";import"./path-aUcfwwLI.js";function Jt(e,t,i){e=+e,t=+t,i=(n=arguments.length)<2?(t=e,e=0,1):n<3?1:+i;for(var s=-1,n=Math.max(0,Math.ceil((t-e)/i))|0,o=new Array(n);++s"u"&&(k.yylloc={});var tt=k.yylloc;a.push(tt);var Wt=k.options&&k.options.ranges;typeof B.yy.parseError=="function"?this.parseError=B.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Ot(){var I;return I=g.pop()||k.lex()||xt,typeof I!="number"&&(I instanceof Array&&(g=I,I=g.pop()),I=l.symbols_[I]||I),I}for(var D,W,v,it,O={},q,M,dt,j;;){if(W=u[u.length-1],this.defaultActions[W]?v=this.defaultActions[W]:((D===null||typeof D>"u")&&(D=Ot()),v=F[W]&&F[W][D]),typeof v>"u"||!v.length||!v[0]){var et="";j=[];for(q in F[W])this.terminals_[q]&&q>Vt&&j.push("'"+this.terminals_[q]+"'");k.showPosition?et="Parse error on line "+(U+1)+`:
                         `+k.showPosition()+`
                         Expecting `+j.join(", ")+", got '"+(this.terminals_[D]||D)+"'":et="Parse error on line "+(U+1)+": Unexpected "+(D==xt?"end of input":"'"+(this.terminals_[D]||D)+"'"),this.parseError(et,{text:k.match,token:this.terminals_[D]||D,line:k.yylineno,loc:tt,expected:j})}if(v[0]instanceof Array&&v.length>1)throw new Error("Parse Error: multiple actions possible at state: "+W+", token: "+D);switch(v[0]){case 1:u.push(D),b.push(k.yytext),a.push(k.yylloc),u.push(v[1]),D=null,gt=k.yyleng,x=k.yytext,U=k.yylineno,tt=k.yylloc;break;case 2:if(M=this.productions_[v[1]][1],O.$=b[b.length-M],O._$={first_line:a[a.length-(M||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(M||1)].first_column,last_column:a[a.length-1].last_column},Wt&&(O._$.range=[a[a.length-(M||1)].range[0],a[a.length-1].range[1]]),it=this.performAction.apply(O,[x,gt,U,B.yy,v[1],b,a].concat(Bt)),typeof it<"u")return it;M&&(u=u.slice(0,-1*M*2),b=b.slice(0,-1*M),a=a.slice(0,-1*M)),u.push(this.productions_[v[1]][0]),b.push(O.$),a.push(O._$),dt=F[u[u.length-2]][u[u.length-1]],u.push(dt);break;case 3:return!0}}return!0}},It=function(){var V={EOF:1,parseError:function(l,u){if(this.yy.parser)this.yy.parser.parseError(l,u);else throw new Error(l)},setInput:function(r,l){return this.yy=l||this.yy||{},this._input=r,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var r=this._input[0];this.yytext+=r,this.yyleng++,this.offset++,this.match+=r,this.matched+=r;var l=r.match(/(?:\r\n?|\n).*/g);return l?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),r},unput:function(r){var l=r.length,u=r.split(/(?:\r\n?|\n)/g);this._input=r+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-l),this.offset-=l;var g=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),u.length-1&&(this.yylineno-=u.length-1);var b=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:u?(u.length===g.length?this.yylloc.first_column:0)+g[g.length-u.length].length-u[0].length:this.yylloc.first_column-l},this.options.ranges&&(this.yylloc.range=[b[0],b[0]+this.yyleng-l]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).
                         `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},less:function(r){this.unput(this.match.slice(r))},pastInput:function(){var r=this.matched.substr(0,this.matched.length-this.match.length);return(r.length>20?"...":"")+r.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var r=this.match;return r.length<20&&(r+=this._input.substr(0,20-r.length)),(r.substr(0,20)+(r.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var r=this.pastInput(),l=new Array(r.length+1).join("-");return r+this.upcomingInput()+`
                        diff --git a/config/api.html b/config/api.html
                        index 2cb3d2b461..c0147318a2 100644
                        --- a/config/api.html
                        +++ b/config/api.html
                        @@ -24,8 +24,8 @@
                             
                             API 接口 | Project X
                             
                        -    
                        -    
                        +    
                        +    
                           
                           
                             

                        API 接口

                        API 接口配置提供了一些基于 gRPCopen in new tag的 API 接口供远程调用。

                        可以通过 api 配置模块开启接口. 当 api 配置开启时,Xray 会自建一个出站代理,须手动将所有的 API 入站连接通过 路由规则配置 指向这一出站代理。

                        请参考本节中的 相关配置

                        注意

                        大多数用户并不会用到此 API,新手可以直接忽略这一项。

                        ApiObject

                        ApiObject 对应配置文件的 api 项。

                        {
                        @@ -69,6 +69,6 @@
                         xray.app.proxyman.command.HandlerService
                         xray.app.stats.command.StatsService
                         

                        API 调用示例

                        Xray-API-documentsopen in new tag @crossfw

                        - + diff --git a/config/dns.html b/config/dns.html index 97e390e42c..b74360c1f3 100644 --- a/config/dns.html +++ b/config/dns.html @@ -24,8 +24,8 @@ 内置 DNS 服务器 | Project X - - + +

                        内置 DNS 服务器

                        DNS 服务器

                        Xray 内置的 DNS 模块,主要有两大用途:

                        • 在路由阶段, 解析域名为 IP, 并且根据域名解析得到的 IP 进行规则匹配以分流. 是否解析域名及分流和路由配置模块中 domainStrategy 的值有关, 只有在设置以下两种值时,才会使用内置 DNS 服务器进行 DNS 查询:

                          • "IPIfNonMatch", 请求一个域名时,进行路由里面的 domain 进行匹配,若无法匹配到结果,则对这个域名使用内置 DNS 服务器进行 DNS 查询,并且使用查询返回的 IP 地址再重新进行 IP 路由匹配。
                          • "IPOnDemand", 当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配。
                        • 解析目标地址进行连接。

                          • 如 在 freedom 出站中,将 domainStrategy 设置为 UseIP, 由此出站发出的请求, 会先将域名通过内置服务器解析成 IP, 然后进行连接。
                          • 如 在 sockopt 中,将 domainStrategy 设置为 UseIP, 此出站发起的系统连接,将先由内置服务器解析为 IP, 然后进行连接。

                        TIP 1

                        内置 DNS 服务器所发出的 DNS 查询请求,会自动根据路由配置进行转发。

                        TIP 2

                        只支持最基本的 IP 查询(A 和 AAAA 记录),CNAME 记录将会重复查询直至返回 A/AAAA 记录为止。其他查询不会进入内置 DNS 服务器。

                        DNS 处理流程

                        若当前要查询的域名:

                        • 命中了 hosts 中的「域名 - IP」、「域名 - IP 数组」映射,则将该 IP 或 IP 数组作为 DNS 解析结果返回。
                        • 命中了 hosts 中的「域名 - 域名」映射,则该映射的值(另一个域名)将作为当前要查询的域名,进入 DNS 处理流程,直到解析出 IP 后返回,或返回空解析。
                        • 没有命中 hosts,但命中了某(几)个 DNS 服务器中的 domains 域名列表,则按照命中的规则的优先级,依次使用该规则对应的 DNS 服务器进行查询。若命中的 DNS 服务器查询失败或 expectIPs 不匹配,则使用下一个命中的 DNS 服务器进行查询;否则返回解析得到的 IP。若所有命中的 DNS 服务器均查询失败或 expectIPs 不匹配,此时 DNS 组件:
                          • 默认会进行 「DNS 回退(fallback)查询」:使用「上一轮失败查询中未被使用的、且 skipFallback 为默认值 false 的 DNS 服务器」依次查询。若查询失败或 expectIPs 不匹配,返回空解析;否则返回解析得到的 IP。
                          • disableFallback 设置为 true,则不会进行「DNS 回退(fallback)查询」。
                        • 既没有命中 hosts,又没有命中 DNS 服务器中的 domains 域名列表,则:
                          • 默认使用「skipFallback 为默认值 false 的 DNS 服务器」依次查询。若第一个被选中的 DNS 服务器查询失败或 expectIPs 不匹配,则使用下一个被选中的 DNS 服务器进行查询;否则返回解析得到的 IP。若所有被选中的 DNS 服务器均查询失败或 expectIPs 不匹配,返回空解析。
                          • 若「skipFallback 为默认值 false 的 DNS 服务器」数量为 0 或 disableFallback 设置为 true,则使用 DNS 配置中的第一个 DNS 服务器进行查询。查询失败或 expectIPs 不匹配,返回空解析;否则返回解析得到的 IP。

                        DnsObject

                        DnsObject 对应配置文件的 dns 项。

                        {
                        @@ -116,6 +116,6 @@
                           "clientIP": "1.2.3.4"
                         }
                         

                        address: address

                        一个 DNS 服务器列表,支持的类型有两种:DNS 地址(字符串形式)和 ServerObject 。

                        当值为 "localhost" 时,表示使用本机预设的 DNS 配置。

                        当它的值是一个 DNS "IP" 地址时,如 "8.8.8.8",Xray 会使用此地址的指定 UDP 端口进行 DNS 查询。该查询遵循路由规则。默认使用 53 端口。

                        当值是 "tcp://host" 的形式,如 "tcp://8.8.8.8",Xray 会使用 DNS over TCP 进行查询。该查询遵循路由规则。默认使用 53 端口。

                        当值是 "tcp+local://host" 的形式,如 "tcp+local://8.8.8.8",Xray 会使用 TCP 本地模式 (TCPL) 进行查询。即 DNS 请求不会经过路由组件,直接通过 Freedom outbound 对外请求,以降低耗时。不指定端口时,默认使用 53 端口。

                        当值是 "https://host:port/dns-query" 的形式,如 "https://dns.google/dns-query",Xray 会使用 DNS over HTTPS (RFC8484, 简称 DOH) 进行查询。有些服务商拥有 IP 别名的证书,可以直接写 IP 形式,比如 https://1.1.1.1/dns-query。也可使用非标准端口和路径,如 "https://a.b.c.d:8443/my-dns-query"

                        当值是 "https+local://host:port/dns-query" 的形式,如 "https+local://dns.google/dns-query",Xray 会使用 DOH 本地模式 (DOHL) 进行查询,即 DOH 请求不会经过路由组件,直接通过 Freedom outbound 对外请求,以降低耗时。一般适合在服务端使用。也可使用非标端口和路径。

                        当值是 "quic+local://host:port" 的形式,如 "quic+local://dns.adguard.com",Xray 会使用 DOQ 本地模式 (DOQL) 进行查询,即 DNS 请求不会经过路由组件,直接通过 Freedom outbound 对外请求。该方式需要 DNS 服务器支持 DNS over QUIC。默认使用 784 端口进行查询,可以使用非标端口。

                        当值是 fakedns 时,将使用 FakeDNS 功能进行查询。

                        port: number

                        DNS 服务器端口,如 53。此项缺省时默认为 53。当使用 DOH、DOHL、DOQL 模式时该项无效,非标端口应在 URL 中指定。

                        domains: [string]

                        一个域名列表,此列表包含的域名,将优先使用此服务器进行查询。域名格式和 路由配置 中相同。

                        expectIPs:[string]

                        一个 IP 范围列表,格式和 路由配置 中相同。

                        当配置此项时,Xray DNS 会对返回的 IP 的进行校验,只返回包含 expectIPs 列表中的地址。

                        如果未配置此项,会原样返回 IP 地址。

                        skipFallback: true | false

                        true,在进行 DNS fallback 查询时将跳过此服务器, 默认为 false,即不跳过。

                        - + diff --git a/config/fakedns.html b/config/fakedns.html index 0ff252ab36..2f9668ae1f 100644 --- a/config/fakedns.html +++ b/config/fakedns.html @@ -24,8 +24,8 @@ FakeDNS | Project X - - + + - + diff --git a/config/features/browser_dialer.html b/config/features/browser_dialer.html index b1987fa262..61c2776e83 100644 --- a/config/features/browser_dialer.html +++ b/config/features/browser_dialer.html @@ -24,11 +24,11 @@ Browser Dialer | Project X - - + +

                        Browser Dialer

                        BETA v1.4.1+

                        Background

                        基于 一年前的想法open in new tag ,利用原生 JS 实现了简洁的 WSS Browser Dialer,达到了真实浏览器的 TLS 指纹、行为特征。

                        不过 WSS 仍存在 ALPN 明显的问题,所以下一步是浏览器转发 HTTP/2,QUIC

                        Xray & JS

                        创造了一个非常简单、巧妙的通信机制:

                        • Xray 监听地址端口 A,作为 HTTP 服务,浏览器访问 A,加载网页中的 JS。
                        • JS 主动向 A 建立 WebSocket 连接,成功后,Xray 将连接发给 channel。
                        • 需要建立连接时,Xray 从 channel 接收一个可用的连接,并发送目标 URL 和可选的 early data。
                        • JS 成功连接到目标后告知 Xray,并继续用这个 conn 全双工双向转发数据,连接关闭行为同步。
                        • 连接使用后就会被关闭,但 JS 会确保始终有新空闲连接可用。

                        Early data

                        根据浏览器的需求,对 early data 机制进行了如下调整:

                        • 服务端响应头会带有请求的 Sec-WebSocket-Protocol,这也初步混淆了 WSS 握手响应的长度特征。
                        • 用于浏览器的 early data 编码是 base64.RawURLEncoding 而不是 StdEncoding,服务端做了兼容。
                        • 此外,由于 Xray-core#375open in new tag 推荐 ?ed=2048,这个 PR 顺便将服务端一处 MaxHeaderBytes 扩至了 4096。 (虽然好像不改也没问题)

                        Configuration v1.4.1

                        这是一个探索的过程,目前两边都是 Xray-core v1.4.1 时的配置方式:

                        • 准备一份可用的 WSS 配置,注意 address 必须填域名,若需要指定 IP,请配置 DNS 或系统 hosts。
                        • 若浏览器的流量也会经过 Xray-core,务必将这个域名设为直连,否则会造成流量回环。
                        • 设置环境变量指定要监听的地址端口,比如 XRAY_BROWSER_DIALER = 127.0.0.1:8080
                        • 先运行 Xray-core,再用任意浏览器访问上面指定的地址端口,还可以 F12ConsoleNetwork
                        • 浏览器会限制 WebSocket 连接数,所以建议开启 Mux.Cool
                        - + diff --git a/config/features/env.html b/config/features/env.html index be323c1aeb..aa17111507 100644 --- a/config/features/env.html +++ b/config/features/env.html @@ -24,14 +24,14 @@ 环境变量 | Project X - - + +

                        环境变量

                        Xray 提供以下环境变量以供修改 Xray 的一些底层配置。

                        资源文件路径

                        • 名称:xray.location.assetXRAY_LOCATION_ASSET
                        • 默认值:特定 FHSopen in new tag 目录或 Xray 文件同路径。

                        这个环境变量指定了一个文件夹位置,这个文件夹应当包含 geoip.dat 和 geosite.dat 文件。 若无指定变量值,程序将会按以下顺序寻找资源文件:

                        ./
                         /usr/local/share/xray
                         /usr/share/xray
                         

                        配置文件位置

                        • 名称:xray.location.configXRAY_LOCATION_CONFIG
                        • 默认值:和 Xray 文件同路径。

                        这个环境变量指定了一个文件夹位置,这个文件夹应当包含 config.json 文件。

                        多配置目录

                        • 名称:xray.location.confdirXRAY_LOCATION_CONFDIR
                        • 默认值:""

                        这个目录内的 .json 文件会按文件名顺序读取,作为多配置选项。

                        - + diff --git a/config/features/fallback.html b/config/features/fallback.html index cc902b9e95..f42f7fc1e8 100644 --- a/config/features/fallback.html +++ b/config/features/fallback.html @@ -24,8 +24,8 @@ Fallback 回落 | Project X - - + +

                        Fallback 回落

                        Fallback 是 Xray 的最强大功能之一, 可有效防止主动探测, 自由配置常用端口多服务共享

                        fallback 为 Xray 提供了高强度的防主动探测性, 并且具有独创的首包回落机制.

                        fallback 也可以将不同类型的流量根据 path 进行分流, 从而实现一个端口, 多种服务共享.

                        目前您可以在使用 VLESS 或者 trojan 协议时, 通过配置 fallbacks 来使用回落这一特性, 并且创造出非常丰富的组合玩法.

                        fallbacks 配置

                          "fallbacks": [
                        @@ -41,6 +41,6 @@
                           "xver": 0
                         }
                         

                        fallbacks 是一个数组,这里是其中一个子元素的配置说明。

                        fallbacks 项是可选的,只能用于 TCP+TLS 传输组合

                        • 该项有子元素时,Inbound TLS 需设置 "alpn":["http/1.1"]。**

                        通常,你需要先设置一组 alpnpath 均省略或为空的默认回落,然后再按需配置其它分流。

                        VLESS 会把 TLS 解密后首包长度 < 18 或协议版本无效、身份认证失败的流量转发到 dest 指定的地址。

                        其它传输组合必须删掉 fallbacks 项或所有子元素,此时也不会开启 Fallback,VLESS 会等待读够所需长度,协议版本无效或身份认证失败时,将直接断开连接。

                        name: string

                        尝试匹配 TLS SNI(Server Name Indication),空为任意,默认为 ""

                        alpn: string

                        尝试匹配 TLS ALPN 协商结果,空为任意,默认为 ""

                        有需要时,VLESS 才会尝试读取 TLS ALPN 协商结果,若成功,输出 info realAlpn = 到日志。 用途:解决了 Nginx 的 h2c 服务不能同时兼容 http/1.1 的问题,Nginx 需要写两行 listen,分别用于 1.1 和 h2c。 注意:fallbacks alpn 存在 "h2" 时,Inbound TLS 需设置 "alpn":["h2","http/1.1"],以支持 h2 访问。

                        提示

                        Fallback 内设置的 alpn 是匹配实际协商出的 ALPN,而 Inbound TLS 设置的 alpn 是握手时可选的 ALPN 列表,两者含义不同。

                        path: string

                        尝试匹配首包 HTTP PATH,空为任意,默认为空,非空则必须以 / 开头,不支持 h2c。

                        智能:有需要时,VLESS 才会尝试看一眼 PATH(不超过 55 个字节;最快算法,并不完整解析 HTTP),若成功,输出 INFO 日志 realPath =。 用途:分流其它 inbound 的 WebSocket 流量或 HTTP 伪装流量,没有多余处理、纯粹转发流量,理论性能比 Nginx 更强。

                        注意:fallbacks 所在入站本身必须是 TCP+TLS,这是分流至其它 WS 入站用的,被分流的入站则无需配置 TLS。

                        dest: string | number

                        决定 TLS 解密后 TCP 流量的去向,目前支持两类地址:(该项必填,否则无法启动)

                        1. TCP,格式为 "addr:port",其中 addr 支持 IPv4、域名、IPv6,若填写域名,也将直接发起 TCP 连接(而不走内置的 DNS)。
                        2. Unix domain socket,格式为绝对路径,形如 "/dev/shm/domain.socket",可在开头加 @ 代表 abstractopen in new tag@@ 则代表带 padding 的 abstract。

                        若只填 port,数字或字符串均可,形如 80"80",通常指向一个明文 http 服务(addr 会被补为 "127.0.0.1")。

                        xver: number

                        发送 PROXY protocolopen in new tag,专用于传递请求的真实来源 IP 和端口,填版本 1 或 2,默认为 0,即不发送。若有需要建议填 1。

                        目前填 1 或 2,功能完全相同,只是结构不同,且前者可打印,后者为二进制。Xray 的 TCP 和 WS 入站均已支持接收 PROXY protocol。

                        注意

                        若你正在 配置 Nginx 接收 PROXY protocolopen in new tag,除了设置 proxy_protocol 外,还需设置 set_real_ip_from,否则可能会出问题。

                        补充说明

                        • 将匹配到最精确的子元素,与子元素的排列顺序无关。若配置了几个 alpn 和 path 均相同的子元素,则会以最后的为准。
                        • 回落分流均是解密后 TCP 层的转发,而不是 HTTP 层,只在必要时检查首包 PATH。
                        • 您可以查看更多的关于 Fallbacks 的使用技巧和心得

                        Fallbacks 设计理论 WIP

                        - + diff --git a/config/features/multiple.html b/config/features/multiple.html index 900da6717e..b8e442cb7b 100644 --- a/config/features/multiple.html +++ b/config/features/multiple.html @@ -24,97 +24,85 @@ 多文件配置 | Project X - - + + -

                        多文件配置

                        Xray 程序支持使用多个配置文件。

                        多配置文件的主要作用在于分散不同作用模块配置,便于管理和维护。

                        该功能主要考虑是为了丰富 Xray 的生态链,比如对于 GUI 的客户端,一般只实现节点选择等固定的功能,对于太复杂的配置难以图形化实现;只需留一个 confdir 的自定义配置目录供配置复杂的功能;对于服务器的部署脚本,只需往 confdir 添加文件即可实现配置多种协议。

                        多文件启动

                        提示

                        启动信息中会提示依次读入的每个配置文件,留意启动信息是否符合你预设的顺序。

                        $ xray run -confdir /etc/xray/confs
                        -

                        也可使用 Xray.location.confdirXray_LOCATION_CONFDIR 指定 confdir

                        参数 -confdir 的作用优先于环境变量,如果参数指定了有效的目录则不再读取环境变量中的路径。

                        规则说明

                        普通对象({}

                        在 json 的顶级对象当中,后者覆盖或补充前者。

                        比如:

                        • base.json
                        {
                        -  "log": {},
                        -  "api": {},
                        -  "dns": {},
                        -  "stats": {},
                        -  "policy": {},
                        -  "transport": {},
                        -  "routing": {},
                        -  "inbounds": []
                        -}
                        -
                        • outbounds.json
                        {
                        -  "outbounds": []
                        -}
                        -

                        以多配置启动 Xray:

                        # 路径 /etc/xray/confs 为多文件存放目录
                        -$ xray run -confdir /etc/xray/confs
                        -

                        base.jsonoutbounds.json 这两个配置文件的效果之和等效于单文件配置的效果, 如下方所示:

                        {
                        -  "log": {},
                        -  "api": {},
                        -  "dns": {},
                        -  "stats": {},
                        -  "policy": {},
                        -  "transport": {},
                        -  "routing": {},
                        -  "inbounds": [],
                        -  "outbounds": []
                        -}
                        -

                        当需要修改出口节点,只需要修改 outbounds.json 的内容。

                        如果需要改变日志 log 的级别,也不需要改 base.json,只需后续增加一个配置:

                        • debuglog.json
                        {
                        +    

                        多文件配置

                        Xray 程序支持使用多个配置文件。

                        多配置文件的主要作用在于分散不同作用模块配置,便于管理和维护。

                        该功能主要考虑是为了丰富 Xray 的生态链,比如对于 GUI 的客户端,一般只实现节点选择等固定的功能,对于太复杂的配置难以图形化实现;只需留一个 confdir 的自定义配置目录供配置复杂的功能;对于服务器的部署脚本,只需往 confdir 添加文件即可实现配置多种协议。

                        多文件启动

                        提示

                        启动信息中会提示依次读入的每个配置文件,留意启动信息是否符合你预设的顺序。可以在每个文件名前面增加前缀数字的方式控制顺序。如 01_文件名, 02_文件名,数字越大排序越靠后。

                        $ xray run -confdir /etc/xray/confs
                        +

                        也可使用 Xray.location.confdirXray_LOCATION_CONFDIR 指定 confdir

                        参数 -confdir 的作用优先于环境变量,如果参数指定了有效的目录则不再读取环境变量中的路径。

                        规则说明

                        普通对象({}

                        顶级对象后者覆盖或补充前者

                        数组([]

                        在 json 配置中的 inboundsoutbounds 是数组结构,他们有特殊的规则:

                        • 查找原有 tag 相同的元素进行覆盖;若无法找到:
                          • 对于 inbounds,添加至最后(inbounds 内元素顺序无关)
                          • 对于 outbounds,添加至最前(outbounds 默认首选出口);但如果文件名含有 tail(大小写均可),添加至最后。

                        配置例子

                        假设 confs 文件夹下有以下三个配置文件。

                        • 01.json
                        {
                           "log": {
                        -    "loglevel": "debug"
                        -  }
                        -}
                        -

                        启动顺序放置在 base 后,即可输出 debug 级别的日志。

                        提示

                        文件启动顺序是通过在每个文件名前面增加前缀数字的方式实现的,如 00_文件名, 01_文件名。 数字越大排序越靠后。

                        数组([]

                        在 json 配置中的inboundsoutbounds是数组结构,他们有特殊的规则:

                        • 当配置中的数组元素有 2 个或以上,则后者覆盖前者的 inbounds/oubounds 的内容,详情看下方的【接近可用配置的例子】;
                        • 当配置中的数组元素只有 1 个时,查找原有tag相同的元素进行覆盖;若无法找到:
                          • 对于 inbounds,添加至最后(inbounds 内元素顺序无关)
                          • 对于 outbounds,添加至最前(outbounds 默认首选出口);但如果文件名含有 tail(大小写均可),添加至最后。

                        借助多配置,可以很方便为原有的配置添加不同协议的 inbound,而不必修改原有配置。

                        接近可用配置的例子

                        以下例子不是有效配置,只为展示上述规则。

                        • 00.json
                        {
                        +    "loglevel": "warning"
                        +  },
                           "inbounds": [
                             {
                        -      "protocol": "socks",
                               "tag": "socks",
                        -      "port": 1234
                        +      "protocol": "socks",
                        +      "listen": "0.0.0.0",
                        +      "port": 8888
                        +    }
                        +  ],
                        +  "outbounds": [
                        +    {
                        +      "tag": "direct",
                        +      "protocol": "freedom"
                             }
                           ]
                         }
                        -
                        • 01.json
                        {
                        +
                        • 02.json
                        {
                        +  "log": {
                        +    "loglevel": "debug"
                        +  },
                           "inbounds": [
                             {
                        -      "protocol": "http",
                        -      "tag": "http"
                        +      "tag": "socks",
                        +      "protocol": "socks",
                        +      "listen": "127.0.0.1",
                        +      "port": 1080
                        +    }
                        +  ],
                        +  "outbounds": [
                        +    {
                        +      "tag": "block",
                        +      "protocol": "blackhole"
                             }
                           ]
                         }
                        -
                        • 02.json
                        {
                        -  "inbounds": [
                        +
                        • 03_tail.json
                        {
                        +  "outbounds": [
                             {
                        -      "protocol": "socks",
                        -      "tag": "socks",
                        -      "port": 4321
                        +      "tag": "direct2",
                        +      "protocol": "freedom"
                             }
                           ]
                         }
                        -

                        三个配置将会合并为:

                        {
                        +

                        三个配置将会合并为:

                        {
                        +  "log": {
                        +    "loglevel": "debug"  // 顶级对象覆盖前者
                        +  },
                           "inbounds": [
                             {
                        +      "tag": "socks", // tag 相同时覆盖前者
                               "protocol": "socks",
                        -      "tag": "socks",
                        -      "port": 4321 // < 02.json顺序在00.json后,因此覆盖tag为socks的inbound端口为4321
                        +      "listen": "127.0.0.1",
                        +      "port": 1080 
                        +    }
                        +  ],
                        +  "outbounds": [
                        +    {
                        +      "tag": "block",  // outbounds 添加至最前
                        +      "protocol": "blackhole"
                        +    },
                        +    {
                        +      "tag": "direct",
                        +      "protocol": "freedom"
                             },
                             {
                        -      "protocol": "http",
                        -      "tag": "http"
                        +      "tag": "direct2", // 03_tail.json 文件名中包含 tail 关键字,添加至最后
                        +      "protocol": "freedom"
                             }
                           ]
                         }
                        -

                        推荐的多文件列表

                        执行:

                        for BASE in 00_log 01_api 02_dns 03_routing 04_policy 05_inbounds 06_outbounds 07_transport 08_stats 09_reverse; do echo '{}' > "/etc/Xray/$BASE.json"; done
                        -

                        for BASE in 00_log 01_api 02_dns 03_routing 04_policy 05_inbounds 06_outbounds 07_transport 08_stats 09_reverse; do echo '{}' > "/usr/local/etc/Xray/$BASE.json"; done
                        -
                        .
                        -├── 00_log.json
                        -├── 01_api.json
                        -├── 02_dns.json
                        -├── 03_routing.json
                        -├── 04_policy.json
                        -├── 05_inbounds.json
                        -├── 06_outbounds.json
                        -├── 07_transport.json
                        -├── 08_stats.json
                        -└── 09_reverse.json
                        -
                        -0 directories, 10 files
                        -
                        - +

                        提示

                        可以使用 xray run -confdir=./confs -dump 命令查看合并后的配置。但是因为 core 内部使用 protobuf 数据格式,所以 -dump 选项输出的配置格式会有所不同。

                        + diff --git a/config/features/xtls.html b/config/features/xtls.html index 5bf1c34f90..b2c197f2fb 100644 --- a/config/features/xtls.html +++ b/config/features/xtls.html @@ -24,11 +24,11 @@ XTLS 深度剖析 | Project X - - + + - + diff --git a/config/inbound.html b/config/inbound.html index 1328ae7474..b12be1b981 100644 --- a/config/inbound.html +++ b/config/inbound.html @@ -24,8 +24,8 @@ 入站代理 | Project X - - + +

                        入站代理

                        入站连接用于接收发来的数据,可用的协议请见入站协议

                        InboundObject

                        InboundObject 对应配置文件中 inbounds 项的一个子元素。

                        {
                        @@ -68,6 +68,6 @@
                           "concurrency": 3
                         }
                         

                        strategy: "always" | "random"

                        端口分配策略。

                        • "always" 表示总是分配所有已指定的端口,port 中指定了多少个端口,Xray 就会监听这些端口。
                        • "random" 表示随机开放端口,每隔 refresh 分钟在 port 范围中随机选取 concurrency 个端口来监听。

                        refresh: number

                        随机端口刷新间隔,单位为分钟。最小值为 2,建议值为 5。这个属性仅当 strategy 设置为 "random" 时有效。

                        concurrency: number

                        随机端口数量。最小值为 1,最大值为 port 范围的三分之一。建议值为 3

                        - + diff --git a/config/inbounds/dokodemo.html b/config/inbounds/dokodemo.html index 2471d9e21e..589bfdd1b0 100644 --- a/config/inbounds/dokodemo.html +++ b/config/inbounds/dokodemo.html @@ -24,8 +24,8 @@ Dokodemo-Door | Project X - - + +

                        Dokodemo-Door

                        Dokodemo door(任意门)可以监听一个本地端口,并把所有进入此端口的数据发送至指定服务器的一个端口,从而达到端口映射的效果。

                        InboundConfigurationObject

                        {
                        @@ -37,6 +37,6 @@
                           "userLevel": 0
                         }
                         

                        address: address

                        将流量转发到此地址。可以是一个 IP 地址,形如 "1.2.3.4",或者一个域名,形如 "xray.com"。字符串类型。

                        followRedirect(见下文)为 true 时,address 可为空。

                        port: number

                        将流量转发到目标地址的指定端口,范围 [1, 65535],数值类型。必填参数。

                        network: "tcp" | "udp" | "tcp,udp"

                        可接收的网络协议类型。比如当指定为 "tcp" 时,仅会接收 TCP 流量。默认值为 "tcp"

                        timeout: number

                        连接空闲的时间限制。单位为秒。默认值为 300。处理一个连接时,如果在 timeout 时间内,没有任何数据被传输,则中断该连接。

                        followRedirect: true | false

                        当值为 true 时,dokodemo-door 会识别出由 iptables 转发而来的数据,并转发到相应的目标地址。

                        可参考 传输配置 中的 tproxy 设置。

                        userLevel: number

                        用户等级,连接会使用这个用户等级对应的 本地策略

                        userLevel 的值, 对应 policylevel 的值. 如不指定, 默认为 0。

                        透明代理配置样例

                        此部分请参考透明代理(TProxy)配置教程

                        - + diff --git a/config/inbounds/http.html b/config/inbounds/http.html index ed9674422c..1ce9dcd637 100644 --- a/config/inbounds/http.html +++ b/config/inbounds/http.html @@ -24,8 +24,8 @@ HTTP | Project X - - + +

                        HTTP

                        HTTP 协议。

                        警告

                        http 协议没有对传输加密,不适宜经公网中传输,更容易成为被人用作攻击的肉鸡。

                        http 入站更有意义的用法是在局域网或本机环境下监听,为其他程序提供本地服务。

                        TIP 1

                        http proxy 只能代理 tcp 协议,udp 系的协议均不能通过。

                        TIP 2

                        在 Linux 中使用以下环境变量即可在当前 session 使用全局 HTTP 代理(很多软件都支持这一设置,也有不支持的)。

                        • export http_proxy=http://127.0.0.1:8080/ (地址须改成你配置的 HTTP 入站代理地址)
                        • export https_proxy=$http_proxy

                        InboundConfigurationObject

                        {
                        @@ -44,6 +44,6 @@
                           "pass": "my-password"
                         }
                         

                        user: string

                        用户名,字符串类型。必填。

                        pass: string

                        密码,字符串类型。必填。

                        - + diff --git a/config/inbounds/shadowsocks.html b/config/inbounds/shadowsocks.html index c5be216b85..3c8f3fec07 100644 --- a/config/inbounds/shadowsocks.html +++ b/config/inbounds/shadowsocks.html @@ -24,8 +24,8 @@ Shadowsocks | Project X - - + +

                        Shadowsocks

                        Shadowsocksopen in new tag 协议,兼容大部分其它版本的实现。

                        目前兼容性如下:

                        • 支持 TCP 和 UDP 数据包转发,其中 UDP 可选择性关闭;
                        • 推荐的加密方式:
                          • 2022-blake3-aes-128-gcm
                          • 2022-blake3-aes-256-gcm
                          • 2022-blake3-chacha20-poly1305
                        • 其他加密方式
                          • aes-256-gcm
                          • aes-128-gcm
                          • chacha20-poly1305 或称 chacha20-ietf-poly1305
                          • xchacha20-poly1305 或称 xchacha20-ietf-poly1305
                          • none 或 plain

                        Shadowsocks 2022 新协议格式提升了性能并带有完整的重放保护,解决了旧协议的以下安全问题:

                        警告

                        "none" 不加密方式下流量将明文传输。为确保安全性, 不要在公共网络上使用。

                        InboundConfigurationObject

                        {
                        @@ -44,6 +44,6 @@
                           "email": "love@xray.com"
                         }
                         

                        method: string

                        必填。

                        password: string

                        必填。

                        • Shadowsocks 2022

                        使用与 WireGuard 类似的预共享密钥作为密码。

                        使用 openssl rand -base64 <长度> 以生成与 shadowsocks-rust 兼容的密钥,长度取决于所使用的加密方法。

                        加密方法密钥长度
                        2022-blake3-aes-128-gcm16
                        2022-blake3-aes-256-gcm32
                        2022-blake3-chacha20-poly130532

                        在 Go 实现中,32 位密钥始终工作。

                        • 其他加密方法

                        任意字符串。 不限制密码长度,但短密码会更可能被破解,建议使用 16 字符或更长的密码。

                        level: number

                        用户等级,连接会使用这个用户等级对应的 本地策略

                        level 的值, 对应 policylevel 的值。 如不指定, 默认为 0。

                        email: string

                        用户邮箱,用于区分不同用户的流量(日志、统计)。

                        - + diff --git a/config/inbounds/socks.html b/config/inbounds/socks.html index dfc28067c8..1a246a5d59 100644 --- a/config/inbounds/socks.html +++ b/config/inbounds/socks.html @@ -24,8 +24,8 @@ Socks | Project X - - + + - + diff --git a/config/inbounds/trojan.html b/config/inbounds/trojan.html index 7e18b3597c..4475a22c1b 100644 --- a/config/inbounds/trojan.html +++ b/config/inbounds/trojan.html @@ -24,8 +24,8 @@ Trojan | Project X - - + + - + diff --git a/config/inbounds/vless.html b/config/inbounds/vless.html index 5e08da6461..98c61f5685 100644 --- a/config/inbounds/vless.html +++ b/config/inbounds/vless.html @@ -24,8 +24,8 @@ VLESS | Project X - - + +

                        VLESS

                        警告

                        目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。

                        VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。

                        VMess 不同,VLESS 不依赖于系统时间,认证方式同样为 UUID。

                        InboundConfigurationObject

                        {
                        @@ -51,6 +51,6 @@
                           "flow": "xtls-rprx-vision"
                         }
                         

                        id: string

                        VLESS 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID. 自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

                        • "id": "我爱🍉老师1314",
                        • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)

                        其映射标准在 VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5open in new tag

                        你可以使用命令 xray uuid -i "自定义字符串" 生成自定义字符串所映射的的 UUID。

                        也可以使用命令 xray uuid 生成随机的 UUID.

                        level: number

                        用户等级,连接会使用这个用户等级对应的 本地策略

                        level 的值, 对应 policylevel 的值。 如不指定, 默认为 0。

                        email: string

                        用户邮箱,用于区分不同用户的流量(会体现在日志、统计中)。

                        flow: string

                        流控模式,用于选择 XTLS 的算法。

                        目前入站协议中有以下流控模式可选:

                        • flow,空字符或者 none:使用普通 TLS 代理
                        • xtls-rprx-vision:使用新 XTLS 模式 包含内层握手随机填充

                        此外,目前 XTLS 仅支持 TCP、mKCP、DomainSocket 这三种传输方式。

                        - + diff --git a/config/inbounds/vmess.html b/config/inbounds/vmess.html index 7f39278585..5fe2eb8a1c 100644 --- a/config/inbounds/vmess.html +++ b/config/inbounds/vmess.html @@ -24,8 +24,8 @@ VMess | Project X - - + + - + diff --git a/config/index.html b/config/index.html index ea1dd71efe..2e4645e5df 100644 --- a/config/index.html +++ b/config/index.html @@ -24,8 +24,8 @@ 配置文件 | Project X - - + +

                        这个章节将告诉您所有的 Xray 配置细节,掌握这些内容,在您手中 Xray 将发挥更大威力。

                        概述

                        Xray 的配置文件为 json 格式, 客户端和服务端的配置格式没有区别, 只是实际的配置内容不一样。
                        形式如下:

                        {
                        @@ -43,6 +43,6 @@
                           "metrics": {}
                         }
                         

                        注意

                        如果你刚接触 Xray, 您可以先点击查看快速入门中的配置运行, 学习最基本的配置方式, 然后查看本章节内容以掌握所有 Xray 的配置方式。

                        基础配置模块

                        log:LogObject

                        日志配置,控制 Xray 输出日志的方式.

                        api:ApiObject

                        提供了一些 API 接口供远程调用。

                        dns: DnsObject

                        内置的 DNS 服务器. 如果没有配置此项,则使用系统的 DNS 设置。

                        routing: RoutingObject

                        路由功能。可以设置规则分流数据从不同的 outbound 发出.

                        policy: PolicyObject

                        本地策略,可以设置不同的用户等级和对应的策略设置。

                        inbounds: [ InboundObject ]

                        一个数组,每个元素是一个入站连接配置。

                        outbounds: [ OutboundObject ]

                        一个数组,每个元素是一个出站连接配置。

                        transport: TransportObject

                        用于配置 Xray 其它服务器建立和使用网络连接的方式。

                        stats: StatsObject

                        用于配置流量数据的统计。

                        reverse: ReverseObject

                        反向代理。可以把服务器端的流量向客户端转发,即逆向流量转发。

                        fakedns: FakeDnsObject

                        FakeDNS 配置。可配合透明代理使用,以获取实际域名。

                        metrics: metricsObject

                        metrics 配置。更直接(希望更好)的统计导出方式。

                        - + diff --git a/config/log.html b/config/log.html index 80dfcaad72..a65eb7e336 100644 --- a/config/log.html +++ b/config/log.html @@ -24,8 +24,8 @@ 日志配置 | Project X - - + +

                        日志配置

                        日志配置,控制 Xray 输出日志的方式.

                        Xray 有两种日志, 访问日志和错误日志, 你可以分别配置两种日志的输出方式.

                        LogObject

                        LogObject 对应配置文件的 log 项。

                        {
                        @@ -37,6 +37,6 @@
                           }
                         }
                         

                        access: string

                        访问日志的文件地址,其值是一个合法的文件地址,如"/var/log/Xray/access.log"(Linux)或者"C:\\Temp\\Xray\\_access.log"(Windows)。当此项不指定或为空值时,表示将日志输出至 stdout。

                        • 特殊值none,即关闭 access log。

                        error: string

                        错误日志的文件地址,其值是一个合法的文件地址,如"/var/log/Xray/error.log"(Linux)或者"C:\\Temp\\Xray\\_error.log"(Windows)。当此项不指定或为空值时,表示将日志输出至 stdout。

                        • 特殊值none,即关闭 error log。

                        loglevel: "debug" | "info" | "warning" | "error" | "none"

                        error 日志的级别, 指示 error 日志需要记录的信息. 默认值为 "warning"

                        • "debug":调试程序时用到的输出信息。同时包含所有 "info" 内容。
                        • "info":运行时的状态信息等,不影响正常使用。同时包含所有 "warning" 内容。
                        • "warning":发生了一些并不影响正常运行的问题时输出的信息,但有可能影响用户的体验。同时包含所有 "error" 内容。
                        • "error":Xray 遇到了无法正常运行的问题,需要立即解决。
                        • "none":不记录任何内容。

                        dnsLog: bool

                        是否启用 DNS 查询日志,例如:DOH//doh.server got answer: domain.com -> [ip1, ip2] 2.333ms

                        - + diff --git a/config/metrics.html b/config/metrics.html index 93ea16ad4a..16c7866507 100644 --- a/config/metrics.html +++ b/config/metrics.html @@ -24,8 +24,8 @@ Metrics | Project X - - + + - + diff --git a/config/outbound.html b/config/outbound.html index 261bb4c510..bc3a6f4fc4 100644 --- a/config/outbound.html +++ b/config/outbound.html @@ -24,8 +24,8 @@ 出站代理 | Project X - - + +

                        出站代理

                        出站连接用于发送数据,可用的协议请见 出站协议

                        OutboundObject

                        OutboundObject 对应配置文件中 outbounds 项的一个子元素。

                        提示

                        列表中的第一个元素作为主 outbound。当路由匹配不存在或没有匹配成功时,流量由主 outbound 发出。

                        {
                        @@ -53,6 +53,6 @@
                           "xudpProxyUDP443": "reject"
                         }
                         

                        enabled: true | false

                        是否启用 Mux 转发请求,默认值 false

                        concurrency: number

                        最大并发连接数。最小值 1,最大值 1024。省略或者填 0 时都等于 8

                        这个数值表示了一个 TCP 连接上最多承载的子连接数量。比如设置 concurrency=8 时,当客户端发出了 8 个 TCP 请求,Xray 只会发出一条实际的 TCP 连接,客户端的 8 个请求全部由这个 TCP 连接传输。

                        提示

                        填负数时,如 -1,不使用 Mux 模块承载 TCP 流量。

                        xudpConcurrency: number

                        使用新 XUDP 聚合隧道(也就是另一条 Mux 连接)代理 UDP 流量,填写最大并发子 UoT 数量。最小值 1,最大值 1024。 省略或者填 0 时,将与 TCP 流量走同一条路,也就是传统的行为。

                        提示

                        填负数时,如 -1,不使用 Mux 模块承载 UDP 流量。将使用代理协议原本的 UDP 传输方式。例如 Shadowsocks 会使用原生 UDP,VLESS 会使用 UoT。

                        xudpProxyUDP443: string

                        控制 Mux 对于被代理的 UDP/443(QUIC)流量的处理方式:

                        • 默认 reject 拒绝流量(一般浏览器会自动回落到 TCP HTTP2)
                        • allow 允许走 Mux 连接。
                        • skip 时,不使用 Mux 模块承载 UDP 443 流量。将使用代理协议原本的 UDP 传输方式。例如 Shadowsocks 会使用原生 UDP,VLESS 会使用 UoT。
                        - + diff --git a/config/outbounds/blackhole.html b/config/outbounds/blackhole.html index 3eb54735a3..0e77ed2031 100644 --- a/config/outbounds/blackhole.html +++ b/config/outbounds/blackhole.html @@ -24,8 +24,8 @@ Blackhole | Project X - - + + - + diff --git a/config/outbounds/dns.html b/config/outbounds/dns.html index f50b1f6353..6b4742ea13 100644 --- a/config/outbounds/dns.html +++ b/config/outbounds/dns.html @@ -24,8 +24,8 @@ DNS | Project X - - + +

                        DNS

                        DNS 是一个出站协议,主要用于拦截和转发 DNS 查询。

                        此出站协议只能接收 DNS 流量(包含基于 UDP 和 TCP 协议的查询),其它类型的流量会导致错误。

                        在处理 DNS 查询时,此出站协议会将 IP 查询(即 A 和 AAAA)转发给内置的 DNS 服务器。其它类型的查询流量将被转发至它们原本的目标地址。

                        OutboundConfigurationObject

                        {
                        @@ -35,6 +35,6 @@
                           "nonIPQuery": "drop"
                         }
                         

                        network: "tcp" | "udp"

                        修改 DNS 流量的传输层协议,可选的值有 "tcp""udp"。当不指定时,保持来源的传输方式不变。

                        address: address

                        修改 DNS 服务器地址。当不指定时,保持来源中指定的地址不变。

                        port: number

                        修改 DNS 服务器端口。当不指定时,保持来源中指定的端口不变。

                        nonIPQuery: string

                        控制非 IP 查询(非 A 和 AAAA),"drop" 丢弃或者 "skip" 不由内置 DNS 服务器处理,将转发给目标。默认为 "drop"

                        DNS 配置实例 WIP

                        - + diff --git a/config/outbounds/freedom.html b/config/outbounds/freedom.html index 4c491c5af2..c48a4525c7 100644 --- a/config/outbounds/freedom.html +++ b/config/outbounds/freedom.html @@ -24,8 +24,8 @@ Freedom | Project X - - + +

                        Freedom

                        Freedom 是一个出站协议,可以用来向任意网络发送(正常的) TCP 或 UDP 数据。

                        OutboundConfigurationObject

                        {
                        @@ -40,6 +40,6 @@
                           "proxyProtocol": 0
                         }
                         

                        domainStrategy: "AsIs"
                        "UseIP" | "UseIPv6v4" | "UseIPv6" | "UseIPv4v6" | "UseIPv4"
                        "ForceIP" | "ForceIPv6v4" | "ForceIPv6" | "ForceIPv4v6" | "ForceIPv4"

                        默认值 "AsIs"

                        当目标地址为域名时,配置相应的值,Freedom 的行为模式如下:

                        • 当使用 "AsIs" 时,Xray将直接使用系统栈发起连接,优先级与选择IP取决于系统设置。
                        • 当填写其他值时,将使用 Xray-core 内置 DNS 服务器 服务器进行解析。若不存在DNSObject,则使用系统DNS。若有多个符合条件的IP地址时,核心会随机选择一个IP作为目标IP。
                        • "IPv4" 代表尝试仅使用IPv4进行连接,"IPv4v6" 代表尝试使用IPv4或IPv6连接,但对于双栈域名,尽量使用IPv4。(v4v6调换后同理,不再赘述)
                        • 当在内置DNS设置了 "queryStrategy" 后,实际行为将会与这个选项取并,只有都被包含的IP类型才会被解析,如 "queryStrategy": "UseIPv4" "domainStrategy": "UseIP",实际上等同于 "domainStrategy": "UseIPv4"
                        • 当使用 "Use" 开头的选项时,若解析结果不符合要求(如,域名只有IPv4解析结果但使用了UseIPv6),则会回落回AsIs。
                        • 当使用 "Force" 开头的选项时,若解析结果不符合要求,则该连接会无法建立。

                        TIP 1

                        当使用 "UseIP""ForceIP" 模式时,并且 出站连接配置 中指定了 sendThrough 时,Freedom 会根据 sendThrough 的值自动判断所需的 IP 类型,IPv4 或 IPv6。若手动指定了单种IP类型(如UseIPv4),但与 sendThrough 指定的本地地址不匹配,将会导致连接失败。

                        redirect: address_port

                        Freedom 会强制将所有数据发送到指定地址(而不是 inbound 指定的地址)。

                        其值为一个字符串,样例:"127.0.0.1:80"":1234"

                        当地址不指定时,如 ":443",Freedom 不会修改原先的目标地址。 当端口为 0 时,如 "xray.com: 0",Freedom 不会修改原先的端口。

                        userLevel: number

                        用户等级,连接会使用这个用户等级对应的 本地策略

                        userLevel 的值, 对应 policylevel 的值。 如不指定, 默认为 0。

                        fragment: map

                        一些键值对配置项,用于控制发出的 TCP 分片,在某些情况下可以欺骗审查系统,比如绕过 SNI 黑名单。

                        "packets":支持两种分片方式 "1-3" 是 TCP 的流切片,应用于客户端第 1 至第 3 次写数据。"tlshello" 是 TLS 握手包切片。

                        "length":分片包长 (byte)

                        "interval":分片间隔(ms)

                        proxyProtocol: number

                        PROXY protocol 通常配合 redirect 重定向到开启了 PROXY protocol 协议的 Nginx 或其他后端服务中。如果后端服务不支持 PROXY protocol 协议,连接将会被断开。

                        proxyProtocol 的值为 PROXY protocol 版本号,可选 12,如不指定,默认为 0 不启用。

                        - + diff --git a/config/outbounds/http.html b/config/outbounds/http.html index 44b0616617..671f0a0c99 100644 --- a/config/outbounds/http.html +++ b/config/outbounds/http.html @@ -24,8 +24,8 @@ HTTP | Project X - - + + - + diff --git a/config/outbounds/loopback.html b/config/outbounds/loopback.html index 1cc5abdf58..169bc38d6d 100644 --- a/config/outbounds/loopback.html +++ b/config/outbounds/loopback.html @@ -24,8 +24,8 @@ Loopback | Project X - - + + - + diff --git a/config/outbounds/shadowsocks.html b/config/outbounds/shadowsocks.html index f61bba8eb1..5d62327fba 100644 --- a/config/outbounds/shadowsocks.html +++ b/config/outbounds/shadowsocks.html @@ -24,8 +24,8 @@ Shadowsocks | Project X - - + +

                        Shadowsocks

                        Shadowsocksopen in new tag 协议,兼容大部分其它版本的实现。

                        目前兼容性如下:

                        • 支持 TCP 和 UDP 数据包转发,其中 UDP 可选择性关闭;
                        • 推荐的加密方式:
                          • 2022-blake3-aes-128-gcm
                          • 2022-blake3-aes-256-gcm
                          • 2022-blake3-chacha20-poly1305
                        • 其他加密方式
                          • aes-256-gcm
                          • aes-128-gcm
                          • chacha20-poly1305 或称 chacha20-ietf-poly1305
                          • xchacha20-poly1305 或称 xchacha20-ietf-poly1305
                          • none 或 plain

                        Shadowsocks 2022 新协议格式提升了性能并带有完整的重放保护,解决了旧协议的以下安全问题:

                        警告

                        "none" 不加密方式下流量将明文传输。为确保安全性, 不要在公共网络上使用。

                        OutboundConfigurationObject

                        {
                        @@ -53,6 +53,6 @@
                           "level": 0
                         }
                         

                        email: string

                        邮件地址,可选,用于标识用户

                        address: address

                        Shadowsocks 服务端地址,支持 IPv4、IPv6 和域名。必填。

                        port: number

                        Shadowsocks 服务端端口。必填。

                        method: string

                        必填。

                        password: string

                        必填。

                        uot: bool

                        启用udp over tcp

                        UoTVersion: number

                        UDP over TCP 的实现版本。

                        当前可选值:1, 2

                        • Shadowsocks 2022

                        使用与 WireGuard 类似的预共享密钥作为密码。

                        使用 openssl rand -base64 <长度> 以生成与 shadowsocks-rust 兼容的密钥,长度取决于所使用的加密方法。

                        加密方法密钥长度
                        2022-blake3-aes-128-gcm16
                        2022-blake3-aes-256-gcm32
                        2022-blake3-chacha20-poly130532

                        在 Go 实现中,32 位密钥始终工作。

                        • 其他加密方法

                        任意字符串。不限制密码长度,但短密码会更可能被破解,建议使用 16 字符或更长的密码。

                        level: number

                        用户等级,连接会使用这个用户等级对应的 本地策略

                        level 的值, 对应 policylevel 的值。 如不指定, 默认为 0。

                        - + diff --git a/config/outbounds/socks.html b/config/outbounds/socks.html index cf398b488f..48cd2f4846 100644 --- a/config/outbounds/socks.html +++ b/config/outbounds/socks.html @@ -24,8 +24,8 @@ Socks | Project X - - + + - + diff --git a/config/outbounds/trojan.html b/config/outbounds/trojan.html index 850164d80e..6a8a09d252 100644 --- a/config/outbounds/trojan.html +++ b/config/outbounds/trojan.html @@ -24,8 +24,8 @@ Trojan | Project X - - + + - + diff --git a/config/outbounds/vless.html b/config/outbounds/vless.html index 99d288c06c..f62a728fd3 100644 --- a/config/outbounds/vless.html +++ b/config/outbounds/vless.html @@ -24,8 +24,8 @@ VLESS | Project X - - + +

                        VLESS

                        警告

                        目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。

                        VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。

                        VMess 不同,VLESS 不依赖于系统时间,认证方式同样为 UUID。

                        OutboundConfigurationObject

                        {
                        @@ -63,6 +63,6 @@
                           "level": 0
                         }
                         

                        id: string

                        VLESS 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID. 自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

                        • "id": "我爱🍉老师1314",
                        • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)

                        其映射标准在 VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5open in new tag

                        你可以使用命令 xray uuid -i "自定义字符串" 生成自定义字符串所映射的的 UUID,也可以使用命令 xray uuid 生成随机的 UUID。

                        encryption: "none"

                        需要填 "none",不能留空。

                        该要求是为了提醒使用者没有加密,也为了以后出加密方式时,防止使用者填错属性名或填错位置导致裸奔。

                        若未正确设置 encryption 的值,使用 Xray 或 -test 时会收到错误信息。

                        flow: string

                        流控模式,用于选择 XTLS 的算法。

                        目前出站协议中有以下流控模式可选:

                        • flow,空字符或者 none:使用普通 TLS 代理
                        • xtls-rprx-vision:使用新 XTLS 模式 包含内层握手随机填充 支持 uTLS 模拟客户端指纹
                        • xtls-rprx-vision-udp443:同 xtls-rprx-vision, 但是放行了目标为 443 端口的 UDP 流量

                        此外,目前 XTLS 仅支持 TCP、mKCP、DomainSocket 这三种传输方式。

                        关于 xtls-rprx-*-udp443 流控模式

                        启用了 Xray-core 的 XTLS 时,通往 UDP 443 端口的流量默认会被拦截(一般情况下为 QUIC),这样应用就不会使用 QUIC 而会使用 TLS,XTLS 才会真正生效。实际上,QUIC 本身也不适合被代理,因为 QUIC 自带了 TCP 的功能,它作为 UDP 流量在通过 VLESS 协议传输时,底层协议为 TCP,就相当于两层 TCP 了。

                        若不需要拦截,请在客户端填写 xtls-rprx-*-udp443,服务端不变。

                        关于 Splice 模式

                        Splice 是 Linux Kernel 提供的函数,系统内核直接转发 TCP,不再经过 Xray 的内存,大大减少了数据拷贝、CPU 上下文切换的次数。

                        Splice 模式的的使用限制:

                        • Linux 环境
                        • 入站协议为 Dokodemo doorSocksHTTP 等纯净的 TCP 连接, 或其它使用了 XTLS 的入站协议
                        • 出站协议为 VLESS + XTLS
                        • 需要注意的是,使用 mKCP 协议时不会使用 Splice(是的,虽然没有报错,但实际上根本没用到)

                        此外,使用 Splice 时网速显示会滞后,这是特性,不是 bug。

                        使用 Vision 模式 如果满足上述条件 会自动启用 Splice

                        level: number

                        用户等级,连接会使用这个用户等级对应的 本地策略

                        level 的值, 对应 policylevel 的值。 如不指定, 默认为 0。

                        - + diff --git a/config/outbounds/vmess.html b/config/outbounds/vmess.html index 09587f7ec9..530783358c 100644 --- a/config/outbounds/vmess.html +++ b/config/outbounds/vmess.html @@ -24,8 +24,8 @@ VMess | Project X - - + +

                        VMess

                        VMess 是一个加密传输协议,通常作为 Xray 客户端和服务器之间的桥梁。

                        警告

                        VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 120 秒之内,时区无关。在 Linux 系统中可以安装ntp服务来自动同步系统时间。

                        OutboundConfigurationObject

                        {
                        @@ -56,6 +56,6 @@
                           "experiments": ""
                         }
                         

                        id:string

                        Vmess 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID.

                        自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

                        • "id": "我爱🍉老师1314",
                        • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)

                        其映射标准在 VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5open in new tag

                        你可以使用命令 xray uuid -i "自定义字符串" 生成自定义字符串所映射的的 UUID, 也可以使用命令 xray uuid 生成随机的 UUID。

                        level: number

                        用户等级,连接会使用这个用户等级对应的 本地策略

                        level 的值, 对应 policylevel 的值。 如不指定, 默认为 0。

                        security: "aes-128-gcm" | "chacha20-poly1305" | "auto" | "none" | "zero"

                        加密方式,客户端将使用配置的加密方式发送数据,服务器端自动识别,无需配置。

                        • "aes-128-gcm":推荐在 PC 上使用
                        • "chacha20-poly1305":推荐在手机端使用
                        • "auto":默认值,自动选择(运行框架为 AMD64、ARM64 或 s390x 时为 aes-128-gcm 加密方式,其他情况则为 Chacha20-Poly1305 加密方式)
                        • "none":不加密
                        • "zero":不加密,也不进行消息认证 (v1.4.0+)

                        提示

                        推荐使用"auto"加密方式,这样可以永久保证安全性和兼容性。

                        "none" 伪加密方式会计算并验证数据包的校验数据,由于认证算法没有硬件支持,在部分平台可能速度比有硬件加速的 "aes-128-gcm" 还慢。

                        "zero" 伪加密方式不会加密消息也不会计算数据的校验数据,因此理论上速度会高于其他任何加密方式。实际速度可能受到其他因素影响。

                        不推荐在未开启 TLS 加密并强制校验证书的情况下使用 "none" "zero" 伪加密方式。 如果使用 CDN 或其他会解密 TLS 的中转平台或网络环境建立连接,不建议使用 "none" "zero" 伪加密方式。

                        无论使用哪种加密方式, VMess 的包头都会受到加密和认证的保护。

                        experiments: string

                        启用的 VMess 协议实验性功能。(此处的功能为不稳定功能, 可能随时被移除)多个启用的实验之间可以用 | 字符分割,如 "AuthenticatedLength|NoTerminationSignal" 。

                        "AuthenticatedLength" 启用认证的数据包长度实验。此实验需要同时在客户端与服务器端同时开启,并运行相同版本的程序。

                        "NoTerminationSignal" 启用不发送断开连接标致实验。此实验可能会影响被代理的连接的稳定性。

                        - + diff --git a/config/outbounds/wireguard.html b/config/outbounds/wireguard.html index 905c09762a..60f18ca4f9 100644 --- a/config/outbounds/wireguard.html +++ b/config/outbounds/wireguard.html @@ -24,8 +24,8 @@ Wireguard | Project X - - + +

                        Wireguard

                        标准 Wireguard 协议实现。

                        警告

                        Wireguard 协议并非专门为翻墙而设计,若在最外层过墙,存在特征可能导致服务器被封锁

                        OutboundConfigurationObject

                        {
                        @@ -77,6 +77,6 @@
                           "allowedIPs": ["0.0.0.0/0"] // optional, default ["0.0.0.0/0", "::/0"]
                         }
                         

                        endpoint: address

                        服务器地址, 必填

                        URL:端口 格式,例如 engage.cloudflareclient.com:2408
                        IP:端口 格式,例如 162.159.192.1:2408[2606:4700:d0::a29f:c001]:2408

                        提示

                        当目标地址类型为 URL 时,将使用 Xray-core 内置 DNS 查询 URL 以获取 IP,IPv4 或 IPv6 优先级由 domainStrategy 的值控制。
                        若没写 "dns" 配置,使用系统 DNS 查询 URL 以获取 IP,IPv4 或 IPv6 优先级由系统控制。

                        publicKey: string

                        服务器公钥,用于验证, 必填

                        preSharedKey: string

                        额外的对称加密密钥

                        keepAlive: int

                        心跳包时间间隔,单位为秒,默认为 0 表示无心跳

                        allowedIPs: string array

                        Wireguard 仅允许特定源 IP 的流量

                        - + diff --git a/config/policy.html b/config/policy.html index af7c8830ca..5802455fc9 100644 --- a/config/policy.html +++ b/config/policy.html @@ -24,8 +24,8 @@ 本地策略 | Project X - - + +

                        本地策略

                        本地策略,可以设置不同的用户等级和对应的策略设置,比如连接超时设置。Xray 处理的每一个连接都对应一个用户,按照用户的等级(level)应用不同的策略。

                        PolicyObject

                        PolicyObject 对应配置文件的 policy 项。

                        {
                        @@ -65,6 +65,6 @@
                           "statsOutboundDownlink": false
                         }
                         

                        statsInboundUplink: true | false

                        当值为 true 时,开启所有入站代理的上行流量统计。

                        statsInboundDownlink: true | false

                        当值为 true 时,开启所有入站代理的下行流量统计。

                        statsOutboundUplink: true | false

                        当值为 true 时,开启所有出站代理的上行流量统计。

                        statsOutboundDownlink: true | false

                        当值为 true 时,开启所有出站代理的下行流量统计。

                        - + diff --git a/config/reverse.html b/config/reverse.html index cd13b0db64..a0e69830a7 100644 --- a/config/reverse.html +++ b/config/reverse.html @@ -24,8 +24,8 @@ 反向代理 | Project X - - + +

                        反向代理

                        反向代理可以把服务器端的流量向客户端转发,即逆向流量转发。

                        反向代理的大致工作原理如下:

                        • 假设在主机 A 中有一个网页服务器,这台主机没有公网 IP,无法在公网上直接访问。另有一台主机 B,它可以由公网访问。现在我们需要把 B 作为入口,把流量从 B 转发到 A。
                        • 在主机 A 中配置 Xray,称为bridge,在 B 中也配置 Xray,称为 portal
                        • bridge 会向 portal 主动建立连接,此连接的目标地址可以自行设定。portal 会收到两种连接,一是由 bridge 发来的连接,二是公网用户发来的连接。portal 会自动将两类连接合并。于是 bridge 就可以收到公网流量了。
                        • bridge 在收到公网流量之后,会将其原封不动地发给主机 A 中的网页服务器。当然,这一步需要路由的协作。
                        • bridge 会根据流量的大小进行动态的负载均衡。

                        提示

                        反向代理默认已开启 Mux,请不要在其用到的 outbound 上再次开启 Mux。

                        注意

                        反向代理功能尚处于测试阶段,可能会有一些问题。

                        ReverseObject

                        ReverseObject 对应配置文件的 reverse 项。

                        {
                        @@ -144,6 +144,6 @@
                           ]
                         }
                         
                        - + diff --git a/config/routing.html b/config/routing.html index e6634b9b61..17add2dbac 100644 --- a/config/routing.html +++ b/config/routing.html @@ -24,8 +24,8 @@ 路由 | Project X - - + +

                        路由

                        路由功能模块可以将入站数据按不同规则由不同的出站连接发出,以达到按需代理的目的。

                        如常见用法是分流国内外流量,Xray 可以通过内部机制判断不同地区的流量,然后将它们发送到不同的出站代理。

                        有关路由功能更详细的解析:路由 (routing) 功能简析open in new tag

                        RoutingObject

                        RoutingObject 对应配置文件的 routing 项。

                        {
                        @@ -99,6 +99,6 @@
                                 }
                             ]
                         

                        预定义域名列表

                        此列表预置于每一个 Xray 的安装包中,文件名为 geosite.dat。这个文件包含了一些常见的域名,使用方式:geosite:filename,如 geosite:google 表示对文件内符合 google 内包含的域名,进行路由筛选或 DNS 筛选。

                        常见的域名有:

                        • category-ads:包含了常见的广告域名。
                        • category-ads-all:包含了常见的广告域名,以及广告提供商的域名。
                        • cn:相当于 geolocation-cntld-cn 的合集。
                        • apple:包含了 Apple 旗下绝大部分域名。
                        • google:包含了 Google 旗下绝大部分域名。
                        • microsoft:包含了 Microsoft 旗下绝大部分域名。
                        • facebook:包含了 Facebook 旗下绝大部分域名。
                        • twitter:包含了 Twitter 旗下绝大部分域名。
                        • telegram:包含了 Telegram 旗下绝大部分域名。
                        • geolocation-cn:包含了常见的大陆站点域名。
                        • geolocation-!cn:包含了常见的非大陆站点域名,同时包含了 tld-!cn
                        • tld-cn:包含了 CNNIC 管理的用于中国大陆的顶级域名,如以 .cn.中国 结尾的域名。
                        • tld-!cn:包含了非中国大陆使用的顶级域名,如以 .hk(香港)、.tw(台湾)、.jp(日本)、.sg(新加坡)、.us(美国).ca(加拿大)等结尾的域名。

                        你也可以在这里查看完整的域名列表 Domain list communityopen in new tag

                        - + diff --git a/config/stats.html b/config/stats.html index bfcc89a630..5a9e60345e 100644 --- a/config/stats.html +++ b/config/stats.html @@ -24,14 +24,14 @@ 统计信息 | Project X - - + +

                        统计信息

                        用于配置 Xray 流量数据的统计。

                        StatsObject

                        StatsObject 对应配置文件的 stats 项。

                        {
                           "stats": {}
                         }
                         

                        目前统计信息不需要任何参数,只要 StatsObject 项存在,内部的统计即会开启。

                        开启了统计以后, 只需在 Policy 中开启对应的项,就可以统计对应的数据。

                        获取统计信息

                        可以用 xray api 的相关命令获取统计信息.

                        目前已有的统计信息如下:

                        • 用户数据

                          • user>>>[email]>>>traffic>>>uplink

                            特定用户的上行流量,单位字节。

                          • user>>>[email]>>>traffic>>>downlink

                            特定用户的下行流量,单位字节。

                        提示

                        如果对应用户没有指定 Email,则不会开启统计。

                        • 全局数据

                          • inbound>>>[tag]>>>traffic>>>uplink

                            特定 inbound 的上行流量,单位字节。

                          • inbound>>>[tag]>>>traffic>>>downlink

                            特定 inbound 的下行流量,单位字节。

                          • outbound>>>[tag]>>>traffic>>>uplink

                            特定 outbound 的上行流量,单位字节。

                          • outbound>>>[tag]>>>traffic>>>downlink

                            特定 outbound 的下行流量,单位字节。

                        - + diff --git a/config/transport.html b/config/transport.html index d6ea4afd33..635524c38e 100644 --- a/config/transport.html +++ b/config/transport.html @@ -24,8 +24,8 @@ 传输方式 | Project X - - + +

                        传输方式

                        传输方式(transport)是当前 Xray 节点和其它节点对接的方式。

                        传输方式指定了稳定的数据传输的方式。通常来说,一个网络连接的两端需要有对称的传输方式。比如一端用了 WebSocket,那么另一个端也必须使用 WebSocket,否则无法建立连接。

                        传输方式(transport)配置有两部分:

                        1. 全局配置(TransportObject
                        2. 局部配置(StreamSettingsObject)。
                        • 局部配置时,可以指定每个单独的入站或出站用怎样的方式传输。
                        • 通常来说客户端和服务器对应的入站和出站需要使用同样的传输方式。当其配置指定了一种传输方式,但没有填写具体设置时,此传输方式会使用全局配置中的设置。

                        TransportObject

                        TransportObject 对应配置文件的 transport 项。

                        {
                        @@ -176,6 +176,6 @@
                           "tcpNoDelay": false
                         }
                         

                        mark: number

                        一个整数。当其值非零时,在 outbound 连接上以此数值标记 SO_MARK。

                        • 仅适用于 Linux 系统。
                        • 需要 CAP_NET_ADMIN 权限。

                        tcpMaxSeg: number

                        用于设置 TCP 数据包的最大传输单元。

                        tcpFastOpen: true | false | number

                        是否启用 TCP Fast Openopen in new tag

                        当其值为 true正整数时,启用 TFO;当其值为 false负数时,强制关闭 TFO;当此项不存在或为 0 时,使用系统默认设置。 可用于 inbound/outbound。

                        • 仅在以下版本(或更新版本)的操作系统中可用:

                          • Windows 10 (1607)
                          • Mac OS 10.11 / iOS 9
                          • Linux 3.16:需要通过内核参数 net.ipv4.tcp_fastopen 进行设定,此参数是一个 bitmap,0x1 代表客户端允许启用,0x2 代表服务器允许启用;默认值为 0x1,如果服务器要启用 TFO,请把此内核参数值设为 0x3
                          • FreeBSD 10.3 (Server) / 12.0 (Client):需要把内核参数 net.inet.tcp.fastopen.server_enabled 以及 net.inet.tcp.fastopen.client_enabled 设为 1
                        • 对于 Inbound,此处所设定的正整数代表 待处理的 TFO 连接请求数上限open in new tag注意并非所有操作系统都支持在此设定

                          • Linux / FreeBSD:此处的设定的正整数值代表上限,可接受的最大值为 2147483647,为 true 时将取 256;注意在 Linux,net.core.somaxconn 会限制此值的上限,如果超过了 somaxconn,请同时提高 somaxconn
                          • Mac OS:此处为 true正整数时,仅代表启用 TFO,上限需要通过内核参数 net.inet.tcp.fastopen_backlog 单独设定。
                          • Windows:此处为 true正整数时,仅代表启用 TFO。
                        • 对于 Outbound,设定为 true正整数在任何操作系统都仅表示启用 TFO。

                        tproxy: "redirect" | "tproxy" | "off"

                        是否开启透明代理(仅适用于 Linux)。

                        • "redirect":使用 Redirect 模式的透明代理。支持所有基于 IPv4/6 的 TCP 和 UDP 连接。
                        • "tproxy":使用 TProxy 模式的透明代理。支持所有基于 IPv4/6 的 TCP 和 UDP 连接。
                        • "off":关闭透明代理。

                        透明代理需要 Root 或 CAP\_NET\_ADMIN 权限。

                        警告

                        Dokodemo-door 中指定了 followRedirecttrue,且 Sockopt 设置中的tproxy 为空时,Sockopt 设置中的tproxy 的值会被设为 "redirect"

                        domainStrategy: "AsIs"
                        "UseIP" | "UseIPv6v4" | "UseIPv6" | "UseIPv4v6" | "UseIPv4"
                        "ForceIP" | "ForceIPv6v4" | "ForceIPv6" | "ForceIPv4v6" | "ForceIPv4"

                        在之前的版本中,当 Xray 尝试使用域名建立系统连接时,域名的解析由系统完成,不受 Xray 控制。这导致了在 非标准 Linux 环境中无法解析域名open in new tag 等问题。为此,Xray 1.3.1 为 Sockopt 引入了 Freedom 中的 domainStrategy,解决了此问题。

                        默认值 "AsIs"

                        当目标地址为域名时,配置相应的值,Freedom 的行为模式如下:

                        • 当使用 "AsIs" 时,Xray将直接使用系统栈发起连接,优先级与选择IP取决于系统设置。
                        • 当填写其他值时,将使用 Xray-core 内置 DNS 服务器 服务器进行解析。若不存在DNSObject,则使用系统DNS。若有多个符合条件的IP地址时,核心会随机选择一个IP作为目标IP。
                        • "IPv4" 代表尝试仅使用IPv4进行连接,"IPv4v6" 代表尝试使用IPv4或IPv6连接,但对于双栈域名,尽量使用IPv4。(v4v6调换后同理,不再赘述)
                        • 当在内置DNS设置了 "queryStrategy" 后,实际行为将会与这个选项取并,只有都被包含的IP类型才会被解析,如 "queryStrategy": "UseIPv4" "domainStrategy": "UseIP",实际上等同于 "domainStrategy": "UseIPv4"
                        • 当使用 "Use" 开头的选项时,若解析结果不符合要求(如,域名只有IPv4解析结果但使用了UseIPv6),则会回落回AsIs。
                        • 当使用 "Force" 开头的选项时,若解析结果不符合要求,则该连接会无法建立。

                        TIP

                        当使用 "UseIP""ForceIP" 模式时,并且 出站连接配置 中指定了 sendThrough 时,Freedom 会根据 sendThrough 的值自动判断所需的 IP 类型,IPv4 或 IPv6。若手动指定了单种IP类型(如UseIPv4),但与 sendThrough 指定的本地地址不匹配,将会导致连接失败。

                        警告

                        启用了此功能后,不当的配置可能会导致死循环。

                        一句话版本:连接到服务器,需要等待 DNS 查询结果;完成 DNS 查询,需要连接到服务器。

                        Tony: 先有鸡还是先有蛋?

                        详细解释:

                        1. 触发条件:代理服务器(proxy.com)。内置 DNS 服务器,非 Local 模式。
                        2. Xray 尝试向 proxy.com 建立 TCP 连接 ,通过内置 DNS 服务器查询 proxy.com。
                        3. 内置 DNS 服务器向 dns.com 建立连接,并发送查询,以获取 proxy.com 的 IP。
                        4. 不当的 的路由规则,导致 proxy.com 代理了步骤 3 中发出的查询。
                        5. Xray 尝试向 proxy.com 建立另一个 TCP 连接。
                        6. 在建立连接前,通过内置 DNS 服务器查询 proxy.com。
                        7. 内置 DNS 服务器复用步骤 3 中的连接,发出查询。
                        8. 问题出现。步骤 3 中连接的建立,需要等待步骤 7 中的查询结果;步骤 7 完成查询,需要等待步骤 3 中的连接完全建立。
                        9. Good Game!

                        解决方案:

                        • 改内置 DNS 服务器的分流。
                        • 用 Hosts。
                        • 如果你还是不知道解决方案,就别用这个功能了。

                        因此,不建议 经验不足的用户擅自使用此功能。

                        dialerProxy: ""

                        一个出站代理的标识。当值不为空时,将使用指定的 outbound 发出连接。 此选项可用于支持底层传输方式的链式转发。

                        警告

                        此选项与 ProxySettingsObject.Tag 不兼容

                        acceptProxyProtocol: true | false

                        仅用于 inbound,指示是否接收 PROXY protocol。

                        PROXY protocolopen in new tag 专用于传递请求的真实来源 IP 和端口,若你不了解它,请先忽略该项

                        常见的反代软件(如 HAProxy、Nginx)都可以配置发送它,VLESS fallbacks xver 也可以发送它。

                        填写 true 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2,否则连接会被关闭。

                        tcpKeepAliveInterval: number

                        TCP 保持活跃的数据包发送间隔,单位为秒。该设置仅适用于 Linux 下。

                        它是连接不正常(未收到 ack)时候的心跳包。

                        不配置此项或配置为 0 表示使用 Go 默认值。

                        提示

                        填负数时,如 -1,不启用 TCP 保持活跃。

                        tcpKeepAliveIdle: number

                        TCP 空闲时间阈值,单位为秒。当 TCP 连接空闲时间达到这个阈值时,将开始发送 Keep-Alive 探测包。

                        它是连接正常时候的心跳包。

                        不配置此项或配置为 0 表示使用 Go 默认值。

                        提示

                        填负数时,如 -1,不启用 TCP 保持活跃。

                        tcpUserTimeout: number

                        单位为毫秒。详细介绍:https://github.com/grpc/proposal/blob/master/A18-tcp-user-timeout.md

                        tcpcongestion: ""

                        TCP 拥塞控制算法。仅支持 Linux。 不配置此项表示使用系统默认值。

                        常见的算法

                        • bbr(推荐)
                        • cubic
                        • reno

                        提示

                        执行命令 sysctl net.ipv4.tcp_congestion_control 获取系统默认值。

                        interface: ""

                        指定绑定出口网卡名称,支持 linux / iOS / Mac OS / Windows。
                        iOS / Mac OS 需要 Xray-core v1.8.6 或更高版本。
                        Windows 需要 Xray-core v1.8.7 或更高版本。

                        V6Only: true | false

                        填写 true 时,监听 :: 地址仅接受 IPv6 连接。仅支持 Linux。

                        tcpWindowClamp: number

                        绑定通告的 windows 大小为该值。内核会在它与 SOCK_MIN_RCVBUF/2 之间选一个最大值。

                        tcpMptcp: true | false

                        Xray-core v1.8.6 新增参数。
                        默认值 false,填写 true 时,启用 Multipath TCPopen in new tag,需在服务端和客户端配置中同时启用。 当前仅支持Linux,需要Linux Kernel 5.6及以上。

                        tcpNoDelay: true | false

                        默认值 false,建议与 "tcpMptcp": true 一起启用。

                        最近更改:
                        Contributors: JimhHan, xqzr, Jim Han, yuhan6665, ちか, 风扇滑翔翼, tdjnodj, 风扇滑翔翼, Binbin Qian, Chuei Kan, Daniel Ding, Kobe Arthur Scofield, KoriIku, Lumière Élevé, WaterLemons2k, Winston2084, Yang Lu, chika0801, flowerinsnow, lxsq, pvqogw
                        - + diff --git a/config/transports/domainsocket.html b/config/transports/domainsocket.html index 3139f901f3..d6e15ce85e 100644 --- a/config/transports/domainsocket.html +++ b/config/transports/domainsocket.html @@ -24,8 +24,8 @@ Domain Socket | Project X - - + +

                        Domain Socket

                        警告

                        推荐写到 inboundslisten 处,传输方式可选 TCP、WebSocket、HTTP/2. 未来这里的 DomainSocket 可能会被弃用。

                        Domain Socket 使用标准的 Unix domain socket 来传输数据。

                        它的优势是使用了操作系统内建的传输通道,而不会占用网络缓存。 理论上相比起本地环回网络(local loopback)来说,Domain socket 速度略快一些。

                        目前仅可用于支持 Unix domain socket 的平台,如 Linux 和 macOS。在 Windows 10 Build 17036 前不可用。

                        如果指定了 domain socket 作为传输方式,在入站出站代理中配置的端口和 IP 地址将会失效,所有的传输由 domain socket 取代。

                        DomainSocketObject

                        DomainSocketObject 对应传输配置的 dsSettings 项。

                        {
                        @@ -34,6 +34,6 @@
                           "padding": false
                         }
                         

                        path: string

                        一个合法的文件路径。

                        警告

                        在运行 Xray 之前,这个文件必须不存在。

                        abstract: true | false

                        是否为 abstract domain socket,默认值 false

                        padding: true | false

                        abstract domain socket 是否带 padding,默认值 false

                        - + diff --git a/config/transports/grpc.html b/config/transports/grpc.html index cec138112d..6041cb171c 100644 --- a/config/transports/grpc.html +++ b/config/transports/grpc.html @@ -24,8 +24,8 @@ gRPC | Project X - - + +

                        gRPC

                        基于 gRPC 的传输方式。

                        它基于 HTTP/2 协议,理论上可以通过其它支持 HTTP/2 的服务器(如 Nginx)进行中转。 gRPC(HTTP/2)内置多路复用,不建议使用 gRPC 与 HTTP/2 时启用 mux.cool。

                        ⚠⚠⚠

                        • gRPC 不支持指定 Host。请在出站代理地址中填写 正确的域名 ,或在 (x)tlsSettings 中填写 ServerName,否则无法连接。
                        • gRPC 不支持回落到其他服务。
                        • gRPC 服务存在被主动探测的风险。建议使用 Caddy 或 Nginx 等反向代理工具,通过 Path 前置分流。

                        提示

                        如果您使用 Caddy 或 Nginx 等反向代理,请注意下列事项:

                        • 请确定反向代理服务器开启了 HTTP/2
                        • 请使用 HTTP/2 或 h2c (Caddy),grpc_pass (Nginx) 连接到 Xray。
                        • 普通模式的 Path 为 /${serviceName}/Tun, Multi 模式为 /${serviceName}/TunMulti
                        • 如果需要接收客户端 IP,可以通过由 Caddy / Nginx 发送 X-Real-IP header 来传递客户端 IP。

                        提示

                        如果你正在使用回落,请注意下列事项:

                        • 不建议回落到 gRPC,存在被主动探测的风险。
                        • 请确认h2 位于 (x)tlsSettings.alpn 中的第一顺位,否则 gRPC(HTTP/2)可能无法完成 TLS 握手。
                        • gRPC 无法通过进行 Path 分流。

                        GRPCObject

                        GRPCObject 对应传输配置的 grpcSettings 项。

                        {
                        @@ -39,6 +39,6 @@
                           "initial_windows_size": 0
                         }
                         

                        authority: string

                        一个字符串,可以当 Host 来用,实现一些其它用途。

                        serviceName: string

                        一个字符串,指定服务名称,类似于 HTTP/2 中的 Path。 客户端会使用此名称进行通信,服务端会验证服务名称是否匹配。

                        提示

                        serviceName 起始为斜杠时可以自定义 path,至少要两个斜杠。
                        例如在服务端填写 "serviceName": "/my/sample/path1|path2",客户端可填写 "serviceName": "/my/sample/path1""/my/sample/path2"

                        user_agent: string

                        提示

                        只需出站客户端)配置。

                        设置 gRPC 的用户代理,可能能防止某些 CDN 阻止 gRPC 流量。

                        multiMode: true | false BETA

                        true 启用 multiMode,默认值为: false

                        这是一个 实验性 选项,可能不会被长期保留,也不保证跨版本兼容。此模式在 测试环境中 能够带来约 20% 的性能提升,实际效果因传输速率不同而不同。

                        提示

                        只需出站客户端)配置。

                        idle_timeout: number

                        单位秒,当这段时间内没有数据传输时,将会进行健康检查。如果此值设置为 10 以下,将会使用 10,即最小值。

                        提示

                        如果没有使用 Caddy 或 Nginx 等反向代理工具(通常不会),设为 60 以下,服务端可能发送意外的 h2 GOAWAY 帧以关闭现有连接。

                        健康检查默认不启用

                        提示

                        只需出站客户端)配置。

                        提示

                        可能会解决一些“断流”问题。

                        health_check_timeout: number

                        单位秒,健康检查的超时时间。如果在这段时间内没有完成健康检查,且仍然没有数据传输时,即认为健康检查失败。默认值为 20

                        提示

                        只需出站客户端)配置。

                        permit_without_stream: true | false

                        true 允许在没有子连接时进行健康检查。默认值为 false

                        提示

                        只需出站客户端)配置。

                        initial_windows_size: number

                        h2 Stream 初始窗口大小。当值小于等于 0 时,此功能不生效。当值大于 65535 时,动态窗口机制(Dynamic Window)会被禁用。默认值为 0,即不生效。

                        提示

                        只需出站客户端)配置。

                        提示

                        通过 Cloudflare CDN 时,可将值设为 65536 及以上,即禁用动态窗口机制(Dynamic Window),可防止 Cloudflare CDN 发送意外的 h2 GOAWAY 帧以关闭现有连接。

                        - + diff --git a/config/transports/h2.html b/config/transports/h2.html index 94676f3e5a..ec1a145025 100644 --- a/config/transports/h2.html +++ b/config/transports/h2.html @@ -24,8 +24,8 @@ HTTP/2 | Project X - - + +

                        HTTP/2

                        基于 HTTP/2 的传输方式。

                        它完整按照 HTTP/2 标准实现,可以通过其它的 HTTP 服务器(如 Nginx)进行中转。

                        由 HTTP/2 的建议,客户端和服务器必须同时开启 TLS 才可以正常使用这个传输方式。

                        HTTP/2 内置多路复用,不建议使用 HTTP/2 时启用 mux.cool。

                        提示

                        当前版本的 HTTP/2 的传输方式并不强制要求入站服务端)有 TLS 配置. 这使得可以在特殊用途的分流部署环境中,由外部网关组件完成 TLS 层对话,Xray 作为后端应用,网关和 Xray 间使用称为 h2c 的明文 http/2 进行通讯。

                        注意

                        ⚠️ 如果你正在使用回落,请注意下列事项:

                        • 请确认 (x)tlsSettings.alpn 中包含 h2,否则 HTTP/2 无法完成 TLS 握手。
                        • HTTP/2 无法通过 Path 进行分流,建议使用 SNI 分流。

                        HttpObject

                        HttpObject 对应传输配置的 httpSettings 项。

                        {
                        @@ -39,6 +39,6 @@
                           }
                         }
                         

                        host: [string]

                        一个字符串数组,每一个元素是一个域名。

                        客户端会随机从列表中选出一个域名进行通信,服务器会验证域名是否在列表中。

                        提示

                        若不写 "httpSettings""host": [] 值留空时,会使用默认值 "www.example.com",需要两端 "host" 值一致才能连接成功。"host": [""] 不是值留空。

                        path: string

                        HTTP 路径,由 / 开头, 客户端和服务器必须一致。

                        默认值为 "/"

                        read_idle_timeout: number

                        单位秒,当这段时间内没有接收到数据时,将会进行健康检查。

                        健康检查默认不启用

                        提示

                        只需出站客户端)配置。

                        提示

                        可能会解决一些“断流”问题。

                        health_check_timeout: number

                        单位秒,健康检查的超时时间。如果在这段时间内没有完成健康检查,即认为健康检查失败。默认值为 15

                        提示

                        只需出站客户端)配置。

                        method: string

                        HTTP 方法。默认值为 "PUT"

                        设置时应参照此处open in new tag列出值。

                        headers: map{ string: [string] }

                        自定义 HTTP 头,一个键值对,每个键表示一个 HTTP 头名称,对应值为一个数组。

                        - + diff --git a/config/transports/httpupgrade.html b/config/transports/httpupgrade.html index a20575f479..c574f5df31 100644 --- a/config/transports/httpupgrade.html +++ b/config/transports/httpupgrade.html @@ -24,8 +24,8 @@ HTTPUpgrade | Project X - - + +

                        HTTPUpgrade

                        一个实现了类似于 WebSocket 进行 HTTP 1.1 升级请求和响应的协议,这使得它可以像 WebSocket 一样可以被CDN或者Nginx进行反代,但无需实现 WebSocket 协议的其他部分,所以具有更高的效率。 其设计不推荐单独使用,而是和TLS等安全协议一起工作。

                        HttpUpgradeObject

                        HttpUpgradeObject 对应传输配置的 httpupgradeSettings 项。

                        {
                        @@ -37,6 +37,6 @@
                           }
                         }
                         

                        acceptProxyProtocol: true | false

                        仅用于 inbound,指示是否接收 PROXY protocol。

                        PROXY protocolopen in new tag 专用于传递请求的真实来源 IP 和端口,若你不了解它,请先忽略该项

                        常见的反代软件(如 HAProxy、Nginx)都可以配置发送它,VLESS fallbacks xver 也可以发送它。

                        填写 true 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2,否则连接会被关闭。

                        path: string

                        HTTPUpgrade 所使用的 HTTP 协议路径,默认值为 "/"

                        如果客户端路径中包含 ed 参数(如 /mypath?ed=2560),将会启用 Early Data 以降低延迟,其值为首包长度阈值。如果首包长度超过此值,就不会启用 Early Data。建议的值为2560。

                        host: string

                        HTTPUpgrade 的HTTP请求中所发送的host,默认值为空。若服务端值为空时,不验证客户端发送来的host值。

                        当在服务端指定该值,或在 headers 中指定host,将会校验与客户端请求host是否一致。

                        客户端选择发送的host优先级 host > headers > address

                        headers: map {string: string}

                        自定义 HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是字符串。

                        默认值为空。

                        - + diff --git a/config/transports/mkcp.html b/config/transports/mkcp.html index 1b909e320c..786d53d332 100644 --- a/config/transports/mkcp.html +++ b/config/transports/mkcp.html @@ -24,8 +24,8 @@ mKCP | Project X - - + +

                        mKCP

                        mKCP 使用 UDP 来模拟 TCP 连接。

                        mKCP 牺牲带宽来降低延迟。传输同样的内容,mKCP 一般比 TCP 消耗更多的流量。

                        提示

                        请确定主机上的防火墙配置正确

                        KcpObject

                        KcpObject 对应传输配置的 kcpSettings 项。

                        {
                        @@ -47,6 +47,6 @@
                           "domain": "example.com"
                         }
                         

                        type: string

                        伪装类型,可选的值有:

                        • "none":默认值,不进行伪装,发送的数据是没有特征的数据包。
                        • "srtp":伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。
                        • "utp":伪装成 uTP 数据包,会被识别为 BT 下载数据。
                        • "wechat-video":伪装成微信视频通话的数据包。
                        • "dtls":伪装成 DTLS 1.2 数据包。
                        • "wireguard":伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)
                        • "dns":某些校园网在未登录的情况下允许DNS查询,给KCP添加DNS头,把流量伪装成dns请求,可以绕过某些校园网登录。

                        domain: string

                        配合伪装类型 "dns" 使用,可随便填一个域名。

                        鸣谢

                        对 KCP 协议的改进

                        更小的协议头

                        原生 KCP 协议使用了 24 字节的固定头部,而 mKCP 修改为数据包 18 字节,确认(ACK)包 16 字节。更小的头部有助于躲避特征检查,并加快传输速度。

                        另外,原生 KCP 的单个确认包只能确认一个数据包已收到,也就是说当 KCP 需要确认 100 个数据已收到时,它会发出 24 * 100 = 2400 字节的数据。其中包含了大量重复的头部数据,造成带宽的浪费。mKCP 会对多个确认包进行压缩,100 个确认包只需要 16 + 2 + 100 * 4 = 418 字节,相当于原生的六分之一。

                        确认包重传

                        原生 KCP 协议的确认(ACK)包只发送一次,如果确认包丢失,则一定会导致数据重传,造成不必要的带宽浪费。而 mKCP 会以一定的频率重发确认包,直到发送方确认为止。单个确认包的大小为 22 字节,相比起数据包的 1000 字节以上,重传确认包的代价要小得多。

                        连接状态控制

                        mKCP 可以有效地开启和关闭连接。当远程主机主动关闭连接时,连接会在两秒钟之内释放;当远程主机断线时,连接会在最多 30 秒内释放。

                        原生 KCP 不支持这个场景。

                        - + diff --git a/config/transports/quic.html b/config/transports/quic.html index 8d4a67aa88..324f1eeb2e 100644 --- a/config/transports/quic.html +++ b/config/transports/quic.html @@ -24,8 +24,8 @@ QUIC | Project X - - + +

                        QUIC

                        QUIC 全称 Quick UDP Internet Connection,是由 Google 提出的使用 UDP 进行多路并发传输的协议。其主要优势是:

                        1. 减少了握手的延迟(1-RTT 或 0-RTT)
                        2. 多路复用,并且没有 TCP 的阻塞问题
                        3. 连接迁移,(主要是在客户端)当由 Wifi 转移到 4G 时,连接不会被断开。

                        QUIC 目前处于实验期,使用了正在标准化过程中的 IETF 实现,不能保证与最终版本的兼容性。

                        • 默认设定:
                          • 12 字节的 Connection ID
                          • 30 秒没有数据通过时自动断开连接 (可能会影响一些长连接的使用)

                        QuicObject

                        QuicObject 对应传输配置的 quicSettings 项。

                        警告

                        对接的两端的配置必须完全一致,否则连接失败。 QUIC 强制要求开启 TLS,在传输配置中没有开启 TLS 时,Xray 会自行签发一个证书进行 TLS 通讯。

                        {
                        @@ -39,6 +39,6 @@
                           "type": "none"
                         }
                         

                        type: string

                        伪装类型,可选的值有:

                        • "none":默认值,不进行伪装,发送的数据是没有特征的数据包。
                        • "srtp":伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。
                        • "utp":伪装成 uTP 数据包,会被识别为 BT 下载数据。
                        • "wechat-video":伪装成微信视频通话的数据包。
                        • "dtls":伪装成 DTLS 1.2 数据包。
                        • "wireguard":伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)

                        提示

                        当加密和伪装都不启用时,数据包即为原始的 QUIC 数据包,可以与其它的 QUIC 工具对接。 为了避免被探测,建议加密或伪装至少开启一项。

                        - + diff --git a/config/transports/tcp.html b/config/transports/tcp.html index 2cbebbfba0..5f868ff299 100644 --- a/config/transports/tcp.html +++ b/config/transports/tcp.html @@ -24,8 +24,8 @@ TCP | Project X - - + +

                        TCP

                        TCP 传输模式是目前推荐使用的传输模式之一.

                        可以和各种协议有多种组合模式.

                        TcpObject

                        TcpObject 对应传输配置的 tcpSettings 项。

                        {
                        @@ -69,6 +69,6 @@
                           }
                         }
                         

                        version: string

                        HTTP 版本,默认值为 "1.1"

                        status: string

                        HTTP 状态,默认值为 "200"

                        reason: string

                        HTTP 状态说明,默认值为 "OK"

                        headers: map {string, [ string ]}

                        HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是一个数组。

                        每次请求会附上所有的键,并随机选择一个对应的值。默认值见上方示例。

                        - + diff --git a/config/transports/websocket.html b/config/transports/websocket.html index 3a9f808c66..184f47b8e8 100644 --- a/config/transports/websocket.html +++ b/config/transports/websocket.html @@ -24,8 +24,8 @@ WebSocket | Project X - - + +

                        WebSocket

                        使用标准的 WebSocket 来传输数据。

                        WebSocket 连接可以被其它 HTTP 服务器(如 Nginx)分流,也可以被 VLESS fallbacks path 分流。

                        提示

                        Websocket 会识别 HTTP 请求的 X-Forwarded-For 头来覆写流量的源地址,优先级高于 PROXY protocol。

                        WebSocketObject

                        WebSocketObject 对应传输配置的 wsSettings 项。

                        {
                        @@ -37,6 +37,6 @@
                           }
                         }
                         

                        acceptProxyProtocol: true | false

                        仅用于 inbound,指示是否接收 PROXY protocol。

                        PROXY protocolopen in new tag 专用于传递请求的真实来源 IP 和端口,若你不了解它,请先忽略该项

                        常见的反代软件(如 HAProxy、Nginx)都可以配置发送它,VLESS fallbacks xver 也可以发送它。

                        填写 true 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2,否则连接会被关闭。

                        path: string

                        WebSocket 所使用的 HTTP 协议路径,默认值为 "/"

                        如果客户端路径中包含 ed 参数(如 /mypath?ed=2560),将会启用 Early Data 以降低延迟,在升级的同时使用 Sec-WebSocket-Protocol 头承载首包数据,其值为首包长度阈值。如果首包长度超过此值,就不会启用 Early Data。推荐值为 2560,最大值为8192,过大的值可能导致部分兼容问题,如果遇到兼容性问题,可以尝试调低阈值。

                        host: string

                        WebSocket 的HTTP请求中所发送的host,默认值为空。若服务端值为空时,不验证客户端发送来的host值。

                        当在服务端指定该值,或在 headers 中指定host,将会校验与客户端请求host是否一致。

                        客户端选择发送的host优先级 host > headers > address

                        headers: map {string: string}

                        自定义 HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是字符串。

                        默认值为空。

                        Browser Dialer

                        使用浏览器处理 TLS,详见 Browser Dialer

                        - + diff --git a/development/index.html b/development/index.html index e759bf9e6f..9004d5fc6a 100644 --- a/development/index.html +++ b/development/index.html @@ -24,11 +24,11 @@ 开发指南 | Project X - - + +

                        开发指南

                        编译文档

                        Xray 支持各种平台, 您可以在多种平台上自行进行交叉编译。

                        请点击编译文档以查看具体编译相关内容。

                        设计思路

                        Xray 内核提供了一个平台,在其之上可以进二次开发。

                        这个章节阐述了 Xray 的设计目标和架构。

                        请点击设计思路以了解 Xray 的设计目标和架构。

                        开发规范

                        这个章节阐述了获取代码,进行开发,提交 PR 的流程中需要遵循的准则, 以及相关的编码规范。

                        请点击开发规范查看 Xray 开发中应遵循的准则。

                        协议详解

                        Xray 用到了很多种协议, 您可以通过各种途径获得协议的详细描述。

                        VLESS 协议

                        VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

                        VMess 协议

                        VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

                        Mux.Cool 协议

                        Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。

                        mKCP 协议

                        mKCP 是流式传输协议,由 KCP 协议open in new tag修改而来,可以按顺序传输任意的数据流。

                        - + diff --git a/development/intro/compile.html b/development/intro/compile.html index e93849a333..acf535c4a9 100644 --- a/development/intro/compile.html +++ b/development/intro/compile.html @@ -24,8 +24,8 @@ 编译文档 | Project X - - + +

                        编译文档

                        前序工作

                        Xray 使用 Golangopen in new tag 作为编程语言,你需要先安装最新版本 Golang 才能够编译。

                        如果你不幸使用 Windows, 请 务必 使用 Powershell

                        拉取 Xray 源代码

                        git clone https://github.com/XTLS/Xray-core.git
                        @@ -40,6 +40,6 @@
                         
                         go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
                         

                        上传到服务器后,记得在服务器终端内执行 chmod +x xray

                        提示

                        执行 go tool dist list 查看所有支持的系统与架构。

                        可复现构建:

                        按照上述步骤,能够编译与 Release 中完全相同的二进制文件。

                        注意

                        请先确认您使用的 Golang 版本与编译 Release 的一致。

                        - + diff --git a/development/intro/design.html b/development/intro/design.html index e746762bfc..af7fd98749 100644 --- a/development/intro/design.html +++ b/development/intro/design.html @@ -24,11 +24,11 @@ 设计目标 | Project X - - + +

                        设计目标

                        • Xray 内核提供了一个平台,支持必要的网络代理功能,在其之上可以进二次开发,以提供更好的用户体验;
                        • 以跨平台为首要原则,以减少二次开发的成本;

                        架构

                        Architecture

                        内核分为三层:应用层、代理层和传输层。

                        每一层内包含数个模块,模块间互相独立,同类型的模块可无缝替换。

                        应用层

                        应用层包含一些代理层中常用的功能,这些功能被抽象出来,以便在不同的代理模块中复用。

                        应用层的模块应为纯软件实现,与硬件或平台相关的技术无关。

                        重要模块列表:

                        • Dispatcher: 用于把入站代理所接收到的数据,传送给出站代理;
                        • Router: 路由模块,详见 路由配置
                        • DNS: 内置的 DNS 服务器模块;
                        • Proxy Manager: 代理管理器;

                        代理层

                        代理层分为两部分:入站代理(Inbound Proxy)和出站代理(Outbound Proxy)。

                        两部分相互独立,入站代理不依赖于某个特定的出站代理,反之亦然。

                        入站代理

                        出站代理

                        传输层

                        传输层提供一些网络数据传输相关的工具模块。

                        - + diff --git a/development/intro/guide.html b/development/intro/guide.html index 0e533a22c7..6aad77fa3c 100644 --- a/development/intro/guide.html +++ b/development/intro/guide.html @@ -24,8 +24,8 @@ 开发规范 | Project X - - + +

                        开发规范

                        基本

                        版本控制

                        Project X 的代码被托管在 github 上:

                        您可以使用 Gitopen in new tag 来获取代码。

                        分支(Branch)

                        • 本项目的主干分支为 main,
                        • 本项目的发布主分支同为 main,
                        • 需要确保 main 在任一时刻都是可编译,且可正常使用的。
                        • 如果需要开发新的功能,请新建分支进行开发,在开发完成并且经过充分测试后,合并回主干分支。
                        • 已经合并入主干且没有必要存在的分支,请删除。

                        发布(Release)

                        WIP
                        • 建立尝鲜版本和稳定版本两个发布通道
                          • 尝鲜版本,可以为 daily build,主要用于特定情况的测试,尝鲜和获得即时反馈和再改进。
                          • 稳定版本,为定时更新(比如月更),合并稳定的修改并发布。

                        引用其它项目

                        • Golang
                          • 产品代码建议使用 Golang 标准库和 golang.org/x/open in new tag 下的库;
                          • 如需引用其它项目,请事先创建 issue 讨论;
                        • 其它
                          • 不违反双方的协议,且对项目有帮助的工具,都可以使用。

                        开发流程

                        写代码之前

                        发现任何问题,或对项目有任何想法,请创建 issueopen in new tag 讨论以减少重复劳动和消耗在代码上的时间。

                        修改代码

                        • Golang
                          • 请参考 Effective Goopen in new tag
                          • 每一次 push 之前,请运行:go generate core/format.go
                          • 如果需要修改 protobuf,例如增加新配置项,请运行:go generate core/proto.go
                          • 提交 pull request 之前,建议测试通过:go test ./...
                          • 提交 pull request 之前,建议新增代码有超过 70% 的代码覆盖率(code coverage);
                        • 其它
                          • 请注意代码的可读性。

                        Pull Request

                        • 提交 PR 之前,请先运行 git pull https://github.com/XTLS/Xray-core.git 以确保 merge 可顺利进行;
                        • 一个 PR 只做一件事,如有对多个 bug 的修复,请对每一个 bug 提交一个 PR;
                        • 由于 Golang 的特殊需求(Package path),Go 项目的 PR 流程和其它项目有所不同,建议流程如下:
                          1. 先 Fork 本项目,创建你自己的 github.com/<your_name>/Xray-core.git 仓库;
                          2. 克隆你自己的 Xray 仓库到本地:git clone https://github.com/<your_name>/Xray-core.git
                          3. 基于 main 分支创建新的分支,例如 git branch issue24 main
                          4. 在新创建的分支上作修改并提交修改(commit);
                          5. 在推送(push)修改完成的分支到自己的仓库前,先切换到 main 分支,运行 git pull https://github.com/XTLS/Xray-core.git 拉取最新的远端代码;
                          6. 如果上一步拉取得到了新的远端代码,则切换到之前自己创建的分支,运行 git rebase main 执行分支合并操作。如遇到文件冲突,则需要解决冲突;
                          7. 上一步处理完毕后,就可以把自己创建的分支推送到自己的仓库:git push -u origin your-branch
                          8. 最后,把自己仓库的新推送的分支往 XTLS/Xray-coremain 分支发 PR 即可;
                          9. 请在 PR 的标题和正文中,完整表述此次 PR 解决的问题 / 新增的功能 / 代码所做的修改的用意等;
                          10. 耐心等待开发者的回应。

                        对代码的修改

                        功能性问题

                        请提交至少一个测试用例(Test Case)来验证对现有功能的改动。

                        性能相关

                        请提交必要的测试数据来证明现有代码的性能缺陷,或是新增代码的性能提升。

                        新功能

                        • 如果新增功能对已有功能不影响,请提供可以开启/关闭的开关(如 flag),并使新功能保持默认关闭的状态;
                        • 大型新功能(比如增加一个新的协议)开发之前,请先提交一个 issue,讨论完毕之后再进行开发。

                        其它

                        视具体情况而定。

                        Xray 编码规范

                        以下内容适用于 Xray 中的 Golang 代码。

                        代码结构

                        Xray-core
                        @@ -40,6 +40,6 @@
                         │   ├── vmess
                         ├── transport  // 传输模块
                         

                        编码规范

                        基本与 Golang 官方所推荐做法一致,有一些例外。写在这里以方便大家熟悉 Golang。

                        命名

                        • 文件和目录名尽量使用单个英文单词,比如 hello.go;
                          • 如果实在没办法,则目录使用连接线/文件名使用下划线连接两个(或多个单词),比如 hello-world/hello_again.go;
                          • 测试代码使用 _test.go 结尾;
                        • 类型使用 Pascal 命名法,比如 ConnectionHandler;
                          • 对缩写不强制小写,即 HTML 不必写成 Html;
                        • 公开成员变量也使用 Pascal 命名法;
                        • 私有成员变量使用 小驼峰式命名法open in new tag ,如 privateAttribute
                        • 为了方便重构,方法建议全部使用 Pascal 命名法;
                          • 完全私有的类型放入 internal

                        内容组织

                        • 一个文件包含一个主要类型,及其相关的私有函数等;
                        • 测试相关的文件,如 Mock 等工具类,放入 testing 子目录。
                        - + diff --git a/development/protocols/mkcp.html b/development/protocols/mkcp.html index 1aed9b3612..61bad57464 100644 --- a/development/protocols/mkcp.html +++ b/development/protocols/mkcp.html @@ -24,11 +24,11 @@ mKCP 协议 | Project X - - + +

                        mKCP 协议

                        mKCP 是流式传输协议,由 KCP 协议open in new tag 修改而来,可以按顺序传输任意的数据流。

                        版本

                        mKCP 没有版本号,不保证版本之间兼容性。

                        依赖

                        底层协议

                        mKCP 是一个基于 UDP 的协议,所有通讯使用 UDP 传输。

                        函数

                        • fnv: FNV-1aopen in new tag 哈希函数
                          • 输入参数为任意长度的字符串;
                          • 输入出一个 32 位无符号整数;

                        通讯过程

                        1. mKCP 将数据流拆成若干个数据包进行发送。一个数据流有一个唯一标识,用以区分不同的数据流。数据流中的每一个数据包都携带了同样的标识。
                        2. mKCP 没有握手过程,当收到一个数据包时,根据其携带的数据流的标识来判断是否为新的通话,或是正在进行中的通话。
                        3. 每一个数据包中包含若干个片段(Segment),片段分为三类:数据(Data)、确认(ACK)、心跳(Ping)。每个片段需要单独处理。

                        数据格式

                        数据包

                        4 字节2 字节L 字节
                        认证信息 A数据长度 L片段部分

                        其中:

                        • 认证信息 A = fnv(片段部分),big endian;
                        • 片段部分可能包含多个片段;

                        数据片段

                        2 字节1 字节1 字节4 字节4 字节4 字节2 字节Len 字节
                        标识 Conv指令 Cmd选项 Opt时间戳 Ts序列号 Sn未确认序列号 Una长度 Len数据

                        其中:

                        • 标识 Conv: mKCP 数据流的标识
                        • 指令 Cmd: 常量 0x01
                        • 选项 Opt: 可选的值有:
                          • 0x00: 空选项
                          • 0x01: 对方已发出所有数据
                        • 时间戳 Ts: 当前片段从远端发送出来时的时间,big endian
                        • 序列号 Sn: 该数据片段时数据流中的位置,起始片段的序列号为 0,之后每个新片段按顺序加 1
                        • 未确认序列号 Una: 远端主机正在发送的,且尚未收到确认的最小的 Sn

                        确认片段

                        2 字节1 字节1 字节4 字节4 字节4 字节2 字节Len * 4 字节
                        标识 Conv指令 Cmd选项 Opt窗口 Wnd下一接收序列号 Sn时间戳 Ts长度 Len已收到的序列号

                        其中:

                        • 标识 Conv: mKCP 数据流的标识
                        • 指令 Cmd: 常量 0x00
                        • 选项 Opt: 同上
                        • 窗口 Wnd: 远端主机可以接收的最大序列号
                        • 下一接收序列号 Sn: 远端主机未收到的数据片段中的最小序列号
                        • 时间戳 Ts: 远端主机最新收到的数据片段的时间戳,可用于计算延迟
                        • 已收到的序列号: 每个 4 字节,表示此序列号的数据已经确认收到

                        注释:

                        • 远程主机期待收到序列号 [Sn, Wnd) 范围内的数据

                        心跳片段

                        2 字节1 字节1 字节4 字节4 字节4 字节
                        标识 Conv指令 Cmd选项 Opt未确认序列号 Una下一接收序列号 Sn延迟 Rto

                        其中:

                        • 标识 Conv: mKCP 数据流的标识
                        • 指令 Cmd: 可选的值有
                          • 0x02: 远端主机强行终止会话
                          • 0x03: 正常心跳
                        • 选项 Opt: 同上
                        • 未确认序列号 Una: 同数据片段的 Una
                        • 下一接收序列号 Sn: 同确认片段的 Sn
                        • 延迟 Rto: 远端主机自己计算出的延迟
                        - + diff --git a/development/protocols/muxcool.html b/development/protocols/muxcool.html index 50d4f3dca3..9988ee4a9c 100644 --- a/development/protocols/muxcool.html +++ b/development/protocols/muxcool.html @@ -24,11 +24,11 @@ Mux.Cool 协议 | Project X - - + +

                        Mux.Cool 协议

                        Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。

                        版本

                        当前版本是 1 Beta。

                        依赖

                        底层协议

                        Mux.Cool 必须运行在一个已建立的可靠数据流之上。

                        通讯过程

                        一个 Mux.Cool 连接中可传输若干个子连接,每个子连接有一个独立的 ID 和状态。传输过程由帧(Frame)组成,每一帧用于传输一个特定的子连接的数据。

                        客户端行为

                        当有连接需求时并且没有现有可用的连接时,客户端向服务器发起一个新连接,以下称为“主连接”。

                        1. 一个主连接可用于发送若干个子连接。客户端可自主决定主连接可承载的子连接数量。
                        2. 对于一个新的子连接,客户端必须发送状态New以通知服务器建立子连接,然后使用状态Keep来传送数据。
                        3. 当子连接结束时,客户端发送End状态来通知服务器关闭子连接。
                        4. 客户端可自行决定何时关闭主连接,但必须确定服务器也同时保持连接。
                        5. 客户端可使用 KeepAlive 状态来避免服务器关闭主连接。

                        服务器端行为

                        当服务器端接收到新的子连接时,服务器应当按正常的连接来处理。

                        1. 当收到状态End时,服务器端可以关闭对目标地址的上行连接。
                        2. 在服务器的响应中,必须使用与请求相同的 ID 来传输子连接的数据。
                        3. 服务器不能使用New状态。
                        4. 服务器可使用 KeepAlive 状态来避免客户端关闭主连接。

                        传输格式

                        Mux.Cool 使用对称传输格式,即客户端和服务器发送和接收相同格式的数据。

                        帧格式

                        2 字节L 字节X 字节
                        元数据长度 L元数据额外数据

                        元数据

                        元数据有若干种类型。所有类型的元数据都包含 ID 和 Opt 两项,其含义为:

                        • ID: 子连接的唯一标识
                        • Opt:
                          • D(0x01): 有额外数据

                        当选项 Opt(D) 开启时,额外数据格式如下:

                        2 字节X-2 字节
                        长度 X-2数据

                        新建子连接 (New)

                        2 字节1 字节1 字节1 字节2 字节1 字节A 字节8 字节
                        ID0x01选项 Opt网络类型 N端口地址类型 T地址 AGlobal ID (XUDP)

                        其中:

                        • 网络类型 N:
                          • 0x01:TCP,表示当前子连接的流量应当以 TCP 的方式发送至目标。
                          • 0x02:UDP,表示当前子连接的流量应当以 UDP 的方式发送至目标。
                        • 地址类型 T:
                          • 0x01:IPv4
                          • 0x02:域名
                          • 0x03:IPv6
                        • 地址 A:
                          • 当 T = 0x01 时,A 为 4 字节 IPv4 地址;
                          • 当 T = 0x02 时,A 为 1 字节长度(L) + L 字节域名;
                          • 当 T = 0x03 时,A 为 16 字节 IPv6 地址;
                        • Global ID (XUDP):
                          • 客户端计算出 UDP 来源二元组的全局独特 ID,服务端用以确保当 XUDP 断线重连时,仍使用同一个端口与目标通信。

                        在新建子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。

                        保持子连接 (Keep)

                        TCP

                        2 字节1 字节1 字节
                        ID0x02选项 Opt

                        UDP

                        2 字节1 字节1 字节1 字节2 字节1 字节A 字节
                        ID0x02选项 Opt网络类型 N端口地址类型 T地址 A

                        在保持子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。 XUDP 在 Opt(D) 之后加 UDP 地址,格式同新建子连接,但没有 Global ID。

                        关闭子连接 (End)

                        2 字节1 字节1 字节
                        ID0x03选项 Opt

                        在保持子连接时,若 Opt(D) 开启,则这一帧所带的数据需要被发往目标主机。

                        保持连接 (KeepAlive)

                        2 字节1 字节1 字节
                        ID0x04选项 Opt

                        在保持连接时:

                        • 若 Opt(D) 开启,则这一帧所带的数据必须被丢弃。
                        • ID 可为随机值。

                        应用

                        Mux.Cool 协议与底层协议无关,理论上可以使用任何可靠的流式连接来传输 Mux.Cool 的协议数据。

                        在目标导向的协议如 Shadowsocks 和 VMess 协议中,连接建立时必须包含一个指定的地址。 为了保持兼容性,Mux.Cool 协议指定地址为“v1.mux.cool”。即当主连接的目标地址与之匹配时,则进行 Mux.Cool 方式的转发,否则按传统方式进行转发。(注:这是一个程序内的标记,VMess 和 VLESS 并不会在数据包中发送“v1.mux.cool”地址)

                        - + diff --git a/development/protocols/vless.html b/development/protocols/vless.html index b3fef931c9..d0cc642692 100644 --- a/development/protocols/vless.html +++ b/development/protocols/vless.html @@ -24,11 +24,11 @@ VLESS 协议 | Project X - - + +

                        VLESS 协议

                        VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

                        Request & Response

                        1 字节16 字节1 字节M 字节1 字节2 字节1 字节S 字节X 字节
                        协议版本等价 UUID附加信息长度 M附加信息 ProtoBuf指令端口地址类型地址请求数据
                        1 字节1 字节N 字节Y 字节
                        协议版本,与请求的一致附加信息长度 N附加信息 ProtoBuf响应数据

                        VLESS 早在第二个测试版 ALPHA 2 时就已经是上述结构了(BETA 是第五个测试版):

                        “响应认证”被替换为“协议版本”并移至最前,使 VLESS 可以升级换代,同时消除了生成伪随机数的开销。混淆相关结构被替换为附加信息(ProtoBuf)并前移,赋予协议本身可扩展性,相关开销也极小(gogo/protobufopen in new tag),若无附加信息则无相关开销。

                        我一直觉得“响应认证”不是必要的,ALPHA 时为了提升生成随机数的性能,还用 math/rand 替换 crypto/rand,而现在都不需要了。

                        “协议版本”不仅能起到“响应认证”的作用,还赋予了 VLESS 无痛升级协议结构的能力,带来无限的可能性。 “协议版本”在测试版本中均为 0,正式版本中为 1,以后若有不兼容的协议结构变更则应升级版本。

                        VLESS 服务端的设计是 switch version,即同时支持所有 VLESS 版本。若需要升级协议版本(可能到不了这一步),推荐的做法是服务端提前一个月支持,一个月后再改客户端。VMess 请求也有协议版本,但它的认证信息在外面,指令部分则高度耦合且有固定加密,导致里面的协议版本毫无意义,服务端也没有进行判断,响应则没有协议版本。Trojan 的协议结构中没有协议版本。

                        接下来是 UUID,我本来觉得 16 字节有点长,曾经考虑过缩短它,但后来看到 Trojan 用了 56 个可打印字符(56 字节),就彻底打消了这个念头。服务端每次都要验证 UUID,所以性能也很重要:VLESS 的 Validator 经历了多次重构/升级,相较于 VMess,它十分简洁且耗资源很少,可以同时支持非常多的用户,性能也十分强悍,验证速度极快(sync.Map)。API 动态增删用户则更高效顺滑。 https://github.com/XTLS/Xray-core/issues/158

                        引入 ProtoBuf 是一个创举,等下会详细讲解。“指令”到“地址”的结构目前与 VMess 完全相同,同样支持 Mux。

                        总体上,ALPHA 2 到 BETA 主要是:结构进化、清理整合、性能提升、更加完善。这些都是一点一滴的,详见 VLESS Changesopen in new tag

                        ProtoBuf

                        似乎只有 VLESS 可选内嵌 ProtoBuf,它是一种数据交换格式,信息被紧密编码成二进制,TLV 结构(Tag Length Value)。

                        起因是我看到一篇文章称 SS 有一些缺点,如没有设计错误回报机制,客户端没办法根据不同的错误采取进一步的动作。 (但我并不认同所有错误都要回报,不然防不了主动探测。下一个测试版中,服务器可以返回一串自定义信息。) 于是想到一个可扩展的结构是很重要的,未来它也可以承载如动态端口指令。不止响应,请求也需要类似的结构。 本来打算自己设计 TLV,接着发觉 ProtoBuf 就是此结构、现成的轮子,完全适合用来做这件事,各语言支持等也不错。

                        目前“附加信息”只有 Scheduler 和 SchedulerV,它们是 MessName 和 MessSeed 的替代者,当你不需要它们时,“附加信息长度”为 0,也就不会有 ProtoBuf 序列化/反序列化的开销。其实我更愿意称这个过程为“拼接”,因为 pb 实际原理上也只是这么做而已,相关开销极小。拼接后的 bytes 十分紧凑,和 ALPHA 的方案相差无几,有兴趣的可以分别输出并对比。

                        为了指示对附加信息(Addons,也可以理解成插件,以后可以有很多个插件)的不同支持程度,下个测试版会在“附加信息长度”前新增“附加信息版本”。256 - 1 = 255 字节是够用且合理的(65535 就太多了,还可能有人恶意填充),现有的只用了十分之一,以后也不会同时有那么多附加信息,且大多数情况下是完全没有附加信息的。真不够用的话,可以升级 VLESS 版本。

                        为了减少逻辑判断等开销,暂定 Addons 不使用多级结构。一个月前出现过“可变协议格式”的想法,pb 是可以做到打乱顺序,但没必要,因为现代加密的设计不会让旁观者看出两次传输的头部相同。

                        下面介绍 Schedulers 和 Encryption 的构想,它们都是可选的,一个应对流量时序特征问题,一个应对密码学上的问题。

                        Schedulers Flow

                        中文名暂称:流量调度器(2020-09-03 更新:中文名确定为“流控”),指令由 ProtoBuf 承载,控制的是数据部分。

                        我之前发现,VMess 原有的 shake “元数据混淆”在 TLS 上完全不会带来有意义的改变,只会降低性能,所以 VLESS 弃用了它。并且,“混淆”这个表述容易被误解成伪装,也弃用了。顺便一提,我一直是不看好伪装的:做不到完全一样,那不就是强特征吗?做得到完全一样,那为什么不直接用伪装目标?我一开始用的是 SSR,后来发现它只是表面伪装骗运营商,就再也没用过了。

                        那么,“流量调度器”要解决什么问题?它影响的是宏观流量时序特征,而不是微观特征,后者是加密要解决的事情。流量时序特征可以是协议带来的,比如 Socks5 over TLS 时的 Socks5 握手 ,TLS 上不同的这种特征对于监测者来说就是不同的协议,此时无限 Schedulers 就相当于无限协议(重新分配每次发送的数据量大小等)。流量时序特征也可以是行为带来的,比如访问 Google 首页时加载了多少文件、顺序、每个文件的大小,多套一层加密并不能有效掩盖这些信息。

                        Schedulers 没必要像下面的 Encryption 一样整个套在外面,因为头部的一丁点数据相对于后面的数据量来说太微不足道了。

                        BETA 2 预计推出两个初级的 Scheduler:Zstd 压缩、数据量动态扩充。进阶操作才是从宏观层面来控制、分配,暂时咕咕。

                        Encryption

                        与 VMess 的高度耦合不同,VLESS 的服务端、客户端不久后可以提前约定好加密方式,仅在外面套一层加密。这有点类似于使用 TLS,不影响承载的任何数据,也可以理解成底层就是从 TLS 换成预设约定加密。相对于高度耦合,这种方式更合理且灵活:一种加密方式出了安全性问题,直接扔掉并换用其它的就行了,十分方便。VLESS 服务端还会允许不同的加密方式共存。

                        对比 VMess,VLESS 相当于把 security 换成 encryption,把 disableInsecureEncryption 换成 decryption,就解决了所有问题。目前 encryption 和 decryption 只接受 "none" 且不能留空(即使以后有连接安全性检查),详见 VLESS 配置文档open in new tag。encryption 并不需要往外移一级,一是因为无法复用很多代码,二是因为会影响控制粒度,看未来的应用就明白了。

                        加密支持两类形式,一类是加密完全独立,需要额外密码,适合私用,另一类是结合已有的 UUID 来加密,适合公用。 (若用第一类加密形式,且密码是以某种形式公开的,比如多人共用,那么中间人攻击就不远了) 重新设计的动态端口可能会随加密同时推出,指令由 ProtoBuf 承载,具体实现和 VMess 的动态端口也会有很多不同。

                        套现成加密是件很简单的事情,也就多一层 writer & reader。BETA 3 预计支持 SS 的 aes-128-gcm 和 chacha20-ietf-poly1305: 客户端的 encryption 可以填 “auto: ss_aes-128-gcm_0_123456, ss_chacha20-ietf-poly1305_0_987654”,auto 会选择最适合当前机器的,0 代表测试版,最后的是密码。服务端的 decryption 也是类似填法,收到请求时会逐一尝试解密。

                        并不是所有组合都需逐一尝试:VMess 的加密分为三段,第一段是认证信息,结合了 UUID、alterId、时间因素,第二段是指令部分,以固定算法加密,指令中含有数据部分使用的加密算法,第三段才是重要的数据部分。可以看出,VMess 的加解密方式实际上是多对一(服务端适配),而不仅是结合 UUID。但仅是结合 UUID 来加密也是件相对麻烦的事情,短时间内不会出,鉴于我们现在有 VMessAEAD 可用,也并不着急。若 VLESS 推出了结合 UUID 的加密方式,相当于重构了整个 VMess。

                        UDP issues

                        XUDP:VLESS & VMess & Mux UDP FullCone NATopen in new tag

                        客户端开发指引

                        1. VLESS 协议本身还会有不兼容升级,但客户端配置文件参数基本上是只增不减的。iOS 客户端的协议实现则需紧跟升级。
                        2. 视觉标准:UI 标识请统一用 VLESS,而不是 VLess / Vless / vless,配置文件不受影响,代码内则顺其自然。
                        3. encryption 应做成输入框而不是选择框,新配置的默认值应为 none,若用户置空则应代填 none

                        VLESS 分享链接标准

                        感谢 a @DuckSoftopen in new tag 的提案!

                        详情请见 VMessAEAD / VLESS 分享链接标准提案open in new tag

                        - + diff --git a/development/protocols/vmess.html b/development/protocols/vmess.html index c5ac579a03..0a0138d8ca 100644 --- a/development/protocols/vmess.html +++ b/development/protocols/vmess.html @@ -24,11 +24,11 @@ VMess 协议 | Project X - - + +

                        VMess 协议

                        VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

                        版本

                        当前版本号为 1。

                        依赖

                        底层协议

                        VMess 是一个基于 TCP 的协议,所有数据使用 TCP 传输。

                        用户 ID

                        ID 等价于 UUIDopen in new tag,是一个 16 字节长的随机数,它的作用相当于一个令牌(Token)。 一个 ID 形如:de305d54-75b4-431b-adb2-eb6b9e546014,几乎完全随机,可以使用任何的 UUID 生成器来生成,比如这个open in new tag

                        用户 ID 可在配置文件中指定。

                        函数

                        通讯过程

                        VMess 是一个无状态协议,即客户端和服务器之间不需要握手即可直接传输数据,每一次数据传输对之前和之后的其它数据传输没有影响。

                        VMess 的客户端发起一次请求,服务器判断该请求是否来自一个合法的客户端。如验证通过,则转发该请求,并把获得的响应发回给客户端。

                        VMess 使用非对称格式,即客户端发出的请求和服务器端的响应使用了不同的格式。

                        客户端请求

                        16 字节X 字节余下部分
                        认证信息指令部分数据部分

                        认证信息

                        认证信息是一个 16 字节的哈希(hash)值,它的计算方式如下:

                        • H = MD5
                        • K = 用户 ID (16 字节)
                        • M = UTC 时间,精确到秒,取值为当前时间的前后 30 秒随机值(8 字节, Big Endian)
                        • Hash = HMAC(H, K, M)

                        指令部分

                        指令部分经过 AES-128-CFB 加密:

                        • Key:MD5(用户 ID + []byte('c48619fe-8f02-49e0-b9e9-edf763e17e21'))
                        • IV:MD5(X + X + X + X),X = []byte(认证信息生成的时间) (8 字节, Big Endian)
                        1 字节16 字节16 字节1 字节1 字节4 位4 位1 字节1 字节2 字节1 字节N 字节P 字节4 字节
                        版本号 Ver数据加密 IV数据加密 Key响应认证 V选项 Opt余量 P加密方式 Sec保留指令 Cmd端口 Port地址类型 T地址 A随机值校验 F

                        选项 Opt 细节:(当某一位为 1 时,表示该选项启用)

                        01234567
                        XXXXXMRS

                        其中:

                        • 版本号 Ver:始终为 1;
                        • 数据加密 IV:随机值;
                        • 数据加密 Key:随机值;
                        • 响应认证 V:随机值;
                        • 选项 Opt:
                          • S (0x01):标准格式的数据流(建议开启);
                          • R (0x02):客户端期待重用 TCP 连接(Xray 2.23+ 弃用);
                            • 只有当 S 开启时,这一项才有效;
                          • M (0x04):开启元数据混淆(建议开启);
                            • 只有当 S 开启时,这一项才有效;
                            • 当其项开启时,客户端和服务器端需要分别构造两个 Shake 实例,分别为 RequestMask = Shake(请求数据 IV), ResponseMask = Shake(响应数据 IV)。
                          • X:保留
                        • 余量 P:在校验值之前加入 P 字节的随机值;
                        • 加密方式:指定数据部分的加密方式,可选的值有:
                          • 0x00:AES-128-CFB;
                          • 0x01:不加密;
                          • 0x02:AES-128-GCM;
                          • 0x03:ChaCha20-Poly1305;
                        • 指令 Cmd:
                          • 0x01:TCP 数据;
                          • 0x02:UDP 数据;
                        • 端口 Port:Big Endian 格式的整型端口号;
                        • 地址类型 T:
                          • 0x01:IPv4
                          • 0x02:域名
                          • 0x03:IPv6
                        • 地址 A:
                          • 当 T = 0x01 时,A 为 4 字节 IPv4 地址;
                          • 当 T = 0x02 时,A 为 1 字节长度(L) + L 字节域名;
                          • 当 T = 0x03 时,A 为 16 字节 IPv6 地址;
                        • 校验 F:指令部分除 F 外所有内容的 FNV1a hash;

                        数据部分

                        当 Opt(S) 开启时,数据部分使用此格式。实际的请求数据被分割为若干个小块,每个小块的格式如下。服务器校验完所有的小块之后,再按基本格式的方式进行转发。

                        2 字节L 字节
                        长度 L数据包

                        其中:

                        • 长度 L:Big Endian 格式的整型,最大值为 2^14;
                          • 当 Opt(M) 开启时,L 的值 = 真实值 xor Mask。Mask = (RequestMask.NextByte() << 8) + RequestMask.NextByte();
                        • 数据包:由指定的加密方式加密过的数据包;

                        在传输结束之前,数据包中必须有实际数据,即除了长度和认证数据之外的数据。当传输结束时,客户端必须发送一个空的数据包,即 L = 0(不加密) 或认证数据长度(有加密),来表示传输结束。

                        按加密方式不同,数据包的格式如下:

                        • 不加密:
                          • L 字节:实际数据;
                        • AES-128-CFB:整个数据部分使用 AES-128-CFB 加密
                          • 4 字节:实际数据的 FNV1a hash;
                          • L - 4 字节:实际数据;
                        • AES-128-GCM:Key 为指令部分的 Key,IV = count (2 字节) + IV (10 字节)。count 从 0 开始递增,每个数据包加 1;IV 为 指令部分 IV 的第 3 至第 12 字节。
                          • L - 16 字节:实际数据;
                          • 16 字节:GCM 认证信息
                        • ChaCha20-Poly1305:Key = MD5(指令部分 Key) + MD5(MD5(指令部分 Key)),IV = count (2 字节) + IV (10 字节)。count 从 0 开始递增,每个数据包加 1;IV 为 指令部分 IV 的第 3 至第 12 字节。
                          • L - 16 字节:实际数据;
                          • 16 字节:Poly1305 认证信息

                        服务器应答

                        应答头部数据使用 AES-128-CFB 加密,IV 为 MD5(数据加密 IV),Key 为 MD5(数据加密 Key)。实际应答数据视加密设置不同而不同。

                        1 字节1 字节1 字节1 字节M 字节余下部分
                        响应认证 V选项 Opt指令 Cmd指令长度 M指令内容实际应答数据

                        其中:

                        • 响应认证 V:必须和客户端请求中的响应认证 V 一致;
                        • 选项 Opt:
                          • 0x01:服务器端准备重用 TCP 连接(Xray 2.23+ 弃用);
                        • 指令 Cmd:
                          • 0x01:动态端口指令
                        • 实际应答数据:
                          • 如果请求中的 Opt(S) 开启,则使用标准格式,否则使用基本格式。
                          • 格式均和请求数据相同。
                            • 当 Opt(M) 开启时,长度 L 的值 = 真实值 xor Mask。Mask = (ResponseMask.NextByte() << 8) + ResponseMask.NextByte();

                        动态端口指令

                        1 字节2 字节16 字节2 字节1 字节1 字节
                        保留端口 Port用户 IDAlterID用户等级有效时间 T

                        其中:

                        • 端口 Port:Big Endian 格式的整型端口号;
                        • 有效时间 T:分钟数;

                        客户端在收到动态端口指令时,服务器已开放新的端口用于通信,这时客户端可以将数据发往新的端口。在 T 分钟之后,这个端口将失效,客户端必须重新使用主端口进行通信。

                        注释

                        • 为确保向前兼容性,所有保留字段的值必须为 0。
                        - + diff --git a/document/command.html b/document/command.html index ea2208b8e1..8506575d22 100644 --- a/document/command.html +++ b/document/command.html @@ -24,8 +24,8 @@ 命令参数 | Project X - - + +

                        命令参数

                        提示

                        Xray 使用 Go 风格的命令及参数

                        获取基本命令

                        您可以运行 xray help 来获得所有 xray 最基础的用法, 以及可用的命令及说明。

                        Xray is a platform for building proxies.
                        @@ -80,6 +80,6 @@
                         

                        xray x25519

                        生成 x25519 密钥对。

                        使用方法:

                        xray x25519 [-i "(base64.RawURLEncoding)" --std-encoding ]
                         

                        xray wg

                        生成 wireguard curve25519 密钥对。

                        使用方法:

                        xray wg [-i "(base64.StdEncoding)"]
                         

                        提示

                        -config 没有指定时,Xray 将先后尝试从以下路径加载 config.json :

                        • 工作目录(Working Directory)
                        • 环境变量Xray.location.asset 所指定的路径
                        - + diff --git a/document/config.html b/document/config.html index 95767f4191..4f00e748bc 100644 --- a/document/config.html +++ b/document/config.html @@ -24,8 +24,8 @@ 配置运行 | Project X - - + +

                        配置运行

                        下载并安装 了 Xray 之后,您需要对它进行一下配置。

                        为了演示,这里只介绍简单的配置方式。更多的模板: Xray-examplesopen in new tag

                        如需配置更复杂的功能,请参考更详细的 配置文件 中相关说明。

                        警告

                        为了避免你的流量被解密,
                        你应该使用 xray uuiduuidgen 生成一个独一无二的uuid
                        在服务端上,放入 inbounds[0].settings.clients[0].id
                        在客户端内,放入 outbounds[0].settings.vnext[0].users[0].id

                        服务端配置

                        你需要一台防火墙外的服务器,来运行服务器端的 Xray。配置如下:

                        {
                        @@ -93,6 +93,6 @@
                           }
                         }
                         

                        上述配置唯一要更改的地方是你的服务器 IP 和用户 uuid,配置中已注明。上述配置会把除局域网(比如访问路由器)和国内IP段(比如访问bilibili、acfun)以外的所有流量转发至你的服务器。

                        运行

                        • 在 Windows 和 macOS 中,配置文件通常是 Xray 同目录下的 config.json 文件。
                          • 直接运行 XrayXray.exe 即可。
                        • 在 Linux 中,配置文件通常位于 /etc/xray//usr/local/etc/xray/ 目录下。
                          • 运行 xray run -c /etc/xray/config.json
                          • 或使用 systemd 等工具将 Xray 作为服务在后台运行。

                        更多详细的说明可以参考 配置文档小小白话文

                        - + diff --git a/document/document.html b/document/document.html index fa3e734af2..ce2037a3fb 100644 --- a/document/document.html +++ b/document/document.html @@ -24,14 +24,14 @@ 为 Project X 的文档贡献 | Project X - - + +

                        为 Project X 的文档贡献

                        欢迎您为 Project X 的文档做出贡献,我们感谢每一位 Contributor 的贡献!是你们让 Xray 更加强大!

                        改进文档

                        Project X 的文档托管在 GitHubopen in new tag 上.

                        您可以通过以下步骤, 提交您对文档的改动:

                        1. Project X 文档仓库open in new tag 打开仓库, 点击右上角的 fork, fork 一份文档仓库的镜像到您自己的 github 仓库.

                        2. 使用任何您喜欢的工具, 从您克隆的仓库获得文档的克隆, 如:

                        git clone https://github.com/XTLS/Xray-docs-next.git
                         
                        1. 基于 main 分支创建新的分支, 如:
                        git checkout -b your-branch
                         
                        1. 在新分支上做修改。

                          注:推荐 中文文案排版指北open in new tag

                        2. 修改完成后,请使用 Prettieropen in new tag 格式化您的更改。

                          注:存在格式问题的 PR,将有可能被拒绝。

                        3. 提交修改,并推送到您的仓库中

                        git push -u origin your-branch
                         
                        1. 打开 GitHub, 点击 'Pull request' 向 Project X 文档仓库open in new tag 提交 PR。

                        2. 请在 PR 的标题和正文中,概述此次 PR 新增/修改的内容等;

                        3. 等待回应, 如果 PR 被 merge, 您做的修改将直接呈现在 Project X 文档网站open in new tag

                        发现问题?

                        如果您发现文档出错,可以改进文档或提交一个 Issue。

                        - + diff --git a/document/index.html b/document/index.html index b1b6855306..2d0f083cb3 100644 --- a/document/index.html +++ b/document/index.html @@ -24,11 +24,11 @@ 快速入门 | Project X - - + +

                        快速入门

                        这个章节将告诉您如何用最简单的方式获得 Xray,并且开始使用 Xray。

                        下载安装

                        Xray 支持各种平台,并且您可以从多种渠道和方式获得 Xray 的各种版本。

                        请点击 下载安装 以获取 Xray

                        配置运行

                        下载并安装 Xray 后,只需对他进行配置即可使用。

                        请点击 配置运行 以学习最简单的配置方式。

                        命令参数

                        Xray 有多种命令和参数可用,因此变得灵活和强大。

                        请点击 命令参数 查看 Xray 的更多命令和参数用法。

                        改进文档

                        如果你有兴趣,请点击 使用文档 帮助我们改进文档,或者点击页面下方的 帮助我们改善此页面!

                        我们十分感谢每一位 Contributor 作出的贡献!是你们让 Project X 变得更加强大!

                        小小白白话文

                        给予新手指导的使用心得

                        请点击 小小白白话文 以进行查看。

                        入门技巧

                        具备了基础之后,你就可以通过 入门技巧 来探索更多的使用方式了。

                        进阶文档

                        给予进阶用户指导的使用技巧

                        点击 进阶文档 以进行查看

                        感谢

                        非常感谢大家无私分享使用技巧和心得, 使得 Xray 日益强大。

                        - + diff --git a/document/install.html b/document/install.html index 9828185355..2f8c71041a 100644 --- a/document/install.html +++ b/document/install.html @@ -24,11 +24,11 @@ 下载安装 | Project X - - + +

                        下载安装

                        平台支持

                        Xray 在以下平台中可用:

                        • Windows 7 及之后版本(x86 / amd64 / arm32 / arm64);
                        • macOS 10.10 Yosemite 及之后版本(amd64 / arm64);
                        • Linux 2.6.23 及之后版本(x86 / amd64 / arm / arm64 / mips64 / mips / ppc64 / s390x / riscv64);
                          • 包括但不限于 Debian 7 / 8、Ubuntu 12.04 / 14.04 及后续版本、CentOS 7 / 8、Arch Linux 等;
                        • FreeBSD (x86 / amd64);
                        • OpenBSD (x86 / amd64);
                        • Dragonfly BSD (amd64);

                        下载 Xray

                        预编译的二进制 ZIP 格式压缩包可在 Github Releasesopen in new tag 中找到。

                        下载对应平台的压缩包,解压后即可使用。

                        验证安装包

                        Xray 提供两种验证方式:

                        • ZIP 压缩包的 SHA1 / SHA256 摘要
                        • 可复现构建:请参照 编译 Xray

                        Windows 安装方式

                        macOS 安装方式

                        Linux 安装方式

                        安装脚本

                        Arch Linux

                        Arch User Repository

                        需要使用 AUR helpersopen in new tag,以 yayopen in new tag 为例,可通过 yay -S xray 安装。

                        Arch Linux CN

                        首先添加 Arch Linux CN 仓库open in new tag,然后在 root 用户下使用 pacman -S xray 安装。

                        Linuxbrew

                        Linuxbrew 包管理器的使用方式与 Homebrew 一致:brew install xray

                        Debian WIP

                        Gentoo

                        目前有三个第三方 Overlay 提供 Portage 安装脚本:

                        使用 layman 或 eselect-repository 添加 Overlay 至本地,然后即可安装。

                        Docker 安装方式

                        Docker image 的文件结构

                        • /etc/xray/config.json:配置文件
                        • /usr/bin/xray:Xray 主程序
                        • /usr/share/xray/geoip.dat:IP 数据文件
                        • /usr/share/xray/geosite.dat:域名数据文件

                        图形化客户端

                        UUID 生成器

                        第三方的 UUID 生成器 uuidgenerator.netopen in new tag

                        - + diff --git a/document/level-0/ch01-preface.html b/document/level-0/ch01-preface.html index a1000def32..0d38d2a51e 100644 --- a/document/level-0/ch01-preface.html +++ b/document/level-0/ch01-preface.html @@ -24,11 +24,11 @@ 【第 1 章】 小小白白话文 | Project X - - + +

                        【第 1 章】 小小白白话文

                        1.1 这篇文档是写给谁的?

                        一句话:写给 ① 零基础 ② 希望学习自建 VPS 的新人。

                        1.2 这篇文档不是写给谁的?

                        包括但不限于:各路大神大能、懒得自己折腾的小白、已经会折腾的高手、确定要用机场的土豪、确定要用一键脚本的逍遥派...... 总之只要有技术基础、或不愿不想自建的同学,您直接关闭本文即可,因为这篇文章大概是入不了您的法眼的,更可能会让您生一肚子闲气,那多划不来。

                        1.3 郑重声明及其他声明

                        郑重声明:

                        鄙人技术奇菜无比,故本文必然挂一漏万破绽百出。您若发现问题还请温柔提醒,莫要人参公鸡。

                        免责声明:

                        本文内容请您自行判断是否可信可靠可用,若您根据本文内容建立和使用 VPS 服务器时出了任何问题和不良结果,鄙人概不负责。

                        啰嗦声明:

                        基于本文【零基础用户】的目标受众,许多内容会尽力详尽说明,所以语言偏啰嗦,请做好心理准备。

                        1.4 为什么自建是个难题?

                        要回答这个问题,就需要稍微多说一点背景信息了。

                        一、科学上网这件事

                        科学上网这件事情,说来已经发展了近二十年(震惊!!!.jpg)。最初,自己稍微动动手即可(改改 host、连一下 ssh)、后来需要找一个网页代理,再后来需要写一个私有协议(比如 Shadowsocks)等等。

                        随着 GFW 技术这十几年来不断的迭代升级,若要完成【自己动手科学上网】这个目标,需要做的事情已经包括但不限于:

                        • 了解 Linux 系统基本命令
                        • 了解网络传输协议
                        • 有技术和经济能力完成 VPS 购买及管理
                        • 有技术和经济能力完成域名购买及管理
                        • 有技术能力完成 TLS 证书申请 等等。

                        这就让【自建 VPS 科学上网】这个曾经简单的行为逐渐变成了令新人望而生畏的挑战。

                        二、零基础用户的无奈

                        零基础的非技术用户,如果完成上面这一连串的操作,势必要学习大量的知识,但稍微搜索之后,新人只怕会更加迷茫:大量的信息散布在互联网的各个角落:博客、问答网站、群组、论坛、GitHub、Telegram、YouTube 等等等等)。这些信息纷乱复杂、水平良莠不齐、甚至可能互相矛盾。基本上就是不把新人彻底弄晕誓不罢休。

                        面对这些杂乱无章的信息,新人突然就从【信息匮乏】变成了【信息过剩】。若是几番连蒙带猜的折腾以失败告终(大概率如此)的话,他的积极性势必大受挫折。在这个过程中,若他又恰好去了一些不太友好的地方去求助,恐怕还要雪上加霜的被嘲讽一番:“这么菜,用机场不就行了,瞎折腾什么啊!”、“先去学会 Linux 再回来问吧”。

                        这时候,大概也只有一声“呵呵”可以表达心情了。

                        1.5 “用机场不就行了?”

                        首先,我想反问一下那些冷嘲热讽的人:“用机场”真的就是万灵药吗?

                        其次,我认为“不懂”和“不想懂”是有本质区别的。态度恶劣的巨婴伸手党自然惹人厌烦,但真心自学却不得要领的人不该受到无端的白眼和歧视,也正是这种对新人不加区分的恶劣社区氛围促使我写下本文。那么闲话少说,我们来看看机场的优势与劣势究竟如何:

                        一、“机场“的优势

                        所谓“机场”,就是“线路提供商”。他负责完成 1.4 提到的那一串技术操作和管理,用户则付费获得使用权。所以,它的优点至少有:

                        1. 用户操作简单:扫码操作、一键添加规则等
                        2. 线路选择多:可解锁不同国家、地区的网络服务;比如 iplc 等专线服务、游戏加速服务等
                        3. 接入节点多:所以抵抗节点封锁的能力强一些,封了一个就换下一个

                        二、“机场”的风险

                        “方便”这枚硬币的另一面就是“风险”,基于“机场”的技术特点和市场情况,它的风险至少有:

                        1. “机场”可完全获得用户信息:用户在网上的所有痕迹,都【必然】经过且【非常可能】长期存储在其服务器上,这些记录无法受到任何具备法律效力的用户隐私协议的约束(窥视、记录你的一举一动
                        2. “机场”缺乏市场管理:不可避免存在着以欺诈为目标的恶意商家(主动跑路
                        3. “机场”面临监管压力:大机场相对有保障的同时,也无法避免树大招风。2020 年间,已经有几个大机场停运、跑路的事件发生,用户的正常使用受到严重干扰(被动跑路
                        4. “机场”技术水平难以确定:线路质量良莠不齐,挂羊头卖狗肉的现象屡见不鲜(速度慢、掉线多、连不上

                        1.6 那么你到底要不要自建呢?

                        现在,你已经看到了机场的优势和风险,要用什么,就请各位充分思考并自行决定。毕竟,最适合你的方案才是最好的方案。

                        It's Your Choice!

                        1. 如果决定使用机场的话,现在,你可以关闭本文了。

                        2. 如果你决定自建,那就请继续阅读后面的章节吧!!

                        总之,本文的目标就是成为零基础用户的知识起点,提供对每一步充分的讲解和演示,清清楚楚(甚至婆婆妈妈、絮絮叨叨、啰啰嗦嗦)的协助新人完成【从输入第一条命令开始,完成 VPS 服务器部署,并成功在客户端完成科学上网】的全程。并在这个过程中帮助新人逐步接触和熟悉 Linux 的基础操作,为之后的进一步自学打下基础。

                        1.7 题外啰嗦几句

                        1. 墙外的信息泥沙俱下,请务必学会理性、独立的思辨,不要随意站队,不要轻信猎奇的信息。

                        2. 衷心希望大家获得更顺畅的网络后,可以获取更新鲜的知识、更丰富的娱乐、接触更美好的世界、结交更多志同道合的朋友,但不要成为任何有不可告人目的之人的替罪羊。

                        3. 你的互联网身份依然是你的身份,绝对的匿名化是极为困难的,所以请务必遵守你个人所在地区和 IP 所在地区的相关法律法规。无论何时,自我保护都是最基本的底线。

                        1.8 你的进度

                        ⬛⬜⬜⬜⬜⬜⬜⬜ 12.5%

                        - + diff --git a/document/level-0/ch02-preparation.html b/document/level-0/ch02-preparation.html index 0ec2488094..1249caf342 100644 --- a/document/level-0/ch02-preparation.html +++ b/document/level-0/ch02-preparation.html @@ -24,11 +24,11 @@ 【第 2 章】原料准备篇 | Project X - - + +

                        【第 2 章】原料准备篇

                        这一章比较特殊,因为涉及到金钱交易行为,本文基于项目的中立立场,不做具体的推荐。我能做的,是告诉你需要准备哪些东西。

                        2.1 获取一台 VPS

                        你需要获取一台健康的、IP 没有被墙的 VPS,并在管理后台做下面这些基础准备:

                        1. 在 VPS 的后台安装 Debian 10 64bit 系统
                        2. 小本本记下 VPS 的 IP 地址(本文会用 "100.200.300.400" 来表示)

                          提示

                          这是一个故意写错的非法 IP,请替换成你的真实 IP)

                        3. 小本本记下 VPS 的 SSH 远程登陆端口(Port)
                        4. 小本本记下 SSH 远程登录的用户名和密码

                        购买 VPS 是一个比较复杂的事情,建议先去学习一下相关知识,选择适合自己的经济能力和线路需求的即可。另外可以选择薅一些国际大厂的羊毛(比如甲骨文和谷歌提供的永久免费或限时免费的套餐)。总之,务必量力而行。

                        说明

                        关于选择 Debian 10 作为操作系统,这里稍微多说一句:不管你在网上听说了什么,不管哪个大神告诉你 XXX 版的 Linux 更好、XXX 版的 Linux 更牛,这些 Linux 的派系之争跟现在的你半毛钱关系也没有!使用 Debian 10 足以让你的 VPS 服务器在安全、稳健运行的同时得到足够的优化(如 cloud 专用内核、及时的 bbr 支持等)。等你对 Linux 熟悉之后,再回头去尝试其他的 Linux 发行版也不迟。

                        2.2 获取一个心仪的域名

                        你需要获取一个域名、并在 DNS 设置中添加一条 A 记录,指向你 VPS 的 IP 地址

                        1. 请选择靠谱的国际域名服务商。选择一些常见的域名后缀就行,注意不要用 .cn 后缀。
                        2. 在 DNS 设置中,添加一条指向你 VPS 的 IP 地址的 A 记录(A 记录的名字可以随便起,本文会用 "a-name" 来表示。完整的域名则会用 "二级域名.你的域名.com" 或者 "a-name.yourdomain.com" 来表示)。效果如下图:

                        添加A记录

                        提示

                        不是一个真实可用的网址,请替换成你的真实网址

                        2.3 你本地电脑上需要安装的软件

                        1. SSH 远程登录工具

                        2. 远程文件拷贝工具

                        3. 靠谱的文本编辑器

                        2.4 你的进度

                        如果上面的原材料你都准备好了的话,你已经拿到了开启新世界大门的钥匙。那还等什么,让我们快点进入下一章,走进这扇门吧!

                        ⬛⬛⬜⬜⬜⬜⬜⬜ 25%

                        - + diff --git a/document/level-0/ch03-ssh.html b/document/level-0/ch03-ssh.html index c1ddaab3d5..ff18ae3ade 100644 --- a/document/level-0/ch03-ssh.html +++ b/document/level-0/ch03-ssh.html @@ -24,13 +24,13 @@ 【第 3 章】远程登录篇 | Project X - - + +

                        【第 3 章】远程登录篇

                        3.1 远程登录 VPS (PuTTY)

                        首先,鉴于零基础人群中 Windows 的用户基数最大,所以本文以 Windows 为例进行展示。

                        其次,虽然 Windows 10 之后的 PowerShell 和 WSL 也可以达到很好的 SSH 操作体验。但是因为并非所有版本的 Windows 都有最新的组件,故本文还是以老牌的 PuTTY 为例,进行 SSH 远程登录的操作详解。(使用其他工具的话、在 SSH 登陆之后的操作都是一样的)

                        下面就跟我一步步操作吧。

                        1. 进入 PuTTY 的官网open in new tag,选择适合你操作系统的版本下载。(本文以 64 位版本为例)

                          下载PuTTY

                        2. 安装运行后,将会看到 PuTTY 的主界面。现在请拿出你上一章记东西的小本本,在下图的对应位置填入你 VPS 的IP 地址(VPS IP)端口(VPS PORT)。为了方便以后使用时不用重复输入,我们可以保存会话 (Saved Sessions),未来使用时只要按 Load 即可一键载入设置。

                          设置PuTTY

                        3. 我建议将 Connection 中的 keepalive 设置为 60 秒,防止你一段时间没有操作之后 SSH 自动断线。另外务必再次保存设置。

                          防止频繁断线

                        注意

                        对 PuTTY 的任何设置更新都要再次手动保存 Session,不然关闭后就会丢失

                        1. 点击 Open 就会进入 SSH 连接窗口,对应下图输入用户名与密码,与你的 VPS 远程主机建立连接。(本文假设默认用户名是 root,另外,在 Linux 系统输入密码的时候,是不会出现 ****** 这种提示符的,这样可以避免密码长度泄漏,不是你的键盘坏掉了哦!)

                          SSH远程登录

                        3.2 成功登录 SSH!初识命令行界面!

                        1. 如果你的信息都填写正确,你将会看到类似下图的界面,说明已登录成功:

                          初次登录VPS

                          这个界面,就等于远程服务器的【桌面】,但它没有你熟悉的图标和鼠标,没有绚丽的色彩,有的只是简单文字,这就是【命令行界面】- Command Line Interface,或者缩写为 CLI

                          接下来的所有操作,都需要你像电影里的黑客一样,在这个命令行界面中完成。也许你会觉得陌生,但请相信我,使用命令行既不可怕,也不神秘。说到底,它只不过是把你习惯的鼠标操作变成了文字指令而已,你说一句,它做一句

                        2. 现在,你可以稍微观察并熟悉一下命令行环境,这个界面其实已经告诉了你一些有用的信息了,比如系统内核版本(比如图内是 4.19.37-5)、上次登录时间及 IP 等。当然根据 VPS 的不同,你看到的界面可能会略有不同。

                        3. 请注意命令行最下面一行,闪动的光标左边,有一串字符。图中显示的是root@vps-server:~#,这一串要怎么理解呢?很简单:

                          • 现在的用户是 root
                          • root 所在的服务器是 vps-server
                          • root 现在所在的文件夹是 ~
                          • # 之后是你可以输入命令的地方

                          前两个很直观,无需多说。第三个是关于 Linux 的文件夹系统,现在也不需要过于深入,你只需要知道,"~"就是【当前用户的大本营】。第四个,提示符#,你也不用管,只需要知道,未来文章中会写一些需要你输入的命令,都会以 "#" 或者 "$" 开头,提示你后面是你输入命令的地方。(所以你复制命令的时候,只需要复制后面的内容,不要复制提示符)

                        3.3 第一次更新 Linux 的软件!

                        1. 正如你的手机,无论安卓还是 iPhone,为了 APP 及时更新(获取安全补丁和新功能),都会时不时从应用商店获得更新信息,并且提示你有多少个 APP 可更新。Linux 系统也有逻辑十分类似的更新机制。所以只要你会更新手机 APP,就能学会更新 Linux 软件!

                        2. Linux 下,每个 APP 都叫做一个“包” (package)。管理 APP 的程序自然就叫做“包管理器”(Package Manager)。你可以通过它安装、更新、卸载各种软件、甚至更新 Linux 系统本身。Linux 下的包管理器非常强大,此处按下不表,现在你只需要知道 Debian 系统的包管理器叫做 apt 即可。接下来,我们就先使用 apt 做一次软件的全面更新,让你熟悉它的基本操作。

                        3. 小小白白 Linux 基础命令:

                          编号命令名称命令说明
                          cmd-01apt update查询软件更新
                          cmd-02apt upgrade执行软件更新
                        4. 现在请输入第一条命令,获取更新信息

                          apt update
                           
                        5. 然后请输入第二条命令,并在询问是否继续安装 (Y/n) 时输入 y 并回车确认,开始安装

                          apt upgrade
                           
                        6. 完整流程演示如下:

                          初次软件更新流程演示

                        3.4 你的进度

                        恭喜你又迈出了坚实的一步! 现在,你已经可以通过 SSH 来登录你的远程服务器了!那登录进去之后,除了升级软件之外,应该再做点什么呢?敬请进入下一章一探究竟吧!

                        ⬛⬛⬛⬜⬜⬜⬜⬜ 37.5%

                        - + diff --git a/document/level-0/ch04-security.html b/document/level-0/ch04-security.html index 4324231234..2a81068310 100644 --- a/document/level-0/ch04-security.html +++ b/document/level-0/ch04-security.html @@ -24,8 +24,8 @@ 【第 4 章】安全防护篇 | Project X - - + +

                        【第 4 章】安全防护篇

                        4.1 为什么要做安全防护

                        Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的网站、APP、服务、甚至线下基础设施都建立在 Linux 的基石之上,这背后牵涉到巨大的经济利益和商业价值,当然也就就意味着黑灰产有巨大的攻击动力。但是这些服务是如此重要、根本不允许出现重大的安全漏洞。于是无数的运维专业人员都在安全攻防的战场上拼搏努力,这才让大家能享受到基本稳定的现代化数字生活。

                        现在,你拥有了一台 VPS,并且将会敞开他的数据访问渠道来达到流量转发的目标,那就相当于你已经置身于安全攻防战场的第一线、直面所有风险。但与此同时,新人由于知识和信息的不足,看待安全问题是总是难免两极分化:要么觉得轻如鸿毛和自己没有半点关系,要么觉得重于泰山甚至惶惶不可终日。

                        • 对于前者,我的建议是:安全无小事,尽量多查一些安全方面的信息,免得自己真的受了损失才后悔莫及

                        • 对于后者,我的建议是:不用紧张,我们的服务器仍不具有太高的价值、一般不会吸引到高水平的攻击,需要面对的基本都是一些自动化脚本的恶意扫描和登录尝试,跟着本文做一些基础的防护即可

                        4.2 具体的风险到底是什么

                        就像我们在《远程登录篇》配置的一样,任何人只需要知道【IP 地址】+【端口】+【用户名】+【密码】这四个要素,就能登录你的 VPS 服务器。那很显然,这四要素的安全就是我们要防护的底线。我们来逐一分析:

                        1. 【IP 地址】:恶意脚本会随机尝试和扫描 IP 段,可以简单认为是公开信息、无法隐藏

                        2. 【端口】:如果使用默认端口,那么【端口 = 22

                        3. 【用户名】:如果使用默认用户,那么【用户名 = root

                        4. 【密码】:密码不存在默认值,一定是由 VPS 后台随机生成或由你自行设置的。也就是说,如果你的服务器都是默认设置,则四要素中的三个已经是已知的,那么你整个服务器的安全,就全部寄托在一串小小的密码上了。这时有几种情况:

                          • 如果你用了 VPS 管理后台随机生成密码,它一般包含随机的十几个大小写混杂的字母和符号,相对比较安全

                          • 如果你为了好记、把密码改成了类似123456这种超弱的密码,破解你的 VPS 服务器可谓不费吹灰之力

                          • 如果你为了好记、把密码改成了比较复杂、但在别的地方用过的密码,其实也并不安全。你要明白黑客手里有作弊器,比如说密码表,包含数万、数十万、数百万甚至更多曾经泄漏的真实密码)

                        5. 但你要明白,没有哪个黑客真的要坐在电脑前一次一次的尝试你的密码,全部的攻击尝试都是恶意脚本自动进行的,它会 24 小时不眠不休的工作。也许每天你酣睡之时,你的服务器都在经受着一轮又一轮的冲击。

                          一旦密码被成功撞破,意味着你的四要素全部被攻击者掌握,恶意脚本就会快速登录服务器、获取服务器的最高 root 控制权、安装部署它的恶意服务,然后就可以用你的服务器来 24 小时做各种坏事(比如挖矿、传播病毒、发送垃圾邮件、欺诈邮件、做 BT 中继、甚至暗网公众节点等等等等)。如果恶意脚本比较克制,其实可以做到相当的隐蔽性。而新人一般也不会去观察留意 VPS 的登录记录、进程变化、CPU 占用变化、流量变化等指标,你其实就很难发现自己被黑了。直到你的 VPS 服务商封禁你的账号、或者收到律师函为止。

                        6. 别忘了,你获得 VPS 时大概率需要使用真实的支付信息,你登录各种网站、社交平台时也会留下你的 IP 地址,这些都与你的身份有直接或者间接的关系。于是,一旦这些坏事发生,它们就不可避免的与你产生了关联。

                        4.3 我们要做的安全防护有哪些

                        基于上述分析,我们要做的,自然就是对【端口】、【用户名】、【密码】这三要素进行加强,来降低被攻破的风险:

                        1. 【端口】:将 SSH 远程登录端口修改为【非 22 端口】 (4.4)
                        2. 【用户名】:建立【非 root】的新用户、并禁用 root 用户 SSH 远程登录 (4.5、4.6)
                        3. 【密码】:SSH 启用 RSA 密钥验证登录、同时禁用密码验证登录 (4.7)

                        记得按顺序来,别把自己锁在门外了。

                        4.4 将 SSH 远程登录端口修改为非 22 端口

                        现在,我们来解决【端口 = 22】的问题。(注意:有些 VPS 服务商,默认的端口已经是非 22 端口,那么你可以忽略这一步,当然也可以跟着本文改成别的端口)

                        1. 小小白白 Linux 基础命令:

                          编号命令名称命令说明
                          cmd-03nano文本编辑器
                          cmd-04systemctl restart重启某个服务
                        2. 小小白白 Linux 基础配置文件

                          编号配置文件位置文件说明
                          conf-01/etc/ssh/sshd_configSSH 远程登录程序设置
                        3. 我们要做的第一件事,当然就是【用nano这个文本编辑器打开SSH远程登录程序设置】,在 Windows 下,你会【找到文件并双击】,在 Linux 下该怎么办呢?仔细看看上面的命令说明,是不是就很简单了?没错,就是:

                          nano /etc/ssh/sshd_config
                          @@ -39,6 +39,6 @@
                           
                        4. 修改 SSH 配置。这个我们已经用了很多次,但现在我们已经从无所不能的root变成了普通用户vpsadmin,此时的我们是没有权限直接编辑 SSH 配置的。这时候就需要使用sudo命令了:

                          sudo nano /etc/ssh/sshd_config
                           
                        5. 找到(ctrl+w) PasswordAuthentication 改成 no

                        6. 找到(ctrl+w) PubkeyAuthentication 改成 yes,然后保存(ctrl+o)退出(ctrl+x)

                        7. 重启 SSH 服务。(啰嗦君:别忘了现在需要使用sudo来获得权限)

                          sudo systemctl restart ssh
                           
                        8. 完整流程如下:

                          SSH开启密钥验证并禁用密码验证

                      76. VPS 端已经设置好了公钥,现在要给 PuTTY 指定私钥位置供登录时使用(啰嗦君:别忘了保存 Session)

                        PuTTY指定私钥位置

                      77. 至此,【密钥登录】已成功开启、【密码验证】已成功关闭、并且还给 PuTTY 保存了默认的登录用户名和私钥。未来使用 PuTTY 登录时,载入VPS-SERVER配置后,点击Open就可以一键登录了。

                        如果你给私钥设置了密码保护,登录时当然还需要输入这个密码才能使用密钥,如下图:

                        输入私钥密码

                      78. 别忘了给WinSCP也做对应的密钥设置,否则之后想要传输文件时就无法登录了:

                        WinSCP指定私钥位置

                      注意

                      任何需要借助 SSH 进行登录的软件都需要密钥验证了,软件过多,无法逐一展示,请根据你的需要自行设置好哦

                      4.8 你的进度

                      到这里为止,你的 VPS 已经完成了【端口】、【用户名】、【密码】这三要素的基本安全保障,虽然远称不上固若金汤,但一般的恶意脚本应该已经无法对你造成伤害了!

                      现在我们终于有了一个安全的系统基础,下一章,我们就可以开始逐步安装配置 Xray 需要的基础设施了!(什么基础设施呢?一个网页,一张证书)

                      ⬛⬛⬛⬛⬜⬜⬜⬜ 50%

                  - + diff --git a/document/level-0/ch05-webpage.html b/document/level-0/ch05-webpage.html index 5cbefa715f..f30176553e 100644 --- a/document/level-0/ch05-webpage.html +++ b/document/level-0/ch05-webpage.html @@ -24,8 +24,8 @@ 【第 5 章】网站建设篇 | Project X - - + +

                  【第 5 章】网站建设篇

                  5.1 为什么要做一个网站?

                  新人也许会迷惑,为什么科学上网还要建一个网站?我不会编程啊,是不是特别麻烦?

                  先回答第一个问题,建网站的原因有:

                  1. 申请合法的 TLS 证书(非常重要)
                  2. 提供合理的回落,防止主动探测攻击,提高安全性
                  3. 建设一个伪装站(如博客、私人网盘、多媒体网站、游戏网站等),直接访问时有合理的前台,使流量使用看上去更合理。

                  再回答第二个问题:

                  1. 本文作为演示,仅仅使用了一个最简单的【单文件 html 页面 + Nginx】来搭建,以此完成上面的目标,所以【非常简单】
                  2. 这个网站完全可以不仅仅是伪装,而是真的做大做强,这个复杂性就完全取决于你了
                  3. 对于“伪装”和“网站运营”这个目标,需要的就是各不相同、秀出真我,需要的同学可以自行搜索学习。这个内容已经完全偏离了科学上网,本文就不深入解析了。

                  5.2 登录 VPS、安装运行 Nginx

                  1. 这里用到的,都是之前已经详解过的命令,所以就不重复讲解了。看不懂的同学可以看看前面的章节哦。

                    sudo apt update && sudo apt install nginx
                    @@ -90,6 +90,6 @@
                             }
                     

                    特别注意!

                    如我在【第 3 步】中的提示所说,请务必确保 /home/vpsadmin/www/webpage 改成你的实际文件路径。

                  2. nginx 重新载入配置使其生效

                    sudo systemctl reload nginx
                     
                  3. 完整的设置流程如下:

                    网页设置演示

                  4. 此时如果你访问 http://二级域名.你的域名.com,你看到这样的页面则说明成功:

                    http网页成功

                5.4 常见错误的说明

                首先,如果你一路按照文章的说明来操作,并且足够细心,那肯定不会出错。所以,我并不打算修改本文的写法。

                那为什么依然有很多同学卡在了这一步,网页怎么也打不开呢?基本上就是两个字:粗心。因为这里配置可能出现的问题只有两种,原因也只有两个。

                一、两种问题:

                • nginx.conf 里面的 /home/vpsadmin/www/webpage 这一条,与你的实际文件路径不符,nginx 找不到文件
                • 路径正确,但 nginx 无权读取

                二、两个原因:

                • 使用了【非 root 用户】,但仍然直接拷贝文中的命令不加修改。(这基本就等于抄答案时把同学的名字一起抄过去了)
                • 坚持使用【 root 用户】

                碰到错误的同学,就回过头仔细看一下【5.3】中【第 3 步】和【第 5-2 步】的说明吧。

                注意

                本文前期已经用了大量篇幅说明了使用【非 root 用户】对安全的重要性,全文也是基于此而写。所以,因使用【 root 用户】而导致的问题并不在本文的设计范围里。

                但我相信,坚持使用【 root 用户】的同学应该是有主见、动手能力强、或者有一定 Linux 基础的同学。问题的症结我已经全部说明了,我相信你一定可以自行解决。

                5.5 你的进度

                至此,Xray 的第一个基础设施【网页】已经就位,我们马上就进入第二个基础设施【证书】吧!

                ⬛⬛⬛⬛⬛⬜⬜⬜ 62.5%

              - + diff --git a/document/level-0/ch06-certificates.html b/document/level-0/ch06-certificates.html index 1fc8a370e2..bdbfb840e0 100644 --- a/document/level-0/ch06-certificates.html +++ b/document/level-0/ch06-certificates.html @@ -24,8 +24,8 @@ 【第 6 章】证书管理篇 | Project X - - + +

              【第 6 章】证书管理篇

              6.1 申请 TLS 证书

              接下来我们要做的,是为我们的域名申请一个真实的 TLS 证书,使网站具备标准 TLS 加密的能力及 HTTPS 访问的能力。这就是 Xray 等现阶段安全代理工具确保流量充分加密最重要的工具。

              注意

              请不要轻易使用自签证书。它并没有让操作简单太多,但增加了无谓的风险(如中间人攻击)。

              这里我会使用一个叫做 acme.shopen in new tag 的证书管理工具,它简单、轻量、高效,并可完成证书自动更新。

              另外,我相信,现在你已经逐渐熟悉了 Linux 的基础操作,所以已经多次出现的命令从本章开始不再重复截图、只做简单的描述。如果实在想不起来怎么用的话,就稍微复习一下前面的章节吧。

              6.2 安装 acme.sh

              1. 小小白白 Linux 基础命令:

                编号命令名称命令说明
                cmd-12wget访问(或下载)某个网页文件
                cmd-13acme.shacme.sh 证书管理相关的命令
              2. 运行安装脚本

                wget -O -  https://get.acme.sh | sh
                @@ -136,6 +136,6 @@
                 [Mon 14 Feb 2022 03:00:25 PM CST] Installing key to: /etc/xray/cert/cert.key
                 [Mon 14 Feb 2022 03:00:25 PM CST] Installing full chain to: /etc/xray/cert/fullchain.crt
                 

              6.6 你的进度

              至此,Xray 所需要的两个基础设施终于全部就位!千呼万唤始出来的 Xray 马上就要揭开面纱,我们终于要进入最激动人心章节啦!

              ⬛⬛⬛⬛⬛⬛⬜⬜ 75%

              - + diff --git a/document/level-0/ch07-xray-server.html b/document/level-0/ch07-xray-server.html index a2c112d0bd..38731e1469 100644 --- a/document/level-0/ch07-xray-server.html +++ b/document/level-0/ch07-xray-server.html @@ -24,8 +24,8 @@ 【第 7 章】Xray 服务器篇 | Project X - - + +

              【第 7 章】Xray 服务器篇

              7.1 博观而约取,厚积而薄发

              本文撰写过程中,大佬开玩笑的吐槽到:你这教程,居然连载了 6 章都还没到 Xray,不知道的还以为你是“手把手教你建网站”教程呢。(我竟无法反驳.jpg!)

              其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连nano都无法正确使用,也不会用WinSCP,远程手写编辑出来的config.json自然错误百出,连查错也变得举步维艰。

              注意

              经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray 时会有一种【水到渠成】的轻快感觉。

              后面要做的事情非常简单:

              1. 安装
              2. 配置(如安装 TLS 证书、config.json
              3. 运行
              4. 优化(如更新内核、开启bbr、网站http访问自动跳转https等)

              7.2 安装 Xray

              首先,Xray 的官方载体,就是 xray-coreopen in new tag 开源项目(基于 MPL 2.0 开源协议)生成的二进制程序。你把这个二进制放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。主要区别来源于【配置】。

              安装时,直接使用官方安装脚本就很简单直接。它提供了多种安装选项,有兴趣的可以去官方的安装脚本仓库open in new tag中看看脚本的说明,本文使用的是【非 root 用户】安装模式

              写本文时,安装脚本在使用非 root 账户时有一些小 bug,所以我决定正好把这几步分开操作,可以顺便说明一下 Linux 下的删除命令。

              1. 小小白白 Linux 基础命令:

                编号命令名称命令说明
                cmd-14rm删除命令
              2. 将安装脚本下载至本地:

                wget https://github.com/XTLS/Xray-install/raw/main/install-release.sh
                @@ -188,6 +188,6 @@
                 
                1. 修改 Xray 的回落设置,将回落从 80 端口改为 8080 端口。(找到 "dest": 80, 并改成 "dest": 8080
                sudo nano /usr/local/etc/xray/config.json
                 
                1. 重启 Xray 服务,即完成了设置
                sudo systemctl restart xray
                 
                1. 完整流程演示如下:

                http自动跳转https

                1. 当你输入 http://a-name.yourdomain.com的时候,它应该已经会自动跳转 https 了

                http自动跳转https生效

                7.9 服务器优化之三:更丰富的回落

                如果你需要更丰富的回落功能,可以参考 《回落 (fallbacks) 功能简析》

                7.10 你的进度

                恭喜!!到这一步,你已经拥有了可以正常科学上网的服务器、同时也有了可以防止主动探测攻击的伪装网站。接下来,只要给你的客户端装上合适的软件,就可以享受顺畅的网络了!

                ⬛⬛⬛⬛⬛⬛⬛⬜ 87.5%

                7.11 重要勘误

                1. 初版中Xray配置文件config.json文件夹位置错误。若你已经根据之前的位置进行了操作,Xray会无法正确启动。故勘误说明于此,请自查,造成不便十分抱歉!
                • 正确位置:/usr/local/etc/xray/config.json
                • 错误位置:/usr/local/etc/config.json

                受影响章节:

                • 7.4 配置Xray - 3. 使用nano创建Xray的配置文件
                • 7.8 服务器优化之二 - 6. 修改Xray的回落设置
                1. 初版中修改Nginx配置文件nginx.conf时内容错误(网页文件夹位置错误),若你已经根据之前的位置进行了操作,Nginx会无法找到正确的网站。请自查,造成不便十分抱歉!
                • 正确文件夹位置:root /home/vpsadmin/www/webpage;
                • 错误文件夹位置:root /var/www/website/html

                受影响章节:

                • 7.8 服务器优化之二 - 4. 在与 80 端口同级的位置增加一个本地端口监听来提供网页展示
              - + diff --git a/document/level-0/ch08-xray-clients.html b/document/level-0/ch08-xray-clients.html index 6b504b0ba5..bb1b7d5f73 100644 --- a/document/level-0/ch08-xray-clients.html +++ b/document/level-0/ch08-xray-clients.html @@ -24,8 +24,8 @@ 【第 8 章】Xray 客户端篇 | Project X - - + +

              【第 8 章】Xray 客户端篇

              8.1 Xray 的工作原理简述

              要正确的配置和使用Xray,就需要正确的理解其工作原理,对于新人,可以先看看下面简化的示意图(省略了许多复杂的设置):

              Xray数据流向

              这其中的关键点是:

              1. APP 要主动或借助转发工具,将数据【流入(inbounds)】Xray 客户端

              2. 流量进入客户端后,会被【客户端路由(routing)】按规则处理后,向不同方向【流出(outbounds)Xray 客户端。比如:

                1. 国内流量直连(direct
                2. 国外流量转发 VPS(proxy
                3. 广告流量屏蔽(block
              3. 向 VPS 转发的国外流量,会跨过防火墙,【流入(inbounds)】 Xray 服务器端

              4. 流量进入服务器端后,与客户端一样,会被【服务器端路由(routing)】按规则处理后,向不同方向【流出(outbounds)】:

                1. 因为已经在防火墙之外,所以流量默认直连,你就可以访问到不存在网站们了(direct
                2. 如果需要在不同的 VPS 之间做链式转发,就可以继续配置转发规则(proxy
                3. 你可以在服务器端继续禁用各种你想禁用的流量,如广告、BT 下载等(block

              注意

              请务必记得,Xray 的路由配置非常灵活,上面的说明只是无限可能性中的一种。

              借助 geosite.datgeoip.dat 这两个文件,可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 GFWList 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)

              现在,《路由 (routing) 功能简析》 已经上线,我建议对路由功能有兴趣的同学,先继续跟着本文完成客户端的基础配置,之后再去这里详细学习。

              8.2 客户端与服务器端正确连接

              现在你已经理解了 Xray 的工作原理,那么接下来的配置,其实就是【告诉你的客户端如何连接 VPS 服务器】。这和你已经很熟悉的、告诉PuTTY如何远程连接服务器是一样的。只不过 Xray 连接时的要素不止是【IP 地址】+【端口】+【用户名】+【密码】这四要素了。

              实际上,Xray的连接要素是由不同的协议决定的。本文在第 7 章的配置文件 config.json 里,我们使用 Xray 下独特而强大的 VLESS 协议 + XTLS 流控。所以看看那个配置文件的内容就能知道,这个协议组合的连接要素有:

              • 服务器【地址】: a-name.yourdomain.com
              • 服务器【端口】: 443
              • 连接的【协议】: vless
              • 连接的【流控】: xtls-rprx-vision (vision 模式适合全平台)
              • 连接的【验证】: uuiduuid-uuid-uuid-uuiduuiduuid
              • 连接的【安全】: "allowInsecure": false

              鉴于新人一般都会使用手机 APP 或者电脑的 GUI 客户端,我就把常用的客户端罗列在下面。每个客户端都有自己独特的配置界面,逐一截图展示并不现实,所以请你务必仔细阅读这些客户端的说明、然后把上述要素填入合适的地方即可。

              注意

              许多工具其实是同时支持 xray-corev2fly-core 的,但默认内置的不一定是哪个,所以别忘记检查一下是否是你想要的那个在工作哦!

              到这一步,你的全套配置就已经可以正常使用啦!

              8.3 附加题 1:在 PC 端手工配置 xray-core

              虽然到上面一步已经可以结束了,但是如果你是个好奇心强、记忆力好的的同学,一定会想起来我在上一章说过,你把xray-core 的二进制文件“放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。” 那究竟要怎样直接使用 xray-core 做客户端呢?

              为了回答这个问题,我加入了附加题章节,有一点点超纲,有一点点麻烦,但费这个笔墨是因为这个方式有它的优势:

              • 第一时间获得最新版而无需等待 APP 升级适配

              • 灵活自由的路由配置能力(当然 GUI 客户端中 Qv2ray 的高级路由编辑器非常强大,也可以完整实现 xray-core 的路由配置功能)

              • 节约系统资源 (GUI 界面一定会有资源消耗,消耗的多少则取决于客户端的实现)

              它的劣势应该就是【需要手写配置文件】有点麻烦了。但其实,你想想,服务器上你已经成功的写过一次了,现在又有什么区别呢?接下来,还是老样子,我们分解一下步骤:

              1. 首先请从 Xray 官方的 GitHub 仓库 Release 页面open in new tag 获取对应平台的版本,并解压缩到合适的文件夹

              2. 在合适的文件夹建立空白配置文件:config.json (自己常用平台下新建文件大家肯定都会,这就真不用啰嗦了)

              3. 至于什么是“合适的文件夹”?这就取决于具体的平台了~

              4. 填写客户端配置

                • 我就以 8.1 原理说明里展示的基本三类分流(国内流量直连、国际流量转发 VPS、广告流量屏蔽),结合 8.2 的连接要素,写成一个配置文件
                • 请将 uuid 替换成与你服务器一致的 uuid
                • 请将 address 替换成你的真实域名
                • 请将 serverName 替换成你的真实域名
                • 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
                // REFERENCE:
                @@ -181,6 +181,6 @@
                 

              8.4 附加题 2:在 PC 端手工运行 xray-core

              写好了配置文件该,要怎么让 xray-core 运行起来呢?双击好像并没有反应啊?

              首先,你要找到电脑上的【命令行界面】。

              1. Linux 桌面、macOS 系统的同学肯定已经比较熟悉了,搜索 Console 或者 Terminal 就可以
              2. Windows 就可以搜索使用 Cmd 或者 Powershell 等程序(WSL 的同学你坐下,你的 Console 当然也可以)

              其次,我们要做的事情是【让 xray 找到并读取配置文件 config.json,然后运行】,所以:

              1. 在 Windows 下,假设你的 Xray 程序位置是 C:\Xray-windows-64\xray.exe,配置文件位置是C:\Xray-windows-64\config.json,那么正确的启动命令就是:

                C:\Xray-windows-64\xray.exe -c C:\Xray-windows-64\config.json
                 

                说明

                这里的 -c 就是指定配置文件路径的参数,告诉 xray 去后面的位置找配置文件

              2. 相似的,在 Linux 和 macOS 下,假设你的 Xray 程序位置是 /usr/local/bin/xray,配置文件位置是/usr/local/etc/xray/config.json,那么正确的启动命令就是

                /usr/local/bin/xray -c /usr/local/etc/xray/config.json
                 

                说明

                每个系统都有系统路径变量,所以写 Xray 程序时不一定要写绝对路径。但是写了肯定没错,所以我就如此演示了。

              8.5 附加题 3:在 PC 端开机自动运行 xray-core

              如果你真的尝试了手动运行 xray-core,你一定会发现这个方式还有点小问题:

              1. 每次运行 Xray 都要出现一个黑乎乎的窗口,很丑
              2. 不能开机自动运行,每次都要手工输入,十分不方便

              我可以肯定的告诉你:完全可以解决。但是具体的解决方式,就当作课外作业留给大家吧!(友情提示,文档站的问答区有线索哦)

              8.6 圆满完成!

              我相信,有耐心看到这里的同学,都是兼具好奇心和行动力的学习派!我现在要郑重的恭喜你,因为到了这里,你已经完完整整的【从第一条命令开始,完成了 VPS 服务器部署,并成功的在客户端配置使用 Xray】了!这毫无疑问是一个巨大的胜利!

              我相信,你现在一定对Linux不再恐惧,对Xray不再陌生了吧!

              至此,小小白白话文圆满结束!

              ⬛⬛⬛⬛⬛⬛⬛⬛ 100%

              8.7 TO INFINITY AND BEYOND!

              但现在你看到的,远远不是 Xray 的全貌。

              Xray是一个强大而丰富的网络工具集合,平台化的提供了众多模块,可以像瑞士军刀一样,通过灵活的配置组合解决各种不同的问题。而本文,仅仅蜻蜓点水的用了最简单最直观的配置来做基础演示

              如果你觉得现在已经完全够用了,那就好好的享受它给你带来的信息自由。但如果你的好奇心依然不能停歇,那就去继续挖掘它无限的可能性吧!

              需要更多信息,可以到这里寻找:

              1. xtls.github.ioopen in new tag - 官方文档站
              2. 官方 Telegram 群组open in new tag - 活跃而友善的官方讨论社区

              TO INFINITY AND BEYOND!

              不算后记的后记

              希望我陪你走过的这一段小小的旅程,可以成为你网络生活中的一份小小助力。

              这篇文章里的工具和信息难免会一点点的陈旧过时,但你一定会逐渐成长为大佬。未来的某个时间,若你能偶尔想起这篇教程、想起我写下本文的初衷,那我衷心希望你能够薪火相传、把最新的知识分享给后来人,让这一份小小的助力在社区里坚定的传递下去。

              这是个大雪封山乌云密布的世界,人们孤独的走在各自的路上试图寻找阳光,如果大家偶尔交汇时不能守望相助互相鼓励,那最终剩下的,恐怕只有【千山鸟飞绝 万径人踪灭】的凄凉了吧。

              - + diff --git a/document/level-0/ch09-appendix.html b/document/level-0/ch09-appendix.html index 9a98e82f9a..a5965593e4 100644 --- a/document/level-0/ch09-appendix.html +++ b/document/level-0/ch09-appendix.html @@ -24,11 +24,11 @@ 【第 9 章】附录 | Project X - - + +

              【第 9 章】附录

              1. 小小白白 Linux 基础命令索引

              编号命令名称命令说明出现篇章
              cmd-01apt update查询软件更新《远程登录篇》
              cmd-02apt upgrade执行软件更新《远程登录篇》
              cmd-03nano文本编辑器《安全防护篇》
              cmd-04systemctl restart重启某个服务《安全防护篇》
              cmd-05adduser给系统新增用户《安全防护篇》
              cmd-06apt install安装某个软件《安全防护篇》
              cmd-07visudo修改 sudo 权限设置专用编辑器《安全防护篇》
              cmd-08sudoroot权限运行某个命令《安全防护篇》
              cmd-09chmod修改目标文件/文件夹的权限《安全防护篇》
              cmd-10mkdir新建文件夹《网站建设篇》
              cmd-11systemctl reload重新加载某个服务《网站建设篇》
              cmd-12wget访问(或下载)某个网页文件《证书管理篇》
              cmd-13acme.shacme.sh 证书管理相关的命令《证书管理篇》
              cmd-14rm删除命令《Xray 服务器篇》
              cmd-15crontab -e编辑当前用户的定时任务《Xray 服务器篇》
              cmd-16touch建立空白文件《Xray 服务器篇》
              cmd-17systemctlsystemd基本服务管理命令《Xray 服务器篇》
              cmd-18reboot重启 Linux 系统《Xray 服务器篇》

              2. 小小白白 Linux 重要配置文件索引

              编号配置文件位置文件说明出现篇章
              conf-01/etc/ssh/sshd_configSSH 远程登录程序设置《远程登录篇》
              conf-02/etc/nginx/nginx.confNginx 程序设置《网站建设篇》
              conf-03/etc/apt/sources.listapt 软件源列表《Xray 服务器篇》
              conf-04/etc/apt/sources.list.d/vpsadmin.list用户自定义软件源列表列表《Xray 服务器篇》
              conf-05crontab -e当前用户的定时任务《Xray 服务器篇》
              conf-06/etc/sysctl.conf手动设置 kernel 参数《Xray 服务器篇》
              conf-07/etc/sysctl.d/vpsadmin.conf用户自定义 kernel 参数配置文件《Xray 服务器篇》

              3. 小小白白 Xray 重要文件索引

              编号配置文件位置文件说明出现篇章
              xray-01/usr/local/etc/xray/config.jsonXray 程序设置《Xray 服务器篇》
              xray-02/home/vpsadmin/xray_cert/xray.certTLS 证书《Xray 服务器篇》
              xray-03/home/vpsadmin/xray_cert/xray.keyTLS 私钥《Xray 服务器篇》
              xray-04/home/vpsadmin/xray_log/access.logXray 访问日志《Xray 服务器篇》
              xray-05/home/vpsadmin/xray_log/error.logXray 错误日志《Xray 服务器篇》
              - + diff --git a/document/level-0/index.html b/document/level-0/index.html index bfab85505d..115583736c 100644 --- a/document/level-0/index.html +++ b/document/level-0/index.html @@ -24,11 +24,11 @@ 小小白白话文 | Project X - - + +

              小小白白话文

              这个章节是【从零开始】的基础课,新来的同学好好看好好学哦

              提示

              Made with ❤️ by @ricuhkaenopen in new tag

              【第 1 章】 前言罗嗦篇 - 机场还是自建?这是个问题

              【第 2 章】 原料准备篇 - 工欲善其事,必先利其器

              【第 3 章】 远程登录篇 - 一桥飞架南北,天堑变通途

              【第 4 章】 安全防护篇 - 安全不注意,亲人两行泪

              【第 5 章】 网站建设篇 - 秀出你的美

              【第 6 章】 证书管理篇 - 领证的才是合法的

              【第 7 章】 Xray 服务器篇 - 终于等到你

              【第 8 章】 Xray 客户端篇 - 新的开始

              【第 9 章】 附录 - 考点都在这里

              - + diff --git a/document/level-1/fallbacks-lv1.html b/document/level-1/fallbacks-lv1.html index ca11abbf8a..1f70e80beb 100644 --- a/document/level-1/fallbacks-lv1.html +++ b/document/level-1/fallbacks-lv1.html @@ -24,8 +24,8 @@ 回落 (fallbacks) 功能简析 | Project X - - + +

              回落 (fallbacks) 功能简析

              在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。

              1. 回顾《小小白白话文》中的回落

              如果你用了《小小白白话文》中的Xray 配置,并完成了HTTP 自动跳转 HTTPS 优化,那么你已经有了基于 VLESS 协议的简易回落:

              {
              @@ -200,6 +200,6 @@
                 }
               }
               
            2. 至此,我们就能够完整的画出模板的回落路线了:

            6. 结语

            至此,Xray 的【回落】功能就介绍完了。希望本文能够对你理解 Xray 的强大有所帮助。

            7. 附加题

            我再无耻的留一个附加题:本文详解的 VLESS-TCP-XTLS-WHATEVERopen in new tag 模板?是否有可以优化的地方?

            提示:HTTP 自动跳转 HTTPS

        - + diff --git a/document/level-1/fallbacks-with-sni.html b/document/level-1/fallbacks-with-sni.html index 77723674d5..c8489f1ff9 100644 --- a/document/level-1/fallbacks-with-sni.html +++ b/document/level-1/fallbacks-with-sni.html @@ -24,8 +24,8 @@ SNI 回落 | Project X - - + +

        通过 SNI 回落功能实现伪装与按域名分流

        VLESS 是一种很轻的协议,和 Trojan 一样,不对流量进行复杂的加密和混淆,而是大隐隐于市,通过 TLS 协议加密,混杂在其他 HTTPS 流量中,在墙内外穿进穿出。为了更好的伪装以应对主动探测,Fallbacks 回落功能随 VLESS 同时出现。这篇教程将演示如何使用 Xray 中 VLESS 入站协议的回落功能配合 Nginx 或 Caddy 在保证伪装完全的前提下实现按域名分流。

        应用情景

        由于 XTLS,Xray 需要监听 443 端口,这导致如果之前有网站运行在服务器上,那么此时网站无法运行或需要运行在其他端口上,这显然是不合理的。有以下三种方案可以解决这个问题:

        • Xray 监听其他常用端口(如 22、3389、8443)

          这个方案是最简单的,但不够完美。

        • Nginx 或 HAProxy 监听 443 端口,通过 SNI 分流做 L4 反向代理,实现端口复用

          这个方案比较复杂,需要对 Nginx 或 HAProxy 的使用有一定了解,此处不作过多解释。

        • Xray 监听 443 端口,通过 Fallbacks 功能 SNI 分流将网站流量回落到 Nginx 或 Caddy

          这个方案难度适中,也是此教程接下来想要演示的方案。

        SNI 简介

        服务器名称指示(英语:Server Name Indication,缩写:SNI)是 TLS 的一个扩展协议。熟悉反向代理的朋友都知道,如果想要通过域名将流量代理到正确的内容上,需要以下配置:

        proxy_set_header Host 主机名;
        @@ -210,6 +210,6 @@
             redir https://{host}{uri} permanent
         }
         

        参考

        1. 服务器名称指示 - 维基百科,自由的百科全书open in new tag
        2. Home · acmesh-official/acme.sh Wikiopen in new tag
        3. HTTP/2 - 维基百科,自由的百科全书open in new tag

        引用


        1. 常见问题 - Let's Encrypt - 免费的 SSL/TLS 证书open in new tag ↩︎

        2. Proxy Protocol - HAProxy Technologiesopen in new tag ↩︎

        3. proxy protocol 介绍及 nginx 配置 - 简书open in new tag ↩︎

        4. v2fly-github-io/vless.md at master · rprx/v2fly-github-ioopen in new tag ↩︎

        - + diff --git a/document/level-1/index.html b/document/level-1/index.html index 73077bf792..928c15d942 100644 --- a/document/level-1/index.html +++ b/document/level-1/index.html @@ -24,11 +24,11 @@ 入门技巧 | Project X - - + +
        - + diff --git a/document/level-1/routing-lv1-part1.html b/document/level-1/routing-lv1-part1.html index e63f54aec1..a35e4db5d3 100644 --- a/document/level-1/routing-lv1-part1.html +++ b/document/level-1/routing-lv1-part1.html @@ -24,8 +24,8 @@ 路由 (routing) 功能简析(上) | Project X - - + +

        路由 (routing) 功能简析(上)

        如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。

        1. 初识【路由】三兄弟

        要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. 入站;2. 路由;3. 出站

        路由三兄弟

        三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。

        所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。

        因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。

        啰嗦君

        路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。

        2. 基本功: “兄弟一条心”

        下图的示例,就是在客户端的 Xray 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。

        下面我们来逐个分析:

        2.1 入站

        提示

        入站: 就是流量如何流入 Xray

        下面的入站配置示例,用大白话说就是:数据按照 socks 协议,通过 10808 端口,从本机 127.0.0.1 流入Xray。同时,Xray 将这个入站用 [tag] 命名为 inbound-10808

        {
        @@ -141,6 +141,6 @@
           ]
         }
         

        此时,路由规则其实变成了:

        这就是路由功能的灵活之处了,你可以自由的改变它的顺序来实现不同的设计。

        至此,我们已经解释完了 【如何利用 geosite.dat 文件,通过路由规则,根据【域名】来分流网络流量】。

        5. 攻城略池 - 多种路由匹配条件

        请确保你已经读懂了上面的内容,因为这样,你就已经理解了【路由】功能的工作逻辑。有了这个基础,我们就可以继续分析【路由】功能更多更详细的配置方式和匹配条件了。

        等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 《路由 (routing) 功能简析(下)》 吧!

        - + diff --git a/document/level-1/routing-lv1-part2.html b/document/level-1/routing-lv1-part2.html index a4bd0c43ce..5a81f97213 100644 --- a/document/level-1/routing-lv1-part2.html +++ b/document/level-1/routing-lv1-part2.html @@ -24,8 +24,8 @@ 路由 (routing) 功能简析(下) | Project X - - + +

        路由 (routing) 功能简析(下)

        欢迎继续学习 Xray 的【路由】功能!

        《路由 (routing) 功能简析(上)》 中,我们已经对【路由】功能的工作逻辑有了清晰的理解,也基于 geosite.dat 文件做了简单的域名分流配置。

        如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!

        5. 攻城略池 - 多种路由匹配条件

        [域名], [IP], [协议], etc.

        基于域名的分流,已经可以让我们对网络流量进行基本合理的分流。为什么说【基本合理】呢?

        因为【三分天下】虽然是正确的战略方向,但如果只用【域名】来实现这个战略,其实漏洞百出,比如:

        1. 我读了《小小白白话文》后,给 VPS 新申请了一个 proxy.yourdomain.com 的域名, 我希望它无论如何都代理,geosite.dat 里面有吗?
        2. 如果我还有个 direct.yourdomain.com 的域名,我希望它无论如何都直连, geosite.dat 里面有吗?
        3. 本机 127.0.0.1 的内部流量,是否正确直连了?(比如 docker 等)
        4. 路由器、本地局域网 192.168.*.* 的流量,是否正确直连了?(比如路由器、群晖等)
        5. 我的国内 DNS 查询(如 223.5.5.5)是否正确直连了?
        6. 我的国外 DNS 查询(如 1.1.1.1)是否正确代理了?
        7. 其他类似国内公共 DNS 一样没有域名、只有 IP 地址的国内网站,是否正确直连了?
        8. 其他类似国外公共 DNS 一样没有域名、只有 IP 地址的国外网站,是否正确代理了?
        9. BT 下载的流量,虽然来源是国外,但如果通过 VPS 下载很可能导致违规使用被封,这该如何强制直连?
        10. ......

        我之所以说只用【域名分流】会漏洞百出,是因为 geosite.dat 文件内只包含了一部分常用的域名。换言之,仅仅依赖它,则会:

        • 无法匹配文件里没有的新域名
        • 无法匹配基于 IP 地址的规则
        • 无法匹配基于网络协议的规则

        啰嗦君

        那我们来复习一下,当上面这些情况无法匹配时,会发生什么?对了,会触发隐藏路由规则,即【转发给第一个出站 】。这其实就是说:

        • 当你的第一个出站是 [direct-out] 时:需要直连的都正确了,但需要代理的则都错误
        • 当你的第一个出站是 [proxy-out-vless] 时:需要代理的都正确了,但需要直连的则都错误

        所以,我们需要一个办法,让我们鱼与熊掌兼得。这样的办法是否存在呢?当然存在! 我们需要的只是【域名】之外更多的【分流判断依据】而已。

        5.1 基于指定域名分流:[domain], [full]

        1. 如果需要匹配某个子域名,如 a-name.yourdomain.com,我们使用 full: "a-name.yourdomain.com"
        2. 前面的 问题1问题2,就可以通过给 proxy.yourdomain.com 指定 [proxy-out-vless] 出站,给 direct.yourdomain.com 指定 [direct-out] 出站来解决
        3. 如果需要匹配 yourdomain.com 的所有子域名,我们使用 domain: "yourdomain.com" 实现
        4. 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
        5. 另外,[domain] 还支持正则表达式等匹配方式。详情请参考 《基础配置模块 - 路由》文档

        上述配置如下:

        {
        @@ -187,6 +187,6 @@
           }
         }
         

        其实,第 6 点已经是我整理过的规则了,原则就是【相同的匹配依据可以合并,不同的匹配依据保持独立】。

        8. 明修栈道、暗渡陈仓

        [domain] 转化 [ip] 的密道:domainStrategy

        我们在 5.4 中提交了多种流量判断的【依据】,其中一种是域名 [domain]、一种是 [IP]

        如果你初步了解过 DNS 的运作过程,就会知道,我们对一个域名 [domain] 发起访问请求时,其实需要先向 DNS 发起请求来解析域名 [domain] 对应的 [IP],在得到 [IP] 后再向它发起实际请求。

        所以,面对入站的一次域名请求,Xray 其实有两次机会去判断它的类型。那么,究竟是否要用这两次机会呢?这就是由 domainStrategy 这个配置来决定的。它有三个选项:

        • AsIs
        • IPIfNonMatch
        • IPOnDemand

        按么我们逐个来解释一下:

        8.1 域名策略: "AsIs"

        就是 "As Domain Is",也就是说 【域名什么样,就什么样,不多折腾】。

        简单粗暴理解就是说【仅用 [domain] 来匹配】。

        提示

        AsIs 的实际意义为 【如原先所示,不加修改】,🍉 老师这里描述的不是很恰当。

        这个方式的处理都在 Xray 内部完成,没有与外界的数据往来,所以速度最快。它的兜底策略也很清晰:即前面所说的、无法匹配的域名自动转入第一条出站处理。所以,对于常规使用路由功能这最推荐的策略。

        8.2 域名策略: "IPIfNonMatch"

        就是 "lookup IP if (there's) no matching rule",也就是说【如果其他所有规则都匹配不上,那就转化成 IP 去匹配 IP 规则】。

        简单粗暴理解就是说【先把访问目标和其他所有类型规则匹配,如果匹配不上,那就通过 DNS 查询转化成 IP,再从头和所有规则匹配一次】。

        该策略下没有命中任何规则的这一部分域名,会需要再经历 DNS 查询过程、以及第二轮规则匹配的过程,其耗时会多于 AsIs 策略,所以并不是首选推荐的策略。

        8.3 域名策略: "IPOnDemand"

        这里其实说 Demand IP 更准确些,也就是说【当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配】。

        简单粗暴理解就是说【只要路由规则中有 IP 类规则,那么所有基于域名 [domain] 的请求都要解析成 [IP] 然后去匹配 [IP] 类规则】。

        它要对所有首次域名访问进行 DNS 解析,所以首次查询比较耗时。虽然由于 XrayDNS 缓存机制的存在,后续对相同域名的访问速度会重回巅峰,但总体来说也不是首选推荐的策略。

        啰嗦君

        domainStrategy 仅对域名生效,不要搞混了哦~

        9. 思考题

        迄今为止,我们都是在【单入站】和【单出站】的基础上,讲解【路由】内部的各种配置逻辑。

        但是,如你所知,Xray 本身是支持多端口,多协议的。那么,如果我问你:

        1. 我希望 VLESS 协议将我日常的网页浏览和 APP 流量转发给美国的大流量服务器
        2. 我希望 trojan 协议将我的所有 Netflix 流量转发给日本的服务器解锁各种二次元
        3. 我希望 shadowsocks 协议将我所有的游戏流量转发给香港的服务器达到最低的延迟
        4. 我希望有一个独立的端口,能够把 telegram 的流量全都转发给 VPS
        5. 我希望有一个独立的端口,能够把 bittorrent 下载流量全都转发给欧洲大盘鸡
        6. 我希望......

        这些想法,是否能通过【路由】功能配置实现呢?

        答案当然是 【完全可以】 啦! 但是这些对于 level-1 来说已经超纲了,就留给各位自由的探索吧!

        10. 结语

        至此,Xray 的【路由】功能就介绍完了。希望本文能够对你理解 Xray 的灵活有所帮助。

        11. 尾注

        • 现在你可以重新阅读一遍 路由,看看是否有更加深刻的理解。
        • 🍉🍉🍉🍉🍉 😄
        - + diff --git a/document/level-1/work.html b/document/level-1/work.html index 1b97ee7350..3c5ce82c6c 100644 --- a/document/level-1/work.html +++ b/document/level-1/work.html @@ -24,11 +24,11 @@ Xray 的工作模式 | Project X - - + +

        Xray 的工作模式

        单服务器模式

        与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。

        一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。

        桥接模式

        如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。

        工作原理

        在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。

        • 需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。
          • 入站连接负责与客户端(如浏览器)通信:
            • 入站连接通常可以配置用户认证,如 ID 和密码等;
            • 入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;
          • 出站连接负责将数据发给服务器,如另一台主机上的 Xray。
        • 当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。
          • 路由会在必要时查询 DNS 以获取更多信息来进行判断。
        - + diff --git a/document/level-2/index.html b/document/level-2/index.html index 45c30184d3..4344417006 100644 --- a/document/level-2/index.html +++ b/document/level-2/index.html @@ -24,11 +24,11 @@ 进阶文档 | Project X - - + +

        进阶文档

        这个章节包含进阶级的 Xray 使用心得分享, 如果您已经熟悉 Xray, 那么这里的经验可以让您更加发挥 Xray 的威力

        透明代理入门 by a @kirinopen in new tag

        透明代理的入门篇章。

        透明代理(TProxy)配置教程 by a @BioniCosmosopen in new tag

        基于 Xray 的透明代理(TProxy)配置完整教程。

        TProxy 透明代理(ipv4 and ipv6)配置教程 by a @SQLimitopen in new tag

        基于 Xray 的 TProxy 透明代理(ipv4 and ipv6)配置教程

        Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹 by a @SQLimitopen in new tag

        双端使用 Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹

        [透明代理]通过 gid 规避 Xray 流量 by a @kirinopen in new tag

        在 iptables/nftables 实现的透明代理中,一种新的规避 Xray 流量的方式。

        通过 Xray 将特定的流量指向特定出口,实现全局路由“分流” by a @Zzz3mopen in new tag

        将 Xray 玩出花:基于 fwmark 、 sendThrough 或 sockopt.interface 方式实现“分流”。

        通过 Cloudflare Warp 增强代理安全性 by a @yuhan6665open in new tag

        Xray v1.6.5 新增 WireGuard 出站的使用介绍。

        Xray 流量统计 by a @yuhan6665open in new tag

        适配 Xray 的流量统计和脚本。

        - + diff --git a/document/level-2/iptables_gid.html b/document/level-2/iptables_gid.html index 42defd918e..dcddb4a06f 100644 --- a/document/level-2/iptables_gid.html +++ b/document/level-2/iptables_gid.html @@ -24,8 +24,8 @@ GID 透明代理 | Project X - - + +

        透明代理通过 gid 规避 Xray 流量

        在现有的 iptables 透明代理白话文(新 V2Ray 白话文指南-透明代理open in new tag新 V2Ray 白话文指南-透明代理(TPROXY)open in new tag透明代理(TProxy)配置教程)教程中,对 Xray 流量的规避处理是打 mark 实现的。即对 Xray 出站流量打 mark,通过设置 iptables 规则对对应 mark 的流量直连,来规避 Xray 流量,防止回环。

        这么做有以下几个问题:

        1. 莫名流量进入 PREROUTING 链open in new tag

        2. 安卓系统有自己的 mark 机制,该方案在安卓上不可用

        本教程的方案不需要设置 mark,理论性能更高,同时也不存在上述问题。

        思路

        tproxy 流量只能被 root 权限用户(uid==0)或其他有 CAP_NET_ADMIN 权限的用户接收。

        iptables 规则可以通过 uid(用户 id)和 gid(用户组 id)分流。

        让 Xray 运行在一个 uid==0 但 gid!=0 的用户上,设置 iptables 规则不代理该 gid 的流量来规避 Xray 流量。

        配置过程

        1. 前期准备

        安卓系统

        1. 系统已 root

        2. 安装 busyboxopen in new tag

        3. 有一个可以执行命令的终端,可以使用 adb shell,termux 等。

        其它 Linux 系统

        需要依赖 sudo,iptables 的 tproxy 模块和 extra 模块。

        一般系统都有自带,openwrt 运行:

        opkg install sudo iptables-mod-tproxy iptables-mod-extra
        @@ -126,6 +126,6 @@
         ip6tables -t mangle -A OUTPUT -p tcp -j XRAY6_MASK
         ip6tables -t mangle -A OUTPUT -p udp -j XRAY6_MASK
         
        - + diff --git a/document/level-2/nginx_or_haproxy_tls_tunnel.html b/document/level-2/nginx_or_haproxy_tls_tunnel.html index 9ceb669601..c4f7a08532 100644 --- a/document/level-2/nginx_or_haproxy_tls_tunnel.html +++ b/document/level-2/nginx_or_haproxy_tls_tunnel.html @@ -24,8 +24,8 @@ Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹 | Project X - - + +

        Nginx 或 Haproxy 实现的 HTTPS 隧道、HTTP/2 over HTTPS 隧道、WebSocket over HTTP/2 over HTTPS 隧道、gRPC over HTTP/2 over HTTPS 隧道以及自签证书双端认证的 gRPC over HTTP/2 over HTTPS 隧道

        客户端服务端 Nginx 构建 HTPPS 隧道隐藏指纹

        网路结构:

        xray_client ---tcp--- nginx_client ---HTTPS--- nginx_sever ---tcp--- xray_server

        编译 nginx --with-stream

        在客户端及服务端均编译

        curl -O -L http://nginx.org/download/nginx-1.22.1.tar.gz

        tar -zxvf nginx-1.22.1.tar.gz

        cd nginx-1.22.1

        apt install gcc make //编译依赖 gcc 以及 make

        ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-stream --with-stream_ssl_module //此步需要依赖一些库,根据报错安装相应 lib

        make && make install

        编译之后 nginx 文件夹位于 /usr/local/nginx

        配置 nginx

        编辑 nginx 配置文件 nginx.conf

        vim /usr/local/nginx/conf/nginx.conf

        服务端加入如下配置

        服务器申请证书不再赘述,参考白话文open in new tag

        stream {
        @@ -548,6 +548,6 @@
         backend web
             server web /dev/shm/h1h2c.sock
         

        xray 配置

        简单的 gRPC 配置,无需 TLS,配置见文档,配置的 serviceName 可用于分流。

        - + diff --git a/document/level-2/redirect.html b/document/level-2/redirect.html index 0a9c6e0b1c..2a67b29fec 100644 --- a/document/level-2/redirect.html +++ b/document/level-2/redirect.html @@ -24,8 +24,8 @@ 出站流量重定向 | Project X - - + +

        基于 fwmark 或 sendThrough 的流量重定向

        通过 Xray 将特定的流量指向特定出口,实现全局路由“分流”

        前言

        之前在网络上看到许多代理或者 VPN 会接管全局路由,如果与 Xray 同时安装,会导致 Xray 失效。参考了网络上许多教程,及时分流,也是通过维护一张或者多张 CIDR 路由表来实现的。这种情况下并不优雅,如果我想可以任意替换,实现按需分流,那有没有更好的办法呢?有!

        通过 fwmark 或 Xray 的 sendThrough/sockopt.interface,再简单配合路由表功能即可实现:

        1. Xray 可设置指定的 Tag、域名等走指定接口。如果您的接口是双栈的,可以指定 IPV4 或者 IPV6
        2. 其余用户则走原 IPV4 或者 IPV6

        具体设置如下(以 Debian10 为例):

        1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)

        根据不同系统和不同软件,请参考官方安装方法

        2、编辑 VPN 配置文件(以 WireGuard 为例)

        原始文件:

        [Interface]
        @@ -168,6 +168,6 @@
         

        开机自启

        systemctl enable wg-quick@wg0
         systemctl start wg-quick@wg0
         

        验证 IPv4/IPv6

        在代理上 运行 curl ip-api.com -4/-6 / 浏览器访问ip-api.com

        后记

        本文本意是可以避免的多余的流量浪费,将路由和分流的功能交给 Xray 处理。避免了维护路由表的繁琐工作。顺便技术提升 UP。

        感谢

        XTLS/Xray-coreopen in new tag; v2fly/v2ray-coreopen in new tag; WireGuardopen in new tag; @p3terxopen in new tag; @w; @Hiram; @Luminous; @Ln; @JackChou;

        - + diff --git a/document/level-2/tproxy.html b/document/level-2/tproxy.html index 61e6f8886d..3afdea5762 100644 --- a/document/level-2/tproxy.html +++ b/document/level-2/tproxy.html @@ -24,8 +24,8 @@ TProxy 透明代理 | Project X - - + +

        透明代理(TProxy)配置教程

        本配置基于TProxy 透明代理的新 V2Ray 白话文教程open in new tag,加入了 Xray 的新特性,使用 VLESS + XTLS Vision 方案,并将旧教程中默认出站代理的分流方式改为默认出站直连,使用者请按照实际情况进行修改。

        本文中所有配置已在 Raspberry Pi 2B、Ubuntu 20.04 环境下测试成功,如在其它环境中使用请自行调整配置。

        开始之前

        请检查您的设备是否有可用的网络连接,且服务端已经配置成功,客户端已经安装完毕。

        需注意的是,目前很多透明代理教程都会将 Linux 系统的 IP 转发打开,但这样会导致 Splice 性能下降。详情请参考大案牍术破案纪实第三篇--我们是如何破解 Splice 性能下降甚至低于 Direct 之谜的open in new tag

        这里我想要补充的是,很多透明代理教程会使用 Netfilter 进行分流,使直连流量直接发出而不经过 Xray,这时必须开启 IP 转发;也有的教程,如本文,会将所有流量导入 Xray 之中,由 Xray 的路由模块进行分流,这时无需开启 IP 转发。

        Xray 配置

        为了更好的分流体验,请替换默认路由规则文件为 Loyalsoldier/v2ray-rules-datopen in new tag,否则 Xray-core 将无法加载本配置。

        sudo curl -oL /usr/local/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
        @@ -281,6 +281,6 @@
         [Install]
         WantedBy=multi-user.target
         
    - + diff --git a/document/level-2/tproxy_ipv4_and_ipv6.html b/document/level-2/tproxy_ipv4_and_ipv6.html index f3f0d54c48..9cf701145d 100644 --- a/document/level-2/tproxy_ipv4_and_ipv6.html +++ b/document/level-2/tproxy_ipv4_and_ipv6.html @@ -24,8 +24,8 @@ TProxy 透明代理 (ipv4 and ipv6) | Project X - - + +

    TProxy 透明代理(ipv4 and ipv6)配置教程

    本配置参考了TProxy 透明代理的新 V2Ray 白话文教程open in new tag透明代理(TProxy)配置教程open in new tag以及透明代理通过 gid 规避 Xray 流量open in new tag,加入了透明代理对 ipv6 的支持,并且使用 VLESS-TCP-XTLS-RPRX-Vision 方案对抗封锁 (推荐使用 1.7.2 及之后版本)。

    关于 Xray 的配置并不是本文重点,使用者可依实际情况进行修改,具体可以参考官方文档示例open in new tag或其他优秀示例 比如@chika0801open in new tag 又如@lxhao61open in new tag

    注意

    若使用其他配置,你需要着重注意客户端配置中 outboundtagproxy 的部分,其他部分不变

    服务端配置也要同时改变

    此配置意在解决例如 Netflix 等默认使用 ipv6 连接的网站无法通过旁路由进行代理的问题,或对 ipv6 代理有需要。

    本文网络结构为单臂旁路由

    本文中所有配置已在 Arch Linux (Kernel: 6.0.10) 环境下测试成功,如在其它环境中同理

    注意安装相应程序 # sudo apt install iptables ip6tables# sudo apt install nftables

    若旁路由未安装 xray 程序,可以手动下载相应 xray 程序如 Xray-linux-64.zipopen in new tag ,然后复制 install-release.shopen in new tag 文件到旁路由,赋予可执行权限 # chmod 700 install-release.sh,然后使用 # ./install-release.sh --local Xray-linux-64.zip 根据提示进行本地安装。

    Xray 配置

    客户端配置

    {
    @@ -429,6 +429,6 @@
     [Install]
     WantedBy=multi-user.target
     
    1. 最后执行 systemctl enable tproxyrules 命令。

    tproxyrules.service

    注意其中主路由器 IP 地址,根据实际修改

    ExecStartPre=/bin/sh -c 'until ping -c1 192.168.31.1; do sleep 1; done;' 命令为确保获得 IP 地址后再执行命令,否则会诡异报错,其中 IP 地址为主路由器地址,根据实际修改。

    注意

    如果通过 dhcpcd 等设置了静态 IP 及网关,则上述相关 ip route add/del 设置需删除

    局域网设备上网设置

    此处假定旁路由 ipv4, ipv6 地址分别为192.168.31.100, fd00:6868:6868::8866, 旁路由的 ipv4, ipv6 地址可由命令ip add获得。

    方法一

    局域网设备上网有两种方式,第一种就是在使用设备上进行静态 IP 的配置,将网关指向旁路由 IP。注意绝大部分手机仅支持手动配置 ipv4 网关,不支持手动配置 ipv6 网关,除非 root 后进行相关设置。

    以 windows 设备为例,可以先开启 DHCP 记录自动分配的 IP 以参考,然后手写静态配置。

    DNS 设置

    此配置劫持 DNS 流量,DNS 可以随便写

    建议设置为旁路由 IP,防止 DNS 泄露

    image image

    方法二

    局域网设备上网的第二种方式,是在路由器上进行网关设置,这种方法对于连接到此路由器的设备无需做任何设置即可科学上网,但注意有些路由器不支持 ipv6 的网关设置,有 ipv6 需求的设备仍需在所需设备上单独手动配置 ipv6 相关设置参考方法一。

    image

    Finally

    按照以上方法设置后设备即可双栈访问,进入测试网站比如 https://ipv6-test.com/ 可以看到如下结果 (需要代理此网站才能看到如下结果)

    image

    写在最后

    如今 ipv6 并未完全普及,我们日常访问的流量 99%仍为 ipv4 流量;很多 VPS 商家虽然提供 ipv6 地址,但线路优化非常垃圾,甚至处于不可用状态,为何要加入 ipV6 的设置?

    可以看到目前 ipv6 处于很尴尬的境地,各种设备对于 ipv6 的支持很烂,但是都在逐步完善,同时 Windows 系统对于 ipv6 的优先级也在提高,很多浏览器也会优先进行 ipv6 的解析以及访问,很多网站也开始默认使用 ipv6 进行访问(比如 Netflix, 如果没有配置 ipv6, 浏览器打开 Netflix 会显示 Not Available 是因为没有代理 Netflix 的 ipv6 请求,当然可以选择禁用 Windows 的 ipv6,但支持 ipv6 的 pt 站就无法使用)

    这种情况下 ipv4 无法完全胜任网络冲浪的需求,即使是那 1%的流量,遇到了也会让人头疼不已。

    而可以预见 ipv6 也会逐步与 ipv4 分庭抗礼,所以有必要加入 ipv6 的设置。

    - + diff --git a/document/level-2/traffic_stats.html b/document/level-2/traffic_stats.html index 8dafa9cb87..ab0e977b3d 100644 --- a/document/level-2/traffic_stats.html +++ b/document/level-2/traffic_stats.html @@ -24,8 +24,8 @@ 流量统计 | Project X - - + +

    流量统计配置教程

    请熟悉流量统计 白话文教程open in new tag,本文在其基础上适配了 Xray(1.5.9+)。

    查看流量信息

    配置方法与 v2fly 一致。 查看流量信息是 xray 命令行的其中一个功能。配置内设置的 api dokodemo-door 端口,即为 --server 参数的端口。

    xray api statsquery --server=127.0.0.1:10085 #查看所有流量
    @@ -120,6 +120,6 @@
     print_sum "$DATA" "user"
     echo "-----------------------------"
     
    - + diff --git a/document/level-2/transparent_proxy/transparent_proxy.html b/document/level-2/transparent_proxy/transparent_proxy.html index fad9623084..e9b0c39d72 100644 --- a/document/level-2/transparent_proxy/transparent_proxy.html +++ b/document/level-2/transparent_proxy/transparent_proxy.html @@ -24,8 +24,8 @@ 透明代理入门 | Project X - - + +

    透明代理入门

    什么是透明代理

    透明代理简单地说就是不让被代理的设备感觉到自己被代理了。简单地说就是,被代理的设备上不需要运行任何代理软件(比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。

    这也意味着,代理的软件运行在别的地方,比如运行在路由器中,通过路由器上网的设备就自动被代理了。

    透明代理的实现

    透明代理的实现目前主要有两种方式:

    tun2socks

    可用 Windows/Linux(包括安卓)实现。因为实现过程比较简单,很少有教程,我这里简单描述一下。

    Windows

    1. 安装 Netchopen in new tag ,使用模式[3] [TUN/TAP] 绕过局域网启动。

    2. 开启热点

    3. 打开控制面板->网络和 Internet->网络和共享中心->更改适配器设置,找到TAP-Windows AdapterMicrosoft Wi-Fi Direct Virtual Adapter

    4. 鼠标右键点击TAP-Windows Adapter属性->共享,勾选允许其他网络用户通过此计算机的 Internet 连接来连接,在家庭网络连接中选择Microsoft Wi-Fi Direct Virtual Adapter的那个网络连接,点击确定。

    Android

    1. 配置连接 V2RayNG

    2. 开启热点

    3. 热点设置 -> 允许热点使用 VPN(部分安卓系统可能没有这个选项)

    iptables/nftables

    iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。

    基于 iptables 的透明代理实现只能用于 Linux 系统(包括 openwrt/安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而广泛使用。

    现存的三篇白话文透明代理教程其实讲的都是基于这种方案的透明代理实现,它们是: 新 V2Ray 白话文指南-透明代理open in new tag新 V2Ray 白话文指南-透明代理(TPROXY)open in new tag透明代理(TProxy)配置教程 。其中第一篇是基于 iptables-redirect 模式,已经过时了,不建议使用,仅供参考。第二篇和第三篇讲的都是基于 iptables-tproxy 模式的透明代理实现。

    iptables 实现透明代理原理

    Linux 使用Netfilter来管理网络,Netfilter模型如下:

    Netfilter

    假设使用路由器作为网关(即我们平时的上网方式),那么:

    局域网设备通过路由器访问互联网的流量方向:

    PREROUTING链->FORWARD链->POSTINGROUTING链

    局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:

    PREROUTING链->INPUT链->网关本机

    路由器访问互联网的流量方向:

    网关本机->OUTPUT链->POSTINGROUTING链

    通过使用 iptables 操控PREROUTING链OUTPUT链的流量走向,转发到 Xray,就可以代理局域网设备和网关本机。

    透明代理难在哪里

    透明代理的难点就在于路由,所谓路由,就是区分哪些流量是直连的,哪些该被代理,所以我个人认为叫做分流更加合适。

    我们可以把路由由易到难分为以下几个阶段:

    1. 代理全部请求

    2. 本地局域网 IP/组播 IP 请求直连,其它请求代理

    3. 在 2 的基础上直连 Xray 发起的连接请求

    4. 在 3 的基础上直连指向中国大陆 IP 的连接请求,并对国内外域名选择国内外 DNS 服务器解析。

    上面说的三篇教程,都是在第四阶段。所以新手直接阅读可能显得有点难懂。

    从零开始一步步实现基于 iptables-tproxy 的透明代理

    在开始之前,你需要有一定的基础知识:

    1. 大概知道什么是 TCP/IP 协议、域名和 DNS 服务器

    2. 知道什么是 WAN 口,LAN 口,LAN_IP,WAN_IP 以及 DHCP 服务器。对于旁路由,只有一个网口,这里称其为 LAN 口

    3. 对 Linux 系统有最基础的了解(知道怎么运行命令)

    4. 能够手写客户端 json 文件配置,至少要能看懂

    前期准备工作

    注意

    在开始操作前,记得使用 sysctl -w net.ipv4.ip_forward=1 打开linux ipv4封包转发

    1. 准备一个运行 Linux 系统的网关

    比如,刷了 OpenWRT 的路由器

    2. 在网关(路由器)准备好 Xray 可执行文件以及配置文件

    配置文件监听 12345 端口,开启 tproxy:

    {
    @@ -111,6 +111,6 @@
     iptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK
     iptables -t mangle -A OUTPUT -p udp -j XRAY_MASK
     

    但是这么配置有个缺点,如果使用 CDN 或者 VPS 很多的话,就不好写规则了。

    1. 通过 mark 规避

    三个白话文教程都是使用这种方法规避,自行参考,这里不再赘述。

    1. 通过 gid 规避(推荐)

    参考 [透明代理]通过 gid 规避 Xray 流量

    这样就完成了第三阶段的代理,也就是平时说的全局代理。但是记得把网关的 DNS 服务器设置为国外的 DNS 服务器,否则可能依然返回被污染的结果。

    第四阶段

    其实,并不是所有人都需要实现第四阶段。全局代理对于大部分情况已经适用。

    特别是对于旁路由而言。需要代理时,将网关调成旁路由的 IP,不需要代理时,将网关换回主路由 IP。

    至于第四阶段的具体实现,那三篇白话文教程讲的都是。在理解了上面的内容后,再去看那三篇白话文教程,就比较容易理解了。

    代理 ipv6

    上面的规则只对 ipv4 生效,如果还想要代理 ipv6 请求,则使用 ip6tables 命令,用法与 iptables 基本相同。参考 [透明代理]通过 gid 规避 Xray 流量#4-设置 iptables 规则

    iptables 透明代理的其它注意事项

    1. 如果作为代理的网关作为主路由,要在PREROUTING链规则中加一条iptables -t mangle -A XRAY ! -s 网关LAN_IP地址段 -j RETURN,即在第一阶段使用、第二阶段被删除的指令。如果不写,WAN 口中同网段的其它人可以将网关填写成你的 WAN_IP,从而蹭你的透明代理用,还可能带来一定的危险性。

    2. 新 V2Ray 白话文指南-透明代理(TPROXY)#设置网关open in new tag 中的第三条说:手动配置 PC 的网络,将默认网关指向树莓派的地址即 192.168.1.22。此时 PC 应当能正常上网(由于还没设置代理,“正常”是指可以上国内的网站)。实际上,Ubuntu、CentOS、debian 等系统就算开启了 IP 转发,PC 也不能正常上网,这是正常的。事实上只有 OpenWRT 能做到文中所描述的那样,据 @BioniCosmosopen in new tag 点拨,这是由于一般的 Linux 系统没有 Masquery 规则。

    3. too many open files 问题open in new tag ,解决方法见 [透明代理]通过 gid 规避 Xray 流量-配置最大文件大开数&运行 Xray 客户端

    4. 避免已有连接的包二次通过 TPROXY ,待补充...

    5. 主路由、单臂路由与旁路由,待补充...

    - + diff --git a/document/level-2/warp.html b/document/level-2/warp.html index 00305bddbb..cf939f85f5 100644 --- a/document/level-2/warp.html +++ b/document/level-2/warp.html @@ -24,8 +24,8 @@ 通过 Cloudflare Warp 增强代理安全性 | Project X - - + +

    通过 Cloudflare Warp 增强代理安全性

    Xray(1.6.5+)新加入了 WireGuard 出站,虽然增加的代码和依赖会增大 core 体积,但是我们认为这是一个很有必要的新功能,原因有三:

    1. 通过近期的一些讨论和实验open in new tag,我们知道代理回国流量是不安全的。一种应对方式是将回国流量路由至黑洞,它的缺点是由于 geosite 和 geoip 更新的不及时或者新手不知道如何在客户端适当分流,结果流量进入黑洞,影响使用体验。 这时我们只需要将回国流量导入 Cloudflare Warp,可以在不影响使用体验的情况下达到同样的安全性。
    2. 众所周知,大部分机场会记录用户访问域名的日志,某些机场还会审计和阻断一些用户流量。保护用户私密性的一个方法,就是在客户端使用链式代理。 Warp 使用的 WireGuard 轻量级 VPN 协议会在代理层内增加一层加密。对于机场而言,用户所有流量的目标都是 Warp,从而最大程度保护自己的隐私。
    3. 方便使用,只需要一个 core 即可完成分流,Wireguard Tun,链式代理的设置。

    申请 Warp 账户

    感谢 Cloudflare 推动自由的互联网,现在你可以免费使用 Warp 服务,连接的时候会根据出口自动选择最近的服务器

    方法 1:

    1. 使用一台 vps,下载 wgcfopen in new tag
    2. 运行 wgcf register 生成 wgcf-account.toml
    3. 运行 wgcf generate 生成 wgcf-profile.conf 拷贝内容如下:
    [Interface]
    @@ -187,6 +187,6 @@
        ]
     }
     
    - + diff --git a/en/about/news.html b/en/about/news.html index c084433c95..0131b06daa 100644 --- a/en/about/news.html +++ b/en/about/news.html @@ -24,11 +24,11 @@ 大史记 | Project X - - + +

    大史记

    2021.4.6

    • VuePress Next.
    • With Dark Mode.

    2021.4.4

    • 本文档迎来的新的首页。
    • 本文档迎来了暗黑模式。
    • 当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。
    • 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
    • 🎉🎉🎉

    2021.4.1 v1.4.2open in new tag

    • 不是愚人节玩笑,今天更新。
    • 加入 Browser Dialer,用与改变 TLS 指纹与行为。
    • 加入 uTLS,用与改变 TLS Client Hello 的指纹。
    • 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。

    2021.3.25

    没错还在变。 -_-

    2021.3.15

    文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

    2021.3.14 v1.4.0open in new tag

    • Happy Pi-Day!
    • 这次是个大更新:
      • 为链式代理引入了传输层支持。
      • 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
      • 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
      • 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
      • 添加了 FakeDNS。
      • 还修复了系列的问题,添加了各类功能,详情请见更新日志。
    • 还是 VuePress 比较爽啊(

    2021.3.3 1.3.1open in new tag

    • 这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。
    • 同时修复了一个会导致 Panic 的 bug。Holmium_认为这是在骗、在偷袭。
    • 修复了几个遗留问题。

    2021.2.14 1.3.0open in new tag

    • Happy 🐮 Year 🎉!
    • v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。
    • OHHHHHHHHHHHH!

    2021.01.31 1.2.4open in new tag

    • 解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。
    • 似乎这个版本没有什么改变,但这只是暴风雨前的宁静。
    • (没错我就是先知)

      你个傻子,你拿的是 UNO 牌。

    2021.01.25

    • 全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载秘籍第一层咯...
    • 英文版文档网站逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!

    2021.01.22 1.2.3open in new tag

    • 对 SS 协议的支持变强了, 支持单端口多用户!
    • 对 trojan 协议的支持也变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!
    • (VLESS: 嘤嘤嘤)
    • UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".
    • 嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.
    • 向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 a @Bohan Yangopen in new tag 致敬!
    • 其他美味小樱桃, 惯例更新品尝就对啦.

    2021.01.19

    • 一些数字
      • 版本发布了 10   个 tag
      • 解决掉了 100  个 issue
      • 复刻了 300  个 fork
      • 点了 2000 个 star
      • 群 3000 个 人

    2021.01.17

    2021.01.15 1.2.2open in new tag

    • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
    • 之前预告的 UUID 修改正式上线.(往下看往下看)
    • 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
    • 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
    • 当然还有其他各种小糖果.(更新品尝就对了)
    • 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE

    2021.01.12

    • 将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户.
      • 客户端写 "id": "我爱 🍉 老师 1314",
      • 服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)
    • 🍉 老师的小小白白话文大结局, 撒花.

    2021.01.10 1.2.1open in new tag

    • 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
    • Google Voice 应该也可以正常使用 v2rayNG 拨打了.
    • 日志现在看起来更顺眼.

    2021.01.07

    • 礼貌和尊重本应是社区不需要明说的准则之一。

    2021.01.05

    • 文档网站正在悄悄的进行着某些神秘的变化。。。,🙊🙊🙊

    2021.01.03

    2021.01.01

    【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 1.2.0open in new tag

    🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!

    • 圣诞礼物v1.1.5后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
    • (UDP 还会继续增强!)
    • 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
    • (不,下面不是广告,是里程碑。)
    • Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
      • 一人扛起了所有!支持各大主流协议!
      • 一骑绝尘的性能!
      • 日趋完善的功能!
      • 可怕的生命力与社区亲和力!
    • Xray 将继续保持前行! 因此 Xray 需要更多的英雄!!open in new tag
    • PS:请品,请细品release notesopen in new tag每一句。似乎有一个小秘密小彩蛋 (啊,有人敲门...我一会和你们说)

    2020.12.29

    透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, TG 群open in new tag火热测试中

    2020.12.25 1.1.5open in new tag

    圣诞节快乐!

    • 游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone
    • 你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...
    • (VLESS 的 UDP fullcone 和更多增强很快就到!)
    • 无须再担心证书验证被墙,OCSP stapling 已经上线!
    • kirin 带来了一大波 脚本更新.脚本在此open in new tag
    • 还有更多美味小樱桃!(不用问,更新品尝就对了)

    2020.12.24

    因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。 网址为:没错你正在看的就是open in new tag

    大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)

    文档网站需要不断完善和增加内容,以及完善设计。 因此更欢迎大家一起为文档建设添砖加瓦。 文档的仓库open in new tag

    仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站. 欢迎大家查看,纠错,修改,增加心得。

    2020.12.23

    Xray-core Shadowsocks UDP FullCone 测试版, TG 群open in new tag火热测试中

    2020.12.21

    • Project X 群人数 2000+
    • 群消息(含游戏群) 日均破万

    2020.12.18 1.1.4open in new tag

    • 更低的启动内占用和内存使用优化
    • 随意定制的 TLS 提高你的 SSL 评级
    • 支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS
    • 还有在您路由器上使用的 Splice 最佳使用模式建议

    2020.12.17

    鉴于日益增长群人数和游戏需求, 开启了TG 游戏群open in new tag

    2020.12.15

    安装脚本 dev 分支open in new tag开启, 持续更新功能中.

    2020.12.11 1.1.3open in new tag

    • 完整版本的 REDIRECT 透明代理模式.
    • 软路由 splice 流控模式的优化建议.

    2020.12.06 1.1.2open in new tag

    • 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
    • 增强了 API 兼容

    2020.12.04

    增加 splice 模式

    2020.11.27

    • Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
    • 登上了 GitHub Trending
    • Project X 群人数破千,频道订阅数 500+

    2020.11.25 1.0.0open in new tag

    Xray 的第一个版本.

    • 基于 v2ray-core 修改而来,改动较大
    • 全面增强, 性能卓越, 完全兼容

    2020.11.23

    project X start

    梦开始的时候

    - + diff --git a/en/config/api.html b/en/config/api.html index 52e4525b2e..f13932e106 100644 --- a/en/config/api.html +++ b/en/config/api.html @@ -24,8 +24,8 @@ API Interface | Project X - - + +

    API Interface

    API interface configuration provides a set of APIs based on gRPCopen in new tag for remote invocation.

    The interface can be enabled through the api configuration module. When the api configuration is enabled, Xray will create an outbound proxy automatically. All incoming API connections need to be manually routed to this outbound proxy through routing rule configuration.

    Please refer to the related configuration in this section.

    Warning

    Most users do not need to use this API. Novices can ignore this item directly.

    ApiObject

    ApiObject corresponds to the api item in the configuration file.

    {
    @@ -63,6 +63,6 @@
     xray.app.proxyman.command.HandlerService
     xray.app.stats.command.StatsService
     

    API Calling Example

    Xray-API-documentsopen in new tag @crossfw

    - + diff --git a/en/config/dns.html b/en/config/dns.html index fe25f89884..9761fb96f7 100644 --- a/en/config/dns.html +++ b/en/config/dns.html @@ -24,8 +24,8 @@ Built-in DNS Server | Project X - - + +

    Built-in DNS Server

    DNS Server

    The DNS module built into Xray has two main purposes:

    • During the routing phase, it resolves domain names to IP addresses and performs traffic splitting based on the results of domain name resolution and the value of domainStrategy in the routing configuration module. The built-in DNS server is only used for DNS queries when either of the following values is set:
      • "IPIfNonMatch": When a domain name is requested, it first tries to match it against the domain entries in the routing configuration. If no match is found, the built-in DNS server is used to perform a DNS query for the domain name, and the returned IP address is used to perform IP routing matching again.
      • "IPOnDemand": When a domain name is matched against any IP-based rule, it is immediately resolved to an IP address for matching.
    • It resolves the target address for connection.
      • In the freedom outbound setting, if domainStrategy is set to UseIP, requests made through the outbound proxy will first resolve the domain name to an IP address using the built-in server before making the connection.
      • In the sockopt setting, if domainStrategy is set to UseIP, system connections initiated through the outbound proxy will first be resolved to an IP address using the built-in server before making the connection.

    TIP 1

    DNS queries sent by the built-in DNS server are automatically forwarded based on the routing configuration.

    TIP 2

    Only basic IP queries (A and AAAA records) are supported. CNAME records will be queried repeatedly until an A/AAAA record is returned. Other queries will not enter the built-in DNS server.

    DNS Processing Flow

    If the domain name to be queried:

    • Matches the mapping of "domain name - IP" or "domain name - IP array" in the hosts, then the IP or IP array will be returned as the DNS resolution result.

    • Matches the mapping of "domain name - domain name" in the hosts, then the value of this mapping (another domain name) will be used as the domain name to be queried, and enter the DNS processing flow until an IP is resolved and returned, or an empty resolution is returned.

    • Does not match hosts, but matches the domains list in one or more DNS servers, then according to the priority of the matching rule, use the DNS server corresponding to the rule to perform the query in sequence. If the DNS server that is hit fails to query or expectIPs does not match, then use the next hit DNS server to perform the query. Otherwise, return the resolved IP. If all hit DNS servers fail to query or expectIPs does not match, then the DNS component:

      • By default, it will perform "DNS fallback query": use the "DNS server that has not been used in the last failed query and has a default value of false for skipFallback" to perform the query in sequence. If the query fails or expectIPs does not match, return an empty resolution; otherwise, return the resolved IP.
      • If disableFallback is set to true, "DNS fallback query" will not be performed.
    • If neither hosts nor the domains list in DNS servers matches, then:

      • By default, use the "DNS server that has a default value of false for skipFallback" to perform the query in sequence. If the first selected DNS server fails to query or expectIPs does not match, then use the next selected DNS server to perform the query. Otherwise, return the resolved IP. If all selected DNS servers fail to query or expectIPs does not match, return an empty resolution.
      • If the number of "DNS servers that have a default value of false for skipFallback" is 0 or disableFallback is set to true, use the first DNS server in the DNS configuration to perform the query. If the query fails or expectIPs does not match, return an empty resolution; otherwise, return the resolved IP.

    DnsObject

    DnsObject corresponds to the dns section in the configuration file.

    {
    @@ -116,6 +116,6 @@
       "clientIP": "1.2.3.4"
     }
     

    address: address

    A list of DNS servers, which can be either DNS addresses (in string form) or ServerObjects.

    When the value is "localhost", it means using the local DNS configuration.

    When the value is a DNS "IP" address, such as "8.8.8.8", Xray will use the specified UDP port of this address for DNS queries. The query follows routing rules. By default, port 53 is used.

    When the value is in the form of "tcp://host", such as "tcp://8.8.8.8", Xray will use DNS over TCP for the query. The query follows routing rules. By default, port 53 is used.

    When the value is in the form of "tcp+local://host", such as "tcp+local://8.8.8.8", Xray will use TCP local mode (TCPL) for the query. That is, the DNS request will not go through the routing component and will be sent directly through the Freedom outbound to reduce latency. When no port is specified, port 53 is used by default.

    When the value is in the form of "https://host:port/dns-query", such as "https://dns.google/dns-query", Xray will use DNS over HTTPS (RFC8484, abbreviated as DOH) for the query. Some service providers have IP alias certificates, which can be directly written in IP form, such as https://1.1.1.1/dns-query. Non-standard ports and paths can also be used, such as "https://a.b.c.d:8443/my-dns-query".

    When the value is in the form of "https+local://host:port/dns-query", such as "https+local://dns.google/dns-query", Xray will use DOH local mode (DOHL) for the query, which means that the DOH request will not go through the routing component and will be sent directly through the Freedom outbound to reduce latency. This is generally suitable for server-side use. Non-standard ports and paths can also be used.

    When the value is in the form of "quic+local://host:port", such as "quic+local://dns.adguard.com", Xray will use DOQ local mode (DOQL) for the query, which means that the DNS request will not go through the routing component and will be sent directly through the Freedom outbound. This method requires DNS server support for DNS over QUIC. By default, port 784 is used for the query, and non-standard ports can be used.

    When the value is fakedns, FakeDNS functionality will be used for the query.

    port: number

    The port number of the DNS server, such as 53. If not specified, the default is 53. This item is not applicable when using DOH, DOHL, or DOQL modes, and non-standard ports should be specified in the URL.

    domains: [string]

    A list of domain names. The domain names in this list will be queried using this server first. The format of domain names is the same as in routing configuration.

    expectIPs: [string]

    A list of IP ranges in the same format as in routing configuration.

    When this item is configured, Xray DNS will verify the returned IP addresses and only return addresses that are included in the expectIPs list.

    If this item is not configured, the IP address will be returned as is.

    skipFallback: true | false

    true means to skip this server when performing DNS fallback queries, and the default is false, which means not to skip.

    - + diff --git a/en/config/fakedns.html b/en/config/fakedns.html index 92d629654d..4d01ea35dd 100644 --- a/en/config/fakedns.html +++ b/en/config/fakedns.html @@ -24,8 +24,8 @@ FakeDNS | Project X - - + + - + diff --git a/en/config/features/browser_dialer.html b/en/config/features/browser_dialer.html index 46ce7d7488..6053115766 100644 --- a/en/config/features/browser_dialer.html +++ b/en/config/features/browser_dialer.html @@ -24,11 +24,11 @@ Browser Dialer | Project X - - + +

    Browser Dialer

    BETA v1.4.1+

    Background

    Based on an idea from 2020open in new tag, a concise WSS Browser Dialer has been implemented using native JS, achieving true browser TLS fingerprints and behavioral characteristics. However, WSS still has significant issues with ALPN, so the next step is to forward HTTP/2 and QUIC through the browser."

    Xray & JS

    A very simple and clever communication mechanism has been created:

    • Xray listens on address port A as an HTTP service, and the browser accesses A to load the JS in the webpage.
    • The JS actively establishes a WebSocket connection to A. After a successful connection, Xray sends the connection to the channel.
    • When a connection needs to be established, Xray receives an available connection from the channel and sends the target URL and optional early data.
    • Once the JS successfully connects to the target, it informs Xray and continues to use this conn to bi-directionally forward data. Connection closing behavior is synchronized.
    • After the connection is used, it will be closed, but the JS ensures that there is always a new idle connection available."

    Early data

    According to the browser's needs, the early data mechanism has been adjusted as follows:

    • The server response header will contain the requested Sec-WebSocket-Protocol, which also initially obfuscates the length characteristic of the WSS handshake response.
    • The encoding used for early data for browsers is base64.RawURLEncoding instead of StdEncoding, and the server has made it compatible.
    • In addition, due to Xray-core#375open in new tag recommendations for ?ed=2048, this PR also increased server MaxHeaderBytes by 4096. (Although it seems like it would work without modification.)

    Configuration v1.4.1

    This is an exploratory process, and the configuration method used when both sides are Xray-core v1.4.1 is as follows:

    • Prepare a usable WSS configuration, making sure to fill in the domain name for the address. If you need to specify an IP address, configure DNS or system hosts.
    • If browser traffic will also pass through Xray-core, be sure to set this domain name as a direct connection, otherwise it will cause traffic looping.
    • Set the environment variable to specify the address port to listen on, such as XRAY_BROWSER_DIALER = 127.0.0.1:8080.
    • First run Xray-core, then use any browser to access the specified address port, and you can also check Console and Network with F12.
    • The browser will limit the number of WebSocket connections, so it is recommended to enable Mux.Cool.
    - + diff --git a/en/config/features/env.html b/en/config/features/env.html index 1bee046c7a..e892b697fd 100644 --- a/en/config/features/env.html +++ b/en/config/features/env.html @@ -24,14 +24,14 @@ Environment Variables | Project X - - + +

    Environment Variables

    Xray provides the following environment variables for modifying some of its underlying configurations.

    Xray Asset Location

    • Name:xray.location.asset or XRAY_LOCATION_ASSET
    • Default value:specified FHSopen in new tag directory or the same path as the Xray file.

    This environment variable specifies a folder location that should contain the geoip.dat and geosite.dat files. If no variable value is specified, the program will search for resource files in the following order:

    ./
     /usr/local/share/xray
     /usr/share/xray
     

    Configuration File Location

    • Name:xray.location.config or XRAY_LOCATION_CONFIG
    • Default value: Same path as the Xray file.

    This environment variable specifies a folder location that should contain the config.json file.

    Multiple Configuration Directories

    • Name:xray.location.confdir or XRAY_LOCATION_CONFDIR
    • Default value:""

    The .json files in this directory will be read in alphabetical order by filename and used as options for multiple configurations.

    - + diff --git a/en/config/features/fallback.html b/en/config/features/fallback.html index 07e7a192f6..1c847e10a0 100644 --- a/en/config/features/fallback.html +++ b/en/config/features/fallback.html @@ -24,8 +24,8 @@ Fallback | Project X - - + +

    Fallback

    Fallback is one of the most powerful features of Xray, which can effectively prevent active probing and allows you to use one port for multiple services

    Fallback provides Xray with high-strength anti-active probing capabilities and has a unique first-packet fallback mechanism.

    Fallback can also divide traffic of different types based on path for multi-service sharing on a single port.

    Currently, you can use the fallback feature by configuring fallbacks when using VLESS or Trojan protocols, thus creating an unimaginable combo of services becomes REALITY.

    fallbacks configuration

      "fallbacks": [
    @@ -41,6 +41,6 @@
       "xver": 0
     }
     

    The fallbacks object is optional and can only be used for the TCP+TLS transport combination.

    • When fallbacks configure with any child elements,"alpn":["http/1.1"] needs to be configured in Inbound TLS.

    Usually, you need to set up a default fallback with both alpn and path omitted or empty, and then configure other routing rules as needed.

    VLESS will forward traffic with TLS decrypted first packet length <18, invalid protocol version, or failed authentication to the address specified by dest.

    For other transport combinations, you must remove the fallbacks object or all its child elements. At this point, no fallbacks will be enabled, and VLESS will wait until it reads enough data. If the protocol version is invalid or authentication fails, the connection will be terminated directly.

    name: string

    Attempt to match the TLS SNI (Server Name Indication), where an empty value matches any SNI. The default value is "", which means empty value.

    alpn: string

    Attempt to match the result of TLS ALPN negotiation, where an empty value matches any ALPN result. The default value is "" , which means empty value.

    VLESS will read the TLS ALPN negotiation result only when necessary. If successful, it will output realAlpn = info to the log. Purpose: To solve the problem of Nginx's inability to simultaneously support http/1.1 and h2c services. Nginx needs to write two lines of listen, one for 1.1 and one for h2c. Note: When "h2" is included in fallbacks alpn, the Inbound TLS needs to be set as "alpn":["h2","http/1.1"] to support h2 access.

    Tip

    The alpn set in the Fallback is used to match the actual negotiated ALPN, while the alpn set in the Inbound TLS represents the list of optional ALPNs during the handshake. These two have different meanings.

    path: string

    Attempt to match the first packet HTTP PATH, where an empty value matches any PATH and a default value is empty. If non-empty, it must start with /, and h2c is not supported.

    Smart: VLESS will only attempt to check the PATH (no more than 55 bytes; the fastest algorithm that does not fully parse HTTP) when necessary. If successful, it will output realPath = in the INFO log. Purpose: To route other inbound WebSocket traffic or HTTP disguised traffic, without additional processing, purely forwarding traffic, and theoretically better performance than Nginx.

    Note: The inbound where fallbacks is located must be TCP+TLS. This is for routing to other WebSocket inbound, while the inbound being routed doesn't need to configure TLS.

    dest: string | number

    Determines the destination of decrypted TLS TCP traffic, which currently supports two types of addresses: (this field is required, otherwise it cannot be started)

    1. TCP, in the format of "addr:port", where addr supports IPv4, domain names, and IPv6. If a domain name is entered, a direct TCP connection will be made (rather than using the built-in DNS resolver).
    2. Unix domain socket, in the format of an absolute path, such as "/dev/shm/domain.socket", which can be prefixed with @ to represent abstractopen in new tag, and @@ to represent padded abstract.

    If only the port is specified, both numbers and strings are accepted, such as 80 or "80". This usually points to a plaintext HTTP service (and the addr will be filled in as "127.0.0.1").

    xver: number

    Sends the PROXY protocolopen in new tag protocol, which is used to transmit the real source IP and port of the request. The version can be set to 1 or 2, with a default value of 0, which means no PROXY protocol is sent. Version 1 is recommended if needed.

    Currently, versions 1 and 2 have the same functionality but different structures, where version 1 is printable while version 2 is binary. Xray's TCP and WebSocket inbound already support receiving the PROXY protocol.

    Warning

    If you are configuring Nginx to receive the PROXY protocolopen in new tag, you need to not only set proxy_protocol, but also set_real_ip_from to avoid potential issues.

    Additional Information

    • Matches the most precise sub-element, regardless of the order of arrangement of the sub-elements. If several sub-elements have the same alpn and path configurations, the last one specified will be used.
    • Fallback routing is performed at the decrypted TCP layer rather than the HTTP layer, and the first packet PATH is only checked when necessary.
    • You can learn more about tips and experiences in using Fallbacks by visiting

    Fallbacks design theory WIP

    - + diff --git a/en/config/features/multiple.html b/en/config/features/multiple.html index 1e5ce643b7..560ffb66d5 100644 --- a/en/config/features/multiple.html +++ b/en/config/features/multiple.html @@ -24,8 +24,8 @@ Multi-file configuration | Project X - - + +

    Multi-file configuration

    The Xray program supports the use of multiple configuration files.

    The main purpose of using multiple configuration files is to distribute different module configurations, making it easier to manage and maintain.

    This feature is mainly designed to enrich the Xray ecosystem. For example, for GUI-based clients, only fixed functions such as node selection are usually implemented, and complex configurations are difficult to implement graphically. By leaving a custom confdir configuration directory for complex functions, server deployment scripts can simply add files to confdir to implement multiple protocol configurations.

    Multi-file startup

    Tip

    The startup information will indicate each configuration file being read in sequence. Please pay attention to whether the startup information matches the order you have set.

    $ xray run -confdir /etc/xray/confs
    @@ -103,6 +103,6 @@
     
     0 directories, 10 files
     
    - + diff --git a/en/config/features/xtls.html b/en/config/features/xtls.html index 31e6b9a190..9baa24b429 100644 --- a/en/config/features/xtls.html +++ b/en/config/features/xtls.html @@ -24,11 +24,11 @@ Deep analysis of XTLS | Project X - - + + - + diff --git a/en/config/inbound.html b/en/config/inbound.html index 2902711f1c..df70431f3b 100644 --- a/en/config/inbound.html +++ b/en/config/inbound.html @@ -24,8 +24,8 @@ Inbound Proxy | Project X - - + +

    Inbound Proxy

    Inbound connections are used to receive incoming data and the available protocols are listed in inbound protocols.

    InboundObject

    The InboundObject corresponds to a subelement of the inbounds item in the configuration file.

    {
    @@ -62,6 +62,6 @@
       "concurrency": 3
     }
     

    strategy: "always" | "random"

    The port allocation strategy.

    • "always" means all specified ports in port will be allocated, and Xray will listen on these ports.
    • "random" means ports will be randomly selected from the port range every refresh minutes, and concurrency ports will be listened on.

    refresh: number

    The interval for refreshing randomly allocated ports in minutes. The minimum value is 2, and it is recommended to set to 5. This property is only effective when strategy is set to "random".

    concurrency: number

    The number of randomly allocated ports. The minimum value is 1, and the maximum value is one-third of the port range. It is recommended to set to 3.

    - + diff --git a/en/config/inbounds/dokodemo.html b/en/config/inbounds/dokodemo.html index 8140246c16..70009a523d 100644 --- a/en/config/inbounds/dokodemo.html +++ b/en/config/inbounds/dokodemo.html @@ -24,8 +24,8 @@ Dokodemo-Door | Project X - - + +

    Dokodemo-Door

    Dokodemo door (Anywhere Door) can listen to a local port and forward all incoming data on this port to a specified server's port, achieving the effect of port mapping.

    InboundConfigurationObject

    {
    @@ -37,6 +37,6 @@
       "userLevel": 0
     }
     

    address: address

    The address to forward the traffic to. It can be an IP address like "1.2.3.4" or a domain name like "xray.com". It is a string type.

    When followRedirect (see below) is set to true, address can be empty.

    port: number

    The specified port on the destination address to forward the traffic to. It should be in the range 1,655351,65535. It is a numeric value and is a required parameter.

    network: "tcp" | "udp" | "tcp,udp"

    The supported network protocol type. For example, when specified as "tcp", it will only receive TCP traffic. The default value is "tcp".

    timeout: number

    The idle timeout in seconds. The default value is 300. When handling a connection, if no data is transmitted within the timeout period, the connection will be terminated.

    followRedirect: true | false

    When set to true, dokodemo-door will recognize data forwarded by iptables and forward it to the corresponding destination address.

    Refer to the tproxy setting in the Transport Configuration for more information.

    userLevel: number

    The user level that the connection will use to determine the corresponding Local Policy.

    The value of userLevel corresponds to the value of level in the policy. If not specified, the default value is 0.

    Transparent Proxy Configuration Example

    Please refer to the Transparent Proxy (TProxy) Configuration Tutorial for this section.

    - + diff --git a/en/config/inbounds/http.html b/en/config/inbounds/http.html index 7068161f84..c965447d65 100644 --- a/en/config/inbounds/http.html +++ b/en/config/inbounds/http.html @@ -24,8 +24,8 @@ HTTP | Project X - - + +

    HTTP

    HTTP protocol.

    Warning

    The HTTP protocol does not provide encryption for transmission and is not suitable for transmission over public networks, as it can easily be used as a target for attacks.

    The more meaningful use of http inbound is to listen in a local network or on the local machine to provide local services for other programs.

    TIP 1

    http proxy can only proxy the TCP protocol and cannot handle protocols based on UDP.

    TIP 2

    In Linux, you can use the following environment variables to enable global HTTP proxy for the current session (many software support this setting, but some may not).

    • export http_proxy=http://127.0.0.1:8080/ (Change the address to the configured inbound HTTP proxy address)
    • export https_proxy=$http_proxy
    • :::

    InboundConfigurationObject

    {
    @@ -44,6 +44,6 @@
       "pass": "my-password"
     }
     

    user: string

    The username. It is a string and is required.

    pass: string

    The password. It is a string and is required.

    - + diff --git a/en/config/inbounds/shadowsocks.html b/en/config/inbounds/shadowsocks.html index c2ebef4a98..19660ddca9 100644 --- a/en/config/inbounds/shadowsocks.html +++ b/en/config/inbounds/shadowsocks.html @@ -24,8 +24,8 @@ Shadowsocks | Project X - - + +

    Shadowsocks

    The Shadowsocksopen in new tag protocol is compatible with most other implementations of Shadowsocks. The server supports TCP and UDP packet forwarding, with an option to selectively disable UDP.

    Supported Encryption Methods

    The currently supported methods are following:

    • Recommended encryption methods:
      • 2022-blake3-aes-128-gcm
      • 2022-blake3-aes-256-gcm
      • 2022-blake3-chacha20-poly1305
    • Other encryption methods:
      • aes-256-gcm
      • aes-128-gcm
      • chacha20-poly1305/chacha20-ietf-poly1305
      • xchacha20-poly1305/xchacha20-ietf-poly1305
      • none/plain

    The Shadowsocks 2022 new protocol format improves performance and includes complete replay protection, addressing the following security issues in the old protocol:

    Danger

    Traffic transmitted without encryption using the "none" method will be in plain text. Do not use it on public networks for security reasons.

    InboundConfigurationObject

    {
    @@ -47,6 +47,6 @@
     

    method: string, any of the supported methods

    Required.

    password: string

    Required. For Shadowsocks 2022 a pre-shared base64 random key similar to WireGuard's keys should be used as the password. The command

    openssl rand -base64 <length>
     

    could used to generate a key. The length of the required key for shadowsocks-rust implementation depends on the encryption method:

    Encryption MethodKey Length
    2022-blake3-aes-128-gcm16
    2022-blake3-aes-256-gcm32
    2022-blake3-chacha20-poly130532

    In the go-shadowsocks implementation written in Golang, a 32-byte key always works.

    For any other encryption method any string could be used. There is no limitation on the password length, but shorter passwords are more susceptible to cracking. It is recommended to use a random-generated password of 16 characters or longer. The following example generates 40-characters length password:

    sudo strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 40 | tr -d '\n'; echo
     

    level: number

    The user level that the connection will use to determine the corresponding Local Policy.

    The value of level corresponds to the value of level in the policy. If not specified, the default value is 0.

    email: string

    The user's email, used to differentiate traffic from different users for logs or statistics.

    - + diff --git a/en/config/inbounds/socks.html b/en/config/inbounds/socks.html index 15348c22e5..f8080d1a5a 100644 --- a/en/config/inbounds/socks.html +++ b/en/config/inbounds/socks.html @@ -24,8 +24,8 @@ SOCKS | Project X - - + +

    SOCKS

    The standard SOCKS protocol implementation is compatible with SOCKS 4open in new tag, SOCKS 4a, and SOCKS 5open in new tag.

    Danger

    The SOCKS protocol does not provide encryption for transport and is not suitable for transmitting data over public networks.

    The use of SOCKS inbound is more meaningful in a local area network or local environment, where it can be used to listen for incoming connections and provide local services to other programs.

    InboundConfigurationObject

    {
    @@ -45,6 +45,6 @@
       "pass": "my-password"
     }
     

    user: string

    The username as a string. Required.

    pass: string

    The password as a string. Required.

    - + diff --git a/en/config/inbounds/trojan.html b/en/config/inbounds/trojan.html index d648c073c3..e7a3afa41c 100644 --- a/en/config/inbounds/trojan.html +++ b/en/config/inbounds/trojan.html @@ -24,8 +24,8 @@ Trojan | Project X - - + +

    Trojan

    The Trojanopen in new tag protocol.

    Danger

    Trojan is designed to work with correctly configured encrypted TLS tunnels.

    InboundConfigurationObject

    {
    @@ -48,6 +48,6 @@
       "level": 0
     }
     

    password: string

    Required. Any string.

    email: string

    Email address. Optional. Used to identify the user.

    Danger

    If there are multiple ClientObjects, please make sure that the email addresses are not duplicated.

    level: number

    The user level that the connection will use to determine the corresponding Local Policy.

    The value of level corresponds to the value of level in the policy. If not specified, the default value is 0.

    - + diff --git a/en/config/inbounds/vless.html b/en/config/inbounds/vless.html index 64a96d8639..d2d335b5ec 100644 --- a/en/config/inbounds/vless.html +++ b/en/config/inbounds/vless.html @@ -24,8 +24,8 @@ VLESS | Project X - - + +

    VLESS

    Danger

    Currently, VLESS does not provide built-in encryption. Please use it with a reliable channel, such as TLS.

    VLESS is a stateless lightweight transport protocol that consists of inbound and outbound parts. It can serve as a bridge between Xray clients and servers.

    Unlike VMess, VLESS does not rely on system time. The authentication method is still UUID-based.

    InboundConfigurationObject

    {
    @@ -51,6 +51,6 @@
       "flow": "xtls-rprx-vision"
     }
     

    id: string

    The user ID for VLESS. It can be any string less than 30 bytes or a valid UUID. Custom strings and their corresponding UUIDs are equivalent, which means you can use either of the following in the configuration file to identify the same user:

    • "id": "我爱🍉老师1314"
    • "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (This UUID is the mapping of the string "我爱 🍉 老师 1314")

    The mapping standard is described in the VLESS UUID Mapping Standard: Mapping a Custom String to a UUIDv5open in new tag.

    You can use the command xray uuid -i "custom string" to generate the UUID corresponding to a custom string.

    You can also use the command xray uuid to generate a random UUID.

    level: number

    The user level that the connection will use to determine the corresponding Local Policy.

    The value of level corresponds to the value of level in the policy. If not specified, the default value is 0.

    email: string

    User email address used to differentiate traffic from different users (reflected in logs and statistics).

    flow: string

    Flow control mode used to select the XTLS algorithm.

    Currently, the following flow control modes are available for inbound protocols:

    • No flow, empty string, or none: Use regular TLS proxy.
    • xtls-rprx-vision: Use the new XTLS mode, including inner-handshake random padding.

    Additionally, XTLS currently only supports TCP, mKCP, and DomainSocket as transport methods.

    - + diff --git a/en/config/inbounds/vmess.html b/en/config/inbounds/vmess.html index 347a39b695..5f3bcd6347 100644 --- a/en/config/inbounds/vmess.html +++ b/en/config/inbounds/vmess.html @@ -24,8 +24,8 @@ VMess | Project X - - + +

    VMess

    VMess is an encrypted transport protocol that is commonly used as a bridge between Xray clients and servers.

    Danger

    VMess relies on system time. Please ensure that the system UTC time used by Xray is within 120 seconds of the actual time, regardless of time zone. On Linux systems, you can install the ntp service to automatically synchronize the system time.

    InboundConfigurationObject

    {
    @@ -55,6 +55,6 @@
       "level": 0
     }
     

    level: number

    The user level that the connection will use to determine the corresponding Local Policy.

    The value of level corresponds to the value of level in the policy. If not specified, the default value is 0.

- + diff --git a/en/config/index.html b/en/config/index.html index f1e7eef55d..977e7a853a 100644 --- a/en/config/index.html +++ b/en/config/index.html @@ -24,8 +24,8 @@ Configurations | Project X - - + +

This section will tell you all the details of Xray configuration. By mastering these contents, Xray will unleash its full power in your hands.

Overview

The configuration file of Xray is in JSON format, and the configuration format for the client and server is the same, except for the actual configuration content. It takes the following form:

{
@@ -43,6 +43,6 @@
   "metrics": {}
 }
 

Warning

If you are new to Xray, you can first click to view configuration and running in the Quick Start guide, to learn the most basic configuration method, and then refer to the contents of this section to master all the configuration methods of Xray.

Basic Configuration Modules

log:LogObject

Log configurations, controlling how Xray emits logs.

api:ApiObject

Configures how Xray provides API interfaces for calling remotely.

dns: DnsObject

Configures the built-in DNS server. System DNS will be used if not configured.

routing: RoutingObject

Configures routing. Specify rules to route connections through different outbounds.

policy: PolicyObject

Local policy configurations, specifying different user levels and corresponding policies.

inbounds: [ InboundObject ]

An array of inbound connection configurations.

outbounds: [ OutboundObject ]

An array of outbound connection configurations.

transport: TransportObject

Configures how Xray establishes and uses network connections to other servers.

stats: StatsObject

Configures traffic statistics.

reverse: ReverseObject

Configures the built-in reverse proxy. You can forward server traffic to the client, effectively achieving reverse proxying.

fakedns: FakeDnsObject

FakeDNS configuration. Can be used with a transparent proxy to obtain the actual domains.

metrics: metricsObject

Metrics configuration. A more straightforward (and hopefully better) way to export metrics.

- + diff --git a/en/config/log.html b/en/config/log.html index 771b895524..3a8c3ea7af 100644 --- a/en/config/log.html +++ b/en/config/log.html @@ -24,8 +24,8 @@ Log Configuration | Project X - - + +

Log Configuration

Log configuration controls how Xray outputs logs.

Xray has two types of logs: access logs and error logs. You can configure the output method for each type of log separately.

LogObject

LogObject corresponds to the log item in the configuration file.

{
@@ -37,6 +37,6 @@
   }
 }
 

access: string

The file path for the access log. The value is a valid file path, such as "/var/log/Xray/access.log" (Linux) or "C:\\Temp\\Xray\\_access.log" (Windows). When this item is not specified or is an empty value, the log is output to stdout.

  • The special value none disables access logs.

error: string

The file path for the error log. The value is a valid file path, such as "/var/log/Xray/error.log" (Linux) or "C:\\Temp\\Xray\\_error.log" (Windows). When this item is not specified or is an empty value, the log is output to stdout.

  • The special value none disables error logs.

loglevel: "debug" | "info" | "warning" | "error" | "none"

The log level for error logs, indicating the information that needs to be recorded. The default value is "warning".

  • "debug": Output information used for debugging the program. Includes all "info" content.
  • "info": Runtime status information, etc., which does not affect normal use. Includes all "warning" content.
  • "warning": Information output when there are some problems that do not affect normal operation but may affect user experience. Includes all "error" content.
  • "error": Xray encountered a problem that cannot be run normally and needs to be resolved immediately.
  • "none": Do not record any content.

dnsLog: bool

Whether to enable DNS query logs, for example: DOH//doh.server got answer: domain.com -> [ip1, ip2] 2.333ms.

- + diff --git a/en/config/metrics.html b/en/config/metrics.html index c402dfc246..582f12da97 100644 --- a/en/config/metrics.html +++ b/en/config/metrics.html @@ -24,8 +24,8 @@ Metrics | Project X - - + + - + diff --git a/en/config/outbound.html b/en/config/outbound.html index 6fbd1d4c43..be52a2fce6 100644 --- a/en/config/outbound.html +++ b/en/config/outbound.html @@ -24,8 +24,8 @@ Outbound Proxies | Project X - - + +

Outbound Proxies

Outbound connections are used for sending data and can use any of the available protocols listed in outbound protocols.

OutboundObject

The OutboundObject corresponds to a sub-element of the outbounds item in the configuration file.

Tip

The first element in the list serves as the main outbound. When there is no match or no successful match for the routing, the traffic is sent out by the main outbound.

{
@@ -51,6 +51,6 @@
   "concurrency": 8
 }
 

enabled: true | false

Whether to enable Mux forwarding requests, default is false.

concurrency: number

Maximum concurrent connections. Minimum value is 1, maximum value is 1024, default is 8.

This value represents the maximum number of Mux connections that can be carried on a TCP connection. For example, when concurrency=8 is set, if the client sends 8 TCP requests, Xray will only send one actual TCP connection, and all 8 requests from the client will be transmitted through this TCP connection.

Tip

When filling in a negative number, such as -1, the mux module is not loaded.

- + diff --git a/en/config/outbounds/blackhole.html b/en/config/outbounds/blackhole.html index 50eb0a5b61..bc71005104 100644 --- a/en/config/outbounds/blackhole.html +++ b/en/config/outbounds/blackhole.html @@ -24,8 +24,8 @@ Blackhole | Project X - - + + - + diff --git a/en/config/outbounds/dns.html b/en/config/outbounds/dns.html index b856daba56..7d53aa512c 100644 --- a/en/config/outbounds/dns.html +++ b/en/config/outbounds/dns.html @@ -24,8 +24,8 @@ DNS | Project X - - + +

DNS

DNS is an outbound protocol used for intercepting and forwarding DNS queries.

This outbound protocol can only handle DNS traffic, including queries based on UDP and TCP protocols. Other types of traffic will result in an error.

When handling DNS queries, this outbound protocol will forward IP queries (A and AAAA) to the built-in DNS server. Other types of query traffic will be forwarded to their original destination addresses.

OutboundConfigurationObject

{
@@ -35,6 +35,6 @@
   "nonIPQuery": "drop"
 }
 

network: "tcp" | "udp"

Modifies the transport layer protocol for DNS traffic. The possible values are "tcp" and "udp". When not specified, the original transport method will be retained.

address: address

Modifies the DNS server address. When not specified, the original address specified in the source will be retained.

port: number

Modifies the DNS server port. When not specified, the original port specified in the source will be retained.

nonIPQuery: string

Control non IP queries (neither A or AAAA), "drop" this request or "skip" processing in DNS module,the request will be forwarded to target. By default is "drop".

DNS Configuration Example WIP

- + diff --git a/en/config/outbounds/freedom.html b/en/config/outbounds/freedom.html index 6c924570ab..5c3cfb0958 100644 --- a/en/config/outbounds/freedom.html +++ b/en/config/outbounds/freedom.html @@ -24,8 +24,8 @@ Freedom | Project X - - + +

Freedom

Freedom is an outbound protocol that can be used to send (normal) TCP or UDP data to any network.

OutboundConfigurationObject

{
@@ -40,6 +40,6 @@
   "proxyProtocol": 0
 }
 

domainStrategy: "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"

When the destination address is a domain name, configure the corresponding value for Freedom's behavior:

  • "AsIs": Freedom resolves the domain name using the system DNS server and connects to it.
  • "UseIP", "UseIPv4", and "UseIPv6": Xray resolves the domain name using the built-in DNS server and connects to it. The default value is "AsIs".

TIP 1

When using the "UseIP" mode and the sendThrough field is specified in the outbound connection configuration, Freedom will automatically determine the required IP type, IPv4 or IPv6, based on the value of sendThrough.

TIP 2

When using the "UseIPv4" or "UseIPv6" mode, Freedom will only use the corresponding IPv4 or IPv6 address. If sendThrough specifies a mismatched local address, the connection will fail.

redirect: address_port

Freedom will force all data to be sent to the specified address (instead of the address specified in the inbound).

It is a string value, for example: "127.0.0.1:80", ":1234".

When the address is not specified, such as ":443", Freedom will not modify the original destination address. When the port is 0, such as "xray.com:0", Freedom will not modify the original port.

userLevel: number

User level. The connection will use the corresponding local policy for this user level.

The value of userLevel corresponds to the value of level in the policy. If not specified, the default value is 0.

fragment: map

A key-value map used to control TCP fragmentation,under some circumstances it can cheat the censor syetem, like bypass a SNI blacklist.

"packets":support two different methods. "1-3" is for segmentation at TCP layer, applying to the beginning 1 to 3 data writes by the client. "tlshello" is for TLS client hello packet fragmentation.

"length": length to make the cut

"interval": time between fragments(ms)

proxyProtocol: number

The value of proxyProtocol represents the PROXY Protocol version. default value is 0.

- + diff --git a/en/config/outbounds/http.html b/en/config/outbounds/http.html index cd62d1855f..6624b5fec5 100644 --- a/en/config/outbounds/http.html +++ b/en/config/outbounds/http.html @@ -24,8 +24,8 @@ HTTP | Project X - - + +

HTTP

HTTP is a protocol that is used for communication over the internet. Please note that HTTP does not provide encryption for data transmission and is not suitable for transmitting sensitive information over public networks, as it can be easily targeted for attacks.

Danger

The HTTP protocol does not provide encryption for transmission, making it unsuitable for transmitting over public networks and more susceptible to being used as a compromised host for attacks.

Tip

HTTP can only proxy TCP protocols, and cannot handle UDP-based protocols.

OutboundConfigurationObject

{
@@ -57,6 +57,6 @@
   "pass": "my-password"
 }
 

user: string

The username. Required.

pass: string

The password. Required.

- + diff --git a/en/config/outbounds/loopback.html b/en/config/outbounds/loopback.html index 5de09a037e..ff5ab18a30 100644 --- a/en/config/outbounds/loopback.html +++ b/en/config/outbounds/loopback.html @@ -24,8 +24,8 @@ Loopback | Project X - - + + - + diff --git a/en/config/outbounds/shadowsocks.html b/en/config/outbounds/shadowsocks.html index 818bee6e5b..d70fc4e90d 100644 --- a/en/config/outbounds/shadowsocks.html +++ b/en/config/outbounds/shadowsocks.html @@ -24,8 +24,8 @@ Shadowsocks | Project X - - + +

Shadowsocks

Shadowsocksopen in new tag protocol is compatible with most other implementations.

Here are the features and compatibility of Shadowsocks:

  • It supports TCP and UDP packet forwarding, with the option to disable UDP.
  • Recommended encryption methods:
    • 2022-blake3-aes-128-gcm
    • 2022-blake3-aes-256-gcm
    • 2022-blake3-chacha20-poly1305
  • Other encryption methods:
    • aes-256-gcm
    • aes-128-gcm
    • chacha20-poly1305 (also known as chacha20-ietf-poly1305)
    • none or plain

The new protocol format of Shadowsocks 2022 improves performance and includes full replay protection, addressing security issues present in the old protocol:

Danger

Using the "none" encryption method will transmit traffic in plaintext. It is not recommended to use "none" encryption on public networks to ensure security.

OutboundConfigurationObject

{
@@ -51,6 +51,6 @@
   "level": 0
 }
 

email: string

Email address (optional) used to identify the user.

address: address

The address of the Shadowsocks server, supporting IPv4, IPv6, and domain names. Required.

port: number

The port of the Shadowsocks server. Required.

method: string

Encryption method. Required.

password: string

Password. Required.

uot: bool

When enabled, UDP over TCP (UOT) will be used.

  • Shadowsocks 2022

Use a pre-shared key (PSK) similar to WireGuard as the password.

To generate a compatible key with shadowsocks-rust, use openssl rand -base64 <length>, where the length depends on the encryption method used.

Encryption MethodKey Length
2022-blake3-aes-128-gcm16
2022-blake3-aes-256-gcm32
2022-blake3-chacha20-poly130532

In the Go implementation, a 32-byte key always works.

  • Other encryption methods

Any string can be used as a password. There is no limit on the password length, but shorter passwords are more susceptible to cracking. It is recommended to use a password of 16 characters or longer.

level: number

User level. Connections will use the corresponding local policy associated with this user level.

The level value corresponds to the level value in the policy. If not specified, the default value is 0.

- + diff --git a/en/config/outbounds/socks.html b/en/config/outbounds/socks.html index b54b5a7b92..0b9355e1d6 100644 --- a/en/config/outbounds/socks.html +++ b/en/config/outbounds/socks.html @@ -24,8 +24,8 @@ Socks | Project X - - + +

Socks

The Socks protocol is a standard protocol implementation that is compatible with Socks 5open in new tag.

Danger

The Socks protocol does not provide encryption for transmission and is not suitable for transmitting data over public networks.

OutboundConfigurationObject

{
@@ -60,6 +60,6 @@
   "level": 0
 }
 

user: string

The username. Required.

pass: string

The password. Required.

level: number

The user level. Connections will use the corresponding local policy associated with this user level.

The level value corresponds to the level value in the policy. If not specified, the default value is 0.

- + diff --git a/en/config/outbounds/trojan.html b/en/config/outbounds/trojan.html index 4da3565338..42654ed1b9 100644 --- a/en/config/outbounds/trojan.html +++ b/en/config/outbounds/trojan.html @@ -24,8 +24,8 @@ Trojan | Project X - - + +

Trojan

Trojanopen in new tag protocol

Danger

Trojan is designed to work with correctly configured encrypted TLS tunnels.

OutboundConfigurationObject

{
@@ -47,6 +47,6 @@
   "level": 0
 }
 

address: address

The server address, which can be an IPv4, IPv6, or domain name. Required.

port: number

The server port, usually the same port that the server is listening on.

password: string

The password for authentication. Required. It can be any string.

email: string

The email address, optional, used to identify the user.

level: number

The user level. Connections will use the corresponding local policy associated with this user level.

The level value corresponds to the level value in the policy. If not specified, the default value is 0.

- + diff --git a/en/config/outbounds/vless.html b/en/config/outbounds/vless.html index 316cefa2f5..669699051f 100644 --- a/en/config/outbounds/vless.html +++ b/en/config/outbounds/vless.html @@ -24,8 +24,8 @@ VLESS | Project X - - + +

VLESS

Danger

Currently, VLESS does not have built-in encryption, please use it on a reliable channel, such as TLS.

VLESS is a stateless lightweight transport protocol, which is divided into inbound and outbound parts, and can be used as a bridge between Xray clients and servers.

Unlike VMess, VLESS does not rely on system time, and the authentication method is also UUID.

OutboundConfigurationObject

{
@@ -63,6 +63,6 @@
   "level": 0
 }
 

id: string

The user ID of VLESS, which can be any string less than 30 bytes, or a valid UUID. Custom strings and their mapped UUIDs are equivalent, which means you can write an id in the configuration file to identify the same user, i.e.

  • Write "id": "I love 🍉 teacher 1314",
  • Or write "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (this UUID is the UUID mapping of I love 🍉 teacher 1314)

The mapping standard is in VLESS UUID mapping standard: mapping custom strings to a UUIDv5open in new tag

You can use the command xray uuid -i "custom string" to generate the UUID mapped by the custom string, or use the command xray uuid to generate a random UUID.

encryption: "none"

Need to fill in "none", cannot be left empty.

This requirement is to remind users that there is no encryption and to prevent users from filling in the wrong attribute name or location, causing exposure when encryption methods come out in the future.

If the value of encryption is not set correctly, an error message will be received when using Xray or -test.

flow: string

Flow control mode, used to select the XTLS algorithm.

Currently, there are the following flow control modes available in the outbound protocol:

  • No flow, empty character or none: using regular TLS proxy
  • xtls-rprx-vision: using the new XTLS mode includes inner handshake random padding supports uTLS client fingerprint simulation
  • xtls-rprx-vision-udp443: same as xtls-rprx-vision, but allows UDP traffic with a destination of port 443

In addition, currently, XTLS only supports TCP, mKCP, and DomainSocket transport modes.

About xtls-rprx-*-udp443 flow control mode

When using Xray-core's XTLS, traffic to UDP port 443 is blocked by default (generally for QUIC), so the application will use TLS instead of QUIC, and XTLS will take effect. In fact, QUIC itself is not suitable for proxying because it has its own TCP functionality. When it is transmitted as UDP traffic through the VLESS protocol, the underlying protocol is TCP, which is equivalent to two layers of TCP.

If you do not need to block it, please fill in xtls-rprx-*-udp443 on the client side and do not change the server side.

About Splice mode

Splice is a function provided by the Linux Kernel. The system kernel directly forwards TCP without going through Xray's memory, greatly reducing the number of data copies and CPU context switches.

The usage restrictions of Splice mode are:

  • Linux environment
  • Inbound protocols are Dokodemo door, Socks, HTTP, etc., pure TCP connections, or other inbound protocols that use XTLS
  • Outbound protocol is VLESS + XTLS
  • It is worth noting that when using the mKCP protocol, Splice will not be used (yes, although there is no error, it is not used at all)

In addition, when using Splice, the speed display will lag behind, which is a feature, not a bug.

Using Vision mode will automatically enable Splice if the above conditions are met.

level: number

User level, the connection will use the local policy corresponding to this user level.

The value of level corresponds to the value of level in policy. If not specified, the default is 0.

- + diff --git a/en/config/outbounds/vmess.html b/en/config/outbounds/vmess.html index 29e17d0361..5ab806880e 100644 --- a/en/config/outbounds/vmess.html +++ b/en/config/outbounds/vmess.html @@ -24,8 +24,8 @@ VMess | Project X - - + +

VMess

VMess is an encrypted transport protocol commonly used as a bridge between Xray clients and servers.

Danger

VMess relies on system time. Please ensure that the UTC time of your system, when using Xray, has an error within 120 seconds, regardless of the time zone. On Linux systems, you can install the ntp service to automatically synchronize the system time.

OutboundConfigurationObject

{
@@ -54,6 +54,6 @@
   "level": 0
 }
 

id: string

The user ID for VMess, which can be any string less than 30 bytes or a valid UUID.

Custom strings and their corresponding UUIDs are equivalent. This means that you can use either a custom string or its corresponding UUID to identify the same user in the configuration file. For example:

  • Write "id": "我爱🍉老师1314",
  • Or write "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (this UUID is the mapping of the custom string "我爱 🍉 老师 1314")

The mapping standard is described in the VLESS UUID Mapping Standard: Mapping a Custom String to a UUIDv5open in new tag.

You can use the command xray uuid -i "custom string" to generate the UUID corresponding to a custom string, or use the command xray uuid to generate a random UUID.

level: number

The user level. Connections will use the corresponding local policy associated with this user level.

The level value corresponds to the level value in the policy. If not specified, the default value is 0.

security: "aes-128-gcm" | "chacha20-poly1305" | "auto" | "none" | "zero"

The encryption method. The client will use the configured encryption method to send data, and the server will automatically recognize it without the need for configuration.

  • "aes-128-gcm": Recommended for use on PCs.
  • "chacha20-poly1305": Recommended for use on mobile devices.
  • "auto": Default value. Automatically selects the encryption method (uses aes-128-gcm when running on AMD64, ARM64, or s390x architecture, and Chacha20-Poly1305 in other cases).
  • "none": No encryption.
  • "zero": No encryption and no message authentication (v1.4.0+).

Tip

It is recommended to use the "auto" encryption method as it ensures long-term security and compatibility.

The "none" pseudo-encryption method calculates and verifies the packet's checksum. However, due to the lack of hardware support for the authentication algorithm, it may be slower than the hardware-accelerated "aes-128-gcm" on some platforms.

The "zero" pseudo-encryption method neither encrypts the message nor calculates the checksum, theoretically providing higher speed than any other encryption method. The actual speed may be influenced by other factors.

It is not recommended to use the "none" or "zero" pseudo-encryption methods without enabling TLS encryption and forcibly verifying certificates. If you use a CDN or other intermediate platforms or network environments that decrypt TLS connections, it is not recommended to use the "none" or "zero" pseudo-encryption methods.

Regardless of the encryption method used, the VMess packet header is protected by encryption and authentication.

- + diff --git a/en/config/outbounds/wireguard.html b/en/config/outbounds/wireguard.html index deeffc2d0a..2951dadd15 100644 --- a/en/config/outbounds/wireguard.html +++ b/en/config/outbounds/wireguard.html @@ -24,8 +24,8 @@ Wireguard | Project X - - + +

Wireguard

Wireguard is a standard implementation of the Wireguard protocol.

Danger

The Wireguard protocol is not specifically designed for circumvention purposes. If used as the outer layer for circumvention, its characteristics may lead to server blocking.

OutboundConfigurationObject

{
@@ -69,6 +69,6 @@
   "allowedIPs": ["0.0.0.0/0"] // optional, default ["0.0.0.0/0", "::/0"]
 }
 

endpoint: address

The server address. Required.

URL:port format, e.g. engage.cloudflareclient.com:2408.
IP:port format, e.g. 162.159.192.1:2408 or [2606:4700:d0::a29f:c001]:2408.

publicKey: string

The server's public key used for verification. Required.

preSharedKey: string

An additional symmetric encryption key.

keepAlive: int

The interval of keep-alive packets in seconds. The default is 0, which means no keep-alive.

allowedIPs: string array

Only allow traffic from specific source IP addresses in Wireguard.

- + diff --git a/en/config/policy.html b/en/config/policy.html index 1c81105710..a4809ecffc 100644 --- a/en/config/policy.html +++ b/en/config/policy.html @@ -24,8 +24,8 @@ Local Policy | Project X - - + +

Local Policy

Local policy can be used to set different policy settings for different user levels, such as connection timeout settings. Each connection handled by Xray corresponds to a user, and different policies are applied based on the user's level.

PolicyObject

PolicyObject corresponds to the policy field in the configuration file.

{
@@ -65,6 +65,6 @@
   "statsOutboundDownlink": false
 }
 

statsInboundUplink: true | false

When set to true, enables upstream traffic statistics for all inbound proxies.

statsInboundDownlink: true | false

When set to true, enables downstream traffic statistics for all inbound proxies.

statsOutboundUplink: true | false

When set to true, enables upstream traffic statistics for all outbound proxies.

statsOutboundDownlink: true | false

When set to true, enables downstream traffic statistics for all outbound proxies.

- + diff --git a/en/config/reverse.html b/en/config/reverse.html index 4ab49397f1..d06c0d02e0 100644 --- a/en/config/reverse.html +++ b/en/config/reverse.html @@ -24,8 +24,8 @@ Reverse Proxy | Project X - - + +

Reverse Proxy

A reverse proxy forwards traffic from a server to a client, which is known as reverse traffic forwarding.

Here's how a reverse proxy generally works:

  • Suppose there is a web server in host A, which does not have a public IP address and cannot be accessed directly on the Internet. There is another host B that can be accessed via the public network. Now we need to use B as the entry point to forward traffic from B to A.
  • Configure Xray in host A as a bridge, and also configure Xray in B as a portal.
  • Bridge will actively establish a connection to portal, and the destination address of this connection can be set by itself. Portal will receive two types of connections: one is the connection sent by bridge, and the other is the connection sent by public network users. Portal will automatically merge the two types of connections. So bridge can receive public network traffic.
  • After receiving the public network traffic, bridge will forward it unchanged to the web server in host A. Of course, this step requires the cooperation of routing.
  • Bridge will dynamically load balance according to the size of the traffic.

Tip

Reverse proxy has Mux enabled by default, so please do not enable Mux again on the outbound it uses.

Warning

The reverse proxy function is still in the testing phase and may have some issues.

ReverseObject

ReverseObject corresponds to the reverse field in the configuration file.

{
@@ -144,6 +144,6 @@
   ]
 }
 
- + diff --git a/en/config/routing.html b/en/config/routing.html index c2b8132e40..4cf338eacd 100644 --- a/en/config/routing.html +++ b/en/config/routing.html @@ -24,8 +24,8 @@ Routing | Project X - - + +

Routing

The routing module can send inbound data through different outbound connections according to different rules to achieve on-demand proxying.

A common use case is to split domestic and foreign traffic. Xray can use its internal mechanisms to determine the traffic from different regions and then send them to different outbound proxies.

For a more detailed analysis of the routing function, please refer to Routing Function Analysisopen in new tag.

RoutingObject

RoutingObject corresponds to the routing item in the configuration file.

{
@@ -57,6 +57,6 @@
   "selector": []
 }
 

tag: string

The identifier of this load balancer, used to match balancerTag in RuleObject.

selector: [ string ]

An array of strings, each of which will be used to match the prefix of the outbound identifier. For example, in the following outbound identifiers: [ "a", "ab", "c", "ba" ], "selector": ["a"] will match [ "a", "ab" ].

If multiple outbounds are matched, the load balancer currently selects one randomly as the final outbound.

Predefined Domain Lists

This list is included in every Xray installation package, and the file name is geosite.dat. This file contains some common domain names, which can be used as geosite:filename to perform routing or DNS filtering for domain names that match those in the file.

Common domain lists include:

  • category-ads: Contains common advertising domain names.
  • category-ads-all: Contains common advertising domain names and advertising provider domain names.
  • cn: Equivalent to the combination of geolocation-cn and tld-cn.
  • apple: Contains most of the domain names under Apple.
  • google: Contains most of the domain names under Google.
  • microsoft: Contains most of the domain names under Microsoft.
  • facebook: Contains most of the domain names under Facebook.
  • twitter: Contains most of the domain names under Twitter.
  • telegram: Contains most of the domain names under Telegram.
  • geolocation-cn: Contains common domain names of mainland Chinese websites.
  • geolocation-!cn: Contains common domain names of non-mainland Chinese websites, as well as tld-!cn.
  • tld-cn: Contains top-level domain names managed by CNNIC for mainland China, such as domain names ending in .cn and .中国.
  • tld-!cn: Contains top-level domain names used outside mainland China, such as domain names ending in .hk (Hong Kong), .tw (Taiwan), .jp (Japan), .sg (Singapore), .us (United States), and .ca (Canada).

You can also find the complete list of domain names here: Domain list communityopen in new tag.

- + diff --git a/en/config/stats.html b/en/config/stats.html index 706cf874c0..3bb9c7f740 100644 --- a/en/config/stats.html +++ b/en/config/stats.html @@ -24,14 +24,14 @@ Traffic Statistics | Project X - - + +

Traffic Statistics

Used to configure traffic statistics for Xray.

StatsObject

The StatsObject corresponds to the stats item in the configuration file.

{
   "stats": {}
 }
 

Currently, no parameters are required for traffic statistics, and internal statistics will be enabled as long as the StatsObject item exists.

After statistics are enabled, you only need to enable the corresponding items in the Policy to collect the corresponding data.

Retrieving Traffic Statistics

You can use the xray api command to retrieve traffic statistics.

The current traffic statistics are as follows:

  • User Data

    • user>>>[email]>>>traffic>>>uplink

      The uplink traffic of a specific user, in bytes.

    • user>>>[email]>>>traffic>>>downlink

      The downlink traffic of a specific user, in bytes.

Tip

If the corresponding user does not have an email specified, statistics will not be enabled.

  • Global Data

    • inbound>>>[tag]>>>traffic>>>uplink

      The uplink traffic of a specific inbound, in bytes.

    • inbound>>>[tag]>>>traffic>>>downlink

      The downlink traffic of a specific inbound, in bytes.

    • outbound>>>[tag]>>>traffic>>>uplink

      The uplink traffic of a specific outbound, in bytes.

    • outbound>>>[tag]>>>traffic>>>downlink

      The downlink traffic of a specific outbound, in bytes.

- + diff --git a/en/config/transport.html b/en/config/transport.html index 565bec524a..6aeea8ea02 100644 --- a/en/config/transport.html +++ b/en/config/transport.html @@ -24,8 +24,8 @@ Transport | Project X - - + +

Transport

Transports specify how Xray communicates with peers.

Transports specify how to achieve stable data transmission. Both ends of a connection often need to specify the same transport protocol to successfully establish a connection. Like, if one end uses WebSocket, the other end must also use WebSocket, or else the connection cannot be established.

Transport configuration consists of two parts:

  1. Global config (TransportObject)
  2. Local config (StreamSettingsObject).
  • When locally configured, you can specify how each inbound or outbound connection is transmitted individually.
  • Server inbounds and client outbounds often need to use the same transport protocol. When a transport protocol is specified without local configs, the transport will fall back to global transport configs.

TransportObject

The TransportObject corresponds to the transport property in the config root.

{
@@ -171,6 +171,6 @@
   "tcpNoDelay": false
 }
 

mark: number

An integer value. When its value is non-zero, SO_MARK is marked with this value on the outbound connection.

  • Only applicable to Linux systems.
  • Requires CAP_NET_ADMIN permission.

tcpFastOpen: true | false | number

Specifies whether TCP Fast Openopen in new tag is enabled.

When its value is true or a positive integer, TFO is enabled; when its value is false or a negative integer, TFO is forced to be disabled; when this item does not exist or is 0, the system default setting is used. It can be used for inbound/outbound connections.

  • Only available in the following (or later) versions of operating systems:
    • Windows 10 (1607)
    • Mac OS 10.11 / iOS 9
    • Linux 3.16: It needs to be set through the kernel parameter net.ipv4.tcp_fastopen, which is a bitmap. 0x1 represents the client allows enabling it, and 0x2 represents the server allows enabling it. The default value is 0x1. If the server wants to enable TFO, set this kernel parameter value to 0x3.
    • FreeBSD 10.3 (Server) / 12.0 (Client): The kernel parameters net.inet.tcp.fastopen.server_enabled and net.inet.tcp.fastopen.client_enabled need to be set to 1.
  • For inbound, the positive integer set here represents the maximum number of TFO connection requests to be processed, note that not all operating systems support this setting:
    • Linux/FreeBSD: The positive integer value set here represents the upper limit, and the maximum acceptable value is 2147483647. If it is set to true, it will take 256. Note that in Linux, net.core.somaxconn will limit the upper limit of this value. If it exceeds somaxconn, please also increase somaxconn.
    • Mac OS: When it is true or a positive integer, it only represents enabling TFO, and the upper limit needs to be set separately through the kernel parameter net.inet.tcp.fastopen_backlog.
    • Windows: When it is true or a positive integer, it only represents enabling TFO.
  • For outbound, setting it to true or a positive integer only represents enabling TFO on any operating system.

tproxy: "redirect" | "tproxy" | "off"

Specifies whether to enable transparent proxy (only applicable to Linux).

  • "redirect": Use the transparent proxy in Redirect mode. It supports all TCP and UDP connections based on IPv4/6.
  • "tproxy": Use the transparent proxy in TProxy mode. It supports all TCP and UDP connections based on IPv4/6.
  • "off": Turn off transparent proxy.

Transparent proxy requires Root or CAP\_NET\_ADMIN permission.

Danger

When followRedirect is set to true in Dokodemo-door, and tproxy in the Sockopt settings is empty, the value of tproxy in the Sockopt settings will be set to "redirect".

domainStrategy: "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"

In previous versions, when Xray attempted to establish a system connection using a domain name, the resolution of the domain name was completed by the system and not controlled by Xray. This led to issues such as the inability to resolve domain names in non-standard Linux environments. To solve this problem, Xray 1.3.1 introduced Freedom's domainStrategy into Sockopt.

When the target address is a domain name, the corresponding value is configured, and the behavior of SystemDialer is as follows:

  • "AsIs": Resolve the IP address using the system DNS server and connect to the domain name.
  • "UseIP", "UseIPv4", and "UseIPv6": Resolve the IP address using the built-in DNS server and connect to the IP address directly.

The default value is "AsIs".

Danger

Improper configuration may cause infinite loops when this feature is enabled.

In short, connecting to the server requires waiting for the DNS query result, and completing the DNS query requires connecting to the server.

Tony: Which came first, the chicken or the egg?

Explanation:

  1. Trigger condition: proxy server (proxy.com). Built-in DNS server, non-local mode.
  2. Before Xray attempts to establish a TCP connection to proxy.com, it queries proxy.com using the built-in DNS server.
  3. The built-in DNS server establishes a connection to dns.com and sends a query to obtain the IP address of proxy.com.
  4. Improper routing rules cause proxy.com to proxy the query sent in step 3.
  5. Xray attempts to establish another TCP connection to proxy.com.
  6. Before establishing the connection, Xray queries proxy.com using the built-in DNS server.
  7. The built-in DNS server reuses the connection established in step 3 to send a query.
  8. A problem arises. The establishment of the connection in step 3 requires waiting for the query result in step 7, and the completion of the query in step 7 requires waiting for the connection in step 3 to be fully established.
  9. Good game!

Solution:

  • Adjust the split of internal DNS servers.
  • Use Hosts file.
  • If you still don't know the solution, then don't use this feature.

Therefore, it is not recommended for inexperienced users to use this feature.

dialerProxy: ""

An identifier for an outbound proxy. When the value is not empty, the specified outbound will be used to establish the connection. This option can be used to support chain forwarding of underlying transport protocols.

Danger

This option is incompatible with ProxySettingsObject.Tag

acceptProxyProtocol: true | false

Only used for inbound, indicates whether to accept the PROXY protocol.

PROXY protocolopen in new tag is used to pass the true source IP and port of a request. If you are not familiar with it, please ignore this option first.

Common reverse proxy software (such as HAProxy, Nginx) can be configured to send it, and VLESS fallbacks xver can also send it.

When set to true, after the lowest-level TCP connection is established, the requesting party must first send PROXY protocol v1 or v2, otherwise the connection will be closed.

tcpKeepAliveInterval: number

Interval between TCP keep-alive packets, in seconds. This setting only applies to Linux.

Not configuring this item or configuring it as 0 means using the default value of Go.

Tip

When filling in a negative number, such as -1, TCP keep-alive is not enabled.

tcpcongestion: ""

TCP congestion control algorithm. Only supported by Linux. Not configuring this item means using the system default value.

Tip

Common algorithms

  • bbr (recommended)
  • cubic
  • reno

Tip

Execute the command sysctl net.ipv4.tcp_congestion_control to get the system default value.

interface: ""

Specifies the name of the bound outbound network interface. supported by Linux MacOS iOS.
MacOS iOS Requires Xray-core v1.8.6 or higher.

tcpMptcp: true | false

Xray-core v1.8.6 New parameter.
Default value false, fill in true to enable Multipath TCPopen in new tag, need to be enabled in both server and client configuration.

tcpNoDelay: true | false

Default value false, recommended to be enabled with "tcpMptcp": true.

- + diff --git a/en/config/transports/domainsocket.html b/en/config/transports/domainsocket.html index e781797bbc..bebfe230f3 100644 --- a/en/config/transports/domainsocket.html +++ b/en/config/transports/domainsocket.html @@ -24,8 +24,8 @@ Domain Socket | Project X - - + +

Domain Socket

Danger

We recommend writing it to the listen field in inboundsand the transport mode can be TCP, WebSocket, or HTTP/2.

Note that the DomainSocket option here may be deprecated in the future.

Domain Socket uses standard Unix domain sockets to transmit data.

The advantage of using DomainSocket is that it uses the built-in transport channel of the operating system and does not occupy the network cache. Theoretically, it is slightly faster than local loopback networks.

Currently, it can only be used on platforms that support Unix domain sockets, such as Linux and macOS. It is not available until Windows 10 Build 17036.

If DomainSocket is specified as the transport mode, the ports and IP addresses configured in the inbound and outbound proxies will be invalidated, and all transports will be replaced by DomainSocket.

DomainSocketObject

DomainSocketObject corresponds to the dsSettings item.

{
@@ -34,6 +34,6 @@
   "padding": false
 }
 

path: string

A valid file path.

Danger

This file must not exist before running Xray.

abstract: true | false

Whether it is an abstract domain socket, with a default value of false.

padding: true | false

Whether the abstract domain socket has padding, with a default value of false.

- + diff --git a/en/config/transports/grpc.html b/en/config/transports/grpc.html index 41152dded1..d5dca62ada 100644 --- a/en/config/transports/grpc.html +++ b/en/config/transports/grpc.html @@ -24,8 +24,8 @@ gRPC | Project X - - + +

gRPC

An modified transport protocol based on gRPC.

gRPC is based on the HTTP/2 protocol and can theoretically be relayed by other servers that support HTTP/2, such as Nginx.

gRPC and HTTP/2 has built-in multiplexing, so it is not recommended to enable mux.cool when using gRPC or HTTP/2.

⚠⚠⚠

  • gRPC doesn't support specifying the Host. Please enter the correct domain name in the outbound proxy address, or fill in ServerName in (x)tlsSettings, otherwise connection cannot be established.
  • gRPC doesn't support fallback to other services.
  • gRPC services are at risk of being actively probed. It is recommended to use reverse proxy tools such as Caddy or Nginx to perform path-based routing.

Tip

If you are using a reverse proxy such as Caddy or Nginx, please note the following:

  • Make sure that the reverse proxy server has enabled HTTP/2.
  • Use HTTP/2 or h2c (Caddy), grpc_pass (Nginx) to connect to Xray.
  • The path for regular mode is /${serviceName}/Tun, and for Multi mode it is /${serviceName}/TunMulti.
  • If you need to receive the client IP address, you can use the X-Real-IP header sent by Caddy / Nginx to pass the client IP.

Tip

If you are using fallback, please note the following:

  • Fallback to gRPC is not recommended, as there is a risk of being actively probed.
  • Please make sure that h2 is the first priority in (x)tlsSettings.alpn, otherwise gRPC (HTTP/2) may not be able to complete TLS handshake.
  • gRPC cannot perform path-based routing by Xray.

GRPCObject

GRPCObject corresponds to the grpcSettings item.

{
@@ -37,6 +37,6 @@
   "initial_windows_size": 0
 }
 

serviceName: string

A string that specifies the service name, similar to the path in HTTP/2.

The client will use this name for communication, and the server will verify whether the service name matches.

multiMode: true | false BETA

true enables multiMode, with a default value of false.

This is an experimental option that may not be retained for the long term, and cross-version compatibility is not guaranteed. This mode can bring about a performance improvement of around 20% in test environments, but actual effects may vary depending on the transmission rate.

Tip

Only need to be configured in outbound (client).

idle_timeout: number

The health check is performed when no data transmission occurs for a certain period of time, measured in seconds. If this value is set to less than 10, 10 will be used as the minimum value.

Tip

If you are not using reverse proxy tools such as Caddy or Nginx (which is usually the case), if this value is set to less than 60, the server may send "unexpected h2 GOAWAY" frames to close existing connections.

By default, the health check is not enabled.

Tip

Only need to be configured in outbound (client).

Tip

Enabling health checks may help solve some "connection drop" issues.

health_check_timeout: number

The timeout for the health check, measured in seconds. If the health check is not completed within this time period, it is considered to have failed. The default value is 20

Tip

Only need to be configured in outbound (client).

permit_without_stream: true | false

true allows health checks to be performed when there are no sub-connections. The default value is false.

Tip

Only need to be configured in outbound (client).

initial_windows_size: number

The initial window size of the h2 stream. When the value is less than or equal to 0, this feature does not take effect. When the value is greater than 65535, the Dynamic Window mechanism will be disabled. The default value is 0, which means it is not effective.

Tip

Only need to be configured in outbound (client).

Tip

When using Cloudflare CDN, set the value to 35536 or higher to disable the Dynamic Window mechanism and prevent Cloudflare CDN from sending "unexpected h2 GOAWAY" frames to close existing connections.

- + diff --git a/en/config/transports/h2.html b/en/config/transports/h2.html index 8f77e6385e..c3c8653748 100644 --- a/en/config/transports/h2.html +++ b/en/config/transports/h2.html @@ -24,8 +24,8 @@ HTTP/2 | Project X - - + +

HTTP/2

The transmission mode based on HTTP/2 fully implements the HTTP/2 standard and can be relayed by other HTTP servers (such as Nginx).

Based on the recommendations of HTTP/2, both the client and server must enable TLS to use this transmission mode normally.

HTTP/2 has built-in multiplexing, so it is not recommended to enable mux.cool when using HTTP/2.

Tip

The current version of the transmission mode based on HTTP/2 does not require TLS configuration for inbound (server-side).

This makes it possible to use a plaintext HTTP/2 protocol called h2c for communication between the gateway and Xray, with external gateway components handling the TLS layer conversation in special-purpose load-balancing deployment environments.

Warning

⚠️ If you are using fallback, please note the following:

  • Please make sure that h2 is included in (x)tlsSettings.alpn, otherwise HTTP/2 cannot complete TLS handshake.
  • HTTP/2 cannot perform path-based routing, so it is recommended to use SNI-based routing.

HttpObject

HttpObject corresponds to the httpSettings in the Transport Protocol,

{
@@ -39,6 +39,6 @@
   }
 }
 

host: [string]

A string array, where each element is a domain name.

The client will randomly select a domain name from the list for communication, and the server will verify whether the domain name is in the list.

path: string

The HTTP path starts with / and must be the same value between the client and server.

The default value is /

read_idle_timeout: number

The connection health check is performed when no data has been received for a certain period of time, measured in seconds.

By default, the health check is disabled.

Tip

Only need to be configured in outbound (client).

Tip

Enabling health checks may help solve some "connection drop" issues.

health_check_timeout: number

The timeout for the health check, measured in seconds. If the health check is not completed within this time period, it is considered to have failed. The default value is 15

Tip

Only need to be configured in outbound (client).

method: string

HTTP request method. The default value is PUT

Please refer this thisopen in new tag when configure.

headers: map{ string: [string] }

Custom HTTP headers, defined as key-value pairs. Each key represents an HTTP header name and its corresponding value is an array.

- + diff --git a/en/config/transports/httpupgrade.html b/en/config/transports/httpupgrade.html index 64af494a3e..30dbae8c77 100644 --- a/en/config/transports/httpupgrade.html +++ b/en/config/transports/httpupgrade.html @@ -24,8 +24,8 @@ HTTPUpgrade | Project X - - + +

HTTPUpgrade

A WebSocket-like transport protocol implementing the HTTP/1.1 upgrade and response, allowing it to be reverse proxied by web servers or CDNs just like WebSocket, but without the need to implement the remaining portions of the WebSocket protocol, yielding better performance.

Standalone usage is not recommended, but rather in conjunction with other security protocols like TLS.

HttpUpgradeObject

The HttpUpgradeObject corresponds to the httpupgradeSettings section under transport configurations.

{
@@ -37,6 +37,6 @@
   }
 }
 

acceptProxyProtocol: true | false

For inbounds only. Specifies whether to accept the PROXY protocol.

The PROXY protocolopen in new tag is used to pass the real IP address and port of a connection along. Ignore it if you have no knowledge regarding this.

Common reverse proxies (e.g. HAProxy, NGINX) and VLESS fallbacks xver can be configured for its inclusion.

When true, the downstream must first send PROXY protocol version 1 or 2 after establishing the underlying TCP connection, or the connection will be closed.

path: string

HTTP path used by the HTTPUpgrade connection. Defaults to "/".

If the path property include an ed query field (e.g. /mypath?ed=2560), "early data" will be used to decrease latency, with the value defining the threshold of the first packet's size. If the size of the first packet exceeds the defined value, "early data" will not be applied. The recommended value is 2560.

host: string

HTTP Host sent by the HTTPUpgrade connection. Empty by default. If this value is empty on the server, the host header sent by clients will not be validated.

If the Host header has been defined on the server in any way, the server will validate if the Host header matches.

The current priority of the Host header sent by clients: host > headers > address

headers: map {string: string}

Customized HTTP headers defined in key-value pairs. Defaults to empty.

- + diff --git a/en/config/transports/mkcp.html b/en/config/transports/mkcp.html index b20228027a..ab3c0dac44 100644 --- a/en/config/transports/mkcp.html +++ b/en/config/transports/mkcp.html @@ -24,8 +24,8 @@ mKCP | Project X - - + +

mKCP

mKCP uses UDP to emulate TCP connections.

mKCP sacrifices bandwidth to reduce latency. To transmit the same content, mKCP generally consumes more data than TCP.

Tip

Make sure the firewall on the host is configured correctly.

KcpObject

KcpObject corresponds to the kcpSettings in the Transport Protocol,

{
@@ -45,6 +45,6 @@
   "type": "none"
 }
 

type: string

Type of obfuscation. Corresponding inbound and outbound must have the same value. Choices are:

  • "none":Default value. No obfuscation is used.
  • "srtp":Obfuscated as SRTP traffic. It may be recognized as video calls such as Facetime.
  • "utp":Obfuscated as uTP traffic. It may be recognized as Bittorrent traffic.
  • "wechat-video":Obfuscated to WeChat traffic.
  • "dtls":Obfuscated as DTLS 1.2 packets.
  • "wireguard":Obfuscated as WireGuard packets. (NOT true WireGuard protocol)

Special Thanks

Improvements to the KCP protocol

smaller protocol header

The original KCP protocol uses a fixed header of 24 bytes, while mKCP modifies it to 18 bytes for data packets and 16 bytes for acknowledgement (ACK) packets. A smaller header helps evade feature detection and speeds up transmission.

In addition, the original KCP can only confirm that one packet has been received with a single ACK packet. This means that when KCP needs to confirm that 100 packets have been received, it will send out 2400 bytes of data (24 x 100), including a large amount of repeated header information that wastes bandwidth. mKCP compresses multiple ACK packets, so 100 ACK packets only require 418 bytes (16 + 2 + 100 x 4), which is equivalent to one-sixth of the original KCP.

ACK packet retransmission

In the original KCP protocol, an ACK packet is only sent once. If an ACK packet is lost, it will cause unnecessary bandwidth waste due to data retransmission. In contrast, mKCP retransmits ACK packets at a certain frequency until they are confirmed by the sender. The size of a single ACK packet is 22 bytes, much smaller than the data packets which are over 1000 bytes. Therefore, the cost of retransmitting ACK packets is much lower.

Connection state control

mKCP can effectively initiate and close connections. When the remote host initiates disconnection, the connection will be released within two seconds. When the remote host lost connection, the connection will be released within a maximum of 30 seconds.

The original KCP does not support this scenario.

- + diff --git a/en/config/transports/quic.html b/en/config/transports/quic.html index 37ce1cc92f..07bd03b8e6 100644 --- a/en/config/transports/quic.html +++ b/en/config/transports/quic.html @@ -24,8 +24,8 @@ QUIC | Project X - - + +

QUIC

QUIC (Quick UDP Internet Connection) is a protocol proposed by Google for multiplexed and concurrent transmission using UDP. Its main advantages are:

  1. Reduced number of roundtrips in handshake phase. (1-RTT or 0-RTT)
  2. Multiplexing, and no Head-of-Line blockingopen in new tag problem.
  3. Connection migration, (mainly on the client side) when switching from Wifi to 4G, the connection will not be interrupted.

QUIC is currently in the experimental phase and uses IETF implementation that is still being standardized, so compatibility with the final version cannot be guaranteed.

  • Default settings:

QuicObject

QuicObject corresponds to the quicSettings item in the Transport Protocol.

Danger

The configurations of both endpoints must be identical, otherwise the connection will fail.

QUIC requires TLS to be enabled and if it is not enabled in the Transport Protocol, Xray will issue a self-signed certificate for TLS communication.

{
@@ -39,6 +39,6 @@
   "type": "none"
 }
 

type: string

Type of obfuscation. Corresponding inbound and outbound proxy must have the same settings. Choices are:

  • "none": Default value. No obfuscation is used.
  • "srtp": Obfuscated as SRTP traffic. It may be recognized as video calls such as Facetime.
  • "utp": Obfuscated as uTP traffic. It may be recognized as Bittorrent traffic.
  • "wechat-video": Obfuscated to WeChat traffic.
  • "dtls": Obfuscated as DTLS 1.2 packets.
  • "wireguard": Obfuscated as WireGuard packets. (NOT true WireGuard protocol)

Tip

When neither encryption nor obfuscation is enabled, QUIC transport is compatible with other QUIC tools. However it is recommended to enable either or both for better undetectable communication.

- + diff --git a/en/config/transports/tcp.html b/en/config/transports/tcp.html index 180e9775d6..db0649fa53 100644 --- a/en/config/transports/tcp.html +++ b/en/config/transports/tcp.html @@ -24,8 +24,8 @@ TCP | Project X - - + +

TCP

TCP (Transmission Control Protocol) is currently one of the recommended transport protocols

It can be combined with various protocols in multiple ways.

TcpObject

TcpObject corresponds to the tcpSettings item in the Transport Protocol.

{
@@ -69,6 +69,6 @@
   }
 }
 

version: string

HTTP version, default is "1.1"

status: string

HTTP status, default is "200"

reason: string

HTTP status description, default value is "OK"

headers: map {string, [ string ]}

HTTP header, a key-value pair, each key represents the name of an HTTP header, and the corresponding value is an array.

Each request will include all the keys and randomly select a corresponding value. Please refer to the default values shown in the example above.

- + diff --git a/en/config/transports/websocket.html b/en/config/transports/websocket.html index 5e6c6cdc1f..ca63b97665 100644 --- a/en/config/transports/websocket.html +++ b/en/config/transports/websocket.html @@ -24,8 +24,8 @@ WebSocket | Project X - - + +

WebSocket

Uses standard WebSocket for data transmission.

WebSocket connections can be proxied by other web servers (like NGINX) or by VLESS fallback paths.

Tip

WebSocket inbounds will parse the X-Forwarded-For header received, overriding the source address with a higher priority than the source address got from PROXY protocol.

WebSocketObject

WebSocketObject corresponds to the wsSettings property of the transport configs.

{
@@ -37,6 +37,6 @@
   }
 }
 

acceptProxyProtocol: true | false

Only used by inbounds. Indicates whether to accept the PROXY protocol.

The PROXY protocolopen in new tag is used to transmit the real source IP and port of connections. If you are not familiar with this, leave it alone.

Commonplace reverse proxy software solutions (like HAProxy and NGINX) can be configured to have source IPs and ports sent with PROXY protocol. Same goes to VLESS fallbacks xver.

When true, after the underlying TCP connection is established, the downstream must first send the source IPs and ports in PROXY protocol v1 or v2, or the connection will be terminated.

path: string

The HTTP path used by the WebSocket connection. Defaults to "/".

If path contains the ed query parameter, early data will be activated for latency reduction, and its value will be the length threshold of the first packet. If the length of the first packet exceeds this value, early data won't be activated. The recommended value is 2560, with a maximum of 8192. Compatibility problems can occur when the value is set too high. Try lowering the threshold when encountering such problems.

host: string

The Host header sent in HTTP requests. Defaults to an empty string. Servers will not validate the Host header sent by clients when left blank.

If the Host header has been defined on the server in any way, the server will validate if the Host header matches.

The current priority of the Host header sent by clients: host > headers > address

headers: map {string: string}

Customized HTTP headers defined in key-value pairs. Defaults to empty.

Browser Dialer

Use the browser to handle TLS, see Browser Dialer

- + diff --git a/en/development/index.html b/en/development/index.html index 35392f8ffa..5e3d7cf329 100644 --- a/en/development/index.html +++ b/en/development/index.html @@ -24,11 +24,11 @@ Development Guide | Project X - - + +

Development Guide

Compile Documentation

Xray supports multiple platforms, and you can perform cross-compilation on various platforms by yourself.

Please click Compile Documentation to view specific compile-related content.

Design Concept

Xray kernel provides a platform for secondary development.

This section explains the design goals and architecture of Xray.

Please click Design Principles to learn about the design goals and architecture of Xray.

Development Standards

This section outlines the guidelines to follow when obtaining code, developing, submitting PRs, as well as the relevant coding standards.

Please click Development Specification to view the guidelines that should be followed during Xray development.

Protocol Details

Xray uses many protocols, and you can obtain a detailed description of each protocol through various means.

VLESS Protocol

VLESS is a stateless lightweight transport protocol that can serve as a bridge between Xray clients and servers.

VMess Protocol

VMess is an encrypted transport protocol that can act as a bridge between Xray clients and servers.

Mux.Cool Protocol

Mux.Cool protocol is a multiplexing transport protocol used to transmit multiple independent data streams within an established data stream.

mKCP Protocol

mKCP is a stream transmission protocol modified from the KCP protocolopen in new tag that can transmit arbitrary data streams in order.

- + diff --git a/en/development/intro/compile.html b/en/development/intro/compile.html index 1d52d1ae11..a82500b418 100644 --- a/en/development/intro/compile.html +++ b/en/development/intro/compile.html @@ -24,8 +24,8 @@ Compile the document | Project X - - + +

Compile the document

Preparatory Work

Xray uses Golangopen in new tag as its programming language, so you need to install the latest version of Golang first in order to compile.

If you happen to use Windows, please make sure to use Powershell.

Pull Xray source code

git clone https://github.com/XTLS/Xray-core.git
@@ -38,6 +38,6 @@
 $env:GOOS="linux"
 $env:GOARCH="amd64"
 

go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main```

After uploading to the server, remember to execute chmod +x xray in the server terminal.

Tip

Execute go tool dist list to view all supported systems and architectures.

Reproducible Build:

Following the above steps, it is possible to compile and release an identical binary file as the one in Release.

Warning

Please confirm that you are using the same Golang version as the one used to compile the release.

- + diff --git a/en/development/intro/design.html b/en/development/intro/design.html index 70f02923e5..b83b89dcf2 100644 --- a/en/development/intro/design.html +++ b/en/development/intro/design.html @@ -24,11 +24,11 @@ Design Objectives | Project X - - + +

Design Objectives

  • Xray Kernel provides a platform that supports essential network proxy functions and can be developed upon to provide a better user experience.
  • Cross-platform is the primary principle to reduce the cost of secondary development.

Architecture

Architecture

The kernel is divided into three layers: the application layer, the proxy layer, and the transport layer.

Each layer contains several modules, which are independent of each other. Modules of the same type can be seamlessly replaced.

Application Layer

The application layer contains some commonly used functions in proxy layers, which are abstracted for reuse in different proxy modules.

The modules at the application layer should be implemented purely in software and should not be dependent on hardware or platform-related technologies.

List of Important Modules:

  • Dispatcher: Used to transfer data received by the inbound agent to the outbound agent;
  • Router: Routing module, see Routing Configuration for details;
  • DNS: Built-in DNS server module;
  • Proxy Manager: Proxy manager;

Proxy Layer

The proxy layer is divided into two parts: Inbound Proxy and Outbound Proxy.

The two parts are independent of each other, where the inbound proxy does not rely on a specific outbound proxy, and vice versa.

Inbound Proxy

Outbound Proxy

Transport Layer

The transport layer provides a set of tools and modules related to network data transmission.

- + diff --git a/en/development/intro/guide.html b/en/development/intro/guide.html index f44c85f5a5..70e53ea089 100644 --- a/en/development/intro/guide.html +++ b/en/development/intro/guide.html @@ -24,8 +24,8 @@ Development Standards | Project X - - + +

Development Standards

Basic

Version Control

Project X's code is hosted on GitHub:

You can use Gitopen in new tag to get the code.

Branch

  • The main branch is the backbone of this project.
  • The main branch is also the release branch of this project.
  • It is necessary to ensure that main can be compiled and used normally at any time.
  • If you need to develop new features, please create a new branch for development. After development and sufficient testing, merge it back to the main branch.
  • Please delete branches that have been merged into the main branch and are no longer necessary.

Release

WIP (Note: this is not translatable as it is a technical tag)
  • Create two release channels: one for the beta version and another for the stable version.
    • The beta version, also known as the daily build, is mainly used for specific testing, experimentation, and instant feedback and improvement.
    • The stable version, updated regularly (e.g. monthly), merges stable modifications and releases them.

Citing other projects

  • Golang
    • It is recommended to use the Golang standard library and libraries under golang.org/x/open in new tag for product code;
    • If you need to reference other projects, please create an issue for discussion beforehand;
  • Other
    • Tools that do not violate the agreement of both parties and are helpful to the project can be used.

Development Process

Before Writing Code

If you encounter any issues or have any ideas for the project, please create an issueopen in new tag for discussion to reduce redundant work and save time spent on coding.

Modify the code

  • Golang
    • Please refer to Effective Goopen in new tag;
    • Run go generate core/format.go before each push;
    • If you need to modify protobuf, such as adding new configuration items, please run: go generate core/proto.go;
    • It is recommended to pass the test before submitting a pull request: go test ./...;
    • It is recommended to have more than 70% code coverage for newly added code before submitting pull requests.
  • Other
    • Please pay attention to the readability of the code.

Pull Request

  • Before submitting a PR, please run git pull https://github.com/xray/xray-core.git to ensure that the merge can proceed smoothly;
  • One PR only does one thing. If there are fixes for multiple bugs, please submit a PR for each bug;
  • Due to Golang's special requirements (Package path), the PR process for Go projects is different from other projects. The recommended process is as follows:
    1. Fork this project first and create your own github.com/<your_name>/Xray-core.git repository;
    2. Clone your own Xray repository to your local machine: git clone https://github.com/<your_name>/Xray-core.git;
    3. Create a new branch based on the main branch, for example git branch issue24 main;
    4. Make changes on the new branch and commit the changes;
    5. Before pushing the modified branch to your own repository, switch to the main branch, and run git pull https://github.com/xray/xray-core.git to pull the latest remote code;
    6. If new remote code is obtained in the previous step, switch to the branch you created earlier and run git rebase main to perform branch merging. If there is a file conflict, you need to resolve the conflict;
    7. After the previous step is completed, you can push the branch you created to your own repository: git push -u origin your-branch
    8. Finally, send a PR from your new pushed branch in your own repository to the main branch of xtls/Xray-core;
    9. Please fully describe the purpose of this PR, including the problem solved, the new feature added, or the modifications made in the title and body of the PR;
    10. Please be patient and wait for the developer's response.

Modifying Code

Functional issue

Please submit at least one test case to verify changes to existing functionality.

Please provide the necessary test data to demonstrate performance issues in existing code or performance improvements in new code.

New Feature

  • If the new feature does not affect the existing functionality, please provide a toggle (such as a flag) that can be turned on/off, and keep the new feature disabled by default.
  • For major new features (such as adding a new protocol), please submit an issue for discussion before development.

Other

It depends on the specific situation.

Xray Coding Guidelines

The following content is applicable to Golang code in Xray.

Code Structure

Xray-core
@@ -40,6 +40,6 @@
 │   ├── vmess
 ├── transport  // Transport module
 

Coding Standards

Basic practices are consistent with the recommendations of the official Golang, with a few exceptions. Written here to help everyone familiarize themselves with Golang.

Naming

  • Use a single English word for file and directory names, such as hello.go;
    • If not possible, use a hyphen for directories / underscore for files to connect two (or more) words, such as hello-world/hello_again.go;
    • Use _test.go to name test code files;
  • Use PascalCase for types, such as ConnectionHandler;
    • Do not force lowercase for abbreviations, i.e. HTML does not need to be written as Html;
  • Use PascalCase for public member variables;
  • Use camelCase for private member variables, such as privateAttribute;
  • For easy refactoring, it is recommended to use PascalCase for all methods;
    • Place completely private types in internal.

Content Organization

  • A file contains a main type and its related private functions;
  • Testing-related files, such as Mock tools, should be placed in the testing subdirectory.
- + diff --git a/en/development/protocols/mkcp.html b/en/development/protocols/mkcp.html index 9a9d5485b7..f589257ef6 100644 --- a/en/development/protocols/mkcp.html +++ b/en/development/protocols/mkcp.html @@ -24,11 +24,11 @@ mKCP Protocol | Project X - - + +

mKCP Protocol

mKCP is a stream transfer protocol, modified from the KCP protocolopen in new tag, which can transmit any data stream in order.

Version

mKCP has no version number and does not guarantee compatibility between versions.

Dependencies

Underlying Protocol

mKCP is a protocol based on UDP, and all communication uses UDP transmission.

Functions

  • fnv: FNV-1aopen in new tag hash function
    • Takes a string of arbitrary length as input parameter;
    • Outputs a 32-bit unsigned integer.

Communication Process

  1. mKCP splits data streams into several data packets for transmission. Each data stream has a unique identifier to distinguish it from other data streams. Each data packet in the data stream carries the same identifier.
  2. mKCP does not have a handshake process. When receiving a data packet, it determines whether it is a new call or an ongoing call based on the identifier of the data stream it carries.
  3. Each data packet contains several segments (Segment), which are divided into three types: data (Data), acknowledgment (ACK), and heartbeat (Ping). Each segment needs to be processed separately.

Data Format

Data Packet

4 Bytes2 BytesL Bytes
Auth AData Len LFragment

as which:

  • Authentication information A = fnv(fragment), big endian;
  • The fragment may contain multiple sections.

Data snippet

2 bytes1 byte1 byte4 bytes4 bytes4 bytes2 bytesLen bytes
Conv flagCmd flagOpt flagTimestampSequenceUnacknowledgedLen flagData

as which:

  • Identifier Conv: Identifier for mKCP data stream
  • Command Cmd: Constant 0x01
  • Option Opt: Optional values include:
    • 0x00: Empty option
    • 0x01: Opposite party has sent all data
  • Timestamp Ts: Time when the current segment was sent from the remote end, big endian
  • Sequence Number Sn: The position of the data segment in the data stream, the sequence number of the starting segment is 0, and each new segment is sequentially added by 1
  • Unacknowledged Sequence Number Una: The minimum Sn that the remote host is sending and has not yet received confirmation.

Confirmation snippet

2 bytes1 byte1 byte4 bytes4 bytes4 bytes2 bytesLen * 4 bytes
Conv IDCmdOptWndNext Seq NumberTimestampLengthReceived Seq Number

as which:

  • Identifier Conv: Identifier of the mKCP data stream
  • Command Cmd: Constant 0x00
  • Option Opt: Same as above
  • Window Wnd: The maximum sequence number that the remote host can receive
  • Next receive sequence number Sn: The smallest sequence number of the data segment that the remote host has not received
  • Timestamp Ts: The timestamp of the latest received data segment by the remote host, which can be used to calculate the delay
  • Received sequence numbers: Each 4 bytes, indicating that the data of this sequence number has been confirmed received.

as which:

  • The remote host expects to receive data within the serial number [Sn, Wnd) range.

Heartbeat Fragments

2 Bytes1 Byte1 Byte4 Bytes4 Bytes4 Bytes
Conv IDCmdOptUnacknowledged Seq NoNext Receive Seq NoRto

as which:

  • Identifier Conv: Identifier for the mKCP data stream
  • Command Cmd: Optional values include:
    • 0x02: Remote host forcibly terminates the session
    • 0x03: Normal heartbeat
  • Option Opt: Same as above
  • Unacknowledged sequence number Una: Same as the Una of the data fragment
  • Next receive sequence number Sn: Same as the Sn of the acknowledgement fragment
  • Delay Rto: Delay calculated by the remote host itself
- + diff --git a/en/development/protocols/muxcool.html b/en/development/protocols/muxcool.html index f9028aa0ee..72732479c2 100644 --- a/en/development/protocols/muxcool.html +++ b/en/development/protocols/muxcool.html @@ -24,11 +24,11 @@ Mux.Cool Protocol | Project X - - + +

Mux.Cool Protocol

Mux.Cool protocol is a multiplexing transport protocol that is used to transmit multiple independent data streams within an established data stream.

Version

The current version is 1 Beta.

Dependencies

Underlying Protocol

Mux.Cool must run on top of a reliable established data stream.

Communication Process

Within a Mux.Cool connection, multiple sub-connections can be transmitted, each with a unique ID and status. The transmission process consists of frames, with each frame used to transmit data for a specific sub-connection.

Client behavior

When there is a need for a connection and there are no existing available connections, the client initiates a new connection to the server, referred to as the "main connection".

  1. One main connection can be used to send several sub-connections. The client can decide independently how many sub-connections the main connection can handle.
  2. For a new sub-connection, the client must send the New status to notify the server to establish the sub-connection, and then use the Keep status to transmit data.
  3. When the sub-connection ends, the client sends the End status to notify the server to close the sub-connection.
  4. The client can decide when to close the main connection, but must ensure that the server also maintains the connection.
  5. The client can use the KeepAlive status to prevent the server from closing the main connection.

Server-side behavior

When a new sub-connection is received on the server side, the server should handle it as a normal connection.

  1. When the status "End" is received, the server can close the upstream connection to the target address.
  2. The same ID used in the request must be used to transfer sub-connection data in the server response.
  3. The server cannot use the "New" status.
  4. The server can use the KeepAlive status to avoid the client closing the main connection.

Data Format

Mux.Cool uses symmetric transmission format, where the client and server send and receive data in the same format.

Frame Format

2 BytesL BytesX Bytes
Metadata Length LMetadataAdditional Data

Metadata

There are several types of metadata. All types of metadata contain two items, ID and Opt, with the following meanings:

  • ID: Unique identifier of the sub-connection
    • For general MUX sub-connections, the ID is accumulated starting from 1
    • For XUDP, the ID is always 0
  • Opt:
    • D(0x01): Additional data is available

When option Opt(D) is enabled, the additional data format is as follows:

2 BytesX-2 Bytes
Length X-2Data
2 Bytes1 Byte1 Byte1 Byte2 Bytes1 ByteA Bytes
ID0x01OptionNetwork NPortType TAddress

where:

  • Network type N:
    • 0x01: TCP, indicating that the traffic of the current sub-connection should be sent to the destination in the way of TCP.
    • 0x02: UDP, indicating that the traffic of the current sub-connection should be sent to the destination in the way of UDP.
  • Address type T:
    • 0x01: IPv4
    • 0x02: Domain name
    • 0x03: IPv6
  • Address A:
    • When T = 0x01, A is a 4-byte IPv4 address;
    • When T = 0x02, A is a 1-byte length (L) + L-byte domain name;
    • When T = 0x03, A is a 16-byte IPv6 address;

If Opt(D) is enabled when creating a sub-connection, the data carried by this frame needs to be sent to the target host.

Keep sub-connections

2 Bytes1 Byte1 Byte
ID0x02Option

If Opt(D) is enabled while maintaining sub-connections, the data carried by this frame needs to be sent to the target host. XUDP adds the UDP address after Opt(D), and the format is the same as creating a new sub-connection.

End

2 Bytes1 Byte1 Byte
ID0x03Option

If Opt(D) is enabled while maintaining sub-connections, the data carried by this frame needs to be sent to the target host.

KeepAlive

2 Bytes1 Byte1 Byte
ID0x04Option Opt

While staying connected:

  • If Opt(D) is enabled, the data carried by this frame must be discarded.
  • ID can be a random value.

Application

The Mux.Cool protocol is agnostic to the underlying protocol and can theoretically use any reliable streaming connection to transmit Mux.Cool protocol data.

In target-oriented protocols such as Shadowsocks and VMess, a specified address must be included when establishing a connection. To maintain compatibility, the Mux.Cool protocol specifies the address as "v1.mux.cool". When the target address of the main connection matches this address, the Mux.Cool forwarding method is used. Otherwise, forwarding is done in the traditional way. (Note: This is an internal tag in the program, and VMess and VLESS do not send the "v1.mux.cool" address in data packets.)

- + diff --git a/en/development/protocols/vless.html b/en/development/protocols/vless.html index 52e338c436..3af1ae1b35 100644 --- a/en/development/protocols/vless.html +++ b/en/development/protocols/vless.html @@ -24,11 +24,11 @@ VLESS Protocol | Project X - - + +

VLESS Protocol

VLESS is a stateless lightweight transmission protocol that can be used as a bridge between Xray clients and servers.

Request & Response

1 byte16 bytes1 byteM bytes1 byte2 bytes1 byteS bytesX bytes
Protocol VersionEquivalent UUIDAdditional Information Length MAdditional Information ProtoBufInstructionPortAddress TypeAddressRequest Data
1 Byte1 ByteN BytesY Bytes
Protocol Version, consistent with the requestLength of additional information NAdditional information in ProtoBufResponse data

VLESS had the aforementioned structure as early as the second alpha test version (ALPHA 2), with BETA being the fifth test version.

"Response authentication" has been replaced with "Protocol version" and moved to the front, allowing VLESS to upgrade and eliminate the overhead of generating pseudo-random numbers. The obfuscation-related structure has been replaced with "Additional information" (ProtoBuf) and moved forward, giving the protocol itself scalability, with minimal overhead (gogo/protobufopen in new tag). If there is no additional information, there is no relevant overhead.

I always thought that "response authentication" was not necessary, and ALPHA replaced crypto/rand with math/rand in order to improve the performance of random number generation, which is no longer needed.

The "Protocol Version" not only serves as "Response Authentication", but also gives VLESS the ability to upgrade the protocol structure seamlessly, bringing infinite possibilities. The "Protocol Version" is 0 in the test version and 1 in the official version. If there are any incompatible protocol structural changes in the future, the version should be upgraded.

The design of VLESS server is switch version, which supports all VLESS versions at the same time. If you need to upgrade the protocol version (which may not happen), it is recommended that the server support it one month in advance, and then change the client after one month. VMess requests also have protocol versions, but their authentication information is outside, and the instruction part is highly coupled and has fixed encryption, which makes the protocol version meaningless inside. The server does not judge it, and the response does not have a protocol version. Trojan's protocol structure does not have a protocol version.

The following is a UUID. I used to think that 16 bytes were a bit long and considered shortening it. However, I later saw that Trojan used 56 printable characters (56 bytes), which completely dispelled this idea. The server needs to verify the UUID every time, so performance is also very important: VLESS's Validator has undergone multiple refactoring/upgrades. Compared with VMess, it is very concise and consumes very few resources. It can support a large number of users at the same time, and its performance is also very strong. The verification speed is extremely fast (sync.Map). API dynamically adds and deletes users, making it more efficient and smooth. https://github.com/XTLS/Xray-core/issues/158

Introducing ProtoBuf is an innovation, which will be explained in detail later. The structure from "instruction" to "address" is currently identical to VMess and also supports Mux.

Overall, ALPHA 2 to BETA mainly includes: structural evolution, cleaning and integration, performance improvement, and more completeness. All of these are incremental improvements, please refer to VLESS Changesopen in new tag for details.

ProtoBuf

It seems that only VLESS supports embedding ProtoBuf, which is a data exchange format that encodes information tightly into binary TLV (Tag Length Value) structures.

The reason is that I saw an article that said that SS has some drawbacks, such as the lack of a design error reporting mechanism, and the client cannot take further action based on different errors. (But I don't agree that all errors should be reported, otherwise it can't prevent active probing. In the next beta version, the server can return a custom string of information.) So I think a scalable structure is important, and in the future, it can also carry dynamic port instructions. Not only the response, but the request also needs a similar structure. I originally planned to design TLV by myself, but then I found that ProtoBuf is the structure, ready-made, and it is completely suitable for this purpose, and the support for various languages is also good.

Currently, "Additional Information" only has Scheduler and SchedulerV, which are substitutes for MessName and MessSeed. When you don't need them, the "Additional Information Length" is 0, so there is no ProtoBuf serialization/deserialization overhead. Actually, I prefer to call this process "concatenation" because that's all pb does in principle, and the related overhead is minimal. The concatenated bytes are very compact, similar to ALPHA's solution, and those who are interested can output and compare them separately.

To indicate different levels of support for additional information (Addons, which can be understood as plugins and can have many plugins in the future), the next beta version will add "Addon Version" before "Addon Length". 256-1 = 255 bytes is enough and reasonable (65535 is too much and there may be malicious padding), and only one-tenth of the existing space is used. In the future, there will not be so many addons at the same time, and most of the time there will be no addons at all. If it is not enough, you can upgrade to a newer version of VLESS.

To reduce logical judgment and other expenses, it is temporarily decided that Addons will not use a multi-level structure. A month ago, there was an idea of "variable protocol format". PB can shuffle the order, but it is not necessary because the design of modern encryption will not allow bystanders to see that the headers of the two transmissions are the same.

Below is an introduction to the concepts of Schedulers and Encryption, both of which are optional. One is designed to address issues related to traffic timing, while the other is designed to address cryptographic issues.

Flow

Flow Control (Formerly Traffic Scheduler)

The Flow Control command is carried by ProtoBuf and manages the data section.

I previously discovered that VMess's original "metadata obfuscation" feature didn't provide any meaningful changes in TLS but only decreased performance. Consequently, VLESS has abandoned this feature. Moreover, the term "obfuscation" is often misinterpreted as camouflage, so it has been discarded.

As for camouflage, if it can't be an exact match, wouldn't it be a noticeable characteristic? If it could be an exact match, why not use the intended target for camouflage directly? Initially, I used SSR but found it only provided superficial disguises, fooling operators. Thus, I stopped using it.

Purpose of Flow Control

Flow Control influences macro traffic temporal characteristics rather than micro characteristics addressed by encryption. Traffic temporal characteristics can be:

  1. Protocol-based, e.g., Socks5 handshake when using Socks5 over TLS. Different traits on TLS are considered different protocols for monitors. Infinite schedulers equate to infinite protocols (reallocating data sent each time).
  2. Behavior-based, e.g., loading files, their order, and size when accessing Google's homepage. Adding another encryption layer cannot effectively conceal this information.

Schedulers don't require wrapping like encryption since the header data's tiny amount is negligible compared to the remaining data.

BETA 2 is anticipated to introduce two basic schedulers: Zstd compression and dynamic data expansion. Advanced operations will control and distribute at a macro level, but for now, these remain under development.

Encryption

Unlike VMess, which is highly coupled, VLESS allows the server and client to pre-agree on an encryption method, which is only encrypted with an outer layer. This is somewhat similar to using TLS, which does not affect any of the data carried, and can be understood as replacing TLS with pre-agreed encryption at the bottom. Compared with high coupling, this approach is more reasonable and flexible: if there is a security issue with one encryption method, it can be discarded and another one can be used directly, which is very convenient. The VLESS server also allows for different encryption methods to coexist.

Compared with VMess, VLESS replaces security with encryption and disableInsecureEncryption with decryption, which solves all the problems. Currently, encryption and decryption only accept "none" and cannot be left blank (even if there are connection security checks in the future), as detailed in the VLESS configuration document. Encryption does not need to be moved out one level, firstly because it cannot reuse a lot of code, and secondly because it will affect the control granularity, which will be understood by looking at future applications.

Encryption supports two types of forms. One type is completely independent and requires an additional password, suitable for private use. The other type combines with the existing UUID for encryption, which is suitable for public use.

(If the first type of encryption is used and the password is publicly available in some form, such as multiple people sharing it, then a man-in-the-middle attack is not far away.)

A redesigned dynamic port may be released simultaneously with encryption, and the command is carried by ProtoBuf. The specific implementation and the dynamic port of VMess will also have many differences.

It is very easy to cash out encrypted currency, which adds an extra layer of writer & reader. BETA 3 is expected to support SS's aes-128-gcm and chacha20-ietf-poly1305:

The encryption on the client-side can be filled with "auto: ss_aes-128-gcm_0_123456, ss_chacha20-ietf-poly1305_0_987654". Auto will choose the most suitable one for the current machine, 0 represents the beta version, and the last one is the password. The decryption on the server-side is also filled in a similar way, and each decryption attempt will be made when the request is received.

Not all combinations need to be tried one by one: VMess encryption is divided into three parts. The first part is the authentication information, which combines UUID, alterId, and time factors. The second part is the instruction part, which is encrypted using a fixed algorithm. The instruction contains the encryption algorithm used in the data part. The third part is the important data part. It can be seen that the VMess encryption and decryption method is actually many-to-one (adapted by the server), not just combining UUID. However, it is also a relatively difficult thing to encrypt only by combining UUID. It will not be available in a short time. Considering that we now have VMessAEAD available, there is no need to rush. If VLESS introduces an encryption method that combines UUID, it is equivalent to reconstructing the entire VMess.

UDP issues

XUDP: VLESS & VMess & Mux UDP FullCone NATopen in new tag

Client Development Guide

  1. The VLESS protocol itself may have incompatible upgrades, but the parameters in the client configuration file are basically only increased and not decreased. The protocol implementation of the iOS client needs to keep up with the upgrade.
  2. Visual standard: Please use VLESS as the UI identifier uniformly, instead of VLess / Vless / vless. The configuration file is not affected, and the code should follow naturally.
  3. Encryption should be made into an input box instead of a selection box. The default value of the new configuration should be none, and if the user leaves it blank, it should be filled in with none.

Thank you to @DuckSoftopen in new tag for the proposal!

Please see VMessAEAD/VLESS Sharing Link Standard Proposalopen in new tag for more details.

- + diff --git a/en/development/protocols/vmess.html b/en/development/protocols/vmess.html index 2975f24613..5ed938463f 100644 --- a/en/development/protocols/vmess.html +++ b/en/development/protocols/vmess.html @@ -24,11 +24,11 @@ VMess Protocol | Project X - - + +

VMess Protocol

VMess is an encrypted transmission protocol that can serve as a bridge between the Xray client and server.

Version

The current version number is 1.

Dependencies

Underlying Protocol

VMess is a TCP-based protocol where all data is transmitted over TCP.

User ID

An ID is equivalent to a UUIDopen in new tag, which is a 16-byte long random number. Its function is similar to a token. An ID looks like: de305d54-75b4-431b-adb2-eb6b9e546014, it is almost entirely random and can be generated using any UUID generator, such as this oneopen in new tag.

User ID can be specified in the configuration file.

Functions

Communication Process

VMess is a stateless protocol, which means that data can be transmitted directly between the client and the server without the need for a handshake. Each data transmission has no impact on other data transmissions before or after it.

When a VMess client initiates a request, the server checks whether the request comes from a legitimate client. If the validation passes, the server forwards the request and sends the obtained response back to the client.

VMess uses an asymmetric format, meaning that the requests sent by the client and the responses from the server use different formats.

Client Request

16 BytesX BytesRemaining
Authentication InformationInstruction PartData Part

Authentication Information

The authentication information is a 16-byte hash (hash) value, which is calculated as follows:

  • H = MD5
  • K = User ID (16 bytes)
  • M = UTC time accurate to seconds, with a random value of ±30 seconds from the current time (8 bytes, Big Endian)
  • Hash = HMAC(H, K, M)

Command Section

The instruction part is encrypted using AES-128-CFB.

  • Key: MD5(user ID + []byte('c48619fe-8f02-49e0-b9e9-edf763e17e21'))
  • IV: MD5(X + X + X + X), X = []byte(time generated by authentication information) (8 bytes, Big Endian)
1 Byte16 Bytes16 Bytes1 Byte1 Byte4 bits4 bits1 Byte1 Byte2 Bytes1 ByteN BytesP Bytes4 Bytes
VersionData Encryption IVData Encryption KeyResponse Authentication ValueOptionsReservedEncryption MethodReservedCommandPortAddress TypeAddressRandom ValueChecksum

Options Opt Details: (When a bit is 1, it means the option is enabled)

01234567
XXXXXMRS

of which:

  • Version Number Ver: Always 1;
  • Data Encryption IV: Random value;
  • Data Encryption Key: Random value;
  • Response Authentication V: Random value;
  • Option Opt:
    • S (0x01): Standard format data stream (recommended);
    • R (0x02): Client expects to reuse TCP connection (deprecated in Xray 2.23+);
      • This item only takes effect when S is enabled;
    • M (0x04): Enable metadata obfuscation (recommended);
      • This item only takes effect when S is enabled;
      • When this item is enabled, the client and server need to construct two Shake instances respectively, RequestMask = Shake (request data IV), ResponseMask = Shake (response data IV).
    • X: Reserved
  • Redundancy P: Random value added before checksum value;
  • Encryption Method: Specify the encryption method for the data part, and the optional values are:
    • 0x00: AES-128-CFB;
    • 0x01: No encryption;
    • 0x02: AES-128-GCM;
    • 0x03: ChaCha20-Poly1305;
  • Instruction Cmd:
    • 0x01: TCP data;
    • 0x02: UDP data;
  • Port Port: Integer port number in Big Endian format;
  • Address Type T:
    • 0x01: IPv4
    • 0x02: Domain name
    • 0x03: IPv6
  • Address A:
    • When T = 0x01, A is a 4-byte IPv4 address;
    • When T = 0x02, A is a 1-byte length (L) + L-byte domain name;
    • When T = 0x03, A is a 16-byte IPv6 address;
  • Check F: FNV1a hash of all content in the instruction except F.

Data Section

When Opt(S) is enabled, this format is used for the data section. The actual request data is divided into several small chunks, and each chunk has the following format. After the server verifies all the small chunks, it will be forwarded in the basic format.

2 BytesL Bytes
Length LData Packet

in which:

  • Length L: A big-endian integer with a maximum value of 2^14.
    • When Opt(M) is enabled, the value of L is equal to the true value xor Mask. Mask = (RequestMask.NextByte() << 8) + RequestMask.NextByte();
  • Packet: A data packet encrypted by the specified encryption method.

Before the transmission is completed, the data packet must contain actual data, in addition to the length and authentication data. When the transmission is complete, the client must send an empty data packet, that is, L = 0 (unencrypted) or the length of the authentication data (encrypted), to indicate the end of the transmission.

The packets are formatted as follows, depending on the encryption method:

  • Unencrypted:   - L bytes: actual data;
  • AES-128-CFB: The entire data section is encrypted using AES-128-CFB.   - 4 bytes: FNV1a hash of actual data;   - L - 4 bytes: actual data;
  • AES-128-GCM: Key is the Key of the instruction section, IV = count (2 bytes) + IV (10 bytes). count starts at 0 and increases by 1 for each packet; IV is the 3rd to 12th byte of the instruction section IV.   - L - 16 bytes: actual data;   - 16 bytes: GCM authentication information
  • ChaCha20-Poly1305: Key = MD5 (instruction part Key) + MD5 (MD5 (instruction part Key)), IV = count (2 bytes) + IV (10 bytes). count starts at 0 and increases by 1 for each packet; IV is the 3rd to 12th byte of the instruction section IV.   - L - 16 bytes: actual data;   - 16 bytes: Poly1305 authentication information

Server Response

The header data is encrypted using AES-128-CFB encryption. The IV is MD5 of the data encryption IV, and the Key is MD5 of the data encryption Key. The actual response data varies depending on the encryption settings.

1 Byte1 Byte1 Byte1 ByteM BytesRemaining Part
Response Authentication VOption OptCommand CmdCommand Length MCommand ContentActual Response Data

in which:

  • Response Authentication V: must match the response authentication V in the client request.
  • Option Opt:
    • 0x01: server prepares to reuse TCP connections (deprecated in Xray 2.23+).
  • Command Cmd:
    • 0x01: dynamic port command.
  • Actual response data:
    • If Opt(S) in the request is enabled, the standard format is used. Otherwise, the basic format is used.
    • Both formats are identical to the request data.
      • When Opt(M) is enabled, the value of length L is equal to the true value XOR Mask. Mask = (ResponseMask.NextByte() << 8) + ResponseMask.NextByte().

Dynamic Port Instructions

1 Byte2 Bytes16 Bytes2 Bytes1 Byte1 Byte
ReservedPortUser IDAlterIDUser levelValidity period T

in which:

  • Port: Integer port number in Big Endian format
  • T: Number of minutes as integer value.

When the client receives a dynamic port command, the server opens a new port for communication. The client can then send data to the new port. After T minutes, the port will expire, and the client must use the main port to communicate again.

Comment

  • To ensure forward compatibility, the values of all reserved fields must be 0.
- + diff --git a/en/document/command.html b/en/document/command.html index 92a102de4a..444107d9cd 100644 --- a/en/document/command.html +++ b/en/document/command.html @@ -24,8 +24,8 @@ Command Parameters | Project X - - + +

Command Parameters

Tip

Xray uses Go-style commands and parameters

Get Basic Commands

You can run xray helpto get the most basic usage of all xray, as well as available commands and instructions.

Xray is a platform for building proxies.
@@ -76,6 +76,6 @@
 

xray x25519

Generate x25519 key pair。

Usage:

xray x25519 [-i "(base64.RawURLEncoding)" --std-encoding]
 

xray wg

Generate wireguard curve25519 key pair。

Usage:

xray wg [-i "(base64.StdEncoding)"]
 

Tip

When -config is not specified, Xray will try to load config.json from the following paths:

- + diff --git a/en/document/config.html b/en/document/config.html index e0a1a99cd9..1402577dd6 100644 --- a/en/document/config.html +++ b/en/document/config.html @@ -24,8 +24,8 @@ Configure and Run | Project X - - + +

Configure and Run

After downloading and installing Xray, you need to configure it.

For demonstration purposes, only a simple configuration method is introduced here. For more templates, please refer to Xray-examplesopen in new tag.

If you need to set up more advanced features, please refer to the relevant instructions in the more detailed configuration file.

Server Configuration

You need a server outside the firewall to run server-side Xray. The configuration is as follows:

{
@@ -93,6 +93,6 @@
   }
 }
 

The only thing you need to modify in the above configuration is your server's IP address, which is indicated in the configuration. This configuration will redirect all traffic to your server, except for traffic on the local area network (such as the access router).

Run

  • On Windows and macOS, the configuration files are usually named config.json.
    • To start Xray, simply run Xray or Xray.exe.
  • On Linux, the configuration files are usually located in /etc/xray/ or /usr/local/etc/xray/.
    • To start Xray, run the command xray run -c /etc/xray/config.json.
    • Alternatively, you can use a tool like systemd to run Xray as a background service.

For more detailed instructions, please refer to the Configuration Document and Layman's Terms.

- + diff --git a/en/document/document.html b/en/document/document.html index 12d0f6ae70..12bc8dc344 100644 --- a/en/document/document.html +++ b/en/document/document.html @@ -24,14 +24,14 @@ Contribute to Project X's Document | Project X - - + +

Contribute to Project X's Document

Contributions to Project X's Document are welcome, and we appreciate every Contributor's contribution! You guys make Xray stronger!

Improve Document

Document for Project X is hosted on GitHubopen in new tag.

You can submit your changes to the Document by following these steps:

  1. Open the repository from Project X Documentopen in new tag, click fork in the upper right corner, fork a mirror image of the document repository to your own GitHub repository.

  2. Get a clone of the docs from the repository you cloned using whatever tool you like, like:

git clone https://github.com/XTLS/Xray-docs-next.git
 
  1. Create a new branch based on the main branch, such as:
git checkout -b your-branch
 
  1. Make changes on the new branch.

  2. After modification, please use Prettieropen in new tagFormat your changes.

    Note: Pull requests with formatting issues may be rejected.

  3. Submit the changes and push them to your repository

git push -u origin your-branch
 
  1. Open GitHub, click 'Pull request' to submit a pull request to Project X Documentopen in new tag.

  2. Please outline the new/modified content of this pull request in the title and body of the pull request;

  3. Waiting for a response, if the pull request is merged, your changes will be directly displayed on Project X Document Websiteopen in new tag.

Found Problems?

If you find an error in the document, you can improve the documentation or submit an issue.

- + diff --git a/en/document/index.html b/en/document/index.html index 65ec3cfacf..b254f1738a 100644 --- a/en/document/index.html +++ b/en/document/index.html @@ -24,11 +24,11 @@ Quick Start | Project X - - + +

Quick Start

This chapter will tell you how to get Xray in the easiest way and start using Xray.

Download and Install

Xray supports various platforms, and you can get various versions of Xray from various sources and methods.

Please click How to Download and Install Xray to get Xray

Configure and Run

After downloading and installing Xray, you need to configure it.

Please click How to Configure and Run Xray to learn the easiest way to configure Xray.

Command Parameters

Xray has a variety of commands and parameters available, making it flexible and powerful.

Please click Command Parameters for Xray to view more commands and parameters usages.

Improve Documents

If you're interested, please click Documents to help us improve the documents, or click theHelp us improve this page!

We are very grateful to every Contributor for their contribution! You guys make Project X even stronger!

Beginner Tutorial

A easy tutorial for beginner.

Please click 小小白白话文 to view it.

Getting Started Tips

After you have the basics, you can explore more ways to use them through Getting Started Tips.

Advanced Documentation

Tips for advanced user guidance

Click on Advanced Documentation to view it

Appreciations

Thank you very much for your selfless sharing of usage skills and experience, which makes Xray more and more powerful.

- + diff --git a/en/document/install.html b/en/document/install.html index 1e78cbeed9..f49269f197 100644 --- a/en/document/install.html +++ b/en/document/install.html @@ -24,11 +24,11 @@ Download and Install | Project X - - + +

Download and Install

Platform Support

  • Xray is available on the following platforms:
    • Windows 7 and later (x86 / amd64 / arm32 / arm64);
    • macOS 10.10 Yosemite and later (amd64 / arm64);
    • Linux 2.6.23 and later (x86 / amd64 / arm / arm64 / mips64 / mips / ppc64 / s390x / riscv64);
      • Including but not limited to Debian 7 / 8, Ubuntu 12.04 / 14.04 and subsequent versions, CentOS 7 / 8, Arch Linux, etc.;
    • FreeBSD (x86 / amd64);
    • OpenBSD (x86 / amd64);
    • Dragonfly BSD (amd64);

Download Xray

Precompiled binaries in ZIP format are available at GitHub Releasesopen in new tag found in.

Download the compressed package of the corresponding platform, and use it after decompression.

Verify the Installation Package

Xray provides two verification methods:

Install on Windows

Install on macOS

Install on Linux

Install Script

Arch Linux

Arch User Repository

Need to use AUR helpersopen in new tag, yayopen in new tag as an example, it can be installed via yay -S xray.

Arch Linux CN

First add Arch Linux CNopen in new tag repository, and then use the root user pacman -S xrayto install.

Linuxbrew

The Linuxbrew package manager is used in the same way as Homebrew: brew install xray

Debian WIP

Install via Docker

The File Structure of the Docker Image

  • /etc/xray/config.json: configuration file
  • /usr/bin/xray: Xray main program
  • /usr/local/share/xray/geoip.dat: IP data file
  • /usr/local/share/xray/geosite.dat: domain name data file

GUI Client

UUID Generator

Third-party UUID generator uuidgenerator.netopen in new tag

- + diff --git a/en/document/level-0/ch01-preface.html b/en/document/level-0/ch01-preface.html index b1efd24558..45b1897f00 100644 --- a/en/document/level-0/ch01-preface.html +++ b/en/document/level-0/ch01-preface.html @@ -24,11 +24,11 @@ [Chapter 1] Simple and Plain Language | Project X - - + +

[Chapter 1] Simple and Plain Language

1.1 Who is this document written for?

One sentence: Written for newbies who are (1) absolute beginners and (2) interested in learning how to build their own VPS.

1.2 Who is this document not written for?

Including but not limited to: experts and professionals, beginners who are too lazy to tinker on their own, advanced users who already know how to tinker, wealthy users who insist on using airport services, and those who prefer using one-click scripts. In short, if you have a technical background or don't want to build it yourself, you can close this article directly, because this article may not be suitable for you and may even make you upset.

1.3 Declaration and Other Statements

Declaration:

My technical skills are extremely limited, so this article is inevitably full of errors and flaws. If you find any problems, please kindly point them out and don't be too harsh on me.

Disclaimer:

Please judge the reliability and usability of the content of this article by yourself. If you encounter any problems or negative results when establishing and using a VPS server based on the content of this article, I am not responsible for it.

Verbose statement:

Considering the target audience of this article, which is "users with zero experience", many details will be explained in great detail, so the language may be verbose. Please be mentally prepared for this.

1.4 Why is self-hosting a challenge?

To answer this question, we need to provide a little more background information.

  1. On the matter of accessing the internet through scientific means

The act of accessing the internet using scientific methods has been around for almost 20 years (shocking!!!.jpg). Initially, one could do it with a little effort (changing the host file, using SSH), then one had to find a web proxy, and later, one had to develop a private protocol (such as Shadowsocks) and so on.

With the continuous iteration and upgrade of GFW technology over the past decade, to achieve the goal of [building your own scientific Internet access], the things that need to be done include but are not limited to:

  • Understand basic Linux commands
  • Understand network transmission protocols
  • Have the technical and financial ability to purchase and manage a VPS
  • Have the technical and financial ability to purchase and manage a domain name
  • Have the technical ability to apply for a TLS certificate, and so on.

This has turned the once simple act of [setting up a self-built VPS for accessing the internet in a secure and unrestricted manner] into a daunting challenge that intimidates newcomers.

  1. Helplessness of Zero-based Users

For non-technical users with zero foundation, if they complete the above series of operations, they will inevitably need to learn a lot of knowledge. However, after a little searching, newbies are likely to become even more confused: a large amount of information is scattered in various corners of the Internet: blogs, Q&A sites, groups, forums, GitHub, Telegram, YouTube, and so on. These pieces of information are chaotic and complex, with varying levels of quality, and may even contradict each other. Basically, they won't stop until they completely confuse the newcomer.

Faced with such chaotic information, newcomers suddenly shift from [information scarcity] to [information overload]. If they fail after several attempts of groping and guessing (which is highly probable), their enthusiasm is bound to be greatly frustrated. In this process, if they happen to seek help in some unfriendly places, they may be ridiculed even more: "You're so inexperienced, just use the airport, why bother messing around!" "Go learn Linux first before coming back to ask."

At this moment, probably only an "hehe" can express the mood.

1.5 "Why not just use the airport?"

First of all, I would like to respond to those who ridicule and criticize by asking a question: Is using the airport really a panacea?

Secondly, I believe that there is a fundamental difference between "not understanding" and "not wanting to understand". The bad attitude of some people who just want handouts is naturally annoying, but those who sincerely want to learn but don't know how should not be subject to unjustified contempt and discrimination. It is precisely this kind of bad community atmosphere that does not distinguish between newcomers that prompted me to write this article. So without further ado, let's take a look at the advantages and disadvantages of the airport:

  1. 稳定性高:机场节点数量多,分布广泛,避免了单点故障的风险,保证了整个网络的稳定性。
  2. 速度快:机场的节点通常采用高速服务器和优化的网络架构,网络速度较快,能够满足用户的高速上网需求。
  3. 安全性高:机场通常会采用严格的安全措施,如流量加密、防火墙等,保护用户数据的安全性。
  4. 稳定性高:机场通常采用专业的运维团队进行管理和维护,保证了服务的稳定性和可靠性。
  5. 服务质量高:机场通常会提供完善的客户服务,及时解决用户的问题和反馈,提升用户的满意度。

The so-called "airport" refers to the "line provider". They are responsible for completing the technical operations and management mentioned in section 1.4, while users pay for the right to use the service. Therefore, its advantages include at least:

  1. Simple User Operation: Scan code operation, one-click rule addition, etc.
  2. Multiple Line Options: Can unlock network services in different countries and regions, such as iplc dedicated line services, game acceleration services, etc.
  3. Multiple Access Nodes: Therefore, it has a stronger ability to resist node blocking, if one is blocked, just switch to another one.
  • Risks of "Airport"

"The other side of the coin of 'convenience' is 'risk'. Based on the technical characteristics and market conditions of the 'airport', its risks include at least:"

  1. "Airport" can fully obtain user information: All the traces left by users online will inevitably and very likely be stored on their servers for a long time. These records cannot be restricted by any legally binding user privacy agreement. ("Snooping and recording your every move")
  2. "Airport" lacks market management: There are inevitably malicious merchants who target fraud. ("Actively run away")
  3. "Airport" faces regulatory pressure: While large airports are relatively secure, they cannot avoid attracting attention. In 2020, several large airports experienced shutdowns and runaways, seriously disrupting users' normal usage. ("Passively run away")
  4. "Airport" technical level is difficult to determine: The quality of the line varies greatly, and the phenomenon of falsely advertising quality services is common. ("Slow speed, frequent disconnections, unable to connect")

1.6 So should you build your own website?

Now that you have seen the advantages and risks of the airport, please think carefully and make your own decision on what to use. After all, the best plan is the one that suits you best.

It's Your Choice!

  1. If you decide to use the airport, you can close this article now.

  2. If you decide to build it yourself, please continue reading the following chapters!

In short, the goal of this article is to serve as a starting point for users with zero experience, providing thorough explanations and demonstrations for each step, even if it may seem overly detailed or repetitive. The aim is to assist beginners in completing the entire process of deploying a VPS server from the first command input to successfully accessing the internet via the client, and gradually introducing them to basic Linux operations, laying a foundation for further self-learning.

1.7 Some digressions

  1. There is a wealth of information outside of the wall, so please learn to think rationally and independently. Don't take sides easily and don't believe in sensational information.

  2. We sincerely hope that with a smoother internet, everyone can access fresher knowledge, richer entertainment, experience a better world, and make more like-minded friends, but do not become a scapegoat for anyone with ulterior motives.

  3. Your internet identity is still your identity, and achieving absolute anonymity is extremely difficult. Therefore, please be sure to comply with the relevant laws and regulations in your personal location and the location of your IP address. Self-protection is always the most basic bottom line.

1.8 Your Progress

⬛⬜⬜⬜⬜⬜⬜⬜ 12.5%

- + diff --git a/en/document/level-0/ch02-preparation.html b/en/document/level-0/ch02-preparation.html index b90040a23c..a8dfaab212 100644 --- a/en/document/level-0/ch02-preparation.html +++ b/en/document/level-0/ch02-preparation.html @@ -24,11 +24,11 @@ [Chapter 2] Preparation of Raw Materials | Project X - - + +

[Chapter 2] Preparation of Raw Materials

This chapter is rather special because it involves monetary transactions. This article takes a neutral stance on the project and does not make specific recommendations. What I can do is to tell you what you need to prepare.

2.1 Acquiring a VPS

You need to obtain a healthy VPS with an unblocked IP, and perform the following basic preparations in the management console:

  1. Install Debian 10 64-bit system in the backend of VPS.
  2. Write down the IP address of VPS in a notebook (this article will use "100.200.300.400" as an example, which is an intentionally incorrect and illegal IP address. Please replace it with your real IP address).
  3. Write down the SSH remote login port of VPS in a notebook.
  4. Write down the username and password for SSH remote login in a notebook.

Buying a VPS is a relatively complex matter. It is recommended to first learn the relevant knowledge and choose one that suits your own economic ability and line requirements. In addition, you can choose to take advantage of some benefits offered by international giants (such as permanent free or limited-time free packages offered by Oracle and Google). In any case, you must act within your means.

Explanation

Regarding the choice of Debian 10 as the operating system, let me elaborate a bit: No matter what you have heard online, no matter which guru has told you that XXX version of Linux is better or XXX version of Linux is more powerful, these sectarian disputes have nothing to do with you right now! Using Debian 10 is enough to optimize your VPS server for security, stability, and performance (such as using cloud-optimized kernel, timely support of BBR, etc.). After you become familiar with Linux, you can try other Linux distributions.

2.2 Obtaining a Desired Domain Name

You need to obtain a domain name and add an A record in the DNS settings, pointing to the IP address of your VPS.

  1. Please choose a reliable international domain name service provider. Choose some common domain name suffixes, and make sure not to use the .cn suffix.
  2. In the DNS settings, add an A record pointing to the IP address of your VPS (the name of the A record can be anything, and in this article, it will be represented by "a-name"). The complete domain name will be represented by "subdomain.yourdomain.com" or "a-name.yourdomain.com". The effect is as shown in the picture below:

Add A Record

Tip

This is not a real usable website. Please replace it with your real website URL.

2.3 Software you need to install on your local computer

  1. SSH remote login tool
  1. Remote file copying tool
  1. Reliable text editor

2.4 Your Progress

If you have all the raw materials ready as mentioned above, you have already obtained the key to unlocking the door to a new world. So, what are you waiting for? Let's quickly move on to the next chapter and step through this door!

⬛⬛⬜⬜⬜⬜⬜⬜ 25%

- + diff --git a/en/document/level-0/ch03-ssh.html b/en/document/level-0/ch03-ssh.html index 327d0cda00..69ab324b5a 100644 --- a/en/document/level-0/ch03-ssh.html +++ b/en/document/level-0/ch03-ssh.html @@ -24,13 +24,13 @@ [Chapter 3] Remote Login | Project X - - + +

[Chapter 3] Remote Login

3.1 Remote Login to VPS (PuTTY)

First of all, considering that the user base of Windows is the largest among the zero-based population, this article uses Windows as an example for demonstration.

Secondly, although PowerShell and WSL after Windows 10 can also achieve a good SSH operation experience, not all versions of Windows have the latest components. Therefore, this article uses the classic PuTTY as an example to provide a detailed explanation of SSH remote login operation. (If you use other tools, the operations after the SSH login are the same.)

Follow me step by step and let's start the operation.

  1. Go to the official websiteopen in new tag of PuTTY and download the version that suits your operating system (this article uses the 64-bit version as an example).

Download PuTTY

  1. After installation and running, you will see the main interface of PuTTY. Now please take out your notebook from the previous chapter where you wrote down the IP address (VPS IP) and port (VPS PORT) of your VPS in the corresponding positions of the following figure. In order to save time and avoid repeatedly entering these details in the future, we can save the session (Saved Sessions), and simply load it in the future with one click.

PuTTY Settings

  1. I suggest setting keepalive to 60 seconds in the Connection to prevent SSH from automatically disconnecting after a period of inactivity. Be sure to save the settings again.

Prevent frequent disconnection

Attention

Any update to the PuTTY configuration needs to be manually saved to the session again. Otherwise, it will be lost after closing.

  1. Click on Open to enter the SSH connection window, then enter the username and password corresponding to the following figure to establish a connection with your VPS remote host. (This article assumes that the default username is root. Also, when entering a password in the Linux system, there will be no prompt like ******, which can avoid password length leakage. It's not that your keyboard is broken!)

SSH Remote Login

3.2 Successfully Logging in SSH! Introduction to Command Line Interface!

  1. If you have filled in your information correctly, you will see a similar interface as the picture below, indicating that you have successfully logged in:

Logging in to VPS for the first time

This interface is equivalent to the "desktop" of a remote server, but it does not have familiar icons and a mouse, nor does it have colorful graphics. Instead, all you see is simple text. This is the "Command Line Interface" - shortened as CLI.

All the following operations require you to act like a hacker in a movie and complete them in this command-line interface. Maybe you will feel unfamiliar, but please believe me, using the command-line interface is neither scary nor mysterious. In the end, it just turns your familiar mouse operations into textual commands, you say it, it does it.

  1. Now, you can observe and familiarize yourself with the command line environment a little bit. This interface has actually provided you with some useful information, such as the system kernel version (e.g. 4.19.37-5 in the picture), last login time and IP address. Of course, depending on the VPS, the interface you see may be slightly different.

  2. Please pay attention to the line at the bottom of the command line, to the left of the flashing cursor, there is a string of characters. The one shown in the figure is root@vps-server:~#. How to understand this string? It's very simple:

  • The current user is root
  • The server where root is located is vps-server
  • The current directory where root is located is ~
  • After # is the place where you can input commands.

The first two are pretty straightforward, no need to explain further. The third one is about the folder system in Linux. You don't need to go too deep into it for now. Just know that "~" represents the home directory of the current user. As for the fourth one, the prompt symbol "#", you don't need to worry about it either. Just know that in future articles, there will be some commands that you need to input, and they will be preceded by "#" or "$" to indicate where you should input the command. (So when you copy the command, just copy the content after the prompt symbol and don't copy the prompt symbol itself.)

3.3 Updating software on Linux for the first time!

  1. Just like your phone, whether it's Android or iPhone, in order to keep your apps up-to-date (to get security patches and new features), you will occasionally receive update notifications from the app store, telling you how many apps need to be updated. Linux systems also have a similar update mechanism that works logically. So as long as you know how to update phone apps, you can learn how to update Linux software!

  2. In Linux, each application is called a "package". The program that manages the applications is naturally called a "package manager". You can use it to install, update, and uninstall various software, and even update the Linux system itself. Package managers in Linux are very powerful, but we won't go into details here. For now, you only need to know that the package manager for the Debian system is called apt. Next, we will first use apt to do a comprehensive update of the software to familiarize you with its basic operations.

  3. Tiny White Linux Basic Commands:

NumberCommand NameCommand Description
cmd-01apt updateQuery software updates
cmd-02apt upgradePerform software updates
  1. Now, please enter the first command to get update information.
apt update
 

This is a command used in a Linux terminal to update the package list from the repositories configured on the system.

  1. Then enter the second command, and when asked if you want to continue installing (Y/n), type y and press enter to confirm and start the installation.
apt upgrade
 

This is a command in the shell terminal to upgrade the installed packages on a Debian or Ubuntu Linux system.

  1. The complete demonstration of the process is as follows:

Demonstration of the software update process for the first time

3.4 Your Progress

Congratulations on taking another solid step! Now, you can log in to your remote server via SSH! After logging in, besides upgrading the software, what else should you do? Please enter the next chapter to find out!

⬛⬛⬛⬜⬜⬜⬜⬜ 37.5%

- + diff --git a/en/document/level-0/ch04-security.html b/en/document/level-0/ch04-security.html index 1f769b65ca..f2167b4c38 100644 --- a/en/document/level-0/ch04-security.html +++ b/en/document/level-0/ch04-security.html @@ -24,8 +24,8 @@ [Chapter 4] Security and Protection | Project X - - + +

[Chapter 4] Security and Protection

4.1 Why Do We Need Security Protection?

Security protection for Linux servers is a complex and huge subject. Countless websites, apps, services, and even offline infrastructure are built on the foundation of Linux, which involves huge economic benefits and commercial value. This also means that there is a huge motivation for black and gray industries to launch attacks. However, these services are so important that major security vulnerabilities are not allowed. Therefore, countless operation and maintenance professionals are working hard on the battlefield of security attacks and defense, which enables us to enjoy a basic stable modern digital life.

Now, you have a VPS and will open its data access channel to achieve the goal of traffic forwarding, which means you are now on the front line of the security battle and face all risks. However, at the same time, newcomers tend to have a polarized view of security issues due to lack of knowledge and information: either they feel it is as light as a feather and has nothing to do with them, or they feel it is as heavy as Mount Tai and feel anxious all day long.

  • For the former, my suggestion is: safety is of utmost importance. Try to gather more information on safety issues to avoid regretting after experiencing losses.

  • For the latter, my suggestion is: don't worry too much, our servers still don't have too much value and generally won't attract high-level attacks. The basic threats we need to face are mostly malicious scans and login attempts from some automated scripts. Just follow this article to do some basic protection.

4.2 What are the specific risks

Just like the configuration we did in the "Remote Login" section, anyone who knows the four elements of [IP address] + [port] + [username] + [password] can log in to your VPS server. So obviously, the security of these four elements is the bottom line that we need to protect. Let's analyze them one by one:

  1. [IP Address]: Malicious scripts randomly attempt to scan IP ranges, which can be regarded as public information and cannot be hidden.

  2. [Port]: If you are using the default port, then [Port = 22].

  3. [Username]: If using the default user, then [Username = root]

  4. [Password]: There is no default value for the password. It must be randomly generated by the VPS backend or set by you. In other words, if all the settings of your server are default, then three of the four elements are already known. Therefore, the security of your entire server relies on a small password. In this case, there are several situations:

  • If you use a VPS management background to generate passwords randomly, it usually contains random uppercase and lowercase letters, symbols, and is relatively secure.

  • If you changed your password to something super weak like 123456 just for the sake of easy memorization, hacking into your VPS server would be a piece of cake.

  • If you change your password to a more complex one that you have used elsewhere just for the sake of easy memory, it is not really safe. You should understand that hackers have cheats in their hands, such as password tables, which contain tens of thousands, hundreds of thousands, millions, or even more real leaked passwords.

  1. But you should understand that no hacker really sits in front of a computer and tries your password repeatedly. All attack attempts are carried out automatically by malicious scripts, which work tirelessly for 24 hours. Perhaps while you are sleeping soundly every night, your server is enduring round after round of attacks.

Once the password is successfully cracked, it means that all four of your elements have been mastered by the attacker. The malicious script will quickly log in to the server, obtain the highest root control of the server, install and deploy its malicious services, and then use your server to do all kinds of bad things 24 hours a day (such as mining, spreading viruses, sending spam emails, fraudulent emails, acting as a BT relay, and even dark web public nodes, and so on). If the malicious script is relatively restrained, it can actually achieve considerable concealment. Generally, newcomers will not observe and pay attention to indicators such as login records, process changes, CPU usage changes, and traffic changes of the VPS, so it is difficult for you to discover that you have been hacked. Until your VPS service provider blocks your account or you receive a lawyer's letter.

  1. Don't forget that when you obtain a VPS, you probably need to use your real payment information, and when you log in to various websites and social platforms, your IP address will also be recorded, which has a direct or indirect relationship with your identity. Therefore, once these bad things happen, they will inevitably be associated with you.

4.3 What security measures do we need to take

Based on the above analysis, what we need to do is to strengthen the three elements of [port], [username], and [password] to reduce the risk of being hacked.

  1. [Port]: Modify the SSH remote login port to a [non-22 port] (4.4).
  2. [Username]: Create a [non-root] new user and disable root user SSH remote login (4.5, 4.6).
  3. [Password]: Enable RSA key verification for SSH login and disable password verification login (4.7).

Remember to follow the order and don't lock yourself out.

4.4 Change the SSH Remote Login Port to a Non-22 Port

Now, let's solve the problem of "port = 22". (Note: some VPS service providers have non-22 ports set as default, so you can ignore this step if that's the case. Of course, you can also follow this article to change it to another port.)

  1. Basic commands of Little White Linux:
IDCommand NameDescription
cmd-03nanoText editor
cmd-04systemctl restartRestart a service
  1. Basic Configuration Files of Little White Linux
NumberConfiguration File LocationFile Description
conf-01/etc/ssh/sshd_configSSH Remote Login Program Settings
  1. The first thing we need to do, of course, is to [open the SSH remote login program settings with the text editor nano]. In Windows, you will [find the file and double-click] it. What should you do in Linux? Take a close look at the command instructions above, isn't it simple? Yes, it is:
nano /etc/ssh/sshd_config
@@ -39,6 +39,6 @@
 

This is a command in shell script to change the permissions of the authorized_keys file to 600 for the current user's SSH directory (~/.ssh/).

  1. Modify SSH configuration. We have used this many times, but now that we have changed from the almighty root to the ordinary user vpsadmin, we do not have the permission to edit SSH configuration directly. At this time, we need to use the sudo command:
sudo nano /etc/ssh/sshd_config
 

(This is a command in the shell/terminal to open the sshd_config file located in the /etc/ssh/ directory with the sudo privilege using the nano text editor.)

  1. Find (ctrl+w) PasswordAuthentication and change it to no.

  2. Find (ctrl+w) PubkeyAuthentication, change it to yes, then save (ctrl+o) and exit (ctrl+x).

  3. Restart the SSH service. (Note: Don't forget to use sudo to gain permission.)

sudo systemctl restart ssh
 

This is a command in the shell terminal to restart the SSH service with root privileges using the systemctl command.

  1. The complete process is as follows:

Enable SSH key verification and disable password verification

  1. The public key has been set up on the VPS end. Now we need to specify the private key location for PuTTY to use when logging in. (Reminder: Don't forget to save the session.)

Specify private key location in PuTTY

  1. Now, the [Key-based login] has been successfully enabled, [Password authentication] has been successfully disabled, and the default login username and private key have been saved for PuTTY. In the future, when using PuTTY to log in, simply load the VPS-SERVER configuration, click Open, and you can log in with just one click.

If you have set a password for your private key, you need to enter this password to use the key when logging in, as shown in the following figure:

Enter Private Key Password

  1. Don't forget to set the corresponding key for WinSCP, otherwise you won't be able to log in when you want to transfer files later.

WinSCP Specify Private Key Location

Warning

Any software that requires SSH login needs key verification. As there are too many software, it is impossible to show them one by one. Please set it up according to your needs.

4.8 Your Progress

Up to this point, your VPS has completed the basic security measures of [port], [username], and [password]. Although it is not completely impregnable, most malicious scripts should no longer be able to harm you.

Now that we finally have a secure system foundation, in the next chapter, we can start step by step to install and configure the infrastructure that Xray needs! (What infrastructure? A web page, a certificate)

⬛⬛⬛⬛⬜⬜⬜⬜ 50%

- + diff --git a/en/document/level-0/ch05-webpage.html b/en/document/level-0/ch05-webpage.html index 3bb7a9a43d..c366209b85 100644 --- a/en/document/level-0/ch05-webpage.html +++ b/en/document/level-0/ch05-webpage.html @@ -24,8 +24,8 @@ Chapter 5: Website Building | Project X - - + +

Chapter 5: Website Building

5.1 Why should you create a website?

Some newcomers may be confused: why do I need to build a website for securing an open digital environment? I don't know how to code! Isn't it very complicated?

First, let's answer the first question. The reasons for building a website are:

  1. Apply for a legitimate TLS certificate (very important)
  2. Provide reasonable fallback to prevent active probing attacks and improve security
  3. Set up a camouflage site (such as a blog, private cloud storage, multimedia site, game site, etc.) with a reasonable frontend when directly accessed, making traffic usage look more legitimate.

Now let's answer the second question:

  1. As a demonstration, this article uses only the simplest "single-file HTML page + Nginx" setup to achieve the above objectives, so it is very easy.
  2. This website can not only be used for camouflage but also for real development and growth. The complexity depends entirely on you.
  3. For the goals of "camouflage" and "website operation", uniqueness and personalization are needed. Students who need this can search and learn by themselves. This content has completely deviated from scientific online access, so this article will not go into depth.

5.2 Log in to VPS, install and run Nginx

  1. Here we use commands that have been explained in detail before, so they won't be repeated. If you don't understand, please refer to the previous chapters.

    sudo apt update && sudo apt install nginx
    @@ -75,6 +75,6 @@
             }
     

    Be extra careful!

    As mentioned in Step 3 of section 5.3, make sure to change /home/vpsadmin/www/webpage to your actual file path.

  2. Make nginx reload the configuration to take effect.

    sudo systemctl reload nginx
     
  3. The complete setup process is as follows:

    Web page settings demonstration

  4. Now, if you visit http://subdomain.your_domain.com, you should see this page, indicating success:

    http web page success

5.4 Common error explanations

First of all, if you follow the instructions in the article step by step and are careful enough, you will definitely not encounter any errors. So, I don't intend to change how this article is written.

Then why do some students still get stuck at this step, and the web page just won't open? There are basically two words: carelessness. Because there are only two possible issues with the configuration here, and there are only two reasons for them.

I. Two types of issues:

  • In nginx.conf, the /home/vpsadmin/www/webpage does not match the actual file path; nginx cannot find the file
  • The path is correct, but nginx doesn't have permission to access it

II. Two reasons:

  • Use a non-root user but still directly copy the commands in the text without modification. (This is basically like copying the name of another student when copying answers)
  • Insist on using a root user

If you encounter any errors, please carefully review the explanations in Steps 3 and 5-2 of Section 5.3.

Warning

In the early stages of this article, a lot of space has been devoted to explaining the importance of using a non-root user for security, and the entire article is written based on this premise. So, issues caused by using a root user are not within the scope of this article.

But I believe that students who persist in using the root user should have their own opinions, strong hands-on ability, or have a certain foundation in Linux. I have already explained the crux of the problem, and I believe you can solve it on your own.

5.5 Your Progress

So far, Xray's first infrastructure [webpage] has been established. Let's now move on to the second infrastructure [certificate]!

⬛⬛⬛⬛⬛⬜⬜⬜ 62.5%

- + diff --git a/en/document/level-0/ch06-certificates.html b/en/document/level-0/ch06-certificates.html index e5e4d1c281..ed41c38052 100644 --- a/en/document/level-0/ch06-certificates.html +++ b/en/document/level-0/ch06-certificates.html @@ -24,8 +24,8 @@ [Chapter 6] Certificate Management | Project X - - + +

[Chapter 6] Certificate Management

6.1 Applying for a TLS Certificate

Next, we need to apply for a real TLS certificate for our domain name, so that the website has the ability to encrypt with standard TLS and the ability to access via HTTPS. This is the most important tool for Xray and other current security proxy tools to ensure fully encrypted traffic.

Warning

Please do not use self-signed certificates lightly. It does not make the operation much simpler, but adds unnecessary risks (such as man-in-the-middle attacks).

Here, I will use a certificate management tool called acme.shopen in new tag, which is simple, lightweight, efficient, and capable of automatically updating certificates.

In addition, I believe that you have gradually become familiar with the basic operations of Linux. Therefore, from this chapter on, commands that have appeared multiple times will no longer have screenshots and will only be briefly described. If you really can't remember how to use them, just review the previous chapters.

6.2 Install acme.sh

  1. Basic Linux commands for beginners:

    NumberCommandDescription
    cmd-12wgetRetrieve (or download) a webpage file
    cmd-13acme.shCommands related to acme.sh certificate management
  2. Run the installation script.

wget -O - https://get.acme.sh | sh
@@ -139,6 +139,6 @@
 [Mon 14 Feb 2022 03:00:25 PM CST] Installing key to: /etc/xray/cert/cert.key
 [Mon 14 Feb 2022 03:00:25 PM CST] Installing full chain to: /etc/xray/cert/fullchain.crt
 

(Note: This is a shell command for installing a SSL certificate using acme.sh. The command is specifying the domain, file paths for the certificate, private key, and full chain, as well as indicating that an ECC certificate should be used.)

6.6 Your Progress

At this point, the two basic infrastructures required by Xray are finally in place! Xray, which has been eagerly awaited, is about to be revealed, and we are finally about to enter the most exciting chapter!

⬛⬛⬛⬛⬛⬛⬜⬜ 75%

- + diff --git a/en/document/level-0/ch07-xray-server.html b/en/document/level-0/ch07-xray-server.html index 6ea78c562b..a806f96163 100644 --- a/en/document/level-0/ch07-xray-server.html +++ b/en/document/level-0/ch07-xray-server.html @@ -24,8 +24,8 @@ 【第 7 章】Xray 服务器篇 | Project X - - + +

【第 7 章】Xray 服务器篇

7.1 博观而约取,厚积而薄发

本文撰写过程中,大佬开玩笑的吐槽到:你这教程,居然连载了 6 章都还没到 Xray,不知道的还以为你是“手把手教你建网站”教程呢。(我竟无法反驳.jpg!)

其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连nano都无法正确使用,也不会用WinSCP,远程手写编辑出来的config.json自然错误百出,连查错也变得举步维艰。

Warning

经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray 时会有一种【水到渠成】的轻快感觉。

后面要做的事情非常简单:

  1. 安装
  2. 配置(如安装 TLS 证书、config.json
  3. 运行
  4. 优化(如更新内核、开启bbr、网站http访问自动跳转https等)

7.2 安装 Xray

首先,Xray 的官方载体,就是 xray-coreopen in new tag 开源项目(基于 MPL 2.0 开源协议)生成的二进制程序。你把这个二进制放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。主要区别来源于【配置】。

安装时,直接使用官方安装脚本就很简单直接。它提供了多种安装选项,有兴趣的可以去官方的安装脚本仓库open in new tag中看看脚本的说明,本文使用的是【非 root 用户】安装模式

写本文时,安装脚本在使用非 root 账户时有一些小 bug,所以我决定正好把这几步分开操作,可以顺便说明一下 Linux 下的删除命令。

  1. 小小白白 Linux 基础命令:

    编号命令名称命令说明
    cmd-14rm删除命令
  2. 将安装脚本下载至本地:

    wget https://github.com/XTLS/Xray-install/raw/main/install-release.sh
    @@ -188,6 +188,6 @@
     
    1. 修改 Xray 的回落设置,将回落从 80 端口改为 8080 端口。(找到 "dest": 80, 并改成 "dest": 8080
    sudo nano /usr/local/etc/xray/config.json
     
    1. 重启 Xray 服务,即完成了设置
    sudo systemctl restart xray
     
    1. 完整流程演示如下:

    http自动跳转https

    1. 当你输入 http://a-name.yourdomain.com的时候,它应该已经会自动跳转 https 了

    http自动跳转https生效

    7.9 服务器优化之三:更丰富的回落

    如果你需要更丰富的回落功能,可以参考 《回落 (fallbacks) 功能简析》

    7.10 你的进度

    恭喜!!到这一步,你已经拥有了可以正常科学上网的服务器、同时也有了可以防止主动探测攻击的伪装网站。接下来,只要给你的客户端装上合适的软件,就可以享受顺畅的网络了!

    ⬛⬛⬛⬛⬛⬛⬛⬜ 87.5%

    7.11 重要勘误

    1. 初版中Xray配置文件config.json文件夹位置错误。若你已经根据之前的位置进行了操作,Xray会无法正确启动。故勘误说明于此,请自查,造成不便十分抱歉!
    • 正确位置:/usr/local/etc/xray/config.json
    • 错误位置:/usr/local/etc/config.json

    受影响章节:

    • 7.4 配置Xray - 3. 使用nano创建Xray的配置文件
    • 7.8 服务器优化之二 - 6. 修改Xray的回落设置
    1. 初版中修改Nginx配置文件nginx.conf时内容错误(网页文件夹位置错误),若你已经根据之前的位置进行了操作,Nginx会无法找到正确的网站。请自查,造成不便十分抱歉!
    • 正确文件夹位置:root /home/vpsadmin/www/webpage;
    • 错误文件夹位置:root /var/www/website/html

    受影响章节:

    • 7.8 服务器优化之二 - 4. 在与 80 端口同级的位置增加一个本地端口监听来提供网页展示
- + diff --git a/en/document/level-0/ch08-xray-clients.html b/en/document/level-0/ch08-xray-clients.html index 7f945f1c3c..8d3dd26172 100644 --- a/en/document/level-0/ch08-xray-clients.html +++ b/en/document/level-0/ch08-xray-clients.html @@ -24,8 +24,8 @@ 【第 8 章】Xray 客户端篇 | Project X - - + +

【第 8 章】Xray 客户端篇

8.1 Xray 的工作原理简述

要正确的配置和使用Xray,就需要正确的理解其工作原理,对于新人,可以先看看下面简化的示意图(省略了许多复杂的设置):

Xray数据流向

这其中的关键点是:

  1. APP 要主动或借助转发工具,将数据【流入(inbounds)】Xray 客户端

  2. 流量进入客户端后,会被【客户端路由(routing)】按规则处理后,向不同方向【流出(outbounds)Xray 客户端。比如:

    1. 国内流量直连(direct
    2. 国外流量转发 VPS(proxy
    3. 广告流量屏蔽(block
  3. 向 VPS 转发的国外流量,会跨过防火墙,【流入(inbounds)】 Xray 服务器端

  4. 流量进入服务器端后,与客户端一样,会被【服务器端路由(routing)】按规则处理后,向不同方向【流出(outbounds)】:

    1. 因为已经在防火墙之外,所以流量默认直连,你就可以访问到不存在网站们了(direct
    2. 如果需要在不同的 VPS 之间做链式转发,就可以继续配置转发规则(proxy
    3. 你可以在服务器端继续禁用各种你想禁用的流量,如广告、BT 下载等(block

注意

请务必记得,Xray 的路由配置非常灵活,上面的说明只是无限可能性中的一种。

借助 geosite.datgeoip.dat 这两个文件,可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 GFWList 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)

现在,《路由 (routing) 功能简析》 已经上线,我建议对路由功能有兴趣的同学,先继续跟着本文完成客户端的基础配置,之后再去这里详细学习。

8.2 客户端与服务器端正确连接

现在你已经理解了 Xray 的工作原理,那么接下来的配置,其实就是【告诉你的客户端如何连接 VPS 服务器】。这和你已经很熟悉的、告诉PuTTY如何远程连接服务器是一样的。只不过 Xray 连接时的要素不止是【IP 地址】+【端口】+【用户名】+【密码】这四要素了。

实际上,Xray的连接要素是由不同的协议决定的。本文在第 7 章的配置文件 config.json 里,我们使用 Xray 下独特而强大的 VLESS 协议 + XTLS 流控。所以看看那个配置文件的内容就能知道,这个协议组合的连接要素有:

  • 服务器【地址】: a-name.yourdomain.com
  • 服务器【端口】: 443
  • 连接的【协议】: vless
  • 连接的【流控】: xtls-rprx-vision (vision 模式适合全平台)
  • 连接的【验证】: uuiduuid-uuid-uuid-uuiduuiduuid
  • 连接的【安全】: "allowInsecure": false

鉴于新人一般都会使用手机 APP 或者电脑的 GUI 客户端,我就把常用的客户端罗列在下面。每个客户端都有自己独特的配置界面,逐一截图展示并不现实,所以请你务必仔细阅读这些客户端的说明、然后把上述要素填入合适的地方即可。

注意

许多工具其实是同时支持 xray-corev2fly-core 的,但默认内置的不一定是哪个,所以别忘记检查一下是否是你想要的那个在工作哦!

到这一步,你的全套配置就已经可以正常使用啦!

8.3 附加题 1:在 PC 端手工配置 xray-core

虽然到上面一步已经可以结束了,但是如果你是个好奇心强、记忆力好的的同学,一定会想起来我在上一章说过,你把xray-core 的二进制文件“放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。” 那究竟要怎样直接使用 xray-core 做客户端呢?

为了回答这个问题,我加入了附加题章节,有一点点超纲,有一点点麻烦,但费这个笔墨是因为这个方式有它的优势:

  • 第一时间获得最新版而无需等待 APP 升级适配

  • 灵活自由的路由配置能力(当然 GUI 客户端中 Qv2ray 的高级路由编辑器非常强大,也可以完整实现 xray-core 的路由配置功能)

  • 节约系统资源 (GUI 界面一定会有资源消耗,消耗的多少则取决于客户端的实现)

它的劣势应该就是【需要手写配置文件】有点麻烦了。但其实,你想想,服务器上你已经成功的写过一次了,现在又有什么区别呢?接下来,还是老样子,我们分解一下步骤:

  1. 首先请从 Xray 官方的 GitHub 仓库 Release 页面open in new tag 获取对应平台的版本,并解压缩到合适的文件夹

  2. 在合适的文件夹建立空白配置文件:config.json (自己常用平台下新建文件大家肯定都会,这就真不用啰嗦了)

  3. 至于什么是“合适的文件夹”?这就取决于具体的平台了~

  4. 填写客户端配置

    • 我就以 8.1 原理说明里展示的基本三类分流(国内流量直连、国际流量转发 VPS、广告流量屏蔽),结合 8.2 的连接要素,写成一个配置文件
    • 请将 uuid 替换成与你服务器一致的 uuid
    • 请将 address 替换成你的真实域名
    • 请将 serverName 替换成你的真实域名
    • 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
    // REFERENCE:
    @@ -181,6 +181,6 @@
     

8.4 附加题 2:在 PC 端手工运行 xray-core

写好了配置文件该,要怎么让 xray-core 运行起来呢?双击好像并没有反应啊?

首先,你要找到电脑上的【命令行界面】。

  1. Linux 桌面、macOS 系统的同学肯定已经比较熟悉了,搜索 Console 或者 Terminal 就可以
  2. Windows 就可以搜索使用 Cmd 或者 Powershell 等程序(WSL 的同学你坐下,你的 Console 当然也可以)

其次,我们要做的事情是【让 xray 找到并读取配置文件 config.json,然后运行】,所以:

  1. 在 Windows 下,假设你的 Xray 程序位置是 C:\Xray-windows-64\xray.exe,配置文件位置是C:\Xray-windows-64\config.json,那么正确的启动命令就是:

    C:\Xray-windows-64\xray.exe -c C:\Xray-windows-64\config.json
     

    说明

    这里的 -c 就是指定配置文件路径的参数,告诉 xray 去后面的位置找配置文件

  2. 相似的,在 Linux 和 macOS 下,假设你的 Xray 程序位置是 /usr/local/bin/xray,配置文件位置是/usr/local/etc/xray/config.json,那么正确的启动命令就是

    /usr/local/bin/xray -c /usr/local/etc/xray/config.json
     

    说明

    每个系统都有系统路径变量,所以写 Xray 程序时不一定要写绝对路径。但是写了肯定没错,所以我就如此演示了。

8.5 附加题 3:在 PC 端开机自动运行 xray-core

如果你真的尝试了手动运行 xray-core,你一定会发现这个方式还有点小问题:

  1. 每次运行 Xray 都要出现一个黑乎乎的窗口,很丑
  2. 不能开机自动运行,每次都要手工输入,十分不方便

我可以肯定的告诉你:完全可以解决。但是具体的解决方式,就当作课外作业留给大家吧!(友情提示,文档站的问答区有线索哦)

8.6 圆满完成!

我相信,有耐心看到这里的同学,都是兼具好奇心和行动力的学习派!我现在要郑重的恭喜你,因为到了这里,你已经完完整整的【从第一条命令开始,完成了 VPS 服务器部署,并成功的在客户端配置使用 Xray】了!这毫无疑问是一个巨大的胜利!

我相信,你现在一定对Linux不再恐惧,对Xray不再陌生了吧!

至此,小小白白话文圆满结束!

⬛⬛⬛⬛⬛⬛⬛⬛ 100%

8.7 TO INFINITY AND BEYOND!

但现在你看到的,远远不是 Xray 的全貌。

Xray是一个强大而丰富的网络工具集合,平台化的提供了众多模块,可以像瑞士军刀一样,通过灵活的配置组合解决各种不同的问题。而本文,仅仅蜻蜓点水的用了最简单最直观的配置来做基础演示

如果你觉得现在已经完全够用了,那就好好的享受它给你带来的信息自由。但如果你的好奇心依然不能停歇,那就去继续挖掘它无限的可能性吧!

需要更多信息,可以到这里寻找:

  1. xtls.github.ioopen in new tag - 官方文档站
  2. 官方 Telegram 群组open in new tag - 活跃而友善的官方讨论社区

TO INFINITY AND BEYOND!

不算后记的后记

希望我陪你走过的这一段小小的旅程,可以成为你网络生活中的一份小小助力。

这篇文章里的工具和信息难免会一点点的陈旧过时,但你一定会逐渐成长为大佬。未来的某个时间,若你能偶尔想起这篇教程、想起我写下本文的初衷,那我衷心希望你能够薪火相传、把最新的知识分享给后来人,让这一份小小的助力在社区里坚定的传递下去。

这是个大雪封山乌云密布的世界,人们孤独的走在各自的路上试图寻找阳光,如果大家偶尔交汇时不能守望相助互相鼓励,那最终剩下的,恐怕只有【千山鸟飞绝 万径人踪灭】的凄凉了吧。

- + diff --git a/en/document/level-0/ch09-appendix.html b/en/document/level-0/ch09-appendix.html index ac513b70eb..aebbf206fc 100644 --- a/en/document/level-0/ch09-appendix.html +++ b/en/document/level-0/ch09-appendix.html @@ -24,11 +24,11 @@ 【第 9 章】附录 | Project X - - + +

【第 9 章】附录

1. 小小白白 Linux 基础命令索引

编号命令名称命令说明出现篇章
cmd-01apt update查询软件更新《远程登录篇》
cmd-02apt upgrade执行软件更新《远程登录篇》
cmd-03nano文本编辑器《安全防护篇》
cmd-04systemctl restart重启某个服务《安全防护篇》
cmd-05adduser给系统新增用户《安全防护篇》
cmd-06apt install安装某个软件《安全防护篇》
cmd-07visudo修改 sudo 权限设置专用编辑器《安全防护篇》
cmd-08sudoroot权限运行某个命令《安全防护篇》
cmd-09chmod修改目标文件/文件夹的权限《安全防护篇》
cmd-10mkdir新建文件夹《网站建设篇》
cmd-11systemctl reload重新加载某个服务《网站建设篇》
cmd-12wget访问(或下载)某个网页文件《证书管理篇》
cmd-13acme.shacme.sh 证书管理相关的命令《证书管理篇》
cmd-14rm删除命令《Xray 服务器篇》
cmd-15crontab -e编辑当前用户的定时任务《Xray 服务器篇》
cmd-16touch建立空白文件《Xray 服务器篇》
cmd-17systemctlsystemd基本服务管理命令《Xray 服务器篇》
cmd-18reboot重启 Linux 系统《Xray 服务器篇》

2. 小小白白 Linux 重要配置文件索引

编号配置文件位置文件说明出现篇章
conf-01/etc/ssh/sshd_configSSH 远程登录程序设置《远程登录篇》
conf-02/etc/nginx/nginx.confNginx 程序设置《网站建设篇》
conf-03/etc/apt/sources.listapt 软件源列表《Xray 服务器篇》
conf-04/etc/apt/sources.list.d/vpsadmin.list用户自定义软件源列表列表《Xray 服务器篇》
conf-05crontab -e当前用户的定时任务《Xray 服务器篇》
conf-06/etc/sysctl.conf手动设置 kernel 参数《Xray 服务器篇》
conf-07/etc/sysctl.d/vpsadmin.conf用户自定义 kernel 参数配置文件《Xray 服务器篇》

3. 小小白白 Xray 重要文件索引

编号配置文件位置文件说明出现篇章
xray-01/usr/local/etc/xray/config.jsonXray 程序设置《Xray 服务器篇》
xray-02/home/vpsadmin/xray_cert/xray.certTLS 证书《Xray 服务器篇》
xray-03/home/vpsadmin/xray_cert/xray.keyTLS 私钥《Xray 服务器篇》
xray-04/home/vpsadmin/xray_log/access.logXray 访问日志《Xray 服务器篇》
xray-05/home/vpsadmin/xray_log/error.logXray 错误日志《Xray 服务器篇》
- + diff --git a/en/document/level-0/index.html b/en/document/level-0/index.html index d8e1542ed1..53f218c069 100644 --- a/en/document/level-0/index.html +++ b/en/document/level-0/index.html @@ -24,11 +24,11 @@ Plain and Simple Language | Project X - - + +

Plain and Simple Language

This chapter is a basic lesson of [Starting from Scratch]. New students, please watch and learn carefully.

Tip

Made with ❤️ by @ricuhkaenopen in new tag

【Chapter 1】 Preface: Rambling - Airport or Self-built? That is the question.

Chapter 2: Preparation of Raw Materials - Tools must be sharpened before they can be used proficiently.

Chapter 3: Remote Login - A bridge connecting the north and south, turning a natural obstacle into a thoroughfare.

【Chapter 4】Security Protection - If you don't pay attention to security, you will shed tears for your loved ones.

[【Chapter 5】Website Construction] - Show Your Beauty (Link to webpage.md file)

Chapter 6: Certificate Management - Only those who obtain certificates are considered legitimate.

Chapter 7: Xray Server - Finally, waited for you.

Chapter 8: Xray Client - A New Beginning.

[Chapter 9] Appendix - All the exam points are here.

- + diff --git a/en/document/level-1/fallbacks-lv1.html b/en/document/level-1/fallbacks-lv1.html index 015575c724..8adfcdd956 100644 --- a/en/document/level-1/fallbacks-lv1.html +++ b/en/document/level-1/fallbacks-lv1.html @@ -24,8 +24,8 @@ 回落 (fallbacks) 功能简析 | Project X - - + +

回落 (fallbacks) 功能简析

在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。

1. 回顾《小小白白话文》中的回落

如果你用了《小小白白话文》中的Xray 配置,并完成了HTTP 自动跳转 HTTPS 优化,那么你已经有了基于 VLESS 协议的简易回落:

{
@@ -200,6 +200,6 @@
   }
 }
 
  • 至此,我们就能够完整的画出模板的回落路线了:

  • 6. 结语

    至此,Xray 的【回落】功能就介绍完了。希望本文能够对你理解 Xray 的强大有所帮助。

    7. 附加题

    我再无耻的留一个附加题:本文详解的 VLESS-TCP-XTLS-WHATEVERopen in new tag 模板?是否有可以优化的地方?

    提示:HTTP 自动跳转 HTTPS

    - + diff --git a/en/document/level-1/fallbacks-with-sni.html b/en/document/level-1/fallbacks-with-sni.html index 0a9497aeeb..68a9ac7152 100644 --- a/en/document/level-1/fallbacks-with-sni.html +++ b/en/document/level-1/fallbacks-with-sni.html @@ -24,8 +24,8 @@ SNI fallback | Project X - - + +

    Implementing camouflage and domain-based routing through SNI fallback function

    VLESS is a lightweight protocol that, like Trojan, does not perform complex encryption and obfuscation on traffic. Instead, it is encrypted through the TLS protocol and mixed in with other HTTPS traffic, making it difficult to detect. In order to better disguise itself and respond to active probing, the fallback function appeared with VLESS at the same time. This tutorial will demonstrate how to use the fallback function of VLESS inbound protocol in Xray, combined with Nginx or Caddy, to achieve domain name-based traffic routing while ensuring complete disguise.

    Application Scenarios

    Due to XTLS, Xray needs to listen on port 443, which means that if there is a website running on the server, it cannot run or needs to run on another port, which is obviously unreasonable. There are three solutions to this problem:

    • Xray monitors other commonly used ports (such as 22, 3389, 8443).

    This plan is the simplest, but not perfect enough.

    • Nginx or HAProxy listens on port 443, uses SNI for L4 load balancing, and achieves port multiplexing through reverse proxy.

    This plan is relatively complicated and requires some understanding of using Nginx or HAProxy. We will not explain it in too much detail here.

    • Xray listens on port 443, and uses Fallbacks feature to split website traffic based on SNI and fallbacks it to Nginx or Caddy.

    This plan has a moderate level of difficulty and is the scheme that this tutorial will demonstrate next.

    Introduction to SNI

    Server Name Indication (SNI) is an extension protocol of TLS. Friends who are familiar with reverse proxies know that the following configuration is required if you want to proxy traffic to the correct content through a domain name:

    proxy_set_header Host hostname;
    @@ -211,6 +211,6 @@
         redir https://{host}{uri} permanent
     }
     

    Reference

    1. Server Name Indication - Wikipedia, the free encyclopediaopen in new tag
    2. Home · acmesh-official/acme.sh Wikiopen in new tag
    3. HTTP/2 - Wikipedia, the free encyclopediaopen in new tag

    Quotation


    1. Proxy Protocol - HAProxy Technologiesopen in new tag ↩︎

    2. Introduction to Proxy Protocol and Nginx Configuration - Jianshuopen in new tag ↩︎

    3. v2fly-github-io/vless.md at master · rprx/v2fly-github-ioopen in new tag ↩︎

    - + diff --git a/en/document/level-1/index.html b/en/document/level-1/index.html index 8e7705a063..cae79cf064 100644 --- a/en/document/level-1/index.html +++ b/en/document/level-1/index.html @@ -24,11 +24,11 @@ Beginner's Tips | Project X - - + +
    - + diff --git a/en/document/level-1/routing-lv1-part1.html b/en/document/level-1/routing-lv1-part1.html index 1826a10e03..f0e5f55d7a 100644 --- a/en/document/level-1/routing-lv1-part1.html +++ b/en/document/level-1/routing-lv1-part1.html @@ -24,8 +24,8 @@ 路由 (routing) 功能简析(上) | Project X - - + +

    路由 (routing) 功能简析(上)

    如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。

    1. 初识【路由】三兄弟

    要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. 入站;2. 路由;3. 出站

    路由三兄弟

    三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。

    所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。

    因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。

    啰嗦君

    路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。

    2. 基本功: “兄弟一条心”

    下图的示例,就是在客户端的 Xray 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。

    下面我们来逐个分析:

    2.1 入站

    Tip

    入站: 就是流量如何流入 Xray

    下面的入站配置示例,用大白话说就是:数据按照 socks 协议,通过 10808 端口,从本机 127.0.0.1 流入Xray。同时,Xray 将这个入站用 [tag] 命名为 inbound-10808

    {
    @@ -141,6 +141,6 @@
       ]
     }
     

    此时,路由规则其实变成了:

    这就是路由功能的灵活之处了,你可以自由的改变它的顺序来实现不同的设计。

    至此,我们已经解释完了 【如何利用 geosite.dat 文件,通过路由规则,根据【域名】来分流网络流量】。

    5. 攻城略池 - 多种路由匹配条件

    请确保你已经读懂了上面的内容,因为这样,你就已经理解了【路由】功能的工作逻辑。有了这个基础,我们就可以继续分析【路由】功能更多更详细的配置方式和匹配条件了。

    等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 《路由 (routing) 功能简析(下)》 吧!

    - + diff --git a/en/document/level-1/routing-lv1-part2.html b/en/document/level-1/routing-lv1-part2.html index dc58d4f619..7841192cab 100644 --- a/en/document/level-1/routing-lv1-part2.html +++ b/en/document/level-1/routing-lv1-part2.html @@ -24,8 +24,8 @@ 路由 (routing) 功能简析(下) | Project X - - + +

    路由 (routing) 功能简析(下)

    欢迎继续学习 Xray 的【路由】功能!

    《路由 (routing) 功能简析(上)》 中,我们已经对【路由】功能的工作逻辑有了清晰的理解,也基于 geosite.dat 文件做了简单的域名分流配置。

    如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!

    5. 攻城略池 - 多种路由匹配条件

    [域名], [IP], [协议], etc.

    基于域名的分流,已经可以让我们对网络流量进行基本合理的分流。为什么说【基本合理】呢?

    因为【三分天下】虽然是正确的战略方向,但如果只用【域名】来实现这个战略,其实漏洞百出,比如:

    1. 我读了《小小白白话文》后,给 VPS 新申请了一个 proxy.yourdomain.com 的域名, 我希望它无论如何都代理,geosite.dat 里面有吗?
    2. 如果我还有个 direct.yourdomain.com 的域名,我希望它无论如何都直连, geosite.dat 里面有吗?
    3. 本机 127.0.0.1 的内部流量,是否正确直连了?(比如 docker 等)
    4. 路由器、本地局域网 192.168.*.* 的流量,是否正确直连了?(比如路由器、群晖等)
    5. 我的国内 DNS 查询(如 223.5.5.5)是否正确直连了?
    6. 我的国外 DNS 查询(如 1.1.1.1)是否正确代理了?
    7. 其他类似国内公共 DNS 一样没有域名、只有 IP 地址的国内网站,是否正确直连了?
    8. 其他类似国外公共 DNS 一样没有域名、只有 IP 地址的国外网站,是否正确代理了?
    9. BT 下载的流量,虽然来源是国外,但如果通过 VPS 下载很可能导致违规使用被封,这该如何强制直连?
    10. ......

    我之所以说只用【域名分流】会漏洞百出,是因为 geosite.dat 文件内只包含了一部分常用的域名。换言之,仅仅依赖它,则会:

    • 无法匹配文件里没有的新域名
    • 无法匹配基于 IP 地址的规则
    • 无法匹配基于网络协议的规则

    啰嗦君

    那我们来复习一下,当上面这些情况无法匹配时,会发生什么?对了,会触发隐藏路由规则,即【转发给第一个出站 】。这其实就是说:

    • 当你的第一个出站是 [direct-out] 时:需要直连的都正确了,但需要代理的则都错误
    • 当你的第一个出站是 [proxy-out-vless] 时:需要代理的都正确了,但需要直连的则都错误

    所以,我们需要一个办法,让我们鱼与熊掌兼得。这样的办法是否存在呢?当然存在! 我们需要的只是【域名】之外更多的【分流判断依据】而已。

    5.1 基于指定域名分流:[domain], [full]

    1. 如果需要匹配某个子域名,如 a-name.yourdomain.com,我们使用 full: "a-name.yourdomain.com"
    2. 前面的 问题1问题2,就可以通过给 proxy.yourdomain.com 指定 [proxy-out-vless] 出站,给 direct.yourdomain.com 指定 [direct-out] 出站来解决
    3. 如果需要匹配 yourdomain.com 的所有子域名,我们使用 domain: "yourdomain.com" 实现
    4. 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
    5. 另外,[domain] 还支持正则表达式等匹配方式。详情请参考 《基础配置模块 - 路由》文档

    上述配置如下:

    {
    @@ -187,6 +187,6 @@
       }
     }
     

    其实,第 6 点已经是我整理过的规则了,原则就是【相同的匹配依据可以合并,不同的匹配依据保持独立】。

    8. 明修栈道、暗渡陈仓

    [domain] 转化 [ip] 的密道:domainStrategy

    我们在 5.4 中提交了多种流量判断的【依据】,其中一种是域名 [domain]、一种是 [IP]

    如果你初步了解过 DNS 的运作过程,就会知道,我们对一个域名 [domain] 发起访问请求时,其实需要先向 DNS 发起请求来解析域名 [domain] 对应的 [IP],在得到 [IP] 后再向它发起实际请求。

    所以,面对入站的一次域名请求,Xray 其实有两次机会去判断它的类型。那么,究竟是否要用这两次机会呢?这就是由 domainStrategy 这个配置来决定的。它有三个选项:

    • AsIs
    • IPIfNonMatch
    • IPOnDemand

    按么我们逐个来解释一下:

    8.1 域名策略: "AsIs"

    就是 "As Domain Is",也就是说 【域名什么样,就什么样,不多折腾】。

    简单粗暴理解就是说【仅用 [domain] 来匹配】。

    Tip

    AsIs 的实际意义为 【如原先所示,不加修改】,🍉 老师这里描述的不是很恰当。

    这个方式的处理都在 Xray 内部完成,没有与外界的数据往来,所以速度最快。它的兜底策略也很清晰:即前面所说的、无法匹配的域名自动转入第一条出站处理。所以,对于常规使用路由功能这最推荐的策略。

    8.2 域名策略: "IPIfNonMatch"

    就是 "lookup IP if (there's) no matching rule",也就是说【如果其他所有规则都匹配不上,那就转化成 IP 去匹配 IP 规则】。

    简单粗暴理解就是说【先把访问目标和其他所有类型规则匹配,如果匹配不上,那就通过 DNS 查询转化成 IP,再从头和所有规则匹配一次】。

    该策略下没有命中任何规则的这一部分域名,会需要再经历 DNS 查询过程、以及第二轮规则匹配的过程,其耗时会多于 AsIs 策略,所以并不是首选推荐的策略。

    8.3 域名策略: "IPOnDemand"

    这里其实说 Demand IP 更准确些,也就是说【当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配】。

    简单粗暴理解就是说【只要路由规则中有 IP 类规则,那么所有基于域名 [domain] 的请求都要解析成 [IP] 然后去匹配 [IP] 类规则】。

    它要对所有首次域名访问进行 DNS 解析,所以首次查询比较耗时。虽然由于 XrayDNS 缓存机制的存在,后续对相同域名的访问速度会重回巅峰,但总体来说也不是首选推荐的策略。

    啰嗦君

    domainStrategy 仅对域名生效,不要搞混了哦~

    9. 思考题

    迄今为止,我们都是在【单入站】和【单出站】的基础上,讲解【路由】内部的各种配置逻辑。

    但是,如你所知,Xray 本身是支持多端口,多协议的。那么,如果我问你:

    1. 我希望 VLESS 协议将我日常的网页浏览和 APP 流量转发给美国的大流量服务器
    2. 我希望 trojan 协议将我的所有 Netflix 流量转发给日本的服务器解锁各种二次元
    3. 我希望 shadowsocks 协议将我所有的游戏流量转发给香港的服务器达到最低的延迟
    4. 我希望有一个独立的端口,能够把 telegram 的流量全都转发给 VPS
    5. 我希望有一个独立的端口,能够把 bittorrent 下载流量全都转发给欧洲大盘鸡
    6. 我希望......

    这些想法,是否能通过【路由】功能配置实现呢?

    答案当然是 【完全可以】 啦! 但是这些对于 level-1 来说已经超纲了,就留给各位自由的探索吧!

    10. 结语

    至此,Xray 的【路由】功能就介绍完了。希望本文能够对你理解 Xray 的灵活有所帮助。

    11. 尾注

    • 现在你可以重新阅读一遍 路由,看看是否有更加深刻的理解。
    • 🍉🍉🍉🍉🍉 😄
    - + diff --git a/en/document/level-1/work.html b/en/document/level-1/work.html index dfc346985d..b05a4192f0 100644 --- a/en/document/level-1/work.html +++ b/en/document/level-1/work.html @@ -24,11 +24,11 @@ Xray 的工作模式 | Project X - - + +

    Xray 的工作模式

    单服务器模式

    与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。

    一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。

    桥接模式

    如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。

    工作原理

    在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。

    • 需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。
      • 入站连接负责与客户端(如浏览器)通信:
        • 入站连接通常可以配置用户认证,如 ID 和密码等;
        • 入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;
      • 出站连接负责将数据发给服务器,如另一台主机上的 Xray。
    • 当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。
      • 路由会在必要时查询 DNS 以获取更多信息来进行判断。
    - + diff --git a/en/document/level-2/index.html b/en/document/level-2/index.html index 0beab4ff67..8f6f0703db 100644 --- a/en/document/level-2/index.html +++ b/en/document/level-2/index.html @@ -24,11 +24,11 @@ Advanced Documentation | Project X - - + +

    Advanced Documentation

    This chapter contains experience sharing of using Xray at an advanced level. If you are already familiar with Xray, the experience shared here can help you unleash the full power of Xray.

    Beginner's Guide to Transparent Proxies by a @kirinopen in new tag

    An Introduction to Transparent Proxies.

    TProxy Configuration Tutorial by a @BioniCosmosopen in new tag

    Complete tutorial on configuring transparent proxy (TProxy) based on Xray.

    TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial by a @SQLimitopen in new tag

    Xray-based TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial

    Nginx_TLS Tunnel Hidden Fingerprint by a @SQLimitopen in new tag

    Use Nginx_TLS tunnel on both ends to hide the fingerprint.

    [Transparent Proxy] Avoiding Xray Traffic Through gid by a @kirinopen in new tag

    A new way of bypassing Xray traffic in transparent proxy implemented by iptables/nftables.

    Redirect Specific Traffic to Specific Gateway using Xray to Achieve Global Routing "Load Balancing" by a @Zzz3mopen in new tag

    Play Xray to the fullest: Implement "load balancing" based on fwmark or sendThrough.

    Enhancing Proxy Security with Cloudflare Warp by a @yuhan6665open in new tag

    Introduction to using WireGuard for outbound traffic added in Xray v1.6.5.

    Xray Traffic Statistics by a @yuhan6665open in new tag

    Adapt traffic statistics and scripts compatible with Xray.

    - + diff --git a/en/document/level-2/iptables_gid.html b/en/document/level-2/iptables_gid.html index 64a7d16798..79d73b604a 100644 --- a/en/document/level-2/iptables_gid.html +++ b/en/document/level-2/iptables_gid.html @@ -24,8 +24,8 @@ Transparent proxy via GID | Project X - - + +

    Transparent proxy to circumvent Xray traffic via GID

    In the existing transparent proxy configuration(New V2Ray vernacular tutorial on transparent proxyopen in new tagNew V2Ray vernacular tutorial on transparent proxy (TProxy)open in new tagTransparent proxy(TProxy)configuration tutorial)tutorials, the circumvention of Xray traffic is achieved by using mark. That is, mark outbound traffics and set up iptables rules which directly connect traffics corresponding to the mark, to circumvent the Xray traffic and prevent loop back.

    There are several problems with this method:

    1. Inexplicable traffic into PREROUTING chainopen in new tag

    2. Android has its own mark mechanism and this solution is not available on Android

    The solution in this tutorial does not require a mark setting and has a higher theoretical performance, as well as not having the problems mentioned above.

    Ideas

    TProxy traffic can only be received by users with root privileges (uid==0) or other users with CAP_NET_ADMIN privileges.

    The iptables rules can separate network traffic by uid (user id) and gid (user group id). Let Xray run on a user with uid==0 but gid!=0. Set the iptables rule to not proxy traffic for that gid to circumvent Xray traffic.

    Configuration Procedure

    1. Preliminary preparation

    Android

    1. System has root privilege.

    2. Install busyboxopen in new tag

    3. There is a terminal that can execute commands, you can use adb shell, termux etc.

    Other Linux system

    Need sudo, iptables-tproxy module and iptables-extra module。

    Usually the system comes with these functions. If you are using openwrt, you will need to run the following command:

    opkg install sudo iptables-mod-tproxy iptables-mod-extra
    @@ -113,6 +113,6 @@
     ip6tables -t mangle -A XRAY6_MASK -j MARK --set-mark 1
     ip6tables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 ! -p icmp -j XRAY6_MASK
     
    - + diff --git a/en/document/level-2/nginx_or_haproxy_tls_tunnel.html b/en/document/level-2/nginx_or_haproxy_tls_tunnel.html index 9a666aa834..161b2109df 100644 --- a/en/document/level-2/nginx_or_haproxy_tls_tunnel.html +++ b/en/document/level-2/nginx_or_haproxy_tls_tunnel.html @@ -24,8 +24,8 @@ Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹 | Project X - - + +

    Nginx 或 Haproxy 实现的 HTTPS 隧道、HTTP/2 over HTTPS 隧道、WebSocket over HTTP/2 over HTTPS 隧道、gRPC over HTTP/2 over HTTPS 隧道以及自签证书双端认证的 gRPC over HTTP/2 over HTTPS 隧道

    客户端服务端 Nginx 构建 HTPPS 隧道隐藏指纹

    网路结构:

    xray_client ---tcp--- nginx_client ---HTTPS--- nginx_sever ---tcp--- xray_server

    编译 nginx --with-stream

    在客户端及服务端均编译

    curl -O -L http://nginx.org/download/nginx-1.22.1.tar.gz

    tar -zxvf nginx-1.22.1.tar.gz

    cd nginx-1.22.1

    apt install gcc make //编译依赖 gcc 以及 make

    ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-stream --with-stream_ssl_module //此步需要依赖一些库,根据报错安装相应 lib

    make && make install

    编译之后 nginx 文件夹位于 /usr/local/nginx

    配置 nginx

    编辑 nginx 配置文件 nginx.conf

    vim /usr/local/nginx/conf/nginx.conf

    服务端加入如下配置

    服务器申请证书不再赘述,参考白话文open in new tag

    stream {
    @@ -548,6 +548,6 @@
     backend web
         server web /dev/shm/h1h2c.sock
     

    xray 配置

    简单的 gRPC 配置,无需 TLS,配置见文档,配置的 serviceName 可用于分流。

    - + diff --git a/en/document/level-2/redirect.html b/en/document/level-2/redirect.html index 8cebc2485a..2fd471e16c 100644 --- a/en/document/level-2/redirect.html +++ b/en/document/level-2/redirect.html @@ -24,8 +24,8 @@ 出站流量重定向 | Project X - - + +

    基于 fwmark 或 sendThrough 的流量重定向

    通过 Xray 将特定的流量指向特定出口,实现全局路由“分流”

    前言

    之前在网络上看到许多代理或者 VPN 会接管全局路由,如果与 Xray 同时安装,会导致 Xray 失效。参考了网络上许多教程,及时分流,也是通过维护一张或者多张 CIDR 路由表来实现的。这种情况下并不优雅,如果我想可以任意替换,实现按需分流,那有没有更好的办法呢?有!

    通过 fwmark 或 Xray 的 sendThrough,再简单配合路由表功能即可实现:

    1. Xray 可设置指定的 Tag、域名等走指定接口。如果您的接口是双栈的,可以指定 IPV4 或者 IPV6
    2. 其余用户则走原 IPV4 或者 IPV6

    具体设置如下(以 Debian10 为例):

    1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)

    根据不同系统和不同软件,请参考官方安装方法

    2、编辑 VPN 配置文件(以 WireGuard 为例)

    原始文件:

    [Interface]
    @@ -240,6 +240,6 @@
     

    开机自启

    systemctl enable wg-quick@wg0
     systemctl start wg-quick@wg0
     

    验证 IPv4/IPv6

    自行验证 Google 搜索 myip

    后记

    本文本意是可以避免的多余的流量浪费,将路由和分流的功能交给 Xray 处理。避免了维护路由表的繁琐工作。顺便技术提升 UP。

    感谢

    @Xray-core @V2ray-core @WireGuard @p3terx @w @Hiram @Luminous @Ln @JackChou

    - + diff --git a/en/document/level-2/tproxy.html b/en/document/level-2/tproxy.html index b6dc3f72bf..0c5618f9bf 100644 --- a/en/document/level-2/tproxy.html +++ b/en/document/level-2/tproxy.html @@ -24,8 +24,8 @@ TProxy 透明代理 | Project X - - + +

    透明代理(TProxy)配置教程

    本配置基于TProxy 透明代理的新 V2Ray 白话文教程open in new tag,加入了 Xray 的新特性,使用 VLESS + XTLS Vision 方案,并将旧教程中默认出站代理的分流方式改为默认出站直连,使用者请按照实际情况进行修改。

    本文中所有配置已在 Raspberry Pi 2B、Ubuntu 20.04 环境下测试成功,如在其它环境中使用请自行调整配置。

    开始之前

    请检查您的设备是否有可用的网络连接,且服务端已经配置成功,客户端已经安装完毕。

    需注意的是,目前很多透明代理教程都会将 Linux 系统的 IP 转发打开,但这样会导致 Splice 性能下降。详情请参考大案牍术破案纪实第三篇--我们是如何破解 Splice 性能下降甚至低于 Direct 之谜的open in new tag

    这里我想要补充的是,很多透明代理教程会使用 Netfilter 进行分流,使直连流量直接发出而不经过 Xray,这时必须开启 IP 转发;也有的教程,如本文,会将所有流量导入 Xray 之中,由 Xray 的路由模块进行分流,这时无需开启 IP 转发。

    Xray 配置

    为了更好的分流体验,请替换默认路由规则文件为 Loyalsoldier/v2ray-rules-datopen in new tag,否则 Xray-core 将无法加载本配置。

    sudo curl -oL /usr/local/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat
    @@ -281,6 +281,6 @@
     [Install]
     WantedBy=multi-user.target
     
    - + diff --git a/en/document/level-2/tproxy_ipv4_and_ipv6.html b/en/document/level-2/tproxy_ipv4_and_ipv6.html index 2c3f8705ef..e8a090a933 100644 --- a/en/document/level-2/tproxy_ipv4_and_ipv6.html +++ b/en/document/level-2/tproxy_ipv4_and_ipv6.html @@ -24,8 +24,8 @@ TProxy 透明代理 (ipv4 and ipv6) | Project X - - + +

    TProxy 透明代理(ipv4 and ipv6)配置教程

    本配置参考了TProxy 透明代理的新 V2Ray 白话文教程open in new tag透明代理(TProxy)配置教程open in new tag以及透明代理通过 gid 规避 Xray 流量open in new tag,加入了透明代理对 ipv6 的支持,并且使用 VLESS-TCP-XTLS-RPRX-Vision 方案对抗封锁 (推荐使用 1.7.2 及之后版本)。

    关于 Xray 的配置并不是本文重点,使用者可依实际情况进行修改,具体可以参考官方文档示例open in new tag或其他优秀示例 比如@chika0801open in new tag 又如@lxhao61open in new tag

    注意

    若使用其他配置,你需要着重注意客户端配置中 outboundtagproxy 的部分,其他部分不变

    服务端配置也要同时改变

    此配置意在解决例如 Netflix 等默认使用 ipv6 连接的网站无法通过旁路由进行代理的问题,或对 ipv6 代理有需要。

    本文网络结构为单臂旁路由

    本文中所有配置已在 Arch Linux (Kernel: 6.0.10) 环境下测试成功,如在其它环境中同理

    注意安装相应程序 # sudo apt install iptables ip6tables# sudo apt install nftables

    若旁路由未安装 xray 程序,可以手动下载相应 xray 程序如 Xray-linux-64.zipopen in new tag ,然后复制 install-release.shopen in new tag 文件到旁路由,赋予可执行权限 # chmod 700 install-release.sh,然后使用 # ./install-release.sh --local Xray-linux-64.zip 根据提示进行本地安装。

    Xray 配置

    客户端配置

    {
    @@ -430,6 +430,6 @@
     [Install]
     WantedBy=multi-user.target
     
    1. 最后执行 systemctl enable tproxyrules 命令。

    tproxyrules.service

    注意其中主路由器 IP 地址,根据实际修改

    ExecStartPre=/bin/sh -c 'until ping -c1 192.168.31.1; do sleep 1; done;' 命令为确保获得 IP 地址后再执行命令,否则会诡异报错,其中 IP 地址为主路由器地址,根据实际修改。

    注意

    如果通过 dhcpcd 等设置了静态 IP 及网关,则上述相关 ip route add/del 设置需删除

    局域网设备上网设置

    此处假定旁路由 ipv4, ipv6 地址分别为192.168.31.100, fd00:6868:6868::8866, 旁路由的 ipv4, ipv6 地址可由命令ip add获得。

    方法一

    局域网设备上网有两种方式,第一种就是在使用设备上进行静态 IP 的配置,将网关指向旁路由 IP。注意绝大部分手机仅支持手动配置 ipv4 网关,不支持手动配置 ipv6 网关,除非 root 后进行相关设置。

    以 windows 设备为例,可以先开启 DHCP 记录自动分配的 IP 以参考,然后手写静态配置。

    DNS 设置

    此配置劫持 DNS 流量,DNS 可以随便写

    image image

    方法二

    局域网设备上网的第二种方式,是在路由器上进行网关设置,这种方法对于连接到此路由器的设备无需做任何设置即可科学上网,但注意有些路由器不支持 ipv6 的网关设置,有 ipv6 需求的设备仍需在所需设备上单独手动配置 ipv6 相关设置参考方法一。

    image

    Finally

    按照以上方法设置后设备即可双栈访问,进入测试网站比如 https://ipv6-test.com/ 可以看到如下结果 (需要代理此网站才能看到如下结果)

    image

    写在最后

    如今 ipv6 并未完全普及,我们日常访问的流量 99%仍为 ipv4 流量;很多 VPS 商家虽然提供 ipv6 地址,但线路优化非常垃圾,甚至处于不可用状态,为何要加入 ipV6 的设置?

    可以看到目前 ipv6 处于很尴尬的境地,各种设备对于 ipv6 的支持很烂,但是都在逐步完善,同时 Windows 系统对于 ipv6 的优先级也在提高,很多浏览器也会优先进行 ipv6 的解析以及访问,很多网站也开始默认使用 ipv6 进行访问(比如 Netflix, 如果没有配置 ipv6, 浏览器打开 Netflix 会显示 Not Available 是因为没有代理 Netflix 的 ipv6 请求,当然可以选择禁用 Windows 的 ipv6,但支持 ipv6 的 pt 站就无法使用)

    这种情况下 ipv4 无法完全胜任网络冲浪的需求,即使是那 1%的流量,遇到了也会让人头疼不已。

    而可以预见 ipv6 也会逐步与 ipv4 分庭抗礼,所以有必要加入 ipv6 的设置。

    - + diff --git a/en/document/level-2/traffic_stats.html b/en/document/level-2/traffic_stats.html index d8b3fb5d20..b3741b2705 100644 --- a/en/document/level-2/traffic_stats.html +++ b/en/document/level-2/traffic_stats.html @@ -24,8 +24,8 @@ 流量统计 | Project X - - + +

    流量统计配置教程

    请熟悉流量统计 白话文教程open in new tag,本文在其基础上适配了 Xray(1.5.9+)。

    查看流量信息

    配置方法与 v2fly 一致。 查看流量信息是 xray 命令行的其中一个功能。配置内设置的 api dokodemo-door 端口,即为 --server 参数的端口。

    xray api statsquery --server=127.0.0.1:10085 #查看所有流量
    @@ -120,6 +120,6 @@
     print_sum "$DATA" "user"
     echo "-----------------------------"
     
    - + diff --git a/en/document/level-2/transparent_proxy/transparent_proxy.html b/en/document/level-2/transparent_proxy/transparent_proxy.html index 5e4d91f8cc..292a9db759 100644 --- a/en/document/level-2/transparent_proxy/transparent_proxy.html +++ b/en/document/level-2/transparent_proxy/transparent_proxy.html @@ -24,8 +24,8 @@ 透明代理入门 | Project X - - + +

    透明代理入门

    什么是透明代理

    透明代理简单地说就是不让被代理的设备感觉到自己被代理了。简单地说就是,被代理的设备上不需要运行任何代理软件(比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。

    这也意味着,代理的软件运行在别的地方,比如运行在路由器中,通过路由器上网的设备就自动被代理了。

    透明代理的实现

    透明代理的实现目前主要有两种方式:

    tun2socks

    可用 Windows/Linux(包括安卓)实现。因为实现过程比较简单,很少有教程,我这里简单描述一下。

    Windows

    1. 安装 Netchopen in new tag ,使用模式[3] [TUN/TAP] 绕过局域网启动。

    2. 开启热点

    3. 打开控制面板->网络和 Internet->网络和共享中心->更改适配器设置,找到TAP-Windows AdapterMicrosoft Wi-Fi Direct Virtual Adapter

    4. 鼠标右键点击TAP-Windows Adapter属性->共享,勾选允许其他网络用户通过此计算机的 Internet 连接来连接,在家庭网络连接中选择Microsoft Wi-Fi Direct Virtual Adapter的那个网络连接,点击确定。

    Android

    1. 配置连接 V2RayNG

    2. 开启热点

    3. 热点设置 -> 允许热点使用 VPN(部分安卓系统可能没有这个选项)

    iptables/nftables

    iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。

    基于 iptables 的透明代理实现只能用于 Linux 系统(包括 openwrt/安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而广泛使用。

    现存的三篇白话文透明代理教程其实讲的都是基于这种方案的透明代理实现,它们是: 新 V2Ray 白话文指南-透明代理open in new tag新 V2Ray 白话文指南-透明代理(TPROXY)open in new tag透明代理(TProxy)配置教程 。其中第一篇是基于 iptables-redirect 模式,已经过时了,不建议使用,仅供参考。第二篇和第三篇讲的都是基于 iptables-tproxy 模式的透明代理实现。

    iptables 实现透明代理原理

    Linux 使用Netfilter来管理网络,Netfilter模型如下:

    Netfilter

    假设使用路由器作为网关(即我们平时的上网方式),那么:

    局域网设备通过路由器访问互联网的流量方向:

    PREROUTING链->FORWARD链->POSTINGROUTING链

    局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:

    PREROUTING链->INPUT链->网关本机

    路由器访问互联网的流量方向:

    网关本机->OUTPUT链->POSTINGROUTING链

    通过使用 iptables 操控PREROUTING链OUTPUT链的流量走向,转发到 Xray,就可以代理局域网设备和网关本机。

    透明代理难在哪里

    透明代理的难点就在于路由,所谓路由,就是区分哪些流量是直连的,哪些该被代理,所以我个人认为叫做分流更加合适。

    我们可以把路由由易到难分为以下几个阶段:

    1. 代理全部请求

    2. 本地局域网 IP/组播 IP 请求直连,其它请求代理

    3. 在 2 的基础上直连 Xray 发起的连接请求

    4. 在 3 的基础上直连指向中国大陆 IP 的连接请求,并对国内外域名选择国内外 DNS 服务器解析。

    上面说的三篇教程,都是在第四阶段。所以新手直接阅读可能显得有点难懂。

    从零开始一步步实现基于 iptables-tproxy 的透明代理

    在开始之前,你需要有一定的基础知识:

    1. 大概知道什么是 TCP/IP 协议、域名和 DNS 服务器

    2. 知道什么是 WAN 口,LAN 口,LAN_IP,WAN_IP 以及 DHCP 服务器。对于旁路由,只有一个网口,这里称其为 LAN 口

    3. 对 Linux 系统有最基础的了解(知道怎么运行命令)

    4. 能够手写客户端 json 文件配置,至少要能看懂

    前期准备工作

    1. 准备一个运行 Linux 系统的网关

    比如,刷了 OpenWRT 的路由器

    2. 在网关(路由器)准备好 Xray 可执行文件以及配置文件

    配置文件监听 12345 端口,开启 tproxy:

    {
    @@ -107,6 +107,6 @@
     iptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK
     iptables -t mangle -A OUTPUT -p udp -j XRAY_MASK
     

    但是这么配置有个缺点,如果使用 CDN 或者 VPS 很多的话,就不好写规则了。

    1. 通过 mark 规避

    三个白话文教程都是使用这种方法规避,自行参考,这里不再赘述。

    1. 通过 gid 规避(推荐)

    参考 [透明代理]通过 gid 规避 Xray 流量

    这样就完成了第三阶段的代理,也就是平时说的全局代理。但是记得把网关的 DNS 服务器设置为国外的 DNS 服务器,否则可能依然返回被污染的结果。

    第四阶段

    其实,并不是所有人都需要实现第四阶段。全局代理对于大部分情况已经适用。

    特别是对于旁路由而言。需要代理时,将网关调成旁路由的 IP,不需要代理时,将网关换回主路由 IP。

    至于第四阶段的具体实现,那三篇白话文教程讲的都是。在理解了上面的内容后,再去看那三篇白话文教程,就比较容易理解了。

    代理 ipv6

    上面的规则只对 ipv4 生效,如果还想要代理 ipv6 请求,则使用 ip6tables 命令,用法与 iptables 基本相同。参考 [透明代理]通过 gid 规避 Xray 流量#4-设置 iptables 规则

    iptables 透明代理的其它注意事项

    1. 如果作为代理的网关作为主路由,要在PREROUTING链规则中加一条iptables -t mangle -A XRAY ! -s 网关LAN_IP地址段 -j RETURN,即在第一阶段使用、第二阶段被删除的指令。如果不写,WAN 口中同网段的其它人可以将网关填写成你的 WAN_IP,从而蹭你的透明代理用,还可能带来一定的危险性。

    2. 新 V2Ray 白话文指南-透明代理(TPROXY)#设置网关open in new tag 中的第三条说:手动配置 PC 的网络,将默认网关指向树莓派的地址即 192.168.1.22。此时 PC 应当能正常上网(由于还没设置代理,“正常”是指可以上国内的网站)。实际上,Ubuntu、CentOS、debian 等系统就算开启了 IP 转发,PC 也不能正常上网,这是正常的。事实上只有 OpenWRT 能做到文中所描述的那样,据 @BioniCosmosopen in new tag 点拨,这是由于一般的 Linux 系统没有 Masquery 规则。

    3. too many open files 问题open in new tag ,解决方法见 [透明代理]通过 gid 规避 Xray 流量-配置最大文件大开数&运行 Xray 客户端

    4. 关于开启 ip_forward,待补充...

    5. 避免已有连接的包二次通过 TPROXY ,待补充...

    6. 主路由、单臂路由与旁路由,待补充...

    - + diff --git a/en/document/level-2/warp.html b/en/document/level-2/warp.html index 55111a7a77..cd83ba34be 100644 --- a/en/document/level-2/warp.html +++ b/en/document/level-2/warp.html @@ -24,8 +24,8 @@ Enhancing Proxy Security with Cloudflare Warp | Project X - - + +

    Enhancing Proxy Security with Cloudflare Warp

    Xray (1.6.5+) has added outbound WireGuard support. Although the added code and dependencies will increase the core size, we believe that this is a necessary new feature for three reasons:

    1. Through recent discussions and experimentsopen in new tag, we know that proxying the traffic back to China is not safe. One way to deal with this is to route the back-to-China traffic to a black hole, but the downside is that due to the delay in geosite and geoip updates or the lack of knowledge on how to properly split the traffic on the client side, the traffic ends up going to the black hole, affecting the user experience. In this case, we only need to import the back-to-China traffic into Cloudflare Warp, which can achieve the same level of security without affecting the user experience.
    2. As we all know, most airports will log the domain names visited by users, and some airports will even audit and block some user traffic. One way to protect user privacy is to use chain proxies on the client side. The WireGuard lightweight VPN protocol used by Warp adds an extra layer of encryption within the proxy layer. For airports, the target of all user traffic is Warp, thereby maximizing privacy protection.
    3. It is easy to use, and only one core is needed to complete the split, Wireguard Tun, and chain proxy settings.

    Applying for a Warp Account

    1. Thank you Cloudflare for promoting a free internet. Now you can use the Warp service for free, and the nearest server will be automatically selected based on the exit.
    2. Use a VPS and download wgcfopen in new tag.
    3. Run wgcf register to generate wgcf-account.toml.
    4. Run wgcf generate to generate wgcf-profile.conf. Copy the following content:
    [Interface]
    @@ -111,6 +111,6 @@
        ]
     }
     
    - + diff --git a/en/index.html b/en/index.html index 3544300b08..f0f100dd7a 100644 --- a/en/index.html +++ b/en/index.html @@ -24,8 +24,8 @@ Project X - - + +
    Project X

    Project X

    Fear not the clouds that obscure the view, golden eyes like a torch brighten the sky

    Start here → Configuration guide →

    High-speed protocol

    Original VLESS and XTLS protocols, free from redundant encryption, release CPU power

    Free combination

    Perfect fallback mechanism, effectively prevent active detection, multi-service sharing ports @@ -34,6 +34,6 @@

    Full compatibility

    Fully compatible with v2ray-core configuration files and API calls

    Affinity

    Active community discussions and contributions, MPL 2.0 open source license

    XTLS? Xray? V2Ray?

    XTLS are brilliant ideas for TLS we study, while Xray is the best practice we maintain.

    • Xray-core is a superset of v2ray-core, with better overall performance and enhancements such as XTLS, and it'scompletelycompatible with v2ray-core functionality and configuration.
      • Only one executable file, including ctl functionality, run is the default command
      • Configuration iscompletelycompatible, environment variables and API calls need to be changed to start with XRAY_
      • Exposed raw protocol's ReadV on all platforms
      • Provides complete VLESS & Trojan XTLS support, both with ReadV
      • Provides multiple XTLS flow control modes, unrivaled performance!

    "Configuration compatible, overall better"

    Who are we?

    It doesn't matter who we are. What matters is that we will keep riding and never look back.

    Help Xray become stronger

    Welcome to help Xray become stronger!

    Telegram

    Thanks

    • Thanks to everyone for their support!
    • Thanks to all kinds of scripts, Docker images, client support... Thanks to all the big guys who helped improve the ecosystem!
    • Thanks to friends who have contributed to the Xray website and documentation.
    • Thanks to friends who have made meaningful suggestions and comments.
    • Thanks to every friend in the Telegram group who helps others.

    More about project X

    • If you would like to learn more about project X's history and growth, please click here

    License

    Mozilla Public License Version 2.0open in new tag

    Stargazers over time

    Stargazers over timeopen in new tag

    - + diff --git a/index.html b/index.html index 17850ed966..ee571e664a 100644 --- a/index.html +++ b/index.html @@ -24,8 +24,8 @@ Project X - - + +
    Project X

    Project X

    不畏浮云遮望眼 · 金睛如炬耀苍穹

    由此开始 → 配置指南 →

    极速协议

    原创 VLESS 与 XTLS 协议,摆脱冗余加密,释放CPU算力

    自由组合

    完善的回落机制,有效防止主动探测,多服务共享端口 @@ -34,6 +34,6 @@

    完整兼容

    完整兼容 v2ray-core 配置文件与 API 调用

    亲和力

    活跃的社区讨论及贡献,MPL 2.0 开源许可协议

    XTLS ? Xray ? V2Ray ?

    XTLS are brilliant ideas for TLS we study, while Xray is the best practice we maintain.

    • Xray-core 是 v2ray-core 的超集,含更好的整体性能和 XTLS 等一系列增强,且完全兼容 v2ray-core 的功能及配置。
      • 只有一个可执行文件,含 ctl 的功能,run 为默认指令
      • 配置上完全兼容,环境变量和 API 对应要改为以 XRAY_ 开头
      • 全平台开放了裸协议的 ReadV
      • 提供完整的 VLESS & Trojan XTLS 支持,均有 ReadV
      • 提供了 XTLS 多种流控模式, 性能一骑绝尘!

    “配置兼容,整体更好”

    我们是谁?

    It doesn't matter who we are. What matters is that we will keep riding and never look back.

    帮助 Xray 变得更强

    欢迎帮助 Xray 变得更强!

    Telegram

    致谢

    • 感谢所有人的支持!
    • 感谢各类脚本、Docker 镜像、客户端支持...感谢所有帮忙完善生态的大佬们!
    • 感谢为 Xray 网站和文档添砖加瓦的朋友们.
    • 感谢提出有意义的建议和意见的朋友们.
    • 感谢 Telegram 群每一位帮助群友的朋友.

    更多关于 Project X

    • 如果你想知道更多关于 Project X 的足迹与成长, 请点击这里

    License

    Mozilla Public License Version 2.0open in new tag

    Stargazers over time

    Stargazers over timeopen in new tag

    - +