diff --git a/404.html b/404.html index 7d8b07f09..40452a6ee 100644 --- a/404.html +++ b/404.html @@ -5,11 +5,11 @@ Project X - + -

404

There's nothing here.
Take me home
- +

404

That's a Four-Oh-Four.
Take me home
+ diff --git a/about/news.html b/about/news.html index 4ea9e2825..f7ce8d797 100644 --- a/about/news.html +++ b/about/news.html @@ -5,11 +5,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 window

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

2021.3.25

没错还在变。 -_-

2021.3.15

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

2021.3.14 v1.4.0open in new window

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

2021.3.3 1.3.1open in new window

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

2021.2.14 1.3.0open in new window

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

2021.01.31 1.2.4open in new window

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

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

2021.01.25

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

2021.01.22 1.2.3open in new window

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

2021.01.19

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

2021.01.17

2021.01.15 1.2.2open in new window

  • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 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 window

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

2021.01.07

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

2021.01.05

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

2021.01.03

2021.01.01

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

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

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

2020.12.29

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

2020.12.25 1.1.5open in new window

圣诞节快乐!

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

2020.12.24

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

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

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

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

2020.12.23

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

2020.12.21

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

2020.12.18 1.1.4open in new window

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

2020.12.17

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

2020.12.15

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

2020.12.11 1.1.3open in new window

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

2020.12.06 1.1.2open in new window

  • 流控增加 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 window

Xray 的第一个版本.

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

2020.11.23

project X start

梦开始的时候

- + diff --git a/assets/404.57a909a7.js b/assets/404.0a7ce90e.js similarity index 68% rename from assets/404.57a909a7.js rename to assets/404.0a7ce90e.js index f28aeaca7..ba4ce0911 100644 --- a/assets/404.57a909a7.js +++ b/assets/404.0a7ce90e.js @@ -1 +1 @@ -import{f as a,u as t,g as o,r as e,c as l,a as s,t as n,b as u,w as r,h as c,o as d,e as h}from"./app.755d843f.js";const m={class:"theme-container"},v={class:"theme-default-content"},f=s("h1",null,"404",-1);var i=a({setup(a){var i,p,k;const b=t(),g=o(),F=null!=(i=g.value.notFound)?i:["Not Found"],M=null!=(p=g.value.home)?p:b.value,j=null!=(k=g.value.backToHome)?k:"Back to home";return(a,t)=>{const o=e("RouterLink");return d(),l("div",m,[s("div",v,[f,s("blockquote",null,n(F[Math.floor(Math.random()*F.length)]),1),u(o,{to:c(M)},{default:r((()=>[h(n(c(j)),1)])),_:1},8,["to"])])])}}});export default i; +import{f as a,u as t,g as o,r as e,c as l,a as s,t as n,b as u,w as r,h as c,o as h,e as d}from"./app.48111a85.js";const m={class:"theme-container"},v={class:"theme-default-content"},f=s("h1",null,"404",-1);var i=a({setup(a){var i,p,k;const b=t(),g=o(),F=null!=(i=g.value.notFound)?i:["Not Found"],M=null!=(p=g.value.home)?p:b.value,j=null!=(k=g.value.backToHome)?k:"Back to home";return(a,t)=>{const o=e("RouterLink");return h(),l("div",m,[s("div",v,[f,s("blockquote",null,n(F[Math.floor(Math.random()*F.length)]),1),u(o,{to:c(M)},{default:r((()=>[d(n(c(j)),1)])),_:1},8,["to"])])])}}});export default i; diff --git a/assets/Layout.5e6424a3.js b/assets/Layout.47faf5cd.js similarity index 56% rename from assets/Layout.5e6424a3.js rename to assets/Layout.47faf5cd.js index 14939aadf..16e9e39f7 100644 --- a/assets/Layout.5e6424a3.js +++ b/assets/Layout.47faf5cd.js @@ -1 +1 @@ -var e=Object.defineProperty,l=Object.defineProperties,t=Object.getOwnPropertyDescriptors,a=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,s=Object.prototype.propertyIsEnumerable,r=(l,t,a)=>t in l?e(l,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):l[t]=a,o=(e,l)=>{for(var t in l||(l={}))n.call(l,t)&&r(e,t,l[t]);if(a)for(var t of a(l))s.call(l,t)&&r(e,t,l[t]);return e},u=(e,a)=>l(e,t(a));"undefined"!=typeof require&&require;import{f as i,i as c,j as v,k as d,l as p,m as h,n as m,r as b,h as f,o as g,p as k,w as y,q as x,e as w,t as L,s as $,c as C,v as M,x as T,y as O,z as j,A as R,B as z,a as P,F as B,C as E,D as _,b as D,T as N,E as S,G as q,H as A,I as F,J as H,u as I,g as W,K as U,L as V,M as X,N as Y,d as G,O as J,P as K,Q,R as Z,S as ee,U as le,V as te,W as ae,X as ne}from"./app.755d843f.js";const se=["href","rel","target","aria-label"],re=i({inheritAttrs:!1});var oe=i(u(o({},re),{props:{item:{type:Object,required:!0}},setup:function(e){const l=e,t=c(),a=T(),{item:n}=v(l),s=d((()=>p(n.value.link))),r=d((()=>h(n.value.link)||m(n.value.link))),o=d((()=>{if(!r.value)return n.value.target?n.value.target:s.value?"_blank":void 0})),u=d((()=>"_blank"===o.value)),i=d((()=>!s.value&&!r.value&&!u.value)),O=d((()=>{if(!r.value)return n.value.rel?n.value.rel:u.value?"noopener noreferrer":void 0})),j=d((()=>n.value.ariaLabel||n.value.text)),R=d((()=>{const e=Object.keys(a.value.locales);return e.length?!e.some((e=>e===n.value.link)):"/"!==n.value.link})),z=d((()=>!!R.value&&t.path.startsWith(n.value.link))),P=d((()=>!!i.value&&(n.value.activeMatch?new RegExp(n.value.activeMatch).test(t.path):z.value)));return(e,l)=>{const t=b("RouterLink"),a=b("OutboundLink");return f(i)?(g(),k(t,$({key:0,class:["nav-link",{"router-link-active":f(P)}],to:f(n).link,"aria-label":f(j)},e.$attrs),{default:y((()=>[x(e.$slots,"before"),w(" "+L(f(n).text)+" ",1),x(e.$slots,"after")])),_:3},16,["class","to","aria-label"])):(g(),C("a",$({key:1,class:"nav-link external",href:f(n).link,rel:f(O),target:f(o),"aria-label":f(j)},e.$attrs),[x(e.$slots,"before"),w(" "+L(f(n).text)+" ",1),f(u)?(g(),k(a,{key:0})):M("",!0),x(e.$slots,"after")],16,se))}}}));const ue=["aria-labelledby"],ie={class:"hero"},ce=["src","alt"],ve={key:1,id:"main-title"},de={key:2,class:"description"},pe={key:3,class:"actions"},he={key:0,class:"features"},me={class:"theme-default-content custom"},be=["innerHTML"],fe=["textContent"];var ge=i({setup(e){const l=O(),t=j(),a=d((()=>l.value.heroImage?R(l.value.heroImage):null)),n=d((()=>null===l.value.heroText?null:l.value.heroText||t.value.title||"Hello")),s=d((()=>l.value.heroAlt||n.value||"hero")),r=d((()=>null===l.value.tagline?null:l.value.tagline||t.value.description||"Welcome to your VuePress site")),o=d((()=>z(l.value.actions)?l.value.actions.map((({text:e,link:l,type:t="primary"})=>({text:e,link:l,type:t}))):[])),u=d((()=>z(l.value.features)?l.value.features:[])),i=d((()=>l.value.footer)),c=d((()=>l.value.footerHtml));return(e,l)=>{const t=b("Content");return g(),C("main",{class:"home","aria-labelledby":f(n)?"main-title":void 0},[P("header",ie,[f(a)?(g(),C("img",{key:0,src:f(a),alt:f(s)},null,8,ce)):M("",!0),f(n)?(g(),C("h1",ve,L(f(n)),1)):M("",!0),f(r)?(g(),C("p",de,L(f(r)),1)):M("",!0),f(o).length?(g(),C("p",pe,[(g(!0),C(B,null,E(f(o),(e=>(g(),k(oe,{key:e.text,class:_(["action-button",[e.type]]),item:e},null,8,["class","item"])))),128))])):M("",!0)]),f(u).length?(g(),C("div",he,[(g(!0),C(B,null,E(f(u),(e=>(g(),C("div",{key:e.title,class:"feature"},[P("h2",null,L(e.title),1),P("p",null,L(e.details),1)])))),128))])):M("",!0),P("div",me,[D(t)]),f(i)?(g(),C(B,{key:1},[f(c)?(g(),C("div",{key:0,class:"footer",innerHTML:f(i)},null,8,be)):(g(),C("div",{key:1,class:"footer",textContent:L(f(i))},null,8,fe))],64)):M("",!0)],8,ue)}}}),ke=i({setup(e){const l=e=>{e.style.height=e.scrollHeight+"px"},t=e=>{e.style.height=""};return(e,a)=>(g(),k(N,{name:"dropdown",onEnter:l,onAfterEnter:t,onBeforeLeave:l},{default:y((()=>[x(e.$slots,"default")])),_:3}))}});const ye=["aria-label"],xe={class:"title"},we=P("span",{class:"arrow down"},null,-1),Le=["aria-label"],$e={class:"title"},Ce={class:"nav-dropdown"},Me={class:"dropdown-subtitle"},Te={key:1},Oe={class:"dropdown-subitem-wrapper"};var je=i({props:{item:{type:Object,required:!0}},setup(e){const l=e,{item:t}=v(l),a=d((()=>t.value.ariaLabel||t.value.text)),n=S(!1),s=c();q((()=>s.path),(()=>{n.value=!1}));const r=e=>{const l=0===e.detail;n.value=!!l&&!n.value},o=(e,l)=>l[l.length-1]===e;return(e,l)=>(g(),C("div",{class:_(["dropdown-wrapper",{open:n.value}])},[P("button",{class:"dropdown-title",type:"button","aria-label":f(a),onClick:r},[P("span",xe,L(f(t).text),1),we],8,ye),P("button",{class:"mobile-dropdown-title",type:"button","aria-label":f(a),onClick:l[0]||(l[0]=e=>n.value=!n.value)},[P("span",$e,L(f(t).text),1),P("span",{class:_(["arrow",n.value?"down":"right"])},null,2)],8,Le),D(ke,null,{default:y((()=>[A(P("ul",Ce,[(g(!0),C(B,null,E(f(t).children,((e,l)=>(g(),C("li",{key:e.link||l,class:"dropdown-item"},[e.children?(g(),C(B,{key:0},[P("h4",Me,[e.link?(g(),k(oe,{key:0,item:e,onFocusout:l=>o(e,f(t).children)&&0===e.children.length&&(n.value=!1)},null,8,["item","onFocusout"])):(g(),C("span",Te,L(e.text),1))]),P("ul",Oe,[(g(!0),C(B,null,E(e.children,(l=>(g(),C("li",{key:l.link,class:"dropdown-subitem"},[D(oe,{item:l,onFocusout:a=>o(l,e.children)&&o(e,f(t).children)&&(n.value=!1)},null,8,["item","onFocusout"])])))),128))])],64)):(g(),k(oe,{key:1,item:e,onFocusout:l=>o(e,f(t).children)&&(n.value=!1)},null,8,["item","onFocusout"]))])))),128))],512),[[F,n.value]])])),_:1})],2))}});const Re={key:0,class:"navbar-links"};var ze=i({setup(e){const l=e=>V(e)?X(e):e.children?u(o({},e),{children:e.children.map(l)}):e,t=(()=>{const e=W();return d((()=>(e.value.navbar||[]).map(l)))})(),a=(()=>{const e=H(),l=I(),t=j(),a=W();return d((()=>{var n,s;const r=Object.keys(t.value.locales);if(r.length<2)return[];const o=e.currentRoute.value.path,u=e.currentRoute.value.fullPath;return[{text:null!=(n=a.value.selectLanguageText)?n:"unkown language",ariaLabel:null!=(s=a.value.selectLanguageAriaLabel)?s:"unkown language",children:r.map((n=>{var s,r,i,c,v,d;const p=null!=(r=null==(s=t.value.locales)?void 0:s[n])?r:{},h=null!=(c=null==(i=a.value.locales)?void 0:i[n])?c:{},m=`${p.lang}`,b=null!=(v=h.selectLanguageName)?v:m;let f;if(m===t.value.lang)f=u;else{const t=o.replace(l.value,n);f=e.getRoutes().some((e=>e.path===t))?t:null!=(d=h.home)?d:n}return{text:b,link:f}}))}]}))})(),n=(()=>{const e=W(),l=d((()=>e.value.repo)),t=d((()=>l.value?U(l.value):null)),a=d((()=>l.value&&!p(l.value)?`https://github.com/${l.value}`:l.value)),n=d((()=>a.value?e.value.repoLabel?e.value.repoLabel:null===t.value?"Source":t.value:null));return d((()=>a.value&&n.value?[{text:n.value,link:a.value}]:[]))})(),s=d((()=>[...t.value,...a.value,...n.value]));return(e,l)=>f(s).length?(g(),C("nav",Re,[(g(!0),C(B,null,E(f(s),(e=>(g(),C("div",{key:e.text,class:"navbar-links-item"},[e.children?(g(),k(je,{key:0,item:e},null,8,["item"])):(g(),k(oe,{key:1,item:e},null,8,["item"]))])))),128))])):M("",!0)}});const Pe=["title"],Be={class:"icon",focusable:"false",viewBox:"0 0 32 32"},Ee=[G('',9)],_e={class:"icon",focusable:"false",viewBox:"0 0 32 32"},De=[P("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)];var Ne=i({setup(e){const l=W(),t=Y(),a=()=>{t.value=!t.value};return(e,n)=>(g(),C("button",{class:"toggle-dark-button",title:f(l).toggleDarkMode,onClick:a},[A((g(),C("svg",Be,Ee,512)),[[F,!f(t)]]),A((g(),C("svg",_e,De,512)),[[F,f(t)]])],8,Pe))}});const Se=["title"],qe=[P("div",{class:"icon","aria-hidden":"true"},[P("span"),P("span"),P("span")],-1)];var Ae=i({emits:["toggle"],setup(e){const l=W();return(e,t)=>(g(),C("div",{class:"toggle-sidebar-button",title:f(l).toggleSidebar,"aria-expanded":"false",role:"button",tabindex:"0",onClick:t[0]||(t[0]=l=>e.$emit("toggle"))},qe,8,Se))}});const Fe=["src","alt"];var He=i({emits:["toggle-sidebar"],setup(e){const l=I(),t=j(),a=W(),n=Y(),s=S(null),r=S(null),o=d((()=>a.value.home||l.value)),u=d((()=>n.value&&void 0!==a.value.logoDark?a.value.logoDark:a.value.logo)),i=d((()=>t.value.title)),c=S(0),v=d((()=>c.value?{maxWidth:c.value+"px"}:{})),p=d((()=>a.value.darkMode));function h(e,l){var t,a,n;const s=null==(n=null==(a=null==(t=null==e?void 0:e.ownerDocument)?void 0:t.defaultView)?void 0:a.getComputedStyle(e,null))?void 0:n[l],r=Number.parseInt(s,10);return Number.isNaN(r)?0:r}return J((()=>{const e=h(s.value,"paddingLeft")+h(s.value,"paddingRight"),l=()=>{var l;window.innerWidth<=719?c.value=0:c.value=s.value.offsetWidth-e-((null==(l=r.value)?void 0:l.offsetWidth)||0)};l(),window.addEventListener("resize",l,!1),window.addEventListener("orientationchange",l,!1)})),(e,l)=>{const t=b("RouterLink"),a=b("NavbarSearch");return g(),C("header",{ref:(e,l)=>{l.navbar=e,s.value=e},class:"navbar"},[D(Ae,{onToggle:l[0]||(l[0]=l=>e.$emit("toggle-sidebar"))}),P("span",{ref:(e,l)=>{l.siteBrand=e,r.value=e}},[D(t,{to:f(o)},{default:y((()=>[f(u)?(g(),C("img",{key:0,class:"logo",src:f(R)(f(u)),alt:f(i)},null,8,Fe)):M("",!0),f(i)?(g(),C("span",{key:1,class:_(["site-name",{"can-hide":f(u)}])},L(f(i)),3)):M("",!0)])),_:1},8,["to"])],512),P("div",{class:"navbar-links-wrapper",style:K(f(v))},[x(e.$slots,"before"),D(ze,{class:"can-hide"}),x(e.$slots,"after"),f(p)?(g(),k(Ne,{key:0})):M("",!0),D(a)],4)],512)}}});const Ie={class:"page-meta"},We={key:0,class:"meta-item edit-link"},Ue={key:1,class:"meta-item last-updated"},Ve={class:"meta-item-label"},Xe={class:"meta-item-info"},Ye={key:2,class:"meta-item contributors"},Ge={class:"meta-item-label"},Je={class:"meta-item-info"},Ke=["title"],Qe=w(", ");var Ze=i({setup(e){const l=W(),t=(()=>{const e=W(),l=Z(),t=O();return d((()=>{var a,n;if(!(null==(n=null!=(a=t.value.editLink)?a:e.value.editLink)||n))return null;const{repo:s,docsRepo:r=s,docsBranch:o="main",docsDir:u="",editLinkText:i}=e.value;if(!r)return null;const c=Q({docsRepo:r,docsBranch:o,docsDir:u,filePathRelative:l.value.filePathRelative,editLinkPattern:e.value.editLinkPattern});return c?{text:null!=i?i:"Edit this page",link:c}:null}))})(),a=(()=>{const e=j(),l=W(),t=Z(),a=O();return d((()=>{var n,s,r,o;if(!(null==(s=null!=(n=a.value.lastUpdated)?n:l.value.lastUpdated)||s))return null;if(!(null==(r=t.value.git)?void 0:r.updatedTime))return null;return new Date(null==(o=t.value.git)?void 0:o.updatedTime).toLocaleString(e.value.lang)}))})(),n=(()=>{const e=W(),l=Z(),t=O();return d((()=>{var a,n,s,r;return(null==(n=null!=(a=t.value.contributors)?a:e.value.contributors)||n)&&null!=(r=null==(s=l.value.git)?void 0:s.contributors)?r:null}))})();return(e,s)=>(g(),C("footer",Ie,[f(t)?(g(),C("div",We,[D(oe,{class:"meta-item-label",item:f(t)},null,8,["item"])])):M("",!0),f(a)?(g(),C("div",Ue,[P("span",Ve,L(f(l).lastUpdatedText)+": ",1),P("span",Xe,L(f(a)),1)])):M("",!0),f(n)&&f(n).length?(g(),C("div",Ye,[P("span",Ge,L(f(l).contributorsText)+": ",1),P("span",Je,[(g(!0),C(B,null,E(f(n),((e,l)=>(g(),C(B,{key:l},[P("span",{class:"contributor",title:`email: ${e.email}`},L(e.name),9,Ke),l!==f(n).length-1?(g(),C(B,{key:0},[Qe],64)):M("",!0)],64)))),128))])])):M("",!0)]))}});const el={key:0,class:"page-nav"},ll={class:"inner"},tl={key:0,class:"prev"},al=w(" ← "),nl={key:1,class:"next"},sl=w(" → ");var rl=i({setup(e){const l=e=>!1===e?null:V(e)?X(e):!!le(e)&&e,t=(e,l,a)=>{const n=e.findIndex((e=>e.link===l));if(-1!==n){const l=e[n+a];return(null==l?void 0:l.link)?l:null}for(const s of e)if(s.children){const e=t(s.children,l,a);if(e)return e}return null},a=O(),n=ee(),s=c(),r=d((()=>{const e=l(a.value.prev);return!1!==e?e:t(n.value,s.path,-1)})),o=d((()=>{const e=l(a.value.next);return!1!==e?e:t(n.value,s.path,1)}));return(e,l)=>f(r)||f(o)?(g(),C("nav",el,[P("p",ll,[f(r)?(g(),C("span",tl,[al,D(oe,{item:f(r)},null,8,["item"])])):M("",!0),f(o)?(g(),C("span",nl,[D(oe,{item:f(o)},null,8,["item"]),sl])):M("",!0)])])):M("",!0)}});const ol={class:"page"},ul={class:"theme-default-content"};var il=i({setup:e=>(e,l)=>{const t=b("Content");return g(),C("main",ol,[x(e.$slots,"top"),P("div",ul,[D(t)]),D(Ze),D(rl),x(e.$slots,"bottom")])}});const cl=e=>decodeURI(e).replace(/#.*$/,"").replace(/(index)?\.(md|html)$/,""),vl=(e,l)=>!!((e,l)=>void 0!==l&&(e.hash===l||cl(e.path)===cl(l)))(e,l.link)||!!l.children&&l.children.some((l=>vl(e,l))),dl=(e,l)=>e.link?te(oe,u(o({},l),{item:e})):te("p",l,e.text),pl=(e,l)=>{var t;return(null===(t=e.children)||void 0===t?void 0:t.length)?te("ul",{class:{"sidebar-sub-items":l>0}},e.children.map((e=>te("li",te(hl,{item:e,depth:l+1}))))):null},hl=({item:e,depth:l=0})=>{const t=c(),a=vl(t,e);return[dl(e,{class:{"sidebar-heading":0===l,"sidebar-item":!0,active:a}}),pl(e,l)]};hl.displayName="SidebarChild",hl.props={item:{type:Object,required:!0},depth:{type:Number,required:!1}};const ml={class:"sidebar"},bl={class:"sidebar-links"};var fl=i({setup(e){const l=ee();return(e,t)=>(g(),C("aside",ml,[D(ze),x(e.$slots,"top"),P("ul",bl,[(g(!0),C(B,null,E(f(l),(e=>(g(),k(f(hl),{key:e.link||e.text,item:e},null,8,["item"])))),128))]),x(e.$slots,"bottom")]))}}),gl=i({setup(e){const l=Z(),t=O(),a=W(),n=d((()=>!1!==t.value.navbar&&!1!==a.value.navbar)),s=ee(),r=S(!1),o=e=>{r.value="boolean"==typeof e?e:!r.value},u={x:0,y:0},i=e=>{u.x=e.changedTouches[0].clientX,u.y=e.changedTouches[0].clientY},c=e=>{const l=e.changedTouches[0].clientX-u.x,t=e.changedTouches[0].clientY-u.y;Math.abs(l)>Math.abs(t)&&Math.abs(l)>40&&(l>0&&u.x<=80?o(!0):o(!1))},v=d((()=>[{"no-navbar":!n.value,"no-sidebar":!s.value.length,"sidebar-open":r.value},t.value.pageClass]));let p;J((()=>{const e=H();p=e.afterEach((()=>{o(!1)}))})),ae((()=>{p()}));const h=ne(),m=h.resolve,b=h.pending;return(e,a)=>(g(),C("div",{class:_(["theme-container",f(v)]),onTouchstart:i,onTouchend:c},[f(n)?(g(),k(He,{key:0,onToggleSidebar:o},{before:y((()=>[x(e.$slots,"navbar-before")])),after:y((()=>[x(e.$slots,"navbar-after")])),_:3})):M("",!0),P("div",{class:"sidebar-mask",onClick:a[0]||(a[0]=e=>o(!1))}),D(fl,null,{top:y((()=>[x(e.$slots,"sidebar-top")])),bottom:y((()=>[x(e.$slots,"sidebar-bottom")])),_:3}),x(e.$slots,"page",{},(()=>[f(t).home?(g(),k(ge,{key:0})):(g(),k(N,{key:1,name:"fade-slide-y",mode:"out-in",onBeforeEnter:f(m),onBeforeLeave:f(b)},{default:y((()=>[D(il,{key:f(l).path},{top:y((()=>[x(e.$slots,"page-top")])),bottom:y((()=>[x(e.$slots,"page-bottom")])),_:3})])),_:3},8,["onBeforeEnter","onBeforeLeave"]))]))],34))}});export default gl; +var e=Object.defineProperty,l=Object.defineProperties,a=Object.getOwnPropertyDescriptors,t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,s=Object.prototype.propertyIsEnumerable,r=(l,a,t)=>a in l?e(l,a,{enumerable:!0,configurable:!0,writable:!0,value:t}):l[a]=t,o=(e,l)=>{for(var a in l||(l={}))n.call(l,a)&&r(e,a,l[a]);if(t)for(var a of t(l))s.call(l,a)&&r(e,a,l[a]);return e},u=(e,t)=>l(e,a(t));"undefined"!=typeof require&&require;import{f as i,i as c,j as v,k as d,l as p,m as h,n as m,r as b,h as f,o as g,p as k,w as y,q as x,e as w,t as L,s as $,c as C,v as M,x as T,y as O,z as j,A as R,B as z,a as P,F as B,C as E,D as _,b as D,T as N,E as S,G as q,H as A,I as F,J as H,u as I,g as W,K as U,L as V,M as X,N as Y,d as G,O as J,P as K,Q,R as Z,S as ee,U as le,V as ae,W as te,X as ne}from"./app.48111a85.js";const se=["href","rel","target","aria-label"],re=i({inheritAttrs:!1});var oe=i(u(o({},re),{props:{item:{type:Object,required:!0}},setup:function(e){const l=e,a=c(),t=T(),{item:n}=v(l),s=d((()=>p(n.value.link))),r=d((()=>h(n.value.link)||m(n.value.link))),o=d((()=>{if(!r.value)return n.value.target?n.value.target:s.value?"_blank":void 0})),u=d((()=>"_blank"===o.value)),i=d((()=>!s.value&&!r.value&&!u.value)),O=d((()=>{if(!r.value)return n.value.rel?n.value.rel:u.value?"noopener noreferrer":void 0})),j=d((()=>n.value.ariaLabel||n.value.text)),R=d((()=>{const e=Object.keys(t.value.locales);return e.length?!e.some((e=>e===n.value.link)):"/"!==n.value.link})),z=d((()=>!!R.value&&a.path.startsWith(n.value.link))),P=d((()=>!!i.value&&(n.value.activeMatch?new RegExp(n.value.activeMatch).test(a.path):z.value)));return(e,l)=>{const a=b("RouterLink"),t=b("OutboundLink");return f(i)?(g(),k(a,$({key:0,class:["nav-link",{"router-link-active":f(P)}],to:f(n).link,"aria-label":f(j)},e.$attrs),{default:y((()=>[x(e.$slots,"before"),w(" "+L(f(n).text)+" ",1),x(e.$slots,"after")])),_:3},16,["class","to","aria-label"])):(g(),C("a",$({key:1,class:"nav-link external",href:f(n).link,rel:f(O),target:f(o),"aria-label":f(j)},e.$attrs),[x(e.$slots,"before"),w(" "+L(f(n).text)+" ",1),f(u)?(g(),k(t,{key:0})):M("",!0),x(e.$slots,"after")],16,se))}}}));const ue=["aria-labelledby"],ie={class:"hero"},ce=["src","alt"],ve={key:1,id:"main-title"},de={key:2,class:"description"},pe={key:3,class:"actions"},he={key:0,class:"features"},me={class:"theme-default-content custom"},be=["innerHTML"],fe=["textContent"];var ge=i({setup(e){const l=O(),a=j(),t=d((()=>l.value.heroImage?R(l.value.heroImage):null)),n=d((()=>null===l.value.heroText?null:l.value.heroText||a.value.title||"Hello")),s=d((()=>l.value.heroAlt||n.value||"hero")),r=d((()=>null===l.value.tagline?null:l.value.tagline||a.value.description||"Welcome to your VuePress site")),o=d((()=>z(l.value.actions)?l.value.actions.map((({text:e,link:l,type:a="primary"})=>({text:e,link:l,type:a}))):[])),u=d((()=>z(l.value.features)?l.value.features:[])),i=d((()=>l.value.footer)),c=d((()=>l.value.footerHtml));return(e,l)=>{const a=b("Content");return g(),C("main",{class:"home","aria-labelledby":f(n)?"main-title":void 0},[P("header",ie,[f(t)?(g(),C("img",{key:0,src:f(t),alt:f(s)},null,8,ce)):M("",!0),f(n)?(g(),C("h1",ve,L(f(n)),1)):M("",!0),f(r)?(g(),C("p",de,L(f(r)),1)):M("",!0),f(o).length?(g(),C("p",pe,[(g(!0),C(B,null,E(f(o),(e=>(g(),k(oe,{key:e.text,class:_(["action-button",[e.type]]),item:e},null,8,["class","item"])))),128))])):M("",!0)]),f(u).length?(g(),C("div",he,[(g(!0),C(B,null,E(f(u),(e=>(g(),C("div",{key:e.title,class:"feature"},[P("h2",null,L(e.title),1),P("p",null,L(e.details),1)])))),128))])):M("",!0),P("div",me,[D(a)]),f(i)?(g(),C(B,{key:1},[f(c)?(g(),C("div",{key:0,class:"footer",innerHTML:f(i)},null,8,be)):(g(),C("div",{key:1,class:"footer",textContent:L(f(i))},null,8,fe))],64)):M("",!0)],8,ue)}}}),ke=i({setup(e){const l=e=>{e.style.height=e.scrollHeight+"px"},a=e=>{e.style.height=""};return(e,t)=>(g(),k(N,{name:"dropdown",onEnter:l,onAfterEnter:a,onBeforeLeave:l},{default:y((()=>[x(e.$slots,"default")])),_:3}))}});const ye=["aria-label"],xe={class:"title"},we=P("span",{class:"arrow down"},null,-1),Le=["aria-label"],$e={class:"title"},Ce={class:"nav-dropdown"},Me={class:"dropdown-subtitle"},Te={key:1},Oe={class:"dropdown-subitem-wrapper"};var je=i({props:{item:{type:Object,required:!0}},setup(e){const l=e,{item:a}=v(l),t=d((()=>a.value.ariaLabel||a.value.text)),n=S(!1),s=c();q((()=>s.path),(()=>{n.value=!1}));const r=e=>{const l=0===e.detail;n.value=!!l&&!n.value},o=(e,l)=>l[l.length-1]===e;return(e,l)=>(g(),C("div",{class:_(["dropdown-wrapper",{open:n.value}])},[P("button",{class:"dropdown-title",type:"button","aria-label":f(t),onClick:r},[P("span",xe,L(f(a).text),1),we],8,ye),P("button",{class:"mobile-dropdown-title",type:"button","aria-label":f(t),onClick:l[0]||(l[0]=e=>n.value=!n.value)},[P("span",$e,L(f(a).text),1),P("span",{class:_(["arrow",n.value?"down":"right"])},null,2)],8,Le),D(ke,null,{default:y((()=>[A(P("ul",Ce,[(g(!0),C(B,null,E(f(a).children,((e,l)=>(g(),C("li",{key:e.link||l,class:"dropdown-item"},[e.children?(g(),C(B,{key:0},[P("h4",Me,[e.link?(g(),k(oe,{key:0,item:e,onFocusout:l=>o(e,f(a).children)&&0===e.children.length&&(n.value=!1)},null,8,["item","onFocusout"])):(g(),C("span",Te,L(e.text),1))]),P("ul",Oe,[(g(!0),C(B,null,E(e.children,(l=>(g(),C("li",{key:l.link,class:"dropdown-subitem"},[D(oe,{item:l,onFocusout:t=>o(l,e.children)&&o(e,f(a).children)&&(n.value=!1)},null,8,["item","onFocusout"])])))),128))])],64)):(g(),k(oe,{key:1,item:e,onFocusout:l=>o(e,f(a).children)&&(n.value=!1)},null,8,["item","onFocusout"]))])))),128))],512),[[F,n.value]])])),_:1})],2))}});const Re={key:0,class:"navbar-links"};var ze=i({setup(e){const l=e=>V(e)?X(e):e.children?u(o({},e),{children:e.children.map(l)}):e,a=(()=>{const e=W();return d((()=>(e.value.navbar||[]).map(l)))})(),t=(()=>{const e=H(),l=I(),a=j(),t=W();return d((()=>{var n,s;const r=Object.keys(a.value.locales);if(r.length<2)return[];const o=e.currentRoute.value.path,u=e.currentRoute.value.fullPath;return[{text:null!=(n=t.value.selectLanguageText)?n:"unkown language",ariaLabel:null!=(s=t.value.selectLanguageAriaLabel)?s:"unkown language",children:r.map((n=>{var s,r,i,c,v,d;const p=null!=(r=null==(s=a.value.locales)?void 0:s[n])?r:{},h=null!=(c=null==(i=t.value.locales)?void 0:i[n])?c:{},m=`${p.lang}`,b=null!=(v=h.selectLanguageName)?v:m;let f;if(m===a.value.lang)f=u;else{const a=o.replace(l.value,n);f=e.getRoutes().some((e=>e.path===a))?a:null!=(d=h.home)?d:n}return{text:b,link:f}}))}]}))})(),n=(()=>{const e=W(),l=d((()=>e.value.repo)),a=d((()=>l.value?U(l.value):null)),t=d((()=>l.value&&!p(l.value)?`https://github.com/${l.value}`:l.value)),n=d((()=>t.value?e.value.repoLabel?e.value.repoLabel:null===a.value?"Source":a.value:null));return d((()=>t.value&&n.value?[{text:n.value,link:t.value}]:[]))})(),s=d((()=>[...a.value,...t.value,...n.value]));return(e,l)=>f(s).length?(g(),C("nav",Re,[(g(!0),C(B,null,E(f(s),(e=>(g(),C("div",{key:e.text,class:"navbar-links-item"},[e.children?(g(),k(je,{key:0,item:e},null,8,["item"])):(g(),k(oe,{key:1,item:e},null,8,["item"]))])))),128))])):M("",!0)}});const Pe=["title"],Be={class:"icon",focusable:"false",viewBox:"0 0 32 32"},Ee=[G('',9)],_e={class:"icon",focusable:"false",viewBox:"0 0 32 32"},De=[P("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)];var Ne=i({setup(e){const l=W(),a=Y(),t=()=>{a.value=!a.value};return(e,n)=>(g(),C("button",{class:"toggle-dark-button",title:f(l).toggleDarkMode,onClick:t},[A((g(),C("svg",Be,Ee,512)),[[F,!f(a)]]),A((g(),C("svg",_e,De,512)),[[F,f(a)]])],8,Pe))}});const Se=["title"],qe=[P("div",{class:"icon","aria-hidden":"true"},[P("span"),P("span"),P("span")],-1)];var Ae=i({emits:["toggle"],setup(e){const l=W();return(e,a)=>(g(),C("div",{class:"toggle-sidebar-button",title:f(l).toggleSidebar,"aria-expanded":"false",role:"button",tabindex:"0",onClick:a[0]||(a[0]=l=>e.$emit("toggle"))},qe,8,Se))}});const Fe=["src","alt"];var He=i({emits:["toggle-sidebar"],setup(e){const l=I(),a=j(),t=W(),n=Y(),s=S(null),r=S(null),o=d((()=>t.value.home||l.value)),u=d((()=>n.value&&void 0!==t.value.logoDark?t.value.logoDark:t.value.logo)),i=d((()=>a.value.title)),c=S(0),v=d((()=>c.value?{maxWidth:c.value+"px"}:{})),p=d((()=>t.value.darkMode));function h(e,l){var a,t,n;const s=null==(n=null==(t=null==(a=null==e?void 0:e.ownerDocument)?void 0:a.defaultView)?void 0:t.getComputedStyle(e,null))?void 0:n[l],r=Number.parseInt(s,10);return Number.isNaN(r)?0:r}return J((()=>{const e=h(s.value,"paddingLeft")+h(s.value,"paddingRight"),l=()=>{var l;window.innerWidth<=719?c.value=0:c.value=s.value.offsetWidth-e-((null==(l=r.value)?void 0:l.offsetWidth)||0)};l(),window.addEventListener("resize",l,!1),window.addEventListener("orientationchange",l,!1)})),(e,l)=>{const a=b("RouterLink"),t=b("NavbarSearch");return g(),C("header",{ref:(e,l)=>{l.navbar=e,s.value=e},class:"navbar"},[D(Ae,{onToggle:l[0]||(l[0]=l=>e.$emit("toggle-sidebar"))}),P("span",{ref:(e,l)=>{l.siteBrand=e,r.value=e}},[D(a,{to:f(o)},{default:y((()=>[f(u)?(g(),C("img",{key:0,class:"logo",src:f(R)(f(u)),alt:f(i)},null,8,Fe)):M("",!0),f(i)?(g(),C("span",{key:1,class:_(["site-name",{"can-hide":f(u)}])},L(f(i)),3)):M("",!0)])),_:1},8,["to"])],512),P("div",{class:"navbar-links-wrapper",style:K(f(v))},[x(e.$slots,"before"),D(ze,{class:"can-hide"}),x(e.$slots,"after"),f(p)?(g(),k(Ne,{key:0})):M("",!0),D(t)],4)],512)}}});const Ie={class:"page-meta"},We={key:0,class:"meta-item edit-link"},Ue={key:1,class:"meta-item last-updated"},Ve={class:"meta-item-label"},Xe={class:"meta-item-info"},Ye={key:2,class:"meta-item contributors"},Ge={class:"meta-item-label"},Je={class:"meta-item-info"},Ke=["title"],Qe=w(", ");var Ze=i({setup(e){const l=W(),a=(()=>{const e=W(),l=Z(),a=O();return d((()=>{var t,n;if(!(null==(n=null!=(t=a.value.editLink)?t:e.value.editLink)||n))return null;const{repo:s,docsRepo:r=s,docsBranch:o="main",docsDir:u="",editLinkText:i}=e.value;if(!r)return null;const c=Q({docsRepo:r,docsBranch:o,docsDir:u,filePathRelative:l.value.filePathRelative,editLinkPattern:e.value.editLinkPattern});return c?{text:null!=i?i:"Edit this page",link:c}:null}))})(),t=(()=>{const e=j(),l=W(),a=Z(),t=O();return d((()=>{var n,s,r,o;if(!(null==(s=null!=(n=t.value.lastUpdated)?n:l.value.lastUpdated)||s))return null;if(!(null==(r=a.value.git)?void 0:r.updatedTime))return null;return new Date(null==(o=a.value.git)?void 0:o.updatedTime).toLocaleString(e.value.lang)}))})(),n=(()=>{const e=W(),l=Z(),a=O();return d((()=>{var t,n,s,r;return(null==(n=null!=(t=a.value.contributors)?t:e.value.contributors)||n)&&null!=(r=null==(s=l.value.git)?void 0:s.contributors)?r:null}))})();return(e,s)=>(g(),C("footer",Ie,[f(a)?(g(),C("div",We,[D(oe,{class:"meta-item-label",item:f(a)},null,8,["item"])])):M("",!0),f(t)?(g(),C("div",Ue,[P("span",Ve,L(f(l).lastUpdatedText)+": ",1),P("span",Xe,L(f(t)),1)])):M("",!0),f(n)&&f(n).length?(g(),C("div",Ye,[P("span",Ge,L(f(l).contributorsText)+": ",1),P("span",Je,[(g(!0),C(B,null,E(f(n),((e,l)=>(g(),C(B,{key:l},[P("span",{class:"contributor",title:`email: ${e.email}`},L(e.name),9,Ke),l!==f(n).length-1?(g(),C(B,{key:0},[Qe],64)):M("",!0)],64)))),128))])])):M("",!0)]))}});const el={key:0,class:"page-nav"},ll={class:"inner"},al={key:0,class:"prev"},tl=w(" ← "),nl={key:1,class:"next"},sl=w(" → ");var rl=i({setup(e){const l=e=>!1===e?null:V(e)?X(e):!!le(e)&&e,a=(e,l,t)=>{const n=e.findIndex((e=>e.link===l));if(-1!==n){const l=e[n+t];return(null==l?void 0:l.link)?l:null}for(const s of e)if(s.children){const e=a(s.children,l,t);if(e)return e}return null},t=O(),n=ee(),s=c(),r=d((()=>{const e=l(t.value.prev);return!1!==e?e:a(n.value,s.path,-1)})),o=d((()=>{const e=l(t.value.next);return!1!==e?e:a(n.value,s.path,1)}));return(e,l)=>f(r)||f(o)?(g(),C("nav",el,[P("p",ll,[f(r)?(g(),C("span",al,[tl,D(oe,{item:f(r)},null,8,["item"])])):M("",!0),f(o)?(g(),C("span",nl,[D(oe,{item:f(o)},null,8,["item"]),sl])):M("",!0)])])):M("",!0)}});const ol={class:"page"},ul={class:"theme-default-content"};var il=i({setup:e=>(e,l)=>{const a=b("Content");return g(),C("main",ol,[x(e.$slots,"top"),P("div",ul,[D(a)]),D(Ze),D(rl),x(e.$slots,"bottom")])}});const cl=e=>decodeURI(e).replace(/#.*$/,"").replace(/(index)?\.(md|html)$/,""),vl=(e,l)=>!!((e,l)=>void 0!==l&&(e.hash===l||cl(e.path)===cl(l)))(e,l.link)||!!l.children&&l.children.some((l=>vl(e,l))),dl=(e,l)=>e.link?ae(oe,u(o({},l),{item:e})):ae("p",l,e.text),pl=(e,l)=>{var a;return(null===(a=e.children)||void 0===a?void 0:a.length)?ae("ul",{class:{"sidebar-sub-items":l>0}},e.children.map((e=>ae("li",ae(hl,{item:e,depth:l+1}))))):null},hl=({item:e,depth:l=0})=>{const a=c(),t=vl(a,e);return[dl(e,{class:{"sidebar-heading":0===l,"sidebar-item":!0,active:t}}),pl(e,l)]};hl.displayName="SidebarChild",hl.props={item:{type:Object,required:!0},depth:{type:Number,required:!1}};const ml={class:"sidebar"},bl={class:"sidebar-links"};var fl=i({setup(e){const l=ee();return(e,a)=>(g(),C("aside",ml,[D(ze),x(e.$slots,"top"),P("ul",bl,[(g(!0),C(B,null,E(f(l),(e=>(g(),k(f(hl),{key:e.link||e.text,item:e},null,8,["item"])))),128))]),x(e.$slots,"bottom")]))}}),gl=i({setup(e){const l=Z(),a=O(),t=W(),n=d((()=>!1!==a.value.navbar&&!1!==t.value.navbar)),s=ee(),r=S(!1),o=e=>{r.value="boolean"==typeof e?e:!r.value},u={x:0,y:0},i=e=>{u.x=e.changedTouches[0].clientX,u.y=e.changedTouches[0].clientY},c=e=>{const l=e.changedTouches[0].clientX-u.x,a=e.changedTouches[0].clientY-u.y;Math.abs(l)>Math.abs(a)&&Math.abs(l)>40&&(l>0&&u.x<=80?o(!0):o(!1))},v=d((()=>[{"no-navbar":!n.value,"no-sidebar":!s.value.length,"sidebar-open":r.value},a.value.pageClass]));let p;J((()=>{const e=H();p=e.afterEach((()=>{o(!1)}))})),te((()=>{p()}));const h=ne(),m=h.resolve,b=h.pending;return(e,t)=>(g(),C("div",{class:_(["theme-container",f(v)]),onTouchstart:i,onTouchend:c},[f(n)?(g(),k(He,{key:0,onToggleSidebar:o},{before:y((()=>[x(e.$slots,"navbar-before")])),after:y((()=>[x(e.$slots,"navbar-after")])),_:3})):M("",!0),P("div",{class:"sidebar-mask",onClick:t[0]||(t[0]=e=>o(!1))}),D(fl,null,{top:y((()=>[x(e.$slots,"sidebar-top")])),bottom:y((()=>[x(e.$slots,"sidebar-bottom")])),_:3}),x(e.$slots,"page",{},(()=>[f(a).home?(g(),k(ge,{key:0})):(g(),k(N,{key:1,name:"fade-slide-y",mode:"out-in",onBeforeEnter:f(m),onBeforeLeave:f(b)},{default:y((()=>[D(il,{key:f(l).path},{top:y((()=>[x(e.$slots,"page-top")])),bottom:y((()=>[x(e.$slots,"page-bottom")])),_:3})])),_:3},8,["onBeforeEnter","onBeforeLeave"]))]))],34))}});export default gl; diff --git a/assets/api.html.620afbc9.js b/assets/api.html.a23d7a18.js similarity index 99% rename from assets/api.html.620afbc9.js rename to assets/api.html.a23d7a18.js index a160c6dad..51235a2bb 100644 --- a/assets/api.html.620afbc9.js +++ b/assets/api.html.a23d7a18.js @@ -1 +1 @@ -import{r as n,o as a,c as s,a as e,b as t,w as o,F as p,e as r,d as i}from"./app.755d843f.js";const l={},c=e("h1",{id:"api-interface",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#api-interface","aria-hidden":"true"},"#"),r(" API Interface")],-1),u=r("API interface configuration provides a set of APIs based on "),d={href:"https://grpc.io/",target:"_blank",rel:"noopener noreferrer"},b=r("gRPC"),h=r(" for remote invocation."),g=r("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 "),k=r("routing rule configuration"),m=r("."),f=i('

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.

{\n  "api": {\n    "tag": "api",\n    "services": ["HandlerService", "LoggerService", "StatsService"]\n  }\n}\n
1
2
3
4
5
6

tag: string

Outbound proxy identifier.

services: [string]

List of enabled APIs, optional values can be found in Supported API List.

An api inbound can be added to the inbounds configuration.

"inbounds": [\n  {\n    "listen": "127.0.0.1",\n    "port": 10085,\n    "protocol": "dokodemo-door",\n    "settings": {\n      "address": "127.0.0.1"\n    },\n    "tag": "api"\n  }\n]\n
1
2
3
4
5
6
7
8
9
10
11

Add routing rules for the api inbound in the routing configuration.

"routing": {\n  "rules": [\n    {\n      "inboundTag": [\n        "api"\n      ],\n      "outboundTag": "api",\n      "type": "field"\n    }\n  ]\n}\n
1
2
3
4
5
6
7
8
9
10
11

Supported API List

HandlerService

APIs that modify the inbound and outbound proxies, with the following available functions:

LoggerService

Supports restarting the built-in logger, which can be used in conjunction with logrotate to perform operations on log files.

StatsService

',21),q=r("Built-in data statistics service, see "),v=r("Statistics Information"),y=r(" for details."),x=i('

ReflectionService

Supports gRPC clients to obtain the list of APIs from the server.

$ grpcurl -plaintext localhost:10085 list\ngrpc.reflection.v1alpha.ServerReflection\nv2ray.core.app.proxyman.command.HandlerService\nv2ray.core.app.stats.command.StatsService\nxray.app.proxyman.command.HandlerService\nxray.app.stats.command.StatsService\n
1
2
3
4
5
6

API Calling Example

',4),S={href:"https://github.com/XTLS/Xray-API-documents",target:"_blank",rel:"noopener noreferrer"},A=r("Xray-API-documents"),j=r(" @crossfw");l.render=function(r,i){const l=n("OutboundLink"),P=n("RouterLink");return a(),s(p,null,[c,e("p",null,[u,e("a",d,[b,t(l)]),h]),e("p",null,[g,t(P,{to:"/en/config/routing.html"},{default:o((()=>[k])),_:1}),m]),f,e("p",null,[q,t(P,{to:"/en/config/stats.html"},{default:o((()=>[v])),_:1}),y]),x,e("p",null,[e("a",S,[A,t(l)]),j])],64)};export default l; +import{r as n,o as a,c as s,a as e,b as t,w as o,F as p,e as r,d as i}from"./app.48111a85.js";const l={},c=e("h1",{id:"api-interface",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#api-interface","aria-hidden":"true"},"#"),r(" API Interface")],-1),u=r("API interface configuration provides a set of APIs based on "),d={href:"https://grpc.io/",target:"_blank",rel:"noopener noreferrer"},b=r("gRPC"),h=r(" for remote invocation."),g=r("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 "),k=r("routing rule configuration"),m=r("."),f=i('

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.

{\n  "api": {\n    "tag": "api",\n    "services": ["HandlerService", "LoggerService", "StatsService"]\n  }\n}\n
1
2
3
4
5
6

tag: string

Outbound proxy identifier.

services: [string]

List of enabled APIs, optional values can be found in Supported API List.

An api inbound can be added to the inbounds configuration.

"inbounds": [\n  {\n    "listen": "127.0.0.1",\n    "port": 10085,\n    "protocol": "dokodemo-door",\n    "settings": {\n      "address": "127.0.0.1"\n    },\n    "tag": "api"\n  }\n]\n
1
2
3
4
5
6
7
8
9
10
11

Add routing rules for the api inbound in the routing configuration.

"routing": {\n  "rules": [\n    {\n      "inboundTag": [\n        "api"\n      ],\n      "outboundTag": "api",\n      "type": "field"\n    }\n  ]\n}\n
1
2
3
4
5
6
7
8
9
10
11

Supported API List

HandlerService

APIs that modify the inbound and outbound proxies, with the following available functions:

LoggerService

Supports restarting the built-in logger, which can be used in conjunction with logrotate to perform operations on log files.

StatsService

',21),q=r("Built-in data statistics service, see "),v=r("Statistics Information"),y=r(" for details."),x=i('

ReflectionService

Supports gRPC clients to obtain the list of APIs from the server.

$ grpcurl -plaintext localhost:10085 list\ngrpc.reflection.v1alpha.ServerReflection\nv2ray.core.app.proxyman.command.HandlerService\nv2ray.core.app.stats.command.StatsService\nxray.app.proxyman.command.HandlerService\nxray.app.stats.command.StatsService\n
1
2
3
4
5
6

API Calling Example

',4),S={href:"https://github.com/XTLS/Xray-API-documents",target:"_blank",rel:"noopener noreferrer"},A=r("Xray-API-documents"),j=r(" @crossfw");l.render=function(r,i){const l=n("OutboundLink"),P=n("RouterLink");return a(),s(p,null,[c,e("p",null,[u,e("a",d,[b,t(l)]),h]),e("p",null,[g,t(P,{to:"/en/config/routing.html"},{default:o((()=>[k])),_:1}),m]),f,e("p",null,[q,t(P,{to:"/en/config/stats.html"},{default:o((()=>[v])),_:1}),y]),x,e("p",null,[e("a",S,[A,t(l)]),j])],64)};export default l; diff --git a/assets/api.html.5f9fa31d.js b/assets/api.html.dd27f4a2.js similarity index 99% rename from assets/api.html.5f9fa31d.js rename to assets/api.html.dd27f4a2.js index 46026a985..4a604b8be 100644 --- a/assets/api.html.5f9fa31d.js +++ b/assets/api.html.dd27f4a2.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as p,w as t,F as o,e as r,d as c}from"./app.755d843f.js";const l={},i=e("h1",{id:"api-接口",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#api-接口","aria-hidden":"true"},"#"),r(" API 接口")],-1),u=r("API 接口配置提供了一些基于 "),d={href:"https://grpc.io/",target:"_blank",rel:"noopener noreferrer"},b=r("gRPC"),k=r("的 API 接口供远程调用。"),h=r("可以通过 api 配置模块开启接口. 当 api 配置开启时,Xray 会自建一个出站代理,须手动将所有的 API 入站连接通过 "),m=r("路由规则配置"),g=r(" 指向这一出站代理。"),q=c('

请参考本节中的 相关配置

注意

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

ApiObject

ApiObject 对应配置文件的 api 项。

{\n  "api": {\n    "tag": "api",\n    "services": ["HandlerService", "LoggerService", "StatsService"]\n  }\n}\n
1
2
3
4
5
6

tag: string

出站代理标识。

services: [string]

开启的 API 列表,可选的值见 API 列表

相关配置

可以在 inbounds 配置中增加一个 api 的 inbound

"inbounds": [\n  {\n    "listen": "127.0.0.1",\n    "port": 10085,\n    "protocol": "dokodemo-door",\n    "settings": {\n      "address": "127.0.0.1"\n    },\n    "tag": "api"\n  }\n]\n
1
2
3
4
5
6
7
8
9
10
11

在路由配置中增加针对 api inbound 的路由规则

"routing": {\n  "rules": [\n    {\n      "inboundTag": [\n        "api"\n      ],\n      "outboundTag": "api",\n      "type": "field"\n    }\n  ]\n}\n
1
2
3
4
5
6
7
8
9
10
11

支持的 API 列表

HandlerService

一些对于入站出站代理进行修改的 API,可用的功能如下:

LoggerService

支持对内置 Logger 的重启,可配合 logrotate 进行一些对日志文件的操作。

StatsService

',21),v=r("内置的数据统计服务,详见 "),f=r("统计信息"),y=r("。"),S=c('

ReflectionService

支持 gRPC 客户端获取服务端的 API 列表。

$ grpcurl -plaintext localhost:10085 list\ngrpc.reflection.v1alpha.ServerReflection\nv2ray.core.app.proxyman.command.HandlerService\nv2ray.core.app.stats.command.StatsService\nxray.app.proxyman.command.HandlerService\nxray.app.stats.command.StatsService\n
1
2
3
4
5
6

API 调用示例

',4),A={href:"https://github.com/XTLS/Xray-API-documents",target:"_blank",rel:"noopener noreferrer"},x=r("Xray-API-documents"),j=r(" @crossfw");l.render=function(r,c){const l=n("OutboundLink"),P=n("RouterLink");return s(),a(o,null,[i,e("p",null,[u,e("a",d,[b,p(l)]),k]),e("p",null,[h,p(P,{to:"/config/routing.html"},{default:t((()=>[m])),_:1}),g]),q,e("p",null,[v,p(P,{to:"/config/stats.html"},{default:t((()=>[f])),_:1}),y]),S,e("p",null,[e("a",A,[x,p(l)]),j])],64)};export default l; +import{r as n,o as s,c as a,a as e,b as p,w as t,F as o,e as r,d as c}from"./app.48111a85.js";const l={},i=e("h1",{id:"api-接口",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#api-接口","aria-hidden":"true"},"#"),r(" API 接口")],-1),u=r("API 接口配置提供了一些基于 "),d={href:"https://grpc.io/",target:"_blank",rel:"noopener noreferrer"},b=r("gRPC"),k=r("的 API 接口供远程调用。"),h=r("可以通过 api 配置模块开启接口. 当 api 配置开启时,Xray 会自建一个出站代理,须手动将所有的 API 入站连接通过 "),m=r("路由规则配置"),g=r(" 指向这一出站代理。"),q=c('

请参考本节中的 相关配置

注意

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

ApiObject

ApiObject 对应配置文件的 api 项。

{\n  "api": {\n    "tag": "api",\n    "services": ["HandlerService", "LoggerService", "StatsService"]\n  }\n}\n
1
2
3
4
5
6

tag: string

出站代理标识。

services: [string]

开启的 API 列表,可选的值见 API 列表

相关配置

可以在 inbounds 配置中增加一个 api 的 inbound

"inbounds": [\n  {\n    "listen": "127.0.0.1",\n    "port": 10085,\n    "protocol": "dokodemo-door",\n    "settings": {\n      "address": "127.0.0.1"\n    },\n    "tag": "api"\n  }\n]\n
1
2
3
4
5
6
7
8
9
10
11

在路由配置中增加针对 api inbound 的路由规则

"routing": {\n  "rules": [\n    {\n      "inboundTag": [\n        "api"\n      ],\n      "outboundTag": "api",\n      "type": "field"\n    }\n  ]\n}\n
1
2
3
4
5
6
7
8
9
10
11

支持的 API 列表

HandlerService

一些对于入站出站代理进行修改的 API,可用的功能如下:

LoggerService

支持对内置 Logger 的重启,可配合 logrotate 进行一些对日志文件的操作。

StatsService

',21),v=r("内置的数据统计服务,详见 "),f=r("统计信息"),y=r("。"),S=c('

ReflectionService

支持 gRPC 客户端获取服务端的 API 列表。

$ grpcurl -plaintext localhost:10085 list\ngrpc.reflection.v1alpha.ServerReflection\nv2ray.core.app.proxyman.command.HandlerService\nv2ray.core.app.stats.command.StatsService\nxray.app.proxyman.command.HandlerService\nxray.app.stats.command.StatsService\n
1
2
3
4
5
6

API 调用示例

',4),A={href:"https://github.com/XTLS/Xray-API-documents",target:"_blank",rel:"noopener noreferrer"},x=r("Xray-API-documents"),j=r(" @crossfw");l.render=function(r,c){const l=n("OutboundLink"),P=n("RouterLink");return s(),a(o,null,[i,e("p",null,[u,e("a",d,[b,p(l)]),k]),e("p",null,[h,p(P,{to:"/config/routing.html"},{default:t((()=>[m])),_:1}),g]),q,e("p",null,[v,p(P,{to:"/config/stats.html"},{default:t((()=>[f])),_:1}),y]),S,e("p",null,[e("a",A,[x,p(l)]),j])],64)};export default l; diff --git a/assets/app.755d843f.js b/assets/app.48111a85.js similarity index 95% rename from assets/app.755d843f.js rename to assets/app.48111a85.js index 7e344d286..ab0d80a3f 100644 --- a/assets/app.755d843f.js +++ b/assets/app.48111a85.js @@ -4,7 +4,7 @@ var e=Object.defineProperty,t=Object.defineProperties,l=Object.getOwnPropertyDes * (c) 2021 Eduardo San Martin Morote * @license MIT */ -const gi="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,_i=e=>gi?Symbol(e):"_vr_"+e,bi=_i("rvlm"),yi=_i("rvd"),Ei=_i("r"),xi=_i("rl"),ji=_i("rvl"),Li="undefined"!=typeof window;const Oi=Object.assign;function wi(e,t){const l={};for(const n in t){const o=t[n];l[n]=Array.isArray(o)?o.map(e):e(o)}return l}let Pi=()=>{};const Ti=/\/$/;function ki(e,t,l="/"){let n,o={},i="",r="";const s=t.indexOf("?"),a=t.indexOf("#",s>-1?s:0);return s>-1&&(n=t.slice(0,s),i=t.slice(s+1,a>-1?a:t.length),o=e(i)),a>-1&&(n=n||t.slice(0,a),r=t.slice(a,t.length)),n=function(e,t){if(e.startsWith("/"))return e;if(!e)return t;const l=t.split("/"),n=e.split("/");let o,i,r=l.length-1;for(o=0;oe===t[l])):1===e.length&&e[0]===t}var Vi,Ci,Fi,Ni;function Mi(e){if(!e)if(Li){const t=document.querySelector("base");e=(e=t&&t.getAttribute("href")||"/").replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return"/"!==e[0]&&"#"!==e[0]&&(e="/"+e),e.replace(Ti,"")}(Ci=Vi||(Vi={})).pop="pop",Ci.push="push",(Ni=Fi||(Fi={})).back="back",Ni.forward="forward",Ni.unknown="";const Hi=/^[^#]+#/;function zi(e,t){return e.replace(Hi,"#")+t}const Bi=()=>({left:window.pageXOffset,top:window.pageYOffset});function $i(e){let t;if("el"in e){let l=e.el;const n="string"==typeof l&&l.startsWith("#"),o="string"==typeof l?n?document.getElementById(l.slice(1)):document.querySelector(l):l;if(!o)return;t=function(e,t){const l=document.documentElement.getBoundingClientRect(),n=e.getBoundingClientRect();return{behavior:t.behavior,left:n.left-l.left-(t.left||0),top:n.top-l.top-(t.top||0)}}(o,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(null!=t.left?t.left:window.pageXOffset,null!=t.top?t.top:window.pageYOffset)}function Wi(e,t){return(history.state?history.state.position-t:-1)+e}const Ui=new Map;function qi(e,t){const{pathname:l,search:n,hash:o}=t,i=e.indexOf("#");if(i>-1){let t=o.includes(e.slice(i))?e.slice(i).length:1,l=o.slice(t);return"/"!==l[0]&&(l="/"+l),Ai(l,"")}return Ai(l,e)+n+o}function Xi(e,t,l,n=!1,o=!1){return{back:e,current:t,forward:l,replaced:n,position:window.history.length,scroll:o?Bi():null}}function Gi(e){const{history:t,location:l}=window;let n={value:qi(e,l)},o={value:t.state};function i(n,i,r){const s=e.indexOf("#"),a=s>-1?(l.host&&document.querySelector("base")?e:e.slice(s))+n:location.protocol+"//"+location.host+e+n;try{t[r?"replaceState":"pushState"](i,"",a),o.value=i}catch(c){console.error(c),l[r?"replace":"assign"](a)}}return o.value||i(n.value,{back:null,current:n.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0),{location:n,state:o,push:function(e,l){const r=Oi({},o.value,t.state,{forward:e,scroll:Bi()});i(r.current,r,!0),i(e,Oi({},Xi(n.value,e,null),{position:r.position+1},l),!1),n.value=e},replace:function(e,l){i(e,Oi({},t.state,Xi(o.value.back,e,o.value.forward,!0),l,{position:o.value.position}),!0),n.value=e}}}function Ki(e){return"string"==typeof e||"symbol"==typeof e}const Yi={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},Qi=_i("nf");var Ji,Zi;function er(e,t){return Oi(new Error,{type:e,[Qi]:!0},t)}function tr(e,t){return e instanceof Error&&Qi in e&&(null==t||!!(e.type&t))}(Zi=Ji||(Ji={}))[Zi.aborted=4]="aborted",Zi[Zi.cancelled=8]="cancelled",Zi[Zi.duplicated=16]="duplicated";const lr={sensitive:!1,strict:!1,start:!0,end:!0},nr=/[.+*?^${}()[\]/\\]/g;function or(e,t){let l=0;for(;lt.length?1===t.length&&80===t[0]?1:-1:0}function ir(e,t){let l=0;const n=e.score,o=t.score;for(;l1&&("*"===s||"+"===s)&&t(`A repeatable param (${c}) must be alone in its segment. eg: '/:ids+.`),i.push({type:1,value:c,regexp:d,repeatable:"*"===s||"+"===s,optional:"*"===s||"?"===s})):t("Invalid state to consume buffer"),c="")}function h(){c+=s}for(;a{i(h)}:Pi}function i(e){if(Ki(e)){const t=n.get(e);t&&(n.delete(e),l.splice(l.indexOf(t),1),t.children.forEach(i),t.alias.forEach(i))}else{let t=l.indexOf(e);t>-1&&(l.splice(t,1),e.record.name&&n.delete(e.record.name),e.children.forEach(i),e.alias.forEach(i))}}function r(e){let t=0;for(;t=0;)t++;l.splice(t,0,e),e.record.name&&!ur(e)&&n.set(e.record.name,e)}return t=pr({strict:!1,end:!0,sensitive:!1},t),e.forEach((e=>o(e))),{addRoute:o,resolve:function(e,t){let o,i,r,s={};if("name"in e&&e.name){if(o=n.get(e.name),!o)throw er(1,{location:e});r=o.record.name,s=Oi(function(e,t){let l={};for(let n of t)n in e&&(l[n]=e[n]);return l}(t.params,o.keys.filter((e=>!e.optional)).map((e=>e.name))),e.params),i=o.stringify(s)}else if("path"in e)i=e.path,o=l.find((e=>e.re.test(i))),o&&(s=o.parse(i),r=o.record.name);else{if(o=t.name?n.get(t.name):l.find((e=>e.re.test(t.path))),!o)throw er(1,{location:e,currentLocation:t});r=o.record.name,s=Oi({},t.params,e.params),i=o.stringify(s)}const a=[];let c=o;for(;c;)a.unshift(c.record),c=c.parent;return{name:r,path:i,params:s,matched:a,meta:hr(a)}},removeRoute:i,getRoutes:function(){return l},getRecordMatcher:function(e){return n.get(e)}}}function dr(e){const t={},l=e.props||!1;if("component"in e)t.default=l;else for(let n in e.components)t[n]="boolean"==typeof l?l:l[n];return t}function ur(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function hr(e){return e.reduce(((e,t)=>Oi(e,t.meta)),{})}function pr(e,t){let l={};for(let n in e)l[n]=n in t?t[n]:e[n];return l}const mr=/#/g,vr=/&/g,fr=/\//g,gr=/=/g,_r=/\?/g,br=/\+/g,yr=/%5B/g,Er=/%5D/g,xr=/%5E/g,jr=/%60/g,Lr=/%7B/g,Or=/%7C/g,wr=/%7D/g,Pr=/%20/g;function Tr(e){return encodeURI(""+e).replace(Or,"|").replace(yr,"[").replace(Er,"]")}function kr(e){return Tr(e).replace(br,"%2B").replace(Pr,"+").replace(mr,"%23").replace(vr,"%26").replace(jr,"`").replace(Lr,"{").replace(wr,"}").replace(xr,"^")}function Ar(e){return function(e){return Tr(e).replace(mr,"%23").replace(_r,"%3F")}(e).replace(fr,"%2F")}function Rr(e){try{return decodeURIComponent(""+e)}catch(t){}return""+e}function Dr(e){const t={};if(""===e||"?"===e)return t;const l=("?"===e[0]?e.slice(1):e).split("&");for(let n=0;ne&&kr(e))):[n&&kr(n)]).forEach((e=>{void 0!==e&&(t+=(t.length?"&":"")+l,null!=e&&(t+="="+e))}))}return t}function Sr(e){const t={};for(let l in e){let n=e[l];void 0!==n&&(t[l]=Array.isArray(n)?n.map((e=>null==e?null:""+e)):null==n?n:""+n)}return t}function Vr(){let e=[];return{add:function(t){return e.push(t),()=>{const l=e.indexOf(t);l>-1&&e.splice(l,1)}},list:()=>e,reset:function(){e=[]}}}function Cr(e,t,l,n,o){const i=n&&(n.enterCallbacks[o]=n.enterCallbacks[o]||[]);return()=>new Promise(((r,s)=>{const a=e=>{var a;!1===e?s(er(4,{from:l,to:t})):e instanceof Error?s(e):"string"==typeof(a=e)||a&&"object"==typeof a?s(er(2,{from:t,to:e})):(i&&n.enterCallbacks[o]===i&&"function"==typeof e&&i.push(e),r())},c=e.call(n&&n.instances[o],t,l,a);let d=Promise.resolve(c);e.length<3&&(d=d.then(a)),d.catch((e=>s(e)))}))}function Fr(e,t,l,n){const o=[];for(const r of e)for(const e in r.components){let s=r.components[e];if("beforeRouteEnter"===t||r.instances[e])if("object"==typeof(i=s)||"displayName"in i||"props"in i||"__vccOpts"in i){const i=(s.__vccOpts||s)[t];i&&o.push(Cr(i,l,n,r,e))}else{let i=s();o.push((()=>i.then((o=>{if(!o)return Promise.reject(new Error(`Couldn't resolve component "${e}" at "${r.path}"`));const i=(s=o).__esModule||gi&&"Module"===s[Symbol.toStringTag]?o.default:o;var s;r.components[e]=i;const a=(i.__vccOpts||i)[t];return a&&Cr(a,l,n,r,e)()}))))}}var i;return o}function Nr(e){const t=Kt(Ei),l=Kt(xi),n=It((()=>t.resolve(wt(e.to)))),o=It((()=>{let{matched:e}=n.value,{length:t}=e;const o=e[t-1];let i=l.matched;if(!o||!i.length)return-1;let r=i.findIndex(Ri.bind(null,o));if(r>-1)return r;let s=Hr(e[t-2]);return t>1&&Hr(o)===s&&i[i.length-1].path!==s?i.findIndex(Ri.bind(null,e[t-2])):r})),i=It((()=>o.value>-1&&function(e,t){for(let l in t){let n=t[l],o=e[l];if("string"==typeof n){if(n!==o)return!1}else if(!Array.isArray(o)||o.length!==n.length||n.some(((e,t)=>e!==o[t])))return!1}return!0}(l.params,n.value.params))),r=It((()=>o.value>-1&&o.value===l.matched.length-1&&Di(l.params,n.value.params)));return{route:n,href:It((()=>n.value.href)),isActive:i,isExactActive:r,navigate:function(l={}){return function(e){if(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)return;if(e.defaultPrevented)return;if(void 0!==e.button&&0!==e.button)return;if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}e.preventDefault&&e.preventDefault();return!0}(l)?t[wt(e.replace)?"replace":"push"](wt(e.to)).catch(Pi):Promise.resolve()}}}const Mr=ol({name:"RouterLink",props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Nr,setup(e,{slots:t}){const l=ut(Nr(e)),{options:n}=Kt(Ei),o=It((()=>({[zr(e.activeClass,n.linkActiveClass,"router-link-active")]:l.isActive,[zr(e.exactActiveClass,n.linkExactActiveClass,"router-link-exact-active")]:l.isExactActive})));return()=>{const n=t.default&&t.default(l);return e.custom?n:Vo("a",{"aria-current":l.isExactActive?e.ariaCurrentValue:null,href:l.href,onClick:l.navigate,class:o.value},n)}}});function Hr(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const zr=(e,t,l)=>null!=e?e:null!=t?t:l;function Br(e,t){if(!e)return null;const l=e(t);return 1===l.length?l[0]:l}const $r=ol({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},setup(e,{attrs:t,slots:l}){const n=Kt(ji),o=It((()=>e.route||n.value)),i=Kt(yi,0),r=It((()=>o.value.matched[i]));Gt(yi,i+1),Gt(bi,r),Gt(ji,o);const s=jt();return Ao((()=>[s.value,r.value,e.name]),(([e,t,l],[n,o,i])=>{t&&(t.instances[l]=e,o&&o!==t&&e&&e===n&&(t.leaveGuards.size||(t.leaveGuards=o.leaveGuards),t.updateGuards.size||(t.updateGuards=o.updateGuards))),!e||!t||o&&Ri(t,o)&&n||(t.enterCallbacks[l]||[]).forEach((t=>t(e)))}),{flush:"post"}),()=>{const n=o.value,i=r.value,a=i&&i.components[e.name],c=e.name;if(!a)return Br(l.default,{Component:a,route:n});const d=i.props[e.name],u=d?!0===d?n.params:"function"==typeof d?d(n):d:null,h=Vo(a,Oi({},u,t,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(i.instances[c]=null)},ref:s}));return Br(l.default,{Component:h,route:n})||h}}});function Wr(e){const t=cr(e.routes,e);let l=e.parseQuery||Dr,n=e.stringifyQuery||Ir,o=e.history;const i=Vr(),r=Vr(),s=Vr(),a=Ot(Yi,!0);let c=Yi;Li&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const d=wi.bind(null,(e=>""+e)),u=wi.bind(null,Ar),h=wi.bind(null,Rr);function p(e,i){if(i=Oi({},i||a.value),"string"==typeof e){let n=ki(l,e,i.path),r=t.resolve({path:n.path},i),s=o.createHref(n.fullPath);return Oi(n,r,{params:h(r.params),hash:Rr(n.hash),redirectedFrom:void 0,href:s})}let r;"path"in e?r=Oi({},e,{path:ki(l,e.path,i.path).path}):(r=Oi({},e,{params:u(e.params)}),i.params=u(i.params));let s=t.resolve(r,i);const c=e.hash||"";s.params=d(h(s.params));const p=function(e,t){let l=t.query?e(t.query):"";return t.path+(l&&"?")+l+(t.hash||"")}(n,Oi({},e,{hash:(m=c,Tr(m).replace(Lr,"{").replace(wr,"}").replace(xr,"^")),path:s.path}));var m;let v=o.createHref(p);return Oi({fullPath:p,hash:c,query:n===Ir?Sr(e.query):e.query},s,{redirectedFrom:void 0,href:v})}function m(e){return"string"==typeof e?ki(l,e,a.value.path):Oi({},e)}function v(e,t){if(c!==e)return er(8,{from:t,to:e})}function f(e){return _(e)}function g(e){const t=e.matched[e.matched.length-1];if(t&&t.redirect){const{redirect:l}=t;let n="function"==typeof l?l(e):l;return"string"==typeof n&&(n=n.includes("?")||n.includes("#")?n=m(n):{path:n},n.params={}),Oi({query:e.query,hash:e.hash,params:e.params},n)}}function _(e,t){const l=c=p(e),o=a.value,i=e.state,r=e.force,s=!0===e.replace,d=g(l);if(d)return _(Oi(m(d),{state:i,force:r,replace:s}),t||l);const u=l;let h;return u.redirectedFrom=t,!r&&function(e,t,l){let n=t.matched.length-1,o=l.matched.length-1;return n>-1&&n===o&&Ri(t.matched[n],l.matched[o])&&Di(t.params,l.params)&&e(t.query)===e(l.query)&&t.hash===l.hash}(n,o,l)&&(h=er(16,{to:u,from:o}),A(o,o,!0,!1)),(h?Promise.resolve(h):y(u,o)).catch((e=>tr(e)?e:T(e,u,o))).then((e=>{if(e){if(tr(e,2))return _(Oi(m(e.to),{state:i,force:r,replace:s}),t||u)}else e=x(u,o,!0,s,i);return E(u,o,e),e}))}function b(e,t){const l=v(e,t);return l?Promise.reject(l):Promise.resolve()}function y(e,t){let l;const[n,o,s]=function(e,t){const l=[],n=[],o=[],i=Math.max(t.matched.length,e.matched.length);for(let r=0;rRi(e,i)))?n.push(i):l.push(i));const s=e.matched[r];s&&(t.matched.find((e=>Ri(e,s)))||o.push(s))}return[l,n,o]}(e,t);l=Fr(n.reverse(),"beforeRouteLeave",e,t);for(const i of n)i.leaveGuards.forEach((n=>{l.push(Cr(n,e,t))}));const a=b.bind(null,e,t);return l.push(a),Ur(l).then((()=>{l=[];for(const n of i.list())l.push(Cr(n,e,t));return l.push(a),Ur(l)})).then((()=>{l=Fr(o,"beforeRouteUpdate",e,t);for(const n of o)n.updateGuards.forEach((n=>{l.push(Cr(n,e,t))}));return l.push(a),Ur(l)})).then((()=>{l=[];for(const n of e.matched)if(n.beforeEnter&&!t.matched.includes(n))if(Array.isArray(n.beforeEnter))for(const o of n.beforeEnter)l.push(Cr(o,e,t));else l.push(Cr(n.beforeEnter,e,t));return l.push(a),Ur(l)})).then((()=>(e.matched.forEach((e=>e.enterCallbacks={})),l=Fr(s,"beforeRouteEnter",e,t),l.push(a),Ur(l)))).then((()=>{l=[];for(const n of r.list())l.push(Cr(n,e,t));return l.push(a),Ur(l)})).catch((e=>tr(e,8)?e:Promise.reject(e)))}function E(e,t,l){for(const n of s.list())n(e,t,l)}function x(e,t,l,n,i){const r=v(e,t);if(r)return r;const s=t===Yi,c=Li?history.state:{};l&&(n||s?o.replace(e.fullPath,Oi({scroll:s&&c&&c.scroll},i)):o.push(e.fullPath,i)),a.value=e,A(e,t,l,s),k()}let j;function L(){j=o.listen(((e,t,l)=>{let n=p(e);const i=g(n);if(i)return void _(Oi(i,{replace:!0}),n).catch(Pi);c=n;const r=a.value;var s,d;Li&&(s=Wi(r.fullPath,l.delta),d=Bi(),Ui.set(s,d)),y(n,r).catch((e=>tr(e,12)?e:tr(e,2)?(_(e.to,n).then((e=>{tr(e,20)&&!l.delta&&l.type===Vi.pop&&o.go(-1,!1)})).catch(Pi),Promise.reject()):(l.delta&&o.go(-l.delta,!1),T(e,n,r)))).then((e=>{(e=e||x(n,r,!1))&&(l.delta?o.go(-l.delta,!1):l.type===Vi.pop&&tr(e,20)&&o.go(-1,!1)),E(n,r,e)})).catch(Pi)}))}let O,w=Vr(),P=Vr();function T(e,t,l){k(e);const n=P.list();return n.length?n.forEach((n=>n(e,t,l))):console.error(e),Promise.reject(e)}function k(e){O||(O=!0,L(),w.list().forEach((([t,l])=>e?l(e):t())),w.reset())}function A(t,l,n,o){const{scrollBehavior:i}=e;if(!Li||!i)return Promise.resolve();let r=!n&&function(e){const t=Ui.get(e);return Ui.delete(e),t}(Wi(t.fullPath,0))||(o||!n)&&history.state&&history.state.scroll||null;return Eo().then((()=>i(t,l,r))).then((e=>e&&$i(e))).catch((e=>T(e,t,l)))}const R=e=>o.go(e);let D;const I=new Set;return{currentRoute:a,addRoute:function(e,l){let n,o;return Ki(e)?(n=t.getRecordMatcher(e),o=l):o=e,t.addRoute(o,n)},removeRoute:function(e){let l=t.getRecordMatcher(e);l&&t.removeRoute(l)},hasRoute:function(e){return!!t.getRecordMatcher(e)},getRoutes:function(){return t.getRoutes().map((e=>e.record))},resolve:p,options:e,push:f,replace:function(e){return f(Oi(m(e),{replace:!0}))},go:R,back:()=>R(-1),forward:()=>R(1),beforeEach:i.add,beforeResolve:r.add,afterEach:s.add,onError:P.add,isReady:function(){return O&&a.value!==Yi?Promise.resolve():new Promise(((e,t)=>{w.add([e,t])}))},install(e){e.component("RouterLink",Mr),e.component("RouterView",$r),e.config.globalProperties.$router=this,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>wt(a)}),Li&&!D&&a.value===Yi&&(D=!0,f(o.location).catch((e=>{})));const t={};for(let n in Yi)t[n]=It((()=>a.value[n]));e.provide(Ei,this),e.provide(xi,ut(t)),e.provide(ji,a);let l=e.unmount;I.add(e),e.unmount=function(){I.delete(e),I.size<1&&(j(),a.value=Yi,D=!1,O=!1),l()}}}}function Ur(e){return e.reduce(((e,t)=>e.then((()=>t()))),Promise.resolve())}function qr(){return Kt(Ei)}function Xr(){return Kt(xi)}const Gr=ol({setup(e,t){const l=jt(!1);return fl((()=>{l.value=!0})),()=>{var e,n;return l.value?null===(n=(e=t.slots).default)||void 0===n?void 0:n.call(e):null}}}),Kr={},Yr=function(e,t){return t&&0!==t.length?Promise.all(t.map((e=>{if((e=`/Xray-docs-next/${e}`)in Kr)return;Kr[e]=!0;const t=e.endsWith(".css"),l=t?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${e}"]${l}`))return;const n=document.createElement("link");return n.rel=t?"stylesheet":"modulepreload",t||(n.as="script",n.crossOrigin=""),n.href=e,document.head.appendChild(n),t?new Promise(((e,t)=>{n.addEventListener("load",e),n.addEventListener("error",t)})):void 0}))).then((()=>e())):e()},Qr={"v-8daa1a0e":rl((()=>Yr((()=>import("./index.html.3a5eaf89.js")),[]))),"v-aad48c6a":rl((()=>Yr((()=>import("./news.html.10dff9e9.js")),[]))),"v-ba934fd8":rl((()=>Yr((()=>import("./index.html.25f2c703.js")),[]))),"v-41ade9da":rl((()=>Yr((()=>import("./api.html.5f9fa31d.js")),[]))),"v-83dedd38":rl((()=>Yr((()=>import("./dns.html.52693cb1.js")),[]))),"v-192a19b9":rl((()=>Yr((()=>import("./fakedns.html.6b2a3805.js")),[]))),"v-7f6279d8":rl((()=>Yr((()=>import("./inbound.html.f5f141f8.js")),[]))),"v-1d860c29":rl((()=>Yr((()=>import("./log.html.0c40cfaf.js")),[]))),"v-2367d756":rl((()=>Yr((()=>import("./outbound.html.27f8ad33.js")),[]))),"v-4ebec35a":rl((()=>Yr((()=>import("./policy.html.a5bb78e3.js")),[]))),"v-31b7756a":rl((()=>Yr((()=>import("./reverse.html.d60fb944.js")),[]))),"v-70677432":rl((()=>Yr((()=>import("./routing.html.72789fb7.js")),[]))),"v-7e21d6ae":rl((()=>Yr((()=>import("./stats.html.19d97934.js")),[]))),"v-e3dfff38":rl((()=>Yr((()=>import("./transport.html.674eebf2.js")),[]))),"v-f7496066":rl((()=>Yr((()=>import("./index.html.db4f3080.js")),[]))),"v-36b1a79b":rl((()=>Yr((()=>import("./index.html.bd1215bd.js")),[]))),"v-09a64f89":rl((()=>Yr((()=>import("./command.html.1ad9e5f1.js")),[]))),"v-2b1adf48":rl((()=>Yr((()=>import("./config.html.bff40b62.js")),[]))),"v-86ee963a":rl((()=>Yr((()=>import("./document.html.548ebf63.js")),[]))),"v-0e5d7b39":rl((()=>Yr((()=>import("./install.html.542ce2ed.js")),[]))),"v-2d0a870d":rl((()=>Yr((()=>import("./index.html.4ececa11.js")),[]))),"v-0d714d87":rl((()=>Yr((()=>import("./browser_dialer.html.e175c84c.js")),[]))),"v-0da7880a":rl((()=>Yr((()=>import("./env.html.993365d3.js")),[]))),"v-2aeb21f9":rl((()=>Yr((()=>import("./fallback.html.45b3f202.js")),[]))),"v-3acf20ea":rl((()=>Yr((()=>import("./multiple.html.1f79c516.js")),[]))),"v-792e28f8":rl((()=>Yr((()=>import("./xtls.html.68940956.js")),[]))),"v-b50d2334":rl((()=>Yr((()=>import("./dokodemo.html.7b8ceccc.js")),[]))),"v-593408b0":rl((()=>Yr((()=>import("./http.html.47cc7e32.js")),[]))),"v-802a842a":rl((()=>Yr((()=>import("./shadowsocks.html.cc95c58a.js")),[]))),"v-29995cea":rl((()=>Yr((()=>import("./socks.html.068a2af0.js")),[]))),"v-2a1b3d72":rl((()=>Yr((()=>import("./trojan.html.50f3922c.js")),[]))),"v-fb92e8aa":rl((()=>Yr((()=>import("./vless.html.36b5a07d.js")),[]))),"v-167afaac":rl((()=>Yr((()=>import("./vmess.html.deaa5626.js")),[]))),"v-749ad71a":rl((()=>Yr((()=>import("./blackhole.html.d545d07f.js")),[]))),"v-6d39b970":rl((()=>Yr((()=>import("./dns.html.bf2b1c62.js")),[]))),"v-d76e893a":rl((()=>Yr((()=>import("./freedom.html.4928c41f.js")),[]))),"v-c6b4b59e":rl((()=>Yr((()=>import("./http.html.6005489a.js")),[]))),"v-7b293e4a":rl((()=>Yr((()=>import("./shadowsocks.html.35c0831b.js")),[]))),"v-15f5452a":rl((()=>Yr((()=>import("./socks.html.40f804cc.js")),[]))),"v-5797bdb3":rl((()=>Yr((()=>import("./trojan.html.17832860.js")),[]))),"v-a60f016c":rl((()=>Yr((()=>import("./vless.html.6731895d.js")),[]))),"v-413cee4b":rl((()=>Yr((()=>import("./vmess.html.e7af9fe7.js")),[]))),"v-208ca3b9":rl((()=>Yr((()=>import("./wireguard.html.d818fa5b.js")),[]))),"v-775db7b1":rl((()=>Yr((()=>import("./domainsocket.html.1d68f776.js")),[]))),"v-2877542a":rl((()=>Yr((()=>import("./grpc.html.5742e390.js")),[]))),"v-03a28284":rl((()=>Yr((()=>import("./h2.html.7e765ae6.js")),[]))),"v-3167b1dd":rl((()=>Yr((()=>import("./mkcp.html.fd4e953c.js")),[]))),"v-8f08dbec":rl((()=>Yr((()=>import("./quic.html.2a3227f2.js")),[]))),"v-33b1b709":rl((()=>Yr((()=>import("./tcp.html.24b07eda.js")),[]))),"v-1ff57bba":rl((()=>Yr((()=>import("./websocket.html.7e909ae6.js")),[]))),"v-6a9e8054":rl((()=>Yr((()=>import("./compile.html.76028011.js")),[]))),"v-95e3eaea":rl((()=>Yr((()=>import("./design.html.05403052.js")),[]))),"v-61e7eea6":rl((()=>Yr((()=>import("./guide.html.b1f5bad2.js")),[]))),"v-6e6c37e6":rl((()=>Yr((()=>import("./mkcp.html.16d65ae7.js")),[]))),"v-13168a21":rl((()=>Yr((()=>import("./muxcool.html.39cdcc2e.js")),[]))),"v-5c48c82b":rl((()=>Yr((()=>import("./vless.html.ea7df066.js")),[]))),"v-1ee591a8":rl((()=>Yr((()=>import("./vmess.html.172c5ae5.js")),[]))),"v-3f09dcfa":rl((()=>Yr((()=>import("./index.html.1b035654.js")),[]))),"v-fb444906":rl((()=>Yr((()=>import("./ch01-preface.html.4a75a4e8.js")),[]))),"v-075f3ae5":rl((()=>Yr((()=>import("./ch02-preparation.html.f06ab21a.js")),[]))),"v-726d0633":rl((()=>Yr((()=>import("./ch03-ssh.html.04205ee1.js")),[]))),"v-430c6ab8":rl((()=>Yr((()=>import("./ch04-security.html.7f3b6fec.js")),[]))),"v-717c6376":rl((()=>Yr((()=>import("./ch05-webpage.html.d85ce3b4.js")),[]))),"v-278039be":rl((()=>Yr((()=>import("./ch06-certificates.html.8c0bdd2e.js")),[]))),"v-a0c7f88e":rl((()=>Yr((()=>import("./ch07-xray-server.html.a3da7220.js")),[]))),"v-86586ca2":rl((()=>Yr((()=>import("./ch08-xray-clients.html.4df4886f.js")),[]))),"v-3eb62514":rl((()=>Yr((()=>import("./ch09-appendix.html.ebc76319.js")),[]))),"v-3f09dcbc":rl((()=>Yr((()=>import("./index.html.ed299f0a.js")),[]))),"v-b21a2a20":rl((()=>Yr((()=>import("./fallbacks-lv1.html.c7274041.js")),[]))),"v-da623318":rl((()=>Yr((()=>import("./fallbacks-with-sni.html.bcd4bfd4.js")),[]))),"v-fdd722ac":rl((()=>Yr((()=>import("./routing-lv1-part1.html.f80179a7.js")),[]))),"v-fa6d716e":rl((()=>Yr((()=>import("./routing-lv1-part2.html.94f43314.js")),[]))),"v-2f29e106":rl((()=>Yr((()=>import("./work.html.bc8c017a.js")),[]))),"v-3f09dc7e":rl((()=>Yr((()=>import("./index.html.1aea56f1.js")),[]))),"v-1c17916e":rl((()=>Yr((()=>import("./iptables_gid.html.5744dd71.js")),[]))),"v-a001cfa6":rl((()=>Yr((()=>import("./nginx_or_haproxy_tls_tunnel.html.7190e425.js")),[]))),"v-46333b48":rl((()=>Yr((()=>import("./redirect.html.8223ec28.js")),[]))),"v-338bc63e":rl((()=>Yr((()=>import("./tproxy.html.276ea185.js")),[]))),"v-d68f7d58":rl((()=>Yr((()=>import("./tproxy_ipv4_and_ipv6.html.ce2184ec.js")),[]))),"v-e533e2c6":rl((()=>Yr((()=>import("./traffic_stats.html.84106893.js")),[]))),"v-1e465ab0":rl((()=>Yr((()=>import("./warp.html.b8d62296.js")),[]))),"v-1080fb37":rl((()=>Yr((()=>import("./news.html.531ce213.js")),[]))),"v-317fc580":rl((()=>Yr((()=>import("./index.html.f6be7756.js")),[]))),"v-45144c7f":rl((()=>Yr((()=>import("./api.html.620afbc9.js")),[]))),"v-23fbd2d0":rl((()=>Yr((()=>import("./dns.html.8f955016.js")),[]))),"v-2b7ec525":rl((()=>Yr((()=>import("./fakedns.html.39dbcc98.js")),[]))),"v-5ab92300":rl((()=>Yr((()=>import("./inbound.html.29c964cf.js")),[]))),"v-f91d64d6":rl((()=>Yr((()=>import("./log.html.4659fb1e.js")),[]))),"v-268cd669":rl((()=>Yr((()=>import("./outbound.html.d2fa4921.js")),[]))),"v-4492d567":rl((()=>Yr((()=>import("./policy.html.bb72f124.js")),[]))),"v-0d0e1e92":rl((()=>Yr((()=>import("./reverse.html.82f6f6f1.js")),[]))),"v-4bbe1d5a":rl((()=>Yr((()=>import("./routing.html.90ac5107.js")),[]))),"v-16426d1a":rl((()=>Yr((()=>import("./stats.html.fb90cc6a.js")),[]))),"v-5de780d0":rl((()=>Yr((()=>import("./transport.html.83a58fcb.js")),[]))),"v-f88d343e":rl((()=>Yr((()=>import("./index.html.8808c83d.js")),[]))),"v-38d56a07":rl((()=>Yr((()=>import("./index.html.7fe27d11.js")),[]))),"v-4d046016":rl((()=>Yr((()=>import("./command.html.7a5c22da.js")),[]))),"v-22b35270":rl((()=>Yr((()=>import("./config.html.647c6656.js")),[]))),"v-30bd7c12":rl((()=>Yr((()=>import("./document.html.5f5222cc.js")),[]))),"v-439608b6":rl((()=>Yr((()=>import("./install.html.a6fadd36.js")),[]))),"v-51a51d87":rl((()=>Yr((()=>import("./transparent_proxy.html.ecc1188f.js")),[]))),"v-76b9a0f3":rl((()=>Yr((()=>import("./browser_dialer.html.621b9ea4.js")),[]))),"v-565dbfc4":rl((()=>Yr((()=>import("./env.html.7adbd95d.js")),[]))),"v-0fbd1336":rl((()=>Yr((()=>import("./fallback.html.688a3beb.js")),[]))),"v-a0627812":rl((()=>Yr((()=>import("./multiple.html.c1dc1778.js")),[]))),"v-d190d938":rl((()=>Yr((()=>import("./xtls.html.aad2ef82.js")),[]))),"v-72afc2d2":rl((()=>Yr((()=>import("./dokodemo.html.75d80861.js")),[]))),"v-773d731c":rl((()=>Yr((()=>import("./http.html.ac5ddbc5.js")),[]))),"v-f555fc02":rl((()=>Yr((()=>import("./shadowsocks.html.8afbb9f3.js")),[]))),"v-e35196c2":rl((()=>Yr((()=>import("./socks.html.00850baf.js")),[]))),"v-29188644":rl((()=>Yr((()=>import("./trojan.html.ae9fa06b.js")),[]))),"v-255a6ebf":rl((()=>Yr((()=>import("./vless.html.98f0b143.js")),[]))),"v-8cc24480":rl((()=>Yr((()=>import("./vmess.html.d7593e24.js")),[]))),"v-64e47ef4":rl((()=>Yr((()=>import("./blackhole.html.65d6a1c1.js")),[]))),"v-e979b848":rl((()=>Yr((()=>import("./dns.html.b39b6b30.js")),[]))),"v-617f0fcf":rl((()=>Yr((()=>import("./freedom.html.975ddd2c.js")),[]))),"v-3fc98845":rl((()=>Yr((()=>import("./http.html.b38fc5e5.js")),[]))),"v-63077cb6":rl((()=>Yr((()=>import("./shadowsocks.html.def40830.js")),[]))),"v-516476d4":rl((()=>Yr((()=>import("./socks.html.ffdb6877.js")),[]))),"v-7d61a872":rl((()=>Yr((()=>import("./trojan.html.b41a334e.js")),[]))),"v-6e50feb6":rl((()=>Yr((()=>import("./vless.html.3be490f9.js")),[]))),"v-02956db7":rl((()=>Yr((()=>import("./vmess.html.906abd7c.js")),[]))),"v-797f8d25":rl((()=>Yr((()=>import("./wireguard.html.efd81cf2.js")),[]))),"v-3eb3e9c6":rl((()=>Yr((()=>import("./domainsocket.html.bdccc3c0.js")),[]))),"v-2c6058d4":rl((()=>Yr((()=>import("./grpc.html.8eb0658a.js")),[]))),"v-1c38292a":rl((()=>Yr((()=>import("./h2.html.154fc280.js")),[]))),"v-1a7f9d6e":rl((()=>Yr((()=>import("./mkcp.html.8ecd0563.js")),[]))),"v-79d41176":rl((()=>Yr((()=>import("./quic.html.f2e89cad.js")),[]))),"v-5254cbc6":rl((()=>Yr((()=>import("./tcp.html.24c3bffb.js")),[]))),"v-9520f392":rl((()=>Yr((()=>import("./websocket.html.5246d66a.js")),[]))),"v-b7760e2c":rl((()=>Yr((()=>import("./compile.html.5b8928f4.js")),[]))),"v-fb774212":rl((()=>Yr((()=>import("./design.html.5dd013d2.js")),[]))),"v-38c376c1":rl((()=>Yr((()=>import("./guide.html.81845aa0.js")),[]))),"v-21bccd79":rl((()=>Yr((()=>import("./mkcp.html.0ca746da.js")),[]))),"v-27001935":rl((()=>Yr((()=>import("./muxcool.html.4b83d2f6.js")),[]))),"v-21b30c3f":rl((()=>Yr((()=>import("./vless.html.a8177d4e.js")),[]))),"v-94110980":rl((()=>Yr((()=>import("./vmess.html.39809dda.js")),[]))),"v-789ba7ef":rl((()=>Yr((()=>import("./index.html.773aa27d.js")),[]))),"v-d3712ade":rl((()=>Yr((()=>import("./ch01-preface.html.b8e2f249.js")),[]))),"v-41f9c00e":rl((()=>Yr((()=>import("./ch02-preparation.html.7a4b9487.js")),[]))),"v-4c013f47":rl((()=>Yr((()=>import("./ch03-ssh.html.58a7d32a.js")),[]))),"v-a75683b8":rl((()=>Yr((()=>import("./ch04-security.html.2b8400fc.js")),[]))),"v-f5341aec":rl((()=>Yr((()=>import("./ch05-webpage.html.ecc4595b.js")),[]))),"v-4458f72a":rl((()=>Yr((()=>import("./ch06-certificates.html.6cd9aaca.js")),[]))),"v-f1802e66":rl((()=>Yr((()=>import("./ch07-xray-server.html.eeae1829.js")),[]))),"v-4ca6f1ca":rl((()=>Yr((()=>import("./ch08-xray-clients.html.347d9b86.js")),[]))),"v-b0030f00":rl((()=>Yr((()=>import("./ch09-appendix.html.ba31318a.js")),[]))),"v-789ba80e":rl((()=>Yr((()=>import("./index.html.9097978e.js")),[]))),"v-103b3e5c":rl((()=>Yr((()=>import("./fallbacks-lv1.html.150de4aa.js")),[]))),"v-110dd688":rl((()=>Yr((()=>import("./fallbacks-with-sni.html.a7aa5d6b.js")),[]))),"v-c425a7d4":rl((()=>Yr((()=>import("./routing-lv1-part1.html.f622db3d.js")),[]))),"v-c0bbf696":rl((()=>Yr((()=>import("./routing-lv1-part2.html.83708fd4.js")),[]))),"v-5b6477cc":rl((()=>Yr((()=>import("./work.html.b1ae1f68.js")),[]))),"v-789ba82d":rl((()=>Yr((()=>import("./index.html.e33f1535.js")),[]))),"v-05ddc65d":rl((()=>Yr((()=>import("./iptables_gid.html.bbe2cc3c.js")),[]))),"v-1f3a890a":rl((()=>Yr((()=>import("./nginx_tls_tunnel.html.48634e5e.js")),[]))),"v-930ac920":rl((()=>Yr((()=>import("./redirect.html.1db13504.js")),[]))),"v-c579975c":rl((()=>Yr((()=>import("./tproxy.html.e317a52f.js")),[]))),"v-7efb7c68":rl((()=>Yr((()=>import("./tproxy_ipv4_and_ipv6.html.1da96407.js")),[]))),"v-12a33bee":rl((()=>Yr((()=>import("./traffic_stats.html.500a1693.js")),[]))),"v-7d2b8478":rl((()=>Yr((()=>import("./warp.html.09cd5ef1.js")),[]))),"v-7689d7f3":rl((()=>Yr((()=>import("./transparent_proxy.html.440228ab.js")),[]))),"v-3706649a":rl((()=>Yr((()=>import("./404.html.c3886853.js")),[])))},Jr=jt({"v-8daa1a0e":()=>Yr((()=>import("./index.html.c788a269.js")),[]).then((({data:e})=>e)),"v-aad48c6a":()=>Yr((()=>import("./news.html.f9558a56.js")),[]).then((({data:e})=>e)),"v-ba934fd8":()=>Yr((()=>import("./index.html.356803e9.js")),[]).then((({data:e})=>e)),"v-41ade9da":()=>Yr((()=>import("./api.html.40e8e214.js")),[]).then((({data:e})=>e)),"v-83dedd38":()=>Yr((()=>import("./dns.html.38d154e3.js")),[]).then((({data:e})=>e)),"v-192a19b9":()=>Yr((()=>import("./fakedns.html.72fc9554.js")),[]).then((({data:e})=>e)),"v-7f6279d8":()=>Yr((()=>import("./inbound.html.c4089bc7.js")),[]).then((({data:e})=>e)),"v-1d860c29":()=>Yr((()=>import("./log.html.54ad11e6.js")),[]).then((({data:e})=>e)),"v-2367d756":()=>Yr((()=>import("./outbound.html.41f06bd9.js")),[]).then((({data:e})=>e)),"v-4ebec35a":()=>Yr((()=>import("./policy.html.a228a213.js")),[]).then((({data:e})=>e)),"v-31b7756a":()=>Yr((()=>import("./reverse.html.430928ac.js")),[]).then((({data:e})=>e)),"v-70677432":()=>Yr((()=>import("./routing.html.43f06e05.js")),[]).then((({data:e})=>e)),"v-7e21d6ae":()=>Yr((()=>import("./stats.html.8ff59a03.js")),[]).then((({data:e})=>e)),"v-e3dfff38":()=>Yr((()=>import("./transport.html.15ed80be.js")),[]).then((({data:e})=>e)),"v-f7496066":()=>Yr((()=>import("./index.html.c2745ef7.js")),[]).then((({data:e})=>e)),"v-36b1a79b":()=>Yr((()=>import("./index.html.c2db9566.js")),[]).then((({data:e})=>e)),"v-09a64f89":()=>Yr((()=>import("./command.html.dc4b563a.js")),[]).then((({data:e})=>e)),"v-2b1adf48":()=>Yr((()=>import("./config.html.1815b253.js")),[]).then((({data:e})=>e)),"v-86ee963a":()=>Yr((()=>import("./document.html.a886c958.js")),[]).then((({data:e})=>e)),"v-0e5d7b39":()=>Yr((()=>import("./install.html.a9b4d86f.js")),[]).then((({data:e})=>e)),"v-2d0a870d":()=>Yr((()=>import("./index.html.6e4b8ecc.js")),[]).then((({data:e})=>e)),"v-0d714d87":()=>Yr((()=>import("./browser_dialer.html.38332fbb.js")),[]).then((({data:e})=>e)),"v-0da7880a":()=>Yr((()=>import("./env.html.d6ae65f9.js")),[]).then((({data:e})=>e)),"v-2aeb21f9":()=>Yr((()=>import("./fallback.html.742cf950.js")),[]).then((({data:e})=>e)),"v-3acf20ea":()=>Yr((()=>import("./multiple.html.782a2f36.js")),[]).then((({data:e})=>e)),"v-792e28f8":()=>Yr((()=>import("./xtls.html.d7e41b35.js")),[]).then((({data:e})=>e)),"v-b50d2334":()=>Yr((()=>import("./dokodemo.html.eea3d70d.js")),[]).then((({data:e})=>e)),"v-593408b0":()=>Yr((()=>import("./http.html.24945aae.js")),[]).then((({data:e})=>e)),"v-802a842a":()=>Yr((()=>import("./shadowsocks.html.e4531595.js")),[]).then((({data:e})=>e)),"v-29995cea":()=>Yr((()=>import("./socks.html.07c0cbb9.js")),[]).then((({data:e})=>e)),"v-2a1b3d72":()=>Yr((()=>import("./trojan.html.3092bf11.js")),[]).then((({data:e})=>e)),"v-fb92e8aa":()=>Yr((()=>import("./vless.html.f0b06754.js")),[]).then((({data:e})=>e)),"v-167afaac":()=>Yr((()=>import("./vmess.html.c6a1f9a1.js")),[]).then((({data:e})=>e)),"v-749ad71a":()=>Yr((()=>import("./blackhole.html.22494a95.js")),[]).then((({data:e})=>e)),"v-6d39b970":()=>Yr((()=>import("./dns.html.a6a56076.js")),[]).then((({data:e})=>e)),"v-d76e893a":()=>Yr((()=>import("./freedom.html.74f209a8.js")),[]).then((({data:e})=>e)),"v-c6b4b59e":()=>Yr((()=>import("./http.html.4bea36d9.js")),[]).then((({data:e})=>e)),"v-7b293e4a":()=>Yr((()=>import("./shadowsocks.html.0e8489f1.js")),[]).then((({data:e})=>e)),"v-15f5452a":()=>Yr((()=>import("./socks.html.ed5a9909.js")),[]).then((({data:e})=>e)),"v-5797bdb3":()=>Yr((()=>import("./trojan.html.adccf10f.js")),[]).then((({data:e})=>e)),"v-a60f016c":()=>Yr((()=>import("./vless.html.38e231a4.js")),[]).then((({data:e})=>e)),"v-413cee4b":()=>Yr((()=>import("./vmess.html.98bee5e8.js")),[]).then((({data:e})=>e)),"v-208ca3b9":()=>Yr((()=>import("./wireguard.html.dfa986c4.js")),[]).then((({data:e})=>e)),"v-775db7b1":()=>Yr((()=>import("./domainsocket.html.89d6a091.js")),[]).then((({data:e})=>e)),"v-2877542a":()=>Yr((()=>import("./grpc.html.e1e71a0c.js")),[]).then((({data:e})=>e)),"v-03a28284":()=>Yr((()=>import("./h2.html.667edbec.js")),[]).then((({data:e})=>e)),"v-3167b1dd":()=>Yr((()=>import("./mkcp.html.67fa5670.js")),[]).then((({data:e})=>e)),"v-8f08dbec":()=>Yr((()=>import("./quic.html.0b4ad469.js")),[]).then((({data:e})=>e)),"v-33b1b709":()=>Yr((()=>import("./tcp.html.c8dc480d.js")),[]).then((({data:e})=>e)),"v-1ff57bba":()=>Yr((()=>import("./websocket.html.1b681c57.js")),[]).then((({data:e})=>e)),"v-6a9e8054":()=>Yr((()=>import("./compile.html.c3dc2a7c.js")),[]).then((({data:e})=>e)),"v-95e3eaea":()=>Yr((()=>import("./design.html.fd048cfc.js")),[]).then((({data:e})=>e)),"v-61e7eea6":()=>Yr((()=>import("./guide.html.8400f750.js")),[]).then((({data:e})=>e)),"v-6e6c37e6":()=>Yr((()=>import("./mkcp.html.53c0886d.js")),[]).then((({data:e})=>e)),"v-13168a21":()=>Yr((()=>import("./muxcool.html.dc6e68e8.js")),[]).then((({data:e})=>e)),"v-5c48c82b":()=>Yr((()=>import("./vless.html.f2fb691f.js")),[]).then((({data:e})=>e)),"v-1ee591a8":()=>Yr((()=>import("./vmess.html.a9f36c59.js")),[]).then((({data:e})=>e)),"v-3f09dcfa":()=>Yr((()=>import("./index.html.87401658.js")),[]).then((({data:e})=>e)),"v-fb444906":()=>Yr((()=>import("./ch01-preface.html.37dc3cd3.js")),[]).then((({data:e})=>e)),"v-075f3ae5":()=>Yr((()=>import("./ch02-preparation.html.45e9207b.js")),[]).then((({data:e})=>e)),"v-726d0633":()=>Yr((()=>import("./ch03-ssh.html.3fa8504d.js")),[]).then((({data:e})=>e)),"v-430c6ab8":()=>Yr((()=>import("./ch04-security.html.cc2fdeeb.js")),[]).then((({data:e})=>e)),"v-717c6376":()=>Yr((()=>import("./ch05-webpage.html.02dee46d.js")),[]).then((({data:e})=>e)),"v-278039be":()=>Yr((()=>import("./ch06-certificates.html.89e63f79.js")),[]).then((({data:e})=>e)),"v-a0c7f88e":()=>Yr((()=>import("./ch07-xray-server.html.988d5515.js")),[]).then((({data:e})=>e)),"v-86586ca2":()=>Yr((()=>import("./ch08-xray-clients.html.246315b3.js")),[]).then((({data:e})=>e)),"v-3eb62514":()=>Yr((()=>import("./ch09-appendix.html.4f965f95.js")),[]).then((({data:e})=>e)),"v-3f09dcbc":()=>Yr((()=>import("./index.html.5d677cbc.js")),[]).then((({data:e})=>e)),"v-b21a2a20":()=>Yr((()=>import("./fallbacks-lv1.html.be80d8f5.js")),[]).then((({data:e})=>e)),"v-da623318":()=>Yr((()=>import("./fallbacks-with-sni.html.47a2e02c.js")),[]).then((({data:e})=>e)),"v-fdd722ac":()=>Yr((()=>import("./routing-lv1-part1.html.92572603.js")),[]).then((({data:e})=>e)),"v-fa6d716e":()=>Yr((()=>import("./routing-lv1-part2.html.dabc417b.js")),[]).then((({data:e})=>e)),"v-2f29e106":()=>Yr((()=>import("./work.html.a41354d6.js")),[]).then((({data:e})=>e)),"v-3f09dc7e":()=>Yr((()=>import("./index.html.ffeb6e40.js")),[]).then((({data:e})=>e)),"v-1c17916e":()=>Yr((()=>import("./iptables_gid.html.f6e26ba6.js")),[]).then((({data:e})=>e)),"v-a001cfa6":()=>Yr((()=>import("./nginx_or_haproxy_tls_tunnel.html.d422e6ac.js")),[]).then((({data:e})=>e)),"v-46333b48":()=>Yr((()=>import("./redirect.html.4edfdf11.js")),[]).then((({data:e})=>e)),"v-338bc63e":()=>Yr((()=>import("./tproxy.html.593c73b0.js")),[]).then((({data:e})=>e)),"v-d68f7d58":()=>Yr((()=>import("./tproxy_ipv4_and_ipv6.html.a4e9bb74.js")),[]).then((({data:e})=>e)),"v-e533e2c6":()=>Yr((()=>import("./traffic_stats.html.39b9a5e7.js")),[]).then((({data:e})=>e)),"v-1e465ab0":()=>Yr((()=>import("./warp.html.07b2efe6.js")),[]).then((({data:e})=>e)),"v-1080fb37":()=>Yr((()=>import("./news.html.b4a0ef66.js")),[]).then((({data:e})=>e)),"v-317fc580":()=>Yr((()=>import("./index.html.b138225e.js")),[]).then((({data:e})=>e)),"v-45144c7f":()=>Yr((()=>import("./api.html.80463963.js")),[]).then((({data:e})=>e)),"v-23fbd2d0":()=>Yr((()=>import("./dns.html.cf7c003a.js")),[]).then((({data:e})=>e)),"v-2b7ec525":()=>Yr((()=>import("./fakedns.html.2978776b.js")),[]).then((({data:e})=>e)),"v-5ab92300":()=>Yr((()=>import("./inbound.html.0d185e80.js")),[]).then((({data:e})=>e)),"v-f91d64d6":()=>Yr((()=>import("./log.html.a903a70e.js")),[]).then((({data:e})=>e)),"v-268cd669":()=>Yr((()=>import("./outbound.html.3948e8de.js")),[]).then((({data:e})=>e)),"v-4492d567":()=>Yr((()=>import("./policy.html.6d7c5ab9.js")),[]).then((({data:e})=>e)),"v-0d0e1e92":()=>Yr((()=>import("./reverse.html.a08c2a40.js")),[]).then((({data:e})=>e)),"v-4bbe1d5a":()=>Yr((()=>import("./routing.html.d367b2ff.js")),[]).then((({data:e})=>e)),"v-16426d1a":()=>Yr((()=>import("./stats.html.1b6dc06a.js")),[]).then((({data:e})=>e)),"v-5de780d0":()=>Yr((()=>import("./transport.html.4bcccfcf.js")),[]).then((({data:e})=>e)),"v-f88d343e":()=>Yr((()=>import("./index.html.84ca1edb.js")),[]).then((({data:e})=>e)),"v-38d56a07":()=>Yr((()=>import("./index.html.fb5a3e20.js")),[]).then((({data:e})=>e)),"v-4d046016":()=>Yr((()=>import("./command.html.1a4ac829.js")),[]).then((({data:e})=>e)),"v-22b35270":()=>Yr((()=>import("./config.html.08447352.js")),[]).then((({data:e})=>e)),"v-30bd7c12":()=>Yr((()=>import("./document.html.35272d77.js")),[]).then((({data:e})=>e)),"v-439608b6":()=>Yr((()=>import("./install.html.cafc1ef5.js")),[]).then((({data:e})=>e)),"v-51a51d87":()=>Yr((()=>import("./transparent_proxy.html.3615c2f2.js")),[]).then((({data:e})=>e)),"v-76b9a0f3":()=>Yr((()=>import("./browser_dialer.html.db4821df.js")),[]).then((({data:e})=>e)),"v-565dbfc4":()=>Yr((()=>import("./env.html.09553594.js")),[]).then((({data:e})=>e)),"v-0fbd1336":()=>Yr((()=>import("./fallback.html.ad8d7190.js")),[]).then((({data:e})=>e)),"v-a0627812":()=>Yr((()=>import("./multiple.html.02688a34.js")),[]).then((({data:e})=>e)),"v-d190d938":()=>Yr((()=>import("./xtls.html.876f1046.js")),[]).then((({data:e})=>e)),"v-72afc2d2":()=>Yr((()=>import("./dokodemo.html.9106219e.js")),[]).then((({data:e})=>e)),"v-773d731c":()=>Yr((()=>import("./http.html.4c95e93b.js")),[]).then((({data:e})=>e)),"v-f555fc02":()=>Yr((()=>import("./shadowsocks.html.93f2c8b8.js")),[]).then((({data:e})=>e)),"v-e35196c2":()=>Yr((()=>import("./socks.html.faac7ded.js")),[]).then((({data:e})=>e)),"v-29188644":()=>Yr((()=>import("./trojan.html.0d637f0d.js")),[]).then((({data:e})=>e)),"v-255a6ebf":()=>Yr((()=>import("./vless.html.42408db4.js")),[]).then((({data:e})=>e)),"v-8cc24480":()=>Yr((()=>import("./vmess.html.91da1a1a.js")),[]).then((({data:e})=>e)),"v-64e47ef4":()=>Yr((()=>import("./blackhole.html.1aa4fc91.js")),[]).then((({data:e})=>e)),"v-e979b848":()=>Yr((()=>import("./dns.html.f6ce6986.js")),[]).then((({data:e})=>e)),"v-617f0fcf":()=>Yr((()=>import("./freedom.html.874e8ef6.js")),[]).then((({data:e})=>e)),"v-3fc98845":()=>Yr((()=>import("./http.html.9e441e87.js")),[]).then((({data:e})=>e)),"v-63077cb6":()=>Yr((()=>import("./shadowsocks.html.4780f083.js")),[]).then((({data:e})=>e)),"v-516476d4":()=>Yr((()=>import("./socks.html.8faf26dd.js")),[]).then((({data:e})=>e)),"v-7d61a872":()=>Yr((()=>import("./trojan.html.7aaa430f.js")),[]).then((({data:e})=>e)),"v-6e50feb6":()=>Yr((()=>import("./vless.html.2daf326e.js")),[]).then((({data:e})=>e)),"v-02956db7":()=>Yr((()=>import("./vmess.html.f64535f2.js")),[]).then((({data:e})=>e)),"v-797f8d25":()=>Yr((()=>import("./wireguard.html.3b999598.js")),[]).then((({data:e})=>e)),"v-3eb3e9c6":()=>Yr((()=>import("./domainsocket.html.e3adec3f.js")),[]).then((({data:e})=>e)),"v-2c6058d4":()=>Yr((()=>import("./grpc.html.f962b1ef.js")),[]).then((({data:e})=>e)),"v-1c38292a":()=>Yr((()=>import("./h2.html.e80e30c6.js")),[]).then((({data:e})=>e)),"v-1a7f9d6e":()=>Yr((()=>import("./mkcp.html.195416a2.js")),[]).then((({data:e})=>e)),"v-79d41176":()=>Yr((()=>import("./quic.html.65ba1f39.js")),[]).then((({data:e})=>e)),"v-5254cbc6":()=>Yr((()=>import("./tcp.html.2fad4214.js")),[]).then((({data:e})=>e)),"v-9520f392":()=>Yr((()=>import("./websocket.html.cf4ddf8f.js")),[]).then((({data:e})=>e)),"v-b7760e2c":()=>Yr((()=>import("./compile.html.e6e475b5.js")),[]).then((({data:e})=>e)),"v-fb774212":()=>Yr((()=>import("./design.html.02ca2fb4.js")),[]).then((({data:e})=>e)),"v-38c376c1":()=>Yr((()=>import("./guide.html.a623f5ad.js")),[]).then((({data:e})=>e)),"v-21bccd79":()=>Yr((()=>import("./mkcp.html.57deee5f.js")),[]).then((({data:e})=>e)),"v-27001935":()=>Yr((()=>import("./muxcool.html.c406cf07.js")),[]).then((({data:e})=>e)),"v-21b30c3f":()=>Yr((()=>import("./vless.html.c6271d36.js")),[]).then((({data:e})=>e)),"v-94110980":()=>Yr((()=>import("./vmess.html.02556ac3.js")),[]).then((({data:e})=>e)),"v-789ba7ef":()=>Yr((()=>import("./index.html.071d4e5f.js")),[]).then((({data:e})=>e)),"v-d3712ade":()=>Yr((()=>import("./ch01-preface.html.68893a38.js")),[]).then((({data:e})=>e)),"v-41f9c00e":()=>Yr((()=>import("./ch02-preparation.html.1b7e03b5.js")),[]).then((({data:e})=>e)),"v-4c013f47":()=>Yr((()=>import("./ch03-ssh.html.c40cdbd4.js")),[]).then((({data:e})=>e)),"v-a75683b8":()=>Yr((()=>import("./ch04-security.html.9e3de46f.js")),[]).then((({data:e})=>e)),"v-f5341aec":()=>Yr((()=>import("./ch05-webpage.html.27d4adb3.js")),[]).then((({data:e})=>e)),"v-4458f72a":()=>Yr((()=>import("./ch06-certificates.html.836a5fbb.js")),[]).then((({data:e})=>e)),"v-f1802e66":()=>Yr((()=>import("./ch07-xray-server.html.d944ec1b.js")),[]).then((({data:e})=>e)),"v-4ca6f1ca":()=>Yr((()=>import("./ch08-xray-clients.html.aaa57d66.js")),[]).then((({data:e})=>e)),"v-b0030f00":()=>Yr((()=>import("./ch09-appendix.html.0dd8a94d.js")),[]).then((({data:e})=>e)),"v-789ba80e":()=>Yr((()=>import("./index.html.f21c5745.js")),[]).then((({data:e})=>e)),"v-103b3e5c":()=>Yr((()=>import("./fallbacks-lv1.html.11b08b9f.js")),[]).then((({data:e})=>e)),"v-110dd688":()=>Yr((()=>import("./fallbacks-with-sni.html.6d67e52b.js")),[]).then((({data:e})=>e)),"v-c425a7d4":()=>Yr((()=>import("./routing-lv1-part1.html.3d780830.js")),[]).then((({data:e})=>e)),"v-c0bbf696":()=>Yr((()=>import("./routing-lv1-part2.html.4c286c2d.js")),[]).then((({data:e})=>e)),"v-5b6477cc":()=>Yr((()=>import("./work.html.8f09f9fb.js")),[]).then((({data:e})=>e)),"v-789ba82d":()=>Yr((()=>import("./index.html.8d58f27b.js")),[]).then((({data:e})=>e)),"v-05ddc65d":()=>Yr((()=>import("./iptables_gid.html.fe8e2788.js")),[]).then((({data:e})=>e)),"v-1f3a890a":()=>Yr((()=>import("./nginx_tls_tunnel.html.64038300.js")),[]).then((({data:e})=>e)),"v-930ac920":()=>Yr((()=>import("./redirect.html.bafbe2e7.js")),[]).then((({data:e})=>e)),"v-c579975c":()=>Yr((()=>import("./tproxy.html.35dfa677.js")),[]).then((({data:e})=>e)),"v-7efb7c68":()=>Yr((()=>import("./tproxy_ipv4_and_ipv6.html.5fe5f9e8.js")),[]).then((({data:e})=>e)),"v-12a33bee":()=>Yr((()=>import("./traffic_stats.html.a3ddd4d1.js")),[]).then((({data:e})=>e)),"v-7d2b8478":()=>Yr((()=>import("./warp.html.674abb24.js")),[]).then((({data:e})=>e)),"v-7689d7f3":()=>Yr((()=>import("./transparent_proxy.html.bdb7098b.js")),[]).then((({data:e})=>e)),"v-3706649a":()=>Yr((()=>import("./404.html.7caa4353.js")),[]).then((({data:e})=>e))}),Zr=ht({key:"",path:"",title:"",lang:"",frontmatter:{},excerpt:"",headers:[]}),es=jt(Zr),ts=()=>es,ls=async e=>{const t=Jr.value[e];if(!t)return Zr;const l=await t();return null!=l?l:Zr};c.webpackHot&&(__VUE_HMR_RUNTIME__.updatePageData=e=>{Jr.value[e.key]=()=>Promise.resolve(e),e.key===es.value.key&&(es.value=e)});const ns=Symbol(""),os=()=>{const e=Kt(ns);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},is=e=>{const t=new Set,l=[];return e.forEach((e=>{const n=(([e,t,l])=>"meta"===e&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:"template"===e&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,l]))(e);t.has(n)||(t.add(n),l.push(e))})),l},rs=e=>/^(https?:)?\/\//.test(e),ss=e=>/^mailto:/.test(e),as=e=>/^tel:/.test(e),cs=e=>"[object Object]"===Object.prototype.toString.call(e),ds=e=>e.replace(/\/$/,""),us=e=>e.replace(/^\//,""),hs=(e,t)=>{const l=Object.keys(e).sort(((e,t)=>{const l=t.split("/").length-e.split("/").length;return 0!==l?l:t.length-e.length}));for(const n of l)if(t.startsWith(n))return n;return"/"},ps=Symbol(""),ms=Symbol(""),vs=Symbol(""),fs=Symbol(""),gs=()=>{const e=Kt(fs);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},_s=jt({base:"/Xray-docs-next/",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"}}}),bs=()=>_s;c.webpackHot&&(__VUE_HMR_RUNTIME__.updateSiteData=e=>{_s.value=e});const ys=Symbol(""),Es=()=>{const e=Kt(ys);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},xs=Symbol(""),js=()=>{const e=Xr(),t=(()=>{const e=Kt(ps);if(!e)throw new Error("usePageHead() is called without provider.");return e})(),l=(()=>{const e=Kt(vs);if(!e)throw new Error("usePageLang() is called without provider.");return e})(),n=jt([]),o=()=>{document.documentElement.lang=l.value,n.value.forEach((e=>{e.parentNode===document.head&&document.head.removeChild(e)})),n.value.splice(0,n.value.length),t.value.forEach((e=>{const t=Os(e);null!==t&&(document.head.appendChild(t),n.value.push(t))}))};Gt(xs,o),fl((()=>{t.value.forEach((e=>{const t=Ls(e);t&&n.value.push(t)})),o(),Ao((()=>e.path),(()=>o()))}))},Ls=([e,t,l=""])=>{const n=`head > ${e}${Object.entries(t).map((([e,t])=>V(t)?`[${e}="${t}"]`:!0===t?`[${e}]`:""))}`;return Array.from(document.querySelectorAll(n)).find((e=>e.innerText===l))||null},Os=([e,t,l])=>{if(!V(e))return null;const n=document.createElement(e);return cs(t)&&Object.entries(t).forEach((([e,t])=>{V(t)?n.setAttribute(e,t):!0===t&&n.setAttribute(e,"")})),V(l)&&n.appendChild(document.createTextNode(l)),n},ws=e=>{let t;if(e.pageKey)t=e.pageKey;else{t=ts().value.key}const l=Qr[t];return l?Vo(l):Vo("div","404 Not Found")};ws.displayName="Content",ws.props={pageKey:{type:String,required:!1}};const Ps=Vo("svg",{class:"icon outbound",xmlns:"http://www.w3.org/2000/svg",ariaHidden:"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"},[Vo("path",{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}),Vo("polygon",{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"})]),Ts=(e,{slots:t})=>{var l;return Vo("span",[Ps,null===(l=t.default)||void 0===l?void 0:l.call(t)])};Ts.displayName="OutboundLink";const ks={404:rl((()=>Yr((()=>import("./404.57a909a7.js")),[]))),Layout:rl((()=>Yr((()=>import("./Layout.5e6424a3.js")),[])))},As=ol({name:"Vuepress",setup(){const e=ts(),t=It((()=>{let t;if(e.value.path){const l=e.value.frontmatter.layout;t=V(l)?l:"Layout"}else t="404";return ks[t]||dn(t,!1)}));return()=>Vo(t.value)}}),Rs=e=>{if(rs(e))return e;return`${bs().value.base}${us(e)}`};var Ds=ol({props:{type:{type:String,required:!1,default:"tip"},text:{type:String,required:!1,default:""},vertical:{type:String,required:!1,default:void 0}},setup:e=>(t,l)=>(bn(),jn("span",{class:g(["badge",e.type]),style:p({verticalAlign:e.vertical})},[zn(t.$slots,"default",{},(()=>[In(_(e.text),1)]))],6))}),Is=ol({name:"CodeGroup",setup(e,{slots:t}){const l=jt(-1),n=jt([]),o=(e,t)=>{" "===e.key||"Enter"===e.key?(e.preventDefault(),l.value=t):"ArrowRight"===e.key?(e.preventDefault(),((e=l.value)=>{e{l.value=e>0?e-1:n.value.length-1,n.value[l.value].focus()})(t))};return()=>{var e;const i=((null===(e=t.default)||void 0===e?void 0:e.call(t))||[]).filter((e=>"CodeGroupItem"===e.type.name)).map((e=>(null===e.props&&(e.props={}),e)));return 0===i.length?null:(l.value<0||l.value>i.length-1?(l.value=i.findIndex((e=>""===e.props.active||!0===e.props.active)),-1===l.value&&(l.value=0)):i.forEach(((e,t)=>{e.props.active=t===l.value})),Vo("div",{class:"code-group"},[Vo("div",{class:"code-group__nav"},Vo("ul",{class:"code-group__ul"},i.map(((e,t)=>{const i=t===l.value;return Vo("li",{class:"code-group__li"},Vo("button",{ref:e=>{e&&(n.value[t]=e)},class:{"code-group__nav-tab":!0,"code-group__nav-tab-active":i},ariaPressed:i,ariaExpanded:i,onClick:()=>l.value=t,onKeydown:e=>o(e,t)},e.props.title))})))),i]))}}});const Ss=["aria-selected"],Vs=ol({name:"CodeGroupItem"});var Cs=ol(a(s({},Vs),{props:{title:{type:String,required:!0},active:{type:Boolean,required:!1,default:!1}},setup:function(e){return(t,l)=>(bn(),jn("div",{class:g(["code-group-item",{"code-group-item__active":e.active}]),"aria-selected":e.active},[zn(t.$slots,"default")],10,Ss))}}));function Fs(e){return!!te&&(function(e){te&&te.cleanups.push(e)}(e),!0)} +const gi="function"==typeof Symbol&&"symbol"==typeof Symbol.toStringTag,_i=e=>gi?Symbol(e):"_vr_"+e,bi=_i("rvlm"),yi=_i("rvd"),Ei=_i("r"),xi=_i("rl"),ji=_i("rvl"),Li="undefined"!=typeof window;const Oi=Object.assign;function wi(e,t){const l={};for(const n in t){const o=t[n];l[n]=Array.isArray(o)?o.map(e):e(o)}return l}let Pi=()=>{};const Ti=/\/$/;function ki(e,t,l="/"){let n,o={},i="",r="";const s=t.indexOf("?"),a=t.indexOf("#",s>-1?s:0);return s>-1&&(n=t.slice(0,s),i=t.slice(s+1,a>-1?a:t.length),o=e(i)),a>-1&&(n=n||t.slice(0,a),r=t.slice(a,t.length)),n=function(e,t){if(e.startsWith("/"))return e;if(!e)return t;const l=t.split("/"),n=e.split("/");let o,i,r=l.length-1;for(o=0;oe===t[l])):1===e.length&&e[0]===t}var Vi,Ci,Fi,Ni;function Mi(e){if(!e)if(Li){const t=document.querySelector("base");e=(e=t&&t.getAttribute("href")||"/").replace(/^\w+:\/\/[^\/]+/,"")}else e="/";return"/"!==e[0]&&"#"!==e[0]&&(e="/"+e),e.replace(Ti,"")}(Ci=Vi||(Vi={})).pop="pop",Ci.push="push",(Ni=Fi||(Fi={})).back="back",Ni.forward="forward",Ni.unknown="";const Hi=/^[^#]+#/;function zi(e,t){return e.replace(Hi,"#")+t}const Bi=()=>({left:window.pageXOffset,top:window.pageYOffset});function $i(e){let t;if("el"in e){let l=e.el;const n="string"==typeof l&&l.startsWith("#"),o="string"==typeof l?n?document.getElementById(l.slice(1)):document.querySelector(l):l;if(!o)return;t=function(e,t){const l=document.documentElement.getBoundingClientRect(),n=e.getBoundingClientRect();return{behavior:t.behavior,left:n.left-l.left-(t.left||0),top:n.top-l.top-(t.top||0)}}(o,e)}else t=e;"scrollBehavior"in document.documentElement.style?window.scrollTo(t):window.scrollTo(null!=t.left?t.left:window.pageXOffset,null!=t.top?t.top:window.pageYOffset)}function Wi(e,t){return(history.state?history.state.position-t:-1)+e}const Ui=new Map;function qi(e,t){const{pathname:l,search:n,hash:o}=t,i=e.indexOf("#");if(i>-1){let t=o.includes(e.slice(i))?e.slice(i).length:1,l=o.slice(t);return"/"!==l[0]&&(l="/"+l),Ai(l,"")}return Ai(l,e)+n+o}function Xi(e,t,l,n=!1,o=!1){return{back:e,current:t,forward:l,replaced:n,position:window.history.length,scroll:o?Bi():null}}function Gi(e){const{history:t,location:l}=window;let n={value:qi(e,l)},o={value:t.state};function i(n,i,r){const s=e.indexOf("#"),a=s>-1?(l.host&&document.querySelector("base")?e:e.slice(s))+n:location.protocol+"//"+location.host+e+n;try{t[r?"replaceState":"pushState"](i,"",a),o.value=i}catch(c){console.error(c),l[r?"replace":"assign"](a)}}return o.value||i(n.value,{back:null,current:n.value,forward:null,position:t.length-1,replaced:!0,scroll:null},!0),{location:n,state:o,push:function(e,l){const r=Oi({},o.value,t.state,{forward:e,scroll:Bi()});i(r.current,r,!0),i(e,Oi({},Xi(n.value,e,null),{position:r.position+1},l),!1),n.value=e},replace:function(e,l){i(e,Oi({},t.state,Xi(o.value.back,e,o.value.forward,!0),l,{position:o.value.position}),!0),n.value=e}}}function Ki(e){return"string"==typeof e||"symbol"==typeof e}const Yi={path:"/",name:void 0,params:{},query:{},hash:"",fullPath:"/",matched:[],meta:{},redirectedFrom:void 0},Qi=_i("nf");var Ji,Zi;function er(e,t){return Oi(new Error,{type:e,[Qi]:!0},t)}function tr(e,t){return e instanceof Error&&Qi in e&&(null==t||!!(e.type&t))}(Zi=Ji||(Ji={}))[Zi.aborted=4]="aborted",Zi[Zi.cancelled=8]="cancelled",Zi[Zi.duplicated=16]="duplicated";const lr={sensitive:!1,strict:!1,start:!0,end:!0},nr=/[.+*?^${}()[\]/\\]/g;function or(e,t){let l=0;for(;lt.length?1===t.length&&80===t[0]?1:-1:0}function ir(e,t){let l=0;const n=e.score,o=t.score;for(;l1&&("*"===s||"+"===s)&&t(`A repeatable param (${c}) must be alone in its segment. eg: '/:ids+.`),i.push({type:1,value:c,regexp:d,repeatable:"*"===s||"+"===s,optional:"*"===s||"?"===s})):t("Invalid state to consume buffer"),c="")}function h(){c+=s}for(;a{i(h)}:Pi}function i(e){if(Ki(e)){const t=n.get(e);t&&(n.delete(e),l.splice(l.indexOf(t),1),t.children.forEach(i),t.alias.forEach(i))}else{let t=l.indexOf(e);t>-1&&(l.splice(t,1),e.record.name&&n.delete(e.record.name),e.children.forEach(i),e.alias.forEach(i))}}function r(e){let t=0;for(;t=0;)t++;l.splice(t,0,e),e.record.name&&!ur(e)&&n.set(e.record.name,e)}return t=pr({strict:!1,end:!0,sensitive:!1},t),e.forEach((e=>o(e))),{addRoute:o,resolve:function(e,t){let o,i,r,s={};if("name"in e&&e.name){if(o=n.get(e.name),!o)throw er(1,{location:e});r=o.record.name,s=Oi(function(e,t){let l={};for(let n of t)n in e&&(l[n]=e[n]);return l}(t.params,o.keys.filter((e=>!e.optional)).map((e=>e.name))),e.params),i=o.stringify(s)}else if("path"in e)i=e.path,o=l.find((e=>e.re.test(i))),o&&(s=o.parse(i),r=o.record.name);else{if(o=t.name?n.get(t.name):l.find((e=>e.re.test(t.path))),!o)throw er(1,{location:e,currentLocation:t});r=o.record.name,s=Oi({},t.params,e.params),i=o.stringify(s)}const a=[];let c=o;for(;c;)a.unshift(c.record),c=c.parent;return{name:r,path:i,params:s,matched:a,meta:hr(a)}},removeRoute:i,getRoutes:function(){return l},getRecordMatcher:function(e){return n.get(e)}}}function dr(e){const t={},l=e.props||!1;if("component"in e)t.default=l;else for(let n in e.components)t[n]="boolean"==typeof l?l:l[n];return t}function ur(e){for(;e;){if(e.record.aliasOf)return!0;e=e.parent}return!1}function hr(e){return e.reduce(((e,t)=>Oi(e,t.meta)),{})}function pr(e,t){let l={};for(let n in e)l[n]=n in t?t[n]:e[n];return l}const mr=/#/g,vr=/&/g,fr=/\//g,gr=/=/g,_r=/\?/g,br=/\+/g,yr=/%5B/g,Er=/%5D/g,xr=/%5E/g,jr=/%60/g,Lr=/%7B/g,Or=/%7C/g,wr=/%7D/g,Pr=/%20/g;function Tr(e){return encodeURI(""+e).replace(Or,"|").replace(yr,"[").replace(Er,"]")}function kr(e){return Tr(e).replace(br,"%2B").replace(Pr,"+").replace(mr,"%23").replace(vr,"%26").replace(jr,"`").replace(Lr,"{").replace(wr,"}").replace(xr,"^")}function Ar(e){return function(e){return Tr(e).replace(mr,"%23").replace(_r,"%3F")}(e).replace(fr,"%2F")}function Rr(e){try{return decodeURIComponent(""+e)}catch(t){}return""+e}function Dr(e){const t={};if(""===e||"?"===e)return t;const l=("?"===e[0]?e.slice(1):e).split("&");for(let n=0;ne&&kr(e))):[n&&kr(n)]).forEach((e=>{void 0!==e&&(t+=(t.length?"&":"")+l,null!=e&&(t+="="+e))}))}return t}function Sr(e){const t={};for(let l in e){let n=e[l];void 0!==n&&(t[l]=Array.isArray(n)?n.map((e=>null==e?null:""+e)):null==n?n:""+n)}return t}function Vr(){let e=[];return{add:function(t){return e.push(t),()=>{const l=e.indexOf(t);l>-1&&e.splice(l,1)}},list:()=>e,reset:function(){e=[]}}}function Cr(e,t,l,n,o){const i=n&&(n.enterCallbacks[o]=n.enterCallbacks[o]||[]);return()=>new Promise(((r,s)=>{const a=e=>{var a;!1===e?s(er(4,{from:l,to:t})):e instanceof Error?s(e):"string"==typeof(a=e)||a&&"object"==typeof a?s(er(2,{from:t,to:e})):(i&&n.enterCallbacks[o]===i&&"function"==typeof e&&i.push(e),r())},c=e.call(n&&n.instances[o],t,l,a);let d=Promise.resolve(c);e.length<3&&(d=d.then(a)),d.catch((e=>s(e)))}))}function Fr(e,t,l,n){const o=[];for(const r of e)for(const e in r.components){let s=r.components[e];if("beforeRouteEnter"===t||r.instances[e])if("object"==typeof(i=s)||"displayName"in i||"props"in i||"__vccOpts"in i){const i=(s.__vccOpts||s)[t];i&&o.push(Cr(i,l,n,r,e))}else{let i=s();o.push((()=>i.then((o=>{if(!o)return Promise.reject(new Error(`Couldn't resolve component "${e}" at "${r.path}"`));const i=(s=o).__esModule||gi&&"Module"===s[Symbol.toStringTag]?o.default:o;var s;r.components[e]=i;const a=(i.__vccOpts||i)[t];return a&&Cr(a,l,n,r,e)()}))))}}var i;return o}function Nr(e){const t=Kt(Ei),l=Kt(xi),n=It((()=>t.resolve(wt(e.to)))),o=It((()=>{let{matched:e}=n.value,{length:t}=e;const o=e[t-1];let i=l.matched;if(!o||!i.length)return-1;let r=i.findIndex(Ri.bind(null,o));if(r>-1)return r;let s=Hr(e[t-2]);return t>1&&Hr(o)===s&&i[i.length-1].path!==s?i.findIndex(Ri.bind(null,e[t-2])):r})),i=It((()=>o.value>-1&&function(e,t){for(let l in t){let n=t[l],o=e[l];if("string"==typeof n){if(n!==o)return!1}else if(!Array.isArray(o)||o.length!==n.length||n.some(((e,t)=>e!==o[t])))return!1}return!0}(l.params,n.value.params))),r=It((()=>o.value>-1&&o.value===l.matched.length-1&&Di(l.params,n.value.params)));return{route:n,href:It((()=>n.value.href)),isActive:i,isExactActive:r,navigate:function(l={}){return function(e){if(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)return;if(e.defaultPrevented)return;if(void 0!==e.button&&0!==e.button)return;if(e.currentTarget&&e.currentTarget.getAttribute){const t=e.currentTarget.getAttribute("target");if(/\b_blank\b/i.test(t))return}e.preventDefault&&e.preventDefault();return!0}(l)?t[wt(e.replace)?"replace":"push"](wt(e.to)).catch(Pi):Promise.resolve()}}}const Mr=ol({name:"RouterLink",props:{to:{type:[String,Object],required:!0},replace:Boolean,activeClass:String,exactActiveClass:String,custom:Boolean,ariaCurrentValue:{type:String,default:"page"}},useLink:Nr,setup(e,{slots:t}){const l=ut(Nr(e)),{options:n}=Kt(Ei),o=It((()=>({[zr(e.activeClass,n.linkActiveClass,"router-link-active")]:l.isActive,[zr(e.exactActiveClass,n.linkExactActiveClass,"router-link-exact-active")]:l.isExactActive})));return()=>{const n=t.default&&t.default(l);return e.custom?n:Vo("a",{"aria-current":l.isExactActive?e.ariaCurrentValue:null,href:l.href,onClick:l.navigate,class:o.value},n)}}});function Hr(e){return e?e.aliasOf?e.aliasOf.path:e.path:""}const zr=(e,t,l)=>null!=e?e:null!=t?t:l;function Br(e,t){if(!e)return null;const l=e(t);return 1===l.length?l[0]:l}const $r=ol({name:"RouterView",inheritAttrs:!1,props:{name:{type:String,default:"default"},route:Object},setup(e,{attrs:t,slots:l}){const n=Kt(ji),o=It((()=>e.route||n.value)),i=Kt(yi,0),r=It((()=>o.value.matched[i]));Gt(yi,i+1),Gt(bi,r),Gt(ji,o);const s=jt();return Ao((()=>[s.value,r.value,e.name]),(([e,t,l],[n,o,i])=>{t&&(t.instances[l]=e,o&&o!==t&&e&&e===n&&(t.leaveGuards.size||(t.leaveGuards=o.leaveGuards),t.updateGuards.size||(t.updateGuards=o.updateGuards))),!e||!t||o&&Ri(t,o)&&n||(t.enterCallbacks[l]||[]).forEach((t=>t(e)))}),{flush:"post"}),()=>{const n=o.value,i=r.value,a=i&&i.components[e.name],c=e.name;if(!a)return Br(l.default,{Component:a,route:n});const d=i.props[e.name],u=d?!0===d?n.params:"function"==typeof d?d(n):d:null,h=Vo(a,Oi({},u,t,{onVnodeUnmounted:e=>{e.component.isUnmounted&&(i.instances[c]=null)},ref:s}));return Br(l.default,{Component:h,route:n})||h}}});function Wr(e){const t=cr(e.routes,e);let l=e.parseQuery||Dr,n=e.stringifyQuery||Ir,o=e.history;const i=Vr(),r=Vr(),s=Vr(),a=Ot(Yi,!0);let c=Yi;Li&&e.scrollBehavior&&"scrollRestoration"in history&&(history.scrollRestoration="manual");const d=wi.bind(null,(e=>""+e)),u=wi.bind(null,Ar),h=wi.bind(null,Rr);function p(e,i){if(i=Oi({},i||a.value),"string"==typeof e){let n=ki(l,e,i.path),r=t.resolve({path:n.path},i),s=o.createHref(n.fullPath);return Oi(n,r,{params:h(r.params),hash:Rr(n.hash),redirectedFrom:void 0,href:s})}let r;"path"in e?r=Oi({},e,{path:ki(l,e.path,i.path).path}):(r=Oi({},e,{params:u(e.params)}),i.params=u(i.params));let s=t.resolve(r,i);const c=e.hash||"";s.params=d(h(s.params));const p=function(e,t){let l=t.query?e(t.query):"";return t.path+(l&&"?")+l+(t.hash||"")}(n,Oi({},e,{hash:(m=c,Tr(m).replace(Lr,"{").replace(wr,"}").replace(xr,"^")),path:s.path}));var m;let v=o.createHref(p);return Oi({fullPath:p,hash:c,query:n===Ir?Sr(e.query):e.query},s,{redirectedFrom:void 0,href:v})}function m(e){return"string"==typeof e?ki(l,e,a.value.path):Oi({},e)}function v(e,t){if(c!==e)return er(8,{from:t,to:e})}function f(e){return _(e)}function g(e){const t=e.matched[e.matched.length-1];if(t&&t.redirect){const{redirect:l}=t;let n="function"==typeof l?l(e):l;return"string"==typeof n&&(n=n.includes("?")||n.includes("#")?n=m(n):{path:n},n.params={}),Oi({query:e.query,hash:e.hash,params:e.params},n)}}function _(e,t){const l=c=p(e),o=a.value,i=e.state,r=e.force,s=!0===e.replace,d=g(l);if(d)return _(Oi(m(d),{state:i,force:r,replace:s}),t||l);const u=l;let h;return u.redirectedFrom=t,!r&&function(e,t,l){let n=t.matched.length-1,o=l.matched.length-1;return n>-1&&n===o&&Ri(t.matched[n],l.matched[o])&&Di(t.params,l.params)&&e(t.query)===e(l.query)&&t.hash===l.hash}(n,o,l)&&(h=er(16,{to:u,from:o}),A(o,o,!0,!1)),(h?Promise.resolve(h):y(u,o)).catch((e=>tr(e)?e:T(e,u,o))).then((e=>{if(e){if(tr(e,2))return _(Oi(m(e.to),{state:i,force:r,replace:s}),t||u)}else e=x(u,o,!0,s,i);return E(u,o,e),e}))}function b(e,t){const l=v(e,t);return l?Promise.reject(l):Promise.resolve()}function y(e,t){let l;const[n,o,s]=function(e,t){const l=[],n=[],o=[],i=Math.max(t.matched.length,e.matched.length);for(let r=0;rRi(e,i)))?n.push(i):l.push(i));const s=e.matched[r];s&&(t.matched.find((e=>Ri(e,s)))||o.push(s))}return[l,n,o]}(e,t);l=Fr(n.reverse(),"beforeRouteLeave",e,t);for(const i of n)i.leaveGuards.forEach((n=>{l.push(Cr(n,e,t))}));const a=b.bind(null,e,t);return l.push(a),Ur(l).then((()=>{l=[];for(const n of i.list())l.push(Cr(n,e,t));return l.push(a),Ur(l)})).then((()=>{l=Fr(o,"beforeRouteUpdate",e,t);for(const n of o)n.updateGuards.forEach((n=>{l.push(Cr(n,e,t))}));return l.push(a),Ur(l)})).then((()=>{l=[];for(const n of e.matched)if(n.beforeEnter&&!t.matched.includes(n))if(Array.isArray(n.beforeEnter))for(const o of n.beforeEnter)l.push(Cr(o,e,t));else l.push(Cr(n.beforeEnter,e,t));return l.push(a),Ur(l)})).then((()=>(e.matched.forEach((e=>e.enterCallbacks={})),l=Fr(s,"beforeRouteEnter",e,t),l.push(a),Ur(l)))).then((()=>{l=[];for(const n of r.list())l.push(Cr(n,e,t));return l.push(a),Ur(l)})).catch((e=>tr(e,8)?e:Promise.reject(e)))}function E(e,t,l){for(const n of s.list())n(e,t,l)}function x(e,t,l,n,i){const r=v(e,t);if(r)return r;const s=t===Yi,c=Li?history.state:{};l&&(n||s?o.replace(e.fullPath,Oi({scroll:s&&c&&c.scroll},i)):o.push(e.fullPath,i)),a.value=e,A(e,t,l,s),k()}let j;function L(){j=o.listen(((e,t,l)=>{let n=p(e);const i=g(n);if(i)return void _(Oi(i,{replace:!0}),n).catch(Pi);c=n;const r=a.value;var s,d;Li&&(s=Wi(r.fullPath,l.delta),d=Bi(),Ui.set(s,d)),y(n,r).catch((e=>tr(e,12)?e:tr(e,2)?(_(e.to,n).then((e=>{tr(e,20)&&!l.delta&&l.type===Vi.pop&&o.go(-1,!1)})).catch(Pi),Promise.reject()):(l.delta&&o.go(-l.delta,!1),T(e,n,r)))).then((e=>{(e=e||x(n,r,!1))&&(l.delta?o.go(-l.delta,!1):l.type===Vi.pop&&tr(e,20)&&o.go(-1,!1)),E(n,r,e)})).catch(Pi)}))}let O,w=Vr(),P=Vr();function T(e,t,l){k(e);const n=P.list();return n.length?n.forEach((n=>n(e,t,l))):console.error(e),Promise.reject(e)}function k(e){O||(O=!0,L(),w.list().forEach((([t,l])=>e?l(e):t())),w.reset())}function A(t,l,n,o){const{scrollBehavior:i}=e;if(!Li||!i)return Promise.resolve();let r=!n&&function(e){const t=Ui.get(e);return Ui.delete(e),t}(Wi(t.fullPath,0))||(o||!n)&&history.state&&history.state.scroll||null;return Eo().then((()=>i(t,l,r))).then((e=>e&&$i(e))).catch((e=>T(e,t,l)))}const R=e=>o.go(e);let D;const I=new Set;return{currentRoute:a,addRoute:function(e,l){let n,o;return Ki(e)?(n=t.getRecordMatcher(e),o=l):o=e,t.addRoute(o,n)},removeRoute:function(e){let l=t.getRecordMatcher(e);l&&t.removeRoute(l)},hasRoute:function(e){return!!t.getRecordMatcher(e)},getRoutes:function(){return t.getRoutes().map((e=>e.record))},resolve:p,options:e,push:f,replace:function(e){return f(Oi(m(e),{replace:!0}))},go:R,back:()=>R(-1),forward:()=>R(1),beforeEach:i.add,beforeResolve:r.add,afterEach:s.add,onError:P.add,isReady:function(){return O&&a.value!==Yi?Promise.resolve():new Promise(((e,t)=>{w.add([e,t])}))},install(e){e.component("RouterLink",Mr),e.component("RouterView",$r),e.config.globalProperties.$router=this,Object.defineProperty(e.config.globalProperties,"$route",{enumerable:!0,get:()=>wt(a)}),Li&&!D&&a.value===Yi&&(D=!0,f(o.location).catch((e=>{})));const t={};for(let n in Yi)t[n]=It((()=>a.value[n]));e.provide(Ei,this),e.provide(xi,ut(t)),e.provide(ji,a);let l=e.unmount;I.add(e),e.unmount=function(){I.delete(e),I.size<1&&(j(),a.value=Yi,D=!1,O=!1),l()}}}}function Ur(e){return e.reduce(((e,t)=>e.then((()=>t()))),Promise.resolve())}function qr(){return Kt(Ei)}function Xr(){return Kt(xi)}const Gr=ol({setup(e,t){const l=jt(!1);return fl((()=>{l.value=!0})),()=>{var e,n;return l.value?null===(n=(e=t.slots).default)||void 0===n?void 0:n.call(e):null}}}),Kr={},Yr=function(e,t){return t&&0!==t.length?Promise.all(t.map((e=>{if((e=`/Xray-docs-next/${e}`)in Kr)return;Kr[e]=!0;const t=e.endsWith(".css"),l=t?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${e}"]${l}`))return;const n=document.createElement("link");return n.rel=t?"stylesheet":"modulepreload",t||(n.as="script",n.crossOrigin=""),n.href=e,document.head.appendChild(n),t?new Promise(((e,t)=>{n.addEventListener("load",e),n.addEventListener("error",t)})):void 0}))).then((()=>e())):e()},Qr={"v-8daa1a0e":rl((()=>Yr((()=>import("./index.html.5ad65f6a.js")),[]))),"v-aad48c6a":rl((()=>Yr((()=>import("./news.html.6f2f8a15.js")),[]))),"v-ba934fd8":rl((()=>Yr((()=>import("./index.html.c4382cba.js")),[]))),"v-41ade9da":rl((()=>Yr((()=>import("./api.html.dd27f4a2.js")),[]))),"v-83dedd38":rl((()=>Yr((()=>import("./dns.html.ed602061.js")),[]))),"v-192a19b9":rl((()=>Yr((()=>import("./fakedns.html.d7b0e008.js")),[]))),"v-7f6279d8":rl((()=>Yr((()=>import("./inbound.html.4ec3aef6.js")),[]))),"v-1d860c29":rl((()=>Yr((()=>import("./log.html.e629044e.js")),[]))),"v-2367d756":rl((()=>Yr((()=>import("./outbound.html.302f540c.js")),[]))),"v-4ebec35a":rl((()=>Yr((()=>import("./policy.html.0fdfc457.js")),[]))),"v-31b7756a":rl((()=>Yr((()=>import("./reverse.html.85bf9d1e.js")),[]))),"v-70677432":rl((()=>Yr((()=>import("./routing.html.8627aedb.js")),[]))),"v-7e21d6ae":rl((()=>Yr((()=>import("./stats.html.d7a6c7c1.js")),[]))),"v-e3dfff38":rl((()=>Yr((()=>import("./transport.html.8d4eb4bb.js")),[]))),"v-f7496066":rl((()=>Yr((()=>import("./index.html.27162517.js")),[]))),"v-36b1a79b":rl((()=>Yr((()=>import("./index.html.f6d047fe.js")),[]))),"v-09a64f89":rl((()=>Yr((()=>import("./command.html.431bc70f.js")),[]))),"v-2b1adf48":rl((()=>Yr((()=>import("./config.html.49585339.js")),[]))),"v-86ee963a":rl((()=>Yr((()=>import("./document.html.f914c675.js")),[]))),"v-0e5d7b39":rl((()=>Yr((()=>import("./install.html.b8e8854f.js")),[]))),"v-2d0a870d":rl((()=>Yr((()=>import("./index.html.fec1bfdb.js")),[]))),"v-0d714d87":rl((()=>Yr((()=>import("./browser_dialer.html.605666d3.js")),[]))),"v-0da7880a":rl((()=>Yr((()=>import("./env.html.dd8e636d.js")),[]))),"v-2aeb21f9":rl((()=>Yr((()=>import("./fallback.html.6b61b4aa.js")),[]))),"v-3acf20ea":rl((()=>Yr((()=>import("./multiple.html.6aacfcfe.js")),[]))),"v-792e28f8":rl((()=>Yr((()=>import("./xtls.html.599a8d69.js")),[]))),"v-b50d2334":rl((()=>Yr((()=>import("./dokodemo.html.fab4abcc.js")),[]))),"v-593408b0":rl((()=>Yr((()=>import("./http.html.01d77f27.js")),[]))),"v-802a842a":rl((()=>Yr((()=>import("./shadowsocks.html.4d363446.js")),[]))),"v-29995cea":rl((()=>Yr((()=>import("./socks.html.9102c266.js")),[]))),"v-2a1b3d72":rl((()=>Yr((()=>import("./trojan.html.33f7a35e.js")),[]))),"v-fb92e8aa":rl((()=>Yr((()=>import("./vless.html.42e5667a.js")),[]))),"v-167afaac":rl((()=>Yr((()=>import("./vmess.html.ed9311ef.js")),[]))),"v-749ad71a":rl((()=>Yr((()=>import("./blackhole.html.39e3071b.js")),[]))),"v-6d39b970":rl((()=>Yr((()=>import("./dns.html.6799dc2b.js")),[]))),"v-d76e893a":rl((()=>Yr((()=>import("./freedom.html.33bca468.js")),[]))),"v-c6b4b59e":rl((()=>Yr((()=>import("./http.html.10a7301c.js")),[]))),"v-7b293e4a":rl((()=>Yr((()=>import("./shadowsocks.html.7d51c0a6.js")),[]))),"v-15f5452a":rl((()=>Yr((()=>import("./socks.html.865647cc.js")),[]))),"v-5797bdb3":rl((()=>Yr((()=>import("./trojan.html.3b43a173.js")),[]))),"v-a60f016c":rl((()=>Yr((()=>import("./vless.html.b352d91c.js")),[]))),"v-413cee4b":rl((()=>Yr((()=>import("./vmess.html.ae1d1f20.js")),[]))),"v-208ca3b9":rl((()=>Yr((()=>import("./wireguard.html.51f49bce.js")),[]))),"v-775db7b1":rl((()=>Yr((()=>import("./domainsocket.html.00afb2a2.js")),[]))),"v-2877542a":rl((()=>Yr((()=>import("./grpc.html.8cee21b3.js")),[]))),"v-03a28284":rl((()=>Yr((()=>import("./h2.html.f3f21890.js")),[]))),"v-3167b1dd":rl((()=>Yr((()=>import("./mkcp.html.2fd0e63c.js")),[]))),"v-8f08dbec":rl((()=>Yr((()=>import("./quic.html.6ef35d12.js")),[]))),"v-33b1b709":rl((()=>Yr((()=>import("./tcp.html.f1af1bd1.js")),[]))),"v-1ff57bba":rl((()=>Yr((()=>import("./websocket.html.787efee2.js")),[]))),"v-6a9e8054":rl((()=>Yr((()=>import("./compile.html.3c9f7ee7.js")),[]))),"v-95e3eaea":rl((()=>Yr((()=>import("./design.html.ae406d25.js")),[]))),"v-61e7eea6":rl((()=>Yr((()=>import("./guide.html.b889797d.js")),[]))),"v-6e6c37e6":rl((()=>Yr((()=>import("./mkcp.html.cc07a53d.js")),[]))),"v-13168a21":rl((()=>Yr((()=>import("./muxcool.html.07864240.js")),[]))),"v-5c48c82b":rl((()=>Yr((()=>import("./vless.html.3960c3c0.js")),[]))),"v-1ee591a8":rl((()=>Yr((()=>import("./vmess.html.f1a5f655.js")),[]))),"v-3f09dcfa":rl((()=>Yr((()=>import("./index.html.00a37cb7.js")),[]))),"v-fb444906":rl((()=>Yr((()=>import("./ch01-preface.html.2015b6e6.js")),[]))),"v-075f3ae5":rl((()=>Yr((()=>import("./ch02-preparation.html.61783a98.js")),[]))),"v-726d0633":rl((()=>Yr((()=>import("./ch03-ssh.html.2e667ccb.js")),[]))),"v-430c6ab8":rl((()=>Yr((()=>import("./ch04-security.html.63f033f2.js")),[]))),"v-717c6376":rl((()=>Yr((()=>import("./ch05-webpage.html.86aeaf74.js")),[]))),"v-278039be":rl((()=>Yr((()=>import("./ch06-certificates.html.4582a562.js")),[]))),"v-a0c7f88e":rl((()=>Yr((()=>import("./ch07-xray-server.html.a49f5a08.js")),[]))),"v-86586ca2":rl((()=>Yr((()=>import("./ch08-xray-clients.html.7ce58dd3.js")),[]))),"v-3eb62514":rl((()=>Yr((()=>import("./ch09-appendix.html.f52297d2.js")),[]))),"v-3f09dcbc":rl((()=>Yr((()=>import("./index.html.b462ed8b.js")),[]))),"v-b21a2a20":rl((()=>Yr((()=>import("./fallbacks-lv1.html.792c6109.js")),[]))),"v-da623318":rl((()=>Yr((()=>import("./fallbacks-with-sni.html.fc031a4e.js")),[]))),"v-fdd722ac":rl((()=>Yr((()=>import("./routing-lv1-part1.html.3298296e.js")),[]))),"v-fa6d716e":rl((()=>Yr((()=>import("./routing-lv1-part2.html.0a7a2f7d.js")),[]))),"v-2f29e106":rl((()=>Yr((()=>import("./work.html.e38c21df.js")),[]))),"v-3f09dc7e":rl((()=>Yr((()=>import("./index.html.28e6f320.js")),[]))),"v-1c17916e":rl((()=>Yr((()=>import("./iptables_gid.html.edd50d36.js")),[]))),"v-a001cfa6":rl((()=>Yr((()=>import("./nginx_or_haproxy_tls_tunnel.html.bbed6a21.js")),[]))),"v-46333b48":rl((()=>Yr((()=>import("./redirect.html.18a443c9.js")),[]))),"v-338bc63e":rl((()=>Yr((()=>import("./tproxy.html.996e8483.js")),[]))),"v-d68f7d58":rl((()=>Yr((()=>import("./tproxy_ipv4_and_ipv6.html.1eefa00d.js")),[]))),"v-e533e2c6":rl((()=>Yr((()=>import("./traffic_stats.html.ff0f8489.js")),[]))),"v-1e465ab0":rl((()=>Yr((()=>import("./warp.html.f0c11712.js")),[]))),"v-1080fb37":rl((()=>Yr((()=>import("./news.html.8c2d830a.js")),[]))),"v-317fc580":rl((()=>Yr((()=>import("./index.html.7bcc5e57.js")),[]))),"v-45144c7f":rl((()=>Yr((()=>import("./api.html.a23d7a18.js")),[]))),"v-23fbd2d0":rl((()=>Yr((()=>import("./dns.html.11732ba6.js")),[]))),"v-2b7ec525":rl((()=>Yr((()=>import("./fakedns.html.52314130.js")),[]))),"v-5ab92300":rl((()=>Yr((()=>import("./inbound.html.fbcacc5d.js")),[]))),"v-f91d64d6":rl((()=>Yr((()=>import("./log.html.68e32d8e.js")),[]))),"v-268cd669":rl((()=>Yr((()=>import("./outbound.html.9d0f168f.js")),[]))),"v-4492d567":rl((()=>Yr((()=>import("./policy.html.f498427e.js")),[]))),"v-0d0e1e92":rl((()=>Yr((()=>import("./reverse.html.f7674b35.js")),[]))),"v-4bbe1d5a":rl((()=>Yr((()=>import("./routing.html.69e2dbb3.js")),[]))),"v-16426d1a":rl((()=>Yr((()=>import("./stats.html.fb81d901.js")),[]))),"v-5de780d0":rl((()=>Yr((()=>import("./transport.html.cd444c5b.js")),[]))),"v-f88d343e":rl((()=>Yr((()=>import("./index.html.3fde6881.js")),[]))),"v-38d56a07":rl((()=>Yr((()=>import("./index.html.92468ffc.js")),[]))),"v-4d046016":rl((()=>Yr((()=>import("./command.html.1ff61964.js")),[]))),"v-22b35270":rl((()=>Yr((()=>import("./config.html.a0df4771.js")),[]))),"v-30bd7c12":rl((()=>Yr((()=>import("./document.html.510dc533.js")),[]))),"v-439608b6":rl((()=>Yr((()=>import("./install.html.a5399da3.js")),[]))),"v-51a51d87":rl((()=>Yr((()=>import("./transparent_proxy.html.46362529.js")),[]))),"v-76b9a0f3":rl((()=>Yr((()=>import("./browser_dialer.html.3fd4af39.js")),[]))),"v-565dbfc4":rl((()=>Yr((()=>import("./env.html.a8947df8.js")),[]))),"v-0fbd1336":rl((()=>Yr((()=>import("./fallback.html.efcedcbf.js")),[]))),"v-a0627812":rl((()=>Yr((()=>import("./multiple.html.125c909a.js")),[]))),"v-d190d938":rl((()=>Yr((()=>import("./xtls.html.e5294d93.js")),[]))),"v-72afc2d2":rl((()=>Yr((()=>import("./dokodemo.html.d7b30331.js")),[]))),"v-773d731c":rl((()=>Yr((()=>import("./http.html.5bafed99.js")),[]))),"v-f555fc02":rl((()=>Yr((()=>import("./shadowsocks.html.0b42deea.js")),[]))),"v-e35196c2":rl((()=>Yr((()=>import("./socks.html.1c6a0f4e.js")),[]))),"v-29188644":rl((()=>Yr((()=>import("./trojan.html.ab92c9a7.js")),[]))),"v-255a6ebf":rl((()=>Yr((()=>import("./vless.html.f8dace8d.js")),[]))),"v-8cc24480":rl((()=>Yr((()=>import("./vmess.html.ee639091.js")),[]))),"v-64e47ef4":rl((()=>Yr((()=>import("./blackhole.html.408848fe.js")),[]))),"v-e979b848":rl((()=>Yr((()=>import("./dns.html.c21ef586.js")),[]))),"v-617f0fcf":rl((()=>Yr((()=>import("./freedom.html.2e43ea4a.js")),[]))),"v-3fc98845":rl((()=>Yr((()=>import("./http.html.a27f6c1c.js")),[]))),"v-63077cb6":rl((()=>Yr((()=>import("./shadowsocks.html.3fe3d4ee.js")),[]))),"v-516476d4":rl((()=>Yr((()=>import("./socks.html.8f599494.js")),[]))),"v-7d61a872":rl((()=>Yr((()=>import("./trojan.html.3b3e33ec.js")),[]))),"v-6e50feb6":rl((()=>Yr((()=>import("./vless.html.abebf13e.js")),[]))),"v-02956db7":rl((()=>Yr((()=>import("./vmess.html.66039f47.js")),[]))),"v-797f8d25":rl((()=>Yr((()=>import("./wireguard.html.d26b82d9.js")),[]))),"v-3eb3e9c6":rl((()=>Yr((()=>import("./domainsocket.html.77773eed.js")),[]))),"v-2c6058d4":rl((()=>Yr((()=>import("./grpc.html.7c965f05.js")),[]))),"v-1c38292a":rl((()=>Yr((()=>import("./h2.html.cb11d7f7.js")),[]))),"v-1a7f9d6e":rl((()=>Yr((()=>import("./mkcp.html.afc1ad80.js")),[]))),"v-79d41176":rl((()=>Yr((()=>import("./quic.html.d388262c.js")),[]))),"v-5254cbc6":rl((()=>Yr((()=>import("./tcp.html.6bfdc869.js")),[]))),"v-9520f392":rl((()=>Yr((()=>import("./websocket.html.fa0466ec.js")),[]))),"v-b7760e2c":rl((()=>Yr((()=>import("./compile.html.64f2baf9.js")),[]))),"v-fb774212":rl((()=>Yr((()=>import("./design.html.88638fc8.js")),[]))),"v-38c376c1":rl((()=>Yr((()=>import("./guide.html.98d180f2.js")),[]))),"v-21bccd79":rl((()=>Yr((()=>import("./mkcp.html.500d7909.js")),[]))),"v-27001935":rl((()=>Yr((()=>import("./muxcool.html.f1872cc3.js")),[]))),"v-21b30c3f":rl((()=>Yr((()=>import("./vless.html.37dc66c1.js")),[]))),"v-94110980":rl((()=>Yr((()=>import("./vmess.html.e111b233.js")),[]))),"v-789ba7ef":rl((()=>Yr((()=>import("./index.html.5cc51c88.js")),[]))),"v-d3712ade":rl((()=>Yr((()=>import("./ch01-preface.html.c3c719d6.js")),[]))),"v-41f9c00e":rl((()=>Yr((()=>import("./ch02-preparation.html.de2666c3.js")),[]))),"v-4c013f47":rl((()=>Yr((()=>import("./ch03-ssh.html.65537063.js")),[]))),"v-a75683b8":rl((()=>Yr((()=>import("./ch04-security.html.099c9936.js")),[]))),"v-f5341aec":rl((()=>Yr((()=>import("./ch05-webpage.html.cd12795a.js")),[]))),"v-4458f72a":rl((()=>Yr((()=>import("./ch06-certificates.html.4036e92b.js")),[]))),"v-f1802e66":rl((()=>Yr((()=>import("./ch07-xray-server.html.af443c4d.js")),[]))),"v-4ca6f1ca":rl((()=>Yr((()=>import("./ch08-xray-clients.html.a6c845bc.js")),[]))),"v-b0030f00":rl((()=>Yr((()=>import("./ch09-appendix.html.6e67299d.js")),[]))),"v-789ba80e":rl((()=>Yr((()=>import("./index.html.eaff5f8e.js")),[]))),"v-103b3e5c":rl((()=>Yr((()=>import("./fallbacks-lv1.html.35d8f45b.js")),[]))),"v-110dd688":rl((()=>Yr((()=>import("./fallbacks-with-sni.html.b7c3a701.js")),[]))),"v-c425a7d4":rl((()=>Yr((()=>import("./routing-lv1-part1.html.5b85fc64.js")),[]))),"v-c0bbf696":rl((()=>Yr((()=>import("./routing-lv1-part2.html.c02655ca.js")),[]))),"v-5b6477cc":rl((()=>Yr((()=>import("./work.html.8cd6df61.js")),[]))),"v-789ba82d":rl((()=>Yr((()=>import("./index.html.69a05f19.js")),[]))),"v-05ddc65d":rl((()=>Yr((()=>import("./iptables_gid.html.5d9991f3.js")),[]))),"v-1f3a890a":rl((()=>Yr((()=>import("./nginx_tls_tunnel.html.2bd19916.js")),[]))),"v-930ac920":rl((()=>Yr((()=>import("./redirect.html.e4ae70df.js")),[]))),"v-c579975c":rl((()=>Yr((()=>import("./tproxy.html.5b84c4de.js")),[]))),"v-7efb7c68":rl((()=>Yr((()=>import("./tproxy_ipv4_and_ipv6.html.05f651ce.js")),[]))),"v-12a33bee":rl((()=>Yr((()=>import("./traffic_stats.html.28cb5cac.js")),[]))),"v-7d2b8478":rl((()=>Yr((()=>import("./warp.html.63d5102a.js")),[]))),"v-7689d7f3":rl((()=>Yr((()=>import("./transparent_proxy.html.aa464a57.js")),[]))),"v-3706649a":rl((()=>Yr((()=>import("./404.html.c3886853.js")),[])))},Jr=jt({"v-8daa1a0e":()=>Yr((()=>import("./index.html.c788a269.js")),[]).then((({data:e})=>e)),"v-aad48c6a":()=>Yr((()=>import("./news.html.f9558a56.js")),[]).then((({data:e})=>e)),"v-ba934fd8":()=>Yr((()=>import("./index.html.356803e9.js")),[]).then((({data:e})=>e)),"v-41ade9da":()=>Yr((()=>import("./api.html.40e8e214.js")),[]).then((({data:e})=>e)),"v-83dedd38":()=>Yr((()=>import("./dns.html.38d154e3.js")),[]).then((({data:e})=>e)),"v-192a19b9":()=>Yr((()=>import("./fakedns.html.72fc9554.js")),[]).then((({data:e})=>e)),"v-7f6279d8":()=>Yr((()=>import("./inbound.html.c4089bc7.js")),[]).then((({data:e})=>e)),"v-1d860c29":()=>Yr((()=>import("./log.html.54ad11e6.js")),[]).then((({data:e})=>e)),"v-2367d756":()=>Yr((()=>import("./outbound.html.41f06bd9.js")),[]).then((({data:e})=>e)),"v-4ebec35a":()=>Yr((()=>import("./policy.html.a228a213.js")),[]).then((({data:e})=>e)),"v-31b7756a":()=>Yr((()=>import("./reverse.html.430928ac.js")),[]).then((({data:e})=>e)),"v-70677432":()=>Yr((()=>import("./routing.html.43f06e05.js")),[]).then((({data:e})=>e)),"v-7e21d6ae":()=>Yr((()=>import("./stats.html.8ff59a03.js")),[]).then((({data:e})=>e)),"v-e3dfff38":()=>Yr((()=>import("./transport.html.15ed80be.js")),[]).then((({data:e})=>e)),"v-f7496066":()=>Yr((()=>import("./index.html.c2745ef7.js")),[]).then((({data:e})=>e)),"v-36b1a79b":()=>Yr((()=>import("./index.html.c2db9566.js")),[]).then((({data:e})=>e)),"v-09a64f89":()=>Yr((()=>import("./command.html.dc4b563a.js")),[]).then((({data:e})=>e)),"v-2b1adf48":()=>Yr((()=>import("./config.html.1815b253.js")),[]).then((({data:e})=>e)),"v-86ee963a":()=>Yr((()=>import("./document.html.a886c958.js")),[]).then((({data:e})=>e)),"v-0e5d7b39":()=>Yr((()=>import("./install.html.a9b4d86f.js")),[]).then((({data:e})=>e)),"v-2d0a870d":()=>Yr((()=>import("./index.html.6e4b8ecc.js")),[]).then((({data:e})=>e)),"v-0d714d87":()=>Yr((()=>import("./browser_dialer.html.38332fbb.js")),[]).then((({data:e})=>e)),"v-0da7880a":()=>Yr((()=>import("./env.html.d6ae65f9.js")),[]).then((({data:e})=>e)),"v-2aeb21f9":()=>Yr((()=>import("./fallback.html.742cf950.js")),[]).then((({data:e})=>e)),"v-3acf20ea":()=>Yr((()=>import("./multiple.html.782a2f36.js")),[]).then((({data:e})=>e)),"v-792e28f8":()=>Yr((()=>import("./xtls.html.d7e41b35.js")),[]).then((({data:e})=>e)),"v-b50d2334":()=>Yr((()=>import("./dokodemo.html.eea3d70d.js")),[]).then((({data:e})=>e)),"v-593408b0":()=>Yr((()=>import("./http.html.24945aae.js")),[]).then((({data:e})=>e)),"v-802a842a":()=>Yr((()=>import("./shadowsocks.html.e4531595.js")),[]).then((({data:e})=>e)),"v-29995cea":()=>Yr((()=>import("./socks.html.07c0cbb9.js")),[]).then((({data:e})=>e)),"v-2a1b3d72":()=>Yr((()=>import("./trojan.html.3092bf11.js")),[]).then((({data:e})=>e)),"v-fb92e8aa":()=>Yr((()=>import("./vless.html.f0b06754.js")),[]).then((({data:e})=>e)),"v-167afaac":()=>Yr((()=>import("./vmess.html.c6a1f9a1.js")),[]).then((({data:e})=>e)),"v-749ad71a":()=>Yr((()=>import("./blackhole.html.22494a95.js")),[]).then((({data:e})=>e)),"v-6d39b970":()=>Yr((()=>import("./dns.html.a6a56076.js")),[]).then((({data:e})=>e)),"v-d76e893a":()=>Yr((()=>import("./freedom.html.74f209a8.js")),[]).then((({data:e})=>e)),"v-c6b4b59e":()=>Yr((()=>import("./http.html.4bea36d9.js")),[]).then((({data:e})=>e)),"v-7b293e4a":()=>Yr((()=>import("./shadowsocks.html.0e8489f1.js")),[]).then((({data:e})=>e)),"v-15f5452a":()=>Yr((()=>import("./socks.html.ed5a9909.js")),[]).then((({data:e})=>e)),"v-5797bdb3":()=>Yr((()=>import("./trojan.html.adccf10f.js")),[]).then((({data:e})=>e)),"v-a60f016c":()=>Yr((()=>import("./vless.html.38e231a4.js")),[]).then((({data:e})=>e)),"v-413cee4b":()=>Yr((()=>import("./vmess.html.98bee5e8.js")),[]).then((({data:e})=>e)),"v-208ca3b9":()=>Yr((()=>import("./wireguard.html.dfa986c4.js")),[]).then((({data:e})=>e)),"v-775db7b1":()=>Yr((()=>import("./domainsocket.html.89d6a091.js")),[]).then((({data:e})=>e)),"v-2877542a":()=>Yr((()=>import("./grpc.html.e1e71a0c.js")),[]).then((({data:e})=>e)),"v-03a28284":()=>Yr((()=>import("./h2.html.667edbec.js")),[]).then((({data:e})=>e)),"v-3167b1dd":()=>Yr((()=>import("./mkcp.html.67fa5670.js")),[]).then((({data:e})=>e)),"v-8f08dbec":()=>Yr((()=>import("./quic.html.0b4ad469.js")),[]).then((({data:e})=>e)),"v-33b1b709":()=>Yr((()=>import("./tcp.html.c8dc480d.js")),[]).then((({data:e})=>e)),"v-1ff57bba":()=>Yr((()=>import("./websocket.html.1b681c57.js")),[]).then((({data:e})=>e)),"v-6a9e8054":()=>Yr((()=>import("./compile.html.c3dc2a7c.js")),[]).then((({data:e})=>e)),"v-95e3eaea":()=>Yr((()=>import("./design.html.fd048cfc.js")),[]).then((({data:e})=>e)),"v-61e7eea6":()=>Yr((()=>import("./guide.html.8400f750.js")),[]).then((({data:e})=>e)),"v-6e6c37e6":()=>Yr((()=>import("./mkcp.html.53c0886d.js")),[]).then((({data:e})=>e)),"v-13168a21":()=>Yr((()=>import("./muxcool.html.dc6e68e8.js")),[]).then((({data:e})=>e)),"v-5c48c82b":()=>Yr((()=>import("./vless.html.f2fb691f.js")),[]).then((({data:e})=>e)),"v-1ee591a8":()=>Yr((()=>import("./vmess.html.a9f36c59.js")),[]).then((({data:e})=>e)),"v-3f09dcfa":()=>Yr((()=>import("./index.html.87401658.js")),[]).then((({data:e})=>e)),"v-fb444906":()=>Yr((()=>import("./ch01-preface.html.37dc3cd3.js")),[]).then((({data:e})=>e)),"v-075f3ae5":()=>Yr((()=>import("./ch02-preparation.html.45e9207b.js")),[]).then((({data:e})=>e)),"v-726d0633":()=>Yr((()=>import("./ch03-ssh.html.3fa8504d.js")),[]).then((({data:e})=>e)),"v-430c6ab8":()=>Yr((()=>import("./ch04-security.html.cc2fdeeb.js")),[]).then((({data:e})=>e)),"v-717c6376":()=>Yr((()=>import("./ch05-webpage.html.02dee46d.js")),[]).then((({data:e})=>e)),"v-278039be":()=>Yr((()=>import("./ch06-certificates.html.89e63f79.js")),[]).then((({data:e})=>e)),"v-a0c7f88e":()=>Yr((()=>import("./ch07-xray-server.html.988d5515.js")),[]).then((({data:e})=>e)),"v-86586ca2":()=>Yr((()=>import("./ch08-xray-clients.html.246315b3.js")),[]).then((({data:e})=>e)),"v-3eb62514":()=>Yr((()=>import("./ch09-appendix.html.4f965f95.js")),[]).then((({data:e})=>e)),"v-3f09dcbc":()=>Yr((()=>import("./index.html.5d677cbc.js")),[]).then((({data:e})=>e)),"v-b21a2a20":()=>Yr((()=>import("./fallbacks-lv1.html.be80d8f5.js")),[]).then((({data:e})=>e)),"v-da623318":()=>Yr((()=>import("./fallbacks-with-sni.html.47a2e02c.js")),[]).then((({data:e})=>e)),"v-fdd722ac":()=>Yr((()=>import("./routing-lv1-part1.html.92572603.js")),[]).then((({data:e})=>e)),"v-fa6d716e":()=>Yr((()=>import("./routing-lv1-part2.html.dabc417b.js")),[]).then((({data:e})=>e)),"v-2f29e106":()=>Yr((()=>import("./work.html.a41354d6.js")),[]).then((({data:e})=>e)),"v-3f09dc7e":()=>Yr((()=>import("./index.html.ffeb6e40.js")),[]).then((({data:e})=>e)),"v-1c17916e":()=>Yr((()=>import("./iptables_gid.html.f6e26ba6.js")),[]).then((({data:e})=>e)),"v-a001cfa6":()=>Yr((()=>import("./nginx_or_haproxy_tls_tunnel.html.d422e6ac.js")),[]).then((({data:e})=>e)),"v-46333b48":()=>Yr((()=>import("./redirect.html.4edfdf11.js")),[]).then((({data:e})=>e)),"v-338bc63e":()=>Yr((()=>import("./tproxy.html.593c73b0.js")),[]).then((({data:e})=>e)),"v-d68f7d58":()=>Yr((()=>import("./tproxy_ipv4_and_ipv6.html.a4e9bb74.js")),[]).then((({data:e})=>e)),"v-e533e2c6":()=>Yr((()=>import("./traffic_stats.html.39b9a5e7.js")),[]).then((({data:e})=>e)),"v-1e465ab0":()=>Yr((()=>import("./warp.html.07b2efe6.js")),[]).then((({data:e})=>e)),"v-1080fb37":()=>Yr((()=>import("./news.html.b4a0ef66.js")),[]).then((({data:e})=>e)),"v-317fc580":()=>Yr((()=>import("./index.html.b138225e.js")),[]).then((({data:e})=>e)),"v-45144c7f":()=>Yr((()=>import("./api.html.80463963.js")),[]).then((({data:e})=>e)),"v-23fbd2d0":()=>Yr((()=>import("./dns.html.cf7c003a.js")),[]).then((({data:e})=>e)),"v-2b7ec525":()=>Yr((()=>import("./fakedns.html.2978776b.js")),[]).then((({data:e})=>e)),"v-5ab92300":()=>Yr((()=>import("./inbound.html.0d185e80.js")),[]).then((({data:e})=>e)),"v-f91d64d6":()=>Yr((()=>import("./log.html.a903a70e.js")),[]).then((({data:e})=>e)),"v-268cd669":()=>Yr((()=>import("./outbound.html.3948e8de.js")),[]).then((({data:e})=>e)),"v-4492d567":()=>Yr((()=>import("./policy.html.6d7c5ab9.js")),[]).then((({data:e})=>e)),"v-0d0e1e92":()=>Yr((()=>import("./reverse.html.a08c2a40.js")),[]).then((({data:e})=>e)),"v-4bbe1d5a":()=>Yr((()=>import("./routing.html.a3a78f6c.js")),[]).then((({data:e})=>e)),"v-16426d1a":()=>Yr((()=>import("./stats.html.1b6dc06a.js")),[]).then((({data:e})=>e)),"v-5de780d0":()=>Yr((()=>import("./transport.html.4bcccfcf.js")),[]).then((({data:e})=>e)),"v-f88d343e":()=>Yr((()=>import("./index.html.84ca1edb.js")),[]).then((({data:e})=>e)),"v-38d56a07":()=>Yr((()=>import("./index.html.fb5a3e20.js")),[]).then((({data:e})=>e)),"v-4d046016":()=>Yr((()=>import("./command.html.1a4ac829.js")),[]).then((({data:e})=>e)),"v-22b35270":()=>Yr((()=>import("./config.html.08447352.js")),[]).then((({data:e})=>e)),"v-30bd7c12":()=>Yr((()=>import("./document.html.35272d77.js")),[]).then((({data:e})=>e)),"v-439608b6":()=>Yr((()=>import("./install.html.cafc1ef5.js")),[]).then((({data:e})=>e)),"v-51a51d87":()=>Yr((()=>import("./transparent_proxy.html.3615c2f2.js")),[]).then((({data:e})=>e)),"v-76b9a0f3":()=>Yr((()=>import("./browser_dialer.html.db4821df.js")),[]).then((({data:e})=>e)),"v-565dbfc4":()=>Yr((()=>import("./env.html.09553594.js")),[]).then((({data:e})=>e)),"v-0fbd1336":()=>Yr((()=>import("./fallback.html.ad8d7190.js")),[]).then((({data:e})=>e)),"v-a0627812":()=>Yr((()=>import("./multiple.html.02688a34.js")),[]).then((({data:e})=>e)),"v-d190d938":()=>Yr((()=>import("./xtls.html.876f1046.js")),[]).then((({data:e})=>e)),"v-72afc2d2":()=>Yr((()=>import("./dokodemo.html.9106219e.js")),[]).then((({data:e})=>e)),"v-773d731c":()=>Yr((()=>import("./http.html.4c95e93b.js")),[]).then((({data:e})=>e)),"v-f555fc02":()=>Yr((()=>import("./shadowsocks.html.93f2c8b8.js")),[]).then((({data:e})=>e)),"v-e35196c2":()=>Yr((()=>import("./socks.html.faac7ded.js")),[]).then((({data:e})=>e)),"v-29188644":()=>Yr((()=>import("./trojan.html.0d637f0d.js")),[]).then((({data:e})=>e)),"v-255a6ebf":()=>Yr((()=>import("./vless.html.42408db4.js")),[]).then((({data:e})=>e)),"v-8cc24480":()=>Yr((()=>import("./vmess.html.91da1a1a.js")),[]).then((({data:e})=>e)),"v-64e47ef4":()=>Yr((()=>import("./blackhole.html.1aa4fc91.js")),[]).then((({data:e})=>e)),"v-e979b848":()=>Yr((()=>import("./dns.html.f6ce6986.js")),[]).then((({data:e})=>e)),"v-617f0fcf":()=>Yr((()=>import("./freedom.html.874e8ef6.js")),[]).then((({data:e})=>e)),"v-3fc98845":()=>Yr((()=>import("./http.html.9e441e87.js")),[]).then((({data:e})=>e)),"v-63077cb6":()=>Yr((()=>import("./shadowsocks.html.4780f083.js")),[]).then((({data:e})=>e)),"v-516476d4":()=>Yr((()=>import("./socks.html.8faf26dd.js")),[]).then((({data:e})=>e)),"v-7d61a872":()=>Yr((()=>import("./trojan.html.7aaa430f.js")),[]).then((({data:e})=>e)),"v-6e50feb6":()=>Yr((()=>import("./vless.html.2daf326e.js")),[]).then((({data:e})=>e)),"v-02956db7":()=>Yr((()=>import("./vmess.html.f64535f2.js")),[]).then((({data:e})=>e)),"v-797f8d25":()=>Yr((()=>import("./wireguard.html.3b999598.js")),[]).then((({data:e})=>e)),"v-3eb3e9c6":()=>Yr((()=>import("./domainsocket.html.e3adec3f.js")),[]).then((({data:e})=>e)),"v-2c6058d4":()=>Yr((()=>import("./grpc.html.f962b1ef.js")),[]).then((({data:e})=>e)),"v-1c38292a":()=>Yr((()=>import("./h2.html.e80e30c6.js")),[]).then((({data:e})=>e)),"v-1a7f9d6e":()=>Yr((()=>import("./mkcp.html.195416a2.js")),[]).then((({data:e})=>e)),"v-79d41176":()=>Yr((()=>import("./quic.html.65ba1f39.js")),[]).then((({data:e})=>e)),"v-5254cbc6":()=>Yr((()=>import("./tcp.html.2fad4214.js")),[]).then((({data:e})=>e)),"v-9520f392":()=>Yr((()=>import("./websocket.html.cf4ddf8f.js")),[]).then((({data:e})=>e)),"v-b7760e2c":()=>Yr((()=>import("./compile.html.e6e475b5.js")),[]).then((({data:e})=>e)),"v-fb774212":()=>Yr((()=>import("./design.html.02ca2fb4.js")),[]).then((({data:e})=>e)),"v-38c376c1":()=>Yr((()=>import("./guide.html.a623f5ad.js")),[]).then((({data:e})=>e)),"v-21bccd79":()=>Yr((()=>import("./mkcp.html.57deee5f.js")),[]).then((({data:e})=>e)),"v-27001935":()=>Yr((()=>import("./muxcool.html.c406cf07.js")),[]).then((({data:e})=>e)),"v-21b30c3f":()=>Yr((()=>import("./vless.html.c6271d36.js")),[]).then((({data:e})=>e)),"v-94110980":()=>Yr((()=>import("./vmess.html.02556ac3.js")),[]).then((({data:e})=>e)),"v-789ba7ef":()=>Yr((()=>import("./index.html.071d4e5f.js")),[]).then((({data:e})=>e)),"v-d3712ade":()=>Yr((()=>import("./ch01-preface.html.68893a38.js")),[]).then((({data:e})=>e)),"v-41f9c00e":()=>Yr((()=>import("./ch02-preparation.html.1b7e03b5.js")),[]).then((({data:e})=>e)),"v-4c013f47":()=>Yr((()=>import("./ch03-ssh.html.c40cdbd4.js")),[]).then((({data:e})=>e)),"v-a75683b8":()=>Yr((()=>import("./ch04-security.html.9e3de46f.js")),[]).then((({data:e})=>e)),"v-f5341aec":()=>Yr((()=>import("./ch05-webpage.html.27d4adb3.js")),[]).then((({data:e})=>e)),"v-4458f72a":()=>Yr((()=>import("./ch06-certificates.html.836a5fbb.js")),[]).then((({data:e})=>e)),"v-f1802e66":()=>Yr((()=>import("./ch07-xray-server.html.d944ec1b.js")),[]).then((({data:e})=>e)),"v-4ca6f1ca":()=>Yr((()=>import("./ch08-xray-clients.html.aaa57d66.js")),[]).then((({data:e})=>e)),"v-b0030f00":()=>Yr((()=>import("./ch09-appendix.html.0dd8a94d.js")),[]).then((({data:e})=>e)),"v-789ba80e":()=>Yr((()=>import("./index.html.f21c5745.js")),[]).then((({data:e})=>e)),"v-103b3e5c":()=>Yr((()=>import("./fallbacks-lv1.html.11b08b9f.js")),[]).then((({data:e})=>e)),"v-110dd688":()=>Yr((()=>import("./fallbacks-with-sni.html.6d67e52b.js")),[]).then((({data:e})=>e)),"v-c425a7d4":()=>Yr((()=>import("./routing-lv1-part1.html.3d780830.js")),[]).then((({data:e})=>e)),"v-c0bbf696":()=>Yr((()=>import("./routing-lv1-part2.html.4c286c2d.js")),[]).then((({data:e})=>e)),"v-5b6477cc":()=>Yr((()=>import("./work.html.8f09f9fb.js")),[]).then((({data:e})=>e)),"v-789ba82d":()=>Yr((()=>import("./index.html.8d58f27b.js")),[]).then((({data:e})=>e)),"v-05ddc65d":()=>Yr((()=>import("./iptables_gid.html.fe8e2788.js")),[]).then((({data:e})=>e)),"v-1f3a890a":()=>Yr((()=>import("./nginx_tls_tunnel.html.64038300.js")),[]).then((({data:e})=>e)),"v-930ac920":()=>Yr((()=>import("./redirect.html.bafbe2e7.js")),[]).then((({data:e})=>e)),"v-c579975c":()=>Yr((()=>import("./tproxy.html.35dfa677.js")),[]).then((({data:e})=>e)),"v-7efb7c68":()=>Yr((()=>import("./tproxy_ipv4_and_ipv6.html.5fe5f9e8.js")),[]).then((({data:e})=>e)),"v-12a33bee":()=>Yr((()=>import("./traffic_stats.html.a3ddd4d1.js")),[]).then((({data:e})=>e)),"v-7d2b8478":()=>Yr((()=>import("./warp.html.674abb24.js")),[]).then((({data:e})=>e)),"v-7689d7f3":()=>Yr((()=>import("./transparent_proxy.html.bdb7098b.js")),[]).then((({data:e})=>e)),"v-3706649a":()=>Yr((()=>import("./404.html.7caa4353.js")),[]).then((({data:e})=>e))}),Zr=ht({key:"",path:"",title:"",lang:"",frontmatter:{},excerpt:"",headers:[]}),es=jt(Zr),ts=()=>es,ls=async e=>{const t=Jr.value[e];if(!t)return Zr;const l=await t();return null!=l?l:Zr};c.webpackHot&&(__VUE_HMR_RUNTIME__.updatePageData=e=>{Jr.value[e.key]=()=>Promise.resolve(e),e.key===es.value.key&&(es.value=e)});const ns=Symbol(""),os=()=>{const e=Kt(ns);if(!e)throw new Error("usePageFrontmatter() is called without provider.");return e},is=e=>{const t=new Set,l=[];return e.forEach((e=>{const n=(([e,t,l])=>"meta"===e&&t.name?`${e}.${t.name}`:["title","base"].includes(e)?e:"template"===e&&t.id?`${e}.${t.id}`:JSON.stringify([e,t,l]))(e);t.has(n)||(t.add(n),l.push(e))})),l},rs=e=>/^(https?:)?\/\//.test(e),ss=e=>/^mailto:/.test(e),as=e=>/^tel:/.test(e),cs=e=>"[object Object]"===Object.prototype.toString.call(e),ds=e=>e.replace(/\/$/,""),us=e=>e.replace(/^\//,""),hs=(e,t)=>{const l=Object.keys(e).sort(((e,t)=>{const l=t.split("/").length-e.split("/").length;return 0!==l?l:t.length-e.length}));for(const n of l)if(t.startsWith(n))return n;return"/"},ps=Symbol(""),ms=Symbol(""),vs=Symbol(""),fs=Symbol(""),gs=()=>{const e=Kt(fs);if(!e)throw new Error("useRouteLocale() is called without provider.");return e},_s=jt({base:"/Xray-docs-next/",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"}}}),bs=()=>_s;c.webpackHot&&(__VUE_HMR_RUNTIME__.updateSiteData=e=>{_s.value=e});const ys=Symbol(""),Es=()=>{const e=Kt(ys);if(!e)throw new Error("useSiteLocaleData() is called without provider.");return e},xs=Symbol(""),js=()=>{const e=Xr(),t=(()=>{const e=Kt(ps);if(!e)throw new Error("usePageHead() is called without provider.");return e})(),l=(()=>{const e=Kt(vs);if(!e)throw new Error("usePageLang() is called without provider.");return e})(),n=jt([]),o=()=>{document.documentElement.lang=l.value,n.value.forEach((e=>{e.parentNode===document.head&&document.head.removeChild(e)})),n.value.splice(0,n.value.length),t.value.forEach((e=>{const t=Os(e);null!==t&&(document.head.appendChild(t),n.value.push(t))}))};Gt(xs,o),fl((()=>{t.value.forEach((e=>{const t=Ls(e);t&&n.value.push(t)})),o(),Ao((()=>e.path),(()=>o()))}))},Ls=([e,t,l=""])=>{const n=`head > ${e}${Object.entries(t).map((([e,t])=>V(t)?`[${e}="${t}"]`:!0===t?`[${e}]`:""))}`;return Array.from(document.querySelectorAll(n)).find((e=>e.innerText===l))||null},Os=([e,t,l])=>{if(!V(e))return null;const n=document.createElement(e);return cs(t)&&Object.entries(t).forEach((([e,t])=>{V(t)?n.setAttribute(e,t):!0===t&&n.setAttribute(e,"")})),V(l)&&n.appendChild(document.createTextNode(l)),n},ws=e=>{let t;if(e.pageKey)t=e.pageKey;else{t=ts().value.key}const l=Qr[t];return l?Vo(l):Vo("div","404 Not Found")};ws.displayName="Content",ws.props={pageKey:{type:String,required:!1}};const Ps=Vo("svg",{class:"icon outbound",xmlns:"http://www.w3.org/2000/svg",ariaHidden:"true",focusable:"false",x:"0px",y:"0px",viewBox:"0 0 100 100",width:"15",height:"15"},[Vo("path",{fill:"currentColor",d:"M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"}),Vo("polygon",{fill:"currentColor",points:"45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"})]),Ts=(e,{slots:t})=>{var l;return Vo("span",[Ps,null===(l=t.default)||void 0===l?void 0:l.call(t)])};Ts.displayName="OutboundLink";const ks={404:rl((()=>Yr((()=>import("./404.0a7ce90e.js")),[]))),Layout:rl((()=>Yr((()=>import("./Layout.47faf5cd.js")),[])))},As=ol({name:"Vuepress",setup(){const e=ts(),t=It((()=>{let t;if(e.value.path){const l=e.value.frontmatter.layout;t=V(l)?l:"Layout"}else t="404";return ks[t]||dn(t,!1)}));return()=>Vo(t.value)}}),Rs=e=>{if(rs(e))return e;return`${bs().value.base}${us(e)}`};var Ds=ol({props:{type:{type:String,required:!1,default:"tip"},text:{type:String,required:!1,default:""},vertical:{type:String,required:!1,default:void 0}},setup:e=>(t,l)=>(bn(),jn("span",{class:g(["badge",e.type]),style:p({verticalAlign:e.vertical})},[zn(t.$slots,"default",{},(()=>[In(_(e.text),1)]))],6))}),Is=ol({name:"CodeGroup",setup(e,{slots:t}){const l=jt(-1),n=jt([]),o=(e,t)=>{" "===e.key||"Enter"===e.key?(e.preventDefault(),l.value=t):"ArrowRight"===e.key?(e.preventDefault(),((e=l.value)=>{e{l.value=e>0?e-1:n.value.length-1,n.value[l.value].focus()})(t))};return()=>{var e;const i=((null===(e=t.default)||void 0===e?void 0:e.call(t))||[]).filter((e=>"CodeGroupItem"===e.type.name)).map((e=>(null===e.props&&(e.props={}),e)));return 0===i.length?null:(l.value<0||l.value>i.length-1?(l.value=i.findIndex((e=>""===e.props.active||!0===e.props.active)),-1===l.value&&(l.value=0)):i.forEach(((e,t)=>{e.props.active=t===l.value})),Vo("div",{class:"code-group"},[Vo("div",{class:"code-group__nav"},Vo("ul",{class:"code-group__ul"},i.map(((e,t)=>{const i=t===l.value;return Vo("li",{class:"code-group__li"},Vo("button",{ref:e=>{e&&(n.value[t]=e)},class:{"code-group__nav-tab":!0,"code-group__nav-tab-active":i},ariaPressed:i,ariaExpanded:i,onClick:()=>l.value=t,onKeydown:e=>o(e,t)},e.props.title))})))),i]))}}});const Ss=["aria-selected"],Vs=ol({name:"CodeGroupItem"});var Cs=ol(a(s({},Vs),{props:{title:{type:String,required:!0},active:{type:Boolean,required:!1,default:!1}},setup:function(e){return(t,l)=>(bn(),jn("div",{class:g(["code-group-item",{"code-group-item__active":e.active}]),"aria-selected":e.active},[zn(t.$slots,"default")],10,Ss))}}));function Fs(e){return!!te&&(function(e){te&&te.cleanups.push(e)}(e),!0)} /*! ***************************************************************************** Copyright (c) Microsoft Corporation. @@ -18,6 +18,6 @@ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */const Ns="undefined"!=typeof window,Ms=()=>{};const Hs=e=>e();function zs(e,t,l={}){const{eventFilter:n=Hs}=l,o=function(e,t){var l={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(l[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);or.apply(this,e)),{fn:r,thisArg:this,args:e})}),o);var i,r}const Bs=Ns?window:void 0;const $s={boolean:{read:e=>"true"===e,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)}};function Ws(e,t,l=(null==Bs?void 0:Bs.localStorage),n={}){var o;const{flush:i="pre",deep:r=!0,listenToStorageChanges:s=!0,window:a=Bs,eventFilter:c,onError:d=(e=>{console.error(e)})}=n,u=null==t?"any":"boolean"==typeof t?"boolean":"string"==typeof t?"string":"object"==typeof t||Array.isArray(t)?"object":Number.isNaN(t)?"any":"number",h=jt(t),p=null!==(o=n.serializer)&&void 0!==o?o:$s[u];function m(n){if(l&&(!n||n.key===e))try{const o=n?n.newValue:l.getItem(e);null==o?(h.value=t,null!==t&&l.setItem(e,p.write(t))):h.value=p.read(o)}catch(o){d(o)}}return m(),a&&s&&function(...e){let t,l,n,o;if("string"==typeof e[0]?([l,n,o]=e,t=Bs):[t,l,n,o]=e,!t)return Ms;let i=Ms;const r=Ao((()=>wt(t)),(e=>{i(),e&&(e.addEventListener(l,n,o),i=()=>{e.removeEventListener(l,n,o),i=Ms})}),{immediate:!0,flush:"post"}),s=()=>{r(),i()};Fs(s)}(a,"storage",m),zs(h,(()=>{if(l)try{null==h.value?l.removeItem(e):l.setItem(e,p.write(h.value))}catch(t){d(t)}}),{flush:i,deep:r,eventFilter:c}),h}function Us(e){return function(e,t={}){const{window:l=Bs}=t;if(!l)return jt(!1);const n=l.matchMedia(e),o=jt(n.matches),i=e=>{o.value=e.matches};return"addEventListener"in n?n.addEventListener("change",i):n.addListener(i),Fs((()=>{"removeEventListener"in n?n.removeEventListener("change",i):n.removeListener(i)})),o}("(prefers-color-scheme: dark)",e)}var qs,Xs;(Xs=qs||(qs={})).UP="UP",Xs.RIGHT="RIGHT",Xs.DOWN="DOWN",Xs.LEFT="LEFT",Xs.NONE="NONE";const Gs=Symbol(""),Ks=()=>{const e=Kt(Gs);if(!e)throw new Error("useDarkMode() is called without provider.");return e},Ys=e=>{const t=(t=e.value)=>{const l=null===window||void 0===window?void 0:window.document.querySelector("html");null==l||l.classList.toggle("dark",t)};fl((()=>{Ao(e,t,{immediate:!0})})),yl((()=>t()))},Qs=(...e)=>{const t=qr().resolve(...e),l=t.matched[t.matched.length-1];if(!(null==l?void 0:l.redirect))return t;const{redirect:n}=l,o=S(n)?n(t):n,i=V(o)?{path:o}:o;return Qs(s({hash:t.hash,query:t.query,params:t.params},i))},Js=e=>{const t=Qs(e);return{text:t.meta.title||e,link:"404"===t.name?e:t.fullPath}};let Zs=null,ea=null;const ta={wait:()=>Zs,pending:()=>{Zs=new Promise((e=>ea=e))},resolve:()=>{null==ea||ea(),Zs=null,ea=null}},la=()=>ta,na=Symbol("sidebarItems"),oa=()=>{const e=Kt(na);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},ia=(e,t)=>{var l,n,o,i;const r=null!==(n=null!==(l=e.sidebar)&&void 0!==l?l:t.sidebar)&&void 0!==n?n:"auto",s=null!==(i=null!==(o=e.sidebarDepth)&&void 0!==o?o:t.sidebarDepth)&&void 0!==i?i:2;return e.home||!1===r?[]:"auto"===r?sa(s):R(r)?aa(r,s):cs(r)?ca(r,s):[]},ra=(e,t)=>t>0?e.map((e=>((e,t)=>({text:e.title,link:`#${e.slug}`,children:ra(e.children,t)}))(e,t-1))):[],sa=e=>{const t=ts();return[{text:t.value.title,children:ra(t.value.headers,e)}]},aa=(e,t)=>{const l=Xr(),n=ts(),o=e=>{var i;let r;if(r=V(e)?Js(e):e,r.children)return a(s({},r),{children:r.children.map((e=>o(e)))});if(r.link===l.path){const e=1===(null===(i=n.value.headers[0])||void 0===i?void 0:i.level)?n.value.headers[0].children:n.value.headers;return a(s({},r),{children:ra(e,t)})}return r};return e.map((e=>o(e)))},ca=(e,t)=>{var l;const n=Xr(),o=null!==(l=e[hs(e,n.path)])&&void 0!==l?l:[];return aa(o,t)},da=jt({smoothScroll:!0,repo:"xtls/xray-core",docsRepo:"xtls/Xray-docs-next",docsDir:"docs",docsBranch:"main",editLinks:!0,enableToggle:!0,locales:{"/":{repoLabel:"查看源码",editLinkText:"帮助我们改善此页面!",tip:"提示",warning:"注意",danger:"警告",lastUpdatedText:"最近更改",selectLanguageName:"简体中文",selectLanguageText:"多语言",selectLanguageAriaLabel:"多语言",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/","/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"]},{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/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/grpc.md","/config/transports/h2.md","/config/transports/mkcp.md","/config/transports/quic.md","/config/transports/tcp.md","/config/transports/websocket.md"]}],"/document/":[{text:"快速入门文档",children:["/document/install.md","/document/config.md","/document/command.md","/document/document.md","/document/level-0","/document/level-1","/document/level-2"]}],"/document/level-0/":[{text:"小小白白话文",children:["/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"]}],"/document/level-1/":[{text:"入门技巧",children:["/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"]}],"/document/level-2/":[{text:"进阶技巧",children:["/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/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"]}]}]},navbar:[{text:"首页",link:"/"},{text:"大史记",link:"/about/news.md"},{text:"配置指南",link:"/config/"},{text:"开发指南",link:"/development/"},{text:"使用指南",link:"/document/"}]},"/en/":{repoLabel:"Source",editLinkText:"Help us improve this page on GitHub!",tip:"Tip",warning:"Warning",danger:"Danger",lastUpdatedText:"Last Updated",selectLanguageName:"English (WIP)",sidebar:{"/en/config/":[{text:"Xray Features",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 Reference",children:["/en/config/","/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"]},{text:"Inbound Protocol",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 Protocol",children:["/en/config/outbounds/blackhole.md","/en/config/outbounds/dns.md","/en/config/outbounds/freedom.md","/en/config/outbounds/http.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:"Stream Transport Protocol",children:["/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/document/level-0/":[{text:"Beginner Tutorial",children:["/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"]}],"/en/document/level-1/":[{text:"Getting Started Tips",children:["/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"]}],"/en/document/level-2/":[{text:"Advanced Documentation",children:["/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/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/"}]}},navbar:[],logo:null,darkMode:!0,selectLanguageText:"Languages",selectLanguageAriaLabel:"Select language",sidebar:"auto",sidebarDepth:2,editLink:!0,editLinkText:"Edit this page",lastUpdated:!0,lastUpdatedText:"Last Updated",contributors:!0,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",toggleDarkMode:"toggle dark mode",toggleSidebar:"toggle sidebar"});c.webpackHot&&(__VUE_HMR_RUNTIME__.updateThemeData=e=>{da.value=e});const ua=Symbol(""),ha=()=>(()=>{const e=Kt(ua);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e})(),pa={class:"sr-only"};var ma=ol({setup(e){const t=ha();return(e,l)=>(bn(),Ln(wt(Ts),null,{default:Bt((()=>[An("span",pa,_(wt(t).openInNewWindow),1)])),_:1}))}}),va=({app:e,router:t})=>{e.component("Badge",Ds),e.component("CodeGroup",Is),e.component("CodeGroupItem",Cs),delete e._context.components.OutboundLink,e.component("OutboundLink",ma),e.component("NavbarSearch",(()=>{const t=e.component("Docsearch")||e.component("SearchBox");return t?Vo(t):null}));const l=t.options.scrollBehavior;t.options.scrollBehavior=async(...e)=>(await la().wait(),l(...e))},fa=Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{},n=window.Promise||function(e){function t(){}e(t,t)},o=function(e){var t=e.target;t!==O?-1!==b.indexOf(t)&&v({target:t}):m()},i=function(){if(!E&&L.original){var e=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(x-e)>j.scrollOffset&&setTimeout(m,150)}},r=function(e){var t=e.key||e.keyCode;"Escape"!==t&&"Esc"!==t&&27!==t||m()},s=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e;if(e.background&&(O.style.background=e.background),e.container&&e.container instanceof Object&&(t.container=fa({},j.container,e.container)),e.template){var l=_a(e.template)?e.template:document.querySelector(e.template);t.template=l}return j=fa({},j,t),b.forEach((function(e){e.dispatchEvent(ja("medium-zoom:update",{detail:{zoom:w}}))})),w},a=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return e(fa({},j,t))},c=function(){for(var e=arguments.length,t=Array(e),l=0;l0?t.reduce((function(e,t){return[].concat(e,ya(t))}),[]):b;return n.forEach((function(e){e.classList.remove("medium-zoom-image"),e.dispatchEvent(ja("medium-zoom:detach",{detail:{zoom:w}}))})),b=b.filter((function(e){return-1===n.indexOf(e)})),w},u=function(e,t){var l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return b.forEach((function(n){n.addEventListener("medium-zoom:"+e,t,l)})),y.push({type:"medium-zoom:"+e,listener:t,options:l}),w},h=function(e,t){var l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return b.forEach((function(n){n.removeEventListener("medium-zoom:"+e,t,l)})),y=y.filter((function(l){return!(l.type==="medium-zoom:"+e&&l.listener.toString()===t.toString())})),w},p=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.target,l=function(){var e={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},t=void 0,l=void 0;if(j.container)if(j.container instanceof Object)t=(e=fa({},e,j.container)).width-e.left-e.right-2*j.margin,l=e.height-e.top-e.bottom-2*j.margin;else{var n=(_a(j.container)?j.container:document.querySelector(j.container)).getBoundingClientRect(),o=n.width,i=n.height,r=n.left,s=n.top;e=fa({},e,{width:o,height:i,left:r,top:s})}t=t||e.width-2*j.margin,l=l||e.height-2*j.margin;var a=L.zoomedHd||L.original,c=ba(a)?t:a.naturalWidth||t,d=ba(a)?l:a.naturalHeight||l,u=a.getBoundingClientRect(),h=u.top,p=u.left,m=u.width,v=u.height,f=Math.min(c,t)/m,g=Math.min(d,l)/v,_=Math.min(f,g),b="scale("+_+") translate3d("+((t-m)/2-p+j.margin+e.left)/_+"px, "+((l-v)/2-h+j.margin+e.top)/_+"px, 0)";L.zoomed.style.transform=b,L.zoomedHd&&(L.zoomedHd.style.transform=b)};return new n((function(e){if(t&&-1===b.indexOf(t))e(w);else{if(L.zoomed)e(w);else{if(t)L.original=t;else{if(!(b.length>0))return void e(w);var n=b;L.original=n[0]}if(L.original.dispatchEvent(ja("medium-zoom:open",{detail:{zoom:w}})),x=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,E=!0,L.zoomed=xa(L.original),document.body.appendChild(O),j.template){var o=_a(j.template)?j.template:document.querySelector(j.template);L.template=document.createElement("div"),L.template.appendChild(o.content.cloneNode(!0)),document.body.appendChild(L.template)}if(document.body.appendChild(L.zoomed),window.requestAnimationFrame((function(){document.body.classList.add("medium-zoom--opened")})),L.original.classList.add("medium-zoom-image--hidden"),L.zoomed.classList.add("medium-zoom-image--opened"),L.zoomed.addEventListener("click",m),L.zoomed.addEventListener("transitionend",(function t(){E=!1,L.zoomed.removeEventListener("transitionend",t),L.original.dispatchEvent(ja("medium-zoom:opened",{detail:{zoom:w}})),e(w)})),L.original.getAttribute("data-zoom-src")){L.zoomedHd=L.zoomed.cloneNode(),L.zoomedHd.removeAttribute("srcset"),L.zoomedHd.removeAttribute("sizes"),L.zoomedHd.src=L.zoomed.getAttribute("data-zoom-src"),L.zoomedHd.onerror=function(){clearInterval(i),console.warn("Unable to reach the zoom image target "+L.zoomedHd.src),L.zoomedHd=null,l()};var i=setInterval((function(){L.zoomedHd.complete&&(clearInterval(i),L.zoomedHd.classList.add("medium-zoom-image--opened"),L.zoomedHd.addEventListener("click",m),document.body.appendChild(L.zoomedHd),l())}),10)}else if(L.original.hasAttribute("srcset")){L.zoomedHd=L.zoomed.cloneNode(),L.zoomedHd.removeAttribute("sizes"),L.zoomedHd.removeAttribute("loading");var r=L.zoomedHd.addEventListener("load",(function(){L.zoomedHd.removeEventListener("load",r),L.zoomedHd.classList.add("medium-zoom-image--opened"),L.zoomedHd.addEventListener("click",m),document.body.appendChild(L.zoomedHd),l()}))}else l()}}}))},m=function(){return new n((function(e){if(!E&&L.original){E=!0,document.body.classList.remove("medium-zoom--opened"),L.zoomed.style.transform="",L.zoomedHd&&(L.zoomedHd.style.transform=""),L.template&&(L.template.style.transition="opacity 150ms",L.template.style.opacity=0),L.original.dispatchEvent(ja("medium-zoom:close",{detail:{zoom:w}})),L.zoomed.addEventListener("transitionend",(function t(){L.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(L.zoomed),L.zoomedHd&&document.body.removeChild(L.zoomedHd),document.body.removeChild(O),L.zoomed.classList.remove("medium-zoom-image--opened"),L.template&&document.body.removeChild(L.template),E=!1,L.zoomed.removeEventListener("transitionend",t),L.original.dispatchEvent(ja("medium-zoom:closed",{detail:{zoom:w}})),L.original=null,L.zoomed=null,L.zoomedHd=null,L.template=null,e(w)}))}else e(w)}))},v=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.target;return L.original?m():p({target:t})},f=function(){return j},g=function(){return b},_=function(){return L.original},b=[],y=[],E=!1,x=0,j=l,L={original:null,zoomed:null,zoomedHd:null,template:null};"[object Object]"===Object.prototype.toString.call(t)?j=t:(t||"string"==typeof t)&&c(t),j=fa({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},j);var O=Ea(j.background);document.addEventListener("click",o),document.addEventListener("keyup",r),document.addEventListener("scroll",i),window.addEventListener("resize",m);var w={open:p,close:m,toggle:v,update:s,clone:a,attach:c,detach:d,on:u,off:h,getOptions:f,getImages:g,getZoomedImage:_};return w};!function(e,t){void 0===t&&(t={});var l=t.insertAt;if(e&&"undefined"!=typeof document){var n=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css","top"===l&&n.firstChild?n.insertBefore(o,n.firstChild):n.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e))}}(".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}");const Oa=Symbol("mediumZoom");const wa={};var Pa=({app:e,router:t})=>{const l=La(wa);l.refresh=(e=".theme-default-content > img, .theme-default-content :not(a) > img")=>{l.detach(),l.attach(e)},e.provide(Oa,l),t.afterEach((()=>{setTimeout((()=>l.refresh()),400)}))},Ta=({app:e})=>{const t=da,l=e._context.provides[fs],n=It((()=>((e,t)=>{var l;return s(s({},e),null===(l=e.locales)||void 0===l?void 0:l[t])})(t.value,l.value)));e.provide(ua,n),Object.defineProperties(e.config.globalProperties,{$theme:{get:()=>t.value},$themeLocale:{get:()=>n.value}})},ka=ol({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"}}});Ht("data-v-bcf9babc");const Aa=["id","aria-labelledby"];zt(),ka.render=function(e,t,l,n,o,i){return bn(),jn("div",{class:"tab-pane fade",id:e.tabID,role:"tabpanel","aria-labelledby":e.labelID},[zn(e.$slots,"default",{},void 0,!0)],8,Aa)},ka.__scopeId="data-v-bcf9babc";var Ra=ol({props:{title:{type:String}},data:()=>({children:[]}),beforeMount(){this.children=[]},mounted(){this.$nextTick((async function(){const e=await Yr((()=>import("./bootstrap.esm.4786c18a.js")),[]);let t=document.getElementById(this.children[0].id+"-label");new e.Tab(t).show()}))},computed:{tag:function(){return"tabs-"+this.title},contentTag:function(){return"tabs-"+this.title+"-content"}}});Ht("data-v-d1085dd8");const Da={class:"container"},Ia=["id"],Sa=["id","aria-controls","data-bs-target"],Va=["id"];zt(),Ra.render=function(e,t,l,n,o,i){return bn(),jn("div",Da,[An("nav",null,[An("div",{id:e.tag,class:"nav nav-pills",role:"tablist"},[(bn(!0),jn(pn,null,Hn(e.children,(e=>(bn(),jn("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,Sa)))),256))],8,Ia)]),An("div",{id:e.contentTag,class:"tab-content"},[zn(e.$slots,"default",{},void 0,!0)],8,Va)])},Ra.__scopeId="data-v-d1085dd8";const Ca=e=>!rs(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,Fa={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"},Na=({docsRepo:e,docsBranch:t,docsDir:l,filePathRelative:n,editLinkPattern:o})=>{const i=Ca(e);let r;return o?r=o:null!==i&&(r=Fa[i]),r?r.replace(/:repo/,rs(e)?e:`https://github.com/${e}`).replace(/:branch/,t).replace(/:path/,us(`${ds(l)}/${n}`)):null};var Ma=ol({name:"Mermaid",props:{identifier:String,graph:String},setup(e){const t=Ks(),l=Rt(e,"identifier"),n=Rt(e,"graph"),o=ut({innerHtml:""});return fl((()=>{Eo((async function(){const e=await Yr((()=>import("./mermaid.core.a66200b0.js").then((function(e){return e.aL}))),[]);e.default.initialize({startOnLoad:!1,theme:t.value?"dark":"default"}),e.default.render(l.value,decodeURI(n.value)).then((({svg:e,bindFunctions:t})=>{o.innerHtml=e}))}))})),Ao(t,(async()=>{const e=await Yr((()=>import("./mermaid.core.a66200b0.js").then((function(e){return e.aL}))),[]);e.default.initialize({startOnLoad:!1,theme:t.value?"dark":"default"}),e.default.render(l.value,decodeURI(n.value)).then((({svg:e,bindFunctions:t})=>{o.innerHtml=e}))})),{tag:l,payload:o}}});const Ha=["innerHTML"];Ma.render=function(e,t,l,n,o,i){return bn(),jn("div",{innerHTML:e.payload.innerHtml},null,8,Ha)};var za=({app:e,router:t,siteData:l})=>{e.component("Tab",ka),e.component("Tabs",Ra),e.component("Mermaid",Ma)};const Ba=jt([{title:"",headers:[{level:2,title:"XTLS ? Xray ? V2Ray ?",slug:"xtls-xray-v2ray",children:[{level:3,title:"我们是谁?",slug:"我们是谁",children:[]},{level:3,title:"帮助 Xray 变得更强",slug:"帮助-xray-变得更强",children:[]},{level:3,title:"Telegram",slug:"telegram",children:[]},{level:3,title:"致谢",slug:"致谢",children:[]},{level:3,title:"更多关于 project X",slug:"更多关于-project-x",children:[]},{level:3,title:"License",slug:"license",children:[]},{level:3,title:"Stargazers over time",slug:"stargazers-over-time",children:[]}]}],path:"/",pathLocale:"/",extraFields:[]},{title:"大史记",headers:[{level:2,title:"2021.4.6",slug:"_2021-4-6",children:[]},{level:2,title:"2021.4.4",slug:"_2021-4-4",children:[]},{level:2,title:"2021.4.1 v1.4.2",slug:"_2021-4-1-v1-4-2",children:[]},{level:2,title:"2021.3.25",slug:"_2021-3-25",children:[]},{level:2,title:"2021.3.15",slug:"_2021-3-15",children:[]},{level:2,title:"2021.3.14 v1.4.0",slug:"_2021-3-14-v1-4-0",children:[]},{level:2,title:"2021.3.3 1.3.1",slug:"_2021-3-3-1-3-1",children:[]},{level:2,title:"2021.2.14 1.3.0",slug:"_2021-2-14-1-3-0",children:[]},{level:2,title:"2021.01.31 1.2.4",slug:"_2021-01-31-1-2-4",children:[]},{level:2,title:"2021.01.25",slug:"_2021-01-25",children:[]},{level:2,title:"2021.01.22 1.2.3",slug:"_2021-01-22-1-2-3",children:[]},{level:2,title:"2021.01.19",slug:"_2021-01-19",children:[]},{level:2,title:"2021.01.17",slug:"_2021-01-17",children:[]},{level:2,title:"2021.01.15 1.2.2",slug:"_2021-01-15-1-2-2",children:[]},{level:2,title:"2021.01.12",slug:"_2021-01-12",children:[]},{level:2,title:"2021.01.10 1.2.1",slug:"_2021-01-10-1-2-1",children:[]},{level:2,title:"2021.01.07",slug:"_2021-01-07",children:[]},{level:2,title:"2021.01.05",slug:"_2021-01-05",children:[]},{level:2,title:"2021.01.03",slug:"_2021-01-03",children:[]},{level:2,title:"2021.01.01",slug:"_2021-01-01",children:[]},{level:2,title:"2020.12.29",slug:"_2020-12-29",children:[]},{level:2,title:"2020.12.25 1.1.5",slug:"_2020-12-25-1-1-5",children:[]},{level:2,title:"2020.12.24",slug:"_2020-12-24",children:[]},{level:2,title:"2020.12.23",slug:"_2020-12-23",children:[]},{level:2,title:"2020.12.21",slug:"_2020-12-21",children:[]},{level:2,title:"2020.12.18 1.1.4",slug:"_2020-12-18-1-1-4",children:[]},{level:2,title:"2020.12.17",slug:"_2020-12-17",children:[]},{level:2,title:"2020.12.15",slug:"_2020-12-15",children:[]},{level:2,title:"2020.12.11 1.1.3",slug:"_2020-12-11-1-1-3",children:[]},{level:2,title:"2020.12.06 1.1.2",slug:"_2020-12-06-1-1-2",children:[]},{level:2,title:"2020.12.04",slug:"_2020-12-04",children:[]},{level:2,title:"2020.11.27",slug:"_2020-11-27",children:[]},{level:2,title:"2020.11.25 1.0.0",slug:"_2020-11-25-1-0-0",children:[]},{level:2,title:"2020.11.23",slug:"_2020-11-23",children:[]}],path:"/about/news.html",pathLocale:"/",extraFields:[]},{title:"配置文件",headers:[{level:2,title:"概述",slug:"概述",children:[]},{level:2,title:"基础配置模块",slug:"基础配置模块",children:[]}],path:"/config/",pathLocale:"/",extraFields:[]},{title:"API 接口",headers:[{level:2,title:"ApiObject",slug:"apiobject",children:[]},{level:2,title:"相关配置",slug:"相关配置",children:[]},{level:2,title:"支持的 API 列表",slug:"支持的-api-列表",children:[{level:3,title:"HandlerService",slug:"handlerservice",children:[]},{level:3,title:"LoggerService",slug:"loggerservice",children:[]},{level:3,title:"StatsService",slug:"statsservice",children:[]},{level:3,title:"ReflectionService",slug:"reflectionservice",children:[]}]},{level:2,title:"API 调用示例",slug:"api-调用示例",children:[]}],path:"/config/api.html",pathLocale:"/",extraFields:[]},{title:"内置 DNS 服务器",headers:[{level:2,title:"DNS 服务器",slug:"dns-服务器",children:[]},{level:2,title:"DNS 处理流程",slug:"dns-处理流程",children:[]},{level:2,title:"DnsObject",slug:"dnsobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/dns.html",pathLocale:"/",extraFields:[]},{title:"FakeDNS",headers:[{level:2,title:"FakeDNSObject",slug:"fakednsobject",children:[{level:3,title:"如何使用?",slug:"如何使用",children:[]},{level:3,title:"与其它类型 DNS 搭配使用",slug:"与其它类型-dns-搭配使用",children:[]}]}],path:"/config/fakedns.html",pathLocale:"/",extraFields:[]},{title:"入站代理",headers:[{level:2,title:"InboundObject",slug:"inboundobject",children:[{level:3,title:"SniffingObject",slug:"sniffingobject",children:[]},{level:3,title:"AllocateObject",slug:"allocateobject",children:[]}]}],path:"/config/inbound.html",pathLocale:"/",extraFields:[]},{title:"日志配置",headers:[{level:2,title:"LogObject",slug:"logobject",children:[]}],path:"/config/log.html",pathLocale:"/",extraFields:[]},{title:"出站代理",headers:[{level:2,title:"OutboundObject",slug:"outboundobject",children:[{level:3,title:"ProxySettingsObject",slug:"proxysettingsobject",children:[]},{level:3,title:"MuxObject",slug:"muxobject",children:[]}]}],path:"/config/outbound.html",pathLocale:"/",extraFields:[]},{title:"本地策略",headers:[{level:2,title:"PolicyObject",slug:"policyobject",children:[{level:3,title:"LevelPolicyObject",slug:"levelpolicyobject",children:[]},{level:3,title:"SystemPolicyObject",slug:"systempolicyobject",children:[]}]}],path:"/config/policy.html",pathLocale:"/",extraFields:[]},{title:"反向代理",headers:[{level:2,title:"ReverseObject",slug:"reverseobject",children:[{level:3,title:"BridgeObject",slug:"bridgeobject",children:[]},{level:3,title:"PortalObject",slug:"portalobject",children:[]}]},{level:2,title:"完整配置样例",slug:"完整配置样例",children:[{level:3,title:"bridge 配置",slug:"bridge-配置",children:[]},{level:3,title:"portal 配置",slug:"portal-配置",children:[]}]}],path:"/config/reverse.html",pathLocale:"/",extraFields:[]},{title:"路由",headers:[{level:2,title:"RoutingObject",slug:"routingobject",children:[{level:3,title:"RuleObject",slug:"ruleobject",children:[]},{level:3,title:"BalancerObject",slug:"balancerobject",children:[]},{level:3,title:"预定义域名列表",slug:"预定义域名列表",children:[]}]}],path:"/config/routing.html",pathLocale:"/",extraFields:[]},{title:"统计信息",headers:[{level:2,title:"StatsObject",slug:"statsobject",children:[]},{level:2,title:"获取统计信息",slug:"获取统计信息",children:[]}],path:"/config/stats.html",pathLocale:"/",extraFields:[]},{title:"传输方式",headers:[{level:2,title:"TransportObject",slug:"transportobject",children:[]},{level:2,title:"StreamSettingsObject",slug:"streamsettingsobject",children:[{level:3,title:"TLSObject",slug:"tlsobject",children:[]},{level:3,title:"RealityObject",slug:"realityobject",children:[]},{level:3,title:"SockoptObject",slug:"sockoptobject",children:[]}]}],path:"/config/transport.html",pathLocale:"/",extraFields:[]},{title:"开发指南",headers:[{level:2,title:"编译文档",slug:"编译文档",children:[]},{level:2,title:"设计思路",slug:"设计思路",children:[]},{level:2,title:"开发规范",slug:"开发规范",children:[]},{level:2,title:"协议详解",slug:"协议详解",children:[{level:3,title:"VLESS 协议",slug:"vless-协议",children:[]},{level:3,title:"VMess 协议",slug:"vmess-协议",children:[]},{level:3,title:"Mux.Cool 协议",slug:"mux-cool-协议",children:[]},{level:3,title:"mKCP 协议",slug:"mkcp-协议",children:[]}]}],path:"/development/",pathLocale:"/",extraFields:[]},{title:"快速入门",headers:[{level:2,title:"下载安装",slug:"下载安装",children:[]},{level:2,title:"配置运行",slug:"配置运行",children:[]},{level:2,title:"命令参数",slug:"命令参数",children:[]},{level:2,title:"改进文档",slug:"改进文档",children:[]},{level:2,title:"小小白白话文",slug:"小小白白话文",children:[]},{level:2,title:"入门技巧",slug:"入门技巧",children:[]},{level:2,title:"进阶文档",slug:"进阶文档",children:[]}],path:"/document/",pathLocale:"/",extraFields:[]},{title:"命令参数",headers:[{level:2,title:"获取基本命令",slug:"获取基本命令",children:[{level:3,title:"xray run",slug:"xray-run",children:[]},{level:3,title:"xray version",slug:"xray-version",children:[]},{level:3,title:"xray api",slug:"xray-api",children:[]},{level:3,title:"xray tls",slug:"xray-tls",children:[]},{level:3,title:"xray uuid",slug:"xray-uuid",children:[]}]}],path:"/document/command.html",pathLocale:"/",extraFields:[]},{title:"配置运行",headers:[{level:2,title:"服务端配置",slug:"服务端配置",children:[]},{level:2,title:"客户端配置",slug:"客户端配置",children:[]},{level:2,title:"运行",slug:"运行",children:[]}],path:"/document/config.html",pathLocale:"/",extraFields:[]},{title:"为 Project X 的文档贡献",headers:[{level:2,title:"改进文档",slug:"改进文档",children:[]},{level:2,title:"发现问题?",slug:"发现问题",children:[]}],path:"/document/document.html",pathLocale:"/",extraFields:[]},{title:"下载安装",headers:[{level:2,title:"平台支持",slug:"平台支持",children:[]},{level:2,title:"下载 Xray",slug:"下载-xray",children:[]},{level:2,title:"验证安装包",slug:"验证安装包",children:[]},{level:2,title:"Windows 安装方式",slug:"windows-安装方式",children:[]},{level:2,title:"macOS 安装方式",slug:"macos-安装方式",children:[]},{level:2,title:"Linux 安装方式",slug:"linux-安装方式",children:[{level:3,title:"安装脚本",slug:"安装脚本",children:[]},{level:3,title:"Arch Linux",slug:"arch-linux",children:[]},{level:3,title:"Linuxbrew",slug:"linuxbrew",children:[]},{level:3,title:"Debian",slug:"debian",children:[]},{level:3,title:"Gentoo",slug:"gentoo",children:[]}]},{level:2,title:"Docker 安装方式",slug:"docker-安装方式",children:[{level:3,title:"Docker image 的文件结构",slug:"docker-image-的文件结构",children:[]}]}],path:"/document/install.html",pathLocale:"/",extraFields:[]},{title:"",headers:[{level:2,title:"XTLS? Xray? V2Ray?",slug:"xtls-xray-v2ray",children:[{level:3,title:"Who are we?",slug:"who-are-we",children:[]},{level:3,title:"Help Xray become stronger",slug:"help-xray-become-stronger",children:[]},{level:3,title:"Telegram",slug:"telegram",children:[]},{level:3,title:"Thanks",slug:"thanks",children:[]},{level:3,title:"More about project X",slug:"more-about-project-x",children:[]},{level:3,title:"License",slug:"license",children:[]},{level:3,title:"Stargazers over time",slug:"stargazers-over-time",children:[]}]}],path:"/en/",pathLocale:"/en/",extraFields:[]},{title:"Browser Dialer",headers:[{level:2,title:"Background",slug:"background",children:[]},{level:2,title:"Xray & JS",slug:"xray-js",children:[]},{level:2,title:"Early data",slug:"early-data",children:[]},{level:2,title:"Configuration",slug:"configuration",children:[]}],path:"/config/features/browser_dialer.html",pathLocale:"/",extraFields:[]},{title:"环境变量",headers:[{level:2,title:"资源文件路径",slug:"资源文件路径",children:[]},{level:2,title:"配置文件位置",slug:"配置文件位置",children:[]},{level:2,title:"多配置目录",slug:"多配置目录",children:[]}],path:"/config/features/env.html",pathLocale:"/",extraFields:[]},{title:"Fallback 回落",headers:[{level:2,title:"fallbacks 配置",slug:"fallbacks-配置",children:[{level:3,title:"FallbackObject",slug:"fallbackobject",children:[]},{level:3,title:"补充说明",slug:"补充说明",children:[]}]},{level:2,title:"Fallbacks 设计理论",slug:"fallbacks-设计理论",children:[]}],path:"/config/features/fallback.html",pathLocale:"/",extraFields:[]},{title:"多文件配置",headers:[{level:2,title:"多文件启动",slug:"多文件启动",children:[]},{level:2,title:"规则说明",slug:"规则说明",children:[{level:3,title:"普通对象({})",slug:"普通对象",children:[]},{level:3,title:"数组([])",slug:"数组",children:[]}]},{level:2,title:"推荐的多文件列表",slug:"推荐的多文件列表",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",children:[]},{level:2,title:"透明代理配置样例",slug:"透明代理配置样例",children:[]}],path:"/config/inbounds/dokodemo.html",pathLocale:"/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",children:[]}]}],path:"/config/inbounds/http.html",pathLocale:"/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[]},{level:2,title:"ClientObject",slug:"clientobject",children:[]}],path:"/config/inbounds/shadowsocks.html",pathLocale:"/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",children:[]}]}],path:"/config/inbounds/socks.html",pathLocale:"/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]}]}],path:"/config/inbounds/trojan.html",pathLocale:"/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]}]}],path:"/config/inbounds/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]},{level:3,title:"DetourObject",slug:"detourobject",children:[]},{level:3,title:"DefaultObject",slug:"defaultobject",children:[]}]}],path:"/config/inbounds/vmess.html",pathLocale:"/",extraFields:[]},{title:"Blackhole",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ResponseObject",slug:"responseobject",children:[]}]}],path:"/config/outbounds/blackhole.html",pathLocale:"/",extraFields:[]},{title:"DNS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[]},{level:2,title:"DNS 配置实例",slug:"dns-配置实例",children:[]}],path:"/config/outbounds/dns.html",pathLocale:"/",extraFields:[]},{title:"Freedom",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[]}],path:"/config/outbounds/freedom.html",pathLocale:"/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/outbounds/http.html",pathLocale:"/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/outbounds/shadowsocks.html",pathLocale:"/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/outbounds/socks.html",pathLocale:"/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/outbounds/trojan.html",pathLocale:"/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]},{level:3,title:"UserObject",slug:"userobject",children:[]}]}],path:"/config/outbounds/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/outbounds/vmess.html",pathLocale:"/",extraFields:[]},{title:"Wireguard",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"Peers",slug:"peers",children:[]}]}],path:"/config/outbounds/wireguard.html",pathLocale:"/",extraFields:[]},{title:"Domain Socket",headers:[{level:2,title:"DomainSocketObject",slug:"domainsocketobject",children:[]}],path:"/config/transports/domainsocket.html",pathLocale:"/",extraFields:[]},{title:"gRPC",headers:[{level:2,title:"GRPCObject",slug:"grpcobject",children:[]}],path:"/config/transports/grpc.html",pathLocale:"/",extraFields:[]},{title:"HTTP/2",headers:[{level:2,title:"HttpObject",slug:"httpobject",children:[]}],path:"/config/transports/h2.html",pathLocale:"/",extraFields:[]},{title:"mKCP",headers:[{level:2,title:"KcpObject",slug:"kcpobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",children:[]}]},{level:2,title:"鸣谢",slug:"鸣谢",children:[]},{level:2,title:"对 KCP 协议的改进",slug:"对-kcp-协议的改进",children:[{level:3,title:"更小的协议头",slug:"更小的协议头",children:[]},{level:3,title:"确认包重传",slug:"确认包重传",children:[]},{level:3,title:"连接状态控制",slug:"连接状态控制",children:[]}]}],path:"/config/transports/mkcp.html",pathLocale:"/",extraFields:[]},{title:"QUIC",headers:[{level:2,title:"QuicObject",slug:"quicobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",children:[]}]}],path:"/config/transports/quic.html",pathLocale:"/",extraFields:[]},{title:"TCP",headers:[{level:2,title:"TcpObject",slug:"tcpobject",children:[{level:3,title:"NoneHeaderObject",slug:"noneheaderobject",children:[]},{level:3,title:"HttpHeaderObject",slug:"httpheaderobject",children:[]}]}],path:"/config/transports/tcp.html",pathLocale:"/",extraFields:[]},{title:"WebSocket",headers:[{level:2,title:"WebSocketObject",slug:"websocketobject",children:[]},{level:2,title:"Browser Dialer",slug:"browser-dialer",children:[]}],path:"/config/transports/websocket.html",pathLocale:"/",extraFields:[]},{title:"编译文档",headers:[{level:2,title:"前序工作",slug:"前序工作",children:[]},{level:2,title:"拉取 Xray 源代码",slug:"拉取-xray-源代码",children:[]},{level:2,title:"构建二进制",slug:"构建二进制",children:[{level:3,title:"Windows(Powershell):",slug:"windows-powershell",children:[]},{level:3,title:"macOS, Linux:",slug:"macos-linux",children:[]}]},{level:2,title:"交叉编译:",slug:"交叉编译",children:[]},{level:2,title:"可复现构建:",slug:"可复现构建",children:[]}],path:"/development/intro/compile.html",pathLocale:"/",extraFields:[]},{title:"设计目标",headers:[{level:2,title:"架构",slug:"架构",children:[{level:3,title:"应用层",slug:"应用层",children:[]},{level:3,title:"代理层",slug:"代理层",children:[]},{level:3,title:"传输层",slug:"传输层",children:[]}]}],path:"/development/intro/design.html",pathLocale:"/",extraFields:[]},{title:"开发规范",headers:[{level:2,title:"基本",slug:"基本",children:[{level:3,title:"版本控制",slug:"版本控制",children:[]},{level:3,title:"分支(Branch)",slug:"分支-branch",children:[]},{level:3,title:"发布(Release)",slug:"发布-release",children:[]},{level:3,title:"引用其它项目",slug:"引用其它项目",children:[]}]},{level:2,title:"开发流程",slug:"开发流程",children:[{level:3,title:"写代码之前",slug:"写代码之前",children:[]},{level:3,title:"修改代码",slug:"修改代码",children:[]},{level:3,title:"Pull Request",slug:"pull-request",children:[]},{level:3,title:"对代码的修改",slug:"对代码的修改",children:[]}]},{level:2,title:"Xray 编码规范",slug:"xray-编码规范",children:[{level:3,title:"代码结构",slug:"代码结构",children:[]},{level:3,title:"编码规范",slug:"编码规范",children:[]}]}],path:"/development/intro/guide.html",pathLocale:"/",extraFields:[]},{title:"mKCP 协议",headers:[{level:2,title:"版本",slug:"版本",children:[]},{level:2,title:"依赖",slug:"依赖",children:[{level:3,title:"底层协议",slug:"底层协议",children:[]},{level:3,title:"函数",slug:"函数",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",children:[]},{level:2,title:"数据格式",slug:"数据格式",children:[{level:3,title:"数据包",slug:"数据包",children:[]},{level:3,title:"数据片段",slug:"数据片段",children:[]},{level:3,title:"确认片段",slug:"确认片段",children:[]},{level:3,title:"心跳片段",slug:"心跳片段",children:[]}]}],path:"/development/protocols/mkcp.html",pathLocale:"/",extraFields:[]},{title:"Mux.Cool 协议",headers:[{level:2,title:"版本",slug:"版本",children:[]},{level:2,title:"依赖",slug:"依赖",children:[{level:3,title:"底层协议",slug:"底层协议",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",children:[{level:3,title:"客户端行为",slug:"客户端行为",children:[]},{level:3,title:"服务器端行为",slug:"服务器端行为",children:[]}]},{level:2,title:"传输格式",slug:"传输格式",children:[{level:3,title:"帧格式",slug:"帧格式",children:[]},{level:3,title:"元数据",slug:"元数据",children:[]},{level:3,title:"新建子连接 (New)",slug:"新建子连接-new",children:[]},{level:3,title:"保持子连接 (Keep)",slug:"保持子连接-keep",children:[]},{level:3,title:"关闭子连接 (End)",slug:"关闭子连接-end",children:[]},{level:3,title:"保持连接 (KeepAlive)",slug:"保持连接-keepalive",children:[]}]},{level:2,title:"应用",slug:"应用",children:[]}],path:"/development/protocols/muxcool.html",pathLocale:"/",extraFields:[]},{title:"VLESS 协议",headers:[{level:2,title:"Request & Response",slug:"request-response",children:[]},{level:2,title:"ProtoBuf",slug:"protobuf",children:[]},{level:2,title:"Schedulers Flow",slug:"schedulers-flow",children:[]},{level:2,title:"Encryption",slug:"encryption",children:[]},{level:2,title:"UDP issues",slug:"udp-issues",children:[]},{level:2,title:"客户端开发指引",slug:"客户端开发指引",children:[]},{level:2,title:"VLESS 分享链接标准",slug:"vless-分享链接标准",children:[]}],path:"/development/protocols/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess 协议",headers:[{level:2,title:"版本",slug:"版本",children:[]},{level:2,title:"依赖",slug:"依赖",children:[{level:3,title:"底层协议",slug:"底层协议",children:[]},{level:3,title:"用户 ID",slug:"用户-id",children:[]},{level:3,title:"函数",slug:"函数",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",children:[]},{level:2,title:"客户端请求",slug:"客户端请求",children:[{level:3,title:"认证信息",slug:"认证信息",children:[]},{level:3,title:"指令部分",slug:"指令部分",children:[]},{level:3,title:"数据部分",slug:"数据部分",children:[]}]},{level:2,title:"服务器应答",slug:"服务器应答",children:[{level:3,title:"动态端口指令",slug:"动态端口指令",children:[]}]},{level:2,title:"注释",slug:"注释",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-这篇文档是写给谁的",children:[]},{level:2,title:"1.2 这篇文档不是写给谁的?",slug:"_1-2-这篇文档不是写给谁的",children:[]},{level:2,title:"1.3 郑重声明及其他声明",slug:"_1-3-郑重声明及其他声明",children:[]},{level:2,title:"1.4 为什么自建是个难题?",slug:"_1-4-为什么自建是个难题",children:[]},{level:2,title:"1.5 “用机场不就行了?”",slug:"_1-5-用机场不就行了",children:[]},{level:2,title:"1.6 那么你到底要不要自建呢?",slug:"_1-6-那么你到底要不要自建呢",children:[]},{level:2,title:"1.7 题外啰嗦几句",slug:"_1-7-题外啰嗦几句",children:[]},{level:2,title:"1.8 你的进度",slug:"_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",children:[]},{level:2,title:"2.2 获取一个心仪的域名",slug:"_2-2-获取一个心仪的域名",children:[]},{level:2,title:"2.3 你本地电脑上需要安装的软件",slug:"_2-3-你本地电脑上需要安装的软件",children:[]},{level:2,title:"2.4 你的进度",slug:"_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",children:[]},{level:2,title:"3.2 成功登录 SSH!初识命令行界面!",slug:"_3-2-成功登录-ssh-初识命令行界面",children:[]},{level:2,title:"3.3 第一次更新 Linux 的软件!",slug:"_3-3-第一次更新-linux-的软件",children:[]},{level:2,title:"3.4 你的进度",slug:"_3-4-你的进度",children:[]}],path:"/document/level-0/ch03-ssh.html",pathLocale:"/",extraFields:[]},{title:"【第 4 章】安全防护篇",headers:[{level:2,title:"4.1 为什么要做安全防护",slug:"_4-1-为什么要做安全防护",children:[]},{level:2,title:"4.2 具体的风险到底是什么",slug:"_4-2-具体的风险到底是什么",children:[]},{level:2,title:"4.3 我们要做的安全防护有哪些",slug:"_4-3-我们要做的安全防护有哪些",children:[]},{level:2,title:"4.4 将 SSH 远程登录端口修改为非 22 端口",slug:"_4-4-将-ssh-远程登录端口修改为非-22-端口",children:[]},{level:2,title:"4.5 建立非 root 的新用户",slug:"_4-5-建立非-root-的新用户",children:[]},{level:2,title:"4.6 禁用 root 用户 SSH 远程登录",slug:"_4-6-禁用-root-用户-ssh-远程登录",children:[]},{level:2,title:"4.7 使用 RSA 密钥登录并禁用密码登录",slug:"_4-7-使用-rsa-密钥登录并禁用密码登录",children:[]},{level:2,title:"4.8 你的进度",slug:"_4-8-你的进度",children:[]}],path:"/document/level-0/ch04-security.html",pathLocale:"/",extraFields:[]},{title:"【第 5 章】网站建设篇",headers:[{level:2,title:"5.1 为什么要做一个网站?",slug:"_5-1-为什么要做一个网站",children:[]},{level:2,title:"5.2 登录 VPS、安装运行 Nginx",slug:"_5-2-登录-vps、安装运行-nginx",children:[]},{level:2,title:"5.3 创建一个最简单的网页",slug:"_5-3-创建一个最简单的网页",children:[]},{level:2,title:"5.4 常见错误的说明",slug:"_5-4-常见错误的说明",children:[]},{level:2,title:"5.5 你的进度",slug:"_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-证书",children:[]},{level:2,title:"6.2 安装 acme.sh",slug:"_6-2-安装-acme-sh",children:[]},{level:2,title:"6.3 测试证书申请",slug:"_6-3-测试证书申请",children:[]},{level:2,title:"6.4 正式证书申请",slug:"_6-4-正式证书申请",children:[]},{level:2,title:"6.5 证书安装",slug:"_6-5-证书安装",children:[]},{level:2,title:"6.6 你的进度",slug:"_6-6-你的进度",children:[]}],path:"/document/level-0/ch06-certificates.html",pathLocale:"/",extraFields:[]},{title:"【第 7 章】Xray 服务器篇",headers:[{level:2,title:"7.1 博观而约取,厚积而薄发",slug:"_7-1-博观而约取-厚积而薄发",children:[]},{level:2,title:"7.2 安装 Xray",slug:"_7-2-安装-xray",children:[]},{level:2,title:"7.3 给 Xray 配置 TLS 证书",slug:"_7-3-给-xray-配置-tls-证书",children:[]},{level:2,title:"7.4 配置 Xray",slug:"_7-4-配置-xray",children:[]},{level:2,title:"7.5 启动 Xray 服务!!(并查看服务状态)",slug:"_7-5-启动-xray-服务-并查看服务状态",children:[]},{level:2,title:"7.6 回顾 systemd 进行基本的服务管理",slug:"_7-6-回顾-systemd-进行基本的服务管理",children:[]},{level:2,title:"7.7 服务器优化之一:开启 BBR",slug:"_7-7-服务器优化之一-开启-bbr",children:[]},{level:2,title:"7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS",slug:"_7-8-服务器优化之二-开启-http-自动跳转-https",children:[]},{level:2,title:"7.9 服务器优化之三:更丰富的回落",slug:"_7-9-服务器优化之三-更丰富的回落",children:[]},{level:2,title:"7.10 你的进度",slug:"_7-10-你的进度",children:[]},{level:2,title:"7.11 重要勘误",slug:"_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-的工作原理简述",children:[]},{level:2,title:"8.2 客户端与服务器端正确连接",slug:"_8-2-客户端与服务器端正确连接",children:[]},{level:2,title:"8.3 附加题 1:在 PC 端手工配置 xray-core",slug:"_8-3-附加题-1-在-pc-端手工配置-xray-core",children:[]},{level:2,title:"8.4 附加题 2:在 PC 端手工运行 xray-core",slug:"_8-4-附加题-2-在-pc-端手工运行-xray-core",children:[]},{level:2,title:"8.5 附加题 3:在 PC 端开机自动运行 xray-core",slug:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",children:[]},{level:2,title:"8.6 圆满完成!",slug:"_8-6-圆满完成",children:[]},{level:2,title:"8.7 TO INFINITY AND BEYOND!",slug:"_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-基础命令索引",children:[]},{level:2,title:"2. 小小白白 Linux 重要配置文件索引",slug:"_2-小小白白-linux-重要配置文件索引",children:[]},{level:2,title:"3. 小小白白 Xray 重要文件索引",slug:"_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-回顾《小小白白话文》中的回落",children:[]},{level:2,title:"2. 重新认识回落 (WHAT, HOW v1)",slug:"_2-重新认识回落-what-how-v1",children:[]},{level:2,title:"3. 为什么要回落 (WHY v1)",slug:"_3-为什么要回落-why-v1",children:[]},{level:2,title:"4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)",slug:"_4-重新认识【回落の完全体】-what-why-how-v2",children:[]},{level:2,title:"5. 多层回落示例及解读",slug:"_5-多层回落示例及解读",children:[{level:3,title:"5.1 首先,我将服务器端配置的 443 监听段摘抄如下:",slug:"_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",children:[]},{level:3,title:"5.2 后续监听处理的配置段摘抄如下:",slug:"_5-2-后续监听处理的配置段摘抄如下",children:[]}]},{level:2,title:"6. 结语",slug:"_6-结语",children:[]},{level:2,title:"7. 附加题",slug:"_7-附加题",children:[]}],path:"/document/level-1/fallbacks-lv1.html",pathLocale:"/",extraFields:[]},{title:"SNI 回落",headers:[{level:2,title:"应用情景",slug:"应用情景",children:[]},{level:2,title:"SNI 简介",slug:"sni-简介",children:[]},{level:2,title:"思路",slug:"思路",children:[]},{level:2,title:"添加 DNS 记录",slug:"添加-dns-记录",children:[]},{level:2,title:"申请 TLS 证书",slug:"申请-tls-证书",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",children:[]},{level:2,title:"Nginx 配置",slug:"nginx-配置",children:[]},{level:2,title:"Caddy 配置",slug:"caddy-配置",children:[]},{level:2,title:"参考",slug:"参考",children:[]},{level:2,title:"引用",slug:"引用",children:[]}],path:"/document/level-1/fallbacks-with-sni.html",pathLocale:"/",extraFields:[]},{title:"路由 (routing) 功能简析(上)",headers:[{level:2,title:"1. 初识【路由】三兄弟",slug:"_1-初识【路由】三兄弟",children:[]},{level:2,title:"2. 基本功: “兄弟一条心”",slug:"_2-基本功-兄弟一条心",children:[{level:3,title:"2.1 入站",slug:"_2-1-入站",children:[]},{level:3,title:"2.3 路由",slug:"_2-3-路由",children:[]},{level:3,title:"2.4 路由配置项解析之一:流量筛选的依据",slug:"_2-4-路由配置项解析之一-流量筛选的依据",children:[]}]},{level:2,title:"3. 小试牛刀: “三分天下” 之 “域名分流”",slug:"_3-小试牛刀-三分天下-之-域名分流",children:[{level:3,title:"3.1 入站",slug:"_3-1-入站",children:[]},{level:3,title:"3.2 出站",slug:"_3-2-出站",children:[]},{level:3,title:"3.3 路由",slug:"_3-3-路由",children:[]},{level:3,title:"3.4 简析域名文件: geosite.dat",slug:"_3-4-简析域名文件-geosite-dat",children:[]},{level:3,title:"3.5 所以 geosite.dat 到底是什么?不是有个 GFWList 吗?",slug:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",children:[]},{level:3,title:"3.6 军师锦囊藏奇兵:一条隐藏的路由规则",slug:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",children:[]},{level:3,title:"3.7 再看“三分天下”的大地图",slug:"_3-7-再看-三分天下-的大地图",children:[]}]},{level:2,title:"4. “三分天下” 之 “蜀魏争雄”",slug:"_4-三分天下-之-蜀魏争雄",children:[]},{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",children:[]}],path:"/document/level-1/routing-lv1-part1.html",pathLocale:"/",extraFields:[]},{title:"路由 (routing) 功能简析(下)",headers:[{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",children:[{level:3,title:"5.1 基于指定域名分流:[domain], [full] 等",slug:"_5-1-基于指定域名分流-domain-full-等",children:[]},{level:3,title:"5.2 基于 IP 文件分流:geoip.dat",slug:"_5-2-基于-ip-文件分流-geoip-dat",children:[]},{level:3,title:"5.3 基于指定 IP 地址分流",slug:"_5-3-基于指定-ip-地址分流",children:[]},{level:3,title:"5.4 基于协议类型分流:[protocol] 等",slug:"_5-4-基于协议类型分流-protocol-等",children:[]},{level:3,title:"5.5 基于更多条件的分流",slug:"_5-5-基于更多条件的分流",children:[]}]},{level:2,title:"6. “霸业初定”:路由规则整体回顾",slug:"_6-霸业初定-路由规则整体回顾",children:[]},{level:2,title:"7. 路由配置常见错误",slug:"_7-路由配置常见错误",children:[{level:3,title:"7.1 错误示范",slug:"_7-1-错误示范",children:[]},{level:3,title:"7.2 正确示范",slug:"_7-2-正确示范",children:[]}]},{level:2,title:"8. 明修栈道、暗渡陈仓",slug:"_8-明修栈道、暗渡陈仓",children:[{level:3,title:'8.1 域名策略: "AsIs"',slug:"_8-1-域名策略-asis",children:[]},{level:3,title:'8.2 域名策略: "IPIfNonMatch"',slug:"_8-2-域名策略-ipifnonmatch",children:[]},{level:3,title:'8.3 域名策略: "IPOnDemand"',slug:"_8-3-域名策略-ipondemand",children:[]}]},{level:2,title:"9. 思考题",slug:"_9-思考题",children:[]},{level:2,title:"10. 结语",slug:"_10-结语",children:[]},{level:2,title:"11. 尾注",slug:"_11-尾注",children:[]}],path:"/document/level-1/routing-lv1-part2.html",pathLocale:"/",extraFields:[]},{title:"Xray 的工作模式",headers:[{level:2,title:"单服务器模式",slug:"单服务器模式",children:[]},{level:2,title:"桥接模式",slug:"桥接模式",children:[]},{level:2,title:"工作原理",slug:"工作原理",children:[]}],path:"/document/level-1/work.html",pathLocale:"/",extraFields:[]},{title:"进阶文档",headers:[],path:"/document/level-2/",pathLocale:"/",extraFields:[]},{title:"GID 透明代理",headers:[{level:2,title:"思路",slug:"思路",children:[]},{level:2,title:"配置过程",slug:"配置过程",children:[{level:3,title:"1. 前期准备",slug:"_1-前期准备",children:[]},{level:3,title:"2. 添加用户(安卓用户请忽略)",slug:"_2-添加用户-安卓用户请忽略",children:[]},{level:3,title:"3. 配置运行 Xray,配置 iptables 规则",slug:"_3-配置运行-xray-配置-iptables-规则",children:[]}]},{level:2,title:"下面提供一个实现 tproxy 全局代理的完整配置过程",slug:"下面提供一个实现-tproxy-全局代理的完整配置过程",children:[{level:3,title:"1. 完成 前期准备 和 添加用户",slug:"_1-完成-前期准备-和-添加用户",children:[]},{level:3,title:"2. 准备 Xray 配置文件",slug:"_2-准备-xray-配置文件",children:[]},{level:3,title:"3. 配置最大文件打开数&运行 Xray 客户端",slug:"_3-配置最大文件打开数-运行-xray-客户端",children:[]},{level:3,title:"4. 设置 iptables 规则",slug:"_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",children:[]},{level:2,title:"配置 nginx",slug:"配置-nginx",children:[]},{level:2,title:"xray 配置",slug:"xray-配置",children:[]},{level:2,title:"客户端及服务端启动服务",slug:"客户端及服务端启动服务",children:[]},{level:2,title:"结束",slug:"结束",children:[]},{level:2,title:"HTTPS 隧道",slug:"https-隧道",children:[{level:3,title:"haproxy_client 配置 (运行前去掉注释)",slug:"haproxy-client-配置-运行前去掉注释",children:[]},{level:3,title:"haproxy_server 配置 (运行前去掉注释)",slug:"haproxy-server-配置-运行前去掉注释",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-1",children:[]}]},{level:2,title:"WebSocket over HTTP/2",slug:"websocket-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-2",children:[]}]},{level:2,title:"gRPC over HTTP/2",slug:"grpc-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-1",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-1",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-3",children:[]},{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-2",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-2",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-4",children:[]}]}],path:"/document/level-2/nginx_or_haproxy_tls_tunnel.html",pathLocale:"/",extraFields:[]},{title:"出站流量重定向",headers:[{level:2,title:"前言",slug:"前言",children:[]},{level:2,title:"1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)",slug:"_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",children:[]},{level:2,title:"2、编辑 VPN 配置文件(以 WireGuard 为例)",slug:"_2、编辑-vpn-配置文件-以-wireguard-为例",children:[]},{level:2,title:"3、启用 WireGuard 网络接口",slug:"_3、启用-wireguard-网络接口",children:[]},{level:2,title:"4、Xray-core 配置文件修改",slug:"_4、xray-core-配置文件修改",children:[]},{level:2,title:"5、系统设置配置",slug:"_5、系统设置配置",children:[]},{level:2,title:"6、完成 WireGuard 相关设置",slug:"_6、完成-wireguard-相关设置",children:[]},{level:2,title:"后记",slug:"后记",children:[]},{level:2,title:"感谢",slug:"感谢",children:[]}],path:"/document/level-2/redirect.html",pathLocale:"/",extraFields:[]},{title:"TProxy 透明代理",headers:[{level:2,title:"开始之前",slug:"开始之前",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",children:[]},{level:2,title:"策略路由配置",slug:"策略路由配置",children:[]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",children:[]},{level:2,title:"配置永久化与开机自启",slug:"配置永久化与开机自启",children:[]}],path:"/document/level-2/tproxy.html",pathLocale:"/",extraFields:[]},{title:"TProxy 透明代理 (ipv4 and ipv6)",headers:[{level:2,title:"Xray 配置",slug:"xray-配置",children:[{level:3,title:"客户端配置",slug:"客户端配置",children:[]},{level:3,title:"服务端配置",slug:"服务端配置",children:[]}]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",children:[{level:3,title:"首先设置策略路由",slug:"首先设置策略路由",children:[]},{level:3,title:"使用 iptables",slug:"使用-iptables",children:[]},{level:3,title:"使用 nftables",slug:"使用-nftables",children:[]},{level:3,title:"开机自动运行 Netfilter 配置",slug:"开机自动运行-netfilter-配置",children:[]}]},{level:2,title:"局域网设备上网设置",slug:"局域网设备上网设置",children:[{level:3,title:"方法一",slug:"方法一",children:[]},{level:3,title:"方法二",slug:"方法二",children:[]}]},{level:2,title:"Finally",slug:"finally",children:[]},{level:2,title:"写在最后",slug:"写在最后",children:[]}],path:"/document/level-2/tproxy_ipv4_and_ipv6.html",pathLocale:"/",extraFields:[]},{title:"流量统计",headers:[{level:2,title:"查看流量信息",slug:"查看流量信息",children:[]},{level:2,title:"流量信息的处理",slug:"流量信息的处理",children:[]}],path:"/document/level-2/traffic_stats.html",pathLocale:"/",extraFields:[]},{title:"通过 Cloudflare Warp 增强代理安全性",headers:[{level:2,title:"申请 Warp 账户",slug:"申请-warp-账户",children:[]},{level:2,title:"在服务端分流回国流量至 warp",slug:"在服务端分流回国流量至-warp",children:[]},{level:2,title:"客户端使用 warp 链式代理",slug:"客户端使用-warp-链式代理",children:[]}],path:"/document/level-2/warp.html",pathLocale:"/",extraFields:[]},{title:"大史记",headers:[{level:2,title:"2021.4.6",slug:"_2021-4-6",children:[]},{level:2,title:"2021.4.4",slug:"_2021-4-4",children:[]},{level:2,title:"2021.4.1 v1.4.2",slug:"_2021-4-1-v1-4-2",children:[]},{level:2,title:"2021.3.25",slug:"_2021-3-25",children:[]},{level:2,title:"2021.3.15",slug:"_2021-3-15",children:[]},{level:2,title:"2021.3.14 v1.4.0",slug:"_2021-3-14-v1-4-0",children:[]},{level:2,title:"2021.3.3 1.3.1",slug:"_2021-3-3-1-3-1",children:[]},{level:2,title:"2021.2.14 1.3.0",slug:"_2021-2-14-1-3-0",children:[]},{level:2,title:"2021.01.31 1.2.4",slug:"_2021-01-31-1-2-4",children:[]},{level:2,title:"2021.01.25",slug:"_2021-01-25",children:[]},{level:2,title:"2021.01.22 1.2.3",slug:"_2021-01-22-1-2-3",children:[]},{level:2,title:"2021.01.19",slug:"_2021-01-19",children:[]},{level:2,title:"2021.01.17",slug:"_2021-01-17",children:[]},{level:2,title:"2021.01.15 1.2.2",slug:"_2021-01-15-1-2-2",children:[]},{level:2,title:"2021.01.12",slug:"_2021-01-12",children:[]},{level:2,title:"2021.01.10 1.2.1",slug:"_2021-01-10-1-2-1",children:[]},{level:2,title:"2021.01.07",slug:"_2021-01-07",children:[]},{level:2,title:"2021.01.05",slug:"_2021-01-05",children:[]},{level:2,title:"2021.01.03",slug:"_2021-01-03",children:[]},{level:2,title:"2021.01.01",slug:"_2021-01-01",children:[]},{level:2,title:"2020.12.29",slug:"_2020-12-29",children:[]},{level:2,title:"2020.12.25 1.1.5",slug:"_2020-12-25-1-1-5",children:[]},{level:2,title:"2020.12.24",slug:"_2020-12-24",children:[]},{level:2,title:"2020.12.23",slug:"_2020-12-23",children:[]},{level:2,title:"2020.12.21",slug:"_2020-12-21",children:[]},{level:2,title:"2020.12.18 1.1.4",slug:"_2020-12-18-1-1-4",children:[]},{level:2,title:"2020.12.17",slug:"_2020-12-17",children:[]},{level:2,title:"2020.12.15",slug:"_2020-12-15",children:[]},{level:2,title:"2020.12.11 1.1.3",slug:"_2020-12-11-1-1-3",children:[]},{level:2,title:"2020.12.06 1.1.2",slug:"_2020-12-06-1-1-2",children:[]},{level:2,title:"2020.12.04",slug:"_2020-12-04",children:[]},{level:2,title:"2020.11.27",slug:"_2020-11-27",children:[]},{level:2,title:"2020.11.25 1.0.0",slug:"_2020-11-25-1-0-0",children:[]},{level:2,title:"2020.11.23",slug:"_2020-11-23",children:[]}],path:"/en/about/news.html",pathLocale:"/en/",extraFields:[]},{title:"Configurations",headers:[{level:2,title:"Overview",slug:"overview",children:[]},{level:2,title:"Basic Configuration Modules",slug:"basic-configuration-modules",children:[]}],path:"/en/config/",pathLocale:"/en/",extraFields:[]},{title:"API Interface",headers:[{level:2,title:"ApiObject",slug:"apiobject",children:[]},{level:2,title:"Related Configuration",slug:"related-configuration",children:[]},{level:2,title:"Supported API List",slug:"supported-api-list",children:[{level:3,title:"HandlerService",slug:"handlerservice",children:[]},{level:3,title:"LoggerService",slug:"loggerservice",children:[]},{level:3,title:"StatsService",slug:"statsservice",children:[]},{level:3,title:"ReflectionService",slug:"reflectionservice",children:[]}]},{level:2,title:"API Calling Example",slug:"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",children:[]},{level:2,title:"DNS Processing Flow",slug:"dns-processing-flow",children:[]},{level:2,title:"DnsObject",slug:"dnsobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/dns.html",pathLocale:"/en/",extraFields:[]},{title:"FakeDNS",headers:[{level:2,title:"FakeDNSObject",slug:"fakednsobject",children:[{level:3,title:"How to use?",slug:"how-to-use",children:[]},{level:3,title:"Using with other types of DNS",slug:"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",children:[{level:3,title:"SniffingObject",slug:"sniffingobject",children:[]},{level:3,title:"AllocateObject",slug:"allocateobject",children:[]}]}],path:"/en/config/inbound.html",pathLocale:"/en/",extraFields:[]},{title:"Log Configuration",headers:[{level:2,title:"LogObject",slug:"logobject",children:[]}],path:"/en/config/log.html",pathLocale:"/en/",extraFields:[]},{title:"Outbound Proxies",headers:[{level:2,title:"OutboundObject",slug:"outboundobject",children:[{level:3,title:"ProxySettingsObject",slug:"proxysettingsobject",children:[]},{level:3,title:"MuxObject",slug:"muxobject",children:[]}]}],path:"/en/config/outbound.html",pathLocale:"/en/",extraFields:[]},{title:"Local Policy",headers:[{level:2,title:"PolicyObject",slug:"policyobject",children:[{level:3,title:"LevelPolicyObject",slug:"levelpolicyobject",children:[]},{level:3,title:"SystemPolicyObject",slug:"systempolicyobject",children:[]}]}],path:"/en/config/policy.html",pathLocale:"/en/",extraFields:[]},{title:"Reverse Proxy",headers:[{level:2,title:"ReverseObject",slug:"reverseobject",children:[{level:3,title:"BridgeObject",slug:"bridgeobject",children:[]},{level:3,title:"PortalObject",slug:"portalobject",children:[]}]},{level:2,title:"Complete Configuration Example",slug:"complete-configuration-example",children:[{level:3,title:"Bridge Configuration",slug:"bridge-configuration",children:[]},{level:3,title:"Portal Configuration",slug:"portal-configuration",children:[]}]}],path:"/en/config/reverse.html",pathLocale:"/en/",extraFields:[]},{title:"Routing",headers:[{level:2,title:"RoutingObject",slug:"routingobject",children:[{level:3,title:"RuleObject",slug:"ruleobject",children:[]},{level:3,title:"BalancerObject",slug:"balancerobject",children:[]},{level:3,title:"Predefined Domain Lists",slug:"predefined-domain-lists",children:[]}]}],path:"/en/config/routing.html",pathLocale:"/en/",extraFields:[]},{title:"Traffic Statistics",headers:[{level:2,title:"StatsObject",slug:"statsobject",children:[]},{level:2,title:"Retrieving Traffic Statistics",slug:"retrieving-traffic-statistics",children:[]}],path:"/en/config/stats.html",pathLocale:"/en/",extraFields:[]},{title:"Transport Protocol",headers:[{level:2,title:"TransportObject",slug:"transportobject",children:[]},{level:2,title:"StreamSettingsObject",slug:"streamsettingsobject",children:[{level:3,title:"TLSObject",slug:"tlsobject",children:[]},{level:3,title:"SockoptObject",slug:"sockoptobject",children:[]}]}],path:"/en/config/transport.html",pathLocale:"/en/",extraFields:[]},{title:"Development Guide",headers:[{level:2,title:"Compile Documentation",slug:"compile-documentation",children:[]},{level:2,title:"Design Concept",slug:"design-concept",children:[]},{level:2,title:"Development Standards",slug:"development-standards",children:[]},{level:2,title:"Protocol Details",slug:"protocol-details",children:[{level:3,title:"VLESS Protocol",slug:"vless-protocol",children:[]},{level:3,title:"VMess Protocol",slug:"vmess-protocol",children:[]},{level:3,title:"Mux.Cool Protocol",slug:"mux-cool-protocol",children:[]},{level:3,title:"mKCP Protocol",slug:"mkcp-protocol",children:[]}]}],path:"/en/development/",pathLocale:"/en/",extraFields:[]},{title:"Quick Start",headers:[{level:2,title:"Download and Install",slug:"download-and-install",children:[]},{level:2,title:"Configure and Run",slug:"configure-and-run",children:[]},{level:2,title:"Command Parameters",slug:"command-parameters",children:[]},{level:2,title:"Improve Documents",slug:"improve-documents",children:[]},{level:2,title:"Beginner Tutorial",slug:"beginner-tutorial",children:[]},{level:2,title:"Getting Started Tips",slug:"getting-started-tips",children:[]},{level:2,title:"Advanced Documentation",slug:"advanced-documentation",children:[]}],path:"/en/document/",pathLocale:"/en/",extraFields:[]},{title:"Command Parameters",headers:[{level:2,title:"Get Basic Commands",slug:"get-basic-commands",children:[{level:3,title:"xray run",slug:"xray-run",children:[]},{level:3,title:"xray version",slug:"xray-version",children:[]},{level:3,title:"xray api",slug:"xray-api",children:[]},{level:3,title:"xray tls",slug:"xray-tls",children:[]},{level:3,title:"xray uuid",slug:"xray-uuid",children:[]}]}],path:"/en/document/command.html",pathLocale:"/en/",extraFields:[]},{title:"Configure and Run",headers:[{level:2,title:"Server Configuration",slug:"server-configuration",children:[]},{level:2,title:"Client Configuration",slug:"client-configuration",children:[]},{level:2,title:"Run",slug:"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",children:[]},{level:2,title:"Found Problems?",slug:"found-problems",children:[]}],path:"/en/document/document.html",pathLocale:"/en/",extraFields:[]},{title:"Download and Install",headers:[{level:2,title:"Platform Support",slug:"platform-support",children:[]},{level:2,title:"Download Xray",slug:"download-xray",children:[]},{level:2,title:"Verify the Installation Package",slug:"verify-the-installation-package",children:[]},{level:2,title:"Install on Windows",slug:"install-on-windows",children:[]},{level:2,title:"Install on macOS",slug:"install-on-macos",children:[]},{level:2,title:"Install on Linux",slug:"install-on-linux",children:[{level:3,title:"Install Script",slug:"install-script",children:[]},{level:3,title:"Arch Linux",slug:"arch-linux",children:[]},{level:3,title:"Linuxbrew",slug:"linuxbrew",children:[]},{level:3,title:"Debian",slug:"debian",children:[]}]},{level:2,title:"Install via Docker",slug:"install-via-docker",children:[{level:3,title:"The File Structure of the Docker Image",slug:"the-file-structure-of-the-docker-image",children:[]}]}],path:"/en/document/install.html",pathLocale:"/en/",extraFields:[]},{title:"透明代理入门",headers:[{level:2,title:"什么是透明代理",slug:"什么是透明代理",children:[]},{level:2,title:"透明代理的实现",slug:"透明代理的实现",children:[{level:3,title:"tun2socks",slug:"tun2socks",children:[]},{level:3,title:"iptables/nftables",slug:"iptables-nftables",children:[]}]},{level:2,title:"iptables 实现透明代理原理",slug:"iptables-实现透明代理原理",children:[]},{level:2,title:"透明代理难在哪里",slug:"透明代理难在哪里",children:[]},{level:2,title:"从零开始一步步实现基于 iptables-tproxy 的透明代理",slug:"从零开始一步步实现基于-iptables-tproxy-的透明代理",children:[{level:3,title:"在开始之前,你需要有一定的基础知识:",slug:"在开始之前-你需要有一定的基础知识",children:[]},{level:3,title:"前期准备工作",slug:"前期准备工作",children:[]},{level:3,title:"首先,我们先试试做到第一阶段",slug:"首先-我们先试试做到第一阶段",children:[]},{level:3,title:"第二阶段",slug:"第二阶段",children:[]},{level:3,title:"第三阶段",slug:"第三阶段",children:[]},{level:3,title:"第四阶段",slug:"第四阶段",children:[]},{level:3,title:"代理 ipv6",slug:"代理-ipv6",children:[]}]}],path:"/document/level-2/transparent_proxy/transparent_proxy.html",pathLocale:"/",extraFields:[]},{title:"Browser Dialer",headers:[{level:2,title:"Background",slug:"background",children:[]},{level:2,title:"Xray & JS",slug:"xray-js",children:[]},{level:2,title:"Early data",slug:"early-data",children:[]},{level:2,title:"Configuration",slug:"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",children:[]},{level:2,title:"Configuration File Location",slug:"configuration-file-location",children:[]},{level:2,title:"Multiple Configuration Directories",slug:"multiple-configuration-directories",children:[]}],path:"/en/config/features/env.html",pathLocale:"/en/",extraFields:[]},{title:"Fallback",headers:[{level:2,title:"fallbacks configuration",slug:"fallbacks-configuration",children:[{level:3,title:"FallbackObject",slug:"fallbackobject",children:[]},{level:3,title:"Additional Information",slug:"additional-information",children:[]}]},{level:2,title:"Fallbacks design theory",slug:"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",children:[]},{level:2,title:"Rule Explaination",slug:"rule-explaination",children:[{level:3,title:"Normal Objects({})",slug:"normal-objects",children:[]},{level:3,title:"Arrays([])",slug:"arrays",children:[]}]},{level:2,title:"Recommended Multi-file List",slug:"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",children:[]},{level:2,title:"Transparent Proxy Configuration Example",slug:"transparent-proxy-configuration-example",children:[]}],path:"/en/config/inbounds/dokodemo.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",children:[]}]}],path:"/en/config/inbounds/http.html",pathLocale:"/en/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[]},{level:2,title:"ClientObject",slug:"clientobject",children:[]}],path:"/en/config/inbounds/shadowsocks.html",pathLocale:"/en/",extraFields:[]},{title:"SOCKS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",children:[]}]}],path:"/en/config/inbounds/socks.html",pathLocale:"/en/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]}]}],path:"/en/config/inbounds/trojan.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]}]}],path:"/en/config/inbounds/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]},{level:3,title:"DetourObject",slug:"detourobject",children:[]},{level:3,title:"DefaultObject",slug:"defaultobject",children:[]}]}],path:"/en/config/inbounds/vmess.html",pathLocale:"/en/",extraFields:[]},{title:"Blackhole",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ResponseObject",slug:"responseobject",children:[]}]}],path:"/en/config/outbounds/blackhole.html",pathLocale:"/en/",extraFields:[]},{title:"DNS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[]},{level:2,title:"DNS Configuration Example",slug:"dns-configuration-example",children:[]}],path:"/en/config/outbounds/dns.html",pathLocale:"/en/",extraFields:[]},{title:"Freedom",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[]}],path:"/en/config/outbounds/freedom.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/outbounds/http.html",pathLocale:"/en/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/outbounds/shadowsocks.html",pathLocale:"/en/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/outbounds/socks.html",pathLocale:"/en/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/outbounds/trojan.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]},{level:3,title:"UserObject",slug:"userobject",children:[]}]}],path:"/en/config/outbounds/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/outbounds/vmess.html",pathLocale:"/en/",extraFields:[]},{title:"Wireguard",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"Peers",slug:"peers",children:[]}]}],path:"/en/config/outbounds/wireguard.html",pathLocale:"/en/",extraFields:[]},{title:"Domain Socket",headers:[{level:2,title:"DomainSocketObject",slug:"domainsocketobject",children:[]}],path:"/en/config/transports/domainsocket.html",pathLocale:"/en/",extraFields:[]},{title:"gRPC",headers:[{level:2,title:"GRPCObject",slug:"grpcobject",children:[]}],path:"/en/config/transports/grpc.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP/2",headers:[{level:2,title:"HttpObject",slug:"httpobject",children:[]}],path:"/en/config/transports/h2.html",pathLocale:"/en/",extraFields:[]},{title:"mKCP",headers:[{level:2,title:"KcpObject",slug:"kcpobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",children:[]}]},{level:2,title:"Special Thanks",slug:"special-thanks",children:[]},{level:2,title:"Improvements to the KCP protocol",slug:"improvements-to-the-kcp-protocol",children:[{level:3,title:"smaller protocol header",slug:"smaller-protocol-header",children:[]},{level:3,title:"ACK packet retransmission",slug:"ack-packet-retransmission",children:[]},{level:3,title:"Connection state control",slug:"connection-state-control",children:[]}]}],path:"/en/config/transports/mkcp.html",pathLocale:"/en/",extraFields:[]},{title:"QUIC",headers:[{level:2,title:"QuicObject",slug:"quicobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",children:[]}]}],path:"/en/config/transports/quic.html",pathLocale:"/en/",extraFields:[]},{title:"TCP",headers:[{level:2,title:"TcpObject",slug:"tcpobject",children:[{level:3,title:"NoneHeaderObject",slug:"noneheaderobject",children:[]},{level:3,title:"HttpHeaderObject",slug:"httpheaderobject",children:[]}]}],path:"/en/config/transports/tcp.html",pathLocale:"/en/",extraFields:[]},{title:"WebSocket",headers:[{level:2,title:"WebSocketObject",slug:"websocketobject",children:[]},{level:2,title:"Browser Dialer",slug:"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",children:[]},{level:2,title:"Pull Xray source code",slug:"pull-xray-source-code",children:[]},{level:2,title:"Build Binary",slug:"build-binary",children:[{level:3,title:"Windows(Powershell):",slug:"windows-powershell",children:[]},{level:3,title:"macOS, Linux:",slug:"macos-linux",children:[]}]},{level:2,title:"Cross compilation:",slug:"cross-compilation",children:[]},{level:2,title:"Reproducible Build:",slug:"reproducible-build",children:[]}],path:"/en/development/intro/compile.html",pathLocale:"/en/",extraFields:[]},{title:"Design Objectives",headers:[{level:2,title:"Architecture",slug:"architecture",children:[{level:3,title:"Application Layer",slug:"application-layer",children:[]},{level:3,title:"Proxy Layer",slug:"proxy-layer",children:[]},{level:3,title:"Transport Layer",slug:"transport-layer",children:[]}]}],path:"/en/development/intro/design.html",pathLocale:"/en/",extraFields:[]},{title:"Development Standards",headers:[{level:2,title:"Basic",slug:"basic",children:[{level:3,title:"Version Control",slug:"version-control",children:[]},{level:3,title:"Branch",slug:"branch",children:[]},{level:3,title:"Release",slug:"release",children:[]},{level:3,title:"Citing other projects",slug:"citing-other-projects",children:[]}]},{level:2,title:"Development Process",slug:"development-process",children:[{level:3,title:"Before Writing Code",slug:"before-writing-code",children:[]},{level:3,title:"Modify the code",slug:"modify-the-code",children:[]},{level:3,title:"Pull Request",slug:"pull-request",children:[]},{level:3,title:"Modifying Code",slug:"modifying-code",children:[]}]},{level:2,title:"Xray Coding Guidelines",slug:"xray-coding-guidelines",children:[{level:3,title:"Code Structure",slug:"code-structure",children:[]},{level:3,title:"Coding Standards",slug:"coding-standards",children:[]}]}],path:"/en/development/intro/guide.html",pathLocale:"/en/",extraFields:[]},{title:"mKCP Protocol",headers:[{level:2,title:"Version",slug:"version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",children:[]},{level:3,title:"Functions",slug:"functions",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",children:[]},{level:2,title:"Data Format",slug:"data-format",children:[{level:3,title:"Data Packet",slug:"data-packet",children:[]},{level:3,title:"Data snippet",slug:"data-snippet",children:[]},{level:3,title:"Confirmation snippet",slug:"confirmation-snippet",children:[]},{level:3,title:"Heartbeat Fragments",slug:"heartbeat-fragments",children:[]}]}],path:"/en/development/protocols/mkcp.html",pathLocale:"/en/",extraFields:[]},{title:"Mux.Cool Protocol",headers:[{level:2,title:"Version",slug:"version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",children:[{level:3,title:"Client behavior",slug:"client-behavior",children:[]},{level:3,title:"Server-side behavior",slug:"server-side-behavior",children:[]}]},{level:2,title:"Data Format",slug:"data-format",children:[{level:3,title:"Frame Format",slug:"frame-format",children:[]},{level:3,title:"Metadata",slug:"metadata",children:[]},{level:3,title:"New Sublink (New)",slug:"new-sublink-new",children:[]},{level:3,title:"Keep sub-connections",slug:"keep-sub-connections",children:[]},{level:3,title:"End",slug:"end",children:[]},{level:3,title:"KeepAlive",slug:"keepalive",children:[]}]},{level:2,title:"Application",slug:"application",children:[]}],path:"/en/development/protocols/muxcool.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS Protocol",headers:[{level:2,title:"Request & Response",slug:"request-response",children:[]},{level:2,title:"ProtoBuf",slug:"protobuf",children:[]},{level:2,title:"Flow",slug:"flow",children:[{level:3,title:"Flow Control (Formerly Traffic Scheduler)",slug:"flow-control-formerly-traffic-scheduler",children:[]}]},{level:2,title:"Encryption",slug:"encryption",children:[]},{level:2,title:"UDP issues",slug:"udp-issues",children:[]},{level:2,title:"Client Development Guide",slug:"client-development-guide",children:[]},{level:2,title:"VLESS Sharing Link Standard",slug:"vless-sharing-link-standard",children:[]}],path:"/en/development/protocols/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess Protocol",headers:[{level:2,title:"Version",slug:"version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",children:[]},{level:3,title:"User ID",slug:"user-id",children:[]},{level:3,title:"Functions",slug:"functions",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",children:[]},{level:2,title:"Client Request",slug:"client-request",children:[{level:3,title:"Authentication Information",slug:"authentication-information",children:[]},{level:3,title:"Command Section",slug:"command-section",children:[]},{level:3,title:"Data Section",slug:"data-section",children:[]}]},{level:2,title:"Server Response",slug:"server-response",children:[{level:3,title:"Dynamic Port Instructions",slug:"dynamic-port-instructions",children:[]}]},{level:2,title:"Comment",slug:"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",children:[]},{level:2,title:"1.2 Who is this document not written for?",slug:"_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",children:[]},{level:2,title:"1.4 Why is self-hosting a challenge?",slug:"_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",children:[]},{level:2,title:"1.6 So should you build your own website?",slug:"_1-6-so-should-you-build-your-own-website",children:[]},{level:2,title:"1.7 Some digressions",slug:"_1-7-some-digressions",children:[]},{level:2,title:"1.8 Your Progress",slug:"_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",children:[]},{level:2,title:"2.2 Obtaining a Desired Domain Name",slug:"_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",children:[]},{level:2,title:"2.4 Your Progress",slug:"_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",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",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",children:[]},{level:2,title:"3.4 Your Progress",slug:"_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",children:[]},{level:2,title:"4.2 What are the specific risks",slug:"_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",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",children:[]},{level:2,title:"4.5 Creating a New User Without Root Access",slug:"_4-5-creating-a-new-user-without-root-access",children:[]},{level:2,title:"4.6 Disabling SSH Remote Login for Root User",slug:"_4-6-disabling-ssh-remote-login-for-root-user",children:[]},{level:2,title:"4.7 Login with RSA Key and Disable Password Login",slug:"_4-7-login-with-rsa-key-and-disable-password-login",children:[]},{level:2,title:"4.8 Your Progress",slug:"_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",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",children:[]},{level:2,title:"5.3 Create the simplest web page",slug:"_5-3-create-the-simplest-web-page",children:[]},{level:2,title:"5.4 Common error explanations",slug:"_5-4-common-error-explanations",children:[]},{level:2,title:"5.5 Your Progress",slug:"_5-5-your-progress",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",children:[]},{level:2,title:"6.2 Install acme.sh",slug:"_6-2-install-acme-sh",children:[]},{level:2,title:"6.3 Testing Certificate Application",slug:"_6-3-testing-certificate-application",children:[]},{level:2,title:"6.4 Application for Official Certification",slug:"_6-4-application-for-official-certification",children:[]},{level:2,title:"6.5 Certificate Installation",slug:"_6-5-certificate-installation",children:[]},{level:2,title:"6.6 Your Progress",slug:"_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-博观而约取-厚积而薄发",children:[]},{level:2,title:"7.2 安装 Xray",slug:"_7-2-安装-xray",children:[]},{level:2,title:"7.3 给 Xray 配置 TLS 证书",slug:"_7-3-给-xray-配置-tls-证书",children:[]},{level:2,title:"7.4 配置 Xray",slug:"_7-4-配置-xray",children:[]},{level:2,title:"7.5 启动 Xray 服务!!(并查看服务状态)",slug:"_7-5-启动-xray-服务-并查看服务状态",children:[]},{level:2,title:"7.6 回顾 systemd 进行基本的服务管理",slug:"_7-6-回顾-systemd-进行基本的服务管理",children:[]},{level:2,title:"7.7 服务器优化之一:开启 BBR",slug:"_7-7-服务器优化之一-开启-bbr",children:[]},{level:2,title:"7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS",slug:"_7-8-服务器优化之二-开启-http-自动跳转-https",children:[]},{level:2,title:"7.9 服务器优化之三:更丰富的回落",slug:"_7-9-服务器优化之三-更丰富的回落",children:[]},{level:2,title:"7.10 你的进度",slug:"_7-10-你的进度",children:[]},{level:2,title:"7.11 重要勘误",slug:"_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-的工作原理简述",children:[]},{level:2,title:"8.2 客户端与服务器端正确连接",slug:"_8-2-客户端与服务器端正确连接",children:[]},{level:2,title:"8.3 附加题 1:在 PC 端手工配置 xray-core",slug:"_8-3-附加题-1-在-pc-端手工配置-xray-core",children:[]},{level:2,title:"8.4 附加题 2:在 PC 端手工运行 xray-core",slug:"_8-4-附加题-2-在-pc-端手工运行-xray-core",children:[]},{level:2,title:"8.5 附加题 3:在 PC 端开机自动运行 xray-core",slug:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",children:[]},{level:2,title:"8.6 圆满完成!",slug:"_8-6-圆满完成",children:[]},{level:2,title:"8.7 TO INFINITY AND BEYOND!",slug:"_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-基础命令索引",children:[]},{level:2,title:"2. 小小白白 Linux 重要配置文件索引",slug:"_2-小小白白-linux-重要配置文件索引",children:[]},{level:2,title:"3. 小小白白 Xray 重要文件索引",slug:"_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-回顾《小小白白话文》中的回落",children:[]},{level:2,title:"2. 重新认识回落 (WHAT, HOW v1)",slug:"_2-重新认识回落-what-how-v1",children:[]},{level:2,title:"3. 为什么要回落 (WHY v1)",slug:"_3-为什么要回落-why-v1",children:[]},{level:2,title:"4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)",slug:"_4-重新认识【回落の完全体】-what-why-how-v2",children:[]},{level:2,title:"5. 多层回落示例及解读",slug:"_5-多层回落示例及解读",children:[{level:3,title:"5.1 首先,我将服务器端配置的 443 监听段摘抄如下:",slug:"_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",children:[]},{level:3,title:"5.2 后续监听处理的配置段摘抄如下:",slug:"_5-2-后续监听处理的配置段摘抄如下",children:[]}]},{level:2,title:"6. 结语",slug:"_6-结语",children:[]},{level:2,title:"7. 附加题",slug:"_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",children:[]},{level:2,title:"Introduction to SNI",slug:"introduction-to-sni",children:[]},{level:2,title:"Idea",slug:"idea",children:[]},{level:2,title:"Adding DNS Records",slug:"adding-dns-records",children:[]},{level:2,title:"Applying for TLS Certificate",slug:"applying-for-tls-certificate",children:[]},{level:2,title:"Xray Configuration",slug:"xray-configuration",children:[]},{level:2,title:"Nginx Configuration",slug:"nginx-configuration",children:[]},{level:2,title:"Caddy Configuration",slug:"caddy-configuration",children:[]},{level:2,title:"Reference",slug:"reference",children:[]},{level:2,title:"Quotation",slug:"quotation",children:[]}],path:"/en/document/level-1/fallbacks-with-sni.html",pathLocale:"/en/",extraFields:[]},{title:"路由 (routing) 功能简析(上)",headers:[{level:2,title:"1. 初识【路由】三兄弟",slug:"_1-初识【路由】三兄弟",children:[]},{level:2,title:"2. 基本功: “兄弟一条心”",slug:"_2-基本功-兄弟一条心",children:[{level:3,title:"2.1 入站",slug:"_2-1-入站",children:[]},{level:3,title:"2.3 路由",slug:"_2-3-路由",children:[]},{level:3,title:"2.4 路由配置项解析之一:流量筛选的依据",slug:"_2-4-路由配置项解析之一-流量筛选的依据",children:[]}]},{level:2,title:"3. 小试牛刀: “三分天下” 之 “域名分流”",slug:"_3-小试牛刀-三分天下-之-域名分流",children:[{level:3,title:"3.1 入站",slug:"_3-1-入站",children:[]},{level:3,title:"3.2 出站",slug:"_3-2-出站",children:[]},{level:3,title:"3.3 路由",slug:"_3-3-路由",children:[]},{level:3,title:"3.4 简析域名文件: geosite.dat",slug:"_3-4-简析域名文件-geosite-dat",children:[]},{level:3,title:"3.5 所以 geosite.dat 到底是什么?不是有个 GFWList 吗?",slug:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",children:[]},{level:3,title:"3.6 军师锦囊藏奇兵:一条隐藏的路由规则",slug:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",children:[]},{level:3,title:"3.7 再看“三分天下”的大地图",slug:"_3-7-再看-三分天下-的大地图",children:[]}]},{level:2,title:"4. “三分天下” 之 “蜀魏争雄”",slug:"_4-三分天下-之-蜀魏争雄",children:[]},{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",children:[]}],path:"/en/document/level-1/routing-lv1-part1.html",pathLocale:"/en/",extraFields:[]},{title:"路由 (routing) 功能简析(下)",headers:[{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",children:[{level:3,title:"5.1 基于指定域名分流:[domain], [full] 等",slug:"_5-1-基于指定域名分流-domain-full-等",children:[]},{level:3,title:"5.2 基于 IP 文件分流:geoip.dat",slug:"_5-2-基于-ip-文件分流-geoip-dat",children:[]},{level:3,title:"5.3 基于指定 IP 地址分流",slug:"_5-3-基于指定-ip-地址分流",children:[]},{level:3,title:"5.4 基于协议类型分流:[protocol] 等",slug:"_5-4-基于协议类型分流-protocol-等",children:[]},{level:3,title:"5.5 基于更多条件的分流",slug:"_5-5-基于更多条件的分流",children:[]}]},{level:2,title:"6. “霸业初定”:路由规则整体回顾",slug:"_6-霸业初定-路由规则整体回顾",children:[]},{level:2,title:"7. 路由配置常见错误",slug:"_7-路由配置常见错误",children:[{level:3,title:"7.1 错误示范",slug:"_7-1-错误示范",children:[]},{level:3,title:"7.2 正确示范",slug:"_7-2-正确示范",children:[]}]},{level:2,title:"8. 明修栈道、暗渡陈仓",slug:"_8-明修栈道、暗渡陈仓",children:[{level:3,title:'8.1 域名策略: "AsIs"',slug:"_8-1-域名策略-asis",children:[]},{level:3,title:'8.2 域名策略: "IPIfNonMatch"',slug:"_8-2-域名策略-ipifnonmatch",children:[]},{level:3,title:'8.3 域名策略: "IPOnDemand"',slug:"_8-3-域名策略-ipondemand",children:[]}]},{level:2,title:"9. 思考题",slug:"_9-思考题",children:[]},{level:2,title:"10. 结语",slug:"_10-结语",children:[]},{level:2,title:"11. 尾注",slug:"_11-尾注",children:[]}],path:"/en/document/level-1/routing-lv1-part2.html",pathLocale:"/en/",extraFields:[]},{title:"Xray 的工作模式",headers:[{level:2,title:"单服务器模式",slug:"单服务器模式",children:[]},{level:2,title:"桥接模式",slug:"桥接模式",children:[]},{level:2,title:"工作原理",slug:"工作原理",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",children:[]},{level:2,title:"Configuration Procedure",slug:"configuration-procedure",children:[{level:3,title:"1. Preliminary preparation",slug:"_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",children:[]},{level:3,title:"3. Configure and run Xray, and configure iptables rules",slug:"_3-configure-and-run-xray-and-configure-iptables-rules",children:[]}]},{level:2,title:"Steps",slug:"steps",children:[{level:3,title:"1. Finish Preliminary preparation and Add user",slug:"_1-finish-preliminary-preparation-and-add-user",children:[]},{level:3,title:"2. Preparing Xray profiles",slug:"_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",children:[]},{level:3,title:"4. Setting up iptables rules",slug:"_4-setting-up-iptables-rules",children:[]}]}],path:"/en/document/level-2/iptables_gid.html",pathLocale:"/en/",extraFields:[]},{title:"Nginx_TLS隧道隐藏指纹",headers:[{level:2,title:"编译 nginx --with-stream",slug:"编译-nginx-with-stream",children:[]},{level:2,title:"配置 nginx",slug:"配置-nginx",children:[]},{level:2,title:"xray 配置",slug:"xray-配置",children:[]},{level:2,title:"客户端及服务端启动服务",slug:"客户端及服务端启动服务",children:[]},{level:2,title:"后记",slug:"后记",children:[]}],path:"/en/document/level-2/nginx_tls_tunnel.html",pathLocale:"/en/",extraFields:[]},{title:"出站流量重定向",headers:[{level:2,title:"前言",slug:"前言",children:[]},{level:2,title:"1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)",slug:"_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",children:[]},{level:2,title:"2、编辑 VPN 配置文件(以 WireGuard 为例)",slug:"_2、编辑-vpn-配置文件-以-wireguard-为例",children:[]},{level:2,title:"3、启用 WireGuard 网络接口",slug:"_3、启用-wireguard-网络接口",children:[]},{level:2,title:"4、Xray-core 配置文件修改",slug:"_4、xray-core-配置文件修改",children:[]},{level:2,title:"5、系统设置配置",slug:"_5、系统设置配置",children:[]},{level:2,title:"6、完成 WireGuard 相关设置",slug:"_6、完成-wireguard-相关设置",children:[]},{level:2,title:"后记",slug:"后记",children:[]},{level:2,title:"感谢",slug:"感谢",children:[]}],path:"/en/document/level-2/redirect.html",pathLocale:"/en/",extraFields:[]},{title:"TProxy 透明代理",headers:[{level:2,title:"开始之前",slug:"开始之前",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",children:[]},{level:2,title:"策略路由配置",slug:"策略路由配置",children:[]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",children:[]},{level:2,title:"配置永久化与开机自启",slug:"配置永久化与开机自启",children:[]}],path:"/en/document/level-2/tproxy.html",pathLocale:"/en/",extraFields:[]},{title:"TProxy 透明代理 (ipv4 and ipv6)",headers:[{level:2,title:"Xray 配置",slug:"xray-配置",children:[{level:3,title:"客户端配置",slug:"客户端配置",children:[]},{level:3,title:"服务端配置",slug:"服务端配置",children:[]}]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",children:[{level:3,title:"首先设置策略路由",slug:"首先设置策略路由",children:[]},{level:3,title:"使用 iptables",slug:"使用-iptables",children:[]},{level:3,title:"使用 nftables",slug:"使用-nftables",children:[]},{level:3,title:"开机自动运行 Netfilter 配置",slug:"开机自动运行-netfilter-配置",children:[]}]},{level:2,title:"局域网设备上网设置",slug:"局域网设备上网设置",children:[{level:3,title:"方法一",slug:"方法一",children:[]},{level:3,title:"方法二",slug:"方法二",children:[]}]},{level:2,title:"Finally",slug:"finally",children:[]},{level:2,title:"写在最后",slug:"写在最后",children:[]}],path:"/en/document/level-2/tproxy_ipv4_and_ipv6.html",pathLocale:"/en/",extraFields:[]},{title:"流量统计",headers:[{level:2,title:"查看流量信息",slug:"查看流量信息",children:[]},{level:2,title:"流量信息的处理",slug:"流量信息的处理",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",children:[]},{level:2,title:"Diverting inbound traffic to warp on the server side",slug:"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",children:[]}],path:"/en/document/level-2/warp.html",pathLocale:"/en/",extraFields:[]},{title:"透明代理入门",headers:[{level:2,title:"什么是透明代理",slug:"什么是透明代理",children:[]},{level:2,title:"透明代理的实现",slug:"透明代理的实现",children:[{level:3,title:"tun2socks",slug:"tun2socks",children:[]},{level:3,title:"iptables/nftables",slug:"iptables-nftables",children:[]}]},{level:2,title:"iptables 实现透明代理原理",slug:"iptables-实现透明代理原理",children:[]},{level:2,title:"透明代理难在哪里",slug:"透明代理难在哪里",children:[]},{level:2,title:"从零开始一步步实现基于 iptables-tproxy 的透明代理",slug:"从零开始一步步实现基于-iptables-tproxy-的透明代理",children:[{level:3,title:"在开始之前,你需要有一定的基础知识:",slug:"在开始之前-你需要有一定的基础知识",children:[]},{level:3,title:"前期准备工作",slug:"前期准备工作",children:[]},{level:3,title:"首先,我们先试试做到第一阶段",slug:"首先-我们先试试做到第一阶段",children:[]},{level:3,title:"第二阶段",slug:"第二阶段",children:[]},{level:3,title:"第三阶段",slug:"第三阶段",children:[]},{level:3,title:"第四阶段",slug:"第四阶段",children:[]},{level:3,title:"代理 ipv6",slug:"代理-ipv6",children:[]}]}],path:"/en/document/level-2/transparent_proxy/transparent_proxy.html",pathLocale:"/en/",extraFields:[]},{title:"",headers:[],path:"/404.html",pathLocale:"/",extraFields:[]}]);c.webpackHot&&(__VUE_HMR_RUNTIME__.updateSearchIndex=e=>{Ba.value=e});const $a=/[^\x00-\x7F]/,Wa=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),Ua=(e,t)=>{const l=t.join(" "),n=e.split(/\s+/g).map((e=>e.trim())).filter((e=>!!e));if($a.test(e))return n.some((e=>l.toLowerCase().indexOf(e)>-1));const o=e.endsWith(" ");return new RegExp(n.map(((e,t)=>n.length!==t+1||o?`(?=.*\\b${Wa(e)}\\b)`:`(?=.*\\b${Wa(e)})`)).join("")+".+","gi").test(l)},qa=ol({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}=kt(e),o=qr(),i=gs(),r=Ba,s=jt(null),a=jt(!1),c=jt(""),d=It((()=>{var e;return null!==(e=t.value[i.value])&&void 0!==e?e:{}})),u=(({searchIndex:e,routeLocale:t,query:l,maxSuggestions:n})=>{const o=It((()=>e.value.filter((e=>e.pathLocale===t.value))));return It((()=>{const e=l.value.trim().toLowerCase();if(!e)return[];const t=[],i=(l,o)=>{Ua(e,[o.title])&&t.push({link:`${l.path}#${o.slug}`,title:l.title,header:o.title});for(const e of o.children){if(t.length>=n.value)return;i(l,e)}};for(const l of o.value){if(t.length>=n.value)break;if(Ua(e,[l.title,...l.extraFields]))t.push({link:l.path,title:l.title});else for(const e of l.headers){if(t.length>=n.value)break;i(l,e)}}return t}))})({searchIndex:r,routeLocale:i,query:c,maxSuggestions:n}),{focusIndex:h,focusNext:p,focusPrev:m}=(e=>{const t=jt(0);return{focusIndex:t,focusNext:()=>{t.value{t.value>0?t.value-=1:t.value=e.value.length-1}}})(u);(({input:e,hotKeys:t})=>{const l=l=>{e.value&&0!==t.value.length&&l.target===document.body&&t.value.includes(l.key)&&(e.value.focus(),l.preventDefault())};fl((()=>{document.addEventListener("keydown",l)})),bl((()=>{document.removeEventListener("keydown",l)}))})({input:s,hotKeys:l});const v=It((()=>a.value&&!!u.value.length)),f=e=>{if(!v.value)return;const t=u.value[e];t&&o.push(t.link).then((()=>{c.value="",h.value=0}))};return()=>Vo("form",{class:"search-box",role:"search"},[Vo("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:e=>c.value=e.target.value,onKeydown:e=>{switch(e.key){case"ArrowUp":v.value&&m();break;case"ArrowDown":v.value&&p();break;case"Enter":e.preventDefault(),f(h.value)}}}),v.value&&Vo("ul",{class:"suggestions",onMouseleave:()=>h.value=-1},u.value.map((({link:e,title:t,header:l},n)=>Vo("li",{class:["suggestion",{focus:h.value===n}],onMouseenter:()=>h.value=n,onMousedown:()=>f(n)},Vo("a",{href:e,onClick:e=>e.preventDefault()},[Vo("span",{class:"page-title"},t),l&&Vo("span",{class:"page-header"},`> ${l}`)])))))])}});const Xa={"/":{placeholder:"搜索"}},Ga=["s","/"];const Ka=[va,Pa,Ta,za,({app:e})=>{e.component("SearchBox",(e=>Vo(qa,s({locales:Xa,hotKeys:Ga,maxSuggestions:5},e))))}];function Ya(e,t,l){var n,o,i;void 0===t&&(t=50),void 0===l&&(l={});var r=null!=(n=l.isImmediate)&&n,s=null!=(o=l.callback)&&o,a=l.maxWait,c=Date.now(),d=[];function u(){if(void 0!==a){var e=Date.now()-c;if(e+t>=a)return a-e}return t}var h=function(){var t=[].slice.call(arguments),l=this;return new Promise((function(n,o){var a=r&&void 0===i;if(void 0!==i&&clearTimeout(i),i=setTimeout((function(){if(i=void 0,c=Date.now(),!r){var n=e.apply(l,t);s&&s(n),d.forEach((function(e){return(0,e.resolve)(n)})),d=[]}}),u()),a){var h=e.apply(l,t);return s&&s(h),n(h)}d.push({resolve:n,reject:o})}))};return h.cancel=function(e){void 0!==i&&clearTimeout(i),d.forEach((function(t){return(0,t.reject)(e)})),d=[]},h}const Qa=()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,Ja=()=>window.scrollTo({top:0,behavior:"smooth"});const Za=[ol({name:"BackToTop",setup(){const e=jt(0),t=It((()=>e.value>300));fl((()=>{e.value=Qa(),window.addEventListener("scroll",Ya((()=>{e.value=Qa()}),100))}));const l=Vo("div",{class:"back-to-top",onClick:Ja});return()=>Vo(ei,{name:"back-to-top"},{default:()=>t.value?l:null})}})];var ec=()=>{(()=>{const e=ha(),t=Us(),l=Ws("vuepress-color-scheme","auto"),n=It({get:()=>!!e.value.darkMode&&("auto"===l.value?t.value:"dark"===l.value),set(e){e===t.value?l.value="auto":l.value=e?"dark":"light"}});Gt(Gs,n),Ys(n)})(),(()=>{const e=ha(),t=os(),l=It((()=>ia(t.value,e.value)));Gt(na,l)})()};const tc=({headerLinkSelector:e,headerAnchorSelector:t,delay:l,offset:n=5})=>{const o=qr(),i=ts(),r=Ya((()=>(()=>{var l,i,r,s;const a=Array.from(document.querySelectorAll(e)),c=Array.from(document.querySelectorAll(t)).filter((e=>a.some((t=>t.hash===e.hash)))),d=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),u=window.innerHeight+d,h=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),p=Math.abs(h-u)=(null!==(i=null===(l=t.parentElement)||void 0===l?void 0:l.offsetTop)&&void 0!==i?i:0)-n,m=!a||d<(null!==(s=null===(r=a.parentElement)||void 0===r?void 0:r.offsetTop)&&void 0!==s?s:0)-n;if(!(u||h&&m))continue;const v=decodeURIComponent(o.currentRoute.value.hash),f=decodeURIComponent(t.hash);if(v===f)return;if(p)for(let l=e+1;l{r(),window.addEventListener("scroll",r)})),bl((()=>{window.removeEventListener("scroll",r)})),Ao((()=>i.value.path),r)},lc=async(e,...t)=>{const{scrollBehavior:l}=e.options;e.options.scrollBehavior=void 0,await e.replace(...t).finally((()=>e.options.scrollBehavior=l))};var nc=()=>{tc({headerLinkSelector:"a.sidebar-item",headerAnchorSelector:".header-anchor",delay:200,offset:5})},oc="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function ic(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function rc(e){throw new Error('Could not dynamically require "'+e+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var sc={exports:{}}; +***************************************************************************** */const Ns="undefined"!=typeof window,Ms=()=>{};const Hs=e=>e();function zs(e,t,l={}){const{eventFilter:n=Hs}=l,o=function(e,t){var l={};for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&t.indexOf(n)<0&&(l[n]=e[n]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(n=Object.getOwnPropertySymbols(e);or.apply(this,e)),{fn:r,thisArg:this,args:e})}),o);var i,r}const Bs=Ns?window:void 0;const $s={boolean:{read:e=>"true"===e,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)}};function Ws(e,t,l=(null==Bs?void 0:Bs.localStorage),n={}){var o;const{flush:i="pre",deep:r=!0,listenToStorageChanges:s=!0,window:a=Bs,eventFilter:c,onError:d=(e=>{console.error(e)})}=n,u=null==t?"any":"boolean"==typeof t?"boolean":"string"==typeof t?"string":"object"==typeof t||Array.isArray(t)?"object":Number.isNaN(t)?"any":"number",h=jt(t),p=null!==(o=n.serializer)&&void 0!==o?o:$s[u];function m(n){if(l&&(!n||n.key===e))try{const o=n?n.newValue:l.getItem(e);null==o?(h.value=t,null!==t&&l.setItem(e,p.write(t))):h.value=p.read(o)}catch(o){d(o)}}return m(),a&&s&&function(...e){let t,l,n,o;if("string"==typeof e[0]?([l,n,o]=e,t=Bs):[t,l,n,o]=e,!t)return Ms;let i=Ms;const r=Ao((()=>wt(t)),(e=>{i(),e&&(e.addEventListener(l,n,o),i=()=>{e.removeEventListener(l,n,o),i=Ms})}),{immediate:!0,flush:"post"}),s=()=>{r(),i()};Fs(s)}(a,"storage",m),zs(h,(()=>{if(l)try{null==h.value?l.removeItem(e):l.setItem(e,p.write(h.value))}catch(t){d(t)}}),{flush:i,deep:r,eventFilter:c}),h}function Us(e){return function(e,t={}){const{window:l=Bs}=t;if(!l)return jt(!1);const n=l.matchMedia(e),o=jt(n.matches),i=e=>{o.value=e.matches};return"addEventListener"in n?n.addEventListener("change",i):n.addListener(i),Fs((()=>{"removeEventListener"in n?n.removeEventListener("change",i):n.removeListener(i)})),o}("(prefers-color-scheme: dark)",e)}var qs,Xs;(Xs=qs||(qs={})).UP="UP",Xs.RIGHT="RIGHT",Xs.DOWN="DOWN",Xs.LEFT="LEFT",Xs.NONE="NONE";const Gs=Symbol(""),Ks=()=>{const e=Kt(Gs);if(!e)throw new Error("useDarkMode() is called without provider.");return e},Ys=e=>{const t=(t=e.value)=>{const l=null===window||void 0===window?void 0:window.document.querySelector("html");null==l||l.classList.toggle("dark",t)};fl((()=>{Ao(e,t,{immediate:!0})})),yl((()=>t()))},Qs=(...e)=>{const t=qr().resolve(...e),l=t.matched[t.matched.length-1];if(!(null==l?void 0:l.redirect))return t;const{redirect:n}=l,o=S(n)?n(t):n,i=V(o)?{path:o}:o;return Qs(s({hash:t.hash,query:t.query,params:t.params},i))},Js=e=>{const t=Qs(e);return{text:t.meta.title||e,link:"404"===t.name?e:t.fullPath}};let Zs=null,ea=null;const ta={wait:()=>Zs,pending:()=>{Zs=new Promise((e=>ea=e))},resolve:()=>{null==ea||ea(),Zs=null,ea=null}},la=()=>ta,na=Symbol("sidebarItems"),oa=()=>{const e=Kt(na);if(!e)throw new Error("useSidebarItems() is called without provider.");return e},ia=(e,t)=>{var l,n,o,i;const r=null!==(n=null!==(l=e.sidebar)&&void 0!==l?l:t.sidebar)&&void 0!==n?n:"auto",s=null!==(i=null!==(o=e.sidebarDepth)&&void 0!==o?o:t.sidebarDepth)&&void 0!==i?i:2;return e.home||!1===r?[]:"auto"===r?sa(s):R(r)?aa(r,s):cs(r)?ca(r,s):[]},ra=(e,t)=>t>0?e.map((e=>((e,t)=>({text:e.title,link:`#${e.slug}`,children:ra(e.children,t)}))(e,t-1))):[],sa=e=>{const t=ts();return[{text:t.value.title,children:ra(t.value.headers,e)}]},aa=(e,t)=>{const l=Xr(),n=ts(),o=e=>{var i;let r;if(r=V(e)?Js(e):e,r.children)return a(s({},r),{children:r.children.map((e=>o(e)))});if(r.link===l.path){const e=1===(null===(i=n.value.headers[0])||void 0===i?void 0:i.level)?n.value.headers[0].children:n.value.headers;return a(s({},r),{children:ra(e,t)})}return r};return e.map((e=>o(e)))},ca=(e,t)=>{var l;const n=Xr(),o=null!==(l=e[hs(e,n.path)])&&void 0!==l?l:[];return aa(o,t)},da=jt({smoothScroll:!0,repo:"xtls/xray-core",docsRepo:"xtls/Xray-docs-next",docsDir:"docs",docsBranch:"main",editLinks:!0,enableToggle:!0,locales:{"/":{repoLabel:"查看源码",editLinkText:"帮助我们改善此页面!",tip:"提示",warning:"注意",danger:"警告",lastUpdatedText:"最近更改",selectLanguageName:"简体中文",selectLanguageText:"多语言",selectLanguageAriaLabel:"多语言",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/","/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"]},{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/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/grpc.md","/config/transports/h2.md","/config/transports/mkcp.md","/config/transports/quic.md","/config/transports/tcp.md","/config/transports/websocket.md"]}],"/document/":[{text:"快速入门文档",children:["/document/install.md","/document/config.md","/document/command.md","/document/document.md","/document/level-0","/document/level-1","/document/level-2"]}],"/document/level-0/":[{text:"小小白白话文",children:["/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"]}],"/document/level-1/":[{text:"入门技巧",children:["/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"]}],"/document/level-2/":[{text:"进阶技巧",children:["/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/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"]}]}]},navbar:[{text:"首页",link:"/"},{text:"大史记",link:"/about/news.md"},{text:"配置指南",link:"/config/"},{text:"开发指南",link:"/development/"},{text:"使用指南",link:"/document/"}]},"/en/":{repoLabel:"Source",editLinkText:"Help us improve this page on GitHub!",tip:"Tip",warning:"Warning",danger:"Danger",lastUpdatedText:"Last Updated",selectLanguageName:"English (WIP)",sidebar:{"/en/config/":[{text:"Xray Features",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 Reference",children:["/en/config/","/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"]},{text:"Inbound Protocol",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 Protocol",children:["/en/config/outbounds/blackhole.md","/en/config/outbounds/dns.md","/en/config/outbounds/freedom.md","/en/config/outbounds/http.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:"Stream Transport Protocol",children:["/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/document/level-0/":[{text:"Beginner Tutorial",children:["/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"]}],"/en/document/level-1/":[{text:"Getting Started Tips",children:["/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"]}],"/en/document/level-2/":[{text:"Advanced Documentation",children:["/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/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/"}]}},navbar:[],logo:null,darkMode:!0,selectLanguageText:"Languages",selectLanguageAriaLabel:"Select language",sidebar:"auto",sidebarDepth:2,editLink:!0,editLinkText:"Edit this page",lastUpdated:!0,lastUpdatedText:"Last Updated",contributors:!0,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",toggleDarkMode:"toggle dark mode",toggleSidebar:"toggle sidebar"});c.webpackHot&&(__VUE_HMR_RUNTIME__.updateThemeData=e=>{da.value=e});const ua=Symbol(""),ha=()=>(()=>{const e=Kt(ua);if(!e)throw new Error("useThemeLocaleData() is called without provider.");return e})(),pa={class:"sr-only"};var ma=ol({setup(e){const t=ha();return(e,l)=>(bn(),Ln(wt(Ts),null,{default:Bt((()=>[An("span",pa,_(wt(t).openInNewWindow),1)])),_:1}))}}),va=({app:e,router:t})=>{e.component("Badge",Ds),e.component("CodeGroup",Is),e.component("CodeGroupItem",Cs),delete e._context.components.OutboundLink,e.component("OutboundLink",ma),e.component("NavbarSearch",(()=>{const t=e.component("Docsearch")||e.component("SearchBox");return t?Vo(t):null}));const l=t.options.scrollBehavior;t.options.scrollBehavior=async(...e)=>(await la().wait(),l(...e))},fa=Object.assign||function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{},n=window.Promise||function(e){function t(){}e(t,t)},o=function(e){var t=e.target;t!==O?-1!==b.indexOf(t)&&v({target:t}):m()},i=function(){if(!E&&L.original){var e=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;Math.abs(x-e)>j.scrollOffset&&setTimeout(m,150)}},r=function(e){var t=e.key||e.keyCode;"Escape"!==t&&"Esc"!==t&&27!==t||m()},s=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e;if(e.background&&(O.style.background=e.background),e.container&&e.container instanceof Object&&(t.container=fa({},j.container,e.container)),e.template){var l=_a(e.template)?e.template:document.querySelector(e.template);t.template=l}return j=fa({},j,t),b.forEach((function(e){e.dispatchEvent(ja("medium-zoom:update",{detail:{zoom:w}}))})),w},a=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return e(fa({},j,t))},c=function(){for(var e=arguments.length,t=Array(e),l=0;l0?t.reduce((function(e,t){return[].concat(e,ya(t))}),[]):b;return n.forEach((function(e){e.classList.remove("medium-zoom-image"),e.dispatchEvent(ja("medium-zoom:detach",{detail:{zoom:w}}))})),b=b.filter((function(e){return-1===n.indexOf(e)})),w},u=function(e,t){var l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return b.forEach((function(n){n.addEventListener("medium-zoom:"+e,t,l)})),y.push({type:"medium-zoom:"+e,listener:t,options:l}),w},h=function(e,t){var l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return b.forEach((function(n){n.removeEventListener("medium-zoom:"+e,t,l)})),y=y.filter((function(l){return!(l.type==="medium-zoom:"+e&&l.listener.toString()===t.toString())})),w},p=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.target,l=function(){var e={width:document.documentElement.clientWidth,height:document.documentElement.clientHeight,left:0,top:0,right:0,bottom:0},t=void 0,l=void 0;if(j.container)if(j.container instanceof Object)t=(e=fa({},e,j.container)).width-e.left-e.right-2*j.margin,l=e.height-e.top-e.bottom-2*j.margin;else{var n=(_a(j.container)?j.container:document.querySelector(j.container)).getBoundingClientRect(),o=n.width,i=n.height,r=n.left,s=n.top;e=fa({},e,{width:o,height:i,left:r,top:s})}t=t||e.width-2*j.margin,l=l||e.height-2*j.margin;var a=L.zoomedHd||L.original,c=ba(a)?t:a.naturalWidth||t,d=ba(a)?l:a.naturalHeight||l,u=a.getBoundingClientRect(),h=u.top,p=u.left,m=u.width,v=u.height,f=Math.min(c,t)/m,g=Math.min(d,l)/v,_=Math.min(f,g),b="scale("+_+") translate3d("+((t-m)/2-p+j.margin+e.left)/_+"px, "+((l-v)/2-h+j.margin+e.top)/_+"px, 0)";L.zoomed.style.transform=b,L.zoomedHd&&(L.zoomedHd.style.transform=b)};return new n((function(e){if(t&&-1===b.indexOf(t))e(w);else{if(L.zoomed)e(w);else{if(t)L.original=t;else{if(!(b.length>0))return void e(w);var n=b;L.original=n[0]}if(L.original.dispatchEvent(ja("medium-zoom:open",{detail:{zoom:w}})),x=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,E=!0,L.zoomed=xa(L.original),document.body.appendChild(O),j.template){var o=_a(j.template)?j.template:document.querySelector(j.template);L.template=document.createElement("div"),L.template.appendChild(o.content.cloneNode(!0)),document.body.appendChild(L.template)}if(document.body.appendChild(L.zoomed),window.requestAnimationFrame((function(){document.body.classList.add("medium-zoom--opened")})),L.original.classList.add("medium-zoom-image--hidden"),L.zoomed.classList.add("medium-zoom-image--opened"),L.zoomed.addEventListener("click",m),L.zoomed.addEventListener("transitionend",(function t(){E=!1,L.zoomed.removeEventListener("transitionend",t),L.original.dispatchEvent(ja("medium-zoom:opened",{detail:{zoom:w}})),e(w)})),L.original.getAttribute("data-zoom-src")){L.zoomedHd=L.zoomed.cloneNode(),L.zoomedHd.removeAttribute("srcset"),L.zoomedHd.removeAttribute("sizes"),L.zoomedHd.src=L.zoomed.getAttribute("data-zoom-src"),L.zoomedHd.onerror=function(){clearInterval(i),console.warn("Unable to reach the zoom image target "+L.zoomedHd.src),L.zoomedHd=null,l()};var i=setInterval((function(){L.zoomedHd.complete&&(clearInterval(i),L.zoomedHd.classList.add("medium-zoom-image--opened"),L.zoomedHd.addEventListener("click",m),document.body.appendChild(L.zoomedHd),l())}),10)}else if(L.original.hasAttribute("srcset")){L.zoomedHd=L.zoomed.cloneNode(),L.zoomedHd.removeAttribute("sizes"),L.zoomedHd.removeAttribute("loading");var r=L.zoomedHd.addEventListener("load",(function(){L.zoomedHd.removeEventListener("load",r),L.zoomedHd.classList.add("medium-zoom-image--opened"),L.zoomedHd.addEventListener("click",m),document.body.appendChild(L.zoomedHd),l()}))}else l()}}}))},m=function(){return new n((function(e){if(!E&&L.original){E=!0,document.body.classList.remove("medium-zoom--opened"),L.zoomed.style.transform="",L.zoomedHd&&(L.zoomedHd.style.transform=""),L.template&&(L.template.style.transition="opacity 150ms",L.template.style.opacity=0),L.original.dispatchEvent(ja("medium-zoom:close",{detail:{zoom:w}})),L.zoomed.addEventListener("transitionend",(function t(){L.original.classList.remove("medium-zoom-image--hidden"),document.body.removeChild(L.zoomed),L.zoomedHd&&document.body.removeChild(L.zoomedHd),document.body.removeChild(O),L.zoomed.classList.remove("medium-zoom-image--opened"),L.template&&document.body.removeChild(L.template),E=!1,L.zoomed.removeEventListener("transitionend",t),L.original.dispatchEvent(ja("medium-zoom:closed",{detail:{zoom:w}})),L.original=null,L.zoomed=null,L.zoomedHd=null,L.template=null,e(w)}))}else e(w)}))},v=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.target;return L.original?m():p({target:t})},f=function(){return j},g=function(){return b},_=function(){return L.original},b=[],y=[],E=!1,x=0,j=l,L={original:null,zoomed:null,zoomedHd:null,template:null};"[object Object]"===Object.prototype.toString.call(t)?j=t:(t||"string"==typeof t)&&c(t),j=fa({margin:0,background:"#fff",scrollOffset:40,container:null,template:null},j);var O=Ea(j.background);document.addEventListener("click",o),document.addEventListener("keyup",r),document.addEventListener("scroll",i),window.addEventListener("resize",m);var w={open:p,close:m,toggle:v,update:s,clone:a,attach:c,detach:d,on:u,off:h,getOptions:f,getImages:g,getZoomedImage:_};return w};!function(e,t){void 0===t&&(t={});var l=t.insertAt;if(e&&"undefined"!=typeof document){var n=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css","top"===l&&n.firstChild?n.insertBefore(o,n.firstChild):n.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e))}}(".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}");const Oa=Symbol("mediumZoom");const wa={};var Pa=({app:e,router:t})=>{const l=La(wa);l.refresh=(e=".theme-default-content > img, .theme-default-content :not(a) > img")=>{l.detach(),l.attach(e)},e.provide(Oa,l),t.afterEach((()=>{setTimeout((()=>l.refresh()),400)}))},Ta=({app:e})=>{const t=da,l=e._context.provides[fs],n=It((()=>((e,t)=>{var l;return s(s({},e),null===(l=e.locales)||void 0===l?void 0:l[t])})(t.value,l.value)));e.provide(ua,n),Object.defineProperties(e.config.globalProperties,{$theme:{get:()=>t.value},$themeLocale:{get:()=>n.value}})},ka=ol({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"}}});Ht("data-v-bcf9babc");const Aa=["id","aria-labelledby"];zt(),ka.render=function(e,t,l,n,o,i){return bn(),jn("div",{class:"tab-pane fade",id:e.tabID,role:"tabpanel","aria-labelledby":e.labelID},[zn(e.$slots,"default",{},void 0,!0)],8,Aa)},ka.__scopeId="data-v-bcf9babc";var Ra=ol({props:{title:{type:String}},data:()=>({children:[]}),beforeMount(){this.children=[]},mounted(){this.$nextTick((async function(){const e=await Yr((()=>import("./bootstrap.esm.4786c18a.js")),[]);let t=document.getElementById(this.children[0].id+"-label");new e.Tab(t).show()}))},computed:{tag:function(){return"tabs-"+this.title},contentTag:function(){return"tabs-"+this.title+"-content"}}});Ht("data-v-d1085dd8");const Da={class:"container"},Ia=["id"],Sa=["id","aria-controls","data-bs-target"],Va=["id"];zt(),Ra.render=function(e,t,l,n,o,i){return bn(),jn("div",Da,[An("nav",null,[An("div",{id:e.tag,class:"nav nav-pills",role:"tablist"},[(bn(!0),jn(pn,null,Hn(e.children,(e=>(bn(),jn("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,Sa)))),256))],8,Ia)]),An("div",{id:e.contentTag,class:"tab-content"},[zn(e.$slots,"default",{},void 0,!0)],8,Va)])},Ra.__scopeId="data-v-d1085dd8";const Ca=e=>!rs(e)||/github\.com/.test(e)?"GitHub":/bitbucket\.org/.test(e)?"Bitbucket":/gitlab\.com/.test(e)?"GitLab":/gitee\.com/.test(e)?"Gitee":null,Fa={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"},Na=({docsRepo:e,docsBranch:t,docsDir:l,filePathRelative:n,editLinkPattern:o})=>{const i=Ca(e);let r;return o?r=o:null!==i&&(r=Fa[i]),r?r.replace(/:repo/,rs(e)?e:`https://github.com/${e}`).replace(/:branch/,t).replace(/:path/,us(`${ds(l)}/${n}`)):null};var Ma=ol({name:"Mermaid",props:{identifier:String,graph:String},setup(e){const t=Ks(),l=Rt(e,"identifier"),n=Rt(e,"graph"),o=ut({innerHtml:""});return fl((()=>{Eo((async function(){const e=await Yr((()=>import("./mermaid.core.3a590193.js").then((function(e){return e.aL}))),[]);e.default.initialize({startOnLoad:!1,theme:t.value?"dark":"default"}),e.default.render(l.value,decodeURI(n.value)).then((({svg:e,bindFunctions:t})=>{o.innerHtml=e}))}))})),Ao(t,(async()=>{const e=await Yr((()=>import("./mermaid.core.3a590193.js").then((function(e){return e.aL}))),[]);e.default.initialize({startOnLoad:!1,theme:t.value?"dark":"default"}),e.default.render(l.value,decodeURI(n.value)).then((({svg:e,bindFunctions:t})=>{o.innerHtml=e}))})),{tag:l,payload:o}}});const Ha=["innerHTML"];Ma.render=function(e,t,l,n,o,i){return bn(),jn("div",{innerHTML:e.payload.innerHtml},null,8,Ha)};var za=({app:e,router:t,siteData:l})=>{e.component("Tab",ka),e.component("Tabs",Ra),e.component("Mermaid",Ma)};const Ba=jt([{title:"",headers:[{level:2,title:"XTLS ? Xray ? V2Ray ?",slug:"xtls-xray-v2ray",children:[{level:3,title:"我们是谁?",slug:"我们是谁",children:[]},{level:3,title:"帮助 Xray 变得更强",slug:"帮助-xray-变得更强",children:[]},{level:3,title:"Telegram",slug:"telegram",children:[]},{level:3,title:"致谢",slug:"致谢",children:[]},{level:3,title:"更多关于 project X",slug:"更多关于-project-x",children:[]},{level:3,title:"License",slug:"license",children:[]},{level:3,title:"Stargazers over time",slug:"stargazers-over-time",children:[]}]}],path:"/",pathLocale:"/",extraFields:[]},{title:"大史记",headers:[{level:2,title:"2021.4.6",slug:"_2021-4-6",children:[]},{level:2,title:"2021.4.4",slug:"_2021-4-4",children:[]},{level:2,title:"2021.4.1 v1.4.2",slug:"_2021-4-1-v1-4-2",children:[]},{level:2,title:"2021.3.25",slug:"_2021-3-25",children:[]},{level:2,title:"2021.3.15",slug:"_2021-3-15",children:[]},{level:2,title:"2021.3.14 v1.4.0",slug:"_2021-3-14-v1-4-0",children:[]},{level:2,title:"2021.3.3 1.3.1",slug:"_2021-3-3-1-3-1",children:[]},{level:2,title:"2021.2.14 1.3.0",slug:"_2021-2-14-1-3-0",children:[]},{level:2,title:"2021.01.31 1.2.4",slug:"_2021-01-31-1-2-4",children:[]},{level:2,title:"2021.01.25",slug:"_2021-01-25",children:[]},{level:2,title:"2021.01.22 1.2.3",slug:"_2021-01-22-1-2-3",children:[]},{level:2,title:"2021.01.19",slug:"_2021-01-19",children:[]},{level:2,title:"2021.01.17",slug:"_2021-01-17",children:[]},{level:2,title:"2021.01.15 1.2.2",slug:"_2021-01-15-1-2-2",children:[]},{level:2,title:"2021.01.12",slug:"_2021-01-12",children:[]},{level:2,title:"2021.01.10 1.2.1",slug:"_2021-01-10-1-2-1",children:[]},{level:2,title:"2021.01.07",slug:"_2021-01-07",children:[]},{level:2,title:"2021.01.05",slug:"_2021-01-05",children:[]},{level:2,title:"2021.01.03",slug:"_2021-01-03",children:[]},{level:2,title:"2021.01.01",slug:"_2021-01-01",children:[]},{level:2,title:"2020.12.29",slug:"_2020-12-29",children:[]},{level:2,title:"2020.12.25 1.1.5",slug:"_2020-12-25-1-1-5",children:[]},{level:2,title:"2020.12.24",slug:"_2020-12-24",children:[]},{level:2,title:"2020.12.23",slug:"_2020-12-23",children:[]},{level:2,title:"2020.12.21",slug:"_2020-12-21",children:[]},{level:2,title:"2020.12.18 1.1.4",slug:"_2020-12-18-1-1-4",children:[]},{level:2,title:"2020.12.17",slug:"_2020-12-17",children:[]},{level:2,title:"2020.12.15",slug:"_2020-12-15",children:[]},{level:2,title:"2020.12.11 1.1.3",slug:"_2020-12-11-1-1-3",children:[]},{level:2,title:"2020.12.06 1.1.2",slug:"_2020-12-06-1-1-2",children:[]},{level:2,title:"2020.12.04",slug:"_2020-12-04",children:[]},{level:2,title:"2020.11.27",slug:"_2020-11-27",children:[]},{level:2,title:"2020.11.25 1.0.0",slug:"_2020-11-25-1-0-0",children:[]},{level:2,title:"2020.11.23",slug:"_2020-11-23",children:[]}],path:"/about/news.html",pathLocale:"/",extraFields:[]},{title:"配置文件",headers:[{level:2,title:"概述",slug:"概述",children:[]},{level:2,title:"基础配置模块",slug:"基础配置模块",children:[]}],path:"/config/",pathLocale:"/",extraFields:[]},{title:"API 接口",headers:[{level:2,title:"ApiObject",slug:"apiobject",children:[]},{level:2,title:"相关配置",slug:"相关配置",children:[]},{level:2,title:"支持的 API 列表",slug:"支持的-api-列表",children:[{level:3,title:"HandlerService",slug:"handlerservice",children:[]},{level:3,title:"LoggerService",slug:"loggerservice",children:[]},{level:3,title:"StatsService",slug:"statsservice",children:[]},{level:3,title:"ReflectionService",slug:"reflectionservice",children:[]}]},{level:2,title:"API 调用示例",slug:"api-调用示例",children:[]}],path:"/config/api.html",pathLocale:"/",extraFields:[]},{title:"内置 DNS 服务器",headers:[{level:2,title:"DNS 服务器",slug:"dns-服务器",children:[]},{level:2,title:"DNS 处理流程",slug:"dns-处理流程",children:[]},{level:2,title:"DnsObject",slug:"dnsobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/dns.html",pathLocale:"/",extraFields:[]},{title:"FakeDNS",headers:[{level:2,title:"FakeDNSObject",slug:"fakednsobject",children:[{level:3,title:"如何使用?",slug:"如何使用",children:[]},{level:3,title:"与其它类型 DNS 搭配使用",slug:"与其它类型-dns-搭配使用",children:[]}]}],path:"/config/fakedns.html",pathLocale:"/",extraFields:[]},{title:"入站代理",headers:[{level:2,title:"InboundObject",slug:"inboundobject",children:[{level:3,title:"SniffingObject",slug:"sniffingobject",children:[]},{level:3,title:"AllocateObject",slug:"allocateobject",children:[]}]}],path:"/config/inbound.html",pathLocale:"/",extraFields:[]},{title:"日志配置",headers:[{level:2,title:"LogObject",slug:"logobject",children:[]}],path:"/config/log.html",pathLocale:"/",extraFields:[]},{title:"出站代理",headers:[{level:2,title:"OutboundObject",slug:"outboundobject",children:[{level:3,title:"ProxySettingsObject",slug:"proxysettingsobject",children:[]},{level:3,title:"MuxObject",slug:"muxobject",children:[]}]}],path:"/config/outbound.html",pathLocale:"/",extraFields:[]},{title:"本地策略",headers:[{level:2,title:"PolicyObject",slug:"policyobject",children:[{level:3,title:"LevelPolicyObject",slug:"levelpolicyobject",children:[]},{level:3,title:"SystemPolicyObject",slug:"systempolicyobject",children:[]}]}],path:"/config/policy.html",pathLocale:"/",extraFields:[]},{title:"反向代理",headers:[{level:2,title:"ReverseObject",slug:"reverseobject",children:[{level:3,title:"BridgeObject",slug:"bridgeobject",children:[]},{level:3,title:"PortalObject",slug:"portalobject",children:[]}]},{level:2,title:"完整配置样例",slug:"完整配置样例",children:[{level:3,title:"bridge 配置",slug:"bridge-配置",children:[]},{level:3,title:"portal 配置",slug:"portal-配置",children:[]}]}],path:"/config/reverse.html",pathLocale:"/",extraFields:[]},{title:"路由",headers:[{level:2,title:"RoutingObject",slug:"routingobject",children:[{level:3,title:"RuleObject",slug:"ruleobject",children:[]},{level:3,title:"BalancerObject",slug:"balancerobject",children:[]},{level:3,title:"预定义域名列表",slug:"预定义域名列表",children:[]}]}],path:"/config/routing.html",pathLocale:"/",extraFields:[]},{title:"统计信息",headers:[{level:2,title:"StatsObject",slug:"statsobject",children:[]},{level:2,title:"获取统计信息",slug:"获取统计信息",children:[]}],path:"/config/stats.html",pathLocale:"/",extraFields:[]},{title:"传输方式",headers:[{level:2,title:"TransportObject",slug:"transportobject",children:[]},{level:2,title:"StreamSettingsObject",slug:"streamsettingsobject",children:[{level:3,title:"TLSObject",slug:"tlsobject",children:[]},{level:3,title:"RealityObject",slug:"realityobject",children:[]},{level:3,title:"SockoptObject",slug:"sockoptobject",children:[]}]}],path:"/config/transport.html",pathLocale:"/",extraFields:[]},{title:"开发指南",headers:[{level:2,title:"编译文档",slug:"编译文档",children:[]},{level:2,title:"设计思路",slug:"设计思路",children:[]},{level:2,title:"开发规范",slug:"开发规范",children:[]},{level:2,title:"协议详解",slug:"协议详解",children:[{level:3,title:"VLESS 协议",slug:"vless-协议",children:[]},{level:3,title:"VMess 协议",slug:"vmess-协议",children:[]},{level:3,title:"Mux.Cool 协议",slug:"mux-cool-协议",children:[]},{level:3,title:"mKCP 协议",slug:"mkcp-协议",children:[]}]}],path:"/development/",pathLocale:"/",extraFields:[]},{title:"快速入门",headers:[{level:2,title:"下载安装",slug:"下载安装",children:[]},{level:2,title:"配置运行",slug:"配置运行",children:[]},{level:2,title:"命令参数",slug:"命令参数",children:[]},{level:2,title:"改进文档",slug:"改进文档",children:[]},{level:2,title:"小小白白话文",slug:"小小白白话文",children:[]},{level:2,title:"入门技巧",slug:"入门技巧",children:[]},{level:2,title:"进阶文档",slug:"进阶文档",children:[]}],path:"/document/",pathLocale:"/",extraFields:[]},{title:"命令参数",headers:[{level:2,title:"获取基本命令",slug:"获取基本命令",children:[{level:3,title:"xray run",slug:"xray-run",children:[]},{level:3,title:"xray version",slug:"xray-version",children:[]},{level:3,title:"xray api",slug:"xray-api",children:[]},{level:3,title:"xray tls",slug:"xray-tls",children:[]},{level:3,title:"xray uuid",slug:"xray-uuid",children:[]}]}],path:"/document/command.html",pathLocale:"/",extraFields:[]},{title:"配置运行",headers:[{level:2,title:"服务端配置",slug:"服务端配置",children:[]},{level:2,title:"客户端配置",slug:"客户端配置",children:[]},{level:2,title:"运行",slug:"运行",children:[]}],path:"/document/config.html",pathLocale:"/",extraFields:[]},{title:"为 Project X 的文档贡献",headers:[{level:2,title:"改进文档",slug:"改进文档",children:[]},{level:2,title:"发现问题?",slug:"发现问题",children:[]}],path:"/document/document.html",pathLocale:"/",extraFields:[]},{title:"下载安装",headers:[{level:2,title:"平台支持",slug:"平台支持",children:[]},{level:2,title:"下载 Xray",slug:"下载-xray",children:[]},{level:2,title:"验证安装包",slug:"验证安装包",children:[]},{level:2,title:"Windows 安装方式",slug:"windows-安装方式",children:[]},{level:2,title:"macOS 安装方式",slug:"macos-安装方式",children:[]},{level:2,title:"Linux 安装方式",slug:"linux-安装方式",children:[{level:3,title:"安装脚本",slug:"安装脚本",children:[]},{level:3,title:"Arch Linux",slug:"arch-linux",children:[]},{level:3,title:"Linuxbrew",slug:"linuxbrew",children:[]},{level:3,title:"Debian",slug:"debian",children:[]},{level:3,title:"Gentoo",slug:"gentoo",children:[]}]},{level:2,title:"Docker 安装方式",slug:"docker-安装方式",children:[{level:3,title:"Docker image 的文件结构",slug:"docker-image-的文件结构",children:[]}]}],path:"/document/install.html",pathLocale:"/",extraFields:[]},{title:"",headers:[{level:2,title:"XTLS? Xray? V2Ray?",slug:"xtls-xray-v2ray",children:[{level:3,title:"Who are we?",slug:"who-are-we",children:[]},{level:3,title:"Help Xray become stronger",slug:"help-xray-become-stronger",children:[]},{level:3,title:"Telegram",slug:"telegram",children:[]},{level:3,title:"Thanks",slug:"thanks",children:[]},{level:3,title:"More about project X",slug:"more-about-project-x",children:[]},{level:3,title:"License",slug:"license",children:[]},{level:3,title:"Stargazers over time",slug:"stargazers-over-time",children:[]}]}],path:"/en/",pathLocale:"/en/",extraFields:[]},{title:"Browser Dialer",headers:[{level:2,title:"Background",slug:"background",children:[]},{level:2,title:"Xray & JS",slug:"xray-js",children:[]},{level:2,title:"Early data",slug:"early-data",children:[]},{level:2,title:"Configuration",slug:"configuration",children:[]}],path:"/config/features/browser_dialer.html",pathLocale:"/",extraFields:[]},{title:"环境变量",headers:[{level:2,title:"资源文件路径",slug:"资源文件路径",children:[]},{level:2,title:"配置文件位置",slug:"配置文件位置",children:[]},{level:2,title:"多配置目录",slug:"多配置目录",children:[]}],path:"/config/features/env.html",pathLocale:"/",extraFields:[]},{title:"Fallback 回落",headers:[{level:2,title:"fallbacks 配置",slug:"fallbacks-配置",children:[{level:3,title:"FallbackObject",slug:"fallbackobject",children:[]},{level:3,title:"补充说明",slug:"补充说明",children:[]}]},{level:2,title:"Fallbacks 设计理论",slug:"fallbacks-设计理论",children:[]}],path:"/config/features/fallback.html",pathLocale:"/",extraFields:[]},{title:"多文件配置",headers:[{level:2,title:"多文件启动",slug:"多文件启动",children:[]},{level:2,title:"规则说明",slug:"规则说明",children:[{level:3,title:"普通对象({})",slug:"普通对象",children:[]},{level:3,title:"数组([])",slug:"数组",children:[]}]},{level:2,title:"推荐的多文件列表",slug:"推荐的多文件列表",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",children:[]},{level:2,title:"透明代理配置样例",slug:"透明代理配置样例",children:[]}],path:"/config/inbounds/dokodemo.html",pathLocale:"/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",children:[]}]}],path:"/config/inbounds/http.html",pathLocale:"/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[]},{level:2,title:"ClientObject",slug:"clientobject",children:[]}],path:"/config/inbounds/shadowsocks.html",pathLocale:"/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",children:[]}]}],path:"/config/inbounds/socks.html",pathLocale:"/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]}]}],path:"/config/inbounds/trojan.html",pathLocale:"/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]}]}],path:"/config/inbounds/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]},{level:3,title:"DetourObject",slug:"detourobject",children:[]},{level:3,title:"DefaultObject",slug:"defaultobject",children:[]}]}],path:"/config/inbounds/vmess.html",pathLocale:"/",extraFields:[]},{title:"Blackhole",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ResponseObject",slug:"responseobject",children:[]}]}],path:"/config/outbounds/blackhole.html",pathLocale:"/",extraFields:[]},{title:"DNS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[]},{level:2,title:"DNS 配置实例",slug:"dns-配置实例",children:[]}],path:"/config/outbounds/dns.html",pathLocale:"/",extraFields:[]},{title:"Freedom",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[]}],path:"/config/outbounds/freedom.html",pathLocale:"/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/outbounds/http.html",pathLocale:"/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/outbounds/shadowsocks.html",pathLocale:"/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/outbounds/socks.html",pathLocale:"/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/outbounds/trojan.html",pathLocale:"/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]},{level:3,title:"UserObject",slug:"userobject",children:[]}]}],path:"/config/outbounds/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/config/outbounds/vmess.html",pathLocale:"/",extraFields:[]},{title:"Wireguard",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"Peers",slug:"peers",children:[]}]}],path:"/config/outbounds/wireguard.html",pathLocale:"/",extraFields:[]},{title:"Domain Socket",headers:[{level:2,title:"DomainSocketObject",slug:"domainsocketobject",children:[]}],path:"/config/transports/domainsocket.html",pathLocale:"/",extraFields:[]},{title:"gRPC",headers:[{level:2,title:"GRPCObject",slug:"grpcobject",children:[]}],path:"/config/transports/grpc.html",pathLocale:"/",extraFields:[]},{title:"HTTP/2",headers:[{level:2,title:"HttpObject",slug:"httpobject",children:[]}],path:"/config/transports/h2.html",pathLocale:"/",extraFields:[]},{title:"mKCP",headers:[{level:2,title:"KcpObject",slug:"kcpobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",children:[]}]},{level:2,title:"鸣谢",slug:"鸣谢",children:[]},{level:2,title:"对 KCP 协议的改进",slug:"对-kcp-协议的改进",children:[{level:3,title:"更小的协议头",slug:"更小的协议头",children:[]},{level:3,title:"确认包重传",slug:"确认包重传",children:[]},{level:3,title:"连接状态控制",slug:"连接状态控制",children:[]}]}],path:"/config/transports/mkcp.html",pathLocale:"/",extraFields:[]},{title:"QUIC",headers:[{level:2,title:"QuicObject",slug:"quicobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",children:[]}]}],path:"/config/transports/quic.html",pathLocale:"/",extraFields:[]},{title:"TCP",headers:[{level:2,title:"TcpObject",slug:"tcpobject",children:[{level:3,title:"NoneHeaderObject",slug:"noneheaderobject",children:[]},{level:3,title:"HttpHeaderObject",slug:"httpheaderobject",children:[]}]}],path:"/config/transports/tcp.html",pathLocale:"/",extraFields:[]},{title:"WebSocket",headers:[{level:2,title:"WebSocketObject",slug:"websocketobject",children:[]},{level:2,title:"Browser Dialer",slug:"browser-dialer",children:[]}],path:"/config/transports/websocket.html",pathLocale:"/",extraFields:[]},{title:"编译文档",headers:[{level:2,title:"前序工作",slug:"前序工作",children:[]},{level:2,title:"拉取 Xray 源代码",slug:"拉取-xray-源代码",children:[]},{level:2,title:"构建二进制",slug:"构建二进制",children:[{level:3,title:"Windows(Powershell):",slug:"windows-powershell",children:[]},{level:3,title:"macOS, Linux:",slug:"macos-linux",children:[]}]},{level:2,title:"交叉编译:",slug:"交叉编译",children:[]},{level:2,title:"可复现构建:",slug:"可复现构建",children:[]}],path:"/development/intro/compile.html",pathLocale:"/",extraFields:[]},{title:"设计目标",headers:[{level:2,title:"架构",slug:"架构",children:[{level:3,title:"应用层",slug:"应用层",children:[]},{level:3,title:"代理层",slug:"代理层",children:[]},{level:3,title:"传输层",slug:"传输层",children:[]}]}],path:"/development/intro/design.html",pathLocale:"/",extraFields:[]},{title:"开发规范",headers:[{level:2,title:"基本",slug:"基本",children:[{level:3,title:"版本控制",slug:"版本控制",children:[]},{level:3,title:"分支(Branch)",slug:"分支-branch",children:[]},{level:3,title:"发布(Release)",slug:"发布-release",children:[]},{level:3,title:"引用其它项目",slug:"引用其它项目",children:[]}]},{level:2,title:"开发流程",slug:"开发流程",children:[{level:3,title:"写代码之前",slug:"写代码之前",children:[]},{level:3,title:"修改代码",slug:"修改代码",children:[]},{level:3,title:"Pull Request",slug:"pull-request",children:[]},{level:3,title:"对代码的修改",slug:"对代码的修改",children:[]}]},{level:2,title:"Xray 编码规范",slug:"xray-编码规范",children:[{level:3,title:"代码结构",slug:"代码结构",children:[]},{level:3,title:"编码规范",slug:"编码规范",children:[]}]}],path:"/development/intro/guide.html",pathLocale:"/",extraFields:[]},{title:"mKCP 协议",headers:[{level:2,title:"版本",slug:"版本",children:[]},{level:2,title:"依赖",slug:"依赖",children:[{level:3,title:"底层协议",slug:"底层协议",children:[]},{level:3,title:"函数",slug:"函数",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",children:[]},{level:2,title:"数据格式",slug:"数据格式",children:[{level:3,title:"数据包",slug:"数据包",children:[]},{level:3,title:"数据片段",slug:"数据片段",children:[]},{level:3,title:"确认片段",slug:"确认片段",children:[]},{level:3,title:"心跳片段",slug:"心跳片段",children:[]}]}],path:"/development/protocols/mkcp.html",pathLocale:"/",extraFields:[]},{title:"Mux.Cool 协议",headers:[{level:2,title:"版本",slug:"版本",children:[]},{level:2,title:"依赖",slug:"依赖",children:[{level:3,title:"底层协议",slug:"底层协议",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",children:[{level:3,title:"客户端行为",slug:"客户端行为",children:[]},{level:3,title:"服务器端行为",slug:"服务器端行为",children:[]}]},{level:2,title:"传输格式",slug:"传输格式",children:[{level:3,title:"帧格式",slug:"帧格式",children:[]},{level:3,title:"元数据",slug:"元数据",children:[]},{level:3,title:"新建子连接 (New)",slug:"新建子连接-new",children:[]},{level:3,title:"保持子连接 (Keep)",slug:"保持子连接-keep",children:[]},{level:3,title:"关闭子连接 (End)",slug:"关闭子连接-end",children:[]},{level:3,title:"保持连接 (KeepAlive)",slug:"保持连接-keepalive",children:[]}]},{level:2,title:"应用",slug:"应用",children:[]}],path:"/development/protocols/muxcool.html",pathLocale:"/",extraFields:[]},{title:"VLESS 协议",headers:[{level:2,title:"Request & Response",slug:"request-response",children:[]},{level:2,title:"ProtoBuf",slug:"protobuf",children:[]},{level:2,title:"Schedulers Flow",slug:"schedulers-flow",children:[]},{level:2,title:"Encryption",slug:"encryption",children:[]},{level:2,title:"UDP issues",slug:"udp-issues",children:[]},{level:2,title:"客户端开发指引",slug:"客户端开发指引",children:[]},{level:2,title:"VLESS 分享链接标准",slug:"vless-分享链接标准",children:[]}],path:"/development/protocols/vless.html",pathLocale:"/",extraFields:[]},{title:"VMess 协议",headers:[{level:2,title:"版本",slug:"版本",children:[]},{level:2,title:"依赖",slug:"依赖",children:[{level:3,title:"底层协议",slug:"底层协议",children:[]},{level:3,title:"用户 ID",slug:"用户-id",children:[]},{level:3,title:"函数",slug:"函数",children:[]}]},{level:2,title:"通讯过程",slug:"通讯过程",children:[]},{level:2,title:"客户端请求",slug:"客户端请求",children:[{level:3,title:"认证信息",slug:"认证信息",children:[]},{level:3,title:"指令部分",slug:"指令部分",children:[]},{level:3,title:"数据部分",slug:"数据部分",children:[]}]},{level:2,title:"服务器应答",slug:"服务器应答",children:[{level:3,title:"动态端口指令",slug:"动态端口指令",children:[]}]},{level:2,title:"注释",slug:"注释",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-这篇文档是写给谁的",children:[]},{level:2,title:"1.2 这篇文档不是写给谁的?",slug:"_1-2-这篇文档不是写给谁的",children:[]},{level:2,title:"1.3 郑重声明及其他声明",slug:"_1-3-郑重声明及其他声明",children:[]},{level:2,title:"1.4 为什么自建是个难题?",slug:"_1-4-为什么自建是个难题",children:[]},{level:2,title:"1.5 “用机场不就行了?”",slug:"_1-5-用机场不就行了",children:[]},{level:2,title:"1.6 那么你到底要不要自建呢?",slug:"_1-6-那么你到底要不要自建呢",children:[]},{level:2,title:"1.7 题外啰嗦几句",slug:"_1-7-题外啰嗦几句",children:[]},{level:2,title:"1.8 你的进度",slug:"_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",children:[]},{level:2,title:"2.2 获取一个心仪的域名",slug:"_2-2-获取一个心仪的域名",children:[]},{level:2,title:"2.3 你本地电脑上需要安装的软件",slug:"_2-3-你本地电脑上需要安装的软件",children:[]},{level:2,title:"2.4 你的进度",slug:"_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",children:[]},{level:2,title:"3.2 成功登录 SSH!初识命令行界面!",slug:"_3-2-成功登录-ssh-初识命令行界面",children:[]},{level:2,title:"3.3 第一次更新 Linux 的软件!",slug:"_3-3-第一次更新-linux-的软件",children:[]},{level:2,title:"3.4 你的进度",slug:"_3-4-你的进度",children:[]}],path:"/document/level-0/ch03-ssh.html",pathLocale:"/",extraFields:[]},{title:"【第 4 章】安全防护篇",headers:[{level:2,title:"4.1 为什么要做安全防护",slug:"_4-1-为什么要做安全防护",children:[]},{level:2,title:"4.2 具体的风险到底是什么",slug:"_4-2-具体的风险到底是什么",children:[]},{level:2,title:"4.3 我们要做的安全防护有哪些",slug:"_4-3-我们要做的安全防护有哪些",children:[]},{level:2,title:"4.4 将 SSH 远程登录端口修改为非 22 端口",slug:"_4-4-将-ssh-远程登录端口修改为非-22-端口",children:[]},{level:2,title:"4.5 建立非 root 的新用户",slug:"_4-5-建立非-root-的新用户",children:[]},{level:2,title:"4.6 禁用 root 用户 SSH 远程登录",slug:"_4-6-禁用-root-用户-ssh-远程登录",children:[]},{level:2,title:"4.7 使用 RSA 密钥登录并禁用密码登录",slug:"_4-7-使用-rsa-密钥登录并禁用密码登录",children:[]},{level:2,title:"4.8 你的进度",slug:"_4-8-你的进度",children:[]}],path:"/document/level-0/ch04-security.html",pathLocale:"/",extraFields:[]},{title:"【第 5 章】网站建设篇",headers:[{level:2,title:"5.1 为什么要做一个网站?",slug:"_5-1-为什么要做一个网站",children:[]},{level:2,title:"5.2 登录 VPS、安装运行 Nginx",slug:"_5-2-登录-vps、安装运行-nginx",children:[]},{level:2,title:"5.3 创建一个最简单的网页",slug:"_5-3-创建一个最简单的网页",children:[]},{level:2,title:"5.4 常见错误的说明",slug:"_5-4-常见错误的说明",children:[]},{level:2,title:"5.5 你的进度",slug:"_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-证书",children:[]},{level:2,title:"6.2 安装 acme.sh",slug:"_6-2-安装-acme-sh",children:[]},{level:2,title:"6.3 测试证书申请",slug:"_6-3-测试证书申请",children:[]},{level:2,title:"6.4 正式证书申请",slug:"_6-4-正式证书申请",children:[]},{level:2,title:"6.5 证书安装",slug:"_6-5-证书安装",children:[]},{level:2,title:"6.6 你的进度",slug:"_6-6-你的进度",children:[]}],path:"/document/level-0/ch06-certificates.html",pathLocale:"/",extraFields:[]},{title:"【第 7 章】Xray 服务器篇",headers:[{level:2,title:"7.1 博观而约取,厚积而薄发",slug:"_7-1-博观而约取-厚积而薄发",children:[]},{level:2,title:"7.2 安装 Xray",slug:"_7-2-安装-xray",children:[]},{level:2,title:"7.3 给 Xray 配置 TLS 证书",slug:"_7-3-给-xray-配置-tls-证书",children:[]},{level:2,title:"7.4 配置 Xray",slug:"_7-4-配置-xray",children:[]},{level:2,title:"7.5 启动 Xray 服务!!(并查看服务状态)",slug:"_7-5-启动-xray-服务-并查看服务状态",children:[]},{level:2,title:"7.6 回顾 systemd 进行基本的服务管理",slug:"_7-6-回顾-systemd-进行基本的服务管理",children:[]},{level:2,title:"7.7 服务器优化之一:开启 BBR",slug:"_7-7-服务器优化之一-开启-bbr",children:[]},{level:2,title:"7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS",slug:"_7-8-服务器优化之二-开启-http-自动跳转-https",children:[]},{level:2,title:"7.9 服务器优化之三:更丰富的回落",slug:"_7-9-服务器优化之三-更丰富的回落",children:[]},{level:2,title:"7.10 你的进度",slug:"_7-10-你的进度",children:[]},{level:2,title:"7.11 重要勘误",slug:"_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-的工作原理简述",children:[]},{level:2,title:"8.2 客户端与服务器端正确连接",slug:"_8-2-客户端与服务器端正确连接",children:[]},{level:2,title:"8.3 附加题 1:在 PC 端手工配置 xray-core",slug:"_8-3-附加题-1-在-pc-端手工配置-xray-core",children:[]},{level:2,title:"8.4 附加题 2:在 PC 端手工运行 xray-core",slug:"_8-4-附加题-2-在-pc-端手工运行-xray-core",children:[]},{level:2,title:"8.5 附加题 3:在 PC 端开机自动运行 xray-core",slug:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",children:[]},{level:2,title:"8.6 圆满完成!",slug:"_8-6-圆满完成",children:[]},{level:2,title:"8.7 TO INFINITY AND BEYOND!",slug:"_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-基础命令索引",children:[]},{level:2,title:"2. 小小白白 Linux 重要配置文件索引",slug:"_2-小小白白-linux-重要配置文件索引",children:[]},{level:2,title:"3. 小小白白 Xray 重要文件索引",slug:"_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-回顾《小小白白话文》中的回落",children:[]},{level:2,title:"2. 重新认识回落 (WHAT, HOW v1)",slug:"_2-重新认识回落-what-how-v1",children:[]},{level:2,title:"3. 为什么要回落 (WHY v1)",slug:"_3-为什么要回落-why-v1",children:[]},{level:2,title:"4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)",slug:"_4-重新认识【回落の完全体】-what-why-how-v2",children:[]},{level:2,title:"5. 多层回落示例及解读",slug:"_5-多层回落示例及解读",children:[{level:3,title:"5.1 首先,我将服务器端配置的 443 监听段摘抄如下:",slug:"_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",children:[]},{level:3,title:"5.2 后续监听处理的配置段摘抄如下:",slug:"_5-2-后续监听处理的配置段摘抄如下",children:[]}]},{level:2,title:"6. 结语",slug:"_6-结语",children:[]},{level:2,title:"7. 附加题",slug:"_7-附加题",children:[]}],path:"/document/level-1/fallbacks-lv1.html",pathLocale:"/",extraFields:[]},{title:"SNI 回落",headers:[{level:2,title:"应用情景",slug:"应用情景",children:[]},{level:2,title:"SNI 简介",slug:"sni-简介",children:[]},{level:2,title:"思路",slug:"思路",children:[]},{level:2,title:"添加 DNS 记录",slug:"添加-dns-记录",children:[]},{level:2,title:"申请 TLS 证书",slug:"申请-tls-证书",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",children:[]},{level:2,title:"Nginx 配置",slug:"nginx-配置",children:[]},{level:2,title:"Caddy 配置",slug:"caddy-配置",children:[]},{level:2,title:"参考",slug:"参考",children:[]},{level:2,title:"引用",slug:"引用",children:[]}],path:"/document/level-1/fallbacks-with-sni.html",pathLocale:"/",extraFields:[]},{title:"路由 (routing) 功能简析(上)",headers:[{level:2,title:"1. 初识【路由】三兄弟",slug:"_1-初识【路由】三兄弟",children:[]},{level:2,title:"2. 基本功: “兄弟一条心”",slug:"_2-基本功-兄弟一条心",children:[{level:3,title:"2.1 入站",slug:"_2-1-入站",children:[]},{level:3,title:"2.3 路由",slug:"_2-3-路由",children:[]},{level:3,title:"2.4 路由配置项解析之一:流量筛选的依据",slug:"_2-4-路由配置项解析之一-流量筛选的依据",children:[]}]},{level:2,title:"3. 小试牛刀: “三分天下” 之 “域名分流”",slug:"_3-小试牛刀-三分天下-之-域名分流",children:[{level:3,title:"3.1 入站",slug:"_3-1-入站",children:[]},{level:3,title:"3.2 出站",slug:"_3-2-出站",children:[]},{level:3,title:"3.3 路由",slug:"_3-3-路由",children:[]},{level:3,title:"3.4 简析域名文件: geosite.dat",slug:"_3-4-简析域名文件-geosite-dat",children:[]},{level:3,title:"3.5 所以 geosite.dat 到底是什么?不是有个 GFWList 吗?",slug:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",children:[]},{level:3,title:"3.6 军师锦囊藏奇兵:一条隐藏的路由规则",slug:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",children:[]},{level:3,title:"3.7 再看“三分天下”的大地图",slug:"_3-7-再看-三分天下-的大地图",children:[]}]},{level:2,title:"4. “三分天下” 之 “蜀魏争雄”",slug:"_4-三分天下-之-蜀魏争雄",children:[]},{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",children:[]}],path:"/document/level-1/routing-lv1-part1.html",pathLocale:"/",extraFields:[]},{title:"路由 (routing) 功能简析(下)",headers:[{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",children:[{level:3,title:"5.1 基于指定域名分流:[domain], [full] 等",slug:"_5-1-基于指定域名分流-domain-full-等",children:[]},{level:3,title:"5.2 基于 IP 文件分流:geoip.dat",slug:"_5-2-基于-ip-文件分流-geoip-dat",children:[]},{level:3,title:"5.3 基于指定 IP 地址分流",slug:"_5-3-基于指定-ip-地址分流",children:[]},{level:3,title:"5.4 基于协议类型分流:[protocol] 等",slug:"_5-4-基于协议类型分流-protocol-等",children:[]},{level:3,title:"5.5 基于更多条件的分流",slug:"_5-5-基于更多条件的分流",children:[]}]},{level:2,title:"6. “霸业初定”:路由规则整体回顾",slug:"_6-霸业初定-路由规则整体回顾",children:[]},{level:2,title:"7. 路由配置常见错误",slug:"_7-路由配置常见错误",children:[{level:3,title:"7.1 错误示范",slug:"_7-1-错误示范",children:[]},{level:3,title:"7.2 正确示范",slug:"_7-2-正确示范",children:[]}]},{level:2,title:"8. 明修栈道、暗渡陈仓",slug:"_8-明修栈道、暗渡陈仓",children:[{level:3,title:'8.1 域名策略: "AsIs"',slug:"_8-1-域名策略-asis",children:[]},{level:3,title:'8.2 域名策略: "IPIfNonMatch"',slug:"_8-2-域名策略-ipifnonmatch",children:[]},{level:3,title:'8.3 域名策略: "IPOnDemand"',slug:"_8-3-域名策略-ipondemand",children:[]}]},{level:2,title:"9. 思考题",slug:"_9-思考题",children:[]},{level:2,title:"10. 结语",slug:"_10-结语",children:[]},{level:2,title:"11. 尾注",slug:"_11-尾注",children:[]}],path:"/document/level-1/routing-lv1-part2.html",pathLocale:"/",extraFields:[]},{title:"Xray 的工作模式",headers:[{level:2,title:"单服务器模式",slug:"单服务器模式",children:[]},{level:2,title:"桥接模式",slug:"桥接模式",children:[]},{level:2,title:"工作原理",slug:"工作原理",children:[]}],path:"/document/level-1/work.html",pathLocale:"/",extraFields:[]},{title:"进阶文档",headers:[],path:"/document/level-2/",pathLocale:"/",extraFields:[]},{title:"GID 透明代理",headers:[{level:2,title:"思路",slug:"思路",children:[]},{level:2,title:"配置过程",slug:"配置过程",children:[{level:3,title:"1. 前期准备",slug:"_1-前期准备",children:[]},{level:3,title:"2. 添加用户(安卓用户请忽略)",slug:"_2-添加用户-安卓用户请忽略",children:[]},{level:3,title:"3. 配置运行 Xray,配置 iptables 规则",slug:"_3-配置运行-xray-配置-iptables-规则",children:[]}]},{level:2,title:"下面提供一个实现 tproxy 全局代理的完整配置过程",slug:"下面提供一个实现-tproxy-全局代理的完整配置过程",children:[{level:3,title:"1. 完成 前期准备 和 添加用户",slug:"_1-完成-前期准备-和-添加用户",children:[]},{level:3,title:"2. 准备 Xray 配置文件",slug:"_2-准备-xray-配置文件",children:[]},{level:3,title:"3. 配置最大文件打开数&运行 Xray 客户端",slug:"_3-配置最大文件打开数-运行-xray-客户端",children:[]},{level:3,title:"4. 设置 iptables 规则",slug:"_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",children:[]},{level:2,title:"配置 nginx",slug:"配置-nginx",children:[]},{level:2,title:"xray 配置",slug:"xray-配置",children:[]},{level:2,title:"客户端及服务端启动服务",slug:"客户端及服务端启动服务",children:[]},{level:2,title:"结束",slug:"结束",children:[]},{level:2,title:"HTTPS 隧道",slug:"https-隧道",children:[{level:3,title:"haproxy_client 配置 (运行前去掉注释)",slug:"haproxy-client-配置-运行前去掉注释",children:[]},{level:3,title:"haproxy_server 配置 (运行前去掉注释)",slug:"haproxy-server-配置-运行前去掉注释",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-1",children:[]}]},{level:2,title:"WebSocket over HTTP/2",slug:"websocket-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-2",children:[]}]},{level:2,title:"gRPC over HTTP/2",slug:"grpc-over-http-2",children:[{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-1",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-1",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-3",children:[]},{level:3,title:"haproxy_client 配置",slug:"haproxy-client-配置-2",children:[]},{level:3,title:"haproxy_server 配置",slug:"haproxy-server-配置-2",children:[]},{level:3,title:"xray 配置",slug:"xray-配置-4",children:[]}]}],path:"/document/level-2/nginx_or_haproxy_tls_tunnel.html",pathLocale:"/",extraFields:[]},{title:"出站流量重定向",headers:[{level:2,title:"前言",slug:"前言",children:[]},{level:2,title:"1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)",slug:"_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",children:[]},{level:2,title:"2、编辑 VPN 配置文件(以 WireGuard 为例)",slug:"_2、编辑-vpn-配置文件-以-wireguard-为例",children:[]},{level:2,title:"3、启用 WireGuard 网络接口",slug:"_3、启用-wireguard-网络接口",children:[]},{level:2,title:"4、Xray-core 配置文件修改",slug:"_4、xray-core-配置文件修改",children:[]},{level:2,title:"5、系统设置配置",slug:"_5、系统设置配置",children:[]},{level:2,title:"6、完成 WireGuard 相关设置",slug:"_6、完成-wireguard-相关设置",children:[]},{level:2,title:"后记",slug:"后记",children:[]},{level:2,title:"感谢",slug:"感谢",children:[]}],path:"/document/level-2/redirect.html",pathLocale:"/",extraFields:[]},{title:"TProxy 透明代理",headers:[{level:2,title:"开始之前",slug:"开始之前",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",children:[]},{level:2,title:"策略路由配置",slug:"策略路由配置",children:[]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",children:[]},{level:2,title:"配置永久化与开机自启",slug:"配置永久化与开机自启",children:[]}],path:"/document/level-2/tproxy.html",pathLocale:"/",extraFields:[]},{title:"TProxy 透明代理 (ipv4 and ipv6)",headers:[{level:2,title:"Xray 配置",slug:"xray-配置",children:[{level:3,title:"客户端配置",slug:"客户端配置",children:[]},{level:3,title:"服务端配置",slug:"服务端配置",children:[]}]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",children:[{level:3,title:"首先设置策略路由",slug:"首先设置策略路由",children:[]},{level:3,title:"使用 iptables",slug:"使用-iptables",children:[]},{level:3,title:"使用 nftables",slug:"使用-nftables",children:[]},{level:3,title:"开机自动运行 Netfilter 配置",slug:"开机自动运行-netfilter-配置",children:[]}]},{level:2,title:"局域网设备上网设置",slug:"局域网设备上网设置",children:[{level:3,title:"方法一",slug:"方法一",children:[]},{level:3,title:"方法二",slug:"方法二",children:[]}]},{level:2,title:"Finally",slug:"finally",children:[]},{level:2,title:"写在最后",slug:"写在最后",children:[]}],path:"/document/level-2/tproxy_ipv4_and_ipv6.html",pathLocale:"/",extraFields:[]},{title:"流量统计",headers:[{level:2,title:"查看流量信息",slug:"查看流量信息",children:[]},{level:2,title:"流量信息的处理",slug:"流量信息的处理",children:[]}],path:"/document/level-2/traffic_stats.html",pathLocale:"/",extraFields:[]},{title:"通过 Cloudflare Warp 增强代理安全性",headers:[{level:2,title:"申请 Warp 账户",slug:"申请-warp-账户",children:[]},{level:2,title:"在服务端分流回国流量至 warp",slug:"在服务端分流回国流量至-warp",children:[]},{level:2,title:"客户端使用 warp 链式代理",slug:"客户端使用-warp-链式代理",children:[]}],path:"/document/level-2/warp.html",pathLocale:"/",extraFields:[]},{title:"大史记",headers:[{level:2,title:"2021.4.6",slug:"_2021-4-6",children:[]},{level:2,title:"2021.4.4",slug:"_2021-4-4",children:[]},{level:2,title:"2021.4.1 v1.4.2",slug:"_2021-4-1-v1-4-2",children:[]},{level:2,title:"2021.3.25",slug:"_2021-3-25",children:[]},{level:2,title:"2021.3.15",slug:"_2021-3-15",children:[]},{level:2,title:"2021.3.14 v1.4.0",slug:"_2021-3-14-v1-4-0",children:[]},{level:2,title:"2021.3.3 1.3.1",slug:"_2021-3-3-1-3-1",children:[]},{level:2,title:"2021.2.14 1.3.0",slug:"_2021-2-14-1-3-0",children:[]},{level:2,title:"2021.01.31 1.2.4",slug:"_2021-01-31-1-2-4",children:[]},{level:2,title:"2021.01.25",slug:"_2021-01-25",children:[]},{level:2,title:"2021.01.22 1.2.3",slug:"_2021-01-22-1-2-3",children:[]},{level:2,title:"2021.01.19",slug:"_2021-01-19",children:[]},{level:2,title:"2021.01.17",slug:"_2021-01-17",children:[]},{level:2,title:"2021.01.15 1.2.2",slug:"_2021-01-15-1-2-2",children:[]},{level:2,title:"2021.01.12",slug:"_2021-01-12",children:[]},{level:2,title:"2021.01.10 1.2.1",slug:"_2021-01-10-1-2-1",children:[]},{level:2,title:"2021.01.07",slug:"_2021-01-07",children:[]},{level:2,title:"2021.01.05",slug:"_2021-01-05",children:[]},{level:2,title:"2021.01.03",slug:"_2021-01-03",children:[]},{level:2,title:"2021.01.01",slug:"_2021-01-01",children:[]},{level:2,title:"2020.12.29",slug:"_2020-12-29",children:[]},{level:2,title:"2020.12.25 1.1.5",slug:"_2020-12-25-1-1-5",children:[]},{level:2,title:"2020.12.24",slug:"_2020-12-24",children:[]},{level:2,title:"2020.12.23",slug:"_2020-12-23",children:[]},{level:2,title:"2020.12.21",slug:"_2020-12-21",children:[]},{level:2,title:"2020.12.18 1.1.4",slug:"_2020-12-18-1-1-4",children:[]},{level:2,title:"2020.12.17",slug:"_2020-12-17",children:[]},{level:2,title:"2020.12.15",slug:"_2020-12-15",children:[]},{level:2,title:"2020.12.11 1.1.3",slug:"_2020-12-11-1-1-3",children:[]},{level:2,title:"2020.12.06 1.1.2",slug:"_2020-12-06-1-1-2",children:[]},{level:2,title:"2020.12.04",slug:"_2020-12-04",children:[]},{level:2,title:"2020.11.27",slug:"_2020-11-27",children:[]},{level:2,title:"2020.11.25 1.0.0",slug:"_2020-11-25-1-0-0",children:[]},{level:2,title:"2020.11.23",slug:"_2020-11-23",children:[]}],path:"/en/about/news.html",pathLocale:"/en/",extraFields:[]},{title:"Configurations",headers:[{level:2,title:"Overview",slug:"overview",children:[]},{level:2,title:"Basic Configuration Modules",slug:"basic-configuration-modules",children:[]}],path:"/en/config/",pathLocale:"/en/",extraFields:[]},{title:"API Interface",headers:[{level:2,title:"ApiObject",slug:"apiobject",children:[]},{level:2,title:"Related Configuration",slug:"related-configuration",children:[]},{level:2,title:"Supported API List",slug:"supported-api-list",children:[{level:3,title:"HandlerService",slug:"handlerservice",children:[]},{level:3,title:"LoggerService",slug:"loggerservice",children:[]},{level:3,title:"StatsService",slug:"statsservice",children:[]},{level:3,title:"ReflectionService",slug:"reflectionservice",children:[]}]},{level:2,title:"API Calling Example",slug:"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",children:[]},{level:2,title:"DNS Processing Flow",slug:"dns-processing-flow",children:[]},{level:2,title:"DnsObject",slug:"dnsobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/dns.html",pathLocale:"/en/",extraFields:[]},{title:"FakeDNS",headers:[{level:2,title:"FakeDNSObject",slug:"fakednsobject",children:[{level:3,title:"How to use?",slug:"how-to-use",children:[]},{level:3,title:"Using with other types of DNS",slug:"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",children:[{level:3,title:"SniffingObject",slug:"sniffingobject",children:[]},{level:3,title:"AllocateObject",slug:"allocateobject",children:[]}]}],path:"/en/config/inbound.html",pathLocale:"/en/",extraFields:[]},{title:"Log Configuration",headers:[{level:2,title:"LogObject",slug:"logobject",children:[]}],path:"/en/config/log.html",pathLocale:"/en/",extraFields:[]},{title:"Outbound Proxies",headers:[{level:2,title:"OutboundObject",slug:"outboundobject",children:[{level:3,title:"ProxySettingsObject",slug:"proxysettingsobject",children:[]},{level:3,title:"MuxObject",slug:"muxobject",children:[]}]}],path:"/en/config/outbound.html",pathLocale:"/en/",extraFields:[]},{title:"Local Policy",headers:[{level:2,title:"PolicyObject",slug:"policyobject",children:[{level:3,title:"LevelPolicyObject",slug:"levelpolicyobject",children:[]},{level:3,title:"SystemPolicyObject",slug:"systempolicyobject",children:[]}]}],path:"/en/config/policy.html",pathLocale:"/en/",extraFields:[]},{title:"Reverse Proxy",headers:[{level:2,title:"ReverseObject",slug:"reverseobject",children:[{level:3,title:"BridgeObject",slug:"bridgeobject",children:[]},{level:3,title:"PortalObject",slug:"portalobject",children:[]}]},{level:2,title:"Complete Configuration Example",slug:"complete-configuration-example",children:[{level:3,title:"Bridge Configuration",slug:"bridge-configuration",children:[]},{level:3,title:"Portal Configuration",slug:"portal-configuration",children:[]}]}],path:"/en/config/reverse.html",pathLocale:"/en/",extraFields:[]},{title:"Routing",headers:[{level:2,title:"RoutingObject",slug:"routingobject",children:[{level:3,title:"RuleObject",slug:"ruleobject",children:[]},{level:3,title:"BalancerObject",slug:"balancerobject",children:[]},{level:3,title:"Predefined Domain Lists",slug:"predefined-domain-lists",children:[]}]}],path:"/en/config/routing.html",pathLocale:"/en/",extraFields:[]},{title:"Traffic Statistics",headers:[{level:2,title:"StatsObject",slug:"statsobject",children:[]},{level:2,title:"Retrieving Traffic Statistics",slug:"retrieving-traffic-statistics",children:[]}],path:"/en/config/stats.html",pathLocale:"/en/",extraFields:[]},{title:"Transport Protocol",headers:[{level:2,title:"TransportObject",slug:"transportobject",children:[]},{level:2,title:"StreamSettingsObject",slug:"streamsettingsobject",children:[{level:3,title:"TLSObject",slug:"tlsobject",children:[]},{level:3,title:"SockoptObject",slug:"sockoptobject",children:[]}]}],path:"/en/config/transport.html",pathLocale:"/en/",extraFields:[]},{title:"Development Guide",headers:[{level:2,title:"Compile Documentation",slug:"compile-documentation",children:[]},{level:2,title:"Design Concept",slug:"design-concept",children:[]},{level:2,title:"Development Standards",slug:"development-standards",children:[]},{level:2,title:"Protocol Details",slug:"protocol-details",children:[{level:3,title:"VLESS Protocol",slug:"vless-protocol",children:[]},{level:3,title:"VMess Protocol",slug:"vmess-protocol",children:[]},{level:3,title:"Mux.Cool Protocol",slug:"mux-cool-protocol",children:[]},{level:3,title:"mKCP Protocol",slug:"mkcp-protocol",children:[]}]}],path:"/en/development/",pathLocale:"/en/",extraFields:[]},{title:"Quick Start",headers:[{level:2,title:"Download and Install",slug:"download-and-install",children:[]},{level:2,title:"Configure and Run",slug:"configure-and-run",children:[]},{level:2,title:"Command Parameters",slug:"command-parameters",children:[]},{level:2,title:"Improve Documents",slug:"improve-documents",children:[]},{level:2,title:"Beginner Tutorial",slug:"beginner-tutorial",children:[]},{level:2,title:"Getting Started Tips",slug:"getting-started-tips",children:[]},{level:2,title:"Advanced Documentation",slug:"advanced-documentation",children:[]}],path:"/en/document/",pathLocale:"/en/",extraFields:[]},{title:"Command Parameters",headers:[{level:2,title:"Get Basic Commands",slug:"get-basic-commands",children:[{level:3,title:"xray run",slug:"xray-run",children:[]},{level:3,title:"xray version",slug:"xray-version",children:[]},{level:3,title:"xray api",slug:"xray-api",children:[]},{level:3,title:"xray tls",slug:"xray-tls",children:[]},{level:3,title:"xray uuid",slug:"xray-uuid",children:[]}]}],path:"/en/document/command.html",pathLocale:"/en/",extraFields:[]},{title:"Configure and Run",headers:[{level:2,title:"Server Configuration",slug:"server-configuration",children:[]},{level:2,title:"Client Configuration",slug:"client-configuration",children:[]},{level:2,title:"Run",slug:"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",children:[]},{level:2,title:"Found Problems?",slug:"found-problems",children:[]}],path:"/en/document/document.html",pathLocale:"/en/",extraFields:[]},{title:"Download and Install",headers:[{level:2,title:"Platform Support",slug:"platform-support",children:[]},{level:2,title:"Download Xray",slug:"download-xray",children:[]},{level:2,title:"Verify the Installation Package",slug:"verify-the-installation-package",children:[]},{level:2,title:"Install on Windows",slug:"install-on-windows",children:[]},{level:2,title:"Install on macOS",slug:"install-on-macos",children:[]},{level:2,title:"Install on Linux",slug:"install-on-linux",children:[{level:3,title:"Install Script",slug:"install-script",children:[]},{level:3,title:"Arch Linux",slug:"arch-linux",children:[]},{level:3,title:"Linuxbrew",slug:"linuxbrew",children:[]},{level:3,title:"Debian",slug:"debian",children:[]}]},{level:2,title:"Install via Docker",slug:"install-via-docker",children:[{level:3,title:"The File Structure of the Docker Image",slug:"the-file-structure-of-the-docker-image",children:[]}]}],path:"/en/document/install.html",pathLocale:"/en/",extraFields:[]},{title:"透明代理入门",headers:[{level:2,title:"什么是透明代理",slug:"什么是透明代理",children:[]},{level:2,title:"透明代理的实现",slug:"透明代理的实现",children:[{level:3,title:"tun2socks",slug:"tun2socks",children:[]},{level:3,title:"iptables/nftables",slug:"iptables-nftables",children:[]}]},{level:2,title:"iptables 实现透明代理原理",slug:"iptables-实现透明代理原理",children:[]},{level:2,title:"透明代理难在哪里",slug:"透明代理难在哪里",children:[]},{level:2,title:"从零开始一步步实现基于 iptables-tproxy 的透明代理",slug:"从零开始一步步实现基于-iptables-tproxy-的透明代理",children:[{level:3,title:"在开始之前,你需要有一定的基础知识:",slug:"在开始之前-你需要有一定的基础知识",children:[]},{level:3,title:"前期准备工作",slug:"前期准备工作",children:[]},{level:3,title:"首先,我们先试试做到第一阶段",slug:"首先-我们先试试做到第一阶段",children:[]},{level:3,title:"第二阶段",slug:"第二阶段",children:[]},{level:3,title:"第三阶段",slug:"第三阶段",children:[]},{level:3,title:"第四阶段",slug:"第四阶段",children:[]},{level:3,title:"代理 ipv6",slug:"代理-ipv6",children:[]}]}],path:"/document/level-2/transparent_proxy/transparent_proxy.html",pathLocale:"/",extraFields:[]},{title:"Browser Dialer",headers:[{level:2,title:"Background",slug:"background",children:[]},{level:2,title:"Xray & JS",slug:"xray-js",children:[]},{level:2,title:"Early data",slug:"early-data",children:[]},{level:2,title:"Configuration",slug:"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",children:[]},{level:2,title:"Configuration File Location",slug:"configuration-file-location",children:[]},{level:2,title:"Multiple Configuration Directories",slug:"multiple-configuration-directories",children:[]}],path:"/en/config/features/env.html",pathLocale:"/en/",extraFields:[]},{title:"Fallback",headers:[{level:2,title:"fallbacks configuration",slug:"fallbacks-configuration",children:[{level:3,title:"FallbackObject",slug:"fallbackobject",children:[]},{level:3,title:"Additional Information",slug:"additional-information",children:[]}]},{level:2,title:"Fallbacks design theory",slug:"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",children:[]},{level:2,title:"Rule Explaination",slug:"rule-explaination",children:[{level:3,title:"Normal Objects({})",slug:"normal-objects",children:[]},{level:3,title:"Arrays([])",slug:"arrays",children:[]}]},{level:2,title:"Recommended Multi-file List",slug:"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",children:[]},{level:2,title:"Transparent Proxy Configuration Example",slug:"transparent-proxy-configuration-example",children:[]}],path:"/en/config/inbounds/dokodemo.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",children:[]}]}],path:"/en/config/inbounds/http.html",pathLocale:"/en/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[]},{level:2,title:"ClientObject",slug:"clientobject",children:[]}],path:"/en/config/inbounds/shadowsocks.html",pathLocale:"/en/",extraFields:[]},{title:"SOCKS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"AccountObject",slug:"accountobject",children:[]}]}],path:"/en/config/inbounds/socks.html",pathLocale:"/en/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]}]}],path:"/en/config/inbounds/trojan.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]}]}],path:"/en/config/inbounds/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"InboundConfigurationObject",slug:"inboundconfigurationobject",children:[{level:3,title:"ClientObject",slug:"clientobject",children:[]},{level:3,title:"DetourObject",slug:"detourobject",children:[]},{level:3,title:"DefaultObject",slug:"defaultobject",children:[]}]}],path:"/en/config/inbounds/vmess.html",pathLocale:"/en/",extraFields:[]},{title:"Blackhole",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ResponseObject",slug:"responseobject",children:[]}]}],path:"/en/config/outbounds/blackhole.html",pathLocale:"/en/",extraFields:[]},{title:"DNS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[]},{level:2,title:"DNS Configuration Example",slug:"dns-configuration-example",children:[]}],path:"/en/config/outbounds/dns.html",pathLocale:"/en/",extraFields:[]},{title:"Freedom",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[]}],path:"/en/config/outbounds/freedom.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/outbounds/http.html",pathLocale:"/en/",extraFields:[]},{title:"Shadowsocks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/outbounds/shadowsocks.html",pathLocale:"/en/",extraFields:[]},{title:"Socks",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/outbounds/socks.html",pathLocale:"/en/",extraFields:[]},{title:"Trojan",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/outbounds/trojan.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]},{level:3,title:"UserObject",slug:"userobject",children:[]}]}],path:"/en/config/outbounds/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"ServerObject",slug:"serverobject",children:[]}]}],path:"/en/config/outbounds/vmess.html",pathLocale:"/en/",extraFields:[]},{title:"Wireguard",headers:[{level:2,title:"OutboundConfigurationObject",slug:"outboundconfigurationobject",children:[{level:3,title:"Peers",slug:"peers",children:[]}]}],path:"/en/config/outbounds/wireguard.html",pathLocale:"/en/",extraFields:[]},{title:"Domain Socket",headers:[{level:2,title:"DomainSocketObject",slug:"domainsocketobject",children:[]}],path:"/en/config/transports/domainsocket.html",pathLocale:"/en/",extraFields:[]},{title:"gRPC",headers:[{level:2,title:"GRPCObject",slug:"grpcobject",children:[]}],path:"/en/config/transports/grpc.html",pathLocale:"/en/",extraFields:[]},{title:"HTTP/2",headers:[{level:2,title:"HttpObject",slug:"httpobject",children:[]}],path:"/en/config/transports/h2.html",pathLocale:"/en/",extraFields:[]},{title:"mKCP",headers:[{level:2,title:"KcpObject",slug:"kcpobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",children:[]}]},{level:2,title:"Special Thanks",slug:"special-thanks",children:[]},{level:2,title:"Improvements to the KCP protocol",slug:"improvements-to-the-kcp-protocol",children:[{level:3,title:"smaller protocol header",slug:"smaller-protocol-header",children:[]},{level:3,title:"ACK packet retransmission",slug:"ack-packet-retransmission",children:[]},{level:3,title:"Connection state control",slug:"connection-state-control",children:[]}]}],path:"/en/config/transports/mkcp.html",pathLocale:"/en/",extraFields:[]},{title:"QUIC",headers:[{level:2,title:"QuicObject",slug:"quicobject",children:[{level:3,title:"HeaderObject",slug:"headerobject",children:[]}]}],path:"/en/config/transports/quic.html",pathLocale:"/en/",extraFields:[]},{title:"TCP",headers:[{level:2,title:"TcpObject",slug:"tcpobject",children:[{level:3,title:"NoneHeaderObject",slug:"noneheaderobject",children:[]},{level:3,title:"HttpHeaderObject",slug:"httpheaderobject",children:[]}]}],path:"/en/config/transports/tcp.html",pathLocale:"/en/",extraFields:[]},{title:"WebSocket",headers:[{level:2,title:"WebSocketObject",slug:"websocketobject",children:[]},{level:2,title:"Browser Dialer",slug:"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",children:[]},{level:2,title:"Pull Xray source code",slug:"pull-xray-source-code",children:[]},{level:2,title:"Build Binary",slug:"build-binary",children:[{level:3,title:"Windows(Powershell):",slug:"windows-powershell",children:[]},{level:3,title:"macOS, Linux:",slug:"macos-linux",children:[]}]},{level:2,title:"Cross compilation:",slug:"cross-compilation",children:[]},{level:2,title:"Reproducible Build:",slug:"reproducible-build",children:[]}],path:"/en/development/intro/compile.html",pathLocale:"/en/",extraFields:[]},{title:"Design Objectives",headers:[{level:2,title:"Architecture",slug:"architecture",children:[{level:3,title:"Application Layer",slug:"application-layer",children:[]},{level:3,title:"Proxy Layer",slug:"proxy-layer",children:[]},{level:3,title:"Transport Layer",slug:"transport-layer",children:[]}]}],path:"/en/development/intro/design.html",pathLocale:"/en/",extraFields:[]},{title:"Development Standards",headers:[{level:2,title:"Basic",slug:"basic",children:[{level:3,title:"Version Control",slug:"version-control",children:[]},{level:3,title:"Branch",slug:"branch",children:[]},{level:3,title:"Release",slug:"release",children:[]},{level:3,title:"Citing other projects",slug:"citing-other-projects",children:[]}]},{level:2,title:"Development Process",slug:"development-process",children:[{level:3,title:"Before Writing Code",slug:"before-writing-code",children:[]},{level:3,title:"Modify the code",slug:"modify-the-code",children:[]},{level:3,title:"Pull Request",slug:"pull-request",children:[]},{level:3,title:"Modifying Code",slug:"modifying-code",children:[]}]},{level:2,title:"Xray Coding Guidelines",slug:"xray-coding-guidelines",children:[{level:3,title:"Code Structure",slug:"code-structure",children:[]},{level:3,title:"Coding Standards",slug:"coding-standards",children:[]}]}],path:"/en/development/intro/guide.html",pathLocale:"/en/",extraFields:[]},{title:"mKCP Protocol",headers:[{level:2,title:"Version",slug:"version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",children:[]},{level:3,title:"Functions",slug:"functions",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",children:[]},{level:2,title:"Data Format",slug:"data-format",children:[{level:3,title:"Data Packet",slug:"data-packet",children:[]},{level:3,title:"Data snippet",slug:"data-snippet",children:[]},{level:3,title:"Confirmation snippet",slug:"confirmation-snippet",children:[]},{level:3,title:"Heartbeat Fragments",slug:"heartbeat-fragments",children:[]}]}],path:"/en/development/protocols/mkcp.html",pathLocale:"/en/",extraFields:[]},{title:"Mux.Cool Protocol",headers:[{level:2,title:"Version",slug:"version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",children:[{level:3,title:"Client behavior",slug:"client-behavior",children:[]},{level:3,title:"Server-side behavior",slug:"server-side-behavior",children:[]}]},{level:2,title:"Data Format",slug:"data-format",children:[{level:3,title:"Frame Format",slug:"frame-format",children:[]},{level:3,title:"Metadata",slug:"metadata",children:[]},{level:3,title:"New Sublink (New)",slug:"new-sublink-new",children:[]},{level:3,title:"Keep sub-connections",slug:"keep-sub-connections",children:[]},{level:3,title:"End",slug:"end",children:[]},{level:3,title:"KeepAlive",slug:"keepalive",children:[]}]},{level:2,title:"Application",slug:"application",children:[]}],path:"/en/development/protocols/muxcool.html",pathLocale:"/en/",extraFields:[]},{title:"VLESS Protocol",headers:[{level:2,title:"Request & Response",slug:"request-response",children:[]},{level:2,title:"ProtoBuf",slug:"protobuf",children:[]},{level:2,title:"Flow",slug:"flow",children:[{level:3,title:"Flow Control (Formerly Traffic Scheduler)",slug:"flow-control-formerly-traffic-scheduler",children:[]}]},{level:2,title:"Encryption",slug:"encryption",children:[]},{level:2,title:"UDP issues",slug:"udp-issues",children:[]},{level:2,title:"Client Development Guide",slug:"client-development-guide",children:[]},{level:2,title:"VLESS Sharing Link Standard",slug:"vless-sharing-link-standard",children:[]}],path:"/en/development/protocols/vless.html",pathLocale:"/en/",extraFields:[]},{title:"VMess Protocol",headers:[{level:2,title:"Version",slug:"version",children:[]},{level:2,title:"Dependencies",slug:"dependencies",children:[{level:3,title:"Underlying Protocol",slug:"underlying-protocol",children:[]},{level:3,title:"User ID",slug:"user-id",children:[]},{level:3,title:"Functions",slug:"functions",children:[]}]},{level:2,title:"Communication Process",slug:"communication-process",children:[]},{level:2,title:"Client Request",slug:"client-request",children:[{level:3,title:"Authentication Information",slug:"authentication-information",children:[]},{level:3,title:"Command Section",slug:"command-section",children:[]},{level:3,title:"Data Section",slug:"data-section",children:[]}]},{level:2,title:"Server Response",slug:"server-response",children:[{level:3,title:"Dynamic Port Instructions",slug:"dynamic-port-instructions",children:[]}]},{level:2,title:"Comment",slug:"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",children:[]},{level:2,title:"1.2 Who is this document not written for?",slug:"_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",children:[]},{level:2,title:"1.4 Why is self-hosting a challenge?",slug:"_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",children:[]},{level:2,title:"1.6 So should you build your own website?",slug:"_1-6-so-should-you-build-your-own-website",children:[]},{level:2,title:"1.7 Some digressions",slug:"_1-7-some-digressions",children:[]},{level:2,title:"1.8 Your Progress",slug:"_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",children:[]},{level:2,title:"2.2 Obtaining a Desired Domain Name",slug:"_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",children:[]},{level:2,title:"2.4 Your Progress",slug:"_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",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",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",children:[]},{level:2,title:"3.4 Your Progress",slug:"_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",children:[]},{level:2,title:"4.2 What are the specific risks",slug:"_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",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",children:[]},{level:2,title:"4.5 Creating a New User Without Root Access",slug:"_4-5-creating-a-new-user-without-root-access",children:[]},{level:2,title:"4.6 Disabling SSH Remote Login for Root User",slug:"_4-6-disabling-ssh-remote-login-for-root-user",children:[]},{level:2,title:"4.7 Login with RSA Key and Disable Password Login",slug:"_4-7-login-with-rsa-key-and-disable-password-login",children:[]},{level:2,title:"4.8 Your Progress",slug:"_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",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",children:[]},{level:2,title:"5.3 Create the simplest web page",slug:"_5-3-create-the-simplest-web-page",children:[]},{level:2,title:"5.4 Common error explanations",slug:"_5-4-common-error-explanations",children:[]},{level:2,title:"5.5 Your Progress",slug:"_5-5-your-progress",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",children:[]},{level:2,title:"6.2 Install acme.sh",slug:"_6-2-install-acme-sh",children:[]},{level:2,title:"6.3 Testing Certificate Application",slug:"_6-3-testing-certificate-application",children:[]},{level:2,title:"6.4 Application for Official Certification",slug:"_6-4-application-for-official-certification",children:[]},{level:2,title:"6.5 Certificate Installation",slug:"_6-5-certificate-installation",children:[]},{level:2,title:"6.6 Your Progress",slug:"_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-博观而约取-厚积而薄发",children:[]},{level:2,title:"7.2 安装 Xray",slug:"_7-2-安装-xray",children:[]},{level:2,title:"7.3 给 Xray 配置 TLS 证书",slug:"_7-3-给-xray-配置-tls-证书",children:[]},{level:2,title:"7.4 配置 Xray",slug:"_7-4-配置-xray",children:[]},{level:2,title:"7.5 启动 Xray 服务!!(并查看服务状态)",slug:"_7-5-启动-xray-服务-并查看服务状态",children:[]},{level:2,title:"7.6 回顾 systemd 进行基本的服务管理",slug:"_7-6-回顾-systemd-进行基本的服务管理",children:[]},{level:2,title:"7.7 服务器优化之一:开启 BBR",slug:"_7-7-服务器优化之一-开启-bbr",children:[]},{level:2,title:"7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS",slug:"_7-8-服务器优化之二-开启-http-自动跳转-https",children:[]},{level:2,title:"7.9 服务器优化之三:更丰富的回落",slug:"_7-9-服务器优化之三-更丰富的回落",children:[]},{level:2,title:"7.10 你的进度",slug:"_7-10-你的进度",children:[]},{level:2,title:"7.11 重要勘误",slug:"_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-的工作原理简述",children:[]},{level:2,title:"8.2 客户端与服务器端正确连接",slug:"_8-2-客户端与服务器端正确连接",children:[]},{level:2,title:"8.3 附加题 1:在 PC 端手工配置 xray-core",slug:"_8-3-附加题-1-在-pc-端手工配置-xray-core",children:[]},{level:2,title:"8.4 附加题 2:在 PC 端手工运行 xray-core",slug:"_8-4-附加题-2-在-pc-端手工运行-xray-core",children:[]},{level:2,title:"8.5 附加题 3:在 PC 端开机自动运行 xray-core",slug:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",children:[]},{level:2,title:"8.6 圆满完成!",slug:"_8-6-圆满完成",children:[]},{level:2,title:"8.7 TO INFINITY AND BEYOND!",slug:"_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-基础命令索引",children:[]},{level:2,title:"2. 小小白白 Linux 重要配置文件索引",slug:"_2-小小白白-linux-重要配置文件索引",children:[]},{level:2,title:"3. 小小白白 Xray 重要文件索引",slug:"_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-回顾《小小白白话文》中的回落",children:[]},{level:2,title:"2. 重新认识回落 (WHAT, HOW v1)",slug:"_2-重新认识回落-what-how-v1",children:[]},{level:2,title:"3. 为什么要回落 (WHY v1)",slug:"_3-为什么要回落-why-v1",children:[]},{level:2,title:"4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)",slug:"_4-重新认识【回落の完全体】-what-why-how-v2",children:[]},{level:2,title:"5. 多层回落示例及解读",slug:"_5-多层回落示例及解读",children:[{level:3,title:"5.1 首先,我将服务器端配置的 443 监听段摘抄如下:",slug:"_5-1-首先-我将服务器端配置的-443-监听段摘抄如下",children:[]},{level:3,title:"5.2 后续监听处理的配置段摘抄如下:",slug:"_5-2-后续监听处理的配置段摘抄如下",children:[]}]},{level:2,title:"6. 结语",slug:"_6-结语",children:[]},{level:2,title:"7. 附加题",slug:"_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",children:[]},{level:2,title:"Introduction to SNI",slug:"introduction-to-sni",children:[]},{level:2,title:"Idea",slug:"idea",children:[]},{level:2,title:"Adding DNS Records",slug:"adding-dns-records",children:[]},{level:2,title:"Applying for TLS Certificate",slug:"applying-for-tls-certificate",children:[]},{level:2,title:"Xray Configuration",slug:"xray-configuration",children:[]},{level:2,title:"Nginx Configuration",slug:"nginx-configuration",children:[]},{level:2,title:"Caddy Configuration",slug:"caddy-configuration",children:[]},{level:2,title:"Reference",slug:"reference",children:[]},{level:2,title:"Quotation",slug:"quotation",children:[]}],path:"/en/document/level-1/fallbacks-with-sni.html",pathLocale:"/en/",extraFields:[]},{title:"路由 (routing) 功能简析(上)",headers:[{level:2,title:"1. 初识【路由】三兄弟",slug:"_1-初识【路由】三兄弟",children:[]},{level:2,title:"2. 基本功: “兄弟一条心”",slug:"_2-基本功-兄弟一条心",children:[{level:3,title:"2.1 入站",slug:"_2-1-入站",children:[]},{level:3,title:"2.3 路由",slug:"_2-3-路由",children:[]},{level:3,title:"2.4 路由配置项解析之一:流量筛选的依据",slug:"_2-4-路由配置项解析之一-流量筛选的依据",children:[]}]},{level:2,title:"3. 小试牛刀: “三分天下” 之 “域名分流”",slug:"_3-小试牛刀-三分天下-之-域名分流",children:[{level:3,title:"3.1 入站",slug:"_3-1-入站",children:[]},{level:3,title:"3.2 出站",slug:"_3-2-出站",children:[]},{level:3,title:"3.3 路由",slug:"_3-3-路由",children:[]},{level:3,title:"3.4 简析域名文件: geosite.dat",slug:"_3-4-简析域名文件-geosite-dat",children:[]},{level:3,title:"3.5 所以 geosite.dat 到底是什么?不是有个 GFWList 吗?",slug:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",children:[]},{level:3,title:"3.6 军师锦囊藏奇兵:一条隐藏的路由规则",slug:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",children:[]},{level:3,title:"3.7 再看“三分天下”的大地图",slug:"_3-7-再看-三分天下-的大地图",children:[]}]},{level:2,title:"4. “三分天下” 之 “蜀魏争雄”",slug:"_4-三分天下-之-蜀魏争雄",children:[]},{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",children:[]}],path:"/en/document/level-1/routing-lv1-part1.html",pathLocale:"/en/",extraFields:[]},{title:"路由 (routing) 功能简析(下)",headers:[{level:2,title:"5. 攻城略池 - 多种路由匹配条件",slug:"_5-攻城略池-多种路由匹配条件",children:[{level:3,title:"5.1 基于指定域名分流:[domain], [full] 等",slug:"_5-1-基于指定域名分流-domain-full-等",children:[]},{level:3,title:"5.2 基于 IP 文件分流:geoip.dat",slug:"_5-2-基于-ip-文件分流-geoip-dat",children:[]},{level:3,title:"5.3 基于指定 IP 地址分流",slug:"_5-3-基于指定-ip-地址分流",children:[]},{level:3,title:"5.4 基于协议类型分流:[protocol] 等",slug:"_5-4-基于协议类型分流-protocol-等",children:[]},{level:3,title:"5.5 基于更多条件的分流",slug:"_5-5-基于更多条件的分流",children:[]}]},{level:2,title:"6. “霸业初定”:路由规则整体回顾",slug:"_6-霸业初定-路由规则整体回顾",children:[]},{level:2,title:"7. 路由配置常见错误",slug:"_7-路由配置常见错误",children:[{level:3,title:"7.1 错误示范",slug:"_7-1-错误示范",children:[]},{level:3,title:"7.2 正确示范",slug:"_7-2-正确示范",children:[]}]},{level:2,title:"8. 明修栈道、暗渡陈仓",slug:"_8-明修栈道、暗渡陈仓",children:[{level:3,title:'8.1 域名策略: "AsIs"',slug:"_8-1-域名策略-asis",children:[]},{level:3,title:'8.2 域名策略: "IPIfNonMatch"',slug:"_8-2-域名策略-ipifnonmatch",children:[]},{level:3,title:'8.3 域名策略: "IPOnDemand"',slug:"_8-3-域名策略-ipondemand",children:[]}]},{level:2,title:"9. 思考题",slug:"_9-思考题",children:[]},{level:2,title:"10. 结语",slug:"_10-结语",children:[]},{level:2,title:"11. 尾注",slug:"_11-尾注",children:[]}],path:"/en/document/level-1/routing-lv1-part2.html",pathLocale:"/en/",extraFields:[]},{title:"Xray 的工作模式",headers:[{level:2,title:"单服务器模式",slug:"单服务器模式",children:[]},{level:2,title:"桥接模式",slug:"桥接模式",children:[]},{level:2,title:"工作原理",slug:"工作原理",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",children:[]},{level:2,title:"Configuration Procedure",slug:"configuration-procedure",children:[{level:3,title:"1. Preliminary preparation",slug:"_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",children:[]},{level:3,title:"3. Configure and run Xray, and configure iptables rules",slug:"_3-configure-and-run-xray-and-configure-iptables-rules",children:[]}]},{level:2,title:"Steps",slug:"steps",children:[{level:3,title:"1. Finish Preliminary preparation and Add user",slug:"_1-finish-preliminary-preparation-and-add-user",children:[]},{level:3,title:"2. Preparing Xray profiles",slug:"_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",children:[]},{level:3,title:"4. Setting up iptables rules",slug:"_4-setting-up-iptables-rules",children:[]}]}],path:"/en/document/level-2/iptables_gid.html",pathLocale:"/en/",extraFields:[]},{title:"Nginx_TLS隧道隐藏指纹",headers:[{level:2,title:"编译 nginx --with-stream",slug:"编译-nginx-with-stream",children:[]},{level:2,title:"配置 nginx",slug:"配置-nginx",children:[]},{level:2,title:"xray 配置",slug:"xray-配置",children:[]},{level:2,title:"客户端及服务端启动服务",slug:"客户端及服务端启动服务",children:[]},{level:2,title:"后记",slug:"后记",children:[]}],path:"/en/document/level-2/nginx_tls_tunnel.html",pathLocale:"/en/",extraFields:[]},{title:"出站流量重定向",headers:[{level:2,title:"前言",slug:"前言",children:[]},{level:2,title:"1、安装代理或者 VPN 软件(例如 Wireguard、IPsec 等)",slug:"_1、安装代理或者-vpn-软件-例如-wireguard、ipsec-等",children:[]},{level:2,title:"2、编辑 VPN 配置文件(以 WireGuard 为例)",slug:"_2、编辑-vpn-配置文件-以-wireguard-为例",children:[]},{level:2,title:"3、启用 WireGuard 网络接口",slug:"_3、启用-wireguard-网络接口",children:[]},{level:2,title:"4、Xray-core 配置文件修改",slug:"_4、xray-core-配置文件修改",children:[]},{level:2,title:"5、系统设置配置",slug:"_5、系统设置配置",children:[]},{level:2,title:"6、完成 WireGuard 相关设置",slug:"_6、完成-wireguard-相关设置",children:[]},{level:2,title:"后记",slug:"后记",children:[]},{level:2,title:"感谢",slug:"感谢",children:[]}],path:"/en/document/level-2/redirect.html",pathLocale:"/en/",extraFields:[]},{title:"TProxy 透明代理",headers:[{level:2,title:"开始之前",slug:"开始之前",children:[]},{level:2,title:"Xray 配置",slug:"xray-配置",children:[]},{level:2,title:"策略路由配置",slug:"策略路由配置",children:[]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",children:[]},{level:2,title:"配置永久化与开机自启",slug:"配置永久化与开机自启",children:[]}],path:"/en/document/level-2/tproxy.html",pathLocale:"/en/",extraFields:[]},{title:"TProxy 透明代理 (ipv4 and ipv6)",headers:[{level:2,title:"Xray 配置",slug:"xray-配置",children:[{level:3,title:"客户端配置",slug:"客户端配置",children:[]},{level:3,title:"服务端配置",slug:"服务端配置",children:[]}]},{level:2,title:"Netfilter 配置",slug:"netfilter-配置",children:[{level:3,title:"首先设置策略路由",slug:"首先设置策略路由",children:[]},{level:3,title:"使用 iptables",slug:"使用-iptables",children:[]},{level:3,title:"使用 nftables",slug:"使用-nftables",children:[]},{level:3,title:"开机自动运行 Netfilter 配置",slug:"开机自动运行-netfilter-配置",children:[]}]},{level:2,title:"局域网设备上网设置",slug:"局域网设备上网设置",children:[{level:3,title:"方法一",slug:"方法一",children:[]},{level:3,title:"方法二",slug:"方法二",children:[]}]},{level:2,title:"Finally",slug:"finally",children:[]},{level:2,title:"写在最后",slug:"写在最后",children:[]}],path:"/en/document/level-2/tproxy_ipv4_and_ipv6.html",pathLocale:"/en/",extraFields:[]},{title:"流量统计",headers:[{level:2,title:"查看流量信息",slug:"查看流量信息",children:[]},{level:2,title:"流量信息的处理",slug:"流量信息的处理",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",children:[]},{level:2,title:"Diverting inbound traffic to warp on the server side",slug:"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",children:[]}],path:"/en/document/level-2/warp.html",pathLocale:"/en/",extraFields:[]},{title:"透明代理入门",headers:[{level:2,title:"什么是透明代理",slug:"什么是透明代理",children:[]},{level:2,title:"透明代理的实现",slug:"透明代理的实现",children:[{level:3,title:"tun2socks",slug:"tun2socks",children:[]},{level:3,title:"iptables/nftables",slug:"iptables-nftables",children:[]}]},{level:2,title:"iptables 实现透明代理原理",slug:"iptables-实现透明代理原理",children:[]},{level:2,title:"透明代理难在哪里",slug:"透明代理难在哪里",children:[]},{level:2,title:"从零开始一步步实现基于 iptables-tproxy 的透明代理",slug:"从零开始一步步实现基于-iptables-tproxy-的透明代理",children:[{level:3,title:"在开始之前,你需要有一定的基础知识:",slug:"在开始之前-你需要有一定的基础知识",children:[]},{level:3,title:"前期准备工作",slug:"前期准备工作",children:[]},{level:3,title:"首先,我们先试试做到第一阶段",slug:"首先-我们先试试做到第一阶段",children:[]},{level:3,title:"第二阶段",slug:"第二阶段",children:[]},{level:3,title:"第三阶段",slug:"第三阶段",children:[]},{level:3,title:"第四阶段",slug:"第四阶段",children:[]},{level:3,title:"代理 ipv6",slug:"代理-ipv6",children:[]}]}],path:"/en/document/level-2/transparent_proxy/transparent_proxy.html",pathLocale:"/en/",extraFields:[]},{title:"",headers:[],path:"/404.html",pathLocale:"/",extraFields:[]}]);c.webpackHot&&(__VUE_HMR_RUNTIME__.updateSearchIndex=e=>{Ba.value=e});const $a=/[^\x00-\x7F]/,Wa=e=>e.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),Ua=(e,t)=>{const l=t.join(" "),n=e.split(/\s+/g).map((e=>e.trim())).filter((e=>!!e));if($a.test(e))return n.some((e=>l.toLowerCase().indexOf(e)>-1));const o=e.endsWith(" ");return new RegExp(n.map(((e,t)=>n.length!==t+1||o?`(?=.*\\b${Wa(e)}\\b)`:`(?=.*\\b${Wa(e)})`)).join("")+".+","gi").test(l)},qa=ol({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}=kt(e),o=qr(),i=gs(),r=Ba,s=jt(null),a=jt(!1),c=jt(""),d=It((()=>{var e;return null!==(e=t.value[i.value])&&void 0!==e?e:{}})),u=(({searchIndex:e,routeLocale:t,query:l,maxSuggestions:n})=>{const o=It((()=>e.value.filter((e=>e.pathLocale===t.value))));return It((()=>{const e=l.value.trim().toLowerCase();if(!e)return[];const t=[],i=(l,o)=>{Ua(e,[o.title])&&t.push({link:`${l.path}#${o.slug}`,title:l.title,header:o.title});for(const e of o.children){if(t.length>=n.value)return;i(l,e)}};for(const l of o.value){if(t.length>=n.value)break;if(Ua(e,[l.title,...l.extraFields]))t.push({link:l.path,title:l.title});else for(const e of l.headers){if(t.length>=n.value)break;i(l,e)}}return t}))})({searchIndex:r,routeLocale:i,query:c,maxSuggestions:n}),{focusIndex:h,focusNext:p,focusPrev:m}=(e=>{const t=jt(0);return{focusIndex:t,focusNext:()=>{t.value{t.value>0?t.value-=1:t.value=e.value.length-1}}})(u);(({input:e,hotKeys:t})=>{const l=l=>{e.value&&0!==t.value.length&&l.target===document.body&&t.value.includes(l.key)&&(e.value.focus(),l.preventDefault())};fl((()=>{document.addEventListener("keydown",l)})),bl((()=>{document.removeEventListener("keydown",l)}))})({input:s,hotKeys:l});const v=It((()=>a.value&&!!u.value.length)),f=e=>{if(!v.value)return;const t=u.value[e];t&&o.push(t.link).then((()=>{c.value="",h.value=0}))};return()=>Vo("form",{class:"search-box",role:"search"},[Vo("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:e=>c.value=e.target.value,onKeydown:e=>{switch(e.key){case"ArrowUp":v.value&&m();break;case"ArrowDown":v.value&&p();break;case"Enter":e.preventDefault(),f(h.value)}}}),v.value&&Vo("ul",{class:"suggestions",onMouseleave:()=>h.value=-1},u.value.map((({link:e,title:t,header:l},n)=>Vo("li",{class:["suggestion",{focus:h.value===n}],onMouseenter:()=>h.value=n,onMousedown:()=>f(n)},Vo("a",{href:e,onClick:e=>e.preventDefault()},[Vo("span",{class:"page-title"},t),l&&Vo("span",{class:"page-header"},`> ${l}`)])))))])}});const Xa={"/":{placeholder:"搜索"}},Ga=["s","/"];const Ka=[va,Pa,Ta,za,({app:e})=>{e.component("SearchBox",(e=>Vo(qa,s({locales:Xa,hotKeys:Ga,maxSuggestions:5},e))))}];function Ya(e,t,l){var n,o,i;void 0===t&&(t=50),void 0===l&&(l={});var r=null!=(n=l.isImmediate)&&n,s=null!=(o=l.callback)&&o,a=l.maxWait,c=Date.now(),d=[];function u(){if(void 0!==a){var e=Date.now()-c;if(e+t>=a)return a-e}return t}var h=function(){var t=[].slice.call(arguments),l=this;return new Promise((function(n,o){var a=r&&void 0===i;if(void 0!==i&&clearTimeout(i),i=setTimeout((function(){if(i=void 0,c=Date.now(),!r){var n=e.apply(l,t);s&&s(n),d.forEach((function(e){return(0,e.resolve)(n)})),d=[]}}),u()),a){var h=e.apply(l,t);return s&&s(h),n(h)}d.push({resolve:n,reject:o})}))};return h.cancel=function(e){void 0!==i&&clearTimeout(i),d.forEach((function(t){return(0,t.reject)(e)})),d=[]},h}const Qa=()=>window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0,Ja=()=>window.scrollTo({top:0,behavior:"smooth"});const Za=[ol({name:"BackToTop",setup(){const e=jt(0),t=It((()=>e.value>300));fl((()=>{e.value=Qa(),window.addEventListener("scroll",Ya((()=>{e.value=Qa()}),100))}));const l=Vo("div",{class:"back-to-top",onClick:Ja});return()=>Vo(ei,{name:"back-to-top"},{default:()=>t.value?l:null})}})];var ec=()=>{(()=>{const e=ha(),t=Us(),l=Ws("vuepress-color-scheme","auto"),n=It({get:()=>!!e.value.darkMode&&("auto"===l.value?t.value:"dark"===l.value),set(e){e===t.value?l.value="auto":l.value=e?"dark":"light"}});Gt(Gs,n),Ys(n)})(),(()=>{const e=ha(),t=os(),l=It((()=>ia(t.value,e.value)));Gt(na,l)})()};const tc=({headerLinkSelector:e,headerAnchorSelector:t,delay:l,offset:n=5})=>{const o=qr(),i=ts(),r=Ya((()=>(()=>{var l,i,r,s;const a=Array.from(document.querySelectorAll(e)),c=Array.from(document.querySelectorAll(t)).filter((e=>a.some((t=>t.hash===e.hash)))),d=Math.max(window.pageYOffset,document.documentElement.scrollTop,document.body.scrollTop),u=window.innerHeight+d,h=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),p=Math.abs(h-u)=(null!==(i=null===(l=t.parentElement)||void 0===l?void 0:l.offsetTop)&&void 0!==i?i:0)-n,m=!a||d<(null!==(s=null===(r=a.parentElement)||void 0===r?void 0:r.offsetTop)&&void 0!==s?s:0)-n;if(!(u||h&&m))continue;const v=decodeURIComponent(o.currentRoute.value.hash),f=decodeURIComponent(t.hash);if(v===f)return;if(p)for(let l=e+1;l{r(),window.addEventListener("scroll",r)})),bl((()=>{window.removeEventListener("scroll",r)})),Ao((()=>i.value.path),r)},lc=async(e,...t)=>{const{scrollBehavior:l}=e.options;e.options.scrollBehavior=void 0,await e.replace(...t).finally((()=>e.options.scrollBehavior=l))};var nc=()=>{tc({headerLinkSelector:"a.sidebar-item",headerAnchorSelector:".header-anchor",delay:200,offset:5})},oc="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function ic(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function rc(e){throw new Error('Could not dynamically require "'+e+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var sc={exports:{}}; /* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress * @license MIT */sc.exports=function(){var e,t,l={version:"0.2.0"},n=l.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function o(e,t,l){return el?l:e}function i(e){return 100*(-1+e)}function r(e,t,l){var o;return(o="translate3d"===n.positionUsing?{transform:"translate3d("+i(e)+"%,0,0)"}:"translate"===n.positionUsing?{transform:"translate("+i(e)+"%,0)"}:{"margin-left":i(e)+"%"}).transition="all "+t+"ms "+l,o}l.configure=function(e){var t,l;for(t in e)void 0!==(l=e[t])&&e.hasOwnProperty(t)&&(n[t]=l);return this},l.status=null,l.set=function(e){var t=l.isStarted();e=o(e,n.minimum,1),l.status=1===e?null:e;var i=l.render(!t),c=i.querySelector(n.barSelector),d=n.speed,u=n.easing;return i.offsetWidth,s((function(t){""===n.positionUsing&&(n.positionUsing=l.getPositioningCSS()),a(c,r(e,d,u)),1===e?(a(i,{transition:"none",opacity:1}),i.offsetWidth,setTimeout((function(){a(i,{transition:"all "+d+"ms linear",opacity:0}),setTimeout((function(){l.remove(),t()}),d)}),d)):setTimeout(t,d)})),this},l.isStarted=function(){return"number"==typeof l.status},l.start=function(){l.status||l.set(0);var e=function(){setTimeout((function(){l.status&&(l.trickle(),e())}),n.trickleSpeed)};return n.trickle&&e(),this},l.done=function(e){return e||l.status?l.inc(.3+.5*Math.random()).set(1):this},l.inc=function(e){var t=l.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),l.set(t)):l.start()},l.trickle=function(){return l.inc(Math.random()*n.trickleRate)},e=0,t=0,l.promise=function(n){return n&&"resolved"!==n.state()?(0===t&&l.start(),e++,t++,n.always((function(){0==--t?(e=0,l.done()):l.set((e-t)/e)})),this):this},l.render=function(e){if(l.isRendered())return document.getElementById("nprogress");d(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=n.template;var o,r=t.querySelector(n.barSelector),s=e?"-100":i(l.status||0),c=document.querySelector(n.parent);return a(r,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),n.showSpinner||(o=t.querySelector(n.spinnerSelector))&&p(o),c!=document.body&&d(c,"nprogress-custom-parent"),c.appendChild(t),t},l.remove=function(){u(document.documentElement,"nprogress-busy"),u(document.querySelector(n.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},l.isRendered=function(){return!!document.getElementById("nprogress")},l.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var l=e.shift();l&&l(t)}return function(l){e.push(l),1==e.length&&t()}}(),a=function(){var e=["Webkit","O","Moz","ms"],t={};function l(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function n(t){var l=document.body.style;if(t in l)return t;for(var n,o=e.length,i=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((n=e[o]+i)in l)return n;return t}function o(e){return e=l(e),t[e]||(t[e]=n(e))}function i(e,t,l){t=o(t),e.style[t]=l}return function(e,t){var l,n,o=arguments;if(2==o.length)for(l in t)void 0!==(n=t[l])&&t.hasOwnProperty(l)&&i(e,l,n);else i(e,o[1],o[2])}}();function c(e,t){return("string"==typeof e?e:h(e)).indexOf(" "+t+" ")>=0}function d(e,t){var l=h(e),n=l+t;c(l,t)||(e.className=n.substring(1))}function u(e,t){var l,n=h(e);c(e,t)&&(l=n.replace(" "+t+" "," "),e.className=l.substring(1,l.length-1))}function h(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return l}();const ac=[ec,nc,()=>{fl((()=>{const e=qr(),t=new Set;t.add(e.currentRoute.value.path),sc.exports.configure({showSpinner:!1}),e.beforeEach((e=>{t.has(e.path)||sc.exports.start()})),e.afterEach((e=>{t.add(e.path),sc.exports.done()}))}))}],cc=[["v-8daa1a0e","/","",["/index.html","/README.md"]],["v-aad48c6a","/about/news.html","大史记",["/about/news","/about/news.md"]],["v-ba934fd8","/config/","配置文件",["/config/index.html","/config/README.md"]],["v-41ade9da","/config/api.html","API 接口",["/config/api","/config/api.md"]],["v-83dedd38","/config/dns.html","内置 DNS 服务器",["/config/dns","/config/dns.md"]],["v-192a19b9","/config/fakedns.html","FakeDNS",["/config/fakedns","/config/fakedns.md"]],["v-7f6279d8","/config/inbound.html","入站代理",["/config/inbound","/config/inbound.md"]],["v-1d860c29","/config/log.html","日志配置",["/config/log","/config/log.md"]],["v-2367d756","/config/outbound.html","出站代理",["/config/outbound","/config/outbound.md"]],["v-4ebec35a","/config/policy.html","本地策略",["/config/policy","/config/policy.md"]],["v-31b7756a","/config/reverse.html","反向代理",["/config/reverse","/config/reverse.md"]],["v-70677432","/config/routing.html","路由",["/config/routing","/config/routing.md"]],["v-7e21d6ae","/config/stats.html","统计信息",["/config/stats","/config/stats.md"]],["v-e3dfff38","/config/transport.html","传输方式",["/config/transport","/config/transport.md"]],["v-f7496066","/development/","开发指南",["/development/index.html","/development/README.md"]],["v-36b1a79b","/document/","快速入门",["/document/index.html","/document/README.md"]],["v-09a64f89","/document/command.html","命令参数",["/document/command","/document/command.md"]],["v-2b1adf48","/document/config.html","配置运行",["/document/config","/document/config.md"]],["v-86ee963a","/document/document.html","为 Project X 的文档贡献",["/document/document","/document/document.md"]],["v-0e5d7b39","/document/install.html","下载安装",["/document/install","/document/install.md"]],["v-2d0a870d","/en/","",["/en/index.html","/en/README.md"]],["v-0d714d87","/config/features/browser_dialer.html","Browser Dialer",["/config/features/browser_dialer","/config/features/browser_dialer.md"]],["v-0da7880a","/config/features/env.html","环境变量",["/config/features/env","/config/features/env.md"]],["v-2aeb21f9","/config/features/fallback.html","Fallback 回落",["/config/features/fallback","/config/features/fallback.md"]],["v-3acf20ea","/config/features/multiple.html","多文件配置",["/config/features/multiple","/config/features/multiple.md"]],["v-792e28f8","/config/features/xtls.html","XTLS 深度剖析",["/config/features/xtls","/config/features/xtls.md"]],["v-b50d2334","/config/inbounds/dokodemo.html","Dokodemo-Door",["/config/inbounds/dokodemo","/config/inbounds/dokodemo.md"]],["v-593408b0","/config/inbounds/http.html","HTTP",["/config/inbounds/http","/config/inbounds/http.md"]],["v-802a842a","/config/inbounds/shadowsocks.html","Shadowsocks",["/config/inbounds/shadowsocks","/config/inbounds/shadowsocks.md"]],["v-29995cea","/config/inbounds/socks.html","Socks",["/config/inbounds/socks","/config/inbounds/socks.md"]],["v-2a1b3d72","/config/inbounds/trojan.html","Trojan",["/config/inbounds/trojan","/config/inbounds/trojan.md"]],["v-fb92e8aa","/config/inbounds/vless.html","VLESS",["/config/inbounds/vless","/config/inbounds/vless.md"]],["v-167afaac","/config/inbounds/vmess.html","VMess",["/config/inbounds/vmess","/config/inbounds/vmess.md"]],["v-749ad71a","/config/outbounds/blackhole.html","Blackhole",["/config/outbounds/blackhole","/config/outbounds/blackhole.md"]],["v-6d39b970","/config/outbounds/dns.html","DNS",["/config/outbounds/dns","/config/outbounds/dns.md"]],["v-d76e893a","/config/outbounds/freedom.html","Freedom",["/config/outbounds/freedom","/config/outbounds/freedom.md"]],["v-c6b4b59e","/config/outbounds/http.html","HTTP",["/config/outbounds/http","/config/outbounds/http.md"]],["v-7b293e4a","/config/outbounds/shadowsocks.html","Shadowsocks",["/config/outbounds/shadowsocks","/config/outbounds/shadowsocks.md"]],["v-15f5452a","/config/outbounds/socks.html","Socks",["/config/outbounds/socks","/config/outbounds/socks.md"]],["v-5797bdb3","/config/outbounds/trojan.html","Trojan",["/config/outbounds/trojan","/config/outbounds/trojan.md"]],["v-a60f016c","/config/outbounds/vless.html","VLESS",["/config/outbounds/vless","/config/outbounds/vless.md"]],["v-413cee4b","/config/outbounds/vmess.html","VMess",["/config/outbounds/vmess","/config/outbounds/vmess.md"]],["v-208ca3b9","/config/outbounds/wireguard.html","Wireguard",["/config/outbounds/wireguard","/config/outbounds/wireguard.md"]],["v-775db7b1","/config/transports/domainsocket.html","Domain Socket",["/config/transports/domainsocket","/config/transports/domainsocket.md"]],["v-2877542a","/config/transports/grpc.html","gRPC",["/config/transports/grpc","/config/transports/grpc.md"]],["v-03a28284","/config/transports/h2.html","HTTP/2",["/config/transports/h2","/config/transports/h2.md"]],["v-3167b1dd","/config/transports/mkcp.html","mKCP",["/config/transports/mkcp","/config/transports/mkcp.md"]],["v-8f08dbec","/config/transports/quic.html","QUIC",["/config/transports/quic","/config/transports/quic.md"]],["v-33b1b709","/config/transports/tcp.html","TCP",["/config/transports/tcp","/config/transports/tcp.md"]],["v-1ff57bba","/config/transports/websocket.html","WebSocket",["/config/transports/websocket","/config/transports/websocket.md"]],["v-6a9e8054","/development/intro/compile.html","编译文档",["/development/intro/compile","/development/intro/compile.md"]],["v-95e3eaea","/development/intro/design.html","设计目标",["/development/intro/design","/development/intro/design.md"]],["v-61e7eea6","/development/intro/guide.html","开发规范",["/development/intro/guide","/development/intro/guide.md"]],["v-6e6c37e6","/development/protocols/mkcp.html","mKCP 协议",["/development/protocols/mkcp","/development/protocols/mkcp.md"]],["v-13168a21","/development/protocols/muxcool.html","Mux.Cool 协议",["/development/protocols/muxcool","/development/protocols/muxcool.md"]],["v-5c48c82b","/development/protocols/vless.html","VLESS 协议",["/development/protocols/vless","/development/protocols/vless.md"]],["v-1ee591a8","/development/protocols/vmess.html","VMess 协议",["/development/protocols/vmess","/development/protocols/vmess.md"]],["v-3f09dcfa","/document/level-0/","小小白白话文",["/document/level-0/index.html","/document/level-0/README.md"]],["v-fb444906","/document/level-0/ch01-preface.html","【第 1 章】 小小白白话文",["/document/level-0/ch01-preface","/document/level-0/ch01-preface.md"]],["v-075f3ae5","/document/level-0/ch02-preparation.html","【第 2 章】原料准备篇",["/document/level-0/ch02-preparation","/document/level-0/ch02-preparation.md"]],["v-726d0633","/document/level-0/ch03-ssh.html","【第 3 章】远程登录篇",["/document/level-0/ch03-ssh","/document/level-0/ch03-ssh.md"]],["v-430c6ab8","/document/level-0/ch04-security.html","【第 4 章】安全防护篇",["/document/level-0/ch04-security","/document/level-0/ch04-security.md"]],["v-717c6376","/document/level-0/ch05-webpage.html","【第 5 章】网站建设篇",["/document/level-0/ch05-webpage","/document/level-0/ch05-webpage.md"]],["v-278039be","/document/level-0/ch06-certificates.html","【第 6 章】证书管理篇",["/document/level-0/ch06-certificates","/document/level-0/ch06-certificates.md"]],["v-a0c7f88e","/document/level-0/ch07-xray-server.html","【第 7 章】Xray 服务器篇",["/document/level-0/ch07-xray-server","/document/level-0/ch07-xray-server.md"]],["v-86586ca2","/document/level-0/ch08-xray-clients.html","【第 8 章】Xray 客户端篇",["/document/level-0/ch08-xray-clients","/document/level-0/ch08-xray-clients.md"]],["v-3eb62514","/document/level-0/ch09-appendix.html","【第 9 章】附录",["/document/level-0/ch09-appendix","/document/level-0/ch09-appendix.md"]],["v-3f09dcbc","/document/level-1/","入门技巧",["/document/level-1/index.html","/document/level-1/README.md"]],["v-b21a2a20","/document/level-1/fallbacks-lv1.html","回落 (fallbacks) 功能简析",["/document/level-1/fallbacks-lv1","/document/level-1/fallbacks-lv1.md"]],["v-da623318","/document/level-1/fallbacks-with-sni.html","SNI 回落",["/document/level-1/fallbacks-with-sni","/document/level-1/fallbacks-with-sni.md"]],["v-fdd722ac","/document/level-1/routing-lv1-part1.html","路由 (routing) 功能简析(上)",["/document/level-1/routing-lv1-part1","/document/level-1/routing-lv1-part1.md"]],["v-fa6d716e","/document/level-1/routing-lv1-part2.html","路由 (routing) 功能简析(下)",["/document/level-1/routing-lv1-part2","/document/level-1/routing-lv1-part2.md"]],["v-2f29e106","/document/level-1/work.html","Xray 的工作模式",["/document/level-1/work","/document/level-1/work.md"]],["v-3f09dc7e","/document/level-2/","进阶文档",["/document/level-2/index.html","/document/level-2/README.md"]],["v-1c17916e","/document/level-2/iptables_gid.html","GID 透明代理",["/document/level-2/iptables_gid","/document/level-2/iptables_gid.md"]],["v-a001cfa6","/document/level-2/nginx_or_haproxy_tls_tunnel.html","Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹",["/document/level-2/nginx_or_haproxy_tls_tunnel","/document/level-2/nginx_or_haproxy_tls_tunnel.md"]],["v-46333b48","/document/level-2/redirect.html","出站流量重定向",["/document/level-2/redirect","/document/level-2/redirect.md"]],["v-338bc63e","/document/level-2/tproxy.html","TProxy 透明代理",["/document/level-2/tproxy","/document/level-2/tproxy.md"]],["v-d68f7d58","/document/level-2/tproxy_ipv4_and_ipv6.html","TProxy 透明代理 (ipv4 and ipv6)",["/document/level-2/tproxy_ipv4_and_ipv6","/document/level-2/tproxy_ipv4_and_ipv6.md"]],["v-e533e2c6","/document/level-2/traffic_stats.html","流量统计",["/document/level-2/traffic_stats","/document/level-2/traffic_stats.md"]],["v-1e465ab0","/document/level-2/warp.html","通过 Cloudflare Warp 增强代理安全性",["/document/level-2/warp","/document/level-2/warp.md"]],["v-1080fb37","/en/about/news.html","大史记",["/en/about/news","/en/about/news.md"]],["v-317fc580","/en/config/","Configurations",["/en/config/index.html","/en/config/README.md"]],["v-45144c7f","/en/config/api.html","API Interface",["/en/config/api","/en/config/api.md"]],["v-23fbd2d0","/en/config/dns.html","Built-in DNS Server",["/en/config/dns","/en/config/dns.md"]],["v-2b7ec525","/en/config/fakedns.html","FakeDNS",["/en/config/fakedns","/en/config/fakedns.md"]],["v-5ab92300","/en/config/inbound.html","Inbound Proxy",["/en/config/inbound","/en/config/inbound.md"]],["v-f91d64d6","/en/config/log.html","Log Configuration",["/en/config/log","/en/config/log.md"]],["v-268cd669","/en/config/outbound.html","Outbound Proxies",["/en/config/outbound","/en/config/outbound.md"]],["v-4492d567","/en/config/policy.html","Local Policy",["/en/config/policy","/en/config/policy.md"]],["v-0d0e1e92","/en/config/reverse.html","Reverse Proxy",["/en/config/reverse","/en/config/reverse.md"]],["v-4bbe1d5a","/en/config/routing.html","Routing",["/en/config/routing","/en/config/routing.md"]],["v-16426d1a","/en/config/stats.html","Traffic Statistics",["/en/config/stats","/en/config/stats.md"]],["v-5de780d0","/en/config/transport.html","Transport Protocol",["/en/config/transport","/en/config/transport.md"]],["v-f88d343e","/en/development/","Development Guide",["/en/development/index.html","/en/development/README.md"]],["v-38d56a07","/en/document/","Quick Start",["/en/document/index.html","/en/document/README.md"]],["v-4d046016","/en/document/command.html","Command Parameters",["/en/document/command","/en/document/command.md"]],["v-22b35270","/en/document/config.html","Configure and Run",["/en/document/config","/en/document/config.md"]],["v-30bd7c12","/en/document/document.html","Contribute to Project X's Document",["/en/document/document","/en/document/document.md"]],["v-439608b6","/en/document/install.html","Download and Install",["/en/document/install","/en/document/install.md"]],["v-51a51d87","/document/level-2/transparent_proxy/transparent_proxy.html","透明代理入门",["/document/level-2/transparent_proxy/transparent_proxy","/document/level-2/transparent_proxy/transparent_proxy.md"]],["v-76b9a0f3","/en/config/features/browser_dialer.html","Browser Dialer",["/en/config/features/browser_dialer","/en/config/features/browser_dialer.md"]],["v-565dbfc4","/en/config/features/env.html","Environment Variables",["/en/config/features/env","/en/config/features/env.md"]],["v-0fbd1336","/en/config/features/fallback.html","Fallback",["/en/config/features/fallback","/en/config/features/fallback.md"]],["v-a0627812","/en/config/features/multiple.html","Multi-file configuration",["/en/config/features/multiple","/en/config/features/multiple.md"]],["v-d190d938","/en/config/features/xtls.html","Deep analysis of XTLS",["/en/config/features/xtls","/en/config/features/xtls.md"]],["v-72afc2d2","/en/config/inbounds/dokodemo.html","Dokodemo-Door",["/en/config/inbounds/dokodemo","/en/config/inbounds/dokodemo.md"]],["v-773d731c","/en/config/inbounds/http.html","HTTP",["/en/config/inbounds/http","/en/config/inbounds/http.md"]],["v-f555fc02","/en/config/inbounds/shadowsocks.html","Shadowsocks",["/en/config/inbounds/shadowsocks","/en/config/inbounds/shadowsocks.md"]],["v-e35196c2","/en/config/inbounds/socks.html","SOCKS",["/en/config/inbounds/socks","/en/config/inbounds/socks.md"]],["v-29188644","/en/config/inbounds/trojan.html","Trojan",["/en/config/inbounds/trojan","/en/config/inbounds/trojan.md"]],["v-255a6ebf","/en/config/inbounds/vless.html","VLESS",["/en/config/inbounds/vless","/en/config/inbounds/vless.md"]],["v-8cc24480","/en/config/inbounds/vmess.html","VMess",["/en/config/inbounds/vmess","/en/config/inbounds/vmess.md"]],["v-64e47ef4","/en/config/outbounds/blackhole.html","Blackhole",["/en/config/outbounds/blackhole","/en/config/outbounds/blackhole.md"]],["v-e979b848","/en/config/outbounds/dns.html","DNS",["/en/config/outbounds/dns","/en/config/outbounds/dns.md"]],["v-617f0fcf","/en/config/outbounds/freedom.html","Freedom",["/en/config/outbounds/freedom","/en/config/outbounds/freedom.md"]],["v-3fc98845","/en/config/outbounds/http.html","HTTP",["/en/config/outbounds/http","/en/config/outbounds/http.md"]],["v-63077cb6","/en/config/outbounds/shadowsocks.html","Shadowsocks",["/en/config/outbounds/shadowsocks","/en/config/outbounds/shadowsocks.md"]],["v-516476d4","/en/config/outbounds/socks.html","Socks",["/en/config/outbounds/socks","/en/config/outbounds/socks.md"]],["v-7d61a872","/en/config/outbounds/trojan.html","Trojan",["/en/config/outbounds/trojan","/en/config/outbounds/trojan.md"]],["v-6e50feb6","/en/config/outbounds/vless.html","VLESS",["/en/config/outbounds/vless","/en/config/outbounds/vless.md"]],["v-02956db7","/en/config/outbounds/vmess.html","VMess",["/en/config/outbounds/vmess","/en/config/outbounds/vmess.md"]],["v-797f8d25","/en/config/outbounds/wireguard.html","Wireguard",["/en/config/outbounds/wireguard","/en/config/outbounds/wireguard.md"]],["v-3eb3e9c6","/en/config/transports/domainsocket.html","Domain Socket",["/en/config/transports/domainsocket","/en/config/transports/domainsocket.md"]],["v-2c6058d4","/en/config/transports/grpc.html","gRPC",["/en/config/transports/grpc","/en/config/transports/grpc.md"]],["v-1c38292a","/en/config/transports/h2.html","HTTP/2",["/en/config/transports/h2","/en/config/transports/h2.md"]],["v-1a7f9d6e","/en/config/transports/mkcp.html","mKCP",["/en/config/transports/mkcp","/en/config/transports/mkcp.md"]],["v-79d41176","/en/config/transports/quic.html","QUIC",["/en/config/transports/quic","/en/config/transports/quic.md"]],["v-5254cbc6","/en/config/transports/tcp.html","TCP",["/en/config/transports/tcp","/en/config/transports/tcp.md"]],["v-9520f392","/en/config/transports/websocket.html","WebSocket",["/en/config/transports/websocket","/en/config/transports/websocket.md"]],["v-b7760e2c","/en/development/intro/compile.html","Compile the document",["/en/development/intro/compile","/en/development/intro/compile.md"]],["v-fb774212","/en/development/intro/design.html","Design Objectives",["/en/development/intro/design","/en/development/intro/design.md"]],["v-38c376c1","/en/development/intro/guide.html","Development Standards",["/en/development/intro/guide","/en/development/intro/guide.md"]],["v-21bccd79","/en/development/protocols/mkcp.html","mKCP Protocol",["/en/development/protocols/mkcp","/en/development/protocols/mkcp.md"]],["v-27001935","/en/development/protocols/muxcool.html","Mux.Cool Protocol",["/en/development/protocols/muxcool","/en/development/protocols/muxcool.md"]],["v-21b30c3f","/en/development/protocols/vless.html","VLESS Protocol",["/en/development/protocols/vless","/en/development/protocols/vless.md"]],["v-94110980","/en/development/protocols/vmess.html","VMess Protocol",["/en/development/protocols/vmess","/en/development/protocols/vmess.md"]],["v-789ba7ef","/en/document/level-0/","Plain and Simple Language",["/en/document/level-0/index.html","/en/document/level-0/README.md"]],["v-d3712ade","/en/document/level-0/ch01-preface.html","[Chapter 1] Simple and Plain Language",["/en/document/level-0/ch01-preface","/en/document/level-0/ch01-preface.md"]],["v-41f9c00e","/en/document/level-0/ch02-preparation.html","[Chapter 2] Preparation of Raw Materials",["/en/document/level-0/ch02-preparation","/en/document/level-0/ch02-preparation.md"]],["v-4c013f47","/en/document/level-0/ch03-ssh.html","[Chapter 3] Remote Login",["/en/document/level-0/ch03-ssh","/en/document/level-0/ch03-ssh.md"]],["v-a75683b8","/en/document/level-0/ch04-security.html","[Chapter 4] Security and Protection",["/en/document/level-0/ch04-security","/en/document/level-0/ch04-security.md"]],["v-f5341aec","/en/document/level-0/ch05-webpage.html","Chapter 5: Website Building",["/en/document/level-0/ch05-webpage","/en/document/level-0/ch05-webpage.md"]],["v-4458f72a","/en/document/level-0/ch06-certificates.html","[Chapter 6] Certificate Management",["/en/document/level-0/ch06-certificates","/en/document/level-0/ch06-certificates.md"]],["v-f1802e66","/en/document/level-0/ch07-xray-server.html","【第 7 章】Xray 服务器篇",["/en/document/level-0/ch07-xray-server","/en/document/level-0/ch07-xray-server.md"]],["v-4ca6f1ca","/en/document/level-0/ch08-xray-clients.html","【第 8 章】Xray 客户端篇",["/en/document/level-0/ch08-xray-clients","/en/document/level-0/ch08-xray-clients.md"]],["v-b0030f00","/en/document/level-0/ch09-appendix.html","【第 9 章】附录",["/en/document/level-0/ch09-appendix","/en/document/level-0/ch09-appendix.md"]],["v-789ba80e","/en/document/level-1/","Beginner's Tips",["/en/document/level-1/index.html","/en/document/level-1/README.md"]],["v-103b3e5c","/en/document/level-1/fallbacks-lv1.html","回落 (fallbacks) 功能简析",["/en/document/level-1/fallbacks-lv1","/en/document/level-1/fallbacks-lv1.md"]],["v-110dd688","/en/document/level-1/fallbacks-with-sni.html","SNI fallback",["/en/document/level-1/fallbacks-with-sni","/en/document/level-1/fallbacks-with-sni.md"]],["v-c425a7d4","/en/document/level-1/routing-lv1-part1.html","路由 (routing) 功能简析(上)",["/en/document/level-1/routing-lv1-part1","/en/document/level-1/routing-lv1-part1.md"]],["v-c0bbf696","/en/document/level-1/routing-lv1-part2.html","路由 (routing) 功能简析(下)",["/en/document/level-1/routing-lv1-part2","/en/document/level-1/routing-lv1-part2.md"]],["v-5b6477cc","/en/document/level-1/work.html","Xray 的工作模式",["/en/document/level-1/work","/en/document/level-1/work.md"]],["v-789ba82d","/en/document/level-2/","Advanced Documentation",["/en/document/level-2/index.html","/en/document/level-2/README.md"]],["v-05ddc65d","/en/document/level-2/iptables_gid.html","Transparent proxy via GID",["/en/document/level-2/iptables_gid","/en/document/level-2/iptables_gid.md"]],["v-1f3a890a","/en/document/level-2/nginx_tls_tunnel.html","Nginx_TLS隧道隐藏指纹",["/en/document/level-2/nginx_tls_tunnel","/en/document/level-2/nginx_tls_tunnel.md"]],["v-930ac920","/en/document/level-2/redirect.html","出站流量重定向",["/en/document/level-2/redirect","/en/document/level-2/redirect.md"]],["v-c579975c","/en/document/level-2/tproxy.html","TProxy 透明代理",["/en/document/level-2/tproxy","/en/document/level-2/tproxy.md"]],["v-7efb7c68","/en/document/level-2/tproxy_ipv4_and_ipv6.html","TProxy 透明代理 (ipv4 and ipv6)",["/en/document/level-2/tproxy_ipv4_and_ipv6","/en/document/level-2/tproxy_ipv4_and_ipv6.md"]],["v-12a33bee","/en/document/level-2/traffic_stats.html","流量统计",["/en/document/level-2/traffic_stats","/en/document/level-2/traffic_stats.md"]],["v-7d2b8478","/en/document/level-2/warp.html","Enhancing Proxy Security with Cloudflare Warp",["/en/document/level-2/warp","/en/document/level-2/warp.md"]],["v-7689d7f3","/en/document/level-2/transparent_proxy/transparent_proxy.html","透明代理入门",["/en/document/level-2/transparent_proxy/transparent_proxy","/en/document/level-2/transparent_proxy/transparent_proxy.md"]],["v-3706649a","/404.html","",["/404"]]].reduce(((e,[t,l,n,o])=>(e.push({name:t,path:l,component:As,meta:{title:n}},...o.map((e=>({path:e,redirect:l})))),e)),[{name:"404",path:"/:catchAll(.*)",component:As}]),dc=(e,t)=>{const l=It((()=>{return e=_s.value.locales,l=t.currentRoute.value.path,hs(e,l);var e,l})),n=It((()=>((e,t)=>s(s({},e),e.locales[t]))(_s.value,l.value))),o=It((()=>es.value.frontmatter)),i=It((()=>{return e=es.value,t=n.value,`${e.title?`${e.title} | `:""}${t.title}`;var e,t})),r=It((()=>((e,t,l)=>{const n=V(t.description)?t.description:l.description,o=[...R(t.head)?t.head:[],...l.head,["title",{},e],["meta",{name:"description",content:n}]];return is(o)})(i.value,o.value,n.value))),a=It((()=>es.value.lang||"en"));e.provide(fs,l),e.provide(ys,n),e.provide(ns,o),e.provide(ms,i),e.provide(ps,r),e.provide(vs,a),Object.defineProperties(e.config.globalProperties,{$frontmatter:{get:()=>o.value},$headTitle:{get:()=>i.value},$lang:{get:()=>a.value},$page:{get:()=>es.value},$routeLocale:{get:()=>l.value},$site:{get:()=>_s.value},$siteLocale:{get:()=>n.value},$withBase:{get:()=>Rs}})},uc=(...e)=>{const t=(vi=fi?vi:rn(mi),fi=!0,vi).createApp(...e),{mount:l}=t;return t.mount=e=>{const t=function(e){if(V(e)){return document.querySelector(e)}return e}(e);if(t)return l(t,!0,t instanceof SVGElement)},t},hc=function(e){const t=Gi(e=Mi(e)),l=function(e,t,l,n){let o=[],i=[],r=null;const s=({state:i})=>{const s=qi(e,location),a=l.value,c=t.value;let d=0;if(i){if(l.value=s,t.value=i,r&&r===a)return void(r=null);d=c?i.position-c.position:0}else n(s);o.forEach((e=>{e(l.value,a,{delta:d,type:Vi.pop,direction:d?d>0?Fi.forward:Fi.back:Fi.unknown})}))};function a(){const{history:e}=window;e.state&&e.replaceState(Oi({},e.state,{scroll:Bi()}),"")}return window.addEventListener("popstate",s),window.addEventListener("beforeunload",a),{pauseListeners:function(){r=l.value},listen:function(e){o.push(e);const t=()=>{const t=o.indexOf(e);t>-1&&o.splice(t,1)};return i.push(t),t},destroy:function(){for(const e of i)e();i=[],window.removeEventListener("popstate",s),window.removeEventListener("beforeunload",a)}}}(e,t.state,t.location,t.replace),n=Oi({location:"",base:e,go:function(e,t=!0){t||l.pauseListeners(),history.go(e)},createHref:zi.bind(null,e)},t,l);return Object.defineProperty(n,"location",{enumerable:!0,get:()=>t.location.value}),Object.defineProperty(n,"state",{enumerable:!0,get:()=>t.state.value}),n},pc=async()=>{const e=uc({name:"VuepressApp",setup(){js();for(const e of ac)e();return()=>[Vo($r),...Za.map((e=>Vo(e)))]}}),t=Wr({history:hc(ds(_s.value.base)),routes:cc,scrollBehavior:(e,t,l)=>l||(e.hash?{el:e.hash}:{top:0})});t.beforeResolve((async(e,t)=>{var l;e.path===t.path&&t!==Yi||([es.value]=await Promise.all([ls(e.name),null===(l=Qr[e.name])||void 0===l?void 0:l.__asyncLoader()]))})),dc(e,t),(e=>{e.component("ClientOnly",Gr),e.component("Content",ws),e.component("OutboundLink",Ts)})(e);for(const l of Ka)await l({app:e,router:t,siteData:_s});return e.use(t),{app:e,router:t}};pc().then((({app:e,router:t})=>{t.isReady().then((()=>{e.mount("#app")}))}));export{Rs as A,R as B,Hn as C,g as D,jt as E,pn as F,Ao as G,Kl as H,hi as I,qr as J,Ca as K,V as L,Js as M,Ks as N,fl as O,p as P,Na as Q,ts as R,oa as S,ei as T,cs as U,Vo as V,yl as W,la as X,oc as Y,ic as Z,rc as _,An as a,Rn as b,jn as c,pc as createVueApp,Sn as d,In as e,ol as f,ha as g,wt as h,Xr as i,kt as j,It as k,rs as l,ss as m,as as n,bn as o,Ln as p,zn as q,dn as r,Mn as s,_ as t,gs as u,Vn as v,Bt as w,bs as x,os as y,Es as z}; diff --git a/assets/arc.56fd4148.js b/assets/arc.56fd4148.js deleted file mode 100644 index b6731fa62..000000000 --- a/assets/arc.56fd4148.js +++ /dev/null @@ -1 +0,0 @@ -import{c as n,p as t}from"./constant.4f073c13.js";import{aq as a,ar as r,ao as c,as as e,at as o,au as u,av as i,aw as y,ax as l,ay as f,az as s,aA as p,aB as x}from"./mermaid.core.a66200b0.js";function h(n){return n.innerRadius}function v(n){return n.outerRadius}function g(n){return n.startAngle}function d(n){return n.endAngle}function m(n){return n&&n.padAngle}function T(n,t,a,c,e,o,u,i){var y=a-n,l=c-t,f=u-e,s=i-o,p=s*y-f*l;if(!(p*pD*D+E*E&&(w=B,z=P),{cx:w,cy:z,x01:-f,y01:-p,x11:w*(c/j-1),y11:z*(c/j-1)}}function R(){var s=h,R=v,j=n(0),b=null,q=g,w=d,z=m,B=null;function P(){var n,h,v=+s.apply(this,arguments),g=+R.apply(this,arguments),d=q.apply(this,arguments)-a,m=w.apply(this,arguments)-a,P=i(m-d),k=m>d;if(B||(B=n=t()),gr)if(P>c-r)B.moveTo(g*e(d),g*o(d)),B.arc(0,0,g,d,m,!k),v>r&&(B.moveTo(v*e(m),v*o(m)),B.arc(0,0,v,m,d,k));else{var C,D,E=d,F=m,G=d,H=m,I=P,J=P,K=z.apply(this,arguments)/2,L=K>r&&(b?+b.apply(this,arguments):l(v*v+g*g)),M=u(i(g-v)/2,+j.apply(this,arguments)),N=M,O=M;if(L>r){var Q=p(L/v*o(K)),S=p(L/g*o(K));(I-=2*Q)>r?(G+=Q*=k?1:-1,H-=Q):(I=0,G=H=(d+m)/2),(J-=2*S)>r?(E+=S*=k?1:-1,F-=S):(J=0,E=F=(d+m)/2)}var U=g*e(E),V=g*o(E),W=v*e(H),X=v*o(H);if(M>r){var Y,Z=g*e(F),$=g*o(F),_=v*e(G),nn=v*o(G);if(Pr?O>r?(C=A(_,nn,U,V,g,O,k),D=A(Z,$,W,X,g,O,k),B.moveTo(C.cx+C.x01,C.cy+C.y01),Or&&I>r?N>r?(C=A(W,X,Z,$,v,-N,k),D=A(U,V,_,nn,v,-N,k),B.lineTo(C.cx+C.x01,C.cy+C.y01),ND*D+E*E&&(z=P,B=b),{cx:z,cy:B,x01:-f,y01:-p,x11:z*(c/j-1),y11:B*(c/j-1)}}function R(){var s=h,R=v,j=n(0),q=null,w=g,z=d,B=m,P=null;function b(){var n,h,v=+s.apply(this,arguments),g=+R.apply(this,arguments),d=w.apply(this,arguments)-a,m=z.apply(this,arguments)-a,b=i(m-d),k=m>d;if(P||(P=n=t()),gr)if(b>c-r)P.moveTo(g*e(d),g*o(d)),P.arc(0,0,g,d,m,!k),v>r&&(P.moveTo(v*e(m),v*o(m)),P.arc(0,0,v,m,d,k));else{var C,D,E=d,F=m,G=d,H=m,I=b,J=b,K=B.apply(this,arguments)/2,L=K>r&&(q?+q.apply(this,arguments):l(v*v+g*g)),M=u(i(g-v)/2,+j.apply(this,arguments)),N=M,O=M;if(L>r){var Q=p(L/v*o(K)),S=p(L/g*o(K));(I-=2*Q)>r?(G+=Q*=k?1:-1,H-=Q):(I=0,G=H=(d+m)/2),(J-=2*S)>r?(E+=S*=k?1:-1,F-=S):(J=0,E=F=(d+m)/2)}var U=g*e(E),V=g*o(E),W=v*e(H),X=v*o(H);if(M>r){var Y,Z=g*e(F),$=g*o(F),_=v*e(G),nn=v*o(G);if(br?O>r?(C=A(_,nn,U,V,g,O,k),D=A(Z,$,W,X,g,O,k),P.moveTo(C.cx+C.x01,C.cy+C.y01),Or&&I>r?N>r?(C=A(W,X,Z,$,v,-N,k),D=A(U,V,_,nn,v,-N,k),P.lineTo(C.cx+C.x01,C.cy+C.y01),N OutboundConfigurationObject
{\n  "response": {\n    "type": "none"\n  }\n}\n
1
2
3
4
5

response: ResponseObject

配置黑洞的响应数据。

Blackhole 会在收到待转发数据之后,发送指定的响应数据,然后关闭连接,待转发的数据将被丢弃。 如不指定此项,Blackhole 将直接关闭连接。

ResponseObject

{\n  "type": "none"\n}\n
1
2
3

type: "http" | "none"

type"none"(默认值)时,Blackhole 将直接关闭连接。

type"http" 时,Blackhole 会发回一个简单的 HTTP 403 数据包,然后关闭连接。

',10);r.render=function(c,l){const r=n("RouterLink");return s(),e(p,null,[u,a("p",null,[i,o(r,{to:"/config/routing.html"},{default:t((()=>[d])),_:1}),b]),h],64)};export default r; +import{r as n,o as s,c as e,a,b as o,w as t,F as p,e as c,d as l}from"./app.48111a85.js";const r={},u=a("h1",{id:"blackhole",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#blackhole","aria-hidden":"true"},"#"),c(" Blackhole")],-1),i=c("Blackhole(黑洞)是一个出站数据协议,它会阻碍所有数据的出站,配合 "),d=c("路由配置"),b=c(" 一起使用,可以达到禁止访问某些网站的效果。"),h=l('

OutboundConfigurationObject

{\n  "response": {\n    "type": "none"\n  }\n}\n
1
2
3
4
5

response: ResponseObject

配置黑洞的响应数据。

Blackhole 会在收到待转发数据之后,发送指定的响应数据,然后关闭连接,待转发的数据将被丢弃。 如不指定此项,Blackhole 将直接关闭连接。

ResponseObject

{\n  "type": "none"\n}\n
1
2
3

type: "http" | "none"

type"none"(默认值)时,Blackhole 将直接关闭连接。

type"http" 时,Blackhole 会发回一个简单的 HTTP 403 数据包,然后关闭连接。

',10);r.render=function(c,l){const r=n("RouterLink");return s(),e(p,null,[u,a("p",null,[i,o(r,{to:"/config/routing.html"},{default:t((()=>[d])),_:1}),b]),h],64)};export default r; diff --git a/assets/blackhole.html.408848fe.js b/assets/blackhole.html.408848fe.js new file mode 100644 index 000000000..0c58e40d7 --- /dev/null +++ b/assets/blackhole.html.408848fe.js @@ -0,0 +1 @@ +import{r as e,o as n,c as s,a,b as o,w as t,F as c,e as p,d as l}from"./app.48111a85.js";const r={},i=a("h1",{id:"blackhole",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#blackhole","aria-hidden":"true"},"#"),p(" Blackhole")],-1),u=p("Blackhole is an outbound data protocol that blocks all outbound data. When used in conjunction with "),d=p("routing configurations"),b=p(", it can be used to block access to certain websites."),h=l('

OutboundConfigurationObject

{\n  "response": {\n    "type": "none"\n  }\n}\n
1
2
3
4
5

response: ResponseObject

Configures the response data for the blackhole.

After receiving the data to be forwarded, the blackhole will send the specified response data and then close the connection. The data to be forwarded will be discarded. If this field is not specified, the blackhole will simply close the connection.

ResponseObject

{\n  "type": "none"\n}\n
1
2
3

type: "http" | "none"

When type is set to "none" (default value), the blackhole will simply close the connection.

When type is set to "http", the blackhole will send a simple HTTP 403 packet as the response and then close the connection.

',10);r.render=function(p,l){const r=e("RouterLink");return n(),s(c,null,[i,a("p",null,[u,o(r,{to:"/en/config/routing.html"},{default:t((()=>[d])),_:1}),b]),h],64)};export default r; diff --git a/assets/blackhole.html.65d6a1c1.js b/assets/blackhole.html.65d6a1c1.js deleted file mode 100644 index 1055d946d..000000000 --- a/assets/blackhole.html.65d6a1c1.js +++ /dev/null @@ -1 +0,0 @@ -import{r as e,o as n,c as s,a as o,b as a,w as t,F as c,e as p,d as l}from"./app.755d843f.js";const r={},i=o("h1",{id:"blackhole",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#blackhole","aria-hidden":"true"},"#"),p(" Blackhole")],-1),u=p("Blackhole is an outbound data protocol that blocks all outbound data. When used in conjunction with "),d=p("routing configurations"),b=p(", it can be used to block access to certain websites."),h=l('

OutboundConfigurationObject

{\n  "response": {\n    "type": "none"\n  }\n}\n
1
2
3
4
5

response: ResponseObject

Configures the response data for the blackhole.

After receiving the data to be forwarded, the blackhole will send the specified response data and then close the connection. The data to be forwarded will be discarded. If this field is not specified, the blackhole will simply close the connection.

ResponseObject

{\n  "type": "none"\n}\n
1
2
3

type: "http" | "none"

When type is set to "none" (default value), the blackhole will simply close the connection.

When type is set to "http", the blackhole will send a simple HTTP 403 packet as the response and then close the connection.

',10);r.render=function(p,l){const r=e("RouterLink");return n(),s(c,null,[i,o("p",null,[u,a(r,{to:"/en/config/routing.html"},{default:t((()=>[d])),_:1}),b]),h],64)};export default r; diff --git a/assets/browser_dialer.html.621b9ea4.js b/assets/browser_dialer.html.3fd4af39.js similarity index 92% rename from assets/browser_dialer.html.621b9ea4.js rename to assets/browser_dialer.html.3fd4af39.js index ff9507376..4629dcb69 100644 --- a/assets/browser_dialer.html.621b9ea4.js +++ b/assets/browser_dialer.html.3fd4af39.js @@ -1 +1 @@ -import{r as e,o as a,c as o,b as n,a as r,F as i,e as t,d as s}from"./app.755d843f.js";const c={},l=r("h1",{id:"browser-dialer",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#browser-dialer","aria-hidden":"true"},"#"),t(" Browser Dialer")],-1),d=t(),h=r("h2",{id:"background",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#background","aria-hidden":"true"},"#"),t(" Background")],-1),u=t("Based on "),f={href:"https://github.com/v2ray/discussion/issues/754#issuecomment-647934994",target:"_blank",rel:"noopener noreferrer"},b=t("an idea from 2020"),p=t(", a concise "),w=r("code",null,"WSS Browser Dialer",-1),y=t(" has been implemented using native "),m=r("code",null,"JS",-1),g=t(", achieving true browser TLS fingerprints and behavioral characteristics. However, "),S=r("code",null,"WSS",-1),v=t(" still has significant issues with "),k=r("code",null,"ALPN",-1),x=t(", so the next step is to forward "),A=r("code",null,"HTTP/2",-1),T=t(" and "),X=r("code",null,"QUIC",-1),W=t(' through the browser."'),B=s('

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),R=r("li",null,[t("The server response header will contain the requested "),r("code",null,"Sec-WebSocket-Protocol"),t(", which also initially obfuscates the length characteristic of the WSS handshake response.")],-1),L=r("li",null,[t("The encoding used for early data for browsers is "),r("code",null,"base64.RawURLEncoding"),t(" instead of "),r("code",null,"StdEncoding"),t(", and the server has made it compatible.")],-1),P=t("In addition, due to "),E={href:"https://github.com/XTLS/Xray-core/pull/375",target:"_blank",rel:"noopener noreferrer"},I=t("Xray-core#375"),J=t(" recommendations for "),C=r("code",null,"?ed=2048",-1),j=t(", this PR also increased server "),D=r("code",null,"MaxHeaderBytes",-1),H=t(" by 4096. "),_=r("s",null,"(Although it seems like it would work without modification.)",-1),F={id:"configuration",tabindex:"-1"},N=r("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#",-1),O=t(" Configuration "),U=s("

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);c.render=function(t,s){const c=e("Badge"),q=e("OutboundLink");return a(),o(i,null,[l,n(c,{text:"BETA",type:"warning"}),d,n(c,{text:"v1.4.1+",type:"warning"}),h,r("p",null,[u,r("a",f,[b,n(q)]),p,w,y,m,g,S,v,k,x,A,T,X,W]),B,r("ul",null,[R,L,r("li",null,[P,r("a",E,[I,n(q)]),J,C,j,D,H,_])]),r("h2",F,[N,O,n(c,{text:"v1.4.1",type:"warning"})]),U],64)};export default c; +import{r as e,o as a,c as o,b as n,a as r,F as i,e as t,d as s}from"./app.48111a85.js";const c={},l=r("h1",{id:"browser-dialer",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#browser-dialer","aria-hidden":"true"},"#"),t(" Browser Dialer")],-1),d=t(),h=r("h2",{id:"background",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#background","aria-hidden":"true"},"#"),t(" Background")],-1),u=t("Based on "),b={href:"https://github.com/v2ray/discussion/issues/754#issuecomment-647934994",target:"_blank",rel:"noopener noreferrer"},f=t("an idea from 2020"),p=t(", a concise "),w=r("code",null,"WSS Browser Dialer",-1),y=t(" has been implemented using native "),m=r("code",null,"JS",-1),g=t(", achieving true browser TLS fingerprints and behavioral characteristics. However, "),S=r("code",null,"WSS",-1),v=t(" still has significant issues with "),k=r("code",null,"ALPN",-1),x=t(", so the next step is to forward "),A=r("code",null,"HTTP/2",-1),T=t(" and "),X=r("code",null,"QUIC",-1),W=t(' through the browser."'),B=s('

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),R=r("li",null,[t("The server response header will contain the requested "),r("code",null,"Sec-WebSocket-Protocol"),t(", which also initially obfuscates the length characteristic of the WSS handshake response.")],-1),L=r("li",null,[t("The encoding used for early data for browsers is "),r("code",null,"base64.RawURLEncoding"),t(" instead of "),r("code",null,"StdEncoding"),t(", and the server has made it compatible.")],-1),P=t("In addition, due to "),E={href:"https://github.com/XTLS/Xray-core/pull/375",target:"_blank",rel:"noopener noreferrer"},I=t("Xray-core#375"),J=t(" recommendations for "),C=r("code",null,"?ed=2048",-1),j=t(", this PR also increased server "),D=r("code",null,"MaxHeaderBytes",-1),H=t(" by 4096. "),_=r("s",null,"(Although it seems like it would work without modification.)",-1),F={id:"configuration",tabindex:"-1"},N=r("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#",-1),O=t(" Configuration "),U=s("

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);c.render=function(t,s){const c=e("Badge"),q=e("OutboundLink");return a(),o(i,null,[l,n(c,{text:"BETA",type:"warning"}),d,n(c,{text:"v1.4.1+",type:"warning"}),h,r("p",null,[u,r("a",b,[f,n(q)]),p,w,y,m,g,S,v,k,x,A,T,X,W]),B,r("ul",null,[R,L,r("li",null,[P,r("a",E,[I,n(q)]),J,C,j,D,H,_])]),r("h2",F,[N,O,n(c,{text:"v1.4.1",type:"warning"})]),U],64)};export default c; diff --git a/assets/browser_dialer.html.e175c84c.js b/assets/browser_dialer.html.605666d3.js similarity index 93% rename from assets/browser_dialer.html.e175c84c.js rename to assets/browser_dialer.html.605666d3.js index bc4ffec7e..fc62821de 100644 --- a/assets/browser_dialer.html.e175c84c.js +++ b/assets/browser_dialer.html.605666d3.js @@ -1 +1 @@ -import{r as e,o as a,c as r,b as l,a as o,F as n,e as d,d as i}from"./app.755d843f.js";const c={},t=o("h1",{id:"browser-dialer",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#browser-dialer","aria-hidden":"true"},"#"),d(" Browser Dialer")],-1),s=d(),u=o("h2",{id:"background",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#background","aria-hidden":"true"},"#"),d(" Background")],-1),h=d("基于 "),y={href:"https://github.com/v2ray/discussion/issues/754#issuecomment-647934994",target:"_blank",rel:"noopener noreferrer"},S=d("一年前的想法"),p=d(" ,利用原生 JS 实现了简洁的 WSS Browser Dialer,达到了真实浏览器的 TLS 指纹、行为特征。"),b=i('

不过 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),f=o("li",null,[d("服务端响应头会带有请求的 "),o("code",null,"Sec-WebSocket-Protocol"),d(",这也初步混淆了 WSS 握手响应的长度特征。")],-1),g=o("li",null,[d("用于浏览器的 early data 编码是 "),o("code",null,"base64.RawURLEncoding"),d(" 而不是 "),o("code",null,"StdEncoding"),d(",服务端做了兼容。")],-1),x=d("此外,由于 "),X={href:"https://github.com/XTLS/Xray-core/pull/375",target:"_blank",rel:"noopener noreferrer"},k=d("Xray-core#375"),w=d(" 推荐 "),R=o("code",null,"?ed=2048",-1),W=d(",这个 PR 顺便将服务端一处 "),m=o("code",null,"MaxHeaderBytes",-1),A=d(" 扩至了 4096。 "),B=o("s",null,"(虽然好像不改也没问题)",-1),L={id:"configuration",tabindex:"-1"},T=o("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#",-1),E=d(" Configuration "),J=i("

这是一个探索的过程,目前两边都是 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);c.render=function(d,i){const c=e("Badge"),P=e("OutboundLink");return a(),r(n,null,[t,l(c,{text:"BETA",type:"warning"}),s,l(c,{text:"v1.4.1+",type:"warning"}),u,o("p",null,[h,o("a",y,[S,l(P)]),p]),b,o("ul",null,[f,g,o("li",null,[x,o("a",X,[k,l(P)]),w,R,W,m,A,B])]),o("h2",L,[T,E,l(c,{text:"v1.4.1",type:"warning"})]),J],64)};export default c; +import{r as e,o as a,c as r,b as l,a as o,F as n,e as d,d as i}from"./app.48111a85.js";const c={},t=o("h1",{id:"browser-dialer",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#browser-dialer","aria-hidden":"true"},"#"),d(" Browser Dialer")],-1),s=d(),u=o("h2",{id:"background",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#background","aria-hidden":"true"},"#"),d(" Background")],-1),h=d("基于 "),y={href:"https://github.com/v2ray/discussion/issues/754#issuecomment-647934994",target:"_blank",rel:"noopener noreferrer"},S=d("一年前的想法"),p=d(" ,利用原生 JS 实现了简洁的 WSS Browser Dialer,达到了真实浏览器的 TLS 指纹、行为特征。"),b=i('

不过 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),g=o("li",null,[d("服务端响应头会带有请求的 "),o("code",null,"Sec-WebSocket-Protocol"),d(",这也初步混淆了 WSS 握手响应的长度特征。")],-1),f=o("li",null,[d("用于浏览器的 early data 编码是 "),o("code",null,"base64.RawURLEncoding"),d(" 而不是 "),o("code",null,"StdEncoding"),d(",服务端做了兼容。")],-1),x=d("此外,由于 "),X={href:"https://github.com/XTLS/Xray-core/pull/375",target:"_blank",rel:"noopener noreferrer"},k=d("Xray-core#375"),w=d(" 推荐 "),R=o("code",null,"?ed=2048",-1),W=d(",这个 PR 顺便将服务端一处 "),m=o("code",null,"MaxHeaderBytes",-1),A=d(" 扩至了 4096。 "),B=o("s",null,"(虽然好像不改也没问题)",-1),L={id:"configuration",tabindex:"-1"},T=o("a",{class:"header-anchor",href:"#configuration","aria-hidden":"true"},"#",-1),E=d(" Configuration "),J=i("

这是一个探索的过程,目前两边都是 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);c.render=function(d,i){const c=e("Badge"),P=e("OutboundLink");return a(),r(n,null,[t,l(c,{text:"BETA",type:"warning"}),s,l(c,{text:"v1.4.1+",type:"warning"}),u,o("p",null,[h,o("a",y,[S,l(P)]),p]),b,o("ul",null,[g,f,o("li",null,[x,o("a",X,[k,l(P)]),w,R,W,m,A,B])]),o("h2",L,[T,E,l(c,{text:"v1.4.1",type:"warning"})]),J],64)};export default c; diff --git a/assets/c4Diagram-4a1de0c4.bba81cd2.js b/assets/c4Diagram-4a1de0c4.1b52351d.js similarity index 99% rename from assets/c4Diagram-4a1de0c4.bba81cd2.js rename to assets/c4Diagram-4a1de0c4.1b52351d.js index 89df0c8c5..ec82caa18 100644 --- a/assets/c4Diagram-4a1de0c4.bba81cd2.js +++ b/assets/c4Diagram-4a1de0c4.1b52351d.js @@ -1 +1 @@ -import{s as t,g as e,a as i,b as n,c as a,d as s,m as r,e as l,f as o,h,l as d,i as p,j as u,w as y,k as f,n as b}from"./mermaid.core.a66200b0.js";import{d as g,g as _}from"./svgDrawCommon-f26cad39.9f4c1d32.js";var x=function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,6],i=[1,7],n=[1,8],a=[1,9],s=[1,16],r=[1,11],l=[1,12],o=[1,13],h=[1,14],d=[1,15],p=[1,27],u=[1,33],y=[1,34],f=[1,35],b=[1,36],g=[1,37],_=[1,72],x=[1,73],m=[1,74],E=[1,75],S=[1,76],A=[1,77],v=[1,78],C=[1,38],O=[1,39],k=[1,40],T=[1,41],w=[1,42],R=[1,43],D=[1,44],N=[1,45],P=[1,46],j=[1,47],M=[1,48],B=[1,49],L=[1,50],Y=[1,51],I=[1,52],U=[1,53],F=[1,54],X=[1,55],z=[1,56],Q=[1,57],W=[1,59],$=[1,60],q=[1,61],V=[1,62],G=[1,63],H=[1,64],K=[1,65],J=[1,66],Z=[1,67],tt=[1,68],et=[1,69],it=[24,52],nt=[24,44,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],at=[15,24,44,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],st=[1,94],rt=[1,95],lt=[1,96],ot=[1,97],ct=[15,24,52],ht=[7,8,9,10,18,22,25,26,27,28],dt=[15,24,43,52],pt=[15,24,43,52,86,87,89,90],ut=[15,43],yt=[44,46,47,48,49,50,51,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],ft={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,directive:6,direction_tb:7,direction_bt:8,direction_rl:9,direction_lr:10,graphConfig:11,openDirective:12,typeDirective:13,closeDirective:14,NEWLINE:15,":":16,argDirective:17,open_directive:18,type_directive:19,arg_directive:20,close_directive:21,C4_CONTEXT:22,statements:23,EOF:24,C4_CONTAINER:25,C4_COMPONENT:26,C4_DYNAMIC:27,C4_DEPLOYMENT:28,otherStatements:29,diagramStatements:30,otherStatement:31,title:32,accDescription:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,boundaryStatement:39,boundaryStartStatement:40,boundaryStopStatement:41,boundaryStart:42,LBRACE:43,ENTERPRISE_BOUNDARY:44,attributes:45,SYSTEM_BOUNDARY:46,BOUNDARY:47,CONTAINER_BOUNDARY:48,NODE:49,NODE_L:50,NODE_R:51,RBRACE:52,diagramStatement:53,PERSON:54,PERSON_EXT:55,SYSTEM:56,SYSTEM_DB:57,SYSTEM_QUEUE:58,SYSTEM_EXT:59,SYSTEM_EXT_DB:60,SYSTEM_EXT_QUEUE:61,CONTAINER:62,CONTAINER_DB:63,CONTAINER_QUEUE:64,CONTAINER_EXT:65,CONTAINER_EXT_DB:66,CONTAINER_EXT_QUEUE:67,COMPONENT:68,COMPONENT_DB:69,COMPONENT_QUEUE:70,COMPONENT_EXT:71,COMPONENT_EXT_DB:72,COMPONENT_EXT_QUEUE:73,REL:74,BIREL:75,REL_U:76,REL_D:77,REL_L:78,REL_R:79,REL_B:80,REL_INDEX:81,UPDATE_EL_STYLE:82,UPDATE_REL_STYLE:83,UPDATE_LAYOUT_CONFIG:84,attribute:85,STR:86,STR_KEY:87,STR_VALUE:88,ATTRIBUTE:89,ATTRIBUTE_EMPTY:90,$accept:0,$end:1},terminals_:{2:"error",7:"direction_tb",8:"direction_bt",9:"direction_rl",10:"direction_lr",15:"NEWLINE",16:":",18:"open_directive",19:"type_directive",20:"arg_directive",21:"close_directive",22:"C4_CONTEXT",24:"EOF",25:"C4_CONTAINER",26:"C4_COMPONENT",27:"C4_DYNAMIC",28:"C4_DEPLOYMENT",32:"title",33:"accDescription",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",43:"LBRACE",44:"ENTERPRISE_BOUNDARY",46:"SYSTEM_BOUNDARY",47:"BOUNDARY",48:"CONTAINER_BOUNDARY",49:"NODE",50:"NODE_L",51:"NODE_R",52:"RBRACE",54:"PERSON",55:"PERSON_EXT",56:"SYSTEM",57:"SYSTEM_DB",58:"SYSTEM_QUEUE",59:"SYSTEM_EXT",60:"SYSTEM_EXT_DB",61:"SYSTEM_EXT_QUEUE",62:"CONTAINER",63:"CONTAINER_DB",64:"CONTAINER_QUEUE",65:"CONTAINER_EXT",66:"CONTAINER_EXT_DB",67:"CONTAINER_EXT_QUEUE",68:"COMPONENT",69:"COMPONENT_DB",70:"COMPONENT_QUEUE",71:"COMPONENT_EXT",72:"COMPONENT_EXT_DB",73:"COMPONENT_EXT_QUEUE",74:"REL",75:"BIREL",76:"REL_U",77:"REL_D",78:"REL_L",79:"REL_R",80:"REL_B",81:"REL_INDEX",82:"UPDATE_EL_STYLE",83:"UPDATE_REL_STYLE",84:"UPDATE_LAYOUT_CONFIG",86:"STR",87:"STR_KEY",88:"STR_VALUE",89:"ATTRIBUTE",90:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[3,2],[5,1],[5,1],[5,1],[5,1],[4,1],[6,4],[6,6],[12,1],[13,1],[17,1],[14,1],[11,4],[11,4],[11,4],[11,4],[11,4],[23,1],[23,1],[23,2],[29,1],[29,2],[29,3],[31,1],[31,1],[31,2],[31,2],[31,1],[39,3],[40,3],[40,3],[40,4],[42,2],[42,2],[42,2],[42,2],[42,2],[42,2],[42,2],[41,1],[30,1],[30,2],[30,3],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,1],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[45,1],[45,2],[85,1],[85,2],[85,1],[85,1]],performAction:function(t,e,i,n,a,s,r){var l=s.length-1;switch(a){case 4:n.setDirection("TB");break;case 5:n.setDirection("BT");break;case 6:n.setDirection("RL");break;case 7:n.setDirection("LR");break;case 11:n.parseDirective("%%{","open_directive");break;case 12:break;case 13:s[l]=s[l].trim().replace(/'/g,'"'),n.parseDirective(s[l],"arg_directive");break;case 14:n.parseDirective("}%%","close_directive","c4Context");break;case 15:case 16:case 17:case 18:case 19:n.setC4Type(s[l-3]);break;case 26:n.setTitle(s[l].substring(6)),this.$=s[l].substring(6);break;case 27:n.setAccDescription(s[l].substring(15)),this.$=s[l].substring(15);break;case 28:this.$=s[l].trim(),n.setTitle(this.$);break;case 29:case 30:this.$=s[l].trim(),n.setAccDescription(this.$);break;case 35:case 36:s[l].splice(2,0,"ENTERPRISE"),n.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 37:n.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 38:s[l].splice(2,0,"CONTAINER"),n.addContainerBoundary(...s[l]),this.$=s[l];break;case 39:n.addDeploymentNode("node",...s[l]),this.$=s[l];break;case 40:n.addDeploymentNode("nodeL",...s[l]),this.$=s[l];break;case 41:n.addDeploymentNode("nodeR",...s[l]),this.$=s[l];break;case 42:n.popBoundaryParseStack();break;case 46:n.addPersonOrSystem("person",...s[l]),this.$=s[l];break;case 47:n.addPersonOrSystem("external_person",...s[l]),this.$=s[l];break;case 48:n.addPersonOrSystem("system",...s[l]),this.$=s[l];break;case 49:n.addPersonOrSystem("system_db",...s[l]),this.$=s[l];break;case 50:n.addPersonOrSystem("system_queue",...s[l]),this.$=s[l];break;case 51:n.addPersonOrSystem("external_system",...s[l]),this.$=s[l];break;case 52:n.addPersonOrSystem("external_system_db",...s[l]),this.$=s[l];break;case 53:n.addPersonOrSystem("external_system_queue",...s[l]),this.$=s[l];break;case 54:n.addContainer("container",...s[l]),this.$=s[l];break;case 55:n.addContainer("container_db",...s[l]),this.$=s[l];break;case 56:n.addContainer("container_queue",...s[l]),this.$=s[l];break;case 57:n.addContainer("external_container",...s[l]),this.$=s[l];break;case 58:n.addContainer("external_container_db",...s[l]),this.$=s[l];break;case 59:n.addContainer("external_container_queue",...s[l]),this.$=s[l];break;case 60:n.addComponent("component",...s[l]),this.$=s[l];break;case 61:n.addComponent("component_db",...s[l]),this.$=s[l];break;case 62:n.addComponent("component_queue",...s[l]),this.$=s[l];break;case 63:n.addComponent("external_component",...s[l]),this.$=s[l];break;case 64:n.addComponent("external_component_db",...s[l]),this.$=s[l];break;case 65:n.addComponent("external_component_queue",...s[l]),this.$=s[l];break;case 67:n.addRel("rel",...s[l]),this.$=s[l];break;case 68:n.addRel("birel",...s[l]),this.$=s[l];break;case 69:n.addRel("rel_u",...s[l]),this.$=s[l];break;case 70:n.addRel("rel_d",...s[l]),this.$=s[l];break;case 71:n.addRel("rel_l",...s[l]),this.$=s[l];break;case 72:n.addRel("rel_r",...s[l]),this.$=s[l];break;case 73:n.addRel("rel_b",...s[l]),this.$=s[l];break;case 74:s[l].splice(0,1),n.addRel("rel",...s[l]),this.$=s[l];break;case 75:n.updateElStyle("update_el_style",...s[l]),this.$=s[l];break;case 76:n.updateRelStyle("update_rel_style",...s[l]),this.$=s[l];break;case 77:n.updateLayoutConfig("update_layout_config",...s[l]),this.$=s[l];break;case 78:this.$=[s[l]];break;case 79:s[l].unshift(s[l-1]),this.$=s[l];break;case 80:case 82:this.$=s[l].trim();break;case 81:let t={};t[s[l-1].trim()]=s[l].trim(),this.$=t;break;case 83:this.$=""}},table:[{3:1,4:2,5:3,6:4,7:e,8:i,9:n,10:a,11:5,12:10,18:s,22:r,25:l,26:o,27:h,28:d},{1:[3]},{1:[2,1]},{1:[2,2]},{3:17,4:2,5:3,6:4,7:e,8:i,9:n,10:a,11:5,12:10,18:s,22:r,25:l,26:o,27:h,28:d},{1:[2,8]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{1:[2,7]},{13:18,19:[1,19]},{15:[1,20]},{15:[1,21]},{15:[1,22]},{15:[1,23]},{15:[1,24]},{19:[2,11]},{1:[2,3]},{14:25,16:[1,26],21:p},t([16,21],[2,12]),{23:28,29:29,30:30,31:31,32:u,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:79,29:29,30:30,31:31,32:u,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:80,29:29,30:30,31:31,32:u,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:81,29:29,30:30,31:31,32:u,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:82,29:29,30:30,31:31,32:u,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{15:[1,83]},{17:84,20:[1,85]},{15:[2,14]},{24:[1,86]},t(it,[2,20],{53:32,39:58,40:70,42:71,30:87,44:_,46:x,47:m,48:E,49:S,50:A,51:v,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et}),t(it,[2,21]),t(nt,[2,23],{15:[1,88]}),t(it,[2,43],{15:[1,89]}),t(at,[2,26]),t(at,[2,27]),{35:[1,90]},{37:[1,91]},t(at,[2,30]),{45:92,85:93,86:st,87:rt,89:lt,90:ot},{45:98,85:93,86:st,87:rt,89:lt,90:ot},{45:99,85:93,86:st,87:rt,89:lt,90:ot},{45:100,85:93,86:st,87:rt,89:lt,90:ot},{45:101,85:93,86:st,87:rt,89:lt,90:ot},{45:102,85:93,86:st,87:rt,89:lt,90:ot},{45:103,85:93,86:st,87:rt,89:lt,90:ot},{45:104,85:93,86:st,87:rt,89:lt,90:ot},{45:105,85:93,86:st,87:rt,89:lt,90:ot},{45:106,85:93,86:st,87:rt,89:lt,90:ot},{45:107,85:93,86:st,87:rt,89:lt,90:ot},{45:108,85:93,86:st,87:rt,89:lt,90:ot},{45:109,85:93,86:st,87:rt,89:lt,90:ot},{45:110,85:93,86:st,87:rt,89:lt,90:ot},{45:111,85:93,86:st,87:rt,89:lt,90:ot},{45:112,85:93,86:st,87:rt,89:lt,90:ot},{45:113,85:93,86:st,87:rt,89:lt,90:ot},{45:114,85:93,86:st,87:rt,89:lt,90:ot},{45:115,85:93,86:st,87:rt,89:lt,90:ot},{45:116,85:93,86:st,87:rt,89:lt,90:ot},t(ct,[2,66]),{45:117,85:93,86:st,87:rt,89:lt,90:ot},{45:118,85:93,86:st,87:rt,89:lt,90:ot},{45:119,85:93,86:st,87:rt,89:lt,90:ot},{45:120,85:93,86:st,87:rt,89:lt,90:ot},{45:121,85:93,86:st,87:rt,89:lt,90:ot},{45:122,85:93,86:st,87:rt,89:lt,90:ot},{45:123,85:93,86:st,87:rt,89:lt,90:ot},{45:124,85:93,86:st,87:rt,89:lt,90:ot},{45:125,85:93,86:st,87:rt,89:lt,90:ot},{45:126,85:93,86:st,87:rt,89:lt,90:ot},{45:127,85:93,86:st,87:rt,89:lt,90:ot},{30:128,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{15:[1,130],43:[1,129]},{45:131,85:93,86:st,87:rt,89:lt,90:ot},{45:132,85:93,86:st,87:rt,89:lt,90:ot},{45:133,85:93,86:st,87:rt,89:lt,90:ot},{45:134,85:93,86:st,87:rt,89:lt,90:ot},{45:135,85:93,86:st,87:rt,89:lt,90:ot},{45:136,85:93,86:st,87:rt,89:lt,90:ot},{45:137,85:93,86:st,87:rt,89:lt,90:ot},{24:[1,138]},{24:[1,139]},{24:[1,140]},{24:[1,141]},t(ht,[2,9]),{14:142,21:p},{21:[2,13]},{1:[2,15]},t(it,[2,22]),t(nt,[2,24],{31:31,29:143,32:u,33:y,34:f,36:b,38:g}),t(it,[2,44],{29:29,30:30,31:31,53:32,39:58,40:70,42:71,23:144,32:u,33:y,34:f,36:b,38:g,44:_,46:x,47:m,48:E,49:S,50:A,51:v,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et}),t(at,[2,28]),t(at,[2,29]),t(ct,[2,46]),t(dt,[2,78],{85:93,45:145,86:st,87:rt,89:lt,90:ot}),t(pt,[2,80]),{88:[1,146]},t(pt,[2,82]),t(pt,[2,83]),t(ct,[2,47]),t(ct,[2,48]),t(ct,[2,49]),t(ct,[2,50]),t(ct,[2,51]),t(ct,[2,52]),t(ct,[2,53]),t(ct,[2,54]),t(ct,[2,55]),t(ct,[2,56]),t(ct,[2,57]),t(ct,[2,58]),t(ct,[2,59]),t(ct,[2,60]),t(ct,[2,61]),t(ct,[2,62]),t(ct,[2,63]),t(ct,[2,64]),t(ct,[2,65]),t(ct,[2,67]),t(ct,[2,68]),t(ct,[2,69]),t(ct,[2,70]),t(ct,[2,71]),t(ct,[2,72]),t(ct,[2,73]),t(ct,[2,74]),t(ct,[2,75]),t(ct,[2,76]),t(ct,[2,77]),{41:147,52:[1,148]},{15:[1,149]},{43:[1,150]},t(ut,[2,35]),t(ut,[2,36]),t(ut,[2,37]),t(ut,[2,38]),t(ut,[2,39]),t(ut,[2,40]),t(ut,[2,41]),{1:[2,16]},{1:[2,17]},{1:[2,18]},{1:[2,19]},{15:[1,151]},t(nt,[2,25]),t(it,[2,45]),t(dt,[2,79]),t(pt,[2,81]),t(ct,[2,31]),t(ct,[2,42]),t(yt,[2,32]),t(yt,[2,33],{15:[1,152]}),t(ht,[2,10]),t(yt,[2,34])],defaultActions:{2:[2,1],3:[2,2],5:[2,8],6:[2,4],7:[2,5],8:[2,6],9:[2,7],16:[2,11],17:[2,3],27:[2,14],85:[2,13],86:[2,15],138:[2,16],139:[2,17],140:[2,18],141:[2,19]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],n=[],a=[null],s=[],r=this.table,l="",o=0,c=0,h=2,d=1,p=s.slice.call(arguments,1),u=Object.create(this.lexer),y={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(y.yy[f]=this.yy[f]);u.setInput(t,y.yy),y.yy.lexer=u,y.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var b=u.yylloc;s.push(b);var g=u.options&&u.options.ranges;function _(){var t;return"number"!=typeof(t=n.pop()||u.lex()||d)&&(t instanceof Array&&(t=(n=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,m,E,S,A,v,C,O,k={};;){if(m=i[i.length-1],this.defaultActions[m]?E=this.defaultActions[m]:(null==x&&(x=_()),E=r[m]&&r[m][x]),void 0===E||!E.length||!E[0]){var T="";for(A in O=[],r[m])this.terminals_[A]&&A>h&&O.push("'"+this.terminals_[A]+"'");T=u.showPosition?"Parse error on line "+(o+1)+":\n"+u.showPosition()+"\nExpecting "+O.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(o+1)+": Unexpected "+(x==d?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(T,{text:u.match,token:this.terminals_[x]||x,line:u.yylineno,loc:b,expected:O})}if(E[0]instanceof Array&&E.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+x);switch(E[0]){case 1:i.push(x),a.push(u.yytext),s.push(u.yylloc),i.push(E[1]),x=null,c=u.yyleng,l=u.yytext,o=u.yylineno,b=u.yylloc;break;case 2:if(v=this.productions_[E[1]][1],k.$=a[a.length-v],k._$={first_line:s[s.length-(v||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(v||1)].first_column,last_column:s[s.length-1].last_column},g&&(k._$.range=[s[s.length-(v||1)].range[0],s[s.length-1].range[1]]),void 0!==(S=this.performAction.apply(k,[l,c,o,y.yy,E[1],a,s].concat(p))))return S;v&&(i=i.slice(0,-1*v*2),a=a.slice(0,-1*v),s=s.slice(0,-1*v)),i.push(this.productions_[E[1]][0]),a.push(k.$),s.push(k._$),C=r[i[i.length-2]][i[i.length-1]],i.push(C);break;case 3:return!0}}return!0}},bt={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,i=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 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),i.length-1&&(this.yylineno-=i.length-1);var a=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===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var i,n,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in a)this[s]=a[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),s=0;se[0].length)){if(e=i,n=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,a[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,i,n){switch(i){case 0:return this.begin("open_directive"),18;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 10;case 5:return this.begin("type_directive"),19;case 6:return this.popState(),this.begin("arg_directive"),16;case 7:return this.popState(),this.popState(),21;case 8:return 20;case 9:return 32;case 10:return 33;case 11:return this.begin("acc_title"),34;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),36;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:break;case 19:c;break;case 20:return 15;case 21:break;case 22:return 22;case 23:return 25;case 24:return 26;case 25:return 27;case 26:return 28;case 27:return this.begin("person_ext"),55;case 28:return this.begin("person"),54;case 29:return this.begin("system_ext_queue"),61;case 30:return this.begin("system_ext_db"),60;case 31:return this.begin("system_ext"),59;case 32:return this.begin("system_queue"),58;case 33:return this.begin("system_db"),57;case 34:return this.begin("system"),56;case 35:return this.begin("boundary"),47;case 36:return this.begin("enterprise_boundary"),44;case 37:return this.begin("system_boundary"),46;case 38:return this.begin("container_ext_queue"),67;case 39:return this.begin("container_ext_db"),66;case 40:return this.begin("container_ext"),65;case 41:return this.begin("container_queue"),64;case 42:return this.begin("container_db"),63;case 43:return this.begin("container"),62;case 44:return this.begin("container_boundary"),48;case 45:return this.begin("component_ext_queue"),73;case 46:return this.begin("component_ext_db"),72;case 47:return this.begin("component_ext"),71;case 48:return this.begin("component_queue"),70;case 49:return this.begin("component_db"),69;case 50:return this.begin("component"),68;case 51:case 52:return this.begin("node"),49;case 53:return this.begin("node_l"),50;case 54:return this.begin("node_r"),51;case 55:return this.begin("rel"),74;case 56:return this.begin("birel"),75;case 57:case 58:return this.begin("rel_u"),76;case 59:case 60:return this.begin("rel_d"),77;case 61:case 62:return this.begin("rel_l"),78;case 63:case 64:return this.begin("rel_r"),79;case 65:return this.begin("rel_b"),80;case 66:return this.begin("rel_index"),81;case 67:return this.begin("update_el_style"),82;case 68:return this.begin("update_rel_style"),83;case 69:return this.begin("update_layout_config"),84;case 70:return"EOF_IN_STRUCT";case 71:return this.begin("attribute"),"ATTRIBUTE_EMPTY";case 72:this.begin("attribute");break;case 73:this.popState(),this.popState();break;case 74:return 90;case 75:break;case 76:return 90;case 77:this.begin("string");break;case 78:this.popState();break;case 79:return"STR";case 80:this.begin("string_kv");break;case 81:return this.begin("string_kv_key"),"STR_KEY";case 82:this.popState(),this.begin("string_kv_value");break;case 83:return"STR_VALUE";case 84:this.popState(),this.popState();break;case 85:return"STR";case 86:return"LBRACE";case 87:return"RBRACE";case 88:return"SPACE";case 89:return"EOL";case 90:return 24}},rules:[/^(?:%%\{)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[16,17],inclusive:!1},acc_descr:{rules:[14],inclusive:!1},acc_title:{rules:[12],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[7,8],inclusive:!1},type_directive:{rules:[6,7],inclusive:!1},open_directive:{rules:[5],inclusive:!1},string_kv_value:{rules:[83,84],inclusive:!1},string_kv_key:{rules:[82],inclusive:!1},string_kv:{rules:[81],inclusive:!1},string:{rules:[78,79],inclusive:!1},attribute:{rules:[73,74,75,76,77,80,85],inclusive:!1},update_layout_config:{rules:[70,71,72,73],inclusive:!1},update_rel_style:{rules:[70,71,72,73],inclusive:!1},update_el_style:{rules:[70,71,72,73],inclusive:!1},rel_b:{rules:[70,71,72,73],inclusive:!1},rel_r:{rules:[70,71,72,73],inclusive:!1},rel_l:{rules:[70,71,72,73],inclusive:!1},rel_d:{rules:[70,71,72,73],inclusive:!1},rel_u:{rules:[70,71,72,73],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[70,71,72,73],inclusive:!1},node_r:{rules:[70,71,72,73],inclusive:!1},node_l:{rules:[70,71,72,73],inclusive:!1},node:{rules:[70,71,72,73],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[70,71,72,73],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[70,71,72,73],inclusive:!1},component_ext:{rules:[70,71,72,73],inclusive:!1},component_queue:{rules:[70,71,72,73],inclusive:!1},component_db:{rules:[70,71,72,73],inclusive:!1},component:{rules:[70,71,72,73],inclusive:!1},container_boundary:{rules:[70,71,72,73],inclusive:!1},container_ext_queue:{rules:[],inclusive:!1},container_ext_db:{rules:[70,71,72,73],inclusive:!1},container_ext:{rules:[70,71,72,73],inclusive:!1},container_queue:{rules:[70,71,72,73],inclusive:!1},container_db:{rules:[70,71,72,73],inclusive:!1},container:{rules:[70,71,72,73],inclusive:!1},birel:{rules:[70,71,72,73],inclusive:!1},system_boundary:{rules:[70,71,72,73],inclusive:!1},enterprise_boundary:{rules:[70,71,72,73],inclusive:!1},boundary:{rules:[70,71,72,73],inclusive:!1},system_ext_queue:{rules:[70,71,72,73],inclusive:!1},system_ext_db:{rules:[70,71,72,73],inclusive:!1},system_ext:{rules:[70,71,72,73],inclusive:!1},system_queue:{rules:[70,71,72,73],inclusive:!1},system_db:{rules:[70,71,72,73],inclusive:!1},system:{rules:[70,71,72,73],inclusive:!1},person_ext:{rules:[70,71,72,73],inclusive:!1},person:{rules:[70,71,72,73],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,9,10,11,13,15,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,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,86,87,88,89,90],inclusive:!0}}};function gt(){this.yy={}}return ft.lexer=bt,gt.prototype=ft,ft.Parser=gt,new gt}();x.parser=x;const m=x;let E=[],S=[""],A="global",v="",C=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],O=[],k="",T=!1,w=4,R=2;var D;const N=function(t){return null==t?E:E.filter((e=>e.parentBoundary===t))},P=function(){return T},j={addPersonOrSystem:function(t,e,i,n,a,s,r){if(null===e||null===i)return;let l={};const o=E.find((t=>t.alias===e));if(o&&e===o.alias?l=o:(l.alias=e,E.push(l)),l.label=null==i?{text:""}:{text:i},null==n)l.descr={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];l[t]={text:e}}else l.descr={text:n};if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]=e}else l.sprite=a;if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=e}else l.tags=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=e}else l.link=r;l.typeC4Shape={text:t},l.parentBoundary=A,l.wrap=P()},addPersonOrSystemBoundary:function(t,e,i,n,a){if(null===t||null===e)return;let s={};const r=C.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,C.push(s)),s.label=null==e?{text:""}:{text:e},null==i)s.type={text:"system"};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]={text:e}}else s.type={text:i};if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]=e}else s.tags=n;if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.link=a;s.parentBoundary=A,s.wrap=P(),v=A,A=t,S.push(v)},addContainer:function(t,e,i,n,a,s,r,l){if(null===e||null===i)return;let o={};const c=E.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,E.push(o)),o.label=null==i?{text:""}:{text:i},null==n)o.techn={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.techn={text:n};if(null==a)o.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.descr={text:a};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=P(),o.typeC4Shape={text:t},o.parentBoundary=A},addContainerBoundary:function(t,e,i,n,a){if(null===t||null===e)return;let s={};const r=C.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,C.push(s)),s.label=null==e?{text:""}:{text:e},null==i)s.type={text:"container"};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]={text:e}}else s.type={text:i};if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]=e}else s.tags=n;if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.link=a;s.parentBoundary=A,s.wrap=P(),v=A,A=t,S.push(v)},addComponent:function(t,e,i,n,a,s,r,l){if(null===e||null===i)return;let o={};const c=E.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,E.push(o)),o.label=null==i?{text:""}:{text:i},null==n)o.techn={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.techn={text:n};if(null==a)o.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.descr={text:a};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=P(),o.typeC4Shape={text:t},o.parentBoundary=A},addDeploymentNode:function(t,e,i,n,a,s,r,l){if(null===e||null===i)return;let o={};const c=C.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,C.push(o)),o.label=null==i?{text:""}:{text:i},null==n)o.type={text:"node"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.type={text:n};if(null==a)o.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.descr={text:a};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.nodeType=t,o.parentBoundary=A,o.wrap=P(),v=A,A=e,S.push(v)},popBoundaryParseStack:function(){A=v,S.pop(),v=S.pop(),S.push(v)},addRel:function(t,e,i,n,a,s,r,l,o){if(null==t||null==e||null==i||null==n)return;let c={};const h=O.find((t=>t.from===e&&t.to===i));if(h?c=h:O.push(c),c.type=t,c.from=e,c.to=i,c.label={text:n},null==a)c.techn={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];c[t]={text:e}}else c.techn={text:a};if(null==s)c.descr={text:""};else if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]={text:e}}else c.descr={text:s};if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]=e}else c.sprite=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];c[t]=e}else c.tags=l;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.wrap=P()},updateElStyle:function(t,e,i,n,a,s,r,l,o,c,h){let d=E.find((t=>t.alias===e));if(void 0!==d||(d=C.find((t=>t.alias===e)),void 0!==d)){if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];d[t]=e}else d.bgColor=i;if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];d[t]=e}else d.fontColor=n;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];d[t]=e}else d.borderColor=a;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];d[t]=e}else d.shadowing=s;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];d[t]=e}else d.shape=r;if(null!=l)if("object"==typeof l){let[t,e]=Object.entries(l)[0];d[t]=e}else d.sprite=l;if(null!=o)if("object"==typeof o){let[t,e]=Object.entries(o)[0];d[t]=e}else d.techn=o;if(null!=c)if("object"==typeof c){let[t,e]=Object.entries(c)[0];d[t]=e}else d.legendText=c;if(null!=h)if("object"==typeof h){let[t,e]=Object.entries(h)[0];d[t]=e}else d.legendSprite=h}},updateRelStyle:function(t,e,i,n,a,s,r){const l=O.find((t=>t.from===e&&t.to===i));if(void 0!==l){if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];l[t]=e}else l.textColor=n;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]=e}else l.lineColor=a;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=parseInt(e)}else l.offsetX=parseInt(s);if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=parseInt(e)}else l.offsetY=parseInt(r)}},updateLayoutConfig:function(t,e,i){let n=w,a=R;if("object"==typeof e){const t=Object.values(e)[0];n=parseInt(t)}else n=parseInt(e);if("object"==typeof i){const t=Object.values(i)[0];a=parseInt(t)}else a=parseInt(i);n>=1&&(w=n),a>=1&&(R=a)},autoWrap:P,setWrap:function(t){T=t},getC4ShapeArray:N,getC4Shape:function(t){return E.find((e=>e.alias===t))},getC4ShapeKeys:function(t){return Object.keys(N(t))},getBoundarys:function(t){return null==t?C:C.filter((e=>e.parentBoundary===t))},getCurrentBoundaryParse:function(){return A},getParentBoundaryParse:function(){return v},getRels:function(){return O},getTitle:function(){return k},getC4Type:function(){return D},getC4ShapeInRow:function(){return w},getC4BoundaryInRow:function(){return R},setAccTitle:t,getAccTitle:e,getAccDescription:i,setAccDescription:n,parseDirective:function(t,e,i){r.parseDirective(this,t,e,i)},getConfig:()=>a().c4,clear:function(){E=[],C=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],v="",A="global",S=[""],O=[],S=[""],k="",T=!1,w=4,R=2},LINETYPE:{SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},setTitle:function(t){let e=s(t,a());k=e},setC4Type:function(t){let e=s(t,a());D=e}},M=function(t,e){return g(t,e)},B=function(t,e,i,n,a,s){const r=t.append("image");r.attr("width",e),r.attr("height",i),r.attr("x",n),r.attr("y",a);let l=s.startsWith("data:image/png;base64")?s:b(s);r.attr("xlink:href",l)},L=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),Y=function(){function t(t,e,i,a,s,r,l){n(e.append("text").attr("x",i+s/2).attr("y",a+r/2+5).style("text-anchor","middle").text(t),l)}function e(t,e,i,a,s,r,l,o){const{fontSize:c,fontFamily:h,fontWeight:d}=o,p=t.split(u.lineBreakRegex);for(let u=0;u>"),e.typeC4Shape.text){case"person":case"external_person":B(o,48,48,e.x+e.width/2-24,e.y+e.image.Y,l)}let d=i[e.typeC4Shape.text+"Font"]();return d.fontWeight="bold",d.fontSize=d.fontSize+2,d.fontColor=r,Y(i)(e.label.text,o,e.x,e.y+e.label.Y,e.width,e.height,{fill:r},d),d=i[e.typeC4Shape.text+"Font"](),d.fontColor=r,e.techn&&""!==(null==(n=e.techn)?void 0:n.text)?Y(i)(e.techn.text,o,e.x,e.y+e.techn.Y,e.width,e.height,{fill:r,"font-style":"italic"},d):e.type&&""!==e.type.text&&Y(i)(e.type.text,o,e.x,e.y+e.type.Y,e.width,e.height,{fill:r,"font-style":"italic"},d),e.descr&&""!==e.descr.text&&(d=i.personFont(),d.fontColor=r,Y(i)(e.descr.text,o,e.x,e.y+e.descr.Y,e.width,e.height,{fill:r},d)),e.height},F=(t,e,i)=>{const n=t.append("g");let a=0;for(let s of e){let t=s.textColor?s.textColor:"#444444",e=s.lineColor?s.lineColor:"#444444",r=s.offsetX?parseInt(s.offsetX):0,l=s.offsetY?parseInt(s.offsetY):0,o="";if(0===a){let t=n.append("line");t.attr("x1",s.startPoint.x),t.attr("y1",s.startPoint.y),t.attr("x2",s.endPoint.x),t.attr("y2",s.endPoint.y),t.attr("stroke-width","1"),t.attr("stroke",e),t.style("fill","none"),"rel_b"!==s.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==s.type&&"rel_b"!==s.type||t.attr("marker-start","url("+o+"#arrowend)"),a=-1}else{let t=n.append("path");t.attr("fill","none").attr("stroke-width","1").attr("stroke",e).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",s.startPoint.x).replaceAll("starty",s.startPoint.y).replaceAll("controlx",s.startPoint.x+(s.endPoint.x-s.startPoint.x)/2-(s.endPoint.x-s.startPoint.x)/4).replaceAll("controly",s.startPoint.y+(s.endPoint.y-s.startPoint.y)/2).replaceAll("stopx",s.endPoint.x).replaceAll("stopy",s.endPoint.y)),"rel_b"!==s.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==s.type&&"rel_b"!==s.type||t.attr("marker-start","url("+o+"#arrowend)")}let c=i.messageFont();Y(i)(s.label.text,n,Math.min(s.startPoint.x,s.endPoint.x)+Math.abs(s.endPoint.x-s.startPoint.x)/2+r,Math.min(s.startPoint.y,s.endPoint.y)+Math.abs(s.endPoint.y-s.startPoint.y)/2+l,s.label.width,s.label.height,{fill:t},c),s.techn&&""!==s.techn.text&&(c=i.messageFont(),Y(i)("["+s.techn.text+"]",n,Math.min(s.startPoint.x,s.endPoint.x)+Math.abs(s.endPoint.x-s.startPoint.x)/2+r,Math.min(s.startPoint.y,s.endPoint.y)+Math.abs(s.endPoint.y-s.startPoint.y)/2+i.messageFontSize+5+l,Math.max(s.label.width,s.techn.width),s.techn.height,{fill:t,"font-style":"italic"},c))}},X=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).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")},z=function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")},Q=function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).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")},W=function(t){const e=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);e.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),e.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},$=function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},q=function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},V=function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")};let G=0,H=0,K=4,J=2;x.yy=j;let Z={};class tt{constructor(t){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,et(t.db.getConfig())}setData(t,e,i,n){this.nextData.startx=this.data.startx=t,this.nextData.stopx=this.data.stopx=e,this.nextData.starty=this.data.starty=i,this.nextData.stopy=this.data.stopy=n}updateVal(t,e,i,n){void 0===t[e]?t[e]=i:t[e]=n(i,t[e])}insert(t){this.nextData.cnt=this.nextData.cnt+1;let e=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+t.margin:this.nextData.stopx+2*t.margin,i=e+t.width,n=this.nextData.starty+2*t.margin,a=n+t.height;(e>=this.data.widthLimit||i>=this.data.widthLimit||this.nextData.cnt>K)&&(e=this.nextData.startx+t.margin+Z.nextLinePaddingX,n=this.nextData.stopy+2*t.margin,this.nextData.stopx=i=e+t.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=a=n+t.height,this.nextData.cnt=1),t.x=e,t.y=n,this.updateVal(this.data,"startx",e,Math.min),this.updateVal(this.data,"starty",n,Math.min),this.updateVal(this.data,"stopx",i,Math.max),this.updateVal(this.data,"stopy",a,Math.max),this.updateVal(this.nextData,"startx",e,Math.min),this.updateVal(this.nextData,"starty",n,Math.min),this.updateVal(this.nextData,"stopx",i,Math.max),this.updateVal(this.nextData,"stopy",a,Math.max)}init(t){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},et(t.db.getConfig())}bumpLastMargin(t){this.data.stopx+=t,this.data.stopy+=t}}const et=function(t){l(Z,t),t.fontFamily&&(Z.personFontFamily=Z.systemFontFamily=Z.messageFontFamily=t.fontFamily),t.fontSize&&(Z.personFontSize=Z.systemFontSize=Z.messageFontSize=t.fontSize),t.fontWeight&&(Z.personFontWeight=Z.systemFontWeight=Z.messageFontWeight=t.fontWeight)},it=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),nt=t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight});function at(t,e,i,n,a){if(!e[t].width)if(i)e[t].text=y(e[t].text,a,n),e[t].textLines=e[t].text.split(u.lineBreakRegex).length,e[t].width=a,e[t].height=f(e[t].text,n);else{let i=e[t].text.split(u.lineBreakRegex);e[t].textLines=i.length;let a=0;e[t].height=0,e[t].width=0;for(const s of i)e[t].width=Math.max(o(s,n),e[t].width),a=f(s,n),e[t].height=e[t].height+a}}const st=function(t,e,i){e.x=i.data.startx,e.y=i.data.starty,e.width=i.data.stopx-i.data.startx,e.height=i.data.stopy-i.data.starty,e.label.y=Z.c4ShapeMargin-35;let n=e.wrap&&Z.wrap,a=nt(Z);a.fontSize=a.fontSize+2,a.fontWeight="bold",at("label",e,n,a,o(e.label.text,a)),I(t,e,Z)},rt=function(t,e,i,n){let a=0;for(const s of n){a=0;const n=i[s];let r=it(Z,n.typeC4Shape.text);switch(r.fontSize=r.fontSize-2,n.typeC4Shape.width=o("<<"+n.typeC4Shape.text+">>",r),n.typeC4Shape.height=r.fontSize+2,n.typeC4Shape.Y=Z.c4ShapePadding,a=n.typeC4Shape.Y+n.typeC4Shape.height-4,n.image={width:0,height:0,Y:0},n.typeC4Shape.text){case"person":case"external_person":n.image.width=48,n.image.height=48,n.image.Y=a,a=n.image.Y+n.image.height}n.sprite&&(n.image.width=48,n.image.height=48,n.image.Y=a,a=n.image.Y+n.image.height);let l=n.wrap&&Z.wrap,c=Z.width-2*Z.c4ShapePadding,h=it(Z,n.typeC4Shape.text);if(h.fontSize=h.fontSize+2,h.fontWeight="bold",at("label",n,l,h,c),n.label.Y=a+8,a=n.label.Y+n.label.height,n.type&&""!==n.type.text){n.type.text="["+n.type.text+"]",at("type",n,l,it(Z,n.typeC4Shape.text),c),n.type.Y=a+5,a=n.type.Y+n.type.height}else if(n.techn&&""!==n.techn.text){n.techn.text="["+n.techn.text+"]",at("techn",n,l,it(Z,n.techn.text),c),n.techn.Y=a+5,a=n.techn.Y+n.techn.height}let d=a,p=n.label.width;if(n.descr&&""!==n.descr.text){at("descr",n,l,it(Z,n.typeC4Shape.text),c),n.descr.Y=a+20,a=n.descr.Y+n.descr.height,p=Math.max(n.label.width,n.descr.width),d=a-5*n.descr.textLines}p+=Z.c4ShapePadding,n.width=Math.max(n.width||Z.width,p,Z.width),n.height=Math.max(n.height||Z.height,d,Z.height),n.margin=n.margin||Z.c4ShapeMargin,t.insert(n),U(e,n,Z)}t.bumpLastMargin(Z.c4ShapeMargin)};class lt{constructor(t,e){this.x=t,this.y=e}}let ot=function(t,e){let i=t.x,n=t.y,a=e.x,s=e.y,r=i+t.width/2,l=n+t.height/2,o=Math.abs(i-a),c=Math.abs(n-s),h=c/o,d=t.height/t.width,p=null;return n==s&&ia?p=new lt(i,l):i==a&&ns&&(p=new lt(r,n)),i>a&&n=h?new lt(i,l+h*t.width/2):new lt(r-o/c*t.height/2,n+t.height):i=h?new lt(i+t.width,l+h*t.width/2):new lt(r+o/c*t.height/2,n+t.height):is?p=d>=h?new lt(i+t.width,l-h*t.width/2):new lt(r+t.height/2*o/c,n):i>a&&n>s&&(p=d>=h?new lt(i,l-t.width/2*h):new lt(r-t.height/2*o/c,n)),p},ct=function(t,e){let i={x:0,y:0};i.x=e.x+e.width/2,i.y=e.y+e.height/2;let n=ot(t,i);return i.x=t.x+t.width/2,i.y=t.y+t.height/2,{startPoint:n,endPoint:ot(e,i)}};function ht(t,e,i,n,a){let s=new tt(a);s.data.widthLimit=i.data.widthLimit/Math.min(J,n.length);for(let[r,l]of n.entries()){let n=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=n,n=l.image.Y+l.image.height);let o=l.wrap&&Z.wrap,c=nt(Z);if(c.fontSize=c.fontSize+2,c.fontWeight="bold",at("label",l,o,c,s.data.widthLimit),l.label.Y=n+8,n=l.label.Y+l.label.height,l.type&&""!==l.type.text){l.type.text="["+l.type.text+"]",at("type",l,o,nt(Z),s.data.widthLimit),l.type.Y=n+5,n=l.type.Y+l.type.height}if(l.descr&&""!==l.descr.text){let t=nt(Z);t.fontSize=t.fontSize-2,at("descr",l,o,t,s.data.widthLimit),l.descr.Y=n+20,n=l.descr.Y+l.descr.height}if(0==r||r%J==0){let t=i.data.startx+Z.diagramMarginX,e=i.data.stopy+Z.diagramMarginY+n;s.setData(t,t,e,e)}else{let t=s.data.stopx!==s.data.startx?s.data.stopx+Z.diagramMarginX:s.data.startx,e=s.data.starty;s.setData(t,t,e,e)}s.name=l.alias;let h=a.db.getC4ShapeArray(l.alias),d=a.db.getC4ShapeKeys(l.alias);d.length>0&&rt(s,t,h,d),e=l.alias;let p=a.db.getBoundarys(e);p.length>0&&ht(t,e,s,p,a),"global"!==l.alias&&st(t,l,s),i.data.stopy=Math.max(s.data.stopy+Z.c4ShapeMargin,i.data.stopy),i.data.stopx=Math.max(s.data.stopx+Z.c4ShapeMargin,i.data.stopx),G=Math.max(G,i.data.stopx),H=Math.max(H,i.data.stopy)}}const dt={drawPersonOrSystemArray:rt,drawBoundary:st,setConf:et,draw:function(t,e,i,n){Z=a().c4;const s=a().securityLevel;let r;"sandbox"===s&&(r=h("#i"+e));const l=h("sandbox"===s?r.nodes()[0].contentDocument.body:"body");let c=n.db;n.db.setWrap(Z.wrap),K=c.getC4ShapeInRow(),J=c.getC4BoundaryInRow(),d.debug(`C:${JSON.stringify(Z,null,2)}`);const u="sandbox"===s?l.select(`[id="${e}"]`):h(`[id="${e}"]`);q(u),$(u),V(u);let y=new tt(n);y.setData(Z.diagramMarginX,Z.diagramMarginX,Z.diagramMarginY,Z.diagramMarginY),y.data.widthLimit=screen.availWidth,G=Z.diagramMarginX,H=Z.diagramMarginY;const f=n.db.getTitle();ht(u,"",y,n.db.getBoundarys(""),n),X(u),z(u),W(u),Q(u),function(t,e,i,n){let a=0;for(let r of e){a+=1;let t=r.wrap&&Z.wrap,e={fontFamily:(s=Z).messageFontFamily,fontSize:s.messageFontSize,fontWeight:s.messageFontWeight};"C4Dynamic"===n.db.getC4Type()&&(r.label.text=a+": "+r.label.text);let l=o(r.label.text,e);at("label",r,t,e,l),r.techn&&""!==r.techn.text&&(l=o(r.techn.text,e),at("techn",r,t,e,l)),r.descr&&""!==r.descr.text&&(l=o(r.descr.text,e),at("descr",r,t,e,l));let c=i(r.from),h=i(r.to),d=ct(c,h);r.startPoint=d.startPoint,r.endPoint=d.endPoint}var s;F(t,e,Z)}(u,n.db.getRels(),n.db.getC4Shape,n),y.data.stopx=G,y.data.stopy=H;const b=y.data;let g=b.stopy-b.starty+2*Z.diagramMarginY;const _=b.stopx-b.startx+2*Z.diagramMarginX;f&&u.append("text").text(f).attr("x",(b.stopx-b.startx)/2-4*Z.diagramMarginX).attr("y",b.starty+Z.diagramMarginY),p(u,g,_,Z.useMaxWidth);const x=f?60:0;u.attr("viewBox",b.startx-Z.diagramMarginX+" -"+(Z.diagramMarginY+x)+" "+_+" "+(g+x)),d.debug("models:",b)}},pt={parser:m,db:j,renderer:dt,styles:t=>`.person {\n stroke: ${t.personBorder};\n fill: ${t.personBkg};\n }\n`,init:t=>{dt.setConf(t.c4)}};export{pt as diagram}; +import{s as t,g as e,a as i,b as n,c as a,d as s,m as r,e as l,f as o,h,l as d,i as p,j as u,w as y,k as f,n as b}from"./mermaid.core.3a590193.js";import{d as g,g as _}from"./svgDrawCommon-f26cad39.447236df.js";var x=function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,6],i=[1,7],n=[1,8],a=[1,9],s=[1,16],r=[1,11],l=[1,12],o=[1,13],h=[1,14],d=[1,15],p=[1,27],u=[1,33],y=[1,34],f=[1,35],b=[1,36],g=[1,37],_=[1,72],x=[1,73],m=[1,74],E=[1,75],S=[1,76],A=[1,77],v=[1,78],C=[1,38],O=[1,39],k=[1,40],T=[1,41],w=[1,42],R=[1,43],D=[1,44],N=[1,45],P=[1,46],j=[1,47],M=[1,48],B=[1,49],L=[1,50],Y=[1,51],I=[1,52],U=[1,53],F=[1,54],X=[1,55],z=[1,56],Q=[1,57],W=[1,59],$=[1,60],q=[1,61],V=[1,62],G=[1,63],H=[1,64],K=[1,65],J=[1,66],Z=[1,67],tt=[1,68],et=[1,69],it=[24,52],nt=[24,44,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],at=[15,24,44,46,47,48,49,50,51,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],st=[1,94],rt=[1,95],lt=[1,96],ot=[1,97],ct=[15,24,52],ht=[7,8,9,10,18,22,25,26,27,28],dt=[15,24,43,52],pt=[15,24,43,52,86,87,89,90],ut=[15,43],yt=[44,46,47,48,49,50,51,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84],ft={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,directive:6,direction_tb:7,direction_bt:8,direction_rl:9,direction_lr:10,graphConfig:11,openDirective:12,typeDirective:13,closeDirective:14,NEWLINE:15,":":16,argDirective:17,open_directive:18,type_directive:19,arg_directive:20,close_directive:21,C4_CONTEXT:22,statements:23,EOF:24,C4_CONTAINER:25,C4_COMPONENT:26,C4_DYNAMIC:27,C4_DEPLOYMENT:28,otherStatements:29,diagramStatements:30,otherStatement:31,title:32,accDescription:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,boundaryStatement:39,boundaryStartStatement:40,boundaryStopStatement:41,boundaryStart:42,LBRACE:43,ENTERPRISE_BOUNDARY:44,attributes:45,SYSTEM_BOUNDARY:46,BOUNDARY:47,CONTAINER_BOUNDARY:48,NODE:49,NODE_L:50,NODE_R:51,RBRACE:52,diagramStatement:53,PERSON:54,PERSON_EXT:55,SYSTEM:56,SYSTEM_DB:57,SYSTEM_QUEUE:58,SYSTEM_EXT:59,SYSTEM_EXT_DB:60,SYSTEM_EXT_QUEUE:61,CONTAINER:62,CONTAINER_DB:63,CONTAINER_QUEUE:64,CONTAINER_EXT:65,CONTAINER_EXT_DB:66,CONTAINER_EXT_QUEUE:67,COMPONENT:68,COMPONENT_DB:69,COMPONENT_QUEUE:70,COMPONENT_EXT:71,COMPONENT_EXT_DB:72,COMPONENT_EXT_QUEUE:73,REL:74,BIREL:75,REL_U:76,REL_D:77,REL_L:78,REL_R:79,REL_B:80,REL_INDEX:81,UPDATE_EL_STYLE:82,UPDATE_REL_STYLE:83,UPDATE_LAYOUT_CONFIG:84,attribute:85,STR:86,STR_KEY:87,STR_VALUE:88,ATTRIBUTE:89,ATTRIBUTE_EMPTY:90,$accept:0,$end:1},terminals_:{2:"error",7:"direction_tb",8:"direction_bt",9:"direction_rl",10:"direction_lr",15:"NEWLINE",16:":",18:"open_directive",19:"type_directive",20:"arg_directive",21:"close_directive",22:"C4_CONTEXT",24:"EOF",25:"C4_CONTAINER",26:"C4_COMPONENT",27:"C4_DYNAMIC",28:"C4_DEPLOYMENT",32:"title",33:"accDescription",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",43:"LBRACE",44:"ENTERPRISE_BOUNDARY",46:"SYSTEM_BOUNDARY",47:"BOUNDARY",48:"CONTAINER_BOUNDARY",49:"NODE",50:"NODE_L",51:"NODE_R",52:"RBRACE",54:"PERSON",55:"PERSON_EXT",56:"SYSTEM",57:"SYSTEM_DB",58:"SYSTEM_QUEUE",59:"SYSTEM_EXT",60:"SYSTEM_EXT_DB",61:"SYSTEM_EXT_QUEUE",62:"CONTAINER",63:"CONTAINER_DB",64:"CONTAINER_QUEUE",65:"CONTAINER_EXT",66:"CONTAINER_EXT_DB",67:"CONTAINER_EXT_QUEUE",68:"COMPONENT",69:"COMPONENT_DB",70:"COMPONENT_QUEUE",71:"COMPONENT_EXT",72:"COMPONENT_EXT_DB",73:"COMPONENT_EXT_QUEUE",74:"REL",75:"BIREL",76:"REL_U",77:"REL_D",78:"REL_L",79:"REL_R",80:"REL_B",81:"REL_INDEX",82:"UPDATE_EL_STYLE",83:"UPDATE_REL_STYLE",84:"UPDATE_LAYOUT_CONFIG",86:"STR",87:"STR_KEY",88:"STR_VALUE",89:"ATTRIBUTE",90:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[3,2],[5,1],[5,1],[5,1],[5,1],[4,1],[6,4],[6,6],[12,1],[13,1],[17,1],[14,1],[11,4],[11,4],[11,4],[11,4],[11,4],[23,1],[23,1],[23,2],[29,1],[29,2],[29,3],[31,1],[31,1],[31,2],[31,2],[31,1],[39,3],[40,3],[40,3],[40,4],[42,2],[42,2],[42,2],[42,2],[42,2],[42,2],[42,2],[41,1],[30,1],[30,2],[30,3],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,1],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[53,2],[45,1],[45,2],[85,1],[85,2],[85,1],[85,1]],performAction:function(t,e,i,n,a,s,r){var l=s.length-1;switch(a){case 4:n.setDirection("TB");break;case 5:n.setDirection("BT");break;case 6:n.setDirection("RL");break;case 7:n.setDirection("LR");break;case 11:n.parseDirective("%%{","open_directive");break;case 12:break;case 13:s[l]=s[l].trim().replace(/'/g,'"'),n.parseDirective(s[l],"arg_directive");break;case 14:n.parseDirective("}%%","close_directive","c4Context");break;case 15:case 16:case 17:case 18:case 19:n.setC4Type(s[l-3]);break;case 26:n.setTitle(s[l].substring(6)),this.$=s[l].substring(6);break;case 27:n.setAccDescription(s[l].substring(15)),this.$=s[l].substring(15);break;case 28:this.$=s[l].trim(),n.setTitle(this.$);break;case 29:case 30:this.$=s[l].trim(),n.setAccDescription(this.$);break;case 35:case 36:s[l].splice(2,0,"ENTERPRISE"),n.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 37:n.addPersonOrSystemBoundary(...s[l]),this.$=s[l];break;case 38:s[l].splice(2,0,"CONTAINER"),n.addContainerBoundary(...s[l]),this.$=s[l];break;case 39:n.addDeploymentNode("node",...s[l]),this.$=s[l];break;case 40:n.addDeploymentNode("nodeL",...s[l]),this.$=s[l];break;case 41:n.addDeploymentNode("nodeR",...s[l]),this.$=s[l];break;case 42:n.popBoundaryParseStack();break;case 46:n.addPersonOrSystem("person",...s[l]),this.$=s[l];break;case 47:n.addPersonOrSystem("external_person",...s[l]),this.$=s[l];break;case 48:n.addPersonOrSystem("system",...s[l]),this.$=s[l];break;case 49:n.addPersonOrSystem("system_db",...s[l]),this.$=s[l];break;case 50:n.addPersonOrSystem("system_queue",...s[l]),this.$=s[l];break;case 51:n.addPersonOrSystem("external_system",...s[l]),this.$=s[l];break;case 52:n.addPersonOrSystem("external_system_db",...s[l]),this.$=s[l];break;case 53:n.addPersonOrSystem("external_system_queue",...s[l]),this.$=s[l];break;case 54:n.addContainer("container",...s[l]),this.$=s[l];break;case 55:n.addContainer("container_db",...s[l]),this.$=s[l];break;case 56:n.addContainer("container_queue",...s[l]),this.$=s[l];break;case 57:n.addContainer("external_container",...s[l]),this.$=s[l];break;case 58:n.addContainer("external_container_db",...s[l]),this.$=s[l];break;case 59:n.addContainer("external_container_queue",...s[l]),this.$=s[l];break;case 60:n.addComponent("component",...s[l]),this.$=s[l];break;case 61:n.addComponent("component_db",...s[l]),this.$=s[l];break;case 62:n.addComponent("component_queue",...s[l]),this.$=s[l];break;case 63:n.addComponent("external_component",...s[l]),this.$=s[l];break;case 64:n.addComponent("external_component_db",...s[l]),this.$=s[l];break;case 65:n.addComponent("external_component_queue",...s[l]),this.$=s[l];break;case 67:n.addRel("rel",...s[l]),this.$=s[l];break;case 68:n.addRel("birel",...s[l]),this.$=s[l];break;case 69:n.addRel("rel_u",...s[l]),this.$=s[l];break;case 70:n.addRel("rel_d",...s[l]),this.$=s[l];break;case 71:n.addRel("rel_l",...s[l]),this.$=s[l];break;case 72:n.addRel("rel_r",...s[l]),this.$=s[l];break;case 73:n.addRel("rel_b",...s[l]),this.$=s[l];break;case 74:s[l].splice(0,1),n.addRel("rel",...s[l]),this.$=s[l];break;case 75:n.updateElStyle("update_el_style",...s[l]),this.$=s[l];break;case 76:n.updateRelStyle("update_rel_style",...s[l]),this.$=s[l];break;case 77:n.updateLayoutConfig("update_layout_config",...s[l]),this.$=s[l];break;case 78:this.$=[s[l]];break;case 79:s[l].unshift(s[l-1]),this.$=s[l];break;case 80:case 82:this.$=s[l].trim();break;case 81:let t={};t[s[l-1].trim()]=s[l].trim(),this.$=t;break;case 83:this.$=""}},table:[{3:1,4:2,5:3,6:4,7:e,8:i,9:n,10:a,11:5,12:10,18:s,22:r,25:l,26:o,27:h,28:d},{1:[3]},{1:[2,1]},{1:[2,2]},{3:17,4:2,5:3,6:4,7:e,8:i,9:n,10:a,11:5,12:10,18:s,22:r,25:l,26:o,27:h,28:d},{1:[2,8]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{1:[2,7]},{13:18,19:[1,19]},{15:[1,20]},{15:[1,21]},{15:[1,22]},{15:[1,23]},{15:[1,24]},{19:[2,11]},{1:[2,3]},{14:25,16:[1,26],21:p},t([16,21],[2,12]),{23:28,29:29,30:30,31:31,32:u,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:79,29:29,30:30,31:31,32:u,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:80,29:29,30:30,31:31,32:u,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:81,29:29,30:30,31:31,32:u,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{23:82,29:29,30:30,31:31,32:u,33:y,34:f,36:b,38:g,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{15:[1,83]},{17:84,20:[1,85]},{15:[2,14]},{24:[1,86]},t(it,[2,20],{53:32,39:58,40:70,42:71,30:87,44:_,46:x,47:m,48:E,49:S,50:A,51:v,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et}),t(it,[2,21]),t(nt,[2,23],{15:[1,88]}),t(it,[2,43],{15:[1,89]}),t(at,[2,26]),t(at,[2,27]),{35:[1,90]},{37:[1,91]},t(at,[2,30]),{45:92,85:93,86:st,87:rt,89:lt,90:ot},{45:98,85:93,86:st,87:rt,89:lt,90:ot},{45:99,85:93,86:st,87:rt,89:lt,90:ot},{45:100,85:93,86:st,87:rt,89:lt,90:ot},{45:101,85:93,86:st,87:rt,89:lt,90:ot},{45:102,85:93,86:st,87:rt,89:lt,90:ot},{45:103,85:93,86:st,87:rt,89:lt,90:ot},{45:104,85:93,86:st,87:rt,89:lt,90:ot},{45:105,85:93,86:st,87:rt,89:lt,90:ot},{45:106,85:93,86:st,87:rt,89:lt,90:ot},{45:107,85:93,86:st,87:rt,89:lt,90:ot},{45:108,85:93,86:st,87:rt,89:lt,90:ot},{45:109,85:93,86:st,87:rt,89:lt,90:ot},{45:110,85:93,86:st,87:rt,89:lt,90:ot},{45:111,85:93,86:st,87:rt,89:lt,90:ot},{45:112,85:93,86:st,87:rt,89:lt,90:ot},{45:113,85:93,86:st,87:rt,89:lt,90:ot},{45:114,85:93,86:st,87:rt,89:lt,90:ot},{45:115,85:93,86:st,87:rt,89:lt,90:ot},{45:116,85:93,86:st,87:rt,89:lt,90:ot},t(ct,[2,66]),{45:117,85:93,86:st,87:rt,89:lt,90:ot},{45:118,85:93,86:st,87:rt,89:lt,90:ot},{45:119,85:93,86:st,87:rt,89:lt,90:ot},{45:120,85:93,86:st,87:rt,89:lt,90:ot},{45:121,85:93,86:st,87:rt,89:lt,90:ot},{45:122,85:93,86:st,87:rt,89:lt,90:ot},{45:123,85:93,86:st,87:rt,89:lt,90:ot},{45:124,85:93,86:st,87:rt,89:lt,90:ot},{45:125,85:93,86:st,87:rt,89:lt,90:ot},{45:126,85:93,86:st,87:rt,89:lt,90:ot},{45:127,85:93,86:st,87:rt,89:lt,90:ot},{30:128,39:58,40:70,42:71,44:_,46:x,47:m,48:E,49:S,50:A,51:v,53:32,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et},{15:[1,130],43:[1,129]},{45:131,85:93,86:st,87:rt,89:lt,90:ot},{45:132,85:93,86:st,87:rt,89:lt,90:ot},{45:133,85:93,86:st,87:rt,89:lt,90:ot},{45:134,85:93,86:st,87:rt,89:lt,90:ot},{45:135,85:93,86:st,87:rt,89:lt,90:ot},{45:136,85:93,86:st,87:rt,89:lt,90:ot},{45:137,85:93,86:st,87:rt,89:lt,90:ot},{24:[1,138]},{24:[1,139]},{24:[1,140]},{24:[1,141]},t(ht,[2,9]),{14:142,21:p},{21:[2,13]},{1:[2,15]},t(it,[2,22]),t(nt,[2,24],{31:31,29:143,32:u,33:y,34:f,36:b,38:g}),t(it,[2,44],{29:29,30:30,31:31,53:32,39:58,40:70,42:71,23:144,32:u,33:y,34:f,36:b,38:g,44:_,46:x,47:m,48:E,49:S,50:A,51:v,54:C,55:O,56:k,57:T,58:w,59:R,60:D,61:N,62:P,63:j,64:M,65:B,66:L,67:Y,68:I,69:U,70:F,71:X,72:z,73:Q,74:W,75:$,76:q,77:V,78:G,79:H,80:K,81:J,82:Z,83:tt,84:et}),t(at,[2,28]),t(at,[2,29]),t(ct,[2,46]),t(dt,[2,78],{85:93,45:145,86:st,87:rt,89:lt,90:ot}),t(pt,[2,80]),{88:[1,146]},t(pt,[2,82]),t(pt,[2,83]),t(ct,[2,47]),t(ct,[2,48]),t(ct,[2,49]),t(ct,[2,50]),t(ct,[2,51]),t(ct,[2,52]),t(ct,[2,53]),t(ct,[2,54]),t(ct,[2,55]),t(ct,[2,56]),t(ct,[2,57]),t(ct,[2,58]),t(ct,[2,59]),t(ct,[2,60]),t(ct,[2,61]),t(ct,[2,62]),t(ct,[2,63]),t(ct,[2,64]),t(ct,[2,65]),t(ct,[2,67]),t(ct,[2,68]),t(ct,[2,69]),t(ct,[2,70]),t(ct,[2,71]),t(ct,[2,72]),t(ct,[2,73]),t(ct,[2,74]),t(ct,[2,75]),t(ct,[2,76]),t(ct,[2,77]),{41:147,52:[1,148]},{15:[1,149]},{43:[1,150]},t(ut,[2,35]),t(ut,[2,36]),t(ut,[2,37]),t(ut,[2,38]),t(ut,[2,39]),t(ut,[2,40]),t(ut,[2,41]),{1:[2,16]},{1:[2,17]},{1:[2,18]},{1:[2,19]},{15:[1,151]},t(nt,[2,25]),t(it,[2,45]),t(dt,[2,79]),t(pt,[2,81]),t(ct,[2,31]),t(ct,[2,42]),t(yt,[2,32]),t(yt,[2,33],{15:[1,152]}),t(ht,[2,10]),t(yt,[2,34])],defaultActions:{2:[2,1],3:[2,2],5:[2,8],6:[2,4],7:[2,5],8:[2,6],9:[2,7],16:[2,11],17:[2,3],27:[2,14],85:[2,13],86:[2,15],138:[2,16],139:[2,17],140:[2,18],141:[2,19]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],n=[],a=[null],s=[],r=this.table,l="",o=0,c=0,h=2,d=1,p=s.slice.call(arguments,1),u=Object.create(this.lexer),y={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(y.yy[f]=this.yy[f]);u.setInput(t,y.yy),y.yy.lexer=u,y.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var b=u.yylloc;s.push(b);var g=u.options&&u.options.ranges;function _(){var t;return"number"!=typeof(t=n.pop()||u.lex()||d)&&(t instanceof Array&&(t=(n=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var x,m,E,S,A,v,C,O,k={};;){if(m=i[i.length-1],this.defaultActions[m]?E=this.defaultActions[m]:(null==x&&(x=_()),E=r[m]&&r[m][x]),void 0===E||!E.length||!E[0]){var T="";for(A in O=[],r[m])this.terminals_[A]&&A>h&&O.push("'"+this.terminals_[A]+"'");T=u.showPosition?"Parse error on line "+(o+1)+":\n"+u.showPosition()+"\nExpecting "+O.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(o+1)+": Unexpected "+(x==d?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(T,{text:u.match,token:this.terminals_[x]||x,line:u.yylineno,loc:b,expected:O})}if(E[0]instanceof Array&&E.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+x);switch(E[0]){case 1:i.push(x),a.push(u.yytext),s.push(u.yylloc),i.push(E[1]),x=null,c=u.yyleng,l=u.yytext,o=u.yylineno,b=u.yylloc;break;case 2:if(v=this.productions_[E[1]][1],k.$=a[a.length-v],k._$={first_line:s[s.length-(v||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(v||1)].first_column,last_column:s[s.length-1].last_column},g&&(k._$.range=[s[s.length-(v||1)].range[0],s[s.length-1].range[1]]),void 0!==(S=this.performAction.apply(k,[l,c,o,y.yy,E[1],a,s].concat(p))))return S;v&&(i=i.slice(0,-1*v*2),a=a.slice(0,-1*v),s=s.slice(0,-1*v)),i.push(this.productions_[E[1]][0]),a.push(k.$),s.push(k._$),C=r[i[i.length-2]][i[i.length-1]],i.push(C);break;case 3:return!0}}return!0}},bt={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,i=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 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),i.length-1&&(this.yylineno-=i.length-1);var a=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===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var i,n,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in a)this[s]=a[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),s=0;se[0].length)){if(e=i,n=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,a[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,i,n){switch(i){case 0:return this.begin("open_directive"),18;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 10;case 5:return this.begin("type_directive"),19;case 6:return this.popState(),this.begin("arg_directive"),16;case 7:return this.popState(),this.popState(),21;case 8:return 20;case 9:return 32;case 10:return 33;case 11:return this.begin("acc_title"),34;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),36;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:break;case 19:c;break;case 20:return 15;case 21:break;case 22:return 22;case 23:return 25;case 24:return 26;case 25:return 27;case 26:return 28;case 27:return this.begin("person_ext"),55;case 28:return this.begin("person"),54;case 29:return this.begin("system_ext_queue"),61;case 30:return this.begin("system_ext_db"),60;case 31:return this.begin("system_ext"),59;case 32:return this.begin("system_queue"),58;case 33:return this.begin("system_db"),57;case 34:return this.begin("system"),56;case 35:return this.begin("boundary"),47;case 36:return this.begin("enterprise_boundary"),44;case 37:return this.begin("system_boundary"),46;case 38:return this.begin("container_ext_queue"),67;case 39:return this.begin("container_ext_db"),66;case 40:return this.begin("container_ext"),65;case 41:return this.begin("container_queue"),64;case 42:return this.begin("container_db"),63;case 43:return this.begin("container"),62;case 44:return this.begin("container_boundary"),48;case 45:return this.begin("component_ext_queue"),73;case 46:return this.begin("component_ext_db"),72;case 47:return this.begin("component_ext"),71;case 48:return this.begin("component_queue"),70;case 49:return this.begin("component_db"),69;case 50:return this.begin("component"),68;case 51:case 52:return this.begin("node"),49;case 53:return this.begin("node_l"),50;case 54:return this.begin("node_r"),51;case 55:return this.begin("rel"),74;case 56:return this.begin("birel"),75;case 57:case 58:return this.begin("rel_u"),76;case 59:case 60:return this.begin("rel_d"),77;case 61:case 62:return this.begin("rel_l"),78;case 63:case 64:return this.begin("rel_r"),79;case 65:return this.begin("rel_b"),80;case 66:return this.begin("rel_index"),81;case 67:return this.begin("update_el_style"),82;case 68:return this.begin("update_rel_style"),83;case 69:return this.begin("update_layout_config"),84;case 70:return"EOF_IN_STRUCT";case 71:return this.begin("attribute"),"ATTRIBUTE_EMPTY";case 72:this.begin("attribute");break;case 73:this.popState(),this.popState();break;case 74:return 90;case 75:break;case 76:return 90;case 77:this.begin("string");break;case 78:this.popState();break;case 79:return"STR";case 80:this.begin("string_kv");break;case 81:return this.begin("string_kv_key"),"STR_KEY";case 82:this.popState(),this.begin("string_kv_value");break;case 83:return"STR_VALUE";case 84:this.popState(),this.popState();break;case 85:return"STR";case 86:return"LBRACE";case 87:return"RBRACE";case 88:return"SPACE";case 89:return"EOL";case 90:return 24}},rules:[/^(?:%%\{)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[16,17],inclusive:!1},acc_descr:{rules:[14],inclusive:!1},acc_title:{rules:[12],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[7,8],inclusive:!1},type_directive:{rules:[6,7],inclusive:!1},open_directive:{rules:[5],inclusive:!1},string_kv_value:{rules:[83,84],inclusive:!1},string_kv_key:{rules:[82],inclusive:!1},string_kv:{rules:[81],inclusive:!1},string:{rules:[78,79],inclusive:!1},attribute:{rules:[73,74,75,76,77,80,85],inclusive:!1},update_layout_config:{rules:[70,71,72,73],inclusive:!1},update_rel_style:{rules:[70,71,72,73],inclusive:!1},update_el_style:{rules:[70,71,72,73],inclusive:!1},rel_b:{rules:[70,71,72,73],inclusive:!1},rel_r:{rules:[70,71,72,73],inclusive:!1},rel_l:{rules:[70,71,72,73],inclusive:!1},rel_d:{rules:[70,71,72,73],inclusive:!1},rel_u:{rules:[70,71,72,73],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[70,71,72,73],inclusive:!1},node_r:{rules:[70,71,72,73],inclusive:!1},node_l:{rules:[70,71,72,73],inclusive:!1},node:{rules:[70,71,72,73],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[70,71,72,73],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[70,71,72,73],inclusive:!1},component_ext:{rules:[70,71,72,73],inclusive:!1},component_queue:{rules:[70,71,72,73],inclusive:!1},component_db:{rules:[70,71,72,73],inclusive:!1},component:{rules:[70,71,72,73],inclusive:!1},container_boundary:{rules:[70,71,72,73],inclusive:!1},container_ext_queue:{rules:[],inclusive:!1},container_ext_db:{rules:[70,71,72,73],inclusive:!1},container_ext:{rules:[70,71,72,73],inclusive:!1},container_queue:{rules:[70,71,72,73],inclusive:!1},container_db:{rules:[70,71,72,73],inclusive:!1},container:{rules:[70,71,72,73],inclusive:!1},birel:{rules:[70,71,72,73],inclusive:!1},system_boundary:{rules:[70,71,72,73],inclusive:!1},enterprise_boundary:{rules:[70,71,72,73],inclusive:!1},boundary:{rules:[70,71,72,73],inclusive:!1},system_ext_queue:{rules:[70,71,72,73],inclusive:!1},system_ext_db:{rules:[70,71,72,73],inclusive:!1},system_ext:{rules:[70,71,72,73],inclusive:!1},system_queue:{rules:[70,71,72,73],inclusive:!1},system_db:{rules:[70,71,72,73],inclusive:!1},system:{rules:[70,71,72,73],inclusive:!1},person_ext:{rules:[70,71,72,73],inclusive:!1},person:{rules:[70,71,72,73],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,9,10,11,13,15,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,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,86,87,88,89,90],inclusive:!0}}};function gt(){this.yy={}}return ft.lexer=bt,gt.prototype=ft,ft.Parser=gt,new gt}();x.parser=x;const m=x;let E=[],S=[""],A="global",v="",C=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],O=[],k="",T=!1,w=4,R=2;var D;const N=function(t){return null==t?E:E.filter((e=>e.parentBoundary===t))},P=function(){return T},j={addPersonOrSystem:function(t,e,i,n,a,s,r){if(null===e||null===i)return;let l={};const o=E.find((t=>t.alias===e));if(o&&e===o.alias?l=o:(l.alias=e,E.push(l)),l.label=null==i?{text:""}:{text:i},null==n)l.descr={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];l[t]={text:e}}else l.descr={text:n};if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]=e}else l.sprite=a;if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=e}else l.tags=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=e}else l.link=r;l.typeC4Shape={text:t},l.parentBoundary=A,l.wrap=P()},addPersonOrSystemBoundary:function(t,e,i,n,a){if(null===t||null===e)return;let s={};const r=C.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,C.push(s)),s.label=null==e?{text:""}:{text:e},null==i)s.type={text:"system"};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]={text:e}}else s.type={text:i};if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]=e}else s.tags=n;if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.link=a;s.parentBoundary=A,s.wrap=P(),v=A,A=t,S.push(v)},addContainer:function(t,e,i,n,a,s,r,l){if(null===e||null===i)return;let o={};const c=E.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,E.push(o)),o.label=null==i?{text:""}:{text:i},null==n)o.techn={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.techn={text:n};if(null==a)o.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.descr={text:a};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=P(),o.typeC4Shape={text:t},o.parentBoundary=A},addContainerBoundary:function(t,e,i,n,a){if(null===t||null===e)return;let s={};const r=C.find((e=>e.alias===t));if(r&&t===r.alias?s=r:(s.alias=t,C.push(s)),s.label=null==e?{text:""}:{text:e},null==i)s.type={text:"container"};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];s[t]={text:e}}else s.type={text:i};if("object"==typeof n){let[t,e]=Object.entries(n)[0];s[t]=e}else s.tags=n;if("object"==typeof a){let[t,e]=Object.entries(a)[0];s[t]=e}else s.link=a;s.parentBoundary=A,s.wrap=P(),v=A,A=t,S.push(v)},addComponent:function(t,e,i,n,a,s,r,l){if(null===e||null===i)return;let o={};const c=E.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,E.push(o)),o.label=null==i?{text:""}:{text:i},null==n)o.techn={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.techn={text:n};if(null==a)o.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.descr={text:a};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.sprite=s;if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=P(),o.typeC4Shape={text:t},o.parentBoundary=A},addDeploymentNode:function(t,e,i,n,a,s,r,l){if(null===e||null===i)return;let o={};const c=C.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,C.push(o)),o.label=null==i?{text:""}:{text:i},null==n)o.type={text:"node"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.type={text:n};if(null==a)o.descr={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];o[t]={text:e}}else o.descr={text:a};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.tags=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.nodeType=t,o.parentBoundary=A,o.wrap=P(),v=A,A=e,S.push(v)},popBoundaryParseStack:function(){A=v,S.pop(),v=S.pop(),S.push(v)},addRel:function(t,e,i,n,a,s,r,l,o){if(null==t||null==e||null==i||null==n)return;let c={};const h=O.find((t=>t.from===e&&t.to===i));if(h?c=h:O.push(c),c.type=t,c.from=e,c.to=i,c.label={text:n},null==a)c.techn={text:""};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];c[t]={text:e}}else c.techn={text:a};if(null==s)c.descr={text:""};else if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]={text:e}}else c.descr={text:s};if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]=e}else c.sprite=r;if("object"==typeof l){let[t,e]=Object.entries(l)[0];c[t]=e}else c.tags=l;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.wrap=P()},updateElStyle:function(t,e,i,n,a,s,r,l,o,c,h){let d=E.find((t=>t.alias===e));if(void 0!==d||(d=C.find((t=>t.alias===e)),void 0!==d)){if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];d[t]=e}else d.bgColor=i;if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];d[t]=e}else d.fontColor=n;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];d[t]=e}else d.borderColor=a;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];d[t]=e}else d.shadowing=s;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];d[t]=e}else d.shape=r;if(null!=l)if("object"==typeof l){let[t,e]=Object.entries(l)[0];d[t]=e}else d.sprite=l;if(null!=o)if("object"==typeof o){let[t,e]=Object.entries(o)[0];d[t]=e}else d.techn=o;if(null!=c)if("object"==typeof c){let[t,e]=Object.entries(c)[0];d[t]=e}else d.legendText=c;if(null!=h)if("object"==typeof h){let[t,e]=Object.entries(h)[0];d[t]=e}else d.legendSprite=h}},updateRelStyle:function(t,e,i,n,a,s,r){const l=O.find((t=>t.from===e&&t.to===i));if(void 0!==l){if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];l[t]=e}else l.textColor=n;if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];l[t]=e}else l.lineColor=a;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=parseInt(e)}else l.offsetX=parseInt(s);if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=parseInt(e)}else l.offsetY=parseInt(r)}},updateLayoutConfig:function(t,e,i){let n=w,a=R;if("object"==typeof e){const t=Object.values(e)[0];n=parseInt(t)}else n=parseInt(e);if("object"==typeof i){const t=Object.values(i)[0];a=parseInt(t)}else a=parseInt(i);n>=1&&(w=n),a>=1&&(R=a)},autoWrap:P,setWrap:function(t){T=t},getC4ShapeArray:N,getC4Shape:function(t){return E.find((e=>e.alias===t))},getC4ShapeKeys:function(t){return Object.keys(N(t))},getBoundarys:function(t){return null==t?C:C.filter((e=>e.parentBoundary===t))},getCurrentBoundaryParse:function(){return A},getParentBoundaryParse:function(){return v},getRels:function(){return O},getTitle:function(){return k},getC4Type:function(){return D},getC4ShapeInRow:function(){return w},getC4BoundaryInRow:function(){return R},setAccTitle:t,getAccTitle:e,getAccDescription:i,setAccDescription:n,parseDirective:function(t,e,i){r.parseDirective(this,t,e,i)},getConfig:()=>a().c4,clear:function(){E=[],C=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],v="",A="global",S=[""],O=[],S=[""],k="",T=!1,w=4,R=2},LINETYPE:{SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},setTitle:function(t){let e=s(t,a());k=e},setC4Type:function(t){let e=s(t,a());D=e}},M=function(t,e){return g(t,e)},B=function(t,e,i,n,a,s){const r=t.append("image");r.attr("width",e),r.attr("height",i),r.attr("x",n),r.attr("y",a);let l=s.startsWith("data:image/png;base64")?s:b(s);r.attr("xlink:href",l)},L=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),Y=function(){function t(t,e,i,a,s,r,l){n(e.append("text").attr("x",i+s/2).attr("y",a+r/2+5).style("text-anchor","middle").text(t),l)}function e(t,e,i,a,s,r,l,o){const{fontSize:c,fontFamily:h,fontWeight:d}=o,p=t.split(u.lineBreakRegex);for(let u=0;u>"),e.typeC4Shape.text){case"person":case"external_person":B(o,48,48,e.x+e.width/2-24,e.y+e.image.Y,l)}let d=i[e.typeC4Shape.text+"Font"]();return d.fontWeight="bold",d.fontSize=d.fontSize+2,d.fontColor=r,Y(i)(e.label.text,o,e.x,e.y+e.label.Y,e.width,e.height,{fill:r},d),d=i[e.typeC4Shape.text+"Font"](),d.fontColor=r,e.techn&&""!==(null==(n=e.techn)?void 0:n.text)?Y(i)(e.techn.text,o,e.x,e.y+e.techn.Y,e.width,e.height,{fill:r,"font-style":"italic"},d):e.type&&""!==e.type.text&&Y(i)(e.type.text,o,e.x,e.y+e.type.Y,e.width,e.height,{fill:r,"font-style":"italic"},d),e.descr&&""!==e.descr.text&&(d=i.personFont(),d.fontColor=r,Y(i)(e.descr.text,o,e.x,e.y+e.descr.Y,e.width,e.height,{fill:r},d)),e.height},F=(t,e,i)=>{const n=t.append("g");let a=0;for(let s of e){let t=s.textColor?s.textColor:"#444444",e=s.lineColor?s.lineColor:"#444444",r=s.offsetX?parseInt(s.offsetX):0,l=s.offsetY?parseInt(s.offsetY):0,o="";if(0===a){let t=n.append("line");t.attr("x1",s.startPoint.x),t.attr("y1",s.startPoint.y),t.attr("x2",s.endPoint.x),t.attr("y2",s.endPoint.y),t.attr("stroke-width","1"),t.attr("stroke",e),t.style("fill","none"),"rel_b"!==s.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==s.type&&"rel_b"!==s.type||t.attr("marker-start","url("+o+"#arrowend)"),a=-1}else{let t=n.append("path");t.attr("fill","none").attr("stroke-width","1").attr("stroke",e).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",s.startPoint.x).replaceAll("starty",s.startPoint.y).replaceAll("controlx",s.startPoint.x+(s.endPoint.x-s.startPoint.x)/2-(s.endPoint.x-s.startPoint.x)/4).replaceAll("controly",s.startPoint.y+(s.endPoint.y-s.startPoint.y)/2).replaceAll("stopx",s.endPoint.x).replaceAll("stopy",s.endPoint.y)),"rel_b"!==s.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==s.type&&"rel_b"!==s.type||t.attr("marker-start","url("+o+"#arrowend)")}let c=i.messageFont();Y(i)(s.label.text,n,Math.min(s.startPoint.x,s.endPoint.x)+Math.abs(s.endPoint.x-s.startPoint.x)/2+r,Math.min(s.startPoint.y,s.endPoint.y)+Math.abs(s.endPoint.y-s.startPoint.y)/2+l,s.label.width,s.label.height,{fill:t},c),s.techn&&""!==s.techn.text&&(c=i.messageFont(),Y(i)("["+s.techn.text+"]",n,Math.min(s.startPoint.x,s.endPoint.x)+Math.abs(s.endPoint.x-s.startPoint.x)/2+r,Math.min(s.startPoint.y,s.endPoint.y)+Math.abs(s.endPoint.y-s.startPoint.y)/2+i.messageFontSize+5+l,Math.max(s.label.width,s.techn.width),s.techn.height,{fill:t,"font-style":"italic"},c))}},X=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).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")},z=function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")},Q=function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).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")},W=function(t){const e=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);e.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),e.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")},$=function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},q=function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},V=function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")};let G=0,H=0,K=4,J=2;x.yy=j;let Z={};class tt{constructor(t){this.name="",this.data={},this.data.startx=void 0,this.data.stopx=void 0,this.data.starty=void 0,this.data.stopy=void 0,this.data.widthLimit=void 0,this.nextData={},this.nextData.startx=void 0,this.nextData.stopx=void 0,this.nextData.starty=void 0,this.nextData.stopy=void 0,this.nextData.cnt=0,et(t.db.getConfig())}setData(t,e,i,n){this.nextData.startx=this.data.startx=t,this.nextData.stopx=this.data.stopx=e,this.nextData.starty=this.data.starty=i,this.nextData.stopy=this.data.stopy=n}updateVal(t,e,i,n){void 0===t[e]?t[e]=i:t[e]=n(i,t[e])}insert(t){this.nextData.cnt=this.nextData.cnt+1;let e=this.nextData.startx===this.nextData.stopx?this.nextData.stopx+t.margin:this.nextData.stopx+2*t.margin,i=e+t.width,n=this.nextData.starty+2*t.margin,a=n+t.height;(e>=this.data.widthLimit||i>=this.data.widthLimit||this.nextData.cnt>K)&&(e=this.nextData.startx+t.margin+Z.nextLinePaddingX,n=this.nextData.stopy+2*t.margin,this.nextData.stopx=i=e+t.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=a=n+t.height,this.nextData.cnt=1),t.x=e,t.y=n,this.updateVal(this.data,"startx",e,Math.min),this.updateVal(this.data,"starty",n,Math.min),this.updateVal(this.data,"stopx",i,Math.max),this.updateVal(this.data,"stopy",a,Math.max),this.updateVal(this.nextData,"startx",e,Math.min),this.updateVal(this.nextData,"starty",n,Math.min),this.updateVal(this.nextData,"stopx",i,Math.max),this.updateVal(this.nextData,"stopy",a,Math.max)}init(t){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},et(t.db.getConfig())}bumpLastMargin(t){this.data.stopx+=t,this.data.stopy+=t}}const et=function(t){l(Z,t),t.fontFamily&&(Z.personFontFamily=Z.systemFontFamily=Z.messageFontFamily=t.fontFamily),t.fontSize&&(Z.personFontSize=Z.systemFontSize=Z.messageFontSize=t.fontSize),t.fontWeight&&(Z.personFontWeight=Z.systemFontWeight=Z.messageFontWeight=t.fontWeight)},it=(t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]}),nt=t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight});function at(t,e,i,n,a){if(!e[t].width)if(i)e[t].text=y(e[t].text,a,n),e[t].textLines=e[t].text.split(u.lineBreakRegex).length,e[t].width=a,e[t].height=f(e[t].text,n);else{let i=e[t].text.split(u.lineBreakRegex);e[t].textLines=i.length;let a=0;e[t].height=0,e[t].width=0;for(const s of i)e[t].width=Math.max(o(s,n),e[t].width),a=f(s,n),e[t].height=e[t].height+a}}const st=function(t,e,i){e.x=i.data.startx,e.y=i.data.starty,e.width=i.data.stopx-i.data.startx,e.height=i.data.stopy-i.data.starty,e.label.y=Z.c4ShapeMargin-35;let n=e.wrap&&Z.wrap,a=nt(Z);a.fontSize=a.fontSize+2,a.fontWeight="bold",at("label",e,n,a,o(e.label.text,a)),I(t,e,Z)},rt=function(t,e,i,n){let a=0;for(const s of n){a=0;const n=i[s];let r=it(Z,n.typeC4Shape.text);switch(r.fontSize=r.fontSize-2,n.typeC4Shape.width=o("<<"+n.typeC4Shape.text+">>",r),n.typeC4Shape.height=r.fontSize+2,n.typeC4Shape.Y=Z.c4ShapePadding,a=n.typeC4Shape.Y+n.typeC4Shape.height-4,n.image={width:0,height:0,Y:0},n.typeC4Shape.text){case"person":case"external_person":n.image.width=48,n.image.height=48,n.image.Y=a,a=n.image.Y+n.image.height}n.sprite&&(n.image.width=48,n.image.height=48,n.image.Y=a,a=n.image.Y+n.image.height);let l=n.wrap&&Z.wrap,c=Z.width-2*Z.c4ShapePadding,h=it(Z,n.typeC4Shape.text);if(h.fontSize=h.fontSize+2,h.fontWeight="bold",at("label",n,l,h,c),n.label.Y=a+8,a=n.label.Y+n.label.height,n.type&&""!==n.type.text){n.type.text="["+n.type.text+"]",at("type",n,l,it(Z,n.typeC4Shape.text),c),n.type.Y=a+5,a=n.type.Y+n.type.height}else if(n.techn&&""!==n.techn.text){n.techn.text="["+n.techn.text+"]",at("techn",n,l,it(Z,n.techn.text),c),n.techn.Y=a+5,a=n.techn.Y+n.techn.height}let d=a,p=n.label.width;if(n.descr&&""!==n.descr.text){at("descr",n,l,it(Z,n.typeC4Shape.text),c),n.descr.Y=a+20,a=n.descr.Y+n.descr.height,p=Math.max(n.label.width,n.descr.width),d=a-5*n.descr.textLines}p+=Z.c4ShapePadding,n.width=Math.max(n.width||Z.width,p,Z.width),n.height=Math.max(n.height||Z.height,d,Z.height),n.margin=n.margin||Z.c4ShapeMargin,t.insert(n),U(e,n,Z)}t.bumpLastMargin(Z.c4ShapeMargin)};class lt{constructor(t,e){this.x=t,this.y=e}}let ot=function(t,e){let i=t.x,n=t.y,a=e.x,s=e.y,r=i+t.width/2,l=n+t.height/2,o=Math.abs(i-a),c=Math.abs(n-s),h=c/o,d=t.height/t.width,p=null;return n==s&&ia?p=new lt(i,l):i==a&&ns&&(p=new lt(r,n)),i>a&&n=h?new lt(i,l+h*t.width/2):new lt(r-o/c*t.height/2,n+t.height):i=h?new lt(i+t.width,l+h*t.width/2):new lt(r+o/c*t.height/2,n+t.height):is?p=d>=h?new lt(i+t.width,l-h*t.width/2):new lt(r+t.height/2*o/c,n):i>a&&n>s&&(p=d>=h?new lt(i,l-t.width/2*h):new lt(r-t.height/2*o/c,n)),p},ct=function(t,e){let i={x:0,y:0};i.x=e.x+e.width/2,i.y=e.y+e.height/2;let n=ot(t,i);return i.x=t.x+t.width/2,i.y=t.y+t.height/2,{startPoint:n,endPoint:ot(e,i)}};function ht(t,e,i,n,a){let s=new tt(a);s.data.widthLimit=i.data.widthLimit/Math.min(J,n.length);for(let[r,l]of n.entries()){let n=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=n,n=l.image.Y+l.image.height);let o=l.wrap&&Z.wrap,c=nt(Z);if(c.fontSize=c.fontSize+2,c.fontWeight="bold",at("label",l,o,c,s.data.widthLimit),l.label.Y=n+8,n=l.label.Y+l.label.height,l.type&&""!==l.type.text){l.type.text="["+l.type.text+"]",at("type",l,o,nt(Z),s.data.widthLimit),l.type.Y=n+5,n=l.type.Y+l.type.height}if(l.descr&&""!==l.descr.text){let t=nt(Z);t.fontSize=t.fontSize-2,at("descr",l,o,t,s.data.widthLimit),l.descr.Y=n+20,n=l.descr.Y+l.descr.height}if(0==r||r%J==0){let t=i.data.startx+Z.diagramMarginX,e=i.data.stopy+Z.diagramMarginY+n;s.setData(t,t,e,e)}else{let t=s.data.stopx!==s.data.startx?s.data.stopx+Z.diagramMarginX:s.data.startx,e=s.data.starty;s.setData(t,t,e,e)}s.name=l.alias;let h=a.db.getC4ShapeArray(l.alias),d=a.db.getC4ShapeKeys(l.alias);d.length>0&&rt(s,t,h,d),e=l.alias;let p=a.db.getBoundarys(e);p.length>0&&ht(t,e,s,p,a),"global"!==l.alias&&st(t,l,s),i.data.stopy=Math.max(s.data.stopy+Z.c4ShapeMargin,i.data.stopy),i.data.stopx=Math.max(s.data.stopx+Z.c4ShapeMargin,i.data.stopx),G=Math.max(G,i.data.stopx),H=Math.max(H,i.data.stopy)}}const dt={drawPersonOrSystemArray:rt,drawBoundary:st,setConf:et,draw:function(t,e,i,n){Z=a().c4;const s=a().securityLevel;let r;"sandbox"===s&&(r=h("#i"+e));const l=h("sandbox"===s?r.nodes()[0].contentDocument.body:"body");let c=n.db;n.db.setWrap(Z.wrap),K=c.getC4ShapeInRow(),J=c.getC4BoundaryInRow(),d.debug(`C:${JSON.stringify(Z,null,2)}`);const u="sandbox"===s?l.select(`[id="${e}"]`):h(`[id="${e}"]`);q(u),$(u),V(u);let y=new tt(n);y.setData(Z.diagramMarginX,Z.diagramMarginX,Z.diagramMarginY,Z.diagramMarginY),y.data.widthLimit=screen.availWidth,G=Z.diagramMarginX,H=Z.diagramMarginY;const f=n.db.getTitle();ht(u,"",y,n.db.getBoundarys(""),n),X(u),z(u),W(u),Q(u),function(t,e,i,n){let a=0;for(let r of e){a+=1;let t=r.wrap&&Z.wrap,e={fontFamily:(s=Z).messageFontFamily,fontSize:s.messageFontSize,fontWeight:s.messageFontWeight};"C4Dynamic"===n.db.getC4Type()&&(r.label.text=a+": "+r.label.text);let l=o(r.label.text,e);at("label",r,t,e,l),r.techn&&""!==r.techn.text&&(l=o(r.techn.text,e),at("techn",r,t,e,l)),r.descr&&""!==r.descr.text&&(l=o(r.descr.text,e),at("descr",r,t,e,l));let c=i(r.from),h=i(r.to),d=ct(c,h);r.startPoint=d.startPoint,r.endPoint=d.endPoint}var s;F(t,e,Z)}(u,n.db.getRels(),n.db.getC4Shape,n),y.data.stopx=G,y.data.stopy=H;const b=y.data;let g=b.stopy-b.starty+2*Z.diagramMarginY;const _=b.stopx-b.startx+2*Z.diagramMarginX;f&&u.append("text").text(f).attr("x",(b.stopx-b.startx)/2-4*Z.diagramMarginX).attr("y",b.starty+Z.diagramMarginY),p(u,g,_,Z.useMaxWidth);const x=f?60:0;u.attr("viewBox",b.startx-Z.diagramMarginX+" -"+(Z.diagramMarginY+x)+" "+_+" "+(g+x)),d.debug("models:",b)}},pt={parser:m,db:j,renderer:dt,styles:t=>`.person {\n stroke: ${t.personBorder};\n fill: ${t.personBkg};\n }\n`,init:t=>{dt.setConf(t.c4)}};export{pt as diagram}; diff --git a/assets/ch01-preface.html.4a75a4e8.js b/assets/ch01-preface.html.2015b6e6.js similarity index 99% rename from assets/ch01-preface.html.4a75a4e8.js rename to assets/ch01-preface.html.2015b6e6.js index 29d9687a0..ff57c5ab0 100644 --- a/assets/ch01-preface.html.4a75a4e8.js +++ b/assets/ch01-preface.html.2015b6e6.js @@ -1 +1 @@ -import{o as l,c as n,F as u,a,e as r}from"./app.755d843f.js";const e={},i=a("h1",{id:"【第-1-章】-小小白白话文",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#【第-1-章】-小小白白话文","aria-hidden":"true"},"#"),r(" 【第 1 章】 小小白白话文")],-1),h=a("h2",{id:"_1-1-这篇文档是写给谁的",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-1-这篇文档是写给谁的","aria-hidden":"true"},"#"),r(" 1.1 这篇文档是写给谁的?")],-1),s=a("p",null,[r("一句话:写给 "),a("strong",null,"① 零基础"),r(),a("strong",null,"② 希望学习自建 VPS"),r(" 的新人。")],-1),d=a("h2",{id:"_1-2-这篇文档不是写给谁的",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-2-这篇文档不是写给谁的","aria-hidden":"true"},"#"),r(" 1.2 这篇文档不是写给谁的?")],-1),t=a("p",null,"包括但不限于:各路大神大能、懒得自己折腾的小白、已经会折腾的高手、确定要用机场的土豪、确定要用一键脚本的逍遥派...... 总之只要有技术基础、或不愿不想自建的同学,您直接关闭本文即可,因为这篇文章大概是入不了您的法眼的,更可能会让您生一肚子闲气,那多划不来。",-1),o=a("h2",{id:"_1-3-郑重声明及其他声明",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-3-郑重声明及其他声明","aria-hidden":"true"},"#"),r(" 1.3 郑重声明及其他声明")],-1),p=a("p",null,"郑重声明:",-1),c=a("p",null,"鄙人技术奇菜无比,故本文必然挂一漏万破绽百出。您若发现问题还请温柔提醒,莫要人参公鸡。",-1),g=a("p",null,"免责声明:",-1),_=a("p",null,"本文内容请您自行判断是否可信可靠可用,若您根据本文内容建立和使用 VPS 服务器时出了任何问题和不良结果,鄙人概不负责。",-1),x=a("p",null,"啰嗦声明:",-1),b=a("p",null,"基于本文【零基础用户】的目标受众,许多内容会尽力详尽说明,所以语言偏啰嗦,请做好心理准备。",-1),f=a("h2",{id:"_1-4-为什么自建是个难题",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-4-为什么自建是个难题","aria-hidden":"true"},"#"),r(" 1.4 为什么自建是个难题?")],-1),S=a("p",null,"要回答这个问题,就需要稍微多说一点背景信息了。",-1),P=a("p",null,"一、科学上网这件事",-1),m=a("p",null,"科学上网这件事情,说来已经发展了近二十年(震惊!!!.jpg)。最初,自己稍微动动手即可(改改 host、连一下 ssh)、后来需要找一个网页代理,再后来需要写一个私有协议(比如 Shadowsocks)等等。",-1),V=a("p",null,"随着 GFW 技术这十几年来不断的迭代升级,若要完成【自己动手科学上网】这个目标,需要做的事情已经包括但不限于:",-1),L=a("ul",null,[a("li",null,"了解 Linux 系统基本命令"),a("li",null,"了解网络传输协议"),a("li",null,"有技术和经济能力完成 VPS 购买及管理"),a("li",null,"有技术和经济能力完成域名购买及管理"),a("li",null,"有技术能力完成 TLS 证书申请 等等。")],-1),T=a("p",null,"这就让【自建 VPS 科学上网】这个曾经简单的行为逐渐变成了令新人望而生畏的挑战。",-1),j=a("p",null,"二、零基础用户的无奈",-1),k=a("p",null,"零基础的非技术用户,如果完成上面这一连串的操作,势必要学习大量的知识,但稍微搜索之后,新人只怕会更加迷茫:大量的信息散布在互联网的各个角落:博客、问答网站、群组、论坛、GitHub、Telegram、YouTube 等等等等)。这些信息纷乱复杂、水平良莠不齐、甚至可能互相矛盾。基本上就是不把新人彻底弄晕誓不罢休。",-1),F=a("p",null,"面对这些杂乱无章的信息,新人突然就从【信息匮乏】变成了【信息过剩】。若是几番连蒙带猜的折腾以失败告终(大概率如此)的话,他的积极性势必大受挫折。在这个过程中,若他又恰好去了一些不太友好的地方去求助,恐怕还要雪上加霜的被嘲讽一番:“这么菜,用机场不就行了,瞎折腾什么啊!”、“先去学会 Linux 再回来问吧”。",-1),G=a("p",null,"这时候,大概也只有一声“呵呵”可以表达心情了。",-1),I=a("h2",{id:"_1-5-用机场不就行了",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-5-用机场不就行了","aria-hidden":"true"},"#"),r(" 1.5 “用机场不就行了?”")],-1),Y=a("p",null,"首先,我想反问一下那些冷嘲热讽的人:“用机场”真的就是万灵药吗?",-1),q=a("p",null,"其次,我认为“不懂”和“不想懂”是有本质区别的。态度恶劣的巨婴伸手党自然惹人厌烦,但真心自学却不得要领的人不该受到无端的白眼和歧视,也正是这种对新人不加区分的恶劣社区氛围促使我写下本文。那么闲话少说,我们来看看机场的优势与劣势究竟如何:",-1),w=a("p",null,"一、“机场“的优势",-1),y=a("p",null,"所谓“机场”,就是“线路提供商”。他负责完成 1.4 提到的那一串技术操作和管理,用户则付费获得使用权。所以,它的优点至少有:",-1),C=a("ol",null,[a("li",null,[a("strong",null,"用户操作简单"),r(":扫码操作、一键添加规则等")]),a("li",null,[a("strong",null,"线路选择多"),r(":可解锁不同国家、地区的网络服务;比如 iplc 等专线服务、游戏加速服务等")]),a("li",null,[a("strong",null,"接入节点多"),r(":所以抵抗节点封锁的能力强一些,封了一个就换下一个")])],-1),H=a("p",null,"二、“机场”的风险",-1),W=a("p",null,"“方便”这枚硬币的另一面就是“风险”,基于“机场”的技术特点和市场情况,它的风险至少有:",-1),X=a("ol",null,[a("li",null,[a("strong",null,"“机场”可完全获得用户信息"),r(":用户在网上的所有痕迹,都【必然】经过且【非常可能】长期存储在其服务器上,这些记录无法受到任何具备法律效力的用户隐私协议的约束("),a("strong",null,"窥视、记录你的一举一动"),r(")")]),a("li",null,[a("strong",null,"“机场”缺乏市场管理"),r(":不可避免存在着以欺诈为目标的恶意商家("),a("strong",null,"主动跑路"),r(")")]),a("li",null,[a("strong",null,"“机场”面临监管压力"),r(":大机场相对有保障的同时,也无法避免树大招风。2020 年间,已经有几个大机场停运、跑路的事件发生,用户的正常使用受到严重干扰("),a("strong",null,"被动跑路"),r(")")]),a("li",null,[a("strong",null,"“机场”技术水平难以确定"),r(":线路质量良莠不齐,挂羊头卖狗肉的现象屡见不鲜("),a("strong",null,"速度慢、掉线多、连不上"),r(")")])],-1),v=a("h2",{id:"_1-6-那么你到底要不要自建呢",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-6-那么你到底要不要自建呢","aria-hidden":"true"},"#"),r(" 1.6 那么你到底要不要自建呢?")],-1),z=a("p",null,"现在,你已经看到了机场的优势和风险,要用什么,就请各位充分思考并自行决定。毕竟,最适合你的方案才是最好的方案。",-1),A=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch01-img01-choice.8b5c938e.png",alt:"It's Your Choice!"})],-1),B=a("ol",null,[a("li",null,[a("p",null,"如果决定使用机场的话,现在,你可以关闭本文了。")]),a("li",null,[a("p",null,"如果你决定自建,那就请继续阅读后面的章节吧!!")])],-1),D=a("p",null,[r("总之,本文的目标就是成为零基础用户的知识起点,提供对每一步充分的讲解和演示,清清楚楚(甚至"),a("strong",null,"婆婆妈妈、絮絮叨叨、啰啰嗦嗦"),r(")的协助新人完成【"),a("strong",null,"从输入第一条命令开始,完成 VPS 服务器部署,并成功在客户端完成科学上网"),r("】的全程。并在这个过程中帮助新人逐步接触和熟悉 Linux 的基础操作,为之后的进一步自学打下基础。")],-1),E=a("h2",{id:"_1-7-题外啰嗦几句",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-7-题外啰嗦几句","aria-hidden":"true"},"#"),r(" 1.7 题外啰嗦几句")],-1),J=a("ol",null,[a("li",null,[a("p",null,"墙外的信息泥沙俱下,请务必学会理性、独立的思辨,不要随意站队,不要轻信猎奇的信息。")]),a("li",null,[a("p",null,"衷心希望大家获得更顺畅的网络后,可以获取更新鲜的知识、更丰富的娱乐、接触更美好的世界、结交更多志同道合的朋友,但不要成为任何有不可告人目的之人的替罪羊。")]),a("li",null,[a("p",null,"你的互联网身份依然是你的身份,绝对的匿名化是极为困难的,所以请务必遵守你个人所在地区和 IP 所在地区的相关法律法规。无论何时,自我保护都是最基本的底线。")])],-1),K=a("h2",{id:"_1-8-你的进度",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-8-你的进度","aria-hidden":"true"},"#"),r(" 1.8 你的进度")],-1),M=a("blockquote",null,[a("p",null,"⬛⬜⬜⬜⬜⬜⬜⬜ 12.5%")],-1);e.render=function(a,r){return l(),n(u,null,[i,h,s,d,t,o,p,c,g,_,x,b,f,S,P,m,V,L,T,j,k,F,G,I,Y,q,w,y,C,H,W,X,v,z,A,B,D,E,J,K,M],64)};export default e; +import{o as l,c as n,F as u,a,e as r}from"./app.48111a85.js";const e={},i=a("h1",{id:"【第-1-章】-小小白白话文",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#【第-1-章】-小小白白话文","aria-hidden":"true"},"#"),r(" 【第 1 章】 小小白白话文")],-1),h=a("h2",{id:"_1-1-这篇文档是写给谁的",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-1-这篇文档是写给谁的","aria-hidden":"true"},"#"),r(" 1.1 这篇文档是写给谁的?")],-1),s=a("p",null,[r("一句话:写给 "),a("strong",null,"① 零基础"),r(),a("strong",null,"② 希望学习自建 VPS"),r(" 的新人。")],-1),d=a("h2",{id:"_1-2-这篇文档不是写给谁的",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-2-这篇文档不是写给谁的","aria-hidden":"true"},"#"),r(" 1.2 这篇文档不是写给谁的?")],-1),t=a("p",null,"包括但不限于:各路大神大能、懒得自己折腾的小白、已经会折腾的高手、确定要用机场的土豪、确定要用一键脚本的逍遥派...... 总之只要有技术基础、或不愿不想自建的同学,您直接关闭本文即可,因为这篇文章大概是入不了您的法眼的,更可能会让您生一肚子闲气,那多划不来。",-1),o=a("h2",{id:"_1-3-郑重声明及其他声明",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-3-郑重声明及其他声明","aria-hidden":"true"},"#"),r(" 1.3 郑重声明及其他声明")],-1),p=a("p",null,"郑重声明:",-1),c=a("p",null,"鄙人技术奇菜无比,故本文必然挂一漏万破绽百出。您若发现问题还请温柔提醒,莫要人参公鸡。",-1),g=a("p",null,"免责声明:",-1),_=a("p",null,"本文内容请您自行判断是否可信可靠可用,若您根据本文内容建立和使用 VPS 服务器时出了任何问题和不良结果,鄙人概不负责。",-1),x=a("p",null,"啰嗦声明:",-1),b=a("p",null,"基于本文【零基础用户】的目标受众,许多内容会尽力详尽说明,所以语言偏啰嗦,请做好心理准备。",-1),f=a("h2",{id:"_1-4-为什么自建是个难题",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-4-为什么自建是个难题","aria-hidden":"true"},"#"),r(" 1.4 为什么自建是个难题?")],-1),S=a("p",null,"要回答这个问题,就需要稍微多说一点背景信息了。",-1),P=a("p",null,"一、科学上网这件事",-1),m=a("p",null,"科学上网这件事情,说来已经发展了近二十年(震惊!!!.jpg)。最初,自己稍微动动手即可(改改 host、连一下 ssh)、后来需要找一个网页代理,再后来需要写一个私有协议(比如 Shadowsocks)等等。",-1),V=a("p",null,"随着 GFW 技术这十几年来不断的迭代升级,若要完成【自己动手科学上网】这个目标,需要做的事情已经包括但不限于:",-1),L=a("ul",null,[a("li",null,"了解 Linux 系统基本命令"),a("li",null,"了解网络传输协议"),a("li",null,"有技术和经济能力完成 VPS 购买及管理"),a("li",null,"有技术和经济能力完成域名购买及管理"),a("li",null,"有技术能力完成 TLS 证书申请 等等。")],-1),T=a("p",null,"这就让【自建 VPS 科学上网】这个曾经简单的行为逐渐变成了令新人望而生畏的挑战。",-1),j=a("p",null,"二、零基础用户的无奈",-1),k=a("p",null,"零基础的非技术用户,如果完成上面这一连串的操作,势必要学习大量的知识,但稍微搜索之后,新人只怕会更加迷茫:大量的信息散布在互联网的各个角落:博客、问答网站、群组、论坛、GitHub、Telegram、YouTube 等等等等)。这些信息纷乱复杂、水平良莠不齐、甚至可能互相矛盾。基本上就是不把新人彻底弄晕誓不罢休。",-1),F=a("p",null,"面对这些杂乱无章的信息,新人突然就从【信息匮乏】变成了【信息过剩】。若是几番连蒙带猜的折腾以失败告终(大概率如此)的话,他的积极性势必大受挫折。在这个过程中,若他又恰好去了一些不太友好的地方去求助,恐怕还要雪上加霜的被嘲讽一番:“这么菜,用机场不就行了,瞎折腾什么啊!”、“先去学会 Linux 再回来问吧”。",-1),G=a("p",null,"这时候,大概也只有一声“呵呵”可以表达心情了。",-1),I=a("h2",{id:"_1-5-用机场不就行了",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-5-用机场不就行了","aria-hidden":"true"},"#"),r(" 1.5 “用机场不就行了?”")],-1),Y=a("p",null,"首先,我想反问一下那些冷嘲热讽的人:“用机场”真的就是万灵药吗?",-1),q=a("p",null,"其次,我认为“不懂”和“不想懂”是有本质区别的。态度恶劣的巨婴伸手党自然惹人厌烦,但真心自学却不得要领的人不该受到无端的白眼和歧视,也正是这种对新人不加区分的恶劣社区氛围促使我写下本文。那么闲话少说,我们来看看机场的优势与劣势究竟如何:",-1),w=a("p",null,"一、“机场“的优势",-1),y=a("p",null,"所谓“机场”,就是“线路提供商”。他负责完成 1.4 提到的那一串技术操作和管理,用户则付费获得使用权。所以,它的优点至少有:",-1),C=a("ol",null,[a("li",null,[a("strong",null,"用户操作简单"),r(":扫码操作、一键添加规则等")]),a("li",null,[a("strong",null,"线路选择多"),r(":可解锁不同国家、地区的网络服务;比如 iplc 等专线服务、游戏加速服务等")]),a("li",null,[a("strong",null,"接入节点多"),r(":所以抵抗节点封锁的能力强一些,封了一个就换下一个")])],-1),H=a("p",null,"二、“机场”的风险",-1),W=a("p",null,"“方便”这枚硬币的另一面就是“风险”,基于“机场”的技术特点和市场情况,它的风险至少有:",-1),X=a("ol",null,[a("li",null,[a("strong",null,"“机场”可完全获得用户信息"),r(":用户在网上的所有痕迹,都【必然】经过且【非常可能】长期存储在其服务器上,这些记录无法受到任何具备法律效力的用户隐私协议的约束("),a("strong",null,"窥视、记录你的一举一动"),r(")")]),a("li",null,[a("strong",null,"“机场”缺乏市场管理"),r(":不可避免存在着以欺诈为目标的恶意商家("),a("strong",null,"主动跑路"),r(")")]),a("li",null,[a("strong",null,"“机场”面临监管压力"),r(":大机场相对有保障的同时,也无法避免树大招风。2020 年间,已经有几个大机场停运、跑路的事件发生,用户的正常使用受到严重干扰("),a("strong",null,"被动跑路"),r(")")]),a("li",null,[a("strong",null,"“机场”技术水平难以确定"),r(":线路质量良莠不齐,挂羊头卖狗肉的现象屡见不鲜("),a("strong",null,"速度慢、掉线多、连不上"),r(")")])],-1),v=a("h2",{id:"_1-6-那么你到底要不要自建呢",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-6-那么你到底要不要自建呢","aria-hidden":"true"},"#"),r(" 1.6 那么你到底要不要自建呢?")],-1),z=a("p",null,"现在,你已经看到了机场的优势和风险,要用什么,就请各位充分思考并自行决定。毕竟,最适合你的方案才是最好的方案。",-1),A=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch01-img01-choice.8b5c938e.png",alt:"It's Your Choice!"})],-1),B=a("ol",null,[a("li",null,[a("p",null,"如果决定使用机场的话,现在,你可以关闭本文了。")]),a("li",null,[a("p",null,"如果你决定自建,那就请继续阅读后面的章节吧!!")])],-1),D=a("p",null,[r("总之,本文的目标就是成为零基础用户的知识起点,提供对每一步充分的讲解和演示,清清楚楚(甚至"),a("strong",null,"婆婆妈妈、絮絮叨叨、啰啰嗦嗦"),r(")的协助新人完成【"),a("strong",null,"从输入第一条命令开始,完成 VPS 服务器部署,并成功在客户端完成科学上网"),r("】的全程。并在这个过程中帮助新人逐步接触和熟悉 Linux 的基础操作,为之后的进一步自学打下基础。")],-1),E=a("h2",{id:"_1-7-题外啰嗦几句",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-7-题外啰嗦几句","aria-hidden":"true"},"#"),r(" 1.7 题外啰嗦几句")],-1),J=a("ol",null,[a("li",null,[a("p",null,"墙外的信息泥沙俱下,请务必学会理性、独立的思辨,不要随意站队,不要轻信猎奇的信息。")]),a("li",null,[a("p",null,"衷心希望大家获得更顺畅的网络后,可以获取更新鲜的知识、更丰富的娱乐、接触更美好的世界、结交更多志同道合的朋友,但不要成为任何有不可告人目的之人的替罪羊。")]),a("li",null,[a("p",null,"你的互联网身份依然是你的身份,绝对的匿名化是极为困难的,所以请务必遵守你个人所在地区和 IP 所在地区的相关法律法规。无论何时,自我保护都是最基本的底线。")])],-1),K=a("h2",{id:"_1-8-你的进度",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_1-8-你的进度","aria-hidden":"true"},"#"),r(" 1.8 你的进度")],-1),M=a("blockquote",null,[a("p",null,"⬛⬜⬜⬜⬜⬜⬜⬜ 12.5%")],-1);e.render=function(a,r){return l(),n(u,null,[i,h,s,d,t,o,p,c,g,_,x,b,f,S,P,m,V,L,T,j,k,F,G,I,Y,q,w,y,C,H,W,X,v,z,A,B,D,E,J,K,M],64)};export default e; diff --git a/assets/ch01-preface.html.b8e2f249.js b/assets/ch01-preface.html.c3c719d6.js similarity index 99% rename from assets/ch01-preface.html.b8e2f249.js rename to assets/ch01-preface.html.c3c719d6.js index 295624a76..4d0558305 100644 --- a/assets/ch01-preface.html.b8e2f249.js +++ b/assets/ch01-preface.html.c3c719d6.js @@ -1 +1 @@ -import{o as e,c as t,F as n,a as i,e as a}from"./app.755d843f.js";const o={},l=i("h1",{id:"chapter-1-simple-and-plain-language",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#chapter-1-simple-and-plain-language","aria-hidden":"true"},"#"),a(" [Chapter 1] Simple and Plain Language")],-1),s=i("h2",{id:"_1-1-who-is-this-document-written-for",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-1-who-is-this-document-written-for","aria-hidden":"true"},"#"),a(" 1.1 Who is this document written for?")],-1),r=i("p",null,[a("One sentence: Written for newbies who are "),i("strong",null,"(1) absolute beginners"),a(" and "),i("strong",null,"(2) interested in learning how to build their own VPS"),a(".")],-1),h=i("h2",{id:"_1-2-who-is-this-document-not-written-for",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-2-who-is-this-document-not-written-for","aria-hidden":"true"},"#"),a(" 1.2 Who is this document not written for?")],-1),u=i("p",null,"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),d=i("h2",{id:"_1-3-declaration-and-other-statements",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-3-declaration-and-other-statements","aria-hidden":"true"},"#"),a(" 1.3 Declaration and Other Statements")],-1),c=i("p",null,"Declaration:",-1),p=i("p",null,"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.",-1),f=i("p",null,"Disclaimer:",-1),y=i("p",null,"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.",-1),m=i("p",null,"Verbose statement:",-1),g=i("p",null,'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),b=i("h2",{id:"_1-4-why-is-self-hosting-a-challenge",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-4-why-is-self-hosting-a-challenge","aria-hidden":"true"},"#"),a(" 1.4 Why is self-hosting a challenge?")],-1),w=i("p",null,"To answer this question, we need to provide a little more background information.",-1),v=i("ol",null,[i("li",null,"On the matter of accessing the internet through scientific means")],-1),k=i("p",null,"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.",-1),x=i("p",null,"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:",-1),I=i("ul",null,[i("li",null,"Understand basic Linux commands"),i("li",null,"Understand network transmission protocols"),i("li",null,"Have the technical and financial ability to purchase and manage a VPS"),i("li",null,"Have the technical and financial ability to purchase and manage a domain name"),i("li",null,"Have the technical ability to apply for a TLS certificate, and so on.")],-1),S=i("p",null,"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),T=i("ol",{start:"2"},[i("li",null,"Helplessness of Zero-based Users")],-1),_=i("p",null,"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.",-1),j=i("p",null,'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."',-1),A=i("p",null,'At this moment, probably only an "hehe" can express the mood.',-1),P=i("h2",{id:"_1-5-why-not-just-use-the-airport",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-5-why-not-just-use-the-airport","aria-hidden":"true"},"#"),a(' 1.5 "Why not just use the airport?"')],-1),W=i("p",null,"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?",-1),q=i("p",null,'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),H=i("ol",null,[i("li",null,"稳定性高:机场节点数量多,分布广泛,避免了单点故障的风险,保证了整个网络的稳定性。"),i("li",null,"速度快:机场的节点通常采用高速服务器和优化的网络架构,网络速度较快,能够满足用户的高速上网需求。"),i("li",null,"安全性高:机场通常会采用严格的安全措施,如流量加密、防火墙等,保护用户数据的安全性。"),i("li",null,"稳定性高:机场通常采用专业的运维团队进行管理和维护,保证了服务的稳定性和可靠性。"),i("li",null,"服务质量高:机场通常会提供完善的客户服务,及时解决用户的问题和反馈,提升用户的满意度。")],-1),L=i("p",null,'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),V=i("ol",null,[i("li",null,[i("strong",null,"Simple User Operation"),a(": Scan code operation, one-click rule addition, etc.")]),i("li",null,[i("strong",null,"Multiple Line Options"),a(": Can unlock network services in different countries and regions, such as iplc dedicated line services, game acceleration services, etc.")]),i("li",null,[i("strong",null,"Multiple Access Nodes"),a(": Therefore, it has a stronger ability to resist node blocking, if one is blocked, just switch to another one.")])],-1),z=i("ul",null,[i("li",null,'Risks of "Airport"')],-1),F=i("p",null,"\"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),O=i("ol",null,[i("li",null,'"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")'),i("li",null,'"Airport" lacks market management: There are inevitably malicious merchants who target fraud. ("Actively run away")'),i("li",null,'"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")'),i("li",null,'"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),Y=i("h2",{id:"_1-6-so-should-you-build-your-own-website",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-6-so-should-you-build-your-own-website","aria-hidden":"true"},"#"),a(" 1.6 So should you build your own website?")],-1),C=i("p",null,"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.",-1),D=i("p",null,[i("img",{src:"/Xray-docs-next/assets/ch01-img01-choice.8b5c938e.png",alt:"It's Your Choice!"})],-1),U=i("ol",null,[i("li",null,[i("p",null,"If you decide to use the airport, you can close this article now.")]),i("li",null,[i("p",null,"If you decide to build it yourself, please continue reading the following chapters!")])],-1),G=i("p",null,"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),M=i("h2",{id:"_1-7-some-digressions",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-7-some-digressions","aria-hidden":"true"},"#"),a(" 1.7 Some digressions")],-1),B=i("ol",null,[i("li",null,[i("p",null,"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.")]),i("li",null,[i("p",null,"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.")]),i("li",null,[i("p",null,"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),N=i("h2",{id:"_1-8-your-progress",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-8-your-progress","aria-hidden":"true"},"#"),a(" 1.8 Your Progress")],-1),Q=i("blockquote",null,[i("p",null,"⬛⬜⬜⬜⬜⬜⬜⬜ 12.5%")],-1);o.render=function(i,a){return e(),t(n,null,[l,s,r,h,u,d,c,p,f,y,m,g,b,w,v,k,x,I,S,T,_,j,A,P,W,q,H,L,V,z,F,O,Y,C,D,U,G,M,B,N,Q],64)};export default o; +import{o as e,c as t,F as n,a as i,e as a}from"./app.48111a85.js";const o={},l=i("h1",{id:"chapter-1-simple-and-plain-language",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#chapter-1-simple-and-plain-language","aria-hidden":"true"},"#"),a(" [Chapter 1] Simple and Plain Language")],-1),s=i("h2",{id:"_1-1-who-is-this-document-written-for",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-1-who-is-this-document-written-for","aria-hidden":"true"},"#"),a(" 1.1 Who is this document written for?")],-1),r=i("p",null,[a("One sentence: Written for newbies who are "),i("strong",null,"(1) absolute beginners"),a(" and "),i("strong",null,"(2) interested in learning how to build their own VPS"),a(".")],-1),h=i("h2",{id:"_1-2-who-is-this-document-not-written-for",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-2-who-is-this-document-not-written-for","aria-hidden":"true"},"#"),a(" 1.2 Who is this document not written for?")],-1),u=i("p",null,"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),d=i("h2",{id:"_1-3-declaration-and-other-statements",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-3-declaration-and-other-statements","aria-hidden":"true"},"#"),a(" 1.3 Declaration and Other Statements")],-1),c=i("p",null,"Declaration:",-1),p=i("p",null,"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.",-1),f=i("p",null,"Disclaimer:",-1),y=i("p",null,"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.",-1),m=i("p",null,"Verbose statement:",-1),g=i("p",null,'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),b=i("h2",{id:"_1-4-why-is-self-hosting-a-challenge",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-4-why-is-self-hosting-a-challenge","aria-hidden":"true"},"#"),a(" 1.4 Why is self-hosting a challenge?")],-1),w=i("p",null,"To answer this question, we need to provide a little more background information.",-1),v=i("ol",null,[i("li",null,"On the matter of accessing the internet through scientific means")],-1),k=i("p",null,"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.",-1),x=i("p",null,"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:",-1),I=i("ul",null,[i("li",null,"Understand basic Linux commands"),i("li",null,"Understand network transmission protocols"),i("li",null,"Have the technical and financial ability to purchase and manage a VPS"),i("li",null,"Have the technical and financial ability to purchase and manage a domain name"),i("li",null,"Have the technical ability to apply for a TLS certificate, and so on.")],-1),S=i("p",null,"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),T=i("ol",{start:"2"},[i("li",null,"Helplessness of Zero-based Users")],-1),_=i("p",null,"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.",-1),j=i("p",null,'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."',-1),A=i("p",null,'At this moment, probably only an "hehe" can express the mood.',-1),P=i("h2",{id:"_1-5-why-not-just-use-the-airport",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-5-why-not-just-use-the-airport","aria-hidden":"true"},"#"),a(' 1.5 "Why not just use the airport?"')],-1),W=i("p",null,"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?",-1),q=i("p",null,'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),H=i("ol",null,[i("li",null,"稳定性高:机场节点数量多,分布广泛,避免了单点故障的风险,保证了整个网络的稳定性。"),i("li",null,"速度快:机场的节点通常采用高速服务器和优化的网络架构,网络速度较快,能够满足用户的高速上网需求。"),i("li",null,"安全性高:机场通常会采用严格的安全措施,如流量加密、防火墙等,保护用户数据的安全性。"),i("li",null,"稳定性高:机场通常采用专业的运维团队进行管理和维护,保证了服务的稳定性和可靠性。"),i("li",null,"服务质量高:机场通常会提供完善的客户服务,及时解决用户的问题和反馈,提升用户的满意度。")],-1),L=i("p",null,'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),V=i("ol",null,[i("li",null,[i("strong",null,"Simple User Operation"),a(": Scan code operation, one-click rule addition, etc.")]),i("li",null,[i("strong",null,"Multiple Line Options"),a(": Can unlock network services in different countries and regions, such as iplc dedicated line services, game acceleration services, etc.")]),i("li",null,[i("strong",null,"Multiple Access Nodes"),a(": Therefore, it has a stronger ability to resist node blocking, if one is blocked, just switch to another one.")])],-1),z=i("ul",null,[i("li",null,'Risks of "Airport"')],-1),F=i("p",null,"\"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),O=i("ol",null,[i("li",null,'"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")'),i("li",null,'"Airport" lacks market management: There are inevitably malicious merchants who target fraud. ("Actively run away")'),i("li",null,'"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")'),i("li",null,'"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),Y=i("h2",{id:"_1-6-so-should-you-build-your-own-website",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-6-so-should-you-build-your-own-website","aria-hidden":"true"},"#"),a(" 1.6 So should you build your own website?")],-1),C=i("p",null,"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.",-1),D=i("p",null,[i("img",{src:"/Xray-docs-next/assets/ch01-img01-choice.8b5c938e.png",alt:"It's Your Choice!"})],-1),U=i("ol",null,[i("li",null,[i("p",null,"If you decide to use the airport, you can close this article now.")]),i("li",null,[i("p",null,"If you decide to build it yourself, please continue reading the following chapters!")])],-1),G=i("p",null,"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),M=i("h2",{id:"_1-7-some-digressions",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-7-some-digressions","aria-hidden":"true"},"#"),a(" 1.7 Some digressions")],-1),B=i("ol",null,[i("li",null,[i("p",null,"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.")]),i("li",null,[i("p",null,"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.")]),i("li",null,[i("p",null,"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),N=i("h2",{id:"_1-8-your-progress",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#_1-8-your-progress","aria-hidden":"true"},"#"),a(" 1.8 Your Progress")],-1),Q=i("blockquote",null,[i("p",null,"⬛⬜⬜⬜⬜⬜⬜⬜ 12.5%")],-1);o.render=function(i,a){return e(),t(n,null,[l,s,r,h,u,d,c,p,f,y,m,g,b,w,v,k,x,I,S,T,_,j,A,P,W,q,H,L,V,z,F,O,Y,C,D,U,G,M,B,N,Q],64)};export default o; diff --git a/assets/ch02-preparation.html.f06ab21a.js b/assets/ch02-preparation.html.61783a98.js similarity index 93% rename from assets/ch02-preparation.html.f06ab21a.js rename to assets/ch02-preparation.html.61783a98.js index 2ad1ae7f0..e45948e70 100644 --- a/assets/ch02-preparation.html.f06ab21a.js +++ b/assets/ch02-preparation.html.61783a98.js @@ -1 +1 @@ -import{r as l,o as n,c as e,a,b as i,F as u,e as r}from"./app.755d843f.js";const t={},o=a("h1",{id:"【第-2-章】原料准备篇",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#【第-2-章】原料准备篇","aria-hidden":"true"},"#"),r(" 【第 2 章】原料准备篇")],-1),s=a("p",null,"这一章比较特殊,因为涉及到金钱交易行为,本文基于项目的中立立场,不做具体的推荐。我能做的,是告诉你需要准备哪些东西。",-1),c=a("h2",{id:"_2-1-获取一台-vps",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2-1-获取一台-vps","aria-hidden":"true"},"#"),r(" 2.1 获取一台 VPS")],-1),d=a("p",null,"你需要获取一台健康的、IP 没有被墙的 VPS,并在管理后台做下面这些基础准备:",-1),h=a("ol",null,[a("li",null,"在 VPS 的后台安装 Debian 10 64bit 系统"),a("li",null,[r("小本本记下 VPS 的 IP 地址(本文会用 "),a("code",null,'"100.200.300.400"'),r(" 来表示)"),a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"提示"),a("p",null,"这是一个故意写错的非法 IP,请替换成你的真实 IP)")])]),a("li",null,"小本本记下 VPS 的 SSH 远程登陆端口(Port)"),a("li",null,"小本本记下 SSH 远程登录的用户名和密码")],-1),p=a("p",null,"购买 VPS 是一个比较复杂的事情,建议先去学习一下相关知识,选择适合自己的经济能力和线路需求的即可。另外可以选择薅一些国际大厂的羊毛(比如甲骨文和谷歌提供的永久免费或限时免费的套餐)。总之,务必量力而行。",-1),m=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[r("关于选择 Debian 10 作为操作系统,这里稍微多说一句:不管你在网上听说了什么,不管哪个大神告诉你 XXX 版的 Linux 更好、XXX 版的 Linux 更牛,这些 Linux 的派系之争"),a("strong",null,"跟现在的你半毛钱关系也没有"),r("!使用 Debian 10 足以让你的 VPS 服务器在安全、稳健运行的同时得到足够的优化(如 cloud 专用内核、及时的 bbr 支持等)。等你对 Linux 熟悉之后,再回头去尝试其他的 Linux 发行版也不迟。")])],-1),S=a("h2",{id:"_2-2-获取一个心仪的域名",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2-2-获取一个心仪的域名","aria-hidden":"true"},"#"),r(" 2.2 获取一个心仪的域名")],-1),P=a("p",null,"你需要获取一个域名、并在 DNS 设置中添加一条 A 记录,指向你 VPS 的 IP 地址",-1),b=a("ol",null,[a("li",null,[r("请选择靠谱的国际域名服务商。选择一些常见的域名后缀就行,注意不要用 "),a("code",null,".cn"),r(" 后缀。")]),a("li",null,[r("在 DNS 设置中,添加一条指向你 VPS 的 IP 地址的 A 记录(A 记录的名字可以随便起,本文会用 "),a("code",null,'"a-name"'),r(" 来表示。完整的域名则会用 "),a("code",null,'"二级域名.你的域名.com"'),r(" 或者 "),a("code",null,'"a-name.yourdomain.com"'),r(" 来表示)。效果如下图:")])],-1),f=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch02-img01-a-name.0e89a8f1.png",alt:"添加A记录"})],-1),x=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"提示"),a("p",null,[r("这"),a("strong",null,"不是"),r("一个真实可用的网址,请替换成你的真实网址")])],-1),g=a("h2",{id:"_2-3-你本地电脑上需要安装的软件",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2-3-你本地电脑上需要安装的软件","aria-hidden":"true"},"#"),r(" 2.3 你本地电脑上需要安装的软件")],-1),_=a("p",null,"SSH 远程登录工具",-1),V=r("Windows: "),L={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},k=r("PuTTY"),w=a("li",null,"macOS/Linux: Terminal",-1),X=a("p",null,"远程文件拷贝工具",-1),v=r("Windows: "),I={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},D=r("WinSCP"),A=a("li",null,"macOS/Linux: Terminal",-1),O=a("p",null,"靠谱的文本编辑器",-1),T=r("Windows/macOS/Linux: "),W={href:"https://code.visualstudio.com",target:"_blank",rel:"noopener noreferrer"},y=r("VSCode"),H=a("h2",{id:"_2-4-你的进度",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2-4-你的进度","aria-hidden":"true"},"#"),r(" 2.4 你的进度")],-1),C=a("p",null,"如果上面的原材料你都准备好了的话,你已经拿到了开启新世界大门的钥匙。那还等什么,让我们快点进入下一章,走进这扇门吧!",-1),N=a("blockquote",null,[a("p",null,"⬛⬛⬜⬜⬜⬜⬜⬜ 25%")],-1);t.render=function(r,t){const j=l("OutboundLink");return n(),e(u,null,[o,s,c,d,h,p,m,S,P,b,f,x,g,a("ol",null,[a("li",null,[_,a("ul",null,[a("li",null,[V,a("a",L,[k,i(j)])]),w])]),a("li",null,[X,a("ul",null,[a("li",null,[v,a("a",I,[D,i(j)])]),A])]),a("li",null,[O,a("ul",null,[a("li",null,[T,a("a",W,[y,i(j)])])])])]),H,C,N],64)};export default t; +import{r as l,o as n,c as e,a,b as i,F as u,e as r}from"./app.48111a85.js";const t={},o=a("h1",{id:"【第-2-章】原料准备篇",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#【第-2-章】原料准备篇","aria-hidden":"true"},"#"),r(" 【第 2 章】原料准备篇")],-1),s=a("p",null,"这一章比较特殊,因为涉及到金钱交易行为,本文基于项目的中立立场,不做具体的推荐。我能做的,是告诉你需要准备哪些东西。",-1),c=a("h2",{id:"_2-1-获取一台-vps",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2-1-获取一台-vps","aria-hidden":"true"},"#"),r(" 2.1 获取一台 VPS")],-1),d=a("p",null,"你需要获取一台健康的、IP 没有被墙的 VPS,并在管理后台做下面这些基础准备:",-1),h=a("ol",null,[a("li",null,"在 VPS 的后台安装 Debian 10 64bit 系统"),a("li",null,[r("小本本记下 VPS 的 IP 地址(本文会用 "),a("code",null,'"100.200.300.400"'),r(" 来表示)"),a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"提示"),a("p",null,"这是一个故意写错的非法 IP,请替换成你的真实 IP)")])]),a("li",null,"小本本记下 VPS 的 SSH 远程登陆端口(Port)"),a("li",null,"小本本记下 SSH 远程登录的用户名和密码")],-1),p=a("p",null,"购买 VPS 是一个比较复杂的事情,建议先去学习一下相关知识,选择适合自己的经济能力和线路需求的即可。另外可以选择薅一些国际大厂的羊毛(比如甲骨文和谷歌提供的永久免费或限时免费的套餐)。总之,务必量力而行。",-1),m=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[r("关于选择 Debian 10 作为操作系统,这里稍微多说一句:不管你在网上听说了什么,不管哪个大神告诉你 XXX 版的 Linux 更好、XXX 版的 Linux 更牛,这些 Linux 的派系之争"),a("strong",null,"跟现在的你半毛钱关系也没有"),r("!使用 Debian 10 足以让你的 VPS 服务器在安全、稳健运行的同时得到足够的优化(如 cloud 专用内核、及时的 bbr 支持等)。等你对 Linux 熟悉之后,再回头去尝试其他的 Linux 发行版也不迟。")])],-1),S=a("h2",{id:"_2-2-获取一个心仪的域名",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2-2-获取一个心仪的域名","aria-hidden":"true"},"#"),r(" 2.2 获取一个心仪的域名")],-1),P=a("p",null,"你需要获取一个域名、并在 DNS 设置中添加一条 A 记录,指向你 VPS 的 IP 地址",-1),b=a("ol",null,[a("li",null,[r("请选择靠谱的国际域名服务商。选择一些常见的域名后缀就行,注意不要用 "),a("code",null,".cn"),r(" 后缀。")]),a("li",null,[r("在 DNS 设置中,添加一条指向你 VPS 的 IP 地址的 A 记录(A 记录的名字可以随便起,本文会用 "),a("code",null,'"a-name"'),r(" 来表示。完整的域名则会用 "),a("code",null,'"二级域名.你的域名.com"'),r(" 或者 "),a("code",null,'"a-name.yourdomain.com"'),r(" 来表示)。效果如下图:")])],-1),x=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch02-img01-a-name.0e89a8f1.png",alt:"添加A记录"})],-1),f=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"提示"),a("p",null,[r("这"),a("strong",null,"不是"),r("一个真实可用的网址,请替换成你的真实网址")])],-1),g=a("h2",{id:"_2-3-你本地电脑上需要安装的软件",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2-3-你本地电脑上需要安装的软件","aria-hidden":"true"},"#"),r(" 2.3 你本地电脑上需要安装的软件")],-1),_=a("p",null,"SSH 远程登录工具",-1),V=r("Windows: "),L={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},k=r("PuTTY"),w=a("li",null,"macOS/Linux: Terminal",-1),X=a("p",null,"远程文件拷贝工具",-1),v=r("Windows: "),I={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},D=r("WinSCP"),A=a("li",null,"macOS/Linux: Terminal",-1),O=a("p",null,"靠谱的文本编辑器",-1),T=r("Windows/macOS/Linux: "),W={href:"https://code.visualstudio.com",target:"_blank",rel:"noopener noreferrer"},y=r("VSCode"),H=a("h2",{id:"_2-4-你的进度",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2-4-你的进度","aria-hidden":"true"},"#"),r(" 2.4 你的进度")],-1),C=a("p",null,"如果上面的原材料你都准备好了的话,你已经拿到了开启新世界大门的钥匙。那还等什么,让我们快点进入下一章,走进这扇门吧!",-1),N=a("blockquote",null,[a("p",null,"⬛⬛⬜⬜⬜⬜⬜⬜ 25%")],-1);t.render=function(r,t){const j=l("OutboundLink");return n(),e(u,null,[o,s,c,d,h,p,m,S,P,b,x,f,g,a("ol",null,[a("li",null,[_,a("ul",null,[a("li",null,[V,a("a",L,[k,i(j)])]),w])]),a("li",null,[X,a("ul",null,[a("li",null,[v,a("a",I,[D,i(j)])]),A])]),a("li",null,[O,a("ul",null,[a("li",null,[T,a("a",W,[y,i(j)])])])])]),H,C,N],64)};export default t; diff --git a/assets/ch02-preparation.html.7a4b9487.js b/assets/ch02-preparation.html.de2666c3.js similarity index 98% rename from assets/ch02-preparation.html.7a4b9487.js rename to assets/ch02-preparation.html.de2666c3.js index bf1d7359b..40c73ea68 100644 --- a/assets/ch02-preparation.html.7a4b9487.js +++ b/assets/ch02-preparation.html.de2666c3.js @@ -1 +1 @@ -import{r as e,o as a,c as n,a as o,b as t,F as i,e as r}from"./app.755d843f.js";const l={},s=o("h1",{id:"chapter-2-preparation-of-raw-materials",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#chapter-2-preparation-of-raw-materials","aria-hidden":"true"},"#"),r(" [Chapter 2] Preparation of Raw Materials")],-1),u=o("p",null,"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.",-1),d=o("h2",{id:"_2-1-acquiring-a-vps",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_2-1-acquiring-a-vps","aria-hidden":"true"},"#"),r(" 2.1 Acquiring a VPS")],-1),c=o("p",null,"You need to obtain a healthy VPS with an unblocked IP, and perform the following basic preparations in the management console:",-1),h=o("ol",null,[o("li",null,"Install Debian 10 64-bit system in the backend of VPS."),o("li",null,[r("Write down the IP address of VPS in a notebook (this article will use "),o("code",null,'"100.200.300.400"'),r(" as an example, which is an intentionally incorrect and illegal IP address. Please replace it with your real IP address).")]),o("li",null,"Write down the SSH remote login port of VPS in a notebook."),o("li",null,"Write down the username and password for SSH remote login in a notebook.")],-1),m=o("p",null,"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.",-1),p=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"Explanation"),o("p",null,[r("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 "),o("strong",null,"nothing to do with you right now"),r("! 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.")])],-1),f=o("h2",{id:"_2-2-obtaining-a-desired-domain-name",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_2-2-obtaining-a-desired-domain-name","aria-hidden":"true"},"#"),r(" 2.2 Obtaining a Desired Domain Name")],-1),y=o("p",null,"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),b=o("ol",null,[o("li",null,[r("Please choose a reliable international domain name service provider. Choose some common domain name suffixes, and make sure not to use the "),o("code",null,".cn"),r(" suffix.")]),o("li",null,[r("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 "),o("code",null,'"a-name"'),r("). The complete domain name will be represented by "),o("code",null,'"subdomain.yourdomain.com"'),r(" or "),o("code",null,'"a-name.yourdomain.com"'),r(". The effect is as shown in the picture below:")])],-1),g=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch02-img01-a-name.0e89a8f1.png",alt:"Add A Record"})],-1),w=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"Tip"),o("p",null,[r("This is "),o("strong",null,"not"),r(" a real usable website. Please replace it with your real website URL.")])],-1),S=o("h2",{id:"_2-3-software-you-need-to-install-on-your-local-computer",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_2-3-software-you-need-to-install-on-your-local-computer","aria-hidden":"true"},"#"),r(" 2.3 Software you need to install on your local computer")],-1),k=o("ol",null,[o("li",null,"SSH remote login tool")],-1),x=r("Windows: "),P={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},v=r("PuTTY"),I=o("ul",null,[o("li",null,"macOS/Linux: Terminal")],-1),_=o("ol",{start:"2"},[o("li",null,"Remote file copying tool")],-1),L=r("Windows: "),T={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},V=r("WinSCP"),W=o("ul",null,[o("li",null,"macOS/Linux: Terminal")],-1),A={start:"3"},D=r("Reliable text editor "),R=r("Windows/macOS/Linux: "),X={href:"https://code.visualstudio.com",target:"_blank",rel:"noopener noreferrer"},q=r("VSCode"),O=o("h2",{id:"_2-4-your-progress",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_2-4-your-progress","aria-hidden":"true"},"#"),r(" 2.4 Your Progress")],-1),C=o("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),N=o("blockquote",null,[o("p",null,"⬛⬛⬜⬜⬜⬜⬜⬜ 25%")],-1);l.render=function(r,l){const Y=e("OutboundLink");return a(),n(i,null,[s,u,d,c,h,m,p,f,y,b,g,w,S,k,o("ul",null,[o("li",null,[x,o("a",P,[v,t(Y)]),I])]),_,o("ul",null,[o("li",null,[L,o("a",T,[V,t(Y)]),W])]),o("ol",A,[o("li",null,[D,o("ul",null,[o("li",null,[R,o("a",X,[q,t(Y)])])])])]),O,C,N],64)};export default l; +import{r as e,o as a,c as n,a as o,b as t,F as i,e as r}from"./app.48111a85.js";const l={},s=o("h1",{id:"chapter-2-preparation-of-raw-materials",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#chapter-2-preparation-of-raw-materials","aria-hidden":"true"},"#"),r(" [Chapter 2] Preparation of Raw Materials")],-1),u=o("p",null,"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.",-1),d=o("h2",{id:"_2-1-acquiring-a-vps",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_2-1-acquiring-a-vps","aria-hidden":"true"},"#"),r(" 2.1 Acquiring a VPS")],-1),c=o("p",null,"You need to obtain a healthy VPS with an unblocked IP, and perform the following basic preparations in the management console:",-1),h=o("ol",null,[o("li",null,"Install Debian 10 64-bit system in the backend of VPS."),o("li",null,[r("Write down the IP address of VPS in a notebook (this article will use "),o("code",null,'"100.200.300.400"'),r(" as an example, which is an intentionally incorrect and illegal IP address. Please replace it with your real IP address).")]),o("li",null,"Write down the SSH remote login port of VPS in a notebook."),o("li",null,"Write down the username and password for SSH remote login in a notebook.")],-1),m=o("p",null,"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.",-1),p=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"Explanation"),o("p",null,[r("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 "),o("strong",null,"nothing to do with you right now"),r("! 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.")])],-1),f=o("h2",{id:"_2-2-obtaining-a-desired-domain-name",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_2-2-obtaining-a-desired-domain-name","aria-hidden":"true"},"#"),r(" 2.2 Obtaining a Desired Domain Name")],-1),y=o("p",null,"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),b=o("ol",null,[o("li",null,[r("Please choose a reliable international domain name service provider. Choose some common domain name suffixes, and make sure not to use the "),o("code",null,".cn"),r(" suffix.")]),o("li",null,[r("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 "),o("code",null,'"a-name"'),r("). The complete domain name will be represented by "),o("code",null,'"subdomain.yourdomain.com"'),r(" or "),o("code",null,'"a-name.yourdomain.com"'),r(". The effect is as shown in the picture below:")])],-1),g=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch02-img01-a-name.0e89a8f1.png",alt:"Add A Record"})],-1),w=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"Tip"),o("p",null,[r("This is "),o("strong",null,"not"),r(" a real usable website. Please replace it with your real website URL.")])],-1),S=o("h2",{id:"_2-3-software-you-need-to-install-on-your-local-computer",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_2-3-software-you-need-to-install-on-your-local-computer","aria-hidden":"true"},"#"),r(" 2.3 Software you need to install on your local computer")],-1),k=o("ol",null,[o("li",null,"SSH remote login tool")],-1),x=r("Windows: "),P={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},v=r("PuTTY"),I=o("ul",null,[o("li",null,"macOS/Linux: Terminal")],-1),_=o("ol",{start:"2"},[o("li",null,"Remote file copying tool")],-1),L=r("Windows: "),T={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},V=r("WinSCP"),W=o("ul",null,[o("li",null,"macOS/Linux: Terminal")],-1),A={start:"3"},D=r("Reliable text editor "),R=r("Windows/macOS/Linux: "),X={href:"https://code.visualstudio.com",target:"_blank",rel:"noopener noreferrer"},q=r("VSCode"),O=o("h2",{id:"_2-4-your-progress",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_2-4-your-progress","aria-hidden":"true"},"#"),r(" 2.4 Your Progress")],-1),C=o("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),N=o("blockquote",null,[o("p",null,"⬛⬛⬜⬜⬜⬜⬜⬜ 25%")],-1);l.render=function(r,l){const Y=e("OutboundLink");return a(),n(i,null,[s,u,d,c,h,m,p,f,y,b,g,w,S,k,o("ul",null,[o("li",null,[x,o("a",P,[v,t(Y)]),I])]),_,o("ul",null,[o("li",null,[L,o("a",T,[V,t(Y)]),W])]),o("ol",A,[o("li",null,[D,o("ul",null,[o("li",null,[R,o("a",X,[q,t(Y)])])])])]),O,C,N],64)};export default l; diff --git a/assets/ch03-ssh.html.04205ee1.js b/assets/ch03-ssh.html.2e667ccb.js similarity index 99% rename from assets/ch03-ssh.html.04205ee1.js rename to assets/ch03-ssh.html.2e667ccb.js index e765e3d1b..954d3be78 100644 --- a/assets/ch03-ssh.html.04205ee1.js +++ b/assets/ch03-ssh.html.2e667ccb.js @@ -1 +1 @@ -import{r as l,o as n,c as e,a as t,b as u,w as a,F as s,e as i}from"./app.755d843f.js";const r={},o=t("h1",{id:"【第-3-章】远程登录篇",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#【第-3-章】远程登录篇","aria-hidden":"true"},"#"),i(" 【第 3 章】远程登录篇")],-1),c=t("h2",{id:"_3-1-远程登录-vps-putty",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-1-远程登录-vps-putty","aria-hidden":"true"},"#"),i(" 3.1 远程登录 VPS (PuTTY)")],-1),d=t("p",null,"首先,鉴于零基础人群中 Windows 的用户基数最大,所以本文以 Windows 为例进行展示。",-1),p=t("p",null,"其次,虽然 Windows 10 之后的 PowerShell 和 WSL 也可以达到很好的 SSH 操作体验。但是因为并非所有版本的 Windows 都有最新的组件,故本文还是以老牌的 PuTTY 为例,进行 SSH 远程登录的操作详解。(使用其他工具的话、在 SSH 登陆之后的操作都是一样的)",-1),g=t("p",null,"下面就跟我一步步操作吧。",-1),h=i("进入 PuTTY 的"),x={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},m=i("官网"),P=i(",选择适合你操作系统的版本下载。(本文以 64 位版本为例)"),S=t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img01-putty-download.af7ceea7.png",alt:"下载PuTTY"})],-1),b=i("安装运行后,将会看到 PuTTY 的主界面。现在请拿出你上一章记东西的"),y=i("小本本"),f=i(",在下图的对应位置填入你 VPS 的"),v=t("strong",null,[i("IP 地址(VPS IP)"),t("strong",null,"和"),i("端口(VPS PORT)")],-1),L=i("。为了方便以后使用时不用重复输入,我们可以保存会话 (Saved Sessions),未来使用时只要按 Load 即可一键载入设置。"),T=t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img02-putty-settings.30196e3d.png",alt:"设置PuTTY"})],-1),k=t("li",null,[t("p",null,[i("我建议将 "),t("code",null,"Connection"),i(" 中的 "),t("code",null,"keepalive"),i(" 设置为 "),t("code",null,"60"),i(" 秒,防止你一段时间没有操作之后 SSH 自动断线。另外务必再次保存设置。")]),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img03-putty-keepalive.999863b9.png",alt:"防止频繁断线"})])],-1),w=t("div",{class:"custom-container warning"},[t("p",{class:"custom-container-title"},"注意"),t("p",null,"对 PuTTY 的任何设置更新都要再次手动保存 Session,不然关闭后就会丢失")],-1),_=t("ol",{start:"4"},[t("li",null,[t("p",null,[i("点击 Open 就会进入 SSH 连接窗口,对应下图输入用户名与密码,与你的 VPS 远程主机建立连接。(本文假设默认用户名是 "),t("code",null,"root"),i(",另外,在 Linux 系统输入密码的时候,是不会出现 "),t("code",null,"******"),i(" 这种提示符的,这样可以避免密码长度泄漏,不是你的键盘坏掉了哦!)")]),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img04-ssh-login.20e1bfcc.png",alt:"SSH远程登录"})])])],-1),H=t("h2",{id:"_3-2-成功登录-ssh-初识命令行界面",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-2-成功登录-ssh-初识命令行界面","aria-hidden":"true"},"#"),i(" 3.2 成功登录 SSH!初识命令行界面!")],-1),Y=t("ol",null,[t("li",null,[t("p",null,"如果你的信息都填写正确,你将会看到类似下图的界面,说明已登录成功:"),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img05-ssh-login-success.c5197ad2.png",alt:"初次登录VPS"})]),t("p",null,[i("这个界面,就等于远程服务器的【桌面】,但它没有你熟悉的图标和鼠标,没有绚丽的色彩,有的只是简单文字,这就是【"),t("strong",null,"命令行界面"),i("】- "),t("code",null,"Command Line Interface"),i(",或者缩写为 "),t("code",null,"CLI"),i("。")]),t("p",null,[i("接下来的所有操作,都需要你像电影里的黑客一样,在这个命令行界面中完成。也许你会觉得陌生,但请相信我,使用命令行既不可怕,也不神秘。说到底,它只不过是把你习惯的鼠标操作变成了文字指令而已,"),t("strong",null,"你说一句,它做一句"),i("。")])]),t("li",null,[t("p",null,[i("现在,你可以稍微观察并熟悉一下命令行环境,这个界面其实已经告诉了你一些有用的信息了,比如系统内核版本(比如图内是 "),t("code",null,"4.19.37-5"),i(")、上次登录时间及 IP 等。当然根据 VPS 的不同,你看到的界面可能会略有不同。")])]),t("li",null,[t("p",null,[i("请注意命令行最下面一行,闪动的光标左边,有一串字符。图中显示的是"),t("code",null,"root@vps-server:~#"),i(",这一串要怎么理解呢?很简单:")]),t("ul",null,[t("li",null,[i("现在的用户是 "),t("code",null,"root")]),t("li",null,[t("code",null,"root"),i(" 所在的服务器是 "),t("code",null,"vps-server")]),t("li",null,[t("code",null,"root"),i(" 现在所在的文件夹是 "),t("code",null,"~")]),t("li",null,[t("code",null,"#"),i(" 之后是你可以输入命令的地方")])]),t("p",null,[i('前两个很直观,无需多说。第三个是关于 Linux 的文件夹系统,现在也不需要过于深入,你只需要知道,"'),t("code",null,"~"),i('"就是【当前用户的大本营】。第四个,提示符'),t("code",null,"#"),i(',你也不用管,只需要知道,未来文章中会写一些需要你输入的命令,都会以 "'),t("code",null,"#"),i('" 或者 "'),t("code",null,"$"),i('" 开头,提示你'),t("strong",null,"后面"),i("是你输入命令的地方。(所以你复制命令的时候,"),t("strong",null,"只需要复制后面的内容"),i(",不要复制提示符)")])])],-1),V=t("h2",{id:"_3-3-第一次更新-linux-的软件",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-3-第一次更新-linux-的软件","aria-hidden":"true"},"#"),i(" 3.3 第一次更新 Linux 的软件!")],-1),X=t("ol",null,[t("li",null,[t("p",null,"正如你的手机,无论安卓还是 iPhone,为了 APP 及时更新(获取安全补丁和新功能),都会时不时从应用商店获得更新信息,并且提示你有多少个 APP 可更新。Linux 系统也有逻辑十分类似的更新机制。所以只要你会更新手机 APP,就能学会更新 Linux 软件!")]),t("li",null,[t("p",null,[i("Linux 下,每个 APP 都叫做一个“包” (package)。管理 APP 的程序自然就叫做“包管理器”(Package Manager)。你可以通过它安装、更新、卸载各种软件、甚至更新 Linux 系统本身。Linux 下的包管理器非常强大,此处按下不表,现在你只需要知道 Debian 系统的包管理器叫做 "),t("code",null,"apt"),i(" 即可。接下来,我们就先使用 "),t("code",null,"apt"),i(" 做一次软件的全面更新,让你熟悉它的基本操作。")])]),t("li",null,[t("p",null,"小小白白 Linux 基础命令:"),t("table",null,[t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"center"}},"命令名称"),t("th",{style:{"text-align":"center"}},"命令说明")])]),t("tbody",null,[t("tr",null,[t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-01")]),t("td",{style:{"text-align":"center"}},[t("code",null,"apt update")]),t("td",{style:{"text-align":"center"}},"查询软件更新")]),t("tr",null,[t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-02")]),t("td",{style:{"text-align":"center"}},[t("code",null,"apt upgrade")]),t("td",{style:{"text-align":"center"}},"执行软件更新")])])])]),t("li",null,[t("p",null,"现在请输入第一条命令,获取更新信息"),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"apt"),i(" update\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])]),t("li",null,[t("p",null,[i("然后请输入第二条命令,并在询问是否继续安装 "),t("code",null,"(Y/n)"),i(" 时输入 "),t("code",null,"y"),i(" 并回车确认,开始安装")]),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"apt"),i(" upgrade\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])]),t("li",null,[t("p",null,"完整流程演示如下:"),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img06-apt-upgrade-full.e4a0b817.gif",alt:"初次软件更新流程演示"})])])],-1),A=t("h2",{id:"_3-4-你的进度",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-4-你的进度","aria-hidden":"true"},"#"),i(" 3.4 你的进度")],-1),E=t("p",null,[t("strong",null,"恭喜你又迈出了坚实的一步!"),i(" 现在,你已经可以通过 SSH 来登录你的远程服务器了!那登录进去之后,除了升级软件之外,应该再做点什么呢?敬请进入下一章一探究竟吧!")],-1),I=t("blockquote",null,[t("p",null,"⬛⬛⬛⬜⬜⬜⬜⬜ 37.5%")],-1);r.render=function(i,r){const W=l("OutboundLink"),B=l("RouterLink");return n(),e(s,null,[o,c,d,p,g,t("ol",null,[t("li",null,[t("p",null,[h,t("a",x,[m,u(W)]),P]),S]),t("li",null,[t("p",null,[b,u(B,{to:"/document/level-0/ch02-preparation.html#21-%E8%8E%B7%E5%8F%96%E4%B8%80%E5%8F%B0vps"},{default:a((()=>[y])),_:1}),f,v,L]),T]),k]),w,_,H,Y,V,X,A,E,I],64)};export default r; +import{r as l,o as n,c as e,a as t,b as u,w as a,F as s,e as i}from"./app.48111a85.js";const r={},o=t("h1",{id:"【第-3-章】远程登录篇",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#【第-3-章】远程登录篇","aria-hidden":"true"},"#"),i(" 【第 3 章】远程登录篇")],-1),c=t("h2",{id:"_3-1-远程登录-vps-putty",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-1-远程登录-vps-putty","aria-hidden":"true"},"#"),i(" 3.1 远程登录 VPS (PuTTY)")],-1),d=t("p",null,"首先,鉴于零基础人群中 Windows 的用户基数最大,所以本文以 Windows 为例进行展示。",-1),p=t("p",null,"其次,虽然 Windows 10 之后的 PowerShell 和 WSL 也可以达到很好的 SSH 操作体验。但是因为并非所有版本的 Windows 都有最新的组件,故本文还是以老牌的 PuTTY 为例,进行 SSH 远程登录的操作详解。(使用其他工具的话、在 SSH 登陆之后的操作都是一样的)",-1),g=t("p",null,"下面就跟我一步步操作吧。",-1),h=i("进入 PuTTY 的"),x={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},m=i("官网"),P=i(",选择适合你操作系统的版本下载。(本文以 64 位版本为例)"),S=t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img01-putty-download.af7ceea7.png",alt:"下载PuTTY"})],-1),b=i("安装运行后,将会看到 PuTTY 的主界面。现在请拿出你上一章记东西的"),y=i("小本本"),f=i(",在下图的对应位置填入你 VPS 的"),v=t("strong",null,[i("IP 地址(VPS IP)"),t("strong",null,"和"),i("端口(VPS PORT)")],-1),L=i("。为了方便以后使用时不用重复输入,我们可以保存会话 (Saved Sessions),未来使用时只要按 Load 即可一键载入设置。"),T=t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img02-putty-settings.30196e3d.png",alt:"设置PuTTY"})],-1),k=t("li",null,[t("p",null,[i("我建议将 "),t("code",null,"Connection"),i(" 中的 "),t("code",null,"keepalive"),i(" 设置为 "),t("code",null,"60"),i(" 秒,防止你一段时间没有操作之后 SSH 自动断线。另外务必再次保存设置。")]),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img03-putty-keepalive.999863b9.png",alt:"防止频繁断线"})])],-1),w=t("div",{class:"custom-container warning"},[t("p",{class:"custom-container-title"},"注意"),t("p",null,"对 PuTTY 的任何设置更新都要再次手动保存 Session,不然关闭后就会丢失")],-1),_=t("ol",{start:"4"},[t("li",null,[t("p",null,[i("点击 Open 就会进入 SSH 连接窗口,对应下图输入用户名与密码,与你的 VPS 远程主机建立连接。(本文假设默认用户名是 "),t("code",null,"root"),i(",另外,在 Linux 系统输入密码的时候,是不会出现 "),t("code",null,"******"),i(" 这种提示符的,这样可以避免密码长度泄漏,不是你的键盘坏掉了哦!)")]),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img04-ssh-login.20e1bfcc.png",alt:"SSH远程登录"})])])],-1),H=t("h2",{id:"_3-2-成功登录-ssh-初识命令行界面",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-2-成功登录-ssh-初识命令行界面","aria-hidden":"true"},"#"),i(" 3.2 成功登录 SSH!初识命令行界面!")],-1),Y=t("ol",null,[t("li",null,[t("p",null,"如果你的信息都填写正确,你将会看到类似下图的界面,说明已登录成功:"),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img05-ssh-login-success.c5197ad2.png",alt:"初次登录VPS"})]),t("p",null,[i("这个界面,就等于远程服务器的【桌面】,但它没有你熟悉的图标和鼠标,没有绚丽的色彩,有的只是简单文字,这就是【"),t("strong",null,"命令行界面"),i("】- "),t("code",null,"Command Line Interface"),i(",或者缩写为 "),t("code",null,"CLI"),i("。")]),t("p",null,[i("接下来的所有操作,都需要你像电影里的黑客一样,在这个命令行界面中完成。也许你会觉得陌生,但请相信我,使用命令行既不可怕,也不神秘。说到底,它只不过是把你习惯的鼠标操作变成了文字指令而已,"),t("strong",null,"你说一句,它做一句"),i("。")])]),t("li",null,[t("p",null,[i("现在,你可以稍微观察并熟悉一下命令行环境,这个界面其实已经告诉了你一些有用的信息了,比如系统内核版本(比如图内是 "),t("code",null,"4.19.37-5"),i(")、上次登录时间及 IP 等。当然根据 VPS 的不同,你看到的界面可能会略有不同。")])]),t("li",null,[t("p",null,[i("请注意命令行最下面一行,闪动的光标左边,有一串字符。图中显示的是"),t("code",null,"root@vps-server:~#"),i(",这一串要怎么理解呢?很简单:")]),t("ul",null,[t("li",null,[i("现在的用户是 "),t("code",null,"root")]),t("li",null,[t("code",null,"root"),i(" 所在的服务器是 "),t("code",null,"vps-server")]),t("li",null,[t("code",null,"root"),i(" 现在所在的文件夹是 "),t("code",null,"~")]),t("li",null,[t("code",null,"#"),i(" 之后是你可以输入命令的地方")])]),t("p",null,[i('前两个很直观,无需多说。第三个是关于 Linux 的文件夹系统,现在也不需要过于深入,你只需要知道,"'),t("code",null,"~"),i('"就是【当前用户的大本营】。第四个,提示符'),t("code",null,"#"),i(',你也不用管,只需要知道,未来文章中会写一些需要你输入的命令,都会以 "'),t("code",null,"#"),i('" 或者 "'),t("code",null,"$"),i('" 开头,提示你'),t("strong",null,"后面"),i("是你输入命令的地方。(所以你复制命令的时候,"),t("strong",null,"只需要复制后面的内容"),i(",不要复制提示符)")])])],-1),V=t("h2",{id:"_3-3-第一次更新-linux-的软件",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-3-第一次更新-linux-的软件","aria-hidden":"true"},"#"),i(" 3.3 第一次更新 Linux 的软件!")],-1),X=t("ol",null,[t("li",null,[t("p",null,"正如你的手机,无论安卓还是 iPhone,为了 APP 及时更新(获取安全补丁和新功能),都会时不时从应用商店获得更新信息,并且提示你有多少个 APP 可更新。Linux 系统也有逻辑十分类似的更新机制。所以只要你会更新手机 APP,就能学会更新 Linux 软件!")]),t("li",null,[t("p",null,[i("Linux 下,每个 APP 都叫做一个“包” (package)。管理 APP 的程序自然就叫做“包管理器”(Package Manager)。你可以通过它安装、更新、卸载各种软件、甚至更新 Linux 系统本身。Linux 下的包管理器非常强大,此处按下不表,现在你只需要知道 Debian 系统的包管理器叫做 "),t("code",null,"apt"),i(" 即可。接下来,我们就先使用 "),t("code",null,"apt"),i(" 做一次软件的全面更新,让你熟悉它的基本操作。")])]),t("li",null,[t("p",null,"小小白白 Linux 基础命令:"),t("table",null,[t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"center"}},"命令名称"),t("th",{style:{"text-align":"center"}},"命令说明")])]),t("tbody",null,[t("tr",null,[t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-01")]),t("td",{style:{"text-align":"center"}},[t("code",null,"apt update")]),t("td",{style:{"text-align":"center"}},"查询软件更新")]),t("tr",null,[t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-02")]),t("td",{style:{"text-align":"center"}},[t("code",null,"apt upgrade")]),t("td",{style:{"text-align":"center"}},"执行软件更新")])])])]),t("li",null,[t("p",null,"现在请输入第一条命令,获取更新信息"),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"apt"),i(" update\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])]),t("li",null,[t("p",null,[i("然后请输入第二条命令,并在询问是否继续安装 "),t("code",null,"(Y/n)"),i(" 时输入 "),t("code",null,"y"),i(" 并回车确认,开始安装")]),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"apt"),i(" upgrade\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])]),t("li",null,[t("p",null,"完整流程演示如下:"),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch03-img06-apt-upgrade-full.e4a0b817.gif",alt:"初次软件更新流程演示"})])])],-1),A=t("h2",{id:"_3-4-你的进度",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_3-4-你的进度","aria-hidden":"true"},"#"),i(" 3.4 你的进度")],-1),E=t("p",null,[t("strong",null,"恭喜你又迈出了坚实的一步!"),i(" 现在,你已经可以通过 SSH 来登录你的远程服务器了!那登录进去之后,除了升级软件之外,应该再做点什么呢?敬请进入下一章一探究竟吧!")],-1),I=t("blockquote",null,[t("p",null,"⬛⬛⬛⬜⬜⬜⬜⬜ 37.5%")],-1);r.render=function(i,r){const W=l("OutboundLink"),B=l("RouterLink");return n(),e(s,null,[o,c,d,p,g,t("ol",null,[t("li",null,[t("p",null,[h,t("a",x,[m,u(W)]),P]),S]),t("li",null,[t("p",null,[b,u(B,{to:"/document/level-0/ch02-preparation.html#21-%E8%8E%B7%E5%8F%96%E4%B8%80%E5%8F%B0vps"},{default:a((()=>[y])),_:1}),f,v,L]),T]),k]),w,_,H,Y,V,X,A,E,I],64)};export default r; diff --git a/assets/ch03-ssh.html.58a7d32a.js b/assets/ch03-ssh.html.65537063.js similarity index 99% rename from assets/ch03-ssh.html.58a7d32a.js rename to assets/ch03-ssh.html.65537063.js index 9f7f8fd3d..fa1d21440 100644 --- a/assets/ch03-ssh.html.58a7d32a.js +++ b/assets/ch03-ssh.html.65537063.js @@ -1 +1 @@ -import{r as e,o as t,c as n,a as o,b as a,F as l,e as s}from"./app.755d843f.js";const i={},r=o("h1",{id:"chapter-3-remote-login",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#chapter-3-remote-login","aria-hidden":"true"},"#"),s(" [Chapter 3] Remote Login")],-1),u=o("h2",{id:"_3-1-remote-login-to-vps-putty",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_3-1-remote-login-to-vps-putty","aria-hidden":"true"},"#"),s(" 3.1 Remote Login to VPS (PuTTY)")],-1),d=o("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),c=o("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),h=o("p",null,"Follow me step by step and let's start the operation.",-1),p=s("Go to the "),m={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},g=s("official website"),f=s(" of PuTTY and download the version that suits your operating system (this article uses the 64-bit version as an example)."),y=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img01-putty-download.af7ceea7.png",alt:"Download PuTTY"})],-1),w=o("ol",{start:"2"},[o("li",null,[s("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 "),o("strong",null,"IP address (VPS IP)"),s(" and "),o("strong",null,"port (VPS PORT)"),s(" 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.")])],-1),b=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img02-putty-settings.30196e3d.png",alt:"PuTTY Settings"})],-1),v=o("ol",{start:"3"},[o("li",null,[s("I suggest setting "),o("code",null,"keepalive"),s(" to "),o("code",null,"60"),s(" seconds in the "),o("code",null,"Connection"),s(" to prevent SSH from automatically disconnecting after a period of inactivity. Be sure to save the settings again.")])],-1),x=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img03-putty-keepalive.999863b9.png",alt:"Prevent frequent disconnection"})],-1),k=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Attention"),o("p",null,"Any update to the PuTTY configuration needs to be manually saved to the session again. Otherwise, it will be lost after closing.")],-1),S=o("ol",{start:"4"},[o("li",null,[s("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 "),o("code",null,"root"),s(". Also, when entering a password in the Linux system, there will be no prompt like "),o("code",null,"******"),s(", which can avoid password length leakage. It's not that your keyboard is broken!)")])],-1),T=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img04-ssh-login.20e1bfcc.png",alt:"SSH Remote Login"})],-1),P=o("h2",{id:"_3-2-successfully-logging-in-ssh-introduction-to-command-line-interface",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_3-2-successfully-logging-in-ssh-introduction-to-command-line-interface","aria-hidden":"true"},"#"),s(" 3.2 Successfully Logging in SSH! Introduction to Command Line Interface!")],-1),L=o("ol",null,[o("li",null,"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:")],-1),I=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img05-ssh-login-success.c5197ad2.png",alt:"Logging in to VPS for the first time"})],-1),Y=o("p",null,[s('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 "'),o("strong",null,"Command Line Interface"),s('" - shortened as '),o("code",null,"CLI"),s(".")],-1),C=o("p",null,[s("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, "),o("strong",null,"you say it, it does it"),s(".")],-1),A=o("ol",{start:"2"},[o("li",null,[o("p",null,[s("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. "),o("code",null,"4.19.37-5"),s(" in the picture), last login time and IP address. Of course, depending on the VPS, the interface you see may be slightly different.")])]),o("li",null,[o("p",null,[s("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 "),o("code",null,"root@vps-server:~#"),s(". How to understand this string? It's very simple:")])])],-1),H=o("ul",null,[o("li",null,[s("The current user is "),o("code",null,"root")]),o("li",null,[s("The server where "),o("code",null,"root"),s(" is located is "),o("code",null,"vps-server")]),o("li",null,[s("The current directory where "),o("code",null,"root"),s(" is located is "),o("code",null,"~")]),o("li",null,[s("After "),o("code",null,"#"),s(" is the place where you can input commands.")])],-1),_=o("p",null,[s("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 \""),o("code",null,"~"),s('" represents '),o("strong",null,"the home directory of the current user"),s('. As for the fourth one, the prompt symbol "'),o("code",null,"#"),s('", 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 "'),o("code",null,"#"),s('" or "'),o("code",null,"$"),s('" to indicate '),o("strong",null,"where you should input the command"),s(". (So when you copy the command, "),o("strong",null,"just copy the content after the prompt symbol"),s(" and don't copy the prompt symbol itself.)")],-1),N=o("h2",{id:"_3-3-updating-software-on-linux-for-the-first-time",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_3-3-updating-software-on-linux-for-the-first-time","aria-hidden":"true"},"#"),s(" 3.3 Updating software on Linux for the first time!")],-1),V=o("ol",null,[o("li",null,[o("p",null,"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!")]),o("li",null,[o("p",null,[s('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 '),o("code",null,"apt"),s(". Next, we will first use "),o("code",null,"apt"),s(" to do a comprehensive update of the software to familiarize you with its basic operations.")])]),o("li",null,[o("p",null,"Tiny White Linux Basic Commands:")])],-1),W=o("table",null,[o("thead",null,[o("tr",null,[o("th",{style:{"text-align":"center"}},"Number"),o("th",{style:{"text-align":"center"}},"Command Name"),o("th",{style:{"text-align":"center"}},"Command Description")])]),o("tbody",null,[o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-01")]),o("td",{style:{"text-align":"center"}},[o("code",null,"apt update")]),o("td",{style:{"text-align":"center"}},"Query software updates")]),o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-02")]),o("td",{style:{"text-align":"center"}},[o("code",null,"apt upgrade")]),o("td",{style:{"text-align":"center"}},"Perform software updates")])])],-1),X=o("ol",{start:"4"},[o("li",null,"Now, please enter the first command to get update information.")],-1),D=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"apt"),s(" update\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),O=o("p",null,"This is a command used in a Linux terminal to update the package list from the repositories configured on the system.",-1),q=o("ol",{start:"5"},[o("li",null,[s("Then enter the second command, and when asked if you want to continue installing "),o("code",null,"(Y/n)"),s(", type "),o("code",null,"y"),s(" and press enter to confirm and start the installation.")])],-1),F=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"apt"),s(" upgrade\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),R=o("p",null,"This is a command in the shell terminal to upgrade the installed packages on a Debian or Ubuntu Linux system.",-1),j=o("ol",{start:"6"},[o("li",null,"The complete demonstration of the process is as follows:")],-1),z=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img06-apt-upgrade-full.e4a0b817.gif",alt:"Demonstration of the software update process for the first time"})],-1),J=o("h2",{id:"_3-4-your-progress",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_3-4-your-progress","aria-hidden":"true"},"#"),s(" 3.4 Your Progress")],-1),B=o("p",null,[o("strong",null,"Congratulations on taking another solid step!"),s(" 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!")],-1),U=o("blockquote",null,[o("p",null,"⬛⬛⬛⬜⬜⬜⬜⬜ 37.5%")],-1);i.render=function(s,i){const G=e("OutboundLink");return t(),n(l,null,[r,u,d,c,h,o("ol",null,[o("li",null,[p,o("a",m,[g,a(G)]),f])]),y,w,b,v,x,k,S,T,P,L,I,Y,C,A,H,_,N,V,W,X,D,O,q,F,R,j,z,J,B,U],64)};export default i; +import{r as e,o as t,c as n,a as o,b as a,F as l,e as s}from"./app.48111a85.js";const i={},r=o("h1",{id:"chapter-3-remote-login",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#chapter-3-remote-login","aria-hidden":"true"},"#"),s(" [Chapter 3] Remote Login")],-1),u=o("h2",{id:"_3-1-remote-login-to-vps-putty",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_3-1-remote-login-to-vps-putty","aria-hidden":"true"},"#"),s(" 3.1 Remote Login to VPS (PuTTY)")],-1),d=o("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),c=o("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),h=o("p",null,"Follow me step by step and let's start the operation.",-1),p=s("Go to the "),m={href:"https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html",target:"_blank",rel:"noopener noreferrer"},g=s("official website"),f=s(" of PuTTY and download the version that suits your operating system (this article uses the 64-bit version as an example)."),y=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img01-putty-download.af7ceea7.png",alt:"Download PuTTY"})],-1),w=o("ol",{start:"2"},[o("li",null,[s("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 "),o("strong",null,"IP address (VPS IP)"),s(" and "),o("strong",null,"port (VPS PORT)"),s(" 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.")])],-1),b=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img02-putty-settings.30196e3d.png",alt:"PuTTY Settings"})],-1),v=o("ol",{start:"3"},[o("li",null,[s("I suggest setting "),o("code",null,"keepalive"),s(" to "),o("code",null,"60"),s(" seconds in the "),o("code",null,"Connection"),s(" to prevent SSH from automatically disconnecting after a period of inactivity. Be sure to save the settings again.")])],-1),x=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img03-putty-keepalive.999863b9.png",alt:"Prevent frequent disconnection"})],-1),k=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Attention"),o("p",null,"Any update to the PuTTY configuration needs to be manually saved to the session again. Otherwise, it will be lost after closing.")],-1),S=o("ol",{start:"4"},[o("li",null,[s("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 "),o("code",null,"root"),s(". Also, when entering a password in the Linux system, there will be no prompt like "),o("code",null,"******"),s(", which can avoid password length leakage. It's not that your keyboard is broken!)")])],-1),T=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img04-ssh-login.20e1bfcc.png",alt:"SSH Remote Login"})],-1),P=o("h2",{id:"_3-2-successfully-logging-in-ssh-introduction-to-command-line-interface",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_3-2-successfully-logging-in-ssh-introduction-to-command-line-interface","aria-hidden":"true"},"#"),s(" 3.2 Successfully Logging in SSH! Introduction to Command Line Interface!")],-1),L=o("ol",null,[o("li",null,"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:")],-1),I=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img05-ssh-login-success.c5197ad2.png",alt:"Logging in to VPS for the first time"})],-1),Y=o("p",null,[s('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 "'),o("strong",null,"Command Line Interface"),s('" - shortened as '),o("code",null,"CLI"),s(".")],-1),C=o("p",null,[s("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, "),o("strong",null,"you say it, it does it"),s(".")],-1),A=o("ol",{start:"2"},[o("li",null,[o("p",null,[s("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. "),o("code",null,"4.19.37-5"),s(" in the picture), last login time and IP address. Of course, depending on the VPS, the interface you see may be slightly different.")])]),o("li",null,[o("p",null,[s("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 "),o("code",null,"root@vps-server:~#"),s(". How to understand this string? It's very simple:")])])],-1),H=o("ul",null,[o("li",null,[s("The current user is "),o("code",null,"root")]),o("li",null,[s("The server where "),o("code",null,"root"),s(" is located is "),o("code",null,"vps-server")]),o("li",null,[s("The current directory where "),o("code",null,"root"),s(" is located is "),o("code",null,"~")]),o("li",null,[s("After "),o("code",null,"#"),s(" is the place where you can input commands.")])],-1),_=o("p",null,[s("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 \""),o("code",null,"~"),s('" represents '),o("strong",null,"the home directory of the current user"),s('. As for the fourth one, the prompt symbol "'),o("code",null,"#"),s('", 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 "'),o("code",null,"#"),s('" or "'),o("code",null,"$"),s('" to indicate '),o("strong",null,"where you should input the command"),s(". (So when you copy the command, "),o("strong",null,"just copy the content after the prompt symbol"),s(" and don't copy the prompt symbol itself.)")],-1),N=o("h2",{id:"_3-3-updating-software-on-linux-for-the-first-time",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_3-3-updating-software-on-linux-for-the-first-time","aria-hidden":"true"},"#"),s(" 3.3 Updating software on Linux for the first time!")],-1),V=o("ol",null,[o("li",null,[o("p",null,"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!")]),o("li",null,[o("p",null,[s('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 '),o("code",null,"apt"),s(". Next, we will first use "),o("code",null,"apt"),s(" to do a comprehensive update of the software to familiarize you with its basic operations.")])]),o("li",null,[o("p",null,"Tiny White Linux Basic Commands:")])],-1),W=o("table",null,[o("thead",null,[o("tr",null,[o("th",{style:{"text-align":"center"}},"Number"),o("th",{style:{"text-align":"center"}},"Command Name"),o("th",{style:{"text-align":"center"}},"Command Description")])]),o("tbody",null,[o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-01")]),o("td",{style:{"text-align":"center"}},[o("code",null,"apt update")]),o("td",{style:{"text-align":"center"}},"Query software updates")]),o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-02")]),o("td",{style:{"text-align":"center"}},[o("code",null,"apt upgrade")]),o("td",{style:{"text-align":"center"}},"Perform software updates")])])],-1),X=o("ol",{start:"4"},[o("li",null,"Now, please enter the first command to get update information.")],-1),D=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"apt"),s(" update\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),O=o("p",null,"This is a command used in a Linux terminal to update the package list from the repositories configured on the system.",-1),q=o("ol",{start:"5"},[o("li",null,[s("Then enter the second command, and when asked if you want to continue installing "),o("code",null,"(Y/n)"),s(", type "),o("code",null,"y"),s(" and press enter to confirm and start the installation.")])],-1),F=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"apt"),s(" upgrade\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),R=o("p",null,"This is a command in the shell terminal to upgrade the installed packages on a Debian or Ubuntu Linux system.",-1),j=o("ol",{start:"6"},[o("li",null,"The complete demonstration of the process is as follows:")],-1),z=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch03-img06-apt-upgrade-full.e4a0b817.gif",alt:"Demonstration of the software update process for the first time"})],-1),J=o("h2",{id:"_3-4-your-progress",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_3-4-your-progress","aria-hidden":"true"},"#"),s(" 3.4 Your Progress")],-1),B=o("p",null,[o("strong",null,"Congratulations on taking another solid step!"),s(" 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!")],-1),U=o("blockquote",null,[o("p",null,"⬛⬛⬛⬜⬜⬜⬜⬜ 37.5%")],-1);i.render=function(s,i){const G=e("OutboundLink");return t(),n(l,null,[r,u,d,c,h,o("ol",null,[o("li",null,[p,o("a",m,[g,a(G)]),f])]),y,w,b,v,x,k,S,T,P,L,I,Y,C,A,H,_,N,V,W,X,D,O,q,F,R,j,z,J,B,U],64)};export default i; diff --git a/assets/ch04-security.html.2b8400fc.js b/assets/ch04-security.html.099c9936.js similarity index 99% rename from assets/ch04-security.html.2b8400fc.js rename to assets/ch04-security.html.099c9936.js index 2a04f5d78..505ffd97f 100644 --- a/assets/ch04-security.html.2b8400fc.js +++ b/assets/ch04-security.html.099c9936.js @@ -1 +1 @@ -import{r as e,o as t,c as n,a as o,b as l,F as s,e as a}from"./app.755d843f.js";const i={},r=o("h1",{id:"chapter-4-security-and-protection",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#chapter-4-security-and-protection","aria-hidden":"true"},"#"),a(" [Chapter 4] Security and Protection")],-1),u=o("h2",{id:"_4-1-why-do-we-need-security-protection",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-1-why-do-we-need-security-protection","aria-hidden":"true"},"#"),a(" 4.1 Why Do We Need Security Protection?")],-1),c=o("p",null,"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.",-1),d=o("p",null,"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.",-1),h=o("ul",null,[o("li",null,[o("p",null,"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.")]),o("li",null,[o("p",null,"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.")])],-1),m=o("h2",{id:"_4-2-what-are-the-specific-risks",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-2-what-are-the-specific-risks","aria-hidden":"true"},"#"),a(" 4.2 What are the specific risks")],-1),p=o("p",null,'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),g=o("ol",null,[o("li",null,[o("p",null,"[IP Address]: Malicious scripts randomly attempt to scan IP ranges, which can be regarded as public information and cannot be hidden.")]),o("li",null,[o("p",null,[a("[Port]: If you are using the default port, then [Port = "),o("code",null,"22"),a("].")])]),o("li",null,[o("p",null,[a("[Username]: If using the default user, then [Username = "),o("code",null,"root"),a("]")])]),o("li",null,[o("p",null,"[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:")])],-1),y=o("ul",null,[o("li",null,[o("p",null,"If you use a VPS management background to generate passwords randomly, it usually contains random uppercase and lowercase letters, symbols, and is relatively secure.")]),o("li",null,[o("p",null,[a("If you changed your password to something super weak like "),o("code",null,"123456"),a(" just for the sake of easy memorization, hacking into your VPS server would be a piece of cake.")])]),o("li",null,[o("p",null,[a("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 "),o("code",null,"password tables"),a(", which contain tens of thousands, hundreds of thousands, millions, or even more real leaked passwords.")])])],-1),f=o("ol",{start:"5"},[o("li",null,"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.")],-1),w=o("p",null,[a("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 "),o("code",null,"root"),a(" 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),b=o("ol",{start:"6"},[o("li",null,"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.")],-1),v=o("h2",{id:"_4-3-what-security-measures-do-we-need-to-take",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-3-what-security-measures-do-we-need-to-take","aria-hidden":"true"},"#"),a(" 4.3 What security measures do we need to take")],-1),k=o("p",null,"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),x=o("ol",null,[o("li",null,"[Port]: Modify the SSH remote login port to a [non-22 port] (4.4)."),o("li",null,"[Username]: Create a [non-root] new user and disable root user SSH remote login (4.5, 4.6)."),o("li",null,"[Password]: Enable RSA key verification for SSH login and disable password verification login (4.7).")],-1),S=o("p",null,"Remember to follow the order and don't lock yourself out.",-1),T=o("h2",{id:"_4-4-change-the-ssh-remote-login-port-to-a-non-22-port",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-4-change-the-ssh-remote-login-port-to-a-non-22-port","aria-hidden":"true"},"#"),a(" 4.4 Change the SSH Remote Login Port to a Non-22 Port")],-1),P=o("p",null,[a("Now, let's solve the problem of \"port = "),o("code",null,"22"),a("\". (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),I=o("ol",null,[o("li",null,"Basic commands of Little White Linux:")],-1),A=o("table",null,[o("thead",null,[o("tr",null,[o("th",{style:{"text-align":"center"}},"ID"),o("th",{style:{"text-align":"center"}},"Command Name"),o("th",{style:{"text-align":"center"}},"Description")])]),o("tbody",null,[o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-03")]),o("td",{style:{"text-align":"center"}},[o("code",null,"nano")]),o("td",{style:{"text-align":"center"}},"Text editor")]),o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-04")]),o("td",{style:{"text-align":"center"}},[o("code",null,"systemctl restart")]),o("td",{style:{"text-align":"center"}},"Restart a service")])])],-1),L=o("ol",{start:"2"},[o("li",null,"Basic Configuration Files of Little White Linux")],-1),C=o("table",null,[o("thead",null,[o("tr",null,[o("th",{style:{"text-align":"center"}},"Number"),o("th",{style:{"text-align":"center"}},"Configuration File Location"),o("th",{style:{"text-align":"center"}},"File Description")])]),o("tbody",null,[o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"conf-01")]),o("td",{style:{"text-align":"center"}},[o("code",null,"/etc/ssh/sshd_config")]),o("td",{style:{"text-align":"center"}},"SSH Remote Login Program Settings")])])],-1),_=o("ol",{start:"3"},[o("li",null,[a("The first thing we need to do, of course, is to [open the SSH remote login program settings with the text editor "),o("code",null,"nano"),a("]. 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:")])],-1),W=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),H=o("p",null,[a("This is a command in the shell terminal to open the "),o("code",null,"sshd_config"),a(" file located in the "),o("code",null,"/etc/ssh/"),a(" directory using the "),o("code",null,"nano"),a(" text editor.")],-1),Y=o("ol",{start:"4"},[o("li",null,[a("Once the file is opened, you will enter the interface of "),o("code",null,"nano"),a(". 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?")])],-1),N=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img01-nano-ui.1b0418d7.png",alt:"Interface of nano"})],-1),D=o("ol",{start:"5"},[o("li",null,[a("The second thing we need to do is to "),o("strong",null,[a("find the "),o("code",null,"Port"),a(" item in the opened file and modify its port")]),a(". The number after "),o("code",null,"Port"),a(" is the SSH port. It is generally recommended to change it to an integer greater than "),o("code",null,"1024"),a(" and less than "),o("code",null,"65535"),a(" (this article takes "),o("code",null,"9753"),a(" as an example). Please think about how to operate it with the shortcut keys of "),o("code",null,"nano"),a(". You are right again! It is:")])],-1),R=o("ul",null,[o("li",null,[a("Use "),o("code",null,"ctrl+w"),a(" to enter search mode, then type "),o("code",null,"Port 22"),a(" and press Enter")]),o("li",null,[a("Delete "),o("code",null,"22"),a(" and replace it with "),o("code",null,"9753")]),o("li",null,[a("Note: If this line starts with "),o("code",null,"#"),a(", 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 "),o("code",null,"#"),a(", or delete the "),o("code",null,"#"),a(" to enable this line.")])],-1),V=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,[a("This article uses "),o("code",null,"9753"),a(" 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),X=o("ol",{start:"6"},[o("li",null,"The third thing we need to do is to [save the file and exit].")],-1),E=o("ul",null,[o("li",null,[a("If you observed carefully in step 3, you would have noticed that saving is not done by the common "),o("code",null,"ctrl+s"),a(".")]),o("li",null,[a("The correct shortcut keys: save is "),o("code",null,"ctrl+o"),a(" + "),o("code",null,"enter"),a(", and exit is "),o("code",null,"ctrl+x"),a(".")])],-1),U=o("ol",{start:"7"},[o("li",null,"The last thing we need to do is to [restart the SSH service to make the changes take effect].")],-1),z=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[a("systemctl restart "),o("span",{class:"token function"},"ssh"),a("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),F=o("p",null,"This is a shell command to restart the SSH service.",-1),j=o("ol",{start:"8"},[o("li",null,"The complete process demonstration is as follows:")],-1),O=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img02-sshd-conf-full.91641b17.gif",alt:"Demonstration of modifying non-22 port"})],-1),B=o("ol",{start:"9"},[o("li",null,"Modify PuTTY Configuration")],-1),K=o("p",null,[a('"Now that the new port is in effect, you will need to use '),o("code",null,"9753"),a(" 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!)\"")],-1),M=o("h2",{id:"_4-5-creating-a-new-user-without-root-access",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-5-creating-a-new-user-without-root-access","aria-hidden":"true"},"#"),a(" 4.5 Creating a New User Without Root Access")],-1),G=o("p",null,[a("In the second step, let's solve the issue of the username being "),o("code",null,"root"),a(".")],-1),q=o("p",null,[a("Firstly, you need to understand that "),o("code",null,"root"),a(" 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 "),o("code",null,"root"),a(" 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),J=o("ol",null,[o("li",null,"Little White Linux Basic Commands:")],-1),Q=o("table",null,[o("thead",null,[o("tr",null,[o("th",{style:{"text-align":"center"}},"Number"),o("th",{style:{"text-align":"center"}},"Command Name"),o("th",{style:{"text-align":"center"}},"Command Description")])]),o("tbody",null,[o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-05")]),o("td",{style:{"text-align":"center"}},[o("code",null,"adduser")]),o("td",{style:{"text-align":"center"}},"Add new user to the system")]),o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-06")]),o("td",{style:{"text-align":"center"}},[o("code",null,"apt install")]),o("td",{style:{"text-align":"center"}},"Install a software package")]),o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-07")]),o("td",{style:{"text-align":"center"}},[o("code",null,"visudo")]),o("td",{style:{"text-align":"center"}},"Special editor to modify sudo permission settings")])])],-1),Z=o("ol",{start:"2"},[o("li",null,[a("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 "),o("code",null,"vpsadmin"),a(" as an example:")])],-1),$=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,"adduser vpsadmin\n")]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),ee=o("p",null,'This is a command in the shell terminal to add a new user named "vpsadmin".',-1),te=o("p",null,[a("After executing the command, follow the prompts to operate. Be sure to set a user password (remember that you won't see "),o("code",null,"******"),a(" 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.")],-1),ne=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img03-adduser.c309caca.png",alt:"Creating a new user"})],-1),oe=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,'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),le=o("ol",{start:"3"},[o("li",null,"The complete process demonstration is as follows:")],-1),se=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img04-adduser-full.b1abf911.gif",alt:"Creating a new user"})],-1),ae=o("ol",{start:"4"},[o("li",null,[a("The second thing we need to do is to install the "),o("code",null,"sudo"),a(" function (which allows ordinary accounts to temporarily obtain the power of "),o("code",null,"root"),a(" at critical moments and unleash their full power to save the world).")])],-1),ie=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"apt"),a(" update "),o("span",{class:"token operator"},"&&"),a(),o("span",{class:"token function"},"apt"),a(),o("span",{class:"token function"},"install"),a(),o("span",{class:"token function"},"sudo"),a("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),re=o("p",null,'This is a shell command to update the package list and install the "sudo" package.',-1),ue=o("p",null,[a("You may have noticed that this command actually consists of two commands. The first half, "),o("code",null,"apt update"),a(", you have seen and used before, is to refresh the software version information on the server. The latter half, "),o("code",null,"apt install"),a(", is the installation command that will be used this time. The two commands are connected together to instruct the system to refresh the latest available software and then install the latest version of the "),o("code",null,"sudo"),a(" program. "),o("code",null,"&&"),a(" is used to link the two commands together for execution.")],-1),ce=o("ol",{start:"5"},[o("li",null,[a("The third thing we need to do is to add the "),o("code",null,"vpsadmin"),a(" user to the "),o("code",null,"sudo"),a(" list, so that they have the privilege to borrow the power of "),o("code",null,"root"),a(".")])],-1),de=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,"visudo\n")]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),he=o("p",null,[a("(Note: "),o("code",null,"visudo"),a(" is a command used in Linux/Unix systems to edit the sudoers file, which specifies which users or groups are allowed to run certain commands with administrative privileges.)")],-1),me=o("p",null,[a("Simply add the following line under "),o("code",null,"User Privilege Specification"),a(": "),o("code",null,"vpsadmin ALL=(ALL) NOPASSWD: ALL"),a(".")],-1),pe=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,[a("I want to specifically explain the setting of "),o("code",null,"NOPASSWD"),a(". It means that when the "),o("code",null,"vpsadmin"),a(" user temporarily uses the "),o("code",null,"root"),a(" permission, no additional password needs to be entered. This is contrary to general security recommendations. The reason why I recommend this is that many newcomers insist on using the "),o("code",null,"root"),a(" account because they feel relaxed when using "),o("code",null,"root"),a(' without repeatedly entering passwords. "Choosing the lesser of two evils," I believe that the risk of [directly using the '),o("code",null,"root"),a(" user] is greater than the risk of [not entering a password when using "),o("code",null,"sudo"),a("], so I made the above suggestion.")]),o("p",null,[a("If you want to follow the traditional practice and enter a password every time you use "),o("code",null,"sudo"),a(", then you can change this line to "),o("code",null,"vpsadmin ALL=(ALL:ALL) ALL"),a(".")]),o("ol",{start:"6"},[o("li",null,"The complete process demonstration is as follows:")]),o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img05-sudo-full.d131730a.gif",alt:"Creating a new user"})]),o("h2",{id:"_4-6-disabling-ssh-remote-login-for-root-user",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-6-disabling-ssh-remote-login-for-root-user","aria-hidden":"true"},"#"),a(" 4.6 Disabling SSH Remote Login for Root User")]),o("ol",null,[o("li",null,[a("Now that you're gradually getting familiar with Linux, it's time for you to think. What's the first thing we need to do? That's right, it's still to use the "),o("code",null,"nano"),a(" editor to open the "),o("code",null,"SSH remote login program settings"),a(". What? You can't remember how to do it? Then go back and review the content above and come back! ............ Correct answer:")])]),o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])]),o("p",null,[a("This is a command line instruction to open and edit the "),o("code",null,"sshd_config"),a(" file located at "),o("code",null,"/etc/ssh/"),a(" using the "),o("code",null,"nano"),a(" text editor.")]),o("ol",{start:"2"},[o("li",null,[a("Find the line "),o("code",null,"PermitRootLogin Yes"),a(", and change the value after it to "),o("code",null,"no"),a(". Do you remember how to do it? ............ Correct answer:")])]),o("ul",null,[o("li",null,[a("Use "),o("code",null,"ctrl+w"),a(" to enter search mode, then enter "),o("code",null,"PermitRootLogin"),a(" and press enter.")]),o("li",null,[a("Delete "),o("code",null,"yes"),a(" and change it to "),o("code",null,"no"),a(".")])]),o("ol",{start:"3"},[o("li",null,"Save the file and exit. Do you remember how to do it? ............ Correct answer: N/A (The correct answer is not provided in the given text.)")]),o("ul",null,[o("li",null,[a("Save is "),o("code",null,"ctrl+o"),a(", then press "),o("code",null,"Enter"),a(" to confirm.")]),o("li",null,[a("Exit is "),o("code",null,"ctrl+x"),a(".")])]),o("ol",{start:"4"},[o("li",null,"Restart the ssh service to make the changes take effect. Do you remember...? Never mind, let's just reveal the correct answer:")]),o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[a("systemctl restart "),o("span",{class:"token function"},"ssh"),a("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])]),o("p",null,"(This is a Linux shell command to restart the SSH service.)"),o("ol",{start:"5"},[o("li",null,"The complete process is demonstrated as follows:")]),o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img06-ssh-no-root-full.a9943c8b.gif",alt:"Disable SSH remote login for root user"})]),o("ol",{start:"6"},[o("li",null,[a("Next time you log in remotely via SSH using PuTTY, you will no longer be able to connect as the "),o("code",null,"root"),a(" user. You will need to use the username "),o("code",null,"vpsadmin"),a(" instead. For convenience, you can set "),o("code",null,"vpsadmin"),a(" as the default login username in PuTTY. (Tip: Don't forget to save the session.)")])]),o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img07-putty-default-user.a515e814.png",alt:"PuTTY Setting Default User Name"})]),o("h2",{id:"_4-7-login-with-rsa-key-and-disable-password-login",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-7-login-with-rsa-key-and-disable-password-login","aria-hidden":"true"},"#"),a(" 4.7 Login with RSA Key and Disable Password Login")]),o("p",null,"In the third step, we will solve the problem of the password being cracked."),o("p",null,'As mentioned earlier, hackers are not foolish enough to crack your password by brute force, but rather they use cheating methods such as "password tables". Unless you use a randomly generated super long password (such as with 1Password, or macOS keychain and other password management tools), it\'s easy to fall victim to this.'),o("p",null,'Although a very long random password can improve security, it is usually difficult to remember and manually enter, which can also lead to mistakes. To solve this problem, we can simply abandon the "password verification" method and switch to a more secure "key verification" method.'),o("p",null,'The so-called "key authentication" refers to generating a pair of related key files (public key and private key), uploading the "public key" to the VPS for backup. Each time you log in, SSH will match the "public key" and "private key". If the verification is correct, the "key pair" will be verified and the authentication will pass. (In other words, you don\'t need to remember and enter complex passwords, just protect the "private key" file from being leaked.)'),o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,[a("This article uses "),o("code",null,"RSA"),a(" keys as an example because "),o("code",null,"RSA"),a(" keys have a long history of support in various devices and "),o("code",null,"SSH"),a(" clients and can still provide sufficient security. However, it is not the only choice available.")]),o("p",null,"Other common keys include:"),o("ul",null,[o("li",null,[o("code",null,"DSA"),a(" - It has been mathematically proven to be insecure, so never use it.")]),o("li",null,[o("code",null,"ECDSA"),a(" - It has high security with small keys, but its algorithm is suspected to have a backdoor by the NSA. If there is something on your VPS that is worth the attention of the NSA, do not use it.")]),o("li",null,[o("code",null,"Ed25519"),a(" - This is an algorithm that is very similar to "),o("code",null,"ECDSA"),a(", and it has similar performance advantages. At the same time, all of its documentation is public, so it is generally considered to be free of backdoors.")])]),o("p",null,[a("So, if your device and software both support it, I recommend choosing "),o("code",null,"Ed25519"),a(" keys as a priority.")])])],-1),ge=o("p",null,"Now let's configure the [Key Authentication]!",-1),ye=o("ol",null,[o("li",null,[o("p",null,[a("Run "),o("code",null,"PuTTYgen"),a(" (PuTTY Key Generator). The location is "),o("code",null,"Start Menu"),a(" --\x3e "),o("code",null,"All Programs"),a(" --\x3e "),o("code",null,"PuTTY (64-bit)"),a(" --\x3e "),o("code",null,"PuTTYgen"),a(".")])]),o("li",null,[o("p",null,[a("Click on "),o("code",null,"Generate"),a(" to start the generation process (move the mouse randomly in the blank area of the interface to add random numbers).")])])],-1),fe=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img08-puttygen-save.32267800.png",alt:"Generate Key"})],-1),we=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,[a("The example in this image is based on a "),o("code",null,"2048"),a("-bit "),o("code",null,"RSA"),a(" key. However, in reality, if you want to achieve the same level of security as a "),o("code",null,"256"),a("-bit key for "),o("code",null,"EDCSA/Ed25519"),a(", you need to use a "),o("code",null,"3072"),a("-bit "),o("code",null,"RSA"),a(" key. (i.e., change the number in the bottom right corner to "),o("code",null,"3072"),a(")")])],-1),be=o("ol",{start:"2"},[o("li",null,"You can add a password to your private key to increase security."),o("li",null,[a("Click on "),o("code",null,"Save public key"),a(" to save the public key with the file name "),o("code",null,"id_rsa.pub"),a(".")]),o("li",null,[a("Click on "),o("code",null,"Save private key"),a(" to save the private key with the file name "),o("code",null,"id_rsa"),a(" (PuTTY private keys come with the "),o("code",null,".ppk"),a(" extension).")]),o("li",null,[a("Most importantly, copy and save all the content inside the red box below by scrolling down, with the file name "),o("code",null,"authorized_keys"),a(". (If you save it using vscode, it will be saved as a text file with a "),o("code",null,".txt"),a(" extension, which is fine. We will remove the extension when uploading it to VPS later.)")])],-1),ve=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img09-puttygen-save-keys.a599bbdf.png",alt:"Save Key"})],-1),ke=o("ol",{start:"2"},[o("li",null,'Upload the public key to the "vpsadmin" user on the VPS.')],-1),xe=o("p",null,[a("1, This step requires the use of the previously prepared "),o("code",null,"WinSCP"),a(".")],-1),Se=a("2, Go to the "),Te={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},Pe=a("official website"),Ie=a(" to download and install. It will prompt you to import PuTTY settings, and of course, you can import them with one click!"),Ae=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img10-winscp-import-session.342a201a.png",alt:"One-click Import Session"})],-1),Le=o("p",null,"3, If there is no prompt for import or you have already installed it in advance, configure it according to the following figure.",-1),Ce=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img11-winscp-ui.70f60717.png",alt:"WinSCP login settings"})],-1),_e=o("p",null,"4, The directory on the left side of WinSCP is the folder and files on your local computer. Please locate the folder where the key is stored.",-1),We=o("p",null,[a("5, The directory on the right side of WinSCP is the folder and files on the VPS server, which are located in the "),o("code",null,"/home/vpsadmin/"),a(" folder by default. To display hidden files, please click on "),o("code",null,"X hidden"),a(" in the lower right corner.")],-1),He=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img12-winscp-locations.f31ffa53.png",alt:"Local and remote folders"})],-1),Ye=o("p",null,[a("6, Right-click on the right side (in VPS) and create a new folder named "),o("code",null,".ssh"),a(" (note the period at the beginning).")],-1),Ne=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img13-winscp-newfolder-key.66d24a49.png",alt:"Create a folder to place public key in VPS"})],-1),De=o("p",null,[a("7, Upload the [public key] "),o("code",null,"authorized_keys"),a(" to the "),o("code",null,".ssh"),a(" folder.")],-1),Re=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img14-winscp-upload-key.9fa9340c.png",alt:"Upload authorized_keys"})],-1),Ve=o("p",null,[a("8, When uploading, rename the [public key] from "),o("code",null,"authorized_keys.txt"),a(" to "),o("code",null,"authorized_keys"),a(" (remove the "),o("code",null,".txt"),a(" extension).")],-1),Xe=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img15-winscp-rename-key.79776390.png",alt:"Ensure there is no file extension"})],-1),Ee=o("p",null,"9, The complete process demonstration is as follows:",-1),Ue=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img16-winscp-full.9c46d03b.gif",alt:"Complete demonstration of WinSCP operation"})],-1),ze=o("ol",{start:"3"},[o("li",null,"Enable RSA key authentication for SSH login and disable password authentication login on the VPS side.")],-1),Fe=o("ul",null,[o("li",null,[a("Basic Linux Commands: "),o("table",null,[o("thead",null,[o("tr",null,[o("th",{style:{"text-align":"center"}},"Number"),o("th",{style:{"text-align":"center"}},"Command"),o("th",{style:{"text-align":"center"}},"Description")])]),o("tbody",null,[o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-08")]),o("td",{style:{"text-align":"center"}},[o("code",null,"sudo")]),o("td",{style:{"text-align":"center"}},[a("Run a command with "),o("code",null,"root"),a(" privileges")])]),o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-09")]),o("td",{style:{"text-align":"center"}},[o("code",null,"chmod")]),o("td",{style:{"text-align":"center"}},"Change the permissions of a target file/directory")])])])]),o("li",null,"SSH remote connection to VPS (PuTTY)"),o("li",null,[a("Change the permission of the "),o("code",null,"authorized_keys"),a(" file to "),o("code",null,"600"),a(" (only the owner can read and write).")])],-1),je=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"chmod"),a(),o("span",{class:"token number"},"600"),a(" ~/.ssh/authorized_keys\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),Oe=o("p",null,[a("This is a command in shell script to change the permissions of the "),o("code",null,"authorized_keys"),a(" file to "),o("code",null,"600"),a(" for the current user's SSH directory ("),o("code",null,"~/.ssh/"),a(").")],-1),Be=o("ol",{start:"4"},[o("li",null,[a("Modify SSH configuration. We have used this many times, but now that we have changed from the almighty "),o("code",null,"root"),a(" to the ordinary user "),o("code",null,"vpsadmin"),a(", we do not have the permission to edit SSH configuration directly. At this time, we need to use the "),o("code",null,"sudo"),a(" command:")])],-1),Ke=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"sudo"),a(),o("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),Me=o("p",null,"(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),Ge=o("ol",{start:"5"},[o("li",null,[o("p",null,[a("Find ("),o("code",null,"ctrl+w"),a(") "),o("code",null,"PasswordAuthentication"),a(" and change it to "),o("code",null,"no"),a(".")])]),o("li",null,[o("p",null,[a("Find ("),o("code",null,"ctrl+w"),a(") "),o("code",null,"PubkeyAuthentication"),a(", change it to "),o("code",null,"yes"),a(", then save ("),o("code",null,"ctrl+o"),a(") and exit ("),o("code",null,"ctrl+x"),a(").")])]),o("li",null,[o("p",null,[a("Restart the SSH service. (Note: Don't forget to use "),o("code",null,"sudo"),a(" to gain permission.)")])])],-1),qe=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"sudo"),a(" systemctl restart "),o("span",{class:"token function"},"ssh"),a("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),Je=o("p",null,[a("This is a command in the shell terminal to restart the SSH service with root privileges using the "),o("code",null,"systemctl"),a(" command.")],-1),Qe=o("ol",{start:"8"},[o("li",null,"The complete process is as follows:")],-1),Ze=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img17-rsa-login-full.2cf70977.gif",alt:"Enable SSH key verification and disable password verification"})],-1),$e=o("ol",{start:"4"},[o("li",null,"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.)")],-1),et=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img18-putty-privatekey-location.694b3b0d.png",alt:"Specify private key location in PuTTY"})],-1),tt=o("ol",{start:"5"},[o("li",null,[a("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 "),o("code",null,"VPS-SERVER"),a(" configuration, click "),o("code",null,"Open"),a(", and you can log in with just one click.")])],-1),nt=o("p",null,"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:",-1),ot=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img19-putty-privatekey-passphrase.d7ab41cd.png",alt:"Enter Private Key Password"})],-1),lt=o("ol",{start:"6"},[o("li",null,[a("Don't forget to set the corresponding key for "),o("code",null,"WinSCP"),a(", otherwise you won't be able to log in when you want to transfer files later.")])],-1),st=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img20-winscp-privatekey-location.b1a9346e.png",alt:"WinSCP Specify Private Key Location"})],-1),at=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,"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.")],-1),it=o("h2",{id:"_4-8-your-progress",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-8-your-progress","aria-hidden":"true"},"#"),a(" 4.8 Your Progress")],-1),rt=o("p",null,"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.",-1),ut=o("p",null,"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)",-1),ct=o("blockquote",null,[o("p",null,"⬛⬛⬛⬛⬜⬜⬜⬜ 50%")],-1);i.render=function(a,i){const dt=e("OutboundLink");return t(),n(s,null,[r,u,c,d,h,m,p,g,y,f,w,b,v,k,x,S,T,P,I,A,L,C,_,W,H,Y,N,D,R,V,X,E,U,z,F,j,O,B,K,M,G,q,J,Q,Z,$,ee,te,ne,oe,le,se,ae,ie,re,ue,ce,de,he,me,pe,ge,ye,fe,we,be,ve,ke,xe,o("p",null,[Se,o("a",Te,[Pe,l(dt)]),Ie]),Ae,Le,Ce,_e,We,He,Ye,Ne,De,Re,Ve,Xe,Ee,Ue,ze,Fe,je,Oe,Be,Ke,Me,Ge,qe,Je,Qe,Ze,$e,et,tt,nt,ot,lt,st,at,it,rt,ut,ct],64)};export default i; +import{r as e,o as t,c as n,a as o,b as l,F as s,e as a}from"./app.48111a85.js";const i={},r=o("h1",{id:"chapter-4-security-and-protection",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#chapter-4-security-and-protection","aria-hidden":"true"},"#"),a(" [Chapter 4] Security and Protection")],-1),u=o("h2",{id:"_4-1-why-do-we-need-security-protection",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-1-why-do-we-need-security-protection","aria-hidden":"true"},"#"),a(" 4.1 Why Do We Need Security Protection?")],-1),c=o("p",null,"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.",-1),d=o("p",null,"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.",-1),h=o("ul",null,[o("li",null,[o("p",null,"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.")]),o("li",null,[o("p",null,"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.")])],-1),m=o("h2",{id:"_4-2-what-are-the-specific-risks",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-2-what-are-the-specific-risks","aria-hidden":"true"},"#"),a(" 4.2 What are the specific risks")],-1),p=o("p",null,'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),g=o("ol",null,[o("li",null,[o("p",null,"[IP Address]: Malicious scripts randomly attempt to scan IP ranges, which can be regarded as public information and cannot be hidden.")]),o("li",null,[o("p",null,[a("[Port]: If you are using the default port, then [Port = "),o("code",null,"22"),a("].")])]),o("li",null,[o("p",null,[a("[Username]: If using the default user, then [Username = "),o("code",null,"root"),a("]")])]),o("li",null,[o("p",null,"[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:")])],-1),y=o("ul",null,[o("li",null,[o("p",null,"If you use a VPS management background to generate passwords randomly, it usually contains random uppercase and lowercase letters, symbols, and is relatively secure.")]),o("li",null,[o("p",null,[a("If you changed your password to something super weak like "),o("code",null,"123456"),a(" just for the sake of easy memorization, hacking into your VPS server would be a piece of cake.")])]),o("li",null,[o("p",null,[a("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 "),o("code",null,"password tables"),a(", which contain tens of thousands, hundreds of thousands, millions, or even more real leaked passwords.")])])],-1),f=o("ol",{start:"5"},[o("li",null,"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.")],-1),w=o("p",null,[a("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 "),o("code",null,"root"),a(" 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),b=o("ol",{start:"6"},[o("li",null,"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.")],-1),v=o("h2",{id:"_4-3-what-security-measures-do-we-need-to-take",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-3-what-security-measures-do-we-need-to-take","aria-hidden":"true"},"#"),a(" 4.3 What security measures do we need to take")],-1),k=o("p",null,"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),x=o("ol",null,[o("li",null,"[Port]: Modify the SSH remote login port to a [non-22 port] (4.4)."),o("li",null,"[Username]: Create a [non-root] new user and disable root user SSH remote login (4.5, 4.6)."),o("li",null,"[Password]: Enable RSA key verification for SSH login and disable password verification login (4.7).")],-1),S=o("p",null,"Remember to follow the order and don't lock yourself out.",-1),T=o("h2",{id:"_4-4-change-the-ssh-remote-login-port-to-a-non-22-port",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-4-change-the-ssh-remote-login-port-to-a-non-22-port","aria-hidden":"true"},"#"),a(" 4.4 Change the SSH Remote Login Port to a Non-22 Port")],-1),P=o("p",null,[a("Now, let's solve the problem of \"port = "),o("code",null,"22"),a("\". (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),I=o("ol",null,[o("li",null,"Basic commands of Little White Linux:")],-1),A=o("table",null,[o("thead",null,[o("tr",null,[o("th",{style:{"text-align":"center"}},"ID"),o("th",{style:{"text-align":"center"}},"Command Name"),o("th",{style:{"text-align":"center"}},"Description")])]),o("tbody",null,[o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-03")]),o("td",{style:{"text-align":"center"}},[o("code",null,"nano")]),o("td",{style:{"text-align":"center"}},"Text editor")]),o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-04")]),o("td",{style:{"text-align":"center"}},[o("code",null,"systemctl restart")]),o("td",{style:{"text-align":"center"}},"Restart a service")])])],-1),L=o("ol",{start:"2"},[o("li",null,"Basic Configuration Files of Little White Linux")],-1),C=o("table",null,[o("thead",null,[o("tr",null,[o("th",{style:{"text-align":"center"}},"Number"),o("th",{style:{"text-align":"center"}},"Configuration File Location"),o("th",{style:{"text-align":"center"}},"File Description")])]),o("tbody",null,[o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"conf-01")]),o("td",{style:{"text-align":"center"}},[o("code",null,"/etc/ssh/sshd_config")]),o("td",{style:{"text-align":"center"}},"SSH Remote Login Program Settings")])])],-1),_=o("ol",{start:"3"},[o("li",null,[a("The first thing we need to do, of course, is to [open the SSH remote login program settings with the text editor "),o("code",null,"nano"),a("]. 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:")])],-1),W=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),H=o("p",null,[a("This is a command in the shell terminal to open the "),o("code",null,"sshd_config"),a(" file located in the "),o("code",null,"/etc/ssh/"),a(" directory using the "),o("code",null,"nano"),a(" text editor.")],-1),Y=o("ol",{start:"4"},[o("li",null,[a("Once the file is opened, you will enter the interface of "),o("code",null,"nano"),a(". 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?")])],-1),N=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img01-nano-ui.1b0418d7.png",alt:"Interface of nano"})],-1),D=o("ol",{start:"5"},[o("li",null,[a("The second thing we need to do is to "),o("strong",null,[a("find the "),o("code",null,"Port"),a(" item in the opened file and modify its port")]),a(". The number after "),o("code",null,"Port"),a(" is the SSH port. It is generally recommended to change it to an integer greater than "),o("code",null,"1024"),a(" and less than "),o("code",null,"65535"),a(" (this article takes "),o("code",null,"9753"),a(" as an example). Please think about how to operate it with the shortcut keys of "),o("code",null,"nano"),a(". You are right again! It is:")])],-1),R=o("ul",null,[o("li",null,[a("Use "),o("code",null,"ctrl+w"),a(" to enter search mode, then type "),o("code",null,"Port 22"),a(" and press Enter")]),o("li",null,[a("Delete "),o("code",null,"22"),a(" and replace it with "),o("code",null,"9753")]),o("li",null,[a("Note: If this line starts with "),o("code",null,"#"),a(", 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 "),o("code",null,"#"),a(", or delete the "),o("code",null,"#"),a(" to enable this line.")])],-1),V=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,[a("This article uses "),o("code",null,"9753"),a(" 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),X=o("ol",{start:"6"},[o("li",null,"The third thing we need to do is to [save the file and exit].")],-1),E=o("ul",null,[o("li",null,[a("If you observed carefully in step 3, you would have noticed that saving is not done by the common "),o("code",null,"ctrl+s"),a(".")]),o("li",null,[a("The correct shortcut keys: save is "),o("code",null,"ctrl+o"),a(" + "),o("code",null,"enter"),a(", and exit is "),o("code",null,"ctrl+x"),a(".")])],-1),U=o("ol",{start:"7"},[o("li",null,"The last thing we need to do is to [restart the SSH service to make the changes take effect].")],-1),z=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[a("systemctl restart "),o("span",{class:"token function"},"ssh"),a("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),F=o("p",null,"This is a shell command to restart the SSH service.",-1),j=o("ol",{start:"8"},[o("li",null,"The complete process demonstration is as follows:")],-1),O=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img02-sshd-conf-full.91641b17.gif",alt:"Demonstration of modifying non-22 port"})],-1),B=o("ol",{start:"9"},[o("li",null,"Modify PuTTY Configuration")],-1),K=o("p",null,[a('"Now that the new port is in effect, you will need to use '),o("code",null,"9753"),a(" 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!)\"")],-1),M=o("h2",{id:"_4-5-creating-a-new-user-without-root-access",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-5-creating-a-new-user-without-root-access","aria-hidden":"true"},"#"),a(" 4.5 Creating a New User Without Root Access")],-1),G=o("p",null,[a("In the second step, let's solve the issue of the username being "),o("code",null,"root"),a(".")],-1),q=o("p",null,[a("Firstly, you need to understand that "),o("code",null,"root"),a(" 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 "),o("code",null,"root"),a(" 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),J=o("ol",null,[o("li",null,"Little White Linux Basic Commands:")],-1),Q=o("table",null,[o("thead",null,[o("tr",null,[o("th",{style:{"text-align":"center"}},"Number"),o("th",{style:{"text-align":"center"}},"Command Name"),o("th",{style:{"text-align":"center"}},"Command Description")])]),o("tbody",null,[o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-05")]),o("td",{style:{"text-align":"center"}},[o("code",null,"adduser")]),o("td",{style:{"text-align":"center"}},"Add new user to the system")]),o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-06")]),o("td",{style:{"text-align":"center"}},[o("code",null,"apt install")]),o("td",{style:{"text-align":"center"}},"Install a software package")]),o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-07")]),o("td",{style:{"text-align":"center"}},[o("code",null,"visudo")]),o("td",{style:{"text-align":"center"}},"Special editor to modify sudo permission settings")])])],-1),Z=o("ol",{start:"2"},[o("li",null,[a("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 "),o("code",null,"vpsadmin"),a(" as an example:")])],-1),$=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,"adduser vpsadmin\n")]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),ee=o("p",null,'This is a command in the shell terminal to add a new user named "vpsadmin".',-1),te=o("p",null,[a("After executing the command, follow the prompts to operate. Be sure to set a user password (remember that you won't see "),o("code",null,"******"),a(" 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.")],-1),ne=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img03-adduser.c309caca.png",alt:"Creating a new user"})],-1),oe=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,'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),le=o("ol",{start:"3"},[o("li",null,"The complete process demonstration is as follows:")],-1),se=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img04-adduser-full.b1abf911.gif",alt:"Creating a new user"})],-1),ae=o("ol",{start:"4"},[o("li",null,[a("The second thing we need to do is to install the "),o("code",null,"sudo"),a(" function (which allows ordinary accounts to temporarily obtain the power of "),o("code",null,"root"),a(" at critical moments and unleash their full power to save the world).")])],-1),ie=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"apt"),a(" update "),o("span",{class:"token operator"},"&&"),a(),o("span",{class:"token function"},"apt"),a(),o("span",{class:"token function"},"install"),a(),o("span",{class:"token function"},"sudo"),a("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),re=o("p",null,'This is a shell command to update the package list and install the "sudo" package.',-1),ue=o("p",null,[a("You may have noticed that this command actually consists of two commands. The first half, "),o("code",null,"apt update"),a(", you have seen and used before, is to refresh the software version information on the server. The latter half, "),o("code",null,"apt install"),a(", is the installation command that will be used this time. The two commands are connected together to instruct the system to refresh the latest available software and then install the latest version of the "),o("code",null,"sudo"),a(" program. "),o("code",null,"&&"),a(" is used to link the two commands together for execution.")],-1),ce=o("ol",{start:"5"},[o("li",null,[a("The third thing we need to do is to add the "),o("code",null,"vpsadmin"),a(" user to the "),o("code",null,"sudo"),a(" list, so that they have the privilege to borrow the power of "),o("code",null,"root"),a(".")])],-1),de=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,"visudo\n")]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),he=o("p",null,[a("(Note: "),o("code",null,"visudo"),a(" is a command used in Linux/Unix systems to edit the sudoers file, which specifies which users or groups are allowed to run certain commands with administrative privileges.)")],-1),me=o("p",null,[a("Simply add the following line under "),o("code",null,"User Privilege Specification"),a(": "),o("code",null,"vpsadmin ALL=(ALL) NOPASSWD: ALL"),a(".")],-1),pe=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,[a("I want to specifically explain the setting of "),o("code",null,"NOPASSWD"),a(". It means that when the "),o("code",null,"vpsadmin"),a(" user temporarily uses the "),o("code",null,"root"),a(" permission, no additional password needs to be entered. This is contrary to general security recommendations. The reason why I recommend this is that many newcomers insist on using the "),o("code",null,"root"),a(" account because they feel relaxed when using "),o("code",null,"root"),a(' without repeatedly entering passwords. "Choosing the lesser of two evils," I believe that the risk of [directly using the '),o("code",null,"root"),a(" user] is greater than the risk of [not entering a password when using "),o("code",null,"sudo"),a("], so I made the above suggestion.")]),o("p",null,[a("If you want to follow the traditional practice and enter a password every time you use "),o("code",null,"sudo"),a(", then you can change this line to "),o("code",null,"vpsadmin ALL=(ALL:ALL) ALL"),a(".")]),o("ol",{start:"6"},[o("li",null,"The complete process demonstration is as follows:")]),o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img05-sudo-full.d131730a.gif",alt:"Creating a new user"})]),o("h2",{id:"_4-6-disabling-ssh-remote-login-for-root-user",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-6-disabling-ssh-remote-login-for-root-user","aria-hidden":"true"},"#"),a(" 4.6 Disabling SSH Remote Login for Root User")]),o("ol",null,[o("li",null,[a("Now that you're gradually getting familiar with Linux, it's time for you to think. What's the first thing we need to do? That's right, it's still to use the "),o("code",null,"nano"),a(" editor to open the "),o("code",null,"SSH remote login program settings"),a(". What? You can't remember how to do it? Then go back and review the content above and come back! ............ Correct answer:")])]),o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])]),o("p",null,[a("This is a command line instruction to open and edit the "),o("code",null,"sshd_config"),a(" file located at "),o("code",null,"/etc/ssh/"),a(" using the "),o("code",null,"nano"),a(" text editor.")]),o("ol",{start:"2"},[o("li",null,[a("Find the line "),o("code",null,"PermitRootLogin Yes"),a(", and change the value after it to "),o("code",null,"no"),a(". Do you remember how to do it? ............ Correct answer:")])]),o("ul",null,[o("li",null,[a("Use "),o("code",null,"ctrl+w"),a(" to enter search mode, then enter "),o("code",null,"PermitRootLogin"),a(" and press enter.")]),o("li",null,[a("Delete "),o("code",null,"yes"),a(" and change it to "),o("code",null,"no"),a(".")])]),o("ol",{start:"3"},[o("li",null,"Save the file and exit. Do you remember how to do it? ............ Correct answer: N/A (The correct answer is not provided in the given text.)")]),o("ul",null,[o("li",null,[a("Save is "),o("code",null,"ctrl+o"),a(", then press "),o("code",null,"Enter"),a(" to confirm.")]),o("li",null,[a("Exit is "),o("code",null,"ctrl+x"),a(".")])]),o("ol",{start:"4"},[o("li",null,"Restart the ssh service to make the changes take effect. Do you remember...? Never mind, let's just reveal the correct answer:")]),o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[a("systemctl restart "),o("span",{class:"token function"},"ssh"),a("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])]),o("p",null,"(This is a Linux shell command to restart the SSH service.)"),o("ol",{start:"5"},[o("li",null,"The complete process is demonstrated as follows:")]),o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img06-ssh-no-root-full.a9943c8b.gif",alt:"Disable SSH remote login for root user"})]),o("ol",{start:"6"},[o("li",null,[a("Next time you log in remotely via SSH using PuTTY, you will no longer be able to connect as the "),o("code",null,"root"),a(" user. You will need to use the username "),o("code",null,"vpsadmin"),a(" instead. For convenience, you can set "),o("code",null,"vpsadmin"),a(" as the default login username in PuTTY. (Tip: Don't forget to save the session.)")])]),o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img07-putty-default-user.a515e814.png",alt:"PuTTY Setting Default User Name"})]),o("h2",{id:"_4-7-login-with-rsa-key-and-disable-password-login",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-7-login-with-rsa-key-and-disable-password-login","aria-hidden":"true"},"#"),a(" 4.7 Login with RSA Key and Disable Password Login")]),o("p",null,"In the third step, we will solve the problem of the password being cracked."),o("p",null,'As mentioned earlier, hackers are not foolish enough to crack your password by brute force, but rather they use cheating methods such as "password tables". Unless you use a randomly generated super long password (such as with 1Password, or macOS keychain and other password management tools), it\'s easy to fall victim to this.'),o("p",null,'Although a very long random password can improve security, it is usually difficult to remember and manually enter, which can also lead to mistakes. To solve this problem, we can simply abandon the "password verification" method and switch to a more secure "key verification" method.'),o("p",null,'The so-called "key authentication" refers to generating a pair of related key files (public key and private key), uploading the "public key" to the VPS for backup. Each time you log in, SSH will match the "public key" and "private key". If the verification is correct, the "key pair" will be verified and the authentication will pass. (In other words, you don\'t need to remember and enter complex passwords, just protect the "private key" file from being leaked.)'),o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,[a("This article uses "),o("code",null,"RSA"),a(" keys as an example because "),o("code",null,"RSA"),a(" keys have a long history of support in various devices and "),o("code",null,"SSH"),a(" clients and can still provide sufficient security. However, it is not the only choice available.")]),o("p",null,"Other common keys include:"),o("ul",null,[o("li",null,[o("code",null,"DSA"),a(" - It has been mathematically proven to be insecure, so never use it.")]),o("li",null,[o("code",null,"ECDSA"),a(" - It has high security with small keys, but its algorithm is suspected to have a backdoor by the NSA. If there is something on your VPS that is worth the attention of the NSA, do not use it.")]),o("li",null,[o("code",null,"Ed25519"),a(" - This is an algorithm that is very similar to "),o("code",null,"ECDSA"),a(", and it has similar performance advantages. At the same time, all of its documentation is public, so it is generally considered to be free of backdoors.")])]),o("p",null,[a("So, if your device and software both support it, I recommend choosing "),o("code",null,"Ed25519"),a(" keys as a priority.")])])],-1),ge=o("p",null,"Now let's configure the [Key Authentication]!",-1),ye=o("ol",null,[o("li",null,[o("p",null,[a("Run "),o("code",null,"PuTTYgen"),a(" (PuTTY Key Generator). The location is "),o("code",null,"Start Menu"),a(" --\x3e "),o("code",null,"All Programs"),a(" --\x3e "),o("code",null,"PuTTY (64-bit)"),a(" --\x3e "),o("code",null,"PuTTYgen"),a(".")])]),o("li",null,[o("p",null,[a("Click on "),o("code",null,"Generate"),a(" to start the generation process (move the mouse randomly in the blank area of the interface to add random numbers).")])])],-1),fe=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img08-puttygen-save.32267800.png",alt:"Generate Key"})],-1),we=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,[a("The example in this image is based on a "),o("code",null,"2048"),a("-bit "),o("code",null,"RSA"),a(" key. However, in reality, if you want to achieve the same level of security as a "),o("code",null,"256"),a("-bit key for "),o("code",null,"EDCSA/Ed25519"),a(", you need to use a "),o("code",null,"3072"),a("-bit "),o("code",null,"RSA"),a(" key. (i.e., change the number in the bottom right corner to "),o("code",null,"3072"),a(")")])],-1),be=o("ol",{start:"2"},[o("li",null,"You can add a password to your private key to increase security."),o("li",null,[a("Click on "),o("code",null,"Save public key"),a(" to save the public key with the file name "),o("code",null,"id_rsa.pub"),a(".")]),o("li",null,[a("Click on "),o("code",null,"Save private key"),a(" to save the private key with the file name "),o("code",null,"id_rsa"),a(" (PuTTY private keys come with the "),o("code",null,".ppk"),a(" extension).")]),o("li",null,[a("Most importantly, copy and save all the content inside the red box below by scrolling down, with the file name "),o("code",null,"authorized_keys"),a(". (If you save it using vscode, it will be saved as a text file with a "),o("code",null,".txt"),a(" extension, which is fine. We will remove the extension when uploading it to VPS later.)")])],-1),ve=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img09-puttygen-save-keys.a599bbdf.png",alt:"Save Key"})],-1),ke=o("ol",{start:"2"},[o("li",null,'Upload the public key to the "vpsadmin" user on the VPS.')],-1),xe=o("p",null,[a("1, This step requires the use of the previously prepared "),o("code",null,"WinSCP"),a(".")],-1),Se=a("2, Go to the "),Te={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},Pe=a("official website"),Ie=a(" to download and install. It will prompt you to import PuTTY settings, and of course, you can import them with one click!"),Ae=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img10-winscp-import-session.342a201a.png",alt:"One-click Import Session"})],-1),Le=o("p",null,"3, If there is no prompt for import or you have already installed it in advance, configure it according to the following figure.",-1),Ce=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img11-winscp-ui.70f60717.png",alt:"WinSCP login settings"})],-1),_e=o("p",null,"4, The directory on the left side of WinSCP is the folder and files on your local computer. Please locate the folder where the key is stored.",-1),We=o("p",null,[a("5, The directory on the right side of WinSCP is the folder and files on the VPS server, which are located in the "),o("code",null,"/home/vpsadmin/"),a(" folder by default. To display hidden files, please click on "),o("code",null,"X hidden"),a(" in the lower right corner.")],-1),He=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img12-winscp-locations.f31ffa53.png",alt:"Local and remote folders"})],-1),Ye=o("p",null,[a("6, Right-click on the right side (in VPS) and create a new folder named "),o("code",null,".ssh"),a(" (note the period at the beginning).")],-1),Ne=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img13-winscp-newfolder-key.66d24a49.png",alt:"Create a folder to place public key in VPS"})],-1),De=o("p",null,[a("7, Upload the [public key] "),o("code",null,"authorized_keys"),a(" to the "),o("code",null,".ssh"),a(" folder.")],-1),Re=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img14-winscp-upload-key.9fa9340c.png",alt:"Upload authorized_keys"})],-1),Ve=o("p",null,[a("8, When uploading, rename the [public key] from "),o("code",null,"authorized_keys.txt"),a(" to "),o("code",null,"authorized_keys"),a(" (remove the "),o("code",null,".txt"),a(" extension).")],-1),Xe=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img15-winscp-rename-key.79776390.png",alt:"Ensure there is no file extension"})],-1),Ee=o("p",null,"9, The complete process demonstration is as follows:",-1),Ue=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img16-winscp-full.9c46d03b.gif",alt:"Complete demonstration of WinSCP operation"})],-1),ze=o("ol",{start:"3"},[o("li",null,"Enable RSA key authentication for SSH login and disable password authentication login on the VPS side.")],-1),Fe=o("ul",null,[o("li",null,[a("Basic Linux Commands: "),o("table",null,[o("thead",null,[o("tr",null,[o("th",{style:{"text-align":"center"}},"Number"),o("th",{style:{"text-align":"center"}},"Command"),o("th",{style:{"text-align":"center"}},"Description")])]),o("tbody",null,[o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-08")]),o("td",{style:{"text-align":"center"}},[o("code",null,"sudo")]),o("td",{style:{"text-align":"center"}},[a("Run a command with "),o("code",null,"root"),a(" privileges")])]),o("tr",null,[o("td",{style:{"text-align":"center"}},[o("code",null,"cmd-09")]),o("td",{style:{"text-align":"center"}},[o("code",null,"chmod")]),o("td",{style:{"text-align":"center"}},"Change the permissions of a target file/directory")])])])]),o("li",null,"SSH remote connection to VPS (PuTTY)"),o("li",null,[a("Change the permission of the "),o("code",null,"authorized_keys"),a(" file to "),o("code",null,"600"),a(" (only the owner can read and write).")])],-1),je=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"chmod"),a(),o("span",{class:"token number"},"600"),a(" ~/.ssh/authorized_keys\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),Oe=o("p",null,[a("This is a command in shell script to change the permissions of the "),o("code",null,"authorized_keys"),a(" file to "),o("code",null,"600"),a(" for the current user's SSH directory ("),o("code",null,"~/.ssh/"),a(").")],-1),Be=o("ol",{start:"4"},[o("li",null,[a("Modify SSH configuration. We have used this many times, but now that we have changed from the almighty "),o("code",null,"root"),a(" to the ordinary user "),o("code",null,"vpsadmin"),a(", we do not have the permission to edit SSH configuration directly. At this time, we need to use the "),o("code",null,"sudo"),a(" command:")])],-1),Ke=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"sudo"),a(),o("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),Me=o("p",null,"(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),Ge=o("ol",{start:"5"},[o("li",null,[o("p",null,[a("Find ("),o("code",null,"ctrl+w"),a(") "),o("code",null,"PasswordAuthentication"),a(" and change it to "),o("code",null,"no"),a(".")])]),o("li",null,[o("p",null,[a("Find ("),o("code",null,"ctrl+w"),a(") "),o("code",null,"PubkeyAuthentication"),a(", change it to "),o("code",null,"yes"),a(", then save ("),o("code",null,"ctrl+o"),a(") and exit ("),o("code",null,"ctrl+x"),a(").")])]),o("li",null,[o("p",null,[a("Restart the SSH service. (Note: Don't forget to use "),o("code",null,"sudo"),a(" to gain permission.)")])])],-1),qe=o("div",{class:"language-bash ext-sh line-numbers-mode"},[o("pre",{class:"language-bash"},[o("code",null,[o("span",{class:"token function"},"sudo"),a(" systemctl restart "),o("span",{class:"token function"},"ssh"),a("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br")])],-1),Je=o("p",null,[a("This is a command in the shell terminal to restart the SSH service with root privileges using the "),o("code",null,"systemctl"),a(" command.")],-1),Qe=o("ol",{start:"8"},[o("li",null,"The complete process is as follows:")],-1),Ze=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img17-rsa-login-full.2cf70977.gif",alt:"Enable SSH key verification and disable password verification"})],-1),$e=o("ol",{start:"4"},[o("li",null,"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.)")],-1),et=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img18-putty-privatekey-location.694b3b0d.png",alt:"Specify private key location in PuTTY"})],-1),tt=o("ol",{start:"5"},[o("li",null,[a("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 "),o("code",null,"VPS-SERVER"),a(" configuration, click "),o("code",null,"Open"),a(", and you can log in with just one click.")])],-1),nt=o("p",null,"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:",-1),ot=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img19-putty-privatekey-passphrase.d7ab41cd.png",alt:"Enter Private Key Password"})],-1),lt=o("ol",{start:"6"},[o("li",null,[a("Don't forget to set the corresponding key for "),o("code",null,"WinSCP"),a(", otherwise you won't be able to log in when you want to transfer files later.")])],-1),st=o("p",null,[o("img",{src:"/Xray-docs-next/assets/ch04-img20-winscp-privatekey-location.b1a9346e.png",alt:"WinSCP Specify Private Key Location"})],-1),at=o("div",{class:"custom-container warning"},[o("p",{class:"custom-container-title"},"Warning"),o("p",null,"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.")],-1),it=o("h2",{id:"_4-8-your-progress",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#_4-8-your-progress","aria-hidden":"true"},"#"),a(" 4.8 Your Progress")],-1),rt=o("p",null,"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.",-1),ut=o("p",null,"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)",-1),ct=o("blockquote",null,[o("p",null,"⬛⬛⬛⬛⬜⬜⬜⬜ 50%")],-1);i.render=function(a,i){const dt=e("OutboundLink");return t(),n(s,null,[r,u,c,d,h,m,p,g,y,f,w,b,v,k,x,S,T,P,I,A,L,C,_,W,H,Y,N,D,R,V,X,E,U,z,F,j,O,B,K,M,G,q,J,Q,Z,$,ee,te,ne,oe,le,se,ae,ie,re,ue,ce,de,he,me,pe,ge,ye,fe,we,be,ve,ke,xe,o("p",null,[Se,o("a",Te,[Pe,l(dt)]),Ie]),Ae,Le,Ce,_e,We,He,Ye,Ne,De,Re,Ve,Xe,Ee,Ue,ze,Fe,je,Oe,Be,Ke,Me,Ge,qe,Je,Qe,Ze,$e,et,tt,nt,ot,lt,st,at,it,rt,ut,ct],64)};export default i; diff --git a/assets/ch04-security.html.7f3b6fec.js b/assets/ch04-security.html.63f033f2.js similarity index 99% rename from assets/ch04-security.html.7f3b6fec.js rename to assets/ch04-security.html.63f033f2.js index 933f4f2b1..944b91104 100644 --- a/assets/ch04-security.html.7f3b6fec.js +++ b/assets/ch04-security.html.63f033f2.js @@ -1 +1 @@ -import{r as l,o as n,c as e,a as u,b as s,F as t,e as a}from"./app.755d843f.js";const c={},o=u("h1",{id:"【第-4-章】安全防护篇",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#【第-4-章】安全防护篇","aria-hidden":"true"},"#"),a(" 【第 4 章】安全防护篇")],-1),i=u("h2",{id:"_4-1-为什么要做安全防护",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-1-为什么要做安全防护","aria-hidden":"true"},"#"),a(" 4.1 为什么要做安全防护")],-1),d=u("p",null,"Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的网站、APP、服务、甚至线下基础设施都建立在 Linux 的基石之上,这背后牵涉到巨大的经济利益和商业价值,当然也就就意味着黑灰产有巨大的攻击动力。但是这些服务是如此重要、根本不允许出现重大的安全漏洞。于是无数的运维专业人员都在安全攻防的战场上拼搏努力,这才让大家能享受到基本稳定的现代化数字生活。",-1),r=u("p",null,"现在,你拥有了一台 VPS,并且将会敞开他的数据访问渠道来达到流量转发的目标,那就相当于你已经置身于安全攻防战场的第一线、直面所有风险。但与此同时,新人由于知识和信息的不足,看待安全问题是总是难免两极分化:要么觉得轻如鸿毛和自己没有半点关系,要么觉得重于泰山甚至惶惶不可终日。",-1),p=u("ul",null,[u("li",null,[u("p",null,"对于前者,我的建议是:安全无小事,尽量多查一些安全方面的信息,免得自己真的受了损失才后悔莫及")]),u("li",null,[u("p",null,"对于后者,我的建议是:不用紧张,我们的服务器仍不具有太高的价值、一般不会吸引到高水平的攻击,需要面对的基本都是一些自动化脚本的恶意扫描和登录尝试,跟着本文做一些基础的防护即可")])],-1),g=u("h2",{id:"_4-2-具体的风险到底是什么",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-2-具体的风险到底是什么","aria-hidden":"true"},"#"),a(" 4.2 具体的风险到底是什么")],-1),h=u("p",null,"就像我们在《远程登录篇》配置的一样,任何人只需要知道【IP 地址】+【端口】+【用户名】+【密码】这四个要素,就能登录你的 VPS 服务器。那很显然,这四要素的安全就是我们要防护的底线。我们来逐一分析:",-1),m=u("ol",null,[u("li",null,[u("p",null,"【IP 地址】:恶意脚本会随机尝试和扫描 IP 段,可以简单认为是公开信息、无法隐藏")]),u("li",null,[u("p",null,[a("【端口】:如果使用默认端口,那么【端口 = "),u("code",null,"22"),a("】")])]),u("li",null,[u("p",null,[a("【用户名】:如果使用默认用户,那么【用户名 = "),u("code",null,"root"),a("】")])]),u("li",null,[u("p",null,"【密码】:密码不存在默认值,一定是由 VPS 后台随机生成或由你自行设置的。也就是说,如果你的服务器都是默认设置,则四要素中的三个已经是已知的,那么你整个服务器的安全,就全部寄托在一串小小的密码上了。这时有几种情况:"),u("ul",null,[u("li",null,[u("p",null,"如果你用了 VPS 管理后台随机生成密码,它一般包含随机的十几个大小写混杂的字母和符号,相对比较安全")]),u("li",null,[u("p",null,[a("如果你为了好记、把密码改成了类似"),u("code",null,"123456"),a("这种超弱的密码,破解你的 VPS 服务器可谓不费吹灰之力")])]),u("li",null,[u("p",null,[a("如果你为了好记、把密码改成了比较复杂、但在别的地方用过的密码,其实也并不安全。你要明白黑客手里有作弊器,比如说"),u("code",null,"密码表"),a(",包含数万、数十万、数百万甚至更多曾经泄漏的真实密码)")])])])]),u("li",null,[u("p",null,"但你要明白,没有哪个黑客真的要坐在电脑前一次一次的尝试你的密码,全部的攻击尝试都是恶意脚本自动进行的,它会 24 小时不眠不休的工作。也许每天你酣睡之时,你的服务器都在经受着一轮又一轮的冲击。"),u("p",null,[a("一旦密码被成功撞破,意味着你的四要素全部被攻击者掌握,恶意脚本就会快速登录服务器、获取服务器的最高 "),u("code",null,"root"),a(" 控制权、安装部署它的恶意服务,然后就可以用你的服务器来 24 小时做各种坏事(比如挖矿、传播病毒、发送垃圾邮件、欺诈邮件、做 BT 中继、甚至暗网公众节点等等等等)。如果恶意脚本比较克制,其实可以做到相当的隐蔽性。而新人一般也不会去观察留意 VPS 的登录记录、进程变化、CPU 占用变化、流量变化等指标,你其实就很难发现自己被黑了。直到你的 VPS 服务商封禁你的账号、或者收到律师函为止。")])]),u("li",null,[u("p",null,[a("别忘了,你获得 VPS 时大概率需要使用真实的支付信息,你登录各种网站、社交平台时也会留下你的 IP 地址,这些都与你的身份有直接或者间接的关系。于是,"),u("strong",null,"一旦这些坏事发生,它们就不可避免的与你产生了关联。")])])],-1),b=u("h2",{id:"_4-3-我们要做的安全防护有哪些",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-3-我们要做的安全防护有哪些","aria-hidden":"true"},"#"),a(" 4.3 我们要做的安全防护有哪些")],-1),x=u("p",null,"基于上述分析,我们要做的,自然就是对【端口】、【用户名】、【密码】这三要素进行加强,来降低被攻破的风险:",-1),S=u("ol",null,[u("li",null,"【端口】:将 SSH 远程登录端口修改为【非 22 端口】 (4.4)"),u("li",null,"【用户名】:建立【非 root】的新用户、并禁用 root 用户 SSH 远程登录 (4.5、4.6)"),u("li",null,"【密码】:SSH 启用 RSA 密钥验证登录、同时禁用密码验证登录 (4.7)")],-1),y=u("p",null,"记得按顺序来,别把自己锁在门外了。",-1),P=u("h2",{id:"_4-4-将-ssh-远程登录端口修改为非-22-端口",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-4-将-ssh-远程登录端口修改为非-22-端口","aria-hidden":"true"},"#"),a(" 4.4 将 SSH 远程登录端口修改为非 22 端口")],-1),f=u("p",null,[a("现在,我们来解决【端口 = "),u("code",null,"22"),a("】的问题。(注意:有些 VPS 服务商,默认的端口已经是非 22 端口,那么你可以忽略这一步,当然也可以跟着本文改成别的端口)")],-1),v=u("ol",null,[u("li",null,[u("p",null,"小小白白 Linux 基础命令:"),u("table",null,[u("thead",null,[u("tr",null,[u("th",{style:{"text-align":"center"}},"编号"),u("th",{style:{"text-align":"center"}},"命令名称"),u("th",{style:{"text-align":"center"}},"命令说明")])]),u("tbody",null,[u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-03")]),u("td",{style:{"text-align":"center"}},[u("code",null,"nano")]),u("td",{style:{"text-align":"center"}},"文本编辑器")]),u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-04")]),u("td",{style:{"text-align":"center"}},[u("code",null,"systemctl restart")]),u("td",{style:{"text-align":"center"}},"重启某个服务")])])])]),u("li",null,[u("p",null,"小小白白 Linux 基础配置文件"),u("table",null,[u("thead",null,[u("tr",null,[u("th",{style:{"text-align":"center"}},"编号"),u("th",{style:{"text-align":"center"}},"配置文件位置"),u("th",{style:{"text-align":"center"}},"文件说明")])]),u("tbody",null,[u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"conf-01")]),u("td",{style:{"text-align":"center"}},[u("code",null,"/etc/ssh/sshd_config")]),u("td",{style:{"text-align":"center"}},"SSH 远程登录程序设置")])])])]),u("li",null,[u("p",null,[a("我们要做的第一件事,当然就是【用"),u("code",null,"nano"),a("这个文本编辑器打开"),u("code",null,"SSH远程登录程序设置"),a("】,在 Windows 下,你会【找到文件并双击】,在 Linux 下该怎么办呢?仔细看看上面的命令说明,是不是就很简单了?没错,就是:")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,[a("文件打开后,你就进入了"),u("code",null,"nano"),a("的界面,稍微观察一下,你会发现,它把重要的快捷键都显示在屏幕下方了(下图红框内),直接开卷考试、不用死记硬背,是不是很贴心呢?")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img01-nano-ui.1b0418d7.png",alt:"nano的界面"})])])],-1),k=u("ol",{start:"5"},[u("li",null,[u("p",null,[a("我们要做的第二件事,是【在打开的文件中找到"),u("code",null,"Port"),a("这一项,并修改它的端口】。Port 后面的数字就是 SSH 的端口,一般建议把它改成一个大于"),u("code",null,"1024"),a("小于"),u("code",null,"65535"),a("的整数(本文以"),u("code",null,"9753"),a("为例)。请结合"),u("code",null,"nano"),a("的快捷键,想一下该怎么操作呢?果然,你又说对了!就是:")]),u("ul",null,[u("li",null,[a("使用 "),u("code",null,"ctrl+w"),a(" 进入搜索模式,然后输入 "),u("code",null,"Port 22"),a(" 并回车")]),u("li",null,[a("删除 "),u("code",null,"22"),a(" 并改成 "),u("code",null,"9753")]),u("li",null,[a("说明:如果这一行开头有个"),u("code",null,"#"),a(",证明这一行【不生效】(被注释掉了),你可像我一样在文件最后写一个不带"),u("code",null,"#"),a("的,或者把"),u("code",null,"#"),a("删掉就好。")])]),u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,[a("本文以"),u("code",null,"9753"),a("为例,就意味着随着本文的发布,这个端口会变成一个不大不小的特征,也许会被攻击者优先尝试、也许被 GFW 干扰、阻断。所以我强烈建议你用一个自己想到的其他端口,毕竟,你有 6 万多个端口可以自由选择。")])])])],-1),T=u("ol",{start:"6"},[u("li",null,[u("p",null,"我们要做的第三件事,是【保存文件并退出】"),u("ul",null,[u("li",null,[a("如果第 3 步你有仔细观察,就会发现保存并不是常见的 "),u("code",null,"ctrl+s"),a("。")]),u("li",null,[a("正确的快捷键:保存是 "),u("code",null,"ctrl+o"),a(" + "),u("code",null,"回车"),a(",退出是 "),u("code",null,"ctrl+x")])])]),u("li",null,[u("p",null,"我们最后要做的事,是【重启 ssh 服务,使变更生效】"),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[a("systemctl restart "),u("span",{class:"token function"},"ssh"),a("\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,"完整流程演示如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img02-sshd-conf-full.91641b17.gif",alt:"修改非22端口演示"})])]),u("li",null,[u("p",null,"修改 PuTTY 配置"),u("p",null,[a("现在新的端口已经生效,下次使用 PuTTY 登录时就要用"),u("code",null,"9753"),a("了。所以现在请到 PuTTY 的设置中修改端口号码,然后保存 Session。嗯,你应该知道去哪里改了吧?(如果不知道的话,要重读前面的内容了哦!)")])])],-1),_=u("h2",{id:"_4-5-建立非-root-的新用户",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-5-建立非-root-的新用户","aria-hidden":"true"},"#"),a(" 4.5 建立非 root 的新用户")],-1),L=u("p",null,[a("第二步,我们来解决【用户名 = "),u("code",null,"root"),a("】的问题。")],-1),A=u("p",null,[a("首先你要理解, Linux 系统中的"),u("code",null,"root"),a(",不仅仅是一个管理员账号那么简单。它是整个系统的【根基】、是系统的主宰、至高无上的神。一旦"),u("code",null,"root"),a("账号出现安全问题,整个系统都只能任人鱼肉、无处可逃。那么就跟随我进行操作吧:")],-1),w=u("ol",null,[u("li",null,[u("p",null,"小小白白 Linux 基础命令:"),u("table",null,[u("thead",null,[u("tr",null,[u("th",{style:{"text-align":"center"}},"编号"),u("th",{style:{"text-align":"center"}},"命令名称"),u("th",{style:{"text-align":"center"}},"命令说明")])]),u("tbody",null,[u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-05")]),u("td",{style:{"text-align":"center"}},[u("code",null,"adduser")]),u("td",{style:{"text-align":"center"}},"给系统新增用户")]),u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-06")]),u("td",{style:{"text-align":"center"}},[u("code",null,"apt install")]),u("td",{style:{"text-align":"center"}},"安装某个软件")]),u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-07")]),u("td",{style:{"text-align":"center"}},[u("code",null,"visudo")]),u("td",{style:{"text-align":"center"}},"修改 sudo 权限设置专用编辑器")])])])]),u("li",null,[u("p",null,[a("我们要做的第一件事,是【新增一个用户并设定登录密码】,名字你可以随便起,我这里以"),u("code",null,"vpsadmin"),a("为例:")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,"adduser vpsadmin\n")]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])]),u("p",null,[a("执行命令后,根据提示操作即可。请务必设置一个用户密码(别忘记设置密码时你时看不到 "),u("code",null,"******"),a(" 的)。之后系统会询问你一些用户的附加信息,这些就可以无视,一路回车即可。")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img03-adduser.c309caca.png",alt:"建立新用户"})]),u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,[a("本文以"),u("code",null,"vpsadmin"),a("为例,就意味着随着本文的发布,这个用户名也会变成一个不大不小的特征,也许会被攻击者优先尝试。所以和端口一样,我强烈建议你用一个自己想到的其他用户名。")])])]),u("li",null,[u("p",null,"完整流程演示如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img04-adduser-full.b1abf911.gif",alt:"建立新用户"})])]),u("li",null,[u("p",null,[a("我们要做的第二件事,是【安装"),u("code",null,"sudo"),a("功能】("),u("code",null,"sudo"),a(" 就是在关键时刻,让普通账户临时获得 "),u("code",null,"root"),a(" 的神力,战力全开拯救世界)")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"apt"),a(" update "),u("span",{class:"token operator"},"&&"),a(),u("span",{class:"token function"},"apt"),a(),u("span",{class:"token function"},"install"),a(),u("span",{class:"token function"},"sudo"),a("\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])]),u("p",null,[a("聪明的你大概已经发现,这一行命令其实是两个命令。前一半 "),u("code",null,"apt update"),a(" 你之前已经见过并且用过了,是去服务器刷新软件版本信息。后面的 "),u("code",null,"apt install"),a(" 就是这一次要用到的【安装命令】。两条连接在一起,就是让系统去【刷新可用的最新软件,然后安装最新版的"),u("code",null,"sudo"),a("程序】。 "),u("code",null,"&&"),a(" 则是把两个命令连起来执行的意思。")])]),u("li",null,[u("p",null,[a("我们要做的第三件事,是【把"),u("code",null,"vpsadmin"),a("用户加入"),u("code",null,"sudo"),a("名单里,让他有资格借用"),u("code",null,"root"),a("的神力】")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,"visudo\n")]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])]),u("p",null,[a("在 "),u("code",null,"User Privilege Specification"),a(" 下加入一行 "),u("code",null,"vpsadmin ALL=(ALL) NOPASSWD: ALL"),a(" 即可。")]),u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,[a("我要特别说明的是"),u("code",null,"NOPASSWD"),a("这个设置,它的意思是"),u("code",null,"vpsadmin"),a("用户临时使用"),u("code",null,"root"),a("权限时,不用额外输入密码。"),u("strong",null,"这与一般的安全建议相反"),a("。我之所以如此推荐,是因为很多新人不顾危险坚持使用"),u("code",null,"root"),a("账号就是因为用"),u("code",null,"root"),a("时不用重复输入密码、觉得轻松。“两害相权取其轻”,我认为【直接用"),u("code",null,"root"),a("用户的风险】大于【使用"),u("code",null,"sudo"),a(" 时不用输密码的风险】,所以做了以上的建议。")]),u("p",null,[a("如果你希望遵守传统习惯、每次使用"),u("code",null,"sudo"),a("时需要输入密码,那么这一行改成 "),u("code",null,"vpsadmin ALL=(ALL:ALL) ALL"),a(" 即可。")])])]),u("li",null,[u("p",null,"完整流程演示如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img05-sudo-full.d131730a.gif",alt:"建立新用户"})])])],-1),V=u("h2",{id:"_4-6-禁用-root-用户-ssh-远程登录",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-6-禁用-root-用户-ssh-远程登录","aria-hidden":"true"},"#"),a(" 4.6 禁用 root 用户 SSH 远程登录")],-1),X=u("ol",null,[u("li",null,[u("p",null,[a("现在你已经逐渐熟悉 Linux 了,所以这次换你思考,我们要做的第一件事是什么呢?没错,还是【用"),u("code",null,"nano"),a("编辑器打开"),u("code",null,"SSH远程登录程序设置"),a("】,什么,你想不起来怎么操作了?那去复习一下上面的内容再回来吧!............ 正确答案:")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,[a("找到"),u("code",null,"PermitRootLogin Yes"),a("这一项,然后把它后面的设定值改为"),u("code",null,"no"),a("即可。还记得怎么操作吗?............ 正确答案:")]),u("ul",null,[u("li",null,[a("使用 "),u("code",null,"ctrl+w"),a(" 进入搜索模式,然后输入 "),u("code",null,"PermitRootLogin"),a(" 并回车")]),u("li",null,[a("删除 "),u("code",null,"yes"),a(" 并改成 "),u("code",null,"no")])])]),u("li",null,[u("p",null,"保存文件并退出。还记得怎么操作吗?............ 正确答案:"),u("ul",null,[u("li",null,[a("保存是 "),u("code",null,"ctrl+o"),a(",然后 "),u("code",null,"回车"),a(" 确认")]),u("li",null,[a("退出是 "),u("code",null,"ctrl+x")])])]),u("li",null,[u("p",null,"重启 ssh 服务,让变更生效。还记得............ 算了直接公布正确答案:"),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[a("systemctl restart "),u("span",{class:"token function"},"ssh"),a("\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,"完整流程演示如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img06-ssh-no-root-full.a9943c8b.gif",alt:"禁用root用户SSH远程登录"})])]),u("li",null,[u("p",null,[a("下次通过 PuTTY 远程 SSH 登录的时候,"),u("code",null,"root"),a("用户已无法连接,用户名就要换成"),u("code",null,"vpsadmin"),a("了!方便起见,我们可以在 PuTTY 中把"),u("code",null,"vpsadmin"),a("设置成默认登录用户名。(啰嗦君:别忘了保存 Session)")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img07-putty-default-user.a515e814.png",alt:"PuTTY设置默认用户名"})])])],-1),H=u("h2",{id:"_4-7-使用-rsa-密钥登录并禁用密码登录",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-7-使用-rsa-密钥登录并禁用密码登录","aria-hidden":"true"},"#"),a(" 4.7 使用 RSA 密钥登录并禁用密码登录")],-1),Y=u("p",null,"第三步,我们来解决【密码】可能被撞破的问题。",-1),C=u("p",null,"前面我说过,黑客并不是很蠢的用穷举法破解你的密码,而是会用一些比如“密码表”的作弊手段。除非你用的是随机生成的超长密码(比如借助 1Password,或者 macOS 的 keychain 等密码管理工具),否则很容易中招。",-1),R=u("p",null,"超长随机密码虽然安全性有所提高,但是基本上无法记忆,手动输入也十分麻烦易错。为了解决这个困境,我们可以直接弃用【密码验证】方式,改用更安全的【密钥验证】。",-1),W=u("p",null,"所谓的【密钥验证】,就是生成【一对】相关联的密钥文件(公钥和私钥),然后把【公钥】上传到 VPS 备用。每次登录时,SSH 会将【公钥】和【私钥】进行匹配,若验证是正确的【密钥对】,则验证通过。(换言之,你无需记忆和输入复杂的密码,只要保护好【私钥】这个文件不外泄即可)",-1),E=u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,[a("本文以 "),u("code",null,"RSA"),a(" 密钥举例,是因为 "),u("code",null,"RSA"),a(" 密钥在各种设备、各种 "),u("code",null,"SSH"),a(" 客户端中有广泛悠久的支持历史,且目前依然能提供够用的安全性。但它绝非唯一选择。")]),u("p",null,"其他的常见密钥还有:"),u("ul",null,[u("li",null,[u("code",null,"DSA"),a(" - 已经从数学层面被证明不安全,所以永远不要用它")]),u("li",null,[u("code",null,"ECDSA"),a(" - 密钥小安全性高,但其算法被指留有 NSA 的后门,如果你的 VPS 上有值得 NSA 关注的东西就不要用它")]),u("li",null,[u("code",null,"Ed25519"),a(" - 这是一个与 "),u("code",null,"ECDSA"),a(" 十分类似的算法,故具有相似的性能优势。同时其文档全部公开,所以普遍认为无后门")])]),u("p",null,[a("所以,如果你的设备和软件都支持的话,我建议优先选择 "),u("code",null,"Ed25519"),a(" 密钥。")])],-1),z=u("p",null,"那我们现在就来配置【密钥验证】吧!",-1),D=u("li",null,[u("p",null,[a("运行"),u("code",null,"PuTTYgen"),a(" (PuTTY 密钥生成器)。位置是 "),u("code",null,"开始菜单"),a(" --\x3e "),u("code",null,"所有程序"),a(" --\x3e "),u("code",null,"PuTTY (64-bit)"),a(" --\x3e "),u("code",null,"PuTTYgen")]),u("ol",null,[u("li",null,[u("p",null,[a("点击"),u("code",null,"Generate"),a("开始生成(在界面空白处乱晃鼠标增加随机数)")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img08-puttygen-save.32267800.png",alt:"生成密钥"})])])]),u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,[a("本图中是以 "),u("code",null,"2048"),a(" 位的 "),u("code",null,"RSA"),a(" 密钥为例的。但实际上,如果要获得与 "),u("code",null,"EDCSA/Ed25519"),a(" 的 "),u("code",null,"256"),a(" 位密钥相同的安全性,你需要使用 "),u("code",null,"3072"),a(" 位的 "),u("code",null,"RSA"),a(" 密钥。(即右下角的数字改成 "),u("code",null,"3072"),a(")")])]),u("ol",{start:"2"},[u("li",null,[u("p",null,"你可以给私钥设置密码,增加一层安全性")]),u("li",null,[u("p",null,[a("点击 "),u("code",null,"Save public key"),a(" 保存公钥,文件名为 "),u("code",null,"id_rsa.pub")])]),u("li",null,[u("p",null,[a("点击 "),u("code",null,"Save private key"),a(" 保存私钥,文件名为 "),u("code",null,"id_rsa"),a(" (PuTTY 私钥自带"),u("code",null,".ppk"),a("后缀)")])]),u("li",null,[u("p",null,[a("最重要的,将上方红框内的内容,向下滚动全部复制出来并保存,文件名为 "),u("code",null,"authorized_keys"),a("。(用 vscode 保存,默认会变成带"),u("code",null,"txt"),a("后缀的文本文件,这没关系,之后上传 VPS 时我们会把后缀名去掉)")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img09-puttygen-save-keys.a599bbdf.png",alt:"保存密钥"})])])])],-1),O=u("p",null,[a("将公钥上传至 VPS 的"),u("code",null,"vpsadmin"),a("用户下")],-1),I=u("li",null,[u("p",null,[a("这一步就需要用到之前准备的"),u("code",null,"WinSCP"),a("了。")])],-1),N=a("去"),F={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},G=a("官网"),U=a("下载并安装,会提示你导入 PuTTY 的设置,当然一键导入啦!"),j=u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img10-winscp-import-session.342a201a.png",alt:"一键导入Session"})],-1),q=u("li",null,[u("p",null,"如果没有提示导入或者你已经提前安装好了,那按照下图进行配置即可"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img11-winscp-ui.70f60717.png",alt:"WinSCP登录设置"})])],-1),B=u("li",null,[u("p",null,"WinSCP 左边的目录就是本地电脑上的文件夹和文件,请定位到密钥所在的文件夹")],-1),J=u("li",null,[u("p",null,[a("WinSCP 右边的目录则是 VPS 服务器上的文件夹和文件,默认就在 "),u("code",null,"/home/vpsadmin/"),a(" 文件夹,此时在请点击右下角 "),u("code",null,"X hidden"),a(" 来显示隐藏文件")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img12-winscp-locations.f31ffa53.png",alt:"本地和远程文件夹"})])],-1),K=u("li",null,[u("p",null,[a("在右边(VPS 中)点击右键并新建文件夹,起名"),u("code",null,".ssh"),a(" (注意有一个"),u("code",null,"."),a(")")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img13-winscp-newfolder-key.66d24a49.png",alt:"在VPS中建立放置公钥的文件夹"})])],-1),M=u("li",null,[u("p",null,[a("将【公钥】"),u("code",null,"authorized_keys"),a("上传到"),u("code",null,".ssh"),a("文件夹内")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img14-winscp-upload-key.9fa9340c.png",alt:"上传authorized_keys"})])],-1),Q=u("li",null,[u("p",null,[a("在上传时,将【公钥】从 "),u("code",null,"authorized_keys.txt"),a(" 改名为 "),u("code",null,"authorized_keys"),a("(去掉"),u("code",null,".txt"),a("这个后缀名)")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img15-winscp-rename-key.79776390.png",alt:"确保没有任何后缀"})])],-1),Z=u("li",null,[u("p",null,"完整流程演示如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img16-winscp-full.9c46d03b.gif",alt:"WinSCP操作完整演示"})])],-1),$=u("li",null,[u("p",null,"在 VPS 端设置 SSH 启用 RSA 密钥验证登录、同时禁用密码验证登录"),u("ol",null,[u("li",null,[u("p",null,"小小白白 Linux 基础命令:"),u("table",null,[u("thead",null,[u("tr",null,[u("th",{style:{"text-align":"center"}},"编号"),u("th",{style:{"text-align":"center"}},"命令名称"),u("th",{style:{"text-align":"center"}},"命令说明")])]),u("tbody",null,[u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-08")]),u("td",{style:{"text-align":"center"}},[u("code",null,"sudo")]),u("td",{style:{"text-align":"center"}},[a("用"),u("code",null,"root"),a("权限运行某个命令")])]),u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-09")]),u("td",{style:{"text-align":"center"}},[u("code",null,"chmod")]),u("td",{style:{"text-align":"center"}},"修改目标文件/文件夹的权限")])])])]),u("li",null,[u("p",null,"SSH 远程连接到 VPS 上(PuTTY)")]),u("li",null,[u("p",null,[a("修改 "),u("code",null,"authorized_keys"),a(" 文件权限为 "),u("code",null,"600"),a(" (仅所有者可读可写)")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"chmod"),a(),u("span",{class:"token number"},"600"),a(" ~/.ssh/authorized_keys\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,[a("修改 SSH 配置。这个我们已经用了很多次,但现在我们已经从无所不能的"),u("code",null,"root"),a("变成了普通用户"),u("code",null,"vpsadmin"),a(",此时的我们是没有权限直接编辑 SSH 配置的。这时候就需要使用"),u("code",null,"sudo"),a("命令了:")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"sudo"),a(),u("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,[a("找到("),u("code",null,"ctrl+w"),a(") "),u("code",null,"PasswordAuthentication"),a(" 改成 "),u("code",null,"no")])]),u("li",null,[u("p",null,[a("找到("),u("code",null,"ctrl+w"),a(") "),u("code",null,"PubkeyAuthentication"),a(" 改成 "),u("code",null,"yes"),a(",然后保存("),u("code",null,"ctrl+o"),a(")退出("),u("code",null,"ctrl+x"),a(")")])]),u("li",null,[u("p",null,[a("重启 SSH 服务。(啰嗦君:别忘了现在需要使用"),u("code",null,"sudo"),a("来获得权限)")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"sudo"),a(" systemctl restart "),u("span",{class:"token function"},"ssh"),a("\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,"完整流程如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img17-rsa-login-full.2cf70977.gif",alt:"SSH开启密钥验证并禁用密码验证"})])])])],-1),ll=u("li",null,[u("p",null,"VPS 端已经设置好了公钥,现在要给 PuTTY 指定私钥位置供登录时使用(啰嗦君:别忘了保存 Session)"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img18-putty-privatekey-location.694b3b0d.png",alt:"PuTTY指定私钥位置"})])],-1),nl=u("li",null,[u("p",null,[a("至此,【密钥登录】已成功开启、【密码验证】已成功关闭、并且还给 PuTTY 保存了默认的登录用户名和私钥。未来使用 PuTTY 登录时,载入"),u("code",null,"VPS-SERVER"),a("配置后,点击"),u("code",null,"Open"),a("就可以一键登录了。")]),u("p",null,"如果你给私钥设置了密码保护,登录时当然还需要输入这个密码才能使用密钥,如下图:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img19-putty-privatekey-passphrase.d7ab41cd.png",alt:"输入私钥密码"})])],-1),el=u("li",null,[u("p",null,[a("别忘了给"),u("code",null,"WinSCP"),a("也做对应的密钥设置,否则之后想要传输文件时就无法登录了:")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img20-winscp-privatekey-location.b1a9346e.png",alt:"WinSCP指定私钥位置"})])],-1),ul=u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,"任何需要借助 SSH 进行登录的软件都需要密钥验证了,软件过多,无法逐一展示,请根据你的需要自行设置好哦")],-1),sl=u("h2",{id:"_4-8-你的进度",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-8-你的进度","aria-hidden":"true"},"#"),a(" 4.8 你的进度")],-1),tl=u("p",null,"到这里为止,你的 VPS 已经完成了【端口】、【用户名】、【密码】这三要素的基本安全保障,虽然远称不上固若金汤,但一般的恶意脚本应该已经无法对你造成伤害了!",-1),al=u("p",null,"现在我们终于有了一个安全的系统基础,下一章,我们就可以开始逐步安装配置 Xray 需要的基础设施了!(什么基础设施呢?一个网页,一张证书)",-1),cl=u("blockquote",null,[u("p",null,"⬛⬛⬛⬛⬜⬜⬜⬜ 50%")],-1);c.render=function(a,c){const ol=l("OutboundLink");return n(),e(t,null,[o,i,d,r,p,g,h,m,b,x,S,y,P,f,v,k,T,_,L,A,w,V,X,H,Y,C,R,W,E,z,u("ol",null,[D,u("li",null,[O,u("ol",null,[I,u("li",null,[u("p",null,[N,u("a",F,[G,s(ol)]),U]),j]),q,B,J,K,M,Q,Z])]),$,ll,nl,el]),ul,sl,tl,al,cl],64)};export default c; +import{r as l,o as n,c as e,a as u,b as s,F as t,e as a}from"./app.48111a85.js";const c={},o=u("h1",{id:"【第-4-章】安全防护篇",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#【第-4-章】安全防护篇","aria-hidden":"true"},"#"),a(" 【第 4 章】安全防护篇")],-1),i=u("h2",{id:"_4-1-为什么要做安全防护",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-1-为什么要做安全防护","aria-hidden":"true"},"#"),a(" 4.1 为什么要做安全防护")],-1),d=u("p",null,"Linux 服务器的安全防护是一个纷繁复杂的巨大课题。无数的网站、APP、服务、甚至线下基础设施都建立在 Linux 的基石之上,这背后牵涉到巨大的经济利益和商业价值,当然也就就意味着黑灰产有巨大的攻击动力。但是这些服务是如此重要、根本不允许出现重大的安全漏洞。于是无数的运维专业人员都在安全攻防的战场上拼搏努力,这才让大家能享受到基本稳定的现代化数字生活。",-1),r=u("p",null,"现在,你拥有了一台 VPS,并且将会敞开他的数据访问渠道来达到流量转发的目标,那就相当于你已经置身于安全攻防战场的第一线、直面所有风险。但与此同时,新人由于知识和信息的不足,看待安全问题是总是难免两极分化:要么觉得轻如鸿毛和自己没有半点关系,要么觉得重于泰山甚至惶惶不可终日。",-1),p=u("ul",null,[u("li",null,[u("p",null,"对于前者,我的建议是:安全无小事,尽量多查一些安全方面的信息,免得自己真的受了损失才后悔莫及")]),u("li",null,[u("p",null,"对于后者,我的建议是:不用紧张,我们的服务器仍不具有太高的价值、一般不会吸引到高水平的攻击,需要面对的基本都是一些自动化脚本的恶意扫描和登录尝试,跟着本文做一些基础的防护即可")])],-1),g=u("h2",{id:"_4-2-具体的风险到底是什么",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-2-具体的风险到底是什么","aria-hidden":"true"},"#"),a(" 4.2 具体的风险到底是什么")],-1),h=u("p",null,"就像我们在《远程登录篇》配置的一样,任何人只需要知道【IP 地址】+【端口】+【用户名】+【密码】这四个要素,就能登录你的 VPS 服务器。那很显然,这四要素的安全就是我们要防护的底线。我们来逐一分析:",-1),m=u("ol",null,[u("li",null,[u("p",null,"【IP 地址】:恶意脚本会随机尝试和扫描 IP 段,可以简单认为是公开信息、无法隐藏")]),u("li",null,[u("p",null,[a("【端口】:如果使用默认端口,那么【端口 = "),u("code",null,"22"),a("】")])]),u("li",null,[u("p",null,[a("【用户名】:如果使用默认用户,那么【用户名 = "),u("code",null,"root"),a("】")])]),u("li",null,[u("p",null,"【密码】:密码不存在默认值,一定是由 VPS 后台随机生成或由你自行设置的。也就是说,如果你的服务器都是默认设置,则四要素中的三个已经是已知的,那么你整个服务器的安全,就全部寄托在一串小小的密码上了。这时有几种情况:"),u("ul",null,[u("li",null,[u("p",null,"如果你用了 VPS 管理后台随机生成密码,它一般包含随机的十几个大小写混杂的字母和符号,相对比较安全")]),u("li",null,[u("p",null,[a("如果你为了好记、把密码改成了类似"),u("code",null,"123456"),a("这种超弱的密码,破解你的 VPS 服务器可谓不费吹灰之力")])]),u("li",null,[u("p",null,[a("如果你为了好记、把密码改成了比较复杂、但在别的地方用过的密码,其实也并不安全。你要明白黑客手里有作弊器,比如说"),u("code",null,"密码表"),a(",包含数万、数十万、数百万甚至更多曾经泄漏的真实密码)")])])])]),u("li",null,[u("p",null,"但你要明白,没有哪个黑客真的要坐在电脑前一次一次的尝试你的密码,全部的攻击尝试都是恶意脚本自动进行的,它会 24 小时不眠不休的工作。也许每天你酣睡之时,你的服务器都在经受着一轮又一轮的冲击。"),u("p",null,[a("一旦密码被成功撞破,意味着你的四要素全部被攻击者掌握,恶意脚本就会快速登录服务器、获取服务器的最高 "),u("code",null,"root"),a(" 控制权、安装部署它的恶意服务,然后就可以用你的服务器来 24 小时做各种坏事(比如挖矿、传播病毒、发送垃圾邮件、欺诈邮件、做 BT 中继、甚至暗网公众节点等等等等)。如果恶意脚本比较克制,其实可以做到相当的隐蔽性。而新人一般也不会去观察留意 VPS 的登录记录、进程变化、CPU 占用变化、流量变化等指标,你其实就很难发现自己被黑了。直到你的 VPS 服务商封禁你的账号、或者收到律师函为止。")])]),u("li",null,[u("p",null,[a("别忘了,你获得 VPS 时大概率需要使用真实的支付信息,你登录各种网站、社交平台时也会留下你的 IP 地址,这些都与你的身份有直接或者间接的关系。于是,"),u("strong",null,"一旦这些坏事发生,它们就不可避免的与你产生了关联。")])])],-1),b=u("h2",{id:"_4-3-我们要做的安全防护有哪些",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-3-我们要做的安全防护有哪些","aria-hidden":"true"},"#"),a(" 4.3 我们要做的安全防护有哪些")],-1),x=u("p",null,"基于上述分析,我们要做的,自然就是对【端口】、【用户名】、【密码】这三要素进行加强,来降低被攻破的风险:",-1),S=u("ol",null,[u("li",null,"【端口】:将 SSH 远程登录端口修改为【非 22 端口】 (4.4)"),u("li",null,"【用户名】:建立【非 root】的新用户、并禁用 root 用户 SSH 远程登录 (4.5、4.6)"),u("li",null,"【密码】:SSH 启用 RSA 密钥验证登录、同时禁用密码验证登录 (4.7)")],-1),y=u("p",null,"记得按顺序来,别把自己锁在门外了。",-1),P=u("h2",{id:"_4-4-将-ssh-远程登录端口修改为非-22-端口",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-4-将-ssh-远程登录端口修改为非-22-端口","aria-hidden":"true"},"#"),a(" 4.4 将 SSH 远程登录端口修改为非 22 端口")],-1),f=u("p",null,[a("现在,我们来解决【端口 = "),u("code",null,"22"),a("】的问题。(注意:有些 VPS 服务商,默认的端口已经是非 22 端口,那么你可以忽略这一步,当然也可以跟着本文改成别的端口)")],-1),v=u("ol",null,[u("li",null,[u("p",null,"小小白白 Linux 基础命令:"),u("table",null,[u("thead",null,[u("tr",null,[u("th",{style:{"text-align":"center"}},"编号"),u("th",{style:{"text-align":"center"}},"命令名称"),u("th",{style:{"text-align":"center"}},"命令说明")])]),u("tbody",null,[u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-03")]),u("td",{style:{"text-align":"center"}},[u("code",null,"nano")]),u("td",{style:{"text-align":"center"}},"文本编辑器")]),u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-04")]),u("td",{style:{"text-align":"center"}},[u("code",null,"systemctl restart")]),u("td",{style:{"text-align":"center"}},"重启某个服务")])])])]),u("li",null,[u("p",null,"小小白白 Linux 基础配置文件"),u("table",null,[u("thead",null,[u("tr",null,[u("th",{style:{"text-align":"center"}},"编号"),u("th",{style:{"text-align":"center"}},"配置文件位置"),u("th",{style:{"text-align":"center"}},"文件说明")])]),u("tbody",null,[u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"conf-01")]),u("td",{style:{"text-align":"center"}},[u("code",null,"/etc/ssh/sshd_config")]),u("td",{style:{"text-align":"center"}},"SSH 远程登录程序设置")])])])]),u("li",null,[u("p",null,[a("我们要做的第一件事,当然就是【用"),u("code",null,"nano"),a("这个文本编辑器打开"),u("code",null,"SSH远程登录程序设置"),a("】,在 Windows 下,你会【找到文件并双击】,在 Linux 下该怎么办呢?仔细看看上面的命令说明,是不是就很简单了?没错,就是:")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,[a("文件打开后,你就进入了"),u("code",null,"nano"),a("的界面,稍微观察一下,你会发现,它把重要的快捷键都显示在屏幕下方了(下图红框内),直接开卷考试、不用死记硬背,是不是很贴心呢?")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img01-nano-ui.1b0418d7.png",alt:"nano的界面"})])])],-1),k=u("ol",{start:"5"},[u("li",null,[u("p",null,[a("我们要做的第二件事,是【在打开的文件中找到"),u("code",null,"Port"),a("这一项,并修改它的端口】。Port 后面的数字就是 SSH 的端口,一般建议把它改成一个大于"),u("code",null,"1024"),a("小于"),u("code",null,"65535"),a("的整数(本文以"),u("code",null,"9753"),a("为例)。请结合"),u("code",null,"nano"),a("的快捷键,想一下该怎么操作呢?果然,你又说对了!就是:")]),u("ul",null,[u("li",null,[a("使用 "),u("code",null,"ctrl+w"),a(" 进入搜索模式,然后输入 "),u("code",null,"Port 22"),a(" 并回车")]),u("li",null,[a("删除 "),u("code",null,"22"),a(" 并改成 "),u("code",null,"9753")]),u("li",null,[a("说明:如果这一行开头有个"),u("code",null,"#"),a(",证明这一行【不生效】(被注释掉了),你可像我一样在文件最后写一个不带"),u("code",null,"#"),a("的,或者把"),u("code",null,"#"),a("删掉就好。")])]),u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,[a("本文以"),u("code",null,"9753"),a("为例,就意味着随着本文的发布,这个端口会变成一个不大不小的特征,也许会被攻击者优先尝试、也许被 GFW 干扰、阻断。所以我强烈建议你用一个自己想到的其他端口,毕竟,你有 6 万多个端口可以自由选择。")])])])],-1),T=u("ol",{start:"6"},[u("li",null,[u("p",null,"我们要做的第三件事,是【保存文件并退出】"),u("ul",null,[u("li",null,[a("如果第 3 步你有仔细观察,就会发现保存并不是常见的 "),u("code",null,"ctrl+s"),a("。")]),u("li",null,[a("正确的快捷键:保存是 "),u("code",null,"ctrl+o"),a(" + "),u("code",null,"回车"),a(",退出是 "),u("code",null,"ctrl+x")])])]),u("li",null,[u("p",null,"我们最后要做的事,是【重启 ssh 服务,使变更生效】"),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[a("systemctl restart "),u("span",{class:"token function"},"ssh"),a("\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,"完整流程演示如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img02-sshd-conf-full.91641b17.gif",alt:"修改非22端口演示"})])]),u("li",null,[u("p",null,"修改 PuTTY 配置"),u("p",null,[a("现在新的端口已经生效,下次使用 PuTTY 登录时就要用"),u("code",null,"9753"),a("了。所以现在请到 PuTTY 的设置中修改端口号码,然后保存 Session。嗯,你应该知道去哪里改了吧?(如果不知道的话,要重读前面的内容了哦!)")])])],-1),_=u("h2",{id:"_4-5-建立非-root-的新用户",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-5-建立非-root-的新用户","aria-hidden":"true"},"#"),a(" 4.5 建立非 root 的新用户")],-1),L=u("p",null,[a("第二步,我们来解决【用户名 = "),u("code",null,"root"),a("】的问题。")],-1),A=u("p",null,[a("首先你要理解, Linux 系统中的"),u("code",null,"root"),a(",不仅仅是一个管理员账号那么简单。它是整个系统的【根基】、是系统的主宰、至高无上的神。一旦"),u("code",null,"root"),a("账号出现安全问题,整个系统都只能任人鱼肉、无处可逃。那么就跟随我进行操作吧:")],-1),w=u("ol",null,[u("li",null,[u("p",null,"小小白白 Linux 基础命令:"),u("table",null,[u("thead",null,[u("tr",null,[u("th",{style:{"text-align":"center"}},"编号"),u("th",{style:{"text-align":"center"}},"命令名称"),u("th",{style:{"text-align":"center"}},"命令说明")])]),u("tbody",null,[u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-05")]),u("td",{style:{"text-align":"center"}},[u("code",null,"adduser")]),u("td",{style:{"text-align":"center"}},"给系统新增用户")]),u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-06")]),u("td",{style:{"text-align":"center"}},[u("code",null,"apt install")]),u("td",{style:{"text-align":"center"}},"安装某个软件")]),u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-07")]),u("td",{style:{"text-align":"center"}},[u("code",null,"visudo")]),u("td",{style:{"text-align":"center"}},"修改 sudo 权限设置专用编辑器")])])])]),u("li",null,[u("p",null,[a("我们要做的第一件事,是【新增一个用户并设定登录密码】,名字你可以随便起,我这里以"),u("code",null,"vpsadmin"),a("为例:")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,"adduser vpsadmin\n")]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])]),u("p",null,[a("执行命令后,根据提示操作即可。请务必设置一个用户密码(别忘记设置密码时你时看不到 "),u("code",null,"******"),a(" 的)。之后系统会询问你一些用户的附加信息,这些就可以无视,一路回车即可。")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img03-adduser.c309caca.png",alt:"建立新用户"})]),u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,[a("本文以"),u("code",null,"vpsadmin"),a("为例,就意味着随着本文的发布,这个用户名也会变成一个不大不小的特征,也许会被攻击者优先尝试。所以和端口一样,我强烈建议你用一个自己想到的其他用户名。")])])]),u("li",null,[u("p",null,"完整流程演示如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img04-adduser-full.b1abf911.gif",alt:"建立新用户"})])]),u("li",null,[u("p",null,[a("我们要做的第二件事,是【安装"),u("code",null,"sudo"),a("功能】("),u("code",null,"sudo"),a(" 就是在关键时刻,让普通账户临时获得 "),u("code",null,"root"),a(" 的神力,战力全开拯救世界)")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"apt"),a(" update "),u("span",{class:"token operator"},"&&"),a(),u("span",{class:"token function"},"apt"),a(),u("span",{class:"token function"},"install"),a(),u("span",{class:"token function"},"sudo"),a("\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])]),u("p",null,[a("聪明的你大概已经发现,这一行命令其实是两个命令。前一半 "),u("code",null,"apt update"),a(" 你之前已经见过并且用过了,是去服务器刷新软件版本信息。后面的 "),u("code",null,"apt install"),a(" 就是这一次要用到的【安装命令】。两条连接在一起,就是让系统去【刷新可用的最新软件,然后安装最新版的"),u("code",null,"sudo"),a("程序】。 "),u("code",null,"&&"),a(" 则是把两个命令连起来执行的意思。")])]),u("li",null,[u("p",null,[a("我们要做的第三件事,是【把"),u("code",null,"vpsadmin"),a("用户加入"),u("code",null,"sudo"),a("名单里,让他有资格借用"),u("code",null,"root"),a("的神力】")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,"visudo\n")]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])]),u("p",null,[a("在 "),u("code",null,"User Privilege Specification"),a(" 下加入一行 "),u("code",null,"vpsadmin ALL=(ALL) NOPASSWD: ALL"),a(" 即可。")]),u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,[a("我要特别说明的是"),u("code",null,"NOPASSWD"),a("这个设置,它的意思是"),u("code",null,"vpsadmin"),a("用户临时使用"),u("code",null,"root"),a("权限时,不用额外输入密码。"),u("strong",null,"这与一般的安全建议相反"),a("。我之所以如此推荐,是因为很多新人不顾危险坚持使用"),u("code",null,"root"),a("账号就是因为用"),u("code",null,"root"),a("时不用重复输入密码、觉得轻松。“两害相权取其轻”,我认为【直接用"),u("code",null,"root"),a("用户的风险】大于【使用"),u("code",null,"sudo"),a(" 时不用输密码的风险】,所以做了以上的建议。")]),u("p",null,[a("如果你希望遵守传统习惯、每次使用"),u("code",null,"sudo"),a("时需要输入密码,那么这一行改成 "),u("code",null,"vpsadmin ALL=(ALL:ALL) ALL"),a(" 即可。")])])]),u("li",null,[u("p",null,"完整流程演示如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img05-sudo-full.d131730a.gif",alt:"建立新用户"})])])],-1),V=u("h2",{id:"_4-6-禁用-root-用户-ssh-远程登录",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-6-禁用-root-用户-ssh-远程登录","aria-hidden":"true"},"#"),a(" 4.6 禁用 root 用户 SSH 远程登录")],-1),X=u("ol",null,[u("li",null,[u("p",null,[a("现在你已经逐渐熟悉 Linux 了,所以这次换你思考,我们要做的第一件事是什么呢?没错,还是【用"),u("code",null,"nano"),a("编辑器打开"),u("code",null,"SSH远程登录程序设置"),a("】,什么,你想不起来怎么操作了?那去复习一下上面的内容再回来吧!............ 正确答案:")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,[a("找到"),u("code",null,"PermitRootLogin Yes"),a("这一项,然后把它后面的设定值改为"),u("code",null,"no"),a("即可。还记得怎么操作吗?............ 正确答案:")]),u("ul",null,[u("li",null,[a("使用 "),u("code",null,"ctrl+w"),a(" 进入搜索模式,然后输入 "),u("code",null,"PermitRootLogin"),a(" 并回车")]),u("li",null,[a("删除 "),u("code",null,"yes"),a(" 并改成 "),u("code",null,"no")])])]),u("li",null,[u("p",null,"保存文件并退出。还记得怎么操作吗?............ 正确答案:"),u("ul",null,[u("li",null,[a("保存是 "),u("code",null,"ctrl+o"),a(",然后 "),u("code",null,"回车"),a(" 确认")]),u("li",null,[a("退出是 "),u("code",null,"ctrl+x")])])]),u("li",null,[u("p",null,"重启 ssh 服务,让变更生效。还记得............ 算了直接公布正确答案:"),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[a("systemctl restart "),u("span",{class:"token function"},"ssh"),a("\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,"完整流程演示如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img06-ssh-no-root-full.a9943c8b.gif",alt:"禁用root用户SSH远程登录"})])]),u("li",null,[u("p",null,[a("下次通过 PuTTY 远程 SSH 登录的时候,"),u("code",null,"root"),a("用户已无法连接,用户名就要换成"),u("code",null,"vpsadmin"),a("了!方便起见,我们可以在 PuTTY 中把"),u("code",null,"vpsadmin"),a("设置成默认登录用户名。(啰嗦君:别忘了保存 Session)")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img07-putty-default-user.a515e814.png",alt:"PuTTY设置默认用户名"})])])],-1),H=u("h2",{id:"_4-7-使用-rsa-密钥登录并禁用密码登录",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-7-使用-rsa-密钥登录并禁用密码登录","aria-hidden":"true"},"#"),a(" 4.7 使用 RSA 密钥登录并禁用密码登录")],-1),Y=u("p",null,"第三步,我们来解决【密码】可能被撞破的问题。",-1),C=u("p",null,"前面我说过,黑客并不是很蠢的用穷举法破解你的密码,而是会用一些比如“密码表”的作弊手段。除非你用的是随机生成的超长密码(比如借助 1Password,或者 macOS 的 keychain 等密码管理工具),否则很容易中招。",-1),R=u("p",null,"超长随机密码虽然安全性有所提高,但是基本上无法记忆,手动输入也十分麻烦易错。为了解决这个困境,我们可以直接弃用【密码验证】方式,改用更安全的【密钥验证】。",-1),W=u("p",null,"所谓的【密钥验证】,就是生成【一对】相关联的密钥文件(公钥和私钥),然后把【公钥】上传到 VPS 备用。每次登录时,SSH 会将【公钥】和【私钥】进行匹配,若验证是正确的【密钥对】,则验证通过。(换言之,你无需记忆和输入复杂的密码,只要保护好【私钥】这个文件不外泄即可)",-1),E=u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,[a("本文以 "),u("code",null,"RSA"),a(" 密钥举例,是因为 "),u("code",null,"RSA"),a(" 密钥在各种设备、各种 "),u("code",null,"SSH"),a(" 客户端中有广泛悠久的支持历史,且目前依然能提供够用的安全性。但它绝非唯一选择。")]),u("p",null,"其他的常见密钥还有:"),u("ul",null,[u("li",null,[u("code",null,"DSA"),a(" - 已经从数学层面被证明不安全,所以永远不要用它")]),u("li",null,[u("code",null,"ECDSA"),a(" - 密钥小安全性高,但其算法被指留有 NSA 的后门,如果你的 VPS 上有值得 NSA 关注的东西就不要用它")]),u("li",null,[u("code",null,"Ed25519"),a(" - 这是一个与 "),u("code",null,"ECDSA"),a(" 十分类似的算法,故具有相似的性能优势。同时其文档全部公开,所以普遍认为无后门")])]),u("p",null,[a("所以,如果你的设备和软件都支持的话,我建议优先选择 "),u("code",null,"Ed25519"),a(" 密钥。")])],-1),z=u("p",null,"那我们现在就来配置【密钥验证】吧!",-1),D=u("li",null,[u("p",null,[a("运行"),u("code",null,"PuTTYgen"),a(" (PuTTY 密钥生成器)。位置是 "),u("code",null,"开始菜单"),a(" --\x3e "),u("code",null,"所有程序"),a(" --\x3e "),u("code",null,"PuTTY (64-bit)"),a(" --\x3e "),u("code",null,"PuTTYgen")]),u("ol",null,[u("li",null,[u("p",null,[a("点击"),u("code",null,"Generate"),a("开始生成(在界面空白处乱晃鼠标增加随机数)")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img08-puttygen-save.32267800.png",alt:"生成密钥"})])])]),u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,[a("本图中是以 "),u("code",null,"2048"),a(" 位的 "),u("code",null,"RSA"),a(" 密钥为例的。但实际上,如果要获得与 "),u("code",null,"EDCSA/Ed25519"),a(" 的 "),u("code",null,"256"),a(" 位密钥相同的安全性,你需要使用 "),u("code",null,"3072"),a(" 位的 "),u("code",null,"RSA"),a(" 密钥。(即右下角的数字改成 "),u("code",null,"3072"),a(")")])]),u("ol",{start:"2"},[u("li",null,[u("p",null,"你可以给私钥设置密码,增加一层安全性")]),u("li",null,[u("p",null,[a("点击 "),u("code",null,"Save public key"),a(" 保存公钥,文件名为 "),u("code",null,"id_rsa.pub")])]),u("li",null,[u("p",null,[a("点击 "),u("code",null,"Save private key"),a(" 保存私钥,文件名为 "),u("code",null,"id_rsa"),a(" (PuTTY 私钥自带"),u("code",null,".ppk"),a("后缀)")])]),u("li",null,[u("p",null,[a("最重要的,将上方红框内的内容,向下滚动全部复制出来并保存,文件名为 "),u("code",null,"authorized_keys"),a("。(用 vscode 保存,默认会变成带"),u("code",null,"txt"),a("后缀的文本文件,这没关系,之后上传 VPS 时我们会把后缀名去掉)")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img09-puttygen-save-keys.a599bbdf.png",alt:"保存密钥"})])])])],-1),O=u("p",null,[a("将公钥上传至 VPS 的"),u("code",null,"vpsadmin"),a("用户下")],-1),I=u("li",null,[u("p",null,[a("这一步就需要用到之前准备的"),u("code",null,"WinSCP"),a("了。")])],-1),N=a("去"),F={href:"https://winscp.net/eng/index.php",target:"_blank",rel:"noopener noreferrer"},G=a("官网"),U=a("下载并安装,会提示你导入 PuTTY 的设置,当然一键导入啦!"),j=u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img10-winscp-import-session.342a201a.png",alt:"一键导入Session"})],-1),q=u("li",null,[u("p",null,"如果没有提示导入或者你已经提前安装好了,那按照下图进行配置即可"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img11-winscp-ui.70f60717.png",alt:"WinSCP登录设置"})])],-1),B=u("li",null,[u("p",null,"WinSCP 左边的目录就是本地电脑上的文件夹和文件,请定位到密钥所在的文件夹")],-1),J=u("li",null,[u("p",null,[a("WinSCP 右边的目录则是 VPS 服务器上的文件夹和文件,默认就在 "),u("code",null,"/home/vpsadmin/"),a(" 文件夹,此时在请点击右下角 "),u("code",null,"X hidden"),a(" 来显示隐藏文件")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img12-winscp-locations.f31ffa53.png",alt:"本地和远程文件夹"})])],-1),K=u("li",null,[u("p",null,[a("在右边(VPS 中)点击右键并新建文件夹,起名"),u("code",null,".ssh"),a(" (注意有一个"),u("code",null,"."),a(")")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img13-winscp-newfolder-key.66d24a49.png",alt:"在VPS中建立放置公钥的文件夹"})])],-1),M=u("li",null,[u("p",null,[a("将【公钥】"),u("code",null,"authorized_keys"),a("上传到"),u("code",null,".ssh"),a("文件夹内")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img14-winscp-upload-key.9fa9340c.png",alt:"上传authorized_keys"})])],-1),Q=u("li",null,[u("p",null,[a("在上传时,将【公钥】从 "),u("code",null,"authorized_keys.txt"),a(" 改名为 "),u("code",null,"authorized_keys"),a("(去掉"),u("code",null,".txt"),a("这个后缀名)")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img15-winscp-rename-key.79776390.png",alt:"确保没有任何后缀"})])],-1),Z=u("li",null,[u("p",null,"完整流程演示如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img16-winscp-full.9c46d03b.gif",alt:"WinSCP操作完整演示"})])],-1),$=u("li",null,[u("p",null,"在 VPS 端设置 SSH 启用 RSA 密钥验证登录、同时禁用密码验证登录"),u("ol",null,[u("li",null,[u("p",null,"小小白白 Linux 基础命令:"),u("table",null,[u("thead",null,[u("tr",null,[u("th",{style:{"text-align":"center"}},"编号"),u("th",{style:{"text-align":"center"}},"命令名称"),u("th",{style:{"text-align":"center"}},"命令说明")])]),u("tbody",null,[u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-08")]),u("td",{style:{"text-align":"center"}},[u("code",null,"sudo")]),u("td",{style:{"text-align":"center"}},[a("用"),u("code",null,"root"),a("权限运行某个命令")])]),u("tr",null,[u("td",{style:{"text-align":"center"}},[u("code",null,"cmd-09")]),u("td",{style:{"text-align":"center"}},[u("code",null,"chmod")]),u("td",{style:{"text-align":"center"}},"修改目标文件/文件夹的权限")])])])]),u("li",null,[u("p",null,"SSH 远程连接到 VPS 上(PuTTY)")]),u("li",null,[u("p",null,[a("修改 "),u("code",null,"authorized_keys"),a(" 文件权限为 "),u("code",null,"600"),a(" (仅所有者可读可写)")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"chmod"),a(),u("span",{class:"token number"},"600"),a(" ~/.ssh/authorized_keys\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,[a("修改 SSH 配置。这个我们已经用了很多次,但现在我们已经从无所不能的"),u("code",null,"root"),a("变成了普通用户"),u("code",null,"vpsadmin"),a(",此时的我们是没有权限直接编辑 SSH 配置的。这时候就需要使用"),u("code",null,"sudo"),a("命令了:")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"sudo"),a(),u("span",{class:"token function"},"nano"),a(" /etc/ssh/sshd_config\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,[a("找到("),u("code",null,"ctrl+w"),a(") "),u("code",null,"PasswordAuthentication"),a(" 改成 "),u("code",null,"no")])]),u("li",null,[u("p",null,[a("找到("),u("code",null,"ctrl+w"),a(") "),u("code",null,"PubkeyAuthentication"),a(" 改成 "),u("code",null,"yes"),a(",然后保存("),u("code",null,"ctrl+o"),a(")退出("),u("code",null,"ctrl+x"),a(")")])]),u("li",null,[u("p",null,[a("重启 SSH 服务。(啰嗦君:别忘了现在需要使用"),u("code",null,"sudo"),a("来获得权限)")]),u("div",{class:"language-bash ext-sh line-numbers-mode"},[u("pre",{class:"language-bash"},[u("code",null,[u("span",{class:"token function"},"sudo"),a(" systemctl restart "),u("span",{class:"token function"},"ssh"),a("\n")])]),u("div",{class:"line-numbers"},[u("span",{class:"line-number"},"1"),u("br")])])]),u("li",null,[u("p",null,"完整流程如下:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img17-rsa-login-full.2cf70977.gif",alt:"SSH开启密钥验证并禁用密码验证"})])])])],-1),ll=u("li",null,[u("p",null,"VPS 端已经设置好了公钥,现在要给 PuTTY 指定私钥位置供登录时使用(啰嗦君:别忘了保存 Session)"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img18-putty-privatekey-location.694b3b0d.png",alt:"PuTTY指定私钥位置"})])],-1),nl=u("li",null,[u("p",null,[a("至此,【密钥登录】已成功开启、【密码验证】已成功关闭、并且还给 PuTTY 保存了默认的登录用户名和私钥。未来使用 PuTTY 登录时,载入"),u("code",null,"VPS-SERVER"),a("配置后,点击"),u("code",null,"Open"),a("就可以一键登录了。")]),u("p",null,"如果你给私钥设置了密码保护,登录时当然还需要输入这个密码才能使用密钥,如下图:"),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img19-putty-privatekey-passphrase.d7ab41cd.png",alt:"输入私钥密码"})])],-1),el=u("li",null,[u("p",null,[a("别忘了给"),u("code",null,"WinSCP"),a("也做对应的密钥设置,否则之后想要传输文件时就无法登录了:")]),u("p",null,[u("img",{src:"/Xray-docs-next/assets/ch04-img20-winscp-privatekey-location.b1a9346e.png",alt:"WinSCP指定私钥位置"})])],-1),ul=u("div",{class:"custom-container warning"},[u("p",{class:"custom-container-title"},"注意"),u("p",null,"任何需要借助 SSH 进行登录的软件都需要密钥验证了,软件过多,无法逐一展示,请根据你的需要自行设置好哦")],-1),sl=u("h2",{id:"_4-8-你的进度",tabindex:"-1"},[u("a",{class:"header-anchor",href:"#_4-8-你的进度","aria-hidden":"true"},"#"),a(" 4.8 你的进度")],-1),tl=u("p",null,"到这里为止,你的 VPS 已经完成了【端口】、【用户名】、【密码】这三要素的基本安全保障,虽然远称不上固若金汤,但一般的恶意脚本应该已经无法对你造成伤害了!",-1),al=u("p",null,"现在我们终于有了一个安全的系统基础,下一章,我们就可以开始逐步安装配置 Xray 需要的基础设施了!(什么基础设施呢?一个网页,一张证书)",-1),cl=u("blockquote",null,[u("p",null,"⬛⬛⬛⬛⬜⬜⬜⬜ 50%")],-1);c.render=function(a,c){const ol=l("OutboundLink");return n(),e(t,null,[o,i,d,r,p,g,h,m,b,x,S,y,P,f,v,k,T,_,L,A,w,V,X,H,Y,C,R,W,E,z,u("ol",null,[D,u("li",null,[O,u("ol",null,[I,u("li",null,[u("p",null,[N,u("a",F,[G,s(ol)]),U]),j]),q,B,J,K,M,Q,Z])]),$,ll,nl,el]),ul,sl,tl,al,cl],64)};export default c; diff --git a/assets/ch05-webpage.html.d85ce3b4.js b/assets/ch05-webpage.html.86aeaf74.js similarity index 99% rename from assets/ch05-webpage.html.d85ce3b4.js rename to assets/ch05-webpage.html.86aeaf74.js index bbe2a29a8..3c132edec 100644 --- a/assets/ch05-webpage.html.d85ce3b4.js +++ b/assets/ch05-webpage.html.86aeaf74.js @@ -1 +1 @@ -import{o as n,c as s,F as a,a as t,e as l}from"./app.755d843f.js";const e={},c=t("h1",{id:"【第-5-章】网站建设篇",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#【第-5-章】网站建设篇","aria-hidden":"true"},"#"),l(" 【第 5 章】网站建设篇")],-1),o=t("h2",{id:"_5-1-为什么要做一个网站",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_5-1-为什么要做一个网站","aria-hidden":"true"},"#"),l(" 5.1 为什么要做一个网站?")],-1),u=t("p",null,"新人也许会迷惑,为什么科学上网还要建一个网站?我不会编程啊,是不是特别麻烦?",-1),p=t("p",null,"先回答第一个问题,建网站的原因有:",-1),i=t("ol",null,[t("li",null,"申请合法的 TLS 证书(非常重要)"),t("li",null,"提供合理的回落,防止主动探测攻击,提高安全性"),t("li",null,"建设一个伪装站(如博客、私人网盘、多媒体网站、游戏网站等),直接访问时有合理的前台,使流量使用看上去更合理。")],-1),r=t("p",null,"再回答第二个问题:",-1),k=t("ol",null,[t("li",null,"本文作为演示,仅仅使用了一个最简单的【单文件 html 页面 + Nginx】来搭建,以此完成上面的目标,所以【非常简单】"),t("li",null,"这个网站完全可以不仅仅是伪装,而是真的做大做强,这个复杂性就完全取决于你了"),t("li",null,"对于“伪装”和“网站运营”这个目标,需要的就是各不相同、秀出真我,需要的同学可以自行搜索学习。这个内容已经完全偏离了科学上网,本文就不深入解析了。")],-1),g=t("h2",{id:"_5-2-登录-vps、安装运行-nginx",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_5-2-登录-vps、安装运行-nginx","aria-hidden":"true"},"#"),l(" 5.2 登录 VPS、安装运行 Nginx")],-1),d=t("ol",null,[t("li",null,[t("p",null,"这里用到的,都是之前已经详解过的命令,所以就不重复讲解了。看不懂的同学可以看看前面的章节哦。"),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"sudo"),l(),t("span",{class:"token function"},"apt"),l(" update "),t("span",{class:"token operator"},"&&"),l(),t("span",{class:"token function"},"sudo"),l(),t("span",{class:"token function"},"apt"),l(),t("span",{class:"token function"},"install"),l(" nginx\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])]),t("li",null,[t("p",null,[l("完成后,Nginx 已经自动运行。此时打开 Windows 上的浏览器并输入 "),t("code",null,"http://100.200.300.400:80"),l(",若看到下图的界面就说明 Nginx 已经正常在运行了。")]),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch05-img01-nginx-default-running.24698092.png",alt:"Nginx默认界面"})])])],-1),b=t("h2",{id:"_5-3-创建一个最简单的网页",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_5-3-创建一个最简单的网页","aria-hidden":"true"},"#"),l(" 5.3 创建一个最简单的网页")],-1),m=t("ol",null,[t("li",null,[t("p",null,"小小白白 Linux 基础命令:"),t("table",null,[t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"center"}},"命令名称"),t("th",{style:{"text-align":"center"}},"命令说明")])]),t("tbody",null,[t("tr",null,[t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-10")]),t("td",{style:{"text-align":"center"}},[t("code",null,"mkdir")]),t("td",{style:{"text-align":"center"}},"新建文件夹")]),t("tr",null,[t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-11")]),t("td",{style:{"text-align":"center"}},[t("code",null,"systemctl reload")]),t("td",{style:{"text-align":"center"}},"重新加载某个服务")])])])]),t("li",null,[t("p",null,"小小白白 Linux 基础配置文件:"),t("table",null,[t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"center"}},"配置文件位置"),t("th",{style:{"text-align":"center"}},"文件说明")])]),t("tbody",null,[t("tr",null,[t("td",{style:{"text-align":"center"}},[t("code",null,"conf-02")]),t("td",{style:{"text-align":"center"}},[t("code",null,"/etc/nginx/nginx.conf")]),t("td",{style:{"text-align":"center"}},"Nginx 程序设置")])])])]),t("li",null,[t("p",null,[l("创建一个网站专用的文件夹"),t("code",null,"/home/vpsadmin/www/webpage/"),l("并建立网页文件"),t("code",null,"index.html")]),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"mkdir"),l(" -p ~/www/webpage/ "),t("span",{class:"token operator"},"&&"),l(),t("span",{class:"token function"},"nano"),l(" ~/www/webpage/index.html\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])])],-1),h=t("div",{class:"custom-container warning"},[t("p",{class:"custom-container-title"},"注意"),t("p",null,[l("如果你用的不是 "),t("code",null,"vpsadmin"),l(" 这个用户名,请务必理解这条命令中 "),t("code",null,"“~”"),l(" 符号的意义(这关系到【第 5 步】你要写的内容):")]),t("ul",null,[t("li",null,[l("如果是 【非 "),t("code",null,"root"),l(" 用户】,"),t("code",null,"“~”"),l(" 就等价于 "),t("code",null,"/home/用户名")]),t("li",null,[l("如果是 【 "),t("code",null,"root"),l(" 用户】,"),t("code",null,"“~”"),l(" 就等价于 "),t("code",null,"/root")])])],-1),x=t("ol",{start:"4"},[t("li",null,[t("p",null,[l("把下面的内容完整的复制进去,然后保存("),t("code",null,"ctrl+o"),l(")退出("),t("code",null,"ctrl+x"),l(")")]),t("div",{class:"language-html ext-html line-numbers-mode"},[t("pre",{class:"language-html"},[t("code",null,[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("html")]),l(),t("span",{class:"token attr-name"},"lang"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),l("\n "),t("span",{class:"token comment"},"\x3c!-- Text between angle brackets is an HTML tag and is not displayed.\n Most tags, such as the HTML and /HTML tags that surround the contents of\n a page, come in pairs; some tags, like HR, for a horizontal rule, stand\n alone. Comments, such as the text you're reading, are not displayed when\n the Web page is shown. The information between the HEAD and /HEAD tags is\n not displayed. The information between the BODY and /BODY tags is displayed.--\x3e"),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("head")]),t("span",{class:"token punctuation"},">")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("title")]),t("span",{class:"token punctuation"},">")]),l("Enter a title, displayed at the top of the window."),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token comment"},"\x3c!-- The information between the BODY and /BODY tags is displayed.--\x3e"),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("body")]),t("span",{class:"token punctuation"},">")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("h1")]),t("span",{class:"token punctuation"},">")]),l("Enter the main heading, usually the same as the title."),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),l("Be "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("b")]),t("span",{class:"token punctuation"},">")]),l("bold"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l(" in stating your key points. Put them in a list:"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("ul")]),t("span",{class:"token punctuation"},">")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("li")]),t("span",{class:"token punctuation"},">")]),l("The first item in your list"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("li")]),t("span",{class:"token punctuation"},">")]),l("The second item; "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("i")]),t("span",{class:"token punctuation"},">")]),l("italicize"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l(" key words"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),l("Improve your image by including an image."),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("img")]),l(),t("span",{class:"token attr-name"},"src"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),l("https://i.imgur.com/SEBww.jpg"),t("span",{class:"token punctuation"},'"')]),l(),t("span",{class:"token attr-name"},"alt"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),l("A Great HTML Resource"),t("span",{class:"token punctuation"},'"')]),l(),t("span",{class:"token punctuation"},"/>")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),l("\n Add a link to your favorite\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("a")]),l(),t("span",{class:"token attr-name"},"href"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),l("https://www.dummies.com/"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),l("Web site"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l(". Break up your page\n with a horizontal rule or two.\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("hr")]),l(),t("span",{class:"token punctuation"},"/>")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),l("\n Finally, link to "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("a")]),l(),t("span",{class:"token attr-name"},"href"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),l("page2.html"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),l("another page"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l(" in your own Web\n site.\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token comment"},"\x3c!-- And add a copyright notice.--\x3e"),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),t("span",{class:"token entity",title:"©"},"©"),l(" Wiley Publishing, 2011"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br"),t("span",{class:"line-number"},"21"),t("br"),t("span",{class:"line-number"},"22"),t("br"),t("span",{class:"line-number"},"23"),t("br"),t("span",{class:"line-number"},"24"),t("br"),t("span",{class:"line-number"},"25"),t("br"),t("span",{class:"line-number"},"26"),t("br"),t("span",{class:"line-number"},"27"),t("br"),t("span",{class:"line-number"},"28"),t("br"),t("span",{class:"line-number"},"29"),t("br"),t("span",{class:"line-number"},"30"),t("br"),t("span",{class:"line-number"},"31"),t("br"),t("span",{class:"line-number"},"32"),t("br"),t("span",{class:"line-number"},"33"),t("br"),t("span",{class:"line-number"},"34"),t("br"),t("span",{class:"line-number"},"35"),t("br"),t("span",{class:"line-number"},"36"),t("br")])])]),t("li",null,[t("p",null,[l("修改 "),t("code",null,"nginx.conf"),l(" 并重启 "),t("code",null,"Nginx"),l(" 服务,将"),t("code",null,"80"),l("端口的 http 访问定位到刚才建立的 "),t("code",null,"html"),l(" 页面上")]),t("ol",null,[t("li",null,[t("p",null,[l("修改 "),t("code",null,"nginx.conf"),l(" 。")]),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"sudo"),l(),t("span",{class:"token function"},"nano"),l(" /etc/nginx/nginx.conf\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])]),t("li",null,[t("p",null,[l("将下面一段,添加在 "),t("code",null,"http{}"),l(" 内,然后保存("),t("code",null,"ctrl+o"),l(")退出("),t("code",null,"ctrl+x"),l(")。(记得将域名替换为之前准备好的、包含二级域名的真实域名)")]),t("div",{class:"language-text ext-text line-numbers-mode"},[t("pre",{class:"language-text"},[t("code",null," server {\n listen 80;\n server_name 二级域名.你的域名.com;\n root /home/vpsadmin/www/webpage;\n index index.html;\n }\n")]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br")])]),t("div",{class:"custom-container warning"},[t("p",{class:"custom-container-title"},"特别注意!"),t("p",null,[l("如我在【第 3 步】中的提示所说,请务必确保 "),t("code",null,"/home/vpsadmin/www/webpage"),l(" 改成你的实际文件路径。")])])]),t("li",null,[t("p",null,[l("让 "),t("code",null,"nginx"),l(" 重新载入配置使其生效")]),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"sudo"),l(" systemctl reload nginx\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])]),t("li",null,[t("p",null,"完整的设置流程如下:"),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch05-img02-nginx-conf-full.d3e1011d.gif",alt:"网页设置演示"})])]),t("li",null,[t("p",null,[l("此时如果你访问 "),t("code",null,"http://二级域名.你的域名.com"),l(",你看到这样的页面则说明成功:")]),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch05-img03-nginx-http-running.46c296a3.png",alt:"http网页成功"})])])])])],-1),y=t("h2",{id:"_5-4-常见错误的说明",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_5-4-常见错误的说明","aria-hidden":"true"},"#"),l(" 5.4 常见错误的说明")],-1),w=t("p",null,"首先,如果你一路按照文章的说明来操作,并且足够细心,那肯定不会出错。所以,我并不打算修改本文的写法。",-1),f=t("p",null,[l("那为什么依然有很多同学卡在了这一步,网页怎么也打不开呢?基本上就是两个字:"),t("strong",null,"粗心"),l("。因为这里配置可能出现的问题只有两种,原因也只有两个。")],-1),v=t("p",null,"一、两种问题:",-1),T=t("ul",null,[t("li",null,[t("code",null,"nginx.conf"),l(" 里面的 "),t("code",null,"/home/vpsadmin/www/webpage"),l(" 这一条,与你的实际文件路径不符,"),t("code",null,"nginx"),l(" 找不到文件")]),t("li",null,[l("路径正确,但 "),t("code",null,"nginx"),l(" 无权读取")])],-1),_=t("p",null,"二、两个原因:",-1),L=t("ul",null,[t("li",null,[l("使用了【非 "),t("code",null,"root"),l(" 用户】,但仍然直接拷贝文中的命令不加修改。(这基本就等于抄答案时把同学的名字一起抄过去了)")]),t("li",null,[l("坚持使用【 "),t("code",null,"root"),l(" 用户】")])],-1),B=t("p",null,"碰到错误的同学,就回过头仔细看一下【5.3】中【第 3 步】和【第 5-2 步】的说明吧。",-1),H=t("div",{class:"custom-container warning"},[t("p",{class:"custom-container-title"},"注意"),t("p",null,[l("本文前期已经用了大量篇幅说明了使用【非 "),t("code",null,"root"),l(" 用户】对安全的重要性,全文也是基于此而写。所以,因使用【 "),t("code",null,"root"),l(" 用户】而导致的问题并不在本文的设计范围里。")]),t("p",null,[l("但我相信,坚持使用【 "),t("code",null,"root"),l(" 用户】的同学应该是有主见、动手能力强、或者有一定 Linux 基础的同学。问题的症结我已经全部说明了,我相信你一定可以自行解决。")])],-1),N=t("h2",{id:"_5-5-你的进度",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_5-5-你的进度","aria-hidden":"true"},"#"),l(" 5.5 你的进度")],-1),q=t("p",null,"至此,Xray 的第一个基础设施【网页】已经就位,我们马上就进入第二个基础设施【证书】吧!",-1),D=t("blockquote",null,[t("p",null,"⬛⬛⬛⬛⬛⬜⬜⬜ 62.5%")],-1);e.render=function(t,l){return n(),s(a,null,[c,o,u,p,i,r,k,g,d,b,m,h,x,y,w,f,v,T,_,L,B,H,N,q,D],64)};export default e; +import{o as n,c as s,F as a,a as t,e as l}from"./app.48111a85.js";const e={},c=t("h1",{id:"【第-5-章】网站建设篇",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#【第-5-章】网站建设篇","aria-hidden":"true"},"#"),l(" 【第 5 章】网站建设篇")],-1),o=t("h2",{id:"_5-1-为什么要做一个网站",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_5-1-为什么要做一个网站","aria-hidden":"true"},"#"),l(" 5.1 为什么要做一个网站?")],-1),u=t("p",null,"新人也许会迷惑,为什么科学上网还要建一个网站?我不会编程啊,是不是特别麻烦?",-1),p=t("p",null,"先回答第一个问题,建网站的原因有:",-1),i=t("ol",null,[t("li",null,"申请合法的 TLS 证书(非常重要)"),t("li",null,"提供合理的回落,防止主动探测攻击,提高安全性"),t("li",null,"建设一个伪装站(如博客、私人网盘、多媒体网站、游戏网站等),直接访问时有合理的前台,使流量使用看上去更合理。")],-1),r=t("p",null,"再回答第二个问题:",-1),k=t("ol",null,[t("li",null,"本文作为演示,仅仅使用了一个最简单的【单文件 html 页面 + Nginx】来搭建,以此完成上面的目标,所以【非常简单】"),t("li",null,"这个网站完全可以不仅仅是伪装,而是真的做大做强,这个复杂性就完全取决于你了"),t("li",null,"对于“伪装”和“网站运营”这个目标,需要的就是各不相同、秀出真我,需要的同学可以自行搜索学习。这个内容已经完全偏离了科学上网,本文就不深入解析了。")],-1),g=t("h2",{id:"_5-2-登录-vps、安装运行-nginx",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_5-2-登录-vps、安装运行-nginx","aria-hidden":"true"},"#"),l(" 5.2 登录 VPS、安装运行 Nginx")],-1),d=t("ol",null,[t("li",null,[t("p",null,"这里用到的,都是之前已经详解过的命令,所以就不重复讲解了。看不懂的同学可以看看前面的章节哦。"),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"sudo"),l(),t("span",{class:"token function"},"apt"),l(" update "),t("span",{class:"token operator"},"&&"),l(),t("span",{class:"token function"},"sudo"),l(),t("span",{class:"token function"},"apt"),l(),t("span",{class:"token function"},"install"),l(" nginx\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])]),t("li",null,[t("p",null,[l("完成后,Nginx 已经自动运行。此时打开 Windows 上的浏览器并输入 "),t("code",null,"http://100.200.300.400:80"),l(",若看到下图的界面就说明 Nginx 已经正常在运行了。")]),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch05-img01-nginx-default-running.24698092.png",alt:"Nginx默认界面"})])])],-1),b=t("h2",{id:"_5-3-创建一个最简单的网页",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_5-3-创建一个最简单的网页","aria-hidden":"true"},"#"),l(" 5.3 创建一个最简单的网页")],-1),m=t("ol",null,[t("li",null,[t("p",null,"小小白白 Linux 基础命令:"),t("table",null,[t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"center"}},"命令名称"),t("th",{style:{"text-align":"center"}},"命令说明")])]),t("tbody",null,[t("tr",null,[t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-10")]),t("td",{style:{"text-align":"center"}},[t("code",null,"mkdir")]),t("td",{style:{"text-align":"center"}},"新建文件夹")]),t("tr",null,[t("td",{style:{"text-align":"center"}},[t("code",null,"cmd-11")]),t("td",{style:{"text-align":"center"}},[t("code",null,"systemctl reload")]),t("td",{style:{"text-align":"center"}},"重新加载某个服务")])])])]),t("li",null,[t("p",null,"小小白白 Linux 基础配置文件:"),t("table",null,[t("thead",null,[t("tr",null,[t("th",{style:{"text-align":"center"}},"编号"),t("th",{style:{"text-align":"center"}},"配置文件位置"),t("th",{style:{"text-align":"center"}},"文件说明")])]),t("tbody",null,[t("tr",null,[t("td",{style:{"text-align":"center"}},[t("code",null,"conf-02")]),t("td",{style:{"text-align":"center"}},[t("code",null,"/etc/nginx/nginx.conf")]),t("td",{style:{"text-align":"center"}},"Nginx 程序设置")])])])]),t("li",null,[t("p",null,[l("创建一个网站专用的文件夹"),t("code",null,"/home/vpsadmin/www/webpage/"),l("并建立网页文件"),t("code",null,"index.html")]),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"mkdir"),l(" -p ~/www/webpage/ "),t("span",{class:"token operator"},"&&"),l(),t("span",{class:"token function"},"nano"),l(" ~/www/webpage/index.html\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])])],-1),h=t("div",{class:"custom-container warning"},[t("p",{class:"custom-container-title"},"注意"),t("p",null,[l("如果你用的不是 "),t("code",null,"vpsadmin"),l(" 这个用户名,请务必理解这条命令中 "),t("code",null,"“~”"),l(" 符号的意义(这关系到【第 5 步】你要写的内容):")]),t("ul",null,[t("li",null,[l("如果是 【非 "),t("code",null,"root"),l(" 用户】,"),t("code",null,"“~”"),l(" 就等价于 "),t("code",null,"/home/用户名")]),t("li",null,[l("如果是 【 "),t("code",null,"root"),l(" 用户】,"),t("code",null,"“~”"),l(" 就等价于 "),t("code",null,"/root")])])],-1),x=t("ol",{start:"4"},[t("li",null,[t("p",null,[l("把下面的内容完整的复制进去,然后保存("),t("code",null,"ctrl+o"),l(")退出("),t("code",null,"ctrl+x"),l(")")]),t("div",{class:"language-html ext-html line-numbers-mode"},[t("pre",{class:"language-html"},[t("code",null,[t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("html")]),l(),t("span",{class:"token attr-name"},"lang"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),l("\n "),t("span",{class:"token comment"},"\x3c!-- Text between angle brackets is an HTML tag and is not displayed.\n Most tags, such as the HTML and /HTML tags that surround the contents of\n a page, come in pairs; some tags, like HR, for a horizontal rule, stand\n alone. Comments, such as the text you're reading, are not displayed when\n the Web page is shown. The information between the HEAD and /HEAD tags is\n not displayed. The information between the BODY and /BODY tags is displayed.--\x3e"),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("head")]),t("span",{class:"token punctuation"},">")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("title")]),t("span",{class:"token punctuation"},">")]),l("Enter a title, displayed at the top of the window."),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token comment"},"\x3c!-- The information between the BODY and /BODY tags is displayed.--\x3e"),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("body")]),t("span",{class:"token punctuation"},">")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("h1")]),t("span",{class:"token punctuation"},">")]),l("Enter the main heading, usually the same as the title."),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),l("Be "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("b")]),t("span",{class:"token punctuation"},">")]),l("bold"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l(" in stating your key points. Put them in a list:"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("ul")]),t("span",{class:"token punctuation"},">")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("li")]),t("span",{class:"token punctuation"},">")]),l("The first item in your list"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("li")]),t("span",{class:"token punctuation"},">")]),l("The second item; "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("i")]),t("span",{class:"token punctuation"},">")]),l("italicize"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l(" key words"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),l("Improve your image by including an image."),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("img")]),l(),t("span",{class:"token attr-name"},"src"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),l("https://i.imgur.com/SEBww.jpg"),t("span",{class:"token punctuation"},'"')]),l(),t("span",{class:"token attr-name"},"alt"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),l("A Great HTML Resource"),t("span",{class:"token punctuation"},'"')]),l(),t("span",{class:"token punctuation"},"/>")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),l("\n Add a link to your favorite\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("a")]),l(),t("span",{class:"token attr-name"},"href"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),l("https://www.dummies.com/"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),l("Web site"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l(". Break up your page\n with a horizontal rule or two.\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("hr")]),l(),t("span",{class:"token punctuation"},"/>")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),l("\n Finally, link to "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("a")]),l(),t("span",{class:"token attr-name"},"href"),t("span",{class:"token attr-value"},[t("span",{class:"token punctuation attr-equals"},"="),t("span",{class:"token punctuation"},'"'),l("page2.html"),t("span",{class:"token punctuation"},'"')]),t("span",{class:"token punctuation"},">")]),l("another page"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l(" in your own Web\n site.\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token comment"},"\x3c!-- And add a copyright notice.--\x3e"),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"<"),l("p")]),t("span",{class:"token punctuation"},">")]),t("span",{class:"token entity",title:"©"},"©"),l(" Wiley Publishing, 2011"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n "),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n"),t("span",{class:"token tag"},[t("span",{class:"token tag"},[t("span",{class:"token punctuation"},"")]),l("\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br"),t("span",{class:"line-number"},"21"),t("br"),t("span",{class:"line-number"},"22"),t("br"),t("span",{class:"line-number"},"23"),t("br"),t("span",{class:"line-number"},"24"),t("br"),t("span",{class:"line-number"},"25"),t("br"),t("span",{class:"line-number"},"26"),t("br"),t("span",{class:"line-number"},"27"),t("br"),t("span",{class:"line-number"},"28"),t("br"),t("span",{class:"line-number"},"29"),t("br"),t("span",{class:"line-number"},"30"),t("br"),t("span",{class:"line-number"},"31"),t("br"),t("span",{class:"line-number"},"32"),t("br"),t("span",{class:"line-number"},"33"),t("br"),t("span",{class:"line-number"},"34"),t("br"),t("span",{class:"line-number"},"35"),t("br"),t("span",{class:"line-number"},"36"),t("br")])])]),t("li",null,[t("p",null,[l("修改 "),t("code",null,"nginx.conf"),l(" 并重启 "),t("code",null,"Nginx"),l(" 服务,将"),t("code",null,"80"),l("端口的 http 访问定位到刚才建立的 "),t("code",null,"html"),l(" 页面上")]),t("ol",null,[t("li",null,[t("p",null,[l("修改 "),t("code",null,"nginx.conf"),l(" 。")]),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"sudo"),l(),t("span",{class:"token function"},"nano"),l(" /etc/nginx/nginx.conf\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])]),t("li",null,[t("p",null,[l("将下面一段,添加在 "),t("code",null,"http{}"),l(" 内,然后保存("),t("code",null,"ctrl+o"),l(")退出("),t("code",null,"ctrl+x"),l(")。(记得将域名替换为之前准备好的、包含二级域名的真实域名)")]),t("div",{class:"language-text ext-text line-numbers-mode"},[t("pre",{class:"language-text"},[t("code",null," server {\n listen 80;\n server_name 二级域名.你的域名.com;\n root /home/vpsadmin/www/webpage;\n index index.html;\n }\n")]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br")])]),t("div",{class:"custom-container warning"},[t("p",{class:"custom-container-title"},"特别注意!"),t("p",null,[l("如我在【第 3 步】中的提示所说,请务必确保 "),t("code",null,"/home/vpsadmin/www/webpage"),l(" 改成你的实际文件路径。")])])]),t("li",null,[t("p",null,[l("让 "),t("code",null,"nginx"),l(" 重新载入配置使其生效")]),t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[t("span",{class:"token function"},"sudo"),l(" systemctl reload nginx\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br")])])]),t("li",null,[t("p",null,"完整的设置流程如下:"),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch05-img02-nginx-conf-full.d3e1011d.gif",alt:"网页设置演示"})])]),t("li",null,[t("p",null,[l("此时如果你访问 "),t("code",null,"http://二级域名.你的域名.com"),l(",你看到这样的页面则说明成功:")]),t("p",null,[t("img",{src:"/Xray-docs-next/assets/ch05-img03-nginx-http-running.46c296a3.png",alt:"http网页成功"})])])])])],-1),y=t("h2",{id:"_5-4-常见错误的说明",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_5-4-常见错误的说明","aria-hidden":"true"},"#"),l(" 5.4 常见错误的说明")],-1),w=t("p",null,"首先,如果你一路按照文章的说明来操作,并且足够细心,那肯定不会出错。所以,我并不打算修改本文的写法。",-1),f=t("p",null,[l("那为什么依然有很多同学卡在了这一步,网页怎么也打不开呢?基本上就是两个字:"),t("strong",null,"粗心"),l("。因为这里配置可能出现的问题只有两种,原因也只有两个。")],-1),v=t("p",null,"一、两种问题:",-1),T=t("ul",null,[t("li",null,[t("code",null,"nginx.conf"),l(" 里面的 "),t("code",null,"/home/vpsadmin/www/webpage"),l(" 这一条,与你的实际文件路径不符,"),t("code",null,"nginx"),l(" 找不到文件")]),t("li",null,[l("路径正确,但 "),t("code",null,"nginx"),l(" 无权读取")])],-1),_=t("p",null,"二、两个原因:",-1),L=t("ul",null,[t("li",null,[l("使用了【非 "),t("code",null,"root"),l(" 用户】,但仍然直接拷贝文中的命令不加修改。(这基本就等于抄答案时把同学的名字一起抄过去了)")]),t("li",null,[l("坚持使用【 "),t("code",null,"root"),l(" 用户】")])],-1),B=t("p",null,"碰到错误的同学,就回过头仔细看一下【5.3】中【第 3 步】和【第 5-2 步】的说明吧。",-1),H=t("div",{class:"custom-container warning"},[t("p",{class:"custom-container-title"},"注意"),t("p",null,[l("本文前期已经用了大量篇幅说明了使用【非 "),t("code",null,"root"),l(" 用户】对安全的重要性,全文也是基于此而写。所以,因使用【 "),t("code",null,"root"),l(" 用户】而导致的问题并不在本文的设计范围里。")]),t("p",null,[l("但我相信,坚持使用【 "),t("code",null,"root"),l(" 用户】的同学应该是有主见、动手能力强、或者有一定 Linux 基础的同学。问题的症结我已经全部说明了,我相信你一定可以自行解决。")])],-1),N=t("h2",{id:"_5-5-你的进度",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#_5-5-你的进度","aria-hidden":"true"},"#"),l(" 5.5 你的进度")],-1),q=t("p",null,"至此,Xray 的第一个基础设施【网页】已经就位,我们马上就进入第二个基础设施【证书】吧!",-1),D=t("blockquote",null,[t("p",null,"⬛⬛⬛⬛⬛⬜⬜⬜ 62.5%")],-1);e.render=function(t,l){return n(),s(a,null,[c,o,u,p,i,r,k,g,d,b,m,h,x,y,w,f,v,T,_,L,B,H,N,q,D],64)};export default e; diff --git a/assets/ch05-webpage.html.ecc4595b.js b/assets/ch05-webpage.html.cd12795a.js similarity index 99% rename from assets/ch05-webpage.html.ecc4595b.js rename to assets/ch05-webpage.html.cd12795a.js index 39c03d3fb..49050e4a7 100644 --- a/assets/ch05-webpage.html.ecc4595b.js +++ b/assets/ch05-webpage.html.cd12795a.js @@ -1 +1 @@ -import{o as n,c as s,F as a,a as e,e as t}from"./app.755d843f.js";const l={},o=e("h1",{id:"chapter-5-website-building",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#chapter-5-website-building","aria-hidden":"true"},"#"),t(" Chapter 5: Website Building")],-1),i=e("h2",{id:"_5-1-why-should-you-create-a-website",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-1-why-should-you-create-a-website","aria-hidden":"true"},"#"),t(" 5.1 Why should you create a website?")],-1),c=e("p",null,"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?",-1),u=e("p",null,"First, let's answer the first question. The reasons for building a website are:",-1),p=e("ol",null,[e("li",null,"Apply for a legitimate TLS certificate (very important)"),e("li",null,"Provide reasonable fallback to prevent active probing attacks and improve security"),e("li",null,"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.")],-1),r=e("p",null,"Now let's answer the second question:",-1),d=e("ol",null,[e("li",null,[t('As a demonstration, this article uses only the simplest "single-file HTML page + Nginx" setup to achieve the above objectives, so it is '),e("strong",null,"very easy"),t(".")]),e("li",null,"This website can not only be used for camouflage but also for real development and growth. The complexity depends entirely on you."),e("li",null,'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.')],-1),g=e("h2",{id:"_5-2-log-in-to-vps-install-and-run-nginx",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-2-log-in-to-vps-install-and-run-nginx","aria-hidden":"true"},"#"),t(" 5.2 Log in to VPS, install and run Nginx")],-1),h=e("ol",null,[e("li",null,[e("p",null,"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."),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"sudo"),t(),e("span",{class:"token function"},"apt"),t(" update "),e("span",{class:"token operator"},"&&"),t(),e("span",{class:"token function"},"sudo"),t(),e("span",{class:"token function"},"apt"),t(),e("span",{class:"token function"},"install"),t(" nginx\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,[t("After completion, Nginx will automatically run. Open the browser on Windows and enter "),e("code",null,"http://100.200.300.400:80"),t(". If you see the interface shown below, it means Nginx is running normally.")]),e("p",null,[e("img",{src:"/Xray-docs-next/assets/ch05-img01-nginx-default-running.24698092.png",alt:"Nginx default interface"})])])],-1),m=e("h2",{id:"_5-3-create-the-simplest-web-page",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-3-create-the-simplest-web-page","aria-hidden":"true"},"#"),t(" 5.3 Create the simplest web page")],-1),k=e("ol",null,[e("li",null,[e("p",null,"Basic Linux commands for beginners:"),e("table",null,[e("thead",null,[e("tr",null,[e("th",{style:{"text-align":"center"}},"No."),e("th",{style:{"text-align":"center"}},"Command Name"),e("th",{style:{"text-align":"center"}},"Command Description")])]),e("tbody",null,[e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"cmd-10")]),e("td",{style:{"text-align":"center"}},[e("code",null,"mkdir")]),e("td",{style:{"text-align":"center"}},"Create a new folder")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"cmd-11")]),e("td",{style:{"text-align":"center"}},[e("code",null,"systemctl reload")]),e("td",{style:{"text-align":"center"}},"Reload a specific service")])])])]),e("li",null,[e("p",null,"Basic Linux configuration files for beginners:"),e("table",null,[e("thead",null,[e("tr",null,[e("th",{style:{"text-align":"center"}},"No."),e("th",{style:{"text-align":"center"}},"Configuration File Location"),e("th",{style:{"text-align":"center"}},"File Description")])]),e("tbody",null,[e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"conf-02")]),e("td",{style:{"text-align":"center"}},[e("code",null,"/etc/nginx/nginx.conf")]),e("td",{style:{"text-align":"center"}},"Nginx program settings")])])])]),e("li",null,[e("p",null,[t("Create a dedicated folder "),e("code",null,"/home/vpsadmin/www/webpage/"),t(" for the website and create the web page file "),e("code",null,"index.html")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"mkdir"),t(" -p ~/www/webpage/ "),e("span",{class:"token operator"},"&&"),t(),e("span",{class:"token function"},"nano"),t(" ~/www/webpage/index.html\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])])],-1),b=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"Warning"),e("p",null,[t("If you are not using the username "),e("code",null,"vpsadmin"),t(', please be sure to understand the meaning of the "~" symbol in this command (this is related to Step 5 content):')]),e("ul",null,[e("li",null,[t("If it is a "),e("strong",null,"non-root user"),t(', "~" is equivalent to '),e("code",null,"/home/username")]),e("li",null,[t("If it is a "),e("strong",null,"root user"),t(', "~" is equivalent to '),e("code",null,"/root")])])],-1),f=e("ol",{start:"4"},[e("li",null,[e("p",null,[t("Copy the entire content below, save ("),e("code",null,"ctrl+o"),t(") and exit ("),e("code",null,"ctrl+x"),t(").")]),e("div",{class:"language-html ext-html line-numbers-mode"},[e("pre",{class:"language-html"},[e("code",null,[e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("html")]),t(),e("span",{class:"token attr-name"},"lang"),e("span",{class:"token attr-value"},[e("span",{class:"token punctuation attr-equals"},"="),e("span",{class:"token punctuation"},'"'),e("span",{class:"token punctuation"},'"')]),e("span",{class:"token punctuation"},">")]),t("\n "),e("span",{class:"token comment"},"\x3c!-- Text between angle brackets is an HTML tag and is not displayed.\n Most tags, such as the HTML and /HTML tags that surround the contents of\n a page, come in pairs; some tags, like HR, for a horizontal rule, stand\n alone. Comments, such as the text you're reading, are not displayed when\n the Web page is shown. The information between the HEAD and /HEAD tags is\n not displayed. The information between the BODY and /BODY tags is displayed.--\x3e"),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("head")]),e("span",{class:"token punctuation"},">")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("title")]),e("span",{class:"token punctuation"},">")]),t("Enter a title, displayed at the top of the window."),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token comment"},"\x3c!-- The information between the BODY and /BODY tags is displayed.--\x3e"),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("body")]),e("span",{class:"token punctuation"},">")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("h1")]),e("span",{class:"token punctuation"},">")]),t("Enter the main heading, usually the same as the title."),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("Be "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("b")]),e("span",{class:"token punctuation"},">")]),t("bold"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t(" in stating your key points. Put them in a list:"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("ul")]),e("span",{class:"token punctuation"},">")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("li")]),e("span",{class:"token punctuation"},">")]),t("The first item in your list"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("li")]),e("span",{class:"token punctuation"},">")]),t("The second item; "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("i")]),e("span",{class:"token punctuation"},">")]),t("italicize"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t(" key words"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("Improve your image by including an image."),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("img")]),t(),e("span",{class:"token attr-name"},"src"),e("span",{class:"token attr-value"},[e("span",{class:"token punctuation attr-equals"},"="),e("span",{class:"token punctuation"},'"'),t("https://i.imgur.com/SEBww.jpg"),e("span",{class:"token punctuation"},'"')]),t(),e("span",{class:"token attr-name"},"alt"),e("span",{class:"token attr-value"},[e("span",{class:"token punctuation attr-equals"},"="),e("span",{class:"token punctuation"},'"'),t("A Great HTML Resource"),e("span",{class:"token punctuation"},'"')]),t(),e("span",{class:"token punctuation"},"/>")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("\n Add a link to your favorite\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("a")]),t(),e("span",{class:"token attr-name"},"href"),e("span",{class:"token attr-value"},[e("span",{class:"token punctuation attr-equals"},"="),e("span",{class:"token punctuation"},'"'),t("https://www.dummies.com/"),e("span",{class:"token punctuation"},'"')]),e("span",{class:"token punctuation"},">")]),t("Web site"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t(". Break up your page\n with a horizontal rule or two.\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("hr")]),t(),e("span",{class:"token punctuation"},"/>")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("\n Finally, link to "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("a")]),t(),e("span",{class:"token attr-name"},"href"),e("span",{class:"token attr-value"},[e("span",{class:"token punctuation attr-equals"},"="),e("span",{class:"token punctuation"},'"'),t("page2.html"),e("span",{class:"token punctuation"},'"')]),e("span",{class:"token punctuation"},">")]),t("another page"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t(" in your own Web\n site.\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token comment"},"\x3c!-- And add a copyright notice.--\x3e"),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("© Wiley Publishing, 2011"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br"),e("span",{class:"line-number"},"34"),e("br"),e("span",{class:"line-number"},"35"),e("br"),e("span",{class:"line-number"},"36"),e("br")])])]),e("li",null,[e("p",null,[t("Modify "),e("code",null,"nginx.conf"),t(" and restart the "),e("code",null,"Nginx"),t(" service, directing the http access on port 80 to the newly created "),e("code",null,"html"),t(" page.")]),e("ol",null,[e("li",null,[e("p",null,[t("Modify "),e("code",null,"nginx.conf"),t(".")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"sudo"),t(),e("span",{class:"token function"},"nano"),t(" /etc/nginx/nginx.conf\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,[t("Add the following content inside"),e("code",null,"http{}"),t(", then save ("),e("code",null,"ctrl+o"),t(") and exit ("),e("code",null,"ctrl+x"),t("). (Remember to replace the domain name with the real domain name you prepared earlier, including the subdomain)")]),e("div",{class:"language-text ext-text line-numbers-mode"},[e("pre",{class:"language-text"},[e("code",null," server {\n listen 80;\n server_name subdomain.your_domain.com;\n root /home/vpsadmin/www/webpage;\n index index.html;\n }\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br")])]),e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"Be extra careful!"),e("p",null,[t("As mentioned in Step 3 of section 5.3, make sure to change "),e("code",null,"/home/vpsadmin/www/webpage"),t(" to your actual file path.")])])]),e("li",null,[e("p",null,[t("Make "),e("code",null,"nginx"),t(" reload the configuration to take effect.")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"sudo"),t(" systemctl reload nginx\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,"The complete setup process is as follows:"),e("p",null,[e("img",{src:"/Xray-docs-next/assets/ch05-img02-nginx-conf-full.d3e1011d.gif",alt:"Web page settings demonstration"})])]),e("li",null,[e("p",null,[t("Now, if you visit "),e("code",null,"http://subdomain.your_domain.com"),t(", you should see this page, indicating success:")]),e("p",null,[e("img",{src:"/Xray-docs-next/assets/ch05-img03-nginx-http-running.46c296a3.png",alt:"http web page success"})])])])])],-1),w=e("h2",{id:"_5-4-common-error-explanations",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-4-common-error-explanations","aria-hidden":"true"},"#"),t(" 5.4 Common error explanations")],-1),y=e("p",null,"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.",-1),x=e("p",null,[t("Then why do some students still get stuck at this step, and the web page just won't open? There are basically two words: "),e("strong",null,"carelessness"),t(". Because there are only two possible issues with the configuration here, and there are only two reasons for them.")],-1),v=e("p",null,"I. Two types of issues:",-1),T=e("ul",null,[e("li",null,[t("In "),e("code",null,"nginx.conf"),t(", the "),e("code",null,"/home/vpsadmin/www/webpage"),t(" does not match the actual file path; "),e("code",null,"nginx"),t(" cannot find the file")]),e("li",null,[t("The path is correct, but "),e("code",null,"nginx"),t(" doesn't have permission to access it")])],-1),I=e("p",null,"II. Two reasons:",-1),B=e("ul",null,[e("li",null,[t("Use a "),e("strong",null,"non-root user"),t(" but still directly copy the commands in the text without modification. (This is basically like copying the name of another student when copying answers)")]),e("li",null,[t("Insist on using a "),e("strong",null,"root user")])],-1),S=e("p",null,"If you encounter any errors, please carefully review the explanations in Steps 3 and 5-2 of Section 5.3.",-1),_=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"Warning"),e("p",null,[t("In the early stages of this article, a lot of space has been devoted to explaining the importance of using a "),e("strong",null,"non-root user"),t(" for security, and the entire article is written based on this premise. So, issues caused by using a "),e("strong",null,"root user"),t(" are not within the scope of this article.")]),e("p",null,[t("But I believe that students who persist in using the "),e("code",null,"root"),t(" 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.")]),e("h2",{id:"_5-5-your-progress",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-5-your-progress","aria-hidden":"true"},"#"),t(" 5.5 Your Progress")]),e("p",null,"So far, Xray's first infrastructure [webpage] has been established. Let's now move on to the second infrastructure [certificate]!"),e("blockquote",null,[e("p",null,"⬛⬛⬛⬛⬛⬜⬜⬜ 62.5%")])],-1);l.render=function(e,t){return n(),s(a,null,[o,i,c,u,p,r,d,g,h,m,k,b,f,w,y,x,v,T,I,B,S,_],64)};export default l; +import{o as n,c as s,F as a,a as e,e as t}from"./app.48111a85.js";const l={},o=e("h1",{id:"chapter-5-website-building",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#chapter-5-website-building","aria-hidden":"true"},"#"),t(" Chapter 5: Website Building")],-1),i=e("h2",{id:"_5-1-why-should-you-create-a-website",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-1-why-should-you-create-a-website","aria-hidden":"true"},"#"),t(" 5.1 Why should you create a website?")],-1),c=e("p",null,"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?",-1),u=e("p",null,"First, let's answer the first question. The reasons for building a website are:",-1),p=e("ol",null,[e("li",null,"Apply for a legitimate TLS certificate (very important)"),e("li",null,"Provide reasonable fallback to prevent active probing attacks and improve security"),e("li",null,"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.")],-1),r=e("p",null,"Now let's answer the second question:",-1),d=e("ol",null,[e("li",null,[t('As a demonstration, this article uses only the simplest "single-file HTML page + Nginx" setup to achieve the above objectives, so it is '),e("strong",null,"very easy"),t(".")]),e("li",null,"This website can not only be used for camouflage but also for real development and growth. The complexity depends entirely on you."),e("li",null,'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.')],-1),g=e("h2",{id:"_5-2-log-in-to-vps-install-and-run-nginx",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-2-log-in-to-vps-install-and-run-nginx","aria-hidden":"true"},"#"),t(" 5.2 Log in to VPS, install and run Nginx")],-1),h=e("ol",null,[e("li",null,[e("p",null,"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."),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"sudo"),t(),e("span",{class:"token function"},"apt"),t(" update "),e("span",{class:"token operator"},"&&"),t(),e("span",{class:"token function"},"sudo"),t(),e("span",{class:"token function"},"apt"),t(),e("span",{class:"token function"},"install"),t(" nginx\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,[t("After completion, Nginx will automatically run. Open the browser on Windows and enter "),e("code",null,"http://100.200.300.400:80"),t(". If you see the interface shown below, it means Nginx is running normally.")]),e("p",null,[e("img",{src:"/Xray-docs-next/assets/ch05-img01-nginx-default-running.24698092.png",alt:"Nginx default interface"})])])],-1),m=e("h2",{id:"_5-3-create-the-simplest-web-page",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-3-create-the-simplest-web-page","aria-hidden":"true"},"#"),t(" 5.3 Create the simplest web page")],-1),k=e("ol",null,[e("li",null,[e("p",null,"Basic Linux commands for beginners:"),e("table",null,[e("thead",null,[e("tr",null,[e("th",{style:{"text-align":"center"}},"No."),e("th",{style:{"text-align":"center"}},"Command Name"),e("th",{style:{"text-align":"center"}},"Command Description")])]),e("tbody",null,[e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"cmd-10")]),e("td",{style:{"text-align":"center"}},[e("code",null,"mkdir")]),e("td",{style:{"text-align":"center"}},"Create a new folder")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"cmd-11")]),e("td",{style:{"text-align":"center"}},[e("code",null,"systemctl reload")]),e("td",{style:{"text-align":"center"}},"Reload a specific service")])])])]),e("li",null,[e("p",null,"Basic Linux configuration files for beginners:"),e("table",null,[e("thead",null,[e("tr",null,[e("th",{style:{"text-align":"center"}},"No."),e("th",{style:{"text-align":"center"}},"Configuration File Location"),e("th",{style:{"text-align":"center"}},"File Description")])]),e("tbody",null,[e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"conf-02")]),e("td",{style:{"text-align":"center"}},[e("code",null,"/etc/nginx/nginx.conf")]),e("td",{style:{"text-align":"center"}},"Nginx program settings")])])])]),e("li",null,[e("p",null,[t("Create a dedicated folder "),e("code",null,"/home/vpsadmin/www/webpage/"),t(" for the website and create the web page file "),e("code",null,"index.html")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"mkdir"),t(" -p ~/www/webpage/ "),e("span",{class:"token operator"},"&&"),t(),e("span",{class:"token function"},"nano"),t(" ~/www/webpage/index.html\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])])],-1),b=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"Warning"),e("p",null,[t("If you are not using the username "),e("code",null,"vpsadmin"),t(', please be sure to understand the meaning of the "~" symbol in this command (this is related to Step 5 content):')]),e("ul",null,[e("li",null,[t("If it is a "),e("strong",null,"non-root user"),t(', "~" is equivalent to '),e("code",null,"/home/username")]),e("li",null,[t("If it is a "),e("strong",null,"root user"),t(', "~" is equivalent to '),e("code",null,"/root")])])],-1),f=e("ol",{start:"4"},[e("li",null,[e("p",null,[t("Copy the entire content below, save ("),e("code",null,"ctrl+o"),t(") and exit ("),e("code",null,"ctrl+x"),t(").")]),e("div",{class:"language-html ext-html line-numbers-mode"},[e("pre",{class:"language-html"},[e("code",null,[e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("html")]),t(),e("span",{class:"token attr-name"},"lang"),e("span",{class:"token attr-value"},[e("span",{class:"token punctuation attr-equals"},"="),e("span",{class:"token punctuation"},'"'),e("span",{class:"token punctuation"},'"')]),e("span",{class:"token punctuation"},">")]),t("\n "),e("span",{class:"token comment"},"\x3c!-- Text between angle brackets is an HTML tag and is not displayed.\n Most tags, such as the HTML and /HTML tags that surround the contents of\n a page, come in pairs; some tags, like HR, for a horizontal rule, stand\n alone. Comments, such as the text you're reading, are not displayed when\n the Web page is shown. The information between the HEAD and /HEAD tags is\n not displayed. The information between the BODY and /BODY tags is displayed.--\x3e"),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("head")]),e("span",{class:"token punctuation"},">")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("title")]),e("span",{class:"token punctuation"},">")]),t("Enter a title, displayed at the top of the window."),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token comment"},"\x3c!-- The information between the BODY and /BODY tags is displayed.--\x3e"),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("body")]),e("span",{class:"token punctuation"},">")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("h1")]),e("span",{class:"token punctuation"},">")]),t("Enter the main heading, usually the same as the title."),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("Be "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("b")]),e("span",{class:"token punctuation"},">")]),t("bold"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t(" in stating your key points. Put them in a list:"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("ul")]),e("span",{class:"token punctuation"},">")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("li")]),e("span",{class:"token punctuation"},">")]),t("The first item in your list"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("li")]),e("span",{class:"token punctuation"},">")]),t("The second item; "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("i")]),e("span",{class:"token punctuation"},">")]),t("italicize"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t(" key words"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("Improve your image by including an image."),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("img")]),t(),e("span",{class:"token attr-name"},"src"),e("span",{class:"token attr-value"},[e("span",{class:"token punctuation attr-equals"},"="),e("span",{class:"token punctuation"},'"'),t("https://i.imgur.com/SEBww.jpg"),e("span",{class:"token punctuation"},'"')]),t(),e("span",{class:"token attr-name"},"alt"),e("span",{class:"token attr-value"},[e("span",{class:"token punctuation attr-equals"},"="),e("span",{class:"token punctuation"},'"'),t("A Great HTML Resource"),e("span",{class:"token punctuation"},'"')]),t(),e("span",{class:"token punctuation"},"/>")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("\n Add a link to your favorite\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("a")]),t(),e("span",{class:"token attr-name"},"href"),e("span",{class:"token attr-value"},[e("span",{class:"token punctuation attr-equals"},"="),e("span",{class:"token punctuation"},'"'),t("https://www.dummies.com/"),e("span",{class:"token punctuation"},'"')]),e("span",{class:"token punctuation"},">")]),t("Web site"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t(". Break up your page\n with a horizontal rule or two.\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("hr")]),t(),e("span",{class:"token punctuation"},"/>")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("\n Finally, link to "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("a")]),t(),e("span",{class:"token attr-name"},"href"),e("span",{class:"token attr-value"},[e("span",{class:"token punctuation attr-equals"},"="),e("span",{class:"token punctuation"},'"'),t("page2.html"),e("span",{class:"token punctuation"},'"')]),e("span",{class:"token punctuation"},">")]),t("another page"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t(" in your own Web\n site.\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token comment"},"\x3c!-- And add a copyright notice.--\x3e"),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"<"),t("p")]),e("span",{class:"token punctuation"},">")]),t("© Wiley Publishing, 2011"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n "),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n"),e("span",{class:"token tag"},[e("span",{class:"token tag"},[e("span",{class:"token punctuation"},"")]),t("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br"),e("span",{class:"line-number"},"34"),e("br"),e("span",{class:"line-number"},"35"),e("br"),e("span",{class:"line-number"},"36"),e("br")])])]),e("li",null,[e("p",null,[t("Modify "),e("code",null,"nginx.conf"),t(" and restart the "),e("code",null,"Nginx"),t(" service, directing the http access on port 80 to the newly created "),e("code",null,"html"),t(" page.")]),e("ol",null,[e("li",null,[e("p",null,[t("Modify "),e("code",null,"nginx.conf"),t(".")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"sudo"),t(),e("span",{class:"token function"},"nano"),t(" /etc/nginx/nginx.conf\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,[t("Add the following content inside"),e("code",null,"http{}"),t(", then save ("),e("code",null,"ctrl+o"),t(") and exit ("),e("code",null,"ctrl+x"),t("). (Remember to replace the domain name with the real domain name you prepared earlier, including the subdomain)")]),e("div",{class:"language-text ext-text line-numbers-mode"},[e("pre",{class:"language-text"},[e("code",null," server {\n listen 80;\n server_name subdomain.your_domain.com;\n root /home/vpsadmin/www/webpage;\n index index.html;\n }\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br")])]),e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"Be extra careful!"),e("p",null,[t("As mentioned in Step 3 of section 5.3, make sure to change "),e("code",null,"/home/vpsadmin/www/webpage"),t(" to your actual file path.")])])]),e("li",null,[e("p",null,[t("Make "),e("code",null,"nginx"),t(" reload the configuration to take effect.")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"sudo"),t(" systemctl reload nginx\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,"The complete setup process is as follows:"),e("p",null,[e("img",{src:"/Xray-docs-next/assets/ch05-img02-nginx-conf-full.d3e1011d.gif",alt:"Web page settings demonstration"})])]),e("li",null,[e("p",null,[t("Now, if you visit "),e("code",null,"http://subdomain.your_domain.com"),t(", you should see this page, indicating success:")]),e("p",null,[e("img",{src:"/Xray-docs-next/assets/ch05-img03-nginx-http-running.46c296a3.png",alt:"http web page success"})])])])])],-1),w=e("h2",{id:"_5-4-common-error-explanations",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-4-common-error-explanations","aria-hidden":"true"},"#"),t(" 5.4 Common error explanations")],-1),y=e("p",null,"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.",-1),x=e("p",null,[t("Then why do some students still get stuck at this step, and the web page just won't open? There are basically two words: "),e("strong",null,"carelessness"),t(". Because there are only two possible issues with the configuration here, and there are only two reasons for them.")],-1),v=e("p",null,"I. Two types of issues:",-1),T=e("ul",null,[e("li",null,[t("In "),e("code",null,"nginx.conf"),t(", the "),e("code",null,"/home/vpsadmin/www/webpage"),t(" does not match the actual file path; "),e("code",null,"nginx"),t(" cannot find the file")]),e("li",null,[t("The path is correct, but "),e("code",null,"nginx"),t(" doesn't have permission to access it")])],-1),I=e("p",null,"II. Two reasons:",-1),B=e("ul",null,[e("li",null,[t("Use a "),e("strong",null,"non-root user"),t(" but still directly copy the commands in the text without modification. (This is basically like copying the name of another student when copying answers)")]),e("li",null,[t("Insist on using a "),e("strong",null,"root user")])],-1),S=e("p",null,"If you encounter any errors, please carefully review the explanations in Steps 3 and 5-2 of Section 5.3.",-1),_=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"Warning"),e("p",null,[t("In the early stages of this article, a lot of space has been devoted to explaining the importance of using a "),e("strong",null,"non-root user"),t(" for security, and the entire article is written based on this premise. So, issues caused by using a "),e("strong",null,"root user"),t(" are not within the scope of this article.")]),e("p",null,[t("But I believe that students who persist in using the "),e("code",null,"root"),t(" 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.")]),e("h2",{id:"_5-5-your-progress",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-5-your-progress","aria-hidden":"true"},"#"),t(" 5.5 Your Progress")]),e("p",null,"So far, Xray's first infrastructure [webpage] has been established. Let's now move on to the second infrastructure [certificate]!"),e("blockquote",null,[e("p",null,"⬛⬛⬛⬛⬛⬜⬜⬜ 62.5%")])],-1);l.render=function(e,t){return n(),s(a,null,[o,i,c,u,p,r,d,g,h,m,k,b,f,w,y,x,v,T,I,B,S,_],64)};export default l; diff --git a/assets/ch06-certificates.html.6cd9aaca.js b/assets/ch06-certificates.html.4036e92b.js similarity index 99% rename from assets/ch06-certificates.html.6cd9aaca.js rename to assets/ch06-certificates.html.4036e92b.js index 673d53a96..2352b6538 100644 --- a/assets/ch06-certificates.html.6cd9aaca.js +++ b/assets/ch06-certificates.html.4036e92b.js @@ -1 +1 @@ -import{r as n,o as e,c as s,a,b as t,F as o,e as c}from"./app.755d843f.js";const l={},r=a("h1",{id:"chapter-6-certificate-management",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#chapter-6-certificate-management","aria-hidden":"true"},"#"),c(" [Chapter 6] Certificate Management")],-1),i=a("h2",{id:"_6-1-applying-for-a-tls-certificate",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-1-applying-for-a-tls-certificate","aria-hidden":"true"},"#"),c(" 6.1 Applying for a TLS Certificate")],-1),p=a("p",null,"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.",-1),u=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Warning"),a("p",null,"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).")],-1),m=c("Here, I will use a certificate management tool called "),b={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},d=a("code",null,"acme.sh",-1),k=c(", which is simple, lightweight, efficient, and capable of automatically updating certificates."),h=a("p",null,"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.",-1),f=a("h2",{id:"_6-2-install-acme-sh",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-2-install-acme-sh","aria-hidden":"true"},"#"),c(" 6.2 Install "),a("code",null,"acme.sh")],-1),g=a("ol",null,[a("li",null,[a("p",null,"Basic Linux commands for beginners:"),a("table",null,[a("thead",null,[a("tr",null,[a("th",{style:{"text-align":"center"}},"Number"),a("th",{style:{"text-align":"center"}},"Command"),a("th",{style:{"text-align":"center"}},"Description")])]),a("tbody",null,[a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-12")]),a("td",{style:{"text-align":"center"}},[a("code",null,"wget")]),a("td",{style:{"text-align":"center"}},"Retrieve (or download) a webpage file")]),a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-13")]),a("td",{style:{"text-align":"center"}},[a("code",null,"acme.sh")]),a("td",{style:{"text-align":"center"}},"Commands related to acme.sh certificate management")])])])]),a("li",null,[a("p",null,"Run the installation script.")])],-1),y=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"wget"),c(" -O - https://get.acme.sh "),a("span",{class:"token operator"},"|"),c(),a("span",{class:"token function"},"sh"),c("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),v=a("ol",{start:"3"},[a("li",null,[c("Make the "),a("code",null,"acme.sh"),c(" command effective.")])],-1),w=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token builtin class-name"},"."),c(" .bashrc\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),E=a("p",null,[c("(Note: This command is used to source (load) the "),a("code",null,".bashrc"),c(" file in the shell environment.)")],-1),T=a("ol",{start:"4"},[a("li",null,[c("Enable "),a("code",null,"acme.sh"),c(" automatic upgrade.")])],-1),M=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"acme.sh --upgrade --auto-upgrade\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),C=a("ol",{start:"5"},[a("li",null,"The complete process up to this point is shown in the following diagram:")],-1),A=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch06-img01-acme-install.809938be.gif",alt:"acme.sh installation demo"})],-1),x=a("h2",{id:"_6-3-testing-certificate-application",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-3-testing-certificate-application","aria-hidden":"true"},"#"),c(" 6.3 Testing Certificate Application")],-1),S=a("p",null,[c("Before officially applying for the certificate, we use the testing command ("),a("code",null,"--issue --test"),c(") 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),D=a("ol",null,[a("li",null,"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):")],-1),I=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"acme.sh --issue --server letsencrypt --test -d subdomain.yourdomain.com -w /home/vpsadmin/www/webpage --keylength ec-256\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),W=a("p",null,"(Note: This is a command in shell script for obtaining SSL certificate from Let's Encrypt CA using ACME protocol. It specifies the test server, the subdomain for which the certificate is requested, the webroot directory of the subdomain, and the key length to use for the certificate.)",-1),P=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Explanation"),a("p",null,[c("The main advantage of the "),a("code",null,"ECC"),c(" certificate is that its "),a("code",null,"Keysize"),c(" is smaller, which means that security is improved and encryption and decryption speed is faster for the same size. Why not choose ECC-256bit, which is approximately equivalent to RSA-3072bit in strength? Of course, some people say that the ECC certificate handshake is significantly faster, which I think is a bit exaggerated, because RSA handshake is not too slow either. Even if there is a difference, it should be in milliseconds and difficult to perceive directly.")]),a("p",null,"In addition, if some websites do need to be compatible with certain old devices, please still choose RSA certificates according to your needs."),a("ol",{start:"2"},[a("li",null,"You should eventually see a prompt similar to this:")]),a("div",{class:"language-log ext-log line-numbers-mode"},[a("pre",{class:"language-log"},[a("code",null,[a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:12"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Using ACME_DIRECTORY:"),c(),a("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Using CA:"),c(),a("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Create account key ok"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Registering account:"),c(),a("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Registered\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" ACCOUNT_THUMBPRINT"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'CU6qmPKuRqhyTAIrF4swosR375194z_1ddUlWef8xDc'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Creating domain key\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"The domain key is here:"),c(),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Single domain"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Getting domain auth token for each domain\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:14"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Getting webroot for domain"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:14"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Verifying:"),c(" 二级域名"),a("span",{class:"token punctuation"},"."),c("你的域名"),a("span",{class:"token punctuation"},"."),c("com\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:23"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Pending\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Success\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Verify finished"),a("span",{class:"token punctuation"},","),c(" start to sign"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Lets finalize the order"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Le_OrderFinalize"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'https://acme-staging-v02.api.letsencrypt.org/acme/finalize/490205995/7730242871'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Downloading cert"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Le_LinkCert"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'https://acme-staging-v02.api.letsencrypt.org/acme/cert/xujss5xt8i38waubafz2xujss5xt8i38waubz2'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:21:52"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Cert success"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("BEGIN CERTIFICAT"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("\nsxlYqPvWreKgD5b8JyOQX0Yg2MLoRUoDyqVkd31PthIiwzdckoh5eD3JU7ysYBtN\ncTFK4LGOfjqi8Ks87EVJdK9IaSAu7ZC6h5to0eqpJ5PLhaM3e6yJBbHmYA8w1Smp\nwAb3tdoHZ9ttUIm9CrSzvDBt6BBT6GqYdDamMyCYBLooMyDEM4CUFsOzCRrEqqvC\n2mTTEmhvpojo5rhdTSJxibozyNWTGwoTj0v9pTUeQcGqLIzqi4DowjBHD5guwRid\nSjAFnm6JT2xUQgWFm58A1gv1OhbH1TRPUUmtE1nFEN7YiSjI4xgxqAXT3CLD2EUb\nwXlUrO6c75zSsQP4bRMzgOjJUqHtSb6IEqELzt4M7KzL5iCOruCChCo2DZxUwvVX\ntOoaAyQJzCbTqE6aUqwiKi3gVyoxvDP9mI5JdRYzsDL6GVud7EHPnYeMl9ubLZAK\n0vg84mbMP3f6mYM4KRa1cqiyOIcQPT4AzGFYVv4sm049bZQg7sd0Bz9CaFvE7yDA\n1y17XlgCDnsjxl66bqI1vkENN9XT5xeFHONqc18b5fZEKSIvdX7iWPFWp1PyMPpG\n0pMCP1EymZNFxIMJLgbWqExwLWfPc5Ib3PjBaIqhXPnw6sT2MQSxXwDupq1UJVhV\n7E3hQRVlwI4CXi6WLHJMNvNRyyK87gCrLH1bKYsPeRVaz77poWBq49zwBCts6hPY\nIeF4ltGXyANNIOPEi8vy138fRU4LYh81d8FjOtFfJZogMjwhfNvapqxPMsioPlmX\nTnZu0n7setrVNUEfTMHWqPpDgk5MPrWLA4LapqaDfEX4pwnQJLMwMi6s94z165c0\niMRSKA1yU5zqv8aNsDfPoY4OkSPWs4MaXgRRSLBsUfZ15DwQXPk76kegHIyxWvwF\ntYw9HKR5QCMK66fa0z4aJoFVFLK0IIOGEZOanRFUCnkLUDd3QZ3YU8lEcrj7Uxos\nhaiRNICyC6UfsCJ94a8vcNyMosPv3xBLMp19WXgiFYqEFQkntkv1FLRI35fjeJmg\n0fmD9VG9bkzGPHihJgQLRlCHasGf6XrdfkSsODAyCUHUHJ0RzqF4YEZMcxDxzuQ2\nYO7bFwj7S3mUdVPZ6MPasjxdyBjJgEBMch2uy4AhmudXfEBQBye8W6ZI4ztZjLVV\nFmP4SIuaNUmMe20TjR8b9NVC96AhxOanWT3mRROsdokpKQGTJvl27EHH8KuAbUOc\nG6KtPy4wslNZNXWcBy9n63RcWak12r7kAIFn38tZxmlw2WUKoRSMAH64GcDTjRQd\nAm65hBHzvGrj93wEuVNIebvNIsJOlng3HFjpIxVqKGMCIfWIKGDE3YzK3p4LbGZ6\nNZFQWYJLNVf2M9CCJfbEImPYgvctrxl39H6KVYPCw1SAdaj9NneUqmREOQkKoEB0\nx6PmNirbMscHhQPSC0JQaqUgaQFgba1ALmzRYAnYhNb0twkTxWbY7DBkAarxqMIp\nyiLKcBFc5H7dgJCImo7us7aJeftC44uWkPIjw9AKH"),a("span",{class:"token operator"},"="),c("\n"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("END CERTIFICAT"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:21:52"),c(" AM\n\n"),a("span",{class:"token number"},"3"),a("span",{class:"token punctuation"},"."),c(" Note"),a("span",{class:"token operator"},":"),c(" The certificate applied for here is a test certificate"),a("span",{class:"token punctuation"},","),c(" which cannot be used directly"),a("span",{class:"token punctuation"},"."),c(" It is only used to prove that your domain and configuration are correct"),a("span",{class:"token punctuation"},"."),c(" If you observe carefully"),a("span",{class:"token punctuation"},","),c(" you will find that the domain that issues the certificate to you is `"),a("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org`"),a("span",{class:"token punctuation"},","),c(" and this `staging` can be understood as a "),a("span",{class:"token string"},'"test server"'),a("span",{class:"token operator"},"!"),c("\n\n"),a("span",{class:"token number"},"4"),a("span",{class:"token punctuation"},"."),c(" If this step goes wrong"),a("span",{class:"token punctuation"},","),c(" you can run the following command to check the detailed application process and specific errors"),a("span",{class:"token punctuation"},"."),c(" If you don't understand"),a("span",{class:"token punctuation"},","),c(" you can hide sensitive information and ask in the Xray group"),a("span",{class:"token punctuation"},"."),c("\n\n```shell\n"),a("span",{class:"token domain constant"},"acme.sh"),c(),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("issue "),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("server letsencrypt "),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("test "),a("span",{class:"token operator"},"-"),c("d "),a("span",{class:"token domain constant"},"subdomain.yourdomain.com"),c(),a("span",{class:"token operator"},"-"),c("w "),a("span",{class:"token file-path string"},"/home/vpsadmin/www/webpage"),c(),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("keylength ec"),a("span",{class:"token operator"},"-"),a("span",{class:"token number"},"256"),c(),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("debug\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br"),a("span",{class:"line-number"},"37"),a("br"),a("span",{class:"line-number"},"38"),a("br"),a("span",{class:"line-number"},"39"),a("br"),a("span",{class:"line-number"},"40"),a("br"),a("span",{class:"line-number"},"41"),a("br"),a("span",{class:"line-number"},"42"),a("br"),a("span",{class:"line-number"},"43"),a("br"),a("span",{class:"line-number"},"44"),a("br"),a("span",{class:"line-number"},"45"),a("br"),a("span",{class:"line-number"},"46"),a("br"),a("span",{class:"line-number"},"47"),a("br"),a("span",{class:"line-number"},"48"),a("br"),a("span",{class:"line-number"},"49"),a("br"),a("span",{class:"line-number"},"50"),a("br"),a("span",{class:"line-number"},"51"),a("br"),a("span",{class:"line-number"},"52"),a("br"),a("span",{class:"line-number"},"53"),a("br"),a("span",{class:"line-number"},"54"),a("br")])]),a("p",null,"(Note: This command is written in Chinese characters, therefore I have translated it into English. The command is used to issue SSL/TLS certificates using acme.sh client with Let's Encrypt CA in test mode for a subdomain of your domain with the specified webroot path, key length and in debug mode.)"),a("p",null,[c("Hmm, that's right. Just added a "),a("code",null,"--debug"),c(" parameter at the end of the command.")]),a("ol",{start:"5"},[a("li",null,"Once this step is confirmed to be successful, you can apply for the formal certificate. (The test certificate does not need to be deleted, as it will be automatically replaced by the formal certificate.)")]),a("h2",{id:"_6-4-application-for-official-certification",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-4-application-for-official-certification","aria-hidden":"true"},"#"),c(" 6.4 Application for Official Certification")]),a("ol",null,[a("li",null,[c("The command for applying for an official certificate is as follows (i.e., remove the "),a("code",null,"--test"),c(" parameter and add the "),a("code",null,"--force"),c(" parameter at the end):")])]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"acme.sh --set-default-ca --server letsencrypt\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("p",null,[c("This is a command in the shell language. It sets the default Certificate Authority (CA) to Let's Encrypt by using the "),a("code",null,"acme.sh"),c(" script.")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"acme.sh --issue -d subdomain.yourdomain.com -w /home/vpsadmin/www/webpage --keylength ec-256 --force\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("p",null,'(Note: This is a command written in shell script that requests a SSL certificate from ACME server using the ACME client "acme.sh". It specifies the subdomain of the domain name, the web root directory of the website, the key length, and forces the re-issuance of the certificate.)'),a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Explanation"),a("p",null,[c("The meaning of the "),a("code",null,"--force"),c(' parameter is to manually (forcefully) update the certificate before the existing certificate expires. Although the certificate we applied for from the "test server" in the previous step cannot be used directly, it has not expired yet, so this parameter is needed.')])])],-1),L=a("ol",{start:"2"},[a("li",null,"You should eventually see a prompt that looks similar to the one above.")],-1),R=a("div",{class:"language-log ext-log line-numbers-mode"},[a("pre",{class:"language-log"},[a("code",null,[c("vpsadmin"),a("span",{class:"token operator"},"@"),c("vps"),a("span",{class:"token operator"},"-"),c("server"),a("span",{class:"token operator"},":"),a("span",{class:"token operator"},"~"),a("span",{class:"token operator"},"$"),c(),a("span",{class:"token domain constant"},"acme.sh"),c(),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("issue "),a("span",{class:"token operator"},"-"),c("d "),a("span",{class:"token domain constant"},"subdomain.yourdomain.com"),c(),a("span",{class:"token operator"},"-"),c("w "),a("span",{class:"token file-path string"},"/home/vpsadmin/www/webpage"),c(),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("keylength ec"),a("span",{class:"token operator"},"-"),a("span",{class:"token number"},"256"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Using CA:"),c(),a("span",{class:"token url"},"https://acme-v02.api.letsencrypt.org/directory"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Creating domain key\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"The domain key is here:"),c(),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/subdomain.yourdomain.com_ecc/subdomain.yourdomain.com.key"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Single domain"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'subdomain.yourdomain.com'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Getting domain auth token for each domain\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Getting webroot for domain"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'subdomain.yourdomain.com'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Verifying:"),c(),a("span",{class:"token domain constant"},"subdomain.yourdomain.com"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Pending\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Success\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Verify finished"),a("span",{class:"token punctuation"},","),c(" start to sign"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Lets finalize the order"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Le_OrderFinalize"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'https://acme-v02.api.letsencrypt.org/acme/finalize/490205996/7730242872'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Downloading cert"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Le_LinkCert"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'https://acme-v02.api.letsencrypt.org/acme/cert/vsxvk0oldnuobe51ayxz4dms62sk2dwmw9zhuw'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Cert success"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("BEGIN CERTIFICAT"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("\nsxlYqPvWreKgD5b8JyOQX0Yg2MLoRUoDyqVkd31PthIiwzdckoh5eD3JU7ysYBtN\ncTFK4LGOfjqi8Ks87EVJdK9IaSAu7ZC6h5to0eqpJ5PLhaM3e6yJBbHmYA8w1Smp\nwAb3tdoHZ9ttUIm9CrSzvDBt6BBT6GqYdDamMyCYBLooMyDEM4CUFsOzCRrEqqvC\n2mTTEmhvpojo5rhdTSJxibozyNWTGwoTj0v9pTUeQcGqLIzqi4DowjBHD5guwRid\nSjAFnm6JT2xUQgWFm58A1gv1OhbH1TRPUUmtE1nFEN7YiSjI4xgxqAXT3CLD2EUb\nwXlUrO6c75zSsQP4bRMzgOjJUqHtSb6IEqELzt4M7KzL5iCOruCChCo2DZxUwvVX\ntOoaAyQJzCbTqE6aUqwiKi3gVyoxvDP9mI5JdRYzsDL6GVud7EHPnYeMl9ubLZAK\n0vg84mbMP3f6mYM4KRa1cqiyOIcQPT4AzGFYVv4sm049bZQg7sd0Bz9CaFvE7yDA\n1y17XlgCDnsjxl66bqI1vkENN9XT5xeFHONqc18b5fZEKSIvdX7iWPFWp1PyMPpG\n0pMCP1EymZNFxIMJLgbWqExwLWfPc5Ib3PjBaIqhXPnw6sT2MQSxXwDupq1UJVhV\n7E3hQRVlwI4CXi6WLHJMNvNRyyK87gCrLH1bKYsPeRVaz77poWBq49zwBCts6hPY\nIeF4ltGXyANNIOPEi8vy138fRU4LYh81d8FjOtFfJZogMjwhfNvapqxPMsioPlmX\nTnZu0n7setrVNUEfTMHWqPpDgk5MPrWLA4LapqaDfEX4pwnQJLMwMi6s94z165c0\niMRSKA1yU5zqv8aNsDfPoY4OkSPWs4MaXgRRSLBsUfZ15DwQXPk76kegHIyxWvwF\ntYw9HKR5QCMK66fa0z4aJoFVFLK0IIOGEZOanRFUCnkLUDd3QZ3YU8lEcrj7Uxos\nhaiRNICyC6UfsCJ94a8vcNyMosPv3xBLMp19WXgiFYqEFQkntkv1FLRI35fjeJmg\n0fmD9VG9bkzGPHihJgQLRlCHasGf6XrdfkSsODAyCUHUHJ0RzqF4YEZMcxDxzuQ2\nYO7bFwj7S3mUdVPZ6MPasjxdyBjJgEBMch2uy4AhmudXfEBQBye8W6ZI4ztZjLVV\nFmP4SIuaNUmMe20TjR8b9NVC96AhxOanWT3mRROsdokpKQGTJvl27EHH8KuAbUOc\nG6KtPy4wslNZNXWcBy9n63RcWak12r7kAIFn38tZxmlw2WUKoRSMAH64GcDTjRQd\nAm65hBHzvGrj93wEuVNIebvNIsJOlng3HFjpIxVqKGMCIfWIKGDE3YzK3p4LbGZ6\nNZFQWYJLNVf2M9CCJfbEImPYgvctrxl39H6KVYPCw1SAdaj9NneUqmREOQkKoEB0\nx6PmNirbMscHhQPSC0JQaqUgaQFgba1ALmzRYAnYhNb0twkTxWbY7DBkAarxqMIp\nyiLKcBFc5H7dgJCImo7us7aJeftC44uWkPM"),a("span",{class:"token operator"},"="),c("\n"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("END CERTIFICAT"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:52"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Your cert is in "),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/subdomain.yourdomain.com_ecc/subdomain.yourdomain.com.cer"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:52"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Your cert key is in "),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/subdomain.yourdomain.com_ecc/subdomain.yourdomain.com.key"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:52"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" The intermediate CA cert is in "),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/subdomain.yourdomain.com_ecc/ca.cer"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:52"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"And the full chain certs is there:"),c(),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/subdomain.yourdomain.com_ecc/fullchain.cer"),c("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br"),a("span",{class:"line-number"},"37"),a("br"),a("span",{class:"line-number"},"38"),a("br"),a("span",{class:"line-number"},"39"),a("br"),a("span",{class:"line-number"},"40"),a("br"),a("span",{class:"line-number"},"41"),a("br"),a("span",{class:"line-number"},"42"),a("br"),a("span",{class:"line-number"},"43"),a("br"),a("span",{class:"line-number"},"44"),a("br"),a("span",{class:"line-number"},"45"),a("br"),a("span",{class:"line-number"},"46"),a("br")])],-1),q=a("ol",{start:"3"},[a("li",null,[c("If you observe carefully, you will find that the domain name that issues the certificate to you this time is "),a("code",null,"https://acme-v02.api.letsencrypt.org"),c(", which lacks the word "),a("code",null,"staging"),c(". Therefore, this is the [Production Environment]!")])],-1),U=a("h2",{id:"_6-5-certificate-installation",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-5-certificate-installation","aria-hidden":"true"},"#"),c(" 6.5 Certificate Installation")],-1),N=a("ol",null,[a("li",null,"After completing the certificate application, it needs to be installed to a specified location and referenced in the configuration file to take effect:")],-1),F=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[c("vpsadmin@vps-server:~$ acme.sh --installcert -d subdomain.yourdomain.com --cert-file /path/to/install/cert.crt --key-file /path/to/install/cert.key --fullchain-file /path/to/install/fullchain.crt --ecc\n"),a("span",{class:"token punctuation"},"["),c("Mon "),a("span",{class:"token number"},"14"),c(" Feb "),a("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),a("span",{class:"token punctuation"},"]"),c(" Installing cert to: /etc/xray/cert/cert.crt\n"),a("span",{class:"token punctuation"},"["),c("Mon "),a("span",{class:"token number"},"14"),c(" Feb "),a("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),a("span",{class:"token punctuation"},"]"),c(" Installing key to: /etc/xray/cert/cert.key\n"),a("span",{class:"token punctuation"},"["),c("Mon "),a("span",{class:"token number"},"14"),c(" Feb "),a("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),a("span",{class:"token punctuation"},"]"),c(" Installing full chain to: /etc/xray/cert/fullchain.crt\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br")])],-1),z=a("p",null,"(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.)",-1),Y=a("h2",{id:"_6-6-your-progress",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-6-your-progress","aria-hidden":"true"},"#"),c(" 6.6 Your Progress")],-1),J=a("p",null,"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!",-1),H=a("blockquote",null,[a("p",null,"⬛⬛⬛⬛⬛⬛⬜⬜ 75%")],-1);l.render=function(c,l){const K=n("OutboundLink");return e(),s(o,null,[r,i,p,u,a("p",null,[m,a("a",b,[d,t(K)]),k]),h,f,g,y,v,w,E,T,M,C,A,x,S,D,I,W,P,L,R,q,U,N,F,z,Y,J,H],64)};export default l; +import{r as n,o as e,c as s,a,b as t,F as o,e as c}from"./app.48111a85.js";const l={},r=a("h1",{id:"chapter-6-certificate-management",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#chapter-6-certificate-management","aria-hidden":"true"},"#"),c(" [Chapter 6] Certificate Management")],-1),i=a("h2",{id:"_6-1-applying-for-a-tls-certificate",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-1-applying-for-a-tls-certificate","aria-hidden":"true"},"#"),c(" 6.1 Applying for a TLS Certificate")],-1),p=a("p",null,"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.",-1),u=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Warning"),a("p",null,"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).")],-1),m=c("Here, I will use a certificate management tool called "),b={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},d=a("code",null,"acme.sh",-1),k=c(", which is simple, lightweight, efficient, and capable of automatically updating certificates."),h=a("p",null,"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.",-1),f=a("h2",{id:"_6-2-install-acme-sh",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-2-install-acme-sh","aria-hidden":"true"},"#"),c(" 6.2 Install "),a("code",null,"acme.sh")],-1),g=a("ol",null,[a("li",null,[a("p",null,"Basic Linux commands for beginners:"),a("table",null,[a("thead",null,[a("tr",null,[a("th",{style:{"text-align":"center"}},"Number"),a("th",{style:{"text-align":"center"}},"Command"),a("th",{style:{"text-align":"center"}},"Description")])]),a("tbody",null,[a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-12")]),a("td",{style:{"text-align":"center"}},[a("code",null,"wget")]),a("td",{style:{"text-align":"center"}},"Retrieve (or download) a webpage file")]),a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-13")]),a("td",{style:{"text-align":"center"}},[a("code",null,"acme.sh")]),a("td",{style:{"text-align":"center"}},"Commands related to acme.sh certificate management")])])])]),a("li",null,[a("p",null,"Run the installation script.")])],-1),y=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"wget"),c(" -O - https://get.acme.sh "),a("span",{class:"token operator"},"|"),c(),a("span",{class:"token function"},"sh"),c("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),v=a("ol",{start:"3"},[a("li",null,[c("Make the "),a("code",null,"acme.sh"),c(" command effective.")])],-1),w=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token builtin class-name"},"."),c(" .bashrc\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),E=a("p",null,[c("(Note: This command is used to source (load) the "),a("code",null,".bashrc"),c(" file in the shell environment.)")],-1),T=a("ol",{start:"4"},[a("li",null,[c("Enable "),a("code",null,"acme.sh"),c(" automatic upgrade.")])],-1),M=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"acme.sh --upgrade --auto-upgrade\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),C=a("ol",{start:"5"},[a("li",null,"The complete process up to this point is shown in the following diagram:")],-1),A=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch06-img01-acme-install.809938be.gif",alt:"acme.sh installation demo"})],-1),x=a("h2",{id:"_6-3-testing-certificate-application",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-3-testing-certificate-application","aria-hidden":"true"},"#"),c(" 6.3 Testing Certificate Application")],-1),S=a("p",null,[c("Before officially applying for the certificate, we use the testing command ("),a("code",null,"--issue --test"),c(") 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),D=a("ol",null,[a("li",null,"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):")],-1),I=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"acme.sh --issue --server letsencrypt --test -d subdomain.yourdomain.com -w /home/vpsadmin/www/webpage --keylength ec-256\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),W=a("p",null,"(Note: This is a command in shell script for obtaining SSL certificate from Let's Encrypt CA using ACME protocol. It specifies the test server, the subdomain for which the certificate is requested, the webroot directory of the subdomain, and the key length to use for the certificate.)",-1),P=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Explanation"),a("p",null,[c("The main advantage of the "),a("code",null,"ECC"),c(" certificate is that its "),a("code",null,"Keysize"),c(" is smaller, which means that security is improved and encryption and decryption speed is faster for the same size. Why not choose ECC-256bit, which is approximately equivalent to RSA-3072bit in strength? Of course, some people say that the ECC certificate handshake is significantly faster, which I think is a bit exaggerated, because RSA handshake is not too slow either. Even if there is a difference, it should be in milliseconds and difficult to perceive directly.")]),a("p",null,"In addition, if some websites do need to be compatible with certain old devices, please still choose RSA certificates according to your needs."),a("ol",{start:"2"},[a("li",null,"You should eventually see a prompt similar to this:")]),a("div",{class:"language-log ext-log line-numbers-mode"},[a("pre",{class:"language-log"},[a("code",null,[a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:12"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Using ACME_DIRECTORY:"),c(),a("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Using CA:"),c(),a("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Create account key ok"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Registering account:"),c(),a("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Registered\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" ACCOUNT_THUMBPRINT"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'CU6qmPKuRqhyTAIrF4swosR375194z_1ddUlWef8xDc'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Creating domain key\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"The domain key is here:"),c(),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Single domain"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:13"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Getting domain auth token for each domain\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:14"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Getting webroot for domain"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:14"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Verifying:"),c(" 二级域名"),a("span",{class:"token punctuation"},"."),c("你的域名"),a("span",{class:"token punctuation"},"."),c("com\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:23"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Pending\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Success\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Verify finished"),a("span",{class:"token punctuation"},","),c(" start to sign"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Lets finalize the order"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Le_OrderFinalize"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'https://acme-staging-v02.api.letsencrypt.org/acme/finalize/490205995/7730242871'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Downloading cert"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"04:25:25"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Le_LinkCert"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'https://acme-staging-v02.api.letsencrypt.org/acme/cert/xujss5xt8i38waubafz2xujss5xt8i38waubz2'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:21:52"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Cert success"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("BEGIN CERTIFICAT"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("\nsxlYqPvWreKgD5b8JyOQX0Yg2MLoRUoDyqVkd31PthIiwzdckoh5eD3JU7ysYBtN\ncTFK4LGOfjqi8Ks87EVJdK9IaSAu7ZC6h5to0eqpJ5PLhaM3e6yJBbHmYA8w1Smp\nwAb3tdoHZ9ttUIm9CrSzvDBt6BBT6GqYdDamMyCYBLooMyDEM4CUFsOzCRrEqqvC\n2mTTEmhvpojo5rhdTSJxibozyNWTGwoTj0v9pTUeQcGqLIzqi4DowjBHD5guwRid\nSjAFnm6JT2xUQgWFm58A1gv1OhbH1TRPUUmtE1nFEN7YiSjI4xgxqAXT3CLD2EUb\nwXlUrO6c75zSsQP4bRMzgOjJUqHtSb6IEqELzt4M7KzL5iCOruCChCo2DZxUwvVX\ntOoaAyQJzCbTqE6aUqwiKi3gVyoxvDP9mI5JdRYzsDL6GVud7EHPnYeMl9ubLZAK\n0vg84mbMP3f6mYM4KRa1cqiyOIcQPT4AzGFYVv4sm049bZQg7sd0Bz9CaFvE7yDA\n1y17XlgCDnsjxl66bqI1vkENN9XT5xeFHONqc18b5fZEKSIvdX7iWPFWp1PyMPpG\n0pMCP1EymZNFxIMJLgbWqExwLWfPc5Ib3PjBaIqhXPnw6sT2MQSxXwDupq1UJVhV\n7E3hQRVlwI4CXi6WLHJMNvNRyyK87gCrLH1bKYsPeRVaz77poWBq49zwBCts6hPY\nIeF4ltGXyANNIOPEi8vy138fRU4LYh81d8FjOtFfJZogMjwhfNvapqxPMsioPlmX\nTnZu0n7setrVNUEfTMHWqPpDgk5MPrWLA4LapqaDfEX4pwnQJLMwMi6s94z165c0\niMRSKA1yU5zqv8aNsDfPoY4OkSPWs4MaXgRRSLBsUfZ15DwQXPk76kegHIyxWvwF\ntYw9HKR5QCMK66fa0z4aJoFVFLK0IIOGEZOanRFUCnkLUDd3QZ3YU8lEcrj7Uxos\nhaiRNICyC6UfsCJ94a8vcNyMosPv3xBLMp19WXgiFYqEFQkntkv1FLRI35fjeJmg\n0fmD9VG9bkzGPHihJgQLRlCHasGf6XrdfkSsODAyCUHUHJ0RzqF4YEZMcxDxzuQ2\nYO7bFwj7S3mUdVPZ6MPasjxdyBjJgEBMch2uy4AhmudXfEBQBye8W6ZI4ztZjLVV\nFmP4SIuaNUmMe20TjR8b9NVC96AhxOanWT3mRROsdokpKQGTJvl27EHH8KuAbUOc\nG6KtPy4wslNZNXWcBy9n63RcWak12r7kAIFn38tZxmlw2WUKoRSMAH64GcDTjRQd\nAm65hBHzvGrj93wEuVNIebvNIsJOlng3HFjpIxVqKGMCIfWIKGDE3YzK3p4LbGZ6\nNZFQWYJLNVf2M9CCJfbEImPYgvctrxl39H6KVYPCw1SAdaj9NneUqmREOQkKoEB0\nx6PmNirbMscHhQPSC0JQaqUgaQFgba1ALmzRYAnYhNb0twkTxWbY7DBkAarxqMIp\nyiLKcBFc5H7dgJCImo7us7aJeftC44uWkPIjw9AKH"),a("span",{class:"token operator"},"="),c("\n"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("END CERTIFICAT"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:21:52"),c(" AM\n\n"),a("span",{class:"token number"},"3"),a("span",{class:"token punctuation"},"."),c(" Note"),a("span",{class:"token operator"},":"),c(" The certificate applied for here is a test certificate"),a("span",{class:"token punctuation"},","),c(" which cannot be used directly"),a("span",{class:"token punctuation"},"."),c(" It is only used to prove that your domain and configuration are correct"),a("span",{class:"token punctuation"},"."),c(" If you observe carefully"),a("span",{class:"token punctuation"},","),c(" you will find that the domain that issues the certificate to you is `"),a("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org`"),a("span",{class:"token punctuation"},","),c(" and this `staging` can be understood as a "),a("span",{class:"token string"},'"test server"'),a("span",{class:"token operator"},"!"),c("\n\n"),a("span",{class:"token number"},"4"),a("span",{class:"token punctuation"},"."),c(" If this step goes wrong"),a("span",{class:"token punctuation"},","),c(" you can run the following command to check the detailed application process and specific errors"),a("span",{class:"token punctuation"},"."),c(" If you don't understand"),a("span",{class:"token punctuation"},","),c(" you can hide sensitive information and ask in the Xray group"),a("span",{class:"token punctuation"},"."),c("\n\n```shell\n"),a("span",{class:"token domain constant"},"acme.sh"),c(),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("issue "),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("server letsencrypt "),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("test "),a("span",{class:"token operator"},"-"),c("d "),a("span",{class:"token domain constant"},"subdomain.yourdomain.com"),c(),a("span",{class:"token operator"},"-"),c("w "),a("span",{class:"token file-path string"},"/home/vpsadmin/www/webpage"),c(),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("keylength ec"),a("span",{class:"token operator"},"-"),a("span",{class:"token number"},"256"),c(),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("debug\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br"),a("span",{class:"line-number"},"37"),a("br"),a("span",{class:"line-number"},"38"),a("br"),a("span",{class:"line-number"},"39"),a("br"),a("span",{class:"line-number"},"40"),a("br"),a("span",{class:"line-number"},"41"),a("br"),a("span",{class:"line-number"},"42"),a("br"),a("span",{class:"line-number"},"43"),a("br"),a("span",{class:"line-number"},"44"),a("br"),a("span",{class:"line-number"},"45"),a("br"),a("span",{class:"line-number"},"46"),a("br"),a("span",{class:"line-number"},"47"),a("br"),a("span",{class:"line-number"},"48"),a("br"),a("span",{class:"line-number"},"49"),a("br"),a("span",{class:"line-number"},"50"),a("br"),a("span",{class:"line-number"},"51"),a("br"),a("span",{class:"line-number"},"52"),a("br"),a("span",{class:"line-number"},"53"),a("br"),a("span",{class:"line-number"},"54"),a("br")])]),a("p",null,"(Note: This command is written in Chinese characters, therefore I have translated it into English. The command is used to issue SSL/TLS certificates using acme.sh client with Let's Encrypt CA in test mode for a subdomain of your domain with the specified webroot path, key length and in debug mode.)"),a("p",null,[c("Hmm, that's right. Just added a "),a("code",null,"--debug"),c(" parameter at the end of the command.")]),a("ol",{start:"5"},[a("li",null,"Once this step is confirmed to be successful, you can apply for the formal certificate. (The test certificate does not need to be deleted, as it will be automatically replaced by the formal certificate.)")]),a("h2",{id:"_6-4-application-for-official-certification",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-4-application-for-official-certification","aria-hidden":"true"},"#"),c(" 6.4 Application for Official Certification")]),a("ol",null,[a("li",null,[c("The command for applying for an official certificate is as follows (i.e., remove the "),a("code",null,"--test"),c(" parameter and add the "),a("code",null,"--force"),c(" parameter at the end):")])]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"acme.sh --set-default-ca --server letsencrypt\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("p",null,[c("This is a command in the shell language. It sets the default Certificate Authority (CA) to Let's Encrypt by using the "),a("code",null,"acme.sh"),c(" script.")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"acme.sh --issue -d subdomain.yourdomain.com -w /home/vpsadmin/www/webpage --keylength ec-256 --force\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("p",null,'(Note: This is a command written in shell script that requests a SSL certificate from ACME server using the ACME client "acme.sh". It specifies the subdomain of the domain name, the web root directory of the website, the key length, and forces the re-issuance of the certificate.)'),a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Explanation"),a("p",null,[c("The meaning of the "),a("code",null,"--force"),c(' parameter is to manually (forcefully) update the certificate before the existing certificate expires. Although the certificate we applied for from the "test server" in the previous step cannot be used directly, it has not expired yet, so this parameter is needed.')])])],-1),L=a("ol",{start:"2"},[a("li",null,"You should eventually see a prompt that looks similar to the one above.")],-1),R=a("div",{class:"language-log ext-log line-numbers-mode"},[a("pre",{class:"language-log"},[a("code",null,[c("vpsadmin"),a("span",{class:"token operator"},"@"),c("vps"),a("span",{class:"token operator"},"-"),c("server"),a("span",{class:"token operator"},":"),a("span",{class:"token operator"},"~"),a("span",{class:"token operator"},"$"),c(),a("span",{class:"token domain constant"},"acme.sh"),c(),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("issue "),a("span",{class:"token operator"},"-"),c("d "),a("span",{class:"token domain constant"},"subdomain.yourdomain.com"),c(),a("span",{class:"token operator"},"-"),c("w "),a("span",{class:"token file-path string"},"/home/vpsadmin/www/webpage"),c(),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("keylength ec"),a("span",{class:"token operator"},"-"),a("span",{class:"token number"},"256"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Using CA:"),c(),a("span",{class:"token url"},"https://acme-v02.api.letsencrypt.org/directory"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Creating domain key\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"The domain key is here:"),c(),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/subdomain.yourdomain.com_ecc/subdomain.yourdomain.com.key"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Single domain"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'subdomain.yourdomain.com'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Getting domain auth token for each domain\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Getting webroot for domain"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'subdomain.yourdomain.com'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"Verifying:"),c(),a("span",{class:"token domain constant"},"subdomain.yourdomain.com"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Pending\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Success\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Verify finished"),a("span",{class:"token punctuation"},","),c(" start to sign"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Lets finalize the order"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Le_OrderFinalize"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'https://acme-v02.api.letsencrypt.org/acme/finalize/490205996/7730242872'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Downloading cert"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Le_LinkCert"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},"'https://acme-v02.api.letsencrypt.org/acme/cert/vsxvk0oldnuobe51ayxz4dms62sk2dwmw9zhuw'"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:51"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Cert success"),a("span",{class:"token punctuation"},"."),c("\n"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("BEGIN CERTIFICAT"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("\nsxlYqPvWreKgD5b8JyOQX0Yg2MLoRUoDyqVkd31PthIiwzdckoh5eD3JU7ysYBtN\ncTFK4LGOfjqi8Ks87EVJdK9IaSAu7ZC6h5to0eqpJ5PLhaM3e6yJBbHmYA8w1Smp\nwAb3tdoHZ9ttUIm9CrSzvDBt6BBT6GqYdDamMyCYBLooMyDEM4CUFsOzCRrEqqvC\n2mTTEmhvpojo5rhdTSJxibozyNWTGwoTj0v9pTUeQcGqLIzqi4DowjBHD5guwRid\nSjAFnm6JT2xUQgWFm58A1gv1OhbH1TRPUUmtE1nFEN7YiSjI4xgxqAXT3CLD2EUb\nwXlUrO6c75zSsQP4bRMzgOjJUqHtSb6IEqELzt4M7KzL5iCOruCChCo2DZxUwvVX\ntOoaAyQJzCbTqE6aUqwiKi3gVyoxvDP9mI5JdRYzsDL6GVud7EHPnYeMl9ubLZAK\n0vg84mbMP3f6mYM4KRa1cqiyOIcQPT4AzGFYVv4sm049bZQg7sd0Bz9CaFvE7yDA\n1y17XlgCDnsjxl66bqI1vkENN9XT5xeFHONqc18b5fZEKSIvdX7iWPFWp1PyMPpG\n0pMCP1EymZNFxIMJLgbWqExwLWfPc5Ib3PjBaIqhXPnw6sT2MQSxXwDupq1UJVhV\n7E3hQRVlwI4CXi6WLHJMNvNRyyK87gCrLH1bKYsPeRVaz77poWBq49zwBCts6hPY\nIeF4ltGXyANNIOPEi8vy138fRU4LYh81d8FjOtFfJZogMjwhfNvapqxPMsioPlmX\nTnZu0n7setrVNUEfTMHWqPpDgk5MPrWLA4LapqaDfEX4pwnQJLMwMi6s94z165c0\niMRSKA1yU5zqv8aNsDfPoY4OkSPWs4MaXgRRSLBsUfZ15DwQXPk76kegHIyxWvwF\ntYw9HKR5QCMK66fa0z4aJoFVFLK0IIOGEZOanRFUCnkLUDd3QZ3YU8lEcrj7Uxos\nhaiRNICyC6UfsCJ94a8vcNyMosPv3xBLMp19WXgiFYqEFQkntkv1FLRI35fjeJmg\n0fmD9VG9bkzGPHihJgQLRlCHasGf6XrdfkSsODAyCUHUHJ0RzqF4YEZMcxDxzuQ2\nYO7bFwj7S3mUdVPZ6MPasjxdyBjJgEBMch2uy4AhmudXfEBQBye8W6ZI4ztZjLVV\nFmP4SIuaNUmMe20TjR8b9NVC96AhxOanWT3mRROsdokpKQGTJvl27EHH8KuAbUOc\nG6KtPy4wslNZNXWcBy9n63RcWak12r7kAIFn38tZxmlw2WUKoRSMAH64GcDTjRQd\nAm65hBHzvGrj93wEuVNIebvNIsJOlng3HFjpIxVqKGMCIfWIKGDE3YzK3p4LbGZ6\nNZFQWYJLNVf2M9CCJfbEImPYgvctrxl39H6KVYPCw1SAdaj9NneUqmREOQkKoEB0\nx6PmNirbMscHhQPSC0JQaqUgaQFgba1ALmzRYAnYhNb0twkTxWbY7DBkAarxqMIp\nyiLKcBFc5H7dgJCImo7us7aJeftC44uWkPM"),a("span",{class:"token operator"},"="),c("\n"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("END CERTIFICAT"),a("span",{class:"token operator"},"-"),a("span",{class:"token operator"},"-"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:52"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Your cert is in "),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/subdomain.yourdomain.com_ecc/subdomain.yourdomain.com.cer"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:52"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" Your cert key is in "),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/subdomain.yourdomain.com_ecc/subdomain.yourdomain.com.key"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:52"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(" The intermediate CA cert is in "),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/subdomain.yourdomain.com_ecc/ca.cer"),c("\n"),a("span",{class:"token punctuation"},"["),a("span",{class:"token date number"},"Wed 30"),c(" Dec "),a("span",{class:"token number"},"2022"),c(),a("span",{class:"token time number"},"15:22:52"),c(" AM EST"),a("span",{class:"token punctuation"},"]"),c(),a("span",{class:"token property"},"And the full chain certs is there:"),c(),a("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/subdomain.yourdomain.com_ecc/fullchain.cer"),c("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br"),a("span",{class:"line-number"},"37"),a("br"),a("span",{class:"line-number"},"38"),a("br"),a("span",{class:"line-number"},"39"),a("br"),a("span",{class:"line-number"},"40"),a("br"),a("span",{class:"line-number"},"41"),a("br"),a("span",{class:"line-number"},"42"),a("br"),a("span",{class:"line-number"},"43"),a("br"),a("span",{class:"line-number"},"44"),a("br"),a("span",{class:"line-number"},"45"),a("br"),a("span",{class:"line-number"},"46"),a("br")])],-1),q=a("ol",{start:"3"},[a("li",null,[c("If you observe carefully, you will find that the domain name that issues the certificate to you this time is "),a("code",null,"https://acme-v02.api.letsencrypt.org"),c(", which lacks the word "),a("code",null,"staging"),c(". Therefore, this is the [Production Environment]!")])],-1),U=a("h2",{id:"_6-5-certificate-installation",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-5-certificate-installation","aria-hidden":"true"},"#"),c(" 6.5 Certificate Installation")],-1),N=a("ol",null,[a("li",null,"After completing the certificate application, it needs to be installed to a specified location and referenced in the configuration file to take effect:")],-1),F=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[c("vpsadmin@vps-server:~$ acme.sh --installcert -d subdomain.yourdomain.com --cert-file /path/to/install/cert.crt --key-file /path/to/install/cert.key --fullchain-file /path/to/install/fullchain.crt --ecc\n"),a("span",{class:"token punctuation"},"["),c("Mon "),a("span",{class:"token number"},"14"),c(" Feb "),a("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),a("span",{class:"token punctuation"},"]"),c(" Installing cert to: /etc/xray/cert/cert.crt\n"),a("span",{class:"token punctuation"},"["),c("Mon "),a("span",{class:"token number"},"14"),c(" Feb "),a("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),a("span",{class:"token punctuation"},"]"),c(" Installing key to: /etc/xray/cert/cert.key\n"),a("span",{class:"token punctuation"},"["),c("Mon "),a("span",{class:"token number"},"14"),c(" Feb "),a("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),a("span",{class:"token punctuation"},"]"),c(" Installing full chain to: /etc/xray/cert/fullchain.crt\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br")])],-1),z=a("p",null,"(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.)",-1),Y=a("h2",{id:"_6-6-your-progress",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_6-6-your-progress","aria-hidden":"true"},"#"),c(" 6.6 Your Progress")],-1),J=a("p",null,"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!",-1),H=a("blockquote",null,[a("p",null,"⬛⬛⬛⬛⬛⬛⬜⬜ 75%")],-1);l.render=function(c,l){const K=n("OutboundLink");return e(),s(o,null,[r,i,p,u,a("p",null,[m,a("a",b,[d,t(K)]),k]),h,f,g,y,v,w,E,T,M,C,A,x,S,D,I,W,P,L,R,q,U,N,F,z,Y,J,H],64)};export default l; diff --git a/assets/ch06-certificates.html.8c0bdd2e.js b/assets/ch06-certificates.html.4582a562.js similarity index 99% rename from assets/ch06-certificates.html.8c0bdd2e.js rename to assets/ch06-certificates.html.4582a562.js index 935f886f6..8db6d94d4 100644 --- a/assets/ch06-certificates.html.8c0bdd2e.js +++ b/assets/ch06-certificates.html.4582a562.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as t,F as l,e as c}from"./app.755d843f.js";const o={},p=e("h1",{id:"【第-6-章】证书管理篇",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#【第-6-章】证书管理篇","aria-hidden":"true"},"#"),c(" 【第 6 章】证书管理篇")],-1),r=e("h2",{id:"_6-1-申请-tls-证书",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-1-申请-tls-证书","aria-hidden":"true"},"#"),c(" 6.1 申请 TLS 证书")],-1),u=e("p",null,"接下来我们要做的,是为我们的域名申请一个真实的 TLS 证书,使网站具备标准 TLS 加密的能力及 HTTPS 访问的能力。这就是 Xray 等现阶段安全代理工具确保流量充分加密最重要的工具。",-1),i=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,"请不要轻易使用自签证书。它并没有让操作简单太多,但增加了无谓的风险(如中间人攻击)。")],-1),m=c("这里我会使用一个叫做 "),b={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},k=e("code",null,"acme.sh",-1),d=c(" 的证书管理工具,它简单、轻量、高效,并可完成证书自动更新。"),h=e("p",null,"另外,我相信,现在你已经逐渐熟悉了 Linux 的基础操作,所以已经多次出现的命令从本章开始不再重复截图、只做简单的描述。如果实在想不起来怎么用的话,就稍微复习一下前面的章节吧。",-1),g=e("h2",{id:"_6-2-安装-acme-sh",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-2-安装-acme-sh","aria-hidden":"true"},"#"),c(" 6.2 安装 "),e("code",null,"acme.sh")],-1),y=e("ol",null,[e("li",null,[e("p",null,"小小白白 Linux 基础命令:"),e("table",null,[e("thead",null,[e("tr",null,[e("th",{style:{"text-align":"center"}},"编号"),e("th",{style:{"text-align":"center"}},"命令名称"),e("th",{style:{"text-align":"center"}},"命令说明")])]),e("tbody",null,[e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"cmd-12")]),e("td",{style:{"text-align":"center"}},[e("code",null,"wget")]),e("td",{style:{"text-align":"center"}},"访问(或下载)某个网页文件")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"cmd-13")]),e("td",{style:{"text-align":"center"}},[e("code",null,"acme.sh")]),e("td",{style:{"text-align":"center"}},"acme.sh 证书管理相关的命令")])])])]),e("li",null,[e("p",null,"运行安装脚本"),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"wget"),c(" -O - https://get.acme.sh "),e("span",{class:"token operator"},"|"),c(),e("span",{class:"token function"},"sh"),c("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,[c("让 "),e("code",null,"acme.sh"),c(" 命令生效")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token builtin class-name"},"."),c(" .bashrc\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,[c("开启 "),e("code",null,"acme.sh"),c(" 的自动升级")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,"acme.sh --upgrade --auto-upgrade\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,"到这一步的完整流程如下图:"),e("p",null,[e("img",{src:"/Xray-docs-next/assets/ch06-img01-acme-install.809938be.gif",alt:"acme.sh安装演示"})])])],-1),E=e("h2",{id:"_6-3-测试证书申请",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-3-测试证书申请","aria-hidden":"true"},"#"),c(" 6.3 测试证书申请")],-1),M=e("p",null,[c("在正式申请证书之前,我们先用测试命令("),e("code",null,"--issue --test"),c(")来验证是否可以成功申请,这样可以避免在本地配置有误时,反复申请证书失败,超过 Let's Encrypt 的频率上限(比如,每小时、每个域名、每个用户失败最多 5 次),导致后面的步骤无法进行。")],-1),T=e("ol",null,[e("li",null,[e("p",null,[c("测试证书申请的命令如下(本文均以 "),e("code",null,"ECC"),c(" 证书为例,因为时至今日,实在没什么理由不用它):")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,"acme.sh --issue --server letsencrypt --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])]),e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"说明"),e("p",null,[e("code",null,"ECC"),c("证书的主要优势在于它的 Keysize 更小,意味着同等大小下安全性的提升和加密解密速度的加快。如 ECC-256bit 的强度大约相当于 RSA-3072bit,何乐而不为呢?当然,有人说 ECC 证书握手会明显更快,这我觉得就有些夸张了,因为 RSA 握手也没有太慢,就算有差别应该也是毫秒级,很难直接感知。")]),e("p",null,[c("另外,如果有些网站确实需要兼容某些古老设备的,那也还是请按需选择"),e("code",null,"RSA"),c("证书。")])])]),e("li",null,[e("p",null,"你最终应该看到类似这样的提示:"),e("div",{class:"language-log ext-log line-numbers-mode"},[e("pre",{class:"language-log"},[e("code",null,[e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:12"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Using ACME_DIRECTORY:"),c(),e("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Using CA:"),c(),e("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Create account key ok"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Registering account:"),c(),e("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Registered\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" ACCOUNT_THUMBPRINT"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'CU6qmPKuRqhyTAIrF4swosR375194z_1ddUlWef8xDc'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Creating domain key\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"The domain key is here:"),c(),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Single domain"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Getting domain auth token for each domain\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:14"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Getting webroot for domain"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:14"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Verifying:"),c(" 二级域名"),e("span",{class:"token punctuation"},"."),c("你的域名"),e("span",{class:"token punctuation"},"."),c("com\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:23"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Pending\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Success\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Verify finished"),e("span",{class:"token punctuation"},","),c(" start to sign"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Lets finalize the order"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Le_OrderFinalize"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'https://acme-staging-v02.api.letsencrypt.org/acme/finalize/490205995/7730242871'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Downloading cert"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Le_LinkCert"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'https://acme-staging-v02.api.letsencrypt.org/acme/cert/xujss5xt8i38waubafz2xujss5xt8i38waubz2'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:21:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Cert success"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("BEGIN CERTIFICAT"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("\nsxlYqPvWreKgD5b8JyOQX0Yg2MLoRUoDyqVkd31PthIiwzdckoh5eD3JU7ysYBtN\ncTFK4LGOfjqi8Ks87EVJdK9IaSAu7ZC6h5to0eqpJ5PLhaM3e6yJBbHmYA8w1Smp\nwAb3tdoHZ9ttUIm9CrSzvDBt6BBT6GqYdDamMyCYBLooMyDEM4CUFsOzCRrEqqvC\n2mTTEmhvpojo5rhdTSJxibozyNWTGwoTj0v9pTUeQcGqLIzqi4DowjBHD5guwRid\nSjAFnm6JT2xUQgWFm58A1gv1OhbH1TRPUUmtE1nFEN7YiSjI4xgxqAXT3CLD2EUb\nwXlUrO6c75zSsQP4bRMzgOjJUqHtSb6IEqELzt4M7KzL5iCOruCChCo2DZxUwvVX\ntOoaAyQJzCbTqE6aUqwiKi3gVyoxvDP9mI5JdRYzsDL6GVud7EHPnYeMl9ubLZAK\n0vg84mbMP3f6mYM4KRa1cqiyOIcQPT4AzGFYVv4sm049bZQg7sd0Bz9CaFvE7yDA\n1y17XlgCDnsjxl66bqI1vkENN9XT5xeFHONqc18b5fZEKSIvdX7iWPFWp1PyMPpG\n0pMCP1EymZNFxIMJLgbWqExwLWfPc5Ib3PjBaIqhXPnw6sT2MQSxXwDupq1UJVhV\n7E3hQRVlwI4CXi6WLHJMNvNRyyK87gCrLH1bKYsPeRVaz77poWBq49zwBCts6hPY\nIeF4ltGXyANNIOPEi8vy138fRU4LYh81d8FjOtFfJZogMjwhfNvapqxPMsioPlmX\nTnZu0n7setrVNUEfTMHWqPpDgk5MPrWLA4LapqaDfEX4pwnQJLMwMi6s94z165c0\niMRSKA1yU5zqv8aNsDfPoY4OkSPWs4MaXgRRSLBsUfZ15DwQXPk76kegHIyxWvwF\ntYw9HKR5QCMK66fa0z4aJoFVFLK0IIOGEZOanRFUCnkLUDd3QZ3YU8lEcrj7Uxos\nhaiRNICyC6UfsCJ94a8vcNyMosPv3xBLMp19WXgiFYqEFQkntkv1FLRI35fjeJmg\n0fmD9VG9bkzGPHihJgQLRlCHasGf6XrdfkSsODAyCUHUHJ0RzqF4YEZMcxDxzuQ2\nYO7bFwj7S3mUdVPZ6MPasjxdyBjJgEBMch2uy4AhmudXfEBQBye8W6ZI4ztZjLVV\nFmP4SIuaNUmMe20TjR8b9NVC96AhxOanWT3mRROsdokpKQGTJvl27EHH8KuAbUOc\nG6KtPy4wslNZNXWcBy9n63RcWak12r7kAIFn38tZxmlw2WUKoRSMAH64GcDTjRQd\nAm65hBHzvGrj93wEuVNIebvNIsJOlng3HFjpIxVqKGMCIfWIKGDE3YzK3p4LbGZ6\nNZFQWYJLNVf2M9CCJfbEImPYgvctrxl39H6KVYPCw1SAdaj9NneUqmREOQkKoEB0\nx6PmNirbMscHhQPSC0JQaqUgaQFgba1ALmzRYAnYhNb0twkTxWbY7DBkAarxqMIp\nyiLKcBFc5H7dgJCImo7us7aJeftC44uWkPIjw9AKH"),e("span",{class:"token operator"},"="),c("\n"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("END CERTIFICAT"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:21:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Your cert is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.cer"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:21:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Your cert key is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:21:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" The intermediate CA cert is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/ca.cer"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:21:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"And the full chain certs is there:"),c(" "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/fullchain.cer"),c("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br"),e("span",{class:"line-number"},"34"),e("br"),e("span",{class:"line-number"},"35"),e("br"),e("span",{class:"line-number"},"36"),e("br"),e("span",{class:"line-number"},"37"),e("br"),e("span",{class:"line-number"},"38"),e("br"),e("span",{class:"line-number"},"39"),e("br"),e("span",{class:"line-number"},"40"),e("br"),e("span",{class:"line-number"},"41"),e("br"),e("span",{class:"line-number"},"42"),e("br"),e("span",{class:"line-number"},"43"),e("br"),e("span",{class:"line-number"},"44"),e("br"),e("span",{class:"line-number"},"45"),e("br"),e("span",{class:"line-number"},"46"),e("br"),e("span",{class:"line-number"},"47"),e("br"),e("span",{class:"line-number"},"48"),e("br"),e("span",{class:"line-number"},"49"),e("br"),e("span",{class:"line-number"},"50"),e("br")])])]),e("li",null,[e("p",null,[c("注意:这里申请的是测试证书,没办法直接用的,只是用来证明你的域名、配置全都正确。仔细观察,你会发现给你发证书的域名是 "),e("code",null,"https://acme-staging-v02.api.letsencrypt.org"),c(",这个 "),e("code",null,"staging"),c(" 你就理解成【测试服】吧!")])]),e("li",null,[e("p",null,"如果这一步出错的话,你可以运行下面的命令,来查看详细的申请过程和具体的错误。(看不懂就隐藏掉敏感信息后,去 Xray 群里问吧)"),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,"acme.sh --issue --server letsencrypt --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256 --debug\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])]),e("p",null,[c("嗯没错,就是在命令的最后加了一个 "),e("code",null,"--debug"),c(" 参数")])]),e("li",null,[e("p",null,"这一步确定成功之后,就可以申请正式的证书了。(测试证书不需要删除,它会自动被正式证书覆盖)")])],-1),v=e("h2",{id:"_6-4-正式证书申请",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-4-正式证书申请","aria-hidden":"true"},"#"),c(" 6.4 正式证书申请")],-1),A=e("ol",null,[e("li",null,[e("p",null,[c("申请正式证书的命令如下(即删掉 "),e("code",null,"--test"),c(" 参数,并在最后加入 "),e("code",null,"--force"),c("参数):")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,"acme.sh --set-default-ca --server letsencrypt\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,"acme.sh --issue -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256 --force\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])]),e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"说明"),e("p",null,[e("code",null,"--force"),c(" 参数的意思就是,在现有证书到期前,手动(强行)更新证书。上一步我们从“测试服”申请的证书虽然不能直接用,但是它本身是尚未过期的,所以需要用到这个参数。")])])]),e("li",null,[e("p",null,"你最终应该看到跟上面很像的提示:"),e("div",{class:"language-log ext-log line-numbers-mode"},[e("pre",{class:"language-log"},[e("code",null,[c("vpsadmin"),e("span",{class:"token operator"},"@"),c("vps"),e("span",{class:"token operator"},"-"),c("server"),e("span",{class:"token operator"},":"),e("span",{class:"token operator"},"~"),e("span",{class:"token operator"},"$"),c(),e("span",{class:"token domain constant"},"acme.sh"),c(),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("issue "),e("span",{class:"token operator"},"-"),c("d 二级域名"),e("span",{class:"token punctuation"},"."),c("你的域名"),e("span",{class:"token punctuation"},"."),c("com "),e("span",{class:"token operator"},"-"),c("w "),e("span",{class:"token file-path string"},"/home/vpsadmin/www/webpage"),c(),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("keylength ec"),e("span",{class:"token operator"},"-"),e("span",{class:"token number"},"256"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Using CA:"),c(),e("span",{class:"token url"},"https://acme-v02.api.letsencrypt.org/directory"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Creating domain key\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"The domain key is here:"),c(),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Single domain"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Getting domain auth token for each domain\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Getting webroot for domain"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Verifying:"),c(" 二级域名"),e("span",{class:"token punctuation"},"."),c("你的域名"),e("span",{class:"token punctuation"},"."),c("com\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Pending\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Success\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Verify finished"),e("span",{class:"token punctuation"},","),c(" start to sign"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Lets finalize the order"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Le_OrderFinalize"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'https://acme-v02.api.letsencrypt.org/acme/finalize/490205996/7730242872'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Downloading cert"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Le_LinkCert"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'https://acme-v02.api.letsencrypt.org/acme/cert/vsxvk0oldnuobe51ayxz4dms62sk2dwmw9zhuw'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Cert success"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("BEGIN CERTIFICAT"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("\nsxlYqPvWreKgD5b8JyOQX0Yg2MLoRUoDyqVkd31PthIiwzdckoh5eD3JU7ysYBtN\ncTFK4LGOfjqi8Ks87EVJdK9IaSAu7ZC6h5to0eqpJ5PLhaM3e6yJBbHmYA8w1Smp\nwAb3tdoHZ9ttUIm9CrSzvDBt6BBT6GqYdDamMyCYBLooMyDEM4CUFsOzCRrEqqvC\n2mTTEmhvpojo5rhdTSJxibozyNWTGwoTj0v9pTUeQcGqLIzqi4DowjBHD5guwRid\nSjAFnm6JT2xUQgWFm58A1gv1OhbH1TRPUUmtE1nFEN7YiSjI4xgxqAXT3CLD2EUb\nwXlUrO6c75zSsQP4bRMzgOjJUqHtSb6IEqELzt4M7KzL5iCOruCChCo2DZxUwvVX\ntOoaAyQJzCbTqE6aUqwiKi3gVyoxvDP9mI5JdRYzsDL6GVud7EHPnYeMl9ubLZAK\n0vg84mbMP3f6mYM4KRa1cqiyOIcQPT4AzGFYVv4sm049bZQg7sd0Bz9CaFvE7yDA\n1y17XlgCDnsjxl66bqI1vkENN9XT5xeFHONqc18b5fZEKSIvdX7iWPFWp1PyMPpG\n0pMCP1EymZNFxIMJLgbWqExwLWfPc5Ib3PjBaIqhXPnw6sT2MQSxXwDupq1UJVhV\n7E3hQRVlwI4CXi6WLHJMNvNRyyK87gCrLH1bKYsPeRVaz77poWBq49zwBCts6hPY\nIeF4ltGXyANNIOPEi8vy138fRU4LYh81d8FjOtFfJZogMjwhfNvapqxPMsioPlmX\nTnZu0n7setrVNUEfTMHWqPpDgk5MPrWLA4LapqaDfEX4pwnQJLMwMi6s94z165c0\niMRSKA1yU5zqv8aNsDfPoY4OkSPWs4MaXgRRSLBsUfZ15DwQXPk76kegHIyxWvwF\ntYw9HKR5QCMK66fa0z4aJoFVFLK0IIOGEZOanRFUCnkLUDd3QZ3YU8lEcrj7Uxos\nhaiRNICyC6UfsCJ94a8vcNyMosPv3xBLMp19WXgiFYqEFQkntkv1FLRI35fjeJmg\n0fmD9VG9bkzGPHihJgQLRlCHasGf6XrdfkSsODAyCUHUHJ0RzqF4YEZMcxDxzuQ2\nYO7bFwj7S3mUdVPZ6MPasjxdyBjJgEBMch2uy4AhmudXfEBQBye8W6ZI4ztZjLVV\nFmP4SIuaNUmMe20TjR8b9NVC96AhxOanWT3mRROsdokpKQGTJvl27EHH8KuAbUOc\nG6KtPy4wslNZNXWcBy9n63RcWak12r7kAIFn38tZxmlw2WUKoRSMAH64GcDTjRQd\nAm65hBHzvGrj93wEuVNIebvNIsJOlng3HFjpIxVqKGMCIfWIKGDE3YzK3p4LbGZ6\nNZFQWYJLNVf2M9CCJfbEImPYgvctrxl39H6KVYPCw1SAdaj9NneUqmREOQkKoEB0\nx6PmNirbMscHhQPSC0JQaqUgaQFgba1ALmzRYAnYhNb0twkTxWbY7DBkAarxqMIp\nyiLKcBFc5H7dgJCImo7us7aJeftC44uWkPM"),e("span",{class:"token operator"},"="),c("\n"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("END CERTIFICAT"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Your cert is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.cer"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Your cert key is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" The intermediate CA cert is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/ca.cer"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"And the full chain certs is there:"),c(" "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/fullchain.cer"),c("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br"),e("span",{class:"line-number"},"34"),e("br"),e("span",{class:"line-number"},"35"),e("br"),e("span",{class:"line-number"},"36"),e("br"),e("span",{class:"line-number"},"37"),e("br"),e("span",{class:"line-number"},"38"),e("br"),e("span",{class:"line-number"},"39"),e("br"),e("span",{class:"line-number"},"40"),e("br"),e("span",{class:"line-number"},"41"),e("br"),e("span",{class:"line-number"},"42"),e("br"),e("span",{class:"line-number"},"43"),e("br"),e("span",{class:"line-number"},"44"),e("br"),e("span",{class:"line-number"},"45"),e("br"),e("span",{class:"line-number"},"46"),e("br")])])]),e("li",null,[e("p",null,[c("仔细观察,你会发现这次给你发证书的域名是 "),e("code",null,"https://acme-v02.api.letsencrypt.org"),c(",少了 "),e("code",null,"staging"),c(",自然就是【正式服】了!")])])],-1),f=e("h2",{id:"_6-5-证书安装",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-5-证书安装","aria-hidden":"true"},"#"),c(" 6.5 证书安装")],-1),C=e("ol",null,[e("li",null,[e("p",null,"证书申请完成后,需要安装,安装到指定位置,并在配置文件中引用即可:"),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[c("vpsadmin@vps-server:~$ acme.sh --installcert -d 二级域名.你的域名.com --cert-file /你要安装到的位置/cert.crt --key-file /你要安装到的位置/cert.key --fullchain-file /你要安装到的位置/fullchain.crt --ecc\n"),e("span",{class:"token punctuation"},"["),c("Mon "),e("span",{class:"token number"},"14"),c(" Feb "),e("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),e("span",{class:"token punctuation"},"]"),c(" Installing cert to: /etc/xray/cert/cert.crt\n"),e("span",{class:"token punctuation"},"["),c("Mon "),e("span",{class:"token number"},"14"),c(" Feb "),e("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),e("span",{class:"token punctuation"},"]"),c(" Installing key to: /etc/xray/cert/cert.key\n"),e("span",{class:"token punctuation"},"["),c("Mon "),e("span",{class:"token number"},"14"),c(" Feb "),e("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),e("span",{class:"token punctuation"},"]"),c(" Installing full chain to: /etc/xray/cert/fullchain.crt\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br")])])])],-1),D=e("h2",{id:"_6-6-你的进度",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-6-你的进度","aria-hidden":"true"},"#"),c(" 6.6 你的进度")],-1),S=e("p",null,"至此,Xray 所需要的两个基础设施终于全部就位!千呼万唤始出来的 Xray 马上就要揭开面纱,我们终于要进入最激动人心章节啦!",-1),x=e("blockquote",null,[e("p",null,"⬛⬛⬛⬛⬛⬛⬜⬜ 75%")],-1);o.render=function(c,o){const W=n("OutboundLink");return s(),a(l,null,[p,r,u,i,e("p",null,[m,e("a",b,[k,t(W)]),d]),h,g,y,E,M,T,v,A,f,C,D,S,x],64)};export default o; +import{r as n,o as s,c as a,a as e,b as t,F as l,e as c}from"./app.48111a85.js";const o={},p=e("h1",{id:"【第-6-章】证书管理篇",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#【第-6-章】证书管理篇","aria-hidden":"true"},"#"),c(" 【第 6 章】证书管理篇")],-1),r=e("h2",{id:"_6-1-申请-tls-证书",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-1-申请-tls-证书","aria-hidden":"true"},"#"),c(" 6.1 申请 TLS 证书")],-1),u=e("p",null,"接下来我们要做的,是为我们的域名申请一个真实的 TLS 证书,使网站具备标准 TLS 加密的能力及 HTTPS 访问的能力。这就是 Xray 等现阶段安全代理工具确保流量充分加密最重要的工具。",-1),i=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,"请不要轻易使用自签证书。它并没有让操作简单太多,但增加了无谓的风险(如中间人攻击)。")],-1),m=c("这里我会使用一个叫做 "),b={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},k=e("code",null,"acme.sh",-1),d=c(" 的证书管理工具,它简单、轻量、高效,并可完成证书自动更新。"),h=e("p",null,"另外,我相信,现在你已经逐渐熟悉了 Linux 的基础操作,所以已经多次出现的命令从本章开始不再重复截图、只做简单的描述。如果实在想不起来怎么用的话,就稍微复习一下前面的章节吧。",-1),g=e("h2",{id:"_6-2-安装-acme-sh",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-2-安装-acme-sh","aria-hidden":"true"},"#"),c(" 6.2 安装 "),e("code",null,"acme.sh")],-1),y=e("ol",null,[e("li",null,[e("p",null,"小小白白 Linux 基础命令:"),e("table",null,[e("thead",null,[e("tr",null,[e("th",{style:{"text-align":"center"}},"编号"),e("th",{style:{"text-align":"center"}},"命令名称"),e("th",{style:{"text-align":"center"}},"命令说明")])]),e("tbody",null,[e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"cmd-12")]),e("td",{style:{"text-align":"center"}},[e("code",null,"wget")]),e("td",{style:{"text-align":"center"}},"访问(或下载)某个网页文件")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"cmd-13")]),e("td",{style:{"text-align":"center"}},[e("code",null,"acme.sh")]),e("td",{style:{"text-align":"center"}},"acme.sh 证书管理相关的命令")])])])]),e("li",null,[e("p",null,"运行安装脚本"),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"wget"),c(" -O - https://get.acme.sh "),e("span",{class:"token operator"},"|"),c(),e("span",{class:"token function"},"sh"),c("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,[c("让 "),e("code",null,"acme.sh"),c(" 命令生效")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token builtin class-name"},"."),c(" .bashrc\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,[c("开启 "),e("code",null,"acme.sh"),c(" 的自动升级")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,"acme.sh --upgrade --auto-upgrade\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])])]),e("li",null,[e("p",null,"到这一步的完整流程如下图:"),e("p",null,[e("img",{src:"/Xray-docs-next/assets/ch06-img01-acme-install.809938be.gif",alt:"acme.sh安装演示"})])])],-1),E=e("h2",{id:"_6-3-测试证书申请",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-3-测试证书申请","aria-hidden":"true"},"#"),c(" 6.3 测试证书申请")],-1),M=e("p",null,[c("在正式申请证书之前,我们先用测试命令("),e("code",null,"--issue --test"),c(")来验证是否可以成功申请,这样可以避免在本地配置有误时,反复申请证书失败,超过 Let's Encrypt 的频率上限(比如,每小时、每个域名、每个用户失败最多 5 次),导致后面的步骤无法进行。")],-1),T=e("ol",null,[e("li",null,[e("p",null,[c("测试证书申请的命令如下(本文均以 "),e("code",null,"ECC"),c(" 证书为例,因为时至今日,实在没什么理由不用它):")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,"acme.sh --issue --server letsencrypt --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])]),e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"说明"),e("p",null,[e("code",null,"ECC"),c("证书的主要优势在于它的 Keysize 更小,意味着同等大小下安全性的提升和加密解密速度的加快。如 ECC-256bit 的强度大约相当于 RSA-3072bit,何乐而不为呢?当然,有人说 ECC 证书握手会明显更快,这我觉得就有些夸张了,因为 RSA 握手也没有太慢,就算有差别应该也是毫秒级,很难直接感知。")]),e("p",null,[c("另外,如果有些网站确实需要兼容某些古老设备的,那也还是请按需选择"),e("code",null,"RSA"),c("证书。")])])]),e("li",null,[e("p",null,"你最终应该看到类似这样的提示:"),e("div",{class:"language-log ext-log line-numbers-mode"},[e("pre",{class:"language-log"},[e("code",null,[e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:12"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Using ACME_DIRECTORY:"),c(),e("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Using CA:"),c(),e("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Create account key ok"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Registering account:"),c(),e("span",{class:"token url"},"https://acme-staging-v02.api.letsencrypt.org/directory"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Registered\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" ACCOUNT_THUMBPRINT"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'CU6qmPKuRqhyTAIrF4swosR375194z_1ddUlWef8xDc'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Creating domain key\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"The domain key is here:"),c(),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Single domain"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:13"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Getting domain auth token for each domain\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:14"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Getting webroot for domain"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:14"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Verifying:"),c(" 二级域名"),e("span",{class:"token punctuation"},"."),c("你的域名"),e("span",{class:"token punctuation"},"."),c("com\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:23"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Pending\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Success\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Verify finished"),e("span",{class:"token punctuation"},","),c(" start to sign"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Lets finalize the order"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Le_OrderFinalize"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'https://acme-staging-v02.api.letsencrypt.org/acme/finalize/490205995/7730242871'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Downloading cert"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"04:25:25"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Le_LinkCert"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'https://acme-staging-v02.api.letsencrypt.org/acme/cert/xujss5xt8i38waubafz2xujss5xt8i38waubz2'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:21:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Cert success"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("BEGIN CERTIFICAT"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("\nsxlYqPvWreKgD5b8JyOQX0Yg2MLoRUoDyqVkd31PthIiwzdckoh5eD3JU7ysYBtN\ncTFK4LGOfjqi8Ks87EVJdK9IaSAu7ZC6h5to0eqpJ5PLhaM3e6yJBbHmYA8w1Smp\nwAb3tdoHZ9ttUIm9CrSzvDBt6BBT6GqYdDamMyCYBLooMyDEM4CUFsOzCRrEqqvC\n2mTTEmhvpojo5rhdTSJxibozyNWTGwoTj0v9pTUeQcGqLIzqi4DowjBHD5guwRid\nSjAFnm6JT2xUQgWFm58A1gv1OhbH1TRPUUmtE1nFEN7YiSjI4xgxqAXT3CLD2EUb\nwXlUrO6c75zSsQP4bRMzgOjJUqHtSb6IEqELzt4M7KzL5iCOruCChCo2DZxUwvVX\ntOoaAyQJzCbTqE6aUqwiKi3gVyoxvDP9mI5JdRYzsDL6GVud7EHPnYeMl9ubLZAK\n0vg84mbMP3f6mYM4KRa1cqiyOIcQPT4AzGFYVv4sm049bZQg7sd0Bz9CaFvE7yDA\n1y17XlgCDnsjxl66bqI1vkENN9XT5xeFHONqc18b5fZEKSIvdX7iWPFWp1PyMPpG\n0pMCP1EymZNFxIMJLgbWqExwLWfPc5Ib3PjBaIqhXPnw6sT2MQSxXwDupq1UJVhV\n7E3hQRVlwI4CXi6WLHJMNvNRyyK87gCrLH1bKYsPeRVaz77poWBq49zwBCts6hPY\nIeF4ltGXyANNIOPEi8vy138fRU4LYh81d8FjOtFfJZogMjwhfNvapqxPMsioPlmX\nTnZu0n7setrVNUEfTMHWqPpDgk5MPrWLA4LapqaDfEX4pwnQJLMwMi6s94z165c0\niMRSKA1yU5zqv8aNsDfPoY4OkSPWs4MaXgRRSLBsUfZ15DwQXPk76kegHIyxWvwF\ntYw9HKR5QCMK66fa0z4aJoFVFLK0IIOGEZOanRFUCnkLUDd3QZ3YU8lEcrj7Uxos\nhaiRNICyC6UfsCJ94a8vcNyMosPv3xBLMp19WXgiFYqEFQkntkv1FLRI35fjeJmg\n0fmD9VG9bkzGPHihJgQLRlCHasGf6XrdfkSsODAyCUHUHJ0RzqF4YEZMcxDxzuQ2\nYO7bFwj7S3mUdVPZ6MPasjxdyBjJgEBMch2uy4AhmudXfEBQBye8W6ZI4ztZjLVV\nFmP4SIuaNUmMe20TjR8b9NVC96AhxOanWT3mRROsdokpKQGTJvl27EHH8KuAbUOc\nG6KtPy4wslNZNXWcBy9n63RcWak12r7kAIFn38tZxmlw2WUKoRSMAH64GcDTjRQd\nAm65hBHzvGrj93wEuVNIebvNIsJOlng3HFjpIxVqKGMCIfWIKGDE3YzK3p4LbGZ6\nNZFQWYJLNVf2M9CCJfbEImPYgvctrxl39H6KVYPCw1SAdaj9NneUqmREOQkKoEB0\nx6PmNirbMscHhQPSC0JQaqUgaQFgba1ALmzRYAnYhNb0twkTxWbY7DBkAarxqMIp\nyiLKcBFc5H7dgJCImo7us7aJeftC44uWkPIjw9AKH"),e("span",{class:"token operator"},"="),c("\n"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("END CERTIFICAT"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:21:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Your cert is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.cer"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:21:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Your cert key is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:21:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" The intermediate CA cert is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/ca.cer"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:21:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"And the full chain certs is there:"),c(" "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/fullchain.cer"),c("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br"),e("span",{class:"line-number"},"34"),e("br"),e("span",{class:"line-number"},"35"),e("br"),e("span",{class:"line-number"},"36"),e("br"),e("span",{class:"line-number"},"37"),e("br"),e("span",{class:"line-number"},"38"),e("br"),e("span",{class:"line-number"},"39"),e("br"),e("span",{class:"line-number"},"40"),e("br"),e("span",{class:"line-number"},"41"),e("br"),e("span",{class:"line-number"},"42"),e("br"),e("span",{class:"line-number"},"43"),e("br"),e("span",{class:"line-number"},"44"),e("br"),e("span",{class:"line-number"},"45"),e("br"),e("span",{class:"line-number"},"46"),e("br"),e("span",{class:"line-number"},"47"),e("br"),e("span",{class:"line-number"},"48"),e("br"),e("span",{class:"line-number"},"49"),e("br"),e("span",{class:"line-number"},"50"),e("br")])])]),e("li",null,[e("p",null,[c("注意:这里申请的是测试证书,没办法直接用的,只是用来证明你的域名、配置全都正确。仔细观察,你会发现给你发证书的域名是 "),e("code",null,"https://acme-staging-v02.api.letsencrypt.org"),c(",这个 "),e("code",null,"staging"),c(" 你就理解成【测试服】吧!")])]),e("li",null,[e("p",null,"如果这一步出错的话,你可以运行下面的命令,来查看详细的申请过程和具体的错误。(看不懂就隐藏掉敏感信息后,去 Xray 群里问吧)"),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,"acme.sh --issue --server letsencrypt --test -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256 --debug\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])]),e("p",null,[c("嗯没错,就是在命令的最后加了一个 "),e("code",null,"--debug"),c(" 参数")])]),e("li",null,[e("p",null,"这一步确定成功之后,就可以申请正式的证书了。(测试证书不需要删除,它会自动被正式证书覆盖)")])],-1),v=e("h2",{id:"_6-4-正式证书申请",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-4-正式证书申请","aria-hidden":"true"},"#"),c(" 6.4 正式证书申请")],-1),A=e("ol",null,[e("li",null,[e("p",null,[c("申请正式证书的命令如下(即删掉 "),e("code",null,"--test"),c(" 参数,并在最后加入 "),e("code",null,"--force"),c("参数):")]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,"acme.sh --set-default-ca --server letsencrypt\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])]),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,"acme.sh --issue -d 二级域名.你的域名.com -w /home/vpsadmin/www/webpage --keylength ec-256 --force\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])]),e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"说明"),e("p",null,[e("code",null,"--force"),c(" 参数的意思就是,在现有证书到期前,手动(强行)更新证书。上一步我们从“测试服”申请的证书虽然不能直接用,但是它本身是尚未过期的,所以需要用到这个参数。")])])]),e("li",null,[e("p",null,"你最终应该看到跟上面很像的提示:"),e("div",{class:"language-log ext-log line-numbers-mode"},[e("pre",{class:"language-log"},[e("code",null,[c("vpsadmin"),e("span",{class:"token operator"},"@"),c("vps"),e("span",{class:"token operator"},"-"),c("server"),e("span",{class:"token operator"},":"),e("span",{class:"token operator"},"~"),e("span",{class:"token operator"},"$"),c(),e("span",{class:"token domain constant"},"acme.sh"),c(),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("issue "),e("span",{class:"token operator"},"-"),c("d 二级域名"),e("span",{class:"token punctuation"},"."),c("你的域名"),e("span",{class:"token punctuation"},"."),c("com "),e("span",{class:"token operator"},"-"),c("w "),e("span",{class:"token file-path string"},"/home/vpsadmin/www/webpage"),c(),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("keylength ec"),e("span",{class:"token operator"},"-"),e("span",{class:"token number"},"256"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Using CA:"),c(),e("span",{class:"token url"},"https://acme-v02.api.letsencrypt.org/directory"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Creating domain key\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"The domain key is here:"),c(),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Single domain"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Getting domain auth token for each domain\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Getting webroot for domain"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'二级域名.你的域名.com'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"Verifying:"),c(" 二级域名"),e("span",{class:"token punctuation"},"."),c("你的域名"),e("span",{class:"token punctuation"},"."),c("com\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Pending\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Success\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Verify finished"),e("span",{class:"token punctuation"},","),c(" start to sign"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Lets finalize the order"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Le_OrderFinalize"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'https://acme-v02.api.letsencrypt.org/acme/finalize/490205996/7730242872'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Downloading cert"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Le_LinkCert"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},"'https://acme-v02.api.letsencrypt.org/acme/cert/vsxvk0oldnuobe51ayxz4dms62sk2dwmw9zhuw'"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:51"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Cert success"),e("span",{class:"token punctuation"},"."),c("\n"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("BEGIN CERTIFICAT"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("\nsxlYqPvWreKgD5b8JyOQX0Yg2MLoRUoDyqVkd31PthIiwzdckoh5eD3JU7ysYBtN\ncTFK4LGOfjqi8Ks87EVJdK9IaSAu7ZC6h5to0eqpJ5PLhaM3e6yJBbHmYA8w1Smp\nwAb3tdoHZ9ttUIm9CrSzvDBt6BBT6GqYdDamMyCYBLooMyDEM4CUFsOzCRrEqqvC\n2mTTEmhvpojo5rhdTSJxibozyNWTGwoTj0v9pTUeQcGqLIzqi4DowjBHD5guwRid\nSjAFnm6JT2xUQgWFm58A1gv1OhbH1TRPUUmtE1nFEN7YiSjI4xgxqAXT3CLD2EUb\nwXlUrO6c75zSsQP4bRMzgOjJUqHtSb6IEqELzt4M7KzL5iCOruCChCo2DZxUwvVX\ntOoaAyQJzCbTqE6aUqwiKi3gVyoxvDP9mI5JdRYzsDL6GVud7EHPnYeMl9ubLZAK\n0vg84mbMP3f6mYM4KRa1cqiyOIcQPT4AzGFYVv4sm049bZQg7sd0Bz9CaFvE7yDA\n1y17XlgCDnsjxl66bqI1vkENN9XT5xeFHONqc18b5fZEKSIvdX7iWPFWp1PyMPpG\n0pMCP1EymZNFxIMJLgbWqExwLWfPc5Ib3PjBaIqhXPnw6sT2MQSxXwDupq1UJVhV\n7E3hQRVlwI4CXi6WLHJMNvNRyyK87gCrLH1bKYsPeRVaz77poWBq49zwBCts6hPY\nIeF4ltGXyANNIOPEi8vy138fRU4LYh81d8FjOtFfJZogMjwhfNvapqxPMsioPlmX\nTnZu0n7setrVNUEfTMHWqPpDgk5MPrWLA4LapqaDfEX4pwnQJLMwMi6s94z165c0\niMRSKA1yU5zqv8aNsDfPoY4OkSPWs4MaXgRRSLBsUfZ15DwQXPk76kegHIyxWvwF\ntYw9HKR5QCMK66fa0z4aJoFVFLK0IIOGEZOanRFUCnkLUDd3QZ3YU8lEcrj7Uxos\nhaiRNICyC6UfsCJ94a8vcNyMosPv3xBLMp19WXgiFYqEFQkntkv1FLRI35fjeJmg\n0fmD9VG9bkzGPHihJgQLRlCHasGf6XrdfkSsODAyCUHUHJ0RzqF4YEZMcxDxzuQ2\nYO7bFwj7S3mUdVPZ6MPasjxdyBjJgEBMch2uy4AhmudXfEBQBye8W6ZI4ztZjLVV\nFmP4SIuaNUmMe20TjR8b9NVC96AhxOanWT3mRROsdokpKQGTJvl27EHH8KuAbUOc\nG6KtPy4wslNZNXWcBy9n63RcWak12r7kAIFn38tZxmlw2WUKoRSMAH64GcDTjRQd\nAm65hBHzvGrj93wEuVNIebvNIsJOlng3HFjpIxVqKGMCIfWIKGDE3YzK3p4LbGZ6\nNZFQWYJLNVf2M9CCJfbEImPYgvctrxl39H6KVYPCw1SAdaj9NneUqmREOQkKoEB0\nx6PmNirbMscHhQPSC0JQaqUgaQFgba1ALmzRYAnYhNb0twkTxWbY7DBkAarxqMIp\nyiLKcBFc5H7dgJCImo7us7aJeftC44uWkPM"),e("span",{class:"token operator"},"="),c("\n"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("END CERTIFICAT"),e("span",{class:"token operator"},"-"),e("span",{class:"token operator"},"-"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Your cert is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.cer"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" Your cert key is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/二级域名.你的域名.com.key"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(" The intermediate CA cert is in "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/ca.cer"),c("\n"),e("span",{class:"token punctuation"},"["),e("span",{class:"token date number"},"Wed 30"),c(" Dec "),e("span",{class:"token number"},"2022"),c(),e("span",{class:"token time number"},"15:22:52"),c(" AM EST"),e("span",{class:"token punctuation"},"]"),c(),e("span",{class:"token property"},"And the full chain certs is there:"),c(" "),e("span",{class:"token file-path string"},"/home/vpsadmin/.acme.sh/二级域名.你的域名.com_ecc/fullchain.cer"),c("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br"),e("span",{class:"line-number"},"34"),e("br"),e("span",{class:"line-number"},"35"),e("br"),e("span",{class:"line-number"},"36"),e("br"),e("span",{class:"line-number"},"37"),e("br"),e("span",{class:"line-number"},"38"),e("br"),e("span",{class:"line-number"},"39"),e("br"),e("span",{class:"line-number"},"40"),e("br"),e("span",{class:"line-number"},"41"),e("br"),e("span",{class:"line-number"},"42"),e("br"),e("span",{class:"line-number"},"43"),e("br"),e("span",{class:"line-number"},"44"),e("br"),e("span",{class:"line-number"},"45"),e("br"),e("span",{class:"line-number"},"46"),e("br")])])]),e("li",null,[e("p",null,[c("仔细观察,你会发现这次给你发证书的域名是 "),e("code",null,"https://acme-v02.api.letsencrypt.org"),c(",少了 "),e("code",null,"staging"),c(",自然就是【正式服】了!")])])],-1),f=e("h2",{id:"_6-5-证书安装",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-5-证书安装","aria-hidden":"true"},"#"),c(" 6.5 证书安装")],-1),C=e("ol",null,[e("li",null,[e("p",null,"证书申请完成后,需要安装,安装到指定位置,并在配置文件中引用即可:"),e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[c("vpsadmin@vps-server:~$ acme.sh --installcert -d 二级域名.你的域名.com --cert-file /你要安装到的位置/cert.crt --key-file /你要安装到的位置/cert.key --fullchain-file /你要安装到的位置/fullchain.crt --ecc\n"),e("span",{class:"token punctuation"},"["),c("Mon "),e("span",{class:"token number"},"14"),c(" Feb "),e("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),e("span",{class:"token punctuation"},"]"),c(" Installing cert to: /etc/xray/cert/cert.crt\n"),e("span",{class:"token punctuation"},"["),c("Mon "),e("span",{class:"token number"},"14"),c(" Feb "),e("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),e("span",{class:"token punctuation"},"]"),c(" Installing key to: /etc/xray/cert/cert.key\n"),e("span",{class:"token punctuation"},"["),c("Mon "),e("span",{class:"token number"},"14"),c(" Feb "),e("span",{class:"token number"},"2022"),c(" 03:00:25 PM CST"),e("span",{class:"token punctuation"},"]"),c(" Installing full chain to: /etc/xray/cert/fullchain.crt\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br")])])])],-1),D=e("h2",{id:"_6-6-你的进度",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_6-6-你的进度","aria-hidden":"true"},"#"),c(" 6.6 你的进度")],-1),S=e("p",null,"至此,Xray 所需要的两个基础设施终于全部就位!千呼万唤始出来的 Xray 马上就要揭开面纱,我们终于要进入最激动人心章节啦!",-1),x=e("blockquote",null,[e("p",null,"⬛⬛⬛⬛⬛⬛⬜⬜ 75%")],-1);o.render=function(c,o){const W=n("OutboundLink");return s(),a(l,null,[p,r,u,i,e("p",null,[m,e("a",b,[k,t(W)]),d]),h,g,y,E,M,T,v,A,f,C,D,S,x],64)};export default o; diff --git a/assets/ch07-xray-server.html.a3da7220.js b/assets/ch07-xray-server.html.a49f5a08.js similarity index 99% rename from assets/ch07-xray-server.html.a3da7220.js rename to assets/ch07-xray-server.html.a49f5a08.js index 3172ce711..3e8b3f620 100644 --- a/assets/ch07-xray-server.html.a3da7220.js +++ b/assets/ch07-xray-server.html.a49f5a08.js @@ -1 +1 @@ -import{r as n,o as s,c as l,a,b as e,w as t,F as c,e as o,d as r}from"./app.755d843f.js";const u={},p=a("h1",{id:"【第-7-章】xray-服务器篇",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#【第-7-章】xray-服务器篇","aria-hidden":"true"},"#"),o(" 【第 7 章】Xray 服务器篇")],-1),i=a("h2",{id:"_7-1-博观而约取-厚积而薄发",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-1-博观而约取-厚积而薄发","aria-hidden":"true"},"#"),o(" 7.1 博观而约取,厚积而薄发")],-1),b=a("p",null,"本文撰写过程中,大佬开玩笑的吐槽到:你这教程,居然连载了 6 章都还没到 Xray,不知道的还以为你是“手把手教你建网站”教程呢。(我竟无法反驳.jpg!)",-1),d=a("p",null,[o("其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连"),a("code",null,"nano"),o("都无法正确使用,也不会用"),a("code",null,"WinSCP"),o(",远程手写编辑出来的"),a("code",null,"config.json"),o("自然错误百出,连查错也变得举步维艰。")],-1),m=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,"经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray 时会有一种【水到渠成】的轻快感觉。")],-1),g=a("p",null,"后面要做的事情非常简单:",-1),k=a("ol",null,[a("li",null,"安装"),a("li",null,[o("配置(如安装 TLS 证书、"),a("code",null,"config.json"),o(")")]),a("li",null,"运行"),a("li",null,[o("优化(如更新内核、开启"),a("code",null,"bbr"),o("、网站"),a("code",null,"http"),o("访问自动跳转"),a("code",null,"https"),o("等)")])],-1),h=a("h2",{id:"_7-2-安装-xray",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-2-安装-xray","aria-hidden":"true"},"#"),o(" 7.2 安装 Xray")],-1),y=o("首先,Xray 的官方载体,就是 "),x={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},v=o("xray-core"),f=o(" 开源项目(基于 "),_=a("code",null,"MPL 2.0",-1),X=o(" 开源协议)生成的二进制程序。你把这个二进制放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。主要区别来源于【配置】。"),B=o("安装时,直接使用官方安装脚本就很简单直接。它提供了多种安装选项,有兴趣的可以去官方的"),w={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},S=o("安装脚本仓库"),L=o("中看看脚本的说明,"),R=a("strong",null,"本文使用的是【非 root 用户】安装模式",-1),q=o("。"),T=a("p",null,"写本文时,安装脚本在使用非 root 账户时有一些小 bug,所以我决定正好把这几步分开操作,可以顺便说明一下 Linux 下的删除命令。",-1),D=a("ol",null,[a("li",null,[a("p",null,"小小白白 Linux 基础命令:"),a("table",null,[a("thead",null,[a("tr",null,[a("th",{style:{"text-align":"center"}},"编号"),a("th",{style:{"text-align":"center"}},"命令名称"),a("th",{style:{"text-align":"center"}},"命令说明")])]),a("tbody",null,[a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-14")]),a("td",{style:{"text-align":"center"}},[a("code",null,"rm")]),a("td",{style:{"text-align":"center"}},"删除命令")])])])]),a("li",null,[a("p",null,"将安装脚本下载至本地:"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"wget"),o(" https://github.com/XTLS/Xray-install/raw/main/install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"执行安装命令"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"bash"),o(" install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"使用完成之后可以删除该脚本"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"rm"),o(" ~/install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,[o("使用 "),a("code",null,"rm"),o(" 命令删除文件的时候,默认其实就是删除现在所在的文件夹下的文件。但是,"),a("strong",null,"我依然写了完整的路径"),o(": "),a("code",null,"~/install-release.sh"),o(",这是我使用 "),a("code",null,"rm"),o(" 时的一个安全习惯、也是我把安装分成几步之后想强调一下的内容。如果你听过一些“程序员从删库到跑路”之类的段子,大概就知道为什么了。")])])]),a("li",null,[a("p",null,"完整流程演示如下:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img01-xray-install.39750018.gif",alt:"Xray服务器端安装流程演示"})])])],-1),P=a("h2",{id:"_7-3-给-xray-配置-tls-证书",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-3-给-xray-配置-tls-证书","aria-hidden":"true"},"#"),o(" 7.3 给 Xray 配置 TLS 证书")],-1),E=o("虽然我们前面已经申请好了 TLS 证书,但是按照 "),j={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"},N=a("code",null,"acme.sh",-1),I=o("的官方说明"),U=o(",申请后的证书不建议直接使用。正确的方法是使用 "),V=a("code",null,"--install-cert",-1),F=o(" 命令安装给需要的程序。我们现在就来把证书安装给 "),A=a("code",null,"xray-core",-1),C=o(" 使用。"),H=a("li",null,[a("p",null,"为了规避非 root 账户的各种潜在的权限困扰,我们在 vpsadmin 账户下建立一个证书文件夹"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"mkdir"),o(" ~/xray_cert\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),K=a("li",null,[a("p",null,[o("使用"),a("code",null,"acme.sh"),o("的"),a("code",null,"--install-cert"),o("正确安装(拷贝)证书文件")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("acme.sh --install-cert -d 二级域名.你的域名.com --ecc "),a("span",{class:"token punctuation"},"\\"),o("\n --fullchain-file ~/xray_cert/xray.crt "),a("span",{class:"token punctuation"},"\\"),o("\n --key-file ~/xray_cert/xray.key\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br")])])],-1),M=a("li",null,[a("p",null,[a("code",null,"xray.key"),o("文件默认对其他用户不可读,所以需要赋予其可读性权限")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"chmod"),o(" +r ~/xray_cert/xray.key\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),$=a("li",null,[a("p",null,"过程比较简单就不放动图了:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img02-xray-cert-install.4136686d.png",alt:"Xray服务器端安装流程演示"})])],-1),G=r('

acme.sh 会每 60 天检查一次证书并自动更新临期证书。但据我所知是它并不会自动将新证书安装给 xray-core,所以我们需要新增一个系统的自动周期任务来完成这一步。

  1. 小小白白 Linux 基础命令:
编号命令名称命令说明
cmd-15crontab -e编辑当前用户的定时任务
',3),O={start:"2"},W=a("li",null,[a("p",null,[o("建立一个脚本文件("),a("code",null,"xray-cert-renew.sh"),o(")")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"nano"),o(" ~/xray_cert/xray-cert-renew.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),z=r('

把下面的内容复制进去,记得替换你的真实域名,然后保存退出

#!/bin/bash\n\n/home/vpsadmin/.acme.sh/acme.sh --install-cert -d a-name.yourdomain.com --ecc --fullchain-file /home/vpsadmin/xray_cert/xray.crt --key-file /home/vpsadmin/xray_cert/xray.key\necho "Xray Certificates Renewed"\n\nchmod +r /home/vpsadmin/xray_cert/xray.key\necho "Read Permission Granted for Private Key"\n\nsudo systemctl restart xray\necho "Xray Restarted"\n
1
2
3
4
5
6
7
8
9
10
',2),J={class:"custom-container warning"},Q=a("p",{class:"custom-container-title"},"注意",-1),Y=r("经大家提醒,acme.sh 有一个 reloadcmd 命令,可以在证书更新时自动执行特定命令,那么就可以指定自动给 Xray 安装证书,但因为 crontab 是 Linux 系统中一个非常有用、非常常用的功能,所以本文保留 crontab 的方式来更新 Xray 证书。(对 reloadcmd 感兴趣的同学可以查看 acme.sh 的",17),Z={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},nn=o("官方文档"),sn=o(")"),ln=a("p",null,[o("另外,录制动图时,脚本中没有加入重启 "),a("code",null,"Xray"),o(" 的命令,是因为 "),a("code",null,"Xray"),o(" 计划支持【证书热更新】功能,即 "),a("code",null,"Xray"),o(" 会自动识别证书更新并重载证书、无需手动重启。待功能加入后,我将适当修改 "),a("code",null,"config.json"),o(" 开启此设置,并删除脚本中的重启命令。")],-1),an=a("li",null,[a("p",null,"给这个文件增加【可执行】权限"),a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"chmod +x ~/xray_cert/xray-cert-renew.sh\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),en=a("li",null,[a("p",null,[o("运行 "),a("code",null,"crontab -e"),o(",添加一个自动任务【每月自动运行一次"),a("code",null,"xray-cert-renew.sh"),o("】 (注意不要加"),a("code",null,"sudo"),o(",因为我们增加的是"),a("code",null,"vpsadmin"),o(" 账户的自动任务。初次运行时会让你选择编辑器,当然是选择熟悉的"),a("code",null,"nano"),o("啦!)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"crontab"),o(" -e\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),tn=a("li",null,[a("p",null,"把下面的内容增加在文件最后,保存退出即可。"),a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"# 1:00am, 1st day each month, run `xray-cert-renew.sh`\n0 1 1 * * bash /home/vpsadmin/xray_cert/xray-cert-renew.sh\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])])],-1),cn=a("li",null,[a("p",null,"完整流程演示如下:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img03-crontab-cert-renew.ce7049d5.gif",alt:"每月自动给Xray安装证书"})])],-1),on=a("h2",{id:"_7-4-配置-xray",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-4-配置-xray","aria-hidden":"true"},"#"),o(" 7.4 配置 Xray")],-1),rn=o("首先,各种配置都可以参考"),un={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},pn=o("官方 VLESS 配置示例"),bn=o("。本文会基于官方示例,配置一个最精简的方式:【单 "),dn=a("code",null,"VLESS",-1),mn=o(" 协议入站 + "),gn=a("code",null,"80",-1),kn=o(" 端口回落】,满足大多数场景的最大速度及必要安全。"),hn=a("ol",null,[a("li",null,[a("p",null,[o("生成一个合法的 "),a("code",null,"UUID"),o(" 并保存备用("),a("code",null,"UUID"),o("可以简单粗暴的理解为像指纹一样几乎不会重复的 ID)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"xray uuid\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"建立日志文件及文件夹备用"),a("ol",null,[a("li",null,[a("p",null,"小小白白 Linux 基础命令:"),a("table",null,[a("thead",null,[a("tr",null,[a("th",{style:{"text-align":"center"}},"编号"),a("th",{style:{"text-align":"center"}},"命令名称"),a("th",{style:{"text-align":"center"}},"命令说明")])]),a("tbody",null,[a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-16")]),a("td",{style:{"text-align":"center"}},[a("code",null,"touch")]),a("td",{style:{"text-align":"center"}},"建立空白文件")])])])]),a("li",null,[a("p",null,[o("在"),a("code",null,"vpsadmin"),o("的文件夹内建立一个【日志专用文件夹】")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"mkdir"),o(" ~/xray_log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"生成所需的两个日志文件(访问日志、错误日志)"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"touch"),o(" ~/xray_log/access.log "),a("span",{class:"token operator"},"&&"),o(),a("span",{class:"token function"},"touch"),o(" ~/xray_log/error.log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,[o("这个位置不是"),a("code",null,"Xray"),o("标准的日志文件位置,放在这里是避免权限问题对新人的操作带来困扰。当你熟悉之后,建议回归默认位置: "),a("code",null,"/var/log/xray/access.log"),o(" 和 "),a("code",null,"/var/log/xray/error.log"),o(" 。")])])]),a("li",null,[a("p",null,[o("因为 Xray 默认是 nobody 用户使用,所以我们需要让其他用户也有“写”的权限("),a("code",null,"*.log"),o(" 就是所有文件后缀是"),a("code",null,"log"),o("的文件,此时"),a("code",null,"CLI"),o("界面的效率优势就逐渐出现了)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"chmod"),o(" a+w ~/xray_log/*.log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])])])]),a("li",null,[a("p",null,[o("使用"),a("code",null,"nano"),o("创建"),a("code",null,"Xray"),o("的配置文件")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /usr/local/etc/xray/config.json\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,[o("将下面的文件全部复制进去,并将之前生成的"),a("code",null,"UUID"),o("填入第 61 行 "),a("code",null,'"id": "",'),o(" 之中。(填好之后的样子是 "),a("code",null,'"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid"'),o(" ),本文的这个配置文件中增加了我的各种啰嗦注解,以方便你理解每一个配置模块的功能是什么。")]),a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token comment"},"// REFERENCE:"),o("\n"),a("span",{class:"token comment"},"// https://github.com/XTLS/Xray-examples"),o("\n"),a("span",{class:"token comment"},"// https://xtls.github.io/config/"),o("\n"),a("span",{class:"token comment"},"// 常用的 config 文件,不论服务器端还是客户端,都有 5 个部分。外加小小白解读:"),o("\n"),a("span",{class:"token comment"},"// ┌─ 1*log 日志设置 - 日志写什么,写哪里(出错时有据可查)"),o("\n"),a("span",{class:"token comment"},"// ├─ 2_dns DNS-设置 - DNS 怎么查(防 DNS 污染、防偷窥、避免国内外站匹配到国外服务器等)"),o("\n"),a("span",{class:"token comment"},"// ├─ 3_routing 分流设置 - 流量怎么分类处理(是否过滤广告、是否国内外分流)"),o("\n"),a("span",{class:"token comment"},"// ├─ 4_inbounds 入站设置 - 什么流量可以流入 Xray"),o("\n"),a("span",{class:"token comment"},"// └─ 5_outbounds 出站设置 - 流出 Xray 的流量往哪里去"),o("\n"),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token comment"},"// 1\\_日志设置"),o("\n "),a("span",{class:"token property"},'"log"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"loglevel"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"warning"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},'// 内容从少到多: "none", "error", "warning", "info", "debug"'),o("\n "),a("span",{class:"token property"},'"access"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_log/access.log"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 访问记录"),o("\n "),a("span",{class:"token property"},'"error"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_log/error.log"'),o(),a("span",{class:"token comment"},"// 错误记录"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 2_DNS 设置"),o("\n "),a("span",{class:"token property"},'"dns"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"servers"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"https+local://1.1.1.1/dns-query"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 首选 1.1.1.1 的 DoH 查询,牺牲速度但可防止 ISP 偷窥"),o("\n "),a("span",{class:"token string"},'"localhost"'),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 3*分流设置"),o("\n "),a("span",{class:"token property"},'"routing"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"domainStrategy"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"IPIfNonMatch"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"rules"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token comment"},"// 3.1 防止服务器本地流转问题:如内网被攻击或滥用、错误的本地回环等"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"ip"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"geoip:private"'),o(),a("span",{class:"token comment"},'// 分流条件:geoip 文件内,名为"private"的规则(本地)'),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o(),a("span",{class:"token comment"},'// 分流策略:交给出站"block"处理(黑洞屏蔽)'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token comment"},"// 3.2 防止服务器直连国内"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"ip"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),a("span",{class:"token string"},'"geoip:cn"'),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 3.3 屏蔽广告"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"domain"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"geosite:category-ads-all"'),o(),a("span",{class:"token comment"},'// 分流条件:geosite 文件内,名为"category-ads-all"的规则(各种广告域名)'),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o(),a("span",{class:"token comment"},'// 分流策略:交给出站"block"处理(黑洞屏蔽)'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 4*入站设置"),o("\n "),a("span",{class:"token comment"},"// 4.1 这里只写了一个最简单的 vless+xtls 的入站,因为这是 Xray 最强大的模式。如有其他需要,请根据模版自行添加。"),o("\n "),a("span",{class:"token property"},'"inbounds"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"443"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"vless"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"clients"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"id"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'""'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 填写你的 UUID"),o("\n "),a("span",{class:"token property"},'"flow"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"xtls-rprx-vision"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"level"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"0"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"email"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"vpsadmin@yourdomain.com"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"decryption"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"none"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"fallbacks"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"80"),o(),a("span",{class:"token comment"},"// 默认回落到防探测的代理"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"tcp"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"security"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"tls"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"tlsSettings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"alpn"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"http/1.1"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"certificates"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"certificateFile"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_cert/xray.crt"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"keyFile"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_cert/xray.key"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 5*出站设置"),o("\n "),a("span",{class:"token property"},'"outbounds"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token comment"},"// 5.1 第一个出站是默认规则,freedom 就是对外直连(vps 已经是外网,所以直连)"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"tag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"direct"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"freedom"'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 5.2 屏蔽规则,blackhole 协议就是把流量导入到黑洞里(屏蔽)"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"tag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"blackhole"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n"),a("span",{class:"token punctuation"},"}"),o("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br"),a("span",{class:"line-number"},"37"),a("br"),a("span",{class:"line-number"},"38"),a("br"),a("span",{class:"line-number"},"39"),a("br"),a("span",{class:"line-number"},"40"),a("br"),a("span",{class:"line-number"},"41"),a("br"),a("span",{class:"line-number"},"42"),a("br"),a("span",{class:"line-number"},"43"),a("br"),a("span",{class:"line-number"},"44"),a("br"),a("span",{class:"line-number"},"45"),a("br"),a("span",{class:"line-number"},"46"),a("br"),a("span",{class:"line-number"},"47"),a("br"),a("span",{class:"line-number"},"48"),a("br"),a("span",{class:"line-number"},"49"),a("br"),a("span",{class:"line-number"},"50"),a("br"),a("span",{class:"line-number"},"51"),a("br"),a("span",{class:"line-number"},"52"),a("br"),a("span",{class:"line-number"},"53"),a("br"),a("span",{class:"line-number"},"54"),a("br"),a("span",{class:"line-number"},"55"),a("br"),a("span",{class:"line-number"},"56"),a("br"),a("span",{class:"line-number"},"57"),a("br"),a("span",{class:"line-number"},"58"),a("br"),a("span",{class:"line-number"},"59"),a("br"),a("span",{class:"line-number"},"60"),a("br"),a("span",{class:"line-number"},"61"),a("br"),a("span",{class:"line-number"},"62"),a("br"),a("span",{class:"line-number"},"63"),a("br"),a("span",{class:"line-number"},"64"),a("br"),a("span",{class:"line-number"},"65"),a("br"),a("span",{class:"line-number"},"66"),a("br"),a("span",{class:"line-number"},"67"),a("br"),a("span",{class:"line-number"},"68"),a("br"),a("span",{class:"line-number"},"69"),a("br"),a("span",{class:"line-number"},"70"),a("br"),a("span",{class:"line-number"},"71"),a("br"),a("span",{class:"line-number"},"72"),a("br"),a("span",{class:"line-number"},"73"),a("br"),a("span",{class:"line-number"},"74"),a("br"),a("span",{class:"line-number"},"75"),a("br"),a("span",{class:"line-number"},"76"),a("br"),a("span",{class:"line-number"},"77"),a("br"),a("span",{class:"line-number"},"78"),a("br"),a("span",{class:"line-number"},"79"),a("br"),a("span",{class:"line-number"},"80"),a("br"),a("span",{class:"line-number"},"81"),a("br"),a("span",{class:"line-number"},"82"),a("br"),a("span",{class:"line-number"},"83"),a("br"),a("span",{class:"line-number"},"84"),a("br"),a("span",{class:"line-number"},"85"),a("br"),a("span",{class:"line-number"},"86"),a("br"),a("span",{class:"line-number"},"87"),a("br"),a("span",{class:"line-number"},"88"),a("br"),a("span",{class:"line-number"},"89"),a("br"),a("span",{class:"line-number"},"90"),a("br"),a("span",{class:"line-number"},"91"),a("br"),a("span",{class:"line-number"},"92"),a("br"),a("span",{class:"line-number"},"93"),a("br"),a("span",{class:"line-number"},"94"),a("br"),a("span",{class:"line-number"},"95"),a("br"),a("span",{class:"line-number"},"96"),a("br"),a("span",{class:"line-number"},"97"),a("br"),a("span",{class:"line-number"},"98"),a("br"),a("span",{class:"line-number"},"99"),a("br"),a("span",{class:"line-number"},"100"),a("br"),a("span",{class:"line-number"},"101"),a("br"),a("span",{class:"line-number"},"102"),a("br")])])])],-1),yn=a("ol",{start:"5"},[a("li",null,[o("完整流程演示如下: "),a("img",{src:"/Xray-docs-next/assets/ch07-img04-xray-log-and-config.1876d557.gif",alt:"创建日志文件及配置文件"})])],-1),xn=a("h2",{id:"_7-5-启动-xray-服务-并查看服务状态",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-5-启动-xray-服务-并查看服务状态","aria-hidden":"true"},"#"),o(" 7.5 启动 Xray 服务!!(并查看服务状态)")],-1),vn=a("p",null,[o("如果你是跟随本文一步步设置过来,其实就已经避开了最常见"),a("strong",null,"日志文件权限不足"),o("、"),a("strong",null,"证书文件权限不足"),o(" 这两个大坑。那么现在运行"),a("code",null,"Xray"),o("自然应该无比顺利。")],-1),fn=a("ol",null,[a("li",null,[o("输入下面的命令,享受启动"),a("code",null,"Xray"),o("的历史性时刻吧!!!")])],-1),_n=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl start xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Xn=a("ol",{start:"2"},[a("li",null,[o("仅仅"),a("code",null,"start"),o("我们并不能确定是否成功的开启了 Xray 的服务,要确定它的状态,就要用到下面的命令。")])],-1),Bn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl status xray\n\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])],-1),wn=a("p",null,[o("看到那个绿色的、令人愉悦的 "),a("code",null,"active (running)"),o(" 了吗?它就是说 "),a("code",null,"Xray"),o(" 已经在正确的运行了")],-1),Sn=a("ol",{start:"3"},[a("li",null,"完整流程演示如下:")],-1),Ln=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img05-xray-start-and-status.b77f6ab3.gif",alt:"启动并查看Xray运行状态"})],-1),Rn=a("h2",{id:"_7-6-回顾-systemd-进行基本的服务管理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-6-回顾-systemd-进行基本的服务管理","aria-hidden":"true"},"#"),o(" 7.6 回顾 "),a("code",null,"systemd"),o(" 进行基本的服务管理")],-1),qn=a("p",null,[o("到现在为止,我们已经使用过了"),a("code",null,"systemctl"),o("相关的"),a("code",null,"start"),o(", "),a("code",null,"status"),o(", "),a("code",null,"reload"),o(" 等命令,这些都是基于"),a("code",null,"systemd"),o("管理模块对 Linux 系统中各种服务进行管理的通用命令。现在正好熟悉一下相关的其他几个命令。")],-1),Tn=a("ol",null,[a("li",null,[o("若你需要暂时关闭 "),a("code",null,"Xray"),o(" 的服务,那就用"),a("code",null,"stop"),o("命令")])],-1),Dn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl stop xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Pn=a("ol",{start:"2"},[a("li",null,[o("若你需要重启"),a("code",null,"Xray"),o("的服务,那就用"),a("code",null,"restart"),o("命令")])],-1),En=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),jn=a("ol",{start:"3"},[a("li",null,[o("若你需要禁用"),a("code",null,"Xray"),o("的服务(电脑重启后禁止 Xray 自动运行),那就用"),a("code",null,"disable"),o("命令")])],-1),Nn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl disable xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),In=a("ol",{start:"4"},[a("li",null,[o("若你需要启用"),a("code",null,"Xray"),o("的服务(电脑重启后确保 Xray 自动运行),那就用"),a("code",null,"enable"),o("命令")])],-1),Un=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl "),a("span",{class:"token builtin class-name"},"enable"),o(" xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Vn=a("h2",{id:"_7-7-服务器优化之一-开启-bbr",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-7-服务器优化之一-开启-bbr","aria-hidden":"true"},"#"),o(" 7.7 服务器优化之一:开启 BBR")],-1),Fn=a("ol",null,[a("li",null,[o("传说中的"),a("code",null,"BBR")])],-1),An=a("p",null,[o("我相信,你在搜索各种科学上网技术的时候,肯定不止一次的听过"),a("code",null,"bbr"),o("这个东西,在各种博客添油加醋之下,让人觉得它神乎其神。更有"),a("code",null,"bbrplus"),o(", "),a("code",null,"bbr2"),o(", "),a("code",null,"魔改bbr"),o(" 等一大堆衍生品。仿佛神油一般,用了就能野鸡线路变专线。")],-1),Cn=a("p",null,"那么,这东西究竟是什么?它有没有用?又该用哪一个版本呢?",-1),Hn=a("ol",{start:"2"},[a("li",null,[o("实际的"),a("code",null,"BBR")])],-1),Kn=a("p",null,[a("strong",null,"BBR"),o(" = "),a("strong",null,"B"),o("ottleneck "),a("strong",null,"B"),o("andwidth and "),a("strong",null,"R"),o("ound-trip propagation time,是一种 TCP 的"),a("strong",null,"拥塞控制算法"),o("。简单粗暴的理解就是"),a("strong",null,"数据流量的交通管理"),o(" :当公路不再塞车的时候,每辆车自然就能保持较快的车速了。")],-1),Mn=a("p",null,[o("那么它有没有用呢?一般而言,"),a("code",null,"有BBR"),o(" 和 "),a("code",null,"没有BBR"),o(" 会有可以感知的差别(速度、稳定性、延迟方面都会有一些改善),所以 "),a("strong",null,[o("【非常建议开启 "),a("code",null,"BBR"),o("】")]),o("。")],-1),$n=a("p",null,[o("但开启之后,"),a("code",null,"BBR"),o(" 在 "),a("code",null,"4.x"),o(" 和 "),a("code",null,"5.x"),o(" 之间的差异往往比较微妙、见仁见智,造成体验差别的决定性因素仍然是线路质量。所以 "),a("strong",null,"【不必纠结版本、不必盲目追新、跟随你的发行版更新内核即可】")],-1),Gn=a("ol",{start:"3"},[a("li",null,[a("code",null,"bbrplus"),o(", "),a("code",null,"bbr2"),o(", "),a("code",null,"魔改bbr"),o(" 和其他各种听起来就酷炫的版本是不是更好?")])],-1),On=a("p",null,[o("一句话:"),a("strong",null,"不是!不要用这些!这些都为了吸引眼球乱起的名字!")],-1),Wn=a("p",null,[a("code",null,"BBR"),o(" 的更新和发布,都是跟随 Linux 的内核("),a("code",null,"Kernel"),o(")进行的。换言之,只要你用的是比较新的内核,就自然会使用到新版"),a("code",null,"BBR"),o("。")],-1),zn=a("p",null,[o("而这些名字看起来很酷炫的东西,说白了就是仍未正式发布的、尚在测试阶段的内核及其对应的"),a("code",null,"BBR"),o("版本。这些脚本也仅仅就是通过下载预览版的内核(甚至第三方魔改内核)来率先开启而已。")],-1),Jn=a("p",null,[o("内核的稳定是一台服务器稳定运行的基石。"),a("strong",null,"【BBR 测试版带来的细微性能差异绝对不值得更换不稳定的内核。】"),o(" 请选择你所在的 Linux 发行版所支持的最新内核,这样可以最大限度的保持服务器的长期稳定和兼容。")],-1),Qn=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,[o("所谓魔改"),a("code",null,"bbr"),o("的【领先】是有非常强的时效性的。比如很多 "),a("code",null,"bbrplus"),o(" 脚本,因为几年来都没有更新,到现在还会把你的内核换成 "),a("code",null,"4.19"),o(",要知道现在稳定如 Debian 已经是 "),a("code",null,"5.9"),o(" 的时代了,那么这个脚本放在 2018 年 1 月也许领先了一点,到 2018 年 10 月 4.19 正发布时就已经失去了意义,放在现在甚至可以说是完完全全的【降级】和【劣化】")])],-1),Yn=a("ol",{start:"4"},[a("li",null,[a("code",null,"fq"),o(", "),a("code",null,"fq_codel"),o(", "),a("code",null,"fq_pie"),o(", "),a("code",null,"cake"),o("和其他算法哪个好?")])],-1),Zn=a("p",null,[o("一句话:"),a("strong",null,[o("看不懂的话,请保持"),a("code",null,"fq"),o(",足够、且不会劣化你的线路")])],-1),ns=a("ol",{start:"5"},[a("li",null,"锐速、Finalspeed、LotServer 和其他“加速工具”")],-1),ss=a("p",null,[o("一句话:"),a("strong",null,"不要用这些!把他们丢进历史的垃圾桶吧!")],-1),ls=a("p",null,"它能解决的也只有丢包率的问题。不太准确的比喻,就是本来你用一辆车送你的货,有时候车半路就坏了(丢包),用了这些以后,你直接派出 3 份一样的货,让三辆车同时送,只要有一辆没坏就能送到。马路上都是你的车,自然就能把别人挤下去。但可想而知,你挤别人的时候,别人也会来挤你,而整个机房的出口道路一共就那么宽,最终势必就变成集体大堵车了。",-1),as=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("它们的原理不是算法优化、不是提速、大多数是简单粗暴的"),a("strong",null,"多倍发包"),o("。对于【丢包率非常高】的差线路可能有一点作用,但【对丢包率低的好线路没有任何优化作用,反而会成倍的消耗你的流量】,进而造成服务器和你的邻居不必要的压力。")]),a("p",null,"如果你的线路真的丢包率奇高,真正靠谱的解决方案是【换线路】。")],-1),es=a("ol",{start:"6"},[a("li",null,[a("p",null,[o("啰嗦了这么多,就是因为围绕 "),a("code",null,"BBR"),o(" 忽悠小白的错误概念和坑人脚本实在是太多了。我希望你们现在对 "),a("code",null,"BBR"),o(" 有了相对清晰的理解。接下来,我们就动手安装最新的 Debian 内核并开启"),a("code",null,"BBR"),o(" 吧!(真的很简单)")])]),a("li",null,[a("p",null,[o("给 Debian 10 添加官方 "),a("code",null,"backports"),o(" 源,获取更新的软件库")])])],-1),ts=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/apt/sources.list\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),cs=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("本文以 Debian 10 为例,所以使用 "),a("code",null,"/etc/apt/sources.list"),o(" 仍无问题,但如果你并不是根据本文从头开始,或者使用了其他 Linux 发行版,那么建议你建立 "),a("code",null,"/etc/apt/sources.list.d/"),o(" 文件夹,并在这个文件夹内建立自己的配置文件,形如 "),a("code",null,"/etc/apt/sources.list.d/vpsadmin.list"),o(" ,以此保证兼容性,也可避免默认文件在不可预见的情况下被覆盖而导致配置丢失。")])],-1),os=a("ol",{start:"2"},[a("li",null,"然后把下面这一条加在最后,并保存退出。")],-1),rs=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"deb http://deb.debian.org/debian buster-backports main\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),us=a("ol",{start:"3"},[a("li",null,"刷新软件库并查询 Debian 官方的最新版内核并安装。请务必安装你的 VPS 对应的版本(本文以比较常见的【amd64】为例)。")],-1),ps=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"apt"),o(" update "),a("span",{class:"token operator"},"&&"),o(),a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"apt"),o(" -t buster-backports "),a("span",{class:"token function"},"install"),o(" linux-image-amd64\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),is=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,[o("如果你的 VPS 支持,可以尝试【云服务器专用内核】"),a("code",null,"linux-image-cloud-amd64"),o(",优点就是精简、资源占用低,缺点嘛是有同学反馈不支持的系统强行安装会导致无法开机(Kernel 无法识别)。")]),a("p",null,"为了避免无法识别的悲剧,请确保:"),a("ul",null,[a("li",null,"尝试前做一个系统快照,或者"),a("li",null,[o("你有 "),a("code",null,"vnc"),o(" 可以救场(并且你知道怎么用)")])])],-1),bs=a("ol",{start:"4"},[a("li",null,[o("修改 "),a("code",null,"kernel"),o(" 参数配置文件 "),a("code",null,"sysctl.conf"),o(" 并指定开启 "),a("code",null,"BBR")])],-1),ds=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/sysctl.conf\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),ms=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("本文以 Debian 10 为例,所以使用 "),a("code",null,"/etc/sysctl.conf"),o(" 仍无问题,但如果你并不是跟着本文从头开始,或者使用了其他 Linux 发行版,那么建议你建立 "),a("code",null,"/etc/sysctl.d/"),o(" 文件夹,并在这个文件夹内建立自己的配置文件,形如 "),a("code",null,"/etc/sysctl.d/vpsadmin.conf"),o(",以此保证兼容性,因为部分发行版在 "),a("code",null,"systemd"),o(" 207 版本之后便不再从 "),a("code",null,"/etc/sysctl.conf"),o(" 读取参数。使用自定义配置文件也可避免默认文件在不可预见的情况下被覆盖而导致配置丢失。")])],-1),gs=a("ol",{start:"5"},[a("li",null,"把下面的内容添加进去")],-1),ks=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"net.core.default_qdisc=fq\nnet.ipv4.tcp_congestion_control=bbr\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])],-1),hs=a("ol",{start:"6"},[a("li",null,[o("重启 VPS、使内核更新和"),a("code",null,"BBR"),o("设置都生效")])],-1),ys=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"reboot"),o("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),xs=a("ol",{start:"7"},[a("li",null,"完整流程演示如下:")],-1),vs=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"啰嗦君"),a("p",null,[o("因为我做展示的 VPS 支持云服务器专用内核,所以动图中我用了 "),a("code",null,"linux-image-cloud-amd64"),o(" 。如果你不确定你的 VPS 是否支持,那请务必按照第 3 步的命令,使用常规内核 "),a("code",null,"linux-image-amd64"),o("。")])],-1),fs=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img06-bbr-proper.496ecbe2.gif",alt:"更新Debian内核并开启"})],-1),_s=a("ol",{start:"8"},[a("li",null,[o("确认"),a("code",null,"BBR"),o("开启")])],-1),Xs=a("p",null,[o("如果你想确认 "),a("code",null,"BBR"),o(" 是否正确开启,可以使用下面的命令:")],-1),Bs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("lsmod "),a("span",{class:"token operator"},"|"),o(),a("span",{class:"token function"},"grep"),o(" bbr\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),ws=a("p",null,"此时应该返回这样的结果:",-1),Ss=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"tcp_bbr\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ls=a("p",null,[o("如果你想确认 "),a("code",null,"fq"),o(" 算法是否正确开启,可以使用下面的命令:")],-1),Rs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("lsmod "),a("span",{class:"token operator"},"|"),o(),a("span",{class:"token function"},"grep"),o(" fq\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),qs=a("p",null,"此时应该返回这样的结果:",-1),Ts=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"sch_fq\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ds=a("h2",{id:"_7-8-服务器优化之二-开启-http-自动跳转-https",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-8-服务器优化之二-开启-http-自动跳转-https","aria-hidden":"true"},"#"),o(" 7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS")],-1),Ps=a("ol",null,[a("li",null,[o("之前我们已经搭建了 "),a("code",null,"80"),o(" 端口的 "),a("code",null,"http"),o(" 网页,并以此申请了 TLS 证书。")])],-1),Es=a("p",null,[o("但如果你尝试过用浏览器访问我们的这个界面,就会发现 "),a("code",null,"http"),o(" 访问并不会像大多数网站一样自动升级为 "),a("code",null,"https"),o(" 访问。换言之,我们现在的设置下,"),a("code",null,"http(80)"),o(" 和 "),a("code",null,"https(443)"),o(" 之间完全是独立的。如果要解决这个问题,就需要做一些修改。")],-1),js=a("ol",{start:"2"},[a("li",null,"编辑 Nginx 的配置文件")],-1),Ns=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/nginx/nginx.conf\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Is=a("ol",{start:"3"},[a("li",null,[o("在我们设置过的 80 端口 Server 中加入下面的语句,并保存退出(可同时删除"),a("code",null,"root"),o("和"),a("code",null,"index"),o("两行)")])],-1),Us=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"return 301 https://$http_host$request_uri;\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Vs=a("ol",{start:"4"},[a("li",null,[o("在与 "),a("code",null,"80"),o(" 端口同级的位置增加一个本地端口监听来提供网页展示。本文以 "),a("code",null,"8080"),o(" 端口做演示。(可以是任意端口)")])],-1),Fs=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,'server {\n listen 127.0.0.1:8080;\n root /home/vpsadmin/www/webpage;\n index index.html;\n add_header Strict-Transport-Security "max-age=63072000" always;\n}\n')]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br")])],-1),As=a("ol",{start:"5"},[a("li",null,"重启 Nginx 服务")],-1),Cs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart nginx\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Hs=a("ol",{start:"6"},[a("li",null,[o("修改 Xray 的回落设置,将回落从 "),a("code",null,"80"),o(" 端口改为 "),a("code",null,"8080"),o(" 端口。(找到 "),a("code",null,'"dest": 80'),o(", 并改成 "),a("code",null,'"dest": 8080'),o(")")])],-1),Ks=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /usr/local/etc/xray/config.json\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ms=a("ol",{start:"7"},[a("li",null,[o("重启 "),a("code",null,"Xray"),o(" 服务,即完成了设置")])],-1),$s=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Gs=a("ol",{start:"8"},[a("li",null,"完整流程演示如下:")],-1),Os=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img07-http-to-https.a87dc99c.gif",alt:"http自动跳转https"})],-1),Ws=a("ol",{start:"9"},[a("li",null,[o("当你输入 "),a("code",null,"http://a-name.yourdomain.com"),o("的时候,它应该已经会自动跳转 https 了")])],-1),zs=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img08-http-to-https-check.bc6ae06e.png",alt:"http自动跳转https生效"})],-1),Js=a("h2",{id:"_7-9-服务器优化之三-更丰富的回落",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-9-服务器优化之三-更丰富的回落","aria-hidden":"true"},"#"),o(" 7.9 服务器优化之三:更丰富的回落")],-1),Qs=o("如果你需要更丰富的回落功能,可以参考 "),Ys=o("《回落 (fallbacks) 功能简析》"),Zs=a("h2",{id:"_7-10-你的进度",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-10-你的进度","aria-hidden":"true"},"#"),o(" 7.10 你的进度")],-1),nl=a("p",null,"恭喜!!到这一步,你已经拥有了可以正常科学上网的服务器、同时也有了可以防止主动探测攻击的伪装网站。接下来,只要给你的客户端装上合适的软件,就可以享受顺畅的网络了!",-1),sl=a("blockquote",null,[a("p",null,"⬛⬛⬛⬛⬛⬛⬛⬜ 87.5%")],-1),ll=a("h2",{id:"_7-11-重要勘误",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-11-重要勘误","aria-hidden":"true"},"#"),o(" 7.11 重要勘误")],-1),al=a("ol",null,[a("li",null,[o("初版中"),a("code",null,"Xray"),o("配置文件"),a("code",null,"config.json"),o("文件夹位置错误。若你已经根据之前的位置进行了操作,"),a("code",null,"Xray"),o("会无法正确启动。故勘误说明于此,请自查,造成不便十分抱歉!")])],-1),el=a("ul",null,[a("li",null,[o("正确位置:"),a("code",null,"/usr/local/etc/xray/config.json")]),a("li",null,[o("错误位置:"),a("code",null,"/usr/local/etc/config.json")])],-1),tl=a("p",null,"受影响章节:",-1),cl=a("ul",null,[a("li",null,[o("7.4 配置"),a("code",null,"Xray"),o(" - 3. 使用"),a("code",null,"nano"),o("创建"),a("code",null,"Xray"),o("的配置文件")]),a("li",null,[o("7.8 服务器优化之二 - 6. 修改"),a("code",null,"Xray"),o("的回落设置")])],-1),ol=a("ol",{start:"2"},[a("li",null,[o("初版中修改"),a("code",null,"Nginx"),o("配置文件"),a("code",null,"nginx.conf"),o("时内容错误(网页文件夹位置错误),若你已经根据之前的位置进行了操作,"),a("code",null,"Nginx"),o("会无法找到正确的网站。请自查,造成不便十分抱歉!")])],-1),rl=a("ul",null,[a("li",null,[o("正确文件夹位置:"),a("code",null,"root /home/vpsadmin/www/webpage;")]),a("li",null,[o("错误文件夹位置:"),a("code",null,"root /var/www/website/html")])],-1),ul=a("p",null,"受影响章节:",-1),pl=a("ul",null,[a("li",null,[o("7.8 服务器优化之二 - 4. 在与 "),a("code",null,"80"),o(" 端口同级的位置增加一个本地端口监听来提供网页展示")])],-1);u.render=function(o,r){const u=n("OutboundLink"),il=n("RouterLink");return s(),l(c,null,[p,i,b,d,m,g,k,h,a("p",null,[y,a("a",x,[v,e(u)]),f,_,X]),a("p",null,[B,a("a",w,[S,e(u)]),L,R,q]),T,D,P,a("p",null,[E,a("a",j,[N,I,e(u)]),U,V,F,A,C]),a("ol",null,[H,K,M,$,a("li",null,[G,a("ol",O,[W,a("li",null,[z,a("div",J,[Q,a("p",null,[Y,a("a",Z,[nn,e(u)]),sn]),ln])]),an,en,tn,cn])])]),on,a("p",null,[rn,a("a",un,[pn,e(u)]),bn,dn,mn,gn,kn]),hn,yn,xn,vn,fn,_n,Xn,Bn,wn,Sn,Ln,Rn,qn,Tn,Dn,Pn,En,jn,Nn,In,Un,Vn,Fn,An,Cn,Hn,Kn,Mn,$n,Gn,On,Wn,zn,Jn,Qn,Yn,Zn,ns,ss,ls,as,es,ts,cs,os,rs,us,ps,is,bs,ds,ms,gs,ks,hs,ys,xs,vs,fs,_s,Xs,Bs,ws,Ss,Ls,Rs,qs,Ts,Ds,Ps,Es,js,Ns,Is,Us,Vs,Fs,As,Cs,Hs,Ks,Ms,$s,Gs,Os,Ws,zs,Js,a("p",null,[Qs,e(il,{to:"/document/level-1/fallbacks-lv1/"},{default:t((()=>[Ys])),_:1})]),Zs,nl,sl,ll,al,el,tl,cl,ol,rl,ul,pl],64)};export default u; +import{r as n,o as s,c as l,a,b as e,w as t,F as c,e as o,d as r}from"./app.48111a85.js";const u={},p=a("h1",{id:"【第-7-章】xray-服务器篇",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#【第-7-章】xray-服务器篇","aria-hidden":"true"},"#"),o(" 【第 7 章】Xray 服务器篇")],-1),i=a("h2",{id:"_7-1-博观而约取-厚积而薄发",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-1-博观而约取-厚积而薄发","aria-hidden":"true"},"#"),o(" 7.1 博观而约取,厚积而薄发")],-1),b=a("p",null,"本文撰写过程中,大佬开玩笑的吐槽到:你这教程,居然连载了 6 章都还没到 Xray,不知道的还以为你是“手把手教你建网站”教程呢。(我竟无法反驳.jpg!)",-1),d=a("p",null,[o("其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连"),a("code",null,"nano"),o("都无法正确使用,也不会用"),a("code",null,"WinSCP"),o(",远程手写编辑出来的"),a("code",null,"config.json"),o("自然错误百出,连查错也变得举步维艰。")],-1),m=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,"经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray 时会有一种【水到渠成】的轻快感觉。")],-1),g=a("p",null,"后面要做的事情非常简单:",-1),k=a("ol",null,[a("li",null,"安装"),a("li",null,[o("配置(如安装 TLS 证书、"),a("code",null,"config.json"),o(")")]),a("li",null,"运行"),a("li",null,[o("优化(如更新内核、开启"),a("code",null,"bbr"),o("、网站"),a("code",null,"http"),o("访问自动跳转"),a("code",null,"https"),o("等)")])],-1),h=a("h2",{id:"_7-2-安装-xray",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-2-安装-xray","aria-hidden":"true"},"#"),o(" 7.2 安装 Xray")],-1),y=o("首先,Xray 的官方载体,就是 "),x={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},v=o("xray-core"),f=o(" 开源项目(基于 "),_=a("code",null,"MPL 2.0",-1),X=o(" 开源协议)生成的二进制程序。你把这个二进制放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。主要区别来源于【配置】。"),B=o("安装时,直接使用官方安装脚本就很简单直接。它提供了多种安装选项,有兴趣的可以去官方的"),w={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},S=o("安装脚本仓库"),L=o("中看看脚本的说明,"),R=a("strong",null,"本文使用的是【非 root 用户】安装模式",-1),q=o("。"),T=a("p",null,"写本文时,安装脚本在使用非 root 账户时有一些小 bug,所以我决定正好把这几步分开操作,可以顺便说明一下 Linux 下的删除命令。",-1),D=a("ol",null,[a("li",null,[a("p",null,"小小白白 Linux 基础命令:"),a("table",null,[a("thead",null,[a("tr",null,[a("th",{style:{"text-align":"center"}},"编号"),a("th",{style:{"text-align":"center"}},"命令名称"),a("th",{style:{"text-align":"center"}},"命令说明")])]),a("tbody",null,[a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-14")]),a("td",{style:{"text-align":"center"}},[a("code",null,"rm")]),a("td",{style:{"text-align":"center"}},"删除命令")])])])]),a("li",null,[a("p",null,"将安装脚本下载至本地:"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"wget"),o(" https://github.com/XTLS/Xray-install/raw/main/install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"执行安装命令"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"bash"),o(" install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"使用完成之后可以删除该脚本"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"rm"),o(" ~/install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,[o("使用 "),a("code",null,"rm"),o(" 命令删除文件的时候,默认其实就是删除现在所在的文件夹下的文件。但是,"),a("strong",null,"我依然写了完整的路径"),o(": "),a("code",null,"~/install-release.sh"),o(",这是我使用 "),a("code",null,"rm"),o(" 时的一个安全习惯、也是我把安装分成几步之后想强调一下的内容。如果你听过一些“程序员从删库到跑路”之类的段子,大概就知道为什么了。")])])]),a("li",null,[a("p",null,"完整流程演示如下:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img01-xray-install.39750018.gif",alt:"Xray服务器端安装流程演示"})])])],-1),P=a("h2",{id:"_7-3-给-xray-配置-tls-证书",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-3-给-xray-配置-tls-证书","aria-hidden":"true"},"#"),o(" 7.3 给 Xray 配置 TLS 证书")],-1),E=o("虽然我们前面已经申请好了 TLS 证书,但是按照 "),j={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"},N=a("code",null,"acme.sh",-1),I=o("的官方说明"),U=o(",申请后的证书不建议直接使用。正确的方法是使用 "),V=a("code",null,"--install-cert",-1),F=o(" 命令安装给需要的程序。我们现在就来把证书安装给 "),A=a("code",null,"xray-core",-1),C=o(" 使用。"),H=a("li",null,[a("p",null,"为了规避非 root 账户的各种潜在的权限困扰,我们在 vpsadmin 账户下建立一个证书文件夹"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"mkdir"),o(" ~/xray_cert\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),K=a("li",null,[a("p",null,[o("使用"),a("code",null,"acme.sh"),o("的"),a("code",null,"--install-cert"),o("正确安装(拷贝)证书文件")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("acme.sh --install-cert -d 二级域名.你的域名.com --ecc "),a("span",{class:"token punctuation"},"\\"),o("\n --fullchain-file ~/xray_cert/xray.crt "),a("span",{class:"token punctuation"},"\\"),o("\n --key-file ~/xray_cert/xray.key\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br")])])],-1),M=a("li",null,[a("p",null,[a("code",null,"xray.key"),o("文件默认对其他用户不可读,所以需要赋予其可读性权限")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"chmod"),o(" +r ~/xray_cert/xray.key\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),$=a("li",null,[a("p",null,"过程比较简单就不放动图了:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img02-xray-cert-install.4136686d.png",alt:"Xray服务器端安装流程演示"})])],-1),G=r('

acme.sh 会每 60 天检查一次证书并自动更新临期证书。但据我所知是它并不会自动将新证书安装给 xray-core,所以我们需要新增一个系统的自动周期任务来完成这一步。

  1. 小小白白 Linux 基础命令:
编号命令名称命令说明
cmd-15crontab -e编辑当前用户的定时任务
',3),O={start:"2"},W=a("li",null,[a("p",null,[o("建立一个脚本文件("),a("code",null,"xray-cert-renew.sh"),o(")")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"nano"),o(" ~/xray_cert/xray-cert-renew.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),z=r('

把下面的内容复制进去,记得替换你的真实域名,然后保存退出

#!/bin/bash\n\n/home/vpsadmin/.acme.sh/acme.sh --install-cert -d a-name.yourdomain.com --ecc --fullchain-file /home/vpsadmin/xray_cert/xray.crt --key-file /home/vpsadmin/xray_cert/xray.key\necho "Xray Certificates Renewed"\n\nchmod +r /home/vpsadmin/xray_cert/xray.key\necho "Read Permission Granted for Private Key"\n\nsudo systemctl restart xray\necho "Xray Restarted"\n
1
2
3
4
5
6
7
8
9
10
',2),J={class:"custom-container warning"},Q=a("p",{class:"custom-container-title"},"注意",-1),Y=r("经大家提醒,acme.sh 有一个 reloadcmd 命令,可以在证书更新时自动执行特定命令,那么就可以指定自动给 Xray 安装证书,但因为 crontab 是 Linux 系统中一个非常有用、非常常用的功能,所以本文保留 crontab 的方式来更新 Xray 证书。(对 reloadcmd 感兴趣的同学可以查看 acme.sh 的",17),Z={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},nn=o("官方文档"),sn=o(")"),ln=a("p",null,[o("另外,录制动图时,脚本中没有加入重启 "),a("code",null,"Xray"),o(" 的命令,是因为 "),a("code",null,"Xray"),o(" 计划支持【证书热更新】功能,即 "),a("code",null,"Xray"),o(" 会自动识别证书更新并重载证书、无需手动重启。待功能加入后,我将适当修改 "),a("code",null,"config.json"),o(" 开启此设置,并删除脚本中的重启命令。")],-1),an=a("li",null,[a("p",null,"给这个文件增加【可执行】权限"),a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"chmod +x ~/xray_cert/xray-cert-renew.sh\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),en=a("li",null,[a("p",null,[o("运行 "),a("code",null,"crontab -e"),o(",添加一个自动任务【每月自动运行一次"),a("code",null,"xray-cert-renew.sh"),o("】 (注意不要加"),a("code",null,"sudo"),o(",因为我们增加的是"),a("code",null,"vpsadmin"),o(" 账户的自动任务。初次运行时会让你选择编辑器,当然是选择熟悉的"),a("code",null,"nano"),o("啦!)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"crontab"),o(" -e\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),tn=a("li",null,[a("p",null,"把下面的内容增加在文件最后,保存退出即可。"),a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"# 1:00am, 1st day each month, run `xray-cert-renew.sh`\n0 1 1 * * bash /home/vpsadmin/xray_cert/xray-cert-renew.sh\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])])],-1),cn=a("li",null,[a("p",null,"完整流程演示如下:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img03-crontab-cert-renew.ce7049d5.gif",alt:"每月自动给Xray安装证书"})])],-1),on=a("h2",{id:"_7-4-配置-xray",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-4-配置-xray","aria-hidden":"true"},"#"),o(" 7.4 配置 Xray")],-1),rn=o("首先,各种配置都可以参考"),un={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},pn=o("官方 VLESS 配置示例"),bn=o("。本文会基于官方示例,配置一个最精简的方式:【单 "),dn=a("code",null,"VLESS",-1),mn=o(" 协议入站 + "),gn=a("code",null,"80",-1),kn=o(" 端口回落】,满足大多数场景的最大速度及必要安全。"),hn=a("ol",null,[a("li",null,[a("p",null,[o("生成一个合法的 "),a("code",null,"UUID"),o(" 并保存备用("),a("code",null,"UUID"),o("可以简单粗暴的理解为像指纹一样几乎不会重复的 ID)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"xray uuid\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"建立日志文件及文件夹备用"),a("ol",null,[a("li",null,[a("p",null,"小小白白 Linux 基础命令:"),a("table",null,[a("thead",null,[a("tr",null,[a("th",{style:{"text-align":"center"}},"编号"),a("th",{style:{"text-align":"center"}},"命令名称"),a("th",{style:{"text-align":"center"}},"命令说明")])]),a("tbody",null,[a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-16")]),a("td",{style:{"text-align":"center"}},[a("code",null,"touch")]),a("td",{style:{"text-align":"center"}},"建立空白文件")])])])]),a("li",null,[a("p",null,[o("在"),a("code",null,"vpsadmin"),o("的文件夹内建立一个【日志专用文件夹】")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"mkdir"),o(" ~/xray_log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"生成所需的两个日志文件(访问日志、错误日志)"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"touch"),o(" ~/xray_log/access.log "),a("span",{class:"token operator"},"&&"),o(),a("span",{class:"token function"},"touch"),o(" ~/xray_log/error.log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,[o("这个位置不是"),a("code",null,"Xray"),o("标准的日志文件位置,放在这里是避免权限问题对新人的操作带来困扰。当你熟悉之后,建议回归默认位置: "),a("code",null,"/var/log/xray/access.log"),o(" 和 "),a("code",null,"/var/log/xray/error.log"),o(" 。")])])]),a("li",null,[a("p",null,[o("因为 Xray 默认是 nobody 用户使用,所以我们需要让其他用户也有“写”的权限("),a("code",null,"*.log"),o(" 就是所有文件后缀是"),a("code",null,"log"),o("的文件,此时"),a("code",null,"CLI"),o("界面的效率优势就逐渐出现了)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"chmod"),o(" a+w ~/xray_log/*.log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])])])]),a("li",null,[a("p",null,[o("使用"),a("code",null,"nano"),o("创建"),a("code",null,"Xray"),o("的配置文件")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /usr/local/etc/xray/config.json\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,[o("将下面的文件全部复制进去,并将之前生成的"),a("code",null,"UUID"),o("填入第 61 行 "),a("code",null,'"id": "",'),o(" 之中。(填好之后的样子是 "),a("code",null,'"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid"'),o(" ),本文的这个配置文件中增加了我的各种啰嗦注解,以方便你理解每一个配置模块的功能是什么。")]),a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token comment"},"// REFERENCE:"),o("\n"),a("span",{class:"token comment"},"// https://github.com/XTLS/Xray-examples"),o("\n"),a("span",{class:"token comment"},"// https://xtls.github.io/config/"),o("\n"),a("span",{class:"token comment"},"// 常用的 config 文件,不论服务器端还是客户端,都有 5 个部分。外加小小白解读:"),o("\n"),a("span",{class:"token comment"},"// ┌─ 1*log 日志设置 - 日志写什么,写哪里(出错时有据可查)"),o("\n"),a("span",{class:"token comment"},"// ├─ 2_dns DNS-设置 - DNS 怎么查(防 DNS 污染、防偷窥、避免国内外站匹配到国外服务器等)"),o("\n"),a("span",{class:"token comment"},"// ├─ 3_routing 分流设置 - 流量怎么分类处理(是否过滤广告、是否国内外分流)"),o("\n"),a("span",{class:"token comment"},"// ├─ 4_inbounds 入站设置 - 什么流量可以流入 Xray"),o("\n"),a("span",{class:"token comment"},"// └─ 5_outbounds 出站设置 - 流出 Xray 的流量往哪里去"),o("\n"),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token comment"},"// 1\\_日志设置"),o("\n "),a("span",{class:"token property"},'"log"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"loglevel"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"warning"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},'// 内容从少到多: "none", "error", "warning", "info", "debug"'),o("\n "),a("span",{class:"token property"},'"access"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_log/access.log"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 访问记录"),o("\n "),a("span",{class:"token property"},'"error"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_log/error.log"'),o(),a("span",{class:"token comment"},"// 错误记录"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 2_DNS 设置"),o("\n "),a("span",{class:"token property"},'"dns"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"servers"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"https+local://1.1.1.1/dns-query"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 首选 1.1.1.1 的 DoH 查询,牺牲速度但可防止 ISP 偷窥"),o("\n "),a("span",{class:"token string"},'"localhost"'),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 3*分流设置"),o("\n "),a("span",{class:"token property"},'"routing"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"domainStrategy"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"IPIfNonMatch"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"rules"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token comment"},"// 3.1 防止服务器本地流转问题:如内网被攻击或滥用、错误的本地回环等"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"ip"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"geoip:private"'),o(),a("span",{class:"token comment"},'// 分流条件:geoip 文件内,名为"private"的规则(本地)'),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o(),a("span",{class:"token comment"},'// 分流策略:交给出站"block"处理(黑洞屏蔽)'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token comment"},"// 3.2 防止服务器直连国内"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"ip"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),a("span",{class:"token string"},'"geoip:cn"'),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 3.3 屏蔽广告"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"domain"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"geosite:category-ads-all"'),o(),a("span",{class:"token comment"},'// 分流条件:geosite 文件内,名为"category-ads-all"的规则(各种广告域名)'),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o(),a("span",{class:"token comment"},'// 分流策略:交给出站"block"处理(黑洞屏蔽)'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 4*入站设置"),o("\n "),a("span",{class:"token comment"},"// 4.1 这里只写了一个最简单的 vless+xtls 的入站,因为这是 Xray 最强大的模式。如有其他需要,请根据模版自行添加。"),o("\n "),a("span",{class:"token property"},'"inbounds"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"443"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"vless"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"clients"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"id"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'""'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 填写你的 UUID"),o("\n "),a("span",{class:"token property"},'"flow"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"xtls-rprx-vision"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"level"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"0"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"email"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"vpsadmin@yourdomain.com"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"decryption"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"none"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"fallbacks"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"80"),o(),a("span",{class:"token comment"},"// 默认回落到防探测的代理"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"tcp"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"security"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"tls"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"tlsSettings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"alpn"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"http/1.1"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"certificates"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"certificateFile"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_cert/xray.crt"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"keyFile"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_cert/xray.key"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 5*出站设置"),o("\n "),a("span",{class:"token property"},'"outbounds"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token comment"},"// 5.1 第一个出站是默认规则,freedom 就是对外直连(vps 已经是外网,所以直连)"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"tag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"direct"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"freedom"'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 5.2 屏蔽规则,blackhole 协议就是把流量导入到黑洞里(屏蔽)"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"tag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"blackhole"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n"),a("span",{class:"token punctuation"},"}"),o("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br"),a("span",{class:"line-number"},"37"),a("br"),a("span",{class:"line-number"},"38"),a("br"),a("span",{class:"line-number"},"39"),a("br"),a("span",{class:"line-number"},"40"),a("br"),a("span",{class:"line-number"},"41"),a("br"),a("span",{class:"line-number"},"42"),a("br"),a("span",{class:"line-number"},"43"),a("br"),a("span",{class:"line-number"},"44"),a("br"),a("span",{class:"line-number"},"45"),a("br"),a("span",{class:"line-number"},"46"),a("br"),a("span",{class:"line-number"},"47"),a("br"),a("span",{class:"line-number"},"48"),a("br"),a("span",{class:"line-number"},"49"),a("br"),a("span",{class:"line-number"},"50"),a("br"),a("span",{class:"line-number"},"51"),a("br"),a("span",{class:"line-number"},"52"),a("br"),a("span",{class:"line-number"},"53"),a("br"),a("span",{class:"line-number"},"54"),a("br"),a("span",{class:"line-number"},"55"),a("br"),a("span",{class:"line-number"},"56"),a("br"),a("span",{class:"line-number"},"57"),a("br"),a("span",{class:"line-number"},"58"),a("br"),a("span",{class:"line-number"},"59"),a("br"),a("span",{class:"line-number"},"60"),a("br"),a("span",{class:"line-number"},"61"),a("br"),a("span",{class:"line-number"},"62"),a("br"),a("span",{class:"line-number"},"63"),a("br"),a("span",{class:"line-number"},"64"),a("br"),a("span",{class:"line-number"},"65"),a("br"),a("span",{class:"line-number"},"66"),a("br"),a("span",{class:"line-number"},"67"),a("br"),a("span",{class:"line-number"},"68"),a("br"),a("span",{class:"line-number"},"69"),a("br"),a("span",{class:"line-number"},"70"),a("br"),a("span",{class:"line-number"},"71"),a("br"),a("span",{class:"line-number"},"72"),a("br"),a("span",{class:"line-number"},"73"),a("br"),a("span",{class:"line-number"},"74"),a("br"),a("span",{class:"line-number"},"75"),a("br"),a("span",{class:"line-number"},"76"),a("br"),a("span",{class:"line-number"},"77"),a("br"),a("span",{class:"line-number"},"78"),a("br"),a("span",{class:"line-number"},"79"),a("br"),a("span",{class:"line-number"},"80"),a("br"),a("span",{class:"line-number"},"81"),a("br"),a("span",{class:"line-number"},"82"),a("br"),a("span",{class:"line-number"},"83"),a("br"),a("span",{class:"line-number"},"84"),a("br"),a("span",{class:"line-number"},"85"),a("br"),a("span",{class:"line-number"},"86"),a("br"),a("span",{class:"line-number"},"87"),a("br"),a("span",{class:"line-number"},"88"),a("br"),a("span",{class:"line-number"},"89"),a("br"),a("span",{class:"line-number"},"90"),a("br"),a("span",{class:"line-number"},"91"),a("br"),a("span",{class:"line-number"},"92"),a("br"),a("span",{class:"line-number"},"93"),a("br"),a("span",{class:"line-number"},"94"),a("br"),a("span",{class:"line-number"},"95"),a("br"),a("span",{class:"line-number"},"96"),a("br"),a("span",{class:"line-number"},"97"),a("br"),a("span",{class:"line-number"},"98"),a("br"),a("span",{class:"line-number"},"99"),a("br"),a("span",{class:"line-number"},"100"),a("br"),a("span",{class:"line-number"},"101"),a("br"),a("span",{class:"line-number"},"102"),a("br")])])])],-1),yn=a("ol",{start:"5"},[a("li",null,[o("完整流程演示如下: "),a("img",{src:"/Xray-docs-next/assets/ch07-img04-xray-log-and-config.1876d557.gif",alt:"创建日志文件及配置文件"})])],-1),xn=a("h2",{id:"_7-5-启动-xray-服务-并查看服务状态",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-5-启动-xray-服务-并查看服务状态","aria-hidden":"true"},"#"),o(" 7.5 启动 Xray 服务!!(并查看服务状态)")],-1),vn=a("p",null,[o("如果你是跟随本文一步步设置过来,其实就已经避开了最常见"),a("strong",null,"日志文件权限不足"),o("、"),a("strong",null,"证书文件权限不足"),o(" 这两个大坑。那么现在运行"),a("code",null,"Xray"),o("自然应该无比顺利。")],-1),fn=a("ol",null,[a("li",null,[o("输入下面的命令,享受启动"),a("code",null,"Xray"),o("的历史性时刻吧!!!")])],-1),_n=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl start xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Xn=a("ol",{start:"2"},[a("li",null,[o("仅仅"),a("code",null,"start"),o("我们并不能确定是否成功的开启了 Xray 的服务,要确定它的状态,就要用到下面的命令。")])],-1),Bn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl status xray\n\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])],-1),wn=a("p",null,[o("看到那个绿色的、令人愉悦的 "),a("code",null,"active (running)"),o(" 了吗?它就是说 "),a("code",null,"Xray"),o(" 已经在正确的运行了")],-1),Sn=a("ol",{start:"3"},[a("li",null,"完整流程演示如下:")],-1),Ln=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img05-xray-start-and-status.b77f6ab3.gif",alt:"启动并查看Xray运行状态"})],-1),Rn=a("h2",{id:"_7-6-回顾-systemd-进行基本的服务管理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-6-回顾-systemd-进行基本的服务管理","aria-hidden":"true"},"#"),o(" 7.6 回顾 "),a("code",null,"systemd"),o(" 进行基本的服务管理")],-1),qn=a("p",null,[o("到现在为止,我们已经使用过了"),a("code",null,"systemctl"),o("相关的"),a("code",null,"start"),o(", "),a("code",null,"status"),o(", "),a("code",null,"reload"),o(" 等命令,这些都是基于"),a("code",null,"systemd"),o("管理模块对 Linux 系统中各种服务进行管理的通用命令。现在正好熟悉一下相关的其他几个命令。")],-1),Tn=a("ol",null,[a("li",null,[o("若你需要暂时关闭 "),a("code",null,"Xray"),o(" 的服务,那就用"),a("code",null,"stop"),o("命令")])],-1),Dn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl stop xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Pn=a("ol",{start:"2"},[a("li",null,[o("若你需要重启"),a("code",null,"Xray"),o("的服务,那就用"),a("code",null,"restart"),o("命令")])],-1),En=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),jn=a("ol",{start:"3"},[a("li",null,[o("若你需要禁用"),a("code",null,"Xray"),o("的服务(电脑重启后禁止 Xray 自动运行),那就用"),a("code",null,"disable"),o("命令")])],-1),Nn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl disable xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),In=a("ol",{start:"4"},[a("li",null,[o("若你需要启用"),a("code",null,"Xray"),o("的服务(电脑重启后确保 Xray 自动运行),那就用"),a("code",null,"enable"),o("命令")])],-1),Un=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl "),a("span",{class:"token builtin class-name"},"enable"),o(" xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Vn=a("h2",{id:"_7-7-服务器优化之一-开启-bbr",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-7-服务器优化之一-开启-bbr","aria-hidden":"true"},"#"),o(" 7.7 服务器优化之一:开启 BBR")],-1),Fn=a("ol",null,[a("li",null,[o("传说中的"),a("code",null,"BBR")])],-1),An=a("p",null,[o("我相信,你在搜索各种科学上网技术的时候,肯定不止一次的听过"),a("code",null,"bbr"),o("这个东西,在各种博客添油加醋之下,让人觉得它神乎其神。更有"),a("code",null,"bbrplus"),o(", "),a("code",null,"bbr2"),o(", "),a("code",null,"魔改bbr"),o(" 等一大堆衍生品。仿佛神油一般,用了就能野鸡线路变专线。")],-1),Cn=a("p",null,"那么,这东西究竟是什么?它有没有用?又该用哪一个版本呢?",-1),Hn=a("ol",{start:"2"},[a("li",null,[o("实际的"),a("code",null,"BBR")])],-1),Kn=a("p",null,[a("strong",null,"BBR"),o(" = "),a("strong",null,"B"),o("ottleneck "),a("strong",null,"B"),o("andwidth and "),a("strong",null,"R"),o("ound-trip propagation time,是一种 TCP 的"),a("strong",null,"拥塞控制算法"),o("。简单粗暴的理解就是"),a("strong",null,"数据流量的交通管理"),o(" :当公路不再塞车的时候,每辆车自然就能保持较快的车速了。")],-1),Mn=a("p",null,[o("那么它有没有用呢?一般而言,"),a("code",null,"有BBR"),o(" 和 "),a("code",null,"没有BBR"),o(" 会有可以感知的差别(速度、稳定性、延迟方面都会有一些改善),所以 "),a("strong",null,[o("【非常建议开启 "),a("code",null,"BBR"),o("】")]),o("。")],-1),$n=a("p",null,[o("但开启之后,"),a("code",null,"BBR"),o(" 在 "),a("code",null,"4.x"),o(" 和 "),a("code",null,"5.x"),o(" 之间的差异往往比较微妙、见仁见智,造成体验差别的决定性因素仍然是线路质量。所以 "),a("strong",null,"【不必纠结版本、不必盲目追新、跟随你的发行版更新内核即可】")],-1),Gn=a("ol",{start:"3"},[a("li",null,[a("code",null,"bbrplus"),o(", "),a("code",null,"bbr2"),o(", "),a("code",null,"魔改bbr"),o(" 和其他各种听起来就酷炫的版本是不是更好?")])],-1),On=a("p",null,[o("一句话:"),a("strong",null,"不是!不要用这些!这些都为了吸引眼球乱起的名字!")],-1),Wn=a("p",null,[a("code",null,"BBR"),o(" 的更新和发布,都是跟随 Linux 的内核("),a("code",null,"Kernel"),o(")进行的。换言之,只要你用的是比较新的内核,就自然会使用到新版"),a("code",null,"BBR"),o("。")],-1),zn=a("p",null,[o("而这些名字看起来很酷炫的东西,说白了就是仍未正式发布的、尚在测试阶段的内核及其对应的"),a("code",null,"BBR"),o("版本。这些脚本也仅仅就是通过下载预览版的内核(甚至第三方魔改内核)来率先开启而已。")],-1),Jn=a("p",null,[o("内核的稳定是一台服务器稳定运行的基石。"),a("strong",null,"【BBR 测试版带来的细微性能差异绝对不值得更换不稳定的内核。】"),o(" 请选择你所在的 Linux 发行版所支持的最新内核,这样可以最大限度的保持服务器的长期稳定和兼容。")],-1),Qn=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,[o("所谓魔改"),a("code",null,"bbr"),o("的【领先】是有非常强的时效性的。比如很多 "),a("code",null,"bbrplus"),o(" 脚本,因为几年来都没有更新,到现在还会把你的内核换成 "),a("code",null,"4.19"),o(",要知道现在稳定如 Debian 已经是 "),a("code",null,"5.9"),o(" 的时代了,那么这个脚本放在 2018 年 1 月也许领先了一点,到 2018 年 10 月 4.19 正发布时就已经失去了意义,放在现在甚至可以说是完完全全的【降级】和【劣化】")])],-1),Yn=a("ol",{start:"4"},[a("li",null,[a("code",null,"fq"),o(", "),a("code",null,"fq_codel"),o(", "),a("code",null,"fq_pie"),o(", "),a("code",null,"cake"),o("和其他算法哪个好?")])],-1),Zn=a("p",null,[o("一句话:"),a("strong",null,[o("看不懂的话,请保持"),a("code",null,"fq"),o(",足够、且不会劣化你的线路")])],-1),ns=a("ol",{start:"5"},[a("li",null,"锐速、Finalspeed、LotServer 和其他“加速工具”")],-1),ss=a("p",null,[o("一句话:"),a("strong",null,"不要用这些!把他们丢进历史的垃圾桶吧!")],-1),ls=a("p",null,"它能解决的也只有丢包率的问题。不太准确的比喻,就是本来你用一辆车送你的货,有时候车半路就坏了(丢包),用了这些以后,你直接派出 3 份一样的货,让三辆车同时送,只要有一辆没坏就能送到。马路上都是你的车,自然就能把别人挤下去。但可想而知,你挤别人的时候,别人也会来挤你,而整个机房的出口道路一共就那么宽,最终势必就变成集体大堵车了。",-1),as=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("它们的原理不是算法优化、不是提速、大多数是简单粗暴的"),a("strong",null,"多倍发包"),o("。对于【丢包率非常高】的差线路可能有一点作用,但【对丢包率低的好线路没有任何优化作用,反而会成倍的消耗你的流量】,进而造成服务器和你的邻居不必要的压力。")]),a("p",null,"如果你的线路真的丢包率奇高,真正靠谱的解决方案是【换线路】。")],-1),es=a("ol",{start:"6"},[a("li",null,[a("p",null,[o("啰嗦了这么多,就是因为围绕 "),a("code",null,"BBR"),o(" 忽悠小白的错误概念和坑人脚本实在是太多了。我希望你们现在对 "),a("code",null,"BBR"),o(" 有了相对清晰的理解。接下来,我们就动手安装最新的 Debian 内核并开启"),a("code",null,"BBR"),o(" 吧!(真的很简单)")])]),a("li",null,[a("p",null,[o("给 Debian 10 添加官方 "),a("code",null,"backports"),o(" 源,获取更新的软件库")])])],-1),ts=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/apt/sources.list\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),cs=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("本文以 Debian 10 为例,所以使用 "),a("code",null,"/etc/apt/sources.list"),o(" 仍无问题,但如果你并不是根据本文从头开始,或者使用了其他 Linux 发行版,那么建议你建立 "),a("code",null,"/etc/apt/sources.list.d/"),o(" 文件夹,并在这个文件夹内建立自己的配置文件,形如 "),a("code",null,"/etc/apt/sources.list.d/vpsadmin.list"),o(" ,以此保证兼容性,也可避免默认文件在不可预见的情况下被覆盖而导致配置丢失。")])],-1),os=a("ol",{start:"2"},[a("li",null,"然后把下面这一条加在最后,并保存退出。")],-1),rs=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"deb http://deb.debian.org/debian buster-backports main\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),us=a("ol",{start:"3"},[a("li",null,"刷新软件库并查询 Debian 官方的最新版内核并安装。请务必安装你的 VPS 对应的版本(本文以比较常见的【amd64】为例)。")],-1),ps=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"apt"),o(" update "),a("span",{class:"token operator"},"&&"),o(),a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"apt"),o(" -t buster-backports "),a("span",{class:"token function"},"install"),o(" linux-image-amd64\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),is=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,[o("如果你的 VPS 支持,可以尝试【云服务器专用内核】"),a("code",null,"linux-image-cloud-amd64"),o(",优点就是精简、资源占用低,缺点嘛是有同学反馈不支持的系统强行安装会导致无法开机(Kernel 无法识别)。")]),a("p",null,"为了避免无法识别的悲剧,请确保:"),a("ul",null,[a("li",null,"尝试前做一个系统快照,或者"),a("li",null,[o("你有 "),a("code",null,"vnc"),o(" 可以救场(并且你知道怎么用)")])])],-1),bs=a("ol",{start:"4"},[a("li",null,[o("修改 "),a("code",null,"kernel"),o(" 参数配置文件 "),a("code",null,"sysctl.conf"),o(" 并指定开启 "),a("code",null,"BBR")])],-1),ds=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/sysctl.conf\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),ms=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("本文以 Debian 10 为例,所以使用 "),a("code",null,"/etc/sysctl.conf"),o(" 仍无问题,但如果你并不是跟着本文从头开始,或者使用了其他 Linux 发行版,那么建议你建立 "),a("code",null,"/etc/sysctl.d/"),o(" 文件夹,并在这个文件夹内建立自己的配置文件,形如 "),a("code",null,"/etc/sysctl.d/vpsadmin.conf"),o(",以此保证兼容性,因为部分发行版在 "),a("code",null,"systemd"),o(" 207 版本之后便不再从 "),a("code",null,"/etc/sysctl.conf"),o(" 读取参数。使用自定义配置文件也可避免默认文件在不可预见的情况下被覆盖而导致配置丢失。")])],-1),gs=a("ol",{start:"5"},[a("li",null,"把下面的内容添加进去")],-1),ks=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"net.core.default_qdisc=fq\nnet.ipv4.tcp_congestion_control=bbr\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])],-1),hs=a("ol",{start:"6"},[a("li",null,[o("重启 VPS、使内核更新和"),a("code",null,"BBR"),o("设置都生效")])],-1),ys=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"reboot"),o("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),xs=a("ol",{start:"7"},[a("li",null,"完整流程演示如下:")],-1),vs=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"啰嗦君"),a("p",null,[o("因为我做展示的 VPS 支持云服务器专用内核,所以动图中我用了 "),a("code",null,"linux-image-cloud-amd64"),o(" 。如果你不确定你的 VPS 是否支持,那请务必按照第 3 步的命令,使用常规内核 "),a("code",null,"linux-image-amd64"),o("。")])],-1),fs=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img06-bbr-proper.496ecbe2.gif",alt:"更新Debian内核并开启"})],-1),_s=a("ol",{start:"8"},[a("li",null,[o("确认"),a("code",null,"BBR"),o("开启")])],-1),Xs=a("p",null,[o("如果你想确认 "),a("code",null,"BBR"),o(" 是否正确开启,可以使用下面的命令:")],-1),Bs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("lsmod "),a("span",{class:"token operator"},"|"),o(),a("span",{class:"token function"},"grep"),o(" bbr\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),ws=a("p",null,"此时应该返回这样的结果:",-1),Ss=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"tcp_bbr\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ls=a("p",null,[o("如果你想确认 "),a("code",null,"fq"),o(" 算法是否正确开启,可以使用下面的命令:")],-1),Rs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("lsmod "),a("span",{class:"token operator"},"|"),o(),a("span",{class:"token function"},"grep"),o(" fq\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),qs=a("p",null,"此时应该返回这样的结果:",-1),Ts=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"sch_fq\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ds=a("h2",{id:"_7-8-服务器优化之二-开启-http-自动跳转-https",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-8-服务器优化之二-开启-http-自动跳转-https","aria-hidden":"true"},"#"),o(" 7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS")],-1),Ps=a("ol",null,[a("li",null,[o("之前我们已经搭建了 "),a("code",null,"80"),o(" 端口的 "),a("code",null,"http"),o(" 网页,并以此申请了 TLS 证书。")])],-1),Es=a("p",null,[o("但如果你尝试过用浏览器访问我们的这个界面,就会发现 "),a("code",null,"http"),o(" 访问并不会像大多数网站一样自动升级为 "),a("code",null,"https"),o(" 访问。换言之,我们现在的设置下,"),a("code",null,"http(80)"),o(" 和 "),a("code",null,"https(443)"),o(" 之间完全是独立的。如果要解决这个问题,就需要做一些修改。")],-1),js=a("ol",{start:"2"},[a("li",null,"编辑 Nginx 的配置文件")],-1),Ns=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/nginx/nginx.conf\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Is=a("ol",{start:"3"},[a("li",null,[o("在我们设置过的 80 端口 Server 中加入下面的语句,并保存退出(可同时删除"),a("code",null,"root"),o("和"),a("code",null,"index"),o("两行)")])],-1),Us=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"return 301 https://$http_host$request_uri;\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Vs=a("ol",{start:"4"},[a("li",null,[o("在与 "),a("code",null,"80"),o(" 端口同级的位置增加一个本地端口监听来提供网页展示。本文以 "),a("code",null,"8080"),o(" 端口做演示。(可以是任意端口)")])],-1),Fs=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,'server {\n listen 127.0.0.1:8080;\n root /home/vpsadmin/www/webpage;\n index index.html;\n add_header Strict-Transport-Security "max-age=63072000" always;\n}\n')]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br")])],-1),As=a("ol",{start:"5"},[a("li",null,"重启 Nginx 服务")],-1),Cs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart nginx\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Hs=a("ol",{start:"6"},[a("li",null,[o("修改 Xray 的回落设置,将回落从 "),a("code",null,"80"),o(" 端口改为 "),a("code",null,"8080"),o(" 端口。(找到 "),a("code",null,'"dest": 80'),o(", 并改成 "),a("code",null,'"dest": 8080'),o(")")])],-1),Ks=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /usr/local/etc/xray/config.json\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ms=a("ol",{start:"7"},[a("li",null,[o("重启 "),a("code",null,"Xray"),o(" 服务,即完成了设置")])],-1),$s=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Gs=a("ol",{start:"8"},[a("li",null,"完整流程演示如下:")],-1),Os=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img07-http-to-https.a87dc99c.gif",alt:"http自动跳转https"})],-1),Ws=a("ol",{start:"9"},[a("li",null,[o("当你输入 "),a("code",null,"http://a-name.yourdomain.com"),o("的时候,它应该已经会自动跳转 https 了")])],-1),zs=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img08-http-to-https-check.bc6ae06e.png",alt:"http自动跳转https生效"})],-1),Js=a("h2",{id:"_7-9-服务器优化之三-更丰富的回落",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-9-服务器优化之三-更丰富的回落","aria-hidden":"true"},"#"),o(" 7.9 服务器优化之三:更丰富的回落")],-1),Qs=o("如果你需要更丰富的回落功能,可以参考 "),Ys=o("《回落 (fallbacks) 功能简析》"),Zs=a("h2",{id:"_7-10-你的进度",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-10-你的进度","aria-hidden":"true"},"#"),o(" 7.10 你的进度")],-1),nl=a("p",null,"恭喜!!到这一步,你已经拥有了可以正常科学上网的服务器、同时也有了可以防止主动探测攻击的伪装网站。接下来,只要给你的客户端装上合适的软件,就可以享受顺畅的网络了!",-1),sl=a("blockquote",null,[a("p",null,"⬛⬛⬛⬛⬛⬛⬛⬜ 87.5%")],-1),ll=a("h2",{id:"_7-11-重要勘误",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-11-重要勘误","aria-hidden":"true"},"#"),o(" 7.11 重要勘误")],-1),al=a("ol",null,[a("li",null,[o("初版中"),a("code",null,"Xray"),o("配置文件"),a("code",null,"config.json"),o("文件夹位置错误。若你已经根据之前的位置进行了操作,"),a("code",null,"Xray"),o("会无法正确启动。故勘误说明于此,请自查,造成不便十分抱歉!")])],-1),el=a("ul",null,[a("li",null,[o("正确位置:"),a("code",null,"/usr/local/etc/xray/config.json")]),a("li",null,[o("错误位置:"),a("code",null,"/usr/local/etc/config.json")])],-1),tl=a("p",null,"受影响章节:",-1),cl=a("ul",null,[a("li",null,[o("7.4 配置"),a("code",null,"Xray"),o(" - 3. 使用"),a("code",null,"nano"),o("创建"),a("code",null,"Xray"),o("的配置文件")]),a("li",null,[o("7.8 服务器优化之二 - 6. 修改"),a("code",null,"Xray"),o("的回落设置")])],-1),ol=a("ol",{start:"2"},[a("li",null,[o("初版中修改"),a("code",null,"Nginx"),o("配置文件"),a("code",null,"nginx.conf"),o("时内容错误(网页文件夹位置错误),若你已经根据之前的位置进行了操作,"),a("code",null,"Nginx"),o("会无法找到正确的网站。请自查,造成不便十分抱歉!")])],-1),rl=a("ul",null,[a("li",null,[o("正确文件夹位置:"),a("code",null,"root /home/vpsadmin/www/webpage;")]),a("li",null,[o("错误文件夹位置:"),a("code",null,"root /var/www/website/html")])],-1),ul=a("p",null,"受影响章节:",-1),pl=a("ul",null,[a("li",null,[o("7.8 服务器优化之二 - 4. 在与 "),a("code",null,"80"),o(" 端口同级的位置增加一个本地端口监听来提供网页展示")])],-1);u.render=function(o,r){const u=n("OutboundLink"),il=n("RouterLink");return s(),l(c,null,[p,i,b,d,m,g,k,h,a("p",null,[y,a("a",x,[v,e(u)]),f,_,X]),a("p",null,[B,a("a",w,[S,e(u)]),L,R,q]),T,D,P,a("p",null,[E,a("a",j,[N,I,e(u)]),U,V,F,A,C]),a("ol",null,[H,K,M,$,a("li",null,[G,a("ol",O,[W,a("li",null,[z,a("div",J,[Q,a("p",null,[Y,a("a",Z,[nn,e(u)]),sn]),ln])]),an,en,tn,cn])])]),on,a("p",null,[rn,a("a",un,[pn,e(u)]),bn,dn,mn,gn,kn]),hn,yn,xn,vn,fn,_n,Xn,Bn,wn,Sn,Ln,Rn,qn,Tn,Dn,Pn,En,jn,Nn,In,Un,Vn,Fn,An,Cn,Hn,Kn,Mn,$n,Gn,On,Wn,zn,Jn,Qn,Yn,Zn,ns,ss,ls,as,es,ts,cs,os,rs,us,ps,is,bs,ds,ms,gs,ks,hs,ys,xs,vs,fs,_s,Xs,Bs,ws,Ss,Ls,Rs,qs,Ts,Ds,Ps,Es,js,Ns,Is,Us,Vs,Fs,As,Cs,Hs,Ks,Ms,$s,Gs,Os,Ws,zs,Js,a("p",null,[Qs,e(il,{to:"/document/level-1/fallbacks-lv1/"},{default:t((()=>[Ys])),_:1})]),Zs,nl,sl,ll,al,el,tl,cl,ol,rl,ul,pl],64)};export default u; diff --git a/assets/ch07-xray-server.html.eeae1829.js b/assets/ch07-xray-server.html.af443c4d.js similarity index 99% rename from assets/ch07-xray-server.html.eeae1829.js rename to assets/ch07-xray-server.html.af443c4d.js index edffea692..d6cfd174e 100644 --- a/assets/ch07-xray-server.html.eeae1829.js +++ b/assets/ch07-xray-server.html.af443c4d.js @@ -1 +1 @@ -import{r as n,o as s,c as l,a,b as e,w as t,F as c,e as o,d as r}from"./app.755d843f.js";const u={},p=a("h1",{id:"【第-7-章】xray-服务器篇",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#【第-7-章】xray-服务器篇","aria-hidden":"true"},"#"),o(" 【第 7 章】Xray 服务器篇")],-1),i=a("h2",{id:"_7-1-博观而约取-厚积而薄发",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-1-博观而约取-厚积而薄发","aria-hidden":"true"},"#"),o(" 7.1 博观而约取,厚积而薄发")],-1),b=a("p",null,"本文撰写过程中,大佬开玩笑的吐槽到:你这教程,居然连载了 6 章都还没到 Xray,不知道的还以为你是“手把手教你建网站”教程呢。(我竟无法反驳.jpg!)",-1),d=a("p",null,[o("其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连"),a("code",null,"nano"),o("都无法正确使用,也不会用"),a("code",null,"WinSCP"),o(",远程手写编辑出来的"),a("code",null,"config.json"),o("自然错误百出,连查错也变得举步维艰。")],-1),m=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Warning"),a("p",null,"经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray 时会有一种【水到渠成】的轻快感觉。")],-1),g=a("p",null,"后面要做的事情非常简单:",-1),k=a("ol",null,[a("li",null,"安装"),a("li",null,[o("配置(如安装 TLS 证书、"),a("code",null,"config.json"),o(")")]),a("li",null,"运行"),a("li",null,[o("优化(如更新内核、开启"),a("code",null,"bbr"),o("、网站"),a("code",null,"http"),o("访问自动跳转"),a("code",null,"https"),o("等)")])],-1),h=a("h2",{id:"_7-2-安装-xray",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-2-安装-xray","aria-hidden":"true"},"#"),o(" 7.2 安装 Xray")],-1),y=o("首先,Xray 的官方载体,就是 "),x={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},v=o("xray-core"),f=o(" 开源项目(基于 "),_=a("code",null,"MPL 2.0",-1),X=o(" 开源协议)生成的二进制程序。你把这个二进制放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。主要区别来源于【配置】。"),B=o("安装时,直接使用官方安装脚本就很简单直接。它提供了多种安装选项,有兴趣的可以去官方的"),w={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},S=o("安装脚本仓库"),L=o("中看看脚本的说明,"),R=a("strong",null,"本文使用的是【非 root 用户】安装模式",-1),q=o("。"),T=a("p",null,"写本文时,安装脚本在使用非 root 账户时有一些小 bug,所以我决定正好把这几步分开操作,可以顺便说明一下 Linux 下的删除命令。",-1),D=a("ol",null,[a("li",null,[a("p",null,"小小白白 Linux 基础命令:"),a("table",null,[a("thead",null,[a("tr",null,[a("th",{style:{"text-align":"center"}},"编号"),a("th",{style:{"text-align":"center"}},"命令名称"),a("th",{style:{"text-align":"center"}},"命令说明")])]),a("tbody",null,[a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-14")]),a("td",{style:{"text-align":"center"}},[a("code",null,"rm")]),a("td",{style:{"text-align":"center"}},"删除命令")])])])]),a("li",null,[a("p",null,"将安装脚本下载至本地:"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"wget"),o(" https://github.com/XTLS/Xray-install/raw/main/install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"执行安装命令"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"bash"),o(" install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"使用完成之后可以删除该脚本"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"rm"),o(" ~/install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Warning"),a("p",null,[o("使用 "),a("code",null,"rm"),o(" 命令删除文件的时候,默认其实就是删除现在所在的文件夹下的文件。但是,"),a("strong",null,"我依然写了完整的路径"),o(": "),a("code",null,"~/install-release.sh"),o(",这是我使用 "),a("code",null,"rm"),o(" 时的一个安全习惯、也是我把安装分成几步之后想强调一下的内容。如果你听过一些“程序员从删库到跑路”之类的段子,大概就知道为什么了。")])])]),a("li",null,[a("p",null,"完整流程演示如下:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img01-xray-install.39750018.gif",alt:"Xray服务器端安装流程演示"})])])],-1),P=a("h2",{id:"_7-3-给-xray-配置-tls-证书",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-3-给-xray-配置-tls-证书","aria-hidden":"true"},"#"),o(" 7.3 给 Xray 配置 TLS 证书")],-1),E=o("虽然我们前面已经申请好了 TLS 证书,但是按照 "),j={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"},N=a("code",null,"acme.sh",-1),I=o("的官方说明"),U=o(",申请后的证书不建议直接使用。正确的方法是使用 "),V=a("code",null,"--install-cert",-1),F=o(" 命令安装给需要的程序。我们现在就来把证书安装给 "),W=a("code",null,"xray-core",-1),A=o(" 使用。"),C=a("li",null,[a("p",null,"为了规避非 root 账户的各种潜在的权限困扰,我们在 vpsadmin 账户下建立一个证书文件夹"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"mkdir"),o(" ~/xray_cert\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),H=a("li",null,[a("p",null,[o("使用"),a("code",null,"acme.sh"),o("的"),a("code",null,"--install-cert"),o("正确安装(拷贝)证书文件")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("acme.sh --install-cert -d 二级域名.你的域名.com --ecc "),a("span",{class:"token punctuation"},"\\"),o("\n --fullchain-file ~/xray_cert/xray.crt "),a("span",{class:"token punctuation"},"\\"),o("\n --key-file ~/xray_cert/xray.key\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br")])])],-1),K=a("li",null,[a("p",null,[a("code",null,"xray.key"),o("文件默认对其他用户不可读,所以需要赋予其可读性权限")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"chmod"),o(" +r ~/xray_cert/xray.key\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),M=a("li",null,[a("p",null,"过程比较简单就不放动图了:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img02-xray-cert-install.4136686d.png",alt:"Xray服务器端安装流程演示"})])],-1),$=r('

acme.sh 会每 60 天检查一次证书并自动更新临期证书。但据我所知是它并不会自动将新证书安装给 xray-core,所以我们需要新增一个系统的自动周期任务来完成这一步。

  1. 小小白白 Linux 基础命令:
编号命令名称命令说明
cmd-15crontab -e编辑当前用户的定时任务
',3),G={start:"2"},O=a("li",null,[a("p",null,[o("建立一个脚本文件("),a("code",null,"xray-cert-renew.sh"),o(")")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"nano"),o(" ~/xray_cert/xray-cert-renew.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),z=r('

把下面的内容复制进去,记得替换你的真实域名,然后保存退出

#!/bin/bash\n\n/home/vpsadmin/.acme.sh/acme.sh --install-cert -d a-name.yourdomain.com --ecc --fullchain-file /home/vpsadmin/xray_cert/xray.crt --key-file /home/vpsadmin/xray_cert/xray.key\necho "Xray Certificates Renewed"\n\nchmod +r /home/vpsadmin/xray_cert/xray.key\necho "Read Permission Granted for Private Key"\n\nsudo systemctl restart xray\necho "Xray Restarted"\n
1
2
3
4
5
6
7
8
9
10
',2),J={class:"custom-container warning"},Q=a("p",{class:"custom-container-title"},"Warning",-1),Y=r("经大家提醒,acme.sh 有一个 reloadcmd 命令,可以在证书更新时自动执行特定命令,那么就可以指定自动给 Xray 安装证书,但因为 crontab 是 Linux 系统中一个非常有用、非常常用的功能,所以本文保留 crontab 的方式来更新 Xray 证书。(对 reloadcmd 感兴趣的同学可以查看 acme.sh 的",17),Z={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},nn=o("官方文档"),sn=o(")"),ln=a("p",null,[o("另外,录制动图时,脚本中没有加入重启 "),a("code",null,"Xray"),o(" 的命令,是因为 "),a("code",null,"Xray"),o(" 计划支持【证书热更新】功能,即 "),a("code",null,"Xray"),o(" 会自动识别证书更新并重载证书、无需手动重启。待功能加入后,我将适当修改 "),a("code",null,"config.json"),o(" 开启此设置,并删除脚本中的重启命令。")],-1),an=a("li",null,[a("p",null,"给这个文件增加【可执行】权限"),a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"chmod +x ~/xray_cert/xray-cert-renew.sh\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),en=a("li",null,[a("p",null,[o("运行 "),a("code",null,"crontab -e"),o(",添加一个自动任务【每月自动运行一次"),a("code",null,"xray-cert-renew.sh"),o("】 (注意不要加"),a("code",null,"sudo"),o(",因为我们增加的是"),a("code",null,"vpsadmin"),o(" 账户的自动任务。初次运行时会让你选择编辑器,当然是选择熟悉的"),a("code",null,"nano"),o("啦!)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"crontab"),o(" -e\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),tn=a("li",null,[a("p",null,"把下面的内容增加在文件最后,保存退出即可。"),a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"# 1:00am, 1st day each month, run `xray-cert-renew.sh`\n0 1 1 * * bash /home/vpsadmin/xray_cert/xray-cert-renew.sh\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])])],-1),cn=a("li",null,[a("p",null,"完整流程演示如下:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img03-crontab-cert-renew.ce7049d5.gif",alt:"每月自动给Xray安装证书"})])],-1),on=a("h2",{id:"_7-4-配置-xray",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-4-配置-xray","aria-hidden":"true"},"#"),o(" 7.4 配置 Xray")],-1),rn=o("首先,各种配置都可以参考"),un={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},pn=o("官方 VLESS 配置示例"),bn=o("。本文会基于官方示例,配置一个最精简的方式:【单 "),dn=a("code",null,"VLESS",-1),mn=o(" 协议入站 + "),gn=a("code",null,"80",-1),kn=o(" 端口回落】,满足大多数场景的最大速度及必要安全。"),hn=a("ol",null,[a("li",null,[a("p",null,[o("生成一个合法的 "),a("code",null,"UUID"),o(" 并保存备用("),a("code",null,"UUID"),o("可以简单粗暴的理解为像指纹一样几乎不会重复的 ID)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"xray uuid\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"建立日志文件及文件夹备用"),a("ol",null,[a("li",null,[a("p",null,"小小白白 Linux 基础命令:"),a("table",null,[a("thead",null,[a("tr",null,[a("th",{style:{"text-align":"center"}},"编号"),a("th",{style:{"text-align":"center"}},"命令名称"),a("th",{style:{"text-align":"center"}},"命令说明")])]),a("tbody",null,[a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-16")]),a("td",{style:{"text-align":"center"}},[a("code",null,"touch")]),a("td",{style:{"text-align":"center"}},"建立空白文件")])])])]),a("li",null,[a("p",null,[o("在"),a("code",null,"vpsadmin"),o("的文件夹内建立一个【日志专用文件夹】")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"mkdir"),o(" ~/xray_log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"生成所需的两个日志文件(访问日志、错误日志)"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"touch"),o(" ~/xray_log/access.log "),a("span",{class:"token operator"},"&&"),o(),a("span",{class:"token function"},"touch"),o(" ~/xray_log/error.log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Warning"),a("p",null,[o("这个位置不是"),a("code",null,"Xray"),o("标准的日志文件位置,放在这里是避免权限问题对新人的操作带来困扰。当你熟悉之后,建议回归默认位置: "),a("code",null,"/var/log/xray/access.log"),o(" 和 "),a("code",null,"/var/log/xray/error.log"),o(" 。")])])]),a("li",null,[a("p",null,[o("因为 Xray 默认是 nobody 用户使用,所以我们需要让其他用户也有“写”的权限("),a("code",null,"*.log"),o(" 就是所有文件后缀是"),a("code",null,"log"),o("的文件,此时"),a("code",null,"CLI"),o("界面的效率优势就逐渐出现了)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"chmod"),o(" a+w ~/xray_log/*.log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])])])]),a("li",null,[a("p",null,[o("使用"),a("code",null,"nano"),o("创建"),a("code",null,"Xray"),o("的配置文件")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /usr/local/etc/xray/config.json\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,[o("将下面的文件全部复制进去,并将之前生成的"),a("code",null,"UUID"),o("填入第 61 行 "),a("code",null,'"id": "",'),o(" 之中。(填好之后的样子是 "),a("code",null,'"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid"'),o(" ),本文的这个配置文件中增加了我的各种啰嗦注解,以方便你理解每一个配置模块的功能是什么。")]),a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token comment"},"// REFERENCE:"),o("\n"),a("span",{class:"token comment"},"// https://github.com/XTLS/Xray-examples"),o("\n"),a("span",{class:"token comment"},"// https://xtls.github.io/config/"),o("\n"),a("span",{class:"token comment"},"// 常用的 config 文件,不论服务器端还是客户端,都有 5 个部分。外加小小白解读:"),o("\n"),a("span",{class:"token comment"},"// ┌─ 1*log 日志设置 - 日志写什么,写哪里(出错时有据可查)"),o("\n"),a("span",{class:"token comment"},"// ├─ 2_dns DNS-设置 - DNS 怎么查(防 DNS 污染、防偷窥、避免国内外站匹配到国外服务器等)"),o("\n"),a("span",{class:"token comment"},"// ├─ 3_routing 分流设置 - 流量怎么分类处理(是否过滤广告、是否国内外分流)"),o("\n"),a("span",{class:"token comment"},"// ├─ 4_inbounds 入站设置 - 什么流量可以流入 Xray"),o("\n"),a("span",{class:"token comment"},"// └─ 5_outbounds 出站设置 - 流出 Xray 的流量往哪里去"),o("\n"),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token comment"},"// 1\\_日志设置"),o("\n "),a("span",{class:"token property"},'"log"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"loglevel"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"warning"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},'// 内容从少到多: "none", "error", "warning", "info", "debug"'),o("\n "),a("span",{class:"token property"},'"access"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_log/access.log"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 访问记录"),o("\n "),a("span",{class:"token property"},'"error"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_log/error.log"'),o(),a("span",{class:"token comment"},"// 错误记录"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 2_DNS 设置"),o("\n "),a("span",{class:"token property"},'"dns"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"servers"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"https+local://1.1.1.1/dns-query"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 首选 1.1.1.1 的 DoH 查询,牺牲速度但可防止 ISP 偷窥"),o("\n "),a("span",{class:"token string"},'"localhost"'),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 3*分流设置"),o("\n "),a("span",{class:"token property"},'"routing"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"domainStrategy"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"IPIfNonMatch"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"rules"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token comment"},"// 3.1 防止服务器本地流转问题:如内网被攻击或滥用、错误的本地回环等"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"ip"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"geoip:private"'),o(),a("span",{class:"token comment"},'// 分流条件:geoip 文件内,名为"private"的规则(本地)'),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o(),a("span",{class:"token comment"},'// 分流策略:交给出站"block"处理(黑洞屏蔽)'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token comment"},"// 3.2 防止服务器直连国内"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"ip"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),a("span",{class:"token string"},'"geoip:cn"'),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 3.3 屏蔽广告"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"domain"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"geosite:category-ads-all"'),o(),a("span",{class:"token comment"},'// 分流条件:geosite 文件内,名为"category-ads-all"的规则(各种广告域名)'),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o(),a("span",{class:"token comment"},'// 分流策略:交给出站"block"处理(黑洞屏蔽)'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 4*入站设置"),o("\n "),a("span",{class:"token comment"},"// 4.1 这里只写了一个最简单的 vless+xtls 的入站,因为这是 Xray 最强大的模式。如有其他需要,请根据模版自行添加。"),o("\n "),a("span",{class:"token property"},'"inbounds"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"443"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"vless"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"clients"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"id"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'""'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 填写你的 UUID"),o("\n "),a("span",{class:"token property"},'"flow"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"xtls-rprx-vision"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"level"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"0"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"email"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"vpsadmin@yourdomain.com"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"decryption"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"none"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"fallbacks"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"80"),o(),a("span",{class:"token comment"},"// 默认回落到防探测的代理"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"tcp"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"security"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"tls"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"tlsSettings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"alpn"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"http/1.1"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"certificates"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"certificateFile"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_cert/xray.crt"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"keyFile"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_cert/xray.key"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 5*出站设置"),o("\n "),a("span",{class:"token property"},'"outbounds"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token comment"},"// 5.1 第一个出站是默认规则,freedom 就是对外直连(vps 已经是外网,所以直连)"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"tag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"direct"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"freedom"'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 5.2 屏蔽规则,blackhole 协议就是把流量导入到黑洞里(屏蔽)"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"tag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"blackhole"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n"),a("span",{class:"token punctuation"},"}"),o("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br"),a("span",{class:"line-number"},"37"),a("br"),a("span",{class:"line-number"},"38"),a("br"),a("span",{class:"line-number"},"39"),a("br"),a("span",{class:"line-number"},"40"),a("br"),a("span",{class:"line-number"},"41"),a("br"),a("span",{class:"line-number"},"42"),a("br"),a("span",{class:"line-number"},"43"),a("br"),a("span",{class:"line-number"},"44"),a("br"),a("span",{class:"line-number"},"45"),a("br"),a("span",{class:"line-number"},"46"),a("br"),a("span",{class:"line-number"},"47"),a("br"),a("span",{class:"line-number"},"48"),a("br"),a("span",{class:"line-number"},"49"),a("br"),a("span",{class:"line-number"},"50"),a("br"),a("span",{class:"line-number"},"51"),a("br"),a("span",{class:"line-number"},"52"),a("br"),a("span",{class:"line-number"},"53"),a("br"),a("span",{class:"line-number"},"54"),a("br"),a("span",{class:"line-number"},"55"),a("br"),a("span",{class:"line-number"},"56"),a("br"),a("span",{class:"line-number"},"57"),a("br"),a("span",{class:"line-number"},"58"),a("br"),a("span",{class:"line-number"},"59"),a("br"),a("span",{class:"line-number"},"60"),a("br"),a("span",{class:"line-number"},"61"),a("br"),a("span",{class:"line-number"},"62"),a("br"),a("span",{class:"line-number"},"63"),a("br"),a("span",{class:"line-number"},"64"),a("br"),a("span",{class:"line-number"},"65"),a("br"),a("span",{class:"line-number"},"66"),a("br"),a("span",{class:"line-number"},"67"),a("br"),a("span",{class:"line-number"},"68"),a("br"),a("span",{class:"line-number"},"69"),a("br"),a("span",{class:"line-number"},"70"),a("br"),a("span",{class:"line-number"},"71"),a("br"),a("span",{class:"line-number"},"72"),a("br"),a("span",{class:"line-number"},"73"),a("br"),a("span",{class:"line-number"},"74"),a("br"),a("span",{class:"line-number"},"75"),a("br"),a("span",{class:"line-number"},"76"),a("br"),a("span",{class:"line-number"},"77"),a("br"),a("span",{class:"line-number"},"78"),a("br"),a("span",{class:"line-number"},"79"),a("br"),a("span",{class:"line-number"},"80"),a("br"),a("span",{class:"line-number"},"81"),a("br"),a("span",{class:"line-number"},"82"),a("br"),a("span",{class:"line-number"},"83"),a("br"),a("span",{class:"line-number"},"84"),a("br"),a("span",{class:"line-number"},"85"),a("br"),a("span",{class:"line-number"},"86"),a("br"),a("span",{class:"line-number"},"87"),a("br"),a("span",{class:"line-number"},"88"),a("br"),a("span",{class:"line-number"},"89"),a("br"),a("span",{class:"line-number"},"90"),a("br"),a("span",{class:"line-number"},"91"),a("br"),a("span",{class:"line-number"},"92"),a("br"),a("span",{class:"line-number"},"93"),a("br"),a("span",{class:"line-number"},"94"),a("br"),a("span",{class:"line-number"},"95"),a("br"),a("span",{class:"line-number"},"96"),a("br"),a("span",{class:"line-number"},"97"),a("br"),a("span",{class:"line-number"},"98"),a("br"),a("span",{class:"line-number"},"99"),a("br"),a("span",{class:"line-number"},"100"),a("br"),a("span",{class:"line-number"},"101"),a("br"),a("span",{class:"line-number"},"102"),a("br")])])])],-1),yn=a("ol",{start:"5"},[a("li",null,[o("完整流程演示如下: "),a("img",{src:"/Xray-docs-next/assets/ch07-img04-xray-log-and-config.1876d557.gif",alt:"创建日志文件及配置文件"})])],-1),xn=a("h2",{id:"_7-5-启动-xray-服务-并查看服务状态",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-5-启动-xray-服务-并查看服务状态","aria-hidden":"true"},"#"),o(" 7.5 启动 Xray 服务!!(并查看服务状态)")],-1),vn=a("p",null,[o("如果你是跟随本文一步步设置过来,其实就已经避开了最常见"),a("strong",null,"日志文件权限不足"),o("、"),a("strong",null,"证书文件权限不足"),o(" 这两个大坑。那么现在运行"),a("code",null,"Xray"),o("自然应该无比顺利。")],-1),fn=a("ol",null,[a("li",null,[o("输入下面的命令,享受启动"),a("code",null,"Xray"),o("的历史性时刻吧!!!")])],-1),_n=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl start xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Xn=a("ol",{start:"2"},[a("li",null,[o("仅仅"),a("code",null,"start"),o("我们并不能确定是否成功的开启了 Xray 的服务,要确定它的状态,就要用到下面的命令。")])],-1),Bn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl status xray\n\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])],-1),wn=a("p",null,[o("看到那个绿色的、令人愉悦的 "),a("code",null,"active (running)"),o(" 了吗?它就是说 "),a("code",null,"Xray"),o(" 已经在正确的运行了")],-1),Sn=a("ol",{start:"3"},[a("li",null,"完整流程演示如下:")],-1),Ln=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img05-xray-start-and-status.b77f6ab3.gif",alt:"启动并查看Xray运行状态"})],-1),Rn=a("h2",{id:"_7-6-回顾-systemd-进行基本的服务管理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-6-回顾-systemd-进行基本的服务管理","aria-hidden":"true"},"#"),o(" 7.6 回顾 "),a("code",null,"systemd"),o(" 进行基本的服务管理")],-1),qn=a("p",null,[o("到现在为止,我们已经使用过了"),a("code",null,"systemctl"),o("相关的"),a("code",null,"start"),o(", "),a("code",null,"status"),o(", "),a("code",null,"reload"),o(" 等命令,这些都是基于"),a("code",null,"systemd"),o("管理模块对 Linux 系统中各种服务进行管理的通用命令。现在正好熟悉一下相关的其他几个命令。")],-1),Tn=a("ol",null,[a("li",null,[o("若你需要暂时关闭 "),a("code",null,"Xray"),o(" 的服务,那就用"),a("code",null,"stop"),o("命令")])],-1),Dn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl stop xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Pn=a("ol",{start:"2"},[a("li",null,[o("若你需要重启"),a("code",null,"Xray"),o("的服务,那就用"),a("code",null,"restart"),o("命令")])],-1),En=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),jn=a("ol",{start:"3"},[a("li",null,[o("若你需要禁用"),a("code",null,"Xray"),o("的服务(电脑重启后禁止 Xray 自动运行),那就用"),a("code",null,"disable"),o("命令")])],-1),Nn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl disable xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),In=a("ol",{start:"4"},[a("li",null,[o("若你需要启用"),a("code",null,"Xray"),o("的服务(电脑重启后确保 Xray 自动运行),那就用"),a("code",null,"enable"),o("命令")])],-1),Un=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl "),a("span",{class:"token builtin class-name"},"enable"),o(" xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Vn=a("h2",{id:"_7-7-服务器优化之一-开启-bbr",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-7-服务器优化之一-开启-bbr","aria-hidden":"true"},"#"),o(" 7.7 服务器优化之一:开启 BBR")],-1),Fn=a("ol",null,[a("li",null,[o("传说中的"),a("code",null,"BBR")])],-1),Wn=a("p",null,[o("我相信,你在搜索各种科学上网技术的时候,肯定不止一次的听过"),a("code",null,"bbr"),o("这个东西,在各种博客添油加醋之下,让人觉得它神乎其神。更有"),a("code",null,"bbrplus"),o(", "),a("code",null,"bbr2"),o(", "),a("code",null,"魔改bbr"),o(" 等一大堆衍生品。仿佛神油一般,用了就能野鸡线路变专线。")],-1),An=a("p",null,"那么,这东西究竟是什么?它有没有用?又该用哪一个版本呢?",-1),Cn=a("ol",{start:"2"},[a("li",null,[o("实际的"),a("code",null,"BBR")])],-1),Hn=a("p",null,[a("strong",null,"BBR"),o(" = "),a("strong",null,"B"),o("ottleneck "),a("strong",null,"B"),o("andwidth and "),a("strong",null,"R"),o("ound-trip propagation time,是一种 TCP 的"),a("strong",null,"拥塞控制算法"),o("。简单粗暴的理解就是"),a("strong",null,"数据流量的交通管理"),o(" :当公路不再塞车的时候,每辆车自然就能保持较快的车速了。")],-1),Kn=a("p",null,[o("那么它有没有用呢?一般而言,"),a("code",null,"有BBR"),o(" 和 "),a("code",null,"没有BBR"),o(" 会有可以感知的差别(速度、稳定性、延迟方面都会有一些改善),所以 "),a("strong",null,[o("【非常建议开启 "),a("code",null,"BBR"),o("】")]),o("。")],-1),Mn=a("p",null,[o("但开启之后,"),a("code",null,"BBR"),o(" 在 "),a("code",null,"4.x"),o(" 和 "),a("code",null,"5.x"),o(" 之间的差异往往比较微妙、见仁见智,造成体验差别的决定性因素仍然是线路质量。所以 "),a("strong",null,"【不必纠结版本、不必盲目追新、跟随你的发行版更新内核即可】")],-1),$n=a("ol",{start:"3"},[a("li",null,[a("code",null,"bbrplus"),o(", "),a("code",null,"bbr2"),o(", "),a("code",null,"魔改bbr"),o(" 和其他各种听起来就酷炫的版本是不是更好?")])],-1),Gn=a("p",null,[o("一句话:"),a("strong",null,"不是!不要用这些!这些都为了吸引眼球乱起的名字!")],-1),On=a("p",null,[a("code",null,"BBR"),o(" 的更新和发布,都是跟随 Linux 的内核("),a("code",null,"Kernel"),o(")进行的。换言之,只要你用的是比较新的内核,就自然会使用到新版"),a("code",null,"BBR"),o("。")],-1),zn=a("p",null,[o("而这些名字看起来很酷炫的东西,说白了就是仍未正式发布的、尚在测试阶段的内核及其对应的"),a("code",null,"BBR"),o("版本。这些脚本也仅仅就是通过下载预览版的内核(甚至第三方魔改内核)来率先开启而已。")],-1),Jn=a("p",null,[o("内核的稳定是一台服务器稳定运行的基石。"),a("strong",null,"【BBR 测试版带来的细微性能差异绝对不值得更换不稳定的内核。】"),o(" 请选择你所在的 Linux 发行版所支持的最新内核,这样可以最大限度的保持服务器的长期稳定和兼容。")],-1),Qn=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Warning"),a("p",null,[o("所谓魔改"),a("code",null,"bbr"),o("的【领先】是有非常强的时效性的。比如很多 "),a("code",null,"bbrplus"),o(" 脚本,因为几年来都没有更新,到现在还会把你的内核换成 "),a("code",null,"4.19"),o(",要知道现在稳定如 Debian 已经是 "),a("code",null,"5.9"),o(" 的时代了,那么这个脚本放在 2018 年 1 月也许领先了一点,到 2018 年 10 月 4.19 正发布时就已经失去了意义,放在现在甚至可以说是完完全全的【降级】和【劣化】")])],-1),Yn=a("ol",{start:"4"},[a("li",null,[a("code",null,"fq"),o(", "),a("code",null,"fq_codel"),o(", "),a("code",null,"fq_pie"),o(", "),a("code",null,"cake"),o("和其他算法哪个好?")])],-1),Zn=a("p",null,[o("一句话:"),a("strong",null,[o("看不懂的话,请保持"),a("code",null,"fq"),o(",足够、且不会劣化你的线路")])],-1),ns=a("ol",{start:"5"},[a("li",null,"锐速、Finalspeed、LotServer 和其他“加速工具”")],-1),ss=a("p",null,[o("一句话:"),a("strong",null,"不要用这些!把他们丢进历史的垃圾桶吧!")],-1),ls=a("p",null,"它能解决的也只有丢包率的问题。不太准确的比喻,就是本来你用一辆车送你的货,有时候车半路就坏了(丢包),用了这些以后,你直接派出 3 份一样的货,让三辆车同时送,只要有一辆没坏就能送到。马路上都是你的车,自然就能把别人挤下去。但可想而知,你挤别人的时候,别人也会来挤你,而整个机房的出口道路一共就那么宽,最终势必就变成集体大堵车了。",-1),as=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("它们的原理不是算法优化、不是提速、大多数是简单粗暴的"),a("strong",null,"多倍发包"),o("。对于【丢包率非常高】的差线路可能有一点作用,但【对丢包率低的好线路没有任何优化作用,反而会成倍的消耗你的流量】,进而造成服务器和你的邻居不必要的压力。")]),a("p",null,"如果你的线路真的丢包率奇高,真正靠谱的解决方案是【换线路】。")],-1),es=a("ol",{start:"6"},[a("li",null,[a("p",null,[o("啰嗦了这么多,就是因为围绕 "),a("code",null,"BBR"),o(" 忽悠小白的错误概念和坑人脚本实在是太多了。我希望你们现在对 "),a("code",null,"BBR"),o(" 有了相对清晰的理解。接下来,我们就动手安装最新的 Debian 内核并开启"),a("code",null,"BBR"),o(" 吧!(真的很简单)")])]),a("li",null,[a("p",null,[o("给 Debian 10 添加官方 "),a("code",null,"backports"),o(" 源,获取更新的软件库")])])],-1),ts=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/apt/sources.list\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),cs=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("本文以 Debian 10 为例,所以使用 "),a("code",null,"/etc/apt/sources.list"),o(" 仍无问题,但如果你并不是根据本文从头开始,或者使用了其他 Linux 发行版,那么建议你建立 "),a("code",null,"/etc/apt/sources.list.d/"),o(" 文件夹,并在这个文件夹内建立自己的配置文件,形如 "),a("code",null,"/etc/apt/sources.list.d/vpsadmin.list"),o(" ,以此保证兼容性,也可避免默认文件在不可预见的情况下被覆盖而导致配置丢失。")])],-1),os=a("ol",{start:"2"},[a("li",null,"然后把下面这一条加在最后,并保存退出。")],-1),rs=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"deb http://deb.debian.org/debian buster-backports main\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),us=a("ol",{start:"3"},[a("li",null,"刷新软件库并查询 Debian 官方的最新版内核并安装。请务必安装你的 VPS 对应的版本(本文以比较常见的【amd64】为例)。")],-1),ps=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"apt"),o(" update "),a("span",{class:"token operator"},"&&"),o(),a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"apt"),o(" -t buster-backports "),a("span",{class:"token function"},"install"),o(" linux-image-amd64\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),is=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,[o("如果你的 VPS 支持,可以尝试【云服务器专用内核】"),a("code",null,"linux-image-cloud-amd64"),o(",优点就是精简、资源占用低,缺点嘛是有同学反馈不支持的系统强行安装会导致无法开机(Kernel 无法识别)。")]),a("p",null,"为了避免无法识别的悲剧,请确保:"),a("ul",null,[a("li",null,"尝试前做一个系统快照,或者"),a("li",null,[o("你有 "),a("code",null,"vnc"),o(" 可以救场(并且你知道怎么用)")])])],-1),bs=a("ol",{start:"4"},[a("li",null,[o("修改 "),a("code",null,"kernel"),o(" 参数配置文件 "),a("code",null,"sysctl.conf"),o(" 并指定开启 "),a("code",null,"BBR")])],-1),ds=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/sysctl.conf\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),ms=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("本文以 Debian 10 为例,所以使用 "),a("code",null,"/etc/sysctl.conf"),o(" 仍无问题,但如果你并不是跟着本文从头开始,或者使用了其他 Linux 发行版,那么建议你建立 "),a("code",null,"/etc/sysctl.d/"),o(" 文件夹,并在这个文件夹内建立自己的配置文件,形如 "),a("code",null,"/etc/sysctl.d/vpsadmin.conf"),o(",以此保证兼容性,因为部分发行版在 "),a("code",null,"systemd"),o(" 207 版本之后便不再从 "),a("code",null,"/etc/sysctl.conf"),o(" 读取参数。使用自定义配置文件也可避免默认文件在不可预见的情况下被覆盖而导致配置丢失。")])],-1),gs=a("ol",{start:"5"},[a("li",null,"把下面的内容添加进去")],-1),ks=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"net.core.default_qdisc=fq\nnet.ipv4.tcp_congestion_control=bbr\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])],-1),hs=a("ol",{start:"6"},[a("li",null,[o("重启 VPS、使内核更新和"),a("code",null,"BBR"),o("设置都生效")])],-1),ys=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"reboot"),o("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),xs=a("ol",{start:"7"},[a("li",null,"完整流程演示如下:")],-1),vs=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"啰嗦君"),a("p",null,[o("因为我做展示的 VPS 支持云服务器专用内核,所以动图中我用了 "),a("code",null,"linux-image-cloud-amd64"),o(" 。如果你不确定你的 VPS 是否支持,那请务必按照第 3 步的命令,使用常规内核 "),a("code",null,"linux-image-amd64"),o("。")])],-1),fs=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img06-bbr-proper.496ecbe2.gif",alt:"更新Debian内核并开启"})],-1),_s=a("ol",{start:"8"},[a("li",null,[o("确认"),a("code",null,"BBR"),o("开启")])],-1),Xs=a("p",null,[o("如果你想确认 "),a("code",null,"BBR"),o(" 是否正确开启,可以使用下面的命令:")],-1),Bs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("lsmod "),a("span",{class:"token operator"},"|"),o(),a("span",{class:"token function"},"grep"),o(" bbr\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),ws=a("p",null,"此时应该返回这样的结果:",-1),Ss=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"tcp_bbr\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ls=a("p",null,[o("如果你想确认 "),a("code",null,"fq"),o(" 算法是否正确开启,可以使用下面的命令:")],-1),Rs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("lsmod "),a("span",{class:"token operator"},"|"),o(),a("span",{class:"token function"},"grep"),o(" fq\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),qs=a("p",null,"此时应该返回这样的结果:",-1),Ts=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"sch_fq\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ds=a("h2",{id:"_7-8-服务器优化之二-开启-http-自动跳转-https",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-8-服务器优化之二-开启-http-自动跳转-https","aria-hidden":"true"},"#"),o(" 7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS")],-1),Ps=a("ol",null,[a("li",null,[o("之前我们已经搭建了 "),a("code",null,"80"),o(" 端口的 "),a("code",null,"http"),o(" 网页,并以此申请了 TLS 证书。")])],-1),Es=a("p",null,[o("但如果你尝试过用浏览器访问我们的这个界面,就会发现 "),a("code",null,"http"),o(" 访问并不会像大多数网站一样自动升级为 "),a("code",null,"https"),o(" 访问。换言之,我们现在的设置下,"),a("code",null,"http(80)"),o(" 和 "),a("code",null,"https(443)"),o(" 之间完全是独立的。如果要解决这个问题,就需要做一些修改。")],-1),js=a("ol",{start:"2"},[a("li",null,"编辑 Nginx 的配置文件")],-1),Ns=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/nginx/nginx.conf\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Is=a("ol",{start:"3"},[a("li",null,[o("在我们设置过的 80 端口 Server 中加入下面的语句,并保存退出(可同时删除"),a("code",null,"root"),o("和"),a("code",null,"index"),o("两行)")])],-1),Us=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"return 301 https://$http_host$request_uri;\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Vs=a("ol",{start:"4"},[a("li",null,[o("在与 "),a("code",null,"80"),o(" 端口同级的位置增加一个本地端口监听来提供网页展示。本文以 "),a("code",null,"8080"),o(" 端口做演示。(可以是任意端口)")])],-1),Fs=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,'server {\n listen 127.0.0.1:8080;\n root /home/vpsadmin/www/webpage;\n index index.html;\n add_header Strict-Transport-Security "max-age=63072000" always;\n}\n')]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br")])],-1),Ws=a("ol",{start:"5"},[a("li",null,"重启 Nginx 服务")],-1),As=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart nginx\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Cs=a("ol",{start:"6"},[a("li",null,[o("修改 Xray 的回落设置,将回落从 "),a("code",null,"80"),o(" 端口改为 "),a("code",null,"8080"),o(" 端口。(找到 "),a("code",null,'"dest": 80'),o(", 并改成 "),a("code",null,'"dest": 8080'),o(")")])],-1),Hs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /usr/local/etc/xray/config.json\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ks=a("ol",{start:"7"},[a("li",null,[o("重启 "),a("code",null,"Xray"),o(" 服务,即完成了设置")])],-1),Ms=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),$s=a("ol",{start:"8"},[a("li",null,"完整流程演示如下:")],-1),Gs=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img07-http-to-https.a87dc99c.gif",alt:"http自动跳转https"})],-1),Os=a("ol",{start:"9"},[a("li",null,[o("当你输入 "),a("code",null,"http://a-name.yourdomain.com"),o("的时候,它应该已经会自动跳转 https 了")])],-1),zs=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img08-http-to-https-check.bc6ae06e.png",alt:"http自动跳转https生效"})],-1),Js=a("h2",{id:"_7-9-服务器优化之三-更丰富的回落",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-9-服务器优化之三-更丰富的回落","aria-hidden":"true"},"#"),o(" 7.9 服务器优化之三:更丰富的回落")],-1),Qs=o("如果你需要更丰富的回落功能,可以参考 "),Ys=o("《回落 (fallbacks) 功能简析》"),Zs=a("h2",{id:"_7-10-你的进度",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-10-你的进度","aria-hidden":"true"},"#"),o(" 7.10 你的进度")],-1),nl=a("p",null,"恭喜!!到这一步,你已经拥有了可以正常科学上网的服务器、同时也有了可以防止主动探测攻击的伪装网站。接下来,只要给你的客户端装上合适的软件,就可以享受顺畅的网络了!",-1),sl=a("blockquote",null,[a("p",null,"⬛⬛⬛⬛⬛⬛⬛⬜ 87.5%")],-1),ll=a("h2",{id:"_7-11-重要勘误",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-11-重要勘误","aria-hidden":"true"},"#"),o(" 7.11 重要勘误")],-1),al=a("ol",null,[a("li",null,[o("初版中"),a("code",null,"Xray"),o("配置文件"),a("code",null,"config.json"),o("文件夹位置错误。若你已经根据之前的位置进行了操作,"),a("code",null,"Xray"),o("会无法正确启动。故勘误说明于此,请自查,造成不便十分抱歉!")])],-1),el=a("ul",null,[a("li",null,[o("正确位置:"),a("code",null,"/usr/local/etc/xray/config.json")]),a("li",null,[o("错误位置:"),a("code",null,"/usr/local/etc/config.json")])],-1),tl=a("p",null,"受影响章节:",-1),cl=a("ul",null,[a("li",null,[o("7.4 配置"),a("code",null,"Xray"),o(" - 3. 使用"),a("code",null,"nano"),o("创建"),a("code",null,"Xray"),o("的配置文件")]),a("li",null,[o("7.8 服务器优化之二 - 6. 修改"),a("code",null,"Xray"),o("的回落设置")])],-1),ol=a("ol",{start:"2"},[a("li",null,[o("初版中修改"),a("code",null,"Nginx"),o("配置文件"),a("code",null,"nginx.conf"),o("时内容错误(网页文件夹位置错误),若你已经根据之前的位置进行了操作,"),a("code",null,"Nginx"),o("会无法找到正确的网站。请自查,造成不便十分抱歉!")])],-1),rl=a("ul",null,[a("li",null,[o("正确文件夹位置:"),a("code",null,"root /home/vpsadmin/www/webpage;")]),a("li",null,[o("错误文件夹位置:"),a("code",null,"root /var/www/website/html")])],-1),ul=a("p",null,"受影响章节:",-1),pl=a("ul",null,[a("li",null,[o("7.8 服务器优化之二 - 4. 在与 "),a("code",null,"80"),o(" 端口同级的位置增加一个本地端口监听来提供网页展示")])],-1);u.render=function(o,r){const u=n("OutboundLink"),il=n("RouterLink");return s(),l(c,null,[p,i,b,d,m,g,k,h,a("p",null,[y,a("a",x,[v,e(u)]),f,_,X]),a("p",null,[B,a("a",w,[S,e(u)]),L,R,q]),T,D,P,a("p",null,[E,a("a",j,[N,I,e(u)]),U,V,F,W,A]),a("ol",null,[C,H,K,M,a("li",null,[$,a("ol",G,[O,a("li",null,[z,a("div",J,[Q,a("p",null,[Y,a("a",Z,[nn,e(u)]),sn]),ln])]),an,en,tn,cn])])]),on,a("p",null,[rn,a("a",un,[pn,e(u)]),bn,dn,mn,gn,kn]),hn,yn,xn,vn,fn,_n,Xn,Bn,wn,Sn,Ln,Rn,qn,Tn,Dn,Pn,En,jn,Nn,In,Un,Vn,Fn,Wn,An,Cn,Hn,Kn,Mn,$n,Gn,On,zn,Jn,Qn,Yn,Zn,ns,ss,ls,as,es,ts,cs,os,rs,us,ps,is,bs,ds,ms,gs,ks,hs,ys,xs,vs,fs,_s,Xs,Bs,ws,Ss,Ls,Rs,qs,Ts,Ds,Ps,Es,js,Ns,Is,Us,Vs,Fs,Ws,As,Cs,Hs,Ks,Ms,$s,Gs,Os,zs,Js,a("p",null,[Qs,e(il,{to:"/en/document/level-1/fallbacks-lv1/"},{default:t((()=>[Ys])),_:1})]),Zs,nl,sl,ll,al,el,tl,cl,ol,rl,ul,pl],64)};export default u; +import{r as n,o as s,c as l,a,b as e,w as t,F as c,e as o,d as r}from"./app.48111a85.js";const u={},p=a("h1",{id:"【第-7-章】xray-服务器篇",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#【第-7-章】xray-服务器篇","aria-hidden":"true"},"#"),o(" 【第 7 章】Xray 服务器篇")],-1),i=a("h2",{id:"_7-1-博观而约取-厚积而薄发",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-1-博观而约取-厚积而薄发","aria-hidden":"true"},"#"),o(" 7.1 博观而约取,厚积而薄发")],-1),b=a("p",null,"本文撰写过程中,大佬开玩笑的吐槽到:你这教程,居然连载了 6 章都还没到 Xray,不知道的还以为你是“手把手教你建网站”教程呢。(我竟无法反驳.jpg!)",-1),d=a("p",null,[o("其实这样的结构是我多番思考之后的决定,毕竟只有打好基础,才能在后面事半功倍快速反超。我在群里看到许多新人连"),a("code",null,"nano"),o("都无法正确使用,也不会用"),a("code",null,"WinSCP"),o(",远程手写编辑出来的"),a("code",null,"config.json"),o("自然错误百出,连查错也变得举步维艰。")],-1),m=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Warning"),a("p",null,"经过了前 6 章的准备,各位已经跟我一起翻越了 Linux 基本操作、VPS 远程管理、网页搭建、域名管理、证书申请等等几座大山。是不是回头看看,觉得其实非常简单呢?现在我们有了如此扎实的准备,接下来安装和配置 Xray 时会有一种【水到渠成】的轻快感觉。")],-1),g=a("p",null,"后面要做的事情非常简单:",-1),k=a("ol",null,[a("li",null,"安装"),a("li",null,[o("配置(如安装 TLS 证书、"),a("code",null,"config.json"),o(")")]),a("li",null,"运行"),a("li",null,[o("优化(如更新内核、开启"),a("code",null,"bbr"),o("、网站"),a("code",null,"http"),o("访问自动跳转"),a("code",null,"https"),o("等)")])],-1),h=a("h2",{id:"_7-2-安装-xray",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-2-安装-xray","aria-hidden":"true"},"#"),o(" 7.2 安装 Xray")],-1),y=o("首先,Xray 的官方载体,就是 "),x={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},v=o("xray-core"),f=o(" 开源项目(基于 "),_=a("code",null,"MPL 2.0",-1),X=o(" 开源协议)生成的二进制程序。你把这个二进制放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。主要区别来源于【配置】。"),B=o("安装时,直接使用官方安装脚本就很简单直接。它提供了多种安装选项,有兴趣的可以去官方的"),w={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},S=o("安装脚本仓库"),L=o("中看看脚本的说明,"),R=a("strong",null,"本文使用的是【非 root 用户】安装模式",-1),q=o("。"),T=a("p",null,"写本文时,安装脚本在使用非 root 账户时有一些小 bug,所以我决定正好把这几步分开操作,可以顺便说明一下 Linux 下的删除命令。",-1),D=a("ol",null,[a("li",null,[a("p",null,"小小白白 Linux 基础命令:"),a("table",null,[a("thead",null,[a("tr",null,[a("th",{style:{"text-align":"center"}},"编号"),a("th",{style:{"text-align":"center"}},"命令名称"),a("th",{style:{"text-align":"center"}},"命令说明")])]),a("tbody",null,[a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-14")]),a("td",{style:{"text-align":"center"}},[a("code",null,"rm")]),a("td",{style:{"text-align":"center"}},"删除命令")])])])]),a("li",null,[a("p",null,"将安装脚本下载至本地:"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"wget"),o(" https://github.com/XTLS/Xray-install/raw/main/install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"执行安装命令"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"bash"),o(" install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"使用完成之后可以删除该脚本"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"rm"),o(" ~/install-release.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Warning"),a("p",null,[o("使用 "),a("code",null,"rm"),o(" 命令删除文件的时候,默认其实就是删除现在所在的文件夹下的文件。但是,"),a("strong",null,"我依然写了完整的路径"),o(": "),a("code",null,"~/install-release.sh"),o(",这是我使用 "),a("code",null,"rm"),o(" 时的一个安全习惯、也是我把安装分成几步之后想强调一下的内容。如果你听过一些“程序员从删库到跑路”之类的段子,大概就知道为什么了。")])])]),a("li",null,[a("p",null,"完整流程演示如下:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img01-xray-install.39750018.gif",alt:"Xray服务器端安装流程演示"})])])],-1),P=a("h2",{id:"_7-3-给-xray-配置-tls-证书",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-3-给-xray-配置-tls-证书","aria-hidden":"true"},"#"),o(" 7.3 给 Xray 配置 TLS 证书")],-1),E=o("虽然我们前面已经申请好了 TLS 证书,但是按照 "),j={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"},N=a("code",null,"acme.sh",-1),I=o("的官方说明"),U=o(",申请后的证书不建议直接使用。正确的方法是使用 "),V=a("code",null,"--install-cert",-1),F=o(" 命令安装给需要的程序。我们现在就来把证书安装给 "),W=a("code",null,"xray-core",-1),A=o(" 使用。"),C=a("li",null,[a("p",null,"为了规避非 root 账户的各种潜在的权限困扰,我们在 vpsadmin 账户下建立一个证书文件夹"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"mkdir"),o(" ~/xray_cert\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),H=a("li",null,[a("p",null,[o("使用"),a("code",null,"acme.sh"),o("的"),a("code",null,"--install-cert"),o("正确安装(拷贝)证书文件")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("acme.sh --install-cert -d 二级域名.你的域名.com --ecc "),a("span",{class:"token punctuation"},"\\"),o("\n --fullchain-file ~/xray_cert/xray.crt "),a("span",{class:"token punctuation"},"\\"),o("\n --key-file ~/xray_cert/xray.key\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br")])])],-1),K=a("li",null,[a("p",null,[a("code",null,"xray.key"),o("文件默认对其他用户不可读,所以需要赋予其可读性权限")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"chmod"),o(" +r ~/xray_cert/xray.key\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),M=a("li",null,[a("p",null,"过程比较简单就不放动图了:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img02-xray-cert-install.4136686d.png",alt:"Xray服务器端安装流程演示"})])],-1),$=r('

acme.sh 会每 60 天检查一次证书并自动更新临期证书。但据我所知是它并不会自动将新证书安装给 xray-core,所以我们需要新增一个系统的自动周期任务来完成这一步。

  1. 小小白白 Linux 基础命令:
编号命令名称命令说明
cmd-15crontab -e编辑当前用户的定时任务
',3),G={start:"2"},O=a("li",null,[a("p",null,[o("建立一个脚本文件("),a("code",null,"xray-cert-renew.sh"),o(")")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"nano"),o(" ~/xray_cert/xray-cert-renew.sh\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),z=r('

把下面的内容复制进去,记得替换你的真实域名,然后保存退出

#!/bin/bash\n\n/home/vpsadmin/.acme.sh/acme.sh --install-cert -d a-name.yourdomain.com --ecc --fullchain-file /home/vpsadmin/xray_cert/xray.crt --key-file /home/vpsadmin/xray_cert/xray.key\necho "Xray Certificates Renewed"\n\nchmod +r /home/vpsadmin/xray_cert/xray.key\necho "Read Permission Granted for Private Key"\n\nsudo systemctl restart xray\necho "Xray Restarted"\n
1
2
3
4
5
6
7
8
9
10
',2),J={class:"custom-container warning"},Q=a("p",{class:"custom-container-title"},"Warning",-1),Y=r("经大家提醒,acme.sh 有一个 reloadcmd 命令,可以在证书更新时自动执行特定命令,那么就可以指定自动给 Xray 安装证书,但因为 crontab 是 Linux 系统中一个非常有用、非常常用的功能,所以本文保留 crontab 的方式来更新 Xray 证书。(对 reloadcmd 感兴趣的同学可以查看 acme.sh 的",17),Z={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},nn=o("官方文档"),sn=o(")"),ln=a("p",null,[o("另外,录制动图时,脚本中没有加入重启 "),a("code",null,"Xray"),o(" 的命令,是因为 "),a("code",null,"Xray"),o(" 计划支持【证书热更新】功能,即 "),a("code",null,"Xray"),o(" 会自动识别证书更新并重载证书、无需手动重启。待功能加入后,我将适当修改 "),a("code",null,"config.json"),o(" 开启此设置,并删除脚本中的重启命令。")],-1),an=a("li",null,[a("p",null,"给这个文件增加【可执行】权限"),a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"chmod +x ~/xray_cert/xray-cert-renew.sh\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),en=a("li",null,[a("p",null,[o("运行 "),a("code",null,"crontab -e"),o(",添加一个自动任务【每月自动运行一次"),a("code",null,"xray-cert-renew.sh"),o("】 (注意不要加"),a("code",null,"sudo"),o(",因为我们增加的是"),a("code",null,"vpsadmin"),o(" 账户的自动任务。初次运行时会让你选择编辑器,当然是选择熟悉的"),a("code",null,"nano"),o("啦!)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"crontab"),o(" -e\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])],-1),tn=a("li",null,[a("p",null,"把下面的内容增加在文件最后,保存退出即可。"),a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"# 1:00am, 1st day each month, run `xray-cert-renew.sh`\n0 1 1 * * bash /home/vpsadmin/xray_cert/xray-cert-renew.sh\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])])],-1),cn=a("li",null,[a("p",null,"完整流程演示如下:"),a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img03-crontab-cert-renew.ce7049d5.gif",alt:"每月自动给Xray安装证书"})])],-1),on=a("h2",{id:"_7-4-配置-xray",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-4-配置-xray","aria-hidden":"true"},"#"),o(" 7.4 配置 Xray")],-1),rn=o("首先,各种配置都可以参考"),un={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},pn=o("官方 VLESS 配置示例"),bn=o("。本文会基于官方示例,配置一个最精简的方式:【单 "),dn=a("code",null,"VLESS",-1),mn=o(" 协议入站 + "),gn=a("code",null,"80",-1),kn=o(" 端口回落】,满足大多数场景的最大速度及必要安全。"),hn=a("ol",null,[a("li",null,[a("p",null,[o("生成一个合法的 "),a("code",null,"UUID"),o(" 并保存备用("),a("code",null,"UUID"),o("可以简单粗暴的理解为像指纹一样几乎不会重复的 ID)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,"xray uuid\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"建立日志文件及文件夹备用"),a("ol",null,[a("li",null,[a("p",null,"小小白白 Linux 基础命令:"),a("table",null,[a("thead",null,[a("tr",null,[a("th",{style:{"text-align":"center"}},"编号"),a("th",{style:{"text-align":"center"}},"命令名称"),a("th",{style:{"text-align":"center"}},"命令说明")])]),a("tbody",null,[a("tr",null,[a("td",{style:{"text-align":"center"}},[a("code",null,"cmd-16")]),a("td",{style:{"text-align":"center"}},[a("code",null,"touch")]),a("td",{style:{"text-align":"center"}},"建立空白文件")])])])]),a("li",null,[a("p",null,[o("在"),a("code",null,"vpsadmin"),o("的文件夹内建立一个【日志专用文件夹】")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"mkdir"),o(" ~/xray_log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,"生成所需的两个日志文件(访问日志、错误日志)"),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"touch"),o(" ~/xray_log/access.log "),a("span",{class:"token operator"},"&&"),o(),a("span",{class:"token function"},"touch"),o(" ~/xray_log/error.log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])]),a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Warning"),a("p",null,[o("这个位置不是"),a("code",null,"Xray"),o("标准的日志文件位置,放在这里是避免权限问题对新人的操作带来困扰。当你熟悉之后,建议回归默认位置: "),a("code",null,"/var/log/xray/access.log"),o(" 和 "),a("code",null,"/var/log/xray/error.log"),o(" 。")])])]),a("li",null,[a("p",null,[o("因为 Xray 默认是 nobody 用户使用,所以我们需要让其他用户也有“写”的权限("),a("code",null,"*.log"),o(" 就是所有文件后缀是"),a("code",null,"log"),o("的文件,此时"),a("code",null,"CLI"),o("界面的效率优势就逐渐出现了)")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"chmod"),o(" a+w ~/xray_log/*.log\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])])])]),a("li",null,[a("p",null,[o("使用"),a("code",null,"nano"),o("创建"),a("code",null,"Xray"),o("的配置文件")]),a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /usr/local/etc/xray/config.json\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])])]),a("li",null,[a("p",null,[o("将下面的文件全部复制进去,并将之前生成的"),a("code",null,"UUID"),o("填入第 61 行 "),a("code",null,'"id": "",'),o(" 之中。(填好之后的样子是 "),a("code",null,'"id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid"'),o(" ),本文的这个配置文件中增加了我的各种啰嗦注解,以方便你理解每一个配置模块的功能是什么。")]),a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token comment"},"// REFERENCE:"),o("\n"),a("span",{class:"token comment"},"// https://github.com/XTLS/Xray-examples"),o("\n"),a("span",{class:"token comment"},"// https://xtls.github.io/config/"),o("\n"),a("span",{class:"token comment"},"// 常用的 config 文件,不论服务器端还是客户端,都有 5 个部分。外加小小白解读:"),o("\n"),a("span",{class:"token comment"},"// ┌─ 1*log 日志设置 - 日志写什么,写哪里(出错时有据可查)"),o("\n"),a("span",{class:"token comment"},"// ├─ 2_dns DNS-设置 - DNS 怎么查(防 DNS 污染、防偷窥、避免国内外站匹配到国外服务器等)"),o("\n"),a("span",{class:"token comment"},"// ├─ 3_routing 分流设置 - 流量怎么分类处理(是否过滤广告、是否国内外分流)"),o("\n"),a("span",{class:"token comment"},"// ├─ 4_inbounds 入站设置 - 什么流量可以流入 Xray"),o("\n"),a("span",{class:"token comment"},"// └─ 5_outbounds 出站设置 - 流出 Xray 的流量往哪里去"),o("\n"),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token comment"},"// 1\\_日志设置"),o("\n "),a("span",{class:"token property"},'"log"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"loglevel"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"warning"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},'// 内容从少到多: "none", "error", "warning", "info", "debug"'),o("\n "),a("span",{class:"token property"},'"access"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_log/access.log"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 访问记录"),o("\n "),a("span",{class:"token property"},'"error"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_log/error.log"'),o(),a("span",{class:"token comment"},"// 错误记录"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 2_DNS 设置"),o("\n "),a("span",{class:"token property"},'"dns"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"servers"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"https+local://1.1.1.1/dns-query"'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 首选 1.1.1.1 的 DoH 查询,牺牲速度但可防止 ISP 偷窥"),o("\n "),a("span",{class:"token string"},'"localhost"'),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 3*分流设置"),o("\n "),a("span",{class:"token property"},'"routing"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"domainStrategy"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"IPIfNonMatch"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"rules"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token comment"},"// 3.1 防止服务器本地流转问题:如内网被攻击或滥用、错误的本地回环等"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"ip"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"geoip:private"'),o(),a("span",{class:"token comment"},'// 分流条件:geoip 文件内,名为"private"的规则(本地)'),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o(),a("span",{class:"token comment"},'// 分流策略:交给出站"block"处理(黑洞屏蔽)'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token comment"},"// 3.2 防止服务器直连国内"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"ip"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),a("span",{class:"token string"},'"geoip:cn"'),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 3.3 屏蔽广告"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"type"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"field"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"domain"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token string"},'"geosite:category-ads-all"'),o(),a("span",{class:"token comment"},'// 分流条件:geosite 文件内,名为"category-ads-all"的规则(各种广告域名)'),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"outboundTag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),o(),a("span",{class:"token comment"},'// 分流策略:交给出站"block"处理(黑洞屏蔽)'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 4*入站设置"),o("\n "),a("span",{class:"token comment"},"// 4.1 这里只写了一个最简单的 vless+xtls 的入站,因为这是 Xray 最强大的模式。如有其他需要,请根据模版自行添加。"),o("\n "),a("span",{class:"token property"},'"inbounds"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"443"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"vless"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"clients"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"id"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'""'),a("span",{class:"token punctuation"},","),o(),a("span",{class:"token comment"},"// 填写你的 UUID"),o("\n "),a("span",{class:"token property"},'"flow"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"xtls-rprx-vision"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"level"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"0"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"email"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"vpsadmin@yourdomain.com"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"decryption"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"none"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"fallbacks"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token number"},"80"),o(),a("span",{class:"token comment"},"// 默认回落到防探测的代理"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"tcp"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"security"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"tls"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"tlsSettings"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"alpn"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"http/1.1"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"certificates"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"certificateFile"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_cert/xray.crt"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"keyFile"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"/home/vpsadmin/xray_cert/xray.key"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 5*出站设置"),o("\n "),a("span",{class:"token property"},'"outbounds"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token punctuation"},"["),o("\n "),a("span",{class:"token comment"},"// 5.1 第一个出站是默认规则,freedom 就是对外直连(vps 已经是外网,所以直连)"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"tag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"direct"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"freedom"'),o("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token comment"},"// 5.2 屏蔽规则,blackhole 协议就是把流量导入到黑洞里(屏蔽)"),o("\n "),a("span",{class:"token punctuation"},"{"),o("\n "),a("span",{class:"token property"},'"tag"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"block"'),a("span",{class:"token punctuation"},","),o("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),o(),a("span",{class:"token string"},'"blackhole"'),o("\n "),a("span",{class:"token punctuation"},"}"),o("\n "),a("span",{class:"token punctuation"},"]"),o("\n"),a("span",{class:"token punctuation"},"}"),o("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br"),a("span",{class:"line-number"},"37"),a("br"),a("span",{class:"line-number"},"38"),a("br"),a("span",{class:"line-number"},"39"),a("br"),a("span",{class:"line-number"},"40"),a("br"),a("span",{class:"line-number"},"41"),a("br"),a("span",{class:"line-number"},"42"),a("br"),a("span",{class:"line-number"},"43"),a("br"),a("span",{class:"line-number"},"44"),a("br"),a("span",{class:"line-number"},"45"),a("br"),a("span",{class:"line-number"},"46"),a("br"),a("span",{class:"line-number"},"47"),a("br"),a("span",{class:"line-number"},"48"),a("br"),a("span",{class:"line-number"},"49"),a("br"),a("span",{class:"line-number"},"50"),a("br"),a("span",{class:"line-number"},"51"),a("br"),a("span",{class:"line-number"},"52"),a("br"),a("span",{class:"line-number"},"53"),a("br"),a("span",{class:"line-number"},"54"),a("br"),a("span",{class:"line-number"},"55"),a("br"),a("span",{class:"line-number"},"56"),a("br"),a("span",{class:"line-number"},"57"),a("br"),a("span",{class:"line-number"},"58"),a("br"),a("span",{class:"line-number"},"59"),a("br"),a("span",{class:"line-number"},"60"),a("br"),a("span",{class:"line-number"},"61"),a("br"),a("span",{class:"line-number"},"62"),a("br"),a("span",{class:"line-number"},"63"),a("br"),a("span",{class:"line-number"},"64"),a("br"),a("span",{class:"line-number"},"65"),a("br"),a("span",{class:"line-number"},"66"),a("br"),a("span",{class:"line-number"},"67"),a("br"),a("span",{class:"line-number"},"68"),a("br"),a("span",{class:"line-number"},"69"),a("br"),a("span",{class:"line-number"},"70"),a("br"),a("span",{class:"line-number"},"71"),a("br"),a("span",{class:"line-number"},"72"),a("br"),a("span",{class:"line-number"},"73"),a("br"),a("span",{class:"line-number"},"74"),a("br"),a("span",{class:"line-number"},"75"),a("br"),a("span",{class:"line-number"},"76"),a("br"),a("span",{class:"line-number"},"77"),a("br"),a("span",{class:"line-number"},"78"),a("br"),a("span",{class:"line-number"},"79"),a("br"),a("span",{class:"line-number"},"80"),a("br"),a("span",{class:"line-number"},"81"),a("br"),a("span",{class:"line-number"},"82"),a("br"),a("span",{class:"line-number"},"83"),a("br"),a("span",{class:"line-number"},"84"),a("br"),a("span",{class:"line-number"},"85"),a("br"),a("span",{class:"line-number"},"86"),a("br"),a("span",{class:"line-number"},"87"),a("br"),a("span",{class:"line-number"},"88"),a("br"),a("span",{class:"line-number"},"89"),a("br"),a("span",{class:"line-number"},"90"),a("br"),a("span",{class:"line-number"},"91"),a("br"),a("span",{class:"line-number"},"92"),a("br"),a("span",{class:"line-number"},"93"),a("br"),a("span",{class:"line-number"},"94"),a("br"),a("span",{class:"line-number"},"95"),a("br"),a("span",{class:"line-number"},"96"),a("br"),a("span",{class:"line-number"},"97"),a("br"),a("span",{class:"line-number"},"98"),a("br"),a("span",{class:"line-number"},"99"),a("br"),a("span",{class:"line-number"},"100"),a("br"),a("span",{class:"line-number"},"101"),a("br"),a("span",{class:"line-number"},"102"),a("br")])])])],-1),yn=a("ol",{start:"5"},[a("li",null,[o("完整流程演示如下: "),a("img",{src:"/Xray-docs-next/assets/ch07-img04-xray-log-and-config.1876d557.gif",alt:"创建日志文件及配置文件"})])],-1),xn=a("h2",{id:"_7-5-启动-xray-服务-并查看服务状态",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-5-启动-xray-服务-并查看服务状态","aria-hidden":"true"},"#"),o(" 7.5 启动 Xray 服务!!(并查看服务状态)")],-1),vn=a("p",null,[o("如果你是跟随本文一步步设置过来,其实就已经避开了最常见"),a("strong",null,"日志文件权限不足"),o("、"),a("strong",null,"证书文件权限不足"),o(" 这两个大坑。那么现在运行"),a("code",null,"Xray"),o("自然应该无比顺利。")],-1),fn=a("ol",null,[a("li",null,[o("输入下面的命令,享受启动"),a("code",null,"Xray"),o("的历史性时刻吧!!!")])],-1),_n=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl start xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Xn=a("ol",{start:"2"},[a("li",null,[o("仅仅"),a("code",null,"start"),o("我们并不能确定是否成功的开启了 Xray 的服务,要确定它的状态,就要用到下面的命令。")])],-1),Bn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl status xray\n\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])],-1),wn=a("p",null,[o("看到那个绿色的、令人愉悦的 "),a("code",null,"active (running)"),o(" 了吗?它就是说 "),a("code",null,"Xray"),o(" 已经在正确的运行了")],-1),Sn=a("ol",{start:"3"},[a("li",null,"完整流程演示如下:")],-1),Ln=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img05-xray-start-and-status.b77f6ab3.gif",alt:"启动并查看Xray运行状态"})],-1),Rn=a("h2",{id:"_7-6-回顾-systemd-进行基本的服务管理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-6-回顾-systemd-进行基本的服务管理","aria-hidden":"true"},"#"),o(" 7.6 回顾 "),a("code",null,"systemd"),o(" 进行基本的服务管理")],-1),qn=a("p",null,[o("到现在为止,我们已经使用过了"),a("code",null,"systemctl"),o("相关的"),a("code",null,"start"),o(", "),a("code",null,"status"),o(", "),a("code",null,"reload"),o(" 等命令,这些都是基于"),a("code",null,"systemd"),o("管理模块对 Linux 系统中各种服务进行管理的通用命令。现在正好熟悉一下相关的其他几个命令。")],-1),Tn=a("ol",null,[a("li",null,[o("若你需要暂时关闭 "),a("code",null,"Xray"),o(" 的服务,那就用"),a("code",null,"stop"),o("命令")])],-1),Dn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl stop xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Pn=a("ol",{start:"2"},[a("li",null,[o("若你需要重启"),a("code",null,"Xray"),o("的服务,那就用"),a("code",null,"restart"),o("命令")])],-1),En=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),jn=a("ol",{start:"3"},[a("li",null,[o("若你需要禁用"),a("code",null,"Xray"),o("的服务(电脑重启后禁止 Xray 自动运行),那就用"),a("code",null,"disable"),o("命令")])],-1),Nn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl disable xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),In=a("ol",{start:"4"},[a("li",null,[o("若你需要启用"),a("code",null,"Xray"),o("的服务(电脑重启后确保 Xray 自动运行),那就用"),a("code",null,"enable"),o("命令")])],-1),Un=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl "),a("span",{class:"token builtin class-name"},"enable"),o(" xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Vn=a("h2",{id:"_7-7-服务器优化之一-开启-bbr",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-7-服务器优化之一-开启-bbr","aria-hidden":"true"},"#"),o(" 7.7 服务器优化之一:开启 BBR")],-1),Fn=a("ol",null,[a("li",null,[o("传说中的"),a("code",null,"BBR")])],-1),Wn=a("p",null,[o("我相信,你在搜索各种科学上网技术的时候,肯定不止一次的听过"),a("code",null,"bbr"),o("这个东西,在各种博客添油加醋之下,让人觉得它神乎其神。更有"),a("code",null,"bbrplus"),o(", "),a("code",null,"bbr2"),o(", "),a("code",null,"魔改bbr"),o(" 等一大堆衍生品。仿佛神油一般,用了就能野鸡线路变专线。")],-1),An=a("p",null,"那么,这东西究竟是什么?它有没有用?又该用哪一个版本呢?",-1),Cn=a("ol",{start:"2"},[a("li",null,[o("实际的"),a("code",null,"BBR")])],-1),Hn=a("p",null,[a("strong",null,"BBR"),o(" = "),a("strong",null,"B"),o("ottleneck "),a("strong",null,"B"),o("andwidth and "),a("strong",null,"R"),o("ound-trip propagation time,是一种 TCP 的"),a("strong",null,"拥塞控制算法"),o("。简单粗暴的理解就是"),a("strong",null,"数据流量的交通管理"),o(" :当公路不再塞车的时候,每辆车自然就能保持较快的车速了。")],-1),Kn=a("p",null,[o("那么它有没有用呢?一般而言,"),a("code",null,"有BBR"),o(" 和 "),a("code",null,"没有BBR"),o(" 会有可以感知的差别(速度、稳定性、延迟方面都会有一些改善),所以 "),a("strong",null,[o("【非常建议开启 "),a("code",null,"BBR"),o("】")]),o("。")],-1),Mn=a("p",null,[o("但开启之后,"),a("code",null,"BBR"),o(" 在 "),a("code",null,"4.x"),o(" 和 "),a("code",null,"5.x"),o(" 之间的差异往往比较微妙、见仁见智,造成体验差别的决定性因素仍然是线路质量。所以 "),a("strong",null,"【不必纠结版本、不必盲目追新、跟随你的发行版更新内核即可】")],-1),$n=a("ol",{start:"3"},[a("li",null,[a("code",null,"bbrplus"),o(", "),a("code",null,"bbr2"),o(", "),a("code",null,"魔改bbr"),o(" 和其他各种听起来就酷炫的版本是不是更好?")])],-1),Gn=a("p",null,[o("一句话:"),a("strong",null,"不是!不要用这些!这些都为了吸引眼球乱起的名字!")],-1),On=a("p",null,[a("code",null,"BBR"),o(" 的更新和发布,都是跟随 Linux 的内核("),a("code",null,"Kernel"),o(")进行的。换言之,只要你用的是比较新的内核,就自然会使用到新版"),a("code",null,"BBR"),o("。")],-1),zn=a("p",null,[o("而这些名字看起来很酷炫的东西,说白了就是仍未正式发布的、尚在测试阶段的内核及其对应的"),a("code",null,"BBR"),o("版本。这些脚本也仅仅就是通过下载预览版的内核(甚至第三方魔改内核)来率先开启而已。")],-1),Jn=a("p",null,[o("内核的稳定是一台服务器稳定运行的基石。"),a("strong",null,"【BBR 测试版带来的细微性能差异绝对不值得更换不稳定的内核。】"),o(" 请选择你所在的 Linux 发行版所支持的最新内核,这样可以最大限度的保持服务器的长期稳定和兼容。")],-1),Qn=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"Warning"),a("p",null,[o("所谓魔改"),a("code",null,"bbr"),o("的【领先】是有非常强的时效性的。比如很多 "),a("code",null,"bbrplus"),o(" 脚本,因为几年来都没有更新,到现在还会把你的内核换成 "),a("code",null,"4.19"),o(",要知道现在稳定如 Debian 已经是 "),a("code",null,"5.9"),o(" 的时代了,那么这个脚本放在 2018 年 1 月也许领先了一点,到 2018 年 10 月 4.19 正发布时就已经失去了意义,放在现在甚至可以说是完完全全的【降级】和【劣化】")])],-1),Yn=a("ol",{start:"4"},[a("li",null,[a("code",null,"fq"),o(", "),a("code",null,"fq_codel"),o(", "),a("code",null,"fq_pie"),o(", "),a("code",null,"cake"),o("和其他算法哪个好?")])],-1),Zn=a("p",null,[o("一句话:"),a("strong",null,[o("看不懂的话,请保持"),a("code",null,"fq"),o(",足够、且不会劣化你的线路")])],-1),ns=a("ol",{start:"5"},[a("li",null,"锐速、Finalspeed、LotServer 和其他“加速工具”")],-1),ss=a("p",null,[o("一句话:"),a("strong",null,"不要用这些!把他们丢进历史的垃圾桶吧!")],-1),ls=a("p",null,"它能解决的也只有丢包率的问题。不太准确的比喻,就是本来你用一辆车送你的货,有时候车半路就坏了(丢包),用了这些以后,你直接派出 3 份一样的货,让三辆车同时送,只要有一辆没坏就能送到。马路上都是你的车,自然就能把别人挤下去。但可想而知,你挤别人的时候,别人也会来挤你,而整个机房的出口道路一共就那么宽,最终势必就变成集体大堵车了。",-1),as=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("它们的原理不是算法优化、不是提速、大多数是简单粗暴的"),a("strong",null,"多倍发包"),o("。对于【丢包率非常高】的差线路可能有一点作用,但【对丢包率低的好线路没有任何优化作用,反而会成倍的消耗你的流量】,进而造成服务器和你的邻居不必要的压力。")]),a("p",null,"如果你的线路真的丢包率奇高,真正靠谱的解决方案是【换线路】。")],-1),es=a("ol",{start:"6"},[a("li",null,[a("p",null,[o("啰嗦了这么多,就是因为围绕 "),a("code",null,"BBR"),o(" 忽悠小白的错误概念和坑人脚本实在是太多了。我希望你们现在对 "),a("code",null,"BBR"),o(" 有了相对清晰的理解。接下来,我们就动手安装最新的 Debian 内核并开启"),a("code",null,"BBR"),o(" 吧!(真的很简单)")])]),a("li",null,[a("p",null,[o("给 Debian 10 添加官方 "),a("code",null,"backports"),o(" 源,获取更新的软件库")])])],-1),ts=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/apt/sources.list\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),cs=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("本文以 Debian 10 为例,所以使用 "),a("code",null,"/etc/apt/sources.list"),o(" 仍无问题,但如果你并不是根据本文从头开始,或者使用了其他 Linux 发行版,那么建议你建立 "),a("code",null,"/etc/apt/sources.list.d/"),o(" 文件夹,并在这个文件夹内建立自己的配置文件,形如 "),a("code",null,"/etc/apt/sources.list.d/vpsadmin.list"),o(" ,以此保证兼容性,也可避免默认文件在不可预见的情况下被覆盖而导致配置丢失。")])],-1),os=a("ol",{start:"2"},[a("li",null,"然后把下面这一条加在最后,并保存退出。")],-1),rs=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"deb http://deb.debian.org/debian buster-backports main\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),us=a("ol",{start:"3"},[a("li",null,"刷新软件库并查询 Debian 官方的最新版内核并安装。请务必安装你的 VPS 对应的版本(本文以比较常见的【amd64】为例)。")],-1),ps=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"apt"),o(" update "),a("span",{class:"token operator"},"&&"),o(),a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"apt"),o(" -t buster-backports "),a("span",{class:"token function"},"install"),o(" linux-image-amd64\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),is=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"注意"),a("p",null,[o("如果你的 VPS 支持,可以尝试【云服务器专用内核】"),a("code",null,"linux-image-cloud-amd64"),o(",优点就是精简、资源占用低,缺点嘛是有同学反馈不支持的系统强行安装会导致无法开机(Kernel 无法识别)。")]),a("p",null,"为了避免无法识别的悲剧,请确保:"),a("ul",null,[a("li",null,"尝试前做一个系统快照,或者"),a("li",null,[o("你有 "),a("code",null,"vnc"),o(" 可以救场(并且你知道怎么用)")])])],-1),bs=a("ol",{start:"4"},[a("li",null,[o("修改 "),a("code",null,"kernel"),o(" 参数配置文件 "),a("code",null,"sysctl.conf"),o(" 并指定开启 "),a("code",null,"BBR")])],-1),ds=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/sysctl.conf\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),ms=a("div",{class:"custom-container warning"},[a("p",{class:"custom-container-title"},"说明"),a("p",null,[o("本文以 Debian 10 为例,所以使用 "),a("code",null,"/etc/sysctl.conf"),o(" 仍无问题,但如果你并不是跟着本文从头开始,或者使用了其他 Linux 发行版,那么建议你建立 "),a("code",null,"/etc/sysctl.d/"),o(" 文件夹,并在这个文件夹内建立自己的配置文件,形如 "),a("code",null,"/etc/sysctl.d/vpsadmin.conf"),o(",以此保证兼容性,因为部分发行版在 "),a("code",null,"systemd"),o(" 207 版本之后便不再从 "),a("code",null,"/etc/sysctl.conf"),o(" 读取参数。使用自定义配置文件也可避免默认文件在不可预见的情况下被覆盖而导致配置丢失。")])],-1),gs=a("ol",{start:"5"},[a("li",null,"把下面的内容添加进去")],-1),ks=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"net.core.default_qdisc=fq\nnet.ipv4.tcp_congestion_control=bbr\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br")])],-1),hs=a("ol",{start:"6"},[a("li",null,[o("重启 VPS、使内核更新和"),a("code",null,"BBR"),o("设置都生效")])],-1),ys=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"reboot"),o("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),xs=a("ol",{start:"7"},[a("li",null,"完整流程演示如下:")],-1),vs=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"啰嗦君"),a("p",null,[o("因为我做展示的 VPS 支持云服务器专用内核,所以动图中我用了 "),a("code",null,"linux-image-cloud-amd64"),o(" 。如果你不确定你的 VPS 是否支持,那请务必按照第 3 步的命令,使用常规内核 "),a("code",null,"linux-image-amd64"),o("。")])],-1),fs=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img06-bbr-proper.496ecbe2.gif",alt:"更新Debian内核并开启"})],-1),_s=a("ol",{start:"8"},[a("li",null,[o("确认"),a("code",null,"BBR"),o("开启")])],-1),Xs=a("p",null,[o("如果你想确认 "),a("code",null,"BBR"),o(" 是否正确开启,可以使用下面的命令:")],-1),Bs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("lsmod "),a("span",{class:"token operator"},"|"),o(),a("span",{class:"token function"},"grep"),o(" bbr\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),ws=a("p",null,"此时应该返回这样的结果:",-1),Ss=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"tcp_bbr\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ls=a("p",null,[o("如果你想确认 "),a("code",null,"fq"),o(" 算法是否正确开启,可以使用下面的命令:")],-1),Rs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[o("lsmod "),a("span",{class:"token operator"},"|"),o(),a("span",{class:"token function"},"grep"),o(" fq\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),qs=a("p",null,"此时应该返回这样的结果:",-1),Ts=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"sch_fq\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ds=a("h2",{id:"_7-8-服务器优化之二-开启-http-自动跳转-https",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-8-服务器优化之二-开启-http-自动跳转-https","aria-hidden":"true"},"#"),o(" 7.8 服务器优化之二:开启 HTTP 自动跳转 HTTPS")],-1),Ps=a("ol",null,[a("li",null,[o("之前我们已经搭建了 "),a("code",null,"80"),o(" 端口的 "),a("code",null,"http"),o(" 网页,并以此申请了 TLS 证书。")])],-1),Es=a("p",null,[o("但如果你尝试过用浏览器访问我们的这个界面,就会发现 "),a("code",null,"http"),o(" 访问并不会像大多数网站一样自动升级为 "),a("code",null,"https"),o(" 访问。换言之,我们现在的设置下,"),a("code",null,"http(80)"),o(" 和 "),a("code",null,"https(443)"),o(" 之间完全是独立的。如果要解决这个问题,就需要做一些修改。")],-1),js=a("ol",{start:"2"},[a("li",null,"编辑 Nginx 的配置文件")],-1),Ns=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /etc/nginx/nginx.conf\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Is=a("ol",{start:"3"},[a("li",null,[o("在我们设置过的 80 端口 Server 中加入下面的语句,并保存退出(可同时删除"),a("code",null,"root"),o("和"),a("code",null,"index"),o("两行)")])],-1),Us=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,"return 301 https://$http_host$request_uri;\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Vs=a("ol",{start:"4"},[a("li",null,[o("在与 "),a("code",null,"80"),o(" 端口同级的位置增加一个本地端口监听来提供网页展示。本文以 "),a("code",null,"8080"),o(" 端口做演示。(可以是任意端口)")])],-1),Fs=a("div",{class:"language-text ext-text line-numbers-mode"},[a("pre",{class:"language-text"},[a("code",null,'server {\n listen 127.0.0.1:8080;\n root /home/vpsadmin/www/webpage;\n index index.html;\n add_header Strict-Transport-Security "max-age=63072000" always;\n}\n')]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br")])],-1),Ws=a("ol",{start:"5"},[a("li",null,"重启 Nginx 服务")],-1),As=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart nginx\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Cs=a("ol",{start:"6"},[a("li",null,[o("修改 Xray 的回落设置,将回落从 "),a("code",null,"80"),o(" 端口改为 "),a("code",null,"8080"),o(" 端口。(找到 "),a("code",null,'"dest": 80'),o(", 并改成 "),a("code",null,'"dest": 8080'),o(")")])],-1),Hs=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(),a("span",{class:"token function"},"nano"),o(" /usr/local/etc/xray/config.json\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),Ks=a("ol",{start:"7"},[a("li",null,[o("重启 "),a("code",null,"Xray"),o(" 服务,即完成了设置")])],-1),Ms=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),o(" systemctl restart xray\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),$s=a("ol",{start:"8"},[a("li",null,"完整流程演示如下:")],-1),Gs=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img07-http-to-https.a87dc99c.gif",alt:"http自动跳转https"})],-1),Os=a("ol",{start:"9"},[a("li",null,[o("当你输入 "),a("code",null,"http://a-name.yourdomain.com"),o("的时候,它应该已经会自动跳转 https 了")])],-1),zs=a("p",null,[a("img",{src:"/Xray-docs-next/assets/ch07-img08-http-to-https-check.bc6ae06e.png",alt:"http自动跳转https生效"})],-1),Js=a("h2",{id:"_7-9-服务器优化之三-更丰富的回落",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-9-服务器优化之三-更丰富的回落","aria-hidden":"true"},"#"),o(" 7.9 服务器优化之三:更丰富的回落")],-1),Qs=o("如果你需要更丰富的回落功能,可以参考 "),Ys=o("《回落 (fallbacks) 功能简析》"),Zs=a("h2",{id:"_7-10-你的进度",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-10-你的进度","aria-hidden":"true"},"#"),o(" 7.10 你的进度")],-1),nl=a("p",null,"恭喜!!到这一步,你已经拥有了可以正常科学上网的服务器、同时也有了可以防止主动探测攻击的伪装网站。接下来,只要给你的客户端装上合适的软件,就可以享受顺畅的网络了!",-1),sl=a("blockquote",null,[a("p",null,"⬛⬛⬛⬛⬛⬛⬛⬜ 87.5%")],-1),ll=a("h2",{id:"_7-11-重要勘误",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_7-11-重要勘误","aria-hidden":"true"},"#"),o(" 7.11 重要勘误")],-1),al=a("ol",null,[a("li",null,[o("初版中"),a("code",null,"Xray"),o("配置文件"),a("code",null,"config.json"),o("文件夹位置错误。若你已经根据之前的位置进行了操作,"),a("code",null,"Xray"),o("会无法正确启动。故勘误说明于此,请自查,造成不便十分抱歉!")])],-1),el=a("ul",null,[a("li",null,[o("正确位置:"),a("code",null,"/usr/local/etc/xray/config.json")]),a("li",null,[o("错误位置:"),a("code",null,"/usr/local/etc/config.json")])],-1),tl=a("p",null,"受影响章节:",-1),cl=a("ul",null,[a("li",null,[o("7.4 配置"),a("code",null,"Xray"),o(" - 3. 使用"),a("code",null,"nano"),o("创建"),a("code",null,"Xray"),o("的配置文件")]),a("li",null,[o("7.8 服务器优化之二 - 6. 修改"),a("code",null,"Xray"),o("的回落设置")])],-1),ol=a("ol",{start:"2"},[a("li",null,[o("初版中修改"),a("code",null,"Nginx"),o("配置文件"),a("code",null,"nginx.conf"),o("时内容错误(网页文件夹位置错误),若你已经根据之前的位置进行了操作,"),a("code",null,"Nginx"),o("会无法找到正确的网站。请自查,造成不便十分抱歉!")])],-1),rl=a("ul",null,[a("li",null,[o("正确文件夹位置:"),a("code",null,"root /home/vpsadmin/www/webpage;")]),a("li",null,[o("错误文件夹位置:"),a("code",null,"root /var/www/website/html")])],-1),ul=a("p",null,"受影响章节:",-1),pl=a("ul",null,[a("li",null,[o("7.8 服务器优化之二 - 4. 在与 "),a("code",null,"80"),o(" 端口同级的位置增加一个本地端口监听来提供网页展示")])],-1);u.render=function(o,r){const u=n("OutboundLink"),il=n("RouterLink");return s(),l(c,null,[p,i,b,d,m,g,k,h,a("p",null,[y,a("a",x,[v,e(u)]),f,_,X]),a("p",null,[B,a("a",w,[S,e(u)]),L,R,q]),T,D,P,a("p",null,[E,a("a",j,[N,I,e(u)]),U,V,F,W,A]),a("ol",null,[C,H,K,M,a("li",null,[$,a("ol",G,[O,a("li",null,[z,a("div",J,[Q,a("p",null,[Y,a("a",Z,[nn,e(u)]),sn]),ln])]),an,en,tn,cn])])]),on,a("p",null,[rn,a("a",un,[pn,e(u)]),bn,dn,mn,gn,kn]),hn,yn,xn,vn,fn,_n,Xn,Bn,wn,Sn,Ln,Rn,qn,Tn,Dn,Pn,En,jn,Nn,In,Un,Vn,Fn,Wn,An,Cn,Hn,Kn,Mn,$n,Gn,On,zn,Jn,Qn,Yn,Zn,ns,ss,ls,as,es,ts,cs,os,rs,us,ps,is,bs,ds,ms,gs,ks,hs,ys,xs,vs,fs,_s,Xs,Bs,ws,Ss,Ls,Rs,qs,Ts,Ds,Ps,Es,js,Ns,Is,Us,Vs,Fs,Ws,As,Cs,Hs,Ks,Ms,$s,Gs,Os,zs,Js,a("p",null,[Qs,e(il,{to:"/en/document/level-1/fallbacks-lv1/"},{default:t((()=>[Ys])),_:1})]),Zs,nl,sl,ll,al,el,tl,cl,ol,rl,ul,pl],64)};export default u; diff --git a/assets/ch08-xray-clients.html.4df4886f.js b/assets/ch08-xray-clients.html.7ce58dd3.js similarity index 99% rename from assets/ch08-xray-clients.html.4df4886f.js rename to assets/ch08-xray-clients.html.7ce58dd3.js index 5806570c7..c061985b8 100644 --- a/assets/ch08-xray-clients.html.4df4886f.js +++ b/assets/ch08-xray-clients.html.7ce58dd3.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as o,w as t,F as e,e as l,d as u}from"./app.755d843f.js";const r={},c=p("h1",{id:"【第-8-章】xray-客户端篇",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#【第-8-章】xray-客户端篇","aria-hidden":"true"},"#"),l(" 【第 8 章】Xray 客户端篇")],-1),i=p("h2",{id:"_8-1-xray-的工作原理简述",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-1-xray-的工作原理简述","aria-hidden":"true"},"#"),l(" 8.1 Xray 的工作原理简述")],-1),b=p("p",null,[l("要正确的配置和使用"),p("code",null,"Xray"),l(",就需要正确的理解其工作原理,对于新人,可以先看看下面简化的示意图(省略了许多复杂的设置):")],-1),k=p("p",null,[p("img",{src:"/Xray-docs-next/assets/ch08-img01-flow.e9c45ad1.png",alt:"Xray数据流向"})],-1),m=p("p",null,"这其中的关键点是:",-1),d=p("ol",null,[p("li",null,[p("p",null,[l("APP 要主动或借助转发工具,将数据【流入("),p("code",null,"inbounds"),l(")】"),p("code",null,"Xray"),l(" 客户端")])]),p("li",null,[p("p",null,[l("流量进入客户端后,会被【客户端路由("),p("code",null,"routing"),l(")】按规则处理后,向不同方向【流出"),p("code",null,"(outbounds)"),l("】"),p("code",null,"Xray"),l(" 客户端。比如:")]),p("ol",null,[p("li",null,[l("国内流量直连("),p("code",null,"direct"),l(")")]),p("li",null,[l("国外流量转发 VPS("),p("code",null,"proxy"),l(")")]),p("li",null,[l("广告流量屏蔽("),p("code",null,"block"),l(")")])])]),p("li",null,[p("p",null,[l("向 VPS 转发的国外流量,会跨过防火墙,【流入("),p("code",null,"inbounds"),l(")】 "),p("code",null,"Xray"),l(" 服务器端")])]),p("li",null,[p("p",null,[l("流量进入服务器端后,与客户端一样,会被【服务器端路由("),p("code",null,"routing"),l(")】按规则处理后,向不同方向【流出"),p("code",null,"(outbounds)"),l("】:")]),p("ol",null,[p("li",null,[l("因为已经在防火墙之外,所以流量默认直连,你就可以访问到不存在网站们了("),p("code",null,"direct"),l(")")]),p("li",null,[l("如果需要在不同的 VPS 之间做链式转发,就可以继续配置转发规则("),p("code",null,"proxy"),l(")")]),p("li",null,[l("你可以在服务器端继续禁用各种你想禁用的流量,如广告、BT 下载等("),p("code",null,"block"),l(")")])])])],-1),q={class:"custom-container warning"},y=p("p",{class:"custom-container-title"},"注意",-1),g=p("p",null,[l("请务必记得,"),p("code",null,"Xray"),l(" 的路由配置非常灵活,上面的说明只是无限可能性中的一种。")],-1),h=p("p",null,[l("借助 "),p("code",null,"geosite.dat"),l(" 和 "),p("code",null,"geoip.dat"),l(" 这两个文件,可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 "),p("code",null,"GFWList"),l(" 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)")],-1),x=l("现在,"),f=l("《路由 (routing) 功能简析》"),S=l(" 已经上线,我建议对路由功能有兴趣的同学,先继续跟着本文完成客户端的基础配置,之后再去这里详细学习。"),X=p("h2",{id:"_8-2-客户端与服务器端正确连接",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-2-客户端与服务器端正确连接","aria-hidden":"true"},"#"),l(" 8.2 客户端与服务器端正确连接")],-1),v=p("p",null,[l("现在你已经理解了 "),p("code",null,"Xray"),l(" 的工作原理,那么接下来的配置,其实就是【告诉你的客户端如何连接 VPS 服务器】。这和你已经很熟悉的、告诉"),p("code",null,"PuTTY"),l("如何远程连接服务器是一样的。只不过 Xray 连接时的要素不止是【IP 地址】+【端口】+【用户名】+【密码】这四要素了。")],-1),_=l("实际上,"),P=p("code",null,"Xray",-1),w=l("的连接要素是由不同的"),N=l("协议"),I=l("决定的。本文在第 7 章的配置文件 "),T=p("code",null,"config.json",-1),L=l(" 里,我们使用 "),C=p("code",null,"Xray",-1),D=l(" 下独特而强大的 "),V=p("code",null,"VLESS",-1),j=l(" 协议 + "),G=p("code",null,"XTLS",-1),O=l(" 流控。所以看看那个配置文件的内容就能知道,这个协议组合的连接要素有:"),A=p("ul",null,[p("li",null,[l("服务器【地址】: "),p("code",null,"a-name.yourdomain.com")]),p("li",null,[l("服务器【端口】: "),p("code",null,"443")]),p("li",null,[l("连接的【协议】: "),p("code",null,"vless")]),p("li",null,[l("连接的【流控】: "),p("code",null,"xtls-rprx-vision"),l(" (vision 模式适合全平台)")]),p("li",null,[l("连接的【验证】: "),p("code",null,"uuiduuid-uuid-uuid-uuiduuiduuid")]),p("li",null,[l("连接的【安全】: "),p("code",null,'"allowInsecure": false')])],-1),R=p("p",null,"鉴于新人一般都会使用手机 APP 或者电脑的 GUI 客户端,我就把常用的客户端罗列在下面。每个客户端都有自己独特的配置界面,逐一截图展示并不现实,所以请你务必仔细阅读这些客户端的说明、然后把上述要素填入合适的地方即可。",-1),E=p("div",{class:"custom-container warning"},[p("p",{class:"custom-container-title"},"注意"),p("p",null,[l("许多工具其实是同时支持 "),p("code",null,"xray-core"),l(" 和 "),p("code",null,"v2fly-core"),l(" 的,但默认内置的不一定是哪个,所以别忘记检查一下是否是你想要的那个在工作哦!")])],-1),F=p("p",null,[p("strong",null,"v2rayN - 适用于 Windows 平台")],-1),H=l("请从它的"),Q={href:"https://github.com/2dust/v2rayN/releases",target:"_blank",rel:"noopener noreferrer"},W=l("GitHub 仓库 Release 页面"),Y=l("获取最新版"),z=p("li",null,"请根据该客户端的说明进行设置",-1),B=p("p",null,[p("strong",null,"v2rayNG - 适用于 Android 平台")],-1),M=l("请从它的"),U={href:"https://github.com/2dust/v2rayNG/releases",target:"_blank",rel:"noopener noreferrer"},J=l("GitHub 仓库 Release 页面"),K=l("获取最新版"),Z=p("li",null,"请根据该客户端的说明进行设置",-1),$=p("li",null,[p("p",null,[p("strong",null,"Shadowrocket - 适用于 iOS, 基于苹果 M 芯片的 macOS")]),p("ul",null,[p("li",null,"你需要注册一个【非中国区】的 iCloud 账户"),p("li",null,"你需要通过 App Store 搜索并购买"),p("li",null,"请根据该客户端的说明进行设置")])],-1),nn=p("p",null,[p("strong",null,"Qv2ray - 跨平台图形界面,适用于 Linux, Windows, macOS")],-1),sn=l("请从它的"),an={href:"https://github.com/Qv2ray/Qv2ray/releases",target:"_blank",rel:"noopener noreferrer"},pn=l("GitHub 仓库 Release 页面"),on=l("获取最新版(还可以从它的"),tn={href:"https://github.com/Qv2ray/Qv2ray/actions",target:"_blank",rel:"noopener noreferrer"},en=l("GitHub 自动构建仓库"),ln=l("寻找更新的版本)"),un=l("请从它的"),rn={href:"https://qv2ray.net/",target:"_blank",rel:"noopener noreferrer"},cn=l("项目主页"),bn=l("学习文档"),kn=p("li",null,"请根据该客户端的说明进行设置",-1),mn=p("p",null,[p("strong",null,"V2RayXS - 基于 V2RayX 开发的一款使用 xray-core 的 macOS 客户端")],-1),dn=l("请从它的 "),qn={href:"https://github.com/tzmax/v2rayXS/releases",target:"_blank",rel:"noopener noreferrer"},yn=l("GitHub 仓库 Release 页面"),gn=l(" 获取最新版"),hn=l("支持一键导入 "),xn={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},fn=l("VMessAEAD / VLESS 分享链接标准提案"),Sn=l(" 为标准的分享链接"),Xn=p("li",null,"请根据该客户端的说明进行设置",-1),vn=p("p",null,"到这一步,你的全套配置就已经可以正常使用啦!",-1),_n=p("h2",{id:"_8-3-附加题-1-在-pc-端手工配置-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-3-附加题-1-在-pc-端手工配置-xray-core","aria-hidden":"true"},"#"),l(" 8.3 附加题 1:在 PC 端手工配置 "),p("code",null,"xray-core")],-1),Pn=p("p",null,[l("虽然到上面一步已经可以结束了,但是如果你是个好奇心强、记忆力好的的同学,一定会想起来我在上一章说过,你把"),p("code",null,"xray-core"),l(" 的二进制文件“放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。” 那究竟要怎样直接使用 "),p("code",null,"xray-core"),l(" 做客户端呢?")],-1),wn=p("p",null,"为了回答这个问题,我加入了附加题章节,有一点点超纲,有一点点麻烦,但费这个笔墨是因为这个方式有它的优势:",-1),Nn=p("ul",null,[p("li",null,[p("p",null,"第一时间获得最新版而无需等待 APP 升级适配")]),p("li",null,[p("p",null,"灵活自由的路由配置能力(当然 GUI 客户端中 Qv2ray 的高级路由编辑器非常强大,也可以完整实现 xray-core 的路由配置功能)")]),p("li",null,[p("p",null,"节约系统资源 (GUI 界面一定会有资源消耗,消耗的多少则取决于客户端的实现)")])],-1),In=p("p",null,"它的劣势应该就是【需要手写配置文件】有点麻烦了。但其实,你想想,服务器上你已经成功的写过一次了,现在又有什么区别呢?接下来,还是老样子,我们分解一下步骤:",-1),Tn=l("首先请从 Xray 官方的 "),Ln={href:"https://github.com/XTLS/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},Cn=l("GitHub 仓库 Release 页面"),Dn=l(" 获取对应平台的版本,并解压缩到合适的文件夹"),Vn=u('
  • 在合适的文件夹建立空白配置文件:config.json (自己常用平台下新建文件大家肯定都会,这就真不用啰嗦了)

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

  • 填写客户端配置

    • 我就以 8.1 原理说明里展示的基本三类分流(国内流量直连、国际流量转发 VPS、广告流量屏蔽),结合 8.2 的连接要素,写成一个配置文件
    • 请将 uuid 替换成与你服务器一致的 uuid
    • 请将 address 替换成你的真实域名
    • 请将 serverName 替换成你的真实域名
    • 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
    // REFERENCE:\n// https://github.com/XTLS/Xray-examples\n// https://xtls.github.io/config/\n\n// 常用的config文件,不论服务器端还是客户端,都有5个部分。外加小小白解读:\n// ┌─ 1_log          日志设置 - 日志写什么,写哪里(出错时有据可查)\n// ├─ 2_dns          DNS-设置 - DNS怎么查(防DNS污染、防偷窥、避免国内外站匹配到国外服务器等)\n// ├─ 3_routing      分流设置 - 流量怎么分类处理(是否过滤广告、是否国内外分流)\n// ├─ 4_inbounds     入站设置 - 什么流量可以流入Xray\n// └─ 5_outbounds    出站设置 - 流出Xray的流量往哪里去\n\n{\n  // 1_日志设置\n  // 注意,本例中我默认注释掉了日志文件,因为windows, macOS, Linux 需要写不同的路径,请自行配置\n  "log": {\n    // "access": "/home/local/xray_log/access.log",    // 访问记录\n    // "error": "/home/local/xray_log/error.log",    // 错误记录\n    "loglevel": "warning" // 内容从少到多: "none", "error", "warning", "info", "debug"\n  },\n\n  // 2_DNS设置\n  "dns": {\n    "servers": [\n      // 2.1 国外域名使用国外DNS查询\n      {\n        "address": "1.1.1.1",\n        "domains": ["geosite:geolocation-!cn"]\n      },\n      // 2.2 国内域名使用国内DNS查询,并期待返回国内的IP,若不是国内IP则舍弃,用下一个查询\n      {\n        "address": "223.5.5.5",\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      // 2.3 作为2.2的备份,对国内网站进行二次查询\n      {\n        "address": "114.114.114.114",\n        "domains": ["geosite:cn"]\n      },\n      // 2.4 最后的备份,上面全部失败时,用本机DNS查询\n      "localhost"\n    ]\n  },\n\n  // 3_分流设置\n  // 所谓分流,就是将符合否个条件的流量,用指定`tag`的出站协议去处理(对应配置的5.x内容)\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      // 3.1 广告域名屏蔽\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      // 3.2 国内域名直连\n      {\n        "type": "field",\n        "domain": ["geosite:cn"],\n        "outboundTag": "direct"\n      },\n      // 3.3 国内IP直连\n      {\n        "type": "field",\n        "ip": ["geoip:cn", "geoip:private"],\n        "outboundTag": "direct"\n      },\n      // 3.4 国外域名代理\n      {\n        "type": "field",\n        "domain": ["geosite:geolocation-!cn"],\n        "outboundTag": "proxy"\n      },\n      // 3.5 默认规则\n      // 在Xray中,任何不符合上述路由规则的流量,都会默认使用【第一个outbound(5.1)】的设置,所以一定要把转发VPS的outbound放第一个\n      // 3.6 走国内"223.5.5.5"的DNS查询流量分流走direct出站\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct"\n      }\n    ]\n  },\n\n  // 4_入站设置\n  "inbounds": [\n    // 4.1 一般都默认使用socks5协议作本地转发\n    {\n      "tag": "socks-in",\n      "protocol": "socks",\n      "listen": "127.0.0.1", // 这个是通过socks5协议做本地转发的地址\n      "port": 10800, // 这个是通过socks5协议做本地转发的端口\n      "settings": {\n        "udp": true\n      }\n    },\n    // 4.2 有少数APP不兼容socks协议,需要用http协议做转发,则可以用下面的端口\n    {\n      "tag": "http-in",\n      "protocol": "http",\n      "listen": "127.0.0.1", // 这个是通过http协议做本地转发的地址\n      "port": 10801 // 这个是通过http协议做本地转发的端口\n    }\n  ],\n\n  // 5_出站设置\n  "outbounds": [\n    // 5.1 默认转发VPS\n    // 一定放在第一个,在routing 3.5 里面已经说明了,这等于是默认规则,所有不符合任何规则的流量都走这个\n    {\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "a-name.yourdomain.com", // 替换成你的真实域名\n            "port": 443,\n            "users": [\n              {\n                "id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid", // 和服务器端的一致\n                "flow": "xtls-rprx-vision",\n                "encryption": "none",\n                "level": 0\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "tls",\n        "tlsSettings": {\n          "serverName": "a-name.yourdomain.com", // 替换成你的真实域名\n          "allowInsecure": false, // 禁止不安全证书\n          "fingerprint": "chrome" // 通过 uTLS 库 模拟 Chrome / Firefox / Safari 或随机生成的指纹\n        }\n      }\n    },\n    // 5.2 用`freedom`协议直连出站,即当routing中指定'direct'流出时,调用这个协议做处理\n    {\n      "tag": "direct",\n      "protocol": "freedom"\n    },\n    // 5.3 用`blackhole`协议屏蔽流量,即当routing中指定'block'时,调用这个协议做处理\n    {\n      "tag": "block",\n      "protocol": "blackhole"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
  • ',3),jn=p("h2",{id:"_8-4-附加题-2-在-pc-端手工运行-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-4-附加题-2-在-pc-端手工运行-xray-core","aria-hidden":"true"},"#"),l(" 8.4 附加题 2:在 PC 端手工运行 "),p("code",null,"xray-core")],-1),Gn=p("p",null,[l("写好了配置文件该,要怎么让 "),p("code",null,"xray-core"),l(" 运行起来呢?双击好像并没有反应啊?")],-1),On=p("p",null,"首先,你要找到电脑上的【命令行界面】。",-1),An=p("ol",null,[p("li",null,[l("Linux 桌面、macOS 系统的同学肯定已经比较熟悉了,搜索 "),p("code",null,"Console"),l(" 或者 "),p("code",null,"Terminal"),l(" 就可以")]),p("li",null,[l("Windows 就可以搜索使用 "),p("code",null,"Cmd"),l(" 或者 "),p("code",null,"Powershell"),l(" 等程序(WSL 的同学你坐下,你的 "),p("code",null,"Console"),l(" 当然也可以)")])],-1),Rn=p("p",null,[l("其次,我们要做的事情是【让 "),p("code",null,"xray"),l(" 找到并读取配置文件 "),p("code",null,"config.json"),l(",然后运行】,所以:")],-1),En=p("ol",null,[p("li",null,[p("p",null,[l("在 Windows 下,假设你的 "),p("code",null,"Xray"),l(" 程序位置是 "),p("code",null,"C:\\Xray-windows-64\\xray.exe"),l(",配置文件位置是"),p("code",null,"C:\\Xray-windows-64\\config.json"),l(",那么正确的启动命令就是:")]),p("div",{class:"language-bash ext-sh line-numbers-mode"},[p("pre",{class:"language-bash"},[p("code",null,[l("C:"),p("span",{class:"token punctuation"},"\\"),l("Xray-windows-64"),p("span",{class:"token punctuation"},"\\"),l("xray.exe -c C:"),p("span",{class:"token punctuation"},"\\"),l("Xray-windows-64"),p("span",{class:"token punctuation"},"\\"),l("config.json\n")])]),p("div",{class:"line-numbers"},[p("span",{class:"line-number"},"1"),p("br")])]),p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"说明"),p("p",null,[l("这里的 "),p("code",null,"-c"),l(" 就是指定配置文件路径的参数,告诉 "),p("code",null,"xray"),l(" 去后面的位置找配置文件")])])]),p("li",null,[p("p",null,[l("相似的,在 Linux 和 macOS 下,假设你的 "),p("code",null,"Xray"),l(" 程序位置是 "),p("code",null,"/usr/local/bin/xray"),l(",配置文件位置是"),p("code",null,"/usr/local/etc/xray/config.json"),l(",那么正确的启动命令就是")]),p("div",{class:"language-bash ext-sh line-numbers-mode"},[p("pre",{class:"language-bash"},[p("code",null,"/usr/local/bin/xray -c /usr/local/etc/xray/config.json\n")]),p("div",{class:"line-numbers"},[p("span",{class:"line-number"},"1"),p("br")])]),p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"说明"),p("p",null,[l("每个系统都有系统路径变量,所以写 "),p("code",null,"Xray"),l(" 程序时不一定要写绝对路径。但是写了肯定没错,所以我就如此演示了。")])])])],-1),Fn=p("h2",{id:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-5-附加题-3-在-pc-端开机自动运行-xray-core","aria-hidden":"true"},"#"),l(" 8.5 附加题 3:在 PC 端开机自动运行 "),p("code",null,"xray-core")],-1),Hn=p("p",null,[l("如果你真的尝试了手动运行 "),p("code",null,"xray-core"),l(",你一定会发现这个方式还有点小问题:")],-1),Qn=p("ol",null,[p("li",null,[l("每次运行 "),p("code",null,"Xray"),l(" 都要出现一个黑乎乎的窗口,很丑")]),p("li",null,"不能开机自动运行,每次都要手工输入,十分不方便")],-1),Wn=p("p",null,[l("我可以肯定的告诉你:"),p("strong",null,"完全可以解决"),l("。但是具体的解决方式,就当作课外作业留给大家吧!(友情提示,文档站的问答区有线索哦)")],-1),Yn=p("h2",{id:"_8-6-圆满完成",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-6-圆满完成","aria-hidden":"true"},"#"),l(" 8.6 圆满完成!")],-1),zn=p("p",null,[l("我相信,有耐心看到这里的同学,都是兼具好奇心和行动力的学习派!我现在要郑重的恭喜你,因为到了这里,你已经完完整整的【"),p("strong",null,"从第一条命令开始,完成了 VPS 服务器部署,并成功的在客户端配置使用 Xray"),l("】了!这毫无疑问是一个巨大的胜利!")],-1),Bn=p("p",null,[l("我相信,你现在一定对"),p("code",null,"Linux"),l("不再恐惧,对"),p("code",null,"Xray"),l("不再陌生了吧!")],-1),Mn=p("p",null,[p("strong",null,"至此,小小白白话文圆满结束!")],-1),Un=p("blockquote",null,[p("p",null,"⬛⬛⬛⬛⬛⬛⬛⬛ 100%")],-1),Jn=p("h2",{id:"_8-7-to-infinity-and-beyond",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-7-to-infinity-and-beyond","aria-hidden":"true"},"#"),l(" 8.7 TO INFINITY AND BEYOND!")],-1),Kn=p("p",null,[p("strong",null,"但现在你看到的,远远不是 Xray 的全貌。")],-1),Zn=p("p",null,[p("code",null,"Xray"),l("是一个强大而丰富的网络工具集合,平台化的提供了众多模块,可以像瑞士军刀一样,通过灵活的配置组合解决各种不同的问题。而本文,仅仅蜻蜓点水的用了"),p("strong",null,"最简单"),l("、"),p("strong",null,"最直观"),l("的配置来做"),p("strong",null,"基础演示"),l("。")],-1),$n=p("p",null,"如果你觉得现在已经完全够用了,那就好好的享受它给你带来的信息自由。但如果你的好奇心依然不能停歇,那就去继续挖掘它无限的可能性吧!",-1),ns=p("p",null,"需要更多信息,可以到这里寻找:",-1),ss={href:"https://xtls.github.io/",target:"_blank",rel:"noopener noreferrer"},as=l("xtls.github.io"),ps=l(" - 官方文档站"),os={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},ts=l("官方 Telegram 群组"),es=l(" - 活跃而友善的官方讨论社区"),ls=p("p",null,[p("img",{src:"/Xray-docs-next/assets/ch08-img02-buzz.2c8cb2a0.png",alt:"TO INFINITY AND BEYOND!"})],-1),us=p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"不算后记的后记"),p("p",null,"希望我陪你走过的这一段小小的旅程,可以成为你网络生活中的一份小小助力。"),p("p",null,"这篇文章里的工具和信息难免会一点点的陈旧过时,但你一定会逐渐成长为大佬。未来的某个时间,若你能偶尔想起这篇教程、想起我写下本文的初衷,那我衷心希望你能够薪火相传、把最新的知识分享给后来人,让这一份小小的助力在社区里坚定的传递下去。"),p("p",null,"这是个大雪封山乌云密布的世界,人们孤独的走在各自的路上试图寻找阳光,如果大家偶尔交汇时不能守望相助互相鼓励,那最终剩下的,恐怕只有【千山鸟飞绝 万径人踪灭】的凄凉了吧。")],-1);r.render=function(l,u){const r=n("RouterLink"),rs=n("OutboundLink");return s(),a(e,null,[c,i,b,k,m,d,p("div",q,[y,g,h,p("p",null,[x,o(r,{to:"/document/level-1/routing-lv1-part1.html"},{default:t((()=>[f])),_:1}),S])]),X,v,p("p",null,[_,P,w,o(r,{to:"/config/inbounds/"},{default:t((()=>[N])),_:1}),I,T,L,C,D,V,j,G,O]),A,R,E,p("ul",null,[p("li",null,[F,p("ul",null,[p("li",null,[H,p("a",Q,[W,o(rs)]),Y]),z])]),p("li",null,[B,p("ul",null,[p("li",null,[M,p("a",U,[J,o(rs)]),K]),Z])]),$,p("li",null,[nn,p("ul",null,[p("li",null,[sn,p("a",an,[pn,o(rs)]),on,p("a",tn,[en,o(rs)]),ln]),p("li",null,[un,p("a",rn,[cn,o(rs)]),bn]),kn])]),p("li",null,[mn,p("ul",null,[p("li",null,[dn,p("a",qn,[yn,o(rs)]),gn]),p("li",null,[hn,p("a",xn,[fn,o(rs)]),Sn]),Xn])])]),vn,_n,Pn,wn,Nn,In,p("ol",null,[p("li",null,[p("p",null,[Tn,p("a",Ln,[Cn,o(rs)]),Dn])]),Vn]),jn,Gn,On,An,Rn,En,Fn,Hn,Qn,Wn,Yn,zn,Bn,Mn,Un,Jn,Kn,Zn,$n,ns,p("ol",null,[p("li",null,[p("a",ss,[as,o(rs)]),ps]),p("li",null,[p("a",os,[ts,o(rs)]),es])]),ls,us],64)};export default r; +import{r as n,o as s,c as a,a as p,b as o,w as t,F as e,e as l,d as u}from"./app.48111a85.js";const r={},c=p("h1",{id:"【第-8-章】xray-客户端篇",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#【第-8-章】xray-客户端篇","aria-hidden":"true"},"#"),l(" 【第 8 章】Xray 客户端篇")],-1),i=p("h2",{id:"_8-1-xray-的工作原理简述",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-1-xray-的工作原理简述","aria-hidden":"true"},"#"),l(" 8.1 Xray 的工作原理简述")],-1),b=p("p",null,[l("要正确的配置和使用"),p("code",null,"Xray"),l(",就需要正确的理解其工作原理,对于新人,可以先看看下面简化的示意图(省略了许多复杂的设置):")],-1),k=p("p",null,[p("img",{src:"/Xray-docs-next/assets/ch08-img01-flow.e9c45ad1.png",alt:"Xray数据流向"})],-1),m=p("p",null,"这其中的关键点是:",-1),d=p("ol",null,[p("li",null,[p("p",null,[l("APP 要主动或借助转发工具,将数据【流入("),p("code",null,"inbounds"),l(")】"),p("code",null,"Xray"),l(" 客户端")])]),p("li",null,[p("p",null,[l("流量进入客户端后,会被【客户端路由("),p("code",null,"routing"),l(")】按规则处理后,向不同方向【流出"),p("code",null,"(outbounds)"),l("】"),p("code",null,"Xray"),l(" 客户端。比如:")]),p("ol",null,[p("li",null,[l("国内流量直连("),p("code",null,"direct"),l(")")]),p("li",null,[l("国外流量转发 VPS("),p("code",null,"proxy"),l(")")]),p("li",null,[l("广告流量屏蔽("),p("code",null,"block"),l(")")])])]),p("li",null,[p("p",null,[l("向 VPS 转发的国外流量,会跨过防火墙,【流入("),p("code",null,"inbounds"),l(")】 "),p("code",null,"Xray"),l(" 服务器端")])]),p("li",null,[p("p",null,[l("流量进入服务器端后,与客户端一样,会被【服务器端路由("),p("code",null,"routing"),l(")】按规则处理后,向不同方向【流出"),p("code",null,"(outbounds)"),l("】:")]),p("ol",null,[p("li",null,[l("因为已经在防火墙之外,所以流量默认直连,你就可以访问到不存在网站们了("),p("code",null,"direct"),l(")")]),p("li",null,[l("如果需要在不同的 VPS 之间做链式转发,就可以继续配置转发规则("),p("code",null,"proxy"),l(")")]),p("li",null,[l("你可以在服务器端继续禁用各种你想禁用的流量,如广告、BT 下载等("),p("code",null,"block"),l(")")])])])],-1),q={class:"custom-container warning"},y=p("p",{class:"custom-container-title"},"注意",-1),g=p("p",null,[l("请务必记得,"),p("code",null,"Xray"),l(" 的路由配置非常灵活,上面的说明只是无限可能性中的一种。")],-1),h=p("p",null,[l("借助 "),p("code",null,"geosite.dat"),l(" 和 "),p("code",null,"geoip.dat"),l(" 这两个文件,可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 "),p("code",null,"GFWList"),l(" 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)")],-1),x=l("现在,"),f=l("《路由 (routing) 功能简析》"),S=l(" 已经上线,我建议对路由功能有兴趣的同学,先继续跟着本文完成客户端的基础配置,之后再去这里详细学习。"),X=p("h2",{id:"_8-2-客户端与服务器端正确连接",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-2-客户端与服务器端正确连接","aria-hidden":"true"},"#"),l(" 8.2 客户端与服务器端正确连接")],-1),v=p("p",null,[l("现在你已经理解了 "),p("code",null,"Xray"),l(" 的工作原理,那么接下来的配置,其实就是【告诉你的客户端如何连接 VPS 服务器】。这和你已经很熟悉的、告诉"),p("code",null,"PuTTY"),l("如何远程连接服务器是一样的。只不过 Xray 连接时的要素不止是【IP 地址】+【端口】+【用户名】+【密码】这四要素了。")],-1),_=l("实际上,"),P=p("code",null,"Xray",-1),w=l("的连接要素是由不同的"),N=l("协议"),I=l("决定的。本文在第 7 章的配置文件 "),T=p("code",null,"config.json",-1),L=l(" 里,我们使用 "),C=p("code",null,"Xray",-1),D=l(" 下独特而强大的 "),V=p("code",null,"VLESS",-1),j=l(" 协议 + "),G=p("code",null,"XTLS",-1),O=l(" 流控。所以看看那个配置文件的内容就能知道,这个协议组合的连接要素有:"),A=p("ul",null,[p("li",null,[l("服务器【地址】: "),p("code",null,"a-name.yourdomain.com")]),p("li",null,[l("服务器【端口】: "),p("code",null,"443")]),p("li",null,[l("连接的【协议】: "),p("code",null,"vless")]),p("li",null,[l("连接的【流控】: "),p("code",null,"xtls-rprx-vision"),l(" (vision 模式适合全平台)")]),p("li",null,[l("连接的【验证】: "),p("code",null,"uuiduuid-uuid-uuid-uuiduuiduuid")]),p("li",null,[l("连接的【安全】: "),p("code",null,'"allowInsecure": false')])],-1),R=p("p",null,"鉴于新人一般都会使用手机 APP 或者电脑的 GUI 客户端,我就把常用的客户端罗列在下面。每个客户端都有自己独特的配置界面,逐一截图展示并不现实,所以请你务必仔细阅读这些客户端的说明、然后把上述要素填入合适的地方即可。",-1),E=p("div",{class:"custom-container warning"},[p("p",{class:"custom-container-title"},"注意"),p("p",null,[l("许多工具其实是同时支持 "),p("code",null,"xray-core"),l(" 和 "),p("code",null,"v2fly-core"),l(" 的,但默认内置的不一定是哪个,所以别忘记检查一下是否是你想要的那个在工作哦!")])],-1),F=p("p",null,[p("strong",null,"v2rayN - 适用于 Windows 平台")],-1),H=l("请从它的"),Q={href:"https://github.com/2dust/v2rayN/releases",target:"_blank",rel:"noopener noreferrer"},W=l("GitHub 仓库 Release 页面"),Y=l("获取最新版"),z=p("li",null,"请根据该客户端的说明进行设置",-1),B=p("p",null,[p("strong",null,"v2rayNG - 适用于 Android 平台")],-1),M=l("请从它的"),U={href:"https://github.com/2dust/v2rayNG/releases",target:"_blank",rel:"noopener noreferrer"},J=l("GitHub 仓库 Release 页面"),K=l("获取最新版"),Z=p("li",null,"请根据该客户端的说明进行设置",-1),$=p("li",null,[p("p",null,[p("strong",null,"Shadowrocket - 适用于 iOS, 基于苹果 M 芯片的 macOS")]),p("ul",null,[p("li",null,"你需要注册一个【非中国区】的 iCloud 账户"),p("li",null,"你需要通过 App Store 搜索并购买"),p("li",null,"请根据该客户端的说明进行设置")])],-1),nn=p("p",null,[p("strong",null,"Qv2ray - 跨平台图形界面,适用于 Linux, Windows, macOS")],-1),sn=l("请从它的"),an={href:"https://github.com/Qv2ray/Qv2ray/releases",target:"_blank",rel:"noopener noreferrer"},pn=l("GitHub 仓库 Release 页面"),on=l("获取最新版(还可以从它的"),tn={href:"https://github.com/Qv2ray/Qv2ray/actions",target:"_blank",rel:"noopener noreferrer"},en=l("GitHub 自动构建仓库"),ln=l("寻找更新的版本)"),un=l("请从它的"),rn={href:"https://qv2ray.net/",target:"_blank",rel:"noopener noreferrer"},cn=l("项目主页"),bn=l("学习文档"),kn=p("li",null,"请根据该客户端的说明进行设置",-1),mn=p("p",null,[p("strong",null,"V2RayXS - 基于 V2RayX 开发的一款使用 xray-core 的 macOS 客户端")],-1),dn=l("请从它的 "),qn={href:"https://github.com/tzmax/v2rayXS/releases",target:"_blank",rel:"noopener noreferrer"},yn=l("GitHub 仓库 Release 页面"),gn=l(" 获取最新版"),hn=l("支持一键导入 "),xn={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},fn=l("VMessAEAD / VLESS 分享链接标准提案"),Sn=l(" 为标准的分享链接"),Xn=p("li",null,"请根据该客户端的说明进行设置",-1),vn=p("p",null,"到这一步,你的全套配置就已经可以正常使用啦!",-1),_n=p("h2",{id:"_8-3-附加题-1-在-pc-端手工配置-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-3-附加题-1-在-pc-端手工配置-xray-core","aria-hidden":"true"},"#"),l(" 8.3 附加题 1:在 PC 端手工配置 "),p("code",null,"xray-core")],-1),Pn=p("p",null,[l("虽然到上面一步已经可以结束了,但是如果你是个好奇心强、记忆力好的的同学,一定会想起来我在上一章说过,你把"),p("code",null,"xray-core"),l(" 的二进制文件“放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。” 那究竟要怎样直接使用 "),p("code",null,"xray-core"),l(" 做客户端呢?")],-1),wn=p("p",null,"为了回答这个问题,我加入了附加题章节,有一点点超纲,有一点点麻烦,但费这个笔墨是因为这个方式有它的优势:",-1),Nn=p("ul",null,[p("li",null,[p("p",null,"第一时间获得最新版而无需等待 APP 升级适配")]),p("li",null,[p("p",null,"灵活自由的路由配置能力(当然 GUI 客户端中 Qv2ray 的高级路由编辑器非常强大,也可以完整实现 xray-core 的路由配置功能)")]),p("li",null,[p("p",null,"节约系统资源 (GUI 界面一定会有资源消耗,消耗的多少则取决于客户端的实现)")])],-1),In=p("p",null,"它的劣势应该就是【需要手写配置文件】有点麻烦了。但其实,你想想,服务器上你已经成功的写过一次了,现在又有什么区别呢?接下来,还是老样子,我们分解一下步骤:",-1),Tn=l("首先请从 Xray 官方的 "),Ln={href:"https://github.com/XTLS/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},Cn=l("GitHub 仓库 Release 页面"),Dn=l(" 获取对应平台的版本,并解压缩到合适的文件夹"),Vn=u('
  • 在合适的文件夹建立空白配置文件:config.json (自己常用平台下新建文件大家肯定都会,这就真不用啰嗦了)

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

  • 填写客户端配置

    • 我就以 8.1 原理说明里展示的基本三类分流(国内流量直连、国际流量转发 VPS、广告流量屏蔽),结合 8.2 的连接要素,写成一个配置文件
    • 请将 uuid 替换成与你服务器一致的 uuid
    • 请将 address 替换成你的真实域名
    • 请将 serverName 替换成你的真实域名
    • 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
    // REFERENCE:\n// https://github.com/XTLS/Xray-examples\n// https://xtls.github.io/config/\n\n// 常用的config文件,不论服务器端还是客户端,都有5个部分。外加小小白解读:\n// ┌─ 1_log          日志设置 - 日志写什么,写哪里(出错时有据可查)\n// ├─ 2_dns          DNS-设置 - DNS怎么查(防DNS污染、防偷窥、避免国内外站匹配到国外服务器等)\n// ├─ 3_routing      分流设置 - 流量怎么分类处理(是否过滤广告、是否国内外分流)\n// ├─ 4_inbounds     入站设置 - 什么流量可以流入Xray\n// └─ 5_outbounds    出站设置 - 流出Xray的流量往哪里去\n\n{\n  // 1_日志设置\n  // 注意,本例中我默认注释掉了日志文件,因为windows, macOS, Linux 需要写不同的路径,请自行配置\n  "log": {\n    // "access": "/home/local/xray_log/access.log",    // 访问记录\n    // "error": "/home/local/xray_log/error.log",    // 错误记录\n    "loglevel": "warning" // 内容从少到多: "none", "error", "warning", "info", "debug"\n  },\n\n  // 2_DNS设置\n  "dns": {\n    "servers": [\n      // 2.1 国外域名使用国外DNS查询\n      {\n        "address": "1.1.1.1",\n        "domains": ["geosite:geolocation-!cn"]\n      },\n      // 2.2 国内域名使用国内DNS查询,并期待返回国内的IP,若不是国内IP则舍弃,用下一个查询\n      {\n        "address": "223.5.5.5",\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      // 2.3 作为2.2的备份,对国内网站进行二次查询\n      {\n        "address": "114.114.114.114",\n        "domains": ["geosite:cn"]\n      },\n      // 2.4 最后的备份,上面全部失败时,用本机DNS查询\n      "localhost"\n    ]\n  },\n\n  // 3_分流设置\n  // 所谓分流,就是将符合否个条件的流量,用指定`tag`的出站协议去处理(对应配置的5.x内容)\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      // 3.1 广告域名屏蔽\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      // 3.2 国内域名直连\n      {\n        "type": "field",\n        "domain": ["geosite:cn"],\n        "outboundTag": "direct"\n      },\n      // 3.3 国内IP直连\n      {\n        "type": "field",\n        "ip": ["geoip:cn", "geoip:private"],\n        "outboundTag": "direct"\n      },\n      // 3.4 国外域名代理\n      {\n        "type": "field",\n        "domain": ["geosite:geolocation-!cn"],\n        "outboundTag": "proxy"\n      },\n      // 3.5 默认规则\n      // 在Xray中,任何不符合上述路由规则的流量,都会默认使用【第一个outbound(5.1)】的设置,所以一定要把转发VPS的outbound放第一个\n      // 3.6 走国内"223.5.5.5"的DNS查询流量分流走direct出站\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct"\n      }\n    ]\n  },\n\n  // 4_入站设置\n  "inbounds": [\n    // 4.1 一般都默认使用socks5协议作本地转发\n    {\n      "tag": "socks-in",\n      "protocol": "socks",\n      "listen": "127.0.0.1", // 这个是通过socks5协议做本地转发的地址\n      "port": 10800, // 这个是通过socks5协议做本地转发的端口\n      "settings": {\n        "udp": true\n      }\n    },\n    // 4.2 有少数APP不兼容socks协议,需要用http协议做转发,则可以用下面的端口\n    {\n      "tag": "http-in",\n      "protocol": "http",\n      "listen": "127.0.0.1", // 这个是通过http协议做本地转发的地址\n      "port": 10801 // 这个是通过http协议做本地转发的端口\n    }\n  ],\n\n  // 5_出站设置\n  "outbounds": [\n    // 5.1 默认转发VPS\n    // 一定放在第一个,在routing 3.5 里面已经说明了,这等于是默认规则,所有不符合任何规则的流量都走这个\n    {\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "a-name.yourdomain.com", // 替换成你的真实域名\n            "port": 443,\n            "users": [\n              {\n                "id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid", // 和服务器端的一致\n                "flow": "xtls-rprx-vision",\n                "encryption": "none",\n                "level": 0\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "tls",\n        "tlsSettings": {\n          "serverName": "a-name.yourdomain.com", // 替换成你的真实域名\n          "allowInsecure": false, // 禁止不安全证书\n          "fingerprint": "chrome" // 通过 uTLS 库 模拟 Chrome / Firefox / Safari 或随机生成的指纹\n        }\n      }\n    },\n    // 5.2 用`freedom`协议直连出站,即当routing中指定'direct'流出时,调用这个协议做处理\n    {\n      "tag": "direct",\n      "protocol": "freedom"\n    },\n    // 5.3 用`blackhole`协议屏蔽流量,即当routing中指定'block'时,调用这个协议做处理\n    {\n      "tag": "block",\n      "protocol": "blackhole"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
  • ',3),jn=p("h2",{id:"_8-4-附加题-2-在-pc-端手工运行-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-4-附加题-2-在-pc-端手工运行-xray-core","aria-hidden":"true"},"#"),l(" 8.4 附加题 2:在 PC 端手工运行 "),p("code",null,"xray-core")],-1),Gn=p("p",null,[l("写好了配置文件该,要怎么让 "),p("code",null,"xray-core"),l(" 运行起来呢?双击好像并没有反应啊?")],-1),On=p("p",null,"首先,你要找到电脑上的【命令行界面】。",-1),An=p("ol",null,[p("li",null,[l("Linux 桌面、macOS 系统的同学肯定已经比较熟悉了,搜索 "),p("code",null,"Console"),l(" 或者 "),p("code",null,"Terminal"),l(" 就可以")]),p("li",null,[l("Windows 就可以搜索使用 "),p("code",null,"Cmd"),l(" 或者 "),p("code",null,"Powershell"),l(" 等程序(WSL 的同学你坐下,你的 "),p("code",null,"Console"),l(" 当然也可以)")])],-1),Rn=p("p",null,[l("其次,我们要做的事情是【让 "),p("code",null,"xray"),l(" 找到并读取配置文件 "),p("code",null,"config.json"),l(",然后运行】,所以:")],-1),En=p("ol",null,[p("li",null,[p("p",null,[l("在 Windows 下,假设你的 "),p("code",null,"Xray"),l(" 程序位置是 "),p("code",null,"C:\\Xray-windows-64\\xray.exe"),l(",配置文件位置是"),p("code",null,"C:\\Xray-windows-64\\config.json"),l(",那么正确的启动命令就是:")]),p("div",{class:"language-bash ext-sh line-numbers-mode"},[p("pre",{class:"language-bash"},[p("code",null,[l("C:"),p("span",{class:"token punctuation"},"\\"),l("Xray-windows-64"),p("span",{class:"token punctuation"},"\\"),l("xray.exe -c C:"),p("span",{class:"token punctuation"},"\\"),l("Xray-windows-64"),p("span",{class:"token punctuation"},"\\"),l("config.json\n")])]),p("div",{class:"line-numbers"},[p("span",{class:"line-number"},"1"),p("br")])]),p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"说明"),p("p",null,[l("这里的 "),p("code",null,"-c"),l(" 就是指定配置文件路径的参数,告诉 "),p("code",null,"xray"),l(" 去后面的位置找配置文件")])])]),p("li",null,[p("p",null,[l("相似的,在 Linux 和 macOS 下,假设你的 "),p("code",null,"Xray"),l(" 程序位置是 "),p("code",null,"/usr/local/bin/xray"),l(",配置文件位置是"),p("code",null,"/usr/local/etc/xray/config.json"),l(",那么正确的启动命令就是")]),p("div",{class:"language-bash ext-sh line-numbers-mode"},[p("pre",{class:"language-bash"},[p("code",null,"/usr/local/bin/xray -c /usr/local/etc/xray/config.json\n")]),p("div",{class:"line-numbers"},[p("span",{class:"line-number"},"1"),p("br")])]),p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"说明"),p("p",null,[l("每个系统都有系统路径变量,所以写 "),p("code",null,"Xray"),l(" 程序时不一定要写绝对路径。但是写了肯定没错,所以我就如此演示了。")])])])],-1),Fn=p("h2",{id:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-5-附加题-3-在-pc-端开机自动运行-xray-core","aria-hidden":"true"},"#"),l(" 8.5 附加题 3:在 PC 端开机自动运行 "),p("code",null,"xray-core")],-1),Hn=p("p",null,[l("如果你真的尝试了手动运行 "),p("code",null,"xray-core"),l(",你一定会发现这个方式还有点小问题:")],-1),Qn=p("ol",null,[p("li",null,[l("每次运行 "),p("code",null,"Xray"),l(" 都要出现一个黑乎乎的窗口,很丑")]),p("li",null,"不能开机自动运行,每次都要手工输入,十分不方便")],-1),Wn=p("p",null,[l("我可以肯定的告诉你:"),p("strong",null,"完全可以解决"),l("。但是具体的解决方式,就当作课外作业留给大家吧!(友情提示,文档站的问答区有线索哦)")],-1),Yn=p("h2",{id:"_8-6-圆满完成",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-6-圆满完成","aria-hidden":"true"},"#"),l(" 8.6 圆满完成!")],-1),zn=p("p",null,[l("我相信,有耐心看到这里的同学,都是兼具好奇心和行动力的学习派!我现在要郑重的恭喜你,因为到了这里,你已经完完整整的【"),p("strong",null,"从第一条命令开始,完成了 VPS 服务器部署,并成功的在客户端配置使用 Xray"),l("】了!这毫无疑问是一个巨大的胜利!")],-1),Bn=p("p",null,[l("我相信,你现在一定对"),p("code",null,"Linux"),l("不再恐惧,对"),p("code",null,"Xray"),l("不再陌生了吧!")],-1),Mn=p("p",null,[p("strong",null,"至此,小小白白话文圆满结束!")],-1),Un=p("blockquote",null,[p("p",null,"⬛⬛⬛⬛⬛⬛⬛⬛ 100%")],-1),Jn=p("h2",{id:"_8-7-to-infinity-and-beyond",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-7-to-infinity-and-beyond","aria-hidden":"true"},"#"),l(" 8.7 TO INFINITY AND BEYOND!")],-1),Kn=p("p",null,[p("strong",null,"但现在你看到的,远远不是 Xray 的全貌。")],-1),Zn=p("p",null,[p("code",null,"Xray"),l("是一个强大而丰富的网络工具集合,平台化的提供了众多模块,可以像瑞士军刀一样,通过灵活的配置组合解决各种不同的问题。而本文,仅仅蜻蜓点水的用了"),p("strong",null,"最简单"),l("、"),p("strong",null,"最直观"),l("的配置来做"),p("strong",null,"基础演示"),l("。")],-1),$n=p("p",null,"如果你觉得现在已经完全够用了,那就好好的享受它给你带来的信息自由。但如果你的好奇心依然不能停歇,那就去继续挖掘它无限的可能性吧!",-1),ns=p("p",null,"需要更多信息,可以到这里寻找:",-1),ss={href:"https://xtls.github.io/",target:"_blank",rel:"noopener noreferrer"},as=l("xtls.github.io"),ps=l(" - 官方文档站"),os={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},ts=l("官方 Telegram 群组"),es=l(" - 活跃而友善的官方讨论社区"),ls=p("p",null,[p("img",{src:"/Xray-docs-next/assets/ch08-img02-buzz.2c8cb2a0.png",alt:"TO INFINITY AND BEYOND!"})],-1),us=p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"不算后记的后记"),p("p",null,"希望我陪你走过的这一段小小的旅程,可以成为你网络生活中的一份小小助力。"),p("p",null,"这篇文章里的工具和信息难免会一点点的陈旧过时,但你一定会逐渐成长为大佬。未来的某个时间,若你能偶尔想起这篇教程、想起我写下本文的初衷,那我衷心希望你能够薪火相传、把最新的知识分享给后来人,让这一份小小的助力在社区里坚定的传递下去。"),p("p",null,"这是个大雪封山乌云密布的世界,人们孤独的走在各自的路上试图寻找阳光,如果大家偶尔交汇时不能守望相助互相鼓励,那最终剩下的,恐怕只有【千山鸟飞绝 万径人踪灭】的凄凉了吧。")],-1);r.render=function(l,u){const r=n("RouterLink"),rs=n("OutboundLink");return s(),a(e,null,[c,i,b,k,m,d,p("div",q,[y,g,h,p("p",null,[x,o(r,{to:"/document/level-1/routing-lv1-part1.html"},{default:t((()=>[f])),_:1}),S])]),X,v,p("p",null,[_,P,w,o(r,{to:"/config/inbounds/"},{default:t((()=>[N])),_:1}),I,T,L,C,D,V,j,G,O]),A,R,E,p("ul",null,[p("li",null,[F,p("ul",null,[p("li",null,[H,p("a",Q,[W,o(rs)]),Y]),z])]),p("li",null,[B,p("ul",null,[p("li",null,[M,p("a",U,[J,o(rs)]),K]),Z])]),$,p("li",null,[nn,p("ul",null,[p("li",null,[sn,p("a",an,[pn,o(rs)]),on,p("a",tn,[en,o(rs)]),ln]),p("li",null,[un,p("a",rn,[cn,o(rs)]),bn]),kn])]),p("li",null,[mn,p("ul",null,[p("li",null,[dn,p("a",qn,[yn,o(rs)]),gn]),p("li",null,[hn,p("a",xn,[fn,o(rs)]),Sn]),Xn])])]),vn,_n,Pn,wn,Nn,In,p("ol",null,[p("li",null,[p("p",null,[Tn,p("a",Ln,[Cn,o(rs)]),Dn])]),Vn]),jn,Gn,On,An,Rn,En,Fn,Hn,Qn,Wn,Yn,zn,Bn,Mn,Un,Jn,Kn,Zn,$n,ns,p("ol",null,[p("li",null,[p("a",ss,[as,o(rs)]),ps]),p("li",null,[p("a",os,[ts,o(rs)]),es])]),ls,us],64)};export default r; diff --git a/assets/ch08-xray-clients.html.347d9b86.js b/assets/ch08-xray-clients.html.a6c845bc.js similarity index 99% rename from assets/ch08-xray-clients.html.347d9b86.js rename to assets/ch08-xray-clients.html.a6c845bc.js index 7df0dfc5e..3f530df9c 100644 --- a/assets/ch08-xray-clients.html.347d9b86.js +++ b/assets/ch08-xray-clients.html.a6c845bc.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as o,w as t,F as e,e as l,d as u}from"./app.755d843f.js";const r={},c=p("h1",{id:"【第-8-章】xray-客户端篇",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#【第-8-章】xray-客户端篇","aria-hidden":"true"},"#"),l(" 【第 8 章】Xray 客户端篇")],-1),i=p("h2",{id:"_8-1-xray-的工作原理简述",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-1-xray-的工作原理简述","aria-hidden":"true"},"#"),l(" 8.1 Xray 的工作原理简述")],-1),b=p("p",null,[l("要正确的配置和使用"),p("code",null,"Xray"),l(",就需要正确的理解其工作原理,对于新人,可以先看看下面简化的示意图(省略了许多复杂的设置):")],-1),k=p("p",null,[p("img",{src:"/Xray-docs-next/assets/ch08-img01-flow.e9c45ad1.png",alt:"Xray数据流向"})],-1),m=p("p",null,"这其中的关键点是:",-1),d=p("ol",null,[p("li",null,[p("p",null,[l("APP 要主动或借助转发工具,将数据【流入("),p("code",null,"inbounds"),l(")】"),p("code",null,"Xray"),l(" 客户端")])]),p("li",null,[p("p",null,[l("流量进入客户端后,会被【客户端路由("),p("code",null,"routing"),l(")】按规则处理后,向不同方向【流出"),p("code",null,"(outbounds)"),l("】"),p("code",null,"Xray"),l(" 客户端。比如:")]),p("ol",null,[p("li",null,[l("国内流量直连("),p("code",null,"direct"),l(")")]),p("li",null,[l("国外流量转发 VPS("),p("code",null,"proxy"),l(")")]),p("li",null,[l("广告流量屏蔽("),p("code",null,"block"),l(")")])])]),p("li",null,[p("p",null,[l("向 VPS 转发的国外流量,会跨过防火墙,【流入("),p("code",null,"inbounds"),l(")】 "),p("code",null,"Xray"),l(" 服务器端")])]),p("li",null,[p("p",null,[l("流量进入服务器端后,与客户端一样,会被【服务器端路由("),p("code",null,"routing"),l(")】按规则处理后,向不同方向【流出"),p("code",null,"(outbounds)"),l("】:")]),p("ol",null,[p("li",null,[l("因为已经在防火墙之外,所以流量默认直连,你就可以访问到不存在网站们了("),p("code",null,"direct"),l(")")]),p("li",null,[l("如果需要在不同的 VPS 之间做链式转发,就可以继续配置转发规则("),p("code",null,"proxy"),l(")")]),p("li",null,[l("你可以在服务器端继续禁用各种你想禁用的流量,如广告、BT 下载等("),p("code",null,"block"),l(")")])])])],-1),q={class:"custom-container warning"},y=p("p",{class:"custom-container-title"},"注意",-1),g=p("p",null,[l("请务必记得,"),p("code",null,"Xray"),l(" 的路由配置非常灵活,上面的说明只是无限可能性中的一种。")],-1),h=p("p",null,[l("借助 "),p("code",null,"geosite.dat"),l(" 和 "),p("code",null,"geoip.dat"),l(" 这两个文件,可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 "),p("code",null,"GFWList"),l(" 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)")],-1),x=l("现在,"),f=l("《路由 (routing) 功能简析》"),S=l(" 已经上线,我建议对路由功能有兴趣的同学,先继续跟着本文完成客户端的基础配置,之后再去这里详细学习。"),X=p("h2",{id:"_8-2-客户端与服务器端正确连接",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-2-客户端与服务器端正确连接","aria-hidden":"true"},"#"),l(" 8.2 客户端与服务器端正确连接")],-1),v=p("p",null,[l("现在你已经理解了 "),p("code",null,"Xray"),l(" 的工作原理,那么接下来的配置,其实就是【告诉你的客户端如何连接 VPS 服务器】。这和你已经很熟悉的、告诉"),p("code",null,"PuTTY"),l("如何远程连接服务器是一样的。只不过 Xray 连接时的要素不止是【IP 地址】+【端口】+【用户名】+【密码】这四要素了。")],-1),_=l("实际上,"),P=p("code",null,"Xray",-1),w=l("的连接要素是由不同的"),N=l("协议"),I=l("决定的。本文在第 7 章的配置文件 "),T=p("code",null,"config.json",-1),L=l(" 里,我们使用 "),C=p("code",null,"Xray",-1),D=l(" 下独特而强大的 "),V=p("code",null,"VLESS",-1),j=l(" 协议 + "),G=p("code",null,"XTLS",-1),O=l(" 流控。所以看看那个配置文件的内容就能知道,这个协议组合的连接要素有:"),A=p("ul",null,[p("li",null,[l("服务器【地址】: "),p("code",null,"a-name.yourdomain.com")]),p("li",null,[l("服务器【端口】: "),p("code",null,"443")]),p("li",null,[l("连接的【协议】: "),p("code",null,"vless")]),p("li",null,[l("连接的【流控】: "),p("code",null,"xtls-rprx-vision"),l(" (vision 模式适合全平台)")]),p("li",null,[l("连接的【验证】: "),p("code",null,"uuiduuid-uuid-uuid-uuiduuiduuid")]),p("li",null,[l("连接的【安全】: "),p("code",null,'"allowInsecure": false')])],-1),R=p("p",null,"鉴于新人一般都会使用手机 APP 或者电脑的 GUI 客户端,我就把常用的客户端罗列在下面。每个客户端都有自己独特的配置界面,逐一截图展示并不现实,所以请你务必仔细阅读这些客户端的说明、然后把上述要素填入合适的地方即可。",-1),E=p("div",{class:"custom-container warning"},[p("p",{class:"custom-container-title"},"注意"),p("p",null,[l("许多工具其实是同时支持 "),p("code",null,"xray-core"),l(" 和 "),p("code",null,"v2fly-core"),l(" 的,但默认内置的不一定是哪个,所以别忘记检查一下是否是你想要的那个在工作哦!")])],-1),F=p("p",null,[p("strong",null,"v2rayN - 适用于 Windows 平台")],-1),H=l("请从它的"),Q={href:"https://github.com/2dust/v2rayN/releases",target:"_blank",rel:"noopener noreferrer"},W=l("GitHub 仓库 Release 页面"),Y=l("获取最新版"),z=p("li",null,"请根据该客户端的说明进行设置",-1),B=p("p",null,[p("strong",null,"v2rayNG - 适用于 Android 平台")],-1),M=l("请从它的"),U={href:"https://github.com/2dust/v2rayNG/releases",target:"_blank",rel:"noopener noreferrer"},J=l("GitHub 仓库 Release 页面"),K=l("获取最新版"),Z=p("li",null,"请根据该客户端的说明进行设置",-1),$=p("li",null,[p("p",null,[p("strong",null,"Shadowrocket - 适用于 iOS, 基于苹果 M 芯片的 macOS")]),p("ul",null,[p("li",null,"你需要注册一个【非中国区】的 iCloud 账户"),p("li",null,"你需要通过 App Store 搜索并购买"),p("li",null,"请根据该客户端的说明进行设置")])],-1),nn=p("p",null,[p("strong",null,"Qv2ray - 跨平台图形界面,适用于 Linux, Windows, macOS")],-1),sn=l("请从它的"),an={href:"https://github.com/Qv2ray/Qv2ray/releases",target:"_blank",rel:"noopener noreferrer"},pn=l("GitHub 仓库 Release 页面"),on=l("获取最新版(还可以从它的"),tn={href:"https://github.com/Qv2ray/Qv2ray/actions",target:"_blank",rel:"noopener noreferrer"},en=l("GitHub 自动构建仓库"),ln=l("寻找更新的版本)"),un=l("请从它的"),rn={href:"https://qv2ray.net/",target:"_blank",rel:"noopener noreferrer"},cn=l("项目主页"),bn=l("学习文档"),kn=p("li",null,"请根据该客户端的说明进行设置",-1),mn=p("p",null,[p("strong",null,"V2RayXS - 基于 V2RayX 开发的一款使用 xray-core 的 macOS 客户端")],-1),dn=l("请从它的 "),qn={href:"https://github.com/tzmax/v2rayXS/releases",target:"_blank",rel:"noopener noreferrer"},yn=l("GitHub 仓库 Release 页面"),gn=l(" 获取最新版"),hn=l("支持一键导入 "),xn={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},fn=l("VMessAEAD / VLESS 分享链接标准提案"),Sn=l(" 为标准的分享链接"),Xn=p("li",null,"请根据该客户端的说明进行设置",-1),vn=p("p",null,"到这一步,你的全套配置就已经可以正常使用啦!",-1),_n=p("h2",{id:"_8-3-附加题-1-在-pc-端手工配置-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-3-附加题-1-在-pc-端手工配置-xray-core","aria-hidden":"true"},"#"),l(" 8.3 附加题 1:在 PC 端手工配置 "),p("code",null,"xray-core")],-1),Pn=p("p",null,[l("虽然到上面一步已经可以结束了,但是如果你是个好奇心强、记忆力好的的同学,一定会想起来我在上一章说过,你把"),p("code",null,"xray-core"),l(" 的二进制文件“放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。” 那究竟要怎样直接使用 "),p("code",null,"xray-core"),l(" 做客户端呢?")],-1),wn=p("p",null,"为了回答这个问题,我加入了附加题章节,有一点点超纲,有一点点麻烦,但费这个笔墨是因为这个方式有它的优势:",-1),Nn=p("ul",null,[p("li",null,[p("p",null,"第一时间获得最新版而无需等待 APP 升级适配")]),p("li",null,[p("p",null,"灵活自由的路由配置能力(当然 GUI 客户端中 Qv2ray 的高级路由编辑器非常强大,也可以完整实现 xray-core 的路由配置功能)")]),p("li",null,[p("p",null,"节约系统资源 (GUI 界面一定会有资源消耗,消耗的多少则取决于客户端的实现)")])],-1),In=p("p",null,"它的劣势应该就是【需要手写配置文件】有点麻烦了。但其实,你想想,服务器上你已经成功的写过一次了,现在又有什么区别呢?接下来,还是老样子,我们分解一下步骤:",-1),Tn=l("首先请从 Xray 官方的 "),Ln={href:"https://github.com/XTLS/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},Cn=l("GitHub 仓库 Release 页面"),Dn=l(" 获取对应平台的版本,并解压缩到合适的文件夹"),Vn=u('
  • 在合适的文件夹建立空白配置文件:config.json (自己常用平台下新建文件大家肯定都会,这就真不用啰嗦了)

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

  • 填写客户端配置

    • 我就以 8.1 原理说明里展示的基本三类分流(国内流量直连、国际流量转发 VPS、广告流量屏蔽),结合 8.2 的连接要素,写成一个配置文件
    • 请将 uuid 替换成与你服务器一致的 uuid
    • 请将 address 替换成你的真实域名
    • 请将 serverName 替换成你的真实域名
    • 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
    // REFERENCE:\n// https://github.com/XTLS/Xray-examples\n// https://xtls.github.io/config/\n\n// 常用的config文件,不论服务器端还是客户端,都有5个部分。外加小小白解读:\n// ┌─ 1_log          日志设置 - 日志写什么,写哪里(出错时有据可查)\n// ├─ 2_dns          DNS-设置 - DNS怎么查(防DNS污染、防偷窥、避免国内外站匹配到国外服务器等)\n// ├─ 3_routing      分流设置 - 流量怎么分类处理(是否过滤广告、是否国内外分流)\n// ├─ 4_inbounds     入站设置 - 什么流量可以流入Xray\n// └─ 5_outbounds    出站设置 - 流出Xray的流量往哪里去\n\n{\n  // 1_日志设置\n  // 注意,本例中我默认注释掉了日志文件,因为windows, macOS, Linux 需要写不同的路径,请自行配置\n  "log": {\n    // "access": "/home/local/xray_log/access.log",    // 访问记录\n    // "error": "/home/local/xray_log/error.log",    // 错误记录\n    "loglevel": "warning" // 内容从少到多: "none", "error", "warning", "info", "debug"\n  },\n\n  // 2_DNS设置\n  "dns": {\n    "servers": [\n      // 2.1 国外域名使用国外DNS查询\n      {\n        "address": "1.1.1.1",\n        "domains": ["geosite:geolocation-!cn"]\n      },\n      // 2.2 国内域名使用国内DNS查询,并期待返回国内的IP,若不是国内IP则舍弃,用下一个查询\n      {\n        "address": "223.5.5.5",\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      // 2.3 作为2.2的备份,对国内网站进行二次查询\n      {\n        "address": "114.114.114.114",\n        "domains": ["geosite:cn"]\n      },\n      // 2.4 最后的备份,上面全部失败时,用本机DNS查询\n      "localhost"\n    ]\n  },\n\n  // 3_分流设置\n  // 所谓分流,就是将符合否个条件的流量,用指定`tag`的出站协议去处理(对应配置的5.x内容)\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      // 3.1 广告域名屏蔽\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      // 3.2 国内域名直连\n      {\n        "type": "field",\n        "domain": ["geosite:cn"],\n        "outboundTag": "direct"\n      },\n      // 3.3 国内IP直连\n      {\n        "type": "field",\n        "ip": ["geoip:cn", "geoip:private"],\n        "outboundTag": "direct"\n      },\n      // 3.4 国外域名代理\n      {\n        "type": "field",\n        "domain": ["geosite:geolocation-!cn"],\n        "outboundTag": "proxy"\n      },\n      // 3.5 默认规则\n      // 在Xray中,任何不符合上述路由规则的流量,都会默认使用【第一个outbound(5.1)】的设置,所以一定要把转发VPS的outbound放第一个\n      // 3.6 走国内"223.5.5.5"的DNS查询流量分流走direct出站\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct"\n      }\n    ]\n  },\n\n  // 4_入站设置\n  "inbounds": [\n    // 4.1 一般都默认使用socks5协议作本地转发\n    {\n      "tag": "socks-in",\n      "protocol": "socks",\n      "listen": "127.0.0.1", // 这个是通过socks5协议做本地转发的地址\n      "port": 10800, // 这个是通过socks5协议做本地转发的端口\n      "settings": {\n        "udp": true\n      }\n    },\n    // 4.2 有少数APP不兼容socks协议,需要用http协议做转发,则可以用下面的端口\n    {\n      "tag": "http-in",\n      "protocol": "http",\n      "listen": "127.0.0.1", // 这个是通过http协议做本地转发的地址\n      "port": 10801 // 这个是通过http协议做本地转发的端口\n    }\n  ],\n\n  // 5_出站设置\n  "outbounds": [\n    // 5.1 默认转发VPS\n    // 一定放在第一个,在routing 3.5 里面已经说明了,这等于是默认规则,所有不符合任何规则的流量都走这个\n    {\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "a-name.yourdomain.com", // 替换成你的真实域名\n            "port": 443,\n            "users": [\n              {\n                "id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid", // 和服务器端的一致\n                "flow": "xtls-rprx-vision",\n                "encryption": "none",\n                "level": 0\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "tls",\n        "tlsSettings": {\n          "serverName": "a-name.yourdomain.com", // 替换成你的真实域名\n          "allowInsecure": false, // 禁止不安全证书\n          "fingerprint": "chrome" // 通过 uTLS 库 模拟 Chrome / Firefox / Safari 或随机生成的指纹\n        }\n      }\n    },\n    // 5.2 用`freedom`协议直连出站,即当routing中指定'direct'流出时,调用这个协议做处理\n    {\n      "tag": "direct",\n      "protocol": "freedom"\n    },\n    // 5.3 用`blackhole`协议屏蔽流量,即当routing中指定'block'时,调用这个协议做处理\n    {\n      "tag": "block",\n      "protocol": "blackhole"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
  • ',3),jn=p("h2",{id:"_8-4-附加题-2-在-pc-端手工运行-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-4-附加题-2-在-pc-端手工运行-xray-core","aria-hidden":"true"},"#"),l(" 8.4 附加题 2:在 PC 端手工运行 "),p("code",null,"xray-core")],-1),Gn=p("p",null,[l("写好了配置文件该,要怎么让 "),p("code",null,"xray-core"),l(" 运行起来呢?双击好像并没有反应啊?")],-1),On=p("p",null,"首先,你要找到电脑上的【命令行界面】。",-1),An=p("ol",null,[p("li",null,[l("Linux 桌面、macOS 系统的同学肯定已经比较熟悉了,搜索 "),p("code",null,"Console"),l(" 或者 "),p("code",null,"Terminal"),l(" 就可以")]),p("li",null,[l("Windows 就可以搜索使用 "),p("code",null,"Cmd"),l(" 或者 "),p("code",null,"Powershell"),l(" 等程序(WSL 的同学你坐下,你的 "),p("code",null,"Console"),l(" 当然也可以)")])],-1),Rn=p("p",null,[l("其次,我们要做的事情是【让 "),p("code",null,"xray"),l(" 找到并读取配置文件 "),p("code",null,"config.json"),l(",然后运行】,所以:")],-1),En=p("ol",null,[p("li",null,[p("p",null,[l("在 Windows 下,假设你的 "),p("code",null,"Xray"),l(" 程序位置是 "),p("code",null,"C:\\Xray-windows-64\\xray.exe"),l(",配置文件位置是"),p("code",null,"C:\\Xray-windows-64\\config.json"),l(",那么正确的启动命令就是:")]),p("div",{class:"language-bash ext-sh line-numbers-mode"},[p("pre",{class:"language-bash"},[p("code",null,[l("C:"),p("span",{class:"token punctuation"},"\\"),l("Xray-windows-64"),p("span",{class:"token punctuation"},"\\"),l("xray.exe -c C:"),p("span",{class:"token punctuation"},"\\"),l("Xray-windows-64"),p("span",{class:"token punctuation"},"\\"),l("config.json\n")])]),p("div",{class:"line-numbers"},[p("span",{class:"line-number"},"1"),p("br")])]),p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"说明"),p("p",null,[l("这里的 "),p("code",null,"-c"),l(" 就是指定配置文件路径的参数,告诉 "),p("code",null,"xray"),l(" 去后面的位置找配置文件")])])]),p("li",null,[p("p",null,[l("相似的,在 Linux 和 macOS 下,假设你的 "),p("code",null,"Xray"),l(" 程序位置是 "),p("code",null,"/usr/local/bin/xray"),l(",配置文件位置是"),p("code",null,"/usr/local/etc/xray/config.json"),l(",那么正确的启动命令就是")]),p("div",{class:"language-bash ext-sh line-numbers-mode"},[p("pre",{class:"language-bash"},[p("code",null,"/usr/local/bin/xray -c /usr/local/etc/xray/config.json\n")]),p("div",{class:"line-numbers"},[p("span",{class:"line-number"},"1"),p("br")])]),p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"说明"),p("p",null,[l("每个系统都有系统路径变量,所以写 "),p("code",null,"Xray"),l(" 程序时不一定要写绝对路径。但是写了肯定没错,所以我就如此演示了。")])])])],-1),Fn=p("h2",{id:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-5-附加题-3-在-pc-端开机自动运行-xray-core","aria-hidden":"true"},"#"),l(" 8.5 附加题 3:在 PC 端开机自动运行 "),p("code",null,"xray-core")],-1),Hn=p("p",null,[l("如果你真的尝试了手动运行 "),p("code",null,"xray-core"),l(",你一定会发现这个方式还有点小问题:")],-1),Qn=p("ol",null,[p("li",null,[l("每次运行 "),p("code",null,"Xray"),l(" 都要出现一个黑乎乎的窗口,很丑")]),p("li",null,"不能开机自动运行,每次都要手工输入,十分不方便")],-1),Wn=p("p",null,[l("我可以肯定的告诉你:"),p("strong",null,"完全可以解决"),l("。但是具体的解决方式,就当作课外作业留给大家吧!(友情提示,文档站的问答区有线索哦)")],-1),Yn=p("h2",{id:"_8-6-圆满完成",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-6-圆满完成","aria-hidden":"true"},"#"),l(" 8.6 圆满完成!")],-1),zn=p("p",null,[l("我相信,有耐心看到这里的同学,都是兼具好奇心和行动力的学习派!我现在要郑重的恭喜你,因为到了这里,你已经完完整整的【"),p("strong",null,"从第一条命令开始,完成了 VPS 服务器部署,并成功的在客户端配置使用 Xray"),l("】了!这毫无疑问是一个巨大的胜利!")],-1),Bn=p("p",null,[l("我相信,你现在一定对"),p("code",null,"Linux"),l("不再恐惧,对"),p("code",null,"Xray"),l("不再陌生了吧!")],-1),Mn=p("p",null,[p("strong",null,"至此,小小白白话文圆满结束!")],-1),Un=p("blockquote",null,[p("p",null,"⬛⬛⬛⬛⬛⬛⬛⬛ 100%")],-1),Jn=p("h2",{id:"_8-7-to-infinity-and-beyond",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-7-to-infinity-and-beyond","aria-hidden":"true"},"#"),l(" 8.7 TO INFINITY AND BEYOND!")],-1),Kn=p("p",null,[p("strong",null,"但现在你看到的,远远不是 Xray 的全貌。")],-1),Zn=p("p",null,[p("code",null,"Xray"),l("是一个强大而丰富的网络工具集合,平台化的提供了众多模块,可以像瑞士军刀一样,通过灵活的配置组合解决各种不同的问题。而本文,仅仅蜻蜓点水的用了"),p("strong",null,"最简单"),l("、"),p("strong",null,"最直观"),l("的配置来做"),p("strong",null,"基础演示"),l("。")],-1),$n=p("p",null,"如果你觉得现在已经完全够用了,那就好好的享受它给你带来的信息自由。但如果你的好奇心依然不能停歇,那就去继续挖掘它无限的可能性吧!",-1),ns=p("p",null,"需要更多信息,可以到这里寻找:",-1),ss={href:"https://xtls.github.io/",target:"_blank",rel:"noopener noreferrer"},as=l("xtls.github.io"),ps=l(" - 官方文档站"),os={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},ts=l("官方 Telegram 群组"),es=l(" - 活跃而友善的官方讨论社区"),ls=p("p",null,[p("img",{src:"/Xray-docs-next/assets/ch08-img02-buzz.2c8cb2a0.png",alt:"TO INFINITY AND BEYOND!"})],-1),us=p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"不算后记的后记"),p("p",null,"希望我陪你走过的这一段小小的旅程,可以成为你网络生活中的一份小小助力。"),p("p",null,"这篇文章里的工具和信息难免会一点点的陈旧过时,但你一定会逐渐成长为大佬。未来的某个时间,若你能偶尔想起这篇教程、想起我写下本文的初衷,那我衷心希望你能够薪火相传、把最新的知识分享给后来人,让这一份小小的助力在社区里坚定的传递下去。"),p("p",null,"这是个大雪封山乌云密布的世界,人们孤独的走在各自的路上试图寻找阳光,如果大家偶尔交汇时不能守望相助互相鼓励,那最终剩下的,恐怕只有【千山鸟飞绝 万径人踪灭】的凄凉了吧。")],-1);r.render=function(l,u){const r=n("RouterLink"),rs=n("OutboundLink");return s(),a(e,null,[c,i,b,k,m,d,p("div",q,[y,g,h,p("p",null,[x,o(r,{to:"/en/document/level-1/routing-lv1-part1.html"},{default:t((()=>[f])),_:1}),S])]),X,v,p("p",null,[_,P,w,o(r,{to:"/en/config/inbounds/"},{default:t((()=>[N])),_:1}),I,T,L,C,D,V,j,G,O]),A,R,E,p("ul",null,[p("li",null,[F,p("ul",null,[p("li",null,[H,p("a",Q,[W,o(rs)]),Y]),z])]),p("li",null,[B,p("ul",null,[p("li",null,[M,p("a",U,[J,o(rs)]),K]),Z])]),$,p("li",null,[nn,p("ul",null,[p("li",null,[sn,p("a",an,[pn,o(rs)]),on,p("a",tn,[en,o(rs)]),ln]),p("li",null,[un,p("a",rn,[cn,o(rs)]),bn]),kn])]),p("li",null,[mn,p("ul",null,[p("li",null,[dn,p("a",qn,[yn,o(rs)]),gn]),p("li",null,[hn,p("a",xn,[fn,o(rs)]),Sn]),Xn])])]),vn,_n,Pn,wn,Nn,In,p("ol",null,[p("li",null,[p("p",null,[Tn,p("a",Ln,[Cn,o(rs)]),Dn])]),Vn]),jn,Gn,On,An,Rn,En,Fn,Hn,Qn,Wn,Yn,zn,Bn,Mn,Un,Jn,Kn,Zn,$n,ns,p("ol",null,[p("li",null,[p("a",ss,[as,o(rs)]),ps]),p("li",null,[p("a",os,[ts,o(rs)]),es])]),ls,us],64)};export default r; +import{r as n,o as s,c as a,a as p,b as o,w as t,F as e,e as l,d as u}from"./app.48111a85.js";const r={},c=p("h1",{id:"【第-8-章】xray-客户端篇",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#【第-8-章】xray-客户端篇","aria-hidden":"true"},"#"),l(" 【第 8 章】Xray 客户端篇")],-1),i=p("h2",{id:"_8-1-xray-的工作原理简述",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-1-xray-的工作原理简述","aria-hidden":"true"},"#"),l(" 8.1 Xray 的工作原理简述")],-1),b=p("p",null,[l("要正确的配置和使用"),p("code",null,"Xray"),l(",就需要正确的理解其工作原理,对于新人,可以先看看下面简化的示意图(省略了许多复杂的设置):")],-1),k=p("p",null,[p("img",{src:"/Xray-docs-next/assets/ch08-img01-flow.e9c45ad1.png",alt:"Xray数据流向"})],-1),m=p("p",null,"这其中的关键点是:",-1),d=p("ol",null,[p("li",null,[p("p",null,[l("APP 要主动或借助转发工具,将数据【流入("),p("code",null,"inbounds"),l(")】"),p("code",null,"Xray"),l(" 客户端")])]),p("li",null,[p("p",null,[l("流量进入客户端后,会被【客户端路由("),p("code",null,"routing"),l(")】按规则处理后,向不同方向【流出"),p("code",null,"(outbounds)"),l("】"),p("code",null,"Xray"),l(" 客户端。比如:")]),p("ol",null,[p("li",null,[l("国内流量直连("),p("code",null,"direct"),l(")")]),p("li",null,[l("国外流量转发 VPS("),p("code",null,"proxy"),l(")")]),p("li",null,[l("广告流量屏蔽("),p("code",null,"block"),l(")")])])]),p("li",null,[p("p",null,[l("向 VPS 转发的国外流量,会跨过防火墙,【流入("),p("code",null,"inbounds"),l(")】 "),p("code",null,"Xray"),l(" 服务器端")])]),p("li",null,[p("p",null,[l("流量进入服务器端后,与客户端一样,会被【服务器端路由("),p("code",null,"routing"),l(")】按规则处理后,向不同方向【流出"),p("code",null,"(outbounds)"),l("】:")]),p("ol",null,[p("li",null,[l("因为已经在防火墙之外,所以流量默认直连,你就可以访问到不存在网站们了("),p("code",null,"direct"),l(")")]),p("li",null,[l("如果需要在不同的 VPS 之间做链式转发,就可以继续配置转发规则("),p("code",null,"proxy"),l(")")]),p("li",null,[l("你可以在服务器端继续禁用各种你想禁用的流量,如广告、BT 下载等("),p("code",null,"block"),l(")")])])])],-1),q={class:"custom-container warning"},y=p("p",{class:"custom-container-title"},"注意",-1),g=p("p",null,[l("请务必记得,"),p("code",null,"Xray"),l(" 的路由配置非常灵活,上面的说明只是无限可能性中的一种。")],-1),h=p("p",null,[l("借助 "),p("code",null,"geosite.dat"),l(" 和 "),p("code",null,"geoip.dat"),l(" 这两个文件,可以很灵活的从【域名】和【IP】这两个角度、不留死角的控制流量流出的方向。这比曾经单一笼统的 "),p("code",null,"GFWList"),l(" 强大很多很多,可以做到非常细致的微调:比如可以指定 Apple 域名直连或转发、指定亚马逊域名代理或转发,百度的域名屏蔽等等。。。)")],-1),x=l("现在,"),f=l("《路由 (routing) 功能简析》"),S=l(" 已经上线,我建议对路由功能有兴趣的同学,先继续跟着本文完成客户端的基础配置,之后再去这里详细学习。"),X=p("h2",{id:"_8-2-客户端与服务器端正确连接",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-2-客户端与服务器端正确连接","aria-hidden":"true"},"#"),l(" 8.2 客户端与服务器端正确连接")],-1),v=p("p",null,[l("现在你已经理解了 "),p("code",null,"Xray"),l(" 的工作原理,那么接下来的配置,其实就是【告诉你的客户端如何连接 VPS 服务器】。这和你已经很熟悉的、告诉"),p("code",null,"PuTTY"),l("如何远程连接服务器是一样的。只不过 Xray 连接时的要素不止是【IP 地址】+【端口】+【用户名】+【密码】这四要素了。")],-1),_=l("实际上,"),P=p("code",null,"Xray",-1),w=l("的连接要素是由不同的"),N=l("协议"),I=l("决定的。本文在第 7 章的配置文件 "),T=p("code",null,"config.json",-1),L=l(" 里,我们使用 "),C=p("code",null,"Xray",-1),D=l(" 下独特而强大的 "),V=p("code",null,"VLESS",-1),j=l(" 协议 + "),G=p("code",null,"XTLS",-1),O=l(" 流控。所以看看那个配置文件的内容就能知道,这个协议组合的连接要素有:"),A=p("ul",null,[p("li",null,[l("服务器【地址】: "),p("code",null,"a-name.yourdomain.com")]),p("li",null,[l("服务器【端口】: "),p("code",null,"443")]),p("li",null,[l("连接的【协议】: "),p("code",null,"vless")]),p("li",null,[l("连接的【流控】: "),p("code",null,"xtls-rprx-vision"),l(" (vision 模式适合全平台)")]),p("li",null,[l("连接的【验证】: "),p("code",null,"uuiduuid-uuid-uuid-uuiduuiduuid")]),p("li",null,[l("连接的【安全】: "),p("code",null,'"allowInsecure": false')])],-1),R=p("p",null,"鉴于新人一般都会使用手机 APP 或者电脑的 GUI 客户端,我就把常用的客户端罗列在下面。每个客户端都有自己独特的配置界面,逐一截图展示并不现实,所以请你务必仔细阅读这些客户端的说明、然后把上述要素填入合适的地方即可。",-1),E=p("div",{class:"custom-container warning"},[p("p",{class:"custom-container-title"},"注意"),p("p",null,[l("许多工具其实是同时支持 "),p("code",null,"xray-core"),l(" 和 "),p("code",null,"v2fly-core"),l(" 的,但默认内置的不一定是哪个,所以别忘记检查一下是否是你想要的那个在工作哦!")])],-1),F=p("p",null,[p("strong",null,"v2rayN - 适用于 Windows 平台")],-1),H=l("请从它的"),Q={href:"https://github.com/2dust/v2rayN/releases",target:"_blank",rel:"noopener noreferrer"},W=l("GitHub 仓库 Release 页面"),Y=l("获取最新版"),z=p("li",null,"请根据该客户端的说明进行设置",-1),B=p("p",null,[p("strong",null,"v2rayNG - 适用于 Android 平台")],-1),M=l("请从它的"),U={href:"https://github.com/2dust/v2rayNG/releases",target:"_blank",rel:"noopener noreferrer"},J=l("GitHub 仓库 Release 页面"),K=l("获取最新版"),Z=p("li",null,"请根据该客户端的说明进行设置",-1),$=p("li",null,[p("p",null,[p("strong",null,"Shadowrocket - 适用于 iOS, 基于苹果 M 芯片的 macOS")]),p("ul",null,[p("li",null,"你需要注册一个【非中国区】的 iCloud 账户"),p("li",null,"你需要通过 App Store 搜索并购买"),p("li",null,"请根据该客户端的说明进行设置")])],-1),nn=p("p",null,[p("strong",null,"Qv2ray - 跨平台图形界面,适用于 Linux, Windows, macOS")],-1),sn=l("请从它的"),an={href:"https://github.com/Qv2ray/Qv2ray/releases",target:"_blank",rel:"noopener noreferrer"},pn=l("GitHub 仓库 Release 页面"),on=l("获取最新版(还可以从它的"),tn={href:"https://github.com/Qv2ray/Qv2ray/actions",target:"_blank",rel:"noopener noreferrer"},en=l("GitHub 自动构建仓库"),ln=l("寻找更新的版本)"),un=l("请从它的"),rn={href:"https://qv2ray.net/",target:"_blank",rel:"noopener noreferrer"},cn=l("项目主页"),bn=l("学习文档"),kn=p("li",null,"请根据该客户端的说明进行设置",-1),mn=p("p",null,[p("strong",null,"V2RayXS - 基于 V2RayX 开发的一款使用 xray-core 的 macOS 客户端")],-1),dn=l("请从它的 "),qn={href:"https://github.com/tzmax/v2rayXS/releases",target:"_blank",rel:"noopener noreferrer"},yn=l("GitHub 仓库 Release 页面"),gn=l(" 获取最新版"),hn=l("支持一键导入 "),xn={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},fn=l("VMessAEAD / VLESS 分享链接标准提案"),Sn=l(" 为标准的分享链接"),Xn=p("li",null,"请根据该客户端的说明进行设置",-1),vn=p("p",null,"到这一步,你的全套配置就已经可以正常使用啦!",-1),_n=p("h2",{id:"_8-3-附加题-1-在-pc-端手工配置-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-3-附加题-1-在-pc-端手工配置-xray-core","aria-hidden":"true"},"#"),l(" 8.3 附加题 1:在 PC 端手工配置 "),p("code",null,"xray-core")],-1),Pn=p("p",null,[l("虽然到上面一步已经可以结束了,但是如果你是个好奇心强、记忆力好的的同学,一定会想起来我在上一章说过,你把"),p("code",null,"xray-core"),l(" 的二进制文件“放在服务器运行,它就是服务器端;你把它下载到本地电脑运行,它就是客户端。” 那究竟要怎样直接使用 "),p("code",null,"xray-core"),l(" 做客户端呢?")],-1),wn=p("p",null,"为了回答这个问题,我加入了附加题章节,有一点点超纲,有一点点麻烦,但费这个笔墨是因为这个方式有它的优势:",-1),Nn=p("ul",null,[p("li",null,[p("p",null,"第一时间获得最新版而无需等待 APP 升级适配")]),p("li",null,[p("p",null,"灵活自由的路由配置能力(当然 GUI 客户端中 Qv2ray 的高级路由编辑器非常强大,也可以完整实现 xray-core 的路由配置功能)")]),p("li",null,[p("p",null,"节约系统资源 (GUI 界面一定会有资源消耗,消耗的多少则取决于客户端的实现)")])],-1),In=p("p",null,"它的劣势应该就是【需要手写配置文件】有点麻烦了。但其实,你想想,服务器上你已经成功的写过一次了,现在又有什么区别呢?接下来,还是老样子,我们分解一下步骤:",-1),Tn=l("首先请从 Xray 官方的 "),Ln={href:"https://github.com/XTLS/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},Cn=l("GitHub 仓库 Release 页面"),Dn=l(" 获取对应平台的版本,并解压缩到合适的文件夹"),Vn=u('
  • 在合适的文件夹建立空白配置文件:config.json (自己常用平台下新建文件大家肯定都会,这就真不用啰嗦了)

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

  • 填写客户端配置

    • 我就以 8.1 原理说明里展示的基本三类分流(国内流量直连、国际流量转发 VPS、广告流量屏蔽),结合 8.2 的连接要素,写成一个配置文件
    • 请将 uuid 替换成与你服务器一致的 uuid
    • 请将 address 替换成你的真实域名
    • 请将 serverName 替换成你的真实域名
    • 各个配置模块的说明我都已经(很啰嗦的)放在对应的配置点上了
    // REFERENCE:\n// https://github.com/XTLS/Xray-examples\n// https://xtls.github.io/config/\n\n// 常用的config文件,不论服务器端还是客户端,都有5个部分。外加小小白解读:\n// ┌─ 1_log          日志设置 - 日志写什么,写哪里(出错时有据可查)\n// ├─ 2_dns          DNS-设置 - DNS怎么查(防DNS污染、防偷窥、避免国内外站匹配到国外服务器等)\n// ├─ 3_routing      分流设置 - 流量怎么分类处理(是否过滤广告、是否国内外分流)\n// ├─ 4_inbounds     入站设置 - 什么流量可以流入Xray\n// └─ 5_outbounds    出站设置 - 流出Xray的流量往哪里去\n\n{\n  // 1_日志设置\n  // 注意,本例中我默认注释掉了日志文件,因为windows, macOS, Linux 需要写不同的路径,请自行配置\n  "log": {\n    // "access": "/home/local/xray_log/access.log",    // 访问记录\n    // "error": "/home/local/xray_log/error.log",    // 错误记录\n    "loglevel": "warning" // 内容从少到多: "none", "error", "warning", "info", "debug"\n  },\n\n  // 2_DNS设置\n  "dns": {\n    "servers": [\n      // 2.1 国外域名使用国外DNS查询\n      {\n        "address": "1.1.1.1",\n        "domains": ["geosite:geolocation-!cn"]\n      },\n      // 2.2 国内域名使用国内DNS查询,并期待返回国内的IP,若不是国内IP则舍弃,用下一个查询\n      {\n        "address": "223.5.5.5",\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      // 2.3 作为2.2的备份,对国内网站进行二次查询\n      {\n        "address": "114.114.114.114",\n        "domains": ["geosite:cn"]\n      },\n      // 2.4 最后的备份,上面全部失败时,用本机DNS查询\n      "localhost"\n    ]\n  },\n\n  // 3_分流设置\n  // 所谓分流,就是将符合否个条件的流量,用指定`tag`的出站协议去处理(对应配置的5.x内容)\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      // 3.1 广告域名屏蔽\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      // 3.2 国内域名直连\n      {\n        "type": "field",\n        "domain": ["geosite:cn"],\n        "outboundTag": "direct"\n      },\n      // 3.3 国内IP直连\n      {\n        "type": "field",\n        "ip": ["geoip:cn", "geoip:private"],\n        "outboundTag": "direct"\n      },\n      // 3.4 国外域名代理\n      {\n        "type": "field",\n        "domain": ["geosite:geolocation-!cn"],\n        "outboundTag": "proxy"\n      },\n      // 3.5 默认规则\n      // 在Xray中,任何不符合上述路由规则的流量,都会默认使用【第一个outbound(5.1)】的设置,所以一定要把转发VPS的outbound放第一个\n      // 3.6 走国内"223.5.5.5"的DNS查询流量分流走direct出站\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct"\n      }\n    ]\n  },\n\n  // 4_入站设置\n  "inbounds": [\n    // 4.1 一般都默认使用socks5协议作本地转发\n    {\n      "tag": "socks-in",\n      "protocol": "socks",\n      "listen": "127.0.0.1", // 这个是通过socks5协议做本地转发的地址\n      "port": 10800, // 这个是通过socks5协议做本地转发的端口\n      "settings": {\n        "udp": true\n      }\n    },\n    // 4.2 有少数APP不兼容socks协议,需要用http协议做转发,则可以用下面的端口\n    {\n      "tag": "http-in",\n      "protocol": "http",\n      "listen": "127.0.0.1", // 这个是通过http协议做本地转发的地址\n      "port": 10801 // 这个是通过http协议做本地转发的端口\n    }\n  ],\n\n  // 5_出站设置\n  "outbounds": [\n    // 5.1 默认转发VPS\n    // 一定放在第一个,在routing 3.5 里面已经说明了,这等于是默认规则,所有不符合任何规则的流量都走这个\n    {\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "a-name.yourdomain.com", // 替换成你的真实域名\n            "port": 443,\n            "users": [\n              {\n                "id": "uuiduuid-uuid-uuid-uuid-uuiduuiduuid", // 和服务器端的一致\n                "flow": "xtls-rprx-vision",\n                "encryption": "none",\n                "level": 0\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "tls",\n        "tlsSettings": {\n          "serverName": "a-name.yourdomain.com", // 替换成你的真实域名\n          "allowInsecure": false, // 禁止不安全证书\n          "fingerprint": "chrome" // 通过 uTLS 库 模拟 Chrome / Firefox / Safari 或随机生成的指纹\n        }\n      }\n    },\n    // 5.2 用`freedom`协议直连出站,即当routing中指定'direct'流出时,调用这个协议做处理\n    {\n      "tag": "direct",\n      "protocol": "freedom"\n    },\n    // 5.3 用`blackhole`协议屏蔽流量,即当routing中指定'block'时,调用这个协议做处理\n    {\n      "tag": "block",\n      "protocol": "blackhole"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
  • ',3),jn=p("h2",{id:"_8-4-附加题-2-在-pc-端手工运行-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-4-附加题-2-在-pc-端手工运行-xray-core","aria-hidden":"true"},"#"),l(" 8.4 附加题 2:在 PC 端手工运行 "),p("code",null,"xray-core")],-1),Gn=p("p",null,[l("写好了配置文件该,要怎么让 "),p("code",null,"xray-core"),l(" 运行起来呢?双击好像并没有反应啊?")],-1),On=p("p",null,"首先,你要找到电脑上的【命令行界面】。",-1),An=p("ol",null,[p("li",null,[l("Linux 桌面、macOS 系统的同学肯定已经比较熟悉了,搜索 "),p("code",null,"Console"),l(" 或者 "),p("code",null,"Terminal"),l(" 就可以")]),p("li",null,[l("Windows 就可以搜索使用 "),p("code",null,"Cmd"),l(" 或者 "),p("code",null,"Powershell"),l(" 等程序(WSL 的同学你坐下,你的 "),p("code",null,"Console"),l(" 当然也可以)")])],-1),Rn=p("p",null,[l("其次,我们要做的事情是【让 "),p("code",null,"xray"),l(" 找到并读取配置文件 "),p("code",null,"config.json"),l(",然后运行】,所以:")],-1),En=p("ol",null,[p("li",null,[p("p",null,[l("在 Windows 下,假设你的 "),p("code",null,"Xray"),l(" 程序位置是 "),p("code",null,"C:\\Xray-windows-64\\xray.exe"),l(",配置文件位置是"),p("code",null,"C:\\Xray-windows-64\\config.json"),l(",那么正确的启动命令就是:")]),p("div",{class:"language-bash ext-sh line-numbers-mode"},[p("pre",{class:"language-bash"},[p("code",null,[l("C:"),p("span",{class:"token punctuation"},"\\"),l("Xray-windows-64"),p("span",{class:"token punctuation"},"\\"),l("xray.exe -c C:"),p("span",{class:"token punctuation"},"\\"),l("Xray-windows-64"),p("span",{class:"token punctuation"},"\\"),l("config.json\n")])]),p("div",{class:"line-numbers"},[p("span",{class:"line-number"},"1"),p("br")])]),p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"说明"),p("p",null,[l("这里的 "),p("code",null,"-c"),l(" 就是指定配置文件路径的参数,告诉 "),p("code",null,"xray"),l(" 去后面的位置找配置文件")])])]),p("li",null,[p("p",null,[l("相似的,在 Linux 和 macOS 下,假设你的 "),p("code",null,"Xray"),l(" 程序位置是 "),p("code",null,"/usr/local/bin/xray"),l(",配置文件位置是"),p("code",null,"/usr/local/etc/xray/config.json"),l(",那么正确的启动命令就是")]),p("div",{class:"language-bash ext-sh line-numbers-mode"},[p("pre",{class:"language-bash"},[p("code",null,"/usr/local/bin/xray -c /usr/local/etc/xray/config.json\n")]),p("div",{class:"line-numbers"},[p("span",{class:"line-number"},"1"),p("br")])]),p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"说明"),p("p",null,[l("每个系统都有系统路径变量,所以写 "),p("code",null,"Xray"),l(" 程序时不一定要写绝对路径。但是写了肯定没错,所以我就如此演示了。")])])])],-1),Fn=p("h2",{id:"_8-5-附加题-3-在-pc-端开机自动运行-xray-core",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-5-附加题-3-在-pc-端开机自动运行-xray-core","aria-hidden":"true"},"#"),l(" 8.5 附加题 3:在 PC 端开机自动运行 "),p("code",null,"xray-core")],-1),Hn=p("p",null,[l("如果你真的尝试了手动运行 "),p("code",null,"xray-core"),l(",你一定会发现这个方式还有点小问题:")],-1),Qn=p("ol",null,[p("li",null,[l("每次运行 "),p("code",null,"Xray"),l(" 都要出现一个黑乎乎的窗口,很丑")]),p("li",null,"不能开机自动运行,每次都要手工输入,十分不方便")],-1),Wn=p("p",null,[l("我可以肯定的告诉你:"),p("strong",null,"完全可以解决"),l("。但是具体的解决方式,就当作课外作业留给大家吧!(友情提示,文档站的问答区有线索哦)")],-1),Yn=p("h2",{id:"_8-6-圆满完成",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-6-圆满完成","aria-hidden":"true"},"#"),l(" 8.6 圆满完成!")],-1),zn=p("p",null,[l("我相信,有耐心看到这里的同学,都是兼具好奇心和行动力的学习派!我现在要郑重的恭喜你,因为到了这里,你已经完完整整的【"),p("strong",null,"从第一条命令开始,完成了 VPS 服务器部署,并成功的在客户端配置使用 Xray"),l("】了!这毫无疑问是一个巨大的胜利!")],-1),Bn=p("p",null,[l("我相信,你现在一定对"),p("code",null,"Linux"),l("不再恐惧,对"),p("code",null,"Xray"),l("不再陌生了吧!")],-1),Mn=p("p",null,[p("strong",null,"至此,小小白白话文圆满结束!")],-1),Un=p("blockquote",null,[p("p",null,"⬛⬛⬛⬛⬛⬛⬛⬛ 100%")],-1),Jn=p("h2",{id:"_8-7-to-infinity-and-beyond",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_8-7-to-infinity-and-beyond","aria-hidden":"true"},"#"),l(" 8.7 TO INFINITY AND BEYOND!")],-1),Kn=p("p",null,[p("strong",null,"但现在你看到的,远远不是 Xray 的全貌。")],-1),Zn=p("p",null,[p("code",null,"Xray"),l("是一个强大而丰富的网络工具集合,平台化的提供了众多模块,可以像瑞士军刀一样,通过灵活的配置组合解决各种不同的问题。而本文,仅仅蜻蜓点水的用了"),p("strong",null,"最简单"),l("、"),p("strong",null,"最直观"),l("的配置来做"),p("strong",null,"基础演示"),l("。")],-1),$n=p("p",null,"如果你觉得现在已经完全够用了,那就好好的享受它给你带来的信息自由。但如果你的好奇心依然不能停歇,那就去继续挖掘它无限的可能性吧!",-1),ns=p("p",null,"需要更多信息,可以到这里寻找:",-1),ss={href:"https://xtls.github.io/",target:"_blank",rel:"noopener noreferrer"},as=l("xtls.github.io"),ps=l(" - 官方文档站"),os={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},ts=l("官方 Telegram 群组"),es=l(" - 活跃而友善的官方讨论社区"),ls=p("p",null,[p("img",{src:"/Xray-docs-next/assets/ch08-img02-buzz.2c8cb2a0.png",alt:"TO INFINITY AND BEYOND!"})],-1),us=p("div",{class:"custom-container tip"},[p("p",{class:"custom-container-title"},"不算后记的后记"),p("p",null,"希望我陪你走过的这一段小小的旅程,可以成为你网络生活中的一份小小助力。"),p("p",null,"这篇文章里的工具和信息难免会一点点的陈旧过时,但你一定会逐渐成长为大佬。未来的某个时间,若你能偶尔想起这篇教程、想起我写下本文的初衷,那我衷心希望你能够薪火相传、把最新的知识分享给后来人,让这一份小小的助力在社区里坚定的传递下去。"),p("p",null,"这是个大雪封山乌云密布的世界,人们孤独的走在各自的路上试图寻找阳光,如果大家偶尔交汇时不能守望相助互相鼓励,那最终剩下的,恐怕只有【千山鸟飞绝 万径人踪灭】的凄凉了吧。")],-1);r.render=function(l,u){const r=n("RouterLink"),rs=n("OutboundLink");return s(),a(e,null,[c,i,b,k,m,d,p("div",q,[y,g,h,p("p",null,[x,o(r,{to:"/en/document/level-1/routing-lv1-part1.html"},{default:t((()=>[f])),_:1}),S])]),X,v,p("p",null,[_,P,w,o(r,{to:"/en/config/inbounds/"},{default:t((()=>[N])),_:1}),I,T,L,C,D,V,j,G,O]),A,R,E,p("ul",null,[p("li",null,[F,p("ul",null,[p("li",null,[H,p("a",Q,[W,o(rs)]),Y]),z])]),p("li",null,[B,p("ul",null,[p("li",null,[M,p("a",U,[J,o(rs)]),K]),Z])]),$,p("li",null,[nn,p("ul",null,[p("li",null,[sn,p("a",an,[pn,o(rs)]),on,p("a",tn,[en,o(rs)]),ln]),p("li",null,[un,p("a",rn,[cn,o(rs)]),bn]),kn])]),p("li",null,[mn,p("ul",null,[p("li",null,[dn,p("a",qn,[yn,o(rs)]),gn]),p("li",null,[hn,p("a",xn,[fn,o(rs)]),Sn]),Xn])])]),vn,_n,Pn,wn,Nn,In,p("ol",null,[p("li",null,[p("p",null,[Tn,p("a",Ln,[Cn,o(rs)]),Dn])]),Vn]),jn,Gn,On,An,Rn,En,Fn,Hn,Qn,Wn,Yn,zn,Bn,Mn,Un,Jn,Kn,Zn,$n,ns,p("ol",null,[p("li",null,[p("a",ss,[as,o(rs)]),ps]),p("li",null,[p("a",os,[ts,o(rs)]),es])]),ls,us],64)};export default r; diff --git a/assets/ch09-appendix.html.ba31318a.js b/assets/ch09-appendix.html.6e67299d.js similarity index 99% rename from assets/ch09-appendix.html.ba31318a.js rename to assets/ch09-appendix.html.6e67299d.js index 3a59cb5fc..e0ea3f253 100644 --- a/assets/ch09-appendix.html.ba31318a.js +++ b/assets/ch09-appendix.html.6e67299d.js @@ -1 +1 @@ -import{r as t,o as e,c as l,a as n,b as d,w as a,F as c,e as r}from"./app.755d843f.js";const s={},u=n("h1",{id:"【第-9-章】附录",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#【第-9-章】附录","aria-hidden":"true"},"#"),r(" 【第 9 章】附录")],-1),y=n("h2",{id:"_1-小小白白-linux-基础命令索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_1-小小白白-linux-基础命令索引","aria-hidden":"true"},"#"),r(" 1. 小小白白 Linux 基础命令索引")],-1),i=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"命令名称"),n("th",{style:{"text-align":"left"}},"命令说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),x=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-01")],-1),o=n("td",{style:{"text-align":"left"}},[n("code",null,"apt update")],-1),g=n("td",{style:{"text-align":"left"}},"查询软件更新",-1),f={style:{"text-align":"center"}},h=r("《远程登录篇》"),m=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-02")],-1),v=n("td",{style:{"text-align":"left"}},[n("code",null,"apt upgrade")],-1),_=n("td",{style:{"text-align":"left"}},"执行软件更新",-1),p={style:{"text-align":"center"}},X=r("《远程登录篇》"),b=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-03")],-1),L=n("td",{style:{"text-align":"left"}},[n("code",null,"nano")],-1),k=n("td",{style:{"text-align":"left"}},"文本编辑器",-1),w={style:{"text-align":"center"}},S=r("《安全防护篇》"),j=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-04")],-1),T=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl restart")],-1),F=n("td",{style:{"text-align":"left"}},"重启某个服务",-1),H={style:{"text-align":"center"}},N=r("《安全防护篇》"),R=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-05")],-1),q=n("td",{style:{"text-align":"left"}},[n("code",null,"adduser")],-1),z=n("td",{style:{"text-align":"left"}},"给系统新增用户",-1),A={style:{"text-align":"center"}},B=r("《安全防护篇》"),C=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-06")],-1),D=n("td",{style:{"text-align":"left"}},[n("code",null,"apt install")],-1),E=n("td",{style:{"text-align":"left"}},"安装某个软件",-1),G={style:{"text-align":"center"}},I=r("《安全防护篇》"),J=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-07")],-1),K=n("td",{style:{"text-align":"left"}},[n("code",null,"visudo")],-1),M=n("td",{style:{"text-align":"left"}},"修改 sudo 权限设置专用编辑器",-1),O={style:{"text-align":"center"}},P=r("《安全防护篇》"),Q=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-08")],-1),U=n("td",{style:{"text-align":"left"}},[n("code",null,"sudo")],-1),V=n("td",{style:{"text-align":"left"}},[r("用"),n("code",null,"root"),r("权限运行某个命令")],-1),W={style:{"text-align":"center"}},Y=r("《安全防护篇》"),Z=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-09")],-1),$=n("td",{style:{"text-align":"left"}},[n("code",null,"chmod")],-1),tt=n("td",{style:{"text-align":"left"}},"修改目标文件/文件夹的权限",-1),et={style:{"text-align":"center"}},lt=r("《安全防护篇》"),nt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-10")],-1),dt=n("td",{style:{"text-align":"left"}},[n("code",null,"mkdir")],-1),at=n("td",{style:{"text-align":"left"}},"新建文件夹",-1),ct={style:{"text-align":"center"}},rt=r("《网站建设篇》"),st=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-11")],-1),ut=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl reload")],-1),yt=n("td",{style:{"text-align":"left"}},"重新加载某个服务",-1),it={style:{"text-align":"center"}},xt=r("《网站建设篇》"),ot=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-12")],-1),gt=n("td",{style:{"text-align":"left"}},[n("code",null,"wget")],-1),ft=n("td",{style:{"text-align":"left"}},"访问(或下载)某个网页文件",-1),ht={style:{"text-align":"center"}},mt=r("《证书管理篇》"),vt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-13")],-1),_t=n("td",{style:{"text-align":"left"}},[n("code",null,"acme.sh")],-1),pt=n("td",{style:{"text-align":"left"}},"acme.sh 证书管理相关的命令",-1),Xt={style:{"text-align":"center"}},bt=r("《证书管理篇》"),Lt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-14")],-1),kt=n("td",{style:{"text-align":"left"}},[n("code",null,"rm")],-1),wt=n("td",{style:{"text-align":"left"}},"删除命令",-1),St={style:{"text-align":"center"}},jt=r("《Xray 服务器篇》"),Tt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-15")],-1),Ft=n("td",{style:{"text-align":"left"}},[n("code",null,"crontab -e")],-1),Ht=n("td",{style:{"text-align":"left"}},"编辑当前用户的定时任务",-1),Nt={style:{"text-align":"center"}},Rt=r("《Xray 服务器篇》"),qt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-16")],-1),zt=n("td",{style:{"text-align":"left"}},[n("code",null,"touch")],-1),At=n("td",{style:{"text-align":"left"}},"建立空白文件",-1),Bt={style:{"text-align":"center"}},Ct=r("《Xray 服务器篇》"),Dt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-17")],-1),Et=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl")],-1),Gt=n("td",{style:{"text-align":"left"}},[n("code",null,"systemd"),r("基本服务管理命令")],-1),It={style:{"text-align":"center"}},Jt=r("《Xray 服务器篇》"),Kt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-18")],-1),Mt=n("td",{style:{"text-align":"left"}},[n("code",null,"reboot")],-1),Ot=n("td",{style:{"text-align":"left"}},"重启 Linux 系统",-1),Pt={style:{"text-align":"center"}},Qt=r("《Xray 服务器篇》"),Ut=n("h2",{id:"_2-小小白白-linux-重要配置文件索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_2-小小白白-linux-重要配置文件索引","aria-hidden":"true"},"#"),r(" 2. 小小白白 Linux 重要配置文件索引")],-1),Vt=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"配置文件位置"),n("th",{style:{"text-align":"left"}},"文件说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),Wt=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-01")],-1),Yt=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/ssh/sshd_config")],-1),Zt=n("td",{style:{"text-align":"left"}},"SSH 远程登录程序设置",-1),$t={style:{"text-align":"center"}},te=r("《远程登录篇》"),ee=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-02")],-1),le=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/nginx/nginx.conf")],-1),ne=n("td",{style:{"text-align":"left"}},"Nginx 程序设置",-1),de={style:{"text-align":"center"}},ae=r("《网站建设篇》"),ce=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-03")],-1),re=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/apt/sources.list")],-1),se=n("td",{style:{"text-align":"left"}},"apt 软件源列表",-1),ue={style:{"text-align":"center"}},ye=r("《Xray 服务器篇》"),ie=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-04")],-1),xe=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/apt/sources.list.d/vpsadmin.list")],-1),oe=n("td",{style:{"text-align":"left"}},"用户自定义软件源列表列表",-1),ge={style:{"text-align":"center"}},fe=r("《Xray 服务器篇》"),he=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-05")],-1),me=n("td",{style:{"text-align":"left"}},[n("code",null,"crontab -e")],-1),ve=n("td",{style:{"text-align":"left"}},"当前用户的定时任务",-1),_e={style:{"text-align":"center"}},pe=r("《Xray 服务器篇》"),Xe=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-06")],-1),be=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/sysctl.conf")],-1),Le=n("td",{style:{"text-align":"left"}},"手动设置 kernel 参数",-1),ke={style:{"text-align":"center"}},we=r("《Xray 服务器篇》"),Se=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-07")],-1),je=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/sysctl.d/vpsadmin.conf")],-1),Te=n("td",{style:{"text-align":"left"}},"用户自定义 kernel 参数配置文件",-1),Fe={style:{"text-align":"center"}},He=r("《Xray 服务器篇》"),Ne=n("h2",{id:"_3-小小白白-xray-重要文件索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_3-小小白白-xray-重要文件索引","aria-hidden":"true"},"#"),r(" 3. 小小白白 Xray 重要文件索引")],-1),Re=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"配置文件位置"),n("th",{style:{"text-align":"left"}},"文件说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),qe=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-01")],-1),ze=n("td",{style:{"text-align":"left"}},[n("code",null,"/usr/local/etc/xray/config.json")],-1),Ae=n("td",{style:{"text-align":"left"}},"Xray 程序设置",-1),Be={style:{"text-align":"center"}},Ce=r("《Xray 服务器篇》"),De=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-02")],-1),Ee=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_cert/xray.cert")],-1),Ge=n("td",{style:{"text-align":"left"}},"TLS 证书",-1),Ie={style:{"text-align":"center"}},Je=r("《Xray 服务器篇》"),Ke=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-03")],-1),Me=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_cert/xray.key")],-1),Oe=n("td",{style:{"text-align":"left"}},"TLS 私钥",-1),Pe={style:{"text-align":"center"}},Qe=r("《Xray 服务器篇》"),Ue=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-04")],-1),Ve=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_log/access.log")],-1),We=n("td",{style:{"text-align":"left"}},"Xray 访问日志",-1),Ye={style:{"text-align":"center"}},Ze=r("《Xray 服务器篇》"),$e=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-05")],-1),tl=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_log/error.log")],-1),el=n("td",{style:{"text-align":"left"}},"Xray 错误日志",-1),ll={style:{"text-align":"center"}},nl=r("《Xray 服务器篇》");s.render=function(r,s){const dl=t("RouterLink");return e(),l(c,null,[u,y,n("table",null,[i,n("tbody",null,[n("tr",null,[x,o,g,n("td",f,[d(dl,{to:"/en/document/level-0/ch03-ssh.html"},{default:a((()=>[h])),_:1})])]),n("tr",null,[m,v,_,n("td",p,[d(dl,{to:"/en/document/level-0/ch03-ssh.html"},{default:a((()=>[X])),_:1})])]),n("tr",null,[b,L,k,n("td",w,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[S])),_:1})])]),n("tr",null,[j,T,F,n("td",H,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[N])),_:1})])]),n("tr",null,[R,q,z,n("td",A,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[B])),_:1})])]),n("tr",null,[C,D,E,n("td",G,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[I])),_:1})])]),n("tr",null,[J,K,M,n("td",O,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[P])),_:1})])]),n("tr",null,[Q,U,V,n("td",W,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[Y])),_:1})])]),n("tr",null,[Z,$,tt,n("td",et,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[lt])),_:1})])]),n("tr",null,[nt,dt,at,n("td",ct,[d(dl,{to:"/en/document/level-0/ch05-webpage.html"},{default:a((()=>[rt])),_:1})])]),n("tr",null,[st,ut,yt,n("td",it,[d(dl,{to:"/en/document/level-0/ch05-webpage.html"},{default:a((()=>[xt])),_:1})])]),n("tr",null,[ot,gt,ft,n("td",ht,[d(dl,{to:"/en/document/level-0/ch06-certificates.html"},{default:a((()=>[mt])),_:1})])]),n("tr",null,[vt,_t,pt,n("td",Xt,[d(dl,{to:"/en/document/level-0/ch06-certificates.html"},{default:a((()=>[bt])),_:1})])]),n("tr",null,[Lt,kt,wt,n("td",St,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[jt])),_:1})])]),n("tr",null,[Tt,Ft,Ht,n("td",Nt,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Rt])),_:1})])]),n("tr",null,[qt,zt,At,n("td",Bt,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ct])),_:1})])]),n("tr",null,[Dt,Et,Gt,n("td",It,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Jt])),_:1})])]),n("tr",null,[Kt,Mt,Ot,n("td",Pt,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Qt])),_:1})])])])]),Ut,n("table",null,[Vt,n("tbody",null,[n("tr",null,[Wt,Yt,Zt,n("td",$t,[d(dl,{to:"/en/document/level-0/ch03-ssh.html"},{default:a((()=>[te])),_:1})])]),n("tr",null,[ee,le,ne,n("td",de,[d(dl,{to:"/en/document/level-0/ch05-webpage.html"},{default:a((()=>[ae])),_:1})])]),n("tr",null,[ce,re,se,n("td",ue,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[ye])),_:1})])]),n("tr",null,[ie,xe,oe,n("td",ge,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[fe])),_:1})])]),n("tr",null,[he,me,ve,n("td",_e,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[pe])),_:1})])]),n("tr",null,[Xe,be,Le,n("td",ke,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[we])),_:1})])]),n("tr",null,[Se,je,Te,n("td",Fe,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[He])),_:1})])])])]),Ne,n("table",null,[Re,n("tbody",null,[n("tr",null,[qe,ze,Ae,n("td",Be,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ce])),_:1})])]),n("tr",null,[De,Ee,Ge,n("td",Ie,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Je])),_:1})])]),n("tr",null,[Ke,Me,Oe,n("td",Pe,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Qe])),_:1})])]),n("tr",null,[Ue,Ve,We,n("td",Ye,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ze])),_:1})])]),n("tr",null,[$e,tl,el,n("td",ll,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[nl])),_:1})])])])])],64)};export default s; +import{r as t,o as e,c as l,a as n,b as d,w as a,F as c,e as r}from"./app.48111a85.js";const s={},u=n("h1",{id:"【第-9-章】附录",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#【第-9-章】附录","aria-hidden":"true"},"#"),r(" 【第 9 章】附录")],-1),y=n("h2",{id:"_1-小小白白-linux-基础命令索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_1-小小白白-linux-基础命令索引","aria-hidden":"true"},"#"),r(" 1. 小小白白 Linux 基础命令索引")],-1),i=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"命令名称"),n("th",{style:{"text-align":"left"}},"命令说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),x=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-01")],-1),o=n("td",{style:{"text-align":"left"}},[n("code",null,"apt update")],-1),g=n("td",{style:{"text-align":"left"}},"查询软件更新",-1),f={style:{"text-align":"center"}},h=r("《远程登录篇》"),m=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-02")],-1),v=n("td",{style:{"text-align":"left"}},[n("code",null,"apt upgrade")],-1),_=n("td",{style:{"text-align":"left"}},"执行软件更新",-1),p={style:{"text-align":"center"}},X=r("《远程登录篇》"),b=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-03")],-1),L=n("td",{style:{"text-align":"left"}},[n("code",null,"nano")],-1),k=n("td",{style:{"text-align":"left"}},"文本编辑器",-1),w={style:{"text-align":"center"}},S=r("《安全防护篇》"),j=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-04")],-1),T=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl restart")],-1),F=n("td",{style:{"text-align":"left"}},"重启某个服务",-1),H={style:{"text-align":"center"}},N=r("《安全防护篇》"),R=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-05")],-1),q=n("td",{style:{"text-align":"left"}},[n("code",null,"adduser")],-1),z=n("td",{style:{"text-align":"left"}},"给系统新增用户",-1),A={style:{"text-align":"center"}},B=r("《安全防护篇》"),C=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-06")],-1),D=n("td",{style:{"text-align":"left"}},[n("code",null,"apt install")],-1),E=n("td",{style:{"text-align":"left"}},"安装某个软件",-1),G={style:{"text-align":"center"}},I=r("《安全防护篇》"),J=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-07")],-1),K=n("td",{style:{"text-align":"left"}},[n("code",null,"visudo")],-1),M=n("td",{style:{"text-align":"left"}},"修改 sudo 权限设置专用编辑器",-1),O={style:{"text-align":"center"}},P=r("《安全防护篇》"),Q=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-08")],-1),U=n("td",{style:{"text-align":"left"}},[n("code",null,"sudo")],-1),V=n("td",{style:{"text-align":"left"}},[r("用"),n("code",null,"root"),r("权限运行某个命令")],-1),W={style:{"text-align":"center"}},Y=r("《安全防护篇》"),Z=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-09")],-1),$=n("td",{style:{"text-align":"left"}},[n("code",null,"chmod")],-1),tt=n("td",{style:{"text-align":"left"}},"修改目标文件/文件夹的权限",-1),et={style:{"text-align":"center"}},lt=r("《安全防护篇》"),nt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-10")],-1),dt=n("td",{style:{"text-align":"left"}},[n("code",null,"mkdir")],-1),at=n("td",{style:{"text-align":"left"}},"新建文件夹",-1),ct={style:{"text-align":"center"}},rt=r("《网站建设篇》"),st=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-11")],-1),ut=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl reload")],-1),yt=n("td",{style:{"text-align":"left"}},"重新加载某个服务",-1),it={style:{"text-align":"center"}},xt=r("《网站建设篇》"),ot=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-12")],-1),gt=n("td",{style:{"text-align":"left"}},[n("code",null,"wget")],-1),ft=n("td",{style:{"text-align":"left"}},"访问(或下载)某个网页文件",-1),ht={style:{"text-align":"center"}},mt=r("《证书管理篇》"),vt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-13")],-1),_t=n("td",{style:{"text-align":"left"}},[n("code",null,"acme.sh")],-1),pt=n("td",{style:{"text-align":"left"}},"acme.sh 证书管理相关的命令",-1),Xt={style:{"text-align":"center"}},bt=r("《证书管理篇》"),Lt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-14")],-1),kt=n("td",{style:{"text-align":"left"}},[n("code",null,"rm")],-1),wt=n("td",{style:{"text-align":"left"}},"删除命令",-1),St={style:{"text-align":"center"}},jt=r("《Xray 服务器篇》"),Tt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-15")],-1),Ft=n("td",{style:{"text-align":"left"}},[n("code",null,"crontab -e")],-1),Ht=n("td",{style:{"text-align":"left"}},"编辑当前用户的定时任务",-1),Nt={style:{"text-align":"center"}},Rt=r("《Xray 服务器篇》"),qt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-16")],-1),zt=n("td",{style:{"text-align":"left"}},[n("code",null,"touch")],-1),At=n("td",{style:{"text-align":"left"}},"建立空白文件",-1),Bt={style:{"text-align":"center"}},Ct=r("《Xray 服务器篇》"),Dt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-17")],-1),Et=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl")],-1),Gt=n("td",{style:{"text-align":"left"}},[n("code",null,"systemd"),r("基本服务管理命令")],-1),It={style:{"text-align":"center"}},Jt=r("《Xray 服务器篇》"),Kt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-18")],-1),Mt=n("td",{style:{"text-align":"left"}},[n("code",null,"reboot")],-1),Ot=n("td",{style:{"text-align":"left"}},"重启 Linux 系统",-1),Pt={style:{"text-align":"center"}},Qt=r("《Xray 服务器篇》"),Ut=n("h2",{id:"_2-小小白白-linux-重要配置文件索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_2-小小白白-linux-重要配置文件索引","aria-hidden":"true"},"#"),r(" 2. 小小白白 Linux 重要配置文件索引")],-1),Vt=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"配置文件位置"),n("th",{style:{"text-align":"left"}},"文件说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),Wt=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-01")],-1),Yt=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/ssh/sshd_config")],-1),Zt=n("td",{style:{"text-align":"left"}},"SSH 远程登录程序设置",-1),$t={style:{"text-align":"center"}},te=r("《远程登录篇》"),ee=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-02")],-1),le=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/nginx/nginx.conf")],-1),ne=n("td",{style:{"text-align":"left"}},"Nginx 程序设置",-1),de={style:{"text-align":"center"}},ae=r("《网站建设篇》"),ce=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-03")],-1),re=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/apt/sources.list")],-1),se=n("td",{style:{"text-align":"left"}},"apt 软件源列表",-1),ue={style:{"text-align":"center"}},ye=r("《Xray 服务器篇》"),ie=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-04")],-1),xe=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/apt/sources.list.d/vpsadmin.list")],-1),oe=n("td",{style:{"text-align":"left"}},"用户自定义软件源列表列表",-1),ge={style:{"text-align":"center"}},fe=r("《Xray 服务器篇》"),he=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-05")],-1),me=n("td",{style:{"text-align":"left"}},[n("code",null,"crontab -e")],-1),ve=n("td",{style:{"text-align":"left"}},"当前用户的定时任务",-1),_e={style:{"text-align":"center"}},pe=r("《Xray 服务器篇》"),Xe=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-06")],-1),be=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/sysctl.conf")],-1),Le=n("td",{style:{"text-align":"left"}},"手动设置 kernel 参数",-1),ke={style:{"text-align":"center"}},we=r("《Xray 服务器篇》"),Se=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-07")],-1),je=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/sysctl.d/vpsadmin.conf")],-1),Te=n("td",{style:{"text-align":"left"}},"用户自定义 kernel 参数配置文件",-1),Fe={style:{"text-align":"center"}},He=r("《Xray 服务器篇》"),Ne=n("h2",{id:"_3-小小白白-xray-重要文件索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_3-小小白白-xray-重要文件索引","aria-hidden":"true"},"#"),r(" 3. 小小白白 Xray 重要文件索引")],-1),Re=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"配置文件位置"),n("th",{style:{"text-align":"left"}},"文件说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),qe=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-01")],-1),ze=n("td",{style:{"text-align":"left"}},[n("code",null,"/usr/local/etc/xray/config.json")],-1),Ae=n("td",{style:{"text-align":"left"}},"Xray 程序设置",-1),Be={style:{"text-align":"center"}},Ce=r("《Xray 服务器篇》"),De=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-02")],-1),Ee=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_cert/xray.cert")],-1),Ge=n("td",{style:{"text-align":"left"}},"TLS 证书",-1),Ie={style:{"text-align":"center"}},Je=r("《Xray 服务器篇》"),Ke=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-03")],-1),Me=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_cert/xray.key")],-1),Oe=n("td",{style:{"text-align":"left"}},"TLS 私钥",-1),Pe={style:{"text-align":"center"}},Qe=r("《Xray 服务器篇》"),Ue=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-04")],-1),Ve=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_log/access.log")],-1),We=n("td",{style:{"text-align":"left"}},"Xray 访问日志",-1),Ye={style:{"text-align":"center"}},Ze=r("《Xray 服务器篇》"),$e=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-05")],-1),tl=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_log/error.log")],-1),el=n("td",{style:{"text-align":"left"}},"Xray 错误日志",-1),ll={style:{"text-align":"center"}},nl=r("《Xray 服务器篇》");s.render=function(r,s){const dl=t("RouterLink");return e(),l(c,null,[u,y,n("table",null,[i,n("tbody",null,[n("tr",null,[x,o,g,n("td",f,[d(dl,{to:"/en/document/level-0/ch03-ssh.html"},{default:a((()=>[h])),_:1})])]),n("tr",null,[m,v,_,n("td",p,[d(dl,{to:"/en/document/level-0/ch03-ssh.html"},{default:a((()=>[X])),_:1})])]),n("tr",null,[b,L,k,n("td",w,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[S])),_:1})])]),n("tr",null,[j,T,F,n("td",H,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[N])),_:1})])]),n("tr",null,[R,q,z,n("td",A,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[B])),_:1})])]),n("tr",null,[C,D,E,n("td",G,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[I])),_:1})])]),n("tr",null,[J,K,M,n("td",O,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[P])),_:1})])]),n("tr",null,[Q,U,V,n("td",W,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[Y])),_:1})])]),n("tr",null,[Z,$,tt,n("td",et,[d(dl,{to:"/en/document/level-0/ch04-security.html"},{default:a((()=>[lt])),_:1})])]),n("tr",null,[nt,dt,at,n("td",ct,[d(dl,{to:"/en/document/level-0/ch05-webpage.html"},{default:a((()=>[rt])),_:1})])]),n("tr",null,[st,ut,yt,n("td",it,[d(dl,{to:"/en/document/level-0/ch05-webpage.html"},{default:a((()=>[xt])),_:1})])]),n("tr",null,[ot,gt,ft,n("td",ht,[d(dl,{to:"/en/document/level-0/ch06-certificates.html"},{default:a((()=>[mt])),_:1})])]),n("tr",null,[vt,_t,pt,n("td",Xt,[d(dl,{to:"/en/document/level-0/ch06-certificates.html"},{default:a((()=>[bt])),_:1})])]),n("tr",null,[Lt,kt,wt,n("td",St,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[jt])),_:1})])]),n("tr",null,[Tt,Ft,Ht,n("td",Nt,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Rt])),_:1})])]),n("tr",null,[qt,zt,At,n("td",Bt,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ct])),_:1})])]),n("tr",null,[Dt,Et,Gt,n("td",It,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Jt])),_:1})])]),n("tr",null,[Kt,Mt,Ot,n("td",Pt,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Qt])),_:1})])])])]),Ut,n("table",null,[Vt,n("tbody",null,[n("tr",null,[Wt,Yt,Zt,n("td",$t,[d(dl,{to:"/en/document/level-0/ch03-ssh.html"},{default:a((()=>[te])),_:1})])]),n("tr",null,[ee,le,ne,n("td",de,[d(dl,{to:"/en/document/level-0/ch05-webpage.html"},{default:a((()=>[ae])),_:1})])]),n("tr",null,[ce,re,se,n("td",ue,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[ye])),_:1})])]),n("tr",null,[ie,xe,oe,n("td",ge,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[fe])),_:1})])]),n("tr",null,[he,me,ve,n("td",_e,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[pe])),_:1})])]),n("tr",null,[Xe,be,Le,n("td",ke,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[we])),_:1})])]),n("tr",null,[Se,je,Te,n("td",Fe,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[He])),_:1})])])])]),Ne,n("table",null,[Re,n("tbody",null,[n("tr",null,[qe,ze,Ae,n("td",Be,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ce])),_:1})])]),n("tr",null,[De,Ee,Ge,n("td",Ie,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Je])),_:1})])]),n("tr",null,[Ke,Me,Oe,n("td",Pe,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Qe])),_:1})])]),n("tr",null,[Ue,Ve,We,n("td",Ye,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ze])),_:1})])]),n("tr",null,[$e,tl,el,n("td",ll,[d(dl,{to:"/en/document/level-0/ch07-xray-server.html"},{default:a((()=>[nl])),_:1})])])])])],64)};export default s; diff --git a/assets/ch09-appendix.html.ebc76319.js b/assets/ch09-appendix.html.f52297d2.js similarity index 99% rename from assets/ch09-appendix.html.ebc76319.js rename to assets/ch09-appendix.html.f52297d2.js index cea18cd74..81e41b8d9 100644 --- a/assets/ch09-appendix.html.ebc76319.js +++ b/assets/ch09-appendix.html.f52297d2.js @@ -1 +1 @@ -import{r as t,o as e,c as l,a as n,b as d,w as a,F as c,e as r}from"./app.755d843f.js";const s={},u=n("h1",{id:"【第-9-章】附录",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#【第-9-章】附录","aria-hidden":"true"},"#"),r(" 【第 9 章】附录")],-1),y=n("h2",{id:"_1-小小白白-linux-基础命令索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_1-小小白白-linux-基础命令索引","aria-hidden":"true"},"#"),r(" 1. 小小白白 Linux 基础命令索引")],-1),i=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"命令名称"),n("th",{style:{"text-align":"left"}},"命令说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),x=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-01")],-1),o=n("td",{style:{"text-align":"left"}},[n("code",null,"apt update")],-1),g=n("td",{style:{"text-align":"left"}},"查询软件更新",-1),f={style:{"text-align":"center"}},h=r("《远程登录篇》"),m=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-02")],-1),v=n("td",{style:{"text-align":"left"}},[n("code",null,"apt upgrade")],-1),_=n("td",{style:{"text-align":"left"}},"执行软件更新",-1),p={style:{"text-align":"center"}},X=r("《远程登录篇》"),b=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-03")],-1),L=n("td",{style:{"text-align":"left"}},[n("code",null,"nano")],-1),k=n("td",{style:{"text-align":"left"}},"文本编辑器",-1),w={style:{"text-align":"center"}},S=r("《安全防护篇》"),j=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-04")],-1),T=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl restart")],-1),F=n("td",{style:{"text-align":"left"}},"重启某个服务",-1),H={style:{"text-align":"center"}},N=r("《安全防护篇》"),R=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-05")],-1),q=n("td",{style:{"text-align":"left"}},[n("code",null,"adduser")],-1),z=n("td",{style:{"text-align":"left"}},"给系统新增用户",-1),A={style:{"text-align":"center"}},B=r("《安全防护篇》"),C=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-06")],-1),D=n("td",{style:{"text-align":"left"}},[n("code",null,"apt install")],-1),E=n("td",{style:{"text-align":"left"}},"安装某个软件",-1),G={style:{"text-align":"center"}},I=r("《安全防护篇》"),J=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-07")],-1),K=n("td",{style:{"text-align":"left"}},[n("code",null,"visudo")],-1),M=n("td",{style:{"text-align":"left"}},"修改 sudo 权限设置专用编辑器",-1),O={style:{"text-align":"center"}},P=r("《安全防护篇》"),Q=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-08")],-1),U=n("td",{style:{"text-align":"left"}},[n("code",null,"sudo")],-1),V=n("td",{style:{"text-align":"left"}},[r("用"),n("code",null,"root"),r("权限运行某个命令")],-1),W={style:{"text-align":"center"}},Y=r("《安全防护篇》"),Z=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-09")],-1),$=n("td",{style:{"text-align":"left"}},[n("code",null,"chmod")],-1),tt=n("td",{style:{"text-align":"left"}},"修改目标文件/文件夹的权限",-1),et={style:{"text-align":"center"}},lt=r("《安全防护篇》"),nt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-10")],-1),dt=n("td",{style:{"text-align":"left"}},[n("code",null,"mkdir")],-1),at=n("td",{style:{"text-align":"left"}},"新建文件夹",-1),ct={style:{"text-align":"center"}},rt=r("《网站建设篇》"),st=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-11")],-1),ut=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl reload")],-1),yt=n("td",{style:{"text-align":"left"}},"重新加载某个服务",-1),it={style:{"text-align":"center"}},xt=r("《网站建设篇》"),ot=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-12")],-1),gt=n("td",{style:{"text-align":"left"}},[n("code",null,"wget")],-1),ft=n("td",{style:{"text-align":"left"}},"访问(或下载)某个网页文件",-1),ht={style:{"text-align":"center"}},mt=r("《证书管理篇》"),vt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-13")],-1),_t=n("td",{style:{"text-align":"left"}},[n("code",null,"acme.sh")],-1),pt=n("td",{style:{"text-align":"left"}},"acme.sh 证书管理相关的命令",-1),Xt={style:{"text-align":"center"}},bt=r("《证书管理篇》"),Lt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-14")],-1),kt=n("td",{style:{"text-align":"left"}},[n("code",null,"rm")],-1),wt=n("td",{style:{"text-align":"left"}},"删除命令",-1),St={style:{"text-align":"center"}},jt=r("《Xray 服务器篇》"),Tt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-15")],-1),Ft=n("td",{style:{"text-align":"left"}},[n("code",null,"crontab -e")],-1),Ht=n("td",{style:{"text-align":"left"}},"编辑当前用户的定时任务",-1),Nt={style:{"text-align":"center"}},Rt=r("《Xray 服务器篇》"),qt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-16")],-1),zt=n("td",{style:{"text-align":"left"}},[n("code",null,"touch")],-1),At=n("td",{style:{"text-align":"left"}},"建立空白文件",-1),Bt={style:{"text-align":"center"}},Ct=r("《Xray 服务器篇》"),Dt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-17")],-1),Et=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl")],-1),Gt=n("td",{style:{"text-align":"left"}},[n("code",null,"systemd"),r("基本服务管理命令")],-1),It={style:{"text-align":"center"}},Jt=r("《Xray 服务器篇》"),Kt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-18")],-1),Mt=n("td",{style:{"text-align":"left"}},[n("code",null,"reboot")],-1),Ot=n("td",{style:{"text-align":"left"}},"重启 Linux 系统",-1),Pt={style:{"text-align":"center"}},Qt=r("《Xray 服务器篇》"),Ut=n("h2",{id:"_2-小小白白-linux-重要配置文件索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_2-小小白白-linux-重要配置文件索引","aria-hidden":"true"},"#"),r(" 2. 小小白白 Linux 重要配置文件索引")],-1),Vt=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"配置文件位置"),n("th",{style:{"text-align":"left"}},"文件说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),Wt=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-01")],-1),Yt=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/ssh/sshd_config")],-1),Zt=n("td",{style:{"text-align":"left"}},"SSH 远程登录程序设置",-1),$t={style:{"text-align":"center"}},te=r("《远程登录篇》"),ee=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-02")],-1),le=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/nginx/nginx.conf")],-1),ne=n("td",{style:{"text-align":"left"}},"Nginx 程序设置",-1),de={style:{"text-align":"center"}},ae=r("《网站建设篇》"),ce=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-03")],-1),re=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/apt/sources.list")],-1),se=n("td",{style:{"text-align":"left"}},"apt 软件源列表",-1),ue={style:{"text-align":"center"}},ye=r("《Xray 服务器篇》"),ie=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-04")],-1),xe=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/apt/sources.list.d/vpsadmin.list")],-1),oe=n("td",{style:{"text-align":"left"}},"用户自定义软件源列表列表",-1),ge={style:{"text-align":"center"}},fe=r("《Xray 服务器篇》"),he=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-05")],-1),me=n("td",{style:{"text-align":"left"}},[n("code",null,"crontab -e")],-1),ve=n("td",{style:{"text-align":"left"}},"当前用户的定时任务",-1),_e={style:{"text-align":"center"}},pe=r("《Xray 服务器篇》"),Xe=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-06")],-1),be=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/sysctl.conf")],-1),Le=n("td",{style:{"text-align":"left"}},"手动设置 kernel 参数",-1),ke={style:{"text-align":"center"}},we=r("《Xray 服务器篇》"),Se=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-07")],-1),je=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/sysctl.d/vpsadmin.conf")],-1),Te=n("td",{style:{"text-align":"left"}},"用户自定义 kernel 参数配置文件",-1),Fe={style:{"text-align":"center"}},He=r("《Xray 服务器篇》"),Ne=n("h2",{id:"_3-小小白白-xray-重要文件索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_3-小小白白-xray-重要文件索引","aria-hidden":"true"},"#"),r(" 3. 小小白白 Xray 重要文件索引")],-1),Re=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"配置文件位置"),n("th",{style:{"text-align":"left"}},"文件说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),qe=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-01")],-1),ze=n("td",{style:{"text-align":"left"}},[n("code",null,"/usr/local/etc/xray/config.json")],-1),Ae=n("td",{style:{"text-align":"left"}},"Xray 程序设置",-1),Be={style:{"text-align":"center"}},Ce=r("《Xray 服务器篇》"),De=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-02")],-1),Ee=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_cert/xray.cert")],-1),Ge=n("td",{style:{"text-align":"left"}},"TLS 证书",-1),Ie={style:{"text-align":"center"}},Je=r("《Xray 服务器篇》"),Ke=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-03")],-1),Me=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_cert/xray.key")],-1),Oe=n("td",{style:{"text-align":"left"}},"TLS 私钥",-1),Pe={style:{"text-align":"center"}},Qe=r("《Xray 服务器篇》"),Ue=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-04")],-1),Ve=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_log/access.log")],-1),We=n("td",{style:{"text-align":"left"}},"Xray 访问日志",-1),Ye={style:{"text-align":"center"}},Ze=r("《Xray 服务器篇》"),$e=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-05")],-1),tl=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_log/error.log")],-1),el=n("td",{style:{"text-align":"left"}},"Xray 错误日志",-1),ll={style:{"text-align":"center"}},nl=r("《Xray 服务器篇》");s.render=function(r,s){const dl=t("RouterLink");return e(),l(c,null,[u,y,n("table",null,[i,n("tbody",null,[n("tr",null,[x,o,g,n("td",f,[d(dl,{to:"/document/level-0/ch03-ssh.html"},{default:a((()=>[h])),_:1})])]),n("tr",null,[m,v,_,n("td",p,[d(dl,{to:"/document/level-0/ch03-ssh.html"},{default:a((()=>[X])),_:1})])]),n("tr",null,[b,L,k,n("td",w,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[S])),_:1})])]),n("tr",null,[j,T,F,n("td",H,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[N])),_:1})])]),n("tr",null,[R,q,z,n("td",A,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[B])),_:1})])]),n("tr",null,[C,D,E,n("td",G,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[I])),_:1})])]),n("tr",null,[J,K,M,n("td",O,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[P])),_:1})])]),n("tr",null,[Q,U,V,n("td",W,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[Y])),_:1})])]),n("tr",null,[Z,$,tt,n("td",et,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[lt])),_:1})])]),n("tr",null,[nt,dt,at,n("td",ct,[d(dl,{to:"/document/level-0/ch05-webpage.html"},{default:a((()=>[rt])),_:1})])]),n("tr",null,[st,ut,yt,n("td",it,[d(dl,{to:"/document/level-0/ch05-webpage.html"},{default:a((()=>[xt])),_:1})])]),n("tr",null,[ot,gt,ft,n("td",ht,[d(dl,{to:"/document/level-0/ch06-certificates.html"},{default:a((()=>[mt])),_:1})])]),n("tr",null,[vt,_t,pt,n("td",Xt,[d(dl,{to:"/document/level-0/ch06-certificates.html"},{default:a((()=>[bt])),_:1})])]),n("tr",null,[Lt,kt,wt,n("td",St,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[jt])),_:1})])]),n("tr",null,[Tt,Ft,Ht,n("td",Nt,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Rt])),_:1})])]),n("tr",null,[qt,zt,At,n("td",Bt,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ct])),_:1})])]),n("tr",null,[Dt,Et,Gt,n("td",It,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Jt])),_:1})])]),n("tr",null,[Kt,Mt,Ot,n("td",Pt,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Qt])),_:1})])])])]),Ut,n("table",null,[Vt,n("tbody",null,[n("tr",null,[Wt,Yt,Zt,n("td",$t,[d(dl,{to:"/document/level-0/ch03-ssh.html"},{default:a((()=>[te])),_:1})])]),n("tr",null,[ee,le,ne,n("td",de,[d(dl,{to:"/document/level-0/ch05-webpage.html"},{default:a((()=>[ae])),_:1})])]),n("tr",null,[ce,re,se,n("td",ue,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[ye])),_:1})])]),n("tr",null,[ie,xe,oe,n("td",ge,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[fe])),_:1})])]),n("tr",null,[he,me,ve,n("td",_e,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[pe])),_:1})])]),n("tr",null,[Xe,be,Le,n("td",ke,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[we])),_:1})])]),n("tr",null,[Se,je,Te,n("td",Fe,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[He])),_:1})])])])]),Ne,n("table",null,[Re,n("tbody",null,[n("tr",null,[qe,ze,Ae,n("td",Be,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ce])),_:1})])]),n("tr",null,[De,Ee,Ge,n("td",Ie,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Je])),_:1})])]),n("tr",null,[Ke,Me,Oe,n("td",Pe,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Qe])),_:1})])]),n("tr",null,[Ue,Ve,We,n("td",Ye,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ze])),_:1})])]),n("tr",null,[$e,tl,el,n("td",ll,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[nl])),_:1})])])])])],64)};export default s; +import{r as t,o as e,c as l,a as n,b as d,w as a,F as c,e as r}from"./app.48111a85.js";const s={},u=n("h1",{id:"【第-9-章】附录",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#【第-9-章】附录","aria-hidden":"true"},"#"),r(" 【第 9 章】附录")],-1),y=n("h2",{id:"_1-小小白白-linux-基础命令索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_1-小小白白-linux-基础命令索引","aria-hidden":"true"},"#"),r(" 1. 小小白白 Linux 基础命令索引")],-1),i=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"命令名称"),n("th",{style:{"text-align":"left"}},"命令说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),x=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-01")],-1),o=n("td",{style:{"text-align":"left"}},[n("code",null,"apt update")],-1),g=n("td",{style:{"text-align":"left"}},"查询软件更新",-1),f={style:{"text-align":"center"}},h=r("《远程登录篇》"),m=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-02")],-1),v=n("td",{style:{"text-align":"left"}},[n("code",null,"apt upgrade")],-1),_=n("td",{style:{"text-align":"left"}},"执行软件更新",-1),p={style:{"text-align":"center"}},X=r("《远程登录篇》"),b=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-03")],-1),L=n("td",{style:{"text-align":"left"}},[n("code",null,"nano")],-1),k=n("td",{style:{"text-align":"left"}},"文本编辑器",-1),w={style:{"text-align":"center"}},S=r("《安全防护篇》"),j=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-04")],-1),T=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl restart")],-1),F=n("td",{style:{"text-align":"left"}},"重启某个服务",-1),H={style:{"text-align":"center"}},N=r("《安全防护篇》"),R=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-05")],-1),q=n("td",{style:{"text-align":"left"}},[n("code",null,"adduser")],-1),z=n("td",{style:{"text-align":"left"}},"给系统新增用户",-1),A={style:{"text-align":"center"}},B=r("《安全防护篇》"),C=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-06")],-1),D=n("td",{style:{"text-align":"left"}},[n("code",null,"apt install")],-1),E=n("td",{style:{"text-align":"left"}},"安装某个软件",-1),G={style:{"text-align":"center"}},I=r("《安全防护篇》"),J=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-07")],-1),K=n("td",{style:{"text-align":"left"}},[n("code",null,"visudo")],-1),M=n("td",{style:{"text-align":"left"}},"修改 sudo 权限设置专用编辑器",-1),O={style:{"text-align":"center"}},P=r("《安全防护篇》"),Q=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-08")],-1),U=n("td",{style:{"text-align":"left"}},[n("code",null,"sudo")],-1),V=n("td",{style:{"text-align":"left"}},[r("用"),n("code",null,"root"),r("权限运行某个命令")],-1),W={style:{"text-align":"center"}},Y=r("《安全防护篇》"),Z=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-09")],-1),$=n("td",{style:{"text-align":"left"}},[n("code",null,"chmod")],-1),tt=n("td",{style:{"text-align":"left"}},"修改目标文件/文件夹的权限",-1),et={style:{"text-align":"center"}},lt=r("《安全防护篇》"),nt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-10")],-1),dt=n("td",{style:{"text-align":"left"}},[n("code",null,"mkdir")],-1),at=n("td",{style:{"text-align":"left"}},"新建文件夹",-1),ct={style:{"text-align":"center"}},rt=r("《网站建设篇》"),st=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-11")],-1),ut=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl reload")],-1),yt=n("td",{style:{"text-align":"left"}},"重新加载某个服务",-1),it={style:{"text-align":"center"}},xt=r("《网站建设篇》"),ot=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-12")],-1),gt=n("td",{style:{"text-align":"left"}},[n("code",null,"wget")],-1),ft=n("td",{style:{"text-align":"left"}},"访问(或下载)某个网页文件",-1),ht={style:{"text-align":"center"}},mt=r("《证书管理篇》"),vt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-13")],-1),_t=n("td",{style:{"text-align":"left"}},[n("code",null,"acme.sh")],-1),pt=n("td",{style:{"text-align":"left"}},"acme.sh 证书管理相关的命令",-1),Xt={style:{"text-align":"center"}},bt=r("《证书管理篇》"),Lt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-14")],-1),kt=n("td",{style:{"text-align":"left"}},[n("code",null,"rm")],-1),wt=n("td",{style:{"text-align":"left"}},"删除命令",-1),St={style:{"text-align":"center"}},jt=r("《Xray 服务器篇》"),Tt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-15")],-1),Ft=n("td",{style:{"text-align":"left"}},[n("code",null,"crontab -e")],-1),Ht=n("td",{style:{"text-align":"left"}},"编辑当前用户的定时任务",-1),Nt={style:{"text-align":"center"}},Rt=r("《Xray 服务器篇》"),qt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-16")],-1),zt=n("td",{style:{"text-align":"left"}},[n("code",null,"touch")],-1),At=n("td",{style:{"text-align":"left"}},"建立空白文件",-1),Bt={style:{"text-align":"center"}},Ct=r("《Xray 服务器篇》"),Dt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-17")],-1),Et=n("td",{style:{"text-align":"left"}},[n("code",null,"systemctl")],-1),Gt=n("td",{style:{"text-align":"left"}},[n("code",null,"systemd"),r("基本服务管理命令")],-1),It={style:{"text-align":"center"}},Jt=r("《Xray 服务器篇》"),Kt=n("td",{style:{"text-align":"center"}},[n("code",null,"cmd-18")],-1),Mt=n("td",{style:{"text-align":"left"}},[n("code",null,"reboot")],-1),Ot=n("td",{style:{"text-align":"left"}},"重启 Linux 系统",-1),Pt={style:{"text-align":"center"}},Qt=r("《Xray 服务器篇》"),Ut=n("h2",{id:"_2-小小白白-linux-重要配置文件索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_2-小小白白-linux-重要配置文件索引","aria-hidden":"true"},"#"),r(" 2. 小小白白 Linux 重要配置文件索引")],-1),Vt=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"配置文件位置"),n("th",{style:{"text-align":"left"}},"文件说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),Wt=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-01")],-1),Yt=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/ssh/sshd_config")],-1),Zt=n("td",{style:{"text-align":"left"}},"SSH 远程登录程序设置",-1),$t={style:{"text-align":"center"}},te=r("《远程登录篇》"),ee=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-02")],-1),le=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/nginx/nginx.conf")],-1),ne=n("td",{style:{"text-align":"left"}},"Nginx 程序设置",-1),de={style:{"text-align":"center"}},ae=r("《网站建设篇》"),ce=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-03")],-1),re=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/apt/sources.list")],-1),se=n("td",{style:{"text-align":"left"}},"apt 软件源列表",-1),ue={style:{"text-align":"center"}},ye=r("《Xray 服务器篇》"),ie=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-04")],-1),xe=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/apt/sources.list.d/vpsadmin.list")],-1),oe=n("td",{style:{"text-align":"left"}},"用户自定义软件源列表列表",-1),ge={style:{"text-align":"center"}},fe=r("《Xray 服务器篇》"),he=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-05")],-1),me=n("td",{style:{"text-align":"left"}},[n("code",null,"crontab -e")],-1),ve=n("td",{style:{"text-align":"left"}},"当前用户的定时任务",-1),_e={style:{"text-align":"center"}},pe=r("《Xray 服务器篇》"),Xe=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-06")],-1),be=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/sysctl.conf")],-1),Le=n("td",{style:{"text-align":"left"}},"手动设置 kernel 参数",-1),ke={style:{"text-align":"center"}},we=r("《Xray 服务器篇》"),Se=n("td",{style:{"text-align":"center"}},[n("code",null,"conf-07")],-1),je=n("td",{style:{"text-align":"left"}},[n("code",null,"/etc/sysctl.d/vpsadmin.conf")],-1),Te=n("td",{style:{"text-align":"left"}},"用户自定义 kernel 参数配置文件",-1),Fe={style:{"text-align":"center"}},He=r("《Xray 服务器篇》"),Ne=n("h2",{id:"_3-小小白白-xray-重要文件索引",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#_3-小小白白-xray-重要文件索引","aria-hidden":"true"},"#"),r(" 3. 小小白白 Xray 重要文件索引")],-1),Re=n("thead",null,[n("tr",null,[n("th",{style:{"text-align":"center"}},"编号"),n("th",{style:{"text-align":"left"}},"配置文件位置"),n("th",{style:{"text-align":"left"}},"文件说明"),n("th",{style:{"text-align":"center"}},"出现篇章")])],-1),qe=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-01")],-1),ze=n("td",{style:{"text-align":"left"}},[n("code",null,"/usr/local/etc/xray/config.json")],-1),Ae=n("td",{style:{"text-align":"left"}},"Xray 程序设置",-1),Be={style:{"text-align":"center"}},Ce=r("《Xray 服务器篇》"),De=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-02")],-1),Ee=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_cert/xray.cert")],-1),Ge=n("td",{style:{"text-align":"left"}},"TLS 证书",-1),Ie={style:{"text-align":"center"}},Je=r("《Xray 服务器篇》"),Ke=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-03")],-1),Me=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_cert/xray.key")],-1),Oe=n("td",{style:{"text-align":"left"}},"TLS 私钥",-1),Pe={style:{"text-align":"center"}},Qe=r("《Xray 服务器篇》"),Ue=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-04")],-1),Ve=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_log/access.log")],-1),We=n("td",{style:{"text-align":"left"}},"Xray 访问日志",-1),Ye={style:{"text-align":"center"}},Ze=r("《Xray 服务器篇》"),$e=n("td",{style:{"text-align":"center"}},[n("code",null,"xray-05")],-1),tl=n("td",{style:{"text-align":"left"}},[n("code",null,"/home/vpsadmin/xray_log/error.log")],-1),el=n("td",{style:{"text-align":"left"}},"Xray 错误日志",-1),ll={style:{"text-align":"center"}},nl=r("《Xray 服务器篇》");s.render=function(r,s){const dl=t("RouterLink");return e(),l(c,null,[u,y,n("table",null,[i,n("tbody",null,[n("tr",null,[x,o,g,n("td",f,[d(dl,{to:"/document/level-0/ch03-ssh.html"},{default:a((()=>[h])),_:1})])]),n("tr",null,[m,v,_,n("td",p,[d(dl,{to:"/document/level-0/ch03-ssh.html"},{default:a((()=>[X])),_:1})])]),n("tr",null,[b,L,k,n("td",w,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[S])),_:1})])]),n("tr",null,[j,T,F,n("td",H,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[N])),_:1})])]),n("tr",null,[R,q,z,n("td",A,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[B])),_:1})])]),n("tr",null,[C,D,E,n("td",G,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[I])),_:1})])]),n("tr",null,[J,K,M,n("td",O,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[P])),_:1})])]),n("tr",null,[Q,U,V,n("td",W,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[Y])),_:1})])]),n("tr",null,[Z,$,tt,n("td",et,[d(dl,{to:"/document/level-0/ch04-security.html"},{default:a((()=>[lt])),_:1})])]),n("tr",null,[nt,dt,at,n("td",ct,[d(dl,{to:"/document/level-0/ch05-webpage.html"},{default:a((()=>[rt])),_:1})])]),n("tr",null,[st,ut,yt,n("td",it,[d(dl,{to:"/document/level-0/ch05-webpage.html"},{default:a((()=>[xt])),_:1})])]),n("tr",null,[ot,gt,ft,n("td",ht,[d(dl,{to:"/document/level-0/ch06-certificates.html"},{default:a((()=>[mt])),_:1})])]),n("tr",null,[vt,_t,pt,n("td",Xt,[d(dl,{to:"/document/level-0/ch06-certificates.html"},{default:a((()=>[bt])),_:1})])]),n("tr",null,[Lt,kt,wt,n("td",St,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[jt])),_:1})])]),n("tr",null,[Tt,Ft,Ht,n("td",Nt,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Rt])),_:1})])]),n("tr",null,[qt,zt,At,n("td",Bt,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ct])),_:1})])]),n("tr",null,[Dt,Et,Gt,n("td",It,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Jt])),_:1})])]),n("tr",null,[Kt,Mt,Ot,n("td",Pt,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Qt])),_:1})])])])]),Ut,n("table",null,[Vt,n("tbody",null,[n("tr",null,[Wt,Yt,Zt,n("td",$t,[d(dl,{to:"/document/level-0/ch03-ssh.html"},{default:a((()=>[te])),_:1})])]),n("tr",null,[ee,le,ne,n("td",de,[d(dl,{to:"/document/level-0/ch05-webpage.html"},{default:a((()=>[ae])),_:1})])]),n("tr",null,[ce,re,se,n("td",ue,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[ye])),_:1})])]),n("tr",null,[ie,xe,oe,n("td",ge,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[fe])),_:1})])]),n("tr",null,[he,me,ve,n("td",_e,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[pe])),_:1})])]),n("tr",null,[Xe,be,Le,n("td",ke,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[we])),_:1})])]),n("tr",null,[Se,je,Te,n("td",Fe,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[He])),_:1})])])])]),Ne,n("table",null,[Re,n("tbody",null,[n("tr",null,[qe,ze,Ae,n("td",Be,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ce])),_:1})])]),n("tr",null,[De,Ee,Ge,n("td",Ie,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Je])),_:1})])]),n("tr",null,[Ke,Me,Oe,n("td",Pe,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Qe])),_:1})])]),n("tr",null,[Ue,Ve,We,n("td",Ye,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[Ze])),_:1})])]),n("tr",null,[$e,tl,el,n("td",ll,[d(dl,{to:"/document/level-0/ch07-xray-server.html"},{default:a((()=>[nl])),_:1})])])])])],64)};export default s; diff --git a/assets/classDiagram-62cfb02d.f8c26c1c.js b/assets/classDiagram-62cfb02d.b94f625b.js similarity index 51% rename from assets/classDiagram-62cfb02d.f8c26c1c.js rename to assets/classDiagram-62cfb02d.b94f625b.js index 08c798edf..b3938d1d9 100644 --- a/assets/classDiagram-62cfb02d.f8c26c1c.js +++ b/assets/classDiagram-62cfb02d.b94f625b.js @@ -1 +1 @@ -import{p as t,d as e,s as r}from"./styles-237fcbdf.f2a0b31b.js";import{c as a,l as d,h as n,i}from"./mermaid.core.a66200b0.js";import{G as o,l as s}from"./layout.2f099f66.js";import{s as p}from"./svgDraw-6750006d.4f7863f3.js";import"./line.f17bed9e.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";let f={};const c=function(t){const e=Object.entries(f).find((e=>e[1].label===t));if(e)return e[0]},g={parser:t,db:e,renderer:{draw:function(t,e,r,g){const h=a().class;f={},d.info("Rendering diagram "+t);const m=a().securityLevel;let l;"sandbox"===m&&(l=n("#i"+e));const u=n("sandbox"===m?l.nodes()[0].contentDocument.body:"body"),k=u.select(`[id='${e}']`);var b;(b=k).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"),b.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"),b.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"),b.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"),b.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"),b.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"),b.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"),b.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");const L=new o({multigraph:!0});L.setGraph({isMultiGraph:!0}),L.setDefaultEdgeLabel((function(){return{}}));const y=g.db.getClasses(),x=Object.keys(y);for(const a of x){const t=y[a],e=p.drawClass(k,t,h,g);f[e.id]=e,L.setNode(e.id,e),d.info("Org height: "+e.height)}g.db.getRelations().forEach((function(t){d.info("tjoho"+c(t.id1)+c(t.id2)+JSON.stringify(t)),L.setEdge(c(t.id1),c(t.id2),{relation:t},t.title||"DEFAULT")}));g.db.getNotes().forEach((function(t){d.debug(`Adding note: ${JSON.stringify(t)}`);const e=p.drawNote(k,t,h,g);f[e.id]=e,L.setNode(e.id,e),t.class&&t.class in y&&L.setEdge(t.id,c(t.class),{relation:{id1:t.id,id2:t.class,relation:{type1:"none",type2:"none",lineType:10}}},"DEFAULT")})),s(L),L.nodes().forEach((function(t){void 0!==t&&void 0!==L.node(t)&&(d.debug("Node "+t+": "+JSON.stringify(L.node(t))),u.select("#"+(g.db.lookUpDomId(t)||t)).attr("transform","translate("+(L.node(t).x-L.node(t).width/2)+","+(L.node(t).y-L.node(t).height/2)+" )"))})),L.edges().forEach((function(t){void 0!==t&&void 0!==L.edge(t)&&(d.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(L.edge(t))),p.drawEdge(k,L.edge(t),L.edge(t).relation,h,g))}));const E=k.node().getBBox(),w=E.width+40,M=E.height+40;i(k,M,w,h.useMaxWidth);const j=`${E.x-20} ${E.y-20} ${w} ${M}`;d.debug(`viewBox ${j}`),k.attr("viewBox",j)}},styles:r,init:t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute,e.clear()}};export{g as diagram}; +import{p as t,d as e,s as r}from"./styles-237fcbdf.3c95e98b.js";import{c as a,l as d,h as n,i}from"./mermaid.core.3a590193.js";import{G as o,l as s}from"./layout.02c3e151.js";import{s as p}from"./svgDraw-6750006d.f814d75b.js";import"./line.53b161c2.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";let c={};const f=function(t){const e=Object.entries(c).find((e=>e[1].label===t));if(e)return e[0]},g={parser:t,db:e,renderer:{draw:function(t,e,r,g){const h=a().class;c={},d.info("Rendering diagram "+t);const m=a().securityLevel;let l;"sandbox"===m&&(l=n("#i"+e));const u=n("sandbox"===m?l.nodes()[0].contentDocument.body:"body"),k=u.select(`[id='${e}']`);var L;(L=k).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"),L.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"),L.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"),L.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"),L.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"),L.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"),L.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"),L.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");const b=new o({multigraph:!0});b.setGraph({isMultiGraph:!0}),b.setDefaultEdgeLabel((function(){return{}}));const y=g.db.getClasses(),x=Object.keys(y);for(const a of x){const t=y[a],e=p.drawClass(k,t,h,g);c[e.id]=e,b.setNode(e.id,e),d.info("Org height: "+e.height)}g.db.getRelations().forEach((function(t){d.info("tjoho"+f(t.id1)+f(t.id2)+JSON.stringify(t)),b.setEdge(f(t.id1),f(t.id2),{relation:t},t.title||"DEFAULT")}));g.db.getNotes().forEach((function(t){d.debug(`Adding note: ${JSON.stringify(t)}`);const e=p.drawNote(k,t,h,g);c[e.id]=e,b.setNode(e.id,e),t.class&&t.class in y&&b.setEdge(t.id,f(t.class),{relation:{id1:t.id,id2:t.class,relation:{type1:"none",type2:"none",lineType:10}}},"DEFAULT")})),s(b),b.nodes().forEach((function(t){void 0!==t&&void 0!==b.node(t)&&(d.debug("Node "+t+": "+JSON.stringify(b.node(t))),u.select("#"+(g.db.lookUpDomId(t)||t)).attr("transform","translate("+(b.node(t).x-b.node(t).width/2)+","+(b.node(t).y-b.node(t).height/2)+" )"))})),b.edges().forEach((function(t){void 0!==t&&void 0!==b.edge(t)&&(d.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(b.edge(t))),p.drawEdge(k,b.edge(t),b.edge(t).relation,h,g))}));const E=k.node().getBBox(),w=E.width+40,M=E.height+40;i(k,M,w,h.useMaxWidth);const j=`${E.x-20} ${E.y-20} ${w} ${M}`;d.debug(`viewBox ${j}`),k.attr("viewBox",j)}},styles:r,init:t=>{t.class||(t.class={}),t.class.arrowMarkerAbsolute=t.arrowMarkerAbsolute,e.clear()}};export{g as diagram}; diff --git a/assets/classDiagram-v2-c1dfb0e0.11f799d7.js b/assets/classDiagram-v2-c1dfb0e0.308507d3.js similarity index 82% rename from assets/classDiagram-v2-c1dfb0e0.11f799d7.js rename to assets/classDiagram-v2-c1dfb0e0.308507d3.js index dfc9c1a27..ebca64188 100644 --- a/assets/classDiagram-v2-c1dfb0e0.11f799d7.js +++ b/assets/classDiagram-v2-c1dfb0e0.308507d3.js @@ -1 +1 @@ -var e=Object.defineProperty,t=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,o=(t,l,a)=>l in t?e(t,l,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[l]=a,n=(e,n)=>{for(var s in n||(n={}))l.call(n,s)&&o(e,s,n[s]);if(t)for(var s of t(n))a.call(n,s)&&o(e,s,n[s]);return e};"undefined"!=typeof require&&require;import{p as s,d as i,s as r}from"./styles-237fcbdf.f2a0b31b.js";import{l as d,c,h as p,y as f,t as b,j as u,r as y,o as g,p as h}from"./mermaid.core.a66200b0.js";import{G as m}from"./layout.2f099f66.js";import{r as v}from"./index-05087a90.4347f31d.js";import"./edges-97052da4.ceadb26f.js";import"./createText-2f679d62.584f3edd.js";import"./svgDraw-6750006d.4f7863f3.js";import"./line.f17bed9e.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";const w=e=>u.sanitizeText(e,c());let x={dividerMargin:10,padding:5,textHeight:10,curve:void 0};const k=function(e,t,l,a,o){const n=Object.keys(e);d.info("keys:",n),d.info(e),n.forEach((function(l){var n,s,i,r;const p=e[l];let f="";p.cssClasses.length>0&&(f=f+" "+p.cssClasses.join(" "));const b="",u="",y=null!=(n=p.label)?n:p.id,g={labelStyle:b,shape:"class_box",labelText:w(y),classData:p,rx:0,ry:0,class:f,style:u,id:p.id,domId:p.domId,tooltip:a.db.getTooltip(p.id,o)||"",haveCallback:p.haveCallback,link:p.link,width:"group"===p.type?500:void 0,type:p.type,padding:null!=(s=null==(i=c().flowchart)?void 0:i.padding)?s:null==(r=c().class)?void 0:r.padding};t.setNode(p.id,g),o&&t.setParent(p.id,o),d.info("setNode",g)}))};function T(e){let t;switch(e){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={parser:s,db:i,renderer:{setConf:function(e){x=n(n({},x),e)},draw:async function(e,t,l,a){var o,n,s,i;d.info("Drawing class - ",t);const r=null!=(o=c().flowchart)?o:c().class,j=c().securityLevel;d.info("config:",r);const S=null!=(n=null==r?void 0:r.nodeSpacing)?n:50,L=null!=(s=null==r?void 0:r.rankSpacing)?s:50,E=new m({multigraph:!0,compound:!0}).setGraph({rankdir:a.db.getDirection(),nodesep:S,ranksep:L,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}})),D=a.db.getNamespaces(),N=a.db.getClasses(),O=a.db.getRelations(),A=a.db.getNotes();let C;d.info(O),function(e,t,l,a){const o=Object.keys(e);d.info("keys:",o),d.info(e),o.forEach((function(o){var n,s,i;const r=e[o],p={shape:"rect",id:r.id,domId:r.domId,labelText:w(r.id),labelStyle:"",style:"fill: none; stroke: black",padding:null!=(n=null==(s=c().flowchart)?void 0:s.padding)?n:null==(i=c().class)?void 0:i.padding};t.setNode(r.id,p),k(r.classes,t,l,a,r.id),d.info("setNode",p)}))}(D,E,t,a),k(N,E,t,a),function(e,t){const l=c().flowchart;let a=0;e.forEach((function(e){var o,n;a++;const s={classes:"relation",pattern:1==e.relation.lineType?"dashed":"solid",id:"id"+a,arrowhead:"arrow_open"===e.type?"none":"normal",startLabelRight:"none"===e.relationTitle1?"":e.relationTitle1,endLabelLeft:"none"===e.relationTitle2?"":e.relationTitle2,arrowTypeStart:T(e.relation.type1),arrowTypeEnd:T(e.relation.type2),style:"fill:none",labelStyle:"",curve:y(null==l?void 0:l.curve,g)};if(d.info(s,e),void 0!==e.style){const t=h(e.style);s.style=t.style,s.labelStyle=t.labelStyle}e.text=e.title,void 0===e.text?void 0!==e.style&&(s.arrowheadStyle="fill: #333"):(s.arrowheadStyle="fill: #333",s.labelpos="c",(null!=(o=null==(n=c().flowchart)?void 0:n.htmlLabels)?o:c().htmlLabels)?(s.labelType="html",s.label=''+e.text+""):(s.labelType="text",s.label=e.text.replace(u.lineBreakRegex,"\n"),void 0===e.style&&(s.style=s.style||"stroke: #333; stroke-width: 1.5px;fill:none"),s.labelStyle=s.labelStyle.replace("color:","fill:"))),t.setEdge(e.id1,e.id2,s,a)}))}(O,E),function(e,t,l,a){d.info(e),e.forEach((function(e,o){var n,s,i;const r=e,p="",f="",b=r.text,u={labelStyle:p,shape:"note",labelText:w(b),noteData:r,rx:0,ry:0,class:"",style:f,id:r.id,domId:r.id,tooltip:"",type:"note",padding:null!=(n=null==(s=c().flowchart)?void 0:s.padding)?n:null==(i=c().class)?void 0:i.padding};if(t.setNode(r.id,u),d.info("setNode",u),!r.class||!(r.class in a))return;const h=l+o,m={id:`edgeNote${h}`,classes:"relation",pattern:"dotted",arrowhead:"none",startLabelRight:"",endLabelLeft:"",arrowTypeStart:"none",arrowTypeEnd:"none",style:"fill:none",labelStyle:"",curve:y(x.curve,g)};t.setEdge(r.id,r.class,m,h)}))}(A,E,O.length+1,N),"sandbox"===j&&(C=p("#i"+t));const I=p("sandbox"===j?C.nodes()[0].contentDocument.body:"body"),M=I.select(`[id="${t}"]`),P=I.select("#"+t+" g");if(await v(P,E,["aggregation","extension","composition","dependency","lollipop"],"classDiagram",t),f.insertTitle(M,"classTitleText",null!=(i=null==r?void 0:r.titleTopMargin)?i:5,a.db.getDiagramTitle()),b(E,M,null==r?void 0:r.diagramPadding,null==r?void 0:r.useMaxWidth),!(null==r?void 0:r.htmlLabels)){const e="sandbox"===j?C.nodes()[0].contentDocument:document,l=e.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const t of l){const l=t.getBBox(),a=e.createElementNS("http://www.w3.org/2000/svg","rect");a.setAttribute("rx",0),a.setAttribute("ry",0),a.setAttribute("width",l.width),a.setAttribute("height",l.height),t.insertBefore(a,t.firstChild)}}}},styles:r,init:e=>{e.class||(e.class={}),e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute,i.clear()}};export{j as diagram}; +var e=Object.defineProperty,t=Object.getOwnPropertySymbols,l=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,o=(t,l,a)=>l in t?e(t,l,{enumerable:!0,configurable:!0,writable:!0,value:a}):t[l]=a,n=(e,n)=>{for(var s in n||(n={}))l.call(n,s)&&o(e,s,n[s]);if(t)for(var s of t(n))a.call(n,s)&&o(e,s,n[s]);return e};"undefined"!=typeof require&&require;import{p as s,d as i,s as r}from"./styles-237fcbdf.3c95e98b.js";import{l as d,c,h as p,y as b,t as f,j as u,r as y,o as g,p as h}from"./mermaid.core.3a590193.js";import{G as m}from"./layout.02c3e151.js";import{r as v}from"./index-05087a90.017bdfe5.js";import"./edges-97052da4.e255927b.js";import"./createText-2f679d62.a374f608.js";import"./svgDraw-6750006d.f814d75b.js";import"./line.53b161c2.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";const w=e=>u.sanitizeText(e,c());let x={dividerMargin:10,padding:5,textHeight:10,curve:void 0};const k=function(e,t,l,a,o){const n=Object.keys(e);d.info("keys:",n),d.info(e),n.forEach((function(l){var n,s,i,r;const p=e[l];let b="";p.cssClasses.length>0&&(b=b+" "+p.cssClasses.join(" "));const f="",u="",y=null!=(n=p.label)?n:p.id,g={labelStyle:f,shape:"class_box",labelText:w(y),classData:p,rx:0,ry:0,class:b,style:u,id:p.id,domId:p.domId,tooltip:a.db.getTooltip(p.id,o)||"",haveCallback:p.haveCallback,link:p.link,width:"group"===p.type?500:void 0,type:p.type,padding:null!=(s=null==(i=c().flowchart)?void 0:i.padding)?s:null==(r=c().class)?void 0:r.padding};t.setNode(p.id,g),o&&t.setParent(p.id,o),d.info("setNode",g)}))};function T(e){let t;switch(e){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={parser:s,db:i,renderer:{setConf:function(e){x=n(n({},x),e)},draw:async function(e,t,l,a){var o,n,s,i;d.info("Drawing class - ",t);const r=null!=(o=c().flowchart)?o:c().class,j=c().securityLevel;d.info("config:",r);const S=null!=(n=null==r?void 0:r.nodeSpacing)?n:50,L=null!=(s=null==r?void 0:r.rankSpacing)?s:50,E=new m({multigraph:!0,compound:!0}).setGraph({rankdir:a.db.getDirection(),nodesep:S,ranksep:L,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}})),D=a.db.getNamespaces(),N=a.db.getClasses(),O=a.db.getRelations(),A=a.db.getNotes();let C;d.info(O),function(e,t,l,a){const o=Object.keys(e);d.info("keys:",o),d.info(e),o.forEach((function(o){var n,s,i;const r=e[o],p={shape:"rect",id:r.id,domId:r.domId,labelText:w(r.id),labelStyle:"",style:"fill: none; stroke: black",padding:null!=(n=null==(s=c().flowchart)?void 0:s.padding)?n:null==(i=c().class)?void 0:i.padding};t.setNode(r.id,p),k(r.classes,t,l,a,r.id),d.info("setNode",p)}))}(D,E,t,a),k(N,E,t,a),function(e,t){const l=c().flowchart;let a=0;e.forEach((function(e){var o,n;a++;const s={classes:"relation",pattern:1==e.relation.lineType?"dashed":"solid",id:"id"+a,arrowhead:"arrow_open"===e.type?"none":"normal",startLabelRight:"none"===e.relationTitle1?"":e.relationTitle1,endLabelLeft:"none"===e.relationTitle2?"":e.relationTitle2,arrowTypeStart:T(e.relation.type1),arrowTypeEnd:T(e.relation.type2),style:"fill:none",labelStyle:"",curve:y(null==l?void 0:l.curve,g)};if(d.info(s,e),void 0!==e.style){const t=h(e.style);s.style=t.style,s.labelStyle=t.labelStyle}e.text=e.title,void 0===e.text?void 0!==e.style&&(s.arrowheadStyle="fill: #333"):(s.arrowheadStyle="fill: #333",s.labelpos="c",(null!=(o=null==(n=c().flowchart)?void 0:n.htmlLabels)?o:c().htmlLabels)?(s.labelType="html",s.label=''+e.text+""):(s.labelType="text",s.label=e.text.replace(u.lineBreakRegex,"\n"),void 0===e.style&&(s.style=s.style||"stroke: #333; stroke-width: 1.5px;fill:none"),s.labelStyle=s.labelStyle.replace("color:","fill:"))),t.setEdge(e.id1,e.id2,s,a)}))}(O,E),function(e,t,l,a){d.info(e),e.forEach((function(e,o){var n,s,i;const r=e,p="",b="",f=r.text,u={labelStyle:p,shape:"note",labelText:w(f),noteData:r,rx:0,ry:0,class:"",style:b,id:r.id,domId:r.id,tooltip:"",type:"note",padding:null!=(n=null==(s=c().flowchart)?void 0:s.padding)?n:null==(i=c().class)?void 0:i.padding};if(t.setNode(r.id,u),d.info("setNode",u),!r.class||!(r.class in a))return;const h=l+o,m={id:`edgeNote${h}`,classes:"relation",pattern:"dotted",arrowhead:"none",startLabelRight:"",endLabelLeft:"",arrowTypeStart:"none",arrowTypeEnd:"none",style:"fill:none",labelStyle:"",curve:y(x.curve,g)};t.setEdge(r.id,r.class,m,h)}))}(A,E,O.length+1,N),"sandbox"===j&&(C=p("#i"+t));const I=p("sandbox"===j?C.nodes()[0].contentDocument.body:"body"),M=I.select(`[id="${t}"]`),P=I.select("#"+t+" g");if(await v(P,E,["aggregation","extension","composition","dependency","lollipop"],"classDiagram",t),b.insertTitle(M,"classTitleText",null!=(i=null==r?void 0:r.titleTopMargin)?i:5,a.db.getDiagramTitle()),f(E,M,null==r?void 0:r.diagramPadding,null==r?void 0:r.useMaxWidth),!(null==r?void 0:r.htmlLabels)){const e="sandbox"===j?C.nodes()[0].contentDocument:document,l=e.querySelectorAll('[id="'+t+'"] .edgeLabel .label');for(const t of l){const l=t.getBBox(),a=e.createElementNS("http://www.w3.org/2000/svg","rect");a.setAttribute("rx",0),a.setAttribute("ry",0),a.setAttribute("width",l.width),a.setAttribute("height",l.height),t.insertBefore(a,t.firstChild)}}}},styles:r,init:e=>{e.class||(e.class={}),e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute,i.clear()}};export{j as diagram}; diff --git a/assets/command.html.7a5c22da.js b/assets/command.html.1ff61964.js similarity index 99% rename from assets/command.html.7a5c22da.js rename to assets/command.html.1ff61964.js index b8e05ecae..78cc2c8be 100644 --- a/assets/command.html.7a5c22da.js +++ b/assets/command.html.1ff61964.js @@ -1 +1 @@ -import{r as n,o as e,c as a,a as s,b as r,w as i,F as l,d as t,e as c}from"./app.755d843f.js";const o={},d=t('

    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.\n\nUsage:\n\n        xray <command> [arguments]\n\nThe commands are:\n\n        run          Run Xray with config, the default command\n        version      Show current version of Xray\n        api          Call an API in an Xray process\n        tls          TLS tools\n        uuid         Generate new UUIDs\n\nUse "xray help <command>" for more information about a command.\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    xray run

    Specify one or more configuration files and run.

    Usage:

     xray run [-c config.json] [-confdir dir]\n
    1
    Run Xray with config, the default command.\n\nThe -config=file, -c=file flags set the config files for\nXray. Multiple assign is accepted.\n\nThe -confdir=dir flag sets a dir with multiple json config\n\nThe -format=json flag sets the format of config files.\nDefault "json".\n\nThe -test flag tells Xray to test config files only,\nwithout launching the server\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    xray version

    Output Xray version, Golang version and other information.

    Usage:

     xray version\n
    1

    xray api

    To call Xray's gRPC API, it needs to be enabled in the configuration file.

    Usage:

    xray api <command> [arguments]\n
    1
            restartlogger Restart the logger\n        stats         Get statistics\n        statsquery    Query statistics\n        statssys      Get system statistics\n        adi           Add inbounds\n        ado           Add outbounds\n        rmi           Remove inbounds\n        rmo           Remove outbounds\n
    1
    2
    3
    4
    5
    6
    7
    8

    xray tls

    Some tools related to TLS.

    Usage:

    xray tls <command> [arguments]\n
    1
            cert         Generate TLS certificates\n        ping         Ping the domain with TLS handshake\n
    1
    2

    xray uuid

    Generated UUID.

    Usage:

    xray uuid\n
    1
    ',28),p={class:"custom-container tip"},u=s("p",{class:"custom-container-title"},"Tip",-1),m=s("p",null,[c("When "),s("code",null,"-config"),c(" is not specified, Xray will try to load "),s("code",null,"config.json"),c(" from the following paths:")],-1),b=s("li",null,"Working Directory",-1),g=c("The path specified by "),h=s("code",null,"Xray.location.asset",-1),x=c(" in the "),f=c("environment variable"),v=c(".");o.render=function(t,c){const o=n("RouterLink");return e(),a(l,null,[d,s("div",p,[u,m,s("ul",null,[b,s("li",null,[g,h,x,r(o,{to:"/en/config/features/env.html"},{default:i((()=>[f])),_:1}),v])])])],64)};export default o; +import{r as n,o as e,c as a,a as s,b as r,w as i,F as l,d as t,e as c}from"./app.48111a85.js";const o={},d=t('

    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.\n\nUsage:\n\n        xray <command> [arguments]\n\nThe commands are:\n\n        run          Run Xray with config, the default command\n        version      Show current version of Xray\n        api          Call an API in an Xray process\n        tls          TLS tools\n        uuid         Generate new UUIDs\n\nUse "xray help <command>" for more information about a command.\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    xray run

    Specify one or more configuration files and run.

    Usage:

     xray run [-c config.json] [-confdir dir]\n
    1
    Run Xray with config, the default command.\n\nThe -config=file, -c=file flags set the config files for\nXray. Multiple assign is accepted.\n\nThe -confdir=dir flag sets a dir with multiple json config\n\nThe -format=json flag sets the format of config files.\nDefault "json".\n\nThe -test flag tells Xray to test config files only,\nwithout launching the server\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    xray version

    Output Xray version, Golang version and other information.

    Usage:

     xray version\n
    1

    xray api

    To call Xray's gRPC API, it needs to be enabled in the configuration file.

    Usage:

    xray api <command> [arguments]\n
    1
            restartlogger Restart the logger\n        stats         Get statistics\n        statsquery    Query statistics\n        statssys      Get system statistics\n        adi           Add inbounds\n        ado           Add outbounds\n        rmi           Remove inbounds\n        rmo           Remove outbounds\n
    1
    2
    3
    4
    5
    6
    7
    8

    xray tls

    Some tools related to TLS.

    Usage:

    xray tls <command> [arguments]\n
    1
            cert         Generate TLS certificates\n        ping         Ping the domain with TLS handshake\n
    1
    2

    xray uuid

    Generated UUID.

    Usage:

    xray uuid\n
    1
    ',28),p={class:"custom-container tip"},u=s("p",{class:"custom-container-title"},"Tip",-1),m=s("p",null,[c("When "),s("code",null,"-config"),c(" is not specified, Xray will try to load "),s("code",null,"config.json"),c(" from the following paths:")],-1),b=s("li",null,"Working Directory",-1),g=c("The path specified by "),h=s("code",null,"Xray.location.asset",-1),x=c(" in the "),f=c("environment variable"),v=c(".");o.render=function(t,c){const o=n("RouterLink");return e(),a(l,null,[d,s("div",p,[u,m,s("ul",null,[b,s("li",null,[g,h,x,r(o,{to:"/en/config/features/env.html"},{default:i((()=>[f])),_:1}),v])])])],64)};export default o; diff --git a/assets/command.html.1ad9e5f1.js b/assets/command.html.431bc70f.js similarity index 99% rename from assets/command.html.1ad9e5f1.js rename to assets/command.html.431bc70f.js index 495f52862..72f5c3479 100644 --- a/assets/command.html.1ad9e5f1.js +++ b/assets/command.html.431bc70f.js @@ -1 +1 @@ -import{r as n,o as a,c as e,a as s,b as r,w as l,F as i,d as t,e as c}from"./app.755d843f.js";const p={},u=t('

    命令参数

    提示

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

    获取基本命令

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

    Xray is a platform for building proxies.\n\nUsage:\n\n        xray <command> [arguments]\n\nThe commands are:\n\n        run          Run Xray with config, the default command\n        version      Show current version of Xray\n        api          Call an API in an Xray process\n        tls          TLS tools\n        uuid         Generate new UUIDs\n\nUse "xray help <command>" for more information about a command.\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    xray run

    指定一个或多个配置文件,并运行。

    使用方法:

     xray run [-c config.json] [-confdir dir]\n
    1
    Run Xray with config, the default command.\n\nThe -config=file, -c=file flags set the config files for\nXray. Multiple assign is accepted.\n\nThe -confdir=dir flag sets a dir with multiple json config\n\nThe -format=json flag sets the format of config files.\nDefault "auto".\n\nThe -test flag tells Xray to test config files only,\nwithout launching the server\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    提示

    配置文件除了默认的 JSON 格式外,也可以使用 TOML 和 YAML。在不指定格式的前提下会通过文件扩展名识别。

    xray version

    输出 Xray 版本、 Golang 版本等信息。

    使用方法:

     xray version\n
    1

    xray api

    调用 Xray 的 gRPC API,需要在配置文件中开启。

    使用方法:

    xray api <command> [arguments]\n
    1
            restartlogger Restart the logger\n        stats         Get statistics\n        statsquery    Query statistics\n        statssys      Get system statistics\n        adi           Add inbounds\n        ado           Add outbounds\n        rmi           Remove inbounds\n        rmo           Remove outbounds\n
    1
    2
    3
    4
    5
    6
    7
    8

    xray tls

    一些与 TLS 相关的工具。

    使用方法:

    xray tls <command> [arguments]\n
    1
            cert          Generate TLS certificates\n        ping          Ping the domain with TLS handshake\n        certChainHash Calculate TLS certificates hash.\n
    1
    2
    3

    xray uuid

    生成 UUID。

    使用方法:

    xray uuid [-i "example"]\n
    1
    ',29),d={class:"custom-container tip"},o=s("p",{class:"custom-container-title"},"提示",-1),b=s("p",null,[c("当 "),s("code",null,"-config"),c(" 没有指定时,Xray 将先后尝试从以下路径加载 "),s("code",null,"config.json"),c(" :")],-1),m=s("li",null,"工作目录(Working Directory)",-1),g=c("环境变量"),h=c("中 "),x=s("code",null,"Xray.location.asset",-1),v=c(" 所指定的路径");p.render=function(t,c){const p=n("RouterLink");return a(),e(i,null,[u,s("div",d,[o,b,s("ul",null,[m,s("li",null,[r(p,{to:"/config/features/env.html#%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84"},{default:l((()=>[g])),_:1}),h,x,v])])])],64)};export default p; +import{r as n,o as a,c as e,a as s,b as r,w as l,F as i,d as t,e as c}from"./app.48111a85.js";const p={},u=t('

    命令参数

    提示

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

    获取基本命令

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

    Xray is a platform for building proxies.\n\nUsage:\n\n        xray <command> [arguments]\n\nThe commands are:\n\n        run          Run Xray with config, the default command\n        version      Show current version of Xray\n        api          Call an API in an Xray process\n        tls          TLS tools\n        uuid         Generate new UUIDs\n\nUse "xray help <command>" for more information about a command.\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    xray run

    指定一个或多个配置文件,并运行。

    使用方法:

     xray run [-c config.json] [-confdir dir]\n
    1
    Run Xray with config, the default command.\n\nThe -config=file, -c=file flags set the config files for\nXray. Multiple assign is accepted.\n\nThe -confdir=dir flag sets a dir with multiple json config\n\nThe -format=json flag sets the format of config files.\nDefault "auto".\n\nThe -test flag tells Xray to test config files only,\nwithout launching the server\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    提示

    配置文件除了默认的 JSON 格式外,也可以使用 TOML 和 YAML。在不指定格式的前提下会通过文件扩展名识别。

    xray version

    输出 Xray 版本、 Golang 版本等信息。

    使用方法:

     xray version\n
    1

    xray api

    调用 Xray 的 gRPC API,需要在配置文件中开启。

    使用方法:

    xray api <command> [arguments]\n
    1
            restartlogger Restart the logger\n        stats         Get statistics\n        statsquery    Query statistics\n        statssys      Get system statistics\n        adi           Add inbounds\n        ado           Add outbounds\n        rmi           Remove inbounds\n        rmo           Remove outbounds\n
    1
    2
    3
    4
    5
    6
    7
    8

    xray tls

    一些与 TLS 相关的工具。

    使用方法:

    xray tls <command> [arguments]\n
    1
            cert          Generate TLS certificates\n        ping          Ping the domain with TLS handshake\n        certChainHash Calculate TLS certificates hash.\n
    1
    2
    3

    xray uuid

    生成 UUID。

    使用方法:

    xray uuid [-i "example"]\n
    1
    ',29),d={class:"custom-container tip"},o=s("p",{class:"custom-container-title"},"提示",-1),b=s("p",null,[c("当 "),s("code",null,"-config"),c(" 没有指定时,Xray 将先后尝试从以下路径加载 "),s("code",null,"config.json"),c(" :")],-1),m=s("li",null,"工作目录(Working Directory)",-1),g=c("环境变量"),h=c("中 "),x=s("code",null,"Xray.location.asset",-1),v=c(" 所指定的路径");p.render=function(t,c){const p=n("RouterLink");return a(),e(i,null,[u,s("div",d,[o,b,s("ul",null,[m,s("li",null,[r(p,{to:"/config/features/env.html#%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84"},{default:l((()=>[g])),_:1}),h,x,v])])])],64)};export default p; diff --git a/assets/compile.html.76028011.js b/assets/compile.html.3c9f7ee7.js similarity index 98% rename from assets/compile.html.76028011.js rename to assets/compile.html.3c9f7ee7.js index 1a8262212..4c7a90f4d 100644 --- a/assets/compile.html.76028011.js +++ b/assets/compile.html.3c9f7ee7.js @@ -1 +1 @@ -import{r as a,o as s,c as n,a as e,b as o,F as l,e as r,d as p}from"./app.755d843f.js";const t={},i=e("h1",{id:"编译文档",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#编译文档","aria-hidden":"true"},"#"),r(" 编译文档")],-1),c=e("h2",{id:"前序工作",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#前序工作","aria-hidden":"true"},"#"),r(" 前序工作")],-1),d=r("Xray 使用 "),u={href:"https://golang.org/",target:"_blank",rel:"noopener noreferrer"},h=r("Golang"),b=r(" 作为编程语言,你需要先安装最新版本 Golang 才能够编译。"),g={class:"custom-container tip"},m=e("p",{class:"custom-container-title"},"TIP",-1),v=r("安装 Golang: "),k={href:"https://golang.org/doc/install",target:"_blank",rel:"noopener noreferrer"},x=r("golang.org/doc/install"),w=p('

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

    拉取 Xray 源代码

    git clone https://github.com/XTLS/Xray-core.git\ncd Xray-core && go mod download\n
    1
    2

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

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

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

    构建二进制

    注意

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

    Windows(Powershell):

    $env:CGO_ENABLED=0\ngo build -o xray.exe -trimpath -ldflags "-s -w -buildid=" ./main\n
    1
    2

    macOS, Linux:

    CGO_ENABLED=0 go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main\n
    1

    运行以上命令会在目录下生成 xray 可执行文件。

    提示

    如果需要编译可以进行 debug 的程序,即可以用 dlv 附加到运行的程序进行调试, 请去掉 ldflags 中的 '-w -s' 选项.

    -w 禁止生成 debug 信息。使用该选项后,将无法使用 gdb 进行调试。 -s 禁用符号表 PS:其实用 vscode 或其他 IDE 调试似乎更方便。

    交叉编译:

    这里以在 Windows(Powershell) 环境中,编译到 Linux 服务器为例:

    $env:CGO_ENABLED=0\n$env:GOOS="linux"\n$env:GOARCH="amd64"\n\ngo build -o xray -trimpath -ldflags "-s -w -buildid=" ./main\n
    1
    2
    3
    4
    5

    上传到服务器后,记得在服务器终端内执行 chmod +x xray

    提示

    执行 go tool dist list 查看所有支持的系统与架构。

    可复现构建:

    按照上述步骤,能够编译与 Release 中完全相同的二进制文件。

    注意

    请先确认您使用的 Golang 版本与编译 Release 的一致。

    ',22);t.render=function(r,p){const t=a("OutboundLink");return s(),n(l,null,[i,c,e("p",null,[d,e("a",u,[h,o(t)]),b]),e("div",g,[m,e("p",null,[v,e("a",k,[x,o(t)])])]),w],64)};export default t; +import{r as a,o as s,c as n,a as e,b as o,F as l,e as r,d as p}from"./app.48111a85.js";const t={},i=e("h1",{id:"编译文档",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#编译文档","aria-hidden":"true"},"#"),r(" 编译文档")],-1),c=e("h2",{id:"前序工作",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#前序工作","aria-hidden":"true"},"#"),r(" 前序工作")],-1),d=r("Xray 使用 "),u={href:"https://golang.org/",target:"_blank",rel:"noopener noreferrer"},h=r("Golang"),b=r(" 作为编程语言,你需要先安装最新版本 Golang 才能够编译。"),g={class:"custom-container tip"},m=e("p",{class:"custom-container-title"},"TIP",-1),v=r("安装 Golang: "),k={href:"https://golang.org/doc/install",target:"_blank",rel:"noopener noreferrer"},x=r("golang.org/doc/install"),w=p('

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

    拉取 Xray 源代码

    git clone https://github.com/XTLS/Xray-core.git\ncd Xray-core && go mod download\n
    1
    2

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

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

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

    构建二进制

    注意

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

    Windows(Powershell):

    $env:CGO_ENABLED=0\ngo build -o xray.exe -trimpath -ldflags "-s -w -buildid=" ./main\n
    1
    2

    macOS, Linux:

    CGO_ENABLED=0 go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main\n
    1

    运行以上命令会在目录下生成 xray 可执行文件。

    提示

    如果需要编译可以进行 debug 的程序,即可以用 dlv 附加到运行的程序进行调试, 请去掉 ldflags 中的 '-w -s' 选项.

    -w 禁止生成 debug 信息。使用该选项后,将无法使用 gdb 进行调试。 -s 禁用符号表 PS:其实用 vscode 或其他 IDE 调试似乎更方便。

    交叉编译:

    这里以在 Windows(Powershell) 环境中,编译到 Linux 服务器为例:

    $env:CGO_ENABLED=0\n$env:GOOS="linux"\n$env:GOARCH="amd64"\n\ngo build -o xray -trimpath -ldflags "-s -w -buildid=" ./main\n
    1
    2
    3
    4
    5

    上传到服务器后,记得在服务器终端内执行 chmod +x xray

    提示

    执行 go tool dist list 查看所有支持的系统与架构。

    可复现构建:

    按照上述步骤,能够编译与 Release 中完全相同的二进制文件。

    注意

    请先确认您使用的 Golang 版本与编译 Release 的一致。

    ',22);t.render=function(r,p){const t=a("OutboundLink");return s(),n(l,null,[i,c,e("p",null,[d,e("a",u,[h,o(t)]),b]),e("div",g,[m,e("p",null,[v,e("a",k,[x,o(t)])])]),w],64)};export default t; diff --git a/assets/compile.html.5b8928f4.js b/assets/compile.html.64f2baf9.js similarity index 98% rename from assets/compile.html.5b8928f4.js rename to assets/compile.html.64f2baf9.js index 665384e48..4519d4982 100644 --- a/assets/compile.html.5b8928f4.js +++ b/assets/compile.html.64f2baf9.js @@ -1 +1 @@ -import{r as e,o as a,c as s,a as n,b as o,F as r,e as i,d as l}from"./app.755d843f.js";const t={},p=n("h1",{id:"compile-the-document",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#compile-the-document","aria-hidden":"true"},"#"),i(" Compile the document")],-1),c=n("h2",{id:"preparatory-work",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#preparatory-work","aria-hidden":"true"},"#"),i(" Preparatory Work")],-1),d=i("Xray uses "),u={href:"https://golang.org/",target:"_blank",rel:"noopener noreferrer"},h=i("Golang"),b=i(" as its programming language, so you need to install the latest version of Golang first in order to compile."),m={class:"custom-container tip"},g=n("p",{class:"custom-container-title"},"TIP",-1),v=i("Install Golang: "),f={href:"https://golang.org/doc/install",target:"_blank",rel:"noopener noreferrer"},w=i("golang.org/doc/install"),y=l('

    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\ncd Xray-core && go mod download\n
    1
    2

    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\n
    1

    Build Binary

    Warning

    This command needs to be executed within Xray root directory.

    Windows(Powershell):

    $env:CGO_ENABLED=0\ngo build -o xray.exe -trimpath -ldflags "-s -w -buildid=" ./main\n
    1
    2

    macOS, Linux:

    CGO_ENABLED=0 go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main\n
    1

    Running the above command will generate an xray executable file in the directory.

    Tip

    If you need to compile a program that can be debugged, i.e., you can use dlv to attach to the running program for debugging, please remove the '-w -s' options from the ldflags.

    • w option disables the generation of debug information. After using this option, gdb cannot be used for debugging.
    • s option disables the symbol table. PS: Actually, debugging with vscode or other IDEs seems to be more convenient.

    Cross compilation:

    Here, we take the example of compiling to a Linux server in a Windows (Powershell) environment:

    $env:CGO_ENABLED=0\n$env:GOOS="linux"\n$env:GOARCH="amd64"\n
    1
    2
    3

    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.

    ',17);t.render=function(i,l){const t=e("OutboundLink");return a(),s(r,null,[p,c,n("p",null,[d,n("a",u,[h,o(t)]),b]),n("div",m,[g,n("p",null,[v,n("a",f,[w,o(t)])])]),y],64)};export default t; +import{r as e,o as a,c as s,a as n,b as o,F as r,e as i,d as l}from"./app.48111a85.js";const t={},p=n("h1",{id:"compile-the-document",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#compile-the-document","aria-hidden":"true"},"#"),i(" Compile the document")],-1),c=n("h2",{id:"preparatory-work",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#preparatory-work","aria-hidden":"true"},"#"),i(" Preparatory Work")],-1),d=i("Xray uses "),u={href:"https://golang.org/",target:"_blank",rel:"noopener noreferrer"},h=i("Golang"),b=i(" as its programming language, so you need to install the latest version of Golang first in order to compile."),m={class:"custom-container tip"},g=n("p",{class:"custom-container-title"},"TIP",-1),v=i("Install Golang: "),f={href:"https://golang.org/doc/install",target:"_blank",rel:"noopener noreferrer"},w=i("golang.org/doc/install"),y=l('

    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\ncd Xray-core && go mod download\n
    1
    2

    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\n
    1

    Build Binary

    Warning

    This command needs to be executed within Xray root directory.

    Windows(Powershell):

    $env:CGO_ENABLED=0\ngo build -o xray.exe -trimpath -ldflags "-s -w -buildid=" ./main\n
    1
    2

    macOS, Linux:

    CGO_ENABLED=0 go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main\n
    1

    Running the above command will generate an xray executable file in the directory.

    Tip

    If you need to compile a program that can be debugged, i.e., you can use dlv to attach to the running program for debugging, please remove the '-w -s' options from the ldflags.

    • w option disables the generation of debug information. After using this option, gdb cannot be used for debugging.
    • s option disables the symbol table. PS: Actually, debugging with vscode or other IDEs seems to be more convenient.

    Cross compilation:

    Here, we take the example of compiling to a Linux server in a Windows (Powershell) environment:

    $env:CGO_ENABLED=0\n$env:GOOS="linux"\n$env:GOARCH="amd64"\n
    1
    2
    3

    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.

    ',17);t.render=function(i,l){const t=e("OutboundLink");return a(),s(r,null,[p,c,n("p",null,[d,n("a",u,[h,o(t)]),b]),n("div",m,[g,n("p",null,[v,n("a",f,[w,o(t)])])]),y],64)};export default t; diff --git a/assets/config.html.bff40b62.js b/assets/config.html.49585339.js similarity index 99% rename from assets/config.html.bff40b62.js rename to assets/config.html.49585339.js index 48f5562a8..129a9a00f 100644 --- a/assets/config.html.bff40b62.js +++ b/assets/config.html.49585339.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as t,w as o,F as e,e as r,d as l}from"./app.755d843f.js";const c={},u=p("h1",{id:"配置运行",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#配置运行","aria-hidden":"true"},"#"),r(" 配置运行")],-1),i=p("p",null,[p("a",{href:"./install"},"下载并安装"),r(" 了 Xray 之后,您需要对它进行一下配置。")],-1),b=r("为了演示,这里只介绍简单的配置方式。更多的模板: "),k={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},m=r("Xray-examples"),q=r("如需配置更复杂的功能,请参考更详细的 "),d=r("配置文件"),y=r(" 中相关说明。"),g=l('

    服务端配置

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

    {\n  "inbounds": [\n    {\n      "port": 10086, // 服务器监听端口\n      "protocol": "vmess",\n      "settings": {\n        "clients": [\n          {\n            "id": "b831381d-6324-4d53-ad4f-8cda48b30811"\n          }\n        ]\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "freedom"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    服务器的配置中需要确保 id 和端口与客户端一致,就可以正常连接了。

    客户端配置

    在你的 PC(或手机)中,需要用以下配置运行 Xray :

    {\n  "inbounds": [\n    {\n      "port": 1080, // SOCKS 代理端口,在浏览器中需配置代理并指向这个端口\n      "listen": "127.0.0.1",\n      "protocol": "socks",\n      "settings": {\n        "udp": true\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "vmess",\n      "settings": {\n        "vnext": [\n          {\n            "address": "server", // 服务器地址,请修改为你自己的服务器 ip 或域名\n            "port": 10086, // 服务器端口\n            "users": [\n              {\n                "id": "b831381d-6324-4d53-ad4f-8cda48b30811"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    {\n      "protocol": "freedom",\n      "tag": "direct"\n    }\n  ],\n  "routing": {\n    "domainStrategy": "IPOnDemand",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["geoip:private"],\n        "outboundTag": "direct"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

    上述配置唯一要更改的地方是你的服务器 IP,配置中已注明。上述配置会把除局域网(比如访问路由器)以外的所有流量转发至你的服务器。

    运行

    • 在 Windows 和 macOS 中,配置文件通常是 Xray 同目录下的 config.json 文件。
      • 直接运行 XrayXray.exe 即可。
    • 在 Linux 中,配置文件通常位于 /etc/xray//usr/local/etc/xray/ 目录下。
      • 运行 xray run -c /etc/xray/config.json
      • 或使用 systemd 等工具将 Xray 作为服务在后台运行。
    ',10),h=r("更多详细的说明可以参考 "),f=r("配置文档"),x=r(" 和 "),v=r("小小白话文"),X=r("。");c.render=function(r,l){const c=n("OutboundLink"),j=n("RouterLink");return s(),a(e,null,[u,i,p("p",null,[b,p("a",k,[m,t(c)])]),p("p",null,[q,t(j,{to:"/config/"},{default:o((()=>[d])),_:1}),y]),g,p("p",null,[h,t(j,{to:"/config/"},{default:o((()=>[f])),_:1}),x,t(j,{to:"/document/level-0/"},{default:o((()=>[v])),_:1}),X])],64)};export default c; +import{r as n,o as s,c as a,a as p,b as t,w as o,F as e,e as r,d as l}from"./app.48111a85.js";const c={},u=p("h1",{id:"配置运行",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#配置运行","aria-hidden":"true"},"#"),r(" 配置运行")],-1),i=p("p",null,[p("a",{href:"./install"},"下载并安装"),r(" 了 Xray 之后,您需要对它进行一下配置。")],-1),b=r("为了演示,这里只介绍简单的配置方式。更多的模板: "),k={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},m=r("Xray-examples"),q=r("如需配置更复杂的功能,请参考更详细的 "),d=r("配置文件"),y=r(" 中相关说明。"),g=l('

    服务端配置

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

    {\n  "inbounds": [\n    {\n      "port": 10086, // 服务器监听端口\n      "protocol": "vmess",\n      "settings": {\n        "clients": [\n          {\n            "id": "b831381d-6324-4d53-ad4f-8cda48b30811"\n          }\n        ]\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "freedom"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    服务器的配置中需要确保 id 和端口与客户端一致,就可以正常连接了。

    客户端配置

    在你的 PC(或手机)中,需要用以下配置运行 Xray :

    {\n  "inbounds": [\n    {\n      "port": 1080, // SOCKS 代理端口,在浏览器中需配置代理并指向这个端口\n      "listen": "127.0.0.1",\n      "protocol": "socks",\n      "settings": {\n        "udp": true\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "vmess",\n      "settings": {\n        "vnext": [\n          {\n            "address": "server", // 服务器地址,请修改为你自己的服务器 ip 或域名\n            "port": 10086, // 服务器端口\n            "users": [\n              {\n                "id": "b831381d-6324-4d53-ad4f-8cda48b30811"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    {\n      "protocol": "freedom",\n      "tag": "direct"\n    }\n  ],\n  "routing": {\n    "domainStrategy": "IPOnDemand",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["geoip:private"],\n        "outboundTag": "direct"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

    上述配置唯一要更改的地方是你的服务器 IP,配置中已注明。上述配置会把除局域网(比如访问路由器)以外的所有流量转发至你的服务器。

    运行

    • 在 Windows 和 macOS 中,配置文件通常是 Xray 同目录下的 config.json 文件。
      • 直接运行 XrayXray.exe 即可。
    • 在 Linux 中,配置文件通常位于 /etc/xray//usr/local/etc/xray/ 目录下。
      • 运行 xray run -c /etc/xray/config.json
      • 或使用 systemd 等工具将 Xray 作为服务在后台运行。
    ',10),h=r("更多详细的说明可以参考 "),f=r("配置文档"),x=r(" 和 "),v=r("小小白话文"),X=r("。");c.render=function(r,l){const c=n("OutboundLink"),j=n("RouterLink");return s(),a(e,null,[u,i,p("p",null,[b,p("a",k,[m,t(c)])]),p("p",null,[q,t(j,{to:"/config/"},{default:o((()=>[d])),_:1}),y]),g,p("p",null,[h,t(j,{to:"/config/"},{default:o((()=>[f])),_:1}),x,t(j,{to:"/document/level-0/"},{default:o((()=>[v])),_:1}),X])],64)};export default c; diff --git a/assets/config.html.647c6656.js b/assets/config.html.a0df4771.js similarity index 99% rename from assets/config.html.647c6656.js rename to assets/config.html.a0df4771.js index 5ce1ce6fc..30ae65862 100644 --- a/assets/config.html.647c6656.js +++ b/assets/config.html.a0df4771.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as t,w as e,F as o,e as r,d as u}from"./app.755d843f.js";const l={},c=p("h1",{id:"configure-and-run",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#configure-and-run","aria-hidden":"true"},"#"),r(" Configure and Run")],-1),i=r("After "),b=r("downloading and installing Xray"),k=r(", you need to configure it."),d=r("For demonstration purposes, only a simple configuration method is introduced here. For more templates, please refer to "),m={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},q=r("Xray-examples"),y=r("."),g=r("If you need to set up more advanced features, please refer to the relevant instructions in the more detailed "),f=r("configuration file"),h=r("."),v=u('

    Server Configuration

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

    {\n  "inbounds": [\n    {\n      "port": 10086, // The port on which the server is listening\n      "protocol": "vmess",\n      "settings": {\n        "clients": [\n          {\n            "id": "b831381d-6324-4d53-ad4f-8cda48b30811"\n          }\n        ]\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "freedom"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    In server configuration, it is necessary to ensure that the id and port are consistent with the client in order to establish a normal connection.

    Client Configuration

    On your PC (or phone), you need to run Xray with the following configuration:

    {\n  "inbounds": [\n    {\n      "port": 1080, // SOCKS代理端口,需要在浏览器中配置代理并指向该端口\n      "listen": "127.0.0.1",\n      "protocol": "socks",\n      "settings": {\n        "udp": true\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "vmess",\n      "settings": {\n        "vnext": [\n          {\n            "address": "server", // 服务器地址,请将其更改为您自己的服务器IP或域名\n            "port": 10086, // 服务器端口\n            "users": [\n              {\n                "id": "b831381d-6324-4d53-ad4f-8cda48b30811"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    {\n      "protocol": "freedom",\n      "tag": "direct"\n    }\n  ],\n  "routing": {\n    "domainStrategy": "IPOnDemand",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["geoip:private"],\n        "outboundTag": "direct"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

    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.
    ',10),x=r("For more detailed instructions, please refer to the "),w=r("Configuration"),X=r(" Document and "),j=r("Layman's Terms"),T=r(".");l.render=function(r,u){const l=n("RouterLink"),C=n("OutboundLink");return s(),a(o,null,[c,p("p",null,[i,t(l,{to:"/en/document/install/"},{default:e((()=>[b])),_:1}),k]),p("p",null,[d,p("a",m,[q,t(C)]),y]),p("p",null,[g,t(l,{to:"/en/config/"},{default:e((()=>[f])),_:1}),h]),v,p("p",null,[x,t(l,{to:"/en/config/"},{default:e((()=>[w])),_:1}),X,t(l,{to:"/en/document/level-0/"},{default:e((()=>[j])),_:1}),T])],64)};export default l; +import{r as n,o as s,c as a,a as p,b as t,w as e,F as o,e as r,d as u}from"./app.48111a85.js";const l={},c=p("h1",{id:"configure-and-run",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#configure-and-run","aria-hidden":"true"},"#"),r(" Configure and Run")],-1),i=r("After "),b=r("downloading and installing Xray"),k=r(", you need to configure it."),d=r("For demonstration purposes, only a simple configuration method is introduced here. For more templates, please refer to "),m={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},q=r("Xray-examples"),y=r("."),g=r("If you need to set up more advanced features, please refer to the relevant instructions in the more detailed "),f=r("configuration file"),h=r("."),v=u('

    Server Configuration

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

    {\n  "inbounds": [\n    {\n      "port": 10086, // The port on which the server is listening\n      "protocol": "vmess",\n      "settings": {\n        "clients": [\n          {\n            "id": "b831381d-6324-4d53-ad4f-8cda48b30811"\n          }\n        ]\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "freedom"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

    In server configuration, it is necessary to ensure that the id and port are consistent with the client in order to establish a normal connection.

    Client Configuration

    On your PC (or phone), you need to run Xray with the following configuration:

    {\n  "inbounds": [\n    {\n      "port": 1080, // SOCKS代理端口,需要在浏览器中配置代理并指向该端口\n      "listen": "127.0.0.1",\n      "protocol": "socks",\n      "settings": {\n        "udp": true\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "vmess",\n      "settings": {\n        "vnext": [\n          {\n            "address": "server", // 服务器地址,请将其更改为您自己的服务器IP或域名\n            "port": 10086, // 服务器端口\n            "users": [\n              {\n                "id": "b831381d-6324-4d53-ad4f-8cda48b30811"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    {\n      "protocol": "freedom",\n      "tag": "direct"\n    }\n  ],\n  "routing": {\n    "domainStrategy": "IPOnDemand",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["geoip:private"],\n        "outboundTag": "direct"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

    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.
    ',10),x=r("For more detailed instructions, please refer to the "),w=r("Configuration"),X=r(" Document and "),j=r("Layman's Terms"),T=r(".");l.render=function(r,u){const l=n("RouterLink"),C=n("OutboundLink");return s(),a(o,null,[c,p("p",null,[i,t(l,{to:"/en/document/install/"},{default:e((()=>[b])),_:1}),k]),p("p",null,[d,p("a",m,[q,t(C)]),y]),p("p",null,[g,t(l,{to:"/en/config/"},{default:e((()=>[f])),_:1}),h]),v,p("p",null,[x,t(l,{to:"/en/config/"},{default:e((()=>[w])),_:1}),X,t(l,{to:"/en/document/level-0/"},{default:e((()=>[j])),_:1}),T])],64)};export default l; diff --git a/assets/createText-2f679d62.584f3edd.js b/assets/createText-2f679d62.a374f608.js similarity index 99% rename from assets/createText-2f679d62.584f3edd.js rename to assets/createText-2f679d62.a374f608.js index c47d65b8f..2590e9a97 100644 --- a/assets/createText-2f679d62.584f3edd.js +++ b/assets/createText-2f679d62.a374f608.js @@ -1 +1 @@ -import{l as e,a4 as t,a6 as n}from"./mermaid.core.a66200b0.js";const r={};function i(e,t,n){if(function(e){return Boolean(e&&"object"==typeof e)}(e)){if("value"in e)return"html"!==e.type||n?e.value:"";if(t&&"alt"in e&&e.alt)return e.alt;if("children"in e)return u(e.children,t,n)}return Array.isArray(e)?u(e,t,n):""}function u(e,t,n){const r=[];let u=-1;for(;++ui?0:i+t:t>i?i:t,n=n>0?n:0,r.length<1e4)u=Array.from(r),u.unshift(t,n),[].splice.apply(e,u);else for(n&&[].splice.apply(e,[t,n]);o0?(o(e,e.length,0,t),e):t}const s={}.hasOwnProperty;function l(e,t){let n;for(n in t){const r=(s.call(e,n)?e[n]:void 0)||(e[n]={}),i=t[n];let u;for(u in i){s.call(r,u)||(r[u]=[]);const e=i[u];a(r[u],Array.isArray(e)?e:e?[e]:[])}}}function a(e,t){let n=-1;const r=[];for(;++nu))return;const n=t.events.length;let i,s,l=n;for(;l--;)if("exit"===t.events[l][0]&&"chunkFlow"===t.events[l][1].type){if(i){s=t.events[l][1].end;break}i=!0}for(k(c),e=n;er;){const r=n[i];t.containerState=r[1],r[0].exit.call(t,e)}n.length=r}function F(){r.write([null]),i=void 0,r=void 0,t.containerState._closeFlow=void 0}}},w={tokenize:function(e,t,n){return E(e,e.attempt(this.parser.constructs.document,t,n),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}};function C(e){return null===e||k(e)||b(e)?1:v(e)?2:void 0}function T(e,t,n){const r=[];let i=-1;for(;++i1&&e[d][1].end.offset-e[d][1].start.offset>1?2:1;const h=Object.assign({},e[n][1].end),p=Object.assign({},e[d][1].start);B(h,-l),B(p,l),u={type:l>1?"strongSequence":"emphasisSequence",start:h,end:Object.assign({},e[n][1].end)},s={type:l>1?"strongSequence":"emphasisSequence",start:Object.assign({},e[d][1].start),end:p},i={type:l>1?"strongText":"emphasisText",start:Object.assign({},e[n][1].end),end:Object.assign({},e[d][1].start)},r={type:l>1?"strong":"emphasis",start:Object.assign({},u.start),end:Object.assign({},s.end)},e[n][1].end=Object.assign({},u.start),e[d][1].start=Object.assign({},s.end),a=[],e[n][1].end.offset-e[n][1].start.offset&&(a=c(a,[["enter",e[n][1],t],["exit",e[n][1],t]])),a=c(a,[["enter",r,t],["enter",u,t],["exit",u,t],["enter",i,t]]),a=c(a,T(t.parser.constructs.insideSpan.null,e.slice(n+1,d),t)),a=c(a,[["exit",i,t],["enter",s,t],["exit",s,t],["exit",r,t]]),e[d][1].end.offset-e[d][1].start.offset?(f=2,a=c(a,[["enter",e[d][1],t],["exit",e[d][1],t]])):f=0,o(e,n-1,d-n+3,a),d=n+a.length-f-2;break}d=-1;for(;++d=4?u(e):n(e)}function u(t){return null===t?c(t):y(t)?e.attempt(q,u,c)(t):(e.enter("codeFlowValue"),o(t))}function o(t){return null===t||y(t)?(e.exit("codeFlowValue"),u(t)):(e.consume(t),o)}function c(n){return e.exit("codeIndented"),t(n)}}},q={tokenize:function(e,t,n){const r=this;return i;function i(t){return r.parser.lazy[r.now().line]?n(t):y(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),i):E(e,u,"linePrefix",5)(t)}function u(e){const u=r.events[r.events.length-1];return u&&"linePrefix"===u[1].type&&u[2].sliceSerialize(u[1],!0).length>=4?t(e):y(e)?i(e):n(e)}},partial:!0};const V={name:"codeText",tokenize:function(e,t,n){let r,i,u=0;return function(t){return e.enter("codeText"),e.enter("codeTextSequence"),o(t)};function o(t){return 96===t?(e.consume(t),u++,o):(e.exit("codeTextSequence"),c(t))}function c(t){return null===t?n(t):96===t?(i=e.enter("codeTextSequence"),r=0,l(t)):32===t?(e.enter("space"),e.consume(t),e.exit("space"),c):y(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),c):(e.enter("codeTextData"),s(t))}function s(t){return null===t||32===t||96===t||y(t)?(e.exit("codeTextData"),c(t)):(e.consume(t),s)}function l(n){return 96===n?(e.consume(n),r++,l):r===u?(e.exit("codeTextSequence"),e.exit("codeText"),t(n)):(i.type="codeTextData",s(n))}},resolve:function(e){let t,n,r=e.length-4,i=3;if(!("lineEnding"!==e[i][1].type&&"space"!==e[i][1].type||"lineEnding"!==e[r][1].type&&"space"!==e[r][1].type))for(t=i;++t=4?t(i):e.interrupt(r.parser.constructs.flow,n,t)(i)}},partial:!0};function W(e,t,n,r,i,u,o,c,s){const l=s||Number.POSITIVE_INFINITY;let a=0;return function(t){if(60===t)return e.enter(r),e.enter(i),e.enter(u),e.consume(t),e.exit(u),f;if(null===t||41===t||x(t))return n(t);return e.enter(r),e.enter(o),e.enter(c),e.enter("chunkString",{contentType:"string"}),p(t)};function f(n){return 62===n?(e.enter(u),e.consume(n),e.exit(u),e.exit(i),e.exit(r),t):(e.enter(c),e.enter("chunkString",{contentType:"string"}),d(n))}function d(t){return 62===t?(e.exit("chunkString"),e.exit(c),f(t)):null===t||60===t||y(t)?n(t):(e.consume(t),92===t?h:d)}function h(t){return 60===t||62===t||92===t?(e.consume(t),d):d(t)}function p(i){return 40===i?++a>l?n(i):(e.consume(i),p):41===i?a--?(e.consume(i),p):(e.exit("chunkString"),e.exit(c),e.exit(o),e.exit(r),t(i)):null===i||k(i)?a?n(i):(e.exit("chunkString"),e.exit(c),e.exit(o),e.exit(r),t(i)):x(i)?n(i):(e.consume(i),92===i?m:p)}function m(t){return 40===t||41===t||92===t?(e.consume(t),p):p(t)}}function Z(e,t,n,r,i,u){const o=this;let c,s=0;return function(t){return e.enter(r),e.enter(i),e.consume(t),e.exit(i),e.enter(u),l};function l(f){return null===f||91===f||93===f&&!c||94===f&&!s&&"_hiddenFootnoteSupport"in o.parser.constructs||s>999?n(f):93===f?(e.exit(u),e.enter(i),e.consume(f),e.exit(i),e.exit(r),t):y(f)?(e.enter("lineEnding"),e.consume(f),e.exit("lineEnding"),l):(e.enter("chunkString",{contentType:"string"}),a(f))}function a(t){return null===t||91===t||93===t||y(t)||s++>999?(e.exit("chunkString"),l(t)):(e.consume(t),c=c||!F(t),92===t?f:a)}function f(t){return 91===t||92===t||93===t?(e.consume(t),s++,a):a(t)}}function Y(e,t,n,r,i,u){let o;return function(t){return e.enter(r),e.enter(i),e.consume(t),e.exit(i),o=40===t?41:t,c};function c(n){return n===o?(e.enter(i),e.consume(n),e.exit(i),e.exit(r),t):(e.enter(u),s(n))}function s(t){return t===o?(e.exit(u),c(o)):null===t?n(t):y(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),E(e,s,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),l(t))}function l(t){return t===o||null===t||y(t)?(e.exit("chunkString"),s(t)):(e.consume(t),92===t?a:l)}function a(t){return t===o||92===t?(e.consume(t),l):l(t)}}function G(e,t){let n;return function r(i){if(y(i))return e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),n=!0,r;if(F(i))return E(e,r,n?"linePrefix":"lineSuffix")(i);return t(i)}}function J(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const K={name:"definition",tokenize:function(e,t,n){const r=this;let i;return function(t){return e.enter("definition"),Z.call(r,e,u,n,"definitionLabel","definitionLabelMarker","definitionLabelString")(t)};function u(t){return i=J(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),58===t?(e.enter("definitionMarker"),e.consume(t),e.exit("definitionMarker"),G(e,W(e,e.attempt(X,E(e,o,"whitespace"),E(e,o,"whitespace")),n,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString"))):n(t)}function o(u){return null===u||y(u)?(e.exit("definition"),r.parser.defined.includes(i)||r.parser.defined.push(i),t(u)):n(u)}}},X={tokenize:function(e,t,n){return function(t){return k(t)?G(e,r)(t):n(t)};function r(t){return 34===t||39===t||40===t?Y(e,E(e,i,"whitespace"),n,"definitionTitle","definitionTitleMarker","definitionTitleString")(t):n(t)}function i(e){return null===e||y(e)?t(e):n(e)}},partial:!0};const ee={name:"hardBreakEscape",tokenize:function(e,t,n){return function(t){return e.enter("hardBreakEscape"),e.enter("escapeMarker"),e.consume(t),r};function r(r){return y(r)?(e.exit("escapeMarker"),e.exit("hardBreakEscape"),t(r)):n(r)}}};const te={name:"headingAtx",tokenize:function(e,t,n){const r=this;let i=0;return function(t){return e.enter("atxHeading"),e.enter("atxHeadingSequence"),u(t)};function u(c){return 35===c&&i++<6?(e.consume(c),u):null===c||k(c)?(e.exit("atxHeadingSequence"),r.interrupt?t(c):o(c)):n(c)}function o(n){return 35===n?(e.enter("atxHeadingSequence"),c(n)):null===n||y(n)?(e.exit("atxHeading"),t(n)):F(n)?E(e,o,"whitespace")(n):(e.enter("atxHeadingText"),s(n))}function c(t){return 35===t?(e.consume(t),c):(e.exit("atxHeadingSequence"),o(t))}function s(t){return null===t||35===t||k(t)?(e.exit("atxHeadingText"),o(t)):(e.consume(t),s)}},resolve:function(e,t){let n,r,i=e.length-2,u=3;"whitespace"===e[u][1].type&&(u+=2);i-2>u&&"whitespace"===e[i][1].type&&(i-=2);"atxHeadingSequence"===e[i][1].type&&(u===i-1||i-4>u&&"whitespace"===e[i-2][1].type)&&(i-=u+1===i?2:4);i>u&&(n={type:"atxHeadingText",start:e[u][1].start,end:e[i][1].end},r={type:"chunkText",start:e[u][1].start,end:e[i][1].end,contentType:"text"},o(e,u,i-u+1,[["enter",n,t],["enter",r,t],["exit",r,t],["exit",n,t]]));return e}};const ne=["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","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],re=["pre","script","style","textarea"],ie={name:"htmlFlow",tokenize:function(e,t,n){const r=this;let i,u,o,c,s;return function(t){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(t),l};function l(c){return 33===c?(e.consume(c),a):47===c?(e.consume(c),m):63===c?(e.consume(c),i=3,r.interrupt?t:H):f(c)?(e.consume(c),o=String.fromCharCode(c),u=!0,g):n(c)}function a(u){return 45===u?(e.consume(u),i=2,d):91===u?(e.consume(u),i=5,o="CDATA[",c=0,h):f(u)?(e.consume(u),i=4,r.interrupt?t:H):n(u)}function d(i){return 45===i?(e.consume(i),r.interrupt?t:H):n(i)}function h(i){return i===o.charCodeAt(c++)?(e.consume(i),c===o.length?r.interrupt?t:B:h):n(i)}function m(t){return f(t)?(e.consume(t),o=String.fromCharCode(t),g):n(t)}function g(c){return null===c||47===c||62===c||k(c)?47!==c&&u&&re.includes(o.toLowerCase())?(i=1,r.interrupt?t(c):B(c)):ne.includes(o.toLowerCase())?(i=6,47===c?(e.consume(c),x):r.interrupt?t(c):B(c)):(i=7,r.interrupt&&!r.parser.lazy[r.now().line]?n(c):u?v(c):b(c)):45===c||p(c)?(e.consume(c),o+=String.fromCharCode(c),g):n(c)}function x(i){return 62===i?(e.consume(i),r.interrupt?t:B):n(i)}function b(t){return F(t)?(e.consume(t),b):T(t)}function v(t){return 47===t?(e.consume(t),T):58===t||95===t||f(t)?(e.consume(t),S):F(t)?(e.consume(t),v):T(t)}function S(t){return 45===t||46===t||58===t||95===t||p(t)?(e.consume(t),S):E(t)}function E(t){return 61===t?(e.consume(t),A):F(t)?(e.consume(t),E):v(t)}function A(t){return null===t||60===t||61===t||62===t||96===t?n(t):34===t||39===t?(e.consume(t),s=t,I):F(t)?(e.consume(t),A):(s=null,w(t))}function I(t){return null===t||y(t)?n(t):t===s?(e.consume(t),C):(e.consume(t),I)}function w(t){return null===t||34===t||39===t||60===t||61===t||62===t||96===t||k(t)?E(t):(e.consume(t),w)}function C(e){return 47===e||62===e||F(e)?v(e):n(e)}function T(t){return 62===t?(e.consume(t),z):n(t)}function z(t){return F(t)?(e.consume(t),z):null===t||y(t)?B(t):n(t)}function B(t){return 45===t&&2===i?(e.consume(t),L):60===t&&1===i?(e.consume(t),P):62===t&&4===i?(e.consume(t),R):63===t&&3===i?(e.consume(t),H):93===t&&5===i?(e.consume(t),j):!y(t)||6!==i&&7!==i?null===t||y(t)?D(t):(e.consume(t),B):e.check(ue,R,D)(t)}function D(t){return e.exit("htmlFlowData"),_(t)}function _(t){return null===t?q(t):y(t)?e.attempt({tokenize:M,partial:!0},_,q)(t):(e.enter("htmlFlowData"),B(t))}function M(e,t,n){return function(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),i};function i(e){return r.parser.lazy[r.now().line]?n(e):t(e)}}function L(t){return 45===t?(e.consume(t),H):B(t)}function P(t){return 47===t?(e.consume(t),o="",O):B(t)}function O(t){return 62===t&&re.includes(o.toLowerCase())?(e.consume(t),R):f(t)&&o.length<8?(e.consume(t),o+=String.fromCharCode(t),O):B(t)}function j(t){return 93===t?(e.consume(t),H):B(t)}function H(t){return 62===t?(e.consume(t),R):45===t&&2===i?(e.consume(t),H):B(t)}function R(t){return null===t||y(t)?(e.exit("htmlFlowData"),q(t)):(e.consume(t),R)}function q(n){return e.exit("htmlFlow"),t(n)}},resolveTo:function(e){let t=e.length;for(;t--&&("enter"!==e[t][0]||"htmlFlow"!==e[t][1].type););t>1&&"linePrefix"===e[t-2][1].type&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2));return e},concrete:!0},ue={tokenize:function(e,t,n){return function(r){return e.exit("htmlFlowData"),e.enter("lineEndingBlank"),e.consume(r),e.exit("lineEndingBlank"),e.attempt(_,t,n)}},partial:!0};const oe={name:"htmlText",tokenize:function(e,t,n){const r=this;let i,u,o,c;return function(t){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(t),s};function s(t){return 33===t?(e.consume(t),l):47===t?(e.consume(t),C):63===t?(e.consume(t),I):f(t)?(e.consume(t),B):n(t)}function l(t){return 45===t?(e.consume(t),a):91===t?(e.consume(t),u="CDATA[",o=0,x):f(t)?(e.consume(t),A):n(t)}function a(t){return 45===t?(e.consume(t),d):n(t)}function d(t){return null===t||62===t?n(t):45===t?(e.consume(t),h):m(t)}function h(e){return null===e||62===e?n(e):m(e)}function m(t){return null===t?n(t):45===t?(e.consume(t),g):y(t)?(c=m,H(t)):(e.consume(t),m)}function g(t){return 45===t?(e.consume(t),q):m(t)}function x(t){return t===u.charCodeAt(o++)?(e.consume(t),o===u.length?b:x):n(t)}function b(t){return null===t?n(t):93===t?(e.consume(t),v):y(t)?(c=b,H(t)):(e.consume(t),b)}function v(t){return 93===t?(e.consume(t),S):b(t)}function S(t){return 62===t?q(t):93===t?(e.consume(t),S):b(t)}function A(t){return null===t||62===t?q(t):y(t)?(c=A,H(t)):(e.consume(t),A)}function I(t){return null===t?n(t):63===t?(e.consume(t),w):y(t)?(c=I,H(t)):(e.consume(t),I)}function w(e){return 62===e?q(e):I(e)}function C(t){return f(t)?(e.consume(t),T):n(t)}function T(t){return 45===t||p(t)?(e.consume(t),T):z(t)}function z(t){return y(t)?(c=z,H(t)):F(t)?(e.consume(t),z):q(t)}function B(t){return 45===t||p(t)?(e.consume(t),B):47===t||62===t||k(t)?D(t):n(t)}function D(t){return 47===t?(e.consume(t),q):58===t||95===t||f(t)?(e.consume(t),_):y(t)?(c=D,H(t)):F(t)?(e.consume(t),D):q(t)}function _(t){return 45===t||46===t||58===t||95===t||p(t)?(e.consume(t),_):M(t)}function M(t){return 61===t?(e.consume(t),L):y(t)?(c=M,H(t)):F(t)?(e.consume(t),M):D(t)}function L(t){return null===t||60===t||61===t||62===t||96===t?n(t):34===t||39===t?(e.consume(t),i=t,P):y(t)?(c=L,H(t)):F(t)?(e.consume(t),L):(e.consume(t),i=void 0,j)}function P(t){return t===i?(e.consume(t),O):null===t?n(t):y(t)?(c=P,H(t)):(e.consume(t),P)}function O(e){return 62===e||47===e||k(e)?D(e):n(e)}function j(t){return null===t||34===t||39===t||60===t||61===t||96===t?n(t):62===t||k(t)?D(t):(e.consume(t),j)}function H(t){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),E(e,R,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function R(t){return e.enter("htmlTextData"),c(t)}function q(r){return 62===r?(e.consume(r),e.exit("htmlTextData"),e.exit("htmlText"),t):n(r)}}};const ce={name:"labelEnd",tokenize:function(e,t,n){const r=this;let i,u,o=r.events.length;for(;o--;)if(("labelImage"===r.events[o][1].type||"labelLink"===r.events[o][1].type)&&!r.events[o][1]._balanced){i=r.events[o][1];break}return function(t){if(!i)return n(t);return i._inactive?s(t):(u=r.parser.defined.includes(J(r.sliceSerialize({start:i.end,end:r.now()}))),e.enter("labelEnd"),e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelEnd"),c)};function c(n){return 40===n?e.attempt(se,t,u?t:s)(n):91===n?e.attempt(le,t,u?e.attempt(ae,t,s):s)(n):u?t(n):s(n)}function s(e){return i._balanced=!0,n(e)}},resolveTo:function(e,t){let n,r,i,u,s=e.length,l=0;for(;s--;)if(n=e[s][1],r){if("link"===n.type||"labelLink"===n.type&&n._inactive)break;"enter"===e[s][0]&&"labelLink"===n.type&&(n._inactive=!0)}else if(i){if("enter"===e[s][0]&&("labelImage"===n.type||"labelLink"===n.type)&&!n._balanced&&(r=s,"labelLink"!==n.type)){l=2;break}}else"labelEnd"===n.type&&(i=s);const a={type:"labelLink"===e[r][1].type?"link":"image",start:Object.assign({},e[r][1].start),end:Object.assign({},e[e.length-1][1].end)},f={type:"label",start:Object.assign({},e[r][1].start),end:Object.assign({},e[i][1].end)},d={type:"labelText",start:Object.assign({},e[r+l+2][1].end),end:Object.assign({},e[i-2][1].start)};return u=[["enter",a,t],["enter",f,t]],u=c(u,e.slice(r+1,r+l+3)),u=c(u,[["enter",d,t]]),u=c(u,T(t.parser.constructs.insideSpan.null,e.slice(r+l+4,i-3),t)),u=c(u,[["exit",d,t],e[i-2],e[i-1],["exit",f,t]]),u=c(u,e.slice(i+1)),u=c(u,[["exit",a,t]]),o(e,r,e.length,u),e},resolveAll:function(e){let t,n=-1;for(;++n-1&&(o[0]=o[0].slice(r)),u>0&&o.push(e[i].slice(0,u)));return o}(s,e)}function p(){return Object.assign({},r)}function m(){let e;for(;r._index13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||65535==(65535&n)||65534==(65535&n)||n>1114111?"�":String.fromCharCode(n)}const je=/\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi;function He(e,t,n){if(t)return t;if(35===n.charCodeAt(0)){const e=n.charCodeAt(1),t=120===e||88===e;return Oe(n.slice(t?2:1),t?16:10)}return O(n)||e}function Re(e){return e&&"object"==typeof e?"position"in e||"type"in e?Ve(e.position):"start"in e||"end"in e?Ve(e):"line"in e||"column"in e?qe(e):"":""}function qe(e){return Qe(e&&e.line)+":"+Qe(e&&e.column)}function Ve(e){return qe(e&&e.start)+"-"+qe(e&&e.end)}function Qe(e){return e&&"number"==typeof e?e:1}const Ne={}.hasOwnProperty,Ue=function(e,t,n){return"string"!=typeof t&&(n=t,t=void 0),function(e){const t={transforms:[],canContainEols:["emphasis","fragment","heading","paragraph","strong"],enter:{autolink:l(oe),autolinkProtocol:T,autolinkEmail:T,atxHeading:l(ne),blockQuote:l(G),characterEscape:T,characterReference:T,codeFenced:l(K),codeFencedFenceInfo:a,codeFencedFenceMeta:a,codeIndented:l(K,a),codeText:l(X,a),codeTextData:T,data:T,codeFlowValue:T,definition:l(ee),definitionDestinationString:a,definitionLabelString:a,definitionTitleString:a,emphasis:l(te),hardBreakEscape:l(re),hardBreakTrailing:l(re),htmlFlow:l(ie,a),htmlFlowData:T,htmlText:l(ie,a),htmlTextData:T,image:l(ue),label:a,link:l(oe),listItem:l(se),listItemValue:g,listOrdered:l(ce,m),listUnordered:l(ce),paragraph:l(le),reference:N,referenceString:a,resourceDestinationString:a,resourceTitleString:a,setextHeading:l(ne),strong:l(ae),thematicBreak:l(de)},exit:{atxHeading:d(),atxHeadingSequence:A,autolink:d(),autolinkEmail:Y,autolinkProtocol:Z,blockQuote:d(),characterEscapeValue:z,characterReferenceMarkerHexadecimal:$,characterReferenceMarkerNumeric:$,characterReferenceValue:W,codeFenced:d(F),codeFencedFence:y,codeFencedFenceInfo:x,codeFencedFenceMeta:k,codeFlowValue:z,codeIndented:d(b),codeText:d(L),codeTextData:z,data:z,definition:d(),definitionDestinationString:E,definitionLabelString:v,definitionTitleString:S,emphasis:d(),hardBreakEscape:d(D),hardBreakTrailing:d(D),htmlFlow:d(_),htmlFlowData:z,htmlText:d(M),htmlTextData:z,image:d(j),label:R,labelText:H,lineEnding:B,link:d(P),listItem:d(),listOrdered:d(),listUnordered:d(),paragraph:d(),referenceString:U,resourceDestinationString:q,resourceTitleString:V,resource:Q,setextHeading:d(C),setextHeadingLineSequence:w,setextHeadingText:I,strong:d(),thematicBreak:d()}};We(t,(e||{}).mdastExtensions||[]);const n={};return u;function u(e){let n={type:"root",children:[]};const r={stack:[n],tokenStack:[],config:t,enter:f,exit:h,buffer:a,resume:p,setData:c,getData:s},i=[];let u=-1;for(;++u0){const e=r.tokenStack[r.tokenStack.length-1];(e[1]||Ye).call(r,void 0,e[0])}for(n.position={start:$e(e.length>0?e[0][1].start:{line:1,column:1,offset:0}),end:$e(e.length>0?e[e.length-2][1].end:{line:1,column:1,offset:0})},u=-1;++u{0!==n&&(u++,i.push([])),e.split(" ").forEach((e=>{e&&i[u].push({content:e,type:t})}))}))}else"strong"!==e.type&&"emphasis"!==e.type||e.children.forEach((t=>{o(t,e.type)}))}return r.forEach((e=>{"paragraph"===e.type&&e.children.forEach((e=>{o(e)}))})),i}function Je(e,t,n){return e.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",t*n-.1+"em").attr("dy",n+"em")}function Ke(e,t){e.text(""),t.forEach(((t,n)=>{const r=e.append("tspan").attr("font-style","em"===t.type?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight","strong"===t.type?"bold":"normal");0===n?r.text(t.content):r.text(" "+t.content)}))}const Xe=(n,r="",{style:i="",isTitle:u=!1,classes:o="",useHtmlLabels:c=!0,isNode:s=!0,width:l,addSvgBackground:a=!1}={})=>{if(e.info("createText",r,i,u,o,c,s,a),c){const e=function(e){const{children:t}=Ue(e);return t.map((function e(t){return"text"===t.type?t.value.replace(/\n/g,"
    "):"strong"===t.type?`${t.children.map(e).join("")}`:"emphasis"===t.type?`${t.children.map(e).join("")}`:"paragraph"===t.type?`

    ${t.children.map(e).join("")}

    `:`Unsupported markdown: ${t.type}`})).join("")}(r);return function(e,t,n,r,i=!1){const u=e.append("foreignObject"),o=u.append("xhtml:div"),c=t.label,s=t.isNode?"nodeLabel":"edgeLabel";var l,a;o.html(`\n "+c+""),l=o,(a=t.labelStyle)&&l.attr("style",a),o.style("display","table-cell"),o.style("white-space","nowrap"),o.style("max-width",n+"px"),o.attr("xmlns","http://www.w3.org/1999/xhtml"),i&&o.attr("class","labelBkg");let f=o.node().getBoundingClientRect();return f.width===n&&(o.style("display","table"),o.style("white-space","break-spaces"),o.style("width",n+"px"),f=o.node().getBoundingClientRect()),u.style("width",f.width),u.style("height",f.height),u.node()}(n,{isNode:s,label:t(e).replace(/fa[blrs]?:fa-[\w-]+/g,(e=>``)),labelStyle:i.replace("fill:","color:")},l,o,a)}return function(e,t,n,r=!1){const i=t.append("g");let u=i.insert("rect").attr("class","background");const o=i.append("text").attr("y","-10.1");let c=-1;if(n.forEach((t=>{c++;let n,r=Je(o,c,1.1),i=[...t].reverse(),u=[];for(;i.length;)n=i.pop(),u.push(n),Ke(r,u),r.node().getComputedTextLength()>e&&(u.pop(),i.push(n),Ke(r,u),u=[],c++,r=Je(o,c,1.1))})),r){const e=o.node().getBBox(),t=2;return u.attr("x",-t).attr("y",-t).attr("width",e.width+2*t).attr("height",e.height+2*t),i.node()}return o.node()}(l,n,Ge(r),a)};export{Xe as c}; +import{l as e,a4 as t,a6 as n}from"./mermaid.core.3a590193.js";const r={};function i(e,t,n){if(function(e){return Boolean(e&&"object"==typeof e)}(e)){if("value"in e)return"html"!==e.type||n?e.value:"";if(t&&"alt"in e&&e.alt)return e.alt;if("children"in e)return u(e.children,t,n)}return Array.isArray(e)?u(e,t,n):""}function u(e,t,n){const r=[];let u=-1;for(;++ui?0:i+t:t>i?i:t,n=n>0?n:0,r.length<1e4)u=Array.from(r),u.unshift(t,n),[].splice.apply(e,u);else for(n&&[].splice.apply(e,[t,n]);o0?(o(e,e.length,0,t),e):t}const s={}.hasOwnProperty;function l(e,t){let n;for(n in t){const r=(s.call(e,n)?e[n]:void 0)||(e[n]={}),i=t[n];let u;for(u in i){s.call(r,u)||(r[u]=[]);const e=i[u];a(r[u],Array.isArray(e)?e:e?[e]:[])}}}function a(e,t){let n=-1;const r=[];for(;++nu))return;const n=t.events.length;let i,s,l=n;for(;l--;)if("exit"===t.events[l][0]&&"chunkFlow"===t.events[l][1].type){if(i){s=t.events[l][1].end;break}i=!0}for(k(c),e=n;er;){const r=n[i];t.containerState=r[1],r[0].exit.call(t,e)}n.length=r}function F(){r.write([null]),i=void 0,r=void 0,t.containerState._closeFlow=void 0}}},w={tokenize:function(e,t,n){return E(e,e.attempt(this.parser.constructs.document,t,n),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}};function C(e){return null===e||k(e)||b(e)?1:v(e)?2:void 0}function T(e,t,n){const r=[];let i=-1;for(;++i1&&e[d][1].end.offset-e[d][1].start.offset>1?2:1;const h=Object.assign({},e[n][1].end),p=Object.assign({},e[d][1].start);B(h,-l),B(p,l),u={type:l>1?"strongSequence":"emphasisSequence",start:h,end:Object.assign({},e[n][1].end)},s={type:l>1?"strongSequence":"emphasisSequence",start:Object.assign({},e[d][1].start),end:p},i={type:l>1?"strongText":"emphasisText",start:Object.assign({},e[n][1].end),end:Object.assign({},e[d][1].start)},r={type:l>1?"strong":"emphasis",start:Object.assign({},u.start),end:Object.assign({},s.end)},e[n][1].end=Object.assign({},u.start),e[d][1].start=Object.assign({},s.end),a=[],e[n][1].end.offset-e[n][1].start.offset&&(a=c(a,[["enter",e[n][1],t],["exit",e[n][1],t]])),a=c(a,[["enter",r,t],["enter",u,t],["exit",u,t],["enter",i,t]]),a=c(a,T(t.parser.constructs.insideSpan.null,e.slice(n+1,d),t)),a=c(a,[["exit",i,t],["enter",s,t],["exit",s,t],["exit",r,t]]),e[d][1].end.offset-e[d][1].start.offset?(f=2,a=c(a,[["enter",e[d][1],t],["exit",e[d][1],t]])):f=0,o(e,n-1,d-n+3,a),d=n+a.length-f-2;break}d=-1;for(;++d=4?u(e):n(e)}function u(t){return null===t?c(t):y(t)?e.attempt(q,u,c)(t):(e.enter("codeFlowValue"),o(t))}function o(t){return null===t||y(t)?(e.exit("codeFlowValue"),u(t)):(e.consume(t),o)}function c(n){return e.exit("codeIndented"),t(n)}}},q={tokenize:function(e,t,n){const r=this;return i;function i(t){return r.parser.lazy[r.now().line]?n(t):y(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),i):E(e,u,"linePrefix",5)(t)}function u(e){const u=r.events[r.events.length-1];return u&&"linePrefix"===u[1].type&&u[2].sliceSerialize(u[1],!0).length>=4?t(e):y(e)?i(e):n(e)}},partial:!0};const V={name:"codeText",tokenize:function(e,t,n){let r,i,u=0;return function(t){return e.enter("codeText"),e.enter("codeTextSequence"),o(t)};function o(t){return 96===t?(e.consume(t),u++,o):(e.exit("codeTextSequence"),c(t))}function c(t){return null===t?n(t):96===t?(i=e.enter("codeTextSequence"),r=0,l(t)):32===t?(e.enter("space"),e.consume(t),e.exit("space"),c):y(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),c):(e.enter("codeTextData"),s(t))}function s(t){return null===t||32===t||96===t||y(t)?(e.exit("codeTextData"),c(t)):(e.consume(t),s)}function l(n){return 96===n?(e.consume(n),r++,l):r===u?(e.exit("codeTextSequence"),e.exit("codeText"),t(n)):(i.type="codeTextData",s(n))}},resolve:function(e){let t,n,r=e.length-4,i=3;if(!("lineEnding"!==e[i][1].type&&"space"!==e[i][1].type||"lineEnding"!==e[r][1].type&&"space"!==e[r][1].type))for(t=i;++t=4?t(i):e.interrupt(r.parser.constructs.flow,n,t)(i)}},partial:!0};function W(e,t,n,r,i,u,o,c,s){const l=s||Number.POSITIVE_INFINITY;let a=0;return function(t){if(60===t)return e.enter(r),e.enter(i),e.enter(u),e.consume(t),e.exit(u),f;if(null===t||41===t||x(t))return n(t);return e.enter(r),e.enter(o),e.enter(c),e.enter("chunkString",{contentType:"string"}),p(t)};function f(n){return 62===n?(e.enter(u),e.consume(n),e.exit(u),e.exit(i),e.exit(r),t):(e.enter(c),e.enter("chunkString",{contentType:"string"}),d(n))}function d(t){return 62===t?(e.exit("chunkString"),e.exit(c),f(t)):null===t||60===t||y(t)?n(t):(e.consume(t),92===t?h:d)}function h(t){return 60===t||62===t||92===t?(e.consume(t),d):d(t)}function p(i){return 40===i?++a>l?n(i):(e.consume(i),p):41===i?a--?(e.consume(i),p):(e.exit("chunkString"),e.exit(c),e.exit(o),e.exit(r),t(i)):null===i||k(i)?a?n(i):(e.exit("chunkString"),e.exit(c),e.exit(o),e.exit(r),t(i)):x(i)?n(i):(e.consume(i),92===i?m:p)}function m(t){return 40===t||41===t||92===t?(e.consume(t),p):p(t)}}function Z(e,t,n,r,i,u){const o=this;let c,s=0;return function(t){return e.enter(r),e.enter(i),e.consume(t),e.exit(i),e.enter(u),l};function l(f){return null===f||91===f||93===f&&!c||94===f&&!s&&"_hiddenFootnoteSupport"in o.parser.constructs||s>999?n(f):93===f?(e.exit(u),e.enter(i),e.consume(f),e.exit(i),e.exit(r),t):y(f)?(e.enter("lineEnding"),e.consume(f),e.exit("lineEnding"),l):(e.enter("chunkString",{contentType:"string"}),a(f))}function a(t){return null===t||91===t||93===t||y(t)||s++>999?(e.exit("chunkString"),l(t)):(e.consume(t),c=c||!F(t),92===t?f:a)}function f(t){return 91===t||92===t||93===t?(e.consume(t),s++,a):a(t)}}function Y(e,t,n,r,i,u){let o;return function(t){return e.enter(r),e.enter(i),e.consume(t),e.exit(i),o=40===t?41:t,c};function c(n){return n===o?(e.enter(i),e.consume(n),e.exit(i),e.exit(r),t):(e.enter(u),s(n))}function s(t){return t===o?(e.exit(u),c(o)):null===t?n(t):y(t)?(e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),E(e,s,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),l(t))}function l(t){return t===o||null===t||y(t)?(e.exit("chunkString"),s(t)):(e.consume(t),92===t?a:l)}function a(t){return t===o||92===t?(e.consume(t),l):l(t)}}function G(e,t){let n;return function r(i){if(y(i))return e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),n=!0,r;if(F(i))return E(e,r,n?"linePrefix":"lineSuffix")(i);return t(i)}}function J(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const K={name:"definition",tokenize:function(e,t,n){const r=this;let i;return function(t){return e.enter("definition"),Z.call(r,e,u,n,"definitionLabel","definitionLabelMarker","definitionLabelString")(t)};function u(t){return i=J(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),58===t?(e.enter("definitionMarker"),e.consume(t),e.exit("definitionMarker"),G(e,W(e,e.attempt(X,E(e,o,"whitespace"),E(e,o,"whitespace")),n,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString"))):n(t)}function o(u){return null===u||y(u)?(e.exit("definition"),r.parser.defined.includes(i)||r.parser.defined.push(i),t(u)):n(u)}}},X={tokenize:function(e,t,n){return function(t){return k(t)?G(e,r)(t):n(t)};function r(t){return 34===t||39===t||40===t?Y(e,E(e,i,"whitespace"),n,"definitionTitle","definitionTitleMarker","definitionTitleString")(t):n(t)}function i(e){return null===e||y(e)?t(e):n(e)}},partial:!0};const ee={name:"hardBreakEscape",tokenize:function(e,t,n){return function(t){return e.enter("hardBreakEscape"),e.enter("escapeMarker"),e.consume(t),r};function r(r){return y(r)?(e.exit("escapeMarker"),e.exit("hardBreakEscape"),t(r)):n(r)}}};const te={name:"headingAtx",tokenize:function(e,t,n){const r=this;let i=0;return function(t){return e.enter("atxHeading"),e.enter("atxHeadingSequence"),u(t)};function u(c){return 35===c&&i++<6?(e.consume(c),u):null===c||k(c)?(e.exit("atxHeadingSequence"),r.interrupt?t(c):o(c)):n(c)}function o(n){return 35===n?(e.enter("atxHeadingSequence"),c(n)):null===n||y(n)?(e.exit("atxHeading"),t(n)):F(n)?E(e,o,"whitespace")(n):(e.enter("atxHeadingText"),s(n))}function c(t){return 35===t?(e.consume(t),c):(e.exit("atxHeadingSequence"),o(t))}function s(t){return null===t||35===t||k(t)?(e.exit("atxHeadingText"),o(t)):(e.consume(t),s)}},resolve:function(e,t){let n,r,i=e.length-2,u=3;"whitespace"===e[u][1].type&&(u+=2);i-2>u&&"whitespace"===e[i][1].type&&(i-=2);"atxHeadingSequence"===e[i][1].type&&(u===i-1||i-4>u&&"whitespace"===e[i-2][1].type)&&(i-=u+1===i?2:4);i>u&&(n={type:"atxHeadingText",start:e[u][1].start,end:e[i][1].end},r={type:"chunkText",start:e[u][1].start,end:e[i][1].end,contentType:"text"},o(e,u,i-u+1,[["enter",n,t],["enter",r,t],["exit",r,t],["exit",n,t]]));return e}};const ne=["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","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],re=["pre","script","style","textarea"],ie={name:"htmlFlow",tokenize:function(e,t,n){const r=this;let i,u,o,c,s;return function(t){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(t),l};function l(c){return 33===c?(e.consume(c),a):47===c?(e.consume(c),m):63===c?(e.consume(c),i=3,r.interrupt?t:H):f(c)?(e.consume(c),o=String.fromCharCode(c),u=!0,g):n(c)}function a(u){return 45===u?(e.consume(u),i=2,d):91===u?(e.consume(u),i=5,o="CDATA[",c=0,h):f(u)?(e.consume(u),i=4,r.interrupt?t:H):n(u)}function d(i){return 45===i?(e.consume(i),r.interrupt?t:H):n(i)}function h(i){return i===o.charCodeAt(c++)?(e.consume(i),c===o.length?r.interrupt?t:B:h):n(i)}function m(t){return f(t)?(e.consume(t),o=String.fromCharCode(t),g):n(t)}function g(c){return null===c||47===c||62===c||k(c)?47!==c&&u&&re.includes(o.toLowerCase())?(i=1,r.interrupt?t(c):B(c)):ne.includes(o.toLowerCase())?(i=6,47===c?(e.consume(c),x):r.interrupt?t(c):B(c)):(i=7,r.interrupt&&!r.parser.lazy[r.now().line]?n(c):u?v(c):b(c)):45===c||p(c)?(e.consume(c),o+=String.fromCharCode(c),g):n(c)}function x(i){return 62===i?(e.consume(i),r.interrupt?t:B):n(i)}function b(t){return F(t)?(e.consume(t),b):T(t)}function v(t){return 47===t?(e.consume(t),T):58===t||95===t||f(t)?(e.consume(t),S):F(t)?(e.consume(t),v):T(t)}function S(t){return 45===t||46===t||58===t||95===t||p(t)?(e.consume(t),S):E(t)}function E(t){return 61===t?(e.consume(t),A):F(t)?(e.consume(t),E):v(t)}function A(t){return null===t||60===t||61===t||62===t||96===t?n(t):34===t||39===t?(e.consume(t),s=t,I):F(t)?(e.consume(t),A):(s=null,w(t))}function I(t){return null===t||y(t)?n(t):t===s?(e.consume(t),C):(e.consume(t),I)}function w(t){return null===t||34===t||39===t||60===t||61===t||62===t||96===t||k(t)?E(t):(e.consume(t),w)}function C(e){return 47===e||62===e||F(e)?v(e):n(e)}function T(t){return 62===t?(e.consume(t),z):n(t)}function z(t){return F(t)?(e.consume(t),z):null===t||y(t)?B(t):n(t)}function B(t){return 45===t&&2===i?(e.consume(t),L):60===t&&1===i?(e.consume(t),P):62===t&&4===i?(e.consume(t),R):63===t&&3===i?(e.consume(t),H):93===t&&5===i?(e.consume(t),j):!y(t)||6!==i&&7!==i?null===t||y(t)?D(t):(e.consume(t),B):e.check(ue,R,D)(t)}function D(t){return e.exit("htmlFlowData"),_(t)}function _(t){return null===t?q(t):y(t)?e.attempt({tokenize:M,partial:!0},_,q)(t):(e.enter("htmlFlowData"),B(t))}function M(e,t,n){return function(t){return e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),i};function i(e){return r.parser.lazy[r.now().line]?n(e):t(e)}}function L(t){return 45===t?(e.consume(t),H):B(t)}function P(t){return 47===t?(e.consume(t),o="",O):B(t)}function O(t){return 62===t&&re.includes(o.toLowerCase())?(e.consume(t),R):f(t)&&o.length<8?(e.consume(t),o+=String.fromCharCode(t),O):B(t)}function j(t){return 93===t?(e.consume(t),H):B(t)}function H(t){return 62===t?(e.consume(t),R):45===t&&2===i?(e.consume(t),H):B(t)}function R(t){return null===t||y(t)?(e.exit("htmlFlowData"),q(t)):(e.consume(t),R)}function q(n){return e.exit("htmlFlow"),t(n)}},resolveTo:function(e){let t=e.length;for(;t--&&("enter"!==e[t][0]||"htmlFlow"!==e[t][1].type););t>1&&"linePrefix"===e[t-2][1].type&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2));return e},concrete:!0},ue={tokenize:function(e,t,n){return function(r){return e.exit("htmlFlowData"),e.enter("lineEndingBlank"),e.consume(r),e.exit("lineEndingBlank"),e.attempt(_,t,n)}},partial:!0};const oe={name:"htmlText",tokenize:function(e,t,n){const r=this;let i,u,o,c;return function(t){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(t),s};function s(t){return 33===t?(e.consume(t),l):47===t?(e.consume(t),C):63===t?(e.consume(t),I):f(t)?(e.consume(t),B):n(t)}function l(t){return 45===t?(e.consume(t),a):91===t?(e.consume(t),u="CDATA[",o=0,x):f(t)?(e.consume(t),A):n(t)}function a(t){return 45===t?(e.consume(t),d):n(t)}function d(t){return null===t||62===t?n(t):45===t?(e.consume(t),h):m(t)}function h(e){return null===e||62===e?n(e):m(e)}function m(t){return null===t?n(t):45===t?(e.consume(t),g):y(t)?(c=m,H(t)):(e.consume(t),m)}function g(t){return 45===t?(e.consume(t),q):m(t)}function x(t){return t===u.charCodeAt(o++)?(e.consume(t),o===u.length?b:x):n(t)}function b(t){return null===t?n(t):93===t?(e.consume(t),v):y(t)?(c=b,H(t)):(e.consume(t),b)}function v(t){return 93===t?(e.consume(t),S):b(t)}function S(t){return 62===t?q(t):93===t?(e.consume(t),S):b(t)}function A(t){return null===t||62===t?q(t):y(t)?(c=A,H(t)):(e.consume(t),A)}function I(t){return null===t?n(t):63===t?(e.consume(t),w):y(t)?(c=I,H(t)):(e.consume(t),I)}function w(e){return 62===e?q(e):I(e)}function C(t){return f(t)?(e.consume(t),T):n(t)}function T(t){return 45===t||p(t)?(e.consume(t),T):z(t)}function z(t){return y(t)?(c=z,H(t)):F(t)?(e.consume(t),z):q(t)}function B(t){return 45===t||p(t)?(e.consume(t),B):47===t||62===t||k(t)?D(t):n(t)}function D(t){return 47===t?(e.consume(t),q):58===t||95===t||f(t)?(e.consume(t),_):y(t)?(c=D,H(t)):F(t)?(e.consume(t),D):q(t)}function _(t){return 45===t||46===t||58===t||95===t||p(t)?(e.consume(t),_):M(t)}function M(t){return 61===t?(e.consume(t),L):y(t)?(c=M,H(t)):F(t)?(e.consume(t),M):D(t)}function L(t){return null===t||60===t||61===t||62===t||96===t?n(t):34===t||39===t?(e.consume(t),i=t,P):y(t)?(c=L,H(t)):F(t)?(e.consume(t),L):(e.consume(t),i=void 0,j)}function P(t){return t===i?(e.consume(t),O):null===t?n(t):y(t)?(c=P,H(t)):(e.consume(t),P)}function O(e){return 62===e||47===e||k(e)?D(e):n(e)}function j(t){return null===t||34===t||39===t||60===t||61===t||96===t?n(t):62===t||k(t)?D(t):(e.consume(t),j)}function H(t){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(t),e.exit("lineEnding"),E(e,R,"linePrefix",r.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function R(t){return e.enter("htmlTextData"),c(t)}function q(r){return 62===r?(e.consume(r),e.exit("htmlTextData"),e.exit("htmlText"),t):n(r)}}};const ce={name:"labelEnd",tokenize:function(e,t,n){const r=this;let i,u,o=r.events.length;for(;o--;)if(("labelImage"===r.events[o][1].type||"labelLink"===r.events[o][1].type)&&!r.events[o][1]._balanced){i=r.events[o][1];break}return function(t){if(!i)return n(t);return i._inactive?s(t):(u=r.parser.defined.includes(J(r.sliceSerialize({start:i.end,end:r.now()}))),e.enter("labelEnd"),e.enter("labelMarker"),e.consume(t),e.exit("labelMarker"),e.exit("labelEnd"),c)};function c(n){return 40===n?e.attempt(se,t,u?t:s)(n):91===n?e.attempt(le,t,u?e.attempt(ae,t,s):s)(n):u?t(n):s(n)}function s(e){return i._balanced=!0,n(e)}},resolveTo:function(e,t){let n,r,i,u,s=e.length,l=0;for(;s--;)if(n=e[s][1],r){if("link"===n.type||"labelLink"===n.type&&n._inactive)break;"enter"===e[s][0]&&"labelLink"===n.type&&(n._inactive=!0)}else if(i){if("enter"===e[s][0]&&("labelImage"===n.type||"labelLink"===n.type)&&!n._balanced&&(r=s,"labelLink"!==n.type)){l=2;break}}else"labelEnd"===n.type&&(i=s);const a={type:"labelLink"===e[r][1].type?"link":"image",start:Object.assign({},e[r][1].start),end:Object.assign({},e[e.length-1][1].end)},f={type:"label",start:Object.assign({},e[r][1].start),end:Object.assign({},e[i][1].end)},d={type:"labelText",start:Object.assign({},e[r+l+2][1].end),end:Object.assign({},e[i-2][1].start)};return u=[["enter",a,t],["enter",f,t]],u=c(u,e.slice(r+1,r+l+3)),u=c(u,[["enter",d,t]]),u=c(u,T(t.parser.constructs.insideSpan.null,e.slice(r+l+4,i-3),t)),u=c(u,[["exit",d,t],e[i-2],e[i-1],["exit",f,t]]),u=c(u,e.slice(i+1)),u=c(u,[["exit",a,t]]),o(e,r,e.length,u),e},resolveAll:function(e){let t,n=-1;for(;++n-1&&(o[0]=o[0].slice(r)),u>0&&o.push(e[i].slice(0,u)));return o}(s,e)}function p(){return Object.assign({},r)}function m(){let e;for(;r._index13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||65535==(65535&n)||65534==(65535&n)||n>1114111?"�":String.fromCharCode(n)}const je=/\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi;function He(e,t,n){if(t)return t;if(35===n.charCodeAt(0)){const e=n.charCodeAt(1),t=120===e||88===e;return Oe(n.slice(t?2:1),t?16:10)}return O(n)||e}function Re(e){return e&&"object"==typeof e?"position"in e||"type"in e?Ve(e.position):"start"in e||"end"in e?Ve(e):"line"in e||"column"in e?qe(e):"":""}function qe(e){return Qe(e&&e.line)+":"+Qe(e&&e.column)}function Ve(e){return qe(e&&e.start)+"-"+qe(e&&e.end)}function Qe(e){return e&&"number"==typeof e?e:1}const Ne={}.hasOwnProperty,Ue=function(e,t,n){return"string"!=typeof t&&(n=t,t=void 0),function(e){const t={transforms:[],canContainEols:["emphasis","fragment","heading","paragraph","strong"],enter:{autolink:l(oe),autolinkProtocol:T,autolinkEmail:T,atxHeading:l(ne),blockQuote:l(G),characterEscape:T,characterReference:T,codeFenced:l(K),codeFencedFenceInfo:a,codeFencedFenceMeta:a,codeIndented:l(K,a),codeText:l(X,a),codeTextData:T,data:T,codeFlowValue:T,definition:l(ee),definitionDestinationString:a,definitionLabelString:a,definitionTitleString:a,emphasis:l(te),hardBreakEscape:l(re),hardBreakTrailing:l(re),htmlFlow:l(ie,a),htmlFlowData:T,htmlText:l(ie,a),htmlTextData:T,image:l(ue),label:a,link:l(oe),listItem:l(se),listItemValue:g,listOrdered:l(ce,m),listUnordered:l(ce),paragraph:l(le),reference:N,referenceString:a,resourceDestinationString:a,resourceTitleString:a,setextHeading:l(ne),strong:l(ae),thematicBreak:l(de)},exit:{atxHeading:d(),atxHeadingSequence:A,autolink:d(),autolinkEmail:Y,autolinkProtocol:Z,blockQuote:d(),characterEscapeValue:z,characterReferenceMarkerHexadecimal:$,characterReferenceMarkerNumeric:$,characterReferenceValue:W,codeFenced:d(F),codeFencedFence:y,codeFencedFenceInfo:x,codeFencedFenceMeta:k,codeFlowValue:z,codeIndented:d(b),codeText:d(L),codeTextData:z,data:z,definition:d(),definitionDestinationString:E,definitionLabelString:v,definitionTitleString:S,emphasis:d(),hardBreakEscape:d(D),hardBreakTrailing:d(D),htmlFlow:d(_),htmlFlowData:z,htmlText:d(M),htmlTextData:z,image:d(j),label:R,labelText:H,lineEnding:B,link:d(P),listItem:d(),listOrdered:d(),listUnordered:d(),paragraph:d(),referenceString:U,resourceDestinationString:q,resourceTitleString:V,resource:Q,setextHeading:d(C),setextHeadingLineSequence:w,setextHeadingText:I,strong:d(),thematicBreak:d()}};We(t,(e||{}).mdastExtensions||[]);const n={};return u;function u(e){let n={type:"root",children:[]};const r={stack:[n],tokenStack:[],config:t,enter:f,exit:h,buffer:a,resume:p,setData:c,getData:s},i=[];let u=-1;for(;++u0){const e=r.tokenStack[r.tokenStack.length-1];(e[1]||Ye).call(r,void 0,e[0])}for(n.position={start:$e(e.length>0?e[0][1].start:{line:1,column:1,offset:0}),end:$e(e.length>0?e[e.length-2][1].end:{line:1,column:1,offset:0})},u=-1;++u{0!==n&&(u++,i.push([])),e.split(" ").forEach((e=>{e&&i[u].push({content:e,type:t})}))}))}else"strong"!==e.type&&"emphasis"!==e.type||e.children.forEach((t=>{o(t,e.type)}))}return r.forEach((e=>{"paragraph"===e.type&&e.children.forEach((e=>{o(e)}))})),i}function Je(e,t,n){return e.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",t*n-.1+"em").attr("dy",n+"em")}function Ke(e,t){e.text(""),t.forEach(((t,n)=>{const r=e.append("tspan").attr("font-style","em"===t.type?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight","strong"===t.type?"bold":"normal");0===n?r.text(t.content):r.text(" "+t.content)}))}const Xe=(n,r="",{style:i="",isTitle:u=!1,classes:o="",useHtmlLabels:c=!0,isNode:s=!0,width:l,addSvgBackground:a=!1}={})=>{if(e.info("createText",r,i,u,o,c,s,a),c){const e=function(e){const{children:t}=Ue(e);return t.map((function e(t){return"text"===t.type?t.value.replace(/\n/g,"
    "):"strong"===t.type?`${t.children.map(e).join("")}`:"emphasis"===t.type?`${t.children.map(e).join("")}`:"paragraph"===t.type?`

    ${t.children.map(e).join("")}

    `:`Unsupported markdown: ${t.type}`})).join("")}(r);return function(e,t,n,r,i=!1){const u=e.append("foreignObject"),o=u.append("xhtml:div"),c=t.label,s=t.isNode?"nodeLabel":"edgeLabel";var l,a;o.html(`\n "+c+""),l=o,(a=t.labelStyle)&&l.attr("style",a),o.style("display","table-cell"),o.style("white-space","nowrap"),o.style("max-width",n+"px"),o.attr("xmlns","http://www.w3.org/1999/xhtml"),i&&o.attr("class","labelBkg");let f=o.node().getBoundingClientRect();return f.width===n&&(o.style("display","table"),o.style("white-space","break-spaces"),o.style("width",n+"px"),f=o.node().getBoundingClientRect()),u.style("width",f.width),u.style("height",f.height),u.node()}(n,{isNode:s,label:t(e).replace(/fa[blrs]?:fa-[\w-]+/g,(e=>``)),labelStyle:i.replace("fill:","color:")},l,o,a)}return function(e,t,n,r=!1){const i=t.append("g");let u=i.insert("rect").attr("class","background");const o=i.append("text").attr("y","-10.1");let c=-1;if(n.forEach((t=>{c++;let n,r=Je(o,c,1.1),i=[...t].reverse(),u=[];for(;i.length;)n=i.pop(),u.push(n),Ke(r,u),r.node().getComputedTextLength()>e&&(u.pop(),i.push(n),Ke(r,u),u=[],c++,r=Je(o,c,1.1))})),r){const e=o.node().getBBox(),t=2;return u.attr("x",-t).attr("y",-t).attr("width",e.width+2*t).attr("height",e.height+2*t),i.node()}return o.node()}(l,n,Ge(r),a)};export{Xe as c}; diff --git a/assets/design.html.5dd013d2.js b/assets/design.html.88638fc8.js similarity index 98% rename from assets/design.html.5dd013d2.js rename to assets/design.html.88638fc8.js index 50ba713cb..9dec78caa 100644 --- a/assets/design.html.5dd013d2.js +++ b/assets/design.html.88638fc8.js @@ -1 +1 @@ -import{r as e,o as r,c as a,a as n,b as o,w as t,F as l,e as i}from"./app.755d843f.js";const d={},s=n("h1",{id:"design-objectives",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#design-objectives","aria-hidden":"true"},"#"),i(" Design Objectives")],-1),u=n("ul",null,[n("li",null,"Xray Kernel provides a platform that supports essential network proxy functions and can be developed upon to provide a better user experience."),n("li",null,"Cross-platform is the primary principle to reduce the cost of secondary development.")],-1),p=n("h2",{id:"architecture",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#architecture","aria-hidden":"true"},"#"),i(" Architecture")],-1),h=n("p",null,[n("img",{src:"/Xray-docs-next/assets/framework.fb23d2b0.png",alt:"Architecture"})],-1),c=n("p",null,"The kernel is divided into three layers: the application layer, the proxy layer, and the transport layer.",-1),y=n("p",null,"Each layer contains several modules, which are independent of each other. Modules of the same type can be seamlessly replaced.",-1),b=n("h3",{id:"application-layer",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#application-layer","aria-hidden":"true"},"#"),i(" Application Layer")],-1),f=n("p",null,"The application layer contains some commonly used functions in proxy layers, which are abstracted for reuse in different proxy modules.",-1),x=n("p",null,"The modules at the application layer should be implemented purely in software and should not be dependent on hardware or platform-related technologies.",-1),m=n("p",null,"List of Important Modules:",-1),g=n("li",null,"Dispatcher: Used to transfer data received by the inbound agent to the outbound agent;",-1),v=i("Router: Routing module, see "),w=i("Routing Configuration"),k=i(" for details;"),P=n("li",null,"DNS: Built-in DNS server module;",-1),T=n("li",null,"Proxy Manager: Proxy manager;",-1),I=n("h3",{id:"proxy-layer",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#proxy-layer","aria-hidden":"true"},"#"),i(" Proxy Layer")],-1),L=n("p",null,"The proxy layer is divided into two parts: Inbound Proxy and Outbound Proxy.",-1),O=n("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),j=n("h4",{id:"inbound-proxy",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#inbound-proxy","aria-hidden":"true"},"#"),i(" Inbound Proxy")],-1),D=i("Implement the "),R={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},X=i("proxy.Inbound"),A=i(" interface;"),M=n("h4",{id:"outbound-proxy",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#outbound-proxy","aria-hidden":"true"},"#"),i(" Outbound Proxy")],-1),_=i("Implement the "),C={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},N=i("proxy.Outbound"),S=i(" interface;"),B=n("h3",{id:"transport-layer",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#transport-layer","aria-hidden":"true"},"#"),i(" Transport Layer")],-1),E=n("p",null,"The transport layer provides a set of tools and modules related to network data transmission.",-1);d.render=function(i,d){const F=e("RouterLink"),K=e("OutboundLink");return r(),a(l,null,[s,u,p,h,c,y,b,f,x,m,n("ul",null,[g,n("li",null,[v,o(F,{to:"/en/config/routing.html"},{default:t((()=>[w])),_:1}),k]),P,T]),I,L,O,j,n("ul",null,[n("li",null,[D,n("a",R,[X,o(K)]),A])]),M,n("ul",null,[n("li",null,[_,n("a",C,[N,o(K)]),S])]),B,E],64)};export default d; +import{r as e,o as r,c as a,a as n,b as o,w as t,F as l,e as i}from"./app.48111a85.js";const d={},s=n("h1",{id:"design-objectives",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#design-objectives","aria-hidden":"true"},"#"),i(" Design Objectives")],-1),u=n("ul",null,[n("li",null,"Xray Kernel provides a platform that supports essential network proxy functions and can be developed upon to provide a better user experience."),n("li",null,"Cross-platform is the primary principle to reduce the cost of secondary development.")],-1),p=n("h2",{id:"architecture",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#architecture","aria-hidden":"true"},"#"),i(" Architecture")],-1),h=n("p",null,[n("img",{src:"/Xray-docs-next/assets/framework.fb23d2b0.png",alt:"Architecture"})],-1),c=n("p",null,"The kernel is divided into three layers: the application layer, the proxy layer, and the transport layer.",-1),y=n("p",null,"Each layer contains several modules, which are independent of each other. Modules of the same type can be seamlessly replaced.",-1),b=n("h3",{id:"application-layer",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#application-layer","aria-hidden":"true"},"#"),i(" Application Layer")],-1),f=n("p",null,"The application layer contains some commonly used functions in proxy layers, which are abstracted for reuse in different proxy modules.",-1),x=n("p",null,"The modules at the application layer should be implemented purely in software and should not be dependent on hardware or platform-related technologies.",-1),m=n("p",null,"List of Important Modules:",-1),g=n("li",null,"Dispatcher: Used to transfer data received by the inbound agent to the outbound agent;",-1),v=i("Router: Routing module, see "),w=i("Routing Configuration"),k=i(" for details;"),P=n("li",null,"DNS: Built-in DNS server module;",-1),T=n("li",null,"Proxy Manager: Proxy manager;",-1),I=n("h3",{id:"proxy-layer",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#proxy-layer","aria-hidden":"true"},"#"),i(" Proxy Layer")],-1),L=n("p",null,"The proxy layer is divided into two parts: Inbound Proxy and Outbound Proxy.",-1),O=n("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),j=n("h4",{id:"inbound-proxy",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#inbound-proxy","aria-hidden":"true"},"#"),i(" Inbound Proxy")],-1),D=i("Implement the "),R={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},X=i("proxy.Inbound"),A=i(" interface;"),M=n("h4",{id:"outbound-proxy",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#outbound-proxy","aria-hidden":"true"},"#"),i(" Outbound Proxy")],-1),_=i("Implement the "),C={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},N=i("proxy.Outbound"),S=i(" interface;"),B=n("h3",{id:"transport-layer",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#transport-layer","aria-hidden":"true"},"#"),i(" Transport Layer")],-1),E=n("p",null,"The transport layer provides a set of tools and modules related to network data transmission.",-1);d.render=function(i,d){const F=e("RouterLink"),K=e("OutboundLink");return r(),a(l,null,[s,u,p,h,c,y,b,f,x,m,n("ul",null,[g,n("li",null,[v,o(F,{to:"/en/config/routing.html"},{default:t((()=>[w])),_:1}),k]),P,T]),I,L,O,j,n("ul",null,[n("li",null,[D,n("a",R,[X,o(K)]),A])]),M,n("ul",null,[n("li",null,[_,n("a",C,[N,o(K)]),S])]),B,E],64)};export default d; diff --git a/assets/design.html.05403052.js b/assets/design.html.ae406d25.js similarity index 97% rename from assets/design.html.05403052.js rename to assets/design.html.ae406d25.js index 6710f7ef2..6ff25b908 100644 --- a/assets/design.html.05403052.js +++ b/assets/design.html.ae406d25.js @@ -1 +1 @@ -import{r,o as a,c as e,a as l,b as n,w as u,F as i,e as o}from"./app.755d843f.js";const t={},d=l("h1",{id:"设计目标",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#设计目标","aria-hidden":"true"},"#"),o(" 设计目标")],-1),h=l("ul",null,[l("li",null,"Xray 内核提供了一个平台,支持必要的网络代理功能,在其之上可以进二次开发,以提供更好的用户体验;"),l("li",null,"以跨平台为首要原则,以减少二次开发的成本;")],-1),s=l("h2",{id:"架构",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#架构","aria-hidden":"true"},"#"),o(" 架构")],-1),c=l("p",null,[l("img",{src:"/Xray-docs-next/assets/framework.fb23d2b0.png",alt:"Architecture"})],-1),p=l("p",null,"内核分为三层:应用层、代理层和传输层。",-1),b=l("p",null,"每一层内包含数个模块,模块间互相独立,同类型的模块可无缝替换。",-1),x=l("h3",{id:"应用层",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#应用层","aria-hidden":"true"},"#"),o(" 应用层")],-1),f=l("p",null,"应用层包含一些代理层中常用的功能,这些功能被抽象出来,以便在不同的代理模块中复用。",-1),y=l("p",null,"应用层的模块应为纯软件实现,与硬件或平台相关的技术无关。",-1),g=l("p",null,"重要模块列表:",-1),m=l("li",null,"Dispatcher: 用于把入站代理所接收到的数据,传送给出站代理;",-1),k=o("Router: 路由模块,详见 "),X=o("路由配置"),D=o(";"),O=l("li",null,"DNS: 内置的 DNS 服务器模块;",-1),P=l("li",null,"Proxy Manager: 代理管理器;",-1),_=l("h3",{id:"代理层",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#代理层","aria-hidden":"true"},"#"),o(" 代理层")],-1),w=l("p",null,"代理层分为两部分:入站代理(Inbound Proxy)和出站代理(Outbound Proxy)。",-1),I=l("p",null,"两部分相互独立,入站代理不依赖于某个特定的出站代理,反之亦然。",-1),L=l("h4",{id:"入站代理",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#入站代理","aria-hidden":"true"},"#"),o(" 入站代理")],-1),N=o("实现 "),R={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},S=o("proxy.Inbound"),j=o(" 接口;"),A=l("h4",{id:"出站代理",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#出站代理","aria-hidden":"true"},"#"),o(" 出站代理")],-1),F=o("实现 "),M={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},q=o("proxy.Outbound"),v=o(" 接口;"),z=l("h3",{id:"传输层",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#传输层","aria-hidden":"true"},"#"),o(" 传输层")],-1),B=l("p",null,"传输层提供一些网络数据传输相关的工具模块。",-1);t.render=function(o,t){const C=r("RouterLink"),E=r("OutboundLink");return a(),e(i,null,[d,h,s,c,p,b,x,f,y,g,l("ul",null,[m,l("li",null,[k,n(C,{to:"/config/routing.html"},{default:u((()=>[X])),_:1}),D]),O,P]),_,w,I,L,l("ul",null,[l("li",null,[N,l("a",R,[S,n(E)]),j])]),A,l("ul",null,[l("li",null,[F,l("a",M,[q,n(E)]),v])]),z,B],64)};export default t; +import{r,o as a,c as e,a as l,b as n,w as u,F as i,e as o}from"./app.48111a85.js";const t={},d=l("h1",{id:"设计目标",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#设计目标","aria-hidden":"true"},"#"),o(" 设计目标")],-1),h=l("ul",null,[l("li",null,"Xray 内核提供了一个平台,支持必要的网络代理功能,在其之上可以进二次开发,以提供更好的用户体验;"),l("li",null,"以跨平台为首要原则,以减少二次开发的成本;")],-1),s=l("h2",{id:"架构",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#架构","aria-hidden":"true"},"#"),o(" 架构")],-1),c=l("p",null,[l("img",{src:"/Xray-docs-next/assets/framework.fb23d2b0.png",alt:"Architecture"})],-1),p=l("p",null,"内核分为三层:应用层、代理层和传输层。",-1),b=l("p",null,"每一层内包含数个模块,模块间互相独立,同类型的模块可无缝替换。",-1),x=l("h3",{id:"应用层",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#应用层","aria-hidden":"true"},"#"),o(" 应用层")],-1),f=l("p",null,"应用层包含一些代理层中常用的功能,这些功能被抽象出来,以便在不同的代理模块中复用。",-1),y=l("p",null,"应用层的模块应为纯软件实现,与硬件或平台相关的技术无关。",-1),g=l("p",null,"重要模块列表:",-1),m=l("li",null,"Dispatcher: 用于把入站代理所接收到的数据,传送给出站代理;",-1),k=o("Router: 路由模块,详见 "),X=o("路由配置"),D=o(";"),O=l("li",null,"DNS: 内置的 DNS 服务器模块;",-1),P=l("li",null,"Proxy Manager: 代理管理器;",-1),_=l("h3",{id:"代理层",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#代理层","aria-hidden":"true"},"#"),o(" 代理层")],-1),w=l("p",null,"代理层分为两部分:入站代理(Inbound Proxy)和出站代理(Outbound Proxy)。",-1),I=l("p",null,"两部分相互独立,入站代理不依赖于某个特定的出站代理,反之亦然。",-1),L=l("h4",{id:"入站代理",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#入站代理","aria-hidden":"true"},"#"),o(" 入站代理")],-1),N=o("实现 "),R={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},S=o("proxy.Inbound"),j=o(" 接口;"),A=l("h4",{id:"出站代理",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#出站代理","aria-hidden":"true"},"#"),o(" 出站代理")],-1),F=o("实现 "),M={href:"https://github.com/xtls/Xray-core/blob/main/proxy/proxy.go",target:"_blank",rel:"noopener noreferrer"},q=o("proxy.Outbound"),v=o(" 接口;"),z=l("h3",{id:"传输层",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#传输层","aria-hidden":"true"},"#"),o(" 传输层")],-1),B=l("p",null,"传输层提供一些网络数据传输相关的工具模块。",-1);t.render=function(o,t){const C=r("RouterLink"),E=r("OutboundLink");return a(),e(i,null,[d,h,s,c,p,b,x,f,y,g,l("ul",null,[m,l("li",null,[k,n(C,{to:"/config/routing.html"},{default:u((()=>[X])),_:1}),D]),O,P]),_,w,I,L,l("ul",null,[l("li",null,[N,l("a",R,[S,n(E)]),j])]),A,l("ul",null,[l("li",null,[F,l("a",M,[q,n(E)]),v])]),z,B],64)};export default t; diff --git a/assets/dns.html.8f955016.js b/assets/dns.html.11732ba6.js similarity index 99% rename from assets/dns.html.8f955016.js rename to assets/dns.html.11732ba6.js index 509e096f5..55b8f7ad7 100644 --- a/assets/dns.html.8f955016.js +++ b/assets/dns.html.11732ba6.js @@ -1 +1 @@ -import{r as e,o as s,c as o,a as t,b as n,w as a,F as r,d as i,e as c}from"./app.755d843f.js";const u={},l=i('

    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.

    {\n  "dns": {\n    "hosts": {\n      "baidu.com": "127.0.0.1",\n      "dns.google": ["8.8.8.8", "8.8.4.4"]\n    },\n    "servers": [\n      "8.8.8.8",\n      "8.8.4.4",\n      {\n        "address": "1.2.3.4",\n        "port": 5353,\n        "domains": ["domain:xray.com"],\n        "expectIPs": ["geoip:cn"],\n        "skipFallback": false,\n        "clientIP": "1.2.3.4"\n      },\n      "localhost"\n    ],\n    "clientIp": "1.2.3.4",\n    "queryStrategy": "UseIP",\n    "disableCache": false,\n    "disableFallback": false,\n    "disableFallbackIfMatch": false,\n    "tag": "dns_inbound"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    hosts: map{string: address} | map{string: [address]}

    A list of static IP addresses, with values consisting of a series of "domain": "address" or "domain": ["address 1","address 2"]. The address can be an IP or a domain name. When resolving a domain name, if the domain name matches an item in this list:

    • If the address of the item is an IP, the resolution result will be that IP.
    • If the address of the item is a domain name, this domain name will be used for IP resolution instead of the original domain name.
    • If multiple IPs and domain names are set in the address, only the first domain name will be returned, and the rest of the IPs and domain names will be ignored.

    The domain name can take several forms:

    • Plain string: When this string matches the target domain name exactly, the rule takes effect. For example, "xray.com" matches "xray.com" but not "www.xray.com".
    • Regular expression: Starting with "regexp:", the rest is a regular expression. When this regular expression matches the target domain name, the rule takes effect. For example, "regexp:\\.goo.*\\.com$" matches "www.google.com" and "fonts.googleapis.com", but not "google.com".
    • Subdomain (recommended): Starting with "domain:", the rest is a domain name. When this domain name is the target domain name or its subdomain, the rule takes effect. For example, "domain:xray.com" matches "www.xray.com" and "xray.com", but not "wxray.com".
    • Substring: Starting with "keyword:", the rest is a string. When this string matches any part of the target domain name, the rule takes effect. For example, "keyword:sina.com" can match "sina.com", "sina.com.cn", and "www.sina.com", but not "sina.cn".
    • Predefined domain name list: Starting with "geosite:", the rest is a name, such as geosite:google or geosite:cn. The names and domain name lists are listed in Predefined Domain Name Lists.

    servers: [string | ServerObject ]

    A list of DNS servers that supports two types: DNS addresses (in string format) and ServerObject.

    When the value is "localhost", it means to use the default DNS configuration on the local machine.

    When the value is a DNS "IP:Port" address, such as "8.8.8.8:53", Xray will use the specified UDP port of this address for DNS queries. The query follows the routing rules. When the port is not specified, the default port 53 is used.

    When the value is in the form of "tcp://host:port", such as "tcp://8.8.8.8:53", Xray will use DNS over TCP for queries. The query follows the routing rules. When the port is not specified, the default port 53 is used.

    When the value is in the form of "tcp+local://host:port", such as "tcp+local://8.8.8.8:53", Xray will use TCP local mode (TCPL) for queries. That is, DNS requests will not pass through the routing component and will directly request outbound through Freedom, to reduce latency. When the port is not specified, the default port 53 is used.

    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 queries. Some service providers have certificates with IP aliases, 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 queries. That is, DOH requests will not pass through the routing component and will directly request outbound through Freedom, to reduce latency. This is generally suitable for use on the server side. Non-standard ports and paths can also be used.

    When the value is in the form of "quic+local://host", such as "quic+local://dns.adguard.com", Xray will use DNS over QUIC local mode (DOQL) for queries. That is, DNS requests will not pass through the routing component and will directly request outbound through Freedom. This method requires DNS server support for DNS over QUIC. The default port 784 is used for queries, and non-standard ports can also be used.

    When the value is fakedns, the FakeDNS function will be used for queries.

    TIP 1

    When using localhost, DNS requests on the local machine are not controlled by Xray and additional configuration is required to make DNS requests forwarded by Xray.

    TIP 2

    DNS clients initialized with different rules will be reflected in the Xray startup log at the info level, such as local DOH, remote DOH, and udp modes.

    ',29),p={class:"custom-container tip"},d=t("p",{class:"custom-container-title"},"TIP 3",-1),h=c("(v1.4.0+) DNS query logging can be enabled in the "),q=c("log"),m=c("."),f=i('

    clientIp: string

    Used to notify the server of the specified IP location during DNS queries. Cannot be a private address.

    TIP 1

    EDNS Client Subnet support is required for the DNS server.

    TIP 2

    You can specify clientIp for all DNS servers in DnsObject, or specify it for each DNS server in the configuration of ServerObject (which has higher priority than the configuration in DnsObject).

    queryStrategy: "UseIP" | "UseIPv4" | "UseIPv6"

    UseIPv4 only queries A records; UseIPv6 only queries AAAA records. The default value is UseIP, which queries both A and AAAA records.

    disableCache: true | false

    true disables DNS caching, default is false which means caching is not disabled.

    disableFallback: true | false

    true disables fallback DNS queries, default is false which means fallback queries are not disabled.

    disableFallbackIfMatch: true | false

    true disables fallback DNS queries when the matching domain list of the DNS server is hit, default is false which means fallback queries are not disabled.

    tag: string

    Traffic generated by built-in DNS, except for localhost, fakedns, TCPL, DOHL, and DOQL modes, can be matched with inboundTag in routing using this identifier.

    ServerObject

    {\n  "address": "1.2.3.4",\n  "port": 5353,\n  "domains": ["domain:xray.com"],\n  "expectIPs": ["geoip:cn"],\n  "skipFallback": false,\n  "clientIP": "1.2.3.4"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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]

    ',29),b=c("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 "),g=c("routing configuration"),k=c("."),y=t("blockquote",null,[t("p",null,[t("code",null,"expectIPs"),c(": [string]")])],-1),v=c("A list of IP ranges in the same format as in "),w=c("routing configuration"),D=c("."),S=t("p",null,[c("When this item is configured, Xray DNS will verify the returned IP addresses and only return addresses that are included in the "),t("code",null,"expectIPs"),c(" list.")],-1),I=t("p",null,"If this item is not configured, the IP address will be returned as is.",-1),P=t("blockquote",null,[t("p",null,[t("code",null,"skipFallback"),c(": true | false")])],-1),N=t("p",null,[t("code",null,"true"),c(" means to skip this server when performing DNS fallback queries, and the default is "),t("code",null,"false"),c(", which means not to skip.")],-1);u.render=function(i,c){const u=e("RouterLink");return s(),o(r,null,[l,t("div",p,[d,t("p",null,[h,n(u,{to:"/en/config/log.html"},{default:a((()=>[q])),_:1}),m])]),f,t("p",null,[b,n(u,{to:"/en/config/routing.html#ruleobject"},{default:a((()=>[g])),_:1}),k]),y,t("p",null,[v,n(u,{to:"/en/config/routing.html#ruleobject"},{default:a((()=>[w])),_:1}),D]),S,I,P,N],64)};export default u; +import{r as e,o as s,c as o,a as t,b as n,w as a,F as r,d as i,e as c}from"./app.48111a85.js";const u={},l=i('

    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.

    {\n  "dns": {\n    "hosts": {\n      "baidu.com": "127.0.0.1",\n      "dns.google": ["8.8.8.8", "8.8.4.4"]\n    },\n    "servers": [\n      "8.8.8.8",\n      "8.8.4.4",\n      {\n        "address": "1.2.3.4",\n        "port": 5353,\n        "domains": ["domain:xray.com"],\n        "expectIPs": ["geoip:cn"],\n        "skipFallback": false,\n        "clientIP": "1.2.3.4"\n      },\n      "localhost"\n    ],\n    "clientIp": "1.2.3.4",\n    "queryStrategy": "UseIP",\n    "disableCache": false,\n    "disableFallback": false,\n    "disableFallbackIfMatch": false,\n    "tag": "dns_inbound"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    hosts: map{string: address} | map{string: [address]}

    A list of static IP addresses, with values consisting of a series of "domain": "address" or "domain": ["address 1","address 2"]. The address can be an IP or a domain name. When resolving a domain name, if the domain name matches an item in this list:

    • If the address of the item is an IP, the resolution result will be that IP.
    • If the address of the item is a domain name, this domain name will be used for IP resolution instead of the original domain name.
    • If multiple IPs and domain names are set in the address, only the first domain name will be returned, and the rest of the IPs and domain names will be ignored.

    The domain name can take several forms:

    • Plain string: When this string matches the target domain name exactly, the rule takes effect. For example, "xray.com" matches "xray.com" but not "www.xray.com".
    • Regular expression: Starting with "regexp:", the rest is a regular expression. When this regular expression matches the target domain name, the rule takes effect. For example, "regexp:\\.goo.*\\.com$" matches "www.google.com" and "fonts.googleapis.com", but not "google.com".
    • Subdomain (recommended): Starting with "domain:", the rest is a domain name. When this domain name is the target domain name or its subdomain, the rule takes effect. For example, "domain:xray.com" matches "www.xray.com" and "xray.com", but not "wxray.com".
    • Substring: Starting with "keyword:", the rest is a string. When this string matches any part of the target domain name, the rule takes effect. For example, "keyword:sina.com" can match "sina.com", "sina.com.cn", and "www.sina.com", but not "sina.cn".
    • Predefined domain name list: Starting with "geosite:", the rest is a name, such as geosite:google or geosite:cn. The names and domain name lists are listed in Predefined Domain Name Lists.

    servers: [string | ServerObject ]

    A list of DNS servers that supports two types: DNS addresses (in string format) and ServerObject.

    When the value is "localhost", it means to use the default DNS configuration on the local machine.

    When the value is a DNS "IP:Port" address, such as "8.8.8.8:53", Xray will use the specified UDP port of this address for DNS queries. The query follows the routing rules. When the port is not specified, the default port 53 is used.

    When the value is in the form of "tcp://host:port", such as "tcp://8.8.8.8:53", Xray will use DNS over TCP for queries. The query follows the routing rules. When the port is not specified, the default port 53 is used.

    When the value is in the form of "tcp+local://host:port", such as "tcp+local://8.8.8.8:53", Xray will use TCP local mode (TCPL) for queries. That is, DNS requests will not pass through the routing component and will directly request outbound through Freedom, to reduce latency. When the port is not specified, the default port 53 is used.

    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 queries. Some service providers have certificates with IP aliases, 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 queries. That is, DOH requests will not pass through the routing component and will directly request outbound through Freedom, to reduce latency. This is generally suitable for use on the server side. Non-standard ports and paths can also be used.

    When the value is in the form of "quic+local://host", such as "quic+local://dns.adguard.com", Xray will use DNS over QUIC local mode (DOQL) for queries. That is, DNS requests will not pass through the routing component and will directly request outbound through Freedom. This method requires DNS server support for DNS over QUIC. The default port 784 is used for queries, and non-standard ports can also be used.

    When the value is fakedns, the FakeDNS function will be used for queries.

    TIP 1

    When using localhost, DNS requests on the local machine are not controlled by Xray and additional configuration is required to make DNS requests forwarded by Xray.

    TIP 2

    DNS clients initialized with different rules will be reflected in the Xray startup log at the info level, such as local DOH, remote DOH, and udp modes.

    ',29),p={class:"custom-container tip"},d=t("p",{class:"custom-container-title"},"TIP 3",-1),h=c("(v1.4.0+) DNS query logging can be enabled in the "),q=c("log"),m=c("."),f=i('

    clientIp: string

    Used to notify the server of the specified IP location during DNS queries. Cannot be a private address.

    TIP 1

    EDNS Client Subnet support is required for the DNS server.

    TIP 2

    You can specify clientIp for all DNS servers in DnsObject, or specify it for each DNS server in the configuration of ServerObject (which has higher priority than the configuration in DnsObject).

    queryStrategy: "UseIP" | "UseIPv4" | "UseIPv6"

    UseIPv4 only queries A records; UseIPv6 only queries AAAA records. The default value is UseIP, which queries both A and AAAA records.

    disableCache: true | false

    true disables DNS caching, default is false which means caching is not disabled.

    disableFallback: true | false

    true disables fallback DNS queries, default is false which means fallback queries are not disabled.

    disableFallbackIfMatch: true | false

    true disables fallback DNS queries when the matching domain list of the DNS server is hit, default is false which means fallback queries are not disabled.

    tag: string

    Traffic generated by built-in DNS, except for localhost, fakedns, TCPL, DOHL, and DOQL modes, can be matched with inboundTag in routing using this identifier.

    ServerObject

    {\n  "address": "1.2.3.4",\n  "port": 5353,\n  "domains": ["domain:xray.com"],\n  "expectIPs": ["geoip:cn"],\n  "skipFallback": false,\n  "clientIP": "1.2.3.4"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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]

    ',29),b=c("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 "),g=c("routing configuration"),k=c("."),y=t("blockquote",null,[t("p",null,[t("code",null,"expectIPs"),c(": [string]")])],-1),v=c("A list of IP ranges in the same format as in "),w=c("routing configuration"),D=c("."),S=t("p",null,[c("When this item is configured, Xray DNS will verify the returned IP addresses and only return addresses that are included in the "),t("code",null,"expectIPs"),c(" list.")],-1),I=t("p",null,"If this item is not configured, the IP address will be returned as is.",-1),P=t("blockquote",null,[t("p",null,[t("code",null,"skipFallback"),c(": true | false")])],-1),N=t("p",null,[t("code",null,"true"),c(" means to skip this server when performing DNS fallback queries, and the default is "),t("code",null,"false"),c(", which means not to skip.")],-1);u.render=function(i,c){const u=e("RouterLink");return s(),o(r,null,[l,t("div",p,[d,t("p",null,[h,n(u,{to:"/en/config/log.html"},{default:a((()=>[q])),_:1}),m])]),f,t("p",null,[b,n(u,{to:"/en/config/routing.html#ruleobject"},{default:a((()=>[g])),_:1}),k]),y,t("p",null,[v,n(u,{to:"/en/config/routing.html#ruleobject"},{default:a((()=>[w])),_:1}),D]),S,I,P,N],64)};export default u; diff --git a/assets/dns.html.bf2b1c62.js b/assets/dns.html.6799dc2b.js similarity index 92% rename from assets/dns.html.bf2b1c62.js rename to assets/dns.html.6799dc2b.js index bc4628132..196c56087 100644 --- a/assets/dns.html.bf2b1c62.js +++ b/assets/dns.html.6799dc2b.js @@ -1 +1 @@ -import{r as n,o,c as s,a,b as e,w as t,F as p,e as u,d as c}from"./app.755d843f.js";const r={},d=a("h1",{id:"dns",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#dns","aria-hidden":"true"},"#"),u(" DNS")],-1),l=a("p",null,"DNS 是一个出站协议,主要用于拦截和转发 DNS 查询。",-1),i=a("p",null,"此出站协议只能接收 DNS 流量(包含基于 UDP 和 TCP 协议的查询),其它类型的流量会导致错误。",-1),q=u("在处理 DNS 查询时,此出站协议会将 IP 查询(即 A 和 AAAA)转发给内置的 "),b=u("DNS 服务器"),k=u("。其它类型的查询流量将被转发至它们原本的目标地址。"),h=c('

    OutboundConfigurationObject

    {\n  "network": "tcp",\n  "address": "1.1.1.1",\n  "port": 53,\n  "nonIPQuery": "drop"\n}\n
    1
    2
    3
    4
    5
    6

    network: "tcp" | "udp"

    修改 DNS 流量的传输层协议,可选的值有 "tcp""udp"。当不指定时,保持来源的传输方式不变。

    address: address

    修改 DNS 服务器地址。当不指定时,保持来源中指定的地址不变。

    port: number

    修改 DNS 服务器端口。当不指定时,保持来源中指定的端口不变。

    nonIPQuery: string

    控制非 IP 查询(非 A 和 AAAA),"drop" 丢弃或者 "skip" 不由内置 DNS 服务器处理,将转发给目标。默认为 "drop"

    ',10),g={id:"dns-配置实例",tabindex:"-1"},m=a("a",{class:"header-anchor",href:"#dns-配置实例","aria-hidden":"true"},"#",-1),f=u(" DNS 配置实例 ");r.render=function(u,c){const r=n("RouterLink"),D=n("Badge");return o(),s(p,null,[d,l,i,a("p",null,[q,e(r,{to:"/config/dns.html"},{default:t((()=>[b])),_:1}),k]),h,a("h2",g,[m,f,e(D,{text:"WIP",type:"warning"})])],64)};export default r; +import{r as n,o,c as s,a,b as e,w as t,F as p,e as u,d as c}from"./app.48111a85.js";const r={},d=a("h1",{id:"dns",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#dns","aria-hidden":"true"},"#"),u(" DNS")],-1),l=a("p",null,"DNS 是一个出站协议,主要用于拦截和转发 DNS 查询。",-1),i=a("p",null,"此出站协议只能接收 DNS 流量(包含基于 UDP 和 TCP 协议的查询),其它类型的流量会导致错误。",-1),q=u("在处理 DNS 查询时,此出站协议会将 IP 查询(即 A 和 AAAA)转发给内置的 "),b=u("DNS 服务器"),k=u("。其它类型的查询流量将被转发至它们原本的目标地址。"),h=c('

    OutboundConfigurationObject

    {\n  "network": "tcp",\n  "address": "1.1.1.1",\n  "port": 53,\n  "nonIPQuery": "drop"\n}\n
    1
    2
    3
    4
    5
    6

    network: "tcp" | "udp"

    修改 DNS 流量的传输层协议,可选的值有 "tcp""udp"。当不指定时,保持来源的传输方式不变。

    address: address

    修改 DNS 服务器地址。当不指定时,保持来源中指定的地址不变。

    port: number

    修改 DNS 服务器端口。当不指定时,保持来源中指定的端口不变。

    nonIPQuery: string

    控制非 IP 查询(非 A 和 AAAA),"drop" 丢弃或者 "skip" 不由内置 DNS 服务器处理,将转发给目标。默认为 "drop"

    ',10),g={id:"dns-配置实例",tabindex:"-1"},m=a("a",{class:"header-anchor",href:"#dns-配置实例","aria-hidden":"true"},"#",-1),D=u(" DNS 配置实例 ");r.render=function(u,c){const r=n("RouterLink"),f=n("Badge");return o(),s(p,null,[d,l,i,a("p",null,[q,e(r,{to:"/config/dns.html"},{default:t((()=>[b])),_:1}),k]),h,a("h2",g,[m,D,e(f,{text:"WIP",type:"warning"})])],64)};export default r; diff --git a/assets/dns.html.b39b6b30.js b/assets/dns.html.c21ef586.js similarity index 98% rename from assets/dns.html.b39b6b30.js rename to assets/dns.html.c21ef586.js index f7491353d..a8ee00f53 100644 --- a/assets/dns.html.b39b6b30.js +++ b/assets/dns.html.c21ef586.js @@ -1 +1 @@ -import{r as e,o as n,c as o,a as s,b as t,w as a,F as r,e as p,d as i}from"./app.755d843f.js";const u={},d=s("h1",{id:"dns",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#dns","aria-hidden":"true"},"#"),p(" DNS")],-1),c=s("p",null,"DNS is an outbound protocol used for intercepting and forwarding DNS queries.",-1),l=s("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),b=p("When handling DNS queries, this outbound protocol will forward IP queries (A and AAAA) to the built-in "),q=p("DNS server"),h=p(". Other types of query traffic will be forwarded to their original destination addresses."),f=i('

    OutboundConfigurationObject

    {\n  "network": "tcp",\n  "address": "1.1.1.1",\n  "port": 53,\n  "nonIPQuery": "drop"\n}\n
    1
    2
    3
    4
    5
    6

    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".

    ',10),k={id:"dns-configuration-example",tabindex:"-1"},g=s("a",{class:"header-anchor",href:"#dns-configuration-example","aria-hidden":"true"},"#",-1),m=p(" DNS Configuration Example ");u.render=function(p,i){const u=e("RouterLink"),w=e("Badge");return n(),o(r,null,[d,c,l,s("p",null,[b,t(u,{to:"/en/config/dns.html"},{default:a((()=>[q])),_:1}),h]),f,s("h2",k,[g,m,t(w,{text:"WIP",type:"warning"})])],64)};export default u; +import{r as e,o as n,c as o,a as s,b as t,w as a,F as r,e as p,d as i}from"./app.48111a85.js";const u={},d=s("h1",{id:"dns",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#dns","aria-hidden":"true"},"#"),p(" DNS")],-1),c=s("p",null,"DNS is an outbound protocol used for intercepting and forwarding DNS queries.",-1),l=s("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),b=p("When handling DNS queries, this outbound protocol will forward IP queries (A and AAAA) to the built-in "),q=p("DNS server"),h=p(". Other types of query traffic will be forwarded to their original destination addresses."),f=i('

    OutboundConfigurationObject

    {\n  "network": "tcp",\n  "address": "1.1.1.1",\n  "port": 53,\n  "nonIPQuery": "drop"\n}\n
    1
    2
    3
    4
    5
    6

    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".

    ',10),k={id:"dns-configuration-example",tabindex:"-1"},g=s("a",{class:"header-anchor",href:"#dns-configuration-example","aria-hidden":"true"},"#",-1),m=p(" DNS Configuration Example ");u.render=function(p,i){const u=e("RouterLink"),w=e("Badge");return n(),o(r,null,[d,c,l,s("p",null,[b,t(u,{to:"/en/config/dns.html"},{default:a((()=>[q])),_:1}),h]),f,s("h2",k,[g,m,t(w,{text:"WIP",type:"warning"})])],64)};export default u; diff --git a/assets/dns.html.52693cb1.js b/assets/dns.html.ed602061.js similarity index 99% rename from assets/dns.html.52693cb1.js rename to assets/dns.html.ed602061.js index 1c6195120..4f588d245 100644 --- a/assets/dns.html.52693cb1.js +++ b/assets/dns.html.ed602061.js @@ -1 +1 @@ -import{r as o,o as s,c as n,a,b as e,w as t,F as c,d as p,e as l}from"./app.755d843f.js";const u={},d=p('

    内置 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 项。

    {\n  "dns": {\n    "hosts": {\n      "baidu.com": "127.0.0.1",\n      "dns.google": ["8.8.8.8", "8.8.4.4"]\n    },\n    "servers": [\n      "8.8.8.8",\n      "8.8.4.4",\n      {\n        "address": "1.2.3.4",\n        "port": 5353,\n        "domains": ["domain:xray.com"],\n        "expectIPs": ["geoip:cn"],\n        "skipFallback": false,\n        "clientIP": "1.2.3.4"\n      },\n      "localhost"\n    ],\n    "clientIp": "1.2.3.4",\n    "queryStrategy": "UseIP",\n    "disableCache": false,\n    "disableFallback": false,\n    "disableFallbackIfMatch": false,\n    "tag": "dns_inbound"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    hosts: map{string: address} | map{string: [address]}

    静态 IP 列表,其值为一系列的 "域名": "地址" 或 "域名": ["地址 1","地址 2"]。其中地址可以是 IP 或者域名。在解析域名时,如果域名匹配这个列表中的某一项:

    • 当该项的地址为 IP 时,则解析结果为该项的 IP
    • 当该项的地址为域名时,会使用此域名进行 IP 解析,而不使用原始域名。
    • 当地址中同时设置了多个 IP 和域名,则只会返回第一个域名,其余 IP 和域名均被忽略。

    域名的格式有以下几种形式:

    ',16),r=a("li",null,'纯字符串:当此字符串完整匹配目标域名时,该规则生效。例如 "xray.com" 匹配 "xray.com",但不匹配 "www.xray.com"。',-1),i=a("li",null,[l("正则表达式:由 "),a("code",null,'"regexp:"'),l(' 开始,余下部分是一个正则表达式。当此正则表达式匹配目标域名时,该规则生效。例如 "regexp:\\\\.goo.*\\\\.com$" 匹配 "www.google.com"、"fonts.googleapis.com",但不匹配 "google.com"。')],-1),q=a("li",null,[l("子域名 (推荐):由 "),a("code",null,'"domain:"'),l(' 开始,余下部分是一个域名。当此域名是目标域名或其子域名时,该规则生效。例如 "domain:xray.com" 匹配 "www.xray.com" 与 "xray.com",但不匹配 "wxray.com"。')],-1),k=a("li",null,[l("子串:由 "),a("code",null,'"keyword:"'),l(' 开始,余下部分是一个字符串。当此字符串匹配目标域名中任意部分,该规则生效。比如 "keyword:sina.com" 可以匹配 "sina.com"、"sina.com.cn" 和 "www.sina.com",但不匹配 "sina.cn"。')],-1),b=l("预定义域名列表:由 "),m=a("code",null,'"geosite:"',-1),D=l(" 开头,余下部分是一个名称,如 "),S=a("code",null,"geosite:google",-1),h=l(" 或者 "),P=a("code",null,"geosite:cn",-1),g=l("。名称及域名列表参考 "),I=l("预定义域名列表"),N=l("。"),y=p('

    servers: [string | ServerObject ]

    一个 DNS 服务器列表,支持的类型有两种:DNS 地址(字符串形式)和 ServerObject

    当值为 "localhost" 时,表示使用本机预设的 DNS 配置。

    当它的值是一个 DNS "IP:Port" 地址时,如 "8.8.8.8:53",Xray 会使用此地址的指定 UDP 端口进行 DNS 查询。该查询遵循路由规则。不指定端口时,默认使用 53 端口。

    当值是 "tcp://host:port" 的形式,如 "tcp://8.8.8.8:53",Xray 会使用 DNS over TCP 进行查询。该查询遵循路由规则。不指定端口时,默认使用 53 端口。

    当值是 "tcp+local://host:port" 的形式,如 "tcp+local://8.8.8.8:53",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" 的形式,如 "quic+local://dns.adguard.com",Xray 会使用 DNS over QUIC 本地模式 (DOQL) 进行查询,即 DNS 请求不会经过路由组件,直接通过 Freedom outbound 对外请求。该方式需要 DNS 服务器支持 DNS over QUIC。默认使用 784 端口进行查询,可以使用非标端口。

    当值是 fakedns 时,将使用 FakeDNS 功能进行查询。

    TIP 1

    当使用 localhost 时,本机的 DNS 请求不受 Xray 控制,需要额外的配置才可以使 DNS 请求由 Xray 转发。

    TIP 2

    不同规则初始化得到的 DNS 客户端会在 Xray 启动日志中以 info 级别体现,比如 local DOHremote DOHudp 等模式。

    ',12),f={class:"custom-container tip"},v=a("p",{class:"custom-container-title"},"TIP 3",-1),x=l("(v1.4.0+) 可以在 "),O=l("日志"),j=l(" 中打开 DNS 查询日志。"),A=p('

    clientIp: string

    用于 DNS 查询时通知服务器以指定 IP 位置。不能是私有地址。

    TIP 1

    需要 DNS 服务器支持 EDNS Client Subnet。

    TIP 2

    可以在 DnsObject 为所有 DNS 服务器指定 clientIp, 也可在每个 DNS 服务器配置的 ServerObject 为此 DNS 服务器指定 clientIp (优先级高于 DnsObject 的配置)。

    queryStrategy: "UseIP" | "UseIPv4" | "UseIPv6"

    UseIPv4 只查询 A 记录;UseIPv6 只查询 AAAA 记录。默认值为 UseIP,即查询 A 和 AAAA 记录。

    disableCache: true | false

    true 禁用 DNS 缓存,默认为 false,即不禁用。

    disableFallback: true | false

    true 禁用 DNS 的 fallback 查询,默认为 false,即不禁用。

    disableFallbackIfMatch: true | false

    true 当 DNS 服务器的优先匹配域名列表命中时,禁用 fallback 查询,默认为 false,即不禁用。

    tag: string

    由内置 DNS 发出的查询流量,除 localhostfakednsTCPLDOHLDOQL 模式外,都可以用此标识在路由使用 inboundTag 进行匹配。

    ServerObject

    {\n  "address": "1.2.3.4",\n  "port": 5353,\n  "domains": ["domain:xray.com"],\n  "expectIPs": ["geoip:cn"],\n  "skipFallback": false,\n  "clientIP": "1.2.3.4"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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]

    ',29),F=l("一个域名列表,此列表包含的域名,将优先使用此服务器进行查询。域名格式和 "),T=l("路由配置"),X=l(" 中相同。"),w=a("blockquote",null,[a("p",null,[a("code",null,"expectIPs"),l(":[string]")])],-1),C=l("一个 IP 范围列表,格式和 "),H=l("路由配置"),U=l(" 中相同。"),L=a("p",null,"当配置此项时,Xray DNS 会对返回的 IP 的进行校验,只返回包含 expectIPs 列表中的地址。",-1),E=a("p",null,"如果未配置此项,会原样返回 IP 地址。",-1),Q=a("blockquote",null,[a("p",null,[a("code",null,"skipFallback"),l(": true | false")])],-1),_=a("p",null,[a("code",null,"true"),l(",在进行 DNS fallback 查询时将跳过此服务器, 默认为 "),a("code",null,"false"),l(",即不跳过。")],-1);u.render=function(p,l){const u=o("RouterLink");return s(),n(c,null,[d,a("ul",null,[r,i,q,k,a("li",null,[b,m,D,S,h,P,g,e(u,{to:"/config/routing.html#%E9%A2%84%E5%AE%9A%E4%B9%89%E5%9F%9F%E5%90%8D%E5%88%97%E8%A1%A8"},{default:t((()=>[I])),_:1}),N])]),y,a("div",f,[v,a("p",null,[x,e(u,{to:"/config/log.html"},{default:t((()=>[O])),_:1}),j])]),A,a("p",null,[F,e(u,{to:"/config/routing.html#ruleobject"},{default:t((()=>[T])),_:1}),X]),w,a("p",null,[C,e(u,{to:"/config/routing.html#ruleobject"},{default:t((()=>[H])),_:1}),U]),L,E,Q,_],64)};export default u; +import{r as o,o as s,c as n,a,b as e,w as t,F as c,d as p,e as l}from"./app.48111a85.js";const u={},d=p('

    内置 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 项。

    {\n  "dns": {\n    "hosts": {\n      "baidu.com": "127.0.0.1",\n      "dns.google": ["8.8.8.8", "8.8.4.4"]\n    },\n    "servers": [\n      "8.8.8.8",\n      "8.8.4.4",\n      {\n        "address": "1.2.3.4",\n        "port": 5353,\n        "domains": ["domain:xray.com"],\n        "expectIPs": ["geoip:cn"],\n        "skipFallback": false,\n        "clientIP": "1.2.3.4"\n      },\n      "localhost"\n    ],\n    "clientIp": "1.2.3.4",\n    "queryStrategy": "UseIP",\n    "disableCache": false,\n    "disableFallback": false,\n    "disableFallbackIfMatch": false,\n    "tag": "dns_inbound"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    hosts: map{string: address} | map{string: [address]}

    静态 IP 列表,其值为一系列的 "域名": "地址" 或 "域名": ["地址 1","地址 2"]。其中地址可以是 IP 或者域名。在解析域名时,如果域名匹配这个列表中的某一项:

    • 当该项的地址为 IP 时,则解析结果为该项的 IP
    • 当该项的地址为域名时,会使用此域名进行 IP 解析,而不使用原始域名。
    • 当地址中同时设置了多个 IP 和域名,则只会返回第一个域名,其余 IP 和域名均被忽略。

    域名的格式有以下几种形式:

    ',16),r=a("li",null,'纯字符串:当此字符串完整匹配目标域名时,该规则生效。例如 "xray.com" 匹配 "xray.com",但不匹配 "www.xray.com"。',-1),i=a("li",null,[l("正则表达式:由 "),a("code",null,'"regexp:"'),l(' 开始,余下部分是一个正则表达式。当此正则表达式匹配目标域名时,该规则生效。例如 "regexp:\\\\.goo.*\\\\.com$" 匹配 "www.google.com"、"fonts.googleapis.com",但不匹配 "google.com"。')],-1),q=a("li",null,[l("子域名 (推荐):由 "),a("code",null,'"domain:"'),l(' 开始,余下部分是一个域名。当此域名是目标域名或其子域名时,该规则生效。例如 "domain:xray.com" 匹配 "www.xray.com" 与 "xray.com",但不匹配 "wxray.com"。')],-1),k=a("li",null,[l("子串:由 "),a("code",null,'"keyword:"'),l(' 开始,余下部分是一个字符串。当此字符串匹配目标域名中任意部分,该规则生效。比如 "keyword:sina.com" 可以匹配 "sina.com"、"sina.com.cn" 和 "www.sina.com",但不匹配 "sina.cn"。')],-1),b=l("预定义域名列表:由 "),m=a("code",null,'"geosite:"',-1),D=l(" 开头,余下部分是一个名称,如 "),S=a("code",null,"geosite:google",-1),h=l(" 或者 "),P=a("code",null,"geosite:cn",-1),g=l("。名称及域名列表参考 "),I=l("预定义域名列表"),N=l("。"),y=p('

    servers: [string | ServerObject ]

    一个 DNS 服务器列表,支持的类型有两种:DNS 地址(字符串形式)和 ServerObject

    当值为 "localhost" 时,表示使用本机预设的 DNS 配置。

    当它的值是一个 DNS "IP:Port" 地址时,如 "8.8.8.8:53",Xray 会使用此地址的指定 UDP 端口进行 DNS 查询。该查询遵循路由规则。不指定端口时,默认使用 53 端口。

    当值是 "tcp://host:port" 的形式,如 "tcp://8.8.8.8:53",Xray 会使用 DNS over TCP 进行查询。该查询遵循路由规则。不指定端口时,默认使用 53 端口。

    当值是 "tcp+local://host:port" 的形式,如 "tcp+local://8.8.8.8:53",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" 的形式,如 "quic+local://dns.adguard.com",Xray 会使用 DNS over QUIC 本地模式 (DOQL) 进行查询,即 DNS 请求不会经过路由组件,直接通过 Freedom outbound 对外请求。该方式需要 DNS 服务器支持 DNS over QUIC。默认使用 784 端口进行查询,可以使用非标端口。

    当值是 fakedns 时,将使用 FakeDNS 功能进行查询。

    TIP 1

    当使用 localhost 时,本机的 DNS 请求不受 Xray 控制,需要额外的配置才可以使 DNS 请求由 Xray 转发。

    TIP 2

    不同规则初始化得到的 DNS 客户端会在 Xray 启动日志中以 info 级别体现,比如 local DOHremote DOHudp 等模式。

    ',12),f={class:"custom-container tip"},v=a("p",{class:"custom-container-title"},"TIP 3",-1),x=l("(v1.4.0+) 可以在 "),O=l("日志"),j=l(" 中打开 DNS 查询日志。"),A=p('

    clientIp: string

    用于 DNS 查询时通知服务器以指定 IP 位置。不能是私有地址。

    TIP 1

    需要 DNS 服务器支持 EDNS Client Subnet。

    TIP 2

    可以在 DnsObject 为所有 DNS 服务器指定 clientIp, 也可在每个 DNS 服务器配置的 ServerObject 为此 DNS 服务器指定 clientIp (优先级高于 DnsObject 的配置)。

    queryStrategy: "UseIP" | "UseIPv4" | "UseIPv6"

    UseIPv4 只查询 A 记录;UseIPv6 只查询 AAAA 记录。默认值为 UseIP,即查询 A 和 AAAA 记录。

    disableCache: true | false

    true 禁用 DNS 缓存,默认为 false,即不禁用。

    disableFallback: true | false

    true 禁用 DNS 的 fallback 查询,默认为 false,即不禁用。

    disableFallbackIfMatch: true | false

    true 当 DNS 服务器的优先匹配域名列表命中时,禁用 fallback 查询,默认为 false,即不禁用。

    tag: string

    由内置 DNS 发出的查询流量,除 localhostfakednsTCPLDOHLDOQL 模式外,都可以用此标识在路由使用 inboundTag 进行匹配。

    ServerObject

    {\n  "address": "1.2.3.4",\n  "port": 5353,\n  "domains": ["domain:xray.com"],\n  "expectIPs": ["geoip:cn"],\n  "skipFallback": false,\n  "clientIP": "1.2.3.4"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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]

    ',29),F=l("一个域名列表,此列表包含的域名,将优先使用此服务器进行查询。域名格式和 "),T=l("路由配置"),X=l(" 中相同。"),w=a("blockquote",null,[a("p",null,[a("code",null,"expectIPs"),l(":[string]")])],-1),C=l("一个 IP 范围列表,格式和 "),H=l("路由配置"),U=l(" 中相同。"),L=a("p",null,"当配置此项时,Xray DNS 会对返回的 IP 的进行校验,只返回包含 expectIPs 列表中的地址。",-1),E=a("p",null,"如果未配置此项,会原样返回 IP 地址。",-1),Q=a("blockquote",null,[a("p",null,[a("code",null,"skipFallback"),l(": true | false")])],-1),_=a("p",null,[a("code",null,"true"),l(",在进行 DNS fallback 查询时将跳过此服务器, 默认为 "),a("code",null,"false"),l(",即不跳过。")],-1);u.render=function(p,l){const u=o("RouterLink");return s(),n(c,null,[d,a("ul",null,[r,i,q,k,a("li",null,[b,m,D,S,h,P,g,e(u,{to:"/config/routing.html#%E9%A2%84%E5%AE%9A%E4%B9%89%E5%9F%9F%E5%90%8D%E5%88%97%E8%A1%A8"},{default:t((()=>[I])),_:1}),N])]),y,a("div",f,[v,a("p",null,[x,e(u,{to:"/config/log.html"},{default:t((()=>[O])),_:1}),j])]),A,a("p",null,[F,e(u,{to:"/config/routing.html#ruleobject"},{default:t((()=>[T])),_:1}),X]),w,a("p",null,[C,e(u,{to:"/config/routing.html#ruleobject"},{default:t((()=>[H])),_:1}),U]),L,E,Q,_],64)};export default u; diff --git a/assets/document.html.5f5222cc.js b/assets/document.html.510dc533.js similarity index 98% rename from assets/document.html.5f5222cc.js rename to assets/document.html.510dc533.js index b99c47440..ffb34045b 100644 --- a/assets/document.html.5f5222cc.js +++ b/assets/document.html.510dc533.js @@ -1 +1 @@ -import{r as e,o as t,c as r,a as n,b as o,F as l,e as a,d as s}from"./app.755d843f.js";const i={},u=n("h1",{id:"contribute-to-project-x-s-document",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#contribute-to-project-x-s-document","aria-hidden":"true"},"#"),a(" Contribute to Project X's Document")],-1),c=n("p",null,"Contributions to Project X's Document are welcome, and we appreciate every Contributor's contribution! You guys make Xray stronger!",-1),d=n("h2",{id:"improve-document",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#improve-document","aria-hidden":"true"},"#"),a(" Improve Document")],-1),h=a("Document for Project X is hosted on "),p={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},m=a("GitHub"),b=a("."),g=n("p",null,"You can submit your changes to the Document by following these steps:",-1),f=a("Open the repository from "),y={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},x=a("Project X Document"),v=a(", click fork in the upper right corner, fork a mirror image of the document repository to your own GitHub repository."),k=n("li",null,[n("p",null,"Get a clone of the docs from the repository you cloned using whatever tool you like, like:")],-1),X=s('
    git clone https://github.com/XTLS/Xray-docs-next.git\n
    1
    1. Create a new branch based on the main branch, such as:
    git checkout -b your-branch\n
    1
    ',3),P={start:"4"},j=n("li",null,[n("p",null,"Make changes on the new branch.")],-1),w=a("After modification, please use "),D={href:"https://prettier.io/docs/en/install.html",target:"_blank",rel:"noopener noreferrer"},q=a("Prettier"),L=a("Format your changes."),S=n("p",null,"Note: Pull requests with formatting issues may be rejected.",-1),_=n("li",null,[n("p",null,"Submit the changes and push them to your repository")],-1),C=n("div",{class:"language-text ext-text line-numbers-mode"},[n("pre",{class:"language-text"},[n("code",null,"git push -u origin your-branch\n")]),n("div",{class:"line-numbers"},[n("span",{class:"line-number"},"1"),n("br")])],-1),G={start:"6"},T=a("Open GitHub, click 'Pull request' to submit a pull request to "),F={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},H=a("Project X Document"),O=a("."),I=n("li",null,[n("p",null,"Please outline the new/modified content of this pull request in the title and body of the pull request;")],-1),W=a("Waiting for a response, if the pull request is merged, your changes will be directly displayed on "),Y={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},A=a("Project X Document Website"),M=a("."),N=n("h2",{id:"found-problems",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#found-problems","aria-hidden":"true"},"#"),a(" Found Problems?")],-1),z=n("p",null,"If you find an error in the document, you can improve the documentation or submit an issue.",-1);i.render=function(a,s){const i=e("OutboundLink");return t(),r(l,null,[u,c,d,n("p",null,[h,n("a",p,[m,o(i)]),b]),g,n("ol",null,[n("li",null,[n("p",null,[f,n("a",y,[x,o(i)]),v])]),k]),X,n("ol",P,[j,n("li",null,[n("p",null,[w,n("a",D,[q,o(i)]),L]),S]),_]),C,n("ol",G,[n("li",null,[n("p",null,[T,n("a",F,[H,o(i)]),O])]),I,n("li",null,[n("p",null,[W,n("a",Y,[A,o(i)]),M])])]),N,z],64)};export default i; +import{r as e,o as t,c as r,a as n,b as o,F as l,e as a,d as s}from"./app.48111a85.js";const i={},u=n("h1",{id:"contribute-to-project-x-s-document",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#contribute-to-project-x-s-document","aria-hidden":"true"},"#"),a(" Contribute to Project X's Document")],-1),c=n("p",null,"Contributions to Project X's Document are welcome, and we appreciate every Contributor's contribution! You guys make Xray stronger!",-1),d=n("h2",{id:"improve-document",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#improve-document","aria-hidden":"true"},"#"),a(" Improve Document")],-1),h=a("Document for Project X is hosted on "),p={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},m=a("GitHub"),b=a("."),g=n("p",null,"You can submit your changes to the Document by following these steps:",-1),f=a("Open the repository from "),y={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},x=a("Project X Document"),v=a(", click fork in the upper right corner, fork a mirror image of the document repository to your own GitHub repository."),k=n("li",null,[n("p",null,"Get a clone of the docs from the repository you cloned using whatever tool you like, like:")],-1),X=s('
    git clone https://github.com/XTLS/Xray-docs-next.git\n
    1
    1. Create a new branch based on the main branch, such as:
    git checkout -b your-branch\n
    1
    ',3),P={start:"4"},j=n("li",null,[n("p",null,"Make changes on the new branch.")],-1),w=a("After modification, please use "),D={href:"https://prettier.io/docs/en/install.html",target:"_blank",rel:"noopener noreferrer"},q=a("Prettier"),L=a("Format your changes."),S=n("p",null,"Note: Pull requests with formatting issues may be rejected.",-1),_=n("li",null,[n("p",null,"Submit the changes and push them to your repository")],-1),C=n("div",{class:"language-text ext-text line-numbers-mode"},[n("pre",{class:"language-text"},[n("code",null,"git push -u origin your-branch\n")]),n("div",{class:"line-numbers"},[n("span",{class:"line-number"},"1"),n("br")])],-1),G={start:"6"},T=a("Open GitHub, click 'Pull request' to submit a pull request to "),F={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},H=a("Project X Document"),O=a("."),I=n("li",null,[n("p",null,"Please outline the new/modified content of this pull request in the title and body of the pull request;")],-1),W=a("Waiting for a response, if the pull request is merged, your changes will be directly displayed on "),Y={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},A=a("Project X Document Website"),M=a("."),N=n("h2",{id:"found-problems",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#found-problems","aria-hidden":"true"},"#"),a(" Found Problems?")],-1),z=n("p",null,"If you find an error in the document, you can improve the documentation or submit an issue.",-1);i.render=function(a,s){const i=e("OutboundLink");return t(),r(l,null,[u,c,d,n("p",null,[h,n("a",p,[m,o(i)]),b]),g,n("ol",null,[n("li",null,[n("p",null,[f,n("a",y,[x,o(i)]),v])]),k]),X,n("ol",P,[j,n("li",null,[n("p",null,[w,n("a",D,[q,o(i)]),L]),S]),_]),C,n("ol",G,[n("li",null,[n("p",null,[T,n("a",F,[H,o(i)]),O])]),I,n("li",null,[n("p",null,[W,n("a",Y,[A,o(i)]),M])])]),N,z],64)};export default i; diff --git a/assets/document.html.548ebf63.js b/assets/document.html.f914c675.js similarity index 98% rename from assets/document.html.548ebf63.js rename to assets/document.html.f914c675.js index 19e715f95..0f7d726a6 100644 --- a/assets/document.html.548ebf63.js +++ b/assets/document.html.f914c675.js @@ -1 +1 @@ -import{r as e,o as r,c as l,a as n,b as t,F as a,e as s,d as o}from"./app.755d843f.js";const i={},u=n("h1",{id:"为-project-x-的文档贡献",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#为-project-x-的文档贡献","aria-hidden":"true"},"#"),s(" 为 Project X 的文档贡献")],-1),c=n("p",null,"欢迎您为 Project X 的文档做出贡献,我们感谢每一位 Contributor 的贡献!是你们让 Xray 更加强大!",-1),p=n("h2",{id:"改进文档",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#改进文档","aria-hidden":"true"},"#"),s(" 改进文档")],-1),d=s("Project X 的文档托管在 "),h={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},b=s("GitHub"),g=s(" 上."),x=n("p",null,"您可以通过以下步骤, 提交您对文档的改动:",-1),m=s("从 "),f={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},X=s("project X 文档仓库"),P=s(" 打开仓库, 点击右上角的 fork, fork 一份文档仓库的镜像到您自己的 github 仓库."),k=n("li",null,[n("p",null,"使用任何您喜欢的工具, 从您克隆的仓库获得文档的克隆, 如:")],-1),v=o('
    git clone https://github.com/XTLS/Xray-docs-next.git\n
    1
    1. 基于 main 分支创建新的分支, 如:
    git checkout -b your-branch\n
    1
    ',3),j={start:"4"},y=n("p",null,"在新分支上做修改。",-1),_=s("注:推荐 "),L={href:"https://github.com/sparanoid/chinese-copywriting-guidelines",target:"_blank",rel:"noopener noreferrer"},R=s("中文文案排版指北"),S=s("修改完成后,请使用 "),T={href:"https://prettier.io/docs/en/install.html",target:"_blank",rel:"noopener noreferrer"},G=s("Prettier"),H=s(" 格式化您的更改。"),q=n("p",null,"注:存在格式问题的 PR,将有可能被拒绝。",-1),w=n("li",null,[n("p",null,"提交修改,并推送到您的仓库中")],-1),C=n("div",{class:"language-text ext-text line-numbers-mode"},[n("pre",{class:"language-text"},[n("code",null,"git push -u origin your-branch\n")]),n("div",{class:"line-numbers"},[n("span",{class:"line-number"},"1"),n("br")])],-1),F={start:"6"},I=s("打开 GitHub, 点击 'Pull request' 向 "),O={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},z=s("project X 文档仓库"),A=s(" 提交 PR。"),B=n("li",null,[n("p",null,"请在 PR 的标题和正文中,概述此次 PR 新增/修改的内容等;")],-1),D=s("等待回应, 如果 PR 被 merge, 您做的修改将直接呈现在 "),E={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},J=s("Project X 文档网站"),K=s("。"),M=n("h2",{id:"发现问题",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#发现问题","aria-hidden":"true"},"#"),s(" 发现问题?")],-1),N=n("p",null,"如果您发现文档出错,可以改进文档或提交一个 Issue。",-1);i.render=function(s,o){const i=e("OutboundLink");return r(),l(a,null,[u,c,p,n("p",null,[d,n("a",h,[b,t(i)]),g]),x,n("ol",null,[n("li",null,[n("p",null,[m,n("a",f,[X,t(i)]),P])]),k]),v,n("ol",j,[n("li",null,[y,n("p",null,[_,n("a",L,[R,t(i)])])]),n("li",null,[n("p",null,[S,n("a",T,[G,t(i)]),H]),q]),w]),C,n("ol",F,[n("li",null,[n("p",null,[I,n("a",O,[z,t(i)]),A])]),B,n("li",null,[n("p",null,[D,n("a",E,[J,t(i)]),K])])]),M,N],64)};export default i; +import{r as e,o as r,c as l,a as n,b as t,F as a,e as s,d as o}from"./app.48111a85.js";const i={},u=n("h1",{id:"为-project-x-的文档贡献",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#为-project-x-的文档贡献","aria-hidden":"true"},"#"),s(" 为 Project X 的文档贡献")],-1),c=n("p",null,"欢迎您为 Project X 的文档做出贡献,我们感谢每一位 Contributor 的贡献!是你们让 Xray 更加强大!",-1),p=n("h2",{id:"改进文档",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#改进文档","aria-hidden":"true"},"#"),s(" 改进文档")],-1),d=s("Project X 的文档托管在 "),h={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},b=s("GitHub"),g=s(" 上."),x=n("p",null,"您可以通过以下步骤, 提交您对文档的改动:",-1),m=s("从 "),f={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},X=s("project X 文档仓库"),P=s(" 打开仓库, 点击右上角的 fork, fork 一份文档仓库的镜像到您自己的 github 仓库."),k=n("li",null,[n("p",null,"使用任何您喜欢的工具, 从您克隆的仓库获得文档的克隆, 如:")],-1),v=o('
    git clone https://github.com/XTLS/Xray-docs-next.git\n
    1
    1. 基于 main 分支创建新的分支, 如:
    git checkout -b your-branch\n
    1
    ',3),j={start:"4"},y=n("p",null,"在新分支上做修改。",-1),_=s("注:推荐 "),L={href:"https://github.com/sparanoid/chinese-copywriting-guidelines",target:"_blank",rel:"noopener noreferrer"},R=s("中文文案排版指北"),S=s("修改完成后,请使用 "),T={href:"https://prettier.io/docs/en/install.html",target:"_blank",rel:"noopener noreferrer"},G=s("Prettier"),H=s(" 格式化您的更改。"),q=n("p",null,"注:存在格式问题的 PR,将有可能被拒绝。",-1),w=n("li",null,[n("p",null,"提交修改,并推送到您的仓库中")],-1),C=n("div",{class:"language-text ext-text line-numbers-mode"},[n("pre",{class:"language-text"},[n("code",null,"git push -u origin your-branch\n")]),n("div",{class:"line-numbers"},[n("span",{class:"line-number"},"1"),n("br")])],-1),F={start:"6"},I=s("打开 GitHub, 点击 'Pull request' 向 "),O={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},z=s("project X 文档仓库"),A=s(" 提交 PR。"),B=n("li",null,[n("p",null,"请在 PR 的标题和正文中,概述此次 PR 新增/修改的内容等;")],-1),D=s("等待回应, 如果 PR 被 merge, 您做的修改将直接呈现在 "),E={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},J=s("Project X 文档网站"),K=s("。"),M=n("h2",{id:"发现问题",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#发现问题","aria-hidden":"true"},"#"),s(" 发现问题?")],-1),N=n("p",null,"如果您发现文档出错,可以改进文档或提交一个 Issue。",-1);i.render=function(s,o){const i=e("OutboundLink");return r(),l(a,null,[u,c,p,n("p",null,[d,n("a",h,[b,t(i)]),g]),x,n("ol",null,[n("li",null,[n("p",null,[m,n("a",f,[X,t(i)]),P])]),k]),v,n("ol",j,[n("li",null,[y,n("p",null,[_,n("a",L,[R,t(i)])])]),n("li",null,[n("p",null,[S,n("a",T,[G,t(i)]),H]),q]),w]),C,n("ol",F,[n("li",null,[n("p",null,[I,n("a",O,[z,t(i)]),A])]),B,n("li",null,[n("p",null,[D,n("a",E,[J,t(i)]),K])])]),M,N],64)};export default i; diff --git a/assets/dokodemo.html.75d80861.js b/assets/dokodemo.html.d7b30331.js similarity index 93% rename from assets/dokodemo.html.75d80861.js rename to assets/dokodemo.html.d7b30331.js index b2df934d8..82ad0d74c 100644 --- a/assets/dokodemo.html.75d80861.js +++ b/assets/dokodemo.html.d7b30331.js @@ -1 +1 @@ -import{r as e,o,c as n,a as t,b as a,w as s,F as r,d as p,e as c}from"./app.755d843f.js";const l={},i=p('

    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

    {\n  "address": "8.8.8.8",\n  "port": 53,\n  "network": "tcp",\n  "timeout": 0,\n  "followRedirect": false,\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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.

    ',15),u=c("Refer to the "),d=t("code",null,"tproxy",-1),f=c(" setting in the "),h=c("Transport Configuration"),b=c(" for more information."),m=t("blockquote",null,[t("p",null,[t("code",null,"userLevel"),c(": number")])],-1),k=c("The user level that the connection will use to determine the corresponding "),q=c("Local Policy"),g=c("."),y=c("The value of "),v=t("code",null,"userLevel",-1),w=c(" corresponds to the value of "),x=t("code",null,"level",-1),T=c(" in the "),j=c("policy"),I=c(". If not specified, the default value is 0."),P=t("h2",{id:"transparent-proxy-configuration-example",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#transparent-proxy-configuration-example","aria-hidden":"true"},"#"),c(" Transparent Proxy Configuration Example")],-1),C=t("p",null,[c("Please refer to the "),t("a",{href:"../../document/level-2/tproxy"},"Transparent Proxy (TProxy) Configuration Tutorial"),c(" for this section.")],-1);l.render=function(p,c){const l=e("RouterLink");return o(),n(r,null,[i,t("p",null,[u,d,f,a(l,{to:"/en/config/transport.html#sockoptobject"},{default:s((()=>[h])),_:1}),b]),m,t("p",null,[k,a(l,{to:"/en/config/policy.html#levelpolicyobject"},{default:s((()=>[q])),_:1}),g]),t("p",null,[y,v,w,x,T,a(l,{to:"/en/config/policy.html#policyobject"},{default:s((()=>[j])),_:1}),I]),P,C],64)};export default l; +import{r as e,o,c as n,a as t,b as a,w as s,F as r,d as p,e as c}from"./app.48111a85.js";const l={},i=p('

    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

    {\n  "address": "8.8.8.8",\n  "port": 53,\n  "network": "tcp",\n  "timeout": 0,\n  "followRedirect": false,\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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.

    ',15),u=c("Refer to the "),d=t("code",null,"tproxy",-1),h=c(" setting in the "),b=c("Transport Configuration"),f=c(" for more information."),m=t("blockquote",null,[t("p",null,[t("code",null,"userLevel"),c(": number")])],-1),k=c("The user level that the connection will use to determine the corresponding "),q=c("Local Policy"),g=c("."),y=c("The value of "),v=t("code",null,"userLevel",-1),w=c(" corresponds to the value of "),x=t("code",null,"level",-1),T=c(" in the "),j=c("policy"),I=c(". If not specified, the default value is 0."),P=t("h2",{id:"transparent-proxy-configuration-example",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#transparent-proxy-configuration-example","aria-hidden":"true"},"#"),c(" Transparent Proxy Configuration Example")],-1),C=t("p",null,[c("Please refer to the "),t("a",{href:"../../document/level-2/tproxy"},"Transparent Proxy (TProxy) Configuration Tutorial"),c(" for this section.")],-1);l.render=function(p,c){const l=e("RouterLink");return o(),n(r,null,[i,t("p",null,[u,d,h,a(l,{to:"/en/config/transport.html#sockoptobject"},{default:s((()=>[b])),_:1}),f]),m,t("p",null,[k,a(l,{to:"/en/config/policy.html#levelpolicyobject"},{default:s((()=>[q])),_:1}),g]),t("p",null,[y,v,w,x,T,a(l,{to:"/en/config/policy.html#policyobject"},{default:s((()=>[j])),_:1}),I]),P,C],64)};export default l; diff --git a/assets/dokodemo.html.7b8ceccc.js b/assets/dokodemo.html.fab4abcc.js similarity index 98% rename from assets/dokodemo.html.7b8ceccc.js rename to assets/dokodemo.html.fab4abcc.js index bcfac2d11..e56007fac 100644 --- a/assets/dokodemo.html.7b8ceccc.js +++ b/assets/dokodemo.html.fab4abcc.js @@ -1 +1 @@ -import{r as o,o as e,c as n,a as s,b as a,w as t,F as p,d as c,e as l}from"./app.755d843f.js";const u={},r=c('

    Dokodemo-Door

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

    InboundConfigurationObject

    {\n  "address": "8.8.8.8",\n  "port": 53,\n  "network": "tcp",\n  "timeout": 0,\n  "followRedirect": false,\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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 转发而来的数据,并转发到相应的目标地址。

    ',15),d=l("可参考 "),i=l("传输配置"),b=l(" 中的 "),k=s("code",null,"tproxy",-1),q=l(" 设置。"),m=s("blockquote",null,[s("p",null,[s("code",null,"userLevel"),l(": number")])],-1),f=l("用户等级,连接会使用这个用户等级对应的 "),h=l("本地策略"),y=l("。"),g=l("userLevel 的值, 对应 "),j=l("policy"),v=l(" 中 "),x=s("code",null,"level",-1),w=l(" 的值. 如不指定, 默认为 0。"),L=s("h2",{id:"透明代理配置样例",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#透明代理配置样例","aria-hidden":"true"},"#"),l(" 透明代理配置样例")],-1),R=s("p",null,[l("此部分请参考"),s("a",{href:"../../document/level-2/tproxy"},"透明代理(TProxy)配置教程"),l("。")],-1);u.render=function(c,l){const u=o("RouterLink");return e(),n(p,null,[r,s("p",null,[d,a(u,{to:"/config/transport.html#sockoptobject"},{default:t((()=>[i])),_:1}),b,k,q]),m,s("p",null,[f,a(u,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[h])),_:1}),y]),s("p",null,[g,a(u,{to:"/config/policy.html#policyobject"},{default:t((()=>[j])),_:1}),v,x,w]),L,R],64)};export default u; +import{r as o,o as e,c as n,a as s,b as a,w as t,F as p,d as c,e as l}from"./app.48111a85.js";const u={},r=c('

    Dokodemo-Door

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

    InboundConfigurationObject

    {\n  "address": "8.8.8.8",\n  "port": 53,\n  "network": "tcp",\n  "timeout": 0,\n  "followRedirect": false,\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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 转发而来的数据,并转发到相应的目标地址。

    ',15),d=l("可参考 "),i=l("传输配置"),b=l(" 中的 "),k=s("code",null,"tproxy",-1),q=l(" 设置。"),m=s("blockquote",null,[s("p",null,[s("code",null,"userLevel"),l(": number")])],-1),f=l("用户等级,连接会使用这个用户等级对应的 "),h=l("本地策略"),y=l("。"),g=l("userLevel 的值, 对应 "),j=l("policy"),v=l(" 中 "),x=s("code",null,"level",-1),w=l(" 的值. 如不指定, 默认为 0。"),L=s("h2",{id:"透明代理配置样例",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#透明代理配置样例","aria-hidden":"true"},"#"),l(" 透明代理配置样例")],-1),R=s("p",null,[l("此部分请参考"),s("a",{href:"../../document/level-2/tproxy"},"透明代理(TProxy)配置教程"),l("。")],-1);u.render=function(c,l){const u=o("RouterLink");return e(),n(p,null,[r,s("p",null,[d,a(u,{to:"/config/transport.html#sockoptobject"},{default:t((()=>[i])),_:1}),b,k,q]),m,s("p",null,[f,a(u,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[h])),_:1}),y]),s("p",null,[g,a(u,{to:"/config/policy.html#policyobject"},{default:t((()=>[j])),_:1}),v,x,w]),L,R],64)};export default u; diff --git a/assets/domainsocket.html.1d68f776.js b/assets/domainsocket.html.00afb2a2.js similarity index 94% rename from assets/domainsocket.html.1d68f776.js rename to assets/domainsocket.html.00afb2a2.js index d61ee8850..8301c80fc 100644 --- a/assets/domainsocket.html.1d68f776.js +++ b/assets/domainsocket.html.00afb2a2.js @@ -1 +1 @@ -import{r as a,o as n,c as s,a as o,b as e,w as t,F as c,e as p,d as i}from"./app.755d843f.js";const l={},d=o("h1",{id:"domain-socket",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#domain-socket","aria-hidden":"true"},"#"),p(" Domain Socket")],-1),r={class:"custom-container danger"},u=o("p",{class:"custom-container-title"},"警告",-1),k=p("推荐写到 "),b=p("inbounds"),m=p(" 的 "),f=o("code",null,"listen",-1),h=p(" 处,传输方式可选 TCP、WebSocket、HTTP/2. 未来这里的 DomainSocket 可能会被弃用。"),q=i('

    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 项。

    {\n  "path": "/path/to/ds/file",\n  "abstract": false,\n  "padding": false\n}\n
    1
    2
    3
    4
    5

    path: string

    一个合法的文件路径。

    警告

    在运行 Xray 之前,这个文件必须不存在。

    abstract: true | false

    是否为 abstract domain socket,默认值 false

    padding: true | false

    abstract domain socket 是否带 padding,默认值 false

    ',14);l.render=function(p,i){const l=a("RouterLink");return n(),s(c,null,[d,o("div",r,[u,o("p",null,[k,e(l,{to:"/config/inbound.html"},{default:t((()=>[b])),_:1}),m,f,h])]),q],64)};export default l; +import{r as a,o as n,c as s,a as o,b as e,w as t,F as c,e as p,d as i}from"./app.48111a85.js";const l={},d=o("h1",{id:"domain-socket",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#domain-socket","aria-hidden":"true"},"#"),p(" Domain Socket")],-1),r={class:"custom-container danger"},u=o("p",{class:"custom-container-title"},"警告",-1),k=p("推荐写到 "),b=p("inbounds"),m=p(" 的 "),h=o("code",null,"listen",-1),f=p(" 处,传输方式可选 TCP、WebSocket、HTTP/2. 未来这里的 DomainSocket 可能会被弃用。"),q=i('

    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 项。

    {\n  "path": "/path/to/ds/file",\n  "abstract": false,\n  "padding": false\n}\n
    1
    2
    3
    4
    5

    path: string

    一个合法的文件路径。

    警告

    在运行 Xray 之前,这个文件必须不存在。

    abstract: true | false

    是否为 abstract domain socket,默认值 false

    padding: true | false

    abstract domain socket 是否带 padding,默认值 false

    ',14);l.render=function(p,i){const l=a("RouterLink");return n(),s(c,null,[d,o("div",r,[u,o("p",null,[k,e(l,{to:"/config/inbound.html"},{default:t((()=>[b])),_:1}),m,h,f])]),q],64)};export default l; diff --git a/assets/domainsocket.html.bdccc3c0.js b/assets/domainsocket.html.77773eed.js similarity index 97% rename from assets/domainsocket.html.bdccc3c0.js rename to assets/domainsocket.html.77773eed.js index 42d2f9180..df7f3838c 100644 --- a/assets/domainsocket.html.bdccc3c0.js +++ b/assets/domainsocket.html.77773eed.js @@ -1 +1 @@ -import{r as a,o as e,c as n,a as t,b as s,w as o,F as c,e as i,d as p}from"./app.755d843f.js";const r={},l=t("h1",{id:"domain-socket",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#domain-socket","aria-hidden":"true"},"#"),i(" Domain Socket")],-1),d={class:"custom-container danger"},u=t("p",{class:"custom-container-title"},"Danger",-1),h=i("We recommend writing it to the "),b=t("code",null,"listen",-1),m=i(" field in "),k=i("inbounds"),f=i("and the transport mode can be TCP, WebSocket, or HTTP/2."),g=t("p",null,"Note that the DomainSocket option here may be deprecated in the future.",-1),q=p('

    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.

    {\n  "path": "/path/to/ds/file",\n  "abstract": false,\n  "padding": false\n}\n
    1
    2
    3
    4
    5

    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.

    ',14);r.render=function(i,p){const r=a("RouterLink");return e(),n(c,null,[l,t("div",d,[u,t("p",null,[h,b,m,s(r,{to:"/en/config/inbound.html"},{default:o((()=>[k])),_:1}),f]),g]),q],64)};export default r; +import{r as a,o as e,c as n,a as t,b as s,w as o,F as c,e as i,d as p}from"./app.48111a85.js";const r={},l=t("h1",{id:"domain-socket",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#domain-socket","aria-hidden":"true"},"#"),i(" Domain Socket")],-1),d={class:"custom-container danger"},u=t("p",{class:"custom-container-title"},"Danger",-1),h=i("We recommend writing it to the "),b=t("code",null,"listen",-1),m=i(" field in "),k=i("inbounds"),f=i("and the transport mode can be TCP, WebSocket, or HTTP/2."),g=t("p",null,"Note that the DomainSocket option here may be deprecated in the future.",-1),q=p('

    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.

    {\n  "path": "/path/to/ds/file",\n  "abstract": false,\n  "padding": false\n}\n
    1
    2
    3
    4
    5

    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.

    ',14);r.render=function(i,p){const r=a("RouterLink");return e(),n(c,null,[l,t("div",d,[u,t("p",null,[h,b,m,s(r,{to:"/en/config/inbound.html"},{default:o((()=>[k])),_:1}),f]),g]),q],64)};export default r; diff --git a/assets/edges-97052da4.ceadb26f.js b/assets/edges-97052da4.e255927b.js similarity index 99% rename from assets/edges-97052da4.ceadb26f.js rename to assets/edges-97052da4.e255927b.js index 38991c531..8a56e06c8 100644 --- a/assets/edges-97052da4.ceadb26f.js +++ b/assets/edges-97052da4.e255927b.js @@ -1 +1 @@ -import{q as t,c as e,d as r,a4 as a,h as n,l as i,y as s,a5 as l}from"./mermaid.core.a66200b0.js";import{c as o}from"./createText-2f679d62.584f3edd.js";import{p as d}from"./svgDraw-6750006d.4f7863f3.js";import{l as c}from"./line.f17bed9e.js";const h={extension:(t,e,r)=>{i.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",e+"-extensionStart").attr("class","marker extension "+e).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"),t.append("defs").append("marker").attr("id",e+"-extensionEnd").attr("class","marker extension "+e).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")},composition:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-compositionStart").attr("class","marker composition "+e).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"),t.append("defs").append("marker").attr("id",e+"-compositionEnd").attr("class","marker composition "+e).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")},aggregation:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-aggregationStart").attr("class","marker aggregation "+e).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"),t.append("defs").append("marker").attr("id",e+"-aggregationEnd").attr("class","marker aggregation "+e).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")},dependency:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-dependencyStart").attr("class","marker dependency "+e).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"),t.append("defs").append("marker").attr("id",e+"-dependencyEnd").attr("class","marker dependency "+e).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")},lollipop:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","white").attr("cx",6).attr("cy",7).attr("r",6)},point:(t,e)=>{t.append("marker").attr("id",e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",10).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"),t.append("marker").attr("id",e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",0).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")},circle:(t,e)=>{t.append("marker").attr("id",e+"-circleEnd").attr("class","marker "+e).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"),t.append("marker").attr("id",e+"-circleStart").attr("class","marker "+e).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")},cross:(t,e)=>{t.append("marker").attr("id",e+"-crossEnd").attr("class","marker cross "+e).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"),t.append("marker").attr("id",e+"-crossStart").attr("class","marker cross "+e).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")},barb:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-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")}},p=(t,e,r,a)=>{e.forEach((e=>{h[e](t,r,a)}))};const g=(r,s,l,o)=>{let d=r||"";if("object"==typeof d&&(d=d[0]),t(e().flowchart.htmlLabels)){d=d.replace(/\\n|\n/g,"
    "),i.info("vertexText"+d);return function(t){const e=n(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),a=t.label,i=t.isNode?"nodeLabel":"edgeLabel";var s,l;return r.html('"+a+""),s=r,(l=t.labelStyle)&&s.attr("style",l),r.style("display","inline-block"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}({isNode:o,label:a(d).replace(/fa[blrs]?:fa-[\w-]+/g,(t=>``)),labelStyle:s.replace("fill:","color:")})}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",s.replace("color:","fill:"));let e=[];e="string"==typeof d?d.split(/\\n|\n|/gi):Array.isArray(d)?d:[];for(const r of e){const e=document.createElementNS("http://www.w3.org/2000/svg","tspan");e.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),e.setAttribute("dy","1em"),e.setAttribute("x","0"),l?e.setAttribute("class","title-row"):e.setAttribute("class","row"),e.textContent=r.trim(),t.appendChild(e)}return t}},y=async(i,s,l,d)=>{let c;const h=s.useHtmlLabels||t(e().flowchart.htmlLabels);c=l||"node default";const p=i.insert("g").attr("class",c).attr("id",s.domId||s.id),y=p.insert("g").attr("class","label").attr("style",s.labelStyle);let f;f=void 0===s.labelText?"":"string"==typeof s.labelText?s.labelText:s.labelText[0];const b=y.node();let w;w="markdown"===s.labelType?o(y,r(a(f),e()),{useHtmlLabels:h,width:s.width||e().flowchart.wrappingWidth,classes:"markdown-node-label"}):b.appendChild(g(r(a(f),e()),s.labelStyle,!1,d));let u=w.getBBox();const x=s.padding/2;if(t(e().flowchart.htmlLabels)){const t=w.children[0],r=n(w),a=t.getElementsByTagName("img");if(a){const t=""===f.replace(/]*>/g,"").trim();await Promise.all([...a].map((r=>new Promise((a=>r.addEventListener("load",(function(){if(r.style.display="flex",r.style.flexDirection="column",t){const t=e().fontSize?e().fontSize:window.getComputedStyle(document.body).fontSize,a=5;r.style.width=parseInt(t,10)*a+"px"}else r.style.width="100%";a(r)})))))))}u=t.getBoundingClientRect(),r.attr("width",u.width),r.attr("height",u.height)}return h?y.attr("transform","translate("+-u.width/2+", "+-u.height/2+")"):y.attr("transform","translate(0, "+-u.height/2+")"),s.centerLabel&&y.attr("transform","translate("+-u.width/2+", "+-u.height/2+")"),y.insert("rect",":first-child"),{shapeSvg:p,bbox:u,halfPadding:x,label:y}},f=(t,e)=>{const r=e.node().getBBox();t.width=r.width,t.height=r.height};function b(t,e,r,a){return t.insert("polygon",":first-child").attr("points",a.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}function w(t,e,r,a){var n=t.x,i=t.y,s=n-a.x,l=i-a.y,o=Math.sqrt(e*e*l*l+r*r*s*s),d=Math.abs(e*r*s/o);a.x0}const m=(t,e)=>{var r,a,n=t.x,i=t.y,s=e.x-n,l=e.y-i,o=t.width/2,d=t.height/2;return Math.abs(l)*o>Math.abs(s)*d?(l<0&&(d=-d),r=0===l?0:d*s/l,a=d):(s<0&&(o=-o),r=o,a=0===s?0:o*l/s),{x:n+r,y:i+a}},k={node:function(t,e){return t.intersect(e)},circle:function(t,e,r){return w(t,e,e,r)},ellipse:w,polygon:function(t,e,r){var a=t.x,n=t.y,i=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach((function(t){s=Math.min(s,t.x),l=Math.min(l,t.y)})):(s=Math.min(s,e.x),l=Math.min(l,e.y));for(var o=a-t.width/2-s,d=n-t.height/2-l,c=0;c1&&i.sort((function(t,e){var a=t.x-r.x,n=t.y-r.y,i=Math.sqrt(a*a+n*n),s=e.x-r.x,l=e.y-r.y,o=Math.sqrt(s*s+l*l);return i{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding+(a.height+e.padding),s=[{x:n/2,y:0},{x:n,y:-n/2},{x:n/2,y:-n},{x:0,y:-n/2}];i.info("Question main (Circle)");const l=b(r,n,n,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return i.warn("Intersect called"),k.polygon(e,s,t)},r};function S(t,e,r,a){const n=[],s=t=>{n.push(t,0)},l=t=>{n.push(0,t)};e.includes("t")?(i.debug("add top border"),s(r)):l(r),e.includes("r")?(i.debug("add right border"),s(a)):l(a),e.includes("b")?(i.debug("add bottom border"),s(r)):l(r),e.includes("l")?(i.debug("add left border"),s(a)):l(a),t.attr("stroke-dasharray",n.join(" "))}const v=(t,e,r)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let n=70,i=10;"LR"===r&&(n=10,i=70);const s=a.append("rect").attr("x",-1*n/2).attr("y",-1*i/2).attr("width",n).attr("height",i).attr("class","fork-join");return f(e,s),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(t){return k.rect(e,t)},a},M={rhombus:L,question:L,rect:async(t,e)=>{const{shapeSvg:r,bbox:a,halfPadding:n}=await y(t,e,"node "+e.classes,!0),s=r.insert("rect",":first-child"),l=a.width+e.padding,o=a.height+e.padding;if(s.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",-a.width/2-n).attr("y",-a.height/2-n).attr("width",l).attr("height",o),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(S(s,e.props.borders,l,o),t.delete("borders")),t.forEach((t=>{i.warn(`Unknown node property ${t}`)}))}return f(e,s),e.intersect=function(t){return k.rect(e,t)},r},labelRect:async(t,e)=>{const{shapeSvg:r}=await y(t,e,"label",!0);i.trace("Classes = ",e.classes);const a=r.insert("rect",":first-child");if(a.attr("width",0).attr("height",0),r.attr("class","label edgeLabel"),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(S(a,e.props.borders,0,0),t.delete("borders")),t.forEach((t=>{i.warn(`Unknown node property ${t}`)}))}return f(e,a),e.intersect=function(t){return k.rect(e,t)},r},rectWithTitle:(r,a)=>{let s;s=a.classes?"node "+a.classes:"node default";const l=r.insert("g").attr("class",s).attr("id",a.domId||a.id),o=l.insert("rect",":first-child"),d=l.insert("line"),c=l.insert("g").attr("class","label"),h=a.labelText.flat?a.labelText.flat():a.labelText;let p="";p="object"==typeof h?h[0]:h,i.info("Label text abc79",p,h,"object"==typeof h);const y=c.node().appendChild(g(p,a.labelStyle,!0,!0));let b={width:0,height:0};if(t(e().flowchart.htmlLabels)){const t=y.children[0],e=n(y);b=t.getBoundingClientRect(),e.attr("width",b.width),e.attr("height",b.height)}i.info("Text 2",h);const w=h.slice(1,h.length);let u=y.getBBox();const x=c.node().appendChild(g(w.join?w.join("
    "):w,a.labelStyle,!0,!0));if(t(e().flowchart.htmlLabels)){const t=x.children[0],e=n(x);b=t.getBoundingClientRect(),e.attr("width",b.width),e.attr("height",b.height)}const m=a.padding/2;return n(x).attr("transform","translate( "+(b.width>u.width?0:(u.width-b.width)/2)+", "+(u.height+m+5)+")"),n(y).attr("transform","translate( "+(b.width{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=[{x:0,y:14},{x:14,y:0},{x:0,y:-14},{x:-14,y:0}];return r.insert("polygon",":first-child").attr("points",a.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(t){return k.circle(e,14,t)},r},circle:async(t,e)=>{const{shapeSvg:r,bbox:a,halfPadding:n}=await y(t,e,void 0,!0),s=r.insert("circle",":first-child");return s.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",a.width/2+n).attr("width",a.width+e.padding).attr("height",a.height+e.padding),i.info("Circle main"),f(e,s),e.intersect=function(t){return i.info("Circle intersect",e,a.width/2+n,t),k.circle(e,a.width/2+n,t)},r},doublecircle:async(t,e)=>{const{shapeSvg:r,bbox:a,halfPadding:n}=await y(t,e,void 0,!0),s=r.insert("g",":first-child"),l=s.insert("circle"),o=s.insert("circle");return l.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",a.width/2+n+5).attr("width",a.width+e.padding+10).attr("height",a.height+e.padding+10),o.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",a.width/2+n).attr("width",a.width+e.padding).attr("height",a.height+e.padding),i.info("DoubleCircle main"),f(e,l),e.intersect=function(t){return i.info("DoubleCircle intersect",e,a.width/2+n+5,t),k.circle(e,a.width/2+n+5,t)},r},stadium:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.height+e.padding,i=a.width+n/4+e.padding,s=r.insert("rect",":first-child").attr("style",e.style).attr("rx",n/2).attr("ry",n/2).attr("x",-i/2).attr("y",-n/2).attr("width",i).attr("height",n);return f(e,s),e.intersect=function(t){return k.rect(e,t)},r},hexagon:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.height+e.padding,i=n/4,s=a.width+2*i+e.padding,l=[{x:i,y:0},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:i,y:-n},{x:0,y:-n/2}],o=b(r,s,n,l);return o.attr("style",e.style),f(e,o),e.intersect=function(t){return k.polygon(e,l,t)},r},rect_left_inv_arrow:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-i/2,y:0},{x:n,y:0},{x:n,y:-i},{x:-i/2,y:-i},{x:0,y:-i/2}];return b(r,n,i,s).attr("style",e.style),e.width=n+i,e.height=i,e.intersect=function(t){return k.polygon(e,s,t)},r},lean_right:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-2*i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:i/6,y:-i}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},lean_left:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:2*i/6,y:0},{x:n+i/6,y:0},{x:n-2*i/6,y:-i},{x:-i/6,y:-i}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},trapezoid:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-2*i/6,y:0},{x:n+2*i/6,y:0},{x:n-i/6,y:-i},{x:i/6,y:-i}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},inv_trapezoid:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:-2*i/6,y:-i}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},rect_right_inv_arrow:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:0,y:0},{x:n+i/2,y:0},{x:n,y:-i/2},{x:n+i/2,y:-i},{x:0,y:-i}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},cylinder:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=n/2,s=i/(2.5+n/50),l=a.height+s+e.padding,o="M 0,"+s+" a "+i+","+s+" 0,0,0 "+n+" 0 a "+i+","+s+" 0,0,0 "+-n+" 0 l 0,"+l+" a "+i+","+s+" 0,0,0 "+n+" 0 l 0,"+-l,d=r.attr("label-offset-y",s).insert("path",":first-child").attr("style",e.style).attr("d",o).attr("transform","translate("+-n/2+","+-(l/2+s)+")");return f(e,d),e.intersect=function(t){const r=k.rect(e,t),a=r.x-e.x;if(0!=i&&(Math.abs(a)e.height/2-s)){let n=s*s*(1-a*a/(i*i));0!=n&&(n=Math.sqrt(n)),n=s-n,t.y-e.y>0&&(n=-n),r.y+=n}return r},r},start:(t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=r.insert("circle",":first-child");return a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),f(e,a),e.intersect=function(t){return k.circle(e,7,t)},r},end:(t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=r.insert("circle",":first-child"),n=r.insert("circle",":first-child");return n.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),a.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),f(e,n),e.intersect=function(t){return k.circle(e,7,t)},r},note:async(t,r)=>{r.useHtmlLabels||e().flowchart.htmlLabels||(r.centerLabel=!0);const{shapeSvg:a,bbox:n,halfPadding:s}=await y(t,r,"node "+r.classes,!0);i.info("Classes = ",r.classes);const l=a.insert("rect",":first-child");return l.attr("rx",r.rx).attr("ry",r.ry).attr("x",-n.width/2-s).attr("y",-n.height/2-s).attr("width",n.width+r.padding).attr("height",n.height+r.padding),f(r,l),r.intersect=function(t){return k.rect(r,t)},a},subroutine:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:0,y:0},{x:n,y:0},{x:n,y:-i},{x:0,y:-i},{x:0,y:0},{x:-8,y:0},{x:n+8,y:0},{x:n+8,y:-i},{x:-8,y:-i},{x:-8,y:0}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},fork:v,join:v,class_box:(r,a)=>{const i=a.padding/2;let s;s=a.classes?"node "+a.classes:"node default";const l=r.insert("g").attr("class",s).attr("id",a.domId||a.id),o=l.insert("rect",":first-child"),c=l.insert("line"),h=l.insert("line");let p=0,y=4;const b=l.insert("g").attr("class","label");let w=0;const u=a.classData.annotations&&a.classData.annotations[0],x=a.classData.annotations[0]?"«"+a.classData.annotations[0]+"»":"",m=b.node().appendChild(g(x,a.labelStyle,!0,!0));let L=m.getBBox();if(t(e().flowchart.htmlLabels)){const t=m.children[0],e=n(m);L=t.getBoundingClientRect(),e.attr("width",L.width),e.attr("height",L.height)}a.classData.annotations[0]&&(y+=L.height+4,p+=L.width);let S=a.classData.label;void 0!==a.classData.type&&""!==a.classData.type&&(e().flowchart.htmlLabels?S+="<"+a.classData.type+">":S+="<"+a.classData.type+">");const v=b.node().appendChild(g(S,a.labelStyle,!0,!0));n(v).attr("class","classTitle");let M=v.getBBox();if(t(e().flowchart.htmlLabels)){const t=v.children[0],e=n(v);M=t.getBoundingClientRect(),e.attr("width",M.width),e.attr("height",M.height)}y+=M.height+4,M.width>p&&(p=M.width);const T=[];a.classData.members.forEach((r=>{const i=d(r);let s=i.displayText;e().flowchart.htmlLabels&&(s=s.replace(//g,">"));const l=b.node().appendChild(g(s,i.cssStyle?i.cssStyle:a.labelStyle,!0,!0));let o=l.getBBox();if(t(e().flowchart.htmlLabels)){const t=l.children[0],e=n(l);o=t.getBoundingClientRect(),e.attr("width",o.width),e.attr("height",o.height)}o.width>p&&(p=o.width),y+=o.height+4,T.push(l)})),y+=8;const B=[];if(a.classData.methods.forEach((r=>{const i=d(r);let s=i.displayText;e().flowchart.htmlLabels&&(s=s.replace(//g,">"));const l=b.node().appendChild(g(s,i.cssStyle?i.cssStyle:a.labelStyle,!0,!0));let o=l.getBBox();if(t(e().flowchart.htmlLabels)){const t=l.children[0],e=n(l);o=t.getBoundingClientRect(),e.attr("width",o.width),e.attr("height",o.height)}o.width>p&&(p=o.width),y+=o.height+4,B.push(l)})),y+=8,u){let t=(p-L.width)/2;n(m).attr("transform","translate( "+(-1*p/2+t)+", "+-1*y/2+")"),w=L.height+4}let E=(p-M.width)/2;return n(v).attr("transform","translate( "+(-1*p/2+E)+", "+(-1*y/2+w)+")"),w+=M.height+4,c.attr("class","divider").attr("x1",-p/2-i).attr("x2",p/2+i).attr("y1",-y/2-i+8+w).attr("y2",-y/2-i+8+w),w+=8,T.forEach((t=>{n(t).attr("transform","translate( "+-p/2+", "+(-1*y/2+w+4)+")"),w+=M.height+4})),w+=8,h.attr("class","divider").attr("x1",-p/2-i).attr("x2",p/2+i).attr("y1",-y/2-i+8+w).attr("y2",-y/2-i+8+w),w+=8,B.forEach((t=>{n(t).attr("transform","translate( "+-p/2+", "+(-1*y/2+w)+")"),w+=M.height+4})),o.attr("class","outer title-state").attr("x",-p/2-i).attr("y",-y/2-i).attr("width",p+a.padding).attr("height",y+a.padding),f(a,o),a.intersect=function(t){return k.rect(a,t)},l}};let T={};const B=async(t,r,a)=>{let n,i;if(r.link){let s;"sandbox"===e().securityLevel?s="_top":r.linkTarget&&(s=r.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",r.link).attr("target",s),i=await M[r.shape](n,r,a)}else i=await M[r.shape](t,r,a),n=i;return r.tooltip&&i.attr("title",r.tooltip),r.class&&i.attr("class","node default "+r.class),T[r.id]=n,r.haveCallback&&T[r.id].attr("class",T[r.id].attr("class")+" clickable"),n},E=(t,e)=>{T[e.id]=t},C=()=>{T={}},P=t=>{const e=T[t.id];i.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const r=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+r-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),r};let _={},R={};const I=()=>{_={},R={}},H=(r,a)=>{const s=t(e().flowchart.htmlLabels),l="markdown"===a.labelType?o(r,a.label,{style:a.labelStyle,useHtmlLabels:s,addSvgBackground:!0}):g(a.label,a.labelStyle);i.info("abc82",a,a.labelType);const d=r.insert("g").attr("class","edgeLabel"),c=d.insert("g").attr("class","label");c.node().appendChild(l);let h,p=l.getBBox();if(s){const t=l.children[0],e=n(l);p=t.getBoundingClientRect(),e.attr("width",p.width),e.attr("height",p.height)}if(c.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),_[a.id]=d,a.width=p.width,a.height=p.height,a.startLabelLeft){const t=g(a.startLabelLeft,a.labelStyle),e=r.insert("g").attr("class","edgeTerminals"),n=e.insert("g").attr("class","inner");h=n.node().appendChild(t);const i=t.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),R[a.id]||(R[a.id]={}),R[a.id].startLeft=e,N(h,a.startLabelLeft)}if(a.startLabelRight){const t=g(a.startLabelRight,a.labelStyle),e=r.insert("g").attr("class","edgeTerminals"),n=e.insert("g").attr("class","inner");h=e.node().appendChild(t),n.node().appendChild(t);const i=t.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),R[a.id]||(R[a.id]={}),R[a.id].startRight=e,N(h,a.startLabelRight)}if(a.endLabelLeft){const t=g(a.endLabelLeft,a.labelStyle),e=r.insert("g").attr("class","edgeTerminals"),n=e.insert("g").attr("class","inner");h=n.node().appendChild(t);const i=t.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),e.node().appendChild(t),R[a.id]||(R[a.id]={}),R[a.id].endLeft=e,N(h,a.endLabelLeft)}if(a.endLabelRight){const t=g(a.endLabelRight,a.labelStyle),e=r.insert("g").attr("class","edgeTerminals"),n=e.insert("g").attr("class","inner");h=n.node().appendChild(t);const i=t.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),e.node().appendChild(t),R[a.id]||(R[a.id]={}),R[a.id].endRight=e,N(h,a.endLabelRight)}return l};function N(t,r){e().flowchart.htmlLabels&&t&&(t.style.width=9*r.length+"px",t.style.height="12px")}const W=(t,e)=>{i.info("Moving label abc78 ",t.id,t.label,_[t.id]);let r=e.updatedPath?e.updatedPath:e.originalPath;if(t.label){const a=_[t.id];let n=t.x,l=t.y;if(r){const a=s.calcLabelPosition(r);i.info("Moving label "+t.label+" from (",n,",",l,") to (",a.x,",",a.y,") abc78"),e.updatedPath&&(n=a.x,l=a.y)}a.attr("transform","translate("+n+", "+l+")")}if(t.startLabelLeft){const e=R[t.id].startLeft;let a=t.x,n=t.y;if(r){const e=s.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);a=e.x,n=e.y}e.attr("transform","translate("+a+", "+n+")")}if(t.startLabelRight){const e=R[t.id].startRight;let a=t.x,n=t.y;if(r){const e=s.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);a=e.x,n=e.y}e.attr("transform","translate("+a+", "+n+")")}if(t.endLabelLeft){const e=R[t.id].endLeft;let a=t.x,n=t.y;if(r){const e=s.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);a=e.x,n=e.y}e.attr("transform","translate("+a+", "+n+")")}if(t.endLabelRight){const e=R[t.id].endRight;let a=t.x,n=t.y;if(r){const e=s.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);a=e.x,n=e.y}e.attr("transform","translate("+a+", "+n+")")}},Y=(t,e)=>{i.warn("abc88 cutPathAtIntersect",t,e);let r=[],a=t[0],n=!1;return t.forEach((t=>{if(i.info("abc88 checking point",t,e),((t,e)=>{const r=t.x,a=t.y,n=Math.abs(e.x-r),i=Math.abs(e.y-a),s=t.width/2,l=t.height/2;return n>=s||i>=l})(e,t)||n)i.warn("abc88 outside",t,a),a=t,n||r.push(t);else{const s=((t,e,r)=>{i.warn(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(r)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const a=t.x,n=t.y,s=Math.abs(a-r.x),l=t.width/2;let o=r.xMath.abs(a-e.x)*d){let t=r.y{l=l||t.x===s.x&&t.y===s.y})),r.some((t=>t.x===s.x&&t.y===s.y))?i.warn("abc88 no intersect",s,r):r.push(s),n=!0}})),i.warn("abc88 returning points",r),r},j=function(t,r,a,n,s,o){let d=a.points,h=!1;const p=o.node(r.v);var g=o.node(r.w);i.info("abc88 InsertEdge: ",a),g.intersect&&p.intersect&&(d=d.slice(1,a.points.length-1),d.unshift(p.intersect(d[0])),i.info("Last point",d[d.length-1],g,g.intersect(d[d.length-1])),d.push(g.intersect(d[d.length-1]))),a.toCluster&&(i.info("to cluster abc88",n[a.toCluster]),d=Y(a.points,n[a.toCluster].node),h=!0),a.fromCluster&&(i.info("from cluster abc88",n[a.fromCluster]),d=Y(d.reverse(),n[a.fromCluster].node).reverse(),h=!0);const y=d.filter((t=>!Number.isNaN(t.y)));let f;f=("graph"===s||"flowchart"===s)&&a.curve||l;const b=c().x((function(t){return t.x})).y((function(t){return t.y})).curve(f);let w;switch(a.thickness){case"normal":w="edge-thickness-normal";break;case"thick":case"invisible":w="edge-thickness-thick";break;default:w=""}switch(a.pattern){case"solid":w+=" edge-pattern-solid";break;case"dotted":w+=" edge-pattern-dotted";break;case"dashed":w+=" edge-pattern-dashed"}const u=t.append("path").attr("d",b(y)).attr("id",a.id).attr("class"," "+w+(a.classes?" "+a.classes:"")).attr("style",a.style);let x="";switch((e().flowchart.arrowMarkerAbsolute||e().state.arrowMarkerAbsolute)&&(x=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,x=x.replace(/\(/g,"\\("),x=x.replace(/\)/g,"\\)")),i.info("arrowTypeStart",a.arrowTypeStart),i.info("arrowTypeEnd",a.arrowTypeEnd),a.arrowTypeStart){case"arrow_cross":u.attr("marker-start","url("+x+"#"+s+"-crossStart)");break;case"arrow_point":u.attr("marker-start","url("+x+"#"+s+"-pointStart)");break;case"arrow_barb":u.attr("marker-start","url("+x+"#"+s+"-barbStart)");break;case"arrow_circle":u.attr("marker-start","url("+x+"#"+s+"-circleStart)");break;case"aggregation":u.attr("marker-start","url("+x+"#"+s+"-aggregationStart)");break;case"extension":u.attr("marker-start","url("+x+"#"+s+"-extensionStart)");break;case"composition":u.attr("marker-start","url("+x+"#"+s+"-compositionStart)");break;case"dependency":u.attr("marker-start","url("+x+"#"+s+"-dependencyStart)");break;case"lollipop":u.attr("marker-start","url("+x+"#"+s+"-lollipopStart)")}switch(a.arrowTypeEnd){case"arrow_cross":u.attr("marker-end","url("+x+"#"+s+"-crossEnd)");break;case"arrow_point":u.attr("marker-end","url("+x+"#"+s+"-pointEnd)");break;case"arrow_barb":u.attr("marker-end","url("+x+"#"+s+"-barbEnd)");break;case"arrow_circle":u.attr("marker-end","url("+x+"#"+s+"-circleEnd)");break;case"aggregation":u.attr("marker-end","url("+x+"#"+s+"-aggregationEnd)");break;case"extension":u.attr("marker-end","url("+x+"#"+s+"-extensionEnd)");break;case"composition":u.attr("marker-end","url("+x+"#"+s+"-compositionEnd)");break;case"dependency":u.attr("marker-end","url("+x+"#"+s+"-dependencyEnd)");break;case"lollipop":u.attr("marker-end","url("+x+"#"+s+"-lollipopEnd)")}let m={};return h&&(m.updatedPath=d),m.originalPath=a.points,m};export{B as a,H as b,j as c,W as d,C as e,I as f,g,m as h,p as i,y as l,P as p,E as s,f as u}; +import{q as t,c as e,d as r,a4 as a,h as n,l as i,y as s,a5 as l}from"./mermaid.core.3a590193.js";import{c as o}from"./createText-2f679d62.a374f608.js";import{p as d}from"./svgDraw-6750006d.f814d75b.js";import{l as c}from"./line.53b161c2.js";const h={extension:(t,e,r)=>{i.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",e+"-extensionStart").attr("class","marker extension "+e).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"),t.append("defs").append("marker").attr("id",e+"-extensionEnd").attr("class","marker extension "+e).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")},composition:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-compositionStart").attr("class","marker composition "+e).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"),t.append("defs").append("marker").attr("id",e+"-compositionEnd").attr("class","marker composition "+e).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")},aggregation:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-aggregationStart").attr("class","marker aggregation "+e).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"),t.append("defs").append("marker").attr("id",e+"-aggregationEnd").attr("class","marker aggregation "+e).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")},dependency:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-dependencyStart").attr("class","marker dependency "+e).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"),t.append("defs").append("marker").attr("id",e+"-dependencyEnd").attr("class","marker dependency "+e).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")},lollipop:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","white").attr("cx",6).attr("cy",7).attr("r",6)},point:(t,e)=>{t.append("marker").attr("id",e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",10).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"),t.append("marker").attr("id",e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",0).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")},circle:(t,e)=>{t.append("marker").attr("id",e+"-circleEnd").attr("class","marker "+e).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"),t.append("marker").attr("id",e+"-circleStart").attr("class","marker "+e).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")},cross:(t,e)=>{t.append("marker").attr("id",e+"-crossEnd").attr("class","marker cross "+e).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"),t.append("marker").attr("id",e+"-crossStart").attr("class","marker cross "+e).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")},barb:(t,e)=>{t.append("defs").append("marker").attr("id",e+"-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")}},p=(t,e,r,a)=>{e.forEach((e=>{h[e](t,r,a)}))};const g=(r,s,l,o)=>{let d=r||"";if("object"==typeof d&&(d=d[0]),t(e().flowchart.htmlLabels)){d=d.replace(/\\n|\n/g,"
    "),i.info("vertexText"+d);return function(t){const e=n(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),a=t.label,i=t.isNode?"nodeLabel":"edgeLabel";var s,l;return r.html('"+a+""),s=r,(l=t.labelStyle)&&s.attr("style",l),r.style("display","inline-block"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}({isNode:o,label:a(d).replace(/fa[blrs]?:fa-[\w-]+/g,(t=>``)),labelStyle:s.replace("fill:","color:")})}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",s.replace("color:","fill:"));let e=[];e="string"==typeof d?d.split(/\\n|\n|/gi):Array.isArray(d)?d:[];for(const r of e){const e=document.createElementNS("http://www.w3.org/2000/svg","tspan");e.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),e.setAttribute("dy","1em"),e.setAttribute("x","0"),l?e.setAttribute("class","title-row"):e.setAttribute("class","row"),e.textContent=r.trim(),t.appendChild(e)}return t}},y=async(i,s,l,d)=>{let c;const h=s.useHtmlLabels||t(e().flowchart.htmlLabels);c=l||"node default";const p=i.insert("g").attr("class",c).attr("id",s.domId||s.id),y=p.insert("g").attr("class","label").attr("style",s.labelStyle);let f;f=void 0===s.labelText?"":"string"==typeof s.labelText?s.labelText:s.labelText[0];const b=y.node();let w;w="markdown"===s.labelType?o(y,r(a(f),e()),{useHtmlLabels:h,width:s.width||e().flowchart.wrappingWidth,classes:"markdown-node-label"}):b.appendChild(g(r(a(f),e()),s.labelStyle,!1,d));let u=w.getBBox();const x=s.padding/2;if(t(e().flowchart.htmlLabels)){const t=w.children[0],r=n(w),a=t.getElementsByTagName("img");if(a){const t=""===f.replace(/]*>/g,"").trim();await Promise.all([...a].map((r=>new Promise((a=>r.addEventListener("load",(function(){if(r.style.display="flex",r.style.flexDirection="column",t){const t=e().fontSize?e().fontSize:window.getComputedStyle(document.body).fontSize,a=5;r.style.width=parseInt(t,10)*a+"px"}else r.style.width="100%";a(r)})))))))}u=t.getBoundingClientRect(),r.attr("width",u.width),r.attr("height",u.height)}return h?y.attr("transform","translate("+-u.width/2+", "+-u.height/2+")"):y.attr("transform","translate(0, "+-u.height/2+")"),s.centerLabel&&y.attr("transform","translate("+-u.width/2+", "+-u.height/2+")"),y.insert("rect",":first-child"),{shapeSvg:p,bbox:u,halfPadding:x,label:y}},f=(t,e)=>{const r=e.node().getBBox();t.width=r.width,t.height=r.height};function b(t,e,r,a){return t.insert("polygon",":first-child").attr("points",a.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}function w(t,e,r,a){var n=t.x,i=t.y,s=n-a.x,l=i-a.y,o=Math.sqrt(e*e*l*l+r*r*s*s),d=Math.abs(e*r*s/o);a.x0}const m=(t,e)=>{var r,a,n=t.x,i=t.y,s=e.x-n,l=e.y-i,o=t.width/2,d=t.height/2;return Math.abs(l)*o>Math.abs(s)*d?(l<0&&(d=-d),r=0===l?0:d*s/l,a=d):(s<0&&(o=-o),r=o,a=0===s?0:o*l/s),{x:n+r,y:i+a}},k={node:function(t,e){return t.intersect(e)},circle:function(t,e,r){return w(t,e,e,r)},ellipse:w,polygon:function(t,e,r){var a=t.x,n=t.y,i=[],s=Number.POSITIVE_INFINITY,l=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach((function(t){s=Math.min(s,t.x),l=Math.min(l,t.y)})):(s=Math.min(s,e.x),l=Math.min(l,e.y));for(var o=a-t.width/2-s,d=n-t.height/2-l,c=0;c1&&i.sort((function(t,e){var a=t.x-r.x,n=t.y-r.y,i=Math.sqrt(a*a+n*n),s=e.x-r.x,l=e.y-r.y,o=Math.sqrt(s*s+l*l);return i{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding+(a.height+e.padding),s=[{x:n/2,y:0},{x:n,y:-n/2},{x:n/2,y:-n},{x:0,y:-n/2}];i.info("Question main (Circle)");const l=b(r,n,n,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return i.warn("Intersect called"),k.polygon(e,s,t)},r};function S(t,e,r,a){const n=[],s=t=>{n.push(t,0)},l=t=>{n.push(0,t)};e.includes("t")?(i.debug("add top border"),s(r)):l(r),e.includes("r")?(i.debug("add right border"),s(a)):l(a),e.includes("b")?(i.debug("add bottom border"),s(r)):l(r),e.includes("l")?(i.debug("add left border"),s(a)):l(a),t.attr("stroke-dasharray",n.join(" "))}const v=(t,e,r)=>{const a=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let n=70,i=10;"LR"===r&&(n=10,i=70);const s=a.append("rect").attr("x",-1*n/2).attr("y",-1*i/2).attr("width",n).attr("height",i).attr("class","fork-join");return f(e,s),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(t){return k.rect(e,t)},a},M={rhombus:L,question:L,rect:async(t,e)=>{const{shapeSvg:r,bbox:a,halfPadding:n}=await y(t,e,"node "+e.classes,!0),s=r.insert("rect",":first-child"),l=a.width+e.padding,o=a.height+e.padding;if(s.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",-a.width/2-n).attr("y",-a.height/2-n).attr("width",l).attr("height",o),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(S(s,e.props.borders,l,o),t.delete("borders")),t.forEach((t=>{i.warn(`Unknown node property ${t}`)}))}return f(e,s),e.intersect=function(t){return k.rect(e,t)},r},labelRect:async(t,e)=>{const{shapeSvg:r}=await y(t,e,"label",!0);i.trace("Classes = ",e.classes);const a=r.insert("rect",":first-child");if(a.attr("width",0).attr("height",0),r.attr("class","label edgeLabel"),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(S(a,e.props.borders,0,0),t.delete("borders")),t.forEach((t=>{i.warn(`Unknown node property ${t}`)}))}return f(e,a),e.intersect=function(t){return k.rect(e,t)},r},rectWithTitle:(r,a)=>{let s;s=a.classes?"node "+a.classes:"node default";const l=r.insert("g").attr("class",s).attr("id",a.domId||a.id),o=l.insert("rect",":first-child"),d=l.insert("line"),c=l.insert("g").attr("class","label"),h=a.labelText.flat?a.labelText.flat():a.labelText;let p="";p="object"==typeof h?h[0]:h,i.info("Label text abc79",p,h,"object"==typeof h);const y=c.node().appendChild(g(p,a.labelStyle,!0,!0));let b={width:0,height:0};if(t(e().flowchart.htmlLabels)){const t=y.children[0],e=n(y);b=t.getBoundingClientRect(),e.attr("width",b.width),e.attr("height",b.height)}i.info("Text 2",h);const w=h.slice(1,h.length);let u=y.getBBox();const x=c.node().appendChild(g(w.join?w.join("
    "):w,a.labelStyle,!0,!0));if(t(e().flowchart.htmlLabels)){const t=x.children[0],e=n(x);b=t.getBoundingClientRect(),e.attr("width",b.width),e.attr("height",b.height)}const m=a.padding/2;return n(x).attr("transform","translate( "+(b.width>u.width?0:(u.width-b.width)/2)+", "+(u.height+m+5)+")"),n(y).attr("transform","translate( "+(b.width{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=[{x:0,y:14},{x:14,y:0},{x:0,y:-14},{x:-14,y:0}];return r.insert("polygon",":first-child").attr("points",a.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(t){return k.circle(e,14,t)},r},circle:async(t,e)=>{const{shapeSvg:r,bbox:a,halfPadding:n}=await y(t,e,void 0,!0),s=r.insert("circle",":first-child");return s.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",a.width/2+n).attr("width",a.width+e.padding).attr("height",a.height+e.padding),i.info("Circle main"),f(e,s),e.intersect=function(t){return i.info("Circle intersect",e,a.width/2+n,t),k.circle(e,a.width/2+n,t)},r},doublecircle:async(t,e)=>{const{shapeSvg:r,bbox:a,halfPadding:n}=await y(t,e,void 0,!0),s=r.insert("g",":first-child"),l=s.insert("circle"),o=s.insert("circle");return l.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",a.width/2+n+5).attr("width",a.width+e.padding+10).attr("height",a.height+e.padding+10),o.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",a.width/2+n).attr("width",a.width+e.padding).attr("height",a.height+e.padding),i.info("DoubleCircle main"),f(e,l),e.intersect=function(t){return i.info("DoubleCircle intersect",e,a.width/2+n+5,t),k.circle(e,a.width/2+n+5,t)},r},stadium:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.height+e.padding,i=a.width+n/4+e.padding,s=r.insert("rect",":first-child").attr("style",e.style).attr("rx",n/2).attr("ry",n/2).attr("x",-i/2).attr("y",-n/2).attr("width",i).attr("height",n);return f(e,s),e.intersect=function(t){return k.rect(e,t)},r},hexagon:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.height+e.padding,i=n/4,s=a.width+2*i+e.padding,l=[{x:i,y:0},{x:s-i,y:0},{x:s,y:-n/2},{x:s-i,y:-n},{x:i,y:-n},{x:0,y:-n/2}],o=b(r,s,n,l);return o.attr("style",e.style),f(e,o),e.intersect=function(t){return k.polygon(e,l,t)},r},rect_left_inv_arrow:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-i/2,y:0},{x:n,y:0},{x:n,y:-i},{x:-i/2,y:-i},{x:0,y:-i/2}];return b(r,n,i,s).attr("style",e.style),e.width=n+i,e.height=i,e.intersect=function(t){return k.polygon(e,s,t)},r},lean_right:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-2*i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:i/6,y:-i}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},lean_left:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:2*i/6,y:0},{x:n+i/6,y:0},{x:n-2*i/6,y:-i},{x:-i/6,y:-i}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},trapezoid:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:-2*i/6,y:0},{x:n+2*i/6,y:0},{x:n-i/6,y:-i},{x:i/6,y:-i}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},inv_trapezoid:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:i/6,y:0},{x:n-i/6,y:0},{x:n+2*i/6,y:-i},{x:-2*i/6,y:-i}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},rect_right_inv_arrow:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:0,y:0},{x:n+i/2,y:0},{x:n,y:-i/2},{x:n+i/2,y:-i},{x:0,y:-i}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},cylinder:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=n/2,s=i/(2.5+n/50),l=a.height+s+e.padding,o="M 0,"+s+" a "+i+","+s+" 0,0,0 "+n+" 0 a "+i+","+s+" 0,0,0 "+-n+" 0 l 0,"+l+" a "+i+","+s+" 0,0,0 "+n+" 0 l 0,"+-l,d=r.attr("label-offset-y",s).insert("path",":first-child").attr("style",e.style).attr("d",o).attr("transform","translate("+-n/2+","+-(l/2+s)+")");return f(e,d),e.intersect=function(t){const r=k.rect(e,t),a=r.x-e.x;if(0!=i&&(Math.abs(a)e.height/2-s)){let n=s*s*(1-a*a/(i*i));0!=n&&(n=Math.sqrt(n)),n=s-n,t.y-e.y>0&&(n=-n),r.y+=n}return r},r},start:(t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=r.insert("circle",":first-child");return a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),f(e,a),e.intersect=function(t){return k.circle(e,7,t)},r},end:(t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),a=r.insert("circle",":first-child"),n=r.insert("circle",":first-child");return n.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),a.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),f(e,n),e.intersect=function(t){return k.circle(e,7,t)},r},note:async(t,r)=>{r.useHtmlLabels||e().flowchart.htmlLabels||(r.centerLabel=!0);const{shapeSvg:a,bbox:n,halfPadding:s}=await y(t,r,"node "+r.classes,!0);i.info("Classes = ",r.classes);const l=a.insert("rect",":first-child");return l.attr("rx",r.rx).attr("ry",r.ry).attr("x",-n.width/2-s).attr("y",-n.height/2-s).attr("width",n.width+r.padding).attr("height",n.height+r.padding),f(r,l),r.intersect=function(t){return k.rect(r,t)},a},subroutine:async(t,e)=>{const{shapeSvg:r,bbox:a}=await y(t,e,void 0,!0),n=a.width+e.padding,i=a.height+e.padding,s=[{x:0,y:0},{x:n,y:0},{x:n,y:-i},{x:0,y:-i},{x:0,y:0},{x:-8,y:0},{x:n+8,y:0},{x:n+8,y:-i},{x:-8,y:-i},{x:-8,y:0}],l=b(r,n,i,s);return l.attr("style",e.style),f(e,l),e.intersect=function(t){return k.polygon(e,s,t)},r},fork:v,join:v,class_box:(r,a)=>{const i=a.padding/2;let s;s=a.classes?"node "+a.classes:"node default";const l=r.insert("g").attr("class",s).attr("id",a.domId||a.id),o=l.insert("rect",":first-child"),c=l.insert("line"),h=l.insert("line");let p=0,y=4;const b=l.insert("g").attr("class","label");let w=0;const u=a.classData.annotations&&a.classData.annotations[0],x=a.classData.annotations[0]?"«"+a.classData.annotations[0]+"»":"",m=b.node().appendChild(g(x,a.labelStyle,!0,!0));let L=m.getBBox();if(t(e().flowchart.htmlLabels)){const t=m.children[0],e=n(m);L=t.getBoundingClientRect(),e.attr("width",L.width),e.attr("height",L.height)}a.classData.annotations[0]&&(y+=L.height+4,p+=L.width);let S=a.classData.label;void 0!==a.classData.type&&""!==a.classData.type&&(e().flowchart.htmlLabels?S+="<"+a.classData.type+">":S+="<"+a.classData.type+">");const v=b.node().appendChild(g(S,a.labelStyle,!0,!0));n(v).attr("class","classTitle");let M=v.getBBox();if(t(e().flowchart.htmlLabels)){const t=v.children[0],e=n(v);M=t.getBoundingClientRect(),e.attr("width",M.width),e.attr("height",M.height)}y+=M.height+4,M.width>p&&(p=M.width);const T=[];a.classData.members.forEach((r=>{const i=d(r);let s=i.displayText;e().flowchart.htmlLabels&&(s=s.replace(//g,">"));const l=b.node().appendChild(g(s,i.cssStyle?i.cssStyle:a.labelStyle,!0,!0));let o=l.getBBox();if(t(e().flowchart.htmlLabels)){const t=l.children[0],e=n(l);o=t.getBoundingClientRect(),e.attr("width",o.width),e.attr("height",o.height)}o.width>p&&(p=o.width),y+=o.height+4,T.push(l)})),y+=8;const B=[];if(a.classData.methods.forEach((r=>{const i=d(r);let s=i.displayText;e().flowchart.htmlLabels&&(s=s.replace(//g,">"));const l=b.node().appendChild(g(s,i.cssStyle?i.cssStyle:a.labelStyle,!0,!0));let o=l.getBBox();if(t(e().flowchart.htmlLabels)){const t=l.children[0],e=n(l);o=t.getBoundingClientRect(),e.attr("width",o.width),e.attr("height",o.height)}o.width>p&&(p=o.width),y+=o.height+4,B.push(l)})),y+=8,u){let t=(p-L.width)/2;n(m).attr("transform","translate( "+(-1*p/2+t)+", "+-1*y/2+")"),w=L.height+4}let E=(p-M.width)/2;return n(v).attr("transform","translate( "+(-1*p/2+E)+", "+(-1*y/2+w)+")"),w+=M.height+4,c.attr("class","divider").attr("x1",-p/2-i).attr("x2",p/2+i).attr("y1",-y/2-i+8+w).attr("y2",-y/2-i+8+w),w+=8,T.forEach((t=>{n(t).attr("transform","translate( "+-p/2+", "+(-1*y/2+w+4)+")"),w+=M.height+4})),w+=8,h.attr("class","divider").attr("x1",-p/2-i).attr("x2",p/2+i).attr("y1",-y/2-i+8+w).attr("y2",-y/2-i+8+w),w+=8,B.forEach((t=>{n(t).attr("transform","translate( "+-p/2+", "+(-1*y/2+w)+")"),w+=M.height+4})),o.attr("class","outer title-state").attr("x",-p/2-i).attr("y",-y/2-i).attr("width",p+a.padding).attr("height",y+a.padding),f(a,o),a.intersect=function(t){return k.rect(a,t)},l}};let T={};const B=async(t,r,a)=>{let n,i;if(r.link){let s;"sandbox"===e().securityLevel?s="_top":r.linkTarget&&(s=r.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",r.link).attr("target",s),i=await M[r.shape](n,r,a)}else i=await M[r.shape](t,r,a),n=i;return r.tooltip&&i.attr("title",r.tooltip),r.class&&i.attr("class","node default "+r.class),T[r.id]=n,r.haveCallback&&T[r.id].attr("class",T[r.id].attr("class")+" clickable"),n},E=(t,e)=>{T[e.id]=t},C=()=>{T={}},P=t=>{const e=T[t.id];i.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const r=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+r-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),r};let _={},R={};const I=()=>{_={},R={}},H=(r,a)=>{const s=t(e().flowchart.htmlLabels),l="markdown"===a.labelType?o(r,a.label,{style:a.labelStyle,useHtmlLabels:s,addSvgBackground:!0}):g(a.label,a.labelStyle);i.info("abc82",a,a.labelType);const d=r.insert("g").attr("class","edgeLabel"),c=d.insert("g").attr("class","label");c.node().appendChild(l);let h,p=l.getBBox();if(s){const t=l.children[0],e=n(l);p=t.getBoundingClientRect(),e.attr("width",p.width),e.attr("height",p.height)}if(c.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),_[a.id]=d,a.width=p.width,a.height=p.height,a.startLabelLeft){const t=g(a.startLabelLeft,a.labelStyle),e=r.insert("g").attr("class","edgeTerminals"),n=e.insert("g").attr("class","inner");h=n.node().appendChild(t);const i=t.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),R[a.id]||(R[a.id]={}),R[a.id].startLeft=e,N(h,a.startLabelLeft)}if(a.startLabelRight){const t=g(a.startLabelRight,a.labelStyle),e=r.insert("g").attr("class","edgeTerminals"),n=e.insert("g").attr("class","inner");h=e.node().appendChild(t),n.node().appendChild(t);const i=t.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),R[a.id]||(R[a.id]={}),R[a.id].startRight=e,N(h,a.startLabelRight)}if(a.endLabelLeft){const t=g(a.endLabelLeft,a.labelStyle),e=r.insert("g").attr("class","edgeTerminals"),n=e.insert("g").attr("class","inner");h=n.node().appendChild(t);const i=t.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),e.node().appendChild(t),R[a.id]||(R[a.id]={}),R[a.id].endLeft=e,N(h,a.endLabelLeft)}if(a.endLabelRight){const t=g(a.endLabelRight,a.labelStyle),e=r.insert("g").attr("class","edgeTerminals"),n=e.insert("g").attr("class","inner");h=n.node().appendChild(t);const i=t.getBBox();n.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),e.node().appendChild(t),R[a.id]||(R[a.id]={}),R[a.id].endRight=e,N(h,a.endLabelRight)}return l};function N(t,r){e().flowchart.htmlLabels&&t&&(t.style.width=9*r.length+"px",t.style.height="12px")}const W=(t,e)=>{i.info("Moving label abc78 ",t.id,t.label,_[t.id]);let r=e.updatedPath?e.updatedPath:e.originalPath;if(t.label){const a=_[t.id];let n=t.x,l=t.y;if(r){const a=s.calcLabelPosition(r);i.info("Moving label "+t.label+" from (",n,",",l,") to (",a.x,",",a.y,") abc78"),e.updatedPath&&(n=a.x,l=a.y)}a.attr("transform","translate("+n+", "+l+")")}if(t.startLabelLeft){const e=R[t.id].startLeft;let a=t.x,n=t.y;if(r){const e=s.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);a=e.x,n=e.y}e.attr("transform","translate("+a+", "+n+")")}if(t.startLabelRight){const e=R[t.id].startRight;let a=t.x,n=t.y;if(r){const e=s.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);a=e.x,n=e.y}e.attr("transform","translate("+a+", "+n+")")}if(t.endLabelLeft){const e=R[t.id].endLeft;let a=t.x,n=t.y;if(r){const e=s.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);a=e.x,n=e.y}e.attr("transform","translate("+a+", "+n+")")}if(t.endLabelRight){const e=R[t.id].endRight;let a=t.x,n=t.y;if(r){const e=s.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);a=e.x,n=e.y}e.attr("transform","translate("+a+", "+n+")")}},Y=(t,e)=>{i.warn("abc88 cutPathAtIntersect",t,e);let r=[],a=t[0],n=!1;return t.forEach((t=>{if(i.info("abc88 checking point",t,e),((t,e)=>{const r=t.x,a=t.y,n=Math.abs(e.x-r),i=Math.abs(e.y-a),s=t.width/2,l=t.height/2;return n>=s||i>=l})(e,t)||n)i.warn("abc88 outside",t,a),a=t,n||r.push(t);else{const s=((t,e,r)=>{i.warn(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(r)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const a=t.x,n=t.y,s=Math.abs(a-r.x),l=t.width/2;let o=r.xMath.abs(a-e.x)*d){let t=r.y{l=l||t.x===s.x&&t.y===s.y})),r.some((t=>t.x===s.x&&t.y===s.y))?i.warn("abc88 no intersect",s,r):r.push(s),n=!0}})),i.warn("abc88 returning points",r),r},j=function(t,r,a,n,s,o){let d=a.points,h=!1;const p=o.node(r.v);var g=o.node(r.w);i.info("abc88 InsertEdge: ",a),g.intersect&&p.intersect&&(d=d.slice(1,a.points.length-1),d.unshift(p.intersect(d[0])),i.info("Last point",d[d.length-1],g,g.intersect(d[d.length-1])),d.push(g.intersect(d[d.length-1]))),a.toCluster&&(i.info("to cluster abc88",n[a.toCluster]),d=Y(a.points,n[a.toCluster].node),h=!0),a.fromCluster&&(i.info("from cluster abc88",n[a.fromCluster]),d=Y(d.reverse(),n[a.fromCluster].node).reverse(),h=!0);const y=d.filter((t=>!Number.isNaN(t.y)));let f;f=("graph"===s||"flowchart"===s)&&a.curve||l;const b=c().x((function(t){return t.x})).y((function(t){return t.y})).curve(f);let w;switch(a.thickness){case"normal":w="edge-thickness-normal";break;case"thick":case"invisible":w="edge-thickness-thick";break;default:w=""}switch(a.pattern){case"solid":w+=" edge-pattern-solid";break;case"dotted":w+=" edge-pattern-dotted";break;case"dashed":w+=" edge-pattern-dashed"}const u=t.append("path").attr("d",b(y)).attr("id",a.id).attr("class"," "+w+(a.classes?" "+a.classes:"")).attr("style",a.style);let x="";switch((e().flowchart.arrowMarkerAbsolute||e().state.arrowMarkerAbsolute)&&(x=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,x=x.replace(/\(/g,"\\("),x=x.replace(/\)/g,"\\)")),i.info("arrowTypeStart",a.arrowTypeStart),i.info("arrowTypeEnd",a.arrowTypeEnd),a.arrowTypeStart){case"arrow_cross":u.attr("marker-start","url("+x+"#"+s+"-crossStart)");break;case"arrow_point":u.attr("marker-start","url("+x+"#"+s+"-pointStart)");break;case"arrow_barb":u.attr("marker-start","url("+x+"#"+s+"-barbStart)");break;case"arrow_circle":u.attr("marker-start","url("+x+"#"+s+"-circleStart)");break;case"aggregation":u.attr("marker-start","url("+x+"#"+s+"-aggregationStart)");break;case"extension":u.attr("marker-start","url("+x+"#"+s+"-extensionStart)");break;case"composition":u.attr("marker-start","url("+x+"#"+s+"-compositionStart)");break;case"dependency":u.attr("marker-start","url("+x+"#"+s+"-dependencyStart)");break;case"lollipop":u.attr("marker-start","url("+x+"#"+s+"-lollipopStart)")}switch(a.arrowTypeEnd){case"arrow_cross":u.attr("marker-end","url("+x+"#"+s+"-crossEnd)");break;case"arrow_point":u.attr("marker-end","url("+x+"#"+s+"-pointEnd)");break;case"arrow_barb":u.attr("marker-end","url("+x+"#"+s+"-barbEnd)");break;case"arrow_circle":u.attr("marker-end","url("+x+"#"+s+"-circleEnd)");break;case"aggregation":u.attr("marker-end","url("+x+"#"+s+"-aggregationEnd)");break;case"extension":u.attr("marker-end","url("+x+"#"+s+"-extensionEnd)");break;case"composition":u.attr("marker-end","url("+x+"#"+s+"-compositionEnd)");break;case"dependency":u.attr("marker-end","url("+x+"#"+s+"-dependencyEnd)");break;case"lollipop":u.attr("marker-end","url("+x+"#"+s+"-lollipopEnd)")}let m={};return h&&(m.updatedPath=d),m.originalPath=a.points,m};export{B as a,H as b,j as c,W as d,C as e,I as f,g,m as h,p as i,y as l,P as p,E as s,f as u}; diff --git a/assets/env.html.7adbd95d.js b/assets/env.html.a8947df8.js similarity index 87% rename from assets/env.html.7adbd95d.js rename to assets/env.html.a8947df8.js index ee8ea4796..de15e21b0 100644 --- a/assets/env.html.7adbd95d.js +++ b/assets/env.html.a8947df8.js @@ -1 +1 @@ -import{r as e,o as a,c as i,a as o,b as n,F as r,e as l,d as t}from"./app.755d843f.js";const s={},d=o("h1",{id:"environment-variables",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#environment-variables","aria-hidden":"true"},"#"),l(" Environment Variables")],-1),c=o("p",null,"Xray provides the following environment variables for modifying some of its underlying configurations.",-1),u=o("h2",{id:"xray-asset-location",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#xray-asset-location","aria-hidden":"true"},"#"),l(" Xray Asset Location")],-1),f=o("li",null,[l("Name:"),o("code",null,"xray.location.asset"),l(" or "),o("code",null,"XRAY_LOCATION_ASSET"),l("。")],-1),h=l("Default value:specified "),p={href:"https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard",target:"_blank",rel:"noopener noreferrer"},m=l("FHS"),b=l(" directory or the same path as the Xray file."),g=t('

    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:

    ./\n/usr/local/share/xray\n/usr/share/xray\n
    1
    2
    3

    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);s.render=function(l,t){const s=e("OutboundLink");return a(),i(r,null,[d,c,u,o("ul",null,[f,o("li",null,[h,o("a",p,[m,n(s)]),b])]),g],64)};export default s; +import{r as e,o as a,c as i,a as o,b as n,F as r,e as l,d as t}from"./app.48111a85.js";const s={},c=o("h1",{id:"environment-variables",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#environment-variables","aria-hidden":"true"},"#"),l(" Environment Variables")],-1),d=o("p",null,"Xray provides the following environment variables for modifying some of its underlying configurations.",-1),u=o("h2",{id:"xray-asset-location",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#xray-asset-location","aria-hidden":"true"},"#"),l(" Xray Asset Location")],-1),h=o("li",null,[l("Name:"),o("code",null,"xray.location.asset"),l(" or "),o("code",null,"XRAY_LOCATION_ASSET"),l("。")],-1),f=l("Default value:specified "),p={href:"https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard",target:"_blank",rel:"noopener noreferrer"},m=l("FHS"),b=l(" directory or the same path as the Xray file."),g=t('

    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:

    ./\n/usr/local/share/xray\n/usr/share/xray\n
    1
    2
    3

    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);s.render=function(l,t){const s=e("OutboundLink");return a(),i(r,null,[c,d,u,o("ul",null,[h,o("li",null,[f,o("a",p,[m,n(s)]),b])]),g],64)};export default s; diff --git a/assets/env.html.993365d3.js b/assets/env.html.dd8e636d.js similarity index 97% rename from assets/env.html.993365d3.js rename to assets/env.html.dd8e636d.js index 42a2e8508..04364d755 100644 --- a/assets/env.html.993365d3.js +++ b/assets/env.html.dd8e636d.js @@ -1 +1 @@ -import{r as e,o as a,c as r,a as n,b as l,F as i,e as d,d as s}from"./app.755d843f.js";const o={},c=n("h1",{id:"环境变量",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#环境变量","aria-hidden":"true"},"#"),d(" 环境变量")],-1),t=n("p",null,"Xray 提供以下环境变量以供修改 Xray 的一些底层配置。",-1),u=n("h2",{id:"资源文件路径",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#资源文件路径","aria-hidden":"true"},"#"),d(" 资源文件路径")],-1),h=n("li",null,[d("名称:"),n("code",null,"xray.location.asset"),d(" 或 "),n("code",null,"XRAY_LOCATION_ASSET"),d("。")],-1),p=d("默认值:特定 "),b={href:"https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard",target:"_blank",rel:"noopener noreferrer"},x=d("FHS"),f=d(" 目录或 Xray 文件同路径。"),y=s('

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

    ./\n/usr/local/share/xray\n/usr/share/xray\n
    1
    2
    3

    配置文件位置

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

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

    多配置目录

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

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

    ',8);o.render=function(d,s){const o=e("OutboundLink");return a(),r(i,null,[c,t,u,n("ul",null,[h,n("li",null,[p,n("a",b,[x,l(o)]),f])]),y],64)};export default o; +import{r as e,o as a,c as r,a as n,b as l,F as i,e as d,d as s}from"./app.48111a85.js";const o={},c=n("h1",{id:"环境变量",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#环境变量","aria-hidden":"true"},"#"),d(" 环境变量")],-1),t=n("p",null,"Xray 提供以下环境变量以供修改 Xray 的一些底层配置。",-1),u=n("h2",{id:"资源文件路径",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#资源文件路径","aria-hidden":"true"},"#"),d(" 资源文件路径")],-1),h=n("li",null,[d("名称:"),n("code",null,"xray.location.asset"),d(" 或 "),n("code",null,"XRAY_LOCATION_ASSET"),d("。")],-1),p=d("默认值:特定 "),b={href:"https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard",target:"_blank",rel:"noopener noreferrer"},x=d("FHS"),f=d(" 目录或 Xray 文件同路径。"),y=s('

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

    ./\n/usr/local/share/xray\n/usr/share/xray\n
    1
    2
    3

    配置文件位置

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

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

    多配置目录

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

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

    ',8);o.render=function(d,s){const o=e("OutboundLink");return a(),r(i,null,[c,t,u,n("ul",null,[h,n("li",null,[p,n("a",b,[x,l(o)]),f])]),y],64)};export default o; diff --git a/assets/erDiagram-5e907343.259e9da2.js b/assets/erDiagram-5e907343.ea1d1557.js similarity index 91% rename from assets/erDiagram-5e907343.259e9da2.js rename to assets/erDiagram-5e907343.ea1d1557.js index 3f85ab2a7..f133174c1 100644 --- a/assets/erDiagram-5e907343.259e9da2.js +++ b/assets/erDiagram-5e907343.ea1d1557.js @@ -1 +1 @@ -import{c as t,s as e,g as r,b as i,a,v as n,x as s,m as o,l as c,z as l,h,y as d,i as u,a5 as y,a7 as p}from"./mermaid.core.a66200b0.js";import{G as _,l as f}from"./layout.2f099f66.js";import{l as m}from"./line.f17bed9e.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";var g=/^(?:[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;const E=[];for(let F=0;F<256;++F)E.push((F+256).toString(16).slice(1));function b(t){if(!function(t){return"string"==typeof t&&g.test(t)}(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]=255&e,r[4]=(e=parseInt(t.slice(9,13),16))>>>8,r[5]=255&e,r[6]=(e=parseInt(t.slice(14,18),16))>>>8,r[7]=255&e,r[8]=(e=parseInt(t.slice(19,23),16))>>>8,r[9]=255&e,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]=255&e,r}function O(t,e,r,i){switch(t){case 0:return e&r^~e&i;case 1:return e^r^i;case 2:return e&r^e&i^r&i;case 3:return e^r^i}}function k(t,e){return t<>>32-e}const R=function(t,e,r){function i(t,i,a,n){var s;if("string"==typeof t&&(t=function(t){t=unescape(encodeURIComponent(t));const e=[];for(let r=0;r>>0;l=c,c=o,o=k(a,30)>>>0,a=i,i=s}r[0]=r[0]+i>>>0,r[1]=r[1]+a>>>0,r[2]=r[2]+o>>>0,r[3]=r[3]+c>>>0,r[4]=r[4]+l>>>0}return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,255&r[0],r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,255&r[1],r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,255&r[2],r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,255&r[3],r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,255&r[4]]}));var N=function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[1,2],r=[1,5],i=[6,9,11,23,25,27,29,30,31,52],a=[1,17],n=[1,18],s=[1,19],o=[1,20],c=[1,21],l=[1,22],h=[1,25],d=[1,30],u=[1,31],y=[1,32],p=[1,33],_=[1,34],f=[6,9,11,15,20,23,25,27,29,30,31,44,45,46,47,48,52],m=[1,46],g=[30,31,49,50],E=[4,6,9,11,23,25,27,29,30,31,52],b=[44,45,46,47,48],O=[22,37],k=[1,66],R=[1,65],N=[22,37,39,41],x={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,entityName:17,relSpec:18,role:19,BLOCK_START:20,attributes:21,BLOCK_STOP:22,title:23,title_value:24,acc_title:25,acc_title_value:26,acc_descr:27,acc_descr_value:28,acc_descr_multiline_value:29,ALPHANUM:30,ENTITY_NAME:31,attribute:32,attributeType:33,attributeName:34,attributeKeyTypeList:35,attributeComment:36,ATTRIBUTE_WORD:37,attributeKeyType:38,COMMA:39,ATTRIBUTE_KEY:40,COMMENT:41,cardinality:42,relType:43,ZERO_OR_ONE:44,ZERO_OR_MORE:45,ONE_OR_MORE:46,ONLY_ONE:47,MD_PARENT:48,NON_IDENTIFYING:49,IDENTIFYING:50,WORD:51,open_directive:52,type_directive:53,arg_directive:54,close_directive:55,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",20:"BLOCK_START",22:"BLOCK_STOP",23:"title",24:"title_value",25:"acc_title",26:"acc_title_value",27:"acc_descr",28:"acc_descr_value",29:"acc_descr_multiline_value",30:"ALPHANUM",31:"ENTITY_NAME",37:"ATTRIBUTE_WORD",39:"COMMA",40:"ATTRIBUTE_KEY",41:"COMMENT",44:"ZERO_OR_ONE",45:"ZERO_OR_MORE",46:"ONE_OR_MORE",47:"ONLY_ONE",48:"MD_PARENT",49:"NON_IDENTIFYING",50:"IDENTIFYING",51:"WORD",52:"open_directive",53:"type_directive",54:"arg_directive",55:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,5],[10,4],[10,3],[10,1],[10,2],[10,2],[10,2],[10,1],[17,1],[17,1],[21,1],[21,2],[32,2],[32,3],[32,3],[32,4],[33,1],[34,1],[35,1],[35,3],[38,1],[36,1],[18,3],[42,1],[42,1],[42,1],[42,1],[42,1],[43,1],[43,1],[19,1],[19,1],[19,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,r,i,a,n,s){var o=n.length-1;switch(a){case 1:break;case 3:this.$=[];break;case 4:n[o-1].push(n[o]),this.$=n[o-1];break;case 5:case 6:this.$=n[o];break;case 7:case 8:this.$=[];break;case 12:i.addEntity(n[o-4]),i.addEntity(n[o-2]),i.addRelationship(n[o-4],n[o],n[o-2],n[o-3]);break;case 13:i.addEntity(n[o-3]),i.addAttributes(n[o-3],n[o-1]);break;case 14:i.addEntity(n[o-2]);break;case 15:i.addEntity(n[o]);break;case 16:case 17:this.$=n[o].trim(),i.setAccTitle(this.$);break;case 18:case 19:this.$=n[o].trim(),i.setAccDescription(this.$);break;case 20:case 44:this.$=n[o];break;case 21:case 42:case 43:this.$=n[o].replace(/"/g,"");break;case 22:case 30:this.$=[n[o]];break;case 23:n[o].push(n[o-1]),this.$=n[o];break;case 24:this.$={attributeType:n[o-1],attributeName:n[o]};break;case 25:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeKeyTypeList:n[o]};break;case 26:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeComment:n[o]};break;case 27:this.$={attributeType:n[o-3],attributeName:n[o-2],attributeKeyTypeList:n[o-1],attributeComment:n[o]};break;case 28:case 29:case 32:this.$=n[o];break;case 31:n[o-2].push(n[o]),this.$=n[o-2];break;case 33:this.$=n[o].replace(/"/g,"");break;case 34:this.$={cardA:n[o],relType:n[o-1],cardB:n[o-2]};break;case 35:this.$=i.Cardinality.ZERO_OR_ONE;break;case 36:this.$=i.Cardinality.ZERO_OR_MORE;break;case 37:this.$=i.Cardinality.ONE_OR_MORE;break;case 38:this.$=i.Cardinality.ONLY_ONE;break;case 39:this.$=i.Cardinality.MD_PARENT;break;case 40:this.$=i.Identification.NON_IDENTIFYING;break;case 41:this.$=i.Identification.IDENTIFYING;break;case 45:i.parseDirective("%%{","open_directive");break;case 46:i.parseDirective(n[o],"type_directive");break;case 47:n[o]=n[o].trim().replace(/'/g,'"'),i.parseDirective(n[o],"arg_directive");break;case 48:i.parseDirective("}%%","close_directive","er")}},table:[{3:1,4:e,7:3,12:4,52:r},{1:[3]},t(i,[2,3],{5:6}),{3:7,4:e,7:3,12:4,52:r},{13:8,53:[1,9]},{53:[2,45]},{6:[1,10],7:15,8:11,9:[1,12],10:13,11:[1,14],12:4,17:16,23:a,25:n,27:s,29:o,30:c,31:l,52:r},{1:[2,2]},{14:23,15:[1,24],55:h},t([15,55],[2,46]),t(i,[2,8],{1:[2,1]}),t(i,[2,4]),{7:15,10:26,12:4,17:16,23:a,25:n,27:s,29:o,30:c,31:l,52:r},t(i,[2,6]),t(i,[2,7]),t(i,[2,11]),t(i,[2,15],{18:27,42:29,20:[1,28],44:d,45:u,46:y,47:p,48:_}),{24:[1,35]},{26:[1,36]},{28:[1,37]},t(i,[2,19]),t(f,[2,20]),t(f,[2,21]),{11:[1,38]},{16:39,54:[1,40]},{11:[2,48]},t(i,[2,5]),{17:41,30:c,31:l},{21:42,22:[1,43],32:44,33:45,37:m},{43:47,49:[1,48],50:[1,49]},t(g,[2,35]),t(g,[2,36]),t(g,[2,37]),t(g,[2,38]),t(g,[2,39]),t(i,[2,16]),t(i,[2,17]),t(i,[2,18]),t(E,[2,9]),{14:50,55:h},{55:[2,47]},{15:[1,51]},{22:[1,52]},t(i,[2,14]),{21:53,22:[2,22],32:44,33:45,37:m},{34:54,37:[1,55]},{37:[2,28]},{42:56,44:d,45:u,46:y,47:p,48:_},t(b,[2,40]),t(b,[2,41]),{11:[1,57]},{19:58,30:[1,61],31:[1,60],51:[1,59]},t(i,[2,13]),{22:[2,23]},t(O,[2,24],{35:62,36:63,38:64,40:k,41:R}),t([22,37,40,41],[2,29]),t([30,31],[2,34]),t(E,[2,10]),t(i,[2,12]),t(i,[2,42]),t(i,[2,43]),t(i,[2,44]),t(O,[2,25],{36:67,39:[1,68],41:R}),t(O,[2,26]),t(N,[2,30]),t(O,[2,33]),t(N,[2,32]),t(O,[2,27]),{38:69,40:k},t(N,[2,31])],defaultActions:{5:[2,45],7:[2,2],25:[2,48],40:[2,47],46:[2,28],53:[2,23]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=this,r=[0],i=[],a=[null],n=[],s=this.table,o="",c=0,l=0,h=2,d=1,u=n.slice.call(arguments,1),y=Object.create(this.lexer),p={yy:{}};for(var _ in this.yy)Object.prototype.hasOwnProperty.call(this.yy,_)&&(p.yy[_]=this.yy[_]);y.setInput(t,p.yy),p.yy.lexer=y,p.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var f=y.yylloc;n.push(f);var m=y.options&&y.options.ranges;function g(){var t;return"number"!=typeof(t=i.pop()||y.lex()||d)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,b,O,k,R,N,x,T,A={};;){if(b=r[r.length-1],this.defaultActions[b]?O=this.defaultActions[b]:(null==E&&(E=g()),O=s[b]&&s[b][E]),void 0===O||!O.length||!O[0]){var v="";for(R in T=[],s[b])this.terminals_[R]&&R>h&&T.push("'"+this.terminals_[R]+"'");v=y.showPosition?"Parse error on line "+(c+1)+":\n"+y.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(E==d?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(v,{text:y.match,token:this.terminals_[E]||E,line:y.yylineno,loc:f,expected:T})}if(O[0]instanceof Array&&O.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+E);switch(O[0]){case 1:r.push(E),a.push(y.yytext),n.push(y.yylloc),r.push(O[1]),E=null,l=y.yyleng,o=y.yytext,c=y.yylineno,f=y.yylloc;break;case 2:if(N=this.productions_[O[1]][1],A.$=a[a.length-N],A._$={first_line:n[n.length-(N||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(N||1)].first_column,last_column:n[n.length-1].last_column},m&&(A._$.range=[n[n.length-(N||1)].range[0],n[n.length-1].range[1]]),void 0!==(k=this.performAction.apply(A,[o,l,c,p.yy,O[1],a,n].concat(u))))return k;N&&(r=r.slice(0,-1*N*2),a=a.slice(0,-1*N),n=n.slice(0,-1*N)),r.push(this.productions_[O[1]][0]),a.push(A.$),n.push(A._$),x=s[r[r.length-2]][r[r.length-1]],r.push(x);break;case 3:return!0}}return!0}},T={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,r=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 i=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),r.length-1&&(this.yylineno-=r.length-1);var a=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:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var r,i,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var n in a)this[n]=a[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),n=0;ne[0].length)){if(e=r,i=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,a[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("acc_title"),25;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),27;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return this.begin("open_directive"),52;case 8:return this.begin("type_directive"),53;case 9:return this.popState(),this.begin("arg_directive"),15;case 10:return this.popState(),this.popState(),55;case 11:return 54;case 12:return 11;case 13:break;case 14:return 9;case 15:return 31;case 16:return 51;case 17:return 4;case 18:return this.begin("block"),20;case 19:return 39;case 20:break;case 21:return 40;case 22:case 23:return 37;case 24:return 41;case 25:break;case 26:return this.popState(),22;case 27:return e.yytext[0];case 28:return 44;case 29:case 30:case 31:return 46;case 32:case 33:return 44;case 34:case 35:case 36:case 37:case 38:return 45;case 39:return 46;case 40:return 45;case 41:return 46;case 42:case 43:case 44:case 45:return 47;case 46:return 44;case 47:return 45;case 48:return 46;case 49:return 48;case 50:return 49;case 51:case 52:return 50;case 53:case 54:case 55:return 49;case 56:return 30;case 57:return e.yytext[0];case 58:return 6}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:,)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:(.*?)[~](.*?)*[~])/i,/^(?:[A-Za-z_][A-Za-z0-9\-_\[\]\(\)]*)/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:[A-Za-z][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},open_directive:{rules:[8],inclusive:!1},type_directive:{rules:[9,10],inclusive:!1},arg_directive:{rules:[10,11],inclusive:!1},block:{rules:[19,20,21,22,23,24,25,26,27],inclusive:!1},INITIAL:{rules:[0,2,4,7,12,13,14,15,16,17,18,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58],inclusive:!0}}};function A(){this.yy={}}return x.lexer=T,A.prototype=x,x.Parser=A,new A}();N.parser=N;const x=N;let T={},A=[];const v=function(t){return void 0===T[t]&&(T[t]={attributes:[]},c.info("Added new entity :",t)),T[t]},M={Cardinality:{ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"},Identification:{NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},parseDirective:function(t,e,r){o.parseDirective(this,t,e,r)},getConfig:()=>t().er,addEntity:v,addAttributes:function(t,e){let r,i=v(t);for(r=e.length-1;r>=0;r--)i.attributes.push(e[r]),c.debug("Added attribute ",e[r].attributeName)},getEntities:()=>T,addRelationship:function(t,e,r,i){let a={entityA:t,roleA:e,entityB:r,relSpec:i};A.push(a),c.debug("Added new relationship :",a)},getRelationships:()=>A,clear:function(){T={},A=[],l()},setAccTitle:e,getAccTitle:r,setAccDescription:i,getAccDescription:a,setDiagramTitle:n,getDiagramTitle:s},D={ONLY_ONE_START:"ONLY_ONE_START",ONLY_ONE_END:"ONLY_ONE_END",ZERO_OR_ONE_START:"ZERO_OR_ONE_START",ZERO_OR_ONE_END:"ZERO_OR_ONE_END",ONE_OR_MORE_START:"ONE_OR_MORE_START",ONE_OR_MORE_END:"ONE_OR_MORE_END",ZERO_OR_MORE_START:"ZERO_OR_MORE_START",ZERO_OR_MORE_END:"ZERO_OR_MORE_END",MD_PARENT_END:"MD_PARENT_END",MD_PARENT_START:"MD_PARENT_START"},w=D,I=function(t,e){let r;t.append("defs").append("marker").attr("id",D.MD_PARENT_START).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"),t.append("defs").append("marker").attr("id",D.MD_PARENT_END).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"),t.append("defs").append("marker").attr("id",D.ONLY_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",D.ONLY_ONE_END).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,0 L3,18 M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",D.ZERO_OR_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",D.ZERO_OR_ONE_END).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,0 L21,18"),t.append("defs").append("marker").attr("id",D.ONE_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",D.ONE_OR_MORE_END).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"),r=t.append("defs").append("marker").attr("id",D.ZERO_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18"),r=t.append("defs").append("marker").attr("id",D.ZERO_OR_MORE_END).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},$=/[^\dA-Za-z](\W)*/g;let L={},S=new Map;const B=function(e,r,i){let a;return Object.keys(r).forEach((function(n){const s=function(t="",e=""){const r=t.replace($,"");return`${Y(e)}${Y(r)}${R(t,"28e9f9db-3c8d-5aa5-9faf-44286ae5937c")}`}(n,"entity");S.set(n,s);const o=e.append("g").attr("id",s);a=void 0===a?s:a;const c="text-"+s,l=o.append("text").classed("er entityLabel",!0).attr("id",c).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","middle").style("font-family",t().fontFamily).style("font-size",L.fontSize+"px").text(n),{width:h,height:d}=((e,r,i)=>{const a=L.entityPadding/3,n=L.entityPadding/3,s=.85*L.fontSize,o=r.node().getBBox(),c=[];let l=!1,h=!1,d=0,u=0,y=0,_=0,f=o.height+2*a,m=1;i.forEach((t=>{void 0!==t.attributeKeyTypeList&&t.attributeKeyTypeList.length>0&&(l=!0),void 0!==t.attributeComment&&(h=!0)})),i.forEach((i=>{const n=`${r.node().id}-attr-${m}`;let o=0;const g=p(i.attributeType),E=e.append("text").classed("er entityLabel",!0).attr("id",`${n}-type`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",t().fontFamily).style("font-size",s+"px").text(g),b=e.append("text").classed("er entityLabel",!0).attr("id",`${n}-name`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",t().fontFamily).style("font-size",s+"px").text(i.attributeName),O={};O.tn=E,O.nn=b;const k=E.node().getBBox(),R=b.node().getBBox();if(d=Math.max(d,k.width),u=Math.max(u,R.width),o=Math.max(k.height,R.height),l){const r=void 0!==i.attributeKeyTypeList?i.attributeKeyTypeList.join(","):"",a=e.append("text").classed("er entityLabel",!0).attr("id",`${n}-key`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",t().fontFamily).style("font-size",s+"px").text(r);O.kn=a;const c=a.node().getBBox();y=Math.max(y,c.width),o=Math.max(o,c.height)}if(h){const r=e.append("text").classed("er entityLabel",!0).attr("id",`${n}-comment`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",t().fontFamily).style("font-size",s+"px").text(i.attributeComment||"");O.cn=r;const a=r.node().getBBox();_=Math.max(_,a.width),o=Math.max(o,a.height)}O.height=o,c.push(O),f+=o+2*a,m+=1}));let g=4;l&&(g+=2),h&&(g+=2);const E=d+u+y+_,b={width:Math.max(L.minEntityWidth,Math.max(o.width+2*L.entityPadding,E+n*g)),height:i.length>0?f:Math.max(L.minEntityHeight,o.height+2*L.entityPadding)};if(i.length>0){const t=Math.max(0,(b.width-E-n*g)/(g/2));r.attr("transform","translate("+b.width/2+","+(a+o.height/2)+")");let i=o.height+2*a,s="attributeBoxOdd";c.forEach((r=>{const o=i+a+r.height/2;r.tn.attr("transform","translate("+n+","+o+")");const c=e.insert("rect","#"+r.tn.node().id).classed(`er ${s}`,!0).attr("x",0).attr("y",i).attr("width",d+2*n+t).attr("height",r.height+2*a),p=parseFloat(c.attr("x"))+parseFloat(c.attr("width"));r.nn.attr("transform","translate("+(p+n)+","+o+")");const f=e.insert("rect","#"+r.nn.node().id).classed(`er ${s}`,!0).attr("x",p).attr("y",i).attr("width",u+2*n+t).attr("height",r.height+2*a);let m=parseFloat(f.attr("x"))+parseFloat(f.attr("width"));if(l){r.kn.attr("transform","translate("+(m+n)+","+o+")");const c=e.insert("rect","#"+r.kn.node().id).classed(`er ${s}`,!0).attr("x",m).attr("y",i).attr("width",y+2*n+t).attr("height",r.height+2*a);m=parseFloat(c.attr("x"))+parseFloat(c.attr("width"))}h&&(r.cn.attr("transform","translate("+(m+n)+","+o+")"),e.insert("rect","#"+r.cn.node().id).classed(`er ${s}`,"true").attr("x",m).attr("y",i).attr("width",_+2*n+t).attr("height",r.height+2*a)),i+=r.height+2*a,s="attributeBoxOdd"===s?"attributeBoxEven":"attributeBoxOdd"}))}else b.height=Math.max(L.minEntityHeight,f),r.attr("transform","translate("+b.width/2+","+b.height/2+")");return b})(o,l,r[n].attributes),u=o.insert("rect","#"+c).classed("er entityBox",!0).attr("x",0).attr("y",0).attr("width",h).attr("height",d).node().getBBox();i.setNode(s,{width:u.width,height:u.height,shape:"rect",id:s})})),a},C=function(t){return(t.entityA+t.roleA+t.entityB).replace(/\s/g,"")};let P=0;function Y(t=""){return t.length>0?`${t}-`:""}const Z={parser:x,db:M,renderer:{setConf:function(t){const e=Object.keys(t);for(const r of e)L[r]=t[r]},draw:function(e,r,i,a){L=t().er,c.info("Drawing ER diagram");const n=t().securityLevel;let s;"sandbox"===n&&(s=h("#i"+r));const o=h("sandbox"===n?s.nodes()[0].contentDocument.body:"body").select(`[id='${r}']`);let l;I(o,L),l=new _({multigraph:!0,directed:!0,compound:!1}).setGraph({rankdir:L.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));const p=B(o,a.db.getEntities(),l),g=function(t,e){return t.forEach((function(t){e.setEdge(S.get(t.entityA),S.get(t.entityB),{relationship:t},C(t))})),t}(a.db.getRelationships(),l);var E,b;f(l),E=o,(b=l).nodes().forEach((function(t){void 0!==t&&void 0!==b.node(t)&&E.select("#"+t).attr("transform","translate("+(b.node(t).x-b.node(t).width/2)+","+(b.node(t).y-b.node(t).height/2)+" )")})),g.forEach((function(e){!function(e,r,i,a,n){P++;const s=i.edge(S.get(r.entityA),S.get(r.entityB),C(r)),o=m().x((function(t){return t.x})).y((function(t){return t.y})).curve(y),c=e.insert("path","#"+a).classed("er relationshipLine",!0).attr("d",o(s.points)).style("stroke",L.stroke).style("fill","none");r.relSpec.relType===n.db.Identification.NON_IDENTIFYING&&c.attr("stroke-dasharray","8,8");let l="";switch(L.arrowMarkerAbsolute&&(l=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,l=l.replace(/\(/g,"\\("),l=l.replace(/\)/g,"\\)")),r.relSpec.cardA){case n.db.Cardinality.ZERO_OR_ONE:c.attr("marker-end","url("+l+"#"+w.ZERO_OR_ONE_END+")");break;case n.db.Cardinality.ZERO_OR_MORE:c.attr("marker-end","url("+l+"#"+w.ZERO_OR_MORE_END+")");break;case n.db.Cardinality.ONE_OR_MORE:c.attr("marker-end","url("+l+"#"+w.ONE_OR_MORE_END+")");break;case n.db.Cardinality.ONLY_ONE:c.attr("marker-end","url("+l+"#"+w.ONLY_ONE_END+")");break;case n.db.Cardinality.MD_PARENT:c.attr("marker-end","url("+l+"#"+w.MD_PARENT_END+")")}switch(r.relSpec.cardB){case n.db.Cardinality.ZERO_OR_ONE:c.attr("marker-start","url("+l+"#"+w.ZERO_OR_ONE_START+")");break;case n.db.Cardinality.ZERO_OR_MORE:c.attr("marker-start","url("+l+"#"+w.ZERO_OR_MORE_START+")");break;case n.db.Cardinality.ONE_OR_MORE:c.attr("marker-start","url("+l+"#"+w.ONE_OR_MORE_START+")");break;case n.db.Cardinality.ONLY_ONE:c.attr("marker-start","url("+l+"#"+w.ONLY_ONE_START+")");break;case n.db.Cardinality.MD_PARENT:c.attr("marker-start","url("+l+"#"+w.MD_PARENT_START+")")}const h=c.node().getTotalLength(),d=c.node().getPointAtLength(.5*h),u="rel"+P,p=e.append("text").classed("er relationshipLabel",!0).attr("id",u).attr("x",d.x).attr("y",d.y).style("text-anchor","middle").style("dominant-baseline","middle").style("font-family",t().fontFamily).style("font-size",L.fontSize+"px").text(r.roleA).node().getBBox();e.insert("rect","#"+u).classed("er relationshipLabelBox",!0).attr("x",d.x-p.width/2).attr("y",d.y-p.height/2).attr("width",p.width).attr("height",p.height)}(o,e,l,p,a)}));const O=L.diagramPadding;d.insertTitle(o,"entityTitleText",L.titleTopMargin,a.db.getDiagramTitle());const k=o.node().getBBox(),R=k.width+2*O,N=k.height+2*O;u(o,N,R,L.useMaxWidth),o.attr("viewBox",`${k.x-O} ${k.y-O} ${R} ${N}`)}},styles:t=>`\n .entityBox {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxOdd {\n fill: ${t.attributeBackgroundColorOdd};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxEven {\n fill: ${t.attributeBackgroundColorEven};\n stroke: ${t.nodeBorder};\n }\n\n .relationshipLabelBox {\n fill: ${t.tertiaryColor};\n opacity: 0.7;\n background-color: ${t.tertiaryColor};\n rect {\n opacity: 0.5;\n }\n }\n\n .relationshipLine {\n stroke: ${t.lineColor};\n }\n\n .entityTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n } \n #MD_PARENT_START {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n #MD_PARENT_END {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n \n`};export{Z as diagram}; +import{c as t,s as e,g as r,b as i,a,v as n,x as s,m as o,l as c,z as l,h,y as d,i as u,a5 as y,a7 as p}from"./mermaid.core.3a590193.js";import{G as _,l as f}from"./layout.02c3e151.js";import{l as m}from"./line.53b161c2.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";var g=/^(?:[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;const E=[];for(let F=0;F<256;++F)E.push((F+256).toString(16).slice(1));function O(t){if(!function(t){return"string"==typeof t&&g.test(t)}(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]=255&e,r[4]=(e=parseInt(t.slice(9,13),16))>>>8,r[5]=255&e,r[6]=(e=parseInt(t.slice(14,18),16))>>>8,r[7]=255&e,r[8]=(e=parseInt(t.slice(19,23),16))>>>8,r[9]=255&e,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]=255&e,r}function b(t,e,r,i){switch(t){case 0:return e&r^~e&i;case 1:return e^r^i;case 2:return e&r^e&i^r&i;case 3:return e^r^i}}function k(t,e){return t<>>32-e}const R=function(t,e,r){function i(t,i,a,n){var s;if("string"==typeof t&&(t=function(t){t=unescape(encodeURIComponent(t));const e=[];for(let r=0;r>>0;l=c,c=o,o=k(a,30)>>>0,a=i,i=s}r[0]=r[0]+i>>>0,r[1]=r[1]+a>>>0,r[2]=r[2]+o>>>0,r[3]=r[3]+c>>>0,r[4]=r[4]+l>>>0}return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,255&r[0],r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,255&r[1],r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,255&r[2],r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,255&r[3],r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,255&r[4]]}));var N=function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[1,2],r=[1,5],i=[6,9,11,23,25,27,29,30,31,52],a=[1,17],n=[1,18],s=[1,19],o=[1,20],c=[1,21],l=[1,22],h=[1,25],d=[1,30],u=[1,31],y=[1,32],p=[1,33],_=[1,34],f=[6,9,11,15,20,23,25,27,29,30,31,44,45,46,47,48,52],m=[1,46],g=[30,31,49,50],E=[4,6,9,11,23,25,27,29,30,31,52],O=[44,45,46,47,48],b=[22,37],k=[1,66],R=[1,65],N=[22,37,39,41],x={trace:function(){},yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,entityName:17,relSpec:18,role:19,BLOCK_START:20,attributes:21,BLOCK_STOP:22,title:23,title_value:24,acc_title:25,acc_title_value:26,acc_descr:27,acc_descr_value:28,acc_descr_multiline_value:29,ALPHANUM:30,ENTITY_NAME:31,attribute:32,attributeType:33,attributeName:34,attributeKeyTypeList:35,attributeComment:36,ATTRIBUTE_WORD:37,attributeKeyType:38,COMMA:39,ATTRIBUTE_KEY:40,COMMENT:41,cardinality:42,relType:43,ZERO_OR_ONE:44,ZERO_OR_MORE:45,ONE_OR_MORE:46,ONLY_ONE:47,MD_PARENT:48,NON_IDENTIFYING:49,IDENTIFYING:50,WORD:51,open_directive:52,type_directive:53,arg_directive:54,close_directive:55,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",20:"BLOCK_START",22:"BLOCK_STOP",23:"title",24:"title_value",25:"acc_title",26:"acc_title_value",27:"acc_descr",28:"acc_descr_value",29:"acc_descr_multiline_value",30:"ALPHANUM",31:"ENTITY_NAME",37:"ATTRIBUTE_WORD",39:"COMMA",40:"ATTRIBUTE_KEY",41:"COMMENT",44:"ZERO_OR_ONE",45:"ZERO_OR_MORE",46:"ONE_OR_MORE",47:"ONLY_ONE",48:"MD_PARENT",49:"NON_IDENTIFYING",50:"IDENTIFYING",51:"WORD",52:"open_directive",53:"type_directive",54:"arg_directive",55:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,5],[10,4],[10,3],[10,1],[10,2],[10,2],[10,2],[10,1],[17,1],[17,1],[21,1],[21,2],[32,2],[32,3],[32,3],[32,4],[33,1],[34,1],[35,1],[35,3],[38,1],[36,1],[18,3],[42,1],[42,1],[42,1],[42,1],[42,1],[43,1],[43,1],[19,1],[19,1],[19,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,r,i,a,n,s){var o=n.length-1;switch(a){case 1:break;case 3:this.$=[];break;case 4:n[o-1].push(n[o]),this.$=n[o-1];break;case 5:case 6:this.$=n[o];break;case 7:case 8:this.$=[];break;case 12:i.addEntity(n[o-4]),i.addEntity(n[o-2]),i.addRelationship(n[o-4],n[o],n[o-2],n[o-3]);break;case 13:i.addEntity(n[o-3]),i.addAttributes(n[o-3],n[o-1]);break;case 14:i.addEntity(n[o-2]);break;case 15:i.addEntity(n[o]);break;case 16:case 17:this.$=n[o].trim(),i.setAccTitle(this.$);break;case 18:case 19:this.$=n[o].trim(),i.setAccDescription(this.$);break;case 20:case 44:this.$=n[o];break;case 21:case 42:case 43:this.$=n[o].replace(/"/g,"");break;case 22:case 30:this.$=[n[o]];break;case 23:n[o].push(n[o-1]),this.$=n[o];break;case 24:this.$={attributeType:n[o-1],attributeName:n[o]};break;case 25:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeKeyTypeList:n[o]};break;case 26:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeComment:n[o]};break;case 27:this.$={attributeType:n[o-3],attributeName:n[o-2],attributeKeyTypeList:n[o-1],attributeComment:n[o]};break;case 28:case 29:case 32:this.$=n[o];break;case 31:n[o-2].push(n[o]),this.$=n[o-2];break;case 33:this.$=n[o].replace(/"/g,"");break;case 34:this.$={cardA:n[o],relType:n[o-1],cardB:n[o-2]};break;case 35:this.$=i.Cardinality.ZERO_OR_ONE;break;case 36:this.$=i.Cardinality.ZERO_OR_MORE;break;case 37:this.$=i.Cardinality.ONE_OR_MORE;break;case 38:this.$=i.Cardinality.ONLY_ONE;break;case 39:this.$=i.Cardinality.MD_PARENT;break;case 40:this.$=i.Identification.NON_IDENTIFYING;break;case 41:this.$=i.Identification.IDENTIFYING;break;case 45:i.parseDirective("%%{","open_directive");break;case 46:i.parseDirective(n[o],"type_directive");break;case 47:n[o]=n[o].trim().replace(/'/g,'"'),i.parseDirective(n[o],"arg_directive");break;case 48:i.parseDirective("}%%","close_directive","er")}},table:[{3:1,4:e,7:3,12:4,52:r},{1:[3]},t(i,[2,3],{5:6}),{3:7,4:e,7:3,12:4,52:r},{13:8,53:[1,9]},{53:[2,45]},{6:[1,10],7:15,8:11,9:[1,12],10:13,11:[1,14],12:4,17:16,23:a,25:n,27:s,29:o,30:c,31:l,52:r},{1:[2,2]},{14:23,15:[1,24],55:h},t([15,55],[2,46]),t(i,[2,8],{1:[2,1]}),t(i,[2,4]),{7:15,10:26,12:4,17:16,23:a,25:n,27:s,29:o,30:c,31:l,52:r},t(i,[2,6]),t(i,[2,7]),t(i,[2,11]),t(i,[2,15],{18:27,42:29,20:[1,28],44:d,45:u,46:y,47:p,48:_}),{24:[1,35]},{26:[1,36]},{28:[1,37]},t(i,[2,19]),t(f,[2,20]),t(f,[2,21]),{11:[1,38]},{16:39,54:[1,40]},{11:[2,48]},t(i,[2,5]),{17:41,30:c,31:l},{21:42,22:[1,43],32:44,33:45,37:m},{43:47,49:[1,48],50:[1,49]},t(g,[2,35]),t(g,[2,36]),t(g,[2,37]),t(g,[2,38]),t(g,[2,39]),t(i,[2,16]),t(i,[2,17]),t(i,[2,18]),t(E,[2,9]),{14:50,55:h},{55:[2,47]},{15:[1,51]},{22:[1,52]},t(i,[2,14]),{21:53,22:[2,22],32:44,33:45,37:m},{34:54,37:[1,55]},{37:[2,28]},{42:56,44:d,45:u,46:y,47:p,48:_},t(O,[2,40]),t(O,[2,41]),{11:[1,57]},{19:58,30:[1,61],31:[1,60],51:[1,59]},t(i,[2,13]),{22:[2,23]},t(b,[2,24],{35:62,36:63,38:64,40:k,41:R}),t([22,37,40,41],[2,29]),t([30,31],[2,34]),t(E,[2,10]),t(i,[2,12]),t(i,[2,42]),t(i,[2,43]),t(i,[2,44]),t(b,[2,25],{36:67,39:[1,68],41:R}),t(b,[2,26]),t(N,[2,30]),t(b,[2,33]),t(N,[2,32]),t(b,[2,27]),{38:69,40:k},t(N,[2,31])],defaultActions:{5:[2,45],7:[2,2],25:[2,48],40:[2,47],46:[2,28],53:[2,23]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=this,r=[0],i=[],a=[null],n=[],s=this.table,o="",c=0,l=0,h=2,d=1,u=n.slice.call(arguments,1),y=Object.create(this.lexer),p={yy:{}};for(var _ in this.yy)Object.prototype.hasOwnProperty.call(this.yy,_)&&(p.yy[_]=this.yy[_]);y.setInput(t,p.yy),p.yy.lexer=y,p.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var f=y.yylloc;n.push(f);var m=y.options&&y.options.ranges;function g(){var t;return"number"!=typeof(t=i.pop()||y.lex()||d)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var E,O,b,k,R,N,x,T,A={};;){if(O=r[r.length-1],this.defaultActions[O]?b=this.defaultActions[O]:(null==E&&(E=g()),b=s[O]&&s[O][E]),void 0===b||!b.length||!b[0]){var v="";for(R in T=[],s[O])this.terminals_[R]&&R>h&&T.push("'"+this.terminals_[R]+"'");v=y.showPosition?"Parse error on line "+(c+1)+":\n"+y.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[E]||E)+"'":"Parse error on line "+(c+1)+": Unexpected "+(E==d?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(v,{text:y.match,token:this.terminals_[E]||E,line:y.yylineno,loc:f,expected:T})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+O+", token: "+E);switch(b[0]){case 1:r.push(E),a.push(y.yytext),n.push(y.yylloc),r.push(b[1]),E=null,l=y.yyleng,o=y.yytext,c=y.yylineno,f=y.yylloc;break;case 2:if(N=this.productions_[b[1]][1],A.$=a[a.length-N],A._$={first_line:n[n.length-(N||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(N||1)].first_column,last_column:n[n.length-1].last_column},m&&(A._$.range=[n[n.length-(N||1)].range[0],n[n.length-1].range[1]]),void 0!==(k=this.performAction.apply(A,[o,l,c,p.yy,b[1],a,n].concat(u))))return k;N&&(r=r.slice(0,-1*N*2),a=a.slice(0,-1*N),n=n.slice(0,-1*N)),r.push(this.productions_[b[1]][0]),a.push(A.$),n.push(A._$),x=s[r[r.length-2]][r[r.length-1]],r.push(x);break;case 3:return!0}}return!0}},T={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,r=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 i=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),r.length-1&&(this.yylineno-=r.length-1);var a=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:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var r,i,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var n in a)this[n]=a[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),n=0;ne[0].length)){if(e=r,i=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,a[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("acc_title"),25;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),27;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return this.begin("open_directive"),52;case 8:return this.begin("type_directive"),53;case 9:return this.popState(),this.begin("arg_directive"),15;case 10:return this.popState(),this.popState(),55;case 11:return 54;case 12:return 11;case 13:break;case 14:return 9;case 15:return 31;case 16:return 51;case 17:return 4;case 18:return this.begin("block"),20;case 19:return 39;case 20:break;case 21:return 40;case 22:case 23:return 37;case 24:return 41;case 25:break;case 26:return this.popState(),22;case 27:return e.yytext[0];case 28:return 44;case 29:case 30:case 31:return 46;case 32:case 33:return 44;case 34:case 35:case 36:case 37:case 38:return 45;case 39:return 46;case 40:return 45;case 41:return 46;case 42:case 43:case 44:case 45:return 47;case 46:return 44;case 47:return 45;case 48:return 46;case 49:return 48;case 50:return 49;case 51:case 52:return 50;case 53:case 54:case 55:return 49;case 56:return 30;case 57:return e.yytext[0];case 58:return 6}},rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:,)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:(.*?)[~](.*?)*[~])/i,/^(?:[A-Za-z_][A-Za-z0-9\-_\[\]\(\)]*)/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:[A-Za-z][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},open_directive:{rules:[8],inclusive:!1},type_directive:{rules:[9,10],inclusive:!1},arg_directive:{rules:[10,11],inclusive:!1},block:{rules:[19,20,21,22,23,24,25,26,27],inclusive:!1},INITIAL:{rules:[0,2,4,7,12,13,14,15,16,17,18,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58],inclusive:!0}}};function A(){this.yy={}}return x.lexer=T,A.prototype=x,x.Parser=A,new A}();N.parser=N;const x=N;let T={},A=[];const v=function(t){return void 0===T[t]&&(T[t]={attributes:[]},c.info("Added new entity :",t)),T[t]},M={Cardinality:{ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"},Identification:{NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},parseDirective:function(t,e,r){o.parseDirective(this,t,e,r)},getConfig:()=>t().er,addEntity:v,addAttributes:function(t,e){let r,i=v(t);for(r=e.length-1;r>=0;r--)i.attributes.push(e[r]),c.debug("Added attribute ",e[r].attributeName)},getEntities:()=>T,addRelationship:function(t,e,r,i){let a={entityA:t,roleA:e,entityB:r,relSpec:i};A.push(a),c.debug("Added new relationship :",a)},getRelationships:()=>A,clear:function(){T={},A=[],l()},setAccTitle:e,getAccTitle:r,setAccDescription:i,getAccDescription:a,setDiagramTitle:n,getDiagramTitle:s},D={ONLY_ONE_START:"ONLY_ONE_START",ONLY_ONE_END:"ONLY_ONE_END",ZERO_OR_ONE_START:"ZERO_OR_ONE_START",ZERO_OR_ONE_END:"ZERO_OR_ONE_END",ONE_OR_MORE_START:"ONE_OR_MORE_START",ONE_OR_MORE_END:"ONE_OR_MORE_END",ZERO_OR_MORE_START:"ZERO_OR_MORE_START",ZERO_OR_MORE_END:"ZERO_OR_MORE_END",MD_PARENT_END:"MD_PARENT_END",MD_PARENT_START:"MD_PARENT_START"},w=D,I=function(t,e){let r;t.append("defs").append("marker").attr("id",D.MD_PARENT_START).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"),t.append("defs").append("marker").attr("id",D.MD_PARENT_END).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"),t.append("defs").append("marker").attr("id",D.ONLY_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",D.ONLY_ONE_END).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,0 L3,18 M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",D.ZERO_OR_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",D.ZERO_OR_ONE_END).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,0 L21,18"),t.append("defs").append("marker").attr("id",D.ONE_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",D.ONE_OR_MORE_END).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"),r=t.append("defs").append("marker").attr("id",D.ZERO_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18"),r=t.append("defs").append("marker").attr("id",D.ZERO_OR_MORE_END).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")},$=/[^\dA-Za-z](\W)*/g;let L={},S=new Map;const B=function(e,r,i){let a;return Object.keys(r).forEach((function(n){const s=function(t="",e=""){const r=t.replace($,"");return`${Y(e)}${Y(r)}${R(t,"28e9f9db-3c8d-5aa5-9faf-44286ae5937c")}`}(n,"entity");S.set(n,s);const o=e.append("g").attr("id",s);a=void 0===a?s:a;const c="text-"+s,l=o.append("text").classed("er entityLabel",!0).attr("id",c).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","middle").style("font-family",t().fontFamily).style("font-size",L.fontSize+"px").text(n),{width:h,height:d}=((e,r,i)=>{const a=L.entityPadding/3,n=L.entityPadding/3,s=.85*L.fontSize,o=r.node().getBBox(),c=[];let l=!1,h=!1,d=0,u=0,y=0,_=0,f=o.height+2*a,m=1;i.forEach((t=>{void 0!==t.attributeKeyTypeList&&t.attributeKeyTypeList.length>0&&(l=!0),void 0!==t.attributeComment&&(h=!0)})),i.forEach((i=>{const n=`${r.node().id}-attr-${m}`;let o=0;const g=p(i.attributeType),E=e.append("text").classed("er entityLabel",!0).attr("id",`${n}-type`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",t().fontFamily).style("font-size",s+"px").text(g),O=e.append("text").classed("er entityLabel",!0).attr("id",`${n}-name`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",t().fontFamily).style("font-size",s+"px").text(i.attributeName),b={};b.tn=E,b.nn=O;const k=E.node().getBBox(),R=O.node().getBBox();if(d=Math.max(d,k.width),u=Math.max(u,R.width),o=Math.max(k.height,R.height),l){const r=void 0!==i.attributeKeyTypeList?i.attributeKeyTypeList.join(","):"",a=e.append("text").classed("er entityLabel",!0).attr("id",`${n}-key`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",t().fontFamily).style("font-size",s+"px").text(r);b.kn=a;const c=a.node().getBBox();y=Math.max(y,c.width),o=Math.max(o,c.height)}if(h){const r=e.append("text").classed("er entityLabel",!0).attr("id",`${n}-comment`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",t().fontFamily).style("font-size",s+"px").text(i.attributeComment||"");b.cn=r;const a=r.node().getBBox();_=Math.max(_,a.width),o=Math.max(o,a.height)}b.height=o,c.push(b),f+=o+2*a,m+=1}));let g=4;l&&(g+=2),h&&(g+=2);const E=d+u+y+_,O={width:Math.max(L.minEntityWidth,Math.max(o.width+2*L.entityPadding,E+n*g)),height:i.length>0?f:Math.max(L.minEntityHeight,o.height+2*L.entityPadding)};if(i.length>0){const t=Math.max(0,(O.width-E-n*g)/(g/2));r.attr("transform","translate("+O.width/2+","+(a+o.height/2)+")");let i=o.height+2*a,s="attributeBoxOdd";c.forEach((r=>{const o=i+a+r.height/2;r.tn.attr("transform","translate("+n+","+o+")");const c=e.insert("rect","#"+r.tn.node().id).classed(`er ${s}`,!0).attr("x",0).attr("y",i).attr("width",d+2*n+t).attr("height",r.height+2*a),p=parseFloat(c.attr("x"))+parseFloat(c.attr("width"));r.nn.attr("transform","translate("+(p+n)+","+o+")");const f=e.insert("rect","#"+r.nn.node().id).classed(`er ${s}`,!0).attr("x",p).attr("y",i).attr("width",u+2*n+t).attr("height",r.height+2*a);let m=parseFloat(f.attr("x"))+parseFloat(f.attr("width"));if(l){r.kn.attr("transform","translate("+(m+n)+","+o+")");const c=e.insert("rect","#"+r.kn.node().id).classed(`er ${s}`,!0).attr("x",m).attr("y",i).attr("width",y+2*n+t).attr("height",r.height+2*a);m=parseFloat(c.attr("x"))+parseFloat(c.attr("width"))}h&&(r.cn.attr("transform","translate("+(m+n)+","+o+")"),e.insert("rect","#"+r.cn.node().id).classed(`er ${s}`,"true").attr("x",m).attr("y",i).attr("width",_+2*n+t).attr("height",r.height+2*a)),i+=r.height+2*a,s="attributeBoxOdd"===s?"attributeBoxEven":"attributeBoxOdd"}))}else O.height=Math.max(L.minEntityHeight,f),r.attr("transform","translate("+O.width/2+","+O.height/2+")");return O})(o,l,r[n].attributes),u=o.insert("rect","#"+c).classed("er entityBox",!0).attr("x",0).attr("y",0).attr("width",h).attr("height",d).node().getBBox();i.setNode(s,{width:u.width,height:u.height,shape:"rect",id:s})})),a},C=function(t){return(t.entityA+t.roleA+t.entityB).replace(/\s/g,"")};let P=0;function Y(t=""){return t.length>0?`${t}-`:""}const Z={parser:x,db:M,renderer:{setConf:function(t){const e=Object.keys(t);for(const r of e)L[r]=t[r]},draw:function(e,r,i,a){L=t().er,c.info("Drawing ER diagram");const n=t().securityLevel;let s;"sandbox"===n&&(s=h("#i"+r));const o=h("sandbox"===n?s.nodes()[0].contentDocument.body:"body").select(`[id='${r}']`);let l;I(o,L),l=new _({multigraph:!0,directed:!0,compound:!1}).setGraph({rankdir:L.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));const p=B(o,a.db.getEntities(),l),g=function(t,e){return t.forEach((function(t){e.setEdge(S.get(t.entityA),S.get(t.entityB),{relationship:t},C(t))})),t}(a.db.getRelationships(),l);var E,O;f(l),E=o,(O=l).nodes().forEach((function(t){void 0!==t&&void 0!==O.node(t)&&E.select("#"+t).attr("transform","translate("+(O.node(t).x-O.node(t).width/2)+","+(O.node(t).y-O.node(t).height/2)+" )")})),g.forEach((function(e){!function(e,r,i,a,n){P++;const s=i.edge(S.get(r.entityA),S.get(r.entityB),C(r)),o=m().x((function(t){return t.x})).y((function(t){return t.y})).curve(y),c=e.insert("path","#"+a).classed("er relationshipLine",!0).attr("d",o(s.points)).style("stroke",L.stroke).style("fill","none");r.relSpec.relType===n.db.Identification.NON_IDENTIFYING&&c.attr("stroke-dasharray","8,8");let l="";switch(L.arrowMarkerAbsolute&&(l=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,l=l.replace(/\(/g,"\\("),l=l.replace(/\)/g,"\\)")),r.relSpec.cardA){case n.db.Cardinality.ZERO_OR_ONE:c.attr("marker-end","url("+l+"#"+w.ZERO_OR_ONE_END+")");break;case n.db.Cardinality.ZERO_OR_MORE:c.attr("marker-end","url("+l+"#"+w.ZERO_OR_MORE_END+")");break;case n.db.Cardinality.ONE_OR_MORE:c.attr("marker-end","url("+l+"#"+w.ONE_OR_MORE_END+")");break;case n.db.Cardinality.ONLY_ONE:c.attr("marker-end","url("+l+"#"+w.ONLY_ONE_END+")");break;case n.db.Cardinality.MD_PARENT:c.attr("marker-end","url("+l+"#"+w.MD_PARENT_END+")")}switch(r.relSpec.cardB){case n.db.Cardinality.ZERO_OR_ONE:c.attr("marker-start","url("+l+"#"+w.ZERO_OR_ONE_START+")");break;case n.db.Cardinality.ZERO_OR_MORE:c.attr("marker-start","url("+l+"#"+w.ZERO_OR_MORE_START+")");break;case n.db.Cardinality.ONE_OR_MORE:c.attr("marker-start","url("+l+"#"+w.ONE_OR_MORE_START+")");break;case n.db.Cardinality.ONLY_ONE:c.attr("marker-start","url("+l+"#"+w.ONLY_ONE_START+")");break;case n.db.Cardinality.MD_PARENT:c.attr("marker-start","url("+l+"#"+w.MD_PARENT_START+")")}const h=c.node().getTotalLength(),d=c.node().getPointAtLength(.5*h),u="rel"+P,p=e.append("text").classed("er relationshipLabel",!0).attr("id",u).attr("x",d.x).attr("y",d.y).style("text-anchor","middle").style("dominant-baseline","middle").style("font-family",t().fontFamily).style("font-size",L.fontSize+"px").text(r.roleA).node().getBBox();e.insert("rect","#"+u).classed("er relationshipLabelBox",!0).attr("x",d.x-p.width/2).attr("y",d.y-p.height/2).attr("width",p.width).attr("height",p.height)}(o,e,l,p,a)}));const b=L.diagramPadding;d.insertTitle(o,"entityTitleText",L.titleTopMargin,a.db.getDiagramTitle());const k=o.node().getBBox(),R=k.width+2*b,N=k.height+2*b;u(o,N,R,L.useMaxWidth),o.attr("viewBox",`${k.x-b} ${k.y-b} ${R} ${N}`)}},styles:t=>`\n .entityBox {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxOdd {\n fill: ${t.attributeBackgroundColorOdd};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxEven {\n fill: ${t.attributeBackgroundColorEven};\n stroke: ${t.nodeBorder};\n }\n\n .relationshipLabelBox {\n fill: ${t.tertiaryColor};\n opacity: 0.7;\n background-color: ${t.tertiaryColor};\n rect {\n opacity: 0.5;\n }\n }\n\n .relationshipLine {\n stroke: ${t.lineColor};\n }\n\n .entityTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n } \n #MD_PARENT_START {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n #MD_PARENT_END {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n \n`};export{Z as diagram}; diff --git a/assets/fakedns.html.39dbcc98.js b/assets/fakedns.html.52314130.js similarity index 99% rename from assets/fakedns.html.39dbcc98.js rename to assets/fakedns.html.52314130.js index 93d000251..7d96ff3b3 100644 --- a/assets/fakedns.html.39dbcc98.js +++ b/assets/fakedns.html.52314130.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as t,w as p,F as o,d as c,e as r}from"./app.755d843f.js";const l={},u=c('

    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.

    {\n  "ipPool": "198.18.0.0/16",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    FakeDnsObject can also be configured as an array containing multiple FakeIP Pools. When a DNS query request is received, FakeDNS returns a group of FakeIPs obtained by multiple FakeIP Pools at the same time.

    [\n  {\n    "ipPool": "198.18.0.0/15",\n    "poolSize": 65535\n  },\n  {\n    "ipPool": "fc00::/18",\n    "poolSize": 65535\n  }\n]\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    ipPool: CIDR

    FakeDNS will use the IP block specified by this option to allocate addresses.

    poolSize: int

    Specifies the maximum number of domain name-IP mappings stored by FakeDNS. When the number of mappings exceeds this value, mappings will be eliminated according to the LRU rule. The default is 65535.

    Warning

    poolSize must be less than or equal to the total number of addresses corresponding to ipPool.

    Tip

    If the dns item in the configuration file sets fakedns, but the configuration file does not set FakeDNSObject, Xray will initialize FakeDNSObject based on the queryStrategy of the DNS component.

    When queryStrategy is set to UseIP, the initialized FakeIP Pool is equivalent to

    [\n  {\n    "ipPool": "198.18.0.0/15",\n    "poolSize": 32768\n  },\n  {\n    "ipPool": "fc00::/18",\n    "poolSize": 32768\n  }\n]\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    When queryStrategy is set to UseIPv4, the initialized FakeIP Pool is equivalent to

    {\n  "ipPool": "198.18.0.0/15",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    When queryStrategy is set to UseIPv6, the initialized FakeIP Pool is equivalent to

    {\n  "ipPool": "fc00::/18",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    How to use?

    ',15),i=r("FakeDNS is essentially a "),d=r("DNS server"),k=r(" that can be used in conjunction with any DNS rules."),b=c('

    Only by routing DNS queries to FakeDNS can it be effective.

    {\n  "dns": {\n    "servers": [\n      "fakedns", // fakedns comes first\n      "8.8.8.8"\n    ]\n  },\n  "outbounds": [\n    {\n      "protocol": "dns",\n      "tag": "dns-out"\n    }\n  ],\n  "routing": {\n    "rules": [\n      {\n        "type": "field",\n        "inboundTag": ["dns-in"], // Intercept DNS traffic from DNS query inbound or from inbound traffic of transparent proxies.\n        "port": 53,\n        "outboundTag": "dns-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    When external DNS requests enter the FakeDNS component, it will return IP addresses within its own ipPool as the virtual resolution results of the domain name, and record the mapping relationship between the domain name and the virtual resolution results.

    In addition, you need to enable Sniffing in the client for incoming traffic that needs to be proxied, and use the fakedns target address reset.

    "sniffing": {\n  "enabled": true,\n  "destOverride": ["fakedns"], // Use "fakedns", or use it with other sniffer, or directly use "fakedns+others".\n  "metadataOnly": false        // When this item is true, destOverride can only use fakedns.\n},\n
    1
    2
    3
    4
    5

    Warning

    If the FakeIP is not correctly restored to the domain name, the server will not be accessible.

    Using with other types of DNS

    Coexistence with DNS shunting

    When using DNS shunting, to give fakedns a higher priority, you need to add the same domains as other types of DNS.

    {\n  "servers": [\n    {\n      "address": "fakedns",\n      "domains": [\n        // consistent with the content used in the shunt below\n        "geosite:cn",\n        "domain:example.com"\n      ]\n    },\n    {\n      "address": "1.2.3.4",\n      "domains": ["geosite:cn"],\n      "expectIPs": ["geoip:cn"]\n    },\n    {\n      "address": "1.1.1.1",\n      "domains": ["domain:example.com"]\n    },\n    "8.8.8.8"\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    FakeDNS blacklist

    If you do not want certain domain names to use FakeDNS, you can add domains configuration in other types of DNS configurations so that when the specified domain names are matched, other DNS servers have a higher priority than FakeDNS, thereby achieving the FakeDNS blacklist mechanism.

    {\n  "servers": [\n    "fakedns",\n    {\n      "address": "1.2.3.4",\n      "domains": ["domain:do-not-use-fakedns.com"]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    FakeDNS whitelist

    If you only want certain domain names to use FakeDNS, you can add domains configuration to fakedns so that when the specified domain names are matched, fakedns has a higher priority than other DNS servers, thereby achieving the FakeDNS whitelist mechanism.

    {\n  "servers": [\n    "1.2.3.4",\n    {\n      "address": "fakedns",\n      "domains": ["domain:only-this-use-fakedns.com"]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ',16);l.render=function(c,r){const l=n("RouterLink");return s(),a(o,null,[u,e("p",null,[i,t(l,{to:"/en/config/dns.html#serverobject"},{default:p((()=>[d])),_:1}),k]),b],64)};export default l; +import{r as n,o as s,c as a,a as e,b as t,w as p,F as o,d as c,e as r}from"./app.48111a85.js";const l={},u=c('

    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.

    {\n  "ipPool": "198.18.0.0/16",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    FakeDnsObject can also be configured as an array containing multiple FakeIP Pools. When a DNS query request is received, FakeDNS returns a group of FakeIPs obtained by multiple FakeIP Pools at the same time.

    [\n  {\n    "ipPool": "198.18.0.0/15",\n    "poolSize": 65535\n  },\n  {\n    "ipPool": "fc00::/18",\n    "poolSize": 65535\n  }\n]\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    ipPool: CIDR

    FakeDNS will use the IP block specified by this option to allocate addresses.

    poolSize: int

    Specifies the maximum number of domain name-IP mappings stored by FakeDNS. When the number of mappings exceeds this value, mappings will be eliminated according to the LRU rule. The default is 65535.

    Warning

    poolSize must be less than or equal to the total number of addresses corresponding to ipPool.

    Tip

    If the dns item in the configuration file sets fakedns, but the configuration file does not set FakeDNSObject, Xray will initialize FakeDNSObject based on the queryStrategy of the DNS component.

    When queryStrategy is set to UseIP, the initialized FakeIP Pool is equivalent to

    [\n  {\n    "ipPool": "198.18.0.0/15",\n    "poolSize": 32768\n  },\n  {\n    "ipPool": "fc00::/18",\n    "poolSize": 32768\n  }\n]\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    When queryStrategy is set to UseIPv4, the initialized FakeIP Pool is equivalent to

    {\n  "ipPool": "198.18.0.0/15",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    When queryStrategy is set to UseIPv6, the initialized FakeIP Pool is equivalent to

    {\n  "ipPool": "fc00::/18",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    How to use?

    ',15),i=r("FakeDNS is essentially a "),d=r("DNS server"),k=r(" that can be used in conjunction with any DNS rules."),b=c('

    Only by routing DNS queries to FakeDNS can it be effective.

    {\n  "dns": {\n    "servers": [\n      "fakedns", // fakedns comes first\n      "8.8.8.8"\n    ]\n  },\n  "outbounds": [\n    {\n      "protocol": "dns",\n      "tag": "dns-out"\n    }\n  ],\n  "routing": {\n    "rules": [\n      {\n        "type": "field",\n        "inboundTag": ["dns-in"], // Intercept DNS traffic from DNS query inbound or from inbound traffic of transparent proxies.\n        "port": 53,\n        "outboundTag": "dns-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    When external DNS requests enter the FakeDNS component, it will return IP addresses within its own ipPool as the virtual resolution results of the domain name, and record the mapping relationship between the domain name and the virtual resolution results.

    In addition, you need to enable Sniffing in the client for incoming traffic that needs to be proxied, and use the fakedns target address reset.

    "sniffing": {\n  "enabled": true,\n  "destOverride": ["fakedns"], // Use "fakedns", or use it with other sniffer, or directly use "fakedns+others".\n  "metadataOnly": false        // When this item is true, destOverride can only use fakedns.\n},\n
    1
    2
    3
    4
    5

    Warning

    If the FakeIP is not correctly restored to the domain name, the server will not be accessible.

    Using with other types of DNS

    Coexistence with DNS shunting

    When using DNS shunting, to give fakedns a higher priority, you need to add the same domains as other types of DNS.

    {\n  "servers": [\n    {\n      "address": "fakedns",\n      "domains": [\n        // consistent with the content used in the shunt below\n        "geosite:cn",\n        "domain:example.com"\n      ]\n    },\n    {\n      "address": "1.2.3.4",\n      "domains": ["geosite:cn"],\n      "expectIPs": ["geoip:cn"]\n    },\n    {\n      "address": "1.1.1.1",\n      "domains": ["domain:example.com"]\n    },\n    "8.8.8.8"\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    FakeDNS blacklist

    If you do not want certain domain names to use FakeDNS, you can add domains configuration in other types of DNS configurations so that when the specified domain names are matched, other DNS servers have a higher priority than FakeDNS, thereby achieving the FakeDNS blacklist mechanism.

    {\n  "servers": [\n    "fakedns",\n    {\n      "address": "1.2.3.4",\n      "domains": ["domain:do-not-use-fakedns.com"]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    FakeDNS whitelist

    If you only want certain domain names to use FakeDNS, you can add domains configuration to fakedns so that when the specified domain names are matched, fakedns has a higher priority than other DNS servers, thereby achieving the FakeDNS whitelist mechanism.

    {\n  "servers": [\n    "1.2.3.4",\n    {\n      "address": "fakedns",\n      "domains": ["domain:only-this-use-fakedns.com"]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ',16);l.render=function(c,r){const l=n("RouterLink");return s(),a(o,null,[u,e("p",null,[i,t(l,{to:"/en/config/dns.html#serverobject"},{default:p((()=>[d])),_:1}),k]),b],64)};export default l; diff --git a/assets/fakedns.html.6b2a3805.js b/assets/fakedns.html.d7b0e008.js similarity index 99% rename from assets/fakedns.html.6b2a3805.js rename to assets/fakedns.html.d7b0e008.js index 57fcfa301..3ff4c29a5 100644 --- a/assets/fakedns.html.6b2a3805.js +++ b/assets/fakedns.html.d7b0e008.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as e,w as o,F as t,d as c,e as l}from"./app.755d843f.js";const u={},r=c('

    FakeDNS

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

    注意

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

    FakeDNSObject

    FakeDNSObject 对应配置文件的 fakedns 项。

    {\n  "ipPool": "198.18.0.0/16",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    FakeDnsObject 亦可配置为一个包含多个 FakeIP Pool 的数组。当收到 DNS 查询请求时,FakeDNS 会返回一组同时由多个 FakeIP Pool 得到的一组 FakeIP。

    [\n  {\n    "ipPool": "198.18.0.0/15",\n    "poolSize": 65535\n  },\n  {\n    "ipPool": "fc00::/18",\n    "poolSize": 65535\n  }\n]\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    ipPool: CIDR

    FakeDNS 将使用此选项指定的 IP 块分配地址。

    poolSize: int

    指定 FakeDNS 储存的 域名-IP 映射的最大数目。当映射数超过此值后,会按照 LRU 规则淘汰映射。默认为 65535。

    注意

    poolSize 必须小于或等于 ipPool 对应的地址总数。

    提示

    若配置文件中 dns 项设置了 fakedns 但配置文件没有设置 FakeDnsObject,Xray 会根据 DNS 组件的 queryStrategy 来初始化 FakeDnsObject

    queryStrategyUseIP 时,初始化的 FakeIP Pool 相当于

    [\n  {\n    "ipPool": "198.18.0.0/15",\n    "poolSize": 32768\n  },\n  {\n    "ipPool": "fc00::/18",\n    "poolSize": 32768\n  }\n]\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    queryStrategyUseIPv4 时,初始化的 FakeIP Pool 相当于

    {\n  "ipPool": "198.18.0.0/15",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    queryStrategyUseIPv6 时,初始化的 FakeIP Pool 相当于

    {\n  "ipPool": "fc00::/18",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    如何使用?

    ',15),i=l("FakeDNS 本质上是一个 "),k=l("DNS 服务器"),b=l(",能够与任意 DNS 规则配合使用。"),d=c('

    只有将 DNS 查询路由到 FakeDNS,才能使其发挥作用。

    {\n  "dns": {\n    "servers": [\n      "fakedns", // fakedns 排在首位\n      "8.8.8.8"\n    ]\n  },\n  "outbounds": [\n    {\n      "protocol": "dns",\n      "tag": "dns-out"\n    }\n  ],\n  "routing": {\n    "rules": [\n      {\n        "type": "field",\n        "inboundTag": ["dns-in"], // 劫持来自 DNS 查询入口的 DNS 流量,或劫持来自透明代理入站的 DNS 流量。\n        "port": 53,\n        "outboundTag": "dns-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    当外部 DNS 请求进入 FakeDNS 组件时,它会返回位于自己 ipPool 内的 IP 地址作为域名的虚构解析结果,并记录该域名与虚构解析结果之间的映射关系。

    另外,你需要在客户端接收需代理流量的入站中开启 Sniffing,并使用 fakedns 目标地址重置。

    "sniffing": {\n  "enabled": true,\n  "destOverride": ["fakedns"], // 使用 "fakedns",或与其它 sniffer 搭配使用,或直接使用 "fakedns+others"\n  "metadataOnly": false        // 此项为 true 时 destOverride 仅可使用 fakedns\n},\n
    1
    2
    3
    4
    5

    注意

    如果 FakeIP 没有被正确的还原为域名,将无法连接到服务器。

    与其它类型 DNS 搭配使用

    与 DNS 分流共存

    使用 DNS 分流时,为了使 fakedns 拥有高优先级,需要对其增加与其他类型 DNS 相同的 domains

    {\n  "servers": [\n    {\n      "address": "fakedns",\n      "domains": [\n        // 与下方分流所用的内容一致\n        "geosite:cn",\n        "domain:example.com"\n      ]\n    },\n    {\n      "address": "1.2.3.4",\n      "domains": ["geosite:cn"],\n      "expectIPs": ["geoip:cn"]\n    },\n    {\n      "address": "1.1.1.1",\n      "domains": ["domain:example.com"]\n    },\n    "8.8.8.8"\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    FakeDNS 黑名单

    如不希望某些域名使用 FakeDNS,则可在其它类型的 DNS 配置中添加 domains 配置,使指定域名在匹配时其它 DNS 服务器拥有比 FakeDNS 更高的优先级,进而实现 FakeDNS 的黑名单机制。

    {\n  "servers": [\n    "fakedns",\n    {\n      "address": "1.2.3.4",\n      "domains": ["domain:do-not-use-fakedns.com"]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    FakeDNS 白名单

    如希望仅某些域名使用 FakeDNS,则可在 fakedns 增加 domains 配置,使指定域名在匹配时 fakedns 拥有比其它 DNS 服务器更高的优先级,进而实现 FakeDNS 的白名单机制。

    {\n  "servers": [\n    "1.2.3.4",\n    {\n      "address": "fakedns",\n      "domains": ["domain:only-this-use-fakedns.com"]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ',16);u.render=function(c,l){const u=n("RouterLink");return s(),a(t,null,[r,p("p",null,[i,e(u,{to:"/config/dns.html#serverobject"},{default:o((()=>[k])),_:1}),b]),d],64)};export default u; +import{r as n,o as s,c as a,a as p,b as e,w as o,F as t,d as c,e as l}from"./app.48111a85.js";const u={},r=c('

    FakeDNS

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

    注意

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

    FakeDNSObject

    FakeDNSObject 对应配置文件的 fakedns 项。

    {\n  "ipPool": "198.18.0.0/16",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    FakeDnsObject 亦可配置为一个包含多个 FakeIP Pool 的数组。当收到 DNS 查询请求时,FakeDNS 会返回一组同时由多个 FakeIP Pool 得到的一组 FakeIP。

    [\n  {\n    "ipPool": "198.18.0.0/15",\n    "poolSize": 65535\n  },\n  {\n    "ipPool": "fc00::/18",\n    "poolSize": 65535\n  }\n]\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    ipPool: CIDR

    FakeDNS 将使用此选项指定的 IP 块分配地址。

    poolSize: int

    指定 FakeDNS 储存的 域名-IP 映射的最大数目。当映射数超过此值后,会按照 LRU 规则淘汰映射。默认为 65535。

    注意

    poolSize 必须小于或等于 ipPool 对应的地址总数。

    提示

    若配置文件中 dns 项设置了 fakedns 但配置文件没有设置 FakeDnsObject,Xray 会根据 DNS 组件的 queryStrategy 来初始化 FakeDnsObject

    queryStrategyUseIP 时,初始化的 FakeIP Pool 相当于

    [\n  {\n    "ipPool": "198.18.0.0/15",\n    "poolSize": 32768\n  },\n  {\n    "ipPool": "fc00::/18",\n    "poolSize": 32768\n  }\n]\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    queryStrategyUseIPv4 时,初始化的 FakeIP Pool 相当于

    {\n  "ipPool": "198.18.0.0/15",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    queryStrategyUseIPv6 时,初始化的 FakeIP Pool 相当于

    {\n  "ipPool": "fc00::/18",\n  "poolSize": 65535\n}\n
    1
    2
    3
    4

    如何使用?

    ',15),i=l("FakeDNS 本质上是一个 "),k=l("DNS 服务器"),b=l(",能够与任意 DNS 规则配合使用。"),d=c('

    只有将 DNS 查询路由到 FakeDNS,才能使其发挥作用。

    {\n  "dns": {\n    "servers": [\n      "fakedns", // fakedns 排在首位\n      "8.8.8.8"\n    ]\n  },\n  "outbounds": [\n    {\n      "protocol": "dns",\n      "tag": "dns-out"\n    }\n  ],\n  "routing": {\n    "rules": [\n      {\n        "type": "field",\n        "inboundTag": ["dns-in"], // 劫持来自 DNS 查询入口的 DNS 流量,或劫持来自透明代理入站的 DNS 流量。\n        "port": 53,\n        "outboundTag": "dns-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    当外部 DNS 请求进入 FakeDNS 组件时,它会返回位于自己 ipPool 内的 IP 地址作为域名的虚构解析结果,并记录该域名与虚构解析结果之间的映射关系。

    另外,你需要在客户端接收需代理流量的入站中开启 Sniffing,并使用 fakedns 目标地址重置。

    "sniffing": {\n  "enabled": true,\n  "destOverride": ["fakedns"], // 使用 "fakedns",或与其它 sniffer 搭配使用,或直接使用 "fakedns+others"\n  "metadataOnly": false        // 此项为 true 时 destOverride 仅可使用 fakedns\n},\n
    1
    2
    3
    4
    5

    注意

    如果 FakeIP 没有被正确的还原为域名,将无法连接到服务器。

    与其它类型 DNS 搭配使用

    与 DNS 分流共存

    使用 DNS 分流时,为了使 fakedns 拥有高优先级,需要对其增加与其他类型 DNS 相同的 domains

    {\n  "servers": [\n    {\n      "address": "fakedns",\n      "domains": [\n        // 与下方分流所用的内容一致\n        "geosite:cn",\n        "domain:example.com"\n      ]\n    },\n    {\n      "address": "1.2.3.4",\n      "domains": ["geosite:cn"],\n      "expectIPs": ["geoip:cn"]\n    },\n    {\n      "address": "1.1.1.1",\n      "domains": ["domain:example.com"]\n    },\n    "8.8.8.8"\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    FakeDNS 黑名单

    如不希望某些域名使用 FakeDNS,则可在其它类型的 DNS 配置中添加 domains 配置,使指定域名在匹配时其它 DNS 服务器拥有比 FakeDNS 更高的优先级,进而实现 FakeDNS 的黑名单机制。

    {\n  "servers": [\n    "fakedns",\n    {\n      "address": "1.2.3.4",\n      "domains": ["domain:do-not-use-fakedns.com"]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    FakeDNS 白名单

    如希望仅某些域名使用 FakeDNS,则可在 fakedns 增加 domains 配置,使指定域名在匹配时 fakedns 拥有比其它 DNS 服务器更高的优先级,进而实现 FakeDNS 的白名单机制。

    {\n  "servers": [\n    "1.2.3.4",\n    {\n      "address": "fakedns",\n      "domains": ["domain:only-this-use-fakedns.com"]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ',16);u.render=function(c,l){const u=n("RouterLink");return s(),a(t,null,[r,p("p",null,[i,e(u,{to:"/config/dns.html#serverobject"},{default:o((()=>[k])),_:1}),b]),d],64)};export default u; diff --git a/assets/fallback.html.45b3f202.js b/assets/fallback.html.6b61b4aa.js similarity index 97% rename from assets/fallback.html.45b3f202.js rename to assets/fallback.html.6b61b4aa.js index e78ad7f21..02d76ee1d 100644 --- a/assets/fallback.html.45b3f202.js +++ b/assets/fallback.html.6b61b4aa.js @@ -1 +1 @@ -import{r as a,o as n,c as s,a as l,b as o,w as e,F as t,d as p,e as c}from"./app.755d843f.js";const r={},u=p('

    Fallback 回落

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

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

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

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

    fallbacks 配置

      "fallbacks": [\n    {\n      "dest": 80\n    }\n  ]\n
    1
    2
    3
    4
    5

    fallbacks: [ FallbackObject ]

    一个数组,包含一系列强大的回落分流配置。

    FallbackObject

    {\n  "name": "",\n  "alpn": "",\n  "path": "",\n  "dest": 80,\n  "xver": 0\n}\n
    1
    2
    3
    4
    5
    6
    7

    fallbacks 是一个数组,这里是其中一个子元素的配置说明。

    fallbacks 项是可选的,只能用于 TCP+TLS 传输组合

    ',13),d=c("该项有子元素时,"),i=c("Inbound TLS"),b=c(" 需设置 "),k=l("code",null,'"alpn":["http/1.1"]',-1),h=c("。**"),f=p("

    通常,你需要先设置一组 alpnpath 均省略或为空的默认回落,然后再按需配置其它分流。

    VLESS 会把 TLS 解密后首包长度 < 18 或协议版本无效、身份认证失败的流量转发到 dest 指定的地址。

    其它传输组合必须删掉 fallbacks 项或所有子元素,此时也不会开启 Fallback,VLESS 会等待读够所需长度,协议版本无效或身份认证失败时,将直接断开连接。

    name: string

    尝试匹配 TLS SNI(Server Name Indication),空为任意,默认为 ""

    alpn: string

    尝试匹配 TLS ALPN 协商结果,空为任意,默认为 ""

    ",7),m=c("有需要时,VLESS 才会尝试读取 TLS ALPN 协商结果,若成功,输出 info "),g=l("code",null,"realAlpn =",-1),q=c(" 到日志。 用途:解决了 Nginx 的 h2c 服务不能同时兼容 http/1.1 的问题,Nginx 需要写两行 listen,分别用于 1.1 和 h2c。 注意:fallbacks alpn 存在 "),T=l("code",null,'"h2"',-1),x=c(" 时,"),S=c("Inbound TLS"),P=c(" 需设置 "),L=l("code",null,'"alpn":["h2","http/1.1"]',-1),v=c(",以支持 h2 访问。"),y=p('

    提示

    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 流量的去向,目前支持两类地址:(该项必填,否则无法启动)

    ',7),j=l("li",null,[c("TCP,格式为 "),l("code",null,'"addr:port"'),c(",其中 addr 支持 IPv4、域名、IPv6,若填写域名,也将直接发起 TCP 连接(而不走内置的 DNS)。")],-1),N=c("Unix domain socket,格式为绝对路径,形如 "),F=l("code",null,'"/dev/shm/domain.socket"',-1),w=c(",可在开头加 "),I=l("code",null,"@",-1),_=c(" 代表 "),A={href:"https://www.man7.org/linux/man-pages/man7/unix.7.html",target:"_blank",rel:"noopener noreferrer"},C=c("abstract"),H=c(","),O=l("code",null,"@@",-1),X=c(" 则代表带 padding 的 abstract。"),E=l("p",null,[c("若只填 port,数字或字符串均可,形如 "),l("code",null,"80"),c("、"),l("code",null,'"80"'),c(",通常指向一个明文 http 服务(addr 会被补为 "),l("code",null,'"127.0.0.1"'),c(")。")],-1),V=l("blockquote",null,[l("p",null,[l("code",null,"xver"),c(": number")])],-1),R=c("发送 "),W={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},Y=c("PROXY protocol"),B=c(",专用于传递请求的真实来源 IP 和端口,填版本 1 或 2,默认为 0,即不发送。若有需要建议填 1。"),D=l("p",null,"目前填 1 或 2,功能完全相同,只是结构不同,且前者可打印,后者为二进制。Xray 的 TCP 和 WS 入站均已支持接收 PROXY protocol。",-1),U={class:"custom-container warning"},z=l("p",{class:"custom-container-title"},"注意",-1),G=c("若你正在 "),J={href:"https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/#configuring-nginx-to-accept-the-proxy-protocol",target:"_blank",rel:"noopener noreferrer"},K=c("配置 Nginx 接收 PROXY protocol"),M=c(",除了设置 proxy_protocol 外,还需设置 set_real_ip_from,否则可能会出问题。"),Q=l("h3",{id:"补充说明",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#补充说明","aria-hidden":"true"},"#"),c(" 补充说明")],-1),Z=l("ul",null,[l("li",null,"将匹配到最精确的子元素,与子元素的排列顺序无关。若配置了几个 alpn 和 path 均相同的子元素,则会以最后的为准。"),l("li",null,"回落分流均是解密后 TCP 层的转发,而不是 HTTP 层,只在必要时检查首包 PATH。"),l("li",null,[c("您可以查看更多的关于 Fallbacks 的使用技巧和心得 "),l("ul",null,[l("li",null,[l("a",{href:"../../document/level-1/fallbacks-lv1"},"Fallbacks 功能简析")])])])],-1),$={id:"fallbacks-设计理论",tabindex:"-1"},aa=l("a",{class:"header-anchor",href:"#fallbacks-设计理论","aria-hidden":"true"},"#",-1),na=c(" Fallbacks 设计理论 ");r.render=function(p,c){const r=a("RouterLink"),sa=a("OutboundLink"),la=a("Badge");return n(),s(t,null,[u,l("ul",null,[l("li",null,[d,o(r,{to:"/config/transport.html#tlsobject"},{default:e((()=>[i])),_:1}),b,k,h])]),f,l("p",null,[m,g,q,T,x,o(r,{to:"/config/transport.html#tlsobject"},{default:e((()=>[S])),_:1}),P,L,v]),y,l("ol",null,[j,l("li",null,[N,F,w,I,_,l("a",A,[C,o(sa)]),H,O,X])]),E,V,l("p",null,[R,l("a",W,[Y,o(sa)]),B]),D,l("div",U,[z,l("p",null,[G,l("a",J,[K,o(sa)]),M])]),Q,Z,l("h2",$,[aa,na,o(la,{text:"WIP",type:"warning"})])],64)};export default r; +import{r as a,o as n,c as s,a as l,b as o,w as e,F as t,d as p,e as c}from"./app.48111a85.js";const r={},u=p('

    Fallback 回落

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

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

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

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

    fallbacks 配置

      "fallbacks": [\n    {\n      "dest": 80\n    }\n  ]\n
    1
    2
    3
    4
    5

    fallbacks: [ FallbackObject ]

    一个数组,包含一系列强大的回落分流配置。

    FallbackObject

    {\n  "name": "",\n  "alpn": "",\n  "path": "",\n  "dest": 80,\n  "xver": 0\n}\n
    1
    2
    3
    4
    5
    6
    7

    fallbacks 是一个数组,这里是其中一个子元素的配置说明。

    fallbacks 项是可选的,只能用于 TCP+TLS 传输组合

    ',13),d=c("该项有子元素时,"),i=c("Inbound TLS"),b=c(" 需设置 "),k=l("code",null,'"alpn":["http/1.1"]',-1),h=c("。**"),m=p("

    通常,你需要先设置一组 alpnpath 均省略或为空的默认回落,然后再按需配置其它分流。

    VLESS 会把 TLS 解密后首包长度 < 18 或协议版本无效、身份认证失败的流量转发到 dest 指定的地址。

    其它传输组合必须删掉 fallbacks 项或所有子元素,此时也不会开启 Fallback,VLESS 会等待读够所需长度,协议版本无效或身份认证失败时,将直接断开连接。

    name: string

    尝试匹配 TLS SNI(Server Name Indication),空为任意,默认为 ""

    alpn: string

    尝试匹配 TLS ALPN 协商结果,空为任意,默认为 ""

    ",7),f=c("有需要时,VLESS 才会尝试读取 TLS ALPN 协商结果,若成功,输出 info "),g=l("code",null,"realAlpn =",-1),q=c(" 到日志。 用途:解决了 Nginx 的 h2c 服务不能同时兼容 http/1.1 的问题,Nginx 需要写两行 listen,分别用于 1.1 和 h2c。 注意:fallbacks alpn 存在 "),T=l("code",null,'"h2"',-1),x=c(" 时,"),S=c("Inbound TLS"),P=c(" 需设置 "),L=l("code",null,'"alpn":["h2","http/1.1"]',-1),v=c(",以支持 h2 访问。"),y=p('

    提示

    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 流量的去向,目前支持两类地址:(该项必填,否则无法启动)

    ',7),j=l("li",null,[c("TCP,格式为 "),l("code",null,'"addr:port"'),c(",其中 addr 支持 IPv4、域名、IPv6,若填写域名,也将直接发起 TCP 连接(而不走内置的 DNS)。")],-1),N=c("Unix domain socket,格式为绝对路径,形如 "),F=l("code",null,'"/dev/shm/domain.socket"',-1),w=c(",可在开头加 "),I=l("code",null,"@",-1),_=c(" 代表 "),A={href:"https://www.man7.org/linux/man-pages/man7/unix.7.html",target:"_blank",rel:"noopener noreferrer"},C=c("abstract"),H=c(","),O=l("code",null,"@@",-1),X=c(" 则代表带 padding 的 abstract。"),E=l("p",null,[c("若只填 port,数字或字符串均可,形如 "),l("code",null,"80"),c("、"),l("code",null,'"80"'),c(",通常指向一个明文 http 服务(addr 会被补为 "),l("code",null,'"127.0.0.1"'),c(")。")],-1),V=l("blockquote",null,[l("p",null,[l("code",null,"xver"),c(": number")])],-1),R=c("发送 "),W={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},Y=c("PROXY protocol"),B=c(",专用于传递请求的真实来源 IP 和端口,填版本 1 或 2,默认为 0,即不发送。若有需要建议填 1。"),D=l("p",null,"目前填 1 或 2,功能完全相同,只是结构不同,且前者可打印,后者为二进制。Xray 的 TCP 和 WS 入站均已支持接收 PROXY protocol。",-1),U={class:"custom-container warning"},z=l("p",{class:"custom-container-title"},"注意",-1),G=c("若你正在 "),J={href:"https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/#configuring-nginx-to-accept-the-proxy-protocol",target:"_blank",rel:"noopener noreferrer"},K=c("配置 Nginx 接收 PROXY protocol"),M=c(",除了设置 proxy_protocol 外,还需设置 set_real_ip_from,否则可能会出问题。"),Q=l("h3",{id:"补充说明",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#补充说明","aria-hidden":"true"},"#"),c(" 补充说明")],-1),Z=l("ul",null,[l("li",null,"将匹配到最精确的子元素,与子元素的排列顺序无关。若配置了几个 alpn 和 path 均相同的子元素,则会以最后的为准。"),l("li",null,"回落分流均是解密后 TCP 层的转发,而不是 HTTP 层,只在必要时检查首包 PATH。"),l("li",null,[c("您可以查看更多的关于 Fallbacks 的使用技巧和心得 "),l("ul",null,[l("li",null,[l("a",{href:"../../document/level-1/fallbacks-lv1"},"Fallbacks 功能简析")])])])],-1),$={id:"fallbacks-设计理论",tabindex:"-1"},aa=l("a",{class:"header-anchor",href:"#fallbacks-设计理论","aria-hidden":"true"},"#",-1),na=c(" Fallbacks 设计理论 ");r.render=function(p,c){const r=a("RouterLink"),sa=a("OutboundLink"),la=a("Badge");return n(),s(t,null,[u,l("ul",null,[l("li",null,[d,o(r,{to:"/config/transport.html#tlsobject"},{default:e((()=>[i])),_:1}),b,k,h])]),m,l("p",null,[f,g,q,T,x,o(r,{to:"/config/transport.html#tlsobject"},{default:e((()=>[S])),_:1}),P,L,v]),y,l("ol",null,[j,l("li",null,[N,F,w,I,_,l("a",A,[C,o(sa)]),H,O,X])]),E,V,l("p",null,[R,l("a",W,[Y,o(sa)]),B]),D,l("div",U,[z,l("p",null,[G,l("a",J,[K,o(sa)]),M])]),Q,Z,l("h2",$,[aa,na,o(la,{text:"WIP",type:"warning"})])],64)};export default r; diff --git a/assets/fallback.html.688a3beb.js b/assets/fallback.html.efcedcbf.js similarity index 99% rename from assets/fallback.html.688a3beb.js rename to assets/fallback.html.efcedcbf.js index 363ccd824..c6dd1fdec 100644 --- a/assets/fallback.html.688a3beb.js +++ b/assets/fallback.html.efcedcbf.js @@ -1 +1 @@ -import{r as e,o as n,c as a,a as t,b as o,w as s,F as l,d as r,e as i}from"./app.755d843f.js";const c={},p=r('

    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": [\n    {\n      "dest": 80\n    }\n  ]\n
    1
    2
    3
    4
    5

    fallbacks: [ FallbackObject ]

    fallbacks is an array, and here is an example configuration of one of its child elements.

    FallbackObject

    {\n  "name": "",\n  "alpn": "",\n  "path": "",\n  "dest": 80,\n  "xver": 0\n}\n
    1
    2
    3
    4
    5
    6
    7

    The fallbacks object is optional and can only be used for the TCP+TLS transport combination.

    ',12),d=i("When "),u=t("code",null,"fallbacks",-1),h=i(" configure with any child elements,"),b=t("code",null,'"alpn":["http/1.1"]',-1),f=i(" needs to be configured in "),m=i("Inbound TLS"),k=i("."),g=r('

    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)

    ',15),y=t("li",null,[i("TCP, in the format of "),t("code",null,'"addr:port"'),i(", 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).")],-1),w=i("Unix domain socket, in the format of an absolute path, such as "),v=t("code",null,'"/dev/shm/domain.socket"',-1),q=i(", which can be prefixed with "),T=t("code",null,"@",-1),P=i(" to represent "),x={href:"https://www.man7.org/linux/man-pages/man7/unix.7.html",target:"_blank",rel:"noopener noreferrer"},S=i("abstract"),L=i(", and "),I=t("code",null,"@@",-1),A=i(" to represent padded abstract."),j=t("p",null,[i("If only the port is specified, both numbers and strings are accepted, such as "),t("code",null,"80"),i(" or "),t("code",null,'"80"'),i(". This usually points to a plaintext HTTP service (and the addr will be filled in as "),t("code",null,'"127.0.0.1"'),i(").")],-1),N=t("blockquote",null,[t("p",null,[t("code",null,"xver"),i(": number")])],-1),F=i("Sends the "),C={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},H=i("PROXY protocol"),O=i(" protocol, which is used to transmit the real source IP and port of the request. The version can be set to "),_=t("code",null,"1",-1),W=i(" or "),X=t("code",null,"2",-1),E=i(", with a default value of "),R=t("code",null,"0",-1),V=i(", which means no PROXY protocol is sent. Version "),Y=t("code",null,"1",-1),D=i(" is recommended if needed."),U=r("

    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.

    ",1),B={class:"custom-container warning"},M=t("p",{class:"custom-container-title"},"Warning",-1),z=i("If you are "),G={href:"https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/#configuring-nginx-to-accept-the-proxy-protocol",target:"_blank",rel:"noopener noreferrer"},J=i("configuring Nginx to receive the PROXY protocol"),K=i(", you need to not only set "),Q=t("code",null,"proxy_protocol",-1),Z=i(", but also "),$=t("code",null,"set_real_ip_from",-1),ee=i(" to avoid potential issues."),ne=r('

    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
    ',2),ae={id:"fallbacks-design-theory",tabindex:"-1"},te=t("a",{class:"header-anchor",href:"#fallbacks-design-theory","aria-hidden":"true"},"#",-1),oe=i(" Fallbacks design theory ");c.render=function(r,i){const c=e("RouterLink"),se=e("OutboundLink"),le=e("Badge");return n(),a(l,null,[p,t("ul",null,[t("li",null,[d,u,h,b,f,o(c,{to:"/en/config/transport.html#tlsobject"},{default:s((()=>[m])),_:1}),k])]),g,t("ol",null,[y,t("li",null,[w,v,q,T,P,t("a",x,[S,o(se)]),L,I,A])]),j,N,t("p",null,[F,t("a",C,[H,o(se)]),O,_,W,X,E,R,V,Y,D]),U,t("div",B,[M,t("p",null,[z,t("a",G,[J,o(se)]),K,Q,Z,$,ee])]),ne,t("h2",ae,[te,oe,o(le,{text:"WIP",type:"warning"})])],64)};export default c; +import{r as e,o as n,c as a,a as t,b as o,w as s,F as l,d as r,e as i}from"./app.48111a85.js";const c={},p=r('

    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": [\n    {\n      "dest": 80\n    }\n  ]\n
    1
    2
    3
    4
    5

    fallbacks: [ FallbackObject ]

    fallbacks is an array, and here is an example configuration of one of its child elements.

    FallbackObject

    {\n  "name": "",\n  "alpn": "",\n  "path": "",\n  "dest": 80,\n  "xver": 0\n}\n
    1
    2
    3
    4
    5
    6
    7

    The fallbacks object is optional and can only be used for the TCP+TLS transport combination.

    ',12),d=i("When "),u=t("code",null,"fallbacks",-1),h=i(" configure with any child elements,"),b=t("code",null,'"alpn":["http/1.1"]',-1),f=i(" needs to be configured in "),m=i("Inbound TLS"),k=i("."),g=r('

    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)

    ',15),y=t("li",null,[i("TCP, in the format of "),t("code",null,'"addr:port"'),i(", 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).")],-1),w=i("Unix domain socket, in the format of an absolute path, such as "),v=t("code",null,'"/dev/shm/domain.socket"',-1),q=i(", which can be prefixed with "),T=t("code",null,"@",-1),P=i(" to represent "),x={href:"https://www.man7.org/linux/man-pages/man7/unix.7.html",target:"_blank",rel:"noopener noreferrer"},S=i("abstract"),L=i(", and "),I=t("code",null,"@@",-1),A=i(" to represent padded abstract."),j=t("p",null,[i("If only the port is specified, both numbers and strings are accepted, such as "),t("code",null,"80"),i(" or "),t("code",null,'"80"'),i(". This usually points to a plaintext HTTP service (and the addr will be filled in as "),t("code",null,'"127.0.0.1"'),i(").")],-1),N=t("blockquote",null,[t("p",null,[t("code",null,"xver"),i(": number")])],-1),F=i("Sends the "),C={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},H=i("PROXY protocol"),O=i(" protocol, which is used to transmit the real source IP and port of the request. The version can be set to "),_=t("code",null,"1",-1),W=i(" or "),X=t("code",null,"2",-1),E=i(", with a default value of "),R=t("code",null,"0",-1),V=i(", which means no PROXY protocol is sent. Version "),Y=t("code",null,"1",-1),D=i(" is recommended if needed."),U=r("

    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.

    ",1),B={class:"custom-container warning"},M=t("p",{class:"custom-container-title"},"Warning",-1),z=i("If you are "),G={href:"https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/#configuring-nginx-to-accept-the-proxy-protocol",target:"_blank",rel:"noopener noreferrer"},J=i("configuring Nginx to receive the PROXY protocol"),K=i(", you need to not only set "),Q=t("code",null,"proxy_protocol",-1),Z=i(", but also "),$=t("code",null,"set_real_ip_from",-1),ee=i(" to avoid potential issues."),ne=r('

    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
    ',2),ae={id:"fallbacks-design-theory",tabindex:"-1"},te=t("a",{class:"header-anchor",href:"#fallbacks-design-theory","aria-hidden":"true"},"#",-1),oe=i(" Fallbacks design theory ");c.render=function(r,i){const c=e("RouterLink"),se=e("OutboundLink"),le=e("Badge");return n(),a(l,null,[p,t("ul",null,[t("li",null,[d,u,h,b,f,o(c,{to:"/en/config/transport.html#tlsobject"},{default:s((()=>[m])),_:1}),k])]),g,t("ol",null,[y,t("li",null,[w,v,q,T,P,t("a",x,[S,o(se)]),L,I,A])]),j,N,t("p",null,[F,t("a",C,[H,o(se)]),O,_,W,X,E,R,V,Y,D]),U,t("div",B,[M,t("p",null,[z,t("a",G,[J,o(se)]),K,Q,Z,$,ee])]),ne,t("h2",ae,[te,oe,o(le,{text:"WIP",type:"warning"})])],64)};export default c; diff --git a/assets/fallbacks-lv1.html.150de4aa.js b/assets/fallbacks-lv1.html.35d8f45b.js similarity index 99% rename from assets/fallbacks-lv1.html.150de4aa.js rename to assets/fallbacks-lv1.html.35d8f45b.js index 0f70842c9..d5fcbbfc9 100644 --- a/assets/fallbacks-lv1.html.150de4aa.js +++ b/assets/fallbacks-lv1.html.35d8f45b.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as o,w as t,F as e,e as c,d as l}from"./app.755d843f.js";const r={},u=p("h1",{id:"回落-fallbacks-功能简析",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#回落-fallbacks-功能简析","aria-hidden":"true"},"#"),c(" 回落 (fallbacks) 功能简析")],-1),i=p("p",null,"在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),k=p("h2",{id:"_1-回顾《小小白白话文》中的回落",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_1-回顾《小小白白话文》中的回落","aria-hidden":"true"},"#"),c(" 1. 回顾《小小白白话文》中的回落")],-1),b=c("如果你用了《小小白白话文》中的"),d=c("Xray 配置"),m=c(",并完成了"),q=c("HTTP 自动跳转 HTTPS 优化"),E=c(",那么你已经有了基于 "),y=p("code",null,"VLESS",-1),g=c(" 协议的简易回落:"),A=l('
    {\n  "inbounds": [\n    {\n      "port": 443,\n      "protocol": "vless",\n      "settings": {\n        "clients": [\n          // ... ...\n        ],\n        "decryption": "none",\n        "fallbacks": [\n          {\n            "dest": 8080 // 默认回落到防探测的代理\n          }\n        ]\n      },\n      "streamSettings": {\n        // ... ...\n      }\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    这一段配置用人话要怎么解释呢?

    ',2),h=l('
  • Xray 的入站端口 [inbound port]443

    即由 Xray 负责监听 443 端口的 HTTPS 流量

  • Xray 的入站协议 [inbound protocol]vless

    只有 vless 协议的流量才会流入 Xray 中做后续处理。

    Warning

    注: VLESS 这个轻量协议开发的初衷就是给 xrayv2fly 等核心引入回落功能、并同时减少冗余校验/加密。(当然,到目前为止,xray 中的 trojan 协议也已完整支持回落功能。)

  • 回落目标端口 [fallback dest]8080

    Xray 接受 443 端口的访问流量后,属于 vless 协议的流量、由 Xray 进行内部处理并转发至出站模块。而其他非 vless 协议的流量,则转发至 8080 端口。

    Warning

    问:到底是单数还是复数?

    答:一定有聪明的同学发现,配置文件中,明明是复数 inbounds, fallbacks,为什么我解释的时候都是单数:inbound, fallback 呢?

    因为,配置文件中用复数,说明 xray 支持 N 个同等级的元素(即 N 个入站,M 个回落等等),上面的示例解析中仅仅是其中一个,所以我用了单数。

  • 回落给 8080 端口的流量,由后续程序处理

    小小白白话文中的示例,就是 8080 端口由 Nginx 处理,根据配置找到并展示小熊猫的网页。

  • ',4),v=p("p",null,[p("strong",null,"总结,小小白白话文示例中的最简单回落,完整数据路线如下:")],-1),X=l('

    2. 重新认识回落 (WHAT, HOW v1)

    基于上面的示例,你应该就可以明白什么是回落(What)和怎么回落(How)了,简单地说就是下面这几个要素:

    1. 回落的时间是流量进入 Xray监听端口
    2. 回落的依据是 协议类型 等流量特征
    3. 回落的目标是某个 端口
    4. 被回落的流量由监听 回落端口 的后续程序接手

    3. 为什么要回落 (WHY v1)

    最初,是为了防御 【主动探测】 (Active Probing)

    主动探测: 简单粗暴的理解,就是指外部通过发送特定的网络请求,并解读服务器的回应内容,来推测服务器端是否运行了 xray, v2fly, shadowsocks 等代理工具。一旦可以准确认定,则服务器可能受到干扰或阻断。

    之所以可以根据服务器回应内容进行解读,就是因为一次完整的数据请求,其实有很多数据交换的步骤,每一个步骤,都会产生一些软件特征。用大白话说就是:

    • 正常的网站的回应,一定【会有】类似 Nginx, Apache, MySQL 的 Web 服务、数据库等工具的特征
    • 正常的网站的回应,一定【不会有】类似 xray, v2fly, shadowsocks 等代理工具的特征

    于是,当我们给 Xray 提供了【回落】功能后(如上例,回落给 Nginx),面对任何用来探测的请求,产生的结果是:

    • 探测流量无法掌握你的 VLESS 要素,故都会被回落至 Nginx
    • 探测流量全都回落进入 Nginx ,故 VPS 服务器的回应一定【会有】 Nginx 的特征
    • 因为 Xray 本身不对探测流量做任何回应 ,所以 VPS 的回应一定【不会有】 Xray 的特征

    至此,【回落】功能就从数据交互逻辑上解决了服务器被 【主动探测】 的安全隐患。

    4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)

    为什么又要再次认识回落呢? 因为,上面仅仅说清楚了基于“协议”的、抵抗【主动探测】的初版回落。

    ',13),x=c("在 "),S={href:"https://github.com/rprx",target:"_blank",rel:"noopener noreferrer"},B=c("RPRX"),f=c(" 不断开发迭代 "),C=p("code",null,"VLESS",-1),T=c(" 协议及 "),w=p("code",null,"fallback",-1),P=c(" 功能的过程中,逐渐发现,回落完全可以更加灵活强大,只要在保证抵抗【主动探测】的前提下,充分利用数据首包中的信息,其实可以做到多元素、多层次的回落。(如 "),F=p("code",null,"path",-1),H=c(", "),j=p("code",null,"alpn",-1),_=c(" 等)"),L=l('

    基于这个开发理念,【回落】功能才逐渐成长为现在的完全体,即完成了 纯伪装 --> ws分流 --> 多协议多特征分流 的进化。最终版甚至完全替代了以前要用 Web 服务器、其他工具才能完成的分流的功能。且由于上述的【回落/分流】处理都在首包判断阶段以毫秒级的速度完成、不涉及任何数据操作,所以几乎没有任何过程损耗。

    因此,现在 Xray 中【完整体的回落功能】,同时具备下述属性:

    • 安全: 充分抵御主动探测攻击
    • 高效: 几乎毫无性能损失
    • 灵活: 数据灵活分流、常用端口复用(如 443)

    啰嗦君

    这样多轮介绍虽然略显繁琐,但只有这样层层深入展开,才能充分的说明【回落の完全体】独有的强大!

    5. 多层回落示例及解读

    ',5),D=c("理解了【回落の完全体】是什么,那就可以动手操作配置多层回落了。其实,项目已经提供了非常完整的示例,即官方模板中的 "),N={href:"https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/",target:"_blank",rel:"noopener noreferrer"},W=c("VLESS-TCP-XTLS-WHATEVER"),V=c("。"),R=l('

    5.1 首先,我将服务器端配置的 443 监听段摘抄如下:

    {\n  "port": 443,\n  "protocol": "vless",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "flow": "xtls-rprx-vision",\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "decryption": "none",\n    "fallbacks": [\n      {\n        "dest": 1310, // 默认回落到 Xray 的 Trojan 协议\n        "xver": 1\n      },\n      {\n        "path": "/websocket", // 必须换成自定义的 PATH\n        "dest": 1234,\n        "xver": 1\n      },\n      {\n        "path": "/vmesstcp", // 必须换成自定义的 PATH\n        "dest": 2345,\n        "xver": 1\n      },\n      {\n        "path": "/vmessws", // 必须换成自定义的 PATH\n        "dest": 3456,\n        "xver": 1\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "tls",\n    "tlsSettings": {\n      "alpn": ["http/1.1"],\n      "certificates": [\n        {\n          "certificateFile": "/path/to/fullchain.crt", // 换成你的证书,绝对路径\n          "keyFile": "/path/to/private.key" // 换成你的私钥,绝对路径\n        }\n      ]\n    }\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49

    这一段配置用人话要怎么解释呢?

    ',3),O=l("
  • Xray 的入站端口 (inbound port) 是 443

    即由 Xray 负责监听 443 端口的 HTTPS 流量,并使用 certificates 项下设定的 TLS 证书来进行验证

  • Xray 的入站协议 (inbound protocol) 是 vless

    vless 协议流量直接流入 Xray 中做后续处理

  • VLESS 协议流量有 4 个不同的回落目标:

    1. pathwebsocket 的流量,回落给端口 1234 后续处理
    2. pathvmesstcp 的流量,回落给端口 2345 后续处理
    3. pathvmessws 的流量,回落给端口 3456 后续处理
    4. 其它所有流量,回落给端口 1310 后续处理
  • xver1 表示开启 proxy protocol 功能,向后传递来源真实 IP

  • ",4),U=p("p",null,[p("strong",null,"上述回落结构如下图所示:")],-1),I=p("li",null,[p("p",null,[p("strong",null,"网页回落不见了!")]),p("p",null,[c("没错,聪明的同学应该发现了,防御【主动探测】的 "),p("code",null,"nginx回落"),c(" 不见了!!!这是为什么呢?会不会不安全?别急,我们继续分析:")])],-1),M=l('

    5.2 后续监听处理的配置段摘抄如下:

    1. 后续处理回落至 1310 端口的流量,按照下面的配置验证、处理:

      {\n  "port": 1310,\n  "listen": "127.0.0.1",\n  "protocol": "trojan",\n  "settings": {\n    "clients": [\n      {\n        "password": "", // 填写你的密码\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "fallbacks": [\n      {\n        "dest": 80 // 或者回落到其它也防探测的代理\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "none",\n    "tcpSettings": {\n      "acceptProxyProtocol": true\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26

      看,神奇的事情发生了, trojan 协议这里又出现了一个新的 fallbacks。前面已经说过,xray 中的 trojan 协议也具有完整的回落能力,所以,此时 trojan 协议可以再次做判断和回落(这也就是传说中的套娃回落了):

      • 所有 trojan 协议的流量,流入 Xray 中做后续处理
      • 所有非 trojan 协议的流量,转发至 80 端口,【主动探测】的防御,完成!
    2. 后续处理回落至 1234 端口的流量,仔细看!它其实是 vless+ws

      {\n  "port": 1234,\n  "listen": "127.0.0.1",\n  "protocol": "vless",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "decryption": "none"\n  },\n  "streamSettings": {\n    "network": "ws",\n    "security": "none",\n    "wsSettings": {\n      "acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS,需要删掉这行\n      "path": "/websocket" // 必须换成自定义的 PATH,需要和分流的一致\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
    3. 后续处理回落至 2345 端口的流量,仔细看!它其实是 vmess直连

      {\n  "port": 2345,\n  "listen": "127.0.0.1",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "none",\n    "tcpSettings": {\n      "acceptProxyProtocol": true,\n      "header": {\n        "type": "http",\n        "request": {\n          "path": [\n            "/vmesstcp" // 必须换成自定义的 PATH,需要和分流的一致\n          ]\n        }\n      }\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
    4. 后续处理回落至 3456 端口的流量,再仔细看!它其实是是 vmess+ws(+cdn)

      说明

      你没看错,这就是 v2fly 曾经推荐的组合之一,并可完整支持 CDN。现已加入完美回落套餐哦!

      {\n  "port": 3456,\n  "listen": "127.0.0.1",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "ws",\n    "security": "none",\n    "wsSettings": {\n      "acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS,需要删掉这行\n      "path": "/vmessws" // 必须换成自定义的 PATH,需要和分流的一致\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
    5. 至此,我们就能够完整的画出模板的回落路线了:

    ',2),Y=p("h2",{id:"_6-结语",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_6-结语","aria-hidden":"true"},"#"),c(" 6. 结语")],-1),Q=p("p",null,[c("至此,"),p("code",null,"Xray"),c(" 的【回落】功能就介绍完了。希望本文能够对你理解 "),p("code",null,"Xray"),c(" 的强大有所帮助。")],-1),z=p("h2",{id:"_7-附加题",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_7-附加题","aria-hidden":"true"},"#"),c(" 7. 附加题")],-1),G=c("我再无耻的留一个附加题:本文详解的 "),J={href:"https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/",target:"_blank",rel:"noopener noreferrer"},K=c("VLESS-TCP-XTLS-WHATEVER"),Z=c(" 模板?是否有可以优化的地方?"),$=p("p",null,"提示:HTTP 自动跳转 HTTPS",-1);r.render=function(c,l){const r=n("RouterLink"),nn=n("Mermaid"),sn=n("OutboundLink");return s(),a(e,null,[u,i,k,p("p",null,[b,o(r,{to:"/en/document/level-0/ch07-xray-server.html#_7-4-%E9%85%8D%E7%BD%AExray"},{default:t((()=>[d])),_:1}),m,o(r,{to:"/en/document/level-0/ch07-xray-server.html#_7-8-%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%BC%98%E5%8C%96%E4%B9%8B%E4%BA%8C-%E5%BC%80%E5%90%AFhttp%E8%87%AA%E5%8A%A8%E8%B7%B3%E8%BD%AChttps"},{default:t((()=>[q])),_:1}),E,y,g]),A,p("ol",null,[h,p("li",null,[v,o(nn,{identifier:"mermaid_382ee1e9",graph:"graph%20LR;%0A%0AW(%E5%A4%96%E9%83%A8%20HTTP:80%20%E8%AF%B7%E6%B1%82)%20--%3E%20N80(HTTP:80)%0A%0Asubgraph%20Nginx%20%E5%A4%96%E9%83%A8%E7%9B%91%E5%90%AC%0AN80%20-.-%20N301(301%E8%BD%AC%E5%86%99)%20-.-%20N443(HTTPS:443)%0Aend%0A%0AN443%20--%3E%20X(Xray%20%E7%9B%91%E5%90%AC%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0AX1%20--%3E%20%7C%E6%8E%A5%E6%94%B6%20VLESS%20%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0AX2%20--%3E%20O(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0AX1%20==%3E%20%7C%E5%9B%9E%E8%90%BD%20%E9%9D%9EVLESS%20%E6%B5%81%E9%87%8F%7C%20N8080(Nginx:8080)%0AN8080:::nginxclass%20==%3E%20H(index.html)%0A%0AH:::nginxclass%0AclassDef%20nginxclass%20fill:#FFFFDE%0A%0A"})])]),X,p("p",null,[x,p("a",S,[B,o(sn)]),f,C,T,w,P,F,H,j,_]),L,p("p",null,[D,p("a",N,[W,o(sn)]),V]),R,p("ol",null,[O,p("li",null,[U,o(nn,{identifier:"mermaid_64a56832",graph:"graph%20LR;%0A%0AW443(%E5%A4%96%E9%83%A8%20HTTP:443%20%E8%AF%B7%E6%B1%82)%20--%3E%20X443(Xray-inbound:%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0AX1%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20VLESS%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0AX2%20--%3E%20O(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0A%0AX1%20--%3E%20%7Cpath%20=%20/websocket%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X1234(Xray-inbound:1234)%0AX1%20--%3E%20%7Cpath%20=%20/vmesstcp%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2345(Xray-inbound:2345)%0AX1%20--%3E%20%7Cpath%20=%20/vmessws%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X3456(Xray-inbound:3456)%0AX1%20--%3E%20%7C%E5%85%B6%E5%AE%83%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20X1310(Xray-inbound:1310)%0A%0A"})]),I]),M,o(nn,{identifier:"mermaid_64a5619e",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20W443(%E5%A4%96%E9%83%A8%20HTTP:443%20%E8%AF%B7%E6%B1%82)%20--%3E%20X443(Xray-inbound:%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0A%20%20%20%20X1%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20VLESS%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0A%20%20%20%20X2%20--%3E%20XO(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0A%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/websocket%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X1234(Xray-inbound:1234)%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/vmesstcp%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2345(Xray-inbound:2345)%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/vmessws%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X3456(Xray-inbound:3456)%0A%20%20%20%20X1%20--%3E%20%7C%E5%85%B6%E5%AE%83%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20X1310(Xray-inbound:1310)%0A%0A%20%20%20%20X1234%20--%3E%20X2%0A%20%20%20%20X2345%20--%3E%20X2%0A%20%20%20%20X3456%20--%3E%20X2%0A%0A%20%20%20%20X1310%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20trojan%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2%0A%20%20%20%20X1310%20--%3E%20%7C%E5%85%B6%E4%BB%96%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20N80(Nginx:80)%0A%0A%20%20%20%20N80:::nginxclass%20--%3E%20H(index.html)%0A%0A%20%20%20%20H:::nginxclass%0A%20%20%20%20classDef%20nginxclass%20fill:#FFFFDE%0A"}),Y,Q,z,p("p",null,[G,p("a",J,[K,o(sn)]),Z]),$],64)};export default r; +import{r as n,o as s,c as a,a as p,b as o,w as t,F as e,e as c,d as l}from"./app.48111a85.js";const r={},u=p("h1",{id:"回落-fallbacks-功能简析",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#回落-fallbacks-功能简析","aria-hidden":"true"},"#"),c(" 回落 (fallbacks) 功能简析")],-1),i=p("p",null,"在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),k=p("h2",{id:"_1-回顾《小小白白话文》中的回落",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_1-回顾《小小白白话文》中的回落","aria-hidden":"true"},"#"),c(" 1. 回顾《小小白白话文》中的回落")],-1),b=c("如果你用了《小小白白话文》中的"),d=c("Xray 配置"),m=c(",并完成了"),q=c("HTTP 自动跳转 HTTPS 优化"),E=c(",那么你已经有了基于 "),y=p("code",null,"VLESS",-1),g=c(" 协议的简易回落:"),A=l('
    {\n  "inbounds": [\n    {\n      "port": 443,\n      "protocol": "vless",\n      "settings": {\n        "clients": [\n          // ... ...\n        ],\n        "decryption": "none",\n        "fallbacks": [\n          {\n            "dest": 8080 // 默认回落到防探测的代理\n          }\n        ]\n      },\n      "streamSettings": {\n        // ... ...\n      }\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    这一段配置用人话要怎么解释呢?

    ',2),h=l('
  • Xray 的入站端口 [inbound port]443

    即由 Xray 负责监听 443 端口的 HTTPS 流量

  • Xray 的入站协议 [inbound protocol]vless

    只有 vless 协议的流量才会流入 Xray 中做后续处理。

    Warning

    注: VLESS 这个轻量协议开发的初衷就是给 xrayv2fly 等核心引入回落功能、并同时减少冗余校验/加密。(当然,到目前为止,xray 中的 trojan 协议也已完整支持回落功能。)

  • 回落目标端口 [fallback dest]8080

    Xray 接受 443 端口的访问流量后,属于 vless 协议的流量、由 Xray 进行内部处理并转发至出站模块。而其他非 vless 协议的流量,则转发至 8080 端口。

    Warning

    问:到底是单数还是复数?

    答:一定有聪明的同学发现,配置文件中,明明是复数 inbounds, fallbacks,为什么我解释的时候都是单数:inbound, fallback 呢?

    因为,配置文件中用复数,说明 xray 支持 N 个同等级的元素(即 N 个入站,M 个回落等等),上面的示例解析中仅仅是其中一个,所以我用了单数。

  • 回落给 8080 端口的流量,由后续程序处理

    小小白白话文中的示例,就是 8080 端口由 Nginx 处理,根据配置找到并展示小熊猫的网页。

  • ',4),v=p("p",null,[p("strong",null,"总结,小小白白话文示例中的最简单回落,完整数据路线如下:")],-1),X=l('

    2. 重新认识回落 (WHAT, HOW v1)

    基于上面的示例,你应该就可以明白什么是回落(What)和怎么回落(How)了,简单地说就是下面这几个要素:

    1. 回落的时间是流量进入 Xray监听端口
    2. 回落的依据是 协议类型 等流量特征
    3. 回落的目标是某个 端口
    4. 被回落的流量由监听 回落端口 的后续程序接手

    3. 为什么要回落 (WHY v1)

    最初,是为了防御 【主动探测】 (Active Probing)

    主动探测: 简单粗暴的理解,就是指外部通过发送特定的网络请求,并解读服务器的回应内容,来推测服务器端是否运行了 xray, v2fly, shadowsocks 等代理工具。一旦可以准确认定,则服务器可能受到干扰或阻断。

    之所以可以根据服务器回应内容进行解读,就是因为一次完整的数据请求,其实有很多数据交换的步骤,每一个步骤,都会产生一些软件特征。用大白话说就是:

    • 正常的网站的回应,一定【会有】类似 Nginx, Apache, MySQL 的 Web 服务、数据库等工具的特征
    • 正常的网站的回应,一定【不会有】类似 xray, v2fly, shadowsocks 等代理工具的特征

    于是,当我们给 Xray 提供了【回落】功能后(如上例,回落给 Nginx),面对任何用来探测的请求,产生的结果是:

    • 探测流量无法掌握你的 VLESS 要素,故都会被回落至 Nginx
    • 探测流量全都回落进入 Nginx ,故 VPS 服务器的回应一定【会有】 Nginx 的特征
    • 因为 Xray 本身不对探测流量做任何回应 ,所以 VPS 的回应一定【不会有】 Xray 的特征

    至此,【回落】功能就从数据交互逻辑上解决了服务器被 【主动探测】 的安全隐患。

    4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)

    为什么又要再次认识回落呢? 因为,上面仅仅说清楚了基于“协议”的、抵抗【主动探测】的初版回落。

    ',13),x=c("在 "),S={href:"https://github.com/rprx",target:"_blank",rel:"noopener noreferrer"},B=c("RPRX"),f=c(" 不断开发迭代 "),C=p("code",null,"VLESS",-1),T=c(" 协议及 "),w=p("code",null,"fallback",-1),P=c(" 功能的过程中,逐渐发现,回落完全可以更加灵活强大,只要在保证抵抗【主动探测】的前提下,充分利用数据首包中的信息,其实可以做到多元素、多层次的回落。(如 "),F=p("code",null,"path",-1),H=c(", "),j=p("code",null,"alpn",-1),_=c(" 等)"),L=l('

    基于这个开发理念,【回落】功能才逐渐成长为现在的完全体,即完成了 纯伪装 --> ws分流 --> 多协议多特征分流 的进化。最终版甚至完全替代了以前要用 Web 服务器、其他工具才能完成的分流的功能。且由于上述的【回落/分流】处理都在首包判断阶段以毫秒级的速度完成、不涉及任何数据操作,所以几乎没有任何过程损耗。

    因此,现在 Xray 中【完整体的回落功能】,同时具备下述属性:

    • 安全: 充分抵御主动探测攻击
    • 高效: 几乎毫无性能损失
    • 灵活: 数据灵活分流、常用端口复用(如 443)

    啰嗦君

    这样多轮介绍虽然略显繁琐,但只有这样层层深入展开,才能充分的说明【回落の完全体】独有的强大!

    5. 多层回落示例及解读

    ',5),D=c("理解了【回落の完全体】是什么,那就可以动手操作配置多层回落了。其实,项目已经提供了非常完整的示例,即官方模板中的 "),N={href:"https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/",target:"_blank",rel:"noopener noreferrer"},W=c("VLESS-TCP-XTLS-WHATEVER"),V=c("。"),R=l('

    5.1 首先,我将服务器端配置的 443 监听段摘抄如下:

    {\n  "port": 443,\n  "protocol": "vless",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "flow": "xtls-rprx-vision",\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "decryption": "none",\n    "fallbacks": [\n      {\n        "dest": 1310, // 默认回落到 Xray 的 Trojan 协议\n        "xver": 1\n      },\n      {\n        "path": "/websocket", // 必须换成自定义的 PATH\n        "dest": 1234,\n        "xver": 1\n      },\n      {\n        "path": "/vmesstcp", // 必须换成自定义的 PATH\n        "dest": 2345,\n        "xver": 1\n      },\n      {\n        "path": "/vmessws", // 必须换成自定义的 PATH\n        "dest": 3456,\n        "xver": 1\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "tls",\n    "tlsSettings": {\n      "alpn": ["http/1.1"],\n      "certificates": [\n        {\n          "certificateFile": "/path/to/fullchain.crt", // 换成你的证书,绝对路径\n          "keyFile": "/path/to/private.key" // 换成你的私钥,绝对路径\n        }\n      ]\n    }\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49

    这一段配置用人话要怎么解释呢?

    ',3),O=l("
  • Xray 的入站端口 (inbound port) 是 443

    即由 Xray 负责监听 443 端口的 HTTPS 流量,并使用 certificates 项下设定的 TLS 证书来进行验证

  • Xray 的入站协议 (inbound protocol) 是 vless

    vless 协议流量直接流入 Xray 中做后续处理

  • VLESS 协议流量有 4 个不同的回落目标:

    1. pathwebsocket 的流量,回落给端口 1234 后续处理
    2. pathvmesstcp 的流量,回落给端口 2345 后续处理
    3. pathvmessws 的流量,回落给端口 3456 后续处理
    4. 其它所有流量,回落给端口 1310 后续处理
  • xver1 表示开启 proxy protocol 功能,向后传递来源真实 IP

  • ",4),U=p("p",null,[p("strong",null,"上述回落结构如下图所示:")],-1),I=p("li",null,[p("p",null,[p("strong",null,"网页回落不见了!")]),p("p",null,[c("没错,聪明的同学应该发现了,防御【主动探测】的 "),p("code",null,"nginx回落"),c(" 不见了!!!这是为什么呢?会不会不安全?别急,我们继续分析:")])],-1),M=l('

    5.2 后续监听处理的配置段摘抄如下:

    1. 后续处理回落至 1310 端口的流量,按照下面的配置验证、处理:

      {\n  "port": 1310,\n  "listen": "127.0.0.1",\n  "protocol": "trojan",\n  "settings": {\n    "clients": [\n      {\n        "password": "", // 填写你的密码\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "fallbacks": [\n      {\n        "dest": 80 // 或者回落到其它也防探测的代理\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "none",\n    "tcpSettings": {\n      "acceptProxyProtocol": true\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26

      看,神奇的事情发生了, trojan 协议这里又出现了一个新的 fallbacks。前面已经说过,xray 中的 trojan 协议也具有完整的回落能力,所以,此时 trojan 协议可以再次做判断和回落(这也就是传说中的套娃回落了):

      • 所有 trojan 协议的流量,流入 Xray 中做后续处理
      • 所有非 trojan 协议的流量,转发至 80 端口,【主动探测】的防御,完成!
    2. 后续处理回落至 1234 端口的流量,仔细看!它其实是 vless+ws

      {\n  "port": 1234,\n  "listen": "127.0.0.1",\n  "protocol": "vless",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "decryption": "none"\n  },\n  "streamSettings": {\n    "network": "ws",\n    "security": "none",\n    "wsSettings": {\n      "acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS,需要删掉这行\n      "path": "/websocket" // 必须换成自定义的 PATH,需要和分流的一致\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
    3. 后续处理回落至 2345 端口的流量,仔细看!它其实是 vmess直连

      {\n  "port": 2345,\n  "listen": "127.0.0.1",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "none",\n    "tcpSettings": {\n      "acceptProxyProtocol": true,\n      "header": {\n        "type": "http",\n        "request": {\n          "path": [\n            "/vmesstcp" // 必须换成自定义的 PATH,需要和分流的一致\n          ]\n        }\n      }\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
    4. 后续处理回落至 3456 端口的流量,再仔细看!它其实是是 vmess+ws(+cdn)

      说明

      你没看错,这就是 v2fly 曾经推荐的组合之一,并可完整支持 CDN。现已加入完美回落套餐哦!

      {\n  "port": 3456,\n  "listen": "127.0.0.1",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "ws",\n    "security": "none",\n    "wsSettings": {\n      "acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS,需要删掉这行\n      "path": "/vmessws" // 必须换成自定义的 PATH,需要和分流的一致\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
    5. 至此,我们就能够完整的画出模板的回落路线了:

    ',2),Y=p("h2",{id:"_6-结语",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_6-结语","aria-hidden":"true"},"#"),c(" 6. 结语")],-1),Q=p("p",null,[c("至此,"),p("code",null,"Xray"),c(" 的【回落】功能就介绍完了。希望本文能够对你理解 "),p("code",null,"Xray"),c(" 的强大有所帮助。")],-1),z=p("h2",{id:"_7-附加题",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_7-附加题","aria-hidden":"true"},"#"),c(" 7. 附加题")],-1),G=c("我再无耻的留一个附加题:本文详解的 "),J={href:"https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/",target:"_blank",rel:"noopener noreferrer"},K=c("VLESS-TCP-XTLS-WHATEVER"),Z=c(" 模板?是否有可以优化的地方?"),$=p("p",null,"提示:HTTP 自动跳转 HTTPS",-1);r.render=function(c,l){const r=n("RouterLink"),nn=n("Mermaid"),sn=n("OutboundLink");return s(),a(e,null,[u,i,k,p("p",null,[b,o(r,{to:"/en/document/level-0/ch07-xray-server.html#_7-4-%E9%85%8D%E7%BD%AExray"},{default:t((()=>[d])),_:1}),m,o(r,{to:"/en/document/level-0/ch07-xray-server.html#_7-8-%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%BC%98%E5%8C%96%E4%B9%8B%E4%BA%8C-%E5%BC%80%E5%90%AFhttp%E8%87%AA%E5%8A%A8%E8%B7%B3%E8%BD%AChttps"},{default:t((()=>[q])),_:1}),E,y,g]),A,p("ol",null,[h,p("li",null,[v,o(nn,{identifier:"mermaid_382ee1e9",graph:"graph%20LR;%0A%0AW(%E5%A4%96%E9%83%A8%20HTTP:80%20%E8%AF%B7%E6%B1%82)%20--%3E%20N80(HTTP:80)%0A%0Asubgraph%20Nginx%20%E5%A4%96%E9%83%A8%E7%9B%91%E5%90%AC%0AN80%20-.-%20N301(301%E8%BD%AC%E5%86%99)%20-.-%20N443(HTTPS:443)%0Aend%0A%0AN443%20--%3E%20X(Xray%20%E7%9B%91%E5%90%AC%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0AX1%20--%3E%20%7C%E6%8E%A5%E6%94%B6%20VLESS%20%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0AX2%20--%3E%20O(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0AX1%20==%3E%20%7C%E5%9B%9E%E8%90%BD%20%E9%9D%9EVLESS%20%E6%B5%81%E9%87%8F%7C%20N8080(Nginx:8080)%0AN8080:::nginxclass%20==%3E%20H(index.html)%0A%0AH:::nginxclass%0AclassDef%20nginxclass%20fill:#FFFFDE%0A%0A"})])]),X,p("p",null,[x,p("a",S,[B,o(sn)]),f,C,T,w,P,F,H,j,_]),L,p("p",null,[D,p("a",N,[W,o(sn)]),V]),R,p("ol",null,[O,p("li",null,[U,o(nn,{identifier:"mermaid_64a56832",graph:"graph%20LR;%0A%0AW443(%E5%A4%96%E9%83%A8%20HTTP:443%20%E8%AF%B7%E6%B1%82)%20--%3E%20X443(Xray-inbound:%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0AX1%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20VLESS%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0AX2%20--%3E%20O(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0A%0AX1%20--%3E%20%7Cpath%20=%20/websocket%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X1234(Xray-inbound:1234)%0AX1%20--%3E%20%7Cpath%20=%20/vmesstcp%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2345(Xray-inbound:2345)%0AX1%20--%3E%20%7Cpath%20=%20/vmessws%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X3456(Xray-inbound:3456)%0AX1%20--%3E%20%7C%E5%85%B6%E5%AE%83%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20X1310(Xray-inbound:1310)%0A%0A"})]),I]),M,o(nn,{identifier:"mermaid_64a5619e",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20W443(%E5%A4%96%E9%83%A8%20HTTP:443%20%E8%AF%B7%E6%B1%82)%20--%3E%20X443(Xray-inbound:%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0A%20%20%20%20X1%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20VLESS%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0A%20%20%20%20X2%20--%3E%20XO(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0A%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/websocket%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X1234(Xray-inbound:1234)%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/vmesstcp%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2345(Xray-inbound:2345)%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/vmessws%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X3456(Xray-inbound:3456)%0A%20%20%20%20X1%20--%3E%20%7C%E5%85%B6%E5%AE%83%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20X1310(Xray-inbound:1310)%0A%0A%20%20%20%20X1234%20--%3E%20X2%0A%20%20%20%20X2345%20--%3E%20X2%0A%20%20%20%20X3456%20--%3E%20X2%0A%0A%20%20%20%20X1310%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20trojan%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2%0A%20%20%20%20X1310%20--%3E%20%7C%E5%85%B6%E4%BB%96%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20N80(Nginx:80)%0A%0A%20%20%20%20N80:::nginxclass%20--%3E%20H(index.html)%0A%0A%20%20%20%20H:::nginxclass%0A%20%20%20%20classDef%20nginxclass%20fill:#FFFFDE%0A"}),Y,Q,z,p("p",null,[G,p("a",J,[K,o(sn)]),Z]),$],64)};export default r; diff --git a/assets/fallbacks-lv1.html.c7274041.js b/assets/fallbacks-lv1.html.792c6109.js similarity index 99% rename from assets/fallbacks-lv1.html.c7274041.js rename to assets/fallbacks-lv1.html.792c6109.js index 7ca3887ef..7ec3752b3 100644 --- a/assets/fallbacks-lv1.html.c7274041.js +++ b/assets/fallbacks-lv1.html.792c6109.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as o,w as t,F as e,e as c,d as l}from"./app.755d843f.js";const r={},u=p("h1",{id:"回落-fallbacks-功能简析",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#回落-fallbacks-功能简析","aria-hidden":"true"},"#"),c(" 回落 (fallbacks) 功能简析")],-1),i=p("p",null,"在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),k=p("h2",{id:"_1-回顾《小小白白话文》中的回落",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_1-回顾《小小白白话文》中的回落","aria-hidden":"true"},"#"),c(" 1. 回顾《小小白白话文》中的回落")],-1),b=c("如果你用了《小小白白话文》中的"),d=c("Xray 配置"),m=c(",并完成了"),q=c("HTTP 自动跳转 HTTPS 优化"),E=c(",那么你已经有了基于 "),y=p("code",null,"VLESS",-1),g=c(" 协议的简易回落:"),A=l('
    {\n  "inbounds": [\n    {\n      "port": 443,\n      "protocol": "vless",\n      "settings": {\n        "clients": [\n          // ... ...\n        ],\n        "decryption": "none",\n        "fallbacks": [\n          {\n            "dest": 8080 // 默认回落到防探测的代理\n          }\n        ]\n      },\n      "streamSettings": {\n        // ... ...\n      }\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    这一段配置用人话要怎么解释呢?

    ',2),h=l('
  • Xray 的入站端口 [inbound port]443

    即由 Xray 负责监听 443 端口的 HTTPS 流量

  • Xray 的入站协议 [inbound protocol]vless

    只有 vless 协议的流量才会流入 Xray 中做后续处理。

    注意

    注: VLESS 这个轻量协议开发的初衷就是给 xrayv2fly 等核心引入回落功能、并同时减少冗余校验/加密。(当然,到目前为止,xray 中的 trojan 协议也已完整支持回落功能。)

  • 回落目标端口 [fallback dest]8080

    Xray 接受 443 端口的访问流量后,属于 vless 协议的流量、由 Xray 进行内部处理并转发至出站模块。而其他非 vless 协议的流量,则转发至 8080 端口。

    注意

    问:到底是单数还是复数?

    答:一定有聪明的同学发现,配置文件中,明明是复数 inbounds, fallbacks,为什么我解释的时候都是单数:inbound, fallback 呢?

    因为,配置文件中用复数,说明 xray 支持 N 个同等级的元素(即 N 个入站,M 个回落等等),上面的示例解析中仅仅是其中一个,所以我用了单数。

  • 回落给 8080 端口的流量,由后续程序处理

    小小白白话文中的示例,就是 8080 端口由 Nginx 处理,根据配置找到并展示小熊猫的网页。

  • ',4),v=p("p",null,[p("strong",null,"总结,小小白白话文示例中的最简单回落,完整数据路线如下:")],-1),X=l('

    2. 重新认识回落 (WHAT, HOW v1)

    基于上面的示例,你应该就可以明白什么是回落(What)和怎么回落(How)了,简单地说就是下面这几个要素:

    1. 回落的时间是流量进入 Xray监听端口
    2. 回落的依据是 协议类型 等流量特征
    3. 回落的目标是某个 端口
    4. 被回落的流量由监听 回落端口 的后续程序接手

    3. 为什么要回落 (WHY v1)

    最初,是为了防御 【主动探测】 (Active Probing)

    主动探测: 简单粗暴的理解,就是指外部通过发送特定的网络请求,并解读服务器的回应内容,来推测服务器端是否运行了 xray, v2fly, shadowsocks 等代理工具。一旦可以准确认定,则服务器可能受到干扰或阻断。

    之所以可以根据服务器回应内容进行解读,就是因为一次完整的数据请求,其实有很多数据交换的步骤,每一个步骤,都会产生一些软件特征。用大白话说就是:

    • 正常的网站的回应,一定【会有】类似 Nginx, Apache, MySQL 的 Web 服务、数据库等工具的特征
    • 正常的网站的回应,一定【不会有】类似 xray, v2fly, shadowsocks 等代理工具的特征

    于是,当我们给 Xray 提供了【回落】功能后(如上例,回落给 Nginx),面对任何用来探测的请求,产生的结果是:

    • 探测流量无法掌握你的 VLESS 要素,故都会被回落至 Nginx
    • 探测流量全都回落进入 Nginx ,故 VPS 服务器的回应一定【会有】 Nginx 的特征
    • 因为 Xray 本身不对探测流量做任何回应 ,所以 VPS 的回应一定【不会有】 Xray 的特征

    至此,【回落】功能就从数据交互逻辑上解决了服务器被 【主动探测】 的安全隐患。

    4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)

    为什么又要再次认识回落呢? 因为,上面仅仅说清楚了基于“协议”的、抵抗【主动探测】的初版回落。

    ',13),x=c("在 "),S={href:"https://github.com/rprx",target:"_blank",rel:"noopener noreferrer"},B=c("RPRX"),f=c(" 不断开发迭代 "),C=p("code",null,"VLESS",-1),T=c(" 协议及 "),w=p("code",null,"fallback",-1),P=c(" 功能的过程中,逐渐发现,回落完全可以更加灵活强大,只要在保证抵抗【主动探测】的前提下,充分利用数据首包中的信息,其实可以做到多元素、多层次的回落。(如 "),F=p("code",null,"path",-1),H=c(", "),j=p("code",null,"alpn",-1),_=c(" 等)"),L=l('

    基于这个开发理念,【回落】功能才逐渐成长为现在的完全体,即完成了 纯伪装 --> ws分流 --> 多协议多特征分流 的进化。最终版甚至完全替代了以前要用 Web 服务器、其他工具才能完成的分流的功能。且由于上述的【回落/分流】处理都在首包判断阶段以毫秒级的速度完成、不涉及任何数据操作,所以几乎没有任何过程损耗。

    因此,现在 Xray 中【完整体的回落功能】,同时具备下述属性:

    • 安全: 充分抵御主动探测攻击
    • 高效: 几乎毫无性能损失
    • 灵活: 数据灵活分流、常用端口复用(如 443)

    啰嗦君

    这样多轮介绍虽然略显繁琐,但只有这样层层深入展开,才能充分的说明【回落の完全体】独有的强大!

    5. 多层回落示例及解读

    ',5),D=c("理解了【回落の完全体】是什么,那就可以动手操作配置多层回落了。其实,项目已经提供了非常完整的示例,即官方模板中的 "),N={href:"https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/",target:"_blank",rel:"noopener noreferrer"},V=c("VLESS-TCP-XTLS-WHATEVER"),W=c("。"),R=l('

    5.1 首先,我将服务器端配置的 443 监听段摘抄如下:

    {\n  "port": 443,\n  "protocol": "vless",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "flow": "xtls-rprx-vision",\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "decryption": "none",\n    "fallbacks": [\n      {\n        "dest": 1310, // 默认回落到 Xray 的 Trojan 协议\n        "xver": 1\n      },\n      {\n        "path": "/websocket", // 必须换成自定义的 PATH\n        "dest": 1234,\n        "xver": 1\n      },\n      {\n        "path": "/vmesstcp", // 必须换成自定义的 PATH\n        "dest": 2345,\n        "xver": 1\n      },\n      {\n        "path": "/vmessws", // 必须换成自定义的 PATH\n        "dest": 3456,\n        "xver": 1\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "tls",\n    "tlsSettings": {\n      "alpn": ["http/1.1"],\n      "certificates": [\n        {\n          "certificateFile": "/path/to/fullchain.crt", // 换成你的证书,绝对路径\n          "keyFile": "/path/to/private.key" // 换成你的私钥,绝对路径\n        }\n      ]\n    }\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49

    这一段配置用人话要怎么解释呢?

    ',3),O=l("
  • Xray 的入站端口 (inbound port) 是 443

    即由 Xray 负责监听 443 端口的 HTTPS 流量,并使用 certificates 项下设定的 TLS 证书来进行验证

  • Xray 的入站协议 (inbound protocol) 是 vless

    vless 协议流量直接流入 Xray 中做后续处理

  • VLESS 协议流量有 4 个不同的回落目标:

    1. pathwebsocket 的流量,回落给端口 1234 后续处理
    2. pathvmesstcp 的流量,回落给端口 2345 后续处理
    3. pathvmessws 的流量,回落给端口 3456 后续处理
    4. 其它所有流量,回落给端口 1310 后续处理
  • xver1 表示开启 proxy protocol 功能,向后传递来源真实 IP

  • ",4),U=p("p",null,[p("strong",null,"上述回落结构如下图所示:")],-1),I=p("li",null,[p("p",null,[p("strong",null,"网页回落不见了!")]),p("p",null,[c("没错,聪明的同学应该发现了,防御【主动探测】的 "),p("code",null,"nginx回落"),c(" 不见了!!!这是为什么呢?会不会不安全?别急,我们继续分析:")])],-1),M=l('

    5.2 后续监听处理的配置段摘抄如下:

    1. 后续处理回落至 1310 端口的流量,按照下面的配置验证、处理:

      {\n  "port": 1310,\n  "listen": "127.0.0.1",\n  "protocol": "trojan",\n  "settings": {\n    "clients": [\n      {\n        "password": "", // 填写你的密码\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "fallbacks": [\n      {\n        "dest": 80 // 或者回落到其它也防探测的代理\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "none",\n    "tcpSettings": {\n      "acceptProxyProtocol": true\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26

      看,神奇的事情发生了, trojan 协议这里又出现了一个新的 fallbacks。前面已经说过,xray 中的 trojan 协议也具有完整的回落能力,所以,此时 trojan 协议可以再次做判断和回落(这也就是传说中的套娃回落了):

      • 所有 trojan 协议的流量,流入 Xray 中做后续处理
      • 所有非 trojan 协议的流量,转发至 80 端口,【主动探测】的防御,完成!
    2. 后续处理回落至 1234 端口的流量,仔细看!它其实是 vless+ws

      {\n  "port": 1234,\n  "listen": "127.0.0.1",\n  "protocol": "vless",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "decryption": "none"\n  },\n  "streamSettings": {\n    "network": "ws",\n    "security": "none",\n    "wsSettings": {\n      "acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS,需要删掉这行\n      "path": "/websocket" // 必须换成自定义的 PATH,需要和分流的一致\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
    3. 后续处理回落至 2345 端口的流量,仔细看!它其实是 vmess直连

      {\n  "port": 2345,\n  "listen": "127.0.0.1",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "none",\n    "tcpSettings": {\n      "acceptProxyProtocol": true,\n      "header": {\n        "type": "http",\n        "request": {\n          "path": [\n            "/vmesstcp" // 必须换成自定义的 PATH,需要和分流的一致\n          ]\n        }\n      }\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
    4. 后续处理回落至 3456 端口的流量,再仔细看!它其实是是 vmess+ws(+cdn)

      说明

      你没看错,这就是 v2fly 曾经推荐的组合之一,并可完整支持 CDN。现已加入完美回落套餐哦!

      {\n  "port": 3456,\n  "listen": "127.0.0.1",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "ws",\n    "security": "none",\n    "wsSettings": {\n      "acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS,需要删掉这行\n      "path": "/vmessws" // 必须换成自定义的 PATH,需要和分流的一致\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
    5. 至此,我们就能够完整的画出模板的回落路线了:

    ',2),Y=p("h2",{id:"_6-结语",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_6-结语","aria-hidden":"true"},"#"),c(" 6. 结语")],-1),Q=p("p",null,[c("至此,"),p("code",null,"Xray"),c(" 的【回落】功能就介绍完了。希望本文能够对你理解 "),p("code",null,"Xray"),c(" 的强大有所帮助。")],-1),z=p("h2",{id:"_7-附加题",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_7-附加题","aria-hidden":"true"},"#"),c(" 7. 附加题")],-1),G=c("我再无耻的留一个附加题:本文详解的 "),J={href:"https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/",target:"_blank",rel:"noopener noreferrer"},K=c("VLESS-TCP-XTLS-WHATEVER"),Z=c(" 模板?是否有可以优化的地方?"),$=p("p",null,"提示:HTTP 自动跳转 HTTPS",-1);r.render=function(c,l){const r=n("RouterLink"),nn=n("Mermaid"),sn=n("OutboundLink");return s(),a(e,null,[u,i,k,p("p",null,[b,o(r,{to:"/document/level-0/ch07-xray-server.html#_7-4-%E9%85%8D%E7%BD%AExray"},{default:t((()=>[d])),_:1}),m,o(r,{to:"/document/level-0/ch07-xray-server.html#_7-8-%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%BC%98%E5%8C%96%E4%B9%8B%E4%BA%8C-%E5%BC%80%E5%90%AFhttp%E8%87%AA%E5%8A%A8%E8%B7%B3%E8%BD%AChttps"},{default:t((()=>[q])),_:1}),E,y,g]),A,p("ol",null,[h,p("li",null,[v,o(nn,{identifier:"mermaid_382ee1e9",graph:"graph%20LR;%0A%0AW(%E5%A4%96%E9%83%A8%20HTTP:80%20%E8%AF%B7%E6%B1%82)%20--%3E%20N80(HTTP:80)%0A%0Asubgraph%20Nginx%20%E5%A4%96%E9%83%A8%E7%9B%91%E5%90%AC%0AN80%20-.-%20N301(301%E8%BD%AC%E5%86%99)%20-.-%20N443(HTTPS:443)%0Aend%0A%0AN443%20--%3E%20X(Xray%20%E7%9B%91%E5%90%AC%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0AX1%20--%3E%20%7C%E6%8E%A5%E6%94%B6%20VLESS%20%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0AX2%20--%3E%20O(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0AX1%20==%3E%20%7C%E5%9B%9E%E8%90%BD%20%E9%9D%9EVLESS%20%E6%B5%81%E9%87%8F%7C%20N8080(Nginx:8080)%0AN8080:::nginxclass%20==%3E%20H(index.html)%0A%0AH:::nginxclass%0AclassDef%20nginxclass%20fill:#FFFFDE%0A%0A"})])]),X,p("p",null,[x,p("a",S,[B,o(sn)]),f,C,T,w,P,F,H,j,_]),L,p("p",null,[D,p("a",N,[V,o(sn)]),W]),R,p("ol",null,[O,p("li",null,[U,o(nn,{identifier:"mermaid_64a56832",graph:"graph%20LR;%0A%0AW443(%E5%A4%96%E9%83%A8%20HTTP:443%20%E8%AF%B7%E6%B1%82)%20--%3E%20X443(Xray-inbound:%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0AX1%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20VLESS%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0AX2%20--%3E%20O(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0A%0AX1%20--%3E%20%7Cpath%20=%20/websocket%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X1234(Xray-inbound:1234)%0AX1%20--%3E%20%7Cpath%20=%20/vmesstcp%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2345(Xray-inbound:2345)%0AX1%20--%3E%20%7Cpath%20=%20/vmessws%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X3456(Xray-inbound:3456)%0AX1%20--%3E%20%7C%E5%85%B6%E5%AE%83%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20X1310(Xray-inbound:1310)%0A%0A"})]),I]),M,o(nn,{identifier:"mermaid_64a5619e",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20W443(%E5%A4%96%E9%83%A8%20HTTP:443%20%E8%AF%B7%E6%B1%82)%20--%3E%20X443(Xray-inbound:%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0A%20%20%20%20X1%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20VLESS%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0A%20%20%20%20X2%20--%3E%20XO(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0A%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/websocket%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X1234(Xray-inbound:1234)%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/vmesstcp%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2345(Xray-inbound:2345)%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/vmessws%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X3456(Xray-inbound:3456)%0A%20%20%20%20X1%20--%3E%20%7C%E5%85%B6%E5%AE%83%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20X1310(Xray-inbound:1310)%0A%0A%20%20%20%20X1234%20--%3E%20X2%0A%20%20%20%20X2345%20--%3E%20X2%0A%20%20%20%20X3456%20--%3E%20X2%0A%0A%20%20%20%20X1310%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20trojan%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2%0A%20%20%20%20X1310%20--%3E%20%7C%E5%85%B6%E4%BB%96%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20N80(Nginx:80)%0A%0A%20%20%20%20N80:::nginxclass%20--%3E%20H(index.html)%0A%0A%20%20%20%20H:::nginxclass%0A%20%20%20%20classDef%20nginxclass%20fill:#FFFFDE%0A"}),Y,Q,z,p("p",null,[G,p("a",J,[K,o(sn)]),Z]),$],64)};export default r; +import{r as n,o as s,c as a,a as p,b as o,w as t,F as e,e as c,d as l}from"./app.48111a85.js";const r={},u=p("h1",{id:"回落-fallbacks-功能简析",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#回落-fallbacks-功能简析","aria-hidden":"true"},"#"),c(" 回落 (fallbacks) 功能简析")],-1),i=p("p",null,"在使用 Xray 的过程中,你一定无数次的听说了【回落】这个功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),k=p("h2",{id:"_1-回顾《小小白白话文》中的回落",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_1-回顾《小小白白话文》中的回落","aria-hidden":"true"},"#"),c(" 1. 回顾《小小白白话文》中的回落")],-1),b=c("如果你用了《小小白白话文》中的"),d=c("Xray 配置"),m=c(",并完成了"),q=c("HTTP 自动跳转 HTTPS 优化"),E=c(",那么你已经有了基于 "),y=p("code",null,"VLESS",-1),g=c(" 协议的简易回落:"),A=l('
    {\n  "inbounds": [\n    {\n      "port": 443,\n      "protocol": "vless",\n      "settings": {\n        "clients": [\n          // ... ...\n        ],\n        "decryption": "none",\n        "fallbacks": [\n          {\n            "dest": 8080 // 默认回落到防探测的代理\n          }\n        ]\n      },\n      "streamSettings": {\n        // ... ...\n      }\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    这一段配置用人话要怎么解释呢?

    ',2),h=l('
  • Xray 的入站端口 [inbound port]443

    即由 Xray 负责监听 443 端口的 HTTPS 流量

  • Xray 的入站协议 [inbound protocol]vless

    只有 vless 协议的流量才会流入 Xray 中做后续处理。

    注意

    注: VLESS 这个轻量协议开发的初衷就是给 xrayv2fly 等核心引入回落功能、并同时减少冗余校验/加密。(当然,到目前为止,xray 中的 trojan 协议也已完整支持回落功能。)

  • 回落目标端口 [fallback dest]8080

    Xray 接受 443 端口的访问流量后,属于 vless 协议的流量、由 Xray 进行内部处理并转发至出站模块。而其他非 vless 协议的流量,则转发至 8080 端口。

    注意

    问:到底是单数还是复数?

    答:一定有聪明的同学发现,配置文件中,明明是复数 inbounds, fallbacks,为什么我解释的时候都是单数:inbound, fallback 呢?

    因为,配置文件中用复数,说明 xray 支持 N 个同等级的元素(即 N 个入站,M 个回落等等),上面的示例解析中仅仅是其中一个,所以我用了单数。

  • 回落给 8080 端口的流量,由后续程序处理

    小小白白话文中的示例,就是 8080 端口由 Nginx 处理,根据配置找到并展示小熊猫的网页。

  • ',4),v=p("p",null,[p("strong",null,"总结,小小白白话文示例中的最简单回落,完整数据路线如下:")],-1),X=l('

    2. 重新认识回落 (WHAT, HOW v1)

    基于上面的示例,你应该就可以明白什么是回落(What)和怎么回落(How)了,简单地说就是下面这几个要素:

    1. 回落的时间是流量进入 Xray监听端口
    2. 回落的依据是 协议类型 等流量特征
    3. 回落的目标是某个 端口
    4. 被回落的流量由监听 回落端口 的后续程序接手

    3. 为什么要回落 (WHY v1)

    最初,是为了防御 【主动探测】 (Active Probing)

    主动探测: 简单粗暴的理解,就是指外部通过发送特定的网络请求,并解读服务器的回应内容,来推测服务器端是否运行了 xray, v2fly, shadowsocks 等代理工具。一旦可以准确认定,则服务器可能受到干扰或阻断。

    之所以可以根据服务器回应内容进行解读,就是因为一次完整的数据请求,其实有很多数据交换的步骤,每一个步骤,都会产生一些软件特征。用大白话说就是:

    • 正常的网站的回应,一定【会有】类似 Nginx, Apache, MySQL 的 Web 服务、数据库等工具的特征
    • 正常的网站的回应,一定【不会有】类似 xray, v2fly, shadowsocks 等代理工具的特征

    于是,当我们给 Xray 提供了【回落】功能后(如上例,回落给 Nginx),面对任何用来探测的请求,产生的结果是:

    • 探测流量无法掌握你的 VLESS 要素,故都会被回落至 Nginx
    • 探测流量全都回落进入 Nginx ,故 VPS 服务器的回应一定【会有】 Nginx 的特征
    • 因为 Xray 本身不对探测流量做任何回应 ,所以 VPS 的回应一定【不会有】 Xray 的特征

    至此,【回落】功能就从数据交互逻辑上解决了服务器被 【主动探测】 的安全隐患。

    4. 重新认识【回落の完全体】 (WHAT, WHY, HOW v2)

    为什么又要再次认识回落呢? 因为,上面仅仅说清楚了基于“协议”的、抵抗【主动探测】的初版回落。

    ',13),x=c("在 "),S={href:"https://github.com/rprx",target:"_blank",rel:"noopener noreferrer"},B=c("RPRX"),f=c(" 不断开发迭代 "),C=p("code",null,"VLESS",-1),T=c(" 协议及 "),w=p("code",null,"fallback",-1),P=c(" 功能的过程中,逐渐发现,回落完全可以更加灵活强大,只要在保证抵抗【主动探测】的前提下,充分利用数据首包中的信息,其实可以做到多元素、多层次的回落。(如 "),F=p("code",null,"path",-1),H=c(", "),j=p("code",null,"alpn",-1),_=c(" 等)"),L=l('

    基于这个开发理念,【回落】功能才逐渐成长为现在的完全体,即完成了 纯伪装 --> ws分流 --> 多协议多特征分流 的进化。最终版甚至完全替代了以前要用 Web 服务器、其他工具才能完成的分流的功能。且由于上述的【回落/分流】处理都在首包判断阶段以毫秒级的速度完成、不涉及任何数据操作,所以几乎没有任何过程损耗。

    因此,现在 Xray 中【完整体的回落功能】,同时具备下述属性:

    • 安全: 充分抵御主动探测攻击
    • 高效: 几乎毫无性能损失
    • 灵活: 数据灵活分流、常用端口复用(如 443)

    啰嗦君

    这样多轮介绍虽然略显繁琐,但只有这样层层深入展开,才能充分的说明【回落の完全体】独有的强大!

    5. 多层回落示例及解读

    ',5),D=c("理解了【回落の完全体】是什么,那就可以动手操作配置多层回落了。其实,项目已经提供了非常完整的示例,即官方模板中的 "),N={href:"https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/",target:"_blank",rel:"noopener noreferrer"},V=c("VLESS-TCP-XTLS-WHATEVER"),W=c("。"),R=l('

    5.1 首先,我将服务器端配置的 443 监听段摘抄如下:

    {\n  "port": 443,\n  "protocol": "vless",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "flow": "xtls-rprx-vision",\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "decryption": "none",\n    "fallbacks": [\n      {\n        "dest": 1310, // 默认回落到 Xray 的 Trojan 协议\n        "xver": 1\n      },\n      {\n        "path": "/websocket", // 必须换成自定义的 PATH\n        "dest": 1234,\n        "xver": 1\n      },\n      {\n        "path": "/vmesstcp", // 必须换成自定义的 PATH\n        "dest": 2345,\n        "xver": 1\n      },\n      {\n        "path": "/vmessws", // 必须换成自定义的 PATH\n        "dest": 3456,\n        "xver": 1\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "tls",\n    "tlsSettings": {\n      "alpn": ["http/1.1"],\n      "certificates": [\n        {\n          "certificateFile": "/path/to/fullchain.crt", // 换成你的证书,绝对路径\n          "keyFile": "/path/to/private.key" // 换成你的私钥,绝对路径\n        }\n      ]\n    }\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49

    这一段配置用人话要怎么解释呢?

    ',3),O=l("
  • Xray 的入站端口 (inbound port) 是 443

    即由 Xray 负责监听 443 端口的 HTTPS 流量,并使用 certificates 项下设定的 TLS 证书来进行验证

  • Xray 的入站协议 (inbound protocol) 是 vless

    vless 协议流量直接流入 Xray 中做后续处理

  • VLESS 协议流量有 4 个不同的回落目标:

    1. pathwebsocket 的流量,回落给端口 1234 后续处理
    2. pathvmesstcp 的流量,回落给端口 2345 后续处理
    3. pathvmessws 的流量,回落给端口 3456 后续处理
    4. 其它所有流量,回落给端口 1310 后续处理
  • xver1 表示开启 proxy protocol 功能,向后传递来源真实 IP

  • ",4),U=p("p",null,[p("strong",null,"上述回落结构如下图所示:")],-1),I=p("li",null,[p("p",null,[p("strong",null,"网页回落不见了!")]),p("p",null,[c("没错,聪明的同学应该发现了,防御【主动探测】的 "),p("code",null,"nginx回落"),c(" 不见了!!!这是为什么呢?会不会不安全?别急,我们继续分析:")])],-1),M=l('

    5.2 后续监听处理的配置段摘抄如下:

    1. 后续处理回落至 1310 端口的流量,按照下面的配置验证、处理:

      {\n  "port": 1310,\n  "listen": "127.0.0.1",\n  "protocol": "trojan",\n  "settings": {\n    "clients": [\n      {\n        "password": "", // 填写你的密码\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "fallbacks": [\n      {\n        "dest": 80 // 或者回落到其它也防探测的代理\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "none",\n    "tcpSettings": {\n      "acceptProxyProtocol": true\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26

      看,神奇的事情发生了, trojan 协议这里又出现了一个新的 fallbacks。前面已经说过,xray 中的 trojan 协议也具有完整的回落能力,所以,此时 trojan 协议可以再次做判断和回落(这也就是传说中的套娃回落了):

      • 所有 trojan 协议的流量,流入 Xray 中做后续处理
      • 所有非 trojan 协议的流量,转发至 80 端口,【主动探测】的防御,完成!
    2. 后续处理回落至 1234 端口的流量,仔细看!它其实是 vless+ws

      {\n  "port": 1234,\n  "listen": "127.0.0.1",\n  "protocol": "vless",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ],\n    "decryption": "none"\n  },\n  "streamSettings": {\n    "network": "ws",\n    "security": "none",\n    "wsSettings": {\n      "acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS,需要删掉这行\n      "path": "/websocket" // 必须换成自定义的 PATH,需要和分流的一致\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
    3. 后续处理回落至 2345 端口的流量,仔细看!它其实是 vmess直连

      {\n  "port": 2345,\n  "listen": "127.0.0.1",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "tcp",\n    "security": "none",\n    "tcpSettings": {\n      "acceptProxyProtocol": true,\n      "header": {\n        "type": "http",\n        "request": {\n          "path": [\n            "/vmesstcp" // 必须换成自定义的 PATH,需要和分流的一致\n          ]\n        }\n      }\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
    4. 后续处理回落至 3456 端口的流量,再仔细看!它其实是是 vmess+ws(+cdn)

      说明

      你没看错,这就是 v2fly 曾经推荐的组合之一,并可完整支持 CDN。现已加入完美回落套餐哦!

      {\n  "port": 3456,\n  "listen": "127.0.0.1",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "", // 填写你的 UUID\n        "level": 0,\n        "email": "love@example.com"\n      }\n    ]\n  },\n  "streamSettings": {\n    "network": "ws",\n    "security": "none",\n    "wsSettings": {\n      "acceptProxyProtocol": true, // 提醒:若你用 Nginx/Caddy 等反代 WS,需要删掉这行\n      "path": "/vmessws" // 必须换成自定义的 PATH,需要和分流的一致\n    }\n  }\n}\n
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
    5. 至此,我们就能够完整的画出模板的回落路线了:

    ',2),Y=p("h2",{id:"_6-结语",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_6-结语","aria-hidden":"true"},"#"),c(" 6. 结语")],-1),Q=p("p",null,[c("至此,"),p("code",null,"Xray"),c(" 的【回落】功能就介绍完了。希望本文能够对你理解 "),p("code",null,"Xray"),c(" 的强大有所帮助。")],-1),z=p("h2",{id:"_7-附加题",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#_7-附加题","aria-hidden":"true"},"#"),c(" 7. 附加题")],-1),G=c("我再无耻的留一个附加题:本文详解的 "),J={href:"https://github.com/XTLS/Xray-examples/blob/main/VLESS-TCP-XTLS-WHATEVER/",target:"_blank",rel:"noopener noreferrer"},K=c("VLESS-TCP-XTLS-WHATEVER"),Z=c(" 模板?是否有可以优化的地方?"),$=p("p",null,"提示:HTTP 自动跳转 HTTPS",-1);r.render=function(c,l){const r=n("RouterLink"),nn=n("Mermaid"),sn=n("OutboundLink");return s(),a(e,null,[u,i,k,p("p",null,[b,o(r,{to:"/document/level-0/ch07-xray-server.html#_7-4-%E9%85%8D%E7%BD%AExray"},{default:t((()=>[d])),_:1}),m,o(r,{to:"/document/level-0/ch07-xray-server.html#_7-8-%E6%9C%8D%E5%8A%A1%E5%99%A8%E4%BC%98%E5%8C%96%E4%B9%8B%E4%BA%8C-%E5%BC%80%E5%90%AFhttp%E8%87%AA%E5%8A%A8%E8%B7%B3%E8%BD%AChttps"},{default:t((()=>[q])),_:1}),E,y,g]),A,p("ol",null,[h,p("li",null,[v,o(nn,{identifier:"mermaid_382ee1e9",graph:"graph%20LR;%0A%0AW(%E5%A4%96%E9%83%A8%20HTTP:80%20%E8%AF%B7%E6%B1%82)%20--%3E%20N80(HTTP:80)%0A%0Asubgraph%20Nginx%20%E5%A4%96%E9%83%A8%E7%9B%91%E5%90%AC%0AN80%20-.-%20N301(301%E8%BD%AC%E5%86%99)%20-.-%20N443(HTTPS:443)%0Aend%0A%0AN443%20--%3E%20X(Xray%20%E7%9B%91%E5%90%AC%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0AX1%20--%3E%20%7C%E6%8E%A5%E6%94%B6%20VLESS%20%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0AX2%20--%3E%20O(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0AX1%20==%3E%20%7C%E5%9B%9E%E8%90%BD%20%E9%9D%9EVLESS%20%E6%B5%81%E9%87%8F%7C%20N8080(Nginx:8080)%0AN8080:::nginxclass%20==%3E%20H(index.html)%0A%0AH:::nginxclass%0AclassDef%20nginxclass%20fill:#FFFFDE%0A%0A"})])]),X,p("p",null,[x,p("a",S,[B,o(sn)]),f,C,T,w,P,F,H,j,_]),L,p("p",null,[D,p("a",N,[V,o(sn)]),W]),R,p("ol",null,[O,p("li",null,[U,o(nn,{identifier:"mermaid_64a56832",graph:"graph%20LR;%0A%0AW443(%E5%A4%96%E9%83%A8%20HTTP:443%20%E8%AF%B7%E6%B1%82)%20--%3E%20X443(Xray-inbound:%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0AX1%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20VLESS%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0AX2%20--%3E%20O(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0A%0AX1%20--%3E%20%7Cpath%20=%20/websocket%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X1234(Xray-inbound:1234)%0AX1%20--%3E%20%7Cpath%20=%20/vmesstcp%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2345(Xray-inbound:2345)%0AX1%20--%3E%20%7Cpath%20=%20/vmessws%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X3456(Xray-inbound:3456)%0AX1%20--%3E%20%7C%E5%85%B6%E5%AE%83%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20X1310(Xray-inbound:1310)%0A%0A"})]),I]),M,o(nn,{identifier:"mermaid_64a5619e",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20W443(%E5%A4%96%E9%83%A8%20HTTP:443%20%E8%AF%B7%E6%B1%82)%20--%3E%20X443(Xray-inbound:%20443)%20.-%20X1%7B%E5%85%A5%E7%AB%99%E5%88%A4%E6%96%AD%7D%0A%20%20%20%20X1%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20VLESS%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2(Xray%E5%86%85%E9%83%A8%E8%A7%84%E5%88%99)%0A%20%20%20%20X2%20--%3E%20XO(Xray%20Outbounds%20%E5%87%BA%E7%AB%99)%0A%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/websocket%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X1234(Xray-inbound:1234)%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/vmesstcp%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2345(Xray-inbound:2345)%0A%20%20%20%20X1%20--%3E%20%7Cpath%20=%20/vmessws%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X3456(Xray-inbound:3456)%0A%20%20%20%20X1%20--%3E%20%7C%E5%85%B6%E5%AE%83%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20X1310(Xray-inbound:1310)%0A%0A%20%20%20%20X1234%20--%3E%20X2%0A%20%20%20%20X2345%20--%3E%20X2%0A%20%20%20%20X3456%20--%3E%20X2%0A%0A%20%20%20%20X1310%20--%3E%20%7C%E5%8D%8F%E8%AE%AE%20=%20trojan%20%E7%9A%84%E6%B5%81%E9%87%8F%7C%20X2%0A%20%20%20%20X1310%20--%3E%20%7C%E5%85%B6%E4%BB%96%E6%89%80%E6%9C%89%E6%B5%81%E9%87%8F%7C%20N80(Nginx:80)%0A%0A%20%20%20%20N80:::nginxclass%20--%3E%20H(index.html)%0A%0A%20%20%20%20H:::nginxclass%0A%20%20%20%20classDef%20nginxclass%20fill:#FFFFDE%0A"}),Y,Q,z,p("p",null,[G,p("a",J,[K,o(sn)]),Z]),$],64)};export default r; diff --git a/assets/fallbacks-with-sni.html.a7aa5d6b.js b/assets/fallbacks-with-sni.html.b7c3a701.js similarity index 99% rename from assets/fallbacks-with-sni.html.a7aa5d6b.js rename to assets/fallbacks-with-sni.html.b7c3a701.js index 2f8bfaabc..928572a2f 100644 --- a/assets/fallbacks-with-sni.html.a7aa5d6b.js +++ b/assets/fallbacks-with-sni.html.b7c3a701.js @@ -1 +1 @@ -import{r as n,o as s,c as e,a,b as t,F as o,e as r}from"./app.755d843f.js";const l={},i=a("h1",{id:"implementing-camouflage-and-domain-based-routing-through-sni-fallback-function",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#implementing-camouflage-and-domain-based-routing-through-sni-fallback-function","aria-hidden":"true"},"#"),r(" Implementing camouflage and domain-based routing through SNI fallback function")],-1),c=a("p",null,"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.",-1),p=a("h2",{id:"application-scenarios",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#application-scenarios","aria-hidden":"true"},"#"),r(" Application Scenarios")],-1),u=a("p",null,"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:",-1),b=a("ul",null,[a("li",null,"Xray monitors other commonly used ports (such as 22, 3389, 8443).")],-1),d=a("p",null,"This plan is the simplest, but not perfect enough.",-1),m=a("ul",null,[a("li",null,"Nginx or HAProxy listens on port 443, uses SNI for L4 load balancing, and achieves port multiplexing through reverse proxy.")],-1),h=a("p",null,"This plan is relatively complicated and requires some understanding of using Nginx or HAProxy. We will not explain it in too much detail here.",-1),k=a("ul",null,[a("li",null,"Xray listens on port 443, and uses Fallbacks feature to split website traffic based on SNI and fallbacks it to Nginx or Caddy.")],-1),f=a("p",null,"This plan has a moderate level of difficulty and is the scheme that this tutorial will demonstrate next.",-1),g=a("h2",{id:"introduction-to-sni",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#introduction-to-sni","aria-hidden":"true"},"#"),r(" Introduction to SNI")],-1),y=a("p",null,"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:",-1),v=a("div",{class:"language-nginx ext-nginx line-numbers-mode"},[a("pre",{class:"language-nginx"},[a("code",null,[a("span",{class:"token directive"},[a("span",{class:"token keyword"},"proxy_set_header"),r(" Host hostname")]),a("span",{class:"token punctuation"},";"),r("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),x=a("p",null,'(Note: "hostname" should be replaced with the actual hostname.)',-1),w=a("p",null,'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".',-1),T=a("p",null,"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.",-1),P=a("p",null,[r("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 "),a("code",null,"proxy_ssl_server_name on;"),r(" 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.")],-1),S=a("h2",{id:"idea",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#idea","aria-hidden":"true"},"#"),r(" Idea")],-1),_=a("p",null,[a("img",{src:"/Xray-docs-next/assets/xray-fallbacks.73ad8691.svg",alt:"Xray Fallback Process"})],-1),I=a("p",null,"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.",-1),N=a("h2",{id:"adding-dns-records",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#adding-dns-records","aria-hidden":"true"},"#"),r(" Adding DNS Records")],-1),H=a("p",null,[a("img",{src:"/Xray-docs-next/assets/xray-dns-records.d55b10dd.webp",alt:"DNS Records"})],-1),C=a("p",null,"Please modify the domain name and IP according to the actual situation.",-1),A=a("h2",{id:"applying-for-tls-certificate",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#applying-for-tls-certificate","aria-hidden":"true"},"#"),r(" Applying for TLS Certificate")],-1),L=r("As it is necessary to route traffic to different domain name prefixes, but a wildcard certificate is only valid between two dots (for example, applying for "),j=a("code",null,"*.example.com",-1),F=r(", the certificate cannot be used for "),q=a("code",null,"example.com",-1),X=r(" and "),D=a("code",null,"*.*.example.com",-1),U=r("), it is necessary to apply for a "),W={href:"https://en.wikipedia.org/wiki/Subject_Alternative_Name",target:"_blank",rel:"noopener noreferrer"},E=r("SAN"),R=r(" (Subject Alternative Name) wildcard certificate. According to the information on the Let's Encrypt official website, applying for a wildcard certificate requires DNS-01 verification. Here, we demonstrate how to apply for a free TLS certificate from Let's Encrypt using "),V={href:"https://acme.sh",target:"_blank",rel:"noopener noreferrer"},O=r("acme.sh"),J=r(" for a domain with NS records hosted on Cloudflare. For the application method using other domain name hosting providers, please refer to "),B={href:"https://github.com/acmesh-official/acme.sh/wiki/dnsapi",target:"_blank",rel:"noopener noreferrer"},$=r("dnsapi · acmesh-official/acme.sh Wiki"),z=r("."),G=r("First, you need to go to the "),Q={href:"https://dash.cloudflare.com/profile/api-tokens",target:"_blank",rel:"noopener noreferrer"},K=r("Cloudflare dashboard"),M=r(" to create an API token. The parameters are as follows:"),Y=a("p",null,[a("img",{src:"/Xray-docs-next/assets/cf-api-token-permissions-for-acme.d806d67c.webp",alt:"API Token permission settings"})],-1),Z=a("p",null,"The permission part is crucial, while other parts are optional.",-1),nn=a("p",null,[r("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 "),a("code",null,"CF_Token"),r(" that will be used soon.")],-1),sn=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"Note"),a("p",null,"The following operations need to be performed under the root user. Using sudo will result in errors.")],-1),en=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"curl"),r(" https://get.acme.sh "),a("span",{class:"token operator"},"|"),r(),a("span",{class:"token function"},"sh"),r(),a("span",{class:"token comment"},"# Install acme.sh"),r("\n"),a("span",{class:"token builtin class-name"},"export"),r(),a("span",{class:"token assign-left variable"},"CF_Token"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},'"sdfsdfsdfljlbjkljlkjsdfoiwje"'),r(),a("span",{class:"token comment"},"# Set API Token variable"),r("\nacme.sh --issue -d example.com -d *.example.com --dns dns_cf "),a("span",{class:"token comment"},"# Apply for a certificate using DNS-01 validation method"),r("\n"),a("span",{class:"token function"},"mkdir"),r(" /etc/ssl/xray "),a("span",{class:"token comment"},"# Create a directory to store the certificate"),r("\nacme.sh --install-cert -d example.com --fullchain-file /etc/ssl/xray/cert.pem --key-file /etc/ssl/xray/privkey.key --reloadcmd "),a("span",{class:"token string"},'"chown nobody:nogroup -R /etc/ssl/xray && systemctl restart xray"'),r(),a("span",{class:"token comment"},"# Install the certificate to the specified directory and set the effective command for automatic renewal"),r("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br")])],-1),an=a("h2",{id:"xray-configuration",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#xray-configuration","aria-hidden":"true"},"#"),r(" Xray Configuration")],-1),tn=a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"log"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"loglevel"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"warning"'),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"inbounds"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"443"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"vless"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"clients"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"id"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"UUID"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"flow"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"xtls-rprx-vision"'),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"decryption"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"none"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"fallbacks"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"name"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"example.com"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"path"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"/vmessws"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5000"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5001"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"alpn"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"h2"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5002"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"name"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"blog.example.com"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5003"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"name"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"blog.example.com"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"alpn"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"h2"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5004"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"tcp"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"security"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"tls"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"tlsSettings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"alpn"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),a("span",{class:"token string"},'"h2"'),a("span",{class:"token punctuation"},","),r(),a("span",{class:"token string"},'"http/1.1"'),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"certificates"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"certificateFile"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"/etc/ssl/xray/cert.pem"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"keyFile"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"/etc/ssl/xray/privkey.key"'),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"listen"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"127.0.0.1"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5000"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"vmess"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"clients"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"id"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"UUID"'),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"ws"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"wsSettings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"acceptProxyProtocol"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"path"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"/vmessws"'),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"outbounds"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"freedom"'),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),r("\n"),a("span",{class:"token punctuation"},"}"),r("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br"),a("span",{class:"line-number"},"37"),a("br"),a("span",{class:"line-number"},"38"),a("br"),a("span",{class:"line-number"},"39"),a("br"),a("span",{class:"line-number"},"40"),a("br"),a("span",{class:"line-number"},"41"),a("br"),a("span",{class:"line-number"},"42"),a("br"),a("span",{class:"line-number"},"43"),a("br"),a("span",{class:"line-number"},"44"),a("br"),a("span",{class:"line-number"},"45"),a("br"),a("span",{class:"line-number"},"46"),a("br"),a("span",{class:"line-number"},"47"),a("br"),a("span",{class:"line-number"},"48"),a("br"),a("span",{class:"line-number"},"49"),a("br"),a("span",{class:"line-number"},"50"),a("br"),a("span",{class:"line-number"},"51"),a("br"),a("span",{class:"line-number"},"52"),a("br"),a("span",{class:"line-number"},"53"),a("br"),a("span",{class:"line-number"},"54"),a("br"),a("span",{class:"line-number"},"55"),a("br"),a("span",{class:"line-number"},"56"),a("br"),a("span",{class:"line-number"},"57"),a("br"),a("span",{class:"line-number"},"58"),a("br"),a("span",{class:"line-number"},"59"),a("br"),a("span",{class:"line-number"},"60"),a("br"),a("span",{class:"line-number"},"61"),a("br"),a("span",{class:"line-number"},"62"),a("br"),a("span",{class:"line-number"},"63"),a("br"),a("span",{class:"line-number"},"64"),a("br"),a("span",{class:"line-number"},"65"),a("br"),a("span",{class:"line-number"},"66"),a("br"),a("span",{class:"line-number"},"67"),a("br"),a("span",{class:"line-number"},"68"),a("br"),a("span",{class:"line-number"},"69"),a("br"),a("span",{class:"line-number"},"70"),a("br"),a("span",{class:"line-number"},"71"),a("br"),a("span",{class:"line-number"},"72"),a("br"),a("span",{class:"line-number"},"73"),a("br"),a("span",{class:"line-number"},"74"),a("br"),a("span",{class:"line-number"},"75"),a("br"),a("span",{class:"line-number"},"76"),a("br"),a("span",{class:"line-number"},"77"),a("br"),a("span",{class:"line-number"},"78"),a("br"),a("span",{class:"line-number"},"79"),a("br"),a("span",{class:"line-number"},"80"),a("br"),a("span",{class:"line-number"},"81"),a("br"),a("span",{class:"line-number"},"82"),a("br"),a("span",{class:"line-number"},"83"),a("br"),a("span",{class:"line-number"},"84"),a("br"),a("span",{class:"line-number"},"85"),a("br")])],-1),on=a("p",null,"The above configuration is for Nginx. Here are some details that need to be noted.",-1),rn=a("ul",null,[a("li",null,"About Proxy Protocol")],-1),ln=a("p",null,"Proxy Protocol is a protocol developed by HaProxy to solve the problem of easily losing client information during proxying. It is often used for chain proxying and reverse proxying. The traditional approach to handling this problem is often complex and has many limitations, while Proxy Protocol simply attaches the original connection quadruple information packet to the transmitted data, solving this problem in a very simple way.",-1),cn=a("p",null,"Everything has its advantages and disadvantages, and the same goes for the Proxy Protocol.",-1),pn=a("ul",null,[a("li",null,"If there is sending, there must be receiving, and vice versa."),a("li",null,[r("The same port cannot be compatible with connections that have Proxy Protocol data and those that don't have data (e.g., different virtual hosts (servers) on the same port in Nginx, which is essentially the previous point). "),a("sup",{class:"footnote-ref"},[a("a",{href:"#fn1",id:"fnref1"},"[1]")]),a("sup",{class:"footnote-ref"},[a("a",{href:"#fn2",id:"fnref2"},"[2]")])])],-1),un=a("p",null,"Please consider whether the configuration meets the above conditions when encountering exceptions.",-1),bn=a("p",null,"Here, we use the Proxy Protocol to allow the fallback target to obtain the real IP address of the client.",-1),dn=a("p",null,[r("In addition, when the "),a("code",null,'"acceptProxyProtocol": true'),r(" exists in a certain inbound configuration of Xray, ReadV will be invalidated.")],-1),mn=a("ul",null,[a("li",null,"Regarding HTTP/2")],-1),hn=a("p",null,[r("First, "),a("code",null,"inbounds.streamSettings.tlsSettings.alpn"),r(" has an order. "),a("code",null,"h2"),r(" should be placed before "),a("code",null,"http/1.1"),r(" to prioritize the use of HTTP/2 while ensuring compatibility. Placing them in reverse order will cause HTTP/2 to be negotiated as HTTP/1.1, resulting in an invalid configuration.")],-1),kn=a("p",null,[r("In the above configuration, each "),a("code",null,"fallback"),r(" configuration that falls back to Nginx needs to be divided into two. This is because h2 is an HTTP/2 connection that requires TLS encryption, which is beneficial for the security of data transmission over the Internet, but is unnecessary within the server. On the other hand, h2c is a non-encrypted HTTP/2 connection that is suitable for this environment. However, Nginx cannot listen for HTTP/1.1 and h2c on the same port at the same time. To solve this problem, the "),a("code",null,"alpn"),r(" option (in "),a("code",null,"fallbacks"),r(" rather than "),a("code",null,"tlsSettings"),r(") needs to be specified in the fallback to try to match the TLS ALPN negotiation result.")],-1),fn=a("p",null,[r("Suggestion: Use only two types of fillings for the "),a("code",null,"alpn"),r(" item as needed: "),a("sup",{class:"footnote-ref"},[a("a",{href:"#fn3",id:"fnref3"},"[3]")])],-1),gn=a("ul",null,[a("li",null,"Omitted"),a("li",null,[a("code",null,'"h2"')])],-1),yn=a("p",null,[r("If you use Caddy, you don't need to be so complicated, because "),a("strong",null,"it can"),r(" listen to HTTP/1.1 and h2c on the same port at the same time. The configuration changes are as follows:")],-1),vn=a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"fallbacks"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"name"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"example.com"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"path"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"/vmessws"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5000"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5001"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"name"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"blog.example.com"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5002"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),r("\n"),a("span",{class:"token punctuation"},"}"),r("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br")])],-1),xn=a("p",null,"(Note: This is a JSON code block. It describes fallback configurations for a service.)",-1),wn=a("h2",{id:"nginx-configuration",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#nginx-configuration","aria-hidden":"true"},"#"),r(" Nginx Configuration")],-1),Tn=a("p",null,"Nginx will be installed through official sources.",-1),Pn=a("p",null,"This is a set of Bash commands to install Nginx on Ubuntu.",-1),Sn=a("p",null,"The first command installs the necessary packages for the installation process.",-1),_n=a("p",null,"The second command adds the Nginx repository to the list of sources that Ubuntu uses to find software packages.",-1),In=a("p",null,"The third command downloads the Nginx signing key and adds it to the system's keyring, which verifies the authenticity of the package.",-1),Nn=a("p",null,"The fourth command updates the package list with the newly added Nginx repository.",-1),Hn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"apt"),r(),a("span",{class:"token function"},"install"),r(),a("span",{class:"token function"},"curl"),r(" gnupg2 ca-certificates lsb-release\n"),a("span",{class:"token builtin class-name"},"echo"),r(),a("span",{class:"token string"},[r('"deb [arch=amd64] http://nginx.org/packages/ubuntu '),a("span",{class:"token variable"},[a("span",{class:"token variable"},"`"),r("lsb_release -cs"),a("span",{class:"token variable"},"`")]),r(' nginx"')]),r(),a("span",{class:"token punctuation"},"\\"),r("\n "),a("span",{class:"token operator"},"|"),r(),a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"tee"),r(" /etc/apt/sources.list.d/nginx.list\n"),a("span",{class:"token function"},"curl"),r(" -fsSL https://nginx.org/keys/nginx_signing.key "),a("span",{class:"token operator"},"|"),r(),a("span",{class:"token function"},"sudo"),r(" apt-key "),a("span",{class:"token function"},"add"),r(" -\n"),a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"apt"),r(" update\n"),a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"apt"),r(),a("span",{class:"token function"},"install"),r(" nginx\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br")])],-1),Cn=a("p",null,[r("Delete "),a("code",null,"/etc/nginx/conf.d/default.conf"),r(" and create "),a("code",null,"/etc/nginx/conf.d/fallbacks.conf"),r(" with the following content:")],-1),An=a("div",{class:"language-nginx ext-nginx line-numbers-mode"},[a("pre",{class:"language-nginx"},[a("code",null,[a("span",{class:"token directive"},[a("span",{class:"token keyword"},"set_real_ip_from"),r(" 127.0.0.1")]),a("span",{class:"token punctuation"},";"),r("\n"),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"real_ip_header"),r(" proxy_protocol")]),a("span",{class:"token punctuation"},";"),r("\n\n"),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"server")]),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"listen"),r(" 127.0.0.1:5001 proxy_protocol default_server")]),a("span",{class:"token punctuation"},";"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"listen"),r(" 127.0.0.1:5002 proxy_protocol default_server http2")]),a("span",{class:"token punctuation"},";"),r("\n\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"location"),r(" /")]),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"root"),r(" /srv/http/default")]),a("span",{class:"token punctuation"},";"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n"),a("span",{class:"token punctuation"},"}"),r("\n\n"),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"server")]),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"listen"),r(" 127.0.0.1:5003 proxy_protocol")]),a("span",{class:"token punctuation"},";"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"listen"),r(" 127.0.0.1:5004 proxy_protocol http2")]),a("span",{class:"token punctuation"},";"),r("\n\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"server_name"),r(" blog.example.com")]),a("span",{class:"token punctuation"},";"),r("\n\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"location"),r(" /")]),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"root"),r(" /srv/http/blog.example.com")]),a("span",{class:"token punctuation"},";"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n"),a("span",{class:"token punctuation"},"}"),r("\n\n"),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"server")]),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"listen"),r(),a("span",{class:"token number"},"80")]),a("span",{class:"token punctuation"},";"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"return"),r(),a("span",{class:"token number"},"301"),r(" https://"),a("span",{class:"token variable"},"$host"),a("span",{class:"token variable"},"$request_uri")]),a("span",{class:"token punctuation"},";"),r("\n"),a("span",{class:"token punctuation"},"}"),r("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br")])],-1),Ln=a("h2",{id:"caddy-configuration",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#caddy-configuration","aria-hidden":"true"},"#"),r(" Caddy Configuration")],-1),jn=r("Please refer to "),Fn={href:"https://caddyserver.com/docs/install",target:"_blank",rel:"noopener noreferrer"},qn=r("Install — Caddy Documentation"),Xn=r(" for installing Caddy."),Dn=a("p",null,"To enable Caddy to obtain the real IP address of visitors, it is necessary to compile Caddy with the Proxy Protocol module. It is recommended to compile it directly on the Caddy website.",-1),Un=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"curl"),r(" -o /usr/bin/caddy "),a("span",{class:"token string"},'"https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fmastercactapus%2Fcaddy2-proxyprotocol&idempotency=79074247675458"'),r("\n\n"),a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"chmod"),r(" +x /usr/bin/caddy\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br")])],-1),Wn=a("p",null,"This is a bash script that downloads the Caddy web server and sets the necessary permissions to run it on a Linux system.",-1),En=a("p",null,"Just replace it directly.",-1),Rn=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"Tip"),a("p",null,"It is recommended to install Caddy through the official website documentation first, and then replace the binary file. This way, there is no need to manually set the process management.")],-1),Vn=a("p",null,[r("Edit "),a("code",null,"/etc/caddy/Caddyfile"),r(":")],-1),On=a("p",null,"This is a Caddyfile, which is a configuration file used by the Caddy web server.",-1),Jn=a("p",null,[r("In this specific configuration, there are two servers defined: one listening on "),a("code",null,"127.0.0.1:5001"),r(" and another on "),a("code",null,"127.0.0.1:5002"),r(". Both servers have a "),a("code",null,"listener_wrapper"),r(" defined for "),a("code",null,"proxy_protocol"),r(", which is a protocol used for passing client connection information through a proxy or load balancer. Additionally, both servers have the "),a("code",null,"allow_h2c"),r(" option enabled, which allows clients to connect using HTTP/2 cleartext (h2c) protocol.")],-1),Bn=a("div",{class:"language-Caddyfile ext-Caddyfile line-numbers-mode"},[a("pre",{class:"language-Caddyfile"},[a("code",null,"{\n servers 127.0.0.1:5001 {\n listener_wrappers {\n proxy_protocol\n }\n\tprotocol {\n allow_h2c\n }\n }\n servers 127.0.0.1:5002 {\n listener_wrappers {\n proxy_protocol\n }\n\tprotocol {\n allow_h2c\n }\n }\n}\n\n:5001 {\n root * /srv/http/default\n file_server\n log\n bind 127.0.0.1\n}\n\nhttp://blog.example.com:5002 {\n root * /srv/http/blog.example.com\n file_server\n log\n bind 127.0.0.1\n}\n\n:80 {\n redir https://{host}{uri} permanent\n}\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br")])],-1),$n=a("h2",{id:"reference",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#reference","aria-hidden":"true"},"#"),r(" Reference")],-1),zn={href:"https://en.wikipedia.org/wiki/Server_Name_Indication",target:"_blank",rel:"noopener noreferrer"},Gn=r("Server Name Indication - Wikipedia, the free encyclopedia"),Qn={href:"https://github.com/acmesh-official/acme.sh/wiki",target:"_blank",rel:"noopener noreferrer"},Kn=r("Home · acmesh-official/acme.sh Wiki"),Mn={href:"https://en.wikipedia.org/wiki/HTTP/2",target:"_blank",rel:"noopener noreferrer"},Yn=r("HTTP/2 - Wikipedia, the free encyclopedia"),Zn=a("h2",{id:"quotation",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#quotation","aria-hidden":"true"},"#"),r(" Quotation")],-1),ns=a("hr",{class:"footnotes-sep"},null,-1),ss={class:"footnotes"},es={class:"footnotes-list"},as={id:"fn1",class:"footnote-item"},ts={href:"https://www.haproxy.com/blog/haproxy/proxy-protocol/",target:"_blank",rel:"noopener noreferrer"},os=r("Proxy Protocol - HAProxy Technologies"),rs=r(),ls=a("a",{href:"#fnref1",class:"footnote-backref"},"↩︎",-1),is={id:"fn2",class:"footnote-item"},cs={href:"https://www.jianshu.com/p/cc8d592582c9",target:"_blank",rel:"noopener noreferrer"},ps=r("Introduction to Proxy Protocol and Nginx Configuration - Jianshu"),us=r(),bs=a("a",{href:"#fnref2",class:"footnote-backref"},"↩︎",-1),ds={id:"fn3",class:"footnote-item"},ms={href:"https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md",target:"_blank",rel:"noopener noreferrer"},hs=r("v2fly-github-io/vless.md at master · rprx/v2fly-github-io"),ks=r(),fs=a("a",{href:"#fnref3",class:"footnote-backref"},"↩︎",-1);l.render=function(r,l){const gs=n("OutboundLink");return s(),e(o,null,[i,c,p,u,b,d,m,h,k,f,g,y,v,x,w,T,P,S,_,I,N,H,C,A,a("p",null,[L,j,F,q,X,D,U,a("a",W,[E,t(gs)]),R,a("a",V,[O,t(gs)]),J,a("a",B,[$,t(gs)]),z]),a("p",null,[G,a("a",Q,[K,t(gs)]),M]),Y,Z,nn,sn,en,an,tn,on,rn,ln,cn,pn,un,bn,dn,mn,hn,kn,fn,gn,yn,vn,xn,wn,Tn,Pn,Sn,_n,In,Nn,Hn,Cn,An,Ln,a("p",null,[jn,a("a",Fn,[qn,t(gs)]),Xn]),Dn,Un,Wn,En,Rn,Vn,On,Jn,Bn,$n,a("ol",null,[a("li",null,[a("a",zn,[Gn,t(gs)])]),a("li",null,[a("a",Qn,[Kn,t(gs)])]),a("li",null,[a("a",Mn,[Yn,t(gs)])])]),Zn,ns,a("section",ss,[a("ol",es,[a("li",as,[a("p",null,[a("a",ts,[os,t(gs)]),rs,ls])]),a("li",is,[a("p",null,[a("a",cs,[ps,t(gs)]),us,bs])]),a("li",ds,[a("p",null,[a("a",ms,[hs,t(gs)]),ks,fs])])])])],64)};export default l; +import{r as n,o as s,c as e,a,b as t,F as o,e as r}from"./app.48111a85.js";const l={},i=a("h1",{id:"implementing-camouflage-and-domain-based-routing-through-sni-fallback-function",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#implementing-camouflage-and-domain-based-routing-through-sni-fallback-function","aria-hidden":"true"},"#"),r(" Implementing camouflage and domain-based routing through SNI fallback function")],-1),c=a("p",null,"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.",-1),p=a("h2",{id:"application-scenarios",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#application-scenarios","aria-hidden":"true"},"#"),r(" Application Scenarios")],-1),u=a("p",null,"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:",-1),b=a("ul",null,[a("li",null,"Xray monitors other commonly used ports (such as 22, 3389, 8443).")],-1),d=a("p",null,"This plan is the simplest, but not perfect enough.",-1),m=a("ul",null,[a("li",null,"Nginx or HAProxy listens on port 443, uses SNI for L4 load balancing, and achieves port multiplexing through reverse proxy.")],-1),h=a("p",null,"This plan is relatively complicated and requires some understanding of using Nginx or HAProxy. We will not explain it in too much detail here.",-1),k=a("ul",null,[a("li",null,"Xray listens on port 443, and uses Fallbacks feature to split website traffic based on SNI and fallbacks it to Nginx or Caddy.")],-1),f=a("p",null,"This plan has a moderate level of difficulty and is the scheme that this tutorial will demonstrate next.",-1),g=a("h2",{id:"introduction-to-sni",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#introduction-to-sni","aria-hidden":"true"},"#"),r(" Introduction to SNI")],-1),y=a("p",null,"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:",-1),v=a("div",{class:"language-nginx ext-nginx line-numbers-mode"},[a("pre",{class:"language-nginx"},[a("code",null,[a("span",{class:"token directive"},[a("span",{class:"token keyword"},"proxy_set_header"),r(" Host hostname")]),a("span",{class:"token punctuation"},";"),r("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br")])],-1),x=a("p",null,'(Note: "hostname" should be replaced with the actual hostname.)',-1),w=a("p",null,'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".',-1),T=a("p",null,"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.",-1),P=a("p",null,[r("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 "),a("code",null,"proxy_ssl_server_name on;"),r(" 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.")],-1),S=a("h2",{id:"idea",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#idea","aria-hidden":"true"},"#"),r(" Idea")],-1),_=a("p",null,[a("img",{src:"/Xray-docs-next/assets/xray-fallbacks.73ad8691.svg",alt:"Xray Fallback Process"})],-1),I=a("p",null,"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.",-1),N=a("h2",{id:"adding-dns-records",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#adding-dns-records","aria-hidden":"true"},"#"),r(" Adding DNS Records")],-1),H=a("p",null,[a("img",{src:"/Xray-docs-next/assets/xray-dns-records.d55b10dd.webp",alt:"DNS Records"})],-1),C=a("p",null,"Please modify the domain name and IP according to the actual situation.",-1),A=a("h2",{id:"applying-for-tls-certificate",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#applying-for-tls-certificate","aria-hidden":"true"},"#"),r(" Applying for TLS Certificate")],-1),L=r("As it is necessary to route traffic to different domain name prefixes, but a wildcard certificate is only valid between two dots (for example, applying for "),j=a("code",null,"*.example.com",-1),F=r(", the certificate cannot be used for "),q=a("code",null,"example.com",-1),X=r(" and "),D=a("code",null,"*.*.example.com",-1),U=r("), it is necessary to apply for a "),W={href:"https://en.wikipedia.org/wiki/Subject_Alternative_Name",target:"_blank",rel:"noopener noreferrer"},E=r("SAN"),R=r(" (Subject Alternative Name) wildcard certificate. According to the information on the Let's Encrypt official website, applying for a wildcard certificate requires DNS-01 verification. Here, we demonstrate how to apply for a free TLS certificate from Let's Encrypt using "),V={href:"https://acme.sh",target:"_blank",rel:"noopener noreferrer"},O=r("acme.sh"),J=r(" for a domain with NS records hosted on Cloudflare. For the application method using other domain name hosting providers, please refer to "),B={href:"https://github.com/acmesh-official/acme.sh/wiki/dnsapi",target:"_blank",rel:"noopener noreferrer"},$=r("dnsapi · acmesh-official/acme.sh Wiki"),z=r("."),G=r("First, you need to go to the "),Q={href:"https://dash.cloudflare.com/profile/api-tokens",target:"_blank",rel:"noopener noreferrer"},K=r("Cloudflare dashboard"),M=r(" to create an API token. The parameters are as follows:"),Y=a("p",null,[a("img",{src:"/Xray-docs-next/assets/cf-api-token-permissions-for-acme.d806d67c.webp",alt:"API Token permission settings"})],-1),Z=a("p",null,"The permission part is crucial, while other parts are optional.",-1),nn=a("p",null,[r("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 "),a("code",null,"CF_Token"),r(" that will be used soon.")],-1),sn=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"Note"),a("p",null,"The following operations need to be performed under the root user. Using sudo will result in errors.")],-1),en=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"curl"),r(" https://get.acme.sh "),a("span",{class:"token operator"},"|"),r(),a("span",{class:"token function"},"sh"),r(),a("span",{class:"token comment"},"# Install acme.sh"),r("\n"),a("span",{class:"token builtin class-name"},"export"),r(),a("span",{class:"token assign-left variable"},"CF_Token"),a("span",{class:"token operator"},"="),a("span",{class:"token string"},'"sdfsdfsdfljlbjkljlkjsdfoiwje"'),r(),a("span",{class:"token comment"},"# Set API Token variable"),r("\nacme.sh --issue -d example.com -d *.example.com --dns dns_cf "),a("span",{class:"token comment"},"# Apply for a certificate using DNS-01 validation method"),r("\n"),a("span",{class:"token function"},"mkdir"),r(" /etc/ssl/xray "),a("span",{class:"token comment"},"# Create a directory to store the certificate"),r("\nacme.sh --install-cert -d example.com --fullchain-file /etc/ssl/xray/cert.pem --key-file /etc/ssl/xray/privkey.key --reloadcmd "),a("span",{class:"token string"},'"chown nobody:nogroup -R /etc/ssl/xray && systemctl restart xray"'),r(),a("span",{class:"token comment"},"# Install the certificate to the specified directory and set the effective command for automatic renewal"),r("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br")])],-1),an=a("h2",{id:"xray-configuration",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#xray-configuration","aria-hidden":"true"},"#"),r(" Xray Configuration")],-1),tn=a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"log"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"loglevel"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"warning"'),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"inbounds"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"443"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"vless"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"clients"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"id"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"UUID"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"flow"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"xtls-rprx-vision"'),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"decryption"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"none"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"fallbacks"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"name"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"example.com"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"path"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"/vmessws"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5000"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5001"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"alpn"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"h2"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5002"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"name"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"blog.example.com"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5003"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"name"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"blog.example.com"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"alpn"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"h2"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5004"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"tcp"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"security"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"tls"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"tlsSettings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"alpn"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),a("span",{class:"token string"},'"h2"'),a("span",{class:"token punctuation"},","),r(),a("span",{class:"token string"},'"http/1.1"'),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"certificates"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"certificateFile"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"/etc/ssl/xray/cert.pem"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"keyFile"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"/etc/ssl/xray/privkey.key"'),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"listen"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"127.0.0.1"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5000"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"vmess"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"clients"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"id"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"UUID"'),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"ws"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"wsSettings"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"acceptProxyProtocol"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token boolean"},"true"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"path"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"/vmessws"'),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"outbounds"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"freedom"'),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),r("\n"),a("span",{class:"token punctuation"},"}"),r("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br"),a("span",{class:"line-number"},"37"),a("br"),a("span",{class:"line-number"},"38"),a("br"),a("span",{class:"line-number"},"39"),a("br"),a("span",{class:"line-number"},"40"),a("br"),a("span",{class:"line-number"},"41"),a("br"),a("span",{class:"line-number"},"42"),a("br"),a("span",{class:"line-number"},"43"),a("br"),a("span",{class:"line-number"},"44"),a("br"),a("span",{class:"line-number"},"45"),a("br"),a("span",{class:"line-number"},"46"),a("br"),a("span",{class:"line-number"},"47"),a("br"),a("span",{class:"line-number"},"48"),a("br"),a("span",{class:"line-number"},"49"),a("br"),a("span",{class:"line-number"},"50"),a("br"),a("span",{class:"line-number"},"51"),a("br"),a("span",{class:"line-number"},"52"),a("br"),a("span",{class:"line-number"},"53"),a("br"),a("span",{class:"line-number"},"54"),a("br"),a("span",{class:"line-number"},"55"),a("br"),a("span",{class:"line-number"},"56"),a("br"),a("span",{class:"line-number"},"57"),a("br"),a("span",{class:"line-number"},"58"),a("br"),a("span",{class:"line-number"},"59"),a("br"),a("span",{class:"line-number"},"60"),a("br"),a("span",{class:"line-number"},"61"),a("br"),a("span",{class:"line-number"},"62"),a("br"),a("span",{class:"line-number"},"63"),a("br"),a("span",{class:"line-number"},"64"),a("br"),a("span",{class:"line-number"},"65"),a("br"),a("span",{class:"line-number"},"66"),a("br"),a("span",{class:"line-number"},"67"),a("br"),a("span",{class:"line-number"},"68"),a("br"),a("span",{class:"line-number"},"69"),a("br"),a("span",{class:"line-number"},"70"),a("br"),a("span",{class:"line-number"},"71"),a("br"),a("span",{class:"line-number"},"72"),a("br"),a("span",{class:"line-number"},"73"),a("br"),a("span",{class:"line-number"},"74"),a("br"),a("span",{class:"line-number"},"75"),a("br"),a("span",{class:"line-number"},"76"),a("br"),a("span",{class:"line-number"},"77"),a("br"),a("span",{class:"line-number"},"78"),a("br"),a("span",{class:"line-number"},"79"),a("br"),a("span",{class:"line-number"},"80"),a("br"),a("span",{class:"line-number"},"81"),a("br"),a("span",{class:"line-number"},"82"),a("br"),a("span",{class:"line-number"},"83"),a("br"),a("span",{class:"line-number"},"84"),a("br"),a("span",{class:"line-number"},"85"),a("br")])],-1),on=a("p",null,"The above configuration is for Nginx. Here are some details that need to be noted.",-1),rn=a("ul",null,[a("li",null,"About Proxy Protocol")],-1),ln=a("p",null,"Proxy Protocol is a protocol developed by HaProxy to solve the problem of easily losing client information during proxying. It is often used for chain proxying and reverse proxying. The traditional approach to handling this problem is often complex and has many limitations, while Proxy Protocol simply attaches the original connection quadruple information packet to the transmitted data, solving this problem in a very simple way.",-1),cn=a("p",null,"Everything has its advantages and disadvantages, and the same goes for the Proxy Protocol.",-1),pn=a("ul",null,[a("li",null,"If there is sending, there must be receiving, and vice versa."),a("li",null,[r("The same port cannot be compatible with connections that have Proxy Protocol data and those that don't have data (e.g., different virtual hosts (servers) on the same port in Nginx, which is essentially the previous point). "),a("sup",{class:"footnote-ref"},[a("a",{href:"#fn1",id:"fnref1"},"[1]")]),a("sup",{class:"footnote-ref"},[a("a",{href:"#fn2",id:"fnref2"},"[2]")])])],-1),un=a("p",null,"Please consider whether the configuration meets the above conditions when encountering exceptions.",-1),bn=a("p",null,"Here, we use the Proxy Protocol to allow the fallback target to obtain the real IP address of the client.",-1),dn=a("p",null,[r("In addition, when the "),a("code",null,'"acceptProxyProtocol": true'),r(" exists in a certain inbound configuration of Xray, ReadV will be invalidated.")],-1),mn=a("ul",null,[a("li",null,"Regarding HTTP/2")],-1),hn=a("p",null,[r("First, "),a("code",null,"inbounds.streamSettings.tlsSettings.alpn"),r(" has an order. "),a("code",null,"h2"),r(" should be placed before "),a("code",null,"http/1.1"),r(" to prioritize the use of HTTP/2 while ensuring compatibility. Placing them in reverse order will cause HTTP/2 to be negotiated as HTTP/1.1, resulting in an invalid configuration.")],-1),kn=a("p",null,[r("In the above configuration, each "),a("code",null,"fallback"),r(" configuration that falls back to Nginx needs to be divided into two. This is because h2 is an HTTP/2 connection that requires TLS encryption, which is beneficial for the security of data transmission over the Internet, but is unnecessary within the server. On the other hand, h2c is a non-encrypted HTTP/2 connection that is suitable for this environment. However, Nginx cannot listen for HTTP/1.1 and h2c on the same port at the same time. To solve this problem, the "),a("code",null,"alpn"),r(" option (in "),a("code",null,"fallbacks"),r(" rather than "),a("code",null,"tlsSettings"),r(") needs to be specified in the fallback to try to match the TLS ALPN negotiation result.")],-1),fn=a("p",null,[r("Suggestion: Use only two types of fillings for the "),a("code",null,"alpn"),r(" item as needed: "),a("sup",{class:"footnote-ref"},[a("a",{href:"#fn3",id:"fnref3"},"[3]")])],-1),gn=a("ul",null,[a("li",null,"Omitted"),a("li",null,[a("code",null,'"h2"')])],-1),yn=a("p",null,[r("If you use Caddy, you don't need to be so complicated, because "),a("strong",null,"it can"),r(" listen to HTTP/1.1 and h2c on the same port at the same time. The configuration changes are as follows:")],-1),vn=a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"fallbacks"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token punctuation"},"["),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"name"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"example.com"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"path"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"/vmessws"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5000"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5001"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token property"},'"name"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token string"},'"blog.example.com"'),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"dest"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"5002"),a("span",{class:"token punctuation"},","),r("\n "),a("span",{class:"token property"},'"xver"'),a("span",{class:"token operator"},":"),r(),a("span",{class:"token number"},"1"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n "),a("span",{class:"token punctuation"},"]"),r("\n"),a("span",{class:"token punctuation"},"}"),r("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br")])],-1),xn=a("p",null,"(Note: This is a JSON code block. It describes fallback configurations for a service.)",-1),wn=a("h2",{id:"nginx-configuration",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#nginx-configuration","aria-hidden":"true"},"#"),r(" Nginx Configuration")],-1),Tn=a("p",null,"Nginx will be installed through official sources.",-1),Pn=a("p",null,"This is a set of Bash commands to install Nginx on Ubuntu.",-1),Sn=a("p",null,"The first command installs the necessary packages for the installation process.",-1),_n=a("p",null,"The second command adds the Nginx repository to the list of sources that Ubuntu uses to find software packages.",-1),In=a("p",null,"The third command downloads the Nginx signing key and adds it to the system's keyring, which verifies the authenticity of the package.",-1),Nn=a("p",null,"The fourth command updates the package list with the newly added Nginx repository.",-1),Hn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"apt"),r(),a("span",{class:"token function"},"install"),r(),a("span",{class:"token function"},"curl"),r(" gnupg2 ca-certificates lsb-release\n"),a("span",{class:"token builtin class-name"},"echo"),r(),a("span",{class:"token string"},[r('"deb [arch=amd64] http://nginx.org/packages/ubuntu '),a("span",{class:"token variable"},[a("span",{class:"token variable"},"`"),r("lsb_release -cs"),a("span",{class:"token variable"},"`")]),r(' nginx"')]),r(),a("span",{class:"token punctuation"},"\\"),r("\n "),a("span",{class:"token operator"},"|"),r(),a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"tee"),r(" /etc/apt/sources.list.d/nginx.list\n"),a("span",{class:"token function"},"curl"),r(" -fsSL https://nginx.org/keys/nginx_signing.key "),a("span",{class:"token operator"},"|"),r(),a("span",{class:"token function"},"sudo"),r(" apt-key "),a("span",{class:"token function"},"add"),r(" -\n"),a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"apt"),r(" update\n"),a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"apt"),r(),a("span",{class:"token function"},"install"),r(" nginx\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br")])],-1),Cn=a("p",null,[r("Delete "),a("code",null,"/etc/nginx/conf.d/default.conf"),r(" and create "),a("code",null,"/etc/nginx/conf.d/fallbacks.conf"),r(" with the following content:")],-1),An=a("div",{class:"language-nginx ext-nginx line-numbers-mode"},[a("pre",{class:"language-nginx"},[a("code",null,[a("span",{class:"token directive"},[a("span",{class:"token keyword"},"set_real_ip_from"),r(" 127.0.0.1")]),a("span",{class:"token punctuation"},";"),r("\n"),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"real_ip_header"),r(" proxy_protocol")]),a("span",{class:"token punctuation"},";"),r("\n\n"),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"server")]),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"listen"),r(" 127.0.0.1:5001 proxy_protocol default_server")]),a("span",{class:"token punctuation"},";"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"listen"),r(" 127.0.0.1:5002 proxy_protocol default_server http2")]),a("span",{class:"token punctuation"},";"),r("\n\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"location"),r(" /")]),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"root"),r(" /srv/http/default")]),a("span",{class:"token punctuation"},";"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n"),a("span",{class:"token punctuation"},"}"),r("\n\n"),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"server")]),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"listen"),r(" 127.0.0.1:5003 proxy_protocol")]),a("span",{class:"token punctuation"},";"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"listen"),r(" 127.0.0.1:5004 proxy_protocol http2")]),a("span",{class:"token punctuation"},";"),r("\n\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"server_name"),r(" blog.example.com")]),a("span",{class:"token punctuation"},";"),r("\n\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"location"),r(" /")]),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"root"),r(" /srv/http/blog.example.com")]),a("span",{class:"token punctuation"},";"),r("\n "),a("span",{class:"token punctuation"},"}"),r("\n"),a("span",{class:"token punctuation"},"}"),r("\n\n"),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"server")]),r(),a("span",{class:"token punctuation"},"{"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"listen"),r(),a("span",{class:"token number"},"80")]),a("span",{class:"token punctuation"},";"),r("\n "),a("span",{class:"token directive"},[a("span",{class:"token keyword"},"return"),r(),a("span",{class:"token number"},"301"),r(" https://"),a("span",{class:"token variable"},"$host"),a("span",{class:"token variable"},"$request_uri")]),a("span",{class:"token punctuation"},";"),r("\n"),a("span",{class:"token punctuation"},"}"),r("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br")])],-1),Ln=a("h2",{id:"caddy-configuration",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#caddy-configuration","aria-hidden":"true"},"#"),r(" Caddy Configuration")],-1),jn=r("Please refer to "),Fn={href:"https://caddyserver.com/docs/install",target:"_blank",rel:"noopener noreferrer"},qn=r("Install — Caddy Documentation"),Xn=r(" for installing Caddy."),Dn=a("p",null,"To enable Caddy to obtain the real IP address of visitors, it is necessary to compile Caddy with the Proxy Protocol module. It is recommended to compile it directly on the Caddy website.",-1),Un=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"curl"),r(" -o /usr/bin/caddy "),a("span",{class:"token string"},'"https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fmastercactapus%2Fcaddy2-proxyprotocol&idempotency=79074247675458"'),r("\n\n"),a("span",{class:"token function"},"sudo"),r(),a("span",{class:"token function"},"chmod"),r(" +x /usr/bin/caddy\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br")])],-1),Wn=a("p",null,"This is a bash script that downloads the Caddy web server and sets the necessary permissions to run it on a Linux system.",-1),En=a("p",null,"Just replace it directly.",-1),Rn=a("div",{class:"custom-container tip"},[a("p",{class:"custom-container-title"},"Tip"),a("p",null,"It is recommended to install Caddy through the official website documentation first, and then replace the binary file. This way, there is no need to manually set the process management.")],-1),Vn=a("p",null,[r("Edit "),a("code",null,"/etc/caddy/Caddyfile"),r(":")],-1),On=a("p",null,"This is a Caddyfile, which is a configuration file used by the Caddy web server.",-1),Jn=a("p",null,[r("In this specific configuration, there are two servers defined: one listening on "),a("code",null,"127.0.0.1:5001"),r(" and another on "),a("code",null,"127.0.0.1:5002"),r(". Both servers have a "),a("code",null,"listener_wrapper"),r(" defined for "),a("code",null,"proxy_protocol"),r(", which is a protocol used for passing client connection information through a proxy or load balancer. Additionally, both servers have the "),a("code",null,"allow_h2c"),r(" option enabled, which allows clients to connect using HTTP/2 cleartext (h2c) protocol.")],-1),Bn=a("div",{class:"language-Caddyfile ext-Caddyfile line-numbers-mode"},[a("pre",{class:"language-Caddyfile"},[a("code",null,"{\n servers 127.0.0.1:5001 {\n listener_wrappers {\n proxy_protocol\n }\n\tprotocol {\n allow_h2c\n }\n }\n servers 127.0.0.1:5002 {\n listener_wrappers {\n proxy_protocol\n }\n\tprotocol {\n allow_h2c\n }\n }\n}\n\n:5001 {\n root * /srv/http/default\n file_server\n log\n bind 127.0.0.1\n}\n\nhttp://blog.example.com:5002 {\n root * /srv/http/blog.example.com\n file_server\n log\n bind 127.0.0.1\n}\n\n:80 {\n redir https://{host}{uri} permanent\n}\n")]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br"),a("span",{class:"line-number"},"26"),a("br"),a("span",{class:"line-number"},"27"),a("br"),a("span",{class:"line-number"},"28"),a("br"),a("span",{class:"line-number"},"29"),a("br"),a("span",{class:"line-number"},"30"),a("br"),a("span",{class:"line-number"},"31"),a("br"),a("span",{class:"line-number"},"32"),a("br"),a("span",{class:"line-number"},"33"),a("br"),a("span",{class:"line-number"},"34"),a("br"),a("span",{class:"line-number"},"35"),a("br"),a("span",{class:"line-number"},"36"),a("br")])],-1),$n=a("h2",{id:"reference",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#reference","aria-hidden":"true"},"#"),r(" Reference")],-1),zn={href:"https://en.wikipedia.org/wiki/Server_Name_Indication",target:"_blank",rel:"noopener noreferrer"},Gn=r("Server Name Indication - Wikipedia, the free encyclopedia"),Qn={href:"https://github.com/acmesh-official/acme.sh/wiki",target:"_blank",rel:"noopener noreferrer"},Kn=r("Home · acmesh-official/acme.sh Wiki"),Mn={href:"https://en.wikipedia.org/wiki/HTTP/2",target:"_blank",rel:"noopener noreferrer"},Yn=r("HTTP/2 - Wikipedia, the free encyclopedia"),Zn=a("h2",{id:"quotation",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#quotation","aria-hidden":"true"},"#"),r(" Quotation")],-1),ns=a("hr",{class:"footnotes-sep"},null,-1),ss={class:"footnotes"},es={class:"footnotes-list"},as={id:"fn1",class:"footnote-item"},ts={href:"https://www.haproxy.com/blog/haproxy/proxy-protocol/",target:"_blank",rel:"noopener noreferrer"},os=r("Proxy Protocol - HAProxy Technologies"),rs=r(),ls=a("a",{href:"#fnref1",class:"footnote-backref"},"↩︎",-1),is={id:"fn2",class:"footnote-item"},cs={href:"https://www.jianshu.com/p/cc8d592582c9",target:"_blank",rel:"noopener noreferrer"},ps=r("Introduction to Proxy Protocol and Nginx Configuration - Jianshu"),us=r(),bs=a("a",{href:"#fnref2",class:"footnote-backref"},"↩︎",-1),ds={id:"fn3",class:"footnote-item"},ms={href:"https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md",target:"_blank",rel:"noopener noreferrer"},hs=r("v2fly-github-io/vless.md at master · rprx/v2fly-github-io"),ks=r(),fs=a("a",{href:"#fnref3",class:"footnote-backref"},"↩︎",-1);l.render=function(r,l){const gs=n("OutboundLink");return s(),e(o,null,[i,c,p,u,b,d,m,h,k,f,g,y,v,x,w,T,P,S,_,I,N,H,C,A,a("p",null,[L,j,F,q,X,D,U,a("a",W,[E,t(gs)]),R,a("a",V,[O,t(gs)]),J,a("a",B,[$,t(gs)]),z]),a("p",null,[G,a("a",Q,[K,t(gs)]),M]),Y,Z,nn,sn,en,an,tn,on,rn,ln,cn,pn,un,bn,dn,mn,hn,kn,fn,gn,yn,vn,xn,wn,Tn,Pn,Sn,_n,In,Nn,Hn,Cn,An,Ln,a("p",null,[jn,a("a",Fn,[qn,t(gs)]),Xn]),Dn,Un,Wn,En,Rn,Vn,On,Jn,Bn,$n,a("ol",null,[a("li",null,[a("a",zn,[Gn,t(gs)])]),a("li",null,[a("a",Qn,[Kn,t(gs)])]),a("li",null,[a("a",Mn,[Yn,t(gs)])])]),Zn,ns,a("section",ss,[a("ol",es,[a("li",as,[a("p",null,[a("a",ts,[os,t(gs)]),rs,ls])]),a("li",is,[a("p",null,[a("a",cs,[ps,t(gs)]),us,bs])]),a("li",ds,[a("p",null,[a("a",ms,[hs,t(gs)]),ks,fs])])])])],64)};export default l; diff --git a/assets/fallbacks-with-sni.html.bcd4bfd4.js b/assets/fallbacks-with-sni.html.fc031a4e.js similarity index 99% rename from assets/fallbacks-with-sni.html.bcd4bfd4.js rename to assets/fallbacks-with-sni.html.fc031a4e.js index 2d0c45128..dc5df278a 100644 --- a/assets/fallbacks-with-sni.html.bcd4bfd4.js +++ b/assets/fallbacks-with-sni.html.fc031a4e.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as l,F as t,e as o}from"./app.755d843f.js";const r={},p=e("h1",{id:"通过-sni-回落功能实现伪装与按域名分流",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#通过-sni-回落功能实现伪装与按域名分流","aria-hidden":"true"},"#"),o(" 通过 SNI 回落功能实现伪装与按域名分流")],-1),c=e("p",null,"VLESS 是一种很轻的协议,和 Trojan 一样,不对流量进行复杂的加密和混淆,而是大隐隐于市,通过 TLS 协议加密,混杂在其他 HTTPS 流量中,在墙内外穿进穿出。为了更好的伪装以应对主动探测,Fallbacks 回落功能随 VLESS 同时出现。这篇教程将演示如何使用 Xray 中 VLESS 入站协议的回落功能配合 Nginx 或 Caddy 在保证伪装完全的前提下实现按域名分流。",-1),u=e("h2",{id:"应用情景",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#应用情景","aria-hidden":"true"},"#"),o(" 应用情景")],-1),i=e("p",null,"由于 XTLS,Xray 需要监听 443 端口,这导致如果之前有网站运行在服务器上,那么此时网站无法运行或需要运行在其他端口上,这显然是不合理的。有以下三种方案可以解决这个问题:",-1),b=e("ul",null,[e("li",null,[e("p",null,"Xray 监听其他常用端口(如 22、3389、8443)"),e("p",null,"这个方案是最简单的,但不够完美。")]),e("li",null,[e("p",null,"Nginx 或 HAProxy 监听 443 端口,通过 SNI 分流做 L4 反向代理,实现端口复用"),e("p",null,"这个方案比较复杂,需要对 Nginx 或 HAProxy 的使用有一定了解,此处不作过多解释。")]),e("li",null,[e("p",null,"Xray 监听 443 端口,通过 Fallbacks 功能 SNI 分流将网站流量回落到 Nginx 或 Caddy"),e("p",null,"这个方案难度适中,也是此教程接下来想要演示的方案。")])],-1),k=e("h2",{id:"sni-简介",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#sni-简介","aria-hidden":"true"},"#"),o(" SNI 简介")],-1),m=e("p",null,[o("服务器名称指示(英语:"),e("strong",null,"S"),o("erver "),e("strong",null,"N"),o("ame "),e("strong",null,"I"),o("ndication,缩写:"),e("strong",null,"SNI"),o(")是 TLS 的一个扩展协议。熟悉反向代理的朋友都知道,如果想要通过域名将流量代理到正确的内容上,需要以下配置:")],-1),d=e("div",{class:"language-nginx ext-nginx line-numbers-mode"},[e("pre",{class:"language-nginx"},[e("code",null,[e("span",{class:"token directive"},[e("span",{class:"token keyword"},"proxy_set_header"),o(" Host 主机名")]),e("span",{class:"token punctuation"},";"),o("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])],-1),f=e("p",null,"这句的作用是将名为 “Host” 的 HTTP Header 设定为某个主机名。为什么要这样做?一般而言,一台服务器对应一个 IP,但却运行多个网站,访问者通过域名查询到 IP 以访问服务器,那么问题来了,如何确定访问者想要访问的是哪一个网站?这需要“基于名称的虚拟主机”。",-1),h=e("p",null,"当 Web 服务器收到访问请求后,它会查看请求的主机头,使访问者访问正确的网站。然而当 HTTP 协议被 TLS 协议加密后,这种简单的方法就无法实现了。因为 TLS 握手发生在服务器看到任何 HTTP 头之前,因此,服务器不可能使用 HTTP 主机头中的信息来决定呈现哪个证书,更无法决定访问者的访问目标。",-1),y=e("p",null,[o("SNI 的原理也很简单,它通过让客户端发送主机名作为 TLS 协商的一部分来解决此问题。所以在使用 Nginx 对 HTTPS 协议进行反向代理时,需要在配置中加入 "),e("code",null,"proxy_ssl_server_name on;"),o(",此时 Nginx 会向被代理的服务器发送 SNI 信息,解决了 HTTPS 协议下虚拟主机失效的问题。另外,使用 SNI 时,即使不指定主机头,也可以正确访问网站。")],-1),g=e("h2",{id:"思路",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#思路","aria-hidden":"true"},"#"),o(" 思路")],-1),x=e("p",null,[e("img",{src:"/Xray-docs-next/assets/xray-fallbacks.73ad8691.svg",alt:"Xray 回落流程"})],-1),v=e("p",null,"从 443 端口接收到流量后,Xray 会把 TLS 解密后首包长度 < 18、协议版本无效或身份认证失败的流量通过对 name、path、alpn 的匹配转发到 dest 指定的地址。",-1),T=e("h2",{id:"添加-dns-记录",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#添加-dns-记录","aria-hidden":"true"},"#"),o(" 添加 DNS 记录")],-1),P=e("p",null,[e("img",{src:"/Xray-docs-next/assets/xray-dns-records.d55b10dd.webp",alt:"DNS 记录"})],-1),w=e("p",null,"请按实际情况修改域名和 IP。",-1),S=e("h2",{id:"申请-tls-证书",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#申请-tls-证书","aria-hidden":"true"},"#"),o(" 申请 TLS 证书")],-1),_=o("由于要对不同前缀的域名进行分流,但一个通配符证书的作用域仅限于两“.”之间(例如:申请 "),N=e("code",null,"*.example.com",-1),H=o(","),L=e("code",null,"example.com",-1),C=o(" 和 "),I=e("code",null,"*.*.example.com",-1),E=o(" 并不能使用该证书),故需申请 "),A={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"},j=o("SAN"),X=o(" 通配符证书。根据 Let's Encrypt 官网信息"),D=e("sup",{class:"footnote-ref"},[e("a",{href:"#fn1",id:"fnref1"},"[1]")],-1),F=o(",申请通配符证书要求 DNS-01 验证方式,此处演示 NS 记录为 Cloudflare 的域名通过 "),B={href:"https://acme.sh",target:"_blank",rel:"noopener noreferrer"},z=o("acme.sh"),U=o(" 申请 Let's Encrypt 的免费 TLS 证书。使用其他域名托管商的申请方法请阅读 "),V={href:"https://github.com/acmesh-official/acme.sh/wiki/dnsapi",target:"_blank",rel:"noopener noreferrer"},W=o("dnsapi · acmesh-official/acme.sh Wiki"),q=o("。"),R=o("首先需要到 "),$={href:"https://dash.cloudflare.com/profile/api-tokens",target:"_blank",rel:"noopener noreferrer"},O=o("Cloudflare 面板"),G=o("创建 API Token。参数如下:"),J=e("p",null,[e("img",{src:"/Xray-docs-next/assets/cf-api-token-permissions-for-acme.d806d67c.webp",alt:"API Token 的权限设置"})],-1),K=e("p",null,"权限部分至关重要,其他部分任意。",-1),M=e("p",null,[o("创建完毕后,你会得到一串神秘字符,请将其妥善保管到安全且不会丢失的地方,因为它不再会显示。这串字符就是即将用到的 "),e("code",null,"CF_Token"),o("。")],-1),Q=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,"以下操作需要在 root 用户下进行,使用 sudo 会出现错误。")],-1),Y=e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"curl"),o(" https://get.acme.sh "),e("span",{class:"token operator"},"|"),o(),e("span",{class:"token function"},"sh"),o(),e("span",{class:"token comment"},"# 安装 acme.sh"),o("\n"),e("span",{class:"token builtin class-name"},"export"),o(),e("span",{class:"token assign-left variable"},"CF_Token"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},'"sdfsdfsdfljlbjkljlkjsdfoiwje"'),o(),e("span",{class:"token comment"},"# 设定 API Token 变量"),o("\nacme.sh --issue -d example.com -d *.example.com --dns dns_cf "),e("span",{class:"token comment"},"# 使用 DNS-01 验证方式申请证书"),o("\n"),e("span",{class:"token function"},"mkdir"),o(" /etc/ssl/xray "),e("span",{class:"token comment"},"# 新建证书存放目录"),o("\nacme.sh --install-cert -d example.com --fullchain-file /etc/ssl/xray/cert.pem --key-file /etc/ssl/xray/privkey.key --reloadcmd "),e("span",{class:"token string"},'"chown nobody:nogroup -R /etc/ssl/xray && systemctl restart xray"'),o(),e("span",{class:"token comment"},"# 安装证书到指定目录并设定自动续签生效指令"),o("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br")])],-1),Z=e("h2",{id:"xray-配置",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#xray-配置","aria-hidden":"true"},"#"),o(" Xray 配置")],-1),nn=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"log"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"loglevel"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"warning"'),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"inbounds"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"443"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"vless"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"clients"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"id"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"UUID"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"flow"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"xtls-rprx-vision"'),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"decryption"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"none"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"fallbacks"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"name"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"example.com"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"path"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"/vmessws"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5000"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5001"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"alpn"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"h2"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5002"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"name"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"blog.example.com"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5003"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"name"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"blog.example.com"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"alpn"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"h2"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5004"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"streamSettings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"network"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"tcp"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"security"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"tls"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"tlsSettings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"alpn"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"h2"'),e("span",{class:"token punctuation"},","),o(),e("span",{class:"token string"},'"http/1.1"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"certificates"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"certificateFile"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"/etc/ssl/xray/cert.pem"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"keyFile"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"/etc/ssl/xray/privkey.key"'),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"listen"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"127.0.0.1"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5000"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"vmess"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"clients"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"id"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"UUID"'),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"streamSettings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"network"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"ws"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"wsSettings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"acceptProxyProtocol"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token boolean"},"true"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"path"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"/vmessws"'),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"freedom"'),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),o("\n"),e("span",{class:"token punctuation"},"}"),o("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br"),e("span",{class:"line-number"},"34"),e("br"),e("span",{class:"line-number"},"35"),e("br"),e("span",{class:"line-number"},"36"),e("br"),e("span",{class:"line-number"},"37"),e("br"),e("span",{class:"line-number"},"38"),e("br"),e("span",{class:"line-number"},"39"),e("br"),e("span",{class:"line-number"},"40"),e("br"),e("span",{class:"line-number"},"41"),e("br"),e("span",{class:"line-number"},"42"),e("br"),e("span",{class:"line-number"},"43"),e("br"),e("span",{class:"line-number"},"44"),e("br"),e("span",{class:"line-number"},"45"),e("br"),e("span",{class:"line-number"},"46"),e("br"),e("span",{class:"line-number"},"47"),e("br"),e("span",{class:"line-number"},"48"),e("br"),e("span",{class:"line-number"},"49"),e("br"),e("span",{class:"line-number"},"50"),e("br"),e("span",{class:"line-number"},"51"),e("br"),e("span",{class:"line-number"},"52"),e("br"),e("span",{class:"line-number"},"53"),e("br"),e("span",{class:"line-number"},"54"),e("br"),e("span",{class:"line-number"},"55"),e("br"),e("span",{class:"line-number"},"56"),e("br"),e("span",{class:"line-number"},"57"),e("br"),e("span",{class:"line-number"},"58"),e("br"),e("span",{class:"line-number"},"59"),e("br"),e("span",{class:"line-number"},"60"),e("br"),e("span",{class:"line-number"},"61"),e("br"),e("span",{class:"line-number"},"62"),e("br"),e("span",{class:"line-number"},"63"),e("br"),e("span",{class:"line-number"},"64"),e("br"),e("span",{class:"line-number"},"65"),e("br"),e("span",{class:"line-number"},"66"),e("br"),e("span",{class:"line-number"},"67"),e("br"),e("span",{class:"line-number"},"68"),e("br"),e("span",{class:"line-number"},"69"),e("br"),e("span",{class:"line-number"},"70"),e("br"),e("span",{class:"line-number"},"71"),e("br"),e("span",{class:"line-number"},"72"),e("br"),e("span",{class:"line-number"},"73"),e("br"),e("span",{class:"line-number"},"74"),e("br"),e("span",{class:"line-number"},"75"),e("br"),e("span",{class:"line-number"},"76"),e("br"),e("span",{class:"line-number"},"77"),e("br"),e("span",{class:"line-number"},"78"),e("br"),e("span",{class:"line-number"},"79"),e("br"),e("span",{class:"line-number"},"80"),e("br"),e("span",{class:"line-number"},"81"),e("br"),e("span",{class:"line-number"},"82"),e("br"),e("span",{class:"line-number"},"83"),e("br"),e("span",{class:"line-number"},"84"),e("br"),e("span",{class:"line-number"},"85"),e("br")])],-1),sn=e("p",null,"以上配置针对于 Nginx,以下是需要注意的一些细节。",-1),an=e("ul",null,[e("li",null,[e("p",null,"有关 Proxy Protocol"),e("p",null,"Proxy Protocol 是 HaProxy 开发的一种旨在解决代理时容易丢失客户端信息问题的协议,常用于链式代理和反向代理。传统的处理方法往往较为复杂且有诸多限制,而 Proxy Protocol 非常简单地在传输数据时附带上原始连接四元组信息的数据包,解决了这个问题。"),e("p",null,"凡事皆有利弊,Proxy Protocol 也是如此。"),e("ul",null,[e("li",null,"有发送必须有接收,反之亦然"),e("li",null,[o("同一端口不能既兼容带 Proxy Protocol 数据的连接又兼容不带数据的连接(如:Nginx 同端口的不同虚拟主机(server),本质是上一条)"),e("sup",{class:"footnote-ref"},[e("a",{href:"#fn2",id:"fnref2"},"[2]")]),e("sup",{class:"footnote-ref"},[e("a",{href:"#fn3",id:"fnref3"},"[3]")])])]),e("p",null,"在遇到异常时,请考虑配置是否符合上述条件。"),e("p",null,"此处,我们使用 Proxy Protocol 让被回落到的目标获取到客户端的真实 IP。"),e("p",null,[o("另外,当 Xray 的某个入站配置存在 "),e("code",null,'"acceptProxyProtocol": true'),o(" 时,ReadV 将失效。")])]),e("li",null,[e("p",null,"有关 HTTP/2"),e("p",null,[o("首先,"),e("code",null,"inbounds.streamSettings.tlsSettings.alpn"),o(" 有顺序,应将 "),e("code",null,"h2"),o(" 放前,"),e("code",null,"http/1.1"),o(" 放后,在优先使用 HTTP/2 的同时保证兼容性;反过来会导致 HTTP/2 在协商时变为 HTTP/1.1,成为无效配置。")]),e("p",null,[o("在上述配置中,每条回落到 Nginx 的配置都要分成两个。这是因为 h2 是强制 TLS 加密的 HTTP/2 连接,这有益于数据在互联网中传输的安全,但在服务器内部没有必要;而 h2c 是非加密的 HTTP/2 连接,适合该环境。然而,Nginx 不能在同一端口上同时监听 HTTP/1.1 和 h2c,为了解决这个问题,需要在回落中指定 "),e("code",null,"alpn"),o(" 项(是 "),e("code",null,"fallbacks"),o(" 而不是 "),e("code",null,"tlsSettings"),o(" 里面的),以尝试匹配 TLS ALPN 协商结果。")]),e("p",null,[o("建议 "),e("code",null,"alpn"),o(" 项只按需用两种填法:"),e("sup",{class:"footnote-ref"},[e("a",{href:"#fn4",id:"fnref4"},"[4]")])]),e("ul",null,[e("li",null,"省略"),e("li",null,[e("code",null,'"h2"')])]),e("p",null,[o("如果使用 Caddy 就大可不必如此繁杂了,因为它"),e("strong",null,"可以"),o("在同一端口上同时监听 HTTP/1.1 和 h2c,配置改动如下:")]),e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"fallbacks"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"name"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"example.com"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"path"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"/vmessws"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5000"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5001"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"name"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"blog.example.com"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5002"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),o("\n"),e("span",{class:"token punctuation"},"}"),o("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br")])])])],-1),en=e("h2",{id:"nginx-配置",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#nginx-配置","aria-hidden":"true"},"#"),o(" Nginx 配置")],-1),ln=e("p",null,"Nginx 将通过官方源进行安装。",-1),tn=e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"apt"),o(),e("span",{class:"token function"},"install"),o(),e("span",{class:"token function"},"curl"),o(" gnupg2 ca-certificates lsb-release\n"),e("span",{class:"token builtin class-name"},"echo"),o(),e("span",{class:"token string"},[o('"deb [arch=amd64] http://nginx.org/packages/ubuntu '),e("span",{class:"token variable"},[e("span",{class:"token variable"},"`"),o("lsb_release -cs"),e("span",{class:"token variable"},"`")]),o(' nginx"')]),o(),e("span",{class:"token punctuation"},"\\"),o("\n "),e("span",{class:"token operator"},"|"),o(),e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"tee"),o(" /etc/apt/sources.list.d/nginx.list\n"),e("span",{class:"token function"},"curl"),o(" -fsSL https://nginx.org/keys/nginx_signing.key "),e("span",{class:"token operator"},"|"),o(),e("span",{class:"token function"},"sudo"),o(" apt-key "),e("span",{class:"token function"},"add"),o(" -\n"),e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"apt"),o(" update\n"),e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"apt"),o(),e("span",{class:"token function"},"install"),o(" nginx\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br")])],-1),on=e("p",null,[o("删除 "),e("code",null,"/etc/nginx/conf.d/default.conf"),o(" 并创建 "),e("code",null,"/etc/nginx/conf.d/fallbacks.conf"),o(",内容如下:")],-1),rn=e("div",{class:"language-nginx ext-nginx line-numbers-mode"},[e("pre",{class:"language-nginx"},[e("code",null,[e("span",{class:"token directive"},[e("span",{class:"token keyword"},"set_real_ip_from"),o(" 127.0.0.1")]),e("span",{class:"token punctuation"},";"),o("\n"),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"real_ip_header"),o(" proxy_protocol")]),e("span",{class:"token punctuation"},";"),o("\n\n"),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"server")]),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"listen"),o(" 127.0.0.1:5001 proxy_protocol default_server")]),e("span",{class:"token punctuation"},";"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"listen"),o(" 127.0.0.1:5002 proxy_protocol default_server http2")]),e("span",{class:"token punctuation"},";"),o("\n\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"location"),o(" /")]),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"root"),o(" /srv/http/default")]),e("span",{class:"token punctuation"},";"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n"),e("span",{class:"token punctuation"},"}"),o("\n\n"),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"server")]),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"listen"),o(" 127.0.0.1:5003 proxy_protocol")]),e("span",{class:"token punctuation"},";"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"listen"),o(" 127.0.0.1:5004 proxy_protocol http2")]),e("span",{class:"token punctuation"},";"),o("\n\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"server_name"),o(" blog.example.com")]),e("span",{class:"token punctuation"},";"),o("\n\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"location"),o(" /")]),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"root"),o(" /srv/http/blog.example.com")]),e("span",{class:"token punctuation"},";"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n"),e("span",{class:"token punctuation"},"}"),o("\n\n"),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"server")]),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"listen"),o(),e("span",{class:"token number"},"80")]),e("span",{class:"token punctuation"},";"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"return"),o(),e("span",{class:"token number"},"301"),o(" https://"),e("span",{class:"token variable"},"$host"),e("span",{class:"token variable"},"$request_uri")]),e("span",{class:"token punctuation"},";"),o("\n"),e("span",{class:"token punctuation"},"}"),o("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br")])],-1),pn=e("h2",{id:"caddy-配置",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#caddy-配置","aria-hidden":"true"},"#"),o(" Caddy 配置")],-1),cn=o("安装 Caddy 请参阅 "),un={href:"https://caddyserver.com/docs/install",target:"_blank",rel:"noopener noreferrer"},bn=o("Install — Caddy Documentation"),kn=o("。"),mn=e("p",null,"为了使 Caddy 能获取到访问者的真实 IP,需要编译带有 Proxy Protocol 模块的 Caddy。建议直接在 Caddy 官网上在线编译。",-1),dn=e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"curl"),o(" -o /usr/bin/caddy "),e("span",{class:"token string"},'"https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fmastercactapus%2Fcaddy2-proxyprotocol&idempotency=79074247675458"'),o("\n"),e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"chmod"),o(" +x /usr/bin/caddy\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br")])],-1),fn=e("p",null,"直接替换即可。",-1),hn=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"提示"),e("p",null,"建议先通过官网文档安装 Caddy,再替换二进制文件。这样做无需手动设定进程守护。")],-1),yn=e("p",null,[o("编辑 "),e("code",null,"/etc/caddy/Caddyfile"),o(":")],-1),gn=e("div",{class:"language-Caddyfile ext-Caddyfile line-numbers-mode"},[e("pre",{class:"language-Caddyfile"},[e("code",null,"{\n servers 127.0.0.1:5001 {\n listener_wrappers {\n proxy_protocol\n }\n\tprotocol {\n allow_h2c\n }\n }\n servers 127.0.0.1:5002 {\n listener_wrappers {\n proxy_protocol\n }\n\tprotocol {\n allow_h2c\n }\n }\n}\n\n:5001 {\n root * /srv/http/default\n file_server\n log\n bind 127.0.0.1\n}\n\nhttp://blog.example.com:5002 {\n root * /srv/http/blog.example.com\n file_server\n log\n bind 127.0.0.1\n}\n\n:80 {\n redir https://{host}{uri} permanent\n}\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br"),e("span",{class:"line-number"},"34"),e("br"),e("span",{class:"line-number"},"35"),e("br"),e("span",{class:"line-number"},"36"),e("br")])],-1),xn=e("h2",{id:"参考",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#参考","aria-hidden":"true"},"#"),o(" 参考")],-1),vn={href:"https://zh.wikipedia.org/wiki/%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%90%8D%E7%A7%B0%E6%8C%87%E7%A4%BA",target:"_blank",rel:"noopener noreferrer"},Tn=o("服务器名称指示 - 维基百科,自由的百科全书"),Pn={href:"https://github.com/acmesh-official/acme.sh/wiki",target:"_blank",rel:"noopener noreferrer"},wn=o("Home · acmesh-official/acme.sh Wiki"),Sn={href:"https://zh.wikipedia.org/wiki/HTTP/2",target:"_blank",rel:"noopener noreferrer"},_n=o("HTTP/2 - 维基百科,自由的百科全书"),Nn=e("h2",{id:"引用",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#引用","aria-hidden":"true"},"#"),o(" 引用")],-1),Hn=e("hr",{class:"footnotes-sep"},null,-1),Ln={class:"footnotes"},Cn={class:"footnotes-list"},In={id:"fn1",class:"footnote-item"},En={href:"https://letsencrypt.org/zh-cn/docs/faq/",target:"_blank",rel:"noopener noreferrer"},An=o("常见问题 - Let's Encrypt - 免费的 SSL/TLS 证书"),jn=o(),Xn=e("a",{href:"#fnref1",class:"footnote-backref"},"↩︎",-1),Dn={id:"fn2",class:"footnote-item"},Fn={href:"https://www.haproxy.com/blog/haproxy/proxy-protocol/",target:"_blank",rel:"noopener noreferrer"},Bn=o("Proxy Protocol - HAProxy Technologies"),zn=o(),Un=e("a",{href:"#fnref2",class:"footnote-backref"},"↩︎",-1),Vn={id:"fn3",class:"footnote-item"},Wn={href:"https://www.jianshu.com/p/cc8d592582c9",target:"_blank",rel:"noopener noreferrer"},qn=o("proxy protocol 介绍及 nginx 配置 - 简书"),Rn=o(),$n=e("a",{href:"#fnref3",class:"footnote-backref"},"↩︎",-1),On={id:"fn4",class:"footnote-item"},Gn={href:"https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md",target:"_blank",rel:"noopener noreferrer"},Jn=o("v2fly-github-io/vless.md at master · rprx/v2fly-github-io"),Kn=o(),Mn=e("a",{href:"#fnref4",class:"footnote-backref"},"↩︎",-1);r.render=function(o,r){const Qn=n("OutboundLink");return s(),a(t,null,[p,c,u,i,b,k,m,d,f,h,y,g,x,v,T,P,w,S,e("p",null,[_,N,H,L,C,I,E,e("a",A,[j,l(Qn)]),X,D,F,e("a",B,[z,l(Qn)]),U,e("a",V,[W,l(Qn)]),q]),e("p",null,[R,e("a",$,[O,l(Qn)]),G]),J,K,M,Q,Y,Z,nn,sn,an,en,ln,tn,on,rn,pn,e("p",null,[cn,e("a",un,[bn,l(Qn)]),kn]),mn,dn,fn,hn,yn,gn,xn,e("ol",null,[e("li",null,[e("a",vn,[Tn,l(Qn)])]),e("li",null,[e("a",Pn,[wn,l(Qn)])]),e("li",null,[e("a",Sn,[_n,l(Qn)])])]),Nn,Hn,e("section",Ln,[e("ol",Cn,[e("li",In,[e("p",null,[e("a",En,[An,l(Qn)]),jn,Xn])]),e("li",Dn,[e("p",null,[e("a",Fn,[Bn,l(Qn)]),zn,Un])]),e("li",Vn,[e("p",null,[e("a",Wn,[qn,l(Qn)]),Rn,$n])]),e("li",On,[e("p",null,[e("a",Gn,[Jn,l(Qn)]),Kn,Mn])])])])],64)};export default r; +import{r as n,o as s,c as a,a as e,b as l,F as t,e as o}from"./app.48111a85.js";const r={},p=e("h1",{id:"通过-sni-回落功能实现伪装与按域名分流",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#通过-sni-回落功能实现伪装与按域名分流","aria-hidden":"true"},"#"),o(" 通过 SNI 回落功能实现伪装与按域名分流")],-1),c=e("p",null,"VLESS 是一种很轻的协议,和 Trojan 一样,不对流量进行复杂的加密和混淆,而是大隐隐于市,通过 TLS 协议加密,混杂在其他 HTTPS 流量中,在墙内外穿进穿出。为了更好的伪装以应对主动探测,Fallbacks 回落功能随 VLESS 同时出现。这篇教程将演示如何使用 Xray 中 VLESS 入站协议的回落功能配合 Nginx 或 Caddy 在保证伪装完全的前提下实现按域名分流。",-1),u=e("h2",{id:"应用情景",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#应用情景","aria-hidden":"true"},"#"),o(" 应用情景")],-1),i=e("p",null,"由于 XTLS,Xray 需要监听 443 端口,这导致如果之前有网站运行在服务器上,那么此时网站无法运行或需要运行在其他端口上,这显然是不合理的。有以下三种方案可以解决这个问题:",-1),b=e("ul",null,[e("li",null,[e("p",null,"Xray 监听其他常用端口(如 22、3389、8443)"),e("p",null,"这个方案是最简单的,但不够完美。")]),e("li",null,[e("p",null,"Nginx 或 HAProxy 监听 443 端口,通过 SNI 分流做 L4 反向代理,实现端口复用"),e("p",null,"这个方案比较复杂,需要对 Nginx 或 HAProxy 的使用有一定了解,此处不作过多解释。")]),e("li",null,[e("p",null,"Xray 监听 443 端口,通过 Fallbacks 功能 SNI 分流将网站流量回落到 Nginx 或 Caddy"),e("p",null,"这个方案难度适中,也是此教程接下来想要演示的方案。")])],-1),k=e("h2",{id:"sni-简介",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#sni-简介","aria-hidden":"true"},"#"),o(" SNI 简介")],-1),m=e("p",null,[o("服务器名称指示(英语:"),e("strong",null,"S"),o("erver "),e("strong",null,"N"),o("ame "),e("strong",null,"I"),o("ndication,缩写:"),e("strong",null,"SNI"),o(")是 TLS 的一个扩展协议。熟悉反向代理的朋友都知道,如果想要通过域名将流量代理到正确的内容上,需要以下配置:")],-1),d=e("div",{class:"language-nginx ext-nginx line-numbers-mode"},[e("pre",{class:"language-nginx"},[e("code",null,[e("span",{class:"token directive"},[e("span",{class:"token keyword"},"proxy_set_header"),o(" Host 主机名")]),e("span",{class:"token punctuation"},";"),o("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br")])],-1),f=e("p",null,"这句的作用是将名为 “Host” 的 HTTP Header 设定为某个主机名。为什么要这样做?一般而言,一台服务器对应一个 IP,但却运行多个网站,访问者通过域名查询到 IP 以访问服务器,那么问题来了,如何确定访问者想要访问的是哪一个网站?这需要“基于名称的虚拟主机”。",-1),h=e("p",null,"当 Web 服务器收到访问请求后,它会查看请求的主机头,使访问者访问正确的网站。然而当 HTTP 协议被 TLS 协议加密后,这种简单的方法就无法实现了。因为 TLS 握手发生在服务器看到任何 HTTP 头之前,因此,服务器不可能使用 HTTP 主机头中的信息来决定呈现哪个证书,更无法决定访问者的访问目标。",-1),y=e("p",null,[o("SNI 的原理也很简单,它通过让客户端发送主机名作为 TLS 协商的一部分来解决此问题。所以在使用 Nginx 对 HTTPS 协议进行反向代理时,需要在配置中加入 "),e("code",null,"proxy_ssl_server_name on;"),o(",此时 Nginx 会向被代理的服务器发送 SNI 信息,解决了 HTTPS 协议下虚拟主机失效的问题。另外,使用 SNI 时,即使不指定主机头,也可以正确访问网站。")],-1),g=e("h2",{id:"思路",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#思路","aria-hidden":"true"},"#"),o(" 思路")],-1),x=e("p",null,[e("img",{src:"/Xray-docs-next/assets/xray-fallbacks.73ad8691.svg",alt:"Xray 回落流程"})],-1),v=e("p",null,"从 443 端口接收到流量后,Xray 会把 TLS 解密后首包长度 < 18、协议版本无效或身份认证失败的流量通过对 name、path、alpn 的匹配转发到 dest 指定的地址。",-1),T=e("h2",{id:"添加-dns-记录",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#添加-dns-记录","aria-hidden":"true"},"#"),o(" 添加 DNS 记录")],-1),P=e("p",null,[e("img",{src:"/Xray-docs-next/assets/xray-dns-records.d55b10dd.webp",alt:"DNS 记录"})],-1),w=e("p",null,"请按实际情况修改域名和 IP。",-1),S=e("h2",{id:"申请-tls-证书",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#申请-tls-证书","aria-hidden":"true"},"#"),o(" 申请 TLS 证书")],-1),_=o("由于要对不同前缀的域名进行分流,但一个通配符证书的作用域仅限于两“.”之间(例如:申请 "),N=e("code",null,"*.example.com",-1),H=o(","),L=e("code",null,"example.com",-1),C=o(" 和 "),I=e("code",null,"*.*.example.com",-1),E=o(" 并不能使用该证书),故需申请 "),A={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"},j=o("SAN"),X=o(" 通配符证书。根据 Let's Encrypt 官网信息"),D=e("sup",{class:"footnote-ref"},[e("a",{href:"#fn1",id:"fnref1"},"[1]")],-1),F=o(",申请通配符证书要求 DNS-01 验证方式,此处演示 NS 记录为 Cloudflare 的域名通过 "),B={href:"https://acme.sh",target:"_blank",rel:"noopener noreferrer"},z=o("acme.sh"),U=o(" 申请 Let's Encrypt 的免费 TLS 证书。使用其他域名托管商的申请方法请阅读 "),V={href:"https://github.com/acmesh-official/acme.sh/wiki/dnsapi",target:"_blank",rel:"noopener noreferrer"},W=o("dnsapi · acmesh-official/acme.sh Wiki"),q=o("。"),R=o("首先需要到 "),$={href:"https://dash.cloudflare.com/profile/api-tokens",target:"_blank",rel:"noopener noreferrer"},O=o("Cloudflare 面板"),G=o("创建 API Token。参数如下:"),J=e("p",null,[e("img",{src:"/Xray-docs-next/assets/cf-api-token-permissions-for-acme.d806d67c.webp",alt:"API Token 的权限设置"})],-1),K=e("p",null,"权限部分至关重要,其他部分任意。",-1),M=e("p",null,[o("创建完毕后,你会得到一串神秘字符,请将其妥善保管到安全且不会丢失的地方,因为它不再会显示。这串字符就是即将用到的 "),e("code",null,"CF_Token"),o("。")],-1),Q=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,"以下操作需要在 root 用户下进行,使用 sudo 会出现错误。")],-1),Y=e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"curl"),o(" https://get.acme.sh "),e("span",{class:"token operator"},"|"),o(),e("span",{class:"token function"},"sh"),o(),e("span",{class:"token comment"},"# 安装 acme.sh"),o("\n"),e("span",{class:"token builtin class-name"},"export"),o(),e("span",{class:"token assign-left variable"},"CF_Token"),e("span",{class:"token operator"},"="),e("span",{class:"token string"},'"sdfsdfsdfljlbjkljlkjsdfoiwje"'),o(),e("span",{class:"token comment"},"# 设定 API Token 变量"),o("\nacme.sh --issue -d example.com -d *.example.com --dns dns_cf "),e("span",{class:"token comment"},"# 使用 DNS-01 验证方式申请证书"),o("\n"),e("span",{class:"token function"},"mkdir"),o(" /etc/ssl/xray "),e("span",{class:"token comment"},"# 新建证书存放目录"),o("\nacme.sh --install-cert -d example.com --fullchain-file /etc/ssl/xray/cert.pem --key-file /etc/ssl/xray/privkey.key --reloadcmd "),e("span",{class:"token string"},'"chown nobody:nogroup -R /etc/ssl/xray && systemctl restart xray"'),o(),e("span",{class:"token comment"},"# 安装证书到指定目录并设定自动续签生效指令"),o("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br")])],-1),Z=e("h2",{id:"xray-配置",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#xray-配置","aria-hidden":"true"},"#"),o(" Xray 配置")],-1),nn=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"log"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"loglevel"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"warning"'),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"inbounds"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"443"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"vless"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"clients"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"id"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"UUID"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"flow"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"xtls-rprx-vision"'),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"decryption"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"none"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"fallbacks"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"name"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"example.com"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"path"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"/vmessws"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5000"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5001"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"alpn"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"h2"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5002"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"name"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"blog.example.com"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5003"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"name"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"blog.example.com"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"alpn"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"h2"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5004"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"streamSettings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"network"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"tcp"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"security"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"tls"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"tlsSettings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"alpn"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"h2"'),e("span",{class:"token punctuation"},","),o(),e("span",{class:"token string"},'"http/1.1"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"certificates"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"certificateFile"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"/etc/ssl/xray/cert.pem"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"keyFile"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"/etc/ssl/xray/privkey.key"'),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"listen"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"127.0.0.1"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5000"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"vmess"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"clients"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"id"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"UUID"'),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"streamSettings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"network"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"ws"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"wsSettings"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"acceptProxyProtocol"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token boolean"},"true"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"path"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"/vmessws"'),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"freedom"'),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),o("\n"),e("span",{class:"token punctuation"},"}"),o("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br"),e("span",{class:"line-number"},"34"),e("br"),e("span",{class:"line-number"},"35"),e("br"),e("span",{class:"line-number"},"36"),e("br"),e("span",{class:"line-number"},"37"),e("br"),e("span",{class:"line-number"},"38"),e("br"),e("span",{class:"line-number"},"39"),e("br"),e("span",{class:"line-number"},"40"),e("br"),e("span",{class:"line-number"},"41"),e("br"),e("span",{class:"line-number"},"42"),e("br"),e("span",{class:"line-number"},"43"),e("br"),e("span",{class:"line-number"},"44"),e("br"),e("span",{class:"line-number"},"45"),e("br"),e("span",{class:"line-number"},"46"),e("br"),e("span",{class:"line-number"},"47"),e("br"),e("span",{class:"line-number"},"48"),e("br"),e("span",{class:"line-number"},"49"),e("br"),e("span",{class:"line-number"},"50"),e("br"),e("span",{class:"line-number"},"51"),e("br"),e("span",{class:"line-number"},"52"),e("br"),e("span",{class:"line-number"},"53"),e("br"),e("span",{class:"line-number"},"54"),e("br"),e("span",{class:"line-number"},"55"),e("br"),e("span",{class:"line-number"},"56"),e("br"),e("span",{class:"line-number"},"57"),e("br"),e("span",{class:"line-number"},"58"),e("br"),e("span",{class:"line-number"},"59"),e("br"),e("span",{class:"line-number"},"60"),e("br"),e("span",{class:"line-number"},"61"),e("br"),e("span",{class:"line-number"},"62"),e("br"),e("span",{class:"line-number"},"63"),e("br"),e("span",{class:"line-number"},"64"),e("br"),e("span",{class:"line-number"},"65"),e("br"),e("span",{class:"line-number"},"66"),e("br"),e("span",{class:"line-number"},"67"),e("br"),e("span",{class:"line-number"},"68"),e("br"),e("span",{class:"line-number"},"69"),e("br"),e("span",{class:"line-number"},"70"),e("br"),e("span",{class:"line-number"},"71"),e("br"),e("span",{class:"line-number"},"72"),e("br"),e("span",{class:"line-number"},"73"),e("br"),e("span",{class:"line-number"},"74"),e("br"),e("span",{class:"line-number"},"75"),e("br"),e("span",{class:"line-number"},"76"),e("br"),e("span",{class:"line-number"},"77"),e("br"),e("span",{class:"line-number"},"78"),e("br"),e("span",{class:"line-number"},"79"),e("br"),e("span",{class:"line-number"},"80"),e("br"),e("span",{class:"line-number"},"81"),e("br"),e("span",{class:"line-number"},"82"),e("br"),e("span",{class:"line-number"},"83"),e("br"),e("span",{class:"line-number"},"84"),e("br"),e("span",{class:"line-number"},"85"),e("br")])],-1),sn=e("p",null,"以上配置针对于 Nginx,以下是需要注意的一些细节。",-1),an=e("ul",null,[e("li",null,[e("p",null,"有关 Proxy Protocol"),e("p",null,"Proxy Protocol 是 HaProxy 开发的一种旨在解决代理时容易丢失客户端信息问题的协议,常用于链式代理和反向代理。传统的处理方法往往较为复杂且有诸多限制,而 Proxy Protocol 非常简单地在传输数据时附带上原始连接四元组信息的数据包,解决了这个问题。"),e("p",null,"凡事皆有利弊,Proxy Protocol 也是如此。"),e("ul",null,[e("li",null,"有发送必须有接收,反之亦然"),e("li",null,[o("同一端口不能既兼容带 Proxy Protocol 数据的连接又兼容不带数据的连接(如:Nginx 同端口的不同虚拟主机(server),本质是上一条)"),e("sup",{class:"footnote-ref"},[e("a",{href:"#fn2",id:"fnref2"},"[2]")]),e("sup",{class:"footnote-ref"},[e("a",{href:"#fn3",id:"fnref3"},"[3]")])])]),e("p",null,"在遇到异常时,请考虑配置是否符合上述条件。"),e("p",null,"此处,我们使用 Proxy Protocol 让被回落到的目标获取到客户端的真实 IP。"),e("p",null,[o("另外,当 Xray 的某个入站配置存在 "),e("code",null,'"acceptProxyProtocol": true'),o(" 时,ReadV 将失效。")])]),e("li",null,[e("p",null,"有关 HTTP/2"),e("p",null,[o("首先,"),e("code",null,"inbounds.streamSettings.tlsSettings.alpn"),o(" 有顺序,应将 "),e("code",null,"h2"),o(" 放前,"),e("code",null,"http/1.1"),o(" 放后,在优先使用 HTTP/2 的同时保证兼容性;反过来会导致 HTTP/2 在协商时变为 HTTP/1.1,成为无效配置。")]),e("p",null,[o("在上述配置中,每条回落到 Nginx 的配置都要分成两个。这是因为 h2 是强制 TLS 加密的 HTTP/2 连接,这有益于数据在互联网中传输的安全,但在服务器内部没有必要;而 h2c 是非加密的 HTTP/2 连接,适合该环境。然而,Nginx 不能在同一端口上同时监听 HTTP/1.1 和 h2c,为了解决这个问题,需要在回落中指定 "),e("code",null,"alpn"),o(" 项(是 "),e("code",null,"fallbacks"),o(" 而不是 "),e("code",null,"tlsSettings"),o(" 里面的),以尝试匹配 TLS ALPN 协商结果。")]),e("p",null,[o("建议 "),e("code",null,"alpn"),o(" 项只按需用两种填法:"),e("sup",{class:"footnote-ref"},[e("a",{href:"#fn4",id:"fnref4"},"[4]")])]),e("ul",null,[e("li",null,"省略"),e("li",null,[e("code",null,'"h2"')])]),e("p",null,[o("如果使用 Caddy 就大可不必如此繁杂了,因为它"),e("strong",null,"可以"),o("在同一端口上同时监听 HTTP/1.1 和 h2c,配置改动如下:")]),e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"fallbacks"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token punctuation"},"["),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"name"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"example.com"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"path"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"/vmessws"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5000"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5001"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token property"},'"name"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token string"},'"blog.example.com"'),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"dest"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"5002"),e("span",{class:"token punctuation"},","),o("\n "),e("span",{class:"token property"},'"xver"'),e("span",{class:"token operator"},":"),o(),e("span",{class:"token number"},"1"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n "),e("span",{class:"token punctuation"},"]"),o("\n"),e("span",{class:"token punctuation"},"}"),o("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br")])])])],-1),en=e("h2",{id:"nginx-配置",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#nginx-配置","aria-hidden":"true"},"#"),o(" Nginx 配置")],-1),ln=e("p",null,"Nginx 将通过官方源进行安装。",-1),tn=e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"apt"),o(),e("span",{class:"token function"},"install"),o(),e("span",{class:"token function"},"curl"),o(" gnupg2 ca-certificates lsb-release\n"),e("span",{class:"token builtin class-name"},"echo"),o(),e("span",{class:"token string"},[o('"deb [arch=amd64] http://nginx.org/packages/ubuntu '),e("span",{class:"token variable"},[e("span",{class:"token variable"},"`"),o("lsb_release -cs"),e("span",{class:"token variable"},"`")]),o(' nginx"')]),o(),e("span",{class:"token punctuation"},"\\"),o("\n "),e("span",{class:"token operator"},"|"),o(),e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"tee"),o(" /etc/apt/sources.list.d/nginx.list\n"),e("span",{class:"token function"},"curl"),o(" -fsSL https://nginx.org/keys/nginx_signing.key "),e("span",{class:"token operator"},"|"),o(),e("span",{class:"token function"},"sudo"),o(" apt-key "),e("span",{class:"token function"},"add"),o(" -\n"),e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"apt"),o(" update\n"),e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"apt"),o(),e("span",{class:"token function"},"install"),o(" nginx\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br")])],-1),on=e("p",null,[o("删除 "),e("code",null,"/etc/nginx/conf.d/default.conf"),o(" 并创建 "),e("code",null,"/etc/nginx/conf.d/fallbacks.conf"),o(",内容如下:")],-1),rn=e("div",{class:"language-nginx ext-nginx line-numbers-mode"},[e("pre",{class:"language-nginx"},[e("code",null,[e("span",{class:"token directive"},[e("span",{class:"token keyword"},"set_real_ip_from"),o(" 127.0.0.1")]),e("span",{class:"token punctuation"},";"),o("\n"),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"real_ip_header"),o(" proxy_protocol")]),e("span",{class:"token punctuation"},";"),o("\n\n"),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"server")]),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"listen"),o(" 127.0.0.1:5001 proxy_protocol default_server")]),e("span",{class:"token punctuation"},";"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"listen"),o(" 127.0.0.1:5002 proxy_protocol default_server http2")]),e("span",{class:"token punctuation"},";"),o("\n\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"location"),o(" /")]),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"root"),o(" /srv/http/default")]),e("span",{class:"token punctuation"},";"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n"),e("span",{class:"token punctuation"},"}"),o("\n\n"),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"server")]),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"listen"),o(" 127.0.0.1:5003 proxy_protocol")]),e("span",{class:"token punctuation"},";"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"listen"),o(" 127.0.0.1:5004 proxy_protocol http2")]),e("span",{class:"token punctuation"},";"),o("\n\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"server_name"),o(" blog.example.com")]),e("span",{class:"token punctuation"},";"),o("\n\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"location"),o(" /")]),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"root"),o(" /srv/http/blog.example.com")]),e("span",{class:"token punctuation"},";"),o("\n "),e("span",{class:"token punctuation"},"}"),o("\n"),e("span",{class:"token punctuation"},"}"),o("\n\n"),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"server")]),o(),e("span",{class:"token punctuation"},"{"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"listen"),o(),e("span",{class:"token number"},"80")]),e("span",{class:"token punctuation"},";"),o("\n "),e("span",{class:"token directive"},[e("span",{class:"token keyword"},"return"),o(),e("span",{class:"token number"},"301"),o(" https://"),e("span",{class:"token variable"},"$host"),e("span",{class:"token variable"},"$request_uri")]),e("span",{class:"token punctuation"},";"),o("\n"),e("span",{class:"token punctuation"},"}"),o("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br")])],-1),pn=e("h2",{id:"caddy-配置",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#caddy-配置","aria-hidden":"true"},"#"),o(" Caddy 配置")],-1),cn=o("安装 Caddy 请参阅 "),un={href:"https://caddyserver.com/docs/install",target:"_blank",rel:"noopener noreferrer"},bn=o("Install — Caddy Documentation"),kn=o("。"),mn=e("p",null,"为了使 Caddy 能获取到访问者的真实 IP,需要编译带有 Proxy Protocol 模块的 Caddy。建议直接在 Caddy 官网上在线编译。",-1),dn=e("div",{class:"language-bash ext-sh line-numbers-mode"},[e("pre",{class:"language-bash"},[e("code",null,[e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"curl"),o(" -o /usr/bin/caddy "),e("span",{class:"token string"},'"https://caddyserver.com/api/download?os=linux&arch=amd64&p=github.com%2Fmastercactapus%2Fcaddy2-proxyprotocol&idempotency=79074247675458"'),o("\n"),e("span",{class:"token function"},"sudo"),o(),e("span",{class:"token function"},"chmod"),o(" +x /usr/bin/caddy\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br")])],-1),fn=e("p",null,"直接替换即可。",-1),hn=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"提示"),e("p",null,"建议先通过官网文档安装 Caddy,再替换二进制文件。这样做无需手动设定进程守护。")],-1),yn=e("p",null,[o("编辑 "),e("code",null,"/etc/caddy/Caddyfile"),o(":")],-1),gn=e("div",{class:"language-Caddyfile ext-Caddyfile line-numbers-mode"},[e("pre",{class:"language-Caddyfile"},[e("code",null,"{\n servers 127.0.0.1:5001 {\n listener_wrappers {\n proxy_protocol\n }\n\tprotocol {\n allow_h2c\n }\n }\n servers 127.0.0.1:5002 {\n listener_wrappers {\n proxy_protocol\n }\n\tprotocol {\n allow_h2c\n }\n }\n}\n\n:5001 {\n root * /srv/http/default\n file_server\n log\n bind 127.0.0.1\n}\n\nhttp://blog.example.com:5002 {\n root * /srv/http/blog.example.com\n file_server\n log\n bind 127.0.0.1\n}\n\n:80 {\n redir https://{host}{uri} permanent\n}\n")]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br"),e("span",{class:"line-number"},"34"),e("br"),e("span",{class:"line-number"},"35"),e("br"),e("span",{class:"line-number"},"36"),e("br")])],-1),xn=e("h2",{id:"参考",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#参考","aria-hidden":"true"},"#"),o(" 参考")],-1),vn={href:"https://zh.wikipedia.org/wiki/%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%90%8D%E7%A7%B0%E6%8C%87%E7%A4%BA",target:"_blank",rel:"noopener noreferrer"},Tn=o("服务器名称指示 - 维基百科,自由的百科全书"),Pn={href:"https://github.com/acmesh-official/acme.sh/wiki",target:"_blank",rel:"noopener noreferrer"},wn=o("Home · acmesh-official/acme.sh Wiki"),Sn={href:"https://zh.wikipedia.org/wiki/HTTP/2",target:"_blank",rel:"noopener noreferrer"},_n=o("HTTP/2 - 维基百科,自由的百科全书"),Nn=e("h2",{id:"引用",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#引用","aria-hidden":"true"},"#"),o(" 引用")],-1),Hn=e("hr",{class:"footnotes-sep"},null,-1),Ln={class:"footnotes"},Cn={class:"footnotes-list"},In={id:"fn1",class:"footnote-item"},En={href:"https://letsencrypt.org/zh-cn/docs/faq/",target:"_blank",rel:"noopener noreferrer"},An=o("常见问题 - Let's Encrypt - 免费的 SSL/TLS 证书"),jn=o(),Xn=e("a",{href:"#fnref1",class:"footnote-backref"},"↩︎",-1),Dn={id:"fn2",class:"footnote-item"},Fn={href:"https://www.haproxy.com/blog/haproxy/proxy-protocol/",target:"_blank",rel:"noopener noreferrer"},Bn=o("Proxy Protocol - HAProxy Technologies"),zn=o(),Un=e("a",{href:"#fnref2",class:"footnote-backref"},"↩︎",-1),Vn={id:"fn3",class:"footnote-item"},Wn={href:"https://www.jianshu.com/p/cc8d592582c9",target:"_blank",rel:"noopener noreferrer"},qn=o("proxy protocol 介绍及 nginx 配置 - 简书"),Rn=o(),$n=e("a",{href:"#fnref3",class:"footnote-backref"},"↩︎",-1),On={id:"fn4",class:"footnote-item"},Gn={href:"https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md",target:"_blank",rel:"noopener noreferrer"},Jn=o("v2fly-github-io/vless.md at master · rprx/v2fly-github-io"),Kn=o(),Mn=e("a",{href:"#fnref4",class:"footnote-backref"},"↩︎",-1);r.render=function(o,r){const Qn=n("OutboundLink");return s(),a(t,null,[p,c,u,i,b,k,m,d,f,h,y,g,x,v,T,P,w,S,e("p",null,[_,N,H,L,C,I,E,e("a",A,[j,l(Qn)]),X,D,F,e("a",B,[z,l(Qn)]),U,e("a",V,[W,l(Qn)]),q]),e("p",null,[R,e("a",$,[O,l(Qn)]),G]),J,K,M,Q,Y,Z,nn,sn,an,en,ln,tn,on,rn,pn,e("p",null,[cn,e("a",un,[bn,l(Qn)]),kn]),mn,dn,fn,hn,yn,gn,xn,e("ol",null,[e("li",null,[e("a",vn,[Tn,l(Qn)])]),e("li",null,[e("a",Pn,[wn,l(Qn)])]),e("li",null,[e("a",Sn,[_n,l(Qn)])])]),Nn,Hn,e("section",Ln,[e("ol",Cn,[e("li",In,[e("p",null,[e("a",En,[An,l(Qn)]),jn,Xn])]),e("li",Dn,[e("p",null,[e("a",Fn,[Bn,l(Qn)]),zn,Un])]),e("li",Vn,[e("p",null,[e("a",Wn,[qn,l(Qn)]),Rn,$n])]),e("li",On,[e("p",null,[e("a",Gn,[Jn,l(Qn)]),Kn,Mn])])])])],64)};export default r; diff --git a/assets/flowDb-a707052f.485b60ac.js b/assets/flowDb-a707052f.baad4ae4.js similarity index 99% rename from assets/flowDb-a707052f.485b60ac.js rename to assets/flowDb-a707052f.baad4ae4.js index 2c1f9d754..cd31cfeb3 100644 --- a/assets/flowDb-a707052f.485b60ac.js +++ b/assets/flowDb-a707052f.baad4ae4.js @@ -1 +1 @@ -import{c as t,u as e,s,g as u,a as i,b as r,v as n,x as a,m as c,j as o,l,y as h,z as A,h as d}from"./mermaid.core.a66200b0.js";var p=function(){var t=function(t,e,s,u){for(s=s||{},u=t.length;u--;s[t[u]]=e);return s},e=[1,9],s=[1,7],u=[1,6],i=[1,8],r=[1,20,21,22,23,38,44,46,48,52,66,67,87,88,89,90,91,92,96,106,107,110,112,113,119,120,121,122,123,124,125,126,127,128],n=[2,10],a=[1,20],c=[1,21],o=[1,22],l=[1,23],h=[1,30],A=[1,32],d=[1,33],p=[1,34],y=[1,62],E=[1,48],f=[1,52],k=[1,36],D=[1,37],b=[1,38],g=[1,39],_=[1,40],F=[1,56],C=[1,63],B=[1,51],T=[1,53],m=[1,55],S=[1,59],v=[1,60],x=[1,41],L=[1,42],R=[1,43],I=[1,44],$=[1,61],N=[1,50],O=[1,54],P=[1,57],U=[1,58],w=[1,49],V=[1,66],M=[1,71],G=[1,20,21,22,23,38,42,44,46,48,52,66,67,87,88,89,90,91,92,96,106,107,110,112,113,119,120,121,122,123,124,125,126,127,128],K=[1,75],j=[1,74],W=[1,76],Y=[20,21,23,81,82],H=[1,99],z=[1,104],Q=[1,107],X=[1,108],q=[1,101],Z=[1,106],J=[1,109],tt=[1,102],et=[1,114],st=[1,113],ut=[1,103],it=[1,105],rt=[1,110],nt=[1,111],at=[1,112],ct=[1,115],ot=[20,21,22,23,81,82],lt=[20,21,22,23,53,81,82],ht=[20,21,22,23,40,52,53,55,57,59,61,63,65,66,67,69,71,73,74,76,81,82,92,96,106,107,110,112,113,123,124,125,126,127,128],At=[20,21,23],dt=[20,21,23,52,66,67,81,82,92,96,106,107,110,112,113,123,124,125,126,127,128],pt=[1,12,20,21,22,23,24,38,42,44,46,48,52,66,67,87,88,89,90,91,92,96,106,107,110,112,113,119,120,121,122,123,124,125,126,127,128],yt=[52,66,67,92,96,106,107,110,112,113,123,124,125,126,127,128],Et=[1,150],ft=[1,158],kt=[1,159],Dt=[1,160],bt=[1,161],gt=[1,145],_t=[1,146],Ft=[1,141],Ct=[1,142],Bt=[1,153],Tt=[1,154],mt=[1,155],St=[1,156],vt=[1,157],xt=[1,162],Lt=[1,163],Rt=[1,148],It=[1,151],$t=[1,147],Nt=[1,144],Ot=[20,21,22,23,38,42,44,46,48,52,66,67,87,88,89,90,91,92,96,106,107,110,112,113,119,120,121,122,123,124,125,126,127,128],Pt=[1,166],Ut=[20,21,22,23,26,52,66,67,92,106,107,110,112,113,123,124,125,126,127,128],wt=[20,21,22,23,24,26,38,40,41,42,52,56,58,60,62,64,66,67,68,70,72,73,75,77,81,82,87,88,89,90,91,92,93,96,106,107,110,112,113,114,115,123,124,125,126,127,128],Vt=[12,21,22,24],Mt=[22,107],Gt=[1,251],Kt=[1,246],jt=[1,247],Wt=[1,255],Yt=[1,252],Ht=[1,249],zt=[1,248],Qt=[1,250],Xt=[1,253],qt=[1,254],Zt=[1,256],Jt=[1,274],te=[20,21,23,107],ee=[20,21,22,23,66,67,87,103,106,107,110,111,112,113,114],se={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,directive:5,openDirective:6,typeDirective:7,closeDirective:8,separator:9,":":10,argDirective:11,open_directive:12,type_directive:13,arg_directive:14,close_directive:15,graphConfig:16,document:17,line:18,statement:19,SEMI:20,NEWLINE:21,SPACE:22,EOF:23,GRAPH:24,NODIR:25,DIR:26,FirstStmtSeperator:27,ending:28,endToken:29,spaceList:30,spaceListNewline:31,verticeStatement:32,styleStatement:33,linkStyleStatement:34,classDefStatement:35,classStatement:36,clickStatement:37,subgraph:38,text:39,SQS:40,SQE:41,end:42,direction:43,acc_title:44,acc_title_value:45,acc_descr:46,acc_descr_value:47,acc_descr_multiline_value:48,link:49,node:50,vertex:51,AMP:52,STYLE_SEPARATOR:53,idString:54,DOUBLECIRCLESTART:55,DOUBLECIRCLEEND:56,PS:57,PE:58,"(-":59,"-)":60,STADIUMSTART:61,STADIUMEND:62,SUBROUTINESTART:63,SUBROUTINEEND:64,VERTEX_WITH_PROPS_START:65,ALPHA:66,COLON:67,PIPE:68,CYLINDERSTART:69,CYLINDEREND:70,DIAMOND_START:71,DIAMOND_STOP:72,TAGEND:73,TRAPSTART:74,TRAPEND:75,INVTRAPSTART:76,INVTRAPEND:77,linkStatement:78,arrowText:79,TESTSTR:80,START_LINK:81,LINK:82,textToken:83,STR:84,MD_STR:85,keywords:86,STYLE:87,LINKSTYLE:88,CLASSDEF:89,CLASS:90,CLICK:91,DOWN:92,UP:93,textNoTags:94,textNoTagsToken:95,DEFAULT:96,stylesOpt:97,alphaNum:98,CALLBACKNAME:99,CALLBACKARGS:100,HREF:101,LINK_TARGET:102,HEX:103,numList:104,INTERPOLATE:105,NUM:106,COMMA:107,style:108,styleComponent:109,MINUS:110,UNIT:111,BRKT:112,DOT:113,PCT:114,TAGSTART:115,alphaNumToken:116,idStringToken:117,alphaNumStatement:118,direction_tb:119,direction_bt:120,direction_rl:121,direction_lr:122,PUNCTUATION:123,UNICODE_TEXT:124,PLUS:125,EQUALS:126,MULT:127,UNDERSCORE:128,graphCodeTokens:129,ARROW_CROSS:130,ARROW_POINT:131,ARROW_CIRCLE:132,ARROW_OPEN:133,QUOTE:134,$accept:0,$end:1},terminals_:{2:"error",10:":",12:"open_directive",13:"type_directive",14:"arg_directive",15:"close_directive",20:"SEMI",21:"NEWLINE",22:"SPACE",23:"EOF",24:"GRAPH",25:"NODIR",26:"DIR",38:"subgraph",40:"SQS",41:"SQE",42:"end",44:"acc_title",45:"acc_title_value",46:"acc_descr",47:"acc_descr_value",48:"acc_descr_multiline_value",52:"AMP",53:"STYLE_SEPARATOR",55:"DOUBLECIRCLESTART",56:"DOUBLECIRCLEEND",57:"PS",58:"PE",59:"(-",60:"-)",61:"STADIUMSTART",62:"STADIUMEND",63:"SUBROUTINESTART",64:"SUBROUTINEEND",65:"VERTEX_WITH_PROPS_START",66:"ALPHA",67:"COLON",68:"PIPE",69:"CYLINDERSTART",70:"CYLINDEREND",71:"DIAMOND_START",72:"DIAMOND_STOP",73:"TAGEND",74:"TRAPSTART",75:"TRAPEND",76:"INVTRAPSTART",77:"INVTRAPEND",80:"TESTSTR",81:"START_LINK",82:"LINK",84:"STR",85:"MD_STR",87:"STYLE",88:"LINKSTYLE",89:"CLASSDEF",90:"CLASS",91:"CLICK",92:"DOWN",93:"UP",96:"DEFAULT",99:"CALLBACKNAME",100:"CALLBACKARGS",101:"HREF",102:"LINK_TARGET",103:"HEX",105:"INTERPOLATE",106:"NUM",107:"COMMA",110:"MINUS",111:"UNIT",112:"BRKT",113:"DOT",114:"PCT",115:"TAGSTART",119:"direction_tb",120:"direction_bt",121:"direction_rl",122:"direction_lr",123:"PUNCTUATION",124:"UNICODE_TEXT",125:"PLUS",126:"EQUALS",127:"MULT",128:"UNDERSCORE",130:"ARROW_CROSS",131:"ARROW_POINT",132:"ARROW_CIRCLE",133:"ARROW_OPEN",134:"QUOTE"},productions_:[0,[3,1],[3,2],[5,4],[5,6],[6,1],[7,1],[11,1],[8,1],[4,2],[17,0],[17,2],[18,1],[18,1],[18,1],[18,1],[18,1],[16,2],[16,2],[16,2],[16,3],[28,2],[28,1],[29,1],[29,1],[29,1],[27,1],[27,1],[27,2],[31,2],[31,2],[31,1],[31,1],[30,2],[30,1],[19,2],[19,2],[19,2],[19,2],[19,2],[19,2],[19,9],[19,6],[19,4],[19,1],[19,2],[19,2],[19,1],[9,1],[9,1],[9,1],[32,3],[32,4],[32,2],[32,1],[50,1],[50,5],[50,3],[51,4],[51,4],[51,6],[51,4],[51,4],[51,4],[51,8],[51,4],[51,4],[51,4],[51,6],[51,4],[51,4],[51,4],[51,4],[51,4],[51,1],[49,2],[49,3],[49,3],[49,1],[49,3],[78,1],[79,3],[39,1],[39,2],[39,1],[39,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[94,1],[94,2],[35,5],[35,5],[36,5],[37,2],[37,4],[37,3],[37,5],[37,2],[37,4],[37,4],[37,6],[37,2],[37,4],[37,2],[37,4],[37,4],[37,6],[33,5],[33,5],[34,5],[34,5],[34,9],[34,9],[34,7],[34,7],[104,1],[104,3],[97,1],[97,3],[108,1],[108,2],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[95,1],[95,1],[95,1],[95,1],[54,1],[54,2],[98,1],[98,2],[118,1],[118,1],[118,1],[118,1],[43,1],[43,1],[43,1],[43,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1]],performAction:function(t,e,s,u,i,r,n){var a=r.length-1;switch(i){case 5:u.parseDirective("%%{","open_directive");break;case 6:u.parseDirective(r[a],"type_directive");break;case 7:r[a]=r[a].trim().replace(/'/g,'"'),u.parseDirective(r[a],"arg_directive");break;case 8:u.parseDirective("}%%","close_directive","flowchart");break;case 10:this.$=[];break;case 11:(!Array.isArray(r[a])||r[a].length>0)&&r[a-1].push(r[a]),this.$=r[a-1];break;case 12:case 97:case 153:case 155:case 156:this.$=r[a];break;case 19:u.setDirection("TB"),this.$="TB";break;case 20:u.setDirection(r[a-1]),this.$=r[a-1];break;case 35:this.$=r[a-1].nodes;break;case 36:case 37:case 38:case 39:case 40:this.$=[];break;case 41:this.$=u.addSubGraph(r[a-6],r[a-1],r[a-4]);break;case 42:this.$=u.addSubGraph(r[a-3],r[a-1],r[a-3]);break;case 43:this.$=u.addSubGraph(void 0,r[a-1],void 0);break;case 45:this.$=r[a].trim(),u.setAccTitle(this.$);break;case 46:case 47:this.$=r[a].trim(),u.setAccDescription(this.$);break;case 51:u.addLink(r[a-2].stmt,r[a],r[a-1]),this.$={stmt:r[a],nodes:r[a].concat(r[a-2].nodes)};break;case 52:u.addLink(r[a-3].stmt,r[a-1],r[a-2]),this.$={stmt:r[a-1],nodes:r[a-1].concat(r[a-3].nodes)};break;case 53:this.$={stmt:r[a-1],nodes:r[a-1]};break;case 54:this.$={stmt:r[a],nodes:r[a]};break;case 55:this.$=[r[a]];break;case 56:this.$=r[a-4].concat(r[a]);break;case 57:this.$=[r[a-2]],u.setClass(r[a-2],r[a]);break;case 58:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"square");break;case 59:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"doublecircle");break;case 60:this.$=r[a-5],u.addVertex(r[a-5],r[a-2],"circle");break;case 61:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"ellipse");break;case 62:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"stadium");break;case 63:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"subroutine");break;case 64:this.$=r[a-7],u.addVertex(r[a-7],r[a-1],"rect",void 0,void 0,void 0,Object.fromEntries([[r[a-5],r[a-3]]]));break;case 65:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"cylinder");break;case 66:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"round");break;case 67:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"diamond");break;case 68:this.$=r[a-5],u.addVertex(r[a-5],r[a-2],"hexagon");break;case 69:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"odd");break;case 70:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"trapezoid");break;case 71:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"inv_trapezoid");break;case 72:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"lean_right");break;case 73:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"lean_left");break;case 74:this.$=r[a],u.addVertex(r[a]);break;case 75:r[a-1].text=r[a],this.$=r[a-1];break;case 76:case 77:r[a-2].text=r[a-1],this.$=r[a-2];break;case 78:this.$=r[a];break;case 79:var c=u.destructLink(r[a],r[a-2]);this.$={type:c.type,stroke:c.stroke,length:c.length,text:r[a-1]};break;case 80:c=u.destructLink(r[a]);this.$={type:c.type,stroke:c.stroke,length:c.length};break;case 81:this.$=r[a-1];break;case 82:this.$={text:r[a],type:"text"};break;case 83:this.$={text:r[a-1].text+""+r[a],type:r[a-1].type};break;case 84:this.$={text:r[a],type:"text"};break;case 85:this.$={text:r[a],type:"markdown"};break;case 98:case 154:this.$=r[a-1]+""+r[a];break;case 99:case 100:this.$=r[a-4],u.addClass(r[a-2],r[a]);break;case 101:this.$=r[a-4],u.setClass(r[a-2],r[a]);break;case 102:case 110:this.$=r[a-1],u.setClickEvent(r[a-1],r[a]);break;case 103:case 111:this.$=r[a-3],u.setClickEvent(r[a-3],r[a-2]),u.setTooltip(r[a-3],r[a]);break;case 104:this.$=r[a-2],u.setClickEvent(r[a-2],r[a-1],r[a]);break;case 105:this.$=r[a-4],u.setClickEvent(r[a-4],r[a-3],r[a-2]),u.setTooltip(r[a-4],r[a]);break;case 106:case 112:this.$=r[a-1],u.setLink(r[a-1],r[a]);break;case 107:case 113:this.$=r[a-3],u.setLink(r[a-3],r[a-2]),u.setTooltip(r[a-3],r[a]);break;case 108:case 114:this.$=r[a-3],u.setLink(r[a-3],r[a-2],r[a]);break;case 109:case 115:this.$=r[a-5],u.setLink(r[a-5],r[a-4],r[a]),u.setTooltip(r[a-5],r[a-2]);break;case 116:this.$=r[a-4],u.addVertex(r[a-2],void 0,void 0,r[a]);break;case 117:case 119:this.$=r[a-4],u.updateLink(r[a-2],r[a]);break;case 118:this.$=r[a-4],u.updateLink([r[a-2]],r[a]);break;case 120:this.$=r[a-8],u.updateLinkInterpolate([r[a-6]],r[a-2]),u.updateLink([r[a-6]],r[a]);break;case 121:this.$=r[a-8],u.updateLinkInterpolate(r[a-6],r[a-2]),u.updateLink(r[a-6],r[a]);break;case 122:this.$=r[a-6],u.updateLinkInterpolate([r[a-4]],r[a]);break;case 123:this.$=r[a-6],u.updateLinkInterpolate(r[a-4],r[a]);break;case 124:case 126:this.$=[r[a]];break;case 125:case 127:r[a-2].push(r[a]),this.$=r[a-2];break;case 129:this.$=r[a-1]+r[a];break;case 151:this.$=r[a];break;case 152:this.$=r[a-1]+""+r[a];break;case 157:this.$="v";break;case 158:this.$="-";break;case 159:this.$={stmt:"dir",value:"TB"};break;case 160:this.$={stmt:"dir",value:"BT"};break;case 161:this.$={stmt:"dir",value:"RL"};break;case 162:this.$={stmt:"dir",value:"LR"}}},table:[{3:1,4:2,5:3,6:5,12:e,16:4,21:s,22:u,24:i},{1:[3]},{1:[2,1]},{3:10,4:2,5:3,6:5,12:e,16:4,21:s,22:u,24:i},t(r,n,{17:11}),{7:12,13:[1,13]},{16:14,21:s,22:u,24:i},{16:15,21:s,22:u,24:i},{25:[1,16],26:[1,17]},{13:[2,5]},{1:[2,2]},{1:[2,9],18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,43:31,44:A,46:d,48:p,50:35,51:45,52:y,54:46,66:E,67:f,87:k,88:D,89:b,90:g,91:_,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,119:x,120:L,121:R,122:I,123:$,124:N,125:O,126:P,127:U,128:w},{8:64,10:[1,65],15:V},t([10,15],[2,6]),t(r,[2,17]),t(r,[2,18]),t(r,[2,19]),{20:[1,68],21:[1,69],22:M,27:67,30:70},t(G,[2,11]),t(G,[2,12]),t(G,[2,13]),t(G,[2,14]),t(G,[2,15]),t(G,[2,16]),{9:72,20:K,21:j,23:W,49:73,78:77,81:[1,78],82:[1,79]},{9:80,20:K,21:j,23:W},{9:81,20:K,21:j,23:W},{9:82,20:K,21:j,23:W},{9:83,20:K,21:j,23:W},{9:84,20:K,21:j,23:W},{9:86,20:K,21:j,22:[1,85],23:W},t(G,[2,44]),{45:[1,87]},{47:[1,88]},t(G,[2,47]),t(Y,[2,54],{30:89,22:M}),{22:[1,90]},{22:[1,91]},{22:[1,92]},{22:[1,93]},{26:H,52:z,66:Q,67:X,84:[1,97],92:q,98:96,99:[1,94],101:[1,95],106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(G,[2,159]),t(G,[2,160]),t(G,[2,161]),t(G,[2,162]),t(ot,[2,55],{53:[1,116]}),t(lt,[2,74],{117:129,40:[1,117],52:y,55:[1,118],57:[1,119],59:[1,120],61:[1,121],63:[1,122],65:[1,123],66:E,67:f,69:[1,124],71:[1,125],73:[1,126],74:[1,127],76:[1,128],92:F,96:C,106:B,107:T,110:m,112:S,113:v,123:$,124:N,125:O,126:P,127:U,128:w}),t(ht,[2,151]),t(ht,[2,176]),t(ht,[2,177]),t(ht,[2,178]),t(ht,[2,179]),t(ht,[2,180]),t(ht,[2,181]),t(ht,[2,182]),t(ht,[2,183]),t(ht,[2,184]),t(ht,[2,185]),t(ht,[2,186]),t(ht,[2,187]),t(ht,[2,188]),t(ht,[2,189]),t(ht,[2,190]),t(ht,[2,191]),{9:130,20:K,21:j,23:W},{11:131,14:[1,132]},t(At,[2,8]),t(r,[2,20]),t(r,[2,26]),t(r,[2,27]),{21:[1,133]},t(dt,[2,34],{30:134,22:M}),t(G,[2,35]),{50:135,51:45,52:y,54:46,66:E,67:f,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,123:$,124:N,125:O,126:P,127:U,128:w},t(pt,[2,48]),t(pt,[2,49]),t(pt,[2,50]),t(yt,[2,78],{79:136,68:[1,138],80:[1,137]}),{22:Et,24:ft,26:kt,38:Dt,39:139,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t([52,66,67,68,80,92,96,106,107,110,112,113,123,124,125,126,127,128],[2,80]),t(G,[2,36]),t(G,[2,37]),t(G,[2,38]),t(G,[2,39]),t(G,[2,40]),{22:Et,24:ft,26:kt,38:Dt,39:164,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(Ot,n,{17:165}),t(G,[2,45]),t(G,[2,46]),t(Y,[2,53],{52:Pt}),{26:H,52:z,66:Q,67:X,92:q,98:167,103:[1,168],106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{96:[1,169],104:170,106:[1,171]},{26:H,52:z,66:Q,67:X,92:q,96:[1,172],98:173,106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{26:H,52:z,66:Q,67:X,92:q,98:174,106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(At,[2,102],{22:[1,175],100:[1,176]}),t(At,[2,106],{22:[1,177]}),t(At,[2,110],{116:100,118:179,22:[1,178],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,123:ut,124:it,125:rt,126:nt,127:at,128:ct}),t(At,[2,112],{22:[1,180]}),t(Ut,[2,153]),t(Ut,[2,155]),t(Ut,[2,156]),t(Ut,[2,157]),t(Ut,[2,158]),t(wt,[2,163]),t(wt,[2,164]),t(wt,[2,165]),t(wt,[2,166]),t(wt,[2,167]),t(wt,[2,168]),t(wt,[2,169]),t(wt,[2,170]),t(wt,[2,171]),t(wt,[2,172]),t(wt,[2,173]),t(wt,[2,174]),t(wt,[2,175]),{52:y,54:181,66:E,67:f,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,123:$,124:N,125:O,126:P,127:U,128:w},{22:Et,24:ft,26:kt,38:Dt,39:182,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:183,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:185,42:bt,52:z,57:[1,184],66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:186,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:187,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:188,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{66:[1,189]},{22:Et,24:ft,26:kt,38:Dt,39:190,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:191,42:bt,52:z,66:Q,67:X,71:[1,192],73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:193,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:194,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:195,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(ht,[2,152]),t(Vt,[2,3]),{8:196,15:V},{15:[2,7]},t(r,[2,28]),t(dt,[2,33]),t(Y,[2,51],{30:197,22:M}),t(yt,[2,75],{22:[1,198]}),{22:[1,199]},{22:Et,24:ft,26:kt,38:Dt,39:200,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,73:gt,81:_t,82:[1,201],83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(wt,[2,82]),t(wt,[2,84]),t(wt,[2,85]),t(wt,[2,141]),t(wt,[2,142]),t(wt,[2,143]),t(wt,[2,144]),t(wt,[2,145]),t(wt,[2,146]),t(wt,[2,147]),t(wt,[2,148]),t(wt,[2,149]),t(wt,[2,150]),t(wt,[2,86]),t(wt,[2,87]),t(wt,[2,88]),t(wt,[2,89]),t(wt,[2,90]),t(wt,[2,91]),t(wt,[2,92]),t(wt,[2,93]),t(wt,[2,94]),t(wt,[2,95]),t(wt,[2,96]),{9:204,20:K,21:j,22:Et,23:W,24:ft,26:kt,38:Dt,40:[1,203],42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,42:[1,205],43:31,44:A,46:d,48:p,50:35,51:45,52:y,54:46,66:E,67:f,87:k,88:D,89:b,90:g,91:_,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,119:x,120:L,121:R,122:I,123:$,124:N,125:O,126:P,127:U,128:w},{22:M,30:206},{22:[1,207],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,116:100,118:179,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:[1,208]},{22:[1,209]},{22:[1,210],107:[1,211]},t(Mt,[2,124]),{22:[1,212]},{22:[1,213],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,116:100,118:179,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:[1,214],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,116:100,118:179,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{84:[1,215]},t(At,[2,104],{22:[1,216]}),{84:[1,217],102:[1,218]},{84:[1,219]},t(Ut,[2,154]),{84:[1,220],102:[1,221]},t(ot,[2,57],{117:129,52:y,66:E,67:f,92:F,96:C,106:B,107:T,110:m,112:S,113:v,123:$,124:N,125:O,126:P,127:U,128:w}),{22:Et,24:ft,26:kt,38:Dt,41:[1,222],42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,56:[1,223],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:224,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,58:[1,225],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,60:[1,226],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,62:[1,227],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,64:[1,228],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{67:[1,229]},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,70:[1,230],73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,72:[1,231],73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:232,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,41:[1,233],42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,73:gt,75:[1,234],77:[1,235],81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,73:gt,75:[1,237],77:[1,236],81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{9:238,20:K,21:j,23:W},t(Y,[2,52],{52:Pt}),t(yt,[2,77]),t(yt,[2,76]),{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,68:[1,239],73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(yt,[2,79]),t(wt,[2,83]),{22:Et,24:ft,26:kt,38:Dt,39:240,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(Ot,n,{17:241}),t(G,[2,43]),{51:242,52:y,54:46,66:E,67:f,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,123:$,124:N,125:O,126:P,127:U,128:w},{22:Gt,66:Kt,67:jt,87:Wt,97:243,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{22:Gt,66:Kt,67:jt,87:Wt,97:257,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{22:Gt,66:Kt,67:jt,87:Wt,97:258,103:Yt,105:[1,259],106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{22:Gt,66:Kt,67:jt,87:Wt,97:260,103:Yt,105:[1,261],106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{106:[1,262]},{22:Gt,66:Kt,67:jt,87:Wt,97:263,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{22:Gt,66:Kt,67:jt,87:Wt,97:264,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{26:H,52:z,66:Q,67:X,92:q,98:265,106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(At,[2,103]),{84:[1,266]},t(At,[2,107],{22:[1,267]}),t(At,[2,108]),t(At,[2,111]),t(At,[2,113],{22:[1,268]}),t(At,[2,114]),t(lt,[2,58]),t(lt,[2,59]),{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,58:[1,269],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(lt,[2,66]),t(lt,[2,61]),t(lt,[2,62]),t(lt,[2,63]),{66:[1,270]},t(lt,[2,65]),t(lt,[2,67]),{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,72:[1,271],73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(lt,[2,69]),t(lt,[2,70]),t(lt,[2,72]),t(lt,[2,71]),t(lt,[2,73]),t(Vt,[2,4]),t([22,52,66,67,92,96,106,107,110,112,113,123,124,125,126,127,128],[2,81]),{22:Et,24:ft,26:kt,38:Dt,41:[1,272],42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,42:[1,273],43:31,44:A,46:d,48:p,50:35,51:45,52:y,54:46,66:E,67:f,87:k,88:D,89:b,90:g,91:_,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,119:x,120:L,121:R,122:I,123:$,124:N,125:O,126:P,127:U,128:w},t(ot,[2,56]),t(At,[2,116],{107:Jt}),t(te,[2,126],{109:275,22:Gt,66:Kt,67:jt,87:Wt,103:Yt,106:Ht,110:zt,111:Qt,112:Xt,113:qt,114:Zt}),t(ee,[2,128]),t(ee,[2,130]),t(ee,[2,131]),t(ee,[2,132]),t(ee,[2,133]),t(ee,[2,134]),t(ee,[2,135]),t(ee,[2,136]),t(ee,[2,137]),t(ee,[2,138]),t(ee,[2,139]),t(ee,[2,140]),t(At,[2,117],{107:Jt}),t(At,[2,118],{107:Jt}),{22:[1,276]},t(At,[2,119],{107:Jt}),{22:[1,277]},t(Mt,[2,125]),t(At,[2,99],{107:Jt}),t(At,[2,100],{107:Jt}),t(At,[2,101],{116:100,118:179,26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,123:ut,124:it,125:rt,126:nt,127:at,128:ct}),t(At,[2,105]),{102:[1,278]},{102:[1,279]},{58:[1,280]},{68:[1,281]},{72:[1,282]},{9:283,20:K,21:j,23:W},t(G,[2,42]),{22:Gt,66:Kt,67:jt,87:Wt,103:Yt,106:Ht,108:284,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},t(ee,[2,129]),{26:H,52:z,66:Q,67:X,92:q,98:285,106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{26:H,52:z,66:Q,67:X,92:q,98:286,106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(At,[2,109]),t(At,[2,115]),t(lt,[2,60]),{22:Et,24:ft,26:kt,38:Dt,39:287,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(lt,[2,68]),t(Ot,n,{17:288}),t(te,[2,127],{109:275,22:Gt,66:Kt,67:jt,87:Wt,103:Yt,106:Ht,110:zt,111:Qt,112:Xt,113:qt,114:Zt}),t(At,[2,122],{116:100,118:179,22:[1,289],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,123:ut,124:it,125:rt,126:nt,127:at,128:ct}),t(At,[2,123],{116:100,118:179,22:[1,290],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,123:ut,124:it,125:rt,126:nt,127:at,128:ct}),{22:Et,24:ft,26:kt,38:Dt,41:[1,291],42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,42:[1,292],43:31,44:A,46:d,48:p,50:35,51:45,52:y,54:46,66:E,67:f,87:k,88:D,89:b,90:g,91:_,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,119:x,120:L,121:R,122:I,123:$,124:N,125:O,126:P,127:U,128:w},{22:Gt,66:Kt,67:jt,87:Wt,97:293,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{22:Gt,66:Kt,67:jt,87:Wt,97:294,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},t(lt,[2,64]),t(G,[2,41]),t(At,[2,120],{107:Jt}),t(At,[2,121],{107:Jt})],defaultActions:{2:[2,1],9:[2,5],10:[2,2],132:[2,7]},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=this,s=[0],u=[],i=[null],r=[],n=this.table,a="",c=0,o=0,l=2,h=1,A=r.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(p.yy[y]=this.yy[y]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var E=d.yylloc;r.push(E);var f=d.options&&d.options.ranges;function k(){var t;return"number"!=typeof(t=u.pop()||d.lex()||h)&&(t instanceof Array&&(t=(u=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var D,b,g,_,F,C,B,T,m={};;){if(b=s[s.length-1],this.defaultActions[b]?g=this.defaultActions[b]:(null==D&&(D=k()),g=n[b]&&n[b][D]),void 0===g||!g.length||!g[0]){var S="";for(F in T=[],n[b])this.terminals_[F]&&F>l&&T.push("'"+this.terminals_[F]+"'");S=d.showPosition?"Parse error on line "+(c+1)+":\n"+d.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[D]||D)+"'":"Parse error on line "+(c+1)+": Unexpected "+(D==h?"end of input":"'"+(this.terminals_[D]||D)+"'"),this.parseError(S,{text:d.match,token:this.terminals_[D]||D,line:d.yylineno,loc:E,expected:T})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+D);switch(g[0]){case 1:s.push(D),i.push(d.yytext),r.push(d.yylloc),s.push(g[1]),D=null,o=d.yyleng,a=d.yytext,c=d.yylineno,E=d.yylloc;break;case 2:if(C=this.productions_[g[1]][1],m.$=i[i.length-C],m._$={first_line:r[r.length-(C||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(C||1)].first_column,last_column:r[r.length-1].last_column},f&&(m._$.range=[r[r.length-(C||1)].range[0],r[r.length-1].range[1]]),void 0!==(_=this.performAction.apply(m,[a,o,c,p.yy,g[1],i,r].concat(A))))return _;C&&(s=s.slice(0,-1*C*2),i=i.slice(0,-1*C),r=r.slice(0,-1*C)),s.push(this.productions_[g[1]][0]),i.push(m.$),r.push(m._$),B=n[s[s.length-2]][s[s.length-1]],s.push(B);break;case 3:return!0}}return!0}},ue={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,s=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 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),s.length-1&&(this.yylineno-=s.length-1);var i=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:s?(s.length===u.length?this.yylloc.first_column:0)+u[u.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var s,u,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(u=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=u.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:u?u[u.length-1].length-u[u.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in i)this[r]=i[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,u;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),r=0;re[0].length)){if(e=s,u=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,i[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[u]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,s,u){switch(s){case 0:return this.begin("open_directive"),12;case 1:return this.begin("type_directive"),13;case 2:return this.popState(),this.begin("arg_directive"),10;case 3:return this.popState(),this.popState(),15;case 4:return 14;case 5:return this.begin("acc_title"),44;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),46;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:this.begin("md_string");break;case 13:return"MD_STR";case 14:this.popState();break;case 15:this.begin("string");break;case 16:this.popState();break;case 17:return"STR";case 18:return 87;case 19:return 96;case 20:return 88;case 21:return 105;case 22:return 89;case 23:return 90;case 24:this.begin("href");break;case 25:this.popState();break;case 26:return 101;case 27:this.begin("callbackname");break;case 28:this.popState();break;case 29:this.popState(),this.begin("callbackargs");break;case 30:return 99;case 31:this.popState();break;case 32:return 100;case 33:this.begin("click");break;case 34:this.popState();break;case 35:return 91;case 36:case 37:case 38:return t.lex.firstGraph()&&this.begin("dir"),24;case 39:return 38;case 40:return 42;case 41:case 42:case 43:case 44:return 102;case 45:return this.popState(),25;case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:return this.popState(),26;case 56:return 119;case 57:return 120;case 58:return 121;case 59:return 122;case 60:return 106;case 61:return 112;case 62:return 53;case 63:return 67;case 64:return 52;case 65:return 20;case 66:return 107;case 67:return 127;case 68:case 69:case 70:case 71:return 82;case 72:case 73:case 74:return 81;case 75:return 59;case 76:return 60;case 77:return 61;case 78:return 62;case 79:return 63;case 80:return 64;case 81:return 65;case 82:return 69;case 83:return 70;case 84:return 55;case 85:return 56;case 86:return 110;case 87:return 113;case 88:return 128;case 89:return 125;case 90:return 114;case 91:case 92:return 126;case 93:return 115;case 94:return 73;case 95:return 93;case 96:return"SEP";case 97:return 92;case 98:return 66;case 99:return 75;case 100:return 74;case 101:return 77;case 102:return 76;case 103:return 123;case 104:return 124;case 105:return 68;case 106:return 57;case 107:return 58;case 108:return 40;case 109:return 41;case 110:return 71;case 111:return 72;case 112:return 134;case 113:return 21;case 114:return 22;case 115:return 23}},rules:[/^(?:%%\{)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s]+["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*~~[\~]+\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\[)/,/^(?:\]\))/,/^(?:\[\[)/,/^(?:\]\])/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\])/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:-)/,/^(?:\.)/,/^(?:[\_])/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:[A-Za-z]+)/,/^(?:\\\])/,/^(?:\[\/)/,/^(?:\/\])/,/^(?:\[\\)/,/^(?:[!"#$%&'*+,-.`?\\_/])/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},callbackargs:{rules:[31,32],inclusive:!1},callbackname:{rules:[28,29,30],inclusive:!1},href:{rules:[25,26],inclusive:!1},click:{rules:[34,35],inclusive:!1},vertex:{rules:[],inclusive:!1},dir:{rules:[45,46,47,48,49,50,51,52,53,54,55],inclusive:!1},acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},md_string:{rules:[13,14],inclusive:!1},string:{rules:[16,17],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,15,18,19,20,21,22,23,24,27,33,36,37,38,39,40,41,42,43,44,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115],inclusive:!0}}};function ie(){this.yy={}}return se.lexer=ue,ie.prototype=se,se.Parser=ie,new ie}();p.parser=p;const y=p;let E,f,k=0,D=t(),b={},g=[],_={},F=[],C={},B={},T=0,m=!0,S=[];const v=t=>o.sanitizeText(t,D),x=function(t,e,s){c.parseDirective(this,t,e,s)},L=function(t){const e=Object.keys(b);for(const s of e)if(b[s].id===t)return b[s].domId;return t},R=function(e,s,u,i,r,n,a={}){let c,o=e;void 0!==o&&0!==o.trim().length&&(void 0===b[o]&&(b[o]={id:o,labelType:"text",domId:"flowchart-"+o+"-"+k,styles:[],classes:[]}),k++,void 0!==s?(D=t(),c=v(s.text.trim()),b[o].labelType=s.type,'"'===c[0]&&'"'===c[c.length-1]&&(c=c.substring(1,c.length-1)),b[o].text=c):void 0===b[o].text&&(b[o].text=e),void 0!==u&&(b[o].type=u),null!=i&&i.forEach((function(t){b[o].styles.push(t)})),null!=r&&r.forEach((function(t){b[o].classes.push(t)})),void 0!==n&&(b[o].dir=n),void 0===b[o].props?b[o].props=a:void 0!==a&&Object.assign(b[o].props,a))},I=function(t,e,s){const u={start:t,end:e,type:void 0,text:"",labelType:"text"};l.info("abc78 Got edge...",u);const i=s.text;void 0!==i&&(u.text=v(i.text.trim()),'"'===u.text[0]&&'"'===u.text[u.text.length-1]&&(u.text=u.text.substring(1,u.text.length-1)),u.labelType=i.type),void 0!==s&&(u.type=s.type,u.stroke=s.stroke,u.length=s.length),g.push(u)},$=function(t,e,s){let u,i;for(l.info("addLink (abc78)",t,e,s),u=0;u/)&&(E="LR"),E.match(/.*v/)&&(E="TB"),"TD"===E&&(E="TB")},w=function(t,e){t.split(",").forEach((function(t){let s=t;void 0!==b[s]&&b[s].classes.push(e),void 0!==C[s]&&C[s].classes.push(e)}))},V=function(t,e,s){t.split(",").forEach((function(t){void 0!==b[t]&&(b[t].link=h.formatUrl(e,D),b[t].linkTarget=s)})),w(t,"clickable")},M=function(t){return B[t]},G=function(e,s,u){e.split(",").forEach((function(e){!function(e,s,u){let i=L(e);if("loose"!==t().securityLevel)return;if(void 0===s)return;let r=[];if("string"==typeof u){r=u.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);d(this).classed("hover",!1)}))};S.push(z);const Q=function(t="gen-1"){b={},_={},g=[],S=[z],F=[],C={},T=0,B=[],m=!0,f=t,A()},X=t=>{f=t||"gen-2"},q=function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},Z=function(t,e,s){let u=t.text.trim(),i=s.text;t===s&&s.text.match(/\s/)&&(u=void 0);let r=[];const{nodeList:n,dir:a}=function(t){const e={boolean:{},number:{},string:{}},s=[];let u;return{nodeList:t.filter((function(t){const i=typeof t;return t.stmt&&"dir"===t.stmt?(u=t.value,!1):""!==t.trim()&&(i in e?!e[i].hasOwnProperty(t)&&(e[i][t]=!0):!s.includes(t)&&s.push(t))})),dir:u}}(r.concat.apply(r,e));if(r=n,"gen-1"===f)for(let o=0;o2e3)return;if(et[tt]=e,F[e].id===t)return{result:!0,count:0};let u=0,i=1;for(;u=0){const s=st(t,e);if(s.result)return{result:!0,count:i+s.count};i+=s.count}u+=1}return{result:!1,count:i}},ut=function(t){return et[t]},it=function(){tt=-1,F.length>0&&st("none",F.length-1)},rt=function(){return F},nt=()=>!!m&&(m=!1,!0),at=(t,e)=>{const s=(t=>{const e=t.trim();let s=e.slice(0,-1),u="arrow_open";switch(e.slice(-1)){case"x":u="arrow_cross","x"===e[0]&&(u="double_"+u,s=s.slice(1));break;case">":u="arrow_point","<"===e[0]&&(u="double_"+u,s=s.slice(1));break;case"o":u="arrow_circle","o"===e[0]&&(u="double_"+u,s=s.slice(1))}let i="normal",r=s.length-1;"="===s[0]&&(i="thick"),"~"===s[0]&&(i="invisible");let n=((t,e)=>{const s=e.length;let u=0;for(let i=0;i{let e=t.trim(),s="arrow_open";switch(e[0]){case"<":s="arrow_point",e=e.slice(1);break;case"x":s="arrow_cross",e=e.slice(1);break;case"o":s="arrow_circle",e=e.slice(1)}let u="normal";return e.includes("=")&&(u="thick"),e.includes(".")&&(u="dotted"),{type:s,stroke:u}})(e),u.stroke!==s.stroke)return{type:"INVALID",stroke:"INVALID"};if("arrow_open"===u.type)u.type=s.type;else{if(u.type!==s.type)return{type:"INVALID",stroke:"INVALID"};u.type="double_"+u.type}return"double_arrow"===u.type&&(u.type="double_arrow_point"),u.length=s.length,u}return s},ct=(t,e)=>{let s=!1;return t.forEach((t=>{t.nodes.indexOf(e)>=0&&(s=!0)})),s},ot=(t,e)=>{const s=[];return t.nodes.forEach(((u,i)=>{ct(e,u)||s.push(t.nodes[i])})),{nodes:s}},lt={firstGraph:nt},ht={parseDirective:x,defaultConfig:()=>e.flowchart,setAccTitle:s,getAccTitle:u,getAccDescription:i,setAccDescription:r,addVertex:R,lookUpDomId:L,addLink:$,updateLinkInterpolate:N,updateLink:O,addClass:P,setDirection:U,setClass:w,setTooltip:function(t,e){t.split(",").forEach((function(t){void 0!==e&&(B["gen-1"===f?L(t):t]=v(e))}))},getTooltip:M,setClickEvent:G,setLink:V,bindFunctions:K,getDirection:j,getVertices:W,getEdges:Y,getClasses:H,clear:Q,setGen:X,defaultStyle:q,addSubGraph:Z,getDepthFirstPos:ut,indexNodes:it,getSubGraphs:rt,destructLink:at,lex:lt,exists:ct,makeUniq:ot,setDiagramTitle:n,getDiagramTitle:a},At=Object.freeze(Object.defineProperty({__proto__:null,addClass:P,addLink:$,addSingleLink:I,addSubGraph:Z,addVertex:R,bindFunctions:K,clear:Q,default:ht,defaultStyle:q,destructLink:at,firstGraph:nt,getClasses:H,getDepthFirstPos:ut,getDirection:j,getEdges:Y,getSubGraphs:rt,getTooltip:M,getVertices:W,indexNodes:it,lex:lt,lookUpDomId:L,parseDirective:x,setClass:w,setClickEvent:G,setDirection:U,setGen:X,setLink:V,updateLink:O,updateLinkInterpolate:N},Symbol.toStringTag,{value:"Module"}));export{At as d,ht as f,y as p}; +import{c as t,u as e,s,g as u,a as i,b as r,v as n,x as a,m as c,j as o,l,y as h,z as A,h as d}from"./mermaid.core.3a590193.js";var p=function(){var t=function(t,e,s,u){for(s=s||{},u=t.length;u--;s[t[u]]=e);return s},e=[1,9],s=[1,7],u=[1,6],i=[1,8],r=[1,20,21,22,23,38,44,46,48,52,66,67,87,88,89,90,91,92,96,106,107,110,112,113,119,120,121,122,123,124,125,126,127,128],n=[2,10],a=[1,20],c=[1,21],o=[1,22],l=[1,23],h=[1,30],A=[1,32],d=[1,33],p=[1,34],y=[1,62],E=[1,48],f=[1,52],k=[1,36],D=[1,37],b=[1,38],g=[1,39],_=[1,40],F=[1,56],C=[1,63],B=[1,51],T=[1,53],m=[1,55],S=[1,59],v=[1,60],x=[1,41],L=[1,42],R=[1,43],I=[1,44],$=[1,61],N=[1,50],O=[1,54],P=[1,57],U=[1,58],w=[1,49],V=[1,66],M=[1,71],G=[1,20,21,22,23,38,42,44,46,48,52,66,67,87,88,89,90,91,92,96,106,107,110,112,113,119,120,121,122,123,124,125,126,127,128],K=[1,75],j=[1,74],W=[1,76],Y=[20,21,23,81,82],H=[1,99],z=[1,104],Q=[1,107],X=[1,108],q=[1,101],Z=[1,106],J=[1,109],tt=[1,102],et=[1,114],st=[1,113],ut=[1,103],it=[1,105],rt=[1,110],nt=[1,111],at=[1,112],ct=[1,115],ot=[20,21,22,23,81,82],lt=[20,21,22,23,53,81,82],ht=[20,21,22,23,40,52,53,55,57,59,61,63,65,66,67,69,71,73,74,76,81,82,92,96,106,107,110,112,113,123,124,125,126,127,128],At=[20,21,23],dt=[20,21,23,52,66,67,81,82,92,96,106,107,110,112,113,123,124,125,126,127,128],pt=[1,12,20,21,22,23,24,38,42,44,46,48,52,66,67,87,88,89,90,91,92,96,106,107,110,112,113,119,120,121,122,123,124,125,126,127,128],yt=[52,66,67,92,96,106,107,110,112,113,123,124,125,126,127,128],Et=[1,150],ft=[1,158],kt=[1,159],Dt=[1,160],bt=[1,161],gt=[1,145],_t=[1,146],Ft=[1,141],Ct=[1,142],Bt=[1,153],Tt=[1,154],mt=[1,155],St=[1,156],vt=[1,157],xt=[1,162],Lt=[1,163],Rt=[1,148],It=[1,151],$t=[1,147],Nt=[1,144],Ot=[20,21,22,23,38,42,44,46,48,52,66,67,87,88,89,90,91,92,96,106,107,110,112,113,119,120,121,122,123,124,125,126,127,128],Pt=[1,166],Ut=[20,21,22,23,26,52,66,67,92,106,107,110,112,113,123,124,125,126,127,128],wt=[20,21,22,23,24,26,38,40,41,42,52,56,58,60,62,64,66,67,68,70,72,73,75,77,81,82,87,88,89,90,91,92,93,96,106,107,110,112,113,114,115,123,124,125,126,127,128],Vt=[12,21,22,24],Mt=[22,107],Gt=[1,251],Kt=[1,246],jt=[1,247],Wt=[1,255],Yt=[1,252],Ht=[1,249],zt=[1,248],Qt=[1,250],Xt=[1,253],qt=[1,254],Zt=[1,256],Jt=[1,274],te=[20,21,23,107],ee=[20,21,22,23,66,67,87,103,106,107,110,111,112,113,114],se={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,directive:5,openDirective:6,typeDirective:7,closeDirective:8,separator:9,":":10,argDirective:11,open_directive:12,type_directive:13,arg_directive:14,close_directive:15,graphConfig:16,document:17,line:18,statement:19,SEMI:20,NEWLINE:21,SPACE:22,EOF:23,GRAPH:24,NODIR:25,DIR:26,FirstStmtSeperator:27,ending:28,endToken:29,spaceList:30,spaceListNewline:31,verticeStatement:32,styleStatement:33,linkStyleStatement:34,classDefStatement:35,classStatement:36,clickStatement:37,subgraph:38,text:39,SQS:40,SQE:41,end:42,direction:43,acc_title:44,acc_title_value:45,acc_descr:46,acc_descr_value:47,acc_descr_multiline_value:48,link:49,node:50,vertex:51,AMP:52,STYLE_SEPARATOR:53,idString:54,DOUBLECIRCLESTART:55,DOUBLECIRCLEEND:56,PS:57,PE:58,"(-":59,"-)":60,STADIUMSTART:61,STADIUMEND:62,SUBROUTINESTART:63,SUBROUTINEEND:64,VERTEX_WITH_PROPS_START:65,ALPHA:66,COLON:67,PIPE:68,CYLINDERSTART:69,CYLINDEREND:70,DIAMOND_START:71,DIAMOND_STOP:72,TAGEND:73,TRAPSTART:74,TRAPEND:75,INVTRAPSTART:76,INVTRAPEND:77,linkStatement:78,arrowText:79,TESTSTR:80,START_LINK:81,LINK:82,textToken:83,STR:84,MD_STR:85,keywords:86,STYLE:87,LINKSTYLE:88,CLASSDEF:89,CLASS:90,CLICK:91,DOWN:92,UP:93,textNoTags:94,textNoTagsToken:95,DEFAULT:96,stylesOpt:97,alphaNum:98,CALLBACKNAME:99,CALLBACKARGS:100,HREF:101,LINK_TARGET:102,HEX:103,numList:104,INTERPOLATE:105,NUM:106,COMMA:107,style:108,styleComponent:109,MINUS:110,UNIT:111,BRKT:112,DOT:113,PCT:114,TAGSTART:115,alphaNumToken:116,idStringToken:117,alphaNumStatement:118,direction_tb:119,direction_bt:120,direction_rl:121,direction_lr:122,PUNCTUATION:123,UNICODE_TEXT:124,PLUS:125,EQUALS:126,MULT:127,UNDERSCORE:128,graphCodeTokens:129,ARROW_CROSS:130,ARROW_POINT:131,ARROW_CIRCLE:132,ARROW_OPEN:133,QUOTE:134,$accept:0,$end:1},terminals_:{2:"error",10:":",12:"open_directive",13:"type_directive",14:"arg_directive",15:"close_directive",20:"SEMI",21:"NEWLINE",22:"SPACE",23:"EOF",24:"GRAPH",25:"NODIR",26:"DIR",38:"subgraph",40:"SQS",41:"SQE",42:"end",44:"acc_title",45:"acc_title_value",46:"acc_descr",47:"acc_descr_value",48:"acc_descr_multiline_value",52:"AMP",53:"STYLE_SEPARATOR",55:"DOUBLECIRCLESTART",56:"DOUBLECIRCLEEND",57:"PS",58:"PE",59:"(-",60:"-)",61:"STADIUMSTART",62:"STADIUMEND",63:"SUBROUTINESTART",64:"SUBROUTINEEND",65:"VERTEX_WITH_PROPS_START",66:"ALPHA",67:"COLON",68:"PIPE",69:"CYLINDERSTART",70:"CYLINDEREND",71:"DIAMOND_START",72:"DIAMOND_STOP",73:"TAGEND",74:"TRAPSTART",75:"TRAPEND",76:"INVTRAPSTART",77:"INVTRAPEND",80:"TESTSTR",81:"START_LINK",82:"LINK",84:"STR",85:"MD_STR",87:"STYLE",88:"LINKSTYLE",89:"CLASSDEF",90:"CLASS",91:"CLICK",92:"DOWN",93:"UP",96:"DEFAULT",99:"CALLBACKNAME",100:"CALLBACKARGS",101:"HREF",102:"LINK_TARGET",103:"HEX",105:"INTERPOLATE",106:"NUM",107:"COMMA",110:"MINUS",111:"UNIT",112:"BRKT",113:"DOT",114:"PCT",115:"TAGSTART",119:"direction_tb",120:"direction_bt",121:"direction_rl",122:"direction_lr",123:"PUNCTUATION",124:"UNICODE_TEXT",125:"PLUS",126:"EQUALS",127:"MULT",128:"UNDERSCORE",130:"ARROW_CROSS",131:"ARROW_POINT",132:"ARROW_CIRCLE",133:"ARROW_OPEN",134:"QUOTE"},productions_:[0,[3,1],[3,2],[5,4],[5,6],[6,1],[7,1],[11,1],[8,1],[4,2],[17,0],[17,2],[18,1],[18,1],[18,1],[18,1],[18,1],[16,2],[16,2],[16,2],[16,3],[28,2],[28,1],[29,1],[29,1],[29,1],[27,1],[27,1],[27,2],[31,2],[31,2],[31,1],[31,1],[30,2],[30,1],[19,2],[19,2],[19,2],[19,2],[19,2],[19,2],[19,9],[19,6],[19,4],[19,1],[19,2],[19,2],[19,1],[9,1],[9,1],[9,1],[32,3],[32,4],[32,2],[32,1],[50,1],[50,5],[50,3],[51,4],[51,4],[51,6],[51,4],[51,4],[51,4],[51,8],[51,4],[51,4],[51,4],[51,6],[51,4],[51,4],[51,4],[51,4],[51,4],[51,1],[49,2],[49,3],[49,3],[49,1],[49,3],[78,1],[79,3],[39,1],[39,2],[39,1],[39,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[86,1],[94,1],[94,2],[35,5],[35,5],[36,5],[37,2],[37,4],[37,3],[37,5],[37,2],[37,4],[37,4],[37,6],[37,2],[37,4],[37,2],[37,4],[37,4],[37,6],[33,5],[33,5],[34,5],[34,5],[34,9],[34,9],[34,7],[34,7],[104,1],[104,3],[97,1],[97,3],[108,1],[108,2],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[109,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[95,1],[95,1],[95,1],[95,1],[54,1],[54,2],[98,1],[98,2],[118,1],[118,1],[118,1],[118,1],[43,1],[43,1],[43,1],[43,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[116,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[117,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1],[129,1]],performAction:function(t,e,s,u,i,r,n){var a=r.length-1;switch(i){case 5:u.parseDirective("%%{","open_directive");break;case 6:u.parseDirective(r[a],"type_directive");break;case 7:r[a]=r[a].trim().replace(/'/g,'"'),u.parseDirective(r[a],"arg_directive");break;case 8:u.parseDirective("}%%","close_directive","flowchart");break;case 10:this.$=[];break;case 11:(!Array.isArray(r[a])||r[a].length>0)&&r[a-1].push(r[a]),this.$=r[a-1];break;case 12:case 97:case 153:case 155:case 156:this.$=r[a];break;case 19:u.setDirection("TB"),this.$="TB";break;case 20:u.setDirection(r[a-1]),this.$=r[a-1];break;case 35:this.$=r[a-1].nodes;break;case 36:case 37:case 38:case 39:case 40:this.$=[];break;case 41:this.$=u.addSubGraph(r[a-6],r[a-1],r[a-4]);break;case 42:this.$=u.addSubGraph(r[a-3],r[a-1],r[a-3]);break;case 43:this.$=u.addSubGraph(void 0,r[a-1],void 0);break;case 45:this.$=r[a].trim(),u.setAccTitle(this.$);break;case 46:case 47:this.$=r[a].trim(),u.setAccDescription(this.$);break;case 51:u.addLink(r[a-2].stmt,r[a],r[a-1]),this.$={stmt:r[a],nodes:r[a].concat(r[a-2].nodes)};break;case 52:u.addLink(r[a-3].stmt,r[a-1],r[a-2]),this.$={stmt:r[a-1],nodes:r[a-1].concat(r[a-3].nodes)};break;case 53:this.$={stmt:r[a-1],nodes:r[a-1]};break;case 54:this.$={stmt:r[a],nodes:r[a]};break;case 55:this.$=[r[a]];break;case 56:this.$=r[a-4].concat(r[a]);break;case 57:this.$=[r[a-2]],u.setClass(r[a-2],r[a]);break;case 58:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"square");break;case 59:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"doublecircle");break;case 60:this.$=r[a-5],u.addVertex(r[a-5],r[a-2],"circle");break;case 61:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"ellipse");break;case 62:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"stadium");break;case 63:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"subroutine");break;case 64:this.$=r[a-7],u.addVertex(r[a-7],r[a-1],"rect",void 0,void 0,void 0,Object.fromEntries([[r[a-5],r[a-3]]]));break;case 65:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"cylinder");break;case 66:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"round");break;case 67:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"diamond");break;case 68:this.$=r[a-5],u.addVertex(r[a-5],r[a-2],"hexagon");break;case 69:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"odd");break;case 70:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"trapezoid");break;case 71:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"inv_trapezoid");break;case 72:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"lean_right");break;case 73:this.$=r[a-3],u.addVertex(r[a-3],r[a-1],"lean_left");break;case 74:this.$=r[a],u.addVertex(r[a]);break;case 75:r[a-1].text=r[a],this.$=r[a-1];break;case 76:case 77:r[a-2].text=r[a-1],this.$=r[a-2];break;case 78:this.$=r[a];break;case 79:var c=u.destructLink(r[a],r[a-2]);this.$={type:c.type,stroke:c.stroke,length:c.length,text:r[a-1]};break;case 80:c=u.destructLink(r[a]);this.$={type:c.type,stroke:c.stroke,length:c.length};break;case 81:this.$=r[a-1];break;case 82:this.$={text:r[a],type:"text"};break;case 83:this.$={text:r[a-1].text+""+r[a],type:r[a-1].type};break;case 84:this.$={text:r[a],type:"text"};break;case 85:this.$={text:r[a],type:"markdown"};break;case 98:case 154:this.$=r[a-1]+""+r[a];break;case 99:case 100:this.$=r[a-4],u.addClass(r[a-2],r[a]);break;case 101:this.$=r[a-4],u.setClass(r[a-2],r[a]);break;case 102:case 110:this.$=r[a-1],u.setClickEvent(r[a-1],r[a]);break;case 103:case 111:this.$=r[a-3],u.setClickEvent(r[a-3],r[a-2]),u.setTooltip(r[a-3],r[a]);break;case 104:this.$=r[a-2],u.setClickEvent(r[a-2],r[a-1],r[a]);break;case 105:this.$=r[a-4],u.setClickEvent(r[a-4],r[a-3],r[a-2]),u.setTooltip(r[a-4],r[a]);break;case 106:case 112:this.$=r[a-1],u.setLink(r[a-1],r[a]);break;case 107:case 113:this.$=r[a-3],u.setLink(r[a-3],r[a-2]),u.setTooltip(r[a-3],r[a]);break;case 108:case 114:this.$=r[a-3],u.setLink(r[a-3],r[a-2],r[a]);break;case 109:case 115:this.$=r[a-5],u.setLink(r[a-5],r[a-4],r[a]),u.setTooltip(r[a-5],r[a-2]);break;case 116:this.$=r[a-4],u.addVertex(r[a-2],void 0,void 0,r[a]);break;case 117:case 119:this.$=r[a-4],u.updateLink(r[a-2],r[a]);break;case 118:this.$=r[a-4],u.updateLink([r[a-2]],r[a]);break;case 120:this.$=r[a-8],u.updateLinkInterpolate([r[a-6]],r[a-2]),u.updateLink([r[a-6]],r[a]);break;case 121:this.$=r[a-8],u.updateLinkInterpolate(r[a-6],r[a-2]),u.updateLink(r[a-6],r[a]);break;case 122:this.$=r[a-6],u.updateLinkInterpolate([r[a-4]],r[a]);break;case 123:this.$=r[a-6],u.updateLinkInterpolate(r[a-4],r[a]);break;case 124:case 126:this.$=[r[a]];break;case 125:case 127:r[a-2].push(r[a]),this.$=r[a-2];break;case 129:this.$=r[a-1]+r[a];break;case 151:this.$=r[a];break;case 152:this.$=r[a-1]+""+r[a];break;case 157:this.$="v";break;case 158:this.$="-";break;case 159:this.$={stmt:"dir",value:"TB"};break;case 160:this.$={stmt:"dir",value:"BT"};break;case 161:this.$={stmt:"dir",value:"RL"};break;case 162:this.$={stmt:"dir",value:"LR"}}},table:[{3:1,4:2,5:3,6:5,12:e,16:4,21:s,22:u,24:i},{1:[3]},{1:[2,1]},{3:10,4:2,5:3,6:5,12:e,16:4,21:s,22:u,24:i},t(r,n,{17:11}),{7:12,13:[1,13]},{16:14,21:s,22:u,24:i},{16:15,21:s,22:u,24:i},{25:[1,16],26:[1,17]},{13:[2,5]},{1:[2,2]},{1:[2,9],18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,43:31,44:A,46:d,48:p,50:35,51:45,52:y,54:46,66:E,67:f,87:k,88:D,89:b,90:g,91:_,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,119:x,120:L,121:R,122:I,123:$,124:N,125:O,126:P,127:U,128:w},{8:64,10:[1,65],15:V},t([10,15],[2,6]),t(r,[2,17]),t(r,[2,18]),t(r,[2,19]),{20:[1,68],21:[1,69],22:M,27:67,30:70},t(G,[2,11]),t(G,[2,12]),t(G,[2,13]),t(G,[2,14]),t(G,[2,15]),t(G,[2,16]),{9:72,20:K,21:j,23:W,49:73,78:77,81:[1,78],82:[1,79]},{9:80,20:K,21:j,23:W},{9:81,20:K,21:j,23:W},{9:82,20:K,21:j,23:W},{9:83,20:K,21:j,23:W},{9:84,20:K,21:j,23:W},{9:86,20:K,21:j,22:[1,85],23:W},t(G,[2,44]),{45:[1,87]},{47:[1,88]},t(G,[2,47]),t(Y,[2,54],{30:89,22:M}),{22:[1,90]},{22:[1,91]},{22:[1,92]},{22:[1,93]},{26:H,52:z,66:Q,67:X,84:[1,97],92:q,98:96,99:[1,94],101:[1,95],106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(G,[2,159]),t(G,[2,160]),t(G,[2,161]),t(G,[2,162]),t(ot,[2,55],{53:[1,116]}),t(lt,[2,74],{117:129,40:[1,117],52:y,55:[1,118],57:[1,119],59:[1,120],61:[1,121],63:[1,122],65:[1,123],66:E,67:f,69:[1,124],71:[1,125],73:[1,126],74:[1,127],76:[1,128],92:F,96:C,106:B,107:T,110:m,112:S,113:v,123:$,124:N,125:O,126:P,127:U,128:w}),t(ht,[2,151]),t(ht,[2,176]),t(ht,[2,177]),t(ht,[2,178]),t(ht,[2,179]),t(ht,[2,180]),t(ht,[2,181]),t(ht,[2,182]),t(ht,[2,183]),t(ht,[2,184]),t(ht,[2,185]),t(ht,[2,186]),t(ht,[2,187]),t(ht,[2,188]),t(ht,[2,189]),t(ht,[2,190]),t(ht,[2,191]),{9:130,20:K,21:j,23:W},{11:131,14:[1,132]},t(At,[2,8]),t(r,[2,20]),t(r,[2,26]),t(r,[2,27]),{21:[1,133]},t(dt,[2,34],{30:134,22:M}),t(G,[2,35]),{50:135,51:45,52:y,54:46,66:E,67:f,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,123:$,124:N,125:O,126:P,127:U,128:w},t(pt,[2,48]),t(pt,[2,49]),t(pt,[2,50]),t(yt,[2,78],{79:136,68:[1,138],80:[1,137]}),{22:Et,24:ft,26:kt,38:Dt,39:139,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t([52,66,67,68,80,92,96,106,107,110,112,113,123,124,125,126,127,128],[2,80]),t(G,[2,36]),t(G,[2,37]),t(G,[2,38]),t(G,[2,39]),t(G,[2,40]),{22:Et,24:ft,26:kt,38:Dt,39:164,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(Ot,n,{17:165}),t(G,[2,45]),t(G,[2,46]),t(Y,[2,53],{52:Pt}),{26:H,52:z,66:Q,67:X,92:q,98:167,103:[1,168],106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{96:[1,169],104:170,106:[1,171]},{26:H,52:z,66:Q,67:X,92:q,96:[1,172],98:173,106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{26:H,52:z,66:Q,67:X,92:q,98:174,106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(At,[2,102],{22:[1,175],100:[1,176]}),t(At,[2,106],{22:[1,177]}),t(At,[2,110],{116:100,118:179,22:[1,178],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,123:ut,124:it,125:rt,126:nt,127:at,128:ct}),t(At,[2,112],{22:[1,180]}),t(Ut,[2,153]),t(Ut,[2,155]),t(Ut,[2,156]),t(Ut,[2,157]),t(Ut,[2,158]),t(wt,[2,163]),t(wt,[2,164]),t(wt,[2,165]),t(wt,[2,166]),t(wt,[2,167]),t(wt,[2,168]),t(wt,[2,169]),t(wt,[2,170]),t(wt,[2,171]),t(wt,[2,172]),t(wt,[2,173]),t(wt,[2,174]),t(wt,[2,175]),{52:y,54:181,66:E,67:f,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,123:$,124:N,125:O,126:P,127:U,128:w},{22:Et,24:ft,26:kt,38:Dt,39:182,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:183,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:185,42:bt,52:z,57:[1,184],66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:186,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:187,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:188,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{66:[1,189]},{22:Et,24:ft,26:kt,38:Dt,39:190,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:191,42:bt,52:z,66:Q,67:X,71:[1,192],73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:193,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:194,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:195,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(ht,[2,152]),t(Vt,[2,3]),{8:196,15:V},{15:[2,7]},t(r,[2,28]),t(dt,[2,33]),t(Y,[2,51],{30:197,22:M}),t(yt,[2,75],{22:[1,198]}),{22:[1,199]},{22:Et,24:ft,26:kt,38:Dt,39:200,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,73:gt,81:_t,82:[1,201],83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(wt,[2,82]),t(wt,[2,84]),t(wt,[2,85]),t(wt,[2,141]),t(wt,[2,142]),t(wt,[2,143]),t(wt,[2,144]),t(wt,[2,145]),t(wt,[2,146]),t(wt,[2,147]),t(wt,[2,148]),t(wt,[2,149]),t(wt,[2,150]),t(wt,[2,86]),t(wt,[2,87]),t(wt,[2,88]),t(wt,[2,89]),t(wt,[2,90]),t(wt,[2,91]),t(wt,[2,92]),t(wt,[2,93]),t(wt,[2,94]),t(wt,[2,95]),t(wt,[2,96]),{9:204,20:K,21:j,22:Et,23:W,24:ft,26:kt,38:Dt,40:[1,203],42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,42:[1,205],43:31,44:A,46:d,48:p,50:35,51:45,52:y,54:46,66:E,67:f,87:k,88:D,89:b,90:g,91:_,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,119:x,120:L,121:R,122:I,123:$,124:N,125:O,126:P,127:U,128:w},{22:M,30:206},{22:[1,207],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,116:100,118:179,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:[1,208]},{22:[1,209]},{22:[1,210],107:[1,211]},t(Mt,[2,124]),{22:[1,212]},{22:[1,213],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,116:100,118:179,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:[1,214],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,116:100,118:179,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{84:[1,215]},t(At,[2,104],{22:[1,216]}),{84:[1,217],102:[1,218]},{84:[1,219]},t(Ut,[2,154]),{84:[1,220],102:[1,221]},t(ot,[2,57],{117:129,52:y,66:E,67:f,92:F,96:C,106:B,107:T,110:m,112:S,113:v,123:$,124:N,125:O,126:P,127:U,128:w}),{22:Et,24:ft,26:kt,38:Dt,41:[1,222],42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,56:[1,223],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:224,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,58:[1,225],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,60:[1,226],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,62:[1,227],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,64:[1,228],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{67:[1,229]},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,70:[1,230],73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,72:[1,231],73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,39:232,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,41:[1,233],42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,73:gt,75:[1,234],77:[1,235],81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,73:gt,75:[1,237],77:[1,236],81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{9:238,20:K,21:j,23:W},t(Y,[2,52],{52:Pt}),t(yt,[2,77]),t(yt,[2,76]),{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,68:[1,239],73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(yt,[2,79]),t(wt,[2,83]),{22:Et,24:ft,26:kt,38:Dt,39:240,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(Ot,n,{17:241}),t(G,[2,43]),{51:242,52:y,54:46,66:E,67:f,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,123:$,124:N,125:O,126:P,127:U,128:w},{22:Gt,66:Kt,67:jt,87:Wt,97:243,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{22:Gt,66:Kt,67:jt,87:Wt,97:257,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{22:Gt,66:Kt,67:jt,87:Wt,97:258,103:Yt,105:[1,259],106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{22:Gt,66:Kt,67:jt,87:Wt,97:260,103:Yt,105:[1,261],106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{106:[1,262]},{22:Gt,66:Kt,67:jt,87:Wt,97:263,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{22:Gt,66:Kt,67:jt,87:Wt,97:264,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{26:H,52:z,66:Q,67:X,92:q,98:265,106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(At,[2,103]),{84:[1,266]},t(At,[2,107],{22:[1,267]}),t(At,[2,108]),t(At,[2,111]),t(At,[2,113],{22:[1,268]}),t(At,[2,114]),t(lt,[2,58]),t(lt,[2,59]),{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,58:[1,269],66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(lt,[2,66]),t(lt,[2,61]),t(lt,[2,62]),t(lt,[2,63]),{66:[1,270]},t(lt,[2,65]),t(lt,[2,67]),{22:Et,24:ft,26:kt,38:Dt,42:bt,52:z,66:Q,67:X,72:[1,271],73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(lt,[2,69]),t(lt,[2,70]),t(lt,[2,72]),t(lt,[2,71]),t(lt,[2,73]),t(Vt,[2,4]),t([22,52,66,67,92,96,106,107,110,112,113,123,124,125,126,127,128],[2,81]),{22:Et,24:ft,26:kt,38:Dt,41:[1,272],42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,42:[1,273],43:31,44:A,46:d,48:p,50:35,51:45,52:y,54:46,66:E,67:f,87:k,88:D,89:b,90:g,91:_,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,119:x,120:L,121:R,122:I,123:$,124:N,125:O,126:P,127:U,128:w},t(ot,[2,56]),t(At,[2,116],{107:Jt}),t(te,[2,126],{109:275,22:Gt,66:Kt,67:jt,87:Wt,103:Yt,106:Ht,110:zt,111:Qt,112:Xt,113:qt,114:Zt}),t(ee,[2,128]),t(ee,[2,130]),t(ee,[2,131]),t(ee,[2,132]),t(ee,[2,133]),t(ee,[2,134]),t(ee,[2,135]),t(ee,[2,136]),t(ee,[2,137]),t(ee,[2,138]),t(ee,[2,139]),t(ee,[2,140]),t(At,[2,117],{107:Jt}),t(At,[2,118],{107:Jt}),{22:[1,276]},t(At,[2,119],{107:Jt}),{22:[1,277]},t(Mt,[2,125]),t(At,[2,99],{107:Jt}),t(At,[2,100],{107:Jt}),t(At,[2,101],{116:100,118:179,26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,123:ut,124:it,125:rt,126:nt,127:at,128:ct}),t(At,[2,105]),{102:[1,278]},{102:[1,279]},{58:[1,280]},{68:[1,281]},{72:[1,282]},{9:283,20:K,21:j,23:W},t(G,[2,42]),{22:Gt,66:Kt,67:jt,87:Wt,103:Yt,106:Ht,108:284,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},t(ee,[2,129]),{26:H,52:z,66:Q,67:X,92:q,98:285,106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{26:H,52:z,66:Q,67:X,92:q,98:286,106:Z,107:J,110:tt,112:et,113:st,116:100,118:98,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(At,[2,109]),t(At,[2,115]),t(lt,[2,60]),{22:Et,24:ft,26:kt,38:Dt,39:287,42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:140,84:Ft,85:Ct,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},t(lt,[2,68]),t(Ot,n,{17:288}),t(te,[2,127],{109:275,22:Gt,66:Kt,67:jt,87:Wt,103:Yt,106:Ht,110:zt,111:Qt,112:Xt,113:qt,114:Zt}),t(At,[2,122],{116:100,118:179,22:[1,289],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,123:ut,124:it,125:rt,126:nt,127:at,128:ct}),t(At,[2,123],{116:100,118:179,22:[1,290],26:H,52:z,66:Q,67:X,92:q,106:Z,107:J,110:tt,112:et,113:st,123:ut,124:it,125:rt,126:nt,127:at,128:ct}),{22:Et,24:ft,26:kt,38:Dt,41:[1,291],42:bt,52:z,66:Q,67:X,73:gt,81:_t,83:202,86:152,87:Bt,88:Tt,89:mt,90:St,91:vt,92:xt,93:Lt,95:143,96:Rt,106:Z,107:J,110:It,112:et,113:st,114:$t,115:Nt,116:149,123:ut,124:it,125:rt,126:nt,127:at,128:ct},{18:18,19:19,20:a,21:c,22:o,23:l,32:24,33:25,34:26,35:27,36:28,37:29,38:h,42:[1,292],43:31,44:A,46:d,48:p,50:35,51:45,52:y,54:46,66:E,67:f,87:k,88:D,89:b,90:g,91:_,92:F,96:C,106:B,107:T,110:m,112:S,113:v,117:47,119:x,120:L,121:R,122:I,123:$,124:N,125:O,126:P,127:U,128:w},{22:Gt,66:Kt,67:jt,87:Wt,97:293,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},{22:Gt,66:Kt,67:jt,87:Wt,97:294,103:Yt,106:Ht,108:244,109:245,110:zt,111:Qt,112:Xt,113:qt,114:Zt},t(lt,[2,64]),t(G,[2,41]),t(At,[2,120],{107:Jt}),t(At,[2,121],{107:Jt})],defaultActions:{2:[2,1],9:[2,5],10:[2,2],132:[2,7]},parseError:function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)},parse:function(t){var e=this,s=[0],u=[],i=[null],r=[],n=this.table,a="",c=0,o=0,l=2,h=1,A=r.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(p.yy[y]=this.yy[y]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var E=d.yylloc;r.push(E);var f=d.options&&d.options.ranges;function k(){var t;return"number"!=typeof(t=u.pop()||d.lex()||h)&&(t instanceof Array&&(t=(u=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var D,b,g,_,F,C,B,T,m={};;){if(b=s[s.length-1],this.defaultActions[b]?g=this.defaultActions[b]:(null==D&&(D=k()),g=n[b]&&n[b][D]),void 0===g||!g.length||!g[0]){var S="";for(F in T=[],n[b])this.terminals_[F]&&F>l&&T.push("'"+this.terminals_[F]+"'");S=d.showPosition?"Parse error on line "+(c+1)+":\n"+d.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[D]||D)+"'":"Parse error on line "+(c+1)+": Unexpected "+(D==h?"end of input":"'"+(this.terminals_[D]||D)+"'"),this.parseError(S,{text:d.match,token:this.terminals_[D]||D,line:d.yylineno,loc:E,expected:T})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+D);switch(g[0]){case 1:s.push(D),i.push(d.yytext),r.push(d.yylloc),s.push(g[1]),D=null,o=d.yyleng,a=d.yytext,c=d.yylineno,E=d.yylloc;break;case 2:if(C=this.productions_[g[1]][1],m.$=i[i.length-C],m._$={first_line:r[r.length-(C||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(C||1)].first_column,last_column:r[r.length-1].last_column},f&&(m._$.range=[r[r.length-(C||1)].range[0],r[r.length-1].range[1]]),void 0!==(_=this.performAction.apply(m,[a,o,c,p.yy,g[1],i,r].concat(A))))return _;C&&(s=s.slice(0,-1*C*2),i=i.slice(0,-1*C),r=r.slice(0,-1*C)),s.push(this.productions_[g[1]][0]),i.push(m.$),r.push(m._$),B=n[s[s.length-2]][s[s.length-1]],s.push(B);break;case 3:return!0}}return!0}},ue={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,s=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 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),s.length-1&&(this.yylineno-=s.length-1);var i=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:s?(s.length===u.length?this.yylloc.first_column:0)+u[u.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var s,u,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(u=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=u.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:u?u[u.length-1].length-u[u.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in i)this[r]=i[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,s,u;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),r=0;re[0].length)){if(e=s,u=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,i[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[u]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(t,e,s,u){switch(s){case 0:return this.begin("open_directive"),12;case 1:return this.begin("type_directive"),13;case 2:return this.popState(),this.begin("arg_directive"),10;case 3:return this.popState(),this.popState(),15;case 4:return 14;case 5:return this.begin("acc_title"),44;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),46;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:this.begin("md_string");break;case 13:return"MD_STR";case 14:this.popState();break;case 15:this.begin("string");break;case 16:this.popState();break;case 17:return"STR";case 18:return 87;case 19:return 96;case 20:return 88;case 21:return 105;case 22:return 89;case 23:return 90;case 24:this.begin("href");break;case 25:this.popState();break;case 26:return 101;case 27:this.begin("callbackname");break;case 28:this.popState();break;case 29:this.popState(),this.begin("callbackargs");break;case 30:return 99;case 31:this.popState();break;case 32:return 100;case 33:this.begin("click");break;case 34:this.popState();break;case 35:return 91;case 36:case 37:case 38:return t.lex.firstGraph()&&this.begin("dir"),24;case 39:return 38;case 40:return 42;case 41:case 42:case 43:case 44:return 102;case 45:return this.popState(),25;case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:case 55:return this.popState(),26;case 56:return 119;case 57:return 120;case 58:return 121;case 59:return 122;case 60:return 106;case 61:return 112;case 62:return 53;case 63:return 67;case 64:return 52;case 65:return 20;case 66:return 107;case 67:return 127;case 68:case 69:case 70:case 71:return 82;case 72:case 73:case 74:return 81;case 75:return 59;case 76:return 60;case 77:return 61;case 78:return 62;case 79:return 63;case 80:return 64;case 81:return 65;case 82:return 69;case 83:return 70;case 84:return 55;case 85:return 56;case 86:return 110;case 87:return 113;case 88:return 128;case 89:return 125;case 90:return 114;case 91:case 92:return 126;case 93:return 115;case 94:return 73;case 95:return 93;case 96:return"SEP";case 97:return 92;case 98:return 66;case 99:return 75;case 100:return 74;case 101:return 77;case 102:return 76;case 103:return 123;case 104:return 124;case 105:return 68;case 106:return 57;case 107:return 58;case 108:return 40;case 109:return 41;case 110:return 71;case 111:return 72;case 112:return 134;case 113:return 21;case 114:return 22;case 115:return 23}},rules:[/^(?:%%\{)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s]+["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*~~[\~]+\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\[)/,/^(?:\]\))/,/^(?:\[\[)/,/^(?:\]\])/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\])/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:-)/,/^(?:\.)/,/^(?:[\_])/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:[A-Za-z]+)/,/^(?:\\\])/,/^(?:\[\/)/,/^(?:\/\])/,/^(?:\[\\)/,/^(?:[!"#$%&'*+,-.`?\\_/])/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\{)/,/^(?:\})/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},callbackargs:{rules:[31,32],inclusive:!1},callbackname:{rules:[28,29,30],inclusive:!1},href:{rules:[25,26],inclusive:!1},click:{rules:[34,35],inclusive:!1},vertex:{rules:[],inclusive:!1},dir:{rules:[45,46,47,48,49,50,51,52,53,54,55],inclusive:!1},acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},md_string:{rules:[13,14],inclusive:!1},string:{rules:[16,17],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,15,18,19,20,21,22,23,24,27,33,36,37,38,39,40,41,42,43,44,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115],inclusive:!0}}};function ie(){this.yy={}}return se.lexer=ue,ie.prototype=se,se.Parser=ie,new ie}();p.parser=p;const y=p;let E,f,k=0,D=t(),b={},g=[],_={},F=[],C={},B={},T=0,m=!0,S=[];const v=t=>o.sanitizeText(t,D),x=function(t,e,s){c.parseDirective(this,t,e,s)},L=function(t){const e=Object.keys(b);for(const s of e)if(b[s].id===t)return b[s].domId;return t},R=function(e,s,u,i,r,n,a={}){let c,o=e;void 0!==o&&0!==o.trim().length&&(void 0===b[o]&&(b[o]={id:o,labelType:"text",domId:"flowchart-"+o+"-"+k,styles:[],classes:[]}),k++,void 0!==s?(D=t(),c=v(s.text.trim()),b[o].labelType=s.type,'"'===c[0]&&'"'===c[c.length-1]&&(c=c.substring(1,c.length-1)),b[o].text=c):void 0===b[o].text&&(b[o].text=e),void 0!==u&&(b[o].type=u),null!=i&&i.forEach((function(t){b[o].styles.push(t)})),null!=r&&r.forEach((function(t){b[o].classes.push(t)})),void 0!==n&&(b[o].dir=n),void 0===b[o].props?b[o].props=a:void 0!==a&&Object.assign(b[o].props,a))},I=function(t,e,s){const u={start:t,end:e,type:void 0,text:"",labelType:"text"};l.info("abc78 Got edge...",u);const i=s.text;void 0!==i&&(u.text=v(i.text.trim()),'"'===u.text[0]&&'"'===u.text[u.text.length-1]&&(u.text=u.text.substring(1,u.text.length-1)),u.labelType=i.type),void 0!==s&&(u.type=s.type,u.stroke=s.stroke,u.length=s.length),g.push(u)},$=function(t,e,s){let u,i;for(l.info("addLink (abc78)",t,e,s),u=0;u/)&&(E="LR"),E.match(/.*v/)&&(E="TB"),"TD"===E&&(E="TB")},w=function(t,e){t.split(",").forEach((function(t){let s=t;void 0!==b[s]&&b[s].classes.push(e),void 0!==C[s]&&C[s].classes.push(e)}))},V=function(t,e,s){t.split(",").forEach((function(t){void 0!==b[t]&&(b[t].link=h.formatUrl(e,D),b[t].linkTarget=s)})),w(t,"clickable")},M=function(t){return B[t]},G=function(e,s,u){e.split(",").forEach((function(e){!function(e,s,u){let i=L(e);if("loose"!==t().securityLevel)return;if(void 0===s)return;let r=[];if("string"==typeof u){r=u.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);d(this).classed("hover",!1)}))};S.push(z);const Q=function(t="gen-1"){b={},_={},g=[],S=[z],F=[],C={},T=0,B=[],m=!0,f=t,A()},X=t=>{f=t||"gen-2"},q=function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"},Z=function(t,e,s){let u=t.text.trim(),i=s.text;t===s&&s.text.match(/\s/)&&(u=void 0);let r=[];const{nodeList:n,dir:a}=function(t){const e={boolean:{},number:{},string:{}},s=[];let u;return{nodeList:t.filter((function(t){const i=typeof t;return t.stmt&&"dir"===t.stmt?(u=t.value,!1):""!==t.trim()&&(i in e?!e[i].hasOwnProperty(t)&&(e[i][t]=!0):!s.includes(t)&&s.push(t))})),dir:u}}(r.concat.apply(r,e));if(r=n,"gen-1"===f)for(let o=0;o2e3)return;if(et[tt]=e,F[e].id===t)return{result:!0,count:0};let u=0,i=1;for(;u=0){const s=st(t,e);if(s.result)return{result:!0,count:i+s.count};i+=s.count}u+=1}return{result:!1,count:i}},ut=function(t){return et[t]},it=function(){tt=-1,F.length>0&&st("none",F.length-1)},rt=function(){return F},nt=()=>!!m&&(m=!1,!0),at=(t,e)=>{const s=(t=>{const e=t.trim();let s=e.slice(0,-1),u="arrow_open";switch(e.slice(-1)){case"x":u="arrow_cross","x"===e[0]&&(u="double_"+u,s=s.slice(1));break;case">":u="arrow_point","<"===e[0]&&(u="double_"+u,s=s.slice(1));break;case"o":u="arrow_circle","o"===e[0]&&(u="double_"+u,s=s.slice(1))}let i="normal",r=s.length-1;"="===s[0]&&(i="thick"),"~"===s[0]&&(i="invisible");let n=((t,e)=>{const s=e.length;let u=0;for(let i=0;i{let e=t.trim(),s="arrow_open";switch(e[0]){case"<":s="arrow_point",e=e.slice(1);break;case"x":s="arrow_cross",e=e.slice(1);break;case"o":s="arrow_circle",e=e.slice(1)}let u="normal";return e.includes("=")&&(u="thick"),e.includes(".")&&(u="dotted"),{type:s,stroke:u}})(e),u.stroke!==s.stroke)return{type:"INVALID",stroke:"INVALID"};if("arrow_open"===u.type)u.type=s.type;else{if(u.type!==s.type)return{type:"INVALID",stroke:"INVALID"};u.type="double_"+u.type}return"double_arrow"===u.type&&(u.type="double_arrow_point"),u.length=s.length,u}return s},ct=(t,e)=>{let s=!1;return t.forEach((t=>{t.nodes.indexOf(e)>=0&&(s=!0)})),s},ot=(t,e)=>{const s=[];return t.nodes.forEach(((u,i)=>{ct(e,u)||s.push(t.nodes[i])})),{nodes:s}},lt={firstGraph:nt},ht={parseDirective:x,defaultConfig:()=>e.flowchart,setAccTitle:s,getAccTitle:u,getAccDescription:i,setAccDescription:r,addVertex:R,lookUpDomId:L,addLink:$,updateLinkInterpolate:N,updateLink:O,addClass:P,setDirection:U,setClass:w,setTooltip:function(t,e){t.split(",").forEach((function(t){void 0!==e&&(B["gen-1"===f?L(t):t]=v(e))}))},getTooltip:M,setClickEvent:G,setLink:V,bindFunctions:K,getDirection:j,getVertices:W,getEdges:Y,getClasses:H,clear:Q,setGen:X,defaultStyle:q,addSubGraph:Z,getDepthFirstPos:ut,indexNodes:it,getSubGraphs:rt,destructLink:at,lex:lt,exists:ct,makeUniq:ot,setDiagramTitle:n,getDiagramTitle:a},At=Object.freeze(Object.defineProperty({__proto__:null,addClass:P,addLink:$,addSingleLink:I,addSubGraph:Z,addVertex:R,bindFunctions:K,clear:Q,default:ht,defaultStyle:q,destructLink:at,firstGraph:nt,getClasses:H,getDepthFirstPos:ut,getDirection:j,getEdges:Y,getSubGraphs:rt,getTooltip:M,getVertices:W,indexNodes:it,lex:lt,lookUpDomId:L,parseDirective:x,setClass:w,setClickEvent:G,setDirection:U,setGen:X,setLink:V,updateLink:O,updateLinkInterpolate:N},Symbol.toStringTag,{value:"Module"}));export{At as d,ht as f,y as p}; diff --git a/assets/flowDiagram-702318ad.9fc2e165.js b/assets/flowDiagram-702318ad.9fc2e165.js deleted file mode 100644 index d64017c85..000000000 --- a/assets/flowDiagram-702318ad.9fc2e165.js +++ /dev/null @@ -1 +0,0 @@ -import{p as s,f as a}from"./flowDb-a707052f.485b60ac.js";import{h as r,u as t,r as o,p as e,l as f,d as c,f as i,G as m}from"./layout.2f099f66.js";import{h as l,o as d,p as n,q as p,c as j,j as b,l as w,r as u,t as h}from"./mermaid.core.a66200b0.js";import{a as g,b as x,i as y,c as k,e as v,d as A,f as D,g as G}from"./styles-40ddcbf3.5ed229ca.js";import{l as M}from"./line.f17bed9e.js";import{s as T}from"./selectAll.11c20240.js";import"./index-05087a90.4347f31d.js";import"./edges-97052da4.ceadb26f.js";import"./createText-2f679d62.584f3edd.js";import"./svgDraw-6750006d.4f7863f3.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";function q(s){if(!s.ok)throw new Error(s.status+" "+s.statusText);return s.text()}var E;E="image/svg+xml";const O={},z=function(s){const a=Object.keys(s);for(const r of a)O[r]=s[r]},B={parser:s,db:a,renderer:D,styles:G,init:s=>{s.flowchart||(s.flowchart={}),s.flowchart.arrowMarkerAbsolute=s.arrowMarkerAbsolute,z(s.flowchart),a.clear(),a.setGen("gen-1")}};export{B as diagram}; diff --git a/assets/flowDiagram-702318ad.c596a7e8.js b/assets/flowDiagram-702318ad.c596a7e8.js new file mode 100644 index 000000000..dd9d03731 --- /dev/null +++ b/assets/flowDiagram-702318ad.c596a7e8.js @@ -0,0 +1 @@ +import{p as s,f as a}from"./flowDb-a707052f.baad4ae4.js";import{h as r,u as t,r as o,p as e,l as f,d as c,f as i,G as m}from"./layout.02c3e151.js";import{h as l,o as n,p,q as d,c as j,j as b,l as w,r as u,t as h}from"./mermaid.core.3a590193.js";import{a as g,b as x,i as y,c as k,e as v,d as A,f as D,g as G}from"./styles-40ddcbf3.551e5741.js";import{l as M}from"./line.53b161c2.js";import{s as T}from"./selectAll.256eca5b.js";import"./index-05087a90.017bdfe5.js";import"./edges-97052da4.e255927b.js";import"./createText-2f679d62.a374f608.js";import"./svgDraw-6750006d.f814d75b.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";function q(s){if(!s.ok)throw new Error(s.status+" "+s.statusText);return s.text()}var E;E="image/svg+xml";const O={},z=function(s){const a=Object.keys(s);for(const r of a)O[r]=s[r]},B={parser:s,db:a,renderer:D,styles:G,init:s=>{s.flowchart||(s.flowchart={}),s.flowchart.arrowMarkerAbsolute=s.arrowMarkerAbsolute,z(s.flowchart),a.clear(),a.setGen("gen-1")}};export{B as diagram}; diff --git a/assets/flowDiagram-v2-8716a26e.0519cf3e.js b/assets/flowDiagram-v2-8716a26e.0519cf3e.js deleted file mode 100644 index f5d032c63..000000000 --- a/assets/flowDiagram-v2-8716a26e.0519cf3e.js +++ /dev/null @@ -1 +0,0 @@ -import{p as r,f as e}from"./flowDb-a707052f.485b60ac.js";import{f as a,g as o}from"./styles-40ddcbf3.5ed229ca.js";import{a8 as t}from"./mermaid.core.a66200b0.js";import"./layout.2f099f66.js";import"./index-05087a90.4347f31d.js";import"./edges-97052da4.ceadb26f.js";import"./createText-2f679d62.584f3edd.js";import"./svgDraw-6750006d.4f7863f3.js";import"./line.f17bed9e.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";import"./selectAll.11c20240.js";const s={parser:r,db:e,renderer:a,styles:o,init:r=>{r.flowchart||(r.flowchart={}),r.flowchart.arrowMarkerAbsolute=r.arrowMarkerAbsolute,t({flowchart:{arrowMarkerAbsolute:r.arrowMarkerAbsolute}}),a.setConf(r.flowchart),e.clear(),e.setGen("gen-2")}};export{s as diagram}; diff --git a/assets/flowDiagram-v2-8716a26e.61097f7a.js b/assets/flowDiagram-v2-8716a26e.61097f7a.js new file mode 100644 index 000000000..cffc5d7af --- /dev/null +++ b/assets/flowDiagram-v2-8716a26e.61097f7a.js @@ -0,0 +1 @@ +import{p as r,f as e}from"./flowDb-a707052f.baad4ae4.js";import{f as a,g as o}from"./styles-40ddcbf3.551e5741.js";import{a8 as t}from"./mermaid.core.3a590193.js";import"./layout.02c3e151.js";import"./index-05087a90.017bdfe5.js";import"./edges-97052da4.e255927b.js";import"./createText-2f679d62.a374f608.js";import"./svgDraw-6750006d.f814d75b.js";import"./line.53b161c2.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";import"./selectAll.256eca5b.js";const s={parser:r,db:e,renderer:a,styles:o,init:r=>{r.flowchart||(r.flowchart={}),r.flowchart.arrowMarkerAbsolute=r.arrowMarkerAbsolute,t({flowchart:{arrowMarkerAbsolute:r.arrowMarkerAbsolute}}),a.setConf(r.flowchart),e.clear(),e.setGen("gen-2")}};export{s as diagram}; diff --git a/assets/flowchart-elk-definition-206a7d68.1cfd1a2c.js b/assets/flowchart-elk-definition-206a7d68.4a925c35.js similarity index 99% rename from assets/flowchart-elk-definition-206a7d68.1cfd1a2c.js rename to assets/flowchart-elk-definition-206a7d68.4a925c35.js index 87cf93791..b6e91ae6e 100644 --- a/assets/flowchart-elk-definition-206a7d68.1cfd1a2c.js +++ b/assets/flowchart-elk-definition-206a7d68.4a925c35.js @@ -1 +1 @@ -import{d as n,p as t}from"./flowDb-a707052f.485b60ac.js";import{l as e,h as i,c as r,t as c,p as a,r as u,o,j as s}from"./mermaid.core.a66200b0.js";import{i as h,a as f,l,b}from"./edges-97052da4.ceadb26f.js";import{Y as w,Z as d,_ as g}from"./app.755d843f.js";import{l as p}from"./line.f17bed9e.js";import"./createText-2f679d62.584f3edd.js";import"./svgDraw-6750006d.4f7863f3.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";var v={exports:{}};v.exports=function(){function n(t,e,i){function r(a,u){if(!e[a]){if(!t[a]){var o="function"==typeof g&&g;if(!u&&o)return o(a,!0);if(c)return c(a,!0);var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}var h=e[a]={exports:{}};t[a][0].call(h.exports,(function(n){return r(t[a][1][n]||n)}),h,h.exports,n,t,e,i)}return e[a].exports}for(var c="function"==typeof g&&g,a=0;a0&&void 0!==arguments[0]?arguments[0]:{},i=e.defaultLayoutOptions,c=void 0===i?{}:i,u=e.algorithms,o=void 0===u?["layered","stress","mrtree","radial","force","disco","sporeOverlap","sporeCompaction","rectpacking"]:u,s=e.workerFactory,h=e.workerUrl;if(r(this,n),this.defaultLayoutOptions=c,this.initialized=!1,void 0===h&&void 0===s)throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");var f=s;void 0!==h&&void 0===s&&(f=function(n){return new Worker(n)});var l=f(h);if("function"!=typeof l.postMessage)throw new TypeError("Created worker does not provide the required 'postMessage' function.");this.worker=new a(l),this.worker.postMessage({cmd:"register",algorithms:o}).then((function(n){return t.initialized=!0})).catch(console.err)}return i(n,[{key:"layout",value:function(n){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=t.layoutOptions,i=void 0===e?this.defaultLayoutOptions:e,r=t.logging,c=void 0!==r&&r,a=t.measureExecutionTime,u=void 0!==a&&a;return n?this.worker.postMessage({cmd:"layout",graph:n,layoutOptions:i,options:{logging:c,measureExecutionTime:u}}):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()}}]),n}();e.default=c;var a=function(){function n(t){var e=this;if(r(this,n),void 0===t)throw new Error("Missing mandatory parameter 'worker'.");this.resolvers={},this.worker=t,this.worker.onmessage=function(n){setTimeout((function(){e.receive(e,n)}),0)}}return i(n,[{key:"postMessage",value:function(n){var t=this.id||0;this.id=t+1,n.id=t;var e=this;return new Promise((function(i,r){e.resolvers[t]=function(n,t){n?(e.convertGwtStyleError(n),r(n)):i(t)},e.worker.postMessage(n)}))}},{key:"receive",value:function(n,t){var e=t.data,i=n.resolvers[e.id];i&&(delete n.resolvers[e.id],e.error?i(e.error):i(null,e.data))}},{key:"terminate",value:function(){this.worker.terminate&&this.worker.terminate()}},{key:"convertGwtStyleError",value:function(n){if(n){var t=n.__java$exception;t&&(t.cause&&t.cause.backingJsObject&&(n.cause=t.cause.backingJsObject,this.convertGwtStyleError(n.cause)),delete n.__java$exception)}}}]),n}()},{}],2:[function(n,t,e){(function(n){(function(){var i;function r(){}function c(){}function a(){}function u(){}function o(){}function s(){}function h(){}function f(){}function l(){}function b(){}function w(){}function d(){}function g(){}function p(){}function v(){}function m(){}function y(){}function k(){}function j(){}function E(){}function T(){}function M(){}function S(){}function P(){}function I(){}function C(){}function O(){}function A(){}function $(){}function L(){}function N(){}function x(){}function D(){}function R(){}function K(){}function _(){}function F(){}function B(){}function H(){}function q(){}function G(){}function z(){}function U(){}function X(){}function W(){}function V(){}function Q(){}function J(){}function Y(){}function Z(){}function nn(){}function tn(){}function en(){}function rn(){}function cn(){}function an(){}function un(){}function on(){}function sn(){}function hn(){}function fn(){}function ln(){}function bn(){}function wn(){}function dn(){}function gn(){}function pn(){}function vn(){}function mn(){}function yn(){}function kn(){}function jn(){}function En(){}function Tn(){}function Mn(){}function Sn(){}function Pn(){}function In(){}function Cn(){}function On(){}function An(){}function $n(){}function Ln(){}function Nn(){}function xn(){}function Dn(){}function Rn(){}function Kn(){}function _n(){}function Fn(){}function Bn(){}function Hn(){}function qn(){}function Gn(){}function zn(){}function Un(){}function Xn(){}function Wn(){}function Vn(){}function Qn(){}function Jn(){}function Yn(){}function Zn(){}function nt(){}function tt(){}function et(){}function it(){}function rt(){}function ct(){}function at(){}function ut(){}function ot(){}function st(){}function ht(){}function ft(){}function lt(){}function bt(){}function wt(){}function dt(){}function gt(){}function pt(){}function vt(){}function mt(){}function yt(){}function kt(){}function jt(){}function Et(){}function Tt(){}function Mt(){}function St(){}function Pt(){}function It(){}function Ct(){}function Ot(){}function At(){}function $t(){}function Lt(){}function Nt(){}function xt(){}function Dt(){}function Rt(){}function Kt(){}function _t(){}function Ft(){}function Bt(){}function Ht(){}function qt(){}function Gt(){}function zt(){}function Ut(){}function Xt(){}function Wt(){}function Vt(){}function Qt(){}function Jt(){}function Yt(){}function Zt(){}function ne(){}function te(){}function ee(){}function ie(){}function re(){}function ce(){}function ae(){}function ue(){}function oe(){}function se(){}function he(){}function fe(){}function le(){}function be(){}function we(){}function de(){}function ge(){}function pe(){}function ve(){}function me(){}function ye(){}function ke(){}function je(){}function Ee(){}function Te(){}function Me(){}function Se(){}function Pe(){}function Ie(){}function Ce(){}function Oe(){}function Ae(){}function $e(){}function Le(){}function Ne(){}function xe(){}function De(){}function Re(){}function Ke(){}function _e(){}function Fe(){}function Be(){}function He(){}function qe(){}function Ge(){}function ze(){}function Ue(){}function Xe(){}function We(){}function Ve(){}function Qe(){}function Je(){}function Ye(){}function Ze(){}function ni(){}function ti(){}function ei(){}function ii(){}function ri(){}function ci(){}function ai(){}function ui(){}function oi(){}function si(){}function hi(){}function fi(){}function li(){}function bi(){}function wi(){}function di(){}function gi(){}function pi(){}function vi(){}function mi(){}function yi(){}function ki(){}function ji(){}function Ei(){}function Ti(){}function Mi(){}function Si(){}function Pi(){}function Ii(){}function Ci(){}function Oi(){}function Ai(){}function $i(){}function Li(){}function Ni(){}function xi(){}function Di(){}function Ri(){}function Ki(){}function _i(){}function Fi(){}function Bi(){}function Hi(){}function qi(){}function Gi(){}function zi(){}function Ui(){}function Xi(){}function Wi(){}function Vi(){}function Qi(){}function Ji(){}function Yi(){}function Zi(){}function nr(){}function tr(){}function er(){}function ir(){}function rr(){}function cr(){}function ar(){}function ur(){}function or(){}function sr(){}function hr(){}function fr(){}function lr(){}function br(){}function wr(){}function dr(){}function gr(){}function pr(){}function vr(){}function mr(){}function yr(){}function kr(){}function jr(){}function Er(){}function Tr(){}function Mr(){}function Sr(){}function Pr(){}function Ir(){}function Cr(){}function Or(){}function Ar(){}function $r(){}function Lr(){}function Nr(){}function xr(){}function Dr(){}function Rr(){}function Kr(){}function _r(){}function Fr(){}function Br(){}function Hr(){}function qr(){}function Gr(){}function zr(){}function Ur(){}function Xr(){}function Wr(){}function Vr(){}function Qr(){}function Jr(){}function Yr(){}function Zr(){}function nc(){}function tc(){}function ec(){}function ic(){}function rc(){}function cc(){}function ac(){}function uc(){}function oc(){}function sc(){}function hc(){}function fc(){}function lc(){}function bc(){}function wc(){}function dc(){}function gc(){}function pc(){}function vc(){}function mc(){}function yc(){}function kc(){}function jc(){}function Ec(){}function Tc(){}function Mc(){}function Sc(){}function Pc(){}function Ic(){}function Cc(){}function Oc(){}function Ac(){}function $c(){}function Lc(){}function Nc(){}function xc(){}function Dc(){}function Rc(){}function Kc(){}function _c(){}function Fc(){}function Bc(){}function Hc(){}function qc(){}function Gc(){}function zc(){}function Uc(){}function Xc(){}function Wc(){}function Vc(){}function Qc(){}function Jc(){}function Yc(){}function Zc(){}function na(){}function ta(){}function ea(){}function ia(){}function ra(){}function ca(){}function aa(){}function ua(){}function oa(){}function sa(){}function ha(){}function fa(){}function la(){}function ba(){}function wa(){}function da(){}function ga(){}function pa(){}function va(){}function ma(){}function ya(){}function ka(){}function ja(){}function Ea(){}function Ta(){}function Ma(){}function Sa(){}function Pa(){}function Ia(){}function Ca(){}function Oa(){}function Aa(){}function $a(){}function La(){}function Na(){}function xa(){}function Da(){}function Ra(){}function Ka(){}function _a(){}function Fa(){}function Ba(){}function Ha(){}function qa(){}function Ga(){}function za(){}function Ua(){}function Xa(){}function Wa(){}function Va(){}function Qa(){}function Ja(){}function Ya(){}function Za(){}function nu(){}function tu(){}function eu(){}function iu(){}function ru(){}function cu(){}function au(){}function uu(){}function ou(){}function su(){}function hu(){}function fu(){}function lu(){}function bu(){}function wu(){}function du(){}function gu(){}function pu(){}function vu(){}function mu(){}function yu(){}function ku(){}function ju(){}function Eu(){}function Tu(){}function Mu(){}function Su(){}function Pu(){}function Iu(){}function Cu(){}function Ou(){}function Au(){}function $u(){}function Lu(){}function Nu(){}function xu(){}function Du(){}function Ru(){}function Ku(){}function _u(){}function Fu(){}function Bu(){}function Hu(){}function qu(){}function Gu(){}function zu(){}function Uu(){}function Xu(){}function Wu(){}function Vu(){}function Qu(){}function Ju(){}function Yu(){}function Zu(){}function no(){}function to(){}function eo(){}function io(){}function ro(){}function co(){}function ao(){}function uo(){}function oo(){}function so(){}function ho(){}function fo(){}function lo(){}function bo(){}function wo(){}function go(){}function po(){}function vo(){}function mo(){}function yo(){}function ko(){}function jo(){}function Eo(){}function To(){}function Mo(){}function So(){}function Po(){}function Io(){}function Co(){}function Oo(){}function Ao(){}function $o(){}function Lo(){}function No(){}function xo(){}function Do(){}function Ro(){}function Ko(){}function _o(){}function Fo(){}function Bo(){}function Ho(){}function qo(){}function Go(){}function zo(){}function Uo(){}function Xo(){}function Wo(){}function Vo(){}function Qo(){}function Jo(){}function Yo(){}function Zo(){}function ns(){}function ts(){}function es(){}function is(){}function rs(){}function cs(){}function as(){}function us(){}function os(){}function ss(){}function hs(){}function fs(){}function ls(){}function bs(){}function ws(){}function ds(){}function gs(){}function ps(){}function vs(){}function ms(){}function ys(){}function ks(){}function js(){}function Es(){}function Ts(){}function Ms(){}function Ss(){}function Ps(){}function Is(){}function Cs(){}function Os(){}function As(){}function $s(){}function Ls(){}function Ns(){}function xs(){}function Ds(){}function Rs(){}function Ks(){}function _s(){}function Fs(){}function Bs(){}function Hs(){}function qs(){}function Gs(){}function zs(){}function Us(){}function Xs(){}function Ws(){}function Vs(){}function Qs(){}function Js(){}function Ys(){}function Zs(){}function nh(){}function th(){}function eh(){}function ih(){}function rh(){}function ch(){}function ah(){}function uh(){}function oh(){}function sh(){}function hh(){}function fh(){}function lh(){}function bh(){}function wh(){}function dh(){}function gh(){}function ph(){}function vh(){}function mh(){}function yh(){}function kh(){}function jh(){}function Eh(){}function Th(){}function Mh(){}function Sh(){}function Ph(){}function Ih(){}function Ch(){}function Oh(){}function Ah(){}function $h(){}function Lh(){}function Nh(){}function xh(){}function Dh(){}function Rh(){}function Kh(){}function _h(){ty()}function Fh(){Hsn()}function Bh(){kpn()}function Hh(){Rkn()}function qh(){ySn()}function Gh(){sRn()}function zh(){Dyn()}function Uh(){ekn()}function Xh(){kM()}function Wh(){pM()}function Vh(){B_()}function Qh(){jM()}function Jh(){Prn()}function Yh(){TM()}function Zh(){P6()}function nf(){Min()}function tf(){W8()}function ef(){RZ()}function rf(){qsn()}function cf(){RMn()}function af(){Sin()}function uf(){G2()}function of(){sWn()}function sf(){Hyn()}function hf(){KZ()}function ff(){FXn()}function lf(){xZ()}function bf(){Pin()}function wf(){Vun()}function df(){HZ()}function gf(){S9()}function pf(){MM()}function vf(){DAn()}function mf(){Gyn()}function yf(){Kcn()}function kf(){EMn()}function jf(){fRn()}function Ef(){_vn()}function Tf(){SAn()}function Mf(){xan()}function Sf(){FZ()}function Pf(){u_n()}function If(){OAn()}function Cf(){U$n()}function Of(){L9()}function Af(){TMn()}function $f(){uWn()}function Lf(){zsn()}function Nf(){gdn()}function xf(){BBn()}function Df(){c_()}function Rf(){lcn()}function Kf(){sFn()}function _f(n){mW(n)}function Ff(n){this.a=n}function Bf(n){this.a=n}function Hf(n){this.a=n}function qf(n){this.a=n}function Gf(n){this.a=n}function zf(n){this.a=n}function Uf(n){this.a=n}function Xf(n){this.a=n}function Wf(n){this.a=n}function Vf(n){this.a=n}function Qf(n){this.a=n}function Jf(n){this.a=n}function Yf(n){this.a=n}function Zf(n){this.a=n}function nl(n){this.a=n}function tl(n){this.a=n}function el(n){this.a=n}function il(n){this.a=n}function rl(n){this.a=n}function cl(n){this.a=n}function al(n){this.a=n}function ul(n){this.b=n}function ol(n){this.c=n}function sl(n){this.a=n}function hl(n){this.a=n}function fl(n){this.a=n}function ll(n){this.a=n}function bl(n){this.a=n}function wl(n){this.a=n}function dl(n){this.a=n}function gl(n){this.a=n}function pl(n){this.a=n}function vl(n){this.a=n}function ml(n){this.a=n}function yl(n){this.a=n}function kl(n){this.a=n}function jl(n){this.a=n}function El(n){this.a=n}function Tl(n){this.a=n}function Ml(n){this.a=n}function Sl(){this.a=[]}function Pl(n,t){n.a=t}function Il(n,t){n.a=t}function Cl(n,t){n.b=t}function Ol(n,t){n.b=t}function Al(n,t){n.b=t}function $l(n,t){n.j=t}function Ll(n,t){n.g=t}function Nl(n,t){n.i=t}function xl(n,t){n.c=t}function Dl(n,t){n.d=t}function Rl(n,t){n.d=t}function Kl(n,t){n.c=t}function _l(n,t){n.k=t}function Fl(n,t){n.c=t}function Bl(n,t){n.c=t}function Hl(n,t){n.a=t}function ql(n,t){n.a=t}function Gl(n,t){n.f=t}function zl(n,t){n.a=t}function Ul(n,t){n.b=t}function Xl(n,t){n.d=t}function Wl(n,t){n.i=t}function Vl(n,t){n.o=t}function Ql(n,t){n.r=t}function Jl(n,t){n.a=t}function Yl(n,t){n.b=t}function Zl(n,t){n.e=t}function nb(n,t){n.f=t}function tb(n,t){n.g=t}function eb(n,t){n.e=t}function ib(n,t){n.f=t}function rb(n,t){n.f=t}function cb(n,t){n.n=t}function ab(n,t){n.a=t}function ub(n,t){n.a=t}function ob(n,t){n.c=t}function sb(n,t){n.c=t}function hb(n,t){n.d=t}function fb(n,t){n.e=t}function lb(n,t){n.g=t}function bb(n,t){n.a=t}function wb(n,t){n.c=t}function db(n,t){n.d=t}function gb(n,t){n.e=t}function pb(n,t){n.f=t}function vb(n,t){n.j=t}function mb(n,t){n.a=t}function yb(n,t){n.b=t}function kb(n,t){n.a=t}function jb(n){n.b=n.a}function Eb(n){n.c=n.d.d}function Tb(n){this.d=n}function Mb(n){this.a=n}function Sb(n){this.a=n}function Pb(n){this.a=n}function Ib(n){this.a=n}function Cb(n){this.a=n}function Ob(n){this.a=n}function Ab(n){this.a=n}function $b(n){this.a=n}function Lb(n){this.a=n}function Nb(n){this.a=n}function xb(n){this.a=n}function Db(n){this.a=n}function Rb(n){this.a=n}function Kb(n){this.a=n}function _b(n){this.b=n}function Fb(n){this.b=n}function Bb(n){this.b=n}function Hb(n){this.a=n}function qb(n){this.a=n}function Gb(n){this.a=n}function zb(n){this.c=n}function Ub(n){this.c=n}function Xb(n){this.c=n}function Wb(n){this.a=n}function Vb(n){this.a=n}function Qb(n){this.a=n}function Jb(n){this.a=n}function Yb(n){this.a=n}function Zb(n){this.a=n}function nw(n){this.a=n}function tw(n){this.a=n}function ew(n){this.a=n}function iw(n){this.a=n}function rw(n){this.a=n}function cw(n){this.a=n}function aw(n){this.a=n}function uw(n){this.a=n}function ow(n){this.a=n}function sw(n){this.a=n}function hw(n){this.a=n}function fw(n){this.a=n}function lw(n){this.a=n}function bw(n){this.a=n}function ww(n){this.a=n}function dw(n){this.a=n}function gw(n){this.a=n}function pw(n){this.a=n}function vw(n){this.a=n}function mw(n){this.a=n}function yw(n){this.a=n}function kw(n){this.a=n}function jw(n){this.a=n}function Ew(n){this.a=n}function Tw(n){this.a=n}function Mw(n){this.a=n}function Sw(n){this.a=n}function Pw(n){this.a=n}function Iw(n){this.a=n}function Cw(n){this.a=n}function Ow(n){this.a=n}function Aw(n){this.a=n}function $w(n){this.a=n}function Lw(n){this.a=n}function Nw(n){this.a=n}function xw(n){this.a=n}function Dw(n){this.a=n}function Rw(n){this.a=n}function Kw(n){this.a=n}function _w(n){this.e=n}function Fw(n){this.a=n}function Bw(n){this.a=n}function Hw(n){this.a=n}function qw(n){this.a=n}function Gw(n){this.a=n}function zw(n){this.a=n}function Uw(n){this.a=n}function Xw(n){this.a=n}function Ww(n){this.a=n}function Vw(n){this.a=n}function Qw(n){this.a=n}function Jw(n){this.a=n}function Yw(n){this.a=n}function Zw(n){this.a=n}function nd(n){this.a=n}function td(n){this.a=n}function ed(n){this.a=n}function id(n){this.a=n}function rd(n){this.a=n}function cd(n){this.a=n}function ad(n){this.a=n}function ud(n){this.a=n}function od(n){this.a=n}function sd(n){this.a=n}function hd(n){this.a=n}function fd(n){this.a=n}function ld(n){this.a=n}function bd(n){this.a=n}function wd(n){this.a=n}function dd(n){this.a=n}function gd(n){this.a=n}function pd(n){this.a=n}function vd(n){this.a=n}function md(n){this.a=n}function yd(n){this.a=n}function kd(n){this.a=n}function jd(n){this.a=n}function Ed(n){this.a=n}function Td(n){this.a=n}function Md(n){this.a=n}function Sd(n){this.a=n}function Pd(n){this.a=n}function Id(n){this.a=n}function Cd(n){this.a=n}function Od(n){this.a=n}function Ad(n){this.a=n}function $d(n){this.a=n}function Ld(n){this.a=n}function Nd(n){this.a=n}function xd(n){this.a=n}function Dd(n){this.a=n}function Rd(n){this.a=n}function Kd(n){this.a=n}function _d(n){this.c=n}function Fd(n){this.b=n}function Bd(n){this.a=n}function Hd(n){this.a=n}function qd(n){this.a=n}function Gd(n){this.a=n}function zd(n){this.a=n}function Ud(n){this.a=n}function Xd(n){this.a=n}function Wd(n){this.a=n}function Vd(n){this.a=n}function Qd(n){this.a=n}function Jd(n){this.a=n}function Yd(n){this.a=n}function Zd(n){this.a=n}function ng(n){this.a=n}function tg(n){this.a=n}function eg(n){this.a=n}function ig(n){this.a=n}function rg(n){this.a=n}function cg(n){this.a=n}function ag(n){this.a=n}function ug(n){this.a=n}function og(n){this.a=n}function sg(n){this.a=n}function hg(n){this.a=n}function fg(n){this.a=n}function lg(n){this.a=n}function bg(n){this.a=n}function wg(n){this.a=n}function dg(n){this.a=n}function gg(n){this.a=n}function pg(n){this.a=n}function vg(n){this.a=n}function mg(n){this.a=n}function yg(n){this.a=n}function kg(n){this.a=n}function jg(n){this.a=n}function Eg(n){this.a=n}function Tg(n){this.a=n}function Mg(n){this.a=n}function Sg(n){this.a=n}function Pg(n){this.a=n}function Ig(n){this.a=n}function Cg(n){this.a=n}function Og(n){this.a=n}function Ag(n){this.a=n}function $g(n){this.a=n}function Lg(n){this.a=n}function Ng(n){this.a=n}function xg(n){this.a=n}function Dg(n){this.a=n}function Rg(n){this.a=n}function Kg(n){this.a=n}function _g(n){this.a=n}function Fg(n){this.a=n}function Bg(n){this.a=n}function Hg(n){this.a=n}function qg(n){this.a=n}function Gg(n){this.a=n}function zg(n){this.a=n}function Ug(n){this.a=n}function Xg(n){this.a=n}function Wg(n){this.a=n}function Vg(n){this.a=n}function Qg(n){this.a=n}function Jg(n){this.a=n}function Yg(n){this.a=n}function Zg(n){this.a=n}function np(n){this.a=n}function tp(n){this.a=n}function ep(n){this.a=n}function ip(n){this.a=n}function rp(n){this.a=n}function cp(n){this.b=n}function ap(n){this.f=n}function up(n){this.a=n}function op(n){this.a=n}function sp(n){this.a=n}function hp(n){this.a=n}function fp(n){this.a=n}function lp(n){this.a=n}function bp(n){this.a=n}function wp(n){this.a=n}function dp(n){this.a=n}function gp(n){this.a=n}function pp(n){this.a=n}function vp(n){this.b=n}function mp(n){this.c=n}function yp(n){this.e=n}function kp(n){this.a=n}function jp(n){this.a=n}function Ep(n){this.a=n}function Tp(n){this.a=n}function Mp(n){this.a=n}function Sp(n){this.d=n}function Pp(n){this.a=n}function Ip(n){this.a=n}function Cp(n){this.e=n}function Op(){this.a=0}function Ap(){NA(this)}function $p(){LA(this)}function Lp(){OU(this)}function Np(){lV(this)}function xp(){}function Dp(){this.c=O$t}function Rp(n,t){t.Wb(n)}function Kp(n,t){n.b+=t}function _p(n){n.b=new ak}function Fp(n){return n.e}function Bp(n){return n.a}function Hp(n){return n.a}function qp(n){return n.a}function Gp(n){return n.a}function zp(n){return n.a}function Up(){return null}function Xp(){return null}function Wp(){rE(),bXn()}function Vp(n){n.b.tf(n.e)}function Qp(n,t){n.b=t-n.b}function Jp(n,t){n.a=t-n.a}function Yp(n,t){t.ad(n.a)}function Zp(n,t){BIn(t,n)}function nv(n,t,e){n.Od(e,t)}function tv(n,t){n.e=t,t.b=n}function ev(n){u_(),this.a=n}function iv(n){u_(),this.a=n}function rv(n){u_(),this.a=n}function cv(n){UX(),this.a=n}function av(n){MJ(),ntt.be(n)}function uv(){wN.call(this)}function ov(){wN.call(this)}function sv(){uv.call(this)}function hv(){uv.call(this)}function fv(){uv.call(this)}function lv(){uv.call(this)}function bv(){uv.call(this)}function wv(){uv.call(this)}function dv(){uv.call(this)}function gv(){uv.call(this)}function pv(){uv.call(this)}function vv(){uv.call(this)}function mv(){uv.call(this)}function yv(){this.a=this}function kv(){this.Bb|=256}function jv(){this.b=new MO}function Ev(){Ev=O,new Lp}function Tv(){sv.call(this)}function Mv(n,t){n.length=t}function Sv(n,t){UB(n.a,t)}function Pv(n,t){GSn(n.c,t)}function Iv(n,t){jU(n.b,t)}function Cv(n,t){Pvn(n.a,t)}function Ov(n,t){Iln(n.a,t)}function Av(n,t){fan(n.e,t)}function $v(n){COn(n.c,n.b)}function Lv(n,t){n.kc().Nb(t)}function Nv(n){this.a=wbn(n)}function xv(){this.a=new Lp}function Dv(){this.a=new Lp}function Rv(){this.a=new $p}function Kv(){this.a=new $p}function _v(){this.a=new $p}function Fv(){this.a=new kn}function Bv(){this.a=new m6}function Hv(){this.a=new bt}function qv(){this.a=new UT}function Gv(){this.a=new N0}function zv(){this.a=new iZ}function Uv(){this.a=new CR}function Xv(){this.a=new $p}function Wv(){this.a=new $p}function Vv(){this.a=new $p}function Qv(){this.a=new $p}function Jv(){this.d=new $p}function Yv(){this.a=new xv}function Zv(){this.a=new Lp}function nm(){this.b=new Lp}function tm(){this.b=new $p}function em(){this.e=new $p}function im(){this.d=new $p}function rm(){this.a=new cf}function cm(){$p.call(this)}function am(){Rv.call(this)}function um(){$R.call(this)}function om(){Wv.call(this)}function sm(){hm.call(this)}function hm(){xp.call(this)}function fm(){xp.call(this)}function lm(){fm.call(this)}function bm(){bJ.call(this)}function wm(){bJ.call(this)}function dm(){Um.call(this)}function gm(){Um.call(this)}function pm(){Um.call(this)}function vm(){Xm.call(this)}function mm(){VT.call(this)}function ym(){eo.call(this)}function km(){eo.call(this)}function jm(){Ym.call(this)}function Em(){Ym.call(this)}function Tm(){Lp.call(this)}function Mm(){Lp.call(this)}function Sm(){Lp.call(this)}function Pm(){xv.call(this)}function Im(){yin.call(this)}function Cm(){kv.call(this)}function Om(){IL.call(this)}function Am(){IL.call(this)}function $m(){Lp.call(this)}function Lm(){Lp.call(this)}function Nm(){Lp.call(this)}function xm(){yo.call(this)}function Dm(){yo.call(this)}function Rm(){xm.call(this)}function Km(){Dh.call(this)}function _m(n){btn.call(this,n)}function Fm(n){btn.call(this,n)}function Bm(n){Wf.call(this,n)}function Hm(n){ET.call(this,n)}function qm(n){Hm.call(this,n)}function Gm(n){ET.call(this,n)}function zm(){this.a=new VT}function Um(){this.a=new xv}function Xm(){this.a=new Lp}function Wm(){this.a=new $p}function Vm(){this.j=new $p}function Qm(){this.a=new Xa}function Jm(){this.a=new AE}function Ym(){this.a=new mo}function Zm(){Zm=O,Rnt=new Lk}function ny(){ny=O,Dnt=new $k}function ty(){ty=O,Int=new c}function ey(){ey=O,qnt=new iN}function iy(n){Hm.call(this,n)}function ry(n){Hm.call(this,n)}function cy(n){b4.call(this,n)}function ay(n){b4.call(this,n)}function uy(n){XK.call(this,n)}function oy(n){vSn.call(this,n)}function sy(n){ST.call(this,n)}function hy(n){IT.call(this,n)}function fy(n){IT.call(this,n)}function ly(n){IT.call(this,n)}function by(n){sz.call(this,n)}function wy(n){by.call(this,n)}function dy(){Ml.call(this,{})}function gy(n){SL(),this.a=n}function py(n){n.b=null,n.c=0}function vy(n,t){n.e=t,Sxn(n,t)}function my(n,t){n.a=t,rIn(n)}function yy(n,t,e){n.a[t.g]=e}function ky(n,t,e){ljn(e,n,t)}function jy(n,t){JR(t.i,n.n)}function Ey(n,t){usn(n).td(t)}function Ty(n,t){return n*n/t}function My(n,t){return n.g-t.g}function Sy(n){return new Tl(n)}function Py(n){return new HX(n)}function Iy(n){by.call(this,n)}function Cy(n){by.call(this,n)}function Oy(n){by.call(this,n)}function Ay(n){sz.call(this,n)}function $y(n){Rcn(),this.a=n}function Ly(n){r_(),this.a=n}function Ny(n){KG(),this.f=n}function xy(n){KG(),this.f=n}function Dy(n){by.call(this,n)}function Ry(n){by.call(this,n)}function Ky(n){by.call(this,n)}function _y(n){by.call(this,n)}function Fy(n){by.call(this,n)}function By(n){return mW(n),n}function Hy(n){return mW(n),n}function qy(n){return mW(n),n}function Gy(n){return mW(n),n}function zy(n){return mW(n),n}function Uy(n){return n.b==n.c}function Xy(n){return!!n&&n.b}function Wy(n){return!!n&&n.k}function Vy(n){return!!n&&n.j}function Qy(n){mW(n),this.a=n}function Jy(n){return Jon(n),n}function Yy(n){gU(n,n.length)}function Zy(n){by.call(this,n)}function nk(n){by.call(this,n)}function tk(n){by.call(this,n)}function ek(n){by.call(this,n)}function ik(n){by.call(this,n)}function rk(n){by.call(this,n)}function ck(n){JN.call(this,n,0)}function ak(){a1.call(this,12,3)}function uk(){uk=O,Znt=new j}function ok(){ok=O,Vnt=new r}function sk(){sk=O,ett=new g}function hk(){hk=O,ott=new v}function fk(){throw Fp(new dv)}function lk(){throw Fp(new dv)}function bk(){throw Fp(new dv)}function wk(){throw Fp(new dv)}function dk(){throw Fp(new dv)}function gk(){throw Fp(new dv)}function pk(){this.a=TD(vX(KWn))}function vk(n){u_(),this.a=vX(n)}function mk(n,t){n.Td(t),t.Sd(n)}function yk(n,t){n.a.ec().Mc(t)}function kk(n,t,e){n.c.lf(t,e)}function jk(n){Cy.call(this,n)}function Ek(n){Ry.call(this,n)}function Tk(){Cb.call(this,"")}function Mk(){Cb.call(this,"")}function Sk(){Cb.call(this,"")}function Pk(){Cb.call(this,"")}function Ik(n){Cy.call(this,n)}function Ck(n){Fb.call(this,n)}function Ok(n){fN.call(this,n)}function Ak(n){Ck.call(this,n)}function $k(){Zf.call(this,null)}function Lk(){Zf.call(this,null)}function Nk(){Nk=O,MJ()}function xk(){xk=O,met=pEn()}function Dk(n){return n.a?n.b:0}function Rk(n){return n.a?n.b:0}function Kk(n,t){return n.a-t.a}function _k(n,t){return n.a-t.a}function Fk(n,t){return n.a-t.a}function Bk(n,t){return p7(n,t)}function Hk(n,t){return wZ(n,t)}function qk(n,t){return t in n.a}function Gk(n,t){return n.f=t,n}function zk(n,t){return n.b=t,n}function Uk(n,t){return n.c=t,n}function Xk(n,t){return n.g=t,n}function Wk(n,t){return n.a=t,n}function Vk(n,t){return n.f=t,n}function Qk(n,t){return n.k=t,n}function Jk(n,t){return n.a=t,n}function Yk(n,t){return n.e=t,n}function Zk(n,t){return n.e=t,n}function nj(n,t){return n.f=t,n}function tj(n,t){n.b=!0,n.d=t}function ej(n,t){n.b=new lA(t)}function ij(n,t,e){t.td(n.a[e])}function rj(n,t,e){t.we(n.a[e])}function cj(n,t){return n.b-t.b}function aj(n,t){return n.g-t.g}function uj(n,t){return n.s-t.s}function oj(n,t){return n?0:t-1}function sj(n,t){return n?0:t-1}function hj(n,t){return n?t-1:0}function fj(n,t){return t.Yf(n)}function lj(n,t){return n.b=t,n}function bj(n,t){return n.a=t,n}function wj(n,t){return n.c=t,n}function dj(n,t){return n.d=t,n}function gj(n,t){return n.e=t,n}function pj(n,t){return n.f=t,n}function vj(n,t){return n.a=t,n}function mj(n,t){return n.b=t,n}function yj(n,t){return n.c=t,n}function kj(n,t){return n.c=t,n}function jj(n,t){return n.b=t,n}function Ej(n,t){return n.d=t,n}function Tj(n,t){return n.e=t,n}function Mj(n,t){return n.f=t,n}function Sj(n,t){return n.g=t,n}function Pj(n,t){return n.a=t,n}function Ij(n,t){return n.i=t,n}function Cj(n,t){return n.j=t,n}function Oj(n,t){return n.k=t,n}function Aj(n,t){return n.j=t,n}function $j(n,t){RMn(),SZ(t,n)}function Lj(n,t,e){HG(n.a,t,e)}function Nj(n){_V.call(this,n)}function xj(n){_V.call(this,n)}function Dj(n){YK.call(this,n)}function Rj(n){Bbn.call(this,n)}function Kj(n){wtn.call(this,n)}function _j(n){dQ.call(this,n)}function Fj(n){dQ.call(this,n)}function Bj(){I$.call(this,"")}function Hj(){this.a=0,this.b=0}function qj(){this.b=0,this.a=0}function Gj(n,t){n.b=0,$en(n,t)}function zj(n,t){n.c=t,n.b=!0}function Uj(n,t){return n.c._b(t)}function Xj(n){return n.e&&n.e()}function Wj(n){return n?n.d:null}function Vj(n,t){return wfn(n.b,t)}function Qj(n){return n?n.g:null}function Jj(n){return n?n.i:null}function Yj(n){return kD(n),n.o}function Zj(){Zj=O,bOt=zkn()}function nE(){nE=O,wOt=aTn()}function tE(){tE=O,JAt=Xkn()}function eE(){eE=O,lLt=Ukn()}function iE(){iE=O,bLt=tIn()}function rE(){rE=O,sAt=iin()}function cE(){throw Fp(new dv)}function aE(){throw Fp(new dv)}function uE(){throw Fp(new dv)}function oE(){throw Fp(new dv)}function sE(){throw Fp(new dv)}function hE(){throw Fp(new dv)}function fE(n){this.a=new zT(n)}function lE(n){hUn(),NXn(this,n)}function bE(n){this.a=new Uz(n)}function wE(n,t){for(;n.ye(t););}function dE(n,t){for(;n.sd(t););}function gE(n,t){return n.a+=t,n}function pE(n,t){return n.a+=t,n}function vE(n,t){return n.a+=t,n}function mE(n,t){return n.a+=t,n}function yE(n){return kW(n),n.a}function kE(n){return n.b!=n.d.c}function jE(n){return n.l|n.m<<22}function EE(n,t){return n.d[t.p]}function TE(n,t){return Txn(n,t)}function ME(n,t,e){n.splice(t,e)}function SE(n){n.c?$Dn(n):LDn(n)}function PE(n){this.a=0,this.b=n}function IE(){this.a=new SNn(tjt)}function CE(){this.b=new SNn(Byt)}function OE(){this.b=new SNn(UEt)}function AE(){this.b=new SNn(UEt)}function $E(){throw Fp(new dv)}function LE(){throw Fp(new dv)}function NE(){throw Fp(new dv)}function xE(){throw Fp(new dv)}function DE(){throw Fp(new dv)}function RE(){throw Fp(new dv)}function KE(){throw Fp(new dv)}function _E(){throw Fp(new dv)}function FE(){throw Fp(new dv)}function BE(){throw Fp(new dv)}function HE(){throw Fp(new vv)}function qE(){throw Fp(new vv)}function GE(n){this.a=new zE(n)}function zE(n){Hin(this,n,IEn())}function UE(n){return!n||dW(n)}function XE(n){return-1!=zLt[n]}function WE(){0!=itt&&(itt=0),ctt=-1}function VE(){null==MWn&&(MWn=[])}function QE(n,t){ZOn(WQ(n.a),t)}function JE(n,t){ZOn(WQ(n.a),t)}function YE(n,t){FL.call(this,n,t)}function ZE(n,t){YE.call(this,n,t)}function nT(n,t){this.b=n,this.c=t}function tT(n,t){this.b=n,this.a=t}function eT(n,t){this.a=n,this.b=t}function iT(n,t){this.a=n,this.b=t}function rT(n,t){this.a=n,this.b=t}function cT(n,t){this.a=n,this.b=t}function aT(n,t){this.a=n,this.b=t}function uT(n,t){this.a=n,this.b=t}function oT(n,t){this.a=n,this.b=t}function sT(n,t){this.a=n,this.b=t}function hT(n,t){this.b=n,this.a=t}function fT(n,t){this.b=n,this.a=t}function lT(n,t){this.b=n,this.a=t}function bT(n,t){this.b=n,this.a=t}function wT(n,t){this.f=n,this.g=t}function dT(n,t){this.e=n,this.d=t}function gT(n,t){this.g=n,this.i=t}function pT(n,t){this.a=n,this.b=t}function vT(n,t){this.a=n,this.f=t}function mT(n,t){this.b=n,this.c=t}function yT(n,t){this.a=n,this.b=t}function kT(n,t){this.a=n,this.b=t}function jT(n,t){this.a=n,this.b=t}function ET(n){rN(n.dc()),this.c=n}function TT(n){this.b=_B(vX(n),83)}function MT(n){this.a=_B(vX(n),83)}function ST(n){this.a=_B(vX(n),15)}function PT(n){this.a=_B(vX(n),15)}function IT(n){this.b=_B(vX(n),47)}function CT(){this.q=new i.Date}function OT(){OT=O,_tt=new A}function AT(){AT=O,het=new P}function $T(n){return n.f.c+n.g.c}function LT(n,t){return n.b.Hc(t)}function NT(n,t){return n.b.Ic(t)}function xT(n,t){return n.b.Qc(t)}function DT(n,t){return n.b.Hc(t)}function RT(n,t){return n.c.uc(t)}function KT(n,t){return n.a._b(t)}function _T(n,t){return $fn(n.c,t)}function FT(n,t){return oU(n.b,t)}function BT(n,t){return n>t&&t0}function uS(n,t){return Xhn(n,t)<0}function oS(n,t){return n.a.get(t)}function sS(n,t){return t.split(n)}function hS(n,t){return oU(n.e,t)}function fS(n){return mW(n),!1}function lS(n){l1.call(this,n,21)}function bS(n,t){RY.call(this,n,t)}function wS(n,t){wT.call(this,n,t)}function dS(n,t){wT.call(this,n,t)}function gS(n){XX(),XK.call(this,n)}function pS(n,t){yG(n,n.length,t)}function vS(n,t){WU(n,n.length,t)}function mS(n,t,e){t.ud(n.a.Ge(e))}function yS(n,t,e){t.we(n.a.Fe(e))}function kS(n,t,e){t.td(n.a.Kb(e))}function jS(n,t,e){n.Mb(e)&&t.td(e)}function ES(n,t,e){n.splice(t,0,e)}function TS(n,t){return TN(n.e,t)}function MS(n,t){this.d=n,this.e=t}function SS(n,t){this.b=n,this.a=t}function PS(n,t){this.b=n,this.a=t}function IS(n,t){this.b=n,this.a=t}function CS(n,t){this.a=n,this.b=t}function OS(n,t){this.a=n,this.b=t}function AS(n,t){this.a=n,this.b=t}function $S(n,t){this.a=n,this.b=t}function LS(n,t){this.a=n,this.b=t}function NS(n,t){this.b=n,this.a=t}function xS(n,t){this.b=n,this.a=t}function DS(n,t){wT.call(this,n,t)}function RS(n,t){wT.call(this,n,t)}function KS(n,t){wT.call(this,n,t)}function _S(n,t){wT.call(this,n,t)}function FS(n,t){wT.call(this,n,t)}function BS(n,t){wT.call(this,n,t)}function HS(n,t){wT.call(this,n,t)}function qS(n,t){wT.call(this,n,t)}function GS(n,t){wT.call(this,n,t)}function zS(n,t){wT.call(this,n,t)}function US(n,t){wT.call(this,n,t)}function XS(n,t){wT.call(this,n,t)}function WS(n,t){wT.call(this,n,t)}function VS(n,t){wT.call(this,n,t)}function QS(n,t){wT.call(this,n,t)}function JS(n,t){wT.call(this,n,t)}function YS(n,t){wT.call(this,n,t)}function ZS(n,t){wT.call(this,n,t)}function nP(n,t){this.a=n,this.b=t}function tP(n,t){this.a=n,this.b=t}function eP(n,t){this.a=n,this.b=t}function iP(n,t){this.a=n,this.b=t}function rP(n,t){this.a=n,this.b=t}function cP(n,t){this.a=n,this.b=t}function aP(n,t){this.a=n,this.b=t}function uP(n,t){this.a=n,this.b=t}function oP(n,t){this.a=n,this.b=t}function sP(n,t){this.b=n,this.a=t}function hP(n,t){this.b=n,this.a=t}function fP(n,t){this.b=n,this.a=t}function lP(n,t){this.b=n,this.a=t}function bP(n,t){this.c=n,this.d=t}function wP(n,t){this.e=n,this.d=t}function dP(n,t){this.a=n,this.b=t}function gP(n,t){this.b=t,this.c=n}function pP(n,t){wT.call(this,n,t)}function vP(n,t){wT.call(this,n,t)}function mP(n,t){wT.call(this,n,t)}function yP(n,t){wT.call(this,n,t)}function kP(n,t){wT.call(this,n,t)}function jP(n,t){wT.call(this,n,t)}function EP(n,t){wT.call(this,n,t)}function TP(n,t){wT.call(this,n,t)}function MP(n,t){wT.call(this,n,t)}function SP(n,t){wT.call(this,n,t)}function PP(n,t){wT.call(this,n,t)}function IP(n,t){wT.call(this,n,t)}function CP(n,t){wT.call(this,n,t)}function OP(n,t){wT.call(this,n,t)}function AP(n,t){wT.call(this,n,t)}function $P(n,t){wT.call(this,n,t)}function LP(n,t){wT.call(this,n,t)}function NP(n,t){wT.call(this,n,t)}function xP(n,t){wT.call(this,n,t)}function DP(n,t){wT.call(this,n,t)}function RP(n,t){wT.call(this,n,t)}function KP(n,t){wT.call(this,n,t)}function _P(n,t){wT.call(this,n,t)}function FP(n,t){wT.call(this,n,t)}function BP(n,t){wT.call(this,n,t)}function HP(n,t){wT.call(this,n,t)}function qP(n,t){wT.call(this,n,t)}function GP(n,t){wT.call(this,n,t)}function zP(n,t){wT.call(this,n,t)}function UP(n,t){wT.call(this,n,t)}function XP(n,t){wT.call(this,n,t)}function WP(n,t){wT.call(this,n,t)}function VP(n,t){wT.call(this,n,t)}function QP(n,t){wT.call(this,n,t)}function JP(n,t){this.b=n,this.a=t}function YP(n,t){this.a=n,this.b=t}function ZP(n,t){this.a=n,this.b=t}function nI(n,t){this.a=n,this.b=t}function tI(n,t){this.a=n,this.b=t}function eI(n,t){wT.call(this,n,t)}function iI(n,t){wT.call(this,n,t)}function rI(n,t){this.b=n,this.d=t}function cI(n,t){wT.call(this,n,t)}function aI(n,t){wT.call(this,n,t)}function uI(n,t){this.a=n,this.b=t}function oI(n,t){this.a=n,this.b=t}function sI(n,t){wT.call(this,n,t)}function hI(n,t){wT.call(this,n,t)}function fI(n,t){wT.call(this,n,t)}function lI(n,t){wT.call(this,n,t)}function bI(n,t){wT.call(this,n,t)}function wI(n,t){wT.call(this,n,t)}function dI(n,t){wT.call(this,n,t)}function gI(n,t){wT.call(this,n,t)}function pI(n,t){wT.call(this,n,t)}function vI(n,t){wT.call(this,n,t)}function mI(n,t){wT.call(this,n,t)}function yI(n,t){wT.call(this,n,t)}function kI(n,t){wT.call(this,n,t)}function jI(n,t){wT.call(this,n,t)}function EI(n,t){wT.call(this,n,t)}function TI(n,t){wT.call(this,n,t)}function MI(n,t){return TN(n.c,t)}function SI(n,t){return TN(t.b,n)}function PI(n,t){return-n.b.Je(t)}function II(n,t){return TN(n.g,t)}function CI(n,t){wT.call(this,n,t)}function OI(n,t){wT.call(this,n,t)}function AI(n,t){this.a=n,this.b=t}function $I(n,t){this.a=n,this.b=t}function LI(n,t){this.a=n,this.b=t}function NI(n,t){wT.call(this,n,t)}function xI(n,t){wT.call(this,n,t)}function DI(n,t){wT.call(this,n,t)}function RI(n,t){wT.call(this,n,t)}function KI(n,t){wT.call(this,n,t)}function _I(n,t){wT.call(this,n,t)}function FI(n,t){wT.call(this,n,t)}function BI(n,t){wT.call(this,n,t)}function HI(n,t){wT.call(this,n,t)}function qI(n,t){wT.call(this,n,t)}function GI(n,t){wT.call(this,n,t)}function zI(n,t){wT.call(this,n,t)}function UI(n,t){wT.call(this,n,t)}function XI(n,t){wT.call(this,n,t)}function WI(n,t){wT.call(this,n,t)}function VI(n,t){wT.call(this,n,t)}function QI(n,t){this.a=n,this.b=t}function JI(n,t){this.a=n,this.b=t}function YI(n,t){this.a=n,this.b=t}function ZI(n,t){this.a=n,this.b=t}function nC(n,t){this.a=n,this.b=t}function tC(n,t){this.a=n,this.b=t}function eC(n,t){this.a=n,this.b=t}function iC(n,t){wT.call(this,n,t)}function rC(n,t){this.a=n,this.b=t}function cC(n,t){this.a=n,this.b=t}function aC(n,t){this.a=n,this.b=t}function uC(n,t){this.a=n,this.b=t}function oC(n,t){this.a=n,this.b=t}function sC(n,t){this.a=n,this.b=t}function hC(n,t){this.b=n,this.a=t}function fC(n,t){this.b=n,this.a=t}function lC(n,t){this.b=n,this.a=t}function bC(n,t){this.b=n,this.a=t}function wC(n,t){this.a=n,this.b=t}function dC(n,t){this.a=n,this.b=t}function gC(n,t){QLn(n.a,_B(t,56))}function pC(n,t){g7(n.a,_B(t,11))}function vC(n,t){return oH(),t!=n}function mC(){return xk(),new met}function yC(){BZ(),this.b=new xv}function kC(){bxn(),this.a=new xv}function jC(){DZ(),DG.call(this)}function EC(n,t){wT.call(this,n,t)}function TC(n,t){this.a=n,this.b=t}function MC(n,t){this.a=n,this.b=t}function SC(n,t){this.a=n,this.b=t}function PC(n,t){this.a=n,this.b=t}function IC(n,t){this.a=n,this.b=t}function CC(n,t){this.a=n,this.b=t}function OC(n,t){this.d=n,this.b=t}function AC(n,t){this.d=n,this.e=t}function $C(n,t){this.f=n,this.c=t}function LC(n,t){this.b=n,this.c=t}function NC(n,t){this.i=n,this.g=t}function xC(n,t){this.e=n,this.a=t}function DC(n,t){this.a=n,this.b=t}function RC(n,t){n.i=null,rrn(n,t)}function KC(n,t){n&&XW(cAt,n,t)}function _C(n,t){return edn(n.a,t)}function FC(n){return rdn(n.c,n.b)}function BC(n){return n?n.dd():null}function HC(n){return null==n?null:n}function qC(n){return typeof n===OWn}function GC(n){return typeof n===AWn}function zC(n){return typeof n===$Wn}function UC(n,t){return n.Hd().Xb(t)}function XC(n,t){return Wcn(n.Kc(),t)}function WC(n,t){return 0==Xhn(n,t)}function VC(n,t){return Xhn(n,t)>=0}function QC(n,t){return 0!=Xhn(n,t)}function JC(n){return""+(mW(n),n)}function YC(n,t){return n.substr(t)}function ZC(n){return qbn(n),n.d.gc()}function nO(n){return qOn(n,n.c),n}function tO(n){return QH(null==n),n}function eO(n,t){return n.a+=""+t,n}function iO(n,t){return n.a+=""+t,n}function rO(n,t){return n.a+=""+t,n}function cO(n,t){return n.a+=""+t,n}function aO(n,t){return n.a+=""+t,n}function uO(n,t){return n.a+=""+t,n}function oO(n,t){e5(n,t,n.a,n.a.a)}function sO(n,t){e5(n,t,n.c.b,n.c)}function hO(n,t,e){Djn(t,xPn(n,e))}function fO(n,t,e){Djn(t,xPn(n,e))}function lO(n,t){jnn(new CL(n),t)}function bO(n,t){n.q.setTime(y2(t))}function wO(n,t){qz.call(this,n,t)}function dO(n,t){qz.call(this,n,t)}function gO(n,t){qz.call(this,n,t)}function pO(n){OU(this),jcn(this,n)}function vO(n){return h1(n,0),null}function mO(n){return n.a=0,n.b=0,n}function yO(n,t){return n.a=t.g+1,n}function kO(n,t){return 2==n.j[t.p]}function jO(n){return uX(_B(n,79))}function EO(){EO=O,Crt=hhn(Zgn())}function TO(){TO=O,Jot=hhn(kNn())}function MO(){this.b=new zT(ntn(12))}function SO(){this.b=0,this.a=!1}function PO(){this.b=0,this.a=!1}function IO(n){this.a=n,_h.call(this)}function CO(n){this.a=n,_h.call(this)}function OO(n,t){tR.call(this,n,t)}function AO(n,t){ZR.call(this,n,t)}function $O(n,t){NC.call(this,n,t)}function LO(n,t){Can.call(this,n,t)}function NO(n,t){WN.call(this,n,t)}function xO(n,t){YM(),XW(gAt,n,t)}function DO(n,t){return sx(n.a,0,t)}function RO(n,t){return n.a.a.a.cc(t)}function KO(n,t){return HC(n)===HC(t)}function _O(n,t){return Mln(n.a,t.a)}function FO(n,t){return k$(n.a,t.a)}function BO(n,t){return KU(n.a,t.a)}function HO(n,t){return n.indexOf(t)}function qO(n,t){return n==t?0:n?1:-1}function GO(n){return n<10?"0"+n:""+n}function zO(n){return vX(n),new IO(n)}function UO(n){return E$(n.l,n.m,n.h)}function XO(n){return SY((mW(n),n))}function WO(n){return SY((mW(n),n))}function VO(n,t){return k$(n.g,t.g)}function QO(n){return typeof n===AWn}function JO(n){return n==Jat||n==nut}function YO(n){return n==Jat||n==Yat}function ZO(n){return k7(n.b.b,n,0)}function nA(n){this.a=mC(),this.b=n}function tA(n){this.a=mC(),this.b=n}function eA(n,t){return UB(n.a,t),t}function iA(n,t){return UB(n.c,t),n}function rA(n,t){return Qcn(n.a,t),n}function cA(n,t){return H_(),t.a+=n}function aA(n,t){return H_(),t.a+=n}function uA(n,t){return H_(),t.c+=n}function oA(n,t){q9(n,0,n.length,t)}function sA(){nw.call(this,new g4)}function hA(){cG.call(this,0,0,0,0)}function fA(){GV.call(this,0,0,0,0)}function lA(n){this.a=n.a,this.b=n.b}function bA(n){return n==RPt||n==KPt}function wA(n){return n==FPt||n==DPt}function dA(n){return n==svt||n==ovt}function gA(n){return n!=WIt&&n!=VIt}function pA(n){return n.Lg()&&n.Mg()}function vA(n){return pV(_B(n,118))}function mA(n){return Qcn(new _2,n)}function yA(n,t){return new Can(t,n)}function kA(n,t){return new Can(t,n)}function jA(n,t,e){yen(n,t),ken(n,e)}function EA(n,t,e){Ten(n,t),Een(n,e)}function TA(n,t,e){Men(n,t),Sen(n,e)}function MA(n,t,e){jen(n,t),Ien(n,e)}function SA(n,t,e){Pen(n,t),Cen(n,e)}function PA(n,t){Nsn(n,t),Len(n,n.D)}function IA(n){$C.call(this,n,!0)}function CA(n,t,e){$D.call(this,n,t,e)}function OA(n){IDn(),uan.call(this,n)}function AA(){wS.call(this,"Head",1)}function $A(){wS.call(this,"Tail",3)}function LA(n){n.c=L8(Cnt,FWn,1,0,5,1)}function NA(n){n.a=L8(Cnt,FWn,1,8,5,1)}function xA(n){Itn(n.xf(),new Tw(n))}function DA(n){return null!=n?Yon(n):0}function RA(n,t){return Stn(t,UY(n))}function KA(n,t){return Stn(t,UY(n))}function _A(n,t){return n[n.length]=t}function FA(n,t){return n[n.length]=t}function BA(n){return KB(n.b.Kc(),n.a)}function HA(n,t){return Gin(MX(n.d),t)}function qA(n,t){return Gin(MX(n.g),t)}function GA(n,t){return Gin(MX(n.j),t)}function zA(n,t){tR.call(this,n.b,t)}function UA(n){cG.call(this,n,n,n,n)}function XA(n){return n.b&&XBn(n),n.a}function WA(n){return n.b&&XBn(n),n.c}function VA(n,t){Wet||(n.b=t)}function QA(n,t,e){return OX(n,t,e),e}function JA(n,t,e){OX(n.c[t.g],t.g,e)}function YA(n,t,e){_B(n.c,69).Xh(t,e)}function ZA(n,t,e){TA(e,e.i+n,e.j+t)}function n$(n,t){s9(r4(n.a),n1(t))}function t$(n,t){s9(F7(n.a),t1(t))}function e$(n){lWn(),Cp.call(this,n)}function i$(n){return null==n?0:Yon(n)}function r$(){r$=O,uyt=new Fbn(aIt)}function c$(){c$=O,new a$,new $p}function a$(){new Lp,new Lp,new Lp}function u$(){u$=O,Ev(),ttt=new Lp}function o$(){o$=O,i.Math.log(2)}function s$(){s$=O,qM(),N$t=SOt}function h$(){throw Fp(new Zy(jnt))}function f$(){throw Fp(new Zy(jnt))}function l$(){throw Fp(new Zy(Ent))}function b$(){throw Fp(new Zy(Ent))}function w$(n){this.a=n,WB.call(this,n)}function d$(n){this.a=n,TT.call(this,n)}function g$(n){this.a=n,TT.call(this,n)}function p$(n,t){vG(n.c,n.c.length,t)}function v$(n){return n.at?1:0}function j$(n,t){return Xhn(n,t)>0?n:t}function E$(n,t,e){return{l:n,m:t,h:e}}function T$(n,t){null!=n.a&&pC(t,n.a)}function M$(n){n.a=new $,n.c=new $}function S$(n){this.b=n,this.a=new $p}function P$(n){this.b=new et,this.a=n}function I$(n){AR.call(this),this.a=n}function C$(){wS.call(this,"Range",2)}function O$(){Zkn(),this.a=new SNn(Gat)}function A$(n,t){vX(t),kV(n).Jc(new b)}function $$(n,t){return _Z(),t.n.b+=n}function L$(n,t,e){return XW(n.g,e,t)}function N$(n,t,e){return XW(n.k,e,t)}function x$(n,t){return XW(n.a,t.a,t)}function D$(n,t,e){return Pdn(t,e,n.c)}function R$(n){return new LI(n.c,n.d)}function K$(n){return new LI(n.c,n.d)}function _$(n){return new LI(n.a,n.b)}function F$(n,t){return ZGn(n.a,t,null)}function B$(n){TZ(n,null),EZ(n,null)}function H$(n){UZ(n,null),XZ(n,null)}function q$(){WN.call(this,null,null)}function G$(){VN.call(this,null,null)}function z$(n){this.a=n,Lp.call(this)}function U$(n){this.b=(TQ(),new zb(n))}function X$(n){n.j=L8(Ktt,uVn,310,0,0,1)}function W$(n,t,e){n.c.Vc(t,_B(e,133))}function V$(n,t,e){n.c.ji(t,_B(e,133))}function Q$(n,t){uqn(n),n.Gc(_B(t,15))}function J$(n,t){return _qn(n.c,n.b,t)}function Y$(n,t){return new dN(n.Kc(),t)}function Z$(n,t){return-1!=Kun(n.Kc(),t)}function nL(n,t){return null!=n.a.Bc(t)}function tL(n){return n.Ob()?n.Pb():null}function eL(n){return _dn(n,0,n.length)}function iL(n,t){return null!=n&&Wpn(n,t)}function rL(n,t){n.q.setHours(t),hBn(n,t)}function cL(n,t){n.c&&(xH(t),mY(t))}function aL(n,t,e){_B(n.Kb(e),164).Nb(t)}function uL(n,t,e){return FGn(n,t,e),e}function oL(n,t,e){n.a=1502^t,n.b=e^rJn}function sL(n,t,e){return n.a[t.g][e.g]}function hL(n,t){return n.a[t.c.p][t.p]}function fL(n,t){return n.e[t.c.p][t.p]}function lL(n,t){return n.c[t.c.p][t.p]}function bL(n,t){return n.j[t.p]=dLn(t)}function wL(n,t){return s6(n.f,t.tg())}function dL(n,t){return s6(n.b,t.tg())}function gL(n,t){return n.a0?t*t/n:t*t*100}function Lx(n,t){return n>0?t/(n*n):100*t}function Nx(n,t,e){return UB(t,awn(n,e))}function xx(n,t,e){L9(),n.Xe(t)&&e.td(n)}function Dx(n,t,e){n.Zc(t).Rb(e)}function Rx(n,t,e){return n.a+=t,n.b+=e,n}function Kx(n,t,e){return n.a*=t,n.b*=e,n}function _x(n,t,e){return n.a-=t,n.b-=e,n}function Fx(n,t){return n.a=t.a,n.b=t.b,n}function Bx(n){return n.a=-n.a,n.b=-n.b,n}function Hx(n){this.c=n,this.a=1,this.b=1}function qx(n){this.c=n,Men(n,0),Sen(n,0)}function Gx(n){VT.call(this),Yen(this,n)}function zx(n){xXn(),_p(this),this.mf(n)}function Ux(n,t){WM(),WN.call(this,n,t)}function Xx(n,t){VM(),VN.call(this,n,t)}function Wx(n,t){VM(),VN.call(this,n,t)}function Vx(n,t){VM(),Xx.call(this,n,t)}function Qx(n,t,e){v9.call(this,n,t,e,2)}function Jx(n,t){s$(),iG.call(this,n,t)}function Yx(n,t){s$(),Jx.call(this,n,t)}function Zx(n,t){s$(),Jx.call(this,n,t)}function nD(n,t){s$(),Zx.call(this,n,t)}function tD(n,t){s$(),iG.call(this,n,t)}function eD(n,t){s$(),tD.call(this,n,t)}function iD(n,t){s$(),iG.call(this,n,t)}function rD(n,t){return n.c.Fc(_B(t,133))}function cD(n,t,e){return $Hn(K7(n,t),e)}function aD(n,t,e){return t.Qk(n.e,n.c,e)}function uD(n,t,e){return t.Rk(n.e,n.c,e)}function oD(n,t){return Zhn(n.e,_B(t,49))}function sD(n,t,e){uln(F7(n.a),t,t1(e))}function hD(n,t,e){uln(r4(n.a),t,n1(e))}function fD(n,t){t.$modCount=n.$modCount}function lD(){lD=O,Xkt=new cp("root")}function bD(){bD=O,wAt=new jm,new Em}function wD(){this.a=new dY,this.b=new dY}function dD(){yin.call(this),this.Bb|=_Qn}function gD(){wT.call(this,"GROW_TREE",0)}function pD(n){return null==n?null:lUn(n)}function vD(n){return null==n?null:ASn(n)}function mD(n){return null==n?null:_bn(n)}function yD(n){return null==n?null:_bn(n)}function kD(n){null==n.o&&w$n(n)}function jD(n){return QH(null==n||qC(n)),n}function ED(n){return QH(null==n||GC(n)),n}function TD(n){return QH(null==n||zC(n)),n}function MD(n){this.q=new i.Date(y2(n))}function SD(n,t){this.c=n,dT.call(this,n,t)}function PD(n,t){this.a=n,SD.call(this,n,t)}function ID(n,t){this.d=n,Eb(this),this.b=t}function CD(n,t){_8.call(this,n),this.a=t}function OD(n,t){_8.call(this,n),this.a=t}function AD(n){Bwn.call(this,0,0),this.f=n}function $D(n,t,e){U6.call(this,n,t,e,null)}function LD(n,t,e){U6.call(this,n,t,e,null)}function ND(n,t,e){return n.ue(t,e)<=0?e:t}function xD(n,t,e){return n.ue(t,e)<=0?t:e}function DD(n,t){return _B(hnn(n.b,t),149)}function RD(n,t){return _B(hnn(n.c,t),229)}function KD(n){return _B(Lq(n.a,n.b),287)}function _D(n){return new LI(n.c,n.d+n.a)}function FD(n){return _Z(),dA(_B(n,197))}function BD(){BD=O,Ort=Yln((pdn(),RCt))}function HD(n,t){t.a?Kxn(n,t):EN(n.a,t.b)}function qD(n,t){Wet||UB(n.a,t)}function GD(n,t){return pM(),lan(t.d.i,n)}function zD(n,t){return Prn(),new iKn(t,n)}function UD(n,t){return IJ(t,cYn),n.f=t,n}function XD(n,t,e){return e=j_n(n,t,3,e)}function WD(n,t,e){return e=j_n(n,t,6,e)}function VD(n,t,e){return e=j_n(n,t,9,e)}function QD(n,t,e){++n.j,n.Ki(),A8(n,t,e)}function JD(n,t,e){++n.j,n.Hi(t,n.oi(t,e))}function YD(n,t,e){n.Zc(t).Rb(e)}function ZD(n,t,e){return JBn(n.c,n.b,t,e)}function nR(n,t){return(t&NWn)%n.d.length}function tR(n,t){cp.call(this,n),this.a=t}function eR(n,t){mp.call(this,n),this.a=t}function iR(n,t){mp.call(this,n),this.a=t}function rR(n,t){this.c=n,wtn.call(this,t)}function cR(n,t){this.a=n,vp.call(this,t)}function aR(n,t){this.a=n,vp.call(this,t)}function uR(n){this.a=(hin(n,CVn),new Q6(n))}function oR(n){this.a=(hin(n,CVn),new Q6(n))}function sR(n){return!n.a&&(n.a=new w),n.a}function hR(n){return n>8?0:n+1}function fR(n,t){return oN(),n==t?0:n?1:-1}function lR(n,t,e){return pG(n,_B(t,22),e)}function bR(n,t,e){return n.apply(t,e)}function wR(n,t,e){return n.a+=_dn(t,0,e),n}function dR(n,t){var e;return e=n.e,n.e=t,e}function gR(n,t){n[tJn].call(n,t)}function pR(n,t){n[tJn].call(n,t)}function vR(n,t){n.a.Vc(n.b,t),++n.b,n.c=-1}function mR(n){OU(n.e),n.d.b=n.d,n.d.a=n.d}function yR(n){n.b?yR(n.b):n.f.c.zc(n.e,n.d)}function kR(n,t,e){bM(),Pl(n,t.Ce(n.a,e))}function jR(n,t){return Wj(Edn(n.a,t,!0))}function ER(n,t){return Wj(Tdn(n.a,t,!0))}function TR(n,t){return Bk(new Array(t),n)}function MR(n){return String.fromCharCode(n)}function SR(n){return null==n?null:n.message}function PR(){this.a=new $p,this.b=new $p}function IR(){this.a=new bt,this.b=new jv}function CR(){this.b=new Hj,this.c=new $p}function OR(){this.d=new Hj,this.e=new Hj}function AR(){this.n=new Hj,this.o=new Hj}function $R(){this.n=new fm,this.i=new fA}function LR(){this.a=new Yh,this.b=new uc}function NR(){this.a=new $p,this.d=new $p}function xR(){this.b=new xv,this.a=new xv}function DR(){this.b=new Lp,this.a=new Lp}function RR(){this.b=new CE,this.a=new da}function KR(){$R.call(this),this.a=new Hj}function _R(n){Ian.call(this,n,(J9(),$et))}function FR(n,t,e,i){cG.call(this,n,t,e,i)}function BR(n,t,e){null!=e&&Ain(t,Cmn(n,e))}function HR(n,t,e){null!=e&&$in(t,Cmn(n,e))}function qR(n,t,e){return e=j_n(n,t,11,e)}function GR(n,t){return n.a+=t.a,n.b+=t.b,n}function zR(n,t){return n.a-=t.a,n.b-=t.b,n}function UR(n,t){return n.n.a=(mW(t),t+10)}function XR(n,t){return n.n.a=(mW(t),t+10)}function WR(n,t){return t==n||Tjn(SLn(t),n)}function VR(n,t){return null==XW(n.a,t,"")}function QR(n,t){return pM(),!lan(t.d.i,n)}function JR(n,t){bA(n.f)?i$n(n,t):PTn(n,t)}function YR(n,t){return t.Hh(n.a)}function ZR(n,t){Cy.call(this,n9n+n+a8n+t)}function nK(n,t,e,i){nU.call(this,n,t,e,i)}function tK(n,t,e,i){nU.call(this,n,t,e,i)}function eK(n,t,e,i){tK.call(this,n,t,e,i)}function iK(n,t,e,i){tU.call(this,n,t,e,i)}function rK(n,t,e,i){tU.call(this,n,t,e,i)}function cK(n,t,e,i){tU.call(this,n,t,e,i)}function aK(n,t,e,i){rK.call(this,n,t,e,i)}function uK(n,t,e,i){rK.call(this,n,t,e,i)}function oK(n,t,e,i){cK.call(this,n,t,e,i)}function sK(n,t,e,i){uK.call(this,n,t,e,i)}function hK(n,t,e,i){Jz.call(this,n,t,e,i)}function fK(n,t,e){this.a=n,JN.call(this,t,e)}function lK(n,t,e){this.c=t,this.b=e,this.a=n}function bK(n,t,e){return n.d=_B(t.Kb(e),164)}function wK(n,t){return n.Aj().Nh().Kh(n,t)}function dK(n,t){return n.Aj().Nh().Ih(n,t)}function gK(n,t){return mW(n),HC(n)===HC(t)}function pK(n,t){return mW(n),HC(n)===HC(t)}function vK(n,t){return Wj(Edn(n.a,t,!1))}function mK(n,t){return Wj(Tdn(n.a,t,!1))}function yK(n,t){return n.b.sd(new OS(n,t))}function kK(n,t){return n.b.sd(new AS(n,t))}function jK(n,t){return n.b.sd(new $S(n,t))}function EK(n,t,e){return n.lastIndexOf(t,e)}function TK(n,t,e){return Mln(n[t.b],n[e.b])}function MK(n,t){return oon(t,(FXn(),xdt),n)}function SK(n,t){return k$(t.a.d.p,n.a.d.p)}function PK(n,t){return k$(n.a.d.p,t.a.d.p)}function IK(n,t){return Mln(n.c-n.s,t.c-t.s)}function CK(n){return n.c?k7(n.c.a,n,0):-1}function OK(n){return n<100?null:new Kj(n)}function AK(n){return n==GIt||n==UIt||n==zIt}function $K(n,t){return iL(t,15)&&WDn(n.c,t)}function LK(n,t){Wet||t&&(n.d=t)}function NK(n,t){return!!hsn(n,t)}function xK(n,t){this.c=n,HU.call(this,n,t)}function DK(n){this.c=n,gO.call(this,fVn,0)}function RK(n,t){QB.call(this,n,n.length,t)}function KK(n,t,e){return _B(n.c,69).lk(t,e)}function _K(n,t,e){return _B(n.c,69).mk(t,e)}function FK(n,t,e){return aD(n,_B(t,332),e)}function BK(n,t,e){return uD(n,_B(t,332),e)}function HK(n,t,e){return PEn(n,_B(t,332),e)}function qK(n,t,e){return WTn(n,_B(t,332),e)}function GK(n,t){return null==t?null:hfn(n.b,t)}function zK(n){return GC(n)?(mW(n),n):n.ke()}function UK(n){return!isNaN(n)&&!isFinite(n)}function XK(n){u_(),this.a=(TQ(),new Ck(n))}function WK(n){oH(),this.d=n,this.a=new Ap}function VK(n,t,e){this.a=n,this.b=t,this.c=e}function QK(n,t,e){this.a=n,this.b=t,this.c=e}function JK(n,t,e){this.d=n,this.b=e,this.a=t}function YK(n){M$(this),vQ(this),Krn(this,n)}function ZK(n){LA(this),ZB(this.c,0,n.Pc())}function n_(n){sW(n.a),q8(n.c,n.b),n.b=null}function t_(n){this.a=n,OT(),san(Date.now())}function e_(){e_=O,tit=new r,eit=new r}function i_(){i_=O,jet=new L,Eet=new N}function r_(){r_=O,fAt=L8(Cnt,FWn,1,0,5,1)}function c_(){c_=O,j$t=L8(Cnt,FWn,1,0,5,1)}function a_(){a_=O,E$t=L8(Cnt,FWn,1,0,5,1)}function u_(){u_=O,new ev((TQ(),TQ(),uet))}function o_(n){return J9(),Snn((Y9(),Ret),n)}function s_(n){return Bsn(),Snn((n8(),Jet),n)}function h_(n){return opn(),Snn((P4(),dit),n)}function f_(n){return xnn(),Snn((I4(),mit),n)}function l_(n){return ZDn(),Snn((Lan(),Kit),n)}function b_(n){return Ntn(),Snn((J6(),Uit),n)}function w_(n){return Q9(),Snn((Y6(),Zit),n)}function d_(n){return H7(),Snn((Z6(),crt),n)}function g_(n){return bWn(),Snn((EO(),Crt),n)}function p_(n){return Nan(),Snn((n7(),Rrt),n)}function v_(n){return Fpn(),Snn((t7(),qrt),n)}function m_(n){return Bpn(),Snn((e7(),tct),n)}function y_(n){return lM(),Snn((W2(),rct),n)}function k_(n){return Dnn(),Snn((C4(),Rct),n)}function j_(n){return B7(),Snn((t8(),Aat),n)}function E_(n){return vMn(),Snn((znn(),Bat),n)}function T_(n){return Cun(),Snn((Z9(),eut),n)}function M_(n){return _fn(),Snn((e8(),wut),n)}function S_(n,t){if(!n)throw Fp(new Ry(t))}function P_(n){return cSn(),Snn((oen(),Cut),n)}function I_(n){cG.call(this,n.d,n.c,n.a,n.b)}function C_(n){cG.call(this,n.d,n.c,n.a,n.b)}function O_(n,t,e){this.b=n,this.c=t,this.a=e}function A_(n,t,e){this.b=n,this.a=t,this.c=e}function $_(n,t,e){this.a=n,this.b=t,this.c=e}function L_(n,t,e){this.a=n,this.b=t,this.c=e}function N_(n,t,e){this.a=n,this.b=t,this.c=e}function x_(n,t,e){this.a=n,this.b=t,this.c=e}function D_(n,t,e){this.b=n,this.a=t,this.c=e}function R_(n,t,e){this.e=t,this.b=n,this.d=e}function K_(n,t,e){return bM(),n.a.Od(t,e),t}function __(n){var t;return(t=new jn).e=n,t}function F_(n){var t;return(t=new Jv).b=n,t}function B_(){B_=O,Gut=new Ne,zut=new xe}function H_(){H_=O,bst=new vr,wst=new mr}function q_(n){return Pun(),Snn((r7(),ast),n)}function G_(n){return Iun(),Snn((a7(),kst),n)}function z_(n){return mDn(),Snn((Hcn(),Xst),n)}function U_(n){return OPn(),Snn((fen(),eht),n)}function X_(n){return X8(),Snn((x4(),aht),n)}function W_(n){return Iin(),Snn((i8(),fht),n)}function V_(n){return AEn(),Snn((Fnn(),Ist),n)}function Q_(n){return Srn(),Snn((a8(),Rst),n)}function J_(n){return cin(),Snn((r8(),ght),n)}function Y_(n){return Xvn(),Snn((Knn(),Eht),n)}function Z_(n){return Rnn(),Snn((A4(),Pht),n)}function nF(n){return Qun(),Snn((c8(),$ht),n)}function tF(n){return wSn(),Snn((den(),Fht),n)}function eF(n){return w7(),Snn(($4(),Ght),n)}function iF(n){return _jn(),Snn((ben(),Yht),n)}function rF(n){return QMn(),Snn((len(),aft),n)}function cF(n){return fDn(),Snn((Xun(),vft),n)}function aF(n){return Dan(),Snn((o8(),Eft),n)}function uF(n){return q7(),Snn((u8(),Ift),n)}function oF(n){return q2(),Snn((D4(),$ft),n)}function sF(n){return jbn(),Snn((Bnn(),qlt),n)}function hF(n){return jTn(),Snn((wen(),evt),n)}function fF(n){return Ehn(),Snn((s8(),uvt),n)}function lF(n){return fvn(),Snn((u7(),bvt),n)}function bF(n){return rin(),Snn((l8(),Gvt),n)}function wF(n){return uNn(),Snn((Bcn(),Ovt),n)}function dF(n){return pon(),Snn((f8(),xvt),n)}function gF(n){return G7(),Snn((N4(),_vt),n)}function pF(n){return Fcn(),Snn((h8(),Vvt),n)}function vF(n){return $vn(),Snn((_nn(),yvt),n)}function mF(n){return C6(),Snn((L4(),Zvt),n)}function yF(n){return Gsn(),Snn((w8(),rmt),n)}function kF(n){return bcn(),Snn((d8(),smt),n)}function jF(n){return Oun(),Snn((b8(),wmt),n)}function EF(n){return ain(),Snn((g8(),$mt),n)}function TF(n){return W4(),Snn((K4(),Hmt),n)}function MF(n){return wY(),Snn((_4(),tyt),n)}function SF(n){return aZ(),Snn((F4(),cyt),n)}function PF(n){return I6(),Snn((R4(),Myt),n)}function IF(n){return bY(),Snn((B4(),Nyt),n)}function CF(n){return qyn(),Snn((i7(),Fyt),n)}function OF(n){return NPn(),Snn((gen(),Qyt),n)}function AF(n){return uZ(),Snn((G4(),Kkt),n)}function $F(n){return Mrn(),Snn((q4(),Jkt),n)}function LF(n){return _0(),Snn((H4(),Hkt),n)}function NF(n){return Sbn(),Snn((p8(),ejt),n)}function xF(n){return N9(),Snn((z4(),ajt),n)}function DF(n){return Fsn(),Snn((v8(),fjt),n)}function RF(n){return Imn(),Snn((c7(),qjt),n)}function KF(n){return _cn(),Snn((y8(),Wjt),n)}function _F(n){return Tbn(),Snn((m8(),nEt),n)}function FF(n){return VLn(),Snn((Gnn(),_Et),n)}function BF(n){return Mbn(),Snn((k8(),GEt),n)}function HF(n){return SM(),Snn((U2(),XEt),n)}function qF(n){return PM(),Snn((z2(),QEt),n)}function GF(n){return O6(),Snn((X4(),nTt),n)}function zF(n){return OSn(),Snn((Hnn(),uTt),n)}function UF(n){return IM(),Snn((X2(),GTt),n)}function XF(n){return Aun(),Snn((U4(),WTt),n)}function WF(n){return epn(),Snn((qnn(),fMt),n)}function VF(n){return MPn(),Snn((qcn(),kMt),n)}function QF(n){return lvn(),Snn((hen(),LMt),n)}function JF(n){return lEn(),Snn((sen(),ZMt),n)}function YF(n){return hWn(),Snn((TO(),Jot),n)}function ZF(n){return Trn(),Snn((O4(),qut),n)}function nB(n){return Kfn(),Snn((Unn(),HPt),n)}function tB(n){return xtn(),Snn((E8(),XPt),n)}function eB(n){return Ebn(),Snn((h7(),ZPt),n)}function iB(n){return YTn(),Snn((ven(),uIt),n)}function rB(n){return cfn(),Snn((j8(),mIt),n)}function cB(n){return zyn(),Snn((s7(),MIt),n)}function aB(n){return YAn(),Snn(($an(),DIt),n)}function uB(n){return ipn(),Snn((Xnn(),qIt),n)}function oB(n){return WEn(),Snn((Ftn(),JIt),n)}function sB(n){return hCn(),Snn((pen(),cCt),n)}function hB(n){return pdn(),Snn((l7(),_Ct),n)}function fB(n){return YKn(),Snn((Wun(),QCt),n)}function lB(n){return mUn(),Snn((Wnn(),ICt),n)}function bB(n){return Kwn(),Snn((f7(),eOt),n)}function wB(n){return _sn(),Snn((o7(),sOt),n)}function dB(n){return oAn(),Snn((Gcn(),eAt),n)}function gB(n,t){return mW(n),n+(mW(t),t)}function pB(n,t){return OT(),s9(WQ(n.a),t)}function vB(n,t){return OT(),s9(WQ(n.a),t)}function mB(n,t){this.c=n,this.a=t,this.b=t-n}function yB(n,t,e){this.a=n,this.b=t,this.c=e}function kB(n,t,e){this.a=n,this.b=t,this.c=e}function jB(n,t,e){this.a=n,this.b=t,this.c=e}function EB(n,t,e){this.a=n,this.b=t,this.c=e}function TB(n,t,e){this.a=n,this.b=t,this.c=e}function MB(n,t,e){this.e=n,this.a=t,this.c=e}function SB(n,t,e){s$(),pY.call(this,n,t,e)}function PB(n,t,e){s$(),eW.call(this,n,t,e)}function IB(n,t,e){s$(),eW.call(this,n,t,e)}function CB(n,t,e){s$(),eW.call(this,n,t,e)}function OB(n,t,e){s$(),PB.call(this,n,t,e)}function AB(n,t,e){s$(),PB.call(this,n,t,e)}function $B(n,t,e){s$(),AB.call(this,n,t,e)}function LB(n,t,e){s$(),IB.call(this,n,t,e)}function NB(n,t,e){s$(),CB.call(this,n,t,e)}function xB(n,t){return vX(n),vX(t),new oT(n,t)}function DB(n,t){return vX(n),vX(t),new RH(n,t)}function RB(n,t){return vX(n),vX(t),new KH(n,t)}function KB(n,t){return vX(n),vX(t),new hT(n,t)}function _B(n,t){return QH(null==n||Wpn(n,t)),n}function FB(n){var t;return snn(t=new $p,n),t}function BB(n){var t;return snn(t=new xv,n),t}function HB(n){var t;return Brn(t=new qv,n),t}function qB(n){var t;return Brn(t=new VT,n),t}function GB(n){return!n.e&&(n.e=new $p),n.e}function zB(n){return!n.c&&(n.c=new Bo),n.c}function UB(n,t){return n.c[n.c.length]=t,!0}function XB(n,t){this.c=n,this.b=t,this.a=!1}function WB(n){this.d=n,Eb(this),this.b=ez(n.d)}function VB(){this.a=";,;",this.b="",this.c=""}function QB(n,t,e){Gz.call(this,t,e),this.a=n}function JB(n,t,e){this.b=n,wO.call(this,t,e)}function YB(n,t,e){this.c=n,MS.call(this,t,e)}function ZB(n,t,e){RIn(e,0,n,t,e.length,!1)}function nH(n,t,e,i,r){n.b=t,n.c=e,n.d=i,n.a=r}function tH(n,t){t&&(n.b=t,n.a=(kW(t),t.a))}function eH(n,t,e,i,r){n.d=t,n.c=e,n.a=i,n.b=r}function iH(n){var t,e;t=n.b,e=n.c,n.b=e,n.c=t}function rH(n){var t,e;e=n.d,t=n.a,n.d=t,n.a=e}function cH(n){return can(LU(QO(n)?Man(n):n))}function aH(n,t){return k$(aq(n.d),aq(t.d))}function uH(n,t){return t==(mUn(),SCt)?n.c:n.d}function oH(){oH=O,mUn(),xmt=SCt,Dmt=aCt}function sH(){this.b=Hy(ED(ppn((sRn(),rat))))}function hH(n){return bM(),L8(Cnt,FWn,1,n,5,1)}function fH(n){return new LI(n.c+n.b,n.d+n.a)}function lH(n,t){return TM(),k$(n.d.p,t.d.p)}function bH(n){return Mx(0!=n.b),Ctn(n,n.a.a)}function wH(n){return Mx(0!=n.b),Ctn(n,n.c.b)}function dH(n,t){if(!n)throw Fp(new Oy(t))}function gH(n,t){if(!n)throw Fp(new Ry(t))}function pH(n,t,e){bP.call(this,n,t),this.b=e}function vH(n,t,e){AC.call(this,n,t),this.c=e}function mH(n,t,e){ftn.call(this,t,e),this.d=n}function yH(n){a_(),yo.call(this),this.th(n)}function kH(n,t,e){this.a=n,$O.call(this,t,e)}function jH(n,t,e){this.a=n,$O.call(this,t,e)}function EH(n,t,e){AC.call(this,n,t),this.c=e}function TH(){x5(),aW.call(this,(UM(),HAt))}function MH(n){return null!=n&&!zbn(n,OAt,AAt)}function SH(n,t){return(Ufn(n)<<4|Ufn(t))&WVn}function PH(n,t){return YW(),qvn(n,t),new HW(n,t)}function IH(n,t){var e;n.n&&(e=t,UB(n.f,e))}function CH(n,t,e){etn(n,t,new HX(e))}function OH(n,t){var e;return e=n.c,Din(n,t),e}function AH(n,t){return n.g=t<0?-1:t,n}function $H(n,t){return qtn(n),n.a*=t,n.b*=t,n}function LH(n,t,e,i,r){n.c=t,n.d=e,n.b=i,n.a=r}function NH(n,t){return e5(n,t,n.c.b,n.c),!0}function xH(n){n.a.b=n.b,n.b.a=n.a,n.a=n.b=null}function DH(n){this.b=n,this.a=hz(this.b.a).Ed()}function RH(n,t){this.b=n,this.a=t,_h.call(this)}function KH(n,t){this.a=n,this.b=t,_h.call(this)}function _H(n,t){Gz.call(this,t,1040),this.a=n}function FH(n){return 0==n||isNaN(n)?n:n<0?-1:1}function BH(n){return EQ(),MMn(n)==QY(IMn(n))}function HH(n){return EQ(),IMn(n)==QY(MMn(n))}function qH(n,t){return Vjn(n,new bP(t.a,t.b))}function GH(n){return!f5(n)&&n.c.i.c==n.d.i.c}function zH(n){var t;return t=n.n,n.a.b+t.d+t.a}function UH(n){var t;return t=n.n,n.e.b+t.d+t.a}function XH(n){var t;return t=n.n,n.e.a+t.b+t.c}function WH(n){return lWn(),new aG(0,n)}function VH(n){return n.a?n.a:nQ(n)}function QH(n){if(!n)throw Fp(new Dy(null))}function JH(){JH=O,TQ(),rLt=new Hb(M7n)}function YH(){YH=O,new uvn((Zm(),Rnt),(ny(),Dnt))}function ZH(){ZH=O,Ptt=L8(Ctt,uVn,19,256,0,1)}function nq(n,t,e,i){rwn.call(this,n,t,e,i,0,0)}function tq(n,t,e){return XW(n.b,_B(e.b,17),t)}function eq(n,t,e){return XW(n.b,_B(e.b,17),t)}function iq(n,t){return UB(n,new LI(t.a,t.b))}function rq(n,t){return n.c=t)throw Fp(new Tv)}function Rz(n,t,e){return OX(t,0,Fq(t[0],e[0])),t}function Kz(n,t,e){t.Ye(e,Hy(ED(xX(n.b,e)))*n.a)}function _z(n,t,e){return yDn(),Ncn(n,t)&&Ncn(n,e)}function Fz(n){return hCn(),!n.Hc(nCt)&&!n.Hc(eCt)}function Bz(n){return new LI(n.c+n.b/2,n.d+n.a/2)}function Hz(n,t){return t.kh()?Zhn(n.b,_B(t,49)):t}function qz(n,t){this.e=n,this.d=0!=(64&t)?t|oVn:t}function Gz(n,t){this.c=0,this.d=n,this.b=64|t|oVn}function zz(n){this.b=new Q6(11),this.a=(MQ(),n)}function Uz(n){this.b=null,this.a=(MQ(),n||fet)}function Xz(n){this.a=evn(n.a),this.b=new ZK(n.b)}function Wz(n){this.b=n,ix.call(this,n),EL(this)}function Vz(n){this.b=n,cx.call(this,n),TL(this)}function Qz(n,t,e){this.a=n,nK.call(this,t,e,5,6)}function Jz(n,t,e,i){this.b=n,OL.call(this,t,e,i)}function Yz(n,t,e,i,r){m9.call(this,n,t,e,i,r,-1)}function Zz(n,t,e,i,r){y9.call(this,n,t,e,i,r,-1)}function nU(n,t,e,i){OL.call(this,n,t,e),this.b=i}function tU(n,t,e,i){vH.call(this,n,t,e),this.b=i}function eU(n){$C.call(this,n,!1),this.a=!1}function iU(n,t){this.b=n,ol.call(this,n.b),this.a=t}function rU(n,t){UX(),yT.call(this,n,ufn(new Qy(t)))}function cU(n,t){return lWn(),new iW(n,t,0)}function aU(n,t){return lWn(),new iW(6,n,t)}function uU(n,t){return pK(n.substr(0,t.length),t)}function oU(n,t){return zC(t)?nJ(n,t):!!CJ(n.f,t)}function sU(n,t){for(mW(t);n.Ob();)t.td(n.Pb())}function hU(n,t,e){IDn(),this.e=n,this.d=t,this.a=e}function fU(n,t,e,i){var r;(r=n.i).i=t,r.a=e,r.b=i}function lU(n){var t;for(t=n;t.f;)t=t.f;return t}function bU(n){var t;return Mx(null!=(t=kon(n))),t}function wU(n){var t;return Mx(null!=(t=pln(n))),t}function dU(n,t){var e;return l6(t,e=n.a.gc()),e-t}function gU(n,t){var e;for(e=0;e0?i.Math.log(n/t):-100}function KU(n,t){return Xhn(n,t)<0?-1:Xhn(n,t)>0?1:0}function _U(n,t,e){return THn(n,_B(t,46),_B(e,167))}function FU(n,t){return _B(lz(hz(n.a)).Xb(t),42).cd()}function BU(n,t){return dtn(t,n.length),new _H(n,t)}function HU(n,t){this.d=n,CL.call(this,n),this.e=t}function qU(n){this.d=(mW(n),n),this.a=0,this.c=fVn}function GU(n,t){Cp.call(this,1),this.a=n,this.b=t}function zU(n,t){return n.c?zU(n.c,t):UB(n.b,t),n}function UU(n,t,e){var i;return i=bnn(n,t),e4(n,t,e),i}function XU(n,t){return p7(n.slice(0,t),n)}function WU(n,t,e){var i;for(i=0;i=n.g}function JX(n,t,e){return $Rn(n,vrn(n,t,e))}function YX(n,t){var e;bnn(n,e=n.a.length),e4(n,e,t)}function ZX(n,t){console[n].call(console,t)}function nW(n,t){var e;++n.j,e=n.Vi(),n.Ii(n.oi(e,t))}function tW(n,t,e){_B(t.b,65),Itn(t.a,new kB(n,e,t))}function eW(n,t,e){yp.call(this,t),this.a=n,this.b=e}function iW(n,t,e){Cp.call(this,n),this.a=t,this.b=e}function rW(n,t,e){this.a=n,mp.call(this,t),this.b=e}function cW(n,t,e){this.a=n,F2.call(this,8,t,null,e)}function aW(n){this.a=(mW(R9n),R9n),this.b=n,new $m}function uW(n){this.c=n,this.b=this.c.a,this.a=this.c.e}function oW(n){this.c=n,this.b=n.a.d.a,fD(n.a.e,this)}function sW(n){Ex(-1!=n.c),n.d.$c(n.c),n.b=n.c,n.c=-1}function hW(n){return i.Math.sqrt(n.a*n.a+n.b*n.b)}function fW(n,t){return Dz(t,n.a.c.length),Lq(n.a,t)}function lW(n,t){return HC(n)===HC(t)||null!=n&&$fn(n,t)}function bW(n){return 0>=n?new XT:Uin(n-1)}function wW(n){return!!ENt&&nJ(ENt,n)}function dW(n){return n?n.dc():!n.Kc().Ob()}function gW(n){return!n.a&&n.c?n.c.b:n.a}function pW(n){return!n.a&&(n.a=new OL(OOt,n,4)),n.a}function vW(n){return!n.d&&(n.d=new OL(UAt,n,1)),n.d}function mW(n){if(null==n)throw Fp(new wv);return n}function yW(n){n.c?n.c.He():(n.d=!0,WNn(n))}function kW(n){n.c?kW(n.c):(Wln(n),n.d=!0)}function jW(n){jV(n.a),n.b=L8(Cnt,FWn,1,n.b.length,5,1)}function EW(n,t){return k$(t.j.c.length,n.j.c.length)}function TW(n,t){n.c<0||n.b.b=0?n.Bh(e):iCn(n,t)}function SW(n){return n.c.i.c==n.d.i.c}function PW(n){if(4!=n.p)throw Fp(new bv);return n.e}function IW(n){if(3!=n.p)throw Fp(new bv);return n.e}function CW(n){if(6!=n.p)throw Fp(new bv);return n.f}function OW(n){if(6!=n.p)throw Fp(new bv);return n.k}function AW(n){if(3!=n.p)throw Fp(new bv);return n.j}function $W(n){if(4!=n.p)throw Fp(new bv);return n.j}function LW(n){return!n.b&&(n.b=new jp(new Lm)),n.b}function NW(n){return-2==n.c&&wb(n,cMn(n.g,n.b)),n.c}function xW(n,t){var e;return(e=pX("",n)).n=t,e.i=1,e}function DW(n,t){AG(_B(t.b,65),n),Itn(t.a,new Cw(n))}function RW(n,t){s9((!n.a&&(n.a=new aR(n,n)),n.a),t)}function KW(n,t){this.b=n,HU.call(this,n,t),EL(this)}function _W(n,t){this.b=n,xK.call(this,n,t),TL(this)}function FW(n,t,e,i){gT.call(this,n,t),this.d=e,this.a=i}function BW(n,t,e,i){gT.call(this,n,e),this.a=t,this.f=i}function HW(n,t){U$.call(this,Xin(vX(n),vX(t))),this.a=t}function qW(){bMn.call(this,T7n,(eE(),lLt)),Uqn(this)}function GW(){bMn.call(this,X9n,(tE(),JAt)),IHn(this)}function zW(){wT.call(this,"DELAUNAY_TRIANGULATION",0)}function UW(n){return String.fromCharCode.apply(null,n)}function XW(n,t,e){return zC(t)?pZ(n,t,e):yIn(n.f,t,e)}function WW(n){return TQ(),n?n.ve():(MQ(),MQ(),wet)}function VW(n,t,e){return $un(),e.pg(n,_B(t.cd(),146))}function QW(n,t){return YH(),new uvn(new eN(n),new tN(t))}function JW(n){return hin(n,$Vn),Znn(ebn(ebn(5,n),n/10|0))}function YW(){YW=O,_nt=new oy(Mun(Hk(Fnt,1),mVn,42,0,[]))}function ZW(n){return!n.d&&(n.d=new Fb(n.c.Cc())),n.d}function nV(n){return!n.a&&(n.a=new Ak(n.c.vc())),n.a}function tV(n){return!n.b&&(n.b=new Ck(n.c.ec())),n.b}function eV(n,t){for(;t-- >0;)n=n<<1|(n<0?1:0);return n}function iV(n,t){return HC(n)===HC(t)||null!=n&&$fn(n,t)}function rV(n,t){return oN(),_B(t.b,19).a(i=SY(e))&&++i,i}function JV(n){var t;return ien(t=new Dp,n),t}function YV(n){var t;return NMn(t=new Dp,n),t}function ZV(n,t){return Dcn(t,xX(n.f,t)),null}function nQ(n){return Vin(n)||null}function tQ(n){return!n.b&&(n.b=new nU(DOt,n,12,3)),n.b}function eQ(n){return null!=n&<(mAt,n.toLowerCase())}function iQ(n,t){return Mln(tG(n)*nG(n),tG(t)*nG(t))}function rQ(n,t){return Mln(tG(n)*nG(n),tG(t)*nG(t))}function cQ(n,t){return Mln(n.d.c+n.d.b/2,t.d.c+t.d.b/2)}function aQ(n,t){return Mln(n.g.c+n.g.b/2,t.g.c+t.g.b/2)}function uQ(n,t,e){e.a?Sen(n,t.b-n.f/2):Men(n,t.a-n.g/2)}function oQ(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function sQ(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function hQ(n,t,e,i){this.e=n,this.a=t,this.c=e,this.d=i}function fQ(n,t,e,i){this.a=n,this.c=t,this.d=e,this.b=i}function lQ(n,t,e,i){s$(),n6.call(this,t,e,i),this.a=n}function bQ(n,t,e,i){s$(),n6.call(this,t,e,i),this.a=n}function wQ(n,t){this.a=n,ID.call(this,n,_B(n.d,15).Zc(t))}function dQ(n){this.f=n,this.c=this.f.e,n.f>0&&cjn(this)}function gQ(n,t,e,i){this.b=n,this.c=i,gO.call(this,t,e)}function pQ(n){return Mx(n.b=0&&pK(n.substr(e,t.length),t)}function AJ(n,t,e,i,r,c,a){return new f4(n.e,t,e,i,r,c,a)}function $J(n,t,e,i,r,c){this.a=n,min.call(this,t,e,i,r,c)}function LJ(n,t,e,i,r,c){this.a=n,min.call(this,t,e,i,r,c)}function NJ(n,t){this.g=n,this.d=Mun(Hk(Iut,1),r1n,10,0,[t])}function xJ(n,t){this.e=n,this.a=Cnt,this.b=CRn(t),this.c=t}function DJ(n,t){$R.call(this),Ltn(this),this.a=n,this.c=t}function RJ(n,t,e,i){OX(n.c[t.g],e.g,i),OX(n.c[e.g],t.g,i)}function KJ(n,t,e,i){OX(n.c[t.g],t.g,e),OX(n.b[t.g],t.g,i)}function _J(){return C6(),Mun(Hk(imt,1),OVn,376,0,[Jvt,Qvt])}function FJ(){return w7(),Mun(Hk(Jht,1),OVn,479,0,[Hht,Bht])}function BJ(){return Rnn(),Mun(Hk(Aht,1),OVn,419,0,[Tht,Mht])}function HJ(){return X8(),Mun(Hk(hht,1),OVn,422,0,[iht,rht])}function qJ(){return q2(),Mun(Hk(Hlt,1),OVn,420,0,[Cft,Oft])}function GJ(){return G7(),Mun(Hk(qvt,1),OVn,421,0,[Dvt,Rvt])}function zJ(){return W4(),Mun(Hk(Xmt,1),OVn,523,0,[Fmt,_mt])}function UJ(){return I6(),Mun(Hk(Lyt,1),OVn,520,0,[Eyt,jyt])}function XJ(){return wY(),Mun(Hk(ryt,1),OVn,516,0,[Zmt,Ymt])}function WJ(){return aZ(),Mun(Hk(Tyt,1),OVn,515,0,[eyt,iyt])}function VJ(){return bY(),Mun(Hk(_yt,1),OVn,455,0,[Ayt,$yt])}function QJ(){return _0(),Mun(Hk(Qkt,1),OVn,425,0,[Fkt,_kt])}function JJ(){return uZ(),Mun(Hk(Bkt,1),OVn,480,0,[xkt,Dkt])}function YJ(){return Mrn(),Mun(Hk(tjt,1),OVn,495,0,[Wkt,Vkt])}function ZJ(){return N9(),Mun(Hk(hjt,1),OVn,426,0,[ijt,rjt])}function nY(){return Aun(),Mun(Hk(VTt,1),OVn,429,0,[UTt,zTt])}function tY(){return O6(),Mun(Hk(aTt,1),OVn,430,0,[YEt,JEt])}function eY(){return opn(),Mun(Hk(vit,1),OVn,428,0,[bit,lit])}function iY(){return xnn(),Mun(Hk(Dit,1),OVn,427,0,[git,pit])}function rY(){return Dnn(),Mun(Hk(Oat,1),OVn,424,0,[Nct,xct])}function cY(){return Trn(),Mun(Hk(Uut,1),OVn,511,0,[But,Fut])}function aY(n,t,e,i){return e>=0?n.jh(t,e,i):n.Sg(null,e,i)}function uY(n){return 0==n.b.b?n.a.$e():bH(n.b)}function oY(n){if(5!=n.p)throw Fp(new bv);return bG(n.f)}function sY(n){if(5!=n.p)throw Fp(new bv);return bG(n.k)}function hY(n){return HC(n.a)===HC((lcn(),S$t))&&xqn(n),n.a}function fY(n){this.a=_B(vX(n),271),this.b=(TQ(),new bN(n))}function lY(n,t){Jl(this,new LI(n.a,n.b)),Yl(this,qB(t))}function bY(){bY=O,Ayt=new aI(iYn,0),$yt=new aI(rYn,1)}function wY(){wY=O,Zmt=new iI(rYn,0),Ymt=new iI(iYn,1)}function dY(){ry.call(this,new zT(ntn(12))),rN(!0),this.a=2}function gY(n,t,e){lWn(),Cp.call(this,n),this.b=t,this.a=e}function pY(n,t,e){s$(),yp.call(this,t),this.a=n,this.b=e}function vY(n){$R.call(this),Ltn(this),this.a=n,this.c=!0}function mY(n){var t;t=n.c.d.b,n.b=t,n.a=n.c.d,t.a=n.c.d.b=n}function yY(n){din(n.a),xA(n.a),Zbn(new Mw(n.a))}function kY(n,t){aRn(n,!0),Itn(n.e.wf(),new O_(n,!0,t))}function jY(n,t){return i4(t),Ven(n,L8(INt,oQn,25,t,15,1),t)}function EY(n,t){return EQ(),n==QY(MMn(t))||n==QY(IMn(t))}function TY(n,t){return null==t?BC(CJ(n.f,null)):oS(n.g,t)}function MY(n){return 0==n.b?null:(Mx(0!=n.b),Ctn(n,n.a.a))}function SY(n){return 0|Math.max(Math.min(n,NWn),-2147483648)}function PY(n,t){var e=Jnt[n.charCodeAt(0)];return null==e?n:e}function IY(n,t){return UQ(n,"set1"),UQ(t,"set2"),new kT(n,t)}function CY(n,t){return GR(Bx(Ytn(n.f,t)),n.f.d)}function OY(n,t){var e;return VGn(n,t,e=new q),e.d}function AY(n,t,e,i){var r;r=new KR,t.a[e.g]=r,pG(n.b,i,r)}function $Y(n,t,e){var i;(i=n.Yg(t))>=0?n.sh(i,e):jLn(n,t,e)}function LY(n,t,e){oZ(),n&&XW(aAt,n,t),n&&XW(cAt,n,e)}function NY(n,t,e){this.i=new $p,this.b=n,this.g=t,this.a=e}function xY(n,t,e){this.c=new $p,this.e=n,this.f=t,this.b=e}function DY(n,t,e){this.a=new $p,this.e=n,this.f=t,this.c=e}function RY(n,t){X$(this),this.f=t,this.g=n,yQ(this),this._d()}function KY(n,t){var e;e=n.q.getHours(),n.q.setDate(t),hBn(n,e)}function _Y(n,t){var e;for(vX(t),e=n.a;e;e=e.c)t.Od(e.g,e.i)}function FY(n){var t;return Oon(t=new fE(ntn(n.length)),n),t}function BY(n){function t(){}return t.prototype=n||{},new t}function HY(n,t){return!!lun(n,t)&&(nin(n),!0)}function qY(n,t){if(null==t)throw Fp(new wv);return cgn(n,t)}function GY(n){if(n.qe())return null;var t=n.n;return TWn[t]}function zY(n){return n.Db>>16!=3?null:_B(n.Cb,33)}function UY(n){return n.Db>>16!=9?null:_B(n.Cb,33)}function XY(n){return n.Db>>16!=6?null:_B(n.Cb,79)}function WY(n){return n.Db>>16!=7?null:_B(n.Cb,235)}function VY(n){return n.Db>>16!=7?null:_B(n.Cb,160)}function QY(n){return n.Db>>16!=11?null:_B(n.Cb,33)}function JY(n,t){var e;return(e=n.Yg(t))>=0?n.lh(e):BCn(n,t)}function YY(n,t){var e;return aMn(e=new Aq(t),n),new ZK(e)}function ZY(n){var t;return t=n.d,t=n.si(n.f),s9(n,t),t.Ob()}function nZ(n,t){return n.b+=t.b,n.c+=t.c,n.d+=t.d,n.a+=t.a,n}function tZ(n,t){return i.Math.abs(n)0}function iZ(){this.a=new sA,this.e=new xv,this.g=0,this.i=0}function rZ(n){this.a=n,this.b=L8(Rmt,uVn,1944,n.e.length,0,2)}function cZ(n,t,e){var i;i=$on(n,t,e),n.b=new prn(i.c.length)}function aZ(){aZ=O,eyt=new eI(dYn,0),iyt=new eI("UP",1)}function uZ(){uZ=O,xkt=new fI(G3n,0),Dkt=new fI("FAN",1)}function oZ(){oZ=O,aAt=new Lp,cAt=new Lp,KC(vet,new wo)}function sZ(n){if(0!=n.p)throw Fp(new bv);return QC(n.f,0)}function hZ(n){if(0!=n.p)throw Fp(new bv);return QC(n.k,0)}function fZ(n){return n.Db>>16!=3?null:_B(n.Cb,147)}function lZ(n){return n.Db>>16!=6?null:_B(n.Cb,235)}function bZ(n){return n.Db>>16!=17?null:_B(n.Cb,26)}function wZ(n,t){var e=n.a=n.a||[];return e[t]||(e[t]=n.le(t))}function dZ(n,t){var e;return null==(e=n.a.get(t))?new Array:e}function gZ(n,t){var e;e=n.q.getHours(),n.q.setMonth(t),hBn(n,e)}function pZ(n,t,e){return null==t?yIn(n.f,null,e):cbn(n.g,t,e)}function vZ(n,t,e,i,r,c){return new $7(n.e,t,n.aj(),e,i,r,c)}function mZ(n,t,e){return n.a=sx(n.a,0,t)+""+e+YC(n.a,t),n}function yZ(n,t,e){return UB(n.a,(YW(),qvn(t,e),new gT(t,e))),n}function kZ(n){return aN(n.c),n.e=n.a=n.c,n.c=n.c.c,++n.d,n.a.f}function jZ(n){return aN(n.e),n.c=n.a=n.e,n.e=n.e.e,--n.d,n.a.f}function EZ(n,t){n.d&&v7(n.d.e,n),n.d=t,n.d&&UB(n.d.e,n)}function TZ(n,t){n.c&&v7(n.c.g,n),n.c=t,n.c&&UB(n.c.g,n)}function MZ(n,t){n.c&&v7(n.c.a,n),n.c=t,n.c&&UB(n.c.a,n)}function SZ(n,t){n.i&&v7(n.i.j,n),n.i=t,n.i&&UB(n.i.j,n)}function PZ(n,t,e){this.a=t,this.c=n,this.b=(vX(e),new ZK(e))}function IZ(n,t,e){this.a=t,this.c=n,this.b=(vX(e),new ZK(e))}function CZ(n,t){this.a=n,this.c=_$(this.a),this.b=new wJ(t)}function OZ(n){return Wln(n),CV(n,new gw(new xv))}function AZ(n,t){if(n<0||n>t)throw Fp(new Cy(yJn+n+kJn+t))}function $Z(n,t){return PG(n.a,t)?kU(n,_B(t,22).g,null):null}function LZ(n){return Thn(),oN(),0!=_B(n.a,81).d.e}function NZ(){NZ=O,znt=hhn((ey(),Mun(Hk(Unt,1),OVn,538,0,[qnt])))}function xZ(){xZ=O,dmt=UG(new _2,(vMn(),_at),(hWn(),Bot))}function DZ(){DZ=O,gmt=UG(new _2,(vMn(),_at),(hWn(),Bot))}function RZ(){RZ=O,vmt=UG(new _2,(vMn(),_at),(hWn(),Bot))}function KZ(){KZ=O,qmt=bq(new _2,(vMn(),_at),(hWn(),bot))}function _Z(){_Z=O,Wmt=bq(new _2,(vMn(),_at),(hWn(),bot))}function FZ(){FZ=O,Jmt=bq(new _2,(vMn(),_at),(hWn(),bot))}function BZ(){BZ=O,ayt=bq(new _2,(vMn(),_at),(hWn(),bot))}function HZ(){HZ=O,qkt=UG(new _2,(qyn(),Kyt),(NPn(),qyt))}function qZ(n,t,e,i){this.c=n,this.d=i,UZ(this,t),XZ(this,e)}function GZ(n){this.c=new VT,this.b=n.b,this.d=n.c,this.a=n.a}function zZ(n){this.a=i.Math.cos(n),this.b=i.Math.sin(n)}function UZ(n,t){n.a&&v7(n.a.k,n),n.a=t,n.a&&UB(n.a.k,n)}function XZ(n,t){n.b&&v7(n.b.f,n),n.b=t,n.b&&UB(n.b.f,n)}function WZ(n,t){tW(n,n.b,n.c),_B(n.b.b,65),t&&_B(t.b,65).b}function VZ(n,t){qln(n,t),iL(n.Cb,88)&&CIn(M5(_B(n.Cb,88)),2)}function QZ(n,t){iL(n.Cb,88)&&CIn(M5(_B(n.Cb,88)),4),$rn(n,t)}function JZ(n,t){iL(n.Cb,179)&&(_B(n.Cb,179).tb=null),$rn(n,t)}function YZ(n,t){return JM(),onn(t)?new hq(t,n):new LC(t,n)}function ZZ(n,t){null!=t.c&&YX(n,new HX(t.c))}function n1(n){var t;return tE(),ien(t=new Dp,n),t}function t1(n){var t;return tE(),ien(t=new Dp,n),t}function e1(n,t){var e;return e=new FX(n),t.c[t.c.length]=e,e}function i1(n,t){var e;return(e=_B(hfn(IQ(n.a),t),14))?e.gc():0}function r1(n){return Wln(n),MQ(),MQ(),vtn(n,bet)}function c1(n){for(var t;;)if(t=n.Pb(),!n.Ob())return t}function a1(n,t){Gm.call(this,new zT(ntn(n))),hin(t,aVn),this.a=t}function u1(n,t,e){Ffn(t,e,n.gc()),this.c=n,this.a=t,this.b=e-t}function o1(n,t,e){var i;Ffn(t,e,n.c.length),i=e-t,ME(n.c,t,i)}function s1(n,t){oL(n,bG(n0(mz(t,24),uJn)),bG(n0(t,uJn)))}function h1(n,t){if(n<0||n>=t)throw Fp(new Cy(yJn+n+kJn+t))}function f1(n,t){if(n<0||n>=t)throw Fp(new Ik(yJn+n+kJn+t))}function l1(n,t){this.b=(mW(n),n),this.a=0==(t&RQn)?64|t|oVn:t}function b1(n){NA(this),Mv(this.a,mon(i.Math.max(8,n))<<1)}function w1(n){return Con(Mun(Hk(MMt,1),uVn,8,0,[n.i.n,n.n,n.a]))}function d1(){return Bsn(),Mun(Hk(Yet,1),OVn,132,0,[qet,Get,zet])}function g1(){return Ntn(),Mun(Hk(Xit,1),OVn,232,0,[Hit,qit,Git])}function p1(){return Q9(),Mun(Hk(nrt,1),OVn,461,0,[Vit,Wit,Qit])}function v1(){return H7(),Mun(Hk(Irt,1),OVn,462,0,[irt,ert,trt])}function m1(){return _fn(),Mun(Hk(put,1),OVn,423,0,[lut,fut,hut])}function y1(){return B7(),Mun(Hk(Fat,1),OVn,379,0,[Iat,Pat,Cat])}function k1(){return Ehn(),Mun(Hk(lvt,1),OVn,378,0,[ivt,rvt,cvt])}function j1(){return Iin(),Mun(Hk(dht,1),OVn,314,0,[oht,uht,sht])}function E1(){return cin(),Mun(Hk(jht,1),OVn,337,0,[lht,wht,bht])}function T1(){return Qun(),Mun(Hk(_ht,1),OVn,450,0,[Cht,Iht,Oht])}function M1(){return Srn(),Mun(Hk(Ust,1),OVn,361,0,[xst,Nst,Lst])}function S1(){return q7(),Mun(Hk(Aft,1),OVn,303,0,[Mft,Sft,Tft])}function P1(){return Dan(),Mun(Hk(Pft,1),OVn,292,0,[yft,kft,mft])}function I1(){return rin(),Mun(Hk(Wvt,1),OVn,452,0,[Hvt,Fvt,Bvt])}function C1(){return pon(),Mun(Hk(Kvt,1),OVn,339,0,[$vt,Avt,Lvt])}function O1(){return Fcn(),Mun(Hk(Yvt,1),OVn,375,0,[zvt,Uvt,Xvt])}function A1(){return Oun(),Mun(Hk(Tmt,1),OVn,377,0,[fmt,lmt,hmt])}function $1(){return Gsn(),Mun(Hk(omt,1),OVn,336,0,[nmt,tmt,emt])}function L1(){return bcn(),Mun(Hk(bmt,1),OVn,338,0,[umt,cmt,amt])}function N1(){return ain(),Mun(Hk(Lmt,1),OVn,454,0,[Imt,Cmt,Omt])}function x1(){return Sbn(),Mun(Hk(cjt,1),OVn,442,0,[njt,Ykt,Zkt])}function D1(){return Fsn(),Mun(Hk(Hjt,1),OVn,380,0,[ujt,ojt,sjt])}function R1(){return Tbn(),Mun(Hk($Et,1),OVn,381,0,[Jjt,Yjt,Qjt])}function K1(){return _cn(),Mun(Hk(Vjt,1),OVn,293,0,[zjt,Ujt,Gjt])}function _1(){return Mbn(),Mun(Hk(UEt,1),OVn,437,0,[FEt,BEt,HEt])}function F1(){return cfn(),Mun(Hk(TIt,1),OVn,334,0,[gIt,dIt,pIt])}function B1(){return xtn(),Mun(Hk(YPt,1),OVn,272,0,[qPt,GPt,zPt])}function H1(n,t){return m$n(n,t,iL(t,99)&&0!=(_B(t,18).Bb&_Qn))}function q1(n,t,e){var i;return(i=iHn(n,t,!1)).b<=t&&i.a<=e}function G1(n,t,e){var i;(i=new ca).b=t,i.a=e,++t.b,UB(n.d,i)}function z1(n,t){var e;return jx(!!(e=(mW(n),n).g)),mW(t),e(t)}function U1(n,t){var e,i;return i=dU(n,t),e=n.a.Zc(i),new mT(n,e)}function X1(n){return n.Db>>16!=6?null:_B(iAn(n),235)}function W1(n){if(2!=n.p)throw Fp(new bv);return bG(n.f)&WVn}function V1(n){if(2!=n.p)throw Fp(new bv);return bG(n.k)&WVn}function Q1(n){return n.a==(x5(),Z$t)&&bb(n,nLn(n.g,n.b)),n.a}function J1(n){return n.d==(x5(),Z$t)&&db(n,$Kn(n.g,n.b)),n.d}function Y1(n){return Mx(n.ai?1:0}function l0(n,t){var e;return e=T7(t),_B(xX(n.c,e),19).a}function b0(n,t){var e;for(e=n+"";e.length0&&0==n.a[--n.d];);0==n.a[n.d++]&&(n.e=0)}function U0(n){return n.a?0==n.e.length?n.a.a:n.a.a+""+n.e:n.c}function X0(n){return!(!n.a||0==F7(n.a.a).i||n.b&&Dvn(n.b))}function W0(n){return!(!n.u||0==r4(n.u.a).i||n.n&&xvn(n.n))}function V0(n){return vq(n.e.Hd().gc()*n.c.Hd().gc(),16,new qf(n))}function Q0(n,t){return KU(san(n.q.getTime()),san(t.q.getTime()))}function J0(n){return _B(Wgn(n,L8(vut,i1n,17,n.c.length,0,1)),474)}function Y0(n){return _B(Wgn(n,L8(Iut,r1n,10,n.c.length,0,1)),193)}function Z0(n){return _Z(),!(f5(n)||!f5(n)&&n.c.i.c==n.d.i.c)}function n2(n,t,e){vX(n),Lyn(new PZ(new ZK(n),t,e))}function t2(n,t,e){vX(n),Nyn(new IZ(new ZK(n),t,e))}function e2(n,t){var e;return e=1-t,n.a[e]=lrn(n.a[e],e),lrn(n,t)}function i2(n,t){var e;n.e=new Qm,p$(e=lDn(t),n.c),PDn(n,e,0)}function r2(n,t,e,i){var r;(r=new vu).a=t,r.b=e,r.c=i,NH(n.a,r)}function c2(n,t,e,i){var r;(r=new vu).a=t,r.b=e,r.c=i,NH(n.b,r)}function a2(n){var t,e;return e=ZKn(t=new hX,n),vzn(t),e}function u2(){var n,t;return n=new Dp,UB(U$t,t=n),t}function o2(n){return n.j.c=L8(Cnt,FWn,1,0,5,1),jV(n.c),wV(n.a),n}function s2(n){return EM(),iL(n.g,10)?_B(n.g,10):null}function h2(n){return!kV(n).dc()&&(A$(n,new m),!0)}function f2(n){if(!("stack"in n))try{throw n}catch(t){}return n}function l2(n,t){if(n<0||n>=t)throw Fp(new Cy(AIn(n,t)));return n}function b2(n,t,e){if(n<0||te)throw Fp(new Cy(aPn(n,t,e)))}function w2(n,t){if(jU(n.a,t),t.d)throw Fp(new by(PJn));t.d=n}function d2(n,t){if(t.$modCount!=n.$modCount)throw Fp(new gv)}function g2(n,t){return!!iL(t,42)&&Emn(n.a,_B(t,42))}function p2(n,t){return!!iL(t,42)&&Emn(n.a,_B(t,42))}function v2(n,t){return!!iL(t,42)&&Emn(n.a,_B(t,42))}function m2(n,t){return n.a<=n.b&&(t.ud(n.a++),!0)}function y2(n){var t;return QO(n)?-0==(t=n)?0:t:dnn(n)}function k2(n){var t;return kW(n),t=new F,wE(n.a,new ww(t)),t}function j2(n){var t;return kW(n),t=new _,wE(n.a,new bw(t)),t}function E2(n,t){this.a=n,Tb.call(this,n),AZ(t,n.gc()),this.b=t}function T2(n){this.e=n,this.b=this.e.a.entries(),this.a=new Array}function M2(n){return vq(n.e.Hd().gc()*n.c.Hd().gc(),273,new Hf(n))}function S2(n){return new Q6((hin(n,$Vn),Znn(ebn(ebn(5,n),n/10|0))))}function P2(n){return _B(Wgn(n,L8(Hut,c1n,11,n.c.length,0,1)),1943)}function I2(n,t,e){return e.f.c.length>0?_U(n.a,t,e):_U(n.b,t,e)}function C2(n,t,e){n.d&&v7(n.d.e,n),n.d=t,n.d&&mG(n.d.e,e,n)}function O2(n,t){gXn(t,n),rH(n.d),rH(_B(pMn(n,(FXn(),Cgt)),207))}function A2(n,t){dXn(t,n),iH(n.d),iH(_B(pMn(n,(FXn(),Cgt)),207))}function $2(n,t){var e,i;return i=null,(e=qY(n,t))&&(i=e.fe()),i}function L2(n,t){var e,i;return i=null,(e=bnn(n,t))&&(i=e.ie()),i}function N2(n,t){var e,i;return i=null,(e=qY(n,t))&&(i=e.ie()),i}function x2(n,t){var e,i;return i=null,(e=qY(n,t))&&(i=vPn(e)),i}function D2(n,t,e){var i;return i=Wdn(e),lKn(n.g,i,t),lKn(n.i,t,e),t}function R2(n,t,e){var i;i=Adn();try{return bR(n,t,e)}finally{v3(i)}}function K2(n){var t;t=n.Wg(),this.a=iL(t,69)?_B(t,69).Zh():t.Kc()}function _2(){Vm.call(this),this.j.c=L8(Cnt,FWn,1,0,5,1),this.a=-1}function F2(n,t,e,i){this.d=n,this.n=t,this.g=e,this.o=i,this.p=-1}function B2(n,t,e,i){this.e=i,this.d=null,this.c=n,this.a=t,this.b=e}function H2(n,t,e){this.d=new Kd(this),this.e=n,this.i=t,this.f=e}function q2(){q2=O,Cft=new NP(nYn,0),Oft=new NP("TOP_LEFT",1)}function G2(){G2=O,jmt=QW(tln(1),tln(4)),kmt=QW(tln(1),tln(2))}function z2(){z2=O,QEt=hhn((PM(),Mun(Hk(ZEt,1),OVn,551,0,[WEt])))}function U2(){U2=O,XEt=hhn((SM(),Mun(Hk(VEt,1),OVn,482,0,[zEt])))}function X2(){X2=O,GTt=hhn((IM(),Mun(Hk(XTt,1),OVn,530,0,[HTt])))}function W2(){W2=O,rct=hhn((lM(),Mun(Hk(Mct,1),OVn,481,0,[ect])))}function V2(){return Nan(),Mun(Hk(Hrt,1),OVn,406,0,[xrt,$rt,Lrt,Nrt])}function Q2(){return J9(),Mun(Hk(Ket,1),OVn,297,0,[$et,Let,Net,xet])}function J2(){return Bpn(),Mun(Hk(ict,1),OVn,394,0,[Jrt,Qrt,Yrt,Zrt])}function Y2(){return Fpn(),Mun(Hk(Grt,1),OVn,323,0,[_rt,Krt,Frt,Brt])}function Z2(){return Cun(),Mun(Hk(but,1),OVn,405,0,[Jat,nut,Yat,Zat])}function n3(){return Pun(),Mun(Hk(dst,1),OVn,360,0,[rst,est,ist,tst])}function t3(n,t,e,i){return iL(e,54)?new Ix(n,t,e,i):new uz(n,t,e,i)}function e3(){return Iun(),Mun(Hk(Pst,1),OVn,411,0,[gst,pst,vst,mst])}function i3(n){return n.j==(mUn(),TCt)&&TN(GOn(n),aCt)}function r3(n,t){var e;TZ(e=t.a,t.c.d),EZ(e,t.d.d),Jtn(e.a,n.n)}function c3(n,t){return _B(ON(Pz(_B(o6(n.k,t),15).Oc(),Wst)),113)}function a3(n,t){return _B(ON(Iz(_B(o6(n.k,t),15).Oc(),Wst)),113)}function u3(n){return new l1(Zrn(_B(n.a.dd(),14).gc(),n.a.cd()),16)}function o3(n){return iL(n,14)?_B(n,14).dc():!n.Kc().Ob()}function s3(n){return EM(),iL(n.g,145)?_B(n.g,145):null}function h3(n){if(n.e.g!=n.b)throw Fp(new gv);return!!n.c&&n.d>0}function f3(n){return Mx(n.b!=n.d.c),n.c=n.b,n.b=n.b.a,++n.a,n.c.c}function l3(n,t){mW(t),OX(n.a,n.c,t),n.c=n.c+1&n.a.length-1,lyn(n)}function b3(n,t){mW(t),n.b=n.b-1&n.a.length-1,OX(n.a,n.b,t),lyn(n)}function w3(n,t){var e;for(e=n.j.c.length;e0&&rHn(n.g,0,t,0,n.i),t}function L3(n,t){var e;return YM(),!(e=_B(xX(gAt,n),55))||e.wj(t)}function N3(n){if(1!=n.p)throw Fp(new bv);return bG(n.f)<<24>>24}function x3(n){if(1!=n.p)throw Fp(new bv);return bG(n.k)<<24>>24}function D3(n){if(7!=n.p)throw Fp(new bv);return bG(n.k)<<16>>16}function R3(n){if(7!=n.p)throw Fp(new bv);return bG(n.f)<<16>>16}function K3(n){var t;for(t=0;n.Ob();)n.Pb(),t=ebn(t,1);return Znn(t)}function _3(n,t){var e;return e=new Pk,n.xd(e),e.a+="..",t.yd(e),e.a}function F3(n,t,e){var i;i=_B(xX(n.g,e),57),UB(n.a.c,new eC(t,i))}function B3(n,t,e){return jz(ED(BC(CJ(n.f,t))),ED(BC(CJ(n.f,e))))}function H3(n,t,e){return GFn(n,t,e,iL(t,99)&&0!=(_B(t,18).Bb&_Qn))}function q3(n,t,e){return dBn(n,t,e,iL(t,99)&&0!=(_B(t,18).Bb&_Qn))}function G3(n,t,e){return L$n(n,t,e,iL(t,99)&&0!=(_B(t,18).Bb&_Qn))}function z3(n,t){return n==(cSn(),Sut)&&t==Sut?4:n==Sut||t==Sut?8:32}function U3(n,t){return HC(t)===HC(n)?"(this Map)":null==t?qWn:_bn(t)}function X3(n,t){return _B(null==t?BC(CJ(n.f,null)):oS(n.g,t),281)}function W3(n,t,e){var i;return i=Wdn(e),XW(n.b,i,t),XW(n.c,t,e),t}function V3(n,t){var e;for(e=t;e;)Rx(n,e.i,e.j),e=QY(e);return n}function Q3(n,t){var e;return e=eJ(FB(new S7(n,t))),Sq(new S7(n,t)),e}function J3(n,t){var e;return JM(),jSn(e=_B(n,66).Mj(),t),e.Ok(t)}function Y3(n,t,e,i,r){UB(t,pIn(r,z$n(r,e,i))),GMn(n,r,t)}function Z3(n,t,e){n.i=0,n.e=0,t!=e&&(Uon(n,t,e),zon(n,t,e))}function n4(n,t){var e;e=n.q.getHours(),n.q.setFullYear(t+uQn),hBn(n,e)}function t4(n,t,e){if(e){var i=e.ee();n.a[t]=i(e)}else delete n.a[t]}function e4(n,t,e){if(e){var i=e.ee();e=i(e)}else e=void 0;n.a[t]=e}function i4(n){if(n<0)throw Fp(new _y("Negative array size: "+n))}function r4(n){return n.n||(M5(n),n.n=new VG(n,UAt,n),mJ(n)),n.n}function c4(n){return Mx(n.a=0&&n.a[e]===t[e];e--);return e<0}function j4(n,t){var e;return qsn(),0!=(e=n.j.g-t.j.g)?e:0}function E4(n,t){return mW(t),null!=n.a?MG(t.Kb(n.a)):Tet}function T4(n){var t;return n?new Aq(n):(Brn(t=new sA,n),t)}function M4(n,t){return t.b.Kb(j7(n,t.c.Ee(),new vw(t)))}function S4(n){vTn(),oL(this,bG(n0(mz(n,24),uJn)),bG(n0(n,uJn)))}function P4(){P4=O,dit=hhn((opn(),Mun(Hk(vit,1),OVn,428,0,[bit,lit])))}function I4(){I4=O,mit=hhn((xnn(),Mun(Hk(Dit,1),OVn,427,0,[git,pit])))}function C4(){C4=O,Rct=hhn((Dnn(),Mun(Hk(Oat,1),OVn,424,0,[Nct,xct])))}function O4(){O4=O,qut=hhn((Trn(),Mun(Hk(Uut,1),OVn,511,0,[But,Fut])))}function A4(){A4=O,Pht=hhn((Rnn(),Mun(Hk(Aht,1),OVn,419,0,[Tht,Mht])))}function $4(){$4=O,Ght=hhn((w7(),Mun(Hk(Jht,1),OVn,479,0,[Hht,Bht])))}function L4(){L4=O,Zvt=hhn((C6(),Mun(Hk(imt,1),OVn,376,0,[Jvt,Qvt])))}function N4(){N4=O,_vt=hhn((G7(),Mun(Hk(qvt,1),OVn,421,0,[Dvt,Rvt])))}function x4(){x4=O,aht=hhn((X8(),Mun(Hk(hht,1),OVn,422,0,[iht,rht])))}function D4(){D4=O,$ft=hhn((q2(),Mun(Hk(Hlt,1),OVn,420,0,[Cft,Oft])))}function R4(){R4=O,Myt=hhn((I6(),Mun(Hk(Lyt,1),OVn,520,0,[Eyt,jyt])))}function K4(){K4=O,Hmt=hhn((W4(),Mun(Hk(Xmt,1),OVn,523,0,[Fmt,_mt])))}function _4(){_4=O,tyt=hhn((wY(),Mun(Hk(ryt,1),OVn,516,0,[Zmt,Ymt])))}function F4(){F4=O,cyt=hhn((aZ(),Mun(Hk(Tyt,1),OVn,515,0,[eyt,iyt])))}function B4(){B4=O,Nyt=hhn((bY(),Mun(Hk(_yt,1),OVn,455,0,[Ayt,$yt])))}function H4(){H4=O,Hkt=hhn((_0(),Mun(Hk(Qkt,1),OVn,425,0,[Fkt,_kt])))}function q4(){q4=O,Jkt=hhn((Mrn(),Mun(Hk(tjt,1),OVn,495,0,[Wkt,Vkt])))}function G4(){G4=O,Kkt=hhn((uZ(),Mun(Hk(Bkt,1),OVn,480,0,[xkt,Dkt])))}function z4(){z4=O,ajt=hhn((N9(),Mun(Hk(hjt,1),OVn,426,0,[ijt,rjt])))}function U4(){U4=O,WTt=hhn((Aun(),Mun(Hk(VTt,1),OVn,429,0,[UTt,zTt])))}function X4(){X4=O,nTt=hhn((O6(),Mun(Hk(aTt,1),OVn,430,0,[YEt,JEt])))}function W4(){W4=O,Fmt=new QP("UPPER",0),_mt=new QP("LOWER",1)}function V4(n,t){var e;BQ(e=new dy,"x",t.a),BQ(e,"y",t.b),YX(n,e)}function Q4(n,t){var e;BQ(e=new dy,"x",t.a),BQ(e,"y",t.b),YX(n,e)}function J4(n,t){var e,i;i=!1;do{i|=e=fon(n,t)}while(e);return i}function Y4(n,t){var e,i;for(e=t,i=0;e>0;)i+=n.a[e],e-=e&-e;return i}function Z4(n,t){var e;for(e=t;e;)Rx(n,-e.i,-e.j),e=QY(e);return n}function n5(n,t){var e,i;for(mW(t),i=n.Kc();i.Ob();)e=i.Pb(),t.td(e)}function t5(n,t){var e;return new gT(e=t.cd(),n.e.pc(e,_B(t.dd(),14)))}function e5(n,t,e,i){var r;(r=new $).c=t,r.b=e,r.a=i,i.b=e.a=r,++n.b}function i5(n,t,e){var i;return h1(t,n.c.length),i=n.c[t],n.c[t]=e,i}function r5(n,t,e){return _B(null==t?yIn(n.f,null,e):cbn(n.g,t,e),281)}function c5(n){return n.c&&n.d?d0(n.c)+"->"+d0(n.d):"e_"+MN(n)}function a5(n,t){return(Wln(n),yE(new xq(n,new W9(t,n.a)))).sd(Zet)}function u5(){return vMn(),Mun(Hk(Gat,1),OVn,356,0,[xat,Dat,Rat,Kat,_at])}function o5(){return mUn(),Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt])}function s5(n){return Nk(),function(){return R2(n,this,arguments)}}function h5(){return Date.now?Date.now():(new Date).getTime()}function f5(n){return!(!n.c||!n.d||!n.c.i||n.c.i!=n.d.i)}function l5(n){if(!n.c.Sb())throw Fp(new vv);return n.a=!0,n.c.Ub()}function b5(n){n.i=0,vS(n.b,null),vS(n.c,null),n.a=null,n.e=null,++n.g}function w5(n){bS.call(this,null==n?qWn:_bn(n),iL(n,78)?_B(n,78):null)}function d5(n){nWn(),_p(this),this.a=new VT,bsn(this,n),NH(this.a,n)}function g5(){LA(this),this.b=new LI(xQn,xQn),this.a=new LI(DQn,DQn)}function p5(n,t){this.c=0,this.b=t,dO.call(this,n,17493),this.a=this.c}function v5(n){m5(),Wet||(this.c=n,this.e=!0,this.a=new $p)}function m5(){m5=O,Wet=!0,Uet=!1,Xet=!1,Qet=!1,Vet=!1}function y5(n,t){return!!iL(t,149)&&pK(n.c,_B(t,149).c)}function k5(n,t){var e;return e=0,n&&(e+=n.f.a/2),t&&(e+=t.f.a/2),e}function j5(n,t){return _B(hnn(n.d,t),23)||_B(hnn(n.e,t),23)}function E5(n){this.b=n,CL.call(this,n),this.a=_B(van(this.b.a,4),126)}function T5(n){this.b=n,rx.call(this,n),this.a=_B(van(this.b.a,4),126)}function M5(n){return n.t||(n.t=new bp(n),uln(new Ly(n),0,n.t)),n.t}function S5(){return Kfn(),Mun(Hk(UPt,1),OVn,103,0,[_Pt,KPt,RPt,DPt,FPt])}function P5(){return ipn(),Mun(Hk(QIt,1),OVn,249,0,[_It,BIt,RIt,KIt,FIt])}function I5(){return epn(),Mun(Hk(yMt,1),OVn,175,0,[oMt,uMt,cMt,sMt,aMt])}function C5(){return OSn(),Mun(Hk(qTt,1),OVn,316,0,[tTt,eTt,cTt,iTt,rTt])}function O5(){return $vn(),Mun(Hk(Cvt,1),OVn,315,0,[vvt,dvt,gvt,wvt,pvt])}function A5(){return Xvn(),Mun(Hk(Sht,1),OVn,335,0,[vht,pht,yht,kht,mht])}function $5(){return VLn(),Mun(Hk(qEt,1),OVn,355,0,[NEt,LEt,DEt,xEt,REt])}function L5(){return AEn(),Mun(Hk(Dst,1),OVn,363,0,[Est,Mst,Sst,Tst,jst])}function N5(){return jbn(),Mun(Hk(tvt,1),OVn,163,0,[Blt,Rlt,Klt,_lt,Flt])}function x5(){var n,t;x5=O,tE(),t=new kv,Y$t=t,n=new Im,Z$t=n}function D5(n){var t;return n.c||iL(t=n.r,88)&&(n.c=_B(t,26)),n.c}function R5(n){return n.e=3,n.d=n.Yb(),2!=n.e&&(n.e=0,!0)}function K5(n){return E$(n&TQn,n>>22&TQn,n<0?MQn:0)}function _5(n){var t,e,i;for(e=0,i=(t=n).length;e0?kdn(n,t):Pxn(n,-t)}function q5(n,t){return 0==t||0==n.e?n:t>0?Pxn(n,t):kdn(n,-t)}function G5(n){if(bAn(n))return n.c=n.a,n.a.Pb();throw Fp(new vv)}function z5(n){var t,e;return t=n.c.i,e=n.d.i,t.k==(cSn(),Eut)&&e.k==Eut}function U5(n){var t;return Ban(t=new lJ,n),oon(t,(FXn(),ggt),null),t}function X5(n,t,e){var i;return(i=n.Yg(t))>=0?n._g(i,e,!0):iOn(n,t,e)}function W5(n,t,e,i){var r;for(r=0;rt)throw Fp(new Cy(bIn(n,t,"index")));return n}function b6(n,t,e,i){var r;return gTn(r=L8(INt,oQn,25,t,15,1),n,t,e,i),r}function w6(n,t){var e;e=n.q.getHours()+(t/60|0),n.q.setMinutes(t),hBn(n,e)}function d6(n,t){return i.Math.min(U8(t.a,n.d.d.c),U8(t.b,n.d.d.c))}function g6(n,t){return zC(t)?null==t?wAn(n.f,null):Han(n.g,t):wAn(n.f,t)}function p6(n){this.c=n,this.a=new Ub(this.c.a),this.b=new Ub(this.c.b)}function v6(){this.e=new $p,this.c=new $p,this.d=new $p,this.b=new $p}function m6(){this.g=new _v,this.b=new _v,this.a=new $p,this.k=new $p}function y6(n,t,e){this.a=n,this.c=t,this.d=e,UB(t.e,this),UB(e.b,this)}function k6(n,t){wO.call(this,t.rd(),-6&t.qd()),mW(n),this.a=n,this.b=t}function j6(n,t){dO.call(this,t.rd(),-6&t.qd()),mW(n),this.a=n,this.b=t}function E6(n,t){gO.call(this,t.rd(),-6&t.qd()),mW(n),this.a=n,this.b=t}function T6(n,t,e){this.a=n,this.b=t,this.c=e,UB(n.t,this),UB(t.i,this)}function M6(){this.b=new VT,this.a=new VT,this.b=new VT,this.a=new VT}function S6(){S6=O,jMt=new cp("org.eclipse.elk.labels.labelManager")}function P6(){P6=O,nst=new tR("separateLayerConnections",(Pun(),rst))}function I6(){I6=O,Eyt=new cI("REGULAR",0),jyt=new cI("CRITICAL",1)}function C6(){C6=O,Jvt=new zP("STACKED",0),Qvt=new zP("SEQUENCED",1)}function O6(){O6=O,YEt=new jI("FIXED",0),JEt=new jI("CENTER_NODE",1)}function A6(n,t){var e;return e=LGn(n,t),n.b=new prn(e.c.length),vqn(n,e)}function $6(n,t,e){return++n.e,--n.f,_B(n.d[t].$c(e),133).dd()}function L6(n){var t;return n.a||iL(t=n.r,148)&&(n.a=_B(t,148)),n.a}function N6(n){return n.a?n.e?N6(n.e):null:n}function x6(n,t){return n.pt.p?-1:0}function D6(n,t){return mW(t),n.c=0,"Initial capacity must not be negative")}function J6(){J6=O,Uit=hhn((Ntn(),Mun(Hk(Xit,1),OVn,232,0,[Hit,qit,Git])))}function Y6(){Y6=O,Zit=hhn((Q9(),Mun(Hk(nrt,1),OVn,461,0,[Vit,Wit,Qit])))}function Z6(){Z6=O,crt=hhn((H7(),Mun(Hk(Irt,1),OVn,462,0,[irt,ert,trt])))}function n8(){n8=O,Jet=hhn((Bsn(),Mun(Hk(Yet,1),OVn,132,0,[qet,Get,zet])))}function t8(){t8=O,Aat=hhn((B7(),Mun(Hk(Fat,1),OVn,379,0,[Iat,Pat,Cat])))}function e8(){e8=O,wut=hhn((_fn(),Mun(Hk(put,1),OVn,423,0,[lut,fut,hut])))}function i8(){i8=O,fht=hhn((Iin(),Mun(Hk(dht,1),OVn,314,0,[oht,uht,sht])))}function r8(){r8=O,ght=hhn((cin(),Mun(Hk(jht,1),OVn,337,0,[lht,wht,bht])))}function c8(){c8=O,$ht=hhn((Qun(),Mun(Hk(_ht,1),OVn,450,0,[Cht,Iht,Oht])))}function a8(){a8=O,Rst=hhn((Srn(),Mun(Hk(Ust,1),OVn,361,0,[xst,Nst,Lst])))}function u8(){u8=O,Ift=hhn((q7(),Mun(Hk(Aft,1),OVn,303,0,[Mft,Sft,Tft])))}function o8(){o8=O,Eft=hhn((Dan(),Mun(Hk(Pft,1),OVn,292,0,[yft,kft,mft])))}function s8(){s8=O,uvt=hhn((Ehn(),Mun(Hk(lvt,1),OVn,378,0,[ivt,rvt,cvt])))}function h8(){h8=O,Vvt=hhn((Fcn(),Mun(Hk(Yvt,1),OVn,375,0,[zvt,Uvt,Xvt])))}function f8(){f8=O,xvt=hhn((pon(),Mun(Hk(Kvt,1),OVn,339,0,[$vt,Avt,Lvt])))}function l8(){l8=O,Gvt=hhn((rin(),Mun(Hk(Wvt,1),OVn,452,0,[Hvt,Fvt,Bvt])))}function b8(){b8=O,wmt=hhn((Oun(),Mun(Hk(Tmt,1),OVn,377,0,[fmt,lmt,hmt])))}function w8(){w8=O,rmt=hhn((Gsn(),Mun(Hk(omt,1),OVn,336,0,[nmt,tmt,emt])))}function d8(){d8=O,smt=hhn((bcn(),Mun(Hk(bmt,1),OVn,338,0,[umt,cmt,amt])))}function g8(){g8=O,$mt=hhn((ain(),Mun(Hk(Lmt,1),OVn,454,0,[Imt,Cmt,Omt])))}function p8(){p8=O,ejt=hhn((Sbn(),Mun(Hk(cjt,1),OVn,442,0,[njt,Ykt,Zkt])))}function v8(){v8=O,fjt=hhn((Fsn(),Mun(Hk(Hjt,1),OVn,380,0,[ujt,ojt,sjt])))}function m8(){m8=O,nEt=hhn((Tbn(),Mun(Hk($Et,1),OVn,381,0,[Jjt,Yjt,Qjt])))}function y8(){y8=O,Wjt=hhn((_cn(),Mun(Hk(Vjt,1),OVn,293,0,[zjt,Ujt,Gjt])))}function k8(){k8=O,GEt=hhn((Mbn(),Mun(Hk(UEt,1),OVn,437,0,[FEt,BEt,HEt])))}function j8(){j8=O,mIt=hhn((cfn(),Mun(Hk(TIt,1),OVn,334,0,[gIt,dIt,pIt])))}function E8(){E8=O,XPt=hhn((xtn(),Mun(Hk(YPt,1),OVn,272,0,[qPt,GPt,zPt])))}function T8(){return WEn(),Mun(Hk(rCt,1),OVn,98,0,[VIt,WIt,XIt,GIt,UIt,zIt])}function M8(n,t){return!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),edn(n.o,t)}function S8(n){return!n.g&&(n.g=new oo),!n.g.d&&(n.g.d=new hp(n)),n.g.d}function P8(n){return!n.g&&(n.g=new oo),!n.g.a&&(n.g.a=new fp(n)),n.g.a}function I8(n){return!n.g&&(n.g=new oo),!n.g.b&&(n.g.b=new sp(n)),n.g.b}function C8(n){return!n.g&&(n.g=new oo),!n.g.c&&(n.g.c=new lp(n)),n.g.c}function O8(n,t,e){var i,r;for(r=new Can(t,n),i=0;ie||t=0?n._g(e,!0,!0):iOn(n,t,!0)}function M9(n,t){return Mln(Hy(ED(pMn(n,(oWn(),jlt)))),Hy(ED(pMn(t,jlt))))}function S9(){S9=O,Gkt=agn(agn(KM(new _2,(qyn(),Dyt)),(NPn(),Wyt)),Gyt)}function P9(n,t,e){var i;return i=$on(n,t,e),n.b=new prn(i.c.length),uDn(n,i)}function I9(n){if(n.b<=0)throw Fp(new vv);return--n.b,n.a-=n.c.c,tln(n.a)}function C9(n){var t;if(!n.a)throw Fp(new hV);return t=n.a,n.a=QY(n.a),t}function O9(n){for(;!n.a;)if(!jK(n.c,new dw(n)))return!1;return!0}function A9(n){return vX(n),iL(n,198)?_B(n,198):new al(n)}function $9(n){L9(),_B(n.We((uWn(),sPt)),174).Fc((hCn(),tCt)),n.Ye(oPt,null)}function L9(){L9=O,ZTt=new bu,tMt=new wu,nMt=gsn((uWn(),oPt),ZTt,BSt,tMt)}function N9(){N9=O,ijt=new dI("LEAF_NUMBER",0),rjt=new dI("NODE_SIZE",1)}function x9(n,t,e){n.a=t,n.c=e,n.b.a.$b(),vQ(n.d),n.e.a.c=L8(Cnt,FWn,1,0,5,1)}function D9(n){n.a=L8(INt,oQn,25,n.b+1,15,1),n.c=L8(INt,oQn,25,n.b,15,1),n.d=0}function R9(n,t){n.a.ue(t.d,n.b)>0&&(UB(n.c,new pH(t.c,t.d,n.d)),n.b=t.d)}function K9(n,t){if(null==n.g||t>=n.i)throw Fp(new AO(t,n.i));return n.g[t]}function _9(n,t,e){if(Lsn(n,e),null!=e&&!n.wj(e))throw Fp(new hv);return e}function F9(n){var t;if(n.Ek())for(t=n.i-1;t>=0;--t)Utn(n,t);return $3(n)}function B9(n){var t,e;if(!n.b)return null;for(e=n.b;t=e.a[0];)e=t;return e}function H9(n,t){var e;return i4(t),(e=p7(n.slice(0,t),n)).length=t,e}function q9(n,t,e,i){MQ(),i=i||fet,wIn(n.slice(t,e),n,t,e,-t,i)}function G9(n,t,e,i,r){return t<0?iOn(n,e,i):_B(e,66).Nj().Pj(n,n.yh(),t,i,r)}function z9(n){return iL(n,172)?""+_B(n,172).a:null==n?null:_bn(n)}function U9(n){return iL(n,172)?""+_B(n,172).a:null==n?null:_bn(n)}function X9(n,t){if(t.a)throw Fp(new by(PJn));jU(n.a,t),t.a=n,!n.j&&(n.j=t)}function W9(n,t){gO.call(this,t.rd(),-16449&t.qd()),mW(n),this.a=n,this.c=t}function V9(n,t){var e,i;return i=t/n.c.Hd().gc()|0,e=t%n.c.Hd().gc(),G6(n,i,e)}function Q9(){Q9=O,Vit=new HS(iYn,0),Wit=new HS(nYn,1),Qit=new HS(rYn,2)}function J9(){J9=O,$et=new wS("All",0),Let=new AA,Net=new C$,xet=new $A}function Y9(){Y9=O,Ret=hhn((J9(),Mun(Hk(Ket,1),OVn,297,0,[$et,Let,Net,xet])))}function Z9(){Z9=O,eut=hhn((Cun(),Mun(Hk(but,1),OVn,405,0,[Jat,nut,Yat,Zat])))}function n7(){n7=O,Rrt=hhn((Nan(),Mun(Hk(Hrt,1),OVn,406,0,[xrt,$rt,Lrt,Nrt])))}function t7(){t7=O,qrt=hhn((Fpn(),Mun(Hk(Grt,1),OVn,323,0,[_rt,Krt,Frt,Brt])))}function e7(){e7=O,tct=hhn((Bpn(),Mun(Hk(ict,1),OVn,394,0,[Jrt,Qrt,Yrt,Zrt])))}function i7(){i7=O,Fyt=hhn((qyn(),Mun(Hk(Byt,1),OVn,393,0,[xyt,Dyt,Ryt,Kyt])))}function r7(){r7=O,ast=hhn((Pun(),Mun(Hk(dst,1),OVn,360,0,[rst,est,ist,tst])))}function c7(){c7=O,qjt=hhn((Imn(),Mun(Hk(Xjt,1),OVn,340,0,[Bjt,_jt,Fjt,Kjt])))}function a7(){a7=O,kst=hhn((Iun(),Mun(Hk(Pst,1),OVn,411,0,[gst,pst,vst,mst])))}function u7(){u7=O,bvt=hhn((fvn(),Mun(Hk(mvt,1),OVn,197,0,[hvt,fvt,svt,ovt])))}function o7(){o7=O,sOt=hhn((_sn(),Mun(Hk(lOt,1),OVn,396,0,[cOt,aOt,rOt,uOt])))}function s7(){s7=O,MIt=hhn((zyn(),Mun(Hk(xIt,1),OVn,285,0,[EIt,yIt,kIt,jIt])))}function h7(){h7=O,ZPt=hhn((Ebn(),Mun(Hk(aIt,1),OVn,218,0,[JPt,VPt,WPt,QPt])))}function f7(){f7=O,eOt=hhn((Kwn(),Mun(Hk(iOt,1),OVn,311,0,[nOt,JCt,ZCt,YCt])))}function l7(){l7=O,_Ct=hhn((pdn(),Mun(Hk(VCt,1),OVn,374,0,[DCt,RCt,xCt,NCt])))}function b7(){b7=O,BBn(),_Lt=xQn,KLt=DQn,BLt=new $b(xQn),FLt=new $b(DQn)}function w7(){w7=O,Hht=new IP(WZn,0),Bht=new IP("IMPROVE_STRAIGHTNESS",1)}function d7(n,t){return oH(),UB(n,new eC(t,tln(t.e.c.length+t.g.c.length)))}function g7(n,t){return oH(),UB(n,new eC(t,tln(t.e.c.length+t.g.c.length)))}function p7(n,t){return 10!=gnn(t)&&Mun(Zon(t),t.hm,t.__elementTypeId$,gnn(t),n),n}function v7(n,t){var e;return-1!=(e=k7(n,t,0))&&(u6(n,e),!0)}function m7(n,t){var e;return(e=_B(g6(n.e,t),387))?(xH(e),e.e):null}function y7(n){var t;return QO(n)&&(t=0-n,!isNaN(t))?t:can(ron(n))}function k7(n,t,e){for(;e=0?Jpn(n,e,!0,!0):iOn(n,t,!0)}function J7(n,t){var e,i;return EM(),e=s3(n),i=s3(t),!!e&&!!i&&!Dpn(e.k,i.k)}function Y7(n,t){Men(n,null==t||UK((mW(t),t))||isNaN((mW(t),t))?0:(mW(t),t))}function Z7(n,t){Sen(n,null==t||UK((mW(t),t))||isNaN((mW(t),t))?0:(mW(t),t))}function nnn(n,t){Ten(n,null==t||UK((mW(t),t))||isNaN((mW(t),t))?0:(mW(t),t))}function tnn(n,t){Een(n,null==t||UK((mW(t),t))||isNaN((mW(t),t))?0:(mW(t),t))}function enn(n){(this.q?this.q:(TQ(),TQ(),oet)).Ac(n.q?n.q:(TQ(),TQ(),oet))}function inn(n,t){return iL(t,99)&&0!=(_B(t,18).Bb&_Qn)?new LO(t,n):new Can(t,n)}function rnn(n,t){return iL(t,99)&&0!=(_B(t,18).Bb&_Qn)?new LO(t,n):new Can(t,n)}function cnn(n,t){Xrt=new it,nct=t,_B((Urt=n).b,65),D8(Urt,Xrt,null),cqn(Urt)}function ann(n,t,e){var i;return i=n.g[t],yL(n,t,n.oi(t,e)),n.gi(t,e,i),n.ci(),i}function unn(n,t){var e;return(e=n.Xc(t))>=0&&(n.$c(e),!0)}function onn(n){var t;return n.d!=n.r&&(t=Pkn(n),n.e=!!t&&t.Cj()==k9n,n.d=t),n.e}function snn(n,t){var e;for(vX(n),vX(t),e=!1;t.Ob();)e|=n.Fc(t.Pb());return e}function hnn(n,t){var e;return(e=_B(xX(n.e,t),387))?(cL(n,e),e.e):null}function fnn(n){var t,e;return t=n/60|0,0==(e=n%60)?""+t:t+":"+e}function lnn(n,t){return Wln(n),new xq(n,new DK(new E6(t,n.a)))}function bnn(n,t){var e=n.a[t],i=(Jun(),stt)[typeof e];return i?i(e):mhn(typeof e)}function wnn(n){switch(n.g){case 0:return NWn;case 1:return-1;default:return 0}}function dnn(n){return Dkn(n,(z7(),wtt))<0?-SN(ron(n)):n.l+n.m*PQn+n.h*IQn}function gnn(n){return null==n.__elementTypeCategory$?10:n.__elementTypeCategory$}function pnn(n){var t;return null!=(t=0==n.b.c.length?null:Lq(n.b,0))&&orn(n,0),t}function vnn(n,t){for(;t[0]=0;)++t[0]}function mnn(n,t){this.e=t,this.a=Xan(n),this.a<54?this.f=y2(n):this.c=Ygn(n)}function ynn(n,t,e,i){lWn(),Cp.call(this,26),this.c=n,this.a=t,this.d=e,this.b=i}function knn(n,t,e){var i,r;for(i=10,r=0;rn.a[i]&&(i=e);return i}function Ann(n,t){var e;return 0==(e=Pbn(n.e.c,t.e.c))?Mln(n.e.d,t.e.d):e}function $nn(n,t){return 0==t.e||0==n.e?net:(OOn(),CNn(n,t))}function Lnn(n,t){if(!n)throw Fp(new Ry(VNn("Enum constant undefined: %s",t)))}function Nnn(){Nnn=O,cut=new St,aut=new Tt,iut=new At,rut=new $t,uut=new Lt}function xnn(){xnn=O,git=new _S("BY_SIZE",0),pit=new _S("BY_SIZE_AND_SHAPE",1)}function Dnn(){Dnn=O,Nct=new zS("EADES",0),xct=new zS("FRUCHTERMAN_REINGOLD",1)}function Rnn(){Rnn=O,Tht=new MP("READING_DIRECTION",0),Mht=new MP("ROTATION",1)}function Knn(){Knn=O,Eht=hhn((Xvn(),Mun(Hk(Sht,1),OVn,335,0,[vht,pht,yht,kht,mht])))}function _nn(){_nn=O,yvt=hhn(($vn(),Mun(Hk(Cvt,1),OVn,315,0,[vvt,dvt,gvt,wvt,pvt])))}function Fnn(){Fnn=O,Ist=hhn((AEn(),Mun(Hk(Dst,1),OVn,363,0,[Est,Mst,Sst,Tst,jst])))}function Bnn(){Bnn=O,qlt=hhn((jbn(),Mun(Hk(tvt,1),OVn,163,0,[Blt,Rlt,Klt,_lt,Flt])))}function Hnn(){Hnn=O,uTt=hhn((OSn(),Mun(Hk(qTt,1),OVn,316,0,[tTt,eTt,cTt,iTt,rTt])))}function qnn(){qnn=O,fMt=hhn((epn(),Mun(Hk(yMt,1),OVn,175,0,[oMt,uMt,cMt,sMt,aMt])))}function Gnn(){Gnn=O,_Et=hhn((VLn(),Mun(Hk(qEt,1),OVn,355,0,[NEt,LEt,DEt,xEt,REt])))}function znn(){znn=O,Bat=hhn((vMn(),Mun(Hk(Gat,1),OVn,356,0,[xat,Dat,Rat,Kat,_at])))}function Unn(){Unn=O,HPt=hhn((Kfn(),Mun(Hk(UPt,1),OVn,103,0,[_Pt,KPt,RPt,DPt,FPt])))}function Xnn(){Xnn=O,qIt=hhn((ipn(),Mun(Hk(QIt,1),OVn,249,0,[_It,BIt,RIt,KIt,FIt])))}function Wnn(){Wnn=O,ICt=hhn((mUn(),Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt])))}function Vnn(n,t){var e;return(e=_B(xX(n.a,t),134))||(e=new Zn,XW(n.a,t,e)),e}function Qnn(n){var t;return!!(t=_B(pMn(n,(oWn(),xft)),305))&&t.a==n}function Jnn(n){var t;return!!(t=_B(pMn(n,(oWn(),xft)),305))&&t.i==n}function Ynn(n,t){return mW(t),Nz(n),!!n.d.Ob()&&(t.td(n.d.Pb()),!0)}function Znn(n){return Xhn(n,NWn)>0?NWn:Xhn(n,RVn)<0?RVn:bG(n)}function ntn(n){return n<3?(hin(n,PVn),n+1):n=0&&t=-.01&&n.a<=sYn&&(n.a=0),n.b>=-.01&&n.b<=sYn&&(n.b=0),n}function rtn(n,t){return t==(i_(),i_(),Eet)?n.toLocaleLowerCase():n.toLowerCase()}function ctn(n){return(0!=(2&n.i)?"interface ":0!=(1&n.i)?"":"class ")+(kD(n),n.o)}function atn(n){var t;t=new Om,s9((!n.q&&(n.q=new nU(XAt,n,11,10)),n.q),t)}function utn(n,t){var e;return e=t>0?t-1:t,Oj(Aj(Ken(AH(new zm,e),n.n),n.j),n.k)}function otn(n,t,e,i){n.j=-1,BOn(n,kPn(n,t,e),(JM(),_B(t,66).Mj().Ok(i)))}function stn(n){this.g=n,this.f=new $p,this.a=i.Math.min(this.g.c.c,this.g.d.c)}function htn(n){this.b=new $p,this.a=new $p,this.c=new $p,this.d=new $p,this.e=n}function ftn(n,t){this.a=new Lp,this.e=new Lp,this.b=(Ehn(),cvt),this.c=n,this.b=t}function ltn(n,t,e){$R.call(this),Ltn(this),this.a=n,this.c=e,this.b=t.d,this.f=t.e}function btn(n){this.d=n,this.c=n.c.vc().Kc(),this.b=null,this.a=null,this.e=(ey(),qnt)}function wtn(n){if(n<0)throw Fp(new Ry("Illegal Capacity: "+n));this.g=this.ri(n)}function dtn(n,t){if(0>n||n>t)throw Fp(new jk("fromIndex: 0, toIndex: "+n+oJn+t))}function gtn(n){var t;if(n.a==n.b.a)throw Fp(new vv);return t=n.a,n.c=t,n.a=n.a.e,t}function ptn(n){var t;Ex(!!n.c),t=n.c.a,Ctn(n.d,n.c),n.b==n.c?n.b=t:--n.a,n.c=null}function vtn(n,t){var e;return Wln(n),e=new gQ(n,n.a.rd(),4|n.a.qd(),t),new xq(n,e)}function mtn(n,t){var e,i;return(e=_B(hfn(n.d,t),14))?(i=t,n.e.pc(i,e)):null}function ytn(n,t){var e;for(e=n.Kc();e.Ob();)oon(_B(e.Pb(),70),(oWn(),clt),t)}function ktn(n){var t;return(t=Hy(ED(pMn(n,(FXn(),rgt)))))<0&&oon(n,rgt,t=0),t}function jtn(n,t,e){var r;Kkn(e,r=i.Math.max(0,n.b/2-.5),1),UB(t,new tP(e,r))}function Etn(n,t,e){return SY(FH(n.a.e[_B(t.a,10).p]-n.a.e[_B(e.a,10).p]))}function Ttn(n,t,e,i,r,c){var a;TZ(a=U5(i),r),EZ(a,c),QCn(n.a,i,new A_(a,t,e.f))}function Mtn(n,t){var e;if(!(e=$Nn(n.Tg(),t)))throw Fp(new Ry(e6n+t+c6n));return e}function Stn(n,t){var e;for(e=n;QY(e);)if((e=QY(e))==t)return!0;return!1}function Ptn(n,t){var e,i,r;for(i=t.a.cd(),e=_B(t.a.dd(),14).gc(),r=0;r0&&(n.a/=t,n.b/=t),n}function Gtn(n){var t;return n.w?n.w:((t=X1(n))&&!t.kh()&&(n.w=t),t)}function ztn(n){var t;return null==n?null:XTn(t=_B(n,190),t.length)}function Utn(n,t){if(null==n.g||t>=n.i)throw Fp(new AO(t,n.i));return n.li(t,n.g[t])}function Xtn(n){var t,e;for(t=n.a.d.j,e=n.c.d.j;t!=e;)arn(n.b,t),t=Eln(t);arn(n.b,t)}function Wtn(n){var t;for(t=0;t=14&&t<=16)),n}function ten(n,t,e){var i=function(){return n.apply(i,arguments)};return t.apply(i,e),i}function een(n,t,e){var i,r;i=t;do{r=Hy(n.p[i.p])+e,n.p[i.p]=r,i=n.a[i.p]}while(i!=t)}function ien(n,t){var e,i;i=n.a,e=Wfn(n,t,null),i!=t&&!n.e&&(e=rzn(n,t,e)),e&&e.Fi()}function ren(n,t){return o$(),ein(DVn),i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)}function cen(n,t){return o$(),ein(DVn),i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)}function aen(n,t){return RMn(),k$(n.b.c.length-n.e.c.length,t.b.c.length-t.e.c.length)}function uen(n,t){return Jj(Qrn(n,t,bG(ibn(TVn,eV(bG(ibn(null==t?0:Yon(t),MVn)),15)))))}function oen(){oen=O,Cut=hhn((cSn(),Mun(Hk(Out,1),OVn,267,0,[Sut,Mut,Eut,Put,Tut,jut])))}function sen(){sen=O,ZMt=hhn((lEn(),Mun(Hk(BPt,1),OVn,291,0,[JMt,QMt,VMt,XMt,UMt,WMt])))}function hen(){hen=O,LMt=hhn((lvn(),Mun(Hk(YMt,1),OVn,248,0,[SMt,CMt,OMt,AMt,PMt,IMt])))}function fen(){fen=O,eht=hhn((OPn(),Mun(Hk(cht,1),OVn,227,0,[Jst,Zst,Qst,Yst,nht,Vst])))}function len(){len=O,aft=hhn((QMn(),Mun(Hk(pft,1),OVn,275,0,[ift,nft,rft,eft,tft,Zht])))}function ben(){ben=O,Yht=hhn((_jn(),Mun(Hk(cft,1),OVn,274,0,[Wht,Xht,Qht,Uht,Vht,zht])))}function wen(){wen=O,evt=hhn((jTn(),Mun(Hk(avt,1),OVn,313,0,[Zpt,Jpt,Vpt,Qpt,nvt,Ypt])))}function den(){den=O,Fht=hhn((wSn(),Mun(Hk(qht,1),OVn,276,0,[Nht,Lht,Dht,xht,Kht,Rht])))}function gen(){gen=O,Qyt=hhn((NPn(),Mun(Hk(Rkt,1),OVn,327,0,[Wyt,Gyt,Uyt,zyt,Xyt,qyt])))}function pen(){pen=O,cCt=hhn((hCn(),Mun(Hk(PCt,1),OVn,273,0,[eCt,nCt,tCt,ZIt,YIt,iCt])))}function ven(){ven=O,uIt=hhn((YTn(),Mun(Hk(vIt,1),OVn,312,0,[rIt,eIt,cIt,nIt,iIt,tIt])))}function men(){return YAn(),Mun(Hk(HIt,1),OVn,93,0,[PIt,SIt,CIt,NIt,LIt,$It,OIt,AIt,IIt])}function yen(n,t){var e;e=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,0,e,n.a))}function ken(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,1,e,n.b))}function jen(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,3,e,n.b))}function Een(n,t){var e;e=n.f,n.f=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,3,e,n.f))}function Ten(n,t){var e;e=n.g,n.g=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,4,e,n.g))}function Men(n,t){var e;e=n.i,n.i=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,5,e,n.i))}function Sen(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,6,e,n.j))}function Pen(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,1,e,n.j))}function Ien(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,4,e,n.c))}function Cen(n,t){var e;e=n.k,n.k=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,2,e,n.k))}function Oen(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new h4(n,2,e,n.d))}function Aen(n,t){var e;e=n.s,n.s=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new h4(n,4,e,n.s))}function $en(n,t){var e;e=n.t,n.t=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new h4(n,5,e,n.t))}function Len(n,t){var e;e=n.F,n.F=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,5,e,t))}function Nen(n,t){var e;return(e=_B(xX((YM(),gAt),n),55))?e.xj(t):L8(Cnt,FWn,1,t,5,1)}function xen(n,t){var e;return t in n.a&&(e=qY(n,t).he())?e.a:null}function Den(n,t){var e,i;return Zj(),i=new uo,!!t&&PNn(i,t),Lin(e=i,n),e}function Ren(n,t,e){if(Lsn(n,e),!n.Bk()&&null!=e&&!n.wj(e))throw Fp(new hv);return e}function Ken(n,t){return n.n=t,n.n?(n.f=new $p,n.e=new $p):(n.f=null,n.e=null),n}function _en(n,t,e,i,r,c){var a;return Wen(e,a=pX(n,t)),a.i=r?8:0,a.f=i,a.e=r,a.g=c,a}function Fen(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=1,this.c=n,this.a=e}function Ben(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=2,this.c=n,this.a=e}function Hen(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=6,this.c=n,this.a=e}function qen(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=7,this.c=n,this.a=e}function Gen(n,t,e,i,r){this.d=t,this.j=i,this.e=r,this.o=-1,this.p=4,this.c=n,this.a=e}function zen(n,t){var e,i,r,c;for(r=0,c=(i=t).length;r=0),egn(n.d,n.c)<0&&(n.a=n.a-1&n.d.a.length-1,n.b=n.d.c),n.c=-1}function tin(n){return n.a<54?n.f<0?-1:n.f>0?1:0:(!n.c&&(n.c=vhn(n.f)),n.c).e}function ein(n){if(!(n>=0))throw Fp(new Ry("tolerance ("+n+") must be >= 0"));return n}function iin(){return iMt||msn(iMt=new IRn,Mun(Hk(Rit,1),FWn,130,0,[new $f])),iMt}function rin(){rin=O,Hvt=new qP(oYn,0),Fvt=new qP("INPUT",1),Bvt=new qP("OUTPUT",2)}function cin(){cin=O,lht=new EP("ARD",0),wht=new EP("MSD",1),bht=new EP("MANUAL",2)}function ain(){ain=O,Imt=new VP("BARYCENTER",0),Cmt=new VP(k1n,1),Omt=new VP(j1n,2)}function uin(n,t){var e;if(e=n.gc(),t<0||t>e)throw Fp(new ZR(t,e));return new xK(n,t)}function oin(n,t){var e;return iL(t,42)?n.c.Mc(t):(e=edn(n,t),Udn(n,t),e)}function sin(n,t,e){return Phn(n,t),$rn(n,e),Aen(n,0),$en(n,1),Yfn(n,!0),Vfn(n,!0),n}function hin(n,t){if(n<0)throw Fp(new Ry(t+" cannot be negative but was: "+n));return n}function fin(n,t){var e,i;for(e=0,i=n.gc();e0?_B(Lq(e.a,i-1),10):null}function Oin(n,t){var e;e=n.k,n.k=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,2,e,n.k))}function Ain(n,t){var e;e=n.f,n.f=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,8,e,n.f))}function $in(n,t){var e;e=n.i,n.i=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,7,e,n.i))}function Lin(n,t){var e;e=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,8,e,n.a))}function Nin(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,0,e,n.b))}function xin(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,0,e,n.b))}function Din(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,1,e,n.c))}function Rin(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,1,e,n.c))}function Kin(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,4,e,n.c))}function _in(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,1,e,n.d))}function Fin(n,t){var e;e=n.D,n.D=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,2,e,n.D))}function Bin(n,t){n.r>0&&n.c0&&0!=n.g&&Bin(n.i,t/n.r*n.i.d))}function Hin(n,t,e){var i;n.b=t,n.a=e,i=512==(512&n.a)?new Km:new Dh,n.c=EDn(i,n.b,n.a)}function qin(n,t){return Oxn(n.e,t)?(JM(),onn(t)?new hq(t,n):new LC(t,n)):new DC(t,n)}function Gin(n,t){return Qj(Jrn(n.a,t,bG(ibn(TVn,eV(bG(ibn(null==t?0:Yon(t),MVn)),15)))))}function zin(n,t,e){return L7(n,new sw(t),new un,new hw(e),Mun(Hk(Yet,1),OVn,132,0,[]))}function Uin(n){return 0>n?new XT:new OD(null,new p5(n+1,n))}function Xin(n,t){var e;return TQ(),e=new zT(1),zC(n)?pZ(e,n,t):yIn(e.f,n,t),new zb(e)}function Win(n,t){var e,i;return(e=n.o+n.p)<(i=t.o+t.p)?-1:e==i?0:1}function Vin(n){var t;return iL(t=pMn(n,(oWn(),blt)),160)?pwn(_B(t,160)):null}function Qin(n){var t;return(n=i.Math.max(n,2))>(t=mon(n))?(t<<=1)>0?t:IVn:t}function Jin(n){switch(cN(3!=n.e),n.e){case 2:return!1;case 0:return!0}return R5(n)}function Yin(n,t){var e;return!!iL(t,8)&&(e=_B(t,8),n.a==e.a&&n.b==e.b)}function Zin(n,t,e){var i,r;return r=t>>5,i=31&t,n0(yz(n.n[e][r],bG(vz(i,1))),3)}function nrn(n,t){var e,i;for(i=t.vc().Kc();i.Ob();)gjn(n,(e=_B(i.Pb(),42)).cd(),e.dd())}function trn(n,t){var e;e=new it,_B(t.b,65),_B(t.b,65),_B(t.b,65),Itn(t.a,new jB(n,e,t))}function ern(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,21,e,n.b))}function irn(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,11,e,n.d))}function rrn(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,13,e,n.j))}function crn(n,t,e){var i,r,c;for(c=n.a.length-1,r=n.b,i=0;i>>31;0!=i&&(n[e]=i)}function Zrn(n,t){var e,i;for(TQ(),i=new $p,e=0;e0&&(this.g=this.ri(this.i+(this.i/8|0)+1),n.Qc(this.g))}function kcn(n,t){EH.call(this,z$t,n,t),this.b=this,this.a=rxn(n.Tg(),ttn(this.e.Tg(),this.c))}function jcn(n,t){var e,i;for(mW(t),i=t.vc().Kc();i.Ob();)e=_B(i.Pb(),42),n.zc(e.cd(),e.dd())}function Ecn(n,t,e){var i;for(i=e.Kc();i.Ob();)if(!H3(n,t,i.Pb()))return!1;return!0}function Tcn(n,t,e,i,r){var c;return e&&(c=Cwn(t.Tg(),n.c),r=e.gh(t,-1-(-1==c?i:c),null,r)),r}function Mcn(n,t,e,i,r){var c;return e&&(c=Cwn(t.Tg(),n.c),r=e.ih(t,-1-(-1==c?i:c),null,r)),r}function Scn(n){var t;if(-2==n.b){if(0==n.e)t=-1;else for(t=0;0==n.a[t];t++);n.b=t}return n.b}function Pcn(n){switch(n.g){case 2:return mUn(),SCt;case 4:return mUn(),aCt;default:return n}}function Icn(n){switch(n.g){case 1:return mUn(),TCt;case 3:return mUn(),uCt;default:return n}}function Ccn(n){var t,e,i;return n.j==(mUn(),uCt)&&(e=TN(t=GOn(n),aCt),(i=TN(t,SCt))||i&&e)}function Ocn(n){var t;return new VK(t=_B(n.e&&n.e(),9),_B(XU(t,t.length),9),t.length)}function Acn(n,t){ITn(t,m1n,1),Zbn(uM(new Mw((wM(),new FV(n,!1,!1,new Ft))))),FSn(t)}function $cn(n,t){return oN(),zC(n)?s6(n,TD(t)):GC(n)?jz(n,ED(t)):qC(n)?kz(n,jD(t)):n.wd(t)}function Lcn(n,t){t.q=n,n.d=i.Math.max(n.d,t.r),n.b+=t.d+(0==n.a.c.length?0:n.c),UB(n.a,t)}function Ncn(n,t){var e,i,r,c;return r=n.c,e=n.c+n.b,c=n.d,i=n.d+n.a,t.a>r&&t.ac&&t.b1||n.Ob())return++n.a,n.g=0,t=n.i,n.Ob(),t;throw Fp(new vv)}function Tan(n){var t;return r$(),cS(uyt,n)||((t=new ua).a=n,lR(uyt,n,t)),_B(aV(uyt,n),635)}function Man(n){var t,e,i;return e=0,(i=n)<0&&(i+=IQn,e=MQn),t=SY(i/PQn),E$(SY(i-t*PQn),t,e)}function San(n){var t,e,i;for(i=0,e=new WT(n.a);e.a>22),r=n.h+t.h+(i>>22),E$(e&TQn,i&TQn,r&MQn)}function oun(n,t){var e,i,r;return e=n.l-t.l,i=n.m-t.m+(e>>22),r=n.h-t.h+(i>>22),E$(e&TQn,i&TQn,r&MQn)}function sun(n){var t;return n<128?(!(t=(Eq(),Ett)[n])&&(t=Ett[n]=new Ab(n)),t):new Ab(n)}function hun(n){var t;return iL(n,78)?n:((t=n&&n.__java$exception)||av(t=new yhn(n)),t)}function fun(n){if(iL(n,186))return _B(n,118);if(n)return null;throw Fp(new Fy(n8n))}function lun(n,t){if(null==t)return!1;for(;n.a!=n.b;)if($fn(t,Rhn(n)))return!0;return!1}function bun(n){return!!n.a.Ob()||n.a==n.d&&(n.a=new T2(n.e.f),n.a.Ob())}function wun(n,t){var e;return 0!=(e=t.Pc()).length&&(ZB(n.c,n.c.length,e),!0)}function dun(n,t,e){var i,r;for(r=t.vc().Kc();r.Ob();)i=_B(r.Pb(),42),n.yc(i.cd(),i.dd(),e);return n}function gun(n,t){var e;for(e=new Ub(n.b);e.a=0,"Negative initial capacity"),gH(t>=0,"Non-positive load factor"),OU(this)}function Zun(n,t,e){return!(n>=128)&&QC(n<64?n0(vz(1,n),e):n0(vz(1,n-64),t),0)}function non(n,t){return!(!n||!t||n==t)&&Pbn(n.b.c,t.b.c+t.b.b)<0&&Pbn(t.b.c,n.b.c+n.b.b)<0}function ton(n){var t,e,i;return e=n.n,i=n.o,t=n.d,new GV(e.a-t.b,e.b-t.d,i.a+(t.b+t.c),i.b+(t.d+t.a))}function eon(n){var t,e,i,r;for(i=0,r=(e=n.a).length;i(i=n.gc()))throw Fp(new ZR(t,i));return n.hi()&&(e=YY(n,e)),n.Vh(t,e)}function uon(n,t,e){return null==e?(!n.q&&(n.q=new Lp),g6(n.q,t)):(!n.q&&(n.q=new Lp),XW(n.q,t,e)),n}function oon(n,t,e){return null==e?(!n.q&&(n.q=new Lp),g6(n.q,t)):(!n.q&&(n.q=new Lp),XW(n.q,t,e)),n}function son(n){var t,e;return Ban(e=new v6,n),oon(e,(Ern(),uat),n),nBn(n,e,t=new Lp),Tzn(n,e,t),e}function hon(n){var t,e,i;for(yDn(),e=L8(MMt,uVn,8,2,0,1),i=0,t=0;t<2;t++)i+=.5,e[t]=hmn(i,n);return e}function fon(n,t){var e,i,r;for(e=!1,i=n.a[t].length,r=0;r>=1);return t}function yon(n){var t,e;return 32==(e=JCn(n.h))?32==(t=JCn(n.m))?JCn(n.l)+32:t+20-10:e-12}function kon(n){var t;return null==(t=n.a[n.b])?null:(OX(n.a,n.b,null),n.b=n.b+1&n.a.length-1,t)}function jon(n){var t,e;return t=n.t-n.k[n.o.p]*n.d+n.j[n.o.p]>n.f,e=n.u+n.e[n.o.p]*n.d>n.f*n.s*n.d,t||e}function Eon(n,t,e){var i,r;return i=new F8(t,e),r=new q,n.b=Uxn(n,n.b,i,r),r.b||++n.c,n.b.b=!1,r.d}function Ton(n,t,e){var i,r,c;for(c=0,r=Afn(t,e).Kc();r.Ob();)i=_B(r.Pb(),11),XW(n.c,i,tln(c++))}function Mon(n){var t,e;for(e=new Ub(n.a.b);e.ae&&(e=n[t]);return e}function $on(n,t,e){var i;return yxn(n,t,i=new $p,(mUn(),aCt),!0,!1),yxn(n,e,i,SCt,!1,!1),i}function Lon(n,t,e){var i,r;return r=$2(t,"labels"),zAn((i=new wC(n,e)).a,i.b,r),r}function Non(n,t,e,i){var r;return(r=p$n(n,t,e,i))||!(r=rln(n,e,i))||Kqn(n,t,r)?r:null}function xon(n,t,e,i){var r;return(r=v$n(n,t,e,i))||!(r=cln(n,e,i))||Kqn(n,t,r)?r:null}function Don(n,t){var e;for(e=0;e1||t>=0&&n.b<3)}function Qon(n){var t,e;for(t=new mm,e=upn(n,0);e.b!=e.d.c;)Dx(t,0,new lA(_B(f3(e),8)));return t}function Jon(n){var t;for(t=new Ub(n.a.b);t.ai?1:0}function bsn(n,t){return!!fNn(n,t)&&(QCn(n.b,_B(pMn(t,(oWn(),zft)),21),t),NH(n.a,t),!0)}function wsn(n){var t,e;(t=_B(pMn(n,(oWn(),klt)),10))&&(v7((e=t.c).a,t),0==e.a.c.length&&v7(gW(t).b,e))}function dsn(n){return Wet?L8(Het,bJn,572,0,0,1):_B(Wgn(n.a,L8(Het,bJn,572,n.a.c.length,0,1)),842)}function gsn(n,t,e,i){return YW(),new oy(Mun(Hk(Fnt,1),mVn,42,0,[(qvn(n,t),new gT(n,t)),(qvn(e,i),new gT(e,i))]))}function psn(n,t,e){var i;return sin(i=new Om,t,e),s9((!n.q&&(n.q=new nU(XAt,n,11,10)),n.q),i),i}function vsn(n){var t,e,i,r;for(e=(r=sS(COt,n)).length,i=L8(Wtt,uVn,2,e,6,1),t=0;t=n.b.c.length||(ksn(n,2*t+1),(e=2*t+2)=0&&n[i]===t[i];i--);return i<0?0:uS(n0(n[i],GQn),n0(t[i],GQn))?-1:1}function Tsn(n,t){var e,i;for(i=upn(n,0);i.b!=i.d.c;)(e=_B(f3(i),214)).e.length>0&&(t.td(e),e.i&&dln(e))}function Msn(n,t){var e,i;return i=_B(van(n.a,4),126),e=L8(lAt,t9n,415,t,0,1),null!=i&&rHn(i,0,e,0,i.length),e}function Ssn(n,t){var e;return e=new eRn(0!=(256&n.f),n.i,n.a,n.d,0!=(16&n.f),n.j,n.g,t),null!=n.e||(e.c=n),e}function Psn(n,t){var e;for(e=n.Zb().Cc().Kc();e.Ob();)if(_B(e.Pb(),14).Hc(t))return!0;return!1}function Isn(n,t,e,i,r){var c,a;for(a=e;a<=r;a++)for(c=t;c<=i;c++)if(gmn(n,c,a))return!0;return!1}function Csn(n,t,e){var i,r,c,a;for(mW(e),a=!1,c=n.Zc(t),r=e.Kc();r.Ob();)i=r.Pb(),c.Rb(i),a=!0;return a}function Osn(n,t){var e;return n===t||!!iL(t,83)&&(e=_B(t,83),qSn(hz(n),e.vc()))}function Asn(n,t,e){var i,r;for(r=e.Kc();r.Ob();)if(i=_B(r.Pb(),42),n.re(t,i.dd()))return!0;return!1}function $sn(n,t,e){return n.d[t.p][e.p]||(tvn(n,t,e),n.d[t.p][e.p]=!0,n.d[e.p][t.p]=!0),n.a[t.p][e.p]}function Lsn(n,t){if(!n.ai()&&null==t)throw Fp(new Ry("The 'no null' constraint is violated"));return t}function Nsn(n,t){null==n.D&&null!=n.B&&(n.D=n.B,n.B=null),Fin(n,null==t?null:(mW(t),t)),n.C&&n.yk(null)}function xsn(n,t){return!(!n||n==t||!Ax(t,(oWn(),elt)))&&_B(pMn(t,(oWn(),elt)),10)!=n}function Dsn(n){switch(n.i){case 2:return!0;case 1:return!1;case-1:++n.c;default:return n.pl()}}function Rsn(n){switch(n.i){case-2:return!0;case-1:return!1;case 1:--n.c;default:return n.ql()}}function Ksn(n){RY.call(this,"The given string does not match the expected format for individual spacings.",n)}function _sn(){_sn=O,cOt=new iC("ELK",0),aOt=new iC("JSON",1),rOt=new iC("DOT",2),uOt=new iC("SVG",3)}function Fsn(){Fsn=O,ujt=new gI(WZn,0),ojt=new gI("RADIAL_COMPACTION",1),sjt=new gI("WEDGE_COMPACTION",2)}function Bsn(){Bsn=O,qet=new dS("CONCURRENT",0),Get=new dS("IDENTITY_FINISH",1),zet=new dS("UNORDERED",2)}function Hsn(){Hsn=O,lM(),act=new OO(_Yn,uct=ect),cct=new cp(FYn),oct=new cp(BYn),sct=new cp(HYn)}function qsn(){qsn=O,hst=new ji,fst=new Ei,sst=new Ti,ost=new Mi,mW(new Si),ust=new D}function Gsn(){Gsn=O,nmt=new UP("CONSERVATIVE",0),tmt=new UP("CONSERVATIVE_SOFT",1),emt=new UP("SLOPPY",2)}function zsn(){zsn=O,bIt=new UA(15),lIt=new zA((uWn(),zSt),bIt),wIt=wPt,oIt=rSt,sIt=DSt,fIt=_St,hIt=KSt}function Usn(n,t,e){var i,r;for(i=new VT,r=upn(e,0);r.b!=r.d.c;)NH(i,new lA(_B(f3(r),8)));Csn(n,t,i)}function Xsn(n){var t,e,i;for(t=0,i=L8(MMt,uVn,8,n.b,0,1),e=upn(n,0);e.b!=e.d.c;)i[t++]=_B(f3(e),8);return i}function Wsn(n){var t;return!n.a&&(n.a=new nU(zAt,n,9,5)),0!=(t=n.a).i?FM(_B(Utn(t,0),678)):null}function Vsn(n,t){var e;return e=ebn(n,t),uS(e0(n,t),0)|VC(e0(n,e),0)?e:ebn(fVn,e0(yz(e,63),1))}function Qsn(n,t){var e;e=null!=ppn((xwn(),Xpt))&&null!=t.wg()?Hy(ED(t.wg()))/Hy(ED(ppn(Xpt))):1,XW(n.b,t,e)}function Jsn(n,t){var e,i;return(e=_B(n.d.Bc(t),14))?((i=n.e.hc()).Gc(e),n.e.d-=e.gc(),e.$b(),i):null}function Ysn(n,t){var e,i;if(0!=(i=n.c[t]))for(n.c[t]=0,n.d-=i,e=t+1;e0)return Dz(t-1,n.a.c.length),u6(n.a,t-1);throw Fp(new pv)}function nhn(n,t,e){if(t<0)throw Fp(new Cy(Y4n+t));tt)throw Fp(new Ry(pJn+n+vJn+t));if(n<0||t>e)throw Fp(new jk(pJn+n+mJn+t+oJn+e))}function ehn(n){if(!n.a||0==(8&n.a.i))throw Fp(new Ky("Enumeration class expected for layout option "+n.f))}function ihn(n){var t;++n.j,0==n.i?n.g=null:n.iR3n?n-e>R3n:e-n>R3n)}function ghn(n,t){return n?t&&!n.j||iL(n,124)&&0==_B(n,124).a.b?0:n.Re():0}function phn(n,t){return n?t&&!n.k||iL(n,124)&&0==_B(n,124).a.a?0:n.Se():0}function vhn(n){return IDn(),n<0?-1!=n?new xpn(-1,-n):Vtt:n<=10?Jtt[SY(n)]:new xpn(1,n)}function mhn(n){throw Jun(),Fp(new wy("Unexpected typeof result '"+n+"'; please report this bug to the GWT team"))}function yhn(n){ok(),X$(this),yQ(this),this.e=n,Sxn(this,n),this.g=null==n?qWn:_bn(n),this.a="",this.b=n,this.a=""}function khn(){this.a=new nu,this.f=new bg(this),this.b=new wg(this),this.i=new dg(this),this.e=new gg(this)}function jhn(){iy.call(this,new B8(ntn(16))),hin(2,aVn),this.b=2,this.a=new FW(null,null,0,null),tv(this.a,this.a)}function Ehn(){Ehn=O,ivt=new DP("DUMMY_NODE_OVER",0),rvt=new DP("DUMMY_NODE_UNDER",1),cvt=new DP("EQUAL",2)}function Thn(){Thn=O,zat=FY(Mun(Hk(UPt,1),OVn,103,0,[(Kfn(),RPt),KPt])),Uat=FY(Mun(Hk(UPt,1),OVn,103,0,[FPt,DPt]))}function Mhn(n){return(mUn(),vCt).Hc(n.j)?Hy(ED(pMn(n,(oWn(),Alt)))):Con(Mun(Hk(MMt,1),uVn,8,0,[n.i.n,n.n,n.a])).b}function Shn(n){var t,e;for(t=n.b.a.a.ec().Kc();t.Ob();)e=new W$n(_B(t.Pb(),561),n.e,n.f),UB(n.g,e)}function Phn(n,t){var e,i;e=n.nk(t,null),i=null,t&&(tE(),ien(i=new Dp,n.r)),(e=FTn(n,i,e))&&e.Fi()}function Ihn(n,t){var e,i;for(i=0!=F$n(n.d,1),e=!0;e;)e=!1,e=t.c.Tf(t.e,i),e|=NNn(n,t,i,!1),i=!i;Orn(n)}function Chn(n,t){var e,i,r;return i=!1,e=t.q.d,t.dr&&(rEn(t.q,r),i=e!=t.q.d)),i}function Ohn(n,t){var e,r,c,a,u;return a=t.i,u=t.j,r=a-(e=n.f).i,c=u-e.j,i.Math.sqrt(r*r+c*c)}function Ahn(n,t){var e;return(e=Vdn(n))||(xHn(),s9((e=new Sp(VPn(t))).Vk(),n)),e}function $hn(n,t){var e,i;return(e=_B(n.c.Bc(t),14))?((i=n.hc()).Gc(e),n.d-=e.gc(),e.$b(),n.mc(i)):n.jc()}function Lhn(n,t){var e;for(e=0;e=n.c.b:n.a<=n.c.b))throw Fp(new vv);return t=n.a,n.a+=n.c.c,++n.b,tln(t)}function _hn(n){var t;return t=new stn(n),t2(n.a,uut,new Qy(Mun(Hk(Qat,1),FWn,369,0,[t]))),t.d&&UB(t.f,t.d),t.f}function Fhn(n){var t;return Ban(t=new I$(n.a),n),oon(t,(oWn(),blt),n),t.o.a=n.g,t.o.b=n.f,t.n.a=n.i,t.n.b=n.j,t}function Bhn(n,t,e,i){var r,c;for(c=n.Kc();c.Ob();)(r=_B(c.Pb(),70)).n.a=t.a+(i.a-r.o.a)/2,r.n.b=t.b,t.b+=r.o.b+e}function Hhn(n,t,e){var i;for(i=t.a.a.ec().Kc();i.Ob();)if(iJ(n,_B(i.Pb(),57),e))return!0;return!1}function qhn(n){var t,e;for(e=new Ub(n.r);e.a=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function tfn(n,t){var e,i,r;for(r=1,e=n,i=t>=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function efn(n){var t,e;if(null!=n)for(e=0;e0&&bsn(_B(Lq(n.a,n.a.c.length-1),570),t)||UB(n.a,new d5(t))}function gfn(n){var t,e;H_(),t=n.d.c-n.e.c,Itn((e=_B(n.g,145)).b,new yd(t)),Itn(e.c,new kd(t)),n5(e.i,new jd(t))}function pfn(n){var t;return(t=new Sk).a+="VerticalSegment ",cO(t,n.e),t.a+=" ",aO(t,QL(new pk,new Ub(n.k))),t.a}function vfn(n){var t;return(t=_B(hnn(n.c.c,""),229))||(t=new GZ(yj(mj(new pu,""),"Other")),Qgn(n.c.c,"",t)),t}function mfn(n){var t;return 0!=(64&n.Db)?M$n(n):((t=new sN(M$n(n))).a+=" (name: ",iO(t,n.zb),t.a+=")",t.a)}function yfn(n,t,e){var i,r;return r=n.sb,n.sb=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new Yz(n,1,4,r,t),e?e.Ei(i):e=i),e}function kfn(n,t){var e,i;for(e=0,i=rbn(n,t).Kc();i.Ob();)e+=null!=pMn(_B(i.Pb(),11),(oWn(),klt))?1:0;return e}function jfn(n,t,e){var i,r,c;for(i=0,c=upn(n,0);c.b!=c.d.c&&!((r=Hy(ED(f3(c))))>e);)r>=t&&++i;return i}function Efn(n,t,e){var i;return i=new $7(n.e,3,13,null,t.c||(wWn(),s$t),cvn(n,t),!1),e?e.Ei(i):e=i,e}function Tfn(n,t,e){var i;return i=new $7(n.e,4,13,t.c||(wWn(),s$t),null,cvn(n,t),!1),e?e.Ei(i):e=i,e}function Mfn(n,t,e){var i,r;return r=n.r,n.r=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new Yz(n,1,8,r,n.r),e?e.Ei(i):e=i),e}function Sfn(n,t){var e,i;return!(i=(e=_B(t,676)).vk())&&e.wk(i=iL(t,88)?new OC(n,_B(t,26)):new R0(n,_B(t,148))),i}function Pfn(n,t,e){var i;n.qi(n.i+1),i=n.oi(t,e),t!=n.i&&rHn(n.g,t,n.g,t+1,n.i-t),OX(n.g,t,i),++n.i,n.bi(t,e),n.ci()}function Ifn(n,t){var e;return t.a&&(e=t.a.a.length,n.a?aO(n.a,n.b):n.a=new hN(n.d),H0(n.a,t.a,t.d.length,e)),n}function Cfn(n,t){var e,i,r;if(t.vi(n.a),null!=(r=_B(van(n.a,8),1936)))for(e=0,i=r.length;ee)throw Fp(new Cy(pJn+n+mJn+t+", size: "+e));if(n>t)throw Fp(new Ry(pJn+n+vJn+t))}function Bfn(n,t,e){if(t<0)iCn(n,e);else{if(!e.Ij())throw Fp(new Ry(e6n+e.ne()+i6n));_B(e,66).Nj().Vj(n,n.yh(),t)}}function Hfn(n,t,e,i,r,c,a,u){var o;for(o=e;c=i||t=65&&n<=70?n-65+10:n>=97&&n<=102?n-97+10:n>=48&&n<=57?n-48:0}function Xfn(n){var t;return 0!=(64&n.Db)?M$n(n):((t=new sN(M$n(n))).a+=" (source: ",iO(t,n.d),t.a+=")",t.a)}function Wfn(n,t,e){var i,r;return r=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new Yz(n,1,5,r,n.a),e?DEn(e,i):e=i),e}function Vfn(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,2,e,t))}function Qfn(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,8,e,t))}function Jfn(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,8,e,t))}function Yfn(n,t){var e;e=0!=(512&n.Bb),t?n.Bb|=512:n.Bb&=-513,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,3,e,t))}function Zfn(n,t){var e;e=0!=(512&n.Bb),t?n.Bb|=512:n.Bb&=-513,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,9,e,t))}function nln(n,t){var e;return-1==n.b&&n.a&&(e=n.a.Gj(),n.b=e?n.c.Xg(n.a.aj(),e):Cwn(n.c.Tg(),n.a)),n.c.Og(n.b,t)}function tln(n){var t,e;return n>-129&&n<128?(t=n+128,!(e=(ZH(),Ptt)[t])&&(e=Ptt[t]=new Lb(n)),e):new Lb(n)}function eln(n){var t,e;return n>-129&&n<128?(t=n+128,!(e=(jq(),Dtt)[t])&&(e=Dtt[t]=new xb(n)),e):new xb(n)}function iln(n){var t;return n.k==(cSn(),Eut)&&((t=_B(pMn(n,(oWn(),Wft)),61))==(mUn(),uCt)||t==TCt)}function rln(n,t,e){var i,r;return(r=O$n(n.b,t))&&(i=_B($Hn(K7(n,r),""),26))?p$n(n,i,t,e):null}function cln(n,t,e){var i,r;return(r=O$n(n.b,t))&&(i=_B($Hn(K7(n,r),""),26))?v$n(n,i,t,e):null}function aln(n,t){var e,i;for(i=new CL(n);i.e!=i.i.gc();)if(e=_B(mpn(i),138),HC(t)===HC(e))return!0;return!1}function uln(n,t,e){var i;if(t>(i=n.gc()))throw Fp(new ZR(t,i));if(n.hi()&&n.Hc(e))throw Fp(new Ry(r8n));n.Xh(t,e)}function oln(n,t){var e;if(null==(e=uen(n.i,t)))throw Fp(new nk("Node did not exist in input."));return Dcn(t,e),null}function sln(n,t){var e;if(iL(e=$Nn(n,t),322))return _B(e,34);throw Fp(new Ry(e6n+t+"' is not a valid attribute"))}function hln(n,t,e){var i,r;for(r=iL(t,99)&&0!=(_B(t,18).Bb&_Qn)?new LO(t,n):new Can(t,n),i=0;it?1:n==t?0==n?Mln(1/n,1/t):0:isNaN(n)?isNaN(t)?0:1:-1}function Sln(n,t){ITn(t,"Sort end labels",1),QT(CV(lnn(new xq(null,new l1(n.b,16)),new we),new de),new ge),FSn(t)}function Pln(n,t,e){var i,r;return n.ej()?(r=n.fj(),i=VCn(n,t,e),n.$i(n.Zi(7,tln(e),i,t,r)),i):VCn(n,t,e)}function Iln(n,t){var e,i,r;null==n.d?(++n.e,--n.f):(r=t.cd(),$6(n,i=((e=t.Sh())&NWn)%n.d.length,C$n(n,i,e,r)))}function Cln(n,t){var e;e=0!=(n.Bb&m6n),t?n.Bb|=m6n:n.Bb&=-1025,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,10,e,t))}function Oln(n,t){var e;e=0!=(n.Bb&RQn),t?n.Bb|=RQn:n.Bb&=-4097,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,12,e,t))}function Aln(n,t){var e;e=0!=(n.Bb&j9n),t?n.Bb|=j9n:n.Bb&=-8193,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,15,e,t))}function $ln(n,t){var e;e=0!=(n.Bb&E9n),t?n.Bb|=E9n:n.Bb&=-2049,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,11,e,t))}function Lln(n,t){var e;return 0!=(e=Mln(n.b.c,t.b.c))||0!=(e=Mln(n.a.a,t.a.a))?e:Mln(n.a.b,t.a.b)}function Nln(n,t){var e;if(null==(e=xX(n.k,t)))throw Fp(new nk("Port did not exist in input."));return Dcn(t,e),null}function xln(n){var t,e;for(e=H$n(Gtn(n)).Kc();e.Ob();)if($_n(n,t=TD(e.Pb())))return v4((GM(),NAt),t);return null}function Dln(n,t){var e,i,r,c,a;for(a=rxn(n.e.Tg(),t),c=0,e=_B(n.g,119),r=0;r>10)+FQn&WVn,t[1]=56320+(1023&n)&WVn,_dn(t,0,t.length)}function Uln(n){var t;return(t=_B(pMn(n,(FXn(),Gdt)),103))==(Kfn(),_Pt)?Hy(ED(pMn(n,kdt)))>=1?KPt:DPt:t}function Xln(n){switch(_B(pMn(n,(FXn(),Jdt)),218).g){case 1:return new ic;case 3:return new oc;default:return new ec}}function Wln(n){if(n.c)Wln(n.c);else if(n.d)throw Fp(new Ky("Stream already terminated, can't be modified or used"))}function Vln(n){var t;return 0!=(64&n.Db)?M$n(n):((t=new sN(M$n(n))).a+=" (identifier: ",iO(t,n.k),t.a+=")",t.a)}function Qln(n,t,e){var i;return Zj(),yen(i=new ro,t),ken(i,e),n&&s9((!n.a&&(n.a=new OL($Ot,n,5)),n.a),i),i}function Jln(n,t,e,i){var r,c;return mW(i),mW(e),null==(c=null==(r=n.xc(t))?e:JT(_B(r,15),_B(e,14)))?n.Bc(t):n.zc(t,c),c}function Yln(n){var t,e,i,r;return arn(e=new VK(t=_B(Xj((r=(i=n.gm).f)==Gnt?i:r),9),_B(TR(t,t.length),9),0),n),e}function Zln(n,t,e){var i,r;for(r=n.a.ec().Kc();r.Ob();)if(i=_B(r.Pb(),10),aun(e,_B(Lq(t,i.p),14)))return i;return null}function nbn(n,t,e){try{Ron(n,t,e)}catch(i){throw iL(i=hun(i),597)?Fp(new w5(i)):Fp(i)}return t}function tbn(n,t){var e;return QO(n)&&QO(t)&&OQn<(e=n-t)&&e>1,n.k=e-1>>1}function ubn(){var n,t,e;vTn(),e=Aet+++Date.now(),n=SY(i.Math.floor(e*cJn))&uJn,t=SY(e-n*aJn),this.a=1502^n,this.b=t^rJn}function obn(n){var t,e;for(t=new $p,e=new Ub(n.j);e.a34028234663852886e22?xQn:t<-34028234663852886e22?DQn:t}function dbn(n){return n=((n=((n-=n>>1&1431655765)>>2&858993459)+(858993459&n))>>4)+n&252645135,n+=n>>8,63&(n+=n>>16)}function gbn(n){var t,e,i;for(t=new oR(n.Hd().gc()),i=0,e=A9(n.Hd().Kc());e.Ob();)yZ(t,e.Pb(),tln(i++));return $Sn(t.a)}function pbn(n,t){var e,i,r;for(r=new Lp,i=t.vc().Kc();i.Ob();)XW(r,(e=_B(i.Pb(),42)).cd(),han(n,_B(e.dd(),15)));return r}function vbn(n,t){0==n.n.c.length&&UB(n.n,new xY(n.s,n.t,n.i)),UB(n.b,t),umn(_B(Lq(n.n,n.n.c.length-1),211),t),_Fn(n,t)}function mbn(n){return n.c==n.b.b&&n.i==n.g.b||(n.a.c=L8(Cnt,FWn,1,0,5,1),wun(n.a,n.b),wun(n.a,n.g),n.c=n.b.b,n.i=n.g.b),n.a}function ybn(n,t){var e,i;for(i=0,e=_B(t.Kb(n),20).Kc();e.Ob();)By(jD(pMn(_B(e.Pb(),17),(oWn(),Slt))))||++i;return i}function kbn(n,t){var e,r;r=Hy(ED(ndn(s2(t),(FXn(),vpt)))),Kkn(t,e=i.Math.max(0,r/2-.5),1),UB(n,new hP(t,e))}function jbn(){jbn=O,Blt=new _P(WZn,0),Rlt=new _P("FIRST",1),Klt=new _P(S1n,2),_lt=new _P("LAST",3),Flt=new _P(P1n,4)}function Ebn(){Ebn=O,JPt=new KI(oYn,0),VPt=new KI("POLYLINE",1),WPt=new KI("ORTHOGONAL",2),QPt=new KI("SPLINES",3)}function Tbn(){Tbn=O,Jjt=new mI("ASPECT_RATIO_DRIVEN",0),Yjt=new mI("MAX_SCALE_DRIVEN",1),Qjt=new mI("AREA_DRIVEN",2)}function Mbn(){Mbn=O,FEt=new kI("P1_STRUCTURE",0),BEt=new kI("P2_PROCESSING_ORDER",1),HEt=new kI("P3_EXECUTION",2)}function Sbn(){Sbn=O,njt=new wI("OVERLAP_REMOVAL",0),Ykt=new wI("COMPACTION",1),Zkt=new wI("GRAPH_SIZE_CALCULATION",2)}function Pbn(n,t){return o$(),ein(DVn),i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:qO(isNaN(n),isNaN(t))}function Ibn(n,t){var e,i;for(e=upn(n,0);e.b!=e.d.c;){if((i=qy(ED(f3(e))))==t)return;if(i>t){G0(e);break}}YU(e,t)}function Cbn(n,t){var e,i,r,c,a;if(e=t.f,Qgn(n.c.d,e,t),null!=t.g)for(c=0,a=(r=t.g).length;ct&&i.ue(n[c-1],n[c])>0;--c)a=n[c],OX(n,c,n[c-1]),OX(n,c-1,a)}function Abn(n,t,e,i){if(t<0)jLn(n,e,i);else{if(!e.Ij())throw Fp(new Ry(e6n+e.ne()+i6n));_B(e,66).Nj().Tj(n,n.yh(),t,i)}}function $bn(n,t){if(t==n.d)return n.e;if(t==n.e)return n.d;throw Fp(new Ry("Node "+t+" not part of edge "+n))}function Lbn(n,t){switch(t.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 Nbn(n,t){switch(t.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 xbn(n,t,e,i){switch(t){case 3:return n.f;case 4:return n.g;case 5:return n.i;case 6:return n.j}return Rfn(n,t,e,i)}function Dbn(n){return n.k==(cSn(),Sut)&&a5(new xq(null,new qU(new az(JL(hbn(n).a.Kc(),new h)))),new qr)}function Rbn(n){return null==n.e?n:(!n.c&&(n.c=new eRn(0!=(256&n.f),n.i,n.a,n.d,0!=(16&n.f),n.j,n.g,null)),n.c)}function Kbn(n,t){return n.h==SQn&&0==n.m&&0==n.l?(t&&(htt=E$(0,0,0)),UO((z7(),btt))):(t&&(htt=E$(n.l,n.m,n.h)),E$(0,0,0))}function _bn(n){return Array.isArray(n)&&n.im===C?Yj(Zon(n))+"@"+(Yon(n)>>>0).toString(16):n.toString()}function Fbn(n){var t;this.a=new VK(t=_B(n.e&&n.e(),9),_B(TR(t,t.length),9),0),this.b=L8(Cnt,FWn,1,this.a.a.length,5,1)}function Bbn(n){var t,e,i;for(this.a=new sA,i=new Ub(n);i.a0&&(f1(t-1,n.length),58==n.charCodeAt(t-1))&&!zbn(n,OAt,AAt)}function zbn(n,t,e){var i,r;for(i=0,r=n.length;i=r)return t.c+e;return t.c+t.b.gc()}function Wbn(n,t){var e,i,r,c;for(bD(),r=t,q9(i=F9(n),0,i.length,r),e=0;e0&&(i+=r,++e);return e>1&&(i+=n.d*(e-1)),i}function Qbn(n){var t,e,i;for((i=new Tk).a+="[",t=0,e=n.gc();t0&&this.b>0&&Vq(this.c,this.b,this.a)}function cwn(n){xwn(),this.c=c6(Mun(Hk(eMt,1),FWn,831,0,[Upt])),this.b=new Lp,this.a=n,XW(this.b,Xpt,1),Itn(Wpt,new Mg(this))}function awn(n,t){var e;return n.d?oU(n.b,t)?_B(xX(n.b,t),51):(e=t.Kf(),XW(n.b,t,e),e):t.Kf()}function uwn(n,t){var e;return HC(n)===HC(t)||!!iL(t,91)&&(e=_B(t,91),n.e==e.e&&n.d==e.d&&k4(n,e.a))}function own(n){switch(mUn(),n.g){case 4:return uCt;case 1:return aCt;case 3:return TCt;case 2:return SCt;default:return MCt}}function swn(n,t){switch(t){case 3:return 0!=n.f;case 4:return 0!=n.g;case 5:return 0!=n.i;case 6:return 0!=n.j}return kan(n,t)}function hwn(n){switch(n.g){case 0:return new Ga;case 1:return new za;default:throw Fp(new Ry(i4n+(null!=n.f?n.f:""+n.g)))}}function fwn(n){switch(n.g){case 0:return new qa;case 1:return new Ua;default:throw Fp(new Ry(E1n+(null!=n.f?n.f:""+n.g)))}}function lwn(n){switch(n.g){case 0:return new Xm;case 1:return new vm;default:throw Fp(new Ry($4n+(null!=n.f?n.f:""+n.g)))}}function bwn(n){switch(n.g){case 1:return new Ra;case 2:return new wD;default:throw Fp(new Ry(i4n+(null!=n.f?n.f:""+n.g)))}}function wwn(n){var t,e;if(n.b)return n.b;for(e=Wet?null:n.d;e;){if(t=Wet?null:e.b)return t;e=Wet?null:e.d}return hM(),Fet}function dwn(n){var t,e;return 0==n.e?0:(t=n.d<<5,e=n.a[n.d-1],n.e<0&&Scn(n)==n.d-1&&(--e,e|=0),t-=JCn(e))}function gwn(n){var t,e,i;return n>5),15,1))[e]=1<3;)r*=10,--c;n=(n+(r>>1))/r|0}return i.i=n,!0}function kwn(n){return Thn(),oN(),!!(Nbn(_B(n.a,81).j,_B(n.b,103))||0!=_B(n.a,81).d.e&&Nbn(_B(n.a,81).j,_B(n.b,103)))}function jwn(n){L9(),_B(n.We((uWn(),BSt)),174).Hc((YKn(),XCt))&&(_B(n.We(sPt),174).Fc((hCn(),iCt)),_B(n.We(BSt),174).Mc(XCt))}function Ewn(n,t){var e;if(t){for(e=0;e=0;--i)for(t=e[i],r=0;r>1,this.k=t-1>>1}function Hwn(n,t){ITn(t,"End label post-processing",1),QT(CV(lnn(new xq(null,new l1(n.b,16)),new ae),new ue),new oe),FSn(t)}function qwn(n,t,e){var i;return i=Hy(n.p[t.i.p])+Hy(n.d[t.i.p])+t.n.b+t.a.b,Hy(n.p[e.i.p])+Hy(n.d[e.i.p])+e.n.b+e.a.b-i}function Gwn(n,t,e){var i,r;for(i=n0(e,GQn),r=0;0!=Xhn(i,0)&&r0&&(f1(0,t.length),43==t.charCodeAt(0))?t.substr(1):t)}function Xwn(n){var t;return null==n?null:new OA((t=KBn(n,!0)).length>0&&(f1(0,t.length),43==t.charCodeAt(0))?t.substr(1):t)}function Wwn(n,t){return n.i>0&&(t.lengthn.i&&OX(t,n.i,null),t}function Vwn(n,t,e){var i,r,c;return n.ej()?(i=n.i,c=n.fj(),Pfn(n,i,t),r=n.Zi(3,null,t,i,c),e?e.Ei(r):e=r):Pfn(n,n.i,t),e}function Qwn(n,t,e){var i,r;return i=new $7(n.e,4,10,iL(r=t.c,88)?_B(r,26):(wWn(),l$t),null,cvn(n,t),!1),e?e.Ei(i):e=i,e}function Jwn(n,t,e){var i,r;return i=new $7(n.e,3,10,null,iL(r=t.c,88)?_B(r,26):(wWn(),l$t),cvn(n,t),!1),e?e.Ei(i):e=i,e}function Ywn(n){var t;return BD(),t=new lA(_B(n.e.We((uWn(),_St)),8)),n.B.Hc((YKn(),HCt))&&(t.a<=0&&(t.a=20),t.b<=0&&(t.b=20)),t}function Zwn(n){return fvn(),(n.q?n.q:(TQ(),TQ(),oet))._b((FXn(),xgt))?_B(pMn(n,xgt),197):_B(pMn(gW(n),Dgt),197)}function ndn(n,t){var e,i;return i=null,Ax(n,(FXn(),Ept))&&(e=_B(pMn(n,Ept),94)).Xe(t)&&(i=e.We(t)),null==i&&(i=pMn(gW(n),t)),i}function tdn(n,t){var e,i,r;return!!iL(t,42)&&(i=(e=_B(t,42)).cd(),lW(r=hfn(n.Rc(),i),e.dd())&&(null!=r||n.Rc()._b(i)))}function edn(n,t){var e;return n.f>0&&(n.qj(),-1!=C$n(n,((e=null==t?0:Yon(t))&NWn)%n.d.length,e,t))}function idn(n,t){var e,i;return n.f>0&&(n.qj(),e=rOn(n,((i=null==t?0:Yon(t))&NWn)%n.d.length,i,t))?e.dd():null}function rdn(n,t){var e,i,r,c;for(c=rxn(n.e.Tg(),t),e=_B(n.g,119),r=0;r1?t0(vz(t.a[1],32),n0(t.a[0],GQn)):n0(t.a[0],GQn),y2(ibn(t.e,e))))}function hdn(n,t){var e;return QO(n)&&QO(t)&&OQn<(e=n%t)&&e>5,t&=31,r=n.d+e+(0==t?0:1),LTn(i=L8(INt,oQn,25,r,15,1),n.a,e,t),z0(c=new hU(n.e,r,i)),c}function jdn(n,t,e){var i,r;i=_B(TY(nNt,t),117),r=_B(TY(tNt,t),117),e?(pZ(nNt,n,i),pZ(tNt,n,r)):(pZ(tNt,n,i),pZ(nNt,n,r))}function Edn(n,t,e){var i,r,c;for(r=null,c=n.b;c;){if(i=n.a.ue(t,c.d),e&&0==i)return c;i>=0?c=c.a[1]:(r=c,c=c.a[0])}return r}function Tdn(n,t,e){var i,r,c;for(r=null,c=n.b;c;){if(i=n.a.ue(t,c.d),e&&0==i)return c;i<=0?c=c.a[0]:(r=c,c=c.a[1])}return r}function Mdn(n,t,e,i){var r,c,a;return r=!1,AGn(n.f,e,i)&&(Lgn(n.f,n.a[t][e],n.a[t][i]),a=(c=n.a[t])[i],c[i]=c[e],c[e]=a,r=!0),r}function Sdn(n,t,e,i,r){var c,a,u;for(a=r;t.b!=t.c;)c=_B(bU(t),10),u=_B(rbn(c,i).Xb(0),11),n.d[u.p]=a++,e.c[e.c.length]=u;return a}function Pdn(n,t,e){var r,c,a,u,o;return u=n.k,o=t.k,c=ED(ndn(n,r=e[u.g][o.g])),a=ED(ndn(t,r)),i.Math.max((mW(c),c),(mW(a),a))}function Idn(n,t,e){var i,r,c,a;for(i=e/n.c.length,r=0,a=new Ub(n);a.a2e3&&(rtt=n,ctt=i.setTimeout(WE,10)),0==itt++&&(Inn((uk(),Znt)),!0)}function $dn(n,t){var e;for(e=new az(JL(hbn(n).a.Kc(),new h));bAn(e);)if(_B(G5(e),17).d.i.c==t)return!1;return!0}function Ldn(n,t){var e;if(iL(t,245)){e=_B(t,245);try{return 0==n.vd(e)}catch(i){if(!iL(i=hun(i),205))throw Fp(i)}}return!1}function Ndn(){return Error.stackTraceLimit>0?(i.Error.stackTraceLimit=Error.stackTraceLimit=64,!0):"stack"in new Error}function xdn(n,t){return o$(),o$(),ein(DVn),(i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:qO(isNaN(n),isNaN(t)))>0}function Ddn(n,t){return o$(),o$(),ein(DVn),(i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:qO(isNaN(n),isNaN(t)))<0}function Rdn(n,t){return o$(),o$(),ein(DVn),(i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:qO(isNaN(n),isNaN(t)))<=0}function Kdn(n,t){for(var e=0;!t[e]||""==t[e];)e++;for(var i=t[e++];eHQn)return e.fh();if((i=e.Zg())||e==n)break}return i}function Qdn(n){return oZ(),iL(n,156)?_B(xX(cAt,vet),288).vg(n):oU(cAt,Zon(n))?_B(xX(cAt,Zon(n)),288).vg(n):null}function Jdn(n){if(pgn(r5n,n))return oN(),gtt;if(pgn(c5n,n))return oN(),dtt;throw Fp(new Ry("Expecting true or false"))}function Ydn(n,t){if(t.c==n)return t.d;if(t.d==n)return t.c;throw Fp(new Ry("Input edge is not connected to the input port."))}function Zdn(n,t){return n.e>t.e?1:n.et.d?n.e:n.d=48&&n<48+i.Math.min(10,10)?n-48:n>=97&&n<97?n-97+10:n>=65&&n<65?n-65+10:-1}function tgn(n,t){var e;return HC(t)===HC(n)||!!iL(t,21)&&(e=_B(t,21)).gc()==n.gc()&&n.Ic(e)}function egn(n,t){var e,i,r;return i=n.a.length-1,e=t-n.b&i,r=n.c-t&i,kx(e<(n.c-n.b&i)),e>=r?(rhn(n,t),-1):(chn(n,t),1)}function ign(n,t){var e,i;for(f1(t,n.length),e=n.charCodeAt(t),i=t+1;it.e?1:n.ft.f?1:Yon(n)-Yon(t)}function pgn(n,t){return mW(n),null!=t&&(!!pK(n,t)||n.length==t.length&&pK(n.toLowerCase(),t.toLowerCase()))}function vgn(n,t){var e,i,r,c;for(i=0,r=t.gc();i0&&Xhn(n,128)<0?(t=bG(n)+128,!(e=(kq(),Ott)[t])&&(e=Ott[t]=new Nb(n)),e):new Nb(n)}function kgn(n,t){var e,i;return(e=t.Hh(n.a))&&null!=(i=TD(idn((!e.b&&(e.b=new Qx((wWn(),v$t),G$t,e)),e.b),Z6n)))?i:t.ne()}function jgn(n,t){var e,i;return(e=t.Hh(n.a))&&null!=(i=TD(idn((!e.b&&(e.b=new Qx((wWn(),v$t),G$t,e)),e.b),Z6n)))?i:t.ne()}function Egn(n,t){var e,i;for(BZ(),i=new az(JL(obn(n).a.Kc(),new h));bAn(i);)if((e=_B(G5(i),17)).d.i==t||e.c.i==t)return e;return null}function Tgn(n,t,e){this.c=n,this.f=new $p,this.e=new Hj,this.j=new Tq,this.n=new Tq,this.b=t,this.g=new GV(t.c,t.d,t.b,t.a),this.a=e}function Mgn(n){var t,e,i,r;for(this.a=new sA,this.d=new xv,this.e=0,i=0,r=(e=n).length;i0)}function $gn(n){var t;HC(JAn(n,(uWn(),kSt)))===HC((cfn(),gIt))&&(QY(n)?(t=_B(JAn(QY(n),kSt),334),Vpn(n,kSt,t)):Vpn(n,kSt,pIt))}function Lgn(n,t,e){var i,r;sMn(n.e,t,e,(mUn(),SCt)),sMn(n.i,t,e,aCt),n.a&&(r=_B(pMn(t,(oWn(),blt)),11),i=_B(pMn(e,blt),11),m0(n.g,r,i))}function Ngn(n,t,e){var i,r,c;i=t.c.p,c=t.p,n.b[i][c]=new NJ(n,t),e&&(n.a[i][c]=new _d(t),(r=_B(pMn(t,(oWn(),elt)),10))&&QCn(n.d,r,t))}function xgn(n,t){var e,i,r;if(UB(Tct,n),t.Fc(n),e=_B(xX(Ect,n),21))for(r=e.Kc();r.Ob();)i=_B(r.Pb(),33),-1!=k7(Tct,i,0)||xgn(i,t)}function Dgn(n,t,e){var i;(Uet?(wwn(n),1):Xet||Qet?(hM(),1):Vet&&(hM(),0))&&((i=new t_(t)).b=e,rSn(n,i))}function Rgn(n,t){var e;e=!n.A.Hc((pdn(),RCt))||n.q==(WEn(),zIt),n.u.Hc((hCn(),nCt))?e?$Un(n,t):rUn(n,t):n.u.Hc(eCt)&&(e?Czn(n,t):QUn(n,t))}function Kgn(n,t){var e,i;++n.j,null!=t&&aOn(t,e=iL(i=n.a.Cb,97)?_B(i,97).Jg():null)?ogn(n.a,4,e):ogn(n.a,4,_B(t,126))}function _gn(n,t,e){return new GV(i.Math.min(n.a,t.a)-e/2,i.Math.min(n.b,t.b)-e/2,i.Math.abs(n.a-t.a)+e,i.Math.abs(n.b-t.b)+e)}function Fgn(n,t){var e,i;return 0!=(e=k$(n.a.c.p,t.a.c.p))?e:0!=(i=k$(n.a.d.i.p,t.a.d.i.p))?i:k$(t.a.d.p,n.a.d.p)}function Bgn(n,t,e){var i,r,c,a;return(c=t.j)!=(a=e.j)?c.g-a.g:(i=n.f[t.p],r=n.f[e.p],0==i&&0==r?0:0==i?-1:0==r?1:Mln(i,r))}function Hgn(n,t,e){var i;if(!e[t.d])for(e[t.d]=!0,i=new Ub(mbn(t));i.a=(r=n.length))return r;for(t=t>0?t:0;ti&&OX(t,i,null),t}function Vgn(n,t){var e,i;for(i=n.a.length,t.lengthi&&OX(t,i,null),t}function Qgn(n,t,e){var i,r,c;return(r=_B(xX(n.e,t),387))?(c=dR(r,e),cL(n,r),c):(i=new YB(n,t,e),XW(n.e,t,i),mY(i),null)}function Jgn(n){var t;if(null==n)return null;if(null==(t=A$n(KBn(n,!0))))throw Fp(new tk("Invalid hexBinary value: '"+n+"'"));return t}function Ygn(n){return IDn(),Xhn(n,0)<0?0!=Xhn(n,-1)?new gEn(-1,y7(n)):Vtt:Xhn(n,10)<=0?Jtt[bG(n)]:new gEn(1,n)}function Zgn(){return bWn(),Mun(Hk(Drt,1),OVn,159,0,[Mrt,Trt,Srt,grt,drt,prt,yrt,mrt,vrt,Ert,jrt,krt,brt,lrt,wrt,hrt,srt,frt,urt,art,ort,Prt])}function npn(n){var t;this.d=new $p,this.j=new Hj,this.g=new Hj,t=n.g.b,this.f=_B(pMn(gW(t),(FXn(),Gdt)),103),this.e=Hy(ED(wpn(t,Tpt)))}function tpn(n){this.b=new $p,this.e=new $p,this.d=n,this.a=!yE(CV(new xq(null,new qU(new p6(n.b))),new rw(new Gr))).sd((bM(),Zet))}function epn(){epn=O,oMt=new CI("PARENTS",0),uMt=new CI("NODES",1),cMt=new CI("EDGES",2),sMt=new CI("PORTS",3),aMt=new CI("LABELS",4)}function ipn(){ipn=O,_It=new qI("DISTRIBUTED",0),BIt=new qI("JUSTIFIED",1),RIt=new qI("BEGIN",2),KIt=new qI(nYn,3),FIt=new qI("END",4)}function rpn(n){switch(n.yi(null)){case 10:return 0;case 15:return 1;case 14:return 2;case 11:return 3;case 21:return 4}return-1}function cpn(n){switch(n.g){case 1:return Kfn(),FPt;case 4:return Kfn(),RPt;case 2:return Kfn(),KPt;case 3:return Kfn(),DPt}return Kfn(),_Pt}function apn(n,t,e){var i;switch((i=e.q.getFullYear()-uQn+uQn)<0&&(i=-i),t){case 1:n.a+=i;break;case 2:knn(n,i%100,2);break;default:knn(n,i,t)}}function upn(n,t){var e,i;if(AZ(t,n.b),t>=n.b>>1)for(i=n.c,e=n.b;e>t;--e)i=i.b;else for(i=n.a.a,e=0;e=64&&t<128&&(r=t0(r,vz(1,t-64)));return r}function wpn(n,t){var e,i;return i=null,Ax(n,(uWn(),SPt))&&(e=_B(pMn(n,SPt),94)).Xe(t)&&(i=e.We(t)),null==i&&gW(n)&&(i=pMn(gW(n),t)),i}function dpn(n,t){var e,i,r;(i=(r=t.d.i).k)!=(cSn(),Sut)&&i!=jut&&bAn(e=new az(JL(hbn(r).a.Kc(),new h)))&&XW(n.k,t,_B(G5(e),17))}function gpn(n,t){var e,i,r;return i=ttn(n.Tg(),t),(e=t-n.Ah())<0?(r=n.Yg(i))>=0?n.lh(r):BCn(n,i):e<0?BCn(n,i):_B(i,66).Nj().Sj(n,n.yh(),e)}function ppn(n){var t;if(iL(n.a,4)){if(null==(t=Qdn(n.a)))throw Fp(new Ky(a5n+n.b+"'. "+e5n+(kD(hAt),hAt.k)+i5n));return t}return n.a}function vpn(n){var t;if(null==n)return null;if(null==(t=GUn(KBn(n,!0))))throw Fp(new tk("Invalid base64Binary value: '"+n+"'"));return t}function mpn(n){var t;try{return t=n.i.Xb(n.e),n.mj(),n.g=n.e++,t}catch(e){throw iL(e=hun(e),73)?(n.mj(),Fp(new vv)):Fp(e)}}function ypn(n){var t;try{return t=n.c.ki(n.e),n.mj(),n.g=n.e++,t}catch(e){throw iL(e=hun(e),73)?(n.mj(),Fp(new vv)):Fp(e)}}function kpn(){kpn=O,uWn(),kct=jPt,dct=vSt,hct=iSt,gct=zSt,Rkn(),mct=Eit,vct=kit,yct=Mit,pct=yit,Hsn(),lct=act,fct=cct,bct=oct,wct=sct}function jpn(n){switch(yM(),this.c=new $p,this.d=n,n.g){case 0:case 2:this.a=WW(out),this.b=xQn;break;case 3:case 1:this.a=out,this.b=DQn}}function Epn(n,t,e){var i;if(n.c)Men(n.c,n.c.i+t),Sen(n.c,n.c.j+e);else for(i=new Ub(n.b);i.a0&&(UB(n.b,new XB(t.a,e)),0<(i=t.a.length)?t.a=t.a.substr(0,0):0>i&&(t.a+=eL(L8(PNt,UVn,25,-i,15,1))))}function Spn(n,t){var e,i,r;for(e=n.o,r=_B(_B(o6(n.r,t),21),84).Kc();r.Ob();)(i=_B(r.Pb(),111)).e.a=byn(i,e.a),i.e.b=e.b*Hy(ED(i.b.We(Art)))}function Ppn(n,t){var e,i,r,c;return r=n.k,e=Hy(ED(pMn(n,(oWn(),jlt)))),c=t.k,i=Hy(ED(pMn(t,jlt))),c!=(cSn(),Eut)?-1:r!=Eut?1:e==i?0:e=0?n.hh(t,e,i):(n.eh()&&(i=(r=n.Vg())>=0?n.Qg(i):n.eh().ih(n,-1-r,null,i)),n.Sg(t,e,i))}function Lpn(n,t){switch(t){case 7:return!n.e&&(n.e=new oK(DOt,n,7,4)),void uqn(n.e);case 8:return!n.d&&(n.d=new oK(DOt,n,8,5)),void uqn(n.d)}Nwn(n,t)}function Npn(n,t){var e;e=n.Zc(t);try{return e.Pb()}catch(i){throw iL(i=hun(i),109)?Fp(new Cy("Can't get element "+t)):Fp(i)}}function xpn(n,t){this.e=n,t=0&&(e.d=n.t);break;case 3:n.t>=0&&(e.a=n.t)}n.C&&(e.b=n.C.b,e.c=n.C.c)}function Fpn(){Fpn=O,_rt=new RS(pYn,0),Krt=new RS(vYn,1),Frt=new RS(mYn,2),Brt=new RS(yYn,3),_rt.a=!1,Krt.a=!0,Frt.a=!1,Brt.a=!0}function Bpn(){Bpn=O,Jrt=new DS(pYn,0),Qrt=new DS(vYn,1),Yrt=new DS(mYn,2),Zrt=new DS(yYn,3),Jrt.a=!1,Qrt.a=!0,Yrt.a=!1,Zrt.a=!0}function Hpn(n){var t;t=n.a;do{(t=_B(G5(new az(JL(sbn(t).a.Kc(),new h))),17).c.i).k==(cSn(),Mut)&&n.b.Fc(t)}while(t.k==(cSn(),Mut));n.b=nan(n.b)}function qpn(n){var t,e,i;for(i=n.c.a,n.p=(vX(i),new ZK(i)),e=new Ub(i);e.ae.b)return!0}return!1}function Wpn(n,t){return zC(n)?!!IWn[t]:n.hm?!!n.hm[t]:GC(n)?!!PWn[t]:!!qC(n)&&!!SWn[t]}function Vpn(n,t,e){return null==e?(!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),Udn(n.o,t)):(!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),gjn(n.o,t,e)),n}function Qpn(n,t,e,i){var r;(r=zfn(t.Xe((uWn(),NSt))?_B(t.We(NSt),21):n.j))!=(bWn(),Prt)&&(e&&!rgn(r)||GSn($$n(n,r,i),t))}function Jpn(n,t,e,i){var r,c,a;return c=ttn(n.Tg(),t),(r=t-n.Ah())<0?(a=n.Yg(c))>=0?n._g(a,e,!0):iOn(n,c,e):_B(c,66).Nj().Pj(n,n.yh(),r,e,i)}function Ypn(n,t,e,i){var r,c;e.mh(t)&&(JM(),onn(t)?vgn(n,_B(e.ah(t),153)):(r=(c=t)?_B(i,49).xh(c):null)&&Rp(e.ah(t),r))}function Zpn(n){switch(n.g){case 1:return Nan(),xrt;case 3:return Nan(),$rt;case 2:return Nan(),Nrt;case 4:return Nan(),Lrt;default:return null}}function nvn(n){switch(typeof n){case $Wn:return gvn(n);case AWn:return SY(n);case OWn:return oN(),n?1231:1237;default:return null==n?0:MN(n)}}function tvn(n,t,e){if(n.e)switch(n.b){case 1:_Q(n.c,t,e);break;case 0:FQ(n.c,t,e)}else Z3(n.c,t,e);n.a[t.p][e.p]=n.c.i,n.a[e.p][t.p]=n.c.e}function evn(n){var t,e;if(null==n)return null;for(e=L8(Iut,uVn,193,n.length,0,2),t=0;t=0)return i;if(n.Fk())for(e=0;e=(r=n.gc()))throw Fp(new ZR(t,r));if(n.hi()&&(i=n.Xc(e))>=0&&i!=t)throw Fp(new Ry(r8n));return n.mi(t,e)}function uvn(n,t){if(this.a=_B(vX(n),245),this.b=_B(vX(t),245),n.vd(t)>0||n==(ny(),Dnt)||t==(Zm(),Rnt))throw Fp(new Ry("Invalid range: "+_3(n,t)))}function ovn(n){var t,e;for(this.b=new $p,this.c=n,this.a=!1,e=new Ub(n.a);e.a0),(t&-t)==t)return SY(t*F$n(n,31)*4.656612873077393e-10);do{i=(e=F$n(n,31))%t}while(e-i+(t-1)<0);return SY(i)}function gvn(n){var t,e,i;return e_(),null!=(i=eit[e=":"+n])?SY((mW(i),i)):(t=null==(i=tit[e])?QNn(n):SY((mW(i),i)),PQ(),eit[e]=t,t)}function pvn(n,t,e){ITn(e,"Compound graph preprocessor",1),n.a=new dY,$zn(n,t,null),HHn(n,t),ZLn(n),oon(t,(oWn(),Fft),n.a),n.a=null,OU(n.b),FSn(e)}function vvn(n,t,e){switch(e.g){case 1:n.a=t.a/2,n.b=0;break;case 2:n.a=t.a,n.b=t.b/2;break;case 3:n.a=t.a/2,n.b=t.b;break;case 4:n.a=0,n.b=t.b/2}}function mvn(n){var t,e,i;for(i=_B(o6(n.a,(AEn(),Mst)),15).Kc();i.Ob();)tX(n,e=_B(i.Pb(),101),(t=Fyn(e))[0],(Srn(),Lst),0),tX(n,e,t[1],xst,1)}function yvn(n){var t,e,i;for(i=_B(o6(n.a,(AEn(),Sst)),15).Kc();i.Ob();)tX(n,e=_B(i.Pb(),101),(t=Fyn(e))[0],(Srn(),Lst),0),tX(n,e,t[1],xst,1)}function kvn(n){switch(n.g){case 0:return null;case 1:return new Crn;case 2:return new Qm;default:throw Fp(new Ry(i4n+(null!=n.f?n.f:""+n.g)))}}function jvn(n,t,e){var i,r;for(pun(n,t-n.s,e-n.t),r=new Ub(n.n);r.a1&&(r=svn(n,t)),r}function Tvn(n){var t;return n.f&&n.f.kh()&&(t=_B(n.f,49),n.f=_B(Zhn(n,t),82),n.f!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,9,8,t,n.f))),n.f}function Mvn(n){var t;return n.i&&n.i.kh()&&(t=_B(n.i,49),n.i=_B(Zhn(n,t),82),n.i!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,9,7,t,n.i))),n.i}function Svn(n){var t;return n.b&&0!=(64&n.b.Db)&&(t=n.b,n.b=_B(Zhn(n,t),18),n.b!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,9,21,t,n.b))),n.b}function Pvn(n,t){var e,i,r;null==n.d?(++n.e,++n.f):(i=t.Sh(),sNn(n,n.f+1),r=(i&NWn)%n.d.length,!(e=n.d[r])&&(e=n.d[r]=n.uj()),e.Fc(t),++n.f)}function Ivn(n,t,e){var i;return!t.Kj()&&(-2!=t.Zj()?null==(i=t.zj())?null==e:$fn(i,e):t.Hj()==n.e.Tg()&&null==e)}function Cvn(){var n;hin(16,PVn),n=Qin(16),this.b=L8(Hnt,SVn,317,n,0,1),this.c=L8(Hnt,SVn,317,n,0,1),this.a=null,this.e=null,this.i=0,this.f=n-1,this.g=0}function Ovn(n){AR.call(this),this.k=(cSn(),Sut),this.j=(hin(6,CVn),new Q6(6)),this.b=(hin(2,CVn),new Q6(2)),this.d=new sm,this.f=new lm,this.a=n}function Avn(n){var t,e;n.c.length<=1||(bPn(n,_B((t=kDn(n,(mUn(),TCt))).a,19).a,_B(t.b,19).a),bPn(n,_B((e=kDn(n,SCt)).a,19).a,_B(e.b,19).a))}function $vn(){$vn=O,vvt=new KP("SIMPLE",0),dvt=new KP(_1n,1),gvt=new KP("LINEAR_SEGMENTS",2),wvt=new KP("BRANDES_KOEPF",3),pvt=new KP(y3n,4)}function Lvn(n,t,e){AK(_B(pMn(t,(FXn(),npt)),98))||(U7(n,t,NSn(t,e)),U7(n,t,NSn(t,(mUn(),TCt))),U7(n,t,NSn(t,uCt)),TQ(),p$(t.j,new Rd(n)))}function Nvn(n,t,e,i){var r;for(r=_B(o6(i?n.a:n.b,t),21).Kc();r.Ob();)if(RDn(n,e,_B(r.Pb(),33)))return!0;return!1}function xvn(n){var t,e;for(e=new CL(n);e.e!=e.i.gc();)if((t=_B(mpn(e),87)).e||0!=(!t.d&&(t.d=new OL(UAt,t,1)),t.d).i)return!0;return!1}function Dvn(n){var t,e;for(e=new CL(n);e.e!=e.i.gc();)if((t=_B(mpn(e),87)).e||0!=(!t.d&&(t.d=new OL(UAt,t,1)),t.d).i)return!0;return!1}function Rvn(n){var t,e;for(t=0,e=new Ub(n.c.a);e.a102?-1:n<=57?n-48:n<65?-1:n<=70?n-65+10:n<97?-1:n-97+10}function qvn(n,t){if(null==n)throw Fp(new Fy("null key in entry: null="+t));if(null==t)throw Fp(new Fy("null value in entry: "+n+"=null"))}function Gvn(n,t){for(var e,i;n.Ob();){if(!t.Ob())return!1;if(e=n.Pb(),i=t.Pb(),!(HC(e)===HC(i)||null!=e&&$fn(e,i)))return!1}return!t.Ob()}function zvn(n,t){var e;return e=Mun(Hk($Nt,1),BQn,25,15,[ghn(n.a[0],t),ghn(n.a[1],t),ghn(n.a[2],t)]),n.d&&(e[0]=i.Math.max(e[0],e[2]),e[2]=e[0]),e}function Uvn(n,t){var e;return e=Mun(Hk($Nt,1),BQn,25,15,[phn(n.a[0],t),phn(n.a[1],t),phn(n.a[2],t)]),n.d&&(e[0]=i.Math.max(e[0],e[2]),e[2]=e[0]),e}function Xvn(){Xvn=O,vht=new TP("GREEDY",0),pht=new TP(F1n,1),yht=new TP(_1n,2),kht=new TP("MODEL_ORDER",3),mht=new TP("GREEDY_MODEL_ORDER",4)}function Wvn(n,t){var e,i,r;for(n.b[t.g]=1,i=upn(t.d,0);i.b!=i.d.c;)r=(e=_B(f3(i),188)).c,1==n.b[r.g]?NH(n.a,e):2==n.b[r.g]?n.b[r.g]=1:Wvn(n,r)}function Vvn(n,t){var e,i,r;for(r=new Q6(t.gc()),i=t.Kc();i.Ob();)(e=_B(i.Pb(),286)).c==e.f?oPn(n,e,e.c):ePn(n,e)||(r.c[r.c.length]=e);return r}function Qvn(n,t,e){var i,r,c,a;for(a=n.r+t,n.r+=t,n.d+=e,i=e/n.n.c.length,r=0,c=new Ub(n.n);c.ac&&OX(t,c,null),t}function jmn(n,t){var e,i;if(i=n.gc(),null==t){for(e=0;e0&&(o+=r),s[h]=a,a+=u*(o+i)}function Nmn(n){var t,e,i;for(i=n.f,n.n=L8($Nt,BQn,25,i,15,1),n.d=L8($Nt,BQn,25,i,15,1),t=0;t0?n.c:0),++c;n.b=r,n.d=a}function qmn(n,t){var e,r,c,a,u;for(r=0,c=0,e=0,u=new Ub(t);u.a0?n.g:0),++e;n.c=c,n.d=r}function Gmn(n,t){var e;return e=Mun(Hk($Nt,1),BQn,25,15,[wvn(n,(Ntn(),Hit),t),wvn(n,qit,t),wvn(n,Git,t)]),n.f&&(e[0]=i.Math.max(e[0],e[2]),e[2]=e[0]),e}function zmn(n,t,e){try{KRn(n,t+n.j,e+n.k,!1,!0)}catch(i){throw iL(i=hun(i),73)?Fp(new Cy(i.g+SYn+t+KWn+e+").")):Fp(i)}}function Umn(n,t,e){try{KRn(n,t+n.j,e+n.k,!0,!1)}catch(i){throw iL(i=hun(i),73)?Fp(new Cy(i.g+SYn+t+KWn+e+").")):Fp(i)}}function Xmn(n){var t;Ax(n,(FXn(),Ogt))&&((t=_B(pMn(n,Ogt),21)).Hc((YAn(),PIt))?(t.Mc(PIt),t.Fc(CIt)):t.Hc(CIt)&&(t.Mc(CIt),t.Fc(PIt)))}function Wmn(n){var t;Ax(n,(FXn(),Ogt))&&((t=_B(pMn(n,Ogt),21)).Hc((YAn(),NIt))?(t.Mc(NIt),t.Fc($It)):t.Hc($It)&&(t.Mc($It),t.Fc(NIt)))}function Vmn(n,t,e){ITn(e,"Self-Loop ordering",1),QT(OV(CV(CV(lnn(new xq(null,new l1(t.b,16)),new Ci),new Oi),new Ai),new $i),new fd(n)),FSn(e)}function Qmn(n,t,e,i){var r,c;for(r=t;r0&&(c.b+=t),c}function cyn(n,t){var e,r,c;for(c=new Hj,r=n.Kc();r.Ob();)JRn(e=_B(r.Pb(),37),0,c.b),c.b+=e.f.b+t,c.a=i.Math.max(c.a,e.f.a);return c.a>0&&(c.a+=t),c}function ayn(n){var t,e,r;for(r=NWn,e=new Ub(n.a);e.a>16==6?n.Cb.ih(n,5,BOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||n.zh(),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function hyn(n){MJ();var t=n.e;if(t&&t.stack){var e=t.stack,i=t+"\n";return e.substring(0,i.length)==i&&(e=e.substring(i.length)),e.split("\n")}return[]}function fyn(n){var t;return Ein(),(t=Itt)[n>>>28]|t[n>>24&15]<<4|t[n>>20&15]<<8|t[n>>16&15]<<12|t[n>>12&15]<<16|t[n>>8&15]<<20|t[n>>4&15]<<24|t[15&n]<<28}function lyn(n){var t,e,r;n.b==n.c&&(r=n.a.length,e=mon(i.Math.max(8,r))<<1,0!=n.b?(crn(n,t=TR(n.a,e),r),n.a=t,n.b=0):Mv(n.a,e),n.c=r)}function byn(n,t){var e;return(e=n.b).Xe((uWn(),rPt))?e.Hf()==(mUn(),SCt)?-e.rf().a-Hy(ED(e.We(rPt))):t+Hy(ED(e.We(rPt))):e.Hf()==(mUn(),SCt)?-e.rf().a:t}function wyn(n){var t;return 0!=n.b.c.length&&_B(Lq(n.b,0),70).a?_B(Lq(n.b,0),70).a:null!=(t=nQ(n))?t:""+(n.c?k7(n.c.a,n,0):-1)}function dyn(n){var t;return 0!=n.f.c.length&&_B(Lq(n.f,0),70).a?_B(Lq(n.f,0),70).a:null!=(t=nQ(n))?t:""+(n.i?k7(n.i.j,n,0):-1)}function gyn(n,t){var e,i;if(t<0||t>=n.gc())return null;for(e=t;e0?n.c:0),c=i.Math.max(c,t.d),++r;n.e=a,n.b=c}function myn(n){var t,e;if(!n.b)for(n.b=S2(_B(n.f,118).Ag().i),e=new CL(_B(n.f,118).Ag());e.e!=e.i.gc();)t=_B(mpn(e),137),UB(n.b,new xy(t));return n.b}function yyn(n,t){var e,i,r;if(t.dc())return bD(),bD(),wAt;for(e=new rR(n,t.gc()),r=new CL(n);r.e!=r.i.gc();)i=mpn(r),t.Hc(i)&&s9(e,i);return e}function kyn(n,t,e,i){return 0==t?i?(!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),n.o):(!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),C8(n.o)):Jpn(n,t,e,i)}function jyn(n){var t,e;if(n.rb)for(t=0,e=n.rb.i;t>22))>>22)<0||(n.l=e&TQn,n.m=i&TQn,n.h=r&MQn,0)))}function Pyn(n,t,e,i,r,c,a){var u,o;return!(t.Ae()&&(o=n.a.ue(e,i),o<0||!r&&0==o)||t.Be()&&(u=n.a.ue(e,c),u>0||!a&&0==u))}function Iyn(n,t){if(qsn(),0!=n.j.g-t.j.g)return 0;switch(n.j.g){case 2:return ybn(t,fst)-ybn(n,fst);case 4:return ybn(n,hst)-ybn(t,hst)}return 0}function Cyn(n){switch(n.g){case 0:return Lht;case 1:return Nht;case 2:return xht;case 3:return Dht;case 4:return Rht;case 5:return Kht;default:return null}}function Oyn(n,t,e){var i,r;return Phn(r=new Am,t),$rn(r,e),s9((!n.c&&(n.c=new nU(WAt,n,12,10)),n.c),r),Aen(i=r,0),$en(i,1),Yfn(i,!0),Vfn(i,!0),i}function Ayn(n,t){var e,i;if(t>=n.i)throw Fp(new AO(t,n.i));return++n.j,e=n.g[t],(i=n.i-t-1)>0&&rHn(n.g,t+1,n.g,t,i),OX(n.g,--n.i,null),n.fi(t,e),n.ci(),e}function $yn(n,t){var e;return n.Db>>16==17?n.Cb.ih(n,21,FAt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||n.zh(),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Lyn(n){var t,e,i;for(TQ(),p$(n.c,n.a),i=new Ub(n.c);i.ae.a.c.length))throw Fp(new Ry("index must be >= 0 and <= layer node count"));n.c&&v7(n.c.a,n),n.c=e,e&&mG(e.a,t,n)}function Vyn(n,t){var e,i,r;for(i=new az(JL(obn(n).a.Kc(),new h));bAn(i);)return e=_B(G5(i),17),new Bf(vX((r=_B(t.Kb(e),10)).n.b+r.o.b/2));return ty(),ty(),Int}function Qyn(n,t){this.c=new Lp,this.a=n,this.b=t,this.d=_B(pMn(n,(oWn(),Clt)),304),HC(pMn(n,(FXn(),Agt)))===HC((w7(),Bht))?this.e=new wm:this.e=new bm}function Jyn(n,t){var e,r,c;for(c=0,r=new Ub(n);r.a>16==6?n.Cb.ih(n,6,DOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(SXn(),vOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function okn(n,t){var e;return n.Db>>16==7?n.Cb.ih(n,1,LOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(SXn(),yOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function skn(n,t){var e;return n.Db>>16==9?n.Cb.ih(n,9,qOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(SXn(),jOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function hkn(n,t){var e;return n.Db>>16==5?n.Cb.ih(n,9,GAt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(wWn(),a$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function fkn(n,t){var e;return n.Db>>16==3?n.Cb.ih(n,0,KOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(wWn(),ZAt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function lkn(n,t){var e;return n.Db>>16==7?n.Cb.ih(n,6,BOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(wWn(),d$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function bkn(){this.a=new lo,this.g=new Cvn,this.j=new Cvn,this.b=new Lp,this.d=new Cvn,this.i=new Cvn,this.k=new Lp,this.c=new Lp,this.e=new Lp,this.f=new Lp}function wkn(n,t,e){var i,r,c;for(e<0&&(e=0),c=n.i,r=e;rHQn)return gkn(n,i);if(i==n)return!0}}return!1}function pkn(n){switch(NN(),n.q.g){case 5:gCn(n,(mUn(),uCt)),gCn(n,TCt);break;case 4:q$n(n,(mUn(),uCt)),q$n(n,TCt);break;default:gUn(n,(mUn(),uCt)),gUn(n,TCt)}}function vkn(n){switch(NN(),n.q.g){case 5:TOn(n,(mUn(),aCt)),TOn(n,SCt);break;case 4:Spn(n,(mUn(),aCt)),Spn(n,SCt);break;default:pUn(n,(mUn(),aCt)),pUn(n,SCt)}}function mkn(n){var t,e;(t=_B(pMn(n,(sRn(),Yct)),19))?(e=t.a,oon(n,(Ern(),oat),0==e?new ubn:new S4(e))):oon(n,(Ern(),oat),new S4(1))}function ykn(n,t){var e;switch(e=n.i,t.g){case 1:return-(n.n.b+n.o.b);case 2:return n.n.a-e.o.a;case 3:return n.n.b-e.o.b;case 4:return-(n.n.a+n.o.a)}return 0}function kkn(n,t){switch(n.g){case 0:return t==(jbn(),Klt)?est:ist;case 1:return t==(jbn(),Klt)?est:tst;case 2:return t==(jbn(),Klt)?tst:ist;default:return tst}}function jkn(n,t){var e,r,c;for(v7(n.a,t),n.e-=t.r+(0==n.a.c.length?0:n.c),c=Y3n,r=new Ub(n.a);r.a>16==3?n.Cb.ih(n,12,qOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(SXn(),pOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Tkn(n,t){var e;return n.Db>>16==11?n.Cb.ih(n,10,qOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(SXn(),kOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Mkn(n,t){var e;return n.Db>>16==10?n.Cb.ih(n,11,FAt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(wWn(),b$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Skn(n,t){var e;return n.Db>>16==10?n.Cb.ih(n,12,XAt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(wWn(),g$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Pkn(n){var t;return 0==(1&n.Bb)&&n.r&&n.r.kh()&&(t=_B(n.r,49),n.r=_B(Zhn(n,t),138),n.r!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,9,8,t,n.r))),n.r}function Ikn(n,t,e){var r;return r=Mun(Hk($Nt,1),BQn,25,15,[tMn(n,(Ntn(),Hit),t,e),tMn(n,qit,t,e),tMn(n,Git,t,e)]),n.f&&(r[0]=i.Math.max(r[0],r[2]),r[2]=r[0]),r}function Ckn(n,t){var e,i,r;if(0!=(r=Vvn(n,t)).c.length)for(p$(r,new ti),e=r.c.length,i=0;i>19)!=(u=t.h>>19)?u-a:(i=n.h)!=(c=t.h)?i-c:(e=n.m)!=(r=t.m)?e-r:n.l-t.l}function Rkn(){Rkn=O,ZDn(),Mit=new OO(GJn,Sit=Lit),xnn(),Eit=new OO(zJn,Tit=pit),opn(),kit=new OO(UJn,jit=bit),yit=new OO(XJn,(oN(),!0))}function Kkn(n,t,e){var i,r;i=t*e,iL(n.g,145)?(r=s3(n)).f.d?r.f.a||(n.d.a+=i+sYn):(n.d.d-=i+sYn,n.d.a+=i+sYn):iL(n.g,10)&&(n.d.d-=i,n.d.a+=2*i)}function _kn(n,t,e){var r,c,a,u,o;for(c=n[e.g],o=new Ub(t.d);o.a0?n.g:0),++e;t.b=r,t.e=c}function Bkn(n){var t,e,i;if(i=n.b,BT(n.i,i.length)){for(e=2*i.length,n.b=L8(Hnt,SVn,317,e,0,1),n.c=L8(Hnt,SVn,317,e,0,1),n.f=e-1,n.i=0,t=n.a;t;t=t.c)VIn(n,t,t);++n.g}}function Hkn(n,t,e,i){var r,c,a,u;for(r=0;ru&&(o=u/r),(c=i.Math.abs(n.b))>a&&(s=a/c),mL(n,i.Math.min(o,s)),n}function zkn(){var n,t;BBn();try{if(t=_B(zjn((UM(),HAt),v6n),2014))return t}catch(e){if(!iL(e=hun(e),102))throw Fp(e);n=e,cz((c$(),n))}return new ao}function Ukn(){var n,t;b7();try{if(t=_B(zjn((UM(),HAt),T7n),2024))return t}catch(e){if(!iL(e=hun(e),102))throw Fp(e);n=e,cz((c$(),n))}return new Ds}function Xkn(){var n,t;BBn();try{if(t=_B(zjn((UM(),HAt),X9n),1941))return t}catch(e){if(!iL(e=hun(e),102))throw Fp(e);n=e,cz((c$(),n))}return new qo}function Wkn(n,t,e){var i,r;return r=n.e,n.e=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new Yz(n,1,4,r,t),e?e.Ei(i):e=i),r!=t&&(e=rzn(n,t?mLn(n,t):n.a,e)),e}function Vkn(){CT.call(this),this.e=-1,this.a=!1,this.p=RVn,this.k=-1,this.c=-1,this.b=-1,this.g=!1,this.f=-1,this.j=-1,this.n=-1,this.i=-1,this.d=-1,this.o=RVn}function Qkn(n,t){var e,i,r;if(i=n.b.d.d,n.a||(i+=n.b.d.a),r=t.b.d.d,t.a||(r+=t.b.d.a),0==(e=Mln(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function Jkn(n,t){var e,i,r;if(i=n.b.b.d,n.a||(i+=n.b.b.a),r=t.b.b.d,t.a||(r+=t.b.b.a),0==(e=Mln(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function Ykn(n,t){var e,i,r;if(i=n.b.g.d,n.a||(i+=n.b.g.a),r=t.b.g.d,t.a||(r+=t.b.g.a),0==(e=Mln(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function Zkn(){Zkn=O,$at=UG(bq(bq(bq(new _2,(vMn(),Kat),(hWn(),vot)),Kat,jot),_at,Cot),_at,aot),Nat=bq(bq(new _2,Kat,Qut),Kat,uot),Lat=UG(new _2,_at,sot)}function njn(n){var t,e,i,r,c;for(t=_B(pMn(n,(oWn(),qft)),83),c=n.n,i=t.Cc().Kc();i.Ob();)(r=(e=_B(i.Pb(),306)).i).c+=c.a,r.d+=c.b,e.c?$Dn(e):LDn(e);oon(n,qft,null)}function tjn(n,t,e){var i,r;switch(i=(r=n.b).d,t.g){case 1:return-i.d-e;case 2:return r.o.a+i.c+e;case 3:return r.o.b+i.a+e;case 4:return-i.b-e;default:return-1}}function ejn(n){var t,e,i,r,c;if(i=0,r=JYn,n.b)for(t=0;t<360;t++)e=.017453292519943295*t,GKn(n,n.d,0,0,J3n,e),(c=n.b.ig(n.d))0&&(r=rOn(n,(c&NWn)%n.d.length,c,t))?r.ed(e):(i=n.tj(c,t,e),n.c.Fc(i),null)}function pjn(n,t){var e,i,r,c;switch(Sfn(n,t)._k()){case 3:case 2:for(r=0,c=(e=VBn(t)).i;r=0;r--)if(pK(n[r].d,t)||pK(n[r].d,e)){n.length>=r+1&&n.splice(0,r+1);break}return n}function Ijn(n,t){var e;return QO(n)&&QO(t)&&OQn<(e=n/t)&&e0&&(n.b+=2,n.a+=r):(n.b+=1,n.a+=i.Math.min(r,c))}function Djn(n,t){var e;if(e=!1,zC(t)&&(e=!0,YX(n,new HX(TD(t)))),e||iL(t,236)&&(e=!0,YX(n,new Tl(zK(_B(t,236))))),!e)throw Fp(new Ay(F6n))}function Rjn(n,t,e,i){var r,c,a;return r=new $7(n.e,1,10,iL(a=t.c,88)?_B(a,26):(wWn(),l$t),iL(c=e.c,88)?_B(c,26):(wWn(),l$t),cvn(n,t),!1),i?i.Ei(r):i=r,i}function Kjn(n){var t,e;switch(_B(pMn(gW(n),(FXn(),dgt)),420).g){case 0:return t=n.n,e=n.o,new LI(t.a+e.a/2,t.b+e.b/2);case 1:return new lA(n.n);default:return null}}function _jn(){_jn=O,Wht=new CP(WZn,0),Xht=new CP("LEFTUP",1),Qht=new CP("RIGHTUP",2),Uht=new CP("LEFTDOWN",3),Vht=new CP("RIGHTDOWN",4),zht=new CP("BALANCED",5)}function Fjn(n,t,e){var i,r,c;if(0==(i=Mln(n.a[t.p],n.a[e.p]))){if(r=_B(pMn(t,(oWn(),ilt)),15),c=_B(pMn(e,ilt),15),r.Hc(e))return-1;if(c.Hc(t))return 1}return i}function Bjn(n){switch(n.g){case 1:return new _a;case 2:return new Fa;case 3:return new Ka;case 0:return null;default:throw Fp(new Ry(i4n+(null!=n.f?n.f:""+n.g)))}}function Hjn(n,t,e){switch(t){case 1:return!n.n&&(n.n=new nU(HOt,n,1,7)),uqn(n.n),!n.n&&(n.n=new nU(HOt,n,1,7)),void dX(n.n,_B(e,14));case 2:return void Oin(n,TD(e))}esn(n,t,e)}function qjn(n,t,e){switch(t){case 3:return void Een(n,Hy(ED(e)));case 4:return void Ten(n,Hy(ED(e)));case 5:return void Men(n,Hy(ED(e)));case 6:return void Sen(n,Hy(ED(e)))}Hjn(n,t,e)}function Gjn(n,t,e){var i,r;(i=FTn(r=new Am,t,null))&&i.Fi(),$rn(r,e),s9((!n.c&&(n.c=new nU(WAt,n,12,10)),n.c),r),Aen(r,0),$en(r,1),Yfn(r,!0),Vfn(r,!0)}function zjn(n,t){var e,i;return iL(e=oS(n.g,t),235)?((i=_B(e,235)).Qh(),i.Nh()):iL(e,498)?i=_B(e,1938).b:null}function Ujn(n,t,e,i){var r,c;return vX(t),vX(e),x7(!!(c=_B(GK(n.d,t),19)),"Row %s not in %s",t,n.e),x7(!!(r=_B(GK(n.b,e),19)),"Column %s not in %s",e,n.c),Tun(n,c.a,r.a,i)}function Xjn(n,t,e,i,r,c,a){var u,o,s,h,f;if(f=_mn(u=(s=c==a-1)?i:0,h=r[c]),10!=i&&Mun(Hk(n,a-c),t[c],e[c],u,f),!s)for(++c,o=0;o1||-1==u?(c=_B(o,15),r.Wb(zdn(n,c))):r.Wb(ZKn(n,_B(o,56))))}function oEn(n,t,e,i){VE();var r=MWn;function c(){for(var n=0;nN3n)return e;i>-1e-6&&++e}return e}function mEn(n,t){var e;t!=n.b?(e=null,n.b&&(e=aY(n.b,n,-4,e)),t&&(e=$pn(t,n,-4,e)),(e=Jhn(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,3,t,t))}function yEn(n,t){var e;t!=n.f?(e=null,n.f&&(e=aY(n.f,n,-1,e)),t&&(e=$pn(t,n,-1,e)),(e=Yhn(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,0,t,t))}function kEn(n){var t,e,i;if(null==n)return null;if((e=_B(n,15)).dc())return"";for(i=new Tk,t=e.Kc();t.Ob();)iO(i,(Gqn(),TD(t.Pb()))),i.a+=" ";return DO(i,i.a.length-1)}function jEn(n){var t,e,i;if(null==n)return null;if((e=_B(n,15)).dc())return"";for(i=new Tk,t=e.Kc();t.Ob();)iO(i,(Gqn(),TD(t.Pb()))),i.a+=" ";return DO(i,i.a.length-1)}function EEn(n,t,e){var i,r;return i=n.c[t.c.p][t.p],r=n.c[e.c.p][e.p],null!=i.a&&null!=r.a?jz(i.a,r.a):null!=i.a?-1:null!=r.a?1:0}function TEn(n,t){var e,i,r;if(t)for(r=((e=new oz(t.a.length)).b-e.a)*e.c<0?(nS(),jNt):new zL(e);r.Ob();)i=L2(t,_B(r.Pb(),19).a),IV(new _g(n).a,i)}function MEn(n,t){var e,i,r;if(t)for(r=((e=new oz(t.a.length)).b-e.a)*e.c<0?(nS(),jNt):new zL(e);r.Ob();)i=L2(t,_B(r.Pb(),19).a),PV(new Og(n).a,i)}function SEn(n){if(null!=n&&n.length>0&&33==sV(n,n.length-1))try{return null==VPn(sx(n,0,n.length-1)).e}catch(t){if(!iL(t=hun(t),32))throw Fp(t)}return!1}function PEn(n,t,e){var i,r,c;return i=t.ak(),c=t.dd(),r=i.$j()?AJ(n,3,i,null,c,dBn(n,i,c,iL(i,99)&&0!=(_B(i,18).Bb&_Qn)),!0):AJ(n,1,i,i.zj(),c,-1,!0),e?e.Ei(r):e=r,e}function IEn(){var n,t,e;for(t=0,n=0;n<"X".length;n++){if(0==(e=WOn((f1(n,"X".length),"X".charCodeAt(n)))))throw Fp(new rk("Unknown Option: "+"X".substr(n)));t|=e}return t}function CEn(n,t,e){var i,r;switch(i=Uln(gW(t)),SZ(r=new SSn,t),e.g){case 1:BIn(r,jln(own(i)));break;case 2:BIn(r,own(i))}return oon(r,(FXn(),Zgt),ED(pMn(n,Zgt))),r}function OEn(n){var t,e;return t=_B(G5(new az(JL(sbn(n.a).a.Kc(),new h))),17),e=_B(G5(new az(JL(hbn(n.a).a.Kc(),new h))),17),By(jD(pMn(t,(oWn(),Slt))))||By(jD(pMn(e,Slt)))}function AEn(){AEn=O,Est=new vP("ONE_SIDE",0),Mst=new vP("TWO_SIDES_CORNER",1),Sst=new vP("TWO_SIDES_OPPOSING",2),Tst=new vP("THREE_SIDES",3),jst=new vP("FOUR_SIDES",4)}function $En(n,t,e,i,r){var c,a;c=_B(M4(CV(t.Oc(),new Zr),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),Get)]))),15),a=_B(wan(n.b,e,i),15),0==r?a.Wc(0,c):a.Gc(c)}function LEn(n,t){var e,i,r;for(i=new Ub(t.a);i.a0&&Ryn(this,this.c-1,(mUn(),aCt)),this.c0&&n[0].length>0&&(this.c=By(jD(pMn(gW(n[0][0]),(oWn(),rlt))))),this.a=L8(Mmt,uVn,2018,n.length,0,2),this.b=L8(Amt,uVn,2019,n.length,0,2),this.d=new jhn}function zEn(n){return 0!=n.c.length&&((h1(0,n.c.length),_B(n.c[0],17)).c.i.k==(cSn(),Mut)||a5(OV(new xq(null,new l1(n,16)),new Kc),new _c))}function UEn(n,t,e){return ITn(e,"Tree layout",1),o2(n.b),SU(n.b,(qyn(),xyt),xyt),SU(n.b,Dyt,Dyt),SU(n.b,Ryt,Ryt),SU(n.b,Kyt,Kyt),n.a=Oqn(n.b,t),hxn(n,t,pcn(e,1)),FSn(e),t}function XEn(n,t){var e,r,c,a,u,o;for(u=lDn(t),c=t.f,o=t.g,a=i.Math.sqrt(c*c+o*o),r=0,e=new Ub(u);e.a=0?(e=Ijn(n,CQn),i=hdn(n,CQn)):(e=Ijn(t=yz(n,1),5e8),i=ebn(vz(i=hdn(t,5e8),1),n0(n,1))),t0(vz(i,32),n0(e,GQn))}function hTn(n,t,e){var i;switch(Mx(0!=t.b),i=_B(Ctn(t,t.a.a),8),e.g){case 0:i.b=0;break;case 2:i.b=n.f;break;case 3:i.a=0;break;default:i.a=n.g}return YU(upn(t,0),i),t}function fTn(n,t,e,i){var r,c,a,u,o;switch(o=n.b,u=qgn(a=(c=t.d).j,o.d[a.g],e),r=GR(_$(c.n),c.a),c.j.g){case 1:case 3:u.a+=r.a;break;case 2:case 4:u.b+=r.b}e5(i,u,i.c.b,i.c)}function lTn(n,t,e){var i,r,c,a;for(a=k7(n.e,t,0),(c=new em).b=e,i=new E2(n.e,a);i.b1;t>>=1)0!=(1&t)&&(i=$nn(i,e)),e=1==e.d?$nn(e,e):new Sgn(P_n(e.a,e.d,L8(INt,oQn,25,e.d<<1,15,1)));return i=$nn(i,e)}function vTn(){var n,t,e,i;for(vTn=O,Iet=L8($Nt,BQn,25,25,15,1),Cet=L8($Nt,BQn,25,33,15,1),i=152587890625e-16,t=32;t>=0;t--)Cet[t]=i,i*=.5;for(e=1,n=24;n>=0;n--)Iet[n]=e,e*=.5}function mTn(n){var t,e;if(By(jD(JAn(n,(FXn(),lgt)))))for(e=new az(JL(bLn(n).a.Kc(),new h));bAn(e);)if(WCn(t=_B(G5(e),79))&&By(jD(JAn(t,bgt))))return!0;return!1}function yTn(n,t){var e,i,r;jU(n.f,t)&&(t.b=n,i=t.c,-1!=k7(n.j,i,0)||UB(n.j,i),r=t.d,-1!=k7(n.j,r,0)||UB(n.j,r),0!=(e=t.a.b).c.length&&(!n.i&&(n.i=new npn(n)),gan(n.i,e)))}function kTn(n){var t,e,i,r;return(e=(t=n.c.d).j)==(r=(i=n.d.d).j)?t.p=0&&pK(n.substr(t,"GMT".length),"GMT")||t>=0&&pK(n.substr(t,"UTC".length),"UTC")?(e[0]=t+3,v_n(n,e,i)):v_n(n,e,i)}function PTn(n,t){var e,i,r,c,a;for(c=n.g.a,a=n.g.b,i=new Ub(n.d);i.ae;c--)n[c]|=t[c-e-1]>>>a,n[c-1]=t[c-e-1]<=n.f)break;c.c[c.c.length]=e}return c}function RTn(n){var t,e,i,r;for(t=null,r=new Ub(n.wf());r.a0&&rHn(n.g,t,n.g,t+i,u),a=e.Kc(),n.i+=i,r=0;rc&&uU(s,rtn(e[u],jet))&&(r=u,c=o);return r>=0&&(i[0]=t+c),r}function GTn(n,t){var e;if(0!=(e=VO(n.b.Hf(),t.b.Hf())))return e;switch(n.b.Hf().g){case 1:case 2:return k$(n.b.sf(),t.b.sf());case 3:case 4:return k$(t.b.sf(),n.b.sf())}return 0}function zTn(n){var t,e,i;for(i=n.e.c.length,n.a=mq(INt,[uVn,oQn],[48,25],15,[i,i],2),e=new Ub(n.c);e.a>4&15,c=15&n[i],a[r++]=IOt[e],a[r++]=IOt[c];return _dn(a,0,a.length)}function WTn(n,t,e){var i,r,c;return i=t.ak(),c=t.dd(),r=i.$j()?AJ(n,4,i,c,null,dBn(n,i,c,iL(i,99)&&0!=(_B(i,18).Bb&_Qn)),!0):AJ(n,i.Kj()?2:1,i,c,i.zj(),-1,!0),e?e.Ei(r):e=r,e}function VTn(n){var t,e;return n>=_Qn?(t=FQn+(n-_Qn>>10&1023)&WVn,e=56320+(n-_Qn&1023)&WVn,String.fromCharCode(t)+""+String.fromCharCode(e)):String.fromCharCode(n&WVn)}function QTn(n,t){var e,i,r,c;return BD(),(r=_B(_B(o6(n.r,t),21),84)).gc()>=2&&(i=_B(r.Kc().Pb(),111),e=n.u.Hc((hCn(),ZIt)),c=n.u.Hc(iCt),!i.a&&!e&&(2==r.gc()||c))}function JTn(n,t,e,i,r){var c,a,u;for(c=nDn(n,t,e,i,r),u=!1;!c;)k$n(n,r,!0),u=!0,c=nDn(n,t,e,i,r);u&&k$n(n,r,!1),0!=(a=Nun(r)).c.length&&(n.d&&n.d.lg(a),JTn(n,r,e,i,a))}function YTn(){YTn=O,rIt=new _I(WZn,0),eIt=new _I("DIRECTED",1),cIt=new _I("UNDIRECTED",2),nIt=new _I("ASSOCIATION",3),iIt=new _I("GENERALIZATION",4),tIt=new _I("DEPENDENCY",5)}function ZTn(n,t){var e;if(!UY(n))throw Fp(new Ky(K5n));switch(e=UY(n),t.g){case 1:return-(n.j+n.f);case 2:return n.i-e.g;case 3:return n.j-e.f;case 4:return-(n.i+n.g)}return 0}function nMn(n,t){var e,i;for(mW(t),i=n.b.c.length,UB(n.b,t);i>0;){if(e=i,i=(i-1)/2|0,n.a.ue(Lq(n.b,i),t)<=0)return i5(n.b,e,t),!0;i5(n.b,e,Lq(n.b,i))}return i5(n.b,i,t),!0}function tMn(n,t,e,r){var c,a;if(c=0,e)c=phn(n.a[e.g][t.g],r);else for(a=0;a=a)}function iMn(n,t,e,i){var r;if(r=!1,zC(i)&&(r=!0,CH(t,e,TD(i))),r||qC(i)&&(r=!0,iMn(n,t,e,i)),r||iL(i,236)&&(r=!0,BQ(t,e,_B(i,236))),!r)throw Fp(new Ay(F6n))}function rMn(n,t){var e,i,r;if((e=t.Hh(n.a))&&null!=(r=idn((!e.b&&(e.b=new Qx((wWn(),v$t),G$t,e)),e.b),K9n)))for(i=1;i<(PPn(),W$t).length;++i)if(pK(W$t[i],r))return i;return 0}function cMn(n,t){var e,i,r;if((e=t.Hh(n.a))&&null!=(r=idn((!e.b&&(e.b=new Qx((wWn(),v$t),G$t,e)),e.b),K9n)))for(i=1;i<(PPn(),V$t).length;++i)if(pK(V$t[i],r))return i;return 0}function aMn(n,t){var e,i,r,c;if(mW(t),(c=n.a.gc())0?1:0;c.a[r]!=e;)c=c.a[r],r=n.a.ue(e.d,c.d)>0?1:0;c.a[r]=i,i.b=e.b,i.a[0]=e.a[0],i.a[1]=e.a[1],e.a[0]=null,e.a[1]=null}function lMn(n){return hCn(),!(San(IY(kG(nCt,Mun(Hk(PCt,1),OVn,273,0,[eCt])),n))>1||San(IY(kG(ZIt,Mun(Hk(PCt,1),OVn,273,0,[YIt,iCt])),n))>1)}function bMn(n,t){iL(TY((UM(),HAt),n),498)?pZ(HAt,n,new IC(this,t)):pZ(HAt,n,this),tSn(this,t),t==(tE(),JAt)?(this.wb=_B(this,1939),_B(t,1941)):this.wb=(WX(),YAt)}function wMn(n){var t,e;if(null==n)return null;for(t=null,e=0;e=XVn?"error":i>=900?"warn":i>=800?"info":"log",n.a),n.b&&LNn(t,e,n.b,"Exception: ",!0))}function pMn(n,t){var e,i;return!n.q&&(n.q=new Lp),null!=(i=xX(n.q,t))?i:(iL(e=t.wg(),4)&&(null==e?(!n.q&&(n.q=new Lp),g6(n.q,t)):(!n.q&&(n.q=new Lp),XW(n.q,t,e))),e)}function vMn(){vMn=O,xat=new XS("P1_CYCLE_BREAKING",0),Dat=new XS("P2_LAYERING",1),Rat=new XS("P3_NODE_ORDERING",2),Kat=new XS("P4_NODE_PLACEMENT",3),_at=new XS("P5_EDGE_ROUTING",4)}function mMn(n,t){var e,i,r,c;for(i=(1==t?Uat:zat).a.ec().Kc();i.Ob();)for(e=_B(i.Pb(),103),c=_B(o6(n.f.c,e),21).Kc();c.Ob();)r=_B(c.Pb(),46),v7(n.b.b,r.b),v7(n.b.a,_B(r.b,81).d)}function yMn(n,t){var e;if(Nnn(),n.c==t.c){if(n.b==t.b||ocn(n.b,t.b)){if(e=JO(n.b)?1:-1,n.a&&!t.a)return e;if(!n.a&&t.a)return-e}return k$(n.b.g,t.b.g)}return Mln(n.c,t.c)}function kMn(n,t){var e;ITn(t,"Hierarchical port position processing",1),(e=n.b).c.length>0&&t_n((h1(0,e.c.length),_B(e.c[0],29)),n),e.c.length>1&&t_n(_B(Lq(e,e.c.length-1),29),n),FSn(t)}function jMn(n,t){var e,i;if($Mn(n,t))return!0;for(i=new Ub(t);i.a=(r=n.Vi())||t<0)throw Fp(new Cy(c8n+t+a8n+r));if(e>=r||e<0)throw Fp(new Cy(u8n+e+a8n+r));return t!=e?(c=n.Ti(e),n.Hi(t,c),i=c):i=n.Oi(e),i}function OMn(n){var t,e,i;if(i=n,n)for(t=0,e=n.Ug();e;e=e.Ug()){if(++t>HQn)return OMn(e);if(i=e,e==n)throw Fp(new Ky("There is a cycle in the containment hierarchy of "+n))}return i}function AMn(n){var t,e,i;for(i=new Oan(KWn,"[","]"),e=n.Kc();e.Ob();)f6(i,HC(t=e.Pb())===HC(n)?"(this Collection)":null==t?qWn:_bn(t));return i.a?0==i.e.length?i.a.a:i.a.a+""+i.e:i.c}function $Mn(n,t){var e,i;if(i=!1,t.gc()<2)return!1;for(e=0;ei&&(f1(t-1,n.length),n.charCodeAt(t-1)<=32);)--t;return i>0||t1&&(n.j.b+=n.e)):(n.j.a+=e.a,n.j.b=i.Math.max(n.j.b,e.b),n.d.c.length>1&&(n.j.a+=n.e))}function RMn(){RMn=O,Ost=Mun(Hk(KCt,1),VZn,61,0,[(mUn(),uCt),aCt,TCt]),Cst=Mun(Hk(KCt,1),VZn,61,0,[aCt,TCt,SCt]),Ast=Mun(Hk(KCt,1),VZn,61,0,[TCt,SCt,uCt]),$st=Mun(Hk(KCt,1),VZn,61,0,[SCt,uCt,aCt])}function KMn(n,t,e,i){var r,c,a,u,o;if(c=n.c.d,a=n.d.d,c.j!=a.j)for(o=n.b,r=c.j,u=null;r!=a.j;)u=0==t?Eln(r):kln(r),NH(i,GR(qgn(r,o.d[r.g],e),qgn(u,o.d[u.g],e))),r=u}function _Mn(n,t,e,i){var r,c,a,u,o;return u=_B((a=Byn(n.a,t,e)).a,19).a,c=_B(a.b,19).a,i&&(o=_B(pMn(t,(oWn(),klt)),10),r=_B(pMn(e,klt),10),o&&r&&(Z3(n.b,o,r),u+=n.b.i,c+=n.b.e)),u>c}function FMn(n){var t,e,i,r,c,a,u,o;for(this.a=evn(n),this.b=new $p,i=0,r=(e=n).length;iKD(n.d).c?(n.i+=n.g.c,wdn(n.d)):KD(n.d).c>KD(n.g).c?(n.e+=n.d.c,wdn(n.g)):(n.i+=Bq(n.g),n.e+=Bq(n.d),wdn(n.g),wdn(n.d))}function GMn(n,t,e){var i,r,c,a;for(c=t.q,a=t.r,new qZ((I6(),jyt),t,c,1),new qZ(jyt,c,a,1),r=new Ub(e);r.ao&&(s=o/r),(c=i.Math.abs(t.b-n.b))>a&&(h=a/c),u=i.Math.min(s,h),n.a+=u*(t.a-n.a),n.b+=u*(t.b-n.b)}function YMn(n,t,e,i,r){var c,a;for(a=!1,c=_B(Lq(e.b,0),33);oBn(n,t,c,i,r)&&(a=!0,iEn(e,c),0!=e.b.c.length);)c=_B(Lq(e.b,0),33);return 0==e.b.c.length&&jkn(e.j,e),a&&Hmn(t.q),a}function ZMn(n,t){var e,i,r,c;if(yDn(),t.b<2)return!1;for(i=e=_B(f3(c=upn(t,0)),8);c.b!=c.d.c;){if(iNn(n,i,r=_B(f3(c),8)))return!0;i=r}return!!iNn(n,i,e)}function nSn(n,t,e,i){return 0==e?(!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),_K(n.o,t,i)):_B(ttn(_B(van(n,16),26)||n.zh(),e),66).Nj().Rj(n,sgn(n),e-fX(n.zh()),t,i)}function tSn(n,t){var e;t!=n.sb?(e=null,n.sb&&(e=_B(n.sb,49).ih(n,1,_Ot,e)),t&&(e=_B(t,49).gh(n,1,_Ot,e)),(e=yfn(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,4,t,t))}function eSn(n,t){var e,i;if(!t)throw Fp(new nk("All edge sections need an end point."));e=xen(t,"x"),jen(new Dg(n).a,(mW(e),e)),i=xen(t,"y"),Ien(new Rg(n).a,(mW(i),i))}function iSn(n,t){var e,i;if(!t)throw Fp(new nk("All edge sections need a start point."));e=xen(t,"x"),Pen(new Lg(n).a,(mW(e),e)),i=xen(t,"y"),Cen(new Ng(n).a,(mW(i),i))}function rSn(n,t){var e,i,r,c,a;for(i=0,c=dsn(n).length;i>22-t,r=n.h<>22-t):t<44?(e=0,i=n.l<>44-t):(e=0,i=0,r=n.l<n)throw Fp(new Ry("k must be smaller than n"));return 0==t||t==n?1:0==n?0:Ejn(n)/(Ejn(t)*Ejn(n-t))}function gSn(n,t){var e,i,r,c;for(e=new IA(n);null!=e.g||e.c?null==e.g||0!=e.i&&_B(e.g[e.i-1],47).Ob():ZY(e);)if(iL(c=_B(rLn(e),56),160))for(i=_B(c,160),r=0;r>4],t[2*e+1]=WLt[15&r];return _dn(t,0,t.length)}function $Sn(n){var t;switch(YW(),n.c.length){case 0:return _nt;case 1:return PH((t=_B(QIn(new Ub(n)),42)).cd(),t.dd());default:return new oy(_B(Wgn(n,L8(Fnt,mVn,42,n.c.length,0,1)),165))}}function LSn(n){var t,e,i,r,c;for(t=new Ap,e=new Ap,b3(t,n),b3(e,n);e.b!=e.c;)for(c=new Ub(_B(bU(e),37).a);c.a0&&cKn(n,e,t),r):POn(n,t,e)}function RSn(n,t,e){var i,r,c,a;if(0!=t.b){for(i=new VT,a=upn(t,0);a.b!=a.d.c;)Krn(i,Lun(c=_B(f3(a),86))),(r=c.e).a=_B(pMn(c,(Bqn(),wkt)),19).a,r.b=_B(pMn(c,dkt),19).a;RSn(n,i,pcn(e,i.b/n.a|0))}}function KSn(n,t){var e,i,r,c,a;if(n.e<=t)return n.g;if(q1(n,n.g,t))return n.g;for(c=n.r,i=n.g,a=n.r,r=(c-i)/2+i;i+11&&(n.e.b+=n.a)):(n.e.a+=e.a,n.e.b=i.Math.max(n.e.b,e.b),n.d.c.length>1&&(n.e.a+=n.a))}function zSn(n){var t,e,i,r;switch(t=(r=n.i).b,i=r.j,e=r.g,r.a.g){case 0:e.a=(n.g.b.o.a-i.a)/2;break;case 1:e.a=t.d.n.a+t.d.a.a;break;case 2:e.a=t.d.n.a+t.d.a.a-i.a;break;case 3:e.b=t.d.n.b+t.d.a.b}}function USn(n,t,e,i,r){if(ii&&(n.a=i),n.br&&(n.b=r),n}function XSn(n){if(iL(n,149))return ENn(_B(n,149));if(iL(n,229))return Jbn(_B(n,229));if(iL(n,23))return oSn(_B(n,23));throw Fp(new Ry(q6n+AMn(new Qy(Mun(Hk(Cnt,1),FWn,1,5,[n])))))}function WSn(n,t,e,i,r){var c,a,u;for(c=!0,a=0;a>>r|e[a+i+1]<>>r,++a}return c}function VSn(n,t,e,i){var r,c;if(t.k==(cSn(),Mut))for(c=new az(JL(sbn(t).a.Kc(),new h));bAn(c);)if((r=_B(G5(c),17)).c.i.k==Mut&&n.c.a[r.c.i.c.p]==i&&n.c.a[t.c.p]==e)return!0;return!1}function QSn(n,t){var e,i,r,c;return t&=63,e=n.h&MQn,t<22?(c=e>>>t,r=n.m>>t|e<<22-t,i=n.l>>t|n.m<<22-t):t<44?(c=0,r=e>>>t-22,i=n.m>>t-22|n.h<<44-t):(c=0,r=0,i=e>>>t-44),E$(i&TQn,r&TQn,c&MQn)}function JSn(n,t,e,i){var r;this.b=i,this.e=n==(ain(),Cmt),r=t[e],this.d=mq(CNt,[uVn,JJn],[177,25],16,[r.length,r.length],2),this.a=mq(INt,[uVn,oQn],[48,25],15,[r.length,r.length],2),this.c=new qEn(t,e)}function YSn(n){var t,e,i;for(n.k=new a1((mUn(),Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt])).length,n.j.c.length),i=new Ub(n.j);i.a=e)return oPn(n,t,i.p),!0;return!1}function iPn(n){var t;return 0!=(64&n.Db)?pSn(n):(t=new hN(J5n),!n.a||aO(aO((t.a+=' "',t),n.a),'"'),aO(mE(aO(mE(aO(mE(aO(mE((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function rPn(n,t,e){var i,r,c,a,u;for(u=rxn(n.e.Tg(),t),r=_B(n.g,119),i=0,a=0;ae?bIn(n,e,"start index"):t<0||t>e?bIn(t,e,"end index"):ORn("end index (%s) must not be less than start index (%s)",Mun(Hk(Cnt,1),FWn,1,5,[tln(t),tln(n)]))}function uPn(n,t){var e,i,r,c;for(i=0,r=n.length;i0&&hPn(n,c,e));t.p=0}function fPn(n){var t;this.c=new VT,this.f=n.e,this.e=n.d,this.i=n.g,this.d=n.c,this.b=n.b,this.k=n.j,this.a=n.a,n.i?this.j=n.i:this.j=new VK(t=_B(Xj(yMt),9),_B(TR(t,t.length),9),0),this.g=n.f}function lPn(n){var t,e,i,r;for(t=LX(aO(new hN("Predicates."),"and"),40),e=!0,r=new Tb(n);r.b0?u[a-1]:L8(Iut,r1n,10,0,0,1),r=u[a],s=a=0?n.Bh(r):iCn(n,i)}else Bfn(n,e,i)}function vPn(n){var t,e;if(e=null,t=!1,iL(n,204)&&(t=!0,e=_B(n,204).a),t||iL(n,258)&&(t=!0,e=""+_B(n,258).a),t||iL(n,483)&&(t=!0,e=""+_B(n,483).a),!t)throw Fp(new Ay(F6n));return e}function mPn(n,t){var e,i;if(n.f){for(;t.Ob();)if(iL(i=(e=_B(t.Pb(),72)).ak(),99)&&0!=(_B(i,18).Bb&o6n)&&(!n.e||i.Gj()!=AOt||0!=i.aj())&&null!=e.dd())return t.Ub(),!0;return!1}return t.Ob()}function yPn(n,t){var e,i;if(n.f){for(;t.Sb();)if(iL(i=(e=_B(t.Ub(),72)).ak(),99)&&0!=(_B(i,18).Bb&o6n)&&(!n.e||i.Gj()!=AOt||0!=i.aj())&&null!=e.dd())return t.Pb(),!0;return!1}return t.Sb()}function kPn(n,t,e){var i,r,c,a,u,o;for(o=rxn(n.e.Tg(),t),i=0,u=n.i,r=_B(n.g,119),a=0;a1&&(t.c[t.c.length]=c)}function TPn(n){var t,e,i;for(Krn(e=new VT,n.o),i=new am;0!=e.b;)UUn(n,t=_B(0==e.b?null:(Mx(0!=e.b),Ctn(e,e.a.a)),508),!0)&&UB(i.a,t);for(;0!=i.a.c.length;)UUn(n,t=_B(Zsn(i),508),!1)}function MPn(){MPn=O,mMt=new OI(oYn,0),lMt=new OI("BOOLEAN",1),gMt=new OI("INT",2),vMt=new OI("STRING",3),bMt=new OI("DOUBLE",4),wMt=new OI("ENUM",5),dMt=new OI("ENUMSET",6),pMt=new OI("OBJECT",7)}function SPn(n,t){var e,r,c,a,u;r=i.Math.min(n.c,t.c),a=i.Math.min(n.d,t.d),(c=i.Math.max(n.c+n.b,t.c+t.b))=(r/2|0))for(this.e=i?i.c:null,this.d=r;e++0;)kZ(this);this.b=t,this.a=null}function RPn(n,t){var e,i;t.a?qNn(n,t):(!!(e=_B(mK(n.b,t.b),57))&&e==n.a[t.b.f]&&!!e.a&&e.a!=t.b.a&&e.c.Fc(t.b),!!(i=_B(vK(n.b,t.b),57))&&n.a[i.f]==t.b&&!!i.a&&i.a!=t.b.a&&t.b.c.Fc(i),EN(n.b,t.b))}function KPn(n,t){var e,i;if(e=_B(aV(n.b,t),124),_B(_B(o6(n.r,t),21),84).dc())return e.n.b=0,void(e.n.c=0);e.n.b=n.C.b,e.n.c=n.C.c,n.A.Hc((pdn(),RCt))&&vRn(n,t),i=zpn(n,t),MDn(n,t)==(ipn(),_It)&&(i+=2*n.w),e.a.a=i}function _Pn(n,t){var e,i;if(e=_B(aV(n.b,t),124),_B(_B(o6(n.r,t),21),84).dc())return e.n.d=0,void(e.n.a=0);e.n.d=n.C.d,e.n.a=n.C.a,n.A.Hc((pdn(),RCt))&&mRn(n,t),i=Upn(n,t),MDn(n,t)==(ipn(),_It)&&(i+=2*n.w),e.a.b=i}function FPn(n,t){var e,i,r,c;for(c=new $p,i=new Ub(t);i.ae.a&&(i.Hc((lEn(),UMt))?r=(t.a-e.a)/2:i.Hc(WMt)&&(r=t.a-e.a)),t.b>e.b&&(i.Hc((lEn(),QMt))?c=(t.b-e.b)/2:i.Hc(VMt)&&(c=t.b-e.b)),hMn(n,r,c)}function fIn(n,t,e,i,r,c,a,u,o,s,h,f,l){iL(n.Cb,88)&&CIn(M5(_B(n.Cb,88)),4),$rn(n,e),n.f=a,Oln(n,u),$ln(n,o),Cln(n,s),Aln(n,h),Yfn(n,f),Bln(n,l),Vfn(n,!0),Aen(n,r),n.ok(c),Phn(n,t),null!=i&&(n.i=null,rrn(n,i))}function lIn(n){var t,e;if(n.f){for(;n.n>0;){if(iL(e=(t=_B(n.k.Xb(n.n-1),72)).ak(),99)&&0!=(_B(e,18).Bb&o6n)&&(!n.e||e.Gj()!=AOt||0!=e.aj())&&null!=t.dd())return!0;--n.n}return!1}return n.n>0}function bIn(n,t,e){if(n<0)return ORn(_Wn,Mun(Hk(Cnt,1),FWn,1,5,[e,tln(n)]));if(t<0)throw Fp(new Ry(BWn+t));return ORn("%s (%s) must not be greater than size (%s)",Mun(Hk(Cnt,1),FWn,1,5,[e,tln(n),tln(t)]))}function wIn(n,t,e,i,r,c){var a,u,o;if(i-e<7)Obn(t,e,i,c);else if(wIn(t,n,u=e+r,o=u+((a=i+r)-u>>1),-r,c),wIn(t,n,o,a,-r,c),c.ue(n[o-1],n[o])<=0)for(;e=0?n.sh(c,e):jLn(n,r,e)}else Abn(n,i,r,e)}function mIn(n){var t,e,i,r;if(e=_B(n,49).qh())try{if(i=null,(t=O$n((UM(),HAt),E_n(Rbn(e))))&&(r=t.rh())&&(i=r.Wk(zy(e.e))),i&&i!=n)return mIn(i)}catch(c){if(!iL(c=hun(c),60))throw Fp(c)}return n}function yIn(n,t,e){var i,r,c,a;if(a=null==t?0:n.b.se(t),0==(r=null==(i=n.a.get(a))?new Array:i).length)n.a.set(a,r);else if(c=ohn(n,t,r))return c.ed(e);return OX(r,r.length,new MS(t,e)),++n.c,aJ(n.b),null}function kIn(n,t){var e;return o2(n.a),SU(n.a,(Mrn(),Wkt),Wkt),SU(n.a,Vkt,Vkt),bq(e=new _2,Vkt,(Sbn(),njt)),HC(JAn(t,(Gyn(),Tjt)))!==HC((Fsn(),ujt))&&bq(e,Vkt,Ykt),bq(e,Vkt,Zkt),rA(n.a,e),Oqn(n.a,t)}function jIn(n){if(!n)return hk(),ott;var t=n.valueOf?n.valueOf():n;if(t!==n){var e=stt[typeof t];return e?e(t):mhn(typeof t)}return n instanceof Array||n instanceof i.Array?new jl(n):new Ml(n)}function EIn(n,t,e){var r,c,a;switch(a=n.o,(c=(r=_B(aV(n.p,e),244)).i).b=TCn(r),c.a=ECn(r),c.b=i.Math.max(c.b,a.a),c.b>a.a&&!t&&(c.b=a.a),c.c=-(c.b-a.a)/2,e.g){case 1:c.d=-c.a;break;case 3:c.d=a.b}RFn(r),HFn(r)}function TIn(n,t,e){var r,c,a;switch(a=n.o,(c=(r=_B(aV(n.p,e),244)).i).b=TCn(r),c.a=ECn(r),c.a=i.Math.max(c.a,a.b),c.a>a.b&&!t&&(c.a=a.b),c.d=-(c.a-a.b)/2,e.g){case 4:c.c=-c.b;break;case 2:c.c=a.a}RFn(r),HFn(r)}function MIn(n,t){var e,i,r,c,a;if(!t.dc())if(r=_B(t.Xb(0),128),1!=t.gc())for(e=1;e0)try{i=h_n(t,RVn,NWn)}catch(r){throw iL(r=hun(r),127)?Fp(new A7(r)):Fp(r)}return!n.a&&(n.a=new Tp(n)),i<(e=n.a).i&&i>=0?_B(Utn(e,i),56):null}function AIn(n,t){if(n<0)return ORn(_Wn,Mun(Hk(Cnt,1),FWn,1,5,["index",tln(n)]));if(t<0)throw Fp(new Ry(BWn+t));return ORn("%s (%s) must be less than size (%s)",Mun(Hk(Cnt,1),FWn,1,5,["index",tln(n),tln(t)]))}function $In(n){var t,e,i,r,c;if(null==n)return qWn;for(c=new Oan(KWn,"[","]"),i=0,r=(e=n).length;i0)for(a=n.c.d,r=mL(zR(new LI((u=n.d.d).a,u.b),a),1/(i+1)),c=new LI(a.a,a.b),e=new Ub(n.a);e.a=0?n._g(e,!0,!0):iOn(n,r,!0),153),_B(i,215).ol(t)}function rCn(n){var t,e;return n>-0x800000000000&&n<0x800000000000?0==n?0:((t=n<0)&&(n=-n),e=SY(i.Math.floor(i.Math.log(n)/.6931471805599453)),(!t||n!=i.Math.pow(2,e))&&++e,e):Xan(san(n))}function cCn(n){var t,e,i,r,c,a,u;for(c=new sA,e=new Ub(n);e.a2&&u.e.b+u.j.b<=2&&(r=u,i=a),c.a.zc(r,c),r.q=i);return c}function aCn(n,t){var e,i,r;return Ban(i=new Ovn(n),t),oon(i,(oWn(),Xft),t),oon(i,(FXn(),npt),(WEn(),zIt)),oon(i,mdt,(lvn(),IMt)),_l(i,(cSn(),Eut)),SZ(e=new SSn,i),BIn(e,(mUn(),SCt)),SZ(r=new SSn,i),BIn(r,aCt),i}function uCn(n){switch(n.g){case 0:return new $y((ain(),Imt));case 1:return new bf;case 2:return new yf;default:throw Fp(new Ry("No implementation is available for the crossing minimizer "+(null!=n.f?n.f:""+n.g)))}}function oCn(n,t){var e,i,r,c;for(n.c[t.p]=!0,UB(n.a,t),c=new Ub(t.j);c.a=(c=a.gc()))a.$b();else for(r=a.Kc(),i=0;i0?lk():c<0&&kCn(n,t,-c),!0)}function ECn(n){var t,e,i,r,c,a;if(a=0,0==n.b){for(t=0,r=0,c=(i=zvn(n,!0)).length;r0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}else a=Dk(ncn(AV(CV(AU(n.a),new Mn),new Sn)));return a>0?a+n.n.d+n.n.a:0}function TCn(n){var t,e,i,r,c,a;if(a=0,0==n.b)a=Dk(ncn(AV(CV(AU(n.a),new En),new Tn)));else{for(t=0,r=0,c=(i=Uvn(n,!0)).length;r0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}return a>0?a+n.n.b+n.n.c:0}function MCn(n,t){var e,r,c,a;for(e=(a=_B(aV(n.b,t),124)).a,c=_B(_B(o6(n.r,t),21),84).Kc();c.Ob();)(r=_B(c.Pb(),111)).c&&(e.a=i.Math.max(e.a,XH(r.c)));if(e.a>0)switch(t.g){case 2:a.n.c=n.s;break;case 4:a.n.b=n.s}}function SCn(n,t){var e,i,r;return 0==(e=_B(pMn(t,(sRn(),Jct)),19).a-_B(pMn(n,Jct),19).a)?(i=zR(_$(_B(pMn(n,(Ern(),cat)),8)),_B(pMn(n,aat),8)),r=zR(_$(_B(pMn(t,cat),8)),_B(pMn(t,aat),8)),Mln(i.a*i.b,r.a*r.b)):e}function PCn(n,t){var e,i,r;return 0==(e=_B(pMn(t,(SAn(),Okt)),19).a-_B(pMn(n,Okt),19).a)?(i=zR(_$(_B(pMn(n,(Bqn(),Jyt)),8)),_B(pMn(n,Yyt),8)),r=zR(_$(_B(pMn(t,Jyt),8)),_B(pMn(t,Yyt),8)),Mln(i.a*i.b,r.a*r.b)):e}function ICn(n){var t,e;return(e=new Sk).a+="e_",null!=(t=zan(n))&&(e.a+=""+t),n.c&&n.d&&(aO((e.a+=" ",e),dyn(n.c)),aO(cO((e.a+="[",e),n.c.i),"]"),aO((e.a+=n1n,e),dyn(n.d)),aO(cO((e.a+="[",e),n.d.i),"]")),e.a}function CCn(n){switch(n.g){case 0:return new df;case 1:return new gf;case 2:return new wf;case 3:return new pf;default:throw Fp(new Ry("No implementation is available for the layout phase "+(null!=n.f?n.f:""+n.g)))}}function OCn(n,t,e,r,c){var a;switch(a=0,c.g){case 1:a=i.Math.max(0,t.b+n.b-(e.b+r));break;case 3:a=i.Math.max(0,-n.b-r);break;case 2:a=i.Math.max(0,-n.a-r);break;case 4:a=i.Math.max(0,t.a+n.a-(e.a+r))}return a}function ACn(n,t,e){var i,r,c;if(e)for(c=((i=new oz(e.a.length)).b-i.a)*i.c<0?(nS(),jNt):new zL(i);c.Ob();)r=L2(e,_B(c.Pb(),19).a),A6n in r.a||$6n in r.a?uKn(n,r,t):kXn(n,r,t),ML(_B(xX(n.b,Wdn(r)),79))}function $Cn(n){var t,e;switch(n.b){case-1:return!0;case 0:return(e=n.t)>1||-1==e||(t=Pkn(n))&&(JM(),t.Cj()==k9n)?(n.b=-1,!0):(n.b=1,!1);default:case 1:return!1}}function LCn(n,t){var e,i,r,c,a;for(!t.s&&(t.s=new nU(RAt,t,21,17)),c=null,r=0,a=(i=t.s).i;r=0&&i=0?n._g(e,!0,!0):iOn(n,r,!0),153),_B(i,215).ll(t);throw Fp(new Ry(e6n+t.ne()+c6n))}function HCn(){var n;return ZM(),X$t?_B(O$n((UM(),HAt),X9n),1939):(xO(Fnt,new Is),YGn(),n=_B(iL(TY((UM(),HAt),X9n),547)?TY(HAt,X9n):new GW,547),X$t=!0,aWn(n),jWn(n),XW((XM(),QAt),n,new Go),pZ(HAt,X9n,n),n)}function qCn(n,t){var e,i,r,c;n.j=-1,pA(n.e)?(e=n.i,c=0!=n.i,i6(n,t),i=new $7(n.e,3,n.c,null,t,e,c),r=t.Qk(n.e,n.c,null),(r=PEn(n,t,r))?(r.Ei(i),r.Fi()):fan(n.e,i)):(i6(n,t),(r=t.Qk(n.e,n.c,null))&&r.Fi())}function GCn(n,t){var e,i,r;if(r=0,(i=t[0])>=n.length)return-1;for(f1(i,n.length),e=n.charCodeAt(i);e>=48&&e<=57&&(r=10*r+(e-48),!(++i>=n.length));)f1(i,n.length),e=n.charCodeAt(i);return i>t[0]?t[0]=i:r=-1,r}function zCn(n){var t,e,r,c,a;return e=c=_B(n.a,19).a,r=a=_B(n.b,19).a,t=i.Math.max(i.Math.abs(c),i.Math.abs(a)),c<=0&&c==a?(e=0,r=a-1):c==-t&&a!=t?(e=a,r=c,a>=0&&++e):(e=-a,r=c),new eC(tln(e),tln(r))}function UCn(n,t,e,i){var r,c,a,u,o,s;for(r=0;r=0&&s>=0&&o=n.i)throw Fp(new Cy(c8n+t+a8n+n.i));if(e>=n.i)throw Fp(new Cy(u8n+e+a8n+n.i));return i=n.g[e],t!=e&&(t>16))>>16&16),e+=t=(i=(n>>=t)-256)>>16&8,e+=t=(i=(n<<=t)-RQn)>>16&4,(e+=t=(i=(n<<=t)-oVn)>>16&2)+2-(t=(i=(n<<=t)>>14)&~(i>>1)))}function YCn(n){var t,e,i,r;for(EQ(),Tct=new $p,Ect=new Lp,jct=new $p,!n.a&&(n.a=new nU(qOt,n,10,11)),LUn(t=n.a),r=new CL(t);r.e!=r.i.gc();)i=_B(mpn(r),33),-1==k7(Tct,i,0)&&(e=new $p,UB(jct,e),xgn(i,e));return jct}function ZCn(n,t,e){var i,r,c,a;n.a=e.b.d,iL(t,352)?(n5(c=BSn(r=iDn(_B(t,79),!1,!1)),i=new $w(n)),XFn(c,r),null!=t.We((uWn(),ISt))&&n5(_B(t.We(ISt),74),i)):((a=_B(t,470)).Hg(a.Dg()+n.a.a),a.Ig(a.Eg()+n.a.b))}function nOn(n,t){var e,r,c,a,u,o,s,h;for(h=Hy(ED(pMn(t,(FXn(),$pt)))),s=n[0].n.a+n[0].o.a+n[0].d.c+h,o=1;o=0?e:(u=hW(zR(new LI(a.c+a.b/2,a.d+a.a/2),new LI(c.c+c.b/2,c.d+c.a/2))),-(V_n(c,a)-1)*u)}function eOn(n,t,e){var i;QT(new xq(null,(!e.a&&(e.a=new nU(ROt,e,6,6)),new l1(e.a,16))),new nC(n,t)),QT(new xq(null,(!e.n&&(e.n=new nU(HOt,e,1,7)),new l1(e.n,16))),new tC(n,t)),(i=_B(JAn(e,(uWn(),ISt)),74))&&Vrn(i,n,t)}function iOn(n,t,e){var i,r,c;if(c=Kqn((PPn(),Q$t),n.Tg(),t))return JM(),_B(c,66).Oj()||(c=J1(_7(Q$t,c))),r=_B((i=n.Yg(c))>=0?n._g(i,!0,!0):iOn(n,c,!0),153),_B(r,215).hl(t,e);throw Fp(new Ry(e6n+t.ne()+c6n))}function rOn(n,t,e,i){var r,c,a,u,o;if(r=n.d[t])if(c=r.g,o=r.i,null!=i){for(u=0;u=e&&(i=t,c=(o=(u.c+u.a)/2)-e,u.c<=o-e&&mG(n,i++,new mB(u.c,c)),(a=o+e)<=u.a&&(r=new mB(a,u.a),AZ(i,n.c.length),ES(n.c,i,r)))}function fOn(n){var t;if(n.c||null!=n.g){if(null==n.g)return!0;if(0==n.i)return!1;t=_B(n.g[n.i-1],47)}else n.d=n.si(n.f),s9(n,n.d),t=n.d;return t==n.b&&null.km>=null.jm()?(rLn(n),fOn(n)):t.Ob()}function lOn(n,t,e){var i,r,c,a;if(!(a=e)&&(a=AH(new zm,0)),ITn(a,BZn,1),OGn(n.c,t),1==(c=xGn(n.a,t)).gc())XHn(_B(c.Xb(0),37),a);else for(r=1/c.gc(),i=c.Kc();i.Ob();)XHn(_B(i.Pb(),37),pcn(a,r));kk(n.a,c,t),KDn(t),FSn(a)}function bOn(n){if(this.a=n,n.c.i.k==(cSn(),Eut))this.c=n.c,this.d=_B(pMn(n.c.i,(oWn(),Wft)),61);else{if(n.d.i.k!=Eut)throw Fp(new Ry("Edge "+n+" is not an external edge."));this.c=n.d,this.d=_B(pMn(n.d.i,(oWn(),Wft)),61)}}function wOn(n,t){var e,i,r;r=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,3,r,n.b)),t?t!=n&&($rn(n,t.zb),Oen(n,t.d),Kin(n,null==(e=null==(i=t.c)?t.zb:i)||pK(e,t.zb)?null:e)):($rn(n,null),Oen(n,0),Kin(n,null))}function dOn(n){var t,e;if(n.f){for(;n.n=(a=null==(e=_B(van(n.a,4),126))?0:e.length))throw Fp(new ZR(t,a));return r=e[t],1==a?i=null:(rHn(e,0,i=L8(lAt,t9n,415,a-1,0,1),0,t),(c=a-t-1)>0&&rHn(e,t+1,i,t,c)),Kgn(n,i),nIn(n,t,r),r}function jOn(){jOn=O,oLt=_B(Utn(WQ((iE(),bLt).qb),6),34),cLt=_B(Utn(WQ(bLt.qb),3),34),aLt=_B(Utn(WQ(bLt.qb),4),34),uLt=_B(Utn(WQ(bLt.qb),5),18),aEn(oLt),aEn(cLt),aEn(aLt),aEn(uLt),sLt=new Qy(Mun(Hk(RAt,1),$9n,170,0,[oLt,cLt]))}function EOn(n,t){var e;this.d=new hm,this.b=t,this.e=new lA(t.qf()),e=n.u.Hc((hCn(),tCt)),n.u.Hc(nCt)?n.D?this.a=e&&!t.If():this.a=!0:n.u.Hc(eCt)?this.a=!!e&&!(t.zf().Kc().Ob()||t.Bf().Kc().Ob()):this.a=!1}function TOn(n,t){var e,i,r,c;for(e=n.o.a,c=_B(_B(o6(n.r,t),21),84).Kc();c.Ob();)(r=_B(c.Pb(),111)).e.a=(i=r.b).Xe((uWn(),rPt))?i.Hf()==(mUn(),SCt)?-i.rf().a-Hy(ED(i.We(rPt))):e+Hy(ED(i.We(rPt))):i.Hf()==(mUn(),SCt)?-i.rf().a:e}function MOn(n,t){var e,i,r;e=_B(pMn(n,(FXn(),Gdt)),103),r=_B(JAn(t,cpt),61),(i=_B(pMn(n,npt),98))!=(WEn(),WIt)&&i!=VIt?r==(mUn(),MCt)&&(r=IFn(t,e))==MCt&&(r=own(e)):r=zHn(t)>0?own(e):jln(own(e)),Vpn(t,cpt,r)}function SOn(n,t){var e,i,r,c,a;for(a=n.j,t.a!=t.b&&p$(a,new Ur),r=a.c.length/2|0,i=0;i0&&cKn(n,e,t),c):null!=i.a?(cKn(n,t,e),-1):null!=r.a?(cKn(n,e,t),1):0}function IOn(n,t){var e,i,r,c;n.ej()?(e=n.Vi(),c=n.fj(),++n.j,n.Hi(e,n.oi(e,t)),i=n.Zi(3,null,t,e,c),n.bj()&&(r=n.cj(t,null))?(r.Ei(i),r.Fi()):n.$i(i)):(nW(n,t),n.bj()&&(r=n.cj(t,null))&&r.Fi())}function COn(n,t){var e,i,r,c,a;for(a=rxn(n.e.Tg(),t),r=new go,e=_B(n.g,119),c=n.i;--c>=0;)i=e[c],a.rl(i.ak())&&s9(r,i);!rXn(n,r)&&pA(n.e)&&Av(n,t.$j()?AJ(n,6,t,(TQ(),uet),null,-1,!1):AJ(n,t.Kj()?2:1,t,null,null,-1,!1))}function OOn(){var n,t;for(OOn=O,ret=L8(aet,uVn,91,32,0,1),cet=L8(aet,uVn,91,32,0,1),n=1,t=0;t<=18;t++)ret[t]=Ygn(n),cet[t]=Ygn(vz(n,t)),n=ibn(n,5);for(;tc)||t.q&&(c=(i=t.C).c.c.a-i.o.a/2,i.n.a-e>c)))}function $On(n,t){ITn(t,"Partition preprocessing",1),QT(_B(M4(CV(lnn(CV(new xq(null,new l1(n.a,16)),new vi),new mi),new yi),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),Get)]))),15).Oc(),new ki),FSn(t)}function LOn(n){var t,e,i,r,c,a;for(BZ(),e=new g4,i=new Ub(n.e.b);i.a1?n.e*=Hy(n.a):n.f/=Hy(n.a),Shn(n),wgn(n),jRn(n),oon(n.b,(kpn(),wct),n.g)}function FOn(n,t,e){var i,r,c,a,u;for(i=0,u=e,t||(i=e*(n.c.length-1),u*=-1),c=new Ub(n);c.a=0?(t||(t=new Mk,i>0&&iO(t,n.substr(0,i))),t.a+="\\",$X(t,e&WVn)):t&&$X(t,e&WVn);return t?t.a:n}function eAn(n){var t;if(!n.a)throw Fp(new Ky("IDataType class expected for layout option "+n.f));if(null==(t=P3(n.a)))throw Fp(new Ky("Couldn't create new instance of property '"+n.f+"'. "+e5n+(kD(hAt),hAt.k)+i5n));return _B(t,414)}function iAn(n){var t,e,i,r,c;return(c=n.eh())&&c.kh()&&(r=Zhn(n,c))!=c?(e=n.Vg(),i=(t=n.Vg())>=0?n.Qg(null):n.eh().ih(n,-1-t,null,null),n.Rg(_B(r,49),e),i&&i.Fi(),n.Lg()&&n.Mg()&&e>-1&&fan(n,new Yz(n,9,e,c,r)),r):c}function rAn(n){var t,e,i,r,c,a,u;for(c=0,r=n.f.e,e=0;e>5)>=n.d)return n.e<0;if(e=n.a[r],t=1<<(31&t),n.e<0){if(r<(i=Scn(n)))return!1;e=i==r?-e:~e}return 0!=(e&t)}function hAn(n,t,e,i){var r;_B(e.b,65),_B(e.b,65),_B(i.b,65),_B(i.b,65),$H(r=zR(_$(_B(e.b,65).c),_B(i.b,65).c),FIn(_B(e.b,65),_B(i.b,65),r)),_B(i.b,65),_B(i.b,65),_B(i.b,65).c.a,r.a,_B(i.b,65).c.b,r.b,_B(i.b,65),Itn(i.a,new jB(n,t,i))}function fAn(n,t){var e,i,r,c,a,u,o;if(c=t.e)for(e=iAn(c),i=_B(n.g,674),a=0;a>16)),15).Xc(c))0&&((!bA(n.a.c)||!t.n.d)&&(!wA(n.a.c)||!t.n.b)&&(t.g.d+=i.Math.max(0,r/2-.5)),(!bA(n.a.c)||!t.n.a)&&(!wA(n.a.c)||!t.n.c)&&(t.g.a-=r-1))}function pAn(n){var t,e,r,c,a;if(a=D_n(n,c=new $p),t=_B(pMn(n,(oWn(),klt)),10))for(r=new Ub(t.j);r.a>t,c=n.m>>t|e<<22-t,r=n.l>>t|n.m<<22-t):t<44?(a=i?MQn:0,c=e>>t-22,r=n.m>>t-22|e<<44-t):(a=i?MQn:0,c=i?TQn:0,r=e>>t-44),E$(r&TQn,c&TQn,a&MQn)}function kAn(n){var t,e,r,c,a,u;for(this.c=new $p,this.d=n,r=xQn,c=xQn,t=DQn,e=DQn,u=upn(n,0);u.b!=u.d.c;)a=_B(f3(u),8),r=i.Math.min(r,a.a),c=i.Math.min(c,a.b),t=i.Math.max(t,a.a),e=i.Math.max(e,a.b);this.a=new GV(r,c,t-r,e-c)}function jAn(n,t){var e,i,r,c;for(i=new Ub(n.b);i.a0&&iL(t,42)&&(n.a.qj(),c=null==(o=(s=_B(t,42)).cd())?0:Yon(o),a=nR(n.a,c),e=n.a.d[a]))for(i=_B(e.g,367),h=e.i,u=0;u=2)for(t=ED((e=c.Kc()).Pb());e.Ob();)a=t,t=ED(e.Pb()),r=i.Math.min(r,(mW(t),t-(mW(a),a)));return r}function FAn(n,t){var e,i,r,c,a;e5(i=new VT,t,i.c.b,i.c);do{for(Mx(0!=i.b),e=_B(Ctn(i,i.a.a),86),n.b[e.g]=1,c=upn(e.d,0);c.b!=c.d.c;)a=(r=_B(f3(c),188)).c,1==n.b[a.g]?NH(n.a,r):2==n.b[a.g]?n.b[a.g]=1:e5(i,a,i.c.b,i.c)}while(0!=i.b)}function BAn(n,t){var e,i,r;if(HC(t)===HC(vX(n)))return!0;if(!iL(t,15))return!1;if(i=_B(t,15),(r=n.gc())!=i.gc())return!1;if(iL(i,54)){for(e=0;e0&&(r=e),a=new Ub(n.f.e);a.a0?(t-=1,e-=1):i>=0&&r<0?(t+=1,e+=1):i>0&&r>=0?(t-=1,e+=1):(t+=1,e-=1),new eC(tln(t),tln(e))}function h$n(n,t){return n.ct.c?1:n.bt.b?1:n.a!=t.a?Yon(n.a)-Yon(t.a):n.d==(W4(),Fmt)&&t.d==_mt?-1:n.d==_mt&&t.d==Fmt?1:0}function f$n(n,t){var e,i,r,c,a;return a=(c=t.a).c.i==t.b?c.d:c.c,i=c.c.i==t.b?c.c:c.d,(r=qwn(n.a,a,i))>0&&r0):r<0&&-r0)}function l$n(n,t,e,i){var r,c,a,u,o,s;for(r=(t-n.d)/n.c.c.length,c=0,n.a+=e,n.d=t,s=new Ub(n.c);s.a>24;return a}function w$n(n){if(n.pe()){var t=n.c;return t.qe()?n.o="["+t.n:t.pe()?n.o="["+t.ne():n.o="[L"+t.ne()+";",n.b=t.me()+"[]",void(n.k=t.oe()+"[]")}var e=n.j,i=n.d;i=i.split("/"),n.o=Kdn(".",[e,Kdn("$",i)]),n.b=Kdn(".",[e,Kdn(".",i)]),n.k=i[i.length-1]}function d$n(n,t){var e,i,r,c,a;for(a=null,c=new Ub(n.e.a);c.a=0;t-=2)for(e=0;e<=t;e+=2)(n.b[e]>n.b[e+2]||n.b[e]===n.b[e+2]&&n.b[e+1]>n.b[e+3])&&(i=n.b[e+2],n.b[e+2]=n.b[e],n.b[e]=i,i=n.b[e+3],n.b[e+3]=n.b[e+1],n.b[e+1]=i);n.c=!0}}function E$n(n,t){var e,i,r,c,a,u;for(c=(1==t?Uat:zat).a.ec().Kc();c.Ob();)for(r=_B(c.Pb(),103),u=_B(o6(n.f.c,r),21).Kc();u.Ob();)switch(a=_B(u.Pb(),46),i=_B(a.b,81),e=_B(a.a,189).c,r.g){case 2:case 1:i.g.d+=e;break;case 4:case 3:i.g.c+=e}}function T$n(n,t){var e,i,r,c,a,u,o,s,h;for(s=-1,h=0,u=0,o=(a=n).length;u0&&++h;++s}return h}function M$n(n){var t;return(t=new hN(Yj(n.gm))).a+="@",aO(t,(Yon(n)>>>0).toString(16)),n.kh()?(t.a+=" (eProxyURI: ",cO(t,n.qh()),n.$g()&&(t.a+=" eClass: ",cO(t,n.$g())),t.a+=")"):n.$g()&&(t.a+=" (eClass: ",cO(t,n.$g()),t.a+=")"),t.a}function S$n(n){var t,e,i;if(n.e)throw Fp(new Ky((kD(wit),CJn+wit.k+OJn)));for(n.d==(Kfn(),_Pt)&&jzn(n,RPt),e=new Ub(n.a.a);e.a>24}return e}function $$n(n,t,e){var i,r,c;if(!(r=_B(aV(n.i,t),306)))if(r=new ltn(n.d,t,e),pG(n.i,t,r),rgn(t))kL(n.a,t.c,t.b,r);else switch(c=APn(t),i=_B(aV(n.p,c),244),c.g){case 1:case 3:r.j=!0,yy(i,t.b,r);break;case 4:case 2:r.k=!0,yy(i,t.c,r)}return r}function L$n(n,t,e,i){var r,c,a,u,o,s;if(u=new go,o=rxn(n.e.Tg(),t),r=_B(n.g,119),JM(),_B(t,66).Oj())for(a=0;a=0)return r;for(c=1,a=new Ub(t.j);a.a0&&t.ue((h1(r-1,n.c.length),_B(n.c[r-1],10)),c)>0;)i5(n,r,(h1(r-1,n.c.length),_B(n.c[r-1],10))),--r;h1(r,n.c.length),n.c[r]=c}e.a=new Lp,e.b=new Lp}function D$n(n,t,e){var i,r,c,a,u,o,s;for(s=new VK(i=_B(t.e&&t.e(),9),_B(TR(i,i.length),9),0),a=0,u=(c=mKn(e,"[\\[\\]\\s,]+")).length;a0&&((!bA(n.a.c)||!t.n.d)&&(!wA(n.a.c)||!t.n.b)&&(t.g.d-=i.Math.max(0,r/2-.5)),(!bA(n.a.c)||!t.n.a)&&(!wA(n.a.c)||!t.n.c)&&(t.g.a+=i.Math.max(0,r-1)))}function K$n(n,t,e){var i;if(2==(n.c-n.b&n.a.length-1))t==(mUn(),uCt)||t==aCt?(ytn(_B(kon(n),15),(zyn(),yIt)),ytn(_B(kon(n),15),kIt)):(ytn(_B(kon(n),15),(zyn(),kIt)),ytn(_B(kon(n),15),yIt));else for(i=new fV(n);i.a!=i.b;)ytn(_B(Rhn(i),15),e)}function _$n(n,t){var e,i,r,c,a,u;for(a=new E2(i=FB(new up(n)),i.c.length),u=new E2(r=FB(new up(t)),r.c.length),c=null;a.b>0&&u.b>0&&(Mx(a.b>0),e=_B(a.a.Xb(a.c=--a.b),33),Mx(u.b>0),e==_B(u.a.Xb(u.c=--u.b),33));)c=e;return c}function F$n(n,t){var e,r,c,a;return c=n.a*rJn+1502*n.b,a=n.b*rJn+11,c+=e=i.Math.floor(a*cJn),a-=e*aJn,c%=aJn,n.a=c,n.b=a,t<=24?i.Math.floor(n.a*Iet[t]):((r=n.a*(1<=2147483648&&(r-=zQn),r)}function B$n(n,t,e){var i,r,c,a;l0(n,t)>l0(n,e)?(i=rbn(e,(mUn(),aCt)),n.d=i.dc()?0:cq(_B(i.Xb(0),11)),a=rbn(t,SCt),n.b=a.dc()?0:cq(_B(a.Xb(0),11))):(r=rbn(e,(mUn(),SCt)),n.d=r.dc()?0:cq(_B(r.Xb(0),11)),c=rbn(t,aCt),n.b=c.dc()?0:cq(_B(c.Xb(0),11)))}function H$n(n){var t,e,i,r,c,a,u;if(n&&(t=n.Hh(X9n))&&null!=(a=TD(idn((!t.b&&(t.b=new Qx((wWn(),v$t),G$t,t)),t.b),"conversionDelegates")))){for(u=new $p,r=0,c=(i=mKn(a,"\\w+")).length;rn.c));a++)r.a>=n.s&&(c<0&&(c=a),u=a);return o=(n.s+n.c)/2,c>=0&&(o=BM((h1(i=VRn(n,t,c,u),t.c.length),_B(t.c[i],329))),hOn(t,i,e)),o}function U$n(){U$n=O,hEt=new zA((uWn(),iSt),1.3),wEt=ySt,PEt=new UA(15),SEt=new zA(zSt,PEt),OEt=new zA(APt,15),fEt=oSt,yEt=DSt,kEt=_St,jEt=BSt,mEt=NSt,EEt=GSt,IEt=sPt,OAn(),MEt=aEt,vEt=rEt,TEt=cEt,CEt=oEt,dEt=iEt,gEt=SSt,pEt=PSt,bEt=eEt,lEt=tEt,AEt=sEt}function X$n(n,t,e){var i,r,c,a,u;for(_in(r=new jo,(mW(t),t)),!r.b&&(r.b=new Qx((wWn(),v$t),G$t,r)),u=r.b,a=1;a0&&Lqn(this,r)}function V$n(n,t,e,i,r,c){var a,u,o;if(!r[t.b]){for(r[t.b]=!0,!(a=i)&&(a=new v6),UB(a.e,t),o=c[t.b].Kc();o.Ob();)(u=_B(o.Pb(),282)).d!=e&&u.c!=e&&(u.c!=t&&V$n(n,u.c,t,a,r,c),u.d!=t&&V$n(n,u.d,t,a,r,c),UB(a.c,u),wun(a.d,u.b));return a}return null}function Q$n(n){var t,e,i;for(t=0,e=new Ub(n.e);e.a=2}function J$n(n,t){var e,i,r,c;for(ITn(t,"Self-Loop pre-processing",1),i=new Ub(n.a);i.a1||San(IY(kG(PIt,Mun(Hk(HIt,1),OVn,93,0,[SIt,CIt])),n))>1||San(IY(kG(NIt,Mun(Hk(HIt,1),OVn,93,0,[LIt,$It])),n))>1)}function nLn(n,t){var e,i,r;return(e=t.Hh(n.a))&&null!=(r=TD(idn((!e.b&&(e.b=new Qx((wWn(),v$t),G$t,e)),e.b),"affiliation")))?-1==(i=pN(r,VTn(35)))?cln(n,rz(n,Gtn(t.Hj())),r):0==i?cln(n,null,r.substr(1)):cln(n,r.substr(0,i),r.substr(i+1)):null}function tLn(n){var t,e;try{return null==n?qWn:_bn(n)}catch(i){if(iL(i=hun(i),102))return t=i,e=Yj(Zon(n))+"@"+(OT(),(nvn(n)>>>0).toString(16)),Dgn(yun(),(hM(),"Exception during lenientFormat for "+e),t),"<"+e+" threw "+Yj(t.gm)+">";throw Fp(i)}}function eLn(n){switch(n.g){case 0:return new af;case 1:return new nf;case 2:return new OM;case 3:return new Cc;case 4:return new xR;case 5:return new uf;default:throw Fp(new Ry("No implementation is available for the layerer "+(null!=n.f?n.f:""+n.g)))}}function iLn(n,t,e){var i,r,c;for(c=new Ub(n.t);c.a0&&(i.b.n-=i.c,i.b.n<=0&&i.b.u>0&&NH(t,i.b));for(r=new Ub(n.i);r.a0&&(i.a.u-=i.c,i.a.u<=0&&i.a.n>0&&NH(e,i.a))}function rLn(n){var t,e,i;if(null==n.g&&(n.d=n.si(n.f),s9(n,n.d),n.c))return n.f;if(i=(t=_B(n.g[n.i-1],47)).Pb(),n.e=t,(e=n.si(i)).Ob())n.d=e,s9(n,e);else for(n.d=null;!t.Ob()&&(OX(n.g,--n.i,null),0!=n.i);)t=_B(n.g[n.i-1],47);return i}function cLn(n,t){var e,i,r,c,a,u;if(r=(i=t).ak(),Oxn(n.e,r)){if(r.hi()&&H3(n,r,i.dd()))return!1}else for(u=rxn(n.e.Tg(),r),e=_B(n.g,119),c=0;c1||e>1)return 2;return t+e==1?2:0}function gLn(n,t,e){var i,r,c,a;for(ITn(e,"ELK Force",1),By(jD(JAn(t,(sRn(),Uct))))||yY(new jw((HM(),new Ny(t)))),mkn(a=son(t)),qon(n,_B(pMn(a,Hct),424)),r=(c=FFn(n.a,a)).Kc();r.Ob();)i=_B(r.Pb(),231),MKn(n.b,i,pcn(e,1/c.gc()));TUn(a=HUn(c)),FSn(e)}function pLn(n,t){var e,i,r;if(ITn(t,"Breaking Point Processor",1),Izn(n),By(jD(pMn(n,(FXn(),Hpt))))){for(i=new Ub(n.b);i.a=0?n._g(i,!0,!0):iOn(n,c,!0),153),_B(r,215).ml(t,e)}function ELn(n,t){var e,i,r,c,a;for(e=new $p,r=lnn(new xq(null,new l1(n,16)),new Ea),c=lnn(new xq(null,new l1(n,16)),new Ta),a=E7(F6(AV(TNn(Mun(Hk(nit,1),FWn,833,0,[r,c])),new Ma))),i=1;i=2*t&&UB(e,new mB(a[i-1]+t,a[i]-t));return e}function TLn(n,t,e){ITn(e,"Eades radial",1),e.n&&t&&v0(e,a2(t),(_sn(),cOt)),n.d=_B(JAn(t,(lD(),Xkt)),33),n.c=Hy(ED(JAn(t,(Gyn(),Njt)))),n.e=kvn(_B(JAn(t,xjt),293)),n.a=hwn(_B(JAn(t,Rjt),426)),n.b=Bjn(_B(JAn(t,Ojt),340)),ejn(n),e.n&&t&&v0(e,a2(t),(_sn(),cOt))}function MLn(n,t,e){var i,r,c,a,u;if(e)for(c=((i=new oz(e.a.length)).b-i.a)*i.c<0?(nS(),jNt):new zL(i);c.Ob();)(r=L2(e,_B(c.Pb(),19).a))&&(Oin(a=O3(n,(Zj(),u=new km,!!t&&_Ln(u,t),u),r),x2(r,B6n)),TTn(r,a),IIn(r,a),Lon(n,r,a))}function SLn(n){var t,e,i,r;if(!n.j){if(r=new Co,null==(t=T$t).a.zc(n,t)){for(i=new CL(mJ(n));i.e!=i.i.gc();)dX(r,SLn(e=_B(mpn(i),26))),s9(r,e);t.a.Bc(n)}ihn(r),n.j=new $O((_B(Utn(WQ((WX(),YAt).o),11),18),r.i),r.g),M5(n).b&=-33}return n.j}function PLn(n){var t,e,i,r;if(null==n)return null;if(i=KBn(n,!0),r=L7n.length,pK(i.substr(i.length-r,r),L7n))if(4==(e=i.length)){if(f1(0,i.length),43==(t=i.charCodeAt(0)))return BLt;if(45==t)return FLt}else if(3==e)return BLt;return new Nv(i)}function ILn(n){var t,e,i;return 0!=((e=n.l)&e-1)||0!=((i=n.m)&i-1)||0!=((t=n.h)&t-1)||0==t&&0==i&&0==e?-1:0==t&&0==i&&0!=e?win(e):0==t&&0!=i&&0==e?win(i)+22:0!=t&&0==i&&0==e?win(t)+44:-1}function CLn(n,t){var e,i,r,c;for(ITn(t,"Edge joining",1),e=By(jD(pMn(n,(FXn(),Npt)))),i=new Ub(n.b);i.a1)for(i=new Ub(n.a);i.a0),c.a.Xb(c.c=--c.b),vR(c,r),Mx(c.b3&&knn(n,0,t-3))}function DLn(n){var t,e,i,r;return HC(pMn(n,(FXn(),ugt)))===HC((cfn(),dIt))?!n.e&&HC(pMn(n,xdt))!==HC((Dan(),mft)):(i=_B(pMn(n,Ddt),292),r=By(jD(pMn(n,Fdt)))||HC(pMn(n,Bdt))===HC((Iin(),uht)),t=_B(pMn(n,Ndt),19).a,e=n.a.c.length,!r&&i!=(Dan(),mft)&&(0==t||t>e))}function RLn(n){var t,e;for(e=0;e0);e++);if(e>0&&e0);t++);return t>0&&e>16!=6&&t){if(gkn(n,t))throw Fp(new Ry(l6n+xOn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?ukn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=$pn(t,n,6,i)),(i=WD(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,6,t,t))}function _Ln(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=9&&t){if(gkn(n,t))throw Fp(new Ry(l6n+GRn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?skn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=$pn(t,n,9,i)),(i=VD(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,9,t,t))}function FLn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(gkn(n,t))throw Fp(new Ry(l6n+hHn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Ekn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=$pn(t,n,12,i)),(i=XD(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,3,t,t))}function BLn(n){var t,e,i,r,c;if(i=Pkn(n),null==(c=n.j)&&i)return n.$j()?null:i.zj();if(iL(i,148)){if((e=i.Aj())&&(r=e.Nh())!=n.i){if((t=_B(i,148)).Ej())try{n.g=r.Kh(t,c)}catch(a){if(!iL(a=hun(a),78))throw Fp(a);n.g=null}n.i=r}return n.g}return null}function HLn(n){var t;return UB(t=new $p,new LS(new LI(n.c,n.d),new LI(n.c+n.b,n.d))),UB(t,new LS(new LI(n.c,n.d),new LI(n.c,n.d+n.a))),UB(t,new LS(new LI(n.c+n.b,n.d+n.a),new LI(n.c+n.b,n.d))),UB(t,new LS(new LI(n.c+n.b,n.d+n.a),new LI(n.c,n.d+n.a))),t}function qLn(n,t,e,i){var r,c,a;if(a=Cjn(t,e),i.c[i.c.length]=t,-1==n.j[a.p]||2==n.j[a.p]||n.a[t.p])return i;for(n.j[a.p]=-1,c=new az(JL(obn(a).a.Kc(),new h));bAn(c);)if(!f5(r=_B(G5(c),17))&&(f5(r)||r.c.i.c!=r.d.i.c)&&r!=t)return qLn(n,r,a,i);return i}function GLn(n,t,e){var i,r;for(r=t.a.ec().Kc();r.Ob();)i=_B(r.Pb(),79),!_B(xX(n.b,i),266)&&(QY(MMn(i))==QY(IMn(i))?Zxn(n,i,e):MMn(i)==QY(IMn(i))?null==xX(n.c,i)&&null!=xX(n.b,IMn(i))&&ezn(n,i,e,!1):null==xX(n.d,i)&&null!=xX(n.b,MMn(i))&&ezn(n,i,e,!0))}function zLn(n,t){var e,i,r,c,a,u,o;for(r=n.Kc();r.Ob();)for(i=_B(r.Pb(),10),SZ(u=new SSn,i),BIn(u,(mUn(),aCt)),oon(u,(oWn(),ylt),(oN(),!0)),a=t.Kc();a.Ob();)c=_B(a.Pb(),10),SZ(o=new SSn,c),BIn(o,SCt),oon(o,ylt,!0),oon(e=new lJ,ylt,!0),TZ(e,u),EZ(e,o)}function ULn(n,t,e,i){var r,c,a,u;r=Cdn(n,t,e),c=Cdn(n,e,t),a=_B(xX(n.c,t),112),u=_B(xX(n.c,e),112),ri.b.g&&(c.c[c.c.length]=i);return c}function VLn(){VLn=O,NEt=new yI("CANDIDATE_POSITION_LAST_PLACED_RIGHT",0),LEt=new yI("CANDIDATE_POSITION_LAST_PLACED_BELOW",1),DEt=new yI("CANDIDATE_POSITION_WHOLE_DRAWING_RIGHT",2),xEt=new yI("CANDIDATE_POSITION_WHOLE_DRAWING_BELOW",3),REt=new yI("WHOLE_DRAWING",4)}function QLn(n,t){if(iL(t,239))return oln(n,_B(t,33));if(iL(t,186))return Nln(n,_B(t,118));if(iL(t,354))return ZV(n,_B(t,137));if(iL(t,352))return QFn(n,_B(t,79));if(t)return null;throw Fp(new Ry(q6n+AMn(new Qy(Mun(Hk(Cnt,1),FWn,1,5,[t])))))}function JLn(n){var t,e,i,r,c,a,u;for(c=new VT,r=new Ub(n.d.a);r.a1)for(t=CN((e=new Bv,++n.b,e),n.d),u=upn(c,0);u.b!=u.d.c;)a=_B(f3(u),121),GNn(rM(iM(cM(eM(new Fv,1),0),t),a))}function YLn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=11&&t){if(gkn(n,t))throw Fp(new Ry(l6n+qRn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Tkn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=$pn(t,n,10,i)),(i=qR(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,11,t,t))}function ZLn(n){var t,e,i,r;for(i=new csn(new Mb(n.b).a);i.b;)r=_B((e=Ztn(i)).cd(),11),oon(t=_B(e.dd(),10),(oWn(),blt),r),oon(r,klt,t),oon(r,nlt,(oN(),!0)),BIn(r,_B(pMn(t,Wft),61)),pMn(t,Wft),oon(r.i,(FXn(),npt),(WEn(),XIt)),_B(pMn(gW(r.i),Jft),21).Fc((fDn(),bft))}function nNn(n,t,e){var i,r,c;if(i=0,r=0,n.c)for(c=new Ub(n.d.i.j);c.ac.a)return-1;if(r.a(o=null==n.d?0:n.d.length)){for(h=n.d,n.d=L8(uAt,i9n,63,2*o+4,0,1),c=0;c=0x8000000000000000?(z7(),ftt):(i=!1,n<0&&(i=!0,n=-n),e=0,n>=IQn&&(n-=(e=SY(n/IQn))*IQn),t=0,n>=PQn&&(n-=(t=SY(n/PQn))*PQn),r=E$(SY(n),t,e),i&&Ion(r),r)}function dNn(n,t){var e,i,r,c;for(e=!t||!n.u.Hc((hCn(),nCt)),c=0,r=new Ub(n.e.Cf());r.a=-t&&r==t?new eC(tln(e-1),tln(r)):new eC(tln(e),tln(r-1))}function kNn(){return hWn(),Mun(Hk(cst,1),OVn,77,0,[eot,Zut,iot,mot,Kot,Eot,Got,Iot,Dot,wot,$ot,Pot,Rot,hot,Uot,Xut,Aot,Fot,yot,_ot,Wot,Not,Wut,xot,Vot,Hot,Xot,kot,uot,jot,vot,zot,Jut,cot,Mot,Qut,Sot,got,fot,Cot,bot,not,Yut,pot,lot,Oot,qot,Vut,Lot,dot,Tot,oot,aot,Bot,rot,sot,tot])}function jNn(n,t,e){n.d=0,n.b=0,t.k==(cSn(),Put)&&e.k==Put&&_B(pMn(t,(oWn(),blt)),10)==_B(pMn(e,blt),10)&&(T7(t).j==(mUn(),uCt)?B$n(n,t,e):B$n(n,e,t)),t.k==Put&&e.k==Mut?T7(t).j==(mUn(),uCt)?n.d=1:n.b=1:e.k==Put&&t.k==Mut&&(T7(e).j==(mUn(),uCt)?n.b=1:n.d=1),cmn(n,t,e)}function ENn(n){var t,e,i,r,c;return c=CTn(n),null!=n.a&&CH(c,"category",n.a),!UE(new Sb(n.d))&&(etn(c,"knownOptions",i=new Sl),t=new np(i),n5(new Sb(n.d),t)),!UE(n.g)&&(etn(c,"supportedFeatures",r=new Sl),e=new tp(r),n5(n.g,e)),c}function TNn(n){var t,e,i,r,c,a,u,o;for(t=336,e=0,r=new uR(n.length),u=0,o=(a=n).length;u>16!=7&&t){if(gkn(n,t))throw Fp(new Ry(l6n+iPn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?okn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=_B(t,49).gh(n,1,LOt,i)),(i=XG(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,7,t,t))}function INn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(gkn(n,t))throw Fp(new Ry(l6n+Xfn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?fkn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=_B(t,49).gh(n,0,KOt,i)),(i=WG(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,3,t,t))}function CNn(n,t){var e,i,r,c,a,u,o,s,h;return OOn(),t.d>n.d&&(u=n,n=t,t=u),t.d<63?zxn(n,t):(s=q5(n,a=(-2&n.d)<<4),h=q5(t,a),i=cBn(n,H5(s,a)),r=cBn(t,H5(h,a)),o=CNn(s,h),e=CNn(i,r),c=H5(c=OHn(OHn(c=CNn(cBn(s,i),cBn(r,h)),o),e),a),OHn(OHn(o=H5(o,a<<1),c),e))}function ONn(n,t,e){var i,r,c,a,u;for(a=Afn(n,e),u=L8(Iut,r1n,10,t.length,0,1),i=0,c=a.Kc();c.Ob();)By(jD(pMn(r=_B(c.Pb(),11),(oWn(),nlt))))&&(u[i++]=_B(pMn(r,klt),10));if(i=0;r+=e?1:-1)c|=t.c.Sf(u,r,e,i&&!By(jD(pMn(t.j,(oWn(),Qft))))&&!By(jD(pMn(t.j,(oWn(),Plt))))),c|=t.q._f(u,r,e),c|=wRn(n,u[r],e,i);return jU(n.c,t),c}function xNn(n,t,e){var i,r,c,a,u,o,s,h;for(s=0,h=(o=P2(n.j)).length;s1&&(n.a=!0),$G(_B(e.b,65),GR(_$(_B(t.b,65).c),mL(zR(_$(_B(e.b,65).a),_B(t.b,65).a),r))),WZ(n,t),KNn(n,e)}function _Nn(n){var t,e,i,r,c,a;for(r=new Ub(n.a.a);r.a0&&c>0?t++:i>0?e++:c>0?r++:e++}TQ(),p$(n.j,new bi)}function BNn(n){var t,e;e=null,t=_B(Lq(n.g,0),17);do{if(Ax(e=t.d.i,(oWn(),slt)))return _B(pMn(e,slt),11).i;if(e.k!=(cSn(),Sut)&&bAn(new az(JL(hbn(e).a.Kc(),new h))))t=_B(G5(new az(JL(hbn(e).a.Kc(),new h))),17);else if(e.k!=Sut)return null}while(e&&e.k!=(cSn(),Sut));return e}function HNn(n,t){var e,i,r,c,a,u,o,s,h;for(u=t.j,a=t.g,o=_B(Lq(u,u.c.length-1),113),h1(0,u.c.length),s=Jmn(n,a,o,h=_B(u.c[0],113)),c=1;cs&&(o=e,h=r,s=i);t.a=h,t.c=o}function qNn(n,t){var e;if(!JU(n.b,t.b))throw Fp(new Ky("Invalid hitboxes for scanline constraint calculation."));(mun(t.b,_B(ER(n.b,t.b),57))||mun(t.b,_B(jR(n.b,t.b),57)))&&(OT(),t.b),n.a[t.b.f]=_B(mK(n.b,t.b),57),(e=_B(vK(n.b,t.b),57))&&(n.a[e.f]=t.b)}function GNn(n){if(!n.a.d||!n.a.e)throw Fp(new Ky((kD(Fit),Fit.k+" must have a source and target "+(kD(Bit),Bit.k+" specified."))));if(n.a.d==n.a.e)throw Fp(new Ky("Network simplex does not support self-loops: "+n.a+" "+n.a.d+" "+n.a.e));return xN(n.a.d.g,n.a),xN(n.a.e.b,n.a),n.a}function zNn(n,t,e){var i,r,c,a,u,o,s;for(s=new bE(new Qd(n)),u=0,o=(a=Mun(Hk(Hut,1),c1n,11,0,[t,e])).length;uo-n.b&&uo-n.a&&u0&&++l;++f}return l}function ixn(n,t){var e,i,r,c,a;for(a=_B(pMn(t,(SAn(),Akt)),425),c=upn(t.b,0);c.b!=c.d.c;)if(r=_B(f3(c),86),0==n.b[r.g]){switch(a.g){case 0:Wvn(n,r);break;case 1:FAn(n,r)}n.b[r.g]=2}for(i=upn(n.a,0);i.b!=i.d.c;)vwn((e=_B(f3(i),188)).b.d,e,!0),vwn(e.c.b,e,!0);oon(t,(Bqn(),hkt),n.a)}function rxn(n,t){var e,i,r,c;return JM(),t?t==(Gqn(),xLt)||(t==pLt||t==dLt||t==gLt)&&n!=wLt?new iUn(n,t):((e=(i=_B(t,677)).pk())||(mV(_7((PPn(),Q$t),t)),e=i.pk()),!e.i&&(e.i=new Lp),!(r=_B(BC(CJ((c=e.i).f,n)),1942))&&XW(c,n,r=new iUn(n,t)),r):iLt}function cxn(n,t){var e,i,r,c,a,u,o,s;for(u=_B(pMn(n,(oWn(),blt)),11),o=Con(Mun(Hk(MMt,1),uVn,8,0,[u.i.n,u.n,u.a])).a,s=n.i.n.b,r=0,c=(i=J0(n.e)).length;r0?c.a?e>(u=c.b.rf().a)&&(r=(e-u)/2,c.d.b=r,c.d.c=r):c.d.c=n.s+e:Fz(n.u)&&((i=RTn(c.b)).c<0&&(c.d.b=-i.c),i.c+i.b>c.b.rf().a&&(c.d.c=i.c+i.b-c.b.rf().a))}function sxn(n,t){var e,i;for(ITn(t,"Semi-Interactive Crossing Minimization Processor",1),e=!1,i=new Ub(n.b);i.a=0){if(t==e)return new eC(tln(-t-1),tln(-t-1));if(t==-e)return new eC(tln(-t),tln(e+1))}return i.Math.abs(t)>i.Math.abs(e)?new eC(tln(-t),tln(t<0?e:e+1)):new eC(tln(t+1),tln(e))}function lxn(n){var t,e;e=_B(pMn(n,(FXn(),mgt)),163),t=_B(pMn(n,(oWn(),tlt)),303),e==(jbn(),Klt)?(oon(n,mgt,Blt),oon(n,tlt,(q7(),Sft))):e==Flt?(oon(n,mgt,Blt),oon(n,tlt,(q7(),Tft))):t==(q7(),Sft)?(oon(n,mgt,Klt),oon(n,tlt,Mft)):t==Tft&&(oon(n,mgt,Flt),oon(n,tlt,Mft))}function bxn(){bxn=O,yyt=new oa,gyt=bq(new _2,(vMn(),Rat),(hWn(),yot)),myt=UG(bq(new _2,Rat,Not),_at,Lot),kyt=agn(agn(KM(UG(bq(new _2,xat,Got),_at,qot),Kat),Hot),zot),pyt=UG(bq(bq(bq(new _2,Dat,Eot),Kat,Mot),Kat,Sot),_at,Tot),vyt=UG(bq(bq(new _2,Kat,Sot),Kat,cot),_at,rot)}function wxn(){wxn=O,Syt=bq(UG(new _2,(vMn(),_at),(hWn(),oot)),Rat,yot),Oyt=agn(agn(KM(UG(bq(new _2,xat,Got),_at,qot),Kat),Hot),zot),Pyt=UG(bq(bq(bq(new _2,Dat,Eot),Kat,Mot),Kat,Sot),_at,Tot),Cyt=bq(bq(new _2,Rat,Not),_at,Lot),Iyt=UG(bq(bq(new _2,Kat,Sot),Kat,cot),_at,rot)}function dxn(n,t,e,i,r){var c,a;(f5(t)||t.c.i.c!=t.d.i.c)&&Yin(Con(Mun(Hk(MMt,1),uVn,8,0,[r.i.n,r.n,r.a])),e)||f5(t)||(t.c==r?Dx(t.a,0,new lA(e)):NH(t.a,new lA(e)),i&&!KT(n.a,e)&&((a=_B(pMn(t,(FXn(),ggt)),74))||(a=new mm,oon(t,ggt,a)),e5(a,c=new lA(e),a.c.b,a.c),jU(n.a,c)))}function gxn(n){var t;for(t=new az(JL(sbn(n).a.Kc(),new h));bAn(t);)if(_B(G5(t),17).c.i.k!=(cSn(),Tut))throw Fp(new ek(M1n+wyn(n)+"' has its layer constraint set to FIRST, but has at least one incoming edge that does not come from a FIRST_SEPARATE node. That must not happen."))}function pxn(n,t,e){var i,r,c,a,u,o;if(0==(r=dbn(254&n.Db)))n.Eb=e;else{if(1==r)a=L8(Cnt,FWn,1,2,5,1),0==xmn(n,t)?(a[0]=e,a[1]=n.Eb):(a[0]=n.Eb,a[1]=e);else for(a=L8(Cnt,FWn,1,r+1,5,1),c=nen(n.Eb),i=2,u=0,o=0;i<=128;i<<=1)i==t?a[o++]=e:0!=(n.Db&i)&&(a[o++]=c[u++]);n.Eb=a}n.Db|=t}function vxn(n,t,e){var r,c,a,u;for(this.b=new $p,c=0,r=0,u=new Ub(n);u.a0&&(c+=(a=_B(Lq(this.b,0),167)).o,r+=a.p),c*=2,r*=2,t>1?c=SY(i.Math.ceil(c*t)):r=SY(i.Math.ceil(r/t)),this.a=new Bwn(c,r)}function mxn(n,t,e,r,c,a){var u,o,s,h,f,l,b,w,d,g;for(h=r,t.j&&t.o?(d=(b=_B(xX(n.f,t.A),57)).d.c+b.d.b,--h):d=t.a.c+t.a.b,f=c,e.q&&e.o?(s=(b=_B(xX(n.f,e.C),57)).d.c,++f):s=e.a.c,w=d+(o=(s-d)/i.Math.max(2,f-h)),l=h;l=0;a+=r?1:-1){for(u=t[a],o=i==(mUn(),aCt)?r?rbn(u,i):nan(rbn(u,i)):r?nan(rbn(u,i)):rbn(u,i),c&&(n.c[u.p]=o.gc()),f=o.Kc();f.Ob();)h=_B(f.Pb(),11),n.d[h.p]=s++;wun(e,o)}}function kxn(n,t,e){var i,r,c,a,u,o,s,h;for(c=Hy(ED(n.b.Kc().Pb())),s=Hy(ED(Uan(t.b))),i=mL(_$(n.a),s-e),r=mL(_$(t.a),e-c),mL(h=GR(i,r),1/(s-c)),this.a=h,this.b=new $p,u=!0,(a=n.b.Kc()).Pb();a.Ob();)o=Hy(ED(a.Pb())),u&&o-e>N3n&&(this.b.Fc(e),u=!1),this.b.Fc(o);u&&this.b.Fc(e)}function jxn(n){var t,e,i,r;if(oKn(n,n.n),n.d.c.length>0){for(Yy(n.c);dAn(n,_B(Y1(new Ub(n.e.a)),121))>5,t&=31,i>=n.d)return n.e<0?(IDn(),Vtt):(IDn(),net);if(c=n.d-i,WSn(r=L8(INt,oQn,25,c+1,15,1),c,n.a,i,t),n.e<0){for(e=0;e0&&n.a[e]<<32-t!=0){for(e=0;e=0)&&(!(e=Kqn((PPn(),Q$t),r,t))||((i=e.Zj())>1||-1==i)&&3!=NW(_7(Q$t,e))))}function Axn(n,t,e,i){var r,c,a,u,o;return u=MTn(_B(Utn((!t.b&&(t.b=new oK(xOt,t,4,7)),t.b),0),82)),o=MTn(_B(Utn((!t.c&&(t.c=new oK(xOt,t,5,8)),t.c),0),82)),QY(u)==QY(o)||Stn(o,u)?null:(a=zY(t))==e?i:(c=_B(xX(n.a,a),10))&&(r=c.e)?r:null}function $xn(n,t){var e;switch(ITn(t,"Label side selection ("+(e=_B(pMn(n,(FXn(),Qdt)),276))+")",1),e.g){case 0:jAn(n,(zyn(),yIt));break;case 1:jAn(n,(zyn(),kIt));break;case 2:uBn(n,(zyn(),yIt));break;case 3:uBn(n,(zyn(),kIt));break;case 4:cDn(n,(zyn(),yIt));break;case 5:cDn(n,(zyn(),kIt))}FSn(t)}function Lxn(n,t,e){var i,r,c,a,u;if((c=n[hj(e,n.length)])[0].k==(cSn(),Eut))for(r=sj(e,c.length),u=t.j,i=0;i0&&(e[0]+=n.d,u-=e[0]),e[2]>0&&(e[2]+=n.d,u-=e[2]),a=i.Math.max(0,u),e[1]=i.Math.max(e[1],u),V5(n,qit,c.c+r.b+e[0]-(e[1]-u)/2,e),t==qit&&(n.c.b=a,n.c.c=c.c+r.b+(a-u)/2)}function Wxn(){this.c=L8($Nt,BQn,25,(mUn(),Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt])).length,15,1),this.b=L8($Nt,BQn,25,Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt]).length,15,1),this.a=L8($Nt,BQn,25,Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt]).length,15,1),pS(this.c,xQn),pS(this.b,DQn),pS(this.a,DQn)}function Vxn(n,t,e){var i,r,c,a;if(t<=e?(r=t,c=e):(r=e,c=t),i=0,null==n.b)n.b=L8(INt,oQn,25,2,15,1),n.b[0]=r,n.b[1]=c,n.c=!0;else{if(i=n.b.length,n.b[i-1]+1==r)return void(n.b[i-1]=c);a=L8(INt,oQn,25,i+2,15,1),rHn(n.b,0,a,0,i),n.b=a,n.b[i-1]>=r&&(n.c=!1,n.a=!1),n.b[i++]=r,n.b[i]=c,n.c||j$n(n)}}function Qxn(n,t,e){var i,r,c,a,u,o,s;for(s=t.d,n.a=new Q6(s.c.length),n.c=new Lp,u=new Ub(s);u.a=0?n._g(s,!1,!0):iOn(n,e,!1),58).Kc();c.Ob();){for(r=_B(c.Pb(),56),h=0;h1;)sDn(r,r.i-1);return i}function rDn(n,t){var e,i,r,c,a,u,o;for(ITn(t,"Comment post-processing",1),c=new Ub(n.b);c.an.d[a.p]&&(e+=Y4(n.b,c),b3(n.a,tln(c)));for(;!Uy(n.a);)Enn(n.b,_B(bU(n.a),19).a)}return e}function oDn(n,t,e){var i,r,c,a;for(c=(!t.a&&(t.a=new nU(qOt,t,10,11)),t.a).i,r=new CL((!t.a&&(t.a=new nU(qOt,t,10,11)),t.a));r.e!=r.i.gc();)0==(!(i=_B(mpn(r),33)).a&&(i.a=new nU(qOt,i,10,11)),i.a).i||(c+=oDn(n,i,!1));if(e)for(a=QY(t);a;)c+=(!a.a&&(a.a=new nU(qOt,a,10,11)),a.a).i,a=QY(a);return c}function sDn(n,t){var e,i,r,c;return n.ej()?(i=null,r=n.fj(),n.ij()&&(i=n.kj(n.pi(t),null)),e=n.Zi(4,c=Ayn(n,t),null,t,r),n.bj()&&null!=c?(i=n.dj(c,i))?(i.Ei(e),i.Fi()):n.$i(e):i?(i.Ei(e),i.Fi()):n.$i(e),c):(c=Ayn(n,t),n.bj()&&null!=c&&(i=n.dj(c,null))&&i.Fi(),c)}function hDn(n){var t,e,r,c,a,u,o,s,h,f;for(h=n.a,t=new xv,s=0,r=new Ub(n.d);r.ao.d&&(f=o.d+o.a+h));e.c.d=f,t.a.zc(e,t),s=i.Math.max(s,e.c.d+e.c.a)}return s}function fDn(){fDn=O,oft=new AP("COMMENTS",0),hft=new AP("EXTERNAL_PORTS",1),fft=new AP("HYPEREDGES",2),lft=new AP("HYPERNODES",3),bft=new AP("NON_FREE_PORTS",4),wft=new AP("NORTH_SOUTH_PORTS",5),gft=new AP(H1n,6),uft=new AP("CENTER_LABELS",7),sft=new AP("END_LABELS",8),dft=new AP("PARTITIONS",9)}function lDn(n){var t,e,i,r,c;for(r=new $p,t=new Oq((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a)),i=new az(JL(bLn(n).a.Kc(),new h));bAn(i);)iL(Utn((!(e=_B(G5(i),79)).b&&(e.b=new oK(xOt,e,4,7)),e.b),0),186)||(c=MTn(_B(Utn((!e.c&&(e.c=new oK(xOt,e,5,8)),e.c),0),82)),t.a._b(c)||(r.c[r.c.length]=c));return r}function bDn(n){var t,e,i,r,c;for(r=new xv,t=new Oq((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a)),i=new az(JL(bLn(n).a.Kc(),new h));bAn(i);)iL(Utn((!(e=_B(G5(i),79)).b&&(e.b=new oK(xOt,e,4,7)),e.b),0),186)||(c=MTn(_B(Utn((!e.c&&(e.c=new oK(xOt,e,5,8)),e.c),0),82)),t.a._b(c)||r.a.zc(c,r));return r}function wDn(n,t,e,i,r){return i<0?((i=qTn(n,r,Mun(Hk(Wtt,1),uVn,2,6,[VVn,QVn,JVn,YVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn]),t))<0&&(i=qTn(n,r,Mun(Hk(Wtt,1),uVn,2,6,["Jan","Feb","Mar","Apr",ZVn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}function dDn(n,t,e,i,r){return i<0?((i=qTn(n,r,Mun(Hk(Wtt,1),uVn,2,6,[VVn,QVn,JVn,YVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn]),t))<0&&(i=qTn(n,r,Mun(Hk(Wtt,1),uVn,2,6,["Jan","Feb","Mar","Apr",ZVn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}function gDn(n,t,e,i,r,c){var a,u,o;if(u=32,i<0){if(t[0]>=n.length)return!1;if(43!=(u=sV(n,t[0]))&&45!=u)return!1;if(++t[0],(i=GCn(n,t))<0)return!1;45==u&&(i=-i)}return 32==u&&t[0]-e==2&&2==r.b&&(a=(o=(new CT).q.getFullYear()-uQn+uQn-80)%100,c.a=i==a,i+=100*(o/100|0)+(i=h&&(s=r);s&&(f=i.Math.max(f,s.a.o.a)),f>b&&(l=h,b=f)}return l}function EDn(n,t,e){var i,r,c;if(n.e=e,n.d=0,n.b=0,n.f=1,n.i=t,16==(16&n.e)&&(n.i=dKn(n.i)),n.j=n.i.length,WXn(n),c=Xdn(n),n.d!=n.j)throw Fp(new rk(mWn((c$(),l8n))));if(n.g){for(i=0;id4n?p$(s,n.b):r<=d4n&&r>g4n?p$(s,n.d):r<=g4n&&r>p4n?p$(s,n.c):r<=p4n&&p$(s,n.a),a=PDn(n,s,a);return c}function IDn(){var n;for(IDn=O,Qtt=new z6(1,1),Ytt=new z6(1,10),net=new z6(0,0),Vtt=new z6(-1,1),Jtt=Mun(Hk(aet,1),uVn,91,0,[net,Qtt,new z6(1,2),new z6(1,3),new z6(1,4),new z6(1,5),new z6(1,6),new z6(1,7),new z6(1,8),new z6(1,9),Ytt]),Ztt=L8(aet,uVn,91,32,0,1),n=0;n1&&(i=new LI(r,e.b),NH(t.a,i)),Yen(t.a,Mun(Hk(MMt,1),uVn,8,0,[f,h]))}function xDn(n){$M(n,new ETn(gj(lj(dj(wj(new du,R5n),"ELK Randomizer"),'Distributes the nodes randomly on the plane, leading to very obfuscating layouts. Can be useful to demonstrate the power of "real" layout algorithms.'),new Qu))),c2(n,R5n,WYn,ACt),c2(n,R5n,gZn,15),c2(n,R5n,vZn,tln(0)),c2(n,R5n,XYn,bZn)}function DDn(){var n,t,e,i,r,c;for(DDn=O,XLt=L8(ANt,g6n,25,255,15,1),WLt=L8(PNt,UVn,25,16,15,1),t=0;t<255;t++)XLt[t]=-1;for(e=57;e>=48;e--)XLt[e]=e-48<<24>>24;for(i=70;i>=65;i--)XLt[i]=i-65+10<<24>>24;for(r=102;r>=97;r--)XLt[r]=r-97+10<<24>>24;for(c=0;c<10;c++)WLt[c]=48+c&WVn;for(n=10;n<=15;n++)WLt[n]=65+n-10&WVn}function RDn(n,t,e){var i,r,c,a,u,o,s,h;return u=t.i-n.g/2,o=e.i-n.g/2,s=t.j-n.g/2,h=e.j-n.g/2,c=t.g+n.g/2,a=e.g+n.g/2,i=t.f+n.g/2,r=e.f+n.g/2,u>19!=0)return"-"+HDn(ron(n));for(e=n,i="";0!=e.l||0!=e.m||0!=e.h;){if(e=Cqn(e,K5(CQn),!0),t=""+jE(htt),0!=e.l||0!=e.m||0!=e.h)for(r=9-t.length;r>0;r--)t="0"+t;i=t+i}return i}function qDn(){if(!Object.create||!Object.getOwnPropertyNames)return!1;var n="__proto__",t=Object.create(null);return void 0===t[n]&&0==Object.getOwnPropertyNames(t).length&&(t[n]=42,42===t[n]&&0!=Object.getOwnPropertyNames(t).length)}function GDn(n){var t,e,i,r,c,a,u;for(t=!1,e=0,r=new Ub(n.d.b);r.a=n.a)return-1;if(!nTn(t,e))return-1;if(o3(_B(r.Kb(t),20)))return 1;for(c=0,u=_B(r.Kb(t),20).Kc();u.Ob();){if(-1==(o=XDn(n,(a=_B(u.Pb(),17)).c.i==t?a.d.i:a.c.i,e,r)))return-1;if((c=i.Math.max(c,o))>n.c-1)return-1}return c+1}function WDn(n,t){var e,i,r,c,a,u;if(HC(t)===HC(n))return!0;if(!iL(t,15))return!1;if(i=_B(t,15),u=n.gc(),i.gc()!=u)return!1;if(a=i.Kc(),n.ni()){for(e=0;e0)if(n.qj(),null!=t){for(c=0;c>24;case 97:case 98:case 99:case 100:case 101:case 102:return n-97+10<<24>>24;case 65:case 66:case 67:case 68:case 69:case 70:return n-65+10<<24>>24;default:throw Fp(new Ek("Invalid hexadecimal"))}}function YDn(n,t,e){var i,r,c,a;for(ITn(e,"Processor order nodes",2),n.a=Hy(ED(pMn(t,(SAn(),Lkt)))),r=new VT,a=upn(t.b,0);a.b!=a.d.c;)By(jD(pMn(c=_B(f3(a),86),(Bqn(),bkt))))&&e5(r,c,r.c.b,r.c);Mx(0!=r.b),DHn(n,i=_B(r.a.a.c,86)),!e.b&&Bin(e,1),_Rn(n,i,0-Hy(ED(pMn(i,(Bqn(),ckt))))/2,0),!e.b&&Bin(e,1),FSn(e)}function ZDn(){ZDn=O,xit=new FS("SPIRAL",0),Oit=new FS("LINE_BY_LINE",1),Ait=new FS("MANHATTAN",2),Cit=new FS("JITTER",3),Lit=new FS("QUADRANTS_LINE_BY_LINE",4),Nit=new FS("QUADRANTS_MANHATTAN",5),$it=new FS("QUADRANTS_JITTER",6),Iit=new FS("COMBINE_LINE_BY_LINE_MANHATTAN",7),Pit=new FS("COMBINE_JITTER_MANHATTAN",8)}function nRn(n,t,e,i){var r,c,a,u,o,s;for(o=$jn(n,e),s=$jn(t,e),r=!1;o&&s&&(i||pyn(o,s,e));)a=$jn(o,e),u=$jn(s,e),C7(t),C7(n),c=o.c,eGn(o,!1),eGn(s,!1),e?(Wyn(t,s.p,c),t.p=s.p,Wyn(n,o.p+1,c),n.p=o.p):(Wyn(n,o.p,c),n.p=o.p,Wyn(t,s.p+1,c),t.p=s.p),MZ(o,null),MZ(s,null),o=a,s=u,r=!0;return r}function tRn(n,t,e,i){var r,c,a,u,o;for(r=!1,c=!1,u=new Ub(i.j);u.a=t.length)throw Fp(new Cy("Greedy SwitchDecider: Free layer not in graph."));this.c=t[n],this.e=new WK(i),vrn(this.e,this.c,(mUn(),SCt)),this.i=new WK(i),vrn(this.i,this.c,aCt),this.f=new hG(this.c),this.a=!c&&r.i&&!r.s&&this.c[0].k==(cSn(),Eut),this.a&&wPn(this,n,t.length)}function aRn(n,t){var e,i,r,c,a,u;c=!n.B.Hc((YKn(),FCt)),a=n.B.Hc(qCt),n.a=new Fwn(a,c,n.c),n.n&&mQ(n.a.n,n.n),yy(n.g,(Ntn(),qit),n.a),t||((i=new Pgn(1,c,n.c)).n.a=n.k,pG(n.p,(mUn(),uCt),i),(r=new Pgn(1,c,n.c)).n.d=n.k,pG(n.p,TCt,r),(u=new Pgn(0,c,n.c)).n.c=n.k,pG(n.p,SCt,u),(e=new Pgn(0,c,n.c)).n.b=n.k,pG(n.p,aCt,e))}function uRn(n){var t,e,i;switch((t=_B(pMn(n.d,(FXn(),Jdt)),218)).g){case 2:e=EXn(n);break;case 3:i=new $p,QT(CV(OV(lnn(lnn(new xq(null,new l1(n.d.b,16)),new Or),new Ar),new $r),new pr),new Sd(i)),e=i;break;default:throw Fp(new Ky("Compaction not supported for "+t+" edges."))}wqn(n,e),n5(new Sb(n.g),new Td(n))}function oRn(n,t){var e;return e=new Zn,t&&Ban(e,_B(xX(n.a,LOt),94)),iL(t,470)&&Ban(e,_B(xX(n.a,NOt),94)),iL(t,354)?(Ban(e,_B(xX(n.a,HOt),94)),e):(iL(t,82)&&Ban(e,_B(xX(n.a,xOt),94)),iL(t,239)?(Ban(e,_B(xX(n.a,qOt),94)),e):iL(t,186)?(Ban(e,_B(xX(n.a,GOt),94)),e):(iL(t,352)&&Ban(e,_B(xX(n.a,DOt),94)),e))}function sRn(){sRn=O,Jct=new zA((uWn(),dPt),tln(1)),iat=new zA(APt,80),eat=new zA(TPt,5),Kct=new zA(iSt,bZn),Yct=new zA(gPt,tln(1)),tat=new zA(mPt,(oN(),!0)),Wct=new UA(50),Xct=new zA(zSt,Wct),Fct=SSt,Vct=cPt,_ct=new zA(bSt,!1),Uct=GSt,zct=BSt,Gct=DSt,qct=NSt,Qct=sPt,ySn(),Hct=Pct,rat=$ct,Bct=Sct,Zct=Cct,nat=Act}function hRn(n){var t,e,i,r,c,a,u;for(u=new g5,a=new Ub(n.a);a.a0&&t=0)return!1;if(t.p=e.b,UB(e.e,t),i==(cSn(),Mut)||i==Put)for(r=new Ub(t.j);r.a1||-1==a)&&(c|=16),0!=(r.Bb&o6n)&&(c|=64)),0!=(e.Bb&_Qn)&&(c|=E9n),c|=m6n):iL(t,457)?c|=512:(i=t.Bj())&&0!=(1&i.i)&&(c|=256),0!=(512&n.Bb)&&(c|=128),c}function ORn(n,t){var e,i,r,c,a;for(n=null==n?qWn:(mW(n),n),r=0;rn.d[u.p]&&(e+=Y4(n.b,c),b3(n.a,tln(c))):++a;for(e+=n.b.d*a;!Uy(n.a);)Enn(n.b,_B(bU(n.a),19).a)}return e}function LRn(n,t){var e;return n.f==rLt?(e=NW(_7((PPn(),Q$t),t)),n.e?4==e&&t!=(jOn(),oLt)&&t!=(jOn(),cLt)&&t!=(jOn(),aLt)&&t!=(jOn(),uLt):2==e):!(!n.d||!(n.d.Hc(t)||n.d.Hc(J1(_7((PPn(),Q$t),t)))||n.d.Hc(Kqn((PPn(),Q$t),n.b,t))))||!(!n.f||!rNn((PPn(),n.f),yV(_7(Q$t,t))))&&(e=NW(_7(Q$t,t)),n.e?4==e:2==e)}function NRn(n,t,e,r){var c,a,u,o,s,h,f,l;return s=(u=_B(JAn(e,(uWn(),wPt)),8)).a,f=u.b+n,(c=i.Math.atan2(f,s))<0&&(c+=J3n),(c+=t)>J3n&&(c-=J3n),h=(o=_B(JAn(r,wPt),8)).a,l=o.b+n,(a=i.Math.atan2(l,h))<0&&(a+=J3n),(a+=t)>J3n&&(a-=J3n),o$(),ein(1e-10),i.Math.abs(c-a)<=1e-10||c==a||isNaN(c)&&isNaN(a)?0:ca?1:qO(isNaN(c),isNaN(a))}function xRn(n){var t,e,i,r,c,a,u;for(u=new Lp,i=new Ub(n.a.b);i.a=n.o)throw Fp(new Tv);a=t>>5,c=vz(1,bG(vz(31&t,1))),n.n[e][a]=r?t0(n.n[e][a],c):n0(n.n[e][a],cH(c)),c=vz(c,1),n.n[e][a]=i?t0(n.n[e][a],c):n0(n.n[e][a],cH(c))}catch(u){throw iL(u=hun(u),320)?Fp(new Cy(EYn+n.o+"*"+n.p+TYn+t+KWn+e+MYn)):Fp(u)}}function _Rn(n,t,e,r){var c,a;t&&(c=Hy(ED(pMn(t,(Bqn(),skt))))+r,a=e+Hy(ED(pMn(t,ckt)))/2,oon(t,wkt,tln(bG(san(i.Math.round(c))))),oon(t,dkt,tln(bG(san(i.Math.round(a))))),0==t.d.b||_Rn(n,_B(tL(new lg(upn(new fg(t).a.d,0))),86),e+Hy(ED(pMn(t,ckt)))+n.a,r+Hy(ED(pMn(t,akt)))),null!=pMn(t,lkt)&&_Rn(n,_B(pMn(t,lkt),86),e,r))}function FRn(n,t){var e,r,c,a,u,o,s,h,f,l,b;for(c=2*Hy(ED(pMn(s=gW(t.a),(FXn(),jpt)))),f=Hy(ED(pMn(s,Cpt))),h=i.Math.max(c,f),a=L8($Nt,BQn,25,t.f-t.c+1,15,1),r=-h,e=0,o=t.b.Kc();o.Ob();)u=_B(o.Pb(),10),r+=n.a[u.c.p]+h,a[e++]=r;for(r+=n.a[t.a.c.p]+h,a[e++]=r,b=new Ub(t.e);b.a0&&(!(i=(!n.n&&(n.n=new nU(HOt,n,1,7)),_B(Utn(n.n,0),137)).a)||aO(aO((t.a+=' "',t),i),'"'))),aO(mE(aO(mE(aO(mE(aO(mE((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function GRn(n){var t,e,i;return 0!=(64&n.Db)?pSn(n):(t=new hN(Z5n),(e=n.k)?aO(aO((t.a+=' "',t),e),'"'):(!n.n&&(n.n=new nU(HOt,n,1,7)),n.n.i>0&&(!(i=(!n.n&&(n.n=new nU(HOt,n,1,7)),_B(Utn(n.n,0),137)).a)||aO(aO((t.a+=' "',t),i),'"'))),aO(mE(aO(mE(aO(mE(aO(mE((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function zRn(n,t){var e,i,r,c,a,u;if(null==t||0==t.length)return null;if(!(r=_B(TY(n.a,t),149))){for(i=new Db(new Ib(n.b).a.vc().Kc());i.a.Ob();)if(c=_B(i.a.Pb(),42),a=(e=_B(c.dd(),149)).c,u=t.length,pK(a.substr(a.length-u,u),t)&&(t.length==a.length||46==sV(a,a.length-t.length-1))){if(r)return null;r=e}r&&pZ(n.a,t,r)}return r}function URn(n,t){var e,i,r;return e=new xn,(i=_B(M4(OV(new xq(null,new l1(n.f,16)),e),L7(new Q,new J,new cn,new an,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),zet),Get]))),21).gc())<(r=_B(M4(OV(new xq(null,new l1(t.f,16)),e),L7(new Q,new J,new cn,new an,Mun(Hk(Yet,1),OVn,132,0,[zet,Get]))),21).gc())?-1:i==r?0:1}function XRn(n){var t,e,i;Ax(n,(FXn(),Ogt))&&((i=_B(pMn(n,Ogt),21)).dc()||(e=new VK(t=_B(Xj(HIt),9),_B(TR(t,t.length),9),0),i.Hc((YAn(),OIt))?arn(e,OIt):arn(e,AIt),i.Hc(IIt)||arn(e,IIt),i.Hc(PIt)?arn(e,NIt):i.Hc(SIt)?arn(e,LIt):i.Hc(CIt)&&arn(e,$It),i.Hc(NIt)?arn(e,PIt):i.Hc(LIt)?arn(e,SIt):i.Hc($It)&&arn(e,CIt),oon(n,Ogt,e)))}function WRn(n){var t,e,i,r,c,a,u;for(r=_B(pMn(n,(oWn(),elt)),10),h1(0,(i=n.j).c.length),e=_B(i.c[0],11),a=new Ub(r.j);a.ar.p?(BIn(c,TCt),c.d&&(u=c.o.b,t=c.a.b,c.a.b=u-t)):c.j==TCt&&r.p>n.p&&(BIn(c,uCt),c.d&&(u=c.o.b,t=c.a.b,c.a.b=-(u-t)));break}return r}function VRn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w;if(c=e,e1&&(i=new LI(r,e.b),NH(t.a,i)),Yen(t.a,Mun(Hk(MMt,1),uVn,8,0,[f,h]))}function wKn(n,t,e){var i,r,c,a,u,o;if(t){if(e<=-1){if(iL(i=ttn(t.Tg(),-1-e),99))return _B(i,18);for(u=0,o=(a=_B(t.ah(i),153)).gc();u0){for(r=o.length;r>0&&""==o[r-1];)--r;r=40)&&kFn(n),_Hn(n),jxn(n),e=vln(n),i=0;e&&i0&&NH(n.f,c)):(n.c[a]-=s+1,n.c[a]<=0&&n.a[a]>0&&NH(n.e,c))))}function VKn(n){var t,e,i,r,c,a,u;for(c=new bE(_B(vX(new Rn),62)),u=DQn,e=new Ub(n.d);e.a=0&&oe?t:e;s<=f;++s)s==e?u=i++:(c=r[s],h=w.rl(c.ak()),s==t&&(o=s!=f||h?i:i-1),h&&++i);return l=_B(Pln(n,t,e),72),u!=o&&Av(n,new y9(n.e,7,a,tln(u),b.dd(),o)),l}return _B(Pln(n,t,e),72)}function c_n(n,t){var e,i,r,c,a,u;for(ITn(t,"Port order processing",1),u=_B(pMn(n,(FXn(),apt)),421),e=new Ub(n.b);e.a=0&&(!Syn(n,a)||(o<22?u.l|=1<>>1,a.m=s>>>1|(1&h)<<21,a.l=f>>>1|(1&s)<<21,--o;return e&&Ion(u),c&&(i?(htt=ron(n),r&&(htt=oun(htt,(z7(),btt)))):htt=E$(n.l,n.m,n.h)),u}function s_n(n,t){var e,i,r,c,a,u,o,s,h,f;for(s=n.e[t.c.p][t.p]+1,o=t.c.a.c.length+1,u=new Ub(n.a);u.a0&&(f1(0,n.length),45==n.charCodeAt(0)||(f1(0,n.length),43==n.charCodeAt(0)))?1:0;ie)throw Fp(new Ek(NQn+n+'"'));return a}function f_n(n){var t,e,r,c,a,u;for(a=new VT,c=new Ub(n.a);c.a1)&&1==t&&_B(n.a[n.b],10).k==(cSn(),Tut)?oFn(_B(n.a[n.b],10),(zyn(),yIt)):i&&(!e||(n.c-n.b&n.a.length-1)>1)&&1==t&&_B(n.a[n.c-1&n.a.length-1],10).k==(cSn(),Tut)?oFn(_B(n.a[n.c-1&n.a.length-1],10),(zyn(),kIt)):2==(n.c-n.b&n.a.length-1)?(oFn(_B(kon(n),10),(zyn(),yIt)),oFn(_B(kon(n),10),kIt)):uLn(n,r),a4(n)}function g_n(n,t,e){var r,c,a,u,o;for(a=0,c=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));c.e!=c.i.gc();)u="",0==(!(r=_B(mpn(c),33)).n&&(r.n=new nU(HOt,r,1,7)),r.n).i||(u=_B(Utn((!r.n&&(r.n=new nU(HOt,r,1,7)),r.n),0),137).a),Ban(o=new isn(a++,t,u),r),oon(o,(Bqn(),ukt),r),o.e.b=r.j+r.f/2,o.f.a=i.Math.max(r.g,1),o.e.a=r.i+r.g/2,o.f.b=i.Math.max(r.f,1),NH(t.b,o),yIn(e.f,r,o)}function p_n(n){var t,e,i,r,c;i=_B(pMn(n,(oWn(),blt)),33),c=_B(JAn(i,(FXn(),Kgt)),174).Hc((pdn(),RCt)),n.e||(r=_B(pMn(n,Jft),21),t=new LI(n.f.a+n.d.b+n.d.c,n.f.b+n.d.d+n.d.a),r.Hc((fDn(),hft))?(Vpn(i,npt,(WEn(),zIt)),DUn(i,t.a,t.b,!1,!0)):By(jD(JAn(i,_gt)))||DUn(i,t.a,t.b,!0,!0)),Vpn(i,Kgt,c?Yln(RCt):new VK(e=_B(Xj(VCt),9),_B(TR(e,e.length),9),0))}function v_n(n,t,e){var i,r,c,a;if(t[0]>=n.length)return e.o=0,!0;switch(sV(n,t[0])){case 43:r=1;break;case 45:r=-1;break;default:return e.o=0,!0}if(++t[0],c=t[0],0==(a=GCn(n,t))&&t[0]==c)return!1;if(t[0]=0&&u!=e&&(c=new Yz(n,1,u,a,null),i?i.Ei(c):i=c),e>=0&&(c=new Yz(n,1,e,u==e?a:null,t),i?i.Ei(c):i=c)),i}function E_n(n){var t,e,i;if(null==n.b){if(i=new Tk,null!=n.i&&(iO(i,n.i),i.a+=":"),0!=(256&n.f)){for(0!=(256&n.f)&&null!=n.a&&(eQ(n.i)||(i.a+="//"),iO(i,n.a)),null!=n.d&&(i.a+="/",iO(i,n.d)),0!=(16&n.f)&&(i.a+="/"),t=0,e=n.j.length;ts)&&(o+u+iHn(i,s,!1).a<=t.b&&(d9(e,c-e.s),e.c=!0,d9(i,c-e.s),jvn(i,e.s,e.t+e.d+u),i.k=!0,Lcn(e.q,i),h=!0,r&&(Zen(t,i),i.j=t,n.c.length>a&&(jkn((h1(a,n.c.length),_B(n.c[a],200)),i),0==(h1(a,n.c.length),_B(n.c[a],200)).a.c.length&&u6(n,a)))),h)}function O_n(n,t){var e,i,r,c,a;if(ITn(t,"Partition midprocessing",1),r=new dY,QT(CV(new xq(null,new l1(n.a,16)),new di),new hd(r)),0!=r.d){for(a=_B(M4(r1(new xq(null,(r.i||(r.i=new FL(r,r.c))).Nc())),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),Get)]))),15),e=_B((i=a.Kc()).Pb(),19);i.Ob();)c=_B(i.Pb(),19),zLn(_B(o6(r,e),21),_B(o6(r,c),21)),e=c;FSn(t)}}function A_n(n,t,e){var i,r,c,a,u;if(0==t.p){for(t.p=1,(r=e)||(r=new eC(new $p,new VK(i=_B(Xj(KCt),9),_B(TR(i,i.length),9),0))),_B(r.a,15).Fc(t),t.k==(cSn(),Eut)&&_B(r.b,21).Fc(_B(pMn(t,(oWn(),Wft)),61)),a=new Ub(t.j);a.a0)if(r=_B(n.Ab.g,1934),null==t){for(c=0;c1)for(i=new Ub(r);i.ae.s&&oa&&(a=r,s.c=L8(Cnt,FWn,1,0,5,1)),r==a&&UB(s,new eC(e.c.i,e)));TQ(),p$(s,n.c),mG(n.b,u.p,s)}}function B_n(n,t){var e,i,r,c,a,u,o,s;for(c=new Ub(t.b);c.aa&&(a=r,s.c=L8(Cnt,FWn,1,0,5,1)),r==a&&UB(s,new eC(e.d.i,e)));TQ(),p$(s,n.c),mG(n.f,u.p,s)}}function H_n(n){$M(n,new ETn(gj(lj(dj(wj(new du,h5n),"ELK Box"),"Algorithm for packing of unconnected boxes, i.e. graphs without edges."),new xu))),c2(n,h5n,WYn,qMt),c2(n,h5n,gZn,15),c2(n,h5n,dZn,tln(0)),c2(n,h5n,C4n,ppn(RMt)),c2(n,h5n,MZn,ppn(_Mt)),c2(n,h5n,TZn,ppn(BMt)),c2(n,h5n,XYn,s5n),c2(n,h5n,yZn,ppn(KMt)),c2(n,h5n,_Zn,ppn(FMt)),c2(n,h5n,f5n,ppn(xMt)),c2(n,h5n,c3n,ppn(DMt))}function q_n(n,t){var e,i,r,c,a,u,o,s,h;if(a=(r=n.i).o.a,c=r.o.b,a<=0&&c<=0)return mUn(),MCt;switch(s=n.n.a,h=n.n.b,u=n.o.a,e=n.o.b,t.g){case 2:case 1:if(s<0)return mUn(),SCt;if(s+u>a)return mUn(),aCt;break;case 4:case 3:if(h<0)return mUn(),uCt;if(h+e>c)return mUn(),TCt}return(o=(s+u/2)/a)+(i=(h+e/2)/c)<=1&&o-i<=0?(mUn(),SCt):o+i>=1&&o-i>=0?(mUn(),aCt):i<.5?(mUn(),uCt):(mUn(),TCt)}function G_n(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;for(e=!1,o=Hy(ED(pMn(t,(FXn(),Ipt)))),l=DVn*o,r=new Ub(t.b);r.aa.n.b-a.d.d+h.a+l&&(b=s.g+h.g,h.a=(h.g*h.a+s.g*s.a)/b,h.g=b,s.f=h,e=!0)),c=a,s=h;return e}function z_n(n,t,e,i,r,c,a){var u,o,s,h,f;for(f=new fA,o=t.Kc();o.Ob();)for(h=new Ub(_B(o.Pb(),839).wf());h.a0?u.a?r>(s=u.b.rf().b)&&(n.v||1==u.c.d.c.length?(a=(r-s)/2,u.d.d=a,u.d.a=a):(e=(_B(Lq(u.c.d,0),181).rf().b-s)/2,u.d.d=i.Math.max(0,e),u.d.a=r-e-s)):u.d.a=n.t+r:Fz(n.u)&&((c=RTn(u.b)).d<0&&(u.d.d=-c.d),c.d+c.a>u.b.rf().b&&(u.d.a=c.d+c.a-u.b.rf().b))}function W_n(n,t){var e;switch(gnn(n)){case 6:return zC(t);case 7:return GC(t);case 8:return qC(t);case 3:return Array.isArray(t)&&!((e=gnn(t))>=14&&e<=16);case 11:return null!=t&&typeof t===LWn;case 12:return null!=t&&(typeof t===CWn||typeof t==LWn);case 0:return Wpn(t,n.__elementTypeId$);case 2:return NU(t)&&!(t.im===C);case 1:return NU(t)&&!(t.im===C)||Wpn(t,n.__elementTypeId$);default:return!0}}function V_n(n,t){var e,r,c,a;return r=i.Math.min(i.Math.abs(n.c-(t.c+t.b)),i.Math.abs(n.c+n.b-t.c)),a=i.Math.min(i.Math.abs(n.d-(t.d+t.a)),i.Math.abs(n.d+n.a-t.d)),(e=i.Math.abs(n.c+n.b/2-(t.c+t.b/2)))>n.b/2+t.b/2||(c=i.Math.abs(n.d+n.a/2-(t.d+t.a/2)))>n.a/2+t.a/2?1:0==e&&0==c?0:0==e?a/c+1:0==c?r/e+1:i.Math.min(r/e,a/c)+1}function Q_n(n,t){var e,r,c,a,u,o;return(c=tin(n))==(o=tin(t))?n.e==t.e&&n.a<54&&t.a<54?n.ft.f?1:0:(r=n.e-t.e,(e=(n.d>0?n.d:i.Math.floor((n.a-1)*qQn)+1)-(t.d>0?t.d:i.Math.floor((t.a-1)*qQn)+1))>r+1?c:e0&&(u=$nn(u,mBn(r))),Zdn(a,u))):c0&&n.d!=(B7(),Cat)&&(u+=a*(i.d.a+n.a[t.b][i.b]*(t.d.a-i.d.a)/e)),e>0&&n.d!=(B7(),Pat)&&(o+=a*(i.d.b+n.a[t.b][i.b]*(t.d.b-i.d.b)/e)));switch(n.d.g){case 1:return new LI(u/c,t.d.b);case 2:return new LI(t.d.a,o/c);default:return new LI(u/c,o/c)}}function Y_n(n,t){var e,i,r,c;if(qsn(),c=_B(pMn(n.i,(FXn(),npt)),98),0!=n.j.g-t.j.g||c!=(WEn(),GIt)&&c!=UIt&&c!=zIt)return 0;if(c==(WEn(),GIt)&&(e=_B(pMn(n,tpt),19),i=_B(pMn(t,tpt),19),e&&i&&0!=(r=e.a-i.a)))return r;switch(n.j.g){case 1:return Mln(n.n.a,t.n.a);case 2:return Mln(n.n.b,t.n.b);case 3:return Mln(t.n.a,n.n.a);case 4:return Mln(t.n.b,n.n.b);default:throw Fp(new Ky(e1n))}}function Z_n(n){var t,e,i,r,c;for(UB(c=new Q6((!n.a&&(n.a=new OL($Ot,n,5)),n.a).i+2),new LI(n.j,n.k)),QT(new xq(null,(!n.a&&(n.a=new OL($Ot,n,5)),new l1(n.a,16))),new Pg(c)),UB(c,new LI(n.b,n.c)),t=1;t0&&(Gun(o,!1,(Kfn(),RPt)),Gun(o,!0,KPt)),Itn(t.g,new uP(n,e)),XW(n.g,t,e)}function tFn(){var n;for(tFn=O,Att=Mun(Hk(INt,1),oQn,25,15,[-1,-1,30,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5]),$tt=L8(INt,oQn,25,37,15,1),Ltt=Mun(Hk(INt,1),oQn,25,15,[-1,-1,63,40,32,28,25,23,21,20,19,19,18,18,17,17,16,16,16,15,15,15,15,14,14,14,14,14,14,13,13,13,13,13,13,13,13]),Ntt=L8(ONt,KQn,25,37,14,1),n=2;n<=36;n++)$tt[n]=SY(i.Math.pow(n,Att[n])),Ntt[n]=Ijn(fVn,$tt[n])}function eFn(n){var t;if(1!=(!n.a&&(n.a=new nU(ROt,n,6,6)),n.a).i)throw Fp(new Ry(_5n+(!n.a&&(n.a=new nU(ROt,n,6,6)),n.a).i));return t=new mm,fun(_B(Utn((!n.b&&(n.b=new oK(xOt,n,4,7)),n.b),0),82))&&Krn(t,qXn(n,fun(_B(Utn((!n.b&&(n.b=new oK(xOt,n,4,7)),n.b),0),82)),!1)),fun(_B(Utn((!n.c&&(n.c=new oK(xOt,n,5,8)),n.c),0),82))&&Krn(t,qXn(n,fun(_B(Utn((!n.c&&(n.c=new oK(xOt,n,5,8)),n.c),0),82)),!0)),t}function iFn(n,t){var e,i,r;for(r=!1,i=new az(JL((t.d?n.a.c==(wY(),Zmt)?sbn(t.b):hbn(t.b):n.a.c==(wY(),Ymt)?sbn(t.b):hbn(t.b)).a.Kc(),new h));bAn(i);)if(e=_B(G5(i),17),(By(n.a.f[n.a.g[t.b.p].p])||f5(e)||e.c.i.c!=e.d.i.c)&&!By(n.a.n[n.a.g[t.b.p].p])&&!By(n.a.n[n.a.g[t.b.p].p])&&(r=!0,KT(n.b,n.a.g[Amn(e,t.b).p])))return t.c=!0,t.a=e,t;return t.c=r,t.a=null,t}function rFn(n,t,e,i,r){var c,a,u,o,s,h,f;for(TQ(),p$(n,new Xu),u=new E2(n,0),f=new $p,c=0;u.b2*c?(h=new Htn(f),s=tG(a)/nG(a),o=vXn(h,t,new fm,e,i,r,s),GR(mO(h.e),o),f.c=L8(Cnt,FWn,1,0,5,1),c=0,f.c[f.c.length]=h,f.c[f.c.length]=a,c=tG(h)*nG(h)+tG(a)*nG(a)):(f.c[f.c.length]=a,c+=tG(a)*nG(a));return f}function cFn(n,t,e){var i,r,c,a,u,o,s;if(0==(i=e.gc()))return!1;if(n.ej())if(o=n.fj(),mwn(n,t,e),a=1==i?n.Zi(3,null,e.Kc().Pb(),t,o):n.Zi(5,null,e,t,o),n.bj()){for(u=i<100?null:new Kj(i),c=t+i,r=t;r0){for(u=0;u>16==-15&&n.Cb.nh()&&O7(new m9(n.Cb,9,13,e,n.c,cvn(F7(_B(n.Cb,59)),n))):iL(n.Cb,88)&&n.Db>>16==-23&&n.Cb.nh()&&(iL(t=n.c,88)||(wWn(),t=l$t),iL(e,88)||(wWn(),e=l$t),O7(new m9(n.Cb,9,10,e,t,cvn(r4(_B(n.Cb,26)),n)))))),n.c}function fFn(n,t){var e,i,r,c,a,u,o,s;for(ITn(t,"Hypernodes processing",1),i=new Ub(n.b);i.ae);return r}function dFn(n,t){var e,i,r;i=0!=F$n(n.d,1),!By(jD(pMn(t.j,(oWn(),Qft))))&&!By(jD(pMn(t.j,Plt)))||HC(pMn(t.j,(FXn(),Adt)))===HC((pon(),$vt))?t.c.Tf(t.e,i):i=By(jD(pMn(t.j,Qft))),NNn(n,t,i,!0),By(jD(pMn(t.j,Plt)))&&oon(t.j,Plt,(oN(),!1)),By(jD(pMn(t.j,Qft)))&&(oon(t.j,Qft,(oN(),!1)),oon(t.j,Plt,!0)),e=YPn(n,t);do{if(Orn(n),0==e)return 0;r=e,NNn(n,t,i=!i,!1),e=YPn(n,t)}while(r>e);return r}function gFn(n,t,e){var i,r,c,a,u,o,s;if(t==e)return!0;if(t=fAn(n,t),e=fAn(n,e),i=Bvn(t)){if((o=Bvn(e))!=i)return!!o&&(a=i.Dj())==o.Dj()&&null!=a;if(!t.d&&(t.d=new OL(UAt,t,1)),r=(c=t.d).i,!e.d&&(e.d=new OL(UAt,e,1)),r==(s=e.d).i)for(u=0;u0,u=$bn(t,c),DN(e?u.b:u.g,t),1==mbn(u).c.length&&e5(i,u,i.c.b,i.c),r=new eC(c,t),b3(n.o,r),v7(n.e.a,c))}function jFn(n,t){var e,r,c,a;return r=i.Math.abs(Bz(n.b).a-Bz(t.b).a),a=i.Math.abs(Bz(n.b).b-Bz(t.b).b),e=1,c=1,r>n.b.b/2+t.b.b/2&&(e=1-i.Math.min(i.Math.abs(n.b.c-(t.b.c+t.b.b)),i.Math.abs(n.b.c+n.b.b-t.b.c))/r),a>n.b.a/2+t.b.a/2&&(c=1-i.Math.min(i.Math.abs(n.b.d-(t.b.d+t.b.a)),i.Math.abs(n.b.d+n.b.a-t.b.d))/a),(1-i.Math.min(e,c))*i.Math.sqrt(r*r+a*a)}function EFn(n){var t,e,i;for(Yzn(n,n.e,n.f,(bY(),Ayt),!0,n.c,n.i),Yzn(n,n.e,n.f,Ayt,!1,n.c,n.i),Yzn(n,n.e,n.f,$yt,!0,n.c,n.i),Yzn(n,n.e,n.f,$yt,!1,n.c,n.i),PFn(n,n.c,n.e,n.f,n.i),e=new E2(n.i,0);e.b=65;e--)zLt[e]=e-65<<24>>24;for(i=122;i>=97;i--)zLt[i]=i-97+26<<24>>24;for(r=57;r>=48;r--)zLt[r]=r-48+52<<24>>24;for(zLt[43]=62,zLt[47]=63,c=0;c<=25;c++)ULt[c]=65+c&WVn;for(a=26,o=0;a<=51;++a,o++)ULt[a]=97+o&WVn;for(n=52,u=0;n<=61;++n,u++)ULt[n]=48+u&WVn;ULt[62]=43,ULt[63]=47}function SFn(n,t){var e,r,c,a,u,o,s,h,f,l,b;if(n.dc())return new Hj;for(s=0,f=0,r=n.Kc();r.Ob();)c=_B(r.Pb(),37).f,s=i.Math.max(s,c.a),f+=c.a*c.b;for(s=i.Math.max(s,i.Math.sqrt(f)*Hy(ED(pMn(_B(n.Kc().Pb(),37),(FXn(),kdt))))),l=0,b=0,o=0,e=t,u=n.Kc();u.Ob();)l+(h=(a=_B(u.Pb(),37)).f).a>s&&(l=0,b+=o+t,o=0),JRn(a,l,b),e=i.Math.max(e,l+h.a),o=i.Math.max(o,h.b),l+=h.a+t;return new LI(e+t,b+o+t)}function PFn(n,t,e,i,r){var c,a,u,o,s,h,f;for(a=new Ub(t);a.ac)return mUn(),aCt;break;case 4:case 3:if(o<0)return mUn(),uCt;if(o+n.f>r)return mUn(),TCt}return(a=(u+n.g/2)/c)+(e=(o+n.f/2)/r)<=1&&a-e<=0?(mUn(),SCt):a+e>=1&&a-e>=0?(mUn(),aCt):e<.5?(mUn(),uCt):(mUn(),TCt)}function CFn(n,t,e,i,r){var c,a;if(c=ebn(n0(t[0],GQn),n0(i[0],GQn)),n[0]=bG(c),c=mz(c,32),e>=r){for(a=1;a0&&(r.b[a++]=0,r.b[a++]=c.b[0]-1),t=1;t0&&(Xl(o,o.d-r.d),r.c==(I6(),jyt)&&zl(o,o.a-r.d),o.d<=0&&o.i>0&&e5(t,o,t.c.b,t.c));for(c=new Ub(n.f);c.a0&&(Wl(u,u.i-r.d),r.c==(I6(),jyt)&&Ul(u,u.b-r.d),u.i<=0&&u.d>0&&e5(e,u,e.c.b,e.c))}function LFn(n,t,e){var i,r,c,a,u,o,s,h;for(ITn(e,"Processor compute fanout",1),OU(n.b),OU(n.a),u=null,c=upn(t.b,0);!u&&c.b!=c.d.c;)By(jD(pMn(s=_B(f3(c),86),(Bqn(),bkt))))&&(u=s);for(e5(o=new VT,u,o.c.b,o.c),yUn(n,o),h=upn(t.b,0);h.b!=h.d.c;)a=TD(pMn(s=_B(f3(h),86),(Bqn(),ekt))),r=null!=TY(n.b,a)?_B(TY(n.b,a),19).a:0,oon(s,tkt,tln(r)),i=1+(null!=TY(n.a,a)?_B(TY(n.a,a),19).a:0),oon(s,Zyt,tln(i));FSn(e)}function NFn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;for(f=vEn(n,e),u=0;u0),i.a.Xb(i.c=--i.b),h>f+u&&sW(i);for(c=new Ub(l);c.a0),i.a.Xb(i.c=--i.b)}}function xFn(){var n,t,e,i,r,c;if(lWn(),MNt)return MNt;for(uHn(n=new E0(4),JUn(dnt,!0)),UGn(n,JUn("M",!0)),UGn(n,JUn("C",!0)),c=new E0(4),i=0;i<11;i++)Vxn(c,i,i);return uHn(t=new E0(4),JUn("M",!0)),Vxn(t,4448,4607),Vxn(t,65438,65439),ZHn(r=new e$(2),n),ZHn(r,aNt),(e=new e$(2)).$l(wG(c,JUn("L",!0))),e.$l(t),e=new GU(r,e=new o4(3,e)),MNt=e}function DFn(n){var t,e;if(!Vcn(t=TD(JAn(n,(uWn(),nSt))),n)&&!M8(n,pPt)&&(0!=(!n.a&&(n.a=new nU(qOt,n,10,11)),n.a).i||By(jD(JAn(n,TSt))))){if(null!=t&&0!=xMn(t).length)throw wzn(n,e=aO(aO(new hN("Layout algorithm '"),t),"' not found for ")),Fp(new ek(e.a));if(!Vcn(l1n,n))throw wzn(n,e=aO(aO(new hN("Unable to load default layout algorithm "),l1n)," for unconfigured node ")),Fp(new ek(e.a))}}function RFn(n){var t,e,r,c,a,u,o,s,h,f,l,b,w;if(e=n.i,t=n.n,0==n.b)for(w=e.c+t.b,b=e.b-t.b-t.c,s=0,f=(u=n.a).length;s0&&(l-=r[0]+n.c,r[0]+=n.c),r[2]>0&&(l-=r[2]+n.c),r[1]=i.Math.max(r[1],l),GG(n.a[1],e.c+t.b+r[0]-(r[1]-l)/2,r[1]);for(o=0,h=(a=n.a).length;o0?(n.n.c.length-1)*n.i:0,e=new Ub(n.n);e.a1)for(i=upn(r,0);i.b!=i.d.c;)for(c=0,u=new Ub((e=_B(f3(i),231)).e);u.a0&&(t[0]+=n.c,l-=t[0]),t[2]>0&&(l-=t[2]+n.c),t[1]=i.Math.max(t[1],l),zG(n.a[1],r.d+e.d+t[0]-(t[1]-l)/2,t[1]);else for(w=r.d+e.d,b=r.a-e.d-e.a,s=0,f=(u=n.a).length;s=0&&c!=e)throw Fp(new Ry(r8n));for(r=0,o=0;o0||0==Pbn(c.b.d,n.b.d+n.b.a)&&r.b<0||0==Pbn(c.b.d+c.b.a,n.b.d)&&r.b>0){o=0;break}}else o=i.Math.min(o,FIn(n,c,r));o=i.Math.min(o,UFn(n,a,o,r))}return o}function XFn(n,t){var e,i,r,c,a,u;if(n.b<2)throw Fp(new Ry("The vector chain must contain at least a source and a target point."));for(Mx(0!=n.b),SA(t,(i=_B(n.a.a.c,8)).a,i.b),u=new ix((!t.a&&(t.a=new OL($Ot,t,5)),t.a)),c=upn(n,1);c.aHy(hL(a.g,a.d[0]).a)?(Mx(o.b>0),o.a.Xb(o.c=--o.b),vR(o,a),r=!0):u.e&&u.e.gc()>0&&(c=(!u.e&&(u.e=new $p),u.e).Mc(t),s=(!u.e&&(u.e=new $p),u.e).Mc(e),(c||s)&&((!u.e&&(u.e=new $p),u.e).Fc(a),++a.c));r||(i.c[i.c.length]=a)}function iBn(n){var t,e,i;if(gA(_B(pMn(n,(FXn(),npt)),98)))for(e=new Ub(n.j);e.a>>0).toString(16),t.length-2,t.length):n>=_Qn?"\\v"+sx(t="0"+(n>>>0).toString(16),t.length-6,t.length):""+String.fromCharCode(n&WVn)}return e}function cBn(n,t){var e,i,r,c,a,u,o,s,h,f;if(a=n.e,0==(o=t.e))return n;if(0==a)return 0==t.e?t:new hU(-t.e,t.d,t.a);if((c=n.d)+(u=t.d)==2)return e=n0(n.a[0],GQn),i=n0(t.a[0],GQn),a<0&&(e=y7(e)),o<0&&(i=y7(i)),Ygn(tbn(e,i));if(-1==(r=c!=u?c>u?1:-1:Esn(n.a,t.a,c)))f=-o,h=a==o?b6(t.a,u,n.a,c):$8(t.a,u,n.a,c);else if(f=a,a==o){if(0==r)return IDn(),net;h=b6(n.a,c,t.a,u)}else h=$8(n.a,c,t.a,u);return z0(s=new hU(f,h.length,h)),s}function aBn(n){var t,e,i,r,c,a;for(this.e=new $p,this.a=new $p,e=n.b-1;e<3;e++)Dx(n,0,_B(Npn(n,0),8));if(n.b<4)throw Fp(new Ry("At (least dimension + 1) control points are necessary!"));for(this.b=3,this.d=!0,this.c=!1,P$n(this,n.b+this.b-1),a=new $p,c=new Ub(this.e),t=0;t=t.o&&e.f<=t.f||.5*t.a<=e.f&&1.5*t.a>=e.f){if((c=_B(Lq(t.n,t.n.c.length-1),211)).e+c.d+e.g+r<=i&&(_B(Lq(t.n,t.n.c.length-1),211).f-n.f+e.f<=n.b||1==n.a.c.length))return vbn(t,e),!0;if(t.s+e.g<=i&&(t.t+t.d+e.f+r<=n.b||1==n.a.c.length))return UB(t.b,e),a=_B(Lq(t.n,t.n.c.length-1),211),UB(t.n,new xY(t.s,a.f+a.a+t.i,t.i)),umn(_B(Lq(t.n,t.n.c.length-1),211),e),_Fn(t,e),!0}return!1}function sBn(n,t,e){var i,r,c,a;return n.ej()?(r=null,c=n.fj(),i=n.Zi(1,a=ann(n,t,e),e,t,c),n.bj()&&!(n.ni()&&null!=a?$fn(a,e):HC(a)===HC(e))?(null!=a&&(r=n.dj(a,r)),r=n.cj(e,r),n.ij()&&(r=n.lj(a,e,r)),r?(r.Ei(i),r.Fi()):n.$i(i)):(n.ij()&&(r=n.lj(a,e,r)),r?(r.Ei(i),r.Fi()):n.$i(i)),a):(a=ann(n,t,e),n.bj()&&!(n.ni()&&null!=a?$fn(a,e):HC(a)===HC(e))&&(r=null,null!=a&&(r=n.dj(a,null)),(r=n.cj(e,r))&&r.Fi()),a)}function hBn(n,t){var e,r,c,a,u,o,s;t%=24,n.q.getHours()!=t&&((e=new i.Date(n.q.getTime())).setDate(e.getDate()+1),(u=n.q.getTimezoneOffset()-e.getTimezoneOffset())>0&&(o=u/60|0,s=u%60,r=n.q.getDate(),n.q.getHours()+o>=24&&++r,c=new i.Date(n.q.getFullYear(),n.q.getMonth(),r,t+o,n.q.getMinutes()+s,n.q.getSeconds(),n.q.getMilliseconds()),n.q.setTime(c.getTime()))),a=n.q.getTime(),n.q.setTime(a+36e5),n.q.getHours()!=t&&n.q.setTime(a)}function fBn(n,t){var e,i,r,c;if(ITn(t,"Path-Like Graph Wrapping",1),0!=n.b.c.length)if(null==(r=new EAn(n)).i&&(r.i=Urn(r,new kc)),e=Hy(r.i)*r.f/(null==r.i&&(r.i=Urn(r,new kc)),Hy(r.i)),r.b>e)FSn(t);else{switch(_B(pMn(n,(FXn(),_pt)),337).g){case 2:c=new Tc;break;case 0:c=new wc;break;default:c=new Mc}if(i=c.Vf(n,r),!c.Wf())switch(_B(pMn(n,zpt),338).g){case 2:i=zIn(r,i);break;case 1:i=DTn(r,i)}tqn(n,r,i),FSn(t)}else FSn(t)}function lBn(n,t){var e,i,r,c;if(s1(n.d,n.e),n.c.a.$b(),0!=Hy(ED(pMn(t.j,(FXn(),Pdt))))||0!=Hy(ED(pMn(t.j,Pdt))))for(e=JYn,HC(pMn(t.j,Adt))!==HC((pon(),$vt))&&oon(t.j,(oWn(),Qft),(oN(),!0)),c=_B(pMn(t.j,Lpt),19).a,r=0;r(h1(c+1,t.c.length),_B(t.c[c+1],19)).a-i&&++u,UB(r,(h1(c+u,t.c.length),_B(t.c[c+u],19))),a+=(h1(c+u,t.c.length),_B(t.c[c+u],19)).a-i,++e;e1&&(o>tG(u)*nG(u)/2||0==a.b)&&(f=new Htn(l),h=tG(u)/nG(u),s=vXn(f,t,new fm,e,i,r,h),GR(mO(f.e),s),u=f,b.c[b.c.length]=f,o=0,l.c=L8(Cnt,FWn,1,0,5,1)));return wun(b,l),b}function pBn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d;if(e.mh(t)&&(h=(b=t)?_B(i,49).xh(b):null))if(d=e.bh(t,n.a),(w=t.t)>1||-1==w)if(f=_B(d,69),l=_B(h,69),f.dc())l.$b();else for(a=!!Svn(t),c=0,u=n.a?f.Kc():f.Zh();u.Ob();)s=_B(u.Pb(),56),(r=_B(hnn(n,s),56))?(a?-1==(o=l.Xc(r))?l.Xh(c,r):c!=o&&l.ji(c,r):l.Xh(c,r),++c):n.b&&!a&&(l.Xh(c,s),++c);else null==d?h.Wb(null):null==(r=hnn(n,d))?n.b&&!Svn(t)&&h.Wb(d):h.Wb(r)}function vBn(n,t){var e,r,c,a,u,o,s,f;for(e=new Le,c=new az(JL(sbn(t).a.Kc(),new h));bAn(c);)if(!f5(r=_B(G5(c),17))&&nTn(o=r.c.i,zut)){if(-1==(f=XDn(n,o,zut,Gut)))continue;e.b=i.Math.max(e.b,f),!e.a&&(e.a=new $p),UB(e.a,o)}for(u=new az(JL(hbn(t).a.Kc(),new h));bAn(u);)if(!f5(a=_B(G5(u),17))&&nTn(s=a.d.i,Gut)){if(-1==(f=XDn(n,s,Gut,zut)))continue;e.d=i.Math.max(e.d,f),!e.c&&(e.c=new $p),UB(e.c,s)}return e}function mBn(n){var t,e,i,r;if(OOn(),t=SY(n),n1e6)throw Fp(new Iy("power of ten too big"));if(n<=NWn)return H5(cOn(ret[1],t),t);for(r=i=cOn(ret[1],NWn),e=san(n-NWn),t=SY(n%NWn);Xhn(e,NWn)>0;)r=$nn(r,i),e=tbn(e,NWn);for(r=H5(r=$nn(r,cOn(ret[1],t)),NWn),e=san(n-NWn);Xhn(e,NWn)>0;)r=H5(r,NWn),e=tbn(e,NWn);return r=H5(r,t)}function yBn(n,t){var e,i,r,c,a,u,o,s;for(ITn(t,"Hierarchical port dummy size processing",1),u=new $p,s=new $p,e=2*Hy(ED(pMn(n,(FXn(),mpt)))),r=new Ub(n.b);r.as&&i>s)){r=!1,e.n&&IH(e,"bk node placement breaks on "+u+" which should have been after "+h);break}h=u,s=Hy(t.p[u.p])+Hy(t.d[u.p])+u.o.b+u.d.a}if(!r)break}return e.n&&IH(e,t+" is feasible: "+r),r}function IBn(n,t,e,i){var r,c,a,u,o,s,h;for(u=-1,h=new Ub(n);h.a=g&&n.e[s.p]>w*n.b||m>=e*g)&&(l.c[l.c.length]=o,o=new $p,Krn(u,a),a.a.$b(),h-=f,b=i.Math.max(b,h*n.b+d),h+=m,v=m,m=0,f=0,d=0);return new eC(b,l)}function $Bn(n){var t,e,i,r,c,a,u,o,s,h,f,l;for(e=new Db(new Ib(n.c.b).a.vc().Kc());e.a.Ob();)u=_B(e.a.Pb(),42),null==(r=(t=_B(u.dd(),149)).a)&&(r=""),!(i=RD(n.c,r))&&0==r.length&&(i=vfn(n)),i&&!vwn(i.c,t,!1)&&NH(i.c,t);for(a=upn(n.a,0);a.b!=a.d.c;)c=_B(f3(a),478),s=j5(n.c,c.a),l=j5(n.c,c.b),s&&l&&NH(s.c,new eC(l,c.c));for(vQ(n.a),f=upn(n.b,0);f.b!=f.d.c;)h=_B(f3(f),478),t=DD(n.c,h.a),o=j5(n.c,h.b),t&&o&&NM(t,o,h.c);vQ(n.b)}function LBn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;c=new Ml(n),b5((a=new bkn).g),b5(a.j),OU(a.b),b5(a.d),b5(a.i),OU(a.k),OU(a.c),OU(a.e),b=fCn(a,c,null),I$n(a,c),r=b,t&&(u=nHn(s=new Ml(t)),gSn(r,Mun(Hk(YTt,1),FWn,527,0,[u]))),l=!1,f=!1,e&&(s=new Ml(e),h8n in s.a&&(l=qY(s,h8n).ge().a),f8n in s.a&&(f=qY(s,f8n).ge().a)),h=Oj(Ken(new zm,l),f),_Sn(new su,r,h),h8n in c.a&&etn(c,h8n,null),(l||f)&&(YFn(h,o=new dy,l,f),etn(c,h8n,o)),i=new zg(a),Gon(new IA(r),i)}function NBn(n,t,e){var i,r,c,a,u,o,s,h,f;for(a=new Vkn,s=Mun(Hk(INt,1),oQn,25,15,[0]),r=-1,c=0,i=0,o=0;o0)){if(r=-1,32==sV(h.c,0)){if(f=s[0],vnn(t,s),s[0]>f)continue}else if(OJ(t,h.c,s[0])){s[0]+=h.c.length;continue}return 0}if(r<0&&h.a&&(r=o,c=s[0],i=0),r>=0){if(u=h.b,o==r&&0==(u-=i++))return 0;if(!AUn(t,s,h,u,a)){o=r-1,s[0]=c;continue}}else if(r=-1,!AUn(t,s,h,0,a))return 0}return bUn(a,e)?s[0]:0}function xBn(n){var t,e,i,r,c,a;if(!n.f){if(a=new Mo,c=new Mo,null==(t=T$t).a.zc(n,t)){for(r=new CL(mJ(n));r.e!=r.i.gc();)dX(a,xBn(_B(mpn(r),26)));t.a.Bc(n),t.a.gc()}for(!n.s&&(n.s=new nU(RAt,n,21,17)),i=new CL(n.s);i.e!=i.i.gc();)iL(e=_B(mpn(i),170),99)&&s9(c,_B(e,18));ihn(c),n.r=new jH(n,(_B(Utn(WQ((WX(),YAt).o),6),18),c.i),c.g),dX(a,n.r),ihn(a),n.f=new $O((_B(Utn(WQ(YAt.o),5),18),a.i),a.g),M5(n).b&=-3}return n.f}function DBn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w;for(a=n.o,i=L8(INt,oQn,25,a,15,1),r=L8(INt,oQn,25,a,15,1),e=n.p,t=L8(INt,oQn,25,e,15,1),c=L8(INt,oQn,25,e,15,1),s=0;s=0&&!gmn(n,h,f);)--f;r[h]=f}for(b=0;b=0&&!gmn(n,u,w);)--u;c[w]=u}for(o=0;ot[l]&&li[o]&&KRn(n,o,l,!1,!0)}function RBn(n){var t,e,i,r,c,a,u,o;e=By(jD(pMn(n,(sRn(),_ct)))),c=n.a.c.d,u=n.a.d.d,e?(a=mL(zR(new LI(u.a,u.b),c),.5),o=mL(_$(n.e),.5),t=zR(GR(new LI(c.a,c.b),a),o),Fx(n.d,t)):(r=Hy(ED(pMn(n.a,eat))),i=n.d,c.a>=u.a?c.b>=u.b?(i.a=u.a+(c.a-u.a)/2+r,i.b=u.b+(c.b-u.b)/2-r-n.e.b):(i.a=u.a+(c.a-u.a)/2+r,i.b=c.b+(u.b-c.b)/2+r):c.b>=u.b?(i.a=c.a+(u.a-c.a)/2+r,i.b=u.b+(c.b-u.b)/2+r):(i.a=c.a+(u.a-c.a)/2+r,i.b=c.b+(u.b-c.b)/2-r-n.e.b))}function KBn(n,t){var e,i,r,c,a,u,o;if(null==n)return null;if(0==(c=n.length))return"";for(o=L8(PNt,UVn,25,c,15,1),R8(0,c,n.length),R8(0,c,o.length),VU(n,0,c,o,0),e=null,u=t,r=0,a=0;r0?sx(e.a,0,c-1):"":n.substr(0,c-1):e?e.a:n}function _Bn(n){$M(n,new ETn(gj(lj(dj(wj(new du,GYn),"ELK DisCo"),"Layouter for arranging unconnected subgraphs. The subgraphs themselves are, by default, not laid out."),new at))),c2(n,GYn,zYn,ppn(kct)),c2(n,GYn,UYn,ppn(dct)),c2(n,GYn,XYn,ppn(hct)),c2(n,GYn,WYn,ppn(gct)),c2(n,GYn,zJn,ppn(mct)),c2(n,GYn,UJn,ppn(vct)),c2(n,GYn,GJn,ppn(yct)),c2(n,GYn,XJn,ppn(pct)),c2(n,GYn,_Yn,ppn(lct)),c2(n,GYn,FYn,ppn(fct)),c2(n,GYn,BYn,ppn(bct)),c2(n,GYn,HYn,ppn(wct))}function FBn(n,t,e,i){var r,c,a,u,o,s,h;if(_l(c=new Ovn(n),(cSn(),Put)),oon(c,(FXn(),npt),(WEn(),zIt)),r=0,t){for(oon(a=new SSn,(oWn(),blt),t),oon(c,blt,t.i),BIn(a,(mUn(),SCt)),SZ(a,c),s=0,h=(o=J0(t.e)).length;s0)if((e-=r.length-t)>=0){for(c.a+="0.";e>Btt.length;e-=Btt.length)$q(c,Btt);wR(c,Btt,SY(e)),aO(c,r.substr(t))}else aO(c,sx(r,t,SY(e=t-e))),c.a+=".",aO(c,YC(r,SY(e)));else{for(aO(c,r.substr(t));e<-Btt.length;e+=Btt.length)$q(c,Btt);wR(c,Btt,SY(-e))}return c.a}function qBn(n,t,e,r){var c,a,u,o,s,h,f,l,b;return h=(s=zR(new LI(e.a,e.b),n)).a*t.b-s.b*t.a,f=t.a*r.b-t.b*r.a,l=(s.a*r.b-s.b*r.a)/f,b=h/f,0==f?0==h?(a=U8(n,c=GR(new LI(e.a,e.b),mL(new LI(r.a,r.b),.5))),u=U8(GR(new LI(n.a,n.b),t),c),o=.5*i.Math.sqrt(r.a*r.a+r.b*r.b),a=0&&l<=1&&b>=0&&b<=1?GR(new LI(n.a,n.b),mL(new LI(t.a,t.b),l)):null}function GBn(n,t,e){var i,r,c,a,u;if(i=_B(pMn(n,(FXn(),$dt)),21),e.a>t.a&&(i.Hc((lEn(),UMt))?n.c.a+=(e.a-t.a)/2:i.Hc(WMt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((lEn(),QMt))?n.c.b+=(e.b-t.b)/2:i.Hc(VMt)&&(n.c.b+=e.b-t.b)),_B(pMn(n,(oWn(),Jft)),21).Hc((fDn(),hft))&&(e.a>t.a||e.b>t.b))for(u=new Ub(n.a);u.at.a&&(i.Hc((lEn(),UMt))?n.c.a+=(e.a-t.a)/2:i.Hc(WMt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((lEn(),QMt))?n.c.b+=(e.b-t.b)/2:i.Hc(VMt)&&(n.c.b+=e.b-t.b)),_B(pMn(n,(oWn(),Jft)),21).Hc((fDn(),hft))&&(e.a>t.a||e.b>t.b))for(a=new Ub(n.a);a.at&&(r=0,c+=s.b+e,h.c[h.c.length]=s,Zen(s=new L0(c,e),i=new rsn(0,s.f,s,e)),r=0),0==i.b.c.length||u.f>=i.o&&u.f<=i.f||.5*i.a<=u.f&&1.5*i.a>=u.f?vbn(i,u):(Zen(s,a=new rsn(i.s+i.r+e,s.f,s,e)),vbn(a,u)),r=u.i+u.g;return h.c[h.c.length]=s,h}function VBn(n){var t,e,i,r,c,a;if(!n.a){if(n.o=null,a=new wp(n),t=new So,null==(e=T$t).a.zc(n,e)){for(c=new CL(mJ(n));c.e!=c.i.gc();)dX(a,VBn(_B(mpn(c),26)));e.a.Bc(n),e.a.gc()}for(!n.s&&(n.s=new nU(RAt,n,21,17)),r=new CL(n.s);r.e!=r.i.gc();)iL(i=_B(mpn(r),170),322)&&s9(t,_B(i,34));ihn(t),n.k=new kH(n,(_B(Utn(WQ((WX(),YAt).o),7),18),t.i),t.g),dX(a,n.k),ihn(a),n.a=new $O((_B(Utn(WQ(YAt.o),4),18),a.i),a.g),M5(n).b&=-2}return n.a}function QBn(n,t,e,i,r,c,a){var u,o,s,h,f;return h=!1,u=bNn(e.q,t.f+t.b-e.q.f),!((f=r-(e.q.e+u-a))=(h1(c,n.c.length),_B(n.c[c],200)).e,!((s=iHn(i,f,!1).a)>t.b&&!o)&&((o||s<=t.b)&&(o&&s>t.b?(e.d=s,d9(e,KSn(e,s))):(rEn(e.q,u),e.c=!0),d9(i,r-(e.s+e.r)),jvn(i,e.q.e+e.q.d,t.f),Zen(t,i),n.c.length>c&&(jkn((h1(c,n.c.length),_B(n.c[c],200)),i),0==(h1(c,n.c.length),_B(n.c[c],200)).a.c.length&&u6(n,c)),h=!0),h))}function JBn(n,t,e,i){var r,c,a,u,o,s,h;if(h=rxn(n.e.Tg(),t),r=0,c=_B(n.g,119),o=null,JM(),_B(t,66).Oj()){for(u=0;un.o.a&&(f=(s-n.o.a)/2,o.b=i.Math.max(o.b,f),o.c=i.Math.max(o.c,f))}}function nHn(n){var t,e,i,r,c,a;for(iA(r=new x0,($un(),QTt)),i=new Tb(new Qy(new jT(n,yrn(n,L8(Wtt,uVn,2,0,6,1))).b));i.b0?n.i:0)>t&&s>0&&(a=0,u+=s+n.i,c=i.Math.max(c,b),r+=s+n.i,s=0,b=0,e&&(++l,UB(n.n,new xY(n.s,u,n.i))),o=0),b+=h.g+(o>0?n.i:0),s=i.Math.max(s,h.f),e&&umn(_B(Lq(n.n,l),211),h),a+=h.g+(o>0?n.i:0),++o;return c=i.Math.max(c,b),r+=s,e&&(n.r=c,n.d=r,vyn(n.j)),new GV(n.s,n.t,c,r)}function rHn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;if(OT(),TU(n,"src"),TU(e,"dest"),l=Zon(n),o=Zon(e),dH(0!=(4&l.i),"srcType is not an array"),dH(0!=(4&o.i),"destType is not an array"),f=l.c,a=o.c,dH(0!=(1&f.i)?f==a:0==(1&a.i),"Array types don't match"),b=n.length,s=e.length,t<0||i<0||r<0||t+r>b||i+r>s)throw Fp(new sv);if(0==(1&f.i)&&l!=o)if(h=nen(n),c=nen(e),HC(n)===HC(e)&&ti;)OX(c,u,h[--t]);else for(u=i+r;i0&&RIn(n,t,e,i,r,!0)}function cHn(){cHn=O,eet=Mun(Hk(INt,1),oQn,25,15,[RVn,1162261467,IVn,1220703125,362797056,1977326743,IVn,387420489,CQn,214358881,429981696,815730721,1475789056,170859375,268435456,410338673,612220032,893871739,128e7,1801088541,113379904,148035889,191102976,244140625,308915776,387420489,481890304,594823321,729e6,887503681,IVn,1291467969,1544804416,1838265625,60466176]),iet=Mun(Hk(INt,1),oQn,25,15,[-1,-1,31,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5])}function aHn(n){var t,e,i,r,c,a,u;for(i=new Ub(n.b);i.a=n.b.length?(c[r++]=a.b[i++],c[r++]=a.b[i++]):i>=a.b.length?(c[r++]=n.b[e++],c[r++]=n.b[e++]):a.b[i]0?n.i:0)),++t;for(Ybn(n.n,s),n.d=e,n.r=r,n.g=0,n.f=0,n.e=0,n.o=xQn,n.p=xQn,a=new Ub(n.b);a.a0&&(!(r=(!n.n&&(n.n=new nU(HOt,n,1,7)),_B(Utn(n.n,0),137)).a)||aO(aO((t.a+=' "',t),r),'"'))),!n.b&&(n.b=new oK(xOt,n,4,7)),e=!(n.b.i<=1&&(!n.c&&(n.c=new oK(xOt,n,5,8)),n.c.i<=1)),t.a+=e?" [":" ",aO(t,QL(new pk,new CL(n.b))),e&&(t.a+="]"),t.a+=n1n,e&&(t.a+="["),aO(t,QL(new pk,new CL(n.c))),e&&(t.a+="]"),t.a)}function fHn(n,t){var e,i,r,c,a,u,o;if(n.a){if(o=null,null!=(u=n.a.ne())?t.a+=""+u:null!=(a=n.a.Dj())&&(-1!=(c=HO(a,VTn(91)))?(o=a.substr(c),t.a+=""+sx(null==a?qWn:(mW(a),a),0,c)):t.a+=""+a),n.d&&0!=n.d.i){for(r=!0,t.a+="<",i=new CL(n.d);i.e!=i.i.gc();)e=_B(mpn(i),87),r?r=!1:t.a+=KWn,fHn(e,t);t.a+=">"}null!=o&&(t.a+=""+o)}else n.e?null!=(u=n.e.zb)&&(t.a+=""+u):(t.a+="?",n.b?(t.a+=" super ",fHn(n.b,t)):n.f&&(t.a+=" extends ",fHn(n.f,t)))}function lHn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;for(y=n.c,k=t.c,e=k7(y.a,n,0),i=k7(k.a,t,0),v=_B(Lwn(n,(rin(),Fvt)).Kc().Pb(),11),T=_B(Lwn(n,Bvt).Kc().Pb(),11),m=_B(Lwn(t,Fvt).Kc().Pb(),11),M=_B(Lwn(t,Bvt).Kc().Pb(),11),g=J0(v.e),j=J0(T.g),p=J0(m.e),E=J0(M.g),Wyn(n,i,k),s=0,b=(c=p).length;sh?new qZ((I6(),Eyt),e,t,s-h):s>0&&h>0&&(new qZ((I6(),Eyt),t,e,0),new qZ(Eyt,e,t,0))),a)}function dHn(n,t){var e,r,c,a,u;for(u=new csn(new Mb(n.f.b).a);u.b;){if(c=_B((a=Ztn(u)).cd(),594),1==t){if(c.gf()!=(Kfn(),FPt)&&c.gf()!=DPt)continue}else if(c.gf()!=(Kfn(),RPt)&&c.gf()!=KPt)continue;switch(r=_B(_B(a.dd(),46).b,81),e=_B(_B(a.dd(),46).a,189).c,c.gf().g){case 2:r.g.c=n.e.a,r.g.b=i.Math.max(1,r.g.b+e);break;case 1:r.g.c=r.g.c+e,r.g.b=i.Math.max(1,r.g.b-e);break;case 4:r.g.d=n.e.b,r.g.a=i.Math.max(1,r.g.a+e);break;case 3:r.g.d=r.g.d+e,r.g.a=i.Math.max(1,r.g.a-e)}}}function gHn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g;for(o=L8(INt,oQn,25,t.b.c.length,15,1),h=L8(Out,OVn,267,t.b.c.length,0,1),s=L8(Iut,r1n,10,t.b.c.length,0,1),b=0,w=(l=n.a).length;b0&&s[r]&&(d=D$(n.b,s[r],c)),g=i.Math.max(g,c.c.c.b+d);for(a=new Ub(f.e);a.a1)throw Fp(new Ry(P7n));o||(c=J3(t,i.Kc().Pb()),a.Fc(c))}return aon(n,kPn(n,t,e),a)}function kHn(n,t){var e,i,r,c;for(Wtn(t.b.j),QT(OV(new xq(null,new l1(t.d,16)),new cc),new ac),c=new Ub(t.d);c.an.o.b)return!1;if(e=rbn(n,aCt),t.d+t.a+(e.gc()-1)*r>n.o.b)return!1}return!0}function OHn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;if(a=n.e,o=t.e,0==a)return t;if(0==o)return n;if((c=n.d)+(u=t.d)==2)return e=n0(n.a[0],GQn),i=n0(t.a[0],GQn),a==o?(w=bG(h=ebn(e,i)),0==(b=bG(yz(h,32)))?new z6(a,w):new hU(a,2,Mun(Hk(INt,1),oQn,25,15,[w,b]))):Ygn(a<0?tbn(i,e):tbn(e,i));if(a==o)l=a,f=c>=u?$8(n.a,c,t.a,u):$8(t.a,u,n.a,c);else{if(0==(r=c!=u?c>u?1:-1:Esn(n.a,t.a,c)))return IDn(),net;1==r?(l=a,f=b6(n.a,c,t.a,u)):(l=o,f=b6(t.a,u,n.a,c))}return z0(s=new hU(l,f.length,f)),s}function AHn(n,t,e,r,c,a,u){var o,s,h,f,l,b,w;return l=By(jD(pMn(t,(FXn(),Igt)))),b=null,a==(rin(),Fvt)&&r.c.i==e?b=r.c:a==Bvt&&r.d.i==e&&(b=r.d),(h=u)&&l&&!b?(UB(h.e,r),w=i.Math.max(Hy(ED(pMn(h.d,rgt))),Hy(ED(pMn(r,rgt)))),oon(h.d,rgt,w)):(mUn(),f=MCt,b?f=b.j:gA(_B(pMn(e,npt),98))&&(f=a==Fvt?SCt:aCt),s=LHn(n,t,e,a,f,r),o=U5((gW(e),r)),a==Fvt?(TZ(o,_B(Lq(s.j,0),11)),EZ(o,c)):(TZ(o,c),EZ(o,_B(Lq(s.j,0),11))),h=new qfn(r,o,s,_B(pMn(s,(oWn(),blt)),11),a,!b)),QCn(n.a,r,new A_(h.d,t,a)),h}function $Hn(n,t){var e,i,r,c,a,u,o,s,h,f;if(h=null,n.d&&(h=_B(TY(n.d,t),138)),!h){if(f=(c=n.a.Mh()).i,!n.d||$T(n.d)!=f){for(o=new Lp,n.d&&jcn(o,n.d),u=s=o.f.c+o.g.c;u0?(b=(w-1)*e,u&&(b+=i),h&&(b+=i),b=n.b[r+1])r+=2;else{if(!(e0)for(i=new ZK(_B(o6(n.a,c),21)),TQ(),p$(i,new Rw(t)),r=new E2(c.b,0);r.bk)?(s=2,u=NWn):0==s?(s=1,u=E):(s=0,u=E):(b=E>=u||u-E0?1:qO(isNaN(r),isNaN(0)))>=0^(ein(C3n),(i.Math.abs(o)<=C3n||0==o||isNaN(o)&&isNaN(0)?0:o<0?-1:o>0?1:qO(isNaN(o),isNaN(0)))>=0)?i.Math.max(o,r):(ein(C3n),(i.Math.abs(r)<=C3n||0==r||isNaN(r)&&isNaN(0)?0:r<0?-1:r>0?1:qO(isNaN(r),isNaN(0)))>0?i.Math.sqrt(o*o+r*r):-i.Math.sqrt(o*o+r*r))}function ZHn(n,t){var e,i,r,c,a;if(t)if(!n.a&&(n.a=new Rv),2!=n.e)if(1!=t.e)0!=(a=n.a.a.c.length)?0!=(c=_B(fW(n.a,a-1),117)).e&&10!=c.e||0!=t.e&&10!=t.e?Sv(n.a,t):(0==t.e||t.bm().length,0==c.e?(e=new Mk,(i=c._l())>=_Qn?iO(e,zln(i)):$X(e,i&WVn),c=new gY(10,null,0),mU(n.a,c,a-1)):(c.bm().length,iO(e=new Mk,c.bm())),0==t.e?(i=t._l())>=_Qn?iO(e,zln(i)):$X(e,i&WVn):iO(e,t.bm()),_B(c,521).b=e.a):Sv(n.a,t);else for(r=0;r0&&i>=-6?i>=0?mZ(c,e-SY(n.e),String.fromCharCode(46)):(c.a=sx(c.a,0,t-1)+"0."+YC(c.a,t-1),mZ(c,t+1,_dn(Btt,0,-SY(i)-1))):(e-t>=1&&(mZ(c,t,String.fromCharCode(46)),++e),mZ(c,e,String.fromCharCode(69)),i>0&&mZ(c,++e,String.fromCharCode(43)),mZ(c,++e,""+gz(san(i)))),n.g=c.a,n.g))}function tqn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(!e.dc()){for(a=0,h=0,l=_B((i=e.Kc()).Pb(),19).a;a1&&(o=s.mg(o,n.a,u));return 1==o.c.length?_B(Lq(o,o.c.length-1),220):2==o.c.length?KHn((h1(0,o.c.length),_B(o.c[0],220)),(h1(1,o.c.length),_B(o.c[1],220)),a,c):null}function cqn(n){var t,e,r,c,a,u;for(Itn(n.a,new nt),e=new Ub(n.a);e.a=i.Math.abs(r.b)?(r.b=0,a.d+a.a>u.d&&a.du.c&&a.c0){if(t=new NC(n.i,n.g),c=(e=n.i)<100?null:new Kj(e),n.ij())for(i=0;i0){for(u=n.g,s=n.i,r6(n),c=s<100?null:new Kj(s),i=0;i>13|(15&n.m)<<9,r=n.m>>4&8191,c=n.m>>17|(255&n.h)<<5,a=(1048320&n.h)>>8,g=i*(u=8191&t.l),p=r*u,v=c*u,m=a*u,0!=(o=t.l>>13|(15&t.m)<<9)&&(g+=e*o,p+=i*o,v+=r*o,m+=c*o),0!=(s=t.m>>4&8191)&&(p+=e*s,v+=i*s,m+=r*s),0!=(h=t.m>>17|(255&t.h)<<5)&&(v+=e*h,m+=i*h),0!=(f=(1048320&t.h)>>8)&&(m+=e*f),b=((d=e*u)>>22)+(g>>9)+((262143&p)<<4)+((31&v)<<17),w=(p>>18)+(v>>5)+((4095&m)<<8),w+=(b+=(l=(d&TQn)+((511&g)<<13))>>22)>>22,E$(l&=TQn,b&=TQn,w&=MQn)}function hqn(n){var t,e,r,c,a,u,o;if(0!=(o=_B(Lq(n.j,0),11)).g.c.length&&0!=o.e.c.length)throw Fp(new Ky("Interactive layout does not support NORTH/SOUTH ports with incoming _and_ outgoing edges."));if(0!=o.g.c.length){for(a=xQn,e=new Ub(o.g);e.a4){if(!n.wj(t))return!1;if(n.rk()){if(u=(e=(i=_B(t,49)).Ug())==n.e&&(n.Dk()?i.Og(i.Vg(),n.zk())==n.Ak():-1-i.Vg()==n.aj()),n.Ek()&&!u&&!e&&i.Zg())for(r=0;r0&&(s=n.n.a/c);break;case 2:case 4:(r=n.i.o.b)>0&&(s=n.n.b/r)}oon(n,(oWn(),jlt),s)}if(o=n.o,a=n.a,i)a.a=i.a,a.b=i.b,n.d=!0;else if(t!=WIt&&t!=VIt&&u!=MCt)switch(u.g){case 1:a.a=o.a/2;break;case 2:a.a=o.a,a.b=o.b/2;break;case 3:a.a=o.a/2,a.b=o.b;break;case 4:a.b=o.b/2}else a.a=o.a/2,a.b=o.b/2}function gqn(n){var t,e,i,r,c,a,u,o,s,h;if(n.ej())if(h=n.Vi(),o=n.fj(),h>0)if(t=new ycn(n.Gi()),c=(e=h)<100?null:new Kj(e),QD(n,e,t.g),r=1==e?n.Zi(4,Utn(t,0),null,0,o):n.Zi(6,t,null,-1,o),n.bj()){for(i=new CL(t);i.e!=i.i.gc();)c=n.dj(mpn(i),c);c?(c.Ei(r),c.Fi()):n.$i(r)}else c?(c.Ei(r),c.Fi()):n.$i(r);else QD(n,n.Vi(),n.Wi()),n.$i(n.Zi(6,(TQ(),uet),null,-1,o));else if(n.bj())if((h=n.Vi())>0){for(u=n.Wi(),s=h,QD(n,h,u),c=s<100?null:new Kj(s),i=0;in.d[r.p]&&(e+=Y4(n.b,i)*_B(a.b,19).a,b3(n.a,tln(i)));for(;!Uy(n.a);)Enn(n.b,_B(bU(n.a),19).a)}return e}function mqn(n,t,e,r){var c,a,u,o,s,h,f,l,b,w;for((f=new lA(_B(JAn(n,(TMn(),FMt)),8))).a=i.Math.max(f.a-e.b-e.c,0),f.b=i.Math.max(f.b-e.d-e.a,0),(null==(c=ED(JAn(n,NMt)))||(mW(c),c<=0))&&(c=1.3),u=new $p,l=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));l.e!=l.i.gc();)a=new qx(_B(mpn(l),33)),u.c[u.c.length]=a;switch(_B(JAn(n,xMt),311).g){case 3:w=rFn(u,t,f.a,f.b,(s=r,mW(c),s));break;case 1:w=gBn(u,t,f.a,f.b,(h=r,mW(c),h));break;default:w=Eqn(u,t,f.a,f.b,(o=r,mW(c),o))}DUn(n,(b=vXn(new Htn(w),t,e,f.a,f.b,r,(mW(c),c))).a,b.b,!1,!0)}function yqn(n,t){var e,i,r,c;c=new ZK((e=t.b).j),r=0,(i=e.j).c=L8(Cnt,FWn,1,0,5,1),nX(_B(wan(n.b,(mUn(),uCt),(Srn(),xst)),15),e),r=Qmn(c,r,new xr,i),nX(_B(wan(n.b,uCt,Nst),15),e),r=Qmn(c,r,new Nr,i),nX(_B(wan(n.b,uCt,Lst),15),e),nX(_B(wan(n.b,aCt,xst),15),e),nX(_B(wan(n.b,aCt,Nst),15),e),r=Qmn(c,r,new Dr,i),nX(_B(wan(n.b,aCt,Lst),15),e),nX(_B(wan(n.b,TCt,xst),15),e),r=Qmn(c,r,new Rr,i),nX(_B(wan(n.b,TCt,Nst),15),e),r=Qmn(c,r,new Kr,i),nX(_B(wan(n.b,TCt,Lst),15),e),nX(_B(wan(n.b,SCt,xst),15),e),r=Qmn(c,r,new Qr,i),nX(_B(wan(n.b,SCt,Nst),15),e),nX(_B(wan(n.b,SCt,Lst),15),e)}function kqn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g;for(ITn(t,"Layer size calculation",1),f=xQn,h=DQn,c=!1,o=new Ub(n.b);o.a.5?p-=2*a*(w-.5):w<.5&&(p+=2*c*(.5-w)),p<(r=u.d.b)&&(p=r),d=u.d.c,p>g.a-d-h&&(p=g.a-d-h),u.n.a=t+p}}function Eqn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;for(u=L8($Nt,BQn,25,n.c.length,15,1),tkn(l=new zz(new Uu),n),s=0,b=new $p;0!=l.b.c.length;)if(a=_B(0==l.b.c.length?null:Lq(l.b,0),157),s>1&&tG(a)*nG(a)/2>u[0]){for(c=0;cu[c];)++c;f=new Htn(new u1(b,0,c+1)),h=tG(a)/nG(a),o=vXn(f,t,new fm,e,i,r,h),GR(mO(f.e),o),K8(nMn(l,f)),tkn(l,new u1(b,c+1,b.c.length)),b.c=L8(Cnt,FWn,1,0,5,1),s=0,yG(u,u.length,0)}else null!=(0==l.b.c.length?null:Lq(l.b,0))&&orn(l,0),s>0&&(u[s]=u[s-1]),u[s]+=tG(a)*nG(a),++s,b.c[b.c.length]=a;return b}function Tqn(n){var t,e,i;if((e=_B(pMn(n,(FXn(),mgt)),163))==(jbn(),Klt)){for(t=new az(JL(sbn(n).a.Kc(),new h));bAn(t);)if(!z5(_B(G5(t),17)))throw Fp(new ek(M1n+wyn(n)+"' has its layer constraint set to FIRST_SEPARATE, but has at least one incoming edge. FIRST_SEPARATE nodes must not have incoming edges."))}else if(e==Flt)for(i=new az(JL(hbn(n).a.Kc(),new h));bAn(i);)if(!z5(_B(G5(i),17)))throw Fp(new ek(M1n+wyn(n)+"' has its layer constraint set to LAST_SEPARATE, but has at least one outgoing edge. LAST_SEPARATE nodes must not have outgoing edges."))}function Mqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;for(ITn(t,"Label dummy removal",1),i=Hy(ED(pMn(n,(FXn(),ypt)))),r=Hy(ED(pMn(n,Tpt))),o=_B(pMn(n,Gdt),103),u=new Ub(n.b);u.a0&&hPn(n,u,h);for(r=new Ub(h);r.a>19!=0&&(t=ron(t),o=!o),a=ILn(t),c=!1,r=!1,i=!1,n.h==SQn&&0==n.m&&0==n.l){if(r=!0,c=!0,-1!=a)return u=yAn(n,a),o&&Ion(u),e&&(htt=E$(0,0,0)),u;n=UO((z7(),ftt)),i=!0,o=!o}else n.h>>19!=0&&(c=!0,n=ron(n),i=!0,o=!o);return-1!=a?_on(n,a,o,c,e):Dkn(n,t)<0?(e&&(htt=c?ron(n):E$(n.l,n.m,n.h)),E$(0,0,0)):o_n(i?n:E$(n.l,n.m,n.h),t,o,c,r,e)}function Oqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;if(n.e&&n.c.ct.f||t.g>n.f)){for(e=0,i=0,a=n.w.a.ec().Kc();a.Ob();)r=_B(a.Pb(),11),dhn(Con(Mun(Hk(MMt,1),uVn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&++e;for(u=n.r.a.ec().Kc();u.Ob();)r=_B(u.Pb(),11),dhn(Con(Mun(Hk(MMt,1),uVn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&--e;for(o=t.w.a.ec().Kc();o.Ob();)r=_B(o.Pb(),11),dhn(Con(Mun(Hk(MMt,1),uVn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&++i;for(c=t.r.a.ec().Kc();c.Ob();)r=_B(c.Pb(),11),dhn(Con(Mun(Hk(MMt,1),uVn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&--i;e=0)return r=bbn(n,t.substr(1,c-1)),VUn(n,t.substr(c+1,u-(c+1)),r)}else{if(e=-1,null==ktt&&(ktt=new RegExp("\\d")),ktt.test(String.fromCharCode(a))&&(e=EK(t,VTn(46),u-1))>=0){i=_B(X5(n,Mtn(n,t.substr(1,e-1)),!1),58),o=0;try{o=h_n(t.substr(e+1),RVn,NWn)}catch(h){throw iL(h=hun(h),127)?Fp(new A7(h)):Fp(h)}if(o=0)return e;switch(NW(_7(n,e))){case 2:if(pK("",Sfn(n,e.Hj()).ne())){if(o=p$n(n,t,u=yV(_7(n,e)),mV(_7(n,e))))return o;for(a=0,s=(r=yKn(n,t)).gc();a1)throw Fp(new Ry(P7n));for(h=rxn(n.e.Tg(),t),i=_B(n.g,119),a=0;a1,h=new p6(b.b);v$(h.a)||v$(h.b);)l=(s=_B(v$(h.a)?Y1(h.a):Y1(h.b),17)).c==b?s.d:s.c,i.Math.abs(Con(Mun(Hk(MMt,1),uVn,8,0,[l.i.n,l.n,l.a])).b-u.b)>1&&dxn(n,s,u,a,b)}}function qqn(n){var t,e,r,c,a,u;if(c=new E2(n.e,0),r=new E2(n.a,0),n.d)for(e=0;eN3n;){for(a=t,u=0;i.Math.abs(t-a)0),c.a.Xb(c.c=--c.b),NFn(n,n.b-u,a,r,c),Mx(c.b0),r.a.Xb(r.c=--r.b)}if(!n.d)for(e=0;e0?(n.f[s.p]=l/(s.e.c.length+s.g.c.length),n.c=i.Math.min(n.c,n.f[s.p]),n.b=i.Math.max(n.b,n.f[s.p])):u&&(n.f[s.p]=l)}}function Uqn(n){n.b=null,n.bb=null,n.fb=null,n.qb=null,n.a=null,n.c=null,n.d=null,n.e=null,n.f=null,n.n=null,n.M=null,n.L=null,n.Q=null,n.R=null,n.K=null,n.db=null,n.eb=null,n.g=null,n.i=null,n.j=null,n.k=null,n.gb=null,n.o=null,n.p=null,n.q=null,n.r=null,n.$=null,n.ib=null,n.S=null,n.T=null,n.t=null,n.s=null,n.u=null,n.v=null,n.w=null,n.B=null,n.A=null,n.C=null,n.D=null,n.F=null,n.G=null,n.H=null,n.I=null,n.J=null,n.P=null,n.Z=null,n.U=null,n.V=null,n.W=null,n.X=null,n.Y=null,n._=null,n.ab=null,n.cb=null,n.hb=null,n.nb=null,n.lb=null,n.mb=null,n.ob=null,n.pb=null,n.jb=null,n.kb=null,n.N=!1,n.O=!1}function Xqn(n,t,e){var i,r;for(ITn(e,"Graph transformation ("+n.a+")",1),r=r0(t.a),i=new Ub(t.b);i.a0&&(n.a=u+(l-1)*r,t.c.b+=n.a,t.f.b+=n.a),0!=b.a.gc()&&(l=CGn(new sX(1,r),t,b,w,t.f.b+u-t.c.b))>0&&(t.f.b+=u+(l-1)*r)}function Vqn(n,t){var e,i,r,c;c=n.F,null==t?(n.F=null,Nsn(n,null)):(n.F=(mW(t),t),-1!=(i=HO(t,VTn(60)))?(r=t.substr(0,i),-1==HO(t,VTn(46))&&!pK(r,OWn)&&!pK(r,T9n)&&!pK(r,M9n)&&!pK(r,S9n)&&!pK(r,P9n)&&!pK(r,I9n)&&!pK(r,C9n)&&!pK(r,O9n)&&(r=A9n),-1!=(e=pN(t,VTn(62)))&&(r+=""+t.substr(e+1)),Nsn(n,r)):(r=t,-1==HO(t,VTn(46))&&(-1!=(i=HO(t,VTn(91)))&&(r=t.substr(0,i)),pK(r,OWn)||pK(r,T9n)||pK(r,M9n)||pK(r,S9n)||pK(r,P9n)||pK(r,I9n)||pK(r,C9n)||pK(r,O9n)?r=t:(r=A9n,-1!=i&&(r+=""+t.substr(i)))),Nsn(n,r),r==t&&(n.F=n.D))),0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,5,c,t))}function Qqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;if(!((d=t.b.c.length)<3)){for(b=L8(INt,oQn,25,d,15,1),f=0,h=new Ub(t.b);h.aa)&&jU(n.b,_B(g.b,17));++u}c=a}}}function Jqn(n,t){var e;if(null==t||pK(t,qWn))return null;if(0==t.length&&n.k!=(MPn(),dMt))return null;switch(n.k.g){case 1:return pgn(t,r5n)?(oN(),gtt):pgn(t,c5n)?(oN(),dtt):null;case 2:try{return tln(h_n(t,RVn,NWn))}catch(i){if(iL(i=hun(i),127))return null;throw Fp(i)}case 4:try{return fSn(t)}catch(i){if(iL(i=hun(i),127))return null;throw Fp(i)}case 3:return t;case 5:return ehn(n),FCn(n,t);case 6:return ehn(n),D$n(n,n.a,t);case 7:try{return(e=eAn(n)).Jf(t),e}catch(i){if(iL(i=hun(i),32))return null;throw Fp(i)}default:throw Fp(new Ky("Invalid type set for this layout option."))}}function Yqn(n){var t,e,i,r,c,a,u;for(Nnn(),u=new Xv,e=new Ub(n);e.a=u.b.c)&&(u.b=t),(!u.c||t.c<=u.c.c)&&(u.d=u.c,u.c=t),(!u.e||t.d>=u.e.d)&&(u.e=t),(!u.f||t.d<=u.f.d)&&(u.f=t);return i=new jpn((Cun(),Jat)),t2(n,aut,new Qy(Mun(Hk(Qat,1),FWn,369,0,[i]))),a=new jpn(nut),t2(n,cut,new Qy(Mun(Hk(Qat,1),FWn,369,0,[a]))),r=new jpn(Yat),t2(n,rut,new Qy(Mun(Hk(Qat,1),FWn,369,0,[r]))),c=new jpn(Zat),t2(n,iut,new Qy(Mun(Hk(Qat,1),FWn,369,0,[c]))),LLn(i.c,Jat),LLn(r.c,Yat),LLn(c.c,Zat),LLn(a.c,nut),u.a.c=L8(Cnt,FWn,1,0,5,1),wun(u.a,i.c),wun(u.a,nan(r.c)),wun(u.a,c.c),wun(u.a,nan(a.c)),u}function Zqn(n){var t;switch(n.d){case 1:if(n.hj())return-2!=n.o;break;case 2:if(n.hj())return-2==n.o;break;case 3:case 5:case 4:case 6:case 7:return n.o>-2;default:return!1}switch(t=n.gj(),n.p){case 0:return null!=t&&By(jD(t))!=QC(n.k,0);case 1:return null!=t&&_B(t,217).a!=bG(n.k)<<24>>24;case 2:return null!=t&&_B(t,172).a!=(bG(n.k)&WVn);case 6:return null!=t&&QC(_B(t,162).a,n.k);case 5:return null!=t&&_B(t,19).a!=bG(n.k);case 7:return null!=t&&_B(t,184).a!=bG(n.k)<<16>>16;case 3:return null!=t&&Hy(ED(t))!=n.j;case 4:return null!=t&&_B(t,155).a!=n.j;default:return null==t?null!=n.n:!$fn(t,n.n)}}function nGn(n,t,e){var i,r,c,a;return n.Fk()&&n.Ek()&&HC(a=Hz(n,_B(e,56)))!==HC(e)?(n.Oi(t),n.Ui(t,_9(n,t,a)),n.rk()&&(r=_B(e,49),c=n.Dk()?n.Bk()?r.ih(n.b,Svn(_B(ttn(yJ(n.b),n.aj()),18)).n,_B(ttn(yJ(n.b),n.aj()).Yj(),26).Bj(),null):r.ih(n.b,Cwn(r.Tg(),Svn(_B(ttn(yJ(n.b),n.aj()),18))),null,null):r.ih(n.b,-1-n.aj(),null,null),!_B(a,49).eh()&&(i=_B(a,49),c=n.Dk()?n.Bk()?i.gh(n.b,Svn(_B(ttn(yJ(n.b),n.aj()),18)).n,_B(ttn(yJ(n.b),n.aj()).Yj(),26).Bj(),c):i.gh(n.b,Cwn(i.Tg(),Svn(_B(ttn(yJ(n.b),n.aj()),18))),null,c):i.gh(n.b,-1-n.aj(),null,c)),c&&c.Fi()),pA(n.b)&&n.$i(n.Zi(9,e,a,t,!1)),a):e}function tGn(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(f=Hy(ED(pMn(n,(FXn(),kpt)))),r=Hy(ED(pMn(n,xpt))),oon(b=new Ju,kpt,f+r),v=(h=t).d,g=h.c.i,m=h.d.i,p=ZO(g.c),y=ZO(m.c),c=new $p,l=p;l<=y;l++)_l(o=new Ovn(n),(cSn(),Mut)),oon(o,(oWn(),blt),h),oon(o,npt,(WEn(),zIt)),oon(o,Ept,b),w=_B(Lq(n.b,l),29),l==p?Wyn(o,w.a.c.length-e,w):MZ(o,w),(k=Hy(ED(pMn(h,rgt))))<0&&oon(h,rgt,k=0),o.o.b=k,d=i.Math.floor(k/2),BIn(u=new SSn,(mUn(),SCt)),SZ(u,o),u.n.b=d,BIn(s=new SSn,aCt),SZ(s,o),s.n.b=d,EZ(h,u),Ban(a=new lJ,h),oon(a,ggt,null),TZ(a,s),EZ(a,v),qkn(o,h,a),c.c[c.c.length]=a,h=a;return c}function eGn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(u=_B(NSn(n,(mUn(),SCt)).Kc().Pb(),11).e,f=_B(NSn(n,aCt).Kc().Pb(),11).g,a=u.c.length,g=w1(_B(Lq(n.j,0),11));a-- >0;){for(h1(0,u.c.length),b=_B(u.c[0],17),h1(0,f.c.length),r=k7((i=_B(f.c[0],17)).d.e,i,0),C2(b,i.d,r),TZ(i,null),EZ(i,null),l=b.a,t&&NH(l,new lA(g)),e=upn(i.a,0);e.b!=e.d.c;)NH(l,new lA(_B(f3(e),8)));for(d=b.b,h=new Ub(i.b);h.a0&&(u=i.Math.max(u,hcn(n.C.b+r.d.b,c))),f=r,l=c,b=a;n.C&&n.C.c>0&&(w=b+n.C.c,h&&(w+=f.d.c),u=i.Math.max(u,(o$(),ein(sYn),i.Math.abs(l-1)<=sYn||1==l||isNaN(l)&&isNaN(1)?0:w/(1-l)))),e.n.b=0,e.a.a=u}function rGn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w;if(e=_B(aV(n.b,t),124),(s=_B(_B(o6(n.r,t),21),84)).dc())return e.n.d=0,void(e.n.a=0);for(h=n.u.Hc((hCn(),nCt)),u=0,n.A.Hc((pdn(),RCt))&&mRn(n,t),o=s.Kc(),f=null,b=0,l=0;o.Ob();)a=Hy(ED((r=_B(o.Pb(),111)).b.We((NN(),Art)))),c=r.b.rf().b,f?(w=l+f.d.a+n.w+r.d.d,u=i.Math.max(u,(o$(),ein(sYn),i.Math.abs(b-a)<=sYn||b==a||isNaN(b)&&isNaN(a)?0:w/(a-b)))):n.C&&n.C.d>0&&(u=i.Math.max(u,hcn(n.C.d+r.d.d,a))),f=r,b=a,l=c;n.C&&n.C.a>0&&(w=l+n.C.a,h&&(w+=f.d.a),u=i.Math.max(u,(o$(),ein(sYn),i.Math.abs(b-1)<=sYn||1==b||isNaN(b)&&isNaN(1)?0:w/(1-b)))),e.n.d=0,e.a.b=u}function cGn(n,t,e){var i,r,c,a,u,o;for(this.g=n,u=t.d.length,o=e.d.length,this.d=L8(Iut,r1n,10,u+o,0,1),a=0;a0?Qtn(this,this.f/this.a):null!=hL(t.g,t.d[0]).a&&null!=hL(e.g,e.d[0]).a?Qtn(this,(Hy(hL(t.g,t.d[0]).a)+Hy(hL(e.g,e.d[0]).a))/2):null!=hL(t.g,t.d[0]).a?Qtn(this,hL(t.g,t.d[0]).a):null!=hL(e.g,e.d[0]).a&&Qtn(this,hL(e.g,e.d[0]).a)}function aGn(n,t){var e,i,r,c,a,u,o,s,h;for(n.a=new _X(Ocn(UPt)),i=new Ub(t.a);i.a=1&&(g-a>0&&f>=0?(o.n.a+=d,o.n.b+=c*a):g-a<0&&h>=0&&(o.n.a+=d*g,o.n.b+=c));n.o.a=t.a,n.o.b=t.b,oon(n,(FXn(),Kgt),(pdn(),new VK(i=_B(Xj(VCt),9),_B(TR(i,i.length),9),0)))}function lGn(n,t,e,i,r,c){if(null!=t&&zbn(t,IAt,CAt))throw Fp(new Ry("invalid scheme: "+t));if(!(n||null!=e&&-1==HO(e,VTn(35))&&e.length>0&&(f1(0,e.length),47!=e.charCodeAt(0))))throw Fp(new Ry("invalid opaquePart: "+e));if(n&&(null==t||!LT(mAt,t.toLowerCase()))&&null!=e&&zbn(e,OAt,AAt))throw Fp(new Ry(a9n+e));if(n&&null!=t&<(mAt,t.toLowerCase())&&!SEn(e))throw Fp(new Ry(a9n+e));if(!Gbn(i))throw Fp(new Ry("invalid device: "+i));if(!xhn(r))throw Fp(new Ry(null==r?"invalid segments: null":"invalid segment: "+uhn(r)));if(null!=c&&-1!=HO(c,VTn(35)))throw Fp(new Ry("invalid query: "+c))}function bGn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(ITn(t,"Calculate Graph Size",1),t.n&&n&&v0(t,a2(n),(_sn(),cOt)),o=JYn,s=JYn,a=Y3n,u=Y3n,l=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));l.e!=l.i.gc();)d=(h=_B(mpn(l),33)).i,g=h.j,v=h.g,r=h.f,c=_B(JAn(h,(uWn(),OSt)),142),o=i.Math.min(o,d-c.b),s=i.Math.min(s,g-c.d),a=i.Math.max(a,d+v+c.c),u=i.Math.max(u,g+r+c.a);for(b=new LI(o-(w=_B(JAn(n,(uWn(),zSt)),116)).b,s-w.d),f=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));f.e!=f.i.gc();)Men(h=_B(mpn(f),33),h.i-b.a),Sen(h,h.j-b.b);p=a-o+(w.b+w.c),e=u-s+(w.d+w.a),Ten(n,p),Een(n,e),t.n&&n&&v0(t,a2(n),(_sn(),cOt))}function wGn(n){var t,e,i,r,c,a,u,o,s,h;for(i=new $p,a=new Ub(n.e.a);a.a0?(Mpn(n,e,0),e.a+=String.fromCharCode(i),Mpn(n,e,r=ign(t,c)),c+=r-1):39==i?c+11)for(d=L8(INt,oQn,25,n.b.b.c.length,15,1),f=0,h=new Ub(n.b.b);h.a=u&&r<=o)u<=r&&c<=o?(e[h++]=r,e[h++]=c,i+=2):u<=r?(e[h++]=r,e[h++]=o,n.b[i]=o+1,a+=2):c<=o?(e[h++]=u,e[h++]=c,i+=2):(e[h++]=u,e[h++]=o,n.b[i]=o+1);else{if(!(oDVn)&&o<10);Zk(n.c,new Et),vGn(n),PU(n.c),sGn(n.f)}function kGn(n,t,e){var i,r,c,a,u,o,s,h,f,l;if(By(jD(pMn(e,(FXn(),lgt)))))for(r=new Ub(e.j);r.a=2){for(a=_B(f3(o=upn(e,0)),8),u=_B(f3(o),8);u.a0&&Gun(o,!0,(Kfn(),KPt)),a.k==(cSn(),Eut)&&lV(o),XW(n.f,a,t)):((s=(i=_B(tJ(obn(a)),17)).c.i)==a&&(s=i.d.i),f=new eC(s,zR(_$(a.n),s.n)),XW(n.b,a,f))}function MGn(n,t,e){var r,c,a,u,o,s,h,f;switch(ITn(e,"Node promotion heuristic",1),n.g=t,vUn(n),n.q=_B(pMn(t,(FXn(),Tgt)),260),f=_B(pMn(n.g,Egt),19).a,a=new hi,n.q.g){case 2:case 1:RHn(n,a);break;case 3:for(n.q=(uNn(),Ivt),RHn(n,a),s=0,o=new Ub(n.a);o.an.j&&(n.q=jvt,RHn(n,a));break;case 4:for(n.q=(uNn(),Ivt),RHn(n,a),h=0,c=new Ub(n.b);c.an.k&&(n.q=Mvt,RHn(n,a));break;case 6:RHn(n,new ad(SY(i.Math.ceil(n.f.length*f/100))));break;case 5:RHn(n,new ud(SY(i.Math.ceil(n.d*f/100))));break;default:RHn(n,a)}aDn(n,t),FSn(e)}function SGn(n,t,e){var i,r,c,a;this.j=n,this.e=BEn(n),this.o=this.j.e,this.i=!!this.o,this.p=this.i?_B(Lq(e,gW(this.o).p),214):null,r=_B(pMn(n,(oWn(),Jft)),21),this.g=r.Hc((fDn(),hft)),this.b=new $p,this.d=new ldn(this.e),a=_B(pMn(this.j,Tlt),230),this.q=Fan(t,a,this.e),this.k=new rZ(this),c=c6(Mun(Hk(yst,1),FWn,225,0,[this,this.d,this.k,this.q])),t!=(ain(),Imt)||By(jD(pMn(n,(FXn(),Ldt))))?t==Imt&&By(jD(pMn(n,(FXn(),Ldt))))?(i=new GEn(this.e),c.c[c.c.length]=i,this.c=new drn(i,a,_B(this.q,402))):this.c=new gP(t,this):(i=new GEn(this.e),c.c[c.c.length]=i,this.c=new H2(i,a,_B(this.q,402))),UB(c,this.c),SHn(c,this.e),this.s=lXn(this.k)}function PGn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(l=(s=_B(tL(new lg(upn(new fg(t).a.d,0))),86))?_B(pMn(s,(Bqn(),ikt)),86):null,r=1;s&&l;){for(a=0,v=0,e=s,i=l,c=0;c=n.i?(++n.i,UB(n.a,tln(1)),UB(n.b,s)):(i=n.c[t.p][1],i5(n.a,o,tln(_B(Lq(n.a,o),19).a+1-i)),i5(n.b,o,Hy(ED(Lq(n.b,o)))+s-i*n.e)),(n.q==(uNn(),jvt)&&(_B(Lq(n.a,o),19).a>n.j||_B(Lq(n.a,o-1),19).a>n.j)||n.q==Mvt&&(Hy(ED(Lq(n.b,o)))>n.k||Hy(ED(Lq(n.b,o-1)))>n.k))&&(u=!1),c=new az(JL(sbn(t).a.Kc(),new h));bAn(c);)a=_B(G5(c),17).c.i,n.f[a.p]==o&&(r+=_B((f=IGn(n,a)).a,19).a,u=u&&By(jD(f.b)));return n.f[t.p]=o,new eC(tln(r+=n.c[t.p][0]),(oN(),!!u))}function CGn(n,t,e,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v;for(l=new Lp,u=new $p,eCn(n,e,n.d.fg(),u,l),eCn(n,r,n.d.gg(),u,l),n.b=.2*(g=_An(lnn(new xq(null,new l1(u,16)),new Sa)),p=_An(lnn(new xq(null,new l1(u,16)),new Pa)),i.Math.min(g,p)),a=0,o=0;o=2&&(v=WLn(u,!0,b),!n.e&&(n.e=new hg(n)),ugn(n.e,v,u,n.b)),tTn(u,b),izn(u),w=-1,f=new Ub(u);f.au)}function $Gn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g;for(e=_B(pMn(n,(FXn(),npt)),98),u=n.f,a=n.d,o=u.a+a.b+a.c,s=0-a.d-n.c.b,f=u.b+a.d+a.a-n.c.b,h=new $p,l=new $p,c=new Ub(t);c.a0),c=_B(s.a.Xb(s.c=--s.b),17);c!=i&&s.b>0;)n.a[c.p]=!0,n.a[i.p]=!0,Mx(s.b>0),c=_B(s.a.Xb(s.c=--s.b),17);s.b>0&&sW(s)}}function BGn(n,t,e){var i,r,c,a,u,o,s,h,f;if(n.a!=t.Aj())throw Fp(new Ry(b6n+t.ne()+w6n));if(i=Sfn((PPn(),Q$t),t).$k())return i.Aj().Nh().Ih(i,e);if(a=Sfn(Q$t,t).al()){if(null==e)return null;if((u=_B(e,15)).dc())return"";for(f=new Tk,c=u.Kc();c.Ob();)r=c.Pb(),iO(f,a.Aj().Nh().Ih(a,r)),f.a+=" ";return DO(f,f.a.length-1)}if(!(h=Sfn(Q$t,t).bl()).dc()){for(s=h.Kc();s.Ob();)if((o=_B(s.Pb(),148)).wj(e))try{if(null!=(f=o.Aj().Nh().Ih(o,e)))return f}catch(l){if(!iL(l=hun(l),102))throw Fp(l)}throw Fp(new Ry("Invalid value: '"+e+"' for datatype :"+t.ne()))}return _B(t,834).Fj(),null==e?null:iL(e,172)?""+_B(e,172).a:Zon(e)==ptt?F$(POt[0],_B(e,199)):_bn(e)}function HGn(n){var t,e,r,c,a,u,o,s,h;for(s=new VT,u=new VT,c=new Ub(n);c.a-1){for(r=upn(u,0);r.b!=r.d.c;)(e=_B(f3(r),128)).v=a;for(;0!=u.b;)for(t=new Ub((e=_B(Zyn(u,0),128)).i);t.a0&&(e+=o.n.a+o.o.a/2,++f),b=new Ub(o.j);b.a0&&(e/=f),g=L8($Nt,BQn,25,i.a.c.length,15,1),u=0,s=new Ub(i.a);s.a=u&&r<=o)u<=r&&c<=o?i+=2:u<=r?(n.b[i]=o+1,a+=2):c<=o?(e[h++]=r,e[h++]=u-1,i+=2):(e[h++]=r,e[h++]=u-1,n.b[i]=o+1,a+=2);else{if(!(o0?r-=864e5:r+=864e5,o=new MD(ebn(san(t.q.getTime()),r))),h=new Pk,s=n.a.length,c=0;c=97&&i<=122||i>=65&&i<=90){for(a=c+1;a=s)throw Fp(new Ry("Missing trailing '"));a+10&&0==e.c&&(!t&&(t=new $p),t.c[t.c.length]=e);if(t)for(;0!=t.c.length;){if((e=_B(u6(t,0),233)).b&&e.b.c.length>0)for(!e.b&&(e.b=new $p),c=new Ub(e.b);c.ak7(n,e,0))return new eC(r,e)}else if(Hy(hL(r.g,r.d[0]).a)>Hy(hL(e.g,e.d[0]).a))return new eC(r,e);for(u=(!e.e&&(e.e=new $p),e.e).Kc();u.Ob();)!(a=_B(u.Pb(),233)).b&&(a.b=new $p),AZ(0,(o=a.b).c.length),ES(o.c,0,e),a.c==o.c.length&&(t.c[t.c.length]=a)}return null}function tzn(n,t){var e,i,r,c,a,u;if(null==n)return qWn;if(null!=t.a.zc(n,t))return"[...]";for(e=new Oan(KWn,"[","]"),c=0,a=(r=n).length;c=14&&u<=16?iL(i,177)?f6(e,xIn(_B(i,177))):iL(i,190)?f6(e,QEn(_B(i,190))):iL(i,195)?f6(e,mSn(_B(i,195))):iL(i,2012)?f6(e,JEn(_B(i,2012))):iL(i,48)?f6(e,NIn(_B(i,48))):iL(i,364)?f6(e,wCn(_B(i,364))):iL(i,832)?f6(e,LIn(_B(i,832))):iL(i,104)&&f6(e,$In(_B(i,104))):t.a._b(i)?(e.a?aO(e.a,e.b):e.a=new hN(e.d),rO(e.a,"[...]")):f6(e,tzn(nen(i),new Oq(t))):f6(e,null==i?qWn:_bn(i));return e.a?0==e.e.length?e.a.a:e.a.a+""+e.e:e.c}function ezn(n,t,e,r){var c,a,u,o,s,h,f,l,b,w,d,g;for(w=BSn(iDn(t,!1,!1)),r&&(w=Qon(w)),g=Hy(ED(JAn(t,(kpn(),dct)))),Mx(0!=w.b),b=_B(w.a.a.c,8),h=_B(Npn(w,1),8),w.b>2?(wun(s=new $p,new u1(w,1,w.b)),Ban(d=new kAn(zXn(s,g+n.a)),t),e.c[e.c.length]=d):d=_B(xX(n.b,r?MMn(t):IMn(t)),266),u=MMn(t),r&&(u=IMn(t)),a=tPn(b,u),o=g+n.a,a.a?(o+=i.Math.abs(b.b-h.b),l=new LI(h.a,(h.b+b.b)/2)):(o+=i.Math.abs(b.a-h.a),l=new LI((h.a+b.a)/2,h.b)),XW(r?n.d:n.c,t,new Pmn(d,a,l,o)),XW(n.b,t,d),!t.n&&(t.n=new nU(HOt,t,1,7)),f=new CL(t.n);f.e!=f.i.gc();)c=QRn(n,_B(mpn(f),137),!0,0,0),e.c[e.c.length]=c}function izn(n){var t,e,r,c,a,u,o,s,h;for(s=new $p,u=new $p,a=new Ub(n);a.a-1){for(c=new Ub(u);c.a0||(Vl(o,i.Math.min(o.o,r.o-1)),Wl(o,o.i-1),0==o.i&&(u.c[u.c.length]=o))}}function rzn(n,t,e){var i,r,c,a,u;if(u=n.c,!t&&(t=O$t),n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&(a=new Yz(n,1,2,u,n.c),e?e.Ei(a):e=a),u!=t)if(iL(n.Cb,284))n.Db>>16==-10?e=_B(n.Cb,284).nk(t,e):n.Db>>16==-15&&(!t&&(wWn(),t=s$t),!u&&(wWn(),u=s$t),n.Cb.nh()&&(a=new $7(n.Cb,1,13,u,t,cvn(F7(_B(n.Cb,59)),n),!1),e?e.Ei(a):e=a));else if(iL(n.Cb,88))n.Db>>16==-23&&(iL(t,88)||(wWn(),t=l$t),iL(u,88)||(wWn(),u=l$t),n.Cb.nh()&&(a=new $7(n.Cb,1,10,u,t,cvn(r4(_B(n.Cb,26)),n),!1),e?e.Ei(a):e=a));else if(iL(n.Cb,444))for(!(c=_B(n.Cb,836)).b&&(c.b=new jp(new Lm)),r=new Ep(new csn(new Mb(c.b.a).a));r.a.b;)e=rzn(i=_B(Ztn(r.a).cd(),87),mLn(i,c),e);return e}function czn(n,t){var e,i,r,c,a,u,o,s,h,f,l;for(a=By(jD(JAn(n,(FXn(),lgt)))),l=_B(JAn(n,ipt),21),o=!1,s=!1,f=new CL((!n.c&&(n.c=new nU(GOt,n,9,9)),n.c));!(f.e==f.i.gc()||o&&s);){for(c=_B(mpn(f),118),u=0,r=$U(Uen(Mun(Hk(Lnt,1),FWn,20,0,[(!c.d&&(c.d=new oK(DOt,c,8,5)),c.d),(!c.e&&(c.e=new oK(DOt,c,7,4)),c.e)])));bAn(r)&&(i=_B(G5(r),79),h=a&&WCn(i)&&By(jD(JAn(i,bgt))),e=fqn((!i.b&&(i.b=new oK(xOt,i,4,7)),i.b),c)?n==QY(MTn(_B(Utn((!i.c&&(i.c=new oK(xOt,i,5,8)),i.c),0),82))):n==QY(MTn(_B(Utn((!i.b&&(i.b=new oK(xOt,i,4,7)),i.b),0),82))),!((h||e)&&++u>1)););(u>0||l.Hc((hCn(),nCt))&&(!c.n&&(c.n=new nU(HOt,c,1,7)),c.n).i>0)&&(o=!0),u>1&&(s=!0)}o&&t.Fc((fDn(),hft)),s&&t.Fc((fDn(),fft))}function azn(n){var t,e,r,c,a,u,o,s,h,f,l,b;if((b=_B(JAn(n,(uWn(),DSt)),21)).dc())return null;if(o=0,u=0,b.Hc((pdn(),DCt))){for(f=_B(JAn(n,cPt),98),r=2,e=2,c=2,a=2,t=QY(n)?_B(JAn(QY(n),fSt),103):_B(JAn(n,fSt),103),h=new CL((!n.c&&(n.c=new nU(GOt,n,9,9)),n.c));h.e!=h.i.gc();)if(s=_B(mpn(h),118),(l=_B(JAn(s,lPt),61))==(mUn(),MCt)&&(l=IFn(s,t),Vpn(s,lPt,l)),f==(WEn(),zIt))switch(l.g){case 1:r=i.Math.max(r,s.i+s.g);break;case 2:e=i.Math.max(e,s.j+s.f);break;case 3:c=i.Math.max(c,s.i+s.g);break;case 4:a=i.Math.max(a,s.j+s.f)}else switch(l.g){case 1:r+=s.g+2;break;case 2:e+=s.f+2;break;case 3:c+=s.g+2;break;case 4:a+=s.f+2}o=i.Math.max(r,c),u=i.Math.max(e,a)}return DUn(n,o,u,!0,!0)}function uzn(n,t,e,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(m=_B(M4(vtn(CV(new xq(null,new l1(t.d,16)),new Od(e)),new Ad(e)),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),Get)]))),15),l=NWn,f=RVn,s=new Ub(t.b.j);s.a0)?s&&(h=d.p,a?++h:--h,f=!(iNn(i=ton(_B(Lq(d.c.a,h),10)),y,e[0])||_z(i,y,e[0]))):f=!0),l=!1,(m=t.D.i)&&m.c&&u.e&&(a&&m.p>0||!a&&m.p0&&(t.a+=KWn),wzn(_B(mpn(a),160),t);for(t.a+=n1n,u=new ix((!i.c&&(i.c=new oK(xOt,i,5,8)),i.c));u.e!=u.i.gc();)u.e>0&&(t.a+=KWn),wzn(_B(mpn(u),160),t);t.a+=")"}}}function dzn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(c=_B(pMn(n,(oWn(),blt)),79)){for(i=n.a,GR(r=new lA(e),Ojn(n)),lan(n.d.i,n.c.i)?(l=n.c,zR(f=Con(Mun(Hk(MMt,1),uVn,8,0,[l.n,l.a])),e)):f=w1(n.c),e5(i,f,i.a,i.a.a),b=w1(n.d),null!=pMn(n,xlt)&&GR(b,_B(pMn(n,xlt),8)),e5(i,b,i.c.b,i.c),Jtn(i,r),Ain(a=iDn(c,!0,!0),_B(Utn((!c.b&&(c.b=new oK(xOt,c,4,7)),c.b),0),82)),$in(a,_B(Utn((!c.c&&(c.c=new oK(xOt,c,5,8)),c.c),0),82)),XFn(i,a),h=new Ub(n.b);h.a=0){for(o=null,u=new E2(h.a,s+1);u.ba?1:qO(isNaN(0),isNaN(a)))<0&&(ein(C3n),(i.Math.abs(a-1)<=C3n||1==a||isNaN(a)&&isNaN(1)?0:a<1?-1:a>1?1:qO(isNaN(a),isNaN(1)))<0)&&(ein(C3n),(i.Math.abs(0-u)<=C3n||0==u||isNaN(0)&&isNaN(u)?0:0u?1:qO(isNaN(0),isNaN(u)))<0)&&(ein(C3n),(i.Math.abs(u-1)<=C3n||1==u||isNaN(u)&&isNaN(1)?0:u<1?-1:u>1?1:qO(isNaN(u),isNaN(1)))<0))}function vzn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j;for(f=new oW(new tw(n));f.b!=f.c.a.d;)for(u=_B((h=u9(f)).d,56),t=_B(h.e,56),d=0,y=(null==(a=u.Tg()).i&&BFn(a),a.i).length;d=0&&d=s.c.c.length?z3((cSn(),Sut),Mut):z3((cSn(),Mut),Mut),h*=2,c=e.a.g,e.a.g=i.Math.max(c,c+(h-c)),a=e.b.g,e.b.g=i.Math.max(a,a+(h-a)),r=t}else qAn(u),CHn((h1(0,u.c.length),_B(u.c[0],17)).d.i)||UB(n.o,u)}function kzn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(m=HB(n),o=new $p,s=(c=n.c.length)-1,h=c+1;0!=m.a.c;){for(;0!=e.b;)Mx(0!=e.b),p=_B(Ctn(e,e.a.a),112),OY(m.a,p),p.g=s--,$Fn(p,t,e,i);for(;0!=t.b;)Mx(0!=t.b),v=_B(Ctn(t,t.a.a),112),OY(m.a,v),v.g=h++,$Fn(v,t,e,i);for(u=RVn,d=new Kb(new _R(new LN(new Rb(m.a).a).b));rS(d.a.a);){if(w=_B(px(d.a).cd(),112),!i&&w.b>0&&w.a<=0){o.c=L8(Cnt,FWn,1,0,5,1),o.c[o.c.length]=w;break}(b=w.i-w.d)>=u&&(b>u&&(o.c=L8(Cnt,FWn,1,0,5,1),u=b),o.c[o.c.length]=w)}0!=o.c.length&&(a=_B(Lq(o,dvn(r,o.c.length)),112),OY(m.a,a),a.g=h++,$Fn(a,t,e,i),o.c=L8(Cnt,FWn,1,0,5,1))}for(g=n.c.length+1,l=new Ub(n);l.a0&&(b.d+=f.n.d,b.d+=f.d),b.a>0&&(b.a+=f.n.a,b.a+=f.d),b.b>0&&(b.b+=f.n.b,b.b+=f.d),b.c>0&&(b.c+=f.n.c,b.c+=f.d),b}function Szn(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d;for(b=e.d,l=e.c,u=(a=new LI(e.f.a+e.d.b+e.d.c,e.f.b+e.d.d+e.d.a)).b,h=new Ub(n.a);h.a0&&(n.c[t.c.p][t.p].d+=F$n(n.i,24)*cJn*.07000000029802322-.03500000014901161,n.c[t.c.p][t.p].a=n.c[t.c.p][t.p].d/n.c[t.c.p][t.p].b)}}function Nzn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w;for(l=new Ub(n);l.ar.d,r.d=i.Math.max(r.d,t),o&&e&&(r.d=i.Math.max(r.d,r.a),r.a=r.d+c);break;case 3:e=t>r.a,r.a=i.Math.max(r.a,t),o&&e&&(r.a=i.Math.max(r.a,r.d),r.d=r.a+c);break;case 2:e=t>r.c,r.c=i.Math.max(r.c,t),o&&e&&(r.c=i.Math.max(r.b,r.c),r.b=r.c+c);break;case 4:e=t>r.b,r.b=i.Math.max(r.b,t),o&&e&&(r.b=i.Math.max(r.b,r.c),r.c=r.b+c)}}}function Kzn(n){var t,e,i,r,c,a,u,o,s,h,f;for(s=new Ub(n);s.a0||h.j==SCt&&h.e.c.length-h.g.c.length<0)){t=!1;break}for(r=new Ub(h.g);r.a=h&&j>=p&&(b+=d.n.b+g.n.b+g.a.b-k,++o));if(e)for(u=new Ub(m.e);u.a=h&&j>=p&&(b+=d.n.b+g.n.b+g.a.b-k,++o))}o>0&&(E+=b/o,++w)}w>0?(t.a=c*E/w,t.g=w):(t.a=0,t.g=0)}function Fzn(n,t){var e,i,r,c,a,u,o,s,h,f;for(i=new Ub(n.a.b);i.aDQn||t.o==eyt&&s0&&Men(p,y*j),k>0&&Sen(p,k*E);for(Ycn(n.b,new lt),t=new $p,u=new csn(new Mb(n.c).a);u.b;)i=_B((a=Ztn(u)).cd(),79),e=_B(a.dd(),395).a,r=iDn(i,!1,!1),XFn(f=hTn(MMn(i),BSn(r),e),r),(m=SMn(i))&&-1==k7(t,m,0)&&(t.c[t.c.length]=m,uQ(m,(Mx(0!=f.b),_B(f.a.a.c,8)),e));for(g=new csn(new Mb(n.d).a);g.b;)i=_B((d=Ztn(g)).cd(),79),e=_B(d.dd(),395).a,r=iDn(i,!1,!1),f=hTn(IMn(i),Qon(BSn(r)),e),XFn(f=Qon(f),r),(m=PMn(i))&&-1==k7(t,m,0)&&(t.c[t.c.length]=m,uQ(m,(Mx(0!=f.b),_B(f.c.b.c,8)),e))}function zzn(n,t,e,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;if(0!=e.c.length){for(w=new $p,b=new Ub(e);b.a1)for(n5(m,new uI(n,b=new oqn(w,m,r))),u.c[u.c.length]=b,f=m.a.ec().Kc();f.Ob();)v7(a,_B(f.Pb(),46).b);if(o.a.gc()>1)for(n5(o,new oI(n,b=new oqn(w,o,r))),u.c[u.c.length]=b,f=o.a.ec().Kc();f.Ob();)v7(a,_B(f.Pb(),46).b)}}function Zzn(n){$M(n,new ETn(bj(gj(lj(dj(wj(new du,l4n),"ELK Radial"),'A radial layout provider which is based on the algorithm of Peter Eades published in "Drawing free trees.", published by International Institute for Advanced Study of Social Information Science, Fujitsu Limited in 1991. The radial layouter takes a tree and places the nodes in radial order around the root. The nodes of the same tree level are placed on the same radius.'),new Ha),l4n))),c2(n,l4n,w3n,ppn(Ljt)),c2(n,l4n,gZn,ppn(Djt)),c2(n,l4n,MZn,ppn(Sjt)),c2(n,l4n,_Zn,ppn(Pjt)),c2(n,l4n,TZn,ppn(Ijt)),c2(n,l4n,SZn,ppn(Mjt)),c2(n,l4n,EZn,ppn(Cjt)),c2(n,l4n,PZn,ppn($jt)),c2(n,l4n,o4n,ppn(Ejt)),c2(n,l4n,u4n,ppn(Tjt)),c2(n,l4n,f4n,ppn(Ojt)),c2(n,l4n,c4n,ppn(Ajt)),c2(n,l4n,a4n,ppn(Njt)),c2(n,l4n,s4n,ppn(xjt)),c2(n,l4n,h4n,ppn(Rjt))}function nUn(n){var t;if(this.r=LV(new Pn,new In),this.b=new Fbn(_B(vX(KCt),290)),this.p=new Fbn(_B(vX(KCt),290)),this.i=new Fbn(_B(vX(Drt),290)),this.e=n,this.o=new lA(n.rf()),this.D=n.Df()||By(jD(n.We((uWn(),TSt)))),this.A=_B(n.We((uWn(),DSt)),21),this.B=_B(n.We(BSt),21),this.q=_B(n.We(cPt),98),this.u=_B(n.We(sPt),21),!lMn(this.u))throw Fp(new ek("Invalid port label placement: "+this.u));if(this.v=By(jD(n.We(fPt))),this.j=_B(n.We(NSt),21),!Z$n(this.j))throw Fp(new ek("Invalid node label placement: "+this.j));this.n=_B(Yyn(n,$St),116),this.k=Hy(ED(Yyn(n,IPt))),this.d=Hy(ED(Yyn(n,PPt))),this.w=Hy(ED(Yyn(n,xPt))),this.s=Hy(ED(Yyn(n,CPt))),this.t=Hy(ED(Yyn(n,OPt))),this.C=_B(Yyn(n,LPt),142),this.c=2*this.d,t=!this.B.Hc((YKn(),FCt)),this.f=new Pgn(0,t,0),this.g=new Pgn(1,t,0),yy(this.f,(Ntn(),qit),this.g)}function tUn(n,t,e,r,c){var a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S;for(y=0,g=0,d=0,w=1,m=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));m.e!=m.i.gc();)w+=K3(new az(JL(bLn(p=_B(mpn(m),33)).a.Kc(),new h))),T=p.g,g=i.Math.max(g,T),b=p.f,d=i.Math.max(d,b),y+=T*b;for(u=y+2*r*r*w*(!n.a&&(n.a=new nU(qOt,n,10,11)),n.a).i,a=i.Math.sqrt(u),s=i.Math.max(a*e,g),o=i.Math.max(a/e,d),v=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));v.e!=v.i.gc();)p=_B(mpn(v),33),M=c.b+(F$n(t,26)*eJn+F$n(t,27)*iJn)*(s-p.g),S=c.b+(F$n(t,26)*eJn+F$n(t,27)*iJn)*(o-p.f),Men(p,M),Sen(p,S);for(E=s+(c.b+c.c),j=o+(c.d+c.a),k=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));k.e!=k.i.gc();)for(l=new az(JL(bLn(_B(mpn(k),33)).a.Kc(),new h));bAn(l);)YOn(f=_B(G5(l),79))||_Xn(f,t,E,j);DUn(n,E+=c.b+c.c,j+=c.d+c.a,!1,!0)}function eUn(n){var t,e,i,r,c,a,u,o,s,h,f;if(null==n)throw Fp(new Ek(qWn));if(s=n,o=!1,(c=n.length)>0&&(f1(0,n.length),45!=(t=n.charCodeAt(0))&&43!=t||(n=n.substr(1),--c,o=45==t)),0==c)throw Fp(new Ek(NQn+s+'"'));for(;n.length>0&&(f1(0,n.length),48==n.charCodeAt(0));)n=n.substr(1),--c;if(c>(tFn(),Ltt)[10])throw Fp(new Ek(NQn+s+'"'));for(r=0;r0&&(f=-parseInt(n.substr(0,i),10),n=n.substr(i),c-=i,e=!1);c>=a;){if(i=parseInt(n.substr(0,a),10),n=n.substr(a),c-=a,e)e=!1;else{if(Xhn(f,u)<0)throw Fp(new Ek(NQn+s+'"'));f=ibn(f,h)}f=tbn(f,i)}if(Xhn(f,0)>0)throw Fp(new Ek(NQn+s+'"'));if(!o&&Xhn(f=y7(f),0)<0)throw Fp(new Ek(NQn+s+'"'));return f}function iUn(n,t){var e,i,r,c,a,u,o;if(JH(),this.a=new z$(this),this.b=n,this.c=t,this.f=IU(_7((PPn(),Q$t),t)),this.f.dc())if((u=pjn(Q$t,n))==t)for(this.e=!0,this.d=new $p,this.f=new fo,this.f.Fc(T7n),_B($Hn(K7(Q$t,Gtn(n)),""),26)==n&&this.f.Fc(rz(Q$t,Gtn(n))),r=kKn(Q$t,n).Kc();r.Ob();)switch(i=_B(r.Pb(),170),NW(_7(Q$t,i))){case 4:this.d.Fc(i);break;case 5:this.f.Gc(IU(_7(Q$t,i)))}else if(JM(),_B(t,66).Oj())for(this.e=!0,this.f=null,this.d=new $p,a=0,o=(null==n.i&&BFn(n),n.i).length;a=0&&a0&&(_B(aV(n.b,t),124).a.b=e)}function cUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(ITn(t,"Comment pre-processing",1),e=0,o=new Ub(n.a);o.a0&&(f1(0,t.length),64!=(u=t.charCodeAt(0)))){if(37==u&&(o=!1,0!=(h=t.lastIndexOf("%"))&&(h==f-1||(f1(h+1,t.length),o=46==t.charCodeAt(h+1))))){if(v=pK("%",a=t.substr(1,h-1))?null:OUn(a),i=0,o)try{i=h_n(t.substr(h+2),RVn,NWn)}catch(m){throw iL(m=hun(m),127)?Fp(new A7(m)):Fp(m)}for(d=krn(n.Wg());d.Ob();)if(iL(b=Ean(d),510)&&(p=(r=_B(b,590)).d,(null==v?null==p:pK(v,p))&&0==i--))return r;return null}if(l=-1==(s=t.lastIndexOf("."))?t:t.substr(0,s),e=0,-1!=s)try{e=h_n(t.substr(s+1),RVn,NWn)}catch(m){if(!iL(m=hun(m),127))throw Fp(m);l=t}for(l=pK("%",l)?null:OUn(l),w=krn(n.Wg());w.Ob();)if(iL(b=Ean(w),191)&&(g=(c=_B(b,191)).ne(),(null==l?null==g:pK(l,g))&&0==e--))return c;return null}return Rqn(n,t)}function sUn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T;for(m=new $p,f=new Ub(n.b);f.a=n.length)return{done:!0};var i=n[e++];return{value:[i,t.get(i)],done:!1}}}},qDn()||(n.prototype.createObject=function(){return{}},n.prototype.get=function(n){return this.obj[":"+n]},n.prototype.set=function(n,t){this.obj[":"+n]=t},n.prototype[tJn]=function(n){delete this.obj[":"+n]},n.prototype.keys=function(){var n=[];for(var t in this.obj)58==t.charCodeAt(0)&&n.push(t.substring(1));return n}),n}function lUn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d;if(MFn(),null==n)return null;if(0==(f=8*n.length))return"";for(l=f/24|0,c=null,c=L8(PNt,UVn,25,4*(0!=(u=f%24)?l+1:l),15,1),s=0,h=0,t=0,e=0,i=0,a=0,r=0,o=0;o>24,s=(3&t)<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,w=0==(-128&e)?e>>4<<24>>24:(e>>4^240)<<24>>24,d=0==(-128&(i=n[r++]))?i>>6<<24>>24:(i>>6^252)<<24>>24,c[a++]=ULt[b],c[a++]=ULt[w|s<<4],c[a++]=ULt[h<<2|d],c[a++]=ULt[63&i];return 8==u?(s=(3&(t=n[r]))<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,c[a++]=ULt[b],c[a++]=ULt[s<<4],c[a++]=61,c[a++]=61):16==u&&(t=n[r],h=(15&(e=n[r+1]))<<24>>24,s=(3&t)<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,w=0==(-128&e)?e>>4<<24>>24:(e>>4^240)<<24>>24,c[a++]=ULt[b],c[a++]=ULt[w|s<<4],c[a++]=ULt[h<<2],c[a++]=61),_dn(c,0,c.length)}function bUn(n,t){var e,r,c,a,u,o;if(0==n.e&&n.p>0&&(n.p=-(n.p-1)),n.p>RVn&&n4(t,n.p-uQn),u=t.q.getDate(),KY(t,1),n.k>=0&&gZ(t,n.k),n.c>=0?KY(t,n.c):n.k>=0?(r=35-new gon(t.q.getFullYear()-uQn,t.q.getMonth(),35).q.getDate(),KY(t,i.Math.min(r,u))):KY(t,u),n.f<0&&(n.f=t.q.getHours()),n.b>0&&n.f<12&&(n.f+=12),rL(t,24==n.f&&n.g?0:n.f),n.j>=0&&w6(t,n.j),n.n>=0&&G8(t,n.n),n.i>=0&&bO(t,ebn(ibn(Ijn(san(t.q.getTime()),XVn),XVn),n.i)),n.a&&(n4(c=new CT,c.q.getFullYear()-uQn-80),uS(san(t.q.getTime()),san(c.q.getTime()))&&n4(t,c.q.getFullYear()-uQn+100)),n.d>=0)if(-1==n.c)(e=(7+n.d-t.q.getDay())%7)>3&&(e-=7),o=t.q.getMonth(),KY(t,t.q.getDate()+e),t.q.getMonth()!=o&&KY(t,t.q.getDate()+(e>0?-7:7));else if(t.q.getDay()!=n.d)return!1;return n.o>RVn&&(a=t.q.getTimezoneOffset(),bO(t,ebn(san(t.q.getTime()),60*(n.o-a)*XVn))),!0}function wUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;if(iL(r=pMn(t,(oWn(),blt)),239)){for(b=_B(r,33),w=t.e,f=new lA(t.c),c=t.d,f.a+=c.b,f.b+=c.d,TN(_B(JAn(b,(FXn(),Bgt)),174),(YKn(),BCt))&&(Il(l=_B(JAn(b,qgt),116),c.a),Rl(l,c.d),Cl(l,c.b),Kl(l,c.c)),e=new $p,s=new Ub(t.a);s.a0&&UB(n.p,l),UB(n.o,l);d=s+(t-=r),f+=t*n.e,i5(n.a,o,tln(d)),i5(n.b,o,f),n.j=i.Math.max(n.j,d),n.k=i.Math.max(n.k,f),n.d+=t,t+=p}}function mUn(){var n;mUn=O,MCt=new UI(oYn,0),uCt=new UI(pYn,1),aCt=new UI(vYn,2),TCt=new UI(mYn,3),SCt=new UI(yYn,4),TQ(),lCt=new Ck(new VK(n=_B(Xj(KCt),9),_B(TR(n,n.length),9),0)),bCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[]))),oCt=sfn(kG(aCt,Mun(Hk(KCt,1),VZn,61,0,[]))),kCt=sfn(kG(TCt,Mun(Hk(KCt,1),VZn,61,0,[]))),ECt=sfn(kG(SCt,Mun(Hk(KCt,1),VZn,61,0,[]))),vCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[TCt]))),fCt=sfn(kG(aCt,Mun(Hk(KCt,1),VZn,61,0,[SCt]))),yCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[SCt]))),wCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[aCt]))),jCt=sfn(kG(TCt,Mun(Hk(KCt,1),VZn,61,0,[SCt]))),sCt=sfn(kG(aCt,Mun(Hk(KCt,1),VZn,61,0,[TCt]))),pCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[aCt,SCt]))),hCt=sfn(kG(aCt,Mun(Hk(KCt,1),VZn,61,0,[TCt,SCt]))),mCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[TCt,SCt]))),dCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[aCt,TCt]))),gCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[aCt,TCt,SCt])))}function yUn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;if(0!=t.b){for(l=new VT,a=null,b=null,e=SY(i.Math.floor(i.Math.log(t.b)*i.Math.LOG10E)+1),u=0,v=upn(t,0);v.b!=v.d.c;)for(g=_B(f3(v),86),HC(b)!==HC(pMn(g,(Bqn(),ekt)))&&(b=TD(pMn(g,ekt)),u=0),a=null!=b?b+b0(u++,e):b0(u++,e),oon(g,ekt,a),d=new lg(upn(new fg(g).a.d,0));kE(d.a);)e5(l,w=_B(f3(d.a),188).c,l.c.b,l.c),oon(w,ekt,a);for(f=new Lp,c=0;c=s){Mx(v.b>0),v.a.Xb(v.c=--v.b);break}g.a>h&&(c?(wun(c.b,g.b),c.a=i.Math.max(c.a,g.a),sW(v)):(UB(g.b,l),g.c=i.Math.min(g.c,h),g.a=i.Math.max(g.a,s),c=g))}c||((c=new tm).c=h,c.a=s,vR(v,c),UB(c.b,l))}for(o=t.b,f=0,p=new Ub(r);p.au?1:0:(n.b&&(n.b._b(c)&&(r=_B(n.b.xc(c),19).a),n.b._b(o)&&(u=_B(n.b.xc(o),19).a)),ru?1:0)):0!=t.e.c.length&&0!=e.g.c.length?1:-1}function EUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(ITn(t,I1n,1),w=new $p,y=new $p,s=new Ub(n.b);s.a0&&(k-=d),jqn(u,k),l=0,w=new Ub(u.a);w.a0),o.a.Xb(o.c=--o.b)),s=.4*r*l,!a&&o.bt.d.c){if((b=n.c[t.a.d])==(g=n.c[f.a.d]))continue;GNn(rM(iM(cM(eM(new Fv,1),100),b),g))}}}function OUn(n){var t,e,i,r,c,a,u,o;if(xHn(),null==n)return null;if((r=HO(n,VTn(37)))<0)return n;for(o=new hN(n.substr(0,r)),t=L8(ANt,g6n,25,4,15,1),u=0,i=0,a=n.length;rr+2&&Zun((f1(r+1,n.length),n.charCodeAt(r+1)),SAt,PAt)&&Zun((f1(r+2,n.length),n.charCodeAt(r+2)),SAt,PAt))if(e=SH((f1(r+1,n.length),n.charCodeAt(r+1)),(f1(r+2,n.length),n.charCodeAt(r+2))),r+=2,i>0?128==(192&e)?t[u++]=e<<24>>24:i=0:e>=128&&(192==(224&e)?(t[u++]=e<<24>>24,i=2):224==(240&e)?(t[u++]=e<<24>>24,i=3):240==(248&e)&&(t[u++]=e<<24>>24,i=4)),i>0){if(u==i){switch(u){case 2:LX(o,((31&t[0])<<6|63&t[1])&WVn);break;case 3:LX(o,((15&t[0])<<12|(63&t[1])<<6|63&t[2])&WVn)}u=0,i=0}}else{for(c=0;c0){if(a+i>n.length)return!1;u=GCn(n.substr(0,a+i),t)}else u=GCn(n,t);switch(c){case 71:return u=qTn(n,a,Mun(Hk(Wtt,1),uVn,2,6,[sQn,hQn]),t),r.e=u,!0;case 77:return wDn(n,t,r,u,a);case 76:return dDn(n,t,r,u,a);case 69:return eIn(n,t,a,r);case 99:return iIn(n,t,a,r);case 97:return u=qTn(n,a,Mun(Hk(Wtt,1),uVn,2,6,["AM","PM"]),t),r.b=u,!0;case 121:return gDn(n,t,a,u,e,r);case 100:return!(u<=0||(r.c=u,0));case 83:return!(u<0)&&ywn(u,a,t[0],r);case 104:12==u&&(u=0);case 75:case 72:return!(u<0||(r.f=u,r.g=!1,0));case 107:return!(u<0||(r.f=u,r.g=!0,0));case 109:return!(u<0||(r.j=u,0));case 115:return!(u<0||(r.n=u,0));case 90:if(aE&&(d.c=E-d.b),UB(u.d,new LG(d,mln(u,d))),m=t==uCt?i.Math.max(m,g.b+h.b.rf().b):i.Math.min(m,g.b));for(m+=t==uCt?n.t:-n.t,(y=Mwn((u.e=m,u)))>0&&(_B(aV(n.b,t),124).a.b=y),f=b.Kc();f.Ob();)!(h=_B(f.Pb(),111)).c||h.c.d.c.length<=0||((d=h.c.i).c-=h.e.a,d.d-=h.e.b)}else rUn(n,t)}function LUn(n){var t,e,i,r,c,a,u,o,s,f;for(t=new Lp,a=new CL(n);a.e!=a.i.gc();){for(c=_B(mpn(a),33),e=new xv,XW(Ect,c,e),f=new ut,i=_B(M4(new xq(null,new qU(new az(JL(lLn(c).a.Kc(),new h)))),TG(f,p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),Get)])))),83),Qen(e,_B(i.xc((oN(),!0)),14),new ot),r=_B(M4(CV(_B(i.xc(!1),15).Lc(),new st),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[Get]))),15).Kc();r.Ob();)(s=SMn(_B(r.Pb(),79)))&&((u=_B(BC(CJ(t.f,s)),21))||(u=Ixn(s),yIn(t.f,s,u)),Krn(e,u));for(i=_B(M4(new xq(null,new qU(new az(JL(bLn(c).a.Kc(),new h)))),TG(f,p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[Get])))),83),Qen(e,_B(i.xc(!0),14),new ht),o=_B(M4(CV(_B(i.xc(!1),15).Lc(),new ft),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[Get]))),15).Kc();o.Ob();)(s=PMn(_B(o.Pb(),79)))&&((u=_B(BC(CJ(t.f,s)),21))||(u=Ixn(s),yIn(t.f,s,u)),Krn(e,u))}}function NUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d;if(cHn(),(o=Xhn(n,0)<0)&&(n=y7(n)),0==Xhn(n,0))switch(t){case 0:return"0";case 1:return UQn;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(b=new Sk).a+=t<0?"0E+":"0E",b.a+=t==RVn?"2147483648":""+-t,b.a}f=L8(PNt,UVn,25,1+(h=18),15,1),e=h,d=n;do{s=d,d=Ijn(d,10),f[--e]=bG(ebn(48,tbn(s,ibn(d,10))))&WVn}while(0!=Xhn(d,0));if(r=tbn(tbn(tbn(h,e),t),1),0==t)return o&&(f[--e]=45),_dn(f,e,h-e);if(t>0&&Xhn(r,-6)>=0){if(Xhn(r,0)>=0){for(c=e+bG(r),u=h-1;u>=c;u--)f[u+1]=f[u];return f[++c]=46,o&&(f[--e]=45),_dn(f,e,h-e+1)}for(a=2;uS(a,ebn(y7(r),1));a++)f[--e]=48;return f[--e]=46,f[--e]=48,o&&(f[--e]=45),_dn(f,e,h-e)}return w=e+1,i=h,l=new Pk,o&&(l.a+="-"),i-w>=1?(LX(l,f[e]),l.a+=".",l.a+=_dn(f,e+1,h-e-1)):l.a+=_dn(f,e,h-e),l.a+="E",Xhn(r,0)>0&&(l.a+="+"),l.a+=""+gz(r),l.a}function xUn(n,t,e){var i,r,c,a,u,o,s,h,f,l;if(n.e.a.$b(),n.f.a.$b(),n.c.c=L8(Cnt,FWn,1,0,5,1),n.i.c=L8(Cnt,FWn,1,0,5,1),n.g.a.$b(),t)for(a=new Ub(t.a);a.a=1&&(j-h>0&&d>=0?(Men(l,l.i+k),Sen(l,l.j+s*h)):j-h<0&&w>=0&&(Men(l,l.i+k*j),Sen(l,l.j+s)));return Vpn(n,(uWn(),DSt),(pdn(),new VK(a=_B(Xj(VCt),9),_B(TR(a,a.length),9),0))),new LI(E,f)}function RUn(n){var t,e,r,c,a,u,o,s,h,f,l;if(f=QY(MTn(_B(Utn((!n.b&&(n.b=new oK(xOt,n,4,7)),n.b),0),82)))==QY(MTn(_B(Utn((!n.c&&(n.c=new oK(xOt,n,5,8)),n.c),0),82))),u=new Hj,(t=_B(JAn(n,(zsn(),oIt)),74))&&t.b>=2){if(0==(!n.a&&(n.a=new nU(ROt,n,6,6)),n.a).i)Zj(),e=new co,s9((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a),e);else if((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a).i>1)for(l=new ix((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a));l.e!=l.i.gc();)Wjn(l);XFn(t,_B(Utn((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a),0),202))}if(f)for(r=new CL((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a));r.e!=r.i.gc();)for(s=new CL((!(e=_B(mpn(r),202)).a&&(e.a=new OL($Ot,e,5)),e.a));s.e!=s.i.gc();)o=_B(mpn(s),469),u.a=i.Math.max(u.a,o.a),u.b=i.Math.max(u.b,o.b);for(a=new CL((!n.n&&(n.n=new nU(HOt,n,1,7)),n.n));a.e!=a.i.gc();)c=_B(mpn(a),137),(h=_B(JAn(c,wIt),8))&&TA(c,h.a,h.b),f&&(u.a=i.Math.max(u.a,c.i+c.g),u.b=i.Math.max(u.b,c.j+c.f));return u}function KUn(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;for(v=t.c.length,c=new BKn(n.a,e,null,null),E=L8($Nt,BQn,25,v,15,1),w=L8($Nt,BQn,25,v,15,1),b=L8($Nt,BQn,25,v,15,1),d=0,o=0;oE[s]&&(d=s),f=new Ub(n.a.b);f.aw&&(a&&(sO(j,b),sO(T,tln(h.b-1))),C=e.b,O+=b+t,b=0,f=i.Math.max(f,e.b+e.c+I)),Men(o,C),Sen(o,O),f=i.Math.max(f,C+I+e.c),b=i.Math.max(b,l),C+=I+t;if(f=i.Math.max(f,r),(P=O+b+e.a)hZn,S=i.Math.abs(b.b-d.b)>hZn,(!e&&M&&S||e&&(M||S))&&NH(p.a,k)),Krn(p.a,r),0==r.b?b=k:(Mx(0!=r.b),b=_B(r.c.b.c,8)),Van(w,l,g),rcn(c)==T&&(gW(T.i)!=c.a&&IPn(g=new Hj,gW(T.i),m),oon(p,xlt,g)),ESn(w,p,m),f.a.zc(w,f);TZ(p,j),EZ(p,T)}for(h=f.a.ec().Kc();h.Ob();)TZ(s=_B(h.Pb(),17),null),EZ(s,null);FSn(t)}function HUn(n){var t,e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;if(1==n.gc())return _B(n.Xb(0),231);if(n.gc()<=0)return new v6;for(c=n.Kc();c.Ob();){for(e=_B(c.Pb(),231),d=0,f=NWn,l=NWn,s=RVn,h=RVn,w=new Ub(e.e);w.ao&&(y=0,k+=u+v,u=0),XKn(g,e,y,k),t=i.Math.max(t,y+p.a),u=i.Math.max(u,p.b),y+=p.a+v;return g}function qUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;switch(h=new mm,n.a.g){case 3:l=_B(pMn(t.e,(oWn(),$lt)),15),b=_B(pMn(t.j,$lt),15),w=_B(pMn(t.f,$lt),15),e=_B(pMn(t.e,Olt),15),i=_B(pMn(t.j,Olt),15),r=_B(pMn(t.f,Olt),15),wun(a=new $p,l),b.Jc(new yc),wun(a,iL(b,152)?a6(_B(b,152)):iL(b,131)?_B(b,131).a:iL(b,54)?new sy(b):new ST(b)),wun(a,w),wun(c=new $p,e),wun(c,iL(i,152)?a6(_B(i,152)):iL(i,131)?_B(i,131).a:iL(i,54)?new sy(i):new ST(i)),wun(c,r),oon(t.f,$lt,a),oon(t.f,Olt,c),oon(t.f,Llt,t.f),oon(t.e,$lt,null),oon(t.e,Olt,null),oon(t.j,$lt,null),oon(t.j,Olt,null);break;case 1:Krn(h,t.e.a),NH(h,t.i.n),Krn(h,nan(t.j.a)),NH(h,t.a.n),Krn(h,t.f.a);break;default:Krn(h,t.e.a),Krn(h,nan(t.j.a)),Krn(h,t.f.a)}vQ(t.f.a),Krn(t.f.a,h),TZ(t.f,t.e.c),u=_B(pMn(t.e,(FXn(),ggt)),74),s=_B(pMn(t.j,ggt),74),o=_B(pMn(t.f,ggt),74),(u||s||o)&&(MU(f=new mm,o),MU(f,s),MU(f,u),oon(t.f,ggt,f)),TZ(t.j,null),EZ(t.j,null),TZ(t.e,null),EZ(t.e,null),MZ(t.a,null),MZ(t.i,null),t.g&&qUn(n,t.g)}function GUn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;if(MFn(),null==n)return null;if((w=fln(c=X7(n)))%4!=0)return null;if(0==(d=w/4|0))return L8(ANt,g6n,25,0,15,1);for(f=null,t=0,e=0,i=0,r=0,a=0,u=0,o=0,s=0,b=0,l=0,h=0,f=L8(ANt,g6n,25,3*d,15,1);b>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24}return XE(a=c[h++])&&XE(u=c[h++])?(t=zLt[a],e=zLt[u],o=c[h++],s=c[h++],-1==zLt[o]||-1==zLt[s]?61==o&&61==s?0!=(15&e)?null:(rHn(f,0,g=L8(ANt,g6n,25,3*b+1,15,1),0,3*b),g[l]=(t<<2|e>>4)<<24>>24,g):61!=o&&61==s?0!=(3&(i=zLt[o]))?null:(rHn(f,0,g=L8(ANt,g6n,25,3*b+2,15,1),0,3*b),g[l++]=(t<<2|e>>4)<<24>>24,g[l]=((15&e)<<4|i>>2&15)<<24>>24,g):null:(i=zLt[o],r=zLt[s],f[l++]=(t<<2|e>>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24,f)):null}function zUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(ITn(t,I1n,1),l=_B(pMn(n,(FXn(),Jdt)),218),i=new Ub(n.b);i.a=2){for(b=!0,e=_B(Y1(h=new Ub(r.j)),11),f=null;h.a0&&(c=_B(Lq(p.c.a,E-1),10),u=n.i[c.p],M=i.Math.ceil(D$(n.n,c,p)),a=j.a.e-p.d.d-(u.a.e+c.o.b+c.d.a)-M),h=xQn,E0&&T.a.e.e-T.a.a-(T.b.e.e-T.b.a)<0,d=y.a.e.e-y.a.a-(y.b.e.e-y.b.a)<0&&T.a.e.e-T.a.a-(T.b.e.e-T.b.a)>0,w=y.a.e.e+y.b.aT.b.e.e+T.a.a,k=0,!g&&!d&&(b?a+l>0?k=l:h-r>0&&(k=r):w&&(a+o>0?k=o:h-m>0&&(k=m))),j.a.e+=k,j.b&&(j.d.e+=k),1)))}function XUn(n,t,e){var r,c,a,u,o,s,h,f,l,b;if(r=new GV(t.qf().a,t.qf().b,t.rf().a,t.rf().b),c=new fA,n.c)for(u=new Ub(t.wf());u.as&&(i.a+=eL(L8(PNt,UVn,25,-s,15,1))),i.a+="Is",HO(o,VTn(32))>=0)for(r=0;r=i.o.b/2}p?(g=_B(pMn(i,(oWn(),Dlt)),15))?l?c=g:(r=_B(pMn(i,Nft),15))?c=g.gc()<=r.gc()?g:r:(c=new $p,oon(i,Nft,c)):(c=new $p,oon(i,Dlt,c)):(r=_B(pMn(i,(oWn(),Nft)),15))?f?c=r:(g=_B(pMn(i,Dlt),15))?c=r.gc()<=g.gc()?r:g:(c=new $p,oon(i,Dlt,c)):(c=new $p,oon(i,Nft,c)),c.Fc(n),oon(n,(oWn(),Dft),e),t.d==e?(EZ(t,null),e.e.c.length+e.g.c.length==0&&SZ(e,null),wsn(e)):(TZ(t,null),e.e.c.length+e.g.c.length==0&&SZ(e,null)),vQ(t.a)}function ZUn(n,t){var e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C;for(v=new E2(n.b,0),d=0,s=_B((f=t.Kc()).Pb(),19).a,k=0,e=new xv,E=new sA;v.b=n.a&&(r=vBn(n,v),l=i.Math.max(l,r.b),y=i.Math.max(y,r.d),UB(o,new eC(v,r)));for(E=new $p,f=0;f0),g.a.Xb(g.c=--g.b),vR(g,T=new FX(n.b)),Mx(g.b0?(h=0,p&&(h+=o),h+=(M-1)*u,m&&(h+=o),T&&m&&(h=i.Math.max(h,YNn(m,u,v,E))),h0){for(l=h<100?null:new Kj(h),w=(s=new ycn(t)).g,g=L8(INt,oQn,25,h,15,1),i=0,m=new wtn(h),r=0;r=0;)if(null!=b?$fn(b,w[o]):HC(b)===HC(w[o])){g.length<=i&&rHn(g,0,g=L8(INt,oQn,25,2*g.length,15,1),0,i),g[i++]=r,s9(m,w[o]);break n}if(HC(b=b)===HC(u))break}}if(s=m,w=m.g,h=i,i>g.length&&rHn(g,0,g=L8(INt,oQn,25,i,15,1),0,i),i>0){for(v=!0,c=0;c=0;)Ayn(n,g[a]);if(i!=h){for(r=h;--r>=i;)Ayn(s,r);rHn(g,0,g=L8(INt,oQn,25,i,15,1),0,i)}t=s}}}else for(t=yyn(n,t),r=n.i;--r>=0;)t.Hc(n.g[r])&&(Ayn(n,r),v=!0);if(v){if(null!=g){for(f=1==(e=t.gc())?vZ(n,4,t.Kc().Pb(),null,g[0],d):vZ(n,6,t,g,g[0],d),l=e<100?null:new Kj(e),r=t.Kc();r.Ob();)l=BK(n,_B(b=r.Pb(),72),l);l?(l.Ei(f),l.Fi()):fan(n.e,f)}else{for(l=OK(t.gc()),r=t.Kc();r.Ob();)l=BK(n,_B(b=r.Pb(),72),l);l&&l.Fi()}return!0}return!1}function cXn(n,t){var e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m;for((e=new ovn(t)).a||w_n(t),s=hRn(t),o=new dY,g=new Wxn,d=new Ub(t.a);d.a0||e.o==iyt&&c0?(f=_B(Lq(l.c.a,a-1),10),T=D$(n.b,l,f),g=l.n.b-l.d.d-(f.n.b+f.o.b+f.d.a+T)):g=l.n.b-l.d.d,s=i.Math.min(g,s),a(a=tEn(n,e))?rKn(n,t,e):rKn(n,e,t),ra?1:0}return(i=_B(pMn(t,(oWn(),llt)),19).a)>(c=_B(pMn(e,llt),19).a)?rKn(n,t,e):rKn(n,e,t),ic?1:0}function hXn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d;if(By(jD(JAn(t,(uWn(),qSt)))))return TQ(),TQ(),uet;if(o=0!=(!t.a&&(t.a=new nU(qOt,t,10,11)),t.a).i,s=!(h=vCn(t)).dc(),o||s){if(!(r=_B(JAn(t,pPt),149)))throw Fp(new ek("Resolved algorithm is not set; apply a LayoutAlgorithmResolver before computing layout."));if(d=II(r,(oAn(),JOt)),$gn(t),!o&&s&&!d)return TQ(),TQ(),uet;if(u=new $p,HC(JAn(t,kSt))===HC((cfn(),dIt))&&(II(r,WOt)||II(r,XOt)))for(l=dRn(n,t),Krn(b=new VT,(!t.a&&(t.a=new nU(qOt,t,10,11)),t.a));0!=b.b;)$gn(f=_B(0==b.b?null:(Mx(0!=b.b),Ctn(b,b.a.a)),33)),HC(JAn(f,kSt))===HC(pIt)||M8(f,nSt)&&!y5(r,JAn(f,pPt))?(wun(u,hXn(n,f,e,i)),Vpn(f,kSt,pIt),DKn(f)):Krn(b,(!f.a&&(f.a=new nU(qOt,f,10,11)),f.a));else for(l=(!t.a&&(t.a=new nU(qOt,t,10,11)),t.a).i,a=new CL((!t.a&&(t.a=new nU(qOt,t,10,11)),t.a));a.e!=a.i.gc();)wun(u,hXn(n,c=_B(mpn(a),33),e,i)),DKn(c);for(w=new Ub(u);w.a=0?own(u):jln(own(u)),n.Ye(cpt,b)),s=new Hj,l=!1,n.Xe(Ygt)?(Fx(s,_B(n.We(Ygt),8)),l=!0):vL(s,a.a/2,a.b/2),b.g){case 4:oon(h,mgt,(jbn(),Klt)),oon(h,Hft,(Qun(),Oht)),h.o.b=a.b,d<0&&(h.o.a=-d),BIn(f,(mUn(),aCt)),l||(s.a=a.a),s.a-=a.a;break;case 2:oon(h,mgt,(jbn(),Flt)),oon(h,Hft,(Qun(),Iht)),h.o.b=a.b,d<0&&(h.o.a=-d),BIn(f,(mUn(),SCt)),l||(s.a=0);break;case 1:oon(h,tlt,(q7(),Sft)),h.o.a=a.a,d<0&&(h.o.b=-d),BIn(f,(mUn(),TCt)),l||(s.b=a.b),s.b-=a.b;break;case 3:oon(h,tlt,(q7(),Tft)),h.o.a=a.a,d<0&&(h.o.b=-d),BIn(f,(mUn(),uCt)),l||(s.b=0)}if(Fx(f.n,s),oon(h,Ygt,s),t==GIt||t==UIt||t==zIt){if(w=0,t==GIt&&n.Xe(tpt))switch(b.g){case 1:case 2:w=_B(n.We(tpt),19).a;break;case 3:case 4:w=-_B(n.We(tpt),19).a}else switch(b.g){case 4:case 2:w=c.b,t==UIt&&(w/=r.b);break;case 1:case 3:w=c.a,t==UIt&&(w/=r.a)}oon(h,jlt,w)}return oon(h,Wft,b),h}function lXn(n){var t,e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E;if((e=Hy(ED(pMn(n.a.j,(FXn(),Rdt)))))<-1||!n.a.i||AK(_B(pMn(n.a.o,npt),98))||rbn(n.a.o,(mUn(),aCt)).gc()<2&&rbn(n.a.o,SCt).gc()<2)return!0;if(n.a.c.Rf())return!1;for(y=0,m=0,v=new $p,o=0,s=(u=n.a.e).length;o=e}function bXn(){function n(n){var t=this;this.dispatch=function(t){var e=t.data;switch(e.cmd){case"algorithms":var i=Twn((TQ(),new Fb(new Ib(sAt.b))));n.postMessage({id:e.id,data:i});break;case"categories":var r=Twn((TQ(),new Fb(new Ib(sAt.c))));n.postMessage({id:e.id,data:r});break;case"options":var c=Twn((TQ(),new Fb(new Ib(sAt.d))));n.postMessage({id:e.id,data:c});break;case"register":hGn(e.algorithms),n.postMessage({id:e.id});break;case"layout":LBn(e.graph,e.layoutOptions||{},e.options||{}),n.postMessage({id:e.id,data:e.graph})}},this.saveDispatch=function(e){try{t.dispatch(e)}catch(i){n.postMessage({id:e.data.id,error:i})}}}function i(t){var e=this;this.dispatcher=new n({postMessage:function(n){e.onmessage({data:n})}}),this.postMessage=function(n){setTimeout((function(){e.dispatcher.saveDispatch({data:n})}),0)}}if(rE(),typeof document===wJn&&typeof self!==wJn){var r=new n(self);self.onmessage=r.saveDispatch}else typeof t!==wJn&&t.exports&&(Object.defineProperty(e,"__esModule",{value:!0}),t.exports={default:i,Worker:i})}function wXn(n){n.N||(n.N=!0,n.b=man(n,0),xrn(n.b,0),xrn(n.b,1),xrn(n.b,2),n.bb=man(n,1),xrn(n.bb,0),xrn(n.bb,1),n.fb=man(n,2),xrn(n.fb,3),xrn(n.fb,4),Drn(n.fb,5),n.qb=man(n,3),xrn(n.qb,0),Drn(n.qb,1),Drn(n.qb,2),xrn(n.qb,3),xrn(n.qb,4),Drn(n.qb,5),xrn(n.qb,6),n.a=yan(n,4),n.c=yan(n,5),n.d=yan(n,6),n.e=yan(n,7),n.f=yan(n,8),n.g=yan(n,9),n.i=yan(n,10),n.j=yan(n,11),n.k=yan(n,12),n.n=yan(n,13),n.o=yan(n,14),n.p=yan(n,15),n.q=yan(n,16),n.s=yan(n,17),n.r=yan(n,18),n.t=yan(n,19),n.u=yan(n,20),n.v=yan(n,21),n.w=yan(n,22),n.B=yan(n,23),n.A=yan(n,24),n.C=yan(n,25),n.D=yan(n,26),n.F=yan(n,27),n.G=yan(n,28),n.H=yan(n,29),n.J=yan(n,30),n.I=yan(n,31),n.K=yan(n,32),n.M=yan(n,33),n.L=yan(n,34),n.P=yan(n,35),n.Q=yan(n,36),n.R=yan(n,37),n.S=yan(n,38),n.T=yan(n,39),n.U=yan(n,40),n.V=yan(n,41),n.X=yan(n,42),n.W=yan(n,43),n.Y=yan(n,44),n.Z=yan(n,45),n.$=yan(n,46),n._=yan(n,47),n.ab=yan(n,48),n.cb=yan(n,49),n.db=yan(n,50),n.eb=yan(n,51),n.gb=yan(n,52),n.hb=yan(n,53),n.ib=yan(n,54),n.jb=yan(n,55),n.kb=yan(n,56),n.lb=yan(n,57),n.mb=yan(n,58),n.nb=yan(n,59),n.ob=yan(n,60),n.pb=yan(n,61))}function dXn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;if(m=0,0==t.f.a)for(p=new Ub(n);p.as&&0==(h1(s,t.c.length),_B(t.c[s],200)).a.c.length;)v7(t,(h1(s,t.c.length),t.c[s]));if(!o){--c;continue}if(C_n(t,h,r,o,l,e,s,i)){f=!0;continue}if(l){if(QBn(t,h,r,o,e,s,i)){f=!0;continue}if(Chn(h,r)){r.c=!0,f=!0;continue}}else if(Chn(h,r)){r.c=!0,f=!0;continue}if(f)continue}Chn(h,r)?(r.c=!0,f=!0,o&&(o.k=!1)):Hmn(r.q)}else OT(),jkn(h,r),--c,f=!0;return f}function vXn(n,t,e,r,c,a,u){var o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A;for(g=0,P=0,h=new Ub(n.b);h.ag&&(a&&(sO(E,w),sO(M,tln(f.b-1)),UB(n.d,d),o.c=L8(Cnt,FWn,1,0,5,1)),O=e.b,A+=w+t,w=0,l=i.Math.max(l,e.b+e.c+C)),o.c[o.c.length]=s,Epn(s,O,A),l=i.Math.max(l,O+C+e.c),w=i.Math.max(w,b),O+=C+t,d=s;if(wun(n.a,o),UB(n.d,_B(Lq(o,o.c.length-1),157)),l=i.Math.max(l,r),(I=A+w+e.a)1&&(u=i.Math.min(u,i.Math.abs(_B(Npn(o.a,1),8).b-f.b)))));else for(d=new Ub(t.j);d.ac&&(a=b.a-c,u=NWn,r.c=L8(Cnt,FWn,1,0,5,1),c=b.a),b.a>=c&&(r.c[r.c.length]=o,o.a.b>1&&(u=i.Math.min(u,i.Math.abs(_B(Npn(o.a,o.a.b-2),8).b-b.b)))));if(0!=r.c.length&&a>t.o.a/2&&u>t.o.b/2){for(SZ(w=new SSn,t),BIn(w,(mUn(),uCt)),w.n.a=t.o.a/2,SZ(g=new SSn,t),BIn(g,TCt),g.n.a=t.o.a/2,g.n.b=t.o.b,s=new Ub(r);s.a=h.b?TZ(o,g):TZ(o,w)):(h=_B(wH(o.a),8),(0==o.a.b?w1(o.c):_B(dx(o.a),8)).b>=h.b?EZ(o,g):EZ(o,w)),(l=_B(pMn(o,(FXn(),ggt)),74))&&vwn(l,h,!0);t.n.a=c-t.o.a/2}}function kXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(s=t,Oin(o=W3(n,A3(e),s),x2(s,B6n)),h=_B(uen(n.g,mCn(qY(s,j6n))),33),i=null,(a=qY(s,"sourcePort"))&&(i=mCn(a)),f=_B(uen(n.j,i),118),!h)throw Fp(new nk("An edge must have a source node (edge id: '"+Wdn(s)+U6n));if(f&&!lW(UY(f),h))throw Fp(new nk("The source port of an edge must be a port of the edge's source node (edge id: '"+x2(s,B6n)+U6n));if(!o.b&&(o.b=new oK(xOt,o,4,7)),s9(o.b,f||h),l=_B(uen(n.g,mCn(qY(s,V6n))),33),r=null,(u=qY(s,"targetPort"))&&(r=mCn(u)),b=_B(uen(n.j,r),118),!l)throw Fp(new nk("An edge must have a target node (edge id: '"+Wdn(s)+U6n));if(b&&!lW(UY(b),l))throw Fp(new nk("The target port of an edge must be a port of the edge's target node (edge id: '"+x2(s,B6n)+U6n));if(!o.c&&(o.c=new oK(xOt,o,5,8)),s9(o.c,b||l),0==(!o.b&&(o.b=new oK(xOt,o,4,7)),o.b).i||0==(!o.c&&(o.c=new oK(xOt,o,5,8)),o.c).i)throw c=x2(s,B6n),Fp(new nk(z6n+c+U6n));return TTn(s,o),u$n(s,o),Lon(n,s,o)}function jXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S;return f=SFn(FN(n,(mUn(),lCt)),t),w=ryn(FN(n,bCt),t),y=ryn(FN(n,kCt),t),T=cyn(FN(n,ECt),t),l=cyn(FN(n,oCt),t),v=ryn(FN(n,yCt),t),d=ryn(FN(n,wCt),t),j=ryn(FN(n,jCt),t),k=ryn(FN(n,sCt),t),M=cyn(FN(n,fCt),t),p=ryn(FN(n,vCt),t),m=ryn(FN(n,pCt),t),E=ryn(FN(n,hCt),t),S=cyn(FN(n,mCt),t),b=cyn(FN(n,dCt),t),g=ryn(FN(n,gCt),t),e=Aon(Mun(Hk($Nt,1),BQn,25,15,[v.a,T.a,j.a,S.a])),i=Aon(Mun(Hk($Nt,1),BQn,25,15,[w.a,f.a,y.a,g.a])),r=p.a,c=Aon(Mun(Hk($Nt,1),BQn,25,15,[d.a,l.a,k.a,b.a])),s=Aon(Mun(Hk($Nt,1),BQn,25,15,[v.b,w.b,d.b,m.b])),o=Aon(Mun(Hk($Nt,1),BQn,25,15,[T.b,f.b,l.b,g.b])),h=M.b,u=Aon(Mun(Hk($Nt,1),BQn,25,15,[j.b,y.b,k.b,E.b])),l9(FN(n,lCt),e+r,s+h),l9(FN(n,gCt),e+r,s+h),l9(FN(n,bCt),e+r,0),l9(FN(n,kCt),e+r,s+h+o),l9(FN(n,ECt),0,s+h),l9(FN(n,oCt),e+r+i,s+h),l9(FN(n,wCt),e+r+i,0),l9(FN(n,jCt),0,s+h+o),l9(FN(n,sCt),e+r+i,s+h+o),l9(FN(n,fCt),0,s),l9(FN(n,vCt),e,0),l9(FN(n,hCt),0,s+h+o),l9(FN(n,dCt),e+r+i,0),(a=new Hj).a=Aon(Mun(Hk($Nt,1),BQn,25,15,[e+i+r+c,M.a,m.a,E.a])),a.b=Aon(Mun(Hk($Nt,1),BQn,25,15,[s+o+h+u,p.b,S.b,b.b])),a}function EXn(n){var t,e,i,r,c,a,u,o,s,f,l,b,w,d,g;for(d=new $p,l=new Ub(n.d.b);l.ar.d.d+r.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))),i.b!=i.d.c&&(t=e);f&&(c=_B(xX(n.f,a.d.i),57),t.bc.d.d+c.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))}for(u=new az(JL(sbn(b).a.Kc(),new h));bAn(u);)0!=(a=_B(G5(u),17)).a.b&&(t=_B(dx(a.a),8),a.d.j==(mUn(),uCt)&&((g=new MBn(t,new LI(t.a,r.d.d),r,a)).f.a=!0,g.a=a.d,d.c[d.c.length]=g),a.d.j==TCt&&((g=new MBn(t,new LI(t.a,r.d.d+r.d.a),r,a)).f.d=!0,g.a=a.d,d.c[d.c.length]=g))}return d}function TXn(n,t,e){var i,r,c,a,u,o,s;if(ITn(e,"Network simplex node placement",1),n.e=t,n.n=_B(pMn(t,(oWn(),Clt)),304),aqn(n),xEn(n),QT(lnn(new xq(null,new l1(n.e.b,16)),new Hc),new ig(n)),QT(CV(lnn(CV(lnn(new xq(null,new l1(n.e.b,16)),new ta),new ea),new ia),new ra),new eg(n)),By(jD(pMn(n.e,(FXn(),Lgt))))&&(ITn(c=pcn(e,1),"Straight Edges Pre-Processing",1),yzn(n),FSn(c)),Evn(n.f),r=_B(pMn(t,Lpt),19).a*n.f.a.c.length,UKn(Wk(Vk(__(n.f),r),!1),pcn(e,1)),0!=n.d.a.gc()){for(ITn(c=pcn(e,1),"Flexible Where Space Processing",1),a=_B(ON(Iz(OV(new xq(null,new l1(n.f.a,16)),new qc),new Dc)),19).a,u=_B(ON(Pz(OV(new xq(null,new l1(n.f.a,16)),new Gc),new Rc)),19).a-a,o=CN(new Bv,n.f),s=CN(new Bv,n.f),GNn(rM(iM(eM(cM(new Fv,2e4),u),o),s)),QT(CV(CV(AU(n.i),new zc),new Uc),new qV(a,o,u,s)),i=n.d.a.ec().Kc();i.Ob();)_B(i.Pb(),213).g=1;UKn(Wk(Vk(__(n.f),r),!1),pcn(c,1)),FSn(c)}By(jD(pMn(t,Lgt)))&&(ITn(c=pcn(e,1),"Straight Edges Post-Processing",1),TPn(n),FSn(c)),WGn(n),n.e=null,n.f=null,n.i=null,n.c=null,OU(n.k),n.j=null,n.a=null,n.o=null,n.d.a.$b(),FSn(e)}function MXn(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(u=new Ub(n.a.b);u.a0)if(r=f.gc(),s=SY(i.Math.floor((r+1)/2))-1,c=SY(i.Math.ceil((r+1)/2))-1,t.o==iyt)for(h=c;h>=s;h--)t.a[y.p]==y&&(d=_B(f.Xb(h),46),w=_B(d.a,10),!KT(e,d.b)&&b>n.b.e[w.p]&&(t.a[w.p]=y,t.g[y.p]=t.g[w.p],t.a[y.p]=t.g[y.p],t.f[t.g[y.p].p]=(oN(),!!(By(t.f[t.g[y.p].p])&y.k==(cSn(),Mut))),b=n.b.e[w.p]));else for(h=s;h<=c;h++)t.a[y.p]==y&&(p=_B(f.Xb(h),46),g=_B(p.a,10),!KT(e,p.b)&&b=w&&(v>w&&(b.c=L8(Cnt,FWn,1,0,5,1),w=v),b.c[b.c.length]=a);0!=b.c.length&&(l=_B(Lq(b,dvn(t,b.c.length)),128),P.a.Bc(l),l.s=d++,iLn(l,M,j),b.c=L8(Cnt,FWn,1,0,5,1))}for(y=n.c.length+1,u=new Ub(n);u.aS.s&&(sW(e),v7(S.i,i),i.c>0&&(i.a=S,UB(S.t,i),i.b=E,UB(E.i,i)))}function IXn(n){var t,e,i,r,c;switch(t=n.c){case 11:return n.Ml();case 12:return n.Ol();case 14:return n.Ql();case 15:return n.Tl();case 16:return n.Rl();case 17:return n.Ul();case 21:return WXn(n),lWn(),lWn(),aNt;case 10:switch(n.a){case 65:return n.yl();case 90:return n.Dl();case 122:return n.Kl();case 98:return n.El();case 66:return n.zl();case 60:return n.Jl();case 62:return n.Hl()}}switch(c=mXn(n),t=n.c){case 3:return n.Zl(c);case 4:return n.Xl(c);case 5:return n.Yl(c);case 0:if(123==n.a&&n.d=48&&t<=57))throw Fp(new rk(mWn((c$(),z8n))));for(i=t-48;r=48&&t<=57;)if((i=10*i+t-48)<0)throw Fp(new rk(mWn((c$(),V8n))));if(e=i,44==t){if(r>=n.j)throw Fp(new rk(mWn((c$(),X8n))));if((t=sV(n.i,r++))>=48&&t<=57){for(e=t-48;r=48&&t<=57;)if((e=10*e+t-48)<0)throw Fp(new rk(mWn((c$(),V8n))));if(i>e)throw Fp(new rk(mWn((c$(),W8n))))}else e=-1}if(125!=t)throw Fp(new rk(mWn((c$(),U8n))));n.sl(r)?(lWn(),lWn(),c=new o4(9,c),n.d=r+1):(lWn(),lWn(),c=new o4(3,c),n.d=r),c.dm(i),c.cm(e),WXn(n)}}return c}function CXn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;for(w=new Q6(t.b),v=new Q6(t.b),l=new Q6(t.b),j=new Q6(t.b),d=new Q6(t.b),k=upn(t,0);k.b!=k.d.c;)for(u=new Ub((m=_B(f3(k),11)).g);u.a0,g=m.g.c.length>0,s&&g?l.c[l.c.length]=m:s?w.c[w.c.length]=m:g&&(v.c[v.c.length]=m);for(b=new Ub(w);b.a1)for(b=new ix((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a));b.e!=b.i.gc();)Wjn(b);for(d=I,I>y+m?d=y+m:Ik+w?g=k+w:Cy-m&&dk-w&&gI+P?E=I+P:yC+j?T=C+j:kI-P&&EC-j&&Te&&(f=e-1),(l=L+F$n(t,24)*cJn*h-h/2)<0?l=1:l>r&&(l=r-1),Zj(),yen(c=new ro,f),ken(c,l),s9((!u.a&&(u.a=new OL($Ot,u,5)),u.a),c)}function FXn(){FXn=O,uWn(),dpt=yPt,gpt=kPt,ppt=jPt,vpt=EPt,ypt=TPt,kpt=MPt,Tpt=PPt,Spt=CPt,Ppt=OPt,Mpt=IPt,Ipt=APt,Opt=$Pt,$pt=xPt,Ept=SPt,sWn(),wpt=Rwt,mpt=Kwt,jpt=_wt,Cpt=Fwt,opt=new zA(dPt,tln(0)),spt=Nwt,hpt=xwt,fpt=Dwt,qpt=hdt,xpt=qwt,Dpt=Uwt,_pt=ndt,Rpt=Vwt,Kpt=Jwt,zpt=ddt,Gpt=ldt,Bpt=adt,Fpt=rdt,Hpt=odt,xgt=Mwt,Dgt=Swt,egt=Dbt,igt=_bt,Ggt=new UA(12),qgt=new zA(zSt,Ggt),Ebn(),Jdt=new zA(gSt,Ydt=WPt),Zgt=new zA(rPt,0),lpt=new zA(gPt,tln(1)),kdt=new zA(iSt,bZn),Hgt=qSt,npt=cPt,cpt=lPt,qdt=hSt,mdt=tSt,ugt=kSt,bpt=new zA(mPt,(oN(),!0)),lgt=TSt,bgt=MSt,Kgt=DSt,Bgt=BSt,_gt=KSt,Kfn(),Gdt=new zA(fSt,Udt=_Pt),Ogt=NSt,Cgt=$St,ipt=sPt,ept=oPt,rpt=fPt,ipn(),new zA(JSt,Xgt=BIt),Vgt=nPt,Qgt=tPt,Jgt=ePt,Wgt=ZSt,Npt=Hwt,Mgt=hwt,Tgt=owt,Lpt=Bwt,mgt=nwt,Hdt=jbt,Bdt=ybt,Ldt=cbt,Ndt=abt,Ddt=fbt,xdt=ubt,Fdt=vbt,Pgt=lwt,Igt=bwt,dgt=Xbt,Rgt=Owt,$gt=pwt,cgt=Hbt,Ngt=Ewt,ngt=$bt,tgt=Nbt,$dt=oSt,Agt=wwt,Mdt=Wlt,Tdt=Ult,Edt=zlt,sgt=zbt,ogt=Gbt,hgt=Ubt,Fgt=_St,ggt=ISt,rgt=vSt,Vdt=wSt,Wdt=bSt,Rdt=wbt,tpt=uPt,jdt=uSt,fgt=ESt,Ygt=iPt,zgt=XSt,Ugt=VSt,kgt=iwt,jgt=cwt,upt=wPt,ydt=Glt,Egt=uwt,Qdt=Ibt,Xdt=Sbt,Sgt=OSt,pgt=Jbt,Lgt=ywt,Apt=LPt,zdt=Tbt,apt=$wt,Zdt=Obt,vgt=Zbt,Kdt=gbt,wgt=PSt,ygt=ewt,_dt=pbt,Adt=ibt,Cdt=nbt,Pdt=Ylt,Idt=Zlt,Odt=ebt,Sdt=Qlt,agt=qbt}function BXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(cHn(),T=n.e,w=n.d,r=n.a,0==T)switch(t){case 0:return"0";case 1:return UQn;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(j=new Sk).a+=t<0?"0E+":"0E",j.a+=-t,j.a}if(y=L8(PNt,UVn,25,1+(m=10*w+1+7),15,1),e=m,1==w)if((u=r[0])<0){I=n0(u,GQn);do{d=I,I=Ijn(I,10),y[--e]=48+bG(tbn(d,ibn(I,10)))&WVn}while(0!=Xhn(I,0))}else{I=u;do{d=I,I=I/10|0,y[--e]=d-10*I+48&WVn}while(0!=I)}else{rHn(r,0,S=L8(INt,oQn,25,w,15,1),0,P=w);n:for(;;){for(E=0,s=P-1;s>=0;s--)p=sTn(ebn(vz(E,32),n0(S[s],GQn))),S[s]=bG(p),E=bG(mz(p,32));v=bG(E),g=e;do{y[--e]=48+v%10&WVn}while(0!=(v=v/10|0)&&0!=e);for(i=9-g+e,o=0;o0;o++)y[--e]=48;for(f=P-1;0==S[f];f--)if(0==f)break n;P=f+1}for(;48==y[e];)++e}if(b=T<0,a=m-e-t-1,0==t)return b&&(y[--e]=45),_dn(y,e,m-e);if(t>0&&a>=-6){if(a>=0){for(h=e+a,l=m-1;l>=h;l--)y[l+1]=y[l];return y[++h]=46,b&&(y[--e]=45),_dn(y,e,m-e+1)}for(f=2;f<1-a;f++)y[--e]=48;return y[--e]=46,y[--e]=48,b&&(y[--e]=45),_dn(y,e,m-e)}return M=e+1,c=m,k=new Pk,b&&(k.a+="-"),c-M>=1?(LX(k,y[e]),k.a+=".",k.a+=_dn(y,e+1,m-e-1)):k.a+=_dn(y,e,m-e),k.a+="E",a>0&&(k.a+="+"),k.a+=""+a,k.a}function HXn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;switch(n.c=t,n.g=new Lp,HM(),Zbn(new Mw(new Ny(n.c))),v=TD(JAn(n.c,(EMn(),bTt))),u=_B(JAn(n.c,dTt),316),y=_B(JAn(n.c,gTt),429),c=_B(JAn(n.c,oTt),482),m=_B(JAn(n.c,wTt),430),n.j=Hy(ED(JAn(n.c,pTt))),a=n.a,u.g){case 0:a=n.a;break;case 1:a=n.b;break;case 2:a=n.i;break;case 3:a=n.e;break;case 4:a=n.f;break;default:throw Fp(new Ry($4n+(null!=u.f?u.f:""+u.g)))}if(n.d=new NY(a,y,c),oon(n.d,(zcn(),Wrt),jD(JAn(n.c,hTt))),n.d.c=By(jD(JAn(n.c,sTt))),0==VQ(n.c).i)return n.d;for(h=new CL(VQ(n.c));h.e!=h.i.gc();){for(l=(s=_B(mpn(h),33)).g/2,f=s.f/2,k=new LI(s.i+l,s.j+f);oU(n.g,k);)Rx(k,(i.Math.random()-.5)*hZn,(i.Math.random()-.5)*hZn);w=_B(JAn(s,(uWn(),OSt)),142),d=new CZ(k,new GV(k.a-l-n.j/2-w.b,k.b-f-n.j/2-w.d,s.g+n.j+(w.b+w.c),s.f+n.j+(w.d+w.a))),UB(n.d.i,d),XW(n.g,k,new eC(d,s))}switch(m.g){case 0:if(null==v)n.d.d=_B(Lq(n.d.i,0),65);else for(p=new Ub(n.d.i);p.a1&&e5(f,v,f.c.b,f.c),ptn(c)));v=m}return f}function GXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A;for(ITn(e,"Greedy cycle removal",1),A=(m=t.a).c.length,n.a=L8(INt,oQn,25,A,15,1),n.c=L8(INt,oQn,25,A,15,1),n.b=L8(INt,oQn,25,A,15,1),s=0,p=new Ub(m);p.a0?S+1:1);for(a=new Ub(k.g);a.a0?S+1:1)}0==n.c[s]?NH(n.e,d):0==n.a[s]&&NH(n.f,d),++s}for(w=-1,b=1,f=new $p,n.d=_B(pMn(t,(oWn(),Tlt)),230);A>0;){for(;0!=n.e.b;)I=_B(bH(n.e),10),n.b[I.p]=w--,WKn(n,I),--A;for(;0!=n.f.b;)C=_B(bH(n.f),10),n.b[C.p]=b++,WKn(n,C),--A;if(A>0){for(l=RVn,v=new Ub(m);v.a=l&&(y>l&&(f.c=L8(Cnt,FWn,1,0,5,1),l=y),f.c[f.c.length]=d);h=n.Zf(f),n.b[h.p]=b++,WKn(n,h),--A}}for(P=m.c.length+1,s=0;sn.b[O]&&(ZFn(i,!0),oon(t,Bft,(oN(),!0)));n.a=null,n.c=null,n.b=null,vQ(n.f),vQ(n.e),FSn(e)}function zXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;for(i=new $p,u=new $p,g=t/2,b=n.gc(),r=_B(n.Xb(0),8),p=_B(n.Xb(1),8),UB(i,(h1(0,(w=WAn(r.a,r.b,p.a,p.b,g)).c.length),_B(w.c[0],8))),UB(u,(h1(1,w.c.length),_B(w.c[1],8))),s=2;s=0;o--)NH(e,(h1(o,a.c.length),_B(a.c[o],8)));return e}function UXn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b;if(a=!0,f=null,i=null,r=null,t=!1,b=vAt,s=null,c=null,(o=Xgn(n,u=0,IAt,CAt))=0&&pK(n.substr(u,"//".length),"//")?(o=Xgn(n,u+=2,OAt,AAt),i=n.substr(u,o-u),u=o):null==f||u!=n.length&&(f1(u,n.length),47==n.charCodeAt(u))||(a=!1,-1==(o=vN(n,VTn(35),u))&&(o=n.length),i=n.substr(u,o-u),u=o);if(!e&&u0&&58==sV(h,h.length-1)&&(r=h,u=o)),u=n.j)return n.a=-1,void(n.c=1);if(t=sV(n.i,n.d++),n.a=t,1!=n.b){switch(t){case 124:i=2;break;case 42:i=3;break;case 43:i=4;break;case 63:i=5;break;case 41:i=7;break;case 46:i=8;break;case 91:i=9;break;case 94:i=11;break;case 36:i=12;break;case 40:if(i=6,n.d>=n.j)break;if(63!=sV(n.i,n.d))break;if(++n.d>=n.j)throw Fp(new rk(mWn((c$(),d8n))));switch(t=sV(n.i,n.d++)){case 58:i=13;break;case 61:i=14;break;case 33:i=15;break;case 91:i=19;break;case 62:i=18;break;case 60:if(n.d>=n.j)throw Fp(new rk(mWn((c$(),d8n))));if(61==(t=sV(n.i,n.d++)))i=16;else{if(33!=t)throw Fp(new rk(mWn((c$(),g8n))));i=17}break;case 35:for(;n.d=n.j)throw Fp(new rk(mWn((c$(),w8n))));n.a=sV(n.i,n.d++);break;default:i=0}n.c=i}else{switch(t){case 92:if(i=10,n.d>=n.j)throw Fp(new rk(mWn((c$(),w8n))));n.a=sV(n.i,n.d++);break;case 45:512==(512&n.e)&&n.d=j||!$dn(v,i))&&(i=e1(t,f)),MZ(v,i),c=new az(JL(sbn(v).a.Kc(),new h));bAn(c);)r=_B(G5(c),17),n.a[r.p]||(g=r.c.i,--n.e[g.p],0==n.e[g.p]&&K8(nMn(w,g)));for(s=f.c.length-1;s>=0;--s)UB(t.b,(h1(s,f.c.length),_B(f.c[s],29)));t.a.c=L8(Cnt,FWn,1,0,5,1),FSn(e)}else FSn(e)}function JXn(n){var t,e,i,r,c,a,u,o;for(n.b=1,WXn(n),t=null,0==n.c&&94==n.a?(WXn(n),lWn(),lWn(),Vxn(t=new E0(4),0,cnt),a=new E0(4)):(lWn(),lWn(),a=new E0(4)),r=!0;1!=(o=n.c);){if(0==o&&93==n.a&&!r){t&&(UGn(t,a),a=t);break}if(e=n.a,i=!1,10==o)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:uHn(a,b_n(e)),i=!0;break;case 105:case 73:case 99:case 67:uHn(a,b_n(e)),(e=-1)<0&&(i=!0);break;case 112:case 80:if(!(u=NCn(n,e)))throw Fp(new rk(mWn((c$(),I8n))));uHn(a,u),i=!0;break;default:e=BDn(n)}else if(24==o&&!r){if(t&&(UGn(t,a),a=t),UGn(a,JXn(n)),0!=n.c||93!=n.a)throw Fp(new rk(mWn((c$(),$8n))));break}if(WXn(n),!i){if(0==o){if(91==e)throw Fp(new rk(mWn((c$(),L8n))));if(93==e)throw Fp(new rk(mWn((c$(),N8n))));if(45==e&&!r&&93!=n.a)throw Fp(new rk(mWn((c$(),x8n))))}if(0!=n.c||45!=n.a||45==e&&r)Vxn(a,e,e);else{if(WXn(n),1==(o=n.c))throw Fp(new rk(mWn((c$(),O8n))));if(0==o&&93==n.a)Vxn(a,e,e),Vxn(a,45,45);else{if(0==o&&93==n.a||24==o)throw Fp(new rk(mWn((c$(),x8n))));if(c=n.a,0==o){if(91==c)throw Fp(new rk(mWn((c$(),L8n))));if(93==c)throw Fp(new rk(mWn((c$(),N8n))));if(45==c)throw Fp(new rk(mWn((c$(),x8n))))}else 10==o&&(c=BDn(n));if(WXn(n),e>c)throw Fp(new rk(mWn((c$(),K8n))));Vxn(a,e,c)}}}r=!1}if(1==n.c)throw Fp(new rk(mWn((c$(),O8n))));return j$n(a),BHn(a),n.b=0,WXn(n),a}function YXn(n){X$n(n.c,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#decimal"])),X$n(n.d,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#integer"])),X$n(n.e,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#boolean"])),X$n(n.f,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EBoolean",Z6n,"EBoolean:Object"])),X$n(n.i,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#byte"])),X$n(n.g,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#hexBinary"])),X$n(n.j,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EByte",Z6n,"EByte:Object"])),X$n(n.n,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EChar",Z6n,"EChar:Object"])),X$n(n.t,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#double"])),X$n(n.u,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EDouble",Z6n,"EDouble:Object"])),X$n(n.F,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#float"])),X$n(n.G,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EFloat",Z6n,"EFloat:Object"])),X$n(n.I,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#int"])),X$n(n.J,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EInt",Z6n,"EInt:Object"])),X$n(n.N,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#long"])),X$n(n.O,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"ELong",Z6n,"ELong:Object"])),X$n(n.Z,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#short"])),X$n(n.$,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EShort",Z6n,"EShort:Object"])),X$n(n._,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#string"]))}function ZXn(n){var t,e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(1==n.c.length)return h1(0,n.c.length),_B(n.c[0],135);if(n.c.length<=0)return new M6;for(s=new Ub(n);s.al&&(P=0,I+=f+E,f=0),kLn(k,u,P,I),t=i.Math.max(t,P+j.a),f=i.Math.max(f,j.b),P+=j.a+E;for(y=new Lp,e=new Lp,M=new Ub(n);M.ag$n(c))&&(f=c);for(!f&&(h1(0,d.c.length),f=_B(d.c[0],180)),w=new Ub(t.b);w.a=-1900?1:0,aO(n,e>=4?Mun(Hk(Wtt,1),uVn,2,6,[sQn,hQn])[a]:Mun(Hk(Wtt,1),uVn,2,6,["BC","AD"])[a]);break;case 121:apn(n,e,i);break;case 77:zKn(n,e,i);break;case 107:knn(n,0==(u=r.q.getHours())?24:u,e);break;case 83:xLn(n,e,r);break;case 69:o=i.q.getDay(),aO(n,5==e?Mun(Hk(Wtt,1),uVn,2,6,["S","M","T","W","T","F","S"])[o]:4==e?Mun(Hk(Wtt,1),uVn,2,6,[fQn,lQn,bQn,wQn,dQn,gQn,pQn])[o]:Mun(Hk(Wtt,1),uVn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[o]);break;case 97:r.q.getHours()>=12&&r.q.getHours()<24?aO(n,Mun(Hk(Wtt,1),uVn,2,6,["AM","PM"])[1]):aO(n,Mun(Hk(Wtt,1),uVn,2,6,["AM","PM"])[0]);break;case 104:knn(n,0==(s=r.q.getHours()%12)?12:s,e);break;case 75:knn(n,r.q.getHours()%12,e);break;case 72:knn(n,r.q.getHours(),e);break;case 99:h=i.q.getDay(),5==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,["S","M","T","W","T","F","S"])[h]):4==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,[fQn,lQn,bQn,wQn,dQn,gQn,pQn])[h]):3==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[h]):knn(n,h,1);break;case 76:f=i.q.getMonth(),5==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,["J","F","M","A","M","J","J","A","S","O","N","D"])[f]):4==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,[VVn,QVn,JVn,YVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn])[f]):3==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,["Jan","Feb","Mar","Apr",ZVn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"])[f]):knn(n,f+1,e);break;case 81:l=i.q.getMonth()/3|0,aO(n,e<4?Mun(Hk(Wtt,1),uVn,2,6,["Q1","Q2","Q3","Q4"])[l]:Mun(Hk(Wtt,1),uVn,2,6,["1st quarter","2nd quarter","3rd quarter","4th quarter"])[l]);break;case 100:knn(n,i.q.getDate(),e);break;case 109:knn(n,r.q.getMinutes(),e);break;case 115:knn(n,r.q.getSeconds(),e);break;case 122:aO(n,e<4?c.c[0]:c.c[1]);break;case 118:aO(n,c.b);break;case 90:aO(n,e<3?YIn(c):3==e?lCn(c):bCn(c.a));break;default:return!1}return!0}function cWn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(ZRn(t),o=_B(Utn((!t.b&&(t.b=new oK(xOt,t,4,7)),t.b),0),82),h=_B(Utn((!t.c&&(t.c=new oK(xOt,t,5,8)),t.c),0),82),u=MTn(o),s=MTn(h),a=0==(!t.a&&(t.a=new nU(ROt,t,6,6)),t.a).i?null:_B(Utn((!t.a&&(t.a=new nU(ROt,t,6,6)),t.a),0),202),j=_B(xX(n.a,u),10),S=_B(xX(n.a,s),10),E=null,P=null,iL(o,186)&&(iL(k=_B(xX(n.a,o),299),11)?E=_B(k,11):iL(k,10)&&(j=_B(k,10),E=_B(Lq(j.j,0),11))),iL(h,186)&&(iL(M=_B(xX(n.a,h),299),11)?P=_B(M,11):iL(M,10)&&(S=_B(M,10),P=_B(Lq(S.j,0),11))),!j||!S)throw Fp(new ik("The source or the target of edge "+t+" could not be found. This usually happens when an edge connects a node laid out by ELK Layered to a node in another level of hierarchy laid out by either another instance of ELK Layered or another layout algorithm alltogether. The former can be solved by setting the hierarchyHandling option to INCLUDE_CHILDREN."));for(Ban(d=new lJ,t),oon(d,(oWn(),blt),t),oon(d,(FXn(),ggt),null),b=_B(pMn(i,Jft),21),j==S&&b.Fc((fDn(),gft)),E||(rin(),y=Bvt,T=null,a&&gA(_B(pMn(j,npt),98))&&(V3(T=new LI(a.j,a.k),zY(t)),Z4(T,e),Stn(s,u)&&(y=Fvt,GR(T,j.n))),E=bHn(j,T,y,i)),P||(rin(),y=Fvt,I=null,a&&gA(_B(pMn(S,npt),98))&&(V3(I=new LI(a.b,a.c),zY(t)),Z4(I,e)),P=bHn(S,I,y,gW(S))),TZ(d,E),EZ(d,P),(E.e.c.length>1||E.g.c.length>1||P.e.c.length>1||P.g.c.length>1)&&b.Fc((fDn(),fft)),l=new CL((!t.n&&(t.n=new nU(HOt,t,1,7)),t.n));l.e!=l.i.gc();)if(!By(jD(JAn(f=_B(mpn(l),137),Hgt)))&&f.a)switch(g=Fhn(f),UB(d.b,g),_B(pMn(g,Vdt),272).g){case 1:case 2:b.Fc((fDn(),sft));break;case 0:b.Fc((fDn(),uft)),oon(g,Vdt,(xtn(),qPt))}if(c=_B(pMn(i,Bdt),314),p=_B(pMn(i,Rgt),315),r=c==(Iin(),uht)||p==($vn(),dvt),a&&0!=(!a.a&&(a.a=new OL($Ot,a,5)),a.a).i&&r){for(v=BSn(a),w=new mm,m=upn(v,0);m.b!=m.d.c;)NH(w,new lA(_B(f3(m),8)));oon(d,wlt,w)}return d}function aWn(n){n.gb||(n.gb=!0,n.b=man(n,0),xrn(n.b,18),Drn(n.b,19),n.a=man(n,1),xrn(n.a,1),Drn(n.a,2),Drn(n.a,3),Drn(n.a,4),Drn(n.a,5),n.o=man(n,2),xrn(n.o,8),xrn(n.o,9),Drn(n.o,10),Drn(n.o,11),Drn(n.o,12),Drn(n.o,13),Drn(n.o,14),Drn(n.o,15),Drn(n.o,16),Drn(n.o,17),Drn(n.o,18),Drn(n.o,19),Drn(n.o,20),Drn(n.o,21),Drn(n.o,22),Drn(n.o,23),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),n.p=man(n,3),xrn(n.p,2),xrn(n.p,3),xrn(n.p,4),xrn(n.p,5),Drn(n.p,6),Drn(n.p,7),atn(n.p),atn(n.p),n.q=man(n,4),xrn(n.q,8),n.v=man(n,5),Drn(n.v,9),atn(n.v),atn(n.v),atn(n.v),n.w=man(n,6),xrn(n.w,2),xrn(n.w,3),xrn(n.w,4),Drn(n.w,5),n.B=man(n,7),Drn(n.B,1),atn(n.B),atn(n.B),atn(n.B),n.Q=man(n,8),Drn(n.Q,0),atn(n.Q),n.R=man(n,9),xrn(n.R,1),n.S=man(n,10),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),n.T=man(n,11),Drn(n.T,10),Drn(n.T,11),Drn(n.T,12),Drn(n.T,13),Drn(n.T,14),atn(n.T),atn(n.T),n.U=man(n,12),xrn(n.U,2),xrn(n.U,3),Drn(n.U,4),Drn(n.U,5),Drn(n.U,6),Drn(n.U,7),atn(n.U),n.V=man(n,13),Drn(n.V,10),n.W=man(n,14),xrn(n.W,18),xrn(n.W,19),xrn(n.W,20),Drn(n.W,21),Drn(n.W,22),Drn(n.W,23),n.bb=man(n,15),xrn(n.bb,10),xrn(n.bb,11),xrn(n.bb,12),xrn(n.bb,13),xrn(n.bb,14),xrn(n.bb,15),xrn(n.bb,16),Drn(n.bb,17),atn(n.bb),atn(n.bb),n.eb=man(n,16),xrn(n.eb,2),xrn(n.eb,3),xrn(n.eb,4),xrn(n.eb,5),xrn(n.eb,6),xrn(n.eb,7),Drn(n.eb,8),Drn(n.eb,9),n.ab=man(n,17),xrn(n.ab,0),xrn(n.ab,1),n.H=man(n,18),Drn(n.H,0),Drn(n.H,1),Drn(n.H,2),Drn(n.H,3),Drn(n.H,4),Drn(n.H,5),atn(n.H),n.db=man(n,19),Drn(n.db,2),n.c=yan(n,20),n.d=yan(n,21),n.e=yan(n,22),n.f=yan(n,23),n.i=yan(n,24),n.g=yan(n,25),n.j=yan(n,26),n.k=yan(n,27),n.n=yan(n,28),n.r=yan(n,29),n.s=yan(n,30),n.t=yan(n,31),n.u=yan(n,32),n.fb=yan(n,33),n.A=yan(n,34),n.C=yan(n,35),n.D=yan(n,36),n.F=yan(n,37),n.G=yan(n,38),n.I=yan(n,39),n.J=yan(n,40),n.L=yan(n,41),n.M=yan(n,42),n.N=yan(n,43),n.O=yan(n,44),n.P=yan(n,45),n.X=yan(n,46),n.Y=yan(n,47),n.Z=yan(n,48),n.$=yan(n,49),n._=yan(n,50),n.cb=yan(n,51),n.K=yan(n,52))}function uWn(){var n,t;uWn=O,nSt=new cp(l5n),pPt=new cp(b5n),lvn(),tSt=new OO(U2n,eSt=SMt),new Op,iSt=new OO(XYn,null),rSt=new cp(w5n),lEn(),sSt=kG(JMt,Mun(Hk(BPt,1),OVn,291,0,[XMt])),oSt=new OO(c3n,sSt),hSt=new OO(z2n,(oN(),!1)),Kfn(),fSt=new OO(Q2n,lSt=_Pt),Ebn(),gSt=new OO(v2n,pSt=JPt),ySt=new OO(C4n,!1),cfn(),kSt=new OO(b2n,jSt=gIt),USt=new UA(12),zSt=new OO(WYn,USt),SSt=new OO(yZn,!1),PSt=new OO(p3n,!1),GSt=new OO(EZn,!1),WEn(),cPt=new OO(kZn,aPt=VIt),wPt=new cp(w3n),dPt=new cp(dZn),gPt=new cp(vZn),mPt=new cp(mZn),CSt=new mm,ISt=new OO(a3n,CSt),uSt=new OO(s3n,!1),ESt=new OO(h3n,!1),new cp(d5n),ASt=new hm,OSt=new OO(d3n,ASt),qSt=new OO(q2n,!1),new Op,vPt=new OO(g5n,1),new OO(p5n,!0),tln(0),new OO(v5n,tln(100)),new OO(m5n,!1),tln(0),new OO(y5n,tln(4e3)),tln(0),new OO(k5n,tln(400)),new OO(j5n,!1),new OO(E5n,!1),new OO(T5n,!0),new OO(M5n,!1),Kwn(),cSt=new OO(f5n,aSt=nOt),yPt=new OO(A2n,10),kPt=new OO($2n,10),jPt=new OO(zYn,20),EPt=new OO(L2n,10),TPt=new OO(pZn,2),MPt=new OO(N2n,10),PPt=new OO(x2n,0),IPt=new OO(K2n,5),CPt=new OO(D2n,1),OPt=new OO(R2n,1),APt=new OO(gZn,20),$Pt=new OO(_2n,10),xPt=new OO(F2n,10),SPt=new cp(B2n),NPt=new hA,LPt=new OO(g3n,NPt),VSt=new cp(b3n),XSt=new OO(l3n,WSt=!1),LSt=new UA(5),$St=new OO(J2n,LSt),YAn(),t=_B(Xj(HIt),9),xSt=new VK(t,_B(TR(t,t.length),9),0),NSt=new OO(SZn,xSt),ipn(),JSt=new OO(n3n,YSt=_It),nPt=new cp(t3n),tPt=new cp(e3n),ePt=new cp(i3n),ZSt=new cp(r3n),n=_B(Xj(VCt),9),RSt=new VK(n,_B(TR(n,n.length),9),0),DSt=new OO(MZn,RSt),HSt=Yln((YKn(),HCt)),BSt=new OO(TZn,HSt),FSt=new LI(0,0),_St=new OO(_Zn,FSt),KSt=new OO(V2n,!1),xtn(),wSt=new OO(u3n,dSt=qPt),bSt=new OO(jZn,!1),new cp(S5n),tln(1),new OO(P5n,null),iPt=new cp(f3n),uPt=new cp(o3n),mUn(),lPt=new OO(G2n,bPt=MCt),rPt=new cp(H2n),hCn(),hPt=Yln(eCt),sPt=new OO(PZn,hPt),oPt=new OO(Y2n,!1),fPt=new OO(Z2n,!0),TSt=new OO(X2n,!1),MSt=new OO(W2n,!1),vSt=new OO(UYn,1),YTn(),new OO(I5n,mSt=rIt),QSt=!0}function oWn(){var n,t;oWn=O,blt=new cp(IZn),Kft=new cp("coordinateOrigin"),Elt=new cp("processors"),Rft=new tR("compoundNode",(oN(),!1)),nlt=new tR("insideConnections",!1),wlt=new cp("originalBendpoints"),dlt=new cp("originalDummyNodePosition"),glt=new cp("originalLabelEdge"),Mlt=new cp("representedLabels"),qft=new cp("endLabels"),Gft=new cp("endLabel.origin"),clt=new tR("labelSide",(zyn(),EIt)),flt=new tR("maxEdgeThickness",0),Slt=new tR("reversed",!1),Tlt=new cp(CZn),olt=new tR("longEdgeSource",null),slt=new tR("longEdgeTarget",null),ult=new tR("longEdgeHasLabelDummies",!1),alt=new tR("longEdgeBeforeLabelDummy",!1),Hft=new tR("edgeConstraint",(Qun(),Cht)),elt=new cp("inLayerLayoutUnit"),tlt=new tR("inLayerConstraint",(q7(),Mft)),ilt=new tR("inLayerSuccessorConstraint",new $p),rlt=new tR("inLayerSuccessorConstraintBetweenNonDummies",!1),klt=new cp("portDummy"),_ft=new tR("crossingHint",tln(0)),Jft=new tR("graphProperties",new VK(t=_B(Xj(jft),9),_B(TR(t,t.length),9),0)),Wft=new tR("externalPortSide",(mUn(),MCt)),Vft=new tR("externalPortSize",new Hj),Uft=new cp("externalPortReplacedDummies"),Xft=new cp("externalPortReplacedDummy"),zft=new tR("externalPortConnections",new VK(n=_B(Xj(KCt),9),_B(TR(n,n.length),9),0)),jlt=new tR(bYn,0),Lft=new cp("barycenterAssociates"),Dlt=new cp("TopSideComments"),Nft=new cp("BottomSideComments"),Dft=new cp("CommentConnectionPort"),Zft=new tR("inputCollect",!1),mlt=new tR("outputCollect",!1),Bft=new tR("cyclic",!1),Fft=new cp("crossHierarchyMap"),xlt=new cp("targetOffset"),new tR("splineLabelSize",new Hj),Clt=new cp("spacings"),ylt=new tR("partitionConstraint",!1),xft=new cp("breakingPoint.info"),Llt=new cp("splines.survivingEdge"),$lt=new cp("splines.route.start"),Olt=new cp("splines.edgeChain"),vlt=new cp("originalPortConstraints"),Ilt=new cp("selfLoopHolder"),Alt=new cp("splines.nsPortY"),llt=new cp("modelOrder"),hlt=new cp("longEdgeTargetNode"),Qft=new tR(q1n,!1),Plt=new tR(q1n,!1),Yft=new cp("layerConstraints.hiddenNodes"),plt=new cp("layerConstraints.opposidePort"),Nlt=new cp("targetNode.modelOrder")}function sWn(){sWn=O,Rnn(),Tbt=new OO(G1n,Mbt=Tht),Hbt=new OO(z1n,(oN(),!1)),q2(),Xbt=new OO(U1n,Wbt=Cft),lwt=new OO(X1n,!1),bwt=new OO(W1n,!0),Glt=new OO(V1n,!1),G7(),$wt=new OO(Q1n,Lwt=Dvt),tln(1),Bwt=new OO(J1n,tln(7)),Hwt=new OO(Y1n,!1),qbt=new OO(Z1n,!1),Xvn(),jbt=new OO(n0n,Ebt=vht),jTn(),hwt=new OO(t0n,fwt=Zpt),jbn(),nwt=new OO(e0n,twt=Blt),tln(-1),Zbt=new OO(i0n,tln(-1)),tln(-1),ewt=new OO(r0n,tln(-1)),tln(-1),iwt=new OO(c0n,tln(4)),tln(-1),cwt=new OO(a0n,tln(2)),uNn(),owt=new OO(u0n,swt=Pvt),tln(0),uwt=new OO(o0n,tln(0)),Jbt=new OO(s0n,tln(NWn)),Iin(),ybt=new OO(h0n,kbt=oht),cbt=new OO(f0n,!1),wbt=new OO(l0n,.1),vbt=new OO(b0n,!1),tln(-1),gbt=new OO(w0n,tln(-1)),tln(-1),pbt=new OO(d0n,tln(-1)),tln(0),abt=new OO(g0n,tln(40)),Dan(),fbt=new OO(p0n,lbt=kft),ubt=new OO(v0n,obt=mft),$vn(),Owt=new OO(m0n,Awt=wvt),ywt=new cp(y0n),w7(),wwt=new OO(k0n,dwt=Bht),_jn(),pwt=new OO(j0n,vwt=Wht),new Op,Ewt=new OO(E0n,.3),Mwt=new cp(T0n),fvn(),Swt=new OO(M0n,Pwt=hvt),Fcn(),$bt=new OO(S0n,Lbt=Uvt),C6(),Nbt=new OO(P0n,xbt=Jvt),Gsn(),Dbt=new OO(I0n,Rbt=emt),_bt=new OO(C0n,.2),Obt=new OO(O0n,2),Rwt=new OO(A0n,null),_wt=new OO($0n,10),Kwt=new OO(L0n,10),Fwt=new OO(N0n,20),tln(0),Nwt=new OO(x0n,tln(0)),tln(0),xwt=new OO(D0n,tln(0)),tln(0),Dwt=new OO(R0n,tln(0)),zlt=new OO(K0n,!1),QMn(),Wlt=new OO(_0n,Vlt=ift),X8(),Ult=new OO(F0n,Xlt=rht),zbt=new OO(B0n,!1),tln(0),Gbt=new OO(H0n,tln(16)),tln(0),Ubt=new OO(q0n,tln(5)),Oun(),hdt=new OO(G0n,fdt=fmt),qwt=new OO(z0n,10),Uwt=new OO(U0n,1),cin(),ndt=new OO(X0n,tdt=wht),Vwt=new cp(W0n),Ywt=tln(1),tln(0),Jwt=new OO(V0n,Ywt),bcn(),ddt=new OO(Q0n,gdt=cmt),ldt=new cp(J0n),adt=new OO(Y0n,!0),rdt=new OO(Z0n,2),odt=new OO(n2n,!0),wSn(),Ibt=new OO(t2n,Cbt=Rht),OPn(),Sbt=new OO(e2n,Pbt=Jst),pon(),ibt=new OO(i2n,rbt=$vt),ebt=new OO(r2n,!1),_fn(),Qlt=new OO(c2n,Jlt=lut),Ehn(),nbt=new OO(a2n,tbt=ivt),Ylt=new OO(u2n,0),Zlt=new OO(o2n,0),Qbt=yht,Vbt=uht,rwt=Ypt,awt=Ypt,Ybt=Vpt,cfn(),dbt=dIt,mbt=oht,bbt=oht,sbt=oht,hbt=dIt,kwt=pvt,jwt=wvt,gwt=wvt,mwt=wvt,Twt=gvt,Cwt=pvt,Iwt=pvt,Ebn(),Kbt=QPt,Fbt=QPt,Bbt=emt,Abt=VPt,Gwt=lmt,zwt=hmt,Xwt=lmt,Wwt=hmt,edt=lmt,idt=hmt,Qwt=bht,Zwt=wht,pdt=lmt,vdt=hmt,bdt=lmt,wdt=hmt,udt=hmt,cdt=hmt,sdt=hmt}function hWn(){hWn=O,eot=new YS("DIRECTION_PREPROCESSOR",0),Zut=new YS("COMMENT_PREPROCESSOR",1),iot=new YS("EDGE_AND_LAYER_CONSTRAINT_EDGE_REVERSER",2),mot=new YS("INTERACTIVE_EXTERNAL_PORT_POSITIONER",3),Kot=new YS("PARTITION_PREPROCESSOR",4),Eot=new YS("LABEL_DUMMY_INSERTER",5),Got=new YS("SELF_LOOP_PREPROCESSOR",6),Iot=new YS("LAYER_CONSTRAINT_PREPROCESSOR",7),Dot=new YS("PARTITION_MIDPROCESSOR",8),wot=new YS("HIGH_DEGREE_NODE_LAYER_PROCESSOR",9),$ot=new YS("NODE_PROMOTION",10),Pot=new YS("LAYER_CONSTRAINT_POSTPROCESSOR",11),Rot=new YS("PARTITION_POSTPROCESSOR",12),hot=new YS("HIERARCHICAL_PORT_CONSTRAINT_PROCESSOR",13),Uot=new YS("SEMI_INTERACTIVE_CROSSMIN_PROCESSOR",14),Xut=new YS("BREAKING_POINT_INSERTER",15),Aot=new YS("LONG_EDGE_SPLITTER",16),Fot=new YS("PORT_SIDE_PROCESSOR",17),yot=new YS("INVERTED_PORT_PROCESSOR",18),_ot=new YS("PORT_LIST_SORTER",19),Wot=new YS("SORT_BY_INPUT_ORDER_OF_MODEL",20),Not=new YS("NORTH_SOUTH_PORT_PREPROCESSOR",21),Wut=new YS("BREAKING_POINT_PROCESSOR",22),xot=new YS(k1n,23),Vot=new YS(j1n,24),Hot=new YS("SELF_LOOP_PORT_RESTORER",25),Xot=new YS("SINGLE_EDGE_GRAPH_WRAPPER",26),kot=new YS("IN_LAYER_CONSTRAINT_PROCESSOR",27),uot=new YS("END_NODE_PORT_LABEL_MANAGEMENT_PROCESSOR",28),jot=new YS("LABEL_AND_NODE_SIZE_PROCESSOR",29),vot=new YS("INNERMOST_NODE_MARGIN_CALCULATOR",30),zot=new YS("SELF_LOOP_ROUTER",31),Jut=new YS("COMMENT_NODE_MARGIN_CALCULATOR",32),cot=new YS("END_LABEL_PREPROCESSOR",33),Mot=new YS("LABEL_DUMMY_SWITCHER",34),Qut=new YS("CENTER_LABEL_MANAGEMENT_PROCESSOR",35),Sot=new YS("LABEL_SIDE_SELECTOR",36),got=new YS("HYPEREDGE_DUMMY_MERGER",37),fot=new YS("HIERARCHICAL_PORT_DUMMY_SIZE_PROCESSOR",38),Cot=new YS("LAYER_SIZE_AND_GRAPH_HEIGHT_CALCULATOR",39),bot=new YS("HIERARCHICAL_PORT_POSITION_PROCESSOR",40),not=new YS("CONSTRAINTS_POSTPROCESSOR",41),Yut=new YS("COMMENT_POSTPROCESSOR",42),pot=new YS("HYPERNODE_PROCESSOR",43),lot=new YS("HIERARCHICAL_PORT_ORTHOGONAL_EDGE_ROUTER",44),Oot=new YS("LONG_EDGE_JOINER",45),qot=new YS("SELF_LOOP_POSTPROCESSOR",46),Vut=new YS("BREAKING_POINT_REMOVER",47),Lot=new YS("NORTH_SOUTH_PORT_POSTPROCESSOR",48),dot=new YS("HORIZONTAL_COMPACTOR",49),Tot=new YS("LABEL_DUMMY_REMOVER",50),oot=new YS("FINAL_SPLINE_BENDPOINTS_CALCULATOR",51),aot=new YS("END_LABEL_SORTER",52),Bot=new YS("REVERSED_EDGE_RESTORER",53),rot=new YS("END_LABEL_POSTPROCESSOR",54),sot=new YS("HIERARCHICAL_NODE_RESIZER",55),tot=new YS("DIRECTION_POSTPROCESSOR",56)}function fWn(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A,$,L,N,x,D,R,K,_,F,B,H,q,G,z,U,X,W,V,Q,J,Y,Z,nn,tn,en,rn,cn,an,un,on;for(Y=0,L=0,D=(O=t).length;L0&&(n.a[q.p]=Y++)}for(rn=0,N=0,R=(A=e).length;N0;){for(Mx(X.b>0),U=0,o=new Ub((q=_B(X.a.Xb(X.c=--X.b),11)).e);o.a0&&(q.j==(mUn(),uCt)?(n.a[q.p]=rn,++rn):(n.a[q.p]=rn+K+F,++F))}rn+=F}for(z=new Lp,d=new sA,$=0,x=(C=t).length;$h.b&&(h.b=W)):q.i.c==J&&(Wh.c&&(h.c=W));for(q9(g,0,g.length,null),en=L8(INt,oQn,25,g.length,15,1),r=L8(INt,oQn,25,rn+1,15,1),v=0;v0;)T%2>0&&(c+=un[T+1]),++un[T=(T-1)/2|0];for(S=L8(Bmt,FWn,362,2*g.length,0,1),k=0;k'?":pK(g8n,n)?"'(?<' or '(? toIndex: ",mJn=", toIndex: ",yJn="Index: ",kJn=", Size: ",jJn="org.eclipse.elk.alg.common",EJn={62:1},TJn="org.eclipse.elk.alg.common.compaction",MJn="Scanline/EventHandler",SJn="org.eclipse.elk.alg.common.compaction.oned",PJn="CNode belongs to another CGroup.",IJn="ISpacingsHandler/1",CJn="The ",OJn=" instance has been finished already.",AJn="The direction ",$Jn=" is not supported by the CGraph instance.",LJn="OneDimensionalCompactor",NJn="OneDimensionalCompactor/lambda$0$Type",xJn="Quadruplet",DJn="ScanlineConstraintCalculator",RJn="ScanlineConstraintCalculator/ConstraintsScanlineHandler",KJn="ScanlineConstraintCalculator/ConstraintsScanlineHandler/lambda$0$Type",_Jn="ScanlineConstraintCalculator/Timestamp",FJn="ScanlineConstraintCalculator/lambda$0$Type",BJn={169:1,45:1},HJn="org.eclipse.elk.alg.common.compaction.options",qJn="org.eclipse.elk.core.data",GJn="org.eclipse.elk.polyomino.traversalStrategy",zJn="org.eclipse.elk.polyomino.lowLevelSort",UJn="org.eclipse.elk.polyomino.highLevelSort",XJn="org.eclipse.elk.polyomino.fill",WJn={130:1},VJn="polyomino",QJn="org.eclipse.elk.alg.common.networksimplex",JJn={177:1,3:1,4:1},YJn="org.eclipse.elk.alg.common.nodespacing",ZJn="org.eclipse.elk.alg.common.nodespacing.cellsystem",nYn="CENTER",tYn={212:1,326:1},eYn={3:1,4:1,5:1,595:1},iYn="LEFT",rYn="RIGHT",cYn="Vertical alignment cannot be null",aYn="BOTTOM",uYn="org.eclipse.elk.alg.common.nodespacing.internal",oYn="UNDEFINED",sYn=.01,hYn="org.eclipse.elk.alg.common.nodespacing.internal.algorithm",fYn="LabelPlacer/lambda$0$Type",lYn="LabelPlacer/lambda$1$Type",bYn="portRatioOrPosition",wYn="org.eclipse.elk.alg.common.overlaps",dYn="DOWN",gYn="org.eclipse.elk.alg.common.polyomino",pYn="NORTH",vYn="EAST",mYn="SOUTH",yYn="WEST",kYn="org.eclipse.elk.alg.common.polyomino.structures",jYn="Direction",EYn="Grid is only of size ",TYn=". Requested point (",MYn=") is out of bounds.",SYn=" Given center based coordinates were (",PYn="org.eclipse.elk.graph.properties",IYn="IPropertyHolder",CYn={3:1,94:1,134:1},OYn="org.eclipse.elk.alg.common.spore",AYn="org.eclipse.elk.alg.common.utils",$Yn={209:1},LYn="org.eclipse.elk.core",NYn="Connected Components Compaction",xYn="org.eclipse.elk.alg.disco",DYn="org.eclipse.elk.alg.disco.graph",RYn="org.eclipse.elk.alg.disco.options",KYn="CompactionStrategy",_Yn="org.eclipse.elk.disco.componentCompaction.strategy",FYn="org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm",BYn="org.eclipse.elk.disco.debug.discoGraph",HYn="org.eclipse.elk.disco.debug.discoPolys",qYn="componentCompaction",GYn="org.eclipse.elk.disco",zYn="org.eclipse.elk.spacing.componentComponent",UYn="org.eclipse.elk.edge.thickness",XYn="org.eclipse.elk.aspectRatio",WYn="org.eclipse.elk.padding",VYn="org.eclipse.elk.alg.disco.transform",QYn=1.5707963267948966,JYn=17976931348623157e292,YYn={3:1,4:1,5:1,192:1},ZYn={3:1,6:1,4:1,5:1,106:1,120:1},nZn="org.eclipse.elk.alg.force",tZn="ComponentsProcessor",eZn="ComponentsProcessor/1",iZn="org.eclipse.elk.alg.force.graph",rZn="Component Layout",cZn="org.eclipse.elk.alg.force.model",aZn="org.eclipse.elk.force.model",uZn="org.eclipse.elk.force.iterations",oZn="org.eclipse.elk.force.repulsivePower",sZn="org.eclipse.elk.force.temperature",hZn=.001,fZn="org.eclipse.elk.force.repulsion",lZn="org.eclipse.elk.alg.force.options",bZn=1.600000023841858,wZn="org.eclipse.elk.force",dZn="org.eclipse.elk.priority",gZn="org.eclipse.elk.spacing.nodeNode",pZn="org.eclipse.elk.spacing.edgeLabel",vZn="org.eclipse.elk.randomSeed",mZn="org.eclipse.elk.separateConnectedComponents",yZn="org.eclipse.elk.interactive",kZn="org.eclipse.elk.portConstraints",jZn="org.eclipse.elk.edgeLabels.inline",EZn="org.eclipse.elk.omitNodeMicroLayout",TZn="org.eclipse.elk.nodeSize.options",MZn="org.eclipse.elk.nodeSize.constraints",SZn="org.eclipse.elk.nodeLabels.placement",PZn="org.eclipse.elk.portLabels.placement",IZn="origin",CZn="random",OZn="boundingBox.upLeft",AZn="boundingBox.lowRight",$Zn="org.eclipse.elk.stress.fixed",LZn="org.eclipse.elk.stress.desiredEdgeLength",NZn="org.eclipse.elk.stress.dimension",xZn="org.eclipse.elk.stress.epsilon",DZn="org.eclipse.elk.stress.iterationLimit",RZn="org.eclipse.elk.stress",KZn="ELK Stress",_Zn="org.eclipse.elk.nodeSize.minimum",FZn="org.eclipse.elk.alg.force.stress",BZn="Layered layout",HZn="org.eclipse.elk.alg.layered",qZn="org.eclipse.elk.alg.layered.compaction.components",GZn="org.eclipse.elk.alg.layered.compaction.oned",zZn="org.eclipse.elk.alg.layered.compaction.oned.algs",UZn="org.eclipse.elk.alg.layered.compaction.recthull",XZn="org.eclipse.elk.alg.layered.components",WZn="NONE",VZn={3:1,6:1,4:1,9:1,5:1,122:1},QZn={3:1,6:1,4:1,5:1,141:1,106:1,120:1},JZn="org.eclipse.elk.alg.layered.compound",YZn={51:1},ZZn="org.eclipse.elk.alg.layered.graph",n1n=" -> ",t1n="Not supported by LGraph",e1n="Port side is undefined",i1n={3:1,6:1,4:1,5:1,474:1,141:1,106:1,120:1},r1n={3:1,6:1,4:1,5:1,141:1,193:1,203:1,106:1,120:1},c1n={3:1,6:1,4:1,5:1,141:1,1943:1,203:1,106:1,120:1},a1n="([{\"' \t\r\n",u1n=")]}\"' \t\r\n",o1n="The given string contains parts that cannot be parsed as numbers.",s1n="org.eclipse.elk.core.math",h1n={3:1,4:1,142:1,207:1,414:1},f1n={3:1,4:1,116:1,207:1,414:1},l1n="org.eclipse.elk.layered",b1n="org.eclipse.elk.alg.layered.graph.transform",w1n="ElkGraphImporter",d1n="ElkGraphImporter/lambda$0$Type",g1n="ElkGraphImporter/lambda$1$Type",p1n="ElkGraphImporter/lambda$2$Type",v1n="ElkGraphImporter/lambda$4$Type",m1n="Node margin calculation",y1n="org.eclipse.elk.alg.layered.intermediate",k1n="ONE_SIDED_GREEDY_SWITCH",j1n="TWO_SIDED_GREEDY_SWITCH",E1n="No implementation is available for the layout processor ",T1n="IntermediateProcessorStrategy",M1n="Node '",S1n="FIRST_SEPARATE",P1n="LAST_SEPARATE",I1n="Odd port side processing",C1n="org.eclipse.elk.alg.layered.intermediate.compaction",O1n="org.eclipse.elk.alg.layered.intermediate.greedyswitch",A1n="org.eclipse.elk.alg.layered.p3order.counting",$1n={225:1},L1n="org.eclipse.elk.alg.layered.intermediate.loops",N1n="org.eclipse.elk.alg.layered.intermediate.loops.ordering",x1n="org.eclipse.elk.alg.layered.intermediate.loops.routing",D1n="org.eclipse.elk.alg.layered.intermediate.preserveorder",R1n="org.eclipse.elk.alg.layered.intermediate.wrapping",K1n="org.eclipse.elk.alg.layered.options",_1n="INTERACTIVE",F1n="DEPTH_FIRST",B1n="EDGE_LENGTH",H1n="SELF_LOOPS",q1n="firstTryWithInitialOrder",G1n="org.eclipse.elk.layered.directionCongruency",z1n="org.eclipse.elk.layered.feedbackEdges",U1n="org.eclipse.elk.layered.interactiveReferencePoint",X1n="org.eclipse.elk.layered.mergeEdges",W1n="org.eclipse.elk.layered.mergeHierarchyEdges",V1n="org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides",Q1n="org.eclipse.elk.layered.portSortingStrategy",J1n="org.eclipse.elk.layered.thoroughness",Y1n="org.eclipse.elk.layered.unnecessaryBendpoints",Z1n="org.eclipse.elk.layered.generatePositionAndLayerIds",n0n="org.eclipse.elk.layered.cycleBreaking.strategy",t0n="org.eclipse.elk.layered.layering.strategy",e0n="org.eclipse.elk.layered.layering.layerConstraint",i0n="org.eclipse.elk.layered.layering.layerChoiceConstraint",r0n="org.eclipse.elk.layered.layering.layerId",c0n="org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth",a0n="org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor",u0n="org.eclipse.elk.layered.layering.nodePromotion.strategy",o0n="org.eclipse.elk.layered.layering.nodePromotion.maxIterations",s0n="org.eclipse.elk.layered.layering.coffmanGraham.layerBound",h0n="org.eclipse.elk.layered.crossingMinimization.strategy",f0n="org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder",l0n="org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness",b0n="org.eclipse.elk.layered.crossingMinimization.semiInteractive",w0n="org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint",d0n="org.eclipse.elk.layered.crossingMinimization.positionId",g0n="org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold",p0n="org.eclipse.elk.layered.crossingMinimization.greedySwitch.type",v0n="org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type",m0n="org.eclipse.elk.layered.nodePlacement.strategy",y0n="org.eclipse.elk.layered.nodePlacement.favorStraightEdges",k0n="org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening",j0n="org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment",E0n="org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening",T0n="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility",M0n="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default",S0n="org.eclipse.elk.layered.edgeRouting.selfLoopDistribution",P0n="org.eclipse.elk.layered.edgeRouting.selfLoopOrdering",I0n="org.eclipse.elk.layered.edgeRouting.splines.mode",C0n="org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor",O0n="org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth",A0n="org.eclipse.elk.layered.spacing.baseValue",$0n="org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers",L0n="org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers",N0n="org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers",x0n="org.eclipse.elk.layered.priority.direction",D0n="org.eclipse.elk.layered.priority.shortness",R0n="org.eclipse.elk.layered.priority.straightness",K0n="org.eclipse.elk.layered.compaction.connectedComponents",_0n="org.eclipse.elk.layered.compaction.postCompaction.strategy",F0n="org.eclipse.elk.layered.compaction.postCompaction.constraints",B0n="org.eclipse.elk.layered.highDegreeNodes.treatment",H0n="org.eclipse.elk.layered.highDegreeNodes.threshold",q0n="org.eclipse.elk.layered.highDegreeNodes.treeHeight",G0n="org.eclipse.elk.layered.wrapping.strategy",z0n="org.eclipse.elk.layered.wrapping.additionalEdgeSpacing",U0n="org.eclipse.elk.layered.wrapping.correctionFactor",X0n="org.eclipse.elk.layered.wrapping.cutting.strategy",W0n="org.eclipse.elk.layered.wrapping.cutting.cuts",V0n="org.eclipse.elk.layered.wrapping.cutting.msd.freedom",Q0n="org.eclipse.elk.layered.wrapping.validify.strategy",J0n="org.eclipse.elk.layered.wrapping.validify.forbiddenIndices",Y0n="org.eclipse.elk.layered.wrapping.multiEdge.improveCuts",Z0n="org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty",n2n="org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges",t2n="org.eclipse.elk.layered.edgeLabels.sideSelection",e2n="org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy",i2n="org.eclipse.elk.layered.considerModelOrder.strategy",r2n="org.eclipse.elk.layered.considerModelOrder.noModelOrder",c2n="org.eclipse.elk.layered.considerModelOrder.components",a2n="org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy",u2n="org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence",o2n="org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence",s2n="layering",h2n="layering.minWidth",f2n="layering.nodePromotion",l2n="crossingMinimization",b2n="org.eclipse.elk.hierarchyHandling",w2n="crossingMinimization.greedySwitch",d2n="nodePlacement",g2n="nodePlacement.bk",p2n="edgeRouting",v2n="org.eclipse.elk.edgeRouting",m2n="spacing",y2n="priority",k2n="compaction",j2n="compaction.postCompaction",E2n="Specifies whether and how post-process compaction is applied.",T2n="highDegreeNodes",M2n="wrapping",S2n="wrapping.cutting",P2n="wrapping.validify",I2n="wrapping.multiEdge",C2n="edgeLabels",O2n="considerModelOrder",A2n="org.eclipse.elk.spacing.commentComment",$2n="org.eclipse.elk.spacing.commentNode",L2n="org.eclipse.elk.spacing.edgeEdge",N2n="org.eclipse.elk.spacing.edgeNode",x2n="org.eclipse.elk.spacing.labelLabel",D2n="org.eclipse.elk.spacing.labelPortHorizontal",R2n="org.eclipse.elk.spacing.labelPortVertical",K2n="org.eclipse.elk.spacing.labelNode",_2n="org.eclipse.elk.spacing.nodeSelfLoop",F2n="org.eclipse.elk.spacing.portPort",B2n="org.eclipse.elk.spacing.individual",H2n="org.eclipse.elk.port.borderOffset",q2n="org.eclipse.elk.noLayout",G2n="org.eclipse.elk.port.side",z2n="org.eclipse.elk.debugMode",U2n="org.eclipse.elk.alignment",X2n="org.eclipse.elk.insideSelfLoops.activate",W2n="org.eclipse.elk.insideSelfLoops.yo",V2n="org.eclipse.elk.nodeSize.fixedGraphSize",Q2n="org.eclipse.elk.direction",J2n="org.eclipse.elk.nodeLabels.padding",Y2n="org.eclipse.elk.portLabels.nextToPortIfPossible",Z2n="org.eclipse.elk.portLabels.treatAsGroup",n3n="org.eclipse.elk.portAlignment.default",t3n="org.eclipse.elk.portAlignment.north",e3n="org.eclipse.elk.portAlignment.south",i3n="org.eclipse.elk.portAlignment.west",r3n="org.eclipse.elk.portAlignment.east",c3n="org.eclipse.elk.contentAlignment",a3n="org.eclipse.elk.junctionPoints",u3n="org.eclipse.elk.edgeLabels.placement",o3n="org.eclipse.elk.port.index",s3n="org.eclipse.elk.commentBox",h3n="org.eclipse.elk.hypernode",f3n="org.eclipse.elk.port.anchor",l3n="org.eclipse.elk.partitioning.activate",b3n="org.eclipse.elk.partitioning.partition",w3n="org.eclipse.elk.position",d3n="org.eclipse.elk.margins",g3n="org.eclipse.elk.spacing.portsSurrounding",p3n="org.eclipse.elk.interactiveLayout",v3n="org.eclipse.elk.core.util",m3n={3:1,4:1,5:1,593:1},y3n="NETWORK_SIMPLEX",k3n={123:1,51:1},j3n="org.eclipse.elk.alg.layered.p1cycles",E3n="org.eclipse.elk.alg.layered.p2layers",T3n={402:1,225:1},M3n={832:1,3:1,4:1},S3n="org.eclipse.elk.alg.layered.p3order",P3n="org.eclipse.elk.alg.layered.p4nodes",I3n={3:1,4:1,5:1,840:1},C3n=1e-5,O3n="org.eclipse.elk.alg.layered.p4nodes.bk",A3n="org.eclipse.elk.alg.layered.p5edges",$3n="org.eclipse.elk.alg.layered.p5edges.orthogonal",L3n="org.eclipse.elk.alg.layered.p5edges.orthogonal.direction",N3n=1e-6,x3n="org.eclipse.elk.alg.layered.p5edges.splines",D3n=.09999999999999998,R3n=1e-8,K3n=4.71238898038469,_3n=3.141592653589793,F3n="org.eclipse.elk.alg.mrtree",B3n="org.eclipse.elk.alg.mrtree.graph",H3n="org.eclipse.elk.alg.mrtree.intermediate",q3n="Set neighbors in level",G3n="DESCENDANTS",z3n="org.eclipse.elk.mrtree.weighting",U3n="org.eclipse.elk.mrtree.searchOrder",X3n="org.eclipse.elk.alg.mrtree.options",W3n="org.eclipse.elk.mrtree",V3n="org.eclipse.elk.tree",Q3n="org.eclipse.elk.alg.radial",J3n=6.283185307179586,Y3n=5e-324,Z3n="org.eclipse.elk.alg.radial.intermediate",n4n="org.eclipse.elk.alg.radial.intermediate.compaction",t4n={3:1,4:1,5:1,106:1},e4n="org.eclipse.elk.alg.radial.intermediate.optimization",i4n="No implementation is available for the layout option ",r4n="org.eclipse.elk.alg.radial.options",c4n="org.eclipse.elk.radial.orderId",a4n="org.eclipse.elk.radial.radius",u4n="org.eclipse.elk.radial.compactor",o4n="org.eclipse.elk.radial.compactionStepSize",s4n="org.eclipse.elk.radial.sorter",h4n="org.eclipse.elk.radial.wedgeCriteria",f4n="org.eclipse.elk.radial.optimizationCriteria",l4n="org.eclipse.elk.radial",b4n="org.eclipse.elk.alg.radial.p1position.wedge",w4n="org.eclipse.elk.alg.radial.sorting",d4n=5.497787143782138,g4n=3.9269908169872414,p4n=2.356194490192345,v4n="org.eclipse.elk.alg.rectpacking",m4n="org.eclipse.elk.alg.rectpacking.firstiteration",y4n="org.eclipse.elk.alg.rectpacking.options",k4n="org.eclipse.elk.rectpacking.optimizationGoal",j4n="org.eclipse.elk.rectpacking.lastPlaceShift",E4n="org.eclipse.elk.rectpacking.currentPosition",T4n="org.eclipse.elk.rectpacking.desiredPosition",M4n="org.eclipse.elk.rectpacking.onlyFirstIteration",S4n="org.eclipse.elk.rectpacking.rowCompaction",P4n="org.eclipse.elk.rectpacking.expandToAspectRatio",I4n="org.eclipse.elk.rectpacking.targetWidth",C4n="org.eclipse.elk.expandNodes",O4n="org.eclipse.elk.rectpacking",A4n="org.eclipse.elk.alg.rectpacking.util",$4n="No implementation available for ",L4n="org.eclipse.elk.alg.spore",N4n="org.eclipse.elk.alg.spore.options",x4n="org.eclipse.elk.sporeCompaction",D4n="org.eclipse.elk.underlyingLayoutAlgorithm",R4n="org.eclipse.elk.processingOrder.treeConstruction",K4n="org.eclipse.elk.processingOrder.spanningTreeCostFunction",_4n="org.eclipse.elk.processingOrder.preferredRoot",F4n="org.eclipse.elk.processingOrder.rootSelection",B4n="org.eclipse.elk.structure.structureExtractionStrategy",H4n="org.eclipse.elk.compaction.compactionStrategy",q4n="org.eclipse.elk.compaction.orthogonal",G4n="org.eclipse.elk.overlapRemoval.maxIterations",z4n="org.eclipse.elk.overlapRemoval.runScanline",U4n="processingOrder",X4n="overlapRemoval",W4n="org.eclipse.elk.sporeOverlap",V4n="org.eclipse.elk.alg.spore.p1structure",Q4n="org.eclipse.elk.alg.spore.p2processingorder",J4n="org.eclipse.elk.alg.spore.p3execution",Y4n="Invalid index: ",Z4n="org.eclipse.elk.core.alg",n5n={331:1},t5n={288:1},e5n="Make sure its type is registered with the ",i5n=" utility class.",r5n="true",c5n="false",a5n="Couldn't clone property '",u5n=.05,o5n="org.eclipse.elk.core.options",s5n=1.2999999523162842,h5n="org.eclipse.elk.box",f5n="org.eclipse.elk.box.packingMode",l5n="org.eclipse.elk.algorithm",b5n="org.eclipse.elk.resolvedAlgorithm",w5n="org.eclipse.elk.bendPoints",d5n="org.eclipse.elk.labelManager",g5n="org.eclipse.elk.scaleFactor",p5n="org.eclipse.elk.animate",v5n="org.eclipse.elk.animTimeFactor",m5n="org.eclipse.elk.layoutAncestors",y5n="org.eclipse.elk.maxAnimTime",k5n="org.eclipse.elk.minAnimTime",j5n="org.eclipse.elk.progressBar",E5n="org.eclipse.elk.validateGraph",T5n="org.eclipse.elk.validateOptions",M5n="org.eclipse.elk.zoomToFit",S5n="org.eclipse.elk.font.name",P5n="org.eclipse.elk.font.size",I5n="org.eclipse.elk.edge.type",C5n="partitioning",O5n="nodeLabels",A5n="portAlignment",$5n="nodeSize",L5n="port",N5n="portLabels",x5n="insideSelfLoops",D5n="org.eclipse.elk.fixed",R5n="org.eclipse.elk.random",K5n="port must have a parent node to calculate the port side",_5n="The edge needs to have exactly one edge section. Found: ",F5n="org.eclipse.elk.core.util.adapters",B5n="org.eclipse.emf.ecore",H5n="org.eclipse.elk.graph",q5n="EMapPropertyHolder",G5n="ElkBendPoint",z5n="ElkGraphElement",U5n="ElkConnectableShape",X5n="ElkEdge",W5n="ElkEdgeSection",V5n="EModelElement",Q5n="ENamedElement",J5n="ElkLabel",Y5n="ElkNode",Z5n="ElkPort",n6n={92:1,90:1},t6n="org.eclipse.emf.common.notify.impl",e6n="The feature '",i6n="' is not a valid changeable feature",r6n="Expecting null",c6n="' is not a valid feature",a6n="The feature ID",u6n=" is not a valid feature ID",o6n=32768,s6n={105:1,92:1,90:1,56:1,49:1,97:1},h6n="org.eclipse.emf.ecore.impl",f6n="org.eclipse.elk.graph.impl",l6n="Recursive containment not allowed for ",b6n="The datatype '",w6n="' is not a valid classifier",d6n="The value '",g6n={190:1,3:1,4:1},p6n="The class '",v6n="http://www.eclipse.org/elk/ElkGraph",m6n=1024,y6n="property",k6n="value",j6n="source",E6n="properties",T6n="identifier",M6n="height",S6n="width",P6n="parent",I6n="text",C6n="children",O6n="hierarchical",A6n="sources",$6n="targets",L6n="sections",N6n="bendPoints",x6n="outgoingShape",D6n="incomingShape",R6n="outgoingSections",K6n="incomingSections",_6n="org.eclipse.emf.common.util",F6n="Severe implementation error in the Json to ElkGraph importer.",B6n="id",H6n="org.eclipse.elk.graph.json",q6n="Unhandled parameter types: ",G6n="startPoint",z6n="An edge must have at least one source and one target (edge id: '",U6n="').",X6n="Referenced edge section does not exist: ",W6n=" (edge id: '",V6n="target",Q6n="sourcePoint",J6n="targetPoint",Y6n="group",Z6n="name",n8n="connectableShape cannot be null",t8n="edge cannot be null",e8n="Passed edge is not 'simple'.",i8n="org.eclipse.elk.graph.util",r8n="The 'no duplicates' constraint is violated",c8n="targetIndex=",a8n=", size=",u8n="sourceIndex=",o8n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1},s8n={3:1,4:1,20:1,28:1,52:1,14:1,47:1,15:1,54:1,67:1,63:1,58:1,588:1},h8n="logging",f8n="measureExecutionTime",l8n="parser.parse.1",b8n="parser.parse.2",w8n="parser.next.1",d8n="parser.next.2",g8n="parser.next.3",p8n="parser.next.4",v8n="parser.factor.1",m8n="parser.factor.2",y8n="parser.factor.3",k8n="parser.factor.4",j8n="parser.factor.5",E8n="parser.factor.6",T8n="parser.atom.1",M8n="parser.atom.2",S8n="parser.atom.3",P8n="parser.atom.4",I8n="parser.atom.5",C8n="parser.cc.1",O8n="parser.cc.2",A8n="parser.cc.3",$8n="parser.cc.5",L8n="parser.cc.6",N8n="parser.cc.7",x8n="parser.cc.8",D8n="parser.ope.1",R8n="parser.ope.2",K8n="parser.ope.3",_8n="parser.descape.1",F8n="parser.descape.2",B8n="parser.descape.3",H8n="parser.descape.4",q8n="parser.descape.5",G8n="parser.process.1",z8n="parser.quantifier.1",U8n="parser.quantifier.2",X8n="parser.quantifier.3",W8n="parser.quantifier.4",V8n="parser.quantifier.5",Q8n="org.eclipse.emf.common.notify",J8n={415:1,672:1},Y8n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1},Z8n={366:1,143:1},n9n="index=",t9n={3:1,4:1,5:1,126:1},e9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,58:1},i9n={3:1,6:1,4:1,5:1,192:1},r9n={3:1,4:1,5:1,165:1,367:1},c9n=";/?:@&=+$,",a9n="invalid authority: ",u9n="EAnnotation",o9n="ETypedElement",s9n="EStructuralFeature",h9n="EAttribute",f9n="EClassifier",l9n="EEnumLiteral",b9n="EGenericType",w9n="EOperation",d9n="EParameter",g9n="EReference",p9n="ETypeParameter",v9n="org.eclipse.emf.ecore.util",m9n={76:1},y9n={3:1,20:1,14:1,15:1,58:1,589:1,76:1,69:1,95:1},k9n="org.eclipse.emf.ecore.util.FeatureMap$Entry",j9n=8192,E9n=2048,T9n="byte",M9n="char",S9n="double",P9n="float",I9n="int",C9n="long",O9n="short",A9n="java.lang.Object",$9n={3:1,4:1,5:1,247:1},L9n={3:1,4:1,5:1,673:1},N9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,69:1},x9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,76:1,69:1,95:1},D9n="mixed",R9n="http:///org/eclipse/emf/ecore/util/ExtendedMetaData",K9n="kind",_9n={3:1,4:1,5:1,674:1},F9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1,76:1,69:1,95:1},B9n={20:1,28:1,52:1,14:1,15:1,58:1,69:1},H9n={47:1,125:1,279:1},q9n={72:1,332:1},G9n="The value of type '",z9n="' must be of type '",U9n=1316,X9n="http://www.eclipse.org/emf/2002/Ecore",W9n=-32768,V9n="constraints",Q9n="baseType",J9n="getEStructuralFeature",Y9n="getFeatureID",Z9n="feature",n7n="getOperationID",t7n="operation",e7n="defaultValue",i7n="eTypeParameters",r7n="isInstance",c7n="getEEnumLiteral",a7n="eContainingClass",u7n={55:1},o7n={3:1,4:1,5:1,119:1},s7n="org.eclipse.emf.ecore.resource",h7n={92:1,90:1,591:1,1935:1},f7n="org.eclipse.emf.ecore.resource.impl",l7n="unspecified",b7n="simple",w7n="attribute",d7n="attributeWildcard",g7n="element",p7n="elementWildcard",v7n="collapse",m7n="itemType",y7n="namespace",k7n="##targetNamespace",j7n="whiteSpace",E7n="wildcards",T7n="http://www.eclipse.org/emf/2003/XMLType",M7n="##any",S7n="uninitialized",P7n="The multiplicity constraint is violated",I7n="org.eclipse.emf.ecore.xml.type",C7n="ProcessingInstruction",O7n="SimpleAnyType",A7n="XMLTypeDocumentRoot",$7n="org.eclipse.emf.ecore.xml.type.impl",L7n="INF",N7n="processing",x7n="ENTITIES_._base",D7n="minLength",R7n="ENTITY",K7n="NCName",_7n="IDREFS_._base",F7n="integer",B7n="token",H7n="pattern",q7n="[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*",G7n="\\i\\c*",z7n="[\\i-[:]][\\c-[:]]*",U7n="nonPositiveInteger",X7n="maxInclusive",W7n="NMTOKEN",V7n="NMTOKENS_._base",Q7n="nonNegativeInteger",J7n="minInclusive",Y7n="normalizedString",Z7n="unsignedByte",nnt="unsignedInt",tnt="18446744073709551615",ent="unsignedShort",int="processingInstruction",rnt="org.eclipse.emf.ecore.xml.type.internal",cnt=1114111,ant="Internal Error: shorthands: \\u",unt="xml:isDigit",ont="xml:isWord",snt="xml:isSpace",hnt="xml:isNameChar",fnt="xml:isInitialNameChar",lnt="09٠٩۰۹०९০৯੦੯૦૯୦୯௧௯౦౯೦೯൦൯๐๙໐໙༠༩",bnt="AZazÀÖØöøıĴľŁňŊžƀǃǍǰǴǵǺȗɐʨʻˁΆΆΈΊΌΌΎΡΣώϐϖϚϚϜϜϞϞϠϠϢϳЁЌЎяёќўҁҐӄӇӈӋӌӐӫӮӵӸӹԱՖՙՙաֆאתװײءغفيٱڷںھۀێېۓەەۥۦअहऽऽक़ॡঅঌএঐওনপরললশহড়ঢ়য়ৡৰৱਅਊਏਐਓਨਪਰਲਲ਼ਵਸ਼ਸਹਖ਼ੜਫ਼ਫ਼ੲੴઅઋઍઍએઑઓનપરલળવહઽઽૠૠଅଌଏଐଓନପରଲଳଶହଽଽଡ଼ଢ଼ୟୡஅஊஎஐஒகஙசஜஜஞடணதநபமவஷஹఅఌఎఐఒనపళవహౠౡಅಌಎಐಒನಪಳವಹೞೞೠೡഅഌഎഐഒനപഹൠൡกฮะะาำเๅກຂຄຄງຈຊຊຍຍດທນຟມຣລລວວສຫອຮະະາຳຽຽເໄཀཇཉཀྵႠჅაჶᄀᄀᄂᄃᄅᄇᄉᄉᄋᄌᄎᄒᄼᄼᄾᄾᅀᅀᅌᅌᅎᅎᅐᅐᅔᅕᅙᅙᅟᅡᅣᅣᅥᅥᅧᅧᅩᅩᅭᅮᅲᅳᅵᅵᆞᆞᆨᆨᆫᆫᆮᆯᆷᆸᆺᆺᆼᇂᇫᇫᇰᇰᇹᇹḀẛẠỹἀἕἘἝἠὅὈὍὐὗὙὙὛὛὝὝὟώᾀᾴᾶᾼιιῂῄῆῌῐΐῖΊῠῬῲῴῶῼΩΩKÅ℮℮ↀↂ〇〇〡〩ぁゔァヺㄅㄬ一龥가힣",wnt="Private Use",dnt="ASSIGNED",gnt="\0€ÿĀſƀɏɐʯʰ˿̀ͯͰϿЀӿ԰֏֐׿؀ۿ܀ݏހ޿ऀॿঀ৿਀੿઀૿଀୿஀௿ఀ౿ಀ೿ഀൿ඀෿฀๿຀໿ༀ࿿က႟Ⴀჿᄀᇿሀ፿Ꭰ᏿᐀ᙿ ᚟ᚠ᛿ក៿᠀᢯Ḁỿἀ῿ ⁰₟₠⃏⃐⃿℀⅏⅐↏←⇿∀⋿⌀⏿␀␿⑀⑟①⓿─╿▀▟■◿☀⛿✀➿⠀⣿⺀⻿⼀⿟⿰⿿ 〿぀ゟ゠ヿ㄀ㄯ㄰㆏㆐㆟ㆠㆿ㈀㋿㌀㏿㐀䶵一鿿ꀀ꒏꒐꓏가힣豈﫿ffﭏﭐ﷿︠︯︰﹏﹐﹯ﹰ﻾\ufeff\ufeff＀￯",pnt="UNASSIGNED",vnt={3:1,117:1},mnt="org.eclipse.emf.ecore.xml.type.util",ynt={3:1,4:1,5:1,368:1},knt="org.eclipse.xtext.xbase.lib",jnt="Cannot add elements to a Range",Ent="Cannot set elements in a Range",Tnt="Cannot remove elements from a Range",Mnt="locale",Snt="default",Pnt="user.agent";i.goog=i.goog||{},i.goog.global=i.goog.global||i,UMn(),lAn(1,null,{},r),EWn.Fb=function(n){return KO(this,n)},EWn.Gb=function(){return this.gm},EWn.Hb=function(){return MN(this)},EWn.Ib=function(){return Yj(Zon(this))+"@"+(Yon(this)>>>0).toString(16)},EWn.equals=function(n){return this.Fb(n)},EWn.hashCode=function(){return this.Hb()},EWn.toString=function(){return this.Ib()},lAn(290,1,{290:1,2026:1},don),EWn.le=function(n){var t;return(t=new don).i=4,t.c=n>1?wZ(this,n-1):this,t},EWn.me=function(){return kD(this),this.b},EWn.ne=function(){return Yj(this)},EWn.oe=function(){return kD(this),this.k},EWn.pe=function(){return 0!=(4&this.i)},EWn.qe=function(){return 0!=(1&this.i)},EWn.Ib=function(){return ctn(this)},EWn.i=0;var Int,Cnt=gX(xWn,"Object",1),Ont=gX(xWn,"Class",290);lAn(1998,1,DWn),gX(RWn,"Optional",1998),lAn(1170,1998,DWn,c),EWn.Fb=function(n){return n===this},EWn.Hb=function(){return 2040732332},EWn.Ib=function(){return"Optional.absent()"},EWn.Jb=function(n){return vX(n),ty(),Int},gX(RWn,"Absent",1170),lAn(628,1,{},pk),gX(RWn,"Joiner",628);var Ant=fq(RWn,"Predicate");lAn(582,1,{169:1,582:1,3:1,45:1},Ff),EWn.Mb=function(n){return Don(this,n)},EWn.Lb=function(n){return Don(this,n)},EWn.Fb=function(n){var t;return!!iL(n,582)&&(t=_B(n,582),$An(this.a,t.a))},EWn.Hb=function(){return Kon(this.a)+306654252},EWn.Ib=function(){return lPn(this.a)},gX(RWn,"Predicates/AndPredicate",582),lAn(408,1998,{408:1,3:1},Bf),EWn.Fb=function(n){var t;return!!iL(n,408)&&(t=_B(n,408),$fn(this.a,t.a))},EWn.Hb=function(){return 1502476572+Yon(this.a)},EWn.Ib=function(){return HWn+this.a+")"},EWn.Jb=function(n){return new Bf(UQ(n.Kb(this.a),"the Function passed to Optional.transform() must not return null."))},gX(RWn,"Present",408),lAn(198,1,GWn),EWn.Nb=function(n){sU(this,n)},EWn.Qb=function(){fk()},gX(zWn,"UnmodifiableIterator",198),lAn(1978,198,UWn),EWn.Qb=function(){fk()},EWn.Rb=function(n){throw Fp(new dv)},EWn.Wb=function(n){throw Fp(new dv)},gX(zWn,"UnmodifiableListIterator",1978),lAn(386,1978,UWn),EWn.Ob=function(){return this.c0},EWn.Pb=function(){if(this.c>=this.d)throw Fp(new vv);return this.Xb(this.c++)},EWn.Tb=function(){return this.c},EWn.Ub=function(){if(this.c<=0)throw Fp(new vv);return this.Xb(--this.c)},EWn.Vb=function(){return this.c-1},EWn.c=0,EWn.d=0,gX(zWn,"AbstractIndexedListIterator",386),lAn(699,198,GWn),EWn.Ob=function(){return Jin(this)},EWn.Pb=function(){return M7(this)},EWn.e=1,gX(zWn,"AbstractIterator",699),lAn(1986,1,{224:1}),EWn.Zb=function(){return this.f||(this.f=this.ac())},EWn.Fb=function(n){return ysn(this,n)},EWn.Hb=function(){return Yon(this.Zb())},EWn.dc=function(){return 0==this.gc()},EWn.ec=function(){return wz(this)},EWn.Ib=function(){return _bn(this.Zb())},gX(zWn,"AbstractMultimap",1986),lAn(726,1986,XWn),EWn.$b=function(){lin(this)},EWn._b=function(n){return Uj(this,n)},EWn.ac=function(){return new dT(this,this.c)},EWn.ic=function(n){return this.hc()},EWn.bc=function(){return new FL(this,this.c)},EWn.jc=function(){return this.mc(this.hc())},EWn.kc=function(){return new Fm(this)},EWn.lc=function(){return BTn(this.c.vc().Nc(),new u,64,this.d)},EWn.cc=function(n){return o6(this,n)},EWn.fc=function(n){return $hn(this,n)},EWn.gc=function(){return this.d},EWn.mc=function(n){return TQ(),new Fb(n)},EWn.nc=function(){return new _m(this)},EWn.oc=function(){return BTn(this.c.Cc().Nc(),new a,64,this.d)},EWn.pc=function(n,t){return new U6(this,n,t,null)},EWn.d=0,gX(zWn,"AbstractMapBasedMultimap",726),lAn(1631,726,XWn),EWn.hc=function(){return new Q6(this.a)},EWn.jc=function(){return TQ(),TQ(),uet},EWn.cc=function(n){return _B(o6(this,n),15)},EWn.fc=function(n){return _B($hn(this,n),15)},EWn.Zb=function(){return IQ(this)},EWn.Fb=function(n){return ysn(this,n)},EWn.qc=function(n){return _B(o6(this,n),15)},EWn.rc=function(n){return _B($hn(this,n),15)},EWn.mc=function(n){return eJ(_B(n,15))},EWn.pc=function(n,t){return t3(this,n,_B(t,15),null)},gX(zWn,"AbstractListMultimap",1631),lAn(732,1,WWn),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return this.c.Ob()||this.e.Ob()},EWn.Pb=function(){var n;return this.e.Ob()||(n=_B(this.c.Pb(),42),this.b=n.cd(),this.a=_B(n.dd(),14),this.e=this.a.Kc()),this.sc(this.b,this.e.Pb())},EWn.Qb=function(){this.e.Qb(),this.a.dc()&&this.c.Qb(),--this.d.d},gX(zWn,"AbstractMapBasedMultimap/Itr",732),lAn(1099,732,WWn,_m),EWn.sc=function(n,t){return t},gX(zWn,"AbstractMapBasedMultimap/1",1099),lAn(1100,1,{},a),EWn.Kb=function(n){return _B(n,14).Nc()},gX(zWn,"AbstractMapBasedMultimap/1methodref$spliterator$Type",1100),lAn(1101,732,WWn,Fm),EWn.sc=function(n,t){return new gT(n,t)},gX(zWn,"AbstractMapBasedMultimap/2",1101);var $nt=fq(VWn,"Map");lAn(1967,1,QWn),EWn.wc=function(n){Ycn(this,n)},EWn.yc=function(n,t,e){return Jln(this,n,t,e)},EWn.$b=function(){this.vc().$b()},EWn.tc=function(n){return Emn(this,n)},EWn._b=function(n){return!!KEn(this,n,!1)},EWn.uc=function(n){var t,e;for(t=this.vc().Kc();t.Ob();)if(e=_B(t.Pb(),42).dd(),HC(n)===HC(e)||null!=n&&$fn(n,e))return!0;return!1},EWn.Fb=function(n){var t,e,i;if(n===this)return!0;if(!iL(n,83))return!1;if(i=_B(n,83),this.gc()!=i.gc())return!1;for(e=i.vc().Kc();e.Ob();)if(t=_B(e.Pb(),42),!this.tc(t))return!1;return!0},EWn.xc=function(n){return BC(KEn(this,n,!1))},EWn.Hb=function(){return Fun(this.vc())},EWn.dc=function(){return 0==this.gc()},EWn.ec=function(){return new Sb(this)},EWn.zc=function(n,t){throw Fp(new Zy("Put not supported on this map"))},EWn.Ac=function(n){jcn(this,n)},EWn.Bc=function(n){return BC(KEn(this,n,!0))},EWn.gc=function(){return this.vc().gc()},EWn.Ib=function(){return YEn(this)},EWn.Cc=function(){return new Ib(this)},gX(VWn,"AbstractMap",1967),lAn(1987,1967,QWn),EWn.bc=function(){return new TT(this)},EWn.vc=function(){return bz(this)},EWn.ec=function(){return this.g||(this.g=this.bc())},EWn.Cc=function(){return this.i||(this.i=new MT(this))},gX(zWn,"Maps/ViewCachingAbstractMap",1987),lAn(389,1987,QWn,dT),EWn.xc=function(n){return mtn(this,n)},EWn.Bc=function(n){return Jsn(this,n)},EWn.$b=function(){this.d==this.e.c?this.e.$b():Sq(new Iq(this))},EWn._b=function(n){return wfn(this.d,n)},EWn.Ec=function(){return new zf(this)},EWn.Dc=function(){return this.Ec()},EWn.Fb=function(n){return this===n||$fn(this.d,n)},EWn.Hb=function(){return Yon(this.d)},EWn.ec=function(){return this.e.ec()},EWn.gc=function(){return this.d.gc()},EWn.Ib=function(){return _bn(this.d)},gX(zWn,"AbstractMapBasedMultimap/AsMap",389);var Lnt=fq(xWn,"Iterable");lAn(28,1,JWn),EWn.Jc=function(n){n5(this,n)},EWn.Lc=function(){return this.Oc()},EWn.Nc=function(){return new l1(this,0)},EWn.Oc=function(){return new xq(null,this.Nc())},EWn.Fc=function(n){throw Fp(new Zy("Add not supported on this collection"))},EWn.Gc=function(n){return Krn(this,n)},EWn.$b=function(){jV(this)},EWn.Hc=function(n){return vwn(this,n,!1)},EWn.Ic=function(n){return aun(this,n)},EWn.dc=function(){return 0==this.gc()},EWn.Mc=function(n){return vwn(this,n,!0)},EWn.Pc=function(){return iz(this)},EWn.Qc=function(n){return kmn(this,n)},EWn.Ib=function(){return AMn(this)},gX(VWn,"AbstractCollection",28);var Nnt=fq(VWn,"Set");lAn(YWn,28,ZWn),EWn.Nc=function(){return new l1(this,1)},EWn.Fb=function(n){return tgn(this,n)},EWn.Hb=function(){return Fun(this)},gX(VWn,"AbstractSet",YWn),lAn(1970,YWn,ZWn),gX(zWn,"Sets/ImprovedAbstractSet",1970),lAn(1971,1970,ZWn),EWn.$b=function(){this.Rc().$b()},EWn.Hc=function(n){return tdn(this,n)},EWn.dc=function(){return this.Rc().dc()},EWn.Mc=function(n){var t;return!!this.Hc(n)&&(t=_B(n,42),this.Rc().ec().Mc(t.cd()))},EWn.gc=function(){return this.Rc().gc()},gX(zWn,"Maps/EntrySet",1971),lAn(1097,1971,ZWn,zf),EWn.Hc=function(n){return lfn(this.a.d.vc(),n)},EWn.Kc=function(){return new Iq(this.a)},EWn.Rc=function(){return this.a},EWn.Mc=function(n){var t;return!!lfn(this.a.d.vc(),n)&&(t=_B(n,42),F5(this.a.e,t.cd()),!0)},EWn.Nc=function(){return xB(this.a.d.vc().Nc(),new Uf(this.a))},gX(zWn,"AbstractMapBasedMultimap/AsMap/AsMapEntries",1097),lAn(1098,1,{},Uf),EWn.Kb=function(n){return t5(this.a,_B(n,42))},gX(zWn,"AbstractMapBasedMultimap/AsMap/AsMapEntries/0methodref$wrapEntry$Type",1098),lAn(730,1,WWn,Iq),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){var n;return n=_B(this.b.Pb(),42),this.a=_B(n.dd(),14),t5(this.c,n)},EWn.Ob=function(){return this.b.Ob()},EWn.Qb=function(){oan(!!this.a),this.b.Qb(),this.c.e.d-=this.a.gc(),this.a.$b(),this.a=null},gX(zWn,"AbstractMapBasedMultimap/AsMap/AsMapIterator",730),lAn(532,1970,ZWn,TT),EWn.$b=function(){this.b.$b()},EWn.Hc=function(n){return this.b._b(n)},EWn.Jc=function(n){vX(n),this.b.wc(new gl(n))},EWn.dc=function(){return this.b.dc()},EWn.Kc=function(){return new hy(this.b.vc().Kc())},EWn.Mc=function(n){return!!this.b._b(n)&&(this.b.Bc(n),!0)},EWn.gc=function(){return this.b.gc()},gX(zWn,"Maps/KeySet",532),lAn(318,532,ZWn,FL),EWn.$b=function(){Sq(new nT(this,this.b.vc().Kc()))},EWn.Ic=function(n){return this.b.ec().Ic(n)},EWn.Fb=function(n){return this===n||$fn(this.b.ec(),n)},EWn.Hb=function(){return Yon(this.b.ec())},EWn.Kc=function(){return new nT(this,this.b.vc().Kc())},EWn.Mc=function(n){var t,e;return e=0,(t=_B(this.b.Bc(n),14))&&(e=t.gc(),t.$b(),this.a.d-=e),e>0},EWn.Nc=function(){return this.b.ec().Nc()},gX(zWn,"AbstractMapBasedMultimap/KeySet",318),lAn(731,1,WWn,nT),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return this.c.Ob()},EWn.Pb=function(){return this.a=_B(this.c.Pb(),42),this.a.cd()},EWn.Qb=function(){var n;oan(!!this.a),n=_B(this.a.dd(),14),this.c.Qb(),this.b.a.d-=n.gc(),n.$b(),this.a=null},gX(zWn,"AbstractMapBasedMultimap/KeySet/1",731),lAn(491,389,{83:1,161:1},SD),EWn.bc=function(){return this.Sc()},EWn.ec=function(){return this.Tc()},EWn.Sc=function(){return new YE(this.c,this.Uc())},EWn.Tc=function(){return this.b||(this.b=this.Sc())},EWn.Uc=function(){return _B(this.d,161)},gX(zWn,"AbstractMapBasedMultimap/SortedAsMap",491),lAn(542,491,nVn,PD),EWn.bc=function(){return new ZE(this.a,_B(_B(this.d,161),171))},EWn.Sc=function(){return new ZE(this.a,_B(_B(this.d,161),171))},EWn.ec=function(){return _B(this.b||(this.b=new ZE(this.a,_B(_B(this.d,161),171))),271)},EWn.Tc=function(){return _B(this.b||(this.b=new ZE(this.a,_B(_B(this.d,161),171))),271)},EWn.Uc=function(){return _B(_B(this.d,161),171)},gX(zWn,"AbstractMapBasedMultimap/NavigableAsMap",542),lAn(490,318,tVn,YE),EWn.Nc=function(){return this.b.ec().Nc()},gX(zWn,"AbstractMapBasedMultimap/SortedKeySet",490),lAn(388,490,eVn,ZE),gX(zWn,"AbstractMapBasedMultimap/NavigableKeySet",388),lAn(541,28,JWn,U6),EWn.Fc=function(n){var t,e;return qbn(this),e=this.d.dc(),(t=this.d.Fc(n))&&(++this.f.d,e&&yR(this)),t},EWn.Gc=function(n){var t,e,i;return!n.dc()&&(qbn(this),i=this.d.gc(),(t=this.d.Gc(n))&&(e=this.d.gc(),this.f.d+=e-i,0==i&&yR(this)),t)},EWn.$b=function(){var n;qbn(this),0!=(n=this.d.gc())&&(this.d.$b(),this.f.d-=n,OG(this))},EWn.Hc=function(n){return qbn(this),this.d.Hc(n)},EWn.Ic=function(n){return qbn(this),this.d.Ic(n)},EWn.Fb=function(n){return n===this||(qbn(this),$fn(this.d,n))},EWn.Hb=function(){return qbn(this),Yon(this.d)},EWn.Kc=function(){return qbn(this),new WB(this)},EWn.Mc=function(n){var t;return qbn(this),(t=this.d.Mc(n))&&(--this.f.d,OG(this)),t},EWn.gc=function(){return ZC(this)},EWn.Nc=function(){return qbn(this),this.d.Nc()},EWn.Ib=function(){return qbn(this),_bn(this.d)},gX(zWn,"AbstractMapBasedMultimap/WrappedCollection",541);var xnt=fq(VWn,"List");lAn(728,541,{20:1,28:1,14:1,15:1},uz),EWn.ad=function(n){Rrn(this,n)},EWn.Nc=function(){return qbn(this),this.d.Nc()},EWn.Vc=function(n,t){var e;qbn(this),e=this.d.dc(),_B(this.d,15).Vc(n,t),++this.a.d,e&&yR(this)},EWn.Wc=function(n,t){var e,i,r;return!t.dc()&&(qbn(this),r=this.d.gc(),(e=_B(this.d,15).Wc(n,t))&&(i=this.d.gc(),this.a.d+=i-r,0==r&&yR(this)),e)},EWn.Xb=function(n){return qbn(this),_B(this.d,15).Xb(n)},EWn.Xc=function(n){return qbn(this),_B(this.d,15).Xc(n)},EWn.Yc=function(){return qbn(this),new w$(this)},EWn.Zc=function(n){return qbn(this),new wQ(this,n)},EWn.$c=function(n){var t;return qbn(this),t=_B(this.d,15).$c(n),--this.a.d,OG(this),t},EWn._c=function(n,t){return qbn(this),_B(this.d,15)._c(n,t)},EWn.bd=function(n,t){return qbn(this),t3(this.a,this.e,_B(this.d,15).bd(n,t),this.b?this.b:this)},gX(zWn,"AbstractMapBasedMultimap/WrappedList",728),lAn(1096,728,{20:1,28:1,14:1,15:1,54:1},Ix),gX(zWn,"AbstractMapBasedMultimap/RandomAccessWrappedList",1096),lAn(620,1,WWn,WB),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return EV(this),this.b.Ob()},EWn.Pb=function(){return EV(this),this.b.Pb()},EWn.Qb=function(){nN(this)},gX(zWn,"AbstractMapBasedMultimap/WrappedCollection/WrappedIterator",620),lAn(729,620,iVn,w$,wQ),EWn.Qb=function(){nN(this)},EWn.Rb=function(n){var t;t=0==ZC(this.a),(EV(this),_B(this.b,125)).Rb(n),++this.a.a.d,t&&yR(this.a)},EWn.Sb=function(){return(EV(this),_B(this.b,125)).Sb()},EWn.Tb=function(){return(EV(this),_B(this.b,125)).Tb()},EWn.Ub=function(){return(EV(this),_B(this.b,125)).Ub()},EWn.Vb=function(){return(EV(this),_B(this.b,125)).Vb()},EWn.Wb=function(n){(EV(this),_B(this.b,125)).Wb(n)},gX(zWn,"AbstractMapBasedMultimap/WrappedList/WrappedListIterator",729),lAn(727,541,tVn,$D),EWn.Nc=function(){return qbn(this),this.d.Nc()},gX(zWn,"AbstractMapBasedMultimap/WrappedSortedSet",727),lAn(1095,727,eVn,CA),gX(zWn,"AbstractMapBasedMultimap/WrappedNavigableSet",1095),lAn(1094,541,ZWn,LD),EWn.Nc=function(){return qbn(this),this.d.Nc()},gX(zWn,"AbstractMapBasedMultimap/WrappedSet",1094),lAn(1103,1,{},u),EWn.Kb=function(n){return K6(_B(n,42))},gX(zWn,"AbstractMapBasedMultimap/lambda$1$Type",1103),lAn(1102,1,{},Xf),EWn.Kb=function(n){return new gT(this.a,n)},gX(zWn,"AbstractMapBasedMultimap/lambda$2$Type",1102);var Dnt,Rnt,Knt,_nt,Fnt=fq(VWn,"Map/Entry");lAn(345,1,rVn),EWn.Fb=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),lW(this.cd(),t.cd())&&lW(this.dd(),t.dd()))},EWn.Hb=function(){var n,t;return n=this.cd(),t=this.dd(),(null==n?0:Yon(n))^(null==t?0:Yon(t))},EWn.ed=function(n){throw Fp(new dv)},EWn.Ib=function(){return this.cd()+"="+this.dd()},gX(zWn,cVn,345),lAn(1988,28,JWn),EWn.$b=function(){this.fd().$b()},EWn.Hc=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),F0(this.fd(),t.cd(),t.dd()))},EWn.Mc=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),B0(this.fd(),t.cd(),t.dd()))},EWn.gc=function(){return this.fd().d},gX(zWn,"Multimaps/Entries",1988),lAn(733,1988,JWn,Wf),EWn.Kc=function(){return this.a.kc()},EWn.fd=function(){return this.a},EWn.Nc=function(){return this.a.lc()},gX(zWn,"AbstractMultimap/Entries",733),lAn(734,733,ZWn,Bm),EWn.Nc=function(){return this.a.lc()},EWn.Fb=function(n){return qSn(this,n)},EWn.Hb=function(){return _rn(this)},gX(zWn,"AbstractMultimap/EntrySet",734),lAn(735,28,JWn,Vf),EWn.$b=function(){this.a.$b()},EWn.Hc=function(n){return Psn(this.a,n)},EWn.Kc=function(){return this.a.nc()},EWn.gc=function(){return this.a.d},EWn.Nc=function(){return this.a.oc()},gX(zWn,"AbstractMultimap/Values",735),lAn(1989,28,{835:1,20:1,28:1,14:1}),EWn.Jc=function(n){vX(n),kV(this).Jc(new dl(n))},EWn.Nc=function(){var n;return BTn(n=kV(this).Nc(),new y,64|1296&n.qd(),this.a.d)},EWn.Fc=function(n){return lk(),!0},EWn.Gc=function(n){return vX(this),vX(n),iL(n,543)?h2(_B(n,835)):!n.dc()&&snn(this,n.Kc())},EWn.Hc=function(n){var t;return((t=_B(hfn(IQ(this.a),n),14))?t.gc():0)>0},EWn.Fb=function(n){return o$n(this,n)},EWn.Hb=function(){return Yon(kV(this))},EWn.dc=function(){return kV(this).dc()},EWn.Mc=function(n){return kCn(this,n,1)>0},EWn.Ib=function(){return _bn(kV(this))},gX(zWn,"AbstractMultiset",1989),lAn(1991,1970,ZWn),EWn.$b=function(){lin(this.a.a)},EWn.Hc=function(n){var t;return!(!iL(n,492)||(t=_B(n,416),_B(t.a.dd(),14).gc()<=0||i1(this.a,t.a.cd())!=_B(t.a.dd(),14).gc()))},EWn.Mc=function(n){var t,e,i;return!(!iL(n,492)||(t=(e=_B(n,416)).a.cd(),0==(i=_B(e.a.dd(),14).gc())))&&jCn(this.a,t,i)},gX(zWn,"Multisets/EntrySet",1991),lAn(1109,1991,ZWn,Qf),EWn.Kc=function(){return new ly(bz(IQ(this.a.a)).Kc())},EWn.gc=function(){return IQ(this.a.a).gc()},gX(zWn,"AbstractMultiset/EntrySet",1109),lAn(619,726,XWn),EWn.hc=function(){return this.gd()},EWn.jc=function(){return this.hd()},EWn.cc=function(n){return this.jd(n)},EWn.fc=function(n){return this.kd(n)},EWn.Zb=function(){return this.f||(this.f=this.ac())},EWn.hd=function(){return TQ(),TQ(),set},EWn.Fb=function(n){return ysn(this,n)},EWn.jd=function(n){return _B(o6(this,n),21)},EWn.kd=function(n){return _B($hn(this,n),21)},EWn.mc=function(n){return TQ(),new Ck(_B(n,21))},EWn.pc=function(n,t){return new LD(this,n,_B(t,21))},gX(zWn,"AbstractSetMultimap",619),lAn(1657,619,XWn),EWn.hc=function(){return new bE(this.b)},EWn.gd=function(){return new bE(this.b)},EWn.jc=function(){return PX(new bE(this.b))},EWn.hd=function(){return PX(new bE(this.b))},EWn.cc=function(n){return _B(_B(o6(this,n),21),84)},EWn.jd=function(n){return _B(_B(o6(this,n),21),84)},EWn.fc=function(n){return _B(_B($hn(this,n),21),84)},EWn.kd=function(n){return _B(_B($hn(this,n),21),84)},EWn.mc=function(n){return iL(n,271)?PX(_B(n,271)):(TQ(),new bN(_B(n,84)))},EWn.Zb=function(){return this.f||(this.f=iL(this.c,171)?new PD(this,_B(this.c,171)):iL(this.c,161)?new SD(this,_B(this.c,161)):new dT(this,this.c))},EWn.pc=function(n,t){return iL(t,271)?new CA(this,n,_B(t,271)):new $D(this,n,_B(t,84))},gX(zWn,"AbstractSortedSetMultimap",1657),lAn(1658,1657,XWn),EWn.Zb=function(){return _B(_B(this.f||(this.f=iL(this.c,171)?new PD(this,_B(this.c,171)):iL(this.c,161)?new SD(this,_B(this.c,161)):new dT(this,this.c)),161),171)},EWn.ec=function(){return _B(_B(this.i||(this.i=iL(this.c,171)?new ZE(this,_B(this.c,171)):iL(this.c,161)?new YE(this,_B(this.c,161)):new FL(this,this.c)),84),271)},EWn.bc=function(){return iL(this.c,171)?new ZE(this,_B(this.c,171)):iL(this.c,161)?new YE(this,_B(this.c,161)):new FL(this,this.c)},gX(zWn,"AbstractSortedKeySortedSetMultimap",1658),lAn(2010,1,{1947:1}),EWn.Fb=function(n){return Sjn(this,n)},EWn.Hb=function(){return Fun(this.g||(this.g=new Jf(this)))},EWn.Ib=function(){return YEn(this.f||(this.f=new GL(this)))},gX(zWn,"AbstractTable",2010),lAn(665,YWn,ZWn,Jf),EWn.$b=function(){bk()},EWn.Hc=function(n){var t,e;return!!iL(n,468)&&(t=_B(n,682),!!(e=_B(hfn(yX(this.a),UC(t.c.e,t.b)),83))&&lfn(e.vc(),new gT(UC(t.c.c,t.a),G6(t.c,t.b,t.a))))},EWn.Kc=function(){return JQ(this.a)},EWn.Mc=function(n){var t,e;return!!iL(n,468)&&(t=_B(n,682),!!(e=_B(hfn(yX(this.a),UC(t.c.e,t.b)),83))&&bfn(e.vc(),new gT(UC(t.c.c,t.a),G6(t.c,t.b,t.a))))},EWn.gc=function(){return qq(this.a)},EWn.Nc=function(){return M2(this.a)},gX(zWn,"AbstractTable/CellSet",665),lAn(1928,28,JWn,Yf),EWn.$b=function(){bk()},EWn.Hc=function(n){return oTn(this.a,n)},EWn.Kc=function(){return YQ(this.a)},EWn.gc=function(){return qq(this.a)},EWn.Nc=function(){return V0(this.a)},gX(zWn,"AbstractTable/Values",1928),lAn(1632,1631,XWn),gX(zWn,"ArrayListMultimapGwtSerializationDependencies",1632),lAn(513,1632,XWn,ak,a1),EWn.hc=function(){return new Q6(this.a)},EWn.a=0,gX(zWn,"ArrayListMultimap",513),lAn(664,2010,{664:1,1947:1,3:1},gOn),gX(zWn,"ArrayTable",664),lAn(1924,386,UWn,BL),EWn.Xb=function(n){return new won(this.a,n)},gX(zWn,"ArrayTable/1",1924),lAn(1925,1,{},Hf),EWn.ld=function(n){return new won(this.a,n)},gX(zWn,"ArrayTable/1methodref$getCell$Type",1925),lAn(2011,1,{682:1}),EWn.Fb=function(n){var t;return n===this||!!iL(n,468)&&(t=_B(n,682),lW(UC(this.c.e,this.b),UC(t.c.e,t.b))&&lW(UC(this.c.c,this.a),UC(t.c.c,t.a))&&lW(G6(this.c,this.b,this.a),G6(t.c,t.b,t.a)))},EWn.Hb=function(){return shn(Mun(Hk(Cnt,1),FWn,1,5,[UC(this.c.e,this.b),UC(this.c.c,this.a),G6(this.c,this.b,this.a)]))},EWn.Ib=function(){return"("+UC(this.c.e,this.b)+","+UC(this.c.c,this.a)+")="+G6(this.c,this.b,this.a)},gX(zWn,"Tables/AbstractCell",2011),lAn(468,2011,{468:1,682:1},won),EWn.a=0,EWn.b=0,EWn.d=0,gX(zWn,"ArrayTable/2",468),lAn(1927,1,{},qf),EWn.ld=function(n){return V9(this.a,n)},gX(zWn,"ArrayTable/2methodref$getValue$Type",1927),lAn(1926,386,UWn,HL),EWn.Xb=function(n){return V9(this.a,n)},gX(zWn,"ArrayTable/3",1926),lAn(1979,1967,QWn),EWn.$b=function(){Sq(this.kc())},EWn.vc=function(){return new pl(this)},EWn.lc=function(){return new SV(this.kc(),this.gc())},gX(zWn,"Maps/IteratorBasedAbstractMap",1979),lAn(828,1979,QWn),EWn.$b=function(){throw Fp(new dv)},EWn._b=function(n){return Vj(this.c,n)},EWn.kc=function(){return new qL(this,this.c.b.c.gc())},EWn.lc=function(){return vq(this.c.b.c.gc(),16,new Gf(this))},EWn.xc=function(n){var t;return(t=_B(GK(this.c,n),19))?this.nd(t.a):null},EWn.dc=function(){return this.c.b.c.dc()},EWn.ec=function(){return fz(this.c)},EWn.zc=function(n,t){var e;if(!(e=_B(GK(this.c,n),19)))throw Fp(new Ry(this.md()+" "+n+" not in "+fz(this.c)));return this.od(e.a,t)},EWn.Bc=function(n){throw Fp(new dv)},EWn.gc=function(){return this.c.b.c.gc()},gX(zWn,"ArrayTable/ArrayMap",828),lAn(1923,1,{},Gf),EWn.ld=function(n){return IX(this.a,n)},gX(zWn,"ArrayTable/ArrayMap/0methodref$getEntry$Type",1923),lAn(1921,345,rVn,uT),EWn.cd=function(){return VL(this.a,this.b)},EWn.dd=function(){return this.a.nd(this.b)},EWn.ed=function(n){return this.a.od(this.b,n)},EWn.b=0,gX(zWn,"ArrayTable/ArrayMap/1",1921),lAn(1922,386,UWn,qL),EWn.Xb=function(n){return IX(this.a,n)},gX(zWn,"ArrayTable/ArrayMap/2",1922),lAn(1920,828,QWn,iU),EWn.md=function(){return"Column"},EWn.nd=function(n){return G6(this.b,this.a,n)},EWn.od=function(n,t){return Tun(this.b,this.a,n,t)},EWn.a=0,gX(zWn,"ArrayTable/Row",1920),lAn(829,828,QWn,GL),EWn.nd=function(n){return new iU(this.a,n)},EWn.zc=function(n,t){return _B(t,83),wk()},EWn.od=function(n,t){return _B(t,83),dk()},EWn.md=function(){return"Row"},gX(zWn,"ArrayTable/RowMap",829),lAn(1120,1,sVn,oT),EWn.qd=function(){return-262&this.a.qd()},EWn.rd=function(){return this.a.rd()},EWn.Nb=function(n){this.a.Nb(new iT(n,this.b))},EWn.sd=function(n){return this.a.sd(new eT(n,this.b))},gX(zWn,"CollectSpliterators/1",1120),lAn(1121,1,hVn,eT),EWn.td=function(n){this.a.td(this.b.Kb(n))},gX(zWn,"CollectSpliterators/1/lambda$0$Type",1121),lAn(1122,1,hVn,iT),EWn.td=function(n){this.a.td(this.b.Kb(n))},gX(zWn,"CollectSpliterators/1/lambda$1$Type",1122),lAn(1123,1,sVn,B2),EWn.qd=function(){return this.a},EWn.rd=function(){return this.d&&(this.b=j$(this.b,this.d.rd())),j$(this.b,0)},EWn.Nb=function(n){this.d&&(this.d.Nb(n),this.d=null),this.c.Nb(new tT(this.e,n)),this.b=0},EWn.sd=function(n){for(;;){if(this.d&&this.d.sd(n))return QC(this.b,fVn)&&(this.b=tbn(this.b,1)),!0;if(this.d=null,!this.c.sd(new rT(this,this.e)))return!1}},EWn.a=0,EWn.b=0,gX(zWn,"CollectSpliterators/1FlatMapSpliterator",1123),lAn(1124,1,hVn,rT),EWn.td=function(n){bK(this.a,this.b,n)},gX(zWn,"CollectSpliterators/1FlatMapSpliterator/lambda$0$Type",1124),lAn(1125,1,hVn,tT),EWn.td=function(n){aL(this.b,this.a,n)},gX(zWn,"CollectSpliterators/1FlatMapSpliterator/lambda$1$Type",1125),lAn(1117,1,sVn,lK),EWn.qd=function(){return 16464|this.b},EWn.rd=function(){return this.a.rd()},EWn.Nb=function(n){this.a.xe(new aT(n,this.c))},EWn.sd=function(n){return this.a.ye(new cT(n,this.c))},EWn.b=0,gX(zWn,"CollectSpliterators/1WithCharacteristics",1117),lAn(1118,1,lVn,cT),EWn.ud=function(n){this.a.td(this.b.ld(n))},gX(zWn,"CollectSpliterators/1WithCharacteristics/lambda$0$Type",1118),lAn(1119,1,lVn,aT),EWn.ud=function(n){this.a.td(this.b.ld(n))},gX(zWn,"CollectSpliterators/1WithCharacteristics/lambda$1$Type",1119),lAn(245,1,bVn),EWn.wd=function(n){return this.vd(_B(n,245))},EWn.vd=function(n){var t;return n==(Zm(),Rnt)?1:n==(ny(),Dnt)?-1:(YH(),0!=(t=$cn(this.a,n.a))?t:iL(this,519)==iL(n,519)?0:iL(this,519)?1:-1)},EWn.zd=function(){return this.a},EWn.Fb=function(n){return Ldn(this,n)},gX(zWn,"Cut",245),lAn(1761,245,bVn,$k),EWn.vd=function(n){return n==this?0:1},EWn.xd=function(n){throw Fp(new ov)},EWn.yd=function(n){n.a+="+∞)"},EWn.zd=function(){throw Fp(new Ky(wVn))},EWn.Hb=function(){return OT(),nvn(this)},EWn.Ad=function(n){return!1},EWn.Ib=function(){return"+∞"},gX(zWn,"Cut/AboveAll",1761),lAn(519,245,{245:1,519:1,3:1,35:1},tN),EWn.xd=function(n){cO((n.a+="(",n),this.a)},EWn.yd=function(n){LX(cO(n,this.a),93)},EWn.Hb=function(){return~Yon(this.a)},EWn.Ad=function(n){return YH(),$cn(this.a,n)<0},EWn.Ib=function(){return"/"+this.a+"\\"},gX(zWn,"Cut/AboveValue",519),lAn(1760,245,bVn,Lk),EWn.vd=function(n){return n==this?0:-1},EWn.xd=function(n){n.a+="(-∞"},EWn.yd=function(n){throw Fp(new ov)},EWn.zd=function(){throw Fp(new Ky(wVn))},EWn.Hb=function(){return OT(),nvn(this)},EWn.Ad=function(n){return!0},EWn.Ib=function(){return"-∞"},gX(zWn,"Cut/BelowAll",1760),lAn(1762,245,bVn,eN),EWn.xd=function(n){cO((n.a+="[",n),this.a)},EWn.yd=function(n){LX(cO(n,this.a),41)},EWn.Hb=function(){return Yon(this.a)},EWn.Ad=function(n){return YH(),$cn(this.a,n)<=0},EWn.Ib=function(){return"\\"+this.a+"/"},gX(zWn,"Cut/BelowValue",1762),lAn(537,1,dVn),EWn.Jc=function(n){n5(this,n)},EWn.Ib=function(){return Fln(_B(UQ(this,"use Optional.orNull() instead of Optional.or(null)"),20).Kc())},gX(zWn,"FluentIterable",537),lAn(433,537,dVn,IO),EWn.Kc=function(){return new az(JL(this.a.Kc(),new h))},gX(zWn,"FluentIterable/2",433),lAn(1046,537,dVn,CO),EWn.Kc=function(){return $U(this)},gX(zWn,"FluentIterable/3",1046),lAn(708,386,UWn,UL),EWn.Xb=function(n){return this.a[n].Kc()},gX(zWn,"FluentIterable/3/1",708),lAn(1972,1,{}),EWn.Ib=function(){return _bn(this.Bd().b)},gX(zWn,"ForwardingObject",1972),lAn(1973,1972,gVn),EWn.Bd=function(){return this.Cd()},EWn.Jc=function(n){n5(this,n)},EWn.Lc=function(){return this.Oc()},EWn.Nc=function(){return new l1(this,0)},EWn.Oc=function(){return new xq(null,this.Nc())},EWn.Fc=function(n){return this.Cd(),aE()},EWn.Gc=function(n){return this.Cd(),uE()},EWn.$b=function(){this.Cd(),oE()},EWn.Hc=function(n){return this.Cd().Hc(n)},EWn.Ic=function(n){return this.Cd().Ic(n)},EWn.dc=function(){return this.Cd().b.dc()},EWn.Kc=function(){return this.Cd().Kc()},EWn.Mc=function(n){return this.Cd(),sE()},EWn.gc=function(){return this.Cd().b.gc()},EWn.Pc=function(){return this.Cd().Pc()},EWn.Qc=function(n){return this.Cd().Qc(n)},gX(zWn,"ForwardingCollection",1973),lAn(1980,28,pVn),EWn.Kc=function(){return this.Ed()},EWn.Fc=function(n){throw Fp(new dv)},EWn.Gc=function(n){throw Fp(new dv)},EWn.$b=function(){throw Fp(new dv)},EWn.Hc=function(n){return null!=n&&vwn(this,n,!1)},EWn.Dd=function(){switch(this.gc()){case 0:return UX(),UX(),Knt;case 1:return UX(),new Mq(vX(this.Ed().Pb()));default:return new rU(this,this.Pc())}},EWn.Mc=function(n){throw Fp(new dv)},gX(zWn,"ImmutableCollection",1980),lAn(712,1980,pVn,ev),EWn.Kc=function(){return A9(this.a.Kc())},EWn.Hc=function(n){return null!=n&&this.a.Hc(n)},EWn.Ic=function(n){return this.a.Ic(n)},EWn.dc=function(){return this.a.dc()},EWn.Ed=function(){return A9(this.a.Kc())},EWn.gc=function(){return this.a.gc()},EWn.Pc=function(){return this.a.Pc()},EWn.Qc=function(n){return this.a.Qc(n)},EWn.Ib=function(){return _bn(this.a)},gX(zWn,"ForwardingImmutableCollection",712),lAn(152,1980,vVn),EWn.Kc=function(){return this.Ed()},EWn.Yc=function(){return this.Fd(0)},EWn.Zc=function(n){return this.Fd(n)},EWn.ad=function(n){Rrn(this,n)},EWn.Nc=function(){return new l1(this,16)},EWn.bd=function(n,t){return this.Gd(n,t)},EWn.Vc=function(n,t){throw Fp(new dv)},EWn.Wc=function(n,t){throw Fp(new dv)},EWn.Fb=function(n){return BAn(this,n)},EWn.Hb=function(){return Pan(this)},EWn.Xc=function(n){return null==n?-1:jmn(this,n)},EWn.Ed=function(){return this.Fd(0)},EWn.Fd=function(n){return tx(this,n)},EWn.$c=function(n){throw Fp(new dv)},EWn._c=function(n,t){throw Fp(new dv)},EWn.Gd=function(n,t){return ufn(new u1(new PT(this),n,t))},gX(zWn,"ImmutableList",152),lAn(2006,152,vVn),EWn.Kc=function(){return A9(this.Hd().Kc())},EWn.bd=function(n,t){return ufn(this.Hd().bd(n,t))},EWn.Hc=function(n){return null!=n&&this.Hd().Hc(n)},EWn.Ic=function(n){return this.Hd().Ic(n)},EWn.Fb=function(n){return $fn(this.Hd(),n)},EWn.Xb=function(n){return UC(this,n)},EWn.Hb=function(){return Yon(this.Hd())},EWn.Xc=function(n){return this.Hd().Xc(n)},EWn.dc=function(){return this.Hd().dc()},EWn.Ed=function(){return A9(this.Hd().Kc())},EWn.gc=function(){return this.Hd().gc()},EWn.Gd=function(n,t){return ufn(this.Hd().bd(n,t))},EWn.Pc=function(){return this.Hd().Qc(L8(Cnt,FWn,1,this.Hd().gc(),5,1))},EWn.Qc=function(n){return this.Hd().Qc(n)},EWn.Ib=function(){return _bn(this.Hd())},gX(zWn,"ForwardingImmutableList",2006),lAn(714,1,yVn),EWn.vc=function(){return hz(this)},EWn.wc=function(n){Ycn(this,n)},EWn.ec=function(){return fz(this)},EWn.yc=function(n,t,e){return Jln(this,n,t,e)},EWn.Cc=function(){return this.Ld()},EWn.$b=function(){throw Fp(new dv)},EWn._b=function(n){return null!=this.xc(n)},EWn.uc=function(n){return this.Ld().Hc(n)},EWn.Jd=function(){return new iv(this)},EWn.Kd=function(){return new rv(this)},EWn.Fb=function(n){return Osn(this,n)},EWn.Hb=function(){return hz(this).Hb()},EWn.dc=function(){return 0==this.gc()},EWn.zc=function(n,t){return gk()},EWn.Bc=function(n){throw Fp(new dv)},EWn.Ib=function(){return sSn(this)},EWn.Ld=function(){return this.e?this.e:this.e=this.Kd()},EWn.c=null,EWn.d=null,EWn.e=null,gX(zWn,"ImmutableMap",714),lAn(715,714,yVn),EWn._b=function(n){return Vj(this,n)},EWn.uc=function(n){return RT(this.b,n)},EWn.Id=function(){return ofn(new nl(this))},EWn.Jd=function(){return ofn(tV(this.b))},EWn.Kd=function(){return u_(),new ev(ZW(this.b))},EWn.Fb=function(n){return _T(this.b,n)},EWn.xc=function(n){return GK(this,n)},EWn.Hb=function(){return Yon(this.b.c)},EWn.dc=function(){return this.b.c.dc()},EWn.gc=function(){return this.b.c.gc()},EWn.Ib=function(){return _bn(this.b.c)},gX(zWn,"ForwardingImmutableMap",715),lAn(1974,1973,kVn),EWn.Bd=function(){return this.Md()},EWn.Cd=function(){return this.Md()},EWn.Nc=function(){return new l1(this,1)},EWn.Fb=function(n){return n===this||this.Md().Fb(n)},EWn.Hb=function(){return this.Md().Hb()},gX(zWn,"ForwardingSet",1974),lAn(1069,1974,kVn,nl),EWn.Bd=function(){return nV(this.a.b)},EWn.Cd=function(){return nV(this.a.b)},EWn.Hc=function(n){if(iL(n,42)&&null==_B(n,42).cd())return!1;try{return DT(nV(this.a.b),n)}catch(t){if(iL(t=hun(t),205))return!1;throw Fp(t)}},EWn.Md=function(){return nV(this.a.b)},EWn.Qc=function(n){var t;return t=PJ(nV(this.a.b),n),nV(this.a.b).b.gc()=0?"+":"")+(e/60|0),t=GO(i.Math.abs(e)%60),(dMn(),det)[this.q.getDay()]+" "+get[this.q.getMonth()]+" "+GO(this.q.getDate())+" "+GO(this.q.getHours())+":"+GO(this.q.getMinutes())+":"+GO(this.q.getSeconds())+" GMT"+n+t+" "+this.q.getFullYear()};var att,utt,ott,stt,htt,ftt,ltt,btt,wtt,dtt,gtt,ptt=gX(VWn,"Date",199);lAn(1915,199,jQn,Vkn),EWn.a=!1,EWn.b=0,EWn.c=0,EWn.d=0,EWn.e=0,EWn.f=0,EWn.g=!1,EWn.i=0,EWn.j=0,EWn.k=0,EWn.n=0,EWn.o=0,EWn.p=0,gX("com.google.gwt.i18n.shared.impl","DateRecord",1915),lAn(1966,1,{}),EWn.fe=function(){return null},EWn.ge=function(){return null},EWn.he=function(){return null},EWn.ie=function(){return null},EWn.je=function(){return null},gX(EQn,"JSONValue",1966),lAn(216,1966,{216:1},Sl,jl),EWn.Fb=function(n){return!!iL(n,216)&&g0(this.a,_B(n,216).a)},EWn.ee=function(){return Bp},EWn.Hb=function(){return ZQ(this.a)},EWn.fe=function(){return this},EWn.Ib=function(){var n,t,e;for(e=new hN("["),t=0,n=this.a.length;t0&&(e.a+=","),cO(e,bnn(this,t));return e.a+="]",e.a},gX(EQn,"JSONArray",216),lAn(483,1966,{483:1},El),EWn.ee=function(){return Hp},EWn.ge=function(){return this},EWn.Ib=function(){return oN(),""+this.a},EWn.a=!1,gX(EQn,"JSONBoolean",483),lAn(985,60,_Vn,wy),gX(EQn,"JSONException",985),lAn(1023,1966,{},v),EWn.ee=function(){return Xp},EWn.Ib=function(){return qWn},gX(EQn,"JSONNull",1023),lAn(258,1966,{258:1},Tl),EWn.Fb=function(n){return!!iL(n,258)&&this.a==_B(n,258).a},EWn.ee=function(){return qp},EWn.Hb=function(){return XO(this.a)},EWn.he=function(){return this},EWn.Ib=function(){return this.a+""},EWn.a=0,gX(EQn,"JSONNumber",258),lAn(183,1966,{183:1},dy,Ml),EWn.Fb=function(n){return!!iL(n,183)&&g0(this.a,_B(n,183).a)},EWn.ee=function(){return Gp},EWn.Hb=function(){return ZQ(this.a)},EWn.ie=function(){return this},EWn.Ib=function(){var n,t,e,i,r,c;for(c=new hN("{"),n=!0,i=0,r=(e=yrn(this,L8(Wtt,uVn,2,0,6,1))).length;i=0?":"+this.c:"")+")"},EWn.c=0;var Ktt=gX(xWn,"StackTraceElement",310);IWn={3:1,475:1,35:1,2:1};var _tt,Ftt,Btt,Htt,qtt,Gtt,ztt,Utt,Xtt,Wtt=gX(xWn,BVn,2);lAn(107,418,{475:1},Tk,Mk,sN),gX(xWn,"StringBuffer",107),lAn(100,418,{475:1},Sk,Pk,hN),gX(xWn,"StringBuilder",100),lAn(687,73,$Qn,Ik),gX(xWn,"StringIndexOutOfBoundsException",687),lAn(2043,1,{}),lAn(844,1,{},x),EWn.Kb=function(n){return _B(n,78).e},gX(xWn,"Throwable/lambda$0$Type",844),lAn(41,60,{3:1,102:1,60:1,78:1,41:1},dv,Zy),gX(xWn,"UnsupportedOperationException",41),lAn(240,236,{3:1,35:1,236:1,240:1},mnn,lE),EWn.wd=function(n){return Q_n(this,_B(n,240))},EWn.ke=function(){return fSn(nqn(this))},EWn.Fb=function(n){var t;return this===n||!!iL(n,240)&&(t=_B(n,240),this.e==t.e&&0==Q_n(this,t))},EWn.Hb=function(){var n;return 0!=this.b?this.b:this.a<54?(n=san(this.f),this.b=bG(n0(n,-1)),this.b=33*this.b+bG(n0(mz(n,32),-1)),this.b=17*this.b+SY(this.e),this.b):(this.b=17*Dhn(this.c)+SY(this.e),this.b)},EWn.Ib=function(){return nqn(this)},EWn.a=0,EWn.b=0,EWn.d=0,EWn.e=0,EWn.f=0;var Vtt,Qtt,Jtt,Ytt,Ztt,net,tet=gX("java.math","BigDecimal",240);lAn(91,236,{3:1,35:1,236:1,91:1},xpn,z6,hU,gEn,Sgn,OA),EWn.wd=function(n){return Zdn(this,_B(n,91))},EWn.ke=function(){return fSn(BXn(this,0))},EWn.Fb=function(n){return uwn(this,n)},EWn.Hb=function(){return Dhn(this)},EWn.Ib=function(){return BXn(this,0)},EWn.b=-2,EWn.c=0,EWn.d=0,EWn.e=0;var eet,iet,ret,cet,aet=gX("java.math","BigInteger",91);lAn(488,1967,QWn),EWn.$b=function(){OU(this)},EWn._b=function(n){return oU(this,n)},EWn.uc=function(n){return Asn(this,n,this.g)||Asn(this,n,this.f)},EWn.vc=function(){return new Mb(this)},EWn.xc=function(n){return xX(this,n)},EWn.zc=function(n,t){return XW(this,n,t)},EWn.Bc=function(n){return g6(this,n)},EWn.gc=function(){return $T(this)},gX(VWn,"AbstractHashMap",488),lAn(261,YWn,ZWn,Mb),EWn.$b=function(){this.a.$b()},EWn.Hc=function(n){return p2(this,n)},EWn.Kc=function(){return new csn(this.a)},EWn.Mc=function(n){var t;return!!p2(this,n)&&(t=_B(n,42).cd(),this.a.Bc(t),!0)},EWn.gc=function(){return this.a.gc()},gX(VWn,"AbstractHashMap/EntrySet",261),lAn(262,1,WWn,csn),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return Ztn(this)},EWn.Ob=function(){return this.b},EWn.Qb=function(){a9(this)},EWn.b=!1,gX(VWn,"AbstractHashMap/EntrySetIterator",262),lAn(417,1,WWn,Tb),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return rS(this)},EWn.Pb=function(){return pQ(this)},EWn.Qb=function(){sW(this)},EWn.b=0,EWn.c=-1,gX(VWn,"AbstractList/IteratorImpl",417),lAn(96,417,iVn,E2),EWn.Qb=function(){sW(this)},EWn.Rb=function(n){vR(this,n)},EWn.Sb=function(){return this.b>0},EWn.Tb=function(){return this.b},EWn.Ub=function(){return Mx(this.b>0),this.a.Xb(this.c=--this.b)},EWn.Vb=function(){return this.b-1},EWn.Wb=function(n){Ex(-1!=this.c),this.a._c(this.c,n)},gX(VWn,"AbstractList/ListIteratorImpl",96),lAn(219,52,AVn,u1),EWn.Vc=function(n,t){AZ(n,this.b),this.c.Vc(this.a+n,t),++this.b},EWn.Xb=function(n){return h1(n,this.b),this.c.Xb(this.a+n)},EWn.$c=function(n){var t;return h1(n,this.b),t=this.c.$c(this.a+n),--this.b,t},EWn._c=function(n,t){return h1(n,this.b),this.c._c(this.a+n,t)},EWn.gc=function(){return this.b},EWn.a=0,EWn.b=0,gX(VWn,"AbstractList/SubList",219),lAn(384,YWn,ZWn,Sb),EWn.$b=function(){this.a.$b()},EWn.Hc=function(n){return this.a._b(n)},EWn.Kc=function(){return new Pb(this.a.vc().Kc())},EWn.Mc=function(n){return!!this.a._b(n)&&(this.a.Bc(n),!0)},EWn.gc=function(){return this.a.gc()},gX(VWn,"AbstractMap/1",384),lAn(691,1,WWn,Pb),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return this.a.Ob()},EWn.Pb=function(){return _B(this.a.Pb(),42).cd()},EWn.Qb=function(){this.a.Qb()},gX(VWn,"AbstractMap/1/1",691),lAn(226,28,JWn,Ib),EWn.$b=function(){this.a.$b()},EWn.Hc=function(n){return this.a.uc(n)},EWn.Kc=function(){return new Db(this.a.vc().Kc())},EWn.gc=function(){return this.a.gc()},gX(VWn,"AbstractMap/2",226),lAn(294,1,WWn,Db),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return this.a.Ob()},EWn.Pb=function(){return _B(this.a.Pb(),42).dd()},EWn.Qb=function(){this.a.Qb()},gX(VWn,"AbstractMap/2/1",294),lAn(484,1,{484:1,42:1}),EWn.Fb=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),iV(this.d,t.cd())&&iV(this.e,t.dd()))},EWn.cd=function(){return this.d},EWn.dd=function(){return this.e},EWn.Hb=function(){return DA(this.d)^DA(this.e)},EWn.ed=function(n){return dR(this,n)},EWn.Ib=function(){return this.d+"="+this.e},gX(VWn,"AbstractMap/AbstractEntry",484),lAn(383,484,{484:1,383:1,42:1},MS),gX(VWn,"AbstractMap/SimpleEntry",383),lAn(1984,1,XQn),EWn.Fb=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),iV(this.cd(),t.cd())&&iV(this.dd(),t.dd()))},EWn.Hb=function(){return DA(this.cd())^DA(this.dd())},EWn.Ib=function(){return this.cd()+"="+this.dd()},gX(VWn,cVn,1984),lAn(1992,1967,nVn),EWn.tc=function(n){return B5(this,n)},EWn._b=function(n){return NK(this,n)},EWn.vc=function(){return new _b(this)},EWn.xc=function(n){return BC(hsn(this,n))},EWn.ec=function(){return new Rb(this)},gX(VWn,"AbstractNavigableMap",1992),lAn(739,YWn,ZWn,_b),EWn.Hc=function(n){return iL(n,42)&&B5(this.b,_B(n,42))},EWn.Kc=function(){return new _R(this.b)},EWn.Mc=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),q8(this.b,t))},EWn.gc=function(){return this.b.c},gX(VWn,"AbstractNavigableMap/EntrySet",739),lAn(493,YWn,eVn,Rb),EWn.Nc=function(){return new lS(this)},EWn.$b=function(){py(this.a)},EWn.Hc=function(n){return NK(this.a,n)},EWn.Kc=function(){return new Kb(new _R(new LN(this.a).b))},EWn.Mc=function(n){return!!NK(this.a,n)&&(OY(this.a,n),!0)},EWn.gc=function(){return this.a.c},gX(VWn,"AbstractNavigableMap/NavigableKeySet",493),lAn(494,1,WWn,Kb),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return rS(this.a.a)},EWn.Pb=function(){return px(this.a).cd()},EWn.Qb=function(){n_(this.a)},gX(VWn,"AbstractNavigableMap/NavigableKeySet/1",494),lAn(2004,28,JWn),EWn.Fc=function(n){return K8(nMn(this,n)),!0},EWn.Gc=function(n){return mW(n),gH(n!=this,"Can't add a queue to itself"),Krn(this,n)},EWn.$b=function(){for(;null!=pnn(this););},gX(VWn,"AbstractQueue",2004),lAn(302,28,{4:1,20:1,28:1,14:1},Ap,b1),EWn.Fc=function(n){return l3(this,n),!0},EWn.$b=function(){a4(this)},EWn.Hc=function(n){return lun(new fV(this),n)},EWn.dc=function(){return Uy(this)},EWn.Kc=function(){return new fV(this)},EWn.Mc=function(n){return HY(new fV(this),n)},EWn.gc=function(){return this.c-this.b&this.a.length-1},EWn.Nc=function(){return new l1(this,272)},EWn.Qc=function(n){var t;return t=this.c-this.b&this.a.length-1,n.lengtht&&OX(n,t,null),n},EWn.b=0,EWn.c=0,gX(VWn,"ArrayDeque",302),lAn(446,1,WWn,fV),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return this.a!=this.b},EWn.Pb=function(){return Rhn(this)},EWn.Qb=function(){nin(this)},EWn.a=0,EWn.b=0,EWn.c=-1,gX(VWn,"ArrayDeque/IteratorImpl",446),lAn(12,52,WQn,$p,Q6,ZK),EWn.Vc=function(n,t){mG(this,n,t)},EWn.Fc=function(n){return UB(this,n)},EWn.Wc=function(n,t){return ahn(this,n,t)},EWn.Gc=function(n){return wun(this,n)},EWn.$b=function(){this.c=L8(Cnt,FWn,1,0,5,1)},EWn.Hc=function(n){return-1!=k7(this,n,0)},EWn.Jc=function(n){Itn(this,n)},EWn.Xb=function(n){return Lq(this,n)},EWn.Xc=function(n){return k7(this,n,0)},EWn.dc=function(){return 0==this.c.length},EWn.Kc=function(){return new Ub(this)},EWn.$c=function(n){return u6(this,n)},EWn.Mc=function(n){return v7(this,n)},EWn.Ud=function(n,t){o1(this,n,t)},EWn._c=function(n,t){return i5(this,n,t)},EWn.gc=function(){return this.c.length},EWn.ad=function(n){p$(this,n)},EWn.Pc=function(){return fx(this)},EWn.Qc=function(n){return Wgn(this,n)};var uet,oet,set,het,fet,bet,wet,det,get,pet=gX(VWn,"ArrayList",12);lAn(7,1,WWn,Ub),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return v$(this)},EWn.Pb=function(){return Y1(this)},EWn.Qb=function(){CU(this)},EWn.a=0,EWn.b=-1,gX(VWn,"ArrayList/1",7),lAn(2013,i.Function,{},T),EWn.te=function(n,t){return Mln(n,t)},lAn(154,52,VQn,Qy),EWn.Hc=function(n){return-1!=fin(this,n)},EWn.Jc=function(n){var t,e,i,r;for(mW(n),i=0,r=(e=this.a).length;i>>0).toString(16))},EWn.f=0,EWn.i=DQn;var uit,oit,sit,hit,fit=gX(SJn,"CNode",57);lAn(814,1,{},Uv),gX(SJn,"CNode/CNodeBuilder",814),lAn(1525,1,{},dn),EWn.Oe=function(n,t){return 0},EWn.Pe=function(n,t){return 0},gX(SJn,IJn,1525),lAn(1790,1,{},gn),EWn.Le=function(n){var t,e,r,c,a,u,o,s,h,f,l,b,w,d,g;for(h=xQn,r=new Ub(n.a.b);r.ae.d.c||e.d.c==r.d.c&&e.d.b0?n+this.n.d+this.n.a:0},EWn.Se=function(){var n,t,e,r,c;if(c=0,this.e)this.b?c=this.b.a:this.a[1][1]&&(c=this.a[1][1].Se());else if(this.g)c=Vbn(this,Ikn(this,null,!0));else for(Ntn(),e=0,r=(t=Mun(Hk(Xit,1),OVn,232,0,[Hit,qit,Git])).length;e0?c+this.n.b+this.n.c:0},EWn.Te=function(){var n,t,e,i,r;if(this.g)for(n=Ikn(this,null,!1),Ntn(),i=0,r=(e=Mun(Hk(Xit,1),OVn,232,0,[Hit,qit,Git])).length;i0&&(r[0]+=this.d,e-=r[0]),r[2]>0&&(r[2]+=this.d,e-=r[2]),this.c.a=i.Math.max(0,e),this.c.d=t.d+n.d+(this.c.a-e)/2,r[1]=i.Math.max(r[1],e),W5(this,qit,t.d+n.d+r[0]-(r[1]-e)/2,r)},EWn.b=null,EWn.d=0,EWn.e=!1,EWn.f=!1,EWn.g=!1;var Wit,Vit,Qit,Jit=0,Yit=0;gX(ZJn,"GridContainerCell",1473),lAn(461,22,{3:1,35:1,22:1,461:1},HS);var Zit,nrt=_en(ZJn,"HorizontalLabelAlignment",461,Gnt,p1,w_);lAn(306,212,{212:1,306:1},vY,ltn,DJ),EWn.Re=function(){return UH(this)},EWn.Se=function(){return XH(this)},EWn.a=0,EWn.c=!1;var trt,ert,irt,rrt=gX(ZJn,"LabelCell",306);lAn(244,326,{212:1,326:1,244:1},Pgn),EWn.Re=function(){return ECn(this)},EWn.Se=function(){return TCn(this)},EWn.Te=function(){RFn(this)},EWn.Ue=function(){HFn(this)},EWn.b=0,EWn.c=0,EWn.d=!1,gX(ZJn,"StripContainerCell",244),lAn(1626,1,NVn,En),EWn.Mb=function(n){return Wy(_B(n,212))},gX(ZJn,"StripContainerCell/lambda$0$Type",1626),lAn(1627,1,{},Tn),EWn.Fe=function(n){return _B(n,212).Se()},gX(ZJn,"StripContainerCell/lambda$1$Type",1627),lAn(1628,1,NVn,Mn),EWn.Mb=function(n){return Vy(_B(n,212))},gX(ZJn,"StripContainerCell/lambda$2$Type",1628),lAn(1629,1,{},Sn),EWn.Fe=function(n){return _B(n,212).Re()},gX(ZJn,"StripContainerCell/lambda$3$Type",1629),lAn(462,22,{3:1,35:1,22:1,462:1},qS);var crt,art,urt,ort,srt,hrt,frt,lrt,brt,wrt,drt,grt,prt,vrt,mrt,yrt,krt,jrt,Ert,Trt,Mrt,Srt,Prt,Irt=_en(ZJn,"VerticalLabelAlignment",462,Gnt,v1,d_);lAn(789,1,{},nUn),EWn.c=0,EWn.d=0,EWn.k=0,EWn.s=0,EWn.t=0,EWn.v=!1,EWn.w=0,EWn.D=!1,gX(uYn,"NodeContext",789),lAn(1471,1,EJn,Pn),EWn.ue=function(n,t){return VO(_B(n,61),_B(t,61))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(uYn,"NodeContext/0methodref$comparePortSides$Type",1471),lAn(1472,1,EJn,In),EWn.ue=function(n,t){return GTn(_B(n,111),_B(t,111))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(uYn,"NodeContext/1methodref$comparePortContexts$Type",1472),lAn(159,22,{3:1,35:1,22:1,159:1},acn);var Crt,Ort,Art,$rt,Lrt,Nrt,xrt,Drt=_en(uYn,"NodeLabelLocation",159,Gnt,Zgn,g_);lAn(111,1,{111:1},EOn),EWn.a=!1,gX(uYn,"PortContext",111),lAn(1476,1,hVn,Cn),EWn.td=function(n){SE(_B(n,306))},gX(hYn,fYn,1476),lAn(1477,1,NVn,On),EWn.Mb=function(n){return!!_B(n,111).c},gX(hYn,lYn,1477),lAn(1478,1,hVn,An),EWn.td=function(n){SE(_B(n,111).c)},gX(hYn,"LabelPlacer/lambda$2$Type",1478),lAn(1475,1,hVn,Ln),EWn.td=function(n){BD(),Vp(_B(n,111))},gX(hYn,"NodeLabelAndSizeUtilities/lambda$0$Type",1475),lAn(790,1,hVn,O_),EWn.td=function(n){xM(this.b,this.c,this.a,_B(n,181))},EWn.a=!1,EWn.c=!1,gX(hYn,"NodeLabelCellCreator/lambda$0$Type",790),lAn(1474,1,hVn,Sw),EWn.td=function(n){Pv(this.a,_B(n,181))},gX(hYn,"PortContextCreator/lambda$0$Type",1474),lAn(1829,1,{},Nn),gX(wYn,"GreedyRectangleStripOverlapRemover",1829),lAn(1830,1,EJn,$n),EWn.ue=function(n,t){return KN(_B(n,222),_B(t,222))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(wYn,"GreedyRectangleStripOverlapRemover/0methodref$compareByYCoordinate$Type",1830),lAn(1786,1,{},Jv),EWn.a=5,EWn.e=0,gX(wYn,"RectangleStripOverlapRemover",1786),lAn(1787,1,EJn,Dn),EWn.ue=function(n,t){return _N(_B(n,222),_B(t,222))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(wYn,"RectangleStripOverlapRemover/0methodref$compareLeftRectangleBorders$Type",1787),lAn(1789,1,EJn,Rn),EWn.ue=function(n,t){return QU(_B(n,222),_B(t,222))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(wYn,"RectangleStripOverlapRemover/1methodref$compareRightRectangleBorders$Type",1789),lAn(406,22,{3:1,35:1,22:1,406:1},GS);var Rrt,Krt,_rt,Frt,Brt,Hrt=_en(wYn,"RectangleStripOverlapRemover/OverlapRemovalDirection",406,Gnt,V2,p_);lAn(222,1,{222:1},LG),gX(wYn,"RectangleStripOverlapRemover/RectangleNode",222),lAn(1788,1,hVn,Pw),EWn.td=function(n){Smn(this.a,_B(n,222))},gX(wYn,"RectangleStripOverlapRemover/lambda$1$Type",1788),lAn(1304,1,EJn,Kn),EWn.ue=function(n,t){return qHn(_B(n,167),_B(t,167))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator",1304),lAn(1307,1,{},_n),EWn.Kb=function(n){return _B(n,324).a},gX(gYn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$0$Type",1307),lAn(1308,1,NVn,Fn),EWn.Mb=function(n){return _B(n,323).a},gX(gYn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$1$Type",1308),lAn(1309,1,NVn,Bn),EWn.Mb=function(n){return _B(n,323).a},gX(gYn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$2$Type",1309),lAn(1302,1,EJn,Hn),EWn.ue=function(n,t){return URn(_B(n,167),_B(t,167))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator",1302),lAn(1305,1,{},xn),EWn.Kb=function(n){return _B(n,324).a},gX(gYn,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator/lambda$0$Type",1305),lAn(767,1,EJn,qn),EWn.ue=function(n,t){return Gan(_B(n,167),_B(t,167))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/MinNumOfExtensionsComparator",767),lAn(1300,1,EJn,Gn),EWn.ue=function(n,t){return Win(_B(n,321),_B(t,321))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/MinPerimeterComparator",1300),lAn(1301,1,EJn,zn),EWn.ue=function(n,t){return rvn(_B(n,321),_B(t,321))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/MinPerimeterComparatorWithShape",1301),lAn(1303,1,EJn,Un),EWn.ue=function(n,t){return _Kn(_B(n,167),_B(t,167))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator",1303),lAn(1306,1,{},Xn),EWn.Kb=function(n){return _B(n,324).a},gX(gYn,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator/lambda$0$Type",1306),lAn(777,1,{},NS),EWn.Ce=function(n,t){return I2(this,_B(n,46),_B(t,167))},gX(gYn,"SuccessorCombination",777),lAn(644,1,{},Wn),EWn.Ce=function(n,t){var e;return zCn((e=_B(n,46),_B(t,167),e))},gX(gYn,"SuccessorJitter",644),lAn(643,1,{},Vn),EWn.Ce=function(n,t){var e;return fxn((e=_B(n,46),_B(t,167),e))},gX(gYn,"SuccessorLineByLine",643),lAn(568,1,{},Qn),EWn.Ce=function(n,t){var e;return s$n((e=_B(n,46),_B(t,167),e))},gX(gYn,"SuccessorManhattan",568),lAn(1356,1,{},Jn),EWn.Ce=function(n,t){var e;return yNn((e=_B(n,46),_B(t,167),e))},gX(gYn,"SuccessorMaxNormWindingInMathPosSense",1356),lAn(400,1,{},Iw),EWn.Ce=function(n,t){return _U(this,n,t)},EWn.c=!1,EWn.d=!1,EWn.e=!1,EWn.f=!1,gX(gYn,"SuccessorQuadrantsGeneric",400),lAn(1357,1,{},Yn),EWn.Kb=function(n){return _B(n,324).a},gX(gYn,"SuccessorQuadrantsGeneric/lambda$0$Type",1357),lAn(323,22,{3:1,35:1,22:1,323:1},RS),EWn.a=!1;var qrt,Grt=_en(kYn,jYn,323,Gnt,Y2,v_);lAn(1298,1,{}),EWn.Ib=function(){var n,t,e,i,r,c;for(e=" ",n=tln(0),r=0;r=0?"b"+n+"["+c5(this.a)+"]":"b["+c5(this.a)+"]":"b_"+MN(this)},gX(iZn,"FBendpoint",559),lAn(282,134,{3:1,282:1,94:1,134:1},PR),EWn.Ib=function(){return c5(this)},gX(iZn,"FEdge",282),lAn(231,134,{3:1,231:1,94:1,134:1},v6);var Sct,Pct,Ict,Cct,Oct,Act,$ct,Lct,Nct,xct,Dct=gX(iZn,"FGraph",231);lAn(447,357,{3:1,447:1,357:1,94:1,134:1},p4),EWn.Ib=function(){return null==this.b||0==this.b.length?"l["+c5(this.a)+"]":"l_"+this.b},gX(iZn,"FLabel",447),lAn(144,357,{3:1,144:1,357:1,94:1,134:1},BX),EWn.Ib=function(){return d0(this)},EWn.b=0,gX(iZn,"FNode",144),lAn(2003,1,{}),EWn.bf=function(n){uFn(this,n)},EWn.cf=function(){Bmn(this)},EWn.d=0,gX(cZn,"AbstractForceModel",2003),lAn(631,2003,{631:1},Aan),EWn.af=function(n,t){var e,r,c,a;return ZIn(this.f,n,t),c=zR(_$(t.d),n.d),a=i.Math.sqrt(c.a*c.a+c.b*c.b),r=i.Math.max(0,a-hW(n.e)/2-hW(t.e)/2),mL(c,((e=Bon(this.e,n,t))>0?-RU(r,this.c)*e:Lx(r,this.b)*_B(pMn(n,(sRn(),Jct)),19).a)/a),c},EWn.bf=function(n){uFn(this,n),this.a=_B(pMn(n,(sRn(),Bct)),19).a,this.c=Hy(ED(pMn(n,iat))),this.b=Hy(ED(pMn(n,Zct)))},EWn.df=function(n){return n0&&(a-=Ty(r,this.a)*e),mL(c,a*this.b/u),c},EWn.bf=function(n){var t,e,r,c,a,u,o;for(uFn(this,n),this.b=Hy(ED(pMn(n,(sRn(),rat)))),this.c=this.b/_B(pMn(n,Bct),19).a,r=n.e.c.length,a=0,c=0,o=new Ub(n.e);o.a0},EWn.a=0,EWn.b=0,EWn.c=0,gX(cZn,"FruchtermanReingoldModel",632),lAn(849,1,WJn,qh),EWn.Qe=function(n){Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,aZn),""),"Force Model"),"Determines the model for force calculation."),Ict),(MPn(),wMt)),Oat),Yln((epn(),oMt))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,uZn),""),"Iterations"),"The number of iterations on the force model."),tln(300)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,oZn),""),"Repulsive Power"),"Determines how many bend points are added to the edge; such bend points are regarded as repelling particles in the force model"),tln(0)),gMt),Ctt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,sZn),""),"FR Temperature"),"The temperature is used as a scaling factor for particle displacements."),hZn),bMt),Mtt),Yln(oMt)))),r2(n,sZn,aZn,Lct),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,fZn),""),"Eades Repulsion"),"Factor for repulsive forces in Eades' model."),5),bMt),Mtt),Yln(oMt)))),r2(n,fZn,aZn,Oct),dUn((new Gh,n))},gX(lZn,"ForceMetaDataProvider",849),lAn(424,22,{3:1,35:1,22:1,424:1},zS);var Rct,Kct,_ct,Fct,Bct,Hct,qct,Gct,zct,Uct,Xct,Wct,Vct,Qct,Jct,Yct,Zct,nat,tat,eat,iat,rat,cat,aat,uat,oat,sat,hat,fat,lat,bat,wat,dat,gat,pat,vat,mat,yat,kat,jat,Eat,Tat,Mat,Sat,Pat,Iat,Cat,Oat=_en(lZn,"ForceModelStrategy",424,Gnt,rY,k_);lAn(988,1,WJn,Gh),EWn.Qe=function(n){dUn(n)},gX(lZn,"ForceOptions",988),lAn(989,1,{},dt),EWn.$e=function(){return new Hv},EWn._e=function(n){},gX(lZn,"ForceOptions/ForceFactory",989),lAn(850,1,WJn,zh),EWn.Qe=function(n){Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,$Zn),""),"Fixed Position"),"Prevent that the node is moved by the layout algorithm."),(oN(),!1)),(MPn(),lMt)),mtt),Yln((epn(),uMt))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,LZn),""),"Desired Edge Length"),"Either specified for parent nodes or for individual edges, where the latter takes higher precedence."),100),bMt),Mtt),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[cMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,NZn),""),"Layout Dimension"),"Dimensions that are permitted to be altered during layout."),fat),wMt),Fat),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,xZn),""),"Stress Epsilon"),"Termination criterion for the iterative process."),hZn),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,DZn),""),"Iteration Limit"),"Maximum number of performed iterations. Takes higher precedence than 'epsilon'."),tln(NWn)),gMt),Ctt),Yln(oMt)))),GGn((new Uh,n))},gX(lZn,"StressMetaDataProvider",850),lAn(992,1,WJn,Uh),EWn.Qe=function(n){GGn(n)},gX(lZn,"StressOptions",992),lAn(993,1,{},gt),EWn.$e=function(){return new IR},EWn._e=function(n){},gX(lZn,"StressOptions/StressFactory",993),lAn(1128,209,$Yn,IR),EWn.Ze=function(n,t){var e,i,r,c;for(ITn(t,KZn,1),By(jD(JAn(n,(ekn(),mat))))?By(jD(JAn(n,Mat)))||yY(new jw((HM(),new Ny(n)))):gLn(new Hv,n,pcn(t,1)),i=son(n),c=(e=FFn(this.a,i)).Kc();c.Ob();)(r=_B(c.Pb(),231)).e.c.length<=1||(FHn(this.b,r),t$n(this.b),Itn(r.d,new pt));TUn(i=HUn(e)),FSn(t)},gX(FZn,"StressLayoutProvider",1128),lAn(1129,1,hVn,pt),EWn.td=function(n){RBn(_B(n,447))},gX(FZn,"StressLayoutProvider/lambda$0$Type",1129),lAn(990,1,{},jv),EWn.c=0,EWn.e=0,EWn.g=0,gX(FZn,"StressMajorization",990),lAn(379,22,{3:1,35:1,22:1,379:1},US);var Aat,$at,Lat,Nat,xat,Dat,Rat,Kat,_at,Fat=_en(FZn,"StressMajorization/Dimension",379,Gnt,y1,j_);lAn(991,1,EJn,Lw),EWn.ue=function(n,t){return TK(this.a,_B(n,144),_B(t,144))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(FZn,"StressMajorization/lambda$0$Type",991),lAn(1229,1,{},N0),gX(HZn,"ElkLayered",1229),lAn(1230,1,hVn,vt),EWn.td=function(n){xCn(_B(n,37))},gX(HZn,"ElkLayered/lambda$0$Type",1230),lAn(1231,1,hVn,Nw),EWn.td=function(n){MK(this.a,_B(n,37))},gX(HZn,"ElkLayered/lambda$1$Type",1231),lAn(1263,1,{},O$),gX(HZn,"GraphConfigurator",1263),lAn(759,1,hVn,xw),EWn.td=function(n){XMn(this.a,_B(n,10))},gX(HZn,"GraphConfigurator/lambda$0$Type",759),lAn(760,1,{},mt),EWn.Kb=function(n){return Zkn(),new xq(null,new l1(_B(n,29).a,16))},gX(HZn,"GraphConfigurator/lambda$1$Type",760),lAn(761,1,hVn,Dw),EWn.td=function(n){XMn(this.a,_B(n,10))},gX(HZn,"GraphConfigurator/lambda$2$Type",761),lAn(1127,209,$Yn,Gv),EWn.Ze=function(n,t){var e;e=TBn(new Zv,n),HC(JAn(n,(FXn(),ugt)))===HC((cfn(),dIt))?ewn(this.a,e,t):lOn(this.a,e,t),wUn(new Wh,e)},gX(HZn,"LayeredLayoutProvider",1127),lAn(356,22,{3:1,35:1,22:1,356:1},XS);var Bat,Hat,qat,Gat=_en(HZn,"LayeredPhases",356,Gnt,u5,E_);lAn(1651,1,{},gin),EWn.i=0,gX(qZn,"ComponentsToCGraphTransformer",1651),lAn(1652,1,{},yt),EWn.ef=function(n,t){return i.Math.min(null!=n.a?Hy(n.a):n.c.i,null!=t.a?Hy(t.a):t.c.i)},EWn.ff=function(n,t){return i.Math.min(null!=n.a?Hy(n.a):n.c.i,null!=t.a?Hy(t.a):t.c.i)},gX(qZn,"ComponentsToCGraphTransformer/1",1652),lAn(81,1,{81:1}),EWn.i=0,EWn.k=!0,EWn.o=DQn;var zat,Uat,Xat,Wat=gX(GZn,"CNode",81);lAn(460,81,{460:1,81:1},$N,Tgn),EWn.Ib=function(){return""},gX(qZn,"ComponentsToCGraphTransformer/CRectNode",460),lAn(1623,1,{},kt),gX(qZn,"OneDimensionalComponentsCompaction",1623),lAn(1624,1,{},jt),EWn.Kb=function(n){return LZ(_B(n,46))},EWn.Fb=function(n){return this===n},gX(qZn,"OneDimensionalComponentsCompaction/lambda$0$Type",1624),lAn(1625,1,{},Et),EWn.Kb=function(n){return kwn(_B(n,46))},EWn.Fb=function(n){return this===n},gX(qZn,"OneDimensionalComponentsCompaction/lambda$1$Type",1625),lAn(1654,1,{},_X),gX(GZn,"CGraph",1654),lAn(189,1,{189:1},Mgn),EWn.b=0,EWn.c=0,EWn.e=0,EWn.g=!0,EWn.i=DQn,gX(GZn,"CGroup",189),lAn(1653,1,{},Pt),EWn.ef=function(n,t){return i.Math.max(null!=n.a?Hy(n.a):n.c.i,null!=t.a?Hy(t.a):t.c.i)},EWn.ff=function(n,t){return i.Math.max(null!=n.a?Hy(n.a):n.c.i,null!=t.a?Hy(t.a):t.c.i)},gX(GZn,IJn,1653),lAn(1655,1,{},uOn),EWn.d=!1;var Vat=gX(GZn,LJn,1655);lAn(1656,1,{},It),EWn.Kb=function(n){return mM(),oN(),0!=_B(_B(n,46).a,81).d.e},EWn.Fb=function(n){return this===n},gX(GZn,NJn,1656),lAn(823,1,{},Tq),EWn.a=!1,EWn.b=!1,EWn.c=!1,EWn.d=!1,gX(GZn,xJn,823),lAn(1825,1,{},NG),gX(zZn,DJn,1825);var Qat=fq(UZn,MJn);lAn(1826,1,{369:1},hJ),EWn.Ke=function(n){Hxn(this,_B(n,466))},gX(zZn,RJn,1826),lAn(1827,1,EJn,Ct),EWn.ue=function(n,t){return aQ(_B(n,81),_B(t,81))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(zZn,KJn,1827),lAn(466,1,{466:1},sP),EWn.a=!1,gX(zZn,_Jn,466),lAn(1828,1,EJn,Ot),EWn.ue=function(n,t){return Ykn(_B(n,466),_B(t,466))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(zZn,FJn,1828),lAn(140,1,{140:1},bP,pH),EWn.Fb=function(n){var t;return null!=n&&tut==Zon(n)&&(t=_B(n,140),iV(this.c,t.c)&&iV(this.d,t.d))},EWn.Hb=function(){return shn(Mun(Hk(Cnt,1),FWn,1,5,[this.c,this.d]))},EWn.Ib=function(){return"("+this.c+KWn+this.d+(this.a?"cx":"")+this.b+")"},EWn.a=!0,EWn.c=0,EWn.d=0;var Jat,Yat,Zat,nut,tut=gX(UZn,"Point",140);lAn(405,22,{3:1,35:1,22:1,405:1},WS);var eut,iut,rut,cut,aut,uut,out,sut,hut,fut,lut,but=_en(UZn,"Point/Quadrant",405,Gnt,Z2,T_);lAn(1642,1,{},Xv),EWn.b=null,EWn.c=null,EWn.d=null,EWn.e=null,EWn.f=null,gX(UZn,"RectilinearConvexHull",1642),lAn(574,1,{369:1},jpn),EWn.Ke=function(n){R9(this,_B(n,140))},EWn.b=0,gX(UZn,"RectilinearConvexHull/MaximalElementsEventHandler",574),lAn(1644,1,EJn,Mt),EWn.ue=function(n,t){return NV(ED(n),ED(t))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/MaximalElementsEventHandler/lambda$0$Type",1644),lAn(1643,1,{369:1},stn),EWn.Ke=function(n){MNn(this,_B(n,140))},EWn.a=0,EWn.b=null,EWn.c=null,EWn.d=null,EWn.e=null,gX(UZn,"RectilinearConvexHull/RectangleEventHandler",1643),lAn(1645,1,EJn,St),EWn.ue=function(n,t){return c0(_B(n,140),_B(t,140))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/lambda$0$Type",1645),lAn(1646,1,EJn,Tt),EWn.ue=function(n,t){return a0(_B(n,140),_B(t,140))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/lambda$1$Type",1646),lAn(1647,1,EJn,At),EWn.ue=function(n,t){return o0(_B(n,140),_B(t,140))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/lambda$2$Type",1647),lAn(1648,1,EJn,$t),EWn.ue=function(n,t){return u0(_B(n,140),_B(t,140))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/lambda$3$Type",1648),lAn(1649,1,EJn,Lt),EWn.ue=function(n,t){return yMn(_B(n,140),_B(t,140))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/lambda$4$Type",1649),lAn(1650,1,{},IZ),gX(UZn,"Scanline",1650),lAn(2005,1,{}),gX(XZn,"AbstractGraphPlacer",2005),lAn(325,1,{325:1},zx),EWn.mf=function(n){return!!this.nf(n)&&(QCn(this.b,_B(pMn(n,(oWn(),zft)),21),n),!0)},EWn.nf=function(n){var t,e,i;for(t=_B(pMn(n,(oWn(),zft)),21),i=_B(o6(sut,t),21).Kc();i.Ob();)if(e=_B(i.Pb(),21),!_B(o6(this.b,e),15).dc())return!1;return!0},gX(XZn,"ComponentGroup",325),lAn(765,2005,{},Wv),EWn.of=function(n){var t;for(t=new Ub(this.a);t.ab&&(k=0,j+=l+c,l=0),JRn(u,k+(g=u.c).a,j+g.b),mO(g),e=i.Math.max(e,k+v.a),l=i.Math.max(l,v.b),k+=v.a+c;if(t.f.a=e,t.f.b=j+l,By(jD(pMn(a,Edt)))){for(DXn(r=new Nt,n,c),f=n.Kc();f.Ob();)GR(mO(_B(f.Pb(),37).c),r.e);GR(mO(t.f),r.a)}b9(t,n)}else(m=_B(n.Xb(0),37))!=t&&(t.a.c=L8(Cnt,FWn,1,0,5,1),OKn(t,m,0,0),Ban(t,m),mQ(t.d,m.d),t.f.a=m.f.a,t.f.b=m.f.b)},gX(XZn,"SimpleRowGraphPlacer",1291),lAn(1292,1,EJn,Rt),EWn.ue=function(n,t){return qan(_B(n,37),_B(t,37))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(XZn,"SimpleRowGraphPlacer/1",1292),lAn(1262,1,BJn,Kt),EWn.Lb=function(n){var t;return!!(t=_B(pMn(_B(n,243).b,(FXn(),ggt)),74))&&0!=t.b},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){var t;return!!(t=_B(pMn(_B(n,243).b,(FXn(),ggt)),74))&&0!=t.b},gX(JZn,"CompoundGraphPostprocessor/1",1262),lAn(1261,1,YZn,nm),EWn.pf=function(n,t){pvn(this,_B(n,37),t)},gX(JZn,"CompoundGraphPreprocessor",1261),lAn(441,1,{441:1},qfn),EWn.c=!1,gX(JZn,"CompoundGraphPreprocessor/ExternalPort",441),lAn(243,1,{243:1},A_),EWn.Ib=function(){return bx(this.c)+":"+ICn(this.b)},gX(JZn,"CrossHierarchyEdge",243),lAn(763,1,EJn,Rw),EWn.ue=function(n,t){return Xyn(this,_B(n,243),_B(t,243))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(JZn,"CrossHierarchyEdgeComparator",763),lAn(299,134,{3:1,299:1,94:1,134:1}),EWn.p=0,gX(ZZn,"LGraphElement",299),lAn(17,299,{3:1,17:1,299:1,94:1,134:1},lJ),EWn.Ib=function(){return ICn(this)};var vut=gX(ZZn,"LEdge",17);lAn(37,299,{3:1,20:1,37:1,299:1,94:1,134:1},pin),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new Ub(this.b)},EWn.Ib=function(){return 0==this.b.c.length?"G-unlayered"+AMn(this.a):0==this.a.c.length?"G-layered"+AMn(this.b):"G[layerless"+AMn(this.a)+", layers"+AMn(this.b)+"]"};var mut,yut=gX(ZZn,"LGraph",37);lAn(657,1,{}),EWn.qf=function(){return this.e.n},EWn.We=function(n){return pMn(this.e,n)},EWn.rf=function(){return this.e.o},EWn.sf=function(){return this.e.p},EWn.Xe=function(n){return Ax(this.e,n)},EWn.tf=function(n){this.e.n.a=n.a,this.e.n.b=n.b},EWn.uf=function(n){this.e.o.a=n.a,this.e.o.b=n.b},EWn.vf=function(n){this.e.p=n},gX(ZZn,"LGraphAdapters/AbstractLShapeAdapter",657),lAn(577,1,{839:1},Kw),EWn.wf=function(){var n,t;if(!this.b)for(this.b=ux(this.a.b.c.length),t=new Ub(this.a.b);t.a0&&Nhn((f1(t-1,n.length),n.charCodeAt(t-1)),u1n);)--t;if(r> ",n),dyn(e)),aO(cO((n.a+="[",n),e.i),"]")),n.a},EWn.c=!0,EWn.d=!1;var Kut,_ut,Fut,But,Hut=gX(ZZn,"LPort",11);lAn(397,1,dVn,Fw),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new Bw(new Ub(this.a.e))},gX(ZZn,"LPort/1",397),lAn(1290,1,WWn,Bw),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return _B(Y1(this.a),17).c},EWn.Ob=function(){return v$(this.a)},EWn.Qb=function(){CU(this.a)},gX(ZZn,"LPort/1/1",1290),lAn(359,1,dVn,Hw),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new qw(new Ub(this.a.g))},gX(ZZn,"LPort/2",359),lAn(762,1,WWn,qw),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return _B(Y1(this.a),17).d},EWn.Ob=function(){return v$(this.a)},EWn.Qb=function(){CU(this.a)},gX(ZZn,"LPort/2/1",762),lAn(1283,1,dVn,oP),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new p6(this)},gX(ZZn,"LPort/CombineIter",1283),lAn(201,1,WWn,p6),EWn.Nb=function(n){sU(this,n)},EWn.Qb=function(){cE()},EWn.Ob=function(){return qN(this)},EWn.Pb=function(){return v$(this.a)?Y1(this.a):Y1(this.b)},gX(ZZn,"LPort/CombineIter/1",201),lAn(1285,1,BJn,Bt),EWn.Lb=function(n){return Cz(n)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),0!=_B(n,11).e.c.length},gX(ZZn,"LPort/lambda$0$Type",1285),lAn(1284,1,BJn,Ht),EWn.Lb=function(n){return Oz(n)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),0!=_B(n,11).g.c.length},gX(ZZn,"LPort/lambda$1$Type",1284),lAn(1286,1,BJn,qt),EWn.Lb=function(n){return wcn(),_B(n,11).j==(mUn(),uCt)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),_B(n,11).j==(mUn(),uCt)},gX(ZZn,"LPort/lambda$2$Type",1286),lAn(1287,1,BJn,Gt),EWn.Lb=function(n){return wcn(),_B(n,11).j==(mUn(),aCt)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),_B(n,11).j==(mUn(),aCt)},gX(ZZn,"LPort/lambda$3$Type",1287),lAn(1288,1,BJn,zt),EWn.Lb=function(n){return wcn(),_B(n,11).j==(mUn(),TCt)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),_B(n,11).j==(mUn(),TCt)},gX(ZZn,"LPort/lambda$4$Type",1288),lAn(1289,1,BJn,Ut),EWn.Lb=function(n){return wcn(),_B(n,11).j==(mUn(),SCt)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),_B(n,11).j==(mUn(),SCt)},gX(ZZn,"LPort/lambda$5$Type",1289),lAn(29,299,{3:1,20:1,299:1,29:1,94:1,134:1},FX),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new Ub(this.a)},EWn.Ib=function(){return"L_"+k7(this.b.b,this,0)+AMn(this.a)},gX(ZZn,"Layer",29),lAn(1342,1,{},Zv),gX(b1n,w1n,1342),lAn(1346,1,{},Xt),EWn.Kb=function(n){return MTn(_B(n,82))},gX(b1n,"ElkGraphImporter/0methodref$connectableShapeToNode$Type",1346),lAn(1349,1,{},Wt),EWn.Kb=function(n){return MTn(_B(n,82))},gX(b1n,"ElkGraphImporter/1methodref$connectableShapeToNode$Type",1349),lAn(1343,1,hVn,Gw),EWn.td=function(n){MOn(this.a,_B(n,118))},gX(b1n,d1n,1343),lAn(1344,1,hVn,zw),EWn.td=function(n){MOn(this.a,_B(n,118))},gX(b1n,g1n,1344),lAn(1345,1,{},Vt),EWn.Kb=function(n){return new xq(null,new l1(dV(_B(n,79)),16))},gX(b1n,p1n,1345),lAn(1347,1,NVn,Uw),EWn.Mb=function(n){return RA(this.a,_B(n,33))},gX(b1n,v1n,1347),lAn(1348,1,{},Qt),EWn.Kb=function(n){return new xq(null,new l1(gV(_B(n,79)),16))},gX(b1n,"ElkGraphImporter/lambda$5$Type",1348),lAn(1350,1,NVn,Xw),EWn.Mb=function(n){return KA(this.a,_B(n,33))},gX(b1n,"ElkGraphImporter/lambda$7$Type",1350),lAn(1351,1,NVn,Jt),EWn.Mb=function(n){return CQ(_B(n,79))},gX(b1n,"ElkGraphImporter/lambda$8$Type",1351),lAn(1278,1,{},Wh),gX(b1n,"ElkGraphLayoutTransferrer",1278),lAn(1279,1,NVn,Ww),EWn.Mb=function(n){return QR(this.a,_B(n,17))},gX(b1n,"ElkGraphLayoutTransferrer/lambda$0$Type",1279),lAn(1280,1,hVn,Vw),EWn.td=function(n){pM(),UB(this.a,_B(n,17))},gX(b1n,"ElkGraphLayoutTransferrer/lambda$1$Type",1280),lAn(1281,1,NVn,Qw),EWn.Mb=function(n){return GD(this.a,_B(n,17))},gX(b1n,"ElkGraphLayoutTransferrer/lambda$2$Type",1281),lAn(1282,1,hVn,Jw),EWn.td=function(n){pM(),UB(this.a,_B(n,17))},gX(b1n,"ElkGraphLayoutTransferrer/lambda$3$Type",1282),lAn(1485,1,YZn,Yt),EWn.pf=function(n,t){Xrn(_B(n,37),t)},gX(y1n,"CommentNodeMarginCalculator",1485),lAn(1486,1,{},Zt),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"CommentNodeMarginCalculator/lambda$0$Type",1486),lAn(1487,1,hVn,ne),EWn.td=function(n){ZBn(_B(n,10))},gX(y1n,"CommentNodeMarginCalculator/lambda$1$Type",1487),lAn(1488,1,YZn,te),EWn.pf=function(n,t){rDn(_B(n,37),t)},gX(y1n,"CommentPostprocessor",1488),lAn(1489,1,YZn,ee),EWn.pf=function(n,t){cUn(_B(n,37),t)},gX(y1n,"CommentPreprocessor",1489),lAn(1490,1,YZn,ie),EWn.pf=function(n,t){yLn(_B(n,37),t)},gX(y1n,"ConstraintsPostprocessor",1490),lAn(1491,1,YZn,re),EWn.pf=function(n,t){ian(_B(n,37),t)},gX(y1n,"EdgeAndLayerConstraintEdgeReverser",1491),lAn(1492,1,YZn,ce),EWn.pf=function(n,t){Hwn(_B(n,37),t)},gX(y1n,"EndLabelPostprocessor",1492),lAn(1493,1,{},ae),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"EndLabelPostprocessor/lambda$0$Type",1493),lAn(1494,1,NVn,ue),EWn.Mb=function(n){return EJ(_B(n,10))},gX(y1n,"EndLabelPostprocessor/lambda$1$Type",1494),lAn(1495,1,hVn,oe),EWn.td=function(n){njn(_B(n,10))},gX(y1n,"EndLabelPostprocessor/lambda$2$Type",1495),lAn(1496,1,YZn,se),EWn.pf=function(n,t){JPn(_B(n,37),t)},gX(y1n,"EndLabelPreprocessor",1496),lAn(1497,1,{},he),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"EndLabelPreprocessor/lambda$0$Type",1497),lAn(1498,1,hVn,N_),EWn.td=function(n){DM(this.a,this.b,this.c,_B(n,10))},EWn.a=0,EWn.b=0,EWn.c=!1,gX(y1n,"EndLabelPreprocessor/lambda$1$Type",1498),lAn(1499,1,NVn,fe),EWn.Mb=function(n){return HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),zPt))},gX(y1n,"EndLabelPreprocessor/lambda$2$Type",1499),lAn(1500,1,hVn,Yw),EWn.td=function(n){NH(this.a,_B(n,70))},gX(y1n,"EndLabelPreprocessor/lambda$3$Type",1500),lAn(1501,1,NVn,le),EWn.Mb=function(n){return HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),GPt))},gX(y1n,"EndLabelPreprocessor/lambda$4$Type",1501),lAn(1502,1,hVn,Zw),EWn.td=function(n){NH(this.a,_B(n,70))},gX(y1n,"EndLabelPreprocessor/lambda$5$Type",1502),lAn(1551,1,YZn,Xh),EWn.pf=function(n,t){Sln(_B(n,37),t)},gX(y1n,"EndLabelSorter",1551),lAn(1552,1,EJn,be),EWn.ue=function(n,t){return Fgn(_B(n,456),_B(t,456))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"EndLabelSorter/1",1552),lAn(456,1,{456:1},jQ),gX(y1n,"EndLabelSorter/LabelGroup",456),lAn(1553,1,{},we),EWn.Kb=function(n){return kM(),new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"EndLabelSorter/lambda$0$Type",1553),lAn(1554,1,NVn,de),EWn.Mb=function(n){return kM(),_B(n,10).k==(cSn(),Sut)},gX(y1n,"EndLabelSorter/lambda$1$Type",1554),lAn(1555,1,hVn,ge),EWn.td=function(n){aSn(_B(n,10))},gX(y1n,"EndLabelSorter/lambda$2$Type",1555),lAn(1556,1,NVn,pe),EWn.Mb=function(n){return kM(),HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),GPt))},gX(y1n,"EndLabelSorter/lambda$3$Type",1556),lAn(1557,1,NVn,ve),EWn.Mb=function(n){return kM(),HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),zPt))},gX(y1n,"EndLabelSorter/lambda$4$Type",1557),lAn(1503,1,YZn,me),EWn.pf=function(n,t){PHn(this,_B(n,37))},EWn.b=0,EWn.c=0,gX(y1n,"FinalSplineBendpointsCalculator",1503),lAn(1504,1,{},ye),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"FinalSplineBendpointsCalculator/lambda$0$Type",1504),lAn(1505,1,{},ke),EWn.Kb=function(n){return new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(y1n,"FinalSplineBendpointsCalculator/lambda$1$Type",1505),lAn(1506,1,NVn,je),EWn.Mb=function(n){return!f5(_B(n,17))},gX(y1n,"FinalSplineBendpointsCalculator/lambda$2$Type",1506),lAn(1507,1,NVn,Ee),EWn.Mb=function(n){return Ax(_B(n,17),(oWn(),$lt))},gX(y1n,"FinalSplineBendpointsCalculator/lambda$3$Type",1507),lAn(1508,1,hVn,nd),EWn.td=function(n){qKn(this.a,_B(n,128))},gX(y1n,"FinalSplineBendpointsCalculator/lambda$4$Type",1508),lAn(1509,1,hVn,Te),EWn.td=function(n){QPn(_B(n,17).a)},gX(y1n,"FinalSplineBendpointsCalculator/lambda$5$Type",1509),lAn(792,1,YZn,td),EWn.pf=function(n,t){Xqn(this,_B(n,37),t)},gX(y1n,"GraphTransformer",792),lAn(511,22,{3:1,35:1,22:1,511:1},JS);var qut,Gut,zut,Uut=_en(y1n,"GraphTransformer/Mode",511,Gnt,cY,ZF);lAn(1510,1,YZn,Me),EWn.pf=function(n,t){nxn(_B(n,37),t)},gX(y1n,"HierarchicalNodeResizingProcessor",1510),lAn(1511,1,YZn,Se),EWn.pf=function(n,t){hrn(_B(n,37),t)},gX(y1n,"HierarchicalPortConstraintProcessor",1511),lAn(1512,1,EJn,Pe),EWn.ue=function(n,t){return Ppn(_B(n,10),_B(t,10))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"HierarchicalPortConstraintProcessor/NodeComparator",1512),lAn(1513,1,YZn,Ie),EWn.pf=function(n,t){yBn(_B(n,37),t)},gX(y1n,"HierarchicalPortDummySizeProcessor",1513),lAn(1514,1,YZn,Ce),EWn.pf=function(n,t){QDn(this,_B(n,37),t)},EWn.a=0,gX(y1n,"HierarchicalPortOrthogonalEdgeRouter",1514),lAn(1515,1,EJn,Oe),EWn.ue=function(n,t){return RN(_B(n,10),_B(t,10))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"HierarchicalPortOrthogonalEdgeRouter/1",1515),lAn(1516,1,EJn,Ae),EWn.ue=function(n,t){return M9(_B(n,10),_B(t,10))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"HierarchicalPortOrthogonalEdgeRouter/2",1516),lAn(1517,1,YZn,$e),EWn.pf=function(n,t){kMn(_B(n,37),t)},gX(y1n,"HierarchicalPortPositionProcessor",1517),lAn(1518,1,YZn,Vh),EWn.pf=function(n,t){eXn(this,_B(n,37))},EWn.a=0,EWn.c=0,gX(y1n,"HighDegreeNodeLayeringProcessor",1518),lAn(571,1,{571:1},Le),EWn.b=-1,EWn.d=-1,gX(y1n,"HighDegreeNodeLayeringProcessor/HighDegreeNodeInformation",571),lAn(1519,1,{},Ne),EWn.Kb=function(n){return B_(),sbn(_B(n,10))},EWn.Fb=function(n){return this===n},gX(y1n,"HighDegreeNodeLayeringProcessor/lambda$0$Type",1519),lAn(1520,1,{},xe),EWn.Kb=function(n){return B_(),hbn(_B(n,10))},EWn.Fb=function(n){return this===n},gX(y1n,"HighDegreeNodeLayeringProcessor/lambda$1$Type",1520),lAn(1526,1,YZn,De),EWn.pf=function(n,t){bFn(this,_B(n,37),t)},gX(y1n,"HyperedgeDummyMerger",1526),lAn(793,1,{},x_),EWn.a=!1,EWn.b=!1,EWn.c=!1,gX(y1n,"HyperedgeDummyMerger/MergeState",793),lAn(1527,1,{},Re),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"HyperedgeDummyMerger/lambda$0$Type",1527),lAn(1528,1,{},Ke),EWn.Kb=function(n){return new xq(null,new l1(_B(n,10).j,16))},gX(y1n,"HyperedgeDummyMerger/lambda$1$Type",1528),lAn(1529,1,hVn,_e),EWn.td=function(n){_B(n,11).p=-1},gX(y1n,"HyperedgeDummyMerger/lambda$2$Type",1529),lAn(1530,1,YZn,Fe),EWn.pf=function(n,t){fFn(_B(n,37),t)},gX(y1n,"HypernodesProcessor",1530),lAn(1531,1,YZn,Be),EWn.pf=function(n,t){lFn(_B(n,37),t)},gX(y1n,"InLayerConstraintProcessor",1531),lAn(1532,1,YZn,He),EWn.pf=function(n,t){Acn(_B(n,37),t)},gX(y1n,"InnermostNodeMarginCalculator",1532),lAn(1533,1,YZn,qe),EWn.pf=function(n,t){Xzn(this,_B(n,37))},EWn.a=DQn,EWn.b=DQn,EWn.c=xQn,EWn.d=xQn;var Xut,Wut,Vut,Qut,Jut,Yut,Zut,not,tot,eot,iot,rot,cot,aot,uot,oot,sot,hot,fot,lot,bot,wot,dot,got,pot,vot,mot,yot,kot,jot,Eot,Tot,Mot,Sot,Pot,Iot,Cot,Oot,Aot,$ot,Lot,Not,xot,Dot,Rot,Kot,_ot,Fot,Bot,Hot,qot,Got,zot,Uot,Xot,Wot,Vot,Qot=gX(y1n,"InteractiveExternalPortPositioner",1533);lAn(1534,1,{},Ge),EWn.Kb=function(n){return _B(n,17).d.i},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$0$Type",1534),lAn(1535,1,{},ed),EWn.Kb=function(n){return BN(this.a,ED(n))},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$1$Type",1535),lAn(1536,1,{},ze),EWn.Kb=function(n){return _B(n,17).c.i},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$2$Type",1536),lAn(1537,1,{},id),EWn.Kb=function(n){return HN(this.a,ED(n))},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$3$Type",1537),lAn(1538,1,{},rd),EWn.Kb=function(n){return UR(this.a,ED(n))},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$4$Type",1538),lAn(1539,1,{},cd),EWn.Kb=function(n){return XR(this.a,ED(n))},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$5$Type",1539),lAn(77,22,{3:1,35:1,22:1,77:1,234:1},YS),EWn.Kf=function(){switch(this.g){case 15:return new dc;case 22:return new gc;case 47:return new mc;case 28:case 35:return new ei;case 32:return new Yt;case 42:return new te;case 1:return new ee;case 41:return new ie;case 56:return new td((Trn(),But));case 0:return new td((Trn(),Fut));case 2:return new re;case 54:return new ce;case 33:return new se;case 51:return new me;case 55:return new Me;case 13:return new Se;case 38:return new Ie;case 44:return new Ce;case 40:return new $e;case 9:return new Vh;case 49:return new ax;case 37:return new De;case 43:return new Fe;case 27:return new Be;case 30:return new He;case 3:return new qe;case 18:return new Xe;case 29:return new We;case 5:return new Qh;case 50:return new Ue;case 34:return new Jh;case 36:return new ii;case 52:return new Xh;case 11:return new ci;case 7:return new Zh;case 39:return new ai;case 45:return new ui;case 16:return new oi;case 10:return new si;case 48:return new fi;case 21:return new li;case 23:return new $y((ain(),Cmt));case 8:return new wi;case 12:return new gi;case 4:return new pi;case 19:return new rf;case 17:return new Pi;case 53:return new Ii;case 6:return new Bi;case 25:return new rm;case 46:return new Ni;case 31:return new LR;case 14:return new Vi;case 26:return new Sc;case 20:return new nr;case 24:return new $y((ain(),Omt));default:throw Fp(new Ry(E1n+(null!=this.f?this.f:""+this.g)))}};var Jot,Yot,Zot,nst,tst,est,ist,rst,cst=_en(y1n,T1n,77,Gnt,kNn,YF);lAn(1540,1,YZn,Xe),EWn.pf=function(n,t){Qzn(_B(n,37),t)},gX(y1n,"InvertedPortProcessor",1540),lAn(1541,1,YZn,We),EWn.pf=function(n,t){AKn(_B(n,37),t)},gX(y1n,"LabelAndNodeSizeProcessor",1541),lAn(1542,1,NVn,Ve),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Sut)},gX(y1n,"LabelAndNodeSizeProcessor/lambda$0$Type",1542),lAn(1543,1,NVn,Qe),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Eut)},gX(y1n,"LabelAndNodeSizeProcessor/lambda$1$Type",1543),lAn(1544,1,hVn,D_),EWn.td=function(n){RM(this.b,this.a,this.c,_B(n,10))},EWn.a=!1,EWn.c=!1,gX(y1n,"LabelAndNodeSizeProcessor/lambda$2$Type",1544),lAn(1545,1,YZn,Qh),EWn.pf=function(n,t){szn(_B(n,37),t)},gX(y1n,"LabelDummyInserter",1545),lAn(1546,1,BJn,Je),EWn.Lb=function(n){return HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),qPt))},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),qPt))},gX(y1n,"LabelDummyInserter/1",1546),lAn(1547,1,YZn,Ue),EWn.pf=function(n,t){Mqn(_B(n,37),t)},gX(y1n,"LabelDummyRemover",1547),lAn(1548,1,NVn,Ye),EWn.Mb=function(n){return By(jD(pMn(_B(n,70),(FXn(),Wdt))))},gX(y1n,"LabelDummyRemover/lambda$0$Type",1548),lAn(1359,1,YZn,Jh),EWn.pf=function(n,t){jGn(this,_B(n,37),t)},EWn.a=null,gX(y1n,"LabelDummySwitcher",1359),lAn(286,1,{286:1},iKn),EWn.c=0,EWn.d=null,EWn.f=0,gX(y1n,"LabelDummySwitcher/LabelDummyInfo",286),lAn(1360,1,{},Ze),EWn.Kb=function(n){return Prn(),new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"LabelDummySwitcher/lambda$0$Type",1360),lAn(1361,1,NVn,ni),EWn.Mb=function(n){return Prn(),_B(n,10).k==(cSn(),Tut)},gX(y1n,"LabelDummySwitcher/lambda$1$Type",1361),lAn(1362,1,{},od),EWn.Kb=function(n){return zD(this.a,_B(n,10))},gX(y1n,"LabelDummySwitcher/lambda$2$Type",1362),lAn(1363,1,hVn,sd),EWn.td=function(n){VX(this.a,_B(n,286))},gX(y1n,"LabelDummySwitcher/lambda$3$Type",1363),lAn(1364,1,EJn,ti),EWn.ue=function(n,t){return Az(_B(n,286),_B(t,286))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"LabelDummySwitcher/lambda$4$Type",1364),lAn(791,1,YZn,ei),EWn.pf=function(n,t){V6(_B(n,37),t)},gX(y1n,"LabelManagementProcessor",791),lAn(1549,1,YZn,ii),EWn.pf=function(n,t){$xn(_B(n,37),t)},gX(y1n,"LabelSideSelector",1549),lAn(1550,1,NVn,ri),EWn.Mb=function(n){return By(jD(pMn(_B(n,70),(FXn(),Wdt))))},gX(y1n,"LabelSideSelector/lambda$0$Type",1550),lAn(1558,1,YZn,ci),EWn.pf=function(n,t){kBn(_B(n,37),t)},gX(y1n,"LayerConstraintPostprocessor",1558),lAn(1559,1,YZn,Zh),EWn.pf=function(n,t){e$n(_B(n,37),t)},gX(y1n,"LayerConstraintPreprocessor",1559),lAn(360,22,{3:1,35:1,22:1,360:1},ZS);var ast,ust,ost,sst,hst,fst,lst,bst,wst,dst=_en(y1n,"LayerConstraintPreprocessor/HiddenNodeConnections",360,Gnt,n3,q_);lAn(1560,1,YZn,ai),EWn.pf=function(n,t){kqn(_B(n,37),t)},gX(y1n,"LayerSizeAndGraphHeightCalculator",1560),lAn(1561,1,YZn,ui),EWn.pf=function(n,t){CLn(_B(n,37),t)},gX(y1n,"LongEdgeJoiner",1561),lAn(1562,1,YZn,oi),EWn.pf=function(n,t){UHn(_B(n,37),t)},gX(y1n,"LongEdgeSplitter",1562),lAn(1563,1,YZn,si),EWn.pf=function(n,t){MGn(this,_B(n,37),t)},EWn.d=0,EWn.e=0,EWn.i=0,EWn.j=0,EWn.k=0,EWn.n=0,gX(y1n,"NodePromotion",1563),lAn(1564,1,{},hi),EWn.Kb=function(n){return _B(n,46),oN(),!0},EWn.Fb=function(n){return this===n},gX(y1n,"NodePromotion/lambda$0$Type",1564),lAn(1565,1,{},ad),EWn.Kb=function(n){return rV(this.a,_B(n,46))},EWn.Fb=function(n){return this===n},EWn.a=0,gX(y1n,"NodePromotion/lambda$1$Type",1565),lAn(1566,1,{},ud),EWn.Kb=function(n){return cV(this.a,_B(n,46))},EWn.Fb=function(n){return this===n},EWn.a=0,gX(y1n,"NodePromotion/lambda$2$Type",1566),lAn(1567,1,YZn,fi),EWn.pf=function(n,t){zUn(_B(n,37),t)},gX(y1n,"NorthSouthPortPostprocessor",1567),lAn(1568,1,YZn,li),EWn.pf=function(n,t){EUn(_B(n,37),t)},gX(y1n,"NorthSouthPortPreprocessor",1568),lAn(1569,1,EJn,bi),EWn.ue=function(n,t){return Jan(_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"NorthSouthPortPreprocessor/lambda$0$Type",1569),lAn(1570,1,YZn,wi),EWn.pf=function(n,t){O_n(_B(n,37),t)},gX(y1n,"PartitionMidprocessor",1570),lAn(1571,1,NVn,di),EWn.Mb=function(n){return Ax(_B(n,10),(FXn(),Ugt))},gX(y1n,"PartitionMidprocessor/lambda$0$Type",1571),lAn(1572,1,hVn,hd),EWn.td=function(n){OQ(this.a,_B(n,10))},gX(y1n,"PartitionMidprocessor/lambda$1$Type",1572),lAn(1573,1,YZn,gi),EWn.pf=function(n,t){lNn(_B(n,37),t)},gX(y1n,"PartitionPostprocessor",1573),lAn(1574,1,YZn,pi),EWn.pf=function(n,t){$On(_B(n,37),t)},gX(y1n,"PartitionPreprocessor",1574),lAn(1575,1,NVn,vi),EWn.Mb=function(n){return Ax(_B(n,10),(FXn(),Ugt))},gX(y1n,"PartitionPreprocessor/lambda$0$Type",1575),lAn(1576,1,{},mi),EWn.Kb=function(n){return new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(y1n,"PartitionPreprocessor/lambda$1$Type",1576),lAn(1577,1,NVn,yi),EWn.Mb=function(n){return Agn(_B(n,17))},gX(y1n,"PartitionPreprocessor/lambda$2$Type",1577),lAn(1578,1,hVn,ki),EWn.td=function(n){xun(_B(n,17))},gX(y1n,"PartitionPreprocessor/lambda$3$Type",1578),lAn(1579,1,YZn,rf),EWn.pf=function(n,t){c_n(_B(n,37),t)},gX(y1n,"PortListSorter",1579),lAn(1580,1,{},ji),EWn.Kb=function(n){return qsn(),_B(n,11).e},gX(y1n,"PortListSorter/lambda$0$Type",1580),lAn(1581,1,{},Ei),EWn.Kb=function(n){return qsn(),_B(n,11).g},gX(y1n,"PortListSorter/lambda$1$Type",1581),lAn(1582,1,EJn,Ti),EWn.ue=function(n,t){return j4(_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"PortListSorter/lambda$2$Type",1582),lAn(1583,1,EJn,Mi),EWn.ue=function(n,t){return Iyn(_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"PortListSorter/lambda$3$Type",1583),lAn(1584,1,EJn,Si),EWn.ue=function(n,t){return Y_n(_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"PortListSorter/lambda$4$Type",1584),lAn(1585,1,YZn,Pi),EWn.pf=function(n,t){UAn(_B(n,37),t)},gX(y1n,"PortSideProcessor",1585),lAn(1586,1,YZn,Ii),EWn.pf=function(n,t){PRn(_B(n,37),t)},gX(y1n,"ReversedEdgeRestorer",1586),lAn(1591,1,YZn,rm),EWn.pf=function(n,t){Vmn(this,_B(n,37),t)},gX(y1n,"SelfLoopPortRestorer",1591),lAn(1592,1,{},Ci),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"SelfLoopPortRestorer/lambda$0$Type",1592),lAn(1593,1,NVn,Oi),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Sut)},gX(y1n,"SelfLoopPortRestorer/lambda$1$Type",1593),lAn(1594,1,NVn,Ai),EWn.Mb=function(n){return Ax(_B(n,10),(oWn(),Ilt))},gX(y1n,"SelfLoopPortRestorer/lambda$2$Type",1594),lAn(1595,1,{},$i),EWn.Kb=function(n){return _B(pMn(_B(n,10),(oWn(),Ilt)),403)},gX(y1n,"SelfLoopPortRestorer/lambda$3$Type",1595),lAn(1596,1,hVn,fd),EWn.td=function(n){TSn(this.a,_B(n,403))},gX(y1n,"SelfLoopPortRestorer/lambda$4$Type",1596),lAn(794,1,hVn,Li),EWn.td=function(n){YSn(_B(n,101))},gX(y1n,"SelfLoopPortRestorer/lambda$5$Type",794),lAn(1597,1,YZn,Ni),EWn.pf=function(n,t){Apn(_B(n,37),t)},gX(y1n,"SelfLoopPostProcessor",1597),lAn(1598,1,{},xi),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"SelfLoopPostProcessor/lambda$0$Type",1598),lAn(1599,1,NVn,Di),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Sut)},gX(y1n,"SelfLoopPostProcessor/lambda$1$Type",1599),lAn(1600,1,NVn,Ri),EWn.Mb=function(n){return Ax(_B(n,10),(oWn(),Ilt))},gX(y1n,"SelfLoopPostProcessor/lambda$2$Type",1600),lAn(1601,1,hVn,Ki),EWn.td=function(n){Ajn(_B(n,10))},gX(y1n,"SelfLoopPostProcessor/lambda$3$Type",1601),lAn(1602,1,{},_i),EWn.Kb=function(n){return new xq(null,new l1(_B(n,101).f,1))},gX(y1n,"SelfLoopPostProcessor/lambda$4$Type",1602),lAn(1603,1,hVn,ld),EWn.td=function(n){r3(this.a,_B(n,409))},gX(y1n,"SelfLoopPostProcessor/lambda$5$Type",1603),lAn(1604,1,NVn,Fi),EWn.Mb=function(n){return!!_B(n,101).i},gX(y1n,"SelfLoopPostProcessor/lambda$6$Type",1604),lAn(1605,1,hVn,bd),EWn.td=function(n){jy(this.a,_B(n,101))},gX(y1n,"SelfLoopPostProcessor/lambda$7$Type",1605),lAn(1587,1,YZn,Bi),EWn.pf=function(n,t){J$n(_B(n,37),t)},gX(y1n,"SelfLoopPreProcessor",1587),lAn(1588,1,{},Hi),EWn.Kb=function(n){return new xq(null,new l1(_B(n,101).f,1))},gX(y1n,"SelfLoopPreProcessor/lambda$0$Type",1588),lAn(1589,1,{},qi),EWn.Kb=function(n){return _B(n,409).a},gX(y1n,"SelfLoopPreProcessor/lambda$1$Type",1589),lAn(1590,1,hVn,Gi),EWn.td=function(n){B$(_B(n,17))},gX(y1n,"SelfLoopPreProcessor/lambda$2$Type",1590),lAn(1606,1,YZn,LR),EWn.pf=function(n,t){uSn(this,_B(n,37),t)},gX(y1n,"SelfLoopRouter",1606),lAn(1607,1,{},zi),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"SelfLoopRouter/lambda$0$Type",1607),lAn(1608,1,NVn,Ui),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Sut)},gX(y1n,"SelfLoopRouter/lambda$1$Type",1608),lAn(1609,1,NVn,Xi),EWn.Mb=function(n){return Ax(_B(n,10),(oWn(),Ilt))},gX(y1n,"SelfLoopRouter/lambda$2$Type",1609),lAn(1610,1,{},Wi),EWn.Kb=function(n){return _B(pMn(_B(n,10),(oWn(),Ilt)),403)},gX(y1n,"SelfLoopRouter/lambda$3$Type",1610),lAn(1611,1,hVn,nP),EWn.td=function(n){WV(this.a,this.b,_B(n,403))},gX(y1n,"SelfLoopRouter/lambda$4$Type",1611),lAn(1612,1,YZn,Vi),EWn.pf=function(n,t){sxn(_B(n,37),t)},gX(y1n,"SemiInteractiveCrossMinProcessor",1612),lAn(1613,1,NVn,Qi),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Sut)},gX(y1n,"SemiInteractiveCrossMinProcessor/lambda$0$Type",1613),lAn(1614,1,NVn,Ji),EWn.Mb=function(n){return Hq(_B(n,10))._b((FXn(),upt))},gX(y1n,"SemiInteractiveCrossMinProcessor/lambda$1$Type",1614),lAn(1615,1,EJn,Yi),EWn.ue=function(n,t){return brn(_B(n,10),_B(t,10))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"SemiInteractiveCrossMinProcessor/lambda$2$Type",1615),lAn(1616,1,{},Zi),EWn.Ce=function(n,t){return zQ(_B(n,10),_B(t,10))},gX(y1n,"SemiInteractiveCrossMinProcessor/lambda$3$Type",1616),lAn(1618,1,YZn,nr),EWn.pf=function(n,t){EBn(_B(n,37),t)},gX(y1n,"SortByInputModelProcessor",1618),lAn(1619,1,NVn,tr),EWn.Mb=function(n){return 0!=_B(n,11).g.c.length},gX(y1n,"SortByInputModelProcessor/lambda$0$Type",1619),lAn(1620,1,hVn,wd),EWn.td=function(n){sPn(this.a,_B(n,11))},gX(y1n,"SortByInputModelProcessor/lambda$1$Type",1620),lAn(1693,803,{},wrn),EWn.Me=function(n){var t,e,i,r;switch(this.c=n,this.a.g){case 2:t=new $p,QT(CV(new xq(null,new l1(this.c.a.b,16)),new dr),new cP(this,t)),dIn(this,new rr),Itn(t,new cr),t.c=L8(Cnt,FWn,1,0,5,1),QT(CV(new xq(null,new l1(this.c.a.b,16)),new ar),new gd(t)),dIn(this,new ur),Itn(t,new or),t.c=L8(Cnt,FWn,1,0,5,1),e=y$(tcn(AV(new xq(null,new l1(this.c.a.b,16)),new pd(this))),new sr),QT(new xq(null,new l1(this.c.a.a,16)),new eP(e,t)),dIn(this,new fr),Itn(t,new er),t.c=L8(Cnt,FWn,1,0,5,1);break;case 3:i=new $p,dIn(this,new ir),r=y$(tcn(AV(new xq(null,new l1(this.c.a.b,16)),new dd(this))),new hr),QT(CV(new xq(null,new l1(this.c.a.b,16)),new lr),new rP(r,i)),dIn(this,new br),Itn(i,new wr),i.c=L8(Cnt,FWn,1,0,5,1);break;default:throw Fp(new mv)}},EWn.b=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation",1693),lAn(1694,1,BJn,ir),EWn.Lb=function(n){return iL(_B(n,57).g,145)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return iL(_B(n,57).g,145)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$0$Type",1694),lAn(1695,1,{},dd),EWn.Fe=function(n){return HIn(this.a,_B(n,57))},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$1$Type",1695),lAn(1703,1,xVn,tP),EWn.Vd=function(){Kkn(this.a,this.b,-1)},EWn.b=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$10$Type",1703),lAn(1705,1,BJn,rr),EWn.Lb=function(n){return iL(_B(n,57).g,145)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return iL(_B(n,57).g,145)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$11$Type",1705),lAn(1706,1,hVn,cr),EWn.td=function(n){_B(n,365).Vd()},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$12$Type",1706),lAn(1707,1,NVn,ar),EWn.Mb=function(n){return iL(_B(n,57).g,10)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$13$Type",1707),lAn(1709,1,hVn,gd),EWn.td=function(n){kbn(this.a,_B(n,57))},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$14$Type",1709),lAn(1708,1,xVn,hP),EWn.Vd=function(){Kkn(this.b,this.a,-1)},EWn.a=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$15$Type",1708),lAn(1710,1,BJn,ur),EWn.Lb=function(n){return iL(_B(n,57).g,10)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return iL(_B(n,57).g,10)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$16$Type",1710),lAn(1711,1,hVn,or),EWn.td=function(n){_B(n,365).Vd()},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$17$Type",1711),lAn(1712,1,{},pd),EWn.Fe=function(n){return qIn(this.a,_B(n,57))},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$18$Type",1712),lAn(1713,1,{},sr),EWn.De=function(){return 0},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$19$Type",1713),lAn(1696,1,{},hr),EWn.De=function(){return 0},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$2$Type",1696),lAn(1715,1,hVn,eP),EWn.td=function(n){FG(this.a,this.b,_B(n,307))},EWn.a=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$20$Type",1715),lAn(1714,1,xVn,iP),EWn.Vd=function(){XAn(this.a,this.b,-1)},EWn.b=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$21$Type",1714),lAn(1716,1,BJn,fr),EWn.Lb=function(n){return _B(n,57),!0},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return _B(n,57),!0},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$22$Type",1716),lAn(1717,1,hVn,er),EWn.td=function(n){_B(n,365).Vd()},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$23$Type",1717),lAn(1697,1,NVn,lr),EWn.Mb=function(n){return iL(_B(n,57).g,10)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$3$Type",1697),lAn(1699,1,hVn,rP),EWn.td=function(n){BG(this.a,this.b,_B(n,57))},EWn.a=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$4$Type",1699),lAn(1698,1,xVn,fP),EWn.Vd=function(){Kkn(this.b,this.a,-1)},EWn.a=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$5$Type",1698),lAn(1700,1,BJn,br),EWn.Lb=function(n){return _B(n,57),!0},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return _B(n,57),!0},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$6$Type",1700),lAn(1701,1,hVn,wr),EWn.td=function(n){_B(n,365).Vd()},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$7$Type",1701),lAn(1702,1,NVn,dr),EWn.Mb=function(n){return iL(_B(n,57).g,145)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$8$Type",1702),lAn(1704,1,hVn,cP),EWn.td=function(n){jtn(this.a,this.b,_B(n,57))},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$9$Type",1704),lAn(1521,1,YZn,ax),EWn.pf=function(n,t){iqn(this,_B(n,37),t)},gX(C1n,"HorizontalGraphCompactor",1521),lAn(1522,1,{},vd),EWn.Oe=function(n,t){var e,i;return J7(n,t)?0:(e=s2(n),i=s2(t),e&&e.k==(cSn(),Eut)||i&&i.k==(cSn(),Eut)?0:GN(_B(pMn(this.a.a,(oWn(),Clt)),304),e?e.k:(cSn(),Mut),i?i.k:(cSn(),Mut)))},EWn.Pe=function(n,t){var e,i;return J7(n,t)?1:(e=s2(n),i=s2(t),zN(_B(pMn(this.a.a,(oWn(),Clt)),304),e?e.k:(cSn(),Mut),i?i.k:(cSn(),Mut)))},gX(C1n,"HorizontalGraphCompactor/1",1522),lAn(1523,1,{},gr),EWn.Ne=function(n,t){return EM(),0==n.a.i},gX(C1n,"HorizontalGraphCompactor/lambda$0$Type",1523),lAn(1524,1,{},md),EWn.Ne=function(n,t){return RQ(this.a,n,t)},gX(C1n,"HorizontalGraphCompactor/lambda$1$Type",1524),lAn(1664,1,{},P7),gX(C1n,"LGraphToCGraphTransformer",1664),lAn(1672,1,NVn,pr),EWn.Mb=function(n){return null!=n},gX(C1n,"LGraphToCGraphTransformer/0methodref$nonNull$Type",1672),lAn(1665,1,{},vr),EWn.Kb=function(n){return H_(),_bn(pMn(_B(_B(n,57).g,10),(oWn(),blt)))},gX(C1n,"LGraphToCGraphTransformer/lambda$0$Type",1665),lAn(1666,1,{},mr),EWn.Kb=function(n){return H_(),pfn(_B(_B(n,57).g,145))},gX(C1n,"LGraphToCGraphTransformer/lambda$1$Type",1666),lAn(1675,1,NVn,yr),EWn.Mb=function(n){return H_(),iL(_B(n,57).g,10)},gX(C1n,"LGraphToCGraphTransformer/lambda$10$Type",1675),lAn(1676,1,hVn,kr),EWn.td=function(n){DQ(_B(n,57))},gX(C1n,"LGraphToCGraphTransformer/lambda$11$Type",1676),lAn(1677,1,NVn,jr),EWn.Mb=function(n){return H_(),iL(_B(n,57).g,145)},gX(C1n,"LGraphToCGraphTransformer/lambda$12$Type",1677),lAn(1681,1,hVn,Er),EWn.td=function(n){gfn(_B(n,57))},gX(C1n,"LGraphToCGraphTransformer/lambda$13$Type",1681),lAn(1678,1,hVn,yd),EWn.td=function(n){cA(this.a,_B(n,8))},EWn.a=0,gX(C1n,"LGraphToCGraphTransformer/lambda$14$Type",1678),lAn(1679,1,hVn,kd),EWn.td=function(n){uA(this.a,_B(n,110))},EWn.a=0,gX(C1n,"LGraphToCGraphTransformer/lambda$15$Type",1679),lAn(1680,1,hVn,jd),EWn.td=function(n){aA(this.a,_B(n,8))},EWn.a=0,gX(C1n,"LGraphToCGraphTransformer/lambda$16$Type",1680),lAn(1682,1,{},Tr),EWn.Kb=function(n){return H_(),new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(C1n,"LGraphToCGraphTransformer/lambda$17$Type",1682),lAn(1683,1,NVn,Mr),EWn.Mb=function(n){return H_(),f5(_B(n,17))},gX(C1n,"LGraphToCGraphTransformer/lambda$18$Type",1683),lAn(1684,1,hVn,Ed),EWn.td=function(n){Tnn(this.a,_B(n,17))},gX(C1n,"LGraphToCGraphTransformer/lambda$19$Type",1684),lAn(1668,1,hVn,Td),EWn.td=function(n){h0(this.a,_B(n,145))},gX(C1n,"LGraphToCGraphTransformer/lambda$2$Type",1668),lAn(1685,1,{},Sr),EWn.Kb=function(n){return H_(),new xq(null,new l1(_B(n,29).a,16))},gX(C1n,"LGraphToCGraphTransformer/lambda$20$Type",1685),lAn(1686,1,{},Pr),EWn.Kb=function(n){return H_(),new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(C1n,"LGraphToCGraphTransformer/lambda$21$Type",1686),lAn(1687,1,{},Ir),EWn.Kb=function(n){return H_(),_B(pMn(_B(n,17),(oWn(),$lt)),15)},gX(C1n,"LGraphToCGraphTransformer/lambda$22$Type",1687),lAn(1688,1,NVn,Cr),EWn.Mb=function(n){return ZN(_B(n,15))},gX(C1n,"LGraphToCGraphTransformer/lambda$23$Type",1688),lAn(1689,1,hVn,Md),EWn.td=function(n){MIn(this.a,_B(n,15))},gX(C1n,"LGraphToCGraphTransformer/lambda$24$Type",1689),lAn(1667,1,hVn,aP),EWn.td=function(n){F3(this.a,this.b,_B(n,145))},gX(C1n,"LGraphToCGraphTransformer/lambda$3$Type",1667),lAn(1669,1,{},Or),EWn.Kb=function(n){return H_(),new xq(null,new l1(_B(n,29).a,16))},gX(C1n,"LGraphToCGraphTransformer/lambda$4$Type",1669),lAn(1670,1,{},Ar),EWn.Kb=function(n){return H_(),new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(C1n,"LGraphToCGraphTransformer/lambda$5$Type",1670),lAn(1671,1,{},$r),EWn.Kb=function(n){return H_(),_B(pMn(_B(n,17),(oWn(),$lt)),15)},gX(C1n,"LGraphToCGraphTransformer/lambda$6$Type",1671),lAn(1673,1,hVn,Sd),EWn.td=function(n){DCn(this.a,_B(n,15))},gX(C1n,"LGraphToCGraphTransformer/lambda$8$Type",1673),lAn(1674,1,hVn,uP),EWn.td=function(n){L$(this.a,this.b,_B(n,145))},gX(C1n,"LGraphToCGraphTransformer/lambda$9$Type",1674),lAn(1663,1,{},Lr),EWn.Le=function(n){var t,e,i,r,c;for(this.a=n,this.d=new Kv,this.c=L8(Bit,FWn,121,this.a.a.a.c.length,0,1),this.b=0,e=new Ub(this.a.a.a);e.a=g&&(UB(a,tln(f)),m=i.Math.max(m,y[f-1]-l),o+=d,p+=y[f-1]-p,l=y[f-1],d=s[f]),d=i.Math.max(d,s[f]),++f;o+=d}(w=i.Math.min(1/m,1/t.b/o))>r&&(r=w,e=a)}return e},EWn.Wf=function(){return!1},gX(R1n,"MSDCutIndexHeuristic",802),lAn(1617,1,YZn,Sc),EWn.pf=function(n,t){fBn(_B(n,37),t)},gX(R1n,"SingleEdgeGraphWrapper",1617),lAn(227,22,{3:1,35:1,22:1,227:1},yP);var eht,iht,rht,cht=_en(K1n,"CenterEdgeLabelPlacementStrategy",227,Gnt,J8,U_);lAn(422,22,{3:1,35:1,22:1,422:1},kP);var aht,uht,oht,sht,hht=_en(K1n,"ConstraintCalculationStrategy",422,Gnt,HJ,X_);lAn(314,22,{3:1,35:1,22:1,314:1,246:1,234:1},jP),EWn.Kf=function(){return uCn(this)},EWn.Xf=function(){return uCn(this)};var fht,lht,bht,wht,dht=_en(K1n,"CrossingMinimizationStrategy",314,Gnt,j1,W_);lAn(337,22,{3:1,35:1,22:1,337:1},EP);var ght,pht,vht,mht,yht,kht,jht=_en(K1n,"CuttingStrategy",337,Gnt,E1,J_);lAn(335,22,{3:1,35:1,22:1,335:1,246:1,234:1},TP),EWn.Kf=function(){return xAn(this)},EWn.Xf=function(){return xAn(this)};var Eht,Tht,Mht,Sht=_en(K1n,"CycleBreakingStrategy",335,Gnt,A5,Y_);lAn(419,22,{3:1,35:1,22:1,419:1},MP);var Pht,Iht,Cht,Oht,Aht=_en(K1n,"DirectionCongruency",419,Gnt,BJ,Z_);lAn(450,22,{3:1,35:1,22:1,450:1},SP);var $ht,Lht,Nht,xht,Dht,Rht,Kht,_ht=_en(K1n,"EdgeConstraint",450,Gnt,T1,nF);lAn(276,22,{3:1,35:1,22:1,276:1},PP);var Fht,Bht,Hht,qht=_en(K1n,"EdgeLabelSideSelection",276,Gnt,t9,tF);lAn(479,22,{3:1,35:1,22:1,479:1},IP);var Ght,zht,Uht,Xht,Wht,Vht,Qht,Jht=_en(K1n,"EdgeStraighteningStrategy",479,Gnt,FJ,eF);lAn(274,22,{3:1,35:1,22:1,274:1},CP);var Yht,Zht,nft,tft,eft,ift,rft,cft=_en(K1n,"FixedAlignment",274,Gnt,Z8,iF);lAn(275,22,{3:1,35:1,22:1,275:1},OP);var aft,uft,oft,sft,hft,fft,lft,bft,wft,dft,gft,pft=_en(K1n,"GraphCompactionStrategy",275,Gnt,Y8,rF);lAn(256,22,{3:1,35:1,22:1,256:1},AP);var vft,mft,yft,kft,jft=_en(K1n,"GraphProperties",256,Gnt,fcn,cF);lAn(292,22,{3:1,35:1,22:1,292:1},$P);var Eft,Tft,Mft,Sft,Pft=_en(K1n,"GreedySwitchType",292,Gnt,P1,aF);lAn(303,22,{3:1,35:1,22:1,303:1},LP);var Ift,Cft,Oft,Aft=_en(K1n,"InLayerConstraint",303,Gnt,S1,uF);lAn(420,22,{3:1,35:1,22:1,420:1},NP);var $ft,Lft,Nft,xft,Dft,Rft,Kft,_ft,Fft,Bft,Hft,qft,Gft,zft,Uft,Xft,Wft,Vft,Qft,Jft,Yft,Zft,nlt,tlt,elt,ilt,rlt,clt,alt,ult,olt,slt,hlt,flt,llt,blt,wlt,dlt,glt,plt,vlt,mlt,ylt,klt,jlt,Elt,Tlt,Mlt,Slt,Plt,Ilt,Clt,Olt,Alt,$lt,Llt,Nlt,xlt,Dlt,Rlt,Klt,_lt,Flt,Blt,Hlt=_en(K1n,"InteractiveReferencePoint",420,Gnt,qJ,oF);lAn(163,22,{3:1,35:1,22:1,163:1},_P);var qlt,Glt,zlt,Ult,Xlt,Wlt,Vlt,Qlt,Jlt,Ylt,Zlt,nbt,tbt,ebt,ibt,rbt,cbt,abt,ubt,obt,sbt,hbt,fbt,lbt,bbt,wbt,dbt,gbt,pbt,vbt,mbt,ybt,kbt,jbt,Ebt,Tbt,Mbt,Sbt,Pbt,Ibt,Cbt,Obt,Abt,$bt,Lbt,Nbt,xbt,Dbt,Rbt,Kbt,_bt,Fbt,Bbt,Hbt,qbt,Gbt,zbt,Ubt,Xbt,Wbt,Vbt,Qbt,Jbt,Ybt,Zbt,nwt,twt,ewt,iwt,rwt,cwt,awt,uwt,owt,swt,hwt,fwt,lwt,bwt,wwt,dwt,gwt,pwt,vwt,mwt,ywt,kwt,jwt,Ewt,Twt,Mwt,Swt,Pwt,Iwt,Cwt,Owt,Awt,$wt,Lwt,Nwt,xwt,Dwt,Rwt,Kwt,_wt,Fwt,Bwt,Hwt,qwt,Gwt,zwt,Uwt,Xwt,Wwt,Vwt,Qwt,Jwt,Ywt,Zwt,ndt,tdt,edt,idt,rdt,cdt,adt,udt,odt,sdt,hdt,fdt,ldt,bdt,wdt,ddt,gdt,pdt,vdt,mdt,ydt,kdt,jdt,Edt,Tdt,Mdt,Sdt,Pdt,Idt,Cdt,Odt,Adt,$dt,Ldt,Ndt,xdt,Ddt,Rdt,Kdt,_dt,Fdt,Bdt,Hdt,qdt,Gdt,zdt,Udt,Xdt,Wdt,Vdt,Qdt,Jdt,Ydt,Zdt,ngt,tgt,egt,igt,rgt,cgt,agt,ugt,ogt,sgt,hgt,fgt,lgt,bgt,wgt,dgt,ggt,pgt,vgt,mgt,ygt,kgt,jgt,Egt,Tgt,Mgt,Sgt,Pgt,Igt,Cgt,Ogt,Agt,$gt,Lgt,Ngt,xgt,Dgt,Rgt,Kgt,_gt,Fgt,Bgt,Hgt,qgt,Ggt,zgt,Ugt,Xgt,Wgt,Vgt,Qgt,Jgt,Ygt,Zgt,npt,tpt,ept,ipt,rpt,cpt,apt,upt,opt,spt,hpt,fpt,lpt,bpt,wpt,dpt,gpt,ppt,vpt,mpt,ypt,kpt,jpt,Ept,Tpt,Mpt,Spt,Ppt,Ipt,Cpt,Opt,Apt,$pt,Lpt,Npt,xpt,Dpt,Rpt,Kpt,_pt,Fpt,Bpt,Hpt,qpt,Gpt,zpt,Upt,Xpt,Wpt,Vpt,Qpt,Jpt,Ypt,Zpt,nvt,tvt=_en(K1n,"LayerConstraint",163,Gnt,N5,sF);lAn(848,1,WJn,of),EWn.Qe=function(n){Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,G1n),""),"Direction Congruency"),"Specifies how drawings of the same graph with different layout directions compare to each other: either a natural reading direction is preserved or the drawings are rotated versions of each other."),Mbt),(MPn(),wMt)),Aht),Yln((epn(),oMt))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,z1n),""),"Feedback Edges"),"Whether feedback edges should be highlighted by routing around the nodes."),(oN(),!1)),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,U1n),""),"Interactive Reference Point"),"Determines which point of a node is considered by interactive layout phases."),Wbt),wMt),Hlt),Yln(oMt)))),r2(n,U1n,n0n,Qbt),r2(n,U1n,h0n,Vbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,X1n),""),"Merge Edges"),"Edges that have no ports are merged so they touch the connected nodes at the same points. When this option is disabled, one port is created for each edge directly connected to a node. When it is enabled, all such incoming edges share an input port, and all outgoing edges share an output port."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,W1n),""),"Merge Hierarchy-Crossing Edges"),"If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports as possible. They are broken by the algorithm, with hierarchical ports inserted as required. Usually, one such port is created for each edge at each hierarchy crossing point. With this option set to true, we try to create as few hierarchical ports as possible in the process. In particular, all edges that form a hyperedge can share a port."),!0),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Mj(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,V1n),""),"Allow Non-Flow Ports To Switch Sides"),"Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. Further note that the underlying criterium whether to switch sides or not solely relies on the minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed."),!1),lMt),mtt),Yln(sMt)),Mun(Hk(Wtt,1),uVn,2,6,["org.eclipse.elk.layered.northOrSouthPort"])))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Q1n),""),"Port Sorting Strategy"),"Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes."),Lwt),wMt),qvt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,J1n),""),"Thoroughness"),"How much effort should be spent to produce a nice layout."),tln(7)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Y1n),""),"Add Unnecessary Bendpoints"),"Adds bend points even if an edge does not change direction. If true, each long edge dummy will contribute a bend point to its edges and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries. By default, bend points are only added where an edge changes direction."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Z1n),""),"Generate Position and Layer IDs"),"If enabled position id and layer id are generated, which are usually only used internally when setting the interactiveLayout option. This option should be specified on the root node."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,n0n),"cycleBreaking"),"Cycle Breaking Strategy"),"Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles. Reversed edges will end up pointing to the opposite direction of regular edges (that is, reversed edges will point left if edges usually point right)."),Ebt),wMt),Sht),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,t0n),s2n),"Node Layering Strategy"),"Strategy for node layering."),fwt),wMt),avt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,e0n),s2n),"Layer Constraint"),"Determines a constraint on the placement of the node regarding the layering."),twt),wMt),tvt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,i0n),s2n),"Layer Choice Constraint"),"Allows to set a constraint regarding the layer placement of a node. Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. If set to i, it expresses that the node should be placed in i-th layer. Should i>=n be true then the node is placed in the last layer of the drawing. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),tln(-1)),gMt),Ctt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,r0n),s2n),"Layer ID"),"Layer identifier that was calculated by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),tln(-1)),gMt),Ctt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,c0n),h2n),"Upper Bound On Width [MinWidth Layerer]"),"Defines a loose upper bound on the width of the MinWidth layerer. If set to '-1' multiple values are tested and the best result is selected."),tln(4)),gMt),Ctt),Yln(oMt)))),r2(n,c0n,t0n,rwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,a0n),h2n),"Upper Layer Estimation Scaling Factor [MinWidth Layerer]"),"Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth algorithm. Compensates for too high estimations. If set to '-1' multiple values are tested and the best result is selected."),tln(2)),gMt),Ctt),Yln(oMt)))),r2(n,a0n,t0n,awt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,u0n),f2n),"Node Promotion Strategy"),"Reduces number of dummy nodes after layering phase (if possible)."),swt),wMt),Nvt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,o0n),f2n),"Max Node Promotion Iterations"),"Limits the number of iterations for node promotion."),tln(0)),gMt),Ctt),Yln(oMt)))),r2(n,o0n,u0n,null),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,s0n),"layering.coffmanGraham"),"Layer Bound"),"The maximum number of nodes allowed per layer."),tln(NWn)),gMt),Ctt),Yln(oMt)))),r2(n,s0n,t0n,Ybt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,h0n),l2n),"Crossing Minimization Strategy"),"Strategy for crossing minimization."),kbt),wMt),dht),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,f0n),l2n),"Force Node Model Order"),"The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,l0n),l2n),"Hierarchical Sweepiness"),"How likely it is to use cross-hierarchy (1) vs bottom-up (-1)."),.1),bMt),Mtt),Yln(oMt)))),r2(n,l0n,b2n,dbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,b0n),l2n),"Semi-Interactive Crossing Minimization"),"Preserves the order of nodes within a layer but still minimizes crossings between edges connecting long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints."),!1),lMt),mtt),Yln(oMt)))),r2(n,b0n,h0n,mbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,w0n),l2n),"Position Choice Constraint"),"Allows to set a constraint regarding the position placement of a node in a layer. Assumed the layer in which the node placed includes n other nodes and i < n. If set to i, it expresses that the node should be placed at the i-th position. Should i>=n be true then the node is placed at the last position in the layer. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),tln(-1)),gMt),Ctt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,d0n),l2n),"Position ID"),"Position within a layer that was determined by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),tln(-1)),gMt),Ctt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,g0n),w2n),"Greedy Switch Activation Threshold"),"By default it is decided automatically if the greedy switch is activated or not. The decision is based on whether the size of the input graph (without dummy nodes) is smaller than the value of this option. A '0' enforces the activation."),tln(40)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,p0n),w2n),"Greedy Switch Crossing Minimization"),"Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed after the regular crossing minimization as a post-processor. Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' option must be used."),lbt),wMt),Pft),Yln(oMt)))),r2(n,p0n,h0n,bbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,v0n),"crossingMinimization.greedySwitchHierarchical"),"Greedy Switch Crossing Minimization (hierarchical)"),"Activates the greedy switch heuristic in case hierarchical layout is used. The differences to the non-hierarchical case (see 'greedySwitch.type') are: 1) greedy switch is inactive by default, 3) only the option value set on the node at which hierarchical layout starts is relevant, and 2) if it's activated by the user, it properly addresses hierarchy-crossing edges."),obt),wMt),Pft),Yln(oMt)))),r2(n,v0n,h0n,sbt),r2(n,v0n,b2n,hbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,m0n),d2n),"Node Placement Strategy"),"Strategy for node placement."),Awt),wMt),Cvt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,y0n),d2n),"Favor Straight Edges Over Balancing"),"Favor straight edges over a balanced node placement. The default behavior is determined automatically based on the used 'edgeRouting'. For an orthogonal style it is set to true, for all other styles to false."),lMt),mtt),Yln(oMt)))),r2(n,y0n,m0n,kwt),r2(n,y0n,m0n,jwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,k0n),g2n),"BK Edge Straightening"),"Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges at the expense of diagram size. There is a subtle difference to the 'favorStraightEdges' option, which decides whether a balanced placement of the nodes is desired, or not. In bk terms this means combining the four alignments into a single balanced one, or not. This option on the other hand tries to straighten additional edges during the creation of each of the four alignments."),dwt),wMt),Jht),Yln(oMt)))),r2(n,k0n,m0n,gwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,j0n),g2n),"BK Fixed Alignment"),"Tells the BK node placer to use a certain alignment (out of its four) instead of the one producing the smallest height, or the combination of all four."),vwt),wMt),cft),Yln(oMt)))),r2(n,j0n,m0n,mwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,E0n),"nodePlacement.linearSegments"),"Linear Segments Deflection Dampening"),"Dampens the movement of nodes to keep the diagram from getting too large."),.3),bMt),Mtt),Yln(oMt)))),r2(n,E0n,m0n,Twt),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,T0n),"nodePlacement.networkSimplex"),"Node Flexibility"),"Aims at shorter and straighter edges. Two configurations are possible: (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), (b) additionally allow to enlarge a node wherever it helps. If this option is not configured for a node, the 'nodeFlexibility.default' value is used, which is specified for the node's parent."),wMt),mvt),Yln(uMt)))),r2(n,T0n,m0n,Cwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,M0n),"nodePlacement.networkSimplex.nodeFlexibility"),"Node Flexibility Default"),"Default value of the 'nodeFlexibility' option for the children of a hierarchical node."),Pwt),wMt),mvt),Yln(oMt)))),r2(n,M0n,m0n,Iwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,S0n),p2n),"Self-Loop Distribution"),"Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE."),Lbt),wMt),Yvt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,P0n),p2n),"Self-Loop Ordering"),"Alter the ordering of the loops they can either be stacked or sequenced. It only takes effect for PortConstraints.FREE."),xbt),wMt),imt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,I0n),"edgeRouting.splines"),"Spline Routing Mode"),"Specifies the way control points are assembled for each individual edge. CONSERVATIVE ensures that edges are properly routed around the nodes but feels rather orthogonal at times. SLOPPY uses fewer control points to obtain curvier edge routes but may result in edges overlapping nodes."),Rbt),wMt),omt),Yln(oMt)))),r2(n,I0n,v2n,Kbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,C0n),"edgeRouting.splines.sloppy"),"Sloppy Spline Layer Spacing Factor"),"Spacing factor for routing area between layers when using sloppy spline routing."),.2),bMt),Mtt),Yln(oMt)))),r2(n,C0n,v2n,Fbt),r2(n,C0n,I0n,Bbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,O0n),"edgeRouting.polyline"),"Sloped Edge Zone Width"),"Width of the strip to the left and to the right of each layer where the polyline edge router is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward bend points for nodes that extent almost to the edge of their layer."),2),bMt),Mtt),Yln(oMt)))),r2(n,O0n,v2n,Abt),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,A0n),m2n),"Spacing Base Value"),"An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout options, this base value will have no effect. The base value is not inherited, i.e. it must be set for each hierarchical node."),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,$0n),m2n),"Edge Node Between Layers Spacing"),"The spacing to be preserved between nodes and edges that are routed next to the node's layer. For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,L0n),m2n),"Edge Edge Between Layer Spacing"),"Spacing to be preserved between pairs of edges that are routed between the same pair of layers. Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,N0n),m2n),"Node Node Between Layers Spacing"),"The spacing to be preserved between any pair of nodes of two adjacent layers. Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself."),20),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,x0n),y2n),"Direction Priority"),"Defines how important it is to have a certain edge point into the direction of the overall layout. This option is evaluated during the cycle breaking phase."),tln(0)),gMt),Ctt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,D0n),y2n),"Shortness Priority"),"Defines how important it is to keep an edge as short as possible. This option is evaluated during the layering phase."),tln(0)),gMt),Ctt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,R0n),y2n),"Straightness Priority"),"Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. This option is evaluated during node placement."),tln(0)),gMt),Ctt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,K0n),k2n),NYn),"Tries to further compact components (disconnected sub-graphs)."),!1),lMt),mtt),Yln(oMt)))),r2(n,K0n,mZn,!0),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,_0n),j2n),"Post Compaction Strategy"),E2n),Vlt),wMt),pft),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,F0n),j2n),"Post Compaction Constraint Calculation"),E2n),Xlt),wMt),hht),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,B0n),T2n),"High Degree Node Treatment"),"Makes room around high degree nodes to place leafs and trees."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,H0n),T2n),"High Degree Node Threshold"),"Whether a node is considered to have a high degree."),tln(16)),gMt),Ctt),Yln(oMt)))),r2(n,H0n,B0n,!0),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,q0n),T2n),"High Degree Node Maximum Tree Height"),"Maximum height of a subtree connected to a high degree node to be moved to separate layers."),tln(5)),gMt),Ctt),Yln(oMt)))),r2(n,q0n,B0n,!0),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,G0n),M2n),"Graph Wrapping Strategy"),"For certain graphs and certain prescribed drawing areas it may be desirable to split the laid out graph into chunks that are placed side by side. The edges that connect different chunks are 'wrapped' around from the end of one chunk to the start of the other chunk. The points between the chunks are referred to as 'cuts'."),fdt),wMt),Tmt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,z0n),M2n),"Additional Wrapped Edges Spacing"),"To visually separate edges that are wrapped from regularly routed edges an additional spacing value can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing."),10),bMt),Mtt),Yln(oMt)))),r2(n,z0n,G0n,Gwt),r2(n,z0n,G0n,zwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,U0n),M2n),"Correction Factor for Wrapping"),"At times and for certain types of graphs the executed wrapping may produce results that are consistently biased in the same fashion: either wrapping to often or to rarely. This factor can be used to correct the bias. Internally, it is simply multiplied with the 'aspect ratio' layout option."),1),bMt),Mtt),Yln(oMt)))),r2(n,U0n,G0n,Xwt),r2(n,U0n,G0n,Wwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,X0n),S2n),"Cutting Strategy"),"The strategy by which the layer indexes are determined at which the layering crumbles into chunks."),tdt),wMt),jht),Yln(oMt)))),r2(n,X0n,G0n,edt),r2(n,X0n,G0n,idt),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,W0n),S2n),"Manually Specified Cuts"),"Allows the user to specify her own cuts for a certain graph."),pMt),xnt),Yln(oMt)))),r2(n,W0n,X0n,Qwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,V0n),"wrapping.cutting.msd"),"MSD Freedom"),"The MSD cutting strategy starts with an initial guess on the number of chunks the graph should be split into. The freedom specifies how much the strategy may deviate from this guess. E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts."),Ywt),gMt),Ctt),Yln(oMt)))),r2(n,V0n,X0n,Zwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Q0n),P2n),"Validification Strategy"),"When wrapping graphs, one can specify indices that are not allowed as split points. The validification strategy makes sure every computed split point is allowed."),gdt),wMt),bmt),Yln(oMt)))),r2(n,Q0n,G0n,pdt),r2(n,Q0n,G0n,vdt),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,J0n),P2n),"Valid Indices for Wrapping"),null),pMt),xnt),Yln(oMt)))),r2(n,J0n,G0n,bdt),r2(n,J0n,G0n,wdt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Y0n),I2n),"Improve Cuts"),"For general graphs it is important that not too many edges wrap backwards. Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought."),!0),lMt),mtt),Yln(oMt)))),r2(n,Y0n,G0n,udt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Z0n),I2n),"Distance Penalty When Improving Cuts"),null),2),bMt),Mtt),Yln(oMt)))),r2(n,Z0n,G0n,cdt),r2(n,Z0n,Y0n,!0),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,n2n),I2n),"Improve Wrapped Edges"),"The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges."),!0),lMt),mtt),Yln(oMt)))),r2(n,n2n,G0n,sdt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,t2n),C2n),"Edge Label Side Selection"),"Method to decide on edge label sides."),Cbt),wMt),qht),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,e2n),C2n),"Edge Center Label Placement Strategy"),"Determines in which layer center labels of long edges should be placed."),Pbt),wMt),cht),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,i2n),O2n),"Consider Model Order"),"Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting."),rbt),wMt),Kvt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,r2n),O2n),"No Model Order"),"Set on a node to not set a model order for this node even though it is a real node."),!1),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,c2n),O2n),"Consider Model Order for Components"),"If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub optimal drawings in terms of used area since the ordering should be respected."),Jlt),wMt),put),Yln(oMt)))),r2(n,c2n,mZn,null),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,a2n),O2n),"Long Edge Ordering Strategy"),"Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a vertical layout."),tbt),wMt),lvt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,u2n),O2n),"Crossing Counter Node Order Influence"),"Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no influence (0)."),0),bMt),Mtt),Yln(oMt)))),r2(n,u2n,i2n,null),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,o2n),O2n),"Crossing Counter Port Order Influence"),"Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no influence (0)."),0),bMt),Mtt),Yln(oMt)))),r2(n,o2n,i2n,null),gWn((new ff,n))},gX(K1n,"LayeredMetaDataProvider",848),lAn(986,1,WJn,ff),EWn.Qe=function(n){gWn(n)},gX(K1n,"LayeredOptions",986),lAn(987,1,{},Ic),EWn.$e=function(){return new Gv},EWn._e=function(n){},gX(K1n,"LayeredOptions/LayeredFactory",987),lAn(1372,1,{}),EWn.a=0,gX(v3n,"ElkSpacings/AbstractSpacingsBuilder",1372),lAn(779,1372,{},cwn),gX(K1n,"LayeredSpacings/LayeredSpacingsBuilder",779),lAn(313,22,{3:1,35:1,22:1,313:1,246:1,234:1},xP),EWn.Kf=function(){return eLn(this)},EWn.Xf=function(){return eLn(this)};var evt,ivt,rvt,cvt,avt=_en(K1n,"LayeringStrategy",313,Gnt,n9,hF);lAn(378,22,{3:1,35:1,22:1,378:1},DP);var uvt,ovt,svt,hvt,fvt,lvt=_en(K1n,"LongEdgeOrderingStrategy",378,Gnt,k1,fF);lAn(197,22,{3:1,35:1,22:1,197:1},RP);var bvt,wvt,dvt,gvt,pvt,vvt,mvt=_en(K1n,"NodeFlexibility",197,Gnt,m3,lF);lAn(315,22,{3:1,35:1,22:1,315:1,246:1,234:1},KP),EWn.Kf=function(){return NAn(this)},EWn.Xf=function(){return NAn(this)};var yvt,kvt,jvt,Evt,Tvt,Mvt,Svt,Pvt,Ivt,Cvt=_en(K1n,"NodePlacementStrategy",315,Gnt,O5,vF);lAn(260,22,{3:1,35:1,22:1,260:1},FP);var Ovt,Avt,$vt,Lvt,Nvt=_en(K1n,"NodePromotionStrategy",260,Gnt,_tn,wF);lAn(339,22,{3:1,35:1,22:1,339:1},BP);var xvt,Dvt,Rvt,Kvt=_en(K1n,"OrderingStrategy",339,Gnt,C1,dF);lAn(421,22,{3:1,35:1,22:1,421:1},HP);var _vt,Fvt,Bvt,Hvt,qvt=_en(K1n,"PortSortingStrategy",421,Gnt,GJ,gF);lAn(452,22,{3:1,35:1,22:1,452:1},qP);var Gvt,zvt,Uvt,Xvt,Wvt=_en(K1n,"PortType",452,Gnt,I1,bF);lAn(375,22,{3:1,35:1,22:1,375:1},GP);var Vvt,Qvt,Jvt,Yvt=_en(K1n,"SelfLoopDistributionStrategy",375,Gnt,O1,pF);lAn(376,22,{3:1,35:1,22:1,376:1},zP);var Zvt,nmt,tmt,emt,imt=_en(K1n,"SelfLoopOrderingStrategy",376,Gnt,_J,mF);lAn(304,1,{304:1},uGn),gX(K1n,"Spacings",304),lAn(336,22,{3:1,35:1,22:1,336:1},UP);var rmt,cmt,amt,umt,omt=_en(K1n,"SplineRoutingMode",336,Gnt,$1,yF);lAn(338,22,{3:1,35:1,22:1,338:1},XP);var smt,hmt,fmt,lmt,bmt=_en(K1n,"ValidifyStrategy",338,Gnt,L1,kF);lAn(377,22,{3:1,35:1,22:1,377:1},WP);var wmt,dmt,gmt,pmt,vmt,mmt,ymt,kmt,jmt,Emt,Tmt=_en(K1n,"WrappingStrategy",377,Gnt,A1,jF);lAn(1383,1,k3n,lf),EWn.Yf=function(n){return _B(n,37),dmt},EWn.pf=function(n,t){QHn(this,_B(n,37),t)},gX(j3n,"DepthFirstCycleBreaker",1383),lAn(782,1,k3n,DG),EWn.Yf=function(n){return _B(n,37),gmt},EWn.pf=function(n,t){GXn(this,_B(n,37),t)},EWn.Zf=function(n){return _B(Lq(n,dvn(this.d,n.c.length)),10)},gX(j3n,"GreedyCycleBreaker",782),lAn(1386,782,k3n,jC),EWn.Zf=function(n){var t,e,i,r;for(r=null,t=NWn,i=new Ub(n);i.a1&&(By(jD(pMn(gW((h1(0,n.c.length),_B(n.c[0],10))),(FXn(),Ldt))))?x$n(n,this.d,_B(this,660)):(TQ(),p$(n,this.d)),_an(this.e,n))},EWn.Sf=function(n,t,e,i){var r,c,a,u,o,s,h;for(t!=Qq(e,n.length)&&(c=n[t-(e?1:-1)],H6(this.f,c,e?(rin(),Bvt):(rin(),Fvt))),r=n[t][0],h=!i||r.k==(cSn(),Eut),s=c6(n[t]),this.ag(s,h,!1,e),a=0,o=new Ub(s);o.a"),n0?cZ(this.a,n[t-1],n[t]):!e&&t1&&(By(jD(pMn(gW((h1(0,n.c.length),_B(n.c[0],10))),(FXn(),Ldt))))?x$n(n,this.d,this):(TQ(),p$(n,this.d)),By(jD(pMn(gW((h1(0,n.c.length),_B(n.c[0],10))),Ldt)))||_an(this.e,n))},gX(S3n,"ModelOrderBarycenterHeuristic",660),lAn(1803,1,EJn,Ud),EWn.ue=function(n,t){return DSn(this.a,_B(n,10),_B(t,10))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(S3n,"ModelOrderBarycenterHeuristic/lambda$0$Type",1803),lAn(1403,1,k3n,yf),EWn.Yf=function(n){var t;return _B(n,37),bq(t=mA(Nmt),(vMn(),Rat),(hWn(),_ot)),t},EWn.pf=function(n,t){pJ((_B(n,37),t))},gX(S3n,"NoCrossingMinimizer",1403),lAn(796,402,T3n,xj),EWn.$f=function(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;switch(f=this.g,e.g){case 1:for(r=0,c=0,h=new Ub(n.j);h.a1&&(r.j==(mUn(),aCt)?this.b[n]=!0:r.j==SCt&&n>0&&(this.b[n-1]=!0))},EWn.f=0,gX(A1n,"AllCrossingsCounter",1798),lAn(587,1,{},prn),EWn.b=0,EWn.d=0,gX(A1n,"BinaryIndexedTree",587),lAn(524,1,{},WK),gX(A1n,"CrossingsCounter",524),lAn(1906,1,EJn,Xd),EWn.ue=function(n,t){return zq(this.a,_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(A1n,"CrossingsCounter/lambda$0$Type",1906),lAn(1907,1,EJn,Wd),EWn.ue=function(n,t){return Uq(this.a,_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(A1n,"CrossingsCounter/lambda$1$Type",1907),lAn(1908,1,EJn,Vd),EWn.ue=function(n,t){return Xq(this.a,_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(A1n,"CrossingsCounter/lambda$2$Type",1908),lAn(1909,1,EJn,Qd),EWn.ue=function(n,t){return Wq(this.a,_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(A1n,"CrossingsCounter/lambda$3$Type",1909),lAn(1910,1,hVn,Jd),EWn.td=function(n){d7(this.a,_B(n,11))},gX(A1n,"CrossingsCounter/lambda$4$Type",1910),lAn(1911,1,NVn,Yd),EWn.Mb=function(n){return vC(this.a,_B(n,11))},gX(A1n,"CrossingsCounter/lambda$5$Type",1911),lAn(1912,1,hVn,Zd),EWn.td=function(n){pC(this,n)},gX(A1n,"CrossingsCounter/lambda$6$Type",1912),lAn(1913,1,hVn,JP),EWn.td=function(n){var t;oH(),b3(this.b,(t=this.a,_B(n,11),t))},gX(A1n,"CrossingsCounter/lambda$7$Type",1913),lAn(826,1,BJn,xc),EWn.Lb=function(n){return oH(),Ax(_B(n,11),(oWn(),klt))},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return oH(),Ax(_B(n,11),(oWn(),klt))},gX(A1n,"CrossingsCounter/lambda$8$Type",826),lAn(1905,1,{},ng),gX(A1n,"HyperedgeCrossingsCounter",1905),lAn(467,1,{35:1,467:1},NR),EWn.wd=function(n){return ggn(this,_B(n,467))},EWn.b=0,EWn.c=0,EWn.e=0,EWn.f=0;var Kmt=gX(A1n,"HyperedgeCrossingsCounter/Hyperedge",467);lAn(362,1,{35:1,362:1},BV),EWn.wd=function(n){return h$n(this,_B(n,362))},EWn.b=0,EWn.c=0;var _mt,Fmt,Bmt=gX(A1n,"HyperedgeCrossingsCounter/HyperedgeCorner",362);lAn(523,22,{3:1,35:1,22:1,523:1},QP);var Hmt,qmt,Gmt,zmt,Umt,Xmt=_en(A1n,"HyperedgeCrossingsCounter/HyperedgeCorner/Type",523,Gnt,zJ,TF);lAn(1405,1,k3n,hf),EWn.Yf=function(n){return _B(pMn(_B(n,37),(oWn(),Jft)),21).Hc((fDn(),hft))?qmt:null},EWn.pf=function(n,t){hjn(this,_B(n,37),t)},gX(P3n,"InteractiveNodePlacer",1405),lAn(1406,1,k3n,sf),EWn.Yf=function(n){return _B(pMn(_B(n,37),(oWn(),Jft)),21).Hc((fDn(),hft))?Gmt:null},EWn.pf=function(n,t){ymn(this,_B(n,37),t)},gX(P3n,"LinearSegmentsNodePlacer",1406),lAn(257,1,{35:1,257:1},em),EWn.wd=function(n){return cj(this,_B(n,257))},EWn.Fb=function(n){var t;return!!iL(n,257)&&(t=_B(n,257),this.b==t.b)},EWn.Hb=function(){return this.b},EWn.Ib=function(){return"ls"+AMn(this.e)},EWn.a=0,EWn.b=0,EWn.c=-1,EWn.d=-1,EWn.g=0;var Wmt,Vmt=gX(P3n,"LinearSegmentsNodePlacer/LinearSegment",257);lAn(1408,1,k3n,RG),EWn.Yf=function(n){return _B(pMn(_B(n,37),(oWn(),Jft)),21).Hc((fDn(),hft))?Wmt:null},EWn.pf=function(n,t){TXn(this,_B(n,37),t)},EWn.b=0,EWn.g=0,gX(P3n,"NetworkSimplexPlacer",1408),lAn(1427,1,EJn,Dc),EWn.ue=function(n,t){return k$(_B(n,19).a,_B(t,19).a)},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(P3n,"NetworkSimplexPlacer/0methodref$compare$Type",1427),lAn(1429,1,EJn,Rc),EWn.ue=function(n,t){return k$(_B(n,19).a,_B(t,19).a)},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(P3n,"NetworkSimplexPlacer/1methodref$compare$Type",1429),lAn(649,1,{649:1},YP);var Qmt=gX(P3n,"NetworkSimplexPlacer/EdgeRep",649);lAn(401,1,{401:1},HV),EWn.b=!1;var Jmt,Ymt,Zmt,nyt=gX(P3n,"NetworkSimplexPlacer/NodeRep",401);lAn(508,12,{3:1,4:1,20:1,28:1,52:1,12:1,14:1,15:1,54:1,508:1},cm),gX(P3n,"NetworkSimplexPlacer/Path",508),lAn(1409,1,{},Kc),EWn.Kb=function(n){return _B(n,17).d.i.k},gX(P3n,"NetworkSimplexPlacer/Path/lambda$0$Type",1409),lAn(1410,1,NVn,_c),EWn.Mb=function(n){return _B(n,267)==(cSn(),Mut)},gX(P3n,"NetworkSimplexPlacer/Path/lambda$1$Type",1410),lAn(1411,1,{},Fc),EWn.Kb=function(n){return _B(n,17).d.i},gX(P3n,"NetworkSimplexPlacer/Path/lambda$2$Type",1411),lAn(1412,1,NVn,tg),EWn.Mb=function(n){return FD(Zwn(_B(n,10)))},gX(P3n,"NetworkSimplexPlacer/Path/lambda$3$Type",1412),lAn(1413,1,NVn,Bc),EWn.Mb=function(n){return oq(_B(n,11))},gX(P3n,"NetworkSimplexPlacer/lambda$0$Type",1413),lAn(1414,1,hVn,ZP),EWn.td=function(n){N$(this.a,this.b,_B(n,11))},gX(P3n,"NetworkSimplexPlacer/lambda$1$Type",1414),lAn(1423,1,hVn,eg),EWn.td=function(n){UIn(this.a,_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$10$Type",1423),lAn(1424,1,{},Hc),EWn.Kb=function(n){return _Z(),new xq(null,new l1(_B(n,29).a,16))},gX(P3n,"NetworkSimplexPlacer/lambda$11$Type",1424),lAn(1425,1,hVn,ig),EWn.td=function(n){_Dn(this.a,_B(n,10))},gX(P3n,"NetworkSimplexPlacer/lambda$12$Type",1425),lAn(1426,1,{},qc),EWn.Kb=function(n){return _Z(),tln(_B(n,121).e)},gX(P3n,"NetworkSimplexPlacer/lambda$13$Type",1426),lAn(1428,1,{},Gc),EWn.Kb=function(n){return _Z(),tln(_B(n,121).e)},gX(P3n,"NetworkSimplexPlacer/lambda$15$Type",1428),lAn(1430,1,NVn,zc),EWn.Mb=function(n){return _Z(),_B(n,401).c.k==(cSn(),Sut)},gX(P3n,"NetworkSimplexPlacer/lambda$17$Type",1430),lAn(1431,1,NVn,Uc),EWn.Mb=function(n){return _Z(),_B(n,401).c.j.c.length>1},gX(P3n,"NetworkSimplexPlacer/lambda$18$Type",1431),lAn(1432,1,hVn,qV),EWn.td=function(n){iwn(this.c,this.b,this.d,this.a,_B(n,401))},EWn.c=0,EWn.d=0,gX(P3n,"NetworkSimplexPlacer/lambda$19$Type",1432),lAn(1415,1,{},Xc),EWn.Kb=function(n){return _Z(),new xq(null,new l1(_B(n,29).a,16))},gX(P3n,"NetworkSimplexPlacer/lambda$2$Type",1415),lAn(1433,1,hVn,rg),EWn.td=function(n){$$(this.a,_B(n,11))},EWn.a=0,gX(P3n,"NetworkSimplexPlacer/lambda$20$Type",1433),lAn(1434,1,{},Wc),EWn.Kb=function(n){return _Z(),new xq(null,new l1(_B(n,29).a,16))},gX(P3n,"NetworkSimplexPlacer/lambda$21$Type",1434),lAn(1435,1,hVn,cg),EWn.td=function(n){bL(this.a,_B(n,10))},gX(P3n,"NetworkSimplexPlacer/lambda$22$Type",1435),lAn(1436,1,NVn,Vc),EWn.Mb=function(n){return FD(n)},gX(P3n,"NetworkSimplexPlacer/lambda$23$Type",1436),lAn(1437,1,{},Qc),EWn.Kb=function(n){return _Z(),new xq(null,new l1(_B(n,29).a,16))},gX(P3n,"NetworkSimplexPlacer/lambda$24$Type",1437),lAn(1438,1,NVn,ag),EWn.Mb=function(n){return kO(this.a,_B(n,10))},gX(P3n,"NetworkSimplexPlacer/lambda$25$Type",1438),lAn(1439,1,hVn,nI),EWn.td=function(n){EPn(this.a,this.b,_B(n,10))},gX(P3n,"NetworkSimplexPlacer/lambda$26$Type",1439),lAn(1440,1,NVn,Jc),EWn.Mb=function(n){return _Z(),!f5(_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$27$Type",1440),lAn(1441,1,NVn,Yc),EWn.Mb=function(n){return _Z(),!f5(_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$28$Type",1441),lAn(1442,1,{},ug),EWn.Ce=function(n,t){return uL(this.a,_B(n,29),_B(t,29))},gX(P3n,"NetworkSimplexPlacer/lambda$29$Type",1442),lAn(1416,1,{},Zc),EWn.Kb=function(n){return _Z(),new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(P3n,"NetworkSimplexPlacer/lambda$3$Type",1416),lAn(1417,1,NVn,na),EWn.Mb=function(n){return _Z(),Z0(_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$4$Type",1417),lAn(1418,1,hVn,og),EWn.td=function(n){tBn(this.a,_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$5$Type",1418),lAn(1419,1,{},ta),EWn.Kb=function(n){return _Z(),new xq(null,new l1(_B(n,29).a,16))},gX(P3n,"NetworkSimplexPlacer/lambda$6$Type",1419),lAn(1420,1,NVn,ea),EWn.Mb=function(n){return _Z(),_B(n,10).k==(cSn(),Sut)},gX(P3n,"NetworkSimplexPlacer/lambda$7$Type",1420),lAn(1421,1,{},ia),EWn.Kb=function(n){return _Z(),new xq(null,new qU(new az(JL(obn(_B(n,10)).a.Kc(),new h))))},gX(P3n,"NetworkSimplexPlacer/lambda$8$Type",1421),lAn(1422,1,NVn,ra),EWn.Mb=function(n){return _Z(),GH(_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$9$Type",1422),lAn(1404,1,k3n,Sf),EWn.Yf=function(n){return _B(pMn(_B(n,37),(oWn(),Jft)),21).Hc((fDn(),hft))?Jmt:null},EWn.pf=function(n,t){mHn(_B(n,37),t)},gX(P3n,"SimpleNodePlacer",1404),lAn(180,1,{180:1},BKn),EWn.Ib=function(){var n;return n="",this.c==(wY(),Zmt)?n+=rYn:this.c==Ymt&&(n+=iYn),this.o==(aZ(),eyt)?n+=dYn:this.o==iyt?n+="UP":n+="BALANCED",n},gX(O3n,"BKAlignedLayout",180),lAn(516,22,{3:1,35:1,22:1,516:1},iI);var tyt,eyt,iyt,ryt=_en(O3n,"BKAlignedLayout/HDirection",516,Gnt,XJ,MF);lAn(515,22,{3:1,35:1,22:1,515:1},eI);var cyt,ayt,uyt,oyt,syt,hyt,fyt,lyt,byt,wyt,dyt,gyt,pyt,vyt,myt,yyt,kyt,jyt,Eyt,Tyt=_en(O3n,"BKAlignedLayout/VDirection",515,Gnt,WJ,SF);lAn(1634,1,{},tI),gX(O3n,"BKAligner",1634),lAn(1637,1,{},Qyn),gX(O3n,"BKCompactor",1637),lAn(654,1,{654:1},ca),EWn.a=0,gX(O3n,"BKCompactor/ClassEdge",654),lAn(458,1,{458:1},im),EWn.a=null,EWn.b=0,gX(O3n,"BKCompactor/ClassNode",458),lAn(1407,1,k3n,yC),EWn.Yf=function(n){return _B(pMn(_B(n,37),(oWn(),Jft)),21).Hc((fDn(),hft))?ayt:null},EWn.pf=function(n,t){eWn(this,_B(n,37),t)},EWn.d=!1,gX(O3n,"BKNodePlacer",1407),lAn(1635,1,{},aa),EWn.d=0,gX(O3n,"NeighborhoodInformation",1635),lAn(1636,1,EJn,sg),EWn.ue=function(n,t){return Etn(this,_B(n,46),_B(t,46))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(O3n,"NeighborhoodInformation/NeighborComparator",1636),lAn(808,1,{}),gX(O3n,"ThresholdStrategy",808),lAn(1763,808,{},bm),EWn.bg=function(n,t,e){return this.a.o==(aZ(),iyt)?xQn:DQn},EWn.cg=function(){},gX(O3n,"ThresholdStrategy/NullThresholdStrategy",1763),lAn(579,1,{579:1},rI),EWn.c=!1,EWn.d=!1,gX(O3n,"ThresholdStrategy/Postprocessable",579),lAn(1764,808,{},wm),EWn.bg=function(n,t,e){var i,r,c;return r=t==e,i=this.a.a[e.p]==t,r||i?(c=n,this.a.c,wY(),r&&(c=jHn(this,t,!0)),!isNaN(c)&&!isFinite(c)&&i&&(c=jHn(this,e,!1)),c):n},EWn.cg=function(){for(var n,t,e;0!=this.d.b;)(t=iFn(this,e=_B(MY(this.d),579))).a&&(n=t.a,(By(this.a.f[this.a.g[e.b.p].p])||f5(n)||n.c.i.c!=n.d.i.c)&&(f$n(this,e)||eA(this.e,e)));for(;0!=this.e.a.c.length;)f$n(this,_B(Zsn(this.e),579))},gX(O3n,"ThresholdStrategy/SimpleThresholdStrategy",1764),lAn(635,1,{635:1,246:1,234:1},ua),EWn.Kf=function(){return jan(this)},EWn.Xf=function(){return jan(this)},gX(A3n,"EdgeRouterFactory",635),lAn(1458,1,k3n,Pf),EWn.Yf=function(n){return Gxn(_B(n,37))},EWn.pf=function(n,t){NHn(_B(n,37),t)},gX(A3n,"OrthogonalEdgeRouter",1458),lAn(1451,1,k3n,kC),EWn.Yf=function(n){return kjn(_B(n,37))},EWn.pf=function(n,t){IUn(this,_B(n,37),t)},gX(A3n,"PolylineEdgeRouter",1451),lAn(1452,1,BJn,oa),EWn.Lb=function(n){return Wan(_B(n,10))},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return Wan(_B(n,10))},gX(A3n,"PolylineEdgeRouter/1",1452),lAn(1809,1,NVn,sa),EWn.Mb=function(n){return _B(n,129).c==(I6(),jyt)},gX($3n,"HyperEdgeCycleDetector/lambda$0$Type",1809),lAn(1810,1,{},ha),EWn.Ge=function(n){return _B(n,129).d},gX($3n,"HyperEdgeCycleDetector/lambda$1$Type",1810),lAn(1811,1,NVn,fa),EWn.Mb=function(n){return _B(n,129).c==(I6(),jyt)},gX($3n,"HyperEdgeCycleDetector/lambda$2$Type",1811),lAn(1812,1,{},la),EWn.Ge=function(n){return _B(n,129).d},gX($3n,"HyperEdgeCycleDetector/lambda$3$Type",1812),lAn(1813,1,{},ba),EWn.Ge=function(n){return _B(n,129).d},gX($3n,"HyperEdgeCycleDetector/lambda$4$Type",1813),lAn(1814,1,{},wa),EWn.Ge=function(n){return _B(n,129).d},gX($3n,"HyperEdgeCycleDetector/lambda$5$Type",1814),lAn(112,1,{35:1,112:1},Kan),EWn.wd=function(n){return aj(this,_B(n,112))},EWn.Fb=function(n){var t;return!!iL(n,112)&&(t=_B(n,112),this.g==t.g)},EWn.Hb=function(){return this.g},EWn.Ib=function(){var n,t,e,i;for(n=new hN("{"),i=new Ub(this.n);i.a"+this.b+" ("+lx(this.c)+")"},EWn.d=0,gX($3n,"HyperEdgeSegmentDependency",129),lAn(520,22,{3:1,35:1,22:1,520:1},cI);var Myt,Syt,Pyt,Iyt,Cyt,Oyt,Ayt,$yt,Lyt=_en($3n,"HyperEdgeSegmentDependency/DependencyType",520,Gnt,UJ,PF);lAn(1815,1,{},hg),gX($3n,"HyperEdgeSegmentSplitter",1815),lAn(1816,1,{},qj),EWn.a=0,EWn.b=0,gX($3n,"HyperEdgeSegmentSplitter/AreaRating",1816),lAn(329,1,{329:1},mB),EWn.a=0,EWn.b=0,EWn.c=0,gX($3n,"HyperEdgeSegmentSplitter/FreeArea",329),lAn(1817,1,EJn,ja),EWn.ue=function(n,t){return IK(_B(n,112),_B(t,112))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX($3n,"HyperEdgeSegmentSplitter/lambda$0$Type",1817),lAn(1818,1,hVn,zV),EWn.td=function(n){Y3(this.a,this.d,this.c,this.b,_B(n,112))},EWn.b=0,gX($3n,"HyperEdgeSegmentSplitter/lambda$1$Type",1818),lAn(1819,1,{},Ea),EWn.Kb=function(n){return new xq(null,new l1(_B(n,112).e,16))},gX($3n,"HyperEdgeSegmentSplitter/lambda$2$Type",1819),lAn(1820,1,{},Ta),EWn.Kb=function(n){return new xq(null,new l1(_B(n,112).j,16))},gX($3n,"HyperEdgeSegmentSplitter/lambda$3$Type",1820),lAn(1821,1,{},Ma),EWn.Fe=function(n){return Hy(ED(n))},gX($3n,"HyperEdgeSegmentSplitter/lambda$4$Type",1821),lAn(655,1,{},sX),EWn.a=0,EWn.b=0,EWn.c=0,gX($3n,"OrthogonalRoutingGenerator",655),lAn(1638,1,{},Sa),EWn.Kb=function(n){return new xq(null,new l1(_B(n,112).e,16))},gX($3n,"OrthogonalRoutingGenerator/lambda$0$Type",1638),lAn(1639,1,{},Pa),EWn.Kb=function(n){return new xq(null,new l1(_B(n,112).j,16))},gX($3n,"OrthogonalRoutingGenerator/lambda$1$Type",1639),lAn(661,1,{}),gX(L3n,"BaseRoutingDirectionStrategy",661),lAn(1807,661,{},dm),EWn.dg=function(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*e,h=new Ub(n.n);h.ahZn&&(c=n,r=new LI(l,a=f),NH(u.a,r),K_n(this,u,c,r,!1),(b=n.r)&&(r=new LI(w=Hy(ED(Npn(b.e,0))),a),NH(u.a,r),K_n(this,u,c,r,!1),c=b,r=new LI(w,a=t+b.o*e),NH(u.a,r),K_n(this,u,c,r,!1)),r=new LI(g,a),NH(u.a,r),K_n(this,u,c,r,!1)))},EWn.eg=function(n){return n.i.n.a+n.n.a+n.a.a},EWn.fg=function(){return mUn(),TCt},EWn.gg=function(){return mUn(),uCt},gX(L3n,"NorthToSouthRoutingStrategy",1807),lAn(1808,661,{},gm),EWn.dg=function(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t-n.o*e,h=new Ub(n.n);h.ahZn&&(c=n,r=new LI(l,a=f),NH(u.a,r),K_n(this,u,c,r,!1),(b=n.r)&&(r=new LI(w=Hy(ED(Npn(b.e,0))),a),NH(u.a,r),K_n(this,u,c,r,!1),c=b,r=new LI(w,a=t-b.o*e),NH(u.a,r),K_n(this,u,c,r,!1)),r=new LI(g,a),NH(u.a,r),K_n(this,u,c,r,!1)))},EWn.eg=function(n){return n.i.n.a+n.n.a+n.a.a},EWn.fg=function(){return mUn(),uCt},EWn.gg=function(){return mUn(),TCt},gX(L3n,"SouthToNorthRoutingStrategy",1808),lAn(1806,661,{},pm),EWn.dg=function(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*e,h=new Ub(n.n);h.ahZn&&(c=n,r=new LI(a=f,l),NH(u.a,r),K_n(this,u,c,r,!0),(b=n.r)&&(r=new LI(a,w=Hy(ED(Npn(b.e,0)))),NH(u.a,r),K_n(this,u,c,r,!0),c=b,r=new LI(a=t+b.o*e,w),NH(u.a,r),K_n(this,u,c,r,!0)),r=new LI(a,g),NH(u.a,r),K_n(this,u,c,r,!0)))},EWn.eg=function(n){return n.i.n.b+n.n.b+n.a.b},EWn.fg=function(){return mUn(),aCt},EWn.gg=function(){return mUn(),SCt},gX(L3n,"WestToEastRoutingStrategy",1806),lAn(813,1,{},aBn),EWn.Ib=function(){return AMn(this.a)},EWn.b=0,EWn.c=!1,EWn.d=!1,EWn.f=0,gX(x3n,"NubSpline",813),lAn(407,1,{407:1},kxn,lY),gX(x3n,"NubSpline/PolarCP",407),lAn(1453,1,k3n,oyn),EWn.Yf=function(n){return eTn(_B(n,37))},EWn.pf=function(n,t){iXn(this,_B(n,37),t)},gX(x3n,"SplineEdgeRouter",1453),lAn(268,1,{268:1},T6),EWn.Ib=function(){return this.a+" ->("+this.c+") "+this.b},EWn.c=0,gX(x3n,"SplineEdgeRouter/Dependency",268),lAn(455,22,{3:1,35:1,22:1,455:1},aI);var Nyt,xyt,Dyt,Ryt,Kyt,_yt=_en(x3n,"SplineEdgeRouter/SideToProcess",455,Gnt,VJ,IF);lAn(1454,1,NVn,ya),EWn.Mb=function(n){return wxn(),!_B(n,128).o},gX(x3n,"SplineEdgeRouter/lambda$0$Type",1454),lAn(1455,1,{},ma),EWn.Ge=function(n){return wxn(),_B(n,128).v+1},gX(x3n,"SplineEdgeRouter/lambda$1$Type",1455),lAn(1456,1,hVn,uI),EWn.td=function(n){tq(this.a,this.b,_B(n,46))},gX(x3n,"SplineEdgeRouter/lambda$2$Type",1456),lAn(1457,1,hVn,oI),EWn.td=function(n){eq(this.a,this.b,_B(n,46))},gX(x3n,"SplineEdgeRouter/lambda$3$Type",1457),lAn(128,1,{35:1,128:1},ZPn,oqn),EWn.wd=function(n){return uj(this,_B(n,128))},EWn.b=0,EWn.e=!1,EWn.f=0,EWn.g=0,EWn.j=!1,EWn.k=!1,EWn.n=0,EWn.o=!1,EWn.p=!1,EWn.q=!1,EWn.s=0,EWn.u=0,EWn.v=0,EWn.F=0,gX(x3n,"SplineSegment",128),lAn(459,1,{459:1},ka),EWn.a=0,EWn.b=!1,EWn.c=!1,EWn.d=!1,EWn.e=!1,EWn.f=0,gX(x3n,"SplineSegment/EdgeInformation",459),lAn(1234,1,{},da),gX(F3n,tZn,1234),lAn(1235,1,EJn,ga),EWn.ue=function(n,t){return PCn(_B(n,135),_B(t,135))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(F3n,eZn,1235),lAn(1233,1,{},CE),gX(F3n,"MrTree",1233),lAn(393,22,{3:1,35:1,22:1,393:1,246:1,234:1},sI),EWn.Kf=function(){return CCn(this)},EWn.Xf=function(){return CCn(this)};var Fyt,Byt=_en(F3n,"TreeLayoutPhases",393,Gnt,y3,CF);lAn(1130,209,$Yn,RR),EWn.Ze=function(n,t){var e,i,r,c,a,u;for(By(jD(JAn(n,(SAn(),Skt))))||yY(new jw((HM(),new Ny(n)))),Ban(a=new M6,n),oon(a,(Bqn(),ukt),n),g_n(n,a,u=new Lp),U_n(n,a,u),c=a,i=new Ub(r=L_n(this.a,c));i.a"+w0(this.c):"e_"+Yon(this)},gX(B3n,"TEdge",188),lAn(135,134,{3:1,135:1,94:1,134:1},M6),EWn.Ib=function(){var n,t,e,i,r;for(r=null,i=upn(this.b,0);i.b!=i.d.c;)r+=(null==(e=_B(f3(i),86)).c||0==e.c.length?"n_"+e.g:"n_"+e.c)+"\n";for(t=upn(this.a,0);t.b!=t.d.c;)r+=((n=_B(f3(t),188)).b&&n.c?w0(n.b)+"->"+w0(n.c):"e_"+Yon(n))+"\n";return r};var Hyt=gX(B3n,"TGraph",135);lAn(633,502,{3:1,502:1,633:1,94:1,134:1}),gX(B3n,"TShape",633),lAn(86,633,{3:1,502:1,86:1,633:1,94:1,134:1},isn),EWn.Ib=function(){return w0(this)};var qyt,Gyt,zyt,Uyt,Xyt,Wyt,Vyt=gX(B3n,"TNode",86);lAn(255,1,dVn,fg),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new lg(upn(this.a.d,0))},gX(B3n,"TNode/2",255),lAn(358,1,WWn,lg),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return _B(f3(this.a),188).c},EWn.Ob=function(){return kE(this.a)},EWn.Qb=function(){ptn(this.a)},gX(B3n,"TNode/2/1",358),lAn(1840,1,YZn,DR),EWn.pf=function(n,t){LFn(this,_B(n,135),t)},gX(H3n,"FanProcessor",1840),lAn(327,22,{3:1,35:1,22:1,327:1,234:1},hI),EWn.Kf=function(){switch(this.g){case 0:return new Wm;case 1:return new DR;case 2:return new Oa;case 3:return new Ia;case 4:return new $a;case 5:return new La;default:throw Fp(new Ry(E1n+(null!=this.f?this.f:""+this.g)))}};var Qyt,Jyt,Yyt,Zyt,nkt,tkt,ekt,ikt,rkt,ckt,akt,ukt,okt,skt,hkt,fkt,lkt,bkt,wkt,dkt,gkt,pkt,vkt,mkt,ykt,kkt,jkt,Ekt,Tkt,Mkt,Skt,Pkt,Ikt,Ckt,Okt,Akt,$kt,Lkt,Nkt,xkt,Dkt,Rkt=_en(H3n,T1n,327,Gnt,e9,OF);lAn(1843,1,YZn,Ia),EWn.pf=function(n,t){c$n(this,_B(n,135),t)},EWn.a=0,gX(H3n,"LevelHeightProcessor",1843),lAn(1844,1,dVn,Ca),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return TQ(),AT(),het},gX(H3n,"LevelHeightProcessor/1",1844),lAn(1841,1,YZn,Oa),EWn.pf=function(n,t){WPn(this,_B(n,135),t)},EWn.a=0,gX(H3n,"NeighborsProcessor",1841),lAn(1842,1,dVn,Aa),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return TQ(),AT(),het},gX(H3n,"NeighborsProcessor/1",1842),lAn(1845,1,YZn,$a),EWn.pf=function(n,t){r$n(this,_B(n,135),t)},EWn.a=0,gX(H3n,"NodePositionProcessor",1845),lAn(1839,1,YZn,Wm),EWn.pf=function(n,t){JHn(this,_B(n,135))},gX(H3n,"RootProcessor",1839),lAn(1846,1,YZn,La),EWn.pf=function(n,t){bln(_B(n,135))},gX(H3n,"Untreeifyer",1846),lAn(851,1,WJn,Mf),EWn.Qe=function(n){Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,z3n),""),"Weighting of Nodes"),"Which weighting to use when computing a node order."),mkt),(MPn(),wMt)),Bkt),Yln((epn(),oMt))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,U3n),""),"Search Order"),"Which search order to use when computing a spanning tree."),pkt),wMt),Qkt),Yln(oMt)))),DGn((new Tf,n))},gX(X3n,"MrTreeMetaDataProvider",851),lAn(994,1,WJn,Tf),EWn.Qe=function(n){DGn(n)},gX(X3n,"MrTreeOptions",994),lAn(995,1,{},Na),EWn.$e=function(){return new RR},EWn._e=function(n){},gX(X3n,"MrTreeOptions/MrtreeFactory",995),lAn(480,22,{3:1,35:1,22:1,480:1},fI);var Kkt,_kt,Fkt,Bkt=_en(X3n,"OrderWeighting",480,Gnt,JJ,AF);lAn(425,22,{3:1,35:1,22:1,425:1},lI);var Hkt,qkt,Gkt,zkt,Ukt,Xkt,Wkt,Vkt,Qkt=_en(X3n,"TreeifyingOrder",425,Gnt,QJ,LF);lAn(1459,1,k3n,df),EWn.Yf=function(n){return _B(n,135),qkt},EWn.pf=function(n,t){vcn(this,_B(n,135),t)},gX("org.eclipse.elk.alg.mrtree.p1treeify","DFSTreeifyer",1459),lAn(1460,1,k3n,gf),EWn.Yf=function(n){return _B(n,135),Gkt},EWn.pf=function(n,t){sIn(this,_B(n,135),t)},gX("org.eclipse.elk.alg.mrtree.p2order","NodeOrderer",1460),lAn(1461,1,k3n,wf),EWn.Yf=function(n){return _B(n,135),zkt},EWn.pf=function(n,t){YDn(this,_B(n,135),t)},EWn.a=0,gX("org.eclipse.elk.alg.mrtree.p3place","NodePlacer",1461),lAn(1462,1,k3n,pf),EWn.Yf=function(n){return _B(n,135),Ukt},EWn.pf=function(n,t){Lkn(_B(n,135),t)},gX("org.eclipse.elk.alg.mrtree.p4route","EdgeRouter",1462),lAn(495,22,{3:1,35:1,22:1,495:1,246:1,234:1},bI),EWn.Kf=function(){return fwn(this)},EWn.Xf=function(){return fwn(this)};var Jkt,Ykt,Zkt,njt,tjt=_en(Q3n,"RadialLayoutPhases",495,Gnt,YJ,$F);lAn(1131,209,$Yn,IE),EWn.Ze=function(n,t){var e,i,r;if(ITn(t,"Radial layout",kIn(this,n).c.length),By(jD(JAn(n,(Gyn(),Cjt))))||yY(new jw((HM(),new Ny(n)))),r=cTn(n),Vpn(n,(lD(),Xkt),r),!r)throw Fp(new Ry("The given graph is not a tree!"));for(0==(e=Hy(ED(JAn(n,Njt))))&&(e=sCn(n)),Vpn(n,Njt,e),i=new Ub(kIn(this,n));i.a0&&Lhn((f1(t-1,n.length),n.charCodeAt(t-1)),u1n);)--t;if(e>=t)throw Fp(new Ry("The given string does not contain any numbers."));if(2!=(i=mKn(n.substr(e,t-e),",|;|\r|\n")).length)throw Fp(new Ry("Exactly two numbers are expected, "+i.length+" were found."));try{this.a=fSn(xMn(i[0])),this.b=fSn(xMn(i[1]))}catch(r){throw iL(r=hun(r),127)?Fp(new Ry(o1n+r)):Fp(r)}},EWn.Ib=function(){return"("+this.a+","+this.b+")"},EWn.a=0,EWn.b=0;var MMt=gX(s1n,"KVector",8);lAn(74,68,{3:1,4:1,20:1,28:1,52:1,14:1,68:1,15:1,74:1,414:1},mm,Dj,Gx),EWn.Pc=function(){return Xsn(this)},EWn.Jf=function(n){var t,e,i,r,c;e=mKn(n,",|;|\\(|\\)|\\[|\\]|\\{|\\}| |\t|\n"),vQ(this);try{for(t=0,r=0,i=0,c=0;t0&&(r%2==0?i=fSn(e[t]):c=fSn(e[t]),r>0&&r%2!=0&&NH(this,new LI(i,c)),++r),++t}catch(a){throw iL(a=hun(a),127)?Fp(new Ry("The given string does not match the expected format for vectors."+a)):Fp(a)}},EWn.Ib=function(){var n,t,e;for(n=new hN("("),t=upn(this,0);t.b!=t.d.c;)aO(n,(e=_B(f3(t),8)).a+","+e.b),t.b!=t.d.c&&(n.a+="; ");return(n.a+=")",n).a};var SMt,PMt,IMt,CMt,OMt,AMt,$Mt=gX(s1n,"KVectorChain",74);lAn(248,22,{3:1,35:1,22:1,248:1},NI);var LMt,NMt,xMt,DMt,RMt,KMt,_Mt,FMt,BMt,HMt,qMt,GMt,zMt,UMt,XMt,WMt,VMt,QMt,JMt,YMt=_en(o5n,"Alignment",248,Gnt,Q8,QF);lAn(979,1,WJn,Af),EWn.Qe=function(n){H_n(n)},gX(o5n,"BoxLayouterOptions",979),lAn(980,1,{},xu),EWn.$e=function(){return new Gu},EWn._e=function(n){},gX(o5n,"BoxLayouterOptions/BoxFactory",980),lAn(291,22,{3:1,35:1,22:1,291:1},xI);var ZMt,nSt,tSt,eSt,iSt,rSt,cSt,aSt,uSt,oSt,sSt,hSt,fSt,lSt,bSt,wSt,dSt,gSt,pSt,vSt,mSt,ySt,kSt,jSt,ESt,TSt,MSt,SSt,PSt,ISt,CSt,OSt,ASt,$St,LSt,NSt,xSt,DSt,RSt,KSt,_St,FSt,BSt,HSt,qSt,GSt,zSt,USt,XSt,WSt,VSt,QSt,JSt,YSt,ZSt,nPt,tPt,ePt,iPt,rPt,cPt,aPt,uPt,oPt,sPt,hPt,fPt,lPt,bPt,wPt,dPt,gPt,pPt,vPt,mPt,yPt,kPt,jPt,EPt,TPt,MPt,SPt,PPt,IPt,CPt,OPt,APt,$Pt,LPt,NPt,xPt,DPt,RPt,KPt,_Pt,FPt,BPt=_en(o5n,"ContentAlignment",291,Gnt,V8,JF);lAn(684,1,WJn,$f),EWn.Qe=function(n){Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,l5n),""),"Layout Algorithm"),"Select a specific layout algorithm."),(MPn(),vMt)),Wtt),Yln((epn(),oMt))))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,b5n),""),"Resolved Layout Algorithm"),"Meta data associated with the selected algorithm."),pMt),rMt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,U2n),""),"Alignment"),"Alignment of the selected node relative to other nodes; the exact meaning depends on the used algorithm."),eSt),wMt),YMt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,XYn),""),"Aspect Ratio"),"The desired aspect ratio of the drawing, that is the quotient of width by height."),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,w5n),""),"Bend Points"),"A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to specify a pre-defined routing for an edge. The vector chain must include the source point, any bend points, and the target point, so it must have at least two points."),pMt),$Mt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,c3n),""),"Content Alignment"),"Specifies how the content of a node are aligned. Each node can individually control the alignment of its contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that option."),sSt),dMt),BPt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,z2n),""),"Debug Mode"),"Whether additional debug information shall be generated."),(oN(),!1)),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Q2n),""),jYn),"Overall direction of edges: horizontal (right / left) or vertical (down / up)."),lSt),wMt),UPt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,v2n),""),"Edge Routing"),"What kind of edge routing style should be applied for the content of a parent node. Algorithms may also set this option to single edges in order to mark them as splines. The bend point list of edges with this option set to SPLINES must be interpreted as control points for a piecewise cubic spline."),pSt),wMt),aIt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,C4n),""),"Expand Nodes"),"If active, nodes are expanded to fill the area of their parent."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,b2n),""),"Hierarchy Handling"),"Determines whether separate layout runs are triggered for different compound nodes in a hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay out that node and all of its descendants in a single layout run, until a descendant is encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that setting. Including multiple levels of hierarchy in a single layout run may allow cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` (or not set at all), the default behavior is `SEPARATE_CHILDREN`."),jSt),wMt),TIt),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[uMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,WYn),""),"Padding"),"The padding to be left to a parent element's border when placing child elements. This can also serve as an output option of a layout algorithm if node size calculation is setup appropriately."),USt),pMt),Rut),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[uMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,yZn),""),"Interactive"),"Whether the algorithm should be run in interactive mode for the content of a parent node. What this means exactly depends on how the specific algorithm interprets this option. Usually in the interactive mode algorithms try to modify the current layout as little as possible."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,p3n),""),"interactive Layout"),"Whether the graph should be changeable interactively and by setting constraints"),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,EZn),""),"Omit Node Micro Layout"),"Node micro layout comprises the computation of node dimensions (if requested), the placement of ports and their labels, and the placement of node labels. The functionality is implemented independent of any specific layout algorithm and shouldn't have any negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, this option allows to deactivate the micro layout."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,kZn),""),"Port Constraints"),"Defines constraints of the position of the ports of a node."),aPt),wMt),rCt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,w3n),""),"Position"),"The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to specify a pre-defined position."),pMt),MMt),kG(uMt,Mun(Hk(yMt,1),OVn,175,0,[sMt,aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,dZn),""),"Priority"),"Defines the priority of an object; its meaning depends on the specific layout algorithm and the context where it is used."),gMt),Ctt),kG(uMt,Mun(Hk(yMt,1),OVn,175,0,[cMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,vZn),""),"Randomization Seed"),"Seed used for pseudo-random number generators to control the layout algorithm. If the value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time)."),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,mZn),""),"Separate Connected Components"),"Whether each connected component should be processed separately."),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,a3n),""),"Junction Points"),"This option is not used as option, but as output of the layout algorithms. It is attached to edges and determines the points where junction symbols should be drawn in order to represent hyperedges with orthogonal routing. Whether such points are computed depends on the chosen layout algorithm and edge routing style. The points are put into the vector chain with no specific order."),CSt),pMt),$Mt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,s3n),""),"Comment Box"),"Whether the node should be regarded as a comment box instead of a regular node. In that case its placement should be similar to how labels are handled. Any edges incident to a comment box specify to which graph elements the comment is related."),!1),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,h3n),""),"Hypernode"),"Whether the node should be handled as a hypernode."),!1),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,d5n),""),"Label Manager"),"Label managers can shorten labels upon a layout algorithm's request."),pMt),xNt),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,d3n),""),"Margins"),"Margins define additional space around the actual bounds of a graph element. For instance, ports or labels being placed on the outside of a node's border might introduce such a margin. The margin is used to guarantee non-overlap of other graph elements with those ports or labels."),ASt),pMt),kut),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,q2n),""),"No Layout"),"No layout is done for the associated element. This is used to mark parts of a diagram to avoid their inclusion in the layout graph, or to mark parts of the layout graph to prevent layout engines from processing them. If you wish to exclude the contents of a compound node from automatic layout, while the node itself is still considered on its own layer, use the 'Fixed Layout' algorithm for that node."),!1),lMt),mtt),kG(uMt,Mun(Hk(yMt,1),OVn,175,0,[cMt,sMt,aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,g5n),""),"Scale Factor"),"The scaling factor to be applied to the corresponding node in recursive layout. It causes the corresponding node's size to be adjusted, and its ports and labels to be sized and placed accordingly after the layout of that node has been determined (and before the node itself and its siblings are arranged). The scaling is not reverted afterwards, so the resulting layout graph contains the adjusted size and position data. This option is currently not supported if 'Layout Hierarchy' is set."),1),bMt),Mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,p5n),""),"Animate"),"Whether the shift from the old layout to the new computed layout shall be animated."),!0),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,v5n),""),"Animation Time Factor"),"Factor for computation of animation time. The higher the value, the longer the animation time. If the value is 0, the resulting time is always equal to the minimum defined by 'Minimal Animation Time'."),tln(100)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,m5n),""),"Layout Ancestors"),"Whether the hierarchy levels on the path from the selected element to the root of the diagram shall be included in the layout process."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,y5n),""),"Maximal Animation Time"),"The maximal time for animations, in milliseconds."),tln(4e3)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,k5n),""),"Minimal Animation Time"),"The minimal time for animations, in milliseconds."),tln(400)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,j5n),""),"Progress Bar"),"Whether a progress bar shall be displayed during layout computations."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,E5n),""),"Validate Graph"),"Whether the graph shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,T5n),""),"Validate Options"),"Whether layout options shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!0),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,M5n),""),"Zoom to Fit"),"Whether the zoom level shall be set to view the whole diagram after layout."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,f5n),"box"),"Box Layout Mode"),"Configures the packing mode used by the {@link BoxLayoutProvider}. If SIMPLE is not required (neither priorities are used nor the interactive mode), GROUP_DEC can improve the packing and decrease the area. GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better."),aSt),wMt),iOt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,A2n),m2n),"Comment Comment Spacing"),"Spacing to be preserved between a comment box and other comment boxes connected to the same node. The space left between comment boxes of different nodes is controlled by the node-node spacing."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,$2n),m2n),"Comment Node Spacing"),"Spacing to be preserved between a node and its connected comment boxes. The space left between a node and the comments of another node is controlled by the node-node spacing."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,zYn),m2n),"Components Spacing"),"Spacing to be preserved between pairs of connected components. This option is only relevant if 'separateConnectedComponents' is activated."),20),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,L2n),m2n),"Edge Spacing"),"Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied for the segments of orthogonally drawn edges, it is harder for general polylines or splines."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,pZn),m2n),"Edge Label Spacing"),"The minimal distance to be preserved between a label and the edge it is associated with. Note that the placement of a label is influenced by the 'edgelabels.placement' option."),2),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,N2n),m2n),"Edge Node Spacing"),"Spacing to be preserved between nodes and edges."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,x2n),m2n),"Label Spacing"),"Determines the amount of space to be left between two labels of the same graph element."),0),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,K2n),m2n),"Label Node Spacing"),"Spacing to be preserved between labels and the border of node they are associated with. Note that the placement of a label is influenced by the 'nodelabels.placement' option."),5),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,D2n),m2n),"Horizontal spacing between Label and Port"),"Horizontal spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,R2n),m2n),"Vertical spacing between Label and Port"),"Vertical spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,gZn),m2n),"Node Spacing"),"The minimal distance to be preserved between each two nodes."),20),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,_2n),m2n),"Node Self Loop Spacing"),"Spacing to be preserved between a node and its self loops."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,F2n),m2n),"Port Spacing"),"Spacing between pairs of ports of the same node."),10),bMt),Mtt),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[uMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,B2n),m2n),"Individual Spacing"),"Allows to specify individual spacing values for graph elements that shall be different from the value specified for the element's parent."),pMt),oOt),kG(uMt,Mun(Hk(yMt,1),OVn,175,0,[cMt,sMt,aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,g3n),m2n),"Additional Port Space"),"Additional space around the sets of ports on each node side. For each side of a node, this option can reserve additional space before and after the ports on each side. For example, a top spacing of 20 makes sure that the first port on the western and eastern side is 20 units away from the northern border."),NPt),pMt),kut),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,b3n),C5n),"Layout Partition"),"Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout direction)."),gMt),Ctt),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[uMt]))))),r2(n,b3n,l3n,QSt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,l3n),C5n),"Layout Partitioning"),"Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. a pair of nodes with different partition indices is then placed such that the node with lower index is placed to the left of the other node (with left-to-right layout direction). Depending on the layout algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least if edges that cross partitions are not part of a partition-crossing cycle."),WSt),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,J2n),O5n),"Node Label Padding"),"Define padding for node labels that are placed inside of a node."),LSt),pMt),Rut),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,SZn),O5n),"Node Label Placement"),"Hints for where node labels are to be placed; if empty, the node label's position is not modified."),xSt),dMt),HIt),kG(uMt,Mun(Hk(yMt,1),OVn,175,0,[aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,n3n),A5n),"Port Alignment"),"Defines the default port distribution for a node. May be overridden for each side individually."),YSt),wMt),QIt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,t3n),A5n),"Port Alignment (North)"),"Defines how ports on the northern side are placed, overriding the node's general port alignment."),wMt),QIt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,e3n),A5n),"Port Alignment (South)"),"Defines how ports on the southern side are placed, overriding the node's general port alignment."),wMt),QIt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,i3n),A5n),"Port Alignment (West)"),"Defines how ports on the western side are placed, overriding the node's general port alignment."),wMt),QIt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,r3n),A5n),"Port Alignment (East)"),"Defines how ports on the eastern side are placed, overriding the node's general port alignment."),wMt),QIt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,MZn),$5n),"Node Size Constraints"),"What should be taken into account when calculating a node's size. Empty size constraints specify that a node's size is already fixed and should not be changed."),RSt),dMt),VCt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,TZn),$5n),"Node Size Options"),"Options modifying the behavior of the size constraints set on a node. Each member of the set specifies something that should be taken into account when calculating node sizes. The empty set corresponds to no further modifications."),HSt),dMt),tOt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,_Zn),$5n),"Node Size Minimum"),"The minimal size to which a node can be reduced."),FSt),pMt),MMt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,V2n),$5n),"Fixed Graph Size"),"By default, the fixed layout provider will enlarge a graph until it is large enough to contain its children. If this option is set, it won't do so."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,u3n),C2n),"Edge Label Placement"),"Gives a hint on where to put edge labels."),dSt),wMt),YPt),Yln(aMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,jZn),C2n),"Inline Edge Labels"),"If true, an edge label is placed directly on its edge. May only apply to center edge labels. This kind of label placement is only advisable if the label's rendering is such that it is not crossed by its edge and thus stays legible."),!1),lMt),mtt),Yln(aMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,S5n),"font"),"Font Name"),"Font name used for a label."),vMt),Wtt),Yln(aMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,P5n),"font"),"Font Size"),"Font size used for a label."),gMt),Ctt),Yln(aMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,f3n),L5n),"Port Anchor Offset"),"The offset to the port position where connections shall be attached."),pMt),MMt),Yln(sMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,o3n),L5n),"Port Index"),"The index of a port in the fixed order around a node. The order is assumed as clockwise, starting with the leftmost port on the top side. This option must be set if 'Port Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. Additionally, the option 'Port Side' must be defined in this case."),gMt),Ctt),Yln(sMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,G2n),L5n),"Port Side"),"The side of a node on which a port is situated. This option must be set if 'Port Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given for the ports."),bPt),wMt),KCt),Yln(sMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,H2n),L5n),"Port Border Offset"),"The offset of ports on the node border. With a positive offset the port is moved outside of the node, while with a negative offset the port is moved towards the inside. An offset of 0 means that the port is placed directly on the node border, i.e. if the port side is north, the port's south border touches the nodes's north border; if the port side is east, the port's west border touches the nodes's east border; if the port side is south, the port's north border touches the node's south border; if the port side is west, the port's east border touches the node's west border."),bMt),Mtt),Yln(sMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,PZn),N5n),"Port Label Placement"),"Decides on a placement method for port labels; if empty, the node label's position is not modified."),hPt),dMt),PCt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Y2n),N5n),"Port Labels Next to Port"),"Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE."),!1),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Z2n),N5n),"Treat Port Labels as Group"),"If this option is true (default), the labels of a port will be treated as a group when it comes to centering them next to their port. If this option is false, only the first label will be centered next to the port, with the others being placed below. This only applies to labels of eastern and western ports and will have no effect if labels are not placed next to their port."),!0),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,X2n),x5n),"Activate Inside Self Loops"),"Whether this node allows to route self loops inside of it instead of around it. If set to true, this will make the node a compound node if it isn't already, and will require the layout algorithm to support compound nodes with hierarchical ports."),!1),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,W2n),x5n),"Inside Self Loop"),"Whether a self loop should be routed inside a node instead of around that node."),!1),lMt),mtt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,UYn),"edge"),"Edge Thickness"),"The thickness of an edge. This is a hint on the line width used to draw an edge, possibly requiring more space to be reserved for it."),1),bMt),Mtt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,I5n),"edge"),"Edge Type"),"The type of an edge. This is usually used for UML class diagrams, where associations must be handled differently from generalizations."),mSt),wMt),vIt),Yln(cMt)))),LM(n,new GZ(vj(yj(mj(new pu,l1n),"Layered"),'The layer-based method was introduced by Sugiyama, Tagawa and Toda in 1981. It emphasizes the direction of edges by pointing as many edges as possible into the same direction. The nodes are arranged in layers, which are sometimes called "hierarchies", and then reordered such that the number of edge crossings is minimized. Afterwards, concrete coordinates are computed for the nodes and edge bend points.'))),LM(n,new GZ(vj(yj(mj(new pu,"org.eclipse.elk.orthogonal"),"Orthogonal"),'Orthogonal methods that follow the "topology-shape-metrics" approach by Batini, Nardelli and Tamassia \'86. The first phase determines the topology of the drawing by applying a planarization technique, which results in a planar representation of the graph. The orthogonal shape is computed in the second phase, which aims at minimizing the number of edge bends, and is called orthogonalization. The third phase leads to concrete coordinates for nodes and edge bend points by applying a compaction method, thus defining the metrics.'))),LM(n,new GZ(vj(yj(mj(new pu,wZn),"Force"),"Layout algorithms that follow physical analogies by simulating a system of attractive and repulsive forces. The first successful method of this kind was proposed by Eades in 1984."))),LM(n,new GZ(vj(yj(mj(new pu,"org.eclipse.elk.circle"),"Circle"),"Circular layout algorithms emphasize cycles or biconnected components of a graph by arranging them in circles. This is useful if a drawing is desired where such components are clearly grouped, or where cycles are shown as prominent OPTIONS of the graph."))),LM(n,new GZ(vj(yj(mj(new pu,V3n),"Tree"),"Specialized layout methods for trees, i.e. acyclic graphs. The regular structure of graphs that have no undirected cycles can be emphasized using an algorithm of this type."))),LM(n,new GZ(vj(yj(mj(new pu,"org.eclipse.elk.planar"),"Planar"),"Algorithms that require a planar or upward planar graph. Most of these algorithms are theoretically interesting, but not practically usable."))),LM(n,new GZ(vj(yj(mj(new pu,l4n),"Radial"),"Radial layout algorithms usually position the nodes of the graph on concentric circles."))),fKn((new Lf,n)),H_n((new Af,n)),xDn((new Nf,n))},gX(o5n,"CoreOptions",684),lAn(103,22,{3:1,35:1,22:1,103:1},DI);var HPt,qPt,GPt,zPt,UPt=_en(o5n,jYn,103,Gnt,S5,nB);lAn(272,22,{3:1,35:1,22:1,272:1},RI);var XPt,WPt,VPt,QPt,JPt,YPt=_en(o5n,"EdgeLabelPlacement",272,Gnt,B1,tB);lAn(218,22,{3:1,35:1,22:1,218:1},KI);var ZPt,nIt,tIt,eIt,iIt,rIt,cIt,aIt=_en(o5n,"EdgeRouting",218,Gnt,T3,eB);lAn(312,22,{3:1,35:1,22:1,312:1},_I);var uIt,oIt,sIt,hIt,fIt,lIt,bIt,wIt,dIt,gIt,pIt,vIt=_en(o5n,"EdgeType",312,Gnt,r9,iB);lAn(977,1,WJn,Lf),EWn.Qe=function(n){fKn(n)},gX(o5n,"FixedLayouterOptions",977),lAn(978,1,{},Vu),EWn.$e=function(){return new Hu},EWn._e=function(n){},gX(o5n,"FixedLayouterOptions/FixedFactory",978),lAn(334,22,{3:1,35:1,22:1,334:1},FI);var mIt,yIt,kIt,jIt,EIt,TIt=_en(o5n,"HierarchyHandling",334,Gnt,F1,rB);lAn(285,22,{3:1,35:1,22:1,285:1},BI);var MIt,SIt,PIt,IIt,CIt,OIt,AIt,$It,LIt,NIt,xIt=_en(o5n,"LabelSide",285,Gnt,E3,cB);lAn(93,22,{3:1,35:1,22:1,93:1},HI);var DIt,RIt,KIt,_It,FIt,BIt,HIt=_en(o5n,"NodeLabelPlacement",93,Gnt,men,aB);lAn(249,22,{3:1,35:1,22:1,249:1},qI);var qIt,GIt,zIt,UIt,XIt,WIt,VIt,QIt=_en(o5n,"PortAlignment",249,Gnt,P5,uB);lAn(98,22,{3:1,35:1,22:1,98:1},GI);var JIt,YIt,ZIt,nCt,tCt,eCt,iCt,rCt=_en(o5n,"PortConstraints",98,Gnt,T8,oB);lAn(273,22,{3:1,35:1,22:1,273:1},zI);var cCt,aCt,uCt,oCt,sCt,hCt,fCt,lCt,bCt,wCt,dCt,gCt,pCt,vCt,mCt,yCt,kCt,jCt,ECt,TCt,MCt,SCt,PCt=_en(o5n,"PortLabelPlacement",273,Gnt,i9,sB);lAn(61,22,{3:1,35:1,22:1,61:1},UI);var ICt,CCt,OCt,ACt,$Ct,LCt,NCt,xCt,DCt,RCt,KCt=_en(o5n,"PortSide",61,Gnt,o5,lB);lAn(981,1,WJn,Nf),EWn.Qe=function(n){xDn(n)},gX(o5n,"RandomLayouterOptions",981),lAn(982,1,{},Qu),EWn.$e=function(){return new no},EWn._e=function(n){},gX(o5n,"RandomLayouterOptions/RandomFactory",982),lAn(374,22,{3:1,35:1,22:1,374:1},XI);var _Ct,FCt,BCt,HCt,qCt,GCt,zCt,UCt,XCt,WCt,VCt=_en(o5n,"SizeConstraint",374,Gnt,j3,hB);lAn(259,22,{3:1,35:1,22:1,259:1},WI);var QCt,JCt,YCt,ZCt,nOt,tOt=_en(o5n,"SizeOptions",259,Gnt,kin,fB);lAn(370,1,{1949:1},zm),EWn.b=!1,EWn.c=0,EWn.d=-1,EWn.e=null,EWn.f=null,EWn.g=-1,EWn.j=!1,EWn.k=!1,EWn.n=!1,EWn.o=0,EWn.q=0,EWn.r=0,gX(v3n,"BasicProgressMonitor",370),lAn(972,209,$Yn,Gu),EWn.Ze=function(n,t){var e,i,r,c,a,u,o,s,h;switch(ITn(t,"Box layout",2),r=qy(ED(JAn(n,(TMn(),zMt)))),c=_B(JAn(n,HMt),116),e=By(jD(JAn(n,RMt))),i=By(jD(JAn(n,KMt))),_B(JAn(n,xMt),311).g){case 0:u=new ZK((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a)),TQ(),p$(u,new Tg(i)),a=u,o=zPn(n),(null==(s=ED(JAn(n,NMt)))||(mW(s),s<=0))&&(s=1.3),DUn(n,(h=FUn(a,r,c,o.a,o.b,e,(mW(s),s))).a,h.b,!1,!0);break;default:mqn(n,r,c,e)}FSn(t)},gX(v3n,"BoxLayoutProvider",972),lAn(973,1,EJn,Tg),EWn.ue=function(n,t){return oNn(this,_B(n,33),_B(t,33))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},EWn.a=!1,gX(v3n,"BoxLayoutProvider/1",973),lAn(157,1,{157:1},Htn,qx),EWn.Ib=function(){return this.c?qRn(this.c):AMn(this.b)},gX(v3n,"BoxLayoutProvider/Group",157),lAn(311,22,{3:1,35:1,22:1,311:1},VI);var eOt,iOt=_en(v3n,"BoxLayoutProvider/PackingMode",311,Gnt,M3,bB);lAn(974,1,EJn,zu),EWn.ue=function(n,t){return NQ(_B(n,157),_B(t,157))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(v3n,"BoxLayoutProvider/lambda$0$Type",974),lAn(975,1,EJn,Uu),EWn.ue=function(n,t){return iQ(_B(n,157),_B(t,157))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(v3n,"BoxLayoutProvider/lambda$1$Type",975),lAn(976,1,EJn,Xu),EWn.ue=function(n,t){return rQ(_B(n,157),_B(t,157))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(v3n,"BoxLayoutProvider/lambda$2$Type",976),lAn(1365,1,{831:1},Wu),EWn.qg=function(n,t){return CM(),!iL(t,160)||TE(($un(),_B(n,160)),t)},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$0$Type",1365),lAn(1366,1,hVn,Mg),EWn.td=function(n){Qsn(this.a,_B(n,146))},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$1$Type",1366),lAn(1367,1,hVn,qu),EWn.td=function(n){_B(n,94),CM()},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$2$Type",1367),lAn(1371,1,hVn,Sg),EWn.td=function(n){Irn(this.a,_B(n,94))},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$3$Type",1371),lAn(1369,1,NVn,QI),EWn.Mb=function(n){return Xon(this.a,this.b,_B(n,146))},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$4$Type",1369),lAn(1368,1,NVn,JI),EWn.Mb=function(n){return Ox(this.a,this.b,_B(n,831))},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$5$Type",1368),lAn(1370,1,hVn,YI),EWn.td=function(n){Kz(this.a,this.b,_B(n,146))},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$6$Type",1370),lAn(935,1,{},Bu),EWn.Kb=function(n){return vA(n)},EWn.Fb=function(n){return this===n},gX(v3n,"ElkUtil/lambda$0$Type",935),lAn(936,1,hVn,ZI),EWn.td=function(n){eOn(this.a,this.b,_B(n,79))},EWn.a=0,EWn.b=0,gX(v3n,"ElkUtil/lambda$1$Type",936),lAn(937,1,hVn,nC),EWn.td=function(n){ky(this.a,this.b,_B(n,202))},EWn.a=0,EWn.b=0,gX(v3n,"ElkUtil/lambda$2$Type",937),lAn(938,1,hVn,tC),EWn.td=function(n){ZA(this.a,this.b,_B(n,137))},EWn.a=0,EWn.b=0,gX(v3n,"ElkUtil/lambda$3$Type",938),lAn(939,1,hVn,Pg),EWn.td=function(n){iq(this.a,_B(n,469))},gX(v3n,"ElkUtil/lambda$4$Type",939),lAn(342,1,{35:1,342:1},Op),EWn.wd=function(n){return gL(this,_B(n,236))},EWn.Fb=function(n){var t;return!!iL(n,342)&&(t=_B(n,342),this.a==t.a)},EWn.Hb=function(){return SY(this.a)},EWn.Ib=function(){return this.a+" (exclusive)"},EWn.a=0,gX(v3n,"ExclusiveBounds/ExclusiveLowerBound",342),lAn(1138,209,$Yn,Hu),EWn.Ze=function(n,t){var e,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T;for(ITn(t,"Fixed Layout",1),a=_B(JAn(n,(uWn(),gSt)),218),b=0,w=0,v=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));v.e!=v.i.gc();){for(g=_B(mpn(v),33),(T=_B(JAn(g,(zsn(),wIt)),8))&&(TA(g,T.a,T.b),_B(JAn(g,sIt),174).Hc((pdn(),NCt))&&(d=_B(JAn(g,fIt),8)).a>0&&d.b>0&&DUn(g,d.a,d.b,!0,!0)),b=i.Math.max(b,g.i+g.g),w=i.Math.max(w,g.j+g.f),f=new CL((!g.n&&(g.n=new nU(HOt,g,1,7)),g.n));f.e!=f.i.gc();)o=_B(mpn(f),137),(T=_B(JAn(o,wIt),8))&&TA(o,T.a,T.b),b=i.Math.max(b,g.i+o.i+o.g),w=i.Math.max(w,g.j+o.j+o.f);for(k=new CL((!g.c&&(g.c=new nU(GOt,g,9,9)),g.c));k.e!=k.i.gc();)for(y=_B(mpn(k),118),(T=_B(JAn(y,wIt),8))&&TA(y,T.a,T.b),j=g.i+y.i,E=g.j+y.j,b=i.Math.max(b,j+y.g),w=i.Math.max(w,E+y.f),s=new CL((!y.n&&(y.n=new nU(HOt,y,1,7)),y.n));s.e!=s.i.gc();)o=_B(mpn(s),137),(T=_B(JAn(o,wIt),8))&&TA(o,T.a,T.b),b=i.Math.max(b,j+o.i+o.g),w=i.Math.max(w,E+o.j+o.f);for(c=new az(JL(bLn(g).a.Kc(),new h));bAn(c);)l=RUn(e=_B(G5(c),79)),b=i.Math.max(b,l.a),w=i.Math.max(w,l.b);for(r=new az(JL(lLn(g).a.Kc(),new h));bAn(r);)QY(MMn(e=_B(G5(r),79)))!=n&&(l=RUn(e),b=i.Math.max(b,l.a),w=i.Math.max(w,l.b))}if(a==(Ebn(),WPt))for(p=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));p.e!=p.i.gc();)for(r=new az(JL(bLn(g=_B(mpn(p),33)).a.Kc(),new h));bAn(r);)0==(u=eFn(e=_B(G5(r),79))).b?Vpn(e,ISt,null):Vpn(e,ISt,u);By(jD(JAn(n,(zsn(),hIt))))||DUn(n,b+(m=_B(JAn(n,lIt),116)).b+m.c,w+m.d+m.a,!0,!0),FSn(t)},gX(v3n,"FixedLayoutProvider",1138),lAn(373,134,{3:1,414:1,373:1,94:1,134:1},Ju,enn),EWn.Jf=function(n){var t,e,i,r,c,a,u;if(n)try{for(a=mKn(n,";,;"),r=0,c=(i=a).length;r>16&WVn|n^(e&WVn)<<16},EWn.Kc=function(){return new Ig(this)},EWn.Ib=function(){return null==this.a&&null==this.b?"pair(null,null)":null==this.a?"pair(null,"+_bn(this.b)+")":null==this.b?"pair("+_bn(this.a)+",null)":"pair("+_bn(this.a)+","+_bn(this.b)+")"},gX(v3n,"Pair",46),lAn(983,1,WWn,Ig),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return!this.c&&(!this.b&&null!=this.a.a||null!=this.a.b)},EWn.Pb=function(){if(!this.c&&!this.b&&null!=this.a.a)return this.b=!0,this.a.a;if(!this.c&&null!=this.a.b)return this.c=!0,this.a.b;throw Fp(new vv)},EWn.Qb=function(){throw this.c&&null!=this.a.b?this.a.b=null:this.b&&null!=this.a.a&&(this.a.a=null),Fp(new bv)},EWn.b=!1,EWn.c=!1,gX(v3n,"Pair/1",983),lAn(448,1,{448:1},XV),EWn.Fb=function(n){return iV(this.a,_B(n,448).a)&&iV(this.c,_B(n,448).c)&&iV(this.d,_B(n,448).d)&&iV(this.b,_B(n,448).b)},EWn.Hb=function(){return shn(Mun(Hk(Cnt,1),FWn,1,5,[this.a,this.c,this.d,this.b]))},EWn.Ib=function(){return"("+this.a+KWn+this.c+KWn+this.d+KWn+this.b+")"},gX(v3n,"Quadruple",448),lAn(1126,209,$Yn,no),EWn.Ze=function(n,t){var e;ITn(t,"Random Layout",1),0!=(!n.a&&(n.a=new nU(qOt,n,10,11)),n.a).i?(tUn(n,(e=_B(JAn(n,(gdn(),$Ct)),19))&&0!=e.a?new S4(e.a):new ubn,qy(ED(JAn(n,CCt))),qy(ED(JAn(n,LCt))),_B(JAn(n,OCt),116)),FSn(t)):FSn(t)},gX(v3n,"RandomLayoutProvider",1126),lAn(553,1,{}),EWn.qf=function(){return new LI(this.f.i,this.f.j)},EWn.We=function(n){return kJ(n,(uWn(),rPt))?JAn(this.f,fOt):JAn(this.f,n)},EWn.rf=function(){return new LI(this.f.g,this.f.f)},EWn.sf=function(){return this.g},EWn.Xe=function(n){return M8(this.f,n)},EWn.tf=function(n){Men(this.f,n.a),Sen(this.f,n.b)},EWn.uf=function(n){Ten(this.f,n.a),Een(this.f,n.b)},EWn.vf=function(n){this.g=n},EWn.g=0,gX(F5n,"ElkGraphAdapters/AbstractElkGraphElementAdapter",553),lAn(554,1,{839:1},Cg),EWn.wf=function(){var n,t;if(!this.b)for(this.b=S2(pV(this.a).i),t=new CL(pV(this.a));t.e!=t.i.gc();)n=_B(mpn(t),137),UB(this.b,new xy(n));return this.b},EWn.b=null,gX(F5n,"ElkGraphAdapters/ElkEdgeAdapter",554),lAn(301,553,{},Ny),EWn.xf=function(){return nyn(this)},EWn.a=null,gX(F5n,"ElkGraphAdapters/ElkGraphAdapter",301),lAn(630,553,{181:1},xy),gX(F5n,"ElkGraphAdapters/ElkLabelAdapter",630),lAn(629,553,{680:1},QN),EWn.wf=function(){return Ymn(this)},EWn.Af=function(){var n;return!(n=_B(JAn(this.f,(uWn(),OSt)),142))&&(n=new hm),n},EWn.Cf=function(){return Zmn(this)},EWn.Ef=function(n){var t;t=new C_(n),Vpn(this.f,(uWn(),OSt),t)},EWn.Ff=function(n){Vpn(this.f,(uWn(),zSt),new I_(n))},EWn.yf=function(){return this.d},EWn.zf=function(){var n,t;if(!this.a)for(this.a=new $p,t=new az(JL(lLn(_B(this.f,33)).a.Kc(),new h));bAn(t);)n=_B(G5(t),79),UB(this.a,new Cg(n));return this.a},EWn.Bf=function(){var n,t;if(!this.c)for(this.c=new $p,t=new az(JL(bLn(_B(this.f,33)).a.Kc(),new h));bAn(t);)n=_B(G5(t),79),UB(this.c,new Cg(n));return this.c},EWn.Df=function(){return 0!=VQ(_B(this.f,33)).i||By(jD(_B(this.f,33).We((uWn(),TSt))))},EWn.Gf=function(){R7(this,(HM(),hOt))},EWn.a=null,EWn.b=null,EWn.c=null,EWn.d=null,EWn.e=null,gX(F5n,"ElkGraphAdapters/ElkNodeAdapter",629),lAn(1266,553,{838:1},ap),EWn.wf=function(){return myn(this)},EWn.zf=function(){var n,t;if(!this.a)for(this.a=ux(_B(this.f,118).xg().i),t=new CL(_B(this.f,118).xg());t.e!=t.i.gc();)n=_B(mpn(t),79),UB(this.a,new Cg(n));return this.a},EWn.Bf=function(){var n,t;if(!this.c)for(this.c=ux(_B(this.f,118).yg().i),t=new CL(_B(this.f,118).yg());t.e!=t.i.gc();)n=_B(mpn(t),79),UB(this.c,new Cg(n));return this.c},EWn.Hf=function(){return _B(_B(this.f,118).We((uWn(),lPt)),61)},EWn.If=function(){var n,t,e,i,r,c,a;for(i=UY(_B(this.f,118)),e=new CL(_B(this.f,118).yg());e.e!=e.i.gc();)for(a=new CL((!(n=_B(mpn(e),79)).c&&(n.c=new oK(xOt,n,5,8)),n.c));a.e!=a.i.gc();){if(Stn(MTn(c=_B(mpn(a),82)),i))return!0;if(MTn(c)==i&&By(jD(JAn(n,(uWn(),MSt)))))return!0}for(t=new CL(_B(this.f,118).xg());t.e!=t.i.gc();)for(r=new CL((!(n=_B(mpn(t),79)).b&&(n.b=new oK(xOt,n,4,7)),n.b));r.e!=r.i.gc();)if(Stn(MTn(_B(mpn(r),82)),i))return!0;return!1},EWn.a=null,EWn.b=null,EWn.c=null,gX(F5n,"ElkGraphAdapters/ElkPortAdapter",1266),lAn(1267,1,EJn,to),EWn.ue=function(n,t){return HRn(_B(n,118),_B(t,118))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(F5n,"ElkGraphAdapters/PortComparator",1267);var bOt,wOt,dOt,gOt,pOt,vOt,mOt,yOt,kOt,jOt,EOt,TOt,MOt,SOt,POt,IOt,COt,OOt=fq(B5n,"EObject"),AOt=fq(H5n,q5n),$Ot=fq(H5n,G5n),LOt=fq(H5n,z5n),NOt=fq(H5n,"ElkShape"),xOt=fq(H5n,U5n),DOt=fq(H5n,X5n),ROt=fq(H5n,W5n),KOt=fq(B5n,V5n),_Ot=fq(B5n,"EFactory"),FOt=fq(B5n,Q5n),BOt=fq(B5n,"EPackage"),HOt=fq(H5n,J5n),qOt=fq(H5n,Y5n),GOt=fq(H5n,Z5n);lAn(90,1,n6n),EWn.Jg=function(){return this.Kg(),null},EWn.Kg=function(){return null},EWn.Lg=function(){return this.Kg(),!1},EWn.Mg=function(){return!1},EWn.Ng=function(n){fan(this,n)},gX(t6n,"BasicNotifierImpl",90),lAn(97,90,s6n),EWn.nh=function(){return pA(this)},EWn.Og=function(n,t){return n},EWn.Pg=function(){throw Fp(new dv)},EWn.Qg=function(n){var t;return t=Svn(_B(ttn(this.Tg(),this.Vg()),18)),this.eh().ih(this,t.n,t.f,n)},EWn.Rg=function(n,t){throw Fp(new dv)},EWn.Sg=function(n,t,e){return j_n(this,n,t,e)},EWn.Tg=function(){var n;return this.Pg()&&(n=this.Pg().ck())?n:this.zh()},EWn.Ug=function(){return iAn(this)},EWn.Vg=function(){throw Fp(new dv)},EWn.Wg=function(){var n,t;return!(t=this.ph().dk())&&this.Pg().ik((WM(),t=null==(n=hY(BFn(this.Tg())))?A$t:new WN(this,n))),t},EWn.Xg=function(n,t){return n},EWn.Yg=function(n){return n.Gj()?n.aj():Cwn(this.Tg(),n)},EWn.Zg=function(){var n;return(n=this.Pg())?n.fk():null},EWn.$g=function(){return this.Pg()?this.Pg().ck():null},EWn._g=function(n,t,e){return Jpn(this,n,t,e)},EWn.ah=function(n){return T9(this,n)},EWn.bh=function(n,t){return X5(this,n,t)},EWn.dh=function(){var n;return!!(n=this.Pg())&&n.gk()},EWn.eh=function(){throw Fp(new dv)},EWn.fh=function(){return Vdn(this)},EWn.gh=function(n,t,e,i){return $pn(this,n,t,i)},EWn.hh=function(n,t,e){return _B(ttn(this.Tg(),t),66).Nj().Qj(this,this.yh(),t-this.Ah(),n,e)},EWn.ih=function(n,t,e,i){return aY(this,n,t,i)},EWn.jh=function(n,t,e){return _B(ttn(this.Tg(),t),66).Nj().Rj(this,this.yh(),t-this.Ah(),n,e)},EWn.kh=function(){return!!this.Pg()&&!!this.Pg().ek()},EWn.lh=function(n){return gpn(this,n)},EWn.mh=function(n){return JY(this,n)},EWn.oh=function(n){return Rqn(this,n)},EWn.ph=function(){throw Fp(new dv)},EWn.qh=function(){return this.Pg()?this.Pg().ek():null},EWn.rh=function(){return Vdn(this)},EWn.sh=function(n,t){vIn(this,n,t)},EWn.th=function(n){this.ph().hk(n)},EWn.uh=function(n){this.ph().kk(n)},EWn.vh=function(n){this.ph().jk(n)},EWn.wh=function(n,t){var e,i,r,c;return(c=this.Zg())&&n&&(t=Rpn(c.Vk(),this,t),c.Zk(this)),(i=this.eh())&&(0!=(wKn(this,this.eh(),this.Vg()).Bb&_Qn)?(r=i.fh())&&(n?!c&&r.Zk(this):r.Yk(this)):(t=(e=this.Vg())>=0?this.Qg(t):this.eh().ih(this,-1-e,null,t),t=this.Sg(null,-1,t))),this.uh(n),t},EWn.xh=function(n){var t,e,i,r,c,a,u;if((c=Cwn(e=this.Tg(),n))>=(t=this.Ah()))return _B(n,66).Nj().Uj(this,this.yh(),c-t);if(c<=-1){if(!(a=Kqn((PPn(),Q$t),e,n)))throw Fp(new Ry(e6n+n.ne()+c6n));if(JM(),_B(a,66).Oj()||(a=J1(_7(Q$t,a))),r=_B((i=this.Yg(a))>=0?this._g(i,!0,!0):iOn(this,a,!0),153),(u=a.Zj())>1||-1==u)return _B(_B(r,215).hl(n,!1),76)}else if(n.$j())return _B((i=this.Yg(n))>=0?this._g(i,!1,!0):iOn(this,n,!1),76);return new PC(this,n)},EWn.yh=function(){return W7(this)},EWn.zh=function(){return(WX(),YAt).S},EWn.Ah=function(){return fX(this.zh())},EWn.Bh=function(n){pPn(this,n)},EWn.Ib=function(){return M$n(this)},gX(h6n,"BasicEObjectImpl",97),lAn(114,97,{105:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1}),EWn.Ch=function(n){return V7(this)[n]},EWn.Dh=function(n,t){OX(V7(this),n,t)},EWn.Eh=function(n){OX(V7(this),n,null)},EWn.Jg=function(){return _B(van(this,4),126)},EWn.Kg=function(){throw Fp(new dv)},EWn.Lg=function(){return 0!=(4&this.Db)},EWn.Pg=function(){throw Fp(new dv)},EWn.Fh=function(n){ogn(this,2,n)},EWn.Rg=function(n,t){this.Db=t<<16|255&this.Db,this.Fh(n)},EWn.Tg=function(){return yJ(this)},EWn.Vg=function(){return this.Db>>16},EWn.Wg=function(){var n;return WM(),null==(n=hY(BFn(_B(van(this,16),26)||this.zh())))?A$t:new WN(this,n)},EWn.Mg=function(){return 0==(1&this.Db)},EWn.Zg=function(){return _B(van(this,128),1935)},EWn.$g=function(){return _B(van(this,16),26)},EWn.dh=function(){return 0!=(32&this.Db)},EWn.eh=function(){return _B(van(this,2),49)},EWn.kh=function(){return 0!=(64&this.Db)},EWn.ph=function(){throw Fp(new dv)},EWn.qh=function(){return _B(van(this,64),281)},EWn.th=function(n){ogn(this,16,n)},EWn.uh=function(n){ogn(this,128,n)},EWn.vh=function(n){ogn(this,64,n)},EWn.yh=function(){return sgn(this)},EWn.Db=0,gX(h6n,"MinimalEObjectImpl",114),lAn(115,114,{105:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),EWn.Fh=function(n){this.Cb=n},EWn.eh=function(){return this.Cb},gX(h6n,"MinimalEObjectImpl/Container",115),lAn(1985,115,{105:1,413:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),EWn._g=function(n,t,e){return kyn(this,n,t,e)},EWn.jh=function(n,t,e){return nSn(this,n,t,e)},EWn.lh=function(n){return p0(this,n)},EWn.sh=function(n,t){esn(this,n,t)},EWn.zh=function(){return SXn(),MOt},EWn.Bh=function(n){qun(this,n)},EWn.Ve=function(){return hpn(this)},EWn.We=function(n){return JAn(this,n)},EWn.Xe=function(n){return M8(this,n)},EWn.Ye=function(n,t){return Vpn(this,n,t)},gX(f6n,"EMapPropertyHolderImpl",1985),lAn(567,115,{105:1,469:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},ro),EWn._g=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return Jpn(this,n,t,e)},EWn.lh=function(n){switch(n){case 0:return 0!=this.a;case 1:return 0!=this.b}return gpn(this,n)},EWn.sh=function(n,t){switch(n){case 0:return void yen(this,Hy(ED(t)));case 1:return void ken(this,Hy(ED(t)))}vIn(this,n,t)},EWn.zh=function(){return SXn(),dOt},EWn.Bh=function(n){switch(n){case 0:return void yen(this,0);case 1:return void ken(this,0)}pPn(this,n)},EWn.Ib=function(){var n;return 0!=(64&this.Db)?M$n(this):((n=new sN(M$n(this))).a+=" (x: ",gE(n,this.a),n.a+=", y: ",gE(n,this.b),n.a+=")",n.a)},EWn.a=0,EWn.b=0,gX(f6n,"ElkBendPointImpl",567),lAn(723,1985,{105:1,413:1,160:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),EWn._g=function(n,t,e){return Rfn(this,n,t,e)},EWn.hh=function(n,t,e){return KTn(this,n,t,e)},EWn.jh=function(n,t,e){return eun(this,n,t,e)},EWn.lh=function(n){return kan(this,n)},EWn.sh=function(n,t){Hjn(this,n,t)},EWn.zh=function(){return SXn(),mOt},EWn.Bh=function(n){afn(this,n)},EWn.zg=function(){return this.k},EWn.Ag=function(){return pV(this)},EWn.Ib=function(){return Vln(this)},EWn.k=null,gX(f6n,"ElkGraphElementImpl",723),lAn(724,723,{105:1,413:1,160:1,470:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),EWn._g=function(n,t,e){return xbn(this,n,t,e)},EWn.lh=function(n){return swn(this,n)},EWn.sh=function(n,t){qjn(this,n,t)},EWn.zh=function(){return SXn(),TOt},EWn.Bh=function(n){Nwn(this,n)},EWn.Bg=function(){return this.f},EWn.Cg=function(){return this.g},EWn.Dg=function(){return this.i},EWn.Eg=function(){return this.j},EWn.Fg=function(n,t){EA(this,n,t)},EWn.Gg=function(n,t){TA(this,n,t)},EWn.Hg=function(n){Men(this,n)},EWn.Ig=function(n){Sen(this,n)},EWn.Ib=function(){return pSn(this)},EWn.f=0,EWn.g=0,EWn.i=0,EWn.j=0,gX(f6n,"ElkShapeImpl",724),lAn(725,724,{105:1,413:1,82:1,160:1,470:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),EWn._g=function(n,t,e){return Fvn(this,n,t,e)},EWn.hh=function(n,t,e){return bjn(this,n,t,e)},EWn.jh=function(n,t,e){return wjn(this,n,t,e)},EWn.lh=function(n){return Hon(this,n)},EWn.sh=function(n,t){AAn(this,n,t)},EWn.zh=function(){return SXn(),gOt},EWn.Bh=function(n){Lpn(this,n)},EWn.xg=function(){return!this.d&&(this.d=new oK(DOt,this,8,5)),this.d},EWn.yg=function(){return!this.e&&(this.e=new oK(DOt,this,7,4)),this.e},gX(f6n,"ElkConnectableShapeImpl",725),lAn(352,723,{105:1,413:1,79:1,160:1,352:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},io),EWn.Qg=function(n){return Ekn(this,n)},EWn._g=function(n,t,e){switch(n){case 3:return zY(this);case 4:return!this.b&&(this.b=new oK(xOt,this,4,7)),this.b;case 5:return!this.c&&(this.c=new oK(xOt,this,5,8)),this.c;case 6:return!this.a&&(this.a=new nU(ROt,this,6,6)),this.a;case 7:return oN(),!this.b&&(this.b=new oK(xOt,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new oK(xOt,this,5,8)),this.c.i<=1));case 8:return oN(),!!YOn(this);case 9:return oN(),!!WCn(this);case 10:return oN(),!this.b&&(this.b=new oK(xOt,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new oK(xOt,this,5,8)),0!=this.c.i)}return Rfn(this,n,t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?Ekn(this,e):this.Cb.ih(this,-1-i,null,e)),XD(this,_B(n,33),e);case 4:return!this.b&&(this.b=new oK(xOt,this,4,7)),Vwn(this.b,n,e);case 5:return!this.c&&(this.c=new oK(xOt,this,5,8)),Vwn(this.c,n,e);case 6:return!this.a&&(this.a=new nU(ROt,this,6,6)),Vwn(this.a,n,e)}return KTn(this,n,t,e)},EWn.jh=function(n,t,e){switch(t){case 3:return XD(this,null,e);case 4:return!this.b&&(this.b=new oK(xOt,this,4,7)),Rpn(this.b,n,e);case 5:return!this.c&&(this.c=new oK(xOt,this,5,8)),Rpn(this.c,n,e);case 6:return!this.a&&(this.a=new nU(ROt,this,6,6)),Rpn(this.a,n,e)}return eun(this,n,t,e)},EWn.lh=function(n){switch(n){case 3:return!!zY(this);case 4:return!!this.b&&0!=this.b.i;case 5:return!!this.c&&0!=this.c.i;case 6:return!!this.a&&0!=this.a.i;case 7:return!this.b&&(this.b=new oK(xOt,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new oK(xOt,this,5,8)),this.c.i<=1));case 8:return YOn(this);case 9:return WCn(this);case 10:return!this.b&&(this.b=new oK(xOt,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new oK(xOt,this,5,8)),0!=this.c.i)}return kan(this,n)},EWn.sh=function(n,t){switch(n){case 3:return void FLn(this,_B(t,33));case 4:return!this.b&&(this.b=new oK(xOt,this,4,7)),uqn(this.b),!this.b&&(this.b=new oK(xOt,this,4,7)),void dX(this.b,_B(t,14));case 5:return!this.c&&(this.c=new oK(xOt,this,5,8)),uqn(this.c),!this.c&&(this.c=new oK(xOt,this,5,8)),void dX(this.c,_B(t,14));case 6:return!this.a&&(this.a=new nU(ROt,this,6,6)),uqn(this.a),!this.a&&(this.a=new nU(ROt,this,6,6)),void dX(this.a,_B(t,14))}Hjn(this,n,t)},EWn.zh=function(){return SXn(),pOt},EWn.Bh=function(n){switch(n){case 3:return void FLn(this,null);case 4:return!this.b&&(this.b=new oK(xOt,this,4,7)),void uqn(this.b);case 5:return!this.c&&(this.c=new oK(xOt,this,5,8)),void uqn(this.c);case 6:return!this.a&&(this.a=new nU(ROt,this,6,6)),void uqn(this.a)}afn(this,n)},EWn.Ib=function(){return hHn(this)},gX(f6n,"ElkEdgeImpl",352),lAn(439,1985,{105:1,413:1,202:1,439:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},co),EWn.Qg=function(n){return ukn(this,n)},EWn._g=function(n,t,e){switch(n){case 1:return this.j;case 2:return this.k;case 3:return this.b;case 4:return this.c;case 5:return!this.a&&(this.a=new OL($Ot,this,5)),this.a;case 6:return XY(this);case 7:return t?Mvn(this):this.i;case 8:return t?Tvn(this):this.f;case 9:return!this.g&&(this.g=new oK(ROt,this,9,10)),this.g;case 10:return!this.e&&(this.e=new oK(ROt,this,10,9)),this.e;case 11:return this.d}return kyn(this,n,t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?ukn(this,e):this.Cb.ih(this,-1-i,null,e)),WD(this,_B(n,79),e);case 9:return!this.g&&(this.g=new oK(ROt,this,9,10)),Vwn(this.g,n,e);case 10:return!this.e&&(this.e=new oK(ROt,this,10,9)),Vwn(this.e,n,e)}return _B(ttn(_B(van(this,16),26)||(SXn(),vOt),t),66).Nj().Qj(this,sgn(this),t-fX((SXn(),vOt)),n,e)},EWn.jh=function(n,t,e){switch(t){case 5:return!this.a&&(this.a=new OL($Ot,this,5)),Rpn(this.a,n,e);case 6:return WD(this,null,e);case 9:return!this.g&&(this.g=new oK(ROt,this,9,10)),Rpn(this.g,n,e);case 10:return!this.e&&(this.e=new oK(ROt,this,10,9)),Rpn(this.e,n,e)}return nSn(this,n,t,e)},EWn.lh=function(n){switch(n){case 1:return 0!=this.j;case 2:return 0!=this.k;case 3:return 0!=this.b;case 4:return 0!=this.c;case 5:return!!this.a&&0!=this.a.i;case 6:return!!XY(this);case 7:return!!this.i;case 8:return!!this.f;case 9:return!!this.g&&0!=this.g.i;case 10:return!!this.e&&0!=this.e.i;case 11:return null!=this.d}return p0(this,n)},EWn.sh=function(n,t){switch(n){case 1:return void Pen(this,Hy(ED(t)));case 2:return void Cen(this,Hy(ED(t)));case 3:return void jen(this,Hy(ED(t)));case 4:return void Ien(this,Hy(ED(t)));case 5:return!this.a&&(this.a=new OL($Ot,this,5)),uqn(this.a),!this.a&&(this.a=new OL($Ot,this,5)),void dX(this.a,_B(t,14));case 6:return void KLn(this,_B(t,79));case 7:return void $in(this,_B(t,82));case 8:return void Ain(this,_B(t,82));case 9:return!this.g&&(this.g=new oK(ROt,this,9,10)),uqn(this.g),!this.g&&(this.g=new oK(ROt,this,9,10)),void dX(this.g,_B(t,14));case 10:return!this.e&&(this.e=new oK(ROt,this,10,9)),uqn(this.e),!this.e&&(this.e=new oK(ROt,this,10,9)),void dX(this.e,_B(t,14));case 11:return void irn(this,TD(t))}esn(this,n,t)},EWn.zh=function(){return SXn(),vOt},EWn.Bh=function(n){switch(n){case 1:return void Pen(this,0);case 2:return void Cen(this,0);case 3:return void jen(this,0);case 4:return void Ien(this,0);case 5:return!this.a&&(this.a=new OL($Ot,this,5)),void uqn(this.a);case 6:return void KLn(this,null);case 7:return void $in(this,null);case 8:return void Ain(this,null);case 9:return!this.g&&(this.g=new oK(ROt,this,9,10)),void uqn(this.g);case 10:return!this.e&&(this.e=new oK(ROt,this,10,9)),void uqn(this.e);case 11:return void irn(this,null)}qun(this,n)},EWn.Ib=function(){return xOn(this)},EWn.b=0,EWn.c=0,EWn.d=null,EWn.j=0,EWn.k=0,gX(f6n,"ElkEdgeSectionImpl",439),lAn(150,115,{105:1,92:1,90:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1}),EWn._g=function(n,t,e){return 0==n?(!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab):G9(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t,e)},EWn.hh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e)):_B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Qj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.jh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e)):_B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Rj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.lh=function(n){return 0==n?!!this.Ab&&0!=this.Ab.i:I3(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.oh=function(n){return oUn(this,n)},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14))}Abn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t)},EWn.uh=function(n){ogn(this,128,n)},EWn.zh=function(){return wWn(),h$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab)}Bfn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.Gh=function(){this.Bb|=1},EWn.Hh=function(n){return $_n(this,n)},EWn.Bb=0,gX(h6n,"EModelElementImpl",150),lAn(704,150,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1},xf),EWn.Ih=function(n,t){return BGn(this,n,t)},EWn.Jh=function(n){var t,e,i,r;if(this.a!=Gtn(n)||0!=(256&n.Bb))throw Fp(new Ry(p6n+n.zb+w6n));for(e=mJ(n);0!=r4(e.a).i;){if(tyn(t=_B(nGn(e,0,iL(r=_B(Utn(r4(e.a),0),87).c,88)?_B(r,26):(wWn(),l$t)),26)))return _B(i=Gtn(t).Nh().Jh(t),49).th(n),i;e=mJ(t)}return"java.util.Map$Entry"==(null!=n.D?n.D:n.B)?new sq(n):new yH(n)},EWn.Kh=function(n,t){return LXn(this,n,t)},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.a}return G9(this,n-fX((wWn(),u$t)),ttn(_B(van(this,16),26)||u$t,n),t,e)},EWn.hh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 1:return this.a&&(e=_B(this.a,49).ih(this,4,BOt,e)),Qhn(this,_B(n,235),e)}return _B(ttn(_B(van(this,16),26)||(wWn(),u$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),u$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 1:return Qhn(this,null,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),u$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),u$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return!!this.a}return I3(this,n-fX((wWn(),u$t)),ttn(_B(van(this,16),26)||u$t,n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void LMn(this,_B(t,235))}Abn(this,n-fX((wWn(),u$t)),ttn(_B(van(this,16),26)||u$t,n),t)},EWn.zh=function(){return wWn(),u$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void LMn(this,null)}Bfn(this,n-fX((wWn(),u$t)),ttn(_B(van(this,16),26)||u$t,n))},gX(h6n,"EFactoryImpl",704),lAn(m6n,704,{105:1,2014:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1},ao),EWn.Ih=function(n,t){switch(n.yj()){case 12:return _B(t,146).tg();case 13:return _bn(t);default:throw Fp(new Ry(b6n+n.ne()+w6n))}},EWn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=Gtn(n))?cvn(t.Mh(),n):-1),n.G){case 4:return new uo;case 6:return new ym;case 7:return new km;case 8:return new io;case 9:return new ro;case 10:return new co;case 11:return new so;default:throw Fp(new Ry(p6n+n.zb+w6n))}},EWn.Kh=function(n,t){switch(n.yj()){case 13:case 12:return null;default:throw Fp(new Ry(b6n+n.ne()+w6n))}},gX(f6n,"ElkGraphFactoryImpl",m6n),lAn(438,150,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1}),EWn.Wg=function(){var n;return null==(n=hY(BFn(_B(van(this,16),26)||this.zh())))?(WM(),WM(),A$t):new Ux(this,n)},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.ne()}return G9(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb}return I3(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void this.Lh(TD(t))}Abn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t)},EWn.zh=function(){return wWn(),f$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void this.Lh(null)}Bfn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.ne=function(){return this.zb},EWn.Lh=function(n){$rn(this,n)},EWn.Ib=function(){return mfn(this)},EWn.zb=null,gX(h6n,"ENamedElementImpl",438),lAn(179,438,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1},gJ),EWn.Qg=function(n){return lkn(this,n)},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.yb;case 3:return this.xb;case 4:return this.sb;case 5:return!this.rb&&(this.rb=new Qz(this,_At,this)),this.rb;case 6:return!this.vb&&(this.vb=new nK(BOt,this,6,7)),this.vb;case 7:return t?this.Db>>16==7?_B(this.Cb,235):null:WY(this)}return G9(this,n-fX((wWn(),d$t)),ttn(_B(van(this,16),26)||d$t,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 4:return this.sb&&(e=_B(this.sb,49).ih(this,1,_Ot,e)),yfn(this,_B(n,471),e);case 5:return!this.rb&&(this.rb=new Qz(this,_At,this)),Vwn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new nK(BOt,this,6,7)),Vwn(this.vb,n,e);case 7:return this.Cb&&(e=(i=this.Db>>16)>=0?lkn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,7,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),d$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),d$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 4:return yfn(this,null,e);case 5:return!this.rb&&(this.rb=new Qz(this,_At,this)),Rpn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new nK(BOt,this,6,7)),Rpn(this.vb,n,e);case 7:return j_n(this,null,7,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),d$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),d$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.yb;case 3:return null!=this.xb;case 4:return!!this.sb;case 5:return!!this.rb&&0!=this.rb.i;case 6:return!!this.vb&&0!=this.vb.i;case 7:return!!WY(this)}return I3(this,n-fX((wWn(),d$t)),ttn(_B(van(this,16),26)||d$t,n))},EWn.oh=function(n){return ANn(this,n)||oUn(this,n)},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void $rn(this,TD(t));case 2:return void Nrn(this,TD(t));case 3:return void Lrn(this,TD(t));case 4:return void tSn(this,_B(t,471));case 5:return!this.rb&&(this.rb=new Qz(this,_At,this)),uqn(this.rb),!this.rb&&(this.rb=new Qz(this,_At,this)),void dX(this.rb,_B(t,14));case 6:return!this.vb&&(this.vb=new nK(BOt,this,6,7)),uqn(this.vb),!this.vb&&(this.vb=new nK(BOt,this,6,7)),void dX(this.vb,_B(t,14))}Abn(this,n-fX((wWn(),d$t)),ttn(_B(van(this,16),26)||d$t,n),t)},EWn.vh=function(n){var t,e;if(n&&this.rb)for(e=new CL(this.rb);e.e!=e.i.gc();)iL(t=mpn(e),351)&&(_B(t,351).w=null);ogn(this,64,n)},EWn.zh=function(){return wWn(),d$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void $rn(this,null);case 2:return void Nrn(this,null);case 3:return void Lrn(this,null);case 4:return void tSn(this,null);case 5:return!this.rb&&(this.rb=new Qz(this,_At,this)),void uqn(this.rb);case 6:return!this.vb&&(this.vb=new nK(BOt,this,6,7)),void uqn(this.vb)}Bfn(this,n-fX((wWn(),d$t)),ttn(_B(van(this,16),26)||d$t,n))},EWn.Gh=function(){jyn(this)},EWn.Mh=function(){return!this.rb&&(this.rb=new Qz(this,_At,this)),this.rb},EWn.Nh=function(){return this.sb},EWn.Oh=function(){return this.ub},EWn.Ph=function(){return this.xb},EWn.Qh=function(){return this.yb},EWn.Rh=function(n){this.ub=n},EWn.Ib=function(){var n;return 0!=(64&this.Db)?mfn(this):((n=new sN(mfn(this))).a+=" (nsURI: ",iO(n,this.yb),n.a+=", nsPrefix: ",iO(n,this.xb),n.a+=")",n.a)},EWn.xb=null,EWn.yb=null,gX(h6n,"EPackageImpl",179),lAn(555,179,{105:1,2016:1,555:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1},uAn),EWn.q=!1,EWn.r=!1;var zOt=!1;gX(f6n,"ElkGraphPackageImpl",555),lAn(354,724,{105:1,413:1,160:1,137:1,470:1,354:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},uo),EWn.Qg=function(n){return okn(this,n)},EWn._g=function(n,t,e){switch(n){case 7:return VY(this);case 8:return this.a}return xbn(this,n,t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 7:return this.Cb&&(e=(i=this.Db>>16)>=0?okn(this,e):this.Cb.ih(this,-1-i,null,e)),XG(this,_B(n,160),e)}return KTn(this,n,t,e)},EWn.jh=function(n,t,e){return 7==t?XG(this,null,e):eun(this,n,t,e)},EWn.lh=function(n){switch(n){case 7:return!!VY(this);case 8:return!pK("",this.a)}return swn(this,n)},EWn.sh=function(n,t){switch(n){case 7:return void PNn(this,_B(t,160));case 8:return void Lin(this,TD(t))}qjn(this,n,t)},EWn.zh=function(){return SXn(),yOt},EWn.Bh=function(n){switch(n){case 7:return void PNn(this,null);case 8:return void Lin(this,"")}Nwn(this,n)},EWn.Ib=function(){return iPn(this)},EWn.a="",gX(f6n,"ElkLabelImpl",354),lAn(239,725,{105:1,413:1,82:1,160:1,33:1,470:1,239:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},ym),EWn.Qg=function(n){return Tkn(this,n)},EWn._g=function(n,t,e){switch(n){case 9:return!this.c&&(this.c=new nU(GOt,this,9,9)),this.c;case 10:return!this.a&&(this.a=new nU(qOt,this,10,11)),this.a;case 11:return QY(this);case 12:return!this.b&&(this.b=new nU(DOt,this,12,3)),this.b;case 13:return oN(),!this.a&&(this.a=new nU(qOt,this,10,11)),this.a.i>0}return Fvn(this,n,t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 9:return!this.c&&(this.c=new nU(GOt,this,9,9)),Vwn(this.c,n,e);case 10:return!this.a&&(this.a=new nU(qOt,this,10,11)),Vwn(this.a,n,e);case 11:return this.Cb&&(e=(i=this.Db>>16)>=0?Tkn(this,e):this.Cb.ih(this,-1-i,null,e)),qR(this,_B(n,33),e);case 12:return!this.b&&(this.b=new nU(DOt,this,12,3)),Vwn(this.b,n,e)}return bjn(this,n,t,e)},EWn.jh=function(n,t,e){switch(t){case 9:return!this.c&&(this.c=new nU(GOt,this,9,9)),Rpn(this.c,n,e);case 10:return!this.a&&(this.a=new nU(qOt,this,10,11)),Rpn(this.a,n,e);case 11:return qR(this,null,e);case 12:return!this.b&&(this.b=new nU(DOt,this,12,3)),Rpn(this.b,n,e)}return wjn(this,n,t,e)},EWn.lh=function(n){switch(n){case 9:return!!this.c&&0!=this.c.i;case 10:return!!this.a&&0!=this.a.i;case 11:return!!QY(this);case 12:return!!this.b&&0!=this.b.i;case 13:return!this.a&&(this.a=new nU(qOt,this,10,11)),this.a.i>0}return Hon(this,n)},EWn.sh=function(n,t){switch(n){case 9:return!this.c&&(this.c=new nU(GOt,this,9,9)),uqn(this.c),!this.c&&(this.c=new nU(GOt,this,9,9)),void dX(this.c,_B(t,14));case 10:return!this.a&&(this.a=new nU(qOt,this,10,11)),uqn(this.a),!this.a&&(this.a=new nU(qOt,this,10,11)),void dX(this.a,_B(t,14));case 11:return void YLn(this,_B(t,33));case 12:return!this.b&&(this.b=new nU(DOt,this,12,3)),uqn(this.b),!this.b&&(this.b=new nU(DOt,this,12,3)),void dX(this.b,_B(t,14))}AAn(this,n,t)},EWn.zh=function(){return SXn(),kOt},EWn.Bh=function(n){switch(n){case 9:return!this.c&&(this.c=new nU(GOt,this,9,9)),void uqn(this.c);case 10:return!this.a&&(this.a=new nU(qOt,this,10,11)),void uqn(this.a);case 11:return void YLn(this,null);case 12:return!this.b&&(this.b=new nU(DOt,this,12,3)),void uqn(this.b)}Lpn(this,n)},EWn.Ib=function(){return qRn(this)},gX(f6n,"ElkNodeImpl",239),lAn(186,725,{105:1,413:1,82:1,160:1,118:1,470:1,186:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},km),EWn.Qg=function(n){return skn(this,n)},EWn._g=function(n,t,e){return 9==n?UY(this):Fvn(this,n,t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 9:return this.Cb&&(e=(i=this.Db>>16)>=0?skn(this,e):this.Cb.ih(this,-1-i,null,e)),VD(this,_B(n,33),e)}return bjn(this,n,t,e)},EWn.jh=function(n,t,e){return 9==t?VD(this,null,e):wjn(this,n,t,e)},EWn.lh=function(n){return 9==n?!!UY(this):Hon(this,n)},EWn.sh=function(n,t){switch(n){case 9:return void _Ln(this,_B(t,33))}AAn(this,n,t)},EWn.zh=function(){return SXn(),jOt},EWn.Bh=function(n){switch(n){case 9:return void _Ln(this,null)}Lpn(this,n)},EWn.Ib=function(){return GRn(this)},gX(f6n,"ElkPortImpl",186);var UOt=fq(_6n,"BasicEMap/Entry");lAn(1092,115,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1,114:1,115:1},so),EWn.Fb=function(n){return this===n},EWn.cd=function(){return this.b},EWn.Hb=function(){return MN(this)},EWn.Uh=function(n){Nin(this,_B(n,146))},EWn._g=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return Jpn(this,n,t,e)},EWn.lh=function(n){switch(n){case 0:return!!this.b;case 1:return null!=this.c}return gpn(this,n)},EWn.sh=function(n,t){switch(n){case 0:return void Nin(this,_B(t,146));case 1:return void Rin(this,t)}vIn(this,n,t)},EWn.zh=function(){return SXn(),EOt},EWn.Bh=function(n){switch(n){case 0:return void Nin(this,null);case 1:return void Rin(this,null)}pPn(this,n)},EWn.Sh=function(){var n;return-1==this.a&&(n=this.b,this.a=n?Yon(n):0),this.a},EWn.dd=function(){return this.c},EWn.Th=function(n){this.a=n},EWn.ed=function(n){var t;return t=this.c,Rin(this,n),t},EWn.Ib=function(){var n;return 0!=(64&this.Db)?M$n(this):(aO(aO(aO(n=new Sk,this.b?this.b.tg():qWn),n1n),mN(this.c)),n.a)},EWn.a=-1,EWn.c=null;var XOt,WOt,VOt,QOt,JOt,YOt,ZOt,nAt,tAt=gX(f6n,"ElkPropertyToValueMapEntryImpl",1092);lAn(984,1,{},lo),gX(H6n,"JsonAdapter",984),lAn(210,60,_Vn,nk),gX(H6n,"JsonImportException",210),lAn(857,1,{},bkn),gX(H6n,"JsonImporter",857),lAn(891,1,{},rC),gX(H6n,"JsonImporter/lambda$0$Type",891),lAn(892,1,{},cC),gX(H6n,"JsonImporter/lambda$1$Type",892),lAn(900,1,{},Og),gX(H6n,"JsonImporter/lambda$10$Type",900),lAn(902,1,{},aC),gX(H6n,"JsonImporter/lambda$11$Type",902),lAn(903,1,{},uC),gX(H6n,"JsonImporter/lambda$12$Type",903),lAn(909,1,{},sQ),gX(H6n,"JsonImporter/lambda$13$Type",909),lAn(908,1,{},oQ),gX(H6n,"JsonImporter/lambda$14$Type",908),lAn(904,1,{},oC),gX(H6n,"JsonImporter/lambda$15$Type",904),lAn(905,1,{},sC),gX(H6n,"JsonImporter/lambda$16$Type",905),lAn(906,1,{},hC),gX(H6n,"JsonImporter/lambda$17$Type",906),lAn(907,1,{},fC),gX(H6n,"JsonImporter/lambda$18$Type",907),lAn(912,1,{},Ag),gX(H6n,"JsonImporter/lambda$19$Type",912),lAn(893,1,{},$g),gX(H6n,"JsonImporter/lambda$2$Type",893),lAn(910,1,{},Lg),gX(H6n,"JsonImporter/lambda$20$Type",910),lAn(911,1,{},Ng),gX(H6n,"JsonImporter/lambda$21$Type",911),lAn(915,1,{},xg),gX(H6n,"JsonImporter/lambda$22$Type",915),lAn(913,1,{},Dg),gX(H6n,"JsonImporter/lambda$23$Type",913),lAn(914,1,{},Rg),gX(H6n,"JsonImporter/lambda$24$Type",914),lAn(917,1,{},Kg),gX(H6n,"JsonImporter/lambda$25$Type",917),lAn(916,1,{},_g),gX(H6n,"JsonImporter/lambda$26$Type",916),lAn(918,1,hVn,lC),EWn.td=function(n){k9(this.b,this.a,TD(n))},gX(H6n,"JsonImporter/lambda$27$Type",918),lAn(919,1,hVn,bC),EWn.td=function(n){j9(this.b,this.a,TD(n))},gX(H6n,"JsonImporter/lambda$28$Type",919),lAn(920,1,{},wC),gX(H6n,"JsonImporter/lambda$29$Type",920),lAn(896,1,{},Fg),gX(H6n,"JsonImporter/lambda$3$Type",896),lAn(921,1,{},dC),gX(H6n,"JsonImporter/lambda$30$Type",921),lAn(922,1,{},Bg),gX(H6n,"JsonImporter/lambda$31$Type",922),lAn(923,1,{},Hg),gX(H6n,"JsonImporter/lambda$32$Type",923),lAn(924,1,{},qg),gX(H6n,"JsonImporter/lambda$33$Type",924),lAn(925,1,{},Gg),gX(H6n,"JsonImporter/lambda$34$Type",925),lAn(859,1,{},zg),gX(H6n,"JsonImporter/lambda$35$Type",859),lAn(929,1,{},EB),gX(H6n,"JsonImporter/lambda$36$Type",929),lAn(926,1,hVn,Ug),EWn.td=function(n){V4(this.a,_B(n,469))},gX(H6n,"JsonImporter/lambda$37$Type",926),lAn(927,1,hVn,TC),EWn.td=function(n){hO(this.a,this.b,_B(n,202))},gX(H6n,"JsonImporter/lambda$38$Type",927),lAn(928,1,hVn,MC),EWn.td=function(n){fO(this.a,this.b,_B(n,202))},gX(H6n,"JsonImporter/lambda$39$Type",928),lAn(894,1,{},Xg),gX(H6n,"JsonImporter/lambda$4$Type",894),lAn(930,1,hVn,Wg),EWn.td=function(n){Q4(this.a,_B(n,8))},gX(H6n,"JsonImporter/lambda$40$Type",930),lAn(895,1,{},Vg),gX(H6n,"JsonImporter/lambda$5$Type",895),lAn(899,1,{},Qg),gX(H6n,"JsonImporter/lambda$6$Type",899),lAn(897,1,{},Jg),gX(H6n,"JsonImporter/lambda$7$Type",897),lAn(898,1,{},Yg),gX(H6n,"JsonImporter/lambda$8$Type",898),lAn(901,1,{},Zg),gX(H6n,"JsonImporter/lambda$9$Type",901),lAn(948,1,hVn,np),EWn.td=function(n){YX(this.a,new HX(TD(n)))},gX(H6n,"JsonMetaDataConverter/lambda$0$Type",948),lAn(949,1,hVn,tp),EWn.td=function(n){RX(this.a,_B(n,237))},gX(H6n,"JsonMetaDataConverter/lambda$1$Type",949),lAn(950,1,hVn,ep),EWn.td=function(n){ZZ(this.a,_B(n,149))},gX(H6n,"JsonMetaDataConverter/lambda$2$Type",950),lAn(951,1,hVn,ip),EWn.td=function(n){KX(this.a,_B(n,175))},gX(H6n,"JsonMetaDataConverter/lambda$3$Type",951),lAn(237,22,{3:1,35:1,22:1,237:1},EC);var eAt,iAt=_en(PYn,"GraphFeature",237,Gnt,Dtn,dB);lAn(13,1,{35:1,146:1},cp,tR,OO,zA),EWn.wd=function(n){return dL(this,_B(n,146))},EWn.Fb=function(n){return kJ(this,n)},EWn.wg=function(){return ppn(this)},EWn.tg=function(){return this.b},EWn.Hb=function(){return gvn(this.b)},EWn.Ib=function(){return this.b},gX(PYn,"Property",13),lAn(818,1,EJn,rp),EWn.ue=function(n,t){return Rln(this,_B(n,94),_B(t,94))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(PYn,"PropertyHolderComparator",818),lAn(695,1,WWn,up),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return C9(this)},EWn.Qb=function(){cE()},EWn.Ob=function(){return!!this.a},gX(i8n,"ElkGraphUtil/AncestorIterator",695);var rAt=fq(_6n,"EList");lAn(67,52,{20:1,28:1,52:1,14:1,15:1,67:1,58:1}),EWn.Vc=function(n,t){uln(this,n,t)},EWn.Fc=function(n){return s9(this,n)},EWn.Wc=function(n,t){return aon(this,n,t)},EWn.Gc=function(n){return dX(this,n)},EWn.Zh=function(){return new rx(this)},EWn.$h=function(){return new cx(this)},EWn._h=function(n){return uin(this,n)},EWn.ai=function(){return!0},EWn.bi=function(n,t){},EWn.ci=function(){},EWn.di=function(n,t){A8(this,n,t)},EWn.ei=function(n,t,e){},EWn.fi=function(n,t){},EWn.gi=function(n,t,e){},EWn.Fb=function(n){return WDn(this,n)},EWn.Hb=function(){return Eun(this)},EWn.hi=function(){return!1},EWn.Kc=function(){return new CL(this)},EWn.Yc=function(){return new ix(this)},EWn.Zc=function(n){var t;if(t=this.gc(),n<0||n>t)throw Fp(new ZR(n,t));return new HU(this,n)},EWn.ji=function(n,t){this.ii(n,this.Xc(t))},EWn.Mc=function(n){return unn(this,n)},EWn.li=function(n,t){return t},EWn._c=function(n,t){return avn(this,n,t)},EWn.Ib=function(){return Qbn(this)},EWn.ni=function(){return!0},EWn.oi=function(n,t){return Lsn(this,t)},gX(_6n,"AbstractEList",67),lAn(63,67,o8n,go,wtn,ycn),EWn.Vh=function(n,t){return _Tn(this,n,t)},EWn.Wh=function(n){return fmn(this,n)},EWn.Xh=function(n,t){Pfn(this,n,t)},EWn.Yh=function(n){i6(this,n)},EWn.pi=function(n){return K9(this,n)},EWn.$b=function(){r6(this)},EWn.Hc=function(n){return Tjn(this,n)},EWn.Xb=function(n){return Utn(this,n)},EWn.qi=function(n){var t,e,i;++this.j,n>(e=null==this.g?0:this.g.length)&&(i=this.g,(t=e+(e/2|0)+4)=0&&(this.$c(t),!0)},EWn.mi=function(n,t){return this.Ui(n,this.oi(n,t))},EWn.gc=function(){return this.Vi()},EWn.Pc=function(){return this.Wi()},EWn.Qc=function(n){return this.Xi(n)},EWn.Ib=function(){return this.Yi()},gX(_6n,"DelegatingEList",1995),lAn(1996,1995,Y8n),EWn.Vh=function(n,t){return cFn(this,n,t)},EWn.Wh=function(n){return this.Vh(this.Vi(),n)},EWn.Xh=function(n,t){nAn(this,n,t)},EWn.Yh=function(n){IOn(this,n)},EWn.ai=function(){return!this.bj()},EWn.$b=function(){gqn(this)},EWn.Zi=function(n,t,e,i,r){return new $J(this,n,t,e,i,r)},EWn.$i=function(n){fan(this.Ai(),n)},EWn._i=function(){return null},EWn.aj=function(){return-1},EWn.Ai=function(){return null},EWn.bj=function(){return!1},EWn.cj=function(n,t){return t},EWn.dj=function(n,t){return t},EWn.ej=function(){return!1},EWn.fj=function(){return!this.Ri()},EWn.ii=function(n,t){var e,i;return this.ej()?(i=this.fj(),e=CMn(this,n,t),this.$i(this.Zi(7,tln(t),e,n,i)),e):CMn(this,n,t)},EWn.$c=function(n){var t,e,i,r;return this.ej()?(e=null,i=this.fj(),t=this.Zi(4,r=lq(this,n),null,n,i),this.bj()&&r?(e=this.dj(r,e))?(e.Ei(t),e.Fi()):this.$i(t):e?(e.Ei(t),e.Fi()):this.$i(t),r):(r=lq(this,n),this.bj()&&r&&(e=this.dj(r,null))&&e.Fi(),r)},EWn.mi=function(n,t){return aFn(this,n,t)},gX(t6n,"DelegatingNotifyingListImpl",1996),lAn(143,1,Z8n),EWn.Ei=function(n){return DEn(this,n)},EWn.Fi=function(){O7(this)},EWn.xi=function(){return this.d},EWn._i=function(){return null},EWn.gj=function(){return null},EWn.yi=function(n){return-1},EWn.zi=function(){return xxn(this)},EWn.Ai=function(){return null},EWn.Bi=function(){return Dxn(this)},EWn.Ci=function(){return this.o<0?this.o<-2?-2-this.o-1:-1:this.o},EWn.hj=function(){return!1},EWn.Di=function(n){var t,e,i,r,c,a,u,o;switch(this.d){case 1:case 2:switch(n.xi()){case 1:case 2:if(HC(n.Ai())===HC(this.Ai())&&this.yi(null)==n.yi(null))return this.g=n.zi(),1==n.xi()&&(this.d=1),!0}case 4:switch(n.xi()){case 4:if(HC(n.Ai())===HC(this.Ai())&&this.yi(null)==n.yi(null))return a=Zqn(this),c=this.o<0?this.o<-2?-2-this.o-1:-1:this.o,i=n.Ci(),this.d=6,o=new wtn(2),c<=i?(s9(o,this.n),s9(o,n.Bi()),this.g=Mun(Hk(INt,1),oQn,25,15,[this.o=c,i+1])):(s9(o,n.Bi()),s9(o,this.n),this.g=Mun(Hk(INt,1),oQn,25,15,[this.o=i,c])),this.n=o,a||(this.o=-2-this.o-1),!0}break;case 6:switch(n.xi()){case 4:if(HC(n.Ai())===HC(this.Ai())&&this.yi(null)==n.yi(null)){for(a=Zqn(this),i=n.Ci(),u=_B(this.g,48),e=L8(INt,oQn,25,u.length+1,15,1),t=0;t>>0).toString(16))).a+=" (eventType: ",this.d){case 1:e.a+="SET";break;case 2:e.a+="UNSET";break;case 3:e.a+="ADD";break;case 5:e.a+="ADD_MANY";break;case 4:e.a+="REMOVE";break;case 6:e.a+="REMOVE_MANY";break;case 7:e.a+="MOVE";break;case 8:e.a+="REMOVING_ADAPTER";break;case 9:e.a+="RESOLVE";break;default:pE(e,this.d)}if(hKn(this)&&(e.a+=", touch: true"),e.a+=", position: ",pE(e,this.o<0?this.o<-2?-2-this.o-1:-1:this.o),e.a+=", notifier: ",eO(e,this.Ai()),e.a+=", feature: ",eO(e,this._i()),e.a+=", oldValue: ",eO(e,Dxn(this)),e.a+=", newValue: ",6==this.d&&iL(this.g,48)){for(t=_B(this.g,48),e.a+="[",n=0;n10?(this.b&&this.c.j==this.a||(this.b=new Oq(this),this.a=this.j),KT(this.b,n)):Tjn(this,n)},EWn.ni=function(){return!0},EWn.a=0,gX(_6n,"AbstractEList/1",953),lAn(295,73,$Qn,ZR),gX(_6n,"AbstractEList/BasicIndexOutOfBoundsException",295),lAn(40,1,WWn,CL),EWn.Nb=function(n){sU(this,n)},EWn.mj=function(){if(this.i.j!=this.f)throw Fp(new gv)},EWn.nj=function(){return mpn(this)},EWn.Ob=function(){return this.e!=this.i.gc()},EWn.Pb=function(){return this.nj()},EWn.Qb=function(){Wjn(this)},EWn.e=0,EWn.f=0,EWn.g=-1,gX(_6n,"AbstractEList/EIterator",40),lAn(278,40,iVn,ix,HU),EWn.Qb=function(){Wjn(this)},EWn.Rb=function(n){adn(this,n)},EWn.oj=function(){var n;try{return n=this.d.Xb(--this.e),this.mj(),this.g=this.e,n}catch(t){throw iL(t=hun(t),73)?(this.mj(),Fp(new vv)):Fp(t)}},EWn.pj=function(n){mmn(this,n)},EWn.Sb=function(){return 0!=this.e},EWn.Tb=function(){return this.e},EWn.Ub=function(){return this.oj()},EWn.Vb=function(){return this.e-1},EWn.Wb=function(n){this.pj(n)},gX(_6n,"AbstractEList/EListIterator",278),lAn(341,40,WWn,rx),EWn.nj=function(){return ypn(this)},EWn.Qb=function(){throw Fp(new dv)},gX(_6n,"AbstractEList/NonResolvingEIterator",341),lAn(385,278,iVn,cx,xK),EWn.Rb=function(n){throw Fp(new dv)},EWn.nj=function(){var n;try{return n=this.c.ki(this.e),this.mj(),this.g=this.e++,n}catch(t){throw iL(t=hun(t),73)?(this.mj(),Fp(new vv)):Fp(t)}},EWn.oj=function(){var n;try{return n=this.c.ki(--this.e),this.mj(),this.g=this.e,n}catch(t){throw iL(t=hun(t),73)?(this.mj(),Fp(new vv)):Fp(t)}},EWn.Qb=function(){throw Fp(new dv)},EWn.Wb=function(n){throw Fp(new dv)},gX(_6n,"AbstractEList/NonResolvingEListIterator",385),lAn(1982,67,e9n),EWn.Vh=function(n,t){var e,i,r,c,a,u,o,s,h;if(0!=(i=t.gc())){for(e=Msn(this,(s=null==(o=_B(van(this.a,4),126))?0:o.length)+i),(h=s-n)>0&&rHn(o,n,e,n+i,h),u=t.Kc(),c=0;ce)throw Fp(new ZR(n,e));return new _W(this,n)},EWn.$b=function(){var n,t;++this.j,t=null==(n=_B(van(this.a,4),126))?0:n.length,Kgn(this,null),A8(this,t,n)},EWn.Hc=function(n){var t,e,i,r;if(null!=(t=_B(van(this.a,4),126)))if(null!=n){for(i=0,r=(e=t).length;i=(e=null==(t=_B(van(this.a,4),126))?0:t.length))throw Fp(new ZR(n,e));return t[n]},EWn.Xc=function(n){var t,e,i;if(null!=(t=_B(van(this.a,4),126)))if(null!=n){for(e=0,i=t.length;ee)throw Fp(new ZR(n,e));return new KW(this,n)},EWn.ii=function(n,t){var e,i,r;if(n>=(r=null==(e=Odn(this))?0:e.length))throw Fp(new Cy(c8n+n+a8n+r));if(t>=r)throw Fp(new Cy(u8n+t+a8n+r));return i=e[t],n!=t&&(n0&&rHn(n,0,t,0,e),t},EWn.Qc=function(n){var t,e;return(e=null==(t=_B(van(this.a,4),126))?0:t.length)>0&&(n.lengthe&&OX(n,e,null),n},gX(_6n,"ArrayDelegatingEList",1982),lAn(1038,40,WWn,E5),EWn.mj=function(){if(this.b.j!=this.f||HC(_B(van(this.b.a,4),126))!==HC(this.a))throw Fp(new gv)},EWn.Qb=function(){Wjn(this),this.a=_B(van(this.b.a,4),126)},gX(_6n,"ArrayDelegatingEList/EIterator",1038),lAn(706,278,iVn,Wz,KW),EWn.mj=function(){if(this.b.j!=this.f||HC(_B(van(this.b.a,4),126))!==HC(this.a))throw Fp(new gv)},EWn.pj=function(n){mmn(this,n),this.a=_B(van(this.b.a,4),126)},EWn.Qb=function(){Wjn(this),this.a=_B(van(this.b.a,4),126)},gX(_6n,"ArrayDelegatingEList/EListIterator",706),lAn(1039,341,WWn,T5),EWn.mj=function(){if(this.b.j!=this.f||HC(_B(van(this.b.a,4),126))!==HC(this.a))throw Fp(new gv)},gX(_6n,"ArrayDelegatingEList/NonResolvingEIterator",1039),lAn(707,385,iVn,Vz,_W),EWn.mj=function(){if(this.b.j!=this.f||HC(_B(van(this.b.a,4),126))!==HC(this.a))throw Fp(new gv)},gX(_6n,"ArrayDelegatingEList/NonResolvingEListIterator",707),lAn(606,295,$Qn,AO),gX(_6n,"BasicEList/BasicIndexOutOfBoundsException",606),lAn(696,63,o8n,NC),EWn.Vc=function(n,t){throw Fp(new dv)},EWn.Fc=function(n){throw Fp(new dv)},EWn.Wc=function(n,t){throw Fp(new dv)},EWn.Gc=function(n){throw Fp(new dv)},EWn.$b=function(){throw Fp(new dv)},EWn.qi=function(n){throw Fp(new dv)},EWn.Kc=function(){return this.Zh()},EWn.Yc=function(){return this.$h()},EWn.Zc=function(n){return this._h(n)},EWn.ii=function(n,t){throw Fp(new dv)},EWn.ji=function(n,t){throw Fp(new dv)},EWn.$c=function(n){throw Fp(new dv)},EWn.Mc=function(n){throw Fp(new dv)},EWn._c=function(n,t){throw Fp(new dv)},gX(_6n,"BasicEList/UnmodifiableEList",696),lAn(705,1,{3:1,20:1,14:1,15:1,58:1,589:1}),EWn.Vc=function(n,t){W$(this,n,_B(t,42))},EWn.Fc=function(n){return rD(this,_B(n,42))},EWn.Jc=function(n){n5(this,n)},EWn.Xb=function(n){return _B(Utn(this.c,n),133)},EWn.ii=function(n,t){return _B(this.c.ii(n,t),42)},EWn.ji=function(n,t){V$(this,n,_B(t,42))},EWn.Lc=function(){return new xq(null,new l1(this,16))},EWn.$c=function(n){return _B(this.c.$c(n),42)},EWn._c=function(n,t){return cX(this,n,_B(t,42))},EWn.ad=function(n){Rrn(this,n)},EWn.Nc=function(){return new l1(this,16)},EWn.Oc=function(){return new xq(null,new l1(this,16))},EWn.Wc=function(n,t){return this.c.Wc(n,t)},EWn.Gc=function(n){return this.c.Gc(n)},EWn.$b=function(){this.c.$b()},EWn.Hc=function(n){return this.c.Hc(n)},EWn.Ic=function(n){return aun(this.c,n)},EWn.qj=function(){var n,t;if(null==this.d){for(this.d=L8(uAt,i9n,63,2*this.f+1,0,1),t=this.e,this.f=0,n=this.c.Kc();n.e!=n.i.gc();)Pvn(this,_B(n.nj(),133));this.e=t}},EWn.Fb=function(n){return $K(this,n)},EWn.Hb=function(){return Eun(this.c)},EWn.Xc=function(n){return this.c.Xc(n)},EWn.rj=function(){this.c=new op(this)},EWn.dc=function(){return 0==this.f},EWn.Kc=function(){return this.c.Kc()},EWn.Yc=function(){return this.c.Yc()},EWn.Zc=function(n){return this.c.Zc(n)},EWn.sj=function(){return C8(this)},EWn.tj=function(n,t,e){return new TB(n,t,e)},EWn.uj=function(){return new vo},EWn.Mc=function(n){return oin(this,n)},EWn.gc=function(){return this.f},EWn.bd=function(n,t){return new u1(this.c,n,t)},EWn.Pc=function(){return this.c.Pc()},EWn.Qc=function(n){return this.c.Qc(n)},EWn.Ib=function(){return Qbn(this.c)},EWn.e=0,EWn.f=0,gX(_6n,"BasicEMap",705),lAn(1033,63,o8n,op),EWn.bi=function(n,t){Cv(this,_B(t,133))},EWn.ei=function(n,t,e){var i;++(i=this,_B(t,133),i).a.e},EWn.fi=function(n,t){Ov(this,_B(t,133))},EWn.gi=function(n,t,e){XN(this,_B(t,133),_B(e,133))},EWn.di=function(n,t){ran(this.a)},gX(_6n,"BasicEMap/1",1033),lAn(1034,63,o8n,vo),EWn.ri=function(n){return L8(dAt,r9n,612,n,0,1)},gX(_6n,"BasicEMap/2",1034),lAn(1035,YWn,ZWn,sp),EWn.$b=function(){this.a.c.$b()},EWn.Hc=function(n){return edn(this.a,n)},EWn.Kc=function(){return 0==this.a.f?(bD(),wAt.a):new _j(this.a)},EWn.Mc=function(n){var t;return t=this.a.f,Udn(this.a,n),this.a.f!=t},EWn.gc=function(){return this.a.f},gX(_6n,"BasicEMap/3",1035),lAn(1036,28,JWn,hp),EWn.$b=function(){this.a.c.$b()},EWn.Hc=function(n){return VDn(this.a,n)},EWn.Kc=function(){return 0==this.a.f?(bD(),wAt.a):new Fj(this.a)},EWn.gc=function(){return this.a.f},gX(_6n,"BasicEMap/4",1036),lAn(1037,YWn,ZWn,fp),EWn.$b=function(){this.a.c.$b()},EWn.Hc=function(n){var t,e,i,r,c,a,u,o,s;if(this.a.f>0&&iL(n,42)&&(this.a.qj(),r=null==(u=(o=_B(n,42)).cd())?0:Yon(u),c=nR(this.a,r),t=this.a.d[c]))for(e=_B(t.g,367),s=t.i,a=0;a"+this.c},EWn.a=0;var wAt,dAt=gX(_6n,"BasicEMap/EntryImpl",612);lAn(536,1,{},oo),gX(_6n,"BasicEMap/View",536),lAn(768,1,{}),EWn.Fb=function(n){return $An((TQ(),uet),n)},EWn.Hb=function(){return Kon((TQ(),uet))},EWn.Ib=function(){return AMn((TQ(),uet))},gX(_6n,"ECollections/BasicEmptyUnmodifiableEList",768),lAn(1312,1,iVn,mo),EWn.Nb=function(n){sU(this,n)},EWn.Rb=function(n){throw Fp(new dv)},EWn.Ob=function(){return!1},EWn.Sb=function(){return!1},EWn.Pb=function(){throw Fp(new vv)},EWn.Tb=function(){return 0},EWn.Ub=function(){throw Fp(new vv)},EWn.Vb=function(){return-1},EWn.Qb=function(){throw Fp(new dv)},EWn.Wb=function(n){throw Fp(new dv)},gX(_6n,"ECollections/BasicEmptyUnmodifiableEList/1",1312),lAn(1310,768,{20:1,14:1,15:1,58:1},jm),EWn.Vc=function(n,t){$E()},EWn.Fc=function(n){return LE()},EWn.Wc=function(n,t){return NE()},EWn.Gc=function(n){return xE()},EWn.$b=function(){DE()},EWn.Hc=function(n){return!1},EWn.Ic=function(n){return!1},EWn.Jc=function(n){n5(this,n)},EWn.Xb=function(n){return vO((TQ(),n)),null},EWn.Xc=function(n){return-1},EWn.dc=function(){return!0},EWn.Kc=function(){return this.a},EWn.Yc=function(){return this.a},EWn.Zc=function(n){return this.a},EWn.ii=function(n,t){return RE()},EWn.ji=function(n,t){KE()},EWn.Lc=function(){return new xq(null,new l1(this,16))},EWn.$c=function(n){return _E()},EWn.Mc=function(n){return FE()},EWn._c=function(n,t){return BE()},EWn.gc=function(){return 0},EWn.ad=function(n){Rrn(this,n)},EWn.Nc=function(){return new l1(this,16)},EWn.Oc=function(){return new xq(null,new l1(this,16))},EWn.bd=function(n,t){return TQ(),new u1(uet,n,t)},EWn.Pc=function(){return iz((TQ(),uet))},EWn.Qc=function(n){return TQ(),kmn(uet,n)},gX(_6n,"ECollections/EmptyUnmodifiableEList",1310),lAn(1311,768,{20:1,14:1,15:1,58:1,589:1},Em),EWn.Vc=function(n,t){$E()},EWn.Fc=function(n){return LE()},EWn.Wc=function(n,t){return NE()},EWn.Gc=function(n){return xE()},EWn.$b=function(){DE()},EWn.Hc=function(n){return!1},EWn.Ic=function(n){return!1},EWn.Jc=function(n){n5(this,n)},EWn.Xb=function(n){return vO((TQ(),n)),null},EWn.Xc=function(n){return-1},EWn.dc=function(){return!0},EWn.Kc=function(){return this.a},EWn.Yc=function(){return this.a},EWn.Zc=function(n){return this.a},EWn.ii=function(n,t){return RE()},EWn.ji=function(n,t){KE()},EWn.Lc=function(){return new xq(null,new l1(this,16))},EWn.$c=function(n){return _E()},EWn.Mc=function(n){return FE()},EWn._c=function(n,t){return BE()},EWn.gc=function(){return 0},EWn.ad=function(n){Rrn(this,n)},EWn.Nc=function(){return new l1(this,16)},EWn.Oc=function(){return new xq(null,new l1(this,16))},EWn.bd=function(n,t){return TQ(),new u1(uet,n,t)},EWn.Pc=function(){return iz((TQ(),uet))},EWn.Qc=function(n){return TQ(),kmn(uet,n)},EWn.sj=function(){return TQ(),TQ(),oet},gX(_6n,"ECollections/EmptyUnmodifiableEMap",1311);var gAt,pAt=fq(_6n,"Enumerator");lAn(281,1,{281:1},eRn),EWn.Fb=function(n){var t;return this===n||!!iL(n,281)&&(t=_B(n,281),this.f==t.f&&gG(this.i,t.i)&&dG(this.a,0!=(256&this.f)?0!=(256&t.f)?t.a:null:0!=(256&t.f)?null:t.a)&&dG(this.d,t.d)&&dG(this.g,t.g)&&dG(this.e,t.e)&&Tpn(this,t))},EWn.Hb=function(){return this.f},EWn.Ib=function(){return E_n(this)},EWn.f=0;var vAt,mAt,yAt,kAt=0,jAt=0,EAt=0,TAt=0,MAt=0,SAt=0,PAt=0,IAt=0,CAt=0,OAt=0,AAt=0,$At=0,LAt=0;gX(_6n,"URI",281),lAn(1091,43,ZQn,Tm),EWn.zc=function(n,t){return _B(pZ(this,TD(n),_B(t,281)),281)},gX(_6n,"URI/URICache",1091),lAn(497,63,o8n,fo,eG),EWn.hi=function(){return!0},gX(_6n,"UniqueEList",497),lAn(581,60,_Vn,A7),gX(_6n,"WrappedException",581);var NAt,xAt=fq(B5n,u9n),DAt=fq(B5n,o9n),RAt=fq(B5n,s9n),KAt=fq(B5n,h9n),_At=fq(B5n,f9n),FAt=fq(B5n,"EClass"),BAt=fq(B5n,"EDataType");lAn(1183,43,ZQn,Mm),EWn.xc=function(n){return zC(n)?TY(this,n):BC(CJ(this.f,n))},gX(B5n,"EDataType/Internal/ConversionDelegate/Factory/Registry/Impl",1183);var HAt,qAt,GAt=fq(B5n,"EEnum"),zAt=fq(B5n,l9n),UAt=fq(B5n,b9n),XAt=fq(B5n,w9n),WAt=fq(B5n,d9n),VAt=fq(B5n,g9n);lAn(1029,1,{},ho),EWn.Ib=function(){return"NIL"},gX(B5n,"EStructuralFeature/Internal/DynamicValueHolder/1",1029),lAn(1028,43,ZQn,Sm),EWn.xc=function(n){return zC(n)?TY(this,n):BC(CJ(this.f,n))},gX(B5n,"EStructuralFeature/Internal/SettingDelegate/Factory/Registry/Impl",1028);var QAt,JAt,YAt,ZAt,n$t,t$t,e$t,i$t,r$t,c$t,a$t,u$t,o$t,s$t,h$t,f$t,l$t,b$t,w$t,d$t,g$t,p$t,v$t,m$t,y$t,k$t,j$t,E$t,T$t,M$t,S$t,P$t=fq(B5n,p9n),I$t=fq(B5n,"EValidator/PatternMatcher"),C$t=fq(v9n,"FeatureMap/Entry");lAn(535,1,{72:1},SC),EWn.ak=function(){return this.a},EWn.dd=function(){return this.b},gX(h6n,"BasicEObjectImpl/1",535),lAn(1027,1,m9n,PC),EWn.Wj=function(n){return X5(this.a,this.b,n)},EWn.fj=function(){return JY(this.a,this.b)},EWn.Wb=function(n){$Y(this.a,this.b,n)},EWn.Xj=function(){MW(this.a,this.b)},gX(h6n,"BasicEObjectImpl/4",1027),lAn(1983,1,{108:1}),EWn.bk=function(n){this.e=0==n?j$t:L8(Cnt,FWn,1,n,5,1)},EWn.Ch=function(n){return this.e[n]},EWn.Dh=function(n,t){this.e[n]=t},EWn.Eh=function(n){this.e[n]=null},EWn.ck=function(){return this.c},EWn.dk=function(){throw Fp(new dv)},EWn.ek=function(){throw Fp(new dv)},EWn.fk=function(){return this.d},EWn.gk=function(){return null!=this.e},EWn.hk=function(n){this.c=n},EWn.ik=function(n){throw Fp(new dv)},EWn.jk=function(n){throw Fp(new dv)},EWn.kk=function(n){this.d=n},gX(h6n,"BasicEObjectImpl/EPropertiesHolderBaseImpl",1983),lAn(185,1983,{108:1},Df),EWn.dk=function(){return this.a},EWn.ek=function(){return this.b},EWn.ik=function(n){this.a=n},EWn.jk=function(n){this.b=n},gX(h6n,"BasicEObjectImpl/EPropertiesHolderImpl",185),lAn(506,97,s6n,yo),EWn.Kg=function(){return this.f},EWn.Pg=function(){return this.k},EWn.Rg=function(n,t){this.g=n,this.i=t},EWn.Tg=function(){return 0==(2&this.j)?this.zh():this.ph().ck()},EWn.Vg=function(){return this.i},EWn.Mg=function(){return 0!=(1&this.j)},EWn.eh=function(){return this.g},EWn.kh=function(){return 0!=(4&this.j)},EWn.ph=function(){return!this.k&&(this.k=new Df),this.k},EWn.th=function(n){this.ph().hk(n),n?this.j|=2:this.j&=-3},EWn.vh=function(n){this.ph().jk(n),n?this.j|=4:this.j&=-5},EWn.zh=function(){return(WX(),YAt).S},EWn.i=0,EWn.j=1,gX(h6n,"EObjectImpl",506),lAn(780,506,{105:1,92:1,90:1,56:1,108:1,49:1,97:1},yH),EWn.Ch=function(n){return this.e[n]},EWn.Dh=function(n,t){this.e[n]=t},EWn.Eh=function(n){this.e[n]=null},EWn.Tg=function(){return this.d},EWn.Yg=function(n){return Cwn(this.d,n)},EWn.$g=function(){return this.d},EWn.dh=function(){return null!=this.e},EWn.ph=function(){return!this.k&&(this.k=new ko),this.k},EWn.th=function(n){this.d=n},EWn.yh=function(){var n;return null==this.e&&(n=fX(this.d),this.e=0==n?E$t:L8(Cnt,FWn,1,n,5,1)),this},EWn.Ah=function(){return 0},gX(h6n,"DynamicEObjectImpl",780),lAn(1376,780,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1},sq),EWn.Fb=function(n){return this===n},EWn.Hb=function(){return MN(this)},EWn.th=function(n){this.d=n,this.b=$Nn(n,"key"),this.c=$Nn(n,k6n)},EWn.Sh=function(){var n;return-1==this.a&&(n=Q7(this,this.b),this.a=null==n?0:Yon(n)),this.a},EWn.cd=function(){return Q7(this,this.b)},EWn.dd=function(){return Q7(this,this.c)},EWn.Th=function(n){this.a=n},EWn.Uh=function(n){$Y(this,this.b,n)},EWn.ed=function(n){var t;return t=Q7(this,this.c),$Y(this,this.c,n),t},EWn.a=0,gX(h6n,"DynamicEObjectImpl/BasicEMapEntry",1376),lAn(1377,1,{108:1},ko),EWn.bk=function(n){throw Fp(new dv)},EWn.Ch=function(n){throw Fp(new dv)},EWn.Dh=function(n,t){throw Fp(new dv)},EWn.Eh=function(n){throw Fp(new dv)},EWn.ck=function(){throw Fp(new dv)},EWn.dk=function(){return this.a},EWn.ek=function(){return this.b},EWn.fk=function(){return this.c},EWn.gk=function(){throw Fp(new dv)},EWn.hk=function(n){throw Fp(new dv)},EWn.ik=function(n){this.a=n},EWn.jk=function(n){this.b=n},EWn.kk=function(n){this.c=n},gX(h6n,"DynamicEObjectImpl/DynamicEPropertiesHolderImpl",1377),lAn(510,150,{105:1,92:1,90:1,590:1,147:1,56:1,108:1,49:1,97:1,510:1,150:1,114:1,115:1},jo),EWn.Qg=function(n){return fkn(this,n)},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.d;case 2:return e?(!this.b&&(this.b=new Qx((wWn(),v$t),G$t,this)),this.b):(!this.b&&(this.b=new Qx((wWn(),v$t),G$t,this)),C8(this.b));case 3:return fZ(this);case 4:return!this.a&&(this.a=new OL(OOt,this,4)),this.a;case 5:return!this.c&&(this.c=new xL(OOt,this,5)),this.c}return G9(this,n-fX((wWn(),ZAt)),ttn(_B(van(this,16),26)||ZAt,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?fkn(this,e):this.Cb.ih(this,-1-i,null,e)),WG(this,_B(n,147),e)}return _B(ttn(_B(van(this,16),26)||(wWn(),ZAt),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),ZAt)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 2:return!this.b&&(this.b=new Qx((wWn(),v$t),G$t,this)),_K(this.b,n,e);case 3:return WG(this,null,e);case 4:return!this.a&&(this.a=new OL(OOt,this,4)),Rpn(this.a,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),ZAt),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),ZAt)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.d;case 2:return!!this.b&&0!=this.b.f;case 3:return!!fZ(this);case 4:return!!this.a&&0!=this.a.i;case 5:return!!this.c&&0!=this.c.i}return I3(this,n-fX((wWn(),ZAt)),ttn(_B(van(this,16),26)||ZAt,n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void dq(this,TD(t));case 2:return!this.b&&(this.b=new Qx((wWn(),v$t),G$t,this)),void Zcn(this.b,t);case 3:return void INn(this,_B(t,147));case 4:return!this.a&&(this.a=new OL(OOt,this,4)),uqn(this.a),!this.a&&(this.a=new OL(OOt,this,4)),void dX(this.a,_B(t,14));case 5:return!this.c&&(this.c=new xL(OOt,this,5)),uqn(this.c),!this.c&&(this.c=new xL(OOt,this,5)),void dX(this.c,_B(t,14))}Abn(this,n-fX((wWn(),ZAt)),ttn(_B(van(this,16),26)||ZAt,n),t)},EWn.zh=function(){return wWn(),ZAt},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void _in(this,null);case 2:return!this.b&&(this.b=new Qx((wWn(),v$t),G$t,this)),void this.b.c.$b();case 3:return void INn(this,null);case 4:return!this.a&&(this.a=new OL(OOt,this,4)),void uqn(this.a);case 5:return!this.c&&(this.c=new xL(OOt,this,5)),void uqn(this.c)}Bfn(this,n-fX((wWn(),ZAt)),ttn(_B(van(this,16),26)||ZAt,n))},EWn.Ib=function(){return Xfn(this)},EWn.d=null,gX(h6n,"EAnnotationImpl",510),lAn(151,705,y9n,v9),EWn.Xh=function(n,t){YA(this,n,_B(t,42))},EWn.lk=function(n,t){return KK(this,_B(n,42),t)},EWn.pi=function(n){return _B(_B(this.c,69).pi(n),133)},EWn.Zh=function(){return _B(this.c,69).Zh()},EWn.$h=function(){return _B(this.c,69).$h()},EWn._h=function(n){return _B(this.c,69)._h(n)},EWn.mk=function(n,t){return _K(this,n,t)},EWn.Wj=function(n){return _B(this.c,76).Wj(n)},EWn.rj=function(){},EWn.fj=function(){return _B(this.c,76).fj()},EWn.tj=function(n,t,e){var i;return(i=_B(Gtn(this.b).Nh().Jh(this.b),133)).Th(n),i.Uh(t),i.ed(e),i},EWn.uj=function(){return new Pp(this)},EWn.Wb=function(n){Zcn(this,n)},EWn.Xj=function(){_B(this.c,76).Xj()},gX(v9n,"EcoreEMap",151),lAn(158,151,y9n,Qx),EWn.qj=function(){var n,t,e,i,r;if(null==this.d){for(r=L8(uAt,i9n,63,2*this.f+1,0,1),e=this.c.Kc();e.e!=e.i.gc();)!(n=r[i=((t=_B(e.nj(),133)).Sh()&NWn)%r.length])&&(n=r[i]=new Pp(this)),n.Fc(t);this.d=r}},gX(h6n,"EAnnotationImpl/1",158),lAn(284,438,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,472:1,49:1,97:1,150:1,284:1,114:1,115:1}),EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),!!this.$j();case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q}return G9(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 9:return wX(this,e)}return _B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Rj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.$j();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i)}return I3(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void this.Lh(TD(t));case 2:return void Vfn(this,By(jD(t)));case 3:return void Yfn(this,By(jD(t)));case 4:return void Aen(this,_B(t,19).a);case 5:return void this.ok(_B(t,19).a);case 8:return void Phn(this,_B(t,138));case 9:return void((e=FTn(this,_B(t,87),null))&&e.Fi())}Abn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t)},EWn.zh=function(){return wWn(),y$t},EWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void this.Lh(null);case 2:return void Vfn(this,!0);case 3:return void Yfn(this,!0);case 4:return void Aen(this,0);case 5:return void this.ok(1);case 8:return void Phn(this,null);case 9:return void((t=FTn(this,null,null))&&t.Fi())}Bfn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.Gh=function(){Pkn(this),this.Bb|=1},EWn.Yj=function(){return Pkn(this)},EWn.Zj=function(){return this.t},EWn.$j=function(){var n;return(n=this.t)>1||-1==n},EWn.hi=function(){return 0!=(512&this.Bb)},EWn.nk=function(n,t){return Mfn(this,n,t)},EWn.ok=function(n){$en(this,n)},EWn.Ib=function(){return DOn(this)},EWn.s=0,EWn.t=1,gX(h6n,"ETypedElementImpl",284),lAn(449,284,{105:1,92:1,90:1,147:1,191:1,56:1,170:1,66:1,108:1,472:1,49:1,97:1,150:1,449:1,284:1,114:1,115:1,677:1}),EWn.Qg=function(n){return $yn(this,n)},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),!!this.$j();case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q;case 10:return oN(),0!=(this.Bb&m6n);case 11:return oN(),0!=(this.Bb&E9n);case 12:return oN(),0!=(this.Bb&RQn);case 13:return this.j;case 14:return BLn(this);case 15:return oN(),0!=(this.Bb&j9n);case 16:return oN(),0!=(this.Bb&oVn);case 17:return bZ(this)}return G9(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 17:return this.Cb&&(e=(i=this.Db>>16)>=0?$yn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,17,e)}return _B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Qj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 9:return wX(this,e);case 17:return j_n(this,null,17,e)}return _B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Rj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.$j();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i);case 10:return 0==(this.Bb&m6n);case 11:return 0!=(this.Bb&E9n);case 12:return 0!=(this.Bb&RQn);case 13:return null!=this.j;case 14:return null!=BLn(this);case 15:return 0!=(this.Bb&j9n);case 16:return 0!=(this.Bb&oVn);case 17:return!!bZ(this)}return I3(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void QZ(this,TD(t));case 2:return void Vfn(this,By(jD(t)));case 3:return void Yfn(this,By(jD(t)));case 4:return void Aen(this,_B(t,19).a);case 5:return void this.ok(_B(t,19).a);case 8:return void Phn(this,_B(t,138));case 9:return void((e=FTn(this,_B(t,87),null))&&e.Fi());case 10:return void Cln(this,By(jD(t)));case 11:return void $ln(this,By(jD(t)));case 12:return void Oln(this,By(jD(t)));case 13:return void RC(this,TD(t));case 15:return void Aln(this,By(jD(t)));case 16:return void Bln(this,By(jD(t)))}Abn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t)},EWn.zh=function(){return wWn(),m$t},EWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,88)&&CIn(M5(_B(this.Cb,88)),4),void $rn(this,null);case 2:return void Vfn(this,!0);case 3:return void Yfn(this,!0);case 4:return void Aen(this,0);case 5:return void this.ok(1);case 8:return void Phn(this,null);case 9:return void((t=FTn(this,null,null))&&t.Fi());case 10:return void Cln(this,!0);case 11:return void $ln(this,!1);case 12:return void Oln(this,!1);case 13:return this.i=null,void rrn(this,null);case 15:return void Aln(this,!1);case 16:return void Bln(this,!1)}Bfn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.Gh=function(){mV(_7((PPn(),Q$t),this)),Pkn(this),this.Bb|=1},EWn.Gj=function(){return this.f},EWn.zj=function(){return BLn(this)},EWn.Hj=function(){return bZ(this)},EWn.Lj=function(){return null},EWn.pk=function(){return this.k},EWn.aj=function(){return this.n},EWn.Mj=function(){return aEn(this)},EWn.Nj=function(){var n,t,e,i,r,c,a,u,o;return this.p||((null==(e=bZ(this)).i&&BFn(e),e.i).length,(i=this.Lj())&&fX(bZ(i)),n=(a=(r=Pkn(this)).Bj())?0!=(1&a.i)?a==CNt?mtt:a==INt?Ctt:a==LNt?Stt:a==$Nt?Mtt:a==ONt?xtt:a==NNt?Rtt:a==ANt?jtt:Ttt:a:null,t=BLn(this),u=r.zj(),fbn(this),0!=(this.Bb&oVn)&&((c=pjn((PPn(),Q$t),e))&&c!=this||(c=J1(_7(Q$t,this))))?this.p=new CC(this,c):this.$j()?this.rk()?i?0!=(this.Bb&j9n)?n?this.sk()?this.p=new hQ(47,n,this,i):this.p=new hQ(5,n,this,i):this.sk()?this.p=new l4(46,this,i):this.p=new l4(4,this,i):n?this.sk()?this.p=new hQ(49,n,this,i):this.p=new hQ(7,n,this,i):this.sk()?this.p=new l4(48,this,i):this.p=new l4(6,this,i):0!=(this.Bb&j9n)?n?n==Fnt?this.p=new MB(50,UOt,this):this.sk()?this.p=new MB(43,n,this):this.p=new MB(1,n,this):this.sk()?this.p=new xJ(42,this):this.p=new xJ(0,this):n?n==Fnt?this.p=new MB(41,UOt,this):this.sk()?this.p=new MB(45,n,this):this.p=new MB(3,n,this):this.sk()?this.p=new xJ(44,this):this.p=new xJ(2,this):iL(r,148)?n==C$t?this.p=new xJ(40,this):0!=(512&this.Bb)?0!=(this.Bb&j9n)?this.p=n?new MB(9,n,this):new xJ(8,this):this.p=n?new MB(11,n,this):new xJ(10,this):0!=(this.Bb&j9n)?this.p=n?new MB(13,n,this):new xJ(12,this):this.p=n?new MB(15,n,this):new xJ(14,this):i?(o=i.t)>1||-1==o?this.sk()?0!=(this.Bb&j9n)?this.p=n?new hQ(25,n,this,i):new l4(24,this,i):this.p=n?new hQ(27,n,this,i):new l4(26,this,i):0!=(this.Bb&j9n)?this.p=n?new hQ(29,n,this,i):new l4(28,this,i):this.p=n?new hQ(31,n,this,i):new l4(30,this,i):this.sk()?0!=(this.Bb&j9n)?this.p=n?new hQ(33,n,this,i):new l4(32,this,i):this.p=n?new hQ(35,n,this,i):new l4(34,this,i):0!=(this.Bb&j9n)?this.p=n?new hQ(37,n,this,i):new l4(36,this,i):this.p=n?new hQ(39,n,this,i):new l4(38,this,i):this.sk()?0!=(this.Bb&j9n)?this.p=n?new MB(17,n,this):new xJ(16,this):this.p=n?new MB(19,n,this):new xJ(18,this):0!=(this.Bb&j9n)?this.p=n?new MB(21,n,this):new xJ(20,this):this.p=n?new MB(23,n,this):new xJ(22,this):this.qk()?this.sk()?this.p=new SB(_B(r,26),this,i):this.p=new pY(_B(r,26),this,i):iL(r,148)?n==C$t?this.p=new xJ(40,this):0!=(this.Bb&j9n)?this.p=n?new YG(t,u,this,(_wn(),a==INt?F$t:a==CNt?x$t:a==ONt?B$t:a==LNt?_$t:a==$Nt?K$t:a==NNt?q$t:a==ANt?D$t:a==PNt?R$t:H$t)):new bQ(_B(r,148),t,u,this):this.p=n?new JG(t,u,this,(_wn(),a==INt?F$t:a==CNt?x$t:a==ONt?B$t:a==LNt?_$t:a==$Nt?K$t:a==NNt?q$t:a==ANt?D$t:a==PNt?R$t:H$t)):new lQ(_B(r,148),t,u,this):this.rk()?i?0!=(this.Bb&j9n)?this.sk()?this.p=new $B(_B(r,26),this,i):this.p=new AB(_B(r,26),this,i):this.sk()?this.p=new OB(_B(r,26),this,i):this.p=new PB(_B(r,26),this,i):0!=(this.Bb&j9n)?this.sk()?this.p=new nD(_B(r,26),this):this.p=new Zx(_B(r,26),this):this.sk()?this.p=new Yx(_B(r,26),this):this.p=new Jx(_B(r,26),this):this.sk()?i?0!=(this.Bb&j9n)?this.p=new LB(_B(r,26),this,i):this.p=new IB(_B(r,26),this,i):0!=(this.Bb&j9n)?this.p=new eD(_B(r,26),this):this.p=new tD(_B(r,26),this):i?0!=(this.Bb&j9n)?this.p=new NB(_B(r,26),this,i):this.p=new CB(_B(r,26),this,i):0!=(this.Bb&j9n)?this.p=new iD(_B(r,26),this):this.p=new iG(_B(r,26),this)),this.p},EWn.Ij=function(){return 0!=(this.Bb&m6n)},EWn.qk=function(){return!1},EWn.rk=function(){return!1},EWn.Jj=function(){return 0!=(this.Bb&oVn)},EWn.Oj=function(){return onn(this)},EWn.sk=function(){return!1},EWn.Kj=function(){return 0!=(this.Bb&j9n)},EWn.tk=function(n){this.k=n},EWn.Lh=function(n){QZ(this,n)},EWn.Ib=function(){return kRn(this)},EWn.e=!1,EWn.n=0,gX(h6n,"EStructuralFeatureImpl",449),lAn(322,449,{105:1,92:1,90:1,34:1,147:1,191:1,56:1,170:1,66:1,108:1,472:1,49:1,97:1,322:1,150:1,449:1,284:1,114:1,115:1,677:1},Im),EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),!!$Cn(this);case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q;case 10:return oN(),0!=(this.Bb&m6n);case 11:return oN(),0!=(this.Bb&E9n);case 12:return oN(),0!=(this.Bb&RQn);case 13:return this.j;case 14:return BLn(this);case 15:return oN(),0!=(this.Bb&j9n);case 16:return oN(),0!=(this.Bb&oVn);case 17:return bZ(this);case 18:return oN(),0!=(this.Bb&o6n);case 19:return t?cun(this):L6(this)}return G9(this,n-fX((wWn(),n$t)),ttn(_B(van(this,16),26)||n$t,n),t,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return $Cn(this);case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i);case 10:return 0==(this.Bb&m6n);case 11:return 0!=(this.Bb&E9n);case 12:return 0!=(this.Bb&RQn);case 13:return null!=this.j;case 14:return null!=BLn(this);case 15:return 0!=(this.Bb&j9n);case 16:return 0!=(this.Bb&oVn);case 17:return!!bZ(this);case 18:return 0!=(this.Bb&o6n);case 19:return!!L6(this)}return I3(this,n-fX((wWn(),n$t)),ttn(_B(van(this,16),26)||n$t,n))},EWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void QZ(this,TD(t));case 2:return void Vfn(this,By(jD(t)));case 3:return void Yfn(this,By(jD(t)));case 4:return void Aen(this,_B(t,19).a);case 5:return void Gj(this,_B(t,19).a);case 8:return void Phn(this,_B(t,138));case 9:return void((e=FTn(this,_B(t,87),null))&&e.Fi());case 10:return void Cln(this,By(jD(t)));case 11:return void $ln(this,By(jD(t)));case 12:return void Oln(this,By(jD(t)));case 13:return void RC(this,TD(t));case 15:return void Aln(this,By(jD(t)));case 16:return void Bln(this,By(jD(t)));case 18:return void Hln(this,By(jD(t)))}Abn(this,n-fX((wWn(),n$t)),ttn(_B(van(this,16),26)||n$t,n),t)},EWn.zh=function(){return wWn(),n$t},EWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,88)&&CIn(M5(_B(this.Cb,88)),4),void $rn(this,null);case 2:return void Vfn(this,!0);case 3:return void Yfn(this,!0);case 4:return void Aen(this,0);case 5:return this.b=0,void $en(this,1);case 8:return void Phn(this,null);case 9:return void((t=FTn(this,null,null))&&t.Fi());case 10:return void Cln(this,!0);case 11:return void $ln(this,!1);case 12:return void Oln(this,!1);case 13:return this.i=null,void rrn(this,null);case 15:return void Aln(this,!1);case 16:return void Bln(this,!1);case 18:return void Hln(this,!1)}Bfn(this,n-fX((wWn(),n$t)),ttn(_B(van(this,16),26)||n$t,n))},EWn.Gh=function(){cun(this),mV(_7((PPn(),Q$t),this)),Pkn(this),this.Bb|=1},EWn.$j=function(){return $Cn(this)},EWn.nk=function(n,t){return this.b=0,this.a=null,Mfn(this,n,t)},EWn.ok=function(n){Gj(this,n)},EWn.Ib=function(){var n;return 0!=(64&this.Db)?kRn(this):((n=new sN(kRn(this))).a+=" (iD: ",vE(n,0!=(this.Bb&o6n)),n.a+=")",n.a)},EWn.b=0,gX(h6n,"EAttributeImpl",322),lAn(351,438,{105:1,92:1,90:1,138:1,147:1,191:1,56:1,108:1,49:1,97:1,351:1,150:1,114:1,115:1,676:1}),EWn.uk=function(n){return n.Tg()==this},EWn.Qg=function(n){return syn(this,n)},EWn.Rg=function(n,t){this.w=null,this.Db=t<<16|255&this.Db,this.Cb=n},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return tyn(this);case 4:return this.zj();case 5:return this.F;case 6:return t?Gtn(this):lZ(this);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),this.A}return G9(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?syn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,6,e)}return _B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Qj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 6:return j_n(this,null,6,e);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),Rpn(this.A,n,e)}return _B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Rj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!tyn(this);case 4:return null!=this.zj();case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!lZ(this);case 7:return!!this.A&&0!=this.A.i}return I3(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void JZ(this,TD(t));case 2:return void PA(this,TD(t));case 5:return void Vqn(this,TD(t));case 7:return!this.A&&(this.A=new $L(P$t,this,7)),uqn(this.A),!this.A&&(this.A=new $L(P$t,this,7)),void dX(this.A,_B(t,14))}Abn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t)},EWn.zh=function(){return wWn(),e$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,179)&&(_B(this.Cb,179).tb=null),void $rn(this,null);case 2:return Nsn(this,null),void Len(this,this.D);case 5:return void Vqn(this,null);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),void uqn(this.A)}Bfn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.yj=function(){var n;return-1==this.G&&(this.G=(n=Gtn(this))?cvn(n.Mh(),this):-1),this.G},EWn.zj=function(){return null},EWn.Aj=function(){return Gtn(this)},EWn.vk=function(){return this.v},EWn.Bj=function(){return tyn(this)},EWn.Cj=function(){return null!=this.D?this.D:this.B},EWn.Dj=function(){return this.F},EWn.wj=function(n){return TFn(this,n)},EWn.wk=function(n){this.v=n},EWn.xk=function(n){Grn(this,n)},EWn.yk=function(n){this.C=n},EWn.Lh=function(n){JZ(this,n)},EWn.Ib=function(){return Swn(this)},EWn.C=null,EWn.D=null,EWn.G=-1,gX(h6n,"EClassifierImpl",351),lAn(88,351,{105:1,92:1,90:1,26:1,138:1,147:1,191:1,56:1,108:1,49:1,97:1,88:1,351:1,150:1,473:1,114:1,115:1,676:1},Rf),EWn.uk=function(n){return WR(this,n.Tg())},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return tyn(this);case 4:return null;case 5:return this.F;case 6:return t?Gtn(this):lZ(this);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),this.A;case 8:return oN(),0!=(256&this.Bb);case 9:return oN(),0!=(512&this.Bb);case 10:return mJ(this);case 11:return!this.q&&(this.q=new nU(XAt,this,11,10)),this.q;case 12:return VBn(this);case 13:return xBn(this);case 14:return xBn(this),this.r;case 15:return VBn(this),this.k;case 16:return UPn(this);case 17:return wBn(this);case 18:return BFn(this);case 19:return SLn(this);case 20:return VBn(this),this.o;case 21:return!this.s&&(this.s=new nU(RAt,this,21,17)),this.s;case 22:return r4(this);case 23:return FDn(this)}return G9(this,n-fX((wWn(),t$t)),ttn(_B(van(this,16),26)||t$t,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?syn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,6,e);case 11:return!this.q&&(this.q=new nU(XAt,this,11,10)),Vwn(this.q,n,e);case 21:return!this.s&&(this.s=new nU(RAt,this,21,17)),Vwn(this.s,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),t$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),t$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 6:return j_n(this,null,6,e);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),Rpn(this.A,n,e);case 11:return!this.q&&(this.q=new nU(XAt,this,11,10)),Rpn(this.q,n,e);case 21:return!this.s&&(this.s=new nU(RAt,this,21,17)),Rpn(this.s,n,e);case 22:return Rpn(r4(this),n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),t$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),t$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!tyn(this);case 4:return!1;case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!lZ(this);case 7:return!!this.A&&0!=this.A.i;case 8:return 0!=(256&this.Bb);case 9:return 0!=(512&this.Bb);case 10:return!(!this.u||0==r4(this.u.a).i||this.n&&xvn(this.n));case 11:return!!this.q&&0!=this.q.i;case 12:return 0!=VBn(this).i;case 13:return 0!=xBn(this).i;case 14:return xBn(this),0!=this.r.i;case 15:return VBn(this),0!=this.k.i;case 16:return 0!=UPn(this).i;case 17:return 0!=wBn(this).i;case 18:return 0!=BFn(this).i;case 19:return 0!=SLn(this).i;case 20:return VBn(this),!!this.o;case 21:return!!this.s&&0!=this.s.i;case 22:return!!this.n&&xvn(this.n);case 23:return 0!=FDn(this).i}return I3(this,n-fX((wWn(),t$t)),ttn(_B(van(this,16),26)||t$t,n))},EWn.oh=function(n){return(null==this.i||this.q&&0!=this.q.i?null:$Nn(this,n))||oUn(this,n)},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void JZ(this,TD(t));case 2:return void PA(this,TD(t));case 5:return void Vqn(this,TD(t));case 7:return!this.A&&(this.A=new $L(P$t,this,7)),uqn(this.A),!this.A&&(this.A=new $L(P$t,this,7)),void dX(this.A,_B(t,14));case 8:return void Qfn(this,By(jD(t)));case 9:return void Zfn(this,By(jD(t)));case 10:return gqn(mJ(this)),void dX(mJ(this),_B(t,14));case 11:return!this.q&&(this.q=new nU(XAt,this,11,10)),uqn(this.q),!this.q&&(this.q=new nU(XAt,this,11,10)),void dX(this.q,_B(t,14));case 21:return!this.s&&(this.s=new nU(RAt,this,21,17)),uqn(this.s),!this.s&&(this.s=new nU(RAt,this,21,17)),void dX(this.s,_B(t,14));case 22:return uqn(r4(this)),void dX(r4(this),_B(t,14))}Abn(this,n-fX((wWn(),t$t)),ttn(_B(van(this,16),26)||t$t,n),t)},EWn.zh=function(){return wWn(),t$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,179)&&(_B(this.Cb,179).tb=null),void $rn(this,null);case 2:return Nsn(this,null),void Len(this,this.D);case 5:return void Vqn(this,null);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),void uqn(this.A);case 8:return void Qfn(this,!1);case 9:return void Zfn(this,!1);case 10:return void(this.u&&gqn(this.u));case 11:return!this.q&&(this.q=new nU(XAt,this,11,10)),void uqn(this.q);case 21:return!this.s&&(this.s=new nU(RAt,this,21,17)),void uqn(this.s);case 22:return void(this.n&&uqn(this.n))}Bfn(this,n-fX((wWn(),t$t)),ttn(_B(van(this,16),26)||t$t,n))},EWn.Gh=function(){var n,t;if(VBn(this),xBn(this),UPn(this),wBn(this),BFn(this),SLn(this),FDn(this),r6(zB(M5(this))),this.s)for(n=0,t=this.s.i;n=0;--t)Utn(this,t);return Wwn(this,n)},EWn.Xj=function(){uqn(this)},EWn.oi=function(n,t){return Ren(this,n,t)},gX(v9n,"EcoreEList",622),lAn(496,622,x9n,vH),EWn.ai=function(){return!1},EWn.aj=function(){return this.c},EWn.bj=function(){return!1},EWn.Fk=function(){return!0},EWn.hi=function(){return!0},EWn.li=function(n,t){return t},EWn.ni=function(){return!1},EWn.c=0,gX(v9n,"EObjectEList",496),lAn(85,496,x9n,OL),EWn.bj=function(){return!0},EWn.Dk=function(){return!1},EWn.rk=function(){return!0},gX(v9n,"EObjectContainmentEList",85),lAn(545,85,x9n,AL),EWn.ci=function(){this.b=!0},EWn.fj=function(){return this.b},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.b,this.b=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.b=!1},EWn.b=!1,gX(v9n,"EObjectContainmentEList/Unsettable",545),lAn(1140,545,x9n,VG),EWn.ii=function(n,t){var e,i;return e=_B(Pln(this,n,t),87),pA(this.e)&&Av(this,new y9(this.a,7,(wWn(),i$t),tln(t),iL(i=e.c,88)?_B(i,26):l$t,n)),e},EWn.jj=function(n,t){return Jwn(this,_B(n,87),t)},EWn.kj=function(n,t){return Qwn(this,_B(n,87),t)},EWn.lj=function(n,t,e){return Rjn(this,_B(n,87),_B(t,87),e)},EWn.Zi=function(n,t,e,i,r){switch(n){case 3:return vZ(this,n,t,e,i,this.i>1);case 5:return vZ(this,n,t,e,i,this.i-_B(e,15).gc()>0);default:return new $7(this.e,n,this.c,t,e,i,!0)}},EWn.ij=function(){return!0},EWn.fj=function(){return xvn(this)},EWn.Xj=function(){uqn(this)},gX(h6n,"EClassImpl/1",1140),lAn(1154,1153,J8n),EWn.ui=function(n){var t,e,i,r,c,a,u;if(8!=(e=n.xi())){if(0==(i=rpn(n)))switch(e){case 1:case 9:null!=(u=n.Bi())&&(!(t=M5(_B(u,473))).c&&(t.c=new Bo),unn(t.c,n.Ai())),null!=(a=n.zi())&&0==(1&(r=_B(a,473)).Bb)&&(!(t=M5(r)).c&&(t.c=new Bo),s9(t.c,_B(n.Ai(),26)));break;case 3:null!=(a=n.zi())&&0==(1&(r=_B(a,473)).Bb)&&(!(t=M5(r)).c&&(t.c=new Bo),s9(t.c,_B(n.Ai(),26)));break;case 5:if(null!=(a=n.zi()))for(c=_B(a,14).Kc();c.Ob();)0==(1&(r=_B(c.Pb(),473)).Bb)&&(!(t=M5(r)).c&&(t.c=new Bo),s9(t.c,_B(n.Ai(),26)));break;case 4:null!=(u=n.Bi())&&0==(1&(r=_B(u,473)).Bb)&&(!(t=M5(r)).c&&(t.c=new Bo),unn(t.c,n.Ai()));break;case 6:if(null!=(u=n.Bi()))for(c=_B(u,14).Kc();c.Ob();)0==(1&(r=_B(c.Pb(),473)).Bb)&&(!(t=M5(r)).c&&(t.c=new Bo),unn(t.c,n.Ai()))}this.Hk(i)}},EWn.Hk=function(n){bRn(this,n)},EWn.b=63,gX(h6n,"ESuperAdapter",1154),lAn(1155,1154,J8n,bp),EWn.Hk=function(n){CIn(this,n)},gX(h6n,"EClassImpl/10",1155),lAn(1144,696,x9n),EWn.Vh=function(n,t){return _Tn(this,n,t)},EWn.Wh=function(n){return fmn(this,n)},EWn.Xh=function(n,t){Pfn(this,n,t)},EWn.Yh=function(n){i6(this,n)},EWn.pi=function(n){return K9(this,n)},EWn.mi=function(n,t){return ann(this,n,t)},EWn.lk=function(n,t){throw Fp(new dv)},EWn.Zh=function(){return new rx(this)},EWn.$h=function(){return new cx(this)},EWn._h=function(n){return uin(this,n)},EWn.mk=function(n,t){throw Fp(new dv)},EWn.Wj=function(n){return this},EWn.fj=function(){return 0!=this.i},EWn.Wb=function(n){throw Fp(new dv)},EWn.Xj=function(){throw Fp(new dv)},gX(v9n,"EcoreEList/UnmodifiableEList",1144),lAn(319,1144,x9n,$O),EWn.ni=function(){return!1},gX(v9n,"EcoreEList/UnmodifiableEList/FastCompare",319),lAn(1147,319,x9n,bon),EWn.Xc=function(n){var t,e;if(iL(n,170)&&-1!=(t=_B(n,170).aj()))for(e=this.i;t4){if(!this.wj(n))return!1;if(this.rk()){if(a=(t=(e=_B(n,49)).Ug())==this.b&&(this.Dk()?e.Og(e.Vg(),_B(ttn(yJ(this.b),this.aj()).Yj(),26).Bj())==Svn(_B(ttn(yJ(this.b),this.aj()),18)).n:-1-e.Vg()==this.aj()),this.Ek()&&!a&&!t&&e.Zg())for(i=0;i1||-1==e)},EWn.Dk=function(){var n;return!!iL(n=ttn(yJ(this.b),this.aj()),99)&&!!Svn(_B(n,18))},EWn.Ek=function(){var n;return!!iL(n=ttn(yJ(this.b),this.aj()),99)&&0!=(_B(n,18).Bb&_Qn)},EWn.Xc=function(n){var t,e,i;if((e=this.Qi(n))>=0)return e;if(this.Fk())for(t=0,i=this.Vi();t=0;--n)nGn(this,n,this.Oi(n));return this.Wi()},EWn.Qc=function(n){var t;if(this.Ek())for(t=this.Vi()-1;t>=0;--t)nGn(this,t,this.Oi(t));return this.Xi(n)},EWn.Xj=function(){gqn(this)},EWn.oi=function(n,t){return _9(this,n,t)},gX(v9n,"DelegatingEcoreEList",742),lAn(1150,742,F9n,cR),EWn.Hi=function(n,t){hD(this,n,_B(t,26))},EWn.Ii=function(n){n$(this,_B(n,26))},EWn.Oi=function(n){var t;return iL(t=_B(Utn(r4(this.a),n),87).c,88)?_B(t,26):(wWn(),l$t)},EWn.Ti=function(n){var t;return iL(t=_B(sDn(r4(this.a),n),87).c,88)?_B(t,26):(wWn(),l$t)},EWn.Ui=function(n,t){return bmn(this,n,_B(t,26))},EWn.ai=function(){return!1},EWn.Zi=function(n,t,e,i,r){return null},EWn.Ji=function(){return new dp(this)},EWn.Ki=function(){uqn(r4(this.a))},EWn.Li=function(n){return Gfn(this,n)},EWn.Mi=function(n){var t;for(t=n.Kc();t.Ob();)if(!Gfn(this,t.Pb()))return!1;return!0},EWn.Ni=function(n){var t,e,i;if(iL(n,15)&&(i=_B(n,15)).gc()==r4(this.a).i){for(t=i.Kc(),e=new CL(this);t.Ob();)if(HC(t.Pb())!==HC(mpn(e)))return!1;return!0}return!1},EWn.Pi=function(){var n,t,e,i;for(t=1,n=new CL(r4(this.a));n.e!=n.i.gc();)t=31*t+((e=iL(i=_B(mpn(n),87).c,88)?_B(i,26):(wWn(),l$t))?MN(e):0);return t},EWn.Qi=function(n){var t,e,i,r;for(i=0,e=new CL(r4(this.a));e.e!=e.i.gc();){if(t=_B(mpn(e),87),HC(n)===HC(iL(r=t.c,88)?_B(r,26):(wWn(),l$t)))return i;++i}return-1},EWn.Ri=function(){return 0==r4(this.a).i},EWn.Si=function(){return null},EWn.Vi=function(){return r4(this.a).i},EWn.Wi=function(){var n,t,e,i,r,c;for(c=r4(this.a).i,r=L8(Cnt,FWn,1,c,5,1),e=0,t=new CL(r4(this.a));t.e!=t.i.gc();)n=_B(mpn(t),87),r[e++]=iL(i=n.c,88)?_B(i,26):(wWn(),l$t);return r},EWn.Xi=function(n){var t,e,i,r;for(r=r4(this.a).i,n.lengthr&&OX(n,r,null),e=0,t=new CL(r4(this.a));t.e!=t.i.gc();)OX(n,e++,iL(i=_B(mpn(t),87).c,88)?_B(i,26):(wWn(),l$t));return n},EWn.Yi=function(){var n,t,e,i,r;for((r=new Tk).a+="[",n=r4(this.a),t=0,i=r4(this.a).i;t>16)>=0?syn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,6,e);case 9:return!this.a&&(this.a=new nU(zAt,this,9,5)),Vwn(this.a,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),c$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),c$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 6:return j_n(this,null,6,e);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),Rpn(this.A,n,e);case 9:return!this.a&&(this.a=new nU(zAt,this,9,5)),Rpn(this.a,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),c$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),c$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!tyn(this);case 4:return!!Wsn(this);case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!lZ(this);case 7:return!!this.A&&0!=this.A.i;case 8:return 0==(256&this.Bb);case 9:return!!this.a&&0!=this.a.i}return I3(this,n-fX((wWn(),c$t)),ttn(_B(van(this,16),26)||c$t,n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void JZ(this,TD(t));case 2:return void PA(this,TD(t));case 5:return void Vqn(this,TD(t));case 7:return!this.A&&(this.A=new $L(P$t,this,7)),uqn(this.A),!this.A&&(this.A=new $L(P$t,this,7)),void dX(this.A,_B(t,14));case 8:return void Jfn(this,By(jD(t)));case 9:return!this.a&&(this.a=new nU(zAt,this,9,5)),uqn(this.a),!this.a&&(this.a=new nU(zAt,this,9,5)),void dX(this.a,_B(t,14))}Abn(this,n-fX((wWn(),c$t)),ttn(_B(van(this,16),26)||c$t,n),t)},EWn.zh=function(){return wWn(),c$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,179)&&(_B(this.Cb,179).tb=null),void $rn(this,null);case 2:return Nsn(this,null),void Len(this,this.D);case 5:return void Vqn(this,null);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),void uqn(this.A);case 8:return void Jfn(this,!0);case 9:return!this.a&&(this.a=new nU(zAt,this,9,5)),void uqn(this.a)}Bfn(this,n-fX((wWn(),c$t)),ttn(_B(van(this,16),26)||c$t,n))},EWn.Gh=function(){var n,t;if(this.a)for(n=0,t=this.a.i;n>16==5?_B(this.Cb,671):null}return G9(this,n-fX((wWn(),a$t)),ttn(_B(van(this,16),26)||a$t,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 5:return this.Cb&&(e=(i=this.Db>>16)>=0?hkn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,5,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),a$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),a$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 5:return j_n(this,null,5,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),a$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),a$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0!=this.d;case 3:return!!this.b;case 4:return null!=this.c;case 5:return!(this.Db>>16!=5||!_B(this.Cb,671))}return I3(this,n-fX((wWn(),a$t)),ttn(_B(van(this,16),26)||a$t,n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void $rn(this,TD(t));case 2:return void Oen(this,_B(t,19).a);case 3:return void wOn(this,_B(t,1940));case 4:return void Kin(this,TD(t))}Abn(this,n-fX((wWn(),a$t)),ttn(_B(van(this,16),26)||a$t,n),t)},EWn.zh=function(){return wWn(),a$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void $rn(this,null);case 2:return void Oen(this,0);case 3:return void wOn(this,null);case 4:return void Kin(this,null)}Bfn(this,n-fX((wWn(),a$t)),ttn(_B(van(this,16),26)||a$t,n))},EWn.Ib=function(){var n;return null==(n=this.c)?this.zb:n},EWn.b=null,EWn.c=null,EWn.d=0,gX(h6n,"EEnumLiteralImpl",573);var O$t,A$t,$$t,L$t=fq(h6n,"EFactoryImpl/InternalEDateTimeFormat");lAn(489,1,{2015:1},gp),gX(h6n,"EFactoryImpl/1ClientInternalEDateTimeFormat",489),lAn(241,115,{105:1,92:1,90:1,87:1,56:1,108:1,49:1,97:1,241:1,114:1,115:1},Dp),EWn.Sg=function(n,t,e){var i;return e=j_n(this,n,t,e),this.e&&iL(n,170)&&(i=mLn(this,this.e))!=this.c&&(e=rzn(this,i,e)),e},EWn._g=function(n,t,e){switch(n){case 0:return this.f;case 1:return!this.d&&(this.d=new OL(UAt,this,1)),this.d;case 2:return t?hFn(this):this.c;case 3:return this.b;case 4:return this.e;case 5:return t?Bvn(this):this.a}return G9(this,n-fX((wWn(),o$t)),ttn(_B(van(this,16),26)||o$t,n),t,e)},EWn.jh=function(n,t,e){switch(t){case 0:return Yhn(this,null,e);case 1:return!this.d&&(this.d=new OL(UAt,this,1)),Rpn(this.d,n,e);case 3:return Jhn(this,null,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),o$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),o$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.f;case 1:return!!this.d&&0!=this.d.i;case 2:return!!this.c;case 3:return!!this.b;case 4:return!!this.e;case 5:return!!this.a}return I3(this,n-fX((wWn(),o$t)),ttn(_B(van(this,16),26)||o$t,n))},EWn.sh=function(n,t){switch(n){case 0:return void yEn(this,_B(t,87));case 1:return!this.d&&(this.d=new OL(UAt,this,1)),uqn(this.d),!this.d&&(this.d=new OL(UAt,this,1)),void dX(this.d,_B(t,14));case 3:return void mEn(this,_B(t,87));case 4:return void NMn(this,_B(t,836));case 5:return void ien(this,_B(t,138))}Abn(this,n-fX((wWn(),o$t)),ttn(_B(van(this,16),26)||o$t,n),t)},EWn.zh=function(){return wWn(),o$t},EWn.Bh=function(n){switch(n){case 0:return void yEn(this,null);case 1:return!this.d&&(this.d=new OL(UAt,this,1)),void uqn(this.d);case 3:return void mEn(this,null);case 4:return void NMn(this,null);case 5:return void ien(this,null)}Bfn(this,n-fX((wWn(),o$t)),ttn(_B(van(this,16),26)||o$t,n))},EWn.Ib=function(){var n;return(n=new hN(M$n(this))).a+=" (expression: ",fHn(this,n),n.a+=")",n.a},gX(h6n,"EGenericTypeImpl",241),lAn(1969,1964,B9n),EWn.Xh=function(n,t){YD(this,n,t)},EWn.lk=function(n,t){return YD(this,this.gc(),n),t},EWn.pi=function(n){return Npn(this.Gi(),n)},EWn.Zh=function(){return this.$h()},EWn.Gi=function(){return new Mp(this)},EWn.$h=function(){return this._h(0)},EWn._h=function(n){return this.Gi().Zc(n)},EWn.mk=function(n,t){return vwn(this,n,!0),t},EWn.ii=function(n,t){var e;return e=Zyn(this,t),this.Zc(n).Rb(e),e},EWn.ji=function(n,t){vwn(this,t,!0),this.Zc(n).Rb(t)},gX(v9n,"AbstractSequentialInternalEList",1969),lAn(486,1969,B9n,WN),EWn.pi=function(n){return Npn(this.Gi(),n)},EWn.Zh=function(){return null==this.b?(VM(),VM(),$$t):this.Jk()},EWn.Gi=function(){return new NO(this.a,this.b)},EWn.$h=function(){return null==this.b?(VM(),VM(),$$t):this.Jk()},EWn._h=function(n){var t,e;if(null==this.b){if(n<0||n>1)throw Fp(new Cy(n9n+n+", size=0"));return VM(),VM(),$$t}for(e=this.Jk(),t=0;t0;)if(t=this.c[--this.d],(!this.e||t.Gj()!=AOt||0!=t.aj())&&(!this.Mk()||this.b.mh(t)))if(c=this.b.bh(t,this.Lk()),this.f=(JM(),_B(t,66).Oj()),this.f||t.$j()){if(this.Lk()?(i=_B(c,15),this.k=i):(i=_B(c,69),this.k=this.j=i),iL(this.k,54)?(this.o=this.k.gc(),this.n=this.o):this.p=this.j?this.j._h(this.k.gc()):this.k.Zc(this.k.gc()),this.p?yPn(this,this.p):lIn(this))return r=this.p?this.p.Ub():this.j?this.j.pi(--this.n):this.k.Xb(--this.n),this.f?((n=_B(r,72)).ak(),e=n.dd(),this.i=e):(e=r,this.i=e),this.g=-3,!0}else if(null!=c)return this.k=null,this.p=null,e=c,this.i=e,this.g=-2,!0;return this.k=null,this.p=null,this.g=-1,!1}},EWn.Pb=function(){return Ean(this)},EWn.Tb=function(){return this.a},EWn.Ub=function(){var n;if(this.g<-1||this.Sb())return--this.a,this.g=0,n=this.i,this.Sb(),n;throw Fp(new vv)},EWn.Vb=function(){return this.a-1},EWn.Qb=function(){throw Fp(new dv)},EWn.Lk=function(){return!1},EWn.Wb=function(n){throw Fp(new dv)},EWn.Mk=function(){return!0},EWn.a=0,EWn.d=0,EWn.f=!1,EWn.g=0,EWn.n=0,EWn.o=0,gX(v9n,"EContentsEList/FeatureIteratorImpl",279),lAn(697,279,H9n,Xx),EWn.Lk=function(){return!0},gX(v9n,"EContentsEList/ResolvingFeatureIteratorImpl",697),lAn(1157,697,H9n,Vx),EWn.Mk=function(){return!1},gX(h6n,"ENamedElementImpl/1/1",1157),lAn(1158,279,H9n,Wx),EWn.Mk=function(){return!1},gX(h6n,"ENamedElementImpl/1/2",1158),lAn(36,143,Z8n,s4,h4,Yz,m9,$7,Z5,Fen,T0,Ben,M0,Q5,S0,Gen,P0,J5,I0,Hen,C0,Zz,y9,HQ,qen,O0,Y5,A0),EWn._i=function(){return o9(this)},EWn.gj=function(){var n;return(n=o9(this))?n.zj():null},EWn.yi=function(n){return-1==this.b&&this.a&&(this.b=this.c.Xg(this.a.aj(),this.a.Gj())),this.c.Og(this.b,n)},EWn.Ai=function(){return this.c},EWn.hj=function(){var n;return!!(n=o9(this))&&n.Kj()},EWn.b=-1,gX(h6n,"ENotificationImpl",36),lAn(399,284,{105:1,92:1,90:1,147:1,191:1,56:1,59:1,108:1,472:1,49:1,97:1,150:1,399:1,284:1,114:1,115:1},Om),EWn.Qg=function(n){return Mkn(this,n)},EWn._g=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),(i=this.t)>1||-1==i;case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?_B(this.Cb,26):null;case 11:return!this.d&&(this.d=new $L(P$t,this,11)),this.d;case 12:return!this.c&&(this.c=new nU(WAt,this,12,10)),this.c;case 13:return!this.a&&(this.a=new aR(this,this)),this.a;case 14:return F7(this)}return G9(this,n-fX((wWn(),b$t)),ttn(_B(van(this,16),26)||b$t,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?Mkn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,10,e);case 12:return!this.c&&(this.c=new nU(WAt,this,12,10)),Vwn(this.c,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),b$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),b$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 9:return wX(this,e);case 10:return j_n(this,null,10,e);case 11:return!this.d&&(this.d=new $L(P$t,this,11)),Rpn(this.d,n,e);case 12:return!this.c&&(this.c=new nU(WAt,this,12,10)),Rpn(this.c,n,e);case 14:return Rpn(F7(this),n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),b$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),b$t)),n,e)},EWn.lh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i);case 10:return!(this.Db>>16!=10||!_B(this.Cb,26));case 11:return!!this.d&&0!=this.d.i;case 12:return!!this.c&&0!=this.c.i;case 13:return!(!this.a||0==F7(this.a.a).i||this.b&&Dvn(this.b));case 14:return!!this.b&&Dvn(this.b)}return I3(this,n-fX((wWn(),b$t)),ttn(_B(van(this,16),26)||b$t,n))},EWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void $rn(this,TD(t));case 2:return void Vfn(this,By(jD(t)));case 3:return void Yfn(this,By(jD(t)));case 4:return void Aen(this,_B(t,19).a);case 5:return void $en(this,_B(t,19).a);case 8:return void Phn(this,_B(t,138));case 9:return void((e=FTn(this,_B(t,87),null))&&e.Fi());case 11:return!this.d&&(this.d=new $L(P$t,this,11)),uqn(this.d),!this.d&&(this.d=new $L(P$t,this,11)),void dX(this.d,_B(t,14));case 12:return!this.c&&(this.c=new nU(WAt,this,12,10)),uqn(this.c),!this.c&&(this.c=new nU(WAt,this,12,10)),void dX(this.c,_B(t,14));case 13:return!this.a&&(this.a=new aR(this,this)),gqn(this.a),!this.a&&(this.a=new aR(this,this)),void dX(this.a,_B(t,14));case 14:return uqn(F7(this)),void dX(F7(this),_B(t,14))}Abn(this,n-fX((wWn(),b$t)),ttn(_B(van(this,16),26)||b$t,n),t)},EWn.zh=function(){return wWn(),b$t},EWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void $rn(this,null);case 2:return void Vfn(this,!0);case 3:return void Yfn(this,!0);case 4:return void Aen(this,0);case 5:return void $en(this,1);case 8:return void Phn(this,null);case 9:return void((t=FTn(this,null,null))&&t.Fi());case 11:return!this.d&&(this.d=new $L(P$t,this,11)),void uqn(this.d);case 12:return!this.c&&(this.c=new nU(WAt,this,12,10)),void uqn(this.c);case 13:return void(this.a&&gqn(this.a));case 14:return void(this.b&&uqn(this.b))}Bfn(this,n-fX((wWn(),b$t)),ttn(_B(van(this,16),26)||b$t,n))},EWn.Gh=function(){var n,t;if(this.c)for(n=0,t=this.c.i;ni&&OX(n,i,null),e=0,t=new CL(F7(this.a));t.e!=t.i.gc();)OX(n,e++,_B(mpn(t),87).c||(wWn(),s$t));return n},EWn.Yi=function(){var n,t,e,i;for((i=new Tk).a+="[",n=F7(this.a),t=0,e=F7(this.a).i;t1);case 5:return vZ(this,n,t,e,i,this.i-_B(e,15).gc()>0);default:return new $7(this.e,n,this.c,t,e,i,!0)}},EWn.ij=function(){return!0},EWn.fj=function(){return Dvn(this)},EWn.Xj=function(){uqn(this)},gX(h6n,"EOperationImpl/2",1341),lAn(498,1,{1938:1,498:1},IC),gX(h6n,"EPackageImpl/1",498),lAn(16,85,x9n,nU),EWn.zk=function(){return this.d},EWn.Ak=function(){return this.b},EWn.Dk=function(){return!0},EWn.b=0,gX(v9n,"EObjectContainmentWithInverseEList",16),lAn(353,16,x9n,nK),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectContainmentWithInverseEList/Resolving",353),lAn(298,353,x9n,Qz),EWn.ci=function(){this.a.tb=null},gX(h6n,"EPackageImpl/2",298),lAn(1228,1,{},Oo),gX(h6n,"EPackageImpl/3",1228),lAn(718,43,ZQn,$m),EWn._b=function(n){return zC(n)?nJ(this,n):!!CJ(this.f,n)},gX(h6n,"EPackageRegistryImpl",718),lAn(509,284,{105:1,92:1,90:1,147:1,191:1,56:1,2017:1,108:1,472:1,49:1,97:1,150:1,509:1,284:1,114:1,115:1},Am),EWn.Qg=function(n){return Skn(this,n)},EWn._g=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),(i=this.t)>1||-1==i;case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?_B(this.Cb,59):null}return G9(this,n-fX((wWn(),g$t)),ttn(_B(van(this,16),26)||g$t,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?Skn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,10,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),g$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),g$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 9:return wX(this,e);case 10:return j_n(this,null,10,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),g$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),g$t)),n,e)},EWn.lh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i);case 10:return!(this.Db>>16!=10||!_B(this.Cb,59))}return I3(this,n-fX((wWn(),g$t)),ttn(_B(van(this,16),26)||g$t,n))},EWn.zh=function(){return wWn(),g$t},gX(h6n,"EParameterImpl",509),lAn(99,449,{105:1,92:1,90:1,147:1,191:1,56:1,18:1,170:1,66:1,108:1,472:1,49:1,97:1,150:1,99:1,449:1,284:1,114:1,115:1,677:1},dD),EWn._g=function(n,t,e){var i,r;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),(r=this.t)>1||-1==r;case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q;case 10:return oN(),0!=(this.Bb&m6n);case 11:return oN(),0!=(this.Bb&E9n);case 12:return oN(),0!=(this.Bb&RQn);case 13:return this.j;case 14:return BLn(this);case 15:return oN(),0!=(this.Bb&j9n);case 16:return oN(),0!=(this.Bb&oVn);case 17:return bZ(this);case 18:return oN(),0!=(this.Bb&o6n);case 19:return oN(),!(!(i=Svn(this))||0==(i.Bb&o6n));case 20:return oN(),0!=(this.Bb&_Qn);case 21:return t?Svn(this):this.b;case 22:return t?Pon(this):D5(this);case 23:return!this.a&&(this.a=new xL(KAt,this,23)),this.a}return G9(this,n-fX((wWn(),p$t)),ttn(_B(van(this,16),26)||p$t,n),t,e)},EWn.lh=function(n){var t,e;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(e=this.t)>1||-1==e;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i);case 10:return 0==(this.Bb&m6n);case 11:return 0!=(this.Bb&E9n);case 12:return 0!=(this.Bb&RQn);case 13:return null!=this.j;case 14:return null!=BLn(this);case 15:return 0!=(this.Bb&j9n);case 16:return 0!=(this.Bb&oVn);case 17:return!!bZ(this);case 18:return 0!=(this.Bb&o6n);case 19:return!!(t=Svn(this))&&0!=(t.Bb&o6n);case 20:return 0==(this.Bb&_Qn);case 21:return!!this.b;case 22:return!!D5(this);case 23:return!!this.a&&0!=this.a.i}return I3(this,n-fX((wWn(),p$t)),ttn(_B(van(this,16),26)||p$t,n))},EWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void QZ(this,TD(t));case 2:return void Vfn(this,By(jD(t)));case 3:return void Yfn(this,By(jD(t)));case 4:return void Aen(this,_B(t,19).a);case 5:return void $en(this,_B(t,19).a);case 8:return void Phn(this,_B(t,138));case 9:return void((e=FTn(this,_B(t,87),null))&&e.Fi());case 10:return void Cln(this,By(jD(t)));case 11:return void $ln(this,By(jD(t)));case 12:return void Oln(this,By(jD(t)));case 13:return void RC(this,TD(t));case 15:return void Aln(this,By(jD(t)));case 16:return void Bln(this,By(jD(t)));case 18:return void VZ(this,By(jD(t)));case 20:return void Gln(this,By(jD(t)));case 21:return void ern(this,_B(t,18));case 23:return!this.a&&(this.a=new xL(KAt,this,23)),uqn(this.a),!this.a&&(this.a=new xL(KAt,this,23)),void dX(this.a,_B(t,14))}Abn(this,n-fX((wWn(),p$t)),ttn(_B(van(this,16),26)||p$t,n),t)},EWn.zh=function(){return wWn(),p$t},EWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,88)&&CIn(M5(_B(this.Cb,88)),4),void $rn(this,null);case 2:return void Vfn(this,!0);case 3:return void Yfn(this,!0);case 4:return void Aen(this,0);case 5:return void $en(this,1);case 8:return void Phn(this,null);case 9:return void((t=FTn(this,null,null))&&t.Fi());case 10:return void Cln(this,!0);case 11:return void $ln(this,!1);case 12:return void Oln(this,!1);case 13:return this.i=null,void rrn(this,null);case 15:return void Aln(this,!1);case 16:return void Bln(this,!1);case 18:return qln(this,!1),void(iL(this.Cb,88)&&CIn(M5(_B(this.Cb,88)),2));case 20:return void Gln(this,!0);case 21:return void ern(this,null);case 23:return!this.a&&(this.a=new xL(KAt,this,23)),void uqn(this.a)}Bfn(this,n-fX((wWn(),p$t)),ttn(_B(van(this,16),26)||p$t,n))},EWn.Gh=function(){Pon(this),mV(_7((PPn(),Q$t),this)),Pkn(this),this.Bb|=1},EWn.Lj=function(){return Svn(this)},EWn.qk=function(){var n;return!!(n=Svn(this))&&0!=(n.Bb&o6n)},EWn.rk=function(){return 0!=(this.Bb&o6n)},EWn.sk=function(){return 0!=(this.Bb&_Qn)},EWn.nk=function(n,t){return this.c=null,Mfn(this,n,t)},EWn.Ib=function(){var n;return 0!=(64&this.Db)?kRn(this):((n=new sN(kRn(this))).a+=" (containment: ",vE(n,0!=(this.Bb&o6n)),n.a+=", resolveProxies: ",vE(n,0!=(this.Bb&_Qn)),n.a+=")",n.a)},gX(h6n,"EReferenceImpl",99),lAn(548,115,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1,548:1,114:1,115:1},Ao),EWn.Fb=function(n){return this===n},EWn.cd=function(){return this.b},EWn.dd=function(){return this.c},EWn.Hb=function(){return MN(this)},EWn.Uh=function(n){gq(this,TD(n))},EWn.ed=function(n){return OH(this,TD(n))},EWn._g=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return G9(this,n-fX((wWn(),v$t)),ttn(_B(van(this,16),26)||v$t,n),t,e)},EWn.lh=function(n){switch(n){case 0:return null!=this.b;case 1:return null!=this.c}return I3(this,n-fX((wWn(),v$t)),ttn(_B(van(this,16),26)||v$t,n))},EWn.sh=function(n,t){switch(n){case 0:return void pq(this,TD(t));case 1:return void Din(this,TD(t))}Abn(this,n-fX((wWn(),v$t)),ttn(_B(van(this,16),26)||v$t,n),t)},EWn.zh=function(){return wWn(),v$t},EWn.Bh=function(n){switch(n){case 0:return void xin(this,null);case 1:return void Din(this,null)}Bfn(this,n-fX((wWn(),v$t)),ttn(_B(van(this,16),26)||v$t,n))},EWn.Sh=function(){var n;return-1==this.a&&(n=this.b,this.a=null==n?0:gvn(n)),this.a},EWn.Th=function(n){this.a=n},EWn.Ib=function(){var n;return 0!=(64&this.Db)?M$n(this):((n=new sN(M$n(this))).a+=" (key: ",iO(n,this.b),n.a+=", value: ",iO(n,this.c),n.a+=")",n.a)},EWn.a=-1,EWn.b=null,EWn.c=null;var N$t,x$t,D$t,R$t,K$t,_$t,F$t,B$t,H$t,q$t,G$t=gX(h6n,"EStringToStringMapEntryImpl",548),z$t=fq(v9n,"FeatureMap/Entry/Internal");lAn(565,1,q9n),EWn.Ok=function(n){return this.Pk(_B(n,49))},EWn.Pk=function(n){return this.Ok(n)},EWn.Fb=function(n){var t,e;return this===n||!!iL(n,72)&&(t=_B(n,72)).ak()==this.c&&(null==(e=this.dd())?null==t.dd():$fn(e,t.dd()))},EWn.ak=function(){return this.c},EWn.Hb=function(){var n;return n=this.dd(),Yon(this.c)^(null==n?0:Yon(n))},EWn.Ib=function(){var n,t;return t=Gtn((n=this.c).Hj()).Ph(),n.ne(),(null!=t&&0!=t.length?t+":"+n.ne():n.ne())+"="+this.dd()},gX(h6n,"EStructuralFeatureImpl/BasicFeatureMapEntry",565),lAn(776,565,q9n,eR),EWn.Pk=function(n){return new eR(this.c,n)},EWn.dd=function(){return this.a},EWn.Qk=function(n,t,e){return Tcn(this,n,this.a,t,e)},EWn.Rk=function(n,t,e){return Mcn(this,n,this.a,t,e)},gX(h6n,"EStructuralFeatureImpl/ContainmentUpdatingFeatureMapEntry",776),lAn(1314,1,{},CC),EWn.Pj=function(n,t,e,i,r){return _B(T9(n,this.b),215).nl(this.a).Wj(i)},EWn.Qj=function(n,t,e,i,r){return _B(T9(n,this.b),215).el(this.a,i,r)},EWn.Rj=function(n,t,e,i,r){return _B(T9(n,this.b),215).fl(this.a,i,r)},EWn.Sj=function(n,t,e){return _B(T9(n,this.b),215).nl(this.a).fj()},EWn.Tj=function(n,t,e,i){_B(T9(n,this.b),215).nl(this.a).Wb(i)},EWn.Uj=function(n,t,e){return _B(T9(n,this.b),215).nl(this.a)},EWn.Vj=function(n,t,e){_B(T9(n,this.b),215).nl(this.a).Xj()},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateFeatureMapDelegator",1314),lAn(89,1,{},MB,hQ,xJ,l4),EWn.Pj=function(n,t,e,i,r){var c;if(null==(c=t.Ch(e))&&t.Dh(e,c=tWn(this,n)),!r)switch(this.e){case 50:case 41:return _B(c,589).sj();case 40:return _B(c,215).kl()}return c},EWn.Qj=function(n,t,e,i,r){var c;return null==(c=t.Ch(e))&&t.Dh(e,c=tWn(this,n)),_B(c,69).lk(i,r)},EWn.Rj=function(n,t,e,i,r){var c;return null!=(c=t.Ch(e))&&(r=_B(c,69).mk(i,r)),r},EWn.Sj=function(n,t,e){var i;return null!=(i=t.Ch(e))&&_B(i,76).fj()},EWn.Tj=function(n,t,e,i){var r;!(r=_B(t.Ch(e),76))&&t.Dh(e,r=tWn(this,n)),r.Wb(i)},EWn.Uj=function(n,t,e){var i;return null==(i=t.Ch(e))&&t.Dh(e,i=tWn(this,n)),iL(i,76)?_B(i,76):new kp(_B(t.Ch(e),15))},EWn.Vj=function(n,t,e){var i;!(i=_B(t.Ch(e),76))&&t.Dh(e,i=tWn(this,n)),i.Xj()},EWn.b=0,EWn.e=0,gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateMany",89),lAn(504,1,{}),EWn.Qj=function(n,t,e,i,r){throw Fp(new dv)},EWn.Rj=function(n,t,e,i,r){throw Fp(new dv)},EWn.Uj=function(n,t,e){return new fQ(this,n,t,e)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingle",504),lAn(1331,1,m9n,fQ),EWn.Wj=function(n){return this.a.Pj(this.c,this.d,this.b,n,!0)},EWn.fj=function(){return this.a.Sj(this.c,this.d,this.b)},EWn.Wb=function(n){this.a.Tj(this.c,this.d,this.b,n)},EWn.Xj=function(){this.a.Vj(this.c,this.d,this.b)},EWn.b=0,gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingle/1",1331),lAn(769,504,{},pY),EWn.Pj=function(n,t,e,i,r){return wKn(n,n.eh(),n.Vg())==this.b?this.sk()&&i?iAn(n):n.eh():null},EWn.Qj=function(n,t,e,i,r){var c,a;return n.eh()&&(r=(c=n.Vg())>=0?n.Qg(r):n.eh().ih(n,-1-c,null,r)),a=Cwn(n.Tg(),this.e),n.Sg(i,a,r)},EWn.Rj=function(n,t,e,i,r){var c;return c=Cwn(n.Tg(),this.e),n.Sg(null,c,r)},EWn.Sj=function(n,t,e){var i;return i=Cwn(n.Tg(),this.e),!!n.eh()&&n.Vg()==i},EWn.Tj=function(n,t,e,i){var r,c,a,u,o;if(null!=i&&!TFn(this.a,i))throw Fp(new Dy(G9n+(iL(i,56)?bEn(_B(i,56).Tg()):ctn(Zon(i)))+z9n+this.a+"'"));if(r=n.eh(),a=Cwn(n.Tg(),this.e),HC(i)!==HC(r)||n.Vg()!=a&&null!=i){if(gkn(n,_B(i,56)))throw Fp(new Ry(l6n+n.Ib()));o=null,r&&(o=(c=n.Vg())>=0?n.Qg(o):n.eh().ih(n,-1-c,null,o)),(u=_B(i,49))&&(o=u.gh(n,Cwn(u.Tg(),this.b),null,o)),(o=n.Sg(u,a,o))&&o.Fi()}else n.Lg()&&n.Mg()&&fan(n,new Yz(n,1,a,i,i))},EWn.Vj=function(n,t,e){var i,r,c;n.eh()?(c=(i=n.Vg())>=0?n.Qg(null):n.eh().ih(n,-1-i,null,null),r=Cwn(n.Tg(),this.e),(c=n.Sg(null,r,c))&&c.Fi()):n.Lg()&&n.Mg()&&fan(n,new Zz(n,1,this.e,null,null))},EWn.sk=function(){return!1},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainer",769),lAn(1315,769,{},SB),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainerResolving",1315),lAn(563,504,{}),EWn.Pj=function(n,t,e,i,r){var c;return null==(c=t.Ch(e))?this.b:HC(c)===HC(N$t)?null:c},EWn.Sj=function(n,t,e){var i;return null!=(i=t.Ch(e))&&(HC(i)===HC(N$t)||!$fn(i,this.b))},EWn.Tj=function(n,t,e,i){var r,c;n.Lg()&&n.Mg()?(r=null==(c=t.Ch(e))?this.b:HC(c)===HC(N$t)?null:c,null==i?null!=this.c?(t.Dh(e,null),i=this.b):null!=this.b?t.Dh(e,N$t):t.Dh(e,null):(this.Sk(i),t.Dh(e,i)),fan(n,this.d.Tk(n,1,this.e,r,i))):null==i?null!=this.c?t.Dh(e,null):null!=this.b?t.Dh(e,N$t):t.Dh(e,null):(this.Sk(i),t.Dh(e,i))},EWn.Vj=function(n,t,e){var i,r;n.Lg()&&n.Mg()?(i=null==(r=t.Ch(e))?this.b:HC(r)===HC(N$t)?null:r,t.Eh(e),fan(n,this.d.Tk(n,1,this.e,i,this.b))):t.Eh(e)},EWn.Sk=function(n){throw Fp(new fv)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData",563),lAn(U9n,1,{},$o),EWn.Tk=function(n,t,e,i,r){return new Zz(n,t,e,i,r)},EWn.Uk=function(n,t,e,i,r,c){return new HQ(n,t,e,i,r,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator",U9n),lAn(1332,U9n,{},Lo),EWn.Tk=function(n,t,e,i,r){return new Y5(n,t,e,By(jD(i)),By(jD(r)))},EWn.Uk=function(n,t,e,i,r,c){return new A0(n,t,e,By(jD(i)),By(jD(r)),c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/1",1332),lAn(1333,U9n,{},No),EWn.Tk=function(n,t,e,i,r){return new Fen(n,t,e,_B(i,217).a,_B(r,217).a)},EWn.Uk=function(n,t,e,i,r,c){return new T0(n,t,e,_B(i,217).a,_B(r,217).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/2",1333),lAn(1334,U9n,{},xo),EWn.Tk=function(n,t,e,i,r){return new Ben(n,t,e,_B(i,172).a,_B(r,172).a)},EWn.Uk=function(n,t,e,i,r,c){return new M0(n,t,e,_B(i,172).a,_B(r,172).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/3",1334),lAn(1335,U9n,{},Do),EWn.Tk=function(n,t,e,i,r){return new Q5(n,t,e,Hy(ED(i)),Hy(ED(r)))},EWn.Uk=function(n,t,e,i,r,c){return new S0(n,t,e,Hy(ED(i)),Hy(ED(r)),c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/4",1335),lAn(1336,U9n,{},Ro),EWn.Tk=function(n,t,e,i,r){return new Gen(n,t,e,_B(i,155).a,_B(r,155).a)},EWn.Uk=function(n,t,e,i,r,c){return new P0(n,t,e,_B(i,155).a,_B(r,155).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/5",1336),lAn(1337,U9n,{},Ko),EWn.Tk=function(n,t,e,i,r){return new J5(n,t,e,_B(i,19).a,_B(r,19).a)},EWn.Uk=function(n,t,e,i,r,c){return new I0(n,t,e,_B(i,19).a,_B(r,19).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/6",1337),lAn(1338,U9n,{},_o),EWn.Tk=function(n,t,e,i,r){return new Hen(n,t,e,_B(i,162).a,_B(r,162).a)},EWn.Uk=function(n,t,e,i,r,c){return new C0(n,t,e,_B(i,162).a,_B(r,162).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/7",1338),lAn(1339,U9n,{},Fo),EWn.Tk=function(n,t,e,i,r){return new qen(n,t,e,_B(i,184).a,_B(r,184).a)},EWn.Uk=function(n,t,e,i,r,c){return new O0(n,t,e,_B(i,184).a,_B(r,184).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/8",1339),lAn(1317,563,{},lQ),EWn.Sk=function(n){if(!this.a.wj(n))throw Fp(new Dy(G9n+Zon(n)+z9n+this.a+"'"))},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataDynamic",1317),lAn(1318,563,{},JG),EWn.Sk=function(n){},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataStatic",1318),lAn(770,563,{}),EWn.Sj=function(n,t,e){return null!=t.Ch(e)},EWn.Tj=function(n,t,e,i){var r,c;n.Lg()&&n.Mg()?(r=!0,null==(c=t.Ch(e))?(r=!1,c=this.b):HC(c)===HC(N$t)&&(c=null),null==i?null!=this.c?(t.Dh(e,null),i=this.b):t.Dh(e,N$t):(this.Sk(i),t.Dh(e,i)),fan(n,this.d.Uk(n,1,this.e,c,i,!r))):null==i?null!=this.c?t.Dh(e,null):t.Dh(e,N$t):(this.Sk(i),t.Dh(e,i))},EWn.Vj=function(n,t,e){var i,r;n.Lg()&&n.Mg()?(i=!0,null==(r=t.Ch(e))?(i=!1,r=this.b):HC(r)===HC(N$t)&&(r=null),t.Eh(e),fan(n,this.d.Uk(n,2,this.e,r,this.b,i))):t.Eh(e)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettable",770),lAn(1319,770,{},bQ),EWn.Sk=function(n){if(!this.a.wj(n))throw Fp(new Dy(G9n+Zon(n)+z9n+this.a+"'"))},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableDynamic",1319),lAn(1320,770,{},YG),EWn.Sk=function(n){},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableStatic",1320),lAn(398,504,{},iG),EWn.Pj=function(n,t,e,i,r){var c,a,u,o,s;if(s=t.Ch(e),this.Kj()&&HC(s)===HC(N$t))return null;if(this.sk()&&i&&null!=s){if((u=_B(s,49)).kh()&&u!=(o=Zhn(n,u))){if(!TFn(this.a,o))throw Fp(new Dy(G9n+Zon(o)+z9n+this.a+"'"));t.Dh(e,s=o),this.rk()&&(c=_B(o,49),a=u.ih(n,this.b?Cwn(u.Tg(),this.b):-1-Cwn(n.Tg(),this.e),null,null),!c.eh()&&(a=c.gh(n,this.b?Cwn(c.Tg(),this.b):-1-Cwn(n.Tg(),this.e),null,a)),a&&a.Fi()),n.Lg()&&n.Mg()&&fan(n,new Zz(n,9,this.e,u,o))}return s}return s},EWn.Qj=function(n,t,e,i,r){var c,a;return HC(a=t.Ch(e))===HC(N$t)&&(a=null),t.Dh(e,i),this.bj()?HC(a)!==HC(i)&&null!=a&&(r=(c=_B(a,49)).ih(n,Cwn(c.Tg(),this.b),null,r)):this.rk()&&null!=a&&(r=_B(a,49).ih(n,-1-Cwn(n.Tg(),this.e),null,r)),n.Lg()&&n.Mg()&&(!r&&(r=new Kj(4)),r.Ei(new Zz(n,1,this.e,a,i))),r},EWn.Rj=function(n,t,e,i,r){var c;return HC(c=t.Ch(e))===HC(N$t)&&(c=null),t.Eh(e),n.Lg()&&n.Mg()&&(!r&&(r=new Kj(4)),this.Kj()?r.Ei(new Zz(n,2,this.e,c,null)):r.Ei(new Zz(n,1,this.e,c,null))),r},EWn.Sj=function(n,t,e){return null!=t.Ch(e)},EWn.Tj=function(n,t,e,i){var r,c,a,u,o;if(null!=i&&!TFn(this.a,i))throw Fp(new Dy(G9n+(iL(i,56)?bEn(_B(i,56).Tg()):ctn(Zon(i)))+z9n+this.a+"'"));u=null!=(o=t.Ch(e)),this.Kj()&&HC(o)===HC(N$t)&&(o=null),a=null,this.bj()?HC(o)!==HC(i)&&(null!=o&&(a=(r=_B(o,49)).ih(n,Cwn(r.Tg(),this.b),null,a)),null!=i&&(a=(r=_B(i,49)).gh(n,Cwn(r.Tg(),this.b),null,a))):this.rk()&&HC(o)!==HC(i)&&(null!=o&&(a=_B(o,49).ih(n,-1-Cwn(n.Tg(),this.e),null,a)),null!=i&&(a=_B(i,49).gh(n,-1-Cwn(n.Tg(),this.e),null,a))),null==i&&this.Kj()?t.Dh(e,N$t):t.Dh(e,i),n.Lg()&&n.Mg()?(c=new HQ(n,1,this.e,o,i,this.Kj()&&!u),a?(a.Ei(c),a.Fi()):fan(n,c)):a&&a.Fi()},EWn.Vj=function(n,t,e){var i,r,c,a,u;a=null!=(u=t.Ch(e)),this.Kj()&&HC(u)===HC(N$t)&&(u=null),c=null,null!=u&&(this.bj()?c=(i=_B(u,49)).ih(n,Cwn(i.Tg(),this.b),null,c):this.rk()&&(c=_B(u,49).ih(n,-1-Cwn(n.Tg(),this.e),null,c))),t.Eh(e),n.Lg()&&n.Mg()?(r=new HQ(n,this.Kj()?2:1,this.e,u,null,a),c?(c.Ei(r),c.Fi()):fan(n,r)):c&&c.Fi()},EWn.bj=function(){return!1},EWn.rk=function(){return!1},EWn.sk=function(){return!1},EWn.Kj=function(){return!1},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObject",398),lAn(564,398,{},Jx),EWn.rk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainment",564),lAn(1323,564,{},Yx),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentResolving",1323),lAn(772,564,{},Zx),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettable",772),lAn(1325,772,{},nD),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettableResolving",1325),lAn(640,564,{},PB),EWn.bj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverse",640),lAn(1324,640,{},OB),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseResolving",1324),lAn(773,640,{},AB),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettable",773),lAn(1326,773,{},$B),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettableResolving",1326),lAn(641,398,{},tD),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolving",641),lAn(1327,641,{},eD),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingUnsettable",1327),lAn(774,641,{},IB),EWn.bj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverse",774),lAn(1328,774,{},LB),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverseUnsettable",1328),lAn(1321,398,{},iD),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectUnsettable",1321),lAn(771,398,{},CB),EWn.bj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverse",771),lAn(1322,771,{},NB),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverseUnsettable",1322),lAn(775,565,q9n,rW),EWn.Pk=function(n){return new rW(this.a,this.c,n)},EWn.dd=function(){return this.b},EWn.Qk=function(n,t,e){return N8(this,n,this.b,e)},EWn.Rk=function(n,t,e){return x8(this,n,this.b,e)},gX(h6n,"EStructuralFeatureImpl/InverseUpdatingFeatureMapEntry",775),lAn(1329,1,m9n,kp),EWn.Wj=function(n){return this.a},EWn.fj=function(){return iL(this.a,95)?_B(this.a,95).fj():!this.a.dc()},EWn.Wb=function(n){this.a.$b(),this.a.Gc(_B(n,15))},EWn.Xj=function(){iL(this.a,95)?_B(this.a,95).Xj():this.a.$b()},gX(h6n,"EStructuralFeatureImpl/SettingMany",1329),lAn(1330,565,q9n,w4),EWn.Ok=function(n){return new iR((Gqn(),RLt),this.b.Ih(this.a,n))},EWn.dd=function(){return null},EWn.Qk=function(n,t,e){return e},EWn.Rk=function(n,t,e){return e},gX(h6n,"EStructuralFeatureImpl/SimpleContentFeatureMapEntry",1330),lAn(642,565,q9n,iR),EWn.Ok=function(n){return new iR(this.c,n)},EWn.dd=function(){return this.a},EWn.Qk=function(n,t,e){return e},EWn.Rk=function(n,t,e){return e},gX(h6n,"EStructuralFeatureImpl/SimpleFeatureMapEntry",642),lAn(391,497,o8n,Bo),EWn.ri=function(n){return L8(FAt,FWn,26,n,0,1)},EWn.ni=function(){return!1},gX(h6n,"ESuperAdapter/1",391),lAn(444,438,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,836:1,49:1,97:1,150:1,444:1,114:1,115:1},Ho),EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return!this.a&&(this.a=new rG(this,UAt,this)),this.a}return G9(this,n-fX((wWn(),k$t)),ttn(_B(van(this,16),26)||k$t,n),t,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 2:return!this.a&&(this.a=new rG(this,UAt,this)),Rpn(this.a,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),k$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),k$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!!this.a&&0!=this.a.i}return I3(this,n-fX((wWn(),k$t)),ttn(_B(van(this,16),26)||k$t,n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void $rn(this,TD(t));case 2:return!this.a&&(this.a=new rG(this,UAt,this)),uqn(this.a),!this.a&&(this.a=new rG(this,UAt,this)),void dX(this.a,_B(t,14))}Abn(this,n-fX((wWn(),k$t)),ttn(_B(van(this,16),26)||k$t,n),t)},EWn.zh=function(){return wWn(),k$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void $rn(this,null);case 2:return!this.a&&(this.a=new rG(this,UAt,this)),void uqn(this.a)}Bfn(this,n-fX((wWn(),k$t)),ttn(_B(van(this,16),26)||k$t,n))},gX(h6n,"ETypeParameterImpl",444),lAn(445,85,x9n,rG),EWn.cj=function(n,t){return ATn(this,_B(n,87),t)},EWn.dj=function(n,t){return $Tn(this,_B(n,87),t)},gX(h6n,"ETypeParameterImpl/1",445),lAn(634,43,ZQn,Lm),EWn.ec=function(){return new jp(this)},gX(h6n,"ETypeParameterImpl/2",634),lAn(556,YWn,ZWn,jp),EWn.Fc=function(n){return VR(this,_B(n,87))},EWn.Gc=function(n){var t,e,i;for(i=!1,e=n.Kc();e.Ob();)t=_B(e.Pb(),87),null==XW(this.a,t,"")&&(i=!0);return i},EWn.$b=function(){OU(this.a)},EWn.Hc=function(n){return oU(this.a,n)},EWn.Kc=function(){return new Ep(new csn(new Mb(this.a).a))},EWn.Mc=function(n){return R6(this,n)},EWn.gc=function(){return $T(this.a)},gX(h6n,"ETypeParameterImpl/2/1",556),lAn(557,1,WWn,Ep),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return _B(Ztn(this.a).cd(),87)},EWn.Ob=function(){return this.a.b},EWn.Qb=function(){a9(this.a)},gX(h6n,"ETypeParameterImpl/2/1/1",557),lAn(1276,43,ZQn,Nm),EWn._b=function(n){return zC(n)?nJ(this,n):!!CJ(this.f,n)},EWn.xc=function(n){var t;return iL(t=zC(n)?TY(this,n):BC(CJ(this.f,n)),837)?(t=_B(t,837)._j(),XW(this,_B(n,235),t),t):null!=t?t:null==n?(QM(),tLt):null},gX(h6n,"EValidatorRegistryImpl",1276),lAn(1313,704,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,1941:1,49:1,97:1,150:1,114:1,115:1},qo),EWn.Ih=function(n,t){switch(n.yj()){case 21:case 22:case 23:case 24:case 26:case 31:case 32:case 37:case 38:case 39:case 40:case 43:case 44:case 48:case 49:case 20:return null==t?null:_bn(t);case 25:return ztn(t);case 27:return z9(t);case 28:return U9(t);case 29:return null==t?null:F$(POt[0],_B(t,199));case 41:return null==t?"":Yj(_B(t,290));case 42:return _bn(t);case 50:return TD(t);default:throw Fp(new Ry(b6n+n.ne()+w6n))}},EWn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=Gtn(n))?cvn(t.Mh(),n):-1),n.G){case 0:return new Im;case 1:return new jo;case 2:return new Rf;case 4:return new kv;case 5:return new Cm;case 6:return new yv;case 7:return new xf;case 10:return new yo;case 11:return new Om;case 12:return new gJ;case 13:return new Am;case 14:return new dD;case 17:return new Ao;case 18:return new Dp;case 19:return new Ho;default:throw Fp(new Ry(p6n+n.zb+w6n))}},EWn.Kh=function(n,t){switch(n.yj()){case 20:return null==t?null:new lE(t);case 21:return null==t?null:new OA(t);case 23:case 22:return null==t?null:Jdn(t);case 26:case 24:return null==t?null:Mnn(h_n(t,-128,127)<<24>>24);case 25:return b$n(t);case 27:return Tyn(t);case 28:return Myn(t);case 29:return wMn(t);case 32:case 31:return null==t?null:fSn(t);case 38:case 37:return null==t?null:new Nv(t);case 40:case 39:return null==t?null:tln(h_n(t,RVn,NWn));case 41:case 42:return null;case 44:case 43:return null==t?null:ygn(eUn(t));case 49:case 48:return null==t?null:eln(h_n(t,W9n,32767)<<16>>16);case 50:return t;default:throw Fp(new Ry(b6n+n.ne()+w6n))}},gX(h6n,"EcoreFactoryImpl",1313),lAn(547,179,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,1939:1,49:1,97:1,150:1,179:1,547:1,114:1,115:1,675:1},GW),EWn.gb=!1,EWn.hb=!1;var U$t,X$t=!1;gX(h6n,"EcorePackageImpl",547),lAn(1184,1,{837:1},Go),EWn._j=function(){return uN(),eLt},gX(h6n,"EcorePackageImpl/1",1184),lAn(1193,1,u7n,zo),EWn.wj=function(n){return iL(n,147)},EWn.xj=function(n){return L8(KOt,FWn,147,n,0,1)},gX(h6n,"EcorePackageImpl/10",1193),lAn(1194,1,u7n,Uo),EWn.wj=function(n){return iL(n,191)},EWn.xj=function(n){return L8(FOt,FWn,191,n,0,1)},gX(h6n,"EcorePackageImpl/11",1194),lAn(1195,1,u7n,Xo),EWn.wj=function(n){return iL(n,56)},EWn.xj=function(n){return L8(OOt,FWn,56,n,0,1)},gX(h6n,"EcorePackageImpl/12",1195),lAn(1196,1,u7n,Wo),EWn.wj=function(n){return iL(n,399)},EWn.xj=function(n){return L8(XAt,L9n,59,n,0,1)},gX(h6n,"EcorePackageImpl/13",1196),lAn(1197,1,u7n,Vo),EWn.wj=function(n){return iL(n,235)},EWn.xj=function(n){return L8(BOt,FWn,235,n,0,1)},gX(h6n,"EcorePackageImpl/14",1197),lAn(1198,1,u7n,Qo),EWn.wj=function(n){return iL(n,509)},EWn.xj=function(n){return L8(WAt,FWn,2017,n,0,1)},gX(h6n,"EcorePackageImpl/15",1198),lAn(1199,1,u7n,Jo),EWn.wj=function(n){return iL(n,99)},EWn.xj=function(n){return L8(VAt,$9n,18,n,0,1)},gX(h6n,"EcorePackageImpl/16",1199),lAn(1200,1,u7n,Yo),EWn.wj=function(n){return iL(n,170)},EWn.xj=function(n){return L8(RAt,$9n,170,n,0,1)},gX(h6n,"EcorePackageImpl/17",1200),lAn(1201,1,u7n,Zo),EWn.wj=function(n){return iL(n,472)},EWn.xj=function(n){return L8(DAt,FWn,472,n,0,1)},gX(h6n,"EcorePackageImpl/18",1201),lAn(1202,1,u7n,ns),EWn.wj=function(n){return iL(n,548)},EWn.xj=function(n){return L8(G$t,r9n,548,n,0,1)},gX(h6n,"EcorePackageImpl/19",1202),lAn(1185,1,u7n,ts),EWn.wj=function(n){return iL(n,322)},EWn.xj=function(n){return L8(KAt,$9n,34,n,0,1)},gX(h6n,"EcorePackageImpl/2",1185),lAn(1203,1,u7n,es),EWn.wj=function(n){return iL(n,241)},EWn.xj=function(n){return L8(UAt,_9n,87,n,0,1)},gX(h6n,"EcorePackageImpl/20",1203),lAn(1204,1,u7n,is),EWn.wj=function(n){return iL(n,444)},EWn.xj=function(n){return L8(P$t,FWn,836,n,0,1)},gX(h6n,"EcorePackageImpl/21",1204),lAn(1205,1,u7n,rs),EWn.wj=function(n){return qC(n)},EWn.xj=function(n){return L8(mtt,uVn,476,n,8,1)},gX(h6n,"EcorePackageImpl/22",1205),lAn(1206,1,u7n,cs),EWn.wj=function(n){return iL(n,190)},EWn.xj=function(n){return L8(ANt,uVn,190,n,0,2)},gX(h6n,"EcorePackageImpl/23",1206),lAn(1207,1,u7n,as),EWn.wj=function(n){return iL(n,217)},EWn.xj=function(n){return L8(jtt,uVn,217,n,0,1)},gX(h6n,"EcorePackageImpl/24",1207),lAn(1208,1,u7n,us),EWn.wj=function(n){return iL(n,172)},EWn.xj=function(n){return L8(Ttt,uVn,172,n,0,1)},gX(h6n,"EcorePackageImpl/25",1208),lAn(1209,1,u7n,os),EWn.wj=function(n){return iL(n,199)},EWn.xj=function(n){return L8(ptt,uVn,199,n,0,1)},gX(h6n,"EcorePackageImpl/26",1209),lAn(1210,1,u7n,ss),EWn.wj=function(n){return!1},EWn.xj=function(n){return L8(DNt,FWn,2110,n,0,1)},gX(h6n,"EcorePackageImpl/27",1210),lAn(1211,1,u7n,hs),EWn.wj=function(n){return GC(n)},EWn.xj=function(n){return L8(Mtt,uVn,333,n,7,1)},gX(h6n,"EcorePackageImpl/28",1211),lAn(1212,1,u7n,fs),EWn.wj=function(n){return iL(n,58)},EWn.xj=function(n){return L8(rAt,YYn,58,n,0,1)},gX(h6n,"EcorePackageImpl/29",1212),lAn(1186,1,u7n,ls),EWn.wj=function(n){return iL(n,510)},EWn.xj=function(n){return L8(xAt,{3:1,4:1,5:1,1934:1},590,n,0,1)},gX(h6n,"EcorePackageImpl/3",1186),lAn(1213,1,u7n,bs),EWn.wj=function(n){return iL(n,573)},EWn.xj=function(n){return L8(pAt,FWn,1940,n,0,1)},gX(h6n,"EcorePackageImpl/30",1213),lAn(1214,1,u7n,ws),EWn.wj=function(n){return iL(n,153)},EWn.xj=function(n){return L8(hLt,YYn,153,n,0,1)},gX(h6n,"EcorePackageImpl/31",1214),lAn(1215,1,u7n,ds),EWn.wj=function(n){return iL(n,72)},EWn.xj=function(n){return L8(C$t,o7n,72,n,0,1)},gX(h6n,"EcorePackageImpl/32",1215),lAn(1216,1,u7n,gs),EWn.wj=function(n){return iL(n,155)},EWn.xj=function(n){return L8(Stt,uVn,155,n,0,1)},gX(h6n,"EcorePackageImpl/33",1216),lAn(1217,1,u7n,ps),EWn.wj=function(n){return iL(n,19)},EWn.xj=function(n){return L8(Ctt,uVn,19,n,0,1)},gX(h6n,"EcorePackageImpl/34",1217),lAn(1218,1,u7n,vs),EWn.wj=function(n){return iL(n,290)},EWn.xj=function(n){return L8(Ont,FWn,290,n,0,1)},gX(h6n,"EcorePackageImpl/35",1218),lAn(1219,1,u7n,ms),EWn.wj=function(n){return iL(n,162)},EWn.xj=function(n){return L8(xtt,uVn,162,n,0,1)},gX(h6n,"EcorePackageImpl/36",1219),lAn(1220,1,u7n,ys),EWn.wj=function(n){return iL(n,83)},EWn.xj=function(n){return L8($nt,FWn,83,n,0,1)},gX(h6n,"EcorePackageImpl/37",1220),lAn(1221,1,u7n,ks),EWn.wj=function(n){return iL(n,591)},EWn.xj=function(n){return L8(nLt,FWn,591,n,0,1)},gX(h6n,"EcorePackageImpl/38",1221),lAn(1222,1,u7n,js),EWn.wj=function(n){return!1},EWn.xj=function(n){return L8(RNt,FWn,2111,n,0,1)},gX(h6n,"EcorePackageImpl/39",1222),lAn(1187,1,u7n,Es),EWn.wj=function(n){return iL(n,88)},EWn.xj=function(n){return L8(FAt,FWn,26,n,0,1)},gX(h6n,"EcorePackageImpl/4",1187),lAn(1223,1,u7n,Ts),EWn.wj=function(n){return iL(n,184)},EWn.xj=function(n){return L8(Rtt,uVn,184,n,0,1)},gX(h6n,"EcorePackageImpl/40",1223),lAn(1224,1,u7n,Ms),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX(h6n,"EcorePackageImpl/41",1224),lAn(1225,1,u7n,Ss),EWn.wj=function(n){return iL(n,588)},EWn.xj=function(n){return L8(oAt,FWn,588,n,0,1)},gX(h6n,"EcorePackageImpl/42",1225),lAn(1226,1,u7n,Ps),EWn.wj=function(n){return!1},EWn.xj=function(n){return L8(KNt,uVn,2112,n,0,1)},gX(h6n,"EcorePackageImpl/43",1226),lAn(1227,1,u7n,Is),EWn.wj=function(n){return iL(n,42)},EWn.xj=function(n){return L8(Fnt,mVn,42,n,0,1)},gX(h6n,"EcorePackageImpl/44",1227),lAn(1188,1,u7n,Cs),EWn.wj=function(n){return iL(n,138)},EWn.xj=function(n){return L8(_At,FWn,138,n,0,1)},gX(h6n,"EcorePackageImpl/5",1188),lAn(1189,1,u7n,Os),EWn.wj=function(n){return iL(n,148)},EWn.xj=function(n){return L8(BAt,FWn,148,n,0,1)},gX(h6n,"EcorePackageImpl/6",1189),lAn(1190,1,u7n,As),EWn.wj=function(n){return iL(n,457)},EWn.xj=function(n){return L8(GAt,FWn,671,n,0,1)},gX(h6n,"EcorePackageImpl/7",1190),lAn(1191,1,u7n,$s),EWn.wj=function(n){return iL(n,573)},EWn.xj=function(n){return L8(zAt,FWn,678,n,0,1)},gX(h6n,"EcorePackageImpl/8",1191),lAn(1192,1,u7n,Ls),EWn.wj=function(n){return iL(n,471)},EWn.xj=function(n){return L8(_Ot,FWn,471,n,0,1)},gX(h6n,"EcorePackageImpl/9",1192),lAn(1025,1982,e9n,Ly),EWn.bi=function(n,t){Cfn(this,_B(t,415))},EWn.fi=function(n,t){nIn(this,n,_B(t,415))},gX(h6n,"MinimalEObjectImpl/1ArrayDelegatingAdapterList",1025),lAn(1026,143,Z8n,cW),EWn.Ai=function(){return this.a.a},gX(h6n,"MinimalEObjectImpl/1ArrayDelegatingAdapterList/1",1026),lAn(1053,1052,{},a$),gX("org.eclipse.emf.ecore.plugin","EcorePlugin",1053);var W$t,V$t,Q$t,J$t,Y$t,Z$t,nLt=fq(s7n,"Resource");lAn(781,1378,h7n),EWn.Yk=function(n){},EWn.Zk=function(n){},EWn.Vk=function(){return!this.a&&(this.a=new Tp(this)),this.a},EWn.Wk=function(n){var t,e,i,r,c;if((i=n.length)>0){if(f1(0,n.length),47==n.charCodeAt(0)){for(c=new Q6(4),r=1,t=1;t0&&(n=n.substr(0,e))}return yCn(this,n)},EWn.Xk=function(){return this.c},EWn.Ib=function(){return Yj(this.gm)+"@"+(Yon(this)>>>0).toString(16)+" uri='"+this.d+"'"},EWn.b=!1,gX(f7n,"ResourceImpl",781),lAn(1379,781,h7n,Sp),gX(f7n,"BinaryResourceImpl",1379),lAn(1169,694,s8n),EWn.si=function(n){return iL(n,56)?jJ(this,_B(n,56)):iL(n,591)?new CL(_B(n,591).Vk()):HC(n)===HC(this.f)?_B(n,14).Kc():(bD(),wAt.a)},EWn.Ob=function(){return fOn(this)},EWn.a=!1,gX(v9n,"EcoreUtil/ContentTreeIterator",1169),lAn(1380,1169,s8n,eU),EWn.si=function(n){return HC(n)===HC(this.f)?_B(n,15).Kc():new K2(_B(n,56))},gX(f7n,"ResourceImpl/5",1380),lAn(648,1994,N9n,Tp),EWn.Hc=function(n){return this.i<=4?Tjn(this,n):iL(n,49)&&_B(n,49).Zg()==this.a},EWn.bi=function(n,t){n==this.i-1&&(this.a.b||(this.a.b=!0))},EWn.di=function(n,t){0==n?this.a.b||(this.a.b=!0):A8(this,n,t)},EWn.fi=function(n,t){},EWn.gi=function(n,t,e){},EWn.aj=function(){return 2},EWn.Ai=function(){return this.a},EWn.bj=function(){return!0},EWn.cj=function(n,t){return t=_B(n,49).wh(this.a,t)},EWn.dj=function(n,t){return _B(n,49).wh(null,t)},EWn.ej=function(){return!1},EWn.hi=function(){return!0},EWn.ri=function(n){return L8(OOt,FWn,56,n,0,1)},EWn.ni=function(){return!1},gX(f7n,"ResourceImpl/ContentsEList",648),lAn(957,1964,AVn,Mp),EWn.Zc=function(n){return this.a._h(n)},EWn.gc=function(){return this.a.gc()},gX(v9n,"AbstractSequentialInternalEList/1",957),lAn(624,1,{},TH),gX(v9n,"BasicExtendedMetaData",624),lAn(1160,1,{},OC),EWn.$k=function(){return null},EWn._k=function(){return-2==this.a&&ab(this,rMn(this.d,this.b)),this.a},EWn.al=function(){return null},EWn.bl=function(){return TQ(),TQ(),uet},EWn.ne=function(){return this.c==S7n&&ob(this,kgn(this.d,this.b)),this.c},EWn.cl=function(){return 0},EWn.a=-2,EWn.c=S7n,gX(v9n,"BasicExtendedMetaData/EClassExtendedMetaDataImpl",1160),lAn(1161,1,{},R0),EWn.$k=function(){return this.a==(x5(),Y$t)&&ub(this,gNn(this.f,this.b)),this.a},EWn._k=function(){return 0},EWn.al=function(){return this.c==(x5(),Y$t)&&sb(this,pNn(this.f,this.b)),this.c},EWn.bl=function(){return!this.d&&hb(this,TKn(this.f,this.b)),this.d},EWn.ne=function(){return this.e==S7n&&fb(this,kgn(this.f,this.b)),this.e},EWn.cl=function(){return-2==this.g&&lb(this,VEn(this.f,this.b)),this.g},EWn.e=S7n,EWn.g=-2,gX(v9n,"BasicExtendedMetaData/EDataTypeExtendedMetaDataImpl",1161),lAn(1159,1,{},xC),EWn.b=!1,EWn.c=!1,gX(v9n,"BasicExtendedMetaData/EPackageExtendedMetaDataImpl",1159),lAn(1162,1,{},D0),EWn.c=-2,EWn.e=S7n,EWn.f=S7n,gX(v9n,"BasicExtendedMetaData/EStructuralFeatureExtendedMetaDataImpl",1162),lAn(585,622,x9n,EH),EWn.aj=function(){return this.c},EWn.Fk=function(){return!1},EWn.li=function(n,t){return t},EWn.c=0,gX(v9n,"EDataTypeEList",585);var tLt,eLt,iLt,rLt,cLt,aLt,uLt,oLt,sLt,hLt=fq(v9n,"FeatureMap");lAn(75,585,{3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,76:1,153:1,215:1,1937:1,69:1,95:1},kcn),EWn.Vc=function(n,t){hNn(this,n,_B(t,72))},EWn.Fc=function(n){return cLn(this,_B(n,72))},EWn.Yh=function(n){bX(this,_B(n,72))},EWn.cj=function(n,t){return FK(this,_B(n,72),t)},EWn.dj=function(n,t){return BK(this,_B(n,72),t)},EWn.ii=function(n,t){return r_n(this,n,t)},EWn.li=function(n,t){return oGn(this,n,_B(t,72))},EWn._c=function(n,t){return Mxn(this,n,_B(t,72))},EWn.jj=function(n,t){return HK(this,_B(n,72),t)},EWn.kj=function(n,t){return qK(this,_B(n,72),t)},EWn.lj=function(n,t,e){return wEn(this,_B(n,72),_B(t,72),e)},EWn.oi=function(n,t){return uTn(this,n,_B(t,72))},EWn.dl=function(n,t){return LKn(this,n,t)},EWn.Wc=function(n,t){var e,i,r,c,a,u,o,s,h;for(s=new wtn(t.gc()),r=t.Kc();r.Ob();)if(c=(i=_B(r.Pb(),72)).ak(),Oxn(this.e,c))(!c.hi()||!H3(this,c,i.dd())&&!Tjn(s,i))&&s9(s,i);else{for(h=rxn(this.e.Tg(),c),e=_B(this.g,119),a=!0,u=0;u=0;)if(t=n[this.c],this.k.rl(t.ak()))return this.j=this.f?t:t.dd(),this.i=-2,!0;return this.i=-1,this.g=-1,!1},gX(v9n,"BasicFeatureMap/FeatureEIterator",410),lAn(662,410,iVn,LO),EWn.Lk=function(){return!0},gX(v9n,"BasicFeatureMap/ResolvingFeatureEIterator",662),lAn(955,486,B9n,q$),EWn.Gi=function(){return this},gX(v9n,"EContentsEList/1",955),lAn(956,486,B9n,NO),EWn.Lk=function(){return!1},gX(v9n,"EContentsEList/2",956),lAn(954,279,H9n,G$),EWn.Nk=function(n){},EWn.Ob=function(){return!1},EWn.Sb=function(){return!1},gX(v9n,"EContentsEList/FeatureIteratorImpl/1",954),lAn(825,585,x9n,DL),EWn.ci=function(){this.a=!0},EWn.fj=function(){return this.a},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.a,this.a=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.a=!1},EWn.a=!1,gX(v9n,"EDataTypeEList/Unsettable",825),lAn(1849,585,x9n,RL),EWn.hi=function(){return!0},gX(v9n,"EDataTypeUniqueEList",1849),lAn(1850,825,x9n,KL),EWn.hi=function(){return!0},gX(v9n,"EDataTypeUniqueEList/Unsettable",1850),lAn(139,85,x9n,$L),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectContainmentEList/Resolving",139),lAn(1163,545,x9n,LL),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectContainmentEList/Unsettable/Resolving",1163),lAn(748,16,x9n,tK),EWn.ci=function(){this.a=!0},EWn.fj=function(){return this.a},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.a,this.a=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.a=!1},EWn.a=!1,gX(v9n,"EObjectContainmentWithInverseEList/Unsettable",748),lAn(1173,748,x9n,eK),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectContainmentWithInverseEList/Unsettable/Resolving",1173),lAn(743,496,x9n,NL),EWn.ci=function(){this.a=!0},EWn.fj=function(){return this.a},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.a,this.a=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.a=!1},EWn.a=!1,gX(v9n,"EObjectEList/Unsettable",743),lAn(328,496,x9n,xL),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectResolvingEList",328),lAn(1641,743,x9n,_L),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectResolvingEList/Unsettable",1641),lAn(1381,1,{},Ns),gX(v9n,"EObjectValidator",1381),lAn(546,496,x9n,tU),EWn.zk=function(){return this.d},EWn.Ak=function(){return this.b},EWn.bj=function(){return!0},EWn.Dk=function(){return!0},EWn.b=0,gX(v9n,"EObjectWithInverseEList",546),lAn(1176,546,x9n,iK),EWn.Ck=function(){return!0},gX(v9n,"EObjectWithInverseEList/ManyInverse",1176),lAn(625,546,x9n,rK),EWn.ci=function(){this.a=!0},EWn.fj=function(){return this.a},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.a,this.a=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.a=!1},EWn.a=!1,gX(v9n,"EObjectWithInverseEList/Unsettable",625),lAn(1175,625,x9n,aK),EWn.Ck=function(){return!0},gX(v9n,"EObjectWithInverseEList/Unsettable/ManyInverse",1175),lAn(749,546,x9n,cK),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectWithInverseResolvingEList",749),lAn(31,749,x9n,oK),EWn.Ck=function(){return!0},gX(v9n,"EObjectWithInverseResolvingEList/ManyInverse",31),lAn(750,625,x9n,uK),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectWithInverseResolvingEList/Unsettable",750),lAn(1174,750,x9n,sK),EWn.Ck=function(){return!0},gX(v9n,"EObjectWithInverseResolvingEList/Unsettable/ManyInverse",1174),lAn(1164,622,x9n),EWn.ai=function(){return 0==(1792&this.b)},EWn.ci=function(){this.b|=1},EWn.Bk=function(){return 0!=(4&this.b)},EWn.bj=function(){return 0!=(40&this.b)},EWn.Ck=function(){return 0!=(16&this.b)},EWn.Dk=function(){return 0!=(8&this.b)},EWn.Ek=function(){return 0!=(this.b&E9n)},EWn.rk=function(){return 0!=(32&this.b)},EWn.Fk=function(){return 0!=(this.b&m6n)},EWn.wj=function(n){return this.d?L3(this.d,n):this.ak().Yj().wj(n)},EWn.fj=function(){return 0!=(2&this.b)?0!=(1&this.b):0!=this.i},EWn.hi=function(){return 0!=(128&this.b)},EWn.Xj=function(){var n;uqn(this),0!=(2&this.b)&&(pA(this.e)?(n=0!=(1&this.b),this.b&=-2,Av(this,new Z5(this.e,2,Cwn(this.e.Tg(),this.ak()),n,!1))):this.b&=-2)},EWn.ni=function(){return 0==(1536&this.b)},EWn.b=0,gX(v9n,"EcoreEList/Generic",1164),lAn(1165,1164,x9n,qQ),EWn.ak=function(){return this.a},gX(v9n,"EcoreEList/Dynamic",1165),lAn(747,63,o8n,Pp),EWn.ri=function(n){return Nen(this.a.a,n)},gX(v9n,"EcoreEMap/1",747),lAn(746,85,x9n,Jz),EWn.bi=function(n,t){Pvn(this.b,_B(t,133))},EWn.di=function(n,t){ran(this.b)},EWn.ei=function(n,t,e){var i;++(i=this.b,_B(t,133),i).e},EWn.fi=function(n,t){Iln(this.b,_B(t,133))},EWn.gi=function(n,t,e){Iln(this.b,_B(e,133)),HC(e)===HC(t)&&_B(e,133).Th(i$(_B(t,133).cd())),Pvn(this.b,_B(t,133))},gX(v9n,"EcoreEMap/DelegateEObjectContainmentEList",746),lAn(1171,151,y9n,vin),gX(v9n,"EcoreEMap/Unsettable",1171),lAn(1172,746,x9n,hK),EWn.ci=function(){this.a=!0},EWn.fj=function(){return this.a},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.a,this.a=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.a=!1},EWn.a=!1,gX(v9n,"EcoreEMap/Unsettable/UnsettableDelegateEObjectContainmentEList",1172),lAn(1168,228,ZQn,hX),EWn.a=!1,EWn.b=!1,gX(v9n,"EcoreUtil/Copier",1168),lAn(745,1,WWn,K2),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return cdn(this)},EWn.Pb=function(){var n;return cdn(this),n=this.b,this.b=null,n},EWn.Qb=function(){this.a.Qb()},gX(v9n,"EcoreUtil/ProperContentIterator",745),lAn(1382,1381,{},Kf),gX(v9n,"EcoreValidator",1382),fq(v9n,"FeatureMapUtil/Validator"),lAn(1260,1,{1942:1},xs),EWn.rl=function(n){return!0},gX(v9n,"FeatureMapUtil/1",1260),lAn(757,1,{1942:1},iUn),EWn.rl=function(n){var t;return this.c==n||(null==(t=jD(xX(this.a,n)))?LRn(this,n)?(e6(this.a,n,(oN(),gtt)),!0):(e6(this.a,n,(oN(),dtt)),!1):t==(oN(),gtt))},EWn.e=!1,gX(v9n,"FeatureMapUtil/BasicValidator",757),lAn(758,43,ZQn,z$),gX(v9n,"FeatureMapUtil/BasicValidator/Cache",758),lAn(501,52,{20:1,28:1,52:1,14:1,15:1,58:1,76:1,69:1,95:1},LC),EWn.Vc=function(n,t){Cxn(this.c,this.b,n,t)},EWn.Fc=function(n){return LKn(this.c,this.b,n)},EWn.Wc=function(n,t){return yHn(this.c,this.b,n,t)},EWn.Gc=function(n){return J$(this,n)},EWn.Xh=function(n,t){otn(this.c,this.b,n,t)},EWn.lk=function(n,t){return MRn(this.c,this.b,n,t)},EWn.pi=function(n){return tHn(this.c,this.b,n,!1)},EWn.Zh=function(){return yA(this.c,this.b)},EWn.$h=function(){return kA(this.c,this.b)},EWn._h=function(n){return O8(this.c,this.b,n)},EWn.mk=function(n,t){return ZD(this,n,t)},EWn.$b=function(){$v(this)},EWn.Hc=function(n){return H3(this.c,this.b,n)},EWn.Ic=function(n){return Ecn(this.c,this.b,n)},EWn.Xb=function(n){return tHn(this.c,this.b,n,!0)},EWn.Wj=function(n){return this},EWn.Xc=function(n){return q3(this.c,this.b,n)},EWn.dc=function(){return FC(this)},EWn.fj=function(){return!rdn(this.c,this.b)},EWn.Kc=function(){return inn(this.c,this.b)},EWn.Yc=function(){return rnn(this.c,this.b)},EWn.Zc=function(n){return hln(this.c,this.b,n)},EWn.ii=function(n,t){return pFn(this.c,this.b,n,t)},EWn.ji=function(n,t){W6(this.c,this.b,n,t)},EWn.$c=function(n){return rPn(this.c,this.b,n)},EWn.Mc=function(n){return SKn(this.c,this.b,n)},EWn._c=function(n,t){return zFn(this.c,this.b,n,t)},EWn.Wb=function(n){COn(this.c,this.b),J$(this,_B(n,15))},EWn.gc=function(){return Dln(this.c,this.b)},EWn.Pc=function(){return H1(this.c,this.b)},EWn.Qc=function(n){return G3(this.c,this.b,n)},EWn.Ib=function(){var n,t;for((t=new Tk).a+="[",n=yA(this.c,this.b);Dsn(n);)iO(t,mN(ivn(n))),Dsn(n)&&(t.a+=KWn);return t.a+="]",t.a},EWn.Xj=function(){COn(this.c,this.b)},gX(v9n,"FeatureMapUtil/FeatureEList",501),lAn(627,36,Z8n,f4),EWn.yi=function(n){return nln(this,n)},EWn.Di=function(n){var t,e,i,r;switch(this.d){case 1:case 2:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return this.g=n.zi(),1==n.xi()&&(this.d=1),!0;break;case 3:switch(n.xi()){case 3:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return this.d=5,s9(t=new wtn(2),this.g),s9(t,n.zi()),this.g=t,!0}break;case 5:switch(n.xi()){case 3:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return _B(this.g,14).Fc(n.zi()),!0}break;case 4:switch(n.xi()){case 3:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return this.d=1,this.g=n.zi(),!0;break;case 4:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return this.d=6,s9(r=new wtn(2),this.n),s9(r,n.Bi()),this.n=r,i=Mun(Hk(INt,1),oQn,25,15,[this.o,n.Ci()]),this.g=i,!0}break;case 6:switch(n.xi()){case 4:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return _B(this.n,14).Fc(n.Bi()),rHn(i=_B(this.g,48),0,e=L8(INt,oQn,25,i.length+1,15,1),0,i.length),e[i.length]=n.Ci(),this.g=e,!0}}return!1},gX(v9n,"FeatureMapUtil/FeatureENotificationImpl",627),lAn(552,501,{20:1,28:1,52:1,14:1,15:1,58:1,76:1,153:1,215:1,1937:1,69:1,95:1},hq),EWn.dl=function(n,t){return LKn(this.c,n,t)},EWn.el=function(n,t,e){return MRn(this.c,n,t,e)},EWn.fl=function(n,t,e){return JBn(this.c,n,t,e)},EWn.gl=function(){return this},EWn.hl=function(n,t){return eHn(this.c,n,t)},EWn.il=function(n){return _B(tHn(this.c,this.b,n,!1),72).ak()},EWn.jl=function(n){return _B(tHn(this.c,this.b,n,!1),72).dd()},EWn.kl=function(){return this.a},EWn.ll=function(n){return!rdn(this.c,n)},EWn.ml=function(n,t){EHn(this.c,n,t)},EWn.nl=function(n){return qin(this.c,n)},EWn.ol=function(n){Dmn(this.c,n)},gX(v9n,"FeatureMapUtil/FeatureFeatureMap",552),lAn(1259,1,m9n,DC),EWn.Wj=function(n){return tHn(this.b,this.a,-1,n)},EWn.fj=function(){return!rdn(this.b,this.a)},EWn.Wb=function(n){EHn(this.b,this.a,n)},EWn.Xj=function(){COn(this.b,this.a)},gX(v9n,"FeatureMapUtil/FeatureValue",1259);var fLt=fq(I7n,"AnyType");lAn(666,60,_Vn,tk),gX(I7n,"InvalidDatatypeValueException",666);var lLt,bLt,wLt,dLt,gLt,pLt,vLt,mLt,yLt,kLt,jLt,ELt,TLt,MLt,SLt,PLt,ILt,CLt,OLt,ALt,$Lt,LLt,NLt,xLt,DLt,RLt,KLt,_Lt,FLt,BLt,HLt=fq(I7n,C7n),qLt=fq(I7n,O7n),GLt=fq(I7n,A7n);lAn(830,506,{105:1,92:1,90:1,56:1,49:1,97:1,843:1},xm),EWn._g=function(n,t,e){switch(n){case 0:return e?(!this.c&&(this.c=new kcn(this,0)),this.c):(!this.c&&(this.c=new kcn(this,0)),this.c.b);case 1:return e?(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)):(!this.c&&(this.c=new kcn(this,0)),_B(_B(YZ(this.c,(Gqn(),dLt)),153),215)).kl();case 2:return e?(!this.b&&(this.b=new kcn(this,2)),this.b):(!this.b&&(this.b=new kcn(this,2)),this.b.b)}return G9(this,n-fX(this.zh()),ttn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new Df),this.k).ck(),n),t,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.c&&(this.c=new kcn(this,0)),jKn(this.c,n,e);case 1:return(!this.c&&(this.c=new kcn(this,0)),_B(_B(YZ(this.c,(Gqn(),dLt)),153),69)).mk(n,e);case 2:return!this.b&&(this.b=new kcn(this,2)),jKn(this.b,n,e)}return _B(ttn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new Df),this.k).ck(),t),66).Nj().Rj(this,W7(this),t-fX(this.zh()),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.c&&0!=this.c.i;case 1:return!(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)).dc();case 2:return!!this.b&&0!=this.b.i}return I3(this,n-fX(this.zh()),ttn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.sh=function(n,t){switch(n){case 0:return!this.c&&(this.c=new kcn(this,0)),void ZU(this.c,t);case 1:return void(!this.c&&(this.c=new kcn(this,0)),_B(_B(YZ(this.c,(Gqn(),dLt)),153),215)).Wb(t);case 2:return!this.b&&(this.b=new kcn(this,2)),void ZU(this.b,t)}Abn(this,n-fX(this.zh()),ttn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new Df),this.k).ck(),n),t)},EWn.zh=function(){return Gqn(),wLt},EWn.Bh=function(n){switch(n){case 0:return!this.c&&(this.c=new kcn(this,0)),void uqn(this.c);case 1:return void(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)).$b();case 2:return!this.b&&(this.b=new kcn(this,2)),void uqn(this.b)}Bfn(this,n-fX(this.zh()),ttn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.Ib=function(){var n;return 0!=(4&this.j)?M$n(this):((n=new sN(M$n(this))).a+=" (mixed: ",eO(n,this.c),n.a+=", anyAttribute: ",eO(n,this.b),n.a+=")",n.a)},gX($7n,"AnyTypeImpl",830),lAn(667,506,{105:1,92:1,90:1,56:1,49:1,97:1,2021:1,667:1},Rs),EWn._g=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return G9(this,n-fX((Gqn(),PLt)),ttn(0==(2&this.j)?PLt:(!this.k&&(this.k=new Df),this.k).ck(),n),t,e)},EWn.lh=function(n){switch(n){case 0:return null!=this.a;case 1:return null!=this.b}return I3(this,n-fX((Gqn(),PLt)),ttn(0==(2&this.j)?PLt:(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.sh=function(n,t){switch(n){case 0:return void mb(this,TD(t));case 1:return void yb(this,TD(t))}Abn(this,n-fX((Gqn(),PLt)),ttn(0==(2&this.j)?PLt:(!this.k&&(this.k=new Df),this.k).ck(),n),t)},EWn.zh=function(){return Gqn(),PLt},EWn.Bh=function(n){switch(n){case 0:return void(this.a=null);case 1:return void(this.b=null)}Bfn(this,n-fX((Gqn(),PLt)),ttn(0==(2&this.j)?PLt:(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.Ib=function(){var n;return 0!=(4&this.j)?M$n(this):((n=new sN(M$n(this))).a+=" (data: ",iO(n,this.a),n.a+=", target: ",iO(n,this.b),n.a+=")",n.a)},EWn.a=null,EWn.b=null,gX($7n,"ProcessingInstructionImpl",667),lAn(668,830,{105:1,92:1,90:1,56:1,49:1,97:1,843:1,2022:1,668:1},Rm),EWn._g=function(n,t,e){switch(n){case 0:return e?(!this.c&&(this.c=new kcn(this,0)),this.c):(!this.c&&(this.c=new kcn(this,0)),this.c.b);case 1:return e?(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)):(!this.c&&(this.c=new kcn(this,0)),_B(_B(YZ(this.c,(Gqn(),dLt)),153),215)).kl();case 2:return e?(!this.b&&(this.b=new kcn(this,2)),this.b):(!this.b&&(this.b=new kcn(this,2)),this.b.b);case 3:return!this.c&&(this.c=new kcn(this,0)),TD(eHn(this.c,(Gqn(),OLt),!0));case 4:return wK(this.a,(!this.c&&(this.c=new kcn(this,0)),TD(eHn(this.c,(Gqn(),OLt),!0))));case 5:return this.a}return G9(this,n-fX((Gqn(),CLt)),ttn(0==(2&this.j)?CLt:(!this.k&&(this.k=new Df),this.k).ck(),n),t,e)},EWn.lh=function(n){switch(n){case 0:return!!this.c&&0!=this.c.i;case 1:return!(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)).dc();case 2:return!!this.b&&0!=this.b.i;case 3:return!this.c&&(this.c=new kcn(this,0)),null!=TD(eHn(this.c,(Gqn(),OLt),!0));case 4:return null!=wK(this.a,(!this.c&&(this.c=new kcn(this,0)),TD(eHn(this.c,(Gqn(),OLt),!0))));case 5:return!!this.a}return I3(this,n-fX((Gqn(),CLt)),ttn(0==(2&this.j)?CLt:(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.sh=function(n,t){switch(n){case 0:return!this.c&&(this.c=new kcn(this,0)),void ZU(this.c,t);case 1:return void(!this.c&&(this.c=new kcn(this,0)),_B(_B(YZ(this.c,(Gqn(),dLt)),153),215)).Wb(t);case 2:return!this.b&&(this.b=new kcn(this,2)),void ZU(this.b,t);case 3:return void K0(this,TD(t));case 4:return void K0(this,dK(this.a,t));case 5:return void kb(this,_B(t,148))}Abn(this,n-fX((Gqn(),CLt)),ttn(0==(2&this.j)?CLt:(!this.k&&(this.k=new Df),this.k).ck(),n),t)},EWn.zh=function(){return Gqn(),CLt},EWn.Bh=function(n){switch(n){case 0:return!this.c&&(this.c=new kcn(this,0)),void uqn(this.c);case 1:return void(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)).$b();case 2:return!this.b&&(this.b=new kcn(this,2)),void uqn(this.b);case 3:return!this.c&&(this.c=new kcn(this,0)),void EHn(this.c,(Gqn(),OLt),null);case 4:return void K0(this,dK(this.a,null));case 5:return void(this.a=null)}Bfn(this,n-fX((Gqn(),CLt)),ttn(0==(2&this.j)?CLt:(!this.k&&(this.k=new Df),this.k).ck(),n))},gX($7n,"SimpleAnyTypeImpl",668),lAn(669,506,{105:1,92:1,90:1,56:1,49:1,97:1,2023:1,669:1},Dm),EWn._g=function(n,t,e){switch(n){case 0:return e?(!this.a&&(this.a=new kcn(this,0)),this.a):(!this.a&&(this.a=new kcn(this,0)),this.a.b);case 1:return e?(!this.b&&(this.b=new v9((wWn(),v$t),G$t,this,1)),this.b):(!this.b&&(this.b=new v9((wWn(),v$t),G$t,this,1)),C8(this.b));case 2:return e?(!this.c&&(this.c=new v9((wWn(),v$t),G$t,this,2)),this.c):(!this.c&&(this.c=new v9((wWn(),v$t),G$t,this,2)),C8(this.c));case 3:return!this.a&&(this.a=new kcn(this,0)),YZ(this.a,(Gqn(),LLt));case 4:return!this.a&&(this.a=new kcn(this,0)),YZ(this.a,(Gqn(),NLt));case 5:return!this.a&&(this.a=new kcn(this,0)),YZ(this.a,(Gqn(),DLt));case 6:return!this.a&&(this.a=new kcn(this,0)),YZ(this.a,(Gqn(),RLt))}return G9(this,n-fX((Gqn(),$Lt)),ttn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new Df),this.k).ck(),n),t,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.a&&(this.a=new kcn(this,0)),jKn(this.a,n,e);case 1:return!this.b&&(this.b=new v9((wWn(),v$t),G$t,this,1)),_K(this.b,n,e);case 2:return!this.c&&(this.c=new v9((wWn(),v$t),G$t,this,2)),_K(this.c,n,e);case 5:return!this.a&&(this.a=new kcn(this,0)),ZD(YZ(this.a,(Gqn(),DLt)),n,e)}return _B(ttn(0==(2&this.j)?(Gqn(),$Lt):(!this.k&&(this.k=new Df),this.k).ck(),t),66).Nj().Rj(this,W7(this),t-fX((Gqn(),$Lt)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.a&&0!=this.a.i;case 1:return!!this.b&&0!=this.b.f;case 2:return!!this.c&&0!=this.c.f;case 3:return!this.a&&(this.a=new kcn(this,0)),!FC(YZ(this.a,(Gqn(),LLt)));case 4:return!this.a&&(this.a=new kcn(this,0)),!FC(YZ(this.a,(Gqn(),NLt)));case 5:return!this.a&&(this.a=new kcn(this,0)),!FC(YZ(this.a,(Gqn(),DLt)));case 6:return!this.a&&(this.a=new kcn(this,0)),!FC(YZ(this.a,(Gqn(),RLt)))}return I3(this,n-fX((Gqn(),$Lt)),ttn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.sh=function(n,t){switch(n){case 0:return!this.a&&(this.a=new kcn(this,0)),void ZU(this.a,t);case 1:return!this.b&&(this.b=new v9((wWn(),v$t),G$t,this,1)),void Zcn(this.b,t);case 2:return!this.c&&(this.c=new v9((wWn(),v$t),G$t,this,2)),void Zcn(this.c,t);case 3:return!this.a&&(this.a=new kcn(this,0)),$v(YZ(this.a,(Gqn(),LLt))),!this.a&&(this.a=new kcn(this,0)),void J$(YZ(this.a,LLt),_B(t,14));case 4:return!this.a&&(this.a=new kcn(this,0)),$v(YZ(this.a,(Gqn(),NLt))),!this.a&&(this.a=new kcn(this,0)),void J$(YZ(this.a,NLt),_B(t,14));case 5:return!this.a&&(this.a=new kcn(this,0)),$v(YZ(this.a,(Gqn(),DLt))),!this.a&&(this.a=new kcn(this,0)),void J$(YZ(this.a,DLt),_B(t,14));case 6:return!this.a&&(this.a=new kcn(this,0)),$v(YZ(this.a,(Gqn(),RLt))),!this.a&&(this.a=new kcn(this,0)),void J$(YZ(this.a,RLt),_B(t,14))}Abn(this,n-fX((Gqn(),$Lt)),ttn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new Df),this.k).ck(),n),t)},EWn.zh=function(){return Gqn(),$Lt},EWn.Bh=function(n){switch(n){case 0:return!this.a&&(this.a=new kcn(this,0)),void uqn(this.a);case 1:return!this.b&&(this.b=new v9((wWn(),v$t),G$t,this,1)),void this.b.c.$b();case 2:return!this.c&&(this.c=new v9((wWn(),v$t),G$t,this,2)),void this.c.c.$b();case 3:return!this.a&&(this.a=new kcn(this,0)),void $v(YZ(this.a,(Gqn(),LLt)));case 4:return!this.a&&(this.a=new kcn(this,0)),void $v(YZ(this.a,(Gqn(),NLt)));case 5:return!this.a&&(this.a=new kcn(this,0)),void $v(YZ(this.a,(Gqn(),DLt)));case 6:return!this.a&&(this.a=new kcn(this,0)),void $v(YZ(this.a,(Gqn(),RLt)))}Bfn(this,n-fX((Gqn(),$Lt)),ttn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.Ib=function(){var n;return 0!=(4&this.j)?M$n(this):((n=new sN(M$n(this))).a+=" (mixed: ",eO(n,this.a),n.a+=")",n.a)},gX($7n,"XMLTypeDocumentRootImpl",669),lAn(1919,704,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1,2024:1},Ds),EWn.Ih=function(n,t){switch(n.yj()){case 7:case 8:case 9:case 10:case 16:case 22:case 23:case 24:case 25:case 26:case 32:case 33:case 34:case 36:case 37:case 44:case 45:case 50:case 51:case 53:case 55:case 56:case 57:case 58:case 60:case 61:case 4:return null==t?null:_bn(t);case 19:case 28:case 29:case 35:case 38:case 39:case 41:case 46:case 52:case 54:case 5:return TD(t);case 6:return pD(_B(t,190));case 12:case 47:case 49:case 11:return BGn(this,n,t);case 13:return null==t?null:HBn(_B(t,240));case 15:case 14:return null==t?null:xU(Hy(ED(t)));case 17:return kEn((Gqn(),t));case 18:return kEn(t);case 21:case 20:return null==t?null:DU(_B(t,155).a);case 27:return vD(_B(t,190));case 30:return Rmn((Gqn(),_B(t,15)));case 31:return Rmn(_B(t,15));case 40:return yD((Gqn(),t));case 42:return jEn((Gqn(),t));case 43:return jEn(t);case 59:case 48:return mD((Gqn(),t));default:throw Fp(new Ry(b6n+n.ne()+w6n))}},EWn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=Gtn(n))?cvn(t.Mh(),n):-1),n.G){case 0:return new xm;case 1:return new Rs;case 2:return new Rm;case 3:return new Dm;default:throw Fp(new Ry(p6n+n.zb+w6n))}},EWn.Kh=function(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;switch(n.yj()){case 5:case 52:case 4:return t;case 6:return vpn(t);case 8:case 7:return null==t?null:REn(t);case 9:return null==t?null:Mnn(h_n((i=KBn(t,!0)).length>0&&(f1(0,i.length),43==i.charCodeAt(0))?i.substr(1):i,-128,127)<<24>>24);case 10:return null==t?null:Mnn(h_n((r=KBn(t,!0)).length>0&&(f1(0,r.length),43==r.charCodeAt(0))?r.substr(1):r,-128,127)<<24>>24);case 11:return TD(LXn(this,(Gqn(),vLt),t));case 12:return TD(LXn(this,(Gqn(),mLt),t));case 13:return null==t?null:new lE(KBn(t,!0));case 15:case 14:return wLn(t);case 16:return TD(LXn(this,(Gqn(),yLt),t));case 17:return Fdn((Gqn(),t));case 18:return Fdn(t);case 28:case 29:case 35:case 38:case 39:case 41:case 54:case 19:return KBn(t,!0);case 21:case 20:return PLn(t);case 22:return TD(LXn(this,(Gqn(),kLt),t));case 23:return TD(LXn(this,(Gqn(),jLt),t));case 24:return TD(LXn(this,(Gqn(),ELt),t));case 25:return TD(LXn(this,(Gqn(),TLt),t));case 26:return TD(LXn(this,(Gqn(),MLt),t));case 27:return Jgn(t);case 30:return Bdn((Gqn(),t));case 31:return Bdn(t);case 32:return null==t?null:tln(h_n((h=KBn(t,!0)).length>0&&(f1(0,h.length),43==h.charCodeAt(0))?h.substr(1):h,RVn,NWn));case 33:return null==t?null:new OA((f=KBn(t,!0)).length>0&&(f1(0,f.length),43==f.charCodeAt(0))?f.substr(1):f);case 34:return null==t?null:tln(h_n((l=KBn(t,!0)).length>0&&(f1(0,l.length),43==l.charCodeAt(0))?l.substr(1):l,RVn,NWn));case 36:return null==t?null:ygn(eUn((b=KBn(t,!0)).length>0&&(f1(0,b.length),43==b.charCodeAt(0))?b.substr(1):b));case 37:return null==t?null:ygn(eUn((w=KBn(t,!0)).length>0&&(f1(0,w.length),43==w.charCodeAt(0))?w.substr(1):w));case 40:return Xwn((Gqn(),t));case 42:return Hdn((Gqn(),t));case 43:return Hdn(t);case 44:return null==t?null:new OA((d=KBn(t,!0)).length>0&&(f1(0,d.length),43==d.charCodeAt(0))?d.substr(1):d);case 45:return null==t?null:new OA((g=KBn(t,!0)).length>0&&(f1(0,g.length),43==g.charCodeAt(0))?g.substr(1):g);case 46:return KBn(t,!1);case 47:return TD(LXn(this,(Gqn(),SLt),t));case 59:case 48:return Uwn((Gqn(),t));case 49:return TD(LXn(this,(Gqn(),ILt),t));case 50:return null==t?null:eln(h_n((p=KBn(t,!0)).length>0&&(f1(0,p.length),43==p.charCodeAt(0))?p.substr(1):p,W9n,32767)<<16>>16);case 51:return null==t?null:eln(h_n((c=KBn(t,!0)).length>0&&(f1(0,c.length),43==c.charCodeAt(0))?c.substr(1):c,W9n,32767)<<16>>16);case 53:return TD(LXn(this,(Gqn(),ALt),t));case 55:return null==t?null:eln(h_n((a=KBn(t,!0)).length>0&&(f1(0,a.length),43==a.charCodeAt(0))?a.substr(1):a,W9n,32767)<<16>>16);case 56:return null==t?null:eln(h_n((u=KBn(t,!0)).length>0&&(f1(0,u.length),43==u.charCodeAt(0))?u.substr(1):u,W9n,32767)<<16>>16);case 57:return null==t?null:ygn(eUn((o=KBn(t,!0)).length>0&&(f1(0,o.length),43==o.charCodeAt(0))?o.substr(1):o));case 58:return null==t?null:ygn(eUn((s=KBn(t,!0)).length>0&&(f1(0,s.length),43==s.charCodeAt(0))?s.substr(1):s));case 60:return null==t?null:tln(h_n((e=KBn(t,!0)).length>0&&(f1(0,e.length),43==e.charCodeAt(0))?e.substr(1):e,RVn,NWn));case 61:return null==t?null:tln(h_n(KBn(t,!0),RVn,NWn));default:throw Fp(new Ry(b6n+n.ne()+w6n))}},gX($7n,"XMLTypeFactoryImpl",1919),lAn(586,179,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1,1945:1,586:1},qW),EWn.N=!1,EWn.O=!1;var zLt,ULt,XLt,WLt,VLt,QLt=!1;gX($7n,"XMLTypePackageImpl",586),lAn(1852,1,{837:1},Ks),EWn._j=function(){return sFn(),kNt},gX($7n,"XMLTypePackageImpl/1",1852),lAn(1861,1,u7n,_s),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/10",1861),lAn(1862,1,u7n,Fs),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/11",1862),lAn(1863,1,u7n,Bs),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/12",1863),lAn(1864,1,u7n,Hs),EWn.wj=function(n){return GC(n)},EWn.xj=function(n){return L8(Mtt,uVn,333,n,7,1)},gX($7n,"XMLTypePackageImpl/13",1864),lAn(1865,1,u7n,qs),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/14",1865),lAn(1866,1,u7n,Gs),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/15",1866),lAn(1867,1,u7n,zs),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/16",1867),lAn(1868,1,u7n,Us),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/17",1868),lAn(1869,1,u7n,Xs),EWn.wj=function(n){return iL(n,155)},EWn.xj=function(n){return L8(Stt,uVn,155,n,0,1)},gX($7n,"XMLTypePackageImpl/18",1869),lAn(1870,1,u7n,Ws),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/19",1870),lAn(1853,1,u7n,Vs),EWn.wj=function(n){return iL(n,843)},EWn.xj=function(n){return L8(fLt,FWn,843,n,0,1)},gX($7n,"XMLTypePackageImpl/2",1853),lAn(1871,1,u7n,Qs),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/20",1871),lAn(1872,1,u7n,Js),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/21",1872),lAn(1873,1,u7n,Ys),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/22",1873),lAn(1874,1,u7n,Zs),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/23",1874),lAn(1875,1,u7n,nh),EWn.wj=function(n){return iL(n,190)},EWn.xj=function(n){return L8(ANt,uVn,190,n,0,2)},gX($7n,"XMLTypePackageImpl/24",1875),lAn(1876,1,u7n,th),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/25",1876),lAn(1877,1,u7n,eh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/26",1877),lAn(1878,1,u7n,ih),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/27",1878),lAn(1879,1,u7n,rh),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/28",1879),lAn(1880,1,u7n,ch),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/29",1880),lAn(1854,1,u7n,ah),EWn.wj=function(n){return iL(n,667)},EWn.xj=function(n){return L8(HLt,FWn,2021,n,0,1)},gX($7n,"XMLTypePackageImpl/3",1854),lAn(1881,1,u7n,uh),EWn.wj=function(n){return iL(n,19)},EWn.xj=function(n){return L8(Ctt,uVn,19,n,0,1)},gX($7n,"XMLTypePackageImpl/30",1881),lAn(1882,1,u7n,oh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/31",1882),lAn(1883,1,u7n,sh),EWn.wj=function(n){return iL(n,162)},EWn.xj=function(n){return L8(xtt,uVn,162,n,0,1)},gX($7n,"XMLTypePackageImpl/32",1883),lAn(1884,1,u7n,hh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/33",1884),lAn(1885,1,u7n,fh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/34",1885),lAn(1886,1,u7n,lh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/35",1886),lAn(1887,1,u7n,bh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/36",1887),lAn(1888,1,u7n,wh),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/37",1888),lAn(1889,1,u7n,dh),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/38",1889),lAn(1890,1,u7n,gh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/39",1890),lAn(1855,1,u7n,ph),EWn.wj=function(n){return iL(n,668)},EWn.xj=function(n){return L8(qLt,FWn,2022,n,0,1)},gX($7n,"XMLTypePackageImpl/4",1855),lAn(1891,1,u7n,vh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/40",1891),lAn(1892,1,u7n,mh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/41",1892),lAn(1893,1,u7n,yh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/42",1893),lAn(1894,1,u7n,kh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/43",1894),lAn(1895,1,u7n,jh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/44",1895),lAn(1896,1,u7n,Eh),EWn.wj=function(n){return iL(n,184)},EWn.xj=function(n){return L8(Rtt,uVn,184,n,0,1)},gX($7n,"XMLTypePackageImpl/45",1896),lAn(1897,1,u7n,Th),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/46",1897),lAn(1898,1,u7n,Mh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/47",1898),lAn(1899,1,u7n,Sh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/48",1899),lAn(uQn,1,u7n,Ph),EWn.wj=function(n){return iL(n,184)},EWn.xj=function(n){return L8(Rtt,uVn,184,n,0,1)},gX($7n,"XMLTypePackageImpl/49",uQn),lAn(1856,1,u7n,Ih),EWn.wj=function(n){return iL(n,669)},EWn.xj=function(n){return L8(GLt,FWn,2023,n,0,1)},gX($7n,"XMLTypePackageImpl/5",1856),lAn(1901,1,u7n,Ch),EWn.wj=function(n){return iL(n,162)},EWn.xj=function(n){return L8(xtt,uVn,162,n,0,1)},gX($7n,"XMLTypePackageImpl/50",1901),lAn(1902,1,u7n,Oh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/51",1902),lAn(1903,1,u7n,Ah),EWn.wj=function(n){return iL(n,19)},EWn.xj=function(n){return L8(Ctt,uVn,19,n,0,1)},gX($7n,"XMLTypePackageImpl/52",1903),lAn(1857,1,u7n,$h),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/6",1857),lAn(1858,1,u7n,Lh),EWn.wj=function(n){return iL(n,190)},EWn.xj=function(n){return L8(ANt,uVn,190,n,0,2)},gX($7n,"XMLTypePackageImpl/7",1858),lAn(1859,1,u7n,Nh),EWn.wj=function(n){return qC(n)},EWn.xj=function(n){return L8(mtt,uVn,476,n,8,1)},gX($7n,"XMLTypePackageImpl/8",1859),lAn(1860,1,u7n,xh),EWn.wj=function(n){return iL(n,217)},EWn.xj=function(n){return L8(jtt,uVn,217,n,0,1)},gX($7n,"XMLTypePackageImpl/9",1860),lAn(50,60,_Vn,rk),gX(rnt,"RegEx/ParseException",50),lAn(820,1,{},Dh),EWn.sl=function(n){return n16*e)throw Fp(new rk(mWn((c$(),F8n))));e=16*e+r}if(125!=this.a)throw Fp(new rk(mWn((c$(),B8n))));if(e>cnt)throw Fp(new rk(mWn((c$(),H8n))));n=e}else{if(r=0,0!=this.c||(r=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(e=r,WXn(this),0!=this.c||(r=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));n=e=16*e+r}break;case 117:if(i=0,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));n=t=16*t+i;break;case 118:if(WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if((t=16*t+i)>cnt)throw Fp(new rk(mWn((c$(),"parser.descappe.4"))));n=t;break;case 65:case 90:case 122:throw Fp(new rk(mWn((c$(),q8n))))}return n},EWn.ul=function(n){var t;switch(n){case 100:t=32==(32&this.e)?JUn("Nd",!0):(lWn(),rNt);break;case 68:t=32==(32&this.e)?JUn("Nd",!1):(lWn(),sNt);break;case 119:t=32==(32&this.e)?JUn("IsWord",!0):(lWn(),vNt);break;case 87:t=32==(32&this.e)?JUn("IsWord",!1):(lWn(),fNt);break;case 115:t=32==(32&this.e)?JUn("IsSpace",!0):(lWn(),bNt);break;case 83:t=32==(32&this.e)?JUn("IsSpace",!1):(lWn(),hNt);break;default:throw Fp(new by(ant+n.toString(16)))}return t},EWn.vl=function(n){var t,e,i,r,c,a,u,o,s,h,f;for(this.b=1,WXn(this),t=null,0==this.c&&94==this.a?(WXn(this),n?(lWn(),lWn(),s=new E0(5)):(lWn(),lWn(),Vxn(t=new E0(4),0,cnt),s=new E0(4))):(lWn(),lWn(),s=new E0(4)),r=!0;1!=(f=this.c)&&(0!=f||93!=this.a||r);){if(r=!1,e=this.a,i=!1,10==f)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:uHn(s,this.ul(e)),i=!0;break;case 105:case 73:case 99:case 67:(e=this.Ll(s,e))<0&&(i=!0);break;case 112:case 80:if(!(h=NCn(this,e)))throw Fp(new rk(mWn((c$(),I8n))));uHn(s,h),i=!0;break;default:e=this.tl()}else if(20==f){if((c=hx(this.i,58,this.d))<0)throw Fp(new rk(mWn((c$(),C8n))));if(a=!0,94==sV(this.i,this.d)&&(++this.d,a=!1),!(u=f9(sx(this.i,this.d,c),a,512==(512&this.e))))throw Fp(new rk(mWn((c$(),A8n))));if(uHn(s,u),i=!0,c+1>=this.j||93!=sV(this.i,c+1))throw Fp(new rk(mWn((c$(),C8n))));this.d=c+2}if(WXn(this),!i)if(0!=this.c||45!=this.a)Vxn(s,e,e);else{if(WXn(this),1==(f=this.c))throw Fp(new rk(mWn((c$(),O8n))));0==f&&93==this.a?(Vxn(s,e,e),Vxn(s,45,45)):(o=this.a,10==f&&(o=this.tl()),WXn(this),Vxn(s,e,o))}(this.e&m6n)==m6n&&0==this.c&&44==this.a&&WXn(this)}if(1==this.c)throw Fp(new rk(mWn((c$(),O8n))));return t&&(UGn(t,s),s=t),j$n(s),BHn(s),this.b=0,WXn(this),s},EWn.wl=function(){var n,t,e,i;for(e=this.vl(!1);7!=(i=this.c);){if(n=this.a,(0!=i||45!=n&&38!=n)&&4!=i)throw Fp(new rk(mWn((c$(),R8n))));if(WXn(this),9!=this.c)throw Fp(new rk(mWn((c$(),D8n))));if(t=this.vl(!1),4==i)uHn(e,t);else if(45==n)UGn(e,t);else{if(38!=n)throw Fp(new by("ASSERT"));mGn(e,t)}}return WXn(this),e},EWn.xl=function(){var n,t;return n=this.a-48,lWn(),lWn(),t=new gY(12,null,n),!this.g&&(this.g=new Rv),Sv(this.g,new Ip(n)),WXn(this),t},EWn.yl=function(){return WXn(this),lWn(),wNt},EWn.zl=function(){return WXn(this),lWn(),lNt},EWn.Al=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Bl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Cl=function(){return WXn(this),ssn()},EWn.Dl=function(){return WXn(this),lWn(),gNt},EWn.El=function(){return WXn(this),lWn(),mNt},EWn.Fl=function(){var n;if(this.d>=this.j||64!=(65504&(n=sV(this.i,this.d++))))throw Fp(new rk(mWn((c$(),T8n))));return WXn(this),lWn(),lWn(),new aG(0,n-64)},EWn.Gl=function(){return WXn(this),xFn()},EWn.Hl=function(){return WXn(this),lWn(),yNt},EWn.Il=function(){var n;return lWn(),lWn(),n=new aG(0,105),WXn(this),n},EWn.Jl=function(){return WXn(this),lWn(),pNt},EWn.Kl=function(){return WXn(this),lWn(),dNt},EWn.Ll=function(n,t){return this.tl()},EWn.Ml=function(){return WXn(this),lWn(),uNt},EWn.Nl=function(){var n,t,e,i,r;if(this.d+1>=this.j)throw Fp(new rk(mWn((c$(),k8n))));if(i=-1,t=null,49<=(n=sV(this.i,this.d))&&n<=57){if(i=n-48,!this.g&&(this.g=new Rv),Sv(this.g,new Ip(i)),++this.d,41!=sV(this.i,this.d))throw Fp(new rk(mWn((c$(),v8n))));++this.d}else switch(63==n&&--this.d,WXn(this),(t=IXn(this)).e){case 20:case 21:case 22:case 23:break;case 8:if(7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));break;default:throw Fp(new rk(mWn((c$(),j8n))))}if(WXn(this),e=null,2==(r=Xdn(this)).e){if(2!=r.em())throw Fp(new rk(mWn((c$(),E8n))));e=r.am(1),r=r.am(0)}if(7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),lWn(),lWn(),new ynn(i,t,r,e)},EWn.Ol=function(){return WXn(this),lWn(),oNt},EWn.Pl=function(){var n;if(WXn(this),n=cU(24,Xdn(this)),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Ql=function(){var n;if(WXn(this),n=cU(20,Xdn(this)),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Rl=function(){var n;if(WXn(this),n=cU(22,Xdn(this)),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Sl=function(){var n,t,e,i,r;for(n=0,e=0,t=-1;this.d=this.j)throw Fp(new rk(mWn((c$(),m8n))));if(45==t){for(++this.d;this.d=this.j)throw Fp(new rk(mWn((c$(),m8n))))}if(58==t){if(++this.d,WXn(this),i=CX(Xdn(this),n,e),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));WXn(this)}else{if(41!=t)throw Fp(new rk(mWn((c$(),y8n))));++this.d,WXn(this),i=CX(Xdn(this),n,e)}return i},EWn.Tl=function(){var n;if(WXn(this),n=cU(21,Xdn(this)),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Ul=function(){var n;if(WXn(this),n=cU(23,Xdn(this)),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Vl=function(){var n,t;if(WXn(this),n=this.f++,t=aU(Xdn(this),n),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),t},EWn.Wl=function(){var n;if(WXn(this),n=aU(Xdn(this),0),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Xl=function(n){return WXn(this),5==this.c?(WXn(this),wG(n,(lWn(),lWn(),new o4(9,n)))):wG(n,(lWn(),lWn(),new o4(3,n)))},EWn.Yl=function(n){var t;return WXn(this),lWn(),lWn(),t=new e$(2),5==this.c?(WXn(this),ZHn(t,aNt),ZHn(t,n)):(ZHn(t,n),ZHn(t,aNt)),t},EWn.Zl=function(n){return WXn(this),5==this.c?(WXn(this),lWn(),lWn(),new o4(9,n)):(lWn(),lWn(),new o4(3,n))},EWn.a=0,EWn.b=0,EWn.c=0,EWn.d=0,EWn.e=0,EWn.f=1,EWn.g=null,EWn.j=0,gX(rnt,"RegEx/RegexParser",820),lAn(1824,820,{},Km),EWn.sl=function(n){return!1},EWn.tl=function(){return BDn(this)},EWn.ul=function(n){return b_n(n)},EWn.vl=function(n){return JXn(this)},EWn.wl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.xl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.yl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.zl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Al=function(){return WXn(this),b_n(67)},EWn.Bl=function(){return WXn(this),b_n(73)},EWn.Cl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Dl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.El=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Fl=function(){return WXn(this),b_n(99)},EWn.Gl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Hl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Il=function(){return WXn(this),b_n(105)},EWn.Jl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Kl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Ll=function(n,t){return uHn(n,b_n(t)),-1},EWn.Ml=function(){return WXn(this),lWn(),lWn(),new aG(0,94)},EWn.Nl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Ol=function(){return WXn(this),lWn(),lWn(),new aG(0,36)},EWn.Pl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Ql=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Rl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Sl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Tl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Ul=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Vl=function(){var n;if(WXn(this),n=aU(Xdn(this),0),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Wl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Xl=function(n){return WXn(this),wG(n,(lWn(),lWn(),new o4(3,n)))},EWn.Yl=function(n){var t;return WXn(this),lWn(),lWn(),ZHn(t=new e$(2),n),ZHn(t,aNt),t},EWn.Zl=function(n){return WXn(this),lWn(),lWn(),new o4(3,n)};var JLt=null,YLt=null;gX(rnt,"RegEx/ParserForXMLSchema",1824),lAn(117,1,vnt,Cp),EWn.$l=function(n){throw Fp(new by("Not supported."))},EWn._l=function(){return-1},EWn.am=function(n){return null},EWn.bm=function(){return null},EWn.cm=function(n){},EWn.dm=function(n){},EWn.em=function(){return 0},EWn.Ib=function(){return this.fm(0)},EWn.fm=function(n){return 11==this.e?".":""},EWn.e=0;var ZLt,nNt,tNt,eNt,iNt,rNt,cNt,aNt,uNt,oNt,sNt,hNt,fNt,lNt,bNt,wNt,dNt,gNt,pNt,vNt,mNt,yNt,kNt,jNt,ENt=null,TNt=null,MNt=null,SNt=gX(rnt,"RegEx/Token",117);lAn(136,117,{3:1,136:1,117:1},E0),EWn.fm=function(n){var t,e,i;if(4==this.e)if(this==cNt)e=".";else if(this==rNt)e="\\d";else if(this==vNt)e="\\w";else if(this==bNt)e="\\s";else{for((i=new Tk).a+="[",t=0;t0&&(i.a+=","),this.b[t]===this.b[t+1]?iO(i,rBn(this.b[t])):(iO(i,rBn(this.b[t])),i.a+="-",iO(i,rBn(this.b[t+1])));i.a+="]",e=i.a}else if(this==sNt)e="\\D";else if(this==fNt)e="\\W";else if(this==hNt)e="\\S";else{for((i=new Tk).a+="[^",t=0;t0&&(i.a+=","),this.b[t]===this.b[t+1]?iO(i,rBn(this.b[t])):(iO(i,rBn(this.b[t])),i.a+="-",iO(i,rBn(this.b[t+1])));i.a+="]",e=i.a}return e},EWn.a=!1,EWn.c=!1,gX(rnt,"RegEx/RangeToken",136),lAn(584,1,{584:1},Ip),EWn.a=0,gX(rnt,"RegEx/RegexParser/ReferencePosition",584),lAn(583,1,{3:1,583:1},zE),EWn.Fb=function(n){var t;return null!=n&&!!iL(n,583)&&(t=_B(n,583),pK(this.b,t.b)&&this.a==t.a)},EWn.Hb=function(){return gvn(this.b+"/"+ZNn(this.a))},EWn.Ib=function(){return this.c.fm(this.a)},EWn.a=0,gX(rnt,"RegEx/RegularExpression",583),lAn(223,117,vnt,aG),EWn._l=function(){return this.a},EWn.fm=function(n){var t,e;switch(this.e){case 0:switch(this.a){case 124:case 42:case 43:case 63:case 40:case 41:case 46:case 91:case 123:case 92:e="\\"+MR(this.a&WVn);break;case 12:e="\\f";break;case 10:e="\\n";break;case 13:e="\\r";break;case 9:e="\\t";break;case 27:e="\\e";break;default:e=this.a>=_Qn?"\\v"+sx(t="0"+(this.a>>>0).toString(16),t.length-6,t.length):""+MR(this.a&WVn)}break;case 8:e=this==uNt||this==oNt?""+MR(this.a&WVn):"\\"+MR(this.a&WVn);break;default:e=null}return e},EWn.a=0,gX(rnt,"RegEx/Token/CharToken",223),lAn(309,117,vnt,o4),EWn.am=function(n){return this.a},EWn.cm=function(n){this.b=n},EWn.dm=function(n){this.c=n},EWn.em=function(){return 1},EWn.fm=function(n){var t;if(3==this.e)if(this.c<0&&this.b<0)t=this.a.fm(n)+"*";else if(this.c==this.b)t=this.a.fm(n)+"{"+this.c+"}";else if(this.c>=0&&this.b>=0)t=this.a.fm(n)+"{"+this.c+","+this.b+"}";else{if(!(this.c>=0&&this.b<0))throw Fp(new by("Token#toString(): CLOSURE "+this.c+KWn+this.b));t=this.a.fm(n)+"{"+this.c+",}"}else if(this.c<0&&this.b<0)t=this.a.fm(n)+"*?";else if(this.c==this.b)t=this.a.fm(n)+"{"+this.c+"}?";else if(this.c>=0&&this.b>=0)t=this.a.fm(n)+"{"+this.c+","+this.b+"}?";else{if(!(this.c>=0&&this.b<0))throw Fp(new by("Token#toString(): NONGREEDYCLOSURE "+this.c+KWn+this.b));t=this.a.fm(n)+"{"+this.c+",}?"}return t},EWn.b=0,EWn.c=0,gX(rnt,"RegEx/Token/ClosureToken",309),lAn(821,117,vnt,GU),EWn.am=function(n){return 0==n?this.a:this.b},EWn.em=function(){return 2},EWn.fm=function(n){return 3==this.b.e&&this.b.am(0)==this.a?this.a.fm(n)+"+":9==this.b.e&&this.b.am(0)==this.a?this.a.fm(n)+"+?":this.a.fm(n)+""+this.b.fm(n)},gX(rnt,"RegEx/Token/ConcatToken",821),lAn(1822,117,vnt,ynn),EWn.am=function(n){if(0==n)return this.d;if(1==n)return this.b;throw Fp(new by("Internal Error: "+n))},EWn.em=function(){return this.b?2:1},EWn.fm=function(n){var t;return t=this.c>0?"(?("+this.c+")":8==this.a.e?"(?("+this.a+")":"(?"+this.a,this.b?t+=this.d+"|"+this.b+")":t+=this.d+")",t},EWn.c=0,gX(rnt,"RegEx/Token/ConditionToken",1822),lAn(1823,117,vnt,j0),EWn.am=function(n){return this.b},EWn.em=function(){return 1},EWn.fm=function(n){return"(?"+(0==this.a?"":ZNn(this.a))+(0==this.c?"":ZNn(this.c))+":"+this.b.fm(n)+")"},EWn.a=0,EWn.c=0,gX(rnt,"RegEx/Token/ModifierToken",1823),lAn(822,117,vnt,iW),EWn.am=function(n){return this.a},EWn.em=function(){return 1},EWn.fm=function(n){var t;switch(t=null,this.e){case 6:t=0==this.b?"(?:"+this.a.fm(n)+")":"("+this.a.fm(n)+")";break;case 20:t="(?="+this.a.fm(n)+")";break;case 21:t="(?!"+this.a.fm(n)+")";break;case 22:t="(?<="+this.a.fm(n)+")";break;case 23:t="(?"+this.a.fm(n)+")"}return t},EWn.b=0,gX(rnt,"RegEx/Token/ParenToken",822),lAn(521,117,{3:1,117:1,521:1},gY),EWn.bm=function(){return this.b},EWn.fm=function(n){return 12==this.e?"\\"+this.a:tAn(this.b)},EWn.a=0,gX(rnt,"RegEx/Token/StringToken",521),lAn(465,117,vnt,e$),EWn.$l=function(n){ZHn(this,n)},EWn.am=function(n){return _B(fW(this.a,n),117)},EWn.em=function(){return this.a?this.a.a.c.length:0},EWn.fm=function(n){var t,e,i,r,c;if(1==this.e){if(2==this.a.a.c.length)t=_B(fW(this.a,0),117),r=3==(e=_B(fW(this.a,1),117)).e&&e.am(0)==t?t.fm(n)+"+":9==e.e&&e.am(0)==t?t.fm(n)+"+?":t.fm(n)+""+e.fm(n);else{for(c=new Tk,i=0;i=this.c.b:this.a<=this.c.b},EWn.Sb=function(){return this.b>0},EWn.Tb=function(){return this.b},EWn.Vb=function(){return this.b-1},EWn.Qb=function(){throw Fp(new Zy(Tnt))},EWn.a=0,EWn.b=0,gX(knt,"ExclusiveRange/RangeIterator",254);var PNt=xW(M9n,"C"),INt=xW(I9n,"I"),CNt=xW(OWn,"Z"),ONt=xW(C9n,"J"),ANt=xW(T9n,"B"),$Nt=xW(S9n,"D"),LNt=xW(P9n,"F"),NNt=xW(O9n,"S"),xNt=fq("org.eclipse.elk.core.labels","ILabelManager"),DNt=fq(_6n,"DiagnosticChain"),RNt=fq(s7n,"ResourceSet"),KNt=gX(_6n,"InvocationTargetException",null),_Nt=(Nk(),s5),FNt=FNt=oEn;Jen(Wp),ucn("permProps",[[[Mnt,Snt],[Pnt,"gecko1_8"]],[[Mnt,Snt],[Pnt,"ie10"]],[[Mnt,Snt],[Pnt,"ie8"]],[[Mnt,Snt],[Pnt,"ie9"]],[[Mnt,Snt],[Pnt,"safari"]]]),FNt(null,"elk",null)}).call(this)}).call(this,void 0!==w?w:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(n,t,e){function i(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}function r(n,t){if(!n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?n:t}function c(n,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);n.prototype=Object.create(t&&t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(n,t):n.__proto__=t)}var a=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,e);var c=Object.assign({},t),a=!1;try{n.resolve("web-worker"),a=!0}catch(s){}if(t.workerUrl)if(a){var u=n("web-worker");c.workerFactory=function(n){return new u(n)}}else console.warn("Web worker requested but 'web-worker' package not installed. \nConsider installing the package or pass your own 'workerFactory' to ELK's constructor.\n... Falling back to non-web worker version.");if(!c.workerFactory){var o=n("./elk-worker.min.js").Worker;c.workerFactory=function(n){return new o(n)}}return r(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,c))}return c(e,t),e}(n("./elk-api.js").default);Object.defineProperty(t.exports,"__esModule",{value:!0}),t.exports=a,a.default=a},{"./elk-api.js":1,"./elk-worker.min.js":2,"web-worker":4}],4:[function(n,t,e){t.exports=Worker},{}]},{},[3])(3);const m=new(d(v.exports));let y={};const k={};let j={};const E=(n,t,i)=>{const r={TB:{in:{north:"north"},out:{south:"west",west:"east",east:"south"}},LR:{in:{west:"west"},out:{east:"south",south:"north",north:"east"}},RL:{in:{east:"east"},out:{west:"north",north:"south",south:"west"}},BT:{in:{south:"south"},out:{north:"east",east:"west",west:"north"}}};return r.TD=r.TB,e.info("abc88",i,t,n),r[i][t][n]},T=(n,t,i)=>{if(e.info("getNextPort abc88",{node:n,edgeDirection:t,graphDirection:i}),!y[n])switch(i){case"TB":case"TD":y[n]={inPosition:"north",outPosition:"south"};break;case"BT":y[n]={inPosition:"south",outPosition:"north"};break;case"RL":y[n]={inPosition:"east",outPosition:"west"};break;case"LR":y[n]={inPosition:"west",outPosition:"east"}}const r="in"===t?y[n].inPosition:y[n].outPosition;return"in"===t?y[n].inPosition=E(y[n].inPosition,t,i):y[n].outPosition=E(y[n].outPosition,t,i),r},M=function(n,t,i,r){e.info("abc78 edges = ",n);const c=r.insert("g").attr("class","edgeLabels");let h,f,l={},w=t.db.getDirection();if(void 0!==n.defaultStyle){const t=a(n.defaultStyle);h=t.style,f=t.labelStyle}return n.forEach((function(t){const r="L-"+t.start+"-"+t.end;void 0===l[r]?(l[r]=0,e.info("abc78 new entry",r,l[r])):(l[r]++,e.info("abc78 new entry",r,l[r]));let d=r+"-"+l[r];e.info("abc78 new link id to be used is",r,d,l[r]);const g="LS-"+t.start,p="LE-"+t.end,v={style:"",labelStyle:""};switch(v.minlen=t.length||1,"arrow_open"===t.type?v.arrowhead="none":v.arrowhead="normal",v.arrowTypeStart="arrow_open",v.arrowTypeEnd="arrow_open",t.type){case"double_arrow_cross":v.arrowTypeStart="arrow_cross";case"arrow_cross":v.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":v.arrowTypeStart="arrow_point";case"arrow_point":v.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":v.arrowTypeStart="arrow_circle";case"arrow_circle":v.arrowTypeEnd="arrow_circle"}let m="",y="";switch(t.stroke){case"normal":m="fill:none;",void 0!==h&&(m=h),void 0!==f&&(y=f),v.thickness="normal",v.pattern="solid";break;case"dotted":v.thickness="normal",v.pattern="dotted",v.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":v.thickness="thick",v.pattern="solid",v.style="stroke-width: 3.5px;fill:none;"}if(void 0!==t.style){const n=a(t.style);m=n.style,y=n.labelStyle}v.style=v.style+=m,v.labelStyle=v.labelStyle+=y,void 0!==t.interpolate?v.curve=u(t.interpolate,o):void 0!==n.defaultInterpolate?v.curve=u(n.defaultInterpolate,o):v.curve=u(k.curve,o),void 0===t.text?void 0!==t.style&&(v.arrowheadStyle="fill: #333"):(v.arrowheadStyle="fill: #333",v.labelpos="c"),v.labelType=t.labelType,v.label=t.text.replace(s.lineBreakRegex,"\n"),void 0===t.style&&(v.style=v.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),v.labelStyle=v.labelStyle.replace("color:","fill:"),v.id=d,v.classes="flowchart-link "+g+" "+p;const E=b(c,v),{source:M,target:S,sourceId:P,targetId:I}=((n,t)=>{let e=n.start,i=n.end;const r=e,c=i,a=j[e],u=j[i];return a&&u?("diamond"===a.type&&(e=`${e}-${T(e,"out",t)}`),"diamond"===u.type&&(i=`${i}-${T(i,"in",t)}`),{source:e,target:i,sourceId:r,targetId:c}):{source:e,target:i}})(t,w);e.debug("abc78 source and target",M,S),i.edges.push({id:"e"+t.start+t.end,sources:[M],targets:[S],sourceId:P,targetId:I,labelEl:E,labels:[{width:v.width,height:v.height,orgWidth:v.width,orgHeight:v.height,text:v.label,layoutOptions:{"edgeLabels.inline":"true","edgeLabels.placement":"CENTER"}}],edgeData:v})})),i},S=function(n,t,e){const i=((n,t,e)=>{const{parentById:i}=e,r=new Set;let c=n;for(;c;){if(r.add(c),c===t)return c;c=i[c]}for(c=t;c;){if(r.has(c))return c;c=i[c]}return"root"})(n,t,e);if(void 0===i||"root"===i)return{x:0,y:0};const r=j[i].offset;return{x:r.posX,y:r.posY}},P=function(n,t,e,r,c){const a=S(t.sourceId,t.targetId,c),u=t.sections[0].startPoint,s=t.sections[0].endPoint,h=(t.sections[0].bendPoints?t.sections[0].bendPoints:[]).map((n=>[n.x+a.x,n.y+a.y])),f=[[u.x+a.x,u.y+a.y],...h,[s.x+a.x,s.y+a.y]],l=p().curve(o),b=n.insert("path").attr("d",l(f)).attr("class","path").attr("fill","none"),w=n.insert("g").attr("class","edgeLabel"),d=i(w.node().appendChild(t.labelEl)),g=d.node().firstChild.getBoundingClientRect();d.attr("width",g.width),d.attr("height",g.height),w.attr("transform",`translate(${t.labels[0].x+a.x}, ${t.labels[0].y+a.y})`),function(n,t,e,i){let r="";switch(i&&(r=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,r=r.replace(/\(/g,"\\("),r=r.replace(/\)/g,"\\)")),t.arrowTypeStart){case"arrow_cross":n.attr("marker-start","url("+r+"#"+e+"-crossStart)");break;case"arrow_point":n.attr("marker-start","url("+r+"#"+e+"-pointStart)");break;case"arrow_barb":n.attr("marker-start","url("+r+"#"+e+"-barbStart)");break;case"arrow_circle":n.attr("marker-start","url("+r+"#"+e+"-circleStart)");break;case"aggregation":n.attr("marker-start","url("+r+"#"+e+"-aggregationStart)");break;case"extension":n.attr("marker-start","url("+r+"#"+e+"-extensionStart)");break;case"composition":n.attr("marker-start","url("+r+"#"+e+"-compositionStart)");break;case"dependency":n.attr("marker-start","url("+r+"#"+e+"-dependencyStart)");break;case"lollipop":n.attr("marker-start","url("+r+"#"+e+"-lollipopStart)")}switch(t.arrowTypeEnd){case"arrow_cross":n.attr("marker-end","url("+r+"#"+e+"-crossEnd)");break;case"arrow_point":n.attr("marker-end","url("+r+"#"+e+"-pointEnd)");break;case"arrow_barb":n.attr("marker-end","url("+r+"#"+e+"-barbEnd)");break;case"arrow_circle":n.attr("marker-end","url("+r+"#"+e+"-circleEnd)");break;case"aggregation":n.attr("marker-end","url("+r+"#"+e+"-aggregationEnd)");break;case"extension":n.attr("marker-end","url("+r+"#"+e+"-extensionEnd)");break;case"composition":n.attr("marker-end","url("+r+"#"+e+"-compositionEnd)");break;case"dependency":n.attr("marker-end","url("+r+"#"+e+"-dependencyEnd)");break;case"lollipop":n.attr("marker-end","url("+r+"#"+e+"-lollipopEnd)")}}(b,e,r.type,r.arrowMarkerAbsolute)},I=(n,t)=>{n.forEach((n=>{n.children||(n.children=[]);const e=t.childrenById[n.id];e&&e.forEach((t=>{n.children.push(j[t])})),I(n.children,t)}))},C=(n,t,i,c,a,u,o)=>{i.forEach((function(i){if(i)if(j[i.id].offset={posX:i.x+n,posY:i.y+t,x:n,y:t,depth:o,width:i.width,height:i.height},"group"===i.type){const c=a.insert("g").attr("class","subgraph");c.insert("rect").attr("class","subgraph subgraph-lvl-"+o%5+" node").attr("x",i.x+n).attr("y",i.y+t).attr("width",i.width).attr("height",i.height);const u=c.insert("g").attr("class","label"),s=r().flowchart.htmlLabels?i.labelData.width/2:0;u.attr("transform",`translate(${i.labels[0].x+n+i.x+s}, ${i.labels[0].y+t+i.y+3})`),u.node().appendChild(i.labelData.labelNode),e.info("Id (UGH)= ",i.type,i.labels)}else e.info("Id (UGH)= ",i.id),i.el.attr("transform",`translate(${i.x+n+i.width/2}, ${i.y+t+i.height/2})`)})),i.forEach((function(e){e&&"group"===e.type&&C(n+e.x,t+e.y,e.children,c,a,u,o+1)}))},O={db:n,renderer:{getClasses:function(n,t){e.info("Extracting classes"),t.db.clear("ver-2");try{return t.parse(n),t.db.getClasses()}catch(i){return{}}},draw:async function(n,t,u,o){var s;o.db.clear(),j={},y={},o.db.setGen("gen-2"),o.parser.parse(n);const b=i("body").append("div").attr("style","height:400px").attr("id","cy");let w={id:"root",layoutOptions:{"elk.hierarchyHandling":"INCLUDE_CHILDREN","org.eclipse.elk.padding":"[top=100, left=100, bottom=110, right=110]","elk.layered.spacing.edgeNodeBetweenLayers":"30","elk.direction":"DOWN"},children:[],edges:[]};switch(e.info("Drawing flowchart using v3 renderer",m),o.db.getDirection()){case"BT":w.layoutOptions["elk.direction"]="UP";break;case"TB":w.layoutOptions["elk.direction"]="DOWN";break;case"LR":w.layoutOptions["elk.direction"]="RIGHT";break;case"RL":w.layoutOptions["elk.direction"]="LEFT"}const{securityLevel:d,flowchart:g}=r();let p;"sandbox"===d&&(p=i("#i"+t));const v=i("sandbox"===d?p.nodes()[0].contentDocument.body:"body"),k="sandbox"===d?p.nodes()[0].contentDocument:document,E=v.select(`[id="${t}"]`);h(E,["point","circle","cross"],o.type,o.arrowMarkerAbsolute);const T=o.db.getVertices();let S;const O=o.db.getSubGraphs();e.info("Subgraphs - ",O);for(let e=O.length-1;e>=0;e--)S=O[e],o.db.addVertex(S.id,{text:S.title,type:S.labelType},"group",void 0,S.classes,S.dir);const A=E.insert("g").attr("class","subgraphs"),$=function(n){const t={parentById:{},childrenById:{}},i=n.getSubGraphs();return e.info("Subgraphs - ",i),i.forEach((function(n){n.nodes.forEach((function(e){t.parentById[e]=n.id,void 0===t.childrenById[n.id]&&(t.childrenById[n.id]=[]),t.childrenById[n.id].push(e)}))})),i.forEach((function(n){n.id,void 0!==t.parentById[n.id]&&t.parentById[n.id]})),t}(o.db);w=await async function(n,t,e,i,c,u,o){const s=e.select(`[id="${t}"]`).insert("g").attr("class","nodes"),h=Object.keys(n);return await Promise.all(h.map((async function(t){const e=n[t];let o="default";e.classes.length>0&&(o=e.classes.join(" ")),o+=" flowchart-label";const h=a(e.styles);let b=void 0!==e.text?e.text:e.id;const w={width:0,height:0},d=[{id:e.id+"-west",layoutOptions:{"port.side":"WEST"}},{id:e.id+"-east",layoutOptions:{"port.side":"EAST"}},{id:e.id+"-south",layoutOptions:{"port.side":"SOUTH"}},{id:e.id+"-north",layoutOptions:{"port.side":"NORTH"}}];let g=0,p="",v={};switch(e.type){case"round":g=5,p="rect";break;case"square":p="rect";break;case"diamond":p="question",v={portConstraints:"FIXED_SIDE"};break;case"hexagon":p="hexagon";break;case"odd":p="rect_left_inv_arrow";break;case"lean_right":p="lean_right";break;case"lean_left":p="lean_left";break;case"trapezoid":p="trapezoid";break;case"inv_trapezoid":p="inv_trapezoid";break;case"odd_right":p="rect_left_inv_arrow";break;case"circle":p="circle";break;case"ellipse":p="ellipse";break;case"stadium":p="stadium";break;case"subroutine":p="subroutine";break;case"cylinder":p="cylinder";break;case"group":p="rect";break;case"doublecircle":p="doublecircle";break;default:p="rect"}const m={labelStyle:h.labelStyle,shape:p,labelText:b,labelType:e.labelType,rx:g,ry:g,class:o,style:h.style,id:e.id,link:e.link,linkTarget:e.linkTarget,tooltip:c.db.getTooltip(e.id)||"",domId:c.db.lookUpDomId(e.id),haveCallback:e.haveCallback,width:"group"===e.type?500:void 0,dir:e.dir,type:e.type,props:e.props,padding:r().flowchart.padding};let y,k;if("group"!==m.type)k=await f(s,m,e.dir),y=k.node().getBBox();else{i.createElementNS("http://www.w3.org/2000/svg","text");const{shapeSvg:n,bbox:t}=await l(s,m,void 0,!0);w.width=t.width,w.wrappingWidth=r().flowchart.wrappingWidth,w.height=t.height,w.labelNode=n.node(),m.labelData=w}const E={id:e.id,ports:"diamond"===e.type?d:[],layoutOptions:v,labelText:b,labelData:w,domId:c.db.lookUpDomId(e.id),width:null==y?void 0:y.width,height:null==y?void 0:y.height,type:e.type,el:k,parent:u.parentById[e.id]};j[m.id]=E}))),o}(T,t,v,k,o,$,w);const L=E.insert("g").attr("class","edges edgePath"),N=o.db.getEdges();w=M(N,o,w,E);Object.keys(j).forEach((n=>{const t=j[n];t.parent||w.children.push(t),void 0!==$.childrenById[n]&&(t.labels=[{text:t.labelText,layoutOptions:{"nodeLabels.placement":"[H_CENTER, V_TOP, INSIDE]"},width:t.labelData.width,height:t.labelData.height}],delete t.x,delete t.y,delete t.width,delete t.height)})),I(w.children,$),e.info("after layout",JSON.stringify(w,null,2));const x=await m.layout(w);C(0,0,x.children,E,A,o,0),e.info("after layout",x),null==(s=x.edges)||s.map((n=>{P(L,n,n.edgeData,o,$)})),c({},E,g.diagramPadding,g.useMaxWidth),b.remove()}},parser:t,styles:n=>`.label {\n font-family: ${n.fontFamily};\n color: ${n.nodeTextColor||n.textColor};\n }\n .cluster-label text {\n fill: ${n.titleColor};\n }\n .cluster-label span {\n color: ${n.titleColor};\n }\n\n .label text,span {\n fill: ${n.nodeTextColor||n.textColor};\n color: ${n.nodeTextColor||n.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${n.mainBkg};\n stroke: ${n.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${n.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${n.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${n.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${n.edgeLabelBackground};\n rect {\n opacity: 0.85;\n background-color: ${n.edgeLabelBackground};\n fill: ${n.edgeLabelBackground};\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ${n.clusterBkg};\n stroke: ${n.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${n.titleColor};\n }\n\n .cluster span {\n color: ${n.titleColor};\n }\n /* .cluster div {\n color: ${n.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${n.fontFamily};\n font-size: 12px;\n background: ${n.tertiaryColor};\n border: 1px solid ${n.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${n.textColor};\n }\n .subgraph {\n stroke-width:2;\n rx:3;\n }\n // .subgraph-lvl-1 {\n // fill:#ccc;\n // // stroke:black;\n // }\n\n .flowchart-label text {\n text-anchor: middle;\n }\n\n ${(n=>{let t="";for(let e=0;e<5;e++)t+=`\n .subgraph-lvl-${e} {\n fill: ${n[`surface${e}`]};\n stroke: ${n[`surfacePeer${e}`]};\n }\n `;return t})(n)}\n`};export{O as diagram}; +import{d as n,p as t}from"./flowDb-a707052f.baad4ae4.js";import{l as e,h as i,c as r,t as c,p as a,r as u,o,j as s}from"./mermaid.core.3a590193.js";import{i as h,a as f,l,b}from"./edges-97052da4.e255927b.js";import{Y as w,Z as d,_ as g}from"./app.48111a85.js";import{l as p}from"./line.53b161c2.js";import"./createText-2f679d62.a374f608.js";import"./svgDraw-6750006d.f814d75b.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";var v={exports:{}};v.exports=function(){function n(t,e,i){function r(a,u){if(!e[a]){if(!t[a]){var o="function"==typeof g&&g;if(!u&&o)return o(a,!0);if(c)return c(a,!0);var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}var h=e[a]={exports:{}};t[a][0].call(h.exports,(function(n){return r(t[a][1][n]||n)}),h,h.exports,n,t,e,i)}return e[a].exports}for(var c="function"==typeof g&&g,a=0;a0&&void 0!==arguments[0]?arguments[0]:{},i=e.defaultLayoutOptions,c=void 0===i?{}:i,u=e.algorithms,o=void 0===u?["layered","stress","mrtree","radial","force","disco","sporeOverlap","sporeCompaction","rectpacking"]:u,s=e.workerFactory,h=e.workerUrl;if(r(this,n),this.defaultLayoutOptions=c,this.initialized=!1,void 0===h&&void 0===s)throw new Error("Cannot construct an ELK without both 'workerUrl' and 'workerFactory'.");var f=s;void 0!==h&&void 0===s&&(f=function(n){return new Worker(n)});var l=f(h);if("function"!=typeof l.postMessage)throw new TypeError("Created worker does not provide the required 'postMessage' function.");this.worker=new a(l),this.worker.postMessage({cmd:"register",algorithms:o}).then((function(n){return t.initialized=!0})).catch(console.err)}return i(n,[{key:"layout",value:function(n){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},e=t.layoutOptions,i=void 0===e?this.defaultLayoutOptions:e,r=t.logging,c=void 0!==r&&r,a=t.measureExecutionTime,u=void 0!==a&&a;return n?this.worker.postMessage({cmd:"layout",graph:n,layoutOptions:i,options:{logging:c,measureExecutionTime:u}}):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()}}]),n}();e.default=c;var a=function(){function n(t){var e=this;if(r(this,n),void 0===t)throw new Error("Missing mandatory parameter 'worker'.");this.resolvers={},this.worker=t,this.worker.onmessage=function(n){setTimeout((function(){e.receive(e,n)}),0)}}return i(n,[{key:"postMessage",value:function(n){var t=this.id||0;this.id=t+1,n.id=t;var e=this;return new Promise((function(i,r){e.resolvers[t]=function(n,t){n?(e.convertGwtStyleError(n),r(n)):i(t)},e.worker.postMessage(n)}))}},{key:"receive",value:function(n,t){var e=t.data,i=n.resolvers[e.id];i&&(delete n.resolvers[e.id],e.error?i(e.error):i(null,e.data))}},{key:"terminate",value:function(){this.worker.terminate&&this.worker.terminate()}},{key:"convertGwtStyleError",value:function(n){if(n){var t=n.__java$exception;t&&(t.cause&&t.cause.backingJsObject&&(n.cause=t.cause.backingJsObject,this.convertGwtStyleError(n.cause)),delete n.__java$exception)}}}]),n}()},{}],2:[function(n,t,e){(function(n){(function(){var i;function r(){}function c(){}function a(){}function u(){}function o(){}function s(){}function h(){}function f(){}function l(){}function b(){}function w(){}function d(){}function g(){}function p(){}function v(){}function m(){}function y(){}function k(){}function j(){}function E(){}function T(){}function M(){}function S(){}function P(){}function I(){}function C(){}function O(){}function A(){}function $(){}function L(){}function N(){}function x(){}function D(){}function R(){}function K(){}function _(){}function F(){}function B(){}function H(){}function q(){}function G(){}function z(){}function U(){}function X(){}function W(){}function V(){}function Q(){}function J(){}function Y(){}function Z(){}function nn(){}function tn(){}function en(){}function rn(){}function cn(){}function an(){}function un(){}function on(){}function sn(){}function hn(){}function fn(){}function ln(){}function bn(){}function wn(){}function dn(){}function gn(){}function pn(){}function vn(){}function mn(){}function yn(){}function kn(){}function jn(){}function En(){}function Tn(){}function Mn(){}function Sn(){}function Pn(){}function In(){}function Cn(){}function On(){}function An(){}function $n(){}function Ln(){}function Nn(){}function xn(){}function Dn(){}function Rn(){}function Kn(){}function _n(){}function Fn(){}function Bn(){}function Hn(){}function qn(){}function Gn(){}function zn(){}function Un(){}function Xn(){}function Wn(){}function Vn(){}function Qn(){}function Jn(){}function Yn(){}function Zn(){}function nt(){}function tt(){}function et(){}function it(){}function rt(){}function ct(){}function at(){}function ut(){}function ot(){}function st(){}function ht(){}function ft(){}function lt(){}function bt(){}function wt(){}function dt(){}function gt(){}function pt(){}function vt(){}function mt(){}function yt(){}function kt(){}function jt(){}function Et(){}function Tt(){}function Mt(){}function St(){}function Pt(){}function It(){}function Ct(){}function Ot(){}function At(){}function $t(){}function Lt(){}function Nt(){}function xt(){}function Dt(){}function Rt(){}function Kt(){}function _t(){}function Ft(){}function Bt(){}function Ht(){}function qt(){}function Gt(){}function zt(){}function Ut(){}function Xt(){}function Wt(){}function Vt(){}function Qt(){}function Jt(){}function Yt(){}function Zt(){}function ne(){}function te(){}function ee(){}function ie(){}function re(){}function ce(){}function ae(){}function ue(){}function oe(){}function se(){}function he(){}function fe(){}function le(){}function be(){}function we(){}function de(){}function ge(){}function pe(){}function ve(){}function me(){}function ye(){}function ke(){}function je(){}function Ee(){}function Te(){}function Me(){}function Se(){}function Pe(){}function Ie(){}function Ce(){}function Oe(){}function Ae(){}function $e(){}function Le(){}function Ne(){}function xe(){}function De(){}function Re(){}function Ke(){}function _e(){}function Fe(){}function Be(){}function He(){}function qe(){}function Ge(){}function ze(){}function Ue(){}function Xe(){}function We(){}function Ve(){}function Qe(){}function Je(){}function Ye(){}function Ze(){}function ni(){}function ti(){}function ei(){}function ii(){}function ri(){}function ci(){}function ai(){}function ui(){}function oi(){}function si(){}function hi(){}function fi(){}function li(){}function bi(){}function wi(){}function di(){}function gi(){}function pi(){}function vi(){}function mi(){}function yi(){}function ki(){}function ji(){}function Ei(){}function Ti(){}function Mi(){}function Si(){}function Pi(){}function Ii(){}function Ci(){}function Oi(){}function Ai(){}function $i(){}function Li(){}function Ni(){}function xi(){}function Di(){}function Ri(){}function Ki(){}function _i(){}function Fi(){}function Bi(){}function Hi(){}function qi(){}function Gi(){}function zi(){}function Ui(){}function Xi(){}function Wi(){}function Vi(){}function Qi(){}function Ji(){}function Yi(){}function Zi(){}function nr(){}function tr(){}function er(){}function ir(){}function rr(){}function cr(){}function ar(){}function ur(){}function or(){}function sr(){}function hr(){}function fr(){}function lr(){}function br(){}function wr(){}function dr(){}function gr(){}function pr(){}function vr(){}function mr(){}function yr(){}function kr(){}function jr(){}function Er(){}function Tr(){}function Mr(){}function Sr(){}function Pr(){}function Ir(){}function Cr(){}function Or(){}function Ar(){}function $r(){}function Lr(){}function Nr(){}function xr(){}function Dr(){}function Rr(){}function Kr(){}function _r(){}function Fr(){}function Br(){}function Hr(){}function qr(){}function Gr(){}function zr(){}function Ur(){}function Xr(){}function Wr(){}function Vr(){}function Qr(){}function Jr(){}function Yr(){}function Zr(){}function nc(){}function tc(){}function ec(){}function ic(){}function rc(){}function cc(){}function ac(){}function uc(){}function oc(){}function sc(){}function hc(){}function fc(){}function lc(){}function bc(){}function wc(){}function dc(){}function gc(){}function pc(){}function vc(){}function mc(){}function yc(){}function kc(){}function jc(){}function Ec(){}function Tc(){}function Mc(){}function Sc(){}function Pc(){}function Ic(){}function Cc(){}function Oc(){}function Ac(){}function $c(){}function Lc(){}function Nc(){}function xc(){}function Dc(){}function Rc(){}function Kc(){}function _c(){}function Fc(){}function Bc(){}function Hc(){}function qc(){}function Gc(){}function zc(){}function Uc(){}function Xc(){}function Wc(){}function Vc(){}function Qc(){}function Jc(){}function Yc(){}function Zc(){}function na(){}function ta(){}function ea(){}function ia(){}function ra(){}function ca(){}function aa(){}function ua(){}function oa(){}function sa(){}function ha(){}function fa(){}function la(){}function ba(){}function wa(){}function da(){}function ga(){}function pa(){}function va(){}function ma(){}function ya(){}function ka(){}function ja(){}function Ea(){}function Ta(){}function Ma(){}function Sa(){}function Pa(){}function Ia(){}function Ca(){}function Oa(){}function Aa(){}function $a(){}function La(){}function Na(){}function xa(){}function Da(){}function Ra(){}function Ka(){}function _a(){}function Fa(){}function Ba(){}function Ha(){}function qa(){}function Ga(){}function za(){}function Ua(){}function Xa(){}function Wa(){}function Va(){}function Qa(){}function Ja(){}function Ya(){}function Za(){}function nu(){}function tu(){}function eu(){}function iu(){}function ru(){}function cu(){}function au(){}function uu(){}function ou(){}function su(){}function hu(){}function fu(){}function lu(){}function bu(){}function wu(){}function du(){}function gu(){}function pu(){}function vu(){}function mu(){}function yu(){}function ku(){}function ju(){}function Eu(){}function Tu(){}function Mu(){}function Su(){}function Pu(){}function Iu(){}function Cu(){}function Ou(){}function Au(){}function $u(){}function Lu(){}function Nu(){}function xu(){}function Du(){}function Ru(){}function Ku(){}function _u(){}function Fu(){}function Bu(){}function Hu(){}function qu(){}function Gu(){}function zu(){}function Uu(){}function Xu(){}function Wu(){}function Vu(){}function Qu(){}function Ju(){}function Yu(){}function Zu(){}function no(){}function to(){}function eo(){}function io(){}function ro(){}function co(){}function ao(){}function uo(){}function oo(){}function so(){}function ho(){}function fo(){}function lo(){}function bo(){}function wo(){}function go(){}function po(){}function vo(){}function mo(){}function yo(){}function ko(){}function jo(){}function Eo(){}function To(){}function Mo(){}function So(){}function Po(){}function Io(){}function Co(){}function Oo(){}function Ao(){}function $o(){}function Lo(){}function No(){}function xo(){}function Do(){}function Ro(){}function Ko(){}function _o(){}function Fo(){}function Bo(){}function Ho(){}function qo(){}function Go(){}function zo(){}function Uo(){}function Xo(){}function Wo(){}function Vo(){}function Qo(){}function Jo(){}function Yo(){}function Zo(){}function ns(){}function ts(){}function es(){}function is(){}function rs(){}function cs(){}function as(){}function us(){}function os(){}function ss(){}function hs(){}function fs(){}function ls(){}function bs(){}function ws(){}function ds(){}function gs(){}function ps(){}function vs(){}function ms(){}function ys(){}function ks(){}function js(){}function Es(){}function Ts(){}function Ms(){}function Ss(){}function Ps(){}function Is(){}function Cs(){}function Os(){}function As(){}function $s(){}function Ls(){}function Ns(){}function xs(){}function Ds(){}function Rs(){}function Ks(){}function _s(){}function Fs(){}function Bs(){}function Hs(){}function qs(){}function Gs(){}function zs(){}function Us(){}function Xs(){}function Ws(){}function Vs(){}function Qs(){}function Js(){}function Ys(){}function Zs(){}function nh(){}function th(){}function eh(){}function ih(){}function rh(){}function ch(){}function ah(){}function uh(){}function oh(){}function sh(){}function hh(){}function fh(){}function lh(){}function bh(){}function wh(){}function dh(){}function gh(){}function ph(){}function vh(){}function mh(){}function yh(){}function kh(){}function jh(){}function Eh(){}function Th(){}function Mh(){}function Sh(){}function Ph(){}function Ih(){}function Ch(){}function Oh(){}function Ah(){}function $h(){}function Lh(){}function Nh(){}function xh(){}function Dh(){}function Rh(){}function Kh(){}function _h(){ty()}function Fh(){Hsn()}function Bh(){kpn()}function Hh(){Rkn()}function qh(){ySn()}function Gh(){sRn()}function zh(){Dyn()}function Uh(){ekn()}function Xh(){kM()}function Wh(){pM()}function Vh(){B_()}function Qh(){jM()}function Jh(){Prn()}function Yh(){TM()}function Zh(){P6()}function nf(){Min()}function tf(){W8()}function ef(){RZ()}function rf(){qsn()}function cf(){RMn()}function af(){Sin()}function uf(){G2()}function of(){sWn()}function sf(){Hyn()}function hf(){KZ()}function ff(){FXn()}function lf(){xZ()}function bf(){Pin()}function wf(){Vun()}function df(){HZ()}function gf(){S9()}function pf(){MM()}function vf(){DAn()}function mf(){Gyn()}function yf(){Kcn()}function kf(){EMn()}function jf(){fRn()}function Ef(){_vn()}function Tf(){SAn()}function Mf(){xan()}function Sf(){FZ()}function Pf(){u_n()}function If(){OAn()}function Cf(){U$n()}function Of(){L9()}function Af(){TMn()}function $f(){uWn()}function Lf(){zsn()}function Nf(){gdn()}function xf(){BBn()}function Df(){c_()}function Rf(){lcn()}function Kf(){sFn()}function _f(n){mW(n)}function Ff(n){this.a=n}function Bf(n){this.a=n}function Hf(n){this.a=n}function qf(n){this.a=n}function Gf(n){this.a=n}function zf(n){this.a=n}function Uf(n){this.a=n}function Xf(n){this.a=n}function Wf(n){this.a=n}function Vf(n){this.a=n}function Qf(n){this.a=n}function Jf(n){this.a=n}function Yf(n){this.a=n}function Zf(n){this.a=n}function nl(n){this.a=n}function tl(n){this.a=n}function el(n){this.a=n}function il(n){this.a=n}function rl(n){this.a=n}function cl(n){this.a=n}function al(n){this.a=n}function ul(n){this.b=n}function ol(n){this.c=n}function sl(n){this.a=n}function hl(n){this.a=n}function fl(n){this.a=n}function ll(n){this.a=n}function bl(n){this.a=n}function wl(n){this.a=n}function dl(n){this.a=n}function gl(n){this.a=n}function pl(n){this.a=n}function vl(n){this.a=n}function ml(n){this.a=n}function yl(n){this.a=n}function kl(n){this.a=n}function jl(n){this.a=n}function El(n){this.a=n}function Tl(n){this.a=n}function Ml(n){this.a=n}function Sl(){this.a=[]}function Pl(n,t){n.a=t}function Il(n,t){n.a=t}function Cl(n,t){n.b=t}function Ol(n,t){n.b=t}function Al(n,t){n.b=t}function $l(n,t){n.j=t}function Ll(n,t){n.g=t}function Nl(n,t){n.i=t}function xl(n,t){n.c=t}function Dl(n,t){n.d=t}function Rl(n,t){n.d=t}function Kl(n,t){n.c=t}function _l(n,t){n.k=t}function Fl(n,t){n.c=t}function Bl(n,t){n.c=t}function Hl(n,t){n.a=t}function ql(n,t){n.a=t}function Gl(n,t){n.f=t}function zl(n,t){n.a=t}function Ul(n,t){n.b=t}function Xl(n,t){n.d=t}function Wl(n,t){n.i=t}function Vl(n,t){n.o=t}function Ql(n,t){n.r=t}function Jl(n,t){n.a=t}function Yl(n,t){n.b=t}function Zl(n,t){n.e=t}function nb(n,t){n.f=t}function tb(n,t){n.g=t}function eb(n,t){n.e=t}function ib(n,t){n.f=t}function rb(n,t){n.f=t}function cb(n,t){n.n=t}function ab(n,t){n.a=t}function ub(n,t){n.a=t}function ob(n,t){n.c=t}function sb(n,t){n.c=t}function hb(n,t){n.d=t}function fb(n,t){n.e=t}function lb(n,t){n.g=t}function bb(n,t){n.a=t}function wb(n,t){n.c=t}function db(n,t){n.d=t}function gb(n,t){n.e=t}function pb(n,t){n.f=t}function vb(n,t){n.j=t}function mb(n,t){n.a=t}function yb(n,t){n.b=t}function kb(n,t){n.a=t}function jb(n){n.b=n.a}function Eb(n){n.c=n.d.d}function Tb(n){this.d=n}function Mb(n){this.a=n}function Sb(n){this.a=n}function Pb(n){this.a=n}function Ib(n){this.a=n}function Cb(n){this.a=n}function Ob(n){this.a=n}function Ab(n){this.a=n}function $b(n){this.a=n}function Lb(n){this.a=n}function Nb(n){this.a=n}function xb(n){this.a=n}function Db(n){this.a=n}function Rb(n){this.a=n}function Kb(n){this.a=n}function _b(n){this.b=n}function Fb(n){this.b=n}function Bb(n){this.b=n}function Hb(n){this.a=n}function qb(n){this.a=n}function Gb(n){this.a=n}function zb(n){this.c=n}function Ub(n){this.c=n}function Xb(n){this.c=n}function Wb(n){this.a=n}function Vb(n){this.a=n}function Qb(n){this.a=n}function Jb(n){this.a=n}function Yb(n){this.a=n}function Zb(n){this.a=n}function nw(n){this.a=n}function tw(n){this.a=n}function ew(n){this.a=n}function iw(n){this.a=n}function rw(n){this.a=n}function cw(n){this.a=n}function aw(n){this.a=n}function uw(n){this.a=n}function ow(n){this.a=n}function sw(n){this.a=n}function hw(n){this.a=n}function fw(n){this.a=n}function lw(n){this.a=n}function bw(n){this.a=n}function ww(n){this.a=n}function dw(n){this.a=n}function gw(n){this.a=n}function pw(n){this.a=n}function vw(n){this.a=n}function mw(n){this.a=n}function yw(n){this.a=n}function kw(n){this.a=n}function jw(n){this.a=n}function Ew(n){this.a=n}function Tw(n){this.a=n}function Mw(n){this.a=n}function Sw(n){this.a=n}function Pw(n){this.a=n}function Iw(n){this.a=n}function Cw(n){this.a=n}function Ow(n){this.a=n}function Aw(n){this.a=n}function $w(n){this.a=n}function Lw(n){this.a=n}function Nw(n){this.a=n}function xw(n){this.a=n}function Dw(n){this.a=n}function Rw(n){this.a=n}function Kw(n){this.a=n}function _w(n){this.e=n}function Fw(n){this.a=n}function Bw(n){this.a=n}function Hw(n){this.a=n}function qw(n){this.a=n}function Gw(n){this.a=n}function zw(n){this.a=n}function Uw(n){this.a=n}function Xw(n){this.a=n}function Ww(n){this.a=n}function Vw(n){this.a=n}function Qw(n){this.a=n}function Jw(n){this.a=n}function Yw(n){this.a=n}function Zw(n){this.a=n}function nd(n){this.a=n}function td(n){this.a=n}function ed(n){this.a=n}function id(n){this.a=n}function rd(n){this.a=n}function cd(n){this.a=n}function ad(n){this.a=n}function ud(n){this.a=n}function od(n){this.a=n}function sd(n){this.a=n}function hd(n){this.a=n}function fd(n){this.a=n}function ld(n){this.a=n}function bd(n){this.a=n}function wd(n){this.a=n}function dd(n){this.a=n}function gd(n){this.a=n}function pd(n){this.a=n}function vd(n){this.a=n}function md(n){this.a=n}function yd(n){this.a=n}function kd(n){this.a=n}function jd(n){this.a=n}function Ed(n){this.a=n}function Td(n){this.a=n}function Md(n){this.a=n}function Sd(n){this.a=n}function Pd(n){this.a=n}function Id(n){this.a=n}function Cd(n){this.a=n}function Od(n){this.a=n}function Ad(n){this.a=n}function $d(n){this.a=n}function Ld(n){this.a=n}function Nd(n){this.a=n}function xd(n){this.a=n}function Dd(n){this.a=n}function Rd(n){this.a=n}function Kd(n){this.a=n}function _d(n){this.c=n}function Fd(n){this.b=n}function Bd(n){this.a=n}function Hd(n){this.a=n}function qd(n){this.a=n}function Gd(n){this.a=n}function zd(n){this.a=n}function Ud(n){this.a=n}function Xd(n){this.a=n}function Wd(n){this.a=n}function Vd(n){this.a=n}function Qd(n){this.a=n}function Jd(n){this.a=n}function Yd(n){this.a=n}function Zd(n){this.a=n}function ng(n){this.a=n}function tg(n){this.a=n}function eg(n){this.a=n}function ig(n){this.a=n}function rg(n){this.a=n}function cg(n){this.a=n}function ag(n){this.a=n}function ug(n){this.a=n}function og(n){this.a=n}function sg(n){this.a=n}function hg(n){this.a=n}function fg(n){this.a=n}function lg(n){this.a=n}function bg(n){this.a=n}function wg(n){this.a=n}function dg(n){this.a=n}function gg(n){this.a=n}function pg(n){this.a=n}function vg(n){this.a=n}function mg(n){this.a=n}function yg(n){this.a=n}function kg(n){this.a=n}function jg(n){this.a=n}function Eg(n){this.a=n}function Tg(n){this.a=n}function Mg(n){this.a=n}function Sg(n){this.a=n}function Pg(n){this.a=n}function Ig(n){this.a=n}function Cg(n){this.a=n}function Og(n){this.a=n}function Ag(n){this.a=n}function $g(n){this.a=n}function Lg(n){this.a=n}function Ng(n){this.a=n}function xg(n){this.a=n}function Dg(n){this.a=n}function Rg(n){this.a=n}function Kg(n){this.a=n}function _g(n){this.a=n}function Fg(n){this.a=n}function Bg(n){this.a=n}function Hg(n){this.a=n}function qg(n){this.a=n}function Gg(n){this.a=n}function zg(n){this.a=n}function Ug(n){this.a=n}function Xg(n){this.a=n}function Wg(n){this.a=n}function Vg(n){this.a=n}function Qg(n){this.a=n}function Jg(n){this.a=n}function Yg(n){this.a=n}function Zg(n){this.a=n}function np(n){this.a=n}function tp(n){this.a=n}function ep(n){this.a=n}function ip(n){this.a=n}function rp(n){this.a=n}function cp(n){this.b=n}function ap(n){this.f=n}function up(n){this.a=n}function op(n){this.a=n}function sp(n){this.a=n}function hp(n){this.a=n}function fp(n){this.a=n}function lp(n){this.a=n}function bp(n){this.a=n}function wp(n){this.a=n}function dp(n){this.a=n}function gp(n){this.a=n}function pp(n){this.a=n}function vp(n){this.b=n}function mp(n){this.c=n}function yp(n){this.e=n}function kp(n){this.a=n}function jp(n){this.a=n}function Ep(n){this.a=n}function Tp(n){this.a=n}function Mp(n){this.a=n}function Sp(n){this.d=n}function Pp(n){this.a=n}function Ip(n){this.a=n}function Cp(n){this.e=n}function Op(){this.a=0}function Ap(){NA(this)}function $p(){LA(this)}function Lp(){OU(this)}function Np(){lV(this)}function xp(){}function Dp(){this.c=O$t}function Rp(n,t){t.Wb(n)}function Kp(n,t){n.b+=t}function _p(n){n.b=new ak}function Fp(n){return n.e}function Bp(n){return n.a}function Hp(n){return n.a}function qp(n){return n.a}function Gp(n){return n.a}function zp(n){return n.a}function Up(){return null}function Xp(){return null}function Wp(){rE(),bXn()}function Vp(n){n.b.tf(n.e)}function Qp(n,t){n.b=t-n.b}function Jp(n,t){n.a=t-n.a}function Yp(n,t){t.ad(n.a)}function Zp(n,t){BIn(t,n)}function nv(n,t,e){n.Od(e,t)}function tv(n,t){n.e=t,t.b=n}function ev(n){u_(),this.a=n}function iv(n){u_(),this.a=n}function rv(n){u_(),this.a=n}function cv(n){UX(),this.a=n}function av(n){MJ(),ntt.be(n)}function uv(){wN.call(this)}function ov(){wN.call(this)}function sv(){uv.call(this)}function hv(){uv.call(this)}function fv(){uv.call(this)}function lv(){uv.call(this)}function bv(){uv.call(this)}function wv(){uv.call(this)}function dv(){uv.call(this)}function gv(){uv.call(this)}function pv(){uv.call(this)}function vv(){uv.call(this)}function mv(){uv.call(this)}function yv(){this.a=this}function kv(){this.Bb|=256}function jv(){this.b=new MO}function Ev(){Ev=O,new Lp}function Tv(){sv.call(this)}function Mv(n,t){n.length=t}function Sv(n,t){UB(n.a,t)}function Pv(n,t){GSn(n.c,t)}function Iv(n,t){jU(n.b,t)}function Cv(n,t){Pvn(n.a,t)}function Ov(n,t){Iln(n.a,t)}function Av(n,t){fan(n.e,t)}function $v(n){COn(n.c,n.b)}function Lv(n,t){n.kc().Nb(t)}function Nv(n){this.a=wbn(n)}function xv(){this.a=new Lp}function Dv(){this.a=new Lp}function Rv(){this.a=new $p}function Kv(){this.a=new $p}function _v(){this.a=new $p}function Fv(){this.a=new kn}function Bv(){this.a=new m6}function Hv(){this.a=new bt}function qv(){this.a=new UT}function Gv(){this.a=new N0}function zv(){this.a=new iZ}function Uv(){this.a=new CR}function Xv(){this.a=new $p}function Wv(){this.a=new $p}function Vv(){this.a=new $p}function Qv(){this.a=new $p}function Jv(){this.d=new $p}function Yv(){this.a=new xv}function Zv(){this.a=new Lp}function nm(){this.b=new Lp}function tm(){this.b=new $p}function em(){this.e=new $p}function im(){this.d=new $p}function rm(){this.a=new cf}function cm(){$p.call(this)}function am(){Rv.call(this)}function um(){$R.call(this)}function om(){Wv.call(this)}function sm(){hm.call(this)}function hm(){xp.call(this)}function fm(){xp.call(this)}function lm(){fm.call(this)}function bm(){bJ.call(this)}function wm(){bJ.call(this)}function dm(){Um.call(this)}function gm(){Um.call(this)}function pm(){Um.call(this)}function vm(){Xm.call(this)}function mm(){VT.call(this)}function ym(){eo.call(this)}function km(){eo.call(this)}function jm(){Ym.call(this)}function Em(){Ym.call(this)}function Tm(){Lp.call(this)}function Mm(){Lp.call(this)}function Sm(){Lp.call(this)}function Pm(){xv.call(this)}function Im(){yin.call(this)}function Cm(){kv.call(this)}function Om(){IL.call(this)}function Am(){IL.call(this)}function $m(){Lp.call(this)}function Lm(){Lp.call(this)}function Nm(){Lp.call(this)}function xm(){yo.call(this)}function Dm(){yo.call(this)}function Rm(){xm.call(this)}function Km(){Dh.call(this)}function _m(n){btn.call(this,n)}function Fm(n){btn.call(this,n)}function Bm(n){Wf.call(this,n)}function Hm(n){ET.call(this,n)}function qm(n){Hm.call(this,n)}function Gm(n){ET.call(this,n)}function zm(){this.a=new VT}function Um(){this.a=new xv}function Xm(){this.a=new Lp}function Wm(){this.a=new $p}function Vm(){this.j=new $p}function Qm(){this.a=new Xa}function Jm(){this.a=new AE}function Ym(){this.a=new mo}function Zm(){Zm=O,Rnt=new Lk}function ny(){ny=O,Dnt=new $k}function ty(){ty=O,Int=new c}function ey(){ey=O,qnt=new iN}function iy(n){Hm.call(this,n)}function ry(n){Hm.call(this,n)}function cy(n){b4.call(this,n)}function ay(n){b4.call(this,n)}function uy(n){XK.call(this,n)}function oy(n){vSn.call(this,n)}function sy(n){ST.call(this,n)}function hy(n){IT.call(this,n)}function fy(n){IT.call(this,n)}function ly(n){IT.call(this,n)}function by(n){sz.call(this,n)}function wy(n){by.call(this,n)}function dy(){Ml.call(this,{})}function gy(n){SL(),this.a=n}function py(n){n.b=null,n.c=0}function vy(n,t){n.e=t,Sxn(n,t)}function my(n,t){n.a=t,rIn(n)}function yy(n,t,e){n.a[t.g]=e}function ky(n,t,e){ljn(e,n,t)}function jy(n,t){JR(t.i,n.n)}function Ey(n,t){usn(n).td(t)}function Ty(n,t){return n*n/t}function My(n,t){return n.g-t.g}function Sy(n){return new Tl(n)}function Py(n){return new HX(n)}function Iy(n){by.call(this,n)}function Cy(n){by.call(this,n)}function Oy(n){by.call(this,n)}function Ay(n){sz.call(this,n)}function $y(n){Rcn(),this.a=n}function Ly(n){r_(),this.a=n}function Ny(n){KG(),this.f=n}function xy(n){KG(),this.f=n}function Dy(n){by.call(this,n)}function Ry(n){by.call(this,n)}function Ky(n){by.call(this,n)}function _y(n){by.call(this,n)}function Fy(n){by.call(this,n)}function By(n){return mW(n),n}function Hy(n){return mW(n),n}function qy(n){return mW(n),n}function Gy(n){return mW(n),n}function zy(n){return mW(n),n}function Uy(n){return n.b==n.c}function Xy(n){return!!n&&n.b}function Wy(n){return!!n&&n.k}function Vy(n){return!!n&&n.j}function Qy(n){mW(n),this.a=n}function Jy(n){return Jon(n),n}function Yy(n){gU(n,n.length)}function Zy(n){by.call(this,n)}function nk(n){by.call(this,n)}function tk(n){by.call(this,n)}function ek(n){by.call(this,n)}function ik(n){by.call(this,n)}function rk(n){by.call(this,n)}function ck(n){JN.call(this,n,0)}function ak(){a1.call(this,12,3)}function uk(){uk=O,Znt=new j}function ok(){ok=O,Vnt=new r}function sk(){sk=O,ett=new g}function hk(){hk=O,ott=new v}function fk(){throw Fp(new dv)}function lk(){throw Fp(new dv)}function bk(){throw Fp(new dv)}function wk(){throw Fp(new dv)}function dk(){throw Fp(new dv)}function gk(){throw Fp(new dv)}function pk(){this.a=TD(vX(KWn))}function vk(n){u_(),this.a=vX(n)}function mk(n,t){n.Td(t),t.Sd(n)}function yk(n,t){n.a.ec().Mc(t)}function kk(n,t,e){n.c.lf(t,e)}function jk(n){Cy.call(this,n)}function Ek(n){Ry.call(this,n)}function Tk(){Cb.call(this,"")}function Mk(){Cb.call(this,"")}function Sk(){Cb.call(this,"")}function Pk(){Cb.call(this,"")}function Ik(n){Cy.call(this,n)}function Ck(n){Fb.call(this,n)}function Ok(n){fN.call(this,n)}function Ak(n){Ck.call(this,n)}function $k(){Zf.call(this,null)}function Lk(){Zf.call(this,null)}function Nk(){Nk=O,MJ()}function xk(){xk=O,met=pEn()}function Dk(n){return n.a?n.b:0}function Rk(n){return n.a?n.b:0}function Kk(n,t){return n.a-t.a}function _k(n,t){return n.a-t.a}function Fk(n,t){return n.a-t.a}function Bk(n,t){return p7(n,t)}function Hk(n,t){return wZ(n,t)}function qk(n,t){return t in n.a}function Gk(n,t){return n.f=t,n}function zk(n,t){return n.b=t,n}function Uk(n,t){return n.c=t,n}function Xk(n,t){return n.g=t,n}function Wk(n,t){return n.a=t,n}function Vk(n,t){return n.f=t,n}function Qk(n,t){return n.k=t,n}function Jk(n,t){return n.a=t,n}function Yk(n,t){return n.e=t,n}function Zk(n,t){return n.e=t,n}function nj(n,t){return n.f=t,n}function tj(n,t){n.b=!0,n.d=t}function ej(n,t){n.b=new lA(t)}function ij(n,t,e){t.td(n.a[e])}function rj(n,t,e){t.we(n.a[e])}function cj(n,t){return n.b-t.b}function aj(n,t){return n.g-t.g}function uj(n,t){return n.s-t.s}function oj(n,t){return n?0:t-1}function sj(n,t){return n?0:t-1}function hj(n,t){return n?t-1:0}function fj(n,t){return t.Yf(n)}function lj(n,t){return n.b=t,n}function bj(n,t){return n.a=t,n}function wj(n,t){return n.c=t,n}function dj(n,t){return n.d=t,n}function gj(n,t){return n.e=t,n}function pj(n,t){return n.f=t,n}function vj(n,t){return n.a=t,n}function mj(n,t){return n.b=t,n}function yj(n,t){return n.c=t,n}function kj(n,t){return n.c=t,n}function jj(n,t){return n.b=t,n}function Ej(n,t){return n.d=t,n}function Tj(n,t){return n.e=t,n}function Mj(n,t){return n.f=t,n}function Sj(n,t){return n.g=t,n}function Pj(n,t){return n.a=t,n}function Ij(n,t){return n.i=t,n}function Cj(n,t){return n.j=t,n}function Oj(n,t){return n.k=t,n}function Aj(n,t){return n.j=t,n}function $j(n,t){RMn(),SZ(t,n)}function Lj(n,t,e){HG(n.a,t,e)}function Nj(n){_V.call(this,n)}function xj(n){_V.call(this,n)}function Dj(n){YK.call(this,n)}function Rj(n){Bbn.call(this,n)}function Kj(n){wtn.call(this,n)}function _j(n){dQ.call(this,n)}function Fj(n){dQ.call(this,n)}function Bj(){I$.call(this,"")}function Hj(){this.a=0,this.b=0}function qj(){this.b=0,this.a=0}function Gj(n,t){n.b=0,$en(n,t)}function zj(n,t){n.c=t,n.b=!0}function Uj(n,t){return n.c._b(t)}function Xj(n){return n.e&&n.e()}function Wj(n){return n?n.d:null}function Vj(n,t){return wfn(n.b,t)}function Qj(n){return n?n.g:null}function Jj(n){return n?n.i:null}function Yj(n){return kD(n),n.o}function Zj(){Zj=O,bOt=zkn()}function nE(){nE=O,wOt=aTn()}function tE(){tE=O,JAt=Xkn()}function eE(){eE=O,lLt=Ukn()}function iE(){iE=O,bLt=tIn()}function rE(){rE=O,sAt=iin()}function cE(){throw Fp(new dv)}function aE(){throw Fp(new dv)}function uE(){throw Fp(new dv)}function oE(){throw Fp(new dv)}function sE(){throw Fp(new dv)}function hE(){throw Fp(new dv)}function fE(n){this.a=new zT(n)}function lE(n){hUn(),NXn(this,n)}function bE(n){this.a=new Uz(n)}function wE(n,t){for(;n.ye(t););}function dE(n,t){for(;n.sd(t););}function gE(n,t){return n.a+=t,n}function pE(n,t){return n.a+=t,n}function vE(n,t){return n.a+=t,n}function mE(n,t){return n.a+=t,n}function yE(n){return kW(n),n.a}function kE(n){return n.b!=n.d.c}function jE(n){return n.l|n.m<<22}function EE(n,t){return n.d[t.p]}function TE(n,t){return Txn(n,t)}function ME(n,t,e){n.splice(t,e)}function SE(n){n.c?$Dn(n):LDn(n)}function PE(n){this.a=0,this.b=n}function IE(){this.a=new SNn(tjt)}function CE(){this.b=new SNn(Byt)}function OE(){this.b=new SNn(UEt)}function AE(){this.b=new SNn(UEt)}function $E(){throw Fp(new dv)}function LE(){throw Fp(new dv)}function NE(){throw Fp(new dv)}function xE(){throw Fp(new dv)}function DE(){throw Fp(new dv)}function RE(){throw Fp(new dv)}function KE(){throw Fp(new dv)}function _E(){throw Fp(new dv)}function FE(){throw Fp(new dv)}function BE(){throw Fp(new dv)}function HE(){throw Fp(new vv)}function qE(){throw Fp(new vv)}function GE(n){this.a=new zE(n)}function zE(n){Hin(this,n,IEn())}function UE(n){return!n||dW(n)}function XE(n){return-1!=zLt[n]}function WE(){0!=itt&&(itt=0),ctt=-1}function VE(){null==MWn&&(MWn=[])}function QE(n,t){ZOn(WQ(n.a),t)}function JE(n,t){ZOn(WQ(n.a),t)}function YE(n,t){FL.call(this,n,t)}function ZE(n,t){YE.call(this,n,t)}function nT(n,t){this.b=n,this.c=t}function tT(n,t){this.b=n,this.a=t}function eT(n,t){this.a=n,this.b=t}function iT(n,t){this.a=n,this.b=t}function rT(n,t){this.a=n,this.b=t}function cT(n,t){this.a=n,this.b=t}function aT(n,t){this.a=n,this.b=t}function uT(n,t){this.a=n,this.b=t}function oT(n,t){this.a=n,this.b=t}function sT(n,t){this.a=n,this.b=t}function hT(n,t){this.b=n,this.a=t}function fT(n,t){this.b=n,this.a=t}function lT(n,t){this.b=n,this.a=t}function bT(n,t){this.b=n,this.a=t}function wT(n,t){this.f=n,this.g=t}function dT(n,t){this.e=n,this.d=t}function gT(n,t){this.g=n,this.i=t}function pT(n,t){this.a=n,this.b=t}function vT(n,t){this.a=n,this.f=t}function mT(n,t){this.b=n,this.c=t}function yT(n,t){this.a=n,this.b=t}function kT(n,t){this.a=n,this.b=t}function jT(n,t){this.a=n,this.b=t}function ET(n){rN(n.dc()),this.c=n}function TT(n){this.b=_B(vX(n),83)}function MT(n){this.a=_B(vX(n),83)}function ST(n){this.a=_B(vX(n),15)}function PT(n){this.a=_B(vX(n),15)}function IT(n){this.b=_B(vX(n),47)}function CT(){this.q=new i.Date}function OT(){OT=O,_tt=new A}function AT(){AT=O,het=new P}function $T(n){return n.f.c+n.g.c}function LT(n,t){return n.b.Hc(t)}function NT(n,t){return n.b.Ic(t)}function xT(n,t){return n.b.Qc(t)}function DT(n,t){return n.b.Hc(t)}function RT(n,t){return n.c.uc(t)}function KT(n,t){return n.a._b(t)}function _T(n,t){return $fn(n.c,t)}function FT(n,t){return oU(n.b,t)}function BT(n,t){return n>t&&t0}function uS(n,t){return Xhn(n,t)<0}function oS(n,t){return n.a.get(t)}function sS(n,t){return t.split(n)}function hS(n,t){return oU(n.e,t)}function fS(n){return mW(n),!1}function lS(n){l1.call(this,n,21)}function bS(n,t){RY.call(this,n,t)}function wS(n,t){wT.call(this,n,t)}function dS(n,t){wT.call(this,n,t)}function gS(n){XX(),XK.call(this,n)}function pS(n,t){yG(n,n.length,t)}function vS(n,t){WU(n,n.length,t)}function mS(n,t,e){t.ud(n.a.Ge(e))}function yS(n,t,e){t.we(n.a.Fe(e))}function kS(n,t,e){t.td(n.a.Kb(e))}function jS(n,t,e){n.Mb(e)&&t.td(e)}function ES(n,t,e){n.splice(t,0,e)}function TS(n,t){return TN(n.e,t)}function MS(n,t){this.d=n,this.e=t}function SS(n,t){this.b=n,this.a=t}function PS(n,t){this.b=n,this.a=t}function IS(n,t){this.b=n,this.a=t}function CS(n,t){this.a=n,this.b=t}function OS(n,t){this.a=n,this.b=t}function AS(n,t){this.a=n,this.b=t}function $S(n,t){this.a=n,this.b=t}function LS(n,t){this.a=n,this.b=t}function NS(n,t){this.b=n,this.a=t}function xS(n,t){this.b=n,this.a=t}function DS(n,t){wT.call(this,n,t)}function RS(n,t){wT.call(this,n,t)}function KS(n,t){wT.call(this,n,t)}function _S(n,t){wT.call(this,n,t)}function FS(n,t){wT.call(this,n,t)}function BS(n,t){wT.call(this,n,t)}function HS(n,t){wT.call(this,n,t)}function qS(n,t){wT.call(this,n,t)}function GS(n,t){wT.call(this,n,t)}function zS(n,t){wT.call(this,n,t)}function US(n,t){wT.call(this,n,t)}function XS(n,t){wT.call(this,n,t)}function WS(n,t){wT.call(this,n,t)}function VS(n,t){wT.call(this,n,t)}function QS(n,t){wT.call(this,n,t)}function JS(n,t){wT.call(this,n,t)}function YS(n,t){wT.call(this,n,t)}function ZS(n,t){wT.call(this,n,t)}function nP(n,t){this.a=n,this.b=t}function tP(n,t){this.a=n,this.b=t}function eP(n,t){this.a=n,this.b=t}function iP(n,t){this.a=n,this.b=t}function rP(n,t){this.a=n,this.b=t}function cP(n,t){this.a=n,this.b=t}function aP(n,t){this.a=n,this.b=t}function uP(n,t){this.a=n,this.b=t}function oP(n,t){this.a=n,this.b=t}function sP(n,t){this.b=n,this.a=t}function hP(n,t){this.b=n,this.a=t}function fP(n,t){this.b=n,this.a=t}function lP(n,t){this.b=n,this.a=t}function bP(n,t){this.c=n,this.d=t}function wP(n,t){this.e=n,this.d=t}function dP(n,t){this.a=n,this.b=t}function gP(n,t){this.b=t,this.c=n}function pP(n,t){wT.call(this,n,t)}function vP(n,t){wT.call(this,n,t)}function mP(n,t){wT.call(this,n,t)}function yP(n,t){wT.call(this,n,t)}function kP(n,t){wT.call(this,n,t)}function jP(n,t){wT.call(this,n,t)}function EP(n,t){wT.call(this,n,t)}function TP(n,t){wT.call(this,n,t)}function MP(n,t){wT.call(this,n,t)}function SP(n,t){wT.call(this,n,t)}function PP(n,t){wT.call(this,n,t)}function IP(n,t){wT.call(this,n,t)}function CP(n,t){wT.call(this,n,t)}function OP(n,t){wT.call(this,n,t)}function AP(n,t){wT.call(this,n,t)}function $P(n,t){wT.call(this,n,t)}function LP(n,t){wT.call(this,n,t)}function NP(n,t){wT.call(this,n,t)}function xP(n,t){wT.call(this,n,t)}function DP(n,t){wT.call(this,n,t)}function RP(n,t){wT.call(this,n,t)}function KP(n,t){wT.call(this,n,t)}function _P(n,t){wT.call(this,n,t)}function FP(n,t){wT.call(this,n,t)}function BP(n,t){wT.call(this,n,t)}function HP(n,t){wT.call(this,n,t)}function qP(n,t){wT.call(this,n,t)}function GP(n,t){wT.call(this,n,t)}function zP(n,t){wT.call(this,n,t)}function UP(n,t){wT.call(this,n,t)}function XP(n,t){wT.call(this,n,t)}function WP(n,t){wT.call(this,n,t)}function VP(n,t){wT.call(this,n,t)}function QP(n,t){wT.call(this,n,t)}function JP(n,t){this.b=n,this.a=t}function YP(n,t){this.a=n,this.b=t}function ZP(n,t){this.a=n,this.b=t}function nI(n,t){this.a=n,this.b=t}function tI(n,t){this.a=n,this.b=t}function eI(n,t){wT.call(this,n,t)}function iI(n,t){wT.call(this,n,t)}function rI(n,t){this.b=n,this.d=t}function cI(n,t){wT.call(this,n,t)}function aI(n,t){wT.call(this,n,t)}function uI(n,t){this.a=n,this.b=t}function oI(n,t){this.a=n,this.b=t}function sI(n,t){wT.call(this,n,t)}function hI(n,t){wT.call(this,n,t)}function fI(n,t){wT.call(this,n,t)}function lI(n,t){wT.call(this,n,t)}function bI(n,t){wT.call(this,n,t)}function wI(n,t){wT.call(this,n,t)}function dI(n,t){wT.call(this,n,t)}function gI(n,t){wT.call(this,n,t)}function pI(n,t){wT.call(this,n,t)}function vI(n,t){wT.call(this,n,t)}function mI(n,t){wT.call(this,n,t)}function yI(n,t){wT.call(this,n,t)}function kI(n,t){wT.call(this,n,t)}function jI(n,t){wT.call(this,n,t)}function EI(n,t){wT.call(this,n,t)}function TI(n,t){wT.call(this,n,t)}function MI(n,t){return TN(n.c,t)}function SI(n,t){return TN(t.b,n)}function PI(n,t){return-n.b.Je(t)}function II(n,t){return TN(n.g,t)}function CI(n,t){wT.call(this,n,t)}function OI(n,t){wT.call(this,n,t)}function AI(n,t){this.a=n,this.b=t}function $I(n,t){this.a=n,this.b=t}function LI(n,t){this.a=n,this.b=t}function NI(n,t){wT.call(this,n,t)}function xI(n,t){wT.call(this,n,t)}function DI(n,t){wT.call(this,n,t)}function RI(n,t){wT.call(this,n,t)}function KI(n,t){wT.call(this,n,t)}function _I(n,t){wT.call(this,n,t)}function FI(n,t){wT.call(this,n,t)}function BI(n,t){wT.call(this,n,t)}function HI(n,t){wT.call(this,n,t)}function qI(n,t){wT.call(this,n,t)}function GI(n,t){wT.call(this,n,t)}function zI(n,t){wT.call(this,n,t)}function UI(n,t){wT.call(this,n,t)}function XI(n,t){wT.call(this,n,t)}function WI(n,t){wT.call(this,n,t)}function VI(n,t){wT.call(this,n,t)}function QI(n,t){this.a=n,this.b=t}function JI(n,t){this.a=n,this.b=t}function YI(n,t){this.a=n,this.b=t}function ZI(n,t){this.a=n,this.b=t}function nC(n,t){this.a=n,this.b=t}function tC(n,t){this.a=n,this.b=t}function eC(n,t){this.a=n,this.b=t}function iC(n,t){wT.call(this,n,t)}function rC(n,t){this.a=n,this.b=t}function cC(n,t){this.a=n,this.b=t}function aC(n,t){this.a=n,this.b=t}function uC(n,t){this.a=n,this.b=t}function oC(n,t){this.a=n,this.b=t}function sC(n,t){this.a=n,this.b=t}function hC(n,t){this.b=n,this.a=t}function fC(n,t){this.b=n,this.a=t}function lC(n,t){this.b=n,this.a=t}function bC(n,t){this.b=n,this.a=t}function wC(n,t){this.a=n,this.b=t}function dC(n,t){this.a=n,this.b=t}function gC(n,t){QLn(n.a,_B(t,56))}function pC(n,t){g7(n.a,_B(t,11))}function vC(n,t){return oH(),t!=n}function mC(){return xk(),new met}function yC(){BZ(),this.b=new xv}function kC(){bxn(),this.a=new xv}function jC(){DZ(),DG.call(this)}function EC(n,t){wT.call(this,n,t)}function TC(n,t){this.a=n,this.b=t}function MC(n,t){this.a=n,this.b=t}function SC(n,t){this.a=n,this.b=t}function PC(n,t){this.a=n,this.b=t}function IC(n,t){this.a=n,this.b=t}function CC(n,t){this.a=n,this.b=t}function OC(n,t){this.d=n,this.b=t}function AC(n,t){this.d=n,this.e=t}function $C(n,t){this.f=n,this.c=t}function LC(n,t){this.b=n,this.c=t}function NC(n,t){this.i=n,this.g=t}function xC(n,t){this.e=n,this.a=t}function DC(n,t){this.a=n,this.b=t}function RC(n,t){n.i=null,rrn(n,t)}function KC(n,t){n&&XW(cAt,n,t)}function _C(n,t){return edn(n.a,t)}function FC(n){return rdn(n.c,n.b)}function BC(n){return n?n.dd():null}function HC(n){return null==n?null:n}function qC(n){return typeof n===OWn}function GC(n){return typeof n===AWn}function zC(n){return typeof n===$Wn}function UC(n,t){return n.Hd().Xb(t)}function XC(n,t){return Wcn(n.Kc(),t)}function WC(n,t){return 0==Xhn(n,t)}function VC(n,t){return Xhn(n,t)>=0}function QC(n,t){return 0!=Xhn(n,t)}function JC(n){return""+(mW(n),n)}function YC(n,t){return n.substr(t)}function ZC(n){return qbn(n),n.d.gc()}function nO(n){return qOn(n,n.c),n}function tO(n){return QH(null==n),n}function eO(n,t){return n.a+=""+t,n}function iO(n,t){return n.a+=""+t,n}function rO(n,t){return n.a+=""+t,n}function cO(n,t){return n.a+=""+t,n}function aO(n,t){return n.a+=""+t,n}function uO(n,t){return n.a+=""+t,n}function oO(n,t){e5(n,t,n.a,n.a.a)}function sO(n,t){e5(n,t,n.c.b,n.c)}function hO(n,t,e){Djn(t,xPn(n,e))}function fO(n,t,e){Djn(t,xPn(n,e))}function lO(n,t){jnn(new CL(n),t)}function bO(n,t){n.q.setTime(y2(t))}function wO(n,t){qz.call(this,n,t)}function dO(n,t){qz.call(this,n,t)}function gO(n,t){qz.call(this,n,t)}function pO(n){OU(this),jcn(this,n)}function vO(n){return h1(n,0),null}function mO(n){return n.a=0,n.b=0,n}function yO(n,t){return n.a=t.g+1,n}function kO(n,t){return 2==n.j[t.p]}function jO(n){return uX(_B(n,79))}function EO(){EO=O,Crt=hhn(Zgn())}function TO(){TO=O,Jot=hhn(kNn())}function MO(){this.b=new zT(ntn(12))}function SO(){this.b=0,this.a=!1}function PO(){this.b=0,this.a=!1}function IO(n){this.a=n,_h.call(this)}function CO(n){this.a=n,_h.call(this)}function OO(n,t){tR.call(this,n,t)}function AO(n,t){ZR.call(this,n,t)}function $O(n,t){NC.call(this,n,t)}function LO(n,t){Can.call(this,n,t)}function NO(n,t){WN.call(this,n,t)}function xO(n,t){YM(),XW(gAt,n,t)}function DO(n,t){return sx(n.a,0,t)}function RO(n,t){return n.a.a.a.cc(t)}function KO(n,t){return HC(n)===HC(t)}function _O(n,t){return Mln(n.a,t.a)}function FO(n,t){return k$(n.a,t.a)}function BO(n,t){return KU(n.a,t.a)}function HO(n,t){return n.indexOf(t)}function qO(n,t){return n==t?0:n?1:-1}function GO(n){return n<10?"0"+n:""+n}function zO(n){return vX(n),new IO(n)}function UO(n){return E$(n.l,n.m,n.h)}function XO(n){return SY((mW(n),n))}function WO(n){return SY((mW(n),n))}function VO(n,t){return k$(n.g,t.g)}function QO(n){return typeof n===AWn}function JO(n){return n==Jat||n==nut}function YO(n){return n==Jat||n==Yat}function ZO(n){return k7(n.b.b,n,0)}function nA(n){this.a=mC(),this.b=n}function tA(n){this.a=mC(),this.b=n}function eA(n,t){return UB(n.a,t),t}function iA(n,t){return UB(n.c,t),n}function rA(n,t){return Qcn(n.a,t),n}function cA(n,t){return H_(),t.a+=n}function aA(n,t){return H_(),t.a+=n}function uA(n,t){return H_(),t.c+=n}function oA(n,t){q9(n,0,n.length,t)}function sA(){nw.call(this,new g4)}function hA(){cG.call(this,0,0,0,0)}function fA(){GV.call(this,0,0,0,0)}function lA(n){this.a=n.a,this.b=n.b}function bA(n){return n==RPt||n==KPt}function wA(n){return n==FPt||n==DPt}function dA(n){return n==svt||n==ovt}function gA(n){return n!=WIt&&n!=VIt}function pA(n){return n.Lg()&&n.Mg()}function vA(n){return pV(_B(n,118))}function mA(n){return Qcn(new _2,n)}function yA(n,t){return new Can(t,n)}function kA(n,t){return new Can(t,n)}function jA(n,t,e){yen(n,t),ken(n,e)}function EA(n,t,e){Ten(n,t),Een(n,e)}function TA(n,t,e){Men(n,t),Sen(n,e)}function MA(n,t,e){jen(n,t),Ien(n,e)}function SA(n,t,e){Pen(n,t),Cen(n,e)}function PA(n,t){Nsn(n,t),Len(n,n.D)}function IA(n){$C.call(this,n,!0)}function CA(n,t,e){$D.call(this,n,t,e)}function OA(n){IDn(),uan.call(this,n)}function AA(){wS.call(this,"Head",1)}function $A(){wS.call(this,"Tail",3)}function LA(n){n.c=L8(Cnt,FWn,1,0,5,1)}function NA(n){n.a=L8(Cnt,FWn,1,8,5,1)}function xA(n){Itn(n.xf(),new Tw(n))}function DA(n){return null!=n?Yon(n):0}function RA(n,t){return Stn(t,UY(n))}function KA(n,t){return Stn(t,UY(n))}function _A(n,t){return n[n.length]=t}function FA(n,t){return n[n.length]=t}function BA(n){return KB(n.b.Kc(),n.a)}function HA(n,t){return Gin(MX(n.d),t)}function qA(n,t){return Gin(MX(n.g),t)}function GA(n,t){return Gin(MX(n.j),t)}function zA(n,t){tR.call(this,n.b,t)}function UA(n){cG.call(this,n,n,n,n)}function XA(n){return n.b&&XBn(n),n.a}function WA(n){return n.b&&XBn(n),n.c}function VA(n,t){Wet||(n.b=t)}function QA(n,t,e){return OX(n,t,e),e}function JA(n,t,e){OX(n.c[t.g],t.g,e)}function YA(n,t,e){_B(n.c,69).Xh(t,e)}function ZA(n,t,e){TA(e,e.i+n,e.j+t)}function n$(n,t){s9(r4(n.a),n1(t))}function t$(n,t){s9(F7(n.a),t1(t))}function e$(n){lWn(),Cp.call(this,n)}function i$(n){return null==n?0:Yon(n)}function r$(){r$=O,uyt=new Fbn(aIt)}function c$(){c$=O,new a$,new $p}function a$(){new Lp,new Lp,new Lp}function u$(){u$=O,Ev(),ttt=new Lp}function o$(){o$=O,i.Math.log(2)}function s$(){s$=O,qM(),N$t=SOt}function h$(){throw Fp(new Zy(jnt))}function f$(){throw Fp(new Zy(jnt))}function l$(){throw Fp(new Zy(Ent))}function b$(){throw Fp(new Zy(Ent))}function w$(n){this.a=n,WB.call(this,n)}function d$(n){this.a=n,TT.call(this,n)}function g$(n){this.a=n,TT.call(this,n)}function p$(n,t){vG(n.c,n.c.length,t)}function v$(n){return n.at?1:0}function j$(n,t){return Xhn(n,t)>0?n:t}function E$(n,t,e){return{l:n,m:t,h:e}}function T$(n,t){null!=n.a&&pC(t,n.a)}function M$(n){n.a=new $,n.c=new $}function S$(n){this.b=n,this.a=new $p}function P$(n){this.b=new et,this.a=n}function I$(n){AR.call(this),this.a=n}function C$(){wS.call(this,"Range",2)}function O$(){Zkn(),this.a=new SNn(Gat)}function A$(n,t){vX(t),kV(n).Jc(new b)}function $$(n,t){return _Z(),t.n.b+=n}function L$(n,t,e){return XW(n.g,e,t)}function N$(n,t,e){return XW(n.k,e,t)}function x$(n,t){return XW(n.a,t.a,t)}function D$(n,t,e){return Pdn(t,e,n.c)}function R$(n){return new LI(n.c,n.d)}function K$(n){return new LI(n.c,n.d)}function _$(n){return new LI(n.a,n.b)}function F$(n,t){return ZGn(n.a,t,null)}function B$(n){TZ(n,null),EZ(n,null)}function H$(n){UZ(n,null),XZ(n,null)}function q$(){WN.call(this,null,null)}function G$(){VN.call(this,null,null)}function z$(n){this.a=n,Lp.call(this)}function U$(n){this.b=(TQ(),new zb(n))}function X$(n){n.j=L8(Ktt,uVn,310,0,0,1)}function W$(n,t,e){n.c.Vc(t,_B(e,133))}function V$(n,t,e){n.c.ji(t,_B(e,133))}function Q$(n,t){uqn(n),n.Gc(_B(t,15))}function J$(n,t){return _qn(n.c,n.b,t)}function Y$(n,t){return new dN(n.Kc(),t)}function Z$(n,t){return-1!=Kun(n.Kc(),t)}function nL(n,t){return null!=n.a.Bc(t)}function tL(n){return n.Ob()?n.Pb():null}function eL(n){return _dn(n,0,n.length)}function iL(n,t){return null!=n&&Wpn(n,t)}function rL(n,t){n.q.setHours(t),hBn(n,t)}function cL(n,t){n.c&&(xH(t),mY(t))}function aL(n,t,e){_B(n.Kb(e),164).Nb(t)}function uL(n,t,e){return FGn(n,t,e),e}function oL(n,t,e){n.a=1502^t,n.b=e^rJn}function sL(n,t,e){return n.a[t.g][e.g]}function hL(n,t){return n.a[t.c.p][t.p]}function fL(n,t){return n.e[t.c.p][t.p]}function lL(n,t){return n.c[t.c.p][t.p]}function bL(n,t){return n.j[t.p]=dLn(t)}function wL(n,t){return s6(n.f,t.tg())}function dL(n,t){return s6(n.b,t.tg())}function gL(n,t){return n.a0?t*t/n:t*t*100}function Lx(n,t){return n>0?t/(n*n):100*t}function Nx(n,t,e){return UB(t,awn(n,e))}function xx(n,t,e){L9(),n.Xe(t)&&e.td(n)}function Dx(n,t,e){n.Zc(t).Rb(e)}function Rx(n,t,e){return n.a+=t,n.b+=e,n}function Kx(n,t,e){return n.a*=t,n.b*=e,n}function _x(n,t,e){return n.a-=t,n.b-=e,n}function Fx(n,t){return n.a=t.a,n.b=t.b,n}function Bx(n){return n.a=-n.a,n.b=-n.b,n}function Hx(n){this.c=n,this.a=1,this.b=1}function qx(n){this.c=n,Men(n,0),Sen(n,0)}function Gx(n){VT.call(this),Yen(this,n)}function zx(n){xXn(),_p(this),this.mf(n)}function Ux(n,t){WM(),WN.call(this,n,t)}function Xx(n,t){VM(),VN.call(this,n,t)}function Wx(n,t){VM(),VN.call(this,n,t)}function Vx(n,t){VM(),Xx.call(this,n,t)}function Qx(n,t,e){v9.call(this,n,t,e,2)}function Jx(n,t){s$(),iG.call(this,n,t)}function Yx(n,t){s$(),Jx.call(this,n,t)}function Zx(n,t){s$(),Jx.call(this,n,t)}function nD(n,t){s$(),Zx.call(this,n,t)}function tD(n,t){s$(),iG.call(this,n,t)}function eD(n,t){s$(),tD.call(this,n,t)}function iD(n,t){s$(),iG.call(this,n,t)}function rD(n,t){return n.c.Fc(_B(t,133))}function cD(n,t,e){return $Hn(K7(n,t),e)}function aD(n,t,e){return t.Qk(n.e,n.c,e)}function uD(n,t,e){return t.Rk(n.e,n.c,e)}function oD(n,t){return Zhn(n.e,_B(t,49))}function sD(n,t,e){uln(F7(n.a),t,t1(e))}function hD(n,t,e){uln(r4(n.a),t,n1(e))}function fD(n,t){t.$modCount=n.$modCount}function lD(){lD=O,Xkt=new cp("root")}function bD(){bD=O,wAt=new jm,new Em}function wD(){this.a=new dY,this.b=new dY}function dD(){yin.call(this),this.Bb|=_Qn}function gD(){wT.call(this,"GROW_TREE",0)}function pD(n){return null==n?null:lUn(n)}function vD(n){return null==n?null:ASn(n)}function mD(n){return null==n?null:_bn(n)}function yD(n){return null==n?null:_bn(n)}function kD(n){null==n.o&&w$n(n)}function jD(n){return QH(null==n||qC(n)),n}function ED(n){return QH(null==n||GC(n)),n}function TD(n){return QH(null==n||zC(n)),n}function MD(n){this.q=new i.Date(y2(n))}function SD(n,t){this.c=n,dT.call(this,n,t)}function PD(n,t){this.a=n,SD.call(this,n,t)}function ID(n,t){this.d=n,Eb(this),this.b=t}function CD(n,t){_8.call(this,n),this.a=t}function OD(n,t){_8.call(this,n),this.a=t}function AD(n){Bwn.call(this,0,0),this.f=n}function $D(n,t,e){U6.call(this,n,t,e,null)}function LD(n,t,e){U6.call(this,n,t,e,null)}function ND(n,t,e){return n.ue(t,e)<=0?e:t}function xD(n,t,e){return n.ue(t,e)<=0?t:e}function DD(n,t){return _B(hnn(n.b,t),149)}function RD(n,t){return _B(hnn(n.c,t),229)}function KD(n){return _B(Lq(n.a,n.b),287)}function _D(n){return new LI(n.c,n.d+n.a)}function FD(n){return _Z(),dA(_B(n,197))}function BD(){BD=O,Ort=Yln((pdn(),RCt))}function HD(n,t){t.a?Kxn(n,t):EN(n.a,t.b)}function qD(n,t){Wet||UB(n.a,t)}function GD(n,t){return pM(),lan(t.d.i,n)}function zD(n,t){return Prn(),new iKn(t,n)}function UD(n,t){return IJ(t,cYn),n.f=t,n}function XD(n,t,e){return e=j_n(n,t,3,e)}function WD(n,t,e){return e=j_n(n,t,6,e)}function VD(n,t,e){return e=j_n(n,t,9,e)}function QD(n,t,e){++n.j,n.Ki(),A8(n,t,e)}function JD(n,t,e){++n.j,n.Hi(t,n.oi(t,e))}function YD(n,t,e){n.Zc(t).Rb(e)}function ZD(n,t,e){return JBn(n.c,n.b,t,e)}function nR(n,t){return(t&NWn)%n.d.length}function tR(n,t){cp.call(this,n),this.a=t}function eR(n,t){mp.call(this,n),this.a=t}function iR(n,t){mp.call(this,n),this.a=t}function rR(n,t){this.c=n,wtn.call(this,t)}function cR(n,t){this.a=n,vp.call(this,t)}function aR(n,t){this.a=n,vp.call(this,t)}function uR(n){this.a=(hin(n,CVn),new Q6(n))}function oR(n){this.a=(hin(n,CVn),new Q6(n))}function sR(n){return!n.a&&(n.a=new w),n.a}function hR(n){return n>8?0:n+1}function fR(n,t){return oN(),n==t?0:n?1:-1}function lR(n,t,e){return pG(n,_B(t,22),e)}function bR(n,t,e){return n.apply(t,e)}function wR(n,t,e){return n.a+=_dn(t,0,e),n}function dR(n,t){var e;return e=n.e,n.e=t,e}function gR(n,t){n[tJn].call(n,t)}function pR(n,t){n[tJn].call(n,t)}function vR(n,t){n.a.Vc(n.b,t),++n.b,n.c=-1}function mR(n){OU(n.e),n.d.b=n.d,n.d.a=n.d}function yR(n){n.b?yR(n.b):n.f.c.zc(n.e,n.d)}function kR(n,t,e){bM(),Pl(n,t.Ce(n.a,e))}function jR(n,t){return Wj(Edn(n.a,t,!0))}function ER(n,t){return Wj(Tdn(n.a,t,!0))}function TR(n,t){return Bk(new Array(t),n)}function MR(n){return String.fromCharCode(n)}function SR(n){return null==n?null:n.message}function PR(){this.a=new $p,this.b=new $p}function IR(){this.a=new bt,this.b=new jv}function CR(){this.b=new Hj,this.c=new $p}function OR(){this.d=new Hj,this.e=new Hj}function AR(){this.n=new Hj,this.o=new Hj}function $R(){this.n=new fm,this.i=new fA}function LR(){this.a=new Yh,this.b=new uc}function NR(){this.a=new $p,this.d=new $p}function xR(){this.b=new xv,this.a=new xv}function DR(){this.b=new Lp,this.a=new Lp}function RR(){this.b=new CE,this.a=new da}function KR(){$R.call(this),this.a=new Hj}function _R(n){Ian.call(this,n,(J9(),$et))}function FR(n,t,e,i){cG.call(this,n,t,e,i)}function BR(n,t,e){null!=e&&Ain(t,Cmn(n,e))}function HR(n,t,e){null!=e&&$in(t,Cmn(n,e))}function qR(n,t,e){return e=j_n(n,t,11,e)}function GR(n,t){return n.a+=t.a,n.b+=t.b,n}function zR(n,t){return n.a-=t.a,n.b-=t.b,n}function UR(n,t){return n.n.a=(mW(t),t+10)}function XR(n,t){return n.n.a=(mW(t),t+10)}function WR(n,t){return t==n||Tjn(SLn(t),n)}function VR(n,t){return null==XW(n.a,t,"")}function QR(n,t){return pM(),!lan(t.d.i,n)}function JR(n,t){bA(n.f)?i$n(n,t):PTn(n,t)}function YR(n,t){return t.Hh(n.a)}function ZR(n,t){Cy.call(this,n9n+n+a8n+t)}function nK(n,t,e,i){nU.call(this,n,t,e,i)}function tK(n,t,e,i){nU.call(this,n,t,e,i)}function eK(n,t,e,i){tK.call(this,n,t,e,i)}function iK(n,t,e,i){tU.call(this,n,t,e,i)}function rK(n,t,e,i){tU.call(this,n,t,e,i)}function cK(n,t,e,i){tU.call(this,n,t,e,i)}function aK(n,t,e,i){rK.call(this,n,t,e,i)}function uK(n,t,e,i){rK.call(this,n,t,e,i)}function oK(n,t,e,i){cK.call(this,n,t,e,i)}function sK(n,t,e,i){uK.call(this,n,t,e,i)}function hK(n,t,e,i){Jz.call(this,n,t,e,i)}function fK(n,t,e){this.a=n,JN.call(this,t,e)}function lK(n,t,e){this.c=t,this.b=e,this.a=n}function bK(n,t,e){return n.d=_B(t.Kb(e),164)}function wK(n,t){return n.Aj().Nh().Kh(n,t)}function dK(n,t){return n.Aj().Nh().Ih(n,t)}function gK(n,t){return mW(n),HC(n)===HC(t)}function pK(n,t){return mW(n),HC(n)===HC(t)}function vK(n,t){return Wj(Edn(n.a,t,!1))}function mK(n,t){return Wj(Tdn(n.a,t,!1))}function yK(n,t){return n.b.sd(new OS(n,t))}function kK(n,t){return n.b.sd(new AS(n,t))}function jK(n,t){return n.b.sd(new $S(n,t))}function EK(n,t,e){return n.lastIndexOf(t,e)}function TK(n,t,e){return Mln(n[t.b],n[e.b])}function MK(n,t){return oon(t,(FXn(),xdt),n)}function SK(n,t){return k$(t.a.d.p,n.a.d.p)}function PK(n,t){return k$(n.a.d.p,t.a.d.p)}function IK(n,t){return Mln(n.c-n.s,t.c-t.s)}function CK(n){return n.c?k7(n.c.a,n,0):-1}function OK(n){return n<100?null:new Kj(n)}function AK(n){return n==GIt||n==UIt||n==zIt}function $K(n,t){return iL(t,15)&&WDn(n.c,t)}function LK(n,t){Wet||t&&(n.d=t)}function NK(n,t){return!!hsn(n,t)}function xK(n,t){this.c=n,HU.call(this,n,t)}function DK(n){this.c=n,gO.call(this,fVn,0)}function RK(n,t){QB.call(this,n,n.length,t)}function KK(n,t,e){return _B(n.c,69).lk(t,e)}function _K(n,t,e){return _B(n.c,69).mk(t,e)}function FK(n,t,e){return aD(n,_B(t,332),e)}function BK(n,t,e){return uD(n,_B(t,332),e)}function HK(n,t,e){return PEn(n,_B(t,332),e)}function qK(n,t,e){return WTn(n,_B(t,332),e)}function GK(n,t){return null==t?null:hfn(n.b,t)}function zK(n){return GC(n)?(mW(n),n):n.ke()}function UK(n){return!isNaN(n)&&!isFinite(n)}function XK(n){u_(),this.a=(TQ(),new Ck(n))}function WK(n){oH(),this.d=n,this.a=new Ap}function VK(n,t,e){this.a=n,this.b=t,this.c=e}function QK(n,t,e){this.a=n,this.b=t,this.c=e}function JK(n,t,e){this.d=n,this.b=e,this.a=t}function YK(n){M$(this),vQ(this),Krn(this,n)}function ZK(n){LA(this),ZB(this.c,0,n.Pc())}function n_(n){sW(n.a),q8(n.c,n.b),n.b=null}function t_(n){this.a=n,OT(),san(Date.now())}function e_(){e_=O,tit=new r,eit=new r}function i_(){i_=O,jet=new L,Eet=new N}function r_(){r_=O,fAt=L8(Cnt,FWn,1,0,5,1)}function c_(){c_=O,j$t=L8(Cnt,FWn,1,0,5,1)}function a_(){a_=O,E$t=L8(Cnt,FWn,1,0,5,1)}function u_(){u_=O,new ev((TQ(),TQ(),uet))}function o_(n){return J9(),Snn((Y9(),Ret),n)}function s_(n){return Bsn(),Snn((n8(),Jet),n)}function h_(n){return opn(),Snn((P4(),dit),n)}function f_(n){return xnn(),Snn((I4(),mit),n)}function l_(n){return ZDn(),Snn((Lan(),Kit),n)}function b_(n){return Ntn(),Snn((J6(),Uit),n)}function w_(n){return Q9(),Snn((Y6(),Zit),n)}function d_(n){return H7(),Snn((Z6(),crt),n)}function g_(n){return bWn(),Snn((EO(),Crt),n)}function p_(n){return Nan(),Snn((n7(),Rrt),n)}function v_(n){return Fpn(),Snn((t7(),qrt),n)}function m_(n){return Bpn(),Snn((e7(),tct),n)}function y_(n){return lM(),Snn((W2(),rct),n)}function k_(n){return Dnn(),Snn((C4(),Rct),n)}function j_(n){return B7(),Snn((t8(),Aat),n)}function E_(n){return vMn(),Snn((znn(),Bat),n)}function T_(n){return Cun(),Snn((Z9(),eut),n)}function M_(n){return _fn(),Snn((e8(),wut),n)}function S_(n,t){if(!n)throw Fp(new Ry(t))}function P_(n){return cSn(),Snn((oen(),Cut),n)}function I_(n){cG.call(this,n.d,n.c,n.a,n.b)}function C_(n){cG.call(this,n.d,n.c,n.a,n.b)}function O_(n,t,e){this.b=n,this.c=t,this.a=e}function A_(n,t,e){this.b=n,this.a=t,this.c=e}function $_(n,t,e){this.a=n,this.b=t,this.c=e}function L_(n,t,e){this.a=n,this.b=t,this.c=e}function N_(n,t,e){this.a=n,this.b=t,this.c=e}function x_(n,t,e){this.a=n,this.b=t,this.c=e}function D_(n,t,e){this.b=n,this.a=t,this.c=e}function R_(n,t,e){this.e=t,this.b=n,this.d=e}function K_(n,t,e){return bM(),n.a.Od(t,e),t}function __(n){var t;return(t=new jn).e=n,t}function F_(n){var t;return(t=new Jv).b=n,t}function B_(){B_=O,Gut=new Ne,zut=new xe}function H_(){H_=O,bst=new vr,wst=new mr}function q_(n){return Pun(),Snn((r7(),ast),n)}function G_(n){return Iun(),Snn((a7(),kst),n)}function z_(n){return mDn(),Snn((Hcn(),Xst),n)}function U_(n){return OPn(),Snn((fen(),eht),n)}function X_(n){return X8(),Snn((x4(),aht),n)}function W_(n){return Iin(),Snn((i8(),fht),n)}function V_(n){return AEn(),Snn((Fnn(),Ist),n)}function Q_(n){return Srn(),Snn((a8(),Rst),n)}function J_(n){return cin(),Snn((r8(),ght),n)}function Y_(n){return Xvn(),Snn((Knn(),Eht),n)}function Z_(n){return Rnn(),Snn((A4(),Pht),n)}function nF(n){return Qun(),Snn((c8(),$ht),n)}function tF(n){return wSn(),Snn((den(),Fht),n)}function eF(n){return w7(),Snn(($4(),Ght),n)}function iF(n){return _jn(),Snn((ben(),Yht),n)}function rF(n){return QMn(),Snn((len(),aft),n)}function cF(n){return fDn(),Snn((Xun(),vft),n)}function aF(n){return Dan(),Snn((o8(),Eft),n)}function uF(n){return q7(),Snn((u8(),Ift),n)}function oF(n){return q2(),Snn((D4(),$ft),n)}function sF(n){return jbn(),Snn((Bnn(),qlt),n)}function hF(n){return jTn(),Snn((wen(),evt),n)}function fF(n){return Ehn(),Snn((s8(),uvt),n)}function lF(n){return fvn(),Snn((u7(),bvt),n)}function bF(n){return rin(),Snn((l8(),Gvt),n)}function wF(n){return uNn(),Snn((Bcn(),Ovt),n)}function dF(n){return pon(),Snn((f8(),xvt),n)}function gF(n){return G7(),Snn((N4(),_vt),n)}function pF(n){return Fcn(),Snn((h8(),Vvt),n)}function vF(n){return $vn(),Snn((_nn(),yvt),n)}function mF(n){return C6(),Snn((L4(),Zvt),n)}function yF(n){return Gsn(),Snn((w8(),rmt),n)}function kF(n){return bcn(),Snn((d8(),smt),n)}function jF(n){return Oun(),Snn((b8(),wmt),n)}function EF(n){return ain(),Snn((g8(),$mt),n)}function TF(n){return W4(),Snn((K4(),Hmt),n)}function MF(n){return wY(),Snn((_4(),tyt),n)}function SF(n){return aZ(),Snn((F4(),cyt),n)}function PF(n){return I6(),Snn((R4(),Myt),n)}function IF(n){return bY(),Snn((B4(),Nyt),n)}function CF(n){return qyn(),Snn((i7(),Fyt),n)}function OF(n){return NPn(),Snn((gen(),Qyt),n)}function AF(n){return uZ(),Snn((G4(),Kkt),n)}function $F(n){return Mrn(),Snn((q4(),Jkt),n)}function LF(n){return _0(),Snn((H4(),Hkt),n)}function NF(n){return Sbn(),Snn((p8(),ejt),n)}function xF(n){return N9(),Snn((z4(),ajt),n)}function DF(n){return Fsn(),Snn((v8(),fjt),n)}function RF(n){return Imn(),Snn((c7(),qjt),n)}function KF(n){return _cn(),Snn((y8(),Wjt),n)}function _F(n){return Tbn(),Snn((m8(),nEt),n)}function FF(n){return VLn(),Snn((Gnn(),_Et),n)}function BF(n){return Mbn(),Snn((k8(),GEt),n)}function HF(n){return SM(),Snn((U2(),XEt),n)}function qF(n){return PM(),Snn((z2(),QEt),n)}function GF(n){return O6(),Snn((X4(),nTt),n)}function zF(n){return OSn(),Snn((Hnn(),uTt),n)}function UF(n){return IM(),Snn((X2(),GTt),n)}function XF(n){return Aun(),Snn((U4(),WTt),n)}function WF(n){return epn(),Snn((qnn(),fMt),n)}function VF(n){return MPn(),Snn((qcn(),kMt),n)}function QF(n){return lvn(),Snn((hen(),LMt),n)}function JF(n){return lEn(),Snn((sen(),ZMt),n)}function YF(n){return hWn(),Snn((TO(),Jot),n)}function ZF(n){return Trn(),Snn((O4(),qut),n)}function nB(n){return Kfn(),Snn((Unn(),HPt),n)}function tB(n){return xtn(),Snn((E8(),XPt),n)}function eB(n){return Ebn(),Snn((h7(),ZPt),n)}function iB(n){return YTn(),Snn((ven(),uIt),n)}function rB(n){return cfn(),Snn((j8(),mIt),n)}function cB(n){return zyn(),Snn((s7(),MIt),n)}function aB(n){return YAn(),Snn(($an(),DIt),n)}function uB(n){return ipn(),Snn((Xnn(),qIt),n)}function oB(n){return WEn(),Snn((Ftn(),JIt),n)}function sB(n){return hCn(),Snn((pen(),cCt),n)}function hB(n){return pdn(),Snn((l7(),_Ct),n)}function fB(n){return YKn(),Snn((Wun(),QCt),n)}function lB(n){return mUn(),Snn((Wnn(),ICt),n)}function bB(n){return Kwn(),Snn((f7(),eOt),n)}function wB(n){return _sn(),Snn((o7(),sOt),n)}function dB(n){return oAn(),Snn((Gcn(),eAt),n)}function gB(n,t){return mW(n),n+(mW(t),t)}function pB(n,t){return OT(),s9(WQ(n.a),t)}function vB(n,t){return OT(),s9(WQ(n.a),t)}function mB(n,t){this.c=n,this.a=t,this.b=t-n}function yB(n,t,e){this.a=n,this.b=t,this.c=e}function kB(n,t,e){this.a=n,this.b=t,this.c=e}function jB(n,t,e){this.a=n,this.b=t,this.c=e}function EB(n,t,e){this.a=n,this.b=t,this.c=e}function TB(n,t,e){this.a=n,this.b=t,this.c=e}function MB(n,t,e){this.e=n,this.a=t,this.c=e}function SB(n,t,e){s$(),pY.call(this,n,t,e)}function PB(n,t,e){s$(),eW.call(this,n,t,e)}function IB(n,t,e){s$(),eW.call(this,n,t,e)}function CB(n,t,e){s$(),eW.call(this,n,t,e)}function OB(n,t,e){s$(),PB.call(this,n,t,e)}function AB(n,t,e){s$(),PB.call(this,n,t,e)}function $B(n,t,e){s$(),AB.call(this,n,t,e)}function LB(n,t,e){s$(),IB.call(this,n,t,e)}function NB(n,t,e){s$(),CB.call(this,n,t,e)}function xB(n,t){return vX(n),vX(t),new oT(n,t)}function DB(n,t){return vX(n),vX(t),new RH(n,t)}function RB(n,t){return vX(n),vX(t),new KH(n,t)}function KB(n,t){return vX(n),vX(t),new hT(n,t)}function _B(n,t){return QH(null==n||Wpn(n,t)),n}function FB(n){var t;return snn(t=new $p,n),t}function BB(n){var t;return snn(t=new xv,n),t}function HB(n){var t;return Brn(t=new qv,n),t}function qB(n){var t;return Brn(t=new VT,n),t}function GB(n){return!n.e&&(n.e=new $p),n.e}function zB(n){return!n.c&&(n.c=new Bo),n.c}function UB(n,t){return n.c[n.c.length]=t,!0}function XB(n,t){this.c=n,this.b=t,this.a=!1}function WB(n){this.d=n,Eb(this),this.b=ez(n.d)}function VB(){this.a=";,;",this.b="",this.c=""}function QB(n,t,e){Gz.call(this,t,e),this.a=n}function JB(n,t,e){this.b=n,wO.call(this,t,e)}function YB(n,t,e){this.c=n,MS.call(this,t,e)}function ZB(n,t,e){RIn(e,0,n,t,e.length,!1)}function nH(n,t,e,i,r){n.b=t,n.c=e,n.d=i,n.a=r}function tH(n,t){t&&(n.b=t,n.a=(kW(t),t.a))}function eH(n,t,e,i,r){n.d=t,n.c=e,n.a=i,n.b=r}function iH(n){var t,e;t=n.b,e=n.c,n.b=e,n.c=t}function rH(n){var t,e;e=n.d,t=n.a,n.d=t,n.a=e}function cH(n){return can(LU(QO(n)?Man(n):n))}function aH(n,t){return k$(aq(n.d),aq(t.d))}function uH(n,t){return t==(mUn(),SCt)?n.c:n.d}function oH(){oH=O,mUn(),xmt=SCt,Dmt=aCt}function sH(){this.b=Hy(ED(ppn((sRn(),rat))))}function hH(n){return bM(),L8(Cnt,FWn,1,n,5,1)}function fH(n){return new LI(n.c+n.b,n.d+n.a)}function lH(n,t){return TM(),k$(n.d.p,t.d.p)}function bH(n){return Mx(0!=n.b),Ctn(n,n.a.a)}function wH(n){return Mx(0!=n.b),Ctn(n,n.c.b)}function dH(n,t){if(!n)throw Fp(new Oy(t))}function gH(n,t){if(!n)throw Fp(new Ry(t))}function pH(n,t,e){bP.call(this,n,t),this.b=e}function vH(n,t,e){AC.call(this,n,t),this.c=e}function mH(n,t,e){ftn.call(this,t,e),this.d=n}function yH(n){a_(),yo.call(this),this.th(n)}function kH(n,t,e){this.a=n,$O.call(this,t,e)}function jH(n,t,e){this.a=n,$O.call(this,t,e)}function EH(n,t,e){AC.call(this,n,t),this.c=e}function TH(){x5(),aW.call(this,(UM(),HAt))}function MH(n){return null!=n&&!zbn(n,OAt,AAt)}function SH(n,t){return(Ufn(n)<<4|Ufn(t))&WVn}function PH(n,t){return YW(),qvn(n,t),new HW(n,t)}function IH(n,t){var e;n.n&&(e=t,UB(n.f,e))}function CH(n,t,e){etn(n,t,new HX(e))}function OH(n,t){var e;return e=n.c,Din(n,t),e}function AH(n,t){return n.g=t<0?-1:t,n}function $H(n,t){return qtn(n),n.a*=t,n.b*=t,n}function LH(n,t,e,i,r){n.c=t,n.d=e,n.b=i,n.a=r}function NH(n,t){return e5(n,t,n.c.b,n.c),!0}function xH(n){n.a.b=n.b,n.b.a=n.a,n.a=n.b=null}function DH(n){this.b=n,this.a=hz(this.b.a).Ed()}function RH(n,t){this.b=n,this.a=t,_h.call(this)}function KH(n,t){this.a=n,this.b=t,_h.call(this)}function _H(n,t){Gz.call(this,t,1040),this.a=n}function FH(n){return 0==n||isNaN(n)?n:n<0?-1:1}function BH(n){return EQ(),MMn(n)==QY(IMn(n))}function HH(n){return EQ(),IMn(n)==QY(MMn(n))}function qH(n,t){return Vjn(n,new bP(t.a,t.b))}function GH(n){return!f5(n)&&n.c.i.c==n.d.i.c}function zH(n){var t;return t=n.n,n.a.b+t.d+t.a}function UH(n){var t;return t=n.n,n.e.b+t.d+t.a}function XH(n){var t;return t=n.n,n.e.a+t.b+t.c}function WH(n){return lWn(),new aG(0,n)}function VH(n){return n.a?n.a:nQ(n)}function QH(n){if(!n)throw Fp(new Dy(null))}function JH(){JH=O,TQ(),rLt=new Hb(M7n)}function YH(){YH=O,new uvn((Zm(),Rnt),(ny(),Dnt))}function ZH(){ZH=O,Ptt=L8(Ctt,uVn,19,256,0,1)}function nq(n,t,e,i){rwn.call(this,n,t,e,i,0,0)}function tq(n,t,e){return XW(n.b,_B(e.b,17),t)}function eq(n,t,e){return XW(n.b,_B(e.b,17),t)}function iq(n,t){return UB(n,new LI(t.a,t.b))}function rq(n,t){return n.c=t)throw Fp(new Tv)}function Rz(n,t,e){return OX(t,0,Fq(t[0],e[0])),t}function Kz(n,t,e){t.Ye(e,Hy(ED(xX(n.b,e)))*n.a)}function _z(n,t,e){return yDn(),Ncn(n,t)&&Ncn(n,e)}function Fz(n){return hCn(),!n.Hc(nCt)&&!n.Hc(eCt)}function Bz(n){return new LI(n.c+n.b/2,n.d+n.a/2)}function Hz(n,t){return t.kh()?Zhn(n.b,_B(t,49)):t}function qz(n,t){this.e=n,this.d=0!=(64&t)?t|oVn:t}function Gz(n,t){this.c=0,this.d=n,this.b=64|t|oVn}function zz(n){this.b=new Q6(11),this.a=(MQ(),n)}function Uz(n){this.b=null,this.a=(MQ(),n||fet)}function Xz(n){this.a=evn(n.a),this.b=new ZK(n.b)}function Wz(n){this.b=n,ix.call(this,n),EL(this)}function Vz(n){this.b=n,cx.call(this,n),TL(this)}function Qz(n,t,e){this.a=n,nK.call(this,t,e,5,6)}function Jz(n,t,e,i){this.b=n,OL.call(this,t,e,i)}function Yz(n,t,e,i,r){m9.call(this,n,t,e,i,r,-1)}function Zz(n,t,e,i,r){y9.call(this,n,t,e,i,r,-1)}function nU(n,t,e,i){OL.call(this,n,t,e),this.b=i}function tU(n,t,e,i){vH.call(this,n,t,e),this.b=i}function eU(n){$C.call(this,n,!1),this.a=!1}function iU(n,t){this.b=n,ol.call(this,n.b),this.a=t}function rU(n,t){UX(),yT.call(this,n,ufn(new Qy(t)))}function cU(n,t){return lWn(),new iW(n,t,0)}function aU(n,t){return lWn(),new iW(6,n,t)}function uU(n,t){return pK(n.substr(0,t.length),t)}function oU(n,t){return zC(t)?nJ(n,t):!!CJ(n.f,t)}function sU(n,t){for(mW(t);n.Ob();)t.td(n.Pb())}function hU(n,t,e){IDn(),this.e=n,this.d=t,this.a=e}function fU(n,t,e,i){var r;(r=n.i).i=t,r.a=e,r.b=i}function lU(n){var t;for(t=n;t.f;)t=t.f;return t}function bU(n){var t;return Mx(null!=(t=kon(n))),t}function wU(n){var t;return Mx(null!=(t=pln(n))),t}function dU(n,t){var e;return l6(t,e=n.a.gc()),e-t}function gU(n,t){var e;for(e=0;e0?i.Math.log(n/t):-100}function KU(n,t){return Xhn(n,t)<0?-1:Xhn(n,t)>0?1:0}function _U(n,t,e){return THn(n,_B(t,46),_B(e,167))}function FU(n,t){return _B(lz(hz(n.a)).Xb(t),42).cd()}function BU(n,t){return dtn(t,n.length),new _H(n,t)}function HU(n,t){this.d=n,CL.call(this,n),this.e=t}function qU(n){this.d=(mW(n),n),this.a=0,this.c=fVn}function GU(n,t){Cp.call(this,1),this.a=n,this.b=t}function zU(n,t){return n.c?zU(n.c,t):UB(n.b,t),n}function UU(n,t,e){var i;return i=bnn(n,t),e4(n,t,e),i}function XU(n,t){return p7(n.slice(0,t),n)}function WU(n,t,e){var i;for(i=0;i=n.g}function JX(n,t,e){return $Rn(n,vrn(n,t,e))}function YX(n,t){var e;bnn(n,e=n.a.length),e4(n,e,t)}function ZX(n,t){console[n].call(console,t)}function nW(n,t){var e;++n.j,e=n.Vi(),n.Ii(n.oi(e,t))}function tW(n,t,e){_B(t.b,65),Itn(t.a,new kB(n,e,t))}function eW(n,t,e){yp.call(this,t),this.a=n,this.b=e}function iW(n,t,e){Cp.call(this,n),this.a=t,this.b=e}function rW(n,t,e){this.a=n,mp.call(this,t),this.b=e}function cW(n,t,e){this.a=n,F2.call(this,8,t,null,e)}function aW(n){this.a=(mW(R9n),R9n),this.b=n,new $m}function uW(n){this.c=n,this.b=this.c.a,this.a=this.c.e}function oW(n){this.c=n,this.b=n.a.d.a,fD(n.a.e,this)}function sW(n){Ex(-1!=n.c),n.d.$c(n.c),n.b=n.c,n.c=-1}function hW(n){return i.Math.sqrt(n.a*n.a+n.b*n.b)}function fW(n,t){return Dz(t,n.a.c.length),Lq(n.a,t)}function lW(n,t){return HC(n)===HC(t)||null!=n&&$fn(n,t)}function bW(n){return 0>=n?new XT:Uin(n-1)}function wW(n){return!!ENt&&nJ(ENt,n)}function dW(n){return n?n.dc():!n.Kc().Ob()}function gW(n){return!n.a&&n.c?n.c.b:n.a}function pW(n){return!n.a&&(n.a=new OL(OOt,n,4)),n.a}function vW(n){return!n.d&&(n.d=new OL(UAt,n,1)),n.d}function mW(n){if(null==n)throw Fp(new wv);return n}function yW(n){n.c?n.c.He():(n.d=!0,WNn(n))}function kW(n){n.c?kW(n.c):(Wln(n),n.d=!0)}function jW(n){jV(n.a),n.b=L8(Cnt,FWn,1,n.b.length,5,1)}function EW(n,t){return k$(t.j.c.length,n.j.c.length)}function TW(n,t){n.c<0||n.b.b=0?n.Bh(e):iCn(n,t)}function SW(n){return n.c.i.c==n.d.i.c}function PW(n){if(4!=n.p)throw Fp(new bv);return n.e}function IW(n){if(3!=n.p)throw Fp(new bv);return n.e}function CW(n){if(6!=n.p)throw Fp(new bv);return n.f}function OW(n){if(6!=n.p)throw Fp(new bv);return n.k}function AW(n){if(3!=n.p)throw Fp(new bv);return n.j}function $W(n){if(4!=n.p)throw Fp(new bv);return n.j}function LW(n){return!n.b&&(n.b=new jp(new Lm)),n.b}function NW(n){return-2==n.c&&wb(n,cMn(n.g,n.b)),n.c}function xW(n,t){var e;return(e=pX("",n)).n=t,e.i=1,e}function DW(n,t){AG(_B(t.b,65),n),Itn(t.a,new Cw(n))}function RW(n,t){s9((!n.a&&(n.a=new aR(n,n)),n.a),t)}function KW(n,t){this.b=n,HU.call(this,n,t),EL(this)}function _W(n,t){this.b=n,xK.call(this,n,t),TL(this)}function FW(n,t,e,i){gT.call(this,n,t),this.d=e,this.a=i}function BW(n,t,e,i){gT.call(this,n,e),this.a=t,this.f=i}function HW(n,t){U$.call(this,Xin(vX(n),vX(t))),this.a=t}function qW(){bMn.call(this,T7n,(eE(),lLt)),Uqn(this)}function GW(){bMn.call(this,X9n,(tE(),JAt)),IHn(this)}function zW(){wT.call(this,"DELAUNAY_TRIANGULATION",0)}function UW(n){return String.fromCharCode.apply(null,n)}function XW(n,t,e){return zC(t)?pZ(n,t,e):yIn(n.f,t,e)}function WW(n){return TQ(),n?n.ve():(MQ(),MQ(),wet)}function VW(n,t,e){return $un(),e.pg(n,_B(t.cd(),146))}function QW(n,t){return YH(),new uvn(new eN(n),new tN(t))}function JW(n){return hin(n,$Vn),Znn(ebn(ebn(5,n),n/10|0))}function YW(){YW=O,_nt=new oy(Mun(Hk(Fnt,1),mVn,42,0,[]))}function ZW(n){return!n.d&&(n.d=new Fb(n.c.Cc())),n.d}function nV(n){return!n.a&&(n.a=new Ak(n.c.vc())),n.a}function tV(n){return!n.b&&(n.b=new Ck(n.c.ec())),n.b}function eV(n,t){for(;t-- >0;)n=n<<1|(n<0?1:0);return n}function iV(n,t){return HC(n)===HC(t)||null!=n&&$fn(n,t)}function rV(n,t){return oN(),_B(t.b,19).a(i=SY(e))&&++i,i}function JV(n){var t;return ien(t=new Dp,n),t}function YV(n){var t;return NMn(t=new Dp,n),t}function ZV(n,t){return Dcn(t,xX(n.f,t)),null}function nQ(n){return Vin(n)||null}function tQ(n){return!n.b&&(n.b=new nU(DOt,n,12,3)),n.b}function eQ(n){return null!=n&<(mAt,n.toLowerCase())}function iQ(n,t){return Mln(tG(n)*nG(n),tG(t)*nG(t))}function rQ(n,t){return Mln(tG(n)*nG(n),tG(t)*nG(t))}function cQ(n,t){return Mln(n.d.c+n.d.b/2,t.d.c+t.d.b/2)}function aQ(n,t){return Mln(n.g.c+n.g.b/2,t.g.c+t.g.b/2)}function uQ(n,t,e){e.a?Sen(n,t.b-n.f/2):Men(n,t.a-n.g/2)}function oQ(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function sQ(n,t,e,i){this.a=n,this.b=t,this.c=e,this.d=i}function hQ(n,t,e,i){this.e=n,this.a=t,this.c=e,this.d=i}function fQ(n,t,e,i){this.a=n,this.c=t,this.d=e,this.b=i}function lQ(n,t,e,i){s$(),n6.call(this,t,e,i),this.a=n}function bQ(n,t,e,i){s$(),n6.call(this,t,e,i),this.a=n}function wQ(n,t){this.a=n,ID.call(this,n,_B(n.d,15).Zc(t))}function dQ(n){this.f=n,this.c=this.f.e,n.f>0&&cjn(this)}function gQ(n,t,e,i){this.b=n,this.c=i,gO.call(this,t,e)}function pQ(n){return Mx(n.b=0&&pK(n.substr(e,t.length),t)}function AJ(n,t,e,i,r,c,a){return new f4(n.e,t,e,i,r,c,a)}function $J(n,t,e,i,r,c){this.a=n,min.call(this,t,e,i,r,c)}function LJ(n,t,e,i,r,c){this.a=n,min.call(this,t,e,i,r,c)}function NJ(n,t){this.g=n,this.d=Mun(Hk(Iut,1),r1n,10,0,[t])}function xJ(n,t){this.e=n,this.a=Cnt,this.b=CRn(t),this.c=t}function DJ(n,t){$R.call(this),Ltn(this),this.a=n,this.c=t}function RJ(n,t,e,i){OX(n.c[t.g],e.g,i),OX(n.c[e.g],t.g,i)}function KJ(n,t,e,i){OX(n.c[t.g],t.g,e),OX(n.b[t.g],t.g,i)}function _J(){return C6(),Mun(Hk(imt,1),OVn,376,0,[Jvt,Qvt])}function FJ(){return w7(),Mun(Hk(Jht,1),OVn,479,0,[Hht,Bht])}function BJ(){return Rnn(),Mun(Hk(Aht,1),OVn,419,0,[Tht,Mht])}function HJ(){return X8(),Mun(Hk(hht,1),OVn,422,0,[iht,rht])}function qJ(){return q2(),Mun(Hk(Hlt,1),OVn,420,0,[Cft,Oft])}function GJ(){return G7(),Mun(Hk(qvt,1),OVn,421,0,[Dvt,Rvt])}function zJ(){return W4(),Mun(Hk(Xmt,1),OVn,523,0,[Fmt,_mt])}function UJ(){return I6(),Mun(Hk(Lyt,1),OVn,520,0,[Eyt,jyt])}function XJ(){return wY(),Mun(Hk(ryt,1),OVn,516,0,[Zmt,Ymt])}function WJ(){return aZ(),Mun(Hk(Tyt,1),OVn,515,0,[eyt,iyt])}function VJ(){return bY(),Mun(Hk(_yt,1),OVn,455,0,[Ayt,$yt])}function QJ(){return _0(),Mun(Hk(Qkt,1),OVn,425,0,[Fkt,_kt])}function JJ(){return uZ(),Mun(Hk(Bkt,1),OVn,480,0,[xkt,Dkt])}function YJ(){return Mrn(),Mun(Hk(tjt,1),OVn,495,0,[Wkt,Vkt])}function ZJ(){return N9(),Mun(Hk(hjt,1),OVn,426,0,[ijt,rjt])}function nY(){return Aun(),Mun(Hk(VTt,1),OVn,429,0,[UTt,zTt])}function tY(){return O6(),Mun(Hk(aTt,1),OVn,430,0,[YEt,JEt])}function eY(){return opn(),Mun(Hk(vit,1),OVn,428,0,[bit,lit])}function iY(){return xnn(),Mun(Hk(Dit,1),OVn,427,0,[git,pit])}function rY(){return Dnn(),Mun(Hk(Oat,1),OVn,424,0,[Nct,xct])}function cY(){return Trn(),Mun(Hk(Uut,1),OVn,511,0,[But,Fut])}function aY(n,t,e,i){return e>=0?n.jh(t,e,i):n.Sg(null,e,i)}function uY(n){return 0==n.b.b?n.a.$e():bH(n.b)}function oY(n){if(5!=n.p)throw Fp(new bv);return bG(n.f)}function sY(n){if(5!=n.p)throw Fp(new bv);return bG(n.k)}function hY(n){return HC(n.a)===HC((lcn(),S$t))&&xqn(n),n.a}function fY(n){this.a=_B(vX(n),271),this.b=(TQ(),new bN(n))}function lY(n,t){Jl(this,new LI(n.a,n.b)),Yl(this,qB(t))}function bY(){bY=O,Ayt=new aI(iYn,0),$yt=new aI(rYn,1)}function wY(){wY=O,Zmt=new iI(rYn,0),Ymt=new iI(iYn,1)}function dY(){ry.call(this,new zT(ntn(12))),rN(!0),this.a=2}function gY(n,t,e){lWn(),Cp.call(this,n),this.b=t,this.a=e}function pY(n,t,e){s$(),yp.call(this,t),this.a=n,this.b=e}function vY(n){$R.call(this),Ltn(this),this.a=n,this.c=!0}function mY(n){var t;t=n.c.d.b,n.b=t,n.a=n.c.d,t.a=n.c.d.b=n}function yY(n){din(n.a),xA(n.a),Zbn(new Mw(n.a))}function kY(n,t){aRn(n,!0),Itn(n.e.wf(),new O_(n,!0,t))}function jY(n,t){return i4(t),Ven(n,L8(INt,oQn,25,t,15,1),t)}function EY(n,t){return EQ(),n==QY(MMn(t))||n==QY(IMn(t))}function TY(n,t){return null==t?BC(CJ(n.f,null)):oS(n.g,t)}function MY(n){return 0==n.b?null:(Mx(0!=n.b),Ctn(n,n.a.a))}function SY(n){return 0|Math.max(Math.min(n,NWn),-2147483648)}function PY(n,t){var e=Jnt[n.charCodeAt(0)];return null==e?n:e}function IY(n,t){return UQ(n,"set1"),UQ(t,"set2"),new kT(n,t)}function CY(n,t){return GR(Bx(Ytn(n.f,t)),n.f.d)}function OY(n,t){var e;return VGn(n,t,e=new q),e.d}function AY(n,t,e,i){var r;r=new KR,t.a[e.g]=r,pG(n.b,i,r)}function $Y(n,t,e){var i;(i=n.Yg(t))>=0?n.sh(i,e):jLn(n,t,e)}function LY(n,t,e){oZ(),n&&XW(aAt,n,t),n&&XW(cAt,n,e)}function NY(n,t,e){this.i=new $p,this.b=n,this.g=t,this.a=e}function xY(n,t,e){this.c=new $p,this.e=n,this.f=t,this.b=e}function DY(n,t,e){this.a=new $p,this.e=n,this.f=t,this.c=e}function RY(n,t){X$(this),this.f=t,this.g=n,yQ(this),this._d()}function KY(n,t){var e;e=n.q.getHours(),n.q.setDate(t),hBn(n,e)}function _Y(n,t){var e;for(vX(t),e=n.a;e;e=e.c)t.Od(e.g,e.i)}function FY(n){var t;return Oon(t=new fE(ntn(n.length)),n),t}function BY(n){function t(){}return t.prototype=n||{},new t}function HY(n,t){return!!lun(n,t)&&(nin(n),!0)}function qY(n,t){if(null==t)throw Fp(new wv);return cgn(n,t)}function GY(n){if(n.qe())return null;var t=n.n;return TWn[t]}function zY(n){return n.Db>>16!=3?null:_B(n.Cb,33)}function UY(n){return n.Db>>16!=9?null:_B(n.Cb,33)}function XY(n){return n.Db>>16!=6?null:_B(n.Cb,79)}function WY(n){return n.Db>>16!=7?null:_B(n.Cb,235)}function VY(n){return n.Db>>16!=7?null:_B(n.Cb,160)}function QY(n){return n.Db>>16!=11?null:_B(n.Cb,33)}function JY(n,t){var e;return(e=n.Yg(t))>=0?n.lh(e):BCn(n,t)}function YY(n,t){var e;return aMn(e=new Aq(t),n),new ZK(e)}function ZY(n){var t;return t=n.d,t=n.si(n.f),s9(n,t),t.Ob()}function nZ(n,t){return n.b+=t.b,n.c+=t.c,n.d+=t.d,n.a+=t.a,n}function tZ(n,t){return i.Math.abs(n)0}function iZ(){this.a=new sA,this.e=new xv,this.g=0,this.i=0}function rZ(n){this.a=n,this.b=L8(Rmt,uVn,1944,n.e.length,0,2)}function cZ(n,t,e){var i;i=$on(n,t,e),n.b=new prn(i.c.length)}function aZ(){aZ=O,eyt=new eI(dYn,0),iyt=new eI("UP",1)}function uZ(){uZ=O,xkt=new fI(G3n,0),Dkt=new fI("FAN",1)}function oZ(){oZ=O,aAt=new Lp,cAt=new Lp,KC(vet,new wo)}function sZ(n){if(0!=n.p)throw Fp(new bv);return QC(n.f,0)}function hZ(n){if(0!=n.p)throw Fp(new bv);return QC(n.k,0)}function fZ(n){return n.Db>>16!=3?null:_B(n.Cb,147)}function lZ(n){return n.Db>>16!=6?null:_B(n.Cb,235)}function bZ(n){return n.Db>>16!=17?null:_B(n.Cb,26)}function wZ(n,t){var e=n.a=n.a||[];return e[t]||(e[t]=n.le(t))}function dZ(n,t){var e;return null==(e=n.a.get(t))?new Array:e}function gZ(n,t){var e;e=n.q.getHours(),n.q.setMonth(t),hBn(n,e)}function pZ(n,t,e){return null==t?yIn(n.f,null,e):cbn(n.g,t,e)}function vZ(n,t,e,i,r,c){return new $7(n.e,t,n.aj(),e,i,r,c)}function mZ(n,t,e){return n.a=sx(n.a,0,t)+""+e+YC(n.a,t),n}function yZ(n,t,e){return UB(n.a,(YW(),qvn(t,e),new gT(t,e))),n}function kZ(n){return aN(n.c),n.e=n.a=n.c,n.c=n.c.c,++n.d,n.a.f}function jZ(n){return aN(n.e),n.c=n.a=n.e,n.e=n.e.e,--n.d,n.a.f}function EZ(n,t){n.d&&v7(n.d.e,n),n.d=t,n.d&&UB(n.d.e,n)}function TZ(n,t){n.c&&v7(n.c.g,n),n.c=t,n.c&&UB(n.c.g,n)}function MZ(n,t){n.c&&v7(n.c.a,n),n.c=t,n.c&&UB(n.c.a,n)}function SZ(n,t){n.i&&v7(n.i.j,n),n.i=t,n.i&&UB(n.i.j,n)}function PZ(n,t,e){this.a=t,this.c=n,this.b=(vX(e),new ZK(e))}function IZ(n,t,e){this.a=t,this.c=n,this.b=(vX(e),new ZK(e))}function CZ(n,t){this.a=n,this.c=_$(this.a),this.b=new wJ(t)}function OZ(n){return Wln(n),CV(n,new gw(new xv))}function AZ(n,t){if(n<0||n>t)throw Fp(new Cy(yJn+n+kJn+t))}function $Z(n,t){return PG(n.a,t)?kU(n,_B(t,22).g,null):null}function LZ(n){return Thn(),oN(),0!=_B(n.a,81).d.e}function NZ(){NZ=O,znt=hhn((ey(),Mun(Hk(Unt,1),OVn,538,0,[qnt])))}function xZ(){xZ=O,dmt=UG(new _2,(vMn(),_at),(hWn(),Bot))}function DZ(){DZ=O,gmt=UG(new _2,(vMn(),_at),(hWn(),Bot))}function RZ(){RZ=O,vmt=UG(new _2,(vMn(),_at),(hWn(),Bot))}function KZ(){KZ=O,qmt=bq(new _2,(vMn(),_at),(hWn(),bot))}function _Z(){_Z=O,Wmt=bq(new _2,(vMn(),_at),(hWn(),bot))}function FZ(){FZ=O,Jmt=bq(new _2,(vMn(),_at),(hWn(),bot))}function BZ(){BZ=O,ayt=bq(new _2,(vMn(),_at),(hWn(),bot))}function HZ(){HZ=O,qkt=UG(new _2,(qyn(),Kyt),(NPn(),qyt))}function qZ(n,t,e,i){this.c=n,this.d=i,UZ(this,t),XZ(this,e)}function GZ(n){this.c=new VT,this.b=n.b,this.d=n.c,this.a=n.a}function zZ(n){this.a=i.Math.cos(n),this.b=i.Math.sin(n)}function UZ(n,t){n.a&&v7(n.a.k,n),n.a=t,n.a&&UB(n.a.k,n)}function XZ(n,t){n.b&&v7(n.b.f,n),n.b=t,n.b&&UB(n.b.f,n)}function WZ(n,t){tW(n,n.b,n.c),_B(n.b.b,65),t&&_B(t.b,65).b}function VZ(n,t){qln(n,t),iL(n.Cb,88)&&CIn(M5(_B(n.Cb,88)),2)}function QZ(n,t){iL(n.Cb,88)&&CIn(M5(_B(n.Cb,88)),4),$rn(n,t)}function JZ(n,t){iL(n.Cb,179)&&(_B(n.Cb,179).tb=null),$rn(n,t)}function YZ(n,t){return JM(),onn(t)?new hq(t,n):new LC(t,n)}function ZZ(n,t){null!=t.c&&YX(n,new HX(t.c))}function n1(n){var t;return tE(),ien(t=new Dp,n),t}function t1(n){var t;return tE(),ien(t=new Dp,n),t}function e1(n,t){var e;return e=new FX(n),t.c[t.c.length]=e,e}function i1(n,t){var e;return(e=_B(hfn(IQ(n.a),t),14))?e.gc():0}function r1(n){return Wln(n),MQ(),MQ(),vtn(n,bet)}function c1(n){for(var t;;)if(t=n.Pb(),!n.Ob())return t}function a1(n,t){Gm.call(this,new zT(ntn(n))),hin(t,aVn),this.a=t}function u1(n,t,e){Ffn(t,e,n.gc()),this.c=n,this.a=t,this.b=e-t}function o1(n,t,e){var i;Ffn(t,e,n.c.length),i=e-t,ME(n.c,t,i)}function s1(n,t){oL(n,bG(n0(mz(t,24),uJn)),bG(n0(t,uJn)))}function h1(n,t){if(n<0||n>=t)throw Fp(new Cy(yJn+n+kJn+t))}function f1(n,t){if(n<0||n>=t)throw Fp(new Ik(yJn+n+kJn+t))}function l1(n,t){this.b=(mW(n),n),this.a=0==(t&RQn)?64|t|oVn:t}function b1(n){NA(this),Mv(this.a,mon(i.Math.max(8,n))<<1)}function w1(n){return Con(Mun(Hk(MMt,1),uVn,8,0,[n.i.n,n.n,n.a]))}function d1(){return Bsn(),Mun(Hk(Yet,1),OVn,132,0,[qet,Get,zet])}function g1(){return Ntn(),Mun(Hk(Xit,1),OVn,232,0,[Hit,qit,Git])}function p1(){return Q9(),Mun(Hk(nrt,1),OVn,461,0,[Vit,Wit,Qit])}function v1(){return H7(),Mun(Hk(Irt,1),OVn,462,0,[irt,ert,trt])}function m1(){return _fn(),Mun(Hk(put,1),OVn,423,0,[lut,fut,hut])}function y1(){return B7(),Mun(Hk(Fat,1),OVn,379,0,[Iat,Pat,Cat])}function k1(){return Ehn(),Mun(Hk(lvt,1),OVn,378,0,[ivt,rvt,cvt])}function j1(){return Iin(),Mun(Hk(dht,1),OVn,314,0,[oht,uht,sht])}function E1(){return cin(),Mun(Hk(jht,1),OVn,337,0,[lht,wht,bht])}function T1(){return Qun(),Mun(Hk(_ht,1),OVn,450,0,[Cht,Iht,Oht])}function M1(){return Srn(),Mun(Hk(Ust,1),OVn,361,0,[xst,Nst,Lst])}function S1(){return q7(),Mun(Hk(Aft,1),OVn,303,0,[Mft,Sft,Tft])}function P1(){return Dan(),Mun(Hk(Pft,1),OVn,292,0,[yft,kft,mft])}function I1(){return rin(),Mun(Hk(Wvt,1),OVn,452,0,[Hvt,Fvt,Bvt])}function C1(){return pon(),Mun(Hk(Kvt,1),OVn,339,0,[$vt,Avt,Lvt])}function O1(){return Fcn(),Mun(Hk(Yvt,1),OVn,375,0,[zvt,Uvt,Xvt])}function A1(){return Oun(),Mun(Hk(Tmt,1),OVn,377,0,[fmt,lmt,hmt])}function $1(){return Gsn(),Mun(Hk(omt,1),OVn,336,0,[nmt,tmt,emt])}function L1(){return bcn(),Mun(Hk(bmt,1),OVn,338,0,[umt,cmt,amt])}function N1(){return ain(),Mun(Hk(Lmt,1),OVn,454,0,[Imt,Cmt,Omt])}function x1(){return Sbn(),Mun(Hk(cjt,1),OVn,442,0,[njt,Ykt,Zkt])}function D1(){return Fsn(),Mun(Hk(Hjt,1),OVn,380,0,[ujt,ojt,sjt])}function R1(){return Tbn(),Mun(Hk($Et,1),OVn,381,0,[Jjt,Yjt,Qjt])}function K1(){return _cn(),Mun(Hk(Vjt,1),OVn,293,0,[zjt,Ujt,Gjt])}function _1(){return Mbn(),Mun(Hk(UEt,1),OVn,437,0,[FEt,BEt,HEt])}function F1(){return cfn(),Mun(Hk(TIt,1),OVn,334,0,[gIt,dIt,pIt])}function B1(){return xtn(),Mun(Hk(YPt,1),OVn,272,0,[qPt,GPt,zPt])}function H1(n,t){return m$n(n,t,iL(t,99)&&0!=(_B(t,18).Bb&_Qn))}function q1(n,t,e){var i;return(i=iHn(n,t,!1)).b<=t&&i.a<=e}function G1(n,t,e){var i;(i=new ca).b=t,i.a=e,++t.b,UB(n.d,i)}function z1(n,t){var e;return jx(!!(e=(mW(n),n).g)),mW(t),e(t)}function U1(n,t){var e,i;return i=dU(n,t),e=n.a.Zc(i),new mT(n,e)}function X1(n){return n.Db>>16!=6?null:_B(iAn(n),235)}function W1(n){if(2!=n.p)throw Fp(new bv);return bG(n.f)&WVn}function V1(n){if(2!=n.p)throw Fp(new bv);return bG(n.k)&WVn}function Q1(n){return n.a==(x5(),Z$t)&&bb(n,nLn(n.g,n.b)),n.a}function J1(n){return n.d==(x5(),Z$t)&&db(n,$Kn(n.g,n.b)),n.d}function Y1(n){return Mx(n.ai?1:0}function l0(n,t){var e;return e=T7(t),_B(xX(n.c,e),19).a}function b0(n,t){var e;for(e=n+"";e.length0&&0==n.a[--n.d];);0==n.a[n.d++]&&(n.e=0)}function U0(n){return n.a?0==n.e.length?n.a.a:n.a.a+""+n.e:n.c}function X0(n){return!(!n.a||0==F7(n.a.a).i||n.b&&Dvn(n.b))}function W0(n){return!(!n.u||0==r4(n.u.a).i||n.n&&xvn(n.n))}function V0(n){return vq(n.e.Hd().gc()*n.c.Hd().gc(),16,new qf(n))}function Q0(n,t){return KU(san(n.q.getTime()),san(t.q.getTime()))}function J0(n){return _B(Wgn(n,L8(vut,i1n,17,n.c.length,0,1)),474)}function Y0(n){return _B(Wgn(n,L8(Iut,r1n,10,n.c.length,0,1)),193)}function Z0(n){return _Z(),!(f5(n)||!f5(n)&&n.c.i.c==n.d.i.c)}function n2(n,t,e){vX(n),Lyn(new PZ(new ZK(n),t,e))}function t2(n,t,e){vX(n),Nyn(new IZ(new ZK(n),t,e))}function e2(n,t){var e;return e=1-t,n.a[e]=lrn(n.a[e],e),lrn(n,t)}function i2(n,t){var e;n.e=new Qm,p$(e=lDn(t),n.c),PDn(n,e,0)}function r2(n,t,e,i){var r;(r=new vu).a=t,r.b=e,r.c=i,NH(n.a,r)}function c2(n,t,e,i){var r;(r=new vu).a=t,r.b=e,r.c=i,NH(n.b,r)}function a2(n){var t,e;return e=ZKn(t=new hX,n),vzn(t),e}function u2(){var n,t;return n=new Dp,UB(U$t,t=n),t}function o2(n){return n.j.c=L8(Cnt,FWn,1,0,5,1),jV(n.c),wV(n.a),n}function s2(n){return EM(),iL(n.g,10)?_B(n.g,10):null}function h2(n){return!kV(n).dc()&&(A$(n,new m),!0)}function f2(n){if(!("stack"in n))try{throw n}catch(t){}return n}function l2(n,t){if(n<0||n>=t)throw Fp(new Cy(AIn(n,t)));return n}function b2(n,t,e){if(n<0||te)throw Fp(new Cy(aPn(n,t,e)))}function w2(n,t){if(jU(n.a,t),t.d)throw Fp(new by(PJn));t.d=n}function d2(n,t){if(t.$modCount!=n.$modCount)throw Fp(new gv)}function g2(n,t){return!!iL(t,42)&&Emn(n.a,_B(t,42))}function p2(n,t){return!!iL(t,42)&&Emn(n.a,_B(t,42))}function v2(n,t){return!!iL(t,42)&&Emn(n.a,_B(t,42))}function m2(n,t){return n.a<=n.b&&(t.ud(n.a++),!0)}function y2(n){var t;return QO(n)?-0==(t=n)?0:t:dnn(n)}function k2(n){var t;return kW(n),t=new F,wE(n.a,new ww(t)),t}function j2(n){var t;return kW(n),t=new _,wE(n.a,new bw(t)),t}function E2(n,t){this.a=n,Tb.call(this,n),AZ(t,n.gc()),this.b=t}function T2(n){this.e=n,this.b=this.e.a.entries(),this.a=new Array}function M2(n){return vq(n.e.Hd().gc()*n.c.Hd().gc(),273,new Hf(n))}function S2(n){return new Q6((hin(n,$Vn),Znn(ebn(ebn(5,n),n/10|0))))}function P2(n){return _B(Wgn(n,L8(Hut,c1n,11,n.c.length,0,1)),1943)}function I2(n,t,e){return e.f.c.length>0?_U(n.a,t,e):_U(n.b,t,e)}function C2(n,t,e){n.d&&v7(n.d.e,n),n.d=t,n.d&&mG(n.d.e,e,n)}function O2(n,t){gXn(t,n),rH(n.d),rH(_B(pMn(n,(FXn(),Cgt)),207))}function A2(n,t){dXn(t,n),iH(n.d),iH(_B(pMn(n,(FXn(),Cgt)),207))}function $2(n,t){var e,i;return i=null,(e=qY(n,t))&&(i=e.fe()),i}function L2(n,t){var e,i;return i=null,(e=bnn(n,t))&&(i=e.ie()),i}function N2(n,t){var e,i;return i=null,(e=qY(n,t))&&(i=e.ie()),i}function x2(n,t){var e,i;return i=null,(e=qY(n,t))&&(i=vPn(e)),i}function D2(n,t,e){var i;return i=Wdn(e),lKn(n.g,i,t),lKn(n.i,t,e),t}function R2(n,t,e){var i;i=Adn();try{return bR(n,t,e)}finally{v3(i)}}function K2(n){var t;t=n.Wg(),this.a=iL(t,69)?_B(t,69).Zh():t.Kc()}function _2(){Vm.call(this),this.j.c=L8(Cnt,FWn,1,0,5,1),this.a=-1}function F2(n,t,e,i){this.d=n,this.n=t,this.g=e,this.o=i,this.p=-1}function B2(n,t,e,i){this.e=i,this.d=null,this.c=n,this.a=t,this.b=e}function H2(n,t,e){this.d=new Kd(this),this.e=n,this.i=t,this.f=e}function q2(){q2=O,Cft=new NP(nYn,0),Oft=new NP("TOP_LEFT",1)}function G2(){G2=O,jmt=QW(tln(1),tln(4)),kmt=QW(tln(1),tln(2))}function z2(){z2=O,QEt=hhn((PM(),Mun(Hk(ZEt,1),OVn,551,0,[WEt])))}function U2(){U2=O,XEt=hhn((SM(),Mun(Hk(VEt,1),OVn,482,0,[zEt])))}function X2(){X2=O,GTt=hhn((IM(),Mun(Hk(XTt,1),OVn,530,0,[HTt])))}function W2(){W2=O,rct=hhn((lM(),Mun(Hk(Mct,1),OVn,481,0,[ect])))}function V2(){return Nan(),Mun(Hk(Hrt,1),OVn,406,0,[xrt,$rt,Lrt,Nrt])}function Q2(){return J9(),Mun(Hk(Ket,1),OVn,297,0,[$et,Let,Net,xet])}function J2(){return Bpn(),Mun(Hk(ict,1),OVn,394,0,[Jrt,Qrt,Yrt,Zrt])}function Y2(){return Fpn(),Mun(Hk(Grt,1),OVn,323,0,[_rt,Krt,Frt,Brt])}function Z2(){return Cun(),Mun(Hk(but,1),OVn,405,0,[Jat,nut,Yat,Zat])}function n3(){return Pun(),Mun(Hk(dst,1),OVn,360,0,[rst,est,ist,tst])}function t3(n,t,e,i){return iL(e,54)?new Ix(n,t,e,i):new uz(n,t,e,i)}function e3(){return Iun(),Mun(Hk(Pst,1),OVn,411,0,[gst,pst,vst,mst])}function i3(n){return n.j==(mUn(),TCt)&&TN(GOn(n),aCt)}function r3(n,t){var e;TZ(e=t.a,t.c.d),EZ(e,t.d.d),Jtn(e.a,n.n)}function c3(n,t){return _B(ON(Pz(_B(o6(n.k,t),15).Oc(),Wst)),113)}function a3(n,t){return _B(ON(Iz(_B(o6(n.k,t),15).Oc(),Wst)),113)}function u3(n){return new l1(Zrn(_B(n.a.dd(),14).gc(),n.a.cd()),16)}function o3(n){return iL(n,14)?_B(n,14).dc():!n.Kc().Ob()}function s3(n){return EM(),iL(n.g,145)?_B(n.g,145):null}function h3(n){if(n.e.g!=n.b)throw Fp(new gv);return!!n.c&&n.d>0}function f3(n){return Mx(n.b!=n.d.c),n.c=n.b,n.b=n.b.a,++n.a,n.c.c}function l3(n,t){mW(t),OX(n.a,n.c,t),n.c=n.c+1&n.a.length-1,lyn(n)}function b3(n,t){mW(t),n.b=n.b-1&n.a.length-1,OX(n.a,n.b,t),lyn(n)}function w3(n,t){var e;for(e=n.j.c.length;e0&&rHn(n.g,0,t,0,n.i),t}function L3(n,t){var e;return YM(),!(e=_B(xX(gAt,n),55))||e.wj(t)}function N3(n){if(1!=n.p)throw Fp(new bv);return bG(n.f)<<24>>24}function x3(n){if(1!=n.p)throw Fp(new bv);return bG(n.k)<<24>>24}function D3(n){if(7!=n.p)throw Fp(new bv);return bG(n.k)<<16>>16}function R3(n){if(7!=n.p)throw Fp(new bv);return bG(n.f)<<16>>16}function K3(n){var t;for(t=0;n.Ob();)n.Pb(),t=ebn(t,1);return Znn(t)}function _3(n,t){var e;return e=new Pk,n.xd(e),e.a+="..",t.yd(e),e.a}function F3(n,t,e){var i;i=_B(xX(n.g,e),57),UB(n.a.c,new eC(t,i))}function B3(n,t,e){return jz(ED(BC(CJ(n.f,t))),ED(BC(CJ(n.f,e))))}function H3(n,t,e){return GFn(n,t,e,iL(t,99)&&0!=(_B(t,18).Bb&_Qn))}function q3(n,t,e){return dBn(n,t,e,iL(t,99)&&0!=(_B(t,18).Bb&_Qn))}function G3(n,t,e){return L$n(n,t,e,iL(t,99)&&0!=(_B(t,18).Bb&_Qn))}function z3(n,t){return n==(cSn(),Sut)&&t==Sut?4:n==Sut||t==Sut?8:32}function U3(n,t){return HC(t)===HC(n)?"(this Map)":null==t?qWn:_bn(t)}function X3(n,t){return _B(null==t?BC(CJ(n.f,null)):oS(n.g,t),281)}function W3(n,t,e){var i;return i=Wdn(e),XW(n.b,i,t),XW(n.c,t,e),t}function V3(n,t){var e;for(e=t;e;)Rx(n,e.i,e.j),e=QY(e);return n}function Q3(n,t){var e;return e=eJ(FB(new S7(n,t))),Sq(new S7(n,t)),e}function J3(n,t){var e;return JM(),jSn(e=_B(n,66).Mj(),t),e.Ok(t)}function Y3(n,t,e,i,r){UB(t,pIn(r,z$n(r,e,i))),GMn(n,r,t)}function Z3(n,t,e){n.i=0,n.e=0,t!=e&&(Uon(n,t,e),zon(n,t,e))}function n4(n,t){var e;e=n.q.getHours(),n.q.setFullYear(t+uQn),hBn(n,e)}function t4(n,t,e){if(e){var i=e.ee();n.a[t]=i(e)}else delete n.a[t]}function e4(n,t,e){if(e){var i=e.ee();e=i(e)}else e=void 0;n.a[t]=e}function i4(n){if(n<0)throw Fp(new _y("Negative array size: "+n))}function r4(n){return n.n||(M5(n),n.n=new VG(n,UAt,n),mJ(n)),n.n}function c4(n){return Mx(n.a=0&&n.a[e]===t[e];e--);return e<0}function j4(n,t){var e;return qsn(),0!=(e=n.j.g-t.j.g)?e:0}function E4(n,t){return mW(t),null!=n.a?MG(t.Kb(n.a)):Tet}function T4(n){var t;return n?new Aq(n):(Brn(t=new sA,n),t)}function M4(n,t){return t.b.Kb(j7(n,t.c.Ee(),new vw(t)))}function S4(n){vTn(),oL(this,bG(n0(mz(n,24),uJn)),bG(n0(n,uJn)))}function P4(){P4=O,dit=hhn((opn(),Mun(Hk(vit,1),OVn,428,0,[bit,lit])))}function I4(){I4=O,mit=hhn((xnn(),Mun(Hk(Dit,1),OVn,427,0,[git,pit])))}function C4(){C4=O,Rct=hhn((Dnn(),Mun(Hk(Oat,1),OVn,424,0,[Nct,xct])))}function O4(){O4=O,qut=hhn((Trn(),Mun(Hk(Uut,1),OVn,511,0,[But,Fut])))}function A4(){A4=O,Pht=hhn((Rnn(),Mun(Hk(Aht,1),OVn,419,0,[Tht,Mht])))}function $4(){$4=O,Ght=hhn((w7(),Mun(Hk(Jht,1),OVn,479,0,[Hht,Bht])))}function L4(){L4=O,Zvt=hhn((C6(),Mun(Hk(imt,1),OVn,376,0,[Jvt,Qvt])))}function N4(){N4=O,_vt=hhn((G7(),Mun(Hk(qvt,1),OVn,421,0,[Dvt,Rvt])))}function x4(){x4=O,aht=hhn((X8(),Mun(Hk(hht,1),OVn,422,0,[iht,rht])))}function D4(){D4=O,$ft=hhn((q2(),Mun(Hk(Hlt,1),OVn,420,0,[Cft,Oft])))}function R4(){R4=O,Myt=hhn((I6(),Mun(Hk(Lyt,1),OVn,520,0,[Eyt,jyt])))}function K4(){K4=O,Hmt=hhn((W4(),Mun(Hk(Xmt,1),OVn,523,0,[Fmt,_mt])))}function _4(){_4=O,tyt=hhn((wY(),Mun(Hk(ryt,1),OVn,516,0,[Zmt,Ymt])))}function F4(){F4=O,cyt=hhn((aZ(),Mun(Hk(Tyt,1),OVn,515,0,[eyt,iyt])))}function B4(){B4=O,Nyt=hhn((bY(),Mun(Hk(_yt,1),OVn,455,0,[Ayt,$yt])))}function H4(){H4=O,Hkt=hhn((_0(),Mun(Hk(Qkt,1),OVn,425,0,[Fkt,_kt])))}function q4(){q4=O,Jkt=hhn((Mrn(),Mun(Hk(tjt,1),OVn,495,0,[Wkt,Vkt])))}function G4(){G4=O,Kkt=hhn((uZ(),Mun(Hk(Bkt,1),OVn,480,0,[xkt,Dkt])))}function z4(){z4=O,ajt=hhn((N9(),Mun(Hk(hjt,1),OVn,426,0,[ijt,rjt])))}function U4(){U4=O,WTt=hhn((Aun(),Mun(Hk(VTt,1),OVn,429,0,[UTt,zTt])))}function X4(){X4=O,nTt=hhn((O6(),Mun(Hk(aTt,1),OVn,430,0,[YEt,JEt])))}function W4(){W4=O,Fmt=new QP("UPPER",0),_mt=new QP("LOWER",1)}function V4(n,t){var e;BQ(e=new dy,"x",t.a),BQ(e,"y",t.b),YX(n,e)}function Q4(n,t){var e;BQ(e=new dy,"x",t.a),BQ(e,"y",t.b),YX(n,e)}function J4(n,t){var e,i;i=!1;do{i|=e=fon(n,t)}while(e);return i}function Y4(n,t){var e,i;for(e=t,i=0;e>0;)i+=n.a[e],e-=e&-e;return i}function Z4(n,t){var e;for(e=t;e;)Rx(n,-e.i,-e.j),e=QY(e);return n}function n5(n,t){var e,i;for(mW(t),i=n.Kc();i.Ob();)e=i.Pb(),t.td(e)}function t5(n,t){var e;return new gT(e=t.cd(),n.e.pc(e,_B(t.dd(),14)))}function e5(n,t,e,i){var r;(r=new $).c=t,r.b=e,r.a=i,i.b=e.a=r,++n.b}function i5(n,t,e){var i;return h1(t,n.c.length),i=n.c[t],n.c[t]=e,i}function r5(n,t,e){return _B(null==t?yIn(n.f,null,e):cbn(n.g,t,e),281)}function c5(n){return n.c&&n.d?d0(n.c)+"->"+d0(n.d):"e_"+MN(n)}function a5(n,t){return(Wln(n),yE(new xq(n,new W9(t,n.a)))).sd(Zet)}function u5(){return vMn(),Mun(Hk(Gat,1),OVn,356,0,[xat,Dat,Rat,Kat,_at])}function o5(){return mUn(),Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt])}function s5(n){return Nk(),function(){return R2(n,this,arguments)}}function h5(){return Date.now?Date.now():(new Date).getTime()}function f5(n){return!(!n.c||!n.d||!n.c.i||n.c.i!=n.d.i)}function l5(n){if(!n.c.Sb())throw Fp(new vv);return n.a=!0,n.c.Ub()}function b5(n){n.i=0,vS(n.b,null),vS(n.c,null),n.a=null,n.e=null,++n.g}function w5(n){bS.call(this,null==n?qWn:_bn(n),iL(n,78)?_B(n,78):null)}function d5(n){nWn(),_p(this),this.a=new VT,bsn(this,n),NH(this.a,n)}function g5(){LA(this),this.b=new LI(xQn,xQn),this.a=new LI(DQn,DQn)}function p5(n,t){this.c=0,this.b=t,dO.call(this,n,17493),this.a=this.c}function v5(n){m5(),Wet||(this.c=n,this.e=!0,this.a=new $p)}function m5(){m5=O,Wet=!0,Uet=!1,Xet=!1,Qet=!1,Vet=!1}function y5(n,t){return!!iL(t,149)&&pK(n.c,_B(t,149).c)}function k5(n,t){var e;return e=0,n&&(e+=n.f.a/2),t&&(e+=t.f.a/2),e}function j5(n,t){return _B(hnn(n.d,t),23)||_B(hnn(n.e,t),23)}function E5(n){this.b=n,CL.call(this,n),this.a=_B(van(this.b.a,4),126)}function T5(n){this.b=n,rx.call(this,n),this.a=_B(van(this.b.a,4),126)}function M5(n){return n.t||(n.t=new bp(n),uln(new Ly(n),0,n.t)),n.t}function S5(){return Kfn(),Mun(Hk(UPt,1),OVn,103,0,[_Pt,KPt,RPt,DPt,FPt])}function P5(){return ipn(),Mun(Hk(QIt,1),OVn,249,0,[_It,BIt,RIt,KIt,FIt])}function I5(){return epn(),Mun(Hk(yMt,1),OVn,175,0,[oMt,uMt,cMt,sMt,aMt])}function C5(){return OSn(),Mun(Hk(qTt,1),OVn,316,0,[tTt,eTt,cTt,iTt,rTt])}function O5(){return $vn(),Mun(Hk(Cvt,1),OVn,315,0,[vvt,dvt,gvt,wvt,pvt])}function A5(){return Xvn(),Mun(Hk(Sht,1),OVn,335,0,[vht,pht,yht,kht,mht])}function $5(){return VLn(),Mun(Hk(qEt,1),OVn,355,0,[NEt,LEt,DEt,xEt,REt])}function L5(){return AEn(),Mun(Hk(Dst,1),OVn,363,0,[Est,Mst,Sst,Tst,jst])}function N5(){return jbn(),Mun(Hk(tvt,1),OVn,163,0,[Blt,Rlt,Klt,_lt,Flt])}function x5(){var n,t;x5=O,tE(),t=new kv,Y$t=t,n=new Im,Z$t=n}function D5(n){var t;return n.c||iL(t=n.r,88)&&(n.c=_B(t,26)),n.c}function R5(n){return n.e=3,n.d=n.Yb(),2!=n.e&&(n.e=0,!0)}function K5(n){return E$(n&TQn,n>>22&TQn,n<0?MQn:0)}function _5(n){var t,e,i;for(e=0,i=(t=n).length;e0?kdn(n,t):Pxn(n,-t)}function q5(n,t){return 0==t||0==n.e?n:t>0?Pxn(n,t):kdn(n,-t)}function G5(n){if(bAn(n))return n.c=n.a,n.a.Pb();throw Fp(new vv)}function z5(n){var t,e;return t=n.c.i,e=n.d.i,t.k==(cSn(),Eut)&&e.k==Eut}function U5(n){var t;return Ban(t=new lJ,n),oon(t,(FXn(),ggt),null),t}function X5(n,t,e){var i;return(i=n.Yg(t))>=0?n._g(i,e,!0):iOn(n,t,e)}function W5(n,t,e,i){var r;for(r=0;rt)throw Fp(new Cy(bIn(n,t,"index")));return n}function b6(n,t,e,i){var r;return gTn(r=L8(INt,oQn,25,t,15,1),n,t,e,i),r}function w6(n,t){var e;e=n.q.getHours()+(t/60|0),n.q.setMinutes(t),hBn(n,e)}function d6(n,t){return i.Math.min(U8(t.a,n.d.d.c),U8(t.b,n.d.d.c))}function g6(n,t){return zC(t)?null==t?wAn(n.f,null):Han(n.g,t):wAn(n.f,t)}function p6(n){this.c=n,this.a=new Ub(this.c.a),this.b=new Ub(this.c.b)}function v6(){this.e=new $p,this.c=new $p,this.d=new $p,this.b=new $p}function m6(){this.g=new _v,this.b=new _v,this.a=new $p,this.k=new $p}function y6(n,t,e){this.a=n,this.c=t,this.d=e,UB(t.e,this),UB(e.b,this)}function k6(n,t){wO.call(this,t.rd(),-6&t.qd()),mW(n),this.a=n,this.b=t}function j6(n,t){dO.call(this,t.rd(),-6&t.qd()),mW(n),this.a=n,this.b=t}function E6(n,t){gO.call(this,t.rd(),-6&t.qd()),mW(n),this.a=n,this.b=t}function T6(n,t,e){this.a=n,this.b=t,this.c=e,UB(n.t,this),UB(t.i,this)}function M6(){this.b=new VT,this.a=new VT,this.b=new VT,this.a=new VT}function S6(){S6=O,jMt=new cp("org.eclipse.elk.labels.labelManager")}function P6(){P6=O,nst=new tR("separateLayerConnections",(Pun(),rst))}function I6(){I6=O,Eyt=new cI("REGULAR",0),jyt=new cI("CRITICAL",1)}function C6(){C6=O,Jvt=new zP("STACKED",0),Qvt=new zP("SEQUENCED",1)}function O6(){O6=O,YEt=new jI("FIXED",0),JEt=new jI("CENTER_NODE",1)}function A6(n,t){var e;return e=LGn(n,t),n.b=new prn(e.c.length),vqn(n,e)}function $6(n,t,e){return++n.e,--n.f,_B(n.d[t].$c(e),133).dd()}function L6(n){var t;return n.a||iL(t=n.r,148)&&(n.a=_B(t,148)),n.a}function N6(n){return n.a?n.e?N6(n.e):null:n}function x6(n,t){return n.pt.p?-1:0}function D6(n,t){return mW(t),n.c=0,"Initial capacity must not be negative")}function J6(){J6=O,Uit=hhn((Ntn(),Mun(Hk(Xit,1),OVn,232,0,[Hit,qit,Git])))}function Y6(){Y6=O,Zit=hhn((Q9(),Mun(Hk(nrt,1),OVn,461,0,[Vit,Wit,Qit])))}function Z6(){Z6=O,crt=hhn((H7(),Mun(Hk(Irt,1),OVn,462,0,[irt,ert,trt])))}function n8(){n8=O,Jet=hhn((Bsn(),Mun(Hk(Yet,1),OVn,132,0,[qet,Get,zet])))}function t8(){t8=O,Aat=hhn((B7(),Mun(Hk(Fat,1),OVn,379,0,[Iat,Pat,Cat])))}function e8(){e8=O,wut=hhn((_fn(),Mun(Hk(put,1),OVn,423,0,[lut,fut,hut])))}function i8(){i8=O,fht=hhn((Iin(),Mun(Hk(dht,1),OVn,314,0,[oht,uht,sht])))}function r8(){r8=O,ght=hhn((cin(),Mun(Hk(jht,1),OVn,337,0,[lht,wht,bht])))}function c8(){c8=O,$ht=hhn((Qun(),Mun(Hk(_ht,1),OVn,450,0,[Cht,Iht,Oht])))}function a8(){a8=O,Rst=hhn((Srn(),Mun(Hk(Ust,1),OVn,361,0,[xst,Nst,Lst])))}function u8(){u8=O,Ift=hhn((q7(),Mun(Hk(Aft,1),OVn,303,0,[Mft,Sft,Tft])))}function o8(){o8=O,Eft=hhn((Dan(),Mun(Hk(Pft,1),OVn,292,0,[yft,kft,mft])))}function s8(){s8=O,uvt=hhn((Ehn(),Mun(Hk(lvt,1),OVn,378,0,[ivt,rvt,cvt])))}function h8(){h8=O,Vvt=hhn((Fcn(),Mun(Hk(Yvt,1),OVn,375,0,[zvt,Uvt,Xvt])))}function f8(){f8=O,xvt=hhn((pon(),Mun(Hk(Kvt,1),OVn,339,0,[$vt,Avt,Lvt])))}function l8(){l8=O,Gvt=hhn((rin(),Mun(Hk(Wvt,1),OVn,452,0,[Hvt,Fvt,Bvt])))}function b8(){b8=O,wmt=hhn((Oun(),Mun(Hk(Tmt,1),OVn,377,0,[fmt,lmt,hmt])))}function w8(){w8=O,rmt=hhn((Gsn(),Mun(Hk(omt,1),OVn,336,0,[nmt,tmt,emt])))}function d8(){d8=O,smt=hhn((bcn(),Mun(Hk(bmt,1),OVn,338,0,[umt,cmt,amt])))}function g8(){g8=O,$mt=hhn((ain(),Mun(Hk(Lmt,1),OVn,454,0,[Imt,Cmt,Omt])))}function p8(){p8=O,ejt=hhn((Sbn(),Mun(Hk(cjt,1),OVn,442,0,[njt,Ykt,Zkt])))}function v8(){v8=O,fjt=hhn((Fsn(),Mun(Hk(Hjt,1),OVn,380,0,[ujt,ojt,sjt])))}function m8(){m8=O,nEt=hhn((Tbn(),Mun(Hk($Et,1),OVn,381,0,[Jjt,Yjt,Qjt])))}function y8(){y8=O,Wjt=hhn((_cn(),Mun(Hk(Vjt,1),OVn,293,0,[zjt,Ujt,Gjt])))}function k8(){k8=O,GEt=hhn((Mbn(),Mun(Hk(UEt,1),OVn,437,0,[FEt,BEt,HEt])))}function j8(){j8=O,mIt=hhn((cfn(),Mun(Hk(TIt,1),OVn,334,0,[gIt,dIt,pIt])))}function E8(){E8=O,XPt=hhn((xtn(),Mun(Hk(YPt,1),OVn,272,0,[qPt,GPt,zPt])))}function T8(){return WEn(),Mun(Hk(rCt,1),OVn,98,0,[VIt,WIt,XIt,GIt,UIt,zIt])}function M8(n,t){return!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),edn(n.o,t)}function S8(n){return!n.g&&(n.g=new oo),!n.g.d&&(n.g.d=new hp(n)),n.g.d}function P8(n){return!n.g&&(n.g=new oo),!n.g.a&&(n.g.a=new fp(n)),n.g.a}function I8(n){return!n.g&&(n.g=new oo),!n.g.b&&(n.g.b=new sp(n)),n.g.b}function C8(n){return!n.g&&(n.g=new oo),!n.g.c&&(n.g.c=new lp(n)),n.g.c}function O8(n,t,e){var i,r;for(r=new Can(t,n),i=0;ie||t=0?n._g(e,!0,!0):iOn(n,t,!0)}function M9(n,t){return Mln(Hy(ED(pMn(n,(oWn(),jlt)))),Hy(ED(pMn(t,jlt))))}function S9(){S9=O,Gkt=agn(agn(KM(new _2,(qyn(),Dyt)),(NPn(),Wyt)),Gyt)}function P9(n,t,e){var i;return i=$on(n,t,e),n.b=new prn(i.c.length),uDn(n,i)}function I9(n){if(n.b<=0)throw Fp(new vv);return--n.b,n.a-=n.c.c,tln(n.a)}function C9(n){var t;if(!n.a)throw Fp(new hV);return t=n.a,n.a=QY(n.a),t}function O9(n){for(;!n.a;)if(!jK(n.c,new dw(n)))return!1;return!0}function A9(n){return vX(n),iL(n,198)?_B(n,198):new al(n)}function $9(n){L9(),_B(n.We((uWn(),sPt)),174).Fc((hCn(),tCt)),n.Ye(oPt,null)}function L9(){L9=O,ZTt=new bu,tMt=new wu,nMt=gsn((uWn(),oPt),ZTt,BSt,tMt)}function N9(){N9=O,ijt=new dI("LEAF_NUMBER",0),rjt=new dI("NODE_SIZE",1)}function x9(n,t,e){n.a=t,n.c=e,n.b.a.$b(),vQ(n.d),n.e.a.c=L8(Cnt,FWn,1,0,5,1)}function D9(n){n.a=L8(INt,oQn,25,n.b+1,15,1),n.c=L8(INt,oQn,25,n.b,15,1),n.d=0}function R9(n,t){n.a.ue(t.d,n.b)>0&&(UB(n.c,new pH(t.c,t.d,n.d)),n.b=t.d)}function K9(n,t){if(null==n.g||t>=n.i)throw Fp(new AO(t,n.i));return n.g[t]}function _9(n,t,e){if(Lsn(n,e),null!=e&&!n.wj(e))throw Fp(new hv);return e}function F9(n){var t;if(n.Ek())for(t=n.i-1;t>=0;--t)Utn(n,t);return $3(n)}function B9(n){var t,e;if(!n.b)return null;for(e=n.b;t=e.a[0];)e=t;return e}function H9(n,t){var e;return i4(t),(e=p7(n.slice(0,t),n)).length=t,e}function q9(n,t,e,i){MQ(),i=i||fet,wIn(n.slice(t,e),n,t,e,-t,i)}function G9(n,t,e,i,r){return t<0?iOn(n,e,i):_B(e,66).Nj().Pj(n,n.yh(),t,i,r)}function z9(n){return iL(n,172)?""+_B(n,172).a:null==n?null:_bn(n)}function U9(n){return iL(n,172)?""+_B(n,172).a:null==n?null:_bn(n)}function X9(n,t){if(t.a)throw Fp(new by(PJn));jU(n.a,t),t.a=n,!n.j&&(n.j=t)}function W9(n,t){gO.call(this,t.rd(),-16449&t.qd()),mW(n),this.a=n,this.c=t}function V9(n,t){var e,i;return i=t/n.c.Hd().gc()|0,e=t%n.c.Hd().gc(),G6(n,i,e)}function Q9(){Q9=O,Vit=new HS(iYn,0),Wit=new HS(nYn,1),Qit=new HS(rYn,2)}function J9(){J9=O,$et=new wS("All",0),Let=new AA,Net=new C$,xet=new $A}function Y9(){Y9=O,Ret=hhn((J9(),Mun(Hk(Ket,1),OVn,297,0,[$et,Let,Net,xet])))}function Z9(){Z9=O,eut=hhn((Cun(),Mun(Hk(but,1),OVn,405,0,[Jat,nut,Yat,Zat])))}function n7(){n7=O,Rrt=hhn((Nan(),Mun(Hk(Hrt,1),OVn,406,0,[xrt,$rt,Lrt,Nrt])))}function t7(){t7=O,qrt=hhn((Fpn(),Mun(Hk(Grt,1),OVn,323,0,[_rt,Krt,Frt,Brt])))}function e7(){e7=O,tct=hhn((Bpn(),Mun(Hk(ict,1),OVn,394,0,[Jrt,Qrt,Yrt,Zrt])))}function i7(){i7=O,Fyt=hhn((qyn(),Mun(Hk(Byt,1),OVn,393,0,[xyt,Dyt,Ryt,Kyt])))}function r7(){r7=O,ast=hhn((Pun(),Mun(Hk(dst,1),OVn,360,0,[rst,est,ist,tst])))}function c7(){c7=O,qjt=hhn((Imn(),Mun(Hk(Xjt,1),OVn,340,0,[Bjt,_jt,Fjt,Kjt])))}function a7(){a7=O,kst=hhn((Iun(),Mun(Hk(Pst,1),OVn,411,0,[gst,pst,vst,mst])))}function u7(){u7=O,bvt=hhn((fvn(),Mun(Hk(mvt,1),OVn,197,0,[hvt,fvt,svt,ovt])))}function o7(){o7=O,sOt=hhn((_sn(),Mun(Hk(lOt,1),OVn,396,0,[cOt,aOt,rOt,uOt])))}function s7(){s7=O,MIt=hhn((zyn(),Mun(Hk(xIt,1),OVn,285,0,[EIt,yIt,kIt,jIt])))}function h7(){h7=O,ZPt=hhn((Ebn(),Mun(Hk(aIt,1),OVn,218,0,[JPt,VPt,WPt,QPt])))}function f7(){f7=O,eOt=hhn((Kwn(),Mun(Hk(iOt,1),OVn,311,0,[nOt,JCt,ZCt,YCt])))}function l7(){l7=O,_Ct=hhn((pdn(),Mun(Hk(VCt,1),OVn,374,0,[DCt,RCt,xCt,NCt])))}function b7(){b7=O,BBn(),_Lt=xQn,KLt=DQn,BLt=new $b(xQn),FLt=new $b(DQn)}function w7(){w7=O,Hht=new IP(WZn,0),Bht=new IP("IMPROVE_STRAIGHTNESS",1)}function d7(n,t){return oH(),UB(n,new eC(t,tln(t.e.c.length+t.g.c.length)))}function g7(n,t){return oH(),UB(n,new eC(t,tln(t.e.c.length+t.g.c.length)))}function p7(n,t){return 10!=gnn(t)&&Mun(Zon(t),t.hm,t.__elementTypeId$,gnn(t),n),n}function v7(n,t){var e;return-1!=(e=k7(n,t,0))&&(u6(n,e),!0)}function m7(n,t){var e;return(e=_B(g6(n.e,t),387))?(xH(e),e.e):null}function y7(n){var t;return QO(n)&&(t=0-n,!isNaN(t))?t:can(ron(n))}function k7(n,t,e){for(;e=0?Jpn(n,e,!0,!0):iOn(n,t,!0)}function J7(n,t){var e,i;return EM(),e=s3(n),i=s3(t),!!e&&!!i&&!Dpn(e.k,i.k)}function Y7(n,t){Men(n,null==t||UK((mW(t),t))||isNaN((mW(t),t))?0:(mW(t),t))}function Z7(n,t){Sen(n,null==t||UK((mW(t),t))||isNaN((mW(t),t))?0:(mW(t),t))}function nnn(n,t){Ten(n,null==t||UK((mW(t),t))||isNaN((mW(t),t))?0:(mW(t),t))}function tnn(n,t){Een(n,null==t||UK((mW(t),t))||isNaN((mW(t),t))?0:(mW(t),t))}function enn(n){(this.q?this.q:(TQ(),TQ(),oet)).Ac(n.q?n.q:(TQ(),TQ(),oet))}function inn(n,t){return iL(t,99)&&0!=(_B(t,18).Bb&_Qn)?new LO(t,n):new Can(t,n)}function rnn(n,t){return iL(t,99)&&0!=(_B(t,18).Bb&_Qn)?new LO(t,n):new Can(t,n)}function cnn(n,t){Xrt=new it,nct=t,_B((Urt=n).b,65),D8(Urt,Xrt,null),cqn(Urt)}function ann(n,t,e){var i;return i=n.g[t],yL(n,t,n.oi(t,e)),n.gi(t,e,i),n.ci(),i}function unn(n,t){var e;return(e=n.Xc(t))>=0&&(n.$c(e),!0)}function onn(n){var t;return n.d!=n.r&&(t=Pkn(n),n.e=!!t&&t.Cj()==k9n,n.d=t),n.e}function snn(n,t){var e;for(vX(n),vX(t),e=!1;t.Ob();)e|=n.Fc(t.Pb());return e}function hnn(n,t){var e;return(e=_B(xX(n.e,t),387))?(cL(n,e),e.e):null}function fnn(n){var t,e;return t=n/60|0,0==(e=n%60)?""+t:t+":"+e}function lnn(n,t){return Wln(n),new xq(n,new DK(new E6(t,n.a)))}function bnn(n,t){var e=n.a[t],i=(Jun(),stt)[typeof e];return i?i(e):mhn(typeof e)}function wnn(n){switch(n.g){case 0:return NWn;case 1:return-1;default:return 0}}function dnn(n){return Dkn(n,(z7(),wtt))<0?-SN(ron(n)):n.l+n.m*PQn+n.h*IQn}function gnn(n){return null==n.__elementTypeCategory$?10:n.__elementTypeCategory$}function pnn(n){var t;return null!=(t=0==n.b.c.length?null:Lq(n.b,0))&&orn(n,0),t}function vnn(n,t){for(;t[0]=0;)++t[0]}function mnn(n,t){this.e=t,this.a=Xan(n),this.a<54?this.f=y2(n):this.c=Ygn(n)}function ynn(n,t,e,i){lWn(),Cp.call(this,26),this.c=n,this.a=t,this.d=e,this.b=i}function knn(n,t,e){var i,r;for(i=10,r=0;rn.a[i]&&(i=e);return i}function Ann(n,t){var e;return 0==(e=Pbn(n.e.c,t.e.c))?Mln(n.e.d,t.e.d):e}function $nn(n,t){return 0==t.e||0==n.e?net:(OOn(),CNn(n,t))}function Lnn(n,t){if(!n)throw Fp(new Ry(VNn("Enum constant undefined: %s",t)))}function Nnn(){Nnn=O,cut=new St,aut=new Tt,iut=new At,rut=new $t,uut=new Lt}function xnn(){xnn=O,git=new _S("BY_SIZE",0),pit=new _S("BY_SIZE_AND_SHAPE",1)}function Dnn(){Dnn=O,Nct=new zS("EADES",0),xct=new zS("FRUCHTERMAN_REINGOLD",1)}function Rnn(){Rnn=O,Tht=new MP("READING_DIRECTION",0),Mht=new MP("ROTATION",1)}function Knn(){Knn=O,Eht=hhn((Xvn(),Mun(Hk(Sht,1),OVn,335,0,[vht,pht,yht,kht,mht])))}function _nn(){_nn=O,yvt=hhn(($vn(),Mun(Hk(Cvt,1),OVn,315,0,[vvt,dvt,gvt,wvt,pvt])))}function Fnn(){Fnn=O,Ist=hhn((AEn(),Mun(Hk(Dst,1),OVn,363,0,[Est,Mst,Sst,Tst,jst])))}function Bnn(){Bnn=O,qlt=hhn((jbn(),Mun(Hk(tvt,1),OVn,163,0,[Blt,Rlt,Klt,_lt,Flt])))}function Hnn(){Hnn=O,uTt=hhn((OSn(),Mun(Hk(qTt,1),OVn,316,0,[tTt,eTt,cTt,iTt,rTt])))}function qnn(){qnn=O,fMt=hhn((epn(),Mun(Hk(yMt,1),OVn,175,0,[oMt,uMt,cMt,sMt,aMt])))}function Gnn(){Gnn=O,_Et=hhn((VLn(),Mun(Hk(qEt,1),OVn,355,0,[NEt,LEt,DEt,xEt,REt])))}function znn(){znn=O,Bat=hhn((vMn(),Mun(Hk(Gat,1),OVn,356,0,[xat,Dat,Rat,Kat,_at])))}function Unn(){Unn=O,HPt=hhn((Kfn(),Mun(Hk(UPt,1),OVn,103,0,[_Pt,KPt,RPt,DPt,FPt])))}function Xnn(){Xnn=O,qIt=hhn((ipn(),Mun(Hk(QIt,1),OVn,249,0,[_It,BIt,RIt,KIt,FIt])))}function Wnn(){Wnn=O,ICt=hhn((mUn(),Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt])))}function Vnn(n,t){var e;return(e=_B(xX(n.a,t),134))||(e=new Zn,XW(n.a,t,e)),e}function Qnn(n){var t;return!!(t=_B(pMn(n,(oWn(),xft)),305))&&t.a==n}function Jnn(n){var t;return!!(t=_B(pMn(n,(oWn(),xft)),305))&&t.i==n}function Ynn(n,t){return mW(t),Nz(n),!!n.d.Ob()&&(t.td(n.d.Pb()),!0)}function Znn(n){return Xhn(n,NWn)>0?NWn:Xhn(n,RVn)<0?RVn:bG(n)}function ntn(n){return n<3?(hin(n,PVn),n+1):n=0&&t=-.01&&n.a<=sYn&&(n.a=0),n.b>=-.01&&n.b<=sYn&&(n.b=0),n}function rtn(n,t){return t==(i_(),i_(),Eet)?n.toLocaleLowerCase():n.toLowerCase()}function ctn(n){return(0!=(2&n.i)?"interface ":0!=(1&n.i)?"":"class ")+(kD(n),n.o)}function atn(n){var t;t=new Om,s9((!n.q&&(n.q=new nU(XAt,n,11,10)),n.q),t)}function utn(n,t){var e;return e=t>0?t-1:t,Oj(Aj(Ken(AH(new zm,e),n.n),n.j),n.k)}function otn(n,t,e,i){n.j=-1,BOn(n,kPn(n,t,e),(JM(),_B(t,66).Mj().Ok(i)))}function stn(n){this.g=n,this.f=new $p,this.a=i.Math.min(this.g.c.c,this.g.d.c)}function htn(n){this.b=new $p,this.a=new $p,this.c=new $p,this.d=new $p,this.e=n}function ftn(n,t){this.a=new Lp,this.e=new Lp,this.b=(Ehn(),cvt),this.c=n,this.b=t}function ltn(n,t,e){$R.call(this),Ltn(this),this.a=n,this.c=e,this.b=t.d,this.f=t.e}function btn(n){this.d=n,this.c=n.c.vc().Kc(),this.b=null,this.a=null,this.e=(ey(),qnt)}function wtn(n){if(n<0)throw Fp(new Ry("Illegal Capacity: "+n));this.g=this.ri(n)}function dtn(n,t){if(0>n||n>t)throw Fp(new jk("fromIndex: 0, toIndex: "+n+oJn+t))}function gtn(n){var t;if(n.a==n.b.a)throw Fp(new vv);return t=n.a,n.c=t,n.a=n.a.e,t}function ptn(n){var t;Ex(!!n.c),t=n.c.a,Ctn(n.d,n.c),n.b==n.c?n.b=t:--n.a,n.c=null}function vtn(n,t){var e;return Wln(n),e=new gQ(n,n.a.rd(),4|n.a.qd(),t),new xq(n,e)}function mtn(n,t){var e,i;return(e=_B(hfn(n.d,t),14))?(i=t,n.e.pc(i,e)):null}function ytn(n,t){var e;for(e=n.Kc();e.Ob();)oon(_B(e.Pb(),70),(oWn(),clt),t)}function ktn(n){var t;return(t=Hy(ED(pMn(n,(FXn(),rgt)))))<0&&oon(n,rgt,t=0),t}function jtn(n,t,e){var r;Kkn(e,r=i.Math.max(0,n.b/2-.5),1),UB(t,new tP(e,r))}function Etn(n,t,e){return SY(FH(n.a.e[_B(t.a,10).p]-n.a.e[_B(e.a,10).p]))}function Ttn(n,t,e,i,r,c){var a;TZ(a=U5(i),r),EZ(a,c),QCn(n.a,i,new A_(a,t,e.f))}function Mtn(n,t){var e;if(!(e=$Nn(n.Tg(),t)))throw Fp(new Ry(e6n+t+c6n));return e}function Stn(n,t){var e;for(e=n;QY(e);)if((e=QY(e))==t)return!0;return!1}function Ptn(n,t){var e,i,r;for(i=t.a.cd(),e=_B(t.a.dd(),14).gc(),r=0;r0&&(n.a/=t,n.b/=t),n}function Gtn(n){var t;return n.w?n.w:((t=X1(n))&&!t.kh()&&(n.w=t),t)}function ztn(n){var t;return null==n?null:XTn(t=_B(n,190),t.length)}function Utn(n,t){if(null==n.g||t>=n.i)throw Fp(new AO(t,n.i));return n.li(t,n.g[t])}function Xtn(n){var t,e;for(t=n.a.d.j,e=n.c.d.j;t!=e;)arn(n.b,t),t=Eln(t);arn(n.b,t)}function Wtn(n){var t;for(t=0;t=14&&t<=16)),n}function ten(n,t,e){var i=function(){return n.apply(i,arguments)};return t.apply(i,e),i}function een(n,t,e){var i,r;i=t;do{r=Hy(n.p[i.p])+e,n.p[i.p]=r,i=n.a[i.p]}while(i!=t)}function ien(n,t){var e,i;i=n.a,e=Wfn(n,t,null),i!=t&&!n.e&&(e=rzn(n,t,e)),e&&e.Fi()}function ren(n,t){return o$(),ein(DVn),i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)}function cen(n,t){return o$(),ein(DVn),i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)}function aen(n,t){return RMn(),k$(n.b.c.length-n.e.c.length,t.b.c.length-t.e.c.length)}function uen(n,t){return Jj(Qrn(n,t,bG(ibn(TVn,eV(bG(ibn(null==t?0:Yon(t),MVn)),15)))))}function oen(){oen=O,Cut=hhn((cSn(),Mun(Hk(Out,1),OVn,267,0,[Sut,Mut,Eut,Put,Tut,jut])))}function sen(){sen=O,ZMt=hhn((lEn(),Mun(Hk(BPt,1),OVn,291,0,[JMt,QMt,VMt,XMt,UMt,WMt])))}function hen(){hen=O,LMt=hhn((lvn(),Mun(Hk(YMt,1),OVn,248,0,[SMt,CMt,OMt,AMt,PMt,IMt])))}function fen(){fen=O,eht=hhn((OPn(),Mun(Hk(cht,1),OVn,227,0,[Jst,Zst,Qst,Yst,nht,Vst])))}function len(){len=O,aft=hhn((QMn(),Mun(Hk(pft,1),OVn,275,0,[ift,nft,rft,eft,tft,Zht])))}function ben(){ben=O,Yht=hhn((_jn(),Mun(Hk(cft,1),OVn,274,0,[Wht,Xht,Qht,Uht,Vht,zht])))}function wen(){wen=O,evt=hhn((jTn(),Mun(Hk(avt,1),OVn,313,0,[Zpt,Jpt,Vpt,Qpt,nvt,Ypt])))}function den(){den=O,Fht=hhn((wSn(),Mun(Hk(qht,1),OVn,276,0,[Nht,Lht,Dht,xht,Kht,Rht])))}function gen(){gen=O,Qyt=hhn((NPn(),Mun(Hk(Rkt,1),OVn,327,0,[Wyt,Gyt,Uyt,zyt,Xyt,qyt])))}function pen(){pen=O,cCt=hhn((hCn(),Mun(Hk(PCt,1),OVn,273,0,[eCt,nCt,tCt,ZIt,YIt,iCt])))}function ven(){ven=O,uIt=hhn((YTn(),Mun(Hk(vIt,1),OVn,312,0,[rIt,eIt,cIt,nIt,iIt,tIt])))}function men(){return YAn(),Mun(Hk(HIt,1),OVn,93,0,[PIt,SIt,CIt,NIt,LIt,$It,OIt,AIt,IIt])}function yen(n,t){var e;e=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,0,e,n.a))}function ken(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,1,e,n.b))}function jen(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,3,e,n.b))}function Een(n,t){var e;e=n.f,n.f=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,3,e,n.f))}function Ten(n,t){var e;e=n.g,n.g=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,4,e,n.g))}function Men(n,t){var e;e=n.i,n.i=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,5,e,n.i))}function Sen(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,6,e,n.j))}function Pen(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,1,e,n.j))}function Ien(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,4,e,n.c))}function Cen(n,t){var e;e=n.k,n.k=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new s4(n,2,e,n.k))}function Oen(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new h4(n,2,e,n.d))}function Aen(n,t){var e;e=n.s,n.s=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new h4(n,4,e,n.s))}function $en(n,t){var e;e=n.t,n.t=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new h4(n,5,e,n.t))}function Len(n,t){var e;e=n.F,n.F=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,5,e,t))}function Nen(n,t){var e;return(e=_B(xX((YM(),gAt),n),55))?e.xj(t):L8(Cnt,FWn,1,t,5,1)}function xen(n,t){var e;return t in n.a&&(e=qY(n,t).he())?e.a:null}function Den(n,t){var e,i;return Zj(),i=new uo,!!t&&PNn(i,t),Lin(e=i,n),e}function Ren(n,t,e){if(Lsn(n,e),!n.Bk()&&null!=e&&!n.wj(e))throw Fp(new hv);return e}function Ken(n,t){return n.n=t,n.n?(n.f=new $p,n.e=new $p):(n.f=null,n.e=null),n}function _en(n,t,e,i,r,c){var a;return Wen(e,a=pX(n,t)),a.i=r?8:0,a.f=i,a.e=r,a.g=c,a}function Fen(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=1,this.c=n,this.a=e}function Ben(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=2,this.c=n,this.a=e}function Hen(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=6,this.c=n,this.a=e}function qen(n,t,e,i,r){this.d=t,this.k=i,this.f=r,this.o=-1,this.p=7,this.c=n,this.a=e}function Gen(n,t,e,i,r){this.d=t,this.j=i,this.e=r,this.o=-1,this.p=4,this.c=n,this.a=e}function zen(n,t){var e,i,r,c;for(r=0,c=(i=t).length;r=0),egn(n.d,n.c)<0&&(n.a=n.a-1&n.d.a.length-1,n.b=n.d.c),n.c=-1}function tin(n){return n.a<54?n.f<0?-1:n.f>0?1:0:(!n.c&&(n.c=vhn(n.f)),n.c).e}function ein(n){if(!(n>=0))throw Fp(new Ry("tolerance ("+n+") must be >= 0"));return n}function iin(){return iMt||msn(iMt=new IRn,Mun(Hk(Rit,1),FWn,130,0,[new $f])),iMt}function rin(){rin=O,Hvt=new qP(oYn,0),Fvt=new qP("INPUT",1),Bvt=new qP("OUTPUT",2)}function cin(){cin=O,lht=new EP("ARD",0),wht=new EP("MSD",1),bht=new EP("MANUAL",2)}function ain(){ain=O,Imt=new VP("BARYCENTER",0),Cmt=new VP(k1n,1),Omt=new VP(j1n,2)}function uin(n,t){var e;if(e=n.gc(),t<0||t>e)throw Fp(new ZR(t,e));return new xK(n,t)}function oin(n,t){var e;return iL(t,42)?n.c.Mc(t):(e=edn(n,t),Udn(n,t),e)}function sin(n,t,e){return Phn(n,t),$rn(n,e),Aen(n,0),$en(n,1),Yfn(n,!0),Vfn(n,!0),n}function hin(n,t){if(n<0)throw Fp(new Ry(t+" cannot be negative but was: "+n));return n}function fin(n,t){var e,i;for(e=0,i=n.gc();e0?_B(Lq(e.a,i-1),10):null}function Oin(n,t){var e;e=n.k,n.k=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,2,e,n.k))}function Ain(n,t){var e;e=n.f,n.f=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,8,e,n.f))}function $in(n,t){var e;e=n.i,n.i=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,7,e,n.i))}function Lin(n,t){var e;e=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,8,e,n.a))}function Nin(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,0,e,n.b))}function xin(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,0,e,n.b))}function Din(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,1,e,n.c))}function Rin(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,1,e,n.c))}function Kin(n,t){var e;e=n.c,n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,4,e,n.c))}function _in(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,1,e,n.d))}function Fin(n,t){var e;e=n.D,n.D=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,2,e,n.D))}function Bin(n,t){n.r>0&&n.c0&&0!=n.g&&Bin(n.i,t/n.r*n.i.d))}function Hin(n,t,e){var i;n.b=t,n.a=e,i=512==(512&n.a)?new Km:new Dh,n.c=EDn(i,n.b,n.a)}function qin(n,t){return Oxn(n.e,t)?(JM(),onn(t)?new hq(t,n):new LC(t,n)):new DC(t,n)}function Gin(n,t){return Qj(Jrn(n.a,t,bG(ibn(TVn,eV(bG(ibn(null==t?0:Yon(t),MVn)),15)))))}function zin(n,t,e){return L7(n,new sw(t),new un,new hw(e),Mun(Hk(Yet,1),OVn,132,0,[]))}function Uin(n){return 0>n?new XT:new OD(null,new p5(n+1,n))}function Xin(n,t){var e;return TQ(),e=new zT(1),zC(n)?pZ(e,n,t):yIn(e.f,n,t),new zb(e)}function Win(n,t){var e,i;return(e=n.o+n.p)<(i=t.o+t.p)?-1:e==i?0:1}function Vin(n){var t;return iL(t=pMn(n,(oWn(),blt)),160)?pwn(_B(t,160)):null}function Qin(n){var t;return(n=i.Math.max(n,2))>(t=mon(n))?(t<<=1)>0?t:IVn:t}function Jin(n){switch(cN(3!=n.e),n.e){case 2:return!1;case 0:return!0}return R5(n)}function Yin(n,t){var e;return!!iL(t,8)&&(e=_B(t,8),n.a==e.a&&n.b==e.b)}function Zin(n,t,e){var i,r;return r=t>>5,i=31&t,n0(yz(n.n[e][r],bG(vz(i,1))),3)}function nrn(n,t){var e,i;for(i=t.vc().Kc();i.Ob();)gjn(n,(e=_B(i.Pb(),42)).cd(),e.dd())}function trn(n,t){var e;e=new it,_B(t.b,65),_B(t.b,65),_B(t.b,65),Itn(t.a,new jB(n,e,t))}function ern(n,t){var e;e=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,21,e,n.b))}function irn(n,t){var e;e=n.d,n.d=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,11,e,n.d))}function rrn(n,t){var e;e=n.j,n.j=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,13,e,n.j))}function crn(n,t,e){var i,r,c;for(c=n.a.length-1,r=n.b,i=0;i>>31;0!=i&&(n[e]=i)}function Zrn(n,t){var e,i;for(TQ(),i=new $p,e=0;e0&&(this.g=this.ri(this.i+(this.i/8|0)+1),n.Qc(this.g))}function kcn(n,t){EH.call(this,z$t,n,t),this.b=this,this.a=rxn(n.Tg(),ttn(this.e.Tg(),this.c))}function jcn(n,t){var e,i;for(mW(t),i=t.vc().Kc();i.Ob();)e=_B(i.Pb(),42),n.zc(e.cd(),e.dd())}function Ecn(n,t,e){var i;for(i=e.Kc();i.Ob();)if(!H3(n,t,i.Pb()))return!1;return!0}function Tcn(n,t,e,i,r){var c;return e&&(c=Cwn(t.Tg(),n.c),r=e.gh(t,-1-(-1==c?i:c),null,r)),r}function Mcn(n,t,e,i,r){var c;return e&&(c=Cwn(t.Tg(),n.c),r=e.ih(t,-1-(-1==c?i:c),null,r)),r}function Scn(n){var t;if(-2==n.b){if(0==n.e)t=-1;else for(t=0;0==n.a[t];t++);n.b=t}return n.b}function Pcn(n){switch(n.g){case 2:return mUn(),SCt;case 4:return mUn(),aCt;default:return n}}function Icn(n){switch(n.g){case 1:return mUn(),TCt;case 3:return mUn(),uCt;default:return n}}function Ccn(n){var t,e,i;return n.j==(mUn(),uCt)&&(e=TN(t=GOn(n),aCt),(i=TN(t,SCt))||i&&e)}function Ocn(n){var t;return new VK(t=_B(n.e&&n.e(),9),_B(XU(t,t.length),9),t.length)}function Acn(n,t){ITn(t,m1n,1),Zbn(uM(new Mw((wM(),new FV(n,!1,!1,new Ft))))),FSn(t)}function $cn(n,t){return oN(),zC(n)?s6(n,TD(t)):GC(n)?jz(n,ED(t)):qC(n)?kz(n,jD(t)):n.wd(t)}function Lcn(n,t){t.q=n,n.d=i.Math.max(n.d,t.r),n.b+=t.d+(0==n.a.c.length?0:n.c),UB(n.a,t)}function Ncn(n,t){var e,i,r,c;return r=n.c,e=n.c+n.b,c=n.d,i=n.d+n.a,t.a>r&&t.ac&&t.b1||n.Ob())return++n.a,n.g=0,t=n.i,n.Ob(),t;throw Fp(new vv)}function Tan(n){var t;return r$(),cS(uyt,n)||((t=new ua).a=n,lR(uyt,n,t)),_B(aV(uyt,n),635)}function Man(n){var t,e,i;return e=0,(i=n)<0&&(i+=IQn,e=MQn),t=SY(i/PQn),E$(SY(i-t*PQn),t,e)}function San(n){var t,e,i;for(i=0,e=new WT(n.a);e.a>22),r=n.h+t.h+(i>>22),E$(e&TQn,i&TQn,r&MQn)}function oun(n,t){var e,i,r;return e=n.l-t.l,i=n.m-t.m+(e>>22),r=n.h-t.h+(i>>22),E$(e&TQn,i&TQn,r&MQn)}function sun(n){var t;return n<128?(!(t=(Eq(),Ett)[n])&&(t=Ett[n]=new Ab(n)),t):new Ab(n)}function hun(n){var t;return iL(n,78)?n:((t=n&&n.__java$exception)||av(t=new yhn(n)),t)}function fun(n){if(iL(n,186))return _B(n,118);if(n)return null;throw Fp(new Fy(n8n))}function lun(n,t){if(null==t)return!1;for(;n.a!=n.b;)if($fn(t,Rhn(n)))return!0;return!1}function bun(n){return!!n.a.Ob()||n.a==n.d&&(n.a=new T2(n.e.f),n.a.Ob())}function wun(n,t){var e;return 0!=(e=t.Pc()).length&&(ZB(n.c,n.c.length,e),!0)}function dun(n,t,e){var i,r;for(r=t.vc().Kc();r.Ob();)i=_B(r.Pb(),42),n.yc(i.cd(),i.dd(),e);return n}function gun(n,t){var e;for(e=new Ub(n.b);e.a=0,"Negative initial capacity"),gH(t>=0,"Non-positive load factor"),OU(this)}function Zun(n,t,e){return!(n>=128)&&QC(n<64?n0(vz(1,n),e):n0(vz(1,n-64),t),0)}function non(n,t){return!(!n||!t||n==t)&&Pbn(n.b.c,t.b.c+t.b.b)<0&&Pbn(t.b.c,n.b.c+n.b.b)<0}function ton(n){var t,e,i;return e=n.n,i=n.o,t=n.d,new GV(e.a-t.b,e.b-t.d,i.a+(t.b+t.c),i.b+(t.d+t.a))}function eon(n){var t,e,i,r;for(i=0,r=(e=n.a).length;i(i=n.gc()))throw Fp(new ZR(t,i));return n.hi()&&(e=YY(n,e)),n.Vh(t,e)}function uon(n,t,e){return null==e?(!n.q&&(n.q=new Lp),g6(n.q,t)):(!n.q&&(n.q=new Lp),XW(n.q,t,e)),n}function oon(n,t,e){return null==e?(!n.q&&(n.q=new Lp),g6(n.q,t)):(!n.q&&(n.q=new Lp),XW(n.q,t,e)),n}function son(n){var t,e;return Ban(e=new v6,n),oon(e,(Ern(),uat),n),nBn(n,e,t=new Lp),Tzn(n,e,t),e}function hon(n){var t,e,i;for(yDn(),e=L8(MMt,uVn,8,2,0,1),i=0,t=0;t<2;t++)i+=.5,e[t]=hmn(i,n);return e}function fon(n,t){var e,i,r;for(e=!1,i=n.a[t].length,r=0;r>=1);return t}function yon(n){var t,e;return 32==(e=JCn(n.h))?32==(t=JCn(n.m))?JCn(n.l)+32:t+20-10:e-12}function kon(n){var t;return null==(t=n.a[n.b])?null:(OX(n.a,n.b,null),n.b=n.b+1&n.a.length-1,t)}function jon(n){var t,e;return t=n.t-n.k[n.o.p]*n.d+n.j[n.o.p]>n.f,e=n.u+n.e[n.o.p]*n.d>n.f*n.s*n.d,t||e}function Eon(n,t,e){var i,r;return i=new F8(t,e),r=new q,n.b=Uxn(n,n.b,i,r),r.b||++n.c,n.b.b=!1,r.d}function Ton(n,t,e){var i,r,c;for(c=0,r=Afn(t,e).Kc();r.Ob();)i=_B(r.Pb(),11),XW(n.c,i,tln(c++))}function Mon(n){var t,e;for(e=new Ub(n.a.b);e.ae&&(e=n[t]);return e}function $on(n,t,e){var i;return yxn(n,t,i=new $p,(mUn(),aCt),!0,!1),yxn(n,e,i,SCt,!1,!1),i}function Lon(n,t,e){var i,r;return r=$2(t,"labels"),zAn((i=new wC(n,e)).a,i.b,r),r}function Non(n,t,e,i){var r;return(r=p$n(n,t,e,i))||!(r=rln(n,e,i))||Kqn(n,t,r)?r:null}function xon(n,t,e,i){var r;return(r=v$n(n,t,e,i))||!(r=cln(n,e,i))||Kqn(n,t,r)?r:null}function Don(n,t){var e;for(e=0;e1||t>=0&&n.b<3)}function Qon(n){var t,e;for(t=new mm,e=upn(n,0);e.b!=e.d.c;)Dx(t,0,new lA(_B(f3(e),8)));return t}function Jon(n){var t;for(t=new Ub(n.a.b);t.ai?1:0}function bsn(n,t){return!!fNn(n,t)&&(QCn(n.b,_B(pMn(t,(oWn(),zft)),21),t),NH(n.a,t),!0)}function wsn(n){var t,e;(t=_B(pMn(n,(oWn(),klt)),10))&&(v7((e=t.c).a,t),0==e.a.c.length&&v7(gW(t).b,e))}function dsn(n){return Wet?L8(Het,bJn,572,0,0,1):_B(Wgn(n.a,L8(Het,bJn,572,n.a.c.length,0,1)),842)}function gsn(n,t,e,i){return YW(),new oy(Mun(Hk(Fnt,1),mVn,42,0,[(qvn(n,t),new gT(n,t)),(qvn(e,i),new gT(e,i))]))}function psn(n,t,e){var i;return sin(i=new Om,t,e),s9((!n.q&&(n.q=new nU(XAt,n,11,10)),n.q),i),i}function vsn(n){var t,e,i,r;for(e=(r=sS(COt,n)).length,i=L8(Wtt,uVn,2,e,6,1),t=0;t=n.b.c.length||(ksn(n,2*t+1),(e=2*t+2)=0&&n[i]===t[i];i--);return i<0?0:uS(n0(n[i],GQn),n0(t[i],GQn))?-1:1}function Tsn(n,t){var e,i;for(i=upn(n,0);i.b!=i.d.c;)(e=_B(f3(i),214)).e.length>0&&(t.td(e),e.i&&dln(e))}function Msn(n,t){var e,i;return i=_B(van(n.a,4),126),e=L8(lAt,t9n,415,t,0,1),null!=i&&rHn(i,0,e,0,i.length),e}function Ssn(n,t){var e;return e=new eRn(0!=(256&n.f),n.i,n.a,n.d,0!=(16&n.f),n.j,n.g,t),null!=n.e||(e.c=n),e}function Psn(n,t){var e;for(e=n.Zb().Cc().Kc();e.Ob();)if(_B(e.Pb(),14).Hc(t))return!0;return!1}function Isn(n,t,e,i,r){var c,a;for(a=e;a<=r;a++)for(c=t;c<=i;c++)if(gmn(n,c,a))return!0;return!1}function Csn(n,t,e){var i,r,c,a;for(mW(e),a=!1,c=n.Zc(t),r=e.Kc();r.Ob();)i=r.Pb(),c.Rb(i),a=!0;return a}function Osn(n,t){var e;return n===t||!!iL(t,83)&&(e=_B(t,83),qSn(hz(n),e.vc()))}function Asn(n,t,e){var i,r;for(r=e.Kc();r.Ob();)if(i=_B(r.Pb(),42),n.re(t,i.dd()))return!0;return!1}function $sn(n,t,e){return n.d[t.p][e.p]||(tvn(n,t,e),n.d[t.p][e.p]=!0,n.d[e.p][t.p]=!0),n.a[t.p][e.p]}function Lsn(n,t){if(!n.ai()&&null==t)throw Fp(new Ry("The 'no null' constraint is violated"));return t}function Nsn(n,t){null==n.D&&null!=n.B&&(n.D=n.B,n.B=null),Fin(n,null==t?null:(mW(t),t)),n.C&&n.yk(null)}function xsn(n,t){return!(!n||n==t||!Ax(t,(oWn(),elt)))&&_B(pMn(t,(oWn(),elt)),10)!=n}function Dsn(n){switch(n.i){case 2:return!0;case 1:return!1;case-1:++n.c;default:return n.pl()}}function Rsn(n){switch(n.i){case-2:return!0;case-1:return!1;case 1:--n.c;default:return n.ql()}}function Ksn(n){RY.call(this,"The given string does not match the expected format for individual spacings.",n)}function _sn(){_sn=O,cOt=new iC("ELK",0),aOt=new iC("JSON",1),rOt=new iC("DOT",2),uOt=new iC("SVG",3)}function Fsn(){Fsn=O,ujt=new gI(WZn,0),ojt=new gI("RADIAL_COMPACTION",1),sjt=new gI("WEDGE_COMPACTION",2)}function Bsn(){Bsn=O,qet=new dS("CONCURRENT",0),Get=new dS("IDENTITY_FINISH",1),zet=new dS("UNORDERED",2)}function Hsn(){Hsn=O,lM(),act=new OO(_Yn,uct=ect),cct=new cp(FYn),oct=new cp(BYn),sct=new cp(HYn)}function qsn(){qsn=O,hst=new ji,fst=new Ei,sst=new Ti,ost=new Mi,mW(new Si),ust=new D}function Gsn(){Gsn=O,nmt=new UP("CONSERVATIVE",0),tmt=new UP("CONSERVATIVE_SOFT",1),emt=new UP("SLOPPY",2)}function zsn(){zsn=O,bIt=new UA(15),lIt=new zA((uWn(),zSt),bIt),wIt=wPt,oIt=rSt,sIt=DSt,fIt=_St,hIt=KSt}function Usn(n,t,e){var i,r;for(i=new VT,r=upn(e,0);r.b!=r.d.c;)NH(i,new lA(_B(f3(r),8)));Csn(n,t,i)}function Xsn(n){var t,e,i;for(t=0,i=L8(MMt,uVn,8,n.b,0,1),e=upn(n,0);e.b!=e.d.c;)i[t++]=_B(f3(e),8);return i}function Wsn(n){var t;return!n.a&&(n.a=new nU(zAt,n,9,5)),0!=(t=n.a).i?FM(_B(Utn(t,0),678)):null}function Vsn(n,t){var e;return e=ebn(n,t),uS(e0(n,t),0)|VC(e0(n,e),0)?e:ebn(fVn,e0(yz(e,63),1))}function Qsn(n,t){var e;e=null!=ppn((xwn(),Xpt))&&null!=t.wg()?Hy(ED(t.wg()))/Hy(ED(ppn(Xpt))):1,XW(n.b,t,e)}function Jsn(n,t){var e,i;return(e=_B(n.d.Bc(t),14))?((i=n.e.hc()).Gc(e),n.e.d-=e.gc(),e.$b(),i):null}function Ysn(n,t){var e,i;if(0!=(i=n.c[t]))for(n.c[t]=0,n.d-=i,e=t+1;e0)return Dz(t-1,n.a.c.length),u6(n.a,t-1);throw Fp(new pv)}function nhn(n,t,e){if(t<0)throw Fp(new Cy(Y4n+t));tt)throw Fp(new Ry(pJn+n+vJn+t));if(n<0||t>e)throw Fp(new jk(pJn+n+mJn+t+oJn+e))}function ehn(n){if(!n.a||0==(8&n.a.i))throw Fp(new Ky("Enumeration class expected for layout option "+n.f))}function ihn(n){var t;++n.j,0==n.i?n.g=null:n.iR3n?n-e>R3n:e-n>R3n)}function ghn(n,t){return n?t&&!n.j||iL(n,124)&&0==_B(n,124).a.b?0:n.Re():0}function phn(n,t){return n?t&&!n.k||iL(n,124)&&0==_B(n,124).a.a?0:n.Se():0}function vhn(n){return IDn(),n<0?-1!=n?new xpn(-1,-n):Vtt:n<=10?Jtt[SY(n)]:new xpn(1,n)}function mhn(n){throw Jun(),Fp(new wy("Unexpected typeof result '"+n+"'; please report this bug to the GWT team"))}function yhn(n){ok(),X$(this),yQ(this),this.e=n,Sxn(this,n),this.g=null==n?qWn:_bn(n),this.a="",this.b=n,this.a=""}function khn(){this.a=new nu,this.f=new bg(this),this.b=new wg(this),this.i=new dg(this),this.e=new gg(this)}function jhn(){iy.call(this,new B8(ntn(16))),hin(2,aVn),this.b=2,this.a=new FW(null,null,0,null),tv(this.a,this.a)}function Ehn(){Ehn=O,ivt=new DP("DUMMY_NODE_OVER",0),rvt=new DP("DUMMY_NODE_UNDER",1),cvt=new DP("EQUAL",2)}function Thn(){Thn=O,zat=FY(Mun(Hk(UPt,1),OVn,103,0,[(Kfn(),RPt),KPt])),Uat=FY(Mun(Hk(UPt,1),OVn,103,0,[FPt,DPt]))}function Mhn(n){return(mUn(),vCt).Hc(n.j)?Hy(ED(pMn(n,(oWn(),Alt)))):Con(Mun(Hk(MMt,1),uVn,8,0,[n.i.n,n.n,n.a])).b}function Shn(n){var t,e;for(t=n.b.a.a.ec().Kc();t.Ob();)e=new W$n(_B(t.Pb(),561),n.e,n.f),UB(n.g,e)}function Phn(n,t){var e,i;e=n.nk(t,null),i=null,t&&(tE(),ien(i=new Dp,n.r)),(e=FTn(n,i,e))&&e.Fi()}function Ihn(n,t){var e,i;for(i=0!=F$n(n.d,1),e=!0;e;)e=!1,e=t.c.Tf(t.e,i),e|=NNn(n,t,i,!1),i=!i;Orn(n)}function Chn(n,t){var e,i,r;return i=!1,e=t.q.d,t.dr&&(rEn(t.q,r),i=e!=t.q.d)),i}function Ohn(n,t){var e,r,c,a,u;return a=t.i,u=t.j,r=a-(e=n.f).i,c=u-e.j,i.Math.sqrt(r*r+c*c)}function Ahn(n,t){var e;return(e=Vdn(n))||(xHn(),s9((e=new Sp(VPn(t))).Vk(),n)),e}function $hn(n,t){var e,i;return(e=_B(n.c.Bc(t),14))?((i=n.hc()).Gc(e),n.d-=e.gc(),e.$b(),n.mc(i)):n.jc()}function Lhn(n,t){var e;for(e=0;e=n.c.b:n.a<=n.c.b))throw Fp(new vv);return t=n.a,n.a+=n.c.c,++n.b,tln(t)}function _hn(n){var t;return t=new stn(n),t2(n.a,uut,new Qy(Mun(Hk(Qat,1),FWn,369,0,[t]))),t.d&&UB(t.f,t.d),t.f}function Fhn(n){var t;return Ban(t=new I$(n.a),n),oon(t,(oWn(),blt),n),t.o.a=n.g,t.o.b=n.f,t.n.a=n.i,t.n.b=n.j,t}function Bhn(n,t,e,i){var r,c;for(c=n.Kc();c.Ob();)(r=_B(c.Pb(),70)).n.a=t.a+(i.a-r.o.a)/2,r.n.b=t.b,t.b+=r.o.b+e}function Hhn(n,t,e){var i;for(i=t.a.a.ec().Kc();i.Ob();)if(iJ(n,_B(i.Pb(),57),e))return!0;return!1}function qhn(n){var t,e;for(e=new Ub(n.r);e.a=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function tfn(n,t){var e,i,r;for(r=1,e=n,i=t>=0?t:-t;i>0;)i%2==0?(e*=e,i=i/2|0):(r*=e,i-=1);return t<0?1/r:r}function efn(n){var t,e;if(null!=n)for(e=0;e0&&bsn(_B(Lq(n.a,n.a.c.length-1),570),t)||UB(n.a,new d5(t))}function gfn(n){var t,e;H_(),t=n.d.c-n.e.c,Itn((e=_B(n.g,145)).b,new yd(t)),Itn(e.c,new kd(t)),n5(e.i,new jd(t))}function pfn(n){var t;return(t=new Sk).a+="VerticalSegment ",cO(t,n.e),t.a+=" ",aO(t,QL(new pk,new Ub(n.k))),t.a}function vfn(n){var t;return(t=_B(hnn(n.c.c,""),229))||(t=new GZ(yj(mj(new pu,""),"Other")),Qgn(n.c.c,"",t)),t}function mfn(n){var t;return 0!=(64&n.Db)?M$n(n):((t=new sN(M$n(n))).a+=" (name: ",iO(t,n.zb),t.a+=")",t.a)}function yfn(n,t,e){var i,r;return r=n.sb,n.sb=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new Yz(n,1,4,r,t),e?e.Ei(i):e=i),e}function kfn(n,t){var e,i;for(e=0,i=rbn(n,t).Kc();i.Ob();)e+=null!=pMn(_B(i.Pb(),11),(oWn(),klt))?1:0;return e}function jfn(n,t,e){var i,r,c;for(i=0,c=upn(n,0);c.b!=c.d.c&&!((r=Hy(ED(f3(c))))>e);)r>=t&&++i;return i}function Efn(n,t,e){var i;return i=new $7(n.e,3,13,null,t.c||(wWn(),s$t),cvn(n,t),!1),e?e.Ei(i):e=i,e}function Tfn(n,t,e){var i;return i=new $7(n.e,4,13,t.c||(wWn(),s$t),null,cvn(n,t),!1),e?e.Ei(i):e=i,e}function Mfn(n,t,e){var i,r;return r=n.r,n.r=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new Yz(n,1,8,r,n.r),e?e.Ei(i):e=i),e}function Sfn(n,t){var e,i;return!(i=(e=_B(t,676)).vk())&&e.wk(i=iL(t,88)?new OC(n,_B(t,26)):new R0(n,_B(t,148))),i}function Pfn(n,t,e){var i;n.qi(n.i+1),i=n.oi(t,e),t!=n.i&&rHn(n.g,t,n.g,t+1,n.i-t),OX(n.g,t,i),++n.i,n.bi(t,e),n.ci()}function Ifn(n,t){var e;return t.a&&(e=t.a.a.length,n.a?aO(n.a,n.b):n.a=new hN(n.d),H0(n.a,t.a,t.d.length,e)),n}function Cfn(n,t){var e,i,r;if(t.vi(n.a),null!=(r=_B(van(n.a,8),1936)))for(e=0,i=r.length;ee)throw Fp(new Cy(pJn+n+mJn+t+", size: "+e));if(n>t)throw Fp(new Ry(pJn+n+vJn+t))}function Bfn(n,t,e){if(t<0)iCn(n,e);else{if(!e.Ij())throw Fp(new Ry(e6n+e.ne()+i6n));_B(e,66).Nj().Vj(n,n.yh(),t)}}function Hfn(n,t,e,i,r,c,a,u){var o;for(o=e;c=i||t=65&&n<=70?n-65+10:n>=97&&n<=102?n-97+10:n>=48&&n<=57?n-48:0}function Xfn(n){var t;return 0!=(64&n.Db)?M$n(n):((t=new sN(M$n(n))).a+=" (source: ",iO(t,n.d),t.a+=")",t.a)}function Wfn(n,t,e){var i,r;return r=n.a,n.a=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new Yz(n,1,5,r,n.a),e?DEn(e,i):e=i),e}function Vfn(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,2,e,t))}function Qfn(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,8,e,t))}function Jfn(n,t){var e;e=0!=(256&n.Bb),t?n.Bb|=256:n.Bb&=-257,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,8,e,t))}function Yfn(n,t){var e;e=0!=(512&n.Bb),t?n.Bb|=512:n.Bb&=-513,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,3,e,t))}function Zfn(n,t){var e;e=0!=(512&n.Bb),t?n.Bb|=512:n.Bb&=-513,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,9,e,t))}function nln(n,t){var e;return-1==n.b&&n.a&&(e=n.a.Gj(),n.b=e?n.c.Xg(n.a.aj(),e):Cwn(n.c.Tg(),n.a)),n.c.Og(n.b,t)}function tln(n){var t,e;return n>-129&&n<128?(t=n+128,!(e=(ZH(),Ptt)[t])&&(e=Ptt[t]=new Lb(n)),e):new Lb(n)}function eln(n){var t,e;return n>-129&&n<128?(t=n+128,!(e=(jq(),Dtt)[t])&&(e=Dtt[t]=new xb(n)),e):new xb(n)}function iln(n){var t;return n.k==(cSn(),Eut)&&((t=_B(pMn(n,(oWn(),Wft)),61))==(mUn(),uCt)||t==TCt)}function rln(n,t,e){var i,r;return(r=O$n(n.b,t))&&(i=_B($Hn(K7(n,r),""),26))?p$n(n,i,t,e):null}function cln(n,t,e){var i,r;return(r=O$n(n.b,t))&&(i=_B($Hn(K7(n,r),""),26))?v$n(n,i,t,e):null}function aln(n,t){var e,i;for(i=new CL(n);i.e!=i.i.gc();)if(e=_B(mpn(i),138),HC(t)===HC(e))return!0;return!1}function uln(n,t,e){var i;if(t>(i=n.gc()))throw Fp(new ZR(t,i));if(n.hi()&&n.Hc(e))throw Fp(new Ry(r8n));n.Xh(t,e)}function oln(n,t){var e;if(null==(e=uen(n.i,t)))throw Fp(new nk("Node did not exist in input."));return Dcn(t,e),null}function sln(n,t){var e;if(iL(e=$Nn(n,t),322))return _B(e,34);throw Fp(new Ry(e6n+t+"' is not a valid attribute"))}function hln(n,t,e){var i,r;for(r=iL(t,99)&&0!=(_B(t,18).Bb&_Qn)?new LO(t,n):new Can(t,n),i=0;it?1:n==t?0==n?Mln(1/n,1/t):0:isNaN(n)?isNaN(t)?0:1:-1}function Sln(n,t){ITn(t,"Sort end labels",1),QT(CV(lnn(new xq(null,new l1(n.b,16)),new we),new de),new ge),FSn(t)}function Pln(n,t,e){var i,r;return n.ej()?(r=n.fj(),i=VCn(n,t,e),n.$i(n.Zi(7,tln(e),i,t,r)),i):VCn(n,t,e)}function Iln(n,t){var e,i,r;null==n.d?(++n.e,--n.f):(r=t.cd(),$6(n,i=((e=t.Sh())&NWn)%n.d.length,C$n(n,i,e,r)))}function Cln(n,t){var e;e=0!=(n.Bb&m6n),t?n.Bb|=m6n:n.Bb&=-1025,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,10,e,t))}function Oln(n,t){var e;e=0!=(n.Bb&RQn),t?n.Bb|=RQn:n.Bb&=-4097,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,12,e,t))}function Aln(n,t){var e;e=0!=(n.Bb&j9n),t?n.Bb|=j9n:n.Bb&=-8193,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,15,e,t))}function $ln(n,t){var e;e=0!=(n.Bb&E9n),t?n.Bb|=E9n:n.Bb&=-2049,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Z5(n,1,11,e,t))}function Lln(n,t){var e;return 0!=(e=Mln(n.b.c,t.b.c))||0!=(e=Mln(n.a.a,t.a.a))?e:Mln(n.a.b,t.a.b)}function Nln(n,t){var e;if(null==(e=xX(n.k,t)))throw Fp(new nk("Port did not exist in input."));return Dcn(t,e),null}function xln(n){var t,e;for(e=H$n(Gtn(n)).Kc();e.Ob();)if($_n(n,t=TD(e.Pb())))return v4((GM(),NAt),t);return null}function Dln(n,t){var e,i,r,c,a;for(a=rxn(n.e.Tg(),t),c=0,e=_B(n.g,119),r=0;r>10)+FQn&WVn,t[1]=56320+(1023&n)&WVn,_dn(t,0,t.length)}function Uln(n){var t;return(t=_B(pMn(n,(FXn(),Gdt)),103))==(Kfn(),_Pt)?Hy(ED(pMn(n,kdt)))>=1?KPt:DPt:t}function Xln(n){switch(_B(pMn(n,(FXn(),Jdt)),218).g){case 1:return new ic;case 3:return new oc;default:return new ec}}function Wln(n){if(n.c)Wln(n.c);else if(n.d)throw Fp(new Ky("Stream already terminated, can't be modified or used"))}function Vln(n){var t;return 0!=(64&n.Db)?M$n(n):((t=new sN(M$n(n))).a+=" (identifier: ",iO(t,n.k),t.a+=")",t.a)}function Qln(n,t,e){var i;return Zj(),yen(i=new ro,t),ken(i,e),n&&s9((!n.a&&(n.a=new OL($Ot,n,5)),n.a),i),i}function Jln(n,t,e,i){var r,c;return mW(i),mW(e),null==(c=null==(r=n.xc(t))?e:JT(_B(r,15),_B(e,14)))?n.Bc(t):n.zc(t,c),c}function Yln(n){var t,e,i,r;return arn(e=new VK(t=_B(Xj((r=(i=n.gm).f)==Gnt?i:r),9),_B(TR(t,t.length),9),0),n),e}function Zln(n,t,e){var i,r;for(r=n.a.ec().Kc();r.Ob();)if(i=_B(r.Pb(),10),aun(e,_B(Lq(t,i.p),14)))return i;return null}function nbn(n,t,e){try{Ron(n,t,e)}catch(i){throw iL(i=hun(i),597)?Fp(new w5(i)):Fp(i)}return t}function tbn(n,t){var e;return QO(n)&&QO(t)&&OQn<(e=n-t)&&e>1,n.k=e-1>>1}function ubn(){var n,t,e;vTn(),e=Aet+++Date.now(),n=SY(i.Math.floor(e*cJn))&uJn,t=SY(e-n*aJn),this.a=1502^n,this.b=t^rJn}function obn(n){var t,e;for(t=new $p,e=new Ub(n.j);e.a34028234663852886e22?xQn:t<-34028234663852886e22?DQn:t}function dbn(n){return n=((n=((n-=n>>1&1431655765)>>2&858993459)+(858993459&n))>>4)+n&252645135,n+=n>>8,63&(n+=n>>16)}function gbn(n){var t,e,i;for(t=new oR(n.Hd().gc()),i=0,e=A9(n.Hd().Kc());e.Ob();)yZ(t,e.Pb(),tln(i++));return $Sn(t.a)}function pbn(n,t){var e,i,r;for(r=new Lp,i=t.vc().Kc();i.Ob();)XW(r,(e=_B(i.Pb(),42)).cd(),han(n,_B(e.dd(),15)));return r}function vbn(n,t){0==n.n.c.length&&UB(n.n,new xY(n.s,n.t,n.i)),UB(n.b,t),umn(_B(Lq(n.n,n.n.c.length-1),211),t),_Fn(n,t)}function mbn(n){return n.c==n.b.b&&n.i==n.g.b||(n.a.c=L8(Cnt,FWn,1,0,5,1),wun(n.a,n.b),wun(n.a,n.g),n.c=n.b.b,n.i=n.g.b),n.a}function ybn(n,t){var e,i;for(i=0,e=_B(t.Kb(n),20).Kc();e.Ob();)By(jD(pMn(_B(e.Pb(),17),(oWn(),Slt))))||++i;return i}function kbn(n,t){var e,r;r=Hy(ED(ndn(s2(t),(FXn(),vpt)))),Kkn(t,e=i.Math.max(0,r/2-.5),1),UB(n,new hP(t,e))}function jbn(){jbn=O,Blt=new _P(WZn,0),Rlt=new _P("FIRST",1),Klt=new _P(S1n,2),_lt=new _P("LAST",3),Flt=new _P(P1n,4)}function Ebn(){Ebn=O,JPt=new KI(oYn,0),VPt=new KI("POLYLINE",1),WPt=new KI("ORTHOGONAL",2),QPt=new KI("SPLINES",3)}function Tbn(){Tbn=O,Jjt=new mI("ASPECT_RATIO_DRIVEN",0),Yjt=new mI("MAX_SCALE_DRIVEN",1),Qjt=new mI("AREA_DRIVEN",2)}function Mbn(){Mbn=O,FEt=new kI("P1_STRUCTURE",0),BEt=new kI("P2_PROCESSING_ORDER",1),HEt=new kI("P3_EXECUTION",2)}function Sbn(){Sbn=O,njt=new wI("OVERLAP_REMOVAL",0),Ykt=new wI("COMPACTION",1),Zkt=new wI("GRAPH_SIZE_CALCULATION",2)}function Pbn(n,t){return o$(),ein(DVn),i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:qO(isNaN(n),isNaN(t))}function Ibn(n,t){var e,i;for(e=upn(n,0);e.b!=e.d.c;){if((i=qy(ED(f3(e))))==t)return;if(i>t){G0(e);break}}YU(e,t)}function Cbn(n,t){var e,i,r,c,a;if(e=t.f,Qgn(n.c.d,e,t),null!=t.g)for(c=0,a=(r=t.g).length;ct&&i.ue(n[c-1],n[c])>0;--c)a=n[c],OX(n,c,n[c-1]),OX(n,c-1,a)}function Abn(n,t,e,i){if(t<0)jLn(n,e,i);else{if(!e.Ij())throw Fp(new Ry(e6n+e.ne()+i6n));_B(e,66).Nj().Tj(n,n.yh(),t,i)}}function $bn(n,t){if(t==n.d)return n.e;if(t==n.e)return n.d;throw Fp(new Ry("Node "+t+" not part of edge "+n))}function Lbn(n,t){switch(t.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 Nbn(n,t){switch(t.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 xbn(n,t,e,i){switch(t){case 3:return n.f;case 4:return n.g;case 5:return n.i;case 6:return n.j}return Rfn(n,t,e,i)}function Dbn(n){return n.k==(cSn(),Sut)&&a5(new xq(null,new qU(new az(JL(hbn(n).a.Kc(),new h)))),new qr)}function Rbn(n){return null==n.e?n:(!n.c&&(n.c=new eRn(0!=(256&n.f),n.i,n.a,n.d,0!=(16&n.f),n.j,n.g,null)),n.c)}function Kbn(n,t){return n.h==SQn&&0==n.m&&0==n.l?(t&&(htt=E$(0,0,0)),UO((z7(),btt))):(t&&(htt=E$(n.l,n.m,n.h)),E$(0,0,0))}function _bn(n){return Array.isArray(n)&&n.im===C?Yj(Zon(n))+"@"+(Yon(n)>>>0).toString(16):n.toString()}function Fbn(n){var t;this.a=new VK(t=_B(n.e&&n.e(),9),_B(TR(t,t.length),9),0),this.b=L8(Cnt,FWn,1,this.a.a.length,5,1)}function Bbn(n){var t,e,i;for(this.a=new sA,i=new Ub(n);i.a0&&(f1(t-1,n.length),58==n.charCodeAt(t-1))&&!zbn(n,OAt,AAt)}function zbn(n,t,e){var i,r;for(i=0,r=n.length;i=r)return t.c+e;return t.c+t.b.gc()}function Wbn(n,t){var e,i,r,c;for(bD(),r=t,q9(i=F9(n),0,i.length,r),e=0;e0&&(i+=r,++e);return e>1&&(i+=n.d*(e-1)),i}function Qbn(n){var t,e,i;for((i=new Tk).a+="[",t=0,e=n.gc();t0&&this.b>0&&Vq(this.c,this.b,this.a)}function cwn(n){xwn(),this.c=c6(Mun(Hk(eMt,1),FWn,831,0,[Upt])),this.b=new Lp,this.a=n,XW(this.b,Xpt,1),Itn(Wpt,new Mg(this))}function awn(n,t){var e;return n.d?oU(n.b,t)?_B(xX(n.b,t),51):(e=t.Kf(),XW(n.b,t,e),e):t.Kf()}function uwn(n,t){var e;return HC(n)===HC(t)||!!iL(t,91)&&(e=_B(t,91),n.e==e.e&&n.d==e.d&&k4(n,e.a))}function own(n){switch(mUn(),n.g){case 4:return uCt;case 1:return aCt;case 3:return TCt;case 2:return SCt;default:return MCt}}function swn(n,t){switch(t){case 3:return 0!=n.f;case 4:return 0!=n.g;case 5:return 0!=n.i;case 6:return 0!=n.j}return kan(n,t)}function hwn(n){switch(n.g){case 0:return new Ga;case 1:return new za;default:throw Fp(new Ry(i4n+(null!=n.f?n.f:""+n.g)))}}function fwn(n){switch(n.g){case 0:return new qa;case 1:return new Ua;default:throw Fp(new Ry(E1n+(null!=n.f?n.f:""+n.g)))}}function lwn(n){switch(n.g){case 0:return new Xm;case 1:return new vm;default:throw Fp(new Ry($4n+(null!=n.f?n.f:""+n.g)))}}function bwn(n){switch(n.g){case 1:return new Ra;case 2:return new wD;default:throw Fp(new Ry(i4n+(null!=n.f?n.f:""+n.g)))}}function wwn(n){var t,e;if(n.b)return n.b;for(e=Wet?null:n.d;e;){if(t=Wet?null:e.b)return t;e=Wet?null:e.d}return hM(),Fet}function dwn(n){var t,e;return 0==n.e?0:(t=n.d<<5,e=n.a[n.d-1],n.e<0&&Scn(n)==n.d-1&&(--e,e|=0),t-=JCn(e))}function gwn(n){var t,e,i;return n>5),15,1))[e]=1<3;)r*=10,--c;n=(n+(r>>1))/r|0}return i.i=n,!0}function kwn(n){return Thn(),oN(),!!(Nbn(_B(n.a,81).j,_B(n.b,103))||0!=_B(n.a,81).d.e&&Nbn(_B(n.a,81).j,_B(n.b,103)))}function jwn(n){L9(),_B(n.We((uWn(),BSt)),174).Hc((YKn(),XCt))&&(_B(n.We(sPt),174).Fc((hCn(),iCt)),_B(n.We(BSt),174).Mc(XCt))}function Ewn(n,t){var e;if(t){for(e=0;e=0;--i)for(t=e[i],r=0;r>1,this.k=t-1>>1}function Hwn(n,t){ITn(t,"End label post-processing",1),QT(CV(lnn(new xq(null,new l1(n.b,16)),new ae),new ue),new oe),FSn(t)}function qwn(n,t,e){var i;return i=Hy(n.p[t.i.p])+Hy(n.d[t.i.p])+t.n.b+t.a.b,Hy(n.p[e.i.p])+Hy(n.d[e.i.p])+e.n.b+e.a.b-i}function Gwn(n,t,e){var i,r;for(i=n0(e,GQn),r=0;0!=Xhn(i,0)&&r0&&(f1(0,t.length),43==t.charCodeAt(0))?t.substr(1):t)}function Xwn(n){var t;return null==n?null:new OA((t=KBn(n,!0)).length>0&&(f1(0,t.length),43==t.charCodeAt(0))?t.substr(1):t)}function Wwn(n,t){return n.i>0&&(t.lengthn.i&&OX(t,n.i,null),t}function Vwn(n,t,e){var i,r,c;return n.ej()?(i=n.i,c=n.fj(),Pfn(n,i,t),r=n.Zi(3,null,t,i,c),e?e.Ei(r):e=r):Pfn(n,n.i,t),e}function Qwn(n,t,e){var i,r;return i=new $7(n.e,4,10,iL(r=t.c,88)?_B(r,26):(wWn(),l$t),null,cvn(n,t),!1),e?e.Ei(i):e=i,e}function Jwn(n,t,e){var i,r;return i=new $7(n.e,3,10,null,iL(r=t.c,88)?_B(r,26):(wWn(),l$t),cvn(n,t),!1),e?e.Ei(i):e=i,e}function Ywn(n){var t;return BD(),t=new lA(_B(n.e.We((uWn(),_St)),8)),n.B.Hc((YKn(),HCt))&&(t.a<=0&&(t.a=20),t.b<=0&&(t.b=20)),t}function Zwn(n){return fvn(),(n.q?n.q:(TQ(),TQ(),oet))._b((FXn(),xgt))?_B(pMn(n,xgt),197):_B(pMn(gW(n),Dgt),197)}function ndn(n,t){var e,i;return i=null,Ax(n,(FXn(),Ept))&&(e=_B(pMn(n,Ept),94)).Xe(t)&&(i=e.We(t)),null==i&&(i=pMn(gW(n),t)),i}function tdn(n,t){var e,i,r;return!!iL(t,42)&&(i=(e=_B(t,42)).cd(),lW(r=hfn(n.Rc(),i),e.dd())&&(null!=r||n.Rc()._b(i)))}function edn(n,t){var e;return n.f>0&&(n.qj(),-1!=C$n(n,((e=null==t?0:Yon(t))&NWn)%n.d.length,e,t))}function idn(n,t){var e,i;return n.f>0&&(n.qj(),e=rOn(n,((i=null==t?0:Yon(t))&NWn)%n.d.length,i,t))?e.dd():null}function rdn(n,t){var e,i,r,c;for(c=rxn(n.e.Tg(),t),e=_B(n.g,119),r=0;r1?t0(vz(t.a[1],32),n0(t.a[0],GQn)):n0(t.a[0],GQn),y2(ibn(t.e,e))))}function hdn(n,t){var e;return QO(n)&&QO(t)&&OQn<(e=n%t)&&e>5,t&=31,r=n.d+e+(0==t?0:1),LTn(i=L8(INt,oQn,25,r,15,1),n.a,e,t),z0(c=new hU(n.e,r,i)),c}function jdn(n,t,e){var i,r;i=_B(TY(nNt,t),117),r=_B(TY(tNt,t),117),e?(pZ(nNt,n,i),pZ(tNt,n,r)):(pZ(tNt,n,i),pZ(nNt,n,r))}function Edn(n,t,e){var i,r,c;for(r=null,c=n.b;c;){if(i=n.a.ue(t,c.d),e&&0==i)return c;i>=0?c=c.a[1]:(r=c,c=c.a[0])}return r}function Tdn(n,t,e){var i,r,c;for(r=null,c=n.b;c;){if(i=n.a.ue(t,c.d),e&&0==i)return c;i<=0?c=c.a[0]:(r=c,c=c.a[1])}return r}function Mdn(n,t,e,i){var r,c,a;return r=!1,AGn(n.f,e,i)&&(Lgn(n.f,n.a[t][e],n.a[t][i]),a=(c=n.a[t])[i],c[i]=c[e],c[e]=a,r=!0),r}function Sdn(n,t,e,i,r){var c,a,u;for(a=r;t.b!=t.c;)c=_B(bU(t),10),u=_B(rbn(c,i).Xb(0),11),n.d[u.p]=a++,e.c[e.c.length]=u;return a}function Pdn(n,t,e){var r,c,a,u,o;return u=n.k,o=t.k,c=ED(ndn(n,r=e[u.g][o.g])),a=ED(ndn(t,r)),i.Math.max((mW(c),c),(mW(a),a))}function Idn(n,t,e){var i,r,c,a;for(i=e/n.c.length,r=0,a=new Ub(n);a.a2e3&&(rtt=n,ctt=i.setTimeout(WE,10)),0==itt++&&(Inn((uk(),Znt)),!0)}function $dn(n,t){var e;for(e=new az(JL(hbn(n).a.Kc(),new h));bAn(e);)if(_B(G5(e),17).d.i.c==t)return!1;return!0}function Ldn(n,t){var e;if(iL(t,245)){e=_B(t,245);try{return 0==n.vd(e)}catch(i){if(!iL(i=hun(i),205))throw Fp(i)}}return!1}function Ndn(){return Error.stackTraceLimit>0?(i.Error.stackTraceLimit=Error.stackTraceLimit=64,!0):"stack"in new Error}function xdn(n,t){return o$(),o$(),ein(DVn),(i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:qO(isNaN(n),isNaN(t)))>0}function Ddn(n,t){return o$(),o$(),ein(DVn),(i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:qO(isNaN(n),isNaN(t)))<0}function Rdn(n,t){return o$(),o$(),ein(DVn),(i.Math.abs(n-t)<=DVn||n==t||isNaN(n)&&isNaN(t)?0:nt?1:qO(isNaN(n),isNaN(t)))<=0}function Kdn(n,t){for(var e=0;!t[e]||""==t[e];)e++;for(var i=t[e++];eHQn)return e.fh();if((i=e.Zg())||e==n)break}return i}function Qdn(n){return oZ(),iL(n,156)?_B(xX(cAt,vet),288).vg(n):oU(cAt,Zon(n))?_B(xX(cAt,Zon(n)),288).vg(n):null}function Jdn(n){if(pgn(r5n,n))return oN(),gtt;if(pgn(c5n,n))return oN(),dtt;throw Fp(new Ry("Expecting true or false"))}function Ydn(n,t){if(t.c==n)return t.d;if(t.d==n)return t.c;throw Fp(new Ry("Input edge is not connected to the input port."))}function Zdn(n,t){return n.e>t.e?1:n.et.d?n.e:n.d=48&&n<48+i.Math.min(10,10)?n-48:n>=97&&n<97?n-97+10:n>=65&&n<65?n-65+10:-1}function tgn(n,t){var e;return HC(t)===HC(n)||!!iL(t,21)&&(e=_B(t,21)).gc()==n.gc()&&n.Ic(e)}function egn(n,t){var e,i,r;return i=n.a.length-1,e=t-n.b&i,r=n.c-t&i,kx(e<(n.c-n.b&i)),e>=r?(rhn(n,t),-1):(chn(n,t),1)}function ign(n,t){var e,i;for(f1(t,n.length),e=n.charCodeAt(t),i=t+1;it.e?1:n.ft.f?1:Yon(n)-Yon(t)}function pgn(n,t){return mW(n),null!=t&&(!!pK(n,t)||n.length==t.length&&pK(n.toLowerCase(),t.toLowerCase()))}function vgn(n,t){var e,i,r,c;for(i=0,r=t.gc();i0&&Xhn(n,128)<0?(t=bG(n)+128,!(e=(kq(),Ott)[t])&&(e=Ott[t]=new Nb(n)),e):new Nb(n)}function kgn(n,t){var e,i;return(e=t.Hh(n.a))&&null!=(i=TD(idn((!e.b&&(e.b=new Qx((wWn(),v$t),G$t,e)),e.b),Z6n)))?i:t.ne()}function jgn(n,t){var e,i;return(e=t.Hh(n.a))&&null!=(i=TD(idn((!e.b&&(e.b=new Qx((wWn(),v$t),G$t,e)),e.b),Z6n)))?i:t.ne()}function Egn(n,t){var e,i;for(BZ(),i=new az(JL(obn(n).a.Kc(),new h));bAn(i);)if((e=_B(G5(i),17)).d.i==t||e.c.i==t)return e;return null}function Tgn(n,t,e){this.c=n,this.f=new $p,this.e=new Hj,this.j=new Tq,this.n=new Tq,this.b=t,this.g=new GV(t.c,t.d,t.b,t.a),this.a=e}function Mgn(n){var t,e,i,r;for(this.a=new sA,this.d=new xv,this.e=0,i=0,r=(e=n).length;i0)}function $gn(n){var t;HC(JAn(n,(uWn(),kSt)))===HC((cfn(),gIt))&&(QY(n)?(t=_B(JAn(QY(n),kSt),334),Vpn(n,kSt,t)):Vpn(n,kSt,pIt))}function Lgn(n,t,e){var i,r;sMn(n.e,t,e,(mUn(),SCt)),sMn(n.i,t,e,aCt),n.a&&(r=_B(pMn(t,(oWn(),blt)),11),i=_B(pMn(e,blt),11),m0(n.g,r,i))}function Ngn(n,t,e){var i,r,c;i=t.c.p,c=t.p,n.b[i][c]=new NJ(n,t),e&&(n.a[i][c]=new _d(t),(r=_B(pMn(t,(oWn(),elt)),10))&&QCn(n.d,r,t))}function xgn(n,t){var e,i,r;if(UB(Tct,n),t.Fc(n),e=_B(xX(Ect,n),21))for(r=e.Kc();r.Ob();)i=_B(r.Pb(),33),-1!=k7(Tct,i,0)||xgn(i,t)}function Dgn(n,t,e){var i;(Uet?(wwn(n),1):Xet||Qet?(hM(),1):Vet&&(hM(),0))&&((i=new t_(t)).b=e,rSn(n,i))}function Rgn(n,t){var e;e=!n.A.Hc((pdn(),RCt))||n.q==(WEn(),zIt),n.u.Hc((hCn(),nCt))?e?$Un(n,t):rUn(n,t):n.u.Hc(eCt)&&(e?Czn(n,t):QUn(n,t))}function Kgn(n,t){var e,i;++n.j,null!=t&&aOn(t,e=iL(i=n.a.Cb,97)?_B(i,97).Jg():null)?ogn(n.a,4,e):ogn(n.a,4,_B(t,126))}function _gn(n,t,e){return new GV(i.Math.min(n.a,t.a)-e/2,i.Math.min(n.b,t.b)-e/2,i.Math.abs(n.a-t.a)+e,i.Math.abs(n.b-t.b)+e)}function Fgn(n,t){var e,i;return 0!=(e=k$(n.a.c.p,t.a.c.p))?e:0!=(i=k$(n.a.d.i.p,t.a.d.i.p))?i:k$(t.a.d.p,n.a.d.p)}function Bgn(n,t,e){var i,r,c,a;return(c=t.j)!=(a=e.j)?c.g-a.g:(i=n.f[t.p],r=n.f[e.p],0==i&&0==r?0:0==i?-1:0==r?1:Mln(i,r))}function Hgn(n,t,e){var i;if(!e[t.d])for(e[t.d]=!0,i=new Ub(mbn(t));i.a=(r=n.length))return r;for(t=t>0?t:0;ti&&OX(t,i,null),t}function Vgn(n,t){var e,i;for(i=n.a.length,t.lengthi&&OX(t,i,null),t}function Qgn(n,t,e){var i,r,c;return(r=_B(xX(n.e,t),387))?(c=dR(r,e),cL(n,r),c):(i=new YB(n,t,e),XW(n.e,t,i),mY(i),null)}function Jgn(n){var t;if(null==n)return null;if(null==(t=A$n(KBn(n,!0))))throw Fp(new tk("Invalid hexBinary value: '"+n+"'"));return t}function Ygn(n){return IDn(),Xhn(n,0)<0?0!=Xhn(n,-1)?new gEn(-1,y7(n)):Vtt:Xhn(n,10)<=0?Jtt[bG(n)]:new gEn(1,n)}function Zgn(){return bWn(),Mun(Hk(Drt,1),OVn,159,0,[Mrt,Trt,Srt,grt,drt,prt,yrt,mrt,vrt,Ert,jrt,krt,brt,lrt,wrt,hrt,srt,frt,urt,art,ort,Prt])}function npn(n){var t;this.d=new $p,this.j=new Hj,this.g=new Hj,t=n.g.b,this.f=_B(pMn(gW(t),(FXn(),Gdt)),103),this.e=Hy(ED(wpn(t,Tpt)))}function tpn(n){this.b=new $p,this.e=new $p,this.d=n,this.a=!yE(CV(new xq(null,new qU(new p6(n.b))),new rw(new Gr))).sd((bM(),Zet))}function epn(){epn=O,oMt=new CI("PARENTS",0),uMt=new CI("NODES",1),cMt=new CI("EDGES",2),sMt=new CI("PORTS",3),aMt=new CI("LABELS",4)}function ipn(){ipn=O,_It=new qI("DISTRIBUTED",0),BIt=new qI("JUSTIFIED",1),RIt=new qI("BEGIN",2),KIt=new qI(nYn,3),FIt=new qI("END",4)}function rpn(n){switch(n.yi(null)){case 10:return 0;case 15:return 1;case 14:return 2;case 11:return 3;case 21:return 4}return-1}function cpn(n){switch(n.g){case 1:return Kfn(),FPt;case 4:return Kfn(),RPt;case 2:return Kfn(),KPt;case 3:return Kfn(),DPt}return Kfn(),_Pt}function apn(n,t,e){var i;switch((i=e.q.getFullYear()-uQn+uQn)<0&&(i=-i),t){case 1:n.a+=i;break;case 2:knn(n,i%100,2);break;default:knn(n,i,t)}}function upn(n,t){var e,i;if(AZ(t,n.b),t>=n.b>>1)for(i=n.c,e=n.b;e>t;--e)i=i.b;else for(i=n.a.a,e=0;e=64&&t<128&&(r=t0(r,vz(1,t-64)));return r}function wpn(n,t){var e,i;return i=null,Ax(n,(uWn(),SPt))&&(e=_B(pMn(n,SPt),94)).Xe(t)&&(i=e.We(t)),null==i&&gW(n)&&(i=pMn(gW(n),t)),i}function dpn(n,t){var e,i,r;(i=(r=t.d.i).k)!=(cSn(),Sut)&&i!=jut&&bAn(e=new az(JL(hbn(r).a.Kc(),new h)))&&XW(n.k,t,_B(G5(e),17))}function gpn(n,t){var e,i,r;return i=ttn(n.Tg(),t),(e=t-n.Ah())<0?(r=n.Yg(i))>=0?n.lh(r):BCn(n,i):e<0?BCn(n,i):_B(i,66).Nj().Sj(n,n.yh(),e)}function ppn(n){var t;if(iL(n.a,4)){if(null==(t=Qdn(n.a)))throw Fp(new Ky(a5n+n.b+"'. "+e5n+(kD(hAt),hAt.k)+i5n));return t}return n.a}function vpn(n){var t;if(null==n)return null;if(null==(t=GUn(KBn(n,!0))))throw Fp(new tk("Invalid base64Binary value: '"+n+"'"));return t}function mpn(n){var t;try{return t=n.i.Xb(n.e),n.mj(),n.g=n.e++,t}catch(e){throw iL(e=hun(e),73)?(n.mj(),Fp(new vv)):Fp(e)}}function ypn(n){var t;try{return t=n.c.ki(n.e),n.mj(),n.g=n.e++,t}catch(e){throw iL(e=hun(e),73)?(n.mj(),Fp(new vv)):Fp(e)}}function kpn(){kpn=O,uWn(),kct=jPt,dct=vSt,hct=iSt,gct=zSt,Rkn(),mct=Eit,vct=kit,yct=Mit,pct=yit,Hsn(),lct=act,fct=cct,bct=oct,wct=sct}function jpn(n){switch(yM(),this.c=new $p,this.d=n,n.g){case 0:case 2:this.a=WW(out),this.b=xQn;break;case 3:case 1:this.a=out,this.b=DQn}}function Epn(n,t,e){var i;if(n.c)Men(n.c,n.c.i+t),Sen(n.c,n.c.j+e);else for(i=new Ub(n.b);i.a0&&(UB(n.b,new XB(t.a,e)),0<(i=t.a.length)?t.a=t.a.substr(0,0):0>i&&(t.a+=eL(L8(PNt,UVn,25,-i,15,1))))}function Spn(n,t){var e,i,r;for(e=n.o,r=_B(_B(o6(n.r,t),21),84).Kc();r.Ob();)(i=_B(r.Pb(),111)).e.a=byn(i,e.a),i.e.b=e.b*Hy(ED(i.b.We(Art)))}function Ppn(n,t){var e,i,r,c;return r=n.k,e=Hy(ED(pMn(n,(oWn(),jlt)))),c=t.k,i=Hy(ED(pMn(t,jlt))),c!=(cSn(),Eut)?-1:r!=Eut?1:e==i?0:e=0?n.hh(t,e,i):(n.eh()&&(i=(r=n.Vg())>=0?n.Qg(i):n.eh().ih(n,-1-r,null,i)),n.Sg(t,e,i))}function Lpn(n,t){switch(t){case 7:return!n.e&&(n.e=new oK(DOt,n,7,4)),void uqn(n.e);case 8:return!n.d&&(n.d=new oK(DOt,n,8,5)),void uqn(n.d)}Nwn(n,t)}function Npn(n,t){var e;e=n.Zc(t);try{return e.Pb()}catch(i){throw iL(i=hun(i),109)?Fp(new Cy("Can't get element "+t)):Fp(i)}}function xpn(n,t){this.e=n,t=0&&(e.d=n.t);break;case 3:n.t>=0&&(e.a=n.t)}n.C&&(e.b=n.C.b,e.c=n.C.c)}function Fpn(){Fpn=O,_rt=new RS(pYn,0),Krt=new RS(vYn,1),Frt=new RS(mYn,2),Brt=new RS(yYn,3),_rt.a=!1,Krt.a=!0,Frt.a=!1,Brt.a=!0}function Bpn(){Bpn=O,Jrt=new DS(pYn,0),Qrt=new DS(vYn,1),Yrt=new DS(mYn,2),Zrt=new DS(yYn,3),Jrt.a=!1,Qrt.a=!0,Yrt.a=!1,Zrt.a=!0}function Hpn(n){var t;t=n.a;do{(t=_B(G5(new az(JL(sbn(t).a.Kc(),new h))),17).c.i).k==(cSn(),Mut)&&n.b.Fc(t)}while(t.k==(cSn(),Mut));n.b=nan(n.b)}function qpn(n){var t,e,i;for(i=n.c.a,n.p=(vX(i),new ZK(i)),e=new Ub(i);e.ae.b)return!0}return!1}function Wpn(n,t){return zC(n)?!!IWn[t]:n.hm?!!n.hm[t]:GC(n)?!!PWn[t]:!!qC(n)&&!!SWn[t]}function Vpn(n,t,e){return null==e?(!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),Udn(n.o,t)):(!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),gjn(n.o,t,e)),n}function Qpn(n,t,e,i){var r;(r=zfn(t.Xe((uWn(),NSt))?_B(t.We(NSt),21):n.j))!=(bWn(),Prt)&&(e&&!rgn(r)||GSn($$n(n,r,i),t))}function Jpn(n,t,e,i){var r,c,a;return c=ttn(n.Tg(),t),(r=t-n.Ah())<0?(a=n.Yg(c))>=0?n._g(a,e,!0):iOn(n,c,e):_B(c,66).Nj().Pj(n,n.yh(),r,e,i)}function Ypn(n,t,e,i){var r,c;e.mh(t)&&(JM(),onn(t)?vgn(n,_B(e.ah(t),153)):(r=(c=t)?_B(i,49).xh(c):null)&&Rp(e.ah(t),r))}function Zpn(n){switch(n.g){case 1:return Nan(),xrt;case 3:return Nan(),$rt;case 2:return Nan(),Nrt;case 4:return Nan(),Lrt;default:return null}}function nvn(n){switch(typeof n){case $Wn:return gvn(n);case AWn:return SY(n);case OWn:return oN(),n?1231:1237;default:return null==n?0:MN(n)}}function tvn(n,t,e){if(n.e)switch(n.b){case 1:_Q(n.c,t,e);break;case 0:FQ(n.c,t,e)}else Z3(n.c,t,e);n.a[t.p][e.p]=n.c.i,n.a[e.p][t.p]=n.c.e}function evn(n){var t,e;if(null==n)return null;for(e=L8(Iut,uVn,193,n.length,0,2),t=0;t=0)return i;if(n.Fk())for(e=0;e=(r=n.gc()))throw Fp(new ZR(t,r));if(n.hi()&&(i=n.Xc(e))>=0&&i!=t)throw Fp(new Ry(r8n));return n.mi(t,e)}function uvn(n,t){if(this.a=_B(vX(n),245),this.b=_B(vX(t),245),n.vd(t)>0||n==(ny(),Dnt)||t==(Zm(),Rnt))throw Fp(new Ry("Invalid range: "+_3(n,t)))}function ovn(n){var t,e;for(this.b=new $p,this.c=n,this.a=!1,e=new Ub(n.a);e.a0),(t&-t)==t)return SY(t*F$n(n,31)*4.656612873077393e-10);do{i=(e=F$n(n,31))%t}while(e-i+(t-1)<0);return SY(i)}function gvn(n){var t,e,i;return e_(),null!=(i=eit[e=":"+n])?SY((mW(i),i)):(t=null==(i=tit[e])?QNn(n):SY((mW(i),i)),PQ(),eit[e]=t,t)}function pvn(n,t,e){ITn(e,"Compound graph preprocessor",1),n.a=new dY,$zn(n,t,null),HHn(n,t),ZLn(n),oon(t,(oWn(),Fft),n.a),n.a=null,OU(n.b),FSn(e)}function vvn(n,t,e){switch(e.g){case 1:n.a=t.a/2,n.b=0;break;case 2:n.a=t.a,n.b=t.b/2;break;case 3:n.a=t.a/2,n.b=t.b;break;case 4:n.a=0,n.b=t.b/2}}function mvn(n){var t,e,i;for(i=_B(o6(n.a,(AEn(),Mst)),15).Kc();i.Ob();)tX(n,e=_B(i.Pb(),101),(t=Fyn(e))[0],(Srn(),Lst),0),tX(n,e,t[1],xst,1)}function yvn(n){var t,e,i;for(i=_B(o6(n.a,(AEn(),Sst)),15).Kc();i.Ob();)tX(n,e=_B(i.Pb(),101),(t=Fyn(e))[0],(Srn(),Lst),0),tX(n,e,t[1],xst,1)}function kvn(n){switch(n.g){case 0:return null;case 1:return new Crn;case 2:return new Qm;default:throw Fp(new Ry(i4n+(null!=n.f?n.f:""+n.g)))}}function jvn(n,t,e){var i,r;for(pun(n,t-n.s,e-n.t),r=new Ub(n.n);r.a1&&(r=svn(n,t)),r}function Tvn(n){var t;return n.f&&n.f.kh()&&(t=_B(n.f,49),n.f=_B(Zhn(n,t),82),n.f!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,9,8,t,n.f))),n.f}function Mvn(n){var t;return n.i&&n.i.kh()&&(t=_B(n.i,49),n.i=_B(Zhn(n,t),82),n.i!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,9,7,t,n.i))),n.i}function Svn(n){var t;return n.b&&0!=(64&n.b.Db)&&(t=n.b,n.b=_B(Zhn(n,t),18),n.b!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,9,21,t,n.b))),n.b}function Pvn(n,t){var e,i,r;null==n.d?(++n.e,++n.f):(i=t.Sh(),sNn(n,n.f+1),r=(i&NWn)%n.d.length,!(e=n.d[r])&&(e=n.d[r]=n.uj()),e.Fc(t),++n.f)}function Ivn(n,t,e){var i;return!t.Kj()&&(-2!=t.Zj()?null==(i=t.zj())?null==e:$fn(i,e):t.Hj()==n.e.Tg()&&null==e)}function Cvn(){var n;hin(16,PVn),n=Qin(16),this.b=L8(Hnt,SVn,317,n,0,1),this.c=L8(Hnt,SVn,317,n,0,1),this.a=null,this.e=null,this.i=0,this.f=n-1,this.g=0}function Ovn(n){AR.call(this),this.k=(cSn(),Sut),this.j=(hin(6,CVn),new Q6(6)),this.b=(hin(2,CVn),new Q6(2)),this.d=new sm,this.f=new lm,this.a=n}function Avn(n){var t,e;n.c.length<=1||(bPn(n,_B((t=kDn(n,(mUn(),TCt))).a,19).a,_B(t.b,19).a),bPn(n,_B((e=kDn(n,SCt)).a,19).a,_B(e.b,19).a))}function $vn(){$vn=O,vvt=new KP("SIMPLE",0),dvt=new KP(_1n,1),gvt=new KP("LINEAR_SEGMENTS",2),wvt=new KP("BRANDES_KOEPF",3),pvt=new KP(y3n,4)}function Lvn(n,t,e){AK(_B(pMn(t,(FXn(),npt)),98))||(U7(n,t,NSn(t,e)),U7(n,t,NSn(t,(mUn(),TCt))),U7(n,t,NSn(t,uCt)),TQ(),p$(t.j,new Rd(n)))}function Nvn(n,t,e,i){var r;for(r=_B(o6(i?n.a:n.b,t),21).Kc();r.Ob();)if(RDn(n,e,_B(r.Pb(),33)))return!0;return!1}function xvn(n){var t,e;for(e=new CL(n);e.e!=e.i.gc();)if((t=_B(mpn(e),87)).e||0!=(!t.d&&(t.d=new OL(UAt,t,1)),t.d).i)return!0;return!1}function Dvn(n){var t,e;for(e=new CL(n);e.e!=e.i.gc();)if((t=_B(mpn(e),87)).e||0!=(!t.d&&(t.d=new OL(UAt,t,1)),t.d).i)return!0;return!1}function Rvn(n){var t,e;for(t=0,e=new Ub(n.c.a);e.a102?-1:n<=57?n-48:n<65?-1:n<=70?n-65+10:n<97?-1:n-97+10}function qvn(n,t){if(null==n)throw Fp(new Fy("null key in entry: null="+t));if(null==t)throw Fp(new Fy("null value in entry: "+n+"=null"))}function Gvn(n,t){for(var e,i;n.Ob();){if(!t.Ob())return!1;if(e=n.Pb(),i=t.Pb(),!(HC(e)===HC(i)||null!=e&&$fn(e,i)))return!1}return!t.Ob()}function zvn(n,t){var e;return e=Mun(Hk($Nt,1),BQn,25,15,[ghn(n.a[0],t),ghn(n.a[1],t),ghn(n.a[2],t)]),n.d&&(e[0]=i.Math.max(e[0],e[2]),e[2]=e[0]),e}function Uvn(n,t){var e;return e=Mun(Hk($Nt,1),BQn,25,15,[phn(n.a[0],t),phn(n.a[1],t),phn(n.a[2],t)]),n.d&&(e[0]=i.Math.max(e[0],e[2]),e[2]=e[0]),e}function Xvn(){Xvn=O,vht=new TP("GREEDY",0),pht=new TP(F1n,1),yht=new TP(_1n,2),kht=new TP("MODEL_ORDER",3),mht=new TP("GREEDY_MODEL_ORDER",4)}function Wvn(n,t){var e,i,r;for(n.b[t.g]=1,i=upn(t.d,0);i.b!=i.d.c;)r=(e=_B(f3(i),188)).c,1==n.b[r.g]?NH(n.a,e):2==n.b[r.g]?n.b[r.g]=1:Wvn(n,r)}function Vvn(n,t){var e,i,r;for(r=new Q6(t.gc()),i=t.Kc();i.Ob();)(e=_B(i.Pb(),286)).c==e.f?oPn(n,e,e.c):ePn(n,e)||(r.c[r.c.length]=e);return r}function Qvn(n,t,e){var i,r,c,a;for(a=n.r+t,n.r+=t,n.d+=e,i=e/n.n.c.length,r=0,c=new Ub(n.n);c.ac&&OX(t,c,null),t}function jmn(n,t){var e,i;if(i=n.gc(),null==t){for(e=0;e0&&(o+=r),s[h]=a,a+=u*(o+i)}function Nmn(n){var t,e,i;for(i=n.f,n.n=L8($Nt,BQn,25,i,15,1),n.d=L8($Nt,BQn,25,i,15,1),t=0;t0?n.c:0),++c;n.b=r,n.d=a}function qmn(n,t){var e,r,c,a,u;for(r=0,c=0,e=0,u=new Ub(t);u.a0?n.g:0),++e;n.c=c,n.d=r}function Gmn(n,t){var e;return e=Mun(Hk($Nt,1),BQn,25,15,[wvn(n,(Ntn(),Hit),t),wvn(n,qit,t),wvn(n,Git,t)]),n.f&&(e[0]=i.Math.max(e[0],e[2]),e[2]=e[0]),e}function zmn(n,t,e){try{KRn(n,t+n.j,e+n.k,!1,!0)}catch(i){throw iL(i=hun(i),73)?Fp(new Cy(i.g+SYn+t+KWn+e+").")):Fp(i)}}function Umn(n,t,e){try{KRn(n,t+n.j,e+n.k,!0,!1)}catch(i){throw iL(i=hun(i),73)?Fp(new Cy(i.g+SYn+t+KWn+e+").")):Fp(i)}}function Xmn(n){var t;Ax(n,(FXn(),Ogt))&&((t=_B(pMn(n,Ogt),21)).Hc((YAn(),PIt))?(t.Mc(PIt),t.Fc(CIt)):t.Hc(CIt)&&(t.Mc(CIt),t.Fc(PIt)))}function Wmn(n){var t;Ax(n,(FXn(),Ogt))&&((t=_B(pMn(n,Ogt),21)).Hc((YAn(),NIt))?(t.Mc(NIt),t.Fc($It)):t.Hc($It)&&(t.Mc($It),t.Fc(NIt)))}function Vmn(n,t,e){ITn(e,"Self-Loop ordering",1),QT(OV(CV(CV(lnn(new xq(null,new l1(t.b,16)),new Ci),new Oi),new Ai),new $i),new fd(n)),FSn(e)}function Qmn(n,t,e,i){var r,c;for(r=t;r0&&(c.b+=t),c}function cyn(n,t){var e,r,c;for(c=new Hj,r=n.Kc();r.Ob();)JRn(e=_B(r.Pb(),37),0,c.b),c.b+=e.f.b+t,c.a=i.Math.max(c.a,e.f.a);return c.a>0&&(c.a+=t),c}function ayn(n){var t,e,r;for(r=NWn,e=new Ub(n.a);e.a>16==6?n.Cb.ih(n,5,BOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||n.zh(),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function hyn(n){MJ();var t=n.e;if(t&&t.stack){var e=t.stack,i=t+"\n";return e.substring(0,i.length)==i&&(e=e.substring(i.length)),e.split("\n")}return[]}function fyn(n){var t;return Ein(),(t=Itt)[n>>>28]|t[n>>24&15]<<4|t[n>>20&15]<<8|t[n>>16&15]<<12|t[n>>12&15]<<16|t[n>>8&15]<<20|t[n>>4&15]<<24|t[15&n]<<28}function lyn(n){var t,e,r;n.b==n.c&&(r=n.a.length,e=mon(i.Math.max(8,r))<<1,0!=n.b?(crn(n,t=TR(n.a,e),r),n.a=t,n.b=0):Mv(n.a,e),n.c=r)}function byn(n,t){var e;return(e=n.b).Xe((uWn(),rPt))?e.Hf()==(mUn(),SCt)?-e.rf().a-Hy(ED(e.We(rPt))):t+Hy(ED(e.We(rPt))):e.Hf()==(mUn(),SCt)?-e.rf().a:t}function wyn(n){var t;return 0!=n.b.c.length&&_B(Lq(n.b,0),70).a?_B(Lq(n.b,0),70).a:null!=(t=nQ(n))?t:""+(n.c?k7(n.c.a,n,0):-1)}function dyn(n){var t;return 0!=n.f.c.length&&_B(Lq(n.f,0),70).a?_B(Lq(n.f,0),70).a:null!=(t=nQ(n))?t:""+(n.i?k7(n.i.j,n,0):-1)}function gyn(n,t){var e,i;if(t<0||t>=n.gc())return null;for(e=t;e0?n.c:0),c=i.Math.max(c,t.d),++r;n.e=a,n.b=c}function myn(n){var t,e;if(!n.b)for(n.b=S2(_B(n.f,118).Ag().i),e=new CL(_B(n.f,118).Ag());e.e!=e.i.gc();)t=_B(mpn(e),137),UB(n.b,new xy(t));return n.b}function yyn(n,t){var e,i,r;if(t.dc())return bD(),bD(),wAt;for(e=new rR(n,t.gc()),r=new CL(n);r.e!=r.i.gc();)i=mpn(r),t.Hc(i)&&s9(e,i);return e}function kyn(n,t,e,i){return 0==t?i?(!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),n.o):(!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),C8(n.o)):Jpn(n,t,e,i)}function jyn(n){var t,e;if(n.rb)for(t=0,e=n.rb.i;t>22))>>22)<0||(n.l=e&TQn,n.m=i&TQn,n.h=r&MQn,0)))}function Pyn(n,t,e,i,r,c,a){var u,o;return!(t.Ae()&&(o=n.a.ue(e,i),o<0||!r&&0==o)||t.Be()&&(u=n.a.ue(e,c),u>0||!a&&0==u))}function Iyn(n,t){if(qsn(),0!=n.j.g-t.j.g)return 0;switch(n.j.g){case 2:return ybn(t,fst)-ybn(n,fst);case 4:return ybn(n,hst)-ybn(t,hst)}return 0}function Cyn(n){switch(n.g){case 0:return Lht;case 1:return Nht;case 2:return xht;case 3:return Dht;case 4:return Rht;case 5:return Kht;default:return null}}function Oyn(n,t,e){var i,r;return Phn(r=new Am,t),$rn(r,e),s9((!n.c&&(n.c=new nU(WAt,n,12,10)),n.c),r),Aen(i=r,0),$en(i,1),Yfn(i,!0),Vfn(i,!0),i}function Ayn(n,t){var e,i;if(t>=n.i)throw Fp(new AO(t,n.i));return++n.j,e=n.g[t],(i=n.i-t-1)>0&&rHn(n.g,t+1,n.g,t,i),OX(n.g,--n.i,null),n.fi(t,e),n.ci(),e}function $yn(n,t){var e;return n.Db>>16==17?n.Cb.ih(n,21,FAt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||n.zh(),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Lyn(n){var t,e,i;for(TQ(),p$(n.c,n.a),i=new Ub(n.c);i.ae.a.c.length))throw Fp(new Ry("index must be >= 0 and <= layer node count"));n.c&&v7(n.c.a,n),n.c=e,e&&mG(e.a,t,n)}function Vyn(n,t){var e,i,r;for(i=new az(JL(obn(n).a.Kc(),new h));bAn(i);)return e=_B(G5(i),17),new Bf(vX((r=_B(t.Kb(e),10)).n.b+r.o.b/2));return ty(),ty(),Int}function Qyn(n,t){this.c=new Lp,this.a=n,this.b=t,this.d=_B(pMn(n,(oWn(),Clt)),304),HC(pMn(n,(FXn(),Agt)))===HC((w7(),Bht))?this.e=new wm:this.e=new bm}function Jyn(n,t){var e,r,c;for(c=0,r=new Ub(n);r.a>16==6?n.Cb.ih(n,6,DOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(SXn(),vOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function okn(n,t){var e;return n.Db>>16==7?n.Cb.ih(n,1,LOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(SXn(),yOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function skn(n,t){var e;return n.Db>>16==9?n.Cb.ih(n,9,qOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(SXn(),jOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function hkn(n,t){var e;return n.Db>>16==5?n.Cb.ih(n,9,GAt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(wWn(),a$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function fkn(n,t){var e;return n.Db>>16==3?n.Cb.ih(n,0,KOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(wWn(),ZAt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function lkn(n,t){var e;return n.Db>>16==7?n.Cb.ih(n,6,BOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(wWn(),d$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function bkn(){this.a=new lo,this.g=new Cvn,this.j=new Cvn,this.b=new Lp,this.d=new Cvn,this.i=new Cvn,this.k=new Lp,this.c=new Lp,this.e=new Lp,this.f=new Lp}function wkn(n,t,e){var i,r,c;for(e<0&&(e=0),c=n.i,r=e;rHQn)return gkn(n,i);if(i==n)return!0}}return!1}function pkn(n){switch(NN(),n.q.g){case 5:gCn(n,(mUn(),uCt)),gCn(n,TCt);break;case 4:q$n(n,(mUn(),uCt)),q$n(n,TCt);break;default:gUn(n,(mUn(),uCt)),gUn(n,TCt)}}function vkn(n){switch(NN(),n.q.g){case 5:TOn(n,(mUn(),aCt)),TOn(n,SCt);break;case 4:Spn(n,(mUn(),aCt)),Spn(n,SCt);break;default:pUn(n,(mUn(),aCt)),pUn(n,SCt)}}function mkn(n){var t,e;(t=_B(pMn(n,(sRn(),Yct)),19))?(e=t.a,oon(n,(Ern(),oat),0==e?new ubn:new S4(e))):oon(n,(Ern(),oat),new S4(1))}function ykn(n,t){var e;switch(e=n.i,t.g){case 1:return-(n.n.b+n.o.b);case 2:return n.n.a-e.o.a;case 3:return n.n.b-e.o.b;case 4:return-(n.n.a+n.o.a)}return 0}function kkn(n,t){switch(n.g){case 0:return t==(jbn(),Klt)?est:ist;case 1:return t==(jbn(),Klt)?est:tst;case 2:return t==(jbn(),Klt)?tst:ist;default:return tst}}function jkn(n,t){var e,r,c;for(v7(n.a,t),n.e-=t.r+(0==n.a.c.length?0:n.c),c=Y3n,r=new Ub(n.a);r.a>16==3?n.Cb.ih(n,12,qOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(SXn(),pOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Tkn(n,t){var e;return n.Db>>16==11?n.Cb.ih(n,10,qOt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(SXn(),kOt),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Mkn(n,t){var e;return n.Db>>16==10?n.Cb.ih(n,11,FAt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(wWn(),b$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Skn(n,t){var e;return n.Db>>16==10?n.Cb.ih(n,12,XAt,t):(e=Svn(_B(ttn(_B(van(n,16),26)||(wWn(),g$t),n.Db>>16),18)),n.Cb.ih(n,e.n,e.f,t))}function Pkn(n){var t;return 0==(1&n.Bb)&&n.r&&n.r.kh()&&(t=_B(n.r,49),n.r=_B(Zhn(n,t),138),n.r!=t&&0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,9,8,t,n.r))),n.r}function Ikn(n,t,e){var r;return r=Mun(Hk($Nt,1),BQn,25,15,[tMn(n,(Ntn(),Hit),t,e),tMn(n,qit,t,e),tMn(n,Git,t,e)]),n.f&&(r[0]=i.Math.max(r[0],r[2]),r[2]=r[0]),r}function Ckn(n,t){var e,i,r;if(0!=(r=Vvn(n,t)).c.length)for(p$(r,new ti),e=r.c.length,i=0;i>19)!=(u=t.h>>19)?u-a:(i=n.h)!=(c=t.h)?i-c:(e=n.m)!=(r=t.m)?e-r:n.l-t.l}function Rkn(){Rkn=O,ZDn(),Mit=new OO(GJn,Sit=Lit),xnn(),Eit=new OO(zJn,Tit=pit),opn(),kit=new OO(UJn,jit=bit),yit=new OO(XJn,(oN(),!0))}function Kkn(n,t,e){var i,r;i=t*e,iL(n.g,145)?(r=s3(n)).f.d?r.f.a||(n.d.a+=i+sYn):(n.d.d-=i+sYn,n.d.a+=i+sYn):iL(n.g,10)&&(n.d.d-=i,n.d.a+=2*i)}function _kn(n,t,e){var r,c,a,u,o;for(c=n[e.g],o=new Ub(t.d);o.a0?n.g:0),++e;t.b=r,t.e=c}function Bkn(n){var t,e,i;if(i=n.b,BT(n.i,i.length)){for(e=2*i.length,n.b=L8(Hnt,SVn,317,e,0,1),n.c=L8(Hnt,SVn,317,e,0,1),n.f=e-1,n.i=0,t=n.a;t;t=t.c)VIn(n,t,t);++n.g}}function Hkn(n,t,e,i){var r,c,a,u;for(r=0;ru&&(o=u/r),(c=i.Math.abs(n.b))>a&&(s=a/c),mL(n,i.Math.min(o,s)),n}function zkn(){var n,t;BBn();try{if(t=_B(zjn((UM(),HAt),v6n),2014))return t}catch(e){if(!iL(e=hun(e),102))throw Fp(e);n=e,cz((c$(),n))}return new ao}function Ukn(){var n,t;b7();try{if(t=_B(zjn((UM(),HAt),T7n),2024))return t}catch(e){if(!iL(e=hun(e),102))throw Fp(e);n=e,cz((c$(),n))}return new Ds}function Xkn(){var n,t;BBn();try{if(t=_B(zjn((UM(),HAt),X9n),1941))return t}catch(e){if(!iL(e=hun(e),102))throw Fp(e);n=e,cz((c$(),n))}return new qo}function Wkn(n,t,e){var i,r;return r=n.e,n.e=t,0!=(4&n.Db)&&0==(1&n.Db)&&(i=new Yz(n,1,4,r,t),e?e.Ei(i):e=i),r!=t&&(e=rzn(n,t?mLn(n,t):n.a,e)),e}function Vkn(){CT.call(this),this.e=-1,this.a=!1,this.p=RVn,this.k=-1,this.c=-1,this.b=-1,this.g=!1,this.f=-1,this.j=-1,this.n=-1,this.i=-1,this.d=-1,this.o=RVn}function Qkn(n,t){var e,i,r;if(i=n.b.d.d,n.a||(i+=n.b.d.a),r=t.b.d.d,t.a||(r+=t.b.d.a),0==(e=Mln(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function Jkn(n,t){var e,i,r;if(i=n.b.b.d,n.a||(i+=n.b.b.a),r=t.b.b.d,t.a||(r+=t.b.b.a),0==(e=Mln(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function Ykn(n,t){var e,i,r;if(i=n.b.g.d,n.a||(i+=n.b.g.a),r=t.b.g.d,t.a||(r+=t.b.g.a),0==(e=Mln(i,r))){if(!n.a&&t.a)return-1;if(!t.a&&n.a)return 1}return e}function Zkn(){Zkn=O,$at=UG(bq(bq(bq(new _2,(vMn(),Kat),(hWn(),vot)),Kat,jot),_at,Cot),_at,aot),Nat=bq(bq(new _2,Kat,Qut),Kat,uot),Lat=UG(new _2,_at,sot)}function njn(n){var t,e,i,r,c;for(t=_B(pMn(n,(oWn(),qft)),83),c=n.n,i=t.Cc().Kc();i.Ob();)(r=(e=_B(i.Pb(),306)).i).c+=c.a,r.d+=c.b,e.c?$Dn(e):LDn(e);oon(n,qft,null)}function tjn(n,t,e){var i,r;switch(i=(r=n.b).d,t.g){case 1:return-i.d-e;case 2:return r.o.a+i.c+e;case 3:return r.o.b+i.a+e;case 4:return-i.b-e;default:return-1}}function ejn(n){var t,e,i,r,c;if(i=0,r=JYn,n.b)for(t=0;t<360;t++)e=.017453292519943295*t,GKn(n,n.d,0,0,J3n,e),(c=n.b.ig(n.d))0&&(r=rOn(n,(c&NWn)%n.d.length,c,t))?r.ed(e):(i=n.tj(c,t,e),n.c.Fc(i),null)}function pjn(n,t){var e,i,r,c;switch(Sfn(n,t)._k()){case 3:case 2:for(r=0,c=(e=VBn(t)).i;r=0;r--)if(pK(n[r].d,t)||pK(n[r].d,e)){n.length>=r+1&&n.splice(0,r+1);break}return n}function Ijn(n,t){var e;return QO(n)&&QO(t)&&OQn<(e=n/t)&&e0&&(n.b+=2,n.a+=r):(n.b+=1,n.a+=i.Math.min(r,c))}function Djn(n,t){var e;if(e=!1,zC(t)&&(e=!0,YX(n,new HX(TD(t)))),e||iL(t,236)&&(e=!0,YX(n,new Tl(zK(_B(t,236))))),!e)throw Fp(new Ay(F6n))}function Rjn(n,t,e,i){var r,c,a;return r=new $7(n.e,1,10,iL(a=t.c,88)?_B(a,26):(wWn(),l$t),iL(c=e.c,88)?_B(c,26):(wWn(),l$t),cvn(n,t),!1),i?i.Ei(r):i=r,i}function Kjn(n){var t,e;switch(_B(pMn(gW(n),(FXn(),dgt)),420).g){case 0:return t=n.n,e=n.o,new LI(t.a+e.a/2,t.b+e.b/2);case 1:return new lA(n.n);default:return null}}function _jn(){_jn=O,Wht=new CP(WZn,0),Xht=new CP("LEFTUP",1),Qht=new CP("RIGHTUP",2),Uht=new CP("LEFTDOWN",3),Vht=new CP("RIGHTDOWN",4),zht=new CP("BALANCED",5)}function Fjn(n,t,e){var i,r,c;if(0==(i=Mln(n.a[t.p],n.a[e.p]))){if(r=_B(pMn(t,(oWn(),ilt)),15),c=_B(pMn(e,ilt),15),r.Hc(e))return-1;if(c.Hc(t))return 1}return i}function Bjn(n){switch(n.g){case 1:return new _a;case 2:return new Fa;case 3:return new Ka;case 0:return null;default:throw Fp(new Ry(i4n+(null!=n.f?n.f:""+n.g)))}}function Hjn(n,t,e){switch(t){case 1:return!n.n&&(n.n=new nU(HOt,n,1,7)),uqn(n.n),!n.n&&(n.n=new nU(HOt,n,1,7)),void dX(n.n,_B(e,14));case 2:return void Oin(n,TD(e))}esn(n,t,e)}function qjn(n,t,e){switch(t){case 3:return void Een(n,Hy(ED(e)));case 4:return void Ten(n,Hy(ED(e)));case 5:return void Men(n,Hy(ED(e)));case 6:return void Sen(n,Hy(ED(e)))}Hjn(n,t,e)}function Gjn(n,t,e){var i,r;(i=FTn(r=new Am,t,null))&&i.Fi(),$rn(r,e),s9((!n.c&&(n.c=new nU(WAt,n,12,10)),n.c),r),Aen(r,0),$en(r,1),Yfn(r,!0),Vfn(r,!0)}function zjn(n,t){var e,i;return iL(e=oS(n.g,t),235)?((i=_B(e,235)).Qh(),i.Nh()):iL(e,498)?i=_B(e,1938).b:null}function Ujn(n,t,e,i){var r,c;return vX(t),vX(e),x7(!!(c=_B(GK(n.d,t),19)),"Row %s not in %s",t,n.e),x7(!!(r=_B(GK(n.b,e),19)),"Column %s not in %s",e,n.c),Tun(n,c.a,r.a,i)}function Xjn(n,t,e,i,r,c,a){var u,o,s,h,f;if(f=_mn(u=(s=c==a-1)?i:0,h=r[c]),10!=i&&Mun(Hk(n,a-c),t[c],e[c],u,f),!s)for(++c,o=0;o1||-1==u?(c=_B(o,15),r.Wb(zdn(n,c))):r.Wb(ZKn(n,_B(o,56))))}function oEn(n,t,e,i){VE();var r=MWn;function c(){for(var n=0;nN3n)return e;i>-1e-6&&++e}return e}function mEn(n,t){var e;t!=n.b?(e=null,n.b&&(e=aY(n.b,n,-4,e)),t&&(e=$pn(t,n,-4,e)),(e=Jhn(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,3,t,t))}function yEn(n,t){var e;t!=n.f?(e=null,n.f&&(e=aY(n.f,n,-1,e)),t&&(e=$pn(t,n,-1,e)),(e=Yhn(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,0,t,t))}function kEn(n){var t,e,i;if(null==n)return null;if((e=_B(n,15)).dc())return"";for(i=new Tk,t=e.Kc();t.Ob();)iO(i,(Gqn(),TD(t.Pb()))),i.a+=" ";return DO(i,i.a.length-1)}function jEn(n){var t,e,i;if(null==n)return null;if((e=_B(n,15)).dc())return"";for(i=new Tk,t=e.Kc();t.Ob();)iO(i,(Gqn(),TD(t.Pb()))),i.a+=" ";return DO(i,i.a.length-1)}function EEn(n,t,e){var i,r;return i=n.c[t.c.p][t.p],r=n.c[e.c.p][e.p],null!=i.a&&null!=r.a?jz(i.a,r.a):null!=i.a?-1:null!=r.a?1:0}function TEn(n,t){var e,i,r;if(t)for(r=((e=new oz(t.a.length)).b-e.a)*e.c<0?(nS(),jNt):new zL(e);r.Ob();)i=L2(t,_B(r.Pb(),19).a),IV(new _g(n).a,i)}function MEn(n,t){var e,i,r;if(t)for(r=((e=new oz(t.a.length)).b-e.a)*e.c<0?(nS(),jNt):new zL(e);r.Ob();)i=L2(t,_B(r.Pb(),19).a),PV(new Og(n).a,i)}function SEn(n){if(null!=n&&n.length>0&&33==sV(n,n.length-1))try{return null==VPn(sx(n,0,n.length-1)).e}catch(t){if(!iL(t=hun(t),32))throw Fp(t)}return!1}function PEn(n,t,e){var i,r,c;return i=t.ak(),c=t.dd(),r=i.$j()?AJ(n,3,i,null,c,dBn(n,i,c,iL(i,99)&&0!=(_B(i,18).Bb&_Qn)),!0):AJ(n,1,i,i.zj(),c,-1,!0),e?e.Ei(r):e=r,e}function IEn(){var n,t,e;for(t=0,n=0;n<"X".length;n++){if(0==(e=WOn((f1(n,"X".length),"X".charCodeAt(n)))))throw Fp(new rk("Unknown Option: "+"X".substr(n)));t|=e}return t}function CEn(n,t,e){var i,r;switch(i=Uln(gW(t)),SZ(r=new SSn,t),e.g){case 1:BIn(r,jln(own(i)));break;case 2:BIn(r,own(i))}return oon(r,(FXn(),Zgt),ED(pMn(n,Zgt))),r}function OEn(n){var t,e;return t=_B(G5(new az(JL(sbn(n.a).a.Kc(),new h))),17),e=_B(G5(new az(JL(hbn(n.a).a.Kc(),new h))),17),By(jD(pMn(t,(oWn(),Slt))))||By(jD(pMn(e,Slt)))}function AEn(){AEn=O,Est=new vP("ONE_SIDE",0),Mst=new vP("TWO_SIDES_CORNER",1),Sst=new vP("TWO_SIDES_OPPOSING",2),Tst=new vP("THREE_SIDES",3),jst=new vP("FOUR_SIDES",4)}function $En(n,t,e,i,r){var c,a;c=_B(M4(CV(t.Oc(),new Zr),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),Get)]))),15),a=_B(wan(n.b,e,i),15),0==r?a.Wc(0,c):a.Gc(c)}function LEn(n,t){var e,i,r;for(i=new Ub(t.a);i.a0&&Ryn(this,this.c-1,(mUn(),aCt)),this.c0&&n[0].length>0&&(this.c=By(jD(pMn(gW(n[0][0]),(oWn(),rlt))))),this.a=L8(Mmt,uVn,2018,n.length,0,2),this.b=L8(Amt,uVn,2019,n.length,0,2),this.d=new jhn}function zEn(n){return 0!=n.c.length&&((h1(0,n.c.length),_B(n.c[0],17)).c.i.k==(cSn(),Mut)||a5(OV(new xq(null,new l1(n,16)),new Kc),new _c))}function UEn(n,t,e){return ITn(e,"Tree layout",1),o2(n.b),SU(n.b,(qyn(),xyt),xyt),SU(n.b,Dyt,Dyt),SU(n.b,Ryt,Ryt),SU(n.b,Kyt,Kyt),n.a=Oqn(n.b,t),hxn(n,t,pcn(e,1)),FSn(e),t}function XEn(n,t){var e,r,c,a,u,o;for(u=lDn(t),c=t.f,o=t.g,a=i.Math.sqrt(c*c+o*o),r=0,e=new Ub(u);e.a=0?(e=Ijn(n,CQn),i=hdn(n,CQn)):(e=Ijn(t=yz(n,1),5e8),i=ebn(vz(i=hdn(t,5e8),1),n0(n,1))),t0(vz(i,32),n0(e,GQn))}function hTn(n,t,e){var i;switch(Mx(0!=t.b),i=_B(Ctn(t,t.a.a),8),e.g){case 0:i.b=0;break;case 2:i.b=n.f;break;case 3:i.a=0;break;default:i.a=n.g}return YU(upn(t,0),i),t}function fTn(n,t,e,i){var r,c,a,u,o;switch(o=n.b,u=qgn(a=(c=t.d).j,o.d[a.g],e),r=GR(_$(c.n),c.a),c.j.g){case 1:case 3:u.a+=r.a;break;case 2:case 4:u.b+=r.b}e5(i,u,i.c.b,i.c)}function lTn(n,t,e){var i,r,c,a;for(a=k7(n.e,t,0),(c=new em).b=e,i=new E2(n.e,a);i.b1;t>>=1)0!=(1&t)&&(i=$nn(i,e)),e=1==e.d?$nn(e,e):new Sgn(P_n(e.a,e.d,L8(INt,oQn,25,e.d<<1,15,1)));return i=$nn(i,e)}function vTn(){var n,t,e,i;for(vTn=O,Iet=L8($Nt,BQn,25,25,15,1),Cet=L8($Nt,BQn,25,33,15,1),i=152587890625e-16,t=32;t>=0;t--)Cet[t]=i,i*=.5;for(e=1,n=24;n>=0;n--)Iet[n]=e,e*=.5}function mTn(n){var t,e;if(By(jD(JAn(n,(FXn(),lgt)))))for(e=new az(JL(bLn(n).a.Kc(),new h));bAn(e);)if(WCn(t=_B(G5(e),79))&&By(jD(JAn(t,bgt))))return!0;return!1}function yTn(n,t){var e,i,r;jU(n.f,t)&&(t.b=n,i=t.c,-1!=k7(n.j,i,0)||UB(n.j,i),r=t.d,-1!=k7(n.j,r,0)||UB(n.j,r),0!=(e=t.a.b).c.length&&(!n.i&&(n.i=new npn(n)),gan(n.i,e)))}function kTn(n){var t,e,i,r;return(e=(t=n.c.d).j)==(r=(i=n.d.d).j)?t.p=0&&pK(n.substr(t,"GMT".length),"GMT")||t>=0&&pK(n.substr(t,"UTC".length),"UTC")?(e[0]=t+3,v_n(n,e,i)):v_n(n,e,i)}function PTn(n,t){var e,i,r,c,a;for(c=n.g.a,a=n.g.b,i=new Ub(n.d);i.ae;c--)n[c]|=t[c-e-1]>>>a,n[c-1]=t[c-e-1]<=n.f)break;c.c[c.c.length]=e}return c}function RTn(n){var t,e,i,r;for(t=null,r=new Ub(n.wf());r.a0&&rHn(n.g,t,n.g,t+i,u),a=e.Kc(),n.i+=i,r=0;rc&&uU(s,rtn(e[u],jet))&&(r=u,c=o);return r>=0&&(i[0]=t+c),r}function GTn(n,t){var e;if(0!=(e=VO(n.b.Hf(),t.b.Hf())))return e;switch(n.b.Hf().g){case 1:case 2:return k$(n.b.sf(),t.b.sf());case 3:case 4:return k$(t.b.sf(),n.b.sf())}return 0}function zTn(n){var t,e,i;for(i=n.e.c.length,n.a=mq(INt,[uVn,oQn],[48,25],15,[i,i],2),e=new Ub(n.c);e.a>4&15,c=15&n[i],a[r++]=IOt[e],a[r++]=IOt[c];return _dn(a,0,a.length)}function WTn(n,t,e){var i,r,c;return i=t.ak(),c=t.dd(),r=i.$j()?AJ(n,4,i,c,null,dBn(n,i,c,iL(i,99)&&0!=(_B(i,18).Bb&_Qn)),!0):AJ(n,i.Kj()?2:1,i,c,i.zj(),-1,!0),e?e.Ei(r):e=r,e}function VTn(n){var t,e;return n>=_Qn?(t=FQn+(n-_Qn>>10&1023)&WVn,e=56320+(n-_Qn&1023)&WVn,String.fromCharCode(t)+""+String.fromCharCode(e)):String.fromCharCode(n&WVn)}function QTn(n,t){var e,i,r,c;return BD(),(r=_B(_B(o6(n.r,t),21),84)).gc()>=2&&(i=_B(r.Kc().Pb(),111),e=n.u.Hc((hCn(),ZIt)),c=n.u.Hc(iCt),!i.a&&!e&&(2==r.gc()||c))}function JTn(n,t,e,i,r){var c,a,u;for(c=nDn(n,t,e,i,r),u=!1;!c;)k$n(n,r,!0),u=!0,c=nDn(n,t,e,i,r);u&&k$n(n,r,!1),0!=(a=Nun(r)).c.length&&(n.d&&n.d.lg(a),JTn(n,r,e,i,a))}function YTn(){YTn=O,rIt=new _I(WZn,0),eIt=new _I("DIRECTED",1),cIt=new _I("UNDIRECTED",2),nIt=new _I("ASSOCIATION",3),iIt=new _I("GENERALIZATION",4),tIt=new _I("DEPENDENCY",5)}function ZTn(n,t){var e;if(!UY(n))throw Fp(new Ky(K5n));switch(e=UY(n),t.g){case 1:return-(n.j+n.f);case 2:return n.i-e.g;case 3:return n.j-e.f;case 4:return-(n.i+n.g)}return 0}function nMn(n,t){var e,i;for(mW(t),i=n.b.c.length,UB(n.b,t);i>0;){if(e=i,i=(i-1)/2|0,n.a.ue(Lq(n.b,i),t)<=0)return i5(n.b,e,t),!0;i5(n.b,e,Lq(n.b,i))}return i5(n.b,i,t),!0}function tMn(n,t,e,r){var c,a;if(c=0,e)c=phn(n.a[e.g][t.g],r);else for(a=0;a=a)}function iMn(n,t,e,i){var r;if(r=!1,zC(i)&&(r=!0,CH(t,e,TD(i))),r||qC(i)&&(r=!0,iMn(n,t,e,i)),r||iL(i,236)&&(r=!0,BQ(t,e,_B(i,236))),!r)throw Fp(new Ay(F6n))}function rMn(n,t){var e,i,r;if((e=t.Hh(n.a))&&null!=(r=idn((!e.b&&(e.b=new Qx((wWn(),v$t),G$t,e)),e.b),K9n)))for(i=1;i<(PPn(),W$t).length;++i)if(pK(W$t[i],r))return i;return 0}function cMn(n,t){var e,i,r;if((e=t.Hh(n.a))&&null!=(r=idn((!e.b&&(e.b=new Qx((wWn(),v$t),G$t,e)),e.b),K9n)))for(i=1;i<(PPn(),V$t).length;++i)if(pK(V$t[i],r))return i;return 0}function aMn(n,t){var e,i,r,c;if(mW(t),(c=n.a.gc())0?1:0;c.a[r]!=e;)c=c.a[r],r=n.a.ue(e.d,c.d)>0?1:0;c.a[r]=i,i.b=e.b,i.a[0]=e.a[0],i.a[1]=e.a[1],e.a[0]=null,e.a[1]=null}function lMn(n){return hCn(),!(San(IY(kG(nCt,Mun(Hk(PCt,1),OVn,273,0,[eCt])),n))>1||San(IY(kG(ZIt,Mun(Hk(PCt,1),OVn,273,0,[YIt,iCt])),n))>1)}function bMn(n,t){iL(TY((UM(),HAt),n),498)?pZ(HAt,n,new IC(this,t)):pZ(HAt,n,this),tSn(this,t),t==(tE(),JAt)?(this.wb=_B(this,1939),_B(t,1941)):this.wb=(WX(),YAt)}function wMn(n){var t,e;if(null==n)return null;for(t=null,e=0;e=XVn?"error":i>=900?"warn":i>=800?"info":"log",n.a),n.b&&LNn(t,e,n.b,"Exception: ",!0))}function pMn(n,t){var e,i;return!n.q&&(n.q=new Lp),null!=(i=xX(n.q,t))?i:(iL(e=t.wg(),4)&&(null==e?(!n.q&&(n.q=new Lp),g6(n.q,t)):(!n.q&&(n.q=new Lp),XW(n.q,t,e))),e)}function vMn(){vMn=O,xat=new XS("P1_CYCLE_BREAKING",0),Dat=new XS("P2_LAYERING",1),Rat=new XS("P3_NODE_ORDERING",2),Kat=new XS("P4_NODE_PLACEMENT",3),_at=new XS("P5_EDGE_ROUTING",4)}function mMn(n,t){var e,i,r,c;for(i=(1==t?Uat:zat).a.ec().Kc();i.Ob();)for(e=_B(i.Pb(),103),c=_B(o6(n.f.c,e),21).Kc();c.Ob();)r=_B(c.Pb(),46),v7(n.b.b,r.b),v7(n.b.a,_B(r.b,81).d)}function yMn(n,t){var e;if(Nnn(),n.c==t.c){if(n.b==t.b||ocn(n.b,t.b)){if(e=JO(n.b)?1:-1,n.a&&!t.a)return e;if(!n.a&&t.a)return-e}return k$(n.b.g,t.b.g)}return Mln(n.c,t.c)}function kMn(n,t){var e;ITn(t,"Hierarchical port position processing",1),(e=n.b).c.length>0&&t_n((h1(0,e.c.length),_B(e.c[0],29)),n),e.c.length>1&&t_n(_B(Lq(e,e.c.length-1),29),n),FSn(t)}function jMn(n,t){var e,i;if($Mn(n,t))return!0;for(i=new Ub(t);i.a=(r=n.Vi())||t<0)throw Fp(new Cy(c8n+t+a8n+r));if(e>=r||e<0)throw Fp(new Cy(u8n+e+a8n+r));return t!=e?(c=n.Ti(e),n.Hi(t,c),i=c):i=n.Oi(e),i}function OMn(n){var t,e,i;if(i=n,n)for(t=0,e=n.Ug();e;e=e.Ug()){if(++t>HQn)return OMn(e);if(i=e,e==n)throw Fp(new Ky("There is a cycle in the containment hierarchy of "+n))}return i}function AMn(n){var t,e,i;for(i=new Oan(KWn,"[","]"),e=n.Kc();e.Ob();)f6(i,HC(t=e.Pb())===HC(n)?"(this Collection)":null==t?qWn:_bn(t));return i.a?0==i.e.length?i.a.a:i.a.a+""+i.e:i.c}function $Mn(n,t){var e,i;if(i=!1,t.gc()<2)return!1;for(e=0;ei&&(f1(t-1,n.length),n.charCodeAt(t-1)<=32);)--t;return i>0||t1&&(n.j.b+=n.e)):(n.j.a+=e.a,n.j.b=i.Math.max(n.j.b,e.b),n.d.c.length>1&&(n.j.a+=n.e))}function RMn(){RMn=O,Ost=Mun(Hk(KCt,1),VZn,61,0,[(mUn(),uCt),aCt,TCt]),Cst=Mun(Hk(KCt,1),VZn,61,0,[aCt,TCt,SCt]),Ast=Mun(Hk(KCt,1),VZn,61,0,[TCt,SCt,uCt]),$st=Mun(Hk(KCt,1),VZn,61,0,[SCt,uCt,aCt])}function KMn(n,t,e,i){var r,c,a,u,o;if(c=n.c.d,a=n.d.d,c.j!=a.j)for(o=n.b,r=c.j,u=null;r!=a.j;)u=0==t?Eln(r):kln(r),NH(i,GR(qgn(r,o.d[r.g],e),qgn(u,o.d[u.g],e))),r=u}function _Mn(n,t,e,i){var r,c,a,u,o;return u=_B((a=Byn(n.a,t,e)).a,19).a,c=_B(a.b,19).a,i&&(o=_B(pMn(t,(oWn(),klt)),10),r=_B(pMn(e,klt),10),o&&r&&(Z3(n.b,o,r),u+=n.b.i,c+=n.b.e)),u>c}function FMn(n){var t,e,i,r,c,a,u,o;for(this.a=evn(n),this.b=new $p,i=0,r=(e=n).length;iKD(n.d).c?(n.i+=n.g.c,wdn(n.d)):KD(n.d).c>KD(n.g).c?(n.e+=n.d.c,wdn(n.g)):(n.i+=Bq(n.g),n.e+=Bq(n.d),wdn(n.g),wdn(n.d))}function GMn(n,t,e){var i,r,c,a;for(c=t.q,a=t.r,new qZ((I6(),jyt),t,c,1),new qZ(jyt,c,a,1),r=new Ub(e);r.ao&&(s=o/r),(c=i.Math.abs(t.b-n.b))>a&&(h=a/c),u=i.Math.min(s,h),n.a+=u*(t.a-n.a),n.b+=u*(t.b-n.b)}function YMn(n,t,e,i,r){var c,a;for(a=!1,c=_B(Lq(e.b,0),33);oBn(n,t,c,i,r)&&(a=!0,iEn(e,c),0!=e.b.c.length);)c=_B(Lq(e.b,0),33);return 0==e.b.c.length&&jkn(e.j,e),a&&Hmn(t.q),a}function ZMn(n,t){var e,i,r,c;if(yDn(),t.b<2)return!1;for(i=e=_B(f3(c=upn(t,0)),8);c.b!=c.d.c;){if(iNn(n,i,r=_B(f3(c),8)))return!0;i=r}return!!iNn(n,i,e)}function nSn(n,t,e,i){return 0==e?(!n.o&&(n.o=new v9((SXn(),EOt),tAt,n,0)),_K(n.o,t,i)):_B(ttn(_B(van(n,16),26)||n.zh(),e),66).Nj().Rj(n,sgn(n),e-fX(n.zh()),t,i)}function tSn(n,t){var e;t!=n.sb?(e=null,n.sb&&(e=_B(n.sb,49).ih(n,1,_Ot,e)),t&&(e=_B(t,49).gh(n,1,_Ot,e)),(e=yfn(n,t,e))&&e.Fi()):0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,4,t,t))}function eSn(n,t){var e,i;if(!t)throw Fp(new nk("All edge sections need an end point."));e=xen(t,"x"),jen(new Dg(n).a,(mW(e),e)),i=xen(t,"y"),Ien(new Rg(n).a,(mW(i),i))}function iSn(n,t){var e,i;if(!t)throw Fp(new nk("All edge sections need a start point."));e=xen(t,"x"),Pen(new Lg(n).a,(mW(e),e)),i=xen(t,"y"),Cen(new Ng(n).a,(mW(i),i))}function rSn(n,t){var e,i,r,c,a;for(i=0,c=dsn(n).length;i>22-t,r=n.h<>22-t):t<44?(e=0,i=n.l<>44-t):(e=0,i=0,r=n.l<n)throw Fp(new Ry("k must be smaller than n"));return 0==t||t==n?1:0==n?0:Ejn(n)/(Ejn(t)*Ejn(n-t))}function gSn(n,t){var e,i,r,c;for(e=new IA(n);null!=e.g||e.c?null==e.g||0!=e.i&&_B(e.g[e.i-1],47).Ob():ZY(e);)if(iL(c=_B(rLn(e),56),160))for(i=_B(c,160),r=0;r>4],t[2*e+1]=WLt[15&r];return _dn(t,0,t.length)}function $Sn(n){var t;switch(YW(),n.c.length){case 0:return _nt;case 1:return PH((t=_B(QIn(new Ub(n)),42)).cd(),t.dd());default:return new oy(_B(Wgn(n,L8(Fnt,mVn,42,n.c.length,0,1)),165))}}function LSn(n){var t,e,i,r,c;for(t=new Ap,e=new Ap,b3(t,n),b3(e,n);e.b!=e.c;)for(c=new Ub(_B(bU(e),37).a);c.a0&&cKn(n,e,t),r):POn(n,t,e)}function RSn(n,t,e){var i,r,c,a;if(0!=t.b){for(i=new VT,a=upn(t,0);a.b!=a.d.c;)Krn(i,Lun(c=_B(f3(a),86))),(r=c.e).a=_B(pMn(c,(Bqn(),wkt)),19).a,r.b=_B(pMn(c,dkt),19).a;RSn(n,i,pcn(e,i.b/n.a|0))}}function KSn(n,t){var e,i,r,c,a;if(n.e<=t)return n.g;if(q1(n,n.g,t))return n.g;for(c=n.r,i=n.g,a=n.r,r=(c-i)/2+i;i+11&&(n.e.b+=n.a)):(n.e.a+=e.a,n.e.b=i.Math.max(n.e.b,e.b),n.d.c.length>1&&(n.e.a+=n.a))}function zSn(n){var t,e,i,r;switch(t=(r=n.i).b,i=r.j,e=r.g,r.a.g){case 0:e.a=(n.g.b.o.a-i.a)/2;break;case 1:e.a=t.d.n.a+t.d.a.a;break;case 2:e.a=t.d.n.a+t.d.a.a-i.a;break;case 3:e.b=t.d.n.b+t.d.a.b}}function USn(n,t,e,i,r){if(ii&&(n.a=i),n.br&&(n.b=r),n}function XSn(n){if(iL(n,149))return ENn(_B(n,149));if(iL(n,229))return Jbn(_B(n,229));if(iL(n,23))return oSn(_B(n,23));throw Fp(new Ry(q6n+AMn(new Qy(Mun(Hk(Cnt,1),FWn,1,5,[n])))))}function WSn(n,t,e,i,r){var c,a,u;for(c=!0,a=0;a>>r|e[a+i+1]<>>r,++a}return c}function VSn(n,t,e,i){var r,c;if(t.k==(cSn(),Mut))for(c=new az(JL(sbn(t).a.Kc(),new h));bAn(c);)if((r=_B(G5(c),17)).c.i.k==Mut&&n.c.a[r.c.i.c.p]==i&&n.c.a[t.c.p]==e)return!0;return!1}function QSn(n,t){var e,i,r,c;return t&=63,e=n.h&MQn,t<22?(c=e>>>t,r=n.m>>t|e<<22-t,i=n.l>>t|n.m<<22-t):t<44?(c=0,r=e>>>t-22,i=n.m>>t-22|n.h<<44-t):(c=0,r=0,i=e>>>t-44),E$(i&TQn,r&TQn,c&MQn)}function JSn(n,t,e,i){var r;this.b=i,this.e=n==(ain(),Cmt),r=t[e],this.d=mq(CNt,[uVn,JJn],[177,25],16,[r.length,r.length],2),this.a=mq(INt,[uVn,oQn],[48,25],15,[r.length,r.length],2),this.c=new qEn(t,e)}function YSn(n){var t,e,i;for(n.k=new a1((mUn(),Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt])).length,n.j.c.length),i=new Ub(n.j);i.a=e)return oPn(n,t,i.p),!0;return!1}function iPn(n){var t;return 0!=(64&n.Db)?pSn(n):(t=new hN(J5n),!n.a||aO(aO((t.a+=' "',t),n.a),'"'),aO(mE(aO(mE(aO(mE(aO(mE((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function rPn(n,t,e){var i,r,c,a,u;for(u=rxn(n.e.Tg(),t),r=_B(n.g,119),i=0,a=0;ae?bIn(n,e,"start index"):t<0||t>e?bIn(t,e,"end index"):ORn("end index (%s) must not be less than start index (%s)",Mun(Hk(Cnt,1),FWn,1,5,[tln(t),tln(n)]))}function uPn(n,t){var e,i,r,c;for(i=0,r=n.length;i0&&hPn(n,c,e));t.p=0}function fPn(n){var t;this.c=new VT,this.f=n.e,this.e=n.d,this.i=n.g,this.d=n.c,this.b=n.b,this.k=n.j,this.a=n.a,n.i?this.j=n.i:this.j=new VK(t=_B(Xj(yMt),9),_B(TR(t,t.length),9),0),this.g=n.f}function lPn(n){var t,e,i,r;for(t=LX(aO(new hN("Predicates."),"and"),40),e=!0,r=new Tb(n);r.b0?u[a-1]:L8(Iut,r1n,10,0,0,1),r=u[a],s=a=0?n.Bh(r):iCn(n,i)}else Bfn(n,e,i)}function vPn(n){var t,e;if(e=null,t=!1,iL(n,204)&&(t=!0,e=_B(n,204).a),t||iL(n,258)&&(t=!0,e=""+_B(n,258).a),t||iL(n,483)&&(t=!0,e=""+_B(n,483).a),!t)throw Fp(new Ay(F6n));return e}function mPn(n,t){var e,i;if(n.f){for(;t.Ob();)if(iL(i=(e=_B(t.Pb(),72)).ak(),99)&&0!=(_B(i,18).Bb&o6n)&&(!n.e||i.Gj()!=AOt||0!=i.aj())&&null!=e.dd())return t.Ub(),!0;return!1}return t.Ob()}function yPn(n,t){var e,i;if(n.f){for(;t.Sb();)if(iL(i=(e=_B(t.Ub(),72)).ak(),99)&&0!=(_B(i,18).Bb&o6n)&&(!n.e||i.Gj()!=AOt||0!=i.aj())&&null!=e.dd())return t.Pb(),!0;return!1}return t.Sb()}function kPn(n,t,e){var i,r,c,a,u,o;for(o=rxn(n.e.Tg(),t),i=0,u=n.i,r=_B(n.g,119),a=0;a1&&(t.c[t.c.length]=c)}function TPn(n){var t,e,i;for(Krn(e=new VT,n.o),i=new am;0!=e.b;)UUn(n,t=_B(0==e.b?null:(Mx(0!=e.b),Ctn(e,e.a.a)),508),!0)&&UB(i.a,t);for(;0!=i.a.c.length;)UUn(n,t=_B(Zsn(i),508),!1)}function MPn(){MPn=O,mMt=new OI(oYn,0),lMt=new OI("BOOLEAN",1),gMt=new OI("INT",2),vMt=new OI("STRING",3),bMt=new OI("DOUBLE",4),wMt=new OI("ENUM",5),dMt=new OI("ENUMSET",6),pMt=new OI("OBJECT",7)}function SPn(n,t){var e,r,c,a,u;r=i.Math.min(n.c,t.c),a=i.Math.min(n.d,t.d),(c=i.Math.max(n.c+n.b,t.c+t.b))=(r/2|0))for(this.e=i?i.c:null,this.d=r;e++0;)kZ(this);this.b=t,this.a=null}function RPn(n,t){var e,i;t.a?qNn(n,t):(!!(e=_B(mK(n.b,t.b),57))&&e==n.a[t.b.f]&&!!e.a&&e.a!=t.b.a&&e.c.Fc(t.b),!!(i=_B(vK(n.b,t.b),57))&&n.a[i.f]==t.b&&!!i.a&&i.a!=t.b.a&&t.b.c.Fc(i),EN(n.b,t.b))}function KPn(n,t){var e,i;if(e=_B(aV(n.b,t),124),_B(_B(o6(n.r,t),21),84).dc())return e.n.b=0,void(e.n.c=0);e.n.b=n.C.b,e.n.c=n.C.c,n.A.Hc((pdn(),RCt))&&vRn(n,t),i=zpn(n,t),MDn(n,t)==(ipn(),_It)&&(i+=2*n.w),e.a.a=i}function _Pn(n,t){var e,i;if(e=_B(aV(n.b,t),124),_B(_B(o6(n.r,t),21),84).dc())return e.n.d=0,void(e.n.a=0);e.n.d=n.C.d,e.n.a=n.C.a,n.A.Hc((pdn(),RCt))&&mRn(n,t),i=Upn(n,t),MDn(n,t)==(ipn(),_It)&&(i+=2*n.w),e.a.b=i}function FPn(n,t){var e,i,r,c;for(c=new $p,i=new Ub(t);i.ae.a&&(i.Hc((lEn(),UMt))?r=(t.a-e.a)/2:i.Hc(WMt)&&(r=t.a-e.a)),t.b>e.b&&(i.Hc((lEn(),QMt))?c=(t.b-e.b)/2:i.Hc(VMt)&&(c=t.b-e.b)),hMn(n,r,c)}function fIn(n,t,e,i,r,c,a,u,o,s,h,f,l){iL(n.Cb,88)&&CIn(M5(_B(n.Cb,88)),4),$rn(n,e),n.f=a,Oln(n,u),$ln(n,o),Cln(n,s),Aln(n,h),Yfn(n,f),Bln(n,l),Vfn(n,!0),Aen(n,r),n.ok(c),Phn(n,t),null!=i&&(n.i=null,rrn(n,i))}function lIn(n){var t,e;if(n.f){for(;n.n>0;){if(iL(e=(t=_B(n.k.Xb(n.n-1),72)).ak(),99)&&0!=(_B(e,18).Bb&o6n)&&(!n.e||e.Gj()!=AOt||0!=e.aj())&&null!=t.dd())return!0;--n.n}return!1}return n.n>0}function bIn(n,t,e){if(n<0)return ORn(_Wn,Mun(Hk(Cnt,1),FWn,1,5,[e,tln(n)]));if(t<0)throw Fp(new Ry(BWn+t));return ORn("%s (%s) must not be greater than size (%s)",Mun(Hk(Cnt,1),FWn,1,5,[e,tln(n),tln(t)]))}function wIn(n,t,e,i,r,c){var a,u,o;if(i-e<7)Obn(t,e,i,c);else if(wIn(t,n,u=e+r,o=u+((a=i+r)-u>>1),-r,c),wIn(t,n,o,a,-r,c),c.ue(n[o-1],n[o])<=0)for(;e=0?n.sh(c,e):jLn(n,r,e)}else Abn(n,i,r,e)}function mIn(n){var t,e,i,r;if(e=_B(n,49).qh())try{if(i=null,(t=O$n((UM(),HAt),E_n(Rbn(e))))&&(r=t.rh())&&(i=r.Wk(zy(e.e))),i&&i!=n)return mIn(i)}catch(c){if(!iL(c=hun(c),60))throw Fp(c)}return n}function yIn(n,t,e){var i,r,c,a;if(a=null==t?0:n.b.se(t),0==(r=null==(i=n.a.get(a))?new Array:i).length)n.a.set(a,r);else if(c=ohn(n,t,r))return c.ed(e);return OX(r,r.length,new MS(t,e)),++n.c,aJ(n.b),null}function kIn(n,t){var e;return o2(n.a),SU(n.a,(Mrn(),Wkt),Wkt),SU(n.a,Vkt,Vkt),bq(e=new _2,Vkt,(Sbn(),njt)),HC(JAn(t,(Gyn(),Tjt)))!==HC((Fsn(),ujt))&&bq(e,Vkt,Ykt),bq(e,Vkt,Zkt),rA(n.a,e),Oqn(n.a,t)}function jIn(n){if(!n)return hk(),ott;var t=n.valueOf?n.valueOf():n;if(t!==n){var e=stt[typeof t];return e?e(t):mhn(typeof t)}return n instanceof Array||n instanceof i.Array?new jl(n):new Ml(n)}function EIn(n,t,e){var r,c,a;switch(a=n.o,(c=(r=_B(aV(n.p,e),244)).i).b=TCn(r),c.a=ECn(r),c.b=i.Math.max(c.b,a.a),c.b>a.a&&!t&&(c.b=a.a),c.c=-(c.b-a.a)/2,e.g){case 1:c.d=-c.a;break;case 3:c.d=a.b}RFn(r),HFn(r)}function TIn(n,t,e){var r,c,a;switch(a=n.o,(c=(r=_B(aV(n.p,e),244)).i).b=TCn(r),c.a=ECn(r),c.a=i.Math.max(c.a,a.b),c.a>a.b&&!t&&(c.a=a.b),c.d=-(c.a-a.b)/2,e.g){case 4:c.c=-c.b;break;case 2:c.c=a.a}RFn(r),HFn(r)}function MIn(n,t){var e,i,r,c,a;if(!t.dc())if(r=_B(t.Xb(0),128),1!=t.gc())for(e=1;e0)try{i=h_n(t,RVn,NWn)}catch(r){throw iL(r=hun(r),127)?Fp(new A7(r)):Fp(r)}return!n.a&&(n.a=new Tp(n)),i<(e=n.a).i&&i>=0?_B(Utn(e,i),56):null}function AIn(n,t){if(n<0)return ORn(_Wn,Mun(Hk(Cnt,1),FWn,1,5,["index",tln(n)]));if(t<0)throw Fp(new Ry(BWn+t));return ORn("%s (%s) must be less than size (%s)",Mun(Hk(Cnt,1),FWn,1,5,["index",tln(n),tln(t)]))}function $In(n){var t,e,i,r,c;if(null==n)return qWn;for(c=new Oan(KWn,"[","]"),i=0,r=(e=n).length;i0)for(a=n.c.d,r=mL(zR(new LI((u=n.d.d).a,u.b),a),1/(i+1)),c=new LI(a.a,a.b),e=new Ub(n.a);e.a=0?n._g(e,!0,!0):iOn(n,r,!0),153),_B(i,215).ol(t)}function rCn(n){var t,e;return n>-0x800000000000&&n<0x800000000000?0==n?0:((t=n<0)&&(n=-n),e=SY(i.Math.floor(i.Math.log(n)/.6931471805599453)),(!t||n!=i.Math.pow(2,e))&&++e,e):Xan(san(n))}function cCn(n){var t,e,i,r,c,a,u;for(c=new sA,e=new Ub(n);e.a2&&u.e.b+u.j.b<=2&&(r=u,i=a),c.a.zc(r,c),r.q=i);return c}function aCn(n,t){var e,i,r;return Ban(i=new Ovn(n),t),oon(i,(oWn(),Xft),t),oon(i,(FXn(),npt),(WEn(),zIt)),oon(i,mdt,(lvn(),IMt)),_l(i,(cSn(),Eut)),SZ(e=new SSn,i),BIn(e,(mUn(),SCt)),SZ(r=new SSn,i),BIn(r,aCt),i}function uCn(n){switch(n.g){case 0:return new $y((ain(),Imt));case 1:return new bf;case 2:return new yf;default:throw Fp(new Ry("No implementation is available for the crossing minimizer "+(null!=n.f?n.f:""+n.g)))}}function oCn(n,t){var e,i,r,c;for(n.c[t.p]=!0,UB(n.a,t),c=new Ub(t.j);c.a=(c=a.gc()))a.$b();else for(r=a.Kc(),i=0;i0?lk():c<0&&kCn(n,t,-c),!0)}function ECn(n){var t,e,i,r,c,a;if(a=0,0==n.b){for(t=0,r=0,c=(i=zvn(n,!0)).length;r0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}else a=Dk(ncn(AV(CV(AU(n.a),new Mn),new Sn)));return a>0?a+n.n.d+n.n.a:0}function TCn(n){var t,e,i,r,c,a;if(a=0,0==n.b)a=Dk(ncn(AV(CV(AU(n.a),new En),new Tn)));else{for(t=0,r=0,c=(i=Uvn(n,!0)).length;r0&&(a+=e,++t);t>1&&(a+=n.c*(t-1))}return a>0?a+n.n.b+n.n.c:0}function MCn(n,t){var e,r,c,a;for(e=(a=_B(aV(n.b,t),124)).a,c=_B(_B(o6(n.r,t),21),84).Kc();c.Ob();)(r=_B(c.Pb(),111)).c&&(e.a=i.Math.max(e.a,XH(r.c)));if(e.a>0)switch(t.g){case 2:a.n.c=n.s;break;case 4:a.n.b=n.s}}function SCn(n,t){var e,i,r;return 0==(e=_B(pMn(t,(sRn(),Jct)),19).a-_B(pMn(n,Jct),19).a)?(i=zR(_$(_B(pMn(n,(Ern(),cat)),8)),_B(pMn(n,aat),8)),r=zR(_$(_B(pMn(t,cat),8)),_B(pMn(t,aat),8)),Mln(i.a*i.b,r.a*r.b)):e}function PCn(n,t){var e,i,r;return 0==(e=_B(pMn(t,(SAn(),Okt)),19).a-_B(pMn(n,Okt),19).a)?(i=zR(_$(_B(pMn(n,(Bqn(),Jyt)),8)),_B(pMn(n,Yyt),8)),r=zR(_$(_B(pMn(t,Jyt),8)),_B(pMn(t,Yyt),8)),Mln(i.a*i.b,r.a*r.b)):e}function ICn(n){var t,e;return(e=new Sk).a+="e_",null!=(t=zan(n))&&(e.a+=""+t),n.c&&n.d&&(aO((e.a+=" ",e),dyn(n.c)),aO(cO((e.a+="[",e),n.c.i),"]"),aO((e.a+=n1n,e),dyn(n.d)),aO(cO((e.a+="[",e),n.d.i),"]")),e.a}function CCn(n){switch(n.g){case 0:return new df;case 1:return new gf;case 2:return new wf;case 3:return new pf;default:throw Fp(new Ry("No implementation is available for the layout phase "+(null!=n.f?n.f:""+n.g)))}}function OCn(n,t,e,r,c){var a;switch(a=0,c.g){case 1:a=i.Math.max(0,t.b+n.b-(e.b+r));break;case 3:a=i.Math.max(0,-n.b-r);break;case 2:a=i.Math.max(0,-n.a-r);break;case 4:a=i.Math.max(0,t.a+n.a-(e.a+r))}return a}function ACn(n,t,e){var i,r,c;if(e)for(c=((i=new oz(e.a.length)).b-i.a)*i.c<0?(nS(),jNt):new zL(i);c.Ob();)r=L2(e,_B(c.Pb(),19).a),A6n in r.a||$6n in r.a?uKn(n,r,t):kXn(n,r,t),ML(_B(xX(n.b,Wdn(r)),79))}function $Cn(n){var t,e;switch(n.b){case-1:return!0;case 0:return(e=n.t)>1||-1==e||(t=Pkn(n))&&(JM(),t.Cj()==k9n)?(n.b=-1,!0):(n.b=1,!1);default:case 1:return!1}}function LCn(n,t){var e,i,r,c,a;for(!t.s&&(t.s=new nU(RAt,t,21,17)),c=null,r=0,a=(i=t.s).i;r=0&&i=0?n._g(e,!0,!0):iOn(n,r,!0),153),_B(i,215).ll(t);throw Fp(new Ry(e6n+t.ne()+c6n))}function HCn(){var n;return ZM(),X$t?_B(O$n((UM(),HAt),X9n),1939):(xO(Fnt,new Is),YGn(),n=_B(iL(TY((UM(),HAt),X9n),547)?TY(HAt,X9n):new GW,547),X$t=!0,aWn(n),jWn(n),XW((XM(),QAt),n,new Go),pZ(HAt,X9n,n),n)}function qCn(n,t){var e,i,r,c;n.j=-1,pA(n.e)?(e=n.i,c=0!=n.i,i6(n,t),i=new $7(n.e,3,n.c,null,t,e,c),r=t.Qk(n.e,n.c,null),(r=PEn(n,t,r))?(r.Ei(i),r.Fi()):fan(n.e,i)):(i6(n,t),(r=t.Qk(n.e,n.c,null))&&r.Fi())}function GCn(n,t){var e,i,r;if(r=0,(i=t[0])>=n.length)return-1;for(f1(i,n.length),e=n.charCodeAt(i);e>=48&&e<=57&&(r=10*r+(e-48),!(++i>=n.length));)f1(i,n.length),e=n.charCodeAt(i);return i>t[0]?t[0]=i:r=-1,r}function zCn(n){var t,e,r,c,a;return e=c=_B(n.a,19).a,r=a=_B(n.b,19).a,t=i.Math.max(i.Math.abs(c),i.Math.abs(a)),c<=0&&c==a?(e=0,r=a-1):c==-t&&a!=t?(e=a,r=c,a>=0&&++e):(e=-a,r=c),new eC(tln(e),tln(r))}function UCn(n,t,e,i){var r,c,a,u,o,s;for(r=0;r=0&&s>=0&&o=n.i)throw Fp(new Cy(c8n+t+a8n+n.i));if(e>=n.i)throw Fp(new Cy(u8n+e+a8n+n.i));return i=n.g[e],t!=e&&(t>16))>>16&16),e+=t=(i=(n>>=t)-256)>>16&8,e+=t=(i=(n<<=t)-RQn)>>16&4,(e+=t=(i=(n<<=t)-oVn)>>16&2)+2-(t=(i=(n<<=t)>>14)&~(i>>1)))}function YCn(n){var t,e,i,r;for(EQ(),Tct=new $p,Ect=new Lp,jct=new $p,!n.a&&(n.a=new nU(qOt,n,10,11)),LUn(t=n.a),r=new CL(t);r.e!=r.i.gc();)i=_B(mpn(r),33),-1==k7(Tct,i,0)&&(e=new $p,UB(jct,e),xgn(i,e));return jct}function ZCn(n,t,e){var i,r,c,a;n.a=e.b.d,iL(t,352)?(n5(c=BSn(r=iDn(_B(t,79),!1,!1)),i=new $w(n)),XFn(c,r),null!=t.We((uWn(),ISt))&&n5(_B(t.We(ISt),74),i)):((a=_B(t,470)).Hg(a.Dg()+n.a.a),a.Ig(a.Eg()+n.a.b))}function nOn(n,t){var e,r,c,a,u,o,s,h;for(h=Hy(ED(pMn(t,(FXn(),$pt)))),s=n[0].n.a+n[0].o.a+n[0].d.c+h,o=1;o=0?e:(u=hW(zR(new LI(a.c+a.b/2,a.d+a.a/2),new LI(c.c+c.b/2,c.d+c.a/2))),-(V_n(c,a)-1)*u)}function eOn(n,t,e){var i;QT(new xq(null,(!e.a&&(e.a=new nU(ROt,e,6,6)),new l1(e.a,16))),new nC(n,t)),QT(new xq(null,(!e.n&&(e.n=new nU(HOt,e,1,7)),new l1(e.n,16))),new tC(n,t)),(i=_B(JAn(e,(uWn(),ISt)),74))&&Vrn(i,n,t)}function iOn(n,t,e){var i,r,c;if(c=Kqn((PPn(),Q$t),n.Tg(),t))return JM(),_B(c,66).Oj()||(c=J1(_7(Q$t,c))),r=_B((i=n.Yg(c))>=0?n._g(i,!0,!0):iOn(n,c,!0),153),_B(r,215).hl(t,e);throw Fp(new Ry(e6n+t.ne()+c6n))}function rOn(n,t,e,i){var r,c,a,u,o;if(r=n.d[t])if(c=r.g,o=r.i,null!=i){for(u=0;u=e&&(i=t,c=(o=(u.c+u.a)/2)-e,u.c<=o-e&&mG(n,i++,new mB(u.c,c)),(a=o+e)<=u.a&&(r=new mB(a,u.a),AZ(i,n.c.length),ES(n.c,i,r)))}function fOn(n){var t;if(n.c||null!=n.g){if(null==n.g)return!0;if(0==n.i)return!1;t=_B(n.g[n.i-1],47)}else n.d=n.si(n.f),s9(n,n.d),t=n.d;return t==n.b&&null.km>=null.jm()?(rLn(n),fOn(n)):t.Ob()}function lOn(n,t,e){var i,r,c,a;if(!(a=e)&&(a=AH(new zm,0)),ITn(a,BZn,1),OGn(n.c,t),1==(c=xGn(n.a,t)).gc())XHn(_B(c.Xb(0),37),a);else for(r=1/c.gc(),i=c.Kc();i.Ob();)XHn(_B(i.Pb(),37),pcn(a,r));kk(n.a,c,t),KDn(t),FSn(a)}function bOn(n){if(this.a=n,n.c.i.k==(cSn(),Eut))this.c=n.c,this.d=_B(pMn(n.c.i,(oWn(),Wft)),61);else{if(n.d.i.k!=Eut)throw Fp(new Ry("Edge "+n+" is not an external edge."));this.c=n.d,this.d=_B(pMn(n.d.i,(oWn(),Wft)),61)}}function wOn(n,t){var e,i,r;r=n.b,n.b=t,0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,3,r,n.b)),t?t!=n&&($rn(n,t.zb),Oen(n,t.d),Kin(n,null==(e=null==(i=t.c)?t.zb:i)||pK(e,t.zb)?null:e)):($rn(n,null),Oen(n,0),Kin(n,null))}function dOn(n){var t,e;if(n.f){for(;n.n=(a=null==(e=_B(van(n.a,4),126))?0:e.length))throw Fp(new ZR(t,a));return r=e[t],1==a?i=null:(rHn(e,0,i=L8(lAt,t9n,415,a-1,0,1),0,t),(c=a-t-1)>0&&rHn(e,t+1,i,t,c)),Kgn(n,i),nIn(n,t,r),r}function jOn(){jOn=O,oLt=_B(Utn(WQ((iE(),bLt).qb),6),34),cLt=_B(Utn(WQ(bLt.qb),3),34),aLt=_B(Utn(WQ(bLt.qb),4),34),uLt=_B(Utn(WQ(bLt.qb),5),18),aEn(oLt),aEn(cLt),aEn(aLt),aEn(uLt),sLt=new Qy(Mun(Hk(RAt,1),$9n,170,0,[oLt,cLt]))}function EOn(n,t){var e;this.d=new hm,this.b=t,this.e=new lA(t.qf()),e=n.u.Hc((hCn(),tCt)),n.u.Hc(nCt)?n.D?this.a=e&&!t.If():this.a=!0:n.u.Hc(eCt)?this.a=!!e&&!(t.zf().Kc().Ob()||t.Bf().Kc().Ob()):this.a=!1}function TOn(n,t){var e,i,r,c;for(e=n.o.a,c=_B(_B(o6(n.r,t),21),84).Kc();c.Ob();)(r=_B(c.Pb(),111)).e.a=(i=r.b).Xe((uWn(),rPt))?i.Hf()==(mUn(),SCt)?-i.rf().a-Hy(ED(i.We(rPt))):e+Hy(ED(i.We(rPt))):i.Hf()==(mUn(),SCt)?-i.rf().a:e}function MOn(n,t){var e,i,r;e=_B(pMn(n,(FXn(),Gdt)),103),r=_B(JAn(t,cpt),61),(i=_B(pMn(n,npt),98))!=(WEn(),WIt)&&i!=VIt?r==(mUn(),MCt)&&(r=IFn(t,e))==MCt&&(r=own(e)):r=zHn(t)>0?own(e):jln(own(e)),Vpn(t,cpt,r)}function SOn(n,t){var e,i,r,c,a;for(a=n.j,t.a!=t.b&&p$(a,new Ur),r=a.c.length/2|0,i=0;i0&&cKn(n,e,t),c):null!=i.a?(cKn(n,t,e),-1):null!=r.a?(cKn(n,e,t),1):0}function IOn(n,t){var e,i,r,c;n.ej()?(e=n.Vi(),c=n.fj(),++n.j,n.Hi(e,n.oi(e,t)),i=n.Zi(3,null,t,e,c),n.bj()&&(r=n.cj(t,null))?(r.Ei(i),r.Fi()):n.$i(i)):(nW(n,t),n.bj()&&(r=n.cj(t,null))&&r.Fi())}function COn(n,t){var e,i,r,c,a;for(a=rxn(n.e.Tg(),t),r=new go,e=_B(n.g,119),c=n.i;--c>=0;)i=e[c],a.rl(i.ak())&&s9(r,i);!rXn(n,r)&&pA(n.e)&&Av(n,t.$j()?AJ(n,6,t,(TQ(),uet),null,-1,!1):AJ(n,t.Kj()?2:1,t,null,null,-1,!1))}function OOn(){var n,t;for(OOn=O,ret=L8(aet,uVn,91,32,0,1),cet=L8(aet,uVn,91,32,0,1),n=1,t=0;t<=18;t++)ret[t]=Ygn(n),cet[t]=Ygn(vz(n,t)),n=ibn(n,5);for(;tc)||t.q&&(c=(i=t.C).c.c.a-i.o.a/2,i.n.a-e>c)))}function $On(n,t){ITn(t,"Partition preprocessing",1),QT(_B(M4(CV(lnn(CV(new xq(null,new l1(n.a,16)),new vi),new mi),new yi),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),Get)]))),15).Oc(),new ki),FSn(t)}function LOn(n){var t,e,i,r,c,a;for(BZ(),e=new g4,i=new Ub(n.e.b);i.a1?n.e*=Hy(n.a):n.f/=Hy(n.a),Shn(n),wgn(n),jRn(n),oon(n.b,(kpn(),wct),n.g)}function FOn(n,t,e){var i,r,c,a,u;for(i=0,u=e,t||(i=e*(n.c.length-1),u*=-1),c=new Ub(n);c.a=0?(t||(t=new Mk,i>0&&iO(t,n.substr(0,i))),t.a+="\\",$X(t,e&WVn)):t&&$X(t,e&WVn);return t?t.a:n}function eAn(n){var t;if(!n.a)throw Fp(new Ky("IDataType class expected for layout option "+n.f));if(null==(t=P3(n.a)))throw Fp(new Ky("Couldn't create new instance of property '"+n.f+"'. "+e5n+(kD(hAt),hAt.k)+i5n));return _B(t,414)}function iAn(n){var t,e,i,r,c;return(c=n.eh())&&c.kh()&&(r=Zhn(n,c))!=c?(e=n.Vg(),i=(t=n.Vg())>=0?n.Qg(null):n.eh().ih(n,-1-t,null,null),n.Rg(_B(r,49),e),i&&i.Fi(),n.Lg()&&n.Mg()&&e>-1&&fan(n,new Yz(n,9,e,c,r)),r):c}function rAn(n){var t,e,i,r,c,a,u;for(c=0,r=n.f.e,e=0;e>5)>=n.d)return n.e<0;if(e=n.a[r],t=1<<(31&t),n.e<0){if(r<(i=Scn(n)))return!1;e=i==r?-e:~e}return 0!=(e&t)}function hAn(n,t,e,i){var r;_B(e.b,65),_B(e.b,65),_B(i.b,65),_B(i.b,65),$H(r=zR(_$(_B(e.b,65).c),_B(i.b,65).c),FIn(_B(e.b,65),_B(i.b,65),r)),_B(i.b,65),_B(i.b,65),_B(i.b,65).c.a,r.a,_B(i.b,65).c.b,r.b,_B(i.b,65),Itn(i.a,new jB(n,t,i))}function fAn(n,t){var e,i,r,c,a,u,o;if(c=t.e)for(e=iAn(c),i=_B(n.g,674),a=0;a>16)),15).Xc(c))0&&((!bA(n.a.c)||!t.n.d)&&(!wA(n.a.c)||!t.n.b)&&(t.g.d+=i.Math.max(0,r/2-.5)),(!bA(n.a.c)||!t.n.a)&&(!wA(n.a.c)||!t.n.c)&&(t.g.a-=r-1))}function pAn(n){var t,e,r,c,a;if(a=D_n(n,c=new $p),t=_B(pMn(n,(oWn(),klt)),10))for(r=new Ub(t.j);r.a>t,c=n.m>>t|e<<22-t,r=n.l>>t|n.m<<22-t):t<44?(a=i?MQn:0,c=e>>t-22,r=n.m>>t-22|e<<44-t):(a=i?MQn:0,c=i?TQn:0,r=e>>t-44),E$(r&TQn,c&TQn,a&MQn)}function kAn(n){var t,e,r,c,a,u;for(this.c=new $p,this.d=n,r=xQn,c=xQn,t=DQn,e=DQn,u=upn(n,0);u.b!=u.d.c;)a=_B(f3(u),8),r=i.Math.min(r,a.a),c=i.Math.min(c,a.b),t=i.Math.max(t,a.a),e=i.Math.max(e,a.b);this.a=new GV(r,c,t-r,e-c)}function jAn(n,t){var e,i,r,c;for(i=new Ub(n.b);i.a0&&iL(t,42)&&(n.a.qj(),c=null==(o=(s=_B(t,42)).cd())?0:Yon(o),a=nR(n.a,c),e=n.a.d[a]))for(i=_B(e.g,367),h=e.i,u=0;u=2)for(t=ED((e=c.Kc()).Pb());e.Ob();)a=t,t=ED(e.Pb()),r=i.Math.min(r,(mW(t),t-(mW(a),a)));return r}function FAn(n,t){var e,i,r,c,a;e5(i=new VT,t,i.c.b,i.c);do{for(Mx(0!=i.b),e=_B(Ctn(i,i.a.a),86),n.b[e.g]=1,c=upn(e.d,0);c.b!=c.d.c;)a=(r=_B(f3(c),188)).c,1==n.b[a.g]?NH(n.a,r):2==n.b[a.g]?n.b[a.g]=1:e5(i,a,i.c.b,i.c)}while(0!=i.b)}function BAn(n,t){var e,i,r;if(HC(t)===HC(vX(n)))return!0;if(!iL(t,15))return!1;if(i=_B(t,15),(r=n.gc())!=i.gc())return!1;if(iL(i,54)){for(e=0;e0&&(r=e),a=new Ub(n.f.e);a.a0?(t-=1,e-=1):i>=0&&r<0?(t+=1,e+=1):i>0&&r>=0?(t-=1,e+=1):(t+=1,e-=1),new eC(tln(t),tln(e))}function h$n(n,t){return n.ct.c?1:n.bt.b?1:n.a!=t.a?Yon(n.a)-Yon(t.a):n.d==(W4(),Fmt)&&t.d==_mt?-1:n.d==_mt&&t.d==Fmt?1:0}function f$n(n,t){var e,i,r,c,a;return a=(c=t.a).c.i==t.b?c.d:c.c,i=c.c.i==t.b?c.c:c.d,(r=qwn(n.a,a,i))>0&&r0):r<0&&-r0)}function l$n(n,t,e,i){var r,c,a,u,o,s;for(r=(t-n.d)/n.c.c.length,c=0,n.a+=e,n.d=t,s=new Ub(n.c);s.a>24;return a}function w$n(n){if(n.pe()){var t=n.c;return t.qe()?n.o="["+t.n:t.pe()?n.o="["+t.ne():n.o="[L"+t.ne()+";",n.b=t.me()+"[]",void(n.k=t.oe()+"[]")}var e=n.j,i=n.d;i=i.split("/"),n.o=Kdn(".",[e,Kdn("$",i)]),n.b=Kdn(".",[e,Kdn(".",i)]),n.k=i[i.length-1]}function d$n(n,t){var e,i,r,c,a;for(a=null,c=new Ub(n.e.a);c.a=0;t-=2)for(e=0;e<=t;e+=2)(n.b[e]>n.b[e+2]||n.b[e]===n.b[e+2]&&n.b[e+1]>n.b[e+3])&&(i=n.b[e+2],n.b[e+2]=n.b[e],n.b[e]=i,i=n.b[e+3],n.b[e+3]=n.b[e+1],n.b[e+1]=i);n.c=!0}}function E$n(n,t){var e,i,r,c,a,u;for(c=(1==t?Uat:zat).a.ec().Kc();c.Ob();)for(r=_B(c.Pb(),103),u=_B(o6(n.f.c,r),21).Kc();u.Ob();)switch(a=_B(u.Pb(),46),i=_B(a.b,81),e=_B(a.a,189).c,r.g){case 2:case 1:i.g.d+=e;break;case 4:case 3:i.g.c+=e}}function T$n(n,t){var e,i,r,c,a,u,o,s,h;for(s=-1,h=0,u=0,o=(a=n).length;u0&&++h;++s}return h}function M$n(n){var t;return(t=new hN(Yj(n.gm))).a+="@",aO(t,(Yon(n)>>>0).toString(16)),n.kh()?(t.a+=" (eProxyURI: ",cO(t,n.qh()),n.$g()&&(t.a+=" eClass: ",cO(t,n.$g())),t.a+=")"):n.$g()&&(t.a+=" (eClass: ",cO(t,n.$g()),t.a+=")"),t.a}function S$n(n){var t,e,i;if(n.e)throw Fp(new Ky((kD(wit),CJn+wit.k+OJn)));for(n.d==(Kfn(),_Pt)&&jzn(n,RPt),e=new Ub(n.a.a);e.a>24}return e}function $$n(n,t,e){var i,r,c;if(!(r=_B(aV(n.i,t),306)))if(r=new ltn(n.d,t,e),pG(n.i,t,r),rgn(t))kL(n.a,t.c,t.b,r);else switch(c=APn(t),i=_B(aV(n.p,c),244),c.g){case 1:case 3:r.j=!0,yy(i,t.b,r);break;case 4:case 2:r.k=!0,yy(i,t.c,r)}return r}function L$n(n,t,e,i){var r,c,a,u,o,s;if(u=new go,o=rxn(n.e.Tg(),t),r=_B(n.g,119),JM(),_B(t,66).Oj())for(a=0;a=0)return r;for(c=1,a=new Ub(t.j);a.a0&&t.ue((h1(r-1,n.c.length),_B(n.c[r-1],10)),c)>0;)i5(n,r,(h1(r-1,n.c.length),_B(n.c[r-1],10))),--r;h1(r,n.c.length),n.c[r]=c}e.a=new Lp,e.b=new Lp}function D$n(n,t,e){var i,r,c,a,u,o,s;for(s=new VK(i=_B(t.e&&t.e(),9),_B(TR(i,i.length),9),0),a=0,u=(c=mKn(e,"[\\[\\]\\s,]+")).length;a0&&((!bA(n.a.c)||!t.n.d)&&(!wA(n.a.c)||!t.n.b)&&(t.g.d-=i.Math.max(0,r/2-.5)),(!bA(n.a.c)||!t.n.a)&&(!wA(n.a.c)||!t.n.c)&&(t.g.a+=i.Math.max(0,r-1)))}function K$n(n,t,e){var i;if(2==(n.c-n.b&n.a.length-1))t==(mUn(),uCt)||t==aCt?(ytn(_B(kon(n),15),(zyn(),yIt)),ytn(_B(kon(n),15),kIt)):(ytn(_B(kon(n),15),(zyn(),kIt)),ytn(_B(kon(n),15),yIt));else for(i=new fV(n);i.a!=i.b;)ytn(_B(Rhn(i),15),e)}function _$n(n,t){var e,i,r,c,a,u;for(a=new E2(i=FB(new up(n)),i.c.length),u=new E2(r=FB(new up(t)),r.c.length),c=null;a.b>0&&u.b>0&&(Mx(a.b>0),e=_B(a.a.Xb(a.c=--a.b),33),Mx(u.b>0),e==_B(u.a.Xb(u.c=--u.b),33));)c=e;return c}function F$n(n,t){var e,r,c,a;return c=n.a*rJn+1502*n.b,a=n.b*rJn+11,c+=e=i.Math.floor(a*cJn),a-=e*aJn,c%=aJn,n.a=c,n.b=a,t<=24?i.Math.floor(n.a*Iet[t]):((r=n.a*(1<=2147483648&&(r-=zQn),r)}function B$n(n,t,e){var i,r,c,a;l0(n,t)>l0(n,e)?(i=rbn(e,(mUn(),aCt)),n.d=i.dc()?0:cq(_B(i.Xb(0),11)),a=rbn(t,SCt),n.b=a.dc()?0:cq(_B(a.Xb(0),11))):(r=rbn(e,(mUn(),SCt)),n.d=r.dc()?0:cq(_B(r.Xb(0),11)),c=rbn(t,aCt),n.b=c.dc()?0:cq(_B(c.Xb(0),11)))}function H$n(n){var t,e,i,r,c,a,u;if(n&&(t=n.Hh(X9n))&&null!=(a=TD(idn((!t.b&&(t.b=new Qx((wWn(),v$t),G$t,t)),t.b),"conversionDelegates")))){for(u=new $p,r=0,c=(i=mKn(a,"\\w+")).length;rn.c));a++)r.a>=n.s&&(c<0&&(c=a),u=a);return o=(n.s+n.c)/2,c>=0&&(o=BM((h1(i=VRn(n,t,c,u),t.c.length),_B(t.c[i],329))),hOn(t,i,e)),o}function U$n(){U$n=O,hEt=new zA((uWn(),iSt),1.3),wEt=ySt,PEt=new UA(15),SEt=new zA(zSt,PEt),OEt=new zA(APt,15),fEt=oSt,yEt=DSt,kEt=_St,jEt=BSt,mEt=NSt,EEt=GSt,IEt=sPt,OAn(),MEt=aEt,vEt=rEt,TEt=cEt,CEt=oEt,dEt=iEt,gEt=SSt,pEt=PSt,bEt=eEt,lEt=tEt,AEt=sEt}function X$n(n,t,e){var i,r,c,a,u;for(_in(r=new jo,(mW(t),t)),!r.b&&(r.b=new Qx((wWn(),v$t),G$t,r)),u=r.b,a=1;a0&&Lqn(this,r)}function V$n(n,t,e,i,r,c){var a,u,o;if(!r[t.b]){for(r[t.b]=!0,!(a=i)&&(a=new v6),UB(a.e,t),o=c[t.b].Kc();o.Ob();)(u=_B(o.Pb(),282)).d!=e&&u.c!=e&&(u.c!=t&&V$n(n,u.c,t,a,r,c),u.d!=t&&V$n(n,u.d,t,a,r,c),UB(a.c,u),wun(a.d,u.b));return a}return null}function Q$n(n){var t,e,i;for(t=0,e=new Ub(n.e);e.a=2}function J$n(n,t){var e,i,r,c;for(ITn(t,"Self-Loop pre-processing",1),i=new Ub(n.a);i.a1||San(IY(kG(PIt,Mun(Hk(HIt,1),OVn,93,0,[SIt,CIt])),n))>1||San(IY(kG(NIt,Mun(Hk(HIt,1),OVn,93,0,[LIt,$It])),n))>1)}function nLn(n,t){var e,i,r;return(e=t.Hh(n.a))&&null!=(r=TD(idn((!e.b&&(e.b=new Qx((wWn(),v$t),G$t,e)),e.b),"affiliation")))?-1==(i=pN(r,VTn(35)))?cln(n,rz(n,Gtn(t.Hj())),r):0==i?cln(n,null,r.substr(1)):cln(n,r.substr(0,i),r.substr(i+1)):null}function tLn(n){var t,e;try{return null==n?qWn:_bn(n)}catch(i){if(iL(i=hun(i),102))return t=i,e=Yj(Zon(n))+"@"+(OT(),(nvn(n)>>>0).toString(16)),Dgn(yun(),(hM(),"Exception during lenientFormat for "+e),t),"<"+e+" threw "+Yj(t.gm)+">";throw Fp(i)}}function eLn(n){switch(n.g){case 0:return new af;case 1:return new nf;case 2:return new OM;case 3:return new Cc;case 4:return new xR;case 5:return new uf;default:throw Fp(new Ry("No implementation is available for the layerer "+(null!=n.f?n.f:""+n.g)))}}function iLn(n,t,e){var i,r,c;for(c=new Ub(n.t);c.a0&&(i.b.n-=i.c,i.b.n<=0&&i.b.u>0&&NH(t,i.b));for(r=new Ub(n.i);r.a0&&(i.a.u-=i.c,i.a.u<=0&&i.a.n>0&&NH(e,i.a))}function rLn(n){var t,e,i;if(null==n.g&&(n.d=n.si(n.f),s9(n,n.d),n.c))return n.f;if(i=(t=_B(n.g[n.i-1],47)).Pb(),n.e=t,(e=n.si(i)).Ob())n.d=e,s9(n,e);else for(n.d=null;!t.Ob()&&(OX(n.g,--n.i,null),0!=n.i);)t=_B(n.g[n.i-1],47);return i}function cLn(n,t){var e,i,r,c,a,u;if(r=(i=t).ak(),Oxn(n.e,r)){if(r.hi()&&H3(n,r,i.dd()))return!1}else for(u=rxn(n.e.Tg(),r),e=_B(n.g,119),c=0;c1||e>1)return 2;return t+e==1?2:0}function gLn(n,t,e){var i,r,c,a;for(ITn(e,"ELK Force",1),By(jD(JAn(t,(sRn(),Uct))))||yY(new jw((HM(),new Ny(t)))),mkn(a=son(t)),qon(n,_B(pMn(a,Hct),424)),r=(c=FFn(n.a,a)).Kc();r.Ob();)i=_B(r.Pb(),231),MKn(n.b,i,pcn(e,1/c.gc()));TUn(a=HUn(c)),FSn(e)}function pLn(n,t){var e,i,r;if(ITn(t,"Breaking Point Processor",1),Izn(n),By(jD(pMn(n,(FXn(),Hpt))))){for(i=new Ub(n.b);i.a=0?n._g(i,!0,!0):iOn(n,c,!0),153),_B(r,215).ml(t,e)}function ELn(n,t){var e,i,r,c,a;for(e=new $p,r=lnn(new xq(null,new l1(n,16)),new Ea),c=lnn(new xq(null,new l1(n,16)),new Ta),a=E7(F6(AV(TNn(Mun(Hk(nit,1),FWn,833,0,[r,c])),new Ma))),i=1;i=2*t&&UB(e,new mB(a[i-1]+t,a[i]-t));return e}function TLn(n,t,e){ITn(e,"Eades radial",1),e.n&&t&&v0(e,a2(t),(_sn(),cOt)),n.d=_B(JAn(t,(lD(),Xkt)),33),n.c=Hy(ED(JAn(t,(Gyn(),Njt)))),n.e=kvn(_B(JAn(t,xjt),293)),n.a=hwn(_B(JAn(t,Rjt),426)),n.b=Bjn(_B(JAn(t,Ojt),340)),ejn(n),e.n&&t&&v0(e,a2(t),(_sn(),cOt))}function MLn(n,t,e){var i,r,c,a,u;if(e)for(c=((i=new oz(e.a.length)).b-i.a)*i.c<0?(nS(),jNt):new zL(i);c.Ob();)(r=L2(e,_B(c.Pb(),19).a))&&(Oin(a=O3(n,(Zj(),u=new km,!!t&&_Ln(u,t),u),r),x2(r,B6n)),TTn(r,a),IIn(r,a),Lon(n,r,a))}function SLn(n){var t,e,i,r;if(!n.j){if(r=new Co,null==(t=T$t).a.zc(n,t)){for(i=new CL(mJ(n));i.e!=i.i.gc();)dX(r,SLn(e=_B(mpn(i),26))),s9(r,e);t.a.Bc(n)}ihn(r),n.j=new $O((_B(Utn(WQ((WX(),YAt).o),11),18),r.i),r.g),M5(n).b&=-33}return n.j}function PLn(n){var t,e,i,r;if(null==n)return null;if(i=KBn(n,!0),r=L7n.length,pK(i.substr(i.length-r,r),L7n))if(4==(e=i.length)){if(f1(0,i.length),43==(t=i.charCodeAt(0)))return BLt;if(45==t)return FLt}else if(3==e)return BLt;return new Nv(i)}function ILn(n){var t,e,i;return 0!=((e=n.l)&e-1)||0!=((i=n.m)&i-1)||0!=((t=n.h)&t-1)||0==t&&0==i&&0==e?-1:0==t&&0==i&&0!=e?win(e):0==t&&0!=i&&0==e?win(i)+22:0!=t&&0==i&&0==e?win(t)+44:-1}function CLn(n,t){var e,i,r,c;for(ITn(t,"Edge joining",1),e=By(jD(pMn(n,(FXn(),Npt)))),i=new Ub(n.b);i.a1)for(i=new Ub(n.a);i.a0),c.a.Xb(c.c=--c.b),vR(c,r),Mx(c.b3&&knn(n,0,t-3))}function DLn(n){var t,e,i,r;return HC(pMn(n,(FXn(),ugt)))===HC((cfn(),dIt))?!n.e&&HC(pMn(n,xdt))!==HC((Dan(),mft)):(i=_B(pMn(n,Ddt),292),r=By(jD(pMn(n,Fdt)))||HC(pMn(n,Bdt))===HC((Iin(),uht)),t=_B(pMn(n,Ndt),19).a,e=n.a.c.length,!r&&i!=(Dan(),mft)&&(0==t||t>e))}function RLn(n){var t,e;for(e=0;e0);e++);if(e>0&&e0);t++);return t>0&&e>16!=6&&t){if(gkn(n,t))throw Fp(new Ry(l6n+xOn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?ukn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=$pn(t,n,6,i)),(i=WD(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,6,t,t))}function _Ln(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=9&&t){if(gkn(n,t))throw Fp(new Ry(l6n+GRn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?skn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=$pn(t,n,9,i)),(i=VD(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,9,t,t))}function FLn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(gkn(n,t))throw Fp(new Ry(l6n+hHn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Ekn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=$pn(t,n,12,i)),(i=XD(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,3,t,t))}function BLn(n){var t,e,i,r,c;if(i=Pkn(n),null==(c=n.j)&&i)return n.$j()?null:i.zj();if(iL(i,148)){if((e=i.Aj())&&(r=e.Nh())!=n.i){if((t=_B(i,148)).Ej())try{n.g=r.Kh(t,c)}catch(a){if(!iL(a=hun(a),78))throw Fp(a);n.g=null}n.i=r}return n.g}return null}function HLn(n){var t;return UB(t=new $p,new LS(new LI(n.c,n.d),new LI(n.c+n.b,n.d))),UB(t,new LS(new LI(n.c,n.d),new LI(n.c,n.d+n.a))),UB(t,new LS(new LI(n.c+n.b,n.d+n.a),new LI(n.c+n.b,n.d))),UB(t,new LS(new LI(n.c+n.b,n.d+n.a),new LI(n.c,n.d+n.a))),t}function qLn(n,t,e,i){var r,c,a;if(a=Cjn(t,e),i.c[i.c.length]=t,-1==n.j[a.p]||2==n.j[a.p]||n.a[t.p])return i;for(n.j[a.p]=-1,c=new az(JL(obn(a).a.Kc(),new h));bAn(c);)if(!f5(r=_B(G5(c),17))&&(f5(r)||r.c.i.c!=r.d.i.c)&&r!=t)return qLn(n,r,a,i);return i}function GLn(n,t,e){var i,r;for(r=t.a.ec().Kc();r.Ob();)i=_B(r.Pb(),79),!_B(xX(n.b,i),266)&&(QY(MMn(i))==QY(IMn(i))?Zxn(n,i,e):MMn(i)==QY(IMn(i))?null==xX(n.c,i)&&null!=xX(n.b,IMn(i))&&ezn(n,i,e,!1):null==xX(n.d,i)&&null!=xX(n.b,MMn(i))&&ezn(n,i,e,!0))}function zLn(n,t){var e,i,r,c,a,u,o;for(r=n.Kc();r.Ob();)for(i=_B(r.Pb(),10),SZ(u=new SSn,i),BIn(u,(mUn(),aCt)),oon(u,(oWn(),ylt),(oN(),!0)),a=t.Kc();a.Ob();)c=_B(a.Pb(),10),SZ(o=new SSn,c),BIn(o,SCt),oon(o,ylt,!0),oon(e=new lJ,ylt,!0),TZ(e,u),EZ(e,o)}function ULn(n,t,e,i){var r,c,a,u;r=Cdn(n,t,e),c=Cdn(n,e,t),a=_B(xX(n.c,t),112),u=_B(xX(n.c,e),112),ri.b.g&&(c.c[c.c.length]=i);return c}function VLn(){VLn=O,NEt=new yI("CANDIDATE_POSITION_LAST_PLACED_RIGHT",0),LEt=new yI("CANDIDATE_POSITION_LAST_PLACED_BELOW",1),DEt=new yI("CANDIDATE_POSITION_WHOLE_DRAWING_RIGHT",2),xEt=new yI("CANDIDATE_POSITION_WHOLE_DRAWING_BELOW",3),REt=new yI("WHOLE_DRAWING",4)}function QLn(n,t){if(iL(t,239))return oln(n,_B(t,33));if(iL(t,186))return Nln(n,_B(t,118));if(iL(t,354))return ZV(n,_B(t,137));if(iL(t,352))return QFn(n,_B(t,79));if(t)return null;throw Fp(new Ry(q6n+AMn(new Qy(Mun(Hk(Cnt,1),FWn,1,5,[t])))))}function JLn(n){var t,e,i,r,c,a,u;for(c=new VT,r=new Ub(n.d.a);r.a1)for(t=CN((e=new Bv,++n.b,e),n.d),u=upn(c,0);u.b!=u.d.c;)a=_B(f3(u),121),GNn(rM(iM(cM(eM(new Fv,1),0),t),a))}function YLn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=11&&t){if(gkn(n,t))throw Fp(new Ry(l6n+qRn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?Tkn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=$pn(t,n,10,i)),(i=qR(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,11,t,t))}function ZLn(n){var t,e,i,r;for(i=new csn(new Mb(n.b).a);i.b;)r=_B((e=Ztn(i)).cd(),11),oon(t=_B(e.dd(),10),(oWn(),blt),r),oon(r,klt,t),oon(r,nlt,(oN(),!0)),BIn(r,_B(pMn(t,Wft),61)),pMn(t,Wft),oon(r.i,(FXn(),npt),(WEn(),XIt)),_B(pMn(gW(r.i),Jft),21).Fc((fDn(),bft))}function nNn(n,t,e){var i,r,c;if(i=0,r=0,n.c)for(c=new Ub(n.d.i.j);c.ac.a)return-1;if(r.a(o=null==n.d?0:n.d.length)){for(h=n.d,n.d=L8(uAt,i9n,63,2*o+4,0,1),c=0;c=0x8000000000000000?(z7(),ftt):(i=!1,n<0&&(i=!0,n=-n),e=0,n>=IQn&&(n-=(e=SY(n/IQn))*IQn),t=0,n>=PQn&&(n-=(t=SY(n/PQn))*PQn),r=E$(SY(n),t,e),i&&Ion(r),r)}function dNn(n,t){var e,i,r,c;for(e=!t||!n.u.Hc((hCn(),nCt)),c=0,r=new Ub(n.e.Cf());r.a=-t&&r==t?new eC(tln(e-1),tln(r)):new eC(tln(e),tln(r-1))}function kNn(){return hWn(),Mun(Hk(cst,1),OVn,77,0,[eot,Zut,iot,mot,Kot,Eot,Got,Iot,Dot,wot,$ot,Pot,Rot,hot,Uot,Xut,Aot,Fot,yot,_ot,Wot,Not,Wut,xot,Vot,Hot,Xot,kot,uot,jot,vot,zot,Jut,cot,Mot,Qut,Sot,got,fot,Cot,bot,not,Yut,pot,lot,Oot,qot,Vut,Lot,dot,Tot,oot,aot,Bot,rot,sot,tot])}function jNn(n,t,e){n.d=0,n.b=0,t.k==(cSn(),Put)&&e.k==Put&&_B(pMn(t,(oWn(),blt)),10)==_B(pMn(e,blt),10)&&(T7(t).j==(mUn(),uCt)?B$n(n,t,e):B$n(n,e,t)),t.k==Put&&e.k==Mut?T7(t).j==(mUn(),uCt)?n.d=1:n.b=1:e.k==Put&&t.k==Mut&&(T7(e).j==(mUn(),uCt)?n.b=1:n.d=1),cmn(n,t,e)}function ENn(n){var t,e,i,r,c;return c=CTn(n),null!=n.a&&CH(c,"category",n.a),!UE(new Sb(n.d))&&(etn(c,"knownOptions",i=new Sl),t=new np(i),n5(new Sb(n.d),t)),!UE(n.g)&&(etn(c,"supportedFeatures",r=new Sl),e=new tp(r),n5(n.g,e)),c}function TNn(n){var t,e,i,r,c,a,u,o;for(t=336,e=0,r=new uR(n.length),u=0,o=(a=n).length;u>16!=7&&t){if(gkn(n,t))throw Fp(new Ry(l6n+iPn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?okn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=_B(t,49).gh(n,1,LOt,i)),(i=XG(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,7,t,t))}function INn(n,t){var e,i;if(t!=n.Cb||n.Db>>16!=3&&t){if(gkn(n,t))throw Fp(new Ry(l6n+Xfn(n)));i=null,n.Cb&&(i=(e=n.Db>>16)>=0?fkn(n,i):n.Cb.ih(n,-1-e,null,i)),t&&(i=_B(t,49).gh(n,0,KOt,i)),(i=WG(n,t,i))&&i.Fi()}else 0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,3,t,t))}function CNn(n,t){var e,i,r,c,a,u,o,s,h;return OOn(),t.d>n.d&&(u=n,n=t,t=u),t.d<63?zxn(n,t):(s=q5(n,a=(-2&n.d)<<4),h=q5(t,a),i=cBn(n,H5(s,a)),r=cBn(t,H5(h,a)),o=CNn(s,h),e=CNn(i,r),c=H5(c=OHn(OHn(c=CNn(cBn(s,i),cBn(r,h)),o),e),a),OHn(OHn(o=H5(o,a<<1),c),e))}function ONn(n,t,e){var i,r,c,a,u;for(a=Afn(n,e),u=L8(Iut,r1n,10,t.length,0,1),i=0,c=a.Kc();c.Ob();)By(jD(pMn(r=_B(c.Pb(),11),(oWn(),nlt))))&&(u[i++]=_B(pMn(r,klt),10));if(i=0;r+=e?1:-1)c|=t.c.Sf(u,r,e,i&&!By(jD(pMn(t.j,(oWn(),Qft))))&&!By(jD(pMn(t.j,(oWn(),Plt))))),c|=t.q._f(u,r,e),c|=wRn(n,u[r],e,i);return jU(n.c,t),c}function xNn(n,t,e){var i,r,c,a,u,o,s,h;for(s=0,h=(o=P2(n.j)).length;s1&&(n.a=!0),$G(_B(e.b,65),GR(_$(_B(t.b,65).c),mL(zR(_$(_B(e.b,65).a),_B(t.b,65).a),r))),WZ(n,t),KNn(n,e)}function _Nn(n){var t,e,i,r,c,a;for(r=new Ub(n.a.a);r.a0&&c>0?t++:i>0?e++:c>0?r++:e++}TQ(),p$(n.j,new bi)}function BNn(n){var t,e;e=null,t=_B(Lq(n.g,0),17);do{if(Ax(e=t.d.i,(oWn(),slt)))return _B(pMn(e,slt),11).i;if(e.k!=(cSn(),Sut)&&bAn(new az(JL(hbn(e).a.Kc(),new h))))t=_B(G5(new az(JL(hbn(e).a.Kc(),new h))),17);else if(e.k!=Sut)return null}while(e&&e.k!=(cSn(),Sut));return e}function HNn(n,t){var e,i,r,c,a,u,o,s,h;for(u=t.j,a=t.g,o=_B(Lq(u,u.c.length-1),113),h1(0,u.c.length),s=Jmn(n,a,o,h=_B(u.c[0],113)),c=1;cs&&(o=e,h=r,s=i);t.a=h,t.c=o}function qNn(n,t){var e;if(!JU(n.b,t.b))throw Fp(new Ky("Invalid hitboxes for scanline constraint calculation."));(mun(t.b,_B(ER(n.b,t.b),57))||mun(t.b,_B(jR(n.b,t.b),57)))&&(OT(),t.b),n.a[t.b.f]=_B(mK(n.b,t.b),57),(e=_B(vK(n.b,t.b),57))&&(n.a[e.f]=t.b)}function GNn(n){if(!n.a.d||!n.a.e)throw Fp(new Ky((kD(Fit),Fit.k+" must have a source and target "+(kD(Bit),Bit.k+" specified."))));if(n.a.d==n.a.e)throw Fp(new Ky("Network simplex does not support self-loops: "+n.a+" "+n.a.d+" "+n.a.e));return xN(n.a.d.g,n.a),xN(n.a.e.b,n.a),n.a}function zNn(n,t,e){var i,r,c,a,u,o,s;for(s=new bE(new Qd(n)),u=0,o=(a=Mun(Hk(Hut,1),c1n,11,0,[t,e])).length;uo-n.b&&uo-n.a&&u0&&++l;++f}return l}function ixn(n,t){var e,i,r,c,a;for(a=_B(pMn(t,(SAn(),Akt)),425),c=upn(t.b,0);c.b!=c.d.c;)if(r=_B(f3(c),86),0==n.b[r.g]){switch(a.g){case 0:Wvn(n,r);break;case 1:FAn(n,r)}n.b[r.g]=2}for(i=upn(n.a,0);i.b!=i.d.c;)vwn((e=_B(f3(i),188)).b.d,e,!0),vwn(e.c.b,e,!0);oon(t,(Bqn(),hkt),n.a)}function rxn(n,t){var e,i,r,c;return JM(),t?t==(Gqn(),xLt)||(t==pLt||t==dLt||t==gLt)&&n!=wLt?new iUn(n,t):((e=(i=_B(t,677)).pk())||(mV(_7((PPn(),Q$t),t)),e=i.pk()),!e.i&&(e.i=new Lp),!(r=_B(BC(CJ((c=e.i).f,n)),1942))&&XW(c,n,r=new iUn(n,t)),r):iLt}function cxn(n,t){var e,i,r,c,a,u,o,s;for(u=_B(pMn(n,(oWn(),blt)),11),o=Con(Mun(Hk(MMt,1),uVn,8,0,[u.i.n,u.n,u.a])).a,s=n.i.n.b,r=0,c=(i=J0(n.e)).length;r0?c.a?e>(u=c.b.rf().a)&&(r=(e-u)/2,c.d.b=r,c.d.c=r):c.d.c=n.s+e:Fz(n.u)&&((i=RTn(c.b)).c<0&&(c.d.b=-i.c),i.c+i.b>c.b.rf().a&&(c.d.c=i.c+i.b-c.b.rf().a))}function sxn(n,t){var e,i;for(ITn(t,"Semi-Interactive Crossing Minimization Processor",1),e=!1,i=new Ub(n.b);i.a=0){if(t==e)return new eC(tln(-t-1),tln(-t-1));if(t==-e)return new eC(tln(-t),tln(e+1))}return i.Math.abs(t)>i.Math.abs(e)?new eC(tln(-t),tln(t<0?e:e+1)):new eC(tln(t+1),tln(e))}function lxn(n){var t,e;e=_B(pMn(n,(FXn(),mgt)),163),t=_B(pMn(n,(oWn(),tlt)),303),e==(jbn(),Klt)?(oon(n,mgt,Blt),oon(n,tlt,(q7(),Sft))):e==Flt?(oon(n,mgt,Blt),oon(n,tlt,(q7(),Tft))):t==(q7(),Sft)?(oon(n,mgt,Klt),oon(n,tlt,Mft)):t==Tft&&(oon(n,mgt,Flt),oon(n,tlt,Mft))}function bxn(){bxn=O,yyt=new oa,gyt=bq(new _2,(vMn(),Rat),(hWn(),yot)),myt=UG(bq(new _2,Rat,Not),_at,Lot),kyt=agn(agn(KM(UG(bq(new _2,xat,Got),_at,qot),Kat),Hot),zot),pyt=UG(bq(bq(bq(new _2,Dat,Eot),Kat,Mot),Kat,Sot),_at,Tot),vyt=UG(bq(bq(new _2,Kat,Sot),Kat,cot),_at,rot)}function wxn(){wxn=O,Syt=bq(UG(new _2,(vMn(),_at),(hWn(),oot)),Rat,yot),Oyt=agn(agn(KM(UG(bq(new _2,xat,Got),_at,qot),Kat),Hot),zot),Pyt=UG(bq(bq(bq(new _2,Dat,Eot),Kat,Mot),Kat,Sot),_at,Tot),Cyt=bq(bq(new _2,Rat,Not),_at,Lot),Iyt=UG(bq(bq(new _2,Kat,Sot),Kat,cot),_at,rot)}function dxn(n,t,e,i,r){var c,a;(f5(t)||t.c.i.c!=t.d.i.c)&&Yin(Con(Mun(Hk(MMt,1),uVn,8,0,[r.i.n,r.n,r.a])),e)||f5(t)||(t.c==r?Dx(t.a,0,new lA(e)):NH(t.a,new lA(e)),i&&!KT(n.a,e)&&((a=_B(pMn(t,(FXn(),ggt)),74))||(a=new mm,oon(t,ggt,a)),e5(a,c=new lA(e),a.c.b,a.c),jU(n.a,c)))}function gxn(n){var t;for(t=new az(JL(sbn(n).a.Kc(),new h));bAn(t);)if(_B(G5(t),17).c.i.k!=(cSn(),Tut))throw Fp(new ek(M1n+wyn(n)+"' has its layer constraint set to FIRST, but has at least one incoming edge that does not come from a FIRST_SEPARATE node. That must not happen."))}function pxn(n,t,e){var i,r,c,a,u,o;if(0==(r=dbn(254&n.Db)))n.Eb=e;else{if(1==r)a=L8(Cnt,FWn,1,2,5,1),0==xmn(n,t)?(a[0]=e,a[1]=n.Eb):(a[0]=n.Eb,a[1]=e);else for(a=L8(Cnt,FWn,1,r+1,5,1),c=nen(n.Eb),i=2,u=0,o=0;i<=128;i<<=1)i==t?a[o++]=e:0!=(n.Db&i)&&(a[o++]=c[u++]);n.Eb=a}n.Db|=t}function vxn(n,t,e){var r,c,a,u;for(this.b=new $p,c=0,r=0,u=new Ub(n);u.a0&&(c+=(a=_B(Lq(this.b,0),167)).o,r+=a.p),c*=2,r*=2,t>1?c=SY(i.Math.ceil(c*t)):r=SY(i.Math.ceil(r/t)),this.a=new Bwn(c,r)}function mxn(n,t,e,r,c,a){var u,o,s,h,f,l,b,w,d,g;for(h=r,t.j&&t.o?(d=(b=_B(xX(n.f,t.A),57)).d.c+b.d.b,--h):d=t.a.c+t.a.b,f=c,e.q&&e.o?(s=(b=_B(xX(n.f,e.C),57)).d.c,++f):s=e.a.c,w=d+(o=(s-d)/i.Math.max(2,f-h)),l=h;l=0;a+=r?1:-1){for(u=t[a],o=i==(mUn(),aCt)?r?rbn(u,i):nan(rbn(u,i)):r?nan(rbn(u,i)):rbn(u,i),c&&(n.c[u.p]=o.gc()),f=o.Kc();f.Ob();)h=_B(f.Pb(),11),n.d[h.p]=s++;wun(e,o)}}function kxn(n,t,e){var i,r,c,a,u,o,s,h;for(c=Hy(ED(n.b.Kc().Pb())),s=Hy(ED(Uan(t.b))),i=mL(_$(n.a),s-e),r=mL(_$(t.a),e-c),mL(h=GR(i,r),1/(s-c)),this.a=h,this.b=new $p,u=!0,(a=n.b.Kc()).Pb();a.Ob();)o=Hy(ED(a.Pb())),u&&o-e>N3n&&(this.b.Fc(e),u=!1),this.b.Fc(o);u&&this.b.Fc(e)}function jxn(n){var t,e,i,r;if(oKn(n,n.n),n.d.c.length>0){for(Yy(n.c);dAn(n,_B(Y1(new Ub(n.e.a)),121))>5,t&=31,i>=n.d)return n.e<0?(IDn(),Vtt):(IDn(),net);if(c=n.d-i,WSn(r=L8(INt,oQn,25,c+1,15,1),c,n.a,i,t),n.e<0){for(e=0;e0&&n.a[e]<<32-t!=0){for(e=0;e=0)&&(!(e=Kqn((PPn(),Q$t),r,t))||((i=e.Zj())>1||-1==i)&&3!=NW(_7(Q$t,e))))}function Axn(n,t,e,i){var r,c,a,u,o;return u=MTn(_B(Utn((!t.b&&(t.b=new oK(xOt,t,4,7)),t.b),0),82)),o=MTn(_B(Utn((!t.c&&(t.c=new oK(xOt,t,5,8)),t.c),0),82)),QY(u)==QY(o)||Stn(o,u)?null:(a=zY(t))==e?i:(c=_B(xX(n.a,a),10))&&(r=c.e)?r:null}function $xn(n,t){var e;switch(ITn(t,"Label side selection ("+(e=_B(pMn(n,(FXn(),Qdt)),276))+")",1),e.g){case 0:jAn(n,(zyn(),yIt));break;case 1:jAn(n,(zyn(),kIt));break;case 2:uBn(n,(zyn(),yIt));break;case 3:uBn(n,(zyn(),kIt));break;case 4:cDn(n,(zyn(),yIt));break;case 5:cDn(n,(zyn(),kIt))}FSn(t)}function Lxn(n,t,e){var i,r,c,a,u;if((c=n[hj(e,n.length)])[0].k==(cSn(),Eut))for(r=sj(e,c.length),u=t.j,i=0;i0&&(e[0]+=n.d,u-=e[0]),e[2]>0&&(e[2]+=n.d,u-=e[2]),a=i.Math.max(0,u),e[1]=i.Math.max(e[1],u),V5(n,qit,c.c+r.b+e[0]-(e[1]-u)/2,e),t==qit&&(n.c.b=a,n.c.c=c.c+r.b+(a-u)/2)}function Wxn(){this.c=L8($Nt,BQn,25,(mUn(),Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt])).length,15,1),this.b=L8($Nt,BQn,25,Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt]).length,15,1),this.a=L8($Nt,BQn,25,Mun(Hk(KCt,1),VZn,61,0,[MCt,uCt,aCt,TCt,SCt]).length,15,1),pS(this.c,xQn),pS(this.b,DQn),pS(this.a,DQn)}function Vxn(n,t,e){var i,r,c,a;if(t<=e?(r=t,c=e):(r=e,c=t),i=0,null==n.b)n.b=L8(INt,oQn,25,2,15,1),n.b[0]=r,n.b[1]=c,n.c=!0;else{if(i=n.b.length,n.b[i-1]+1==r)return void(n.b[i-1]=c);a=L8(INt,oQn,25,i+2,15,1),rHn(n.b,0,a,0,i),n.b=a,n.b[i-1]>=r&&(n.c=!1,n.a=!1),n.b[i++]=r,n.b[i]=c,n.c||j$n(n)}}function Qxn(n,t,e){var i,r,c,a,u,o,s;for(s=t.d,n.a=new Q6(s.c.length),n.c=new Lp,u=new Ub(s);u.a=0?n._g(s,!1,!0):iOn(n,e,!1),58).Kc();c.Ob();){for(r=_B(c.Pb(),56),h=0;h1;)sDn(r,r.i-1);return i}function rDn(n,t){var e,i,r,c,a,u,o;for(ITn(t,"Comment post-processing",1),c=new Ub(n.b);c.an.d[a.p]&&(e+=Y4(n.b,c),b3(n.a,tln(c)));for(;!Uy(n.a);)Enn(n.b,_B(bU(n.a),19).a)}return e}function oDn(n,t,e){var i,r,c,a;for(c=(!t.a&&(t.a=new nU(qOt,t,10,11)),t.a).i,r=new CL((!t.a&&(t.a=new nU(qOt,t,10,11)),t.a));r.e!=r.i.gc();)0==(!(i=_B(mpn(r),33)).a&&(i.a=new nU(qOt,i,10,11)),i.a).i||(c+=oDn(n,i,!1));if(e)for(a=QY(t);a;)c+=(!a.a&&(a.a=new nU(qOt,a,10,11)),a.a).i,a=QY(a);return c}function sDn(n,t){var e,i,r,c;return n.ej()?(i=null,r=n.fj(),n.ij()&&(i=n.kj(n.pi(t),null)),e=n.Zi(4,c=Ayn(n,t),null,t,r),n.bj()&&null!=c?(i=n.dj(c,i))?(i.Ei(e),i.Fi()):n.$i(e):i?(i.Ei(e),i.Fi()):n.$i(e),c):(c=Ayn(n,t),n.bj()&&null!=c&&(i=n.dj(c,null))&&i.Fi(),c)}function hDn(n){var t,e,r,c,a,u,o,s,h,f;for(h=n.a,t=new xv,s=0,r=new Ub(n.d);r.ao.d&&(f=o.d+o.a+h));e.c.d=f,t.a.zc(e,t),s=i.Math.max(s,e.c.d+e.c.a)}return s}function fDn(){fDn=O,oft=new AP("COMMENTS",0),hft=new AP("EXTERNAL_PORTS",1),fft=new AP("HYPEREDGES",2),lft=new AP("HYPERNODES",3),bft=new AP("NON_FREE_PORTS",4),wft=new AP("NORTH_SOUTH_PORTS",5),gft=new AP(H1n,6),uft=new AP("CENTER_LABELS",7),sft=new AP("END_LABELS",8),dft=new AP("PARTITIONS",9)}function lDn(n){var t,e,i,r,c;for(r=new $p,t=new Oq((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a)),i=new az(JL(bLn(n).a.Kc(),new h));bAn(i);)iL(Utn((!(e=_B(G5(i),79)).b&&(e.b=new oK(xOt,e,4,7)),e.b),0),186)||(c=MTn(_B(Utn((!e.c&&(e.c=new oK(xOt,e,5,8)),e.c),0),82)),t.a._b(c)||(r.c[r.c.length]=c));return r}function bDn(n){var t,e,i,r,c;for(r=new xv,t=new Oq((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a)),i=new az(JL(bLn(n).a.Kc(),new h));bAn(i);)iL(Utn((!(e=_B(G5(i),79)).b&&(e.b=new oK(xOt,e,4,7)),e.b),0),186)||(c=MTn(_B(Utn((!e.c&&(e.c=new oK(xOt,e,5,8)),e.c),0),82)),t.a._b(c)||r.a.zc(c,r));return r}function wDn(n,t,e,i,r){return i<0?((i=qTn(n,r,Mun(Hk(Wtt,1),uVn,2,6,[VVn,QVn,JVn,YVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn]),t))<0&&(i=qTn(n,r,Mun(Hk(Wtt,1),uVn,2,6,["Jan","Feb","Mar","Apr",ZVn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}function dDn(n,t,e,i,r){return i<0?((i=qTn(n,r,Mun(Hk(Wtt,1),uVn,2,6,[VVn,QVn,JVn,YVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn]),t))<0&&(i=qTn(n,r,Mun(Hk(Wtt,1),uVn,2,6,["Jan","Feb","Mar","Apr",ZVn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),t)),!(i<0||(e.k=i,0))):i>0&&(e.k=i-1,!0)}function gDn(n,t,e,i,r,c){var a,u,o;if(u=32,i<0){if(t[0]>=n.length)return!1;if(43!=(u=sV(n,t[0]))&&45!=u)return!1;if(++t[0],(i=GCn(n,t))<0)return!1;45==u&&(i=-i)}return 32==u&&t[0]-e==2&&2==r.b&&(a=(o=(new CT).q.getFullYear()-uQn+uQn-80)%100,c.a=i==a,i+=100*(o/100|0)+(i=h&&(s=r);s&&(f=i.Math.max(f,s.a.o.a)),f>b&&(l=h,b=f)}return l}function EDn(n,t,e){var i,r,c;if(n.e=e,n.d=0,n.b=0,n.f=1,n.i=t,16==(16&n.e)&&(n.i=dKn(n.i)),n.j=n.i.length,WXn(n),c=Xdn(n),n.d!=n.j)throw Fp(new rk(mWn((c$(),l8n))));if(n.g){for(i=0;id4n?p$(s,n.b):r<=d4n&&r>g4n?p$(s,n.d):r<=g4n&&r>p4n?p$(s,n.c):r<=p4n&&p$(s,n.a),a=PDn(n,s,a);return c}function IDn(){var n;for(IDn=O,Qtt=new z6(1,1),Ytt=new z6(1,10),net=new z6(0,0),Vtt=new z6(-1,1),Jtt=Mun(Hk(aet,1),uVn,91,0,[net,Qtt,new z6(1,2),new z6(1,3),new z6(1,4),new z6(1,5),new z6(1,6),new z6(1,7),new z6(1,8),new z6(1,9),Ytt]),Ztt=L8(aet,uVn,91,32,0,1),n=0;n1&&(i=new LI(r,e.b),NH(t.a,i)),Yen(t.a,Mun(Hk(MMt,1),uVn,8,0,[f,h]))}function xDn(n){$M(n,new ETn(gj(lj(dj(wj(new du,R5n),"ELK Randomizer"),'Distributes the nodes randomly on the plane, leading to very obfuscating layouts. Can be useful to demonstrate the power of "real" layout algorithms.'),new Qu))),c2(n,R5n,WYn,ACt),c2(n,R5n,gZn,15),c2(n,R5n,vZn,tln(0)),c2(n,R5n,XYn,bZn)}function DDn(){var n,t,e,i,r,c;for(DDn=O,XLt=L8(ANt,g6n,25,255,15,1),WLt=L8(PNt,UVn,25,16,15,1),t=0;t<255;t++)XLt[t]=-1;for(e=57;e>=48;e--)XLt[e]=e-48<<24>>24;for(i=70;i>=65;i--)XLt[i]=i-65+10<<24>>24;for(r=102;r>=97;r--)XLt[r]=r-97+10<<24>>24;for(c=0;c<10;c++)WLt[c]=48+c&WVn;for(n=10;n<=15;n++)WLt[n]=65+n-10&WVn}function RDn(n,t,e){var i,r,c,a,u,o,s,h;return u=t.i-n.g/2,o=e.i-n.g/2,s=t.j-n.g/2,h=e.j-n.g/2,c=t.g+n.g/2,a=e.g+n.g/2,i=t.f+n.g/2,r=e.f+n.g/2,u>19!=0)return"-"+HDn(ron(n));for(e=n,i="";0!=e.l||0!=e.m||0!=e.h;){if(e=Cqn(e,K5(CQn),!0),t=""+jE(htt),0!=e.l||0!=e.m||0!=e.h)for(r=9-t.length;r>0;r--)t="0"+t;i=t+i}return i}function qDn(){if(!Object.create||!Object.getOwnPropertyNames)return!1;var n="__proto__",t=Object.create(null);return void 0===t[n]&&0==Object.getOwnPropertyNames(t).length&&(t[n]=42,42===t[n]&&0!=Object.getOwnPropertyNames(t).length)}function GDn(n){var t,e,i,r,c,a,u;for(t=!1,e=0,r=new Ub(n.d.b);r.a=n.a)return-1;if(!nTn(t,e))return-1;if(o3(_B(r.Kb(t),20)))return 1;for(c=0,u=_B(r.Kb(t),20).Kc();u.Ob();){if(-1==(o=XDn(n,(a=_B(u.Pb(),17)).c.i==t?a.d.i:a.c.i,e,r)))return-1;if((c=i.Math.max(c,o))>n.c-1)return-1}return c+1}function WDn(n,t){var e,i,r,c,a,u;if(HC(t)===HC(n))return!0;if(!iL(t,15))return!1;if(i=_B(t,15),u=n.gc(),i.gc()!=u)return!1;if(a=i.Kc(),n.ni()){for(e=0;e0)if(n.qj(),null!=t){for(c=0;c>24;case 97:case 98:case 99:case 100:case 101:case 102:return n-97+10<<24>>24;case 65:case 66:case 67:case 68:case 69:case 70:return n-65+10<<24>>24;default:throw Fp(new Ek("Invalid hexadecimal"))}}function YDn(n,t,e){var i,r,c,a;for(ITn(e,"Processor order nodes",2),n.a=Hy(ED(pMn(t,(SAn(),Lkt)))),r=new VT,a=upn(t.b,0);a.b!=a.d.c;)By(jD(pMn(c=_B(f3(a),86),(Bqn(),bkt))))&&e5(r,c,r.c.b,r.c);Mx(0!=r.b),DHn(n,i=_B(r.a.a.c,86)),!e.b&&Bin(e,1),_Rn(n,i,0-Hy(ED(pMn(i,(Bqn(),ckt))))/2,0),!e.b&&Bin(e,1),FSn(e)}function ZDn(){ZDn=O,xit=new FS("SPIRAL",0),Oit=new FS("LINE_BY_LINE",1),Ait=new FS("MANHATTAN",2),Cit=new FS("JITTER",3),Lit=new FS("QUADRANTS_LINE_BY_LINE",4),Nit=new FS("QUADRANTS_MANHATTAN",5),$it=new FS("QUADRANTS_JITTER",6),Iit=new FS("COMBINE_LINE_BY_LINE_MANHATTAN",7),Pit=new FS("COMBINE_JITTER_MANHATTAN",8)}function nRn(n,t,e,i){var r,c,a,u,o,s;for(o=$jn(n,e),s=$jn(t,e),r=!1;o&&s&&(i||pyn(o,s,e));)a=$jn(o,e),u=$jn(s,e),C7(t),C7(n),c=o.c,eGn(o,!1),eGn(s,!1),e?(Wyn(t,s.p,c),t.p=s.p,Wyn(n,o.p+1,c),n.p=o.p):(Wyn(n,o.p,c),n.p=o.p,Wyn(t,s.p+1,c),t.p=s.p),MZ(o,null),MZ(s,null),o=a,s=u,r=!0;return r}function tRn(n,t,e,i){var r,c,a,u,o;for(r=!1,c=!1,u=new Ub(i.j);u.a=t.length)throw Fp(new Cy("Greedy SwitchDecider: Free layer not in graph."));this.c=t[n],this.e=new WK(i),vrn(this.e,this.c,(mUn(),SCt)),this.i=new WK(i),vrn(this.i,this.c,aCt),this.f=new hG(this.c),this.a=!c&&r.i&&!r.s&&this.c[0].k==(cSn(),Eut),this.a&&wPn(this,n,t.length)}function aRn(n,t){var e,i,r,c,a,u;c=!n.B.Hc((YKn(),FCt)),a=n.B.Hc(qCt),n.a=new Fwn(a,c,n.c),n.n&&mQ(n.a.n,n.n),yy(n.g,(Ntn(),qit),n.a),t||((i=new Pgn(1,c,n.c)).n.a=n.k,pG(n.p,(mUn(),uCt),i),(r=new Pgn(1,c,n.c)).n.d=n.k,pG(n.p,TCt,r),(u=new Pgn(0,c,n.c)).n.c=n.k,pG(n.p,SCt,u),(e=new Pgn(0,c,n.c)).n.b=n.k,pG(n.p,aCt,e))}function uRn(n){var t,e,i;switch((t=_B(pMn(n.d,(FXn(),Jdt)),218)).g){case 2:e=EXn(n);break;case 3:i=new $p,QT(CV(OV(lnn(lnn(new xq(null,new l1(n.d.b,16)),new Or),new Ar),new $r),new pr),new Sd(i)),e=i;break;default:throw Fp(new Ky("Compaction not supported for "+t+" edges."))}wqn(n,e),n5(new Sb(n.g),new Td(n))}function oRn(n,t){var e;return e=new Zn,t&&Ban(e,_B(xX(n.a,LOt),94)),iL(t,470)&&Ban(e,_B(xX(n.a,NOt),94)),iL(t,354)?(Ban(e,_B(xX(n.a,HOt),94)),e):(iL(t,82)&&Ban(e,_B(xX(n.a,xOt),94)),iL(t,239)?(Ban(e,_B(xX(n.a,qOt),94)),e):iL(t,186)?(Ban(e,_B(xX(n.a,GOt),94)),e):(iL(t,352)&&Ban(e,_B(xX(n.a,DOt),94)),e))}function sRn(){sRn=O,Jct=new zA((uWn(),dPt),tln(1)),iat=new zA(APt,80),eat=new zA(TPt,5),Kct=new zA(iSt,bZn),Yct=new zA(gPt,tln(1)),tat=new zA(mPt,(oN(),!0)),Wct=new UA(50),Xct=new zA(zSt,Wct),Fct=SSt,Vct=cPt,_ct=new zA(bSt,!1),Uct=GSt,zct=BSt,Gct=DSt,qct=NSt,Qct=sPt,ySn(),Hct=Pct,rat=$ct,Bct=Sct,Zct=Cct,nat=Act}function hRn(n){var t,e,i,r,c,a,u;for(u=new g5,a=new Ub(n.a);a.a0&&t=0)return!1;if(t.p=e.b,UB(e.e,t),i==(cSn(),Mut)||i==Put)for(r=new Ub(t.j);r.a1||-1==a)&&(c|=16),0!=(r.Bb&o6n)&&(c|=64)),0!=(e.Bb&_Qn)&&(c|=E9n),c|=m6n):iL(t,457)?c|=512:(i=t.Bj())&&0!=(1&i.i)&&(c|=256),0!=(512&n.Bb)&&(c|=128),c}function ORn(n,t){var e,i,r,c,a;for(n=null==n?qWn:(mW(n),n),r=0;rn.d[u.p]&&(e+=Y4(n.b,c),b3(n.a,tln(c))):++a;for(e+=n.b.d*a;!Uy(n.a);)Enn(n.b,_B(bU(n.a),19).a)}return e}function LRn(n,t){var e;return n.f==rLt?(e=NW(_7((PPn(),Q$t),t)),n.e?4==e&&t!=(jOn(),oLt)&&t!=(jOn(),cLt)&&t!=(jOn(),aLt)&&t!=(jOn(),uLt):2==e):!(!n.d||!(n.d.Hc(t)||n.d.Hc(J1(_7((PPn(),Q$t),t)))||n.d.Hc(Kqn((PPn(),Q$t),n.b,t))))||!(!n.f||!rNn((PPn(),n.f),yV(_7(Q$t,t))))&&(e=NW(_7(Q$t,t)),n.e?4==e:2==e)}function NRn(n,t,e,r){var c,a,u,o,s,h,f,l;return s=(u=_B(JAn(e,(uWn(),wPt)),8)).a,f=u.b+n,(c=i.Math.atan2(f,s))<0&&(c+=J3n),(c+=t)>J3n&&(c-=J3n),h=(o=_B(JAn(r,wPt),8)).a,l=o.b+n,(a=i.Math.atan2(l,h))<0&&(a+=J3n),(a+=t)>J3n&&(a-=J3n),o$(),ein(1e-10),i.Math.abs(c-a)<=1e-10||c==a||isNaN(c)&&isNaN(a)?0:ca?1:qO(isNaN(c),isNaN(a))}function xRn(n){var t,e,i,r,c,a,u;for(u=new Lp,i=new Ub(n.a.b);i.a=n.o)throw Fp(new Tv);a=t>>5,c=vz(1,bG(vz(31&t,1))),n.n[e][a]=r?t0(n.n[e][a],c):n0(n.n[e][a],cH(c)),c=vz(c,1),n.n[e][a]=i?t0(n.n[e][a],c):n0(n.n[e][a],cH(c))}catch(u){throw iL(u=hun(u),320)?Fp(new Cy(EYn+n.o+"*"+n.p+TYn+t+KWn+e+MYn)):Fp(u)}}function _Rn(n,t,e,r){var c,a;t&&(c=Hy(ED(pMn(t,(Bqn(),skt))))+r,a=e+Hy(ED(pMn(t,ckt)))/2,oon(t,wkt,tln(bG(san(i.Math.round(c))))),oon(t,dkt,tln(bG(san(i.Math.round(a))))),0==t.d.b||_Rn(n,_B(tL(new lg(upn(new fg(t).a.d,0))),86),e+Hy(ED(pMn(t,ckt)))+n.a,r+Hy(ED(pMn(t,akt)))),null!=pMn(t,lkt)&&_Rn(n,_B(pMn(t,lkt),86),e,r))}function FRn(n,t){var e,r,c,a,u,o,s,h,f,l,b;for(c=2*Hy(ED(pMn(s=gW(t.a),(FXn(),jpt)))),f=Hy(ED(pMn(s,Cpt))),h=i.Math.max(c,f),a=L8($Nt,BQn,25,t.f-t.c+1,15,1),r=-h,e=0,o=t.b.Kc();o.Ob();)u=_B(o.Pb(),10),r+=n.a[u.c.p]+h,a[e++]=r;for(r+=n.a[t.a.c.p]+h,a[e++]=r,b=new Ub(t.e);b.a0&&(!(i=(!n.n&&(n.n=new nU(HOt,n,1,7)),_B(Utn(n.n,0),137)).a)||aO(aO((t.a+=' "',t),i),'"'))),aO(mE(aO(mE(aO(mE(aO(mE((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function GRn(n){var t,e,i;return 0!=(64&n.Db)?pSn(n):(t=new hN(Z5n),(e=n.k)?aO(aO((t.a+=' "',t),e),'"'):(!n.n&&(n.n=new nU(HOt,n,1,7)),n.n.i>0&&(!(i=(!n.n&&(n.n=new nU(HOt,n,1,7)),_B(Utn(n.n,0),137)).a)||aO(aO((t.a+=' "',t),i),'"'))),aO(mE(aO(mE(aO(mE(aO(mE((t.a+=" (",t),n.i),","),n.j)," | "),n.g),","),n.f),")"),t.a)}function zRn(n,t){var e,i,r,c,a,u;if(null==t||0==t.length)return null;if(!(r=_B(TY(n.a,t),149))){for(i=new Db(new Ib(n.b).a.vc().Kc());i.a.Ob();)if(c=_B(i.a.Pb(),42),a=(e=_B(c.dd(),149)).c,u=t.length,pK(a.substr(a.length-u,u),t)&&(t.length==a.length||46==sV(a,a.length-t.length-1))){if(r)return null;r=e}r&&pZ(n.a,t,r)}return r}function URn(n,t){var e,i,r;return e=new xn,(i=_B(M4(OV(new xq(null,new l1(n.f,16)),e),L7(new Q,new J,new cn,new an,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),zet),Get]))),21).gc())<(r=_B(M4(OV(new xq(null,new l1(t.f,16)),e),L7(new Q,new J,new cn,new an,Mun(Hk(Yet,1),OVn,132,0,[zet,Get]))),21).gc())?-1:i==r?0:1}function XRn(n){var t,e,i;Ax(n,(FXn(),Ogt))&&((i=_B(pMn(n,Ogt),21)).dc()||(e=new VK(t=_B(Xj(HIt),9),_B(TR(t,t.length),9),0),i.Hc((YAn(),OIt))?arn(e,OIt):arn(e,AIt),i.Hc(IIt)||arn(e,IIt),i.Hc(PIt)?arn(e,NIt):i.Hc(SIt)?arn(e,LIt):i.Hc(CIt)&&arn(e,$It),i.Hc(NIt)?arn(e,PIt):i.Hc(LIt)?arn(e,SIt):i.Hc($It)&&arn(e,CIt),oon(n,Ogt,e)))}function WRn(n){var t,e,i,r,c,a,u;for(r=_B(pMn(n,(oWn(),elt)),10),h1(0,(i=n.j).c.length),e=_B(i.c[0],11),a=new Ub(r.j);a.ar.p?(BIn(c,TCt),c.d&&(u=c.o.b,t=c.a.b,c.a.b=u-t)):c.j==TCt&&r.p>n.p&&(BIn(c,uCt),c.d&&(u=c.o.b,t=c.a.b,c.a.b=-(u-t)));break}return r}function VRn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w;if(c=e,e1&&(i=new LI(r,e.b),NH(t.a,i)),Yen(t.a,Mun(Hk(MMt,1),uVn,8,0,[f,h]))}function wKn(n,t,e){var i,r,c,a,u,o;if(t){if(e<=-1){if(iL(i=ttn(t.Tg(),-1-e),99))return _B(i,18);for(u=0,o=(a=_B(t.ah(i),153)).gc();u0){for(r=o.length;r>0&&""==o[r-1];)--r;r=40)&&kFn(n),_Hn(n),jxn(n),e=vln(n),i=0;e&&i0&&NH(n.f,c)):(n.c[a]-=s+1,n.c[a]<=0&&n.a[a]>0&&NH(n.e,c))))}function VKn(n){var t,e,i,r,c,a,u;for(c=new bE(_B(vX(new Rn),62)),u=DQn,e=new Ub(n.d);e.a=0&&oe?t:e;s<=f;++s)s==e?u=i++:(c=r[s],h=w.rl(c.ak()),s==t&&(o=s!=f||h?i:i-1),h&&++i);return l=_B(Pln(n,t,e),72),u!=o&&Av(n,new y9(n.e,7,a,tln(u),b.dd(),o)),l}return _B(Pln(n,t,e),72)}function c_n(n,t){var e,i,r,c,a,u;for(ITn(t,"Port order processing",1),u=_B(pMn(n,(FXn(),apt)),421),e=new Ub(n.b);e.a=0&&(!Syn(n,a)||(o<22?u.l|=1<>>1,a.m=s>>>1|(1&h)<<21,a.l=f>>>1|(1&s)<<21,--o;return e&&Ion(u),c&&(i?(htt=ron(n),r&&(htt=oun(htt,(z7(),btt)))):htt=E$(n.l,n.m,n.h)),u}function s_n(n,t){var e,i,r,c,a,u,o,s,h,f;for(s=n.e[t.c.p][t.p]+1,o=t.c.a.c.length+1,u=new Ub(n.a);u.a0&&(f1(0,n.length),45==n.charCodeAt(0)||(f1(0,n.length),43==n.charCodeAt(0)))?1:0;ie)throw Fp(new Ek(NQn+n+'"'));return a}function f_n(n){var t,e,r,c,a,u;for(a=new VT,c=new Ub(n.a);c.a1)&&1==t&&_B(n.a[n.b],10).k==(cSn(),Tut)?oFn(_B(n.a[n.b],10),(zyn(),yIt)):i&&(!e||(n.c-n.b&n.a.length-1)>1)&&1==t&&_B(n.a[n.c-1&n.a.length-1],10).k==(cSn(),Tut)?oFn(_B(n.a[n.c-1&n.a.length-1],10),(zyn(),kIt)):2==(n.c-n.b&n.a.length-1)?(oFn(_B(kon(n),10),(zyn(),yIt)),oFn(_B(kon(n),10),kIt)):uLn(n,r),a4(n)}function g_n(n,t,e){var r,c,a,u,o;for(a=0,c=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));c.e!=c.i.gc();)u="",0==(!(r=_B(mpn(c),33)).n&&(r.n=new nU(HOt,r,1,7)),r.n).i||(u=_B(Utn((!r.n&&(r.n=new nU(HOt,r,1,7)),r.n),0),137).a),Ban(o=new isn(a++,t,u),r),oon(o,(Bqn(),ukt),r),o.e.b=r.j+r.f/2,o.f.a=i.Math.max(r.g,1),o.e.a=r.i+r.g/2,o.f.b=i.Math.max(r.f,1),NH(t.b,o),yIn(e.f,r,o)}function p_n(n){var t,e,i,r,c;i=_B(pMn(n,(oWn(),blt)),33),c=_B(JAn(i,(FXn(),Kgt)),174).Hc((pdn(),RCt)),n.e||(r=_B(pMn(n,Jft),21),t=new LI(n.f.a+n.d.b+n.d.c,n.f.b+n.d.d+n.d.a),r.Hc((fDn(),hft))?(Vpn(i,npt,(WEn(),zIt)),DUn(i,t.a,t.b,!1,!0)):By(jD(JAn(i,_gt)))||DUn(i,t.a,t.b,!0,!0)),Vpn(i,Kgt,c?Yln(RCt):new VK(e=_B(Xj(VCt),9),_B(TR(e,e.length),9),0))}function v_n(n,t,e){var i,r,c,a;if(t[0]>=n.length)return e.o=0,!0;switch(sV(n,t[0])){case 43:r=1;break;case 45:r=-1;break;default:return e.o=0,!0}if(++t[0],c=t[0],0==(a=GCn(n,t))&&t[0]==c)return!1;if(t[0]=0&&u!=e&&(c=new Yz(n,1,u,a,null),i?i.Ei(c):i=c),e>=0&&(c=new Yz(n,1,e,u==e?a:null,t),i?i.Ei(c):i=c)),i}function E_n(n){var t,e,i;if(null==n.b){if(i=new Tk,null!=n.i&&(iO(i,n.i),i.a+=":"),0!=(256&n.f)){for(0!=(256&n.f)&&null!=n.a&&(eQ(n.i)||(i.a+="//"),iO(i,n.a)),null!=n.d&&(i.a+="/",iO(i,n.d)),0!=(16&n.f)&&(i.a+="/"),t=0,e=n.j.length;ts)&&(o+u+iHn(i,s,!1).a<=t.b&&(d9(e,c-e.s),e.c=!0,d9(i,c-e.s),jvn(i,e.s,e.t+e.d+u),i.k=!0,Lcn(e.q,i),h=!0,r&&(Zen(t,i),i.j=t,n.c.length>a&&(jkn((h1(a,n.c.length),_B(n.c[a],200)),i),0==(h1(a,n.c.length),_B(n.c[a],200)).a.c.length&&u6(n,a)))),h)}function O_n(n,t){var e,i,r,c,a;if(ITn(t,"Partition midprocessing",1),r=new dY,QT(CV(new xq(null,new l1(n.a,16)),new di),new hd(r)),0!=r.d){for(a=_B(M4(r1(new xq(null,(r.i||(r.i=new FL(r,r.c))).Nc())),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),Get)]))),15),e=_B((i=a.Kc()).Pb(),19);i.Ob();)c=_B(i.Pb(),19),zLn(_B(o6(r,e),21),_B(o6(r,c),21)),e=c;FSn(t)}}function A_n(n,t,e){var i,r,c,a,u;if(0==t.p){for(t.p=1,(r=e)||(r=new eC(new $p,new VK(i=_B(Xj(KCt),9),_B(TR(i,i.length),9),0))),_B(r.a,15).Fc(t),t.k==(cSn(),Eut)&&_B(r.b,21).Fc(_B(pMn(t,(oWn(),Wft)),61)),a=new Ub(t.j);a.a0)if(r=_B(n.Ab.g,1934),null==t){for(c=0;c1)for(i=new Ub(r);i.ae.s&&oa&&(a=r,s.c=L8(Cnt,FWn,1,0,5,1)),r==a&&UB(s,new eC(e.c.i,e)));TQ(),p$(s,n.c),mG(n.b,u.p,s)}}function B_n(n,t){var e,i,r,c,a,u,o,s;for(c=new Ub(t.b);c.aa&&(a=r,s.c=L8(Cnt,FWn,1,0,5,1)),r==a&&UB(s,new eC(e.d.i,e)));TQ(),p$(s,n.c),mG(n.f,u.p,s)}}function H_n(n){$M(n,new ETn(gj(lj(dj(wj(new du,h5n),"ELK Box"),"Algorithm for packing of unconnected boxes, i.e. graphs without edges."),new xu))),c2(n,h5n,WYn,qMt),c2(n,h5n,gZn,15),c2(n,h5n,dZn,tln(0)),c2(n,h5n,C4n,ppn(RMt)),c2(n,h5n,MZn,ppn(_Mt)),c2(n,h5n,TZn,ppn(BMt)),c2(n,h5n,XYn,s5n),c2(n,h5n,yZn,ppn(KMt)),c2(n,h5n,_Zn,ppn(FMt)),c2(n,h5n,f5n,ppn(xMt)),c2(n,h5n,c3n,ppn(DMt))}function q_n(n,t){var e,i,r,c,a,u,o,s,h;if(a=(r=n.i).o.a,c=r.o.b,a<=0&&c<=0)return mUn(),MCt;switch(s=n.n.a,h=n.n.b,u=n.o.a,e=n.o.b,t.g){case 2:case 1:if(s<0)return mUn(),SCt;if(s+u>a)return mUn(),aCt;break;case 4:case 3:if(h<0)return mUn(),uCt;if(h+e>c)return mUn(),TCt}return(o=(s+u/2)/a)+(i=(h+e/2)/c)<=1&&o-i<=0?(mUn(),SCt):o+i>=1&&o-i>=0?(mUn(),aCt):i<.5?(mUn(),uCt):(mUn(),TCt)}function G_n(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;for(e=!1,o=Hy(ED(pMn(t,(FXn(),Ipt)))),l=DVn*o,r=new Ub(t.b);r.aa.n.b-a.d.d+h.a+l&&(b=s.g+h.g,h.a=(h.g*h.a+s.g*s.a)/b,h.g=b,s.f=h,e=!0)),c=a,s=h;return e}function z_n(n,t,e,i,r,c,a){var u,o,s,h,f;for(f=new fA,o=t.Kc();o.Ob();)for(h=new Ub(_B(o.Pb(),839).wf());h.a0?u.a?r>(s=u.b.rf().b)&&(n.v||1==u.c.d.c.length?(a=(r-s)/2,u.d.d=a,u.d.a=a):(e=(_B(Lq(u.c.d,0),181).rf().b-s)/2,u.d.d=i.Math.max(0,e),u.d.a=r-e-s)):u.d.a=n.t+r:Fz(n.u)&&((c=RTn(u.b)).d<0&&(u.d.d=-c.d),c.d+c.a>u.b.rf().b&&(u.d.a=c.d+c.a-u.b.rf().b))}function W_n(n,t){var e;switch(gnn(n)){case 6:return zC(t);case 7:return GC(t);case 8:return qC(t);case 3:return Array.isArray(t)&&!((e=gnn(t))>=14&&e<=16);case 11:return null!=t&&typeof t===LWn;case 12:return null!=t&&(typeof t===CWn||typeof t==LWn);case 0:return Wpn(t,n.__elementTypeId$);case 2:return NU(t)&&!(t.im===C);case 1:return NU(t)&&!(t.im===C)||Wpn(t,n.__elementTypeId$);default:return!0}}function V_n(n,t){var e,r,c,a;return r=i.Math.min(i.Math.abs(n.c-(t.c+t.b)),i.Math.abs(n.c+n.b-t.c)),a=i.Math.min(i.Math.abs(n.d-(t.d+t.a)),i.Math.abs(n.d+n.a-t.d)),(e=i.Math.abs(n.c+n.b/2-(t.c+t.b/2)))>n.b/2+t.b/2||(c=i.Math.abs(n.d+n.a/2-(t.d+t.a/2)))>n.a/2+t.a/2?1:0==e&&0==c?0:0==e?a/c+1:0==c?r/e+1:i.Math.min(r/e,a/c)+1}function Q_n(n,t){var e,r,c,a,u,o;return(c=tin(n))==(o=tin(t))?n.e==t.e&&n.a<54&&t.a<54?n.ft.f?1:0:(r=n.e-t.e,(e=(n.d>0?n.d:i.Math.floor((n.a-1)*qQn)+1)-(t.d>0?t.d:i.Math.floor((t.a-1)*qQn)+1))>r+1?c:e0&&(u=$nn(u,mBn(r))),Zdn(a,u))):c0&&n.d!=(B7(),Cat)&&(u+=a*(i.d.a+n.a[t.b][i.b]*(t.d.a-i.d.a)/e)),e>0&&n.d!=(B7(),Pat)&&(o+=a*(i.d.b+n.a[t.b][i.b]*(t.d.b-i.d.b)/e)));switch(n.d.g){case 1:return new LI(u/c,t.d.b);case 2:return new LI(t.d.a,o/c);default:return new LI(u/c,o/c)}}function Y_n(n,t){var e,i,r,c;if(qsn(),c=_B(pMn(n.i,(FXn(),npt)),98),0!=n.j.g-t.j.g||c!=(WEn(),GIt)&&c!=UIt&&c!=zIt)return 0;if(c==(WEn(),GIt)&&(e=_B(pMn(n,tpt),19),i=_B(pMn(t,tpt),19),e&&i&&0!=(r=e.a-i.a)))return r;switch(n.j.g){case 1:return Mln(n.n.a,t.n.a);case 2:return Mln(n.n.b,t.n.b);case 3:return Mln(t.n.a,n.n.a);case 4:return Mln(t.n.b,n.n.b);default:throw Fp(new Ky(e1n))}}function Z_n(n){var t,e,i,r,c;for(UB(c=new Q6((!n.a&&(n.a=new OL($Ot,n,5)),n.a).i+2),new LI(n.j,n.k)),QT(new xq(null,(!n.a&&(n.a=new OL($Ot,n,5)),new l1(n.a,16))),new Pg(c)),UB(c,new LI(n.b,n.c)),t=1;t0&&(Gun(o,!1,(Kfn(),RPt)),Gun(o,!0,KPt)),Itn(t.g,new uP(n,e)),XW(n.g,t,e)}function tFn(){var n;for(tFn=O,Att=Mun(Hk(INt,1),oQn,25,15,[-1,-1,30,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5]),$tt=L8(INt,oQn,25,37,15,1),Ltt=Mun(Hk(INt,1),oQn,25,15,[-1,-1,63,40,32,28,25,23,21,20,19,19,18,18,17,17,16,16,16,15,15,15,15,14,14,14,14,14,14,13,13,13,13,13,13,13,13]),Ntt=L8(ONt,KQn,25,37,14,1),n=2;n<=36;n++)$tt[n]=SY(i.Math.pow(n,Att[n])),Ntt[n]=Ijn(fVn,$tt[n])}function eFn(n){var t;if(1!=(!n.a&&(n.a=new nU(ROt,n,6,6)),n.a).i)throw Fp(new Ry(_5n+(!n.a&&(n.a=new nU(ROt,n,6,6)),n.a).i));return t=new mm,fun(_B(Utn((!n.b&&(n.b=new oK(xOt,n,4,7)),n.b),0),82))&&Krn(t,qXn(n,fun(_B(Utn((!n.b&&(n.b=new oK(xOt,n,4,7)),n.b),0),82)),!1)),fun(_B(Utn((!n.c&&(n.c=new oK(xOt,n,5,8)),n.c),0),82))&&Krn(t,qXn(n,fun(_B(Utn((!n.c&&(n.c=new oK(xOt,n,5,8)),n.c),0),82)),!0)),t}function iFn(n,t){var e,i,r;for(r=!1,i=new az(JL((t.d?n.a.c==(wY(),Zmt)?sbn(t.b):hbn(t.b):n.a.c==(wY(),Ymt)?sbn(t.b):hbn(t.b)).a.Kc(),new h));bAn(i);)if(e=_B(G5(i),17),(By(n.a.f[n.a.g[t.b.p].p])||f5(e)||e.c.i.c!=e.d.i.c)&&!By(n.a.n[n.a.g[t.b.p].p])&&!By(n.a.n[n.a.g[t.b.p].p])&&(r=!0,KT(n.b,n.a.g[Amn(e,t.b).p])))return t.c=!0,t.a=e,t;return t.c=r,t.a=null,t}function rFn(n,t,e,i,r){var c,a,u,o,s,h,f;for(TQ(),p$(n,new Xu),u=new E2(n,0),f=new $p,c=0;u.b2*c?(h=new Htn(f),s=tG(a)/nG(a),o=vXn(h,t,new fm,e,i,r,s),GR(mO(h.e),o),f.c=L8(Cnt,FWn,1,0,5,1),c=0,f.c[f.c.length]=h,f.c[f.c.length]=a,c=tG(h)*nG(h)+tG(a)*nG(a)):(f.c[f.c.length]=a,c+=tG(a)*nG(a));return f}function cFn(n,t,e){var i,r,c,a,u,o,s;if(0==(i=e.gc()))return!1;if(n.ej())if(o=n.fj(),mwn(n,t,e),a=1==i?n.Zi(3,null,e.Kc().Pb(),t,o):n.Zi(5,null,e,t,o),n.bj()){for(u=i<100?null:new Kj(i),c=t+i,r=t;r0){for(u=0;u>16==-15&&n.Cb.nh()&&O7(new m9(n.Cb,9,13,e,n.c,cvn(F7(_B(n.Cb,59)),n))):iL(n.Cb,88)&&n.Db>>16==-23&&n.Cb.nh()&&(iL(t=n.c,88)||(wWn(),t=l$t),iL(e,88)||(wWn(),e=l$t),O7(new m9(n.Cb,9,10,e,t,cvn(r4(_B(n.Cb,26)),n)))))),n.c}function fFn(n,t){var e,i,r,c,a,u,o,s;for(ITn(t,"Hypernodes processing",1),i=new Ub(n.b);i.ae);return r}function dFn(n,t){var e,i,r;i=0!=F$n(n.d,1),!By(jD(pMn(t.j,(oWn(),Qft))))&&!By(jD(pMn(t.j,Plt)))||HC(pMn(t.j,(FXn(),Adt)))===HC((pon(),$vt))?t.c.Tf(t.e,i):i=By(jD(pMn(t.j,Qft))),NNn(n,t,i,!0),By(jD(pMn(t.j,Plt)))&&oon(t.j,Plt,(oN(),!1)),By(jD(pMn(t.j,Qft)))&&(oon(t.j,Qft,(oN(),!1)),oon(t.j,Plt,!0)),e=YPn(n,t);do{if(Orn(n),0==e)return 0;r=e,NNn(n,t,i=!i,!1),e=YPn(n,t)}while(r>e);return r}function gFn(n,t,e){var i,r,c,a,u,o,s;if(t==e)return!0;if(t=fAn(n,t),e=fAn(n,e),i=Bvn(t)){if((o=Bvn(e))!=i)return!!o&&(a=i.Dj())==o.Dj()&&null!=a;if(!t.d&&(t.d=new OL(UAt,t,1)),r=(c=t.d).i,!e.d&&(e.d=new OL(UAt,e,1)),r==(s=e.d).i)for(u=0;u0,u=$bn(t,c),DN(e?u.b:u.g,t),1==mbn(u).c.length&&e5(i,u,i.c.b,i.c),r=new eC(c,t),b3(n.o,r),v7(n.e.a,c))}function jFn(n,t){var e,r,c,a;return r=i.Math.abs(Bz(n.b).a-Bz(t.b).a),a=i.Math.abs(Bz(n.b).b-Bz(t.b).b),e=1,c=1,r>n.b.b/2+t.b.b/2&&(e=1-i.Math.min(i.Math.abs(n.b.c-(t.b.c+t.b.b)),i.Math.abs(n.b.c+n.b.b-t.b.c))/r),a>n.b.a/2+t.b.a/2&&(c=1-i.Math.min(i.Math.abs(n.b.d-(t.b.d+t.b.a)),i.Math.abs(n.b.d+n.b.a-t.b.d))/a),(1-i.Math.min(e,c))*i.Math.sqrt(r*r+a*a)}function EFn(n){var t,e,i;for(Yzn(n,n.e,n.f,(bY(),Ayt),!0,n.c,n.i),Yzn(n,n.e,n.f,Ayt,!1,n.c,n.i),Yzn(n,n.e,n.f,$yt,!0,n.c,n.i),Yzn(n,n.e,n.f,$yt,!1,n.c,n.i),PFn(n,n.c,n.e,n.f,n.i),e=new E2(n.i,0);e.b=65;e--)zLt[e]=e-65<<24>>24;for(i=122;i>=97;i--)zLt[i]=i-97+26<<24>>24;for(r=57;r>=48;r--)zLt[r]=r-48+52<<24>>24;for(zLt[43]=62,zLt[47]=63,c=0;c<=25;c++)ULt[c]=65+c&WVn;for(a=26,o=0;a<=51;++a,o++)ULt[a]=97+o&WVn;for(n=52,u=0;n<=61;++n,u++)ULt[n]=48+u&WVn;ULt[62]=43,ULt[63]=47}function SFn(n,t){var e,r,c,a,u,o,s,h,f,l,b;if(n.dc())return new Hj;for(s=0,f=0,r=n.Kc();r.Ob();)c=_B(r.Pb(),37).f,s=i.Math.max(s,c.a),f+=c.a*c.b;for(s=i.Math.max(s,i.Math.sqrt(f)*Hy(ED(pMn(_B(n.Kc().Pb(),37),(FXn(),kdt))))),l=0,b=0,o=0,e=t,u=n.Kc();u.Ob();)l+(h=(a=_B(u.Pb(),37)).f).a>s&&(l=0,b+=o+t,o=0),JRn(a,l,b),e=i.Math.max(e,l+h.a),o=i.Math.max(o,h.b),l+=h.a+t;return new LI(e+t,b+o+t)}function PFn(n,t,e,i,r){var c,a,u,o,s,h,f;for(a=new Ub(t);a.ac)return mUn(),aCt;break;case 4:case 3:if(o<0)return mUn(),uCt;if(o+n.f>r)return mUn(),TCt}return(a=(u+n.g/2)/c)+(e=(o+n.f/2)/r)<=1&&a-e<=0?(mUn(),SCt):a+e>=1&&a-e>=0?(mUn(),aCt):e<.5?(mUn(),uCt):(mUn(),TCt)}function CFn(n,t,e,i,r){var c,a;if(c=ebn(n0(t[0],GQn),n0(i[0],GQn)),n[0]=bG(c),c=mz(c,32),e>=r){for(a=1;a0&&(r.b[a++]=0,r.b[a++]=c.b[0]-1),t=1;t0&&(Xl(o,o.d-r.d),r.c==(I6(),jyt)&&zl(o,o.a-r.d),o.d<=0&&o.i>0&&e5(t,o,t.c.b,t.c));for(c=new Ub(n.f);c.a0&&(Wl(u,u.i-r.d),r.c==(I6(),jyt)&&Ul(u,u.b-r.d),u.i<=0&&u.d>0&&e5(e,u,e.c.b,e.c))}function LFn(n,t,e){var i,r,c,a,u,o,s,h;for(ITn(e,"Processor compute fanout",1),OU(n.b),OU(n.a),u=null,c=upn(t.b,0);!u&&c.b!=c.d.c;)By(jD(pMn(s=_B(f3(c),86),(Bqn(),bkt))))&&(u=s);for(e5(o=new VT,u,o.c.b,o.c),yUn(n,o),h=upn(t.b,0);h.b!=h.d.c;)a=TD(pMn(s=_B(f3(h),86),(Bqn(),ekt))),r=null!=TY(n.b,a)?_B(TY(n.b,a),19).a:0,oon(s,tkt,tln(r)),i=1+(null!=TY(n.a,a)?_B(TY(n.a,a),19).a:0),oon(s,Zyt,tln(i));FSn(e)}function NFn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;for(f=vEn(n,e),u=0;u0),i.a.Xb(i.c=--i.b),h>f+u&&sW(i);for(c=new Ub(l);c.a0),i.a.Xb(i.c=--i.b)}}function xFn(){var n,t,e,i,r,c;if(lWn(),MNt)return MNt;for(uHn(n=new E0(4),JUn(dnt,!0)),UGn(n,JUn("M",!0)),UGn(n,JUn("C",!0)),c=new E0(4),i=0;i<11;i++)Vxn(c,i,i);return uHn(t=new E0(4),JUn("M",!0)),Vxn(t,4448,4607),Vxn(t,65438,65439),ZHn(r=new e$(2),n),ZHn(r,aNt),(e=new e$(2)).$l(wG(c,JUn("L",!0))),e.$l(t),e=new GU(r,e=new o4(3,e)),MNt=e}function DFn(n){var t,e;if(!Vcn(t=TD(JAn(n,(uWn(),nSt))),n)&&!M8(n,pPt)&&(0!=(!n.a&&(n.a=new nU(qOt,n,10,11)),n.a).i||By(jD(JAn(n,TSt))))){if(null!=t&&0!=xMn(t).length)throw wzn(n,e=aO(aO(new hN("Layout algorithm '"),t),"' not found for ")),Fp(new ek(e.a));if(!Vcn(l1n,n))throw wzn(n,e=aO(aO(new hN("Unable to load default layout algorithm "),l1n)," for unconfigured node ")),Fp(new ek(e.a))}}function RFn(n){var t,e,r,c,a,u,o,s,h,f,l,b,w;if(e=n.i,t=n.n,0==n.b)for(w=e.c+t.b,b=e.b-t.b-t.c,s=0,f=(u=n.a).length;s0&&(l-=r[0]+n.c,r[0]+=n.c),r[2]>0&&(l-=r[2]+n.c),r[1]=i.Math.max(r[1],l),GG(n.a[1],e.c+t.b+r[0]-(r[1]-l)/2,r[1]);for(o=0,h=(a=n.a).length;o0?(n.n.c.length-1)*n.i:0,e=new Ub(n.n);e.a1)for(i=upn(r,0);i.b!=i.d.c;)for(c=0,u=new Ub((e=_B(f3(i),231)).e);u.a0&&(t[0]+=n.c,l-=t[0]),t[2]>0&&(l-=t[2]+n.c),t[1]=i.Math.max(t[1],l),zG(n.a[1],r.d+e.d+t[0]-(t[1]-l)/2,t[1]);else for(w=r.d+e.d,b=r.a-e.d-e.a,s=0,f=(u=n.a).length;s=0&&c!=e)throw Fp(new Ry(r8n));for(r=0,o=0;o0||0==Pbn(c.b.d,n.b.d+n.b.a)&&r.b<0||0==Pbn(c.b.d+c.b.a,n.b.d)&&r.b>0){o=0;break}}else o=i.Math.min(o,FIn(n,c,r));o=i.Math.min(o,UFn(n,a,o,r))}return o}function XFn(n,t){var e,i,r,c,a,u;if(n.b<2)throw Fp(new Ry("The vector chain must contain at least a source and a target point."));for(Mx(0!=n.b),SA(t,(i=_B(n.a.a.c,8)).a,i.b),u=new ix((!t.a&&(t.a=new OL($Ot,t,5)),t.a)),c=upn(n,1);c.aHy(hL(a.g,a.d[0]).a)?(Mx(o.b>0),o.a.Xb(o.c=--o.b),vR(o,a),r=!0):u.e&&u.e.gc()>0&&(c=(!u.e&&(u.e=new $p),u.e).Mc(t),s=(!u.e&&(u.e=new $p),u.e).Mc(e),(c||s)&&((!u.e&&(u.e=new $p),u.e).Fc(a),++a.c));r||(i.c[i.c.length]=a)}function iBn(n){var t,e,i;if(gA(_B(pMn(n,(FXn(),npt)),98)))for(e=new Ub(n.j);e.a>>0).toString(16),t.length-2,t.length):n>=_Qn?"\\v"+sx(t="0"+(n>>>0).toString(16),t.length-6,t.length):""+String.fromCharCode(n&WVn)}return e}function cBn(n,t){var e,i,r,c,a,u,o,s,h,f;if(a=n.e,0==(o=t.e))return n;if(0==a)return 0==t.e?t:new hU(-t.e,t.d,t.a);if((c=n.d)+(u=t.d)==2)return e=n0(n.a[0],GQn),i=n0(t.a[0],GQn),a<0&&(e=y7(e)),o<0&&(i=y7(i)),Ygn(tbn(e,i));if(-1==(r=c!=u?c>u?1:-1:Esn(n.a,t.a,c)))f=-o,h=a==o?b6(t.a,u,n.a,c):$8(t.a,u,n.a,c);else if(f=a,a==o){if(0==r)return IDn(),net;h=b6(n.a,c,t.a,u)}else h=$8(n.a,c,t.a,u);return z0(s=new hU(f,h.length,h)),s}function aBn(n){var t,e,i,r,c,a;for(this.e=new $p,this.a=new $p,e=n.b-1;e<3;e++)Dx(n,0,_B(Npn(n,0),8));if(n.b<4)throw Fp(new Ry("At (least dimension + 1) control points are necessary!"));for(this.b=3,this.d=!0,this.c=!1,P$n(this,n.b+this.b-1),a=new $p,c=new Ub(this.e),t=0;t=t.o&&e.f<=t.f||.5*t.a<=e.f&&1.5*t.a>=e.f){if((c=_B(Lq(t.n,t.n.c.length-1),211)).e+c.d+e.g+r<=i&&(_B(Lq(t.n,t.n.c.length-1),211).f-n.f+e.f<=n.b||1==n.a.c.length))return vbn(t,e),!0;if(t.s+e.g<=i&&(t.t+t.d+e.f+r<=n.b||1==n.a.c.length))return UB(t.b,e),a=_B(Lq(t.n,t.n.c.length-1),211),UB(t.n,new xY(t.s,a.f+a.a+t.i,t.i)),umn(_B(Lq(t.n,t.n.c.length-1),211),e),_Fn(t,e),!0}return!1}function sBn(n,t,e){var i,r,c,a;return n.ej()?(r=null,c=n.fj(),i=n.Zi(1,a=ann(n,t,e),e,t,c),n.bj()&&!(n.ni()&&null!=a?$fn(a,e):HC(a)===HC(e))?(null!=a&&(r=n.dj(a,r)),r=n.cj(e,r),n.ij()&&(r=n.lj(a,e,r)),r?(r.Ei(i),r.Fi()):n.$i(i)):(n.ij()&&(r=n.lj(a,e,r)),r?(r.Ei(i),r.Fi()):n.$i(i)),a):(a=ann(n,t,e),n.bj()&&!(n.ni()&&null!=a?$fn(a,e):HC(a)===HC(e))&&(r=null,null!=a&&(r=n.dj(a,null)),(r=n.cj(e,r))&&r.Fi()),a)}function hBn(n,t){var e,r,c,a,u,o,s;t%=24,n.q.getHours()!=t&&((e=new i.Date(n.q.getTime())).setDate(e.getDate()+1),(u=n.q.getTimezoneOffset()-e.getTimezoneOffset())>0&&(o=u/60|0,s=u%60,r=n.q.getDate(),n.q.getHours()+o>=24&&++r,c=new i.Date(n.q.getFullYear(),n.q.getMonth(),r,t+o,n.q.getMinutes()+s,n.q.getSeconds(),n.q.getMilliseconds()),n.q.setTime(c.getTime()))),a=n.q.getTime(),n.q.setTime(a+36e5),n.q.getHours()!=t&&n.q.setTime(a)}function fBn(n,t){var e,i,r,c;if(ITn(t,"Path-Like Graph Wrapping",1),0!=n.b.c.length)if(null==(r=new EAn(n)).i&&(r.i=Urn(r,new kc)),e=Hy(r.i)*r.f/(null==r.i&&(r.i=Urn(r,new kc)),Hy(r.i)),r.b>e)FSn(t);else{switch(_B(pMn(n,(FXn(),_pt)),337).g){case 2:c=new Tc;break;case 0:c=new wc;break;default:c=new Mc}if(i=c.Vf(n,r),!c.Wf())switch(_B(pMn(n,zpt),338).g){case 2:i=zIn(r,i);break;case 1:i=DTn(r,i)}tqn(n,r,i),FSn(t)}else FSn(t)}function lBn(n,t){var e,i,r,c;if(s1(n.d,n.e),n.c.a.$b(),0!=Hy(ED(pMn(t.j,(FXn(),Pdt))))||0!=Hy(ED(pMn(t.j,Pdt))))for(e=JYn,HC(pMn(t.j,Adt))!==HC((pon(),$vt))&&oon(t.j,(oWn(),Qft),(oN(),!0)),c=_B(pMn(t.j,Lpt),19).a,r=0;r(h1(c+1,t.c.length),_B(t.c[c+1],19)).a-i&&++u,UB(r,(h1(c+u,t.c.length),_B(t.c[c+u],19))),a+=(h1(c+u,t.c.length),_B(t.c[c+u],19)).a-i,++e;e1&&(o>tG(u)*nG(u)/2||0==a.b)&&(f=new Htn(l),h=tG(u)/nG(u),s=vXn(f,t,new fm,e,i,r,h),GR(mO(f.e),s),u=f,b.c[b.c.length]=f,o=0,l.c=L8(Cnt,FWn,1,0,5,1)));return wun(b,l),b}function pBn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d;if(e.mh(t)&&(h=(b=t)?_B(i,49).xh(b):null))if(d=e.bh(t,n.a),(w=t.t)>1||-1==w)if(f=_B(d,69),l=_B(h,69),f.dc())l.$b();else for(a=!!Svn(t),c=0,u=n.a?f.Kc():f.Zh();u.Ob();)s=_B(u.Pb(),56),(r=_B(hnn(n,s),56))?(a?-1==(o=l.Xc(r))?l.Xh(c,r):c!=o&&l.ji(c,r):l.Xh(c,r),++c):n.b&&!a&&(l.Xh(c,s),++c);else null==d?h.Wb(null):null==(r=hnn(n,d))?n.b&&!Svn(t)&&h.Wb(d):h.Wb(r)}function vBn(n,t){var e,r,c,a,u,o,s,f;for(e=new Le,c=new az(JL(sbn(t).a.Kc(),new h));bAn(c);)if(!f5(r=_B(G5(c),17))&&nTn(o=r.c.i,zut)){if(-1==(f=XDn(n,o,zut,Gut)))continue;e.b=i.Math.max(e.b,f),!e.a&&(e.a=new $p),UB(e.a,o)}for(u=new az(JL(hbn(t).a.Kc(),new h));bAn(u);)if(!f5(a=_B(G5(u),17))&&nTn(s=a.d.i,Gut)){if(-1==(f=XDn(n,s,Gut,zut)))continue;e.d=i.Math.max(e.d,f),!e.c&&(e.c=new $p),UB(e.c,s)}return e}function mBn(n){var t,e,i,r;if(OOn(),t=SY(n),n1e6)throw Fp(new Iy("power of ten too big"));if(n<=NWn)return H5(cOn(ret[1],t),t);for(r=i=cOn(ret[1],NWn),e=san(n-NWn),t=SY(n%NWn);Xhn(e,NWn)>0;)r=$nn(r,i),e=tbn(e,NWn);for(r=H5(r=$nn(r,cOn(ret[1],t)),NWn),e=san(n-NWn);Xhn(e,NWn)>0;)r=H5(r,NWn),e=tbn(e,NWn);return r=H5(r,t)}function yBn(n,t){var e,i,r,c,a,u,o,s;for(ITn(t,"Hierarchical port dummy size processing",1),u=new $p,s=new $p,e=2*Hy(ED(pMn(n,(FXn(),mpt)))),r=new Ub(n.b);r.as&&i>s)){r=!1,e.n&&IH(e,"bk node placement breaks on "+u+" which should have been after "+h);break}h=u,s=Hy(t.p[u.p])+Hy(t.d[u.p])+u.o.b+u.d.a}if(!r)break}return e.n&&IH(e,t+" is feasible: "+r),r}function IBn(n,t,e,i){var r,c,a,u,o,s,h;for(u=-1,h=new Ub(n);h.a=g&&n.e[s.p]>w*n.b||m>=e*g)&&(l.c[l.c.length]=o,o=new $p,Krn(u,a),a.a.$b(),h-=f,b=i.Math.max(b,h*n.b+d),h+=m,v=m,m=0,f=0,d=0);return new eC(b,l)}function $Bn(n){var t,e,i,r,c,a,u,o,s,h,f,l;for(e=new Db(new Ib(n.c.b).a.vc().Kc());e.a.Ob();)u=_B(e.a.Pb(),42),null==(r=(t=_B(u.dd(),149)).a)&&(r=""),!(i=RD(n.c,r))&&0==r.length&&(i=vfn(n)),i&&!vwn(i.c,t,!1)&&NH(i.c,t);for(a=upn(n.a,0);a.b!=a.d.c;)c=_B(f3(a),478),s=j5(n.c,c.a),l=j5(n.c,c.b),s&&l&&NH(s.c,new eC(l,c.c));for(vQ(n.a),f=upn(n.b,0);f.b!=f.d.c;)h=_B(f3(f),478),t=DD(n.c,h.a),o=j5(n.c,h.b),t&&o&&NM(t,o,h.c);vQ(n.b)}function LBn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;c=new Ml(n),b5((a=new bkn).g),b5(a.j),OU(a.b),b5(a.d),b5(a.i),OU(a.k),OU(a.c),OU(a.e),b=fCn(a,c,null),I$n(a,c),r=b,t&&(u=nHn(s=new Ml(t)),gSn(r,Mun(Hk(YTt,1),FWn,527,0,[u]))),l=!1,f=!1,e&&(s=new Ml(e),h8n in s.a&&(l=qY(s,h8n).ge().a),f8n in s.a&&(f=qY(s,f8n).ge().a)),h=Oj(Ken(new zm,l),f),_Sn(new su,r,h),h8n in c.a&&etn(c,h8n,null),(l||f)&&(YFn(h,o=new dy,l,f),etn(c,h8n,o)),i=new zg(a),Gon(new IA(r),i)}function NBn(n,t,e){var i,r,c,a,u,o,s,h,f;for(a=new Vkn,s=Mun(Hk(INt,1),oQn,25,15,[0]),r=-1,c=0,i=0,o=0;o0)){if(r=-1,32==sV(h.c,0)){if(f=s[0],vnn(t,s),s[0]>f)continue}else if(OJ(t,h.c,s[0])){s[0]+=h.c.length;continue}return 0}if(r<0&&h.a&&(r=o,c=s[0],i=0),r>=0){if(u=h.b,o==r&&0==(u-=i++))return 0;if(!AUn(t,s,h,u,a)){o=r-1,s[0]=c;continue}}else if(r=-1,!AUn(t,s,h,0,a))return 0}return bUn(a,e)?s[0]:0}function xBn(n){var t,e,i,r,c,a;if(!n.f){if(a=new Mo,c=new Mo,null==(t=T$t).a.zc(n,t)){for(r=new CL(mJ(n));r.e!=r.i.gc();)dX(a,xBn(_B(mpn(r),26)));t.a.Bc(n),t.a.gc()}for(!n.s&&(n.s=new nU(RAt,n,21,17)),i=new CL(n.s);i.e!=i.i.gc();)iL(e=_B(mpn(i),170),99)&&s9(c,_B(e,18));ihn(c),n.r=new jH(n,(_B(Utn(WQ((WX(),YAt).o),6),18),c.i),c.g),dX(a,n.r),ihn(a),n.f=new $O((_B(Utn(WQ(YAt.o),5),18),a.i),a.g),M5(n).b&=-3}return n.f}function DBn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w;for(a=n.o,i=L8(INt,oQn,25,a,15,1),r=L8(INt,oQn,25,a,15,1),e=n.p,t=L8(INt,oQn,25,e,15,1),c=L8(INt,oQn,25,e,15,1),s=0;s=0&&!gmn(n,h,f);)--f;r[h]=f}for(b=0;b=0&&!gmn(n,u,w);)--u;c[w]=u}for(o=0;ot[l]&&li[o]&&KRn(n,o,l,!1,!0)}function RBn(n){var t,e,i,r,c,a,u,o;e=By(jD(pMn(n,(sRn(),_ct)))),c=n.a.c.d,u=n.a.d.d,e?(a=mL(zR(new LI(u.a,u.b),c),.5),o=mL(_$(n.e),.5),t=zR(GR(new LI(c.a,c.b),a),o),Fx(n.d,t)):(r=Hy(ED(pMn(n.a,eat))),i=n.d,c.a>=u.a?c.b>=u.b?(i.a=u.a+(c.a-u.a)/2+r,i.b=u.b+(c.b-u.b)/2-r-n.e.b):(i.a=u.a+(c.a-u.a)/2+r,i.b=c.b+(u.b-c.b)/2+r):c.b>=u.b?(i.a=c.a+(u.a-c.a)/2+r,i.b=u.b+(c.b-u.b)/2+r):(i.a=c.a+(u.a-c.a)/2+r,i.b=c.b+(u.b-c.b)/2-r-n.e.b))}function KBn(n,t){var e,i,r,c,a,u,o;if(null==n)return null;if(0==(c=n.length))return"";for(o=L8(PNt,UVn,25,c,15,1),R8(0,c,n.length),R8(0,c,o.length),VU(n,0,c,o,0),e=null,u=t,r=0,a=0;r0?sx(e.a,0,c-1):"":n.substr(0,c-1):e?e.a:n}function _Bn(n){$M(n,new ETn(gj(lj(dj(wj(new du,GYn),"ELK DisCo"),"Layouter for arranging unconnected subgraphs. The subgraphs themselves are, by default, not laid out."),new at))),c2(n,GYn,zYn,ppn(kct)),c2(n,GYn,UYn,ppn(dct)),c2(n,GYn,XYn,ppn(hct)),c2(n,GYn,WYn,ppn(gct)),c2(n,GYn,zJn,ppn(mct)),c2(n,GYn,UJn,ppn(vct)),c2(n,GYn,GJn,ppn(yct)),c2(n,GYn,XJn,ppn(pct)),c2(n,GYn,_Yn,ppn(lct)),c2(n,GYn,FYn,ppn(fct)),c2(n,GYn,BYn,ppn(bct)),c2(n,GYn,HYn,ppn(wct))}function FBn(n,t,e,i){var r,c,a,u,o,s,h;if(_l(c=new Ovn(n),(cSn(),Put)),oon(c,(FXn(),npt),(WEn(),zIt)),r=0,t){for(oon(a=new SSn,(oWn(),blt),t),oon(c,blt,t.i),BIn(a,(mUn(),SCt)),SZ(a,c),s=0,h=(o=J0(t.e)).length;s0)if((e-=r.length-t)>=0){for(c.a+="0.";e>Btt.length;e-=Btt.length)$q(c,Btt);wR(c,Btt,SY(e)),aO(c,r.substr(t))}else aO(c,sx(r,t,SY(e=t-e))),c.a+=".",aO(c,YC(r,SY(e)));else{for(aO(c,r.substr(t));e<-Btt.length;e+=Btt.length)$q(c,Btt);wR(c,Btt,SY(-e))}return c.a}function qBn(n,t,e,r){var c,a,u,o,s,h,f,l,b;return h=(s=zR(new LI(e.a,e.b),n)).a*t.b-s.b*t.a,f=t.a*r.b-t.b*r.a,l=(s.a*r.b-s.b*r.a)/f,b=h/f,0==f?0==h?(a=U8(n,c=GR(new LI(e.a,e.b),mL(new LI(r.a,r.b),.5))),u=U8(GR(new LI(n.a,n.b),t),c),o=.5*i.Math.sqrt(r.a*r.a+r.b*r.b),a=0&&l<=1&&b>=0&&b<=1?GR(new LI(n.a,n.b),mL(new LI(t.a,t.b),l)):null}function GBn(n,t,e){var i,r,c,a,u;if(i=_B(pMn(n,(FXn(),$dt)),21),e.a>t.a&&(i.Hc((lEn(),UMt))?n.c.a+=(e.a-t.a)/2:i.Hc(WMt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((lEn(),QMt))?n.c.b+=(e.b-t.b)/2:i.Hc(VMt)&&(n.c.b+=e.b-t.b)),_B(pMn(n,(oWn(),Jft)),21).Hc((fDn(),hft))&&(e.a>t.a||e.b>t.b))for(u=new Ub(n.a);u.at.a&&(i.Hc((lEn(),UMt))?n.c.a+=(e.a-t.a)/2:i.Hc(WMt)&&(n.c.a+=e.a-t.a)),e.b>t.b&&(i.Hc((lEn(),QMt))?n.c.b+=(e.b-t.b)/2:i.Hc(VMt)&&(n.c.b+=e.b-t.b)),_B(pMn(n,(oWn(),Jft)),21).Hc((fDn(),hft))&&(e.a>t.a||e.b>t.b))for(a=new Ub(n.a);a.at&&(r=0,c+=s.b+e,h.c[h.c.length]=s,Zen(s=new L0(c,e),i=new rsn(0,s.f,s,e)),r=0),0==i.b.c.length||u.f>=i.o&&u.f<=i.f||.5*i.a<=u.f&&1.5*i.a>=u.f?vbn(i,u):(Zen(s,a=new rsn(i.s+i.r+e,s.f,s,e)),vbn(a,u)),r=u.i+u.g;return h.c[h.c.length]=s,h}function VBn(n){var t,e,i,r,c,a;if(!n.a){if(n.o=null,a=new wp(n),t=new So,null==(e=T$t).a.zc(n,e)){for(c=new CL(mJ(n));c.e!=c.i.gc();)dX(a,VBn(_B(mpn(c),26)));e.a.Bc(n),e.a.gc()}for(!n.s&&(n.s=new nU(RAt,n,21,17)),r=new CL(n.s);r.e!=r.i.gc();)iL(i=_B(mpn(r),170),322)&&s9(t,_B(i,34));ihn(t),n.k=new kH(n,(_B(Utn(WQ((WX(),YAt).o),7),18),t.i),t.g),dX(a,n.k),ihn(a),n.a=new $O((_B(Utn(WQ(YAt.o),4),18),a.i),a.g),M5(n).b&=-2}return n.a}function QBn(n,t,e,i,r,c,a){var u,o,s,h,f;return h=!1,u=bNn(e.q,t.f+t.b-e.q.f),!((f=r-(e.q.e+u-a))=(h1(c,n.c.length),_B(n.c[c],200)).e,!((s=iHn(i,f,!1).a)>t.b&&!o)&&((o||s<=t.b)&&(o&&s>t.b?(e.d=s,d9(e,KSn(e,s))):(rEn(e.q,u),e.c=!0),d9(i,r-(e.s+e.r)),jvn(i,e.q.e+e.q.d,t.f),Zen(t,i),n.c.length>c&&(jkn((h1(c,n.c.length),_B(n.c[c],200)),i),0==(h1(c,n.c.length),_B(n.c[c],200)).a.c.length&&u6(n,c)),h=!0),h))}function JBn(n,t,e,i){var r,c,a,u,o,s,h;if(h=rxn(n.e.Tg(),t),r=0,c=_B(n.g,119),o=null,JM(),_B(t,66).Oj()){for(u=0;un.o.a&&(f=(s-n.o.a)/2,o.b=i.Math.max(o.b,f),o.c=i.Math.max(o.c,f))}}function nHn(n){var t,e,i,r,c,a;for(iA(r=new x0,($un(),QTt)),i=new Tb(new Qy(new jT(n,yrn(n,L8(Wtt,uVn,2,0,6,1))).b));i.b0?n.i:0)>t&&s>0&&(a=0,u+=s+n.i,c=i.Math.max(c,b),r+=s+n.i,s=0,b=0,e&&(++l,UB(n.n,new xY(n.s,u,n.i))),o=0),b+=h.g+(o>0?n.i:0),s=i.Math.max(s,h.f),e&&umn(_B(Lq(n.n,l),211),h),a+=h.g+(o>0?n.i:0),++o;return c=i.Math.max(c,b),r+=s,e&&(n.r=c,n.d=r,vyn(n.j)),new GV(n.s,n.t,c,r)}function rHn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;if(OT(),TU(n,"src"),TU(e,"dest"),l=Zon(n),o=Zon(e),dH(0!=(4&l.i),"srcType is not an array"),dH(0!=(4&o.i),"destType is not an array"),f=l.c,a=o.c,dH(0!=(1&f.i)?f==a:0==(1&a.i),"Array types don't match"),b=n.length,s=e.length,t<0||i<0||r<0||t+r>b||i+r>s)throw Fp(new sv);if(0==(1&f.i)&&l!=o)if(h=nen(n),c=nen(e),HC(n)===HC(e)&&ti;)OX(c,u,h[--t]);else for(u=i+r;i0&&RIn(n,t,e,i,r,!0)}function cHn(){cHn=O,eet=Mun(Hk(INt,1),oQn,25,15,[RVn,1162261467,IVn,1220703125,362797056,1977326743,IVn,387420489,CQn,214358881,429981696,815730721,1475789056,170859375,268435456,410338673,612220032,893871739,128e7,1801088541,113379904,148035889,191102976,244140625,308915776,387420489,481890304,594823321,729e6,887503681,IVn,1291467969,1544804416,1838265625,60466176]),iet=Mun(Hk(INt,1),oQn,25,15,[-1,-1,31,19,15,13,11,11,10,9,9,8,8,8,8,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5])}function aHn(n){var t,e,i,r,c,a,u;for(i=new Ub(n.b);i.a=n.b.length?(c[r++]=a.b[i++],c[r++]=a.b[i++]):i>=a.b.length?(c[r++]=n.b[e++],c[r++]=n.b[e++]):a.b[i]0?n.i:0)),++t;for(Ybn(n.n,s),n.d=e,n.r=r,n.g=0,n.f=0,n.e=0,n.o=xQn,n.p=xQn,a=new Ub(n.b);a.a0&&(!(r=(!n.n&&(n.n=new nU(HOt,n,1,7)),_B(Utn(n.n,0),137)).a)||aO(aO((t.a+=' "',t),r),'"'))),!n.b&&(n.b=new oK(xOt,n,4,7)),e=!(n.b.i<=1&&(!n.c&&(n.c=new oK(xOt,n,5,8)),n.c.i<=1)),t.a+=e?" [":" ",aO(t,QL(new pk,new CL(n.b))),e&&(t.a+="]"),t.a+=n1n,e&&(t.a+="["),aO(t,QL(new pk,new CL(n.c))),e&&(t.a+="]"),t.a)}function fHn(n,t){var e,i,r,c,a,u,o;if(n.a){if(o=null,null!=(u=n.a.ne())?t.a+=""+u:null!=(a=n.a.Dj())&&(-1!=(c=HO(a,VTn(91)))?(o=a.substr(c),t.a+=""+sx(null==a?qWn:(mW(a),a),0,c)):t.a+=""+a),n.d&&0!=n.d.i){for(r=!0,t.a+="<",i=new CL(n.d);i.e!=i.i.gc();)e=_B(mpn(i),87),r?r=!1:t.a+=KWn,fHn(e,t);t.a+=">"}null!=o&&(t.a+=""+o)}else n.e?null!=(u=n.e.zb)&&(t.a+=""+u):(t.a+="?",n.b?(t.a+=" super ",fHn(n.b,t)):n.f&&(t.a+=" extends ",fHn(n.f,t)))}function lHn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;for(y=n.c,k=t.c,e=k7(y.a,n,0),i=k7(k.a,t,0),v=_B(Lwn(n,(rin(),Fvt)).Kc().Pb(),11),T=_B(Lwn(n,Bvt).Kc().Pb(),11),m=_B(Lwn(t,Fvt).Kc().Pb(),11),M=_B(Lwn(t,Bvt).Kc().Pb(),11),g=J0(v.e),j=J0(T.g),p=J0(m.e),E=J0(M.g),Wyn(n,i,k),s=0,b=(c=p).length;sh?new qZ((I6(),Eyt),e,t,s-h):s>0&&h>0&&(new qZ((I6(),Eyt),t,e,0),new qZ(Eyt,e,t,0))),a)}function dHn(n,t){var e,r,c,a,u;for(u=new csn(new Mb(n.f.b).a);u.b;){if(c=_B((a=Ztn(u)).cd(),594),1==t){if(c.gf()!=(Kfn(),FPt)&&c.gf()!=DPt)continue}else if(c.gf()!=(Kfn(),RPt)&&c.gf()!=KPt)continue;switch(r=_B(_B(a.dd(),46).b,81),e=_B(_B(a.dd(),46).a,189).c,c.gf().g){case 2:r.g.c=n.e.a,r.g.b=i.Math.max(1,r.g.b+e);break;case 1:r.g.c=r.g.c+e,r.g.b=i.Math.max(1,r.g.b-e);break;case 4:r.g.d=n.e.b,r.g.a=i.Math.max(1,r.g.a+e);break;case 3:r.g.d=r.g.d+e,r.g.a=i.Math.max(1,r.g.a-e)}}}function gHn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g;for(o=L8(INt,oQn,25,t.b.c.length,15,1),h=L8(Out,OVn,267,t.b.c.length,0,1),s=L8(Iut,r1n,10,t.b.c.length,0,1),b=0,w=(l=n.a).length;b0&&s[r]&&(d=D$(n.b,s[r],c)),g=i.Math.max(g,c.c.c.b+d);for(a=new Ub(f.e);a.a1)throw Fp(new Ry(P7n));o||(c=J3(t,i.Kc().Pb()),a.Fc(c))}return aon(n,kPn(n,t,e),a)}function kHn(n,t){var e,i,r,c;for(Wtn(t.b.j),QT(OV(new xq(null,new l1(t.d,16)),new cc),new ac),c=new Ub(t.d);c.an.o.b)return!1;if(e=rbn(n,aCt),t.d+t.a+(e.gc()-1)*r>n.o.b)return!1}return!0}function OHn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;if(a=n.e,o=t.e,0==a)return t;if(0==o)return n;if((c=n.d)+(u=t.d)==2)return e=n0(n.a[0],GQn),i=n0(t.a[0],GQn),a==o?(w=bG(h=ebn(e,i)),0==(b=bG(yz(h,32)))?new z6(a,w):new hU(a,2,Mun(Hk(INt,1),oQn,25,15,[w,b]))):Ygn(a<0?tbn(i,e):tbn(e,i));if(a==o)l=a,f=c>=u?$8(n.a,c,t.a,u):$8(t.a,u,n.a,c);else{if(0==(r=c!=u?c>u?1:-1:Esn(n.a,t.a,c)))return IDn(),net;1==r?(l=a,f=b6(n.a,c,t.a,u)):(l=o,f=b6(t.a,u,n.a,c))}return z0(s=new hU(l,f.length,f)),s}function AHn(n,t,e,r,c,a,u){var o,s,h,f,l,b,w;return l=By(jD(pMn(t,(FXn(),Igt)))),b=null,a==(rin(),Fvt)&&r.c.i==e?b=r.c:a==Bvt&&r.d.i==e&&(b=r.d),(h=u)&&l&&!b?(UB(h.e,r),w=i.Math.max(Hy(ED(pMn(h.d,rgt))),Hy(ED(pMn(r,rgt)))),oon(h.d,rgt,w)):(mUn(),f=MCt,b?f=b.j:gA(_B(pMn(e,npt),98))&&(f=a==Fvt?SCt:aCt),s=LHn(n,t,e,a,f,r),o=U5((gW(e),r)),a==Fvt?(TZ(o,_B(Lq(s.j,0),11)),EZ(o,c)):(TZ(o,c),EZ(o,_B(Lq(s.j,0),11))),h=new qfn(r,o,s,_B(pMn(s,(oWn(),blt)),11),a,!b)),QCn(n.a,r,new A_(h.d,t,a)),h}function $Hn(n,t){var e,i,r,c,a,u,o,s,h,f;if(h=null,n.d&&(h=_B(TY(n.d,t),138)),!h){if(f=(c=n.a.Mh()).i,!n.d||$T(n.d)!=f){for(o=new Lp,n.d&&jcn(o,n.d),u=s=o.f.c+o.g.c;u0?(b=(w-1)*e,u&&(b+=i),h&&(b+=i),b=n.b[r+1])r+=2;else{if(!(e0)for(i=new ZK(_B(o6(n.a,c),21)),TQ(),p$(i,new Rw(t)),r=new E2(c.b,0);r.bk)?(s=2,u=NWn):0==s?(s=1,u=E):(s=0,u=E):(b=E>=u||u-E0?1:qO(isNaN(r),isNaN(0)))>=0^(ein(C3n),(i.Math.abs(o)<=C3n||0==o||isNaN(o)&&isNaN(0)?0:o<0?-1:o>0?1:qO(isNaN(o),isNaN(0)))>=0)?i.Math.max(o,r):(ein(C3n),(i.Math.abs(r)<=C3n||0==r||isNaN(r)&&isNaN(0)?0:r<0?-1:r>0?1:qO(isNaN(r),isNaN(0)))>0?i.Math.sqrt(o*o+r*r):-i.Math.sqrt(o*o+r*r))}function ZHn(n,t){var e,i,r,c,a;if(t)if(!n.a&&(n.a=new Rv),2!=n.e)if(1!=t.e)0!=(a=n.a.a.c.length)?0!=(c=_B(fW(n.a,a-1),117)).e&&10!=c.e||0!=t.e&&10!=t.e?Sv(n.a,t):(0==t.e||t.bm().length,0==c.e?(e=new Mk,(i=c._l())>=_Qn?iO(e,zln(i)):$X(e,i&WVn),c=new gY(10,null,0),mU(n.a,c,a-1)):(c.bm().length,iO(e=new Mk,c.bm())),0==t.e?(i=t._l())>=_Qn?iO(e,zln(i)):$X(e,i&WVn):iO(e,t.bm()),_B(c,521).b=e.a):Sv(n.a,t);else for(r=0;r0&&i>=-6?i>=0?mZ(c,e-SY(n.e),String.fromCharCode(46)):(c.a=sx(c.a,0,t-1)+"0."+YC(c.a,t-1),mZ(c,t+1,_dn(Btt,0,-SY(i)-1))):(e-t>=1&&(mZ(c,t,String.fromCharCode(46)),++e),mZ(c,e,String.fromCharCode(69)),i>0&&mZ(c,++e,String.fromCharCode(43)),mZ(c,++e,""+gz(san(i)))),n.g=c.a,n.g))}function tqn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(!e.dc()){for(a=0,h=0,l=_B((i=e.Kc()).Pb(),19).a;a1&&(o=s.mg(o,n.a,u));return 1==o.c.length?_B(Lq(o,o.c.length-1),220):2==o.c.length?KHn((h1(0,o.c.length),_B(o.c[0],220)),(h1(1,o.c.length),_B(o.c[1],220)),a,c):null}function cqn(n){var t,e,r,c,a,u;for(Itn(n.a,new nt),e=new Ub(n.a);e.a=i.Math.abs(r.b)?(r.b=0,a.d+a.a>u.d&&a.du.c&&a.c0){if(t=new NC(n.i,n.g),c=(e=n.i)<100?null:new Kj(e),n.ij())for(i=0;i0){for(u=n.g,s=n.i,r6(n),c=s<100?null:new Kj(s),i=0;i>13|(15&n.m)<<9,r=n.m>>4&8191,c=n.m>>17|(255&n.h)<<5,a=(1048320&n.h)>>8,g=i*(u=8191&t.l),p=r*u,v=c*u,m=a*u,0!=(o=t.l>>13|(15&t.m)<<9)&&(g+=e*o,p+=i*o,v+=r*o,m+=c*o),0!=(s=t.m>>4&8191)&&(p+=e*s,v+=i*s,m+=r*s),0!=(h=t.m>>17|(255&t.h)<<5)&&(v+=e*h,m+=i*h),0!=(f=(1048320&t.h)>>8)&&(m+=e*f),b=((d=e*u)>>22)+(g>>9)+((262143&p)<<4)+((31&v)<<17),w=(p>>18)+(v>>5)+((4095&m)<<8),w+=(b+=(l=(d&TQn)+((511&g)<<13))>>22)>>22,E$(l&=TQn,b&=TQn,w&=MQn)}function hqn(n){var t,e,r,c,a,u,o;if(0!=(o=_B(Lq(n.j,0),11)).g.c.length&&0!=o.e.c.length)throw Fp(new Ky("Interactive layout does not support NORTH/SOUTH ports with incoming _and_ outgoing edges."));if(0!=o.g.c.length){for(a=xQn,e=new Ub(o.g);e.a4){if(!n.wj(t))return!1;if(n.rk()){if(u=(e=(i=_B(t,49)).Ug())==n.e&&(n.Dk()?i.Og(i.Vg(),n.zk())==n.Ak():-1-i.Vg()==n.aj()),n.Ek()&&!u&&!e&&i.Zg())for(r=0;r0&&(s=n.n.a/c);break;case 2:case 4:(r=n.i.o.b)>0&&(s=n.n.b/r)}oon(n,(oWn(),jlt),s)}if(o=n.o,a=n.a,i)a.a=i.a,a.b=i.b,n.d=!0;else if(t!=WIt&&t!=VIt&&u!=MCt)switch(u.g){case 1:a.a=o.a/2;break;case 2:a.a=o.a,a.b=o.b/2;break;case 3:a.a=o.a/2,a.b=o.b;break;case 4:a.b=o.b/2}else a.a=o.a/2,a.b=o.b/2}function gqn(n){var t,e,i,r,c,a,u,o,s,h;if(n.ej())if(h=n.Vi(),o=n.fj(),h>0)if(t=new ycn(n.Gi()),c=(e=h)<100?null:new Kj(e),QD(n,e,t.g),r=1==e?n.Zi(4,Utn(t,0),null,0,o):n.Zi(6,t,null,-1,o),n.bj()){for(i=new CL(t);i.e!=i.i.gc();)c=n.dj(mpn(i),c);c?(c.Ei(r),c.Fi()):n.$i(r)}else c?(c.Ei(r),c.Fi()):n.$i(r);else QD(n,n.Vi(),n.Wi()),n.$i(n.Zi(6,(TQ(),uet),null,-1,o));else if(n.bj())if((h=n.Vi())>0){for(u=n.Wi(),s=h,QD(n,h,u),c=s<100?null:new Kj(s),i=0;in.d[r.p]&&(e+=Y4(n.b,i)*_B(a.b,19).a,b3(n.a,tln(i)));for(;!Uy(n.a);)Enn(n.b,_B(bU(n.a),19).a)}return e}function mqn(n,t,e,r){var c,a,u,o,s,h,f,l,b,w;for((f=new lA(_B(JAn(n,(TMn(),FMt)),8))).a=i.Math.max(f.a-e.b-e.c,0),f.b=i.Math.max(f.b-e.d-e.a,0),(null==(c=ED(JAn(n,NMt)))||(mW(c),c<=0))&&(c=1.3),u=new $p,l=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));l.e!=l.i.gc();)a=new qx(_B(mpn(l),33)),u.c[u.c.length]=a;switch(_B(JAn(n,xMt),311).g){case 3:w=rFn(u,t,f.a,f.b,(s=r,mW(c),s));break;case 1:w=gBn(u,t,f.a,f.b,(h=r,mW(c),h));break;default:w=Eqn(u,t,f.a,f.b,(o=r,mW(c),o))}DUn(n,(b=vXn(new Htn(w),t,e,f.a,f.b,r,(mW(c),c))).a,b.b,!1,!0)}function yqn(n,t){var e,i,r,c;c=new ZK((e=t.b).j),r=0,(i=e.j).c=L8(Cnt,FWn,1,0,5,1),nX(_B(wan(n.b,(mUn(),uCt),(Srn(),xst)),15),e),r=Qmn(c,r,new xr,i),nX(_B(wan(n.b,uCt,Nst),15),e),r=Qmn(c,r,new Nr,i),nX(_B(wan(n.b,uCt,Lst),15),e),nX(_B(wan(n.b,aCt,xst),15),e),nX(_B(wan(n.b,aCt,Nst),15),e),r=Qmn(c,r,new Dr,i),nX(_B(wan(n.b,aCt,Lst),15),e),nX(_B(wan(n.b,TCt,xst),15),e),r=Qmn(c,r,new Rr,i),nX(_B(wan(n.b,TCt,Nst),15),e),r=Qmn(c,r,new Kr,i),nX(_B(wan(n.b,TCt,Lst),15),e),nX(_B(wan(n.b,SCt,xst),15),e),r=Qmn(c,r,new Qr,i),nX(_B(wan(n.b,SCt,Nst),15),e),nX(_B(wan(n.b,SCt,Lst),15),e)}function kqn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g;for(ITn(t,"Layer size calculation",1),f=xQn,h=DQn,c=!1,o=new Ub(n.b);o.a.5?p-=2*a*(w-.5):w<.5&&(p+=2*c*(.5-w)),p<(r=u.d.b)&&(p=r),d=u.d.c,p>g.a-d-h&&(p=g.a-d-h),u.n.a=t+p}}function Eqn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b;for(u=L8($Nt,BQn,25,n.c.length,15,1),tkn(l=new zz(new Uu),n),s=0,b=new $p;0!=l.b.c.length;)if(a=_B(0==l.b.c.length?null:Lq(l.b,0),157),s>1&&tG(a)*nG(a)/2>u[0]){for(c=0;cu[c];)++c;f=new Htn(new u1(b,0,c+1)),h=tG(a)/nG(a),o=vXn(f,t,new fm,e,i,r,h),GR(mO(f.e),o),K8(nMn(l,f)),tkn(l,new u1(b,c+1,b.c.length)),b.c=L8(Cnt,FWn,1,0,5,1),s=0,yG(u,u.length,0)}else null!=(0==l.b.c.length?null:Lq(l.b,0))&&orn(l,0),s>0&&(u[s]=u[s-1]),u[s]+=tG(a)*nG(a),++s,b.c[b.c.length]=a;return b}function Tqn(n){var t,e,i;if((e=_B(pMn(n,(FXn(),mgt)),163))==(jbn(),Klt)){for(t=new az(JL(sbn(n).a.Kc(),new h));bAn(t);)if(!z5(_B(G5(t),17)))throw Fp(new ek(M1n+wyn(n)+"' has its layer constraint set to FIRST_SEPARATE, but has at least one incoming edge. FIRST_SEPARATE nodes must not have incoming edges."))}else if(e==Flt)for(i=new az(JL(hbn(n).a.Kc(),new h));bAn(i);)if(!z5(_B(G5(i),17)))throw Fp(new ek(M1n+wyn(n)+"' has its layer constraint set to LAST_SEPARATE, but has at least one outgoing edge. LAST_SEPARATE nodes must not have outgoing edges."))}function Mqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b;for(ITn(t,"Label dummy removal",1),i=Hy(ED(pMn(n,(FXn(),ypt)))),r=Hy(ED(pMn(n,Tpt))),o=_B(pMn(n,Gdt),103),u=new Ub(n.b);u.a0&&hPn(n,u,h);for(r=new Ub(h);r.a>19!=0&&(t=ron(t),o=!o),a=ILn(t),c=!1,r=!1,i=!1,n.h==SQn&&0==n.m&&0==n.l){if(r=!0,c=!0,-1!=a)return u=yAn(n,a),o&&Ion(u),e&&(htt=E$(0,0,0)),u;n=UO((z7(),ftt)),i=!0,o=!o}else n.h>>19!=0&&(c=!0,n=ron(n),i=!0,o=!o);return-1!=a?_on(n,a,o,c,e):Dkn(n,t)<0?(e&&(htt=c?ron(n):E$(n.l,n.m,n.h)),E$(0,0,0)):o_n(i?n:E$(n.l,n.m,n.h),t,o,c,r,e)}function Oqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;if(n.e&&n.c.ct.f||t.g>n.f)){for(e=0,i=0,a=n.w.a.ec().Kc();a.Ob();)r=_B(a.Pb(),11),dhn(Con(Mun(Hk(MMt,1),uVn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&++e;for(u=n.r.a.ec().Kc();u.Ob();)r=_B(u.Pb(),11),dhn(Con(Mun(Hk(MMt,1),uVn,8,0,[r.i.n,r.n,r.a])).b,t.g,t.f)&&--e;for(o=t.w.a.ec().Kc();o.Ob();)r=_B(o.Pb(),11),dhn(Con(Mun(Hk(MMt,1),uVn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&++i;for(c=t.r.a.ec().Kc();c.Ob();)r=_B(c.Pb(),11),dhn(Con(Mun(Hk(MMt,1),uVn,8,0,[r.i.n,r.n,r.a])).b,n.g,n.f)&&--i;e=0)return r=bbn(n,t.substr(1,c-1)),VUn(n,t.substr(c+1,u-(c+1)),r)}else{if(e=-1,null==ktt&&(ktt=new RegExp("\\d")),ktt.test(String.fromCharCode(a))&&(e=EK(t,VTn(46),u-1))>=0){i=_B(X5(n,Mtn(n,t.substr(1,e-1)),!1),58),o=0;try{o=h_n(t.substr(e+1),RVn,NWn)}catch(h){throw iL(h=hun(h),127)?Fp(new A7(h)):Fp(h)}if(o=0)return e;switch(NW(_7(n,e))){case 2:if(pK("",Sfn(n,e.Hj()).ne())){if(o=p$n(n,t,u=yV(_7(n,e)),mV(_7(n,e))))return o;for(a=0,s=(r=yKn(n,t)).gc();a1)throw Fp(new Ry(P7n));for(h=rxn(n.e.Tg(),t),i=_B(n.g,119),a=0;a1,h=new p6(b.b);v$(h.a)||v$(h.b);)l=(s=_B(v$(h.a)?Y1(h.a):Y1(h.b),17)).c==b?s.d:s.c,i.Math.abs(Con(Mun(Hk(MMt,1),uVn,8,0,[l.i.n,l.n,l.a])).b-u.b)>1&&dxn(n,s,u,a,b)}}function qqn(n){var t,e,r,c,a,u;if(c=new E2(n.e,0),r=new E2(n.a,0),n.d)for(e=0;eN3n;){for(a=t,u=0;i.Math.abs(t-a)0),c.a.Xb(c.c=--c.b),NFn(n,n.b-u,a,r,c),Mx(c.b0),r.a.Xb(r.c=--r.b)}if(!n.d)for(e=0;e0?(n.f[s.p]=l/(s.e.c.length+s.g.c.length),n.c=i.Math.min(n.c,n.f[s.p]),n.b=i.Math.max(n.b,n.f[s.p])):u&&(n.f[s.p]=l)}}function Uqn(n){n.b=null,n.bb=null,n.fb=null,n.qb=null,n.a=null,n.c=null,n.d=null,n.e=null,n.f=null,n.n=null,n.M=null,n.L=null,n.Q=null,n.R=null,n.K=null,n.db=null,n.eb=null,n.g=null,n.i=null,n.j=null,n.k=null,n.gb=null,n.o=null,n.p=null,n.q=null,n.r=null,n.$=null,n.ib=null,n.S=null,n.T=null,n.t=null,n.s=null,n.u=null,n.v=null,n.w=null,n.B=null,n.A=null,n.C=null,n.D=null,n.F=null,n.G=null,n.H=null,n.I=null,n.J=null,n.P=null,n.Z=null,n.U=null,n.V=null,n.W=null,n.X=null,n.Y=null,n._=null,n.ab=null,n.cb=null,n.hb=null,n.nb=null,n.lb=null,n.mb=null,n.ob=null,n.pb=null,n.jb=null,n.kb=null,n.N=!1,n.O=!1}function Xqn(n,t,e){var i,r;for(ITn(e,"Graph transformation ("+n.a+")",1),r=r0(t.a),i=new Ub(t.b);i.a0&&(n.a=u+(l-1)*r,t.c.b+=n.a,t.f.b+=n.a),0!=b.a.gc()&&(l=CGn(new sX(1,r),t,b,w,t.f.b+u-t.c.b))>0&&(t.f.b+=u+(l-1)*r)}function Vqn(n,t){var e,i,r,c;c=n.F,null==t?(n.F=null,Nsn(n,null)):(n.F=(mW(t),t),-1!=(i=HO(t,VTn(60)))?(r=t.substr(0,i),-1==HO(t,VTn(46))&&!pK(r,OWn)&&!pK(r,T9n)&&!pK(r,M9n)&&!pK(r,S9n)&&!pK(r,P9n)&&!pK(r,I9n)&&!pK(r,C9n)&&!pK(r,O9n)&&(r=A9n),-1!=(e=pN(t,VTn(62)))&&(r+=""+t.substr(e+1)),Nsn(n,r)):(r=t,-1==HO(t,VTn(46))&&(-1!=(i=HO(t,VTn(91)))&&(r=t.substr(0,i)),pK(r,OWn)||pK(r,T9n)||pK(r,M9n)||pK(r,S9n)||pK(r,P9n)||pK(r,I9n)||pK(r,C9n)||pK(r,O9n)?r=t:(r=A9n,-1!=i&&(r+=""+t.substr(i)))),Nsn(n,r),r==t&&(n.F=n.D))),0!=(4&n.Db)&&0==(1&n.Db)&&fan(n,new Yz(n,1,5,c,t))}function Qqn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;if(!((d=t.b.c.length)<3)){for(b=L8(INt,oQn,25,d,15,1),f=0,h=new Ub(t.b);h.aa)&&jU(n.b,_B(g.b,17));++u}c=a}}}function Jqn(n,t){var e;if(null==t||pK(t,qWn))return null;if(0==t.length&&n.k!=(MPn(),dMt))return null;switch(n.k.g){case 1:return pgn(t,r5n)?(oN(),gtt):pgn(t,c5n)?(oN(),dtt):null;case 2:try{return tln(h_n(t,RVn,NWn))}catch(i){if(iL(i=hun(i),127))return null;throw Fp(i)}case 4:try{return fSn(t)}catch(i){if(iL(i=hun(i),127))return null;throw Fp(i)}case 3:return t;case 5:return ehn(n),FCn(n,t);case 6:return ehn(n),D$n(n,n.a,t);case 7:try{return(e=eAn(n)).Jf(t),e}catch(i){if(iL(i=hun(i),32))return null;throw Fp(i)}default:throw Fp(new Ky("Invalid type set for this layout option."))}}function Yqn(n){var t,e,i,r,c,a,u;for(Nnn(),u=new Xv,e=new Ub(n);e.a=u.b.c)&&(u.b=t),(!u.c||t.c<=u.c.c)&&(u.d=u.c,u.c=t),(!u.e||t.d>=u.e.d)&&(u.e=t),(!u.f||t.d<=u.f.d)&&(u.f=t);return i=new jpn((Cun(),Jat)),t2(n,aut,new Qy(Mun(Hk(Qat,1),FWn,369,0,[i]))),a=new jpn(nut),t2(n,cut,new Qy(Mun(Hk(Qat,1),FWn,369,0,[a]))),r=new jpn(Yat),t2(n,rut,new Qy(Mun(Hk(Qat,1),FWn,369,0,[r]))),c=new jpn(Zat),t2(n,iut,new Qy(Mun(Hk(Qat,1),FWn,369,0,[c]))),LLn(i.c,Jat),LLn(r.c,Yat),LLn(c.c,Zat),LLn(a.c,nut),u.a.c=L8(Cnt,FWn,1,0,5,1),wun(u.a,i.c),wun(u.a,nan(r.c)),wun(u.a,c.c),wun(u.a,nan(a.c)),u}function Zqn(n){var t;switch(n.d){case 1:if(n.hj())return-2!=n.o;break;case 2:if(n.hj())return-2==n.o;break;case 3:case 5:case 4:case 6:case 7:return n.o>-2;default:return!1}switch(t=n.gj(),n.p){case 0:return null!=t&&By(jD(t))!=QC(n.k,0);case 1:return null!=t&&_B(t,217).a!=bG(n.k)<<24>>24;case 2:return null!=t&&_B(t,172).a!=(bG(n.k)&WVn);case 6:return null!=t&&QC(_B(t,162).a,n.k);case 5:return null!=t&&_B(t,19).a!=bG(n.k);case 7:return null!=t&&_B(t,184).a!=bG(n.k)<<16>>16;case 3:return null!=t&&Hy(ED(t))!=n.j;case 4:return null!=t&&_B(t,155).a!=n.j;default:return null==t?null!=n.n:!$fn(t,n.n)}}function nGn(n,t,e){var i,r,c,a;return n.Fk()&&n.Ek()&&HC(a=Hz(n,_B(e,56)))!==HC(e)?(n.Oi(t),n.Ui(t,_9(n,t,a)),n.rk()&&(r=_B(e,49),c=n.Dk()?n.Bk()?r.ih(n.b,Svn(_B(ttn(yJ(n.b),n.aj()),18)).n,_B(ttn(yJ(n.b),n.aj()).Yj(),26).Bj(),null):r.ih(n.b,Cwn(r.Tg(),Svn(_B(ttn(yJ(n.b),n.aj()),18))),null,null):r.ih(n.b,-1-n.aj(),null,null),!_B(a,49).eh()&&(i=_B(a,49),c=n.Dk()?n.Bk()?i.gh(n.b,Svn(_B(ttn(yJ(n.b),n.aj()),18)).n,_B(ttn(yJ(n.b),n.aj()).Yj(),26).Bj(),c):i.gh(n.b,Cwn(i.Tg(),Svn(_B(ttn(yJ(n.b),n.aj()),18))),null,c):i.gh(n.b,-1-n.aj(),null,c)),c&&c.Fi()),pA(n.b)&&n.$i(n.Zi(9,e,a,t,!1)),a):e}function tGn(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(f=Hy(ED(pMn(n,(FXn(),kpt)))),r=Hy(ED(pMn(n,xpt))),oon(b=new Ju,kpt,f+r),v=(h=t).d,g=h.c.i,m=h.d.i,p=ZO(g.c),y=ZO(m.c),c=new $p,l=p;l<=y;l++)_l(o=new Ovn(n),(cSn(),Mut)),oon(o,(oWn(),blt),h),oon(o,npt,(WEn(),zIt)),oon(o,Ept,b),w=_B(Lq(n.b,l),29),l==p?Wyn(o,w.a.c.length-e,w):MZ(o,w),(k=Hy(ED(pMn(h,rgt))))<0&&oon(h,rgt,k=0),o.o.b=k,d=i.Math.floor(k/2),BIn(u=new SSn,(mUn(),SCt)),SZ(u,o),u.n.b=d,BIn(s=new SSn,aCt),SZ(s,o),s.n.b=d,EZ(h,u),Ban(a=new lJ,h),oon(a,ggt,null),TZ(a,s),EZ(a,v),qkn(o,h,a),c.c[c.c.length]=a,h=a;return c}function eGn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(u=_B(NSn(n,(mUn(),SCt)).Kc().Pb(),11).e,f=_B(NSn(n,aCt).Kc().Pb(),11).g,a=u.c.length,g=w1(_B(Lq(n.j,0),11));a-- >0;){for(h1(0,u.c.length),b=_B(u.c[0],17),h1(0,f.c.length),r=k7((i=_B(f.c[0],17)).d.e,i,0),C2(b,i.d,r),TZ(i,null),EZ(i,null),l=b.a,t&&NH(l,new lA(g)),e=upn(i.a,0);e.b!=e.d.c;)NH(l,new lA(_B(f3(e),8)));for(d=b.b,h=new Ub(i.b);h.a0&&(u=i.Math.max(u,hcn(n.C.b+r.d.b,c))),f=r,l=c,b=a;n.C&&n.C.c>0&&(w=b+n.C.c,h&&(w+=f.d.c),u=i.Math.max(u,(o$(),ein(sYn),i.Math.abs(l-1)<=sYn||1==l||isNaN(l)&&isNaN(1)?0:w/(1-l)))),e.n.b=0,e.a.a=u}function rGn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w;if(e=_B(aV(n.b,t),124),(s=_B(_B(o6(n.r,t),21),84)).dc())return e.n.d=0,void(e.n.a=0);for(h=n.u.Hc((hCn(),nCt)),u=0,n.A.Hc((pdn(),RCt))&&mRn(n,t),o=s.Kc(),f=null,b=0,l=0;o.Ob();)a=Hy(ED((r=_B(o.Pb(),111)).b.We((NN(),Art)))),c=r.b.rf().b,f?(w=l+f.d.a+n.w+r.d.d,u=i.Math.max(u,(o$(),ein(sYn),i.Math.abs(b-a)<=sYn||b==a||isNaN(b)&&isNaN(a)?0:w/(a-b)))):n.C&&n.C.d>0&&(u=i.Math.max(u,hcn(n.C.d+r.d.d,a))),f=r,b=a,l=c;n.C&&n.C.a>0&&(w=l+n.C.a,h&&(w+=f.d.a),u=i.Math.max(u,(o$(),ein(sYn),i.Math.abs(b-1)<=sYn||1==b||isNaN(b)&&isNaN(1)?0:w/(1-b)))),e.n.d=0,e.a.b=u}function cGn(n,t,e){var i,r,c,a,u,o;for(this.g=n,u=t.d.length,o=e.d.length,this.d=L8(Iut,r1n,10,u+o,0,1),a=0;a0?Qtn(this,this.f/this.a):null!=hL(t.g,t.d[0]).a&&null!=hL(e.g,e.d[0]).a?Qtn(this,(Hy(hL(t.g,t.d[0]).a)+Hy(hL(e.g,e.d[0]).a))/2):null!=hL(t.g,t.d[0]).a?Qtn(this,hL(t.g,t.d[0]).a):null!=hL(e.g,e.d[0]).a&&Qtn(this,hL(e.g,e.d[0]).a)}function aGn(n,t){var e,i,r,c,a,u,o,s,h;for(n.a=new _X(Ocn(UPt)),i=new Ub(t.a);i.a=1&&(g-a>0&&f>=0?(o.n.a+=d,o.n.b+=c*a):g-a<0&&h>=0&&(o.n.a+=d*g,o.n.b+=c));n.o.a=t.a,n.o.b=t.b,oon(n,(FXn(),Kgt),(pdn(),new VK(i=_B(Xj(VCt),9),_B(TR(i,i.length),9),0)))}function lGn(n,t,e,i,r,c){if(null!=t&&zbn(t,IAt,CAt))throw Fp(new Ry("invalid scheme: "+t));if(!(n||null!=e&&-1==HO(e,VTn(35))&&e.length>0&&(f1(0,e.length),47!=e.charCodeAt(0))))throw Fp(new Ry("invalid opaquePart: "+e));if(n&&(null==t||!LT(mAt,t.toLowerCase()))&&null!=e&&zbn(e,OAt,AAt))throw Fp(new Ry(a9n+e));if(n&&null!=t&<(mAt,t.toLowerCase())&&!SEn(e))throw Fp(new Ry(a9n+e));if(!Gbn(i))throw Fp(new Ry("invalid device: "+i));if(!xhn(r))throw Fp(new Ry(null==r?"invalid segments: null":"invalid segment: "+uhn(r)));if(null!=c&&-1!=HO(c,VTn(35)))throw Fp(new Ry("invalid query: "+c))}function bGn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(ITn(t,"Calculate Graph Size",1),t.n&&n&&v0(t,a2(n),(_sn(),cOt)),o=JYn,s=JYn,a=Y3n,u=Y3n,l=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));l.e!=l.i.gc();)d=(h=_B(mpn(l),33)).i,g=h.j,v=h.g,r=h.f,c=_B(JAn(h,(uWn(),OSt)),142),o=i.Math.min(o,d-c.b),s=i.Math.min(s,g-c.d),a=i.Math.max(a,d+v+c.c),u=i.Math.max(u,g+r+c.a);for(b=new LI(o-(w=_B(JAn(n,(uWn(),zSt)),116)).b,s-w.d),f=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));f.e!=f.i.gc();)Men(h=_B(mpn(f),33),h.i-b.a),Sen(h,h.j-b.b);p=a-o+(w.b+w.c),e=u-s+(w.d+w.a),Ten(n,p),Een(n,e),t.n&&n&&v0(t,a2(n),(_sn(),cOt))}function wGn(n){var t,e,i,r,c,a,u,o,s,h;for(i=new $p,a=new Ub(n.e.a);a.a0?(Mpn(n,e,0),e.a+=String.fromCharCode(i),Mpn(n,e,r=ign(t,c)),c+=r-1):39==i?c+11)for(d=L8(INt,oQn,25,n.b.b.c.length,15,1),f=0,h=new Ub(n.b.b);h.a=u&&r<=o)u<=r&&c<=o?(e[h++]=r,e[h++]=c,i+=2):u<=r?(e[h++]=r,e[h++]=o,n.b[i]=o+1,a+=2):c<=o?(e[h++]=u,e[h++]=c,i+=2):(e[h++]=u,e[h++]=o,n.b[i]=o+1);else{if(!(oDVn)&&o<10);Zk(n.c,new Et),vGn(n),PU(n.c),sGn(n.f)}function kGn(n,t,e){var i,r,c,a,u,o,s,h,f,l;if(By(jD(pMn(e,(FXn(),lgt)))))for(r=new Ub(e.j);r.a=2){for(a=_B(f3(o=upn(e,0)),8),u=_B(f3(o),8);u.a0&&Gun(o,!0,(Kfn(),KPt)),a.k==(cSn(),Eut)&&lV(o),XW(n.f,a,t)):((s=(i=_B(tJ(obn(a)),17)).c.i)==a&&(s=i.d.i),f=new eC(s,zR(_$(a.n),s.n)),XW(n.b,a,f))}function MGn(n,t,e){var r,c,a,u,o,s,h,f;switch(ITn(e,"Node promotion heuristic",1),n.g=t,vUn(n),n.q=_B(pMn(t,(FXn(),Tgt)),260),f=_B(pMn(n.g,Egt),19).a,a=new hi,n.q.g){case 2:case 1:RHn(n,a);break;case 3:for(n.q=(uNn(),Ivt),RHn(n,a),s=0,o=new Ub(n.a);o.an.j&&(n.q=jvt,RHn(n,a));break;case 4:for(n.q=(uNn(),Ivt),RHn(n,a),h=0,c=new Ub(n.b);c.an.k&&(n.q=Mvt,RHn(n,a));break;case 6:RHn(n,new ad(SY(i.Math.ceil(n.f.length*f/100))));break;case 5:RHn(n,new ud(SY(i.Math.ceil(n.d*f/100))));break;default:RHn(n,a)}aDn(n,t),FSn(e)}function SGn(n,t,e){var i,r,c,a;this.j=n,this.e=BEn(n),this.o=this.j.e,this.i=!!this.o,this.p=this.i?_B(Lq(e,gW(this.o).p),214):null,r=_B(pMn(n,(oWn(),Jft)),21),this.g=r.Hc((fDn(),hft)),this.b=new $p,this.d=new ldn(this.e),a=_B(pMn(this.j,Tlt),230),this.q=Fan(t,a,this.e),this.k=new rZ(this),c=c6(Mun(Hk(yst,1),FWn,225,0,[this,this.d,this.k,this.q])),t!=(ain(),Imt)||By(jD(pMn(n,(FXn(),Ldt))))?t==Imt&&By(jD(pMn(n,(FXn(),Ldt))))?(i=new GEn(this.e),c.c[c.c.length]=i,this.c=new drn(i,a,_B(this.q,402))):this.c=new gP(t,this):(i=new GEn(this.e),c.c[c.c.length]=i,this.c=new H2(i,a,_B(this.q,402))),UB(c,this.c),SHn(c,this.e),this.s=lXn(this.k)}function PGn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;for(l=(s=_B(tL(new lg(upn(new fg(t).a.d,0))),86))?_B(pMn(s,(Bqn(),ikt)),86):null,r=1;s&&l;){for(a=0,v=0,e=s,i=l,c=0;c=n.i?(++n.i,UB(n.a,tln(1)),UB(n.b,s)):(i=n.c[t.p][1],i5(n.a,o,tln(_B(Lq(n.a,o),19).a+1-i)),i5(n.b,o,Hy(ED(Lq(n.b,o)))+s-i*n.e)),(n.q==(uNn(),jvt)&&(_B(Lq(n.a,o),19).a>n.j||_B(Lq(n.a,o-1),19).a>n.j)||n.q==Mvt&&(Hy(ED(Lq(n.b,o)))>n.k||Hy(ED(Lq(n.b,o-1)))>n.k))&&(u=!1),c=new az(JL(sbn(t).a.Kc(),new h));bAn(c);)a=_B(G5(c),17).c.i,n.f[a.p]==o&&(r+=_B((f=IGn(n,a)).a,19).a,u=u&&By(jD(f.b)));return n.f[t.p]=o,new eC(tln(r+=n.c[t.p][0]),(oN(),!!u))}function CGn(n,t,e,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v;for(l=new Lp,u=new $p,eCn(n,e,n.d.fg(),u,l),eCn(n,r,n.d.gg(),u,l),n.b=.2*(g=_An(lnn(new xq(null,new l1(u,16)),new Sa)),p=_An(lnn(new xq(null,new l1(u,16)),new Pa)),i.Math.min(g,p)),a=0,o=0;o=2&&(v=WLn(u,!0,b),!n.e&&(n.e=new hg(n)),ugn(n.e,v,u,n.b)),tTn(u,b),izn(u),w=-1,f=new Ub(u);f.au)}function $Gn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g;for(e=_B(pMn(n,(FXn(),npt)),98),u=n.f,a=n.d,o=u.a+a.b+a.c,s=0-a.d-n.c.b,f=u.b+a.d+a.a-n.c.b,h=new $p,l=new $p,c=new Ub(t);c.a0),c=_B(s.a.Xb(s.c=--s.b),17);c!=i&&s.b>0;)n.a[c.p]=!0,n.a[i.p]=!0,Mx(s.b>0),c=_B(s.a.Xb(s.c=--s.b),17);s.b>0&&sW(s)}}function BGn(n,t,e){var i,r,c,a,u,o,s,h,f;if(n.a!=t.Aj())throw Fp(new Ry(b6n+t.ne()+w6n));if(i=Sfn((PPn(),Q$t),t).$k())return i.Aj().Nh().Ih(i,e);if(a=Sfn(Q$t,t).al()){if(null==e)return null;if((u=_B(e,15)).dc())return"";for(f=new Tk,c=u.Kc();c.Ob();)r=c.Pb(),iO(f,a.Aj().Nh().Ih(a,r)),f.a+=" ";return DO(f,f.a.length-1)}if(!(h=Sfn(Q$t,t).bl()).dc()){for(s=h.Kc();s.Ob();)if((o=_B(s.Pb(),148)).wj(e))try{if(null!=(f=o.Aj().Nh().Ih(o,e)))return f}catch(l){if(!iL(l=hun(l),102))throw Fp(l)}throw Fp(new Ry("Invalid value: '"+e+"' for datatype :"+t.ne()))}return _B(t,834).Fj(),null==e?null:iL(e,172)?""+_B(e,172).a:Zon(e)==ptt?F$(POt[0],_B(e,199)):_bn(e)}function HGn(n){var t,e,r,c,a,u,o,s,h;for(s=new VT,u=new VT,c=new Ub(n);c.a-1){for(r=upn(u,0);r.b!=r.d.c;)(e=_B(f3(r),128)).v=a;for(;0!=u.b;)for(t=new Ub((e=_B(Zyn(u,0),128)).i);t.a0&&(e+=o.n.a+o.o.a/2,++f),b=new Ub(o.j);b.a0&&(e/=f),g=L8($Nt,BQn,25,i.a.c.length,15,1),u=0,s=new Ub(i.a);s.a=u&&r<=o)u<=r&&c<=o?i+=2:u<=r?(n.b[i]=o+1,a+=2):c<=o?(e[h++]=r,e[h++]=u-1,i+=2):(e[h++]=r,e[h++]=u-1,n.b[i]=o+1,a+=2);else{if(!(o0?r-=864e5:r+=864e5,o=new MD(ebn(san(t.q.getTime()),r))),h=new Pk,s=n.a.length,c=0;c=97&&i<=122||i>=65&&i<=90){for(a=c+1;a=s)throw Fp(new Ry("Missing trailing '"));a+10&&0==e.c&&(!t&&(t=new $p),t.c[t.c.length]=e);if(t)for(;0!=t.c.length;){if((e=_B(u6(t,0),233)).b&&e.b.c.length>0)for(!e.b&&(e.b=new $p),c=new Ub(e.b);c.ak7(n,e,0))return new eC(r,e)}else if(Hy(hL(r.g,r.d[0]).a)>Hy(hL(e.g,e.d[0]).a))return new eC(r,e);for(u=(!e.e&&(e.e=new $p),e.e).Kc();u.Ob();)!(a=_B(u.Pb(),233)).b&&(a.b=new $p),AZ(0,(o=a.b).c.length),ES(o.c,0,e),a.c==o.c.length&&(t.c[t.c.length]=a)}return null}function tzn(n,t){var e,i,r,c,a,u;if(null==n)return qWn;if(null!=t.a.zc(n,t))return"[...]";for(e=new Oan(KWn,"[","]"),c=0,a=(r=n).length;c=14&&u<=16?iL(i,177)?f6(e,xIn(_B(i,177))):iL(i,190)?f6(e,QEn(_B(i,190))):iL(i,195)?f6(e,mSn(_B(i,195))):iL(i,2012)?f6(e,JEn(_B(i,2012))):iL(i,48)?f6(e,NIn(_B(i,48))):iL(i,364)?f6(e,wCn(_B(i,364))):iL(i,832)?f6(e,LIn(_B(i,832))):iL(i,104)&&f6(e,$In(_B(i,104))):t.a._b(i)?(e.a?aO(e.a,e.b):e.a=new hN(e.d),rO(e.a,"[...]")):f6(e,tzn(nen(i),new Oq(t))):f6(e,null==i?qWn:_bn(i));return e.a?0==e.e.length?e.a.a:e.a.a+""+e.e:e.c}function ezn(n,t,e,r){var c,a,u,o,s,h,f,l,b,w,d,g;for(w=BSn(iDn(t,!1,!1)),r&&(w=Qon(w)),g=Hy(ED(JAn(t,(kpn(),dct)))),Mx(0!=w.b),b=_B(w.a.a.c,8),h=_B(Npn(w,1),8),w.b>2?(wun(s=new $p,new u1(w,1,w.b)),Ban(d=new kAn(zXn(s,g+n.a)),t),e.c[e.c.length]=d):d=_B(xX(n.b,r?MMn(t):IMn(t)),266),u=MMn(t),r&&(u=IMn(t)),a=tPn(b,u),o=g+n.a,a.a?(o+=i.Math.abs(b.b-h.b),l=new LI(h.a,(h.b+b.b)/2)):(o+=i.Math.abs(b.a-h.a),l=new LI((h.a+b.a)/2,h.b)),XW(r?n.d:n.c,t,new Pmn(d,a,l,o)),XW(n.b,t,d),!t.n&&(t.n=new nU(HOt,t,1,7)),f=new CL(t.n);f.e!=f.i.gc();)c=QRn(n,_B(mpn(f),137),!0,0,0),e.c[e.c.length]=c}function izn(n){var t,e,r,c,a,u,o,s,h;for(s=new $p,u=new $p,a=new Ub(n);a.a-1){for(c=new Ub(u);c.a0||(Vl(o,i.Math.min(o.o,r.o-1)),Wl(o,o.i-1),0==o.i&&(u.c[u.c.length]=o))}}function rzn(n,t,e){var i,r,c,a,u;if(u=n.c,!t&&(t=O$t),n.c=t,0!=(4&n.Db)&&0==(1&n.Db)&&(a=new Yz(n,1,2,u,n.c),e?e.Ei(a):e=a),u!=t)if(iL(n.Cb,284))n.Db>>16==-10?e=_B(n.Cb,284).nk(t,e):n.Db>>16==-15&&(!t&&(wWn(),t=s$t),!u&&(wWn(),u=s$t),n.Cb.nh()&&(a=new $7(n.Cb,1,13,u,t,cvn(F7(_B(n.Cb,59)),n),!1),e?e.Ei(a):e=a));else if(iL(n.Cb,88))n.Db>>16==-23&&(iL(t,88)||(wWn(),t=l$t),iL(u,88)||(wWn(),u=l$t),n.Cb.nh()&&(a=new $7(n.Cb,1,10,u,t,cvn(r4(_B(n.Cb,26)),n),!1),e?e.Ei(a):e=a));else if(iL(n.Cb,444))for(!(c=_B(n.Cb,836)).b&&(c.b=new jp(new Lm)),r=new Ep(new csn(new Mb(c.b.a).a));r.a.b;)e=rzn(i=_B(Ztn(r.a).cd(),87),mLn(i,c),e);return e}function czn(n,t){var e,i,r,c,a,u,o,s,h,f,l;for(a=By(jD(JAn(n,(FXn(),lgt)))),l=_B(JAn(n,ipt),21),o=!1,s=!1,f=new CL((!n.c&&(n.c=new nU(GOt,n,9,9)),n.c));!(f.e==f.i.gc()||o&&s);){for(c=_B(mpn(f),118),u=0,r=$U(Uen(Mun(Hk(Lnt,1),FWn,20,0,[(!c.d&&(c.d=new oK(DOt,c,8,5)),c.d),(!c.e&&(c.e=new oK(DOt,c,7,4)),c.e)])));bAn(r)&&(i=_B(G5(r),79),h=a&&WCn(i)&&By(jD(JAn(i,bgt))),e=fqn((!i.b&&(i.b=new oK(xOt,i,4,7)),i.b),c)?n==QY(MTn(_B(Utn((!i.c&&(i.c=new oK(xOt,i,5,8)),i.c),0),82))):n==QY(MTn(_B(Utn((!i.b&&(i.b=new oK(xOt,i,4,7)),i.b),0),82))),!((h||e)&&++u>1)););(u>0||l.Hc((hCn(),nCt))&&(!c.n&&(c.n=new nU(HOt,c,1,7)),c.n).i>0)&&(o=!0),u>1&&(s=!0)}o&&t.Fc((fDn(),hft)),s&&t.Fc((fDn(),fft))}function azn(n){var t,e,r,c,a,u,o,s,h,f,l,b;if((b=_B(JAn(n,(uWn(),DSt)),21)).dc())return null;if(o=0,u=0,b.Hc((pdn(),DCt))){for(f=_B(JAn(n,cPt),98),r=2,e=2,c=2,a=2,t=QY(n)?_B(JAn(QY(n),fSt),103):_B(JAn(n,fSt),103),h=new CL((!n.c&&(n.c=new nU(GOt,n,9,9)),n.c));h.e!=h.i.gc();)if(s=_B(mpn(h),118),(l=_B(JAn(s,lPt),61))==(mUn(),MCt)&&(l=IFn(s,t),Vpn(s,lPt,l)),f==(WEn(),zIt))switch(l.g){case 1:r=i.Math.max(r,s.i+s.g);break;case 2:e=i.Math.max(e,s.j+s.f);break;case 3:c=i.Math.max(c,s.i+s.g);break;case 4:a=i.Math.max(a,s.j+s.f)}else switch(l.g){case 1:r+=s.g+2;break;case 2:e+=s.f+2;break;case 3:c+=s.g+2;break;case 4:a+=s.f+2}o=i.Math.max(r,c),u=i.Math.max(e,a)}return DUn(n,o,u,!0,!0)}function uzn(n,t,e,r,c){var a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(m=_B(M4(vtn(CV(new xq(null,new l1(t.d,16)),new Od(e)),new Ad(e)),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),Get)]))),15),l=NWn,f=RVn,s=new Ub(t.b.j);s.a0)?s&&(h=d.p,a?++h:--h,f=!(iNn(i=ton(_B(Lq(d.c.a,h),10)),y,e[0])||_z(i,y,e[0]))):f=!0),l=!1,(m=t.D.i)&&m.c&&u.e&&(a&&m.p>0||!a&&m.p0&&(t.a+=KWn),wzn(_B(mpn(a),160),t);for(t.a+=n1n,u=new ix((!i.c&&(i.c=new oK(xOt,i,5,8)),i.c));u.e!=u.i.gc();)u.e>0&&(t.a+=KWn),wzn(_B(mpn(u),160),t);t.a+=")"}}}function dzn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(c=_B(pMn(n,(oWn(),blt)),79)){for(i=n.a,GR(r=new lA(e),Ojn(n)),lan(n.d.i,n.c.i)?(l=n.c,zR(f=Con(Mun(Hk(MMt,1),uVn,8,0,[l.n,l.a])),e)):f=w1(n.c),e5(i,f,i.a,i.a.a),b=w1(n.d),null!=pMn(n,xlt)&&GR(b,_B(pMn(n,xlt),8)),e5(i,b,i.c.b,i.c),Jtn(i,r),Ain(a=iDn(c,!0,!0),_B(Utn((!c.b&&(c.b=new oK(xOt,c,4,7)),c.b),0),82)),$in(a,_B(Utn((!c.c&&(c.c=new oK(xOt,c,5,8)),c.c),0),82)),XFn(i,a),h=new Ub(n.b);h.a=0){for(o=null,u=new E2(h.a,s+1);u.ba?1:qO(isNaN(0),isNaN(a)))<0&&(ein(C3n),(i.Math.abs(a-1)<=C3n||1==a||isNaN(a)&&isNaN(1)?0:a<1?-1:a>1?1:qO(isNaN(a),isNaN(1)))<0)&&(ein(C3n),(i.Math.abs(0-u)<=C3n||0==u||isNaN(0)&&isNaN(u)?0:0u?1:qO(isNaN(0),isNaN(u)))<0)&&(ein(C3n),(i.Math.abs(u-1)<=C3n||1==u||isNaN(u)&&isNaN(1)?0:u<1?-1:u>1?1:qO(isNaN(u),isNaN(1)))<0))}function vzn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j;for(f=new oW(new tw(n));f.b!=f.c.a.d;)for(u=_B((h=u9(f)).d,56),t=_B(h.e,56),d=0,y=(null==(a=u.Tg()).i&&BFn(a),a.i).length;d=0&&d=s.c.c.length?z3((cSn(),Sut),Mut):z3((cSn(),Mut),Mut),h*=2,c=e.a.g,e.a.g=i.Math.max(c,c+(h-c)),a=e.b.g,e.b.g=i.Math.max(a,a+(h-a)),r=t}else qAn(u),CHn((h1(0,u.c.length),_B(u.c[0],17)).d.i)||UB(n.o,u)}function kzn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(m=HB(n),o=new $p,s=(c=n.c.length)-1,h=c+1;0!=m.a.c;){for(;0!=e.b;)Mx(0!=e.b),p=_B(Ctn(e,e.a.a),112),OY(m.a,p),p.g=s--,$Fn(p,t,e,i);for(;0!=t.b;)Mx(0!=t.b),v=_B(Ctn(t,t.a.a),112),OY(m.a,v),v.g=h++,$Fn(v,t,e,i);for(u=RVn,d=new Kb(new _R(new LN(new Rb(m.a).a).b));rS(d.a.a);){if(w=_B(px(d.a).cd(),112),!i&&w.b>0&&w.a<=0){o.c=L8(Cnt,FWn,1,0,5,1),o.c[o.c.length]=w;break}(b=w.i-w.d)>=u&&(b>u&&(o.c=L8(Cnt,FWn,1,0,5,1),u=b),o.c[o.c.length]=w)}0!=o.c.length&&(a=_B(Lq(o,dvn(r,o.c.length)),112),OY(m.a,a),a.g=h++,$Fn(a,t,e,i),o.c=L8(Cnt,FWn,1,0,5,1))}for(g=n.c.length+1,l=new Ub(n);l.a0&&(b.d+=f.n.d,b.d+=f.d),b.a>0&&(b.a+=f.n.a,b.a+=f.d),b.b>0&&(b.b+=f.n.b,b.b+=f.d),b.c>0&&(b.c+=f.n.c,b.c+=f.d),b}function Szn(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d;for(b=e.d,l=e.c,u=(a=new LI(e.f.a+e.d.b+e.d.c,e.f.b+e.d.d+e.d.a)).b,h=new Ub(n.a);h.a0&&(n.c[t.c.p][t.p].d+=F$n(n.i,24)*cJn*.07000000029802322-.03500000014901161,n.c[t.c.p][t.p].a=n.c[t.c.p][t.p].d/n.c[t.c.p][t.p].b)}}function Nzn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w;for(l=new Ub(n);l.ar.d,r.d=i.Math.max(r.d,t),o&&e&&(r.d=i.Math.max(r.d,r.a),r.a=r.d+c);break;case 3:e=t>r.a,r.a=i.Math.max(r.a,t),o&&e&&(r.a=i.Math.max(r.a,r.d),r.d=r.a+c);break;case 2:e=t>r.c,r.c=i.Math.max(r.c,t),o&&e&&(r.c=i.Math.max(r.b,r.c),r.b=r.c+c);break;case 4:e=t>r.b,r.b=i.Math.max(r.b,t),o&&e&&(r.b=i.Math.max(r.b,r.c),r.c=r.b+c)}}}function Kzn(n){var t,e,i,r,c,a,u,o,s,h,f;for(s=new Ub(n);s.a0||h.j==SCt&&h.e.c.length-h.g.c.length<0)){t=!1;break}for(r=new Ub(h.g);r.a=h&&j>=p&&(b+=d.n.b+g.n.b+g.a.b-k,++o));if(e)for(u=new Ub(m.e);u.a=h&&j>=p&&(b+=d.n.b+g.n.b+g.a.b-k,++o))}o>0&&(E+=b/o,++w)}w>0?(t.a=c*E/w,t.g=w):(t.a=0,t.g=0)}function Fzn(n,t){var e,i,r,c,a,u,o,s,h,f;for(i=new Ub(n.a.b);i.aDQn||t.o==eyt&&s0&&Men(p,y*j),k>0&&Sen(p,k*E);for(Ycn(n.b,new lt),t=new $p,u=new csn(new Mb(n.c).a);u.b;)i=_B((a=Ztn(u)).cd(),79),e=_B(a.dd(),395).a,r=iDn(i,!1,!1),XFn(f=hTn(MMn(i),BSn(r),e),r),(m=SMn(i))&&-1==k7(t,m,0)&&(t.c[t.c.length]=m,uQ(m,(Mx(0!=f.b),_B(f.a.a.c,8)),e));for(g=new csn(new Mb(n.d).a);g.b;)i=_B((d=Ztn(g)).cd(),79),e=_B(d.dd(),395).a,r=iDn(i,!1,!1),f=hTn(IMn(i),Qon(BSn(r)),e),XFn(f=Qon(f),r),(m=PMn(i))&&-1==k7(t,m,0)&&(t.c[t.c.length]=m,uQ(m,(Mx(0!=f.b),_B(f.c.b.c,8)),e))}function zzn(n,t,e,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;if(0!=e.c.length){for(w=new $p,b=new Ub(e);b.a1)for(n5(m,new uI(n,b=new oqn(w,m,r))),u.c[u.c.length]=b,f=m.a.ec().Kc();f.Ob();)v7(a,_B(f.Pb(),46).b);if(o.a.gc()>1)for(n5(o,new oI(n,b=new oqn(w,o,r))),u.c[u.c.length]=b,f=o.a.ec().Kc();f.Ob();)v7(a,_B(f.Pb(),46).b)}}function Zzn(n){$M(n,new ETn(bj(gj(lj(dj(wj(new du,l4n),"ELK Radial"),'A radial layout provider which is based on the algorithm of Peter Eades published in "Drawing free trees.", published by International Institute for Advanced Study of Social Information Science, Fujitsu Limited in 1991. The radial layouter takes a tree and places the nodes in radial order around the root. The nodes of the same tree level are placed on the same radius.'),new Ha),l4n))),c2(n,l4n,w3n,ppn(Ljt)),c2(n,l4n,gZn,ppn(Djt)),c2(n,l4n,MZn,ppn(Sjt)),c2(n,l4n,_Zn,ppn(Pjt)),c2(n,l4n,TZn,ppn(Ijt)),c2(n,l4n,SZn,ppn(Mjt)),c2(n,l4n,EZn,ppn(Cjt)),c2(n,l4n,PZn,ppn($jt)),c2(n,l4n,o4n,ppn(Ejt)),c2(n,l4n,u4n,ppn(Tjt)),c2(n,l4n,f4n,ppn(Ojt)),c2(n,l4n,c4n,ppn(Ajt)),c2(n,l4n,a4n,ppn(Njt)),c2(n,l4n,s4n,ppn(xjt)),c2(n,l4n,h4n,ppn(Rjt))}function nUn(n){var t;if(this.r=LV(new Pn,new In),this.b=new Fbn(_B(vX(KCt),290)),this.p=new Fbn(_B(vX(KCt),290)),this.i=new Fbn(_B(vX(Drt),290)),this.e=n,this.o=new lA(n.rf()),this.D=n.Df()||By(jD(n.We((uWn(),TSt)))),this.A=_B(n.We((uWn(),DSt)),21),this.B=_B(n.We(BSt),21),this.q=_B(n.We(cPt),98),this.u=_B(n.We(sPt),21),!lMn(this.u))throw Fp(new ek("Invalid port label placement: "+this.u));if(this.v=By(jD(n.We(fPt))),this.j=_B(n.We(NSt),21),!Z$n(this.j))throw Fp(new ek("Invalid node label placement: "+this.j));this.n=_B(Yyn(n,$St),116),this.k=Hy(ED(Yyn(n,IPt))),this.d=Hy(ED(Yyn(n,PPt))),this.w=Hy(ED(Yyn(n,xPt))),this.s=Hy(ED(Yyn(n,CPt))),this.t=Hy(ED(Yyn(n,OPt))),this.C=_B(Yyn(n,LPt),142),this.c=2*this.d,t=!this.B.Hc((YKn(),FCt)),this.f=new Pgn(0,t,0),this.g=new Pgn(1,t,0),yy(this.f,(Ntn(),qit),this.g)}function tUn(n,t,e,r,c){var a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S;for(y=0,g=0,d=0,w=1,m=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));m.e!=m.i.gc();)w+=K3(new az(JL(bLn(p=_B(mpn(m),33)).a.Kc(),new h))),T=p.g,g=i.Math.max(g,T),b=p.f,d=i.Math.max(d,b),y+=T*b;for(u=y+2*r*r*w*(!n.a&&(n.a=new nU(qOt,n,10,11)),n.a).i,a=i.Math.sqrt(u),s=i.Math.max(a*e,g),o=i.Math.max(a/e,d),v=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));v.e!=v.i.gc();)p=_B(mpn(v),33),M=c.b+(F$n(t,26)*eJn+F$n(t,27)*iJn)*(s-p.g),S=c.b+(F$n(t,26)*eJn+F$n(t,27)*iJn)*(o-p.f),Men(p,M),Sen(p,S);for(E=s+(c.b+c.c),j=o+(c.d+c.a),k=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));k.e!=k.i.gc();)for(l=new az(JL(bLn(_B(mpn(k),33)).a.Kc(),new h));bAn(l);)YOn(f=_B(G5(l),79))||_Xn(f,t,E,j);DUn(n,E+=c.b+c.c,j+=c.d+c.a,!1,!0)}function eUn(n){var t,e,i,r,c,a,u,o,s,h,f;if(null==n)throw Fp(new Ek(qWn));if(s=n,o=!1,(c=n.length)>0&&(f1(0,n.length),45!=(t=n.charCodeAt(0))&&43!=t||(n=n.substr(1),--c,o=45==t)),0==c)throw Fp(new Ek(NQn+s+'"'));for(;n.length>0&&(f1(0,n.length),48==n.charCodeAt(0));)n=n.substr(1),--c;if(c>(tFn(),Ltt)[10])throw Fp(new Ek(NQn+s+'"'));for(r=0;r0&&(f=-parseInt(n.substr(0,i),10),n=n.substr(i),c-=i,e=!1);c>=a;){if(i=parseInt(n.substr(0,a),10),n=n.substr(a),c-=a,e)e=!1;else{if(Xhn(f,u)<0)throw Fp(new Ek(NQn+s+'"'));f=ibn(f,h)}f=tbn(f,i)}if(Xhn(f,0)>0)throw Fp(new Ek(NQn+s+'"'));if(!o&&Xhn(f=y7(f),0)<0)throw Fp(new Ek(NQn+s+'"'));return f}function iUn(n,t){var e,i,r,c,a,u,o;if(JH(),this.a=new z$(this),this.b=n,this.c=t,this.f=IU(_7((PPn(),Q$t),t)),this.f.dc())if((u=pjn(Q$t,n))==t)for(this.e=!0,this.d=new $p,this.f=new fo,this.f.Fc(T7n),_B($Hn(K7(Q$t,Gtn(n)),""),26)==n&&this.f.Fc(rz(Q$t,Gtn(n))),r=kKn(Q$t,n).Kc();r.Ob();)switch(i=_B(r.Pb(),170),NW(_7(Q$t,i))){case 4:this.d.Fc(i);break;case 5:this.f.Gc(IU(_7(Q$t,i)))}else if(JM(),_B(t,66).Oj())for(this.e=!0,this.f=null,this.d=new $p,a=0,o=(null==n.i&&BFn(n),n.i).length;a=0&&a0&&(_B(aV(n.b,t),124).a.b=e)}function cUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;for(ITn(t,"Comment pre-processing",1),e=0,o=new Ub(n.a);o.a0&&(f1(0,t.length),64!=(u=t.charCodeAt(0)))){if(37==u&&(o=!1,0!=(h=t.lastIndexOf("%"))&&(h==f-1||(f1(h+1,t.length),o=46==t.charCodeAt(h+1))))){if(v=pK("%",a=t.substr(1,h-1))?null:OUn(a),i=0,o)try{i=h_n(t.substr(h+2),RVn,NWn)}catch(m){throw iL(m=hun(m),127)?Fp(new A7(m)):Fp(m)}for(d=krn(n.Wg());d.Ob();)if(iL(b=Ean(d),510)&&(p=(r=_B(b,590)).d,(null==v?null==p:pK(v,p))&&0==i--))return r;return null}if(l=-1==(s=t.lastIndexOf("."))?t:t.substr(0,s),e=0,-1!=s)try{e=h_n(t.substr(s+1),RVn,NWn)}catch(m){if(!iL(m=hun(m),127))throw Fp(m);l=t}for(l=pK("%",l)?null:OUn(l),w=krn(n.Wg());w.Ob();)if(iL(b=Ean(w),191)&&(g=(c=_B(b,191)).ne(),(null==l?null==g:pK(l,g))&&0==e--))return c;return null}return Rqn(n,t)}function sUn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T;for(m=new $p,f=new Ub(n.b);f.a=n.length)return{done:!0};var i=n[e++];return{value:[i,t.get(i)],done:!1}}}},qDn()||(n.prototype.createObject=function(){return{}},n.prototype.get=function(n){return this.obj[":"+n]},n.prototype.set=function(n,t){this.obj[":"+n]=t},n.prototype[tJn]=function(n){delete this.obj[":"+n]},n.prototype.keys=function(){var n=[];for(var t in this.obj)58==t.charCodeAt(0)&&n.push(t.substring(1));return n}),n}function lUn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d;if(MFn(),null==n)return null;if(0==(f=8*n.length))return"";for(l=f/24|0,c=null,c=L8(PNt,UVn,25,4*(0!=(u=f%24)?l+1:l),15,1),s=0,h=0,t=0,e=0,i=0,a=0,r=0,o=0;o>24,s=(3&t)<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,w=0==(-128&e)?e>>4<<24>>24:(e>>4^240)<<24>>24,d=0==(-128&(i=n[r++]))?i>>6<<24>>24:(i>>6^252)<<24>>24,c[a++]=ULt[b],c[a++]=ULt[w|s<<4],c[a++]=ULt[h<<2|d],c[a++]=ULt[63&i];return 8==u?(s=(3&(t=n[r]))<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,c[a++]=ULt[b],c[a++]=ULt[s<<4],c[a++]=61,c[a++]=61):16==u&&(t=n[r],h=(15&(e=n[r+1]))<<24>>24,s=(3&t)<<24>>24,b=0==(-128&t)?t>>2<<24>>24:(t>>2^192)<<24>>24,w=0==(-128&e)?e>>4<<24>>24:(e>>4^240)<<24>>24,c[a++]=ULt[b],c[a++]=ULt[w|s<<4],c[a++]=ULt[h<<2],c[a++]=61),_dn(c,0,c.length)}function bUn(n,t){var e,r,c,a,u,o;if(0==n.e&&n.p>0&&(n.p=-(n.p-1)),n.p>RVn&&n4(t,n.p-uQn),u=t.q.getDate(),KY(t,1),n.k>=0&&gZ(t,n.k),n.c>=0?KY(t,n.c):n.k>=0?(r=35-new gon(t.q.getFullYear()-uQn,t.q.getMonth(),35).q.getDate(),KY(t,i.Math.min(r,u))):KY(t,u),n.f<0&&(n.f=t.q.getHours()),n.b>0&&n.f<12&&(n.f+=12),rL(t,24==n.f&&n.g?0:n.f),n.j>=0&&w6(t,n.j),n.n>=0&&G8(t,n.n),n.i>=0&&bO(t,ebn(ibn(Ijn(san(t.q.getTime()),XVn),XVn),n.i)),n.a&&(n4(c=new CT,c.q.getFullYear()-uQn-80),uS(san(t.q.getTime()),san(c.q.getTime()))&&n4(t,c.q.getFullYear()-uQn+100)),n.d>=0)if(-1==n.c)(e=(7+n.d-t.q.getDay())%7)>3&&(e-=7),o=t.q.getMonth(),KY(t,t.q.getDate()+e),t.q.getMonth()!=o&&KY(t,t.q.getDate()+(e>0?-7:7));else if(t.q.getDay()!=n.d)return!1;return n.o>RVn&&(a=t.q.getTimezoneOffset(),bO(t,ebn(san(t.q.getTime()),60*(n.o-a)*XVn))),!0}function wUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;if(iL(r=pMn(t,(oWn(),blt)),239)){for(b=_B(r,33),w=t.e,f=new lA(t.c),c=t.d,f.a+=c.b,f.b+=c.d,TN(_B(JAn(b,(FXn(),Bgt)),174),(YKn(),BCt))&&(Il(l=_B(JAn(b,qgt),116),c.a),Rl(l,c.d),Cl(l,c.b),Kl(l,c.c)),e=new $p,s=new Ub(t.a);s.a0&&UB(n.p,l),UB(n.o,l);d=s+(t-=r),f+=t*n.e,i5(n.a,o,tln(d)),i5(n.b,o,f),n.j=i.Math.max(n.j,d),n.k=i.Math.max(n.k,f),n.d+=t,t+=p}}function mUn(){var n;mUn=O,MCt=new UI(oYn,0),uCt=new UI(pYn,1),aCt=new UI(vYn,2),TCt=new UI(mYn,3),SCt=new UI(yYn,4),TQ(),lCt=new Ck(new VK(n=_B(Xj(KCt),9),_B(TR(n,n.length),9),0)),bCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[]))),oCt=sfn(kG(aCt,Mun(Hk(KCt,1),VZn,61,0,[]))),kCt=sfn(kG(TCt,Mun(Hk(KCt,1),VZn,61,0,[]))),ECt=sfn(kG(SCt,Mun(Hk(KCt,1),VZn,61,0,[]))),vCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[TCt]))),fCt=sfn(kG(aCt,Mun(Hk(KCt,1),VZn,61,0,[SCt]))),yCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[SCt]))),wCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[aCt]))),jCt=sfn(kG(TCt,Mun(Hk(KCt,1),VZn,61,0,[SCt]))),sCt=sfn(kG(aCt,Mun(Hk(KCt,1),VZn,61,0,[TCt]))),pCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[aCt,SCt]))),hCt=sfn(kG(aCt,Mun(Hk(KCt,1),VZn,61,0,[TCt,SCt]))),mCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[TCt,SCt]))),dCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[aCt,TCt]))),gCt=sfn(kG(uCt,Mun(Hk(KCt,1),VZn,61,0,[aCt,TCt,SCt])))}function yUn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v;if(0!=t.b){for(l=new VT,a=null,b=null,e=SY(i.Math.floor(i.Math.log(t.b)*i.Math.LOG10E)+1),u=0,v=upn(t,0);v.b!=v.d.c;)for(g=_B(f3(v),86),HC(b)!==HC(pMn(g,(Bqn(),ekt)))&&(b=TD(pMn(g,ekt)),u=0),a=null!=b?b+b0(u++,e):b0(u++,e),oon(g,ekt,a),d=new lg(upn(new fg(g).a.d,0));kE(d.a);)e5(l,w=_B(f3(d.a),188).c,l.c.b,l.c),oon(w,ekt,a);for(f=new Lp,c=0;c=s){Mx(v.b>0),v.a.Xb(v.c=--v.b);break}g.a>h&&(c?(wun(c.b,g.b),c.a=i.Math.max(c.a,g.a),sW(v)):(UB(g.b,l),g.c=i.Math.min(g.c,h),g.a=i.Math.max(g.a,s),c=g))}c||((c=new tm).c=h,c.a=s,vR(v,c),UB(c.b,l))}for(o=t.b,f=0,p=new Ub(r);p.au?1:0:(n.b&&(n.b._b(c)&&(r=_B(n.b.xc(c),19).a),n.b._b(o)&&(u=_B(n.b.xc(o),19).a)),ru?1:0)):0!=t.e.c.length&&0!=e.g.c.length?1:-1}function EUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(ITn(t,I1n,1),w=new $p,y=new $p,s=new Ub(n.b);s.a0&&(k-=d),jqn(u,k),l=0,w=new Ub(u.a);w.a0),o.a.Xb(o.c=--o.b)),s=.4*r*l,!a&&o.bt.d.c){if((b=n.c[t.a.d])==(g=n.c[f.a.d]))continue;GNn(rM(iM(cM(eM(new Fv,1),100),b),g))}}}function OUn(n){var t,e,i,r,c,a,u,o;if(xHn(),null==n)return null;if((r=HO(n,VTn(37)))<0)return n;for(o=new hN(n.substr(0,r)),t=L8(ANt,g6n,25,4,15,1),u=0,i=0,a=n.length;rr+2&&Zun((f1(r+1,n.length),n.charCodeAt(r+1)),SAt,PAt)&&Zun((f1(r+2,n.length),n.charCodeAt(r+2)),SAt,PAt))if(e=SH((f1(r+1,n.length),n.charCodeAt(r+1)),(f1(r+2,n.length),n.charCodeAt(r+2))),r+=2,i>0?128==(192&e)?t[u++]=e<<24>>24:i=0:e>=128&&(192==(224&e)?(t[u++]=e<<24>>24,i=2):224==(240&e)?(t[u++]=e<<24>>24,i=3):240==(248&e)&&(t[u++]=e<<24>>24,i=4)),i>0){if(u==i){switch(u){case 2:LX(o,((31&t[0])<<6|63&t[1])&WVn);break;case 3:LX(o,((15&t[0])<<12|(63&t[1])<<6|63&t[2])&WVn)}u=0,i=0}}else{for(c=0;c0){if(a+i>n.length)return!1;u=GCn(n.substr(0,a+i),t)}else u=GCn(n,t);switch(c){case 71:return u=qTn(n,a,Mun(Hk(Wtt,1),uVn,2,6,[sQn,hQn]),t),r.e=u,!0;case 77:return wDn(n,t,r,u,a);case 76:return dDn(n,t,r,u,a);case 69:return eIn(n,t,a,r);case 99:return iIn(n,t,a,r);case 97:return u=qTn(n,a,Mun(Hk(Wtt,1),uVn,2,6,["AM","PM"]),t),r.b=u,!0;case 121:return gDn(n,t,a,u,e,r);case 100:return!(u<=0||(r.c=u,0));case 83:return!(u<0)&&ywn(u,a,t[0],r);case 104:12==u&&(u=0);case 75:case 72:return!(u<0||(r.f=u,r.g=!1,0));case 107:return!(u<0||(r.f=u,r.g=!0,0));case 109:return!(u<0||(r.j=u,0));case 115:return!(u<0||(r.n=u,0));case 90:if(aE&&(d.c=E-d.b),UB(u.d,new LG(d,mln(u,d))),m=t==uCt?i.Math.max(m,g.b+h.b.rf().b):i.Math.min(m,g.b));for(m+=t==uCt?n.t:-n.t,(y=Mwn((u.e=m,u)))>0&&(_B(aV(n.b,t),124).a.b=y),f=b.Kc();f.Ob();)!(h=_B(f.Pb(),111)).c||h.c.d.c.length<=0||((d=h.c.i).c-=h.e.a,d.d-=h.e.b)}else rUn(n,t)}function LUn(n){var t,e,i,r,c,a,u,o,s,f;for(t=new Lp,a=new CL(n);a.e!=a.i.gc();){for(c=_B(mpn(a),33),e=new xv,XW(Ect,c,e),f=new ut,i=_B(M4(new xq(null,new qU(new az(JL(lLn(c).a.Kc(),new h)))),TG(f,p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[(Bsn(),Get)])))),83),Qen(e,_B(i.xc((oN(),!0)),14),new ot),r=_B(M4(CV(_B(i.xc(!1),15).Lc(),new st),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[Get]))),15).Kc();r.Ob();)(s=SMn(_B(r.Pb(),79)))&&((u=_B(BC(CJ(t.f,s)),21))||(u=Ixn(s),yIn(t.f,s,u)),Krn(e,u));for(i=_B(M4(new xq(null,new qU(new az(JL(bLn(c).a.Kc(),new h)))),TG(f,p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[Get])))),83),Qen(e,_B(i.xc(!0),14),new ht),o=_B(M4(CV(_B(i.xc(!1),15).Lc(),new ft),p9(new H,new B,new rn,Mun(Hk(Yet,1),OVn,132,0,[Get]))),15).Kc();o.Ob();)(s=PMn(_B(o.Pb(),79)))&&((u=_B(BC(CJ(t.f,s)),21))||(u=Ixn(s),yIn(t.f,s,u)),Krn(e,u))}}function NUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d;if(cHn(),(o=Xhn(n,0)<0)&&(n=y7(n)),0==Xhn(n,0))switch(t){case 0:return"0";case 1:return UQn;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(b=new Sk).a+=t<0?"0E+":"0E",b.a+=t==RVn?"2147483648":""+-t,b.a}f=L8(PNt,UVn,25,1+(h=18),15,1),e=h,d=n;do{s=d,d=Ijn(d,10),f[--e]=bG(ebn(48,tbn(s,ibn(d,10))))&WVn}while(0!=Xhn(d,0));if(r=tbn(tbn(tbn(h,e),t),1),0==t)return o&&(f[--e]=45),_dn(f,e,h-e);if(t>0&&Xhn(r,-6)>=0){if(Xhn(r,0)>=0){for(c=e+bG(r),u=h-1;u>=c;u--)f[u+1]=f[u];return f[++c]=46,o&&(f[--e]=45),_dn(f,e,h-e+1)}for(a=2;uS(a,ebn(y7(r),1));a++)f[--e]=48;return f[--e]=46,f[--e]=48,o&&(f[--e]=45),_dn(f,e,h-e)}return w=e+1,i=h,l=new Pk,o&&(l.a+="-"),i-w>=1?(LX(l,f[e]),l.a+=".",l.a+=_dn(f,e+1,h-e-1)):l.a+=_dn(f,e,h-e),l.a+="E",Xhn(r,0)>0&&(l.a+="+"),l.a+=""+gz(r),l.a}function xUn(n,t,e){var i,r,c,a,u,o,s,h,f,l;if(n.e.a.$b(),n.f.a.$b(),n.c.c=L8(Cnt,FWn,1,0,5,1),n.i.c=L8(Cnt,FWn,1,0,5,1),n.g.a.$b(),t)for(a=new Ub(t.a);a.a=1&&(j-h>0&&d>=0?(Men(l,l.i+k),Sen(l,l.j+s*h)):j-h<0&&w>=0&&(Men(l,l.i+k*j),Sen(l,l.j+s)));return Vpn(n,(uWn(),DSt),(pdn(),new VK(a=_B(Xj(VCt),9),_B(TR(a,a.length),9),0))),new LI(E,f)}function RUn(n){var t,e,r,c,a,u,o,s,h,f,l;if(f=QY(MTn(_B(Utn((!n.b&&(n.b=new oK(xOt,n,4,7)),n.b),0),82)))==QY(MTn(_B(Utn((!n.c&&(n.c=new oK(xOt,n,5,8)),n.c),0),82))),u=new Hj,(t=_B(JAn(n,(zsn(),oIt)),74))&&t.b>=2){if(0==(!n.a&&(n.a=new nU(ROt,n,6,6)),n.a).i)Zj(),e=new co,s9((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a),e);else if((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a).i>1)for(l=new ix((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a));l.e!=l.i.gc();)Wjn(l);XFn(t,_B(Utn((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a),0),202))}if(f)for(r=new CL((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a));r.e!=r.i.gc();)for(s=new CL((!(e=_B(mpn(r),202)).a&&(e.a=new OL($Ot,e,5)),e.a));s.e!=s.i.gc();)o=_B(mpn(s),469),u.a=i.Math.max(u.a,o.a),u.b=i.Math.max(u.b,o.b);for(a=new CL((!n.n&&(n.n=new nU(HOt,n,1,7)),n.n));a.e!=a.i.gc();)c=_B(mpn(a),137),(h=_B(JAn(c,wIt),8))&&TA(c,h.a,h.b),f&&(u.a=i.Math.max(u.a,c.i+c.g),u.b=i.Math.max(u.b,c.j+c.f));return u}function KUn(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E;for(v=t.c.length,c=new BKn(n.a,e,null,null),E=L8($Nt,BQn,25,v,15,1),w=L8($Nt,BQn,25,v,15,1),b=L8($Nt,BQn,25,v,15,1),d=0,o=0;oE[s]&&(d=s),f=new Ub(n.a.b);f.aw&&(a&&(sO(j,b),sO(T,tln(h.b-1))),C=e.b,O+=b+t,b=0,f=i.Math.max(f,e.b+e.c+I)),Men(o,C),Sen(o,O),f=i.Math.max(f,C+I+e.c),b=i.Math.max(b,l),C+=I+t;if(f=i.Math.max(f,r),(P=O+b+e.a)hZn,S=i.Math.abs(b.b-d.b)>hZn,(!e&&M&&S||e&&(M||S))&&NH(p.a,k)),Krn(p.a,r),0==r.b?b=k:(Mx(0!=r.b),b=_B(r.c.b.c,8)),Van(w,l,g),rcn(c)==T&&(gW(T.i)!=c.a&&IPn(g=new Hj,gW(T.i),m),oon(p,xlt,g)),ESn(w,p,m),f.a.zc(w,f);TZ(p,j),EZ(p,T)}for(h=f.a.ec().Kc();h.Ob();)TZ(s=_B(h.Pb(),17),null),EZ(s,null);FSn(t)}function HUn(n){var t,e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;if(1==n.gc())return _B(n.Xb(0),231);if(n.gc()<=0)return new v6;for(c=n.Kc();c.Ob();){for(e=_B(c.Pb(),231),d=0,f=NWn,l=NWn,s=RVn,h=RVn,w=new Ub(e.e);w.ao&&(y=0,k+=u+v,u=0),XKn(g,e,y,k),t=i.Math.max(t,y+p.a),u=i.Math.max(u,p.b),y+=p.a+v;return g}function qUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w;switch(h=new mm,n.a.g){case 3:l=_B(pMn(t.e,(oWn(),$lt)),15),b=_B(pMn(t.j,$lt),15),w=_B(pMn(t.f,$lt),15),e=_B(pMn(t.e,Olt),15),i=_B(pMn(t.j,Olt),15),r=_B(pMn(t.f,Olt),15),wun(a=new $p,l),b.Jc(new yc),wun(a,iL(b,152)?a6(_B(b,152)):iL(b,131)?_B(b,131).a:iL(b,54)?new sy(b):new ST(b)),wun(a,w),wun(c=new $p,e),wun(c,iL(i,152)?a6(_B(i,152)):iL(i,131)?_B(i,131).a:iL(i,54)?new sy(i):new ST(i)),wun(c,r),oon(t.f,$lt,a),oon(t.f,Olt,c),oon(t.f,Llt,t.f),oon(t.e,$lt,null),oon(t.e,Olt,null),oon(t.j,$lt,null),oon(t.j,Olt,null);break;case 1:Krn(h,t.e.a),NH(h,t.i.n),Krn(h,nan(t.j.a)),NH(h,t.a.n),Krn(h,t.f.a);break;default:Krn(h,t.e.a),Krn(h,nan(t.j.a)),Krn(h,t.f.a)}vQ(t.f.a),Krn(t.f.a,h),TZ(t.f,t.e.c),u=_B(pMn(t.e,(FXn(),ggt)),74),s=_B(pMn(t.j,ggt),74),o=_B(pMn(t.f,ggt),74),(u||s||o)&&(MU(f=new mm,o),MU(f,s),MU(f,u),oon(t.f,ggt,f)),TZ(t.j,null),EZ(t.j,null),TZ(t.e,null),EZ(t.e,null),MZ(t.a,null),MZ(t.i,null),t.g&&qUn(n,t.g)}function GUn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b,w,d,g;if(MFn(),null==n)return null;if((w=fln(c=X7(n)))%4!=0)return null;if(0==(d=w/4|0))return L8(ANt,g6n,25,0,15,1);for(f=null,t=0,e=0,i=0,r=0,a=0,u=0,o=0,s=0,b=0,l=0,h=0,f=L8(ANt,g6n,25,3*d,15,1);b>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24}return XE(a=c[h++])&&XE(u=c[h++])?(t=zLt[a],e=zLt[u],o=c[h++],s=c[h++],-1==zLt[o]||-1==zLt[s]?61==o&&61==s?0!=(15&e)?null:(rHn(f,0,g=L8(ANt,g6n,25,3*b+1,15,1),0,3*b),g[l]=(t<<2|e>>4)<<24>>24,g):61!=o&&61==s?0!=(3&(i=zLt[o]))?null:(rHn(f,0,g=L8(ANt,g6n,25,3*b+2,15,1),0,3*b),g[l++]=(t<<2|e>>4)<<24>>24,g[l]=((15&e)<<4|i>>2&15)<<24>>24,g):null:(i=zLt[o],r=zLt[s],f[l++]=(t<<2|e>>4)<<24>>24,f[l++]=((15&e)<<4|i>>2&15)<<24>>24,f[l++]=(i<<6|r)<<24>>24,f)):null}function zUn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m;for(ITn(t,I1n,1),l=_B(pMn(n,(FXn(),Jdt)),218),i=new Ub(n.b);i.a=2){for(b=!0,e=_B(Y1(h=new Ub(r.j)),11),f=null;h.a0&&(c=_B(Lq(p.c.a,E-1),10),u=n.i[c.p],M=i.Math.ceil(D$(n.n,c,p)),a=j.a.e-p.d.d-(u.a.e+c.o.b+c.d.a)-M),h=xQn,E0&&T.a.e.e-T.a.a-(T.b.e.e-T.b.a)<0,d=y.a.e.e-y.a.a-(y.b.e.e-y.b.a)<0&&T.a.e.e-T.a.a-(T.b.e.e-T.b.a)>0,w=y.a.e.e+y.b.aT.b.e.e+T.a.a,k=0,!g&&!d&&(b?a+l>0?k=l:h-r>0&&(k=r):w&&(a+o>0?k=o:h-m>0&&(k=m))),j.a.e+=k,j.b&&(j.d.e+=k),1)))}function XUn(n,t,e){var r,c,a,u,o,s,h,f,l,b;if(r=new GV(t.qf().a,t.qf().b,t.rf().a,t.rf().b),c=new fA,n.c)for(u=new Ub(t.wf());u.as&&(i.a+=eL(L8(PNt,UVn,25,-s,15,1))),i.a+="Is",HO(o,VTn(32))>=0)for(r=0;r=i.o.b/2}p?(g=_B(pMn(i,(oWn(),Dlt)),15))?l?c=g:(r=_B(pMn(i,Nft),15))?c=g.gc()<=r.gc()?g:r:(c=new $p,oon(i,Nft,c)):(c=new $p,oon(i,Dlt,c)):(r=_B(pMn(i,(oWn(),Nft)),15))?f?c=r:(g=_B(pMn(i,Dlt),15))?c=r.gc()<=g.gc()?r:g:(c=new $p,oon(i,Dlt,c)):(c=new $p,oon(i,Nft,c)),c.Fc(n),oon(n,(oWn(),Dft),e),t.d==e?(EZ(t,null),e.e.c.length+e.g.c.length==0&&SZ(e,null),wsn(e)):(TZ(t,null),e.e.c.length+e.g.c.length==0&&SZ(e,null)),vQ(t.a)}function ZUn(n,t){var e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C;for(v=new E2(n.b,0),d=0,s=_B((f=t.Kc()).Pb(),19).a,k=0,e=new xv,E=new sA;v.b=n.a&&(r=vBn(n,v),l=i.Math.max(l,r.b),y=i.Math.max(y,r.d),UB(o,new eC(v,r)));for(E=new $p,f=0;f0),g.a.Xb(g.c=--g.b),vR(g,T=new FX(n.b)),Mx(g.b0?(h=0,p&&(h+=o),h+=(M-1)*u,m&&(h+=o),T&&m&&(h=i.Math.max(h,YNn(m,u,v,E))),h0){for(l=h<100?null:new Kj(h),w=(s=new ycn(t)).g,g=L8(INt,oQn,25,h,15,1),i=0,m=new wtn(h),r=0;r=0;)if(null!=b?$fn(b,w[o]):HC(b)===HC(w[o])){g.length<=i&&rHn(g,0,g=L8(INt,oQn,25,2*g.length,15,1),0,i),g[i++]=r,s9(m,w[o]);break n}if(HC(b=b)===HC(u))break}}if(s=m,w=m.g,h=i,i>g.length&&rHn(g,0,g=L8(INt,oQn,25,i,15,1),0,i),i>0){for(v=!0,c=0;c=0;)Ayn(n,g[a]);if(i!=h){for(r=h;--r>=i;)Ayn(s,r);rHn(g,0,g=L8(INt,oQn,25,i,15,1),0,i)}t=s}}}else for(t=yyn(n,t),r=n.i;--r>=0;)t.Hc(n.g[r])&&(Ayn(n,r),v=!0);if(v){if(null!=g){for(f=1==(e=t.gc())?vZ(n,4,t.Kc().Pb(),null,g[0],d):vZ(n,6,t,g,g[0],d),l=e<100?null:new Kj(e),r=t.Kc();r.Ob();)l=BK(n,_B(b=r.Pb(),72),l);l?(l.Ei(f),l.Fi()):fan(n.e,f)}else{for(l=OK(t.gc()),r=t.Kc();r.Ob();)l=BK(n,_B(b=r.Pb(),72),l);l&&l.Fi()}return!0}return!1}function cXn(n,t){var e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m;for((e=new ovn(t)).a||w_n(t),s=hRn(t),o=new dY,g=new Wxn,d=new Ub(t.a);d.a0||e.o==iyt&&c0?(f=_B(Lq(l.c.a,a-1),10),T=D$(n.b,l,f),g=l.n.b-l.d.d-(f.n.b+f.o.b+f.d.a+T)):g=l.n.b-l.d.d,s=i.Math.min(g,s),a(a=tEn(n,e))?rKn(n,t,e):rKn(n,e,t),ra?1:0}return(i=_B(pMn(t,(oWn(),llt)),19).a)>(c=_B(pMn(e,llt),19).a)?rKn(n,t,e):rKn(n,e,t),ic?1:0}function hXn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d;if(By(jD(JAn(t,(uWn(),qSt)))))return TQ(),TQ(),uet;if(o=0!=(!t.a&&(t.a=new nU(qOt,t,10,11)),t.a).i,s=!(h=vCn(t)).dc(),o||s){if(!(r=_B(JAn(t,pPt),149)))throw Fp(new ek("Resolved algorithm is not set; apply a LayoutAlgorithmResolver before computing layout."));if(d=II(r,(oAn(),JOt)),$gn(t),!o&&s&&!d)return TQ(),TQ(),uet;if(u=new $p,HC(JAn(t,kSt))===HC((cfn(),dIt))&&(II(r,WOt)||II(r,XOt)))for(l=dRn(n,t),Krn(b=new VT,(!t.a&&(t.a=new nU(qOt,t,10,11)),t.a));0!=b.b;)$gn(f=_B(0==b.b?null:(Mx(0!=b.b),Ctn(b,b.a.a)),33)),HC(JAn(f,kSt))===HC(pIt)||M8(f,nSt)&&!y5(r,JAn(f,pPt))?(wun(u,hXn(n,f,e,i)),Vpn(f,kSt,pIt),DKn(f)):Krn(b,(!f.a&&(f.a=new nU(qOt,f,10,11)),f.a));else for(l=(!t.a&&(t.a=new nU(qOt,t,10,11)),t.a).i,a=new CL((!t.a&&(t.a=new nU(qOt,t,10,11)),t.a));a.e!=a.i.gc();)wun(u,hXn(n,c=_B(mpn(a),33),e,i)),DKn(c);for(w=new Ub(u);w.a=0?own(u):jln(own(u)),n.Ye(cpt,b)),s=new Hj,l=!1,n.Xe(Ygt)?(Fx(s,_B(n.We(Ygt),8)),l=!0):vL(s,a.a/2,a.b/2),b.g){case 4:oon(h,mgt,(jbn(),Klt)),oon(h,Hft,(Qun(),Oht)),h.o.b=a.b,d<0&&(h.o.a=-d),BIn(f,(mUn(),aCt)),l||(s.a=a.a),s.a-=a.a;break;case 2:oon(h,mgt,(jbn(),Flt)),oon(h,Hft,(Qun(),Iht)),h.o.b=a.b,d<0&&(h.o.a=-d),BIn(f,(mUn(),SCt)),l||(s.a=0);break;case 1:oon(h,tlt,(q7(),Sft)),h.o.a=a.a,d<0&&(h.o.b=-d),BIn(f,(mUn(),TCt)),l||(s.b=a.b),s.b-=a.b;break;case 3:oon(h,tlt,(q7(),Tft)),h.o.a=a.a,d<0&&(h.o.b=-d),BIn(f,(mUn(),uCt)),l||(s.b=0)}if(Fx(f.n,s),oon(h,Ygt,s),t==GIt||t==UIt||t==zIt){if(w=0,t==GIt&&n.Xe(tpt))switch(b.g){case 1:case 2:w=_B(n.We(tpt),19).a;break;case 3:case 4:w=-_B(n.We(tpt),19).a}else switch(b.g){case 4:case 2:w=c.b,t==UIt&&(w/=r.b);break;case 1:case 3:w=c.a,t==UIt&&(w/=r.a)}oon(h,jlt,w)}return oon(h,Wft,b),h}function lXn(n){var t,e,i,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E;if((e=Hy(ED(pMn(n.a.j,(FXn(),Rdt)))))<-1||!n.a.i||AK(_B(pMn(n.a.o,npt),98))||rbn(n.a.o,(mUn(),aCt)).gc()<2&&rbn(n.a.o,SCt).gc()<2)return!0;if(n.a.c.Rf())return!1;for(y=0,m=0,v=new $p,o=0,s=(u=n.a.e).length;o=e}function bXn(){function n(n){var t=this;this.dispatch=function(t){var e=t.data;switch(e.cmd){case"algorithms":var i=Twn((TQ(),new Fb(new Ib(sAt.b))));n.postMessage({id:e.id,data:i});break;case"categories":var r=Twn((TQ(),new Fb(new Ib(sAt.c))));n.postMessage({id:e.id,data:r});break;case"options":var c=Twn((TQ(),new Fb(new Ib(sAt.d))));n.postMessage({id:e.id,data:c});break;case"register":hGn(e.algorithms),n.postMessage({id:e.id});break;case"layout":LBn(e.graph,e.layoutOptions||{},e.options||{}),n.postMessage({id:e.id,data:e.graph})}},this.saveDispatch=function(e){try{t.dispatch(e)}catch(i){n.postMessage({id:e.data.id,error:i})}}}function i(t){var e=this;this.dispatcher=new n({postMessage:function(n){e.onmessage({data:n})}}),this.postMessage=function(n){setTimeout((function(){e.dispatcher.saveDispatch({data:n})}),0)}}if(rE(),typeof document===wJn&&typeof self!==wJn){var r=new n(self);self.onmessage=r.saveDispatch}else typeof t!==wJn&&t.exports&&(Object.defineProperty(e,"__esModule",{value:!0}),t.exports={default:i,Worker:i})}function wXn(n){n.N||(n.N=!0,n.b=man(n,0),xrn(n.b,0),xrn(n.b,1),xrn(n.b,2),n.bb=man(n,1),xrn(n.bb,0),xrn(n.bb,1),n.fb=man(n,2),xrn(n.fb,3),xrn(n.fb,4),Drn(n.fb,5),n.qb=man(n,3),xrn(n.qb,0),Drn(n.qb,1),Drn(n.qb,2),xrn(n.qb,3),xrn(n.qb,4),Drn(n.qb,5),xrn(n.qb,6),n.a=yan(n,4),n.c=yan(n,5),n.d=yan(n,6),n.e=yan(n,7),n.f=yan(n,8),n.g=yan(n,9),n.i=yan(n,10),n.j=yan(n,11),n.k=yan(n,12),n.n=yan(n,13),n.o=yan(n,14),n.p=yan(n,15),n.q=yan(n,16),n.s=yan(n,17),n.r=yan(n,18),n.t=yan(n,19),n.u=yan(n,20),n.v=yan(n,21),n.w=yan(n,22),n.B=yan(n,23),n.A=yan(n,24),n.C=yan(n,25),n.D=yan(n,26),n.F=yan(n,27),n.G=yan(n,28),n.H=yan(n,29),n.J=yan(n,30),n.I=yan(n,31),n.K=yan(n,32),n.M=yan(n,33),n.L=yan(n,34),n.P=yan(n,35),n.Q=yan(n,36),n.R=yan(n,37),n.S=yan(n,38),n.T=yan(n,39),n.U=yan(n,40),n.V=yan(n,41),n.X=yan(n,42),n.W=yan(n,43),n.Y=yan(n,44),n.Z=yan(n,45),n.$=yan(n,46),n._=yan(n,47),n.ab=yan(n,48),n.cb=yan(n,49),n.db=yan(n,50),n.eb=yan(n,51),n.gb=yan(n,52),n.hb=yan(n,53),n.ib=yan(n,54),n.jb=yan(n,55),n.kb=yan(n,56),n.lb=yan(n,57),n.mb=yan(n,58),n.nb=yan(n,59),n.ob=yan(n,60),n.pb=yan(n,61))}function dXn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;if(m=0,0==t.f.a)for(p=new Ub(n);p.as&&0==(h1(s,t.c.length),_B(t.c[s],200)).a.c.length;)v7(t,(h1(s,t.c.length),t.c[s]));if(!o){--c;continue}if(C_n(t,h,r,o,l,e,s,i)){f=!0;continue}if(l){if(QBn(t,h,r,o,e,s,i)){f=!0;continue}if(Chn(h,r)){r.c=!0,f=!0;continue}}else if(Chn(h,r)){r.c=!0,f=!0;continue}if(f)continue}Chn(h,r)?(r.c=!0,f=!0,o&&(o.k=!1)):Hmn(r.q)}else OT(),jkn(h,r),--c,f=!0;return f}function vXn(n,t,e,r,c,a,u){var o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A;for(g=0,P=0,h=new Ub(n.b);h.ag&&(a&&(sO(E,w),sO(M,tln(f.b-1)),UB(n.d,d),o.c=L8(Cnt,FWn,1,0,5,1)),O=e.b,A+=w+t,w=0,l=i.Math.max(l,e.b+e.c+C)),o.c[o.c.length]=s,Epn(s,O,A),l=i.Math.max(l,O+C+e.c),w=i.Math.max(w,b),O+=C+t,d=s;if(wun(n.a,o),UB(n.d,_B(Lq(o,o.c.length-1),157)),l=i.Math.max(l,r),(I=A+w+e.a)1&&(u=i.Math.min(u,i.Math.abs(_B(Npn(o.a,1),8).b-f.b)))));else for(d=new Ub(t.j);d.ac&&(a=b.a-c,u=NWn,r.c=L8(Cnt,FWn,1,0,5,1),c=b.a),b.a>=c&&(r.c[r.c.length]=o,o.a.b>1&&(u=i.Math.min(u,i.Math.abs(_B(Npn(o.a,o.a.b-2),8).b-b.b)))));if(0!=r.c.length&&a>t.o.a/2&&u>t.o.b/2){for(SZ(w=new SSn,t),BIn(w,(mUn(),uCt)),w.n.a=t.o.a/2,SZ(g=new SSn,t),BIn(g,TCt),g.n.a=t.o.a/2,g.n.b=t.o.b,s=new Ub(r);s.a=h.b?TZ(o,g):TZ(o,w)):(h=_B(wH(o.a),8),(0==o.a.b?w1(o.c):_B(dx(o.a),8)).b>=h.b?EZ(o,g):EZ(o,w)),(l=_B(pMn(o,(FXn(),ggt)),74))&&vwn(l,h,!0);t.n.a=c-t.o.a/2}}function kXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;if(s=t,Oin(o=W3(n,A3(e),s),x2(s,B6n)),h=_B(uen(n.g,mCn(qY(s,j6n))),33),i=null,(a=qY(s,"sourcePort"))&&(i=mCn(a)),f=_B(uen(n.j,i),118),!h)throw Fp(new nk("An edge must have a source node (edge id: '"+Wdn(s)+U6n));if(f&&!lW(UY(f),h))throw Fp(new nk("The source port of an edge must be a port of the edge's source node (edge id: '"+x2(s,B6n)+U6n));if(!o.b&&(o.b=new oK(xOt,o,4,7)),s9(o.b,f||h),l=_B(uen(n.g,mCn(qY(s,V6n))),33),r=null,(u=qY(s,"targetPort"))&&(r=mCn(u)),b=_B(uen(n.j,r),118),!l)throw Fp(new nk("An edge must have a target node (edge id: '"+Wdn(s)+U6n));if(b&&!lW(UY(b),l))throw Fp(new nk("The target port of an edge must be a port of the edge's target node (edge id: '"+x2(s,B6n)+U6n));if(!o.c&&(o.c=new oK(xOt,o,5,8)),s9(o.c,b||l),0==(!o.b&&(o.b=new oK(xOt,o,4,7)),o.b).i||0==(!o.c&&(o.c=new oK(xOt,o,5,8)),o.c).i)throw c=x2(s,B6n),Fp(new nk(z6n+c+U6n));return TTn(s,o),u$n(s,o),Lon(n,s,o)}function jXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S;return f=SFn(FN(n,(mUn(),lCt)),t),w=ryn(FN(n,bCt),t),y=ryn(FN(n,kCt),t),T=cyn(FN(n,ECt),t),l=cyn(FN(n,oCt),t),v=ryn(FN(n,yCt),t),d=ryn(FN(n,wCt),t),j=ryn(FN(n,jCt),t),k=ryn(FN(n,sCt),t),M=cyn(FN(n,fCt),t),p=ryn(FN(n,vCt),t),m=ryn(FN(n,pCt),t),E=ryn(FN(n,hCt),t),S=cyn(FN(n,mCt),t),b=cyn(FN(n,dCt),t),g=ryn(FN(n,gCt),t),e=Aon(Mun(Hk($Nt,1),BQn,25,15,[v.a,T.a,j.a,S.a])),i=Aon(Mun(Hk($Nt,1),BQn,25,15,[w.a,f.a,y.a,g.a])),r=p.a,c=Aon(Mun(Hk($Nt,1),BQn,25,15,[d.a,l.a,k.a,b.a])),s=Aon(Mun(Hk($Nt,1),BQn,25,15,[v.b,w.b,d.b,m.b])),o=Aon(Mun(Hk($Nt,1),BQn,25,15,[T.b,f.b,l.b,g.b])),h=M.b,u=Aon(Mun(Hk($Nt,1),BQn,25,15,[j.b,y.b,k.b,E.b])),l9(FN(n,lCt),e+r,s+h),l9(FN(n,gCt),e+r,s+h),l9(FN(n,bCt),e+r,0),l9(FN(n,kCt),e+r,s+h+o),l9(FN(n,ECt),0,s+h),l9(FN(n,oCt),e+r+i,s+h),l9(FN(n,wCt),e+r+i,0),l9(FN(n,jCt),0,s+h+o),l9(FN(n,sCt),e+r+i,s+h+o),l9(FN(n,fCt),0,s),l9(FN(n,vCt),e,0),l9(FN(n,hCt),0,s+h+o),l9(FN(n,dCt),e+r+i,0),(a=new Hj).a=Aon(Mun(Hk($Nt,1),BQn,25,15,[e+i+r+c,M.a,m.a,E.a])),a.b=Aon(Mun(Hk($Nt,1),BQn,25,15,[s+o+h+u,p.b,S.b,b.b])),a}function EXn(n){var t,e,i,r,c,a,u,o,s,f,l,b,w,d,g;for(d=new $p,l=new Ub(n.d.b);l.ar.d.d+r.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))),i.b!=i.d.c&&(t=e);f&&(c=_B(xX(n.f,a.d.i),57),t.bc.d.d+c.d.a?f.f.d=!0:(f.f.d=!0,f.f.a=!0))}for(u=new az(JL(sbn(b).a.Kc(),new h));bAn(u);)0!=(a=_B(G5(u),17)).a.b&&(t=_B(dx(a.a),8),a.d.j==(mUn(),uCt)&&((g=new MBn(t,new LI(t.a,r.d.d),r,a)).f.a=!0,g.a=a.d,d.c[d.c.length]=g),a.d.j==TCt&&((g=new MBn(t,new LI(t.a,r.d.d+r.d.a),r,a)).f.d=!0,g.a=a.d,d.c[d.c.length]=g))}return d}function TXn(n,t,e){var i,r,c,a,u,o,s;if(ITn(e,"Network simplex node placement",1),n.e=t,n.n=_B(pMn(t,(oWn(),Clt)),304),aqn(n),xEn(n),QT(lnn(new xq(null,new l1(n.e.b,16)),new Hc),new ig(n)),QT(CV(lnn(CV(lnn(new xq(null,new l1(n.e.b,16)),new ta),new ea),new ia),new ra),new eg(n)),By(jD(pMn(n.e,(FXn(),Lgt))))&&(ITn(c=pcn(e,1),"Straight Edges Pre-Processing",1),yzn(n),FSn(c)),Evn(n.f),r=_B(pMn(t,Lpt),19).a*n.f.a.c.length,UKn(Wk(Vk(__(n.f),r),!1),pcn(e,1)),0!=n.d.a.gc()){for(ITn(c=pcn(e,1),"Flexible Where Space Processing",1),a=_B(ON(Iz(OV(new xq(null,new l1(n.f.a,16)),new qc),new Dc)),19).a,u=_B(ON(Pz(OV(new xq(null,new l1(n.f.a,16)),new Gc),new Rc)),19).a-a,o=CN(new Bv,n.f),s=CN(new Bv,n.f),GNn(rM(iM(eM(cM(new Fv,2e4),u),o),s)),QT(CV(CV(AU(n.i),new zc),new Uc),new qV(a,o,u,s)),i=n.d.a.ec().Kc();i.Ob();)_B(i.Pb(),213).g=1;UKn(Wk(Vk(__(n.f),r),!1),pcn(c,1)),FSn(c)}By(jD(pMn(t,Lgt)))&&(ITn(c=pcn(e,1),"Straight Edges Post-Processing",1),TPn(n),FSn(c)),WGn(n),n.e=null,n.f=null,n.i=null,n.c=null,OU(n.k),n.j=null,n.a=null,n.o=null,n.d.a.$b(),FSn(e)}function MXn(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;for(u=new Ub(n.a.b);u.a0)if(r=f.gc(),s=SY(i.Math.floor((r+1)/2))-1,c=SY(i.Math.ceil((r+1)/2))-1,t.o==iyt)for(h=c;h>=s;h--)t.a[y.p]==y&&(d=_B(f.Xb(h),46),w=_B(d.a,10),!KT(e,d.b)&&b>n.b.e[w.p]&&(t.a[w.p]=y,t.g[y.p]=t.g[w.p],t.a[y.p]=t.g[y.p],t.f[t.g[y.p].p]=(oN(),!!(By(t.f[t.g[y.p].p])&y.k==(cSn(),Mut))),b=n.b.e[w.p]));else for(h=s;h<=c;h++)t.a[y.p]==y&&(p=_B(f.Xb(h),46),g=_B(p.a,10),!KT(e,p.b)&&b=w&&(v>w&&(b.c=L8(Cnt,FWn,1,0,5,1),w=v),b.c[b.c.length]=a);0!=b.c.length&&(l=_B(Lq(b,dvn(t,b.c.length)),128),P.a.Bc(l),l.s=d++,iLn(l,M,j),b.c=L8(Cnt,FWn,1,0,5,1))}for(y=n.c.length+1,u=new Ub(n);u.aS.s&&(sW(e),v7(S.i,i),i.c>0&&(i.a=S,UB(S.t,i),i.b=E,UB(E.i,i)))}function IXn(n){var t,e,i,r,c;switch(t=n.c){case 11:return n.Ml();case 12:return n.Ol();case 14:return n.Ql();case 15:return n.Tl();case 16:return n.Rl();case 17:return n.Ul();case 21:return WXn(n),lWn(),lWn(),aNt;case 10:switch(n.a){case 65:return n.yl();case 90:return n.Dl();case 122:return n.Kl();case 98:return n.El();case 66:return n.zl();case 60:return n.Jl();case 62:return n.Hl()}}switch(c=mXn(n),t=n.c){case 3:return n.Zl(c);case 4:return n.Xl(c);case 5:return n.Yl(c);case 0:if(123==n.a&&n.d=48&&t<=57))throw Fp(new rk(mWn((c$(),z8n))));for(i=t-48;r=48&&t<=57;)if((i=10*i+t-48)<0)throw Fp(new rk(mWn((c$(),V8n))));if(e=i,44==t){if(r>=n.j)throw Fp(new rk(mWn((c$(),X8n))));if((t=sV(n.i,r++))>=48&&t<=57){for(e=t-48;r=48&&t<=57;)if((e=10*e+t-48)<0)throw Fp(new rk(mWn((c$(),V8n))));if(i>e)throw Fp(new rk(mWn((c$(),W8n))))}else e=-1}if(125!=t)throw Fp(new rk(mWn((c$(),U8n))));n.sl(r)?(lWn(),lWn(),c=new o4(9,c),n.d=r+1):(lWn(),lWn(),c=new o4(3,c),n.d=r),c.dm(i),c.cm(e),WXn(n)}}return c}function CXn(n,t,e,i,r){var c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M;for(w=new Q6(t.b),v=new Q6(t.b),l=new Q6(t.b),j=new Q6(t.b),d=new Q6(t.b),k=upn(t,0);k.b!=k.d.c;)for(u=new Ub((m=_B(f3(k),11)).g);u.a0,g=m.g.c.length>0,s&&g?l.c[l.c.length]=m:s?w.c[w.c.length]=m:g&&(v.c[v.c.length]=m);for(b=new Ub(w);b.a1)for(b=new ix((!n.a&&(n.a=new nU(ROt,n,6,6)),n.a));b.e!=b.i.gc();)Wjn(b);for(d=I,I>y+m?d=y+m:Ik+w?g=k+w:Cy-m&&dk-w&&gI+P?E=I+P:yC+j?T=C+j:kI-P&&EC-j&&Te&&(f=e-1),(l=L+F$n(t,24)*cJn*h-h/2)<0?l=1:l>r&&(l=r-1),Zj(),yen(c=new ro,f),ken(c,l),s9((!u.a&&(u.a=new OL($Ot,u,5)),u.a),c)}function FXn(){FXn=O,uWn(),dpt=yPt,gpt=kPt,ppt=jPt,vpt=EPt,ypt=TPt,kpt=MPt,Tpt=PPt,Spt=CPt,Ppt=OPt,Mpt=IPt,Ipt=APt,Opt=$Pt,$pt=xPt,Ept=SPt,sWn(),wpt=Rwt,mpt=Kwt,jpt=_wt,Cpt=Fwt,opt=new zA(dPt,tln(0)),spt=Nwt,hpt=xwt,fpt=Dwt,qpt=hdt,xpt=qwt,Dpt=Uwt,_pt=ndt,Rpt=Vwt,Kpt=Jwt,zpt=ddt,Gpt=ldt,Bpt=adt,Fpt=rdt,Hpt=odt,xgt=Mwt,Dgt=Swt,egt=Dbt,igt=_bt,Ggt=new UA(12),qgt=new zA(zSt,Ggt),Ebn(),Jdt=new zA(gSt,Ydt=WPt),Zgt=new zA(rPt,0),lpt=new zA(gPt,tln(1)),kdt=new zA(iSt,bZn),Hgt=qSt,npt=cPt,cpt=lPt,qdt=hSt,mdt=tSt,ugt=kSt,bpt=new zA(mPt,(oN(),!0)),lgt=TSt,bgt=MSt,Kgt=DSt,Bgt=BSt,_gt=KSt,Kfn(),Gdt=new zA(fSt,Udt=_Pt),Ogt=NSt,Cgt=$St,ipt=sPt,ept=oPt,rpt=fPt,ipn(),new zA(JSt,Xgt=BIt),Vgt=nPt,Qgt=tPt,Jgt=ePt,Wgt=ZSt,Npt=Hwt,Mgt=hwt,Tgt=owt,Lpt=Bwt,mgt=nwt,Hdt=jbt,Bdt=ybt,Ldt=cbt,Ndt=abt,Ddt=fbt,xdt=ubt,Fdt=vbt,Pgt=lwt,Igt=bwt,dgt=Xbt,Rgt=Owt,$gt=pwt,cgt=Hbt,Ngt=Ewt,ngt=$bt,tgt=Nbt,$dt=oSt,Agt=wwt,Mdt=Wlt,Tdt=Ult,Edt=zlt,sgt=zbt,ogt=Gbt,hgt=Ubt,Fgt=_St,ggt=ISt,rgt=vSt,Vdt=wSt,Wdt=bSt,Rdt=wbt,tpt=uPt,jdt=uSt,fgt=ESt,Ygt=iPt,zgt=XSt,Ugt=VSt,kgt=iwt,jgt=cwt,upt=wPt,ydt=Glt,Egt=uwt,Qdt=Ibt,Xdt=Sbt,Sgt=OSt,pgt=Jbt,Lgt=ywt,Apt=LPt,zdt=Tbt,apt=$wt,Zdt=Obt,vgt=Zbt,Kdt=gbt,wgt=PSt,ygt=ewt,_dt=pbt,Adt=ibt,Cdt=nbt,Pdt=Ylt,Idt=Zlt,Odt=ebt,Sdt=Qlt,agt=qbt}function BXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(cHn(),T=n.e,w=n.d,r=n.a,0==T)switch(t){case 0:return"0";case 1:return UQn;case 2:return"0.00";case 3:return"0.000";case 4:return"0.0000";case 5:return"0.00000";case 6:return"0.000000";default:return(j=new Sk).a+=t<0?"0E+":"0E",j.a+=-t,j.a}if(y=L8(PNt,UVn,25,1+(m=10*w+1+7),15,1),e=m,1==w)if((u=r[0])<0){I=n0(u,GQn);do{d=I,I=Ijn(I,10),y[--e]=48+bG(tbn(d,ibn(I,10)))&WVn}while(0!=Xhn(I,0))}else{I=u;do{d=I,I=I/10|0,y[--e]=d-10*I+48&WVn}while(0!=I)}else{rHn(r,0,S=L8(INt,oQn,25,w,15,1),0,P=w);n:for(;;){for(E=0,s=P-1;s>=0;s--)p=sTn(ebn(vz(E,32),n0(S[s],GQn))),S[s]=bG(p),E=bG(mz(p,32));v=bG(E),g=e;do{y[--e]=48+v%10&WVn}while(0!=(v=v/10|0)&&0!=e);for(i=9-g+e,o=0;o0;o++)y[--e]=48;for(f=P-1;0==S[f];f--)if(0==f)break n;P=f+1}for(;48==y[e];)++e}if(b=T<0,a=m-e-t-1,0==t)return b&&(y[--e]=45),_dn(y,e,m-e);if(t>0&&a>=-6){if(a>=0){for(h=e+a,l=m-1;l>=h;l--)y[l+1]=y[l];return y[++h]=46,b&&(y[--e]=45),_dn(y,e,m-e+1)}for(f=2;f<1-a;f++)y[--e]=48;return y[--e]=46,y[--e]=48,b&&(y[--e]=45),_dn(y,e,m-e)}return M=e+1,c=m,k=new Pk,b&&(k.a+="-"),c-M>=1?(LX(k,y[e]),k.a+=".",k.a+=_dn(y,e+1,m-e-1)):k.a+=_dn(y,e,m-e),k.a+="E",a>0&&(k.a+="+"),k.a+=""+a,k.a}function HXn(n,t){var e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k;switch(n.c=t,n.g=new Lp,HM(),Zbn(new Mw(new Ny(n.c))),v=TD(JAn(n.c,(EMn(),bTt))),u=_B(JAn(n.c,dTt),316),y=_B(JAn(n.c,gTt),429),c=_B(JAn(n.c,oTt),482),m=_B(JAn(n.c,wTt),430),n.j=Hy(ED(JAn(n.c,pTt))),a=n.a,u.g){case 0:a=n.a;break;case 1:a=n.b;break;case 2:a=n.i;break;case 3:a=n.e;break;case 4:a=n.f;break;default:throw Fp(new Ry($4n+(null!=u.f?u.f:""+u.g)))}if(n.d=new NY(a,y,c),oon(n.d,(zcn(),Wrt),jD(JAn(n.c,hTt))),n.d.c=By(jD(JAn(n.c,sTt))),0==VQ(n.c).i)return n.d;for(h=new CL(VQ(n.c));h.e!=h.i.gc();){for(l=(s=_B(mpn(h),33)).g/2,f=s.f/2,k=new LI(s.i+l,s.j+f);oU(n.g,k);)Rx(k,(i.Math.random()-.5)*hZn,(i.Math.random()-.5)*hZn);w=_B(JAn(s,(uWn(),OSt)),142),d=new CZ(k,new GV(k.a-l-n.j/2-w.b,k.b-f-n.j/2-w.d,s.g+n.j+(w.b+w.c),s.f+n.j+(w.d+w.a))),UB(n.d.i,d),XW(n.g,k,new eC(d,s))}switch(m.g){case 0:if(null==v)n.d.d=_B(Lq(n.d.i,0),65);else for(p=new Ub(n.d.i);p.a1&&e5(f,v,f.c.b,f.c),ptn(c)));v=m}return f}function GXn(n,t,e){var i,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A;for(ITn(e,"Greedy cycle removal",1),A=(m=t.a).c.length,n.a=L8(INt,oQn,25,A,15,1),n.c=L8(INt,oQn,25,A,15,1),n.b=L8(INt,oQn,25,A,15,1),s=0,p=new Ub(m);p.a0?S+1:1);for(a=new Ub(k.g);a.a0?S+1:1)}0==n.c[s]?NH(n.e,d):0==n.a[s]&&NH(n.f,d),++s}for(w=-1,b=1,f=new $p,n.d=_B(pMn(t,(oWn(),Tlt)),230);A>0;){for(;0!=n.e.b;)I=_B(bH(n.e),10),n.b[I.p]=w--,WKn(n,I),--A;for(;0!=n.f.b;)C=_B(bH(n.f),10),n.b[C.p]=b++,WKn(n,C),--A;if(A>0){for(l=RVn,v=new Ub(m);v.a=l&&(y>l&&(f.c=L8(Cnt,FWn,1,0,5,1),l=y),f.c[f.c.length]=d);h=n.Zf(f),n.b[h.p]=b++,WKn(n,h),--A}}for(P=m.c.length+1,s=0;sn.b[O]&&(ZFn(i,!0),oon(t,Bft,(oN(),!0)));n.a=null,n.c=null,n.b=null,vQ(n.f),vQ(n.e),FSn(e)}function zXn(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;for(i=new $p,u=new $p,g=t/2,b=n.gc(),r=_B(n.Xb(0),8),p=_B(n.Xb(1),8),UB(i,(h1(0,(w=WAn(r.a,r.b,p.a,p.b,g)).c.length),_B(w.c[0],8))),UB(u,(h1(1,w.c.length),_B(w.c[1],8))),s=2;s=0;o--)NH(e,(h1(o,a.c.length),_B(a.c[o],8)));return e}function UXn(n){var t,e,i,r,c,a,u,o,s,h,f,l,b;if(a=!0,f=null,i=null,r=null,t=!1,b=vAt,s=null,c=null,(o=Xgn(n,u=0,IAt,CAt))=0&&pK(n.substr(u,"//".length),"//")?(o=Xgn(n,u+=2,OAt,AAt),i=n.substr(u,o-u),u=o):null==f||u!=n.length&&(f1(u,n.length),47==n.charCodeAt(u))||(a=!1,-1==(o=vN(n,VTn(35),u))&&(o=n.length),i=n.substr(u,o-u),u=o);if(!e&&u0&&58==sV(h,h.length-1)&&(r=h,u=o)),u=n.j)return n.a=-1,void(n.c=1);if(t=sV(n.i,n.d++),n.a=t,1!=n.b){switch(t){case 124:i=2;break;case 42:i=3;break;case 43:i=4;break;case 63:i=5;break;case 41:i=7;break;case 46:i=8;break;case 91:i=9;break;case 94:i=11;break;case 36:i=12;break;case 40:if(i=6,n.d>=n.j)break;if(63!=sV(n.i,n.d))break;if(++n.d>=n.j)throw Fp(new rk(mWn((c$(),d8n))));switch(t=sV(n.i,n.d++)){case 58:i=13;break;case 61:i=14;break;case 33:i=15;break;case 91:i=19;break;case 62:i=18;break;case 60:if(n.d>=n.j)throw Fp(new rk(mWn((c$(),d8n))));if(61==(t=sV(n.i,n.d++)))i=16;else{if(33!=t)throw Fp(new rk(mWn((c$(),g8n))));i=17}break;case 35:for(;n.d=n.j)throw Fp(new rk(mWn((c$(),w8n))));n.a=sV(n.i,n.d++);break;default:i=0}n.c=i}else{switch(t){case 92:if(i=10,n.d>=n.j)throw Fp(new rk(mWn((c$(),w8n))));n.a=sV(n.i,n.d++);break;case 45:512==(512&n.e)&&n.d=j||!$dn(v,i))&&(i=e1(t,f)),MZ(v,i),c=new az(JL(sbn(v).a.Kc(),new h));bAn(c);)r=_B(G5(c),17),n.a[r.p]||(g=r.c.i,--n.e[g.p],0==n.e[g.p]&&K8(nMn(w,g)));for(s=f.c.length-1;s>=0;--s)UB(t.b,(h1(s,f.c.length),_B(f.c[s],29)));t.a.c=L8(Cnt,FWn,1,0,5,1),FSn(e)}else FSn(e)}function JXn(n){var t,e,i,r,c,a,u,o;for(n.b=1,WXn(n),t=null,0==n.c&&94==n.a?(WXn(n),lWn(),lWn(),Vxn(t=new E0(4),0,cnt),a=new E0(4)):(lWn(),lWn(),a=new E0(4)),r=!0;1!=(o=n.c);){if(0==o&&93==n.a&&!r){t&&(UGn(t,a),a=t);break}if(e=n.a,i=!1,10==o)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:uHn(a,b_n(e)),i=!0;break;case 105:case 73:case 99:case 67:uHn(a,b_n(e)),(e=-1)<0&&(i=!0);break;case 112:case 80:if(!(u=NCn(n,e)))throw Fp(new rk(mWn((c$(),I8n))));uHn(a,u),i=!0;break;default:e=BDn(n)}else if(24==o&&!r){if(t&&(UGn(t,a),a=t),UGn(a,JXn(n)),0!=n.c||93!=n.a)throw Fp(new rk(mWn((c$(),$8n))));break}if(WXn(n),!i){if(0==o){if(91==e)throw Fp(new rk(mWn((c$(),L8n))));if(93==e)throw Fp(new rk(mWn((c$(),N8n))));if(45==e&&!r&&93!=n.a)throw Fp(new rk(mWn((c$(),x8n))))}if(0!=n.c||45!=n.a||45==e&&r)Vxn(a,e,e);else{if(WXn(n),1==(o=n.c))throw Fp(new rk(mWn((c$(),O8n))));if(0==o&&93==n.a)Vxn(a,e,e),Vxn(a,45,45);else{if(0==o&&93==n.a||24==o)throw Fp(new rk(mWn((c$(),x8n))));if(c=n.a,0==o){if(91==c)throw Fp(new rk(mWn((c$(),L8n))));if(93==c)throw Fp(new rk(mWn((c$(),N8n))));if(45==c)throw Fp(new rk(mWn((c$(),x8n))))}else 10==o&&(c=BDn(n));if(WXn(n),e>c)throw Fp(new rk(mWn((c$(),K8n))));Vxn(a,e,c)}}}r=!1}if(1==n.c)throw Fp(new rk(mWn((c$(),O8n))));return j$n(a),BHn(a),n.b=0,WXn(n),a}function YXn(n){X$n(n.c,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#decimal"])),X$n(n.d,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#integer"])),X$n(n.e,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#boolean"])),X$n(n.f,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EBoolean",Z6n,"EBoolean:Object"])),X$n(n.i,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#byte"])),X$n(n.g,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#hexBinary"])),X$n(n.j,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EByte",Z6n,"EByte:Object"])),X$n(n.n,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EChar",Z6n,"EChar:Object"])),X$n(n.t,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#double"])),X$n(n.u,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EDouble",Z6n,"EDouble:Object"])),X$n(n.F,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#float"])),X$n(n.G,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EFloat",Z6n,"EFloat:Object"])),X$n(n.I,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#int"])),X$n(n.J,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EInt",Z6n,"EInt:Object"])),X$n(n.N,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#long"])),X$n(n.O,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"ELong",Z6n,"ELong:Object"])),X$n(n.Z,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#short"])),X$n(n.$,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"EShort",Z6n,"EShort:Object"])),X$n(n._,R9n,Mun(Hk(Wtt,1),uVn,2,6,[Q9n,"http://www.w3.org/2001/XMLSchema#string"]))}function ZXn(n){var t,e,r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(1==n.c.length)return h1(0,n.c.length),_B(n.c[0],135);if(n.c.length<=0)return new M6;for(s=new Ub(n);s.al&&(P=0,I+=f+E,f=0),kLn(k,u,P,I),t=i.Math.max(t,P+j.a),f=i.Math.max(f,j.b),P+=j.a+E;for(y=new Lp,e=new Lp,M=new Ub(n);M.ag$n(c))&&(f=c);for(!f&&(h1(0,d.c.length),f=_B(d.c[0],180)),w=new Ub(t.b);w.a=-1900?1:0,aO(n,e>=4?Mun(Hk(Wtt,1),uVn,2,6,[sQn,hQn])[a]:Mun(Hk(Wtt,1),uVn,2,6,["BC","AD"])[a]);break;case 121:apn(n,e,i);break;case 77:zKn(n,e,i);break;case 107:knn(n,0==(u=r.q.getHours())?24:u,e);break;case 83:xLn(n,e,r);break;case 69:o=i.q.getDay(),aO(n,5==e?Mun(Hk(Wtt,1),uVn,2,6,["S","M","T","W","T","F","S"])[o]:4==e?Mun(Hk(Wtt,1),uVn,2,6,[fQn,lQn,bQn,wQn,dQn,gQn,pQn])[o]:Mun(Hk(Wtt,1),uVn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[o]);break;case 97:r.q.getHours()>=12&&r.q.getHours()<24?aO(n,Mun(Hk(Wtt,1),uVn,2,6,["AM","PM"])[1]):aO(n,Mun(Hk(Wtt,1),uVn,2,6,["AM","PM"])[0]);break;case 104:knn(n,0==(s=r.q.getHours()%12)?12:s,e);break;case 75:knn(n,r.q.getHours()%12,e);break;case 72:knn(n,r.q.getHours(),e);break;case 99:h=i.q.getDay(),5==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,["S","M","T","W","T","F","S"])[h]):4==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,[fQn,lQn,bQn,wQn,dQn,gQn,pQn])[h]):3==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,["Sun","Mon","Tue","Wed","Thu","Fri","Sat"])[h]):knn(n,h,1);break;case 76:f=i.q.getMonth(),5==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,["J","F","M","A","M","J","J","A","S","O","N","D"])[f]):4==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,[VVn,QVn,JVn,YVn,ZVn,nQn,tQn,eQn,iQn,rQn,cQn,aQn])[f]):3==e?aO(n,Mun(Hk(Wtt,1),uVn,2,6,["Jan","Feb","Mar","Apr",ZVn,"Jun","Jul","Aug","Sep","Oct","Nov","Dec"])[f]):knn(n,f+1,e);break;case 81:l=i.q.getMonth()/3|0,aO(n,e<4?Mun(Hk(Wtt,1),uVn,2,6,["Q1","Q2","Q3","Q4"])[l]:Mun(Hk(Wtt,1),uVn,2,6,["1st quarter","2nd quarter","3rd quarter","4th quarter"])[l]);break;case 100:knn(n,i.q.getDate(),e);break;case 109:knn(n,r.q.getMinutes(),e);break;case 115:knn(n,r.q.getSeconds(),e);break;case 122:aO(n,e<4?c.c[0]:c.c[1]);break;case 118:aO(n,c.b);break;case 90:aO(n,e<3?YIn(c):3==e?lCn(c):bCn(c.a));break;default:return!1}return!0}function cWn(n,t,e,i){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I;if(ZRn(t),o=_B(Utn((!t.b&&(t.b=new oK(xOt,t,4,7)),t.b),0),82),h=_B(Utn((!t.c&&(t.c=new oK(xOt,t,5,8)),t.c),0),82),u=MTn(o),s=MTn(h),a=0==(!t.a&&(t.a=new nU(ROt,t,6,6)),t.a).i?null:_B(Utn((!t.a&&(t.a=new nU(ROt,t,6,6)),t.a),0),202),j=_B(xX(n.a,u),10),S=_B(xX(n.a,s),10),E=null,P=null,iL(o,186)&&(iL(k=_B(xX(n.a,o),299),11)?E=_B(k,11):iL(k,10)&&(j=_B(k,10),E=_B(Lq(j.j,0),11))),iL(h,186)&&(iL(M=_B(xX(n.a,h),299),11)?P=_B(M,11):iL(M,10)&&(S=_B(M,10),P=_B(Lq(S.j,0),11))),!j||!S)throw Fp(new ik("The source or the target of edge "+t+" could not be found. This usually happens when an edge connects a node laid out by ELK Layered to a node in another level of hierarchy laid out by either another instance of ELK Layered or another layout algorithm alltogether. The former can be solved by setting the hierarchyHandling option to INCLUDE_CHILDREN."));for(Ban(d=new lJ,t),oon(d,(oWn(),blt),t),oon(d,(FXn(),ggt),null),b=_B(pMn(i,Jft),21),j==S&&b.Fc((fDn(),gft)),E||(rin(),y=Bvt,T=null,a&&gA(_B(pMn(j,npt),98))&&(V3(T=new LI(a.j,a.k),zY(t)),Z4(T,e),Stn(s,u)&&(y=Fvt,GR(T,j.n))),E=bHn(j,T,y,i)),P||(rin(),y=Fvt,I=null,a&&gA(_B(pMn(S,npt),98))&&(V3(I=new LI(a.b,a.c),zY(t)),Z4(I,e)),P=bHn(S,I,y,gW(S))),TZ(d,E),EZ(d,P),(E.e.c.length>1||E.g.c.length>1||P.e.c.length>1||P.g.c.length>1)&&b.Fc((fDn(),fft)),l=new CL((!t.n&&(t.n=new nU(HOt,t,1,7)),t.n));l.e!=l.i.gc();)if(!By(jD(JAn(f=_B(mpn(l),137),Hgt)))&&f.a)switch(g=Fhn(f),UB(d.b,g),_B(pMn(g,Vdt),272).g){case 1:case 2:b.Fc((fDn(),sft));break;case 0:b.Fc((fDn(),uft)),oon(g,Vdt,(xtn(),qPt))}if(c=_B(pMn(i,Bdt),314),p=_B(pMn(i,Rgt),315),r=c==(Iin(),uht)||p==($vn(),dvt),a&&0!=(!a.a&&(a.a=new OL($Ot,a,5)),a.a).i&&r){for(v=BSn(a),w=new mm,m=upn(v,0);m.b!=m.d.c;)NH(w,new lA(_B(f3(m),8)));oon(d,wlt,w)}return d}function aWn(n){n.gb||(n.gb=!0,n.b=man(n,0),xrn(n.b,18),Drn(n.b,19),n.a=man(n,1),xrn(n.a,1),Drn(n.a,2),Drn(n.a,3),Drn(n.a,4),Drn(n.a,5),n.o=man(n,2),xrn(n.o,8),xrn(n.o,9),Drn(n.o,10),Drn(n.o,11),Drn(n.o,12),Drn(n.o,13),Drn(n.o,14),Drn(n.o,15),Drn(n.o,16),Drn(n.o,17),Drn(n.o,18),Drn(n.o,19),Drn(n.o,20),Drn(n.o,21),Drn(n.o,22),Drn(n.o,23),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),atn(n.o),n.p=man(n,3),xrn(n.p,2),xrn(n.p,3),xrn(n.p,4),xrn(n.p,5),Drn(n.p,6),Drn(n.p,7),atn(n.p),atn(n.p),n.q=man(n,4),xrn(n.q,8),n.v=man(n,5),Drn(n.v,9),atn(n.v),atn(n.v),atn(n.v),n.w=man(n,6),xrn(n.w,2),xrn(n.w,3),xrn(n.w,4),Drn(n.w,5),n.B=man(n,7),Drn(n.B,1),atn(n.B),atn(n.B),atn(n.B),n.Q=man(n,8),Drn(n.Q,0),atn(n.Q),n.R=man(n,9),xrn(n.R,1),n.S=man(n,10),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),atn(n.S),n.T=man(n,11),Drn(n.T,10),Drn(n.T,11),Drn(n.T,12),Drn(n.T,13),Drn(n.T,14),atn(n.T),atn(n.T),n.U=man(n,12),xrn(n.U,2),xrn(n.U,3),Drn(n.U,4),Drn(n.U,5),Drn(n.U,6),Drn(n.U,7),atn(n.U),n.V=man(n,13),Drn(n.V,10),n.W=man(n,14),xrn(n.W,18),xrn(n.W,19),xrn(n.W,20),Drn(n.W,21),Drn(n.W,22),Drn(n.W,23),n.bb=man(n,15),xrn(n.bb,10),xrn(n.bb,11),xrn(n.bb,12),xrn(n.bb,13),xrn(n.bb,14),xrn(n.bb,15),xrn(n.bb,16),Drn(n.bb,17),atn(n.bb),atn(n.bb),n.eb=man(n,16),xrn(n.eb,2),xrn(n.eb,3),xrn(n.eb,4),xrn(n.eb,5),xrn(n.eb,6),xrn(n.eb,7),Drn(n.eb,8),Drn(n.eb,9),n.ab=man(n,17),xrn(n.ab,0),xrn(n.ab,1),n.H=man(n,18),Drn(n.H,0),Drn(n.H,1),Drn(n.H,2),Drn(n.H,3),Drn(n.H,4),Drn(n.H,5),atn(n.H),n.db=man(n,19),Drn(n.db,2),n.c=yan(n,20),n.d=yan(n,21),n.e=yan(n,22),n.f=yan(n,23),n.i=yan(n,24),n.g=yan(n,25),n.j=yan(n,26),n.k=yan(n,27),n.n=yan(n,28),n.r=yan(n,29),n.s=yan(n,30),n.t=yan(n,31),n.u=yan(n,32),n.fb=yan(n,33),n.A=yan(n,34),n.C=yan(n,35),n.D=yan(n,36),n.F=yan(n,37),n.G=yan(n,38),n.I=yan(n,39),n.J=yan(n,40),n.L=yan(n,41),n.M=yan(n,42),n.N=yan(n,43),n.O=yan(n,44),n.P=yan(n,45),n.X=yan(n,46),n.Y=yan(n,47),n.Z=yan(n,48),n.$=yan(n,49),n._=yan(n,50),n.cb=yan(n,51),n.K=yan(n,52))}function uWn(){var n,t;uWn=O,nSt=new cp(l5n),pPt=new cp(b5n),lvn(),tSt=new OO(U2n,eSt=SMt),new Op,iSt=new OO(XYn,null),rSt=new cp(w5n),lEn(),sSt=kG(JMt,Mun(Hk(BPt,1),OVn,291,0,[XMt])),oSt=new OO(c3n,sSt),hSt=new OO(z2n,(oN(),!1)),Kfn(),fSt=new OO(Q2n,lSt=_Pt),Ebn(),gSt=new OO(v2n,pSt=JPt),ySt=new OO(C4n,!1),cfn(),kSt=new OO(b2n,jSt=gIt),USt=new UA(12),zSt=new OO(WYn,USt),SSt=new OO(yZn,!1),PSt=new OO(p3n,!1),GSt=new OO(EZn,!1),WEn(),cPt=new OO(kZn,aPt=VIt),wPt=new cp(w3n),dPt=new cp(dZn),gPt=new cp(vZn),mPt=new cp(mZn),CSt=new mm,ISt=new OO(a3n,CSt),uSt=new OO(s3n,!1),ESt=new OO(h3n,!1),new cp(d5n),ASt=new hm,OSt=new OO(d3n,ASt),qSt=new OO(q2n,!1),new Op,vPt=new OO(g5n,1),new OO(p5n,!0),tln(0),new OO(v5n,tln(100)),new OO(m5n,!1),tln(0),new OO(y5n,tln(4e3)),tln(0),new OO(k5n,tln(400)),new OO(j5n,!1),new OO(E5n,!1),new OO(T5n,!0),new OO(M5n,!1),Kwn(),cSt=new OO(f5n,aSt=nOt),yPt=new OO(A2n,10),kPt=new OO($2n,10),jPt=new OO(zYn,20),EPt=new OO(L2n,10),TPt=new OO(pZn,2),MPt=new OO(N2n,10),PPt=new OO(x2n,0),IPt=new OO(K2n,5),CPt=new OO(D2n,1),OPt=new OO(R2n,1),APt=new OO(gZn,20),$Pt=new OO(_2n,10),xPt=new OO(F2n,10),SPt=new cp(B2n),NPt=new hA,LPt=new OO(g3n,NPt),VSt=new cp(b3n),XSt=new OO(l3n,WSt=!1),LSt=new UA(5),$St=new OO(J2n,LSt),YAn(),t=_B(Xj(HIt),9),xSt=new VK(t,_B(TR(t,t.length),9),0),NSt=new OO(SZn,xSt),ipn(),JSt=new OO(n3n,YSt=_It),nPt=new cp(t3n),tPt=new cp(e3n),ePt=new cp(i3n),ZSt=new cp(r3n),n=_B(Xj(VCt),9),RSt=new VK(n,_B(TR(n,n.length),9),0),DSt=new OO(MZn,RSt),HSt=Yln((YKn(),HCt)),BSt=new OO(TZn,HSt),FSt=new LI(0,0),_St=new OO(_Zn,FSt),KSt=new OO(V2n,!1),xtn(),wSt=new OO(u3n,dSt=qPt),bSt=new OO(jZn,!1),new cp(S5n),tln(1),new OO(P5n,null),iPt=new cp(f3n),uPt=new cp(o3n),mUn(),lPt=new OO(G2n,bPt=MCt),rPt=new cp(H2n),hCn(),hPt=Yln(eCt),sPt=new OO(PZn,hPt),oPt=new OO(Y2n,!1),fPt=new OO(Z2n,!0),TSt=new OO(X2n,!1),MSt=new OO(W2n,!1),vSt=new OO(UYn,1),YTn(),new OO(I5n,mSt=rIt),QSt=!0}function oWn(){var n,t;oWn=O,blt=new cp(IZn),Kft=new cp("coordinateOrigin"),Elt=new cp("processors"),Rft=new tR("compoundNode",(oN(),!1)),nlt=new tR("insideConnections",!1),wlt=new cp("originalBendpoints"),dlt=new cp("originalDummyNodePosition"),glt=new cp("originalLabelEdge"),Mlt=new cp("representedLabels"),qft=new cp("endLabels"),Gft=new cp("endLabel.origin"),clt=new tR("labelSide",(zyn(),EIt)),flt=new tR("maxEdgeThickness",0),Slt=new tR("reversed",!1),Tlt=new cp(CZn),olt=new tR("longEdgeSource",null),slt=new tR("longEdgeTarget",null),ult=new tR("longEdgeHasLabelDummies",!1),alt=new tR("longEdgeBeforeLabelDummy",!1),Hft=new tR("edgeConstraint",(Qun(),Cht)),elt=new cp("inLayerLayoutUnit"),tlt=new tR("inLayerConstraint",(q7(),Mft)),ilt=new tR("inLayerSuccessorConstraint",new $p),rlt=new tR("inLayerSuccessorConstraintBetweenNonDummies",!1),klt=new cp("portDummy"),_ft=new tR("crossingHint",tln(0)),Jft=new tR("graphProperties",new VK(t=_B(Xj(jft),9),_B(TR(t,t.length),9),0)),Wft=new tR("externalPortSide",(mUn(),MCt)),Vft=new tR("externalPortSize",new Hj),Uft=new cp("externalPortReplacedDummies"),Xft=new cp("externalPortReplacedDummy"),zft=new tR("externalPortConnections",new VK(n=_B(Xj(KCt),9),_B(TR(n,n.length),9),0)),jlt=new tR(bYn,0),Lft=new cp("barycenterAssociates"),Dlt=new cp("TopSideComments"),Nft=new cp("BottomSideComments"),Dft=new cp("CommentConnectionPort"),Zft=new tR("inputCollect",!1),mlt=new tR("outputCollect",!1),Bft=new tR("cyclic",!1),Fft=new cp("crossHierarchyMap"),xlt=new cp("targetOffset"),new tR("splineLabelSize",new Hj),Clt=new cp("spacings"),ylt=new tR("partitionConstraint",!1),xft=new cp("breakingPoint.info"),Llt=new cp("splines.survivingEdge"),$lt=new cp("splines.route.start"),Olt=new cp("splines.edgeChain"),vlt=new cp("originalPortConstraints"),Ilt=new cp("selfLoopHolder"),Alt=new cp("splines.nsPortY"),llt=new cp("modelOrder"),hlt=new cp("longEdgeTargetNode"),Qft=new tR(q1n,!1),Plt=new tR(q1n,!1),Yft=new cp("layerConstraints.hiddenNodes"),plt=new cp("layerConstraints.opposidePort"),Nlt=new cp("targetNode.modelOrder")}function sWn(){sWn=O,Rnn(),Tbt=new OO(G1n,Mbt=Tht),Hbt=new OO(z1n,(oN(),!1)),q2(),Xbt=new OO(U1n,Wbt=Cft),lwt=new OO(X1n,!1),bwt=new OO(W1n,!0),Glt=new OO(V1n,!1),G7(),$wt=new OO(Q1n,Lwt=Dvt),tln(1),Bwt=new OO(J1n,tln(7)),Hwt=new OO(Y1n,!1),qbt=new OO(Z1n,!1),Xvn(),jbt=new OO(n0n,Ebt=vht),jTn(),hwt=new OO(t0n,fwt=Zpt),jbn(),nwt=new OO(e0n,twt=Blt),tln(-1),Zbt=new OO(i0n,tln(-1)),tln(-1),ewt=new OO(r0n,tln(-1)),tln(-1),iwt=new OO(c0n,tln(4)),tln(-1),cwt=new OO(a0n,tln(2)),uNn(),owt=new OO(u0n,swt=Pvt),tln(0),uwt=new OO(o0n,tln(0)),Jbt=new OO(s0n,tln(NWn)),Iin(),ybt=new OO(h0n,kbt=oht),cbt=new OO(f0n,!1),wbt=new OO(l0n,.1),vbt=new OO(b0n,!1),tln(-1),gbt=new OO(w0n,tln(-1)),tln(-1),pbt=new OO(d0n,tln(-1)),tln(0),abt=new OO(g0n,tln(40)),Dan(),fbt=new OO(p0n,lbt=kft),ubt=new OO(v0n,obt=mft),$vn(),Owt=new OO(m0n,Awt=wvt),ywt=new cp(y0n),w7(),wwt=new OO(k0n,dwt=Bht),_jn(),pwt=new OO(j0n,vwt=Wht),new Op,Ewt=new OO(E0n,.3),Mwt=new cp(T0n),fvn(),Swt=new OO(M0n,Pwt=hvt),Fcn(),$bt=new OO(S0n,Lbt=Uvt),C6(),Nbt=new OO(P0n,xbt=Jvt),Gsn(),Dbt=new OO(I0n,Rbt=emt),_bt=new OO(C0n,.2),Obt=new OO(O0n,2),Rwt=new OO(A0n,null),_wt=new OO($0n,10),Kwt=new OO(L0n,10),Fwt=new OO(N0n,20),tln(0),Nwt=new OO(x0n,tln(0)),tln(0),xwt=new OO(D0n,tln(0)),tln(0),Dwt=new OO(R0n,tln(0)),zlt=new OO(K0n,!1),QMn(),Wlt=new OO(_0n,Vlt=ift),X8(),Ult=new OO(F0n,Xlt=rht),zbt=new OO(B0n,!1),tln(0),Gbt=new OO(H0n,tln(16)),tln(0),Ubt=new OO(q0n,tln(5)),Oun(),hdt=new OO(G0n,fdt=fmt),qwt=new OO(z0n,10),Uwt=new OO(U0n,1),cin(),ndt=new OO(X0n,tdt=wht),Vwt=new cp(W0n),Ywt=tln(1),tln(0),Jwt=new OO(V0n,Ywt),bcn(),ddt=new OO(Q0n,gdt=cmt),ldt=new cp(J0n),adt=new OO(Y0n,!0),rdt=new OO(Z0n,2),odt=new OO(n2n,!0),wSn(),Ibt=new OO(t2n,Cbt=Rht),OPn(),Sbt=new OO(e2n,Pbt=Jst),pon(),ibt=new OO(i2n,rbt=$vt),ebt=new OO(r2n,!1),_fn(),Qlt=new OO(c2n,Jlt=lut),Ehn(),nbt=new OO(a2n,tbt=ivt),Ylt=new OO(u2n,0),Zlt=new OO(o2n,0),Qbt=yht,Vbt=uht,rwt=Ypt,awt=Ypt,Ybt=Vpt,cfn(),dbt=dIt,mbt=oht,bbt=oht,sbt=oht,hbt=dIt,kwt=pvt,jwt=wvt,gwt=wvt,mwt=wvt,Twt=gvt,Cwt=pvt,Iwt=pvt,Ebn(),Kbt=QPt,Fbt=QPt,Bbt=emt,Abt=VPt,Gwt=lmt,zwt=hmt,Xwt=lmt,Wwt=hmt,edt=lmt,idt=hmt,Qwt=bht,Zwt=wht,pdt=lmt,vdt=hmt,bdt=lmt,wdt=hmt,udt=hmt,cdt=hmt,sdt=hmt}function hWn(){hWn=O,eot=new YS("DIRECTION_PREPROCESSOR",0),Zut=new YS("COMMENT_PREPROCESSOR",1),iot=new YS("EDGE_AND_LAYER_CONSTRAINT_EDGE_REVERSER",2),mot=new YS("INTERACTIVE_EXTERNAL_PORT_POSITIONER",3),Kot=new YS("PARTITION_PREPROCESSOR",4),Eot=new YS("LABEL_DUMMY_INSERTER",5),Got=new YS("SELF_LOOP_PREPROCESSOR",6),Iot=new YS("LAYER_CONSTRAINT_PREPROCESSOR",7),Dot=new YS("PARTITION_MIDPROCESSOR",8),wot=new YS("HIGH_DEGREE_NODE_LAYER_PROCESSOR",9),$ot=new YS("NODE_PROMOTION",10),Pot=new YS("LAYER_CONSTRAINT_POSTPROCESSOR",11),Rot=new YS("PARTITION_POSTPROCESSOR",12),hot=new YS("HIERARCHICAL_PORT_CONSTRAINT_PROCESSOR",13),Uot=new YS("SEMI_INTERACTIVE_CROSSMIN_PROCESSOR",14),Xut=new YS("BREAKING_POINT_INSERTER",15),Aot=new YS("LONG_EDGE_SPLITTER",16),Fot=new YS("PORT_SIDE_PROCESSOR",17),yot=new YS("INVERTED_PORT_PROCESSOR",18),_ot=new YS("PORT_LIST_SORTER",19),Wot=new YS("SORT_BY_INPUT_ORDER_OF_MODEL",20),Not=new YS("NORTH_SOUTH_PORT_PREPROCESSOR",21),Wut=new YS("BREAKING_POINT_PROCESSOR",22),xot=new YS(k1n,23),Vot=new YS(j1n,24),Hot=new YS("SELF_LOOP_PORT_RESTORER",25),Xot=new YS("SINGLE_EDGE_GRAPH_WRAPPER",26),kot=new YS("IN_LAYER_CONSTRAINT_PROCESSOR",27),uot=new YS("END_NODE_PORT_LABEL_MANAGEMENT_PROCESSOR",28),jot=new YS("LABEL_AND_NODE_SIZE_PROCESSOR",29),vot=new YS("INNERMOST_NODE_MARGIN_CALCULATOR",30),zot=new YS("SELF_LOOP_ROUTER",31),Jut=new YS("COMMENT_NODE_MARGIN_CALCULATOR",32),cot=new YS("END_LABEL_PREPROCESSOR",33),Mot=new YS("LABEL_DUMMY_SWITCHER",34),Qut=new YS("CENTER_LABEL_MANAGEMENT_PROCESSOR",35),Sot=new YS("LABEL_SIDE_SELECTOR",36),got=new YS("HYPEREDGE_DUMMY_MERGER",37),fot=new YS("HIERARCHICAL_PORT_DUMMY_SIZE_PROCESSOR",38),Cot=new YS("LAYER_SIZE_AND_GRAPH_HEIGHT_CALCULATOR",39),bot=new YS("HIERARCHICAL_PORT_POSITION_PROCESSOR",40),not=new YS("CONSTRAINTS_POSTPROCESSOR",41),Yut=new YS("COMMENT_POSTPROCESSOR",42),pot=new YS("HYPERNODE_PROCESSOR",43),lot=new YS("HIERARCHICAL_PORT_ORTHOGONAL_EDGE_ROUTER",44),Oot=new YS("LONG_EDGE_JOINER",45),qot=new YS("SELF_LOOP_POSTPROCESSOR",46),Vut=new YS("BREAKING_POINT_REMOVER",47),Lot=new YS("NORTH_SOUTH_PORT_POSTPROCESSOR",48),dot=new YS("HORIZONTAL_COMPACTOR",49),Tot=new YS("LABEL_DUMMY_REMOVER",50),oot=new YS("FINAL_SPLINE_BENDPOINTS_CALCULATOR",51),aot=new YS("END_LABEL_SORTER",52),Bot=new YS("REVERSED_EDGE_RESTORER",53),rot=new YS("END_LABEL_POSTPROCESSOR",54),sot=new YS("HIERARCHICAL_NODE_RESIZER",55),tot=new YS("DIRECTION_POSTPROCESSOR",56)}function fWn(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g,p,v,m,y,k,j,E,T,M,S,P,I,C,O,A,$,L,N,x,D,R,K,_,F,B,H,q,G,z,U,X,W,V,Q,J,Y,Z,nn,tn,en,rn,cn,an,un,on;for(Y=0,L=0,D=(O=t).length;L0&&(n.a[q.p]=Y++)}for(rn=0,N=0,R=(A=e).length;N0;){for(Mx(X.b>0),U=0,o=new Ub((q=_B(X.a.Xb(X.c=--X.b),11)).e);o.a0&&(q.j==(mUn(),uCt)?(n.a[q.p]=rn,++rn):(n.a[q.p]=rn+K+F,++F))}rn+=F}for(z=new Lp,d=new sA,$=0,x=(C=t).length;$h.b&&(h.b=W)):q.i.c==J&&(Wh.c&&(h.c=W));for(q9(g,0,g.length,null),en=L8(INt,oQn,25,g.length,15,1),r=L8(INt,oQn,25,rn+1,15,1),v=0;v0;)T%2>0&&(c+=un[T+1]),++un[T=(T-1)/2|0];for(S=L8(Bmt,FWn,362,2*g.length,0,1),k=0;k'?":pK(g8n,n)?"'(?<' or '(? toIndex: ",mJn=", toIndex: ",yJn="Index: ",kJn=", Size: ",jJn="org.eclipse.elk.alg.common",EJn={62:1},TJn="org.eclipse.elk.alg.common.compaction",MJn="Scanline/EventHandler",SJn="org.eclipse.elk.alg.common.compaction.oned",PJn="CNode belongs to another CGroup.",IJn="ISpacingsHandler/1",CJn="The ",OJn=" instance has been finished already.",AJn="The direction ",$Jn=" is not supported by the CGraph instance.",LJn="OneDimensionalCompactor",NJn="OneDimensionalCompactor/lambda$0$Type",xJn="Quadruplet",DJn="ScanlineConstraintCalculator",RJn="ScanlineConstraintCalculator/ConstraintsScanlineHandler",KJn="ScanlineConstraintCalculator/ConstraintsScanlineHandler/lambda$0$Type",_Jn="ScanlineConstraintCalculator/Timestamp",FJn="ScanlineConstraintCalculator/lambda$0$Type",BJn={169:1,45:1},HJn="org.eclipse.elk.alg.common.compaction.options",qJn="org.eclipse.elk.core.data",GJn="org.eclipse.elk.polyomino.traversalStrategy",zJn="org.eclipse.elk.polyomino.lowLevelSort",UJn="org.eclipse.elk.polyomino.highLevelSort",XJn="org.eclipse.elk.polyomino.fill",WJn={130:1},VJn="polyomino",QJn="org.eclipse.elk.alg.common.networksimplex",JJn={177:1,3:1,4:1},YJn="org.eclipse.elk.alg.common.nodespacing",ZJn="org.eclipse.elk.alg.common.nodespacing.cellsystem",nYn="CENTER",tYn={212:1,326:1},eYn={3:1,4:1,5:1,595:1},iYn="LEFT",rYn="RIGHT",cYn="Vertical alignment cannot be null",aYn="BOTTOM",uYn="org.eclipse.elk.alg.common.nodespacing.internal",oYn="UNDEFINED",sYn=.01,hYn="org.eclipse.elk.alg.common.nodespacing.internal.algorithm",fYn="LabelPlacer/lambda$0$Type",lYn="LabelPlacer/lambda$1$Type",bYn="portRatioOrPosition",wYn="org.eclipse.elk.alg.common.overlaps",dYn="DOWN",gYn="org.eclipse.elk.alg.common.polyomino",pYn="NORTH",vYn="EAST",mYn="SOUTH",yYn="WEST",kYn="org.eclipse.elk.alg.common.polyomino.structures",jYn="Direction",EYn="Grid is only of size ",TYn=". Requested point (",MYn=") is out of bounds.",SYn=" Given center based coordinates were (",PYn="org.eclipse.elk.graph.properties",IYn="IPropertyHolder",CYn={3:1,94:1,134:1},OYn="org.eclipse.elk.alg.common.spore",AYn="org.eclipse.elk.alg.common.utils",$Yn={209:1},LYn="org.eclipse.elk.core",NYn="Connected Components Compaction",xYn="org.eclipse.elk.alg.disco",DYn="org.eclipse.elk.alg.disco.graph",RYn="org.eclipse.elk.alg.disco.options",KYn="CompactionStrategy",_Yn="org.eclipse.elk.disco.componentCompaction.strategy",FYn="org.eclipse.elk.disco.componentCompaction.componentLayoutAlgorithm",BYn="org.eclipse.elk.disco.debug.discoGraph",HYn="org.eclipse.elk.disco.debug.discoPolys",qYn="componentCompaction",GYn="org.eclipse.elk.disco",zYn="org.eclipse.elk.spacing.componentComponent",UYn="org.eclipse.elk.edge.thickness",XYn="org.eclipse.elk.aspectRatio",WYn="org.eclipse.elk.padding",VYn="org.eclipse.elk.alg.disco.transform",QYn=1.5707963267948966,JYn=17976931348623157e292,YYn={3:1,4:1,5:1,192:1},ZYn={3:1,6:1,4:1,5:1,106:1,120:1},nZn="org.eclipse.elk.alg.force",tZn="ComponentsProcessor",eZn="ComponentsProcessor/1",iZn="org.eclipse.elk.alg.force.graph",rZn="Component Layout",cZn="org.eclipse.elk.alg.force.model",aZn="org.eclipse.elk.force.model",uZn="org.eclipse.elk.force.iterations",oZn="org.eclipse.elk.force.repulsivePower",sZn="org.eclipse.elk.force.temperature",hZn=.001,fZn="org.eclipse.elk.force.repulsion",lZn="org.eclipse.elk.alg.force.options",bZn=1.600000023841858,wZn="org.eclipse.elk.force",dZn="org.eclipse.elk.priority",gZn="org.eclipse.elk.spacing.nodeNode",pZn="org.eclipse.elk.spacing.edgeLabel",vZn="org.eclipse.elk.randomSeed",mZn="org.eclipse.elk.separateConnectedComponents",yZn="org.eclipse.elk.interactive",kZn="org.eclipse.elk.portConstraints",jZn="org.eclipse.elk.edgeLabels.inline",EZn="org.eclipse.elk.omitNodeMicroLayout",TZn="org.eclipse.elk.nodeSize.options",MZn="org.eclipse.elk.nodeSize.constraints",SZn="org.eclipse.elk.nodeLabels.placement",PZn="org.eclipse.elk.portLabels.placement",IZn="origin",CZn="random",OZn="boundingBox.upLeft",AZn="boundingBox.lowRight",$Zn="org.eclipse.elk.stress.fixed",LZn="org.eclipse.elk.stress.desiredEdgeLength",NZn="org.eclipse.elk.stress.dimension",xZn="org.eclipse.elk.stress.epsilon",DZn="org.eclipse.elk.stress.iterationLimit",RZn="org.eclipse.elk.stress",KZn="ELK Stress",_Zn="org.eclipse.elk.nodeSize.minimum",FZn="org.eclipse.elk.alg.force.stress",BZn="Layered layout",HZn="org.eclipse.elk.alg.layered",qZn="org.eclipse.elk.alg.layered.compaction.components",GZn="org.eclipse.elk.alg.layered.compaction.oned",zZn="org.eclipse.elk.alg.layered.compaction.oned.algs",UZn="org.eclipse.elk.alg.layered.compaction.recthull",XZn="org.eclipse.elk.alg.layered.components",WZn="NONE",VZn={3:1,6:1,4:1,9:1,5:1,122:1},QZn={3:1,6:1,4:1,5:1,141:1,106:1,120:1},JZn="org.eclipse.elk.alg.layered.compound",YZn={51:1},ZZn="org.eclipse.elk.alg.layered.graph",n1n=" -> ",t1n="Not supported by LGraph",e1n="Port side is undefined",i1n={3:1,6:1,4:1,5:1,474:1,141:1,106:1,120:1},r1n={3:1,6:1,4:1,5:1,141:1,193:1,203:1,106:1,120:1},c1n={3:1,6:1,4:1,5:1,141:1,1943:1,203:1,106:1,120:1},a1n="([{\"' \t\r\n",u1n=")]}\"' \t\r\n",o1n="The given string contains parts that cannot be parsed as numbers.",s1n="org.eclipse.elk.core.math",h1n={3:1,4:1,142:1,207:1,414:1},f1n={3:1,4:1,116:1,207:1,414:1},l1n="org.eclipse.elk.layered",b1n="org.eclipse.elk.alg.layered.graph.transform",w1n="ElkGraphImporter",d1n="ElkGraphImporter/lambda$0$Type",g1n="ElkGraphImporter/lambda$1$Type",p1n="ElkGraphImporter/lambda$2$Type",v1n="ElkGraphImporter/lambda$4$Type",m1n="Node margin calculation",y1n="org.eclipse.elk.alg.layered.intermediate",k1n="ONE_SIDED_GREEDY_SWITCH",j1n="TWO_SIDED_GREEDY_SWITCH",E1n="No implementation is available for the layout processor ",T1n="IntermediateProcessorStrategy",M1n="Node '",S1n="FIRST_SEPARATE",P1n="LAST_SEPARATE",I1n="Odd port side processing",C1n="org.eclipse.elk.alg.layered.intermediate.compaction",O1n="org.eclipse.elk.alg.layered.intermediate.greedyswitch",A1n="org.eclipse.elk.alg.layered.p3order.counting",$1n={225:1},L1n="org.eclipse.elk.alg.layered.intermediate.loops",N1n="org.eclipse.elk.alg.layered.intermediate.loops.ordering",x1n="org.eclipse.elk.alg.layered.intermediate.loops.routing",D1n="org.eclipse.elk.alg.layered.intermediate.preserveorder",R1n="org.eclipse.elk.alg.layered.intermediate.wrapping",K1n="org.eclipse.elk.alg.layered.options",_1n="INTERACTIVE",F1n="DEPTH_FIRST",B1n="EDGE_LENGTH",H1n="SELF_LOOPS",q1n="firstTryWithInitialOrder",G1n="org.eclipse.elk.layered.directionCongruency",z1n="org.eclipse.elk.layered.feedbackEdges",U1n="org.eclipse.elk.layered.interactiveReferencePoint",X1n="org.eclipse.elk.layered.mergeEdges",W1n="org.eclipse.elk.layered.mergeHierarchyEdges",V1n="org.eclipse.elk.layered.allowNonFlowPortsToSwitchSides",Q1n="org.eclipse.elk.layered.portSortingStrategy",J1n="org.eclipse.elk.layered.thoroughness",Y1n="org.eclipse.elk.layered.unnecessaryBendpoints",Z1n="org.eclipse.elk.layered.generatePositionAndLayerIds",n0n="org.eclipse.elk.layered.cycleBreaking.strategy",t0n="org.eclipse.elk.layered.layering.strategy",e0n="org.eclipse.elk.layered.layering.layerConstraint",i0n="org.eclipse.elk.layered.layering.layerChoiceConstraint",r0n="org.eclipse.elk.layered.layering.layerId",c0n="org.eclipse.elk.layered.layering.minWidth.upperBoundOnWidth",a0n="org.eclipse.elk.layered.layering.minWidth.upperLayerEstimationScalingFactor",u0n="org.eclipse.elk.layered.layering.nodePromotion.strategy",o0n="org.eclipse.elk.layered.layering.nodePromotion.maxIterations",s0n="org.eclipse.elk.layered.layering.coffmanGraham.layerBound",h0n="org.eclipse.elk.layered.crossingMinimization.strategy",f0n="org.eclipse.elk.layered.crossingMinimization.forceNodeModelOrder",l0n="org.eclipse.elk.layered.crossingMinimization.hierarchicalSweepiness",b0n="org.eclipse.elk.layered.crossingMinimization.semiInteractive",w0n="org.eclipse.elk.layered.crossingMinimization.positionChoiceConstraint",d0n="org.eclipse.elk.layered.crossingMinimization.positionId",g0n="org.eclipse.elk.layered.crossingMinimization.greedySwitch.activationThreshold",p0n="org.eclipse.elk.layered.crossingMinimization.greedySwitch.type",v0n="org.eclipse.elk.layered.crossingMinimization.greedySwitchHierarchical.type",m0n="org.eclipse.elk.layered.nodePlacement.strategy",y0n="org.eclipse.elk.layered.nodePlacement.favorStraightEdges",k0n="org.eclipse.elk.layered.nodePlacement.bk.edgeStraightening",j0n="org.eclipse.elk.layered.nodePlacement.bk.fixedAlignment",E0n="org.eclipse.elk.layered.nodePlacement.linearSegments.deflectionDampening",T0n="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility",M0n="org.eclipse.elk.layered.nodePlacement.networkSimplex.nodeFlexibility.default",S0n="org.eclipse.elk.layered.edgeRouting.selfLoopDistribution",P0n="org.eclipse.elk.layered.edgeRouting.selfLoopOrdering",I0n="org.eclipse.elk.layered.edgeRouting.splines.mode",C0n="org.eclipse.elk.layered.edgeRouting.splines.sloppy.layerSpacingFactor",O0n="org.eclipse.elk.layered.edgeRouting.polyline.slopedEdgeZoneWidth",A0n="org.eclipse.elk.layered.spacing.baseValue",$0n="org.eclipse.elk.layered.spacing.edgeNodeBetweenLayers",L0n="org.eclipse.elk.layered.spacing.edgeEdgeBetweenLayers",N0n="org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers",x0n="org.eclipse.elk.layered.priority.direction",D0n="org.eclipse.elk.layered.priority.shortness",R0n="org.eclipse.elk.layered.priority.straightness",K0n="org.eclipse.elk.layered.compaction.connectedComponents",_0n="org.eclipse.elk.layered.compaction.postCompaction.strategy",F0n="org.eclipse.elk.layered.compaction.postCompaction.constraints",B0n="org.eclipse.elk.layered.highDegreeNodes.treatment",H0n="org.eclipse.elk.layered.highDegreeNodes.threshold",q0n="org.eclipse.elk.layered.highDegreeNodes.treeHeight",G0n="org.eclipse.elk.layered.wrapping.strategy",z0n="org.eclipse.elk.layered.wrapping.additionalEdgeSpacing",U0n="org.eclipse.elk.layered.wrapping.correctionFactor",X0n="org.eclipse.elk.layered.wrapping.cutting.strategy",W0n="org.eclipse.elk.layered.wrapping.cutting.cuts",V0n="org.eclipse.elk.layered.wrapping.cutting.msd.freedom",Q0n="org.eclipse.elk.layered.wrapping.validify.strategy",J0n="org.eclipse.elk.layered.wrapping.validify.forbiddenIndices",Y0n="org.eclipse.elk.layered.wrapping.multiEdge.improveCuts",Z0n="org.eclipse.elk.layered.wrapping.multiEdge.distancePenalty",n2n="org.eclipse.elk.layered.wrapping.multiEdge.improveWrappedEdges",t2n="org.eclipse.elk.layered.edgeLabels.sideSelection",e2n="org.eclipse.elk.layered.edgeLabels.centerLabelPlacementStrategy",i2n="org.eclipse.elk.layered.considerModelOrder.strategy",r2n="org.eclipse.elk.layered.considerModelOrder.noModelOrder",c2n="org.eclipse.elk.layered.considerModelOrder.components",a2n="org.eclipse.elk.layered.considerModelOrder.longEdgeStrategy",u2n="org.eclipse.elk.layered.considerModelOrder.crossingCounterNodeInfluence",o2n="org.eclipse.elk.layered.considerModelOrder.crossingCounterPortInfluence",s2n="layering",h2n="layering.minWidth",f2n="layering.nodePromotion",l2n="crossingMinimization",b2n="org.eclipse.elk.hierarchyHandling",w2n="crossingMinimization.greedySwitch",d2n="nodePlacement",g2n="nodePlacement.bk",p2n="edgeRouting",v2n="org.eclipse.elk.edgeRouting",m2n="spacing",y2n="priority",k2n="compaction",j2n="compaction.postCompaction",E2n="Specifies whether and how post-process compaction is applied.",T2n="highDegreeNodes",M2n="wrapping",S2n="wrapping.cutting",P2n="wrapping.validify",I2n="wrapping.multiEdge",C2n="edgeLabels",O2n="considerModelOrder",A2n="org.eclipse.elk.spacing.commentComment",$2n="org.eclipse.elk.spacing.commentNode",L2n="org.eclipse.elk.spacing.edgeEdge",N2n="org.eclipse.elk.spacing.edgeNode",x2n="org.eclipse.elk.spacing.labelLabel",D2n="org.eclipse.elk.spacing.labelPortHorizontal",R2n="org.eclipse.elk.spacing.labelPortVertical",K2n="org.eclipse.elk.spacing.labelNode",_2n="org.eclipse.elk.spacing.nodeSelfLoop",F2n="org.eclipse.elk.spacing.portPort",B2n="org.eclipse.elk.spacing.individual",H2n="org.eclipse.elk.port.borderOffset",q2n="org.eclipse.elk.noLayout",G2n="org.eclipse.elk.port.side",z2n="org.eclipse.elk.debugMode",U2n="org.eclipse.elk.alignment",X2n="org.eclipse.elk.insideSelfLoops.activate",W2n="org.eclipse.elk.insideSelfLoops.yo",V2n="org.eclipse.elk.nodeSize.fixedGraphSize",Q2n="org.eclipse.elk.direction",J2n="org.eclipse.elk.nodeLabels.padding",Y2n="org.eclipse.elk.portLabels.nextToPortIfPossible",Z2n="org.eclipse.elk.portLabels.treatAsGroup",n3n="org.eclipse.elk.portAlignment.default",t3n="org.eclipse.elk.portAlignment.north",e3n="org.eclipse.elk.portAlignment.south",i3n="org.eclipse.elk.portAlignment.west",r3n="org.eclipse.elk.portAlignment.east",c3n="org.eclipse.elk.contentAlignment",a3n="org.eclipse.elk.junctionPoints",u3n="org.eclipse.elk.edgeLabels.placement",o3n="org.eclipse.elk.port.index",s3n="org.eclipse.elk.commentBox",h3n="org.eclipse.elk.hypernode",f3n="org.eclipse.elk.port.anchor",l3n="org.eclipse.elk.partitioning.activate",b3n="org.eclipse.elk.partitioning.partition",w3n="org.eclipse.elk.position",d3n="org.eclipse.elk.margins",g3n="org.eclipse.elk.spacing.portsSurrounding",p3n="org.eclipse.elk.interactiveLayout",v3n="org.eclipse.elk.core.util",m3n={3:1,4:1,5:1,593:1},y3n="NETWORK_SIMPLEX",k3n={123:1,51:1},j3n="org.eclipse.elk.alg.layered.p1cycles",E3n="org.eclipse.elk.alg.layered.p2layers",T3n={402:1,225:1},M3n={832:1,3:1,4:1},S3n="org.eclipse.elk.alg.layered.p3order",P3n="org.eclipse.elk.alg.layered.p4nodes",I3n={3:1,4:1,5:1,840:1},C3n=1e-5,O3n="org.eclipse.elk.alg.layered.p4nodes.bk",A3n="org.eclipse.elk.alg.layered.p5edges",$3n="org.eclipse.elk.alg.layered.p5edges.orthogonal",L3n="org.eclipse.elk.alg.layered.p5edges.orthogonal.direction",N3n=1e-6,x3n="org.eclipse.elk.alg.layered.p5edges.splines",D3n=.09999999999999998,R3n=1e-8,K3n=4.71238898038469,_3n=3.141592653589793,F3n="org.eclipse.elk.alg.mrtree",B3n="org.eclipse.elk.alg.mrtree.graph",H3n="org.eclipse.elk.alg.mrtree.intermediate",q3n="Set neighbors in level",G3n="DESCENDANTS",z3n="org.eclipse.elk.mrtree.weighting",U3n="org.eclipse.elk.mrtree.searchOrder",X3n="org.eclipse.elk.alg.mrtree.options",W3n="org.eclipse.elk.mrtree",V3n="org.eclipse.elk.tree",Q3n="org.eclipse.elk.alg.radial",J3n=6.283185307179586,Y3n=5e-324,Z3n="org.eclipse.elk.alg.radial.intermediate",n4n="org.eclipse.elk.alg.radial.intermediate.compaction",t4n={3:1,4:1,5:1,106:1},e4n="org.eclipse.elk.alg.radial.intermediate.optimization",i4n="No implementation is available for the layout option ",r4n="org.eclipse.elk.alg.radial.options",c4n="org.eclipse.elk.radial.orderId",a4n="org.eclipse.elk.radial.radius",u4n="org.eclipse.elk.radial.compactor",o4n="org.eclipse.elk.radial.compactionStepSize",s4n="org.eclipse.elk.radial.sorter",h4n="org.eclipse.elk.radial.wedgeCriteria",f4n="org.eclipse.elk.radial.optimizationCriteria",l4n="org.eclipse.elk.radial",b4n="org.eclipse.elk.alg.radial.p1position.wedge",w4n="org.eclipse.elk.alg.radial.sorting",d4n=5.497787143782138,g4n=3.9269908169872414,p4n=2.356194490192345,v4n="org.eclipse.elk.alg.rectpacking",m4n="org.eclipse.elk.alg.rectpacking.firstiteration",y4n="org.eclipse.elk.alg.rectpacking.options",k4n="org.eclipse.elk.rectpacking.optimizationGoal",j4n="org.eclipse.elk.rectpacking.lastPlaceShift",E4n="org.eclipse.elk.rectpacking.currentPosition",T4n="org.eclipse.elk.rectpacking.desiredPosition",M4n="org.eclipse.elk.rectpacking.onlyFirstIteration",S4n="org.eclipse.elk.rectpacking.rowCompaction",P4n="org.eclipse.elk.rectpacking.expandToAspectRatio",I4n="org.eclipse.elk.rectpacking.targetWidth",C4n="org.eclipse.elk.expandNodes",O4n="org.eclipse.elk.rectpacking",A4n="org.eclipse.elk.alg.rectpacking.util",$4n="No implementation available for ",L4n="org.eclipse.elk.alg.spore",N4n="org.eclipse.elk.alg.spore.options",x4n="org.eclipse.elk.sporeCompaction",D4n="org.eclipse.elk.underlyingLayoutAlgorithm",R4n="org.eclipse.elk.processingOrder.treeConstruction",K4n="org.eclipse.elk.processingOrder.spanningTreeCostFunction",_4n="org.eclipse.elk.processingOrder.preferredRoot",F4n="org.eclipse.elk.processingOrder.rootSelection",B4n="org.eclipse.elk.structure.structureExtractionStrategy",H4n="org.eclipse.elk.compaction.compactionStrategy",q4n="org.eclipse.elk.compaction.orthogonal",G4n="org.eclipse.elk.overlapRemoval.maxIterations",z4n="org.eclipse.elk.overlapRemoval.runScanline",U4n="processingOrder",X4n="overlapRemoval",W4n="org.eclipse.elk.sporeOverlap",V4n="org.eclipse.elk.alg.spore.p1structure",Q4n="org.eclipse.elk.alg.spore.p2processingorder",J4n="org.eclipse.elk.alg.spore.p3execution",Y4n="Invalid index: ",Z4n="org.eclipse.elk.core.alg",n5n={331:1},t5n={288:1},e5n="Make sure its type is registered with the ",i5n=" utility class.",r5n="true",c5n="false",a5n="Couldn't clone property '",u5n=.05,o5n="org.eclipse.elk.core.options",s5n=1.2999999523162842,h5n="org.eclipse.elk.box",f5n="org.eclipse.elk.box.packingMode",l5n="org.eclipse.elk.algorithm",b5n="org.eclipse.elk.resolvedAlgorithm",w5n="org.eclipse.elk.bendPoints",d5n="org.eclipse.elk.labelManager",g5n="org.eclipse.elk.scaleFactor",p5n="org.eclipse.elk.animate",v5n="org.eclipse.elk.animTimeFactor",m5n="org.eclipse.elk.layoutAncestors",y5n="org.eclipse.elk.maxAnimTime",k5n="org.eclipse.elk.minAnimTime",j5n="org.eclipse.elk.progressBar",E5n="org.eclipse.elk.validateGraph",T5n="org.eclipse.elk.validateOptions",M5n="org.eclipse.elk.zoomToFit",S5n="org.eclipse.elk.font.name",P5n="org.eclipse.elk.font.size",I5n="org.eclipse.elk.edge.type",C5n="partitioning",O5n="nodeLabels",A5n="portAlignment",$5n="nodeSize",L5n="port",N5n="portLabels",x5n="insideSelfLoops",D5n="org.eclipse.elk.fixed",R5n="org.eclipse.elk.random",K5n="port must have a parent node to calculate the port side",_5n="The edge needs to have exactly one edge section. Found: ",F5n="org.eclipse.elk.core.util.adapters",B5n="org.eclipse.emf.ecore",H5n="org.eclipse.elk.graph",q5n="EMapPropertyHolder",G5n="ElkBendPoint",z5n="ElkGraphElement",U5n="ElkConnectableShape",X5n="ElkEdge",W5n="ElkEdgeSection",V5n="EModelElement",Q5n="ENamedElement",J5n="ElkLabel",Y5n="ElkNode",Z5n="ElkPort",n6n={92:1,90:1},t6n="org.eclipse.emf.common.notify.impl",e6n="The feature '",i6n="' is not a valid changeable feature",r6n="Expecting null",c6n="' is not a valid feature",a6n="The feature ID",u6n=" is not a valid feature ID",o6n=32768,s6n={105:1,92:1,90:1,56:1,49:1,97:1},h6n="org.eclipse.emf.ecore.impl",f6n="org.eclipse.elk.graph.impl",l6n="Recursive containment not allowed for ",b6n="The datatype '",w6n="' is not a valid classifier",d6n="The value '",g6n={190:1,3:1,4:1},p6n="The class '",v6n="http://www.eclipse.org/elk/ElkGraph",m6n=1024,y6n="property",k6n="value",j6n="source",E6n="properties",T6n="identifier",M6n="height",S6n="width",P6n="parent",I6n="text",C6n="children",O6n="hierarchical",A6n="sources",$6n="targets",L6n="sections",N6n="bendPoints",x6n="outgoingShape",D6n="incomingShape",R6n="outgoingSections",K6n="incomingSections",_6n="org.eclipse.emf.common.util",F6n="Severe implementation error in the Json to ElkGraph importer.",B6n="id",H6n="org.eclipse.elk.graph.json",q6n="Unhandled parameter types: ",G6n="startPoint",z6n="An edge must have at least one source and one target (edge id: '",U6n="').",X6n="Referenced edge section does not exist: ",W6n=" (edge id: '",V6n="target",Q6n="sourcePoint",J6n="targetPoint",Y6n="group",Z6n="name",n8n="connectableShape cannot be null",t8n="edge cannot be null",e8n="Passed edge is not 'simple'.",i8n="org.eclipse.elk.graph.util",r8n="The 'no duplicates' constraint is violated",c8n="targetIndex=",a8n=", size=",u8n="sourceIndex=",o8n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1},s8n={3:1,4:1,20:1,28:1,52:1,14:1,47:1,15:1,54:1,67:1,63:1,58:1,588:1},h8n="logging",f8n="measureExecutionTime",l8n="parser.parse.1",b8n="parser.parse.2",w8n="parser.next.1",d8n="parser.next.2",g8n="parser.next.3",p8n="parser.next.4",v8n="parser.factor.1",m8n="parser.factor.2",y8n="parser.factor.3",k8n="parser.factor.4",j8n="parser.factor.5",E8n="parser.factor.6",T8n="parser.atom.1",M8n="parser.atom.2",S8n="parser.atom.3",P8n="parser.atom.4",I8n="parser.atom.5",C8n="parser.cc.1",O8n="parser.cc.2",A8n="parser.cc.3",$8n="parser.cc.5",L8n="parser.cc.6",N8n="parser.cc.7",x8n="parser.cc.8",D8n="parser.ope.1",R8n="parser.ope.2",K8n="parser.ope.3",_8n="parser.descape.1",F8n="parser.descape.2",B8n="parser.descape.3",H8n="parser.descape.4",q8n="parser.descape.5",G8n="parser.process.1",z8n="parser.quantifier.1",U8n="parser.quantifier.2",X8n="parser.quantifier.3",W8n="parser.quantifier.4",V8n="parser.quantifier.5",Q8n="org.eclipse.emf.common.notify",J8n={415:1,672:1},Y8n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1},Z8n={366:1,143:1},n9n="index=",t9n={3:1,4:1,5:1,126:1},e9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,58:1},i9n={3:1,6:1,4:1,5:1,192:1},r9n={3:1,4:1,5:1,165:1,367:1},c9n=";/?:@&=+$,",a9n="invalid authority: ",u9n="EAnnotation",o9n="ETypedElement",s9n="EStructuralFeature",h9n="EAttribute",f9n="EClassifier",l9n="EEnumLiteral",b9n="EGenericType",w9n="EOperation",d9n="EParameter",g9n="EReference",p9n="ETypeParameter",v9n="org.eclipse.emf.ecore.util",m9n={76:1},y9n={3:1,20:1,14:1,15:1,58:1,589:1,76:1,69:1,95:1},k9n="org.eclipse.emf.ecore.util.FeatureMap$Entry",j9n=8192,E9n=2048,T9n="byte",M9n="char",S9n="double",P9n="float",I9n="int",C9n="long",O9n="short",A9n="java.lang.Object",$9n={3:1,4:1,5:1,247:1},L9n={3:1,4:1,5:1,673:1},N9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,69:1},x9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,76:1,69:1,95:1},D9n="mixed",R9n="http:///org/eclipse/emf/ecore/util/ExtendedMetaData",K9n="kind",_9n={3:1,4:1,5:1,674:1},F9n={3:1,4:1,20:1,28:1,52:1,14:1,15:1,67:1,58:1,76:1,69:1,95:1},B9n={20:1,28:1,52:1,14:1,15:1,58:1,69:1},H9n={47:1,125:1,279:1},q9n={72:1,332:1},G9n="The value of type '",z9n="' must be of type '",U9n=1316,X9n="http://www.eclipse.org/emf/2002/Ecore",W9n=-32768,V9n="constraints",Q9n="baseType",J9n="getEStructuralFeature",Y9n="getFeatureID",Z9n="feature",n7n="getOperationID",t7n="operation",e7n="defaultValue",i7n="eTypeParameters",r7n="isInstance",c7n="getEEnumLiteral",a7n="eContainingClass",u7n={55:1},o7n={3:1,4:1,5:1,119:1},s7n="org.eclipse.emf.ecore.resource",h7n={92:1,90:1,591:1,1935:1},f7n="org.eclipse.emf.ecore.resource.impl",l7n="unspecified",b7n="simple",w7n="attribute",d7n="attributeWildcard",g7n="element",p7n="elementWildcard",v7n="collapse",m7n="itemType",y7n="namespace",k7n="##targetNamespace",j7n="whiteSpace",E7n="wildcards",T7n="http://www.eclipse.org/emf/2003/XMLType",M7n="##any",S7n="uninitialized",P7n="The multiplicity constraint is violated",I7n="org.eclipse.emf.ecore.xml.type",C7n="ProcessingInstruction",O7n="SimpleAnyType",A7n="XMLTypeDocumentRoot",$7n="org.eclipse.emf.ecore.xml.type.impl",L7n="INF",N7n="processing",x7n="ENTITIES_._base",D7n="minLength",R7n="ENTITY",K7n="NCName",_7n="IDREFS_._base",F7n="integer",B7n="token",H7n="pattern",q7n="[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*",G7n="\\i\\c*",z7n="[\\i-[:]][\\c-[:]]*",U7n="nonPositiveInteger",X7n="maxInclusive",W7n="NMTOKEN",V7n="NMTOKENS_._base",Q7n="nonNegativeInteger",J7n="minInclusive",Y7n="normalizedString",Z7n="unsignedByte",nnt="unsignedInt",tnt="18446744073709551615",ent="unsignedShort",int="processingInstruction",rnt="org.eclipse.emf.ecore.xml.type.internal",cnt=1114111,ant="Internal Error: shorthands: \\u",unt="xml:isDigit",ont="xml:isWord",snt="xml:isSpace",hnt="xml:isNameChar",fnt="xml:isInitialNameChar",lnt="09٠٩۰۹०९০৯੦੯૦૯୦୯௧௯౦౯೦೯൦൯๐๙໐໙༠༩",bnt="AZazÀÖØöøıĴľŁňŊžƀǃǍǰǴǵǺȗɐʨʻˁΆΆΈΊΌΌΎΡΣώϐϖϚϚϜϜϞϞϠϠϢϳЁЌЎяёќўҁҐӄӇӈӋӌӐӫӮӵӸӹԱՖՙՙաֆאתװײءغفيٱڷںھۀێېۓەەۥۦअहऽऽक़ॡঅঌএঐওনপরললশহড়ঢ়য়ৡৰৱਅਊਏਐਓਨਪਰਲਲ਼ਵਸ਼ਸਹਖ਼ੜਫ਼ਫ਼ੲੴઅઋઍઍએઑઓનપરલળવહઽઽૠૠଅଌଏଐଓନପରଲଳଶହଽଽଡ଼ଢ଼ୟୡஅஊஎஐஒகஙசஜஜஞடணதநபமவஷஹఅఌఎఐఒనపళవహౠౡಅಌಎಐಒನಪಳವಹೞೞೠೡഅഌഎഐഒനപഹൠൡกฮะะาำเๅກຂຄຄງຈຊຊຍຍດທນຟມຣລລວວສຫອຮະະາຳຽຽເໄཀཇཉཀྵႠჅაჶᄀᄀᄂᄃᄅᄇᄉᄉᄋᄌᄎᄒᄼᄼᄾᄾᅀᅀᅌᅌᅎᅎᅐᅐᅔᅕᅙᅙᅟᅡᅣᅣᅥᅥᅧᅧᅩᅩᅭᅮᅲᅳᅵᅵᆞᆞᆨᆨᆫᆫᆮᆯᆷᆸᆺᆺᆼᇂᇫᇫᇰᇰᇹᇹḀẛẠỹἀἕἘἝἠὅὈὍὐὗὙὙὛὛὝὝὟώᾀᾴᾶᾼιιῂῄῆῌῐΐῖΊῠῬῲῴῶῼΩΩKÅ℮℮ↀↂ〇〇〡〩ぁゔァヺㄅㄬ一龥가힣",wnt="Private Use",dnt="ASSIGNED",gnt="\0€ÿĀſƀɏɐʯʰ˿̀ͯͰϿЀӿ԰֏֐׿؀ۿ܀ݏހ޿ऀॿঀ৿਀੿઀૿଀୿஀௿ఀ౿ಀ೿ഀൿ඀෿฀๿຀໿ༀ࿿က႟Ⴀჿᄀᇿሀ፿Ꭰ᏿᐀ᙿ ᚟ᚠ᛿ក៿᠀᢯Ḁỿἀ῿ ⁰₟₠⃏⃐⃿℀⅏⅐↏←⇿∀⋿⌀⏿␀␿⑀⑟①⓿─╿▀▟■◿☀⛿✀➿⠀⣿⺀⻿⼀⿟⿰⿿ 〿぀ゟ゠ヿ㄀ㄯ㄰㆏㆐㆟ㆠㆿ㈀㋿㌀㏿㐀䶵一鿿ꀀ꒏꒐꓏가힣豈﫿ffﭏﭐ﷿︠︯︰﹏﹐﹯ﹰ﻾\ufeff\ufeff＀￯",pnt="UNASSIGNED",vnt={3:1,117:1},mnt="org.eclipse.emf.ecore.xml.type.util",ynt={3:1,4:1,5:1,368:1},knt="org.eclipse.xtext.xbase.lib",jnt="Cannot add elements to a Range",Ent="Cannot set elements in a Range",Tnt="Cannot remove elements from a Range",Mnt="locale",Snt="default",Pnt="user.agent";i.goog=i.goog||{},i.goog.global=i.goog.global||i,UMn(),lAn(1,null,{},r),EWn.Fb=function(n){return KO(this,n)},EWn.Gb=function(){return this.gm},EWn.Hb=function(){return MN(this)},EWn.Ib=function(){return Yj(Zon(this))+"@"+(Yon(this)>>>0).toString(16)},EWn.equals=function(n){return this.Fb(n)},EWn.hashCode=function(){return this.Hb()},EWn.toString=function(){return this.Ib()},lAn(290,1,{290:1,2026:1},don),EWn.le=function(n){var t;return(t=new don).i=4,t.c=n>1?wZ(this,n-1):this,t},EWn.me=function(){return kD(this),this.b},EWn.ne=function(){return Yj(this)},EWn.oe=function(){return kD(this),this.k},EWn.pe=function(){return 0!=(4&this.i)},EWn.qe=function(){return 0!=(1&this.i)},EWn.Ib=function(){return ctn(this)},EWn.i=0;var Int,Cnt=gX(xWn,"Object",1),Ont=gX(xWn,"Class",290);lAn(1998,1,DWn),gX(RWn,"Optional",1998),lAn(1170,1998,DWn,c),EWn.Fb=function(n){return n===this},EWn.Hb=function(){return 2040732332},EWn.Ib=function(){return"Optional.absent()"},EWn.Jb=function(n){return vX(n),ty(),Int},gX(RWn,"Absent",1170),lAn(628,1,{},pk),gX(RWn,"Joiner",628);var Ant=fq(RWn,"Predicate");lAn(582,1,{169:1,582:1,3:1,45:1},Ff),EWn.Mb=function(n){return Don(this,n)},EWn.Lb=function(n){return Don(this,n)},EWn.Fb=function(n){var t;return!!iL(n,582)&&(t=_B(n,582),$An(this.a,t.a))},EWn.Hb=function(){return Kon(this.a)+306654252},EWn.Ib=function(){return lPn(this.a)},gX(RWn,"Predicates/AndPredicate",582),lAn(408,1998,{408:1,3:1},Bf),EWn.Fb=function(n){var t;return!!iL(n,408)&&(t=_B(n,408),$fn(this.a,t.a))},EWn.Hb=function(){return 1502476572+Yon(this.a)},EWn.Ib=function(){return HWn+this.a+")"},EWn.Jb=function(n){return new Bf(UQ(n.Kb(this.a),"the Function passed to Optional.transform() must not return null."))},gX(RWn,"Present",408),lAn(198,1,GWn),EWn.Nb=function(n){sU(this,n)},EWn.Qb=function(){fk()},gX(zWn,"UnmodifiableIterator",198),lAn(1978,198,UWn),EWn.Qb=function(){fk()},EWn.Rb=function(n){throw Fp(new dv)},EWn.Wb=function(n){throw Fp(new dv)},gX(zWn,"UnmodifiableListIterator",1978),lAn(386,1978,UWn),EWn.Ob=function(){return this.c0},EWn.Pb=function(){if(this.c>=this.d)throw Fp(new vv);return this.Xb(this.c++)},EWn.Tb=function(){return this.c},EWn.Ub=function(){if(this.c<=0)throw Fp(new vv);return this.Xb(--this.c)},EWn.Vb=function(){return this.c-1},EWn.c=0,EWn.d=0,gX(zWn,"AbstractIndexedListIterator",386),lAn(699,198,GWn),EWn.Ob=function(){return Jin(this)},EWn.Pb=function(){return M7(this)},EWn.e=1,gX(zWn,"AbstractIterator",699),lAn(1986,1,{224:1}),EWn.Zb=function(){return this.f||(this.f=this.ac())},EWn.Fb=function(n){return ysn(this,n)},EWn.Hb=function(){return Yon(this.Zb())},EWn.dc=function(){return 0==this.gc()},EWn.ec=function(){return wz(this)},EWn.Ib=function(){return _bn(this.Zb())},gX(zWn,"AbstractMultimap",1986),lAn(726,1986,XWn),EWn.$b=function(){lin(this)},EWn._b=function(n){return Uj(this,n)},EWn.ac=function(){return new dT(this,this.c)},EWn.ic=function(n){return this.hc()},EWn.bc=function(){return new FL(this,this.c)},EWn.jc=function(){return this.mc(this.hc())},EWn.kc=function(){return new Fm(this)},EWn.lc=function(){return BTn(this.c.vc().Nc(),new u,64,this.d)},EWn.cc=function(n){return o6(this,n)},EWn.fc=function(n){return $hn(this,n)},EWn.gc=function(){return this.d},EWn.mc=function(n){return TQ(),new Fb(n)},EWn.nc=function(){return new _m(this)},EWn.oc=function(){return BTn(this.c.Cc().Nc(),new a,64,this.d)},EWn.pc=function(n,t){return new U6(this,n,t,null)},EWn.d=0,gX(zWn,"AbstractMapBasedMultimap",726),lAn(1631,726,XWn),EWn.hc=function(){return new Q6(this.a)},EWn.jc=function(){return TQ(),TQ(),uet},EWn.cc=function(n){return _B(o6(this,n),15)},EWn.fc=function(n){return _B($hn(this,n),15)},EWn.Zb=function(){return IQ(this)},EWn.Fb=function(n){return ysn(this,n)},EWn.qc=function(n){return _B(o6(this,n),15)},EWn.rc=function(n){return _B($hn(this,n),15)},EWn.mc=function(n){return eJ(_B(n,15))},EWn.pc=function(n,t){return t3(this,n,_B(t,15),null)},gX(zWn,"AbstractListMultimap",1631),lAn(732,1,WWn),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return this.c.Ob()||this.e.Ob()},EWn.Pb=function(){var n;return this.e.Ob()||(n=_B(this.c.Pb(),42),this.b=n.cd(),this.a=_B(n.dd(),14),this.e=this.a.Kc()),this.sc(this.b,this.e.Pb())},EWn.Qb=function(){this.e.Qb(),this.a.dc()&&this.c.Qb(),--this.d.d},gX(zWn,"AbstractMapBasedMultimap/Itr",732),lAn(1099,732,WWn,_m),EWn.sc=function(n,t){return t},gX(zWn,"AbstractMapBasedMultimap/1",1099),lAn(1100,1,{},a),EWn.Kb=function(n){return _B(n,14).Nc()},gX(zWn,"AbstractMapBasedMultimap/1methodref$spliterator$Type",1100),lAn(1101,732,WWn,Fm),EWn.sc=function(n,t){return new gT(n,t)},gX(zWn,"AbstractMapBasedMultimap/2",1101);var $nt=fq(VWn,"Map");lAn(1967,1,QWn),EWn.wc=function(n){Ycn(this,n)},EWn.yc=function(n,t,e){return Jln(this,n,t,e)},EWn.$b=function(){this.vc().$b()},EWn.tc=function(n){return Emn(this,n)},EWn._b=function(n){return!!KEn(this,n,!1)},EWn.uc=function(n){var t,e;for(t=this.vc().Kc();t.Ob();)if(e=_B(t.Pb(),42).dd(),HC(n)===HC(e)||null!=n&&$fn(n,e))return!0;return!1},EWn.Fb=function(n){var t,e,i;if(n===this)return!0;if(!iL(n,83))return!1;if(i=_B(n,83),this.gc()!=i.gc())return!1;for(e=i.vc().Kc();e.Ob();)if(t=_B(e.Pb(),42),!this.tc(t))return!1;return!0},EWn.xc=function(n){return BC(KEn(this,n,!1))},EWn.Hb=function(){return Fun(this.vc())},EWn.dc=function(){return 0==this.gc()},EWn.ec=function(){return new Sb(this)},EWn.zc=function(n,t){throw Fp(new Zy("Put not supported on this map"))},EWn.Ac=function(n){jcn(this,n)},EWn.Bc=function(n){return BC(KEn(this,n,!0))},EWn.gc=function(){return this.vc().gc()},EWn.Ib=function(){return YEn(this)},EWn.Cc=function(){return new Ib(this)},gX(VWn,"AbstractMap",1967),lAn(1987,1967,QWn),EWn.bc=function(){return new TT(this)},EWn.vc=function(){return bz(this)},EWn.ec=function(){return this.g||(this.g=this.bc())},EWn.Cc=function(){return this.i||(this.i=new MT(this))},gX(zWn,"Maps/ViewCachingAbstractMap",1987),lAn(389,1987,QWn,dT),EWn.xc=function(n){return mtn(this,n)},EWn.Bc=function(n){return Jsn(this,n)},EWn.$b=function(){this.d==this.e.c?this.e.$b():Sq(new Iq(this))},EWn._b=function(n){return wfn(this.d,n)},EWn.Ec=function(){return new zf(this)},EWn.Dc=function(){return this.Ec()},EWn.Fb=function(n){return this===n||$fn(this.d,n)},EWn.Hb=function(){return Yon(this.d)},EWn.ec=function(){return this.e.ec()},EWn.gc=function(){return this.d.gc()},EWn.Ib=function(){return _bn(this.d)},gX(zWn,"AbstractMapBasedMultimap/AsMap",389);var Lnt=fq(xWn,"Iterable");lAn(28,1,JWn),EWn.Jc=function(n){n5(this,n)},EWn.Lc=function(){return this.Oc()},EWn.Nc=function(){return new l1(this,0)},EWn.Oc=function(){return new xq(null,this.Nc())},EWn.Fc=function(n){throw Fp(new Zy("Add not supported on this collection"))},EWn.Gc=function(n){return Krn(this,n)},EWn.$b=function(){jV(this)},EWn.Hc=function(n){return vwn(this,n,!1)},EWn.Ic=function(n){return aun(this,n)},EWn.dc=function(){return 0==this.gc()},EWn.Mc=function(n){return vwn(this,n,!0)},EWn.Pc=function(){return iz(this)},EWn.Qc=function(n){return kmn(this,n)},EWn.Ib=function(){return AMn(this)},gX(VWn,"AbstractCollection",28);var Nnt=fq(VWn,"Set");lAn(YWn,28,ZWn),EWn.Nc=function(){return new l1(this,1)},EWn.Fb=function(n){return tgn(this,n)},EWn.Hb=function(){return Fun(this)},gX(VWn,"AbstractSet",YWn),lAn(1970,YWn,ZWn),gX(zWn,"Sets/ImprovedAbstractSet",1970),lAn(1971,1970,ZWn),EWn.$b=function(){this.Rc().$b()},EWn.Hc=function(n){return tdn(this,n)},EWn.dc=function(){return this.Rc().dc()},EWn.Mc=function(n){var t;return!!this.Hc(n)&&(t=_B(n,42),this.Rc().ec().Mc(t.cd()))},EWn.gc=function(){return this.Rc().gc()},gX(zWn,"Maps/EntrySet",1971),lAn(1097,1971,ZWn,zf),EWn.Hc=function(n){return lfn(this.a.d.vc(),n)},EWn.Kc=function(){return new Iq(this.a)},EWn.Rc=function(){return this.a},EWn.Mc=function(n){var t;return!!lfn(this.a.d.vc(),n)&&(t=_B(n,42),F5(this.a.e,t.cd()),!0)},EWn.Nc=function(){return xB(this.a.d.vc().Nc(),new Uf(this.a))},gX(zWn,"AbstractMapBasedMultimap/AsMap/AsMapEntries",1097),lAn(1098,1,{},Uf),EWn.Kb=function(n){return t5(this.a,_B(n,42))},gX(zWn,"AbstractMapBasedMultimap/AsMap/AsMapEntries/0methodref$wrapEntry$Type",1098),lAn(730,1,WWn,Iq),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){var n;return n=_B(this.b.Pb(),42),this.a=_B(n.dd(),14),t5(this.c,n)},EWn.Ob=function(){return this.b.Ob()},EWn.Qb=function(){oan(!!this.a),this.b.Qb(),this.c.e.d-=this.a.gc(),this.a.$b(),this.a=null},gX(zWn,"AbstractMapBasedMultimap/AsMap/AsMapIterator",730),lAn(532,1970,ZWn,TT),EWn.$b=function(){this.b.$b()},EWn.Hc=function(n){return this.b._b(n)},EWn.Jc=function(n){vX(n),this.b.wc(new gl(n))},EWn.dc=function(){return this.b.dc()},EWn.Kc=function(){return new hy(this.b.vc().Kc())},EWn.Mc=function(n){return!!this.b._b(n)&&(this.b.Bc(n),!0)},EWn.gc=function(){return this.b.gc()},gX(zWn,"Maps/KeySet",532),lAn(318,532,ZWn,FL),EWn.$b=function(){Sq(new nT(this,this.b.vc().Kc()))},EWn.Ic=function(n){return this.b.ec().Ic(n)},EWn.Fb=function(n){return this===n||$fn(this.b.ec(),n)},EWn.Hb=function(){return Yon(this.b.ec())},EWn.Kc=function(){return new nT(this,this.b.vc().Kc())},EWn.Mc=function(n){var t,e;return e=0,(t=_B(this.b.Bc(n),14))&&(e=t.gc(),t.$b(),this.a.d-=e),e>0},EWn.Nc=function(){return this.b.ec().Nc()},gX(zWn,"AbstractMapBasedMultimap/KeySet",318),lAn(731,1,WWn,nT),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return this.c.Ob()},EWn.Pb=function(){return this.a=_B(this.c.Pb(),42),this.a.cd()},EWn.Qb=function(){var n;oan(!!this.a),n=_B(this.a.dd(),14),this.c.Qb(),this.b.a.d-=n.gc(),n.$b(),this.a=null},gX(zWn,"AbstractMapBasedMultimap/KeySet/1",731),lAn(491,389,{83:1,161:1},SD),EWn.bc=function(){return this.Sc()},EWn.ec=function(){return this.Tc()},EWn.Sc=function(){return new YE(this.c,this.Uc())},EWn.Tc=function(){return this.b||(this.b=this.Sc())},EWn.Uc=function(){return _B(this.d,161)},gX(zWn,"AbstractMapBasedMultimap/SortedAsMap",491),lAn(542,491,nVn,PD),EWn.bc=function(){return new ZE(this.a,_B(_B(this.d,161),171))},EWn.Sc=function(){return new ZE(this.a,_B(_B(this.d,161),171))},EWn.ec=function(){return _B(this.b||(this.b=new ZE(this.a,_B(_B(this.d,161),171))),271)},EWn.Tc=function(){return _B(this.b||(this.b=new ZE(this.a,_B(_B(this.d,161),171))),271)},EWn.Uc=function(){return _B(_B(this.d,161),171)},gX(zWn,"AbstractMapBasedMultimap/NavigableAsMap",542),lAn(490,318,tVn,YE),EWn.Nc=function(){return this.b.ec().Nc()},gX(zWn,"AbstractMapBasedMultimap/SortedKeySet",490),lAn(388,490,eVn,ZE),gX(zWn,"AbstractMapBasedMultimap/NavigableKeySet",388),lAn(541,28,JWn,U6),EWn.Fc=function(n){var t,e;return qbn(this),e=this.d.dc(),(t=this.d.Fc(n))&&(++this.f.d,e&&yR(this)),t},EWn.Gc=function(n){var t,e,i;return!n.dc()&&(qbn(this),i=this.d.gc(),(t=this.d.Gc(n))&&(e=this.d.gc(),this.f.d+=e-i,0==i&&yR(this)),t)},EWn.$b=function(){var n;qbn(this),0!=(n=this.d.gc())&&(this.d.$b(),this.f.d-=n,OG(this))},EWn.Hc=function(n){return qbn(this),this.d.Hc(n)},EWn.Ic=function(n){return qbn(this),this.d.Ic(n)},EWn.Fb=function(n){return n===this||(qbn(this),$fn(this.d,n))},EWn.Hb=function(){return qbn(this),Yon(this.d)},EWn.Kc=function(){return qbn(this),new WB(this)},EWn.Mc=function(n){var t;return qbn(this),(t=this.d.Mc(n))&&(--this.f.d,OG(this)),t},EWn.gc=function(){return ZC(this)},EWn.Nc=function(){return qbn(this),this.d.Nc()},EWn.Ib=function(){return qbn(this),_bn(this.d)},gX(zWn,"AbstractMapBasedMultimap/WrappedCollection",541);var xnt=fq(VWn,"List");lAn(728,541,{20:1,28:1,14:1,15:1},uz),EWn.ad=function(n){Rrn(this,n)},EWn.Nc=function(){return qbn(this),this.d.Nc()},EWn.Vc=function(n,t){var e;qbn(this),e=this.d.dc(),_B(this.d,15).Vc(n,t),++this.a.d,e&&yR(this)},EWn.Wc=function(n,t){var e,i,r;return!t.dc()&&(qbn(this),r=this.d.gc(),(e=_B(this.d,15).Wc(n,t))&&(i=this.d.gc(),this.a.d+=i-r,0==r&&yR(this)),e)},EWn.Xb=function(n){return qbn(this),_B(this.d,15).Xb(n)},EWn.Xc=function(n){return qbn(this),_B(this.d,15).Xc(n)},EWn.Yc=function(){return qbn(this),new w$(this)},EWn.Zc=function(n){return qbn(this),new wQ(this,n)},EWn.$c=function(n){var t;return qbn(this),t=_B(this.d,15).$c(n),--this.a.d,OG(this),t},EWn._c=function(n,t){return qbn(this),_B(this.d,15)._c(n,t)},EWn.bd=function(n,t){return qbn(this),t3(this.a,this.e,_B(this.d,15).bd(n,t),this.b?this.b:this)},gX(zWn,"AbstractMapBasedMultimap/WrappedList",728),lAn(1096,728,{20:1,28:1,14:1,15:1,54:1},Ix),gX(zWn,"AbstractMapBasedMultimap/RandomAccessWrappedList",1096),lAn(620,1,WWn,WB),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return EV(this),this.b.Ob()},EWn.Pb=function(){return EV(this),this.b.Pb()},EWn.Qb=function(){nN(this)},gX(zWn,"AbstractMapBasedMultimap/WrappedCollection/WrappedIterator",620),lAn(729,620,iVn,w$,wQ),EWn.Qb=function(){nN(this)},EWn.Rb=function(n){var t;t=0==ZC(this.a),(EV(this),_B(this.b,125)).Rb(n),++this.a.a.d,t&&yR(this.a)},EWn.Sb=function(){return(EV(this),_B(this.b,125)).Sb()},EWn.Tb=function(){return(EV(this),_B(this.b,125)).Tb()},EWn.Ub=function(){return(EV(this),_B(this.b,125)).Ub()},EWn.Vb=function(){return(EV(this),_B(this.b,125)).Vb()},EWn.Wb=function(n){(EV(this),_B(this.b,125)).Wb(n)},gX(zWn,"AbstractMapBasedMultimap/WrappedList/WrappedListIterator",729),lAn(727,541,tVn,$D),EWn.Nc=function(){return qbn(this),this.d.Nc()},gX(zWn,"AbstractMapBasedMultimap/WrappedSortedSet",727),lAn(1095,727,eVn,CA),gX(zWn,"AbstractMapBasedMultimap/WrappedNavigableSet",1095),lAn(1094,541,ZWn,LD),EWn.Nc=function(){return qbn(this),this.d.Nc()},gX(zWn,"AbstractMapBasedMultimap/WrappedSet",1094),lAn(1103,1,{},u),EWn.Kb=function(n){return K6(_B(n,42))},gX(zWn,"AbstractMapBasedMultimap/lambda$1$Type",1103),lAn(1102,1,{},Xf),EWn.Kb=function(n){return new gT(this.a,n)},gX(zWn,"AbstractMapBasedMultimap/lambda$2$Type",1102);var Dnt,Rnt,Knt,_nt,Fnt=fq(VWn,"Map/Entry");lAn(345,1,rVn),EWn.Fb=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),lW(this.cd(),t.cd())&&lW(this.dd(),t.dd()))},EWn.Hb=function(){var n,t;return n=this.cd(),t=this.dd(),(null==n?0:Yon(n))^(null==t?0:Yon(t))},EWn.ed=function(n){throw Fp(new dv)},EWn.Ib=function(){return this.cd()+"="+this.dd()},gX(zWn,cVn,345),lAn(1988,28,JWn),EWn.$b=function(){this.fd().$b()},EWn.Hc=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),F0(this.fd(),t.cd(),t.dd()))},EWn.Mc=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),B0(this.fd(),t.cd(),t.dd()))},EWn.gc=function(){return this.fd().d},gX(zWn,"Multimaps/Entries",1988),lAn(733,1988,JWn,Wf),EWn.Kc=function(){return this.a.kc()},EWn.fd=function(){return this.a},EWn.Nc=function(){return this.a.lc()},gX(zWn,"AbstractMultimap/Entries",733),lAn(734,733,ZWn,Bm),EWn.Nc=function(){return this.a.lc()},EWn.Fb=function(n){return qSn(this,n)},EWn.Hb=function(){return _rn(this)},gX(zWn,"AbstractMultimap/EntrySet",734),lAn(735,28,JWn,Vf),EWn.$b=function(){this.a.$b()},EWn.Hc=function(n){return Psn(this.a,n)},EWn.Kc=function(){return this.a.nc()},EWn.gc=function(){return this.a.d},EWn.Nc=function(){return this.a.oc()},gX(zWn,"AbstractMultimap/Values",735),lAn(1989,28,{835:1,20:1,28:1,14:1}),EWn.Jc=function(n){vX(n),kV(this).Jc(new dl(n))},EWn.Nc=function(){var n;return BTn(n=kV(this).Nc(),new y,64|1296&n.qd(),this.a.d)},EWn.Fc=function(n){return lk(),!0},EWn.Gc=function(n){return vX(this),vX(n),iL(n,543)?h2(_B(n,835)):!n.dc()&&snn(this,n.Kc())},EWn.Hc=function(n){var t;return((t=_B(hfn(IQ(this.a),n),14))?t.gc():0)>0},EWn.Fb=function(n){return o$n(this,n)},EWn.Hb=function(){return Yon(kV(this))},EWn.dc=function(){return kV(this).dc()},EWn.Mc=function(n){return kCn(this,n,1)>0},EWn.Ib=function(){return _bn(kV(this))},gX(zWn,"AbstractMultiset",1989),lAn(1991,1970,ZWn),EWn.$b=function(){lin(this.a.a)},EWn.Hc=function(n){var t;return!(!iL(n,492)||(t=_B(n,416),_B(t.a.dd(),14).gc()<=0||i1(this.a,t.a.cd())!=_B(t.a.dd(),14).gc()))},EWn.Mc=function(n){var t,e,i;return!(!iL(n,492)||(t=(e=_B(n,416)).a.cd(),0==(i=_B(e.a.dd(),14).gc())))&&jCn(this.a,t,i)},gX(zWn,"Multisets/EntrySet",1991),lAn(1109,1991,ZWn,Qf),EWn.Kc=function(){return new ly(bz(IQ(this.a.a)).Kc())},EWn.gc=function(){return IQ(this.a.a).gc()},gX(zWn,"AbstractMultiset/EntrySet",1109),lAn(619,726,XWn),EWn.hc=function(){return this.gd()},EWn.jc=function(){return this.hd()},EWn.cc=function(n){return this.jd(n)},EWn.fc=function(n){return this.kd(n)},EWn.Zb=function(){return this.f||(this.f=this.ac())},EWn.hd=function(){return TQ(),TQ(),set},EWn.Fb=function(n){return ysn(this,n)},EWn.jd=function(n){return _B(o6(this,n),21)},EWn.kd=function(n){return _B($hn(this,n),21)},EWn.mc=function(n){return TQ(),new Ck(_B(n,21))},EWn.pc=function(n,t){return new LD(this,n,_B(t,21))},gX(zWn,"AbstractSetMultimap",619),lAn(1657,619,XWn),EWn.hc=function(){return new bE(this.b)},EWn.gd=function(){return new bE(this.b)},EWn.jc=function(){return PX(new bE(this.b))},EWn.hd=function(){return PX(new bE(this.b))},EWn.cc=function(n){return _B(_B(o6(this,n),21),84)},EWn.jd=function(n){return _B(_B(o6(this,n),21),84)},EWn.fc=function(n){return _B(_B($hn(this,n),21),84)},EWn.kd=function(n){return _B(_B($hn(this,n),21),84)},EWn.mc=function(n){return iL(n,271)?PX(_B(n,271)):(TQ(),new bN(_B(n,84)))},EWn.Zb=function(){return this.f||(this.f=iL(this.c,171)?new PD(this,_B(this.c,171)):iL(this.c,161)?new SD(this,_B(this.c,161)):new dT(this,this.c))},EWn.pc=function(n,t){return iL(t,271)?new CA(this,n,_B(t,271)):new $D(this,n,_B(t,84))},gX(zWn,"AbstractSortedSetMultimap",1657),lAn(1658,1657,XWn),EWn.Zb=function(){return _B(_B(this.f||(this.f=iL(this.c,171)?new PD(this,_B(this.c,171)):iL(this.c,161)?new SD(this,_B(this.c,161)):new dT(this,this.c)),161),171)},EWn.ec=function(){return _B(_B(this.i||(this.i=iL(this.c,171)?new ZE(this,_B(this.c,171)):iL(this.c,161)?new YE(this,_B(this.c,161)):new FL(this,this.c)),84),271)},EWn.bc=function(){return iL(this.c,171)?new ZE(this,_B(this.c,171)):iL(this.c,161)?new YE(this,_B(this.c,161)):new FL(this,this.c)},gX(zWn,"AbstractSortedKeySortedSetMultimap",1658),lAn(2010,1,{1947:1}),EWn.Fb=function(n){return Sjn(this,n)},EWn.Hb=function(){return Fun(this.g||(this.g=new Jf(this)))},EWn.Ib=function(){return YEn(this.f||(this.f=new GL(this)))},gX(zWn,"AbstractTable",2010),lAn(665,YWn,ZWn,Jf),EWn.$b=function(){bk()},EWn.Hc=function(n){var t,e;return!!iL(n,468)&&(t=_B(n,682),!!(e=_B(hfn(yX(this.a),UC(t.c.e,t.b)),83))&&lfn(e.vc(),new gT(UC(t.c.c,t.a),G6(t.c,t.b,t.a))))},EWn.Kc=function(){return JQ(this.a)},EWn.Mc=function(n){var t,e;return!!iL(n,468)&&(t=_B(n,682),!!(e=_B(hfn(yX(this.a),UC(t.c.e,t.b)),83))&&bfn(e.vc(),new gT(UC(t.c.c,t.a),G6(t.c,t.b,t.a))))},EWn.gc=function(){return qq(this.a)},EWn.Nc=function(){return M2(this.a)},gX(zWn,"AbstractTable/CellSet",665),lAn(1928,28,JWn,Yf),EWn.$b=function(){bk()},EWn.Hc=function(n){return oTn(this.a,n)},EWn.Kc=function(){return YQ(this.a)},EWn.gc=function(){return qq(this.a)},EWn.Nc=function(){return V0(this.a)},gX(zWn,"AbstractTable/Values",1928),lAn(1632,1631,XWn),gX(zWn,"ArrayListMultimapGwtSerializationDependencies",1632),lAn(513,1632,XWn,ak,a1),EWn.hc=function(){return new Q6(this.a)},EWn.a=0,gX(zWn,"ArrayListMultimap",513),lAn(664,2010,{664:1,1947:1,3:1},gOn),gX(zWn,"ArrayTable",664),lAn(1924,386,UWn,BL),EWn.Xb=function(n){return new won(this.a,n)},gX(zWn,"ArrayTable/1",1924),lAn(1925,1,{},Hf),EWn.ld=function(n){return new won(this.a,n)},gX(zWn,"ArrayTable/1methodref$getCell$Type",1925),lAn(2011,1,{682:1}),EWn.Fb=function(n){var t;return n===this||!!iL(n,468)&&(t=_B(n,682),lW(UC(this.c.e,this.b),UC(t.c.e,t.b))&&lW(UC(this.c.c,this.a),UC(t.c.c,t.a))&&lW(G6(this.c,this.b,this.a),G6(t.c,t.b,t.a)))},EWn.Hb=function(){return shn(Mun(Hk(Cnt,1),FWn,1,5,[UC(this.c.e,this.b),UC(this.c.c,this.a),G6(this.c,this.b,this.a)]))},EWn.Ib=function(){return"("+UC(this.c.e,this.b)+","+UC(this.c.c,this.a)+")="+G6(this.c,this.b,this.a)},gX(zWn,"Tables/AbstractCell",2011),lAn(468,2011,{468:1,682:1},won),EWn.a=0,EWn.b=0,EWn.d=0,gX(zWn,"ArrayTable/2",468),lAn(1927,1,{},qf),EWn.ld=function(n){return V9(this.a,n)},gX(zWn,"ArrayTable/2methodref$getValue$Type",1927),lAn(1926,386,UWn,HL),EWn.Xb=function(n){return V9(this.a,n)},gX(zWn,"ArrayTable/3",1926),lAn(1979,1967,QWn),EWn.$b=function(){Sq(this.kc())},EWn.vc=function(){return new pl(this)},EWn.lc=function(){return new SV(this.kc(),this.gc())},gX(zWn,"Maps/IteratorBasedAbstractMap",1979),lAn(828,1979,QWn),EWn.$b=function(){throw Fp(new dv)},EWn._b=function(n){return Vj(this.c,n)},EWn.kc=function(){return new qL(this,this.c.b.c.gc())},EWn.lc=function(){return vq(this.c.b.c.gc(),16,new Gf(this))},EWn.xc=function(n){var t;return(t=_B(GK(this.c,n),19))?this.nd(t.a):null},EWn.dc=function(){return this.c.b.c.dc()},EWn.ec=function(){return fz(this.c)},EWn.zc=function(n,t){var e;if(!(e=_B(GK(this.c,n),19)))throw Fp(new Ry(this.md()+" "+n+" not in "+fz(this.c)));return this.od(e.a,t)},EWn.Bc=function(n){throw Fp(new dv)},EWn.gc=function(){return this.c.b.c.gc()},gX(zWn,"ArrayTable/ArrayMap",828),lAn(1923,1,{},Gf),EWn.ld=function(n){return IX(this.a,n)},gX(zWn,"ArrayTable/ArrayMap/0methodref$getEntry$Type",1923),lAn(1921,345,rVn,uT),EWn.cd=function(){return VL(this.a,this.b)},EWn.dd=function(){return this.a.nd(this.b)},EWn.ed=function(n){return this.a.od(this.b,n)},EWn.b=0,gX(zWn,"ArrayTable/ArrayMap/1",1921),lAn(1922,386,UWn,qL),EWn.Xb=function(n){return IX(this.a,n)},gX(zWn,"ArrayTable/ArrayMap/2",1922),lAn(1920,828,QWn,iU),EWn.md=function(){return"Column"},EWn.nd=function(n){return G6(this.b,this.a,n)},EWn.od=function(n,t){return Tun(this.b,this.a,n,t)},EWn.a=0,gX(zWn,"ArrayTable/Row",1920),lAn(829,828,QWn,GL),EWn.nd=function(n){return new iU(this.a,n)},EWn.zc=function(n,t){return _B(t,83),wk()},EWn.od=function(n,t){return _B(t,83),dk()},EWn.md=function(){return"Row"},gX(zWn,"ArrayTable/RowMap",829),lAn(1120,1,sVn,oT),EWn.qd=function(){return-262&this.a.qd()},EWn.rd=function(){return this.a.rd()},EWn.Nb=function(n){this.a.Nb(new iT(n,this.b))},EWn.sd=function(n){return this.a.sd(new eT(n,this.b))},gX(zWn,"CollectSpliterators/1",1120),lAn(1121,1,hVn,eT),EWn.td=function(n){this.a.td(this.b.Kb(n))},gX(zWn,"CollectSpliterators/1/lambda$0$Type",1121),lAn(1122,1,hVn,iT),EWn.td=function(n){this.a.td(this.b.Kb(n))},gX(zWn,"CollectSpliterators/1/lambda$1$Type",1122),lAn(1123,1,sVn,B2),EWn.qd=function(){return this.a},EWn.rd=function(){return this.d&&(this.b=j$(this.b,this.d.rd())),j$(this.b,0)},EWn.Nb=function(n){this.d&&(this.d.Nb(n),this.d=null),this.c.Nb(new tT(this.e,n)),this.b=0},EWn.sd=function(n){for(;;){if(this.d&&this.d.sd(n))return QC(this.b,fVn)&&(this.b=tbn(this.b,1)),!0;if(this.d=null,!this.c.sd(new rT(this,this.e)))return!1}},EWn.a=0,EWn.b=0,gX(zWn,"CollectSpliterators/1FlatMapSpliterator",1123),lAn(1124,1,hVn,rT),EWn.td=function(n){bK(this.a,this.b,n)},gX(zWn,"CollectSpliterators/1FlatMapSpliterator/lambda$0$Type",1124),lAn(1125,1,hVn,tT),EWn.td=function(n){aL(this.b,this.a,n)},gX(zWn,"CollectSpliterators/1FlatMapSpliterator/lambda$1$Type",1125),lAn(1117,1,sVn,lK),EWn.qd=function(){return 16464|this.b},EWn.rd=function(){return this.a.rd()},EWn.Nb=function(n){this.a.xe(new aT(n,this.c))},EWn.sd=function(n){return this.a.ye(new cT(n,this.c))},EWn.b=0,gX(zWn,"CollectSpliterators/1WithCharacteristics",1117),lAn(1118,1,lVn,cT),EWn.ud=function(n){this.a.td(this.b.ld(n))},gX(zWn,"CollectSpliterators/1WithCharacteristics/lambda$0$Type",1118),lAn(1119,1,lVn,aT),EWn.ud=function(n){this.a.td(this.b.ld(n))},gX(zWn,"CollectSpliterators/1WithCharacteristics/lambda$1$Type",1119),lAn(245,1,bVn),EWn.wd=function(n){return this.vd(_B(n,245))},EWn.vd=function(n){var t;return n==(Zm(),Rnt)?1:n==(ny(),Dnt)?-1:(YH(),0!=(t=$cn(this.a,n.a))?t:iL(this,519)==iL(n,519)?0:iL(this,519)?1:-1)},EWn.zd=function(){return this.a},EWn.Fb=function(n){return Ldn(this,n)},gX(zWn,"Cut",245),lAn(1761,245,bVn,$k),EWn.vd=function(n){return n==this?0:1},EWn.xd=function(n){throw Fp(new ov)},EWn.yd=function(n){n.a+="+∞)"},EWn.zd=function(){throw Fp(new Ky(wVn))},EWn.Hb=function(){return OT(),nvn(this)},EWn.Ad=function(n){return!1},EWn.Ib=function(){return"+∞"},gX(zWn,"Cut/AboveAll",1761),lAn(519,245,{245:1,519:1,3:1,35:1},tN),EWn.xd=function(n){cO((n.a+="(",n),this.a)},EWn.yd=function(n){LX(cO(n,this.a),93)},EWn.Hb=function(){return~Yon(this.a)},EWn.Ad=function(n){return YH(),$cn(this.a,n)<0},EWn.Ib=function(){return"/"+this.a+"\\"},gX(zWn,"Cut/AboveValue",519),lAn(1760,245,bVn,Lk),EWn.vd=function(n){return n==this?0:-1},EWn.xd=function(n){n.a+="(-∞"},EWn.yd=function(n){throw Fp(new ov)},EWn.zd=function(){throw Fp(new Ky(wVn))},EWn.Hb=function(){return OT(),nvn(this)},EWn.Ad=function(n){return!0},EWn.Ib=function(){return"-∞"},gX(zWn,"Cut/BelowAll",1760),lAn(1762,245,bVn,eN),EWn.xd=function(n){cO((n.a+="[",n),this.a)},EWn.yd=function(n){LX(cO(n,this.a),41)},EWn.Hb=function(){return Yon(this.a)},EWn.Ad=function(n){return YH(),$cn(this.a,n)<=0},EWn.Ib=function(){return"\\"+this.a+"/"},gX(zWn,"Cut/BelowValue",1762),lAn(537,1,dVn),EWn.Jc=function(n){n5(this,n)},EWn.Ib=function(){return Fln(_B(UQ(this,"use Optional.orNull() instead of Optional.or(null)"),20).Kc())},gX(zWn,"FluentIterable",537),lAn(433,537,dVn,IO),EWn.Kc=function(){return new az(JL(this.a.Kc(),new h))},gX(zWn,"FluentIterable/2",433),lAn(1046,537,dVn,CO),EWn.Kc=function(){return $U(this)},gX(zWn,"FluentIterable/3",1046),lAn(708,386,UWn,UL),EWn.Xb=function(n){return this.a[n].Kc()},gX(zWn,"FluentIterable/3/1",708),lAn(1972,1,{}),EWn.Ib=function(){return _bn(this.Bd().b)},gX(zWn,"ForwardingObject",1972),lAn(1973,1972,gVn),EWn.Bd=function(){return this.Cd()},EWn.Jc=function(n){n5(this,n)},EWn.Lc=function(){return this.Oc()},EWn.Nc=function(){return new l1(this,0)},EWn.Oc=function(){return new xq(null,this.Nc())},EWn.Fc=function(n){return this.Cd(),aE()},EWn.Gc=function(n){return this.Cd(),uE()},EWn.$b=function(){this.Cd(),oE()},EWn.Hc=function(n){return this.Cd().Hc(n)},EWn.Ic=function(n){return this.Cd().Ic(n)},EWn.dc=function(){return this.Cd().b.dc()},EWn.Kc=function(){return this.Cd().Kc()},EWn.Mc=function(n){return this.Cd(),sE()},EWn.gc=function(){return this.Cd().b.gc()},EWn.Pc=function(){return this.Cd().Pc()},EWn.Qc=function(n){return this.Cd().Qc(n)},gX(zWn,"ForwardingCollection",1973),lAn(1980,28,pVn),EWn.Kc=function(){return this.Ed()},EWn.Fc=function(n){throw Fp(new dv)},EWn.Gc=function(n){throw Fp(new dv)},EWn.$b=function(){throw Fp(new dv)},EWn.Hc=function(n){return null!=n&&vwn(this,n,!1)},EWn.Dd=function(){switch(this.gc()){case 0:return UX(),UX(),Knt;case 1:return UX(),new Mq(vX(this.Ed().Pb()));default:return new rU(this,this.Pc())}},EWn.Mc=function(n){throw Fp(new dv)},gX(zWn,"ImmutableCollection",1980),lAn(712,1980,pVn,ev),EWn.Kc=function(){return A9(this.a.Kc())},EWn.Hc=function(n){return null!=n&&this.a.Hc(n)},EWn.Ic=function(n){return this.a.Ic(n)},EWn.dc=function(){return this.a.dc()},EWn.Ed=function(){return A9(this.a.Kc())},EWn.gc=function(){return this.a.gc()},EWn.Pc=function(){return this.a.Pc()},EWn.Qc=function(n){return this.a.Qc(n)},EWn.Ib=function(){return _bn(this.a)},gX(zWn,"ForwardingImmutableCollection",712),lAn(152,1980,vVn),EWn.Kc=function(){return this.Ed()},EWn.Yc=function(){return this.Fd(0)},EWn.Zc=function(n){return this.Fd(n)},EWn.ad=function(n){Rrn(this,n)},EWn.Nc=function(){return new l1(this,16)},EWn.bd=function(n,t){return this.Gd(n,t)},EWn.Vc=function(n,t){throw Fp(new dv)},EWn.Wc=function(n,t){throw Fp(new dv)},EWn.Fb=function(n){return BAn(this,n)},EWn.Hb=function(){return Pan(this)},EWn.Xc=function(n){return null==n?-1:jmn(this,n)},EWn.Ed=function(){return this.Fd(0)},EWn.Fd=function(n){return tx(this,n)},EWn.$c=function(n){throw Fp(new dv)},EWn._c=function(n,t){throw Fp(new dv)},EWn.Gd=function(n,t){return ufn(new u1(new PT(this),n,t))},gX(zWn,"ImmutableList",152),lAn(2006,152,vVn),EWn.Kc=function(){return A9(this.Hd().Kc())},EWn.bd=function(n,t){return ufn(this.Hd().bd(n,t))},EWn.Hc=function(n){return null!=n&&this.Hd().Hc(n)},EWn.Ic=function(n){return this.Hd().Ic(n)},EWn.Fb=function(n){return $fn(this.Hd(),n)},EWn.Xb=function(n){return UC(this,n)},EWn.Hb=function(){return Yon(this.Hd())},EWn.Xc=function(n){return this.Hd().Xc(n)},EWn.dc=function(){return this.Hd().dc()},EWn.Ed=function(){return A9(this.Hd().Kc())},EWn.gc=function(){return this.Hd().gc()},EWn.Gd=function(n,t){return ufn(this.Hd().bd(n,t))},EWn.Pc=function(){return this.Hd().Qc(L8(Cnt,FWn,1,this.Hd().gc(),5,1))},EWn.Qc=function(n){return this.Hd().Qc(n)},EWn.Ib=function(){return _bn(this.Hd())},gX(zWn,"ForwardingImmutableList",2006),lAn(714,1,yVn),EWn.vc=function(){return hz(this)},EWn.wc=function(n){Ycn(this,n)},EWn.ec=function(){return fz(this)},EWn.yc=function(n,t,e){return Jln(this,n,t,e)},EWn.Cc=function(){return this.Ld()},EWn.$b=function(){throw Fp(new dv)},EWn._b=function(n){return null!=this.xc(n)},EWn.uc=function(n){return this.Ld().Hc(n)},EWn.Jd=function(){return new iv(this)},EWn.Kd=function(){return new rv(this)},EWn.Fb=function(n){return Osn(this,n)},EWn.Hb=function(){return hz(this).Hb()},EWn.dc=function(){return 0==this.gc()},EWn.zc=function(n,t){return gk()},EWn.Bc=function(n){throw Fp(new dv)},EWn.Ib=function(){return sSn(this)},EWn.Ld=function(){return this.e?this.e:this.e=this.Kd()},EWn.c=null,EWn.d=null,EWn.e=null,gX(zWn,"ImmutableMap",714),lAn(715,714,yVn),EWn._b=function(n){return Vj(this,n)},EWn.uc=function(n){return RT(this.b,n)},EWn.Id=function(){return ofn(new nl(this))},EWn.Jd=function(){return ofn(tV(this.b))},EWn.Kd=function(){return u_(),new ev(ZW(this.b))},EWn.Fb=function(n){return _T(this.b,n)},EWn.xc=function(n){return GK(this,n)},EWn.Hb=function(){return Yon(this.b.c)},EWn.dc=function(){return this.b.c.dc()},EWn.gc=function(){return this.b.c.gc()},EWn.Ib=function(){return _bn(this.b.c)},gX(zWn,"ForwardingImmutableMap",715),lAn(1974,1973,kVn),EWn.Bd=function(){return this.Md()},EWn.Cd=function(){return this.Md()},EWn.Nc=function(){return new l1(this,1)},EWn.Fb=function(n){return n===this||this.Md().Fb(n)},EWn.Hb=function(){return this.Md().Hb()},gX(zWn,"ForwardingSet",1974),lAn(1069,1974,kVn,nl),EWn.Bd=function(){return nV(this.a.b)},EWn.Cd=function(){return nV(this.a.b)},EWn.Hc=function(n){if(iL(n,42)&&null==_B(n,42).cd())return!1;try{return DT(nV(this.a.b),n)}catch(t){if(iL(t=hun(t),205))return!1;throw Fp(t)}},EWn.Md=function(){return nV(this.a.b)},EWn.Qc=function(n){var t;return t=PJ(nV(this.a.b),n),nV(this.a.b).b.gc()=0?"+":"")+(e/60|0),t=GO(i.Math.abs(e)%60),(dMn(),det)[this.q.getDay()]+" "+get[this.q.getMonth()]+" "+GO(this.q.getDate())+" "+GO(this.q.getHours())+":"+GO(this.q.getMinutes())+":"+GO(this.q.getSeconds())+" GMT"+n+t+" "+this.q.getFullYear()};var att,utt,ott,stt,htt,ftt,ltt,btt,wtt,dtt,gtt,ptt=gX(VWn,"Date",199);lAn(1915,199,jQn,Vkn),EWn.a=!1,EWn.b=0,EWn.c=0,EWn.d=0,EWn.e=0,EWn.f=0,EWn.g=!1,EWn.i=0,EWn.j=0,EWn.k=0,EWn.n=0,EWn.o=0,EWn.p=0,gX("com.google.gwt.i18n.shared.impl","DateRecord",1915),lAn(1966,1,{}),EWn.fe=function(){return null},EWn.ge=function(){return null},EWn.he=function(){return null},EWn.ie=function(){return null},EWn.je=function(){return null},gX(EQn,"JSONValue",1966),lAn(216,1966,{216:1},Sl,jl),EWn.Fb=function(n){return!!iL(n,216)&&g0(this.a,_B(n,216).a)},EWn.ee=function(){return Bp},EWn.Hb=function(){return ZQ(this.a)},EWn.fe=function(){return this},EWn.Ib=function(){var n,t,e;for(e=new hN("["),t=0,n=this.a.length;t0&&(e.a+=","),cO(e,bnn(this,t));return e.a+="]",e.a},gX(EQn,"JSONArray",216),lAn(483,1966,{483:1},El),EWn.ee=function(){return Hp},EWn.ge=function(){return this},EWn.Ib=function(){return oN(),""+this.a},EWn.a=!1,gX(EQn,"JSONBoolean",483),lAn(985,60,_Vn,wy),gX(EQn,"JSONException",985),lAn(1023,1966,{},v),EWn.ee=function(){return Xp},EWn.Ib=function(){return qWn},gX(EQn,"JSONNull",1023),lAn(258,1966,{258:1},Tl),EWn.Fb=function(n){return!!iL(n,258)&&this.a==_B(n,258).a},EWn.ee=function(){return qp},EWn.Hb=function(){return XO(this.a)},EWn.he=function(){return this},EWn.Ib=function(){return this.a+""},EWn.a=0,gX(EQn,"JSONNumber",258),lAn(183,1966,{183:1},dy,Ml),EWn.Fb=function(n){return!!iL(n,183)&&g0(this.a,_B(n,183).a)},EWn.ee=function(){return Gp},EWn.Hb=function(){return ZQ(this.a)},EWn.ie=function(){return this},EWn.Ib=function(){var n,t,e,i,r,c;for(c=new hN("{"),n=!0,i=0,r=(e=yrn(this,L8(Wtt,uVn,2,0,6,1))).length;i=0?":"+this.c:"")+")"},EWn.c=0;var Ktt=gX(xWn,"StackTraceElement",310);IWn={3:1,475:1,35:1,2:1};var _tt,Ftt,Btt,Htt,qtt,Gtt,ztt,Utt,Xtt,Wtt=gX(xWn,BVn,2);lAn(107,418,{475:1},Tk,Mk,sN),gX(xWn,"StringBuffer",107),lAn(100,418,{475:1},Sk,Pk,hN),gX(xWn,"StringBuilder",100),lAn(687,73,$Qn,Ik),gX(xWn,"StringIndexOutOfBoundsException",687),lAn(2043,1,{}),lAn(844,1,{},x),EWn.Kb=function(n){return _B(n,78).e},gX(xWn,"Throwable/lambda$0$Type",844),lAn(41,60,{3:1,102:1,60:1,78:1,41:1},dv,Zy),gX(xWn,"UnsupportedOperationException",41),lAn(240,236,{3:1,35:1,236:1,240:1},mnn,lE),EWn.wd=function(n){return Q_n(this,_B(n,240))},EWn.ke=function(){return fSn(nqn(this))},EWn.Fb=function(n){var t;return this===n||!!iL(n,240)&&(t=_B(n,240),this.e==t.e&&0==Q_n(this,t))},EWn.Hb=function(){var n;return 0!=this.b?this.b:this.a<54?(n=san(this.f),this.b=bG(n0(n,-1)),this.b=33*this.b+bG(n0(mz(n,32),-1)),this.b=17*this.b+SY(this.e),this.b):(this.b=17*Dhn(this.c)+SY(this.e),this.b)},EWn.Ib=function(){return nqn(this)},EWn.a=0,EWn.b=0,EWn.d=0,EWn.e=0,EWn.f=0;var Vtt,Qtt,Jtt,Ytt,Ztt,net,tet=gX("java.math","BigDecimal",240);lAn(91,236,{3:1,35:1,236:1,91:1},xpn,z6,hU,gEn,Sgn,OA),EWn.wd=function(n){return Zdn(this,_B(n,91))},EWn.ke=function(){return fSn(BXn(this,0))},EWn.Fb=function(n){return uwn(this,n)},EWn.Hb=function(){return Dhn(this)},EWn.Ib=function(){return BXn(this,0)},EWn.b=-2,EWn.c=0,EWn.d=0,EWn.e=0;var eet,iet,ret,cet,aet=gX("java.math","BigInteger",91);lAn(488,1967,QWn),EWn.$b=function(){OU(this)},EWn._b=function(n){return oU(this,n)},EWn.uc=function(n){return Asn(this,n,this.g)||Asn(this,n,this.f)},EWn.vc=function(){return new Mb(this)},EWn.xc=function(n){return xX(this,n)},EWn.zc=function(n,t){return XW(this,n,t)},EWn.Bc=function(n){return g6(this,n)},EWn.gc=function(){return $T(this)},gX(VWn,"AbstractHashMap",488),lAn(261,YWn,ZWn,Mb),EWn.$b=function(){this.a.$b()},EWn.Hc=function(n){return p2(this,n)},EWn.Kc=function(){return new csn(this.a)},EWn.Mc=function(n){var t;return!!p2(this,n)&&(t=_B(n,42).cd(),this.a.Bc(t),!0)},EWn.gc=function(){return this.a.gc()},gX(VWn,"AbstractHashMap/EntrySet",261),lAn(262,1,WWn,csn),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return Ztn(this)},EWn.Ob=function(){return this.b},EWn.Qb=function(){a9(this)},EWn.b=!1,gX(VWn,"AbstractHashMap/EntrySetIterator",262),lAn(417,1,WWn,Tb),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return rS(this)},EWn.Pb=function(){return pQ(this)},EWn.Qb=function(){sW(this)},EWn.b=0,EWn.c=-1,gX(VWn,"AbstractList/IteratorImpl",417),lAn(96,417,iVn,E2),EWn.Qb=function(){sW(this)},EWn.Rb=function(n){vR(this,n)},EWn.Sb=function(){return this.b>0},EWn.Tb=function(){return this.b},EWn.Ub=function(){return Mx(this.b>0),this.a.Xb(this.c=--this.b)},EWn.Vb=function(){return this.b-1},EWn.Wb=function(n){Ex(-1!=this.c),this.a._c(this.c,n)},gX(VWn,"AbstractList/ListIteratorImpl",96),lAn(219,52,AVn,u1),EWn.Vc=function(n,t){AZ(n,this.b),this.c.Vc(this.a+n,t),++this.b},EWn.Xb=function(n){return h1(n,this.b),this.c.Xb(this.a+n)},EWn.$c=function(n){var t;return h1(n,this.b),t=this.c.$c(this.a+n),--this.b,t},EWn._c=function(n,t){return h1(n,this.b),this.c._c(this.a+n,t)},EWn.gc=function(){return this.b},EWn.a=0,EWn.b=0,gX(VWn,"AbstractList/SubList",219),lAn(384,YWn,ZWn,Sb),EWn.$b=function(){this.a.$b()},EWn.Hc=function(n){return this.a._b(n)},EWn.Kc=function(){return new Pb(this.a.vc().Kc())},EWn.Mc=function(n){return!!this.a._b(n)&&(this.a.Bc(n),!0)},EWn.gc=function(){return this.a.gc()},gX(VWn,"AbstractMap/1",384),lAn(691,1,WWn,Pb),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return this.a.Ob()},EWn.Pb=function(){return _B(this.a.Pb(),42).cd()},EWn.Qb=function(){this.a.Qb()},gX(VWn,"AbstractMap/1/1",691),lAn(226,28,JWn,Ib),EWn.$b=function(){this.a.$b()},EWn.Hc=function(n){return this.a.uc(n)},EWn.Kc=function(){return new Db(this.a.vc().Kc())},EWn.gc=function(){return this.a.gc()},gX(VWn,"AbstractMap/2",226),lAn(294,1,WWn,Db),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return this.a.Ob()},EWn.Pb=function(){return _B(this.a.Pb(),42).dd()},EWn.Qb=function(){this.a.Qb()},gX(VWn,"AbstractMap/2/1",294),lAn(484,1,{484:1,42:1}),EWn.Fb=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),iV(this.d,t.cd())&&iV(this.e,t.dd()))},EWn.cd=function(){return this.d},EWn.dd=function(){return this.e},EWn.Hb=function(){return DA(this.d)^DA(this.e)},EWn.ed=function(n){return dR(this,n)},EWn.Ib=function(){return this.d+"="+this.e},gX(VWn,"AbstractMap/AbstractEntry",484),lAn(383,484,{484:1,383:1,42:1},MS),gX(VWn,"AbstractMap/SimpleEntry",383),lAn(1984,1,XQn),EWn.Fb=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),iV(this.cd(),t.cd())&&iV(this.dd(),t.dd()))},EWn.Hb=function(){return DA(this.cd())^DA(this.dd())},EWn.Ib=function(){return this.cd()+"="+this.dd()},gX(VWn,cVn,1984),lAn(1992,1967,nVn),EWn.tc=function(n){return B5(this,n)},EWn._b=function(n){return NK(this,n)},EWn.vc=function(){return new _b(this)},EWn.xc=function(n){return BC(hsn(this,n))},EWn.ec=function(){return new Rb(this)},gX(VWn,"AbstractNavigableMap",1992),lAn(739,YWn,ZWn,_b),EWn.Hc=function(n){return iL(n,42)&&B5(this.b,_B(n,42))},EWn.Kc=function(){return new _R(this.b)},EWn.Mc=function(n){var t;return!!iL(n,42)&&(t=_B(n,42),q8(this.b,t))},EWn.gc=function(){return this.b.c},gX(VWn,"AbstractNavigableMap/EntrySet",739),lAn(493,YWn,eVn,Rb),EWn.Nc=function(){return new lS(this)},EWn.$b=function(){py(this.a)},EWn.Hc=function(n){return NK(this.a,n)},EWn.Kc=function(){return new Kb(new _R(new LN(this.a).b))},EWn.Mc=function(n){return!!NK(this.a,n)&&(OY(this.a,n),!0)},EWn.gc=function(){return this.a.c},gX(VWn,"AbstractNavigableMap/NavigableKeySet",493),lAn(494,1,WWn,Kb),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return rS(this.a.a)},EWn.Pb=function(){return px(this.a).cd()},EWn.Qb=function(){n_(this.a)},gX(VWn,"AbstractNavigableMap/NavigableKeySet/1",494),lAn(2004,28,JWn),EWn.Fc=function(n){return K8(nMn(this,n)),!0},EWn.Gc=function(n){return mW(n),gH(n!=this,"Can't add a queue to itself"),Krn(this,n)},EWn.$b=function(){for(;null!=pnn(this););},gX(VWn,"AbstractQueue",2004),lAn(302,28,{4:1,20:1,28:1,14:1},Ap,b1),EWn.Fc=function(n){return l3(this,n),!0},EWn.$b=function(){a4(this)},EWn.Hc=function(n){return lun(new fV(this),n)},EWn.dc=function(){return Uy(this)},EWn.Kc=function(){return new fV(this)},EWn.Mc=function(n){return HY(new fV(this),n)},EWn.gc=function(){return this.c-this.b&this.a.length-1},EWn.Nc=function(){return new l1(this,272)},EWn.Qc=function(n){var t;return t=this.c-this.b&this.a.length-1,n.lengtht&&OX(n,t,null),n},EWn.b=0,EWn.c=0,gX(VWn,"ArrayDeque",302),lAn(446,1,WWn,fV),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return this.a!=this.b},EWn.Pb=function(){return Rhn(this)},EWn.Qb=function(){nin(this)},EWn.a=0,EWn.b=0,EWn.c=-1,gX(VWn,"ArrayDeque/IteratorImpl",446),lAn(12,52,WQn,$p,Q6,ZK),EWn.Vc=function(n,t){mG(this,n,t)},EWn.Fc=function(n){return UB(this,n)},EWn.Wc=function(n,t){return ahn(this,n,t)},EWn.Gc=function(n){return wun(this,n)},EWn.$b=function(){this.c=L8(Cnt,FWn,1,0,5,1)},EWn.Hc=function(n){return-1!=k7(this,n,0)},EWn.Jc=function(n){Itn(this,n)},EWn.Xb=function(n){return Lq(this,n)},EWn.Xc=function(n){return k7(this,n,0)},EWn.dc=function(){return 0==this.c.length},EWn.Kc=function(){return new Ub(this)},EWn.$c=function(n){return u6(this,n)},EWn.Mc=function(n){return v7(this,n)},EWn.Ud=function(n,t){o1(this,n,t)},EWn._c=function(n,t){return i5(this,n,t)},EWn.gc=function(){return this.c.length},EWn.ad=function(n){p$(this,n)},EWn.Pc=function(){return fx(this)},EWn.Qc=function(n){return Wgn(this,n)};var uet,oet,set,het,fet,bet,wet,det,get,pet=gX(VWn,"ArrayList",12);lAn(7,1,WWn,Ub),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return v$(this)},EWn.Pb=function(){return Y1(this)},EWn.Qb=function(){CU(this)},EWn.a=0,EWn.b=-1,gX(VWn,"ArrayList/1",7),lAn(2013,i.Function,{},T),EWn.te=function(n,t){return Mln(n,t)},lAn(154,52,VQn,Qy),EWn.Hc=function(n){return-1!=fin(this,n)},EWn.Jc=function(n){var t,e,i,r;for(mW(n),i=0,r=(e=this.a).length;i>>0).toString(16))},EWn.f=0,EWn.i=DQn;var uit,oit,sit,hit,fit=gX(SJn,"CNode",57);lAn(814,1,{},Uv),gX(SJn,"CNode/CNodeBuilder",814),lAn(1525,1,{},dn),EWn.Oe=function(n,t){return 0},EWn.Pe=function(n,t){return 0},gX(SJn,IJn,1525),lAn(1790,1,{},gn),EWn.Le=function(n){var t,e,r,c,a,u,o,s,h,f,l,b,w,d,g;for(h=xQn,r=new Ub(n.a.b);r.ae.d.c||e.d.c==r.d.c&&e.d.b0?n+this.n.d+this.n.a:0},EWn.Se=function(){var n,t,e,r,c;if(c=0,this.e)this.b?c=this.b.a:this.a[1][1]&&(c=this.a[1][1].Se());else if(this.g)c=Vbn(this,Ikn(this,null,!0));else for(Ntn(),e=0,r=(t=Mun(Hk(Xit,1),OVn,232,0,[Hit,qit,Git])).length;e0?c+this.n.b+this.n.c:0},EWn.Te=function(){var n,t,e,i,r;if(this.g)for(n=Ikn(this,null,!1),Ntn(),i=0,r=(e=Mun(Hk(Xit,1),OVn,232,0,[Hit,qit,Git])).length;i0&&(r[0]+=this.d,e-=r[0]),r[2]>0&&(r[2]+=this.d,e-=r[2]),this.c.a=i.Math.max(0,e),this.c.d=t.d+n.d+(this.c.a-e)/2,r[1]=i.Math.max(r[1],e),W5(this,qit,t.d+n.d+r[0]-(r[1]-e)/2,r)},EWn.b=null,EWn.d=0,EWn.e=!1,EWn.f=!1,EWn.g=!1;var Wit,Vit,Qit,Jit=0,Yit=0;gX(ZJn,"GridContainerCell",1473),lAn(461,22,{3:1,35:1,22:1,461:1},HS);var Zit,nrt=_en(ZJn,"HorizontalLabelAlignment",461,Gnt,p1,w_);lAn(306,212,{212:1,306:1},vY,ltn,DJ),EWn.Re=function(){return UH(this)},EWn.Se=function(){return XH(this)},EWn.a=0,EWn.c=!1;var trt,ert,irt,rrt=gX(ZJn,"LabelCell",306);lAn(244,326,{212:1,326:1,244:1},Pgn),EWn.Re=function(){return ECn(this)},EWn.Se=function(){return TCn(this)},EWn.Te=function(){RFn(this)},EWn.Ue=function(){HFn(this)},EWn.b=0,EWn.c=0,EWn.d=!1,gX(ZJn,"StripContainerCell",244),lAn(1626,1,NVn,En),EWn.Mb=function(n){return Wy(_B(n,212))},gX(ZJn,"StripContainerCell/lambda$0$Type",1626),lAn(1627,1,{},Tn),EWn.Fe=function(n){return _B(n,212).Se()},gX(ZJn,"StripContainerCell/lambda$1$Type",1627),lAn(1628,1,NVn,Mn),EWn.Mb=function(n){return Vy(_B(n,212))},gX(ZJn,"StripContainerCell/lambda$2$Type",1628),lAn(1629,1,{},Sn),EWn.Fe=function(n){return _B(n,212).Re()},gX(ZJn,"StripContainerCell/lambda$3$Type",1629),lAn(462,22,{3:1,35:1,22:1,462:1},qS);var crt,art,urt,ort,srt,hrt,frt,lrt,brt,wrt,drt,grt,prt,vrt,mrt,yrt,krt,jrt,Ert,Trt,Mrt,Srt,Prt,Irt=_en(ZJn,"VerticalLabelAlignment",462,Gnt,v1,d_);lAn(789,1,{},nUn),EWn.c=0,EWn.d=0,EWn.k=0,EWn.s=0,EWn.t=0,EWn.v=!1,EWn.w=0,EWn.D=!1,gX(uYn,"NodeContext",789),lAn(1471,1,EJn,Pn),EWn.ue=function(n,t){return VO(_B(n,61),_B(t,61))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(uYn,"NodeContext/0methodref$comparePortSides$Type",1471),lAn(1472,1,EJn,In),EWn.ue=function(n,t){return GTn(_B(n,111),_B(t,111))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(uYn,"NodeContext/1methodref$comparePortContexts$Type",1472),lAn(159,22,{3:1,35:1,22:1,159:1},acn);var Crt,Ort,Art,$rt,Lrt,Nrt,xrt,Drt=_en(uYn,"NodeLabelLocation",159,Gnt,Zgn,g_);lAn(111,1,{111:1},EOn),EWn.a=!1,gX(uYn,"PortContext",111),lAn(1476,1,hVn,Cn),EWn.td=function(n){SE(_B(n,306))},gX(hYn,fYn,1476),lAn(1477,1,NVn,On),EWn.Mb=function(n){return!!_B(n,111).c},gX(hYn,lYn,1477),lAn(1478,1,hVn,An),EWn.td=function(n){SE(_B(n,111).c)},gX(hYn,"LabelPlacer/lambda$2$Type",1478),lAn(1475,1,hVn,Ln),EWn.td=function(n){BD(),Vp(_B(n,111))},gX(hYn,"NodeLabelAndSizeUtilities/lambda$0$Type",1475),lAn(790,1,hVn,O_),EWn.td=function(n){xM(this.b,this.c,this.a,_B(n,181))},EWn.a=!1,EWn.c=!1,gX(hYn,"NodeLabelCellCreator/lambda$0$Type",790),lAn(1474,1,hVn,Sw),EWn.td=function(n){Pv(this.a,_B(n,181))},gX(hYn,"PortContextCreator/lambda$0$Type",1474),lAn(1829,1,{},Nn),gX(wYn,"GreedyRectangleStripOverlapRemover",1829),lAn(1830,1,EJn,$n),EWn.ue=function(n,t){return KN(_B(n,222),_B(t,222))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(wYn,"GreedyRectangleStripOverlapRemover/0methodref$compareByYCoordinate$Type",1830),lAn(1786,1,{},Jv),EWn.a=5,EWn.e=0,gX(wYn,"RectangleStripOverlapRemover",1786),lAn(1787,1,EJn,Dn),EWn.ue=function(n,t){return _N(_B(n,222),_B(t,222))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(wYn,"RectangleStripOverlapRemover/0methodref$compareLeftRectangleBorders$Type",1787),lAn(1789,1,EJn,Rn),EWn.ue=function(n,t){return QU(_B(n,222),_B(t,222))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(wYn,"RectangleStripOverlapRemover/1methodref$compareRightRectangleBorders$Type",1789),lAn(406,22,{3:1,35:1,22:1,406:1},GS);var Rrt,Krt,_rt,Frt,Brt,Hrt=_en(wYn,"RectangleStripOverlapRemover/OverlapRemovalDirection",406,Gnt,V2,p_);lAn(222,1,{222:1},LG),gX(wYn,"RectangleStripOverlapRemover/RectangleNode",222),lAn(1788,1,hVn,Pw),EWn.td=function(n){Smn(this.a,_B(n,222))},gX(wYn,"RectangleStripOverlapRemover/lambda$1$Type",1788),lAn(1304,1,EJn,Kn),EWn.ue=function(n,t){return qHn(_B(n,167),_B(t,167))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator",1304),lAn(1307,1,{},_n),EWn.Kb=function(n){return _B(n,324).a},gX(gYn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$0$Type",1307),lAn(1308,1,NVn,Fn),EWn.Mb=function(n){return _B(n,323).a},gX(gYn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$1$Type",1308),lAn(1309,1,NVn,Bn),EWn.Mb=function(n){return _B(n,323).a},gX(gYn,"PolyominoCompactor/CornerCasesGreaterThanRestComparator/lambda$2$Type",1309),lAn(1302,1,EJn,Hn),EWn.ue=function(n,t){return URn(_B(n,167),_B(t,167))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator",1302),lAn(1305,1,{},xn),EWn.Kb=function(n){return _B(n,324).a},gX(gYn,"PolyominoCompactor/MinNumOfExtensionDirectionsComparator/lambda$0$Type",1305),lAn(767,1,EJn,qn),EWn.ue=function(n,t){return Gan(_B(n,167),_B(t,167))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/MinNumOfExtensionsComparator",767),lAn(1300,1,EJn,Gn),EWn.ue=function(n,t){return Win(_B(n,321),_B(t,321))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/MinPerimeterComparator",1300),lAn(1301,1,EJn,zn),EWn.ue=function(n,t){return rvn(_B(n,321),_B(t,321))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/MinPerimeterComparatorWithShape",1301),lAn(1303,1,EJn,Un),EWn.ue=function(n,t){return _Kn(_B(n,167),_B(t,167))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(gYn,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator",1303),lAn(1306,1,{},Xn),EWn.Kb=function(n){return _B(n,324).a},gX(gYn,"PolyominoCompactor/SingleExtensionSideGreaterThanRestComparator/lambda$0$Type",1306),lAn(777,1,{},NS),EWn.Ce=function(n,t){return I2(this,_B(n,46),_B(t,167))},gX(gYn,"SuccessorCombination",777),lAn(644,1,{},Wn),EWn.Ce=function(n,t){var e;return zCn((e=_B(n,46),_B(t,167),e))},gX(gYn,"SuccessorJitter",644),lAn(643,1,{},Vn),EWn.Ce=function(n,t){var e;return fxn((e=_B(n,46),_B(t,167),e))},gX(gYn,"SuccessorLineByLine",643),lAn(568,1,{},Qn),EWn.Ce=function(n,t){var e;return s$n((e=_B(n,46),_B(t,167),e))},gX(gYn,"SuccessorManhattan",568),lAn(1356,1,{},Jn),EWn.Ce=function(n,t){var e;return yNn((e=_B(n,46),_B(t,167),e))},gX(gYn,"SuccessorMaxNormWindingInMathPosSense",1356),lAn(400,1,{},Iw),EWn.Ce=function(n,t){return _U(this,n,t)},EWn.c=!1,EWn.d=!1,EWn.e=!1,EWn.f=!1,gX(gYn,"SuccessorQuadrantsGeneric",400),lAn(1357,1,{},Yn),EWn.Kb=function(n){return _B(n,324).a},gX(gYn,"SuccessorQuadrantsGeneric/lambda$0$Type",1357),lAn(323,22,{3:1,35:1,22:1,323:1},RS),EWn.a=!1;var qrt,Grt=_en(kYn,jYn,323,Gnt,Y2,v_);lAn(1298,1,{}),EWn.Ib=function(){var n,t,e,i,r,c;for(e=" ",n=tln(0),r=0;r=0?"b"+n+"["+c5(this.a)+"]":"b["+c5(this.a)+"]":"b_"+MN(this)},gX(iZn,"FBendpoint",559),lAn(282,134,{3:1,282:1,94:1,134:1},PR),EWn.Ib=function(){return c5(this)},gX(iZn,"FEdge",282),lAn(231,134,{3:1,231:1,94:1,134:1},v6);var Sct,Pct,Ict,Cct,Oct,Act,$ct,Lct,Nct,xct,Dct=gX(iZn,"FGraph",231);lAn(447,357,{3:1,447:1,357:1,94:1,134:1},p4),EWn.Ib=function(){return null==this.b||0==this.b.length?"l["+c5(this.a)+"]":"l_"+this.b},gX(iZn,"FLabel",447),lAn(144,357,{3:1,144:1,357:1,94:1,134:1},BX),EWn.Ib=function(){return d0(this)},EWn.b=0,gX(iZn,"FNode",144),lAn(2003,1,{}),EWn.bf=function(n){uFn(this,n)},EWn.cf=function(){Bmn(this)},EWn.d=0,gX(cZn,"AbstractForceModel",2003),lAn(631,2003,{631:1},Aan),EWn.af=function(n,t){var e,r,c,a;return ZIn(this.f,n,t),c=zR(_$(t.d),n.d),a=i.Math.sqrt(c.a*c.a+c.b*c.b),r=i.Math.max(0,a-hW(n.e)/2-hW(t.e)/2),mL(c,((e=Bon(this.e,n,t))>0?-RU(r,this.c)*e:Lx(r,this.b)*_B(pMn(n,(sRn(),Jct)),19).a)/a),c},EWn.bf=function(n){uFn(this,n),this.a=_B(pMn(n,(sRn(),Bct)),19).a,this.c=Hy(ED(pMn(n,iat))),this.b=Hy(ED(pMn(n,Zct)))},EWn.df=function(n){return n0&&(a-=Ty(r,this.a)*e),mL(c,a*this.b/u),c},EWn.bf=function(n){var t,e,r,c,a,u,o;for(uFn(this,n),this.b=Hy(ED(pMn(n,(sRn(),rat)))),this.c=this.b/_B(pMn(n,Bct),19).a,r=n.e.c.length,a=0,c=0,o=new Ub(n.e);o.a0},EWn.a=0,EWn.b=0,EWn.c=0,gX(cZn,"FruchtermanReingoldModel",632),lAn(849,1,WJn,qh),EWn.Qe=function(n){Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,aZn),""),"Force Model"),"Determines the model for force calculation."),Ict),(MPn(),wMt)),Oat),Yln((epn(),oMt))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,uZn),""),"Iterations"),"The number of iterations on the force model."),tln(300)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,oZn),""),"Repulsive Power"),"Determines how many bend points are added to the edge; such bend points are regarded as repelling particles in the force model"),tln(0)),gMt),Ctt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,sZn),""),"FR Temperature"),"The temperature is used as a scaling factor for particle displacements."),hZn),bMt),Mtt),Yln(oMt)))),r2(n,sZn,aZn,Lct),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,fZn),""),"Eades Repulsion"),"Factor for repulsive forces in Eades' model."),5),bMt),Mtt),Yln(oMt)))),r2(n,fZn,aZn,Oct),dUn((new Gh,n))},gX(lZn,"ForceMetaDataProvider",849),lAn(424,22,{3:1,35:1,22:1,424:1},zS);var Rct,Kct,_ct,Fct,Bct,Hct,qct,Gct,zct,Uct,Xct,Wct,Vct,Qct,Jct,Yct,Zct,nat,tat,eat,iat,rat,cat,aat,uat,oat,sat,hat,fat,lat,bat,wat,dat,gat,pat,vat,mat,yat,kat,jat,Eat,Tat,Mat,Sat,Pat,Iat,Cat,Oat=_en(lZn,"ForceModelStrategy",424,Gnt,rY,k_);lAn(988,1,WJn,Gh),EWn.Qe=function(n){dUn(n)},gX(lZn,"ForceOptions",988),lAn(989,1,{},dt),EWn.$e=function(){return new Hv},EWn._e=function(n){},gX(lZn,"ForceOptions/ForceFactory",989),lAn(850,1,WJn,zh),EWn.Qe=function(n){Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,$Zn),""),"Fixed Position"),"Prevent that the node is moved by the layout algorithm."),(oN(),!1)),(MPn(),lMt)),mtt),Yln((epn(),uMt))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,LZn),""),"Desired Edge Length"),"Either specified for parent nodes or for individual edges, where the latter takes higher precedence."),100),bMt),Mtt),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[cMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,NZn),""),"Layout Dimension"),"Dimensions that are permitted to be altered during layout."),fat),wMt),Fat),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,xZn),""),"Stress Epsilon"),"Termination criterion for the iterative process."),hZn),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,DZn),""),"Iteration Limit"),"Maximum number of performed iterations. Takes higher precedence than 'epsilon'."),tln(NWn)),gMt),Ctt),Yln(oMt)))),GGn((new Uh,n))},gX(lZn,"StressMetaDataProvider",850),lAn(992,1,WJn,Uh),EWn.Qe=function(n){GGn(n)},gX(lZn,"StressOptions",992),lAn(993,1,{},gt),EWn.$e=function(){return new IR},EWn._e=function(n){},gX(lZn,"StressOptions/StressFactory",993),lAn(1128,209,$Yn,IR),EWn.Ze=function(n,t){var e,i,r,c;for(ITn(t,KZn,1),By(jD(JAn(n,(ekn(),mat))))?By(jD(JAn(n,Mat)))||yY(new jw((HM(),new Ny(n)))):gLn(new Hv,n,pcn(t,1)),i=son(n),c=(e=FFn(this.a,i)).Kc();c.Ob();)(r=_B(c.Pb(),231)).e.c.length<=1||(FHn(this.b,r),t$n(this.b),Itn(r.d,new pt));TUn(i=HUn(e)),FSn(t)},gX(FZn,"StressLayoutProvider",1128),lAn(1129,1,hVn,pt),EWn.td=function(n){RBn(_B(n,447))},gX(FZn,"StressLayoutProvider/lambda$0$Type",1129),lAn(990,1,{},jv),EWn.c=0,EWn.e=0,EWn.g=0,gX(FZn,"StressMajorization",990),lAn(379,22,{3:1,35:1,22:1,379:1},US);var Aat,$at,Lat,Nat,xat,Dat,Rat,Kat,_at,Fat=_en(FZn,"StressMajorization/Dimension",379,Gnt,y1,j_);lAn(991,1,EJn,Lw),EWn.ue=function(n,t){return TK(this.a,_B(n,144),_B(t,144))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(FZn,"StressMajorization/lambda$0$Type",991),lAn(1229,1,{},N0),gX(HZn,"ElkLayered",1229),lAn(1230,1,hVn,vt),EWn.td=function(n){xCn(_B(n,37))},gX(HZn,"ElkLayered/lambda$0$Type",1230),lAn(1231,1,hVn,Nw),EWn.td=function(n){MK(this.a,_B(n,37))},gX(HZn,"ElkLayered/lambda$1$Type",1231),lAn(1263,1,{},O$),gX(HZn,"GraphConfigurator",1263),lAn(759,1,hVn,xw),EWn.td=function(n){XMn(this.a,_B(n,10))},gX(HZn,"GraphConfigurator/lambda$0$Type",759),lAn(760,1,{},mt),EWn.Kb=function(n){return Zkn(),new xq(null,new l1(_B(n,29).a,16))},gX(HZn,"GraphConfigurator/lambda$1$Type",760),lAn(761,1,hVn,Dw),EWn.td=function(n){XMn(this.a,_B(n,10))},gX(HZn,"GraphConfigurator/lambda$2$Type",761),lAn(1127,209,$Yn,Gv),EWn.Ze=function(n,t){var e;e=TBn(new Zv,n),HC(JAn(n,(FXn(),ugt)))===HC((cfn(),dIt))?ewn(this.a,e,t):lOn(this.a,e,t),wUn(new Wh,e)},gX(HZn,"LayeredLayoutProvider",1127),lAn(356,22,{3:1,35:1,22:1,356:1},XS);var Bat,Hat,qat,Gat=_en(HZn,"LayeredPhases",356,Gnt,u5,E_);lAn(1651,1,{},gin),EWn.i=0,gX(qZn,"ComponentsToCGraphTransformer",1651),lAn(1652,1,{},yt),EWn.ef=function(n,t){return i.Math.min(null!=n.a?Hy(n.a):n.c.i,null!=t.a?Hy(t.a):t.c.i)},EWn.ff=function(n,t){return i.Math.min(null!=n.a?Hy(n.a):n.c.i,null!=t.a?Hy(t.a):t.c.i)},gX(qZn,"ComponentsToCGraphTransformer/1",1652),lAn(81,1,{81:1}),EWn.i=0,EWn.k=!0,EWn.o=DQn;var zat,Uat,Xat,Wat=gX(GZn,"CNode",81);lAn(460,81,{460:1,81:1},$N,Tgn),EWn.Ib=function(){return""},gX(qZn,"ComponentsToCGraphTransformer/CRectNode",460),lAn(1623,1,{},kt),gX(qZn,"OneDimensionalComponentsCompaction",1623),lAn(1624,1,{},jt),EWn.Kb=function(n){return LZ(_B(n,46))},EWn.Fb=function(n){return this===n},gX(qZn,"OneDimensionalComponentsCompaction/lambda$0$Type",1624),lAn(1625,1,{},Et),EWn.Kb=function(n){return kwn(_B(n,46))},EWn.Fb=function(n){return this===n},gX(qZn,"OneDimensionalComponentsCompaction/lambda$1$Type",1625),lAn(1654,1,{},_X),gX(GZn,"CGraph",1654),lAn(189,1,{189:1},Mgn),EWn.b=0,EWn.c=0,EWn.e=0,EWn.g=!0,EWn.i=DQn,gX(GZn,"CGroup",189),lAn(1653,1,{},Pt),EWn.ef=function(n,t){return i.Math.max(null!=n.a?Hy(n.a):n.c.i,null!=t.a?Hy(t.a):t.c.i)},EWn.ff=function(n,t){return i.Math.max(null!=n.a?Hy(n.a):n.c.i,null!=t.a?Hy(t.a):t.c.i)},gX(GZn,IJn,1653),lAn(1655,1,{},uOn),EWn.d=!1;var Vat=gX(GZn,LJn,1655);lAn(1656,1,{},It),EWn.Kb=function(n){return mM(),oN(),0!=_B(_B(n,46).a,81).d.e},EWn.Fb=function(n){return this===n},gX(GZn,NJn,1656),lAn(823,1,{},Tq),EWn.a=!1,EWn.b=!1,EWn.c=!1,EWn.d=!1,gX(GZn,xJn,823),lAn(1825,1,{},NG),gX(zZn,DJn,1825);var Qat=fq(UZn,MJn);lAn(1826,1,{369:1},hJ),EWn.Ke=function(n){Hxn(this,_B(n,466))},gX(zZn,RJn,1826),lAn(1827,1,EJn,Ct),EWn.ue=function(n,t){return aQ(_B(n,81),_B(t,81))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(zZn,KJn,1827),lAn(466,1,{466:1},sP),EWn.a=!1,gX(zZn,_Jn,466),lAn(1828,1,EJn,Ot),EWn.ue=function(n,t){return Ykn(_B(n,466),_B(t,466))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(zZn,FJn,1828),lAn(140,1,{140:1},bP,pH),EWn.Fb=function(n){var t;return null!=n&&tut==Zon(n)&&(t=_B(n,140),iV(this.c,t.c)&&iV(this.d,t.d))},EWn.Hb=function(){return shn(Mun(Hk(Cnt,1),FWn,1,5,[this.c,this.d]))},EWn.Ib=function(){return"("+this.c+KWn+this.d+(this.a?"cx":"")+this.b+")"},EWn.a=!0,EWn.c=0,EWn.d=0;var Jat,Yat,Zat,nut,tut=gX(UZn,"Point",140);lAn(405,22,{3:1,35:1,22:1,405:1},WS);var eut,iut,rut,cut,aut,uut,out,sut,hut,fut,lut,but=_en(UZn,"Point/Quadrant",405,Gnt,Z2,T_);lAn(1642,1,{},Xv),EWn.b=null,EWn.c=null,EWn.d=null,EWn.e=null,EWn.f=null,gX(UZn,"RectilinearConvexHull",1642),lAn(574,1,{369:1},jpn),EWn.Ke=function(n){R9(this,_B(n,140))},EWn.b=0,gX(UZn,"RectilinearConvexHull/MaximalElementsEventHandler",574),lAn(1644,1,EJn,Mt),EWn.ue=function(n,t){return NV(ED(n),ED(t))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/MaximalElementsEventHandler/lambda$0$Type",1644),lAn(1643,1,{369:1},stn),EWn.Ke=function(n){MNn(this,_B(n,140))},EWn.a=0,EWn.b=null,EWn.c=null,EWn.d=null,EWn.e=null,gX(UZn,"RectilinearConvexHull/RectangleEventHandler",1643),lAn(1645,1,EJn,St),EWn.ue=function(n,t){return c0(_B(n,140),_B(t,140))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/lambda$0$Type",1645),lAn(1646,1,EJn,Tt),EWn.ue=function(n,t){return a0(_B(n,140),_B(t,140))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/lambda$1$Type",1646),lAn(1647,1,EJn,At),EWn.ue=function(n,t){return o0(_B(n,140),_B(t,140))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/lambda$2$Type",1647),lAn(1648,1,EJn,$t),EWn.ue=function(n,t){return u0(_B(n,140),_B(t,140))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/lambda$3$Type",1648),lAn(1649,1,EJn,Lt),EWn.ue=function(n,t){return yMn(_B(n,140),_B(t,140))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(UZn,"RectilinearConvexHull/lambda$4$Type",1649),lAn(1650,1,{},IZ),gX(UZn,"Scanline",1650),lAn(2005,1,{}),gX(XZn,"AbstractGraphPlacer",2005),lAn(325,1,{325:1},zx),EWn.mf=function(n){return!!this.nf(n)&&(QCn(this.b,_B(pMn(n,(oWn(),zft)),21),n),!0)},EWn.nf=function(n){var t,e,i;for(t=_B(pMn(n,(oWn(),zft)),21),i=_B(o6(sut,t),21).Kc();i.Ob();)if(e=_B(i.Pb(),21),!_B(o6(this.b,e),15).dc())return!1;return!0},gX(XZn,"ComponentGroup",325),lAn(765,2005,{},Wv),EWn.of=function(n){var t;for(t=new Ub(this.a);t.ab&&(k=0,j+=l+c,l=0),JRn(u,k+(g=u.c).a,j+g.b),mO(g),e=i.Math.max(e,k+v.a),l=i.Math.max(l,v.b),k+=v.a+c;if(t.f.a=e,t.f.b=j+l,By(jD(pMn(a,Edt)))){for(DXn(r=new Nt,n,c),f=n.Kc();f.Ob();)GR(mO(_B(f.Pb(),37).c),r.e);GR(mO(t.f),r.a)}b9(t,n)}else(m=_B(n.Xb(0),37))!=t&&(t.a.c=L8(Cnt,FWn,1,0,5,1),OKn(t,m,0,0),Ban(t,m),mQ(t.d,m.d),t.f.a=m.f.a,t.f.b=m.f.b)},gX(XZn,"SimpleRowGraphPlacer",1291),lAn(1292,1,EJn,Rt),EWn.ue=function(n,t){return qan(_B(n,37),_B(t,37))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(XZn,"SimpleRowGraphPlacer/1",1292),lAn(1262,1,BJn,Kt),EWn.Lb=function(n){var t;return!!(t=_B(pMn(_B(n,243).b,(FXn(),ggt)),74))&&0!=t.b},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){var t;return!!(t=_B(pMn(_B(n,243).b,(FXn(),ggt)),74))&&0!=t.b},gX(JZn,"CompoundGraphPostprocessor/1",1262),lAn(1261,1,YZn,nm),EWn.pf=function(n,t){pvn(this,_B(n,37),t)},gX(JZn,"CompoundGraphPreprocessor",1261),lAn(441,1,{441:1},qfn),EWn.c=!1,gX(JZn,"CompoundGraphPreprocessor/ExternalPort",441),lAn(243,1,{243:1},A_),EWn.Ib=function(){return bx(this.c)+":"+ICn(this.b)},gX(JZn,"CrossHierarchyEdge",243),lAn(763,1,EJn,Rw),EWn.ue=function(n,t){return Xyn(this,_B(n,243),_B(t,243))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(JZn,"CrossHierarchyEdgeComparator",763),lAn(299,134,{3:1,299:1,94:1,134:1}),EWn.p=0,gX(ZZn,"LGraphElement",299),lAn(17,299,{3:1,17:1,299:1,94:1,134:1},lJ),EWn.Ib=function(){return ICn(this)};var vut=gX(ZZn,"LEdge",17);lAn(37,299,{3:1,20:1,37:1,299:1,94:1,134:1},pin),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new Ub(this.b)},EWn.Ib=function(){return 0==this.b.c.length?"G-unlayered"+AMn(this.a):0==this.a.c.length?"G-layered"+AMn(this.b):"G[layerless"+AMn(this.a)+", layers"+AMn(this.b)+"]"};var mut,yut=gX(ZZn,"LGraph",37);lAn(657,1,{}),EWn.qf=function(){return this.e.n},EWn.We=function(n){return pMn(this.e,n)},EWn.rf=function(){return this.e.o},EWn.sf=function(){return this.e.p},EWn.Xe=function(n){return Ax(this.e,n)},EWn.tf=function(n){this.e.n.a=n.a,this.e.n.b=n.b},EWn.uf=function(n){this.e.o.a=n.a,this.e.o.b=n.b},EWn.vf=function(n){this.e.p=n},gX(ZZn,"LGraphAdapters/AbstractLShapeAdapter",657),lAn(577,1,{839:1},Kw),EWn.wf=function(){var n,t;if(!this.b)for(this.b=ux(this.a.b.c.length),t=new Ub(this.a.b);t.a0&&Nhn((f1(t-1,n.length),n.charCodeAt(t-1)),u1n);)--t;if(r> ",n),dyn(e)),aO(cO((n.a+="[",n),e.i),"]")),n.a},EWn.c=!0,EWn.d=!1;var Kut,_ut,Fut,But,Hut=gX(ZZn,"LPort",11);lAn(397,1,dVn,Fw),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new Bw(new Ub(this.a.e))},gX(ZZn,"LPort/1",397),lAn(1290,1,WWn,Bw),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return _B(Y1(this.a),17).c},EWn.Ob=function(){return v$(this.a)},EWn.Qb=function(){CU(this.a)},gX(ZZn,"LPort/1/1",1290),lAn(359,1,dVn,Hw),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new qw(new Ub(this.a.g))},gX(ZZn,"LPort/2",359),lAn(762,1,WWn,qw),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return _B(Y1(this.a),17).d},EWn.Ob=function(){return v$(this.a)},EWn.Qb=function(){CU(this.a)},gX(ZZn,"LPort/2/1",762),lAn(1283,1,dVn,oP),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new p6(this)},gX(ZZn,"LPort/CombineIter",1283),lAn(201,1,WWn,p6),EWn.Nb=function(n){sU(this,n)},EWn.Qb=function(){cE()},EWn.Ob=function(){return qN(this)},EWn.Pb=function(){return v$(this.a)?Y1(this.a):Y1(this.b)},gX(ZZn,"LPort/CombineIter/1",201),lAn(1285,1,BJn,Bt),EWn.Lb=function(n){return Cz(n)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),0!=_B(n,11).e.c.length},gX(ZZn,"LPort/lambda$0$Type",1285),lAn(1284,1,BJn,Ht),EWn.Lb=function(n){return Oz(n)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),0!=_B(n,11).g.c.length},gX(ZZn,"LPort/lambda$1$Type",1284),lAn(1286,1,BJn,qt),EWn.Lb=function(n){return wcn(),_B(n,11).j==(mUn(),uCt)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),_B(n,11).j==(mUn(),uCt)},gX(ZZn,"LPort/lambda$2$Type",1286),lAn(1287,1,BJn,Gt),EWn.Lb=function(n){return wcn(),_B(n,11).j==(mUn(),aCt)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),_B(n,11).j==(mUn(),aCt)},gX(ZZn,"LPort/lambda$3$Type",1287),lAn(1288,1,BJn,zt),EWn.Lb=function(n){return wcn(),_B(n,11).j==(mUn(),TCt)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),_B(n,11).j==(mUn(),TCt)},gX(ZZn,"LPort/lambda$4$Type",1288),lAn(1289,1,BJn,Ut),EWn.Lb=function(n){return wcn(),_B(n,11).j==(mUn(),SCt)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return wcn(),_B(n,11).j==(mUn(),SCt)},gX(ZZn,"LPort/lambda$5$Type",1289),lAn(29,299,{3:1,20:1,299:1,29:1,94:1,134:1},FX),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new Ub(this.a)},EWn.Ib=function(){return"L_"+k7(this.b.b,this,0)+AMn(this.a)},gX(ZZn,"Layer",29),lAn(1342,1,{},Zv),gX(b1n,w1n,1342),lAn(1346,1,{},Xt),EWn.Kb=function(n){return MTn(_B(n,82))},gX(b1n,"ElkGraphImporter/0methodref$connectableShapeToNode$Type",1346),lAn(1349,1,{},Wt),EWn.Kb=function(n){return MTn(_B(n,82))},gX(b1n,"ElkGraphImporter/1methodref$connectableShapeToNode$Type",1349),lAn(1343,1,hVn,Gw),EWn.td=function(n){MOn(this.a,_B(n,118))},gX(b1n,d1n,1343),lAn(1344,1,hVn,zw),EWn.td=function(n){MOn(this.a,_B(n,118))},gX(b1n,g1n,1344),lAn(1345,1,{},Vt),EWn.Kb=function(n){return new xq(null,new l1(dV(_B(n,79)),16))},gX(b1n,p1n,1345),lAn(1347,1,NVn,Uw),EWn.Mb=function(n){return RA(this.a,_B(n,33))},gX(b1n,v1n,1347),lAn(1348,1,{},Qt),EWn.Kb=function(n){return new xq(null,new l1(gV(_B(n,79)),16))},gX(b1n,"ElkGraphImporter/lambda$5$Type",1348),lAn(1350,1,NVn,Xw),EWn.Mb=function(n){return KA(this.a,_B(n,33))},gX(b1n,"ElkGraphImporter/lambda$7$Type",1350),lAn(1351,1,NVn,Jt),EWn.Mb=function(n){return CQ(_B(n,79))},gX(b1n,"ElkGraphImporter/lambda$8$Type",1351),lAn(1278,1,{},Wh),gX(b1n,"ElkGraphLayoutTransferrer",1278),lAn(1279,1,NVn,Ww),EWn.Mb=function(n){return QR(this.a,_B(n,17))},gX(b1n,"ElkGraphLayoutTransferrer/lambda$0$Type",1279),lAn(1280,1,hVn,Vw),EWn.td=function(n){pM(),UB(this.a,_B(n,17))},gX(b1n,"ElkGraphLayoutTransferrer/lambda$1$Type",1280),lAn(1281,1,NVn,Qw),EWn.Mb=function(n){return GD(this.a,_B(n,17))},gX(b1n,"ElkGraphLayoutTransferrer/lambda$2$Type",1281),lAn(1282,1,hVn,Jw),EWn.td=function(n){pM(),UB(this.a,_B(n,17))},gX(b1n,"ElkGraphLayoutTransferrer/lambda$3$Type",1282),lAn(1485,1,YZn,Yt),EWn.pf=function(n,t){Xrn(_B(n,37),t)},gX(y1n,"CommentNodeMarginCalculator",1485),lAn(1486,1,{},Zt),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"CommentNodeMarginCalculator/lambda$0$Type",1486),lAn(1487,1,hVn,ne),EWn.td=function(n){ZBn(_B(n,10))},gX(y1n,"CommentNodeMarginCalculator/lambda$1$Type",1487),lAn(1488,1,YZn,te),EWn.pf=function(n,t){rDn(_B(n,37),t)},gX(y1n,"CommentPostprocessor",1488),lAn(1489,1,YZn,ee),EWn.pf=function(n,t){cUn(_B(n,37),t)},gX(y1n,"CommentPreprocessor",1489),lAn(1490,1,YZn,ie),EWn.pf=function(n,t){yLn(_B(n,37),t)},gX(y1n,"ConstraintsPostprocessor",1490),lAn(1491,1,YZn,re),EWn.pf=function(n,t){ian(_B(n,37),t)},gX(y1n,"EdgeAndLayerConstraintEdgeReverser",1491),lAn(1492,1,YZn,ce),EWn.pf=function(n,t){Hwn(_B(n,37),t)},gX(y1n,"EndLabelPostprocessor",1492),lAn(1493,1,{},ae),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"EndLabelPostprocessor/lambda$0$Type",1493),lAn(1494,1,NVn,ue),EWn.Mb=function(n){return EJ(_B(n,10))},gX(y1n,"EndLabelPostprocessor/lambda$1$Type",1494),lAn(1495,1,hVn,oe),EWn.td=function(n){njn(_B(n,10))},gX(y1n,"EndLabelPostprocessor/lambda$2$Type",1495),lAn(1496,1,YZn,se),EWn.pf=function(n,t){JPn(_B(n,37),t)},gX(y1n,"EndLabelPreprocessor",1496),lAn(1497,1,{},he),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"EndLabelPreprocessor/lambda$0$Type",1497),lAn(1498,1,hVn,N_),EWn.td=function(n){DM(this.a,this.b,this.c,_B(n,10))},EWn.a=0,EWn.b=0,EWn.c=!1,gX(y1n,"EndLabelPreprocessor/lambda$1$Type",1498),lAn(1499,1,NVn,fe),EWn.Mb=function(n){return HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),zPt))},gX(y1n,"EndLabelPreprocessor/lambda$2$Type",1499),lAn(1500,1,hVn,Yw),EWn.td=function(n){NH(this.a,_B(n,70))},gX(y1n,"EndLabelPreprocessor/lambda$3$Type",1500),lAn(1501,1,NVn,le),EWn.Mb=function(n){return HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),GPt))},gX(y1n,"EndLabelPreprocessor/lambda$4$Type",1501),lAn(1502,1,hVn,Zw),EWn.td=function(n){NH(this.a,_B(n,70))},gX(y1n,"EndLabelPreprocessor/lambda$5$Type",1502),lAn(1551,1,YZn,Xh),EWn.pf=function(n,t){Sln(_B(n,37),t)},gX(y1n,"EndLabelSorter",1551),lAn(1552,1,EJn,be),EWn.ue=function(n,t){return Fgn(_B(n,456),_B(t,456))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"EndLabelSorter/1",1552),lAn(456,1,{456:1},jQ),gX(y1n,"EndLabelSorter/LabelGroup",456),lAn(1553,1,{},we),EWn.Kb=function(n){return kM(),new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"EndLabelSorter/lambda$0$Type",1553),lAn(1554,1,NVn,de),EWn.Mb=function(n){return kM(),_B(n,10).k==(cSn(),Sut)},gX(y1n,"EndLabelSorter/lambda$1$Type",1554),lAn(1555,1,hVn,ge),EWn.td=function(n){aSn(_B(n,10))},gX(y1n,"EndLabelSorter/lambda$2$Type",1555),lAn(1556,1,NVn,pe),EWn.Mb=function(n){return kM(),HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),GPt))},gX(y1n,"EndLabelSorter/lambda$3$Type",1556),lAn(1557,1,NVn,ve),EWn.Mb=function(n){return kM(),HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),zPt))},gX(y1n,"EndLabelSorter/lambda$4$Type",1557),lAn(1503,1,YZn,me),EWn.pf=function(n,t){PHn(this,_B(n,37))},EWn.b=0,EWn.c=0,gX(y1n,"FinalSplineBendpointsCalculator",1503),lAn(1504,1,{},ye),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"FinalSplineBendpointsCalculator/lambda$0$Type",1504),lAn(1505,1,{},ke),EWn.Kb=function(n){return new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(y1n,"FinalSplineBendpointsCalculator/lambda$1$Type",1505),lAn(1506,1,NVn,je),EWn.Mb=function(n){return!f5(_B(n,17))},gX(y1n,"FinalSplineBendpointsCalculator/lambda$2$Type",1506),lAn(1507,1,NVn,Ee),EWn.Mb=function(n){return Ax(_B(n,17),(oWn(),$lt))},gX(y1n,"FinalSplineBendpointsCalculator/lambda$3$Type",1507),lAn(1508,1,hVn,nd),EWn.td=function(n){qKn(this.a,_B(n,128))},gX(y1n,"FinalSplineBendpointsCalculator/lambda$4$Type",1508),lAn(1509,1,hVn,Te),EWn.td=function(n){QPn(_B(n,17).a)},gX(y1n,"FinalSplineBendpointsCalculator/lambda$5$Type",1509),lAn(792,1,YZn,td),EWn.pf=function(n,t){Xqn(this,_B(n,37),t)},gX(y1n,"GraphTransformer",792),lAn(511,22,{3:1,35:1,22:1,511:1},JS);var qut,Gut,zut,Uut=_en(y1n,"GraphTransformer/Mode",511,Gnt,cY,ZF);lAn(1510,1,YZn,Me),EWn.pf=function(n,t){nxn(_B(n,37),t)},gX(y1n,"HierarchicalNodeResizingProcessor",1510),lAn(1511,1,YZn,Se),EWn.pf=function(n,t){hrn(_B(n,37),t)},gX(y1n,"HierarchicalPortConstraintProcessor",1511),lAn(1512,1,EJn,Pe),EWn.ue=function(n,t){return Ppn(_B(n,10),_B(t,10))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"HierarchicalPortConstraintProcessor/NodeComparator",1512),lAn(1513,1,YZn,Ie),EWn.pf=function(n,t){yBn(_B(n,37),t)},gX(y1n,"HierarchicalPortDummySizeProcessor",1513),lAn(1514,1,YZn,Ce),EWn.pf=function(n,t){QDn(this,_B(n,37),t)},EWn.a=0,gX(y1n,"HierarchicalPortOrthogonalEdgeRouter",1514),lAn(1515,1,EJn,Oe),EWn.ue=function(n,t){return RN(_B(n,10),_B(t,10))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"HierarchicalPortOrthogonalEdgeRouter/1",1515),lAn(1516,1,EJn,Ae),EWn.ue=function(n,t){return M9(_B(n,10),_B(t,10))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"HierarchicalPortOrthogonalEdgeRouter/2",1516),lAn(1517,1,YZn,$e),EWn.pf=function(n,t){kMn(_B(n,37),t)},gX(y1n,"HierarchicalPortPositionProcessor",1517),lAn(1518,1,YZn,Vh),EWn.pf=function(n,t){eXn(this,_B(n,37))},EWn.a=0,EWn.c=0,gX(y1n,"HighDegreeNodeLayeringProcessor",1518),lAn(571,1,{571:1},Le),EWn.b=-1,EWn.d=-1,gX(y1n,"HighDegreeNodeLayeringProcessor/HighDegreeNodeInformation",571),lAn(1519,1,{},Ne),EWn.Kb=function(n){return B_(),sbn(_B(n,10))},EWn.Fb=function(n){return this===n},gX(y1n,"HighDegreeNodeLayeringProcessor/lambda$0$Type",1519),lAn(1520,1,{},xe),EWn.Kb=function(n){return B_(),hbn(_B(n,10))},EWn.Fb=function(n){return this===n},gX(y1n,"HighDegreeNodeLayeringProcessor/lambda$1$Type",1520),lAn(1526,1,YZn,De),EWn.pf=function(n,t){bFn(this,_B(n,37),t)},gX(y1n,"HyperedgeDummyMerger",1526),lAn(793,1,{},x_),EWn.a=!1,EWn.b=!1,EWn.c=!1,gX(y1n,"HyperedgeDummyMerger/MergeState",793),lAn(1527,1,{},Re),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"HyperedgeDummyMerger/lambda$0$Type",1527),lAn(1528,1,{},Ke),EWn.Kb=function(n){return new xq(null,new l1(_B(n,10).j,16))},gX(y1n,"HyperedgeDummyMerger/lambda$1$Type",1528),lAn(1529,1,hVn,_e),EWn.td=function(n){_B(n,11).p=-1},gX(y1n,"HyperedgeDummyMerger/lambda$2$Type",1529),lAn(1530,1,YZn,Fe),EWn.pf=function(n,t){fFn(_B(n,37),t)},gX(y1n,"HypernodesProcessor",1530),lAn(1531,1,YZn,Be),EWn.pf=function(n,t){lFn(_B(n,37),t)},gX(y1n,"InLayerConstraintProcessor",1531),lAn(1532,1,YZn,He),EWn.pf=function(n,t){Acn(_B(n,37),t)},gX(y1n,"InnermostNodeMarginCalculator",1532),lAn(1533,1,YZn,qe),EWn.pf=function(n,t){Xzn(this,_B(n,37))},EWn.a=DQn,EWn.b=DQn,EWn.c=xQn,EWn.d=xQn;var Xut,Wut,Vut,Qut,Jut,Yut,Zut,not,tot,eot,iot,rot,cot,aot,uot,oot,sot,hot,fot,lot,bot,wot,dot,got,pot,vot,mot,yot,kot,jot,Eot,Tot,Mot,Sot,Pot,Iot,Cot,Oot,Aot,$ot,Lot,Not,xot,Dot,Rot,Kot,_ot,Fot,Bot,Hot,qot,Got,zot,Uot,Xot,Wot,Vot,Qot=gX(y1n,"InteractiveExternalPortPositioner",1533);lAn(1534,1,{},Ge),EWn.Kb=function(n){return _B(n,17).d.i},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$0$Type",1534),lAn(1535,1,{},ed),EWn.Kb=function(n){return BN(this.a,ED(n))},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$1$Type",1535),lAn(1536,1,{},ze),EWn.Kb=function(n){return _B(n,17).c.i},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$2$Type",1536),lAn(1537,1,{},id),EWn.Kb=function(n){return HN(this.a,ED(n))},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$3$Type",1537),lAn(1538,1,{},rd),EWn.Kb=function(n){return UR(this.a,ED(n))},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$4$Type",1538),lAn(1539,1,{},cd),EWn.Kb=function(n){return XR(this.a,ED(n))},EWn.Fb=function(n){return this===n},gX(y1n,"InteractiveExternalPortPositioner/lambda$5$Type",1539),lAn(77,22,{3:1,35:1,22:1,77:1,234:1},YS),EWn.Kf=function(){switch(this.g){case 15:return new dc;case 22:return new gc;case 47:return new mc;case 28:case 35:return new ei;case 32:return new Yt;case 42:return new te;case 1:return new ee;case 41:return new ie;case 56:return new td((Trn(),But));case 0:return new td((Trn(),Fut));case 2:return new re;case 54:return new ce;case 33:return new se;case 51:return new me;case 55:return new Me;case 13:return new Se;case 38:return new Ie;case 44:return new Ce;case 40:return new $e;case 9:return new Vh;case 49:return new ax;case 37:return new De;case 43:return new Fe;case 27:return new Be;case 30:return new He;case 3:return new qe;case 18:return new Xe;case 29:return new We;case 5:return new Qh;case 50:return new Ue;case 34:return new Jh;case 36:return new ii;case 52:return new Xh;case 11:return new ci;case 7:return new Zh;case 39:return new ai;case 45:return new ui;case 16:return new oi;case 10:return new si;case 48:return new fi;case 21:return new li;case 23:return new $y((ain(),Cmt));case 8:return new wi;case 12:return new gi;case 4:return new pi;case 19:return new rf;case 17:return new Pi;case 53:return new Ii;case 6:return new Bi;case 25:return new rm;case 46:return new Ni;case 31:return new LR;case 14:return new Vi;case 26:return new Sc;case 20:return new nr;case 24:return new $y((ain(),Omt));default:throw Fp(new Ry(E1n+(null!=this.f?this.f:""+this.g)))}};var Jot,Yot,Zot,nst,tst,est,ist,rst,cst=_en(y1n,T1n,77,Gnt,kNn,YF);lAn(1540,1,YZn,Xe),EWn.pf=function(n,t){Qzn(_B(n,37),t)},gX(y1n,"InvertedPortProcessor",1540),lAn(1541,1,YZn,We),EWn.pf=function(n,t){AKn(_B(n,37),t)},gX(y1n,"LabelAndNodeSizeProcessor",1541),lAn(1542,1,NVn,Ve),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Sut)},gX(y1n,"LabelAndNodeSizeProcessor/lambda$0$Type",1542),lAn(1543,1,NVn,Qe),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Eut)},gX(y1n,"LabelAndNodeSizeProcessor/lambda$1$Type",1543),lAn(1544,1,hVn,D_),EWn.td=function(n){RM(this.b,this.a,this.c,_B(n,10))},EWn.a=!1,EWn.c=!1,gX(y1n,"LabelAndNodeSizeProcessor/lambda$2$Type",1544),lAn(1545,1,YZn,Qh),EWn.pf=function(n,t){szn(_B(n,37),t)},gX(y1n,"LabelDummyInserter",1545),lAn(1546,1,BJn,Je),EWn.Lb=function(n){return HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),qPt))},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return HC(pMn(_B(n,70),(FXn(),Vdt)))===HC((xtn(),qPt))},gX(y1n,"LabelDummyInserter/1",1546),lAn(1547,1,YZn,Ue),EWn.pf=function(n,t){Mqn(_B(n,37),t)},gX(y1n,"LabelDummyRemover",1547),lAn(1548,1,NVn,Ye),EWn.Mb=function(n){return By(jD(pMn(_B(n,70),(FXn(),Wdt))))},gX(y1n,"LabelDummyRemover/lambda$0$Type",1548),lAn(1359,1,YZn,Jh),EWn.pf=function(n,t){jGn(this,_B(n,37),t)},EWn.a=null,gX(y1n,"LabelDummySwitcher",1359),lAn(286,1,{286:1},iKn),EWn.c=0,EWn.d=null,EWn.f=0,gX(y1n,"LabelDummySwitcher/LabelDummyInfo",286),lAn(1360,1,{},Ze),EWn.Kb=function(n){return Prn(),new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"LabelDummySwitcher/lambda$0$Type",1360),lAn(1361,1,NVn,ni),EWn.Mb=function(n){return Prn(),_B(n,10).k==(cSn(),Tut)},gX(y1n,"LabelDummySwitcher/lambda$1$Type",1361),lAn(1362,1,{},od),EWn.Kb=function(n){return zD(this.a,_B(n,10))},gX(y1n,"LabelDummySwitcher/lambda$2$Type",1362),lAn(1363,1,hVn,sd),EWn.td=function(n){VX(this.a,_B(n,286))},gX(y1n,"LabelDummySwitcher/lambda$3$Type",1363),lAn(1364,1,EJn,ti),EWn.ue=function(n,t){return Az(_B(n,286),_B(t,286))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"LabelDummySwitcher/lambda$4$Type",1364),lAn(791,1,YZn,ei),EWn.pf=function(n,t){V6(_B(n,37),t)},gX(y1n,"LabelManagementProcessor",791),lAn(1549,1,YZn,ii),EWn.pf=function(n,t){$xn(_B(n,37),t)},gX(y1n,"LabelSideSelector",1549),lAn(1550,1,NVn,ri),EWn.Mb=function(n){return By(jD(pMn(_B(n,70),(FXn(),Wdt))))},gX(y1n,"LabelSideSelector/lambda$0$Type",1550),lAn(1558,1,YZn,ci),EWn.pf=function(n,t){kBn(_B(n,37),t)},gX(y1n,"LayerConstraintPostprocessor",1558),lAn(1559,1,YZn,Zh),EWn.pf=function(n,t){e$n(_B(n,37),t)},gX(y1n,"LayerConstraintPreprocessor",1559),lAn(360,22,{3:1,35:1,22:1,360:1},ZS);var ast,ust,ost,sst,hst,fst,lst,bst,wst,dst=_en(y1n,"LayerConstraintPreprocessor/HiddenNodeConnections",360,Gnt,n3,q_);lAn(1560,1,YZn,ai),EWn.pf=function(n,t){kqn(_B(n,37),t)},gX(y1n,"LayerSizeAndGraphHeightCalculator",1560),lAn(1561,1,YZn,ui),EWn.pf=function(n,t){CLn(_B(n,37),t)},gX(y1n,"LongEdgeJoiner",1561),lAn(1562,1,YZn,oi),EWn.pf=function(n,t){UHn(_B(n,37),t)},gX(y1n,"LongEdgeSplitter",1562),lAn(1563,1,YZn,si),EWn.pf=function(n,t){MGn(this,_B(n,37),t)},EWn.d=0,EWn.e=0,EWn.i=0,EWn.j=0,EWn.k=0,EWn.n=0,gX(y1n,"NodePromotion",1563),lAn(1564,1,{},hi),EWn.Kb=function(n){return _B(n,46),oN(),!0},EWn.Fb=function(n){return this===n},gX(y1n,"NodePromotion/lambda$0$Type",1564),lAn(1565,1,{},ad),EWn.Kb=function(n){return rV(this.a,_B(n,46))},EWn.Fb=function(n){return this===n},EWn.a=0,gX(y1n,"NodePromotion/lambda$1$Type",1565),lAn(1566,1,{},ud),EWn.Kb=function(n){return cV(this.a,_B(n,46))},EWn.Fb=function(n){return this===n},EWn.a=0,gX(y1n,"NodePromotion/lambda$2$Type",1566),lAn(1567,1,YZn,fi),EWn.pf=function(n,t){zUn(_B(n,37),t)},gX(y1n,"NorthSouthPortPostprocessor",1567),lAn(1568,1,YZn,li),EWn.pf=function(n,t){EUn(_B(n,37),t)},gX(y1n,"NorthSouthPortPreprocessor",1568),lAn(1569,1,EJn,bi),EWn.ue=function(n,t){return Jan(_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"NorthSouthPortPreprocessor/lambda$0$Type",1569),lAn(1570,1,YZn,wi),EWn.pf=function(n,t){O_n(_B(n,37),t)},gX(y1n,"PartitionMidprocessor",1570),lAn(1571,1,NVn,di),EWn.Mb=function(n){return Ax(_B(n,10),(FXn(),Ugt))},gX(y1n,"PartitionMidprocessor/lambda$0$Type",1571),lAn(1572,1,hVn,hd),EWn.td=function(n){OQ(this.a,_B(n,10))},gX(y1n,"PartitionMidprocessor/lambda$1$Type",1572),lAn(1573,1,YZn,gi),EWn.pf=function(n,t){lNn(_B(n,37),t)},gX(y1n,"PartitionPostprocessor",1573),lAn(1574,1,YZn,pi),EWn.pf=function(n,t){$On(_B(n,37),t)},gX(y1n,"PartitionPreprocessor",1574),lAn(1575,1,NVn,vi),EWn.Mb=function(n){return Ax(_B(n,10),(FXn(),Ugt))},gX(y1n,"PartitionPreprocessor/lambda$0$Type",1575),lAn(1576,1,{},mi),EWn.Kb=function(n){return new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(y1n,"PartitionPreprocessor/lambda$1$Type",1576),lAn(1577,1,NVn,yi),EWn.Mb=function(n){return Agn(_B(n,17))},gX(y1n,"PartitionPreprocessor/lambda$2$Type",1577),lAn(1578,1,hVn,ki),EWn.td=function(n){xun(_B(n,17))},gX(y1n,"PartitionPreprocessor/lambda$3$Type",1578),lAn(1579,1,YZn,rf),EWn.pf=function(n,t){c_n(_B(n,37),t)},gX(y1n,"PortListSorter",1579),lAn(1580,1,{},ji),EWn.Kb=function(n){return qsn(),_B(n,11).e},gX(y1n,"PortListSorter/lambda$0$Type",1580),lAn(1581,1,{},Ei),EWn.Kb=function(n){return qsn(),_B(n,11).g},gX(y1n,"PortListSorter/lambda$1$Type",1581),lAn(1582,1,EJn,Ti),EWn.ue=function(n,t){return j4(_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"PortListSorter/lambda$2$Type",1582),lAn(1583,1,EJn,Mi),EWn.ue=function(n,t){return Iyn(_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"PortListSorter/lambda$3$Type",1583),lAn(1584,1,EJn,Si),EWn.ue=function(n,t){return Y_n(_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"PortListSorter/lambda$4$Type",1584),lAn(1585,1,YZn,Pi),EWn.pf=function(n,t){UAn(_B(n,37),t)},gX(y1n,"PortSideProcessor",1585),lAn(1586,1,YZn,Ii),EWn.pf=function(n,t){PRn(_B(n,37),t)},gX(y1n,"ReversedEdgeRestorer",1586),lAn(1591,1,YZn,rm),EWn.pf=function(n,t){Vmn(this,_B(n,37),t)},gX(y1n,"SelfLoopPortRestorer",1591),lAn(1592,1,{},Ci),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"SelfLoopPortRestorer/lambda$0$Type",1592),lAn(1593,1,NVn,Oi),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Sut)},gX(y1n,"SelfLoopPortRestorer/lambda$1$Type",1593),lAn(1594,1,NVn,Ai),EWn.Mb=function(n){return Ax(_B(n,10),(oWn(),Ilt))},gX(y1n,"SelfLoopPortRestorer/lambda$2$Type",1594),lAn(1595,1,{},$i),EWn.Kb=function(n){return _B(pMn(_B(n,10),(oWn(),Ilt)),403)},gX(y1n,"SelfLoopPortRestorer/lambda$3$Type",1595),lAn(1596,1,hVn,fd),EWn.td=function(n){TSn(this.a,_B(n,403))},gX(y1n,"SelfLoopPortRestorer/lambda$4$Type",1596),lAn(794,1,hVn,Li),EWn.td=function(n){YSn(_B(n,101))},gX(y1n,"SelfLoopPortRestorer/lambda$5$Type",794),lAn(1597,1,YZn,Ni),EWn.pf=function(n,t){Apn(_B(n,37),t)},gX(y1n,"SelfLoopPostProcessor",1597),lAn(1598,1,{},xi),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"SelfLoopPostProcessor/lambda$0$Type",1598),lAn(1599,1,NVn,Di),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Sut)},gX(y1n,"SelfLoopPostProcessor/lambda$1$Type",1599),lAn(1600,1,NVn,Ri),EWn.Mb=function(n){return Ax(_B(n,10),(oWn(),Ilt))},gX(y1n,"SelfLoopPostProcessor/lambda$2$Type",1600),lAn(1601,1,hVn,Ki),EWn.td=function(n){Ajn(_B(n,10))},gX(y1n,"SelfLoopPostProcessor/lambda$3$Type",1601),lAn(1602,1,{},_i),EWn.Kb=function(n){return new xq(null,new l1(_B(n,101).f,1))},gX(y1n,"SelfLoopPostProcessor/lambda$4$Type",1602),lAn(1603,1,hVn,ld),EWn.td=function(n){r3(this.a,_B(n,409))},gX(y1n,"SelfLoopPostProcessor/lambda$5$Type",1603),lAn(1604,1,NVn,Fi),EWn.Mb=function(n){return!!_B(n,101).i},gX(y1n,"SelfLoopPostProcessor/lambda$6$Type",1604),lAn(1605,1,hVn,bd),EWn.td=function(n){jy(this.a,_B(n,101))},gX(y1n,"SelfLoopPostProcessor/lambda$7$Type",1605),lAn(1587,1,YZn,Bi),EWn.pf=function(n,t){J$n(_B(n,37),t)},gX(y1n,"SelfLoopPreProcessor",1587),lAn(1588,1,{},Hi),EWn.Kb=function(n){return new xq(null,new l1(_B(n,101).f,1))},gX(y1n,"SelfLoopPreProcessor/lambda$0$Type",1588),lAn(1589,1,{},qi),EWn.Kb=function(n){return _B(n,409).a},gX(y1n,"SelfLoopPreProcessor/lambda$1$Type",1589),lAn(1590,1,hVn,Gi),EWn.td=function(n){B$(_B(n,17))},gX(y1n,"SelfLoopPreProcessor/lambda$2$Type",1590),lAn(1606,1,YZn,LR),EWn.pf=function(n,t){uSn(this,_B(n,37),t)},gX(y1n,"SelfLoopRouter",1606),lAn(1607,1,{},zi),EWn.Kb=function(n){return new xq(null,new l1(_B(n,29).a,16))},gX(y1n,"SelfLoopRouter/lambda$0$Type",1607),lAn(1608,1,NVn,Ui),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Sut)},gX(y1n,"SelfLoopRouter/lambda$1$Type",1608),lAn(1609,1,NVn,Xi),EWn.Mb=function(n){return Ax(_B(n,10),(oWn(),Ilt))},gX(y1n,"SelfLoopRouter/lambda$2$Type",1609),lAn(1610,1,{},Wi),EWn.Kb=function(n){return _B(pMn(_B(n,10),(oWn(),Ilt)),403)},gX(y1n,"SelfLoopRouter/lambda$3$Type",1610),lAn(1611,1,hVn,nP),EWn.td=function(n){WV(this.a,this.b,_B(n,403))},gX(y1n,"SelfLoopRouter/lambda$4$Type",1611),lAn(1612,1,YZn,Vi),EWn.pf=function(n,t){sxn(_B(n,37),t)},gX(y1n,"SemiInteractiveCrossMinProcessor",1612),lAn(1613,1,NVn,Qi),EWn.Mb=function(n){return _B(n,10).k==(cSn(),Sut)},gX(y1n,"SemiInteractiveCrossMinProcessor/lambda$0$Type",1613),lAn(1614,1,NVn,Ji),EWn.Mb=function(n){return Hq(_B(n,10))._b((FXn(),upt))},gX(y1n,"SemiInteractiveCrossMinProcessor/lambda$1$Type",1614),lAn(1615,1,EJn,Yi),EWn.ue=function(n,t){return brn(_B(n,10),_B(t,10))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(y1n,"SemiInteractiveCrossMinProcessor/lambda$2$Type",1615),lAn(1616,1,{},Zi),EWn.Ce=function(n,t){return zQ(_B(n,10),_B(t,10))},gX(y1n,"SemiInteractiveCrossMinProcessor/lambda$3$Type",1616),lAn(1618,1,YZn,nr),EWn.pf=function(n,t){EBn(_B(n,37),t)},gX(y1n,"SortByInputModelProcessor",1618),lAn(1619,1,NVn,tr),EWn.Mb=function(n){return 0!=_B(n,11).g.c.length},gX(y1n,"SortByInputModelProcessor/lambda$0$Type",1619),lAn(1620,1,hVn,wd),EWn.td=function(n){sPn(this.a,_B(n,11))},gX(y1n,"SortByInputModelProcessor/lambda$1$Type",1620),lAn(1693,803,{},wrn),EWn.Me=function(n){var t,e,i,r;switch(this.c=n,this.a.g){case 2:t=new $p,QT(CV(new xq(null,new l1(this.c.a.b,16)),new dr),new cP(this,t)),dIn(this,new rr),Itn(t,new cr),t.c=L8(Cnt,FWn,1,0,5,1),QT(CV(new xq(null,new l1(this.c.a.b,16)),new ar),new gd(t)),dIn(this,new ur),Itn(t,new or),t.c=L8(Cnt,FWn,1,0,5,1),e=y$(tcn(AV(new xq(null,new l1(this.c.a.b,16)),new pd(this))),new sr),QT(new xq(null,new l1(this.c.a.a,16)),new eP(e,t)),dIn(this,new fr),Itn(t,new er),t.c=L8(Cnt,FWn,1,0,5,1);break;case 3:i=new $p,dIn(this,new ir),r=y$(tcn(AV(new xq(null,new l1(this.c.a.b,16)),new dd(this))),new hr),QT(CV(new xq(null,new l1(this.c.a.b,16)),new lr),new rP(r,i)),dIn(this,new br),Itn(i,new wr),i.c=L8(Cnt,FWn,1,0,5,1);break;default:throw Fp(new mv)}},EWn.b=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation",1693),lAn(1694,1,BJn,ir),EWn.Lb=function(n){return iL(_B(n,57).g,145)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return iL(_B(n,57).g,145)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$0$Type",1694),lAn(1695,1,{},dd),EWn.Fe=function(n){return HIn(this.a,_B(n,57))},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$1$Type",1695),lAn(1703,1,xVn,tP),EWn.Vd=function(){Kkn(this.a,this.b,-1)},EWn.b=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$10$Type",1703),lAn(1705,1,BJn,rr),EWn.Lb=function(n){return iL(_B(n,57).g,145)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return iL(_B(n,57).g,145)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$11$Type",1705),lAn(1706,1,hVn,cr),EWn.td=function(n){_B(n,365).Vd()},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$12$Type",1706),lAn(1707,1,NVn,ar),EWn.Mb=function(n){return iL(_B(n,57).g,10)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$13$Type",1707),lAn(1709,1,hVn,gd),EWn.td=function(n){kbn(this.a,_B(n,57))},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$14$Type",1709),lAn(1708,1,xVn,hP),EWn.Vd=function(){Kkn(this.b,this.a,-1)},EWn.a=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$15$Type",1708),lAn(1710,1,BJn,ur),EWn.Lb=function(n){return iL(_B(n,57).g,10)},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return iL(_B(n,57).g,10)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$16$Type",1710),lAn(1711,1,hVn,or),EWn.td=function(n){_B(n,365).Vd()},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$17$Type",1711),lAn(1712,1,{},pd),EWn.Fe=function(n){return qIn(this.a,_B(n,57))},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$18$Type",1712),lAn(1713,1,{},sr),EWn.De=function(){return 0},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$19$Type",1713),lAn(1696,1,{},hr),EWn.De=function(){return 0},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$2$Type",1696),lAn(1715,1,hVn,eP),EWn.td=function(n){FG(this.a,this.b,_B(n,307))},EWn.a=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$20$Type",1715),lAn(1714,1,xVn,iP),EWn.Vd=function(){XAn(this.a,this.b,-1)},EWn.b=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$21$Type",1714),lAn(1716,1,BJn,fr),EWn.Lb=function(n){return _B(n,57),!0},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return _B(n,57),!0},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$22$Type",1716),lAn(1717,1,hVn,er),EWn.td=function(n){_B(n,365).Vd()},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$23$Type",1717),lAn(1697,1,NVn,lr),EWn.Mb=function(n){return iL(_B(n,57).g,10)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$3$Type",1697),lAn(1699,1,hVn,rP),EWn.td=function(n){BG(this.a,this.b,_B(n,57))},EWn.a=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$4$Type",1699),lAn(1698,1,xVn,fP),EWn.Vd=function(){Kkn(this.b,this.a,-1)},EWn.a=0,gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$5$Type",1698),lAn(1700,1,BJn,br),EWn.Lb=function(n){return _B(n,57),!0},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return _B(n,57),!0},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$6$Type",1700),lAn(1701,1,hVn,wr),EWn.td=function(n){_B(n,365).Vd()},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$7$Type",1701),lAn(1702,1,NVn,dr),EWn.Mb=function(n){return iL(_B(n,57).g,145)},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$8$Type",1702),lAn(1704,1,hVn,cP),EWn.td=function(n){jtn(this.a,this.b,_B(n,57))},gX(C1n,"EdgeAwareScanlineConstraintCalculation/lambda$9$Type",1704),lAn(1521,1,YZn,ax),EWn.pf=function(n,t){iqn(this,_B(n,37),t)},gX(C1n,"HorizontalGraphCompactor",1521),lAn(1522,1,{},vd),EWn.Oe=function(n,t){var e,i;return J7(n,t)?0:(e=s2(n),i=s2(t),e&&e.k==(cSn(),Eut)||i&&i.k==(cSn(),Eut)?0:GN(_B(pMn(this.a.a,(oWn(),Clt)),304),e?e.k:(cSn(),Mut),i?i.k:(cSn(),Mut)))},EWn.Pe=function(n,t){var e,i;return J7(n,t)?1:(e=s2(n),i=s2(t),zN(_B(pMn(this.a.a,(oWn(),Clt)),304),e?e.k:(cSn(),Mut),i?i.k:(cSn(),Mut)))},gX(C1n,"HorizontalGraphCompactor/1",1522),lAn(1523,1,{},gr),EWn.Ne=function(n,t){return EM(),0==n.a.i},gX(C1n,"HorizontalGraphCompactor/lambda$0$Type",1523),lAn(1524,1,{},md),EWn.Ne=function(n,t){return RQ(this.a,n,t)},gX(C1n,"HorizontalGraphCompactor/lambda$1$Type",1524),lAn(1664,1,{},P7),gX(C1n,"LGraphToCGraphTransformer",1664),lAn(1672,1,NVn,pr),EWn.Mb=function(n){return null!=n},gX(C1n,"LGraphToCGraphTransformer/0methodref$nonNull$Type",1672),lAn(1665,1,{},vr),EWn.Kb=function(n){return H_(),_bn(pMn(_B(_B(n,57).g,10),(oWn(),blt)))},gX(C1n,"LGraphToCGraphTransformer/lambda$0$Type",1665),lAn(1666,1,{},mr),EWn.Kb=function(n){return H_(),pfn(_B(_B(n,57).g,145))},gX(C1n,"LGraphToCGraphTransformer/lambda$1$Type",1666),lAn(1675,1,NVn,yr),EWn.Mb=function(n){return H_(),iL(_B(n,57).g,10)},gX(C1n,"LGraphToCGraphTransformer/lambda$10$Type",1675),lAn(1676,1,hVn,kr),EWn.td=function(n){DQ(_B(n,57))},gX(C1n,"LGraphToCGraphTransformer/lambda$11$Type",1676),lAn(1677,1,NVn,jr),EWn.Mb=function(n){return H_(),iL(_B(n,57).g,145)},gX(C1n,"LGraphToCGraphTransformer/lambda$12$Type",1677),lAn(1681,1,hVn,Er),EWn.td=function(n){gfn(_B(n,57))},gX(C1n,"LGraphToCGraphTransformer/lambda$13$Type",1681),lAn(1678,1,hVn,yd),EWn.td=function(n){cA(this.a,_B(n,8))},EWn.a=0,gX(C1n,"LGraphToCGraphTransformer/lambda$14$Type",1678),lAn(1679,1,hVn,kd),EWn.td=function(n){uA(this.a,_B(n,110))},EWn.a=0,gX(C1n,"LGraphToCGraphTransformer/lambda$15$Type",1679),lAn(1680,1,hVn,jd),EWn.td=function(n){aA(this.a,_B(n,8))},EWn.a=0,gX(C1n,"LGraphToCGraphTransformer/lambda$16$Type",1680),lAn(1682,1,{},Tr),EWn.Kb=function(n){return H_(),new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(C1n,"LGraphToCGraphTransformer/lambda$17$Type",1682),lAn(1683,1,NVn,Mr),EWn.Mb=function(n){return H_(),f5(_B(n,17))},gX(C1n,"LGraphToCGraphTransformer/lambda$18$Type",1683),lAn(1684,1,hVn,Ed),EWn.td=function(n){Tnn(this.a,_B(n,17))},gX(C1n,"LGraphToCGraphTransformer/lambda$19$Type",1684),lAn(1668,1,hVn,Td),EWn.td=function(n){h0(this.a,_B(n,145))},gX(C1n,"LGraphToCGraphTransformer/lambda$2$Type",1668),lAn(1685,1,{},Sr),EWn.Kb=function(n){return H_(),new xq(null,new l1(_B(n,29).a,16))},gX(C1n,"LGraphToCGraphTransformer/lambda$20$Type",1685),lAn(1686,1,{},Pr),EWn.Kb=function(n){return H_(),new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(C1n,"LGraphToCGraphTransformer/lambda$21$Type",1686),lAn(1687,1,{},Ir),EWn.Kb=function(n){return H_(),_B(pMn(_B(n,17),(oWn(),$lt)),15)},gX(C1n,"LGraphToCGraphTransformer/lambda$22$Type",1687),lAn(1688,1,NVn,Cr),EWn.Mb=function(n){return ZN(_B(n,15))},gX(C1n,"LGraphToCGraphTransformer/lambda$23$Type",1688),lAn(1689,1,hVn,Md),EWn.td=function(n){MIn(this.a,_B(n,15))},gX(C1n,"LGraphToCGraphTransformer/lambda$24$Type",1689),lAn(1667,1,hVn,aP),EWn.td=function(n){F3(this.a,this.b,_B(n,145))},gX(C1n,"LGraphToCGraphTransformer/lambda$3$Type",1667),lAn(1669,1,{},Or),EWn.Kb=function(n){return H_(),new xq(null,new l1(_B(n,29).a,16))},gX(C1n,"LGraphToCGraphTransformer/lambda$4$Type",1669),lAn(1670,1,{},Ar),EWn.Kb=function(n){return H_(),new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(C1n,"LGraphToCGraphTransformer/lambda$5$Type",1670),lAn(1671,1,{},$r),EWn.Kb=function(n){return H_(),_B(pMn(_B(n,17),(oWn(),$lt)),15)},gX(C1n,"LGraphToCGraphTransformer/lambda$6$Type",1671),lAn(1673,1,hVn,Sd),EWn.td=function(n){DCn(this.a,_B(n,15))},gX(C1n,"LGraphToCGraphTransformer/lambda$8$Type",1673),lAn(1674,1,hVn,uP),EWn.td=function(n){L$(this.a,this.b,_B(n,145))},gX(C1n,"LGraphToCGraphTransformer/lambda$9$Type",1674),lAn(1663,1,{},Lr),EWn.Le=function(n){var t,e,i,r,c;for(this.a=n,this.d=new Kv,this.c=L8(Bit,FWn,121,this.a.a.a.c.length,0,1),this.b=0,e=new Ub(this.a.a.a);e.a=g&&(UB(a,tln(f)),m=i.Math.max(m,y[f-1]-l),o+=d,p+=y[f-1]-p,l=y[f-1],d=s[f]),d=i.Math.max(d,s[f]),++f;o+=d}(w=i.Math.min(1/m,1/t.b/o))>r&&(r=w,e=a)}return e},EWn.Wf=function(){return!1},gX(R1n,"MSDCutIndexHeuristic",802),lAn(1617,1,YZn,Sc),EWn.pf=function(n,t){fBn(_B(n,37),t)},gX(R1n,"SingleEdgeGraphWrapper",1617),lAn(227,22,{3:1,35:1,22:1,227:1},yP);var eht,iht,rht,cht=_en(K1n,"CenterEdgeLabelPlacementStrategy",227,Gnt,J8,U_);lAn(422,22,{3:1,35:1,22:1,422:1},kP);var aht,uht,oht,sht,hht=_en(K1n,"ConstraintCalculationStrategy",422,Gnt,HJ,X_);lAn(314,22,{3:1,35:1,22:1,314:1,246:1,234:1},jP),EWn.Kf=function(){return uCn(this)},EWn.Xf=function(){return uCn(this)};var fht,lht,bht,wht,dht=_en(K1n,"CrossingMinimizationStrategy",314,Gnt,j1,W_);lAn(337,22,{3:1,35:1,22:1,337:1},EP);var ght,pht,vht,mht,yht,kht,jht=_en(K1n,"CuttingStrategy",337,Gnt,E1,J_);lAn(335,22,{3:1,35:1,22:1,335:1,246:1,234:1},TP),EWn.Kf=function(){return xAn(this)},EWn.Xf=function(){return xAn(this)};var Eht,Tht,Mht,Sht=_en(K1n,"CycleBreakingStrategy",335,Gnt,A5,Y_);lAn(419,22,{3:1,35:1,22:1,419:1},MP);var Pht,Iht,Cht,Oht,Aht=_en(K1n,"DirectionCongruency",419,Gnt,BJ,Z_);lAn(450,22,{3:1,35:1,22:1,450:1},SP);var $ht,Lht,Nht,xht,Dht,Rht,Kht,_ht=_en(K1n,"EdgeConstraint",450,Gnt,T1,nF);lAn(276,22,{3:1,35:1,22:1,276:1},PP);var Fht,Bht,Hht,qht=_en(K1n,"EdgeLabelSideSelection",276,Gnt,t9,tF);lAn(479,22,{3:1,35:1,22:1,479:1},IP);var Ght,zht,Uht,Xht,Wht,Vht,Qht,Jht=_en(K1n,"EdgeStraighteningStrategy",479,Gnt,FJ,eF);lAn(274,22,{3:1,35:1,22:1,274:1},CP);var Yht,Zht,nft,tft,eft,ift,rft,cft=_en(K1n,"FixedAlignment",274,Gnt,Z8,iF);lAn(275,22,{3:1,35:1,22:1,275:1},OP);var aft,uft,oft,sft,hft,fft,lft,bft,wft,dft,gft,pft=_en(K1n,"GraphCompactionStrategy",275,Gnt,Y8,rF);lAn(256,22,{3:1,35:1,22:1,256:1},AP);var vft,mft,yft,kft,jft=_en(K1n,"GraphProperties",256,Gnt,fcn,cF);lAn(292,22,{3:1,35:1,22:1,292:1},$P);var Eft,Tft,Mft,Sft,Pft=_en(K1n,"GreedySwitchType",292,Gnt,P1,aF);lAn(303,22,{3:1,35:1,22:1,303:1},LP);var Ift,Cft,Oft,Aft=_en(K1n,"InLayerConstraint",303,Gnt,S1,uF);lAn(420,22,{3:1,35:1,22:1,420:1},NP);var $ft,Lft,Nft,xft,Dft,Rft,Kft,_ft,Fft,Bft,Hft,qft,Gft,zft,Uft,Xft,Wft,Vft,Qft,Jft,Yft,Zft,nlt,tlt,elt,ilt,rlt,clt,alt,ult,olt,slt,hlt,flt,llt,blt,wlt,dlt,glt,plt,vlt,mlt,ylt,klt,jlt,Elt,Tlt,Mlt,Slt,Plt,Ilt,Clt,Olt,Alt,$lt,Llt,Nlt,xlt,Dlt,Rlt,Klt,_lt,Flt,Blt,Hlt=_en(K1n,"InteractiveReferencePoint",420,Gnt,qJ,oF);lAn(163,22,{3:1,35:1,22:1,163:1},_P);var qlt,Glt,zlt,Ult,Xlt,Wlt,Vlt,Qlt,Jlt,Ylt,Zlt,nbt,tbt,ebt,ibt,rbt,cbt,abt,ubt,obt,sbt,hbt,fbt,lbt,bbt,wbt,dbt,gbt,pbt,vbt,mbt,ybt,kbt,jbt,Ebt,Tbt,Mbt,Sbt,Pbt,Ibt,Cbt,Obt,Abt,$bt,Lbt,Nbt,xbt,Dbt,Rbt,Kbt,_bt,Fbt,Bbt,Hbt,qbt,Gbt,zbt,Ubt,Xbt,Wbt,Vbt,Qbt,Jbt,Ybt,Zbt,nwt,twt,ewt,iwt,rwt,cwt,awt,uwt,owt,swt,hwt,fwt,lwt,bwt,wwt,dwt,gwt,pwt,vwt,mwt,ywt,kwt,jwt,Ewt,Twt,Mwt,Swt,Pwt,Iwt,Cwt,Owt,Awt,$wt,Lwt,Nwt,xwt,Dwt,Rwt,Kwt,_wt,Fwt,Bwt,Hwt,qwt,Gwt,zwt,Uwt,Xwt,Wwt,Vwt,Qwt,Jwt,Ywt,Zwt,ndt,tdt,edt,idt,rdt,cdt,adt,udt,odt,sdt,hdt,fdt,ldt,bdt,wdt,ddt,gdt,pdt,vdt,mdt,ydt,kdt,jdt,Edt,Tdt,Mdt,Sdt,Pdt,Idt,Cdt,Odt,Adt,$dt,Ldt,Ndt,xdt,Ddt,Rdt,Kdt,_dt,Fdt,Bdt,Hdt,qdt,Gdt,zdt,Udt,Xdt,Wdt,Vdt,Qdt,Jdt,Ydt,Zdt,ngt,tgt,egt,igt,rgt,cgt,agt,ugt,ogt,sgt,hgt,fgt,lgt,bgt,wgt,dgt,ggt,pgt,vgt,mgt,ygt,kgt,jgt,Egt,Tgt,Mgt,Sgt,Pgt,Igt,Cgt,Ogt,Agt,$gt,Lgt,Ngt,xgt,Dgt,Rgt,Kgt,_gt,Fgt,Bgt,Hgt,qgt,Ggt,zgt,Ugt,Xgt,Wgt,Vgt,Qgt,Jgt,Ygt,Zgt,npt,tpt,ept,ipt,rpt,cpt,apt,upt,opt,spt,hpt,fpt,lpt,bpt,wpt,dpt,gpt,ppt,vpt,mpt,ypt,kpt,jpt,Ept,Tpt,Mpt,Spt,Ppt,Ipt,Cpt,Opt,Apt,$pt,Lpt,Npt,xpt,Dpt,Rpt,Kpt,_pt,Fpt,Bpt,Hpt,qpt,Gpt,zpt,Upt,Xpt,Wpt,Vpt,Qpt,Jpt,Ypt,Zpt,nvt,tvt=_en(K1n,"LayerConstraint",163,Gnt,N5,sF);lAn(848,1,WJn,of),EWn.Qe=function(n){Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,G1n),""),"Direction Congruency"),"Specifies how drawings of the same graph with different layout directions compare to each other: either a natural reading direction is preserved or the drawings are rotated versions of each other."),Mbt),(MPn(),wMt)),Aht),Yln((epn(),oMt))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,z1n),""),"Feedback Edges"),"Whether feedback edges should be highlighted by routing around the nodes."),(oN(),!1)),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,U1n),""),"Interactive Reference Point"),"Determines which point of a node is considered by interactive layout phases."),Wbt),wMt),Hlt),Yln(oMt)))),r2(n,U1n,n0n,Qbt),r2(n,U1n,h0n,Vbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,X1n),""),"Merge Edges"),"Edges that have no ports are merged so they touch the connected nodes at the same points. When this option is disabled, one port is created for each edge directly connected to a node. When it is enabled, all such incoming edges share an input port, and all outgoing edges share an output port."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,W1n),""),"Merge Hierarchy-Crossing Edges"),"If hierarchical layout is active, hierarchy-crossing edges use as few hierarchical ports as possible. They are broken by the algorithm, with hierarchical ports inserted as required. Usually, one such port is created for each edge at each hierarchy crossing point. With this option set to true, we try to create as few hierarchical ports as possible in the process. In particular, all edges that form a hyperedge can share a port."),!0),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Mj(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,V1n),""),"Allow Non-Flow Ports To Switch Sides"),"Specifies whether non-flow ports may switch sides if their node's port constraints are either FIXED_SIDE or FIXED_ORDER. A non-flow port is a port on a side that is not part of the currently configured layout flow. For instance, given a left-to-right layout direction, north and south ports would be considered non-flow ports. Further note that the underlying criterium whether to switch sides or not solely relies on the minimization of edge crossings. Hence, edge length and other aesthetics criteria are not addressed."),!1),lMt),mtt),Yln(sMt)),Mun(Hk(Wtt,1),uVn,2,6,["org.eclipse.elk.layered.northOrSouthPort"])))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Q1n),""),"Port Sorting Strategy"),"Only relevant for nodes with FIXED_SIDE port constraints. Determines the way a node's ports are distributed on the sides of a node if their order is not prescribed. The option is set on parent nodes."),Lwt),wMt),qvt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,J1n),""),"Thoroughness"),"How much effort should be spent to produce a nice layout."),tln(7)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Y1n),""),"Add Unnecessary Bendpoints"),"Adds bend points even if an edge does not change direction. If true, each long edge dummy will contribute a bend point to its edges and hierarchy-crossing edges will always get a bend point where they cross hierarchy boundaries. By default, bend points are only added where an edge changes direction."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Z1n),""),"Generate Position and Layer IDs"),"If enabled position id and layer id are generated, which are usually only used internally when setting the interactiveLayout option. This option should be specified on the root node."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,n0n),"cycleBreaking"),"Cycle Breaking Strategy"),"Strategy for cycle breaking. Cycle breaking looks for cycles in the graph and determines which edges to reverse to break the cycles. Reversed edges will end up pointing to the opposite direction of regular edges (that is, reversed edges will point left if edges usually point right)."),Ebt),wMt),Sht),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,t0n),s2n),"Node Layering Strategy"),"Strategy for node layering."),fwt),wMt),avt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,e0n),s2n),"Layer Constraint"),"Determines a constraint on the placement of the node regarding the layering."),twt),wMt),tvt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,i0n),s2n),"Layer Choice Constraint"),"Allows to set a constraint regarding the layer placement of a node. Let i be the value of teh constraint. Assumed the drawing has n layers and i < n. If set to i, it expresses that the node should be placed in i-th layer. Should i>=n be true then the node is placed in the last layer of the drawing. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),tln(-1)),gMt),Ctt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,r0n),s2n),"Layer ID"),"Layer identifier that was calculated by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),tln(-1)),gMt),Ctt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,c0n),h2n),"Upper Bound On Width [MinWidth Layerer]"),"Defines a loose upper bound on the width of the MinWidth layerer. If set to '-1' multiple values are tested and the best result is selected."),tln(4)),gMt),Ctt),Yln(oMt)))),r2(n,c0n,t0n,rwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,a0n),h2n),"Upper Layer Estimation Scaling Factor [MinWidth Layerer]"),"Multiplied with Upper Bound On Width for defining an upper bound on the width of layers which haven't been determined yet, but whose maximum width had been (roughly) estimated by the MinWidth algorithm. Compensates for too high estimations. If set to '-1' multiple values are tested and the best result is selected."),tln(2)),gMt),Ctt),Yln(oMt)))),r2(n,a0n,t0n,awt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,u0n),f2n),"Node Promotion Strategy"),"Reduces number of dummy nodes after layering phase (if possible)."),swt),wMt),Nvt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,o0n),f2n),"Max Node Promotion Iterations"),"Limits the number of iterations for node promotion."),tln(0)),gMt),Ctt),Yln(oMt)))),r2(n,o0n,u0n,null),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,s0n),"layering.coffmanGraham"),"Layer Bound"),"The maximum number of nodes allowed per layer."),tln(NWn)),gMt),Ctt),Yln(oMt)))),r2(n,s0n,t0n,Ybt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,h0n),l2n),"Crossing Minimization Strategy"),"Strategy for crossing minimization."),kbt),wMt),dht),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,f0n),l2n),"Force Node Model Order"),"The node order given by the model does not change to produce a better layout. E.g. if node A is before node B in the model this is not changed during crossing minimization. This assumes that the node model order is already respected before crossing minimization. This can be achieved by setting considerModelOrder.strategy to NODES_AND_EDGES."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,l0n),l2n),"Hierarchical Sweepiness"),"How likely it is to use cross-hierarchy (1) vs bottom-up (-1)."),.1),bMt),Mtt),Yln(oMt)))),r2(n,l0n,b2n,dbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,b0n),l2n),"Semi-Interactive Crossing Minimization"),"Preserves the order of nodes within a layer but still minimizes crossings between edges connecting long edge dummies. Derives the desired order from positions specified by the 'org.eclipse.elk.position' layout option. Requires a crossing minimization strategy that is able to process 'in-layer' constraints."),!1),lMt),mtt),Yln(oMt)))),r2(n,b0n,h0n,mbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,w0n),l2n),"Position Choice Constraint"),"Allows to set a constraint regarding the position placement of a node in a layer. Assumed the layer in which the node placed includes n other nodes and i < n. If set to i, it expresses that the node should be placed at the i-th position. Should i>=n be true then the node is placed at the last position in the layer. Note that this option is not part of any of ELK Layered's default configurations but is only evaluated as part of the `InteractiveLayeredGraphVisitor`, which must be applied manually or used via the `DiagramLayoutEngine."),tln(-1)),gMt),Ctt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,d0n),l2n),"Position ID"),"Position within a layer that was determined by ELK Layered for a node. This is only generated if interactiveLayot or generatePositionAndLayerIds is set."),tln(-1)),gMt),Ctt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,g0n),w2n),"Greedy Switch Activation Threshold"),"By default it is decided automatically if the greedy switch is activated or not. The decision is based on whether the size of the input graph (without dummy nodes) is smaller than the value of this option. A '0' enforces the activation."),tln(40)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,p0n),w2n),"Greedy Switch Crossing Minimization"),"Greedy Switch strategy for crossing minimization. The greedy switch heuristic is executed after the regular crossing minimization as a post-processor. Note that if 'hierarchyHandling' is set to 'INCLUDE_CHILDREN', the 'greedySwitchHierarchical.type' option must be used."),lbt),wMt),Pft),Yln(oMt)))),r2(n,p0n,h0n,bbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,v0n),"crossingMinimization.greedySwitchHierarchical"),"Greedy Switch Crossing Minimization (hierarchical)"),"Activates the greedy switch heuristic in case hierarchical layout is used. The differences to the non-hierarchical case (see 'greedySwitch.type') are: 1) greedy switch is inactive by default, 3) only the option value set on the node at which hierarchical layout starts is relevant, and 2) if it's activated by the user, it properly addresses hierarchy-crossing edges."),obt),wMt),Pft),Yln(oMt)))),r2(n,v0n,h0n,sbt),r2(n,v0n,b2n,hbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,m0n),d2n),"Node Placement Strategy"),"Strategy for node placement."),Awt),wMt),Cvt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,y0n),d2n),"Favor Straight Edges Over Balancing"),"Favor straight edges over a balanced node placement. The default behavior is determined automatically based on the used 'edgeRouting'. For an orthogonal style it is set to true, for all other styles to false."),lMt),mtt),Yln(oMt)))),r2(n,y0n,m0n,kwt),r2(n,y0n,m0n,jwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,k0n),g2n),"BK Edge Straightening"),"Specifies whether the Brandes Koepf node placer tries to increase the number of straight edges at the expense of diagram size. There is a subtle difference to the 'favorStraightEdges' option, which decides whether a balanced placement of the nodes is desired, or not. In bk terms this means combining the four alignments into a single balanced one, or not. This option on the other hand tries to straighten additional edges during the creation of each of the four alignments."),dwt),wMt),Jht),Yln(oMt)))),r2(n,k0n,m0n,gwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,j0n),g2n),"BK Fixed Alignment"),"Tells the BK node placer to use a certain alignment (out of its four) instead of the one producing the smallest height, or the combination of all four."),vwt),wMt),cft),Yln(oMt)))),r2(n,j0n,m0n,mwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,E0n),"nodePlacement.linearSegments"),"Linear Segments Deflection Dampening"),"Dampens the movement of nodes to keep the diagram from getting too large."),.3),bMt),Mtt),Yln(oMt)))),r2(n,E0n,m0n,Twt),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,T0n),"nodePlacement.networkSimplex"),"Node Flexibility"),"Aims at shorter and straighter edges. Two configurations are possible: (a) allow ports to move freely on the side they are assigned to (the order is always defined beforehand), (b) additionally allow to enlarge a node wherever it helps. If this option is not configured for a node, the 'nodeFlexibility.default' value is used, which is specified for the node's parent."),wMt),mvt),Yln(uMt)))),r2(n,T0n,m0n,Cwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,M0n),"nodePlacement.networkSimplex.nodeFlexibility"),"Node Flexibility Default"),"Default value of the 'nodeFlexibility' option for the children of a hierarchical node."),Pwt),wMt),mvt),Yln(oMt)))),r2(n,M0n,m0n,Iwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,S0n),p2n),"Self-Loop Distribution"),"Alter the distribution of the loops around the node. It only takes effect for PortConstraints.FREE."),Lbt),wMt),Yvt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,P0n),p2n),"Self-Loop Ordering"),"Alter the ordering of the loops they can either be stacked or sequenced. It only takes effect for PortConstraints.FREE."),xbt),wMt),imt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,I0n),"edgeRouting.splines"),"Spline Routing Mode"),"Specifies the way control points are assembled for each individual edge. CONSERVATIVE ensures that edges are properly routed around the nodes but feels rather orthogonal at times. SLOPPY uses fewer control points to obtain curvier edge routes but may result in edges overlapping nodes."),Rbt),wMt),omt),Yln(oMt)))),r2(n,I0n,v2n,Kbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,C0n),"edgeRouting.splines.sloppy"),"Sloppy Spline Layer Spacing Factor"),"Spacing factor for routing area between layers when using sloppy spline routing."),.2),bMt),Mtt),Yln(oMt)))),r2(n,C0n,v2n,Fbt),r2(n,C0n,I0n,Bbt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,O0n),"edgeRouting.polyline"),"Sloped Edge Zone Width"),"Width of the strip to the left and to the right of each layer where the polyline edge router is allowed to refrain from ensuring that edges are routed horizontally. This prevents awkward bend points for nodes that extent almost to the edge of their layer."),2),bMt),Mtt),Yln(oMt)))),r2(n,O0n,v2n,Abt),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,A0n),m2n),"Spacing Base Value"),"An optional base value for all other layout options of the 'spacing' group. It can be used to conveniently alter the overall 'spaciousness' of the drawing. Whenever an explicit value is set for the other layout options, this base value will have no effect. The base value is not inherited, i.e. it must be set for each hierarchical node."),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,$0n),m2n),"Edge Node Between Layers Spacing"),"The spacing to be preserved between nodes and edges that are routed next to the node's layer. For the spacing between nodes and edges that cross the node's layer 'spacing.edgeNode' is used."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,L0n),m2n),"Edge Edge Between Layer Spacing"),"Spacing to be preserved between pairs of edges that are routed between the same pair of layers. Note that 'spacing.edgeEdge' is used for the spacing between pairs of edges crossing the same layer."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,N0n),m2n),"Node Node Between Layers Spacing"),"The spacing to be preserved between any pair of nodes of two adjacent layers. Note that 'spacing.nodeNode' is used for the spacing between nodes within the layer itself."),20),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,x0n),y2n),"Direction Priority"),"Defines how important it is to have a certain edge point into the direction of the overall layout. This option is evaluated during the cycle breaking phase."),tln(0)),gMt),Ctt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,D0n),y2n),"Shortness Priority"),"Defines how important it is to keep an edge as short as possible. This option is evaluated during the layering phase."),tln(0)),gMt),Ctt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,R0n),y2n),"Straightness Priority"),"Defines how important it is to keep an edge straight, i.e. aligned with one of the two axes. This option is evaluated during node placement."),tln(0)),gMt),Ctt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,K0n),k2n),NYn),"Tries to further compact components (disconnected sub-graphs)."),!1),lMt),mtt),Yln(oMt)))),r2(n,K0n,mZn,!0),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,_0n),j2n),"Post Compaction Strategy"),E2n),Vlt),wMt),pft),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,F0n),j2n),"Post Compaction Constraint Calculation"),E2n),Xlt),wMt),hht),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,B0n),T2n),"High Degree Node Treatment"),"Makes room around high degree nodes to place leafs and trees."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,H0n),T2n),"High Degree Node Threshold"),"Whether a node is considered to have a high degree."),tln(16)),gMt),Ctt),Yln(oMt)))),r2(n,H0n,B0n,!0),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,q0n),T2n),"High Degree Node Maximum Tree Height"),"Maximum height of a subtree connected to a high degree node to be moved to separate layers."),tln(5)),gMt),Ctt),Yln(oMt)))),r2(n,q0n,B0n,!0),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,G0n),M2n),"Graph Wrapping Strategy"),"For certain graphs and certain prescribed drawing areas it may be desirable to split the laid out graph into chunks that are placed side by side. The edges that connect different chunks are 'wrapped' around from the end of one chunk to the start of the other chunk. The points between the chunks are referred to as 'cuts'."),fdt),wMt),Tmt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,z0n),M2n),"Additional Wrapped Edges Spacing"),"To visually separate edges that are wrapped from regularly routed edges an additional spacing value can be specified in form of this layout option. The spacing is added to the regular edgeNode spacing."),10),bMt),Mtt),Yln(oMt)))),r2(n,z0n,G0n,Gwt),r2(n,z0n,G0n,zwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,U0n),M2n),"Correction Factor for Wrapping"),"At times and for certain types of graphs the executed wrapping may produce results that are consistently biased in the same fashion: either wrapping to often or to rarely. This factor can be used to correct the bias. Internally, it is simply multiplied with the 'aspect ratio' layout option."),1),bMt),Mtt),Yln(oMt)))),r2(n,U0n,G0n,Xwt),r2(n,U0n,G0n,Wwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,X0n),S2n),"Cutting Strategy"),"The strategy by which the layer indexes are determined at which the layering crumbles into chunks."),tdt),wMt),jht),Yln(oMt)))),r2(n,X0n,G0n,edt),r2(n,X0n,G0n,idt),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,W0n),S2n),"Manually Specified Cuts"),"Allows the user to specify her own cuts for a certain graph."),pMt),xnt),Yln(oMt)))),r2(n,W0n,X0n,Qwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,V0n),"wrapping.cutting.msd"),"MSD Freedom"),"The MSD cutting strategy starts with an initial guess on the number of chunks the graph should be split into. The freedom specifies how much the strategy may deviate from this guess. E.g. if an initial number of 3 is computed, a freedom of 1 allows 2, 3, and 4 cuts."),Ywt),gMt),Ctt),Yln(oMt)))),r2(n,V0n,X0n,Zwt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Q0n),P2n),"Validification Strategy"),"When wrapping graphs, one can specify indices that are not allowed as split points. The validification strategy makes sure every computed split point is allowed."),gdt),wMt),bmt),Yln(oMt)))),r2(n,Q0n,G0n,pdt),r2(n,Q0n,G0n,vdt),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,J0n),P2n),"Valid Indices for Wrapping"),null),pMt),xnt),Yln(oMt)))),r2(n,J0n,G0n,bdt),r2(n,J0n,G0n,wdt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Y0n),I2n),"Improve Cuts"),"For general graphs it is important that not too many edges wrap backwards. Thus a compromise between evenly-distributed cuts and the total number of cut edges is sought."),!0),lMt),mtt),Yln(oMt)))),r2(n,Y0n,G0n,udt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Z0n),I2n),"Distance Penalty When Improving Cuts"),null),2),bMt),Mtt),Yln(oMt)))),r2(n,Z0n,G0n,cdt),r2(n,Z0n,Y0n,!0),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,n2n),I2n),"Improve Wrapped Edges"),"The initial wrapping is performed in a very simple way. As a consequence, edges that wrap from one chunk to another may be unnecessarily long. Activating this option tries to shorten such edges."),!0),lMt),mtt),Yln(oMt)))),r2(n,n2n,G0n,sdt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,t2n),C2n),"Edge Label Side Selection"),"Method to decide on edge label sides."),Cbt),wMt),qht),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,e2n),C2n),"Edge Center Label Placement Strategy"),"Determines in which layer center labels of long edges should be placed."),Pbt),wMt),cht),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,i2n),O2n),"Consider Model Order"),"Preserves the order of nodes and edges in the model file if this does not lead to additional edge crossings. Depending on the strategy this is not always possible since the node and edge order might be conflicting."),rbt),wMt),Kvt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,r2n),O2n),"No Model Order"),"Set on a node to not set a model order for this node even though it is a real node."),!1),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,c2n),O2n),"Consider Model Order for Components"),"If set to NONE the usual ordering strategy (by cumulative node priority and size of nodes) is used. INSIDE_PORT_SIDES orders the components with external ports only inside the groups with the same port side. FORCE_MODEL_ORDER enforces the mode order on components. This option might produce bad alignments and sub optimal drawings in terms of used area since the ordering should be respected."),Jlt),wMt),put),Yln(oMt)))),r2(n,c2n,mZn,null),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,a2n),O2n),"Long Edge Ordering Strategy"),"Indicates whether long edges are sorted under, over, or equal to nodes that have no connection to a previous layer in a left-to-right or right-to-left layout. Under and over changes to right and left in a vertical layout."),tbt),wMt),lvt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,u2n),O2n),"Crossing Counter Node Order Influence"),"Indicates with what percentage (1 for 100%) violations of the node model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal node order. Defaults to no influence (0)."),0),bMt),Mtt),Yln(oMt)))),r2(n,u2n,i2n,null),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,o2n),O2n),"Crossing Counter Port Order Influence"),"Indicates with what percentage (1 for 100%) violations of the port model order are weighted against the crossings e.g. a value of 0.5 means two model order violations are as important as on edge crossing. This allows some edge crossings in favor of preserving the model order. It is advised to set this value to a very small positive value (e.g. 0.001) to have minimal crossing and a optimal port order. Defaults to no influence (0)."),0),bMt),Mtt),Yln(oMt)))),r2(n,o2n,i2n,null),gWn((new ff,n))},gX(K1n,"LayeredMetaDataProvider",848),lAn(986,1,WJn,ff),EWn.Qe=function(n){gWn(n)},gX(K1n,"LayeredOptions",986),lAn(987,1,{},Ic),EWn.$e=function(){return new Gv},EWn._e=function(n){},gX(K1n,"LayeredOptions/LayeredFactory",987),lAn(1372,1,{}),EWn.a=0,gX(v3n,"ElkSpacings/AbstractSpacingsBuilder",1372),lAn(779,1372,{},cwn),gX(K1n,"LayeredSpacings/LayeredSpacingsBuilder",779),lAn(313,22,{3:1,35:1,22:1,313:1,246:1,234:1},xP),EWn.Kf=function(){return eLn(this)},EWn.Xf=function(){return eLn(this)};var evt,ivt,rvt,cvt,avt=_en(K1n,"LayeringStrategy",313,Gnt,n9,hF);lAn(378,22,{3:1,35:1,22:1,378:1},DP);var uvt,ovt,svt,hvt,fvt,lvt=_en(K1n,"LongEdgeOrderingStrategy",378,Gnt,k1,fF);lAn(197,22,{3:1,35:1,22:1,197:1},RP);var bvt,wvt,dvt,gvt,pvt,vvt,mvt=_en(K1n,"NodeFlexibility",197,Gnt,m3,lF);lAn(315,22,{3:1,35:1,22:1,315:1,246:1,234:1},KP),EWn.Kf=function(){return NAn(this)},EWn.Xf=function(){return NAn(this)};var yvt,kvt,jvt,Evt,Tvt,Mvt,Svt,Pvt,Ivt,Cvt=_en(K1n,"NodePlacementStrategy",315,Gnt,O5,vF);lAn(260,22,{3:1,35:1,22:1,260:1},FP);var Ovt,Avt,$vt,Lvt,Nvt=_en(K1n,"NodePromotionStrategy",260,Gnt,_tn,wF);lAn(339,22,{3:1,35:1,22:1,339:1},BP);var xvt,Dvt,Rvt,Kvt=_en(K1n,"OrderingStrategy",339,Gnt,C1,dF);lAn(421,22,{3:1,35:1,22:1,421:1},HP);var _vt,Fvt,Bvt,Hvt,qvt=_en(K1n,"PortSortingStrategy",421,Gnt,GJ,gF);lAn(452,22,{3:1,35:1,22:1,452:1},qP);var Gvt,zvt,Uvt,Xvt,Wvt=_en(K1n,"PortType",452,Gnt,I1,bF);lAn(375,22,{3:1,35:1,22:1,375:1},GP);var Vvt,Qvt,Jvt,Yvt=_en(K1n,"SelfLoopDistributionStrategy",375,Gnt,O1,pF);lAn(376,22,{3:1,35:1,22:1,376:1},zP);var Zvt,nmt,tmt,emt,imt=_en(K1n,"SelfLoopOrderingStrategy",376,Gnt,_J,mF);lAn(304,1,{304:1},uGn),gX(K1n,"Spacings",304),lAn(336,22,{3:1,35:1,22:1,336:1},UP);var rmt,cmt,amt,umt,omt=_en(K1n,"SplineRoutingMode",336,Gnt,$1,yF);lAn(338,22,{3:1,35:1,22:1,338:1},XP);var smt,hmt,fmt,lmt,bmt=_en(K1n,"ValidifyStrategy",338,Gnt,L1,kF);lAn(377,22,{3:1,35:1,22:1,377:1},WP);var wmt,dmt,gmt,pmt,vmt,mmt,ymt,kmt,jmt,Emt,Tmt=_en(K1n,"WrappingStrategy",377,Gnt,A1,jF);lAn(1383,1,k3n,lf),EWn.Yf=function(n){return _B(n,37),dmt},EWn.pf=function(n,t){QHn(this,_B(n,37),t)},gX(j3n,"DepthFirstCycleBreaker",1383),lAn(782,1,k3n,DG),EWn.Yf=function(n){return _B(n,37),gmt},EWn.pf=function(n,t){GXn(this,_B(n,37),t)},EWn.Zf=function(n){return _B(Lq(n,dvn(this.d,n.c.length)),10)},gX(j3n,"GreedyCycleBreaker",782),lAn(1386,782,k3n,jC),EWn.Zf=function(n){var t,e,i,r;for(r=null,t=NWn,i=new Ub(n);i.a1&&(By(jD(pMn(gW((h1(0,n.c.length),_B(n.c[0],10))),(FXn(),Ldt))))?x$n(n,this.d,_B(this,660)):(TQ(),p$(n,this.d)),_an(this.e,n))},EWn.Sf=function(n,t,e,i){var r,c,a,u,o,s,h;for(t!=Qq(e,n.length)&&(c=n[t-(e?1:-1)],H6(this.f,c,e?(rin(),Bvt):(rin(),Fvt))),r=n[t][0],h=!i||r.k==(cSn(),Eut),s=c6(n[t]),this.ag(s,h,!1,e),a=0,o=new Ub(s);o.a"),n0?cZ(this.a,n[t-1],n[t]):!e&&t1&&(By(jD(pMn(gW((h1(0,n.c.length),_B(n.c[0],10))),(FXn(),Ldt))))?x$n(n,this.d,this):(TQ(),p$(n,this.d)),By(jD(pMn(gW((h1(0,n.c.length),_B(n.c[0],10))),Ldt)))||_an(this.e,n))},gX(S3n,"ModelOrderBarycenterHeuristic",660),lAn(1803,1,EJn,Ud),EWn.ue=function(n,t){return DSn(this.a,_B(n,10),_B(t,10))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(S3n,"ModelOrderBarycenterHeuristic/lambda$0$Type",1803),lAn(1403,1,k3n,yf),EWn.Yf=function(n){var t;return _B(n,37),bq(t=mA(Nmt),(vMn(),Rat),(hWn(),_ot)),t},EWn.pf=function(n,t){pJ((_B(n,37),t))},gX(S3n,"NoCrossingMinimizer",1403),lAn(796,402,T3n,xj),EWn.$f=function(n,t,e){var i,r,c,a,u,o,s,h,f,l,b;switch(f=this.g,e.g){case 1:for(r=0,c=0,h=new Ub(n.j);h.a1&&(r.j==(mUn(),aCt)?this.b[n]=!0:r.j==SCt&&n>0&&(this.b[n-1]=!0))},EWn.f=0,gX(A1n,"AllCrossingsCounter",1798),lAn(587,1,{},prn),EWn.b=0,EWn.d=0,gX(A1n,"BinaryIndexedTree",587),lAn(524,1,{},WK),gX(A1n,"CrossingsCounter",524),lAn(1906,1,EJn,Xd),EWn.ue=function(n,t){return zq(this.a,_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(A1n,"CrossingsCounter/lambda$0$Type",1906),lAn(1907,1,EJn,Wd),EWn.ue=function(n,t){return Uq(this.a,_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(A1n,"CrossingsCounter/lambda$1$Type",1907),lAn(1908,1,EJn,Vd),EWn.ue=function(n,t){return Xq(this.a,_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(A1n,"CrossingsCounter/lambda$2$Type",1908),lAn(1909,1,EJn,Qd),EWn.ue=function(n,t){return Wq(this.a,_B(n,11),_B(t,11))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(A1n,"CrossingsCounter/lambda$3$Type",1909),lAn(1910,1,hVn,Jd),EWn.td=function(n){d7(this.a,_B(n,11))},gX(A1n,"CrossingsCounter/lambda$4$Type",1910),lAn(1911,1,NVn,Yd),EWn.Mb=function(n){return vC(this.a,_B(n,11))},gX(A1n,"CrossingsCounter/lambda$5$Type",1911),lAn(1912,1,hVn,Zd),EWn.td=function(n){pC(this,n)},gX(A1n,"CrossingsCounter/lambda$6$Type",1912),lAn(1913,1,hVn,JP),EWn.td=function(n){var t;oH(),b3(this.b,(t=this.a,_B(n,11),t))},gX(A1n,"CrossingsCounter/lambda$7$Type",1913),lAn(826,1,BJn,xc),EWn.Lb=function(n){return oH(),Ax(_B(n,11),(oWn(),klt))},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return oH(),Ax(_B(n,11),(oWn(),klt))},gX(A1n,"CrossingsCounter/lambda$8$Type",826),lAn(1905,1,{},ng),gX(A1n,"HyperedgeCrossingsCounter",1905),lAn(467,1,{35:1,467:1},NR),EWn.wd=function(n){return ggn(this,_B(n,467))},EWn.b=0,EWn.c=0,EWn.e=0,EWn.f=0;var Kmt=gX(A1n,"HyperedgeCrossingsCounter/Hyperedge",467);lAn(362,1,{35:1,362:1},BV),EWn.wd=function(n){return h$n(this,_B(n,362))},EWn.b=0,EWn.c=0;var _mt,Fmt,Bmt=gX(A1n,"HyperedgeCrossingsCounter/HyperedgeCorner",362);lAn(523,22,{3:1,35:1,22:1,523:1},QP);var Hmt,qmt,Gmt,zmt,Umt,Xmt=_en(A1n,"HyperedgeCrossingsCounter/HyperedgeCorner/Type",523,Gnt,zJ,TF);lAn(1405,1,k3n,hf),EWn.Yf=function(n){return _B(pMn(_B(n,37),(oWn(),Jft)),21).Hc((fDn(),hft))?qmt:null},EWn.pf=function(n,t){hjn(this,_B(n,37),t)},gX(P3n,"InteractiveNodePlacer",1405),lAn(1406,1,k3n,sf),EWn.Yf=function(n){return _B(pMn(_B(n,37),(oWn(),Jft)),21).Hc((fDn(),hft))?Gmt:null},EWn.pf=function(n,t){ymn(this,_B(n,37),t)},gX(P3n,"LinearSegmentsNodePlacer",1406),lAn(257,1,{35:1,257:1},em),EWn.wd=function(n){return cj(this,_B(n,257))},EWn.Fb=function(n){var t;return!!iL(n,257)&&(t=_B(n,257),this.b==t.b)},EWn.Hb=function(){return this.b},EWn.Ib=function(){return"ls"+AMn(this.e)},EWn.a=0,EWn.b=0,EWn.c=-1,EWn.d=-1,EWn.g=0;var Wmt,Vmt=gX(P3n,"LinearSegmentsNodePlacer/LinearSegment",257);lAn(1408,1,k3n,RG),EWn.Yf=function(n){return _B(pMn(_B(n,37),(oWn(),Jft)),21).Hc((fDn(),hft))?Wmt:null},EWn.pf=function(n,t){TXn(this,_B(n,37),t)},EWn.b=0,EWn.g=0,gX(P3n,"NetworkSimplexPlacer",1408),lAn(1427,1,EJn,Dc),EWn.ue=function(n,t){return k$(_B(n,19).a,_B(t,19).a)},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(P3n,"NetworkSimplexPlacer/0methodref$compare$Type",1427),lAn(1429,1,EJn,Rc),EWn.ue=function(n,t){return k$(_B(n,19).a,_B(t,19).a)},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(P3n,"NetworkSimplexPlacer/1methodref$compare$Type",1429),lAn(649,1,{649:1},YP);var Qmt=gX(P3n,"NetworkSimplexPlacer/EdgeRep",649);lAn(401,1,{401:1},HV),EWn.b=!1;var Jmt,Ymt,Zmt,nyt=gX(P3n,"NetworkSimplexPlacer/NodeRep",401);lAn(508,12,{3:1,4:1,20:1,28:1,52:1,12:1,14:1,15:1,54:1,508:1},cm),gX(P3n,"NetworkSimplexPlacer/Path",508),lAn(1409,1,{},Kc),EWn.Kb=function(n){return _B(n,17).d.i.k},gX(P3n,"NetworkSimplexPlacer/Path/lambda$0$Type",1409),lAn(1410,1,NVn,_c),EWn.Mb=function(n){return _B(n,267)==(cSn(),Mut)},gX(P3n,"NetworkSimplexPlacer/Path/lambda$1$Type",1410),lAn(1411,1,{},Fc),EWn.Kb=function(n){return _B(n,17).d.i},gX(P3n,"NetworkSimplexPlacer/Path/lambda$2$Type",1411),lAn(1412,1,NVn,tg),EWn.Mb=function(n){return FD(Zwn(_B(n,10)))},gX(P3n,"NetworkSimplexPlacer/Path/lambda$3$Type",1412),lAn(1413,1,NVn,Bc),EWn.Mb=function(n){return oq(_B(n,11))},gX(P3n,"NetworkSimplexPlacer/lambda$0$Type",1413),lAn(1414,1,hVn,ZP),EWn.td=function(n){N$(this.a,this.b,_B(n,11))},gX(P3n,"NetworkSimplexPlacer/lambda$1$Type",1414),lAn(1423,1,hVn,eg),EWn.td=function(n){UIn(this.a,_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$10$Type",1423),lAn(1424,1,{},Hc),EWn.Kb=function(n){return _Z(),new xq(null,new l1(_B(n,29).a,16))},gX(P3n,"NetworkSimplexPlacer/lambda$11$Type",1424),lAn(1425,1,hVn,ig),EWn.td=function(n){_Dn(this.a,_B(n,10))},gX(P3n,"NetworkSimplexPlacer/lambda$12$Type",1425),lAn(1426,1,{},qc),EWn.Kb=function(n){return _Z(),tln(_B(n,121).e)},gX(P3n,"NetworkSimplexPlacer/lambda$13$Type",1426),lAn(1428,1,{},Gc),EWn.Kb=function(n){return _Z(),tln(_B(n,121).e)},gX(P3n,"NetworkSimplexPlacer/lambda$15$Type",1428),lAn(1430,1,NVn,zc),EWn.Mb=function(n){return _Z(),_B(n,401).c.k==(cSn(),Sut)},gX(P3n,"NetworkSimplexPlacer/lambda$17$Type",1430),lAn(1431,1,NVn,Uc),EWn.Mb=function(n){return _Z(),_B(n,401).c.j.c.length>1},gX(P3n,"NetworkSimplexPlacer/lambda$18$Type",1431),lAn(1432,1,hVn,qV),EWn.td=function(n){iwn(this.c,this.b,this.d,this.a,_B(n,401))},EWn.c=0,EWn.d=0,gX(P3n,"NetworkSimplexPlacer/lambda$19$Type",1432),lAn(1415,1,{},Xc),EWn.Kb=function(n){return _Z(),new xq(null,new l1(_B(n,29).a,16))},gX(P3n,"NetworkSimplexPlacer/lambda$2$Type",1415),lAn(1433,1,hVn,rg),EWn.td=function(n){$$(this.a,_B(n,11))},EWn.a=0,gX(P3n,"NetworkSimplexPlacer/lambda$20$Type",1433),lAn(1434,1,{},Wc),EWn.Kb=function(n){return _Z(),new xq(null,new l1(_B(n,29).a,16))},gX(P3n,"NetworkSimplexPlacer/lambda$21$Type",1434),lAn(1435,1,hVn,cg),EWn.td=function(n){bL(this.a,_B(n,10))},gX(P3n,"NetworkSimplexPlacer/lambda$22$Type",1435),lAn(1436,1,NVn,Vc),EWn.Mb=function(n){return FD(n)},gX(P3n,"NetworkSimplexPlacer/lambda$23$Type",1436),lAn(1437,1,{},Qc),EWn.Kb=function(n){return _Z(),new xq(null,new l1(_B(n,29).a,16))},gX(P3n,"NetworkSimplexPlacer/lambda$24$Type",1437),lAn(1438,1,NVn,ag),EWn.Mb=function(n){return kO(this.a,_B(n,10))},gX(P3n,"NetworkSimplexPlacer/lambda$25$Type",1438),lAn(1439,1,hVn,nI),EWn.td=function(n){EPn(this.a,this.b,_B(n,10))},gX(P3n,"NetworkSimplexPlacer/lambda$26$Type",1439),lAn(1440,1,NVn,Jc),EWn.Mb=function(n){return _Z(),!f5(_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$27$Type",1440),lAn(1441,1,NVn,Yc),EWn.Mb=function(n){return _Z(),!f5(_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$28$Type",1441),lAn(1442,1,{},ug),EWn.Ce=function(n,t){return uL(this.a,_B(n,29),_B(t,29))},gX(P3n,"NetworkSimplexPlacer/lambda$29$Type",1442),lAn(1416,1,{},Zc),EWn.Kb=function(n){return _Z(),new xq(null,new qU(new az(JL(hbn(_B(n,10)).a.Kc(),new h))))},gX(P3n,"NetworkSimplexPlacer/lambda$3$Type",1416),lAn(1417,1,NVn,na),EWn.Mb=function(n){return _Z(),Z0(_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$4$Type",1417),lAn(1418,1,hVn,og),EWn.td=function(n){tBn(this.a,_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$5$Type",1418),lAn(1419,1,{},ta),EWn.Kb=function(n){return _Z(),new xq(null,new l1(_B(n,29).a,16))},gX(P3n,"NetworkSimplexPlacer/lambda$6$Type",1419),lAn(1420,1,NVn,ea),EWn.Mb=function(n){return _Z(),_B(n,10).k==(cSn(),Sut)},gX(P3n,"NetworkSimplexPlacer/lambda$7$Type",1420),lAn(1421,1,{},ia),EWn.Kb=function(n){return _Z(),new xq(null,new qU(new az(JL(obn(_B(n,10)).a.Kc(),new h))))},gX(P3n,"NetworkSimplexPlacer/lambda$8$Type",1421),lAn(1422,1,NVn,ra),EWn.Mb=function(n){return _Z(),GH(_B(n,17))},gX(P3n,"NetworkSimplexPlacer/lambda$9$Type",1422),lAn(1404,1,k3n,Sf),EWn.Yf=function(n){return _B(pMn(_B(n,37),(oWn(),Jft)),21).Hc((fDn(),hft))?Jmt:null},EWn.pf=function(n,t){mHn(_B(n,37),t)},gX(P3n,"SimpleNodePlacer",1404),lAn(180,1,{180:1},BKn),EWn.Ib=function(){var n;return n="",this.c==(wY(),Zmt)?n+=rYn:this.c==Ymt&&(n+=iYn),this.o==(aZ(),eyt)?n+=dYn:this.o==iyt?n+="UP":n+="BALANCED",n},gX(O3n,"BKAlignedLayout",180),lAn(516,22,{3:1,35:1,22:1,516:1},iI);var tyt,eyt,iyt,ryt=_en(O3n,"BKAlignedLayout/HDirection",516,Gnt,XJ,MF);lAn(515,22,{3:1,35:1,22:1,515:1},eI);var cyt,ayt,uyt,oyt,syt,hyt,fyt,lyt,byt,wyt,dyt,gyt,pyt,vyt,myt,yyt,kyt,jyt,Eyt,Tyt=_en(O3n,"BKAlignedLayout/VDirection",515,Gnt,WJ,SF);lAn(1634,1,{},tI),gX(O3n,"BKAligner",1634),lAn(1637,1,{},Qyn),gX(O3n,"BKCompactor",1637),lAn(654,1,{654:1},ca),EWn.a=0,gX(O3n,"BKCompactor/ClassEdge",654),lAn(458,1,{458:1},im),EWn.a=null,EWn.b=0,gX(O3n,"BKCompactor/ClassNode",458),lAn(1407,1,k3n,yC),EWn.Yf=function(n){return _B(pMn(_B(n,37),(oWn(),Jft)),21).Hc((fDn(),hft))?ayt:null},EWn.pf=function(n,t){eWn(this,_B(n,37),t)},EWn.d=!1,gX(O3n,"BKNodePlacer",1407),lAn(1635,1,{},aa),EWn.d=0,gX(O3n,"NeighborhoodInformation",1635),lAn(1636,1,EJn,sg),EWn.ue=function(n,t){return Etn(this,_B(n,46),_B(t,46))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(O3n,"NeighborhoodInformation/NeighborComparator",1636),lAn(808,1,{}),gX(O3n,"ThresholdStrategy",808),lAn(1763,808,{},bm),EWn.bg=function(n,t,e){return this.a.o==(aZ(),iyt)?xQn:DQn},EWn.cg=function(){},gX(O3n,"ThresholdStrategy/NullThresholdStrategy",1763),lAn(579,1,{579:1},rI),EWn.c=!1,EWn.d=!1,gX(O3n,"ThresholdStrategy/Postprocessable",579),lAn(1764,808,{},wm),EWn.bg=function(n,t,e){var i,r,c;return r=t==e,i=this.a.a[e.p]==t,r||i?(c=n,this.a.c,wY(),r&&(c=jHn(this,t,!0)),!isNaN(c)&&!isFinite(c)&&i&&(c=jHn(this,e,!1)),c):n},EWn.cg=function(){for(var n,t,e;0!=this.d.b;)(t=iFn(this,e=_B(MY(this.d),579))).a&&(n=t.a,(By(this.a.f[this.a.g[e.b.p].p])||f5(n)||n.c.i.c!=n.d.i.c)&&(f$n(this,e)||eA(this.e,e)));for(;0!=this.e.a.c.length;)f$n(this,_B(Zsn(this.e),579))},gX(O3n,"ThresholdStrategy/SimpleThresholdStrategy",1764),lAn(635,1,{635:1,246:1,234:1},ua),EWn.Kf=function(){return jan(this)},EWn.Xf=function(){return jan(this)},gX(A3n,"EdgeRouterFactory",635),lAn(1458,1,k3n,Pf),EWn.Yf=function(n){return Gxn(_B(n,37))},EWn.pf=function(n,t){NHn(_B(n,37),t)},gX(A3n,"OrthogonalEdgeRouter",1458),lAn(1451,1,k3n,kC),EWn.Yf=function(n){return kjn(_B(n,37))},EWn.pf=function(n,t){IUn(this,_B(n,37),t)},gX(A3n,"PolylineEdgeRouter",1451),lAn(1452,1,BJn,oa),EWn.Lb=function(n){return Wan(_B(n,10))},EWn.Fb=function(n){return this===n},EWn.Mb=function(n){return Wan(_B(n,10))},gX(A3n,"PolylineEdgeRouter/1",1452),lAn(1809,1,NVn,sa),EWn.Mb=function(n){return _B(n,129).c==(I6(),jyt)},gX($3n,"HyperEdgeCycleDetector/lambda$0$Type",1809),lAn(1810,1,{},ha),EWn.Ge=function(n){return _B(n,129).d},gX($3n,"HyperEdgeCycleDetector/lambda$1$Type",1810),lAn(1811,1,NVn,fa),EWn.Mb=function(n){return _B(n,129).c==(I6(),jyt)},gX($3n,"HyperEdgeCycleDetector/lambda$2$Type",1811),lAn(1812,1,{},la),EWn.Ge=function(n){return _B(n,129).d},gX($3n,"HyperEdgeCycleDetector/lambda$3$Type",1812),lAn(1813,1,{},ba),EWn.Ge=function(n){return _B(n,129).d},gX($3n,"HyperEdgeCycleDetector/lambda$4$Type",1813),lAn(1814,1,{},wa),EWn.Ge=function(n){return _B(n,129).d},gX($3n,"HyperEdgeCycleDetector/lambda$5$Type",1814),lAn(112,1,{35:1,112:1},Kan),EWn.wd=function(n){return aj(this,_B(n,112))},EWn.Fb=function(n){var t;return!!iL(n,112)&&(t=_B(n,112),this.g==t.g)},EWn.Hb=function(){return this.g},EWn.Ib=function(){var n,t,e,i;for(n=new hN("{"),i=new Ub(this.n);i.a"+this.b+" ("+lx(this.c)+")"},EWn.d=0,gX($3n,"HyperEdgeSegmentDependency",129),lAn(520,22,{3:1,35:1,22:1,520:1},cI);var Myt,Syt,Pyt,Iyt,Cyt,Oyt,Ayt,$yt,Lyt=_en($3n,"HyperEdgeSegmentDependency/DependencyType",520,Gnt,UJ,PF);lAn(1815,1,{},hg),gX($3n,"HyperEdgeSegmentSplitter",1815),lAn(1816,1,{},qj),EWn.a=0,EWn.b=0,gX($3n,"HyperEdgeSegmentSplitter/AreaRating",1816),lAn(329,1,{329:1},mB),EWn.a=0,EWn.b=0,EWn.c=0,gX($3n,"HyperEdgeSegmentSplitter/FreeArea",329),lAn(1817,1,EJn,ja),EWn.ue=function(n,t){return IK(_B(n,112),_B(t,112))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX($3n,"HyperEdgeSegmentSplitter/lambda$0$Type",1817),lAn(1818,1,hVn,zV),EWn.td=function(n){Y3(this.a,this.d,this.c,this.b,_B(n,112))},EWn.b=0,gX($3n,"HyperEdgeSegmentSplitter/lambda$1$Type",1818),lAn(1819,1,{},Ea),EWn.Kb=function(n){return new xq(null,new l1(_B(n,112).e,16))},gX($3n,"HyperEdgeSegmentSplitter/lambda$2$Type",1819),lAn(1820,1,{},Ta),EWn.Kb=function(n){return new xq(null,new l1(_B(n,112).j,16))},gX($3n,"HyperEdgeSegmentSplitter/lambda$3$Type",1820),lAn(1821,1,{},Ma),EWn.Fe=function(n){return Hy(ED(n))},gX($3n,"HyperEdgeSegmentSplitter/lambda$4$Type",1821),lAn(655,1,{},sX),EWn.a=0,EWn.b=0,EWn.c=0,gX($3n,"OrthogonalRoutingGenerator",655),lAn(1638,1,{},Sa),EWn.Kb=function(n){return new xq(null,new l1(_B(n,112).e,16))},gX($3n,"OrthogonalRoutingGenerator/lambda$0$Type",1638),lAn(1639,1,{},Pa),EWn.Kb=function(n){return new xq(null,new l1(_B(n,112).j,16))},gX($3n,"OrthogonalRoutingGenerator/lambda$1$Type",1639),lAn(661,1,{}),gX(L3n,"BaseRoutingDirectionStrategy",661),lAn(1807,661,{},dm),EWn.dg=function(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*e,h=new Ub(n.n);h.ahZn&&(c=n,r=new LI(l,a=f),NH(u.a,r),K_n(this,u,c,r,!1),(b=n.r)&&(r=new LI(w=Hy(ED(Npn(b.e,0))),a),NH(u.a,r),K_n(this,u,c,r,!1),c=b,r=new LI(w,a=t+b.o*e),NH(u.a,r),K_n(this,u,c,r,!1)),r=new LI(g,a),NH(u.a,r),K_n(this,u,c,r,!1)))},EWn.eg=function(n){return n.i.n.a+n.n.a+n.a.a},EWn.fg=function(){return mUn(),TCt},EWn.gg=function(){return mUn(),uCt},gX(L3n,"NorthToSouthRoutingStrategy",1807),lAn(1808,661,{},gm),EWn.dg=function(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t-n.o*e,h=new Ub(n.n);h.ahZn&&(c=n,r=new LI(l,a=f),NH(u.a,r),K_n(this,u,c,r,!1),(b=n.r)&&(r=new LI(w=Hy(ED(Npn(b.e,0))),a),NH(u.a,r),K_n(this,u,c,r,!1),c=b,r=new LI(w,a=t-b.o*e),NH(u.a,r),K_n(this,u,c,r,!1)),r=new LI(g,a),NH(u.a,r),K_n(this,u,c,r,!1)))},EWn.eg=function(n){return n.i.n.a+n.n.a+n.a.a},EWn.fg=function(){return mUn(),uCt},EWn.gg=function(){return mUn(),TCt},gX(L3n,"SouthToNorthRoutingStrategy",1808),lAn(1806,661,{},pm),EWn.dg=function(n,t,e){var r,c,a,u,o,s,h,f,l,b,w,d,g;if(!n.r||n.q)for(f=t+n.o*e,h=new Ub(n.n);h.ahZn&&(c=n,r=new LI(a=f,l),NH(u.a,r),K_n(this,u,c,r,!0),(b=n.r)&&(r=new LI(a,w=Hy(ED(Npn(b.e,0)))),NH(u.a,r),K_n(this,u,c,r,!0),c=b,r=new LI(a=t+b.o*e,w),NH(u.a,r),K_n(this,u,c,r,!0)),r=new LI(a,g),NH(u.a,r),K_n(this,u,c,r,!0)))},EWn.eg=function(n){return n.i.n.b+n.n.b+n.a.b},EWn.fg=function(){return mUn(),aCt},EWn.gg=function(){return mUn(),SCt},gX(L3n,"WestToEastRoutingStrategy",1806),lAn(813,1,{},aBn),EWn.Ib=function(){return AMn(this.a)},EWn.b=0,EWn.c=!1,EWn.d=!1,EWn.f=0,gX(x3n,"NubSpline",813),lAn(407,1,{407:1},kxn,lY),gX(x3n,"NubSpline/PolarCP",407),lAn(1453,1,k3n,oyn),EWn.Yf=function(n){return eTn(_B(n,37))},EWn.pf=function(n,t){iXn(this,_B(n,37),t)},gX(x3n,"SplineEdgeRouter",1453),lAn(268,1,{268:1},T6),EWn.Ib=function(){return this.a+" ->("+this.c+") "+this.b},EWn.c=0,gX(x3n,"SplineEdgeRouter/Dependency",268),lAn(455,22,{3:1,35:1,22:1,455:1},aI);var Nyt,xyt,Dyt,Ryt,Kyt,_yt=_en(x3n,"SplineEdgeRouter/SideToProcess",455,Gnt,VJ,IF);lAn(1454,1,NVn,ya),EWn.Mb=function(n){return wxn(),!_B(n,128).o},gX(x3n,"SplineEdgeRouter/lambda$0$Type",1454),lAn(1455,1,{},ma),EWn.Ge=function(n){return wxn(),_B(n,128).v+1},gX(x3n,"SplineEdgeRouter/lambda$1$Type",1455),lAn(1456,1,hVn,uI),EWn.td=function(n){tq(this.a,this.b,_B(n,46))},gX(x3n,"SplineEdgeRouter/lambda$2$Type",1456),lAn(1457,1,hVn,oI),EWn.td=function(n){eq(this.a,this.b,_B(n,46))},gX(x3n,"SplineEdgeRouter/lambda$3$Type",1457),lAn(128,1,{35:1,128:1},ZPn,oqn),EWn.wd=function(n){return uj(this,_B(n,128))},EWn.b=0,EWn.e=!1,EWn.f=0,EWn.g=0,EWn.j=!1,EWn.k=!1,EWn.n=0,EWn.o=!1,EWn.p=!1,EWn.q=!1,EWn.s=0,EWn.u=0,EWn.v=0,EWn.F=0,gX(x3n,"SplineSegment",128),lAn(459,1,{459:1},ka),EWn.a=0,EWn.b=!1,EWn.c=!1,EWn.d=!1,EWn.e=!1,EWn.f=0,gX(x3n,"SplineSegment/EdgeInformation",459),lAn(1234,1,{},da),gX(F3n,tZn,1234),lAn(1235,1,EJn,ga),EWn.ue=function(n,t){return PCn(_B(n,135),_B(t,135))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(F3n,eZn,1235),lAn(1233,1,{},CE),gX(F3n,"MrTree",1233),lAn(393,22,{3:1,35:1,22:1,393:1,246:1,234:1},sI),EWn.Kf=function(){return CCn(this)},EWn.Xf=function(){return CCn(this)};var Fyt,Byt=_en(F3n,"TreeLayoutPhases",393,Gnt,y3,CF);lAn(1130,209,$Yn,RR),EWn.Ze=function(n,t){var e,i,r,c,a,u;for(By(jD(JAn(n,(SAn(),Skt))))||yY(new jw((HM(),new Ny(n)))),Ban(a=new M6,n),oon(a,(Bqn(),ukt),n),g_n(n,a,u=new Lp),U_n(n,a,u),c=a,i=new Ub(r=L_n(this.a,c));i.a"+w0(this.c):"e_"+Yon(this)},gX(B3n,"TEdge",188),lAn(135,134,{3:1,135:1,94:1,134:1},M6),EWn.Ib=function(){var n,t,e,i,r;for(r=null,i=upn(this.b,0);i.b!=i.d.c;)r+=(null==(e=_B(f3(i),86)).c||0==e.c.length?"n_"+e.g:"n_"+e.c)+"\n";for(t=upn(this.a,0);t.b!=t.d.c;)r+=((n=_B(f3(t),188)).b&&n.c?w0(n.b)+"->"+w0(n.c):"e_"+Yon(n))+"\n";return r};var Hyt=gX(B3n,"TGraph",135);lAn(633,502,{3:1,502:1,633:1,94:1,134:1}),gX(B3n,"TShape",633),lAn(86,633,{3:1,502:1,86:1,633:1,94:1,134:1},isn),EWn.Ib=function(){return w0(this)};var qyt,Gyt,zyt,Uyt,Xyt,Wyt,Vyt=gX(B3n,"TNode",86);lAn(255,1,dVn,fg),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return new lg(upn(this.a.d,0))},gX(B3n,"TNode/2",255),lAn(358,1,WWn,lg),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return _B(f3(this.a),188).c},EWn.Ob=function(){return kE(this.a)},EWn.Qb=function(){ptn(this.a)},gX(B3n,"TNode/2/1",358),lAn(1840,1,YZn,DR),EWn.pf=function(n,t){LFn(this,_B(n,135),t)},gX(H3n,"FanProcessor",1840),lAn(327,22,{3:1,35:1,22:1,327:1,234:1},hI),EWn.Kf=function(){switch(this.g){case 0:return new Wm;case 1:return new DR;case 2:return new Oa;case 3:return new Ia;case 4:return new $a;case 5:return new La;default:throw Fp(new Ry(E1n+(null!=this.f?this.f:""+this.g)))}};var Qyt,Jyt,Yyt,Zyt,nkt,tkt,ekt,ikt,rkt,ckt,akt,ukt,okt,skt,hkt,fkt,lkt,bkt,wkt,dkt,gkt,pkt,vkt,mkt,ykt,kkt,jkt,Ekt,Tkt,Mkt,Skt,Pkt,Ikt,Ckt,Okt,Akt,$kt,Lkt,Nkt,xkt,Dkt,Rkt=_en(H3n,T1n,327,Gnt,e9,OF);lAn(1843,1,YZn,Ia),EWn.pf=function(n,t){c$n(this,_B(n,135),t)},EWn.a=0,gX(H3n,"LevelHeightProcessor",1843),lAn(1844,1,dVn,Ca),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return TQ(),AT(),het},gX(H3n,"LevelHeightProcessor/1",1844),lAn(1841,1,YZn,Oa),EWn.pf=function(n,t){WPn(this,_B(n,135),t)},EWn.a=0,gX(H3n,"NeighborsProcessor",1841),lAn(1842,1,dVn,Aa),EWn.Jc=function(n){n5(this,n)},EWn.Kc=function(){return TQ(),AT(),het},gX(H3n,"NeighborsProcessor/1",1842),lAn(1845,1,YZn,$a),EWn.pf=function(n,t){r$n(this,_B(n,135),t)},EWn.a=0,gX(H3n,"NodePositionProcessor",1845),lAn(1839,1,YZn,Wm),EWn.pf=function(n,t){JHn(this,_B(n,135))},gX(H3n,"RootProcessor",1839),lAn(1846,1,YZn,La),EWn.pf=function(n,t){bln(_B(n,135))},gX(H3n,"Untreeifyer",1846),lAn(851,1,WJn,Mf),EWn.Qe=function(n){Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,z3n),""),"Weighting of Nodes"),"Which weighting to use when computing a node order."),mkt),(MPn(),wMt)),Bkt),Yln((epn(),oMt))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,U3n),""),"Search Order"),"Which search order to use when computing a spanning tree."),pkt),wMt),Qkt),Yln(oMt)))),DGn((new Tf,n))},gX(X3n,"MrTreeMetaDataProvider",851),lAn(994,1,WJn,Tf),EWn.Qe=function(n){DGn(n)},gX(X3n,"MrTreeOptions",994),lAn(995,1,{},Na),EWn.$e=function(){return new RR},EWn._e=function(n){},gX(X3n,"MrTreeOptions/MrtreeFactory",995),lAn(480,22,{3:1,35:1,22:1,480:1},fI);var Kkt,_kt,Fkt,Bkt=_en(X3n,"OrderWeighting",480,Gnt,JJ,AF);lAn(425,22,{3:1,35:1,22:1,425:1},lI);var Hkt,qkt,Gkt,zkt,Ukt,Xkt,Wkt,Vkt,Qkt=_en(X3n,"TreeifyingOrder",425,Gnt,QJ,LF);lAn(1459,1,k3n,df),EWn.Yf=function(n){return _B(n,135),qkt},EWn.pf=function(n,t){vcn(this,_B(n,135),t)},gX("org.eclipse.elk.alg.mrtree.p1treeify","DFSTreeifyer",1459),lAn(1460,1,k3n,gf),EWn.Yf=function(n){return _B(n,135),Gkt},EWn.pf=function(n,t){sIn(this,_B(n,135),t)},gX("org.eclipse.elk.alg.mrtree.p2order","NodeOrderer",1460),lAn(1461,1,k3n,wf),EWn.Yf=function(n){return _B(n,135),zkt},EWn.pf=function(n,t){YDn(this,_B(n,135),t)},EWn.a=0,gX("org.eclipse.elk.alg.mrtree.p3place","NodePlacer",1461),lAn(1462,1,k3n,pf),EWn.Yf=function(n){return _B(n,135),Ukt},EWn.pf=function(n,t){Lkn(_B(n,135),t)},gX("org.eclipse.elk.alg.mrtree.p4route","EdgeRouter",1462),lAn(495,22,{3:1,35:1,22:1,495:1,246:1,234:1},bI),EWn.Kf=function(){return fwn(this)},EWn.Xf=function(){return fwn(this)};var Jkt,Ykt,Zkt,njt,tjt=_en(Q3n,"RadialLayoutPhases",495,Gnt,YJ,$F);lAn(1131,209,$Yn,IE),EWn.Ze=function(n,t){var e,i,r;if(ITn(t,"Radial layout",kIn(this,n).c.length),By(jD(JAn(n,(Gyn(),Cjt))))||yY(new jw((HM(),new Ny(n)))),r=cTn(n),Vpn(n,(lD(),Xkt),r),!r)throw Fp(new Ry("The given graph is not a tree!"));for(0==(e=Hy(ED(JAn(n,Njt))))&&(e=sCn(n)),Vpn(n,Njt,e),i=new Ub(kIn(this,n));i.a0&&Lhn((f1(t-1,n.length),n.charCodeAt(t-1)),u1n);)--t;if(e>=t)throw Fp(new Ry("The given string does not contain any numbers."));if(2!=(i=mKn(n.substr(e,t-e),",|;|\r|\n")).length)throw Fp(new Ry("Exactly two numbers are expected, "+i.length+" were found."));try{this.a=fSn(xMn(i[0])),this.b=fSn(xMn(i[1]))}catch(r){throw iL(r=hun(r),127)?Fp(new Ry(o1n+r)):Fp(r)}},EWn.Ib=function(){return"("+this.a+","+this.b+")"},EWn.a=0,EWn.b=0;var MMt=gX(s1n,"KVector",8);lAn(74,68,{3:1,4:1,20:1,28:1,52:1,14:1,68:1,15:1,74:1,414:1},mm,Dj,Gx),EWn.Pc=function(){return Xsn(this)},EWn.Jf=function(n){var t,e,i,r,c;e=mKn(n,",|;|\\(|\\)|\\[|\\]|\\{|\\}| |\t|\n"),vQ(this);try{for(t=0,r=0,i=0,c=0;t0&&(r%2==0?i=fSn(e[t]):c=fSn(e[t]),r>0&&r%2!=0&&NH(this,new LI(i,c)),++r),++t}catch(a){throw iL(a=hun(a),127)?Fp(new Ry("The given string does not match the expected format for vectors."+a)):Fp(a)}},EWn.Ib=function(){var n,t,e;for(n=new hN("("),t=upn(this,0);t.b!=t.d.c;)aO(n,(e=_B(f3(t),8)).a+","+e.b),t.b!=t.d.c&&(n.a+="; ");return(n.a+=")",n).a};var SMt,PMt,IMt,CMt,OMt,AMt,$Mt=gX(s1n,"KVectorChain",74);lAn(248,22,{3:1,35:1,22:1,248:1},NI);var LMt,NMt,xMt,DMt,RMt,KMt,_Mt,FMt,BMt,HMt,qMt,GMt,zMt,UMt,XMt,WMt,VMt,QMt,JMt,YMt=_en(o5n,"Alignment",248,Gnt,Q8,QF);lAn(979,1,WJn,Af),EWn.Qe=function(n){H_n(n)},gX(o5n,"BoxLayouterOptions",979),lAn(980,1,{},xu),EWn.$e=function(){return new Gu},EWn._e=function(n){},gX(o5n,"BoxLayouterOptions/BoxFactory",980),lAn(291,22,{3:1,35:1,22:1,291:1},xI);var ZMt,nSt,tSt,eSt,iSt,rSt,cSt,aSt,uSt,oSt,sSt,hSt,fSt,lSt,bSt,wSt,dSt,gSt,pSt,vSt,mSt,ySt,kSt,jSt,ESt,TSt,MSt,SSt,PSt,ISt,CSt,OSt,ASt,$St,LSt,NSt,xSt,DSt,RSt,KSt,_St,FSt,BSt,HSt,qSt,GSt,zSt,USt,XSt,WSt,VSt,QSt,JSt,YSt,ZSt,nPt,tPt,ePt,iPt,rPt,cPt,aPt,uPt,oPt,sPt,hPt,fPt,lPt,bPt,wPt,dPt,gPt,pPt,vPt,mPt,yPt,kPt,jPt,EPt,TPt,MPt,SPt,PPt,IPt,CPt,OPt,APt,$Pt,LPt,NPt,xPt,DPt,RPt,KPt,_Pt,FPt,BPt=_en(o5n,"ContentAlignment",291,Gnt,V8,JF);lAn(684,1,WJn,$f),EWn.Qe=function(n){Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,l5n),""),"Layout Algorithm"),"Select a specific layout algorithm."),(MPn(),vMt)),Wtt),Yln((epn(),oMt))))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,b5n),""),"Resolved Layout Algorithm"),"Meta data associated with the selected algorithm."),pMt),rMt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,U2n),""),"Alignment"),"Alignment of the selected node relative to other nodes; the exact meaning depends on the used algorithm."),eSt),wMt),YMt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,XYn),""),"Aspect Ratio"),"The desired aspect ratio of the drawing, that is the quotient of width by height."),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,w5n),""),"Bend Points"),"A fixed list of bend points for the edge. This is used by the 'Fixed Layout' algorithm to specify a pre-defined routing for an edge. The vector chain must include the source point, any bend points, and the target point, so it must have at least two points."),pMt),$Mt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,c3n),""),"Content Alignment"),"Specifies how the content of a node are aligned. Each node can individually control the alignment of its contents. I.e. if a node should be aligned top left in its parent node, the parent node should specify that option."),sSt),dMt),BPt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,z2n),""),"Debug Mode"),"Whether additional debug information shall be generated."),(oN(),!1)),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Q2n),""),jYn),"Overall direction of edges: horizontal (right / left) or vertical (down / up)."),lSt),wMt),UPt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,v2n),""),"Edge Routing"),"What kind of edge routing style should be applied for the content of a parent node. Algorithms may also set this option to single edges in order to mark them as splines. The bend point list of edges with this option set to SPLINES must be interpreted as control points for a piecewise cubic spline."),pSt),wMt),aIt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,C4n),""),"Expand Nodes"),"If active, nodes are expanded to fill the area of their parent."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,b2n),""),"Hierarchy Handling"),"Determines whether separate layout runs are triggered for different compound nodes in a hierarchical graph. Setting a node's hierarchy handling to `INCLUDE_CHILDREN` will lay out that node and all of its descendants in a single layout run, until a descendant is encountered which has its hierarchy handling set to `SEPARATE_CHILDREN`. In general, `SEPARATE_CHILDREN` will ensure that a new layout run is triggered for a node with that setting. Including multiple levels of hierarchy in a single layout run may allow cross-hierarchical edges to be laid out properly. If the root node is set to `INHERIT` (or not set at all), the default behavior is `SEPARATE_CHILDREN`."),jSt),wMt),TIt),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[uMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,WYn),""),"Padding"),"The padding to be left to a parent element's border when placing child elements. This can also serve as an output option of a layout algorithm if node size calculation is setup appropriately."),USt),pMt),Rut),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[uMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,yZn),""),"Interactive"),"Whether the algorithm should be run in interactive mode for the content of a parent node. What this means exactly depends on how the specific algorithm interprets this option. Usually in the interactive mode algorithms try to modify the current layout as little as possible."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,p3n),""),"interactive Layout"),"Whether the graph should be changeable interactively and by setting constraints"),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,EZn),""),"Omit Node Micro Layout"),"Node micro layout comprises the computation of node dimensions (if requested), the placement of ports and their labels, and the placement of node labels. The functionality is implemented independent of any specific layout algorithm and shouldn't have any negative impact on the layout algorithm's performance itself. Yet, if any unforeseen behavior occurs, this option allows to deactivate the micro layout."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,kZn),""),"Port Constraints"),"Defines constraints of the position of the ports of a node."),aPt),wMt),rCt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,w3n),""),"Position"),"The position of a node, port, or label. This is used by the 'Fixed Layout' algorithm to specify a pre-defined position."),pMt),MMt),kG(uMt,Mun(Hk(yMt,1),OVn,175,0,[sMt,aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,dZn),""),"Priority"),"Defines the priority of an object; its meaning depends on the specific layout algorithm and the context where it is used."),gMt),Ctt),kG(uMt,Mun(Hk(yMt,1),OVn,175,0,[cMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,vZn),""),"Randomization Seed"),"Seed used for pseudo-random number generators to control the layout algorithm. If the value is 0, the seed shall be determined pseudo-randomly (e.g. from the system time)."),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,mZn),""),"Separate Connected Components"),"Whether each connected component should be processed separately."),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,a3n),""),"Junction Points"),"This option is not used as option, but as output of the layout algorithms. It is attached to edges and determines the points where junction symbols should be drawn in order to represent hyperedges with orthogonal routing. Whether such points are computed depends on the chosen layout algorithm and edge routing style. The points are put into the vector chain with no specific order."),CSt),pMt),$Mt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,s3n),""),"Comment Box"),"Whether the node should be regarded as a comment box instead of a regular node. In that case its placement should be similar to how labels are handled. Any edges incident to a comment box specify to which graph elements the comment is related."),!1),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,h3n),""),"Hypernode"),"Whether the node should be handled as a hypernode."),!1),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,d5n),""),"Label Manager"),"Label managers can shorten labels upon a layout algorithm's request."),pMt),xNt),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,d3n),""),"Margins"),"Margins define additional space around the actual bounds of a graph element. For instance, ports or labels being placed on the outside of a node's border might introduce such a margin. The margin is used to guarantee non-overlap of other graph elements with those ports or labels."),ASt),pMt),kut),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,q2n),""),"No Layout"),"No layout is done for the associated element. This is used to mark parts of a diagram to avoid their inclusion in the layout graph, or to mark parts of the layout graph to prevent layout engines from processing them. If you wish to exclude the contents of a compound node from automatic layout, while the node itself is still considered on its own layer, use the 'Fixed Layout' algorithm for that node."),!1),lMt),mtt),kG(uMt,Mun(Hk(yMt,1),OVn,175,0,[cMt,sMt,aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,g5n),""),"Scale Factor"),"The scaling factor to be applied to the corresponding node in recursive layout. It causes the corresponding node's size to be adjusted, and its ports and labels to be sized and placed accordingly after the layout of that node has been determined (and before the node itself and its siblings are arranged). The scaling is not reverted afterwards, so the resulting layout graph contains the adjusted size and position data. This option is currently not supported if 'Layout Hierarchy' is set."),1),bMt),Mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,p5n),""),"Animate"),"Whether the shift from the old layout to the new computed layout shall be animated."),!0),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,v5n),""),"Animation Time Factor"),"Factor for computation of animation time. The higher the value, the longer the animation time. If the value is 0, the resulting time is always equal to the minimum defined by 'Minimal Animation Time'."),tln(100)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,m5n),""),"Layout Ancestors"),"Whether the hierarchy levels on the path from the selected element to the root of the diagram shall be included in the layout process."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,y5n),""),"Maximal Animation Time"),"The maximal time for animations, in milliseconds."),tln(4e3)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,k5n),""),"Minimal Animation Time"),"The minimal time for animations, in milliseconds."),tln(400)),gMt),Ctt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,j5n),""),"Progress Bar"),"Whether a progress bar shall be displayed during layout computations."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,E5n),""),"Validate Graph"),"Whether the graph shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,T5n),""),"Validate Options"),"Whether layout options shall be validated before any layout algorithm is applied. If this option is enabled and at least one error is found, the layout process is aborted and a message is shown to the user."),!0),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,M5n),""),"Zoom to Fit"),"Whether the zoom level shall be set to view the whole diagram after layout."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,f5n),"box"),"Box Layout Mode"),"Configures the packing mode used by the {@link BoxLayoutProvider}. If SIMPLE is not required (neither priorities are used nor the interactive mode), GROUP_DEC can improve the packing and decrease the area. GROUP_MIXED and GROUP_INC may, in very specific scenarios, work better."),aSt),wMt),iOt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,A2n),m2n),"Comment Comment Spacing"),"Spacing to be preserved between a comment box and other comment boxes connected to the same node. The space left between comment boxes of different nodes is controlled by the node-node spacing."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,$2n),m2n),"Comment Node Spacing"),"Spacing to be preserved between a node and its connected comment boxes. The space left between a node and the comments of another node is controlled by the node-node spacing."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,zYn),m2n),"Components Spacing"),"Spacing to be preserved between pairs of connected components. This option is only relevant if 'separateConnectedComponents' is activated."),20),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,L2n),m2n),"Edge Spacing"),"Spacing to be preserved between any two edges. Note that while this can somewhat easily be satisfied for the segments of orthogonally drawn edges, it is harder for general polylines or splines."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,pZn),m2n),"Edge Label Spacing"),"The minimal distance to be preserved between a label and the edge it is associated with. Note that the placement of a label is influenced by the 'edgelabels.placement' option."),2),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,N2n),m2n),"Edge Node Spacing"),"Spacing to be preserved between nodes and edges."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,x2n),m2n),"Label Spacing"),"Determines the amount of space to be left between two labels of the same graph element."),0),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,K2n),m2n),"Label Node Spacing"),"Spacing to be preserved between labels and the border of node they are associated with. Note that the placement of a label is influenced by the 'nodelabels.placement' option."),5),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,D2n),m2n),"Horizontal spacing between Label and Port"),"Horizontal spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,R2n),m2n),"Vertical spacing between Label and Port"),"Vertical spacing to be preserved between labels and the ports they are associated with. Note that the placement of a label is influenced by the 'portlabels.placement' option."),1),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,gZn),m2n),"Node Spacing"),"The minimal distance to be preserved between each two nodes."),20),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,_2n),m2n),"Node Self Loop Spacing"),"Spacing to be preserved between a node and its self loops."),10),bMt),Mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,F2n),m2n),"Port Spacing"),"Spacing between pairs of ports of the same node."),10),bMt),Mtt),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[uMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,B2n),m2n),"Individual Spacing"),"Allows to specify individual spacing values for graph elements that shall be different from the value specified for the element's parent."),pMt),oOt),kG(uMt,Mun(Hk(yMt,1),OVn,175,0,[cMt,sMt,aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,g3n),m2n),"Additional Port Space"),"Additional space around the sets of ports on each node side. For each side of a node, this option can reserve additional space before and after the ports on each side. For example, a top spacing of 20 makes sure that the first port on the western and eastern side is 20 units away from the northern border."),NPt),pMt),kut),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,b3n),C5n),"Layout Partition"),"Partition to which the node belongs. This requires Layout Partitioning to be active. Nodes with lower partition IDs will appear to the left of nodes with higher partition IDs (assuming a left-to-right layout direction)."),gMt),Ctt),kG(oMt,Mun(Hk(yMt,1),OVn,175,0,[uMt]))))),r2(n,b3n,l3n,QSt),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,l3n),C5n),"Layout Partitioning"),"Whether to activate partitioned layout. This will allow to group nodes through the Layout Partition option. a pair of nodes with different partition indices is then placed such that the node with lower index is placed to the left of the other node (with left-to-right layout direction). Depending on the layout algorithm, this may only be guaranteed to work if all nodes have a layout partition configured, or at least if edges that cross partitions are not part of a partition-crossing cycle."),WSt),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,J2n),O5n),"Node Label Padding"),"Define padding for node labels that are placed inside of a node."),LSt),pMt),Rut),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,SZn),O5n),"Node Label Placement"),"Hints for where node labels are to be placed; if empty, the node label's position is not modified."),xSt),dMt),HIt),kG(uMt,Mun(Hk(yMt,1),OVn,175,0,[aMt]))))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,n3n),A5n),"Port Alignment"),"Defines the default port distribution for a node. May be overridden for each side individually."),YSt),wMt),QIt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,t3n),A5n),"Port Alignment (North)"),"Defines how ports on the northern side are placed, overriding the node's general port alignment."),wMt),QIt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,e3n),A5n),"Port Alignment (South)"),"Defines how ports on the southern side are placed, overriding the node's general port alignment."),wMt),QIt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,i3n),A5n),"Port Alignment (West)"),"Defines how ports on the western side are placed, overriding the node's general port alignment."),wMt),QIt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,r3n),A5n),"Port Alignment (East)"),"Defines how ports on the eastern side are placed, overriding the node's general port alignment."),wMt),QIt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,MZn),$5n),"Node Size Constraints"),"What should be taken into account when calculating a node's size. Empty size constraints specify that a node's size is already fixed and should not be changed."),RSt),dMt),VCt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,TZn),$5n),"Node Size Options"),"Options modifying the behavior of the size constraints set on a node. Each member of the set specifies something that should be taken into account when calculating node sizes. The empty set corresponds to no further modifications."),HSt),dMt),tOt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,_Zn),$5n),"Node Size Minimum"),"The minimal size to which a node can be reduced."),FSt),pMt),MMt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,V2n),$5n),"Fixed Graph Size"),"By default, the fixed layout provider will enlarge a graph until it is large enough to contain its children. If this option is set, it won't do so."),!1),lMt),mtt),Yln(oMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,u3n),C2n),"Edge Label Placement"),"Gives a hint on where to put edge labels."),dSt),wMt),YPt),Yln(aMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,jZn),C2n),"Inline Edge Labels"),"If true, an edge label is placed directly on its edge. May only apply to center edge labels. This kind of label placement is only advisable if the label's rendering is such that it is not crossed by its edge and thus stays legible."),!1),lMt),mtt),Yln(aMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,S5n),"font"),"Font Name"),"Font name used for a label."),vMt),Wtt),Yln(aMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,P5n),"font"),"Font Size"),"Font size used for a label."),gMt),Ctt),Yln(aMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,f3n),L5n),"Port Anchor Offset"),"The offset to the port position where connections shall be attached."),pMt),MMt),Yln(sMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,o3n),L5n),"Port Index"),"The index of a port in the fixed order around a node. The order is assumed as clockwise, starting with the leftmost port on the top side. This option must be set if 'Port Constraints' is set to FIXED_ORDER and no specific positions are given for the ports. Additionally, the option 'Port Side' must be defined in this case."),gMt),Ctt),Yln(sMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,G2n),L5n),"Port Side"),"The side of a node on which a port is situated. This option must be set if 'Port Constraints' is set to FIXED_SIDE or FIXED_ORDER and no specific positions are given for the ports."),bPt),wMt),KCt),Yln(sMt)))),Cbn(n,new fPn(Ij(Pj(Cj(kj(Sj(Ej(Tj(new Fu,H2n),L5n),"Port Border Offset"),"The offset of ports on the node border. With a positive offset the port is moved outside of the node, while with a negative offset the port is moved towards the inside. An offset of 0 means that the port is placed directly on the node border, i.e. if the port side is north, the port's south border touches the nodes's north border; if the port side is east, the port's west border touches the nodes's east border; if the port side is south, the port's north border touches the node's south border; if the port side is west, the port's east border touches the node's west border."),bMt),Mtt),Yln(sMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,PZn),N5n),"Port Label Placement"),"Decides on a placement method for port labels; if empty, the node label's position is not modified."),hPt),dMt),PCt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Y2n),N5n),"Port Labels Next to Port"),"Use 'portLabels.placement': NEXT_TO_PORT_OF_POSSIBLE."),!1),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,Z2n),N5n),"Treat Port Labels as Group"),"If this option is true (default), the labels of a port will be treated as a group when it comes to centering them next to their port. If this option is false, only the first label will be centered next to the port, with the others being placed below. This only applies to labels of eastern and western ports and will have no effect if labels are not placed next to their port."),!0),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,X2n),x5n),"Activate Inside Self Loops"),"Whether this node allows to route self loops inside of it instead of around it. If set to true, this will make the node a compound node if it isn't already, and will require the layout algorithm to support compound nodes with hierarchical ports."),!1),lMt),mtt),Yln(uMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,W2n),x5n),"Inside Self Loop"),"Whether a self loop should be routed inside a node instead of around that node."),!1),lMt),mtt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,UYn),"edge"),"Edge Thickness"),"The thickness of an edge. This is a hint on the line width used to draw an edge, possibly requiring more space to be reserved for it."),1),bMt),Mtt),Yln(cMt)))),Cbn(n,new fPn(Ij(Pj(Cj(jj(kj(Sj(Ej(Tj(new Fu,I5n),"edge"),"Edge Type"),"The type of an edge. This is usually used for UML class diagrams, where associations must be handled differently from generalizations."),mSt),wMt),vIt),Yln(cMt)))),LM(n,new GZ(vj(yj(mj(new pu,l1n),"Layered"),'The layer-based method was introduced by Sugiyama, Tagawa and Toda in 1981. It emphasizes the direction of edges by pointing as many edges as possible into the same direction. The nodes are arranged in layers, which are sometimes called "hierarchies", and then reordered such that the number of edge crossings is minimized. Afterwards, concrete coordinates are computed for the nodes and edge bend points.'))),LM(n,new GZ(vj(yj(mj(new pu,"org.eclipse.elk.orthogonal"),"Orthogonal"),'Orthogonal methods that follow the "topology-shape-metrics" approach by Batini, Nardelli and Tamassia \'86. The first phase determines the topology of the drawing by applying a planarization technique, which results in a planar representation of the graph. The orthogonal shape is computed in the second phase, which aims at minimizing the number of edge bends, and is called orthogonalization. The third phase leads to concrete coordinates for nodes and edge bend points by applying a compaction method, thus defining the metrics.'))),LM(n,new GZ(vj(yj(mj(new pu,wZn),"Force"),"Layout algorithms that follow physical analogies by simulating a system of attractive and repulsive forces. The first successful method of this kind was proposed by Eades in 1984."))),LM(n,new GZ(vj(yj(mj(new pu,"org.eclipse.elk.circle"),"Circle"),"Circular layout algorithms emphasize cycles or biconnected components of a graph by arranging them in circles. This is useful if a drawing is desired where such components are clearly grouped, or where cycles are shown as prominent OPTIONS of the graph."))),LM(n,new GZ(vj(yj(mj(new pu,V3n),"Tree"),"Specialized layout methods for trees, i.e. acyclic graphs. The regular structure of graphs that have no undirected cycles can be emphasized using an algorithm of this type."))),LM(n,new GZ(vj(yj(mj(new pu,"org.eclipse.elk.planar"),"Planar"),"Algorithms that require a planar or upward planar graph. Most of these algorithms are theoretically interesting, but not practically usable."))),LM(n,new GZ(vj(yj(mj(new pu,l4n),"Radial"),"Radial layout algorithms usually position the nodes of the graph on concentric circles."))),fKn((new Lf,n)),H_n((new Af,n)),xDn((new Nf,n))},gX(o5n,"CoreOptions",684),lAn(103,22,{3:1,35:1,22:1,103:1},DI);var HPt,qPt,GPt,zPt,UPt=_en(o5n,jYn,103,Gnt,S5,nB);lAn(272,22,{3:1,35:1,22:1,272:1},RI);var XPt,WPt,VPt,QPt,JPt,YPt=_en(o5n,"EdgeLabelPlacement",272,Gnt,B1,tB);lAn(218,22,{3:1,35:1,22:1,218:1},KI);var ZPt,nIt,tIt,eIt,iIt,rIt,cIt,aIt=_en(o5n,"EdgeRouting",218,Gnt,T3,eB);lAn(312,22,{3:1,35:1,22:1,312:1},_I);var uIt,oIt,sIt,hIt,fIt,lIt,bIt,wIt,dIt,gIt,pIt,vIt=_en(o5n,"EdgeType",312,Gnt,r9,iB);lAn(977,1,WJn,Lf),EWn.Qe=function(n){fKn(n)},gX(o5n,"FixedLayouterOptions",977),lAn(978,1,{},Vu),EWn.$e=function(){return new Hu},EWn._e=function(n){},gX(o5n,"FixedLayouterOptions/FixedFactory",978),lAn(334,22,{3:1,35:1,22:1,334:1},FI);var mIt,yIt,kIt,jIt,EIt,TIt=_en(o5n,"HierarchyHandling",334,Gnt,F1,rB);lAn(285,22,{3:1,35:1,22:1,285:1},BI);var MIt,SIt,PIt,IIt,CIt,OIt,AIt,$It,LIt,NIt,xIt=_en(o5n,"LabelSide",285,Gnt,E3,cB);lAn(93,22,{3:1,35:1,22:1,93:1},HI);var DIt,RIt,KIt,_It,FIt,BIt,HIt=_en(o5n,"NodeLabelPlacement",93,Gnt,men,aB);lAn(249,22,{3:1,35:1,22:1,249:1},qI);var qIt,GIt,zIt,UIt,XIt,WIt,VIt,QIt=_en(o5n,"PortAlignment",249,Gnt,P5,uB);lAn(98,22,{3:1,35:1,22:1,98:1},GI);var JIt,YIt,ZIt,nCt,tCt,eCt,iCt,rCt=_en(o5n,"PortConstraints",98,Gnt,T8,oB);lAn(273,22,{3:1,35:1,22:1,273:1},zI);var cCt,aCt,uCt,oCt,sCt,hCt,fCt,lCt,bCt,wCt,dCt,gCt,pCt,vCt,mCt,yCt,kCt,jCt,ECt,TCt,MCt,SCt,PCt=_en(o5n,"PortLabelPlacement",273,Gnt,i9,sB);lAn(61,22,{3:1,35:1,22:1,61:1},UI);var ICt,CCt,OCt,ACt,$Ct,LCt,NCt,xCt,DCt,RCt,KCt=_en(o5n,"PortSide",61,Gnt,o5,lB);lAn(981,1,WJn,Nf),EWn.Qe=function(n){xDn(n)},gX(o5n,"RandomLayouterOptions",981),lAn(982,1,{},Qu),EWn.$e=function(){return new no},EWn._e=function(n){},gX(o5n,"RandomLayouterOptions/RandomFactory",982),lAn(374,22,{3:1,35:1,22:1,374:1},XI);var _Ct,FCt,BCt,HCt,qCt,GCt,zCt,UCt,XCt,WCt,VCt=_en(o5n,"SizeConstraint",374,Gnt,j3,hB);lAn(259,22,{3:1,35:1,22:1,259:1},WI);var QCt,JCt,YCt,ZCt,nOt,tOt=_en(o5n,"SizeOptions",259,Gnt,kin,fB);lAn(370,1,{1949:1},zm),EWn.b=!1,EWn.c=0,EWn.d=-1,EWn.e=null,EWn.f=null,EWn.g=-1,EWn.j=!1,EWn.k=!1,EWn.n=!1,EWn.o=0,EWn.q=0,EWn.r=0,gX(v3n,"BasicProgressMonitor",370),lAn(972,209,$Yn,Gu),EWn.Ze=function(n,t){var e,i,r,c,a,u,o,s,h;switch(ITn(t,"Box layout",2),r=qy(ED(JAn(n,(TMn(),zMt)))),c=_B(JAn(n,HMt),116),e=By(jD(JAn(n,RMt))),i=By(jD(JAn(n,KMt))),_B(JAn(n,xMt),311).g){case 0:u=new ZK((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a)),TQ(),p$(u,new Tg(i)),a=u,o=zPn(n),(null==(s=ED(JAn(n,NMt)))||(mW(s),s<=0))&&(s=1.3),DUn(n,(h=FUn(a,r,c,o.a,o.b,e,(mW(s),s))).a,h.b,!1,!0);break;default:mqn(n,r,c,e)}FSn(t)},gX(v3n,"BoxLayoutProvider",972),lAn(973,1,EJn,Tg),EWn.ue=function(n,t){return oNn(this,_B(n,33),_B(t,33))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},EWn.a=!1,gX(v3n,"BoxLayoutProvider/1",973),lAn(157,1,{157:1},Htn,qx),EWn.Ib=function(){return this.c?qRn(this.c):AMn(this.b)},gX(v3n,"BoxLayoutProvider/Group",157),lAn(311,22,{3:1,35:1,22:1,311:1},VI);var eOt,iOt=_en(v3n,"BoxLayoutProvider/PackingMode",311,Gnt,M3,bB);lAn(974,1,EJn,zu),EWn.ue=function(n,t){return NQ(_B(n,157),_B(t,157))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(v3n,"BoxLayoutProvider/lambda$0$Type",974),lAn(975,1,EJn,Uu),EWn.ue=function(n,t){return iQ(_B(n,157),_B(t,157))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(v3n,"BoxLayoutProvider/lambda$1$Type",975),lAn(976,1,EJn,Xu),EWn.ue=function(n,t){return rQ(_B(n,157),_B(t,157))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(v3n,"BoxLayoutProvider/lambda$2$Type",976),lAn(1365,1,{831:1},Wu),EWn.qg=function(n,t){return CM(),!iL(t,160)||TE(($un(),_B(n,160)),t)},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$0$Type",1365),lAn(1366,1,hVn,Mg),EWn.td=function(n){Qsn(this.a,_B(n,146))},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$1$Type",1366),lAn(1367,1,hVn,qu),EWn.td=function(n){_B(n,94),CM()},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$2$Type",1367),lAn(1371,1,hVn,Sg),EWn.td=function(n){Irn(this.a,_B(n,94))},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$3$Type",1371),lAn(1369,1,NVn,QI),EWn.Mb=function(n){return Xon(this.a,this.b,_B(n,146))},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$4$Type",1369),lAn(1368,1,NVn,JI),EWn.Mb=function(n){return Ox(this.a,this.b,_B(n,831))},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$5$Type",1368),lAn(1370,1,hVn,YI),EWn.td=function(n){Kz(this.a,this.b,_B(n,146))},gX(v3n,"ElkSpacings/AbstractSpacingsBuilder/lambda$6$Type",1370),lAn(935,1,{},Bu),EWn.Kb=function(n){return vA(n)},EWn.Fb=function(n){return this===n},gX(v3n,"ElkUtil/lambda$0$Type",935),lAn(936,1,hVn,ZI),EWn.td=function(n){eOn(this.a,this.b,_B(n,79))},EWn.a=0,EWn.b=0,gX(v3n,"ElkUtil/lambda$1$Type",936),lAn(937,1,hVn,nC),EWn.td=function(n){ky(this.a,this.b,_B(n,202))},EWn.a=0,EWn.b=0,gX(v3n,"ElkUtil/lambda$2$Type",937),lAn(938,1,hVn,tC),EWn.td=function(n){ZA(this.a,this.b,_B(n,137))},EWn.a=0,EWn.b=0,gX(v3n,"ElkUtil/lambda$3$Type",938),lAn(939,1,hVn,Pg),EWn.td=function(n){iq(this.a,_B(n,469))},gX(v3n,"ElkUtil/lambda$4$Type",939),lAn(342,1,{35:1,342:1},Op),EWn.wd=function(n){return gL(this,_B(n,236))},EWn.Fb=function(n){var t;return!!iL(n,342)&&(t=_B(n,342),this.a==t.a)},EWn.Hb=function(){return SY(this.a)},EWn.Ib=function(){return this.a+" (exclusive)"},EWn.a=0,gX(v3n,"ExclusiveBounds/ExclusiveLowerBound",342),lAn(1138,209,$Yn,Hu),EWn.Ze=function(n,t){var e,r,c,a,u,o,s,f,l,b,w,d,g,p,v,m,y,k,j,E,T;for(ITn(t,"Fixed Layout",1),a=_B(JAn(n,(uWn(),gSt)),218),b=0,w=0,v=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));v.e!=v.i.gc();){for(g=_B(mpn(v),33),(T=_B(JAn(g,(zsn(),wIt)),8))&&(TA(g,T.a,T.b),_B(JAn(g,sIt),174).Hc((pdn(),NCt))&&(d=_B(JAn(g,fIt),8)).a>0&&d.b>0&&DUn(g,d.a,d.b,!0,!0)),b=i.Math.max(b,g.i+g.g),w=i.Math.max(w,g.j+g.f),f=new CL((!g.n&&(g.n=new nU(HOt,g,1,7)),g.n));f.e!=f.i.gc();)o=_B(mpn(f),137),(T=_B(JAn(o,wIt),8))&&TA(o,T.a,T.b),b=i.Math.max(b,g.i+o.i+o.g),w=i.Math.max(w,g.j+o.j+o.f);for(k=new CL((!g.c&&(g.c=new nU(GOt,g,9,9)),g.c));k.e!=k.i.gc();)for(y=_B(mpn(k),118),(T=_B(JAn(y,wIt),8))&&TA(y,T.a,T.b),j=g.i+y.i,E=g.j+y.j,b=i.Math.max(b,j+y.g),w=i.Math.max(w,E+y.f),s=new CL((!y.n&&(y.n=new nU(HOt,y,1,7)),y.n));s.e!=s.i.gc();)o=_B(mpn(s),137),(T=_B(JAn(o,wIt),8))&&TA(o,T.a,T.b),b=i.Math.max(b,j+o.i+o.g),w=i.Math.max(w,E+o.j+o.f);for(c=new az(JL(bLn(g).a.Kc(),new h));bAn(c);)l=RUn(e=_B(G5(c),79)),b=i.Math.max(b,l.a),w=i.Math.max(w,l.b);for(r=new az(JL(lLn(g).a.Kc(),new h));bAn(r);)QY(MMn(e=_B(G5(r),79)))!=n&&(l=RUn(e),b=i.Math.max(b,l.a),w=i.Math.max(w,l.b))}if(a==(Ebn(),WPt))for(p=new CL((!n.a&&(n.a=new nU(qOt,n,10,11)),n.a));p.e!=p.i.gc();)for(r=new az(JL(bLn(g=_B(mpn(p),33)).a.Kc(),new h));bAn(r);)0==(u=eFn(e=_B(G5(r),79))).b?Vpn(e,ISt,null):Vpn(e,ISt,u);By(jD(JAn(n,(zsn(),hIt))))||DUn(n,b+(m=_B(JAn(n,lIt),116)).b+m.c,w+m.d+m.a,!0,!0),FSn(t)},gX(v3n,"FixedLayoutProvider",1138),lAn(373,134,{3:1,414:1,373:1,94:1,134:1},Ju,enn),EWn.Jf=function(n){var t,e,i,r,c,a,u;if(n)try{for(a=mKn(n,";,;"),r=0,c=(i=a).length;r>16&WVn|n^(e&WVn)<<16},EWn.Kc=function(){return new Ig(this)},EWn.Ib=function(){return null==this.a&&null==this.b?"pair(null,null)":null==this.a?"pair(null,"+_bn(this.b)+")":null==this.b?"pair("+_bn(this.a)+",null)":"pair("+_bn(this.a)+","+_bn(this.b)+")"},gX(v3n,"Pair",46),lAn(983,1,WWn,Ig),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return!this.c&&(!this.b&&null!=this.a.a||null!=this.a.b)},EWn.Pb=function(){if(!this.c&&!this.b&&null!=this.a.a)return this.b=!0,this.a.a;if(!this.c&&null!=this.a.b)return this.c=!0,this.a.b;throw Fp(new vv)},EWn.Qb=function(){throw this.c&&null!=this.a.b?this.a.b=null:this.b&&null!=this.a.a&&(this.a.a=null),Fp(new bv)},EWn.b=!1,EWn.c=!1,gX(v3n,"Pair/1",983),lAn(448,1,{448:1},XV),EWn.Fb=function(n){return iV(this.a,_B(n,448).a)&&iV(this.c,_B(n,448).c)&&iV(this.d,_B(n,448).d)&&iV(this.b,_B(n,448).b)},EWn.Hb=function(){return shn(Mun(Hk(Cnt,1),FWn,1,5,[this.a,this.c,this.d,this.b]))},EWn.Ib=function(){return"("+this.a+KWn+this.c+KWn+this.d+KWn+this.b+")"},gX(v3n,"Quadruple",448),lAn(1126,209,$Yn,no),EWn.Ze=function(n,t){var e;ITn(t,"Random Layout",1),0!=(!n.a&&(n.a=new nU(qOt,n,10,11)),n.a).i?(tUn(n,(e=_B(JAn(n,(gdn(),$Ct)),19))&&0!=e.a?new S4(e.a):new ubn,qy(ED(JAn(n,CCt))),qy(ED(JAn(n,LCt))),_B(JAn(n,OCt),116)),FSn(t)):FSn(t)},gX(v3n,"RandomLayoutProvider",1126),lAn(553,1,{}),EWn.qf=function(){return new LI(this.f.i,this.f.j)},EWn.We=function(n){return kJ(n,(uWn(),rPt))?JAn(this.f,fOt):JAn(this.f,n)},EWn.rf=function(){return new LI(this.f.g,this.f.f)},EWn.sf=function(){return this.g},EWn.Xe=function(n){return M8(this.f,n)},EWn.tf=function(n){Men(this.f,n.a),Sen(this.f,n.b)},EWn.uf=function(n){Ten(this.f,n.a),Een(this.f,n.b)},EWn.vf=function(n){this.g=n},EWn.g=0,gX(F5n,"ElkGraphAdapters/AbstractElkGraphElementAdapter",553),lAn(554,1,{839:1},Cg),EWn.wf=function(){var n,t;if(!this.b)for(this.b=S2(pV(this.a).i),t=new CL(pV(this.a));t.e!=t.i.gc();)n=_B(mpn(t),137),UB(this.b,new xy(n));return this.b},EWn.b=null,gX(F5n,"ElkGraphAdapters/ElkEdgeAdapter",554),lAn(301,553,{},Ny),EWn.xf=function(){return nyn(this)},EWn.a=null,gX(F5n,"ElkGraphAdapters/ElkGraphAdapter",301),lAn(630,553,{181:1},xy),gX(F5n,"ElkGraphAdapters/ElkLabelAdapter",630),lAn(629,553,{680:1},QN),EWn.wf=function(){return Ymn(this)},EWn.Af=function(){var n;return!(n=_B(JAn(this.f,(uWn(),OSt)),142))&&(n=new hm),n},EWn.Cf=function(){return Zmn(this)},EWn.Ef=function(n){var t;t=new C_(n),Vpn(this.f,(uWn(),OSt),t)},EWn.Ff=function(n){Vpn(this.f,(uWn(),zSt),new I_(n))},EWn.yf=function(){return this.d},EWn.zf=function(){var n,t;if(!this.a)for(this.a=new $p,t=new az(JL(lLn(_B(this.f,33)).a.Kc(),new h));bAn(t);)n=_B(G5(t),79),UB(this.a,new Cg(n));return this.a},EWn.Bf=function(){var n,t;if(!this.c)for(this.c=new $p,t=new az(JL(bLn(_B(this.f,33)).a.Kc(),new h));bAn(t);)n=_B(G5(t),79),UB(this.c,new Cg(n));return this.c},EWn.Df=function(){return 0!=VQ(_B(this.f,33)).i||By(jD(_B(this.f,33).We((uWn(),TSt))))},EWn.Gf=function(){R7(this,(HM(),hOt))},EWn.a=null,EWn.b=null,EWn.c=null,EWn.d=null,EWn.e=null,gX(F5n,"ElkGraphAdapters/ElkNodeAdapter",629),lAn(1266,553,{838:1},ap),EWn.wf=function(){return myn(this)},EWn.zf=function(){var n,t;if(!this.a)for(this.a=ux(_B(this.f,118).xg().i),t=new CL(_B(this.f,118).xg());t.e!=t.i.gc();)n=_B(mpn(t),79),UB(this.a,new Cg(n));return this.a},EWn.Bf=function(){var n,t;if(!this.c)for(this.c=ux(_B(this.f,118).yg().i),t=new CL(_B(this.f,118).yg());t.e!=t.i.gc();)n=_B(mpn(t),79),UB(this.c,new Cg(n));return this.c},EWn.Hf=function(){return _B(_B(this.f,118).We((uWn(),lPt)),61)},EWn.If=function(){var n,t,e,i,r,c,a;for(i=UY(_B(this.f,118)),e=new CL(_B(this.f,118).yg());e.e!=e.i.gc();)for(a=new CL((!(n=_B(mpn(e),79)).c&&(n.c=new oK(xOt,n,5,8)),n.c));a.e!=a.i.gc();){if(Stn(MTn(c=_B(mpn(a),82)),i))return!0;if(MTn(c)==i&&By(jD(JAn(n,(uWn(),MSt)))))return!0}for(t=new CL(_B(this.f,118).xg());t.e!=t.i.gc();)for(r=new CL((!(n=_B(mpn(t),79)).b&&(n.b=new oK(xOt,n,4,7)),n.b));r.e!=r.i.gc();)if(Stn(MTn(_B(mpn(r),82)),i))return!0;return!1},EWn.a=null,EWn.b=null,EWn.c=null,gX(F5n,"ElkGraphAdapters/ElkPortAdapter",1266),lAn(1267,1,EJn,to),EWn.ue=function(n,t){return HRn(_B(n,118),_B(t,118))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(F5n,"ElkGraphAdapters/PortComparator",1267);var bOt,wOt,dOt,gOt,pOt,vOt,mOt,yOt,kOt,jOt,EOt,TOt,MOt,SOt,POt,IOt,COt,OOt=fq(B5n,"EObject"),AOt=fq(H5n,q5n),$Ot=fq(H5n,G5n),LOt=fq(H5n,z5n),NOt=fq(H5n,"ElkShape"),xOt=fq(H5n,U5n),DOt=fq(H5n,X5n),ROt=fq(H5n,W5n),KOt=fq(B5n,V5n),_Ot=fq(B5n,"EFactory"),FOt=fq(B5n,Q5n),BOt=fq(B5n,"EPackage"),HOt=fq(H5n,J5n),qOt=fq(H5n,Y5n),GOt=fq(H5n,Z5n);lAn(90,1,n6n),EWn.Jg=function(){return this.Kg(),null},EWn.Kg=function(){return null},EWn.Lg=function(){return this.Kg(),!1},EWn.Mg=function(){return!1},EWn.Ng=function(n){fan(this,n)},gX(t6n,"BasicNotifierImpl",90),lAn(97,90,s6n),EWn.nh=function(){return pA(this)},EWn.Og=function(n,t){return n},EWn.Pg=function(){throw Fp(new dv)},EWn.Qg=function(n){var t;return t=Svn(_B(ttn(this.Tg(),this.Vg()),18)),this.eh().ih(this,t.n,t.f,n)},EWn.Rg=function(n,t){throw Fp(new dv)},EWn.Sg=function(n,t,e){return j_n(this,n,t,e)},EWn.Tg=function(){var n;return this.Pg()&&(n=this.Pg().ck())?n:this.zh()},EWn.Ug=function(){return iAn(this)},EWn.Vg=function(){throw Fp(new dv)},EWn.Wg=function(){var n,t;return!(t=this.ph().dk())&&this.Pg().ik((WM(),t=null==(n=hY(BFn(this.Tg())))?A$t:new WN(this,n))),t},EWn.Xg=function(n,t){return n},EWn.Yg=function(n){return n.Gj()?n.aj():Cwn(this.Tg(),n)},EWn.Zg=function(){var n;return(n=this.Pg())?n.fk():null},EWn.$g=function(){return this.Pg()?this.Pg().ck():null},EWn._g=function(n,t,e){return Jpn(this,n,t,e)},EWn.ah=function(n){return T9(this,n)},EWn.bh=function(n,t){return X5(this,n,t)},EWn.dh=function(){var n;return!!(n=this.Pg())&&n.gk()},EWn.eh=function(){throw Fp(new dv)},EWn.fh=function(){return Vdn(this)},EWn.gh=function(n,t,e,i){return $pn(this,n,t,i)},EWn.hh=function(n,t,e){return _B(ttn(this.Tg(),t),66).Nj().Qj(this,this.yh(),t-this.Ah(),n,e)},EWn.ih=function(n,t,e,i){return aY(this,n,t,i)},EWn.jh=function(n,t,e){return _B(ttn(this.Tg(),t),66).Nj().Rj(this,this.yh(),t-this.Ah(),n,e)},EWn.kh=function(){return!!this.Pg()&&!!this.Pg().ek()},EWn.lh=function(n){return gpn(this,n)},EWn.mh=function(n){return JY(this,n)},EWn.oh=function(n){return Rqn(this,n)},EWn.ph=function(){throw Fp(new dv)},EWn.qh=function(){return this.Pg()?this.Pg().ek():null},EWn.rh=function(){return Vdn(this)},EWn.sh=function(n,t){vIn(this,n,t)},EWn.th=function(n){this.ph().hk(n)},EWn.uh=function(n){this.ph().kk(n)},EWn.vh=function(n){this.ph().jk(n)},EWn.wh=function(n,t){var e,i,r,c;return(c=this.Zg())&&n&&(t=Rpn(c.Vk(),this,t),c.Zk(this)),(i=this.eh())&&(0!=(wKn(this,this.eh(),this.Vg()).Bb&_Qn)?(r=i.fh())&&(n?!c&&r.Zk(this):r.Yk(this)):(t=(e=this.Vg())>=0?this.Qg(t):this.eh().ih(this,-1-e,null,t),t=this.Sg(null,-1,t))),this.uh(n),t},EWn.xh=function(n){var t,e,i,r,c,a,u;if((c=Cwn(e=this.Tg(),n))>=(t=this.Ah()))return _B(n,66).Nj().Uj(this,this.yh(),c-t);if(c<=-1){if(!(a=Kqn((PPn(),Q$t),e,n)))throw Fp(new Ry(e6n+n.ne()+c6n));if(JM(),_B(a,66).Oj()||(a=J1(_7(Q$t,a))),r=_B((i=this.Yg(a))>=0?this._g(i,!0,!0):iOn(this,a,!0),153),(u=a.Zj())>1||-1==u)return _B(_B(r,215).hl(n,!1),76)}else if(n.$j())return _B((i=this.Yg(n))>=0?this._g(i,!1,!0):iOn(this,n,!1),76);return new PC(this,n)},EWn.yh=function(){return W7(this)},EWn.zh=function(){return(WX(),YAt).S},EWn.Ah=function(){return fX(this.zh())},EWn.Bh=function(n){pPn(this,n)},EWn.Ib=function(){return M$n(this)},gX(h6n,"BasicEObjectImpl",97),lAn(114,97,{105:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1}),EWn.Ch=function(n){return V7(this)[n]},EWn.Dh=function(n,t){OX(V7(this),n,t)},EWn.Eh=function(n){OX(V7(this),n,null)},EWn.Jg=function(){return _B(van(this,4),126)},EWn.Kg=function(){throw Fp(new dv)},EWn.Lg=function(){return 0!=(4&this.Db)},EWn.Pg=function(){throw Fp(new dv)},EWn.Fh=function(n){ogn(this,2,n)},EWn.Rg=function(n,t){this.Db=t<<16|255&this.Db,this.Fh(n)},EWn.Tg=function(){return yJ(this)},EWn.Vg=function(){return this.Db>>16},EWn.Wg=function(){var n;return WM(),null==(n=hY(BFn(_B(van(this,16),26)||this.zh())))?A$t:new WN(this,n)},EWn.Mg=function(){return 0==(1&this.Db)},EWn.Zg=function(){return _B(van(this,128),1935)},EWn.$g=function(){return _B(van(this,16),26)},EWn.dh=function(){return 0!=(32&this.Db)},EWn.eh=function(){return _B(van(this,2),49)},EWn.kh=function(){return 0!=(64&this.Db)},EWn.ph=function(){throw Fp(new dv)},EWn.qh=function(){return _B(van(this,64),281)},EWn.th=function(n){ogn(this,16,n)},EWn.uh=function(n){ogn(this,128,n)},EWn.vh=function(n){ogn(this,64,n)},EWn.yh=function(){return sgn(this)},EWn.Db=0,gX(h6n,"MinimalEObjectImpl",114),lAn(115,114,{105:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),EWn.Fh=function(n){this.Cb=n},EWn.eh=function(){return this.Cb},gX(h6n,"MinimalEObjectImpl/Container",115),lAn(1985,115,{105:1,413:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),EWn._g=function(n,t,e){return kyn(this,n,t,e)},EWn.jh=function(n,t,e){return nSn(this,n,t,e)},EWn.lh=function(n){return p0(this,n)},EWn.sh=function(n,t){esn(this,n,t)},EWn.zh=function(){return SXn(),MOt},EWn.Bh=function(n){qun(this,n)},EWn.Ve=function(){return hpn(this)},EWn.We=function(n){return JAn(this,n)},EWn.Xe=function(n){return M8(this,n)},EWn.Ye=function(n,t){return Vpn(this,n,t)},gX(f6n,"EMapPropertyHolderImpl",1985),lAn(567,115,{105:1,469:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},ro),EWn._g=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return Jpn(this,n,t,e)},EWn.lh=function(n){switch(n){case 0:return 0!=this.a;case 1:return 0!=this.b}return gpn(this,n)},EWn.sh=function(n,t){switch(n){case 0:return void yen(this,Hy(ED(t)));case 1:return void ken(this,Hy(ED(t)))}vIn(this,n,t)},EWn.zh=function(){return SXn(),dOt},EWn.Bh=function(n){switch(n){case 0:return void yen(this,0);case 1:return void ken(this,0)}pPn(this,n)},EWn.Ib=function(){var n;return 0!=(64&this.Db)?M$n(this):((n=new sN(M$n(this))).a+=" (x: ",gE(n,this.a),n.a+=", y: ",gE(n,this.b),n.a+=")",n.a)},EWn.a=0,EWn.b=0,gX(f6n,"ElkBendPointImpl",567),lAn(723,1985,{105:1,413:1,160:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),EWn._g=function(n,t,e){return Rfn(this,n,t,e)},EWn.hh=function(n,t,e){return KTn(this,n,t,e)},EWn.jh=function(n,t,e){return eun(this,n,t,e)},EWn.lh=function(n){return kan(this,n)},EWn.sh=function(n,t){Hjn(this,n,t)},EWn.zh=function(){return SXn(),mOt},EWn.Bh=function(n){afn(this,n)},EWn.zg=function(){return this.k},EWn.Ag=function(){return pV(this)},EWn.Ib=function(){return Vln(this)},EWn.k=null,gX(f6n,"ElkGraphElementImpl",723),lAn(724,723,{105:1,413:1,160:1,470:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),EWn._g=function(n,t,e){return xbn(this,n,t,e)},EWn.lh=function(n){return swn(this,n)},EWn.sh=function(n,t){qjn(this,n,t)},EWn.zh=function(){return SXn(),TOt},EWn.Bh=function(n){Nwn(this,n)},EWn.Bg=function(){return this.f},EWn.Cg=function(){return this.g},EWn.Dg=function(){return this.i},EWn.Eg=function(){return this.j},EWn.Fg=function(n,t){EA(this,n,t)},EWn.Gg=function(n,t){TA(this,n,t)},EWn.Hg=function(n){Men(this,n)},EWn.Ig=function(n){Sen(this,n)},EWn.Ib=function(){return pSn(this)},EWn.f=0,EWn.g=0,EWn.i=0,EWn.j=0,gX(f6n,"ElkShapeImpl",724),lAn(725,724,{105:1,413:1,82:1,160:1,470:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1}),EWn._g=function(n,t,e){return Fvn(this,n,t,e)},EWn.hh=function(n,t,e){return bjn(this,n,t,e)},EWn.jh=function(n,t,e){return wjn(this,n,t,e)},EWn.lh=function(n){return Hon(this,n)},EWn.sh=function(n,t){AAn(this,n,t)},EWn.zh=function(){return SXn(),gOt},EWn.Bh=function(n){Lpn(this,n)},EWn.xg=function(){return!this.d&&(this.d=new oK(DOt,this,8,5)),this.d},EWn.yg=function(){return!this.e&&(this.e=new oK(DOt,this,7,4)),this.e},gX(f6n,"ElkConnectableShapeImpl",725),lAn(352,723,{105:1,413:1,79:1,160:1,352:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},io),EWn.Qg=function(n){return Ekn(this,n)},EWn._g=function(n,t,e){switch(n){case 3:return zY(this);case 4:return!this.b&&(this.b=new oK(xOt,this,4,7)),this.b;case 5:return!this.c&&(this.c=new oK(xOt,this,5,8)),this.c;case 6:return!this.a&&(this.a=new nU(ROt,this,6,6)),this.a;case 7:return oN(),!this.b&&(this.b=new oK(xOt,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new oK(xOt,this,5,8)),this.c.i<=1));case 8:return oN(),!!YOn(this);case 9:return oN(),!!WCn(this);case 10:return oN(),!this.b&&(this.b=new oK(xOt,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new oK(xOt,this,5,8)),0!=this.c.i)}return Rfn(this,n,t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?Ekn(this,e):this.Cb.ih(this,-1-i,null,e)),XD(this,_B(n,33),e);case 4:return!this.b&&(this.b=new oK(xOt,this,4,7)),Vwn(this.b,n,e);case 5:return!this.c&&(this.c=new oK(xOt,this,5,8)),Vwn(this.c,n,e);case 6:return!this.a&&(this.a=new nU(ROt,this,6,6)),Vwn(this.a,n,e)}return KTn(this,n,t,e)},EWn.jh=function(n,t,e){switch(t){case 3:return XD(this,null,e);case 4:return!this.b&&(this.b=new oK(xOt,this,4,7)),Rpn(this.b,n,e);case 5:return!this.c&&(this.c=new oK(xOt,this,5,8)),Rpn(this.c,n,e);case 6:return!this.a&&(this.a=new nU(ROt,this,6,6)),Rpn(this.a,n,e)}return eun(this,n,t,e)},EWn.lh=function(n){switch(n){case 3:return!!zY(this);case 4:return!!this.b&&0!=this.b.i;case 5:return!!this.c&&0!=this.c.i;case 6:return!!this.a&&0!=this.a.i;case 7:return!this.b&&(this.b=new oK(xOt,this,4,7)),!(this.b.i<=1&&(!this.c&&(this.c=new oK(xOt,this,5,8)),this.c.i<=1));case 8:return YOn(this);case 9:return WCn(this);case 10:return!this.b&&(this.b=new oK(xOt,this,4,7)),0!=this.b.i&&(!this.c&&(this.c=new oK(xOt,this,5,8)),0!=this.c.i)}return kan(this,n)},EWn.sh=function(n,t){switch(n){case 3:return void FLn(this,_B(t,33));case 4:return!this.b&&(this.b=new oK(xOt,this,4,7)),uqn(this.b),!this.b&&(this.b=new oK(xOt,this,4,7)),void dX(this.b,_B(t,14));case 5:return!this.c&&(this.c=new oK(xOt,this,5,8)),uqn(this.c),!this.c&&(this.c=new oK(xOt,this,5,8)),void dX(this.c,_B(t,14));case 6:return!this.a&&(this.a=new nU(ROt,this,6,6)),uqn(this.a),!this.a&&(this.a=new nU(ROt,this,6,6)),void dX(this.a,_B(t,14))}Hjn(this,n,t)},EWn.zh=function(){return SXn(),pOt},EWn.Bh=function(n){switch(n){case 3:return void FLn(this,null);case 4:return!this.b&&(this.b=new oK(xOt,this,4,7)),void uqn(this.b);case 5:return!this.c&&(this.c=new oK(xOt,this,5,8)),void uqn(this.c);case 6:return!this.a&&(this.a=new nU(ROt,this,6,6)),void uqn(this.a)}afn(this,n)},EWn.Ib=function(){return hHn(this)},gX(f6n,"ElkEdgeImpl",352),lAn(439,1985,{105:1,413:1,202:1,439:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},co),EWn.Qg=function(n){return ukn(this,n)},EWn._g=function(n,t,e){switch(n){case 1:return this.j;case 2:return this.k;case 3:return this.b;case 4:return this.c;case 5:return!this.a&&(this.a=new OL($Ot,this,5)),this.a;case 6:return XY(this);case 7:return t?Mvn(this):this.i;case 8:return t?Tvn(this):this.f;case 9:return!this.g&&(this.g=new oK(ROt,this,9,10)),this.g;case 10:return!this.e&&(this.e=new oK(ROt,this,10,9)),this.e;case 11:return this.d}return kyn(this,n,t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?ukn(this,e):this.Cb.ih(this,-1-i,null,e)),WD(this,_B(n,79),e);case 9:return!this.g&&(this.g=new oK(ROt,this,9,10)),Vwn(this.g,n,e);case 10:return!this.e&&(this.e=new oK(ROt,this,10,9)),Vwn(this.e,n,e)}return _B(ttn(_B(van(this,16),26)||(SXn(),vOt),t),66).Nj().Qj(this,sgn(this),t-fX((SXn(),vOt)),n,e)},EWn.jh=function(n,t,e){switch(t){case 5:return!this.a&&(this.a=new OL($Ot,this,5)),Rpn(this.a,n,e);case 6:return WD(this,null,e);case 9:return!this.g&&(this.g=new oK(ROt,this,9,10)),Rpn(this.g,n,e);case 10:return!this.e&&(this.e=new oK(ROt,this,10,9)),Rpn(this.e,n,e)}return nSn(this,n,t,e)},EWn.lh=function(n){switch(n){case 1:return 0!=this.j;case 2:return 0!=this.k;case 3:return 0!=this.b;case 4:return 0!=this.c;case 5:return!!this.a&&0!=this.a.i;case 6:return!!XY(this);case 7:return!!this.i;case 8:return!!this.f;case 9:return!!this.g&&0!=this.g.i;case 10:return!!this.e&&0!=this.e.i;case 11:return null!=this.d}return p0(this,n)},EWn.sh=function(n,t){switch(n){case 1:return void Pen(this,Hy(ED(t)));case 2:return void Cen(this,Hy(ED(t)));case 3:return void jen(this,Hy(ED(t)));case 4:return void Ien(this,Hy(ED(t)));case 5:return!this.a&&(this.a=new OL($Ot,this,5)),uqn(this.a),!this.a&&(this.a=new OL($Ot,this,5)),void dX(this.a,_B(t,14));case 6:return void KLn(this,_B(t,79));case 7:return void $in(this,_B(t,82));case 8:return void Ain(this,_B(t,82));case 9:return!this.g&&(this.g=new oK(ROt,this,9,10)),uqn(this.g),!this.g&&(this.g=new oK(ROt,this,9,10)),void dX(this.g,_B(t,14));case 10:return!this.e&&(this.e=new oK(ROt,this,10,9)),uqn(this.e),!this.e&&(this.e=new oK(ROt,this,10,9)),void dX(this.e,_B(t,14));case 11:return void irn(this,TD(t))}esn(this,n,t)},EWn.zh=function(){return SXn(),vOt},EWn.Bh=function(n){switch(n){case 1:return void Pen(this,0);case 2:return void Cen(this,0);case 3:return void jen(this,0);case 4:return void Ien(this,0);case 5:return!this.a&&(this.a=new OL($Ot,this,5)),void uqn(this.a);case 6:return void KLn(this,null);case 7:return void $in(this,null);case 8:return void Ain(this,null);case 9:return!this.g&&(this.g=new oK(ROt,this,9,10)),void uqn(this.g);case 10:return!this.e&&(this.e=new oK(ROt,this,10,9)),void uqn(this.e);case 11:return void irn(this,null)}qun(this,n)},EWn.Ib=function(){return xOn(this)},EWn.b=0,EWn.c=0,EWn.d=null,EWn.j=0,EWn.k=0,gX(f6n,"ElkEdgeSectionImpl",439),lAn(150,115,{105:1,92:1,90:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1}),EWn._g=function(n,t,e){return 0==n?(!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab):G9(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t,e)},EWn.hh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e)):_B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Qj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.jh=function(n,t,e){return 0==t?(!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e)):_B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Rj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.lh=function(n){return 0==n?!!this.Ab&&0!=this.Ab.i:I3(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.oh=function(n){return oUn(this,n)},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14))}Abn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t)},EWn.uh=function(n){ogn(this,128,n)},EWn.zh=function(){return wWn(),h$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab)}Bfn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.Gh=function(){this.Bb|=1},EWn.Hh=function(n){return $_n(this,n)},EWn.Bb=0,gX(h6n,"EModelElementImpl",150),lAn(704,150,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1},xf),EWn.Ih=function(n,t){return BGn(this,n,t)},EWn.Jh=function(n){var t,e,i,r;if(this.a!=Gtn(n)||0!=(256&n.Bb))throw Fp(new Ry(p6n+n.zb+w6n));for(e=mJ(n);0!=r4(e.a).i;){if(tyn(t=_B(nGn(e,0,iL(r=_B(Utn(r4(e.a),0),87).c,88)?_B(r,26):(wWn(),l$t)),26)))return _B(i=Gtn(t).Nh().Jh(t),49).th(n),i;e=mJ(t)}return"java.util.Map$Entry"==(null!=n.D?n.D:n.B)?new sq(n):new yH(n)},EWn.Kh=function(n,t){return LXn(this,n,t)},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.a}return G9(this,n-fX((wWn(),u$t)),ttn(_B(van(this,16),26)||u$t,n),t,e)},EWn.hh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 1:return this.a&&(e=_B(this.a,49).ih(this,4,BOt,e)),Qhn(this,_B(n,235),e)}return _B(ttn(_B(van(this,16),26)||(wWn(),u$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),u$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 1:return Qhn(this,null,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),u$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),u$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return!!this.a}return I3(this,n-fX((wWn(),u$t)),ttn(_B(van(this,16),26)||u$t,n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void LMn(this,_B(t,235))}Abn(this,n-fX((wWn(),u$t)),ttn(_B(van(this,16),26)||u$t,n),t)},EWn.zh=function(){return wWn(),u$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void LMn(this,null)}Bfn(this,n-fX((wWn(),u$t)),ttn(_B(van(this,16),26)||u$t,n))},gX(h6n,"EFactoryImpl",704),lAn(m6n,704,{105:1,2014:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1},ao),EWn.Ih=function(n,t){switch(n.yj()){case 12:return _B(t,146).tg();case 13:return _bn(t);default:throw Fp(new Ry(b6n+n.ne()+w6n))}},EWn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=Gtn(n))?cvn(t.Mh(),n):-1),n.G){case 4:return new uo;case 6:return new ym;case 7:return new km;case 8:return new io;case 9:return new ro;case 10:return new co;case 11:return new so;default:throw Fp(new Ry(p6n+n.zb+w6n))}},EWn.Kh=function(n,t){switch(n.yj()){case 13:case 12:return null;default:throw Fp(new Ry(b6n+n.ne()+w6n))}},gX(f6n,"ElkGraphFactoryImpl",m6n),lAn(438,150,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1}),EWn.Wg=function(){var n;return null==(n=hY(BFn(_B(van(this,16),26)||this.zh())))?(WM(),WM(),A$t):new Ux(this,n)},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.ne()}return G9(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb}return I3(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void this.Lh(TD(t))}Abn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t)},EWn.zh=function(){return wWn(),f$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void this.Lh(null)}Bfn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.ne=function(){return this.zb},EWn.Lh=function(n){$rn(this,n)},EWn.Ib=function(){return mfn(this)},EWn.zb=null,gX(h6n,"ENamedElementImpl",438),lAn(179,438,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1},gJ),EWn.Qg=function(n){return lkn(this,n)},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return this.yb;case 3:return this.xb;case 4:return this.sb;case 5:return!this.rb&&(this.rb=new Qz(this,_At,this)),this.rb;case 6:return!this.vb&&(this.vb=new nK(BOt,this,6,7)),this.vb;case 7:return t?this.Db>>16==7?_B(this.Cb,235):null:WY(this)}return G9(this,n-fX((wWn(),d$t)),ttn(_B(van(this,16),26)||d$t,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 4:return this.sb&&(e=_B(this.sb,49).ih(this,1,_Ot,e)),yfn(this,_B(n,471),e);case 5:return!this.rb&&(this.rb=new Qz(this,_At,this)),Vwn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new nK(BOt,this,6,7)),Vwn(this.vb,n,e);case 7:return this.Cb&&(e=(i=this.Db>>16)>=0?lkn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,7,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),d$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),d$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 4:return yfn(this,null,e);case 5:return!this.rb&&(this.rb=new Qz(this,_At,this)),Rpn(this.rb,n,e);case 6:return!this.vb&&(this.vb=new nK(BOt,this,6,7)),Rpn(this.vb,n,e);case 7:return j_n(this,null,7,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),d$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),d$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.yb;case 3:return null!=this.xb;case 4:return!!this.sb;case 5:return!!this.rb&&0!=this.rb.i;case 6:return!!this.vb&&0!=this.vb.i;case 7:return!!WY(this)}return I3(this,n-fX((wWn(),d$t)),ttn(_B(van(this,16),26)||d$t,n))},EWn.oh=function(n){return ANn(this,n)||oUn(this,n)},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void $rn(this,TD(t));case 2:return void Nrn(this,TD(t));case 3:return void Lrn(this,TD(t));case 4:return void tSn(this,_B(t,471));case 5:return!this.rb&&(this.rb=new Qz(this,_At,this)),uqn(this.rb),!this.rb&&(this.rb=new Qz(this,_At,this)),void dX(this.rb,_B(t,14));case 6:return!this.vb&&(this.vb=new nK(BOt,this,6,7)),uqn(this.vb),!this.vb&&(this.vb=new nK(BOt,this,6,7)),void dX(this.vb,_B(t,14))}Abn(this,n-fX((wWn(),d$t)),ttn(_B(van(this,16),26)||d$t,n),t)},EWn.vh=function(n){var t,e;if(n&&this.rb)for(e=new CL(this.rb);e.e!=e.i.gc();)iL(t=mpn(e),351)&&(_B(t,351).w=null);ogn(this,64,n)},EWn.zh=function(){return wWn(),d$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void $rn(this,null);case 2:return void Nrn(this,null);case 3:return void Lrn(this,null);case 4:return void tSn(this,null);case 5:return!this.rb&&(this.rb=new Qz(this,_At,this)),void uqn(this.rb);case 6:return!this.vb&&(this.vb=new nK(BOt,this,6,7)),void uqn(this.vb)}Bfn(this,n-fX((wWn(),d$t)),ttn(_B(van(this,16),26)||d$t,n))},EWn.Gh=function(){jyn(this)},EWn.Mh=function(){return!this.rb&&(this.rb=new Qz(this,_At,this)),this.rb},EWn.Nh=function(){return this.sb},EWn.Oh=function(){return this.ub},EWn.Ph=function(){return this.xb},EWn.Qh=function(){return this.yb},EWn.Rh=function(n){this.ub=n},EWn.Ib=function(){var n;return 0!=(64&this.Db)?mfn(this):((n=new sN(mfn(this))).a+=" (nsURI: ",iO(n,this.yb),n.a+=", nsPrefix: ",iO(n,this.xb),n.a+=")",n.a)},EWn.xb=null,EWn.yb=null,gX(h6n,"EPackageImpl",179),lAn(555,179,{105:1,2016:1,555:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1},uAn),EWn.q=!1,EWn.r=!1;var zOt=!1;gX(f6n,"ElkGraphPackageImpl",555),lAn(354,724,{105:1,413:1,160:1,137:1,470:1,354:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},uo),EWn.Qg=function(n){return okn(this,n)},EWn._g=function(n,t,e){switch(n){case 7:return VY(this);case 8:return this.a}return xbn(this,n,t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 7:return this.Cb&&(e=(i=this.Db>>16)>=0?okn(this,e):this.Cb.ih(this,-1-i,null,e)),XG(this,_B(n,160),e)}return KTn(this,n,t,e)},EWn.jh=function(n,t,e){return 7==t?XG(this,null,e):eun(this,n,t,e)},EWn.lh=function(n){switch(n){case 7:return!!VY(this);case 8:return!pK("",this.a)}return swn(this,n)},EWn.sh=function(n,t){switch(n){case 7:return void PNn(this,_B(t,160));case 8:return void Lin(this,TD(t))}qjn(this,n,t)},EWn.zh=function(){return SXn(),yOt},EWn.Bh=function(n){switch(n){case 7:return void PNn(this,null);case 8:return void Lin(this,"")}Nwn(this,n)},EWn.Ib=function(){return iPn(this)},EWn.a="",gX(f6n,"ElkLabelImpl",354),lAn(239,725,{105:1,413:1,82:1,160:1,33:1,470:1,239:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},ym),EWn.Qg=function(n){return Tkn(this,n)},EWn._g=function(n,t,e){switch(n){case 9:return!this.c&&(this.c=new nU(GOt,this,9,9)),this.c;case 10:return!this.a&&(this.a=new nU(qOt,this,10,11)),this.a;case 11:return QY(this);case 12:return!this.b&&(this.b=new nU(DOt,this,12,3)),this.b;case 13:return oN(),!this.a&&(this.a=new nU(qOt,this,10,11)),this.a.i>0}return Fvn(this,n,t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 9:return!this.c&&(this.c=new nU(GOt,this,9,9)),Vwn(this.c,n,e);case 10:return!this.a&&(this.a=new nU(qOt,this,10,11)),Vwn(this.a,n,e);case 11:return this.Cb&&(e=(i=this.Db>>16)>=0?Tkn(this,e):this.Cb.ih(this,-1-i,null,e)),qR(this,_B(n,33),e);case 12:return!this.b&&(this.b=new nU(DOt,this,12,3)),Vwn(this.b,n,e)}return bjn(this,n,t,e)},EWn.jh=function(n,t,e){switch(t){case 9:return!this.c&&(this.c=new nU(GOt,this,9,9)),Rpn(this.c,n,e);case 10:return!this.a&&(this.a=new nU(qOt,this,10,11)),Rpn(this.a,n,e);case 11:return qR(this,null,e);case 12:return!this.b&&(this.b=new nU(DOt,this,12,3)),Rpn(this.b,n,e)}return wjn(this,n,t,e)},EWn.lh=function(n){switch(n){case 9:return!!this.c&&0!=this.c.i;case 10:return!!this.a&&0!=this.a.i;case 11:return!!QY(this);case 12:return!!this.b&&0!=this.b.i;case 13:return!this.a&&(this.a=new nU(qOt,this,10,11)),this.a.i>0}return Hon(this,n)},EWn.sh=function(n,t){switch(n){case 9:return!this.c&&(this.c=new nU(GOt,this,9,9)),uqn(this.c),!this.c&&(this.c=new nU(GOt,this,9,9)),void dX(this.c,_B(t,14));case 10:return!this.a&&(this.a=new nU(qOt,this,10,11)),uqn(this.a),!this.a&&(this.a=new nU(qOt,this,10,11)),void dX(this.a,_B(t,14));case 11:return void YLn(this,_B(t,33));case 12:return!this.b&&(this.b=new nU(DOt,this,12,3)),uqn(this.b),!this.b&&(this.b=new nU(DOt,this,12,3)),void dX(this.b,_B(t,14))}AAn(this,n,t)},EWn.zh=function(){return SXn(),kOt},EWn.Bh=function(n){switch(n){case 9:return!this.c&&(this.c=new nU(GOt,this,9,9)),void uqn(this.c);case 10:return!this.a&&(this.a=new nU(qOt,this,10,11)),void uqn(this.a);case 11:return void YLn(this,null);case 12:return!this.b&&(this.b=new nU(DOt,this,12,3)),void uqn(this.b)}Lpn(this,n)},EWn.Ib=function(){return qRn(this)},gX(f6n,"ElkNodeImpl",239),lAn(186,725,{105:1,413:1,82:1,160:1,118:1,470:1,186:1,94:1,92:1,90:1,56:1,108:1,49:1,97:1,114:1,115:1},km),EWn.Qg=function(n){return skn(this,n)},EWn._g=function(n,t,e){return 9==n?UY(this):Fvn(this,n,t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 9:return this.Cb&&(e=(i=this.Db>>16)>=0?skn(this,e):this.Cb.ih(this,-1-i,null,e)),VD(this,_B(n,33),e)}return bjn(this,n,t,e)},EWn.jh=function(n,t,e){return 9==t?VD(this,null,e):wjn(this,n,t,e)},EWn.lh=function(n){return 9==n?!!UY(this):Hon(this,n)},EWn.sh=function(n,t){switch(n){case 9:return void _Ln(this,_B(t,33))}AAn(this,n,t)},EWn.zh=function(){return SXn(),jOt},EWn.Bh=function(n){switch(n){case 9:return void _Ln(this,null)}Lpn(this,n)},EWn.Ib=function(){return GRn(this)},gX(f6n,"ElkPortImpl",186);var UOt=fq(_6n,"BasicEMap/Entry");lAn(1092,115,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1,114:1,115:1},so),EWn.Fb=function(n){return this===n},EWn.cd=function(){return this.b},EWn.Hb=function(){return MN(this)},EWn.Uh=function(n){Nin(this,_B(n,146))},EWn._g=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return Jpn(this,n,t,e)},EWn.lh=function(n){switch(n){case 0:return!!this.b;case 1:return null!=this.c}return gpn(this,n)},EWn.sh=function(n,t){switch(n){case 0:return void Nin(this,_B(t,146));case 1:return void Rin(this,t)}vIn(this,n,t)},EWn.zh=function(){return SXn(),EOt},EWn.Bh=function(n){switch(n){case 0:return void Nin(this,null);case 1:return void Rin(this,null)}pPn(this,n)},EWn.Sh=function(){var n;return-1==this.a&&(n=this.b,this.a=n?Yon(n):0),this.a},EWn.dd=function(){return this.c},EWn.Th=function(n){this.a=n},EWn.ed=function(n){var t;return t=this.c,Rin(this,n),t},EWn.Ib=function(){var n;return 0!=(64&this.Db)?M$n(this):(aO(aO(aO(n=new Sk,this.b?this.b.tg():qWn),n1n),mN(this.c)),n.a)},EWn.a=-1,EWn.c=null;var XOt,WOt,VOt,QOt,JOt,YOt,ZOt,nAt,tAt=gX(f6n,"ElkPropertyToValueMapEntryImpl",1092);lAn(984,1,{},lo),gX(H6n,"JsonAdapter",984),lAn(210,60,_Vn,nk),gX(H6n,"JsonImportException",210),lAn(857,1,{},bkn),gX(H6n,"JsonImporter",857),lAn(891,1,{},rC),gX(H6n,"JsonImporter/lambda$0$Type",891),lAn(892,1,{},cC),gX(H6n,"JsonImporter/lambda$1$Type",892),lAn(900,1,{},Og),gX(H6n,"JsonImporter/lambda$10$Type",900),lAn(902,1,{},aC),gX(H6n,"JsonImporter/lambda$11$Type",902),lAn(903,1,{},uC),gX(H6n,"JsonImporter/lambda$12$Type",903),lAn(909,1,{},sQ),gX(H6n,"JsonImporter/lambda$13$Type",909),lAn(908,1,{},oQ),gX(H6n,"JsonImporter/lambda$14$Type",908),lAn(904,1,{},oC),gX(H6n,"JsonImporter/lambda$15$Type",904),lAn(905,1,{},sC),gX(H6n,"JsonImporter/lambda$16$Type",905),lAn(906,1,{},hC),gX(H6n,"JsonImporter/lambda$17$Type",906),lAn(907,1,{},fC),gX(H6n,"JsonImporter/lambda$18$Type",907),lAn(912,1,{},Ag),gX(H6n,"JsonImporter/lambda$19$Type",912),lAn(893,1,{},$g),gX(H6n,"JsonImporter/lambda$2$Type",893),lAn(910,1,{},Lg),gX(H6n,"JsonImporter/lambda$20$Type",910),lAn(911,1,{},Ng),gX(H6n,"JsonImporter/lambda$21$Type",911),lAn(915,1,{},xg),gX(H6n,"JsonImporter/lambda$22$Type",915),lAn(913,1,{},Dg),gX(H6n,"JsonImporter/lambda$23$Type",913),lAn(914,1,{},Rg),gX(H6n,"JsonImporter/lambda$24$Type",914),lAn(917,1,{},Kg),gX(H6n,"JsonImporter/lambda$25$Type",917),lAn(916,1,{},_g),gX(H6n,"JsonImporter/lambda$26$Type",916),lAn(918,1,hVn,lC),EWn.td=function(n){k9(this.b,this.a,TD(n))},gX(H6n,"JsonImporter/lambda$27$Type",918),lAn(919,1,hVn,bC),EWn.td=function(n){j9(this.b,this.a,TD(n))},gX(H6n,"JsonImporter/lambda$28$Type",919),lAn(920,1,{},wC),gX(H6n,"JsonImporter/lambda$29$Type",920),lAn(896,1,{},Fg),gX(H6n,"JsonImporter/lambda$3$Type",896),lAn(921,1,{},dC),gX(H6n,"JsonImporter/lambda$30$Type",921),lAn(922,1,{},Bg),gX(H6n,"JsonImporter/lambda$31$Type",922),lAn(923,1,{},Hg),gX(H6n,"JsonImporter/lambda$32$Type",923),lAn(924,1,{},qg),gX(H6n,"JsonImporter/lambda$33$Type",924),lAn(925,1,{},Gg),gX(H6n,"JsonImporter/lambda$34$Type",925),lAn(859,1,{},zg),gX(H6n,"JsonImporter/lambda$35$Type",859),lAn(929,1,{},EB),gX(H6n,"JsonImporter/lambda$36$Type",929),lAn(926,1,hVn,Ug),EWn.td=function(n){V4(this.a,_B(n,469))},gX(H6n,"JsonImporter/lambda$37$Type",926),lAn(927,1,hVn,TC),EWn.td=function(n){hO(this.a,this.b,_B(n,202))},gX(H6n,"JsonImporter/lambda$38$Type",927),lAn(928,1,hVn,MC),EWn.td=function(n){fO(this.a,this.b,_B(n,202))},gX(H6n,"JsonImporter/lambda$39$Type",928),lAn(894,1,{},Xg),gX(H6n,"JsonImporter/lambda$4$Type",894),lAn(930,1,hVn,Wg),EWn.td=function(n){Q4(this.a,_B(n,8))},gX(H6n,"JsonImporter/lambda$40$Type",930),lAn(895,1,{},Vg),gX(H6n,"JsonImporter/lambda$5$Type",895),lAn(899,1,{},Qg),gX(H6n,"JsonImporter/lambda$6$Type",899),lAn(897,1,{},Jg),gX(H6n,"JsonImporter/lambda$7$Type",897),lAn(898,1,{},Yg),gX(H6n,"JsonImporter/lambda$8$Type",898),lAn(901,1,{},Zg),gX(H6n,"JsonImporter/lambda$9$Type",901),lAn(948,1,hVn,np),EWn.td=function(n){YX(this.a,new HX(TD(n)))},gX(H6n,"JsonMetaDataConverter/lambda$0$Type",948),lAn(949,1,hVn,tp),EWn.td=function(n){RX(this.a,_B(n,237))},gX(H6n,"JsonMetaDataConverter/lambda$1$Type",949),lAn(950,1,hVn,ep),EWn.td=function(n){ZZ(this.a,_B(n,149))},gX(H6n,"JsonMetaDataConverter/lambda$2$Type",950),lAn(951,1,hVn,ip),EWn.td=function(n){KX(this.a,_B(n,175))},gX(H6n,"JsonMetaDataConverter/lambda$3$Type",951),lAn(237,22,{3:1,35:1,22:1,237:1},EC);var eAt,iAt=_en(PYn,"GraphFeature",237,Gnt,Dtn,dB);lAn(13,1,{35:1,146:1},cp,tR,OO,zA),EWn.wd=function(n){return dL(this,_B(n,146))},EWn.Fb=function(n){return kJ(this,n)},EWn.wg=function(){return ppn(this)},EWn.tg=function(){return this.b},EWn.Hb=function(){return gvn(this.b)},EWn.Ib=function(){return this.b},gX(PYn,"Property",13),lAn(818,1,EJn,rp),EWn.ue=function(n,t){return Rln(this,_B(n,94),_B(t,94))},EWn.Fb=function(n){return this===n},EWn.ve=function(){return new Yb(this)},gX(PYn,"PropertyHolderComparator",818),lAn(695,1,WWn,up),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return C9(this)},EWn.Qb=function(){cE()},EWn.Ob=function(){return!!this.a},gX(i8n,"ElkGraphUtil/AncestorIterator",695);var rAt=fq(_6n,"EList");lAn(67,52,{20:1,28:1,52:1,14:1,15:1,67:1,58:1}),EWn.Vc=function(n,t){uln(this,n,t)},EWn.Fc=function(n){return s9(this,n)},EWn.Wc=function(n,t){return aon(this,n,t)},EWn.Gc=function(n){return dX(this,n)},EWn.Zh=function(){return new rx(this)},EWn.$h=function(){return new cx(this)},EWn._h=function(n){return uin(this,n)},EWn.ai=function(){return!0},EWn.bi=function(n,t){},EWn.ci=function(){},EWn.di=function(n,t){A8(this,n,t)},EWn.ei=function(n,t,e){},EWn.fi=function(n,t){},EWn.gi=function(n,t,e){},EWn.Fb=function(n){return WDn(this,n)},EWn.Hb=function(){return Eun(this)},EWn.hi=function(){return!1},EWn.Kc=function(){return new CL(this)},EWn.Yc=function(){return new ix(this)},EWn.Zc=function(n){var t;if(t=this.gc(),n<0||n>t)throw Fp(new ZR(n,t));return new HU(this,n)},EWn.ji=function(n,t){this.ii(n,this.Xc(t))},EWn.Mc=function(n){return unn(this,n)},EWn.li=function(n,t){return t},EWn._c=function(n,t){return avn(this,n,t)},EWn.Ib=function(){return Qbn(this)},EWn.ni=function(){return!0},EWn.oi=function(n,t){return Lsn(this,t)},gX(_6n,"AbstractEList",67),lAn(63,67,o8n,go,wtn,ycn),EWn.Vh=function(n,t){return _Tn(this,n,t)},EWn.Wh=function(n){return fmn(this,n)},EWn.Xh=function(n,t){Pfn(this,n,t)},EWn.Yh=function(n){i6(this,n)},EWn.pi=function(n){return K9(this,n)},EWn.$b=function(){r6(this)},EWn.Hc=function(n){return Tjn(this,n)},EWn.Xb=function(n){return Utn(this,n)},EWn.qi=function(n){var t,e,i;++this.j,n>(e=null==this.g?0:this.g.length)&&(i=this.g,(t=e+(e/2|0)+4)=0&&(this.$c(t),!0)},EWn.mi=function(n,t){return this.Ui(n,this.oi(n,t))},EWn.gc=function(){return this.Vi()},EWn.Pc=function(){return this.Wi()},EWn.Qc=function(n){return this.Xi(n)},EWn.Ib=function(){return this.Yi()},gX(_6n,"DelegatingEList",1995),lAn(1996,1995,Y8n),EWn.Vh=function(n,t){return cFn(this,n,t)},EWn.Wh=function(n){return this.Vh(this.Vi(),n)},EWn.Xh=function(n,t){nAn(this,n,t)},EWn.Yh=function(n){IOn(this,n)},EWn.ai=function(){return!this.bj()},EWn.$b=function(){gqn(this)},EWn.Zi=function(n,t,e,i,r){return new $J(this,n,t,e,i,r)},EWn.$i=function(n){fan(this.Ai(),n)},EWn._i=function(){return null},EWn.aj=function(){return-1},EWn.Ai=function(){return null},EWn.bj=function(){return!1},EWn.cj=function(n,t){return t},EWn.dj=function(n,t){return t},EWn.ej=function(){return!1},EWn.fj=function(){return!this.Ri()},EWn.ii=function(n,t){var e,i;return this.ej()?(i=this.fj(),e=CMn(this,n,t),this.$i(this.Zi(7,tln(t),e,n,i)),e):CMn(this,n,t)},EWn.$c=function(n){var t,e,i,r;return this.ej()?(e=null,i=this.fj(),t=this.Zi(4,r=lq(this,n),null,n,i),this.bj()&&r?(e=this.dj(r,e))?(e.Ei(t),e.Fi()):this.$i(t):e?(e.Ei(t),e.Fi()):this.$i(t),r):(r=lq(this,n),this.bj()&&r&&(e=this.dj(r,null))&&e.Fi(),r)},EWn.mi=function(n,t){return aFn(this,n,t)},gX(t6n,"DelegatingNotifyingListImpl",1996),lAn(143,1,Z8n),EWn.Ei=function(n){return DEn(this,n)},EWn.Fi=function(){O7(this)},EWn.xi=function(){return this.d},EWn._i=function(){return null},EWn.gj=function(){return null},EWn.yi=function(n){return-1},EWn.zi=function(){return xxn(this)},EWn.Ai=function(){return null},EWn.Bi=function(){return Dxn(this)},EWn.Ci=function(){return this.o<0?this.o<-2?-2-this.o-1:-1:this.o},EWn.hj=function(){return!1},EWn.Di=function(n){var t,e,i,r,c,a,u,o;switch(this.d){case 1:case 2:switch(n.xi()){case 1:case 2:if(HC(n.Ai())===HC(this.Ai())&&this.yi(null)==n.yi(null))return this.g=n.zi(),1==n.xi()&&(this.d=1),!0}case 4:switch(n.xi()){case 4:if(HC(n.Ai())===HC(this.Ai())&&this.yi(null)==n.yi(null))return a=Zqn(this),c=this.o<0?this.o<-2?-2-this.o-1:-1:this.o,i=n.Ci(),this.d=6,o=new wtn(2),c<=i?(s9(o,this.n),s9(o,n.Bi()),this.g=Mun(Hk(INt,1),oQn,25,15,[this.o=c,i+1])):(s9(o,n.Bi()),s9(o,this.n),this.g=Mun(Hk(INt,1),oQn,25,15,[this.o=i,c])),this.n=o,a||(this.o=-2-this.o-1),!0}break;case 6:switch(n.xi()){case 4:if(HC(n.Ai())===HC(this.Ai())&&this.yi(null)==n.yi(null)){for(a=Zqn(this),i=n.Ci(),u=_B(this.g,48),e=L8(INt,oQn,25,u.length+1,15,1),t=0;t>>0).toString(16))).a+=" (eventType: ",this.d){case 1:e.a+="SET";break;case 2:e.a+="UNSET";break;case 3:e.a+="ADD";break;case 5:e.a+="ADD_MANY";break;case 4:e.a+="REMOVE";break;case 6:e.a+="REMOVE_MANY";break;case 7:e.a+="MOVE";break;case 8:e.a+="REMOVING_ADAPTER";break;case 9:e.a+="RESOLVE";break;default:pE(e,this.d)}if(hKn(this)&&(e.a+=", touch: true"),e.a+=", position: ",pE(e,this.o<0?this.o<-2?-2-this.o-1:-1:this.o),e.a+=", notifier: ",eO(e,this.Ai()),e.a+=", feature: ",eO(e,this._i()),e.a+=", oldValue: ",eO(e,Dxn(this)),e.a+=", newValue: ",6==this.d&&iL(this.g,48)){for(t=_B(this.g,48),e.a+="[",n=0;n10?(this.b&&this.c.j==this.a||(this.b=new Oq(this),this.a=this.j),KT(this.b,n)):Tjn(this,n)},EWn.ni=function(){return!0},EWn.a=0,gX(_6n,"AbstractEList/1",953),lAn(295,73,$Qn,ZR),gX(_6n,"AbstractEList/BasicIndexOutOfBoundsException",295),lAn(40,1,WWn,CL),EWn.Nb=function(n){sU(this,n)},EWn.mj=function(){if(this.i.j!=this.f)throw Fp(new gv)},EWn.nj=function(){return mpn(this)},EWn.Ob=function(){return this.e!=this.i.gc()},EWn.Pb=function(){return this.nj()},EWn.Qb=function(){Wjn(this)},EWn.e=0,EWn.f=0,EWn.g=-1,gX(_6n,"AbstractEList/EIterator",40),lAn(278,40,iVn,ix,HU),EWn.Qb=function(){Wjn(this)},EWn.Rb=function(n){adn(this,n)},EWn.oj=function(){var n;try{return n=this.d.Xb(--this.e),this.mj(),this.g=this.e,n}catch(t){throw iL(t=hun(t),73)?(this.mj(),Fp(new vv)):Fp(t)}},EWn.pj=function(n){mmn(this,n)},EWn.Sb=function(){return 0!=this.e},EWn.Tb=function(){return this.e},EWn.Ub=function(){return this.oj()},EWn.Vb=function(){return this.e-1},EWn.Wb=function(n){this.pj(n)},gX(_6n,"AbstractEList/EListIterator",278),lAn(341,40,WWn,rx),EWn.nj=function(){return ypn(this)},EWn.Qb=function(){throw Fp(new dv)},gX(_6n,"AbstractEList/NonResolvingEIterator",341),lAn(385,278,iVn,cx,xK),EWn.Rb=function(n){throw Fp(new dv)},EWn.nj=function(){var n;try{return n=this.c.ki(this.e),this.mj(),this.g=this.e++,n}catch(t){throw iL(t=hun(t),73)?(this.mj(),Fp(new vv)):Fp(t)}},EWn.oj=function(){var n;try{return n=this.c.ki(--this.e),this.mj(),this.g=this.e,n}catch(t){throw iL(t=hun(t),73)?(this.mj(),Fp(new vv)):Fp(t)}},EWn.Qb=function(){throw Fp(new dv)},EWn.Wb=function(n){throw Fp(new dv)},gX(_6n,"AbstractEList/NonResolvingEListIterator",385),lAn(1982,67,e9n),EWn.Vh=function(n,t){var e,i,r,c,a,u,o,s,h;if(0!=(i=t.gc())){for(e=Msn(this,(s=null==(o=_B(van(this.a,4),126))?0:o.length)+i),(h=s-n)>0&&rHn(o,n,e,n+i,h),u=t.Kc(),c=0;ce)throw Fp(new ZR(n,e));return new _W(this,n)},EWn.$b=function(){var n,t;++this.j,t=null==(n=_B(van(this.a,4),126))?0:n.length,Kgn(this,null),A8(this,t,n)},EWn.Hc=function(n){var t,e,i,r;if(null!=(t=_B(van(this.a,4),126)))if(null!=n){for(i=0,r=(e=t).length;i=(e=null==(t=_B(van(this.a,4),126))?0:t.length))throw Fp(new ZR(n,e));return t[n]},EWn.Xc=function(n){var t,e,i;if(null!=(t=_B(van(this.a,4),126)))if(null!=n){for(e=0,i=t.length;ee)throw Fp(new ZR(n,e));return new KW(this,n)},EWn.ii=function(n,t){var e,i,r;if(n>=(r=null==(e=Odn(this))?0:e.length))throw Fp(new Cy(c8n+n+a8n+r));if(t>=r)throw Fp(new Cy(u8n+t+a8n+r));return i=e[t],n!=t&&(n0&&rHn(n,0,t,0,e),t},EWn.Qc=function(n){var t,e;return(e=null==(t=_B(van(this.a,4),126))?0:t.length)>0&&(n.lengthe&&OX(n,e,null),n},gX(_6n,"ArrayDelegatingEList",1982),lAn(1038,40,WWn,E5),EWn.mj=function(){if(this.b.j!=this.f||HC(_B(van(this.b.a,4),126))!==HC(this.a))throw Fp(new gv)},EWn.Qb=function(){Wjn(this),this.a=_B(van(this.b.a,4),126)},gX(_6n,"ArrayDelegatingEList/EIterator",1038),lAn(706,278,iVn,Wz,KW),EWn.mj=function(){if(this.b.j!=this.f||HC(_B(van(this.b.a,4),126))!==HC(this.a))throw Fp(new gv)},EWn.pj=function(n){mmn(this,n),this.a=_B(van(this.b.a,4),126)},EWn.Qb=function(){Wjn(this),this.a=_B(van(this.b.a,4),126)},gX(_6n,"ArrayDelegatingEList/EListIterator",706),lAn(1039,341,WWn,T5),EWn.mj=function(){if(this.b.j!=this.f||HC(_B(van(this.b.a,4),126))!==HC(this.a))throw Fp(new gv)},gX(_6n,"ArrayDelegatingEList/NonResolvingEIterator",1039),lAn(707,385,iVn,Vz,_W),EWn.mj=function(){if(this.b.j!=this.f||HC(_B(van(this.b.a,4),126))!==HC(this.a))throw Fp(new gv)},gX(_6n,"ArrayDelegatingEList/NonResolvingEListIterator",707),lAn(606,295,$Qn,AO),gX(_6n,"BasicEList/BasicIndexOutOfBoundsException",606),lAn(696,63,o8n,NC),EWn.Vc=function(n,t){throw Fp(new dv)},EWn.Fc=function(n){throw Fp(new dv)},EWn.Wc=function(n,t){throw Fp(new dv)},EWn.Gc=function(n){throw Fp(new dv)},EWn.$b=function(){throw Fp(new dv)},EWn.qi=function(n){throw Fp(new dv)},EWn.Kc=function(){return this.Zh()},EWn.Yc=function(){return this.$h()},EWn.Zc=function(n){return this._h(n)},EWn.ii=function(n,t){throw Fp(new dv)},EWn.ji=function(n,t){throw Fp(new dv)},EWn.$c=function(n){throw Fp(new dv)},EWn.Mc=function(n){throw Fp(new dv)},EWn._c=function(n,t){throw Fp(new dv)},gX(_6n,"BasicEList/UnmodifiableEList",696),lAn(705,1,{3:1,20:1,14:1,15:1,58:1,589:1}),EWn.Vc=function(n,t){W$(this,n,_B(t,42))},EWn.Fc=function(n){return rD(this,_B(n,42))},EWn.Jc=function(n){n5(this,n)},EWn.Xb=function(n){return _B(Utn(this.c,n),133)},EWn.ii=function(n,t){return _B(this.c.ii(n,t),42)},EWn.ji=function(n,t){V$(this,n,_B(t,42))},EWn.Lc=function(){return new xq(null,new l1(this,16))},EWn.$c=function(n){return _B(this.c.$c(n),42)},EWn._c=function(n,t){return cX(this,n,_B(t,42))},EWn.ad=function(n){Rrn(this,n)},EWn.Nc=function(){return new l1(this,16)},EWn.Oc=function(){return new xq(null,new l1(this,16))},EWn.Wc=function(n,t){return this.c.Wc(n,t)},EWn.Gc=function(n){return this.c.Gc(n)},EWn.$b=function(){this.c.$b()},EWn.Hc=function(n){return this.c.Hc(n)},EWn.Ic=function(n){return aun(this.c,n)},EWn.qj=function(){var n,t;if(null==this.d){for(this.d=L8(uAt,i9n,63,2*this.f+1,0,1),t=this.e,this.f=0,n=this.c.Kc();n.e!=n.i.gc();)Pvn(this,_B(n.nj(),133));this.e=t}},EWn.Fb=function(n){return $K(this,n)},EWn.Hb=function(){return Eun(this.c)},EWn.Xc=function(n){return this.c.Xc(n)},EWn.rj=function(){this.c=new op(this)},EWn.dc=function(){return 0==this.f},EWn.Kc=function(){return this.c.Kc()},EWn.Yc=function(){return this.c.Yc()},EWn.Zc=function(n){return this.c.Zc(n)},EWn.sj=function(){return C8(this)},EWn.tj=function(n,t,e){return new TB(n,t,e)},EWn.uj=function(){return new vo},EWn.Mc=function(n){return oin(this,n)},EWn.gc=function(){return this.f},EWn.bd=function(n,t){return new u1(this.c,n,t)},EWn.Pc=function(){return this.c.Pc()},EWn.Qc=function(n){return this.c.Qc(n)},EWn.Ib=function(){return Qbn(this.c)},EWn.e=0,EWn.f=0,gX(_6n,"BasicEMap",705),lAn(1033,63,o8n,op),EWn.bi=function(n,t){Cv(this,_B(t,133))},EWn.ei=function(n,t,e){var i;++(i=this,_B(t,133),i).a.e},EWn.fi=function(n,t){Ov(this,_B(t,133))},EWn.gi=function(n,t,e){XN(this,_B(t,133),_B(e,133))},EWn.di=function(n,t){ran(this.a)},gX(_6n,"BasicEMap/1",1033),lAn(1034,63,o8n,vo),EWn.ri=function(n){return L8(dAt,r9n,612,n,0,1)},gX(_6n,"BasicEMap/2",1034),lAn(1035,YWn,ZWn,sp),EWn.$b=function(){this.a.c.$b()},EWn.Hc=function(n){return edn(this.a,n)},EWn.Kc=function(){return 0==this.a.f?(bD(),wAt.a):new _j(this.a)},EWn.Mc=function(n){var t;return t=this.a.f,Udn(this.a,n),this.a.f!=t},EWn.gc=function(){return this.a.f},gX(_6n,"BasicEMap/3",1035),lAn(1036,28,JWn,hp),EWn.$b=function(){this.a.c.$b()},EWn.Hc=function(n){return VDn(this.a,n)},EWn.Kc=function(){return 0==this.a.f?(bD(),wAt.a):new Fj(this.a)},EWn.gc=function(){return this.a.f},gX(_6n,"BasicEMap/4",1036),lAn(1037,YWn,ZWn,fp),EWn.$b=function(){this.a.c.$b()},EWn.Hc=function(n){var t,e,i,r,c,a,u,o,s;if(this.a.f>0&&iL(n,42)&&(this.a.qj(),r=null==(u=(o=_B(n,42)).cd())?0:Yon(u),c=nR(this.a,r),t=this.a.d[c]))for(e=_B(t.g,367),s=t.i,a=0;a"+this.c},EWn.a=0;var wAt,dAt=gX(_6n,"BasicEMap/EntryImpl",612);lAn(536,1,{},oo),gX(_6n,"BasicEMap/View",536),lAn(768,1,{}),EWn.Fb=function(n){return $An((TQ(),uet),n)},EWn.Hb=function(){return Kon((TQ(),uet))},EWn.Ib=function(){return AMn((TQ(),uet))},gX(_6n,"ECollections/BasicEmptyUnmodifiableEList",768),lAn(1312,1,iVn,mo),EWn.Nb=function(n){sU(this,n)},EWn.Rb=function(n){throw Fp(new dv)},EWn.Ob=function(){return!1},EWn.Sb=function(){return!1},EWn.Pb=function(){throw Fp(new vv)},EWn.Tb=function(){return 0},EWn.Ub=function(){throw Fp(new vv)},EWn.Vb=function(){return-1},EWn.Qb=function(){throw Fp(new dv)},EWn.Wb=function(n){throw Fp(new dv)},gX(_6n,"ECollections/BasicEmptyUnmodifiableEList/1",1312),lAn(1310,768,{20:1,14:1,15:1,58:1},jm),EWn.Vc=function(n,t){$E()},EWn.Fc=function(n){return LE()},EWn.Wc=function(n,t){return NE()},EWn.Gc=function(n){return xE()},EWn.$b=function(){DE()},EWn.Hc=function(n){return!1},EWn.Ic=function(n){return!1},EWn.Jc=function(n){n5(this,n)},EWn.Xb=function(n){return vO((TQ(),n)),null},EWn.Xc=function(n){return-1},EWn.dc=function(){return!0},EWn.Kc=function(){return this.a},EWn.Yc=function(){return this.a},EWn.Zc=function(n){return this.a},EWn.ii=function(n,t){return RE()},EWn.ji=function(n,t){KE()},EWn.Lc=function(){return new xq(null,new l1(this,16))},EWn.$c=function(n){return _E()},EWn.Mc=function(n){return FE()},EWn._c=function(n,t){return BE()},EWn.gc=function(){return 0},EWn.ad=function(n){Rrn(this,n)},EWn.Nc=function(){return new l1(this,16)},EWn.Oc=function(){return new xq(null,new l1(this,16))},EWn.bd=function(n,t){return TQ(),new u1(uet,n,t)},EWn.Pc=function(){return iz((TQ(),uet))},EWn.Qc=function(n){return TQ(),kmn(uet,n)},gX(_6n,"ECollections/EmptyUnmodifiableEList",1310),lAn(1311,768,{20:1,14:1,15:1,58:1,589:1},Em),EWn.Vc=function(n,t){$E()},EWn.Fc=function(n){return LE()},EWn.Wc=function(n,t){return NE()},EWn.Gc=function(n){return xE()},EWn.$b=function(){DE()},EWn.Hc=function(n){return!1},EWn.Ic=function(n){return!1},EWn.Jc=function(n){n5(this,n)},EWn.Xb=function(n){return vO((TQ(),n)),null},EWn.Xc=function(n){return-1},EWn.dc=function(){return!0},EWn.Kc=function(){return this.a},EWn.Yc=function(){return this.a},EWn.Zc=function(n){return this.a},EWn.ii=function(n,t){return RE()},EWn.ji=function(n,t){KE()},EWn.Lc=function(){return new xq(null,new l1(this,16))},EWn.$c=function(n){return _E()},EWn.Mc=function(n){return FE()},EWn._c=function(n,t){return BE()},EWn.gc=function(){return 0},EWn.ad=function(n){Rrn(this,n)},EWn.Nc=function(){return new l1(this,16)},EWn.Oc=function(){return new xq(null,new l1(this,16))},EWn.bd=function(n,t){return TQ(),new u1(uet,n,t)},EWn.Pc=function(){return iz((TQ(),uet))},EWn.Qc=function(n){return TQ(),kmn(uet,n)},EWn.sj=function(){return TQ(),TQ(),oet},gX(_6n,"ECollections/EmptyUnmodifiableEMap",1311);var gAt,pAt=fq(_6n,"Enumerator");lAn(281,1,{281:1},eRn),EWn.Fb=function(n){var t;return this===n||!!iL(n,281)&&(t=_B(n,281),this.f==t.f&&gG(this.i,t.i)&&dG(this.a,0!=(256&this.f)?0!=(256&t.f)?t.a:null:0!=(256&t.f)?null:t.a)&&dG(this.d,t.d)&&dG(this.g,t.g)&&dG(this.e,t.e)&&Tpn(this,t))},EWn.Hb=function(){return this.f},EWn.Ib=function(){return E_n(this)},EWn.f=0;var vAt,mAt,yAt,kAt=0,jAt=0,EAt=0,TAt=0,MAt=0,SAt=0,PAt=0,IAt=0,CAt=0,OAt=0,AAt=0,$At=0,LAt=0;gX(_6n,"URI",281),lAn(1091,43,ZQn,Tm),EWn.zc=function(n,t){return _B(pZ(this,TD(n),_B(t,281)),281)},gX(_6n,"URI/URICache",1091),lAn(497,63,o8n,fo,eG),EWn.hi=function(){return!0},gX(_6n,"UniqueEList",497),lAn(581,60,_Vn,A7),gX(_6n,"WrappedException",581);var NAt,xAt=fq(B5n,u9n),DAt=fq(B5n,o9n),RAt=fq(B5n,s9n),KAt=fq(B5n,h9n),_At=fq(B5n,f9n),FAt=fq(B5n,"EClass"),BAt=fq(B5n,"EDataType");lAn(1183,43,ZQn,Mm),EWn.xc=function(n){return zC(n)?TY(this,n):BC(CJ(this.f,n))},gX(B5n,"EDataType/Internal/ConversionDelegate/Factory/Registry/Impl",1183);var HAt,qAt,GAt=fq(B5n,"EEnum"),zAt=fq(B5n,l9n),UAt=fq(B5n,b9n),XAt=fq(B5n,w9n),WAt=fq(B5n,d9n),VAt=fq(B5n,g9n);lAn(1029,1,{},ho),EWn.Ib=function(){return"NIL"},gX(B5n,"EStructuralFeature/Internal/DynamicValueHolder/1",1029),lAn(1028,43,ZQn,Sm),EWn.xc=function(n){return zC(n)?TY(this,n):BC(CJ(this.f,n))},gX(B5n,"EStructuralFeature/Internal/SettingDelegate/Factory/Registry/Impl",1028);var QAt,JAt,YAt,ZAt,n$t,t$t,e$t,i$t,r$t,c$t,a$t,u$t,o$t,s$t,h$t,f$t,l$t,b$t,w$t,d$t,g$t,p$t,v$t,m$t,y$t,k$t,j$t,E$t,T$t,M$t,S$t,P$t=fq(B5n,p9n),I$t=fq(B5n,"EValidator/PatternMatcher"),C$t=fq(v9n,"FeatureMap/Entry");lAn(535,1,{72:1},SC),EWn.ak=function(){return this.a},EWn.dd=function(){return this.b},gX(h6n,"BasicEObjectImpl/1",535),lAn(1027,1,m9n,PC),EWn.Wj=function(n){return X5(this.a,this.b,n)},EWn.fj=function(){return JY(this.a,this.b)},EWn.Wb=function(n){$Y(this.a,this.b,n)},EWn.Xj=function(){MW(this.a,this.b)},gX(h6n,"BasicEObjectImpl/4",1027),lAn(1983,1,{108:1}),EWn.bk=function(n){this.e=0==n?j$t:L8(Cnt,FWn,1,n,5,1)},EWn.Ch=function(n){return this.e[n]},EWn.Dh=function(n,t){this.e[n]=t},EWn.Eh=function(n){this.e[n]=null},EWn.ck=function(){return this.c},EWn.dk=function(){throw Fp(new dv)},EWn.ek=function(){throw Fp(new dv)},EWn.fk=function(){return this.d},EWn.gk=function(){return null!=this.e},EWn.hk=function(n){this.c=n},EWn.ik=function(n){throw Fp(new dv)},EWn.jk=function(n){throw Fp(new dv)},EWn.kk=function(n){this.d=n},gX(h6n,"BasicEObjectImpl/EPropertiesHolderBaseImpl",1983),lAn(185,1983,{108:1},Df),EWn.dk=function(){return this.a},EWn.ek=function(){return this.b},EWn.ik=function(n){this.a=n},EWn.jk=function(n){this.b=n},gX(h6n,"BasicEObjectImpl/EPropertiesHolderImpl",185),lAn(506,97,s6n,yo),EWn.Kg=function(){return this.f},EWn.Pg=function(){return this.k},EWn.Rg=function(n,t){this.g=n,this.i=t},EWn.Tg=function(){return 0==(2&this.j)?this.zh():this.ph().ck()},EWn.Vg=function(){return this.i},EWn.Mg=function(){return 0!=(1&this.j)},EWn.eh=function(){return this.g},EWn.kh=function(){return 0!=(4&this.j)},EWn.ph=function(){return!this.k&&(this.k=new Df),this.k},EWn.th=function(n){this.ph().hk(n),n?this.j|=2:this.j&=-3},EWn.vh=function(n){this.ph().jk(n),n?this.j|=4:this.j&=-5},EWn.zh=function(){return(WX(),YAt).S},EWn.i=0,EWn.j=1,gX(h6n,"EObjectImpl",506),lAn(780,506,{105:1,92:1,90:1,56:1,108:1,49:1,97:1},yH),EWn.Ch=function(n){return this.e[n]},EWn.Dh=function(n,t){this.e[n]=t},EWn.Eh=function(n){this.e[n]=null},EWn.Tg=function(){return this.d},EWn.Yg=function(n){return Cwn(this.d,n)},EWn.$g=function(){return this.d},EWn.dh=function(){return null!=this.e},EWn.ph=function(){return!this.k&&(this.k=new ko),this.k},EWn.th=function(n){this.d=n},EWn.yh=function(){var n;return null==this.e&&(n=fX(this.d),this.e=0==n?E$t:L8(Cnt,FWn,1,n,5,1)),this},EWn.Ah=function(){return 0},gX(h6n,"DynamicEObjectImpl",780),lAn(1376,780,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1},sq),EWn.Fb=function(n){return this===n},EWn.Hb=function(){return MN(this)},EWn.th=function(n){this.d=n,this.b=$Nn(n,"key"),this.c=$Nn(n,k6n)},EWn.Sh=function(){var n;return-1==this.a&&(n=Q7(this,this.b),this.a=null==n?0:Yon(n)),this.a},EWn.cd=function(){return Q7(this,this.b)},EWn.dd=function(){return Q7(this,this.c)},EWn.Th=function(n){this.a=n},EWn.Uh=function(n){$Y(this,this.b,n)},EWn.ed=function(n){var t;return t=Q7(this,this.c),$Y(this,this.c,n),t},EWn.a=0,gX(h6n,"DynamicEObjectImpl/BasicEMapEntry",1376),lAn(1377,1,{108:1},ko),EWn.bk=function(n){throw Fp(new dv)},EWn.Ch=function(n){throw Fp(new dv)},EWn.Dh=function(n,t){throw Fp(new dv)},EWn.Eh=function(n){throw Fp(new dv)},EWn.ck=function(){throw Fp(new dv)},EWn.dk=function(){return this.a},EWn.ek=function(){return this.b},EWn.fk=function(){return this.c},EWn.gk=function(){throw Fp(new dv)},EWn.hk=function(n){throw Fp(new dv)},EWn.ik=function(n){this.a=n},EWn.jk=function(n){this.b=n},EWn.kk=function(n){this.c=n},gX(h6n,"DynamicEObjectImpl/DynamicEPropertiesHolderImpl",1377),lAn(510,150,{105:1,92:1,90:1,590:1,147:1,56:1,108:1,49:1,97:1,510:1,150:1,114:1,115:1},jo),EWn.Qg=function(n){return fkn(this,n)},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.d;case 2:return e?(!this.b&&(this.b=new Qx((wWn(),v$t),G$t,this)),this.b):(!this.b&&(this.b=new Qx((wWn(),v$t),G$t,this)),C8(this.b));case 3:return fZ(this);case 4:return!this.a&&(this.a=new OL(OOt,this,4)),this.a;case 5:return!this.c&&(this.c=new xL(OOt,this,5)),this.c}return G9(this,n-fX((wWn(),ZAt)),ttn(_B(van(this,16),26)||ZAt,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 3:return this.Cb&&(e=(i=this.Db>>16)>=0?fkn(this,e):this.Cb.ih(this,-1-i,null,e)),WG(this,_B(n,147),e)}return _B(ttn(_B(van(this,16),26)||(wWn(),ZAt),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),ZAt)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 2:return!this.b&&(this.b=new Qx((wWn(),v$t),G$t,this)),_K(this.b,n,e);case 3:return WG(this,null,e);case 4:return!this.a&&(this.a=new OL(OOt,this,4)),Rpn(this.a,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),ZAt),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),ZAt)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.d;case 2:return!!this.b&&0!=this.b.f;case 3:return!!fZ(this);case 4:return!!this.a&&0!=this.a.i;case 5:return!!this.c&&0!=this.c.i}return I3(this,n-fX((wWn(),ZAt)),ttn(_B(van(this,16),26)||ZAt,n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void dq(this,TD(t));case 2:return!this.b&&(this.b=new Qx((wWn(),v$t),G$t,this)),void Zcn(this.b,t);case 3:return void INn(this,_B(t,147));case 4:return!this.a&&(this.a=new OL(OOt,this,4)),uqn(this.a),!this.a&&(this.a=new OL(OOt,this,4)),void dX(this.a,_B(t,14));case 5:return!this.c&&(this.c=new xL(OOt,this,5)),uqn(this.c),!this.c&&(this.c=new xL(OOt,this,5)),void dX(this.c,_B(t,14))}Abn(this,n-fX((wWn(),ZAt)),ttn(_B(van(this,16),26)||ZAt,n),t)},EWn.zh=function(){return wWn(),ZAt},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void _in(this,null);case 2:return!this.b&&(this.b=new Qx((wWn(),v$t),G$t,this)),void this.b.c.$b();case 3:return void INn(this,null);case 4:return!this.a&&(this.a=new OL(OOt,this,4)),void uqn(this.a);case 5:return!this.c&&(this.c=new xL(OOt,this,5)),void uqn(this.c)}Bfn(this,n-fX((wWn(),ZAt)),ttn(_B(van(this,16),26)||ZAt,n))},EWn.Ib=function(){return Xfn(this)},EWn.d=null,gX(h6n,"EAnnotationImpl",510),lAn(151,705,y9n,v9),EWn.Xh=function(n,t){YA(this,n,_B(t,42))},EWn.lk=function(n,t){return KK(this,_B(n,42),t)},EWn.pi=function(n){return _B(_B(this.c,69).pi(n),133)},EWn.Zh=function(){return _B(this.c,69).Zh()},EWn.$h=function(){return _B(this.c,69).$h()},EWn._h=function(n){return _B(this.c,69)._h(n)},EWn.mk=function(n,t){return _K(this,n,t)},EWn.Wj=function(n){return _B(this.c,76).Wj(n)},EWn.rj=function(){},EWn.fj=function(){return _B(this.c,76).fj()},EWn.tj=function(n,t,e){var i;return(i=_B(Gtn(this.b).Nh().Jh(this.b),133)).Th(n),i.Uh(t),i.ed(e),i},EWn.uj=function(){return new Pp(this)},EWn.Wb=function(n){Zcn(this,n)},EWn.Xj=function(){_B(this.c,76).Xj()},gX(v9n,"EcoreEMap",151),lAn(158,151,y9n,Qx),EWn.qj=function(){var n,t,e,i,r;if(null==this.d){for(r=L8(uAt,i9n,63,2*this.f+1,0,1),e=this.c.Kc();e.e!=e.i.gc();)!(n=r[i=((t=_B(e.nj(),133)).Sh()&NWn)%r.length])&&(n=r[i]=new Pp(this)),n.Fc(t);this.d=r}},gX(h6n,"EAnnotationImpl/1",158),lAn(284,438,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,472:1,49:1,97:1,150:1,284:1,114:1,115:1}),EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),!!this.$j();case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q}return G9(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 9:return wX(this,e)}return _B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Rj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.$j();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i)}return I3(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void this.Lh(TD(t));case 2:return void Vfn(this,By(jD(t)));case 3:return void Yfn(this,By(jD(t)));case 4:return void Aen(this,_B(t,19).a);case 5:return void this.ok(_B(t,19).a);case 8:return void Phn(this,_B(t,138));case 9:return void((e=FTn(this,_B(t,87),null))&&e.Fi())}Abn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t)},EWn.zh=function(){return wWn(),y$t},EWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void this.Lh(null);case 2:return void Vfn(this,!0);case 3:return void Yfn(this,!0);case 4:return void Aen(this,0);case 5:return void this.ok(1);case 8:return void Phn(this,null);case 9:return void((t=FTn(this,null,null))&&t.Fi())}Bfn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.Gh=function(){Pkn(this),this.Bb|=1},EWn.Yj=function(){return Pkn(this)},EWn.Zj=function(){return this.t},EWn.$j=function(){var n;return(n=this.t)>1||-1==n},EWn.hi=function(){return 0!=(512&this.Bb)},EWn.nk=function(n,t){return Mfn(this,n,t)},EWn.ok=function(n){$en(this,n)},EWn.Ib=function(){return DOn(this)},EWn.s=0,EWn.t=1,gX(h6n,"ETypedElementImpl",284),lAn(449,284,{105:1,92:1,90:1,147:1,191:1,56:1,170:1,66:1,108:1,472:1,49:1,97:1,150:1,449:1,284:1,114:1,115:1,677:1}),EWn.Qg=function(n){return $yn(this,n)},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),!!this.$j();case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q;case 10:return oN(),0!=(this.Bb&m6n);case 11:return oN(),0!=(this.Bb&E9n);case 12:return oN(),0!=(this.Bb&RQn);case 13:return this.j;case 14:return BLn(this);case 15:return oN(),0!=(this.Bb&j9n);case 16:return oN(),0!=(this.Bb&oVn);case 17:return bZ(this)}return G9(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 17:return this.Cb&&(e=(i=this.Db>>16)>=0?$yn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,17,e)}return _B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Qj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 9:return wX(this,e);case 17:return j_n(this,null,17,e)}return _B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Rj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return this.$j();case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i);case 10:return 0==(this.Bb&m6n);case 11:return 0!=(this.Bb&E9n);case 12:return 0!=(this.Bb&RQn);case 13:return null!=this.j;case 14:return null!=BLn(this);case 15:return 0!=(this.Bb&j9n);case 16:return 0!=(this.Bb&oVn);case 17:return!!bZ(this)}return I3(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void QZ(this,TD(t));case 2:return void Vfn(this,By(jD(t)));case 3:return void Yfn(this,By(jD(t)));case 4:return void Aen(this,_B(t,19).a);case 5:return void this.ok(_B(t,19).a);case 8:return void Phn(this,_B(t,138));case 9:return void((e=FTn(this,_B(t,87),null))&&e.Fi());case 10:return void Cln(this,By(jD(t)));case 11:return void $ln(this,By(jD(t)));case 12:return void Oln(this,By(jD(t)));case 13:return void RC(this,TD(t));case 15:return void Aln(this,By(jD(t)));case 16:return void Bln(this,By(jD(t)))}Abn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t)},EWn.zh=function(){return wWn(),m$t},EWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,88)&&CIn(M5(_B(this.Cb,88)),4),void $rn(this,null);case 2:return void Vfn(this,!0);case 3:return void Yfn(this,!0);case 4:return void Aen(this,0);case 5:return void this.ok(1);case 8:return void Phn(this,null);case 9:return void((t=FTn(this,null,null))&&t.Fi());case 10:return void Cln(this,!0);case 11:return void $ln(this,!1);case 12:return void Oln(this,!1);case 13:return this.i=null,void rrn(this,null);case 15:return void Aln(this,!1);case 16:return void Bln(this,!1)}Bfn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.Gh=function(){mV(_7((PPn(),Q$t),this)),Pkn(this),this.Bb|=1},EWn.Gj=function(){return this.f},EWn.zj=function(){return BLn(this)},EWn.Hj=function(){return bZ(this)},EWn.Lj=function(){return null},EWn.pk=function(){return this.k},EWn.aj=function(){return this.n},EWn.Mj=function(){return aEn(this)},EWn.Nj=function(){var n,t,e,i,r,c,a,u,o;return this.p||((null==(e=bZ(this)).i&&BFn(e),e.i).length,(i=this.Lj())&&fX(bZ(i)),n=(a=(r=Pkn(this)).Bj())?0!=(1&a.i)?a==CNt?mtt:a==INt?Ctt:a==LNt?Stt:a==$Nt?Mtt:a==ONt?xtt:a==NNt?Rtt:a==ANt?jtt:Ttt:a:null,t=BLn(this),u=r.zj(),fbn(this),0!=(this.Bb&oVn)&&((c=pjn((PPn(),Q$t),e))&&c!=this||(c=J1(_7(Q$t,this))))?this.p=new CC(this,c):this.$j()?this.rk()?i?0!=(this.Bb&j9n)?n?this.sk()?this.p=new hQ(47,n,this,i):this.p=new hQ(5,n,this,i):this.sk()?this.p=new l4(46,this,i):this.p=new l4(4,this,i):n?this.sk()?this.p=new hQ(49,n,this,i):this.p=new hQ(7,n,this,i):this.sk()?this.p=new l4(48,this,i):this.p=new l4(6,this,i):0!=(this.Bb&j9n)?n?n==Fnt?this.p=new MB(50,UOt,this):this.sk()?this.p=new MB(43,n,this):this.p=new MB(1,n,this):this.sk()?this.p=new xJ(42,this):this.p=new xJ(0,this):n?n==Fnt?this.p=new MB(41,UOt,this):this.sk()?this.p=new MB(45,n,this):this.p=new MB(3,n,this):this.sk()?this.p=new xJ(44,this):this.p=new xJ(2,this):iL(r,148)?n==C$t?this.p=new xJ(40,this):0!=(512&this.Bb)?0!=(this.Bb&j9n)?this.p=n?new MB(9,n,this):new xJ(8,this):this.p=n?new MB(11,n,this):new xJ(10,this):0!=(this.Bb&j9n)?this.p=n?new MB(13,n,this):new xJ(12,this):this.p=n?new MB(15,n,this):new xJ(14,this):i?(o=i.t)>1||-1==o?this.sk()?0!=(this.Bb&j9n)?this.p=n?new hQ(25,n,this,i):new l4(24,this,i):this.p=n?new hQ(27,n,this,i):new l4(26,this,i):0!=(this.Bb&j9n)?this.p=n?new hQ(29,n,this,i):new l4(28,this,i):this.p=n?new hQ(31,n,this,i):new l4(30,this,i):this.sk()?0!=(this.Bb&j9n)?this.p=n?new hQ(33,n,this,i):new l4(32,this,i):this.p=n?new hQ(35,n,this,i):new l4(34,this,i):0!=(this.Bb&j9n)?this.p=n?new hQ(37,n,this,i):new l4(36,this,i):this.p=n?new hQ(39,n,this,i):new l4(38,this,i):this.sk()?0!=(this.Bb&j9n)?this.p=n?new MB(17,n,this):new xJ(16,this):this.p=n?new MB(19,n,this):new xJ(18,this):0!=(this.Bb&j9n)?this.p=n?new MB(21,n,this):new xJ(20,this):this.p=n?new MB(23,n,this):new xJ(22,this):this.qk()?this.sk()?this.p=new SB(_B(r,26),this,i):this.p=new pY(_B(r,26),this,i):iL(r,148)?n==C$t?this.p=new xJ(40,this):0!=(this.Bb&j9n)?this.p=n?new YG(t,u,this,(_wn(),a==INt?F$t:a==CNt?x$t:a==ONt?B$t:a==LNt?_$t:a==$Nt?K$t:a==NNt?q$t:a==ANt?D$t:a==PNt?R$t:H$t)):new bQ(_B(r,148),t,u,this):this.p=n?new JG(t,u,this,(_wn(),a==INt?F$t:a==CNt?x$t:a==ONt?B$t:a==LNt?_$t:a==$Nt?K$t:a==NNt?q$t:a==ANt?D$t:a==PNt?R$t:H$t)):new lQ(_B(r,148),t,u,this):this.rk()?i?0!=(this.Bb&j9n)?this.sk()?this.p=new $B(_B(r,26),this,i):this.p=new AB(_B(r,26),this,i):this.sk()?this.p=new OB(_B(r,26),this,i):this.p=new PB(_B(r,26),this,i):0!=(this.Bb&j9n)?this.sk()?this.p=new nD(_B(r,26),this):this.p=new Zx(_B(r,26),this):this.sk()?this.p=new Yx(_B(r,26),this):this.p=new Jx(_B(r,26),this):this.sk()?i?0!=(this.Bb&j9n)?this.p=new LB(_B(r,26),this,i):this.p=new IB(_B(r,26),this,i):0!=(this.Bb&j9n)?this.p=new eD(_B(r,26),this):this.p=new tD(_B(r,26),this):i?0!=(this.Bb&j9n)?this.p=new NB(_B(r,26),this,i):this.p=new CB(_B(r,26),this,i):0!=(this.Bb&j9n)?this.p=new iD(_B(r,26),this):this.p=new iG(_B(r,26),this)),this.p},EWn.Ij=function(){return 0!=(this.Bb&m6n)},EWn.qk=function(){return!1},EWn.rk=function(){return!1},EWn.Jj=function(){return 0!=(this.Bb&oVn)},EWn.Oj=function(){return onn(this)},EWn.sk=function(){return!1},EWn.Kj=function(){return 0!=(this.Bb&j9n)},EWn.tk=function(n){this.k=n},EWn.Lh=function(n){QZ(this,n)},EWn.Ib=function(){return kRn(this)},EWn.e=!1,EWn.n=0,gX(h6n,"EStructuralFeatureImpl",449),lAn(322,449,{105:1,92:1,90:1,34:1,147:1,191:1,56:1,170:1,66:1,108:1,472:1,49:1,97:1,322:1,150:1,449:1,284:1,114:1,115:1,677:1},Im),EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),!!$Cn(this);case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q;case 10:return oN(),0!=(this.Bb&m6n);case 11:return oN(),0!=(this.Bb&E9n);case 12:return oN(),0!=(this.Bb&RQn);case 13:return this.j;case 14:return BLn(this);case 15:return oN(),0!=(this.Bb&j9n);case 16:return oN(),0!=(this.Bb&oVn);case 17:return bZ(this);case 18:return oN(),0!=(this.Bb&o6n);case 19:return t?cun(this):L6(this)}return G9(this,n-fX((wWn(),n$t)),ttn(_B(van(this,16),26)||n$t,n),t,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return $Cn(this);case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i);case 10:return 0==(this.Bb&m6n);case 11:return 0!=(this.Bb&E9n);case 12:return 0!=(this.Bb&RQn);case 13:return null!=this.j;case 14:return null!=BLn(this);case 15:return 0!=(this.Bb&j9n);case 16:return 0!=(this.Bb&oVn);case 17:return!!bZ(this);case 18:return 0!=(this.Bb&o6n);case 19:return!!L6(this)}return I3(this,n-fX((wWn(),n$t)),ttn(_B(van(this,16),26)||n$t,n))},EWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void QZ(this,TD(t));case 2:return void Vfn(this,By(jD(t)));case 3:return void Yfn(this,By(jD(t)));case 4:return void Aen(this,_B(t,19).a);case 5:return void Gj(this,_B(t,19).a);case 8:return void Phn(this,_B(t,138));case 9:return void((e=FTn(this,_B(t,87),null))&&e.Fi());case 10:return void Cln(this,By(jD(t)));case 11:return void $ln(this,By(jD(t)));case 12:return void Oln(this,By(jD(t)));case 13:return void RC(this,TD(t));case 15:return void Aln(this,By(jD(t)));case 16:return void Bln(this,By(jD(t)));case 18:return void Hln(this,By(jD(t)))}Abn(this,n-fX((wWn(),n$t)),ttn(_B(van(this,16),26)||n$t,n),t)},EWn.zh=function(){return wWn(),n$t},EWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,88)&&CIn(M5(_B(this.Cb,88)),4),void $rn(this,null);case 2:return void Vfn(this,!0);case 3:return void Yfn(this,!0);case 4:return void Aen(this,0);case 5:return this.b=0,void $en(this,1);case 8:return void Phn(this,null);case 9:return void((t=FTn(this,null,null))&&t.Fi());case 10:return void Cln(this,!0);case 11:return void $ln(this,!1);case 12:return void Oln(this,!1);case 13:return this.i=null,void rrn(this,null);case 15:return void Aln(this,!1);case 16:return void Bln(this,!1);case 18:return void Hln(this,!1)}Bfn(this,n-fX((wWn(),n$t)),ttn(_B(van(this,16),26)||n$t,n))},EWn.Gh=function(){cun(this),mV(_7((PPn(),Q$t),this)),Pkn(this),this.Bb|=1},EWn.$j=function(){return $Cn(this)},EWn.nk=function(n,t){return this.b=0,this.a=null,Mfn(this,n,t)},EWn.ok=function(n){Gj(this,n)},EWn.Ib=function(){var n;return 0!=(64&this.Db)?kRn(this):((n=new sN(kRn(this))).a+=" (iD: ",vE(n,0!=(this.Bb&o6n)),n.a+=")",n.a)},EWn.b=0,gX(h6n,"EAttributeImpl",322),lAn(351,438,{105:1,92:1,90:1,138:1,147:1,191:1,56:1,108:1,49:1,97:1,351:1,150:1,114:1,115:1,676:1}),EWn.uk=function(n){return n.Tg()==this},EWn.Qg=function(n){return syn(this,n)},EWn.Rg=function(n,t){this.w=null,this.Db=t<<16|255&this.Db,this.Cb=n},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return tyn(this);case 4:return this.zj();case 5:return this.F;case 6:return t?Gtn(this):lZ(this);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),this.A}return G9(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?syn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,6,e)}return _B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Qj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 6:return j_n(this,null,6,e);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),Rpn(this.A,n,e)}return _B(ttn(_B(van(this,16),26)||this.zh(),t),66).Nj().Rj(this,sgn(this),t-fX(this.zh()),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!tyn(this);case 4:return null!=this.zj();case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!lZ(this);case 7:return!!this.A&&0!=this.A.i}return I3(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void JZ(this,TD(t));case 2:return void PA(this,TD(t));case 5:return void Vqn(this,TD(t));case 7:return!this.A&&(this.A=new $L(P$t,this,7)),uqn(this.A),!this.A&&(this.A=new $L(P$t,this,7)),void dX(this.A,_B(t,14))}Abn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n),t)},EWn.zh=function(){return wWn(),e$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,179)&&(_B(this.Cb,179).tb=null),void $rn(this,null);case 2:return Nsn(this,null),void Len(this,this.D);case 5:return void Vqn(this,null);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),void uqn(this.A)}Bfn(this,n-fX(this.zh()),ttn(_B(van(this,16),26)||this.zh(),n))},EWn.yj=function(){var n;return-1==this.G&&(this.G=(n=Gtn(this))?cvn(n.Mh(),this):-1),this.G},EWn.zj=function(){return null},EWn.Aj=function(){return Gtn(this)},EWn.vk=function(){return this.v},EWn.Bj=function(){return tyn(this)},EWn.Cj=function(){return null!=this.D?this.D:this.B},EWn.Dj=function(){return this.F},EWn.wj=function(n){return TFn(this,n)},EWn.wk=function(n){this.v=n},EWn.xk=function(n){Grn(this,n)},EWn.yk=function(n){this.C=n},EWn.Lh=function(n){JZ(this,n)},EWn.Ib=function(){return Swn(this)},EWn.C=null,EWn.D=null,EWn.G=-1,gX(h6n,"EClassifierImpl",351),lAn(88,351,{105:1,92:1,90:1,26:1,138:1,147:1,191:1,56:1,108:1,49:1,97:1,88:1,351:1,150:1,473:1,114:1,115:1,676:1},Rf),EWn.uk=function(n){return WR(this,n.Tg())},EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return null!=this.D?this.D:this.B;case 3:return tyn(this);case 4:return null;case 5:return this.F;case 6:return t?Gtn(this):lZ(this);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),this.A;case 8:return oN(),0!=(256&this.Bb);case 9:return oN(),0!=(512&this.Bb);case 10:return mJ(this);case 11:return!this.q&&(this.q=new nU(XAt,this,11,10)),this.q;case 12:return VBn(this);case 13:return xBn(this);case 14:return xBn(this),this.r;case 15:return VBn(this),this.k;case 16:return UPn(this);case 17:return wBn(this);case 18:return BFn(this);case 19:return SLn(this);case 20:return VBn(this),this.o;case 21:return!this.s&&(this.s=new nU(RAt,this,21,17)),this.s;case 22:return r4(this);case 23:return FDn(this)}return G9(this,n-fX((wWn(),t$t)),ttn(_B(van(this,16),26)||t$t,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 6:return this.Cb&&(e=(i=this.Db>>16)>=0?syn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,6,e);case 11:return!this.q&&(this.q=new nU(XAt,this,11,10)),Vwn(this.q,n,e);case 21:return!this.s&&(this.s=new nU(RAt,this,21,17)),Vwn(this.s,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),t$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),t$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 6:return j_n(this,null,6,e);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),Rpn(this.A,n,e);case 11:return!this.q&&(this.q=new nU(XAt,this,11,10)),Rpn(this.q,n,e);case 21:return!this.s&&(this.s=new nU(RAt,this,21,17)),Rpn(this.s,n,e);case 22:return Rpn(r4(this),n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),t$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),t$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!tyn(this);case 4:return!1;case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!lZ(this);case 7:return!!this.A&&0!=this.A.i;case 8:return 0!=(256&this.Bb);case 9:return 0!=(512&this.Bb);case 10:return!(!this.u||0==r4(this.u.a).i||this.n&&xvn(this.n));case 11:return!!this.q&&0!=this.q.i;case 12:return 0!=VBn(this).i;case 13:return 0!=xBn(this).i;case 14:return xBn(this),0!=this.r.i;case 15:return VBn(this),0!=this.k.i;case 16:return 0!=UPn(this).i;case 17:return 0!=wBn(this).i;case 18:return 0!=BFn(this).i;case 19:return 0!=SLn(this).i;case 20:return VBn(this),!!this.o;case 21:return!!this.s&&0!=this.s.i;case 22:return!!this.n&&xvn(this.n);case 23:return 0!=FDn(this).i}return I3(this,n-fX((wWn(),t$t)),ttn(_B(van(this,16),26)||t$t,n))},EWn.oh=function(n){return(null==this.i||this.q&&0!=this.q.i?null:$Nn(this,n))||oUn(this,n)},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void JZ(this,TD(t));case 2:return void PA(this,TD(t));case 5:return void Vqn(this,TD(t));case 7:return!this.A&&(this.A=new $L(P$t,this,7)),uqn(this.A),!this.A&&(this.A=new $L(P$t,this,7)),void dX(this.A,_B(t,14));case 8:return void Qfn(this,By(jD(t)));case 9:return void Zfn(this,By(jD(t)));case 10:return gqn(mJ(this)),void dX(mJ(this),_B(t,14));case 11:return!this.q&&(this.q=new nU(XAt,this,11,10)),uqn(this.q),!this.q&&(this.q=new nU(XAt,this,11,10)),void dX(this.q,_B(t,14));case 21:return!this.s&&(this.s=new nU(RAt,this,21,17)),uqn(this.s),!this.s&&(this.s=new nU(RAt,this,21,17)),void dX(this.s,_B(t,14));case 22:return uqn(r4(this)),void dX(r4(this),_B(t,14))}Abn(this,n-fX((wWn(),t$t)),ttn(_B(van(this,16),26)||t$t,n),t)},EWn.zh=function(){return wWn(),t$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,179)&&(_B(this.Cb,179).tb=null),void $rn(this,null);case 2:return Nsn(this,null),void Len(this,this.D);case 5:return void Vqn(this,null);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),void uqn(this.A);case 8:return void Qfn(this,!1);case 9:return void Zfn(this,!1);case 10:return void(this.u&&gqn(this.u));case 11:return!this.q&&(this.q=new nU(XAt,this,11,10)),void uqn(this.q);case 21:return!this.s&&(this.s=new nU(RAt,this,21,17)),void uqn(this.s);case 22:return void(this.n&&uqn(this.n))}Bfn(this,n-fX((wWn(),t$t)),ttn(_B(van(this,16),26)||t$t,n))},EWn.Gh=function(){var n,t;if(VBn(this),xBn(this),UPn(this),wBn(this),BFn(this),SLn(this),FDn(this),r6(zB(M5(this))),this.s)for(n=0,t=this.s.i;n=0;--t)Utn(this,t);return Wwn(this,n)},EWn.Xj=function(){uqn(this)},EWn.oi=function(n,t){return Ren(this,n,t)},gX(v9n,"EcoreEList",622),lAn(496,622,x9n,vH),EWn.ai=function(){return!1},EWn.aj=function(){return this.c},EWn.bj=function(){return!1},EWn.Fk=function(){return!0},EWn.hi=function(){return!0},EWn.li=function(n,t){return t},EWn.ni=function(){return!1},EWn.c=0,gX(v9n,"EObjectEList",496),lAn(85,496,x9n,OL),EWn.bj=function(){return!0},EWn.Dk=function(){return!1},EWn.rk=function(){return!0},gX(v9n,"EObjectContainmentEList",85),lAn(545,85,x9n,AL),EWn.ci=function(){this.b=!0},EWn.fj=function(){return this.b},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.b,this.b=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.b=!1},EWn.b=!1,gX(v9n,"EObjectContainmentEList/Unsettable",545),lAn(1140,545,x9n,VG),EWn.ii=function(n,t){var e,i;return e=_B(Pln(this,n,t),87),pA(this.e)&&Av(this,new y9(this.a,7,(wWn(),i$t),tln(t),iL(i=e.c,88)?_B(i,26):l$t,n)),e},EWn.jj=function(n,t){return Jwn(this,_B(n,87),t)},EWn.kj=function(n,t){return Qwn(this,_B(n,87),t)},EWn.lj=function(n,t,e){return Rjn(this,_B(n,87),_B(t,87),e)},EWn.Zi=function(n,t,e,i,r){switch(n){case 3:return vZ(this,n,t,e,i,this.i>1);case 5:return vZ(this,n,t,e,i,this.i-_B(e,15).gc()>0);default:return new $7(this.e,n,this.c,t,e,i,!0)}},EWn.ij=function(){return!0},EWn.fj=function(){return xvn(this)},EWn.Xj=function(){uqn(this)},gX(h6n,"EClassImpl/1",1140),lAn(1154,1153,J8n),EWn.ui=function(n){var t,e,i,r,c,a,u;if(8!=(e=n.xi())){if(0==(i=rpn(n)))switch(e){case 1:case 9:null!=(u=n.Bi())&&(!(t=M5(_B(u,473))).c&&(t.c=new Bo),unn(t.c,n.Ai())),null!=(a=n.zi())&&0==(1&(r=_B(a,473)).Bb)&&(!(t=M5(r)).c&&(t.c=new Bo),s9(t.c,_B(n.Ai(),26)));break;case 3:null!=(a=n.zi())&&0==(1&(r=_B(a,473)).Bb)&&(!(t=M5(r)).c&&(t.c=new Bo),s9(t.c,_B(n.Ai(),26)));break;case 5:if(null!=(a=n.zi()))for(c=_B(a,14).Kc();c.Ob();)0==(1&(r=_B(c.Pb(),473)).Bb)&&(!(t=M5(r)).c&&(t.c=new Bo),s9(t.c,_B(n.Ai(),26)));break;case 4:null!=(u=n.Bi())&&0==(1&(r=_B(u,473)).Bb)&&(!(t=M5(r)).c&&(t.c=new Bo),unn(t.c,n.Ai()));break;case 6:if(null!=(u=n.Bi()))for(c=_B(u,14).Kc();c.Ob();)0==(1&(r=_B(c.Pb(),473)).Bb)&&(!(t=M5(r)).c&&(t.c=new Bo),unn(t.c,n.Ai()))}this.Hk(i)}},EWn.Hk=function(n){bRn(this,n)},EWn.b=63,gX(h6n,"ESuperAdapter",1154),lAn(1155,1154,J8n,bp),EWn.Hk=function(n){CIn(this,n)},gX(h6n,"EClassImpl/10",1155),lAn(1144,696,x9n),EWn.Vh=function(n,t){return _Tn(this,n,t)},EWn.Wh=function(n){return fmn(this,n)},EWn.Xh=function(n,t){Pfn(this,n,t)},EWn.Yh=function(n){i6(this,n)},EWn.pi=function(n){return K9(this,n)},EWn.mi=function(n,t){return ann(this,n,t)},EWn.lk=function(n,t){throw Fp(new dv)},EWn.Zh=function(){return new rx(this)},EWn.$h=function(){return new cx(this)},EWn._h=function(n){return uin(this,n)},EWn.mk=function(n,t){throw Fp(new dv)},EWn.Wj=function(n){return this},EWn.fj=function(){return 0!=this.i},EWn.Wb=function(n){throw Fp(new dv)},EWn.Xj=function(){throw Fp(new dv)},gX(v9n,"EcoreEList/UnmodifiableEList",1144),lAn(319,1144,x9n,$O),EWn.ni=function(){return!1},gX(v9n,"EcoreEList/UnmodifiableEList/FastCompare",319),lAn(1147,319,x9n,bon),EWn.Xc=function(n){var t,e;if(iL(n,170)&&-1!=(t=_B(n,170).aj()))for(e=this.i;t4){if(!this.wj(n))return!1;if(this.rk()){if(a=(t=(e=_B(n,49)).Ug())==this.b&&(this.Dk()?e.Og(e.Vg(),_B(ttn(yJ(this.b),this.aj()).Yj(),26).Bj())==Svn(_B(ttn(yJ(this.b),this.aj()),18)).n:-1-e.Vg()==this.aj()),this.Ek()&&!a&&!t&&e.Zg())for(i=0;i1||-1==e)},EWn.Dk=function(){var n;return!!iL(n=ttn(yJ(this.b),this.aj()),99)&&!!Svn(_B(n,18))},EWn.Ek=function(){var n;return!!iL(n=ttn(yJ(this.b),this.aj()),99)&&0!=(_B(n,18).Bb&_Qn)},EWn.Xc=function(n){var t,e,i;if((e=this.Qi(n))>=0)return e;if(this.Fk())for(t=0,i=this.Vi();t=0;--n)nGn(this,n,this.Oi(n));return this.Wi()},EWn.Qc=function(n){var t;if(this.Ek())for(t=this.Vi()-1;t>=0;--t)nGn(this,t,this.Oi(t));return this.Xi(n)},EWn.Xj=function(){gqn(this)},EWn.oi=function(n,t){return _9(this,n,t)},gX(v9n,"DelegatingEcoreEList",742),lAn(1150,742,F9n,cR),EWn.Hi=function(n,t){hD(this,n,_B(t,26))},EWn.Ii=function(n){n$(this,_B(n,26))},EWn.Oi=function(n){var t;return iL(t=_B(Utn(r4(this.a),n),87).c,88)?_B(t,26):(wWn(),l$t)},EWn.Ti=function(n){var t;return iL(t=_B(sDn(r4(this.a),n),87).c,88)?_B(t,26):(wWn(),l$t)},EWn.Ui=function(n,t){return bmn(this,n,_B(t,26))},EWn.ai=function(){return!1},EWn.Zi=function(n,t,e,i,r){return null},EWn.Ji=function(){return new dp(this)},EWn.Ki=function(){uqn(r4(this.a))},EWn.Li=function(n){return Gfn(this,n)},EWn.Mi=function(n){var t;for(t=n.Kc();t.Ob();)if(!Gfn(this,t.Pb()))return!1;return!0},EWn.Ni=function(n){var t,e,i;if(iL(n,15)&&(i=_B(n,15)).gc()==r4(this.a).i){for(t=i.Kc(),e=new CL(this);t.Ob();)if(HC(t.Pb())!==HC(mpn(e)))return!1;return!0}return!1},EWn.Pi=function(){var n,t,e,i;for(t=1,n=new CL(r4(this.a));n.e!=n.i.gc();)t=31*t+((e=iL(i=_B(mpn(n),87).c,88)?_B(i,26):(wWn(),l$t))?MN(e):0);return t},EWn.Qi=function(n){var t,e,i,r;for(i=0,e=new CL(r4(this.a));e.e!=e.i.gc();){if(t=_B(mpn(e),87),HC(n)===HC(iL(r=t.c,88)?_B(r,26):(wWn(),l$t)))return i;++i}return-1},EWn.Ri=function(){return 0==r4(this.a).i},EWn.Si=function(){return null},EWn.Vi=function(){return r4(this.a).i},EWn.Wi=function(){var n,t,e,i,r,c;for(c=r4(this.a).i,r=L8(Cnt,FWn,1,c,5,1),e=0,t=new CL(r4(this.a));t.e!=t.i.gc();)n=_B(mpn(t),87),r[e++]=iL(i=n.c,88)?_B(i,26):(wWn(),l$t);return r},EWn.Xi=function(n){var t,e,i,r;for(r=r4(this.a).i,n.lengthr&&OX(n,r,null),e=0,t=new CL(r4(this.a));t.e!=t.i.gc();)OX(n,e++,iL(i=_B(mpn(t),87).c,88)?_B(i,26):(wWn(),l$t));return n},EWn.Yi=function(){var n,t,e,i,r;for((r=new Tk).a+="[",n=r4(this.a),t=0,i=r4(this.a).i;t>16)>=0?syn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,6,e);case 9:return!this.a&&(this.a=new nU(zAt,this,9,5)),Vwn(this.a,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),c$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),c$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 6:return j_n(this,null,6,e);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),Rpn(this.A,n,e);case 9:return!this.a&&(this.a=new nU(zAt,this,9,5)),Rpn(this.a,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),c$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),c$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return null!=this.D&&this.D==this.F;case 3:return!!tyn(this);case 4:return!!Wsn(this);case 5:return null!=this.F&&this.F!=this.D&&this.F!=this.B;case 6:return!!lZ(this);case 7:return!!this.A&&0!=this.A.i;case 8:return 0==(256&this.Bb);case 9:return!!this.a&&0!=this.a.i}return I3(this,n-fX((wWn(),c$t)),ttn(_B(van(this,16),26)||c$t,n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void JZ(this,TD(t));case 2:return void PA(this,TD(t));case 5:return void Vqn(this,TD(t));case 7:return!this.A&&(this.A=new $L(P$t,this,7)),uqn(this.A),!this.A&&(this.A=new $L(P$t,this,7)),void dX(this.A,_B(t,14));case 8:return void Jfn(this,By(jD(t)));case 9:return!this.a&&(this.a=new nU(zAt,this,9,5)),uqn(this.a),!this.a&&(this.a=new nU(zAt,this,9,5)),void dX(this.a,_B(t,14))}Abn(this,n-fX((wWn(),c$t)),ttn(_B(van(this,16),26)||c$t,n),t)},EWn.zh=function(){return wWn(),c$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,179)&&(_B(this.Cb,179).tb=null),void $rn(this,null);case 2:return Nsn(this,null),void Len(this,this.D);case 5:return void Vqn(this,null);case 7:return!this.A&&(this.A=new $L(P$t,this,7)),void uqn(this.A);case 8:return void Jfn(this,!0);case 9:return!this.a&&(this.a=new nU(zAt,this,9,5)),void uqn(this.a)}Bfn(this,n-fX((wWn(),c$t)),ttn(_B(van(this,16),26)||c$t,n))},EWn.Gh=function(){var n,t;if(this.a)for(n=0,t=this.a.i;n>16==5?_B(this.Cb,671):null}return G9(this,n-fX((wWn(),a$t)),ttn(_B(van(this,16),26)||a$t,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 5:return this.Cb&&(e=(i=this.Db>>16)>=0?hkn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,5,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),a$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),a$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 5:return j_n(this,null,5,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),a$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),a$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0!=this.d;case 3:return!!this.b;case 4:return null!=this.c;case 5:return!(this.Db>>16!=5||!_B(this.Cb,671))}return I3(this,n-fX((wWn(),a$t)),ttn(_B(van(this,16),26)||a$t,n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void $rn(this,TD(t));case 2:return void Oen(this,_B(t,19).a);case 3:return void wOn(this,_B(t,1940));case 4:return void Kin(this,TD(t))}Abn(this,n-fX((wWn(),a$t)),ttn(_B(van(this,16),26)||a$t,n),t)},EWn.zh=function(){return wWn(),a$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void $rn(this,null);case 2:return void Oen(this,0);case 3:return void wOn(this,null);case 4:return void Kin(this,null)}Bfn(this,n-fX((wWn(),a$t)),ttn(_B(van(this,16),26)||a$t,n))},EWn.Ib=function(){var n;return null==(n=this.c)?this.zb:n},EWn.b=null,EWn.c=null,EWn.d=0,gX(h6n,"EEnumLiteralImpl",573);var O$t,A$t,$$t,L$t=fq(h6n,"EFactoryImpl/InternalEDateTimeFormat");lAn(489,1,{2015:1},gp),gX(h6n,"EFactoryImpl/1ClientInternalEDateTimeFormat",489),lAn(241,115,{105:1,92:1,90:1,87:1,56:1,108:1,49:1,97:1,241:1,114:1,115:1},Dp),EWn.Sg=function(n,t,e){var i;return e=j_n(this,n,t,e),this.e&&iL(n,170)&&(i=mLn(this,this.e))!=this.c&&(e=rzn(this,i,e)),e},EWn._g=function(n,t,e){switch(n){case 0:return this.f;case 1:return!this.d&&(this.d=new OL(UAt,this,1)),this.d;case 2:return t?hFn(this):this.c;case 3:return this.b;case 4:return this.e;case 5:return t?Bvn(this):this.a}return G9(this,n-fX((wWn(),o$t)),ttn(_B(van(this,16),26)||o$t,n),t,e)},EWn.jh=function(n,t,e){switch(t){case 0:return Yhn(this,null,e);case 1:return!this.d&&(this.d=new OL(UAt,this,1)),Rpn(this.d,n,e);case 3:return Jhn(this,null,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),o$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),o$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.f;case 1:return!!this.d&&0!=this.d.i;case 2:return!!this.c;case 3:return!!this.b;case 4:return!!this.e;case 5:return!!this.a}return I3(this,n-fX((wWn(),o$t)),ttn(_B(van(this,16),26)||o$t,n))},EWn.sh=function(n,t){switch(n){case 0:return void yEn(this,_B(t,87));case 1:return!this.d&&(this.d=new OL(UAt,this,1)),uqn(this.d),!this.d&&(this.d=new OL(UAt,this,1)),void dX(this.d,_B(t,14));case 3:return void mEn(this,_B(t,87));case 4:return void NMn(this,_B(t,836));case 5:return void ien(this,_B(t,138))}Abn(this,n-fX((wWn(),o$t)),ttn(_B(van(this,16),26)||o$t,n),t)},EWn.zh=function(){return wWn(),o$t},EWn.Bh=function(n){switch(n){case 0:return void yEn(this,null);case 1:return!this.d&&(this.d=new OL(UAt,this,1)),void uqn(this.d);case 3:return void mEn(this,null);case 4:return void NMn(this,null);case 5:return void ien(this,null)}Bfn(this,n-fX((wWn(),o$t)),ttn(_B(van(this,16),26)||o$t,n))},EWn.Ib=function(){var n;return(n=new hN(M$n(this))).a+=" (expression: ",fHn(this,n),n.a+=")",n.a},gX(h6n,"EGenericTypeImpl",241),lAn(1969,1964,B9n),EWn.Xh=function(n,t){YD(this,n,t)},EWn.lk=function(n,t){return YD(this,this.gc(),n),t},EWn.pi=function(n){return Npn(this.Gi(),n)},EWn.Zh=function(){return this.$h()},EWn.Gi=function(){return new Mp(this)},EWn.$h=function(){return this._h(0)},EWn._h=function(n){return this.Gi().Zc(n)},EWn.mk=function(n,t){return vwn(this,n,!0),t},EWn.ii=function(n,t){var e;return e=Zyn(this,t),this.Zc(n).Rb(e),e},EWn.ji=function(n,t){vwn(this,t,!0),this.Zc(n).Rb(t)},gX(v9n,"AbstractSequentialInternalEList",1969),lAn(486,1969,B9n,WN),EWn.pi=function(n){return Npn(this.Gi(),n)},EWn.Zh=function(){return null==this.b?(VM(),VM(),$$t):this.Jk()},EWn.Gi=function(){return new NO(this.a,this.b)},EWn.$h=function(){return null==this.b?(VM(),VM(),$$t):this.Jk()},EWn._h=function(n){var t,e;if(null==this.b){if(n<0||n>1)throw Fp(new Cy(n9n+n+", size=0"));return VM(),VM(),$$t}for(e=this.Jk(),t=0;t0;)if(t=this.c[--this.d],(!this.e||t.Gj()!=AOt||0!=t.aj())&&(!this.Mk()||this.b.mh(t)))if(c=this.b.bh(t,this.Lk()),this.f=(JM(),_B(t,66).Oj()),this.f||t.$j()){if(this.Lk()?(i=_B(c,15),this.k=i):(i=_B(c,69),this.k=this.j=i),iL(this.k,54)?(this.o=this.k.gc(),this.n=this.o):this.p=this.j?this.j._h(this.k.gc()):this.k.Zc(this.k.gc()),this.p?yPn(this,this.p):lIn(this))return r=this.p?this.p.Ub():this.j?this.j.pi(--this.n):this.k.Xb(--this.n),this.f?((n=_B(r,72)).ak(),e=n.dd(),this.i=e):(e=r,this.i=e),this.g=-3,!0}else if(null!=c)return this.k=null,this.p=null,e=c,this.i=e,this.g=-2,!0;return this.k=null,this.p=null,this.g=-1,!1}},EWn.Pb=function(){return Ean(this)},EWn.Tb=function(){return this.a},EWn.Ub=function(){var n;if(this.g<-1||this.Sb())return--this.a,this.g=0,n=this.i,this.Sb(),n;throw Fp(new vv)},EWn.Vb=function(){return this.a-1},EWn.Qb=function(){throw Fp(new dv)},EWn.Lk=function(){return!1},EWn.Wb=function(n){throw Fp(new dv)},EWn.Mk=function(){return!0},EWn.a=0,EWn.d=0,EWn.f=!1,EWn.g=0,EWn.n=0,EWn.o=0,gX(v9n,"EContentsEList/FeatureIteratorImpl",279),lAn(697,279,H9n,Xx),EWn.Lk=function(){return!0},gX(v9n,"EContentsEList/ResolvingFeatureIteratorImpl",697),lAn(1157,697,H9n,Vx),EWn.Mk=function(){return!1},gX(h6n,"ENamedElementImpl/1/1",1157),lAn(1158,279,H9n,Wx),EWn.Mk=function(){return!1},gX(h6n,"ENamedElementImpl/1/2",1158),lAn(36,143,Z8n,s4,h4,Yz,m9,$7,Z5,Fen,T0,Ben,M0,Q5,S0,Gen,P0,J5,I0,Hen,C0,Zz,y9,HQ,qen,O0,Y5,A0),EWn._i=function(){return o9(this)},EWn.gj=function(){var n;return(n=o9(this))?n.zj():null},EWn.yi=function(n){return-1==this.b&&this.a&&(this.b=this.c.Xg(this.a.aj(),this.a.Gj())),this.c.Og(this.b,n)},EWn.Ai=function(){return this.c},EWn.hj=function(){var n;return!!(n=o9(this))&&n.Kj()},EWn.b=-1,gX(h6n,"ENotificationImpl",36),lAn(399,284,{105:1,92:1,90:1,147:1,191:1,56:1,59:1,108:1,472:1,49:1,97:1,150:1,399:1,284:1,114:1,115:1},Om),EWn.Qg=function(n){return Mkn(this,n)},EWn._g=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),(i=this.t)>1||-1==i;case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?_B(this.Cb,26):null;case 11:return!this.d&&(this.d=new $L(P$t,this,11)),this.d;case 12:return!this.c&&(this.c=new nU(WAt,this,12,10)),this.c;case 13:return!this.a&&(this.a=new aR(this,this)),this.a;case 14:return F7(this)}return G9(this,n-fX((wWn(),b$t)),ttn(_B(van(this,16),26)||b$t,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?Mkn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,10,e);case 12:return!this.c&&(this.c=new nU(WAt,this,12,10)),Vwn(this.c,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),b$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),b$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 9:return wX(this,e);case 10:return j_n(this,null,10,e);case 11:return!this.d&&(this.d=new $L(P$t,this,11)),Rpn(this.d,n,e);case 12:return!this.c&&(this.c=new nU(WAt,this,12,10)),Rpn(this.c,n,e);case 14:return Rpn(F7(this),n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),b$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),b$t)),n,e)},EWn.lh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i);case 10:return!(this.Db>>16!=10||!_B(this.Cb,26));case 11:return!!this.d&&0!=this.d.i;case 12:return!!this.c&&0!=this.c.i;case 13:return!(!this.a||0==F7(this.a.a).i||this.b&&Dvn(this.b));case 14:return!!this.b&&Dvn(this.b)}return I3(this,n-fX((wWn(),b$t)),ttn(_B(van(this,16),26)||b$t,n))},EWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void $rn(this,TD(t));case 2:return void Vfn(this,By(jD(t)));case 3:return void Yfn(this,By(jD(t)));case 4:return void Aen(this,_B(t,19).a);case 5:return void $en(this,_B(t,19).a);case 8:return void Phn(this,_B(t,138));case 9:return void((e=FTn(this,_B(t,87),null))&&e.Fi());case 11:return!this.d&&(this.d=new $L(P$t,this,11)),uqn(this.d),!this.d&&(this.d=new $L(P$t,this,11)),void dX(this.d,_B(t,14));case 12:return!this.c&&(this.c=new nU(WAt,this,12,10)),uqn(this.c),!this.c&&(this.c=new nU(WAt,this,12,10)),void dX(this.c,_B(t,14));case 13:return!this.a&&(this.a=new aR(this,this)),gqn(this.a),!this.a&&(this.a=new aR(this,this)),void dX(this.a,_B(t,14));case 14:return uqn(F7(this)),void dX(F7(this),_B(t,14))}Abn(this,n-fX((wWn(),b$t)),ttn(_B(van(this,16),26)||b$t,n),t)},EWn.zh=function(){return wWn(),b$t},EWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void $rn(this,null);case 2:return void Vfn(this,!0);case 3:return void Yfn(this,!0);case 4:return void Aen(this,0);case 5:return void $en(this,1);case 8:return void Phn(this,null);case 9:return void((t=FTn(this,null,null))&&t.Fi());case 11:return!this.d&&(this.d=new $L(P$t,this,11)),void uqn(this.d);case 12:return!this.c&&(this.c=new nU(WAt,this,12,10)),void uqn(this.c);case 13:return void(this.a&&gqn(this.a));case 14:return void(this.b&&uqn(this.b))}Bfn(this,n-fX((wWn(),b$t)),ttn(_B(van(this,16),26)||b$t,n))},EWn.Gh=function(){var n,t;if(this.c)for(n=0,t=this.c.i;ni&&OX(n,i,null),e=0,t=new CL(F7(this.a));t.e!=t.i.gc();)OX(n,e++,_B(mpn(t),87).c||(wWn(),s$t));return n},EWn.Yi=function(){var n,t,e,i;for((i=new Tk).a+="[",n=F7(this.a),t=0,e=F7(this.a).i;t1);case 5:return vZ(this,n,t,e,i,this.i-_B(e,15).gc()>0);default:return new $7(this.e,n,this.c,t,e,i,!0)}},EWn.ij=function(){return!0},EWn.fj=function(){return Dvn(this)},EWn.Xj=function(){uqn(this)},gX(h6n,"EOperationImpl/2",1341),lAn(498,1,{1938:1,498:1},IC),gX(h6n,"EPackageImpl/1",498),lAn(16,85,x9n,nU),EWn.zk=function(){return this.d},EWn.Ak=function(){return this.b},EWn.Dk=function(){return!0},EWn.b=0,gX(v9n,"EObjectContainmentWithInverseEList",16),lAn(353,16,x9n,nK),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectContainmentWithInverseEList/Resolving",353),lAn(298,353,x9n,Qz),EWn.ci=function(){this.a.tb=null},gX(h6n,"EPackageImpl/2",298),lAn(1228,1,{},Oo),gX(h6n,"EPackageImpl/3",1228),lAn(718,43,ZQn,$m),EWn._b=function(n){return zC(n)?nJ(this,n):!!CJ(this.f,n)},gX(h6n,"EPackageRegistryImpl",718),lAn(509,284,{105:1,92:1,90:1,147:1,191:1,56:1,2017:1,108:1,472:1,49:1,97:1,150:1,509:1,284:1,114:1,115:1},Am),EWn.Qg=function(n){return Skn(this,n)},EWn._g=function(n,t,e){var i;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),(i=this.t)>1||-1==i;case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q;case 10:return this.Db>>16==10?_B(this.Cb,59):null}return G9(this,n-fX((wWn(),g$t)),ttn(_B(van(this,16),26)||g$t,n),t,e)},EWn.hh=function(n,t,e){var i;switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Vwn(this.Ab,n,e);case 10:return this.Cb&&(e=(i=this.Db>>16)>=0?Skn(this,e):this.Cb.ih(this,-1-i,null,e)),j_n(this,n,10,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),g$t),t),66).Nj().Qj(this,sgn(this),t-fX((wWn(),g$t)),n,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 9:return wX(this,e);case 10:return j_n(this,null,10,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),g$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),g$t)),n,e)},EWn.lh=function(n){var t;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(t=this.t)>1||-1==t;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i);case 10:return!(this.Db>>16!=10||!_B(this.Cb,59))}return I3(this,n-fX((wWn(),g$t)),ttn(_B(van(this,16),26)||g$t,n))},EWn.zh=function(){return wWn(),g$t},gX(h6n,"EParameterImpl",509),lAn(99,449,{105:1,92:1,90:1,147:1,191:1,56:1,18:1,170:1,66:1,108:1,472:1,49:1,97:1,150:1,99:1,449:1,284:1,114:1,115:1,677:1},dD),EWn._g=function(n,t,e){var i,r;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return oN(),0!=(256&this.Bb);case 3:return oN(),0!=(512&this.Bb);case 4:return tln(this.s);case 5:return tln(this.t);case 6:return oN(),(r=this.t)>1||-1==r;case 7:return oN(),this.s>=1;case 8:return t?Pkn(this):this.r;case 9:return this.q;case 10:return oN(),0!=(this.Bb&m6n);case 11:return oN(),0!=(this.Bb&E9n);case 12:return oN(),0!=(this.Bb&RQn);case 13:return this.j;case 14:return BLn(this);case 15:return oN(),0!=(this.Bb&j9n);case 16:return oN(),0!=(this.Bb&oVn);case 17:return bZ(this);case 18:return oN(),0!=(this.Bb&o6n);case 19:return oN(),!(!(i=Svn(this))||0==(i.Bb&o6n));case 20:return oN(),0!=(this.Bb&_Qn);case 21:return t?Svn(this):this.b;case 22:return t?Pon(this):D5(this);case 23:return!this.a&&(this.a=new xL(KAt,this,23)),this.a}return G9(this,n-fX((wWn(),p$t)),ttn(_B(van(this,16),26)||p$t,n),t,e)},EWn.lh=function(n){var t,e;switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return 0==(256&this.Bb);case 3:return 0==(512&this.Bb);case 4:return 0!=this.s;case 5:return 1!=this.t;case 6:return(e=this.t)>1||-1==e;case 7:return this.s>=1;case 8:return!!this.r&&!this.q.e&&0==vW(this.q).i;case 9:return!(!this.q||this.r&&!this.q.e&&0==vW(this.q).i);case 10:return 0==(this.Bb&m6n);case 11:return 0!=(this.Bb&E9n);case 12:return 0!=(this.Bb&RQn);case 13:return null!=this.j;case 14:return null!=BLn(this);case 15:return 0!=(this.Bb&j9n);case 16:return 0!=(this.Bb&oVn);case 17:return!!bZ(this);case 18:return 0!=(this.Bb&o6n);case 19:return!!(t=Svn(this))&&0!=(t.Bb&o6n);case 20:return 0==(this.Bb&_Qn);case 21:return!!this.b;case 22:return!!D5(this);case 23:return!!this.a&&0!=this.a.i}return I3(this,n-fX((wWn(),p$t)),ttn(_B(van(this,16),26)||p$t,n))},EWn.sh=function(n,t){var e;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void QZ(this,TD(t));case 2:return void Vfn(this,By(jD(t)));case 3:return void Yfn(this,By(jD(t)));case 4:return void Aen(this,_B(t,19).a);case 5:return void $en(this,_B(t,19).a);case 8:return void Phn(this,_B(t,138));case 9:return void((e=FTn(this,_B(t,87),null))&&e.Fi());case 10:return void Cln(this,By(jD(t)));case 11:return void $ln(this,By(jD(t)));case 12:return void Oln(this,By(jD(t)));case 13:return void RC(this,TD(t));case 15:return void Aln(this,By(jD(t)));case 16:return void Bln(this,By(jD(t)));case 18:return void VZ(this,By(jD(t)));case 20:return void Gln(this,By(jD(t)));case 21:return void ern(this,_B(t,18));case 23:return!this.a&&(this.a=new xL(KAt,this,23)),uqn(this.a),!this.a&&(this.a=new xL(KAt,this,23)),void dX(this.a,_B(t,14))}Abn(this,n-fX((wWn(),p$t)),ttn(_B(van(this,16),26)||p$t,n),t)},EWn.zh=function(){return wWn(),p$t},EWn.Bh=function(n){var t;switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return iL(this.Cb,88)&&CIn(M5(_B(this.Cb,88)),4),void $rn(this,null);case 2:return void Vfn(this,!0);case 3:return void Yfn(this,!0);case 4:return void Aen(this,0);case 5:return void $en(this,1);case 8:return void Phn(this,null);case 9:return void((t=FTn(this,null,null))&&t.Fi());case 10:return void Cln(this,!0);case 11:return void $ln(this,!1);case 12:return void Oln(this,!1);case 13:return this.i=null,void rrn(this,null);case 15:return void Aln(this,!1);case 16:return void Bln(this,!1);case 18:return qln(this,!1),void(iL(this.Cb,88)&&CIn(M5(_B(this.Cb,88)),2));case 20:return void Gln(this,!0);case 21:return void ern(this,null);case 23:return!this.a&&(this.a=new xL(KAt,this,23)),void uqn(this.a)}Bfn(this,n-fX((wWn(),p$t)),ttn(_B(van(this,16),26)||p$t,n))},EWn.Gh=function(){Pon(this),mV(_7((PPn(),Q$t),this)),Pkn(this),this.Bb|=1},EWn.Lj=function(){return Svn(this)},EWn.qk=function(){var n;return!!(n=Svn(this))&&0!=(n.Bb&o6n)},EWn.rk=function(){return 0!=(this.Bb&o6n)},EWn.sk=function(){return 0!=(this.Bb&_Qn)},EWn.nk=function(n,t){return this.c=null,Mfn(this,n,t)},EWn.Ib=function(){var n;return 0!=(64&this.Db)?kRn(this):((n=new sN(kRn(this))).a+=" (containment: ",vE(n,0!=(this.Bb&o6n)),n.a+=", resolveProxies: ",vE(n,0!=(this.Bb&_Qn)),n.a+=")",n.a)},gX(h6n,"EReferenceImpl",99),lAn(548,115,{105:1,42:1,92:1,90:1,133:1,56:1,108:1,49:1,97:1,548:1,114:1,115:1},Ao),EWn.Fb=function(n){return this===n},EWn.cd=function(){return this.b},EWn.dd=function(){return this.c},EWn.Hb=function(){return MN(this)},EWn.Uh=function(n){gq(this,TD(n))},EWn.ed=function(n){return OH(this,TD(n))},EWn._g=function(n,t,e){switch(n){case 0:return this.b;case 1:return this.c}return G9(this,n-fX((wWn(),v$t)),ttn(_B(van(this,16),26)||v$t,n),t,e)},EWn.lh=function(n){switch(n){case 0:return null!=this.b;case 1:return null!=this.c}return I3(this,n-fX((wWn(),v$t)),ttn(_B(van(this,16),26)||v$t,n))},EWn.sh=function(n,t){switch(n){case 0:return void pq(this,TD(t));case 1:return void Din(this,TD(t))}Abn(this,n-fX((wWn(),v$t)),ttn(_B(van(this,16),26)||v$t,n),t)},EWn.zh=function(){return wWn(),v$t},EWn.Bh=function(n){switch(n){case 0:return void xin(this,null);case 1:return void Din(this,null)}Bfn(this,n-fX((wWn(),v$t)),ttn(_B(van(this,16),26)||v$t,n))},EWn.Sh=function(){var n;return-1==this.a&&(n=this.b,this.a=null==n?0:gvn(n)),this.a},EWn.Th=function(n){this.a=n},EWn.Ib=function(){var n;return 0!=(64&this.Db)?M$n(this):((n=new sN(M$n(this))).a+=" (key: ",iO(n,this.b),n.a+=", value: ",iO(n,this.c),n.a+=")",n.a)},EWn.a=-1,EWn.b=null,EWn.c=null;var N$t,x$t,D$t,R$t,K$t,_$t,F$t,B$t,H$t,q$t,G$t=gX(h6n,"EStringToStringMapEntryImpl",548),z$t=fq(v9n,"FeatureMap/Entry/Internal");lAn(565,1,q9n),EWn.Ok=function(n){return this.Pk(_B(n,49))},EWn.Pk=function(n){return this.Ok(n)},EWn.Fb=function(n){var t,e;return this===n||!!iL(n,72)&&(t=_B(n,72)).ak()==this.c&&(null==(e=this.dd())?null==t.dd():$fn(e,t.dd()))},EWn.ak=function(){return this.c},EWn.Hb=function(){var n;return n=this.dd(),Yon(this.c)^(null==n?0:Yon(n))},EWn.Ib=function(){var n,t;return t=Gtn((n=this.c).Hj()).Ph(),n.ne(),(null!=t&&0!=t.length?t+":"+n.ne():n.ne())+"="+this.dd()},gX(h6n,"EStructuralFeatureImpl/BasicFeatureMapEntry",565),lAn(776,565,q9n,eR),EWn.Pk=function(n){return new eR(this.c,n)},EWn.dd=function(){return this.a},EWn.Qk=function(n,t,e){return Tcn(this,n,this.a,t,e)},EWn.Rk=function(n,t,e){return Mcn(this,n,this.a,t,e)},gX(h6n,"EStructuralFeatureImpl/ContainmentUpdatingFeatureMapEntry",776),lAn(1314,1,{},CC),EWn.Pj=function(n,t,e,i,r){return _B(T9(n,this.b),215).nl(this.a).Wj(i)},EWn.Qj=function(n,t,e,i,r){return _B(T9(n,this.b),215).el(this.a,i,r)},EWn.Rj=function(n,t,e,i,r){return _B(T9(n,this.b),215).fl(this.a,i,r)},EWn.Sj=function(n,t,e){return _B(T9(n,this.b),215).nl(this.a).fj()},EWn.Tj=function(n,t,e,i){_B(T9(n,this.b),215).nl(this.a).Wb(i)},EWn.Uj=function(n,t,e){return _B(T9(n,this.b),215).nl(this.a)},EWn.Vj=function(n,t,e){_B(T9(n,this.b),215).nl(this.a).Xj()},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateFeatureMapDelegator",1314),lAn(89,1,{},MB,hQ,xJ,l4),EWn.Pj=function(n,t,e,i,r){var c;if(null==(c=t.Ch(e))&&t.Dh(e,c=tWn(this,n)),!r)switch(this.e){case 50:case 41:return _B(c,589).sj();case 40:return _B(c,215).kl()}return c},EWn.Qj=function(n,t,e,i,r){var c;return null==(c=t.Ch(e))&&t.Dh(e,c=tWn(this,n)),_B(c,69).lk(i,r)},EWn.Rj=function(n,t,e,i,r){var c;return null!=(c=t.Ch(e))&&(r=_B(c,69).mk(i,r)),r},EWn.Sj=function(n,t,e){var i;return null!=(i=t.Ch(e))&&_B(i,76).fj()},EWn.Tj=function(n,t,e,i){var r;!(r=_B(t.Ch(e),76))&&t.Dh(e,r=tWn(this,n)),r.Wb(i)},EWn.Uj=function(n,t,e){var i;return null==(i=t.Ch(e))&&t.Dh(e,i=tWn(this,n)),iL(i,76)?_B(i,76):new kp(_B(t.Ch(e),15))},EWn.Vj=function(n,t,e){var i;!(i=_B(t.Ch(e),76))&&t.Dh(e,i=tWn(this,n)),i.Xj()},EWn.b=0,EWn.e=0,gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateMany",89),lAn(504,1,{}),EWn.Qj=function(n,t,e,i,r){throw Fp(new dv)},EWn.Rj=function(n,t,e,i,r){throw Fp(new dv)},EWn.Uj=function(n,t,e){return new fQ(this,n,t,e)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingle",504),lAn(1331,1,m9n,fQ),EWn.Wj=function(n){return this.a.Pj(this.c,this.d,this.b,n,!0)},EWn.fj=function(){return this.a.Sj(this.c,this.d,this.b)},EWn.Wb=function(n){this.a.Tj(this.c,this.d,this.b,n)},EWn.Xj=function(){this.a.Vj(this.c,this.d,this.b)},EWn.b=0,gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingle/1",1331),lAn(769,504,{},pY),EWn.Pj=function(n,t,e,i,r){return wKn(n,n.eh(),n.Vg())==this.b?this.sk()&&i?iAn(n):n.eh():null},EWn.Qj=function(n,t,e,i,r){var c,a;return n.eh()&&(r=(c=n.Vg())>=0?n.Qg(r):n.eh().ih(n,-1-c,null,r)),a=Cwn(n.Tg(),this.e),n.Sg(i,a,r)},EWn.Rj=function(n,t,e,i,r){var c;return c=Cwn(n.Tg(),this.e),n.Sg(null,c,r)},EWn.Sj=function(n,t,e){var i;return i=Cwn(n.Tg(),this.e),!!n.eh()&&n.Vg()==i},EWn.Tj=function(n,t,e,i){var r,c,a,u,o;if(null!=i&&!TFn(this.a,i))throw Fp(new Dy(G9n+(iL(i,56)?bEn(_B(i,56).Tg()):ctn(Zon(i)))+z9n+this.a+"'"));if(r=n.eh(),a=Cwn(n.Tg(),this.e),HC(i)!==HC(r)||n.Vg()!=a&&null!=i){if(gkn(n,_B(i,56)))throw Fp(new Ry(l6n+n.Ib()));o=null,r&&(o=(c=n.Vg())>=0?n.Qg(o):n.eh().ih(n,-1-c,null,o)),(u=_B(i,49))&&(o=u.gh(n,Cwn(u.Tg(),this.b),null,o)),(o=n.Sg(u,a,o))&&o.Fi()}else n.Lg()&&n.Mg()&&fan(n,new Yz(n,1,a,i,i))},EWn.Vj=function(n,t,e){var i,r,c;n.eh()?(c=(i=n.Vg())>=0?n.Qg(null):n.eh().ih(n,-1-i,null,null),r=Cwn(n.Tg(),this.e),(c=n.Sg(null,r,c))&&c.Fi()):n.Lg()&&n.Mg()&&fan(n,new Zz(n,1,this.e,null,null))},EWn.sk=function(){return!1},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainer",769),lAn(1315,769,{},SB),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleContainerResolving",1315),lAn(563,504,{}),EWn.Pj=function(n,t,e,i,r){var c;return null==(c=t.Ch(e))?this.b:HC(c)===HC(N$t)?null:c},EWn.Sj=function(n,t,e){var i;return null!=(i=t.Ch(e))&&(HC(i)===HC(N$t)||!$fn(i,this.b))},EWn.Tj=function(n,t,e,i){var r,c;n.Lg()&&n.Mg()?(r=null==(c=t.Ch(e))?this.b:HC(c)===HC(N$t)?null:c,null==i?null!=this.c?(t.Dh(e,null),i=this.b):null!=this.b?t.Dh(e,N$t):t.Dh(e,null):(this.Sk(i),t.Dh(e,i)),fan(n,this.d.Tk(n,1,this.e,r,i))):null==i?null!=this.c?t.Dh(e,null):null!=this.b?t.Dh(e,N$t):t.Dh(e,null):(this.Sk(i),t.Dh(e,i))},EWn.Vj=function(n,t,e){var i,r;n.Lg()&&n.Mg()?(i=null==(r=t.Ch(e))?this.b:HC(r)===HC(N$t)?null:r,t.Eh(e),fan(n,this.d.Tk(n,1,this.e,i,this.b))):t.Eh(e)},EWn.Sk=function(n){throw Fp(new fv)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData",563),lAn(U9n,1,{},$o),EWn.Tk=function(n,t,e,i,r){return new Zz(n,t,e,i,r)},EWn.Uk=function(n,t,e,i,r,c){return new HQ(n,t,e,i,r,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator",U9n),lAn(1332,U9n,{},Lo),EWn.Tk=function(n,t,e,i,r){return new Y5(n,t,e,By(jD(i)),By(jD(r)))},EWn.Uk=function(n,t,e,i,r,c){return new A0(n,t,e,By(jD(i)),By(jD(r)),c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/1",1332),lAn(1333,U9n,{},No),EWn.Tk=function(n,t,e,i,r){return new Fen(n,t,e,_B(i,217).a,_B(r,217).a)},EWn.Uk=function(n,t,e,i,r,c){return new T0(n,t,e,_B(i,217).a,_B(r,217).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/2",1333),lAn(1334,U9n,{},xo),EWn.Tk=function(n,t,e,i,r){return new Ben(n,t,e,_B(i,172).a,_B(r,172).a)},EWn.Uk=function(n,t,e,i,r,c){return new M0(n,t,e,_B(i,172).a,_B(r,172).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/3",1334),lAn(1335,U9n,{},Do),EWn.Tk=function(n,t,e,i,r){return new Q5(n,t,e,Hy(ED(i)),Hy(ED(r)))},EWn.Uk=function(n,t,e,i,r,c){return new S0(n,t,e,Hy(ED(i)),Hy(ED(r)),c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/4",1335),lAn(1336,U9n,{},Ro),EWn.Tk=function(n,t,e,i,r){return new Gen(n,t,e,_B(i,155).a,_B(r,155).a)},EWn.Uk=function(n,t,e,i,r,c){return new P0(n,t,e,_B(i,155).a,_B(r,155).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/5",1336),lAn(1337,U9n,{},Ko),EWn.Tk=function(n,t,e,i,r){return new J5(n,t,e,_B(i,19).a,_B(r,19).a)},EWn.Uk=function(n,t,e,i,r,c){return new I0(n,t,e,_B(i,19).a,_B(r,19).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/6",1337),lAn(1338,U9n,{},_o),EWn.Tk=function(n,t,e,i,r){return new Hen(n,t,e,_B(i,162).a,_B(r,162).a)},EWn.Uk=function(n,t,e,i,r,c){return new C0(n,t,e,_B(i,162).a,_B(r,162).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/7",1338),lAn(1339,U9n,{},Fo),EWn.Tk=function(n,t,e,i,r){return new qen(n,t,e,_B(i,184).a,_B(r,184).a)},EWn.Uk=function(n,t,e,i,r,c){return new O0(n,t,e,_B(i,184).a,_B(r,184).a,c)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleData/NotificationCreator/8",1339),lAn(1317,563,{},lQ),EWn.Sk=function(n){if(!this.a.wj(n))throw Fp(new Dy(G9n+Zon(n)+z9n+this.a+"'"))},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataDynamic",1317),lAn(1318,563,{},JG),EWn.Sk=function(n){},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataStatic",1318),lAn(770,563,{}),EWn.Sj=function(n,t,e){return null!=t.Ch(e)},EWn.Tj=function(n,t,e,i){var r,c;n.Lg()&&n.Mg()?(r=!0,null==(c=t.Ch(e))?(r=!1,c=this.b):HC(c)===HC(N$t)&&(c=null),null==i?null!=this.c?(t.Dh(e,null),i=this.b):t.Dh(e,N$t):(this.Sk(i),t.Dh(e,i)),fan(n,this.d.Uk(n,1,this.e,c,i,!r))):null==i?null!=this.c?t.Dh(e,null):t.Dh(e,N$t):(this.Sk(i),t.Dh(e,i))},EWn.Vj=function(n,t,e){var i,r;n.Lg()&&n.Mg()?(i=!0,null==(r=t.Ch(e))?(i=!1,r=this.b):HC(r)===HC(N$t)&&(r=null),t.Eh(e),fan(n,this.d.Uk(n,2,this.e,r,this.b,i))):t.Eh(e)},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettable",770),lAn(1319,770,{},bQ),EWn.Sk=function(n){if(!this.a.wj(n))throw Fp(new Dy(G9n+Zon(n)+z9n+this.a+"'"))},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableDynamic",1319),lAn(1320,770,{},YG),EWn.Sk=function(n){},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleDataUnsettableStatic",1320),lAn(398,504,{},iG),EWn.Pj=function(n,t,e,i,r){var c,a,u,o,s;if(s=t.Ch(e),this.Kj()&&HC(s)===HC(N$t))return null;if(this.sk()&&i&&null!=s){if((u=_B(s,49)).kh()&&u!=(o=Zhn(n,u))){if(!TFn(this.a,o))throw Fp(new Dy(G9n+Zon(o)+z9n+this.a+"'"));t.Dh(e,s=o),this.rk()&&(c=_B(o,49),a=u.ih(n,this.b?Cwn(u.Tg(),this.b):-1-Cwn(n.Tg(),this.e),null,null),!c.eh()&&(a=c.gh(n,this.b?Cwn(c.Tg(),this.b):-1-Cwn(n.Tg(),this.e),null,a)),a&&a.Fi()),n.Lg()&&n.Mg()&&fan(n,new Zz(n,9,this.e,u,o))}return s}return s},EWn.Qj=function(n,t,e,i,r){var c,a;return HC(a=t.Ch(e))===HC(N$t)&&(a=null),t.Dh(e,i),this.bj()?HC(a)!==HC(i)&&null!=a&&(r=(c=_B(a,49)).ih(n,Cwn(c.Tg(),this.b),null,r)):this.rk()&&null!=a&&(r=_B(a,49).ih(n,-1-Cwn(n.Tg(),this.e),null,r)),n.Lg()&&n.Mg()&&(!r&&(r=new Kj(4)),r.Ei(new Zz(n,1,this.e,a,i))),r},EWn.Rj=function(n,t,e,i,r){var c;return HC(c=t.Ch(e))===HC(N$t)&&(c=null),t.Eh(e),n.Lg()&&n.Mg()&&(!r&&(r=new Kj(4)),this.Kj()?r.Ei(new Zz(n,2,this.e,c,null)):r.Ei(new Zz(n,1,this.e,c,null))),r},EWn.Sj=function(n,t,e){return null!=t.Ch(e)},EWn.Tj=function(n,t,e,i){var r,c,a,u,o;if(null!=i&&!TFn(this.a,i))throw Fp(new Dy(G9n+(iL(i,56)?bEn(_B(i,56).Tg()):ctn(Zon(i)))+z9n+this.a+"'"));u=null!=(o=t.Ch(e)),this.Kj()&&HC(o)===HC(N$t)&&(o=null),a=null,this.bj()?HC(o)!==HC(i)&&(null!=o&&(a=(r=_B(o,49)).ih(n,Cwn(r.Tg(),this.b),null,a)),null!=i&&(a=(r=_B(i,49)).gh(n,Cwn(r.Tg(),this.b),null,a))):this.rk()&&HC(o)!==HC(i)&&(null!=o&&(a=_B(o,49).ih(n,-1-Cwn(n.Tg(),this.e),null,a)),null!=i&&(a=_B(i,49).gh(n,-1-Cwn(n.Tg(),this.e),null,a))),null==i&&this.Kj()?t.Dh(e,N$t):t.Dh(e,i),n.Lg()&&n.Mg()?(c=new HQ(n,1,this.e,o,i,this.Kj()&&!u),a?(a.Ei(c),a.Fi()):fan(n,c)):a&&a.Fi()},EWn.Vj=function(n,t,e){var i,r,c,a,u;a=null!=(u=t.Ch(e)),this.Kj()&&HC(u)===HC(N$t)&&(u=null),c=null,null!=u&&(this.bj()?c=(i=_B(u,49)).ih(n,Cwn(i.Tg(),this.b),null,c):this.rk()&&(c=_B(u,49).ih(n,-1-Cwn(n.Tg(),this.e),null,c))),t.Eh(e),n.Lg()&&n.Mg()?(r=new HQ(n,this.Kj()?2:1,this.e,u,null,a),c?(c.Ei(r),c.Fi()):fan(n,r)):c&&c.Fi()},EWn.bj=function(){return!1},EWn.rk=function(){return!1},EWn.sk=function(){return!1},EWn.Kj=function(){return!1},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObject",398),lAn(564,398,{},Jx),EWn.rk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainment",564),lAn(1323,564,{},Yx),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentResolving",1323),lAn(772,564,{},Zx),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettable",772),lAn(1325,772,{},nD),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentUnsettableResolving",1325),lAn(640,564,{},PB),EWn.bj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverse",640),lAn(1324,640,{},OB),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseResolving",1324),lAn(773,640,{},AB),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettable",773),lAn(1326,773,{},$B),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectContainmentWithInverseUnsettableResolving",1326),lAn(641,398,{},tD),EWn.sk=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolving",641),lAn(1327,641,{},eD),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingUnsettable",1327),lAn(774,641,{},IB),EWn.bj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverse",774),lAn(1328,774,{},LB),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectResolvingWithInverseUnsettable",1328),lAn(1321,398,{},iD),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectUnsettable",1321),lAn(771,398,{},CB),EWn.bj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverse",771),lAn(1322,771,{},NB),EWn.Kj=function(){return!0},gX(h6n,"EStructuralFeatureImpl/InternalSettingDelegateSingleEObjectWithInverseUnsettable",1322),lAn(775,565,q9n,rW),EWn.Pk=function(n){return new rW(this.a,this.c,n)},EWn.dd=function(){return this.b},EWn.Qk=function(n,t,e){return N8(this,n,this.b,e)},EWn.Rk=function(n,t,e){return x8(this,n,this.b,e)},gX(h6n,"EStructuralFeatureImpl/InverseUpdatingFeatureMapEntry",775),lAn(1329,1,m9n,kp),EWn.Wj=function(n){return this.a},EWn.fj=function(){return iL(this.a,95)?_B(this.a,95).fj():!this.a.dc()},EWn.Wb=function(n){this.a.$b(),this.a.Gc(_B(n,15))},EWn.Xj=function(){iL(this.a,95)?_B(this.a,95).Xj():this.a.$b()},gX(h6n,"EStructuralFeatureImpl/SettingMany",1329),lAn(1330,565,q9n,w4),EWn.Ok=function(n){return new iR((Gqn(),RLt),this.b.Ih(this.a,n))},EWn.dd=function(){return null},EWn.Qk=function(n,t,e){return e},EWn.Rk=function(n,t,e){return e},gX(h6n,"EStructuralFeatureImpl/SimpleContentFeatureMapEntry",1330),lAn(642,565,q9n,iR),EWn.Ok=function(n){return new iR(this.c,n)},EWn.dd=function(){return this.a},EWn.Qk=function(n,t,e){return e},EWn.Rk=function(n,t,e){return e},gX(h6n,"EStructuralFeatureImpl/SimpleFeatureMapEntry",642),lAn(391,497,o8n,Bo),EWn.ri=function(n){return L8(FAt,FWn,26,n,0,1)},EWn.ni=function(){return!1},gX(h6n,"ESuperAdapter/1",391),lAn(444,438,{105:1,92:1,90:1,147:1,191:1,56:1,108:1,836:1,49:1,97:1,150:1,444:1,114:1,115:1},Ho),EWn._g=function(n,t,e){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),this.Ab;case 1:return this.zb;case 2:return!this.a&&(this.a=new rG(this,UAt,this)),this.a}return G9(this,n-fX((wWn(),k$t)),ttn(_B(van(this,16),26)||k$t,n),t,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),Rpn(this.Ab,n,e);case 2:return!this.a&&(this.a=new rG(this,UAt,this)),Rpn(this.a,n,e)}return _B(ttn(_B(van(this,16),26)||(wWn(),k$t),t),66).Nj().Rj(this,sgn(this),t-fX((wWn(),k$t)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.Ab&&0!=this.Ab.i;case 1:return null!=this.zb;case 2:return!!this.a&&0!=this.a.i}return I3(this,n-fX((wWn(),k$t)),ttn(_B(van(this,16),26)||k$t,n))},EWn.sh=function(n,t){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),uqn(this.Ab),!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void dX(this.Ab,_B(t,14));case 1:return void $rn(this,TD(t));case 2:return!this.a&&(this.a=new rG(this,UAt,this)),uqn(this.a),!this.a&&(this.a=new rG(this,UAt,this)),void dX(this.a,_B(t,14))}Abn(this,n-fX((wWn(),k$t)),ttn(_B(van(this,16),26)||k$t,n),t)},EWn.zh=function(){return wWn(),k$t},EWn.Bh=function(n){switch(n){case 0:return!this.Ab&&(this.Ab=new nU(xAt,this,0,3)),void uqn(this.Ab);case 1:return void $rn(this,null);case 2:return!this.a&&(this.a=new rG(this,UAt,this)),void uqn(this.a)}Bfn(this,n-fX((wWn(),k$t)),ttn(_B(van(this,16),26)||k$t,n))},gX(h6n,"ETypeParameterImpl",444),lAn(445,85,x9n,rG),EWn.cj=function(n,t){return ATn(this,_B(n,87),t)},EWn.dj=function(n,t){return $Tn(this,_B(n,87),t)},gX(h6n,"ETypeParameterImpl/1",445),lAn(634,43,ZQn,Lm),EWn.ec=function(){return new jp(this)},gX(h6n,"ETypeParameterImpl/2",634),lAn(556,YWn,ZWn,jp),EWn.Fc=function(n){return VR(this,_B(n,87))},EWn.Gc=function(n){var t,e,i;for(i=!1,e=n.Kc();e.Ob();)t=_B(e.Pb(),87),null==XW(this.a,t,"")&&(i=!0);return i},EWn.$b=function(){OU(this.a)},EWn.Hc=function(n){return oU(this.a,n)},EWn.Kc=function(){return new Ep(new csn(new Mb(this.a).a))},EWn.Mc=function(n){return R6(this,n)},EWn.gc=function(){return $T(this.a)},gX(h6n,"ETypeParameterImpl/2/1",556),lAn(557,1,WWn,Ep),EWn.Nb=function(n){sU(this,n)},EWn.Pb=function(){return _B(Ztn(this.a).cd(),87)},EWn.Ob=function(){return this.a.b},EWn.Qb=function(){a9(this.a)},gX(h6n,"ETypeParameterImpl/2/1/1",557),lAn(1276,43,ZQn,Nm),EWn._b=function(n){return zC(n)?nJ(this,n):!!CJ(this.f,n)},EWn.xc=function(n){var t;return iL(t=zC(n)?TY(this,n):BC(CJ(this.f,n)),837)?(t=_B(t,837)._j(),XW(this,_B(n,235),t),t):null!=t?t:null==n?(QM(),tLt):null},gX(h6n,"EValidatorRegistryImpl",1276),lAn(1313,704,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,1941:1,49:1,97:1,150:1,114:1,115:1},qo),EWn.Ih=function(n,t){switch(n.yj()){case 21:case 22:case 23:case 24:case 26:case 31:case 32:case 37:case 38:case 39:case 40:case 43:case 44:case 48:case 49:case 20:return null==t?null:_bn(t);case 25:return ztn(t);case 27:return z9(t);case 28:return U9(t);case 29:return null==t?null:F$(POt[0],_B(t,199));case 41:return null==t?"":Yj(_B(t,290));case 42:return _bn(t);case 50:return TD(t);default:throw Fp(new Ry(b6n+n.ne()+w6n))}},EWn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=Gtn(n))?cvn(t.Mh(),n):-1),n.G){case 0:return new Im;case 1:return new jo;case 2:return new Rf;case 4:return new kv;case 5:return new Cm;case 6:return new yv;case 7:return new xf;case 10:return new yo;case 11:return new Om;case 12:return new gJ;case 13:return new Am;case 14:return new dD;case 17:return new Ao;case 18:return new Dp;case 19:return new Ho;default:throw Fp(new Ry(p6n+n.zb+w6n))}},EWn.Kh=function(n,t){switch(n.yj()){case 20:return null==t?null:new lE(t);case 21:return null==t?null:new OA(t);case 23:case 22:return null==t?null:Jdn(t);case 26:case 24:return null==t?null:Mnn(h_n(t,-128,127)<<24>>24);case 25:return b$n(t);case 27:return Tyn(t);case 28:return Myn(t);case 29:return wMn(t);case 32:case 31:return null==t?null:fSn(t);case 38:case 37:return null==t?null:new Nv(t);case 40:case 39:return null==t?null:tln(h_n(t,RVn,NWn));case 41:case 42:return null;case 44:case 43:return null==t?null:ygn(eUn(t));case 49:case 48:return null==t?null:eln(h_n(t,W9n,32767)<<16>>16);case 50:return t;default:throw Fp(new Ry(b6n+n.ne()+w6n))}},gX(h6n,"EcoreFactoryImpl",1313),lAn(547,179,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,1939:1,49:1,97:1,150:1,179:1,547:1,114:1,115:1,675:1},GW),EWn.gb=!1,EWn.hb=!1;var U$t,X$t=!1;gX(h6n,"EcorePackageImpl",547),lAn(1184,1,{837:1},Go),EWn._j=function(){return uN(),eLt},gX(h6n,"EcorePackageImpl/1",1184),lAn(1193,1,u7n,zo),EWn.wj=function(n){return iL(n,147)},EWn.xj=function(n){return L8(KOt,FWn,147,n,0,1)},gX(h6n,"EcorePackageImpl/10",1193),lAn(1194,1,u7n,Uo),EWn.wj=function(n){return iL(n,191)},EWn.xj=function(n){return L8(FOt,FWn,191,n,0,1)},gX(h6n,"EcorePackageImpl/11",1194),lAn(1195,1,u7n,Xo),EWn.wj=function(n){return iL(n,56)},EWn.xj=function(n){return L8(OOt,FWn,56,n,0,1)},gX(h6n,"EcorePackageImpl/12",1195),lAn(1196,1,u7n,Wo),EWn.wj=function(n){return iL(n,399)},EWn.xj=function(n){return L8(XAt,L9n,59,n,0,1)},gX(h6n,"EcorePackageImpl/13",1196),lAn(1197,1,u7n,Vo),EWn.wj=function(n){return iL(n,235)},EWn.xj=function(n){return L8(BOt,FWn,235,n,0,1)},gX(h6n,"EcorePackageImpl/14",1197),lAn(1198,1,u7n,Qo),EWn.wj=function(n){return iL(n,509)},EWn.xj=function(n){return L8(WAt,FWn,2017,n,0,1)},gX(h6n,"EcorePackageImpl/15",1198),lAn(1199,1,u7n,Jo),EWn.wj=function(n){return iL(n,99)},EWn.xj=function(n){return L8(VAt,$9n,18,n,0,1)},gX(h6n,"EcorePackageImpl/16",1199),lAn(1200,1,u7n,Yo),EWn.wj=function(n){return iL(n,170)},EWn.xj=function(n){return L8(RAt,$9n,170,n,0,1)},gX(h6n,"EcorePackageImpl/17",1200),lAn(1201,1,u7n,Zo),EWn.wj=function(n){return iL(n,472)},EWn.xj=function(n){return L8(DAt,FWn,472,n,0,1)},gX(h6n,"EcorePackageImpl/18",1201),lAn(1202,1,u7n,ns),EWn.wj=function(n){return iL(n,548)},EWn.xj=function(n){return L8(G$t,r9n,548,n,0,1)},gX(h6n,"EcorePackageImpl/19",1202),lAn(1185,1,u7n,ts),EWn.wj=function(n){return iL(n,322)},EWn.xj=function(n){return L8(KAt,$9n,34,n,0,1)},gX(h6n,"EcorePackageImpl/2",1185),lAn(1203,1,u7n,es),EWn.wj=function(n){return iL(n,241)},EWn.xj=function(n){return L8(UAt,_9n,87,n,0,1)},gX(h6n,"EcorePackageImpl/20",1203),lAn(1204,1,u7n,is),EWn.wj=function(n){return iL(n,444)},EWn.xj=function(n){return L8(P$t,FWn,836,n,0,1)},gX(h6n,"EcorePackageImpl/21",1204),lAn(1205,1,u7n,rs),EWn.wj=function(n){return qC(n)},EWn.xj=function(n){return L8(mtt,uVn,476,n,8,1)},gX(h6n,"EcorePackageImpl/22",1205),lAn(1206,1,u7n,cs),EWn.wj=function(n){return iL(n,190)},EWn.xj=function(n){return L8(ANt,uVn,190,n,0,2)},gX(h6n,"EcorePackageImpl/23",1206),lAn(1207,1,u7n,as),EWn.wj=function(n){return iL(n,217)},EWn.xj=function(n){return L8(jtt,uVn,217,n,0,1)},gX(h6n,"EcorePackageImpl/24",1207),lAn(1208,1,u7n,us),EWn.wj=function(n){return iL(n,172)},EWn.xj=function(n){return L8(Ttt,uVn,172,n,0,1)},gX(h6n,"EcorePackageImpl/25",1208),lAn(1209,1,u7n,os),EWn.wj=function(n){return iL(n,199)},EWn.xj=function(n){return L8(ptt,uVn,199,n,0,1)},gX(h6n,"EcorePackageImpl/26",1209),lAn(1210,1,u7n,ss),EWn.wj=function(n){return!1},EWn.xj=function(n){return L8(DNt,FWn,2110,n,0,1)},gX(h6n,"EcorePackageImpl/27",1210),lAn(1211,1,u7n,hs),EWn.wj=function(n){return GC(n)},EWn.xj=function(n){return L8(Mtt,uVn,333,n,7,1)},gX(h6n,"EcorePackageImpl/28",1211),lAn(1212,1,u7n,fs),EWn.wj=function(n){return iL(n,58)},EWn.xj=function(n){return L8(rAt,YYn,58,n,0,1)},gX(h6n,"EcorePackageImpl/29",1212),lAn(1186,1,u7n,ls),EWn.wj=function(n){return iL(n,510)},EWn.xj=function(n){return L8(xAt,{3:1,4:1,5:1,1934:1},590,n,0,1)},gX(h6n,"EcorePackageImpl/3",1186),lAn(1213,1,u7n,bs),EWn.wj=function(n){return iL(n,573)},EWn.xj=function(n){return L8(pAt,FWn,1940,n,0,1)},gX(h6n,"EcorePackageImpl/30",1213),lAn(1214,1,u7n,ws),EWn.wj=function(n){return iL(n,153)},EWn.xj=function(n){return L8(hLt,YYn,153,n,0,1)},gX(h6n,"EcorePackageImpl/31",1214),lAn(1215,1,u7n,ds),EWn.wj=function(n){return iL(n,72)},EWn.xj=function(n){return L8(C$t,o7n,72,n,0,1)},gX(h6n,"EcorePackageImpl/32",1215),lAn(1216,1,u7n,gs),EWn.wj=function(n){return iL(n,155)},EWn.xj=function(n){return L8(Stt,uVn,155,n,0,1)},gX(h6n,"EcorePackageImpl/33",1216),lAn(1217,1,u7n,ps),EWn.wj=function(n){return iL(n,19)},EWn.xj=function(n){return L8(Ctt,uVn,19,n,0,1)},gX(h6n,"EcorePackageImpl/34",1217),lAn(1218,1,u7n,vs),EWn.wj=function(n){return iL(n,290)},EWn.xj=function(n){return L8(Ont,FWn,290,n,0,1)},gX(h6n,"EcorePackageImpl/35",1218),lAn(1219,1,u7n,ms),EWn.wj=function(n){return iL(n,162)},EWn.xj=function(n){return L8(xtt,uVn,162,n,0,1)},gX(h6n,"EcorePackageImpl/36",1219),lAn(1220,1,u7n,ys),EWn.wj=function(n){return iL(n,83)},EWn.xj=function(n){return L8($nt,FWn,83,n,0,1)},gX(h6n,"EcorePackageImpl/37",1220),lAn(1221,1,u7n,ks),EWn.wj=function(n){return iL(n,591)},EWn.xj=function(n){return L8(nLt,FWn,591,n,0,1)},gX(h6n,"EcorePackageImpl/38",1221),lAn(1222,1,u7n,js),EWn.wj=function(n){return!1},EWn.xj=function(n){return L8(RNt,FWn,2111,n,0,1)},gX(h6n,"EcorePackageImpl/39",1222),lAn(1187,1,u7n,Es),EWn.wj=function(n){return iL(n,88)},EWn.xj=function(n){return L8(FAt,FWn,26,n,0,1)},gX(h6n,"EcorePackageImpl/4",1187),lAn(1223,1,u7n,Ts),EWn.wj=function(n){return iL(n,184)},EWn.xj=function(n){return L8(Rtt,uVn,184,n,0,1)},gX(h6n,"EcorePackageImpl/40",1223),lAn(1224,1,u7n,Ms),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX(h6n,"EcorePackageImpl/41",1224),lAn(1225,1,u7n,Ss),EWn.wj=function(n){return iL(n,588)},EWn.xj=function(n){return L8(oAt,FWn,588,n,0,1)},gX(h6n,"EcorePackageImpl/42",1225),lAn(1226,1,u7n,Ps),EWn.wj=function(n){return!1},EWn.xj=function(n){return L8(KNt,uVn,2112,n,0,1)},gX(h6n,"EcorePackageImpl/43",1226),lAn(1227,1,u7n,Is),EWn.wj=function(n){return iL(n,42)},EWn.xj=function(n){return L8(Fnt,mVn,42,n,0,1)},gX(h6n,"EcorePackageImpl/44",1227),lAn(1188,1,u7n,Cs),EWn.wj=function(n){return iL(n,138)},EWn.xj=function(n){return L8(_At,FWn,138,n,0,1)},gX(h6n,"EcorePackageImpl/5",1188),lAn(1189,1,u7n,Os),EWn.wj=function(n){return iL(n,148)},EWn.xj=function(n){return L8(BAt,FWn,148,n,0,1)},gX(h6n,"EcorePackageImpl/6",1189),lAn(1190,1,u7n,As),EWn.wj=function(n){return iL(n,457)},EWn.xj=function(n){return L8(GAt,FWn,671,n,0,1)},gX(h6n,"EcorePackageImpl/7",1190),lAn(1191,1,u7n,$s),EWn.wj=function(n){return iL(n,573)},EWn.xj=function(n){return L8(zAt,FWn,678,n,0,1)},gX(h6n,"EcorePackageImpl/8",1191),lAn(1192,1,u7n,Ls),EWn.wj=function(n){return iL(n,471)},EWn.xj=function(n){return L8(_Ot,FWn,471,n,0,1)},gX(h6n,"EcorePackageImpl/9",1192),lAn(1025,1982,e9n,Ly),EWn.bi=function(n,t){Cfn(this,_B(t,415))},EWn.fi=function(n,t){nIn(this,n,_B(t,415))},gX(h6n,"MinimalEObjectImpl/1ArrayDelegatingAdapterList",1025),lAn(1026,143,Z8n,cW),EWn.Ai=function(){return this.a.a},gX(h6n,"MinimalEObjectImpl/1ArrayDelegatingAdapterList/1",1026),lAn(1053,1052,{},a$),gX("org.eclipse.emf.ecore.plugin","EcorePlugin",1053);var W$t,V$t,Q$t,J$t,Y$t,Z$t,nLt=fq(s7n,"Resource");lAn(781,1378,h7n),EWn.Yk=function(n){},EWn.Zk=function(n){},EWn.Vk=function(){return!this.a&&(this.a=new Tp(this)),this.a},EWn.Wk=function(n){var t,e,i,r,c;if((i=n.length)>0){if(f1(0,n.length),47==n.charCodeAt(0)){for(c=new Q6(4),r=1,t=1;t0&&(n=n.substr(0,e))}return yCn(this,n)},EWn.Xk=function(){return this.c},EWn.Ib=function(){return Yj(this.gm)+"@"+(Yon(this)>>>0).toString(16)+" uri='"+this.d+"'"},EWn.b=!1,gX(f7n,"ResourceImpl",781),lAn(1379,781,h7n,Sp),gX(f7n,"BinaryResourceImpl",1379),lAn(1169,694,s8n),EWn.si=function(n){return iL(n,56)?jJ(this,_B(n,56)):iL(n,591)?new CL(_B(n,591).Vk()):HC(n)===HC(this.f)?_B(n,14).Kc():(bD(),wAt.a)},EWn.Ob=function(){return fOn(this)},EWn.a=!1,gX(v9n,"EcoreUtil/ContentTreeIterator",1169),lAn(1380,1169,s8n,eU),EWn.si=function(n){return HC(n)===HC(this.f)?_B(n,15).Kc():new K2(_B(n,56))},gX(f7n,"ResourceImpl/5",1380),lAn(648,1994,N9n,Tp),EWn.Hc=function(n){return this.i<=4?Tjn(this,n):iL(n,49)&&_B(n,49).Zg()==this.a},EWn.bi=function(n,t){n==this.i-1&&(this.a.b||(this.a.b=!0))},EWn.di=function(n,t){0==n?this.a.b||(this.a.b=!0):A8(this,n,t)},EWn.fi=function(n,t){},EWn.gi=function(n,t,e){},EWn.aj=function(){return 2},EWn.Ai=function(){return this.a},EWn.bj=function(){return!0},EWn.cj=function(n,t){return t=_B(n,49).wh(this.a,t)},EWn.dj=function(n,t){return _B(n,49).wh(null,t)},EWn.ej=function(){return!1},EWn.hi=function(){return!0},EWn.ri=function(n){return L8(OOt,FWn,56,n,0,1)},EWn.ni=function(){return!1},gX(f7n,"ResourceImpl/ContentsEList",648),lAn(957,1964,AVn,Mp),EWn.Zc=function(n){return this.a._h(n)},EWn.gc=function(){return this.a.gc()},gX(v9n,"AbstractSequentialInternalEList/1",957),lAn(624,1,{},TH),gX(v9n,"BasicExtendedMetaData",624),lAn(1160,1,{},OC),EWn.$k=function(){return null},EWn._k=function(){return-2==this.a&&ab(this,rMn(this.d,this.b)),this.a},EWn.al=function(){return null},EWn.bl=function(){return TQ(),TQ(),uet},EWn.ne=function(){return this.c==S7n&&ob(this,kgn(this.d,this.b)),this.c},EWn.cl=function(){return 0},EWn.a=-2,EWn.c=S7n,gX(v9n,"BasicExtendedMetaData/EClassExtendedMetaDataImpl",1160),lAn(1161,1,{},R0),EWn.$k=function(){return this.a==(x5(),Y$t)&&ub(this,gNn(this.f,this.b)),this.a},EWn._k=function(){return 0},EWn.al=function(){return this.c==(x5(),Y$t)&&sb(this,pNn(this.f,this.b)),this.c},EWn.bl=function(){return!this.d&&hb(this,TKn(this.f,this.b)),this.d},EWn.ne=function(){return this.e==S7n&&fb(this,kgn(this.f,this.b)),this.e},EWn.cl=function(){return-2==this.g&&lb(this,VEn(this.f,this.b)),this.g},EWn.e=S7n,EWn.g=-2,gX(v9n,"BasicExtendedMetaData/EDataTypeExtendedMetaDataImpl",1161),lAn(1159,1,{},xC),EWn.b=!1,EWn.c=!1,gX(v9n,"BasicExtendedMetaData/EPackageExtendedMetaDataImpl",1159),lAn(1162,1,{},D0),EWn.c=-2,EWn.e=S7n,EWn.f=S7n,gX(v9n,"BasicExtendedMetaData/EStructuralFeatureExtendedMetaDataImpl",1162),lAn(585,622,x9n,EH),EWn.aj=function(){return this.c},EWn.Fk=function(){return!1},EWn.li=function(n,t){return t},EWn.c=0,gX(v9n,"EDataTypeEList",585);var tLt,eLt,iLt,rLt,cLt,aLt,uLt,oLt,sLt,hLt=fq(v9n,"FeatureMap");lAn(75,585,{3:1,4:1,20:1,28:1,52:1,14:1,15:1,54:1,67:1,63:1,58:1,76:1,153:1,215:1,1937:1,69:1,95:1},kcn),EWn.Vc=function(n,t){hNn(this,n,_B(t,72))},EWn.Fc=function(n){return cLn(this,_B(n,72))},EWn.Yh=function(n){bX(this,_B(n,72))},EWn.cj=function(n,t){return FK(this,_B(n,72),t)},EWn.dj=function(n,t){return BK(this,_B(n,72),t)},EWn.ii=function(n,t){return r_n(this,n,t)},EWn.li=function(n,t){return oGn(this,n,_B(t,72))},EWn._c=function(n,t){return Mxn(this,n,_B(t,72))},EWn.jj=function(n,t){return HK(this,_B(n,72),t)},EWn.kj=function(n,t){return qK(this,_B(n,72),t)},EWn.lj=function(n,t,e){return wEn(this,_B(n,72),_B(t,72),e)},EWn.oi=function(n,t){return uTn(this,n,_B(t,72))},EWn.dl=function(n,t){return LKn(this,n,t)},EWn.Wc=function(n,t){var e,i,r,c,a,u,o,s,h;for(s=new wtn(t.gc()),r=t.Kc();r.Ob();)if(c=(i=_B(r.Pb(),72)).ak(),Oxn(this.e,c))(!c.hi()||!H3(this,c,i.dd())&&!Tjn(s,i))&&s9(s,i);else{for(h=rxn(this.e.Tg(),c),e=_B(this.g,119),a=!0,u=0;u=0;)if(t=n[this.c],this.k.rl(t.ak()))return this.j=this.f?t:t.dd(),this.i=-2,!0;return this.i=-1,this.g=-1,!1},gX(v9n,"BasicFeatureMap/FeatureEIterator",410),lAn(662,410,iVn,LO),EWn.Lk=function(){return!0},gX(v9n,"BasicFeatureMap/ResolvingFeatureEIterator",662),lAn(955,486,B9n,q$),EWn.Gi=function(){return this},gX(v9n,"EContentsEList/1",955),lAn(956,486,B9n,NO),EWn.Lk=function(){return!1},gX(v9n,"EContentsEList/2",956),lAn(954,279,H9n,G$),EWn.Nk=function(n){},EWn.Ob=function(){return!1},EWn.Sb=function(){return!1},gX(v9n,"EContentsEList/FeatureIteratorImpl/1",954),lAn(825,585,x9n,DL),EWn.ci=function(){this.a=!0},EWn.fj=function(){return this.a},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.a,this.a=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.a=!1},EWn.a=!1,gX(v9n,"EDataTypeEList/Unsettable",825),lAn(1849,585,x9n,RL),EWn.hi=function(){return!0},gX(v9n,"EDataTypeUniqueEList",1849),lAn(1850,825,x9n,KL),EWn.hi=function(){return!0},gX(v9n,"EDataTypeUniqueEList/Unsettable",1850),lAn(139,85,x9n,$L),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectContainmentEList/Resolving",139),lAn(1163,545,x9n,LL),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectContainmentEList/Unsettable/Resolving",1163),lAn(748,16,x9n,tK),EWn.ci=function(){this.a=!0},EWn.fj=function(){return this.a},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.a,this.a=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.a=!1},EWn.a=!1,gX(v9n,"EObjectContainmentWithInverseEList/Unsettable",748),lAn(1173,748,x9n,eK),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectContainmentWithInverseEList/Unsettable/Resolving",1173),lAn(743,496,x9n,NL),EWn.ci=function(){this.a=!0},EWn.fj=function(){return this.a},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.a,this.a=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.a=!1},EWn.a=!1,gX(v9n,"EObjectEList/Unsettable",743),lAn(328,496,x9n,xL),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectResolvingEList",328),lAn(1641,743,x9n,_L),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectResolvingEList/Unsettable",1641),lAn(1381,1,{},Ns),gX(v9n,"EObjectValidator",1381),lAn(546,496,x9n,tU),EWn.zk=function(){return this.d},EWn.Ak=function(){return this.b},EWn.bj=function(){return!0},EWn.Dk=function(){return!0},EWn.b=0,gX(v9n,"EObjectWithInverseEList",546),lAn(1176,546,x9n,iK),EWn.Ck=function(){return!0},gX(v9n,"EObjectWithInverseEList/ManyInverse",1176),lAn(625,546,x9n,rK),EWn.ci=function(){this.a=!0},EWn.fj=function(){return this.a},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.a,this.a=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.a=!1},EWn.a=!1,gX(v9n,"EObjectWithInverseEList/Unsettable",625),lAn(1175,625,x9n,aK),EWn.Ck=function(){return!0},gX(v9n,"EObjectWithInverseEList/Unsettable/ManyInverse",1175),lAn(749,546,x9n,cK),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectWithInverseResolvingEList",749),lAn(31,749,x9n,oK),EWn.Ck=function(){return!0},gX(v9n,"EObjectWithInverseResolvingEList/ManyInverse",31),lAn(750,625,x9n,uK),EWn.Ek=function(){return!0},EWn.li=function(n,t){return HOn(this,n,_B(t,56))},gX(v9n,"EObjectWithInverseResolvingEList/Unsettable",750),lAn(1174,750,x9n,sK),EWn.Ck=function(){return!0},gX(v9n,"EObjectWithInverseResolvingEList/Unsettable/ManyInverse",1174),lAn(1164,622,x9n),EWn.ai=function(){return 0==(1792&this.b)},EWn.ci=function(){this.b|=1},EWn.Bk=function(){return 0!=(4&this.b)},EWn.bj=function(){return 0!=(40&this.b)},EWn.Ck=function(){return 0!=(16&this.b)},EWn.Dk=function(){return 0!=(8&this.b)},EWn.Ek=function(){return 0!=(this.b&E9n)},EWn.rk=function(){return 0!=(32&this.b)},EWn.Fk=function(){return 0!=(this.b&m6n)},EWn.wj=function(n){return this.d?L3(this.d,n):this.ak().Yj().wj(n)},EWn.fj=function(){return 0!=(2&this.b)?0!=(1&this.b):0!=this.i},EWn.hi=function(){return 0!=(128&this.b)},EWn.Xj=function(){var n;uqn(this),0!=(2&this.b)&&(pA(this.e)?(n=0!=(1&this.b),this.b&=-2,Av(this,new Z5(this.e,2,Cwn(this.e.Tg(),this.ak()),n,!1))):this.b&=-2)},EWn.ni=function(){return 0==(1536&this.b)},EWn.b=0,gX(v9n,"EcoreEList/Generic",1164),lAn(1165,1164,x9n,qQ),EWn.ak=function(){return this.a},gX(v9n,"EcoreEList/Dynamic",1165),lAn(747,63,o8n,Pp),EWn.ri=function(n){return Nen(this.a.a,n)},gX(v9n,"EcoreEMap/1",747),lAn(746,85,x9n,Jz),EWn.bi=function(n,t){Pvn(this.b,_B(t,133))},EWn.di=function(n,t){ran(this.b)},EWn.ei=function(n,t,e){var i;++(i=this.b,_B(t,133),i).e},EWn.fi=function(n,t){Iln(this.b,_B(t,133))},EWn.gi=function(n,t,e){Iln(this.b,_B(e,133)),HC(e)===HC(t)&&_B(e,133).Th(i$(_B(t,133).cd())),Pvn(this.b,_B(t,133))},gX(v9n,"EcoreEMap/DelegateEObjectContainmentEList",746),lAn(1171,151,y9n,vin),gX(v9n,"EcoreEMap/Unsettable",1171),lAn(1172,746,x9n,hK),EWn.ci=function(){this.a=!0},EWn.fj=function(){return this.a},EWn.Xj=function(){var n;uqn(this),pA(this.e)?(n=this.a,this.a=!1,fan(this.e,new Z5(this.e,2,this.c,n,!1))):this.a=!1},EWn.a=!1,gX(v9n,"EcoreEMap/Unsettable/UnsettableDelegateEObjectContainmentEList",1172),lAn(1168,228,ZQn,hX),EWn.a=!1,EWn.b=!1,gX(v9n,"EcoreUtil/Copier",1168),lAn(745,1,WWn,K2),EWn.Nb=function(n){sU(this,n)},EWn.Ob=function(){return cdn(this)},EWn.Pb=function(){var n;return cdn(this),n=this.b,this.b=null,n},EWn.Qb=function(){this.a.Qb()},gX(v9n,"EcoreUtil/ProperContentIterator",745),lAn(1382,1381,{},Kf),gX(v9n,"EcoreValidator",1382),fq(v9n,"FeatureMapUtil/Validator"),lAn(1260,1,{1942:1},xs),EWn.rl=function(n){return!0},gX(v9n,"FeatureMapUtil/1",1260),lAn(757,1,{1942:1},iUn),EWn.rl=function(n){var t;return this.c==n||(null==(t=jD(xX(this.a,n)))?LRn(this,n)?(e6(this.a,n,(oN(),gtt)),!0):(e6(this.a,n,(oN(),dtt)),!1):t==(oN(),gtt))},EWn.e=!1,gX(v9n,"FeatureMapUtil/BasicValidator",757),lAn(758,43,ZQn,z$),gX(v9n,"FeatureMapUtil/BasicValidator/Cache",758),lAn(501,52,{20:1,28:1,52:1,14:1,15:1,58:1,76:1,69:1,95:1},LC),EWn.Vc=function(n,t){Cxn(this.c,this.b,n,t)},EWn.Fc=function(n){return LKn(this.c,this.b,n)},EWn.Wc=function(n,t){return yHn(this.c,this.b,n,t)},EWn.Gc=function(n){return J$(this,n)},EWn.Xh=function(n,t){otn(this.c,this.b,n,t)},EWn.lk=function(n,t){return MRn(this.c,this.b,n,t)},EWn.pi=function(n){return tHn(this.c,this.b,n,!1)},EWn.Zh=function(){return yA(this.c,this.b)},EWn.$h=function(){return kA(this.c,this.b)},EWn._h=function(n){return O8(this.c,this.b,n)},EWn.mk=function(n,t){return ZD(this,n,t)},EWn.$b=function(){$v(this)},EWn.Hc=function(n){return H3(this.c,this.b,n)},EWn.Ic=function(n){return Ecn(this.c,this.b,n)},EWn.Xb=function(n){return tHn(this.c,this.b,n,!0)},EWn.Wj=function(n){return this},EWn.Xc=function(n){return q3(this.c,this.b,n)},EWn.dc=function(){return FC(this)},EWn.fj=function(){return!rdn(this.c,this.b)},EWn.Kc=function(){return inn(this.c,this.b)},EWn.Yc=function(){return rnn(this.c,this.b)},EWn.Zc=function(n){return hln(this.c,this.b,n)},EWn.ii=function(n,t){return pFn(this.c,this.b,n,t)},EWn.ji=function(n,t){W6(this.c,this.b,n,t)},EWn.$c=function(n){return rPn(this.c,this.b,n)},EWn.Mc=function(n){return SKn(this.c,this.b,n)},EWn._c=function(n,t){return zFn(this.c,this.b,n,t)},EWn.Wb=function(n){COn(this.c,this.b),J$(this,_B(n,15))},EWn.gc=function(){return Dln(this.c,this.b)},EWn.Pc=function(){return H1(this.c,this.b)},EWn.Qc=function(n){return G3(this.c,this.b,n)},EWn.Ib=function(){var n,t;for((t=new Tk).a+="[",n=yA(this.c,this.b);Dsn(n);)iO(t,mN(ivn(n))),Dsn(n)&&(t.a+=KWn);return t.a+="]",t.a},EWn.Xj=function(){COn(this.c,this.b)},gX(v9n,"FeatureMapUtil/FeatureEList",501),lAn(627,36,Z8n,f4),EWn.yi=function(n){return nln(this,n)},EWn.Di=function(n){var t,e,i,r;switch(this.d){case 1:case 2:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return this.g=n.zi(),1==n.xi()&&(this.d=1),!0;break;case 3:switch(n.xi()){case 3:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return this.d=5,s9(t=new wtn(2),this.g),s9(t,n.zi()),this.g=t,!0}break;case 5:switch(n.xi()){case 3:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return _B(this.g,14).Fc(n.zi()),!0}break;case 4:switch(n.xi()){case 3:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return this.d=1,this.g=n.zi(),!0;break;case 4:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return this.d=6,s9(r=new wtn(2),this.n),s9(r,n.Bi()),this.n=r,i=Mun(Hk(INt,1),oQn,25,15,[this.o,n.Ci()]),this.g=i,!0}break;case 6:switch(n.xi()){case 4:if(HC(n.Ai())===HC(this.c)&&nln(this,null)==n.yi(null))return _B(this.n,14).Fc(n.Bi()),rHn(i=_B(this.g,48),0,e=L8(INt,oQn,25,i.length+1,15,1),0,i.length),e[i.length]=n.Ci(),this.g=e,!0}}return!1},gX(v9n,"FeatureMapUtil/FeatureENotificationImpl",627),lAn(552,501,{20:1,28:1,52:1,14:1,15:1,58:1,76:1,153:1,215:1,1937:1,69:1,95:1},hq),EWn.dl=function(n,t){return LKn(this.c,n,t)},EWn.el=function(n,t,e){return MRn(this.c,n,t,e)},EWn.fl=function(n,t,e){return JBn(this.c,n,t,e)},EWn.gl=function(){return this},EWn.hl=function(n,t){return eHn(this.c,n,t)},EWn.il=function(n){return _B(tHn(this.c,this.b,n,!1),72).ak()},EWn.jl=function(n){return _B(tHn(this.c,this.b,n,!1),72).dd()},EWn.kl=function(){return this.a},EWn.ll=function(n){return!rdn(this.c,n)},EWn.ml=function(n,t){EHn(this.c,n,t)},EWn.nl=function(n){return qin(this.c,n)},EWn.ol=function(n){Dmn(this.c,n)},gX(v9n,"FeatureMapUtil/FeatureFeatureMap",552),lAn(1259,1,m9n,DC),EWn.Wj=function(n){return tHn(this.b,this.a,-1,n)},EWn.fj=function(){return!rdn(this.b,this.a)},EWn.Wb=function(n){EHn(this.b,this.a,n)},EWn.Xj=function(){COn(this.b,this.a)},gX(v9n,"FeatureMapUtil/FeatureValue",1259);var fLt=fq(I7n,"AnyType");lAn(666,60,_Vn,tk),gX(I7n,"InvalidDatatypeValueException",666);var lLt,bLt,wLt,dLt,gLt,pLt,vLt,mLt,yLt,kLt,jLt,ELt,TLt,MLt,SLt,PLt,ILt,CLt,OLt,ALt,$Lt,LLt,NLt,xLt,DLt,RLt,KLt,_Lt,FLt,BLt,HLt=fq(I7n,C7n),qLt=fq(I7n,O7n),GLt=fq(I7n,A7n);lAn(830,506,{105:1,92:1,90:1,56:1,49:1,97:1,843:1},xm),EWn._g=function(n,t,e){switch(n){case 0:return e?(!this.c&&(this.c=new kcn(this,0)),this.c):(!this.c&&(this.c=new kcn(this,0)),this.c.b);case 1:return e?(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)):(!this.c&&(this.c=new kcn(this,0)),_B(_B(YZ(this.c,(Gqn(),dLt)),153),215)).kl();case 2:return e?(!this.b&&(this.b=new kcn(this,2)),this.b):(!this.b&&(this.b=new kcn(this,2)),this.b.b)}return G9(this,n-fX(this.zh()),ttn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new Df),this.k).ck(),n),t,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.c&&(this.c=new kcn(this,0)),jKn(this.c,n,e);case 1:return(!this.c&&(this.c=new kcn(this,0)),_B(_B(YZ(this.c,(Gqn(),dLt)),153),69)).mk(n,e);case 2:return!this.b&&(this.b=new kcn(this,2)),jKn(this.b,n,e)}return _B(ttn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new Df),this.k).ck(),t),66).Nj().Rj(this,W7(this),t-fX(this.zh()),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.c&&0!=this.c.i;case 1:return!(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)).dc();case 2:return!!this.b&&0!=this.b.i}return I3(this,n-fX(this.zh()),ttn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.sh=function(n,t){switch(n){case 0:return!this.c&&(this.c=new kcn(this,0)),void ZU(this.c,t);case 1:return void(!this.c&&(this.c=new kcn(this,0)),_B(_B(YZ(this.c,(Gqn(),dLt)),153),215)).Wb(t);case 2:return!this.b&&(this.b=new kcn(this,2)),void ZU(this.b,t)}Abn(this,n-fX(this.zh()),ttn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new Df),this.k).ck(),n),t)},EWn.zh=function(){return Gqn(),wLt},EWn.Bh=function(n){switch(n){case 0:return!this.c&&(this.c=new kcn(this,0)),void uqn(this.c);case 1:return void(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)).$b();case 2:return!this.b&&(this.b=new kcn(this,2)),void uqn(this.b)}Bfn(this,n-fX(this.zh()),ttn(0==(2&this.j)?this.zh():(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.Ib=function(){var n;return 0!=(4&this.j)?M$n(this):((n=new sN(M$n(this))).a+=" (mixed: ",eO(n,this.c),n.a+=", anyAttribute: ",eO(n,this.b),n.a+=")",n.a)},gX($7n,"AnyTypeImpl",830),lAn(667,506,{105:1,92:1,90:1,56:1,49:1,97:1,2021:1,667:1},Rs),EWn._g=function(n,t,e){switch(n){case 0:return this.a;case 1:return this.b}return G9(this,n-fX((Gqn(),PLt)),ttn(0==(2&this.j)?PLt:(!this.k&&(this.k=new Df),this.k).ck(),n),t,e)},EWn.lh=function(n){switch(n){case 0:return null!=this.a;case 1:return null!=this.b}return I3(this,n-fX((Gqn(),PLt)),ttn(0==(2&this.j)?PLt:(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.sh=function(n,t){switch(n){case 0:return void mb(this,TD(t));case 1:return void yb(this,TD(t))}Abn(this,n-fX((Gqn(),PLt)),ttn(0==(2&this.j)?PLt:(!this.k&&(this.k=new Df),this.k).ck(),n),t)},EWn.zh=function(){return Gqn(),PLt},EWn.Bh=function(n){switch(n){case 0:return void(this.a=null);case 1:return void(this.b=null)}Bfn(this,n-fX((Gqn(),PLt)),ttn(0==(2&this.j)?PLt:(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.Ib=function(){var n;return 0!=(4&this.j)?M$n(this):((n=new sN(M$n(this))).a+=" (data: ",iO(n,this.a),n.a+=", target: ",iO(n,this.b),n.a+=")",n.a)},EWn.a=null,EWn.b=null,gX($7n,"ProcessingInstructionImpl",667),lAn(668,830,{105:1,92:1,90:1,56:1,49:1,97:1,843:1,2022:1,668:1},Rm),EWn._g=function(n,t,e){switch(n){case 0:return e?(!this.c&&(this.c=new kcn(this,0)),this.c):(!this.c&&(this.c=new kcn(this,0)),this.c.b);case 1:return e?(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)):(!this.c&&(this.c=new kcn(this,0)),_B(_B(YZ(this.c,(Gqn(),dLt)),153),215)).kl();case 2:return e?(!this.b&&(this.b=new kcn(this,2)),this.b):(!this.b&&(this.b=new kcn(this,2)),this.b.b);case 3:return!this.c&&(this.c=new kcn(this,0)),TD(eHn(this.c,(Gqn(),OLt),!0));case 4:return wK(this.a,(!this.c&&(this.c=new kcn(this,0)),TD(eHn(this.c,(Gqn(),OLt),!0))));case 5:return this.a}return G9(this,n-fX((Gqn(),CLt)),ttn(0==(2&this.j)?CLt:(!this.k&&(this.k=new Df),this.k).ck(),n),t,e)},EWn.lh=function(n){switch(n){case 0:return!!this.c&&0!=this.c.i;case 1:return!(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)).dc();case 2:return!!this.b&&0!=this.b.i;case 3:return!this.c&&(this.c=new kcn(this,0)),null!=TD(eHn(this.c,(Gqn(),OLt),!0));case 4:return null!=wK(this.a,(!this.c&&(this.c=new kcn(this,0)),TD(eHn(this.c,(Gqn(),OLt),!0))));case 5:return!!this.a}return I3(this,n-fX((Gqn(),CLt)),ttn(0==(2&this.j)?CLt:(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.sh=function(n,t){switch(n){case 0:return!this.c&&(this.c=new kcn(this,0)),void ZU(this.c,t);case 1:return void(!this.c&&(this.c=new kcn(this,0)),_B(_B(YZ(this.c,(Gqn(),dLt)),153),215)).Wb(t);case 2:return!this.b&&(this.b=new kcn(this,2)),void ZU(this.b,t);case 3:return void K0(this,TD(t));case 4:return void K0(this,dK(this.a,t));case 5:return void kb(this,_B(t,148))}Abn(this,n-fX((Gqn(),CLt)),ttn(0==(2&this.j)?CLt:(!this.k&&(this.k=new Df),this.k).ck(),n),t)},EWn.zh=function(){return Gqn(),CLt},EWn.Bh=function(n){switch(n){case 0:return!this.c&&(this.c=new kcn(this,0)),void uqn(this.c);case 1:return void(!this.c&&(this.c=new kcn(this,0)),_B(YZ(this.c,(Gqn(),dLt)),153)).$b();case 2:return!this.b&&(this.b=new kcn(this,2)),void uqn(this.b);case 3:return!this.c&&(this.c=new kcn(this,0)),void EHn(this.c,(Gqn(),OLt),null);case 4:return void K0(this,dK(this.a,null));case 5:return void(this.a=null)}Bfn(this,n-fX((Gqn(),CLt)),ttn(0==(2&this.j)?CLt:(!this.k&&(this.k=new Df),this.k).ck(),n))},gX($7n,"SimpleAnyTypeImpl",668),lAn(669,506,{105:1,92:1,90:1,56:1,49:1,97:1,2023:1,669:1},Dm),EWn._g=function(n,t,e){switch(n){case 0:return e?(!this.a&&(this.a=new kcn(this,0)),this.a):(!this.a&&(this.a=new kcn(this,0)),this.a.b);case 1:return e?(!this.b&&(this.b=new v9((wWn(),v$t),G$t,this,1)),this.b):(!this.b&&(this.b=new v9((wWn(),v$t),G$t,this,1)),C8(this.b));case 2:return e?(!this.c&&(this.c=new v9((wWn(),v$t),G$t,this,2)),this.c):(!this.c&&(this.c=new v9((wWn(),v$t),G$t,this,2)),C8(this.c));case 3:return!this.a&&(this.a=new kcn(this,0)),YZ(this.a,(Gqn(),LLt));case 4:return!this.a&&(this.a=new kcn(this,0)),YZ(this.a,(Gqn(),NLt));case 5:return!this.a&&(this.a=new kcn(this,0)),YZ(this.a,(Gqn(),DLt));case 6:return!this.a&&(this.a=new kcn(this,0)),YZ(this.a,(Gqn(),RLt))}return G9(this,n-fX((Gqn(),$Lt)),ttn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new Df),this.k).ck(),n),t,e)},EWn.jh=function(n,t,e){switch(t){case 0:return!this.a&&(this.a=new kcn(this,0)),jKn(this.a,n,e);case 1:return!this.b&&(this.b=new v9((wWn(),v$t),G$t,this,1)),_K(this.b,n,e);case 2:return!this.c&&(this.c=new v9((wWn(),v$t),G$t,this,2)),_K(this.c,n,e);case 5:return!this.a&&(this.a=new kcn(this,0)),ZD(YZ(this.a,(Gqn(),DLt)),n,e)}return _B(ttn(0==(2&this.j)?(Gqn(),$Lt):(!this.k&&(this.k=new Df),this.k).ck(),t),66).Nj().Rj(this,W7(this),t-fX((Gqn(),$Lt)),n,e)},EWn.lh=function(n){switch(n){case 0:return!!this.a&&0!=this.a.i;case 1:return!!this.b&&0!=this.b.f;case 2:return!!this.c&&0!=this.c.f;case 3:return!this.a&&(this.a=new kcn(this,0)),!FC(YZ(this.a,(Gqn(),LLt)));case 4:return!this.a&&(this.a=new kcn(this,0)),!FC(YZ(this.a,(Gqn(),NLt)));case 5:return!this.a&&(this.a=new kcn(this,0)),!FC(YZ(this.a,(Gqn(),DLt)));case 6:return!this.a&&(this.a=new kcn(this,0)),!FC(YZ(this.a,(Gqn(),RLt)))}return I3(this,n-fX((Gqn(),$Lt)),ttn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.sh=function(n,t){switch(n){case 0:return!this.a&&(this.a=new kcn(this,0)),void ZU(this.a,t);case 1:return!this.b&&(this.b=new v9((wWn(),v$t),G$t,this,1)),void Zcn(this.b,t);case 2:return!this.c&&(this.c=new v9((wWn(),v$t),G$t,this,2)),void Zcn(this.c,t);case 3:return!this.a&&(this.a=new kcn(this,0)),$v(YZ(this.a,(Gqn(),LLt))),!this.a&&(this.a=new kcn(this,0)),void J$(YZ(this.a,LLt),_B(t,14));case 4:return!this.a&&(this.a=new kcn(this,0)),$v(YZ(this.a,(Gqn(),NLt))),!this.a&&(this.a=new kcn(this,0)),void J$(YZ(this.a,NLt),_B(t,14));case 5:return!this.a&&(this.a=new kcn(this,0)),$v(YZ(this.a,(Gqn(),DLt))),!this.a&&(this.a=new kcn(this,0)),void J$(YZ(this.a,DLt),_B(t,14));case 6:return!this.a&&(this.a=new kcn(this,0)),$v(YZ(this.a,(Gqn(),RLt))),!this.a&&(this.a=new kcn(this,0)),void J$(YZ(this.a,RLt),_B(t,14))}Abn(this,n-fX((Gqn(),$Lt)),ttn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new Df),this.k).ck(),n),t)},EWn.zh=function(){return Gqn(),$Lt},EWn.Bh=function(n){switch(n){case 0:return!this.a&&(this.a=new kcn(this,0)),void uqn(this.a);case 1:return!this.b&&(this.b=new v9((wWn(),v$t),G$t,this,1)),void this.b.c.$b();case 2:return!this.c&&(this.c=new v9((wWn(),v$t),G$t,this,2)),void this.c.c.$b();case 3:return!this.a&&(this.a=new kcn(this,0)),void $v(YZ(this.a,(Gqn(),LLt)));case 4:return!this.a&&(this.a=new kcn(this,0)),void $v(YZ(this.a,(Gqn(),NLt)));case 5:return!this.a&&(this.a=new kcn(this,0)),void $v(YZ(this.a,(Gqn(),DLt)));case 6:return!this.a&&(this.a=new kcn(this,0)),void $v(YZ(this.a,(Gqn(),RLt)))}Bfn(this,n-fX((Gqn(),$Lt)),ttn(0==(2&this.j)?$Lt:(!this.k&&(this.k=new Df),this.k).ck(),n))},EWn.Ib=function(){var n;return 0!=(4&this.j)?M$n(this):((n=new sN(M$n(this))).a+=" (mixed: ",eO(n,this.a),n.a+=")",n.a)},gX($7n,"XMLTypeDocumentRootImpl",669),lAn(1919,704,{105:1,92:1,90:1,471:1,147:1,56:1,108:1,49:1,97:1,150:1,114:1,115:1,2024:1},Ds),EWn.Ih=function(n,t){switch(n.yj()){case 7:case 8:case 9:case 10:case 16:case 22:case 23:case 24:case 25:case 26:case 32:case 33:case 34:case 36:case 37:case 44:case 45:case 50:case 51:case 53:case 55:case 56:case 57:case 58:case 60:case 61:case 4:return null==t?null:_bn(t);case 19:case 28:case 29:case 35:case 38:case 39:case 41:case 46:case 52:case 54:case 5:return TD(t);case 6:return pD(_B(t,190));case 12:case 47:case 49:case 11:return BGn(this,n,t);case 13:return null==t?null:HBn(_B(t,240));case 15:case 14:return null==t?null:xU(Hy(ED(t)));case 17:return kEn((Gqn(),t));case 18:return kEn(t);case 21:case 20:return null==t?null:DU(_B(t,155).a);case 27:return vD(_B(t,190));case 30:return Rmn((Gqn(),_B(t,15)));case 31:return Rmn(_B(t,15));case 40:return yD((Gqn(),t));case 42:return jEn((Gqn(),t));case 43:return jEn(t);case 59:case 48:return mD((Gqn(),t));default:throw Fp(new Ry(b6n+n.ne()+w6n))}},EWn.Jh=function(n){var t;switch(-1==n.G&&(n.G=(t=Gtn(n))?cvn(t.Mh(),n):-1),n.G){case 0:return new xm;case 1:return new Rs;case 2:return new Rm;case 3:return new Dm;default:throw Fp(new Ry(p6n+n.zb+w6n))}},EWn.Kh=function(n,t){var e,i,r,c,a,u,o,s,h,f,l,b,w,d,g,p;switch(n.yj()){case 5:case 52:case 4:return t;case 6:return vpn(t);case 8:case 7:return null==t?null:REn(t);case 9:return null==t?null:Mnn(h_n((i=KBn(t,!0)).length>0&&(f1(0,i.length),43==i.charCodeAt(0))?i.substr(1):i,-128,127)<<24>>24);case 10:return null==t?null:Mnn(h_n((r=KBn(t,!0)).length>0&&(f1(0,r.length),43==r.charCodeAt(0))?r.substr(1):r,-128,127)<<24>>24);case 11:return TD(LXn(this,(Gqn(),vLt),t));case 12:return TD(LXn(this,(Gqn(),mLt),t));case 13:return null==t?null:new lE(KBn(t,!0));case 15:case 14:return wLn(t);case 16:return TD(LXn(this,(Gqn(),yLt),t));case 17:return Fdn((Gqn(),t));case 18:return Fdn(t);case 28:case 29:case 35:case 38:case 39:case 41:case 54:case 19:return KBn(t,!0);case 21:case 20:return PLn(t);case 22:return TD(LXn(this,(Gqn(),kLt),t));case 23:return TD(LXn(this,(Gqn(),jLt),t));case 24:return TD(LXn(this,(Gqn(),ELt),t));case 25:return TD(LXn(this,(Gqn(),TLt),t));case 26:return TD(LXn(this,(Gqn(),MLt),t));case 27:return Jgn(t);case 30:return Bdn((Gqn(),t));case 31:return Bdn(t);case 32:return null==t?null:tln(h_n((h=KBn(t,!0)).length>0&&(f1(0,h.length),43==h.charCodeAt(0))?h.substr(1):h,RVn,NWn));case 33:return null==t?null:new OA((f=KBn(t,!0)).length>0&&(f1(0,f.length),43==f.charCodeAt(0))?f.substr(1):f);case 34:return null==t?null:tln(h_n((l=KBn(t,!0)).length>0&&(f1(0,l.length),43==l.charCodeAt(0))?l.substr(1):l,RVn,NWn));case 36:return null==t?null:ygn(eUn((b=KBn(t,!0)).length>0&&(f1(0,b.length),43==b.charCodeAt(0))?b.substr(1):b));case 37:return null==t?null:ygn(eUn((w=KBn(t,!0)).length>0&&(f1(0,w.length),43==w.charCodeAt(0))?w.substr(1):w));case 40:return Xwn((Gqn(),t));case 42:return Hdn((Gqn(),t));case 43:return Hdn(t);case 44:return null==t?null:new OA((d=KBn(t,!0)).length>0&&(f1(0,d.length),43==d.charCodeAt(0))?d.substr(1):d);case 45:return null==t?null:new OA((g=KBn(t,!0)).length>0&&(f1(0,g.length),43==g.charCodeAt(0))?g.substr(1):g);case 46:return KBn(t,!1);case 47:return TD(LXn(this,(Gqn(),SLt),t));case 59:case 48:return Uwn((Gqn(),t));case 49:return TD(LXn(this,(Gqn(),ILt),t));case 50:return null==t?null:eln(h_n((p=KBn(t,!0)).length>0&&(f1(0,p.length),43==p.charCodeAt(0))?p.substr(1):p,W9n,32767)<<16>>16);case 51:return null==t?null:eln(h_n((c=KBn(t,!0)).length>0&&(f1(0,c.length),43==c.charCodeAt(0))?c.substr(1):c,W9n,32767)<<16>>16);case 53:return TD(LXn(this,(Gqn(),ALt),t));case 55:return null==t?null:eln(h_n((a=KBn(t,!0)).length>0&&(f1(0,a.length),43==a.charCodeAt(0))?a.substr(1):a,W9n,32767)<<16>>16);case 56:return null==t?null:eln(h_n((u=KBn(t,!0)).length>0&&(f1(0,u.length),43==u.charCodeAt(0))?u.substr(1):u,W9n,32767)<<16>>16);case 57:return null==t?null:ygn(eUn((o=KBn(t,!0)).length>0&&(f1(0,o.length),43==o.charCodeAt(0))?o.substr(1):o));case 58:return null==t?null:ygn(eUn((s=KBn(t,!0)).length>0&&(f1(0,s.length),43==s.charCodeAt(0))?s.substr(1):s));case 60:return null==t?null:tln(h_n((e=KBn(t,!0)).length>0&&(f1(0,e.length),43==e.charCodeAt(0))?e.substr(1):e,RVn,NWn));case 61:return null==t?null:tln(h_n(KBn(t,!0),RVn,NWn));default:throw Fp(new Ry(b6n+n.ne()+w6n))}},gX($7n,"XMLTypeFactoryImpl",1919),lAn(586,179,{105:1,92:1,90:1,147:1,191:1,56:1,235:1,108:1,49:1,97:1,150:1,179:1,114:1,115:1,675:1,1945:1,586:1},qW),EWn.N=!1,EWn.O=!1;var zLt,ULt,XLt,WLt,VLt,QLt=!1;gX($7n,"XMLTypePackageImpl",586),lAn(1852,1,{837:1},Ks),EWn._j=function(){return sFn(),kNt},gX($7n,"XMLTypePackageImpl/1",1852),lAn(1861,1,u7n,_s),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/10",1861),lAn(1862,1,u7n,Fs),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/11",1862),lAn(1863,1,u7n,Bs),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/12",1863),lAn(1864,1,u7n,Hs),EWn.wj=function(n){return GC(n)},EWn.xj=function(n){return L8(Mtt,uVn,333,n,7,1)},gX($7n,"XMLTypePackageImpl/13",1864),lAn(1865,1,u7n,qs),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/14",1865),lAn(1866,1,u7n,Gs),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/15",1866),lAn(1867,1,u7n,zs),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/16",1867),lAn(1868,1,u7n,Us),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/17",1868),lAn(1869,1,u7n,Xs),EWn.wj=function(n){return iL(n,155)},EWn.xj=function(n){return L8(Stt,uVn,155,n,0,1)},gX($7n,"XMLTypePackageImpl/18",1869),lAn(1870,1,u7n,Ws),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/19",1870),lAn(1853,1,u7n,Vs),EWn.wj=function(n){return iL(n,843)},EWn.xj=function(n){return L8(fLt,FWn,843,n,0,1)},gX($7n,"XMLTypePackageImpl/2",1853),lAn(1871,1,u7n,Qs),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/20",1871),lAn(1872,1,u7n,Js),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/21",1872),lAn(1873,1,u7n,Ys),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/22",1873),lAn(1874,1,u7n,Zs),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/23",1874),lAn(1875,1,u7n,nh),EWn.wj=function(n){return iL(n,190)},EWn.xj=function(n){return L8(ANt,uVn,190,n,0,2)},gX($7n,"XMLTypePackageImpl/24",1875),lAn(1876,1,u7n,th),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/25",1876),lAn(1877,1,u7n,eh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/26",1877),lAn(1878,1,u7n,ih),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/27",1878),lAn(1879,1,u7n,rh),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/28",1879),lAn(1880,1,u7n,ch),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/29",1880),lAn(1854,1,u7n,ah),EWn.wj=function(n){return iL(n,667)},EWn.xj=function(n){return L8(HLt,FWn,2021,n,0,1)},gX($7n,"XMLTypePackageImpl/3",1854),lAn(1881,1,u7n,uh),EWn.wj=function(n){return iL(n,19)},EWn.xj=function(n){return L8(Ctt,uVn,19,n,0,1)},gX($7n,"XMLTypePackageImpl/30",1881),lAn(1882,1,u7n,oh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/31",1882),lAn(1883,1,u7n,sh),EWn.wj=function(n){return iL(n,162)},EWn.xj=function(n){return L8(xtt,uVn,162,n,0,1)},gX($7n,"XMLTypePackageImpl/32",1883),lAn(1884,1,u7n,hh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/33",1884),lAn(1885,1,u7n,fh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/34",1885),lAn(1886,1,u7n,lh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/35",1886),lAn(1887,1,u7n,bh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/36",1887),lAn(1888,1,u7n,wh),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/37",1888),lAn(1889,1,u7n,dh),EWn.wj=function(n){return iL(n,15)},EWn.xj=function(n){return L8(xnt,YYn,15,n,0,1)},gX($7n,"XMLTypePackageImpl/38",1889),lAn(1890,1,u7n,gh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/39",1890),lAn(1855,1,u7n,ph),EWn.wj=function(n){return iL(n,668)},EWn.xj=function(n){return L8(qLt,FWn,2022,n,0,1)},gX($7n,"XMLTypePackageImpl/4",1855),lAn(1891,1,u7n,vh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/40",1891),lAn(1892,1,u7n,mh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/41",1892),lAn(1893,1,u7n,yh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/42",1893),lAn(1894,1,u7n,kh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/43",1894),lAn(1895,1,u7n,jh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/44",1895),lAn(1896,1,u7n,Eh),EWn.wj=function(n){return iL(n,184)},EWn.xj=function(n){return L8(Rtt,uVn,184,n,0,1)},gX($7n,"XMLTypePackageImpl/45",1896),lAn(1897,1,u7n,Th),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/46",1897),lAn(1898,1,u7n,Mh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/47",1898),lAn(1899,1,u7n,Sh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/48",1899),lAn(uQn,1,u7n,Ph),EWn.wj=function(n){return iL(n,184)},EWn.xj=function(n){return L8(Rtt,uVn,184,n,0,1)},gX($7n,"XMLTypePackageImpl/49",uQn),lAn(1856,1,u7n,Ih),EWn.wj=function(n){return iL(n,669)},EWn.xj=function(n){return L8(GLt,FWn,2023,n,0,1)},gX($7n,"XMLTypePackageImpl/5",1856),lAn(1901,1,u7n,Ch),EWn.wj=function(n){return iL(n,162)},EWn.xj=function(n){return L8(xtt,uVn,162,n,0,1)},gX($7n,"XMLTypePackageImpl/50",1901),lAn(1902,1,u7n,Oh),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/51",1902),lAn(1903,1,u7n,Ah),EWn.wj=function(n){return iL(n,19)},EWn.xj=function(n){return L8(Ctt,uVn,19,n,0,1)},gX($7n,"XMLTypePackageImpl/52",1903),lAn(1857,1,u7n,$h),EWn.wj=function(n){return zC(n)},EWn.xj=function(n){return L8(Wtt,uVn,2,n,6,1)},gX($7n,"XMLTypePackageImpl/6",1857),lAn(1858,1,u7n,Lh),EWn.wj=function(n){return iL(n,190)},EWn.xj=function(n){return L8(ANt,uVn,190,n,0,2)},gX($7n,"XMLTypePackageImpl/7",1858),lAn(1859,1,u7n,Nh),EWn.wj=function(n){return qC(n)},EWn.xj=function(n){return L8(mtt,uVn,476,n,8,1)},gX($7n,"XMLTypePackageImpl/8",1859),lAn(1860,1,u7n,xh),EWn.wj=function(n){return iL(n,217)},EWn.xj=function(n){return L8(jtt,uVn,217,n,0,1)},gX($7n,"XMLTypePackageImpl/9",1860),lAn(50,60,_Vn,rk),gX(rnt,"RegEx/ParseException",50),lAn(820,1,{},Dh),EWn.sl=function(n){return n16*e)throw Fp(new rk(mWn((c$(),F8n))));e=16*e+r}if(125!=this.a)throw Fp(new rk(mWn((c$(),B8n))));if(e>cnt)throw Fp(new rk(mWn((c$(),H8n))));n=e}else{if(r=0,0!=this.c||(r=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(e=r,WXn(this),0!=this.c||(r=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));n=e=16*e+r}break;case 117:if(i=0,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));n=t=16*t+i;break;case 118:if(WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if(t=16*t+i,WXn(this),0!=this.c||(i=Hvn(this.a))<0)throw Fp(new rk(mWn((c$(),_8n))));if((t=16*t+i)>cnt)throw Fp(new rk(mWn((c$(),"parser.descappe.4"))));n=t;break;case 65:case 90:case 122:throw Fp(new rk(mWn((c$(),q8n))))}return n},EWn.ul=function(n){var t;switch(n){case 100:t=32==(32&this.e)?JUn("Nd",!0):(lWn(),rNt);break;case 68:t=32==(32&this.e)?JUn("Nd",!1):(lWn(),sNt);break;case 119:t=32==(32&this.e)?JUn("IsWord",!0):(lWn(),vNt);break;case 87:t=32==(32&this.e)?JUn("IsWord",!1):(lWn(),fNt);break;case 115:t=32==(32&this.e)?JUn("IsSpace",!0):(lWn(),bNt);break;case 83:t=32==(32&this.e)?JUn("IsSpace",!1):(lWn(),hNt);break;default:throw Fp(new by(ant+n.toString(16)))}return t},EWn.vl=function(n){var t,e,i,r,c,a,u,o,s,h,f;for(this.b=1,WXn(this),t=null,0==this.c&&94==this.a?(WXn(this),n?(lWn(),lWn(),s=new E0(5)):(lWn(),lWn(),Vxn(t=new E0(4),0,cnt),s=new E0(4))):(lWn(),lWn(),s=new E0(4)),r=!0;1!=(f=this.c)&&(0!=f||93!=this.a||r);){if(r=!1,e=this.a,i=!1,10==f)switch(e){case 100:case 68:case 119:case 87:case 115:case 83:uHn(s,this.ul(e)),i=!0;break;case 105:case 73:case 99:case 67:(e=this.Ll(s,e))<0&&(i=!0);break;case 112:case 80:if(!(h=NCn(this,e)))throw Fp(new rk(mWn((c$(),I8n))));uHn(s,h),i=!0;break;default:e=this.tl()}else if(20==f){if((c=hx(this.i,58,this.d))<0)throw Fp(new rk(mWn((c$(),C8n))));if(a=!0,94==sV(this.i,this.d)&&(++this.d,a=!1),!(u=f9(sx(this.i,this.d,c),a,512==(512&this.e))))throw Fp(new rk(mWn((c$(),A8n))));if(uHn(s,u),i=!0,c+1>=this.j||93!=sV(this.i,c+1))throw Fp(new rk(mWn((c$(),C8n))));this.d=c+2}if(WXn(this),!i)if(0!=this.c||45!=this.a)Vxn(s,e,e);else{if(WXn(this),1==(f=this.c))throw Fp(new rk(mWn((c$(),O8n))));0==f&&93==this.a?(Vxn(s,e,e),Vxn(s,45,45)):(o=this.a,10==f&&(o=this.tl()),WXn(this),Vxn(s,e,o))}(this.e&m6n)==m6n&&0==this.c&&44==this.a&&WXn(this)}if(1==this.c)throw Fp(new rk(mWn((c$(),O8n))));return t&&(UGn(t,s),s=t),j$n(s),BHn(s),this.b=0,WXn(this),s},EWn.wl=function(){var n,t,e,i;for(e=this.vl(!1);7!=(i=this.c);){if(n=this.a,(0!=i||45!=n&&38!=n)&&4!=i)throw Fp(new rk(mWn((c$(),R8n))));if(WXn(this),9!=this.c)throw Fp(new rk(mWn((c$(),D8n))));if(t=this.vl(!1),4==i)uHn(e,t);else if(45==n)UGn(e,t);else{if(38!=n)throw Fp(new by("ASSERT"));mGn(e,t)}}return WXn(this),e},EWn.xl=function(){var n,t;return n=this.a-48,lWn(),lWn(),t=new gY(12,null,n),!this.g&&(this.g=new Rv),Sv(this.g,new Ip(n)),WXn(this),t},EWn.yl=function(){return WXn(this),lWn(),wNt},EWn.zl=function(){return WXn(this),lWn(),lNt},EWn.Al=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Bl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Cl=function(){return WXn(this),ssn()},EWn.Dl=function(){return WXn(this),lWn(),gNt},EWn.El=function(){return WXn(this),lWn(),mNt},EWn.Fl=function(){var n;if(this.d>=this.j||64!=(65504&(n=sV(this.i,this.d++))))throw Fp(new rk(mWn((c$(),T8n))));return WXn(this),lWn(),lWn(),new aG(0,n-64)},EWn.Gl=function(){return WXn(this),xFn()},EWn.Hl=function(){return WXn(this),lWn(),yNt},EWn.Il=function(){var n;return lWn(),lWn(),n=new aG(0,105),WXn(this),n},EWn.Jl=function(){return WXn(this),lWn(),pNt},EWn.Kl=function(){return WXn(this),lWn(),dNt},EWn.Ll=function(n,t){return this.tl()},EWn.Ml=function(){return WXn(this),lWn(),uNt},EWn.Nl=function(){var n,t,e,i,r;if(this.d+1>=this.j)throw Fp(new rk(mWn((c$(),k8n))));if(i=-1,t=null,49<=(n=sV(this.i,this.d))&&n<=57){if(i=n-48,!this.g&&(this.g=new Rv),Sv(this.g,new Ip(i)),++this.d,41!=sV(this.i,this.d))throw Fp(new rk(mWn((c$(),v8n))));++this.d}else switch(63==n&&--this.d,WXn(this),(t=IXn(this)).e){case 20:case 21:case 22:case 23:break;case 8:if(7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));break;default:throw Fp(new rk(mWn((c$(),j8n))))}if(WXn(this),e=null,2==(r=Xdn(this)).e){if(2!=r.em())throw Fp(new rk(mWn((c$(),E8n))));e=r.am(1),r=r.am(0)}if(7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),lWn(),lWn(),new ynn(i,t,r,e)},EWn.Ol=function(){return WXn(this),lWn(),oNt},EWn.Pl=function(){var n;if(WXn(this),n=cU(24,Xdn(this)),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Ql=function(){var n;if(WXn(this),n=cU(20,Xdn(this)),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Rl=function(){var n;if(WXn(this),n=cU(22,Xdn(this)),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Sl=function(){var n,t,e,i,r;for(n=0,e=0,t=-1;this.d=this.j)throw Fp(new rk(mWn((c$(),m8n))));if(45==t){for(++this.d;this.d=this.j)throw Fp(new rk(mWn((c$(),m8n))))}if(58==t){if(++this.d,WXn(this),i=CX(Xdn(this),n,e),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));WXn(this)}else{if(41!=t)throw Fp(new rk(mWn((c$(),y8n))));++this.d,WXn(this),i=CX(Xdn(this),n,e)}return i},EWn.Tl=function(){var n;if(WXn(this),n=cU(21,Xdn(this)),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Ul=function(){var n;if(WXn(this),n=cU(23,Xdn(this)),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Vl=function(){var n,t;if(WXn(this),n=this.f++,t=aU(Xdn(this),n),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),t},EWn.Wl=function(){var n;if(WXn(this),n=aU(Xdn(this),0),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Xl=function(n){return WXn(this),5==this.c?(WXn(this),wG(n,(lWn(),lWn(),new o4(9,n)))):wG(n,(lWn(),lWn(),new o4(3,n)))},EWn.Yl=function(n){var t;return WXn(this),lWn(),lWn(),t=new e$(2),5==this.c?(WXn(this),ZHn(t,aNt),ZHn(t,n)):(ZHn(t,n),ZHn(t,aNt)),t},EWn.Zl=function(n){return WXn(this),5==this.c?(WXn(this),lWn(),lWn(),new o4(9,n)):(lWn(),lWn(),new o4(3,n))},EWn.a=0,EWn.b=0,EWn.c=0,EWn.d=0,EWn.e=0,EWn.f=1,EWn.g=null,EWn.j=0,gX(rnt,"RegEx/RegexParser",820),lAn(1824,820,{},Km),EWn.sl=function(n){return!1},EWn.tl=function(){return BDn(this)},EWn.ul=function(n){return b_n(n)},EWn.vl=function(n){return JXn(this)},EWn.wl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.xl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.yl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.zl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Al=function(){return WXn(this),b_n(67)},EWn.Bl=function(){return WXn(this),b_n(73)},EWn.Cl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Dl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.El=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Fl=function(){return WXn(this),b_n(99)},EWn.Gl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Hl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Il=function(){return WXn(this),b_n(105)},EWn.Jl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Kl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Ll=function(n,t){return uHn(n,b_n(t)),-1},EWn.Ml=function(){return WXn(this),lWn(),lWn(),new aG(0,94)},EWn.Nl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Ol=function(){return WXn(this),lWn(),lWn(),new aG(0,36)},EWn.Pl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Ql=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Rl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Sl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Tl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Ul=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Vl=function(){var n;if(WXn(this),n=aU(Xdn(this),0),7!=this.c)throw Fp(new rk(mWn((c$(),v8n))));return WXn(this),n},EWn.Wl=function(){throw Fp(new rk(mWn((c$(),G8n))))},EWn.Xl=function(n){return WXn(this),wG(n,(lWn(),lWn(),new o4(3,n)))},EWn.Yl=function(n){var t;return WXn(this),lWn(),lWn(),ZHn(t=new e$(2),n),ZHn(t,aNt),t},EWn.Zl=function(n){return WXn(this),lWn(),lWn(),new o4(3,n)};var JLt=null,YLt=null;gX(rnt,"RegEx/ParserForXMLSchema",1824),lAn(117,1,vnt,Cp),EWn.$l=function(n){throw Fp(new by("Not supported."))},EWn._l=function(){return-1},EWn.am=function(n){return null},EWn.bm=function(){return null},EWn.cm=function(n){},EWn.dm=function(n){},EWn.em=function(){return 0},EWn.Ib=function(){return this.fm(0)},EWn.fm=function(n){return 11==this.e?".":""},EWn.e=0;var ZLt,nNt,tNt,eNt,iNt,rNt,cNt,aNt,uNt,oNt,sNt,hNt,fNt,lNt,bNt,wNt,dNt,gNt,pNt,vNt,mNt,yNt,kNt,jNt,ENt=null,TNt=null,MNt=null,SNt=gX(rnt,"RegEx/Token",117);lAn(136,117,{3:1,136:1,117:1},E0),EWn.fm=function(n){var t,e,i;if(4==this.e)if(this==cNt)e=".";else if(this==rNt)e="\\d";else if(this==vNt)e="\\w";else if(this==bNt)e="\\s";else{for((i=new Tk).a+="[",t=0;t0&&(i.a+=","),this.b[t]===this.b[t+1]?iO(i,rBn(this.b[t])):(iO(i,rBn(this.b[t])),i.a+="-",iO(i,rBn(this.b[t+1])));i.a+="]",e=i.a}else if(this==sNt)e="\\D";else if(this==fNt)e="\\W";else if(this==hNt)e="\\S";else{for((i=new Tk).a+="[^",t=0;t0&&(i.a+=","),this.b[t]===this.b[t+1]?iO(i,rBn(this.b[t])):(iO(i,rBn(this.b[t])),i.a+="-",iO(i,rBn(this.b[t+1])));i.a+="]",e=i.a}return e},EWn.a=!1,EWn.c=!1,gX(rnt,"RegEx/RangeToken",136),lAn(584,1,{584:1},Ip),EWn.a=0,gX(rnt,"RegEx/RegexParser/ReferencePosition",584),lAn(583,1,{3:1,583:1},zE),EWn.Fb=function(n){var t;return null!=n&&!!iL(n,583)&&(t=_B(n,583),pK(this.b,t.b)&&this.a==t.a)},EWn.Hb=function(){return gvn(this.b+"/"+ZNn(this.a))},EWn.Ib=function(){return this.c.fm(this.a)},EWn.a=0,gX(rnt,"RegEx/RegularExpression",583),lAn(223,117,vnt,aG),EWn._l=function(){return this.a},EWn.fm=function(n){var t,e;switch(this.e){case 0:switch(this.a){case 124:case 42:case 43:case 63:case 40:case 41:case 46:case 91:case 123:case 92:e="\\"+MR(this.a&WVn);break;case 12:e="\\f";break;case 10:e="\\n";break;case 13:e="\\r";break;case 9:e="\\t";break;case 27:e="\\e";break;default:e=this.a>=_Qn?"\\v"+sx(t="0"+(this.a>>>0).toString(16),t.length-6,t.length):""+MR(this.a&WVn)}break;case 8:e=this==uNt||this==oNt?""+MR(this.a&WVn):"\\"+MR(this.a&WVn);break;default:e=null}return e},EWn.a=0,gX(rnt,"RegEx/Token/CharToken",223),lAn(309,117,vnt,o4),EWn.am=function(n){return this.a},EWn.cm=function(n){this.b=n},EWn.dm=function(n){this.c=n},EWn.em=function(){return 1},EWn.fm=function(n){var t;if(3==this.e)if(this.c<0&&this.b<0)t=this.a.fm(n)+"*";else if(this.c==this.b)t=this.a.fm(n)+"{"+this.c+"}";else if(this.c>=0&&this.b>=0)t=this.a.fm(n)+"{"+this.c+","+this.b+"}";else{if(!(this.c>=0&&this.b<0))throw Fp(new by("Token#toString(): CLOSURE "+this.c+KWn+this.b));t=this.a.fm(n)+"{"+this.c+",}"}else if(this.c<0&&this.b<0)t=this.a.fm(n)+"*?";else if(this.c==this.b)t=this.a.fm(n)+"{"+this.c+"}?";else if(this.c>=0&&this.b>=0)t=this.a.fm(n)+"{"+this.c+","+this.b+"}?";else{if(!(this.c>=0&&this.b<0))throw Fp(new by("Token#toString(): NONGREEDYCLOSURE "+this.c+KWn+this.b));t=this.a.fm(n)+"{"+this.c+",}?"}return t},EWn.b=0,EWn.c=0,gX(rnt,"RegEx/Token/ClosureToken",309),lAn(821,117,vnt,GU),EWn.am=function(n){return 0==n?this.a:this.b},EWn.em=function(){return 2},EWn.fm=function(n){return 3==this.b.e&&this.b.am(0)==this.a?this.a.fm(n)+"+":9==this.b.e&&this.b.am(0)==this.a?this.a.fm(n)+"+?":this.a.fm(n)+""+this.b.fm(n)},gX(rnt,"RegEx/Token/ConcatToken",821),lAn(1822,117,vnt,ynn),EWn.am=function(n){if(0==n)return this.d;if(1==n)return this.b;throw Fp(new by("Internal Error: "+n))},EWn.em=function(){return this.b?2:1},EWn.fm=function(n){var t;return t=this.c>0?"(?("+this.c+")":8==this.a.e?"(?("+this.a+")":"(?"+this.a,this.b?t+=this.d+"|"+this.b+")":t+=this.d+")",t},EWn.c=0,gX(rnt,"RegEx/Token/ConditionToken",1822),lAn(1823,117,vnt,j0),EWn.am=function(n){return this.b},EWn.em=function(){return 1},EWn.fm=function(n){return"(?"+(0==this.a?"":ZNn(this.a))+(0==this.c?"":ZNn(this.c))+":"+this.b.fm(n)+")"},EWn.a=0,EWn.c=0,gX(rnt,"RegEx/Token/ModifierToken",1823),lAn(822,117,vnt,iW),EWn.am=function(n){return this.a},EWn.em=function(){return 1},EWn.fm=function(n){var t;switch(t=null,this.e){case 6:t=0==this.b?"(?:"+this.a.fm(n)+")":"("+this.a.fm(n)+")";break;case 20:t="(?="+this.a.fm(n)+")";break;case 21:t="(?!"+this.a.fm(n)+")";break;case 22:t="(?<="+this.a.fm(n)+")";break;case 23:t="(?"+this.a.fm(n)+")"}return t},EWn.b=0,gX(rnt,"RegEx/Token/ParenToken",822),lAn(521,117,{3:1,117:1,521:1},gY),EWn.bm=function(){return this.b},EWn.fm=function(n){return 12==this.e?"\\"+this.a:tAn(this.b)},EWn.a=0,gX(rnt,"RegEx/Token/StringToken",521),lAn(465,117,vnt,e$),EWn.$l=function(n){ZHn(this,n)},EWn.am=function(n){return _B(fW(this.a,n),117)},EWn.em=function(){return this.a?this.a.a.c.length:0},EWn.fm=function(n){var t,e,i,r,c;if(1==this.e){if(2==this.a.a.c.length)t=_B(fW(this.a,0),117),r=3==(e=_B(fW(this.a,1),117)).e&&e.am(0)==t?t.fm(n)+"+":9==e.e&&e.am(0)==t?t.fm(n)+"+?":t.fm(n)+""+e.fm(n);else{for(c=new Tk,i=0;i=this.c.b:this.a<=this.c.b},EWn.Sb=function(){return this.b>0},EWn.Tb=function(){return this.b},EWn.Vb=function(){return this.b-1},EWn.Qb=function(){throw Fp(new Zy(Tnt))},EWn.a=0,EWn.b=0,gX(knt,"ExclusiveRange/RangeIterator",254);var PNt=xW(M9n,"C"),INt=xW(I9n,"I"),CNt=xW(OWn,"Z"),ONt=xW(C9n,"J"),ANt=xW(T9n,"B"),$Nt=xW(S9n,"D"),LNt=xW(P9n,"F"),NNt=xW(O9n,"S"),xNt=fq("org.eclipse.elk.core.labels","ILabelManager"),DNt=fq(_6n,"DiagnosticChain"),RNt=fq(s7n,"ResourceSet"),KNt=gX(_6n,"InvocationTargetException",null),_Nt=(Nk(),s5),FNt=FNt=oEn;Jen(Wp),ucn("permProps",[[[Mnt,Snt],[Pnt,"gecko1_8"]],[[Mnt,Snt],[Pnt,"ie10"]],[[Mnt,Snt],[Pnt,"ie8"]],[[Mnt,Snt],[Pnt,"ie9"]],[[Mnt,Snt],[Pnt,"safari"]]]),FNt(null,"elk",null)}).call(this)}).call(this,void 0!==w?w:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],3:[function(n,t,e){function i(n,t){if(!(n instanceof t))throw new TypeError("Cannot call a class as a function")}function r(n,t){if(!n)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?n:t}function c(n,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);n.prototype=Object.create(t&&t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(n,t):n.__proto__=t)}var a=function(t){function e(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};i(this,e);var c=Object.assign({},t),a=!1;try{n.resolve("web-worker"),a=!0}catch(s){}if(t.workerUrl)if(a){var u=n("web-worker");c.workerFactory=function(n){return new u(n)}}else console.warn("Web worker requested but 'web-worker' package not installed. \nConsider installing the package or pass your own 'workerFactory' to ELK's constructor.\n... Falling back to non-web worker version.");if(!c.workerFactory){var o=n("./elk-worker.min.js").Worker;c.workerFactory=function(n){return new o(n)}}return r(this,(e.__proto__||Object.getPrototypeOf(e)).call(this,c))}return c(e,t),e}(n("./elk-api.js").default);Object.defineProperty(t.exports,"__esModule",{value:!0}),t.exports=a,a.default=a},{"./elk-api.js":1,"./elk-worker.min.js":2,"web-worker":4}],4:[function(n,t,e){t.exports=Worker},{}]},{},[3])(3);const m=new(d(v.exports));let y={};const k={};let j={};const E=(n,t,i)=>{const r={TB:{in:{north:"north"},out:{south:"west",west:"east",east:"south"}},LR:{in:{west:"west"},out:{east:"south",south:"north",north:"east"}},RL:{in:{east:"east"},out:{west:"north",north:"south",south:"west"}},BT:{in:{south:"south"},out:{north:"east",east:"west",west:"north"}}};return r.TD=r.TB,e.info("abc88",i,t,n),r[i][t][n]},T=(n,t,i)=>{if(e.info("getNextPort abc88",{node:n,edgeDirection:t,graphDirection:i}),!y[n])switch(i){case"TB":case"TD":y[n]={inPosition:"north",outPosition:"south"};break;case"BT":y[n]={inPosition:"south",outPosition:"north"};break;case"RL":y[n]={inPosition:"east",outPosition:"west"};break;case"LR":y[n]={inPosition:"west",outPosition:"east"}}const r="in"===t?y[n].inPosition:y[n].outPosition;return"in"===t?y[n].inPosition=E(y[n].inPosition,t,i):y[n].outPosition=E(y[n].outPosition,t,i),r},M=function(n,t,i,r){e.info("abc78 edges = ",n);const c=r.insert("g").attr("class","edgeLabels");let h,f,l={},w=t.db.getDirection();if(void 0!==n.defaultStyle){const t=a(n.defaultStyle);h=t.style,f=t.labelStyle}return n.forEach((function(t){const r="L-"+t.start+"-"+t.end;void 0===l[r]?(l[r]=0,e.info("abc78 new entry",r,l[r])):(l[r]++,e.info("abc78 new entry",r,l[r]));let d=r+"-"+l[r];e.info("abc78 new link id to be used is",r,d,l[r]);const g="LS-"+t.start,p="LE-"+t.end,v={style:"",labelStyle:""};switch(v.minlen=t.length||1,"arrow_open"===t.type?v.arrowhead="none":v.arrowhead="normal",v.arrowTypeStart="arrow_open",v.arrowTypeEnd="arrow_open",t.type){case"double_arrow_cross":v.arrowTypeStart="arrow_cross";case"arrow_cross":v.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":v.arrowTypeStart="arrow_point";case"arrow_point":v.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":v.arrowTypeStart="arrow_circle";case"arrow_circle":v.arrowTypeEnd="arrow_circle"}let m="",y="";switch(t.stroke){case"normal":m="fill:none;",void 0!==h&&(m=h),void 0!==f&&(y=f),v.thickness="normal",v.pattern="solid";break;case"dotted":v.thickness="normal",v.pattern="dotted",v.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":v.thickness="thick",v.pattern="solid",v.style="stroke-width: 3.5px;fill:none;"}if(void 0!==t.style){const n=a(t.style);m=n.style,y=n.labelStyle}v.style=v.style+=m,v.labelStyle=v.labelStyle+=y,void 0!==t.interpolate?v.curve=u(t.interpolate,o):void 0!==n.defaultInterpolate?v.curve=u(n.defaultInterpolate,o):v.curve=u(k.curve,o),void 0===t.text?void 0!==t.style&&(v.arrowheadStyle="fill: #333"):(v.arrowheadStyle="fill: #333",v.labelpos="c"),v.labelType=t.labelType,v.label=t.text.replace(s.lineBreakRegex,"\n"),void 0===t.style&&(v.style=v.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),v.labelStyle=v.labelStyle.replace("color:","fill:"),v.id=d,v.classes="flowchart-link "+g+" "+p;const E=b(c,v),{source:M,target:S,sourceId:P,targetId:I}=((n,t)=>{let e=n.start,i=n.end;const r=e,c=i,a=j[e],u=j[i];return a&&u?("diamond"===a.type&&(e=`${e}-${T(e,"out",t)}`),"diamond"===u.type&&(i=`${i}-${T(i,"in",t)}`),{source:e,target:i,sourceId:r,targetId:c}):{source:e,target:i}})(t,w);e.debug("abc78 source and target",M,S),i.edges.push({id:"e"+t.start+t.end,sources:[M],targets:[S],sourceId:P,targetId:I,labelEl:E,labels:[{width:v.width,height:v.height,orgWidth:v.width,orgHeight:v.height,text:v.label,layoutOptions:{"edgeLabels.inline":"true","edgeLabels.placement":"CENTER"}}],edgeData:v})})),i},S=function(n,t,e){const i=((n,t,e)=>{const{parentById:i}=e,r=new Set;let c=n;for(;c;){if(r.add(c),c===t)return c;c=i[c]}for(c=t;c;){if(r.has(c))return c;c=i[c]}return"root"})(n,t,e);if(void 0===i||"root"===i)return{x:0,y:0};const r=j[i].offset;return{x:r.posX,y:r.posY}},P=function(n,t,e,r,c){const a=S(t.sourceId,t.targetId,c),u=t.sections[0].startPoint,s=t.sections[0].endPoint,h=(t.sections[0].bendPoints?t.sections[0].bendPoints:[]).map((n=>[n.x+a.x,n.y+a.y])),f=[[u.x+a.x,u.y+a.y],...h,[s.x+a.x,s.y+a.y]],l=p().curve(o),b=n.insert("path").attr("d",l(f)).attr("class","path").attr("fill","none"),w=n.insert("g").attr("class","edgeLabel"),d=i(w.node().appendChild(t.labelEl)),g=d.node().firstChild.getBoundingClientRect();d.attr("width",g.width),d.attr("height",g.height),w.attr("transform",`translate(${t.labels[0].x+a.x}, ${t.labels[0].y+a.y})`),function(n,t,e,i){let r="";switch(i&&(r=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,r=r.replace(/\(/g,"\\("),r=r.replace(/\)/g,"\\)")),t.arrowTypeStart){case"arrow_cross":n.attr("marker-start","url("+r+"#"+e+"-crossStart)");break;case"arrow_point":n.attr("marker-start","url("+r+"#"+e+"-pointStart)");break;case"arrow_barb":n.attr("marker-start","url("+r+"#"+e+"-barbStart)");break;case"arrow_circle":n.attr("marker-start","url("+r+"#"+e+"-circleStart)");break;case"aggregation":n.attr("marker-start","url("+r+"#"+e+"-aggregationStart)");break;case"extension":n.attr("marker-start","url("+r+"#"+e+"-extensionStart)");break;case"composition":n.attr("marker-start","url("+r+"#"+e+"-compositionStart)");break;case"dependency":n.attr("marker-start","url("+r+"#"+e+"-dependencyStart)");break;case"lollipop":n.attr("marker-start","url("+r+"#"+e+"-lollipopStart)")}switch(t.arrowTypeEnd){case"arrow_cross":n.attr("marker-end","url("+r+"#"+e+"-crossEnd)");break;case"arrow_point":n.attr("marker-end","url("+r+"#"+e+"-pointEnd)");break;case"arrow_barb":n.attr("marker-end","url("+r+"#"+e+"-barbEnd)");break;case"arrow_circle":n.attr("marker-end","url("+r+"#"+e+"-circleEnd)");break;case"aggregation":n.attr("marker-end","url("+r+"#"+e+"-aggregationEnd)");break;case"extension":n.attr("marker-end","url("+r+"#"+e+"-extensionEnd)");break;case"composition":n.attr("marker-end","url("+r+"#"+e+"-compositionEnd)");break;case"dependency":n.attr("marker-end","url("+r+"#"+e+"-dependencyEnd)");break;case"lollipop":n.attr("marker-end","url("+r+"#"+e+"-lollipopEnd)")}}(b,e,r.type,r.arrowMarkerAbsolute)},I=(n,t)=>{n.forEach((n=>{n.children||(n.children=[]);const e=t.childrenById[n.id];e&&e.forEach((t=>{n.children.push(j[t])})),I(n.children,t)}))},C=(n,t,i,c,a,u,o)=>{i.forEach((function(i){if(i)if(j[i.id].offset={posX:i.x+n,posY:i.y+t,x:n,y:t,depth:o,width:i.width,height:i.height},"group"===i.type){const c=a.insert("g").attr("class","subgraph");c.insert("rect").attr("class","subgraph subgraph-lvl-"+o%5+" node").attr("x",i.x+n).attr("y",i.y+t).attr("width",i.width).attr("height",i.height);const u=c.insert("g").attr("class","label"),s=r().flowchart.htmlLabels?i.labelData.width/2:0;u.attr("transform",`translate(${i.labels[0].x+n+i.x+s}, ${i.labels[0].y+t+i.y+3})`),u.node().appendChild(i.labelData.labelNode),e.info("Id (UGH)= ",i.type,i.labels)}else e.info("Id (UGH)= ",i.id),i.el.attr("transform",`translate(${i.x+n+i.width/2}, ${i.y+t+i.height/2})`)})),i.forEach((function(e){e&&"group"===e.type&&C(n+e.x,t+e.y,e.children,c,a,u,o+1)}))},O={db:n,renderer:{getClasses:function(n,t){e.info("Extracting classes"),t.db.clear("ver-2");try{return t.parse(n),t.db.getClasses()}catch(i){return{}}},draw:async function(n,t,u,o){var s;o.db.clear(),j={},y={},o.db.setGen("gen-2"),o.parser.parse(n);const b=i("body").append("div").attr("style","height:400px").attr("id","cy");let w={id:"root",layoutOptions:{"elk.hierarchyHandling":"INCLUDE_CHILDREN","org.eclipse.elk.padding":"[top=100, left=100, bottom=110, right=110]","elk.layered.spacing.edgeNodeBetweenLayers":"30","elk.direction":"DOWN"},children:[],edges:[]};switch(e.info("Drawing flowchart using v3 renderer",m),o.db.getDirection()){case"BT":w.layoutOptions["elk.direction"]="UP";break;case"TB":w.layoutOptions["elk.direction"]="DOWN";break;case"LR":w.layoutOptions["elk.direction"]="RIGHT";break;case"RL":w.layoutOptions["elk.direction"]="LEFT"}const{securityLevel:d,flowchart:g}=r();let p;"sandbox"===d&&(p=i("#i"+t));const v=i("sandbox"===d?p.nodes()[0].contentDocument.body:"body"),k="sandbox"===d?p.nodes()[0].contentDocument:document,E=v.select(`[id="${t}"]`);h(E,["point","circle","cross"],o.type,o.arrowMarkerAbsolute);const T=o.db.getVertices();let S;const O=o.db.getSubGraphs();e.info("Subgraphs - ",O);for(let e=O.length-1;e>=0;e--)S=O[e],o.db.addVertex(S.id,{text:S.title,type:S.labelType},"group",void 0,S.classes,S.dir);const A=E.insert("g").attr("class","subgraphs"),$=function(n){const t={parentById:{},childrenById:{}},i=n.getSubGraphs();return e.info("Subgraphs - ",i),i.forEach((function(n){n.nodes.forEach((function(e){t.parentById[e]=n.id,void 0===t.childrenById[n.id]&&(t.childrenById[n.id]=[]),t.childrenById[n.id].push(e)}))})),i.forEach((function(n){n.id,void 0!==t.parentById[n.id]&&t.parentById[n.id]})),t}(o.db);w=await async function(n,t,e,i,c,u,o){const s=e.select(`[id="${t}"]`).insert("g").attr("class","nodes"),h=Object.keys(n);return await Promise.all(h.map((async function(t){const e=n[t];let o="default";e.classes.length>0&&(o=e.classes.join(" ")),o+=" flowchart-label";const h=a(e.styles);let b=void 0!==e.text?e.text:e.id;const w={width:0,height:0},d=[{id:e.id+"-west",layoutOptions:{"port.side":"WEST"}},{id:e.id+"-east",layoutOptions:{"port.side":"EAST"}},{id:e.id+"-south",layoutOptions:{"port.side":"SOUTH"}},{id:e.id+"-north",layoutOptions:{"port.side":"NORTH"}}];let g=0,p="",v={};switch(e.type){case"round":g=5,p="rect";break;case"square":p="rect";break;case"diamond":p="question",v={portConstraints:"FIXED_SIDE"};break;case"hexagon":p="hexagon";break;case"odd":p="rect_left_inv_arrow";break;case"lean_right":p="lean_right";break;case"lean_left":p="lean_left";break;case"trapezoid":p="trapezoid";break;case"inv_trapezoid":p="inv_trapezoid";break;case"odd_right":p="rect_left_inv_arrow";break;case"circle":p="circle";break;case"ellipse":p="ellipse";break;case"stadium":p="stadium";break;case"subroutine":p="subroutine";break;case"cylinder":p="cylinder";break;case"group":p="rect";break;case"doublecircle":p="doublecircle";break;default:p="rect"}const m={labelStyle:h.labelStyle,shape:p,labelText:b,labelType:e.labelType,rx:g,ry:g,class:o,style:h.style,id:e.id,link:e.link,linkTarget:e.linkTarget,tooltip:c.db.getTooltip(e.id)||"",domId:c.db.lookUpDomId(e.id),haveCallback:e.haveCallback,width:"group"===e.type?500:void 0,dir:e.dir,type:e.type,props:e.props,padding:r().flowchart.padding};let y,k;if("group"!==m.type)k=await f(s,m,e.dir),y=k.node().getBBox();else{i.createElementNS("http://www.w3.org/2000/svg","text");const{shapeSvg:n,bbox:t}=await l(s,m,void 0,!0);w.width=t.width,w.wrappingWidth=r().flowchart.wrappingWidth,w.height=t.height,w.labelNode=n.node(),m.labelData=w}const E={id:e.id,ports:"diamond"===e.type?d:[],layoutOptions:v,labelText:b,labelData:w,domId:c.db.lookUpDomId(e.id),width:null==y?void 0:y.width,height:null==y?void 0:y.height,type:e.type,el:k,parent:u.parentById[e.id]};j[m.id]=E}))),o}(T,t,v,k,o,$,w);const L=E.insert("g").attr("class","edges edgePath"),N=o.db.getEdges();w=M(N,o,w,E);Object.keys(j).forEach((n=>{const t=j[n];t.parent||w.children.push(t),void 0!==$.childrenById[n]&&(t.labels=[{text:t.labelText,layoutOptions:{"nodeLabels.placement":"[H_CENTER, V_TOP, INSIDE]"},width:t.labelData.width,height:t.labelData.height}],delete t.x,delete t.y,delete t.width,delete t.height)})),I(w.children,$),e.info("after layout",JSON.stringify(w,null,2));const x=await m.layout(w);C(0,0,x.children,E,A,o,0),e.info("after layout",x),null==(s=x.edges)||s.map((n=>{P(L,n,n.edgeData,o,$)})),c({},E,g.diagramPadding,g.useMaxWidth),b.remove()}},parser:t,styles:n=>`.label {\n font-family: ${n.fontFamily};\n color: ${n.nodeTextColor||n.textColor};\n }\n .cluster-label text {\n fill: ${n.titleColor};\n }\n .cluster-label span {\n color: ${n.titleColor};\n }\n\n .label text,span {\n fill: ${n.nodeTextColor||n.textColor};\n color: ${n.nodeTextColor||n.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${n.mainBkg};\n stroke: ${n.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${n.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${n.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${n.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${n.edgeLabelBackground};\n rect {\n opacity: 0.85;\n background-color: ${n.edgeLabelBackground};\n fill: ${n.edgeLabelBackground};\n }\n text-align: center;\n }\n\n .cluster rect {\n fill: ${n.clusterBkg};\n stroke: ${n.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${n.titleColor};\n }\n\n .cluster span {\n color: ${n.titleColor};\n }\n /* .cluster div {\n color: ${n.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${n.fontFamily};\n font-size: 12px;\n background: ${n.tertiaryColor};\n border: 1px solid ${n.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${n.textColor};\n }\n .subgraph {\n stroke-width:2;\n rx:3;\n }\n // .subgraph-lvl-1 {\n // fill:#ccc;\n // // stroke:black;\n // }\n\n .flowchart-label text {\n text-anchor: middle;\n }\n\n ${(n=>{let t="";for(let e=0;e<5;e++)t+=`\n .subgraph-lvl-${e} {\n fill: ${n[`surface${e}`]};\n stroke: ${n[`surfacePeer${e}`]};\n }\n `;return t})(n)}\n`};export{O as diagram}; diff --git a/assets/freedom.html.975ddd2c.js b/assets/freedom.html.2e43ea4a.js similarity index 96% rename from assets/freedom.html.975ddd2c.js rename to assets/freedom.html.2e43ea4a.js index 571b025c9..7647b0fd6 100644 --- a/assets/freedom.html.975ddd2c.js +++ b/assets/freedom.html.2e43ea4a.js @@ -1 +1 @@ -import{r as e,o as n,c as o,a as s,b as t,w as a,F as l,d as c,e as u}from"./app.755d843f.js";const p={},r=c('

    Freedom

    Freedom is an outbound protocol that can be used to send (normal) TCP or UDP data to any network.

    OutboundConfigurationObject

    {\n  "domainStrategy": "AsIs",\n  "redirect": "127.0.0.1:3366",\n  "userLevel": 0,\n  "fragment": {\n    "packets": "tlshello",\n    "length": "100-200",\n    "interval": "10-20" // ms\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    domainStrategy: "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"

    When the destination address is a domain name, configure the corresponding value for Freedom's behavior:

    ',6),i=s("li",null,[s("code",null,'"AsIs"'),u(": Freedom resolves the domain name using the system DNS server and connects to it.")],-1),d=s("code",null,'"UseIP"',-1),m=u(", "),h=s("code",null,'"UseIPv4"',-1),b=u(", and "),f=s("code",null,'"UseIPv6"',-1),q=u(": Xray resolves the domain name using the built-in "),k=u("DNS server"),g=u(" and connects to it. The default value is "),v=s("code",null,'"AsIs"',-1),y=u("."),I={class:"custom-container tip"},P=s("p",{class:"custom-container-title"},"TIP 1",-1),w=u("When using the "),T=s("code",null,'"UseIP"',-1),U=u(" mode and the "),j=s("code",null,"sendThrough",-1),F=u(" field is specified in the "),x=u("outbound connection configuration"),S=u(", Freedom will automatically determine the required IP type, IPv4 or IPv6, based on the value of "),A=s("code",null,"sendThrough",-1),L=u("."),W=c('

    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

    ',6),_=u("User level. The connection will use the corresponding "),C=u("local policy"),D=u(" for this user level."),N=u("The value of "),O=s("code",null,"userLevel",-1),R=u(" corresponds to the value of "),X=s("code",null,"level",-1),z=u(" in the "),B=u("policy"),E=u(". If not specified, the default value is 0."),G=s("blockquote",null,[s("p",null,[s("code",null,"fragment"),u(": map")])],-1),H=s("p",null,"A key-value map used to control TCP fragmentation,under some circumstances it can cheat the censor syetem, like bypass a SNI blacklist.",-1),J=s("p",null,[s("code",null,'"packets"'),u(':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.')],-1),K=s("p",null,[s("code",null,'"length"'),u(": length to make the cut")],-1),M=s("p",null,[s("code",null,'"interval"'),u(": time between fragments(ms)")],-1);p.render=function(c,u){const p=e("RouterLink");return n(),o(l,null,[r,s("ul",null,[i,s("li",null,[d,m,h,b,f,q,t(p,{to:"/en/config/dns.html"},{default:a((()=>[k])),_:1}),g,v,y])]),s("div",I,[P,s("p",null,[w,T,U,j,F,t(p,{to:"/en/config/outbound.html#outboundobject"},{default:a((()=>[x])),_:1}),S,A,L])]),W,s("p",null,[_,t(p,{to:"/en/config/policy.html#levelpolicyobject"},{default:a((()=>[C])),_:1}),D]),s("p",null,[N,O,R,X,z,t(p,{to:"/en/config/policy.html#policyobject"},{default:a((()=>[B])),_:1}),E]),G,H,J,K,M],64)};export default p; +import{r as e,o as n,c as o,a as s,b as t,w as a,F as l,d as c,e as u}from"./app.48111a85.js";const p={},r=c('

    Freedom

    Freedom is an outbound protocol that can be used to send (normal) TCP or UDP data to any network.

    OutboundConfigurationObject

    {\n  "domainStrategy": "AsIs",\n  "redirect": "127.0.0.1:3366",\n  "userLevel": 0,\n  "fragment": {\n    "packets": "tlshello",\n    "length": "100-200",\n    "interval": "10-20" // ms\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    domainStrategy: "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"

    When the destination address is a domain name, configure the corresponding value for Freedom's behavior:

    ',6),i=s("li",null,[s("code",null,'"AsIs"'),u(": Freedom resolves the domain name using the system DNS server and connects to it.")],-1),d=s("code",null,'"UseIP"',-1),m=u(", "),h=s("code",null,'"UseIPv4"',-1),b=u(", and "),q=s("code",null,'"UseIPv6"',-1),f=u(": Xray resolves the domain name using the built-in "),k=u("DNS server"),g=u(" and connects to it. The default value is "),v=s("code",null,'"AsIs"',-1),y=u("."),I={class:"custom-container tip"},P=s("p",{class:"custom-container-title"},"TIP 1",-1),w=u("When using the "),T=s("code",null,'"UseIP"',-1),U=u(" mode and the "),j=s("code",null,"sendThrough",-1),F=u(" field is specified in the "),x=u("outbound connection configuration"),S=u(", Freedom will automatically determine the required IP type, IPv4 or IPv6, based on the value of "),A=s("code",null,"sendThrough",-1),L=u("."),W=c('

    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

    ',6),_=u("User level. The connection will use the corresponding "),C=u("local policy"),D=u(" for this user level."),N=u("The value of "),O=s("code",null,"userLevel",-1),R=u(" corresponds to the value of "),X=s("code",null,"level",-1),z=u(" in the "),B=u("policy"),E=u(". If not specified, the default value is 0."),G=s("blockquote",null,[s("p",null,[s("code",null,"fragment"),u(": map")])],-1),H=s("p",null,"A key-value map used to control TCP fragmentation,under some circumstances it can cheat the censor syetem, like bypass a SNI blacklist.",-1),J=s("p",null,[s("code",null,'"packets"'),u(':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.')],-1),K=s("p",null,[s("code",null,'"length"'),u(": length to make the cut")],-1),M=s("p",null,[s("code",null,'"interval"'),u(": time between fragments(ms)")],-1);p.render=function(c,u){const p=e("RouterLink");return n(),o(l,null,[r,s("ul",null,[i,s("li",null,[d,m,h,b,q,f,t(p,{to:"/en/config/dns.html"},{default:a((()=>[k])),_:1}),g,v,y])]),s("div",I,[P,s("p",null,[w,T,U,j,F,t(p,{to:"/en/config/outbound.html#outboundobject"},{default:a((()=>[x])),_:1}),S,A,L])]),W,s("p",null,[_,t(p,{to:"/en/config/policy.html#levelpolicyobject"},{default:a((()=>[C])),_:1}),D]),s("p",null,[N,O,R,X,z,t(p,{to:"/en/config/policy.html#policyobject"},{default:a((()=>[B])),_:1}),E]),G,H,J,K,M],64)};export default p; diff --git a/assets/freedom.html.4928c41f.js b/assets/freedom.html.33bca468.js similarity index 98% rename from assets/freedom.html.4928c41f.js rename to assets/freedom.html.33bca468.js index 700719c48..11670a1b0 100644 --- a/assets/freedom.html.4928c41f.js +++ b/assets/freedom.html.33bca468.js @@ -1 +1 @@ -import{r as n,o as s,c as o,a as e,b as a,w as t,F as l,d as p,e as u}from"./app.755d843f.js";const c={},r=p('

    Freedom

    Freedom 是一个出站协议,可以用来向任意网络发送(正常的) TCP 或 UDP 数据。

    OutboundConfigurationObject

    {\n  "domainStrategy": "AsIs",\n  "redirect": "127.0.0.1:3366",\n  "userLevel": 0,\n  "fragment": {\n    "packets": "tlshello",\n    "length": "100-200",\n    "interval": "10-20" // ms\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    domainStrategy: "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"

    在目标地址为域名时, 配置相应的值, Freedom 的行为模式如下:

    ',6),d=e("li",null,[e("code",null,'"AsIs"'),u(": Freedom 通过系统 DNS 服务器解析获取 IP, 向此域名发出连接.")],-1),i=e("code",null,'"UseIP"',-1),q=u("、"),b=e("code",null,'"UseIPv4"',-1),m=u(" 和 "),k=e("code",null,'"UseIPv6"',-1),h=u(": Xray 使用 "),g=u("内置 DNS 服务器"),v=u(" 解析获取 IP, 向此域名发出连接. 默认值为 "),I=e("code",null,'"AsIs"',-1),P=u("。"),f={class:"custom-container tip"},y=e("p",{class:"custom-container-title"},"TIP 1",-1),j=u("当使用 "),F=e("code",null,'"UseIP"',-1),U=u(" 模式,并且 "),T=u("出站连接配置"),S=u(" 中指定了 "),x=e("code",null,"sendThrough",-1),L=u(" 时,Freedom 会根据 "),_=e("code",null,"sendThrough",-1),A=u(" 的值自动判断所需的 IP 类型,IPv4 或 IPv6。"),C=p('

    TIP 2

    当使用 "UseIPv4""UseIPv6" 模式时,Freedom 会只使用对应的 IPv4 或 IPv6 地址。当 sendThrough 指定了不匹配的本地地址时,将导致连接失败。

    redirect: address_port

    Freedom 会强制将所有数据发送到指定地址(而不是 inbound 指定的地址)。

    其值为一个字符串,样例:"127.0.0.1:80"":1234"

    当地址不指定时,如 ":443",Freedom 不会修改原先的目标地址。 当端口为 0 时,如 "xray.com: 0",Freedom 不会修改原先的端口。

    userLevel: number

    ',6),D=u("用户等级,连接会使用这个用户等级对应的 "),N=u("本地策略"),O=u("。"),w=u("userLevel 的值, 对应 "),R=u("policy"),X=u(" 中 "),z=e("code",null,"level",-1),B=u(" 的值。 如不指定, 默认为 0。"),E=e("blockquote",null,[e("p",null,[e("code",null,"fragment"),u(": map")])],-1),G=e("p",null,"一些键值对配置项,用于控制发出的 TCP 分片,在某些情况下可以欺骗审查系统,比如绕过 SNI 黑名单。",-1),H=e("p",null,[e("code",null,'"packets"'),u(':支持两种分片方式 "1-3" 是 TCP 的流切片,应用于客户端第 1 至第 3 次写数据。"tlshello" 是 TLS 握手包切片。')],-1),J=e("p",null,[e("code",null,'"length"'),u(":分片包长 (byte)")],-1),K=e("p",null,[e("code",null,'"interval"'),u(":分片间隔(ms)")],-1);c.render=function(p,u){const c=n("RouterLink");return s(),o(l,null,[r,e("ul",null,[d,e("li",null,[i,q,b,m,k,h,a(c,{to:"/config/dns.html"},{default:t((()=>[g])),_:1}),v,I,P])]),e("div",f,[y,e("p",null,[j,F,U,a(c,{to:"/config/outbound.html#outboundobject"},{default:t((()=>[T])),_:1}),S,x,L,_,A])]),C,e("p",null,[D,a(c,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[N])),_:1}),O]),e("p",null,[w,a(c,{to:"/config/policy.html#policyobject"},{default:t((()=>[R])),_:1}),X,z,B]),E,G,H,J,K],64)};export default c; +import{r as n,o as s,c as o,a as e,b as a,w as t,F as l,d as p,e as u}from"./app.48111a85.js";const c={},r=p('

    Freedom

    Freedom 是一个出站协议,可以用来向任意网络发送(正常的) TCP 或 UDP 数据。

    OutboundConfigurationObject

    {\n  "domainStrategy": "AsIs",\n  "redirect": "127.0.0.1:3366",\n  "userLevel": 0,\n  "fragment": {\n    "packets": "tlshello",\n    "length": "100-200",\n    "interval": "10-20" // ms\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    domainStrategy: "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"

    在目标地址为域名时, 配置相应的值, Freedom 的行为模式如下:

    ',6),d=e("li",null,[e("code",null,'"AsIs"'),u(": Freedom 通过系统 DNS 服务器解析获取 IP, 向此域名发出连接.")],-1),i=e("code",null,'"UseIP"',-1),q=u("、"),b=e("code",null,'"UseIPv4"',-1),m=u(" 和 "),k=e("code",null,'"UseIPv6"',-1),h=u(": Xray 使用 "),g=u("内置 DNS 服务器"),v=u(" 解析获取 IP, 向此域名发出连接. 默认值为 "),I=e("code",null,'"AsIs"',-1),P=u("。"),f={class:"custom-container tip"},y=e("p",{class:"custom-container-title"},"TIP 1",-1),j=u("当使用 "),F=e("code",null,'"UseIP"',-1),U=u(" 模式,并且 "),T=u("出站连接配置"),S=u(" 中指定了 "),x=e("code",null,"sendThrough",-1),L=u(" 时,Freedom 会根据 "),_=e("code",null,"sendThrough",-1),A=u(" 的值自动判断所需的 IP 类型,IPv4 或 IPv6。"),C=p('

    TIP 2

    当使用 "UseIPv4""UseIPv6" 模式时,Freedom 会只使用对应的 IPv4 或 IPv6 地址。当 sendThrough 指定了不匹配的本地地址时,将导致连接失败。

    redirect: address_port

    Freedom 会强制将所有数据发送到指定地址(而不是 inbound 指定的地址)。

    其值为一个字符串,样例:"127.0.0.1:80"":1234"

    当地址不指定时,如 ":443",Freedom 不会修改原先的目标地址。 当端口为 0 时,如 "xray.com: 0",Freedom 不会修改原先的端口。

    userLevel: number

    ',6),D=u("用户等级,连接会使用这个用户等级对应的 "),N=u("本地策略"),O=u("。"),w=u("userLevel 的值, 对应 "),R=u("policy"),X=u(" 中 "),z=e("code",null,"level",-1),B=u(" 的值。 如不指定, 默认为 0。"),E=e("blockquote",null,[e("p",null,[e("code",null,"fragment"),u(": map")])],-1),G=e("p",null,"一些键值对配置项,用于控制发出的 TCP 分片,在某些情况下可以欺骗审查系统,比如绕过 SNI 黑名单。",-1),H=e("p",null,[e("code",null,'"packets"'),u(':支持两种分片方式 "1-3" 是 TCP 的流切片,应用于客户端第 1 至第 3 次写数据。"tlshello" 是 TLS 握手包切片。')],-1),J=e("p",null,[e("code",null,'"length"'),u(":分片包长 (byte)")],-1),K=e("p",null,[e("code",null,'"interval"'),u(":分片间隔(ms)")],-1);c.render=function(p,u){const c=n("RouterLink");return s(),o(l,null,[r,e("ul",null,[d,e("li",null,[i,q,b,m,k,h,a(c,{to:"/config/dns.html"},{default:t((()=>[g])),_:1}),v,I,P])]),e("div",f,[y,e("p",null,[j,F,U,a(c,{to:"/config/outbound.html#outboundobject"},{default:t((()=>[T])),_:1}),S,x,L,_,A])]),C,e("p",null,[D,a(c,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[N])),_:1}),O]),e("p",null,[w,a(c,{to:"/config/policy.html#policyobject"},{default:t((()=>[R])),_:1}),X,z,B]),E,G,H,J,K],64)};export default c; diff --git a/assets/ganttDiagram-3bc7fa50.538df6c0.js b/assets/ganttDiagram-3bc7fa50.a492c14b.js similarity index 99% rename from assets/ganttDiagram-3bc7fa50.538df6c0.js rename to assets/ganttDiagram-3bc7fa50.a492c14b.js index 4499ef2e4..640c6cb3f 100644 --- a/assets/ganttDiagram-3bc7fa50.538df6c0.js +++ b/assets/ganttDiagram-3bc7fa50.a492c14b.js @@ -1 +1 @@ -import{ac as t,ad as e,ae as n,af as r,ag as i,ah as a,ai as s,aj as o,ak as c,al as u,am as l,an as f,c as h,s as d,g,v as m,x as y,b as p,a as v,m as T,z as k,n as x,l as b,h as D,i as C,j as w,y as M}from"./mermaid.core.a66200b0.js";import{b as _,t as S,c as F,a as Y,l as U}from"./linear.98f7ec84.js";import{i as $}from"./init.0b4a962a.js";function A(t,e){let n;if(void 0===e)for(const r of t)null!=r&&(n=r)&&(n=r);else{let r=-1;for(let i of t)null!=(i=e(i,++r,t))&&(n=i)&&(n=i)}return n}function L(t,e){let n;if(void 0===e)for(const r of t)null!=r&&(n>r||void 0===n&&r>=r)&&(n=r);else{let r=-1;for(let i of t)null!=(i=e(i,++r,t))&&(n>i||void 0===n&&i>=i)&&(n=i)}return n}function E(t){return t}function H(t){return"translate("+t+",0)"}function I(t){return"translate(0,"+t+")"}function O(t){return e=>+t(e)}function z(t,e){return e=Math.max(0,t.bandwidth()-2*e)/2,t.round()&&(e=Math.round(e)),n=>+t(n)+e}function W(){return!this.__axis}function P(t,e){var n=[],r=null,i=null,a=6,s=6,o=3,c="undefined"!=typeof window&&window.devicePixelRatio>1?0:.5,u=1===t||4===t?-1:1,l=4===t||2===t?"x":"y",f=1===t||3===t?H:I;function h(h){var d=null==r?e.ticks?e.ticks.apply(e,n):e.domain():r,g=null==i?e.tickFormat?e.tickFormat.apply(e,n):E:i,m=Math.max(a,0)+o,y=e.range(),p=+y[0]+c,v=+y[y.length-1]+c,T=(e.bandwidth?z:O)(e.copy(),c),k=h.selection?h.selection():h,x=k.selectAll(".domain").data([null]),b=k.selectAll(".tick").data(d,e).order(),D=b.exit(),C=b.enter().append("g").attr("class","tick"),w=b.select("line"),M=b.select("text");x=x.merge(x.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),b=b.merge(C),w=w.merge(C.append("line").attr("stroke","currentColor").attr(l+"2",u*a)),M=M.merge(C.append("text").attr("fill","currentColor").attr(l,u*m).attr("dy",1===t?"0em":3===t?"0.71em":"0.32em")),h!==k&&(x=x.transition(h),b=b.transition(h),w=w.transition(h),M=M.transition(h),D=D.transition(h).attr("opacity",1e-6).attr("transform",(function(t){return isFinite(t=T(t))?f(t+c):this.getAttribute("transform")})),C.attr("opacity",1e-6).attr("transform",(function(t){var e=this.parentNode.__axis;return f((e&&isFinite(e=e(t))?e:T(t))+c)}))),D.remove(),x.attr("d",4===t||2===t?s?"M"+u*s+","+p+"H"+c+"V"+v+"H"+u*s:"M"+c+","+p+"V"+v:s?"M"+p+","+u*s+"V"+c+"H"+v+"V"+u*s:"M"+p+","+c+"H"+v),b.attr("opacity",1).attr("transform",(function(t){return f(T(t)+c)})),w.attr(l+"2",u*a),M.attr(l,u*m).text(g),k.filter(W).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",2===t?"start":4===t?"end":"middle"),k.each((function(){this.__axis=T}))}return h.scale=function(t){return arguments.length?(e=t,h):e},h.ticks=function(){return n=Array.from(arguments),h},h.tickArguments=function(t){return arguments.length?(n=null==t?[]:Array.from(t),h):n.slice()},h.tickValues=function(t){return arguments.length?(r=null==t?null:Array.from(t),h):r&&r.slice()},h.tickFormat=function(t){return arguments.length?(i=t,h):i},h.tickSize=function(t){return arguments.length?(a=s=+t,h):a},h.tickSizeInner=function(t){return arguments.length?(a=+t,h):a},h.tickSizeOuter=function(t){return arguments.length?(s=+t,h):s},h.tickPadding=function(t){return arguments.length?(o=+t,h):o},h.offset=function(t){return arguments.length?(c=+t,h):c},h}const N=Math.PI/180,B=180/Math.PI,V=4/29,Z=6/29,j=3*Z*Z;function G(t){if(t instanceof q)return new q(t.l,t.a,t.b,t.opacity);if(t instanceof et)return nt(t);t instanceof n||(t=i(t));var e,r,a=R(t.r),s=R(t.g),o=R(t.b),c=X((.2225045*a+.7168786*s+.0606169*o)/1);return a===s&&s===o?e=r=c:(e=X((.4360747*a+.3850649*s+.1430804*o)/.96422),r=X((.0139322*a+.0971045*s+.7141733*o)/.82521)),new q(116*c-16,500*(e-c),200*(c-r),t.opacity)}function q(t,e,n,r){this.l=+t,this.a=+e,this.b=+n,this.opacity=+r}function X(t){return t>.008856451679035631?Math.pow(t,1/3):t/j+V}function Q(t){return t>Z?t*t*t:j*(t-V)}function J(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function R(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function K(t){if(t instanceof et)return new et(t.h,t.c,t.l,t.opacity);if(t instanceof q||(t=G(t)),0===t.a&&0===t.b)return new et(NaN,00))return o;do{o.push(s=new Date(+n)),e(n,a),t(n)}while(s=e)for(;t(e),!n(e);)e.setTime(e-1)}),(function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!n(t););else for(;--r>=0;)for(;e(t,1),!n(t););}))},n&&(i.count=function(e,r){return at.setTime(+e),st.setTime(+r),t(at),t(st),Math.floor(n(at,st))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(e){return r(e)%t==0}:function(e){return i.count(0,e)%t==0}):i:null}),i}var ct=ot((function(){}),(function(t,e){t.setTime(+t+e)}),(function(t,e){return e-t}));ct.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?ot((function(e){e.setTime(Math.floor(e/t)*t)}),(function(e,n){e.setTime(+e+n*t)}),(function(e,n){return(n-e)/t})):ct:null};var ut=ot((function(t){t.setTime(t-t.getMilliseconds())}),(function(t,e){t.setTime(+t+1e3*e)}),(function(t,e){return(e-t)/1e3}),(function(t){return t.getUTCSeconds()})),lt=ot((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds())}),(function(t,e){t.setTime(+t+6e4*e)}),(function(t,e){return(e-t)/6e4}),(function(t){return t.getMinutes()})),ft=ot((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds()-6e4*t.getMinutes())}),(function(t,e){t.setTime(+t+36e5*e)}),(function(t,e){return(e-t)/36e5}),(function(t){return t.getHours()})),ht=ot((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/864e5),(t=>t.getDate()-1));function dt(t){return ot((function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+7*e)}),(function(t,e){return(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/6048e5}))}var gt=dt(0),mt=dt(1);dt(2),dt(3);var yt=dt(4);dt(5),dt(6);var pt=ot((function(t){t.setDate(1),t.setHours(0,0,0,0)}),(function(t,e){t.setMonth(t.getMonth()+e)}),(function(t,e){return e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())}),(function(t){return t.getMonth()})),vt=ot((function(t){t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,e){t.setFullYear(t.getFullYear()+e)}),(function(t,e){return e.getFullYear()-t.getFullYear()}),(function(t){return t.getFullYear()}));vt.every=function(t){return isFinite(t=Math.floor(t))&&t>0?ot((function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,n){e.setFullYear(e.getFullYear()+n*t)})):null};var Tt=ot((function(t){t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+e)}),(function(t,e){return(e-t)/864e5}),(function(t){return t.getUTCDate()-1}));function kt(t){return ot((function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+7*e)}),(function(t,e){return(e-t)/6048e5}))}var xt=kt(0),bt=kt(1);kt(2),kt(3);var Dt=kt(4);kt(5),kt(6);var Ct=ot((function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)}),(function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()}),(function(t){return t.getUTCFullYear()}));Ct.every=function(t){return isFinite(t=Math.floor(t))&&t>0?ot((function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,n){e.setUTCFullYear(e.getUTCFullYear()+n*t)})):null};const[wt,Mt]=function(t,e,n,r,i,a){const s=[[ut,1,1e3],[ut,5,5e3],[ut,15,15e3],[ut,30,3e4],[a,1,6e4],[a,5,3e5],[a,15,9e5],[a,30,18e5],[i,1,36e5],[i,3,108e5],[i,6,216e5],[i,12,432e5],[r,1,864e5],[r,2,1728e5],[n,1,6048e5],[e,1,2592e6],[e,3,7776e6],[t,1,31536e6]];function o(e,n,r){const i=Math.abs(n-e)/r,a=_((([,,t])=>t)).right(s,i);if(a===s.length)return t.every(S(e/31536e6,n/31536e6,r));if(0===a)return ct.every(Math.max(S(e,n,r),1));const[o,c]=s[i/s[a-1][2][t.toLowerCase(),e])))}function Wt(t,e,n){var r=At.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function Pt(t,e,n){var r=At.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function Nt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function Bt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function Vt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function Zt(t,e,n){var r=At.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function jt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function Gt(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 qt(t,e,n){var r=At.exec(e.slice(n,n+1));return r?(t.q=3*r[0]-3,n+r[0].length):-1}function Xt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Qt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Jt(t,e,n){var r=At.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function Rt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function Kt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function te(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function ee(t,e,n){var r=At.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function ne(t,e,n){var r=At.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function re(t,e,n){var r=Lt.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function ie(t,e,n){var r=At.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function ae(t,e,n){var r=At.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function se(t,e){return Ht(t.getDate(),e,2)}function oe(t,e){return Ht(t.getHours(),e,2)}function ce(t,e){return Ht(t.getHours()%12||12,e,2)}function ue(t,e){return Ht(1+ht.count(vt(t),t),e,3)}function le(t,e){return Ht(t.getMilliseconds(),e,3)}function fe(t,e){return le(t,e)+"000"}function he(t,e){return Ht(t.getMonth()+1,e,2)}function de(t,e){return Ht(t.getMinutes(),e,2)}function ge(t,e){return Ht(t.getSeconds(),e,2)}function me(t){var e=t.getDay();return 0===e?7:e}function ye(t,e){return Ht(gt.count(vt(t)-1,t),e,2)}function pe(t){var e=t.getDay();return e>=4||0===e?yt(t):yt.ceil(t)}function ve(t,e){return t=pe(t),Ht(yt.count(vt(t),t)+(4===vt(t).getDay()),e,2)}function Te(t){return t.getDay()}function ke(t,e){return Ht(mt.count(vt(t)-1,t),e,2)}function xe(t,e){return Ht(t.getFullYear()%100,e,2)}function be(t,e){return Ht((t=pe(t)).getFullYear()%100,e,2)}function De(t,e){return Ht(t.getFullYear()%1e4,e,4)}function Ce(t,e){var n=t.getDay();return Ht((t=n>=4||0===n?yt(t):yt.ceil(t)).getFullYear()%1e4,e,4)}function we(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Ht(e/60|0,"0",2)+Ht(e%60,"0",2)}function Me(t,e){return Ht(t.getUTCDate(),e,2)}function _e(t,e){return Ht(t.getUTCHours(),e,2)}function Se(t,e){return Ht(t.getUTCHours()%12||12,e,2)}function Fe(t,e){return Ht(1+Tt.count(Ct(t),t),e,3)}function Ye(t,e){return Ht(t.getUTCMilliseconds(),e,3)}function Ue(t,e){return Ye(t,e)+"000"}function $e(t,e){return Ht(t.getUTCMonth()+1,e,2)}function Ae(t,e){return Ht(t.getUTCMinutes(),e,2)}function Le(t,e){return Ht(t.getUTCSeconds(),e,2)}function Ee(t){var e=t.getUTCDay();return 0===e?7:e}function He(t,e){return Ht(xt.count(Ct(t)-1,t),e,2)}function Ie(t){var e=t.getUTCDay();return e>=4||0===e?Dt(t):Dt.ceil(t)}function Oe(t,e){return t=Ie(t),Ht(Dt.count(Ct(t),t)+(4===Ct(t).getUTCDay()),e,2)}function ze(t){return t.getUTCDay()}function We(t,e){return Ht(bt.count(Ct(t)-1,t),e,2)}function Pe(t,e){return Ht(t.getUTCFullYear()%100,e,2)}function Ne(t,e){return Ht((t=Ie(t)).getUTCFullYear()%100,e,2)}function Be(t,e){return Ht(t.getUTCFullYear()%1e4,e,4)}function Ve(t,e){var n=t.getUTCDay();return Ht((t=n>=4||0===n?Dt(t):Dt.ceil(t)).getUTCFullYear()%1e4,e,4)}function Ze(){return"+0000"}function je(){return"%"}function Ge(t){return+t}function qe(t){return Math.floor(+t/1e3)}function Xe(t){return new Date(t)}function Qe(t){return t instanceof Date?+t:+new Date(+t)}function Je(t,e,n,r,i,a,s,o,c,u){var l=F(),f=l.invert,h=l.domain,d=u(".%L"),g=u(":%S"),m=u("%I:%M"),y=u("%I %p"),p=u("%a %d"),v=u("%b %d"),T=u("%B"),k=u("%Y");function x(t){return(c(t)=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Ge,s:qe,S:ge,u:me,U:ye,V:ve,w:Te,W:ke,x:null,X:null,y:xe,Y:De,Z:we,"%":je},k={a:function(t){return s[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return o[t.getUTCMonth()]},c:null,d:Me,e:Me,f:Ue,g:Ne,G:Ve,H:_e,I:Se,j:Fe,L:Ye,m:$e,M:Ae,p:function(t){return i[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Ge,s:qe,S:Le,u:Ee,U:He,V:Oe,w:ze,W:We,x:null,X:null,y:Pe,Y:Be,Z:Ze,"%":je},x={a:function(t,e,n){var r=d.exec(e.slice(n));return r?(t.w=g.get(r[0].toLowerCase()),n+r[0].length):-1},A:function(t,e,n){var r=f.exec(e.slice(n));return r?(t.w=h.get(r[0].toLowerCase()),n+r[0].length):-1},b:function(t,e,n){var r=p.exec(e.slice(n));return r?(t.m=v.get(r[0].toLowerCase()),n+r[0].length):-1},B:function(t,e,n){var r=m.exec(e.slice(n));return r?(t.m=y.get(r[0].toLowerCase()),n+r[0].length):-1},c:function(t,n,r){return C(t,e,n,r)},d:Qt,e:Qt,f:ne,g:jt,G:Zt,H:Rt,I:Rt,j:Jt,L:ee,m:Xt,M:Kt,p:function(t,e,n){var r=u.exec(e.slice(n));return r?(t.p=l.get(r[0].toLowerCase()),n+r[0].length):-1},q:qt,Q:ie,s:ae,S:te,u:Pt,U:Nt,V:Bt,w:Wt,W:Vt,x:function(t,e,r){return C(t,n,e,r)},X:function(t,e,n){return C(t,r,e,n)},y:jt,Y:Zt,Z:Gt,"%":re};function b(t,e){return function(n){var r,i,a,s=[],o=-1,c=0,u=t.length;for(n instanceof Date||(n=new Date(+n));++o53)return null;"w"in a||(a.w=1),"Z"in a?(i=(r=St(Ft(a.y,0,1))).getUTCDay(),r=i>4||0===i?bt.ceil(r):bt(r),r=Tt.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(i=(r=_t(Ft(a.y,0,1))).getDay(),r=i>4||0===i?mt.ceil(r):mt(r),r=ht.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?St(Ft(a.y,0,1)).getUTCDay():_t(Ft(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,St(a)):_t(a)}}function C(t,e,n,r){for(var i,a,s=0,o=e.length,c=n.length;s=c)return-1;if(37===(i=e.charCodeAt(s++))){if(i=e.charAt(s++),!(a=x[i in $t?e.charAt(s++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return T.x=b(n,T),T.X=b(r,T),T.c=b(e,T),k.x=b(n,k),k.X=b(r,k),k.c=b(e,k),{format:function(t){var e=b(t+="",T);return e.toString=function(){return t},e},parse:function(t){var e=D(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=b(t+="",k);return e.toString=function(){return t},e},utcParse:function(t){var e=D(t+="",!0);return e.toString=function(){return t},e}}}({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"]}),Ut=Yt.format;var Re=new Date,Ke=new Date;function tn(t,e,n,r){function i(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return i.floor=function(e){return t(e=new Date(+e)),e},i.ceil=function(n){return t(n=new Date(n-1)),e(n,1),t(n),n},i.round=function(t){var e=i(t),n=i.ceil(t);return t-e0))return o;do{o.push(s=new Date(+n)),e(n,a),t(n)}while(s=e)for(;t(e),!n(e);)e.setTime(e-1)}),(function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!n(t););else for(;--r>=0;)for(;e(t,1),!n(t););}))},n&&(i.count=function(e,r){return Re.setTime(+e),Ke.setTime(+r),t(Re),t(Ke),Math.floor(n(Re,Ke))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(e){return r(e)%t==0}:function(e){return i.count(0,e)%t==0}):i:null}),i}var en=tn((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds())}),(function(t,e){t.setTime(+t+6e4*e)}),(function(t,e){return(e-t)/6e4}),(function(t){return t.getMinutes()})),nn=tn((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds()-6e4*t.getMinutes())}),(function(t,e){t.setTime(+t+36e5*e)}),(function(t,e){return(e-t)/36e5}),(function(t){return t.getHours()})),rn=tn((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/864e5),(t=>t.getDate()-1));function an(t){return tn((function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+7*e)}),(function(t,e){return(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/6048e5}))}var sn=an(0),on=an(1);an(2),an(3);var cn=an(4);an(5),an(6);var un=tn((function(t){t.setDate(1),t.setHours(0,0,0,0)}),(function(t,e){t.setMonth(t.getMonth()+e)}),(function(t,e){return e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())}),(function(t){return t.getMonth()})),ln=tn((function(t){t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,e){t.setFullYear(t.getFullYear()+e)}),(function(t,e){return e.getFullYear()-t.getFullYear()}),(function(t){return t.getFullYear()}));ln.every=function(t){return isFinite(t=Math.floor(t))&&t>0?tn((function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,n){e.setFullYear(e.getFullYear()+n*t)})):null};var fn=tn((function(t){t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+e)}),(function(t,e){return(e-t)/864e5}),(function(t){return t.getUTCDate()-1}));function hn(t){return tn((function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+7*e)}),(function(t,e){return(e-t)/6048e5}))}var dn=hn(0),gn=hn(1);hn(2),hn(3);var mn=hn(4);hn(5),hn(6);var yn=tn((function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)}),(function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()}),(function(t){return t.getUTCFullYear()}));function pn(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function vn(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function Tn(t,e,n){return{y:t,m:e,d:n,H:0,M:0,S:0,L:0}}yn.every=function(t){return isFinite(t=Math.floor(t))&&t>0?tn((function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,n){e.setUTCFullYear(e.getUTCFullYear()+n*t)})):null};var kn,xn,bn={"-":"",_:" ",0:"0"},Dn=/^\s*\d+/,Cn=/^%/,wn=/[\\^$*+?|[\]().{}]/g;function Mn(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",a=i.length;return r+(a[t.toLowerCase(),e])))}function Yn(t,e,n){var r=Dn.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function Un(t,e,n){var r=Dn.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function $n(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function An(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function Ln(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function En(t,e,n){var r=Dn.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function Hn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function In(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 On(t,e,n){var r=Dn.exec(e.slice(n,n+1));return r?(t.q=3*r[0]-3,n+r[0].length):-1}function zn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Wn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Pn(t,e,n){var r=Dn.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function Nn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function Bn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function Vn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Zn(t,e,n){var r=Dn.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function jn(t,e,n){var r=Dn.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Gn(t,e,n){var r=Cn.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function qn(t,e,n){var r=Dn.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function Xn(t,e,n){var r=Dn.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function Qn(t,e){return Mn(t.getDate(),e,2)}function Jn(t,e){return Mn(t.getHours(),e,2)}function Rn(t,e){return Mn(t.getHours()%12||12,e,2)}function Kn(t,e){return Mn(1+rn.count(ln(t),t),e,3)}function tr(t,e){return Mn(t.getMilliseconds(),e,3)}function er(t,e){return tr(t,e)+"000"}function nr(t,e){return Mn(t.getMonth()+1,e,2)}function rr(t,e){return Mn(t.getMinutes(),e,2)}function ir(t,e){return Mn(t.getSeconds(),e,2)}function ar(t){var e=t.getDay();return 0===e?7:e}function sr(t,e){return Mn(sn.count(ln(t)-1,t),e,2)}function or(t){var e=t.getDay();return e>=4||0===e?cn(t):cn.ceil(t)}function cr(t,e){return t=or(t),Mn(cn.count(ln(t),t)+(4===ln(t).getDay()),e,2)}function ur(t){return t.getDay()}function lr(t,e){return Mn(on.count(ln(t)-1,t),e,2)}function fr(t,e){return Mn(t.getFullYear()%100,e,2)}function hr(t,e){return Mn((t=or(t)).getFullYear()%100,e,2)}function dr(t,e){return Mn(t.getFullYear()%1e4,e,4)}function gr(t,e){var n=t.getDay();return Mn((t=n>=4||0===n?cn(t):cn.ceil(t)).getFullYear()%1e4,e,4)}function mr(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Mn(e/60|0,"0",2)+Mn(e%60,"0",2)}function yr(t,e){return Mn(t.getUTCDate(),e,2)}function pr(t,e){return Mn(t.getUTCHours(),e,2)}function vr(t,e){return Mn(t.getUTCHours()%12||12,e,2)}function Tr(t,e){return Mn(1+fn.count(yn(t),t),e,3)}function kr(t,e){return Mn(t.getUTCMilliseconds(),e,3)}function xr(t,e){return kr(t,e)+"000"}function br(t,e){return Mn(t.getUTCMonth()+1,e,2)}function Dr(t,e){return Mn(t.getUTCMinutes(),e,2)}function Cr(t,e){return Mn(t.getUTCSeconds(),e,2)}function wr(t){var e=t.getUTCDay();return 0===e?7:e}function Mr(t,e){return Mn(dn.count(yn(t)-1,t),e,2)}function _r(t){var e=t.getUTCDay();return e>=4||0===e?mn(t):mn.ceil(t)}function Sr(t,e){return t=_r(t),Mn(mn.count(yn(t),t)+(4===yn(t).getUTCDay()),e,2)}function Fr(t){return t.getUTCDay()}function Yr(t,e){return Mn(gn.count(yn(t)-1,t),e,2)}function Ur(t,e){return Mn(t.getUTCFullYear()%100,e,2)}function $r(t,e){return Mn((t=_r(t)).getUTCFullYear()%100,e,2)}function Ar(t,e){return Mn(t.getUTCFullYear()%1e4,e,4)}function Lr(t,e){var n=t.getUTCDay();return Mn((t=n>=4||0===n?mn(t):mn.ceil(t)).getUTCFullYear()%1e4,e,4)}function Er(){return"+0000"}function Hr(){return"%"}function Ir(t){return+t}function Or(t){return Math.floor(+t/1e3)}!function(t){kn=function(t){var e=t.dateTime,n=t.date,r=t.time,i=t.periods,a=t.days,s=t.shortDays,o=t.months,c=t.shortMonths,u=Sn(i),l=Fn(i),f=Sn(a),h=Fn(a),d=Sn(s),g=Fn(s),m=Sn(o),y=Fn(o),p=Sn(c),v=Fn(c),T={a:function(t){return s[t.getDay()]},A:function(t){return a[t.getDay()]},b:function(t){return c[t.getMonth()]},B:function(t){return o[t.getMonth()]},c:null,d:Qn,e:Qn,f:er,g:hr,G:gr,H:Jn,I:Rn,j:Kn,L:tr,m:nr,M:rr,p:function(t){return i[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Ir,s:Or,S:ir,u:ar,U:sr,V:cr,w:ur,W:lr,x:null,X:null,y:fr,Y:dr,Z:mr,"%":Hr},k={a:function(t){return s[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return o[t.getUTCMonth()]},c:null,d:yr,e:yr,f:xr,g:$r,G:Lr,H:pr,I:vr,j:Tr,L:kr,m:br,M:Dr,p:function(t){return i[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Ir,s:Or,S:Cr,u:wr,U:Mr,V:Sr,w:Fr,W:Yr,x:null,X:null,y:Ur,Y:Ar,Z:Er,"%":Hr},x={a:function(t,e,n){var r=d.exec(e.slice(n));return r?(t.w=g.get(r[0].toLowerCase()),n+r[0].length):-1},A:function(t,e,n){var r=f.exec(e.slice(n));return r?(t.w=h.get(r[0].toLowerCase()),n+r[0].length):-1},b:function(t,e,n){var r=p.exec(e.slice(n));return r?(t.m=v.get(r[0].toLowerCase()),n+r[0].length):-1},B:function(t,e,n){var r=m.exec(e.slice(n));return r?(t.m=y.get(r[0].toLowerCase()),n+r[0].length):-1},c:function(t,n,r){return C(t,e,n,r)},d:Wn,e:Wn,f:jn,g:Hn,G:En,H:Nn,I:Nn,j:Pn,L:Zn,m:zn,M:Bn,p:function(t,e,n){var r=u.exec(e.slice(n));return r?(t.p=l.get(r[0].toLowerCase()),n+r[0].length):-1},q:On,Q:qn,s:Xn,S:Vn,u:Un,U:$n,V:An,w:Yn,W:Ln,x:function(t,e,r){return C(t,n,e,r)},X:function(t,e,n){return C(t,r,e,n)},y:Hn,Y:En,Z:In,"%":Gn};function b(t,e){return function(n){var r,i,a,s=[],o=-1,c=0,u=t.length;for(n instanceof Date||(n=new Date(+n));++o53)return null;"w"in a||(a.w=1),"Z"in a?(i=(r=vn(Tn(a.y,0,1))).getUTCDay(),r=i>4||0===i?gn.ceil(r):gn(r),r=fn.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(i=(r=pn(Tn(a.y,0,1))).getDay(),r=i>4||0===i?on.ceil(r):on(r),r=rn.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?vn(Tn(a.y,0,1)).getUTCDay():pn(Tn(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,vn(a)):pn(a)}}function C(t,e,n,r){for(var i,a,s=0,o=e.length,c=n.length;s=c)return-1;if(37===(i=e.charCodeAt(s++))){if(i=e.charAt(s++),!(a=x[i in bn?e.charAt(s++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return T.x=b(n,T),T.X=b(r,T),T.c=b(e,T),k.x=b(n,k),k.X=b(r,k),k.c=b(e,k),{format:function(t){var e=b(t+="",T);return e.toString=function(){return t},e},parse:function(t){var e=D(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=b(t+="",k);return e.toString=function(){return t},e},utcParse:function(t){var e=D(t+="",!0);return e.toString=function(){return t},e}}}(t),xn=kn.format}({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"]});var zr={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"},Wr=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,Pr=/\d\d/,Nr=/\d\d?/,Br=/\d*[^-_:/,()\s\d]+/,Vr={},Zr=function(t){return(t=+t)+(t>68?1900:2e3)};var jr=function(t){return function(e){this[t]=+e}},Gr=[/[+-]\d\d:?(\d\d)?|Z/,function(t){(this.zone||(this.zone={})).offset=function(t){if(!t)return 0;if("Z"===t)return 0;var e=t.match(/([+-]|\d\d)/g),n=60*e[1]+(+e[2]||0);return 0===n?0:"+"===e[0]?-n:n}(t)}],qr=function(t){var e=Vr[t];return e&&(e.indexOf?e:e.s.concat(e.f))},Xr=function(t,e){var n,r=Vr.meridiem;if(r){for(var i=1;i<=24;i+=1)if(t.indexOf(r(i,0,e))>-1){n=i>12;break}}else n=t===(e?"pm":"PM");return n},Qr={A:[Br,function(t){this.afternoon=Xr(t,!1)}],a:[Br,function(t){this.afternoon=Xr(t,!0)}],S:[/\d/,function(t){this.milliseconds=100*+t}],SS:[Pr,function(t){this.milliseconds=10*+t}],SSS:[/\d{3}/,function(t){this.milliseconds=+t}],s:[Nr,jr("seconds")],ss:[Nr,jr("seconds")],m:[Nr,jr("minutes")],mm:[Nr,jr("minutes")],H:[Nr,jr("hours")],h:[Nr,jr("hours")],HH:[Nr,jr("hours")],hh:[Nr,jr("hours")],D:[Nr,jr("day")],DD:[Pr,jr("day")],Do:[Br,function(t){var e=Vr.ordinal,n=t.match(/\d+/);if(this.day=n[0],e)for(var r=1;r<=31;r+=1)e(r).replace(/\[|\]/g,"")===t&&(this.day=r)}],M:[Nr,jr("month")],MM:[Pr,jr("month")],MMM:[Br,function(t){var e=qr("months"),n=(qr("monthsShort")||e.map((function(t){return t.slice(0,3)}))).indexOf(t)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[Br,function(t){var e=qr("months").indexOf(t)+1;if(e<1)throw new Error;this.month=e%12||e}],Y:[/[+-]?\d+/,jr("year")],YY:[Pr,function(t){this.year=Zr(t)}],YYYY:[/\d{4}/,jr("year")],Z:Gr,ZZ:Gr};function Jr(t){var e,n;e=t,n=Vr&&Vr.formats;for(var r=(t=e.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,e,r){var i=r&&r.toUpperCase();return e||n[r]||zr[r]||n[i].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(t,e,n){return e||n.slice(1)}))}))).match(Wr),i=r.length,a=0;al&&M.push("'"+this.terminals_[D]+"'");S=d.showPosition?"Parse error on line "+(c+1)+":\n"+d.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[T]||T)+"'":"Parse error on line "+(c+1)+": Unexpected "+(T==f?"end of input":"'"+(this.terminals_[T]||T)+"'"),this.parseError(S,{text:d.match,token:this.terminals_[T]||T,line:d.yylineno,loc:y,expected:M})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+T);switch(x[0]){case 1:n.push(T),i.push(d.yytext),a.push(d.yylloc),n.push(x[1]),T=null,u=d.yyleng,o=d.yytext,c=d.yylineno,y=d.yylloc;break;case 2:if(C=this.productions_[x[1]][1],_.$=i[i.length-C],_._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},p&&(_._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(b=this.performAction.apply(_,[o,u,c,g.yy,x[1],i,a].concat(h))))return b;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[x[1]][0]),i.push(_.$),a.push(_._$),w=s[n[n.length-2]][n[n.length-1]],n.push(w);break;case 3:return!0}}return!0}},b={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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 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 i=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-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),40;case 1:return this.begin("type_directive"),41;case 2:return this.popState(),this.begin("arg_directive"),33;case 3:return this.popState(),this.popState(),43;case 4:return 42;case 5:return this.begin("acc_title"),21;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),23;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:case 13:case 14:break;case 15:return 11;case 16:case 17:case 18:break;case 19:this.begin("href");break;case 20:this.popState();break;case 21:return 38;case 22:this.begin("callbackname");break;case 23:this.popState();break;case 24:this.popState(),this.begin("callbackargs");break;case 25:return 36;case 26:this.popState();break;case 27:return 37;case 28:this.begin("click");break;case 29:this.popState();break;case 30:return 35;case 31:return 5;case 32:return 12;case 33:return 13;case 34:return 14;case 35:return 15;case 36:return 16;case 37:return 18;case 38:return 17;case 39:return 19;case 40:return"date";case 41:return 20;case 42:return"accDescription";case 43:return 26;case 44:return 28;case 45:return 29;case 46:return 33;case 47:return 7;case 48:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},callbackargs:{rules:[26,27],inclusive:!1},callbackname:{rules:[23,24,25],inclusive:!1},href:{rules:[20,21],inclusive:!1},click:{rules:[29,30],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,13,14,15,16,17,18,19,22,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],inclusive:!0}}};function D(){this.yy={}}return x.lexer=b,D.prototype=x,x.Parser=D,new D}();Rr.parser=Rr;const Kr=Rr;f.extend((function(t,e,n){var r=function(t){return t.add(4-t.isoWeekday(),o)},i=e.prototype;i.isoWeekYear=function(){return r(this).year()},i.isoWeek=function(t){if(!this.$utils().u(t))return this.add(7*(t-this.isoWeek()),o);var e,i,a,s,l=r(this),f=(e=this.isoWeekYear(),i=this.$u,a=(i?n.utc:n)().year(e).startOf(u),s=4-a.isoWeekday(),a.isoWeekday()>4&&(s+=7),a.add(s,o));return l.diff(f,c)+1},i.isoWeekday=function(t){return this.$utils().u(t)?this.day()||7:this.day(this.day()%7?t:t-7)};var a=i.startOf;i.startOf=function(t,e){var n=this.$utils(),r=!!n.u(e)||e;return"isoweek"===n.p(t)?r?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):a.bind(this)(t,e)}})),f.extend((function(t,e,n){n.p.customParseFormat=!0,t&&t.parseTwoDigitYear&&(Zr=t.parseTwoDigitYear);var r=e.prototype,i=r.parse;r.parse=function(t){var e=t.date,r=t.utc,a=t.args;this.$u=r;var s=a[1];if("string"==typeof s){var o=!0===a[2],c=!0===a[3],u=o||c,l=a[2];c&&(l=a[2]),Vr=this.$locale(),!o&&l&&(Vr=n.Ls[l]),this.$d=function(t,e,n){try{if(["x","X"].indexOf(e)>-1)return new Date(("X"===e?1e3:1)*t);var r=Jr(e)(t),i=r.year,a=r.month,s=r.day,o=r.hours,c=r.minutes,u=r.seconds,l=r.milliseconds,f=r.zone,h=new Date,d=s||(i||a?1:h.getDate()),g=i||h.getFullYear(),m=0;i&&!a||(m=a>0?a-1:h.getMonth());var y=o||0,p=c||0,v=u||0,T=l||0;return f?new Date(Date.UTC(g,m,d,y,p,v,T+60*f.offset*1e3)):n?new Date(Date.UTC(g,m,d,y,p,v,T)):new Date(g,m,d,y,p,v,T)}catch(k){return new Date("")}}(e,s,r),this.init(),l&&!0!==l&&(this.$L=this.locale(l).$L),u&&e!=this.format(s)&&(this.$d=new Date("")),Vr={}}else if(s instanceof Array)for(var f=s.length,h=1;h<=f;h+=1){a[1]=s[h-1];var d=n.apply(this,a);if(d.isValid()){this.$d=d.$d,this.$L=d.$L,this.init();break}h===f&&(this.$d=new Date(""))}else i.call(this,t)}})),f.extend((function(t,e){var n=e.prototype,r=n.format;n.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return r.bind(this)(t);var i=this.$utils(),a=(t||l).replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(t){switch(t){case"Q":return Math.ceil((e.$M+1)/3);case"Do":return n.ordinal(e.$D);case"gggg":return e.weekYear();case"GGGG":return e.isoWeekYear();case"wo":return n.ordinal(e.week(),"W");case"w":case"ww":return i.s(e.week(),"w"===t?1:2,"0");case"W":case"WW":return i.s(e.isoWeek(),"W"===t?1:2,"0");case"k":case"kk":return i.s(String(0===e.$H?24:e.$H),"k"===t?1:2,"0");case"X":return Math.floor(e.$d.getTime()/1e3);case"x":return e.$d.getTime();case"z":return"["+e.offsetName()+"]";case"zzz":return"["+e.offsetName("long")+"]";default:return t}}));return r.bind(this)(a)}}));let ti,ei="",ni="",ri="",ii=[],ai=[],si={},oi=[],ci=[],ui="",li="";const fi=["active","done","crit","milestone"];let hi=[],di=!1,gi=!1,mi=0;const yi=function(t,e,n,r){return!r.includes(t.format(e.trim()))&&(!!(t.isoWeekday()>=6&&n.includes("weekends"))||(!!n.includes(t.format("dddd").toLowerCase())||n.includes(t.format(e.trim()))))},pi=function(t,e,n,r){if(!n.length||t.manualEndTime)return;let i,a;i=t.startTime instanceof Date?f(t.startTime):f(t.startTime,e,!0),i=i.add(1,"d"),a=t.endTime instanceof Date?f(t.endTime):f(t.endTime,e,!0);const[s,o]=vi(i,a,e,n,r);t.endTime=s.toDate(),t.renderEndTime=o},vi=function(t,e,n,r,i){let a=!1,s=null;for(;t<=e;)a||(s=e.toDate()),a=yi(t,n,r,i),a&&(e=e.add(1,"d")),t=t.add(1,"d");return[e,s]},Ti=function(t,e,n){n=n.trim();const r=/^after\s+([\d\w- ]+)/.exec(n.trim());if(null!==r){let t=null;if(r[1].split(" ").forEach((function(e){let n=Si(e);void 0!==n&&(t?n.endTime>t.endTime&&(t=n):t=n)})),t)return t.endTime;{const t=new Date;return t.setHours(0,0,0,0),t}}let i=f(n,e.trim(),!0);if(i.isValid())return i.toDate();{b.debug("Invalid date:"+n),b.debug("With date format:"+e.trim());const t=new Date(n);if(void 0===t||isNaN(t.getTime())||t.getFullYear()<-1e4||t.getFullYear()>1e4)throw new Error("Invalid date:"+n);return t}},ki=function(t){const e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return null!==e?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]},xi=function(t,e,n,r=!1){n=n.trim();let i=f(n,e.trim(),!0);if(i.isValid())return r&&(i=i.add(1,"d")),i.toDate();let a=f(t);const[s,o]=ki(n);if(!Number.isNaN(s)){const t=a.add(s,o);t.isValid()&&(a=t)}return a.toDate()};let bi=0;const Di=function(t){return void 0===t?(bi+=1,"task"+bi):t};let Ci,wi,Mi=[];const _i={},Si=function(t){const e=_i[t];return Mi[e]},Fi=function(){const t=function(t){const e=Mi[t];let n="";switch(Mi[t].raw.startTime.type){case"prevTaskEnd":{const t=Si(e.prevTaskId);e.startTime=t.endTime;break}case"getStartDate":n=Ti(0,ei,Mi[t].raw.startTime.startData),n&&(Mi[t].startTime=n)}return Mi[t].startTime&&(Mi[t].endTime=xi(Mi[t].startTime,ei,Mi[t].raw.endTime.data,di),Mi[t].endTime&&(Mi[t].processed=!0,Mi[t].manualEndTime=f(Mi[t].raw.endTime.data,"YYYY-MM-DD",!0).isValid(),pi(Mi[t],ei,ai,ii))),Mi[t].processed};let e=!0;for(const[n,r]of Mi.entries())t(n),e=e&&r.processed;return e},Yi=function(t,e){t.split(",").forEach((function(t){let n=Si(t);void 0!==n&&n.classes.push(e)}))},Ui=function(t,e){hi.push((function(){const n=document.querySelector(`[id="${t}"]`);null!==n&&n.addEventListener("click",(function(){e()}))}),(function(){const n=document.querySelector(`[id="${t}-text"]`);null!==n&&n.addEventListener("click",(function(){e()}))}))};function $i(t,e,n){let r=!0;for(;r;)r=!1,n.forEach((function(n){const i=new RegExp("^\\s*"+n+"\\s*$");t[0].match(i)&&(e[n]=!0,t.shift(1),r=!0)}))}const Ai=(t,e)=>{let n=[...t].map((()=>-1/0)),r=[...t].sort(((t,e)=>t.startTime-e.startTime||t.order-e.order)),i=0;for(const a of r)for(let t=0;t=n[t]){n[t]=a.endTime,a.order=t+e,t>i&&(i=t);break}return i};let Li;const Ei={parser:Kr,db:{parseDirective:function(t,e,n){T.parseDirective(this,t,e,n)},getConfig:()=>h().gantt,clear:function(){oi=[],ci=[],ui="",hi=[],bi=0,Ci=void 0,wi=void 0,Mi=[],ei="",ni="",li="",ti=void 0,ri="",ii=[],ai=[],di=!1,gi=!1,mi=0,si={},k()},setDateFormat:function(t){ei=t},getDateFormat:function(){return ei},enableInclusiveEndDates:function(){di=!0},endDatesAreInclusive:function(){return di},enableTopAxis:function(){gi=!0},topAxisEnabled:function(){return gi},setAxisFormat:function(t){ni=t},getAxisFormat:function(){return ni},setTickInterval:function(t){ti=t},getTickInterval:function(){return ti},setTodayMarker:function(t){ri=t},getTodayMarker:function(){return ri},setAccTitle:d,getAccTitle:g,setDiagramTitle:m,getDiagramTitle:y,setDisplayMode:function(t){li=t},getDisplayMode:function(){return li},setAccDescription:p,getAccDescription:v,addSection:function(t){ui=t,oi.push(t)},getSections:function(){return oi},getTasks:function(){let t=Fi();let e=0;for(;!t&&e<10;)t=Fi(),e++;return ci=Mi,ci},addTask:function(t,e){const n={section:ui,type:ui,processed:!1,manualEndTime:!1,renderEndTime:null,raw:{data:e},task:t,classes:[]},r=function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const r=n.split(","),i={};$i(r,i,fi);for(let a=0;a{M.runFunc(e,...r)}))}(t,e,n)})),Yi(t,"clickable")},setLink:function(t,e){let n=e;"loose"!==h().securityLevel&&(n=x(e)),t.split(",").forEach((function(t){void 0!==Si(t)&&(Ui(t,(()=>{window.open(n,"_self")})),si[t]=n)})),Yi(t,"clickable")},getLinks:function(){return si},bindFunctions:function(t){hi.forEach((function(e){e(t)}))},parseDuration:ki,isInvalidDate:yi},renderer:{setConf:function(){b.debug("Something is calling, setConf, remove the call")},draw:function(t,e,n,r){const i=h().gantt,a=h().securityLevel;let s;"sandbox"===a&&(s=D("#i"+e));const o=D("sandbox"===a?s.nodes()[0].contentDocument.body:"body"),c="sandbox"===a?s.nodes()[0].contentDocument:document,u=c.getElementById(e);Li=u.parentElement.offsetWidth,void 0===Li&&(Li=1200),void 0!==i.useWidth&&(Li=i.useWidth);const l=r.db.getTasks();let d=[];for(const f of l)d.push(f.type);d=function(t){const e={},n=[];for(let r=0,i=t.length;re.type===t)).length}u.setAttribute("viewBox","0 0 "+Li+" "+m);const y=o.select(`[id="${e}"]`),p=function(){return $.apply(Je(wt,Mt,vt,pt,gt,ht,ft,lt,ut,Ut).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}().domain([L(l,(function(t){return t.startTime})),A(l,(function(t){return t.endTime}))]).rangeRound([0,Li-i.leftPadding-i.rightPadding]);l.sort((function(t,e){const n=t.startTime,r=e.startTime;let i=0;return n>r?i=1:nt?Math.min(t,e):e),0),h=o.reduce(((t,{endTime:e})=>t?Math.max(t,e):e),0),d=r.db.getDateFormat();if(!l||!h)return;const g=[];let m=null,v=f(l);for(;v.valueOf()<=h;)r.db.isInvalidDate(v,d,c,u)?m?m.end=v:m={start:v,end:v}:m&&(g.push(m),m=null),v=v.add(1,"d");y.append("g").selectAll("rect").data(g).enter().append("rect").attr("id",(function(t){return"exclude-"+t.start.format("YYYY-MM-DD")})).attr("x",(function(t){return p(t.start)+n})).attr("y",i.gridLineStartPadding).attr("width",(function(t){const e=t.end.add(1,"day");return p(e)-p(t.start)})).attr("height",s-e-i.gridLineStartPadding).attr("transform-origin",(function(e,r){return(p(e.start)+n+.5*(p(e.end)-p(e.start))).toString()+"px "+(r*t+.5*s).toString()+"px"})).attr("class","exclude-range")})(o,u,l,0,a,t,r.db.getExcludes(),r.db.getIncludes()),function(t,e,n,a){let s=(o=p,P(3,o)).tickSize(-a+e+i.gridLineStartPadding).tickFormat(xn(r.db.getAxisFormat()||i.axisFormat||"%Y-%m-%d"));var o;const c=/^([1-9]\d*)(minute|hour|day|week|month)$/.exec(r.db.getTickInterval()||i.tickInterval);if(null!==c){const t=c[1];switch(c[2]){case"minute":s.ticks(en.every(t));break;case"hour":s.ticks(nn.every(t));break;case"day":s.ticks(rn.every(t));break;case"week":s.ticks(sn.every(t));break;case"month":s.ticks(un.every(t))}}if(y.append("g").attr("class","grid").attr("transform","translate("+t+", "+(a-50)+")").call(s).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),r.db.topAxisEnabled()||i.topAxis){let n=function(t){return P(1,t)}(p).tickSize(-a+e+i.gridLineStartPadding).tickFormat(xn(r.db.getAxisFormat()||i.axisFormat||"%Y-%m-%d"));if(null!==c){const t=c[1];switch(c[2]){case"minute":n.ticks(en.every(t));break;case"hour":n.ticks(nn.every(t));break;case"day":n.ticks(rn.every(t));break;case"week":n.ticks(sn.every(t));break;case"month":n.ticks(un.every(t))}}y.append("g").attr("class","grid").attr("transform","translate("+t+", "+e+")").call(n).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}(l,u,0,a),function(t,n,a,s,o,c,u){const l=[...new Set(t.map((t=>t.order)))].map((e=>t.find((t=>t.order===e))));y.append("g").selectAll("rect").data(l).enter().append("rect").attr("x",0).attr("y",(function(t,e){return t.order*n+a-2})).attr("width",(function(){return u-i.rightPadding/2})).attr("height",n).attr("class",(function(t){for(const[e,n]of d.entries())if(t.type===n)return"section section"+e%i.numberSectionStyles;return"section section0"}));const f=y.append("g").selectAll("rect").data(t).enter(),g=r.db.getLinks();f.append("rect").attr("id",(function(t){return t.id})).attr("rx",3).attr("ry",3).attr("x",(function(t){return t.milestone?p(t.startTime)+s+.5*(p(t.endTime)-p(t.startTime))-.5*o:p(t.startTime)+s})).attr("y",(function(t,e){return t.order*n+a})).attr("width",(function(t){return t.milestone?o:p(t.renderEndTime||t.endTime)-p(t.startTime)})).attr("height",o).attr("transform-origin",(function(t,e){return e=t.order,(p(t.startTime)+s+.5*(p(t.endTime)-p(t.startTime))).toString()+"px "+(e*n+a+.5*o).toString()+"px"})).attr("class",(function(t){const e="task";let n="";t.classes.length>0&&(n=t.classes.join(" "));let r=0;for(const[s,o]of d.entries())t.type===o&&(r=s%i.numberSectionStyles);let a="";return t.active?t.crit?a+=" activeCrit":a=" active":t.done?a=t.crit?" doneCrit":" done":t.crit&&(a+=" crit"),0===a.length&&(a=" task"),t.milestone&&(a=" milestone "+a),a+=r,a+=" "+n,e+a})),f.append("text").attr("id",(function(t){return t.id+"-text"})).text((function(t){return t.task})).attr("font-size",i.fontSize).attr("x",(function(t){let e=p(t.startTime),n=p(t.renderEndTime||t.endTime);t.milestone&&(e+=.5*(p(t.endTime)-p(t.startTime))-.5*o),t.milestone&&(n=e+o);const r=this.getBBox().width;return r>n-e?n+r+1.5*i.leftPadding>u?e+s-5:n+s+5:(n-e)/2+e+s})).attr("y",(function(t,e){return t.order*n+i.barHeight/2+(i.fontSize/2-2)+a})).attr("text-height",o).attr("class",(function(t){const e=p(t.startTime);let n=p(t.endTime);t.milestone&&(n=e+o);const r=this.getBBox().width;let a="";t.classes.length>0&&(a=t.classes.join(" "));let s=0;for(const[o,u]of d.entries())t.type===u&&(s=o%i.numberSectionStyles);let c="";return t.active&&(c=t.crit?"activeCritText"+s:"activeText"+s),t.done?c=t.crit?c+" doneCritText"+s:c+" doneText"+s:t.crit&&(c=c+" critText"+s),t.milestone&&(c+=" milestoneText"),r>n-e?n+r+1.5*i.leftPadding>u?a+" taskTextOutsideLeft taskTextOutside"+s+" "+c:a+" taskTextOutsideRight taskTextOutside"+s+" "+c+" width-"+r:a+" taskText taskText"+s+" "+c+" width-"+r}));if("sandbox"===h().securityLevel){let t;t=D("#i"+e);const n=t.nodes()[0].contentDocument;f.filter((function(t){return void 0!==g[t.id]})).each((function(t){var e=n.querySelector("#"+t.id),r=n.querySelector("#"+t.id+"-text");const i=e.parentNode;var a=n.createElement("a");a.setAttribute("xlink:href",g[t.id]),a.setAttribute("target","_top"),i.appendChild(a),a.appendChild(e),a.appendChild(r)}))}}(t,o,u,l,s,0,n),function(t,e){let n=0;const r=Object.keys(g).map((t=>[t,g[t]]));y.append("g").selectAll("text").data(r).enter().append((function(t){const e=t[0].split(w.lineBreakRegex),n=-(e.length-1)/2,r=c.createElementNS("http://www.w3.org/2000/svg","text");r.setAttribute("dy",n+"em");for(const[i,a]of e.entries()){const t=c.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttribute("alignment-baseline","central"),t.setAttribute("x","10"),i>0&&t.setAttribute("dy","1em"),t.textContent=a,r.appendChild(t)}return r})).attr("x",10).attr("y",(function(i,a){if(!(a>0))return i[1]*t/2+e;for(let s=0;s`\n .mermaid-main-font {\n font-family: "trebuchet ms", verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n .exclude-range {\n fill: ${t.excludeBkgColor};\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: ${t.sectionBkgColor};\n }\n\n .section2 {\n fill: ${t.sectionBkgColor2};\n }\n\n .section1,\n .section3 {\n fill: ${t.altSectionBkgColor};\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle1 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle2 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle3 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle {\n text-anchor: start;\n // font-size: ${t.ganttFontSize};\n // text-height: 14px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ${t.gridColor};\n opacity: 0.8;\n shape-rendering: crispEdges;\n text {\n font-family: ${t.fontFamily};\n fill: ${t.textColor};\n }\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ${t.todayLineColor};\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n\n // .taskText:not([font-size]) {\n // font-size: ${t.ganttFontSize};\n // }\n\n .taskTextOutsideRight {\n fill: ${t.taskTextDarkColor};\n text-anchor: start;\n // font-size: ${t.ganttFontSize};\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n\n }\n\n .taskTextOutsideLeft {\n fill: ${t.taskTextDarkColor};\n text-anchor: end;\n // font-size: ${t.ganttFontSize};\n }\n\n /* Special case clickable */\n .task.clickable {\n cursor: pointer;\n }\n .taskText.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ${t.taskTextColor};\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ${t.taskBkgColor};\n stroke: ${t.taskBorderColor};\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ${t.taskTextOutsideColor};\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ${t.taskTextOutsideColor};\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ${t.activeTaskBkgColor};\n stroke: ${t.activeTaskBorderColor};\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ${t.doneTaskBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.critBkgColor};\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.activeTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor} ;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n`};export{Ei as diagram}; +import{ac as t,ad as e,ae as n,af as r,ag as i,ah as a,ai as s,aj as o,ak as c,al as u,am as l,an as f,c as h,s as d,g,v as m,x as y,b as p,a as v,m as T,z as k,n as x,l as b,h as D,i as C,j as w,y as M}from"./mermaid.core.3a590193.js";import{b as _,t as S,c as F,a as Y,l as U}from"./linear.98f7ec84.js";import{i as $}from"./init.0b4a962a.js";function A(t,e){let n;if(void 0===e)for(const r of t)null!=r&&(n=r)&&(n=r);else{let r=-1;for(let i of t)null!=(i=e(i,++r,t))&&(n=i)&&(n=i)}return n}function L(t,e){let n;if(void 0===e)for(const r of t)null!=r&&(n>r||void 0===n&&r>=r)&&(n=r);else{let r=-1;for(let i of t)null!=(i=e(i,++r,t))&&(n>i||void 0===n&&i>=i)&&(n=i)}return n}function E(t){return t}function H(t){return"translate("+t+",0)"}function I(t){return"translate(0,"+t+")"}function O(t){return e=>+t(e)}function z(t,e){return e=Math.max(0,t.bandwidth()-2*e)/2,t.round()&&(e=Math.round(e)),n=>+t(n)+e}function W(){return!this.__axis}function P(t,e){var n=[],r=null,i=null,a=6,s=6,o=3,c="undefined"!=typeof window&&window.devicePixelRatio>1?0:.5,u=1===t||4===t?-1:1,l=4===t||2===t?"x":"y",f=1===t||3===t?H:I;function h(h){var d=null==r?e.ticks?e.ticks.apply(e,n):e.domain():r,g=null==i?e.tickFormat?e.tickFormat.apply(e,n):E:i,m=Math.max(a,0)+o,y=e.range(),p=+y[0]+c,v=+y[y.length-1]+c,T=(e.bandwidth?z:O)(e.copy(),c),k=h.selection?h.selection():h,x=k.selectAll(".domain").data([null]),b=k.selectAll(".tick").data(d,e).order(),D=b.exit(),C=b.enter().append("g").attr("class","tick"),w=b.select("line"),M=b.select("text");x=x.merge(x.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),b=b.merge(C),w=w.merge(C.append("line").attr("stroke","currentColor").attr(l+"2",u*a)),M=M.merge(C.append("text").attr("fill","currentColor").attr(l,u*m).attr("dy",1===t?"0em":3===t?"0.71em":"0.32em")),h!==k&&(x=x.transition(h),b=b.transition(h),w=w.transition(h),M=M.transition(h),D=D.transition(h).attr("opacity",1e-6).attr("transform",(function(t){return isFinite(t=T(t))?f(t+c):this.getAttribute("transform")})),C.attr("opacity",1e-6).attr("transform",(function(t){var e=this.parentNode.__axis;return f((e&&isFinite(e=e(t))?e:T(t))+c)}))),D.remove(),x.attr("d",4===t||2===t?s?"M"+u*s+","+p+"H"+c+"V"+v+"H"+u*s:"M"+c+","+p+"V"+v:s?"M"+p+","+u*s+"V"+c+"H"+v+"V"+u*s:"M"+p+","+c+"H"+v),b.attr("opacity",1).attr("transform",(function(t){return f(T(t)+c)})),w.attr(l+"2",u*a),M.attr(l,u*m).text(g),k.filter(W).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",2===t?"start":4===t?"end":"middle"),k.each((function(){this.__axis=T}))}return h.scale=function(t){return arguments.length?(e=t,h):e},h.ticks=function(){return n=Array.from(arguments),h},h.tickArguments=function(t){return arguments.length?(n=null==t?[]:Array.from(t),h):n.slice()},h.tickValues=function(t){return arguments.length?(r=null==t?null:Array.from(t),h):r&&r.slice()},h.tickFormat=function(t){return arguments.length?(i=t,h):i},h.tickSize=function(t){return arguments.length?(a=s=+t,h):a},h.tickSizeInner=function(t){return arguments.length?(a=+t,h):a},h.tickSizeOuter=function(t){return arguments.length?(s=+t,h):s},h.tickPadding=function(t){return arguments.length?(o=+t,h):o},h.offset=function(t){return arguments.length?(c=+t,h):c},h}const N=Math.PI/180,B=180/Math.PI,V=4/29,Z=6/29,j=3*Z*Z;function G(t){if(t instanceof q)return new q(t.l,t.a,t.b,t.opacity);if(t instanceof et)return nt(t);t instanceof n||(t=i(t));var e,r,a=R(t.r),s=R(t.g),o=R(t.b),c=X((.2225045*a+.7168786*s+.0606169*o)/1);return a===s&&s===o?e=r=c:(e=X((.4360747*a+.3850649*s+.1430804*o)/.96422),r=X((.0139322*a+.0971045*s+.7141733*o)/.82521)),new q(116*c-16,500*(e-c),200*(c-r),t.opacity)}function q(t,e,n,r){this.l=+t,this.a=+e,this.b=+n,this.opacity=+r}function X(t){return t>.008856451679035631?Math.pow(t,1/3):t/j+V}function Q(t){return t>Z?t*t*t:j*(t-V)}function J(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function R(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function K(t){if(t instanceof et)return new et(t.h,t.c,t.l,t.opacity);if(t instanceof q||(t=G(t)),0===t.a&&0===t.b)return new et(NaN,00))return o;do{o.push(s=new Date(+n)),e(n,a),t(n)}while(s=e)for(;t(e),!n(e);)e.setTime(e-1)}),(function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!n(t););else for(;--r>=0;)for(;e(t,1),!n(t););}))},n&&(i.count=function(e,r){return at.setTime(+e),st.setTime(+r),t(at),t(st),Math.floor(n(at,st))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(e){return r(e)%t==0}:function(e){return i.count(0,e)%t==0}):i:null}),i}var ct=ot((function(){}),(function(t,e){t.setTime(+t+e)}),(function(t,e){return e-t}));ct.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?ot((function(e){e.setTime(Math.floor(e/t)*t)}),(function(e,n){e.setTime(+e+n*t)}),(function(e,n){return(n-e)/t})):ct:null};var ut=ot((function(t){t.setTime(t-t.getMilliseconds())}),(function(t,e){t.setTime(+t+1e3*e)}),(function(t,e){return(e-t)/1e3}),(function(t){return t.getUTCSeconds()})),lt=ot((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds())}),(function(t,e){t.setTime(+t+6e4*e)}),(function(t,e){return(e-t)/6e4}),(function(t){return t.getMinutes()})),ft=ot((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds()-6e4*t.getMinutes())}),(function(t,e){t.setTime(+t+36e5*e)}),(function(t,e){return(e-t)/36e5}),(function(t){return t.getHours()})),ht=ot((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/864e5),(t=>t.getDate()-1));function dt(t){return ot((function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+7*e)}),(function(t,e){return(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/6048e5}))}var gt=dt(0),mt=dt(1);dt(2),dt(3);var yt=dt(4);dt(5),dt(6);var pt=ot((function(t){t.setDate(1),t.setHours(0,0,0,0)}),(function(t,e){t.setMonth(t.getMonth()+e)}),(function(t,e){return e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())}),(function(t){return t.getMonth()})),vt=ot((function(t){t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,e){t.setFullYear(t.getFullYear()+e)}),(function(t,e){return e.getFullYear()-t.getFullYear()}),(function(t){return t.getFullYear()}));vt.every=function(t){return isFinite(t=Math.floor(t))&&t>0?ot((function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,n){e.setFullYear(e.getFullYear()+n*t)})):null};var Tt=ot((function(t){t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+e)}),(function(t,e){return(e-t)/864e5}),(function(t){return t.getUTCDate()-1}));function kt(t){return ot((function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+7*e)}),(function(t,e){return(e-t)/6048e5}))}var xt=kt(0),bt=kt(1);kt(2),kt(3);var Dt=kt(4);kt(5),kt(6);var Ct=ot((function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)}),(function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()}),(function(t){return t.getUTCFullYear()}));Ct.every=function(t){return isFinite(t=Math.floor(t))&&t>0?ot((function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,n){e.setUTCFullYear(e.getUTCFullYear()+n*t)})):null};const[wt,Mt]=function(t,e,n,r,i,a){const s=[[ut,1,1e3],[ut,5,5e3],[ut,15,15e3],[ut,30,3e4],[a,1,6e4],[a,5,3e5],[a,15,9e5],[a,30,18e5],[i,1,36e5],[i,3,108e5],[i,6,216e5],[i,12,432e5],[r,1,864e5],[r,2,1728e5],[n,1,6048e5],[e,1,2592e6],[e,3,7776e6],[t,1,31536e6]];function o(e,n,r){const i=Math.abs(n-e)/r,a=_((([,,t])=>t)).right(s,i);if(a===s.length)return t.every(S(e/31536e6,n/31536e6,r));if(0===a)return ct.every(Math.max(S(e,n,r),1));const[o,c]=s[i/s[a-1][2][t.toLowerCase(),e])))}function Wt(t,e,n){var r=At.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function Pt(t,e,n){var r=At.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function Nt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function Bt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function Vt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function Zt(t,e,n){var r=At.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function jt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function Gt(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 qt(t,e,n){var r=At.exec(e.slice(n,n+1));return r?(t.q=3*r[0]-3,n+r[0].length):-1}function Xt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Qt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Jt(t,e,n){var r=At.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function Rt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function Kt(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function te(t,e,n){var r=At.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function ee(t,e,n){var r=At.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function ne(t,e,n){var r=At.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function re(t,e,n){var r=Lt.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function ie(t,e,n){var r=At.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function ae(t,e,n){var r=At.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function se(t,e){return Ht(t.getDate(),e,2)}function oe(t,e){return Ht(t.getHours(),e,2)}function ce(t,e){return Ht(t.getHours()%12||12,e,2)}function ue(t,e){return Ht(1+ht.count(vt(t),t),e,3)}function le(t,e){return Ht(t.getMilliseconds(),e,3)}function fe(t,e){return le(t,e)+"000"}function he(t,e){return Ht(t.getMonth()+1,e,2)}function de(t,e){return Ht(t.getMinutes(),e,2)}function ge(t,e){return Ht(t.getSeconds(),e,2)}function me(t){var e=t.getDay();return 0===e?7:e}function ye(t,e){return Ht(gt.count(vt(t)-1,t),e,2)}function pe(t){var e=t.getDay();return e>=4||0===e?yt(t):yt.ceil(t)}function ve(t,e){return t=pe(t),Ht(yt.count(vt(t),t)+(4===vt(t).getDay()),e,2)}function Te(t){return t.getDay()}function ke(t,e){return Ht(mt.count(vt(t)-1,t),e,2)}function xe(t,e){return Ht(t.getFullYear()%100,e,2)}function be(t,e){return Ht((t=pe(t)).getFullYear()%100,e,2)}function De(t,e){return Ht(t.getFullYear()%1e4,e,4)}function Ce(t,e){var n=t.getDay();return Ht((t=n>=4||0===n?yt(t):yt.ceil(t)).getFullYear()%1e4,e,4)}function we(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Ht(e/60|0,"0",2)+Ht(e%60,"0",2)}function Me(t,e){return Ht(t.getUTCDate(),e,2)}function _e(t,e){return Ht(t.getUTCHours(),e,2)}function Se(t,e){return Ht(t.getUTCHours()%12||12,e,2)}function Fe(t,e){return Ht(1+Tt.count(Ct(t),t),e,3)}function Ye(t,e){return Ht(t.getUTCMilliseconds(),e,3)}function Ue(t,e){return Ye(t,e)+"000"}function $e(t,e){return Ht(t.getUTCMonth()+1,e,2)}function Ae(t,e){return Ht(t.getUTCMinutes(),e,2)}function Le(t,e){return Ht(t.getUTCSeconds(),e,2)}function Ee(t){var e=t.getUTCDay();return 0===e?7:e}function He(t,e){return Ht(xt.count(Ct(t)-1,t),e,2)}function Ie(t){var e=t.getUTCDay();return e>=4||0===e?Dt(t):Dt.ceil(t)}function Oe(t,e){return t=Ie(t),Ht(Dt.count(Ct(t),t)+(4===Ct(t).getUTCDay()),e,2)}function ze(t){return t.getUTCDay()}function We(t,e){return Ht(bt.count(Ct(t)-1,t),e,2)}function Pe(t,e){return Ht(t.getUTCFullYear()%100,e,2)}function Ne(t,e){return Ht((t=Ie(t)).getUTCFullYear()%100,e,2)}function Be(t,e){return Ht(t.getUTCFullYear()%1e4,e,4)}function Ve(t,e){var n=t.getUTCDay();return Ht((t=n>=4||0===n?Dt(t):Dt.ceil(t)).getUTCFullYear()%1e4,e,4)}function Ze(){return"+0000"}function je(){return"%"}function Ge(t){return+t}function qe(t){return Math.floor(+t/1e3)}function Xe(t){return new Date(t)}function Qe(t){return t instanceof Date?+t:+new Date(+t)}function Je(t,e,n,r,i,a,s,o,c,u){var l=F(),f=l.invert,h=l.domain,d=u(".%L"),g=u(":%S"),m=u("%I:%M"),y=u("%I %p"),p=u("%a %d"),v=u("%b %d"),T=u("%B"),k=u("%Y");function x(t){return(c(t)=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Ge,s:qe,S:ge,u:me,U:ye,V:ve,w:Te,W:ke,x:null,X:null,y:xe,Y:De,Z:we,"%":je},k={a:function(t){return s[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return o[t.getUTCMonth()]},c:null,d:Me,e:Me,f:Ue,g:Ne,G:Ve,H:_e,I:Se,j:Fe,L:Ye,m:$e,M:Ae,p:function(t){return i[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Ge,s:qe,S:Le,u:Ee,U:He,V:Oe,w:ze,W:We,x:null,X:null,y:Pe,Y:Be,Z:Ze,"%":je},x={a:function(t,e,n){var r=d.exec(e.slice(n));return r?(t.w=g.get(r[0].toLowerCase()),n+r[0].length):-1},A:function(t,e,n){var r=f.exec(e.slice(n));return r?(t.w=h.get(r[0].toLowerCase()),n+r[0].length):-1},b:function(t,e,n){var r=p.exec(e.slice(n));return r?(t.m=v.get(r[0].toLowerCase()),n+r[0].length):-1},B:function(t,e,n){var r=m.exec(e.slice(n));return r?(t.m=y.get(r[0].toLowerCase()),n+r[0].length):-1},c:function(t,n,r){return C(t,e,n,r)},d:Qt,e:Qt,f:ne,g:jt,G:Zt,H:Rt,I:Rt,j:Jt,L:ee,m:Xt,M:Kt,p:function(t,e,n){var r=u.exec(e.slice(n));return r?(t.p=l.get(r[0].toLowerCase()),n+r[0].length):-1},q:qt,Q:ie,s:ae,S:te,u:Pt,U:Nt,V:Bt,w:Wt,W:Vt,x:function(t,e,r){return C(t,n,e,r)},X:function(t,e,n){return C(t,r,e,n)},y:jt,Y:Zt,Z:Gt,"%":re};function b(t,e){return function(n){var r,i,a,s=[],o=-1,c=0,u=t.length;for(n instanceof Date||(n=new Date(+n));++o53)return null;"w"in a||(a.w=1),"Z"in a?(i=(r=St(Ft(a.y,0,1))).getUTCDay(),r=i>4||0===i?bt.ceil(r):bt(r),r=Tt.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(i=(r=_t(Ft(a.y,0,1))).getDay(),r=i>4||0===i?mt.ceil(r):mt(r),r=ht.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?St(Ft(a.y,0,1)).getUTCDay():_t(Ft(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,St(a)):_t(a)}}function C(t,e,n,r){for(var i,a,s=0,o=e.length,c=n.length;s=c)return-1;if(37===(i=e.charCodeAt(s++))){if(i=e.charAt(s++),!(a=x[i in $t?e.charAt(s++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return T.x=b(n,T),T.X=b(r,T),T.c=b(e,T),k.x=b(n,k),k.X=b(r,k),k.c=b(e,k),{format:function(t){var e=b(t+="",T);return e.toString=function(){return t},e},parse:function(t){var e=D(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=b(t+="",k);return e.toString=function(){return t},e},utcParse:function(t){var e=D(t+="",!0);return e.toString=function(){return t},e}}}({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"]}),Ut=Yt.format;var Re=new Date,Ke=new Date;function tn(t,e,n,r){function i(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return i.floor=function(e){return t(e=new Date(+e)),e},i.ceil=function(n){return t(n=new Date(n-1)),e(n,1),t(n),n},i.round=function(t){var e=i(t),n=i.ceil(t);return t-e0))return o;do{o.push(s=new Date(+n)),e(n,a),t(n)}while(s=e)for(;t(e),!n(e);)e.setTime(e-1)}),(function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!n(t););else for(;--r>=0;)for(;e(t,1),!n(t););}))},n&&(i.count=function(e,r){return Re.setTime(+e),Ke.setTime(+r),t(Re),t(Ke),Math.floor(n(Re,Ke))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(e){return r(e)%t==0}:function(e){return i.count(0,e)%t==0}):i:null}),i}var en=tn((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds())}),(function(t,e){t.setTime(+t+6e4*e)}),(function(t,e){return(e-t)/6e4}),(function(t){return t.getMinutes()})),nn=tn((function(t){t.setTime(t-t.getMilliseconds()-1e3*t.getSeconds()-6e4*t.getMinutes())}),(function(t,e){t.setTime(+t+36e5*e)}),(function(t,e){return(e-t)/36e5}),(function(t){return t.getHours()})),rn=tn((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/864e5),(t=>t.getDate()-1));function an(t){return tn((function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),(function(t,e){t.setDate(t.getDate()+7*e)}),(function(t,e){return(e-t-6e4*(e.getTimezoneOffset()-t.getTimezoneOffset()))/6048e5}))}var sn=an(0),on=an(1);an(2),an(3);var cn=an(4);an(5),an(6);var un=tn((function(t){t.setDate(1),t.setHours(0,0,0,0)}),(function(t,e){t.setMonth(t.getMonth()+e)}),(function(t,e){return e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())}),(function(t){return t.getMonth()})),ln=tn((function(t){t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,e){t.setFullYear(t.getFullYear()+e)}),(function(t,e){return e.getFullYear()-t.getFullYear()}),(function(t){return t.getFullYear()}));ln.every=function(t){return isFinite(t=Math.floor(t))&&t>0?tn((function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,n){e.setFullYear(e.getFullYear()+n*t)})):null};var fn=tn((function(t){t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+e)}),(function(t,e){return(e-t)/864e5}),(function(t){return t.getUTCDate()-1}));function hn(t){return tn((function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCDate(t.getUTCDate()+7*e)}),(function(t,e){return(e-t)/6048e5}))}var dn=hn(0),gn=hn(1);hn(2),hn(3);var mn=hn(4);hn(5),hn(6);var yn=tn((function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)}),(function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()}),(function(t){return t.getUTCFullYear()}));function pn(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function vn(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function Tn(t,e,n){return{y:t,m:e,d:n,H:0,M:0,S:0,L:0}}yn.every=function(t){return isFinite(t=Math.floor(t))&&t>0?tn((function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,n){e.setUTCFullYear(e.getUTCFullYear()+n*t)})):null};var kn,xn,bn={"-":"",_:" ",0:"0"},Dn=/^\s*\d+/,Cn=/^%/,wn=/[\\^$*+?|[\]().{}]/g;function Mn(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",a=i.length;return r+(a[t.toLowerCase(),e])))}function Yn(t,e,n){var r=Dn.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function Un(t,e,n){var r=Dn.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function $n(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function An(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function Ln(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function En(t,e,n){var r=Dn.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function Hn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function In(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 On(t,e,n){var r=Dn.exec(e.slice(n,n+1));return r?(t.q=3*r[0]-3,n+r[0].length):-1}function zn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Wn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Pn(t,e,n){var r=Dn.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function Nn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function Bn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function Vn(t,e,n){var r=Dn.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Zn(t,e,n){var r=Dn.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function jn(t,e,n){var r=Dn.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Gn(t,e,n){var r=Cn.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function qn(t,e,n){var r=Dn.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function Xn(t,e,n){var r=Dn.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function Qn(t,e){return Mn(t.getDate(),e,2)}function Jn(t,e){return Mn(t.getHours(),e,2)}function Rn(t,e){return Mn(t.getHours()%12||12,e,2)}function Kn(t,e){return Mn(1+rn.count(ln(t),t),e,3)}function tr(t,e){return Mn(t.getMilliseconds(),e,3)}function er(t,e){return tr(t,e)+"000"}function nr(t,e){return Mn(t.getMonth()+1,e,2)}function rr(t,e){return Mn(t.getMinutes(),e,2)}function ir(t,e){return Mn(t.getSeconds(),e,2)}function ar(t){var e=t.getDay();return 0===e?7:e}function sr(t,e){return Mn(sn.count(ln(t)-1,t),e,2)}function or(t){var e=t.getDay();return e>=4||0===e?cn(t):cn.ceil(t)}function cr(t,e){return t=or(t),Mn(cn.count(ln(t),t)+(4===ln(t).getDay()),e,2)}function ur(t){return t.getDay()}function lr(t,e){return Mn(on.count(ln(t)-1,t),e,2)}function fr(t,e){return Mn(t.getFullYear()%100,e,2)}function hr(t,e){return Mn((t=or(t)).getFullYear()%100,e,2)}function dr(t,e){return Mn(t.getFullYear()%1e4,e,4)}function gr(t,e){var n=t.getDay();return Mn((t=n>=4||0===n?cn(t):cn.ceil(t)).getFullYear()%1e4,e,4)}function mr(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+Mn(e/60|0,"0",2)+Mn(e%60,"0",2)}function yr(t,e){return Mn(t.getUTCDate(),e,2)}function pr(t,e){return Mn(t.getUTCHours(),e,2)}function vr(t,e){return Mn(t.getUTCHours()%12||12,e,2)}function Tr(t,e){return Mn(1+fn.count(yn(t),t),e,3)}function kr(t,e){return Mn(t.getUTCMilliseconds(),e,3)}function xr(t,e){return kr(t,e)+"000"}function br(t,e){return Mn(t.getUTCMonth()+1,e,2)}function Dr(t,e){return Mn(t.getUTCMinutes(),e,2)}function Cr(t,e){return Mn(t.getUTCSeconds(),e,2)}function wr(t){var e=t.getUTCDay();return 0===e?7:e}function Mr(t,e){return Mn(dn.count(yn(t)-1,t),e,2)}function _r(t){var e=t.getUTCDay();return e>=4||0===e?mn(t):mn.ceil(t)}function Sr(t,e){return t=_r(t),Mn(mn.count(yn(t),t)+(4===yn(t).getUTCDay()),e,2)}function Fr(t){return t.getUTCDay()}function Yr(t,e){return Mn(gn.count(yn(t)-1,t),e,2)}function Ur(t,e){return Mn(t.getUTCFullYear()%100,e,2)}function $r(t,e){return Mn((t=_r(t)).getUTCFullYear()%100,e,2)}function Ar(t,e){return Mn(t.getUTCFullYear()%1e4,e,4)}function Lr(t,e){var n=t.getUTCDay();return Mn((t=n>=4||0===n?mn(t):mn.ceil(t)).getUTCFullYear()%1e4,e,4)}function Er(){return"+0000"}function Hr(){return"%"}function Ir(t){return+t}function Or(t){return Math.floor(+t/1e3)}!function(t){kn=function(t){var e=t.dateTime,n=t.date,r=t.time,i=t.periods,a=t.days,s=t.shortDays,o=t.months,c=t.shortMonths,u=Sn(i),l=Fn(i),f=Sn(a),h=Fn(a),d=Sn(s),g=Fn(s),m=Sn(o),y=Fn(o),p=Sn(c),v=Fn(c),T={a:function(t){return s[t.getDay()]},A:function(t){return a[t.getDay()]},b:function(t){return c[t.getMonth()]},B:function(t){return o[t.getMonth()]},c:null,d:Qn,e:Qn,f:er,g:hr,G:gr,H:Jn,I:Rn,j:Kn,L:tr,m:nr,M:rr,p:function(t){return i[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:Ir,s:Or,S:ir,u:ar,U:sr,V:cr,w:ur,W:lr,x:null,X:null,y:fr,Y:dr,Z:mr,"%":Hr},k={a:function(t){return s[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return c[t.getUTCMonth()]},B:function(t){return o[t.getUTCMonth()]},c:null,d:yr,e:yr,f:xr,g:$r,G:Lr,H:pr,I:vr,j:Tr,L:kr,m:br,M:Dr,p:function(t){return i[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:Ir,s:Or,S:Cr,u:wr,U:Mr,V:Sr,w:Fr,W:Yr,x:null,X:null,y:Ur,Y:Ar,Z:Er,"%":Hr},x={a:function(t,e,n){var r=d.exec(e.slice(n));return r?(t.w=g.get(r[0].toLowerCase()),n+r[0].length):-1},A:function(t,e,n){var r=f.exec(e.slice(n));return r?(t.w=h.get(r[0].toLowerCase()),n+r[0].length):-1},b:function(t,e,n){var r=p.exec(e.slice(n));return r?(t.m=v.get(r[0].toLowerCase()),n+r[0].length):-1},B:function(t,e,n){var r=m.exec(e.slice(n));return r?(t.m=y.get(r[0].toLowerCase()),n+r[0].length):-1},c:function(t,n,r){return C(t,e,n,r)},d:Wn,e:Wn,f:jn,g:Hn,G:En,H:Nn,I:Nn,j:Pn,L:Zn,m:zn,M:Bn,p:function(t,e,n){var r=u.exec(e.slice(n));return r?(t.p=l.get(r[0].toLowerCase()),n+r[0].length):-1},q:On,Q:qn,s:Xn,S:Vn,u:Un,U:$n,V:An,w:Yn,W:Ln,x:function(t,e,r){return C(t,n,e,r)},X:function(t,e,n){return C(t,r,e,n)},y:Hn,Y:En,Z:In,"%":Gn};function b(t,e){return function(n){var r,i,a,s=[],o=-1,c=0,u=t.length;for(n instanceof Date||(n=new Date(+n));++o53)return null;"w"in a||(a.w=1),"Z"in a?(i=(r=vn(Tn(a.y,0,1))).getUTCDay(),r=i>4||0===i?gn.ceil(r):gn(r),r=fn.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(i=(r=pn(Tn(a.y,0,1))).getDay(),r=i>4||0===i?on.ceil(r):on(r),r=rn.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?vn(Tn(a.y,0,1)).getUTCDay():pn(Tn(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,vn(a)):pn(a)}}function C(t,e,n,r){for(var i,a,s=0,o=e.length,c=n.length;s=c)return-1;if(37===(i=e.charCodeAt(s++))){if(i=e.charAt(s++),!(a=x[i in bn?e.charAt(s++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return T.x=b(n,T),T.X=b(r,T),T.c=b(e,T),k.x=b(n,k),k.X=b(r,k),k.c=b(e,k),{format:function(t){var e=b(t+="",T);return e.toString=function(){return t},e},parse:function(t){var e=D(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=b(t+="",k);return e.toString=function(){return t},e},utcParse:function(t){var e=D(t+="",!0);return e.toString=function(){return t},e}}}(t),xn=kn.format}({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"]});var zr={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"},Wr=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|YYYY|YY?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,Pr=/\d\d/,Nr=/\d\d?/,Br=/\d*[^-_:/,()\s\d]+/,Vr={},Zr=function(t){return(t=+t)+(t>68?1900:2e3)};var jr=function(t){return function(e){this[t]=+e}},Gr=[/[+-]\d\d:?(\d\d)?|Z/,function(t){(this.zone||(this.zone={})).offset=function(t){if(!t)return 0;if("Z"===t)return 0;var e=t.match(/([+-]|\d\d)/g),n=60*e[1]+(+e[2]||0);return 0===n?0:"+"===e[0]?-n:n}(t)}],qr=function(t){var e=Vr[t];return e&&(e.indexOf?e:e.s.concat(e.f))},Xr=function(t,e){var n,r=Vr.meridiem;if(r){for(var i=1;i<=24;i+=1)if(t.indexOf(r(i,0,e))>-1){n=i>12;break}}else n=t===(e?"pm":"PM");return n},Qr={A:[Br,function(t){this.afternoon=Xr(t,!1)}],a:[Br,function(t){this.afternoon=Xr(t,!0)}],S:[/\d/,function(t){this.milliseconds=100*+t}],SS:[Pr,function(t){this.milliseconds=10*+t}],SSS:[/\d{3}/,function(t){this.milliseconds=+t}],s:[Nr,jr("seconds")],ss:[Nr,jr("seconds")],m:[Nr,jr("minutes")],mm:[Nr,jr("minutes")],H:[Nr,jr("hours")],h:[Nr,jr("hours")],HH:[Nr,jr("hours")],hh:[Nr,jr("hours")],D:[Nr,jr("day")],DD:[Pr,jr("day")],Do:[Br,function(t){var e=Vr.ordinal,n=t.match(/\d+/);if(this.day=n[0],e)for(var r=1;r<=31;r+=1)e(r).replace(/\[|\]/g,"")===t&&(this.day=r)}],M:[Nr,jr("month")],MM:[Pr,jr("month")],MMM:[Br,function(t){var e=qr("months"),n=(qr("monthsShort")||e.map((function(t){return t.slice(0,3)}))).indexOf(t)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[Br,function(t){var e=qr("months").indexOf(t)+1;if(e<1)throw new Error;this.month=e%12||e}],Y:[/[+-]?\d+/,jr("year")],YY:[Pr,function(t){this.year=Zr(t)}],YYYY:[/\d{4}/,jr("year")],Z:Gr,ZZ:Gr};function Jr(t){var e,n;e=t,n=Vr&&Vr.formats;for(var r=(t=e.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,e,r){var i=r&&r.toUpperCase();return e||n[r]||zr[r]||n[i].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(t,e,n){return e||n.slice(1)}))}))).match(Wr),i=r.length,a=0;al&&M.push("'"+this.terminals_[D]+"'");S=d.showPosition?"Parse error on line "+(c+1)+":\n"+d.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[T]||T)+"'":"Parse error on line "+(c+1)+": Unexpected "+(T==f?"end of input":"'"+(this.terminals_[T]||T)+"'"),this.parseError(S,{text:d.match,token:this.terminals_[T]||T,line:d.yylineno,loc:y,expected:M})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+T);switch(x[0]){case 1:n.push(T),i.push(d.yytext),a.push(d.yylloc),n.push(x[1]),T=null,u=d.yyleng,o=d.yytext,c=d.yylineno,y=d.yylloc;break;case 2:if(C=this.productions_[x[1]][1],_.$=i[i.length-C],_._$={first_line:a[a.length-(C||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(C||1)].first_column,last_column:a[a.length-1].last_column},p&&(_._$.range=[a[a.length-(C||1)].range[0],a[a.length-1].range[1]]),void 0!==(b=this.performAction.apply(_,[o,u,c,g.yy,x[1],i,a].concat(h))))return b;C&&(n=n.slice(0,-1*C*2),i=i.slice(0,-1*C),a=a.slice(0,-1*C)),n.push(this.productions_[x[1]][0]),i.push(_.$),a.push(_._$),w=s[n[n.length-2]][n[n.length-1]],n.push(w);break;case 3:return!0}}return!0}},b={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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 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 i=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-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var n,r,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var a in i)this[a]=i[a];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),a=0;ae[0].length)){if(e=n,r=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,i[a])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,r){switch(n){case 0:return this.begin("open_directive"),40;case 1:return this.begin("type_directive"),41;case 2:return this.popState(),this.begin("arg_directive"),33;case 3:return this.popState(),this.popState(),43;case 4:return 42;case 5:return this.begin("acc_title"),21;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),23;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:case 13:case 14:break;case 15:return 11;case 16:case 17:case 18:break;case 19:this.begin("href");break;case 20:this.popState();break;case 21:return 38;case 22:this.begin("callbackname");break;case 23:this.popState();break;case 24:this.popState(),this.begin("callbackargs");break;case 25:return 36;case 26:this.popState();break;case 27:return 37;case 28:this.begin("click");break;case 29:this.popState();break;case 30:return 35;case 31:return 5;case 32:return 12;case 33:return 13;case 34:return 14;case 35:return 15;case 36:return 16;case 37:return 18;case 38:return 17;case 39:return 19;case 40:return"date";case 41:return 20;case 42:return"accDescription";case 43:return 26;case 44:return 28;case 45:return 29;case 46:return 33;case 47:return 7;case 48:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},callbackargs:{rules:[26,27],inclusive:!1},callbackname:{rules:[23,24,25],inclusive:!1},href:{rules:[20,21],inclusive:!1},click:{rules:[29,30],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,13,14,15,16,17,18,19,22,28,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],inclusive:!0}}};function D(){this.yy={}}return x.lexer=b,D.prototype=x,x.Parser=D,new D}();Rr.parser=Rr;const Kr=Rr;f.extend((function(t,e,n){var r=function(t){return t.add(4-t.isoWeekday(),o)},i=e.prototype;i.isoWeekYear=function(){return r(this).year()},i.isoWeek=function(t){if(!this.$utils().u(t))return this.add(7*(t-this.isoWeek()),o);var e,i,a,s,l=r(this),f=(e=this.isoWeekYear(),i=this.$u,a=(i?n.utc:n)().year(e).startOf(u),s=4-a.isoWeekday(),a.isoWeekday()>4&&(s+=7),a.add(s,o));return l.diff(f,c)+1},i.isoWeekday=function(t){return this.$utils().u(t)?this.day()||7:this.day(this.day()%7?t:t-7)};var a=i.startOf;i.startOf=function(t,e){var n=this.$utils(),r=!!n.u(e)||e;return"isoweek"===n.p(t)?r?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):a.bind(this)(t,e)}})),f.extend((function(t,e,n){n.p.customParseFormat=!0,t&&t.parseTwoDigitYear&&(Zr=t.parseTwoDigitYear);var r=e.prototype,i=r.parse;r.parse=function(t){var e=t.date,r=t.utc,a=t.args;this.$u=r;var s=a[1];if("string"==typeof s){var o=!0===a[2],c=!0===a[3],u=o||c,l=a[2];c&&(l=a[2]),Vr=this.$locale(),!o&&l&&(Vr=n.Ls[l]),this.$d=function(t,e,n){try{if(["x","X"].indexOf(e)>-1)return new Date(("X"===e?1e3:1)*t);var r=Jr(e)(t),i=r.year,a=r.month,s=r.day,o=r.hours,c=r.minutes,u=r.seconds,l=r.milliseconds,f=r.zone,h=new Date,d=s||(i||a?1:h.getDate()),g=i||h.getFullYear(),m=0;i&&!a||(m=a>0?a-1:h.getMonth());var y=o||0,p=c||0,v=u||0,T=l||0;return f?new Date(Date.UTC(g,m,d,y,p,v,T+60*f.offset*1e3)):n?new Date(Date.UTC(g,m,d,y,p,v,T)):new Date(g,m,d,y,p,v,T)}catch(k){return new Date("")}}(e,s,r),this.init(),l&&!0!==l&&(this.$L=this.locale(l).$L),u&&e!=this.format(s)&&(this.$d=new Date("")),Vr={}}else if(s instanceof Array)for(var f=s.length,h=1;h<=f;h+=1){a[1]=s[h-1];var d=n.apply(this,a);if(d.isValid()){this.$d=d.$d,this.$L=d.$L,this.init();break}h===f&&(this.$d=new Date(""))}else i.call(this,t)}})),f.extend((function(t,e){var n=e.prototype,r=n.format;n.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return r.bind(this)(t);var i=this.$utils(),a=(t||l).replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(t){switch(t){case"Q":return Math.ceil((e.$M+1)/3);case"Do":return n.ordinal(e.$D);case"gggg":return e.weekYear();case"GGGG":return e.isoWeekYear();case"wo":return n.ordinal(e.week(),"W");case"w":case"ww":return i.s(e.week(),"w"===t?1:2,"0");case"W":case"WW":return i.s(e.isoWeek(),"W"===t?1:2,"0");case"k":case"kk":return i.s(String(0===e.$H?24:e.$H),"k"===t?1:2,"0");case"X":return Math.floor(e.$d.getTime()/1e3);case"x":return e.$d.getTime();case"z":return"["+e.offsetName()+"]";case"zzz":return"["+e.offsetName("long")+"]";default:return t}}));return r.bind(this)(a)}}));let ti,ei="",ni="",ri="",ii=[],ai=[],si={},oi=[],ci=[],ui="",li="";const fi=["active","done","crit","milestone"];let hi=[],di=!1,gi=!1,mi=0;const yi=function(t,e,n,r){return!r.includes(t.format(e.trim()))&&(!!(t.isoWeekday()>=6&&n.includes("weekends"))||(!!n.includes(t.format("dddd").toLowerCase())||n.includes(t.format(e.trim()))))},pi=function(t,e,n,r){if(!n.length||t.manualEndTime)return;let i,a;i=t.startTime instanceof Date?f(t.startTime):f(t.startTime,e,!0),i=i.add(1,"d"),a=t.endTime instanceof Date?f(t.endTime):f(t.endTime,e,!0);const[s,o]=vi(i,a,e,n,r);t.endTime=s.toDate(),t.renderEndTime=o},vi=function(t,e,n,r,i){let a=!1,s=null;for(;t<=e;)a||(s=e.toDate()),a=yi(t,n,r,i),a&&(e=e.add(1,"d")),t=t.add(1,"d");return[e,s]},Ti=function(t,e,n){n=n.trim();const r=/^after\s+([\d\w- ]+)/.exec(n.trim());if(null!==r){let t=null;if(r[1].split(" ").forEach((function(e){let n=Si(e);void 0!==n&&(t?n.endTime>t.endTime&&(t=n):t=n)})),t)return t.endTime;{const t=new Date;return t.setHours(0,0,0,0),t}}let i=f(n,e.trim(),!0);if(i.isValid())return i.toDate();{b.debug("Invalid date:"+n),b.debug("With date format:"+e.trim());const t=new Date(n);if(void 0===t||isNaN(t.getTime())||t.getFullYear()<-1e4||t.getFullYear()>1e4)throw new Error("Invalid date:"+n);return t}},ki=function(t){const e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return null!==e?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]},xi=function(t,e,n,r=!1){n=n.trim();let i=f(n,e.trim(),!0);if(i.isValid())return r&&(i=i.add(1,"d")),i.toDate();let a=f(t);const[s,o]=ki(n);if(!Number.isNaN(s)){const t=a.add(s,o);t.isValid()&&(a=t)}return a.toDate()};let bi=0;const Di=function(t){return void 0===t?(bi+=1,"task"+bi):t};let Ci,wi,Mi=[];const _i={},Si=function(t){const e=_i[t];return Mi[e]},Fi=function(){const t=function(t){const e=Mi[t];let n="";switch(Mi[t].raw.startTime.type){case"prevTaskEnd":{const t=Si(e.prevTaskId);e.startTime=t.endTime;break}case"getStartDate":n=Ti(0,ei,Mi[t].raw.startTime.startData),n&&(Mi[t].startTime=n)}return Mi[t].startTime&&(Mi[t].endTime=xi(Mi[t].startTime,ei,Mi[t].raw.endTime.data,di),Mi[t].endTime&&(Mi[t].processed=!0,Mi[t].manualEndTime=f(Mi[t].raw.endTime.data,"YYYY-MM-DD",!0).isValid(),pi(Mi[t],ei,ai,ii))),Mi[t].processed};let e=!0;for(const[n,r]of Mi.entries())t(n),e=e&&r.processed;return e},Yi=function(t,e){t.split(",").forEach((function(t){let n=Si(t);void 0!==n&&n.classes.push(e)}))},Ui=function(t,e){hi.push((function(){const n=document.querySelector(`[id="${t}"]`);null!==n&&n.addEventListener("click",(function(){e()}))}),(function(){const n=document.querySelector(`[id="${t}-text"]`);null!==n&&n.addEventListener("click",(function(){e()}))}))};function $i(t,e,n){let r=!0;for(;r;)r=!1,n.forEach((function(n){const i=new RegExp("^\\s*"+n+"\\s*$");t[0].match(i)&&(e[n]=!0,t.shift(1),r=!0)}))}const Ai=(t,e)=>{let n=[...t].map((()=>-1/0)),r=[...t].sort(((t,e)=>t.startTime-e.startTime||t.order-e.order)),i=0;for(const a of r)for(let t=0;t=n[t]){n[t]=a.endTime,a.order=t+e,t>i&&(i=t);break}return i};let Li;const Ei={parser:Kr,db:{parseDirective:function(t,e,n){T.parseDirective(this,t,e,n)},getConfig:()=>h().gantt,clear:function(){oi=[],ci=[],ui="",hi=[],bi=0,Ci=void 0,wi=void 0,Mi=[],ei="",ni="",li="",ti=void 0,ri="",ii=[],ai=[],di=!1,gi=!1,mi=0,si={},k()},setDateFormat:function(t){ei=t},getDateFormat:function(){return ei},enableInclusiveEndDates:function(){di=!0},endDatesAreInclusive:function(){return di},enableTopAxis:function(){gi=!0},topAxisEnabled:function(){return gi},setAxisFormat:function(t){ni=t},getAxisFormat:function(){return ni},setTickInterval:function(t){ti=t},getTickInterval:function(){return ti},setTodayMarker:function(t){ri=t},getTodayMarker:function(){return ri},setAccTitle:d,getAccTitle:g,setDiagramTitle:m,getDiagramTitle:y,setDisplayMode:function(t){li=t},getDisplayMode:function(){return li},setAccDescription:p,getAccDescription:v,addSection:function(t){ui=t,oi.push(t)},getSections:function(){return oi},getTasks:function(){let t=Fi();let e=0;for(;!t&&e<10;)t=Fi(),e++;return ci=Mi,ci},addTask:function(t,e){const n={section:ui,type:ui,processed:!1,manualEndTime:!1,renderEndTime:null,raw:{data:e},task:t,classes:[]},r=function(t,e){let n;n=":"===e.substr(0,1)?e.substr(1,e.length):e;const r=n.split(","),i={};$i(r,i,fi);for(let a=0;a{M.runFunc(e,...r)}))}(t,e,n)})),Yi(t,"clickable")},setLink:function(t,e){let n=e;"loose"!==h().securityLevel&&(n=x(e)),t.split(",").forEach((function(t){void 0!==Si(t)&&(Ui(t,(()=>{window.open(n,"_self")})),si[t]=n)})),Yi(t,"clickable")},getLinks:function(){return si},bindFunctions:function(t){hi.forEach((function(e){e(t)}))},parseDuration:ki,isInvalidDate:yi},renderer:{setConf:function(){b.debug("Something is calling, setConf, remove the call")},draw:function(t,e,n,r){const i=h().gantt,a=h().securityLevel;let s;"sandbox"===a&&(s=D("#i"+e));const o=D("sandbox"===a?s.nodes()[0].contentDocument.body:"body"),c="sandbox"===a?s.nodes()[0].contentDocument:document,u=c.getElementById(e);Li=u.parentElement.offsetWidth,void 0===Li&&(Li=1200),void 0!==i.useWidth&&(Li=i.useWidth);const l=r.db.getTasks();let d=[];for(const f of l)d.push(f.type);d=function(t){const e={},n=[];for(let r=0,i=t.length;re.type===t)).length}u.setAttribute("viewBox","0 0 "+Li+" "+m);const y=o.select(`[id="${e}"]`),p=function(){return $.apply(Je(wt,Mt,vt,pt,gt,ht,ft,lt,ut,Ut).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}().domain([L(l,(function(t){return t.startTime})),A(l,(function(t){return t.endTime}))]).rangeRound([0,Li-i.leftPadding-i.rightPadding]);l.sort((function(t,e){const n=t.startTime,r=e.startTime;let i=0;return n>r?i=1:nt?Math.min(t,e):e),0),h=o.reduce(((t,{endTime:e})=>t?Math.max(t,e):e),0),d=r.db.getDateFormat();if(!l||!h)return;const g=[];let m=null,v=f(l);for(;v.valueOf()<=h;)r.db.isInvalidDate(v,d,c,u)?m?m.end=v:m={start:v,end:v}:m&&(g.push(m),m=null),v=v.add(1,"d");y.append("g").selectAll("rect").data(g).enter().append("rect").attr("id",(function(t){return"exclude-"+t.start.format("YYYY-MM-DD")})).attr("x",(function(t){return p(t.start)+n})).attr("y",i.gridLineStartPadding).attr("width",(function(t){const e=t.end.add(1,"day");return p(e)-p(t.start)})).attr("height",s-e-i.gridLineStartPadding).attr("transform-origin",(function(e,r){return(p(e.start)+n+.5*(p(e.end)-p(e.start))).toString()+"px "+(r*t+.5*s).toString()+"px"})).attr("class","exclude-range")})(o,u,l,0,a,t,r.db.getExcludes(),r.db.getIncludes()),function(t,e,n,a){let s=(o=p,P(3,o)).tickSize(-a+e+i.gridLineStartPadding).tickFormat(xn(r.db.getAxisFormat()||i.axisFormat||"%Y-%m-%d"));var o;const c=/^([1-9]\d*)(minute|hour|day|week|month)$/.exec(r.db.getTickInterval()||i.tickInterval);if(null!==c){const t=c[1];switch(c[2]){case"minute":s.ticks(en.every(t));break;case"hour":s.ticks(nn.every(t));break;case"day":s.ticks(rn.every(t));break;case"week":s.ticks(sn.every(t));break;case"month":s.ticks(un.every(t))}}if(y.append("g").attr("class","grid").attr("transform","translate("+t+", "+(a-50)+")").call(s).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),r.db.topAxisEnabled()||i.topAxis){let n=function(t){return P(1,t)}(p).tickSize(-a+e+i.gridLineStartPadding).tickFormat(xn(r.db.getAxisFormat()||i.axisFormat||"%Y-%m-%d"));if(null!==c){const t=c[1];switch(c[2]){case"minute":n.ticks(en.every(t));break;case"hour":n.ticks(nn.every(t));break;case"day":n.ticks(rn.every(t));break;case"week":n.ticks(sn.every(t));break;case"month":n.ticks(un.every(t))}}y.append("g").attr("class","grid").attr("transform","translate("+t+", "+e+")").call(n).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}(l,u,0,a),function(t,n,a,s,o,c,u){const l=[...new Set(t.map((t=>t.order)))].map((e=>t.find((t=>t.order===e))));y.append("g").selectAll("rect").data(l).enter().append("rect").attr("x",0).attr("y",(function(t,e){return t.order*n+a-2})).attr("width",(function(){return u-i.rightPadding/2})).attr("height",n).attr("class",(function(t){for(const[e,n]of d.entries())if(t.type===n)return"section section"+e%i.numberSectionStyles;return"section section0"}));const f=y.append("g").selectAll("rect").data(t).enter(),g=r.db.getLinks();f.append("rect").attr("id",(function(t){return t.id})).attr("rx",3).attr("ry",3).attr("x",(function(t){return t.milestone?p(t.startTime)+s+.5*(p(t.endTime)-p(t.startTime))-.5*o:p(t.startTime)+s})).attr("y",(function(t,e){return t.order*n+a})).attr("width",(function(t){return t.milestone?o:p(t.renderEndTime||t.endTime)-p(t.startTime)})).attr("height",o).attr("transform-origin",(function(t,e){return e=t.order,(p(t.startTime)+s+.5*(p(t.endTime)-p(t.startTime))).toString()+"px "+(e*n+a+.5*o).toString()+"px"})).attr("class",(function(t){const e="task";let n="";t.classes.length>0&&(n=t.classes.join(" "));let r=0;for(const[s,o]of d.entries())t.type===o&&(r=s%i.numberSectionStyles);let a="";return t.active?t.crit?a+=" activeCrit":a=" active":t.done?a=t.crit?" doneCrit":" done":t.crit&&(a+=" crit"),0===a.length&&(a=" task"),t.milestone&&(a=" milestone "+a),a+=r,a+=" "+n,e+a})),f.append("text").attr("id",(function(t){return t.id+"-text"})).text((function(t){return t.task})).attr("font-size",i.fontSize).attr("x",(function(t){let e=p(t.startTime),n=p(t.renderEndTime||t.endTime);t.milestone&&(e+=.5*(p(t.endTime)-p(t.startTime))-.5*o),t.milestone&&(n=e+o);const r=this.getBBox().width;return r>n-e?n+r+1.5*i.leftPadding>u?e+s-5:n+s+5:(n-e)/2+e+s})).attr("y",(function(t,e){return t.order*n+i.barHeight/2+(i.fontSize/2-2)+a})).attr("text-height",o).attr("class",(function(t){const e=p(t.startTime);let n=p(t.endTime);t.milestone&&(n=e+o);const r=this.getBBox().width;let a="";t.classes.length>0&&(a=t.classes.join(" "));let s=0;for(const[o,u]of d.entries())t.type===u&&(s=o%i.numberSectionStyles);let c="";return t.active&&(c=t.crit?"activeCritText"+s:"activeText"+s),t.done?c=t.crit?c+" doneCritText"+s:c+" doneText"+s:t.crit&&(c=c+" critText"+s),t.milestone&&(c+=" milestoneText"),r>n-e?n+r+1.5*i.leftPadding>u?a+" taskTextOutsideLeft taskTextOutside"+s+" "+c:a+" taskTextOutsideRight taskTextOutside"+s+" "+c+" width-"+r:a+" taskText taskText"+s+" "+c+" width-"+r}));if("sandbox"===h().securityLevel){let t;t=D("#i"+e);const n=t.nodes()[0].contentDocument;f.filter((function(t){return void 0!==g[t.id]})).each((function(t){var e=n.querySelector("#"+t.id),r=n.querySelector("#"+t.id+"-text");const i=e.parentNode;var a=n.createElement("a");a.setAttribute("xlink:href",g[t.id]),a.setAttribute("target","_top"),i.appendChild(a),a.appendChild(e),a.appendChild(r)}))}}(t,o,u,l,s,0,n),function(t,e){let n=0;const r=Object.keys(g).map((t=>[t,g[t]]));y.append("g").selectAll("text").data(r).enter().append((function(t){const e=t[0].split(w.lineBreakRegex),n=-(e.length-1)/2,r=c.createElementNS("http://www.w3.org/2000/svg","text");r.setAttribute("dy",n+"em");for(const[i,a]of e.entries()){const t=c.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttribute("alignment-baseline","central"),t.setAttribute("x","10"),i>0&&t.setAttribute("dy","1em"),t.textContent=a,r.appendChild(t)}return r})).attr("x",10).attr("y",(function(i,a){if(!(a>0))return i[1]*t/2+e;for(let s=0;s`\n .mermaid-main-font {\n font-family: "trebuchet ms", verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n .exclude-range {\n fill: ${t.excludeBkgColor};\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: ${t.sectionBkgColor};\n }\n\n .section2 {\n fill: ${t.sectionBkgColor2};\n }\n\n .section1,\n .section3 {\n fill: ${t.altSectionBkgColor};\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle1 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle2 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle3 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle {\n text-anchor: start;\n // font-size: ${t.ganttFontSize};\n // text-height: 14px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ${t.gridColor};\n opacity: 0.8;\n shape-rendering: crispEdges;\n text {\n font-family: ${t.fontFamily};\n fill: ${t.textColor};\n }\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ${t.todayLineColor};\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n\n // .taskText:not([font-size]) {\n // font-size: ${t.ganttFontSize};\n // }\n\n .taskTextOutsideRight {\n fill: ${t.taskTextDarkColor};\n text-anchor: start;\n // font-size: ${t.ganttFontSize};\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n\n }\n\n .taskTextOutsideLeft {\n fill: ${t.taskTextDarkColor};\n text-anchor: end;\n // font-size: ${t.ganttFontSize};\n }\n\n /* Special case clickable */\n .task.clickable {\n cursor: pointer;\n }\n .taskText.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ${t.taskTextColor};\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ${t.taskBkgColor};\n stroke: ${t.taskBorderColor};\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ${t.taskTextOutsideColor};\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ${t.taskTextOutsideColor};\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ${t.activeTaskBkgColor};\n stroke: ${t.activeTaskBorderColor};\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ${t.doneTaskBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.critBkgColor};\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.activeTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor} ;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n`};export{Ei as diagram}; diff --git a/assets/gitGraphDiagram-127727f3.0a7c406c.js b/assets/gitGraphDiagram-127727f3.024abe5a.js similarity index 99% rename from assets/gitGraphDiagram-127727f3.0a7c406c.js rename to assets/gitGraphDiagram-127727f3.024abe5a.js index be5971e07..3fa307354 100644 --- a/assets/gitGraphDiagram-127727f3.0a7c406c.js +++ b/assets/gitGraphDiagram-127727f3.024abe5a.js @@ -1 +1 @@ -var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,i=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,a=(e,r,i)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[r]=i;"undefined"!=typeof require&&require;import{c as s,s as o,g as l,a as h,b as m,v as u,x as y,m as p,l as g,j as b,a9 as d,z as f,aa as k,h as _,y as $,ab as x}from"./mermaid.core.a66200b0.js";var v=function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[1,4],r=[1,7],i=[1,5],n=[1,9],c=[1,6],a=[2,6],s=[1,16],o=[6,8,14,20,22,24,25,27,29,32,37,40,50,55],l=[8,14,20,22,24,25,27,29,32,37,40],h=[8,13,14,20,22,24,25,27,29,32,37,40],m=[1,26],u=[6,8,14,50,55],y=[8,14,55],p=[1,53],g=[1,52],b=[8,14,30,33,35,38,55],d=[1,67],f=[1,68],k=[1,69],_=[8,14,33,35,42,55],$={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,GG:6,document:7,EOF:8,":":9,DIR:10,options:11,body:12,OPT:13,NL:14,line:15,statement:16,commitStatement:17,mergeStatement:18,cherryPickStatement:19,acc_title:20,acc_title_value:21,acc_descr:22,acc_descr_value:23,acc_descr_multiline_value:24,section:25,branchStatement:26,CHECKOUT:27,ref:28,BRANCH:29,ORDER:30,NUM:31,CHERRY_PICK:32,COMMIT_ID:33,STR: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,openDirective:46,typeDirective:47,closeDirective:48,argDirective:49,open_directive:50,type_directive:51,arg_directive:52,close_directive:53,ID:54,";":55,$accept:0,$end:1},terminals_:{2:"error",6:"GG",8:"EOF",9:":",10:"DIR",13:"OPT",14:"NL",20:"acc_title",21:"acc_title_value",22:"acc_descr",23:"acc_descr_value",24:"acc_descr_multiline_value",25:"section",27:"CHECKOUT",29:"BRANCH",30:"ORDER",31:"NUM",32:"CHERRY_PICK",33:"COMMIT_ID",34:"STR",35:"COMMIT_TAG",36:"EMPTYSTR",37:"MERGE",38:"COMMIT_TYPE",40:"COMMIT",42:"COMMIT_MSG",43:"NORMAL",44:"REVERSE",45:"HIGHLIGHT",50:"open_directive",51:"type_directive",52:"arg_directive",53:"close_directive",54:"ID",55:";"},productions_:[0,[3,2],[3,2],[3,3],[3,4],[3,5],[7,0],[7,2],[11,2],[11,1],[12,0],[12,2],[15,2],[15,1],[16,1],[16,1],[16,1],[16,2],[16,2],[16,1],[16,1],[16,1],[16,2],[26,2],[26,4],[19,3],[19,5],[19,5],[19,5],[19,5],[18,2],[18,4],[18,4],[18,4],[18,6],[18,6],[18,6],[18,6],[18,6],[18,6],[18,8],[18,8],[18,8],[18,8],[18,8],[18,8],[17,2],[17,3],[17,3],[17,5],[17,5],[17,3],[17,5],[17,5],[17,5],[17,5],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,3],[17,5],[17,5],[17,5],[17,5],[17,5],[17,5],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[41,0],[41,1],[39,1],[39,1],[39,1],[5,3],[5,5],[46,1],[47,1],[49,1],[48,1],[28,1],[28,1],[4,1],[4,1],[4,1]],performAction:function(t,e,r,i,n,c,a){var s=c.length-1;switch(n){case 3:return c[s];case 4:return c[s-1];case 5:return i.setDirection(c[s-3]),c[s-1];case 7:i.setOptions(c[s-1]),this.$=c[s];break;case 8:c[s-1]+=c[s],this.$=c[s-1];break;case 10:this.$=[];break;case 11:c[s-1].push(c[s]),this.$=c[s-1];break;case 12:this.$=c[s-1];break;case 17:this.$=c[s].trim(),i.setAccTitle(this.$);break;case 18:case 19:this.$=c[s].trim(),i.setAccDescription(this.$);break;case 20:i.addSection(c[s].substr(8)),this.$=c[s].substr(8);break;case 22:i.checkout(c[s]);break;case 23:i.branch(c[s]);break;case 24:i.branch(c[s-2],c[s]);break;case 25:i.cherryPick(c[s],"",void 0);break;case 26:i.cherryPick(c[s-2],"",c[s]);break;case 27:case 29:i.cherryPick(c[s-2],"","");break;case 28:i.cherryPick(c[s],"",c[s-2]);break;case 30:i.merge(c[s],"","","");break;case 31:i.merge(c[s-2],c[s],"","");break;case 32:i.merge(c[s-2],"",c[s],"");break;case 33:i.merge(c[s-2],"","",c[s]);break;case 34:i.merge(c[s-4],c[s],"",c[s-2]);break;case 35:i.merge(c[s-4],"",c[s],c[s-2]);break;case 36:i.merge(c[s-4],"",c[s-2],c[s]);break;case 37:i.merge(c[s-4],c[s-2],c[s],"");break;case 38:i.merge(c[s-4],c[s-2],"",c[s]);break;case 39:i.merge(c[s-4],c[s],c[s-2],"");break;case 40:i.merge(c[s-6],c[s-4],c[s-2],c[s]);break;case 41:i.merge(c[s-6],c[s],c[s-4],c[s-2]);break;case 42:i.merge(c[s-6],c[s-4],c[s],c[s-2]);break;case 43:i.merge(c[s-6],c[s-2],c[s-4],c[s]);break;case 44:i.merge(c[s-6],c[s],c[s-2],c[s-4]);break;case 45:i.merge(c[s-6],c[s-2],c[s],c[s-4]);break;case 46:i.commit(c[s]);break;case 47:i.commit("","",i.commitType.NORMAL,c[s]);break;case 48:i.commit("","",c[s],"");break;case 49:i.commit("","",c[s],c[s-2]);break;case 50:i.commit("","",c[s-2],c[s]);break;case 51:i.commit("",c[s],i.commitType.NORMAL,"");break;case 52:i.commit("",c[s-2],i.commitType.NORMAL,c[s]);break;case 53:i.commit("",c[s],i.commitType.NORMAL,c[s-2]);break;case 54:i.commit("",c[s-2],c[s],"");break;case 55:i.commit("",c[s],c[s-2],"");break;case 56:i.commit("",c[s-4],c[s-2],c[s]);break;case 57:i.commit("",c[s-4],c[s],c[s-2]);break;case 58:i.commit("",c[s-2],c[s-4],c[s]);break;case 59:i.commit("",c[s],c[s-4],c[s-2]);break;case 60:i.commit("",c[s],c[s-2],c[s-4]);break;case 61:i.commit("",c[s-2],c[s],c[s-4]);break;case 62:i.commit(c[s],"",i.commitType.NORMAL,"");break;case 63:i.commit(c[s],"",i.commitType.NORMAL,c[s-2]);break;case 64:i.commit(c[s-2],"",i.commitType.NORMAL,c[s]);break;case 65:i.commit(c[s-2],"",c[s],"");break;case 66:i.commit(c[s],"",c[s-2],"");break;case 67:i.commit(c[s],c[s-2],i.commitType.NORMAL,"");break;case 68:i.commit(c[s-2],c[s],i.commitType.NORMAL,"");break;case 69:i.commit(c[s-4],"",c[s-2],c[s]);break;case 70:i.commit(c[s-4],"",c[s],c[s-2]);break;case 71:i.commit(c[s-2],"",c[s-4],c[s]);break;case 72:i.commit(c[s],"",c[s-4],c[s-2]);break;case 73:i.commit(c[s],"",c[s-2],c[s-4]);break;case 74:i.commit(c[s-2],"",c[s],c[s-4]);break;case 75:i.commit(c[s-4],c[s],c[s-2],"");break;case 76:i.commit(c[s-4],c[s-2],c[s],"");break;case 77:i.commit(c[s-2],c[s],c[s-4],"");break;case 78:i.commit(c[s],c[s-2],c[s-4],"");break;case 79:i.commit(c[s],c[s-4],c[s-2],"");break;case 80:i.commit(c[s-2],c[s-4],c[s],"");break;case 81:i.commit(c[s-4],c[s],i.commitType.NORMAL,c[s-2]);break;case 82:i.commit(c[s-4],c[s-2],i.commitType.NORMAL,c[s]);break;case 83:i.commit(c[s-2],c[s],i.commitType.NORMAL,c[s-4]);break;case 84:i.commit(c[s],c[s-2],i.commitType.NORMAL,c[s-4]);break;case 85:i.commit(c[s],c[s-4],i.commitType.NORMAL,c[s-2]);break;case 86:i.commit(c[s-2],c[s-4],i.commitType.NORMAL,c[s]);break;case 87:i.commit(c[s-6],c[s-4],c[s-2],c[s]);break;case 88:i.commit(c[s-6],c[s-4],c[s],c[s-2]);break;case 89:i.commit(c[s-6],c[s-2],c[s-4],c[s]);break;case 90:i.commit(c[s-6],c[s],c[s-4],c[s-2]);break;case 91:i.commit(c[s-6],c[s-2],c[s],c[s-4]);break;case 92:i.commit(c[s-6],c[s],c[s-2],c[s-4]);break;case 93:i.commit(c[s-4],c[s-6],c[s-2],c[s]);break;case 94:i.commit(c[s-4],c[s-6],c[s],c[s-2]);break;case 95:i.commit(c[s-2],c[s-6],c[s-4],c[s]);break;case 96:i.commit(c[s],c[s-6],c[s-4],c[s-2]);break;case 97:i.commit(c[s-2],c[s-6],c[s],c[s-4]);break;case 98:i.commit(c[s],c[s-6],c[s-2],c[s-4]);break;case 99:i.commit(c[s],c[s-4],c[s-2],c[s-6]);break;case 100:i.commit(c[s-2],c[s-4],c[s],c[s-6]);break;case 101:i.commit(c[s],c[s-2],c[s-4],c[s-6]);break;case 102:i.commit(c[s-2],c[s],c[s-4],c[s-6]);break;case 103:i.commit(c[s-4],c[s-2],c[s],c[s-6]);break;case 104:i.commit(c[s-4],c[s],c[s-2],c[s-6]);break;case 105:i.commit(c[s-2],c[s-4],c[s-6],c[s]);break;case 106:i.commit(c[s],c[s-4],c[s-6],c[s-2]);break;case 107:i.commit(c[s-2],c[s],c[s-6],c[s-4]);break;case 108:i.commit(c[s],c[s-2],c[s-6],c[s-4]);break;case 109:i.commit(c[s-4],c[s-2],c[s-6],c[s]);break;case 110:i.commit(c[s-4],c[s],c[s-6],c[s-2]);break;case 111:this.$="";break;case 112:this.$=c[s];break;case 113:this.$=i.commitType.NORMAL;break;case 114:this.$=i.commitType.REVERSE;break;case 115:this.$=i.commitType.HIGHLIGHT;break;case 118:i.parseDirective("%%{","open_directive");break;case 119:i.parseDirective(c[s],"type_directive");break;case 120:c[s]=c[s].trim().replace(/'/g,'"'),i.parseDirective(c[s],"arg_directive");break;case 121:i.parseDirective("}%%","close_directive","gitGraph")}},table:[{3:1,4:2,5:3,6:e,8:r,14:i,46:8,50:n,55:c},{1:[3]},{3:10,4:2,5:3,6:e,8:r,14:i,46:8,50:n,55:c},{3:11,4:2,5:3,6:e,8:r,14:i,46:8,50:n,55:c},{7:12,8:a,9:[1,13],10:[1,14],11:15,14:s},t(o,[2,124]),t(o,[2,125]),t(o,[2,126]),{47:17,51:[1,18]},{51:[2,118]},{1:[2,1]},{1:[2,2]},{8:[1,19]},{7:20,8:a,11:15,14:s},{9:[1,21]},t(l,[2,10],{12:22,13:[1,23]}),t(h,[2,9]),{9:[1,25],48:24,53:m},t([9,53],[2,119]),{1:[2,3]},{8:[1,27]},{7:28,8:a,11:15,14:s},{8:[2,7],14:[1,31],15:29,16:30,17:32,18:33,19:34,20:[1,35],22:[1,36],24:[1,37],25:[1,38],26:39,27:[1,40],29:[1,44],32:[1,43],37:[1,42],40:[1,41]},t(h,[2,8]),t(u,[2,116]),{49:45,52:[1,46]},t(u,[2,121]),{1:[2,4]},{8:[1,47]},t(l,[2,11]),{4:48,8:r,14:i,55:c},t(l,[2,13]),t(y,[2,14]),t(y,[2,15]),t(y,[2,16]),{21:[1,49]},{23:[1,50]},t(y,[2,19]),t(y,[2,20]),t(y,[2,21]),{28:51,34:p,54:g},t(y,[2,111],{41:54,33:[1,57],34:[1,59],35:[1,55],38:[1,56],42:[1,58]}),{28:60,34:p,54:g},{33:[1,61],35:[1,62]},{28:63,34:p,54:g},{48:64,53:m},{53:[2,120]},{1:[2,5]},t(l,[2,12]),t(y,[2,17]),t(y,[2,18]),t(y,[2,22]),t(b,[2,122]),t(b,[2,123]),t(y,[2,46]),{34:[1,65]},{39:66,43:d,44:f,45:k},{34:[1,70]},{34:[1,71]},t(y,[2,112]),t(y,[2,30],{33:[1,72],35:[1,74],38:[1,73]}),{34:[1,75]},{34:[1,76],36:[1,77]},t(y,[2,23],{30:[1,78]}),t(u,[2,117]),t(y,[2,47],{33:[1,80],38:[1,79],42:[1,81]}),t(y,[2,48],{33:[1,83],35:[1,82],42:[1,84]}),t(_,[2,113]),t(_,[2,114]),t(_,[2,115]),t(y,[2,51],{35:[1,85],38:[1,86],42:[1,87]}),t(y,[2,62],{33:[1,90],35:[1,88],38:[1,89]}),{34:[1,91]},{39:92,43:d,44:f,45:k},{34:[1,93]},t(y,[2,25],{35:[1,94]}),{33:[1,95]},{33:[1,96]},{31:[1,97]},{39:98,43:d,44:f,45:k},{34:[1,99]},{34:[1,100]},{34:[1,101]},{34:[1,102]},{34:[1,103]},{34:[1,104]},{39:105,43:d,44:f,45:k},{34:[1,106]},{34:[1,107]},{39:108,43:d,44:f,45:k},{34:[1,109]},t(y,[2,31],{35:[1,111],38:[1,110]}),t(y,[2,32],{33:[1,113],35:[1,112]}),t(y,[2,33],{33:[1,114],38:[1,115]}),{34:[1,116],36:[1,117]},{34:[1,118]},{34:[1,119]},t(y,[2,24]),t(y,[2,49],{33:[1,120],42:[1,121]}),t(y,[2,53],{38:[1,122],42:[1,123]}),t(y,[2,63],{33:[1,125],38:[1,124]}),t(y,[2,50],{33:[1,126],42:[1,127]}),t(y,[2,55],{35:[1,128],42:[1,129]}),t(y,[2,66],{33:[1,131],35:[1,130]}),t(y,[2,52],{38:[1,132],42:[1,133]}),t(y,[2,54],{35:[1,134],42:[1,135]}),t(y,[2,67],{35:[1,137],38:[1,136]}),t(y,[2,64],{33:[1,139],38:[1,138]}),t(y,[2,65],{33:[1,141],35:[1,140]}),t(y,[2,68],{35:[1,143],38:[1,142]}),{39:144,43:d,44:f,45:k},{34:[1,145]},{34:[1,146]},{34:[1,147]},{34:[1,148]},{39:149,43:d,44:f,45:k},t(y,[2,26]),t(y,[2,27]),t(y,[2,28]),t(y,[2,29]),{34:[1,150]},{34:[1,151]},{39:152,43:d,44:f,45:k},{34:[1,153]},{39:154,43:d,44:f,45:k},{34:[1,155]},{34:[1,156]},{34:[1,157]},{34:[1,158]},{34:[1,159]},{34:[1,160]},{34:[1,161]},{39:162,43:d,44:f,45:k},{34:[1,163]},{34:[1,164]},{34:[1,165]},{39:166,43:d,44:f,45:k},{34:[1,167]},{39:168,43:d,44:f,45:k},{34:[1,169]},{34:[1,170]},{34:[1,171]},{39:172,43:d,44:f,45:k},{34:[1,173]},t(y,[2,37],{35:[1,174]}),t(y,[2,38],{38:[1,175]}),t(y,[2,36],{33:[1,176]}),t(y,[2,39],{35:[1,177]}),t(y,[2,34],{38:[1,178]}),t(y,[2,35],{33:[1,179]}),t(y,[2,60],{42:[1,180]}),t(y,[2,73],{33:[1,181]}),t(y,[2,61],{42:[1,182]}),t(y,[2,84],{38:[1,183]}),t(y,[2,74],{33:[1,184]}),t(y,[2,83],{38:[1,185]}),t(y,[2,59],{42:[1,186]}),t(y,[2,72],{33:[1,187]}),t(y,[2,58],{42:[1,188]}),t(y,[2,78],{35:[1,189]}),t(y,[2,71],{33:[1,190]}),t(y,[2,77],{35:[1,191]}),t(y,[2,57],{42:[1,192]}),t(y,[2,85],{38:[1,193]}),t(y,[2,56],{42:[1,194]}),t(y,[2,79],{35:[1,195]}),t(y,[2,80],{35:[1,196]}),t(y,[2,86],{38:[1,197]}),t(y,[2,70],{33:[1,198]}),t(y,[2,81],{38:[1,199]}),t(y,[2,69],{33:[1,200]}),t(y,[2,75],{35:[1,201]}),t(y,[2,76],{35:[1,202]}),t(y,[2,82],{38:[1,203]}),{34:[1,204]},{39:205,43:d,44:f,45:k},{34:[1,206]},{34:[1,207]},{39:208,43:d,44:f,45:k},{34:[1,209]},{34:[1,210]},{34:[1,211]},{34:[1,212]},{39:213,43:d,44:f,45:k},{34:[1,214]},{39:215,43:d,44:f,45:k},{34:[1,216]},{34:[1,217]},{34:[1,218]},{34:[1,219]},{34:[1,220]},{34:[1,221]},{34:[1,222]},{39:223,43:d,44:f,45:k},{34:[1,224]},{34:[1,225]},{34:[1,226]},{39:227,43:d,44:f,45:k},{34:[1,228]},{39:229,43:d,44:f,45:k},{34:[1,230]},{34:[1,231]},{34:[1,232]},{39:233,43:d,44:f,45:k},t(y,[2,40]),t(y,[2,42]),t(y,[2,41]),t(y,[2,43]),t(y,[2,45]),t(y,[2,44]),t(y,[2,101]),t(y,[2,102]),t(y,[2,99]),t(y,[2,100]),t(y,[2,104]),t(y,[2,103]),t(y,[2,108]),t(y,[2,107]),t(y,[2,106]),t(y,[2,105]),t(y,[2,110]),t(y,[2,109]),t(y,[2,98]),t(y,[2,97]),t(y,[2,96]),t(y,[2,95]),t(y,[2,93]),t(y,[2,94]),t(y,[2,92]),t(y,[2,91]),t(y,[2,90]),t(y,[2,89]),t(y,[2,87]),t(y,[2,88])],defaultActions:{9:[2,118],10:[2,1],11:[2,2],19:[2,3],27:[2,4],46:[2,120],47:[2,5]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=this,r=[0],i=[],n=[null],c=[],a=this.table,s="",o=0,l=0,h=2,m=1,u=c.slice.call(arguments,1),y=Object.create(this.lexer),p={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);y.setInput(t,p.yy),p.yy.lexer=y,p.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var b=y.yylloc;c.push(b);var d=y.options&&y.options.ranges;function f(){var t;return"number"!=typeof(t=i.pop()||y.lex()||m)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var k,_,$,x,v,w,E,T,O={};;){if(_=r[r.length-1],this.defaultActions[_]?$=this.defaultActions[_]:(null==k&&(k=f()),$=a[_]&&a[_][k]),void 0===$||!$.length||!$[0]){var L="";for(v in T=[],a[_])this.terminals_[v]&&v>h&&T.push("'"+this.terminals_[v]+"'");L=y.showPosition?"Parse error on line "+(o+1)+":\n"+y.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(o+1)+": Unexpected "+(k==m?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(L,{text:y.match,token:this.terminals_[k]||k,line:y.yylineno,loc:b,expected:T})}if($[0]instanceof Array&&$.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+k);switch($[0]){case 1:r.push(k),n.push(y.yytext),c.push(y.yylloc),r.push($[1]),k=null,l=y.yyleng,s=y.yytext,o=y.yylineno,b=y.yylloc;break;case 2:if(w=this.productions_[$[1]][1],O.$=n[n.length-w],O._$={first_line:c[c.length-(w||1)].first_line,last_line:c[c.length-1].last_line,first_column:c[c.length-(w||1)].first_column,last_column:c[c.length-1].last_column},d&&(O._$.range=[c[c.length-(w||1)].range[0],c[c.length-1].range[1]]),void 0!==(x=this.performAction.apply(O,[s,l,o,p.yy,$[1],n,c].concat(u))))return x;w&&(r=r.slice(0,-1*w*2),n=n.slice(0,-1*w),c=c.slice(0,-1*w)),r.push(this.productions_[$[1]][0]),n.push(O.$),c.push(O._$),E=a[r[r.length-2]][r[r.length-1]],r.push(E);break;case 3:return!0}}return!0}},x={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,r=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 i=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),r.length-1&&(this.yylineno-=r.length-1);var n=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:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var r,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var c in n)this[c]=n[c];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),c=0;ce[0].length)){if(e=r,i=c,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,n[c])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("open_directive"),50;case 1:return this.begin("type_directive"),51;case 2:return this.popState(),this.begin("arg_directive"),9;case 3:return this.popState(),this.popState(),53;case 4:return 52;case 5:return this.begin("acc_title"),20;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),22;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:return 14;case 13:case 14:break;case 15:return 6;case 16:return 40;case 17:return 33;case 18:return 38;case 19:return 42;case 20:return 43;case 21:return 44;case 22:return 45;case 23:return 35;case 24:return 29;case 25:return 30;case 26:return 37;case 27:return 32;case 28:return 27;case 29:case 30:return 10;case 31:return 9;case 32:return"CARET";case 33:this.begin("options");break;case 34:this.popState();break;case 35:return 13;case 36:return 36;case 37:this.begin("string");break;case 38:this.popState();break;case 39:return 34;case 40:return 31;case 41:return 54;case 42:return 8}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit(?=\s|$))/i,/^(?:id:)/i,/^(?:type:)/i,/^(?:msg:)/i,/^(?:NORMAL\b)/i,/^(?:REVERSE\b)/i,/^(?:HIGHLIGHT\b)/i,/^(?:tag:)/i,/^(?:branch(?=\s|$))/i,/^(?:order:)/i,/^(?:merge(?=\s|$))/i,/^(?:cherry-pick(?=\s|$))/i,/^(?:checkout(?=\s|$))/i,/^(?:LR\b)/i,/^(?:BT\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:[ \r\n\t]+end\b)/i,/^(?:[\s\S]+(?=[ \r\n\t]+end))/i,/^(?:["]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[0-9]+(?=\s|$))/i,/^(?:\w([-\./\w]*[-\w])?)/i,/^(?:$)/i,/^(?:\s+)/i],conditions:{acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},options:{rules:[34,35],inclusive:!1},string:{rules:[38,39],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,36,37,40,41,42,43],inclusive:!0}}};function v(){this.yy={}}return $.lexer=x,v.prototype=$,$.Parser=v,new v}();v.parser=v;const w=v;let E=s().gitGraph.mainBranchName,T=s().gitGraph.mainBranchOrder,O={},L=null,M={};M[E]={name:E,order:T};let I={};I[E]=L;let A=E,R="LR",S=0;function C(){return d({length:7})}let P={};const N=function(t){if(t=b.sanitizeText(t,s()),void 0===I[t]){let e=new Error('Trying to checkout branch which is not yet created. (Help try using "branch '+t+'")');throw e.hash={text:"checkout "+t,token:"checkout "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"branch '+t+'"']},e}{A=t;const e=I[A];L=O[e]}};function G(t,e,r){const i=t.indexOf(e);-1===i?t.push(r):t.splice(i,1,r)}function D(t){const e=t.reduce(((t,e)=>t.seq>e.seq?t:e),t[0]);let r="";t.forEach((function(t){r+=t===e?"\t*":"\t|"}));const i=[r,e.id,e.seq];for(let n in I)I[n]===e.id&&i.push(n);if(g.debug(i.join(" ")),e.parents&&2==e.parents.length){const r=O[e.parents[0]];G(t,e,r),t.push(O[e.parents[1]])}else{if(0==e.parents.length)return;{const r=O[e.parents];G(t,e,r)}}D(t=function(t,e){const r=Object.create(null);return t.reduce(((t,i)=>{const n=e(i);return r[n]||(r[n]=!0,t.push(i)),t}),[])}(t,(t=>t.id)))}const B=function(){const t=Object.keys(O).map((function(t){return O[t]}));return t.forEach((function(t){g.debug(t.id)})),t.sort(((t,e)=>t.seq-e.seq)),t},H={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4};let j={};const z=0,q=1,F=2,Y=3,U=4;let K={},V={},W=[],J=0;const Q=(t,e,r)=>{const i=k().gitGraph,n=t.append("g").attr("class","commit-bullets"),c=t.append("g").attr("class","commit-labels");let a=0;Object.keys(e).sort(((t,r)=>e[t].seq-e[r].seq)).forEach((t=>{const s=e[t],o=K[s.branch].pos,l=a+10;if(r){let t,e=void 0!==s.customType&&""!==s.customType?s.customType:s.type;switch(e){case z:t="commit-normal";break;case q:t="commit-reverse";break;case F:t="commit-highlight";break;case Y:t="commit-merge";break;case U:t="commit-cherry-pick";break;default:t="commit-normal"}if(e===F){const e=n.append("rect");e.attr("x",l-10),e.attr("y",o-10),e.attr("height",20),e.attr("width",20),e.attr("class",`commit ${s.id} commit-highlight${K[s.branch].index%8} ${t}-outer`),n.append("rect").attr("x",l-6).attr("y",o-6).attr("height",12).attr("width",12).attr("class",`commit ${s.id} commit${K[s.branch].index%8} ${t}-inner`)}else if(e===U)n.append("circle").attr("cx",l).attr("cy",o).attr("r",10).attr("class",`commit ${s.id} ${t}`),n.append("circle").attr("cx",l-3).attr("cy",o+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${s.id} ${t}`),n.append("circle").attr("cx",l+3).attr("cy",o+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${s.id} ${t}`),n.append("line").attr("x1",l+3).attr("y1",o+1).attr("x2",l).attr("y2",o-5).attr("stroke","#fff").attr("class",`commit ${s.id} ${t}`),n.append("line").attr("x1",l-3).attr("y1",o+1).attr("x2",l).attr("y2",o-5).attr("stroke","#fff").attr("class",`commit ${s.id} ${t}`);else{const r=n.append("circle");if(r.attr("cx",l),r.attr("cy",o),r.attr("r",s.type===Y?9:10),r.attr("class",`commit ${s.id} commit${K[s.branch].index%8}`),e===Y){const e=n.append("circle");e.attr("cx",l),e.attr("cy",o),e.attr("r",6),e.attr("class",`commit ${t} ${s.id} commit${K[s.branch].index%8}`)}if(e===q){n.append("path").attr("d",`M ${l-5},${o-5}L${l+5},${o+5}M${l-5},${o+5}L${l+5},${o-5}`).attr("class",`commit ${t} ${s.id} commit${K[s.branch].index%8}`)}}}if(V[s.id]={x:a+10,y:o},r){const t=4,e=2;if(s.type!==U&&(s.customId&&s.type===Y||s.type!==Y)&&i.showCommitLabel){const t=c.append("g"),r=t.insert("rect").attr("class","commit-label-bkg"),n=t.append("text").attr("x",a).attr("y",o+25).attr("class","commit-label").text(s.id);let l=n.node().getBBox();if(r.attr("x",a+10-l.width/2-e).attr("y",o+13.5).attr("width",l.width+2*e).attr("height",l.height+2*e),n.attr("x",a+10-l.width/2),i.rotateCommitLabel){let e=-7.5-(l.width+10)/25*9.5,r=10+l.width/25*8.5;t.attr("transform","translate("+e+", "+r+") rotate(-45, "+a+", "+o+")")}}if(s.tag){const r=c.insert("polygon"),i=c.append("circle"),n=c.append("text").attr("y",o-16).attr("class","tag-label").text(s.tag);let l=n.node().getBBox();n.attr("x",a+10-l.width/2);const h=l.height/2,m=o-19.2;r.attr("class","tag-label-bkg").attr("points",`\n ${a-l.width/2-t/2},${m+e}\n ${a-l.width/2-t/2},${m-e}\n ${a+10-l.width/2-t},${m-h-e}\n ${a+10+l.width/2+t},${m-h-e}\n ${a+10+l.width/2+t},${m+h+e}\n ${a+10-l.width/2-t},${m+h+e}`),i.attr("cx",a-l.width/2+t/2).attr("cy",m).attr("r",1.5).attr("class","tag-hole")}}a+=50,a>J&&(J=a)}))},X=(t,e,r=0)=>{const i=t+Math.abs(t-e)/2;if(r>5)return i;if(W.every((t=>Math.abs(t-i)>=10)))return W.push(i),i;const n=Math.abs(t-e);return X(t,e-n/5,r+1)},Z=(t,e,r,i)=>{const n=V[e.id],c=V[r.id],a=((t,e,r)=>Object.keys(r).filter((i=>r[i].branch===e.branch&&r[i].seq>t.seq&&r[i].seq0)(e,r,i);let s,o="",l="",h=0,m=0,u=K[r.branch].index;if(a){o="A 10 10, 0, 0, 0,",l="A 10 10, 0, 0, 1,",h=10,m=10,u=K[r.branch].index;const t=n.yc.y&&(o="A 20 20, 0, 0, 0,",h=20,m=20,u=K[e.branch].index,s=`M ${n.x} ${n.y} L ${c.x-h} ${n.y} ${o} ${c.x} ${n.y-m} L ${c.x} ${c.y}`),n.y===c.y&&(u=K[e.branch].index,s=`M ${n.x} ${n.y} L ${n.x} ${c.y-h} ${o} ${n.x+m} ${c.y} L ${c.x} ${c.y}`);t.append("path").attr("d",s).attr("class","arrow arrow"+u%8)},tt=(t,e)=>{const r=k().gitGraph,i=t.append("g");e.forEach(((t,e)=>{const n=e%8,c=K[t.name].pos,a=i.append("line");a.attr("x1",0),a.attr("y1",c),a.attr("x2",J),a.attr("y2",c),a.attr("class","branch branch"+n),W.push(c);const s=(t=>{const e=document.createElementNS("http://www.w3.org/2000/svg","text");let r=[];r="string"==typeof t?t.split(/\\n|\n|/gi):Array.isArray(t)?t:[];for(const i of r){const t=document.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","0"),t.setAttribute("class","row"),t.textContent=i.trim(),e.appendChild(t)}return e})(t.name),o=i.insert("rect"),l=i.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+n);l.node().appendChild(s);let h=s.getBBox();o.attr("class","branchLabelBkg label"+n).attr("rx",4).attr("ry",4).attr("x",-h.width-4-(!0===r.rotateCommitLabel?30:0)).attr("y",-h.height/2+8).attr("width",h.width+18).attr("height",h.height+4),l.attr("transform","translate("+(-h.width-14-(!0===r.rotateCommitLabel?30:0))+", "+(c-h.height/2-1)+")"),o.attr("transform","translate(-19, "+(c-h.height/2)+")")}))},et={parser:w,db:{parseDirective:function(t,e,r){p.parseDirective(this,t,e,r)},getConfig:()=>s().gitGraph,setDirection:function(t){R=t},setOptions:function(t){g.debug("options str",t),t=(t=t&&t.trim())||"{}";try{P=JSON.parse(t)}catch(e){g.error("error while parsing gitGraph options",e.message)}},getOptions:function(){return P},commit:function(t,e,r,i){g.debug("Entering commit:",t,e,r,i),e=b.sanitizeText(e,s()),t=b.sanitizeText(t,s()),i=b.sanitizeText(i,s());const n={id:e||S+"-"+C(),message:t,seq:S++,type:r||H.NORMAL,tag:i||"",parents:null==L?[]:[L.id],branch:A};L=n,O[n.id]=n,I[A]=n.id,g.debug("in pushCommit "+n.id)},branch:function(t,e){if(t=b.sanitizeText(t,s()),void 0!==I[t]){let e=new Error('Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout '+t+'")');throw e.hash={text:"branch "+t,token:"branch "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"checkout '+t+'"']},e}I[t]=null!=L?L.id:null,M[t]={name:t,order:e?parseInt(e,10):null},N(t),g.debug("in createBranch")},merge:function(t,e,r,i){t=b.sanitizeText(t,s()),e=b.sanitizeText(e,s());const n=O[I[A]],c=O[I[t]];if(A===t){let e=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(void 0===n||!n){let e=new Error('Incorrect usage of "merge". Current branch ('+A+")has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["commit"]},e}if(void 0===I[t]){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") does not exist");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch "+t]},e}if(void 0===c||!c){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"commit"']},e}if(n===c){let e=new Error('Incorrect usage of "merge". Both branches have same head');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(e&&void 0!==O[e]){let n=new Error('Incorrect usage of "merge". Commit with id:'+e+" already exists, use different custom Id");throw n.hash={text:"merge "+t+e+r+i,token:"merge "+t+e+r+i,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["merge "+t+" "+e+"_UNIQUE "+r+" "+i]},n}const a={id:e||S+"-"+C(),message:"merged branch "+t+" into "+A,seq:S++,parents:[null==L?null:L.id,I[t]],branch:A,type:H.MERGE,customType:r,customId:!!e,tag:i||""};L=a,O[a.id]=a,I[A]=a.id,g.debug(I),g.debug("in mergeBranch")},cherryPick:function(t,e,r){if(g.debug("Entering cherryPick:",t,e,r),t=b.sanitizeText(t,s()),e=b.sanitizeText(e,s()),r=b.sanitizeText(r,s()),!t||void 0===O[t]){let r=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}let i=O[t],n=i.branch;if(i.type===H.MERGE){let r=new Error('Incorrect usage of "cherryPick". Source commit should not be a merge commit');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}if(!e||void 0===O[e]){if(n===A){let r=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const c=O[I[A]];if(void 0===c||!c){let r=new Error('Incorrect usage of "cherry-pick". Current branch ('+A+")has no commits");throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const a={id:S+"-"+C(),message:"cherry-picked "+i+" into "+A,seq:S++,parents:[null==L?null:L.id,i.id],branch:A,type:H.CHERRY_PICK,tag:null!=r?r:"cherry-pick:"+i.id};L=a,O[a.id]=a,I[A]=a.id,g.debug(I),g.debug("in cherryPick")}},checkout:N,prettyPrint:function(){g.debug(O);D([B()[0]])},clear:function(){O={},L=null;let t=s().gitGraph.mainBranchName,e=s().gitGraph.mainBranchOrder;I={},I[t]=null,M={},M[t]={name:t,order:e},A=t,S=0,f()},getBranchesAsObjArray:function(){return Object.values(M).map(((t,s)=>{return null!==t.order?t:(o=((t,e)=>{for(var r in e||(e={}))n.call(e,r)&&a(t,r,e[r]);if(i)for(var r of i(e))c.call(e,r)&&a(t,r,e[r]);return t})({},t),l={order:parseFloat(`0.${s}`,10)},e(o,r(l)));var o,l})).sort(((t,e)=>t.order-e.order)).map((({name:t})=>({name:t})))},getBranches:function(){return I},getCommits:function(){return O},getCommitsArray:B,getCurrentBranch:function(){return A},getDirection:function(){return R},getHead:function(){return L},setAccTitle:o,getAccTitle:l,getAccDescription:h,setAccDescription:m,setDiagramTitle:u,getDiagramTitle:y,commitType:H},renderer:{draw:function(t,e,r,i){var n;K={},V={},j={},J=0,W=[];const c=k(),a=c.gitGraph;g.debug("in gitgraph renderer",t+"\n","id:",e,r),j=i.db.getCommits();const s=i.db.getBranchesAsObjArray();let o=0;s.forEach(((t,e)=>{K[t.name]={pos:o,index:e},o+=50+(a.rotateCommitLabel?40:0)}));const l=_(`[id="${e}"]`);Q(l,j,!1),a.showBranches&&tt(l,s),((t,e)=>{const r=t.append("g").attr("class","commit-arrows");Object.keys(e).forEach((t=>{const i=e[t];i.parents&&i.parents.length>0&&i.parents.forEach((t=>{Z(r,e[t],i,e)}))}))})(l,j),Q(l,j,!0),$.insertTitle(l,"gitTitleText",a.titleTopMargin,i.db.getDiagramTitle()),x(void 0,l,a.diagramPadding,null!=(n=a.useMaxWidth)?n:c.useMaxWidth)}},styles:t=>`\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n ${[0,1,2,3,4,5,6,7].map((e=>`\n .branch-label${e} { fill: ${t["gitBranchLabel"+e]}; }\n .commit${e} { stroke: ${t["git"+e]}; fill: ${t["git"+e]}; }\n .commit-highlight${e} { stroke: ${t["gitInv"+e]}; fill: ${t["gitInv"+e]}; }\n .label${e} { fill: ${t["git"+e]}; }\n .arrow${e} { stroke: ${t["git"+e]}; }\n `)).join("\n")}\n\n .branch {\n stroke-width: 1;\n stroke: ${t.lineColor};\n stroke-dasharray: 2;\n }\n .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};}\n .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; }\n .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};}\n .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; }\n .tag-hole { fill: ${t.textColor}; }\n\n .commit-merge {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n .commit-reverse {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n stroke-width: 3;\n }\n .commit-highlight-outer {\n }\n .commit-highlight-inner {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n\n .arrow { stroke-width: 8; stroke-linecap: round; fill: none}\n .gitTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n`};export{et as diagram}; +var t=Object.defineProperty,e=Object.defineProperties,r=Object.getOwnPropertyDescriptors,i=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,c=Object.prototype.propertyIsEnumerable,a=(e,r,i)=>r in e?t(e,r,{enumerable:!0,configurable:!0,writable:!0,value:i}):e[r]=i;"undefined"!=typeof require&&require;import{c as s,s as o,g as l,a as h,b as m,v as u,x as y,m as p,l as g,j as b,a9 as d,z as f,aa as k,h as _,y as $,ab as x}from"./mermaid.core.3a590193.js";var v=function(){var t=function(t,e,r,i){for(r=r||{},i=t.length;i--;r[t[i]]=e);return r},e=[1,4],r=[1,7],i=[1,5],n=[1,9],c=[1,6],a=[2,6],s=[1,16],o=[6,8,14,20,22,24,25,27,29,32,37,40,50,55],l=[8,14,20,22,24,25,27,29,32,37,40],h=[8,13,14,20,22,24,25,27,29,32,37,40],m=[1,26],u=[6,8,14,50,55],y=[8,14,55],p=[1,53],g=[1,52],b=[8,14,30,33,35,38,55],d=[1,67],f=[1,68],k=[1,69],_=[8,14,33,35,42,55],$={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,GG:6,document:7,EOF:8,":":9,DIR:10,options:11,body:12,OPT:13,NL:14,line:15,statement:16,commitStatement:17,mergeStatement:18,cherryPickStatement:19,acc_title:20,acc_title_value:21,acc_descr:22,acc_descr_value:23,acc_descr_multiline_value:24,section:25,branchStatement:26,CHECKOUT:27,ref:28,BRANCH:29,ORDER:30,NUM:31,CHERRY_PICK:32,COMMIT_ID:33,STR: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,openDirective:46,typeDirective:47,closeDirective:48,argDirective:49,open_directive:50,type_directive:51,arg_directive:52,close_directive:53,ID:54,";":55,$accept:0,$end:1},terminals_:{2:"error",6:"GG",8:"EOF",9:":",10:"DIR",13:"OPT",14:"NL",20:"acc_title",21:"acc_title_value",22:"acc_descr",23:"acc_descr_value",24:"acc_descr_multiline_value",25:"section",27:"CHECKOUT",29:"BRANCH",30:"ORDER",31:"NUM",32:"CHERRY_PICK",33:"COMMIT_ID",34:"STR",35:"COMMIT_TAG",36:"EMPTYSTR",37:"MERGE",38:"COMMIT_TYPE",40:"COMMIT",42:"COMMIT_MSG",43:"NORMAL",44:"REVERSE",45:"HIGHLIGHT",50:"open_directive",51:"type_directive",52:"arg_directive",53:"close_directive",54:"ID",55:";"},productions_:[0,[3,2],[3,2],[3,3],[3,4],[3,5],[7,0],[7,2],[11,2],[11,1],[12,0],[12,2],[15,2],[15,1],[16,1],[16,1],[16,1],[16,2],[16,2],[16,1],[16,1],[16,1],[16,2],[26,2],[26,4],[19,3],[19,5],[19,5],[19,5],[19,5],[18,2],[18,4],[18,4],[18,4],[18,6],[18,6],[18,6],[18,6],[18,6],[18,6],[18,8],[18,8],[18,8],[18,8],[18,8],[18,8],[17,2],[17,3],[17,3],[17,5],[17,5],[17,3],[17,5],[17,5],[17,5],[17,5],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,3],[17,5],[17,5],[17,5],[17,5],[17,5],[17,5],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,7],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[17,9],[41,0],[41,1],[39,1],[39,1],[39,1],[5,3],[5,5],[46,1],[47,1],[49,1],[48,1],[28,1],[28,1],[4,1],[4,1],[4,1]],performAction:function(t,e,r,i,n,c,a){var s=c.length-1;switch(n){case 3:return c[s];case 4:return c[s-1];case 5:return i.setDirection(c[s-3]),c[s-1];case 7:i.setOptions(c[s-1]),this.$=c[s];break;case 8:c[s-1]+=c[s],this.$=c[s-1];break;case 10:this.$=[];break;case 11:c[s-1].push(c[s]),this.$=c[s-1];break;case 12:this.$=c[s-1];break;case 17:this.$=c[s].trim(),i.setAccTitle(this.$);break;case 18:case 19:this.$=c[s].trim(),i.setAccDescription(this.$);break;case 20:i.addSection(c[s].substr(8)),this.$=c[s].substr(8);break;case 22:i.checkout(c[s]);break;case 23:i.branch(c[s]);break;case 24:i.branch(c[s-2],c[s]);break;case 25:i.cherryPick(c[s],"",void 0);break;case 26:i.cherryPick(c[s-2],"",c[s]);break;case 27:case 29:i.cherryPick(c[s-2],"","");break;case 28:i.cherryPick(c[s],"",c[s-2]);break;case 30:i.merge(c[s],"","","");break;case 31:i.merge(c[s-2],c[s],"","");break;case 32:i.merge(c[s-2],"",c[s],"");break;case 33:i.merge(c[s-2],"","",c[s]);break;case 34:i.merge(c[s-4],c[s],"",c[s-2]);break;case 35:i.merge(c[s-4],"",c[s],c[s-2]);break;case 36:i.merge(c[s-4],"",c[s-2],c[s]);break;case 37:i.merge(c[s-4],c[s-2],c[s],"");break;case 38:i.merge(c[s-4],c[s-2],"",c[s]);break;case 39:i.merge(c[s-4],c[s],c[s-2],"");break;case 40:i.merge(c[s-6],c[s-4],c[s-2],c[s]);break;case 41:i.merge(c[s-6],c[s],c[s-4],c[s-2]);break;case 42:i.merge(c[s-6],c[s-4],c[s],c[s-2]);break;case 43:i.merge(c[s-6],c[s-2],c[s-4],c[s]);break;case 44:i.merge(c[s-6],c[s],c[s-2],c[s-4]);break;case 45:i.merge(c[s-6],c[s-2],c[s],c[s-4]);break;case 46:i.commit(c[s]);break;case 47:i.commit("","",i.commitType.NORMAL,c[s]);break;case 48:i.commit("","",c[s],"");break;case 49:i.commit("","",c[s],c[s-2]);break;case 50:i.commit("","",c[s-2],c[s]);break;case 51:i.commit("",c[s],i.commitType.NORMAL,"");break;case 52:i.commit("",c[s-2],i.commitType.NORMAL,c[s]);break;case 53:i.commit("",c[s],i.commitType.NORMAL,c[s-2]);break;case 54:i.commit("",c[s-2],c[s],"");break;case 55:i.commit("",c[s],c[s-2],"");break;case 56:i.commit("",c[s-4],c[s-2],c[s]);break;case 57:i.commit("",c[s-4],c[s],c[s-2]);break;case 58:i.commit("",c[s-2],c[s-4],c[s]);break;case 59:i.commit("",c[s],c[s-4],c[s-2]);break;case 60:i.commit("",c[s],c[s-2],c[s-4]);break;case 61:i.commit("",c[s-2],c[s],c[s-4]);break;case 62:i.commit(c[s],"",i.commitType.NORMAL,"");break;case 63:i.commit(c[s],"",i.commitType.NORMAL,c[s-2]);break;case 64:i.commit(c[s-2],"",i.commitType.NORMAL,c[s]);break;case 65:i.commit(c[s-2],"",c[s],"");break;case 66:i.commit(c[s],"",c[s-2],"");break;case 67:i.commit(c[s],c[s-2],i.commitType.NORMAL,"");break;case 68:i.commit(c[s-2],c[s],i.commitType.NORMAL,"");break;case 69:i.commit(c[s-4],"",c[s-2],c[s]);break;case 70:i.commit(c[s-4],"",c[s],c[s-2]);break;case 71:i.commit(c[s-2],"",c[s-4],c[s]);break;case 72:i.commit(c[s],"",c[s-4],c[s-2]);break;case 73:i.commit(c[s],"",c[s-2],c[s-4]);break;case 74:i.commit(c[s-2],"",c[s],c[s-4]);break;case 75:i.commit(c[s-4],c[s],c[s-2],"");break;case 76:i.commit(c[s-4],c[s-2],c[s],"");break;case 77:i.commit(c[s-2],c[s],c[s-4],"");break;case 78:i.commit(c[s],c[s-2],c[s-4],"");break;case 79:i.commit(c[s],c[s-4],c[s-2],"");break;case 80:i.commit(c[s-2],c[s-4],c[s],"");break;case 81:i.commit(c[s-4],c[s],i.commitType.NORMAL,c[s-2]);break;case 82:i.commit(c[s-4],c[s-2],i.commitType.NORMAL,c[s]);break;case 83:i.commit(c[s-2],c[s],i.commitType.NORMAL,c[s-4]);break;case 84:i.commit(c[s],c[s-2],i.commitType.NORMAL,c[s-4]);break;case 85:i.commit(c[s],c[s-4],i.commitType.NORMAL,c[s-2]);break;case 86:i.commit(c[s-2],c[s-4],i.commitType.NORMAL,c[s]);break;case 87:i.commit(c[s-6],c[s-4],c[s-2],c[s]);break;case 88:i.commit(c[s-6],c[s-4],c[s],c[s-2]);break;case 89:i.commit(c[s-6],c[s-2],c[s-4],c[s]);break;case 90:i.commit(c[s-6],c[s],c[s-4],c[s-2]);break;case 91:i.commit(c[s-6],c[s-2],c[s],c[s-4]);break;case 92:i.commit(c[s-6],c[s],c[s-2],c[s-4]);break;case 93:i.commit(c[s-4],c[s-6],c[s-2],c[s]);break;case 94:i.commit(c[s-4],c[s-6],c[s],c[s-2]);break;case 95:i.commit(c[s-2],c[s-6],c[s-4],c[s]);break;case 96:i.commit(c[s],c[s-6],c[s-4],c[s-2]);break;case 97:i.commit(c[s-2],c[s-6],c[s],c[s-4]);break;case 98:i.commit(c[s],c[s-6],c[s-2],c[s-4]);break;case 99:i.commit(c[s],c[s-4],c[s-2],c[s-6]);break;case 100:i.commit(c[s-2],c[s-4],c[s],c[s-6]);break;case 101:i.commit(c[s],c[s-2],c[s-4],c[s-6]);break;case 102:i.commit(c[s-2],c[s],c[s-4],c[s-6]);break;case 103:i.commit(c[s-4],c[s-2],c[s],c[s-6]);break;case 104:i.commit(c[s-4],c[s],c[s-2],c[s-6]);break;case 105:i.commit(c[s-2],c[s-4],c[s-6],c[s]);break;case 106:i.commit(c[s],c[s-4],c[s-6],c[s-2]);break;case 107:i.commit(c[s-2],c[s],c[s-6],c[s-4]);break;case 108:i.commit(c[s],c[s-2],c[s-6],c[s-4]);break;case 109:i.commit(c[s-4],c[s-2],c[s-6],c[s]);break;case 110:i.commit(c[s-4],c[s],c[s-6],c[s-2]);break;case 111:this.$="";break;case 112:this.$=c[s];break;case 113:this.$=i.commitType.NORMAL;break;case 114:this.$=i.commitType.REVERSE;break;case 115:this.$=i.commitType.HIGHLIGHT;break;case 118:i.parseDirective("%%{","open_directive");break;case 119:i.parseDirective(c[s],"type_directive");break;case 120:c[s]=c[s].trim().replace(/'/g,'"'),i.parseDirective(c[s],"arg_directive");break;case 121:i.parseDirective("}%%","close_directive","gitGraph")}},table:[{3:1,4:2,5:3,6:e,8:r,14:i,46:8,50:n,55:c},{1:[3]},{3:10,4:2,5:3,6:e,8:r,14:i,46:8,50:n,55:c},{3:11,4:2,5:3,6:e,8:r,14:i,46:8,50:n,55:c},{7:12,8:a,9:[1,13],10:[1,14],11:15,14:s},t(o,[2,124]),t(o,[2,125]),t(o,[2,126]),{47:17,51:[1,18]},{51:[2,118]},{1:[2,1]},{1:[2,2]},{8:[1,19]},{7:20,8:a,11:15,14:s},{9:[1,21]},t(l,[2,10],{12:22,13:[1,23]}),t(h,[2,9]),{9:[1,25],48:24,53:m},t([9,53],[2,119]),{1:[2,3]},{8:[1,27]},{7:28,8:a,11:15,14:s},{8:[2,7],14:[1,31],15:29,16:30,17:32,18:33,19:34,20:[1,35],22:[1,36],24:[1,37],25:[1,38],26:39,27:[1,40],29:[1,44],32:[1,43],37:[1,42],40:[1,41]},t(h,[2,8]),t(u,[2,116]),{49:45,52:[1,46]},t(u,[2,121]),{1:[2,4]},{8:[1,47]},t(l,[2,11]),{4:48,8:r,14:i,55:c},t(l,[2,13]),t(y,[2,14]),t(y,[2,15]),t(y,[2,16]),{21:[1,49]},{23:[1,50]},t(y,[2,19]),t(y,[2,20]),t(y,[2,21]),{28:51,34:p,54:g},t(y,[2,111],{41:54,33:[1,57],34:[1,59],35:[1,55],38:[1,56],42:[1,58]}),{28:60,34:p,54:g},{33:[1,61],35:[1,62]},{28:63,34:p,54:g},{48:64,53:m},{53:[2,120]},{1:[2,5]},t(l,[2,12]),t(y,[2,17]),t(y,[2,18]),t(y,[2,22]),t(b,[2,122]),t(b,[2,123]),t(y,[2,46]),{34:[1,65]},{39:66,43:d,44:f,45:k},{34:[1,70]},{34:[1,71]},t(y,[2,112]),t(y,[2,30],{33:[1,72],35:[1,74],38:[1,73]}),{34:[1,75]},{34:[1,76],36:[1,77]},t(y,[2,23],{30:[1,78]}),t(u,[2,117]),t(y,[2,47],{33:[1,80],38:[1,79],42:[1,81]}),t(y,[2,48],{33:[1,83],35:[1,82],42:[1,84]}),t(_,[2,113]),t(_,[2,114]),t(_,[2,115]),t(y,[2,51],{35:[1,85],38:[1,86],42:[1,87]}),t(y,[2,62],{33:[1,90],35:[1,88],38:[1,89]}),{34:[1,91]},{39:92,43:d,44:f,45:k},{34:[1,93]},t(y,[2,25],{35:[1,94]}),{33:[1,95]},{33:[1,96]},{31:[1,97]},{39:98,43:d,44:f,45:k},{34:[1,99]},{34:[1,100]},{34:[1,101]},{34:[1,102]},{34:[1,103]},{34:[1,104]},{39:105,43:d,44:f,45:k},{34:[1,106]},{34:[1,107]},{39:108,43:d,44:f,45:k},{34:[1,109]},t(y,[2,31],{35:[1,111],38:[1,110]}),t(y,[2,32],{33:[1,113],35:[1,112]}),t(y,[2,33],{33:[1,114],38:[1,115]}),{34:[1,116],36:[1,117]},{34:[1,118]},{34:[1,119]},t(y,[2,24]),t(y,[2,49],{33:[1,120],42:[1,121]}),t(y,[2,53],{38:[1,122],42:[1,123]}),t(y,[2,63],{33:[1,125],38:[1,124]}),t(y,[2,50],{33:[1,126],42:[1,127]}),t(y,[2,55],{35:[1,128],42:[1,129]}),t(y,[2,66],{33:[1,131],35:[1,130]}),t(y,[2,52],{38:[1,132],42:[1,133]}),t(y,[2,54],{35:[1,134],42:[1,135]}),t(y,[2,67],{35:[1,137],38:[1,136]}),t(y,[2,64],{33:[1,139],38:[1,138]}),t(y,[2,65],{33:[1,141],35:[1,140]}),t(y,[2,68],{35:[1,143],38:[1,142]}),{39:144,43:d,44:f,45:k},{34:[1,145]},{34:[1,146]},{34:[1,147]},{34:[1,148]},{39:149,43:d,44:f,45:k},t(y,[2,26]),t(y,[2,27]),t(y,[2,28]),t(y,[2,29]),{34:[1,150]},{34:[1,151]},{39:152,43:d,44:f,45:k},{34:[1,153]},{39:154,43:d,44:f,45:k},{34:[1,155]},{34:[1,156]},{34:[1,157]},{34:[1,158]},{34:[1,159]},{34:[1,160]},{34:[1,161]},{39:162,43:d,44:f,45:k},{34:[1,163]},{34:[1,164]},{34:[1,165]},{39:166,43:d,44:f,45:k},{34:[1,167]},{39:168,43:d,44:f,45:k},{34:[1,169]},{34:[1,170]},{34:[1,171]},{39:172,43:d,44:f,45:k},{34:[1,173]},t(y,[2,37],{35:[1,174]}),t(y,[2,38],{38:[1,175]}),t(y,[2,36],{33:[1,176]}),t(y,[2,39],{35:[1,177]}),t(y,[2,34],{38:[1,178]}),t(y,[2,35],{33:[1,179]}),t(y,[2,60],{42:[1,180]}),t(y,[2,73],{33:[1,181]}),t(y,[2,61],{42:[1,182]}),t(y,[2,84],{38:[1,183]}),t(y,[2,74],{33:[1,184]}),t(y,[2,83],{38:[1,185]}),t(y,[2,59],{42:[1,186]}),t(y,[2,72],{33:[1,187]}),t(y,[2,58],{42:[1,188]}),t(y,[2,78],{35:[1,189]}),t(y,[2,71],{33:[1,190]}),t(y,[2,77],{35:[1,191]}),t(y,[2,57],{42:[1,192]}),t(y,[2,85],{38:[1,193]}),t(y,[2,56],{42:[1,194]}),t(y,[2,79],{35:[1,195]}),t(y,[2,80],{35:[1,196]}),t(y,[2,86],{38:[1,197]}),t(y,[2,70],{33:[1,198]}),t(y,[2,81],{38:[1,199]}),t(y,[2,69],{33:[1,200]}),t(y,[2,75],{35:[1,201]}),t(y,[2,76],{35:[1,202]}),t(y,[2,82],{38:[1,203]}),{34:[1,204]},{39:205,43:d,44:f,45:k},{34:[1,206]},{34:[1,207]},{39:208,43:d,44:f,45:k},{34:[1,209]},{34:[1,210]},{34:[1,211]},{34:[1,212]},{39:213,43:d,44:f,45:k},{34:[1,214]},{39:215,43:d,44:f,45:k},{34:[1,216]},{34:[1,217]},{34:[1,218]},{34:[1,219]},{34:[1,220]},{34:[1,221]},{34:[1,222]},{39:223,43:d,44:f,45:k},{34:[1,224]},{34:[1,225]},{34:[1,226]},{39:227,43:d,44:f,45:k},{34:[1,228]},{39:229,43:d,44:f,45:k},{34:[1,230]},{34:[1,231]},{34:[1,232]},{39:233,43:d,44:f,45:k},t(y,[2,40]),t(y,[2,42]),t(y,[2,41]),t(y,[2,43]),t(y,[2,45]),t(y,[2,44]),t(y,[2,101]),t(y,[2,102]),t(y,[2,99]),t(y,[2,100]),t(y,[2,104]),t(y,[2,103]),t(y,[2,108]),t(y,[2,107]),t(y,[2,106]),t(y,[2,105]),t(y,[2,110]),t(y,[2,109]),t(y,[2,98]),t(y,[2,97]),t(y,[2,96]),t(y,[2,95]),t(y,[2,93]),t(y,[2,94]),t(y,[2,92]),t(y,[2,91]),t(y,[2,90]),t(y,[2,89]),t(y,[2,87]),t(y,[2,88])],defaultActions:{9:[2,118],10:[2,1],11:[2,2],19:[2,3],27:[2,4],46:[2,120],47:[2,5]},parseError:function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)},parse:function(t){var e=this,r=[0],i=[],n=[null],c=[],a=this.table,s="",o=0,l=0,h=2,m=1,u=c.slice.call(arguments,1),y=Object.create(this.lexer),p={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(p.yy[g]=this.yy[g]);y.setInput(t,p.yy),p.yy.lexer=y,p.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var b=y.yylloc;c.push(b);var d=y.options&&y.options.ranges;function f(){var t;return"number"!=typeof(t=i.pop()||y.lex()||m)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var k,_,$,x,v,w,E,T,O={};;){if(_=r[r.length-1],this.defaultActions[_]?$=this.defaultActions[_]:(null==k&&(k=f()),$=a[_]&&a[_][k]),void 0===$||!$.length||!$[0]){var L="";for(v in T=[],a[_])this.terminals_[v]&&v>h&&T.push("'"+this.terminals_[v]+"'");L=y.showPosition?"Parse error on line "+(o+1)+":\n"+y.showPosition()+"\nExpecting "+T.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(o+1)+": Unexpected "+(k==m?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(L,{text:y.match,token:this.terminals_[k]||k,line:y.yylineno,loc:b,expected:T})}if($[0]instanceof Array&&$.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+k);switch($[0]){case 1:r.push(k),n.push(y.yytext),c.push(y.yylloc),r.push($[1]),k=null,l=y.yyleng,s=y.yytext,o=y.yylineno,b=y.yylloc;break;case 2:if(w=this.productions_[$[1]][1],O.$=n[n.length-w],O._$={first_line:c[c.length-(w||1)].first_line,last_line:c[c.length-1].last_line,first_column:c[c.length-(w||1)].first_column,last_column:c[c.length-1].last_column},d&&(O._$.range=[c[c.length-(w||1)].range[0],c[c.length-1].range[1]]),void 0!==(x=this.performAction.apply(O,[s,l,o,p.yy,$[1],n,c].concat(u))))return x;w&&(r=r.slice(0,-1*w*2),n=n.slice(0,-1*w),c=c.slice(0,-1*w)),r.push(this.productions_[$[1]][0]),n.push(O.$),c.push(O._$),E=a[r[r.length-2]][r[r.length-1]],r.push(E);break;case 3:return!0}}return!0}},x={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,r=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 i=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),r.length-1&&(this.yylineno-=r.length-1);var n=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:r?(r.length===i.length?this.yylloc.first_column:0)+i[i.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var r,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var c in n)this[c]=n[c];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,r,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),c=0;ce[0].length)){if(e=r,i=c,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,n[c])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,r,i){switch(r){case 0:return this.begin("open_directive"),50;case 1:return this.begin("type_directive"),51;case 2:return this.popState(),this.begin("arg_directive"),9;case 3:return this.popState(),this.popState(),53;case 4:return 52;case 5:return this.begin("acc_title"),20;case 6:return this.popState(),"acc_title_value";case 7:return this.begin("acc_descr"),22;case 8:return this.popState(),"acc_descr_value";case 9:this.begin("acc_descr_multiline");break;case 10:this.popState();break;case 11:return"acc_descr_multiline_value";case 12:return 14;case 13:case 14:break;case 15:return 6;case 16:return 40;case 17:return 33;case 18:return 38;case 19:return 42;case 20:return 43;case 21:return 44;case 22:return 45;case 23:return 35;case 24:return 29;case 25:return 30;case 26:return 37;case 27:return 32;case 28:return 27;case 29:case 30:return 10;case 31:return 9;case 32:return"CARET";case 33:this.begin("options");break;case 34:this.popState();break;case 35:return 13;case 36:return 36;case 37:this.begin("string");break;case 38:this.popState();break;case 39:return 34;case 40:return 31;case 41:return 54;case 42:return 8}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:gitGraph\b)/i,/^(?:commit(?=\s|$))/i,/^(?:id:)/i,/^(?:type:)/i,/^(?:msg:)/i,/^(?:NORMAL\b)/i,/^(?:REVERSE\b)/i,/^(?:HIGHLIGHT\b)/i,/^(?:tag:)/i,/^(?:branch(?=\s|$))/i,/^(?:order:)/i,/^(?:merge(?=\s|$))/i,/^(?:cherry-pick(?=\s|$))/i,/^(?:checkout(?=\s|$))/i,/^(?:LR\b)/i,/^(?:BT\b)/i,/^(?::)/i,/^(?:\^)/i,/^(?:options\r?\n)/i,/^(?:[ \r\n\t]+end\b)/i,/^(?:[\s\S]+(?=[ \r\n\t]+end))/i,/^(?:["]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[0-9]+(?=\s|$))/i,/^(?:\w([-\./\w]*[-\w])?)/i,/^(?:$)/i,/^(?:\s+)/i],conditions:{acc_descr_multiline:{rules:[10,11],inclusive:!1},acc_descr:{rules:[8],inclusive:!1},acc_title:{rules:[6],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},options:{rules:[34,35],inclusive:!1},string:{rules:[38,39],inclusive:!1},INITIAL:{rules:[0,5,7,9,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,36,37,40,41,42,43],inclusive:!0}}};function v(){this.yy={}}return $.lexer=x,v.prototype=$,$.Parser=v,new v}();v.parser=v;const w=v;let E=s().gitGraph.mainBranchName,T=s().gitGraph.mainBranchOrder,O={},L=null,M={};M[E]={name:E,order:T};let I={};I[E]=L;let A=E,R="LR",S=0;function C(){return d({length:7})}let P={};const N=function(t){if(t=b.sanitizeText(t,s()),void 0===I[t]){let e=new Error('Trying to checkout branch which is not yet created. (Help try using "branch '+t+'")');throw e.hash={text:"checkout "+t,token:"checkout "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"branch '+t+'"']},e}{A=t;const e=I[A];L=O[e]}};function G(t,e,r){const i=t.indexOf(e);-1===i?t.push(r):t.splice(i,1,r)}function D(t){const e=t.reduce(((t,e)=>t.seq>e.seq?t:e),t[0]);let r="";t.forEach((function(t){r+=t===e?"\t*":"\t|"}));const i=[r,e.id,e.seq];for(let n in I)I[n]===e.id&&i.push(n);if(g.debug(i.join(" ")),e.parents&&2==e.parents.length){const r=O[e.parents[0]];G(t,e,r),t.push(O[e.parents[1]])}else{if(0==e.parents.length)return;{const r=O[e.parents];G(t,e,r)}}D(t=function(t,e){const r=Object.create(null);return t.reduce(((t,i)=>{const n=e(i);return r[n]||(r[n]=!0,t.push(i)),t}),[])}(t,(t=>t.id)))}const B=function(){const t=Object.keys(O).map((function(t){return O[t]}));return t.forEach((function(t){g.debug(t.id)})),t.sort(((t,e)=>t.seq-e.seq)),t},H={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4};let j={};const z=0,q=1,F=2,Y=3,U=4;let K={},V={},W=[],J=0;const Q=(t,e,r)=>{const i=k().gitGraph,n=t.append("g").attr("class","commit-bullets"),c=t.append("g").attr("class","commit-labels");let a=0;Object.keys(e).sort(((t,r)=>e[t].seq-e[r].seq)).forEach((t=>{const s=e[t],o=K[s.branch].pos,l=a+10;if(r){let t,e=void 0!==s.customType&&""!==s.customType?s.customType:s.type;switch(e){case z:t="commit-normal";break;case q:t="commit-reverse";break;case F:t="commit-highlight";break;case Y:t="commit-merge";break;case U:t="commit-cherry-pick";break;default:t="commit-normal"}if(e===F){const e=n.append("rect");e.attr("x",l-10),e.attr("y",o-10),e.attr("height",20),e.attr("width",20),e.attr("class",`commit ${s.id} commit-highlight${K[s.branch].index%8} ${t}-outer`),n.append("rect").attr("x",l-6).attr("y",o-6).attr("height",12).attr("width",12).attr("class",`commit ${s.id} commit${K[s.branch].index%8} ${t}-inner`)}else if(e===U)n.append("circle").attr("cx",l).attr("cy",o).attr("r",10).attr("class",`commit ${s.id} ${t}`),n.append("circle").attr("cx",l-3).attr("cy",o+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${s.id} ${t}`),n.append("circle").attr("cx",l+3).attr("cy",o+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${s.id} ${t}`),n.append("line").attr("x1",l+3).attr("y1",o+1).attr("x2",l).attr("y2",o-5).attr("stroke","#fff").attr("class",`commit ${s.id} ${t}`),n.append("line").attr("x1",l-3).attr("y1",o+1).attr("x2",l).attr("y2",o-5).attr("stroke","#fff").attr("class",`commit ${s.id} ${t}`);else{const r=n.append("circle");if(r.attr("cx",l),r.attr("cy",o),r.attr("r",s.type===Y?9:10),r.attr("class",`commit ${s.id} commit${K[s.branch].index%8}`),e===Y){const e=n.append("circle");e.attr("cx",l),e.attr("cy",o),e.attr("r",6),e.attr("class",`commit ${t} ${s.id} commit${K[s.branch].index%8}`)}if(e===q){n.append("path").attr("d",`M ${l-5},${o-5}L${l+5},${o+5}M${l-5},${o+5}L${l+5},${o-5}`).attr("class",`commit ${t} ${s.id} commit${K[s.branch].index%8}`)}}}if(V[s.id]={x:a+10,y:o},r){const t=4,e=2;if(s.type!==U&&(s.customId&&s.type===Y||s.type!==Y)&&i.showCommitLabel){const t=c.append("g"),r=t.insert("rect").attr("class","commit-label-bkg"),n=t.append("text").attr("x",a).attr("y",o+25).attr("class","commit-label").text(s.id);let l=n.node().getBBox();if(r.attr("x",a+10-l.width/2-e).attr("y",o+13.5).attr("width",l.width+2*e).attr("height",l.height+2*e),n.attr("x",a+10-l.width/2),i.rotateCommitLabel){let e=-7.5-(l.width+10)/25*9.5,r=10+l.width/25*8.5;t.attr("transform","translate("+e+", "+r+") rotate(-45, "+a+", "+o+")")}}if(s.tag){const r=c.insert("polygon"),i=c.append("circle"),n=c.append("text").attr("y",o-16).attr("class","tag-label").text(s.tag);let l=n.node().getBBox();n.attr("x",a+10-l.width/2);const h=l.height/2,m=o-19.2;r.attr("class","tag-label-bkg").attr("points",`\n ${a-l.width/2-t/2},${m+e}\n ${a-l.width/2-t/2},${m-e}\n ${a+10-l.width/2-t},${m-h-e}\n ${a+10+l.width/2+t},${m-h-e}\n ${a+10+l.width/2+t},${m+h+e}\n ${a+10-l.width/2-t},${m+h+e}`),i.attr("cx",a-l.width/2+t/2).attr("cy",m).attr("r",1.5).attr("class","tag-hole")}}a+=50,a>J&&(J=a)}))},X=(t,e,r=0)=>{const i=t+Math.abs(t-e)/2;if(r>5)return i;if(W.every((t=>Math.abs(t-i)>=10)))return W.push(i),i;const n=Math.abs(t-e);return X(t,e-n/5,r+1)},Z=(t,e,r,i)=>{const n=V[e.id],c=V[r.id],a=((t,e,r)=>Object.keys(r).filter((i=>r[i].branch===e.branch&&r[i].seq>t.seq&&r[i].seq0)(e,r,i);let s,o="",l="",h=0,m=0,u=K[r.branch].index;if(a){o="A 10 10, 0, 0, 0,",l="A 10 10, 0, 0, 1,",h=10,m=10,u=K[r.branch].index;const t=n.yc.y&&(o="A 20 20, 0, 0, 0,",h=20,m=20,u=K[e.branch].index,s=`M ${n.x} ${n.y} L ${c.x-h} ${n.y} ${o} ${c.x} ${n.y-m} L ${c.x} ${c.y}`),n.y===c.y&&(u=K[e.branch].index,s=`M ${n.x} ${n.y} L ${n.x} ${c.y-h} ${o} ${n.x+m} ${c.y} L ${c.x} ${c.y}`);t.append("path").attr("d",s).attr("class","arrow arrow"+u%8)},tt=(t,e)=>{const r=k().gitGraph,i=t.append("g");e.forEach(((t,e)=>{const n=e%8,c=K[t.name].pos,a=i.append("line");a.attr("x1",0),a.attr("y1",c),a.attr("x2",J),a.attr("y2",c),a.attr("class","branch branch"+n),W.push(c);const s=(t=>{const e=document.createElementNS("http://www.w3.org/2000/svg","text");let r=[];r="string"==typeof t?t.split(/\\n|\n|/gi):Array.isArray(t)?t:[];for(const i of r){const t=document.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","0"),t.setAttribute("class","row"),t.textContent=i.trim(),e.appendChild(t)}return e})(t.name),o=i.insert("rect"),l=i.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+n);l.node().appendChild(s);let h=s.getBBox();o.attr("class","branchLabelBkg label"+n).attr("rx",4).attr("ry",4).attr("x",-h.width-4-(!0===r.rotateCommitLabel?30:0)).attr("y",-h.height/2+8).attr("width",h.width+18).attr("height",h.height+4),l.attr("transform","translate("+(-h.width-14-(!0===r.rotateCommitLabel?30:0))+", "+(c-h.height/2-1)+")"),o.attr("transform","translate(-19, "+(c-h.height/2)+")")}))},et={parser:w,db:{parseDirective:function(t,e,r){p.parseDirective(this,t,e,r)},getConfig:()=>s().gitGraph,setDirection:function(t){R=t},setOptions:function(t){g.debug("options str",t),t=(t=t&&t.trim())||"{}";try{P=JSON.parse(t)}catch(e){g.error("error while parsing gitGraph options",e.message)}},getOptions:function(){return P},commit:function(t,e,r,i){g.debug("Entering commit:",t,e,r,i),e=b.sanitizeText(e,s()),t=b.sanitizeText(t,s()),i=b.sanitizeText(i,s());const n={id:e||S+"-"+C(),message:t,seq:S++,type:r||H.NORMAL,tag:i||"",parents:null==L?[]:[L.id],branch:A};L=n,O[n.id]=n,I[A]=n.id,g.debug("in pushCommit "+n.id)},branch:function(t,e){if(t=b.sanitizeText(t,s()),void 0!==I[t]){let e=new Error('Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout '+t+'")');throw e.hash={text:"branch "+t,token:"branch "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"checkout '+t+'"']},e}I[t]=null!=L?L.id:null,M[t]={name:t,order:e?parseInt(e,10):null},N(t),g.debug("in createBranch")},merge:function(t,e,r,i){t=b.sanitizeText(t,s()),e=b.sanitizeText(e,s());const n=O[I[A]],c=O[I[t]];if(A===t){let e=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(void 0===n||!n){let e=new Error('Incorrect usage of "merge". Current branch ('+A+")has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["commit"]},e}if(void 0===I[t]){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") does not exist");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch "+t]},e}if(void 0===c||!c){let e=new Error('Incorrect usage of "merge". Branch to be merged ('+t+") has no commits");throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:['"commit"']},e}if(n===c){let e=new Error('Incorrect usage of "merge". Both branches have same head');throw e.hash={text:"merge "+t,token:"merge "+t,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["branch abc"]},e}if(e&&void 0!==O[e]){let n=new Error('Incorrect usage of "merge". Commit with id:'+e+" already exists, use different custom Id");throw n.hash={text:"merge "+t+e+r+i,token:"merge "+t+e+r+i,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["merge "+t+" "+e+"_UNIQUE "+r+" "+i]},n}const a={id:e||S+"-"+C(),message:"merged branch "+t+" into "+A,seq:S++,parents:[null==L?null:L.id,I[t]],branch:A,type:H.MERGE,customType:r,customId:!!e,tag:i||""};L=a,O[a.id]=a,I[A]=a.id,g.debug(I),g.debug("in mergeBranch")},cherryPick:function(t,e,r){if(g.debug("Entering cherryPick:",t,e,r),t=b.sanitizeText(t,s()),e=b.sanitizeText(e,s()),r=b.sanitizeText(r,s()),!t||void 0===O[t]){let r=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}let i=O[t],n=i.branch;if(i.type===H.MERGE){let r=new Error('Incorrect usage of "cherryPick". Source commit should not be a merge commit');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}if(!e||void 0===O[e]){if(n===A){let r=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const c=O[I[A]];if(void 0===c||!c){let r=new Error('Incorrect usage of "cherry-pick". Current branch ('+A+")has no commits");throw r.hash={text:"cherryPick "+t+" "+e,token:"cherryPick "+t+" "+e,line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["cherry-pick abc"]},r}const a={id:S+"-"+C(),message:"cherry-picked "+i+" into "+A,seq:S++,parents:[null==L?null:L.id,i.id],branch:A,type:H.CHERRY_PICK,tag:null!=r?r:"cherry-pick:"+i.id};L=a,O[a.id]=a,I[A]=a.id,g.debug(I),g.debug("in cherryPick")}},checkout:N,prettyPrint:function(){g.debug(O);D([B()[0]])},clear:function(){O={},L=null;let t=s().gitGraph.mainBranchName,e=s().gitGraph.mainBranchOrder;I={},I[t]=null,M={},M[t]={name:t,order:e},A=t,S=0,f()},getBranchesAsObjArray:function(){return Object.values(M).map(((t,s)=>{return null!==t.order?t:(o=((t,e)=>{for(var r in e||(e={}))n.call(e,r)&&a(t,r,e[r]);if(i)for(var r of i(e))c.call(e,r)&&a(t,r,e[r]);return t})({},t),l={order:parseFloat(`0.${s}`,10)},e(o,r(l)));var o,l})).sort(((t,e)=>t.order-e.order)).map((({name:t})=>({name:t})))},getBranches:function(){return I},getCommits:function(){return O},getCommitsArray:B,getCurrentBranch:function(){return A},getDirection:function(){return R},getHead:function(){return L},setAccTitle:o,getAccTitle:l,getAccDescription:h,setAccDescription:m,setDiagramTitle:u,getDiagramTitle:y,commitType:H},renderer:{draw:function(t,e,r,i){var n;K={},V={},j={},J=0,W=[];const c=k(),a=c.gitGraph;g.debug("in gitgraph renderer",t+"\n","id:",e,r),j=i.db.getCommits();const s=i.db.getBranchesAsObjArray();let o=0;s.forEach(((t,e)=>{K[t.name]={pos:o,index:e},o+=50+(a.rotateCommitLabel?40:0)}));const l=_(`[id="${e}"]`);Q(l,j,!1),a.showBranches&&tt(l,s),((t,e)=>{const r=t.append("g").attr("class","commit-arrows");Object.keys(e).forEach((t=>{const i=e[t];i.parents&&i.parents.length>0&&i.parents.forEach((t=>{Z(r,e[t],i,e)}))}))})(l,j),Q(l,j,!0),$.insertTitle(l,"gitTitleText",a.titleTopMargin,i.db.getDiagramTitle()),x(void 0,l,a.diagramPadding,null!=(n=a.useMaxWidth)?n:c.useMaxWidth)}},styles:t=>`\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n ${[0,1,2,3,4,5,6,7].map((e=>`\n .branch-label${e} { fill: ${t["gitBranchLabel"+e]}; }\n .commit${e} { stroke: ${t["git"+e]}; fill: ${t["git"+e]}; }\n .commit-highlight${e} { stroke: ${t["gitInv"+e]}; fill: ${t["gitInv"+e]}; }\n .label${e} { fill: ${t["git"+e]}; }\n .arrow${e} { stroke: ${t["git"+e]}; }\n `)).join("\n")}\n\n .branch {\n stroke-width: 1;\n stroke: ${t.lineColor};\n stroke-dasharray: 2;\n }\n .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};}\n .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; }\n .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};}\n .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; }\n .tag-hole { fill: ${t.textColor}; }\n\n .commit-merge {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n .commit-reverse {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n stroke-width: 3;\n }\n .commit-highlight-outer {\n }\n .commit-highlight-inner {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n\n .arrow { stroke-width: 8; stroke-linecap: round; fill: none}\n .gitTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n`};export{et as diagram}; diff --git a/assets/grpc.html.8eb0658a.js b/assets/grpc.html.7c965f05.js similarity index 99% rename from assets/grpc.html.8eb0658a.js rename to assets/grpc.html.7c965f05.js index af853f624..c262f2c1e 100644 --- a/assets/grpc.html.8eb0658a.js +++ b/assets/grpc.html.7c965f05.js @@ -1 +1 @@ -import{r as e,o,c as t,a as s,b as n,F as a,d as i,e as c}from"./app.755d843f.js";const r={},l=i('

    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.

    {\n  "serviceName": "name",\n  "multiMode": false,\n  "idle_timeout": 60,\n  "health_check_timeout": 20,\n  "permit_without_stream": false,\n  "initial_windows_size": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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.

    ',13),p=s("code",null,"multiMode",-1),d=c(": true | false "),u=i('

    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.

    ',19);r.render=function(i,c){const r=e("Badge");return o(),t(a,null,[l,s("blockquote",null,[s("p",null,[p,d,n(r,{text:"BETA",type:"warning"})])]),u],64)};export default r; +import{r as e,o,c as t,a as s,b as n,F as a,d as i,e as c}from"./app.48111a85.js";const r={},l=i('

    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.

    {\n  "serviceName": "name",\n  "multiMode": false,\n  "idle_timeout": 60,\n  "health_check_timeout": 20,\n  "permit_without_stream": false,\n  "initial_windows_size": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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.

    ',13),p=s("code",null,"multiMode",-1),d=c(": true | false "),u=i('

    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.

    ',19);r.render=function(i,c){const r=e("Badge");return o(),t(a,null,[l,s("blockquote",null,[s("p",null,[p,d,n(r,{text:"BETA",type:"warning"})])]),u],64)};export default r; diff --git a/assets/grpc.html.5742e390.js b/assets/grpc.html.8cee21b3.js similarity index 99% rename from assets/grpc.html.5742e390.js rename to assets/grpc.html.8cee21b3.js index fef581ed5..7bf8f3565 100644 --- a/assets/grpc.html.5742e390.js +++ b/assets/grpc.html.8cee21b3.js @@ -1 +1 @@ -import{r as s,o as n,c as o,a as t,b as e,F as a,d as c,e as p}from"./app.755d843f.js";const r={},i=c('

    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 项。

    {\n  "serviceName": "name",\n  "multiMode": false,\n  "user_agent": "custom user agent",\n  "idle_timeout": 60,\n  "health_check_timeout": 20,\n  "permit_without_stream": false,\n  "initial_windows_size": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    serviceName: string

    一个字符串,指定服务名称,类似于 HTTP/2 中的 Path。 客户端会使用此名称进行通信,服务端会验证服务名称是否匹配。

    user_agent: string

    提示

    只需出站客户端)配置。

    设置 gRPC 的用户代理,可能能防止某些 CDN 阻止 gRPC 流量。

    ',14),l=t("code",null,"multiMode",-1),u=p(": true | false "),d=c('

    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 帧以关闭现有连接。

    ',19);r.render=function(c,p){const r=s("Badge");return n(),o(a,null,[i,t("blockquote",null,[t("p",null,[l,u,e(r,{text:"BETA",type:"warning"})])]),d],64)};export default r; +import{r as s,o as n,c as o,a as t,b as e,F as a,d as c,e as p}from"./app.48111a85.js";const r={},i=c('

    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 项。

    {\n  "serviceName": "name",\n  "multiMode": false,\n  "user_agent": "custom user agent",\n  "idle_timeout": 60,\n  "health_check_timeout": 20,\n  "permit_without_stream": false,\n  "initial_windows_size": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    serviceName: string

    一个字符串,指定服务名称,类似于 HTTP/2 中的 Path。 客户端会使用此名称进行通信,服务端会验证服务名称是否匹配。

    user_agent: string

    提示

    只需出站客户端)配置。

    设置 gRPC 的用户代理,可能能防止某些 CDN 阻止 gRPC 流量。

    ',14),l=t("code",null,"multiMode",-1),u=p(": true | false "),d=c('

    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 帧以关闭现有连接。

    ',19);r.render=function(c,p){const r=s("Badge");return n(),o(a,null,[i,t("blockquote",null,[t("p",null,[l,u,e(r,{text:"BETA",type:"warning"})])]),d],64)};export default r; diff --git a/assets/guide.html.81845aa0.js b/assets/guide.html.98d180f2.js similarity index 99% rename from assets/guide.html.81845aa0.js rename to assets/guide.html.98d180f2.js index 7b5fd2724..c42d189f7 100644 --- a/assets/guide.html.81845aa0.js +++ b/assets/guide.html.98d180f2.js @@ -1 +1 @@ -import{r as e,o as a,c as r,a as n,b as o,F as t,d as i,e as l}from"./app.755d843f.js";const s={},d=i('

    Development Standards

    Basic

    Version Control

    Project X's code is hosted on GitHub:

    ',4),c=l("Xray Core "),h={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},u=l("xray-core"),p=l("Installation script "),f={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},m=l("Xray-install"),b=l("Configuration template "),g={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},y=l("Xray-examples"),v=l("Xray documentation "),x={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},w=l("Xray-docs-next"),P=l("You can use "),k={href:"https://git-scm.com/",target:"_blank",rel:"noopener noreferrer"},X=l("Git"),C=l(" to get the code."),I=n("h3",{id:"branch",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#branch","aria-hidden":"true"},"#"),l(" Branch")],-1),T=n("ul",null,[n("li",null,"The main branch is the backbone of this project."),n("li",null,"The main branch is also the release branch of this project."),n("li",null,"It is necessary to ensure that main can be compiled and used normally at any time."),n("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."),n("li",null,"Please delete branches that have been merged into the main branch and are no longer necessary.")],-1),j=n("h3",{id:"release",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#release","aria-hidden":"true"},"#"),l(" Release")],-1),_=l(" (Note: this is not translatable as it is a technical tag) "),G=n("ul",null,[n("li",null,[l("Create two release channels: one for the beta version and another for the stable version. "),n("ul",null,[n("li",null,"The beta version, also known as the daily build, is mainly used for specific testing, experimentation, and instant feedback and improvement."),n("li",null,"The stable version, updated regularly (e.g. monthly), merges stable modifications and releases them.")])])],-1),R=n("h3",{id:"citing-other-projects",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#citing-other-projects","aria-hidden":"true"},"#"),l(" Citing other projects")],-1),F=l("Golang "),S=l("It is recommended to use the Golang standard library and libraries under "),q={href:"https://pkg.go.dev/search?q=golang.org%2Fx",target:"_blank",rel:"noopener noreferrer"},B=l("golang.org/x/"),L=l(" for product code;"),O=n("li",null,"If you need to reference other projects, please create an issue for discussion beforehand;",-1),A=n("li",null,[l("Other "),n("ul",null,[n("li",null,"Tools that do not violate the agreement of both parties and are helpful to the project can be used.")])],-1),M=n("h2",{id:"development-process",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#development-process","aria-hidden":"true"},"#"),l(" Development Process")],-1),U=n("h3",{id:"before-writing-code",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#before-writing-code","aria-hidden":"true"},"#"),l(" Before Writing Code")],-1),z=l("If you encounter any issues or have any ideas for the project, please create an "),D={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},H=l("issue"),N=l(" for discussion to reduce redundant work and save time spent on coding."),W=n("h3",{id:"modify-the-code",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#modify-the-code","aria-hidden":"true"},"#"),l(" Modify the code")],-1),E=l("Golang "),V=l("Please refer to "),Y={href:"https://golang.org/doc/effective_go.html",target:"_blank",rel:"noopener noreferrer"},J=l("Effective Go"),K=l(";"),Q=n("li",null,[l("Run "),n("code",null,"go generate core/format.go"),l(" before each push;")],-1),Z=n("li",null,[l("If you need to modify protobuf, such as adding new configuration items, please run: "),n("code",null,"go generate core/proto.go"),l(";")],-1),$=n("li",null,[l("It is recommended to pass the test before submitting a pull request: "),n("code",null,"go test ./..."),l(";")],-1),ee=n("li",null,"It is recommended to have more than 70% code coverage for newly added code before submitting pull requests.",-1),ae=n("li",null,[l("Other "),n("ul",null,[n("li",null,"Please pay attention to the readability of the code.")])],-1),re=i('

    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\n├── app        // Application module\n│   ├── router // Router\n├── common     // Common code\n├── proxy      // Communication protocol\n│   ├── blackhole\n│   ├── dokodemo-door\n│   ├── freedom\n│   ├── socks\n│   ├── vmess\n├── transport  // Transport module\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    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.
    ',21);s.render=function(i,l){const s=e("OutboundLink"),ne=e("Badge");return a(),r(t,null,[d,n("ul",null,[n("li",null,[c,n("a",h,[u,o(s)])]),n("li",null,[p,n("a",f,[m,o(s)])]),n("li",null,[b,n("a",g,[y,o(s)])]),n("li",null,[v,n("a",x,[w,o(s)])])]),n("p",null,[P,n("a",k,[X,o(s)]),C]),I,T,j,o(ne,{text:"WIP",type:"warning"}),_,G,R,n("ul",null,[n("li",null,[F,n("ul",null,[n("li",null,[S,n("a",q,[B,o(s)]),L]),O])]),A]),M,U,n("p",null,[z,n("a",D,[H,o(s)]),N]),W,n("ul",null,[n("li",null,[E,n("ul",null,[n("li",null,[V,n("a",Y,[J,o(s)]),K]),Q,Z,$,ee])]),ae]),re],64)};export default s; +import{r as e,o as a,c as r,a as n,b as o,F as t,d as i,e as l}from"./app.48111a85.js";const s={},d=i('

    Development Standards

    Basic

    Version Control

    Project X's code is hosted on GitHub:

    ',4),c=l("Xray Core "),h={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},u=l("xray-core"),p=l("Installation script "),f={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},m=l("Xray-install"),b=l("Configuration template "),g={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},y=l("Xray-examples"),v=l("Xray documentation "),x={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},w=l("Xray-docs-next"),P=l("You can use "),k={href:"https://git-scm.com/",target:"_blank",rel:"noopener noreferrer"},X=l("Git"),C=l(" to get the code."),I=n("h3",{id:"branch",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#branch","aria-hidden":"true"},"#"),l(" Branch")],-1),T=n("ul",null,[n("li",null,"The main branch is the backbone of this project."),n("li",null,"The main branch is also the release branch of this project."),n("li",null,"It is necessary to ensure that main can be compiled and used normally at any time."),n("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."),n("li",null,"Please delete branches that have been merged into the main branch and are no longer necessary.")],-1),j=n("h3",{id:"release",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#release","aria-hidden":"true"},"#"),l(" Release")],-1),_=l(" (Note: this is not translatable as it is a technical tag) "),G=n("ul",null,[n("li",null,[l("Create two release channels: one for the beta version and another for the stable version. "),n("ul",null,[n("li",null,"The beta version, also known as the daily build, is mainly used for specific testing, experimentation, and instant feedback and improvement."),n("li",null,"The stable version, updated regularly (e.g. monthly), merges stable modifications and releases them.")])])],-1),R=n("h3",{id:"citing-other-projects",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#citing-other-projects","aria-hidden":"true"},"#"),l(" Citing other projects")],-1),F=l("Golang "),S=l("It is recommended to use the Golang standard library and libraries under "),q={href:"https://pkg.go.dev/search?q=golang.org%2Fx",target:"_blank",rel:"noopener noreferrer"},B=l("golang.org/x/"),L=l(" for product code;"),O=n("li",null,"If you need to reference other projects, please create an issue for discussion beforehand;",-1),A=n("li",null,[l("Other "),n("ul",null,[n("li",null,"Tools that do not violate the agreement of both parties and are helpful to the project can be used.")])],-1),M=n("h2",{id:"development-process",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#development-process","aria-hidden":"true"},"#"),l(" Development Process")],-1),U=n("h3",{id:"before-writing-code",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#before-writing-code","aria-hidden":"true"},"#"),l(" Before Writing Code")],-1),z=l("If you encounter any issues or have any ideas for the project, please create an "),D={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},H=l("issue"),N=l(" for discussion to reduce redundant work and save time spent on coding."),W=n("h3",{id:"modify-the-code",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#modify-the-code","aria-hidden":"true"},"#"),l(" Modify the code")],-1),E=l("Golang "),V=l("Please refer to "),Y={href:"https://golang.org/doc/effective_go.html",target:"_blank",rel:"noopener noreferrer"},J=l("Effective Go"),K=l(";"),Q=n("li",null,[l("Run "),n("code",null,"go generate core/format.go"),l(" before each push;")],-1),Z=n("li",null,[l("If you need to modify protobuf, such as adding new configuration items, please run: "),n("code",null,"go generate core/proto.go"),l(";")],-1),$=n("li",null,[l("It is recommended to pass the test before submitting a pull request: "),n("code",null,"go test ./..."),l(";")],-1),ee=n("li",null,"It is recommended to have more than 70% code coverage for newly added code before submitting pull requests.",-1),ae=n("li",null,[l("Other "),n("ul",null,[n("li",null,"Please pay attention to the readability of the code.")])],-1),re=i('

    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\n├── app        // Application module\n│   ├── router // Router\n├── common     // Common code\n├── proxy      // Communication protocol\n│   ├── blackhole\n│   ├── dokodemo-door\n│   ├── freedom\n│   ├── socks\n│   ├── vmess\n├── transport  // Transport module\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    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.
    ',21);s.render=function(i,l){const s=e("OutboundLink"),ne=e("Badge");return a(),r(t,null,[d,n("ul",null,[n("li",null,[c,n("a",h,[u,o(s)])]),n("li",null,[p,n("a",f,[m,o(s)])]),n("li",null,[b,n("a",g,[y,o(s)])]),n("li",null,[v,n("a",x,[w,o(s)])])]),n("p",null,[P,n("a",k,[X,o(s)]),C]),I,T,j,o(ne,{text:"WIP",type:"warning"}),_,G,R,n("ul",null,[n("li",null,[F,n("ul",null,[n("li",null,[S,n("a",q,[B,o(s)]),L]),O])]),A]),M,U,n("p",null,[z,n("a",D,[H,o(s)]),N]),W,n("ul",null,[n("li",null,[E,n("ul",null,[n("li",null,[V,n("a",Y,[J,o(s)]),K]),Q,Z,$,ee])]),ae]),re],64)};export default s; diff --git a/assets/guide.html.b1f5bad2.js b/assets/guide.html.b889797d.js similarity index 97% rename from assets/guide.html.b1f5bad2.js rename to assets/guide.html.b889797d.js index 13abf61ed..8ecc4aae9 100644 --- a/assets/guide.html.b1f5bad2.js +++ b/assets/guide.html.b889797d.js @@ -1 +1 @@ -import{r as e,o as l,c as a,a as r,b as n,F as i,d as o,e as t}from"./app.755d843f.js";const h={},s=o('

    开发规范

    基本

    版本控制

    project X 的代码被托管在 github 上:

    ',4),u=t("xray 核心 "),d={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},c=t("xray-core"),p=t("安装脚本 "),g={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},b=t("Xray-install"),f=t("配置模板 "),m={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},x=t("Xray-examples"),y=t("xray 文档 "),X={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},k=t("Xray-docs-next"),_=t("您可以使用 "),P={href:"https://git-scm.com/",target:"_blank",rel:"noopener noreferrer"},v=t("Git"),G=t(" 来获取代码。"),R=r("h3",{id:"分支-branch",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#分支-branch","aria-hidden":"true"},"#"),t(" 分支(Branch)")],-1),B=r("ul",null,[r("li",null,"本项目的主干分支为 main,"),r("li",null,"本项目的发布主分支同为 main,"),r("li",null,"需要确保 main 在任一时刻都是可编译,且可正常使用的。"),r("li",null,"如果需要开发新的功能,请新建分支进行开发,在开发完成并且经过充分测试后,合并回主干分支。"),r("li",null,"已经合并入主干且没有必要存在的分支,请删除。")],-1),E=r("h3",{id:"发布-release",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#发布-release","aria-hidden":"true"},"#"),t(" 发布(Release)")],-1),L=r("ul",null,[r("li",null,[t("建立尝鲜版本和稳定版本两个发布通道 "),r("ul",null,[r("li",null,"尝鲜版本,可以为 daily build,主要用于特定情况的测试,尝鲜和获得即时反馈和再改进。"),r("li",null,"稳定版本,为定时更新(比如月更),合并稳定的修改并发布。")])])],-1),T=r("h3",{id:"引用其它项目",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#引用其它项目","aria-hidden":"true"},"#"),t(" 引用其它项目")],-1),q=t("Golang "),A=t("产品代码建议使用 Golang 标准库和 "),F={href:"https://pkg.go.dev/search?q=golang.org%2Fx",target:"_blank",rel:"noopener noreferrer"},S=t("golang.org/x/"),w=t(" 下的库;"),C=r("li",null,"如需引用其它项目,请事先创建 issue 讨论;",-1),H=r("li",null,[t("其它 "),r("ul",null,[r("li",null,"不违反双方的协议,且对项目有帮助的工具,都可以使用。")])],-1),j=r("h2",{id:"开发流程",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#开发流程","aria-hidden":"true"},"#"),t(" 开发流程")],-1),M=r("h3",{id:"写代码之前",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#写代码之前","aria-hidden":"true"},"#"),t(" 写代码之前")],-1),z=t("发现任何问题,或对项目有任何想法,请创建 "),D={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},I=t("issue"),O=t(" 讨论以减少重复劳动和消耗在代码上的时间。"),W=r("h3",{id:"修改代码",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#修改代码","aria-hidden":"true"},"#"),t(" 修改代码")],-1),J=t("Golang "),K=t("请参考 "),N={href:"https://golang.org/doc/effective_go.html",target:"_blank",rel:"noopener noreferrer"},Q=t("Effective Go"),U=t(";"),V=r("li",null,[t("每一次 push 之前,请运行:"),r("code",null,"go generate core/format.go"),t(";")],-1),Y=r("li",null,[t("如果需要修改 protobuf,例如增加新配置项,请运行:"),r("code",null,"go generate core/proto.go"),t(";")],-1),Z=r("li",null,[t("提交 pull request 之前,建议测试通过:"),r("code",null,"go test ./..."),t(";")],-1),$=r("li",null,"提交 pull request 之前,建议新增代码有超过 70% 的代码覆盖率(code coverage);",-1),ee=r("li",null,[t("其它 "),r("ul",null,[r("li",null,"请注意代码的可读性。")])],-1),le=o('

    Pull Request

    • 提交 PR 之前,请先运行 git pull https://github.com/xray/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/xray/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\n├── app        // 应用模块\n│   ├── router // 路由\n├── common     // 公用代码\n├── proxy      // 通讯协议\n│   ├── blackhole\n│   ├── dokodemo-door\n│   ├── freedom\n│   ├── socks\n│   ├── vmess\n├── transport  // 传输模块\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    编码规范

    基本与 Golang 官方所推荐做法一致,有一些例外。写在这里以方便大家熟悉 Golang。

    命名

    ',18),ae=r("li",null,[t("文件和目录名尽量使用单个英文单词,比如 hello.go; "),r("ul",null,[r("li",null,"如果实在没办法,则目录使用连接线/文件名使用下划线连接两个(或多个单词),比如 hello-world/hello_again.go;"),r("li",null,"测试代码使用 _test.go 结尾;")])],-1),re=r("li",null,[t("类型使用 Pascal 命名法,比如 ConnectionHandler; "),r("ul",null,[r("li",null,"对缩写不强制小写,即 HTML 不必写成 Html;")])],-1),ne=r("li",null,"公开成员变量也使用 Pascal 命名法;",-1),ie=t("私有成员变量使用 "),oe={href:"https://zh.wikipedia.org/wiki/%E9%A7%9D%E5%B3%B0%E5%BC%8F%E5%A4%A7%E5%B0%8F%E5%AF%AB",target:"_blank",rel:"noopener noreferrer"},te=t("小驼峰式命名法"),he=t(" ,如 "),se=r("code",null,"privateAttribute",-1),ue=t(" ;"),de=r("li",null,[t("为了方便重构,方法建议全部使用 Pascal 命名法; "),r("ul",null,[r("li",null,[t("完全私有的类型放入 "),r("code",null,"internal"),t(" 。")])])],-1),ce=r("h4",{id:"内容组织",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#内容组织","aria-hidden":"true"},"#"),t(" 内容组织")],-1),pe=r("ul",null,[r("li",null,"一个文件包含一个主要类型,及其相关的私有函数等;"),r("li",null,"测试相关的文件,如 Mock 等工具类,放入 testing 子目录。")],-1);h.render=function(o,t){const h=e("OutboundLink"),ge=e("Badge");return l(),a(i,null,[s,r("ul",null,[r("li",null,[u,r("a",d,[c,n(h)])]),r("li",null,[p,r("a",g,[b,n(h)])]),r("li",null,[f,r("a",m,[x,n(h)])]),r("li",null,[y,r("a",X,[k,n(h)])])]),r("p",null,[_,r("a",P,[v,n(h)]),G]),R,B,E,n(ge,{text:"WIP",type:"warning"}),L,T,r("ul",null,[r("li",null,[q,r("ul",null,[r("li",null,[A,r("a",F,[S,n(h)]),w]),C])]),H]),j,M,r("p",null,[z,r("a",D,[I,n(h)]),O]),W,r("ul",null,[r("li",null,[J,r("ul",null,[r("li",null,[K,r("a",N,[Q,n(h)]),U]),V,Y,Z,$])]),ee]),le,r("ul",null,[ae,re,ne,r("li",null,[ie,r("a",oe,[te,n(h)]),he,se,ue]),de]),ce,pe],64)};export default h; +import{r as e,o as l,c as a,a as r,b as n,F as i,d as o,e as t}from"./app.48111a85.js";const h={},s=o('

    开发规范

    基本

    版本控制

    project X 的代码被托管在 github 上:

    ',4),u=t("xray 核心 "),d={href:"https://github.com/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},c=t("xray-core"),p=t("安装脚本 "),g={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},b=t("Xray-install"),m=t("配置模板 "),f={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},x=t("Xray-examples"),y=t("xray 文档 "),X={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},k=t("Xray-docs-next"),_=t("您可以使用 "),P={href:"https://git-scm.com/",target:"_blank",rel:"noopener noreferrer"},v=t("Git"),G=t(" 来获取代码。"),R=r("h3",{id:"分支-branch",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#分支-branch","aria-hidden":"true"},"#"),t(" 分支(Branch)")],-1),B=r("ul",null,[r("li",null,"本项目的主干分支为 main,"),r("li",null,"本项目的发布主分支同为 main,"),r("li",null,"需要确保 main 在任一时刻都是可编译,且可正常使用的。"),r("li",null,"如果需要开发新的功能,请新建分支进行开发,在开发完成并且经过充分测试后,合并回主干分支。"),r("li",null,"已经合并入主干且没有必要存在的分支,请删除。")],-1),E=r("h3",{id:"发布-release",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#发布-release","aria-hidden":"true"},"#"),t(" 发布(Release)")],-1),L=r("ul",null,[r("li",null,[t("建立尝鲜版本和稳定版本两个发布通道 "),r("ul",null,[r("li",null,"尝鲜版本,可以为 daily build,主要用于特定情况的测试,尝鲜和获得即时反馈和再改进。"),r("li",null,"稳定版本,为定时更新(比如月更),合并稳定的修改并发布。")])])],-1),T=r("h3",{id:"引用其它项目",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#引用其它项目","aria-hidden":"true"},"#"),t(" 引用其它项目")],-1),q=t("Golang "),A=t("产品代码建议使用 Golang 标准库和 "),F={href:"https://pkg.go.dev/search?q=golang.org%2Fx",target:"_blank",rel:"noopener noreferrer"},S=t("golang.org/x/"),w=t(" 下的库;"),C=r("li",null,"如需引用其它项目,请事先创建 issue 讨论;",-1),H=r("li",null,[t("其它 "),r("ul",null,[r("li",null,"不违反双方的协议,且对项目有帮助的工具,都可以使用。")])],-1),j=r("h2",{id:"开发流程",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#开发流程","aria-hidden":"true"},"#"),t(" 开发流程")],-1),M=r("h3",{id:"写代码之前",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#写代码之前","aria-hidden":"true"},"#"),t(" 写代码之前")],-1),z=t("发现任何问题,或对项目有任何想法,请创建 "),D={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},I=t("issue"),O=t(" 讨论以减少重复劳动和消耗在代码上的时间。"),W=r("h3",{id:"修改代码",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#修改代码","aria-hidden":"true"},"#"),t(" 修改代码")],-1),J=t("Golang "),K=t("请参考 "),N={href:"https://golang.org/doc/effective_go.html",target:"_blank",rel:"noopener noreferrer"},Q=t("Effective Go"),U=t(";"),V=r("li",null,[t("每一次 push 之前,请运行:"),r("code",null,"go generate core/format.go"),t(";")],-1),Y=r("li",null,[t("如果需要修改 protobuf,例如增加新配置项,请运行:"),r("code",null,"go generate core/proto.go"),t(";")],-1),Z=r("li",null,[t("提交 pull request 之前,建议测试通过:"),r("code",null,"go test ./..."),t(";")],-1),$=r("li",null,"提交 pull request 之前,建议新增代码有超过 70% 的代码覆盖率(code coverage);",-1),ee=r("li",null,[t("其它 "),r("ul",null,[r("li",null,"请注意代码的可读性。")])],-1),le=o('

    Pull Request

    • 提交 PR 之前,请先运行 git pull https://github.com/xray/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/xray/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\n├── app        // 应用模块\n│   ├── router // 路由\n├── common     // 公用代码\n├── proxy      // 通讯协议\n│   ├── blackhole\n│   ├── dokodemo-door\n│   ├── freedom\n│   ├── socks\n│   ├── vmess\n├── transport  // 传输模块\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    编码规范

    基本与 Golang 官方所推荐做法一致,有一些例外。写在这里以方便大家熟悉 Golang。

    命名

    ',18),ae=r("li",null,[t("文件和目录名尽量使用单个英文单词,比如 hello.go; "),r("ul",null,[r("li",null,"如果实在没办法,则目录使用连接线/文件名使用下划线连接两个(或多个单词),比如 hello-world/hello_again.go;"),r("li",null,"测试代码使用 _test.go 结尾;")])],-1),re=r("li",null,[t("类型使用 Pascal 命名法,比如 ConnectionHandler; "),r("ul",null,[r("li",null,"对缩写不强制小写,即 HTML 不必写成 Html;")])],-1),ne=r("li",null,"公开成员变量也使用 Pascal 命名法;",-1),ie=t("私有成员变量使用 "),oe={href:"https://zh.wikipedia.org/wiki/%E9%A7%9D%E5%B3%B0%E5%BC%8F%E5%A4%A7%E5%B0%8F%E5%AF%AB",target:"_blank",rel:"noopener noreferrer"},te=t("小驼峰式命名法"),he=t(" ,如 "),se=r("code",null,"privateAttribute",-1),ue=t(" ;"),de=r("li",null,[t("为了方便重构,方法建议全部使用 Pascal 命名法; "),r("ul",null,[r("li",null,[t("完全私有的类型放入 "),r("code",null,"internal"),t(" 。")])])],-1),ce=r("h4",{id:"内容组织",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#内容组织","aria-hidden":"true"},"#"),t(" 内容组织")],-1),pe=r("ul",null,[r("li",null,"一个文件包含一个主要类型,及其相关的私有函数等;"),r("li",null,"测试相关的文件,如 Mock 等工具类,放入 testing 子目录。")],-1);h.render=function(o,t){const h=e("OutboundLink"),ge=e("Badge");return l(),a(i,null,[s,r("ul",null,[r("li",null,[u,r("a",d,[c,n(h)])]),r("li",null,[p,r("a",g,[b,n(h)])]),r("li",null,[m,r("a",f,[x,n(h)])]),r("li",null,[y,r("a",X,[k,n(h)])])]),r("p",null,[_,r("a",P,[v,n(h)]),G]),R,B,E,n(ge,{text:"WIP",type:"warning"}),L,T,r("ul",null,[r("li",null,[q,r("ul",null,[r("li",null,[A,r("a",F,[S,n(h)]),w]),C])]),H]),j,M,r("p",null,[z,r("a",D,[I,n(h)]),O]),W,r("ul",null,[r("li",null,[J,r("ul",null,[r("li",null,[K,r("a",N,[Q,n(h)]),U]),V,Y,Z,$])]),ee]),le,r("ul",null,[ae,re,ne,r("li",null,[ie,r("a",oe,[te,n(h)]),he,se,ue]),de]),ce,pe],64)};export default h; diff --git a/assets/h2.html.154fc280.js b/assets/h2.html.cb11d7f7.js similarity index 98% rename from assets/h2.html.154fc280.js rename to assets/h2.html.cb11d7f7.js index fb82bd8f1..33d69eecb 100644 --- a/assets/h2.html.154fc280.js +++ b/assets/h2.html.cb11d7f7.js @@ -1 +1 @@ -import{r as e,o as n,c as s,a as t,b as a,w as o,F as p,d as r,e as c}from"./app.755d843f.js";const i={},l=r('

    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),u=t("code",null,"HttpObject",-1),d=c(" corresponds to the "),h=t("code",null,"httpSettings",-1),m=c(" in the "),b=c("Transport Protocol"),k=c(","),T=r('
    {\n  "host": ["xray.com"],\n  "path": "/random/path",\n  "read_idle_timeout": 10,\n  "health_check_timeout": 15,\n  "method": "PUT",\n  "headers": {\n    "Header": ["value"]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    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

    ',17),g=c("Please refer this "),f={href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods",target:"_blank",rel:"noopener noreferrer"},q=c("this"),v=c(" when configure."),y=t("blockquote",null,[t("p",null,[t("code",null,"headers"),c(": map{ string: [string] }")])],-1),P=t("p",null,"Custom HTTP headers, defined as key-value pairs. Each key represents an HTTP header name and its corresponding value is an array.",-1);i.render=function(r,c){const i=e("RouterLink"),H=e("OutboundLink");return n(),s(p,null,[l,t("p",null,[u,d,h,m,a(i,{to:"/en/config/transport.html"},{default:o((()=>[b])),_:1}),k]),T,t("p",null,[g,t("a",f,[q,a(H)]),v]),y,P],64)};export default i; +import{r as e,o as n,c as s,a as t,b as a,w as o,F as p,d as r,e as c}from"./app.48111a85.js";const i={},l=r('

    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),u=t("code",null,"HttpObject",-1),d=c(" corresponds to the "),h=t("code",null,"httpSettings",-1),m=c(" in the "),b=c("Transport Protocol"),k=c(","),T=r('
    {\n  "host": ["xray.com"],\n  "path": "/random/path",\n  "read_idle_timeout": 10,\n  "health_check_timeout": 15,\n  "method": "PUT",\n  "headers": {\n    "Header": ["value"]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    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

    ',17),g=c("Please refer this "),f={href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods",target:"_blank",rel:"noopener noreferrer"},q=c("this"),v=c(" when configure."),y=t("blockquote",null,[t("p",null,[t("code",null,"headers"),c(": map{ string: [string] }")])],-1),P=t("p",null,"Custom HTTP headers, defined as key-value pairs. Each key represents an HTTP header name and its corresponding value is an array.",-1);i.render=function(r,c){const i=e("RouterLink"),H=e("OutboundLink");return n(),s(p,null,[l,t("p",null,[u,d,h,m,a(i,{to:"/en/config/transport.html"},{default:o((()=>[b])),_:1}),k]),T,t("p",null,[g,t("a",f,[q,a(H)]),v]),y,P],64)};export default i; diff --git a/assets/h2.html.7e765ae6.js b/assets/h2.html.f3f21890.js similarity index 98% rename from assets/h2.html.7e765ae6.js rename to assets/h2.html.f3f21890.js index e6e20de6c..c79550211 100644 --- a/assets/h2.html.7e765ae6.js +++ b/assets/h2.html.f3f21890.js @@ -1 +1 @@ -import{r as n,o as s,c as t,a,b as o,F as p,d as e,e as c}from"./app.755d843f.js";const r={},l=e('

    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 项。

    {\n  "host": ["xray.com"],\n  "path": "/random/path",\n  "read_idle_timeout": 10,\n  "health_check_timeout": 15,\n  "method": "PUT",\n  "headers": {\n    "Header": ["value"]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    host: [string]

    一个字符串数组,每一个元素是一个域名。

    客户端会随机从列表中选出一个域名进行通信,服务器会验证域名是否在列表中。

    path: string

    HTTP 路径,由 / 开头, 客户端和服务器必须一致。

    默认值为 "/"

    read_idle_timeout: number

    单位秒,当这段时间内没有接收到数据时,将会进行健康检查。

    健康检查默认不启用

    提示

    只需出站客户端)配置。

    提示

    可能会解决一些“断流”问题。

    health_check_timeout: number

    单位秒,健康检查的超时时间。如果在这段时间内没有完成健康检查,即认为健康检查失败。默认值为 15

    提示

    只需出站客户端)配置。

    method: string

    HTTP 方法。默认值为 "PUT"

    ',26),u=c("设置时应参照"),i={href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods",target:"_blank",rel:"noopener noreferrer"},d=c("此处"),k=c("列出值。"),b=a("blockquote",null,[a("p",null,[a("code",null,"headers"),c(": map{ string: [string] }")])],-1),m=a("p",null,"自定义 HTTP 头,一个键值对,每个键表示一个 HTTP 头名称,对应值为一个数组。",-1);r.render=function(e,c){const r=n("OutboundLink");return s(),t(p,null,[l,a("p",null,[u,a("a",i,[d,o(r)]),k]),b,m],64)};export default r; +import{r as n,o as s,c as t,a,b as o,F as p,d as e,e as c}from"./app.48111a85.js";const r={},l=e('

    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 项。

    {\n  "host": ["xray.com"],\n  "path": "/random/path",\n  "read_idle_timeout": 10,\n  "health_check_timeout": 15,\n  "method": "PUT",\n  "headers": {\n    "Header": ["value"]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    host: [string]

    一个字符串数组,每一个元素是一个域名。

    客户端会随机从列表中选出一个域名进行通信,服务器会验证域名是否在列表中。

    path: string

    HTTP 路径,由 / 开头, 客户端和服务器必须一致。

    默认值为 "/"

    read_idle_timeout: number

    单位秒,当这段时间内没有接收到数据时,将会进行健康检查。

    健康检查默认不启用

    提示

    只需出站客户端)配置。

    提示

    可能会解决一些“断流”问题。

    health_check_timeout: number

    单位秒,健康检查的超时时间。如果在这段时间内没有完成健康检查,即认为健康检查失败。默认值为 15

    提示

    只需出站客户端)配置。

    method: string

    HTTP 方法。默认值为 "PUT"

    ',26),u=c("设置时应参照"),i={href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods",target:"_blank",rel:"noopener noreferrer"},d=c("此处"),k=c("列出值。"),b=a("blockquote",null,[a("p",null,[a("code",null,"headers"),c(": map{ string: [string] }")])],-1),m=a("p",null,"自定义 HTTP 头,一个键值对,每个键表示一个 HTTP 头名称,对应值为一个数组。",-1);r.render=function(e,c){const r=n("OutboundLink");return s(),t(p,null,[l,a("p",null,[u,a("a",i,[d,o(r)]),k]),b,m],64)};export default r; diff --git a/assets/http.html.47cc7e32.js b/assets/http.html.01d77f27.js similarity index 98% rename from assets/http.html.47cc7e32.js rename to assets/http.html.01d77f27.js index 5d17774d5..fddc5e959 100644 --- a/assets/http.html.47cc7e32.js +++ b/assets/http.html.01d77f27.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as o,b as e,w as p,F as t,d as c,e as l}from"./app.755d843f.js";const u={},r=c('

    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

    {\n  "timeout": 0,\n  "accounts": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ],\n  "allowTransparent": false,\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    timeout: number

    连接空闲的时间限制。单位为秒。默认值为 300, 0 表示不限时。

    处理一个连接时,如果在 timeout 时间内,没有任何数据被传输,则中断该连接。

    accounts: [AccountObject]

    一个数组,数组中每个元素为一个用户帐号。默认值为空。

    accounts 非空时,HTTP 代理将对入站连接进行 Basic Authentication 验证。

    allowTransparent: true | false

    当为 true 时,会转发所有 HTTP 请求,而非只是代理请求。

    提示

    若配置不当,开启此选项会导致死循环。

    userLevel: number

    ',18),i=l("用户等级,连接会使用这个用户等级对应的 "),d=l("本地策略"),b=l("。"),k=l("userLevel 的值, 对应 "),m=l("policy"),q=l(" 中 "),h=o("code",null,"level",-1),g=l(" 的值。 如不指定, 默认为 0。"),v=c('

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    ',6);u.render=function(c,l){const u=n("RouterLink");return s(),a(t,null,[r,o("p",null,[i,e(u,{to:"/config/policy.html#levelpolicyobject"},{default:p((()=>[d])),_:1}),b]),o("p",null,[k,e(u,{to:"/config/policy.html#policyobject"},{default:p((()=>[m])),_:1}),q,h,g]),v],64)};export default u; +import{r as n,o as s,c as a,a as o,b as e,w as p,F as t,d as c,e as l}from"./app.48111a85.js";const u={},r=c('

    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

    {\n  "timeout": 0,\n  "accounts": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ],\n  "allowTransparent": false,\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    timeout: number

    连接空闲的时间限制。单位为秒。默认值为 300, 0 表示不限时。

    处理一个连接时,如果在 timeout 时间内,没有任何数据被传输,则中断该连接。

    accounts: [AccountObject]

    一个数组,数组中每个元素为一个用户帐号。默认值为空。

    accounts 非空时,HTTP 代理将对入站连接进行 Basic Authentication 验证。

    allowTransparent: true | false

    当为 true 时,会转发所有 HTTP 请求,而非只是代理请求。

    提示

    若配置不当,开启此选项会导致死循环。

    userLevel: number

    ',18),i=l("用户等级,连接会使用这个用户等级对应的 "),d=l("本地策略"),b=l("。"),k=l("userLevel 的值, 对应 "),m=l("policy"),q=l(" 中 "),h=o("code",null,"level",-1),g=l(" 的值。 如不指定, 默认为 0。"),v=c('

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    ',6);u.render=function(c,l){const u=n("RouterLink");return s(),a(t,null,[r,o("p",null,[i,e(u,{to:"/config/policy.html#levelpolicyobject"},{default:p((()=>[d])),_:1}),b]),o("p",null,[k,e(u,{to:"/config/policy.html#policyobject"},{default:p((()=>[m])),_:1}),q,h,g]),v],64)};export default u; diff --git a/assets/http.html.6005489a.js b/assets/http.html.10a7301c.js similarity index 99% rename from assets/http.html.6005489a.js rename to assets/http.html.10a7301c.js index b93382153..3824f6e10 100644 --- a/assets/http.html.6005489a.js +++ b/assets/http.html.10a7301c.js @@ -1 +1 @@ -import{d as s}from"./app.755d843f.js";const n={},a=s('

    HTTP

    HTTP 协议。

    警告

    http 协议没有对传输加密,不适宜经公网中传输,更容易成为被人用作攻击的肉鸡。

    提示

    http 只能代理 tcp 协议,udp 系的协议均不能通过。

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "address": "192.168.108.1",\n      "port": 3128,\n      "users": [\n        {\n          "user": "my-username",\n          "pass": "my-password"\n        }\n      ]\n    }\n  ],\n  "headers": {\n    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",\n    "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    提示

    目前 HTTP 协议 outbound 中 streamSettings 设置 securitytlsSettings 是生效的。

    servers: [ ServerObject ]

    HTTP 服务器列表,其中每一项是一个服务器配置,若配置多个,循环使用 (RoundRobin)。

    headers: map{ string, string }

    HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,每次请求会附上所有的键值对

    ServerObject

    {\n  "address": "192.168.108.1",\n  "port": 3128,\n  "users": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    address: string

    HTTP 代理服务器地址,必填。

    port: int

    HTTP 代理服务器端口,必填。

    user: [AccountObject]

    一个数组,数组中每个元素为一个用户帐号。默认值为空。

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    ',25);n.render=function(s,n){return a};export default n; +import{d as s}from"./app.48111a85.js";const n={},a=s('

    HTTP

    HTTP 协议。

    警告

    http 协议没有对传输加密,不适宜经公网中传输,更容易成为被人用作攻击的肉鸡。

    提示

    http 只能代理 tcp 协议,udp 系的协议均不能通过。

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "address": "192.168.108.1",\n      "port": 3128,\n      "users": [\n        {\n          "user": "my-username",\n          "pass": "my-password"\n        }\n      ]\n    }\n  ],\n  "headers": {\n    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",\n    "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    提示

    目前 HTTP 协议 outbound 中 streamSettings 设置 securitytlsSettings 是生效的。

    servers: [ ServerObject ]

    HTTP 服务器列表,其中每一项是一个服务器配置,若配置多个,循环使用 (RoundRobin)。

    headers: map{ string, string }

    HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,每次请求会附上所有的键值对

    ServerObject

    {\n  "address": "192.168.108.1",\n  "port": 3128,\n  "users": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    address: string

    HTTP 代理服务器地址,必填。

    port: int

    HTTP 代理服务器端口,必填。

    user: [AccountObject]

    一个数组,数组中每个元素为一个用户帐号。默认值为空。

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    ',25);n.render=function(s,n){return a};export default n; diff --git a/assets/http.html.ac5ddbc5.js b/assets/http.html.5bafed99.js similarity index 98% rename from assets/http.html.ac5ddbc5.js rename to assets/http.html.5bafed99.js index 991f10d04..9c2857270 100644 --- a/assets/http.html.ac5ddbc5.js +++ b/assets/http.html.5bafed99.js @@ -1 +1 @@ -import{r as n,o as s,c as e,a,b as o,w as t,F as p,d as c,e as r}from"./app.755d843f.js";const l={},i=c('

    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

    {\n  "timeout": 0,\n  "accounts": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ],\n  "allowTransparent": false,\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    timeout: number

    The idle timeout in seconds. The default value is 300, and 0 means no timeout.

    When handling a connection, if no data is transmitted within the timeout period, the connection will be terminated.

    accounts: [AccountObject]

    An array where each element represents a user account. The default value is an empty array.

    When accounts is not empty, the HTTP proxy will perform Basic Authentication verification for inbound connections.

    allowTransparent: true | false

    When set to true, it will forward all HTTP requests instead of just proxy requests.

    Tip

    Enabling this option without proper configuration may cause an infinite loop.

    userLevel: number

    ',7),u=r("The user level that the connection will use to determine the corresponding "),d=r("Local Policy"),b=r("."),h=r("The value of "),m=a("code",null,"userLevel",-1),k=r(" corresponds to the value of "),f=a("code",null,"level",-1),q=r(" in the "),y=r("policy"),g=r(". If not specified, the default value is 0."),v=c('

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    The username. It is a string and is required.

    pass: string

    The password. It is a string and is required.

    ',6);l.render=function(c,r){const l=n("RouterLink");return s(),e(p,null,[i,a("p",null,[u,o(l,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[d])),_:1}),b]),a("p",null,[h,m,k,f,q,o(l,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[y])),_:1}),g]),v],64)};export default l; +import{r as n,o as s,c as e,a,b as o,w as t,F as p,d as c,e as r}from"./app.48111a85.js";const l={},i=c('

    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

    {\n  "timeout": 0,\n  "accounts": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ],\n  "allowTransparent": false,\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    timeout: number

    The idle timeout in seconds. The default value is 300, and 0 means no timeout.

    When handling a connection, if no data is transmitted within the timeout period, the connection will be terminated.

    accounts: [AccountObject]

    An array where each element represents a user account. The default value is an empty array.

    When accounts is not empty, the HTTP proxy will perform Basic Authentication verification for inbound connections.

    allowTransparent: true | false

    When set to true, it will forward all HTTP requests instead of just proxy requests.

    Tip

    Enabling this option without proper configuration may cause an infinite loop.

    userLevel: number

    ',7),u=r("The user level that the connection will use to determine the corresponding "),d=r("Local Policy"),b=r("."),h=r("The value of "),m=a("code",null,"userLevel",-1),k=r(" corresponds to the value of "),f=a("code",null,"level",-1),q=r(" in the "),y=r("policy"),g=r(". If not specified, the default value is 0."),v=c('

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    The username. It is a string and is required.

    pass: string

    The password. It is a string and is required.

    ',6);l.render=function(c,r){const l=n("RouterLink");return s(),e(p,null,[i,a("p",null,[u,o(l,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[d])),_:1}),b]),a("p",null,[h,m,k,f,q,o(l,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[y])),_:1}),g]),v],64)};export default l; diff --git a/assets/http.html.b38fc5e5.js b/assets/http.html.a27f6c1c.js similarity index 99% rename from assets/http.html.b38fc5e5.js rename to assets/http.html.a27f6c1c.js index 5a816983e..56c3b166c 100644 --- a/assets/http.html.b38fc5e5.js +++ b/assets/http.html.a27f6c1c.js @@ -1 +1 @@ -import{d as s}from"./app.755d843f.js";const n={},a=s('

    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

    {\n  "servers": [\n    {\n      "address": "192.168.108.1",\n      "port": 3128,\n      "users": [\n        {\n          "user": "my-username",\n          "pass": "my-password"\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    Tip

    Currently, in the HTTP outbound protocol, the streamSettings configuration with security and tlsSettings is effective.

    servers: [ ServerObject ]

    A list of HTTP servers, where each item represents a server configuration. If multiple servers are configured, they will be used in a round-robin manner.

    ServerObject

    {\n  "address": "192.168.108.1",\n  "port": 3128,\n  "users": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    address: string

    The address of the HTTP proxy server. Required.

    port: int

    The port of the HTTP proxy server. Required.

    user: [AccountObject]

    An array of user accounts. Default value is an empty array.

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    The username. Required.

    pass: string

    The password. Required.

    ',23);n.render=function(s,n){return a};export default n; +import{d as s}from"./app.48111a85.js";const n={},a=s('

    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

    {\n  "servers": [\n    {\n      "address": "192.168.108.1",\n      "port": 3128,\n      "users": [\n        {\n          "user": "my-username",\n          "pass": "my-password"\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    Tip

    Currently, in the HTTP outbound protocol, the streamSettings configuration with security and tlsSettings is effective.

    servers: [ ServerObject ]

    A list of HTTP servers, where each item represents a server configuration. If multiple servers are configured, they will be used in a round-robin manner.

    ServerObject

    {\n  "address": "192.168.108.1",\n  "port": 3128,\n  "users": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    address: string

    The address of the HTTP proxy server. Required.

    port: int

    The port of the HTTP proxy server. Required.

    user: [AccountObject]

    An array of user accounts. Default value is an empty array.

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    The username. Required.

    pass: string

    The password. Required.

    ',23);n.render=function(s,n){return a};export default n; diff --git a/assets/inbound.html.f5f141f8.js b/assets/inbound.html.4ec3aef6.js similarity index 99% rename from assets/inbound.html.f5f141f8.js rename to assets/inbound.html.4ec3aef6.js index 04376eaf2..891579f08 100644 --- a/assets/inbound.html.f5f141f8.js +++ b/assets/inbound.html.4ec3aef6.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as o,b as e,w as t,F as p,e as c,d as l}from"./app.755d843f.js";const u={},r=o("h1",{id:"入站代理",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#入站代理","aria-hidden":"true"},"#"),c(" 入站代理")],-1),d=c("入站连接用于接收发来的数据,可用的协议请见"),i=c("入站协议"),b=c("。"),k=l('

    InboundObject

    InboundObject 对应配置文件中 inbounds 项的一个子元素。

    {\n  "inbounds": [\n    {\n      "listen": "127.0.0.1",\n      "port": 1080,\n      "protocol": "协议名称",\n      "settings": {},\n      "streamSettings": {},\n      "tag": "标识",\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      },\n      "allocate": {\n        "strategy": "always",\n        "refresh": 5,\n        "concurrency": 3\n      }\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    listen: address

    监听地址,IP 地址或 Unix domain socket,默认值为 "0.0.0.0",表示接收所有网卡上的连接.

    可以指定一个系统可用的 IP 地址。

    ',6),q=c("支持填写 Unix domain socket,格式为绝对路径,形如 "),m=o("code",null,'"/dev/shm/domain.socket"',-1),g=c(",可在开头加 "),f=o("code",null,"@",-1),y=c(" 代表 "),h={href:"https://www.man7.org/linux/man-pages/man7/unix.7.html",target:"_blank",rel:"noopener noreferrer"},j=c("abstract"),v=c(","),O=o("code",null,"@@",-1),x=c(" 则代表带 padding 的 abstract。"),P=l("

    填写 Unix domain socket 时,portallocate 将被忽略,协议目前可选 VLESS、VMess、Trojan,传输方式可选 TCP、WebSocket、HTTP/2、gRPC。

    填写 Unix domain socket 时,填写为形如 "/dev/shm/domain.socket,0666" 的形式,即 socket 后加逗号及访问权限指示符,即可指定 socket 的访问权限,可用于解决默认情况下出现的 socket 访问权限问题。

    port: number | "env:variable" | string

    端口。接受的格式如下:

    • 整型数值:实际的端口号。
    • 环境变量:以 "env:" 开头,后面是一个环境变量的名称,如 "env:PORT"。Xray 会以字符串形式解析这个环境变量。
    • 字符串:可以是一个数值类型的字符串,如 "1234";或者一个数值范围,如 "5-10" 表示端口 5 到端口 10,这 6 个端口。可以使用逗号进行分段,如 11,13,15-17 表示端口 11、端口 13、端口 15 到端口 17 这 5 个端口。

    当只有一个端口时,Xray 会在此端口监听入站连接。当指定了一个端口范围时,取决于 allocate 设置。

    protocol: string

    ",7),I=c("连接协议名称,可选的协议类型见 "),S=c("入站协议"),w=c("。"),T=o("blockquote",null,[o("p",null,[o("code",null,"settings"),c(": InboundConfigurationObject")])],-1),X=o("p",null,[c("具体的配置内容,视协议不同而不同。详见每个协议中的 "),o("code",null,"InboundConfigurationObject"),c("。")],-1),B=o("code",null,"streamSettings",-1),C=c(": "),D=c("StreamSettingsObject"),E=l('

    底层传输方式(transport)是当前 Xray 节点和其它节点对接的方式

    tag: string 此入站连接的标识,用于在其它的配置中定位此连接。

    警告

    当其不为空时,其值必须在所有 tag唯一

    sniffing: SniffingObject

    流量探测主要作用于在透明代理等用途. 比如一个典型流程如下:

    1. 如有一个设备上网,去访问 abc.com,首先设备通过 DNS 查询得到 abc.com 的 IP 是 1.2.3.4,然后设备会向 1.2.3.4 去发起连接.
    2. 如果不设置嗅探,Xray 收到的连接请求是 1.2.3.4,并不能用于域名规则的路由分流.
    3. 当设置了 sniffing 中的 enable 为 true,Xray 处理此连接的流量时,会从流量的数据中,嗅探出域名,即 abc.com
    4. Xray 会把 1.2.3.4 重置为 abc.com.路由就可以根据域名去进行路由的域名规则的分流

    因为变成了一个向 abc.com 请求的连接, 就可以做更多的事情, 除了路由域名规则分流, 还能重新做 DNS 解析等其他工作.

    当设置了 sniffing 中的 enable 为 true, 还能嗅探出 bittorrent 类型的流量, 然后可以在路由中配置"protocol"项来设置规则处理 BT 流量, 比如服务端用来拦截 BT 流量, 或客户端固定转发 BT 流量到某个 VPS 去等.

    allocate: AllocateObject

    当设置了多个 port 时, 端口分配的具体设置

    SniffingObject

    {\n  "enabled": true,\n  "destOverride": ["http", "tls", "fakedns"],\n  "metadataOnly": false,\n  "domainsExcluded": [],\n  "routeOnly": false\n}\n
    1
    2
    3
    4
    5
    6
    7

    enabled: true | false

    是否开启流量探测。

    destOverride: ["http" | "tls" | "quic" | "fakedns" | "fakedns+others" ]

    当流量为指定类型时,按其中包括的目标地址重置当前连接的目标。

    其中 ["fakedns+others"] 相当于 ["http", "tls", "quic", "fakedns"],当 IP 地址处于 FakeIP 区间内但没有命中域名记录时会使用 httptlsquic 进行匹配。此项仅在 metadataOnlyfalse 时有效。

    metadataOnly: true | false

    当启用时,将仅使用连接的元数据嗅探目标地址。此时,除 fakedns 以外的 sniffer 将不能激活(包括 fakedns+others)。

    如果关闭仅使用元数据推断目标地址,此时客户端必须先发送数据,代理服务器才会实际建立连接。此行为与需要服务器首先发起第一个消息的协议不兼容,如 SMTP 协议。

    ',20),N=o("code",null,"domainsExcluded",-1),U=c(": [string] "),_=l('

    一个域名列表,如果流量探测结果在这个列表中时,将 不会 重置目标地址。

    注意

    目前,domainsExcluded 不支持类似路由中的域名匹配方式。此选项未来可能会改变,不保证跨版本兼容。

    routeOnly: true | false

    将嗅探得到的域名仅用于路由,代理目标地址仍为 IP。默认值为 false

    此项需要开启 destOverride 使用。

    提示

    在能保证 被代理连接能得到正确的 DNS 解析 时,使用 routeOnly 且开启 destOverride 的同时,将路由匹配策略 domainStrategy 设置为 AsIs 即可实现全程无 DNS 解析进行域名及 IP 分流。此时遇到 IP 规则匹配时使用的 IP 为域名原始 IP。

    AllocateObject

    {\n  "strategy": "always",\n  "refresh": 5,\n  "concurrency": 3\n}\n
    1
    2
    3
    4
    5

    strategy: "always" | "random"

    端口分配策略。

    • "always" 表示总是分配所有已指定的端口,port 中指定了多少个端口,Xray 就会监听这些端口。
    • "random" 表示随机开放端口,每隔 refresh 分钟在 port 范围中随机选取 concurrency 个端口来监听。

    refresh: number

    随机端口刷新间隔,单位为分钟。最小值为 2,建议值为 5。这个属性仅当 strategy 设置为 "random" 时有效。

    concurrency: number

    随机端口数量。最小值为 1,最大值为 port 范围的三分之一。建议值为 3

    ',15);u.render=function(c,l){const u=n("RouterLink"),A=n("OutboundLink"),L=n("Badge");return s(),a(p,null,[r,o("p",null,[d,e(u,{to:"/config/inbounds/"},{default:t((()=>[i])),_:1}),b]),k,o("p",null,[q,m,g,f,y,o("a",h,[j,e(A)]),v,O,x]),P,o("p",null,[I,e(u,{to:"/config/inbounds/"},{default:t((()=>[S])),_:1}),w]),T,X,o("blockquote",null,[o("p",null,[B,C,e(u,{to:"/config/transport.html#streamsettingsobject"},{default:t((()=>[D])),_:1})])]),E,o("blockquote",null,[o("p",null,[N,U,e(L,{text:"WIP",type:"warning"})])]),_],64)};export default u; +import{r as n,o as s,c as a,a as o,b as e,w as t,F as p,e as c,d as l}from"./app.48111a85.js";const u={},r=o("h1",{id:"入站代理",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#入站代理","aria-hidden":"true"},"#"),c(" 入站代理")],-1),d=c("入站连接用于接收发来的数据,可用的协议请见"),i=c("入站协议"),b=c("。"),k=l('

    InboundObject

    InboundObject 对应配置文件中 inbounds 项的一个子元素。

    {\n  "inbounds": [\n    {\n      "listen": "127.0.0.1",\n      "port": 1080,\n      "protocol": "协议名称",\n      "settings": {},\n      "streamSettings": {},\n      "tag": "标识",\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      },\n      "allocate": {\n        "strategy": "always",\n        "refresh": 5,\n        "concurrency": 3\n      }\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    listen: address

    监听地址,IP 地址或 Unix domain socket,默认值为 "0.0.0.0",表示接收所有网卡上的连接.

    可以指定一个系统可用的 IP 地址。

    ',6),q=c("支持填写 Unix domain socket,格式为绝对路径,形如 "),m=o("code",null,'"/dev/shm/domain.socket"',-1),g=c(",可在开头加 "),f=o("code",null,"@",-1),y=c(" 代表 "),h={href:"https://www.man7.org/linux/man-pages/man7/unix.7.html",target:"_blank",rel:"noopener noreferrer"},j=c("abstract"),v=c(","),O=o("code",null,"@@",-1),x=c(" 则代表带 padding 的 abstract。"),P=l("

    填写 Unix domain socket 时,portallocate 将被忽略,协议目前可选 VLESS、VMess、Trojan,传输方式可选 TCP、WebSocket、HTTP/2、gRPC。

    填写 Unix domain socket 时,填写为形如 "/dev/shm/domain.socket,0666" 的形式,即 socket 后加逗号及访问权限指示符,即可指定 socket 的访问权限,可用于解决默认情况下出现的 socket 访问权限问题。

    port: number | "env:variable" | string

    端口。接受的格式如下:

    • 整型数值:实际的端口号。
    • 环境变量:以 "env:" 开头,后面是一个环境变量的名称,如 "env:PORT"。Xray 会以字符串形式解析这个环境变量。
    • 字符串:可以是一个数值类型的字符串,如 "1234";或者一个数值范围,如 "5-10" 表示端口 5 到端口 10,这 6 个端口。可以使用逗号进行分段,如 11,13,15-17 表示端口 11、端口 13、端口 15 到端口 17 这 5 个端口。

    当只有一个端口时,Xray 会在此端口监听入站连接。当指定了一个端口范围时,取决于 allocate 设置。

    protocol: string

    ",7),I=c("连接协议名称,可选的协议类型见 "),S=c("入站协议"),w=c("。"),T=o("blockquote",null,[o("p",null,[o("code",null,"settings"),c(": InboundConfigurationObject")])],-1),X=o("p",null,[c("具体的配置内容,视协议不同而不同。详见每个协议中的 "),o("code",null,"InboundConfigurationObject"),c("。")],-1),B=o("code",null,"streamSettings",-1),C=c(": "),D=c("StreamSettingsObject"),E=l('

    底层传输方式(transport)是当前 Xray 节点和其它节点对接的方式

    tag: string 此入站连接的标识,用于在其它的配置中定位此连接。

    警告

    当其不为空时,其值必须在所有 tag唯一

    sniffing: SniffingObject

    流量探测主要作用于在透明代理等用途. 比如一个典型流程如下:

    1. 如有一个设备上网,去访问 abc.com,首先设备通过 DNS 查询得到 abc.com 的 IP 是 1.2.3.4,然后设备会向 1.2.3.4 去发起连接.
    2. 如果不设置嗅探,Xray 收到的连接请求是 1.2.3.4,并不能用于域名规则的路由分流.
    3. 当设置了 sniffing 中的 enable 为 true,Xray 处理此连接的流量时,会从流量的数据中,嗅探出域名,即 abc.com
    4. Xray 会把 1.2.3.4 重置为 abc.com.路由就可以根据域名去进行路由的域名规则的分流

    因为变成了一个向 abc.com 请求的连接, 就可以做更多的事情, 除了路由域名规则分流, 还能重新做 DNS 解析等其他工作.

    当设置了 sniffing 中的 enable 为 true, 还能嗅探出 bittorrent 类型的流量, 然后可以在路由中配置"protocol"项来设置规则处理 BT 流量, 比如服务端用来拦截 BT 流量, 或客户端固定转发 BT 流量到某个 VPS 去等.

    allocate: AllocateObject

    当设置了多个 port 时, 端口分配的具体设置

    SniffingObject

    {\n  "enabled": true,\n  "destOverride": ["http", "tls", "fakedns"],\n  "metadataOnly": false,\n  "domainsExcluded": [],\n  "routeOnly": false\n}\n
    1
    2
    3
    4
    5
    6
    7

    enabled: true | false

    是否开启流量探测。

    destOverride: ["http" | "tls" | "quic" | "fakedns" | "fakedns+others" ]

    当流量为指定类型时,按其中包括的目标地址重置当前连接的目标。

    其中 ["fakedns+others"] 相当于 ["http", "tls", "quic", "fakedns"],当 IP 地址处于 FakeIP 区间内但没有命中域名记录时会使用 httptlsquic 进行匹配。此项仅在 metadataOnlyfalse 时有效。

    metadataOnly: true | false

    当启用时,将仅使用连接的元数据嗅探目标地址。此时,除 fakedns 以外的 sniffer 将不能激活(包括 fakedns+others)。

    如果关闭仅使用元数据推断目标地址,此时客户端必须先发送数据,代理服务器才会实际建立连接。此行为与需要服务器首先发起第一个消息的协议不兼容,如 SMTP 协议。

    ',20),N=o("code",null,"domainsExcluded",-1),U=c(": [string] "),_=l('

    一个域名列表,如果流量探测结果在这个列表中时,将 不会 重置目标地址。

    注意

    目前,domainsExcluded 不支持类似路由中的域名匹配方式。此选项未来可能会改变,不保证跨版本兼容。

    routeOnly: true | false

    将嗅探得到的域名仅用于路由,代理目标地址仍为 IP。默认值为 false

    此项需要开启 destOverride 使用。

    提示

    在能保证 被代理连接能得到正确的 DNS 解析 时,使用 routeOnly 且开启 destOverride 的同时,将路由匹配策略 domainStrategy 设置为 AsIs 即可实现全程无 DNS 解析进行域名及 IP 分流。此时遇到 IP 规则匹配时使用的 IP 为域名原始 IP。

    AllocateObject

    {\n  "strategy": "always",\n  "refresh": 5,\n  "concurrency": 3\n}\n
    1
    2
    3
    4
    5

    strategy: "always" | "random"

    端口分配策略。

    • "always" 表示总是分配所有已指定的端口,port 中指定了多少个端口,Xray 就会监听这些端口。
    • "random" 表示随机开放端口,每隔 refresh 分钟在 port 范围中随机选取 concurrency 个端口来监听。

    refresh: number

    随机端口刷新间隔,单位为分钟。最小值为 2,建议值为 5。这个属性仅当 strategy 设置为 "random" 时有效。

    concurrency: number

    随机端口数量。最小值为 1,最大值为 port 范围的三分之一。建议值为 3

    ',15);u.render=function(c,l){const u=n("RouterLink"),A=n("OutboundLink"),L=n("Badge");return s(),a(p,null,[r,o("p",null,[d,e(u,{to:"/config/inbounds/"},{default:t((()=>[i])),_:1}),b]),k,o("p",null,[q,m,g,f,y,o("a",h,[j,e(A)]),v,O,x]),P,o("p",null,[I,e(u,{to:"/config/inbounds/"},{default:t((()=>[S])),_:1}),w]),T,X,o("blockquote",null,[o("p",null,[B,C,e(u,{to:"/config/transport.html#streamsettingsobject"},{default:t((()=>[D])),_:1})])]),E,o("blockquote",null,[o("p",null,[N,U,e(L,{text:"WIP",type:"warning"})])]),_],64)};export default u; diff --git a/assets/inbound.html.29c964cf.js b/assets/inbound.html.fbcacc5d.js similarity index 99% rename from assets/inbound.html.29c964cf.js rename to assets/inbound.html.fbcacc5d.js index 43df55d69..589bf1077 100644 --- a/assets/inbound.html.29c964cf.js +++ b/assets/inbound.html.fbcacc5d.js @@ -1 +1 @@ -import{r as n,o as e,c as s,a as o,b as t,w as a,F as c,e as p,d as r}from"./app.755d843f.js";const i={},l=o("h1",{id:"inbound-proxy",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#inbound-proxy","aria-hidden":"true"},"#"),p(" Inbound Proxy")],-1),u=p("Inbound connections are used to receive incoming data and the available protocols are listed in "),d=p("inbound protocols"),b=p("."),h=r('

    InboundObject

    The InboundObject corresponds to a subelement of the inbounds item in the configuration file.

    {\n  "inbounds": [\n    {\n      "listen": "127.0.0.1",\n      "port": 1080,\n      "protocol": "protocol_name",\n      "settings": {},\n      "streamSettings": {},\n      "tag": "identifier",\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      },\n      "allocate": {\n        "strategy": "always",\n        "refresh": 5,\n        "concurrency": 3\n      }\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    listen: address

    The listening address, either an IP address or a Unix domain socket. The default value is "0.0.0.0", which means accepting connections on all network interfaces.

    An available system IP address can be specified.

    ',6),m=p("Unix domain socket can also be specified by providing the absolute path in the form of "),f=o("code",null,'"/dev/shm/domain.socket"',-1),k=p(". The "),q=o("code",null,"@",-1),g=p(" symbol can be added at the beginning to represent "),y={href:"https://www.man7.org/linux/man-pages/man7/unix.7.html",target:"_blank",rel:"noopener noreferrer"},v=p("abstract"),w=p(", and "),T=o("code",null,"@@",-1),j=p(" represents padded abstract."),x=r("

    When Unix domain socket is specified, port and allocate will be ignored. The protocol currently supports VLESS, VMess, and Trojan. The transport methods available are TCP, WebSocket, HTTP/2, and gRPC.

    When specifying a Unix domain socket, you can add a comma and an access permission indicator after the socket, such as "/dev/shm/domain.socket,0666", to specify the access permission of the socket. This can be used to solve the socket access permission issue that occurs by default.

    port: number | "env:variable" | string

    Port. The accepted formats are:

    • Integer: the actual port number.
    • Environment variable: starts with "env:", followed by the name of an environment variable, such as "env:PORT". Xray will parse this environment variable as a string.
    • String: can be a numeric string, such as "1234", or a range of port numbers, such as "5-10" which represents ports 5 through 10, a total of 6 ports. You can use commas to separate multiple ranges, such as 11,13,15-17, which represents ports 11, 13, and 15 through 17, a total of 5 ports.

    When only one port is specified, Xray listens for inbound connections on that port. When a range of ports is specified, it depends on the allocate setting.

    protocol: string

    ",7),I=p("The connection protocol name. The optional protocol types are listed in "),O=p("inbound protocols"),S=p("."),P=o("blockquote",null,[o("p",null,[o("code",null,"settings"),p(": InboundConfigurationObject")])],-1),W=o("p",null,[p("The specific configuration content depends on the protocol. See "),o("code",null,"InboundConfigurationObject"),p(" in each protocol for details.")],-1),X=o("code",null,"streamSettings",-1),A=p(": "),C=p("StreamSettingsObject"),D=r('

    The underlying transport method is how the current Xray node interfaces with other nodes.

    tag: string

    The identifier of this inbound connection, used to locate this connection in other configurations.

    Danger

    When it is not empty, its value must be unique among all tags.

    sniffing: SniffingObject

    Traffic sniffing is mainly used in transparent proxies, for example:

    1. If a device wants to access abc.com while connected to the internet, it will first query the IP address of abc.com via DNS and get 1.2.3.4. Then the device will initiate a connection to 1.2.3.4.
    2. If sniffing is not set up, Xray will receive a connection request for 1.2.3.4, which cannot be used for routing based on domain rules.
    3. When enable in sniffing is set to true, Xray will sniff the domain name, abc.com, from the traffic data when processing the traffic of this connection.
    4. Xray will reset 1.2.3.4 to abc.com. Routing can then be based on domain rules.

    Since the connection is now to abc.com, more can be done, such as routing based on domain rules, and even re-resolving the DNS.

    When enable in sniffing is set to true, it can also sniff out bittorrent traffic and then configure the "protocol" item in routing rules to handle bittorrent traffic, such as intercepting bittorrent traffic on the server or forwarding bittorrent traffic to a VPS on the client side.

    allocate: AllocateObject

    Specifies the specific settings for port allocation when multiple ports are set up.

    SniffingObject

    {\n  "enabled": true,\n  "destOverride": ["http", "tls", "quic", "fakedns", "fakedns+others"],\n  "metadataOnly": false,\n  "domainsExcluded": [],\n  "routeOnly": false\n}\n
    1
    2
    3
    4
    5
    6
    7

    enabled: true | false

    Whether to enable traffic sniffing.

    destOverride: ["http" | "tls" | "quic" | "fakedns" | "fakedns+others" ]

    When the traffic is of a specified type, reset the destination of the current connection to the target address included in the list.

    ["fakedns+others"] is equivalent to ["http", "tls", "quic", "fakedns"], and when the IP address is in the FakeIP range but no domain records are hit, http, tls, and quic will be used for matching. This option is only effective when metadataOnly is set to false.

    metadataOnly: true | false

    When enabled, only use the connection's metadata to sniff the target address. In this case, sniffer other than fakedns (including fakedns+others) cannot be activated.

    If metadata-only is disabled, the client must send data before the proxy server actually establishes the connection. This behavior is incompatible with protocols that require the server to initiate the first message, such as the SMTP protocol.

    ',20),E=o("code",null,"domainsExcluded",-1),U=p(": [string] "),_=r('

    A list of domain names. If the traffic sniffing result matches a domain name in this list, the target address will not be reset.

    Warning

    Currently, domainsExcluded does not support domain name matching in the routing sense. This option may change in the future and cross-version compatibility is not guaranteed.

    routeOnly: true | false

    Use the sniffed domain name for routing only, and keep the target address as the IP address. The default value is false.

    This option requires destOverride to be enabled.

    Tip

    When it is possible to ensure that the proxied connection can obtain correct DNS resolution, by using routeOnly and enabling destOverride, and setting the routing matching strategy domainStrategy to AsIs, it is possible to achieve domain and IP separation without DNS resolution throughout the process. The IP used when encountering an IP rule match is the original IP of the domain.

    AllocateObject

    {\n  "strategy": "always",\n  "refresh": 5,\n  "concurrency": 3\n}\n
    1
    2
    3
    4
    5

    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.

    ',15);i.render=function(p,r){const i=n("RouterLink"),N=n("OutboundLink"),R=n("Badge");return e(),s(c,null,[l,o("p",null,[u,t(i,{to:"/en/config/inbounds/"},{default:a((()=>[d])),_:1}),b]),h,o("p",null,[m,f,k,q,g,o("a",y,[v,t(N)]),w,T,j]),x,o("p",null,[I,t(i,{to:"/en/config/inbounds/"},{default:a((()=>[O])),_:1}),S]),P,W,o("blockquote",null,[o("p",null,[X,A,t(i,{to:"/en/config/transport.html#streamsettingsobject"},{default:a((()=>[C])),_:1})])]),D,o("blockquote",null,[o("p",null,[E,U,t(R,{text:"WIP",type:"warning"})])]),_],64)};export default i; +import{r as n,o as e,c as s,a as o,b as t,w as a,F as c,e as p,d as r}from"./app.48111a85.js";const i={},l=o("h1",{id:"inbound-proxy",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#inbound-proxy","aria-hidden":"true"},"#"),p(" Inbound Proxy")],-1),u=p("Inbound connections are used to receive incoming data and the available protocols are listed in "),d=p("inbound protocols"),b=p("."),h=r('

    InboundObject

    The InboundObject corresponds to a subelement of the inbounds item in the configuration file.

    {\n  "inbounds": [\n    {\n      "listen": "127.0.0.1",\n      "port": 1080,\n      "protocol": "protocol_name",\n      "settings": {},\n      "streamSettings": {},\n      "tag": "identifier",\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      },\n      "allocate": {\n        "strategy": "always",\n        "refresh": 5,\n        "concurrency": 3\n      }\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    listen: address

    The listening address, either an IP address or a Unix domain socket. The default value is "0.0.0.0", which means accepting connections on all network interfaces.

    An available system IP address can be specified.

    ',6),m=p("Unix domain socket can also be specified by providing the absolute path in the form of "),f=o("code",null,'"/dev/shm/domain.socket"',-1),k=p(". The "),q=o("code",null,"@",-1),g=p(" symbol can be added at the beginning to represent "),y={href:"https://www.man7.org/linux/man-pages/man7/unix.7.html",target:"_blank",rel:"noopener noreferrer"},v=p("abstract"),w=p(", and "),T=o("code",null,"@@",-1),j=p(" represents padded abstract."),x=r("

    When Unix domain socket is specified, port and allocate will be ignored. The protocol currently supports VLESS, VMess, and Trojan. The transport methods available are TCP, WebSocket, HTTP/2, and gRPC.

    When specifying a Unix domain socket, you can add a comma and an access permission indicator after the socket, such as "/dev/shm/domain.socket,0666", to specify the access permission of the socket. This can be used to solve the socket access permission issue that occurs by default.

    port: number | "env:variable" | string

    Port. The accepted formats are:

    • Integer: the actual port number.
    • Environment variable: starts with "env:", followed by the name of an environment variable, such as "env:PORT". Xray will parse this environment variable as a string.
    • String: can be a numeric string, such as "1234", or a range of port numbers, such as "5-10" which represents ports 5 through 10, a total of 6 ports. You can use commas to separate multiple ranges, such as 11,13,15-17, which represents ports 11, 13, and 15 through 17, a total of 5 ports.

    When only one port is specified, Xray listens for inbound connections on that port. When a range of ports is specified, it depends on the allocate setting.

    protocol: string

    ",7),I=p("The connection protocol name. The optional protocol types are listed in "),O=p("inbound protocols"),S=p("."),P=o("blockquote",null,[o("p",null,[o("code",null,"settings"),p(": InboundConfigurationObject")])],-1),W=o("p",null,[p("The specific configuration content depends on the protocol. See "),o("code",null,"InboundConfigurationObject"),p(" in each protocol for details.")],-1),X=o("code",null,"streamSettings",-1),A=p(": "),C=p("StreamSettingsObject"),D=r('

    The underlying transport method is how the current Xray node interfaces with other nodes.

    tag: string

    The identifier of this inbound connection, used to locate this connection in other configurations.

    Danger

    When it is not empty, its value must be unique among all tags.

    sniffing: SniffingObject

    Traffic sniffing is mainly used in transparent proxies, for example:

    1. If a device wants to access abc.com while connected to the internet, it will first query the IP address of abc.com via DNS and get 1.2.3.4. Then the device will initiate a connection to 1.2.3.4.
    2. If sniffing is not set up, Xray will receive a connection request for 1.2.3.4, which cannot be used for routing based on domain rules.
    3. When enable in sniffing is set to true, Xray will sniff the domain name, abc.com, from the traffic data when processing the traffic of this connection.
    4. Xray will reset 1.2.3.4 to abc.com. Routing can then be based on domain rules.

    Since the connection is now to abc.com, more can be done, such as routing based on domain rules, and even re-resolving the DNS.

    When enable in sniffing is set to true, it can also sniff out bittorrent traffic and then configure the "protocol" item in routing rules to handle bittorrent traffic, such as intercepting bittorrent traffic on the server or forwarding bittorrent traffic to a VPS on the client side.

    allocate: AllocateObject

    Specifies the specific settings for port allocation when multiple ports are set up.

    SniffingObject

    {\n  "enabled": true,\n  "destOverride": ["http", "tls", "quic", "fakedns", "fakedns+others"],\n  "metadataOnly": false,\n  "domainsExcluded": [],\n  "routeOnly": false\n}\n
    1
    2
    3
    4
    5
    6
    7

    enabled: true | false

    Whether to enable traffic sniffing.

    destOverride: ["http" | "tls" | "quic" | "fakedns" | "fakedns+others" ]

    When the traffic is of a specified type, reset the destination of the current connection to the target address included in the list.

    ["fakedns+others"] is equivalent to ["http", "tls", "quic", "fakedns"], and when the IP address is in the FakeIP range but no domain records are hit, http, tls, and quic will be used for matching. This option is only effective when metadataOnly is set to false.

    metadataOnly: true | false

    When enabled, only use the connection's metadata to sniff the target address. In this case, sniffer other than fakedns (including fakedns+others) cannot be activated.

    If metadata-only is disabled, the client must send data before the proxy server actually establishes the connection. This behavior is incompatible with protocols that require the server to initiate the first message, such as the SMTP protocol.

    ',20),E=o("code",null,"domainsExcluded",-1),U=p(": [string] "),_=r('

    A list of domain names. If the traffic sniffing result matches a domain name in this list, the target address will not be reset.

    Warning

    Currently, domainsExcluded does not support domain name matching in the routing sense. This option may change in the future and cross-version compatibility is not guaranteed.

    routeOnly: true | false

    Use the sniffed domain name for routing only, and keep the target address as the IP address. The default value is false.

    This option requires destOverride to be enabled.

    Tip

    When it is possible to ensure that the proxied connection can obtain correct DNS resolution, by using routeOnly and enabling destOverride, and setting the routing matching strategy domainStrategy to AsIs, it is possible to achieve domain and IP separation without DNS resolution throughout the process. The IP used when encountering an IP rule match is the original IP of the domain.

    AllocateObject

    {\n  "strategy": "always",\n  "refresh": 5,\n  "concurrency": 3\n}\n
    1
    2
    3
    4
    5

    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.

    ',15);i.render=function(p,r){const i=n("RouterLink"),N=n("OutboundLink"),R=n("Badge");return e(),s(c,null,[l,o("p",null,[u,t(i,{to:"/en/config/inbounds/"},{default:a((()=>[d])),_:1}),b]),h,o("p",null,[m,f,k,q,g,o("a",y,[v,t(N)]),w,T,j]),x,o("p",null,[I,t(i,{to:"/en/config/inbounds/"},{default:a((()=>[O])),_:1}),S]),P,W,o("blockquote",null,[o("p",null,[X,A,t(i,{to:"/en/config/transport.html#streamsettingsobject"},{default:a((()=>[C])),_:1})])]),D,o("blockquote",null,[o("p",null,[E,U,t(R,{text:"WIP",type:"warning"})])]),_],64)};export default i; diff --git a/assets/index-05087a90.4347f31d.js b/assets/index-05087a90.017bdfe5.js similarity index 97% rename from assets/index-05087a90.4347f31d.js rename to assets/index-05087a90.017bdfe5.js index 496e07636..61d557c05 100644 --- a/assets/index-05087a90.4347f31d.js +++ b/assets/index-05087a90.017bdfe5.js @@ -1 +1 @@ -import{b as e,m as t,a as n,G as r,l as i}from"./layout.2f099f66.js";import{i as a,u as d,s as o,a as s,b as c,p as l,c as h,d as g,e as f,f as u,g as w,h as p}from"./edges-97052da4.ceadb26f.js";import{l as v,q as y,c as m,h as x}from"./mermaid.core.a66200b0.js";import{c as b}from"./createText-2f679d62.584f3edd.js";function N(t){var r,i={options:{directed:t.isDirected(),multigraph:t.isMultigraph(),compound:t.isCompound()},nodes:X(t),edges:E(t)};return n(t.graph())||(i.value=(r=t.graph(),e(r,4))),i}function X(e){return t(e.nodes(),(function(t){var r=e.node(t),i=e.parent(t),a={v:t};return n(r)||(a.value=r),n(i)||(a.parent=i),a}))}function E(e){return t(e.edges(),(function(t){var r=e.edge(t),i={v:t.v,w:t.w};return n(t.name)||(i.name=t.name),n(r)||(i.value=r),i}))}let S={},C={},D={};const O=(e,t)=>(v.trace("In isDecendant",t," ",e," = ",C[t].includes(e)),!!C[t].includes(e)),B=(e,t,n,r)=>{v.warn("Copying children of ",e,"root",r,"data",t.node(e),r);const i=t.children(e)||[];e!==r&&i.push(e),v.warn("Copying (nodes) clusterId",e,"nodes",i),i.forEach((i=>{if(t.children(i).length>0)B(i,t,n,r);else{const a=t.node(i);v.info("cp ",i," to ",r," with parent ",e),n.setNode(i,a),r!==t.parent(i)&&(v.warn("Setting parent",i,t.parent(i)),n.setParent(i,t.parent(i))),e!==r&&i!==e?(v.debug("Setting parent",i,e),n.setParent(i,e)):(v.info("In copy ",e,"root",r,"data",t.node(e),r),v.debug("Not Setting parent for node=",i,"cluster!==rootId",e!==r,"node!==clusterId",i!==e));const d=t.edges(i);v.debug("Copying Edges",d),d.forEach((i=>{v.info("Edge",i);const a=t.edge(i.v,i.w,i.name);v.info("Edge data",a,r);try{((e,t)=>(v.info("Decendants of ",t," is ",C[t]),v.info("Edge is ",e),e.v!==t&&e.w!==t&&(C[t]?C[t].includes(e.v)||O(e.v,t)||O(e.w,t)||C[t].includes(e.w):(v.debug("Tilt, ",t,",not in decendants"),!1))))(i,r)?(v.info("Copying as ",i.v,i.w,a,i.name),n.setEdge(i.v,i.w,a,i.name),v.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]))):v.info("Skipping copy of edge ",i.v,"--\x3e",i.w," rootId: ",r," clusterId:",e)}catch(d){v.error(d)}}))}v.debug("Removing node",i),t.removeNode(i)}))},T=(e,t)=>{const n=t.children(e);let r=[...n];for(const i of n)D[i]=e,r=[...r,...T(i,t)];return r},J=(e,t)=>{v.trace("Searching",e);const n=t.children(e);if(v.trace("Searching children of id ",e,n),n.length<1)return v.trace("This is a valid node",e),e;for(const r of n){const n=J(r,t);if(n)return v.trace("Found replacement for",e," => ",n),n}},I=e=>S[e]&&S[e].externalConnections&&S[e]?S[e].id:e,R=(e,t)=>{if(v.warn("extractor - ",t,N(e),e.children("D")),t>10)return void v.error("Bailing out");let n=e.nodes(),i=!1;for(const r of n){const t=e.children(r);i=i||t.length>0}if(i){v.debug("Nodes = ",n,t);for(const i of n)if(v.debug("Extracting node",i,S,S[i]&&!S[i].externalConnections,!e.parent(i),e.node(i),e.children("D")," Depth ",t),S[i])if(!S[i].externalConnections&&e.children(i)&&e.children(i).length>0){v.warn("Cluster without external connections, without a parent and with children",i,t);let n="TB"===e.graph().rankdir?"LR":"TB";S[i]&&S[i].clusterData&&S[i].clusterData.dir&&(n=S[i].clusterData.dir,v.warn("Fixing dir",S[i].clusterData.dir,n));const a=new r({multigraph:!0,compound:!0}).setGraph({rankdir:n,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));v.warn("Old graph before copy",N(e)),B(i,e,a,i),e.setNode(i,{clusterNode:!0,id:i,clusterData:S[i].clusterData,labelText:S[i].labelText,graph:a}),v.warn("New graph after copy node: (",i,")",N(a)),v.debug("Old graph after copy",N(e))}else v.warn("Cluster ** ",i," **not meeting the criteria !externalConnections:",!S[i].externalConnections," no parent: ",!e.parent(i)," children ",e.children(i)&&e.children(i).length>0,e.children("D"),t),v.debug(S);else v.debug("Not a cluster",i,t);n=e.nodes(),v.warn("New list of nodes",n);for(const r of n){const n=e.node(r);v.warn(" Now next level",r,n),n.clusterNode&&R(n.graph,t+1)}}else v.debug("Done, no node has children",e.nodes())},G=(e,t)=>{if(0===t.length)return[];let n=Object.assign(t);return t.forEach((t=>{const r=e.children(t),i=G(e,r);n=[...n,...i]})),n},L={rect:(e,t)=>{v.info("Creating subgraph rect for ",t.id,t);const n=e.insert("g").attr("class","cluster"+(t.class?" "+t.class:"")).attr("id",t.id),r=n.insert("rect",":first-child"),i=y(m().flowchart.htmlLabels),a=n.insert("g").attr("class","cluster-label"),d="markdown"===t.labelType?b(a,t.labelText,{style:t.labelStyle,useHtmlLabels:i}):a.node().appendChild(w(t.labelText,t.labelStyle,void 0,!0));let o=d.getBBox();if(y(m().flowchart.htmlLabels)){const e=d.children[0],t=x(d);o=e.getBoundingClientRect(),t.attr("width",o.width),t.attr("height",o.height)}const s=0*t.padding,c=s/2,l=t.width<=o.width+s?o.width+s:t.width;t.width<=o.width+s?t.diff=(o.width-t.width)/2-t.padding/2:t.diff=-t.padding/2,v.trace("Data ",t,JSON.stringify(t)),r.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-l/2).attr("y",t.y-t.height/2-c).attr("width",l).attr("height",t.height+s),i?a.attr("transform","translate("+(t.x-o.width/2)+", "+(t.y-t.height/2)+")"):a.attr("transform","translate("+t.x+", "+(t.y-t.height/2)+")");const h=r.node().getBBox();return t.width=h.width,t.height=h.height,t.intersect=function(e){return p(t,e)},n},roundedWithTitle:(e,t)=>{const n=e.insert("g").attr("class",t.classes).attr("id",t.id),r=n.insert("rect",":first-child"),i=n.insert("g").attr("class","cluster-label"),a=n.append("rect"),d=i.node().appendChild(w(t.labelText,t.labelStyle,void 0,!0));let o=d.getBBox();if(y(m().flowchart.htmlLabels)){const e=d.children[0],t=x(d);o=e.getBoundingClientRect(),t.attr("width",o.width),t.attr("height",o.height)}o=d.getBBox();const s=0*t.padding,c=s/2,l=t.width<=o.width+t.padding?o.width+t.padding:t.width;t.width<=o.width+t.padding?t.diff=(o.width+0*t.padding-t.width)/2:t.diff=-t.padding/2,r.attr("class","outer").attr("x",t.x-l/2-c).attr("y",t.y-t.height/2-c).attr("width",l+s).attr("height",t.height+s),a.attr("class","inner").attr("x",t.x-l/2-c).attr("y",t.y-t.height/2-c+o.height-1).attr("width",l+s).attr("height",t.height+s-o.height-3),i.attr("transform","translate("+(t.x-o.width/2)+", "+(t.y-t.height/2-t.padding/3+(y(m().flowchart.htmlLabels)?5:3))+")");const h=r.node().getBBox();return t.height=h.height,t.intersect=function(e){return p(t,e)},n},noteGroup:(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(e){return p(t,e)},n},divider:(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(e){return p(t,e)},n}};let F={};const k=async(e,t,n,r)=>{v.info("Graph in recursive render: XXX",N(t),r);const a=t.graph().rankdir;v.trace("Dir in recursive render - dir:",a);const f=e.insert("g").attr("class","root");t.nodes()?v.info("Recursive render XXX",t.nodes()):v.info("No nodes found for",t),t.edges().length>0&&v.trace("Recursive edges",t.edge(t.edges()[0]));const u=f.insert("g").attr("class","clusters"),w=f.insert("g").attr("class","edgePaths"),p=f.insert("g").attr("class","edgeLabels"),y=f.insert("g").attr("class","nodes");await Promise.all(t.nodes().map((async function(e){const i=t.node(e);if(void 0!==r){const n=JSON.parse(JSON.stringify(r.clusterData));v.info("Setting data for cluster XXX (",e,") ",n,r),t.setNode(r.id,n),t.parent(e)||(v.trace("Setting parent",e,r.id),t.setParent(e,r.id,n))}if(v.info("(Insert) Node XXX"+e+": "+JSON.stringify(t.node(e))),i&&i.clusterNode){v.info("Cluster identified",e,i.width,t.node(e));const r=await k(y,i.graph,n,t.node(e)),a=r.elem;d(i,a),i.diff=r.diff||0,v.info("Node bounds (abc123)",e,i,i.width,i.x,i.y),o(a,i),v.warn("Recursive render complete ",a,i)}else t.children(e).length>0?(v.info("Cluster - the non recursive path XXX",e,i.id,i,t),v.info(J(i.id,t)),S[i.id]={id:J(i.id,t),node:i}):(v.info("Node - the non recursive path",e,i.id,i),await s(y,t.node(e),a))}))),t.edges().forEach((function(e){const n=t.edge(e.v,e.w,e.name);v.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),v.info("Edge "+e.v+" -> "+e.w+": ",e," ",JSON.stringify(t.edge(e))),v.info("Fix",S,"ids:",e.v,e.w,"Translateing: ",S[e.v],S[e.w]),c(p,n)})),t.edges().forEach((function(e){v.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e))})),v.info("#############################################"),v.info("### Layout ###"),v.info("#############################################"),v.info(t),i(t),v.info("Graph after layout:",N(t));let m=0;return(e=>G(e,e.children()))(t).forEach((function(e){const n=t.node(e);v.info("Position "+e+": "+JSON.stringify(t.node(e))),v.info("Position "+e+": ("+n.x,","+n.y,") width: ",n.width," height: ",n.height),n&&n.clusterNode?l(n):t.children(e).length>0?(((e,t)=>{v.trace("Inserting cluster");const n=t.shape||"rect";F[t.id]=L[n](e,t)})(u,n),S[n.id].node=n):l(n)})),t.edges().forEach((function(e){const r=t.edge(e);v.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(r),r);const i=h(w,e,r,S,n,t);g(r,i)})),t.nodes().forEach((function(e){const n=t.node(e);v.info(e,n.type,n.diff),"group"===n.type&&(m=n.diff)})),{elem:f,diff:m}},P=async(e,t,n,r,i)=>{a(e,n,r,i),f(),u(),F={},C={},D={},S={},v.warn("Graph at first:",N(t)),((e,t)=>{!e||t>10?v.debug("Opting out, no graph "):(v.debug("Opting in, graph "),e.nodes().forEach((function(t){e.children(t).length>0&&(v.warn("Cluster identified",t," Replacement id in edges: ",J(t,e)),C[t]=T(t,e),S[t]={id:J(t,e),clusterData:e.node(t)})})),e.nodes().forEach((function(t){const n=e.children(t),r=e.edges();n.length>0?(v.debug("Cluster identified",t,C),r.forEach((e=>{e.v!==t&&e.w!==t&&O(e.v,t)^O(e.w,t)&&(v.warn("Edge: ",e," leaves cluster ",t),v.warn("Decendants of XXX ",t,": ",C[t]),S[t].externalConnections=!0)}))):v.debug("Not a cluster ",t,C)})),e.edges().forEach((function(t){const n=e.edge(t);v.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(t)),v.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(e.edge(t)));let r=t.v,i=t.w;if(v.warn("Fix XXX",S,"ids:",t.v,t.w,"Translating: ",S[t.v]," --- ",S[t.w]),S[t.v]&&S[t.w]&&S[t.v]===S[t.w]){v.warn("Fixing and trixing link to self - removing XXX",t.v,t.w,t.name),v.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=I(t.v),i=I(t.w),e.removeEdge(t.v,t.w,t.name);const a=t.w+"---"+t.v;e.setNode(a,{domId:a,id:a,labelStyle:"",labelText:n.label,padding:0,shape:"labelRect",style:""});const d=JSON.parse(JSON.stringify(n)),o=JSON.parse(JSON.stringify(n));d.label="",d.arrowTypeEnd="none",o.label="",d.fromCluster=t.v,o.toCluster=t.v,e.setEdge(r,a,d,t.name+"-cyclic-special"),e.setEdge(a,i,o,t.name+"-cyclic-special")}else(S[t.v]||S[t.w])&&(v.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=I(t.v),i=I(t.w),e.removeEdge(t.v,t.w,t.name),r!==t.v&&(n.fromCluster=t.v),i!==t.w&&(n.toCluster=t.w),v.warn("Fix Replacing with XXX",r,i,t.name),e.setEdge(r,i,n,t.name))})),v.warn("Adjusted Graph",N(e)),R(e,0),v.trace(S))})(t),v.warn("Graph after:",N(t)),await k(e,t,r)};export{P as r}; +import{b as e,m as t,a as n,G as r,l as i}from"./layout.02c3e151.js";import{i as a,u as d,s as o,a as s,b as c,p as l,c as h,d as g,e as f,f as u,g as w,h as p}from"./edges-97052da4.e255927b.js";import{l as v,q as y,c as m,h as x}from"./mermaid.core.3a590193.js";import{c as b}from"./createText-2f679d62.a374f608.js";function N(t){var r,i={options:{directed:t.isDirected(),multigraph:t.isMultigraph(),compound:t.isCompound()},nodes:X(t),edges:E(t)};return n(t.graph())||(i.value=(r=t.graph(),e(r,4))),i}function X(e){return t(e.nodes(),(function(t){var r=e.node(t),i=e.parent(t),a={v:t};return n(r)||(a.value=r),n(i)||(a.parent=i),a}))}function E(e){return t(e.edges(),(function(t){var r=e.edge(t),i={v:t.v,w:t.w};return n(t.name)||(i.name=t.name),n(r)||(i.value=r),i}))}let S={},C={},D={};const O=(e,t)=>(v.trace("In isDecendant",t," ",e," = ",C[t].includes(e)),!!C[t].includes(e)),B=(e,t,n,r)=>{v.warn("Copying children of ",e,"root",r,"data",t.node(e),r);const i=t.children(e)||[];e!==r&&i.push(e),v.warn("Copying (nodes) clusterId",e,"nodes",i),i.forEach((i=>{if(t.children(i).length>0)B(i,t,n,r);else{const a=t.node(i);v.info("cp ",i," to ",r," with parent ",e),n.setNode(i,a),r!==t.parent(i)&&(v.warn("Setting parent",i,t.parent(i)),n.setParent(i,t.parent(i))),e!==r&&i!==e?(v.debug("Setting parent",i,e),n.setParent(i,e)):(v.info("In copy ",e,"root",r,"data",t.node(e),r),v.debug("Not Setting parent for node=",i,"cluster!==rootId",e!==r,"node!==clusterId",i!==e));const d=t.edges(i);v.debug("Copying Edges",d),d.forEach((i=>{v.info("Edge",i);const a=t.edge(i.v,i.w,i.name);v.info("Edge data",a,r);try{((e,t)=>(v.info("Decendants of ",t," is ",C[t]),v.info("Edge is ",e),e.v!==t&&e.w!==t&&(C[t]?C[t].includes(e.v)||O(e.v,t)||O(e.w,t)||C[t].includes(e.w):(v.debug("Tilt, ",t,",not in decendants"),!1))))(i,r)?(v.info("Copying as ",i.v,i.w,a,i.name),n.setEdge(i.v,i.w,a,i.name),v.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]))):v.info("Skipping copy of edge ",i.v,"--\x3e",i.w," rootId: ",r," clusterId:",e)}catch(d){v.error(d)}}))}v.debug("Removing node",i),t.removeNode(i)}))},T=(e,t)=>{const n=t.children(e);let r=[...n];for(const i of n)D[i]=e,r=[...r,...T(i,t)];return r},J=(e,t)=>{v.trace("Searching",e);const n=t.children(e);if(v.trace("Searching children of id ",e,n),n.length<1)return v.trace("This is a valid node",e),e;for(const r of n){const n=J(r,t);if(n)return v.trace("Found replacement for",e," => ",n),n}},I=e=>S[e]&&S[e].externalConnections&&S[e]?S[e].id:e,R=(e,t)=>{if(v.warn("extractor - ",t,N(e),e.children("D")),t>10)return void v.error("Bailing out");let n=e.nodes(),i=!1;for(const r of n){const t=e.children(r);i=i||t.length>0}if(i){v.debug("Nodes = ",n,t);for(const i of n)if(v.debug("Extracting node",i,S,S[i]&&!S[i].externalConnections,!e.parent(i),e.node(i),e.children("D")," Depth ",t),S[i])if(!S[i].externalConnections&&e.children(i)&&e.children(i).length>0){v.warn("Cluster without external connections, without a parent and with children",i,t);let n="TB"===e.graph().rankdir?"LR":"TB";S[i]&&S[i].clusterData&&S[i].clusterData.dir&&(n=S[i].clusterData.dir,v.warn("Fixing dir",S[i].clusterData.dir,n));const a=new r({multigraph:!0,compound:!0}).setGraph({rankdir:n,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));v.warn("Old graph before copy",N(e)),B(i,e,a,i),e.setNode(i,{clusterNode:!0,id:i,clusterData:S[i].clusterData,labelText:S[i].labelText,graph:a}),v.warn("New graph after copy node: (",i,")",N(a)),v.debug("Old graph after copy",N(e))}else v.warn("Cluster ** ",i," **not meeting the criteria !externalConnections:",!S[i].externalConnections," no parent: ",!e.parent(i)," children ",e.children(i)&&e.children(i).length>0,e.children("D"),t),v.debug(S);else v.debug("Not a cluster",i,t);n=e.nodes(),v.warn("New list of nodes",n);for(const r of n){const n=e.node(r);v.warn(" Now next level",r,n),n.clusterNode&&R(n.graph,t+1)}}else v.debug("Done, no node has children",e.nodes())},G=(e,t)=>{if(0===t.length)return[];let n=Object.assign(t);return t.forEach((t=>{const r=e.children(t),i=G(e,r);n=[...n,...i]})),n},L={rect:(e,t)=>{v.info("Creating subgraph rect for ",t.id,t);const n=e.insert("g").attr("class","cluster"+(t.class?" "+t.class:"")).attr("id",t.id),r=n.insert("rect",":first-child"),i=y(m().flowchart.htmlLabels),a=n.insert("g").attr("class","cluster-label"),d="markdown"===t.labelType?b(a,t.labelText,{style:t.labelStyle,useHtmlLabels:i}):a.node().appendChild(w(t.labelText,t.labelStyle,void 0,!0));let o=d.getBBox();if(y(m().flowchart.htmlLabels)){const e=d.children[0],t=x(d);o=e.getBoundingClientRect(),t.attr("width",o.width),t.attr("height",o.height)}const s=0*t.padding,c=s/2,l=t.width<=o.width+s?o.width+s:t.width;t.width<=o.width+s?t.diff=(o.width-t.width)/2-t.padding/2:t.diff=-t.padding/2,v.trace("Data ",t,JSON.stringify(t)),r.attr("style",t.style).attr("rx",t.rx).attr("ry",t.ry).attr("x",t.x-l/2).attr("y",t.y-t.height/2-c).attr("width",l).attr("height",t.height+s),i?a.attr("transform","translate("+(t.x-o.width/2)+", "+(t.y-t.height/2)+")"):a.attr("transform","translate("+t.x+", "+(t.y-t.height/2)+")");const h=r.node().getBBox();return t.width=h.width,t.height=h.height,t.intersect=function(e){return p(t,e)},n},roundedWithTitle:(e,t)=>{const n=e.insert("g").attr("class",t.classes).attr("id",t.id),r=n.insert("rect",":first-child"),i=n.insert("g").attr("class","cluster-label"),a=n.append("rect"),d=i.node().appendChild(w(t.labelText,t.labelStyle,void 0,!0));let o=d.getBBox();if(y(m().flowchart.htmlLabels)){const e=d.children[0],t=x(d);o=e.getBoundingClientRect(),t.attr("width",o.width),t.attr("height",o.height)}o=d.getBBox();const s=0*t.padding,c=s/2,l=t.width<=o.width+t.padding?o.width+t.padding:t.width;t.width<=o.width+t.padding?t.diff=(o.width+0*t.padding-t.width)/2:t.diff=-t.padding/2,r.attr("class","outer").attr("x",t.x-l/2-c).attr("y",t.y-t.height/2-c).attr("width",l+s).attr("height",t.height+s),a.attr("class","inner").attr("x",t.x-l/2-c).attr("y",t.y-t.height/2-c+o.height-1).attr("width",l+s).attr("height",t.height+s-o.height-3),i.attr("transform","translate("+(t.x-o.width/2)+", "+(t.y-t.height/2-t.padding/3+(y(m().flowchart.htmlLabels)?5:3))+")");const h=r.node().getBBox();return t.height=h.height,t.intersect=function(e){return p(t,e)},n},noteGroup:(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(e){return p(t,e)},n},divider:(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(e){return p(t,e)},n}};let F={};const k=async(e,t,n,r)=>{v.info("Graph in recursive render: XXX",N(t),r);const a=t.graph().rankdir;v.trace("Dir in recursive render - dir:",a);const f=e.insert("g").attr("class","root");t.nodes()?v.info("Recursive render XXX",t.nodes()):v.info("No nodes found for",t),t.edges().length>0&&v.trace("Recursive edges",t.edge(t.edges()[0]));const u=f.insert("g").attr("class","clusters"),w=f.insert("g").attr("class","edgePaths"),p=f.insert("g").attr("class","edgeLabels"),y=f.insert("g").attr("class","nodes");await Promise.all(t.nodes().map((async function(e){const i=t.node(e);if(void 0!==r){const n=JSON.parse(JSON.stringify(r.clusterData));v.info("Setting data for cluster XXX (",e,") ",n,r),t.setNode(r.id,n),t.parent(e)||(v.trace("Setting parent",e,r.id),t.setParent(e,r.id,n))}if(v.info("(Insert) Node XXX"+e+": "+JSON.stringify(t.node(e))),i&&i.clusterNode){v.info("Cluster identified",e,i.width,t.node(e));const r=await k(y,i.graph,n,t.node(e)),a=r.elem;d(i,a),i.diff=r.diff||0,v.info("Node bounds (abc123)",e,i,i.width,i.x,i.y),o(a,i),v.warn("Recursive render complete ",a,i)}else t.children(e).length>0?(v.info("Cluster - the non recursive path XXX",e,i.id,i,t),v.info(J(i.id,t)),S[i.id]={id:J(i.id,t),node:i}):(v.info("Node - the non recursive path",e,i.id,i),await s(y,t.node(e),a))}))),t.edges().forEach((function(e){const n=t.edge(e.v,e.w,e.name);v.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),v.info("Edge "+e.v+" -> "+e.w+": ",e," ",JSON.stringify(t.edge(e))),v.info("Fix",S,"ids:",e.v,e.w,"Translateing: ",S[e.v],S[e.w]),c(p,n)})),t.edges().forEach((function(e){v.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e))})),v.info("#############################################"),v.info("### Layout ###"),v.info("#############################################"),v.info(t),i(t),v.info("Graph after layout:",N(t));let m=0;return(e=>G(e,e.children()))(t).forEach((function(e){const n=t.node(e);v.info("Position "+e+": "+JSON.stringify(t.node(e))),v.info("Position "+e+": ("+n.x,","+n.y,") width: ",n.width," height: ",n.height),n&&n.clusterNode?l(n):t.children(e).length>0?(((e,t)=>{v.trace("Inserting cluster");const n=t.shape||"rect";F[t.id]=L[n](e,t)})(u,n),S[n.id].node=n):l(n)})),t.edges().forEach((function(e){const r=t.edge(e);v.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(r),r);const i=h(w,e,r,S,n,t);g(r,i)})),t.nodes().forEach((function(e){const n=t.node(e);v.info(e,n.type,n.diff),"group"===n.type&&(m=n.diff)})),{elem:f,diff:m}},P=async(e,t,n,r,i)=>{a(e,n,r,i),f(),u(),F={},C={},D={},S={},v.warn("Graph at first:",N(t)),((e,t)=>{!e||t>10?v.debug("Opting out, no graph "):(v.debug("Opting in, graph "),e.nodes().forEach((function(t){e.children(t).length>0&&(v.warn("Cluster identified",t," Replacement id in edges: ",J(t,e)),C[t]=T(t,e),S[t]={id:J(t,e),clusterData:e.node(t)})})),e.nodes().forEach((function(t){const n=e.children(t),r=e.edges();n.length>0?(v.debug("Cluster identified",t,C),r.forEach((e=>{e.v!==t&&e.w!==t&&O(e.v,t)^O(e.w,t)&&(v.warn("Edge: ",e," leaves cluster ",t),v.warn("Decendants of XXX ",t,": ",C[t]),S[t].externalConnections=!0)}))):v.debug("Not a cluster ",t,C)})),e.edges().forEach((function(t){const n=e.edge(t);v.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(t)),v.warn("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(e.edge(t)));let r=t.v,i=t.w;if(v.warn("Fix XXX",S,"ids:",t.v,t.w,"Translating: ",S[t.v]," --- ",S[t.w]),S[t.v]&&S[t.w]&&S[t.v]===S[t.w]){v.warn("Fixing and trixing link to self - removing XXX",t.v,t.w,t.name),v.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=I(t.v),i=I(t.w),e.removeEdge(t.v,t.w,t.name);const a=t.w+"---"+t.v;e.setNode(a,{domId:a,id:a,labelStyle:"",labelText:n.label,padding:0,shape:"labelRect",style:""});const d=JSON.parse(JSON.stringify(n)),o=JSON.parse(JSON.stringify(n));d.label="",d.arrowTypeEnd="none",o.label="",d.fromCluster=t.v,o.toCluster=t.v,e.setEdge(r,a,d,t.name+"-cyclic-special"),e.setEdge(a,i,o,t.name+"-cyclic-special")}else(S[t.v]||S[t.w])&&(v.warn("Fixing and trixing - removing XXX",t.v,t.w,t.name),r=I(t.v),i=I(t.w),e.removeEdge(t.v,t.w,t.name),r!==t.v&&(n.fromCluster=t.v),i!==t.w&&(n.toCluster=t.w),v.warn("Fix Replacing with XXX",r,i,t.name),e.setEdge(r,i,n,t.name))})),v.warn("Adjusted Graph",N(e)),R(e,0),v.trace(S))})(t),v.warn("Graph after:",N(t)),await k(e,t,r)};export{P as r}; diff --git a/assets/index.html.00a37cb7.js b/assets/index.html.00a37cb7.js new file mode 100644 index 000000000..8337b914b --- /dev/null +++ b/assets/index.html.00a37cb7.js @@ -0,0 +1 @@ +import{r as e,o as l,c as t,a,b as n,w as u,F as c,e as o}from"./app.48111a85.js";const r={},h=a("h1",{id:"小小白白话文",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#小小白白话文","aria-hidden":"true"},"#"),o(" 小小白白话文")],-1),d=a("p",null,[a("strong",null,"这个章节是【从零开始】的基础课,新来的同学好好看好好学哦")],-1),s={class:"custom-container tip"},p=a("p",{class:"custom-container-title"},"提示",-1),i=o("Made with ❤️ by "),m={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},f=o("@ricuhkaen"),v=o("【第 1 章】 前言罗嗦篇"),_=o(" - 机场还是自建?这是个问题"),b=o("【第 2 章】 原料准备篇"),y=o(" - 工欲善其事,必先利其器"),k=o("【第 3 章】 远程登录篇"),x=o(" - 一桥飞架南北,天堑变通途"),g=o("【第 4 章】 安全防护篇"),w=o(" - 安全不注意,亲人两行泪"),L=o("【第 5 章】 网站建设篇"),X=o(" - 秀出你的美"),j=o("【第 6 章】 证书管理篇"),F=o(" - 领证的才是合法的"),M=o("【第 7 章】 Xray 服务器篇"),O=o(" - 终于等到你"),R=o("【第 8 章】 Xray 客户端篇"),q=o(" - 新的开始"),z=o("【第 9 章】 附录"),A=o(" - 考点都在这里");r.render=function(o,r){const B=e("OutboundLink"),C=e("RouterLink");return l(),t(c,null,[h,d,a("div",s,[p,a("p",null,[i,a("a",m,[f,n(B)])])]),a("p",null,[n(C,{to:"/document/level-0/ch01-preface.html"},{default:u((()=>[v])),_:1}),_]),a("p",null,[n(C,{to:"/document/level-0/ch02-preparation.html"},{default:u((()=>[b])),_:1}),y]),a("p",null,[n(C,{to:"/document/level-0/ch03-ssh.html"},{default:u((()=>[k])),_:1}),x]),a("p",null,[n(C,{to:"/document/level-0/ch04-security.html"},{default:u((()=>[g])),_:1}),w]),a("p",null,[n(C,{to:"/document/level-0/ch05-webpage.html"},{default:u((()=>[L])),_:1}),X]),a("p",null,[n(C,{to:"/document/level-0/ch06-certificates.html"},{default:u((()=>[j])),_:1}),F]),a("p",null,[n(C,{to:"/document/level-0/ch07-xray-server.html"},{default:u((()=>[M])),_:1}),O]),a("p",null,[n(C,{to:"/document/level-0/ch08-xray-clients.html"},{default:u((()=>[R])),_:1}),q]),a("p",null,[n(C,{to:"/document/level-0/ch09-appendix.html"},{default:u((()=>[z])),_:1}),A])],64)};export default r; diff --git a/assets/index.html.1b035654.js b/assets/index.html.1b035654.js deleted file mode 100644 index 539453dee..000000000 --- a/assets/index.html.1b035654.js +++ /dev/null @@ -1 +0,0 @@ -import{r as e,o as l,c as t,a as n,b as a,w as u,F as c,e as o}from"./app.755d843f.js";const r={},d=n("h1",{id:"小小白白话文",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#小小白白话文","aria-hidden":"true"},"#"),o(" 小小白白话文")],-1),h=n("p",null,[n("strong",null,"这个章节是【从零开始】的基础课,新来的同学好好看好好学哦")],-1),s={class:"custom-container tip"},p=n("p",{class:"custom-container-title"},"提示",-1),i=o("Made with ❤️ by "),m={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},f=o("@ricuhkaen"),v=o("【第 1 章】 前言罗嗦篇"),_=o(" - 机场还是自建?这是个问题"),b=o("【第 2 章】 原料准备篇"),y=o(" - 工欲善其事,必先利其器"),k=o("【第 3 章】 远程登录篇"),x=o(" - 一桥飞架南北,天堑变通途"),g=o("【第 4 章】 安全防护篇"),w=o(" - 安全不注意,亲人两行泪"),L=o("【第 5 章】 网站建设篇"),X=o(" - 秀出你的美"),j=o("【第 6 章】 证书管理篇"),F=o(" - 领证的才是合法的"),M=o("【第 7 章】 Xray 服务器篇"),O=o(" - 终于等到你"),R=o("【第 8 章】 Xray 客户端篇"),q=o(" - 新的开始"),z=o("【第 9 章】 附录"),A=o(" - 考点都在这里");r.render=function(o,r){const B=e("OutboundLink"),C=e("RouterLink");return l(),t(c,null,[d,h,n("div",s,[p,n("p",null,[i,n("a",m,[f,a(B)])])]),n("p",null,[a(C,{to:"/document/level-0/ch01-preface.html"},{default:u((()=>[v])),_:1}),_]),n("p",null,[a(C,{to:"/document/level-0/ch02-preparation.html"},{default:u((()=>[b])),_:1}),y]),n("p",null,[a(C,{to:"/document/level-0/ch03-ssh.html"},{default:u((()=>[k])),_:1}),x]),n("p",null,[a(C,{to:"/document/level-0/ch04-security.html"},{default:u((()=>[g])),_:1}),w]),n("p",null,[a(C,{to:"/document/level-0/ch05-webpage.html"},{default:u((()=>[L])),_:1}),X]),n("p",null,[a(C,{to:"/document/level-0/ch06-certificates.html"},{default:u((()=>[j])),_:1}),F]),n("p",null,[a(C,{to:"/document/level-0/ch07-xray-server.html"},{default:u((()=>[M])),_:1}),O]),n("p",null,[a(C,{to:"/document/level-0/ch08-xray-clients.html"},{default:u((()=>[R])),_:1}),q]),n("p",null,[a(C,{to:"/document/level-0/ch09-appendix.html"},{default:u((()=>[z])),_:1}),A])],64)};export default r; diff --git a/assets/index.html.db4f3080.js b/assets/index.html.27162517.js similarity index 98% rename from assets/index.html.db4f3080.js rename to assets/index.html.27162517.js index dc6756f1b..57e149e4e 100644 --- a/assets/index.html.db4f3080.js +++ b/assets/index.html.27162517.js @@ -1 +1 @@ -import{r as e,o as a,c as r,a as l,b as t,w as d,F as n,e as o}from"./app.755d843f.js";const h={},s=l("h1",{id:"开发指南",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#开发指南","aria-hidden":"true"},"#"),o(" 开发指南")],-1),i=l("h2",{id:"编译文档",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#编译文档","aria-hidden":"true"},"#"),o(" 编译文档")],-1),u=l("p",null,"Xray 支持各种平台, 您可以在多种平台上自行进行交叉编译。",-1),c=o("请点击"),p=o("编译文档"),m=o("以查看具体编译相关内容。"),f=l("h2",{id:"设计思路",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#设计思路","aria-hidden":"true"},"#"),o(" 设计思路")],-1),x=l("p",null,"Xray 内核提供了一个平台,在其之上可以进二次开发。",-1),b=l("p",null,"这个章节阐述了 Xray 的设计目标和架构。",-1),v=o("请点击"),y=o("设计思路"),k=o("以了解 Xray 的设计目标和架构。"),X=l("h2",{id:"开发规范",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#开发规范","aria-hidden":"true"},"#"),o(" 开发规范")],-1),_=l("p",null,"这个章节阐述了获取代码,进行开发,提交 PR 的流程中需要遵循的准则, 以及相关的编码规范。",-1),C=o("请点击"),g=o("开发规范"),L=o("查看 Xray 开发中应遵循的准则。"),M=l("h2",{id:"协议详解",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#协议详解","aria-hidden":"true"},"#"),o(" 协议详解")],-1),P=l("p",null,"Xray 用到了很多种协议, 您可以通过各种途径获得协议的详细描述。",-1),S={id:"vless-协议",tabindex:"-1"},V=l("a",{class:"header-anchor",href:"#vless-协议","aria-hidden":"true"},"#",-1),K=o(),w=o("VLESS 协议"),E=l("p",null,"VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。",-1),R={id:"vmess-协议",tabindex:"-1"},j=l("a",{class:"header-anchor",href:"#vmess-协议","aria-hidden":"true"},"#",-1),F=o(),O=o("VMess 协议"),q=l("p",null,"VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。",-1),z={id:"mux-cool-协议",tabindex:"-1"},A=l("a",{class:"header-anchor",href:"#mux-cool-协议","aria-hidden":"true"},"#",-1),B=o(),D=o("Mux.Cool 协议"),G=l("p",null,"Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。",-1),H={id:"mkcp-协议",tabindex:"-1"},I=l("a",{class:"header-anchor",href:"#mkcp-协议","aria-hidden":"true"},"#",-1),J=o(),N=o("mKCP 协议"),Q=o("mKCP 是流式传输协议,由 "),T={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},U=o("KCP 协议"),W=o("修改而来,可以按顺序传输任意的数据流。");h.render=function(o,h){const Y=e("RouterLink"),Z=e("OutboundLink");return a(),r(n,null,[s,i,u,l("p",null,[c,t(Y,{to:"/development/intro/compile.html"},{default:d((()=>[p])),_:1}),m]),f,x,b,l("p",null,[v,t(Y,{to:"/development/intro/design.html"},{default:d((()=>[y])),_:1}),k]),X,_,l("p",null,[C,t(Y,{to:"/development/intro/guide.html"},{default:d((()=>[g])),_:1}),L]),M,P,l("h3",S,[V,K,t(Y,{to:"/development/protocols/vless.html"},{default:d((()=>[w])),_:1})]),E,l("h3",R,[j,F,t(Y,{to:"/development/protocols/vmess.html"},{default:d((()=>[O])),_:1})]),q,l("h3",z,[A,B,t(Y,{to:"/development/protocols/muxcool.html"},{default:d((()=>[D])),_:1})]),G,l("h3",H,[I,J,t(Y,{to:"/development/protocols/mkcp.html"},{default:d((()=>[N])),_:1})]),l("p",null,[Q,l("a",T,[U,t(Z)]),W])],64)};export default h; +import{r as e,o as a,c as r,a as l,b as t,w as d,F as n,e as o}from"./app.48111a85.js";const h={},s=l("h1",{id:"开发指南",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#开发指南","aria-hidden":"true"},"#"),o(" 开发指南")],-1),i=l("h2",{id:"编译文档",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#编译文档","aria-hidden":"true"},"#"),o(" 编译文档")],-1),u=l("p",null,"Xray 支持各种平台, 您可以在多种平台上自行进行交叉编译。",-1),c=o("请点击"),p=o("编译文档"),m=o("以查看具体编译相关内容。"),f=l("h2",{id:"设计思路",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#设计思路","aria-hidden":"true"},"#"),o(" 设计思路")],-1),x=l("p",null,"Xray 内核提供了一个平台,在其之上可以进二次开发。",-1),b=l("p",null,"这个章节阐述了 Xray 的设计目标和架构。",-1),v=o("请点击"),y=o("设计思路"),k=o("以了解 Xray 的设计目标和架构。"),X=l("h2",{id:"开发规范",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#开发规范","aria-hidden":"true"},"#"),o(" 开发规范")],-1),_=l("p",null,"这个章节阐述了获取代码,进行开发,提交 PR 的流程中需要遵循的准则, 以及相关的编码规范。",-1),C=o("请点击"),g=o("开发规范"),L=o("查看 Xray 开发中应遵循的准则。"),M=l("h2",{id:"协议详解",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#协议详解","aria-hidden":"true"},"#"),o(" 协议详解")],-1),P=l("p",null,"Xray 用到了很多种协议, 您可以通过各种途径获得协议的详细描述。",-1),S={id:"vless-协议",tabindex:"-1"},V=l("a",{class:"header-anchor",href:"#vless-协议","aria-hidden":"true"},"#",-1),K=o(),w=o("VLESS 协议"),E=l("p",null,"VLESS 是一个无状态的轻量传输协议,可以作为 Xray 客户端和服务器之间的桥梁。",-1),R={id:"vmess-协议",tabindex:"-1"},j=l("a",{class:"header-anchor",href:"#vmess-协议","aria-hidden":"true"},"#",-1),F=o(),O=o("VMess 协议"),q=l("p",null,"VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。",-1),z={id:"mux-cool-协议",tabindex:"-1"},A=l("a",{class:"header-anchor",href:"#mux-cool-协议","aria-hidden":"true"},"#",-1),B=o(),D=o("Mux.Cool 协议"),G=l("p",null,"Mux.Cool 协议是一个多路复用传输协议,用于在一条已建立的数据流中传输多个各自独立的数据流。",-1),H={id:"mkcp-协议",tabindex:"-1"},I=l("a",{class:"header-anchor",href:"#mkcp-协议","aria-hidden":"true"},"#",-1),J=o(),N=o("mKCP 协议"),Q=o("mKCP 是流式传输协议,由 "),T={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},U=o("KCP 协议"),W=o("修改而来,可以按顺序传输任意的数据流。");h.render=function(o,h){const Y=e("RouterLink"),Z=e("OutboundLink");return a(),r(n,null,[s,i,u,l("p",null,[c,t(Y,{to:"/development/intro/compile.html"},{default:d((()=>[p])),_:1}),m]),f,x,b,l("p",null,[v,t(Y,{to:"/development/intro/design.html"},{default:d((()=>[y])),_:1}),k]),X,_,l("p",null,[C,t(Y,{to:"/development/intro/guide.html"},{default:d((()=>[g])),_:1}),L]),M,P,l("h3",S,[V,K,t(Y,{to:"/development/protocols/vless.html"},{default:d((()=>[w])),_:1})]),E,l("h3",R,[j,F,t(Y,{to:"/development/protocols/vmess.html"},{default:d((()=>[O])),_:1})]),q,l("h3",z,[A,B,t(Y,{to:"/development/protocols/muxcool.html"},{default:d((()=>[D])),_:1})]),G,l("h3",H,[I,J,t(Y,{to:"/development/protocols/mkcp.html"},{default:d((()=>[N])),_:1})]),l("p",null,[Q,l("a",T,[U,t(Z)]),W])],64)};export default h; diff --git a/assets/index.html.1aea56f1.js b/assets/index.html.28e6f320.js similarity index 98% rename from assets/index.html.1aea56f1.js rename to assets/index.html.28e6f320.js index de14626a5..ec178fbf1 100644 --- a/assets/index.html.1aea56f1.js +++ b/assets/index.html.28e6f320.js @@ -1 +1 @@ -import{r as t,o as r,c as e,a,b as n,w as l,F as o,e as u}from"./app.755d843f.js";const h={},i=a("h1",{id:"进阶文档",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#进阶文档","aria-hidden":"true"},"#"),u(" 进阶文档")],-1),s=a("p",null,[a("strong",null,"这个章节包含进阶级的 Xray 使用心得分享, 如果您已经熟悉 Xray, 那么这里的经验可以让您更加发挥 Xray 的威力")],-1),p=u("透明代理入门"),m=u(" by "),c=a("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),g=u(),d={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},b=u("@kirin"),y=a("p",null,"透明代理的入门篇章。",-1),f=u("透明代理(TProxy)配置教程 "),_=u(" by "),v=a("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32",height:"32",alt:"a"},null,-1),x=u(),k={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},X=u("@BioniCosmos"),w=a("p",null,"基于 Xray 的透明代理(TProxy)配置完整教程。",-1),L=u("TProxy 透明代理(ipv4 and ipv6)配置教程"),T=u(" by "),S=a("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),z=u(),P={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},Q=u("@SQLimit"),C=a("p",null,"基于 Xray 的 TProxy 透明代理(ipv4 and ipv6)配置教程",-1),B=u("Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹"),H=u(" by "),N=a("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),W=u(),Z={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},j=u("@SQLimit"),F=a("p",null,"双端使用 Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹",-1),G=u("[透明代理]通过 gid 规避 Xray 流量"),O=u(" by "),R=a("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),q=u(),A={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},D=u("@kirin"),E=a("p",null,"在 iptables/nftables 实现的透明代理中,一种新的规避 Xray 流量的方式。",-1),I=u("通过 Xray 将特定的流量指向特定出口,实现全局路由“分流”"),J=u(" by "),K=a("img",{src:"https://avatars.githubusercontent.com/u/28607089?s=32",width:"32",height:"32",alt:"a"},null,-1),M=u(),U={href:"https://github.com/Zzz3m",target:"_blank",rel:"noopener noreferrer"},V=u("@Zzz3m"),Y=a("p",null,"将 Xray 玩出花:基于 fwmark 或 sendThrough 方式实现“分流”。",-1),$=u("通过 Cloudflare Warp 增强代理安全性"),tt=u(" by "),rt=a("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),et=u(),at={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},nt=u("@yuhan6665"),lt=a("p",null,"Xray v1.6.5 新增 WireGuard 出站的使用介绍。",-1),ot=u("Xray 流量统计"),ut=u(" by "),ht=a("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),it=u(),st={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},pt=u("@yuhan6665"),mt=a("p",null,"适配 Xray 的流量统计和脚本。",-1);h.render=function(u,h){const ct=t("RouterLink"),gt=t("OutboundLink");return r(),e(o,null,[i,s,a("p",null,[n(ct,{to:"/document/level-2/transparent_proxy/transparent_proxy.html"},{default:l((()=>[p])),_:1}),m,c,g,a("a",d,[b,n(gt)])]),y,a("p",null,[n(ct,{to:"/document/level-2/tproxy.html"},{default:l((()=>[f])),_:1}),_,v,x,a("a",k,[X,n(gt)])]),w,a("p",null,[n(ct,{to:"/document/level-2/tproxy_ipv4_and_ipv6.html"},{default:l((()=>[L])),_:1}),T,S,z,a("a",P,[Q,n(gt)])]),C,a("p",null,[n(ct,{to:"/document/level-2/nginx_or_haproxy_tls_tunnel.html"},{default:l((()=>[B])),_:1}),H,N,W,a("a",Z,[j,n(gt)])]),F,a("p",null,[n(ct,{to:"/document/level-2/iptables_gid.html"},{default:l((()=>[G])),_:1}),O,R,q,a("a",A,[D,n(gt)])]),E,a("p",null,[n(ct,{to:"/document/level-2/redirect.html"},{default:l((()=>[I])),_:1}),J,K,M,a("a",U,[V,n(gt)])]),Y,a("p",null,[n(ct,{to:"/document/level-2/warp.html"},{default:l((()=>[$])),_:1}),tt,rt,et,a("a",at,[nt,n(gt)])]),lt,a("p",null,[n(ct,{to:"/document/level-2/traffic_stats.html"},{default:l((()=>[ot])),_:1}),ut,ht,it,a("a",st,[pt,n(gt)])]),mt],64)};export default h; +import{r as t,o as r,c as e,a,b as n,w as l,F as o,e as u}from"./app.48111a85.js";const h={},i=a("h1",{id:"进阶文档",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#进阶文档","aria-hidden":"true"},"#"),u(" 进阶文档")],-1),s=a("p",null,[a("strong",null,"这个章节包含进阶级的 Xray 使用心得分享, 如果您已经熟悉 Xray, 那么这里的经验可以让您更加发挥 Xray 的威力")],-1),p=u("透明代理入门"),m=u(" by "),c=a("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),g=u(),d={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},b=u("@kirin"),y=a("p",null,"透明代理的入门篇章。",-1),f=u("透明代理(TProxy)配置教程 "),_=u(" by "),v=a("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32",height:"32",alt:"a"},null,-1),x=u(),k={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},X=u("@BioniCosmos"),w=a("p",null,"基于 Xray 的透明代理(TProxy)配置完整教程。",-1),L=u("TProxy 透明代理(ipv4 and ipv6)配置教程"),T=u(" by "),S=a("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),z=u(),P={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},Q=u("@SQLimit"),C=a("p",null,"基于 Xray 的 TProxy 透明代理(ipv4 and ipv6)配置教程",-1),B=u("Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹"),H=u(" by "),N=a("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),W=u(),Z={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},j=u("@SQLimit"),F=a("p",null,"双端使用 Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹",-1),G=u("[透明代理]通过 gid 规避 Xray 流量"),O=u(" by "),R=a("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),q=u(),A={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},D=u("@kirin"),E=a("p",null,"在 iptables/nftables 实现的透明代理中,一种新的规避 Xray 流量的方式。",-1),I=u("通过 Xray 将特定的流量指向特定出口,实现全局路由“分流”"),J=u(" by "),K=a("img",{src:"https://avatars.githubusercontent.com/u/28607089?s=32",width:"32",height:"32",alt:"a"},null,-1),M=u(),U={href:"https://github.com/Zzz3m",target:"_blank",rel:"noopener noreferrer"},V=u("@Zzz3m"),Y=a("p",null,"将 Xray 玩出花:基于 fwmark 或 sendThrough 方式实现“分流”。",-1),$=u("通过 Cloudflare Warp 增强代理安全性"),tt=u(" by "),rt=a("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),et=u(),at={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},nt=u("@yuhan6665"),lt=a("p",null,"Xray v1.6.5 新增 WireGuard 出站的使用介绍。",-1),ot=u("Xray 流量统计"),ut=u(" by "),ht=a("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),it=u(),st={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},pt=u("@yuhan6665"),mt=a("p",null,"适配 Xray 的流量统计和脚本。",-1);h.render=function(u,h){const ct=t("RouterLink"),gt=t("OutboundLink");return r(),e(o,null,[i,s,a("p",null,[n(ct,{to:"/document/level-2/transparent_proxy/transparent_proxy.html"},{default:l((()=>[p])),_:1}),m,c,g,a("a",d,[b,n(gt)])]),y,a("p",null,[n(ct,{to:"/document/level-2/tproxy.html"},{default:l((()=>[f])),_:1}),_,v,x,a("a",k,[X,n(gt)])]),w,a("p",null,[n(ct,{to:"/document/level-2/tproxy_ipv4_and_ipv6.html"},{default:l((()=>[L])),_:1}),T,S,z,a("a",P,[Q,n(gt)])]),C,a("p",null,[n(ct,{to:"/document/level-2/nginx_or_haproxy_tls_tunnel.html"},{default:l((()=>[B])),_:1}),H,N,W,a("a",Z,[j,n(gt)])]),F,a("p",null,[n(ct,{to:"/document/level-2/iptables_gid.html"},{default:l((()=>[G])),_:1}),O,R,q,a("a",A,[D,n(gt)])]),E,a("p",null,[n(ct,{to:"/document/level-2/redirect.html"},{default:l((()=>[I])),_:1}),J,K,M,a("a",U,[V,n(gt)])]),Y,a("p",null,[n(ct,{to:"/document/level-2/warp.html"},{default:l((()=>[$])),_:1}),tt,rt,et,a("a",at,[nt,n(gt)])]),lt,a("p",null,[n(ct,{to:"/document/level-2/traffic_stats.html"},{default:l((()=>[ot])),_:1}),ut,ht,it,a("a",st,[pt,n(gt)])]),mt],64)};export default h; diff --git a/assets/index.html.8808c83d.js b/assets/index.html.3fde6881.js similarity index 98% rename from assets/index.html.8808c83d.js rename to assets/index.html.3fde6881.js index d2bf0c738..24097bc80 100644 --- a/assets/index.html.8808c83d.js +++ b/assets/index.html.3fde6881.js @@ -1 +1 @@ -import{r as e,o,c as t,a,b as n,w as r,F as l,e as s}from"./app.755d843f.js";const i={},d=a("h1",{id:"development-guide",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#development-guide","aria-hidden":"true"},"#"),s(" Development Guide")],-1),c=a("h2",{id:"compile-documentation",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#compile-documentation","aria-hidden":"true"},"#"),s(" Compile Documentation")],-1),p=a("p",null,"Xray supports multiple platforms, and you can perform cross-compilation on various platforms by yourself.",-1),h=s("Please click "),u=s("Compile Documentation"),m=s(" to view specific compile-related content."),f=a("h2",{id:"design-concept",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#design-concept","aria-hidden":"true"},"#"),s(" Design Concept")],-1),v=a("p",null,"Xray kernel provides a platform for secondary development.",-1),g=a("p",null,"This section explains the design goals and architecture of Xray.",-1),b=s("Please click "),x=s("Design Principles"),y=s(" to learn about the design goals and architecture of Xray."),P=a("h2",{id:"development-standards",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#development-standards","aria-hidden":"true"},"#"),s(" Development Standards")],-1),k=a("p",null,"This section outlines the guidelines to follow when obtaining code, developing, submitting PRs, as well as the relevant coding standards.",-1),w=s("Please click "),C=s("Development Specification"),D=s(" to view the guidelines that should be followed during Xray development."),X=a("h2",{id:"protocol-details",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#protocol-details","aria-hidden":"true"},"#"),s(" Protocol Details")],-1),_=a("p",null,"Xray uses many protocols, and you can obtain a detailed description of each protocol through various means.",-1),S={id:"vless-protocol",tabindex:"-1"},L=a("a",{class:"header-anchor",href:"#vless-protocol","aria-hidden":"true"},"#",-1),M=s(),V=s("VLESS Protocol"),K=a("p",null,"VLESS is a stateless lightweight transport protocol that can serve as a bridge between Xray clients and servers.",-1),E={id:"vmess-protocol",tabindex:"-1"},R=a("a",{class:"header-anchor",href:"#vmess-protocol","aria-hidden":"true"},"#",-1),T=s(),j=s("VMess Protocol"),F=a("p",null,"VMess is an encrypted transport protocol that can act as a bridge between Xray clients and servers.",-1),G={id:"mux-cool-protocol",tabindex:"-1"},O=a("a",{class:"header-anchor",href:"#mux-cool-protocol","aria-hidden":"true"},"#",-1),q=s(),z=s("Mux.Cool Protocol"),A=a("p",null,"Mux.Cool protocol is a multiplexing transport protocol used to transmit multiple independent data streams within an established data stream.",-1),B={id:"mkcp-protocol",tabindex:"-1"},H=a("a",{class:"header-anchor",href:"#mkcp-protocol","aria-hidden":"true"},"#",-1),I=s(),J=s("mKCP Protocol"),N=s("mKCP is a stream transmission protocol modified from the "),Q={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},U=s("KCP protocol"),W=s(" that can transmit arbitrary data streams in order.");i.render=function(s,i){const Y=e("RouterLink"),Z=e("OutboundLink");return o(),t(l,null,[d,c,p,a("p",null,[h,n(Y,{to:"/en/development/intro/compile.html"},{default:r((()=>[u])),_:1}),m]),f,v,g,a("p",null,[b,n(Y,{to:"/en/development/intro/design.html"},{default:r((()=>[x])),_:1}),y]),P,k,a("p",null,[w,n(Y,{to:"/en/development/intro/guide.html"},{default:r((()=>[C])),_:1}),D]),X,_,a("h3",S,[L,M,n(Y,{to:"/en/development/protocols/vless.html"},{default:r((()=>[V])),_:1})]),K,a("h3",E,[R,T,n(Y,{to:"/en/development/protocols/vmess.html"},{default:r((()=>[j])),_:1})]),F,a("h3",G,[O,q,n(Y,{to:"/en/development/protocols/muxcool.html"},{default:r((()=>[z])),_:1})]),A,a("h3",B,[H,I,n(Y,{to:"/en/development/protocols/mkcp.html"},{default:r((()=>[J])),_:1})]),a("p",null,[N,a("a",Q,[U,n(Z)]),W])],64)};export default i; +import{r as e,o,c as t,a,b as n,w as r,F as l,e as s}from"./app.48111a85.js";const i={},d=a("h1",{id:"development-guide",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#development-guide","aria-hidden":"true"},"#"),s(" Development Guide")],-1),c=a("h2",{id:"compile-documentation",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#compile-documentation","aria-hidden":"true"},"#"),s(" Compile Documentation")],-1),p=a("p",null,"Xray supports multiple platforms, and you can perform cross-compilation on various platforms by yourself.",-1),h=s("Please click "),u=s("Compile Documentation"),m=s(" to view specific compile-related content."),f=a("h2",{id:"design-concept",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#design-concept","aria-hidden":"true"},"#"),s(" Design Concept")],-1),v=a("p",null,"Xray kernel provides a platform for secondary development.",-1),g=a("p",null,"This section explains the design goals and architecture of Xray.",-1),b=s("Please click "),x=s("Design Principles"),y=s(" to learn about the design goals and architecture of Xray."),P=a("h2",{id:"development-standards",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#development-standards","aria-hidden":"true"},"#"),s(" Development Standards")],-1),k=a("p",null,"This section outlines the guidelines to follow when obtaining code, developing, submitting PRs, as well as the relevant coding standards.",-1),w=s("Please click "),C=s("Development Specification"),D=s(" to view the guidelines that should be followed during Xray development."),X=a("h2",{id:"protocol-details",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#protocol-details","aria-hidden":"true"},"#"),s(" Protocol Details")],-1),_=a("p",null,"Xray uses many protocols, and you can obtain a detailed description of each protocol through various means.",-1),S={id:"vless-protocol",tabindex:"-1"},L=a("a",{class:"header-anchor",href:"#vless-protocol","aria-hidden":"true"},"#",-1),M=s(),V=s("VLESS Protocol"),K=a("p",null,"VLESS is a stateless lightweight transport protocol that can serve as a bridge between Xray clients and servers.",-1),E={id:"vmess-protocol",tabindex:"-1"},R=a("a",{class:"header-anchor",href:"#vmess-protocol","aria-hidden":"true"},"#",-1),T=s(),j=s("VMess Protocol"),F=a("p",null,"VMess is an encrypted transport protocol that can act as a bridge between Xray clients and servers.",-1),G={id:"mux-cool-protocol",tabindex:"-1"},O=a("a",{class:"header-anchor",href:"#mux-cool-protocol","aria-hidden":"true"},"#",-1),q=s(),z=s("Mux.Cool Protocol"),A=a("p",null,"Mux.Cool protocol is a multiplexing transport protocol used to transmit multiple independent data streams within an established data stream.",-1),B={id:"mkcp-protocol",tabindex:"-1"},H=a("a",{class:"header-anchor",href:"#mkcp-protocol","aria-hidden":"true"},"#",-1),I=s(),J=s("mKCP Protocol"),N=s("mKCP is a stream transmission protocol modified from the "),Q={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},U=s("KCP protocol"),W=s(" that can transmit arbitrary data streams in order.");i.render=function(s,i){const Y=e("RouterLink"),Z=e("OutboundLink");return o(),t(l,null,[d,c,p,a("p",null,[h,n(Y,{to:"/en/development/intro/compile.html"},{default:r((()=>[u])),_:1}),m]),f,v,g,a("p",null,[b,n(Y,{to:"/en/development/intro/design.html"},{default:r((()=>[x])),_:1}),y]),P,k,a("p",null,[w,n(Y,{to:"/en/development/intro/guide.html"},{default:r((()=>[C])),_:1}),D]),X,_,a("h3",S,[L,M,n(Y,{to:"/en/development/protocols/vless.html"},{default:r((()=>[V])),_:1})]),K,a("h3",E,[R,T,n(Y,{to:"/en/development/protocols/vmess.html"},{default:r((()=>[j])),_:1})]),F,a("h3",G,[O,q,n(Y,{to:"/en/development/protocols/muxcool.html"},{default:r((()=>[z])),_:1})]),A,a("h3",B,[H,I,n(Y,{to:"/en/development/protocols/mkcp.html"},{default:r((()=>[J])),_:1})]),a("p",null,[N,a("a",Q,[U,n(Z)]),W])],64)};export default i; diff --git a/assets/index.html.3a5eaf89.js b/assets/index.html.5ad65f6a.js similarity index 94% rename from assets/index.html.3a5eaf89.js rename to assets/index.html.5ad65f6a.js index 5e093e704..df8f373e7 100644 --- a/assets/index.html.3a5eaf89.js +++ b/assets/index.html.5ad65f6a.js @@ -1 +1 @@ -import{r as e,o as r,c as a,a as l,b as t,w as n,F as i,d as o,e as s}from"./app.755d843f.js";const u={},h=o('

    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),c=l("li",null,"🖥️ 帮助开发和测试 Xray, 提交高质量的 Pull request.",-1),d=s("📩 在 "),p={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},X=s("GitHub Issues"),b=s(" 或 "),f={href:"https://github.com/XTLS/Xray-core/discussions",target:"_blank",rel:"noopener noreferrer"},g=s("讨论区"),y=s("发起建设性或有意义的 issue 与 discussion."),m=s("📝 写下您的使用心得并提交至 Xray 的 "),x={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},L=s("文档网站"),S=s("."),k=l("li",null,"💬 在 Telegram 群帮助群友/灌水.",-1),T=l("li",null,[l("strong",null,"...事实上,每一份对 Xray 的支持都会让 Xray 变得更强大")],-1),j=l("h3",{id:"telegram",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#telegram","aria-hidden":"true"},"#"),s(" Telegram")],-1),v={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},w=s("Project X 交流群"),_=l("ul",null,[l("li",null,"交流群可在底线之上随便水,不要撕逼,没有滥权。"),l("li",null,"有问题尽管随便问,知道的尽量回答。"),l("li",null,"禁政治,禁 NSFW")],-1),P={href:"https://t.me/projectXtls",target:"_blank",rel:"noopener noreferrer"},q=s("Project X 频道"),z=l("ul",null,[l("li",null,"发布 Project X 的最新资讯")],-1),R=l("h3",{id:"致谢",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#致谢","aria-hidden":"true"},"#"),s(" 致谢")],-1),V=l("ul",null,[l("li",null,"感谢所有人的支持!"),l("li",null,"感谢各类脚本、Docker 镜像、客户端支持...感谢所有帮忙完善生态的大佬们!"),l("li",null,"感谢为 Xray 网站和文档添砖加瓦的朋友们."),l("li",null,"感谢提出有意义的建议和意见的朋友们."),l("li",null,"感谢 Telegram 群每一位帮助群友的朋友.")],-1),I=l("h3",{id:"更多关于-project-x",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#更多关于-project-x","aria-hidden":"true"},"#"),s(" 更多关于 project X")],-1),E=s("如果你想知道更多关于 project X 的足迹与成长, 请点击"),A=s("这里"),F=l("h3",{id:"license",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#license","aria-hidden":"true"},"#"),s(" License")],-1),N={href:"https://github.com/XTLS/Xray-core/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"},W=s("Mozilla Public License Version 2.0"),C=l("h3",{id:"stargazers-over-time",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#stargazers-over-time","aria-hidden":"true"},"#"),s(" Stargazers over time")],-1),D={href:"https://starchart.cc/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},G=l("img",{src:"https://starchart.cc/XTLS/Xray-core.svg",alt:"Stargazers over time"},null,-1);u.render=function(o,s){const u=e("OutboundLink"),H=e("RouterLink");return r(),a(i,null,[h,l("ul",null,[c,l("li",null,[d,l("a",p,[X,t(u)]),b,l("a",f,[g,t(u)]),y]),l("li",null,[m,l("a",x,[L,t(u)]),S]),k,T]),j,l("ul",null,[l("li",null,[l("p",null,[l("a",v,[w,t(u)])]),_]),l("li",null,[l("p",null,[l("a",P,[q,t(u)])]),z])]),R,V,I,l("ul",null,[l("li",null,[E,t(H,{to:"/about/news.html"},{default:n((()=>[A])),_:1})])]),F,l("p",null,[l("a",N,[W,t(u)])]),C,l("p",null,[l("a",D,[G,t(u)])])],64)};export default u; +import{r as e,o as r,c as a,a as l,b as t,w as n,F as i,d as o,e as s}from"./app.48111a85.js";const u={},h=o('

    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),c=l("li",null,"🖥️ 帮助开发和测试 Xray, 提交高质量的 Pull request.",-1),d=s("📩 在 "),p={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},X=s("GitHub Issues"),b=s(" 或 "),g={href:"https://github.com/XTLS/Xray-core/discussions",target:"_blank",rel:"noopener noreferrer"},f=s("讨论区"),y=s("发起建设性或有意义的 issue 与 discussion."),m=s("📝 写下您的使用心得并提交至 Xray 的 "),x={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},L=s("文档网站"),S=s("."),k=l("li",null,"💬 在 Telegram 群帮助群友/灌水.",-1),T=l("li",null,[l("strong",null,"...事实上,每一份对 Xray 的支持都会让 Xray 变得更强大")],-1),j=l("h3",{id:"telegram",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#telegram","aria-hidden":"true"},"#"),s(" Telegram")],-1),v={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},w=s("Project X 交流群"),_=l("ul",null,[l("li",null,"交流群可在底线之上随便水,不要撕逼,没有滥权。"),l("li",null,"有问题尽管随便问,知道的尽量回答。"),l("li",null,"禁政治,禁 NSFW")],-1),P={href:"https://t.me/projectXtls",target:"_blank",rel:"noopener noreferrer"},q=s("Project X 频道"),z=l("ul",null,[l("li",null,"发布 Project X 的最新资讯")],-1),R=l("h3",{id:"致谢",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#致谢","aria-hidden":"true"},"#"),s(" 致谢")],-1),V=l("ul",null,[l("li",null,"感谢所有人的支持!"),l("li",null,"感谢各类脚本、Docker 镜像、客户端支持...感谢所有帮忙完善生态的大佬们!"),l("li",null,"感谢为 Xray 网站和文档添砖加瓦的朋友们."),l("li",null,"感谢提出有意义的建议和意见的朋友们."),l("li",null,"感谢 Telegram 群每一位帮助群友的朋友.")],-1),I=l("h3",{id:"更多关于-project-x",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#更多关于-project-x","aria-hidden":"true"},"#"),s(" 更多关于 project X")],-1),E=s("如果你想知道更多关于 project X 的足迹与成长, 请点击"),A=s("这里"),F=l("h3",{id:"license",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#license","aria-hidden":"true"},"#"),s(" License")],-1),N={href:"https://github.com/XTLS/Xray-core/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"},W=s("Mozilla Public License Version 2.0"),C=l("h3",{id:"stargazers-over-time",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#stargazers-over-time","aria-hidden":"true"},"#"),s(" Stargazers over time")],-1),D={href:"https://starchart.cc/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},G=l("img",{src:"https://starchart.cc/XTLS/Xray-core.svg",alt:"Stargazers over time"},null,-1);u.render=function(o,s){const u=e("OutboundLink"),H=e("RouterLink");return r(),a(i,null,[h,l("ul",null,[c,l("li",null,[d,l("a",p,[X,t(u)]),b,l("a",g,[f,t(u)]),y]),l("li",null,[m,l("a",x,[L,t(u)]),S]),k,T]),j,l("ul",null,[l("li",null,[l("p",null,[l("a",v,[w,t(u)])]),_]),l("li",null,[l("p",null,[l("a",P,[q,t(u)])]),z])]),R,V,I,l("ul",null,[l("li",null,[E,t(H,{to:"/about/news.html"},{default:n((()=>[A])),_:1})])]),F,l("p",null,[l("a",N,[W,t(u)])]),C,l("p",null,[l("a",D,[G,t(u)])])],64)};export default u; diff --git a/assets/index.html.773aa27d.js b/assets/index.html.5cc51c88.js similarity index 97% rename from assets/index.html.773aa27d.js rename to assets/index.html.5cc51c88.js index a82e613c4..9090c2b02 100644 --- a/assets/index.html.773aa27d.js +++ b/assets/index.html.5cc51c88.js @@ -1 +1 @@ -import{r as e,o as t,c as a,a as n,b as l,w as r,F as o,e as i}from"./app.755d843f.js";const u={},s=n("h1",{id:"plain-and-simple-language",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#plain-and-simple-language","aria-hidden":"true"},"#"),i(" Plain and Simple Language")],-1),c=n("p",null,[n("strong",null,"This chapter is a basic lesson of [Starting from Scratch]. New students, please watch and learn carefully.")],-1),h={class:"custom-container tip"},p=n("p",{class:"custom-container-title"},"Tip",-1),d=i("Made with ❤️ by "),f={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},m=i("@ricuhkaen"),g=i("【Chapter 1】 Preface: Rambling"),y=i(" - Airport or Self-built? That is the question."),b=i("Chapter 2: Preparation of Raw Materials"),C=i(" - Tools must be sharpened before they can be used proficiently."),v=i("Chapter 3: Remote Login"),w=i(" - A bridge connecting the north and south, turning a natural obstacle into a thoroughfare."),_=i("【Chapter 4】Security Protection"),S=i(" - If you don't pay attention to security, you will shed tears for your loved ones."),k=n("p",null,"[【Chapter 5】Website Construction] - Show Your Beauty (Link to webpage.md file)",-1),x=i("Chapter 6: Certificate Management"),A=i(" - Only those who obtain certificates are considered legitimate."),L=i("Chapter 7: Xray Server"),P=i(" - Finally, waited for you."),R=i("Chapter 8: Xray Client"),T=i(" - A New Beginning."),M=n("p",null,"[Chapter 9] Appendix - All the exam points are here.",-1);u.render=function(i,u){const B=e("OutboundLink"),F=e("RouterLink");return t(),a(o,null,[s,c,n("div",h,[p,n("p",null,[d,n("a",f,[m,l(B)])])]),n("p",null,[l(F,{to:"/en/document/level-0/ch01-preface.html"},{default:r((()=>[g])),_:1}),y]),n("p",null,[l(F,{to:"/en/document/level-0/ch02-preparation.html"},{default:r((()=>[b])),_:1}),C]),n("p",null,[l(F,{to:"/en/document/level-0/ch03-ssh.html"},{default:r((()=>[v])),_:1}),w]),n("p",null,[l(F,{to:"/en/document/level-0/ch04-security.html"},{default:r((()=>[_])),_:1}),S]),k,n("p",null,[l(F,{to:"/en/document/level-0/ch06-certificates.html"},{default:r((()=>[x])),_:1}),A]),n("p",null,[l(F,{to:"/en/document/level-0/ch07-xray-server.html"},{default:r((()=>[L])),_:1}),P]),n("p",null,[l(F,{to:"/en/document/level-0/ch08-xray-clients.html"},{default:r((()=>[R])),_:1}),T]),M],64)};export default u; +import{r as e,o as t,c as a,a as n,b as l,w as r,F as o,e as i}from"./app.48111a85.js";const u={},s=n("h1",{id:"plain-and-simple-language",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#plain-and-simple-language","aria-hidden":"true"},"#"),i(" Plain and Simple Language")],-1),c=n("p",null,[n("strong",null,"This chapter is a basic lesson of [Starting from Scratch]. New students, please watch and learn carefully.")],-1),h={class:"custom-container tip"},p=n("p",{class:"custom-container-title"},"Tip",-1),d=i("Made with ❤️ by "),f={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},m=i("@ricuhkaen"),g=i("【Chapter 1】 Preface: Rambling"),y=i(" - Airport or Self-built? That is the question."),b=i("Chapter 2: Preparation of Raw Materials"),C=i(" - Tools must be sharpened before they can be used proficiently."),v=i("Chapter 3: Remote Login"),w=i(" - A bridge connecting the north and south, turning a natural obstacle into a thoroughfare."),_=i("【Chapter 4】Security Protection"),S=i(" - If you don't pay attention to security, you will shed tears for your loved ones."),k=n("p",null,"[【Chapter 5】Website Construction] - Show Your Beauty (Link to webpage.md file)",-1),x=i("Chapter 6: Certificate Management"),A=i(" - Only those who obtain certificates are considered legitimate."),L=i("Chapter 7: Xray Server"),P=i(" - Finally, waited for you."),R=i("Chapter 8: Xray Client"),T=i(" - A New Beginning."),M=n("p",null,"[Chapter 9] Appendix - All the exam points are here.",-1);u.render=function(i,u){const B=e("OutboundLink"),F=e("RouterLink");return t(),a(o,null,[s,c,n("div",h,[p,n("p",null,[d,n("a",f,[m,l(B)])])]),n("p",null,[l(F,{to:"/en/document/level-0/ch01-preface.html"},{default:r((()=>[g])),_:1}),y]),n("p",null,[l(F,{to:"/en/document/level-0/ch02-preparation.html"},{default:r((()=>[b])),_:1}),C]),n("p",null,[l(F,{to:"/en/document/level-0/ch03-ssh.html"},{default:r((()=>[v])),_:1}),w]),n("p",null,[l(F,{to:"/en/document/level-0/ch04-security.html"},{default:r((()=>[_])),_:1}),S]),k,n("p",null,[l(F,{to:"/en/document/level-0/ch06-certificates.html"},{default:r((()=>[x])),_:1}),A]),n("p",null,[l(F,{to:"/en/document/level-0/ch07-xray-server.html"},{default:r((()=>[L])),_:1}),P]),n("p",null,[l(F,{to:"/en/document/level-0/ch08-xray-clients.html"},{default:r((()=>[R])),_:1}),T]),M],64)};export default u; diff --git a/assets/index.html.e33f1535.js b/assets/index.html.69a05f19.js similarity index 94% rename from assets/index.html.e33f1535.js rename to assets/index.html.69a05f19.js index ced04a0aa..8756c70cb 100644 --- a/assets/index.html.e33f1535.js +++ b/assets/index.html.69a05f19.js @@ -1 +1 @@ -import{r as t,o as e,c as n,a as r,b as a,w as o,F as i,e as l}from"./app.755d843f.js";const u={},s=r("h1",{id:"advanced-documentation",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#advanced-documentation","aria-hidden":"true"},"#"),l(" Advanced Documentation")],-1),h=r("p",null,[r("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),c=l("Beginner's Guide to Transparent Proxies"),p=l(" by "),d=r("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),g=l(),f={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},m=l("@kirin"),b=r("p",null,"An Introduction to Transparent Proxies.",-1),y=l("TProxy Configuration Tutorial"),v=l(" by "),_=r("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32",height:"32",alt:"a"},null,-1),x=l(),T={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},w=l("@BioniCosmos"),k=r("p",null,"Complete tutorial on configuring transparent proxy (TProxy) based on Xray.",-1),P=l("TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial"),X=l(" by "),S=r("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),L=l(),I={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},C=l("@SQLimit"),A=r("p",null,"Xray-based TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial",-1),z=l("Nginx_TLS Tunnel Hidden Fingerprint"),B=l(" by "),G=r("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),Q=l(),N={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},R=l("@SQLimit"),F=r("p",null,"Use Nginx_TLS tunnel on both ends to hide the fingerprint.",-1),W=l("[Transparent Proxy] Avoiding Xray Traffic Through gid"),Z=l(" by "),j=r("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),D=l(),E={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},H=l("@kirin"),O=r("p",null,"A new way of bypassing Xray traffic in transparent proxy implemented by iptables/nftables.",-1),U=l('Redirect Specific Traffic to Specific Gateway using Xray to Achieve Global Routing "Load Balancing"'),q=l(" by "),J=r("img",{src:"https://avatars.githubusercontent.com/u/28607089?s=32",width:"32",height:"32",alt:"a"},null,-1),K=l(),M={href:"https://github.com/Zzz3m",target:"_blank",rel:"noopener noreferrer"},V=l("@Zzz3m"),Y=r("p",null,'Play Xray to the fullest: Implement "load balancing" based on fwmark or sendThrough.',-1),$=l("Enhancing Proxy Security with Cloudflare Warp"),tt=l(" by "),et=r("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),nt=l(),rt={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},at=l("@yuhan6665"),ot=r("p",null,"Introduction to using WireGuard for outbound traffic added in Xray v1.6.5.",-1),it=l("Xray Traffic Statistics"),lt=l(" by "),ut=r("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),st=l(),ht={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},ct=l("@yuhan6665"),pt=r("p",null,"Adapt traffic statistics and scripts compatible with Xray.",-1);u.render=function(l,u){const dt=t("RouterLink"),gt=t("OutboundLink");return e(),n(i,null,[s,h,r("p",null,[a(dt,{to:"/en/document/level-2/transparent_proxy/transparent_proxy.html"},{default:o((()=>[c])),_:1}),p,d,g,r("a",f,[m,a(gt)])]),b,r("p",null,[a(dt,{to:"/en/document/level-2/tproxy.html"},{default:o((()=>[y])),_:1}),v,_,x,r("a",T,[w,a(gt)])]),k,r("p",null,[a(dt,{to:"/en/document/level-2/tproxy_ipv4_and_ipv6.html"},{default:o((()=>[P])),_:1}),X,S,L,r("a",I,[C,a(gt)])]),A,r("p",null,[a(dt,{to:"/en/document/level-2/Nginx_TLS_tunnel.html"},{default:o((()=>[z])),_:1}),B,G,Q,r("a",N,[R,a(gt)])]),F,r("p",null,[a(dt,{to:"/en/document/level-2/iptables_gid.html"},{default:o((()=>[W])),_:1}),Z,j,D,r("a",E,[H,a(gt)])]),O,r("p",null,[a(dt,{to:"/en/document/level-2/redirect.html"},{default:o((()=>[U])),_:1}),q,J,K,r("a",M,[V,a(gt)])]),Y,r("p",null,[a(dt,{to:"/en/document/level-2/warp.html"},{default:o((()=>[$])),_:1}),tt,et,nt,r("a",rt,[at,a(gt)])]),ot,r("p",null,[a(dt,{to:"/en/document/level-2/traffic_stats.html"},{default:o((()=>[it])),_:1}),lt,ut,st,r("a",ht,[ct,a(gt)])]),pt],64)};export default u; +import{r as t,o as e,c as n,a as r,b as a,w as o,F as i,e as l}from"./app.48111a85.js";const u={},s=r("h1",{id:"advanced-documentation",tabindex:"-1"},[r("a",{class:"header-anchor",href:"#advanced-documentation","aria-hidden":"true"},"#"),l(" Advanced Documentation")],-1),h=r("p",null,[r("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),c=l("Beginner's Guide to Transparent Proxies"),p=l(" by "),d=r("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),g=l(),m={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},f=l("@kirin"),b=r("p",null,"An Introduction to Transparent Proxies.",-1),y=l("TProxy Configuration Tutorial"),v=l(" by "),_=r("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32",height:"32",alt:"a"},null,-1),x=l(),T={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},w=l("@BioniCosmos"),k=r("p",null,"Complete tutorial on configuring transparent proxy (TProxy) based on Xray.",-1),P=l("TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial"),X=l(" by "),S=r("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),L=l(),I={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},C=l("@SQLimit"),A=r("p",null,"Xray-based TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial",-1),z=l("Nginx_TLS Tunnel Hidden Fingerprint"),B=l(" by "),G=r("img",{src:"https://avatars.githubusercontent.com/u/110686480?s=32",width:"32",height:"32",alt:"a"},null,-1),Q=l(),N={href:"https://github.com/SQLimit",target:"_blank",rel:"noopener noreferrer"},R=l("@SQLimit"),F=r("p",null,"Use Nginx_TLS tunnel on both ends to hide the fingerprint.",-1),W=l("[Transparent Proxy] Avoiding Xray Traffic Through gid"),Z=l(" by "),j=r("img",{src:"https://avatars2.githubusercontent.com/u/57820613?s=32",width:"32",height:"32",alt:"a"},null,-1),D=l(),E={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},H=l("@kirin"),O=r("p",null,"A new way of bypassing Xray traffic in transparent proxy implemented by iptables/nftables.",-1),U=l('Redirect Specific Traffic to Specific Gateway using Xray to Achieve Global Routing "Load Balancing"'),q=l(" by "),J=r("img",{src:"https://avatars.githubusercontent.com/u/28607089?s=32",width:"32",height:"32",alt:"a"},null,-1),K=l(),M={href:"https://github.com/Zzz3m",target:"_blank",rel:"noopener noreferrer"},V=l("@Zzz3m"),Y=r("p",null,'Play Xray to the fullest: Implement "load balancing" based on fwmark or sendThrough.',-1),$=l("Enhancing Proxy Security with Cloudflare Warp"),tt=l(" by "),et=r("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),nt=l(),rt={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},at=l("@yuhan6665"),ot=r("p",null,"Introduction to using WireGuard for outbound traffic added in Xray v1.6.5.",-1),it=l("Xray Traffic Statistics"),lt=l(" by "),ut=r("img",{src:"https://avatars.githubusercontent.com/u/1588741?s=32",width:"32",height:"32",alt:"a"},null,-1),st=l(),ht={href:"https://github.com/yuhan6665",target:"_blank",rel:"noopener noreferrer"},ct=l("@yuhan6665"),pt=r("p",null,"Adapt traffic statistics and scripts compatible with Xray.",-1);u.render=function(l,u){const dt=t("RouterLink"),gt=t("OutboundLink");return e(),n(i,null,[s,h,r("p",null,[a(dt,{to:"/en/document/level-2/transparent_proxy/transparent_proxy.html"},{default:o((()=>[c])),_:1}),p,d,g,r("a",m,[f,a(gt)])]),b,r("p",null,[a(dt,{to:"/en/document/level-2/tproxy.html"},{default:o((()=>[y])),_:1}),v,_,x,r("a",T,[w,a(gt)])]),k,r("p",null,[a(dt,{to:"/en/document/level-2/tproxy_ipv4_and_ipv6.html"},{default:o((()=>[P])),_:1}),X,S,L,r("a",I,[C,a(gt)])]),A,r("p",null,[a(dt,{to:"/en/document/level-2/Nginx_TLS_tunnel.html"},{default:o((()=>[z])),_:1}),B,G,Q,r("a",N,[R,a(gt)])]),F,r("p",null,[a(dt,{to:"/en/document/level-2/iptables_gid.html"},{default:o((()=>[W])),_:1}),Z,j,D,r("a",E,[H,a(gt)])]),O,r("p",null,[a(dt,{to:"/en/document/level-2/redirect.html"},{default:o((()=>[U])),_:1}),q,J,K,r("a",M,[V,a(gt)])]),Y,r("p",null,[a(dt,{to:"/en/document/level-2/warp.html"},{default:o((()=>[$])),_:1}),tt,et,nt,r("a",rt,[at,a(gt)])]),ot,r("p",null,[a(dt,{to:"/en/document/level-2/traffic_stats.html"},{default:o((()=>[it])),_:1}),lt,ut,st,r("a",ht,[ct,a(gt)])]),pt],64)};export default u; diff --git a/assets/index.html.f6be7756.js b/assets/index.html.7bcc5e57.js similarity index 99% rename from assets/index.html.f6be7756.js rename to assets/index.html.7bcc5e57.js index 4ef41fed0..fce437293 100644 --- a/assets/index.html.f6be7756.js +++ b/assets/index.html.7bcc5e57.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as t,b as o,w as e,F as p,d as l,e as u}from"./app.755d843f.js";const c={},r=l('

    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:

    {\n  "log": {},\n  "api": {},\n  "dns": {},\n  "routing": {},\n  "policy": {},\n  "inbounds": [],\n  "outbounds": [],\n  "transport": {},\n  "stats": {},\n  "reverse": {},\n  "fakedns": {}\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ',4),i={class:"custom-container warning"},d=t("p",{class:"custom-container-title"},"Warning",-1),f=u("If you are new to Xray, you can first click to view "),k=u("configuration and running in the Quick Start guide"),b=u(", to learn the most basic configuration method, and then refer to the contents of this section to master all the configuration methods of Xray."),h=t("h2",{id:"basic-configuration-modules",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#basic-configuration-modules","aria-hidden":"true"},"#"),u(" Basic Configuration Modules")],-1),g=u("log:"),m=u("LogObject"),y=t("p",null,"Log configuration, which controls the way Xray outputs logs.",-1),q=u("api:"),v=u("ApiObject"),w=t("p",null,"Provides some API interfaces for remote calls.",-1),j=u("dns: "),O=u("DnsObject"),_=t("p",null,"Built-in DNS server. If this item is not configured, the system's DNS settings will be used.",-1),x=u("routing: "),X=u("RoutingObject"),I=t("p",null,"Routing function. You can set rules to route data to different outbounds.",-1),S=u("policy: "),D=u("PolicyObject"),R=t("p",null,"Local policy, which can set different user levels and corresponding policy settings.",-1),A=u("inbounds: [ "),L=u("InboundObject"),N=u(" ]"),B=t("p",null,"An array, with each element being an inbound connection configuration.",-1),F=u("outbounds: [ "),P=u("OutboundObject"),T=u(" ]"),U=t("p",null,"An array, with each element being an outbound connection configuration.",-1),Y=u("transport: "),C=u("TransportObject"),J=t("p",null,"Used to configure the way Xray establishes and uses network connections with other servers.",-1),M=u("stats: "),Q=u("StatsObject"),W=t("p",null,"Used to configure traffic data statistics.",-1),z=u("reverse: "),E=u("ReverseObject"),G=t("p",null,"Reverse proxy. You can forward server-side traffic to the client, that is, reverse traffic forwarding.",-1),H=u("fakedns: "),K=u("FakeDnsObject"),V=t("p",null,"FakeDNS configuration. It can be used with transparent proxy to obtain the actual domain name.",-1);c.render=function(l,u){const c=n("RouterLink");return s(),a(p,null,[r,t("div",i,[d,t("p",null,[f,o(c,{to:"/en/document/install.html"},{default:e((()=>[k])),_:1}),b])]),h,t("blockquote",null,[t("p",null,[g,o(c,{to:"/en/config/log.html"},{default:e((()=>[m])),_:1})])]),y,t("blockquote",null,[t("p",null,[q,o(c,{to:"/en/config/api.html"},{default:e((()=>[v])),_:1})])]),w,t("blockquote",null,[t("p",null,[j,o(c,{to:"/en/config/dns.html"},{default:e((()=>[O])),_:1})])]),_,t("blockquote",null,[t("p",null,[x,o(c,{to:"/en/config/routing.html"},{default:e((()=>[X])),_:1})])]),I,t("blockquote",null,[t("p",null,[S,o(c,{to:"/en/config/policy.html"},{default:e((()=>[D])),_:1})])]),R,t("blockquote",null,[t("p",null,[A,o(c,{to:"/en/config/inbound.html"},{default:e((()=>[L])),_:1}),N])]),B,t("blockquote",null,[t("p",null,[F,o(c,{to:"/en/config/outbound.html"},{default:e((()=>[P])),_:1}),T])]),U,t("blockquote",null,[t("p",null,[Y,o(c,{to:"/en/config/transport.html"},{default:e((()=>[C])),_:1})])]),J,t("blockquote",null,[t("p",null,[M,o(c,{to:"/en/config/stats.html"},{default:e((()=>[Q])),_:1})])]),W,t("blockquote",null,[t("p",null,[z,o(c,{to:"/en/config/reverse.html"},{default:e((()=>[E])),_:1})])]),G,t("blockquote",null,[t("p",null,[H,o(c,{to:"/en/config/fakedns.html"},{default:e((()=>[K])),_:1})])]),V],64)};export default c; +import{r as n,o as s,c as a,a as t,b as o,w as e,F as p,d as l,e as u}from"./app.48111a85.js";const c={},r=l('

    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:

    {\n  "log": {},\n  "api": {},\n  "dns": {},\n  "routing": {},\n  "policy": {},\n  "inbounds": [],\n  "outbounds": [],\n  "transport": {},\n  "stats": {},\n  "reverse": {},\n  "fakedns": {}\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ',4),i={class:"custom-container warning"},d=t("p",{class:"custom-container-title"},"Warning",-1),f=u("If you are new to Xray, you can first click to view "),k=u("configuration and running in the Quick Start guide"),b=u(", to learn the most basic configuration method, and then refer to the contents of this section to master all the configuration methods of Xray."),h=t("h2",{id:"basic-configuration-modules",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#basic-configuration-modules","aria-hidden":"true"},"#"),u(" Basic Configuration Modules")],-1),g=u("log:"),m=u("LogObject"),y=t("p",null,"Log configuration, which controls the way Xray outputs logs.",-1),q=u("api:"),v=u("ApiObject"),w=t("p",null,"Provides some API interfaces for remote calls.",-1),j=u("dns: "),O=u("DnsObject"),_=t("p",null,"Built-in DNS server. If this item is not configured, the system's DNS settings will be used.",-1),x=u("routing: "),X=u("RoutingObject"),I=t("p",null,"Routing function. You can set rules to route data to different outbounds.",-1),S=u("policy: "),D=u("PolicyObject"),R=t("p",null,"Local policy, which can set different user levels and corresponding policy settings.",-1),A=u("inbounds: [ "),L=u("InboundObject"),N=u(" ]"),B=t("p",null,"An array, with each element being an inbound connection configuration.",-1),F=u("outbounds: [ "),P=u("OutboundObject"),T=u(" ]"),U=t("p",null,"An array, with each element being an outbound connection configuration.",-1),Y=u("transport: "),C=u("TransportObject"),J=t("p",null,"Used to configure the way Xray establishes and uses network connections with other servers.",-1),M=u("stats: "),Q=u("StatsObject"),W=t("p",null,"Used to configure traffic data statistics.",-1),z=u("reverse: "),E=u("ReverseObject"),G=t("p",null,"Reverse proxy. You can forward server-side traffic to the client, that is, reverse traffic forwarding.",-1),H=u("fakedns: "),K=u("FakeDnsObject"),V=t("p",null,"FakeDNS configuration. It can be used with transparent proxy to obtain the actual domain name.",-1);c.render=function(l,u){const c=n("RouterLink");return s(),a(p,null,[r,t("div",i,[d,t("p",null,[f,o(c,{to:"/en/document/install.html"},{default:e((()=>[k])),_:1}),b])]),h,t("blockquote",null,[t("p",null,[g,o(c,{to:"/en/config/log.html"},{default:e((()=>[m])),_:1})])]),y,t("blockquote",null,[t("p",null,[q,o(c,{to:"/en/config/api.html"},{default:e((()=>[v])),_:1})])]),w,t("blockquote",null,[t("p",null,[j,o(c,{to:"/en/config/dns.html"},{default:e((()=>[O])),_:1})])]),_,t("blockquote",null,[t("p",null,[x,o(c,{to:"/en/config/routing.html"},{default:e((()=>[X])),_:1})])]),I,t("blockquote",null,[t("p",null,[S,o(c,{to:"/en/config/policy.html"},{default:e((()=>[D])),_:1})])]),R,t("blockquote",null,[t("p",null,[A,o(c,{to:"/en/config/inbound.html"},{default:e((()=>[L])),_:1}),N])]),B,t("blockquote",null,[t("p",null,[F,o(c,{to:"/en/config/outbound.html"},{default:e((()=>[P])),_:1}),T])]),U,t("blockquote",null,[t("p",null,[Y,o(c,{to:"/en/config/transport.html"},{default:e((()=>[C])),_:1})])]),J,t("blockquote",null,[t("p",null,[M,o(c,{to:"/en/config/stats.html"},{default:e((()=>[Q])),_:1})])]),W,t("blockquote",null,[t("p",null,[z,o(c,{to:"/en/config/reverse.html"},{default:e((()=>[E])),_:1})])]),G,t("blockquote",null,[t("p",null,[H,o(c,{to:"/en/config/fakedns.html"},{default:e((()=>[K])),_:1})])]),V],64)};export default c; diff --git a/assets/index.html.7fe27d11.js b/assets/index.html.92468ffc.js similarity index 98% rename from assets/index.html.7fe27d11.js rename to assets/index.html.92468ffc.js index a1cec6389..9a999179a 100644 --- a/assets/index.html.7fe27d11.js +++ b/assets/index.html.92468ffc.js @@ -1 +1 @@ -import{r as e,o as a,c as n,a as t,b as r,w as o,F as i,e as l}from"./app.755d843f.js";const d={},s=t("h1",{id:"quick-start",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#quick-start","aria-hidden":"true"},"#"),l(" Quick Start")],-1),u=t("blockquote",null,[t("p",null,[t("strong",null,"This chapter will tell you how to get Xray in the easiest way and start using Xray.")])],-1),c=t("h2",{id:"download-and-install",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#download-and-install","aria-hidden":"true"},"#"),l(" Download and Install")],-1),h=t("p",null,"Xray supports various platforms, and you can get various versions of Xray from various sources and methods.",-1),m=l("Please click "),p=l("How to Download and Install Xray"),f=l(" to get Xray"),g=t("h2",{id:"configure-and-run",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#configure-and-run","aria-hidden":"true"},"#"),l(" Configure and Run")],-1),y=t("p",null,"After downloading and installing Xray, you need to configure it.",-1),v=l("Please click "),w=l("How to Configure and Run Xray"),b=l(" to learn the easiest way to configure Xray."),k=t("h2",{id:"command-parameters",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#command-parameters","aria-hidden":"true"},"#"),l(" Command Parameters")],-1),X=t("p",null,"Xray has a variety of commands and parameters available, making it flexible and powerful.",-1),x=l("Please click "),P=l("Command Parameters for Xray"),_=l(" to view more commands and parameters usages."),A=t("h2",{id:"improve-documents",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#improve-documents","aria-hidden":"true"},"#"),l(" Improve Documents")],-1),C=l("If you're interested, please click "),D=l("Documents"),T=l(" to help us improve the documents, or click the"),I=t("code",null,"Help us improve this page!",-1),q=t("p",null,"We are very grateful to every Contributor for their contribution! You guys make Project X even stronger!",-1),H=t("h2",{id:"beginner-tutorial",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#beginner-tutorial","aria-hidden":"true"},"#"),l(" Beginner Tutorial")],-1),R=t("p",null,"A easy tutorial for beginner.",-1),S=l("Please click "),j=l("小小白白话文"),G=l(" to view it."),B=t("h2",{id:"getting-started-tips",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#getting-started-tips","aria-hidden":"true"},"#"),l(" Getting Started Tips")],-1),F=l("After you have the basics, you can explore more ways to use them through "),L=l("Getting Started Tips"),Q=l("."),W=t("h2",{id:"advanced-documentation",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#advanced-documentation","aria-hidden":"true"},"#"),l(" Advanced Documentation")],-1),Y=t("p",null,"Tips for advanced user guidance",-1),z=l("Click on "),E=l("Advanced Documentation"),J=l(" to view it"),K=t("div",{class:"custom-container tip"},[t("p",{class:"custom-container-title"},"Appreciations"),t("p",null,"Thank you very much for your selfless sharing of usage skills and experience, which makes Xray more and more powerful.")],-1);d.render=function(l,d){const M=e("RouterLink");return a(),n(i,null,[s,u,c,h,t("p",null,[m,r(M,{to:"/en/document/install.html"},{default:o((()=>[p])),_:1}),f]),g,y,t("p",null,[v,r(M,{to:"/en/document/config.html"},{default:o((()=>[w])),_:1}),b]),k,X,t("p",null,[x,r(M,{to:"/en/document/command.html"},{default:o((()=>[P])),_:1}),_]),A,t("p",null,[C,r(M,{to:"/en/document/document.html"},{default:o((()=>[D])),_:1}),T,I]),q,H,R,t("p",null,[S,r(M,{to:"/en/document/level-0/"},{default:o((()=>[j])),_:1}),G]),B,t("p",null,[F,r(M,{to:"/en/document/level-1/"},{default:o((()=>[L])),_:1}),Q]),W,Y,t("p",null,[z,r(M,{to:"/en/document/level-2/"},{default:o((()=>[E])),_:1}),J]),K],64)};export default d; +import{r as e,o as a,c as n,a as t,b as r,w as o,F as i,e as l}from"./app.48111a85.js";const d={},s=t("h1",{id:"quick-start",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#quick-start","aria-hidden":"true"},"#"),l(" Quick Start")],-1),u=t("blockquote",null,[t("p",null,[t("strong",null,"This chapter will tell you how to get Xray in the easiest way and start using Xray.")])],-1),c=t("h2",{id:"download-and-install",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#download-and-install","aria-hidden":"true"},"#"),l(" Download and Install")],-1),h=t("p",null,"Xray supports various platforms, and you can get various versions of Xray from various sources and methods.",-1),m=l("Please click "),p=l("How to Download and Install Xray"),f=l(" to get Xray"),g=t("h2",{id:"configure-and-run",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#configure-and-run","aria-hidden":"true"},"#"),l(" Configure and Run")],-1),y=t("p",null,"After downloading and installing Xray, you need to configure it.",-1),v=l("Please click "),w=l("How to Configure and Run Xray"),b=l(" to learn the easiest way to configure Xray."),k=t("h2",{id:"command-parameters",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#command-parameters","aria-hidden":"true"},"#"),l(" Command Parameters")],-1),X=t("p",null,"Xray has a variety of commands and parameters available, making it flexible and powerful.",-1),x=l("Please click "),P=l("Command Parameters for Xray"),_=l(" to view more commands and parameters usages."),A=t("h2",{id:"improve-documents",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#improve-documents","aria-hidden":"true"},"#"),l(" Improve Documents")],-1),C=l("If you're interested, please click "),D=l("Documents"),T=l(" to help us improve the documents, or click the"),I=t("code",null,"Help us improve this page!",-1),q=t("p",null,"We are very grateful to every Contributor for their contribution! You guys make Project X even stronger!",-1),H=t("h2",{id:"beginner-tutorial",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#beginner-tutorial","aria-hidden":"true"},"#"),l(" Beginner Tutorial")],-1),R=t("p",null,"A easy tutorial for beginner.",-1),S=l("Please click "),j=l("小小白白话文"),G=l(" to view it."),B=t("h2",{id:"getting-started-tips",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#getting-started-tips","aria-hidden":"true"},"#"),l(" Getting Started Tips")],-1),F=l("After you have the basics, you can explore more ways to use them through "),L=l("Getting Started Tips"),Q=l("."),W=t("h2",{id:"advanced-documentation",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#advanced-documentation","aria-hidden":"true"},"#"),l(" Advanced Documentation")],-1),Y=t("p",null,"Tips for advanced user guidance",-1),z=l("Click on "),E=l("Advanced Documentation"),J=l(" to view it"),K=t("div",{class:"custom-container tip"},[t("p",{class:"custom-container-title"},"Appreciations"),t("p",null,"Thank you very much for your selfless sharing of usage skills and experience, which makes Xray more and more powerful.")],-1);d.render=function(l,d){const M=e("RouterLink");return a(),n(i,null,[s,u,c,h,t("p",null,[m,r(M,{to:"/en/document/install.html"},{default:o((()=>[p])),_:1}),f]),g,y,t("p",null,[v,r(M,{to:"/en/document/config.html"},{default:o((()=>[w])),_:1}),b]),k,X,t("p",null,[x,r(M,{to:"/en/document/command.html"},{default:o((()=>[P])),_:1}),_]),A,t("p",null,[C,r(M,{to:"/en/document/document.html"},{default:o((()=>[D])),_:1}),T,I]),q,H,R,t("p",null,[S,r(M,{to:"/en/document/level-0/"},{default:o((()=>[j])),_:1}),G]),B,t("p",null,[F,r(M,{to:"/en/document/level-1/"},{default:o((()=>[L])),_:1}),Q]),W,Y,t("p",null,[z,r(M,{to:"/en/document/level-2/"},{default:o((()=>[E])),_:1}),J]),K],64)};export default d; diff --git a/assets/index.html.ed299f0a.js b/assets/index.html.b462ed8b.js similarity index 65% rename from assets/index.html.ed299f0a.js rename to assets/index.html.b462ed8b.js index ec48ef73f..18593b5b4 100644 --- a/assets/index.html.ed299f0a.js +++ b/assets/index.html.b462ed8b.js @@ -1 +1 @@ -import{r as l,o as t,c as a,a as e,b as n,w as u,F as o,e as r}from"./app.755d843f.js";const d={},s=e("h1",{id:"入门技巧",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#入门技巧","aria-hidden":"true"},"#"),r(" 入门技巧")],-1),c=e("p",null,[e("strong",null,"这个章节是入门级的 Xray 使用心得分享,主要分享一些 Xray 常用功能模块的原理说明。")],-1),f=r("回落 (fallbacks) 功能简析"),i=r("路由 (routing) 功能简析(上)"),m=r("路由 (routing) 功能简析(下)"),p=r("Xray 的工作模式简析"),h=r("通过 SNI 回落功能实现伪装与按域名分流");d.render=function(r,d){const v=l("RouterLink");return t(),a(o,null,[s,c,e("p",null,[n(v,{to:"/document/level-1/fallbacks-lv1.html"},{default:u((()=>[f])),_:1})]),e("p",null,[n(v,{to:"/document/level-1/routing-lv1-part1.html"},{default:u((()=>[i])),_:1})]),e("p",null,[n(v,{to:"/document/level-1/routing-lv1-part2.html"},{default:u((()=>[m])),_:1})]),e("p",null,[n(v,{to:"/document/level-1/work.html"},{default:u((()=>[p])),_:1})]),e("p",null,[n(v,{to:"/document/level-1/fallbacks-with-sni.html"},{default:u((()=>[h])),_:1})])],64)};export default d; +import{r as l,o as t,c as a,a as e,b as n,w as u,F as o,e as r}from"./app.48111a85.js";const s={},d=e("h1",{id:"入门技巧",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#入门技巧","aria-hidden":"true"},"#"),r(" 入门技巧")],-1),c=e("p",null,[e("strong",null,"这个章节是入门级的 Xray 使用心得分享,主要分享一些 Xray 常用功能模块的原理说明。")],-1),i=r("回落 (fallbacks) 功能简析"),f=r("路由 (routing) 功能简析(上)"),m=r("路由 (routing) 功能简析(下)"),p=r("Xray 的工作模式简析"),h=r("通过 SNI 回落功能实现伪装与按域名分流");s.render=function(r,s){const v=l("RouterLink");return t(),a(o,null,[d,c,e("p",null,[n(v,{to:"/document/level-1/fallbacks-lv1.html"},{default:u((()=>[i])),_:1})]),e("p",null,[n(v,{to:"/document/level-1/routing-lv1-part1.html"},{default:u((()=>[f])),_:1})]),e("p",null,[n(v,{to:"/document/level-1/routing-lv1-part2.html"},{default:u((()=>[m])),_:1})]),e("p",null,[n(v,{to:"/document/level-1/work.html"},{default:u((()=>[p])),_:1})]),e("p",null,[n(v,{to:"/document/level-1/fallbacks-with-sni.html"},{default:u((()=>[h])),_:1})])],64)};export default s; diff --git a/assets/index.html.25f2c703.js b/assets/index.html.c4382cba.js similarity index 99% rename from assets/index.html.25f2c703.js rename to assets/index.html.c4382cba.js index fb2036b9c..5a632a332 100644 --- a/assets/index.html.25f2c703.js +++ b/assets/index.html.c4382cba.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as t,b as p,w as o,F as l,d as u,e}from"./app.755d843f.js";const c={},r=u('

    这个章节将告诉您所有的 Xray 配置细节,掌握这些内容,在您手中 Xray 将发挥更大威力。

    概述

    Xray 的配置文件为 json 格式, 客户端和服务端的配置格式没有区别, 只是实际的配置内容不一样。
    形式如下:

    {\n  "log": {},\n  "api": {},\n  "dns": {},\n  "routing": {},\n  "policy": {},\n  "inbounds": [],\n  "outbounds": [],\n  "transport": {},\n  "stats": {},\n  "reverse": {},\n  "fakedns": {}\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ',4),i={class:"custom-container warning"},k=t("p",{class:"custom-container-title"},"注意",-1),b=e("如果你刚接触 Xray, 您可以先点击查看"),d=e("快速入门中的配置运行"),q=e(", 学习最基本的配置方式, 然后查看本章节内容以掌握所有 Xray 的配置方式。"),m=t("h2",{id:"基础配置模块",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#基础配置模块","aria-hidden":"true"},"#"),e(" 基础配置模块")],-1),f=e("log:"),g=e("LogObject"),h=t("p",null,"日志配置,控制 Xray 输出日志的方式.",-1),y=e("api:"),j=e("ApiObject"),O=t("p",null,"提供了一些 API 接口供远程调用。",-1),_=e("dns: "),v=e("DnsObject"),X=t("p",null,"内置的 DNS 服务器. 如果没有配置此项,则使用系统的 DNS 设置。",-1),D=e("routing: "),x=e("RoutingObject"),S=t("p",null,"路由功能。可以设置规则分流数据从不同的 outbound 发出.",-1),F=e("policy: "),N=e("PolicyObject"),R=t("p",null,"本地策略,可以设置不同的用户等级和对应的策略设置。",-1),w=e("inbounds: [ "),A=e("InboundObject"),I=e(" ]"),L=t("p",null,"一个数组,每个元素是一个入站连接配置。",-1),P=e("outbounds: [ "),T=e("OutboundObject"),z=e(" ]"),B=t("p",null,"一个数组,每个元素是一个出站连接配置。",-1),C=e("transport: "),E=e("TransportObject"),G=t("p",null,"用于配置 Xray 其它服务器建立和使用网络连接的方式。",-1),H=e("stats: "),J=e("StatsObject"),K=t("p",null,"用于配置流量数据的统计。",-1),M=e("reverse: "),Q=e("ReverseObject"),U=t("p",null,"反向代理。可以把服务器端的流量向客户端转发,即逆向流量转发。",-1),V=e("fakedns: "),W=e("FakeDnsObject"),Y=t("p",null,"FakeDNS 配置。可配合透明代理使用,以获取实际域名。",-1);c.render=function(u,e){const c=n("RouterLink");return s(),a(l,null,[r,t("div",i,[k,t("p",null,[b,p(c,{to:"/document/install.html"},{default:o((()=>[d])),_:1}),q])]),m,t("blockquote",null,[t("p",null,[f,p(c,{to:"/config/log.html"},{default:o((()=>[g])),_:1})])]),h,t("blockquote",null,[t("p",null,[y,p(c,{to:"/config/api.html"},{default:o((()=>[j])),_:1})])]),O,t("blockquote",null,[t("p",null,[_,p(c,{to:"/config/dns.html"},{default:o((()=>[v])),_:1})])]),X,t("blockquote",null,[t("p",null,[D,p(c,{to:"/config/routing.html"},{default:o((()=>[x])),_:1})])]),S,t("blockquote",null,[t("p",null,[F,p(c,{to:"/config/policy.html"},{default:o((()=>[N])),_:1})])]),R,t("blockquote",null,[t("p",null,[w,p(c,{to:"/config/inbound.html"},{default:o((()=>[A])),_:1}),I])]),L,t("blockquote",null,[t("p",null,[P,p(c,{to:"/config/outbound.html"},{default:o((()=>[T])),_:1}),z])]),B,t("blockquote",null,[t("p",null,[C,p(c,{to:"/config/transport.html"},{default:o((()=>[E])),_:1})])]),G,t("blockquote",null,[t("p",null,[H,p(c,{to:"/config/stats.html"},{default:o((()=>[J])),_:1})])]),K,t("blockquote",null,[t("p",null,[M,p(c,{to:"/config/reverse.html"},{default:o((()=>[Q])),_:1})])]),U,t("blockquote",null,[t("p",null,[V,p(c,{to:"/config/fakedns.html"},{default:o((()=>[W])),_:1})])]),Y],64)};export default c; +import{r as n,o as s,c as a,a as t,b as p,w as o,F as l,d as u,e}from"./app.48111a85.js";const c={},r=u('

    这个章节将告诉您所有的 Xray 配置细节,掌握这些内容,在您手中 Xray 将发挥更大威力。

    概述

    Xray 的配置文件为 json 格式, 客户端和服务端的配置格式没有区别, 只是实际的配置内容不一样。
    形式如下:

    {\n  "log": {},\n  "api": {},\n  "dns": {},\n  "routing": {},\n  "policy": {},\n  "inbounds": [],\n  "outbounds": [],\n  "transport": {},\n  "stats": {},\n  "reverse": {},\n  "fakedns": {}\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ',4),i={class:"custom-container warning"},k=t("p",{class:"custom-container-title"},"注意",-1),b=e("如果你刚接触 Xray, 您可以先点击查看"),d=e("快速入门中的配置运行"),q=e(", 学习最基本的配置方式, 然后查看本章节内容以掌握所有 Xray 的配置方式。"),m=t("h2",{id:"基础配置模块",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#基础配置模块","aria-hidden":"true"},"#"),e(" 基础配置模块")],-1),f=e("log:"),g=e("LogObject"),h=t("p",null,"日志配置,控制 Xray 输出日志的方式.",-1),y=e("api:"),j=e("ApiObject"),O=t("p",null,"提供了一些 API 接口供远程调用。",-1),_=e("dns: "),v=e("DnsObject"),X=t("p",null,"内置的 DNS 服务器. 如果没有配置此项,则使用系统的 DNS 设置。",-1),D=e("routing: "),x=e("RoutingObject"),S=t("p",null,"路由功能。可以设置规则分流数据从不同的 outbound 发出.",-1),F=e("policy: "),N=e("PolicyObject"),R=t("p",null,"本地策略,可以设置不同的用户等级和对应的策略设置。",-1),w=e("inbounds: [ "),A=e("InboundObject"),I=e(" ]"),L=t("p",null,"一个数组,每个元素是一个入站连接配置。",-1),P=e("outbounds: [ "),T=e("OutboundObject"),z=e(" ]"),B=t("p",null,"一个数组,每个元素是一个出站连接配置。",-1),C=e("transport: "),E=e("TransportObject"),G=t("p",null,"用于配置 Xray 其它服务器建立和使用网络连接的方式。",-1),H=e("stats: "),J=e("StatsObject"),K=t("p",null,"用于配置流量数据的统计。",-1),M=e("reverse: "),Q=e("ReverseObject"),U=t("p",null,"反向代理。可以把服务器端的流量向客户端转发,即逆向流量转发。",-1),V=e("fakedns: "),W=e("FakeDnsObject"),Y=t("p",null,"FakeDNS 配置。可配合透明代理使用,以获取实际域名。",-1);c.render=function(u,e){const c=n("RouterLink");return s(),a(l,null,[r,t("div",i,[k,t("p",null,[b,p(c,{to:"/document/install.html"},{default:o((()=>[d])),_:1}),q])]),m,t("blockquote",null,[t("p",null,[f,p(c,{to:"/config/log.html"},{default:o((()=>[g])),_:1})])]),h,t("blockquote",null,[t("p",null,[y,p(c,{to:"/config/api.html"},{default:o((()=>[j])),_:1})])]),O,t("blockquote",null,[t("p",null,[_,p(c,{to:"/config/dns.html"},{default:o((()=>[v])),_:1})])]),X,t("blockquote",null,[t("p",null,[D,p(c,{to:"/config/routing.html"},{default:o((()=>[x])),_:1})])]),S,t("blockquote",null,[t("p",null,[F,p(c,{to:"/config/policy.html"},{default:o((()=>[N])),_:1})])]),R,t("blockquote",null,[t("p",null,[w,p(c,{to:"/config/inbound.html"},{default:o((()=>[A])),_:1}),I])]),L,t("blockquote",null,[t("p",null,[P,p(c,{to:"/config/outbound.html"},{default:o((()=>[T])),_:1}),z])]),B,t("blockquote",null,[t("p",null,[C,p(c,{to:"/config/transport.html"},{default:o((()=>[E])),_:1})])]),G,t("blockquote",null,[t("p",null,[H,p(c,{to:"/config/stats.html"},{default:o((()=>[J])),_:1})])]),K,t("blockquote",null,[t("p",null,[M,p(c,{to:"/config/reverse.html"},{default:o((()=>[Q])),_:1})])]),U,t("blockquote",null,[t("p",null,[V,p(c,{to:"/config/fakedns.html"},{default:o((()=>[W])),_:1})])]),Y],64)};export default c; diff --git a/assets/index.html.9097978e.js b/assets/index.html.eaff5f8e.js similarity index 94% rename from assets/index.html.9097978e.js rename to assets/index.html.eaff5f8e.js index 13dbb2292..b27d64360 100644 --- a/assets/index.html.9097978e.js +++ b/assets/index.html.eaff5f8e.js @@ -1 +1 @@ -import{r as n,o as l,c as e,a as t,b as a,w as o,F as s,e as i}from"./app.755d843f.js";const u={},r=t("h1",{id:"beginner-s-tips",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#beginner-s-tips","aria-hidden":"true"},"#"),i(" Beginner's Tips")],-1),d=t("p",null,[t("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),c=i("Analysis of Fallbacks Function"),f=i("Analysis of Routing Function (Part 1)"),m=i("Analysis of Routing Function (Part 2)"),p=i("Analysis of Xray's Working Mode"),h=i("Fallbacks with SNI for Disguising and Domain-based Routing");u.render=function(i,u){const g=n("RouterLink");return l(),e(s,null,[r,d,t("p",null,[a(g,{to:"/en/document/level-1/fallbacks-lv1.html"},{default:o((()=>[c])),_:1})]),t("p",null,[a(g,{to:"/en/document/level-1/routing-lv1-part1.html"},{default:o((()=>[f])),_:1})]),t("p",null,[a(g,{to:"/en/document/level-1/routing-lv1-part2.html"},{default:o((()=>[m])),_:1})]),t("p",null,[a(g,{to:"/en/document/level-1/work.html"},{default:o((()=>[p])),_:1})]),t("p",null,[a(g,{to:"/en/document/level-1/fallbacks-with-sni.html"},{default:o((()=>[h])),_:1})])],64)};export default u; +import{r as n,o as l,c as e,a as t,b as a,w as o,F as s,e as i}from"./app.48111a85.js";const u={},r=t("h1",{id:"beginner-s-tips",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#beginner-s-tips","aria-hidden":"true"},"#"),i(" Beginner's Tips")],-1),d=t("p",null,[t("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),c=i("Analysis of Fallbacks Function"),f=i("Analysis of Routing Function (Part 1)"),m=i("Analysis of Routing Function (Part 2)"),p=i("Analysis of Xray's Working Mode"),h=i("Fallbacks with SNI for Disguising and Domain-based Routing");u.render=function(i,u){const g=n("RouterLink");return l(),e(s,null,[r,d,t("p",null,[a(g,{to:"/en/document/level-1/fallbacks-lv1.html"},{default:o((()=>[c])),_:1})]),t("p",null,[a(g,{to:"/en/document/level-1/routing-lv1-part1.html"},{default:o((()=>[f])),_:1})]),t("p",null,[a(g,{to:"/en/document/level-1/routing-lv1-part2.html"},{default:o((()=>[m])),_:1})]),t("p",null,[a(g,{to:"/en/document/level-1/work.html"},{default:o((()=>[p])),_:1})]),t("p",null,[a(g,{to:"/en/document/level-1/fallbacks-with-sni.html"},{default:o((()=>[h])),_:1})])],64)};export default u; diff --git a/assets/index.html.bd1215bd.js b/assets/index.html.f6d047fe.js similarity index 98% rename from assets/index.html.bd1215bd.js rename to assets/index.html.f6d047fe.js index 3a7f95371..38244d870 100644 --- a/assets/index.html.bd1215bd.js +++ b/assets/index.html.f6d047fe.js @@ -1 +1 @@ -import{r as a,o as e,c as l,a as n,b as r,w as t,F as d,e as u}from"./app.755d843f.js";const h={},o=n("h1",{id:"快速入门",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#快速入门","aria-hidden":"true"},"#"),u(" 快速入门")],-1),i=n("blockquote",null,[n("p",null,[n("strong",null,"这个章节将告诉您如何用最简单的方式获得 Xray,并且开始使用 Xray。")])],-1),c=n("h2",{id:"下载安装",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#下载安装","aria-hidden":"true"},"#"),u(" 下载安装")],-1),s=n("p",null,"Xray 支持各种平台,并且您可以从多种渠道和方式获得 Xray 的各种版本。",-1),p=u("请点击 "),f=u("如何下载安装 Xray"),m=u(" 以获取 Xray"),X=n("h2",{id:"配置运行",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#配置运行","aria-hidden":"true"},"#"),u(" 配置运行")],-1),y=n("p",null,"下载并安装 Xray 后,只需对他进行配置即可使用。",-1),b=u("请点击 "),x=u("如何配置运行 Xray"),_=u(" 以学习最简单的配置方式。"),v=n("h2",{id:"命令参数",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#命令参数","aria-hidden":"true"},"#"),u(" 命令参数")],-1),g=n("p",null,"Xray 有多种命令和参数可用,因此变得灵活和强大。",-1),j=u("请点击 "),k=u("Xray 的命令参数"),q=u(" 查看 Xray 的更多命令和参数用法。"),w=n("h2",{id:"改进文档",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#改进文档","aria-hidden":"true"},"#"),u(" 改进文档")],-1),C=u("如果你有兴趣,请点击 "),F=u("使用文档"),L=u(" 帮助我们改进文档,或者点击页面下方的 "),P=n("code",null,"帮助我们改善此页面!",-1),R=n("p",null,"我们十分感谢每一位 Contributor 作出的贡献!是你们让 Project X 变得更加强大!",-1),z=n("h2",{id:"小小白白话文",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#小小白白话文","aria-hidden":"true"},"#"),u(" 小小白白话文")],-1),A=n("p",null,"给予新手指导的使用心得",-1),B=u("请点击 "),D=u("小小白白话文"),E=u(" 以进行查看。"),G=n("h2",{id:"入门技巧",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#入门技巧","aria-hidden":"true"},"#"),u(" 入门技巧")],-1),H=u("具备了基础之后,你就可以通过 "),I=u("入门技巧"),J=u(" 来探索更多的使用方式了。"),K=n("h2",{id:"进阶文档",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#进阶文档","aria-hidden":"true"},"#"),u(" 进阶文档")],-1),M=n("p",null,"给予进阶用户指导的使用技巧",-1),N=u("点击 "),O=u("进阶文档"),Q=u(" 以进行查看"),S=n("div",{class:"custom-container tip"},[n("p",{class:"custom-container-title"},"感谢"),n("p",null,"非常感谢大家无私分享使用技巧和心得, 使得 Xray 日益强大。")],-1);h.render=function(u,h){const T=a("RouterLink");return e(),l(d,null,[o,i,c,s,n("p",null,[p,r(T,{to:"/document/install.html"},{default:t((()=>[f])),_:1}),m]),X,y,n("p",null,[b,r(T,{to:"/document/config.html"},{default:t((()=>[x])),_:1}),_]),v,g,n("p",null,[j,r(T,{to:"/document/command.html"},{default:t((()=>[k])),_:1}),q]),w,n("p",null,[C,r(T,{to:"/document/document.html"},{default:t((()=>[F])),_:1}),L,P]),R,z,A,n("p",null,[B,r(T,{to:"/document/level-0/"},{default:t((()=>[D])),_:1}),E]),G,n("p",null,[H,r(T,{to:"/document/level-1/"},{default:t((()=>[I])),_:1}),J]),K,M,n("p",null,[N,r(T,{to:"/document/level-2/"},{default:t((()=>[O])),_:1}),Q]),S],64)};export default h; +import{r as a,o as e,c as l,a as n,b as r,w as t,F as d,e as u}from"./app.48111a85.js";const h={},o=n("h1",{id:"快速入门",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#快速入门","aria-hidden":"true"},"#"),u(" 快速入门")],-1),i=n("blockquote",null,[n("p",null,[n("strong",null,"这个章节将告诉您如何用最简单的方式获得 Xray,并且开始使用 Xray。")])],-1),c=n("h2",{id:"下载安装",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#下载安装","aria-hidden":"true"},"#"),u(" 下载安装")],-1),s=n("p",null,"Xray 支持各种平台,并且您可以从多种渠道和方式获得 Xray 的各种版本。",-1),p=u("请点击 "),f=u("如何下载安装 Xray"),m=u(" 以获取 Xray"),X=n("h2",{id:"配置运行",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#配置运行","aria-hidden":"true"},"#"),u(" 配置运行")],-1),y=n("p",null,"下载并安装 Xray 后,只需对他进行配置即可使用。",-1),b=u("请点击 "),x=u("如何配置运行 Xray"),_=u(" 以学习最简单的配置方式。"),v=n("h2",{id:"命令参数",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#命令参数","aria-hidden":"true"},"#"),u(" 命令参数")],-1),g=n("p",null,"Xray 有多种命令和参数可用,因此变得灵活和强大。",-1),j=u("请点击 "),k=u("Xray 的命令参数"),q=u(" 查看 Xray 的更多命令和参数用法。"),w=n("h2",{id:"改进文档",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#改进文档","aria-hidden":"true"},"#"),u(" 改进文档")],-1),C=u("如果你有兴趣,请点击 "),F=u("使用文档"),L=u(" 帮助我们改进文档,或者点击页面下方的 "),P=n("code",null,"帮助我们改善此页面!",-1),R=n("p",null,"我们十分感谢每一位 Contributor 作出的贡献!是你们让 Project X 变得更加强大!",-1),z=n("h2",{id:"小小白白话文",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#小小白白话文","aria-hidden":"true"},"#"),u(" 小小白白话文")],-1),A=n("p",null,"给予新手指导的使用心得",-1),B=u("请点击 "),D=u("小小白白话文"),E=u(" 以进行查看。"),G=n("h2",{id:"入门技巧",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#入门技巧","aria-hidden":"true"},"#"),u(" 入门技巧")],-1),H=u("具备了基础之后,你就可以通过 "),I=u("入门技巧"),J=u(" 来探索更多的使用方式了。"),K=n("h2",{id:"进阶文档",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#进阶文档","aria-hidden":"true"},"#"),u(" 进阶文档")],-1),M=n("p",null,"给予进阶用户指导的使用技巧",-1),N=u("点击 "),O=u("进阶文档"),Q=u(" 以进行查看"),S=n("div",{class:"custom-container tip"},[n("p",{class:"custom-container-title"},"感谢"),n("p",null,"非常感谢大家无私分享使用技巧和心得, 使得 Xray 日益强大。")],-1);h.render=function(u,h){const T=a("RouterLink");return e(),l(d,null,[o,i,c,s,n("p",null,[p,r(T,{to:"/document/install.html"},{default:t((()=>[f])),_:1}),m]),X,y,n("p",null,[b,r(T,{to:"/document/config.html"},{default:t((()=>[x])),_:1}),_]),v,g,n("p",null,[j,r(T,{to:"/document/command.html"},{default:t((()=>[k])),_:1}),q]),w,n("p",null,[C,r(T,{to:"/document/document.html"},{default:t((()=>[F])),_:1}),L,P]),R,z,A,n("p",null,[B,r(T,{to:"/document/level-0/"},{default:t((()=>[D])),_:1}),E]),G,n("p",null,[H,r(T,{to:"/document/level-1/"},{default:t((()=>[I])),_:1}),J]),K,M,n("p",null,[N,r(T,{to:"/document/level-2/"},{default:t((()=>[O])),_:1}),Q]),S],64)};export default h; diff --git a/assets/index.html.4ececa11.js b/assets/index.html.fec1bfdb.js similarity index 98% rename from assets/index.html.4ececa11.js rename to assets/index.html.fec1bfdb.js index 38894da4f..ab7147a3b 100644 --- a/assets/index.html.4ececa11.js +++ b/assets/index.html.fec1bfdb.js @@ -1 +1 @@ -import{r as e,o as r,c as a,a as t,b as o,w as l,F as n,d as i,e as s}from"./app.755d843f.js";const u={},h=i('

    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),c=t("li",null,"🖥️ Help develop and test Xray, submit high-quality Pull requests.",-1),d=s("📩 Initiate constructive or meaningful issues and discussions in "),p={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},m=s("GitHub Issues"),b=s(" or "),f={href:"https://github.com/XTLS/Xray-core/discussions",target:"_blank",rel:"noopener noreferrer"},g=s("Discussion area"),y=s("."),X=s("📝 Write down your usage experience and submit it to Xray's "),w={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},k=s("documentation website"),v=s("."),T=t("li",null,"💬 Help group members/chat in Telegram group.",-1),x=t("li",null,[t("strong",null,"...In fact, every support for Xray will make Xray stronger")],-1),L=t("h3",{id:"telegram",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#telegram","aria-hidden":"true"},"#"),s(" Telegram")],-1),S={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},j=s("Project X Discussion Group"),q=t("ul",null,[t("li",null,"You can chat freely above the bottom line in the discussion group, don't fight, no abuse of power."),t("li",null,"Feel free to ask questions, and try to answer those you know."),t("li",null,"No politics, No NSFW")],-1),P={href:"https://t.me/projectXtls",target:"_blank",rel:"noopener noreferrer"},_=s("Project X Channel"),I=t("ul",null,[t("li",null,"Publish the latest news of Project X")],-1),z=t("h3",{id:"thanks",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#thanks","aria-hidden":"true"},"#"),s(" Thanks")],-1),R=t("ul",null,[t("li",null,"Thanks to everyone for their support!"),t("li",null,"Thanks to all kinds of scripts, Docker images, client support... Thanks to all the big guys who helped improve the ecosystem!"),t("li",null,"Thanks to friends who have contributed to the Xray website and documentation."),t("li",null,"Thanks to friends who have made meaningful suggestions and comments."),t("li",null,"Thanks to every friend in the Telegram group who helps others.")],-1),V=t("h3",{id:"more-about-project-x",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#more-about-project-x","aria-hidden":"true"},"#"),s(" More about project X")],-1),W=s("If you would like to learn more about project X's history and growth, please click "),C=s("here"),E=t("h3",{id:"license",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#license","aria-hidden":"true"},"#"),s(" License")],-1),H={href:"https://github.com/XTLS/Xray-core/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"},N=s("Mozilla Public License Version 2.0"),D=t("h3",{id:"stargazers-over-time",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#stargazers-over-time","aria-hidden":"true"},"#"),s(" Stargazers over time")],-1),F={href:"https://starchart.cc/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},A=t("img",{src:"https://starchart.cc/XTLS/Xray-core.svg",alt:"Stargazers over time"},null,-1);u.render=function(i,s){const u=e("OutboundLink"),G=e("RouterLink");return r(),a(n,null,[h,t("ul",null,[c,t("li",null,[d,t("a",p,[m,o(u)]),b,t("a",f,[g,o(u)]),y]),t("li",null,[X,t("a",w,[k,o(u)]),v]),T,x]),L,t("ul",null,[t("li",null,[t("p",null,[t("a",S,[j,o(u)])]),q]),t("li",null,[t("p",null,[t("a",P,[_,o(u)])]),I])]),z,R,V,t("ul",null,[t("li",null,[W,o(G,{to:"/en/about/news.html"},{default:l((()=>[C])),_:1})])]),E,t("p",null,[t("a",H,[N,o(u)])]),D,t("p",null,[t("a",F,[A,o(u)])])],64)};export default u; +import{r as e,o as r,c as a,a as t,b as o,w as l,F as n,d as i,e as s}from"./app.48111a85.js";const u={},h=i('

    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),c=t("li",null,"🖥️ Help develop and test Xray, submit high-quality Pull requests.",-1),d=s("📩 Initiate constructive or meaningful issues and discussions in "),p={href:"https://github.com/XTLS/Xray-core/issues",target:"_blank",rel:"noopener noreferrer"},m=s("GitHub Issues"),b=s(" or "),f={href:"https://github.com/XTLS/Xray-core/discussions",target:"_blank",rel:"noopener noreferrer"},g=s("Discussion area"),y=s("."),X=s("📝 Write down your usage experience and submit it to Xray's "),w={href:"https://github.com/XTLS/Xray-docs-next",target:"_blank",rel:"noopener noreferrer"},k=s("documentation website"),v=s("."),T=t("li",null,"💬 Help group members/chat in Telegram group.",-1),x=t("li",null,[t("strong",null,"...In fact, every support for Xray will make Xray stronger")],-1),L=t("h3",{id:"telegram",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#telegram","aria-hidden":"true"},"#"),s(" Telegram")],-1),S={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},j=s("Project X Discussion Group"),q=t("ul",null,[t("li",null,"You can chat freely above the bottom line in the discussion group, don't fight, no abuse of power."),t("li",null,"Feel free to ask questions, and try to answer those you know."),t("li",null,"No politics, No NSFW")],-1),P={href:"https://t.me/projectXtls",target:"_blank",rel:"noopener noreferrer"},_=s("Project X Channel"),I=t("ul",null,[t("li",null,"Publish the latest news of Project X")],-1),z=t("h3",{id:"thanks",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#thanks","aria-hidden":"true"},"#"),s(" Thanks")],-1),R=t("ul",null,[t("li",null,"Thanks to everyone for their support!"),t("li",null,"Thanks to all kinds of scripts, Docker images, client support... Thanks to all the big guys who helped improve the ecosystem!"),t("li",null,"Thanks to friends who have contributed to the Xray website and documentation."),t("li",null,"Thanks to friends who have made meaningful suggestions and comments."),t("li",null,"Thanks to every friend in the Telegram group who helps others.")],-1),V=t("h3",{id:"more-about-project-x",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#more-about-project-x","aria-hidden":"true"},"#"),s(" More about project X")],-1),W=s("If you would like to learn more about project X's history and growth, please click "),C=s("here"),E=t("h3",{id:"license",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#license","aria-hidden":"true"},"#"),s(" License")],-1),H={href:"https://github.com/XTLS/Xray-core/blob/main/LICENSE",target:"_blank",rel:"noopener noreferrer"},N=s("Mozilla Public License Version 2.0"),D=t("h3",{id:"stargazers-over-time",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#stargazers-over-time","aria-hidden":"true"},"#"),s(" Stargazers over time")],-1),F={href:"https://starchart.cc/XTLS/Xray-core",target:"_blank",rel:"noopener noreferrer"},A=t("img",{src:"https://starchart.cc/XTLS/Xray-core.svg",alt:"Stargazers over time"},null,-1);u.render=function(i,s){const u=e("OutboundLink"),G=e("RouterLink");return r(),a(n,null,[h,t("ul",null,[c,t("li",null,[d,t("a",p,[m,o(u)]),b,t("a",f,[g,o(u)]),y]),t("li",null,[X,t("a",w,[k,o(u)]),v]),T,x]),L,t("ul",null,[t("li",null,[t("p",null,[t("a",S,[j,o(u)])]),q]),t("li",null,[t("p",null,[t("a",P,[_,o(u)])]),I])]),z,R,V,t("ul",null,[t("li",null,[W,o(G,{to:"/en/about/news.html"},{default:l((()=>[C])),_:1})])]),E,t("p",null,[t("a",H,[N,o(u)])]),D,t("p",null,[t("a",F,[A,o(u)])])],64)};export default u; diff --git a/assets/infoDiagram-4374b389.2c0ba8f4.js b/assets/infoDiagram-4374b389.362cabc6.js similarity index 99% rename from assets/infoDiagram-4374b389.2c0ba8f4.js rename to assets/infoDiagram-4374b389.362cabc6.js index 5c5751029..6cac68128 100644 --- a/assets/infoDiagram-4374b389.2c0ba8f4.js +++ b/assets/infoDiagram-4374b389.362cabc6.js @@ -1 +1 @@ -import{z as t,l as i,c as n,h as e}from"./mermaid.core.a66200b0.js";var s=function(){var t=function(t,i,n,e){for(n=n||{},e=t.length;e--;n[t[e]]=i);return n},i=[6,9,10],n={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,i,n,e,s,r,o){switch(r.length,s){case 1:return e;case 4:break;case 6:e.setInfo(!0)}},table:[{3:1,4:[1,2]},{1:[3]},t(i,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},t(i,[2,3]),t(i,[2,4]),t(i,[2,5]),t(i,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,i){if(!i.recoverable){var n=new Error(t);throw n.hash=i,n}this.trace(t)},parse:function(t){var i=this,n=[0],e=[],s=[null],r=[],o=this.table,h="",l=0,c=0,a=2,y=1,u=r.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;r.push(m);var _=p.options&&p.options.ranges;function d(){var t;return"number"!=typeof(t=e.pop()||p.lex()||y)&&(t instanceof Array&&(t=(e=t).pop()),t=i.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var k,x,b,v,w,I,S,E,A={};;){if(x=n[n.length-1],this.defaultActions[x]?b=this.defaultActions[x]:(null==k&&(k=d()),b=o[x]&&o[x][k]),void 0===b||!b.length||!b[0]){var P="";for(w in E=[],o[x])this.terminals_[w]&&w>a&&E.push("'"+this.terminals_[w]+"'");P=p.showPosition?"Parse error on line "+(l+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(l+1)+": Unexpected "+(k==y?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(P,{text:p.match,token:this.terminals_[k]||k,line:p.yylineno,loc:m,expected:E})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+k);switch(b[0]){case 1:n.push(k),s.push(p.yytext),r.push(p.yylloc),n.push(b[1]),k=null,c=p.yyleng,h=p.yytext,l=p.yylineno,m=p.yylloc;break;case 2:if(I=this.productions_[b[1]][1],A.$=s[s.length-I],A._$={first_line:r[r.length-(I||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(I||1)].first_column,last_column:r[r.length-1].last_column},_&&(A._$.range=[r[r.length-(I||1)].range[0],r[r.length-1].range[1]]),void 0!==(v=this.performAction.apply(A,[h,c,l,f.yy,b[1],s,r].concat(u))))return v;I&&(n=n.slice(0,-1*I*2),s=s.slice(0,-1*I),r=r.slice(0,-1*I)),n.push(this.productions_[b[1]][0]),s.push(A.$),r.push(A._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},e={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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 e=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 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:n?(n.length===e.length?this.yylloc.first_column:0)+e[e.length-n.length].length-n[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+i+"^"},test_match:function(t,i){var n,e,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(e=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=e.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:e?e[e.length-1].length-e[e.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,n,e;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;ri[0].length)){if(i=n,e=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,s[e]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,n,e){switch(n){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}};function s(){this.yy={}}return n.lexer=e,s.prototype=n,n.Parser=s,new s}();s.parser=s;var r="",o=!1;const h={parser:s,db:{setMessage:t=>{i.debug("Setting message to: "+t),r=t},getMessage:()=>r,setInfo:t=>{o=t},getInfo:()=>o,clear:t},renderer:{draw:(t,s,r)=>{try{i.debug("Rendering info diagram\n"+t);const o=n().securityLevel;let h;"sandbox"===o&&(h=e("#i"+s));const l=e("sandbox"===o?h.nodes()[0].contentDocument.body:"body").select("#"+s);l.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size","32px").style("text-anchor","middle").text("v "+r),l.attr("height",100),l.attr("width",400)}catch(o){i.error("Error while rendering info diagram"),i.error(o.message)}}},styles:()=>""};export{h as diagram}; +import{z as t,l as i,c as n,h as e}from"./mermaid.core.3a590193.js";var s=function(){var t=function(t,i,n,e){for(n=n||{},e=t.length;e--;n[t[e]]=i);return n},i=[6,9,10],n={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,i,n,e,s,r,o){switch(r.length,s){case 1:return e;case 4:break;case 6:e.setInfo(!0)}},table:[{3:1,4:[1,2]},{1:[3]},t(i,[2,2],{5:3}),{6:[1,4],7:5,8:6,9:[1,7],10:[1,8]},{1:[2,1]},t(i,[2,3]),t(i,[2,4]),t(i,[2,5]),t(i,[2,6])],defaultActions:{4:[2,1]},parseError:function(t,i){if(!i.recoverable){var n=new Error(t);throw n.hash=i,n}this.trace(t)},parse:function(t){var i=this,n=[0],e=[],s=[null],r=[],o=this.table,h="",l=0,c=0,a=2,y=1,u=r.slice.call(arguments,1),p=Object.create(this.lexer),f={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(f.yy[g]=this.yy[g]);p.setInput(t,f.yy),f.yy.lexer=p,f.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;r.push(m);var _=p.options&&p.options.ranges;function d(){var t;return"number"!=typeof(t=e.pop()||p.lex()||y)&&(t instanceof Array&&(t=(e=t).pop()),t=i.symbols_[t]||t),t}"function"==typeof f.yy.parseError?this.parseError=f.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var k,x,b,v,w,I,S,E,A={};;){if(x=n[n.length-1],this.defaultActions[x]?b=this.defaultActions[x]:(null==k&&(k=d()),b=o[x]&&o[x][k]),void 0===b||!b.length||!b[0]){var P="";for(w in E=[],o[x])this.terminals_[w]&&w>a&&E.push("'"+this.terminals_[w]+"'");P=p.showPosition?"Parse error on line "+(l+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(l+1)+": Unexpected "+(k==y?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(P,{text:p.match,token:this.terminals_[k]||k,line:p.yylineno,loc:m,expected:E})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+x+", token: "+k);switch(b[0]){case 1:n.push(k),s.push(p.yytext),r.push(p.yylloc),n.push(b[1]),k=null,c=p.yyleng,h=p.yytext,l=p.yylineno,m=p.yylloc;break;case 2:if(I=this.productions_[b[1]][1],A.$=s[s.length-I],A._$={first_line:r[r.length-(I||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(I||1)].first_column,last_column:r[r.length-1].last_column},_&&(A._$.range=[r[r.length-(I||1)].range[0],r[r.length-1].range[1]]),void 0!==(v=this.performAction.apply(A,[h,c,l,f.yy,b[1],s,r].concat(u))))return v;I&&(n=n.slice(0,-1*I*2),s=s.slice(0,-1*I),r=r.slice(0,-1*I)),n.push(this.productions_[b[1]][0]),s.push(A.$),r.push(A._$),S=o[n[n.length-2]][n[n.length-1]],n.push(S);break;case 3:return!0}}return!0}},e={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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 e=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 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:n?(n.length===e.length?this.yylloc.first_column:0)+e[e.length-n.length].length-n[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+i+"^"},test_match:function(t,i){var n,e,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(e=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=e.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:e?e[e.length-1].length-e[e.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,n,e;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;ri[0].length)){if(i=n,e=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,s[e]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,n,e){switch(n){case 0:return 4;case 1:return 9;case 2:return"space";case 3:return 10;case 4:return 6;case 5:return"TXT"}},rules:[/^(?:info\b)/i,/^(?:[\s\n\r]+)/i,/^(?:[\s]+)/i,/^(?:showInfo\b)/i,/^(?:$)/i,/^(?:.)/i],conditions:{INITIAL:{rules:[0,1,2,3,4,5],inclusive:!0}}};function s(){this.yy={}}return n.lexer=e,s.prototype=n,n.Parser=s,new s}();s.parser=s;var r="",o=!1;const h={parser:s,db:{setMessage:t=>{i.debug("Setting message to: "+t),r=t},getMessage:()=>r,setInfo:t=>{o=t},getInfo:()=>o,clear:t},renderer:{draw:(t,s,r)=>{try{i.debug("Rendering info diagram\n"+t);const o=n().securityLevel;let h;"sandbox"===o&&(h=e("#i"+s));const l=e("sandbox"===o?h.nodes()[0].contentDocument.body:"body").select("#"+s);l.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size","32px").style("text-anchor","middle").text("v "+r),l.attr("height",100),l.attr("width",400)}catch(o){i.error("Error while rendering info diagram"),i.error(o.message)}}},styles:()=>""};export{h as diagram}; diff --git a/assets/install.html.a6fadd36.js b/assets/install.html.a5399da3.js similarity index 99% rename from assets/install.html.a6fadd36.js rename to assets/install.html.a5399da3.js index b009b7b0b..1d985e627 100644 --- a/assets/install.html.a6fadd36.js +++ b/assets/install.html.a5399da3.js @@ -1 +1 @@ -import{r as e,o as r,c as a,a as l,b as n,F as t,d as o,e as i}from"./app.755d843f.js";const h={},s=o('

    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=i("Precompiled binaries in ZIP format are available at "),d={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},c=i("GitHub Releases"),p=i(" found in."),f=l("p",null,"Download the compressed package of the corresponding platform, and use it after decompression.",-1),b=l("h2",{id:"verify-the-installation-package",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#verify-the-installation-package","aria-hidden":"true"},"#"),i(" Verify the Installation Package")],-1),g=l("p",null,"Xray provides two verification methods:",-1),m=l("li",null,"SHA1/SHA256 digest of the ZIP archive",-1),y=i("Reproducible build: Please refer to "),x={href:"https://xtls.github.io/development/intro/compile.html",target:"_blank",rel:"noopener noreferrer"},k=i("Compile Xray"),w=l("h2",{id:"install-on-windows",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#install-on-windows","aria-hidden":"true"},"#"),i(" Install on Windows")],-1),_=i("Download the ZIP archive suitable for the Windows platform on "),v={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},S=i("Github Releases"),X=i(". After decompression, you can get an executable file "),A=l("code",null,"xray.exe",-1),I=i(", and then run it with "),P=l("a",{href:"./command"},"parameters",-1),D=i(" through the command line."),N=i("By "),R={href:"https://scoop.sh/",target:"_blank",rel:"noopener noreferrer"},U=i("Scoop"),L=i(" Package manager installation: Xray has been added to "),O={href:"https://github.com/Qv2ray/mochi",target:"_blank",rel:"noopener noreferrer"},T=i("Mochi"),F=i("."),M=l("h2",{id:"install-on-macos",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#install-on-macos","aria-hidden":"true"},"#"),i(" Install on macOS")],-1),W=i("Download the ZIP archive suitable for the macOS platform on "),j={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},C=i("Github Releases"),G=i(". After decompression, you can get an executable file "),Q=l("code",null,"xray",-1),B=i(", and then run it with "),H=l("a",{href:"./command"},"parameters",-1),K=i(" through the command line."),Z=i("By "),V={href:"https://brew.sh/",target:"_blank",rel:"noopener noreferrer"},q=i("Homebrew"),z=i(" Package manager installation: "),E=l("code",null,"brew install xray",-1),J={href:"https://github.com/N4FA/homebrew-xray",target:"_blank",rel:"noopener noreferrer"},Y=i("homebrew-xray"),$=i(": Thanks "),ee={href:"https://github.com/N4FA",target:"_blank",rel:"noopener noreferrer"},re=i("@N4FA"),ae=l("h2",{id:"install-on-linux",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#install-on-linux","aria-hidden":"true"},"#"),i(" Install on Linux")],-1),le=l("h3",{id:"install-script",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#install-script","aria-hidden":"true"},"#"),i(" Install Script")],-1),ne=l("p",null,"Linux Script",-1),te={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},oe=i("Xray-install"),ie=l("p",null,"One Click",-1),he={href:"https://github.com/kirin10000/Xray-script",target:"_blank",rel:"noopener noreferrer"},se=i("Xray-script"),ue={href:"https://github.com/proxysu/ProxySU",target:"_blank",rel:"noopener noreferrer"},de=i("ProxySU"),ce={href:"https://github.com/reeceyng/v2ray-agent",target:"_blank",rel:"noopener noreferrer"},pe=i("Xray-agent"),fe=i(" Thanks "),be={href:"https://github.com/mack-a",target:"_blank",rel:"noopener noreferrer"},ge=i("@mack-a"),me=i(),ye={href:"https://github.com/reeceyng",target:"_blank",rel:"noopener noreferrer"},xe=i("@Reece"),ke=l("p",null,"Magisk",-1),we={href:"https://github.com/CerteKim/Xray4Magisk",target:"_blank",rel:"noopener noreferrer"},_e=i("Xray4Magisk"),ve={href:"https://github.com/E7KMbb/Xray_For_Magisk",target:"_blank",rel:"noopener noreferrer"},Se=i("Xray_For_Magisk"),Xe=l("h3",{id:"arch-linux",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-linux","aria-hidden":"true"},"#"),i(" Arch Linux")],-1),Ae=l("h4",{id:"arch-user-repository",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-user-repository","aria-hidden":"true"},"#"),i(" Arch User Repository")],-1),Ie=i("Need to use "),Pe={href:"https://wiki.archlinux.org/index.php/AUR_helpers",target:"_blank",rel:"noopener noreferrer"},De=i("AUR helpers"),Ne=i(", "),Re={href:"https://github.com/Jguer/yay",target:"_blank",rel:"noopener noreferrer"},Ue=i("yay"),Le=i(" as an example, it can be installed via "),Oe=l("code",null,"yay -S xray",-1),Te=i("."),Fe=l("h4",{id:"arch-linux-cn",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-linux-cn","aria-hidden":"true"},"#"),i(" Arch Linux CN")],-1),Me=i("First add "),We={href:"https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/",target:"_blank",rel:"noopener noreferrer"},je=i("Arch Linux CN"),Ce=i(" repository, and then use the root user "),Ge=l("code",null,"pacman -S xray",-1),Qe=i("to install."),Be=l("h3",{id:"linuxbrew",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#linuxbrew","aria-hidden":"true"},"#"),i(" Linuxbrew")],-1),He=l("p",null,[i("The Linuxbrew package manager is used in the same way as Homebrew: "),l("code",null,"brew install xray")],-1),Ke={id:"debian",tabindex:"-1"},Ze=l("a",{class:"header-anchor",href:"#debian","aria-hidden":"true"},"#",-1),Ve=i(" Debian "),qe=l("h2",{id:"install-via-docker",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#install-via-docker","aria-hidden":"true"},"#"),i(" Install via Docker")],-1),ze={href:"https://hub.docker.com/r/teddysun/xray",target:"_blank",rel:"noopener noreferrer"},Ee=i("teddysun/xray"),Je=o('

    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),Ye=i("OpenWrt "),$e={href:"https://github.com/xiaorouji/openwrt-passwall",target:"_blank",rel:"noopener noreferrer"},er=i("PassWall"),rr={href:"https://github.com/jerrykuku/luci-app-vssr",target:"_blank",rel:"noopener noreferrer"},ar=i("Hello World"),lr={href:"https://github.com/fw876/helloworld",target:"_blank",rel:"noopener noreferrer"},nr=i("ShadowSocksR Plus+"),tr={href:"https://github.com/yichya/luci-app-xray",target:"_blank",rel:"noopener noreferrer"},or=i("luci-app-xray"),ir=i(" ("),hr={href:"https://github.com/yichya/openwrt-xray",target:"_blank",rel:"noopener noreferrer"},sr=i("openwrt-xray"),ur=i(")"),dr=i("Windows "),cr={href:"https://github.com/2dust/v2rayN",target:"_blank",rel:"noopener noreferrer"},pr=i("v2rayN"),fr={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},br=i("Qv2ray"),gr=i(" (This project has been and archived)"),mr={href:"https://github.com/NetchX/Netch",target:"_blank",rel:"noopener noreferrer"},yr=i("Netch (NetFilter & TUN/TAP)"),xr=i(" (This project has been and archived)"),kr=i("Android "),wr={href:"https://github.com/2dust/v2rayNG",target:"_blank",rel:"noopener noreferrer"},_r=i("v2rayNG"),vr={href:"https://github.com/rurirei/Kitsunebi/tree/release_xtls",target:"_blank",rel:"noopener noreferrer"},Sr=i("Kitsunebi"),Xr=i("iOS / macOS (ARM) "),Ar={href:"https://apps.apple.com/app/shadowrocket/id932747118",target:"_blank",rel:"noopener noreferrer"},Ir=i("Shadowrocket"),Pr={href:"https://apps.apple.com/app/stash/id1596063349",target:"_blank",rel:"noopener noreferrer"},Dr=i("Stash"),Nr=i("macOS (X86/ARM) "),Rr={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},Ur=i("Qv2ray"),Lr=i(" (This project has been and archived)"),Or={href:"https://github.com/tzmax/V2RayXS",target:"_blank",rel:"noopener noreferrer"},Tr=i("V2RayXS"),Fr=l("h1",{id:"uuid-generator",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#uuid-generator","aria-hidden":"true"},"#"),i(" UUID Generator")],-1),Mr=i("Third-party UUID generator "),Wr={href:"https://www.uuidgenerator.net",target:"_blank",rel:"noopener noreferrer"},jr=i("uuidgenerator.net");h.render=function(o,i){const h=e("OutboundLink"),Cr=e("Badge");return r(),a(t,null,[s,l("p",null,[u,l("a",d,[c,n(h)]),p]),f,b,g,l("ul",null,[m,l("li",null,[y,l("a",x,[k,n(h)])])]),w,l("ul",null,[l("li",null,[_,l("a",v,[S,n(h)]),X,A,I,P,D]),l("li",null,[N,l("a",R,[U,n(h)]),L,l("a",O,[T,n(h)]),F])]),M,l("ul",null,[l("li",null,[W,l("a",j,[C,n(h)]),G,Q,B,H,K]),l("li",null,[Z,l("a",V,[q,n(h)]),z,E]),l("li",null,[l("a",J,[Y,n(h)]),$,l("a",ee,[re,n(h)])])]),ae,le,l("ul",null,[l("li",null,[ne,l("ul",null,[l("li",null,[l("a",te,[oe,n(h)])])])])]),l("ul",null,[l("li",null,[ie,l("ul",null,[l("li",null,[l("a",he,[se,n(h)])]),l("li",null,[l("a",ue,[de,n(h)])]),l("li",null,[l("a",ce,[pe,n(h)]),fe,l("a",be,[ge,n(h)]),me,l("a",ye,[xe,n(h)])])])]),l("li",null,[ke,l("ul",null,[l("li",null,[l("a",we,[_e,n(h)])]),l("li",null,[l("a",ve,[Se,n(h)])])])])]),Xe,Ae,l("p",null,[Ie,l("a",Pe,[De,n(h)]),Ne,l("a",Re,[Ue,n(h)]),Le,Oe,Te]),Fe,l("p",null,[Me,l("a",We,[je,n(h)]),Ce,Ge,Qe]),Be,He,l("h3",Ke,[Ze,Ve,n(Cr,{text:"WIP",type:"warning"})]),qe,l("ul",null,[l("li",null,[l("a",ze,[Ee,n(h)])])]),Je,l("ul",null,[l("li",null,[Ye,l("ul",null,[l("li",null,[l("a",$e,[er,n(h)])]),l("li",null,[l("a",rr,[ar,n(h)])]),l("li",null,[l("a",lr,[nr,n(h)])]),l("li",null,[l("a",tr,[or,n(h)]),ir,l("a",hr,[sr,n(h)]),ur])])]),l("li",null,[dr,l("ul",null,[l("li",null,[l("a",cr,[pr,n(h)])]),l("li",null,[l("a",fr,[br,n(h)]),gr]),l("li",null,[l("a",mr,[yr,n(h)]),xr])])]),l("li",null,[kr,l("ul",null,[l("li",null,[l("a",wr,[_r,n(h)])]),l("li",null,[l("a",vr,[Sr,n(h)])])])]),l("li",null,[Xr,l("ul",null,[l("li",null,[l("a",Ar,[Ir,n(h)])]),l("li",null,[l("a",Pr,[Dr,n(h)])])])]),l("li",null,[Nr,l("ul",null,[l("li",null,[l("a",Rr,[Ur,n(h)]),Lr]),l("li",null,[l("a",Or,[Tr,n(h)])])])])]),Fr,l("p",null,[Mr,l("a",Wr,[jr,n(h)])])],64)};export default h; +import{r as e,o as r,c as a,a as l,b as n,F as t,d as o,e as i}from"./app.48111a85.js";const h={},s=o('

    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=i("Precompiled binaries in ZIP format are available at "),d={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},c=i("GitHub Releases"),p=i(" found in."),f=l("p",null,"Download the compressed package of the corresponding platform, and use it after decompression.",-1),b=l("h2",{id:"verify-the-installation-package",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#verify-the-installation-package","aria-hidden":"true"},"#"),i(" Verify the Installation Package")],-1),g=l("p",null,"Xray provides two verification methods:",-1),m=l("li",null,"SHA1/SHA256 digest of the ZIP archive",-1),y=i("Reproducible build: Please refer to "),x={href:"https://xtls.github.io/development/intro/compile.html",target:"_blank",rel:"noopener noreferrer"},k=i("Compile Xray"),w=l("h2",{id:"install-on-windows",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#install-on-windows","aria-hidden":"true"},"#"),i(" Install on Windows")],-1),_=i("Download the ZIP archive suitable for the Windows platform on "),v={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},S=i("Github Releases"),X=i(". After decompression, you can get an executable file "),A=l("code",null,"xray.exe",-1),I=i(", and then run it with "),P=l("a",{href:"./command"},"parameters",-1),D=i(" through the command line."),N=i("By "),R={href:"https://scoop.sh/",target:"_blank",rel:"noopener noreferrer"},U=i("Scoop"),L=i(" Package manager installation: Xray has been added to "),O={href:"https://github.com/Qv2ray/mochi",target:"_blank",rel:"noopener noreferrer"},T=i("Mochi"),F=i("."),M=l("h2",{id:"install-on-macos",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#install-on-macos","aria-hidden":"true"},"#"),i(" Install on macOS")],-1),W=i("Download the ZIP archive suitable for the macOS platform on "),j={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},C=i("Github Releases"),G=i(". After decompression, you can get an executable file "),Q=l("code",null,"xray",-1),B=i(", and then run it with "),H=l("a",{href:"./command"},"parameters",-1),K=i(" through the command line."),Z=i("By "),V={href:"https://brew.sh/",target:"_blank",rel:"noopener noreferrer"},q=i("Homebrew"),z=i(" Package manager installation: "),E=l("code",null,"brew install xray",-1),J={href:"https://github.com/N4FA/homebrew-xray",target:"_blank",rel:"noopener noreferrer"},Y=i("homebrew-xray"),$=i(": Thanks "),ee={href:"https://github.com/N4FA",target:"_blank",rel:"noopener noreferrer"},re=i("@N4FA"),ae=l("h2",{id:"install-on-linux",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#install-on-linux","aria-hidden":"true"},"#"),i(" Install on Linux")],-1),le=l("h3",{id:"install-script",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#install-script","aria-hidden":"true"},"#"),i(" Install Script")],-1),ne=l("p",null,"Linux Script",-1),te={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},oe=i("Xray-install"),ie=l("p",null,"One Click",-1),he={href:"https://github.com/kirin10000/Xray-script",target:"_blank",rel:"noopener noreferrer"},se=i("Xray-script"),ue={href:"https://github.com/proxysu/ProxySU",target:"_blank",rel:"noopener noreferrer"},de=i("ProxySU"),ce={href:"https://github.com/reeceyng/v2ray-agent",target:"_blank",rel:"noopener noreferrer"},pe=i("Xray-agent"),fe=i(" Thanks "),be={href:"https://github.com/mack-a",target:"_blank",rel:"noopener noreferrer"},ge=i("@mack-a"),me=i(),ye={href:"https://github.com/reeceyng",target:"_blank",rel:"noopener noreferrer"},xe=i("@Reece"),ke=l("p",null,"Magisk",-1),we={href:"https://github.com/CerteKim/Xray4Magisk",target:"_blank",rel:"noopener noreferrer"},_e=i("Xray4Magisk"),ve={href:"https://github.com/E7KMbb/Xray_For_Magisk",target:"_blank",rel:"noopener noreferrer"},Se=i("Xray_For_Magisk"),Xe=l("h3",{id:"arch-linux",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-linux","aria-hidden":"true"},"#"),i(" Arch Linux")],-1),Ae=l("h4",{id:"arch-user-repository",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-user-repository","aria-hidden":"true"},"#"),i(" Arch User Repository")],-1),Ie=i("Need to use "),Pe={href:"https://wiki.archlinux.org/index.php/AUR_helpers",target:"_blank",rel:"noopener noreferrer"},De=i("AUR helpers"),Ne=i(", "),Re={href:"https://github.com/Jguer/yay",target:"_blank",rel:"noopener noreferrer"},Ue=i("yay"),Le=i(" as an example, it can be installed via "),Oe=l("code",null,"yay -S xray",-1),Te=i("."),Fe=l("h4",{id:"arch-linux-cn",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-linux-cn","aria-hidden":"true"},"#"),i(" Arch Linux CN")],-1),Me=i("First add "),We={href:"https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/",target:"_blank",rel:"noopener noreferrer"},je=i("Arch Linux CN"),Ce=i(" repository, and then use the root user "),Ge=l("code",null,"pacman -S xray",-1),Qe=i("to install."),Be=l("h3",{id:"linuxbrew",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#linuxbrew","aria-hidden":"true"},"#"),i(" Linuxbrew")],-1),He=l("p",null,[i("The Linuxbrew package manager is used in the same way as Homebrew: "),l("code",null,"brew install xray")],-1),Ke={id:"debian",tabindex:"-1"},Ze=l("a",{class:"header-anchor",href:"#debian","aria-hidden":"true"},"#",-1),Ve=i(" Debian "),qe=l("h2",{id:"install-via-docker",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#install-via-docker","aria-hidden":"true"},"#"),i(" Install via Docker")],-1),ze={href:"https://hub.docker.com/r/teddysun/xray",target:"_blank",rel:"noopener noreferrer"},Ee=i("teddysun/xray"),Je=o('

    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),Ye=i("OpenWrt "),$e={href:"https://github.com/xiaorouji/openwrt-passwall",target:"_blank",rel:"noopener noreferrer"},er=i("PassWall"),rr={href:"https://github.com/jerrykuku/luci-app-vssr",target:"_blank",rel:"noopener noreferrer"},ar=i("Hello World"),lr={href:"https://github.com/fw876/helloworld",target:"_blank",rel:"noopener noreferrer"},nr=i("ShadowSocksR Plus+"),tr={href:"https://github.com/yichya/luci-app-xray",target:"_blank",rel:"noopener noreferrer"},or=i("luci-app-xray"),ir=i(" ("),hr={href:"https://github.com/yichya/openwrt-xray",target:"_blank",rel:"noopener noreferrer"},sr=i("openwrt-xray"),ur=i(")"),dr=i("Windows "),cr={href:"https://github.com/2dust/v2rayN",target:"_blank",rel:"noopener noreferrer"},pr=i("v2rayN"),fr={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},br=i("Qv2ray"),gr=i(" (This project has been and archived)"),mr={href:"https://github.com/NetchX/Netch",target:"_blank",rel:"noopener noreferrer"},yr=i("Netch (NetFilter & TUN/TAP)"),xr=i(" (This project has been and archived)"),kr=i("Android "),wr={href:"https://github.com/2dust/v2rayNG",target:"_blank",rel:"noopener noreferrer"},_r=i("v2rayNG"),vr={href:"https://github.com/rurirei/Kitsunebi/tree/release_xtls",target:"_blank",rel:"noopener noreferrer"},Sr=i("Kitsunebi"),Xr=i("iOS / macOS (ARM) "),Ar={href:"https://apps.apple.com/app/shadowrocket/id932747118",target:"_blank",rel:"noopener noreferrer"},Ir=i("Shadowrocket"),Pr={href:"https://apps.apple.com/app/stash/id1596063349",target:"_blank",rel:"noopener noreferrer"},Dr=i("Stash"),Nr=i("macOS (X86/ARM) "),Rr={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},Ur=i("Qv2ray"),Lr=i(" (This project has been and archived)"),Or={href:"https://github.com/tzmax/V2RayXS",target:"_blank",rel:"noopener noreferrer"},Tr=i("V2RayXS"),Fr=l("h1",{id:"uuid-generator",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#uuid-generator","aria-hidden":"true"},"#"),i(" UUID Generator")],-1),Mr=i("Third-party UUID generator "),Wr={href:"https://www.uuidgenerator.net",target:"_blank",rel:"noopener noreferrer"},jr=i("uuidgenerator.net");h.render=function(o,i){const h=e("OutboundLink"),Cr=e("Badge");return r(),a(t,null,[s,l("p",null,[u,l("a",d,[c,n(h)]),p]),f,b,g,l("ul",null,[m,l("li",null,[y,l("a",x,[k,n(h)])])]),w,l("ul",null,[l("li",null,[_,l("a",v,[S,n(h)]),X,A,I,P,D]),l("li",null,[N,l("a",R,[U,n(h)]),L,l("a",O,[T,n(h)]),F])]),M,l("ul",null,[l("li",null,[W,l("a",j,[C,n(h)]),G,Q,B,H,K]),l("li",null,[Z,l("a",V,[q,n(h)]),z,E]),l("li",null,[l("a",J,[Y,n(h)]),$,l("a",ee,[re,n(h)])])]),ae,le,l("ul",null,[l("li",null,[ne,l("ul",null,[l("li",null,[l("a",te,[oe,n(h)])])])])]),l("ul",null,[l("li",null,[ie,l("ul",null,[l("li",null,[l("a",he,[se,n(h)])]),l("li",null,[l("a",ue,[de,n(h)])]),l("li",null,[l("a",ce,[pe,n(h)]),fe,l("a",be,[ge,n(h)]),me,l("a",ye,[xe,n(h)])])])]),l("li",null,[ke,l("ul",null,[l("li",null,[l("a",we,[_e,n(h)])]),l("li",null,[l("a",ve,[Se,n(h)])])])])]),Xe,Ae,l("p",null,[Ie,l("a",Pe,[De,n(h)]),Ne,l("a",Re,[Ue,n(h)]),Le,Oe,Te]),Fe,l("p",null,[Me,l("a",We,[je,n(h)]),Ce,Ge,Qe]),Be,He,l("h3",Ke,[Ze,Ve,n(Cr,{text:"WIP",type:"warning"})]),qe,l("ul",null,[l("li",null,[l("a",ze,[Ee,n(h)])])]),Je,l("ul",null,[l("li",null,[Ye,l("ul",null,[l("li",null,[l("a",$e,[er,n(h)])]),l("li",null,[l("a",rr,[ar,n(h)])]),l("li",null,[l("a",lr,[nr,n(h)])]),l("li",null,[l("a",tr,[or,n(h)]),ir,l("a",hr,[sr,n(h)]),ur])])]),l("li",null,[dr,l("ul",null,[l("li",null,[l("a",cr,[pr,n(h)])]),l("li",null,[l("a",fr,[br,n(h)]),gr]),l("li",null,[l("a",mr,[yr,n(h)]),xr])])]),l("li",null,[kr,l("ul",null,[l("li",null,[l("a",wr,[_r,n(h)])]),l("li",null,[l("a",vr,[Sr,n(h)])])])]),l("li",null,[Xr,l("ul",null,[l("li",null,[l("a",Ar,[Ir,n(h)])]),l("li",null,[l("a",Pr,[Dr,n(h)])])])]),l("li",null,[Nr,l("ul",null,[l("li",null,[l("a",Rr,[Ur,n(h)]),Lr]),l("li",null,[l("a",Or,[Tr,n(h)])])])])]),Fr,l("p",null,[Mr,l("a",Wr,[jr,n(h)])])],64)};export default h; diff --git a/assets/install.html.542ce2ed.js b/assets/install.html.b8e8854f.js similarity index 99% rename from assets/install.html.542ce2ed.js rename to assets/install.html.b8e8854f.js index 356d06000..7af922e8c 100644 --- a/assets/install.html.542ce2ed.js +++ b/assets/install.html.b8e8854f.js @@ -1 +1 @@ -import{r as e,o as r,c as a,a as l,b as n,w as t,F as o,d as i,e as h}from"./app.755d843f.js";const u={},s=i('

    下载安装

    平台支持

    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),c=h("预编译的二进制 ZIP 格式压缩包可在 "),d={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},p=h("Github Releases"),b=h(" 中找到。"),f=l("p",null,"下载对应平台的压缩包,解压后即可使用。",-1),g=l("h2",{id:"验证安装包",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#验证安装包","aria-hidden":"true"},"#"),h(" 验证安装包")],-1),y=l("p",null,"Xray 提供两种验证方式:",-1),m=l("li",null,"ZIP 压缩包的 SHA1 / SHA256 摘要",-1),x=h("可复现构建:请参照 "),k=h("编译 Xray"),_=l("h2",{id:"windows-安装方式",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#windows-安装方式","aria-hidden":"true"},"#"),h(" Windows 安装方式")],-1),w=h("在 "),X={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},S=h("Github Releases"),v=h(" 下载适用于 Windows 平台的 ZIP 压缩包,解压后可得到可执行文件 "),A=l("code",null,"xray.exe",-1),N=h(" ,然后"),O=l("a",{href:"./command"},"通过命令行带参数运行",-1),R=h(" 即可"),D=h("通过 "),L={href:"https://scoop.sh",target:"_blank",rel:"noopener noreferrer"},P=h("Scoop"),C=h(" 包管理器安装:Xray 已经被添加到 "),U={href:"https://github.com/Qv2ray/mochi",target:"_blank",rel:"noopener noreferrer"},M=h("Mochi"),F=h("。"),I=l("h2",{id:"macos-安装方式",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#macos-安装方式","aria-hidden":"true"},"#"),h(" macOS 安装方式")],-1),W=h("在 "),G={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},Q=h("Github Releases"),H=h(" 下载适用于 macOS 平台的 ZIP 压缩包,解压后可得到可执行文件 "),j=l("code",null,"xray",-1),B=h(" ,然后"),K=h("通过命令行带参数运行"),Z=h(" 即可"),z=h("通过 "),J={href:"https://brew.sh",target:"_blank",rel:"noopener noreferrer"},T=h("Homebrew"),V=h(" 包管理器安装:"),q=l("code",null,"brew install xray",-1),E={href:"https://github.com/N4FA/homebrew-xray",target:"_blank",rel:"noopener noreferrer"},Y=h("homebrew-xray"),$=h(" 感谢"),ee={href:"https://github.com/N4FA",target:"_blank",rel:"noopener noreferrer"},re=h("@N4FA"),ae=l("h2",{id:"linux-安装方式",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#linux-安装方式","aria-hidden":"true"},"#"),h(" Linux 安装方式")],-1),le=l("h3",{id:"安装脚本",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#安装脚本","aria-hidden":"true"},"#"),h(" 安装脚本")],-1),ne=l("p",null,"Linux Script",-1),te={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},oe=h("Xray-install"),ie=l("p",null,"One Click",-1),he={href:"https://github.com/kirin10000/Xray-script",target:"_blank",rel:"noopener noreferrer"},ue=h("Xray-script"),se={href:"https://github.com/proxysu/ProxySU",target:"_blank",rel:"noopener noreferrer"},ce=h("ProxySU"),de={href:"https://github.com/reeceyng/v2ray-agent",target:"_blank",rel:"noopener noreferrer"},pe=h("v2ray-agent"),be=h(" 感谢"),fe={href:"https://github.com/mack-a",target:"_blank",rel:"noopener noreferrer"},ge=h("@mack-a"),ye=h(),me={href:"https://github.com/reeceyng",target:"_blank",rel:"noopener noreferrer"},xe=h("@Reece"),ke={href:"https://github.com/jiuqi9997/Xray-yes",target:"_blank",rel:"noopener noreferrer"},_e=h("Xray-yes"),we={href:"https://github.com/wulabing/Xray_onekey",target:"_blank",rel:"noopener noreferrer"},Xe=h("Xray-onekey"),Se=l("p",null,"Magisk",-1),ve={href:"https://github.com/CerteKim/Xray4Magisk",target:"_blank",rel:"noopener noreferrer"},Ae=h("Xray4Magisk"),Ne={href:"https://github.com/E7KMbb/Xray_For_Magisk",target:"_blank",rel:"noopener noreferrer"},Oe=h("Xray_For_Magisk"),Re=l("h3",{id:"arch-linux",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-linux","aria-hidden":"true"},"#"),h(" Arch Linux")],-1),De=l("h4",{id:"arch-user-repository",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-user-repository","aria-hidden":"true"},"#"),h(" Arch User Repository")],-1),Le=h("需要使用 "),Pe={href:"https://wiki.archlinux.org/index.php/AUR_helpers",target:"_blank",rel:"noopener noreferrer"},Ce=h("AUR helpers"),Ue=h(",以 "),Me={href:"https://github.com/Jguer/yay",target:"_blank",rel:"noopener noreferrer"},Fe=h("yay"),Ie=h(" 为例,可通过 "),We=l("code",null,"yay -S xray",-1),Ge=h(" 安装。"),Qe=l("h4",{id:"arch-linux-cn",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-linux-cn","aria-hidden":"true"},"#"),h(" Arch Linux CN")],-1),He=h("首先添加 "),je={href:"https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/",target:"_blank",rel:"noopener noreferrer"},Be=h("Arch Linux CN 仓库"),Ke=h(",然后在 root 用户下使用 "),Ze=l("code",null,"pacman -S xray",-1),ze=h(" 安装。"),Je=l("h3",{id:"linuxbrew",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#linuxbrew","aria-hidden":"true"},"#"),h(" Linuxbrew")],-1),Te=l("p",null,[h("Linuxbrew 包管理器的使用方式与 Homebrew 一致:"),l("code",null,"brew install xray")],-1),Ve={id:"debian",tabindex:"-1"},qe=l("a",{class:"header-anchor",href:"#debian","aria-hidden":"true"},"#",-1),Ee=h(" Debian "),Ye=l("h3",{id:"gentoo",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#gentoo","aria-hidden":"true"},"#"),h(" Gentoo")],-1),$e=l("p",null,"目前有三个第三方 Overlay 提供 Portage 安装脚本:",-1),er={href:"https://github.com/gentoo-mirror/touchfish-os/tree/master/net-proxy/Xray",target:"_blank",rel:"noopener noreferrer"},rr=h("CHN-beta/touchfish-os"),ar=h(": 个人维护,适用于 systemD 系统"),lr={href:"https://github.com/microcai/gentoo-zh",target:"_blank",rel:"noopener noreferrer"},nr=h("Gentoo-zh"),tr=h(": 社区维护,适用于 systemD 系统"),or={href:"https://github.com/JuanCldCmt/Xray-Overlay",target:"_blank",rel:"noopener noreferrer"},ir=h("JuanCldCmt/Xray-Overlay"),hr=h(":个人维护,适用于 openRC 系统,同时使用 xray 用户组运行以提高安全性"),ur=l("p",null,"使用 layman 或 eselect-repository 添加 Overlay 至本地,然后即可安装。",-1),sr=l("h2",{id:"docker-安装方式",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#docker-安装方式","aria-hidden":"true"},"#"),h(" Docker 安装方式")],-1),cr={href:"https://hub.docker.com/r/teddysun/xray",target:"_blank",rel:"noopener noreferrer"},dr=h("teddysun/xray"),pr=i('

    Docker image 的文件结构

    • /etc/xray/config.json:配置文件
    • /usr/bin/xray:Xray 主程序
    • /usr/local/share/xray/geoip.dat:IP 数据文件
    • /usr/local/share/xray/geosite.dat:域名数据文件

    图形化客户端

    ',3),br=h("OpenWrt "),fr={href:"https://github.com/xiaorouji/openwrt-passwall",target:"_blank",rel:"noopener noreferrer"},gr=h("PassWall"),yr={href:"https://github.com/jerrykuku/luci-app-vssr",target:"_blank",rel:"noopener noreferrer"},mr=h("Hello World"),xr={href:"https://github.com/fw876/helloworld",target:"_blank",rel:"noopener noreferrer"},kr=h("ShadowSocksR Plus+"),_r={href:"https://github.com/yichya/luci-app-xray",target:"_blank",rel:"noopener noreferrer"},wr=h("luci-app-xray"),Xr=h(" ("),Sr={href:"https://github.com/yichya/openwrt-xray",target:"_blank",rel:"noopener noreferrer"},vr=h("openwrt-xray"),Ar=h(")"),Nr=h("Windows "),Or={href:"https://github.com/2dust/v2rayN",target:"_blank",rel:"noopener noreferrer"},Rr=h("v2rayN"),Dr={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},Lr=h("Qv2ray"),Pr=h(" (该项目已冻结存档)"),Cr={href:"https://github.com/NetchX/Netch",target:"_blank",rel:"noopener noreferrer"},Ur=h("Netch (NetFilter & TUN/TAP)"),Mr=h(" (该项目已冻结存档)"),Fr=h("Android "),Ir={href:"https://github.com/2dust/v2rayNG",target:"_blank",rel:"noopener noreferrer"},Wr=h("v2rayNG"),Gr={href:"https://github.com/rurirei/Kitsunebi/tree/release_xtls",target:"_blank",rel:"noopener noreferrer"},Qr=h("Kitsunebi"),Hr=h("iOS / macOS(使用 ARM 芯片) "),jr={href:"https://apps.apple.com/app/shadowrocket/id932747118",target:"_blank",rel:"noopener noreferrer"},Br=h("Shadowrocket"),Kr={href:"https://apps.apple.com/app/stash/id1596063349",target:"_blank",rel:"noopener noreferrer"},Zr=h("Stash"),zr=h("macOS(X86 芯片 / ARM 芯片) "),Jr={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},Tr=h("Qv2ray"),Vr=h(" (该项目已冻结存档)"),qr={href:"https://github.com/tzmax/V2RayXS",target:"_blank",rel:"noopener noreferrer"},Er=h("V2RayXS"),Yr=l("h1",{id:"uuid-生成器",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#uuid-生成器","aria-hidden":"true"},"#"),h(" UUID 生成器")],-1),$r=h("第三方的 UUID 生成器 "),ea={href:"https://www.uuidgenerator.net",target:"_blank",rel:"noopener noreferrer"},ra=h("uuidgenerator.net");u.render=function(i,h){const u=e("OutboundLink"),aa=e("RouterLink"),la=e("Badge");return r(),a(o,null,[s,l("p",null,[c,l("a",d,[p,n(u)]),b]),f,g,y,l("ul",null,[m,l("li",null,[x,n(aa,{to:"/development/intro/compile.html"},{default:t((()=>[k])),_:1})])]),_,l("ul",null,[l("li",null,[w,l("a",X,[S,n(u)]),v,A,N,O,R]),l("li",null,[D,l("a",L,[P,n(u)]),C,l("a",U,[M,n(u)]),F])]),I,l("ul",null,[l("li",null,[W,l("a",G,[Q,n(u)]),H,j,B,n(aa,{to:"/document/command.html"},{default:t((()=>[K])),_:1}),Z]),l("li",null,[z,l("a",J,[T,n(u)]),V,q]),l("li",null,[l("a",E,[Y,n(u)]),$,l("a",ee,[re,n(u)])])]),ae,le,l("ul",null,[l("li",null,[ne,l("ul",null,[l("li",null,[l("a",te,[oe,n(u)])])])])]),l("ul",null,[l("li",null,[ie,l("ul",null,[l("li",null,[l("a",he,[ue,n(u)])]),l("li",null,[l("a",se,[ce,n(u)])]),l("li",null,[l("a",de,[pe,n(u)]),be,l("a",fe,[ge,n(u)]),ye,l("a",me,[xe,n(u)])]),l("li",null,[l("a",ke,[_e,n(u)])]),l("li",null,[l("a",we,[Xe,n(u)])])])]),l("li",null,[Se,l("ul",null,[l("li",null,[l("a",ve,[Ae,n(u)])]),l("li",null,[l("a",Ne,[Oe,n(u)])])])])]),Re,De,l("p",null,[Le,l("a",Pe,[Ce,n(u)]),Ue,l("a",Me,[Fe,n(u)]),Ie,We,Ge]),Qe,l("p",null,[He,l("a",je,[Be,n(u)]),Ke,Ze,ze]),Je,Te,l("h3",Ve,[qe,Ee,n(la,{text:"WIP",type:"warning"})]),Ye,$e,l("ul",null,[l("li",null,[l("a",er,[rr,n(u)]),ar]),l("li",null,[l("a",lr,[nr,n(u)]),tr]),l("li",null,[l("a",or,[ir,n(u)]),hr])]),ur,sr,l("ul",null,[l("li",null,[l("a",cr,[dr,n(u)])])]),pr,l("ul",null,[l("li",null,[br,l("ul",null,[l("li",null,[l("a",fr,[gr,n(u)])]),l("li",null,[l("a",yr,[mr,n(u)])]),l("li",null,[l("a",xr,[kr,n(u)])]),l("li",null,[l("a",_r,[wr,n(u)]),Xr,l("a",Sr,[vr,n(u)]),Ar])])]),l("li",null,[Nr,l("ul",null,[l("li",null,[l("a",Or,[Rr,n(u)])]),l("li",null,[l("a",Dr,[Lr,n(u)]),Pr]),l("li",null,[l("a",Cr,[Ur,n(u)]),Mr])])]),l("li",null,[Fr,l("ul",null,[l("li",null,[l("a",Ir,[Wr,n(u)])]),l("li",null,[l("a",Gr,[Qr,n(u)])])])]),l("li",null,[Hr,l("ul",null,[l("li",null,[l("a",jr,[Br,n(u)])]),l("li",null,[l("a",Kr,[Zr,n(u)])])])]),l("li",null,[zr,l("ul",null,[l("li",null,[l("a",Jr,[Tr,n(u)]),Vr]),l("li",null,[l("a",qr,[Er,n(u)])])])])]),Yr,l("p",null,[$r,l("a",ea,[ra,n(u)])])],64)};export default u; +import{r as e,o as r,c as a,a as l,b as n,w as t,F as o,d as i,e as h}from"./app.48111a85.js";const u={},s=i('

    下载安装

    平台支持

    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),c=h("预编译的二进制 ZIP 格式压缩包可在 "),d={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},p=h("Github Releases"),b=h(" 中找到。"),f=l("p",null,"下载对应平台的压缩包,解压后即可使用。",-1),g=l("h2",{id:"验证安装包",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#验证安装包","aria-hidden":"true"},"#"),h(" 验证安装包")],-1),y=l("p",null,"Xray 提供两种验证方式:",-1),m=l("li",null,"ZIP 压缩包的 SHA1 / SHA256 摘要",-1),x=h("可复现构建:请参照 "),k=h("编译 Xray"),_=l("h2",{id:"windows-安装方式",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#windows-安装方式","aria-hidden":"true"},"#"),h(" Windows 安装方式")],-1),w=h("在 "),X={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},S=h("Github Releases"),v=h(" 下载适用于 Windows 平台的 ZIP 压缩包,解压后可得到可执行文件 "),A=l("code",null,"xray.exe",-1),N=h(" ,然后"),O=l("a",{href:"./command"},"通过命令行带参数运行",-1),R=h(" 即可"),D=h("通过 "),L={href:"https://scoop.sh",target:"_blank",rel:"noopener noreferrer"},P=h("Scoop"),C=h(" 包管理器安装:Xray 已经被添加到 "),U={href:"https://github.com/Qv2ray/mochi",target:"_blank",rel:"noopener noreferrer"},M=h("Mochi"),F=h("。"),I=l("h2",{id:"macos-安装方式",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#macos-安装方式","aria-hidden":"true"},"#"),h(" macOS 安装方式")],-1),W=h("在 "),G={href:"https://github.com/xtls/Xray-core/releases",target:"_blank",rel:"noopener noreferrer"},Q=h("Github Releases"),H=h(" 下载适用于 macOS 平台的 ZIP 压缩包,解压后可得到可执行文件 "),j=l("code",null,"xray",-1),B=h(" ,然后"),K=h("通过命令行带参数运行"),Z=h(" 即可"),z=h("通过 "),J={href:"https://brew.sh",target:"_blank",rel:"noopener noreferrer"},T=h("Homebrew"),V=h(" 包管理器安装:"),q=l("code",null,"brew install xray",-1),E={href:"https://github.com/N4FA/homebrew-xray",target:"_blank",rel:"noopener noreferrer"},Y=h("homebrew-xray"),$=h(" 感谢"),ee={href:"https://github.com/N4FA",target:"_blank",rel:"noopener noreferrer"},re=h("@N4FA"),ae=l("h2",{id:"linux-安装方式",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#linux-安装方式","aria-hidden":"true"},"#"),h(" Linux 安装方式")],-1),le=l("h3",{id:"安装脚本",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#安装脚本","aria-hidden":"true"},"#"),h(" 安装脚本")],-1),ne=l("p",null,"Linux Script",-1),te={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},oe=h("Xray-install"),ie=l("p",null,"One Click",-1),he={href:"https://github.com/kirin10000/Xray-script",target:"_blank",rel:"noopener noreferrer"},ue=h("Xray-script"),se={href:"https://github.com/proxysu/ProxySU",target:"_blank",rel:"noopener noreferrer"},ce=h("ProxySU"),de={href:"https://github.com/reeceyng/v2ray-agent",target:"_blank",rel:"noopener noreferrer"},pe=h("v2ray-agent"),be=h(" 感谢"),fe={href:"https://github.com/mack-a",target:"_blank",rel:"noopener noreferrer"},ge=h("@mack-a"),ye=h(),me={href:"https://github.com/reeceyng",target:"_blank",rel:"noopener noreferrer"},xe=h("@Reece"),ke={href:"https://github.com/jiuqi9997/Xray-yes",target:"_blank",rel:"noopener noreferrer"},_e=h("Xray-yes"),we={href:"https://github.com/wulabing/Xray_onekey",target:"_blank",rel:"noopener noreferrer"},Xe=h("Xray-onekey"),Se=l("p",null,"Magisk",-1),ve={href:"https://github.com/CerteKim/Xray4Magisk",target:"_blank",rel:"noopener noreferrer"},Ae=h("Xray4Magisk"),Ne={href:"https://github.com/E7KMbb/Xray_For_Magisk",target:"_blank",rel:"noopener noreferrer"},Oe=h("Xray_For_Magisk"),Re=l("h3",{id:"arch-linux",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-linux","aria-hidden":"true"},"#"),h(" Arch Linux")],-1),De=l("h4",{id:"arch-user-repository",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-user-repository","aria-hidden":"true"},"#"),h(" Arch User Repository")],-1),Le=h("需要使用 "),Pe={href:"https://wiki.archlinux.org/index.php/AUR_helpers",target:"_blank",rel:"noopener noreferrer"},Ce=h("AUR helpers"),Ue=h(",以 "),Me={href:"https://github.com/Jguer/yay",target:"_blank",rel:"noopener noreferrer"},Fe=h("yay"),Ie=h(" 为例,可通过 "),We=l("code",null,"yay -S xray",-1),Ge=h(" 安装。"),Qe=l("h4",{id:"arch-linux-cn",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#arch-linux-cn","aria-hidden":"true"},"#"),h(" Arch Linux CN")],-1),He=h("首先添加 "),je={href:"https://www.archlinuxcn.org/archlinux-cn-repo-and-mirror/",target:"_blank",rel:"noopener noreferrer"},Be=h("Arch Linux CN 仓库"),Ke=h(",然后在 root 用户下使用 "),Ze=l("code",null,"pacman -S xray",-1),ze=h(" 安装。"),Je=l("h3",{id:"linuxbrew",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#linuxbrew","aria-hidden":"true"},"#"),h(" Linuxbrew")],-1),Te=l("p",null,[h("Linuxbrew 包管理器的使用方式与 Homebrew 一致:"),l("code",null,"brew install xray")],-1),Ve={id:"debian",tabindex:"-1"},qe=l("a",{class:"header-anchor",href:"#debian","aria-hidden":"true"},"#",-1),Ee=h(" Debian "),Ye=l("h3",{id:"gentoo",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#gentoo","aria-hidden":"true"},"#"),h(" Gentoo")],-1),$e=l("p",null,"目前有三个第三方 Overlay 提供 Portage 安装脚本:",-1),er={href:"https://github.com/gentoo-mirror/touchfish-os/tree/master/net-proxy/Xray",target:"_blank",rel:"noopener noreferrer"},rr=h("CHN-beta/touchfish-os"),ar=h(": 个人维护,适用于 systemD 系统"),lr={href:"https://github.com/microcai/gentoo-zh",target:"_blank",rel:"noopener noreferrer"},nr=h("Gentoo-zh"),tr=h(": 社区维护,适用于 systemD 系统"),or={href:"https://github.com/JuanCldCmt/Xray-Overlay",target:"_blank",rel:"noopener noreferrer"},ir=h("JuanCldCmt/Xray-Overlay"),hr=h(":个人维护,适用于 openRC 系统,同时使用 xray 用户组运行以提高安全性"),ur=l("p",null,"使用 layman 或 eselect-repository 添加 Overlay 至本地,然后即可安装。",-1),sr=l("h2",{id:"docker-安装方式",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#docker-安装方式","aria-hidden":"true"},"#"),h(" Docker 安装方式")],-1),cr={href:"https://hub.docker.com/r/teddysun/xray",target:"_blank",rel:"noopener noreferrer"},dr=h("teddysun/xray"),pr=i('

    Docker image 的文件结构

    • /etc/xray/config.json:配置文件
    • /usr/bin/xray:Xray 主程序
    • /usr/local/share/xray/geoip.dat:IP 数据文件
    • /usr/local/share/xray/geosite.dat:域名数据文件

    图形化客户端

    ',3),br=h("OpenWrt "),fr={href:"https://github.com/xiaorouji/openwrt-passwall",target:"_blank",rel:"noopener noreferrer"},gr=h("PassWall"),yr={href:"https://github.com/jerrykuku/luci-app-vssr",target:"_blank",rel:"noopener noreferrer"},mr=h("Hello World"),xr={href:"https://github.com/fw876/helloworld",target:"_blank",rel:"noopener noreferrer"},kr=h("ShadowSocksR Plus+"),_r={href:"https://github.com/yichya/luci-app-xray",target:"_blank",rel:"noopener noreferrer"},wr=h("luci-app-xray"),Xr=h(" ("),Sr={href:"https://github.com/yichya/openwrt-xray",target:"_blank",rel:"noopener noreferrer"},vr=h("openwrt-xray"),Ar=h(")"),Nr=h("Windows "),Or={href:"https://github.com/2dust/v2rayN",target:"_blank",rel:"noopener noreferrer"},Rr=h("v2rayN"),Dr={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},Lr=h("Qv2ray"),Pr=h(" (该项目已冻结存档)"),Cr={href:"https://github.com/NetchX/Netch",target:"_blank",rel:"noopener noreferrer"},Ur=h("Netch (NetFilter & TUN/TAP)"),Mr=h(" (该项目已冻结存档)"),Fr=h("Android "),Ir={href:"https://github.com/2dust/v2rayNG",target:"_blank",rel:"noopener noreferrer"},Wr=h("v2rayNG"),Gr={href:"https://github.com/rurirei/Kitsunebi/tree/release_xtls",target:"_blank",rel:"noopener noreferrer"},Qr=h("Kitsunebi"),Hr=h("iOS / macOS(使用 ARM 芯片) "),jr={href:"https://apps.apple.com/app/shadowrocket/id932747118",target:"_blank",rel:"noopener noreferrer"},Br=h("Shadowrocket"),Kr={href:"https://apps.apple.com/app/stash/id1596063349",target:"_blank",rel:"noopener noreferrer"},Zr=h("Stash"),zr=h("macOS(X86 芯片 / ARM 芯片) "),Jr={href:"https://github.com/Qv2ray/Qv2ray",target:"_blank",rel:"noopener noreferrer"},Tr=h("Qv2ray"),Vr=h(" (该项目已冻结存档)"),qr={href:"https://github.com/tzmax/V2RayXS",target:"_blank",rel:"noopener noreferrer"},Er=h("V2RayXS"),Yr=l("h1",{id:"uuid-生成器",tabindex:"-1"},[l("a",{class:"header-anchor",href:"#uuid-生成器","aria-hidden":"true"},"#"),h(" UUID 生成器")],-1),$r=h("第三方的 UUID 生成器 "),ea={href:"https://www.uuidgenerator.net",target:"_blank",rel:"noopener noreferrer"},ra=h("uuidgenerator.net");u.render=function(i,h){const u=e("OutboundLink"),aa=e("RouterLink"),la=e("Badge");return r(),a(o,null,[s,l("p",null,[c,l("a",d,[p,n(u)]),b]),f,g,y,l("ul",null,[m,l("li",null,[x,n(aa,{to:"/development/intro/compile.html"},{default:t((()=>[k])),_:1})])]),_,l("ul",null,[l("li",null,[w,l("a",X,[S,n(u)]),v,A,N,O,R]),l("li",null,[D,l("a",L,[P,n(u)]),C,l("a",U,[M,n(u)]),F])]),I,l("ul",null,[l("li",null,[W,l("a",G,[Q,n(u)]),H,j,B,n(aa,{to:"/document/command.html"},{default:t((()=>[K])),_:1}),Z]),l("li",null,[z,l("a",J,[T,n(u)]),V,q]),l("li",null,[l("a",E,[Y,n(u)]),$,l("a",ee,[re,n(u)])])]),ae,le,l("ul",null,[l("li",null,[ne,l("ul",null,[l("li",null,[l("a",te,[oe,n(u)])])])])]),l("ul",null,[l("li",null,[ie,l("ul",null,[l("li",null,[l("a",he,[ue,n(u)])]),l("li",null,[l("a",se,[ce,n(u)])]),l("li",null,[l("a",de,[pe,n(u)]),be,l("a",fe,[ge,n(u)]),ye,l("a",me,[xe,n(u)])]),l("li",null,[l("a",ke,[_e,n(u)])]),l("li",null,[l("a",we,[Xe,n(u)])])])]),l("li",null,[Se,l("ul",null,[l("li",null,[l("a",ve,[Ae,n(u)])]),l("li",null,[l("a",Ne,[Oe,n(u)])])])])]),Re,De,l("p",null,[Le,l("a",Pe,[Ce,n(u)]),Ue,l("a",Me,[Fe,n(u)]),Ie,We,Ge]),Qe,l("p",null,[He,l("a",je,[Be,n(u)]),Ke,Ze,ze]),Je,Te,l("h3",Ve,[qe,Ee,n(la,{text:"WIP",type:"warning"})]),Ye,$e,l("ul",null,[l("li",null,[l("a",er,[rr,n(u)]),ar]),l("li",null,[l("a",lr,[nr,n(u)]),tr]),l("li",null,[l("a",or,[ir,n(u)]),hr])]),ur,sr,l("ul",null,[l("li",null,[l("a",cr,[dr,n(u)])])]),pr,l("ul",null,[l("li",null,[br,l("ul",null,[l("li",null,[l("a",fr,[gr,n(u)])]),l("li",null,[l("a",yr,[mr,n(u)])]),l("li",null,[l("a",xr,[kr,n(u)])]),l("li",null,[l("a",_r,[wr,n(u)]),Xr,l("a",Sr,[vr,n(u)]),Ar])])]),l("li",null,[Nr,l("ul",null,[l("li",null,[l("a",Or,[Rr,n(u)])]),l("li",null,[l("a",Dr,[Lr,n(u)]),Pr]),l("li",null,[l("a",Cr,[Ur,n(u)]),Mr])])]),l("li",null,[Fr,l("ul",null,[l("li",null,[l("a",Ir,[Wr,n(u)])]),l("li",null,[l("a",Gr,[Qr,n(u)])])])]),l("li",null,[Hr,l("ul",null,[l("li",null,[l("a",jr,[Br,n(u)])]),l("li",null,[l("a",Kr,[Zr,n(u)])])])]),l("li",null,[zr,l("ul",null,[l("li",null,[l("a",Jr,[Tr,n(u)]),Vr]),l("li",null,[l("a",qr,[Er,n(u)])])])])]),Yr,l("p",null,[$r,l("a",ea,[ra,n(u)])])],64)};export default u; diff --git a/assets/iptables_gid.html.bbe2cc3c.js b/assets/iptables_gid.html.5d9991f3.js similarity index 99% rename from assets/iptables_gid.html.bbe2cc3c.js rename to assets/iptables_gid.html.5d9991f3.js index d841241ed..94d520530 100644 --- a/assets/iptables_gid.html.bbe2cc3c.js +++ b/assets/iptables_gid.html.5d9991f3.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as t,w as r,F as p,e as o,d as l}from"./app.755d843f.js";const i={},u=e("h1",{id:"transparent-proxy-to-circumvent-xray-traffic-via-gid",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#transparent-proxy-to-circumvent-xray-traffic-via-gid","aria-hidden":"true"},"#"),o(" Transparent proxy to circumvent Xray traffic via GID")],-1),c=o("In the existing transparent proxy configuration("),d={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},m=o("New V2Ray vernacular tutorial on transparent proxy"),b=o(" 、 "),h={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},g=o("New V2Ray vernacular tutorial on transparent proxy (TProxy)"),f=o(" 、 "),y=o("Transparent proxy(TProxy)configuration tutorial"),k=o(")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."),x=e("p",null,"There are several problems with this method:",-1),v={href:"https://github.com/v2ray/v2ray-core/issues/2621",target:"_blank",rel:"noopener noreferrer"},A=o("Inexplicable traffic into PREROUTING chain"),w=e("li",null,[e("p",null,"Android has its own mark mechanism and this solution is not available on Android")],-1),q=l('

    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),R=e("li",null,[e("p",null,"System has root privilege.")],-1),_=o("Install "),T={href:"https://play.google.com/store/apps/details?id=stericson.busybox",target:"_blank",rel:"noopener noreferrer"},X=o("busybox"),P=e("li",null,[e("p",null,"There is a terminal that can execute commands, you can use adb shell, termux etc.")],-1),Y=l('

    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\n
    1

    Also attached are some common dependencies for openwrt, the lack of which may prevent Xray from running

    opkg install libopenssl ca-certificates\n
    1

    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\n
    1

    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\n
    1

    The result displayed should be uid 0 and gid 23333.

    3. Configure and run Xray, and configure iptables rules

    ',13),N=o("In the existing transparent proxy configuration("),j={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},U=o("New V2Ray vernacular tutorial on transparent proxy"),E=o(" 、 "),S={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},I=o("New V2Ray vernacular tutorial on transparent proxy (TProxy)"),M=o(" 、 "),O=e("strong",null,[e("a",{href:"../tproxy"},"Transparent proxy(TProxy)configuration tutorial")],-1),L=o(")tutorials, modify:"),K=l('
    1. Modify the json configuration file: remove mark-related content

    2. Modify the iptables rule to remove the mark-related content and add the option at the OUTPUT chain application rule: -m owner ! --gid-owner 23333

    e.g.:

    iptables -t mangle -A OUTPUT -j XRAY_SELF

    Change to

    iptables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 -j XRAY_SELF

    1. Modify the way you run Xray so that it runs on a user with uid 0 and gid 23333, refer to here.

    Steps

    The following provides a complete configuration process for implementing the tproxy global proxy

    1. Finish Preliminary preparation and Add user

    2. Preparing Xray profiles

    Configure Xray to listen to 12345 at dokodemo-door, turn on followRedirect and tproxy, no sniffing required:

    {\n  "inbounds": [\n    {\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy"\n        }\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      // Your server configuration\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    3. Configuring the maximum number of open files and run the Xray client

    ',13),C=o("About the maximum number of open files, see: "),F={href:"https://guide.v2fly.org/app/tproxy.html#%E8%A7%A3%E5%86%B3-too-many-open-files-%E9%97%AE%E9%A2%98",target:"_blank",rel:"noopener noreferrer"},G=o("too many open files issues"),V=l('

    The current Xray server installed with the official script has the maximum number of open files automatically configured, so no further changes are required.

    Android

    ulimit -SHn 1000000\nsetuidgid 0:23333 "Command to run Xray"&\n
    1
    2

    Other Linux system

    ulimit -SHn 1000000\nsudo -u xray_tproxy "Command to run Xray"&\n
    1
    2

    e.g.:

    ulimit -SHn 1000000\nsudo -u xray_tproxy xray -c /etc/xray/config.json &\n
    1
    2

    The first command:

    Change the maximum number of open files, valid only for the current terminal and to be run every time before starting Xray, this command is to set the maximum number of open files for the client.

    The second command:

    Run the Xray client as a user with uid 0 and gid not 0, followed by & for running in the background.

    Check if the maximum number of open files is set successfully

    cat /proc/"Xray's pid"/limits\n
    1

    Find max open files, which should be the value you set. Xray's pid can be obtained by running ps or ps -aux or ps -a

    Both the server and client side should be checked.

    4. Setting up iptables rules

    Proxy ipv4

    ip rule add fwmark 1 table 100\nip route add local 0.0.0.0/0 dev lo table 100\n\n# Proxy LAN devices\niptables -t mangle -N XRAY\n# "ipv4 segment where the gateway is located" is obtained by running the command "ip address | grep -w inet | awk '{print $2}'", usually there are multiple\niptables -t mangle -A XRAY -d "first ipv4 segment where the gateway is located" -j RETURN\niptables -t mangle -A XRAY -d "second ipv4 segment where the gateway is located" -j RETURN\n\n# If the gateway is used as the primary router, add this line, see: [Other considerations for transparent proxy of iptables](https://xtls.github.io/en/documents/level-2/transparent_proxy/transparent_proxy/#proxy-ipv6)\n# The "gateway LAN_IPv4 address segment", obtained by running the command "ip address | grep -w "inet" | awk '{print $2}'", is one of the results\niptables -t mangle -A XRAY ! -s "gateway LAN_IPv4 address segment" -j RETURN\n\n# Mark 1 for TCP and forward to port 12345\n# mark can only be set to 1 for the traffic to be accepted by the Xray dokodemo-door\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port 12345 --tproxy-mark 1\n# Apply rules\niptables -t mangle -A PREROUTING -j XRAY\n\n# Proxy gateway itself\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -d "the first ipv4 segment where the gateway is located" -j RETURN\niptables -t mangle -A XRAY_MASK -d "the second ipv4 segment where the gateway is located" -j RETURN\n\niptables -t mangle -A XRAY_MASK -j MARK --set-mark 1\niptables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 ! -p icmp -j XRAY_MASK\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    Proxy ipv6 (optional)

    ip -6 rule add fwmark 1 table 106\nip -6 route add local ::/0 dev lo table 106\n\n# Proxy LAN devices\nip6tables -t mangle -N XRAY6\n# The "ipv6 segment where the gateway is located" is obtained by running the command "ip address | grep -w inet6 | awk '{print $2}'".\nip6tables -t mangle -A XRAY6 -d "the first ipv6 segment where the gateway is located" -j RETURN\nip6tables -t mangle -A XRAY6 -d "the second ipv6 segment where the gateway is located" -j RETURN\n\n# If the gateway is used as the primary router, add this line, see: [Other considerations for transparent proxy of iptables](https://xtls.github.io/en/documents/level-2/transparent_proxy/transparent_proxy/#proxy-ipv6)\n# The "gateway LAN_IPv6 address segment", obtained by running the command "ip address | grep -w "inet6" | awk '{print $2}'", is one of the results\nip6tables -t mangle -A XRAY6 ! -s "gateway LAN_IPv6 address segment" -j RETURN\n\nip6tables -t mangle -A XRAY6 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A XRAY6 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A PREROUTING -j XRAY6\n\n# Proxy gateway itself\nip6tables -t mangle -N XRAY6_MASK\nip6tables -t mangle -A XRAY6_MASK -d "the first ipv6 segment where the gateway is located" -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d "the second ipv6 segment where the gateway is located" -j RETURN\n\nip6tables -t mangle -A XRAY6_MASK -j MARK --set-mark 1\nip6tables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 ! -p icmp -j XRAY6_MASK\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    ',20);i.render=function(o,l){const i=n("OutboundLink"),$=n("RouterLink");return s(),a(p,null,[u,e("p",null,[c,e("strong",null,[e("a",d,[m,t(i)])]),b,e("strong",null,[e("a",h,[g,t(i)])]),f,e("strong",null,[t($,{to:"/en/document/level-2/tproxy.html"},{default:r((()=>[y])),_:1})]),k]),x,e("ol",null,[e("li",null,[e("p",null,[e("strong",null,[e("a",v,[A,t(i)])])])]),w]),q,e("ol",null,[R,e("li",null,[e("p",null,[_,e("strong",null,[e("a",T,[X,t(i)])])])]),P]),Y,e("p",null,[N,e("strong",null,[e("a",j,[U,t(i)])]),E,e("strong",null,[e("a",S,[I,t(i)])]),M,O,L]),K,e("p",null,[C,e("strong",null,[e("a",F,[G,t(i)])])]),V],64)};export default i; +import{r as n,o as s,c as a,a as e,b as t,w as r,F as p,e as o,d as l}from"./app.48111a85.js";const i={},u=e("h1",{id:"transparent-proxy-to-circumvent-xray-traffic-via-gid",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#transparent-proxy-to-circumvent-xray-traffic-via-gid","aria-hidden":"true"},"#"),o(" Transparent proxy to circumvent Xray traffic via GID")],-1),c=o("In the existing transparent proxy configuration("),d={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},m=o("New V2Ray vernacular tutorial on transparent proxy"),b=o(" 、 "),h={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},g=o("New V2Ray vernacular tutorial on transparent proxy (TProxy)"),f=o(" 、 "),y=o("Transparent proxy(TProxy)configuration tutorial"),k=o(")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."),x=e("p",null,"There are several problems with this method:",-1),v={href:"https://github.com/v2ray/v2ray-core/issues/2621",target:"_blank",rel:"noopener noreferrer"},A=o("Inexplicable traffic into PREROUTING chain"),w=e("li",null,[e("p",null,"Android has its own mark mechanism and this solution is not available on Android")],-1),q=l('

    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),R=e("li",null,[e("p",null,"System has root privilege.")],-1),_=o("Install "),T={href:"https://play.google.com/store/apps/details?id=stericson.busybox",target:"_blank",rel:"noopener noreferrer"},X=o("busybox"),P=e("li",null,[e("p",null,"There is a terminal that can execute commands, you can use adb shell, termux etc.")],-1),Y=l('

    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\n
    1

    Also attached are some common dependencies for openwrt, the lack of which may prevent Xray from running

    opkg install libopenssl ca-certificates\n
    1

    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\n
    1

    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\n
    1

    The result displayed should be uid 0 and gid 23333.

    3. Configure and run Xray, and configure iptables rules

    ',13),N=o("In the existing transparent proxy configuration("),j={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},U=o("New V2Ray vernacular tutorial on transparent proxy"),E=o(" 、 "),S={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},I=o("New V2Ray vernacular tutorial on transparent proxy (TProxy)"),M=o(" 、 "),O=e("strong",null,[e("a",{href:"../tproxy"},"Transparent proxy(TProxy)configuration tutorial")],-1),L=o(")tutorials, modify:"),K=l('
    1. Modify the json configuration file: remove mark-related content

    2. Modify the iptables rule to remove the mark-related content and add the option at the OUTPUT chain application rule: -m owner ! --gid-owner 23333

    e.g.:

    iptables -t mangle -A OUTPUT -j XRAY_SELF

    Change to

    iptables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 -j XRAY_SELF

    1. Modify the way you run Xray so that it runs on a user with uid 0 and gid 23333, refer to here.

    Steps

    The following provides a complete configuration process for implementing the tproxy global proxy

    1. Finish Preliminary preparation and Add user

    2. Preparing Xray profiles

    Configure Xray to listen to 12345 at dokodemo-door, turn on followRedirect and tproxy, no sniffing required:

    {\n  "inbounds": [\n    {\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy"\n        }\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      // Your server configuration\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    3. Configuring the maximum number of open files and run the Xray client

    ',13),C=o("About the maximum number of open files, see: "),F={href:"https://guide.v2fly.org/app/tproxy.html#%E8%A7%A3%E5%86%B3-too-many-open-files-%E9%97%AE%E9%A2%98",target:"_blank",rel:"noopener noreferrer"},G=o("too many open files issues"),V=l('

    The current Xray server installed with the official script has the maximum number of open files automatically configured, so no further changes are required.

    Android

    ulimit -SHn 1000000\nsetuidgid 0:23333 "Command to run Xray"&\n
    1
    2

    Other Linux system

    ulimit -SHn 1000000\nsudo -u xray_tproxy "Command to run Xray"&\n
    1
    2

    e.g.:

    ulimit -SHn 1000000\nsudo -u xray_tproxy xray -c /etc/xray/config.json &\n
    1
    2

    The first command:

    Change the maximum number of open files, valid only for the current terminal and to be run every time before starting Xray, this command is to set the maximum number of open files for the client.

    The second command:

    Run the Xray client as a user with uid 0 and gid not 0, followed by & for running in the background.

    Check if the maximum number of open files is set successfully

    cat /proc/"Xray's pid"/limits\n
    1

    Find max open files, which should be the value you set. Xray's pid can be obtained by running ps or ps -aux or ps -a

    Both the server and client side should be checked.

    4. Setting up iptables rules

    Proxy ipv4

    ip rule add fwmark 1 table 100\nip route add local 0.0.0.0/0 dev lo table 100\n\n# Proxy LAN devices\niptables -t mangle -N XRAY\n# "ipv4 segment where the gateway is located" is obtained by running the command "ip address | grep -w inet | awk '{print $2}'", usually there are multiple\niptables -t mangle -A XRAY -d "first ipv4 segment where the gateway is located" -j RETURN\niptables -t mangle -A XRAY -d "second ipv4 segment where the gateway is located" -j RETURN\n\n# If the gateway is used as the primary router, add this line, see: [Other considerations for transparent proxy of iptables](https://xtls.github.io/en/documents/level-2/transparent_proxy/transparent_proxy/#proxy-ipv6)\n# The "gateway LAN_IPv4 address segment", obtained by running the command "ip address | grep -w "inet" | awk '{print $2}'", is one of the results\niptables -t mangle -A XRAY ! -s "gateway LAN_IPv4 address segment" -j RETURN\n\n# Mark 1 for TCP and forward to port 12345\n# mark can only be set to 1 for the traffic to be accepted by the Xray dokodemo-door\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port 12345 --tproxy-mark 1\n# Apply rules\niptables -t mangle -A PREROUTING -j XRAY\n\n# Proxy gateway itself\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -d "the first ipv4 segment where the gateway is located" -j RETURN\niptables -t mangle -A XRAY_MASK -d "the second ipv4 segment where the gateway is located" -j RETURN\n\niptables -t mangle -A XRAY_MASK -j MARK --set-mark 1\niptables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 ! -p icmp -j XRAY_MASK\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    Proxy ipv6 (optional)

    ip -6 rule add fwmark 1 table 106\nip -6 route add local ::/0 dev lo table 106\n\n# Proxy LAN devices\nip6tables -t mangle -N XRAY6\n# The "ipv6 segment where the gateway is located" is obtained by running the command "ip address | grep -w inet6 | awk '{print $2}'".\nip6tables -t mangle -A XRAY6 -d "the first ipv6 segment where the gateway is located" -j RETURN\nip6tables -t mangle -A XRAY6 -d "the second ipv6 segment where the gateway is located" -j RETURN\n\n# If the gateway is used as the primary router, add this line, see: [Other considerations for transparent proxy of iptables](https://xtls.github.io/en/documents/level-2/transparent_proxy/transparent_proxy/#proxy-ipv6)\n# The "gateway LAN_IPv6 address segment", obtained by running the command "ip address | grep -w "inet6" | awk '{print $2}'", is one of the results\nip6tables -t mangle -A XRAY6 ! -s "gateway LAN_IPv6 address segment" -j RETURN\n\nip6tables -t mangle -A XRAY6 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A XRAY6 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A PREROUTING -j XRAY6\n\n# Proxy gateway itself\nip6tables -t mangle -N XRAY6_MASK\nip6tables -t mangle -A XRAY6_MASK -d "the first ipv6 segment where the gateway is located" -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d "the second ipv6 segment where the gateway is located" -j RETURN\n\nip6tables -t mangle -A XRAY6_MASK -j MARK --set-mark 1\nip6tables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 ! -p icmp -j XRAY6_MASK\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    ',20);i.render=function(o,l){const i=n("OutboundLink"),$=n("RouterLink");return s(),a(p,null,[u,e("p",null,[c,e("strong",null,[e("a",d,[m,t(i)])]),b,e("strong",null,[e("a",h,[g,t(i)])]),f,e("strong",null,[t($,{to:"/en/document/level-2/tproxy.html"},{default:r((()=>[y])),_:1})]),k]),x,e("ol",null,[e("li",null,[e("p",null,[e("strong",null,[e("a",v,[A,t(i)])])])]),w]),q,e("ol",null,[R,e("li",null,[e("p",null,[_,e("strong",null,[e("a",T,[X,t(i)])])])]),P]),Y,e("p",null,[N,e("strong",null,[e("a",j,[U,t(i)])]),E,e("strong",null,[e("a",S,[I,t(i)])]),M,O,L]),K,e("p",null,[C,e("strong",null,[e("a",F,[G,t(i)])])]),V],64)};export default i; diff --git a/assets/iptables_gid.html.5744dd71.js b/assets/iptables_gid.html.edd50d36.js similarity index 99% rename from assets/iptables_gid.html.5744dd71.js rename to assets/iptables_gid.html.edd50d36.js index 0e884ee78..16e7eca82 100644 --- a/assets/iptables_gid.html.5744dd71.js +++ b/assets/iptables_gid.html.edd50d36.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as p,F as l,e as r,d as t}from"./app.755d843f.js";const o={},i=e("h1",{id:"透明代理通过-gid-规避-xray-流量",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#透明代理通过-gid-规避-xray-流量","aria-hidden":"true"},"#"),r(" 透明代理通过 gid 规避 Xray 流量")],-1),c=r("在现有的 iptables 透明代理白话文("),u={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},b=r("新 V2Ray 白话文指南-透明代理"),m=r(" 、 "),d={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},g=r("新 V2Ray 白话文指南-透明代理(TPROXY)"),k=r(" 、 "),h=e("strong",null,[e("a",{href:"./tproxy"},"透明代理(TProxy)配置教程")],-1),A=r(")教程中,对 Xray 流量的规避处理是打 mark 实现的。即对 Xray 出站流量打 mark,通过设置 iptables 规则对对应 mark 的流量直连,来规避 Xray 流量,防止回环。"),y=e("p",null,"这么做有以下几个问题:",-1),x={href:"https://github.com/v2ray/v2ray-core/issues/2621",target:"_blank",rel:"noopener noreferrer"},R=r("莫名流量进入 PREROUTING 链"),v=e("li",null,[e("p",null,"安卓系统有自己的 mark 机制,该方案在安卓上不可用")],-1),f=t('

    本教程的方案不需要设置 mark,理论性能更高,同时也不存在上述问题。

    思路

    tproxy 流量只能被 root 权限用户(uid==0)或其他有 CAP_NET_ADMIN 权限的用户接收。

    iptables 规则可以通过 uid(用户 id)和 gid(用户组 id)分流。

    让 Xray 运行在一个 uid==0 但 gid!=0 的用户上,设置 iptables 规则不代理该 gid 的流量来规避 Xray 流量。

    配置过程

    1. 前期准备

    安卓系统

    ',8),E=e("li",null,[e("p",null,"系统已 root")],-1),X=r("安装 "),_={href:"https://play.google.com/store/apps/details?id=stericson.busybox",target:"_blank",rel:"noopener noreferrer"},q=r("busybox"),T=e("li",null,[e("p",null,"有一个可以执行命令的终端,可以使用 adb shell,termux 等。")],-1),Y=t('

    其它 Linux 系统

    需要依赖 sudo,iptables 的 tproxy 模块和 extra 模块。

    一般系统都有自带,openwrt 运行:

    opkg install sudo iptables-mod-tproxy iptables-mod-extra\n
    1

    另附上一些 openwrt 常用的依赖,缺少可能导致 Xray 无法运行

    opkg install libopenssl ca-certificates\n
    1

    2. 添加用户(安卓用户请忽略)

    安卓系统不支持/etc/passwd 文件来管理用户,请忽略,直接下一步。

    grep -qw xray_tproxy /etc/passwd || echo "xray_tproxy:x:0:23333:::" >> /etc/passwd\n
    1

    其中 xray_tproxy 是用户名,0 是 uid,23333 是 gid,用户名和 gid 可以自己定,uid 必须为 0。 检查用户是否添加成功,运行

    sudo -u xray_tproxy id\n
    1

    显示的结果应该是 uid 为 0,gid 为 23333

    3. 配置运行 Xray,配置 iptables 规则

    ',13),j=r("在现有的 iptables 透明代理白话文("),U={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},w=r("新 V2Ray 白话文指南-透明代理"),N=r(" 、 "),P={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},S=r("新 V2Ray 白话文指南-透明代理(TPROXY)"),B=r(" 、 "),M=e("strong",null,[e("a",{href:"./tproxy"},"透明代理(TProxy)配置教程")],-1),K=r(")教程的基础上修改:"),O=t('
    1. 修改 json 配置文件,删除 mark 相关内容

    2. 修改 iptables 规则,删除 mark 相关内容,并在 OUTPUT 链应用规则处添加选项"-m owner ! --gid-owner 23333"。

    如:

    iptables -t mangle -A OUTPUT -j XRAY_SELF\n
    1

    改为

    iptables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 -j XRAY_SELF\n
    1
    1. 修改运行 Xray 的方式,使其运行在 uid 为 0,gid 为 23333 的用户上,参考这里

    下面提供一个实现 tproxy 全局代理的完整配置过程

    1. 完成 前期准备添加用户

    2. 准备 Xray 配置文件

    配置 Xray 任意门监听 12345,开启 followRedirect 和 tproxy,不需要设置 sniffing:

    {\n  "inbounds": [\n    {\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy"\n        }\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      你的服务器配置\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    3. 配置最大文件打开数&运行 Xray 客户端

    ',12),L=r("关于最大文件打开数问题见: "),F={href:"https://guide.v2fly.org/app/tproxy.html#%E8%A7%A3%E5%86%B3-too-many-open-files-%E9%97%AE%E9%A2%98",target:"_blank",rel:"noopener noreferrer"},I=r("too many open files 问题"),C=t('

    目前 Xray 服务端使用官方脚本安装的已经自动配置了最大文件打开数,无需再修改。

    安卓系统

    ulimit -SHn 1000000\nsetuidgid 0:23333 "运行Xray的命令"&\n
    1
    2

    其它 Linux 系统

    ulimit -SHn 1000000\nsudo -u xray_tproxy "运行Xray的命令"&\n
    1
    2

    例如:

    ulimit -SHn 1000000\nsudo -u xray_tproxy xray -c /etc/xray/config.json &\n
    1
    2

    第一条命令:

    改变最大打开文件数,只对当前终端有效,每次启动 Xray 前都要运行,该命令是设置客户端的最大文件打开数

    第二条命令:

    以 uid 为 0,gid 不为 0 的用户来运行 Xray 客户端,后面加&代表放在后台运行

    检查最大文件打开数是否设置成功

    cat /proc/Xray的pid/limits\n
    1

    找到 max open files 一项,应该是你设置的数值。pid 的获取方法为运行psps -auxps -apidof xray

    服务端和客户端都要检查

    4. 设置 iptables 规则

    代理 ipv4

    ip rule add fwmark 1 table 100\nip route add local 0.0.0.0/0 dev lo table 100\n\n# 代理局域网设备\niptables -t mangle -N XRAY\n#  "网关所在ipv4网段" 通过运行命令"ip address | grep -w inet | awk '{print $2}'"获得,一般有多个\niptables -t mangle -A XRAY -d 网关所在ipv4网段1 -j RETURN\niptables -t mangle -A XRAY -d 网关所在ipv4网段2 -j RETURN\n...\n\n# 组播地址/E类地址/广播地址直连\niptables -t mangle -A XRAY -d 224.0.0.0/3 -j RETURN\n\n\n#如果网关作为主路由,则加上这一句,见:https://xtls.github.io/documents/level-2/transparent_proxy/transparent_proxy.md#iptables透明代理的其它注意事项\n#网关LAN_IPv4地址段,运行命令"ip address | grep -w "inet" | awk '{print $2}'"获得,是其中的一个\niptables -t mangle -A XRAY ! -s 网关LAN_IPv4地址段 -j RETURN\n\n# 给 TCP 打标记 1,转发至 12345 端口\n# mark只有设置为1,流量才能被Xray任意门接受\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port 12345 --tproxy-mark 1\n# 应用规则\niptables -t mangle -A PREROUTING -j XRAY\n\n# 代理网关本机\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -m owner --gid-owner 23333 -j RETURN\niptables -t mangle -A XRAY_MASK -d 网关所在ipv4网段1 -j RETURN\niptables -t mangle -A XRAY_MASK -d 网关所在ipv4网段2 -j RETURN\n...\niptables -t mangle -A XRAY_MASK -d 224.0.0.0/3 -j RETURN\niptables -t mangle -A XRAY_MASK -j MARK --set-mark 1\niptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK\niptables -t mangle -A OUTPUT -p udp -j XRAY_MASK\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35

    代理 ipv6(可选)

    ip -6 rule add fwmark 1 table 106\nip -6 route add local ::/0 dev lo table 106\n\n# 代理局域网设备\nip6tables -t mangle -N XRAY6\n# "网关所在ip6网段" 通过运行命令"ip address | grep -w inet6 | awk '{print $2}'"获得。\nip6tables -t mangle -A XRAY6 -d 网关所在ipv6网段1 -j RETURN\nip6tables -t mangle -A XRAY6 -d 网关所在ipv6网段2 -j RETURN\n...\n\n# 如果网关作为主路由,则加上这一句,见:https://xtls.github.io/documents/level-2/transparent_proxy/transparent_proxy.md#iptables透明代理的其它注意事项\n# 网关LAN_IPv6地址段,运行命令"ip address | grep -w "inet6" | awk '{print $2}'"获得,是其中的一个\nip6tables -t mangle -A XRAY6 ! -s 网关LAN_IPv6地址段 -j RETURN\n\nip6tables -t mangle -A XRAY6 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A XRAY6 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A PREROUTING -j XRAY6\n\n# 代理网关本机\nip6tables -t mangle -N XRAY6_MASK\nip6tables -t mangle -A XRAY6_MASK -m owner --gid-owner 23333 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d 网关所在ipv6网段1 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d 网关所在ipv6网段2 -j RETURN\n...\nip6tables -t mangle -A XRAY6_MASK -j MARK --set-mark 1\nip6tables -t mangle -A OUTPUT -p tcp -j XRAY6_MASK\nip6tables -t mangle -A OUTPUT -p udp -j XRAY6_MASK\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    ',20);o.render=function(r,t){const o=n("OutboundLink");return s(),a(l,null,[i,e("p",null,[c,e("strong",null,[e("a",u,[b,p(o)])]),m,e("strong",null,[e("a",d,[g,p(o)])]),k,h,A]),y,e("ol",null,[e("li",null,[e("p",null,[e("strong",null,[e("a",x,[R,p(o)])])])]),v]),f,e("ol",null,[E,e("li",null,[e("p",null,[X,e("strong",null,[e("a",_,[q,p(o)])])])]),T]),Y,e("p",null,[j,e("strong",null,[e("a",U,[w,p(o)])]),N,e("strong",null,[e("a",P,[S,p(o)])]),B,M,K]),O,e("p",null,[L,e("strong",null,[e("a",F,[I,p(o)])])]),C],64)};export default o; +import{r as n,o as s,c as a,a as e,b as p,F as l,e as r,d as t}from"./app.48111a85.js";const o={},i=e("h1",{id:"透明代理通过-gid-规避-xray-流量",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#透明代理通过-gid-规避-xray-流量","aria-hidden":"true"},"#"),r(" 透明代理通过 gid 规避 Xray 流量")],-1),c=r("在现有的 iptables 透明代理白话文("),u={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},b=r("新 V2Ray 白话文指南-透明代理"),m=r(" 、 "),d={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},g=r("新 V2Ray 白话文指南-透明代理(TPROXY)"),k=r(" 、 "),h=e("strong",null,[e("a",{href:"./tproxy"},"透明代理(TProxy)配置教程")],-1),A=r(")教程中,对 Xray 流量的规避处理是打 mark 实现的。即对 Xray 出站流量打 mark,通过设置 iptables 规则对对应 mark 的流量直连,来规避 Xray 流量,防止回环。"),y=e("p",null,"这么做有以下几个问题:",-1),x={href:"https://github.com/v2ray/v2ray-core/issues/2621",target:"_blank",rel:"noopener noreferrer"},R=r("莫名流量进入 PREROUTING 链"),v=e("li",null,[e("p",null,"安卓系统有自己的 mark 机制,该方案在安卓上不可用")],-1),f=t('

    本教程的方案不需要设置 mark,理论性能更高,同时也不存在上述问题。

    思路

    tproxy 流量只能被 root 权限用户(uid==0)或其他有 CAP_NET_ADMIN 权限的用户接收。

    iptables 规则可以通过 uid(用户 id)和 gid(用户组 id)分流。

    让 Xray 运行在一个 uid==0 但 gid!=0 的用户上,设置 iptables 规则不代理该 gid 的流量来规避 Xray 流量。

    配置过程

    1. 前期准备

    安卓系统

    ',8),E=e("li",null,[e("p",null,"系统已 root")],-1),X=r("安装 "),_={href:"https://play.google.com/store/apps/details?id=stericson.busybox",target:"_blank",rel:"noopener noreferrer"},q=r("busybox"),T=e("li",null,[e("p",null,"有一个可以执行命令的终端,可以使用 adb shell,termux 等。")],-1),Y=t('

    其它 Linux 系统

    需要依赖 sudo,iptables 的 tproxy 模块和 extra 模块。

    一般系统都有自带,openwrt 运行:

    opkg install sudo iptables-mod-tproxy iptables-mod-extra\n
    1

    另附上一些 openwrt 常用的依赖,缺少可能导致 Xray 无法运行

    opkg install libopenssl ca-certificates\n
    1

    2. 添加用户(安卓用户请忽略)

    安卓系统不支持/etc/passwd 文件来管理用户,请忽略,直接下一步。

    grep -qw xray_tproxy /etc/passwd || echo "xray_tproxy:x:0:23333:::" >> /etc/passwd\n
    1

    其中 xray_tproxy 是用户名,0 是 uid,23333 是 gid,用户名和 gid 可以自己定,uid 必须为 0。 检查用户是否添加成功,运行

    sudo -u xray_tproxy id\n
    1

    显示的结果应该是 uid 为 0,gid 为 23333

    3. 配置运行 Xray,配置 iptables 规则

    ',13),j=r("在现有的 iptables 透明代理白话文("),U={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},w=r("新 V2Ray 白话文指南-透明代理"),N=r(" 、 "),P={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},S=r("新 V2Ray 白话文指南-透明代理(TPROXY)"),B=r(" 、 "),M=e("strong",null,[e("a",{href:"./tproxy"},"透明代理(TProxy)配置教程")],-1),K=r(")教程的基础上修改:"),O=t('
    1. 修改 json 配置文件,删除 mark 相关内容

    2. 修改 iptables 规则,删除 mark 相关内容,并在 OUTPUT 链应用规则处添加选项"-m owner ! --gid-owner 23333"。

    如:

    iptables -t mangle -A OUTPUT -j XRAY_SELF\n
    1

    改为

    iptables -t mangle -A OUTPUT -m owner ! --gid-owner 23333 -j XRAY_SELF\n
    1
    1. 修改运行 Xray 的方式,使其运行在 uid 为 0,gid 为 23333 的用户上,参考这里

    下面提供一个实现 tproxy 全局代理的完整配置过程

    1. 完成 前期准备添加用户

    2. 准备 Xray 配置文件

    配置 Xray 任意门监听 12345,开启 followRedirect 和 tproxy,不需要设置 sniffing:

    {\n  "inbounds": [\n    {\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy"\n        }\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      你的服务器配置\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    3. 配置最大文件打开数&运行 Xray 客户端

    ',12),L=r("关于最大文件打开数问题见: "),F={href:"https://guide.v2fly.org/app/tproxy.html#%E8%A7%A3%E5%86%B3-too-many-open-files-%E9%97%AE%E9%A2%98",target:"_blank",rel:"noopener noreferrer"},I=r("too many open files 问题"),C=t('

    目前 Xray 服务端使用官方脚本安装的已经自动配置了最大文件打开数,无需再修改。

    安卓系统

    ulimit -SHn 1000000\nsetuidgid 0:23333 "运行Xray的命令"&\n
    1
    2

    其它 Linux 系统

    ulimit -SHn 1000000\nsudo -u xray_tproxy "运行Xray的命令"&\n
    1
    2

    例如:

    ulimit -SHn 1000000\nsudo -u xray_tproxy xray -c /etc/xray/config.json &\n
    1
    2

    第一条命令:

    改变最大打开文件数,只对当前终端有效,每次启动 Xray 前都要运行,该命令是设置客户端的最大文件打开数

    第二条命令:

    以 uid 为 0,gid 不为 0 的用户来运行 Xray 客户端,后面加&代表放在后台运行

    检查最大文件打开数是否设置成功

    cat /proc/Xray的pid/limits\n
    1

    找到 max open files 一项,应该是你设置的数值。pid 的获取方法为运行psps -auxps -apidof xray

    服务端和客户端都要检查

    4. 设置 iptables 规则

    代理 ipv4

    ip rule add fwmark 1 table 100\nip route add local 0.0.0.0/0 dev lo table 100\n\n# 代理局域网设备\niptables -t mangle -N XRAY\n#  "网关所在ipv4网段" 通过运行命令"ip address | grep -w inet | awk '{print $2}'"获得,一般有多个\niptables -t mangle -A XRAY -d 网关所在ipv4网段1 -j RETURN\niptables -t mangle -A XRAY -d 网关所在ipv4网段2 -j RETURN\n...\n\n# 组播地址/E类地址/广播地址直连\niptables -t mangle -A XRAY -d 224.0.0.0/3 -j RETURN\n\n\n#如果网关作为主路由,则加上这一句,见:https://xtls.github.io/documents/level-2/transparent_proxy/transparent_proxy.md#iptables透明代理的其它注意事项\n#网关LAN_IPv4地址段,运行命令"ip address | grep -w "inet" | awk '{print $2}'"获得,是其中的一个\niptables -t mangle -A XRAY ! -s 网关LAN_IPv4地址段 -j RETURN\n\n# 给 TCP 打标记 1,转发至 12345 端口\n# mark只有设置为1,流量才能被Xray任意门接受\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port 12345 --tproxy-mark 1\n# 应用规则\niptables -t mangle -A PREROUTING -j XRAY\n\n# 代理网关本机\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -m owner --gid-owner 23333 -j RETURN\niptables -t mangle -A XRAY_MASK -d 网关所在ipv4网段1 -j RETURN\niptables -t mangle -A XRAY_MASK -d 网关所在ipv4网段2 -j RETURN\n...\niptables -t mangle -A XRAY_MASK -d 224.0.0.0/3 -j RETURN\niptables -t mangle -A XRAY_MASK -j MARK --set-mark 1\niptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK\niptables -t mangle -A OUTPUT -p udp -j XRAY_MASK\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35

    代理 ipv6(可选)

    ip -6 rule add fwmark 1 table 106\nip -6 route add local ::/0 dev lo table 106\n\n# 代理局域网设备\nip6tables -t mangle -N XRAY6\n# "网关所在ip6网段" 通过运行命令"ip address | grep -w inet6 | awk '{print $2}'"获得。\nip6tables -t mangle -A XRAY6 -d 网关所在ipv6网段1 -j RETURN\nip6tables -t mangle -A XRAY6 -d 网关所在ipv6网段2 -j RETURN\n...\n\n# 如果网关作为主路由,则加上这一句,见:https://xtls.github.io/documents/level-2/transparent_proxy/transparent_proxy.md#iptables透明代理的其它注意事项\n# 网关LAN_IPv6地址段,运行命令"ip address | grep -w "inet6" | awk '{print $2}'"获得,是其中的一个\nip6tables -t mangle -A XRAY6 ! -s 网关LAN_IPv6地址段 -j RETURN\n\nip6tables -t mangle -A XRAY6 -p udp -j TPROXY --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A XRAY6 -p tcp -j TPROXY --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A PREROUTING -j XRAY6\n\n# 代理网关本机\nip6tables -t mangle -N XRAY6_MASK\nip6tables -t mangle -A XRAY6_MASK -m owner --gid-owner 23333 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d 网关所在ipv6网段1 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d 网关所在ipv6网段2 -j RETURN\n...\nip6tables -t mangle -A XRAY6_MASK -j MARK --set-mark 1\nip6tables -t mangle -A OUTPUT -p tcp -j XRAY6_MASK\nip6tables -t mangle -A OUTPUT -p udp -j XRAY6_MASK\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    ',20);o.render=function(r,t){const o=n("OutboundLink");return s(),a(l,null,[i,e("p",null,[c,e("strong",null,[e("a",u,[b,p(o)])]),m,e("strong",null,[e("a",d,[g,p(o)])]),k,h,A]),y,e("ol",null,[e("li",null,[e("p",null,[e("strong",null,[e("a",x,[R,p(o)])])])]),v]),f,e("ol",null,[E,e("li",null,[e("p",null,[X,e("strong",null,[e("a",_,[q,p(o)])])])]),T]),Y,e("p",null,[j,e("strong",null,[e("a",U,[w,p(o)])]),N,e("strong",null,[e("a",P,[S,p(o)])]),B,M,K]),O,e("p",null,[L,e("strong",null,[e("a",F,[I,p(o)])])]),C],64)};export default o; diff --git a/assets/journeyDiagram-ccf0174b.f190e614.js b/assets/journeyDiagram-ccf0174b.5da82ccf.js similarity index 99% rename from assets/journeyDiagram-ccf0174b.f190e614.js rename to assets/journeyDiagram-ccf0174b.5da82ccf.js index cac7cd6ca..4cc842b69 100644 --- a/assets/journeyDiagram-ccf0174b.f190e614.js +++ b/assets/journeyDiagram-ccf0174b.5da82ccf.js @@ -1 +1 @@ -import{c as t,v as e,x as n,s as i,g as s,b as r,a,m as o,z as c,h as l,i as h}from"./mermaid.core.a66200b0.js";import{f as u,d as y,b as p,g as d}from"./svgDrawCommon-f26cad39.9f4c1d32.js";import{a as f}from"./arc.56fd4148.js";import"./constant.4f073c13.js";var g=function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[1,2],n=[1,5],i=[6,9,11,17,18,20,22,23,24,26],s=[1,15],r=[1,16],a=[1,17],o=[1,18],c=[1,19],l=[1,20],h=[1,24],u=[4,6,9,11,17,18,20,22,23,24,26],y={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,title:17,acc_title:18,acc_title_value:19,acc_descr:20,acc_descr_value:21,acc_descr_multiline_value:22,section:23,taskName:24,taskData:25,open_directive:26,type_directive:27,arg_directive:28,close_directive:29,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",17:"title",18:"acc_title",19:"acc_title_value",20:"acc_descr",21:"acc_descr_value",22:"acc_descr_multiline_value",23:"section",24:"taskName",25:"taskData",26:"open_directive",27:"type_directive",28:"arg_directive",29:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,2],[10,2],[10,1],[10,1],[10,2],[10,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 3:this.$=[];break;case 4:r[o-1].push(r[o]),this.$=r[o-1];break;case 5:case 6:this.$=r[o];break;case 7:case 8:this.$=[];break;case 11:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 12:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 13:case 14:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 15:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 16:i.addTask(r[o-1],r[o]),this.$="task";break;case 18:i.parseDirective("%%{","open_directive");break;case 19:i.parseDirective(r[o],"type_directive");break;case 20:r[o]=r[o].trim().replace(/'/g,'"'),i.parseDirective(r[o],"arg_directive");break;case 21:i.parseDirective("}%%","close_directive","journey")}},table:[{3:1,4:e,7:3,12:4,26:n},{1:[3]},t(i,[2,3],{5:6}),{3:7,4:e,7:3,12:4,26:n},{13:8,27:[1,9]},{27:[2,18]},{6:[1,10],7:21,8:11,9:[1,12],10:13,11:[1,14],12:4,17:s,18:r,20:a,22:o,23:c,24:l,26:n},{1:[2,2]},{14:22,15:[1,23],29:h},t([15,29],[2,19]),t(i,[2,8],{1:[2,1]}),t(i,[2,4]),{7:21,10:25,12:4,17:s,18:r,20:a,22:o,23:c,24:l,26:n},t(i,[2,6]),t(i,[2,7]),t(i,[2,11]),{19:[1,26]},{21:[1,27]},t(i,[2,14]),t(i,[2,15]),{25:[1,28]},t(i,[2,17]),{11:[1,29]},{16:30,28:[1,31]},{11:[2,21]},t(i,[2,5]),t(i,[2,12]),t(i,[2,13]),t(i,[2,16]),t(u,[2,9]),{14:32,29:h},{29:[2,20]},{11:[1,33]},t(u,[2,10])],defaultActions:{5:[2,18],7:[2,2],24:[2,21],31:[2,20]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",c=0,l=0,h=2,u=1,y=r.slice.call(arguments,1),p=Object.create(this.lexer),d={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(d.yy[f]=this.yy[f]);p.setInput(t,d.yy),d.yy.lexer=p,d.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var g=p.yylloc;r.push(g);var m=p.options&&p.options.ranges;function x(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,k,b,v,$,w,M,S,T={};;){if(k=n[n.length-1],this.defaultActions[k]?b=this.defaultActions[k]:(null==_&&(_=x()),b=a[k]&&a[k][_]),void 0===b||!b.length||!b[0]){var E="";for($ in S=[],a[k])this.terminals_[$]&&$>h&&S.push("'"+this.terminals_[$]+"'");E=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+S.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(E,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:g,expected:S})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+_);switch(b[0]){case 1:n.push(_),s.push(p.yytext),r.push(p.yylloc),n.push(b[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,g=p.yylloc;break;case 2:if(w=this.productions_[b[1]][1],T.$=s[s.length-w],T._$={first_line:r[r.length-(w||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(w||1)].first_column,last_column:r[r.length-1].last_column},m&&(T._$.range=[r[r.length-(w||1)].range[0],r[r.length-1].range[1]]),void 0!==(v=this.performAction.apply(T,[o,l,c,d.yy,b[1],s,r].concat(y))))return v;w&&(n=n.slice(0,-1*w*2),s=s.slice(0,-1*w),r=r.slice(0,-1*w)),n.push(this.productions_[b[1]][0]),s.push(T.$),r.push(T._$),M=a[n[n.length-2]][n[n.length-1]],n.push(M);break;case 3:return!0}}return!0}},p={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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 i=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 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:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),26;case 1:return this.begin("type_directive"),27;case 2:return this.popState(),this.begin("arg_directive"),15;case 3:return this.popState(),this.popState(),29;case 4:return 28;case 5:case 6:break;case 7:return 11;case 8:case 9:break;case 10:return 4;case 11:return 17;case 12:return this.begin("acc_title"),18;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),20;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:return 23;case 20:return 24;case 21:return 25;case 22:return 15;case 23:return 6;case 24:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,14,16,19,20,21,22,23,24],inclusive:!0}}};function d(){this.yy={}}return y.lexer=p,d.prototype=y,y.Parser=d,new d}();g.parser=g;const m=g;let x="";const _=[],k=[],b=[],v=function(){let t=!0;for(const[e,n]of b.entries())b[e].processed,t=t&&n.processed;return t},$={parseDirective:function(t,e,n){o.parseDirective(this,t,e,n)},getConfig:()=>t().journey,clear:function(){_.length=0,k.length=0,x="",b.length=0,c()},setDiagramTitle:e,getDiagramTitle:n,setAccTitle:i,getAccTitle:s,setAccDescription:r,getAccDescription:a,addSection:function(t){x=t,_.push(t)},getSections:function(){return _},getTasks:function(){let t=v();let e=0;for(;!t&&e<100;)t=v(),e++;return k.push(...b),k},addTask:function(t,e){const n=e.substr(1).split(":");let i=0,s=[];1===n.length?(i=Number(n[0]),s=[]):(i=Number(n[0]),s=n[1].split(","));const r=s.map((t=>t.trim())),a={section:x,type:x,people:r,task:t,score:i};b.push(a)},addTaskOrg:function(t){const e={section:x,type:x,description:t,task:t,classes:[]};k.push(e)},getActors:function(){return function(){const t=[];return k.forEach((e=>{e.people&&t.push(...e.people)})),[...new Set(t)].sort()}()}},w=t=>`.label {\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n color: ${t.textColor};\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ${t.textColor}\n }\n\n .legend {\n fill: ${t.textColor};\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ${t.textColor}\n }\n\n .face {\n ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"};\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ${t.fillType0?`fill: ${t.fillType0}`:""};\n }\n .task-type-1, .section-type-1 {\n ${t.fillType0?`fill: ${t.fillType1}`:""};\n }\n .task-type-2, .section-type-2 {\n ${t.fillType0?`fill: ${t.fillType2}`:""};\n }\n .task-type-3, .section-type-3 {\n ${t.fillType0?`fill: ${t.fillType3}`:""};\n }\n .task-type-4, .section-type-4 {\n ${t.fillType0?`fill: ${t.fillType4}`:""};\n }\n .task-type-5, .section-type-5 {\n ${t.fillType0?`fill: ${t.fillType5}`:""};\n }\n .task-type-6, .section-type-6 {\n ${t.fillType0?`fill: ${t.fillType6}`:""};\n }\n .task-type-7, .section-type-7 {\n ${t.fillType0?`fill: ${t.fillType7}`:""};\n }\n\n .actor-0 {\n ${t.actor0?`fill: ${t.actor0}`:""};\n }\n .actor-1 {\n ${t.actor1?`fill: ${t.actor1}`:""};\n }\n .actor-2 {\n ${t.actor2?`fill: ${t.actor2}`:""};\n }\n .actor-3 {\n ${t.actor3?`fill: ${t.actor3}`:""};\n }\n .actor-4 {\n ${t.actor4?`fill: ${t.actor4}`:""};\n }\n .actor-5 {\n ${t.actor5?`fill: ${t.actor5}`:""};\n }\n`,M=function(t,e){return y(t,e)},S=function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n},T=function(t,e){return u(t,e)};let E=-1;const A=function(){function t(t,e,n,s,r,a,o,c){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,c,l){const{taskFontSize:h,taskFontFamily:u}=c,y=t.split(//gi);for(let p=0;p3?function(t){const i=f().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}(s):e.score<3?function(t){const i=f().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}(s):s.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}(s,{cx:i,cy:300+30*(5-e.score),score:e.score});const r=d();r.x=e.x,r.y=e.y,r.fill=e.fill,r.width=n.width,r.height=n.height,r.class="task task-type-"+e.num,r.rx=3,r.ry=3,M(s,r);let a=e.x+14;e.people.forEach((t=>{const n=e.actors[t].color,i={cx:a,cy:e.y,r:7,fill:n,stroke:"#000",title:t,pos:e.actors[t].position};S(s,i),a+=10})),A(n)(e.task,s,r.x,r.y,r.width,r.height,{class:"task"},n,e.colour)},D=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},V={};const O=t().journey,L=O.leftMargin,N={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},updateVal:function(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])},updateBounds:function(e,n,i,s){const r=t().journey,a=this;let o=0;var c;this.sequenceItems.forEach((function(t){o++;const l=a.sequenceItems.length-o+1;a.updateVal(t,"starty",n-l*r.boxMargin,Math.min),a.updateVal(t,"stopy",s+l*r.boxMargin,Math.max),a.updateVal(N.data,"startx",e-l*r.boxMargin,Math.min),a.updateVal(N.data,"stopx",i+l*r.boxMargin,Math.max),"activation"!==c&&(a.updateVal(t,"startx",e-l*r.boxMargin,Math.min),a.updateVal(t,"stopx",i+l*r.boxMargin,Math.max),a.updateVal(N.data,"starty",n-l*r.boxMargin,Math.min),a.updateVal(N.data,"stopy",s+l*r.boxMargin,Math.max))}))},insert:function(t,e,n,i){const s=Math.min(t,n),r=Math.max(t,n),a=Math.min(e,i),o=Math.max(e,i);this.updateVal(N.data,"startx",s,Math.min),this.updateVal(N.data,"starty",a,Math.min),this.updateVal(N.data,"stopx",r,Math.max),this.updateVal(N.data,"stopy",o,Math.max),this.updateBounds(s,a,r,o)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return this.data}},F=O.sectionFills,z=O.sectionColours,B=function(e,n,i){const s=t().journey;let r="";const a=i+(2*s.height+s.diagramMarginY);let o=0,c="#CCC",l="black",h=0;for(const[t,u]of n.entries()){if(r!==u.section){c=F[o%F.length],h=o%F.length,l=z[o%z.length];let i=0;const a=u.section;for(let e=t;e(V[e]&&(t[e]=V[e]),t)),{});u.x=t*s.taskMargin+t*s.width+L,u.y=a,u.width=s.diagramMarginX,u.height=s.diagramMarginY,u.colour=l,u.fill=c,u.num=h,u.actors=i,C(e,u,s),N.insert(u.x,u.y,u.x+u.width+s.taskMargin,450)}},R={setConf:function(t){Object.keys(t).forEach((function(e){O[e]=t[e]}))},draw:function(e,n,i,s){const r=t().journey;s.db.clear(),s.parser.parse(e+"\n");const a=t().securityLevel;let o;"sandbox"===a&&(o=l("#i"+n));const c=l("sandbox"===a?o.nodes()[0].contentDocument.body:"body");N.init();const u=c.select("#"+n);D(u);const y=s.db.getTasks(),p=s.db.getDiagramTitle(),d=s.db.getActors();for(const t in V)delete V[t];let f=0;d.forEach((t=>{V[t]={color:r.actorColours[f%r.actorColours.length],position:f},f++})),function(e){const n=t().journey;let i=60;Object.keys(V).forEach((t=>{const s=V[t].color,r={cx:20,cy:i,r:7,fill:s,stroke:"#000",pos:V[t].position};I(e,r);const a={x:40,y:i+7,fill:"#666",text:t,textMargin:5|n.boxTextMargin};j(e,a),i+=20}))}(u),N.insert(0,0,L,50*Object.keys(V).length),B(u,y,0);const g=N.getBounds();p&&u.append("text").text(p).attr("x",L).attr("font-size","4ex").attr("font-weight","bold").attr("y",25);const m=g.stopy-g.starty+2*r.diagramMarginY,x=L+g.stopx+2*r.diagramMarginX;h(u,m,x,r.useMaxWidth),u.append("line").attr("x1",L).attr("y1",4*r.height).attr("x2",x-L-4).attr("y2",4*r.height).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");const _=p?70:0;u.attr("viewBox",`${g.startx} -25 ${x} ${m+_}`),u.attr("preserveAspectRatio","xMinYMin meet"),u.attr("height",m+_+25)}},Y={parser:m,db:$,renderer:R,styles:w,init:t=>{R.setConf(t.journey),$.clear()}};export{Y as diagram}; +import{c as t,v as e,x as n,s as i,g as s,b as r,a,m as o,z as c,h as l,i as h}from"./mermaid.core.3a590193.js";import{f as u,d as y,b as p,g as d}from"./svgDrawCommon-f26cad39.447236df.js";import{a as f}from"./arc.8a7dbfa5.js";import"./constant.4f073c13.js";var g=function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[1,2],n=[1,5],i=[6,9,11,17,18,20,22,23,24,26],s=[1,15],r=[1,16],a=[1,17],o=[1,18],c=[1,19],l=[1,20],h=[1,24],u=[4,6,9,11,17,18,20,22,23,24,26],y={trace:function(){},yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,title:17,acc_title:18,acc_title_value:19,acc_descr:20,acc_descr_value:21,acc_descr_multiline_value:22,section:23,taskName:24,taskData:25,open_directive:26,type_directive:27,arg_directive:28,close_directive:29,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",17:"title",18:"acc_title",19:"acc_title_value",20:"acc_descr",21:"acc_descr_value",22:"acc_descr_multiline_value",23:"section",24:"taskName",25:"taskData",26:"open_directive",27:"type_directive",28:"arg_directive",29:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,2],[10,2],[10,1],[10,1],[10,2],[10,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 3:this.$=[];break;case 4:r[o-1].push(r[o]),this.$=r[o-1];break;case 5:case 6:this.$=r[o];break;case 7:case 8:this.$=[];break;case 11:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 12:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 13:case 14:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 15:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 16:i.addTask(r[o-1],r[o]),this.$="task";break;case 18:i.parseDirective("%%{","open_directive");break;case 19:i.parseDirective(r[o],"type_directive");break;case 20:r[o]=r[o].trim().replace(/'/g,'"'),i.parseDirective(r[o],"arg_directive");break;case 21:i.parseDirective("}%%","close_directive","journey")}},table:[{3:1,4:e,7:3,12:4,26:n},{1:[3]},t(i,[2,3],{5:6}),{3:7,4:e,7:3,12:4,26:n},{13:8,27:[1,9]},{27:[2,18]},{6:[1,10],7:21,8:11,9:[1,12],10:13,11:[1,14],12:4,17:s,18:r,20:a,22:o,23:c,24:l,26:n},{1:[2,2]},{14:22,15:[1,23],29:h},t([15,29],[2,19]),t(i,[2,8],{1:[2,1]}),t(i,[2,4]),{7:21,10:25,12:4,17:s,18:r,20:a,22:o,23:c,24:l,26:n},t(i,[2,6]),t(i,[2,7]),t(i,[2,11]),{19:[1,26]},{21:[1,27]},t(i,[2,14]),t(i,[2,15]),{25:[1,28]},t(i,[2,17]),{11:[1,29]},{16:30,28:[1,31]},{11:[2,21]},t(i,[2,5]),t(i,[2,12]),t(i,[2,13]),t(i,[2,16]),t(u,[2,9]),{14:32,29:h},{29:[2,20]},{11:[1,33]},t(u,[2,10])],defaultActions:{5:[2,18],7:[2,2],24:[2,21],31:[2,20]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",c=0,l=0,h=2,u=1,y=r.slice.call(arguments,1),p=Object.create(this.lexer),d={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(d.yy[f]=this.yy[f]);p.setInput(t,d.yy),d.yy.lexer=p,d.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var g=p.yylloc;r.push(g);var m=p.options&&p.options.ranges;function x(){var t;return"number"!=typeof(t=i.pop()||p.lex()||u)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var _,k,b,v,$,w,M,S,T={};;){if(k=n[n.length-1],this.defaultActions[k]?b=this.defaultActions[k]:(null==_&&(_=x()),b=a[k]&&a[k][_]),void 0===b||!b.length||!b[0]){var E="";for($ in S=[],a[k])this.terminals_[$]&&$>h&&S.push("'"+this.terminals_[$]+"'");E=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+S.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(_==u?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(E,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:g,expected:S})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+_);switch(b[0]){case 1:n.push(_),s.push(p.yytext),r.push(p.yylloc),n.push(b[1]),_=null,l=p.yyleng,o=p.yytext,c=p.yylineno,g=p.yylloc;break;case 2:if(w=this.productions_[b[1]][1],T.$=s[s.length-w],T._$={first_line:r[r.length-(w||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(w||1)].first_column,last_column:r[r.length-1].last_column},m&&(T._$.range=[r[r.length-(w||1)].range[0],r[r.length-1].range[1]]),void 0!==(v=this.performAction.apply(T,[o,l,c,d.yy,b[1],s,r].concat(y))))return v;w&&(n=n.slice(0,-1*w*2),s=s.slice(0,-1*w),r=r.slice(0,-1*w)),n.push(this.productions_[b[1]][0]),s.push(T.$),r.push(T._$),M=a[n[n.length-2]][n[n.length-1]],n.push(M);break;case 3:return!0}}return!0}},p={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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 i=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 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:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),26;case 1:return this.begin("type_directive"),27;case 2:return this.popState(),this.begin("arg_directive"),15;case 3:return this.popState(),this.popState(),29;case 4:return 28;case 5:case 6:break;case 7:return 11;case 8:case 9:break;case 10:return 4;case 11:return 17;case 12:return this.begin("acc_title"),18;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),20;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:return 23;case 20:return 24;case 21:return 25;case 22:return 15;case 23:return 6;case 24:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,14,16,19,20,21,22,23,24],inclusive:!0}}};function d(){this.yy={}}return y.lexer=p,d.prototype=y,y.Parser=d,new d}();g.parser=g;const m=g;let x="";const _=[],k=[],b=[],v=function(){let t=!0;for(const[e,n]of b.entries())b[e].processed,t=t&&n.processed;return t},$={parseDirective:function(t,e,n){o.parseDirective(this,t,e,n)},getConfig:()=>t().journey,clear:function(){_.length=0,k.length=0,x="",b.length=0,c()},setDiagramTitle:e,getDiagramTitle:n,setAccTitle:i,getAccTitle:s,setAccDescription:r,getAccDescription:a,addSection:function(t){x=t,_.push(t)},getSections:function(){return _},getTasks:function(){let t=v();let e=0;for(;!t&&e<100;)t=v(),e++;return k.push(...b),k},addTask:function(t,e){const n=e.substr(1).split(":");let i=0,s=[];1===n.length?(i=Number(n[0]),s=[]):(i=Number(n[0]),s=n[1].split(","));const r=s.map((t=>t.trim())),a={section:x,type:x,people:r,task:t,score:i};b.push(a)},addTaskOrg:function(t){const e={section:x,type:x,description:t,task:t,classes:[]};k.push(e)},getActors:function(){return function(){const t=[];return k.forEach((e=>{e.people&&t.push(...e.people)})),[...new Set(t)].sort()}()}},w=t=>`.label {\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n color: ${t.textColor};\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ${t.textColor}\n }\n\n .legend {\n fill: ${t.textColor};\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ${t.textColor}\n }\n\n .face {\n ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"};\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ${t.fillType0?`fill: ${t.fillType0}`:""};\n }\n .task-type-1, .section-type-1 {\n ${t.fillType0?`fill: ${t.fillType1}`:""};\n }\n .task-type-2, .section-type-2 {\n ${t.fillType0?`fill: ${t.fillType2}`:""};\n }\n .task-type-3, .section-type-3 {\n ${t.fillType0?`fill: ${t.fillType3}`:""};\n }\n .task-type-4, .section-type-4 {\n ${t.fillType0?`fill: ${t.fillType4}`:""};\n }\n .task-type-5, .section-type-5 {\n ${t.fillType0?`fill: ${t.fillType5}`:""};\n }\n .task-type-6, .section-type-6 {\n ${t.fillType0?`fill: ${t.fillType6}`:""};\n }\n .task-type-7, .section-type-7 {\n ${t.fillType0?`fill: ${t.fillType7}`:""};\n }\n\n .actor-0 {\n ${t.actor0?`fill: ${t.actor0}`:""};\n }\n .actor-1 {\n ${t.actor1?`fill: ${t.actor1}`:""};\n }\n .actor-2 {\n ${t.actor2?`fill: ${t.actor2}`:""};\n }\n .actor-3 {\n ${t.actor3?`fill: ${t.actor3}`:""};\n }\n .actor-4 {\n ${t.actor4?`fill: ${t.actor4}`:""};\n }\n .actor-5 {\n ${t.actor5?`fill: ${t.actor5}`:""};\n }\n`,M=function(t,e){return y(t,e)},S=function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n},T=function(t,e){return u(t,e)};let E=-1;const A=function(){function t(t,e,n,s,r,a,o,c){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,c,l){const{taskFontSize:h,taskFontFamily:u}=c,y=t.split(//gi);for(let p=0;p3?function(t){const i=f().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}(s):e.score<3?function(t){const i=f().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}(s):s.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}(s,{cx:i,cy:300+30*(5-e.score),score:e.score});const r=d();r.x=e.x,r.y=e.y,r.fill=e.fill,r.width=n.width,r.height=n.height,r.class="task task-type-"+e.num,r.rx=3,r.ry=3,M(s,r);let a=e.x+14;e.people.forEach((t=>{const n=e.actors[t].color,i={cx:a,cy:e.y,r:7,fill:n,stroke:"#000",title:t,pos:e.actors[t].position};S(s,i),a+=10})),A(n)(e.task,s,r.x,r.y,r.width,r.height,{class:"task"},n,e.colour)},D=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},V={};const O=t().journey,L=O.leftMargin,N={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0},updateVal:function(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])},updateBounds:function(e,n,i,s){const r=t().journey,a=this;let o=0;var c;this.sequenceItems.forEach((function(t){o++;const l=a.sequenceItems.length-o+1;a.updateVal(t,"starty",n-l*r.boxMargin,Math.min),a.updateVal(t,"stopy",s+l*r.boxMargin,Math.max),a.updateVal(N.data,"startx",e-l*r.boxMargin,Math.min),a.updateVal(N.data,"stopx",i+l*r.boxMargin,Math.max),"activation"!==c&&(a.updateVal(t,"startx",e-l*r.boxMargin,Math.min),a.updateVal(t,"stopx",i+l*r.boxMargin,Math.max),a.updateVal(N.data,"starty",n-l*r.boxMargin,Math.min),a.updateVal(N.data,"stopy",s+l*r.boxMargin,Math.max))}))},insert:function(t,e,n,i){const s=Math.min(t,n),r=Math.max(t,n),a=Math.min(e,i),o=Math.max(e,i);this.updateVal(N.data,"startx",s,Math.min),this.updateVal(N.data,"starty",a,Math.min),this.updateVal(N.data,"stopx",r,Math.max),this.updateVal(N.data,"stopy",o,Math.max),this.updateBounds(s,a,r,o)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return this.data}},F=O.sectionFills,z=O.sectionColours,B=function(e,n,i){const s=t().journey;let r="";const a=i+(2*s.height+s.diagramMarginY);let o=0,c="#CCC",l="black",h=0;for(const[t,u]of n.entries()){if(r!==u.section){c=F[o%F.length],h=o%F.length,l=z[o%z.length];let i=0;const a=u.section;for(let e=t;e(V[e]&&(t[e]=V[e]),t)),{});u.x=t*s.taskMargin+t*s.width+L,u.y=a,u.width=s.diagramMarginX,u.height=s.diagramMarginY,u.colour=l,u.fill=c,u.num=h,u.actors=i,C(e,u,s),N.insert(u.x,u.y,u.x+u.width+s.taskMargin,450)}},R={setConf:function(t){Object.keys(t).forEach((function(e){O[e]=t[e]}))},draw:function(e,n,i,s){const r=t().journey;s.db.clear(),s.parser.parse(e+"\n");const a=t().securityLevel;let o;"sandbox"===a&&(o=l("#i"+n));const c=l("sandbox"===a?o.nodes()[0].contentDocument.body:"body");N.init();const u=c.select("#"+n);D(u);const y=s.db.getTasks(),p=s.db.getDiagramTitle(),d=s.db.getActors();for(const t in V)delete V[t];let f=0;d.forEach((t=>{V[t]={color:r.actorColours[f%r.actorColours.length],position:f},f++})),function(e){const n=t().journey;let i=60;Object.keys(V).forEach((t=>{const s=V[t].color,r={cx:20,cy:i,r:7,fill:s,stroke:"#000",pos:V[t].position};I(e,r);const a={x:40,y:i+7,fill:"#666",text:t,textMargin:5|n.boxTextMargin};j(e,a),i+=20}))}(u),N.insert(0,0,L,50*Object.keys(V).length),B(u,y,0);const g=N.getBounds();p&&u.append("text").text(p).attr("x",L).attr("font-size","4ex").attr("font-weight","bold").attr("y",25);const m=g.stopy-g.starty+2*r.diagramMarginY,x=L+g.stopx+2*r.diagramMarginX;h(u,m,x,r.useMaxWidth),u.append("line").attr("x1",L).attr("y1",4*r.height).attr("x2",x-L-4).attr("y2",4*r.height).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");const _=p?70:0;u.attr("viewBox",`${g.startx} -25 ${x} ${m+_}`),u.attr("preserveAspectRatio","xMinYMin meet"),u.attr("height",m+_+25)}},Y={parser:m,db:$,renderer:R,styles:w,init:t=>{R.setConf(t.journey),$.clear()}};export{Y as diagram}; diff --git a/assets/layout.2f099f66.js b/assets/layout.02c3e151.js similarity index 99% rename from assets/layout.2f099f66.js rename to assets/layout.02c3e151.js index 750f16681..0df8d7fdc 100644 --- a/assets/layout.2f099f66.js +++ b/assets/layout.02c3e151.js @@ -1 +1 @@ -import{A as e,B as n,S as t,C as r,D as o,E as i,F as u,G as a,H as c,I as s,J as f,K as d,L as h,M as v,N as l,O as g,P as p,Q as b,R as w,T as y,U as m,V as _,W as j,X as E,Y as x,Z as k}from"./mermaid.core.a66200b0.js";function N(t){return"symbol"==typeof t||e(t)&&"[object Symbol]"==n(t)}function O(e,n){for(var t=-1,r=null==e?0:e.length,o=Array(r);++t0){if(++J>=800)return arguments[0]}else J=0;return $.apply(void 0,arguments)});function Q(e,n){for(var t=-1,r=null==e?0:e.length;++t-1}var ne=/^(?:0|[1-9]\d*)$/;function te(e,n){var t=typeof e;return!!(n=null==n?9007199254740991:n)&&("number"==t||"symbol"!=t&&ne.test(e))&&e>-1&&e%1==0&&e0&&t(a)?n>1?Le(a,n-1,t,r,o):Oe(o,a):r||(o[o.length]=a)}return o}function Ae(e){return(null==e?0:e.length)?Le(e,1):[]}var Me=l(Object.getPrototypeOf,Object),Pe=Function.prototype,Se=Object.prototype,Re=Pe.toString,Te=Se.hasOwnProperty,Fe=Re.call(Object);function De(t){if(!e(t)||"[object Object]"!=n(t))return!1;var r=Me(t);if(null===r)return!0;var o=Te.call(r,"constructor")&&r.constructor;return"function"==typeof o&&o instanceof o&&Re.call(o)==Fe}function ze(e,n,t,r){var o=-1,i=null==e?0:e.length;for(r&&i&&(t=e[++o]);++oa))return!1;var s=i.get(e),f=i.get(n);if(s&&f)return s==n&&f==e;var d=-1,h=!0,v=2&t?new bn:void 0;for(i.set(e,n),i.set(n,e);++d2?n[2]:void 0;for(o&&fe(n[0],n[1],o)&&(r=1);++t-1?r[o?e[i]:i]:void 0});function at(e,n){var t=-1,r=a(e)?Array(e.length):[];return Vn(e,(function(e,o,i){r[++t]=n(e,o,i)})),r}function ct(e,n){return(r(e)?O:at)(e,Dn(n))}function st(e,n){return e>n}var ft=Object.prototype.hasOwnProperty;function dt(e,n){return null!=e&&ft.call(e,n)}function ht(e,n){return null!=e&&Sn(e,n,dt)}function vt(e){return null==e?[]:function(e,n){return O(n,(function(n){return e[n]}))}(e,ve(e))}function lt(e){return void 0===e}function gt(e,n){return e1?n[r-1]:void 0,i=r>2?n[2]:void 0;for(o=yt.length>3&&"function"==typeof o?(r--,o):void 0,i&&fe(n[0],n[1],i)&&(o=r<3?void 0:o,r=1),e=Object(e);++tn||i&&u&&c&&!a&&!s||r&&u&&c||!t&&c||!o)return 1;if(!r&&!i&&!s&&e=a?c:c*("desc"==t[r]?-1:1)}return e.index-n.index}(e,n,t)}))}function Nt(e,n){return function(e,n,t){for(var r=-1,o=n.length,i={};++r1&&fe(e,n[0],n[1])?n=[]:t>2&&fe(n[0],n[1],n[2])&&(n=[n[0]]),kt(e,Le(n,1),[])})),St=x&&1/jn(new x([,-0]))[1]==1/0?function(e){return new x(e)}:function(){};var Rt=se((function(e){return function(e,n,t){var r=-1,o=ee,i=e.length,u=!0,a=[],c=a;if(t)u=!1,o=Xn;else if(i>=200){var s=n?null:St(e);if(s)return jn(s);u=!1,o=yn,c=new bn}else c=n?[]:a;e:for(;++r1?r.setNode(e,n):r.setNode(e)})),this}setNode(e,n){return ht(this._nodes,e)?(arguments.length>1&&(this._nodes[e]=n),this):(this._nodes[e]=arguments.length>1?n:this._defaultNodeLabelFn(e),this._isCompound&&(this._parent[e]="\0",this._children[e]={},this._children["\0"][e]=!0),this._in[e]={},this._preds[e]={},this._out[e]={},this._sucs[e]={},++this._nodeCount,this)}node(e){return this._nodes[e]}hasNode(e){return ht(this._nodes,e)}removeNode(e){var n=this;if(ht(this._nodes,e)){var t=function(e){n.removeEdge(n._edgeObjs[e])};delete this._nodes[e],this._isCompound&&(this._removeFromParentsChildList(e),delete this._parent[e],nt(this.children(e),(function(e){n.setParent(e)})),delete this._children[e]),nt(ve(this._in[e]),t),delete this._in[e],delete this._preds[e],nt(ve(this._out[e]),t),delete this._out[e],delete this._sucs[e],--this._nodeCount}return this}setParent(e,n){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(lt(n))n="\0";else{for(var t=n+="";!lt(t);t=this.parent(t))if(t===e)throw new Error("Setting "+n+" as parent of "+e+" would create a cycle");this.setNode(n)}return this.setNode(e),this._removeFromParentsChildList(e),this._parent[e]=n,this._children[n][e]=!0,this}_removeFromParentsChildList(e){delete this._children[this._parent[e]][e]}parent(e){if(this._isCompound){var n=this._parent[e];if("\0"!==n)return n}}children(e){if(lt(e)&&(e="\0"),this._isCompound){var n=this._children[e];if(n)return ve(n)}else{if("\0"===e)return this.nodes();if(this.hasNode(e))return[]}}predecessors(e){var n=this._preds[e];if(n)return ve(n)}successors(e){var n=this._sucs[e];if(n)return ve(n)}neighbors(e){var n=this.predecessors(e);if(n)return Rt(n,this.successors(e))}isLeaf(e){return 0===(this.isDirected()?this.successors(e):this.neighbors(e)).length}filterNodes(e){var n=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});n.setGraph(this.graph());var t=this;nt(this._nodes,(function(t,r){e(r)&&n.setNode(r,t)})),nt(this._edgeObjs,(function(e){n.hasNode(e.v)&&n.hasNode(e.w)&&n.setEdge(e,t.edge(e))}));var r={};function o(e){var i=t.parent(e);return void 0===i||n.hasNode(i)?(r[e]=i,i):i in r?r[i]:o(i)}return this._isCompound&&nt(n.nodes(),(function(e){n.setParent(e,o(e))})),n}setDefaultEdgeLabel(e){return E(e)||(e=q(e)),this._defaultEdgeLabelFn=e,this}edgeCount(){return this._edgeCount}edges(){return vt(this._edgeObjs)}setPath(e,n){var t=this,r=arguments;return Mt(e,(function(e,o){return r.length>1?t.setEdge(e,o,n):t.setEdge(e,o),o})),this}setEdge(){var e,n,t,r,o=!1,i=arguments[0];"object"==typeof i&&null!==i&&"v"in i?(e=i.v,n=i.w,t=i.name,2===arguments.length&&(r=arguments[1],o=!0)):(e=i,n=arguments[1],t=arguments[3],arguments.length>2&&(r=arguments[2],o=!0)),e=""+e,n=""+n,lt(t)||(t=""+t);var u=Gt(this._isDirected,e,n,t);if(ht(this._edgeLabels,u))return o&&(this._edgeLabels[u]=r),this;if(!lt(t)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(e),this.setNode(n),this._edgeLabels[u]=o?r:this._defaultEdgeLabelFn(e,n,t);var a=function(e,n,t,r){var o=""+n,i=""+t;if(!e&&o>i){var u=o;o=i,i=u}var a={v:o,w:i};r&&(a.name=r);return a}(this._isDirected,e,n,t);return e=a.v,n=a.w,Object.freeze(a),this._edgeObjs[u]=a,zt(this._preds[n],e),zt(this._sucs[e],n),this._in[n][u]=a,this._out[e][u]=a,this._edgeCount++,this}edge(e,n,t){var r=1===arguments.length?Vt(this._isDirected,arguments[0]):Gt(this._isDirected,e,n,t);return this._edgeLabels[r]}hasEdge(e,n,t){var r=1===arguments.length?Vt(this._isDirected,arguments[0]):Gt(this._isDirected,e,n,t);return ht(this._edgeLabels,r)}removeEdge(e,n,t){var r=1===arguments.length?Vt(this._isDirected,arguments[0]):Gt(this._isDirected,e,n,t),o=this._edgeObjs[r];return o&&(e=o.v,n=o.w,delete this._edgeLabels[r],delete this._edgeObjs[r],Bt(this._preds[n],e),Bt(this._sucs[e],n),delete this._in[n][r],delete this._out[e][r],this._edgeCount--),this}inEdges(e,n){var t=this._in[e];if(t){var r=vt(t);return n?rt(r,(function(e){return e.v===n})):r}}outEdges(e,n){var t=this._out[e];if(t){var r=vt(t);return n?rt(r,(function(e){return e.w===n})):r}}nodeEdges(e,n){var t=this.inEdges(e,n);if(t)return t.concat(this.outEdges(e,n))}}function zt(e,n){e[n]?e[n]++:e[n]=1}function Bt(e,n){--e[n]||delete e[n]}function Gt(e,n,t,r){var o=""+n,i=""+t;if(!e&&o>i){var u=o;o=i,i=u}return o+""+i+""+(lt(r)?"\0":r)}function Vt(e,n){return Gt(e,n.v,n.w,n.name)}Dt.prototype._nodeCount=0,Dt.prototype._edgeCount=0;class Ut{constructor(){var e={};e._next=e._prev=e,this._sentinel=e}dequeue(){var e=this._sentinel,n=e._prev;if(n!==e)return Yt(n),n}enqueue(e){var n=this._sentinel;e._prev&&e._next&&Yt(e),e._next=n._next,n._next._prev=e,n._next=e,e._prev=n}toString(){for(var e=[],n=this._sentinel,t=n._prev;t!==n;)e.push(JSON.stringify(t,qt)),t=t._prev;return"["+e.join(", ")+"]"}}function Yt(e){e._prev._next=e._next,e._next._prev=e._prev,delete e._next,delete e._prev}function qt(e,n){if("_next"!==e&&"_prev"!==e)return n}var $t=q(1);function Jt(e,n){if(e.nodeCount()<=1)return[];var t=function(e,n){var t=new Dt,r=0,o=0;nt(e.nodes(),(function(e){t.setNode(e,{v:e,in:0,out:0})})),nt(e.edges(),(function(e){var i=t.edge(e.v,e.w)||0,u=n(e),a=i+u;t.setEdge(e.v,e.w,a),o=Math.max(o,t.node(e.v).out+=u),r=Math.max(r,t.node(e.w).in+=u)}));var i=Lt(o+r+3).map((function(){return new Ut})),u=r+1;return nt(t.nodes(),(function(e){Ht(i,u,t.node(e))})),{graph:t,buckets:i,zeroIdx:u}}(e,n||$t);return Ae(ct(function(e,n,t){var r,o=[],i=n[n.length-1],u=n[0];for(;e.nodeCount();){for(;r=u.dequeue();)Wt(e,n,t,r);for(;r=i.dequeue();)Wt(e,n,t,r);if(e.nodeCount())for(var a=n.length-2;a>0;--a)if(r=n[a].dequeue()){o=o.concat(Wt(e,n,t,r,!0));break}}return o}(t.graph,t.buckets,t.zeroIdx),(function(n){return e.outEdges(n.v,n.w)})))}function Wt(e,n,t,r,o){var i=o?[]:void 0;return nt(e.inEdges(r.v),(function(r){var u=e.edge(r),a=e.node(r.v);o&&i.push({v:r.v,w:r.w}),a.out-=u,Ht(n,t,a)})),nt(e.outEdges(r.v),(function(r){var o=e.edge(r),i=r.w,u=e.node(i);u.in-=o,Ht(n,t,u)})),e.removeNode(r.v),i}function Ht(e,n,t){t.out?t.in?e[t.out-t.in+n].enqueue(t):e[e.length-1].enqueue(t):e[0].enqueue(t)}function Kt(e){var n,t="greedy"===e.graph().acyclicer?Jt(e,(n=e,function(e){return n.edge(e).weight})):function(e){var n=[],t={},r={};function o(i){ht(r,i)||(r[i]=!0,t[i]=!0,nt(e.outEdges(i),(function(e){ht(t,e.w)?n.push(e):o(e.w)})),delete t[i])}return nt(e.nodes(),o),n}(e);nt(t,(function(n){var t=e.edge(n);e.removeEdge(n),t.forwardName=n.name,t.reversed=!0,e.setEdge(n.w,n.v,t,Ft("rev"))}))}function Qt(e,n,t,r){var o;do{o=Ft(r)}while(e.hasNode(o));return t.dummy=n,e.setNode(o,t),o}function Xt(e){var n=new Dt({multigraph:e.isMultigraph()}).setGraph(e.graph());return nt(e.nodes(),(function(t){e.children(t).length||n.setNode(t,e.node(t))})),nt(e.edges(),(function(t){n.setEdge(t,e.edge(t))})),n}function Zt(e,n){var t,r,o=e.x,i=e.y,u=n.x-o,a=n.y-i,c=e.width/2,s=e.height/2;if(!u&&!a)throw new Error("Not possible to find intersection inside of the rectangle");return Math.abs(a)*c>Math.abs(u)*s?(a<0&&(s=-s),t=s*u/a,r=s):(u<0&&(c=-c),t=c,r=c*a/u),{x:o+t,y:i+r}}function er(e){var n=ct(Lt(tr(e)+1),(function(){return[]}));return nt(e.nodes(),(function(t){var r=e.node(t),o=r.rank;lt(o)||(n[o][r.order]=t)})),n}function nr(e,n,t,r){var o={width:0,height:0};return arguments.length>=4&&(o.rank=t,o.order=r),Qt(e,"border",o,n)}function tr(e){return wt(ct(e.nodes(),(function(n){var t=e.node(n).rank;if(!lt(t))return t})))}function rr(e,n){var t=Un();try{return n()}finally{console.log(e+" time: "+(Un()-t)+"ms")}}function or(e,n){return n()}function ir(e,n,t,r,o,i){var u={width:0,height:0,rank:i,borderType:n},a=o[n][i-1],c=Qt(e,"border",u,t);o[n][i]=c,e.setParent(c,r),a&&e.setEdge(a,c,{weight:1})}function ur(e){var n=e.graph().rankdir.toLowerCase();"bt"!==n&&"rl"!==n||function(e){nt(e.nodes(),(function(n){sr(e.node(n))})),nt(e.edges(),(function(n){var t=e.edge(n);nt(t.points,sr),ht(t,"y")&&sr(t)}))}(e),"lr"!==n&&"rl"!==n||(!function(e){nt(e.nodes(),(function(n){fr(e.node(n))})),nt(e.edges(),(function(n){var t=e.edge(n);nt(t.points,fr),ht(t,"x")&&fr(t)}))}(e),ar(e))}function ar(e){nt(e.nodes(),(function(n){cr(e.node(n))})),nt(e.edges(),(function(n){cr(e.edge(n))}))}function cr(e){var n=e.width;e.width=e.height,e.height=n}function sr(e){e.y=-e.y}function fr(e){var n=e.x;e.x=e.y,e.y=n}function dr(e){e.graph().dummyChains=[],nt(e.edges(),(function(n){!function(e,n){var t,r,o,i=n.v,u=e.node(i).rank,a=n.w,c=e.node(a).rank,s=n.name,f=e.edge(n),d=f.labelRank;if(c===u+1)return;for(e.removeEdge(n),o=0,++u;uu.lim&&(a=u,c=!0),jt(rt(n.edges(),(function(n){return c===Ir(e,e.node(n.v),a)&&c!==Ir(e,e.node(n.w),a)})),(function(e){return vr(n,e)}))}function Or(e,n,t,r){var o=t.v,i=t.w;e.removeEdge(o,i),e.setEdge(r.v,r.w,{}),Er(e),_r(e,n),function(e,n){var t=ut(e.nodes(),(function(e){return!n.node(e).parent})),r=function(e,n){return wr(e,n,"pre")}(e,t);nt(r=r.slice(1),(function(t){var r=e.node(t).parent,o=n.edge(t,r),i=!1;o||(o=n.edge(r,t),i=!0),n.node(t).rank=n.node(r).rank+(i?o.minlen:-o.minlen)}))}(e,n)}function Ir(e,n,t){return t.low<=n.lim&&n.lim<=t.lim}function Cr(e){switch(e.graph().ranker){case"network-simplex":Ar(e);break;case"tight-tree":!function(e){hr(e),lr(e)}(e);break;case"longest-path":Lr(e);break;default:Ar(e)}}mr.initLowLimValues=Er,mr.initCutValues=_r,mr.calcCutValue=jr,mr.leaveEdge=kr,mr.enterEdge=Nr,mr.exchangeEdges=Or;var Lr=hr;function Ar(e){mr(e)}function Mr(e){var n=Qt(e,"root",{},"_root"),t=function(e){var n={};function t(r,o){var i=e.children(r);i&&i.length&&nt(i,(function(e){t(e,o+1)})),n[r]=o}return nt(e.children(),(function(e){t(e,1)})),n}(e),r=wt(vt(t))-1,o=2*r+1;e.graph().nestingRoot=n,nt(e.edges(),(function(n){e.edge(n).minlen*=o}));var i=function(e){return Mt(e.edges(),(function(n,t){return n+e.edge(t).weight}),0)}(e)+1;nt(e.children(),(function(u){Pr(e,n,o,i,r,t,u)})),e.graph().nodeRankFactor=o}function Pr(e,n,t,r,o,i,u){var a=e.children(u);if(a.length){var c=nr(e,"_bt"),s=nr(e,"_bb"),f=e.node(u);e.setParent(c,u),f.borderTop=c,e.setParent(s,u),f.borderBottom=s,nt(a,(function(a){Pr(e,n,t,r,o,i,a);var f=e.node(a),d=f.borderTop?f.borderTop:a,h=f.borderBottom?f.borderBottom:a,v=f.borderTop?r:2*r,l=d!==h?1:o-i[u]+1;e.setEdge(c,d,{weight:v,minlen:l,nestingEdge:!0}),e.setEdge(h,s,{weight:v,minlen:l,nestingEdge:!0})})),e.parent(u)||e.setEdge(n,c,{weight:0,minlen:o+i[u]})}else u!==n&&e.setEdge(n,u,{weight:0,minlen:t})}function Sr(e,n,t){var r=function(e){var n;for(;e.hasNode(n=Ft("_root")););return n}(e),o=new Dt({compound:!0}).setGraph({root:r}).setDefaultNodeLabel((function(n){return e.node(n)}));return nt(e.nodes(),(function(i){var u=e.node(i),a=e.parent(i);(u.rank===n||u.minRank<=n&&n<=u.maxRank)&&(o.setNode(i),o.setParent(i,a||r),nt(e[t](i),(function(n){var t=n.v===i?n.w:n.v,r=o.edge(t,i),u=lt(r)?0:r.weight;o.setEdge(t,i,{weight:e.edge(n).weight+u})})),ht(u,"minRank")&&o.setNode(i,{borderLeft:u.borderLeft[n],borderRight:u.borderRight[n]}))})),o}function Rr(e,n){for(var t=0,r=1;r0;)n%2&&(t+=s[n+1]),s[n=n-1>>1]+=e.weight;f+=e.weight*t}))),f}function Fr(e,n){var t={};return nt(e,(function(e,n){var r=t[e.v]={indegree:0,in:[],out:[],vs:[e.v],i:n};lt(e.barycenter)||(r.barycenter=e.barycenter,r.weight=e.weight)})),nt(n.edges(),(function(e){var n=t[e.v],r=t[e.w];lt(n)||lt(r)||(r.indegree++,n.out.push(t[e.w]))})),function(e){var n=[];function t(e){return function(n){n.merged||(lt(n.barycenter)||lt(e.barycenter)||n.barycenter>=e.barycenter)&&function(e,n){var t=0,r=0;e.weight&&(t+=e.barycenter*e.weight,r+=e.weight);n.weight&&(t+=n.barycenter*n.weight,r+=n.weight);e.vs=n.vs.concat(e.vs),e.barycenter=t/r,e.weight=r,e.i=Math.min(n.i,e.i),n.merged=!0}(e,n)}}function r(n){return function(t){t.in.push(n),0==--t.indegree&&e.push(t)}}for(;e.length;){var o=e.pop();n.push(o),nt(o.in.reverse(),t(o)),nt(o.out,r(o))}return ct(rt(n,(function(e){return!e.merged})),(function(e){return Ot(e,["vs","i","barycenter","weight"])}))}(rt(t,(function(e){return!e.indegree})))}function Dr(e,n){var t,r=function(e,n){var t={lhs:[],rhs:[]};return nt(e,(function(e){n(e)?t.lhs.push(e):t.rhs.push(e)})),t}(e,(function(e){return ht(e,"barycenter")})),o=r.lhs,i=Pt(r.rhs,(function(e){return-e.i})),u=[],a=0,c=0,s=0;o.sort((t=!!n,function(e,n){return e.barycentern.barycenter?1:t?n.i-e.i:e.i-n.i})),s=zr(u,i,s),nt(o,(function(e){s+=e.vs.length,u.push(e.vs),a+=e.barycenter*e.weight,c+=e.weight,s=zr(u,i,s)}));var f={vs:Ae(u)};return c&&(f.barycenter=a/c,f.weight=c),f}function zr(e,n,t){for(var r;n.length&&(r=Zn(n)).i<=t;)n.pop(),e.push(r.vs),t++;return t}function Br(e,n,t,r){var o=e.children(n),i=e.node(n),u=i?i.borderLeft:void 0,a=i?i.borderRight:void 0,c={};u&&(o=rt(o,(function(e){return e!==u&&e!==a})));var s=function(e,n){return ct(n,(function(n){var t=e.inEdges(n);if(t.length){var r=Mt(t,(function(n,t){var r=e.edge(t),o=e.node(t.v);return{sum:n.sum+r.weight*o.order,weight:n.weight+r.weight}}),{sum:0,weight:0});return{v:n,barycenter:r.sum/r.weight,weight:r.weight}}return{v:n}}))}(e,o);nt(s,(function(n){if(e.children(n.v).length){var o=Br(e,n.v,t,r);c[n.v]=o,ht(o,"barycenter")&&(u=o,lt((i=n).barycenter)?(i.barycenter=u.barycenter,i.weight=u.weight):(i.barycenter=(i.barycenter*i.weight+u.barycenter*u.weight)/(i.weight+u.weight),i.weight+=u.weight))}var i,u}));var f=Fr(s,t);!function(e,n){nt(e,(function(e){e.vs=Ae(e.vs.map((function(e){return n[e]?n[e].vs:e})))}))}(f,c);var d=Dr(f,r);if(u&&(d.vs=Ae([u,d.vs,a]),e.predecessors(u).length)){var h=e.node(e.predecessors(u)[0]),v=e.node(e.predecessors(a)[0]);ht(d,"barycenter")||(d.barycenter=0,d.weight=0),d.barycenter=(d.barycenter*d.weight+h.order+v.order)/(d.weight+2),d.weight+=2}return d}function Gr(e){var n=tr(e),t=Vr(e,Lt(1,n+1),"inEdges"),r=Vr(e,Lt(n-1,-1,-1),"outEdges"),o=function(e){var n={},t=rt(e.nodes(),(function(n){return!e.children(n).length})),r=wt(ct(t,(function(n){return e.node(n).rank}))),o=ct(Lt(r+1),(function(){return[]}));return nt(Pt(t,(function(n){return e.node(n).rank})),(function t(r){if(!ht(n,r)){n[r]=!0;var i=e.node(r);o[i.rank].push(r),nt(e.successors(r),t)}})),o}(e);Yr(e,o);for(var i,u=Number.POSITIVE_INFINITY,a=0,c=0;c<4;++a,++c){Ur(a%2?t:r,a%4>=2);var s=Rr(e,o=er(e));sc||s>n[o].lim));i=o,o=r;for(;(o=e.parent(o))!==i;)a.push(o);return{path:u.concat(a.reverse()),lca:i}}(e,n,o.v,o.w),u=i.path,a=i.lca,c=0,s=u[c],f=!0;t!==o.w;){if(r=e.node(t),f){for(;(s=u[c])!==a&&e.node(s).maxRankt){var r=n;n=t,t=r}var o=e[n];o||(e[n]=o={}),o[t]=!0}function Wr(e,n,t){if(n>t){var r=n;n=t,t=r}return ht(e[n],t)}function Hr(e,n,t,r,o){var i={},u=function(e,n,t,r){var o=new Dt,i=e.graph(),u=function(e,n,t){return function(r,o,i){var u,a=r.node(o),c=r.node(i),s=0;if(s+=a.width/2,ht(a,"labelpos"))switch(a.labelpos.toLowerCase()){case"l":u=-a.width/2;break;case"r":u=a.width/2}if(u&&(s+=t?u:-u),u=0,s+=(a.dummy?n:e)/2,s+=(c.dummy?n:e)/2,s+=c.width/2,ht(c,"labelpos"))switch(c.labelpos.toLowerCase()){case"l":u=c.width/2;break;case"r":u=-c.width/2}return u&&(s+=t?u:-u),u=0,s}}(i.nodesep,i.edgesep,r);return nt(n,(function(n){var r;nt(n,(function(n){var i=t[n];if(o.setNode(i),r){var a=t[r],c=o.edge(a,i);o.setEdge(a,i,Math.max(u(e,n,r),c||0))}r=n}))})),o}(e,n,t,o),a=o?"borderLeft":"borderRight";function c(e,n){for(var t=u.nodes(),r=t.pop(),o={};r;)o[r]?e(r):(o[r]=!0,t.push(r),t=t.concat(n(r))),r=t.pop()}return c((function(e){i[e]=u.inEdges(e).reduce((function(e,n){return Math.max(e,i[n.v]+u.edge(n))}),0)}),u.predecessors.bind(u)),c((function(n){var t=u.outEdges(n).reduce((function(e,n){return Math.min(e,i[n.w]-u.edge(n))}),Number.POSITIVE_INFINITY),r=e.node(n);t!==Number.POSITIVE_INFINITY&&r.borderType!==a&&(i[n]=Math.max(i[n],t))}),u.successors.bind(u)),nt(r,(function(e){i[e]=i[t[e]]})),i}function Kr(e,n){return jt(vt(n),(function(n){var t,r,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY;return r=function(n,t){var r=function(e,n){return e.node(n).width}(e,t)/2;o=Math.max(n+r,o),i=Math.min(n-r,i)},null==(t=n)||Bn(t,et(r),pe),o-i}))}function Qr(e){var n,t=er(e),r=mt($r(e,t),function(e,n){var t={};function r(n,r,o,i,u){var a;nt(Lt(r,o),(function(r){a=n[r],e.node(a).dummy&&nt(e.predecessors(a),(function(n){var r=e.node(n);r.dummy&&(r.orderu)&&Jr(t,n,a)}))}))}return Mt(n,(function(n,t){var o,i=-1,u=0;return nt(t,(function(a,c){if("border"===e.node(a).dummy){var s=e.predecessors(a);s.length&&(o=e.node(s[0]).order,r(t,u,c,i,o),u=c,i=o)}r(t,u,t.length,o,n.length)})),t})),t}(e,t)),o={};nt(["u","d"],(function(i){n="u"===i?t:vt(t).reverse(),nt(["l","r"],(function(t){"r"===t&&(n=ct(n,(function(e){return vt(e).reverse()})));var u=("u"===i?e.predecessors:e.successors).bind(e),a=function(e,n,t,r){var o={},i={},u={};return nt(n,(function(e){nt(e,(function(e,n){o[e]=e,i[e]=e,u[e]=n}))})),nt(n,(function(e){var n=-1;nt(e,(function(e){var a=r(e);if(a.length)for(var c=((a=Pt(a,(function(e){return u[e]}))).length-1)/2,s=Math.floor(c),f=Math.ceil(c);s<=f;++s){var d=a[s];i[e]===e&&n0){if(++J>=800)return arguments[0]}else J=0;return $.apply(void 0,arguments)});function Q(e,n){for(var t=-1,r=null==e?0:e.length;++t-1}var ne=/^(?:0|[1-9]\d*)$/;function te(e,n){var t=typeof e;return!!(n=null==n?9007199254740991:n)&&("number"==t||"symbol"!=t&&ne.test(e))&&e>-1&&e%1==0&&e0&&t(a)?n>1?Le(a,n-1,t,r,o):Oe(o,a):r||(o[o.length]=a)}return o}function Ae(e){return(null==e?0:e.length)?Le(e,1):[]}var Me=l(Object.getPrototypeOf,Object),Pe=Function.prototype,Se=Object.prototype,Re=Pe.toString,Te=Se.hasOwnProperty,Fe=Re.call(Object);function De(t){if(!e(t)||"[object Object]"!=n(t))return!1;var r=Me(t);if(null===r)return!0;var o=Te.call(r,"constructor")&&r.constructor;return"function"==typeof o&&o instanceof o&&Re.call(o)==Fe}function ze(e,n,t,r){var o=-1,i=null==e?0:e.length;for(r&&i&&(t=e[++o]);++oa))return!1;var s=i.get(e),f=i.get(n);if(s&&f)return s==n&&f==e;var d=-1,h=!0,v=2&t?new bn:void 0;for(i.set(e,n),i.set(n,e);++d2?n[2]:void 0;for(o&&fe(n[0],n[1],o)&&(r=1);++t-1?r[o?e[i]:i]:void 0});function at(e,n){var t=-1,r=a(e)?Array(e.length):[];return Vn(e,(function(e,o,i){r[++t]=n(e,o,i)})),r}function ct(e,n){return(r(e)?O:at)(e,Dn(n))}function st(e,n){return e>n}var ft=Object.prototype.hasOwnProperty;function dt(e,n){return null!=e&&ft.call(e,n)}function ht(e,n){return null!=e&&Sn(e,n,dt)}function vt(e){return null==e?[]:function(e,n){return O(n,(function(n){return e[n]}))}(e,ve(e))}function lt(e){return void 0===e}function gt(e,n){return e1?n[r-1]:void 0,i=r>2?n[2]:void 0;for(o=yt.length>3&&"function"==typeof o?(r--,o):void 0,i&&fe(n[0],n[1],i)&&(o=r<3?void 0:o,r=1),e=Object(e);++tn||i&&u&&c&&!a&&!s||r&&u&&c||!t&&c||!o)return 1;if(!r&&!i&&!s&&e=a?c:c*("desc"==t[r]?-1:1)}return e.index-n.index}(e,n,t)}))}function Nt(e,n){return function(e,n,t){for(var r=-1,o=n.length,i={};++r1&&fe(e,n[0],n[1])?n=[]:t>2&&fe(n[0],n[1],n[2])&&(n=[n[0]]),kt(e,Le(n,1),[])})),St=x&&1/jn(new x([,-0]))[1]==1/0?function(e){return new x(e)}:function(){};var Rt=se((function(e){return function(e,n,t){var r=-1,o=ee,i=e.length,u=!0,a=[],c=a;if(t)u=!1,o=Xn;else if(i>=200){var s=n?null:St(e);if(s)return jn(s);u=!1,o=yn,c=new bn}else c=n?[]:a;e:for(;++r1?r.setNode(e,n):r.setNode(e)})),this}setNode(e,n){return ht(this._nodes,e)?(arguments.length>1&&(this._nodes[e]=n),this):(this._nodes[e]=arguments.length>1?n:this._defaultNodeLabelFn(e),this._isCompound&&(this._parent[e]="\0",this._children[e]={},this._children["\0"][e]=!0),this._in[e]={},this._preds[e]={},this._out[e]={},this._sucs[e]={},++this._nodeCount,this)}node(e){return this._nodes[e]}hasNode(e){return ht(this._nodes,e)}removeNode(e){var n=this;if(ht(this._nodes,e)){var t=function(e){n.removeEdge(n._edgeObjs[e])};delete this._nodes[e],this._isCompound&&(this._removeFromParentsChildList(e),delete this._parent[e],nt(this.children(e),(function(e){n.setParent(e)})),delete this._children[e]),nt(ve(this._in[e]),t),delete this._in[e],delete this._preds[e],nt(ve(this._out[e]),t),delete this._out[e],delete this._sucs[e],--this._nodeCount}return this}setParent(e,n){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(lt(n))n="\0";else{for(var t=n+="";!lt(t);t=this.parent(t))if(t===e)throw new Error("Setting "+n+" as parent of "+e+" would create a cycle");this.setNode(n)}return this.setNode(e),this._removeFromParentsChildList(e),this._parent[e]=n,this._children[n][e]=!0,this}_removeFromParentsChildList(e){delete this._children[this._parent[e]][e]}parent(e){if(this._isCompound){var n=this._parent[e];if("\0"!==n)return n}}children(e){if(lt(e)&&(e="\0"),this._isCompound){var n=this._children[e];if(n)return ve(n)}else{if("\0"===e)return this.nodes();if(this.hasNode(e))return[]}}predecessors(e){var n=this._preds[e];if(n)return ve(n)}successors(e){var n=this._sucs[e];if(n)return ve(n)}neighbors(e){var n=this.predecessors(e);if(n)return Rt(n,this.successors(e))}isLeaf(e){return 0===(this.isDirected()?this.successors(e):this.neighbors(e)).length}filterNodes(e){var n=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});n.setGraph(this.graph());var t=this;nt(this._nodes,(function(t,r){e(r)&&n.setNode(r,t)})),nt(this._edgeObjs,(function(e){n.hasNode(e.v)&&n.hasNode(e.w)&&n.setEdge(e,t.edge(e))}));var r={};function o(e){var i=t.parent(e);return void 0===i||n.hasNode(i)?(r[e]=i,i):i in r?r[i]:o(i)}return this._isCompound&&nt(n.nodes(),(function(e){n.setParent(e,o(e))})),n}setDefaultEdgeLabel(e){return E(e)||(e=q(e)),this._defaultEdgeLabelFn=e,this}edgeCount(){return this._edgeCount}edges(){return vt(this._edgeObjs)}setPath(e,n){var t=this,r=arguments;return Mt(e,(function(e,o){return r.length>1?t.setEdge(e,o,n):t.setEdge(e,o),o})),this}setEdge(){var e,n,t,r,o=!1,i=arguments[0];"object"==typeof i&&null!==i&&"v"in i?(e=i.v,n=i.w,t=i.name,2===arguments.length&&(r=arguments[1],o=!0)):(e=i,n=arguments[1],t=arguments[3],arguments.length>2&&(r=arguments[2],o=!0)),e=""+e,n=""+n,lt(t)||(t=""+t);var u=Gt(this._isDirected,e,n,t);if(ht(this._edgeLabels,u))return o&&(this._edgeLabels[u]=r),this;if(!lt(t)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(e),this.setNode(n),this._edgeLabels[u]=o?r:this._defaultEdgeLabelFn(e,n,t);var a=function(e,n,t,r){var o=""+n,i=""+t;if(!e&&o>i){var u=o;o=i,i=u}var a={v:o,w:i};r&&(a.name=r);return a}(this._isDirected,e,n,t);return e=a.v,n=a.w,Object.freeze(a),this._edgeObjs[u]=a,zt(this._preds[n],e),zt(this._sucs[e],n),this._in[n][u]=a,this._out[e][u]=a,this._edgeCount++,this}edge(e,n,t){var r=1===arguments.length?Vt(this._isDirected,arguments[0]):Gt(this._isDirected,e,n,t);return this._edgeLabels[r]}hasEdge(e,n,t){var r=1===arguments.length?Vt(this._isDirected,arguments[0]):Gt(this._isDirected,e,n,t);return ht(this._edgeLabels,r)}removeEdge(e,n,t){var r=1===arguments.length?Vt(this._isDirected,arguments[0]):Gt(this._isDirected,e,n,t),o=this._edgeObjs[r];return o&&(e=o.v,n=o.w,delete this._edgeLabels[r],delete this._edgeObjs[r],Bt(this._preds[n],e),Bt(this._sucs[e],n),delete this._in[n][r],delete this._out[e][r],this._edgeCount--),this}inEdges(e,n){var t=this._in[e];if(t){var r=vt(t);return n?rt(r,(function(e){return e.v===n})):r}}outEdges(e,n){var t=this._out[e];if(t){var r=vt(t);return n?rt(r,(function(e){return e.w===n})):r}}nodeEdges(e,n){var t=this.inEdges(e,n);if(t)return t.concat(this.outEdges(e,n))}}function zt(e,n){e[n]?e[n]++:e[n]=1}function Bt(e,n){--e[n]||delete e[n]}function Gt(e,n,t,r){var o=""+n,i=""+t;if(!e&&o>i){var u=o;o=i,i=u}return o+""+i+""+(lt(r)?"\0":r)}function Vt(e,n){return Gt(e,n.v,n.w,n.name)}Dt.prototype._nodeCount=0,Dt.prototype._edgeCount=0;class Ut{constructor(){var e={};e._next=e._prev=e,this._sentinel=e}dequeue(){var e=this._sentinel,n=e._prev;if(n!==e)return Yt(n),n}enqueue(e){var n=this._sentinel;e._prev&&e._next&&Yt(e),e._next=n._next,n._next._prev=e,n._next=e,e._prev=n}toString(){for(var e=[],n=this._sentinel,t=n._prev;t!==n;)e.push(JSON.stringify(t,qt)),t=t._prev;return"["+e.join(", ")+"]"}}function Yt(e){e._prev._next=e._next,e._next._prev=e._prev,delete e._next,delete e._prev}function qt(e,n){if("_next"!==e&&"_prev"!==e)return n}var $t=q(1);function Jt(e,n){if(e.nodeCount()<=1)return[];var t=function(e,n){var t=new Dt,r=0,o=0;nt(e.nodes(),(function(e){t.setNode(e,{v:e,in:0,out:0})})),nt(e.edges(),(function(e){var i=t.edge(e.v,e.w)||0,u=n(e),a=i+u;t.setEdge(e.v,e.w,a),o=Math.max(o,t.node(e.v).out+=u),r=Math.max(r,t.node(e.w).in+=u)}));var i=Lt(o+r+3).map((function(){return new Ut})),u=r+1;return nt(t.nodes(),(function(e){Ht(i,u,t.node(e))})),{graph:t,buckets:i,zeroIdx:u}}(e,n||$t);return Ae(ct(function(e,n,t){var r,o=[],i=n[n.length-1],u=n[0];for(;e.nodeCount();){for(;r=u.dequeue();)Wt(e,n,t,r);for(;r=i.dequeue();)Wt(e,n,t,r);if(e.nodeCount())for(var a=n.length-2;a>0;--a)if(r=n[a].dequeue()){o=o.concat(Wt(e,n,t,r,!0));break}}return o}(t.graph,t.buckets,t.zeroIdx),(function(n){return e.outEdges(n.v,n.w)})))}function Wt(e,n,t,r,o){var i=o?[]:void 0;return nt(e.inEdges(r.v),(function(r){var u=e.edge(r),a=e.node(r.v);o&&i.push({v:r.v,w:r.w}),a.out-=u,Ht(n,t,a)})),nt(e.outEdges(r.v),(function(r){var o=e.edge(r),i=r.w,u=e.node(i);u.in-=o,Ht(n,t,u)})),e.removeNode(r.v),i}function Ht(e,n,t){t.out?t.in?e[t.out-t.in+n].enqueue(t):e[e.length-1].enqueue(t):e[0].enqueue(t)}function Kt(e){var n,t="greedy"===e.graph().acyclicer?Jt(e,(n=e,function(e){return n.edge(e).weight})):function(e){var n=[],t={},r={};function o(i){ht(r,i)||(r[i]=!0,t[i]=!0,nt(e.outEdges(i),(function(e){ht(t,e.w)?n.push(e):o(e.w)})),delete t[i])}return nt(e.nodes(),o),n}(e);nt(t,(function(n){var t=e.edge(n);e.removeEdge(n),t.forwardName=n.name,t.reversed=!0,e.setEdge(n.w,n.v,t,Ft("rev"))}))}function Qt(e,n,t,r){var o;do{o=Ft(r)}while(e.hasNode(o));return t.dummy=n,e.setNode(o,t),o}function Xt(e){var n=new Dt({multigraph:e.isMultigraph()}).setGraph(e.graph());return nt(e.nodes(),(function(t){e.children(t).length||n.setNode(t,e.node(t))})),nt(e.edges(),(function(t){n.setEdge(t,e.edge(t))})),n}function Zt(e,n){var t,r,o=e.x,i=e.y,u=n.x-o,a=n.y-i,c=e.width/2,s=e.height/2;if(!u&&!a)throw new Error("Not possible to find intersection inside of the rectangle");return Math.abs(a)*c>Math.abs(u)*s?(a<0&&(s=-s),t=s*u/a,r=s):(u<0&&(c=-c),t=c,r=c*a/u),{x:o+t,y:i+r}}function er(e){var n=ct(Lt(tr(e)+1),(function(){return[]}));return nt(e.nodes(),(function(t){var r=e.node(t),o=r.rank;lt(o)||(n[o][r.order]=t)})),n}function nr(e,n,t,r){var o={width:0,height:0};return arguments.length>=4&&(o.rank=t,o.order=r),Qt(e,"border",o,n)}function tr(e){return wt(ct(e.nodes(),(function(n){var t=e.node(n).rank;if(!lt(t))return t})))}function rr(e,n){var t=Un();try{return n()}finally{console.log(e+" time: "+(Un()-t)+"ms")}}function or(e,n){return n()}function ir(e,n,t,r,o,i){var u={width:0,height:0,rank:i,borderType:n},a=o[n][i-1],c=Qt(e,"border",u,t);o[n][i]=c,e.setParent(c,r),a&&e.setEdge(a,c,{weight:1})}function ur(e){var n=e.graph().rankdir.toLowerCase();"bt"!==n&&"rl"!==n||function(e){nt(e.nodes(),(function(n){sr(e.node(n))})),nt(e.edges(),(function(n){var t=e.edge(n);nt(t.points,sr),ht(t,"y")&&sr(t)}))}(e),"lr"!==n&&"rl"!==n||(!function(e){nt(e.nodes(),(function(n){fr(e.node(n))})),nt(e.edges(),(function(n){var t=e.edge(n);nt(t.points,fr),ht(t,"x")&&fr(t)}))}(e),ar(e))}function ar(e){nt(e.nodes(),(function(n){cr(e.node(n))})),nt(e.edges(),(function(n){cr(e.edge(n))}))}function cr(e){var n=e.width;e.width=e.height,e.height=n}function sr(e){e.y=-e.y}function fr(e){var n=e.x;e.x=e.y,e.y=n}function dr(e){e.graph().dummyChains=[],nt(e.edges(),(function(n){!function(e,n){var t,r,o,i=n.v,u=e.node(i).rank,a=n.w,c=e.node(a).rank,s=n.name,f=e.edge(n),d=f.labelRank;if(c===u+1)return;for(e.removeEdge(n),o=0,++u;uu.lim&&(a=u,c=!0),jt(rt(n.edges(),(function(n){return c===Ir(e,e.node(n.v),a)&&c!==Ir(e,e.node(n.w),a)})),(function(e){return vr(n,e)}))}function Or(e,n,t,r){var o=t.v,i=t.w;e.removeEdge(o,i),e.setEdge(r.v,r.w,{}),Er(e),_r(e,n),function(e,n){var t=ut(e.nodes(),(function(e){return!n.node(e).parent})),r=function(e,n){return wr(e,n,"pre")}(e,t);nt(r=r.slice(1),(function(t){var r=e.node(t).parent,o=n.edge(t,r),i=!1;o||(o=n.edge(r,t),i=!0),n.node(t).rank=n.node(r).rank+(i?o.minlen:-o.minlen)}))}(e,n)}function Ir(e,n,t){return t.low<=n.lim&&n.lim<=t.lim}function Cr(e){switch(e.graph().ranker){case"network-simplex":Ar(e);break;case"tight-tree":!function(e){hr(e),lr(e)}(e);break;case"longest-path":Lr(e);break;default:Ar(e)}}mr.initLowLimValues=Er,mr.initCutValues=_r,mr.calcCutValue=jr,mr.leaveEdge=kr,mr.enterEdge=Nr,mr.exchangeEdges=Or;var Lr=hr;function Ar(e){mr(e)}function Mr(e){var n=Qt(e,"root",{},"_root"),t=function(e){var n={};function t(r,o){var i=e.children(r);i&&i.length&&nt(i,(function(e){t(e,o+1)})),n[r]=o}return nt(e.children(),(function(e){t(e,1)})),n}(e),r=wt(vt(t))-1,o=2*r+1;e.graph().nestingRoot=n,nt(e.edges(),(function(n){e.edge(n).minlen*=o}));var i=function(e){return Mt(e.edges(),(function(n,t){return n+e.edge(t).weight}),0)}(e)+1;nt(e.children(),(function(u){Pr(e,n,o,i,r,t,u)})),e.graph().nodeRankFactor=o}function Pr(e,n,t,r,o,i,u){var a=e.children(u);if(a.length){var c=nr(e,"_bt"),s=nr(e,"_bb"),f=e.node(u);e.setParent(c,u),f.borderTop=c,e.setParent(s,u),f.borderBottom=s,nt(a,(function(a){Pr(e,n,t,r,o,i,a);var f=e.node(a),d=f.borderTop?f.borderTop:a,h=f.borderBottom?f.borderBottom:a,v=f.borderTop?r:2*r,l=d!==h?1:o-i[u]+1;e.setEdge(c,d,{weight:v,minlen:l,nestingEdge:!0}),e.setEdge(h,s,{weight:v,minlen:l,nestingEdge:!0})})),e.parent(u)||e.setEdge(n,c,{weight:0,minlen:o+i[u]})}else u!==n&&e.setEdge(n,u,{weight:0,minlen:t})}function Sr(e,n,t){var r=function(e){var n;for(;e.hasNode(n=Ft("_root")););return n}(e),o=new Dt({compound:!0}).setGraph({root:r}).setDefaultNodeLabel((function(n){return e.node(n)}));return nt(e.nodes(),(function(i){var u=e.node(i),a=e.parent(i);(u.rank===n||u.minRank<=n&&n<=u.maxRank)&&(o.setNode(i),o.setParent(i,a||r),nt(e[t](i),(function(n){var t=n.v===i?n.w:n.v,r=o.edge(t,i),u=lt(r)?0:r.weight;o.setEdge(t,i,{weight:e.edge(n).weight+u})})),ht(u,"minRank")&&o.setNode(i,{borderLeft:u.borderLeft[n],borderRight:u.borderRight[n]}))})),o}function Rr(e,n){for(var t=0,r=1;r0;)n%2&&(t+=s[n+1]),s[n=n-1>>1]+=e.weight;f+=e.weight*t}))),f}function Fr(e,n){var t={};return nt(e,(function(e,n){var r=t[e.v]={indegree:0,in:[],out:[],vs:[e.v],i:n};lt(e.barycenter)||(r.barycenter=e.barycenter,r.weight=e.weight)})),nt(n.edges(),(function(e){var n=t[e.v],r=t[e.w];lt(n)||lt(r)||(r.indegree++,n.out.push(t[e.w]))})),function(e){var n=[];function t(e){return function(n){n.merged||(lt(n.barycenter)||lt(e.barycenter)||n.barycenter>=e.barycenter)&&function(e,n){var t=0,r=0;e.weight&&(t+=e.barycenter*e.weight,r+=e.weight);n.weight&&(t+=n.barycenter*n.weight,r+=n.weight);e.vs=n.vs.concat(e.vs),e.barycenter=t/r,e.weight=r,e.i=Math.min(n.i,e.i),n.merged=!0}(e,n)}}function r(n){return function(t){t.in.push(n),0==--t.indegree&&e.push(t)}}for(;e.length;){var o=e.pop();n.push(o),nt(o.in.reverse(),t(o)),nt(o.out,r(o))}return ct(rt(n,(function(e){return!e.merged})),(function(e){return Ot(e,["vs","i","barycenter","weight"])}))}(rt(t,(function(e){return!e.indegree})))}function Dr(e,n){var t,r=function(e,n){var t={lhs:[],rhs:[]};return nt(e,(function(e){n(e)?t.lhs.push(e):t.rhs.push(e)})),t}(e,(function(e){return ht(e,"barycenter")})),o=r.lhs,i=Pt(r.rhs,(function(e){return-e.i})),u=[],a=0,c=0,s=0;o.sort((t=!!n,function(e,n){return e.barycentern.barycenter?1:t?n.i-e.i:e.i-n.i})),s=zr(u,i,s),nt(o,(function(e){s+=e.vs.length,u.push(e.vs),a+=e.barycenter*e.weight,c+=e.weight,s=zr(u,i,s)}));var f={vs:Ae(u)};return c&&(f.barycenter=a/c,f.weight=c),f}function zr(e,n,t){for(var r;n.length&&(r=Zn(n)).i<=t;)n.pop(),e.push(r.vs),t++;return t}function Br(e,n,t,r){var o=e.children(n),i=e.node(n),u=i?i.borderLeft:void 0,a=i?i.borderRight:void 0,c={};u&&(o=rt(o,(function(e){return e!==u&&e!==a})));var s=function(e,n){return ct(n,(function(n){var t=e.inEdges(n);if(t.length){var r=Mt(t,(function(n,t){var r=e.edge(t),o=e.node(t.v);return{sum:n.sum+r.weight*o.order,weight:n.weight+r.weight}}),{sum:0,weight:0});return{v:n,barycenter:r.sum/r.weight,weight:r.weight}}return{v:n}}))}(e,o);nt(s,(function(n){if(e.children(n.v).length){var o=Br(e,n.v,t,r);c[n.v]=o,ht(o,"barycenter")&&(u=o,lt((i=n).barycenter)?(i.barycenter=u.barycenter,i.weight=u.weight):(i.barycenter=(i.barycenter*i.weight+u.barycenter*u.weight)/(i.weight+u.weight),i.weight+=u.weight))}var i,u}));var f=Fr(s,t);!function(e,n){nt(e,(function(e){e.vs=Ae(e.vs.map((function(e){return n[e]?n[e].vs:e})))}))}(f,c);var d=Dr(f,r);if(u&&(d.vs=Ae([u,d.vs,a]),e.predecessors(u).length)){var h=e.node(e.predecessors(u)[0]),v=e.node(e.predecessors(a)[0]);ht(d,"barycenter")||(d.barycenter=0,d.weight=0),d.barycenter=(d.barycenter*d.weight+h.order+v.order)/(d.weight+2),d.weight+=2}return d}function Gr(e){var n=tr(e),t=Vr(e,Lt(1,n+1),"inEdges"),r=Vr(e,Lt(n-1,-1,-1),"outEdges"),o=function(e){var n={},t=rt(e.nodes(),(function(n){return!e.children(n).length})),r=wt(ct(t,(function(n){return e.node(n).rank}))),o=ct(Lt(r+1),(function(){return[]}));return nt(Pt(t,(function(n){return e.node(n).rank})),(function t(r){if(!ht(n,r)){n[r]=!0;var i=e.node(r);o[i.rank].push(r),nt(e.successors(r),t)}})),o}(e);Yr(e,o);for(var i,u=Number.POSITIVE_INFINITY,a=0,c=0;c<4;++a,++c){Ur(a%2?t:r,a%4>=2);var s=Rr(e,o=er(e));sc||s>n[o].lim));i=o,o=r;for(;(o=e.parent(o))!==i;)a.push(o);return{path:u.concat(a.reverse()),lca:i}}(e,n,o.v,o.w),u=i.path,a=i.lca,c=0,s=u[c],f=!0;t!==o.w;){if(r=e.node(t),f){for(;(s=u[c])!==a&&e.node(s).maxRankt){var r=n;n=t,t=r}var o=e[n];o||(e[n]=o={}),o[t]=!0}function Wr(e,n,t){if(n>t){var r=n;n=t,t=r}return ht(e[n],t)}function Hr(e,n,t,r,o){var i={},u=function(e,n,t,r){var o=new Dt,i=e.graph(),u=function(e,n,t){return function(r,o,i){var u,a=r.node(o),c=r.node(i),s=0;if(s+=a.width/2,ht(a,"labelpos"))switch(a.labelpos.toLowerCase()){case"l":u=-a.width/2;break;case"r":u=a.width/2}if(u&&(s+=t?u:-u),u=0,s+=(a.dummy?n:e)/2,s+=(c.dummy?n:e)/2,s+=c.width/2,ht(c,"labelpos"))switch(c.labelpos.toLowerCase()){case"l":u=c.width/2;break;case"r":u=-c.width/2}return u&&(s+=t?u:-u),u=0,s}}(i.nodesep,i.edgesep,r);return nt(n,(function(n){var r;nt(n,(function(n){var i=t[n];if(o.setNode(i),r){var a=t[r],c=o.edge(a,i);o.setEdge(a,i,Math.max(u(e,n,r),c||0))}r=n}))})),o}(e,n,t,o),a=o?"borderLeft":"borderRight";function c(e,n){for(var t=u.nodes(),r=t.pop(),o={};r;)o[r]?e(r):(o[r]=!0,t.push(r),t=t.concat(n(r))),r=t.pop()}return c((function(e){i[e]=u.inEdges(e).reduce((function(e,n){return Math.max(e,i[n.v]+u.edge(n))}),0)}),u.predecessors.bind(u)),c((function(n){var t=u.outEdges(n).reduce((function(e,n){return Math.min(e,i[n.w]-u.edge(n))}),Number.POSITIVE_INFINITY),r=e.node(n);t!==Number.POSITIVE_INFINITY&&r.borderType!==a&&(i[n]=Math.max(i[n],t))}),u.successors.bind(u)),nt(r,(function(e){i[e]=i[t[e]]})),i}function Kr(e,n){return jt(vt(n),(function(n){var t,r,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY;return r=function(n,t){var r=function(e,n){return e.node(n).width}(e,t)/2;o=Math.max(n+r,o),i=Math.min(n-r,i)},null==(t=n)||Bn(t,et(r),pe),o-i}))}function Qr(e){var n,t=er(e),r=mt($r(e,t),function(e,n){var t={};function r(n,r,o,i,u){var a;nt(Lt(r,o),(function(r){a=n[r],e.node(a).dummy&&nt(e.predecessors(a),(function(n){var r=e.node(n);r.dummy&&(r.orderu)&&Jr(t,n,a)}))}))}return Mt(n,(function(n,t){var o,i=-1,u=0;return nt(t,(function(a,c){if("border"===e.node(a).dummy){var s=e.predecessors(a);s.length&&(o=e.node(s[0]).order,r(t,u,c,i,o),u=c,i=o)}r(t,u,t.length,o,n.length)})),t})),t}(e,t)),o={};nt(["u","d"],(function(i){n="u"===i?t:vt(t).reverse(),nt(["l","r"],(function(t){"r"===t&&(n=ct(n,(function(e){return vt(e).reverse()})));var u=("u"===i?e.predecessors:e.successors).bind(e),a=function(e,n,t,r){var o={},i={},u={};return nt(n,(function(e){nt(e,(function(e,n){o[e]=e,i[e]=e,u[e]=n}))})),nt(n,(function(e){var n=-1;nt(e,(function(e){var a=r(e);if(a.length)for(var c=((a=Pt(a,(function(e){return u[e]}))).length-1)/2,s=Math.floor(c),f=Math.ceil(c);s<=f;++s){var d=a[s];i[e]===e&&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.

    {\n  "log": {\n    "access": "file_path",\n    "error": "file_path",\n    "loglevel": "warning",\n    "dnsLog": false\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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.

    ',17);e.render=function(o,e){return n};export default e; +import{d as o}from"./app.48111a85.js";const e={},n=o('

    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.

    {\n  "log": {\n    "access": "file_path",\n    "error": "file_path",\n    "loglevel": "warning",\n    "dnsLog": false\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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.

    ',17);e.render=function(o,e){return n};export default e; diff --git a/assets/log.html.0c40cfaf.js b/assets/log.html.e629044e.js similarity index 98% rename from assets/log.html.0c40cfaf.js rename to assets/log.html.e629044e.js index bb8552db5..4602cc0ec 100644 --- a/assets/log.html.0c40cfaf.js +++ b/assets/log.html.e629044e.js @@ -1 +1 @@ -import{d as o}from"./app.755d843f.js";const n={},e=o('

    日志配置

    日志配置,控制 Xray 输出日志的方式.

    Xray 有两种日志, 访问日志和错误日志, 你可以分别配置两种日志的输出方式.

    LogObject

    LogObject 对应配置文件的 log 项。

    {\n  "log": {\n    "access": "文件地址",\n    "error": "文件地址",\n    "loglevel": "warning",\n    "dnsLog": false\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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

    ',17);n.render=function(o,n){return e};export default n; +import{d as o}from"./app.48111a85.js";const n={},e=o('

    日志配置

    日志配置,控制 Xray 输出日志的方式.

    Xray 有两种日志, 访问日志和错误日志, 你可以分别配置两种日志的输出方式.

    LogObject

    LogObject 对应配置文件的 log 项。

    {\n  "log": {\n    "access": "文件地址",\n    "error": "文件地址",\n    "loglevel": "warning",\n    "dnsLog": false\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    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

    ',17);n.render=function(o,n){return e};export default n; diff --git a/assets/mermaid.core.a66200b0.js b/assets/mermaid.core.3a590193.js similarity index 99% rename from assets/mermaid.core.a66200b0.js rename to assets/mermaid.core.3a590193.js index b9f7c6a69..e592a6138 100644 --- a/assets/mermaid.core.a66200b0.js +++ b/assets/mermaid.core.3a590193.js @@ -2,7 +2,7 @@ var t=Object.defineProperty,e=Object.defineProperties,i=Object.getOwnPropertyDes /*! @license DOMPurify 3.0.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.0.3/LICENSE */ const{entries:en,setPrototypeOf:rn,isFrozen:nn,getPrototypeOf:on,getOwnPropertyDescriptor:an}=Object;let{freeze:sn,seal:ln,create:hn}=Object,{apply:cn,construct:un}="undefined"!=typeof Reflect&&Reflect;cn||(cn=function(t,e,i){return t.apply(e,i)}),sn||(sn=function(t){return t}),ln||(ln=function(t){return t}),un||(un=function(t,e){return new t(...e)});const dn=Tn(Array.prototype.forEach),fn=Tn(Array.prototype.pop),pn=Tn(Array.prototype.push),gn=Tn(String.prototype.toLowerCase),mn=Tn(String.prototype.toString),yn=Tn(String.prototype.match),_n=Tn(String.prototype.replace),bn=Tn(String.prototype.indexOf),Cn=Tn(String.prototype.trim),xn=Tn(RegExp.prototype.test),kn=(vn=TypeError,function(){for(var t=arguments.length,e=new Array(t),i=0;i1?i-1:0),n=1;n/gm),Rn=ln(/\${[\w\W]*}/gm),Pn=ln(/^data-[\-\w.\u00B7-\uFFFF]/),Wn=ln(/^aria-[\-\w]+$/),Hn=ln(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),Un=ln(/^(?:\w+script|data):/i),Yn=ln(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Vn=ln(/^html$/i);var Gn=Object.freeze({__proto__:null,MUSTACHE_EXPR:$n,ERB_EXPR:jn,TMPLIT_EXPR:Rn,DATA_ATTR:Pn,ARIA_ATTR:Wn,IS_ALLOWED_URI:Hn,IS_SCRIPT_OR_DATA:Un,ATTR_WHITESPACE:Yn,DOCTYPE_NAME:Vn});const Xn=()=>"undefined"==typeof window?null:window,Zn=function(t,e){if("object"!=typeof t||"function"!=typeof t.createPolicy)return null;let i=null;const r="data-tt-policy-suffix";e&&e.hasAttribute(r)&&(i=e.getAttribute(r));const n="dompurify"+(i?"#"+i:"");try{return t.createPolicy(n,{createHTML:t=>t,createScriptURL:t=>t})}catch(o){return console.warn("TrustedTypes policy "+n+" could not be created."),null}};var Jn=function t(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Xn();const i=e=>t(e);if(i.version="3.0.3",i.removed=[],!e||!e.document||9!==e.document.nodeType)return i.isSupported=!1,i;const r=e.document,n=r.currentScript;let{document:o}=e;const{DocumentFragment:a,HTMLTemplateElement:s,Node:l,Element:h,NodeFilter:c,NamedNodeMap:u=e.NamedNodeMap||e.MozNamedAttrMap,HTMLFormElement:d,DOMParser:f,trustedTypes:p}=e,g=h.prototype,m=Bn(g,"cloneNode"),y=Bn(g,"nextSibling"),_=Bn(g,"childNodes"),b=Bn(g,"parentNode");if("function"==typeof s){const t=o.createElement("template");t.content&&t.content.ownerDocument&&(o=t.content.ownerDocument)}let C,x="";const{implementation:k,createNodeIterator:v,createDocumentFragment:T,getElementsByTagName:S}=o,{importNode:w}=r;let B={};i.isSupported="function"==typeof en&&"function"==typeof b&&k&&void 0!==k.createHTMLDocument;const{MUSTACHE_EXPR:F,ERB_EXPR:L,TMPLIT_EXPR:A,DATA_ATTR:E,ARIA_ATTR:M,IS_SCRIPT_OR_DATA:O,ATTR_WHITESPACE:I}=Gn;let{IS_ALLOWED_URI:q}=Gn,N=null;const D=Sn({},[...Fn,...Ln,...An,...Mn,...In]);let z=null;const $=Sn({},[...qn,...Nn,...Dn,...zn]);let j=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),R=null,P=null,W=!0,H=!0,U=!1,Y=!0,V=!1,G=!1,X=!1,Z=!1,J=!1,K=!1,Q=!1,tt=!0,et=!1;const it="user-content-";let rt=!0,nt=!1,ot={},at=null;const st=Sn({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let lt=null;const ht=Sn({},["audio","video","img","source","image","track"]);let ct=null;const ut=Sn({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),dt="http://www.w3.org/1998/Math/MathML",ft="http://www.w3.org/2000/svg",pt="http://www.w3.org/1999/xhtml";let gt=pt,mt=!1,yt=null;const _t=Sn({},[dt,ft,pt],mn);let bt;const Ct=["application/xhtml+xml","text/html"],xt="text/html";let kt,vt=null;const Tt=o.createElement("form"),St=function(t){return t instanceof RegExp||t instanceof Function},wt=function(t){if(!vt||vt!==t){if(t&&"object"==typeof t||(t={}),t=wn(t),bt=bt=-1===Ct.indexOf(t.PARSER_MEDIA_TYPE)?xt:t.PARSER_MEDIA_TYPE,kt="application/xhtml+xml"===bt?mn:gn,N="ALLOWED_TAGS"in t?Sn({},t.ALLOWED_TAGS,kt):D,z="ALLOWED_ATTR"in t?Sn({},t.ALLOWED_ATTR,kt):$,yt="ALLOWED_NAMESPACES"in t?Sn({},t.ALLOWED_NAMESPACES,mn):_t,ct="ADD_URI_SAFE_ATTR"in t?Sn(wn(ut),t.ADD_URI_SAFE_ATTR,kt):ut,lt="ADD_DATA_URI_TAGS"in t?Sn(wn(ht),t.ADD_DATA_URI_TAGS,kt):ht,at="FORBID_CONTENTS"in t?Sn({},t.FORBID_CONTENTS,kt):st,R="FORBID_TAGS"in t?Sn({},t.FORBID_TAGS,kt):{},P="FORBID_ATTR"in t?Sn({},t.FORBID_ATTR,kt):{},ot="USE_PROFILES"in t&&t.USE_PROFILES,W=!1!==t.ALLOW_ARIA_ATTR,H=!1!==t.ALLOW_DATA_ATTR,U=t.ALLOW_UNKNOWN_PROTOCOLS||!1,Y=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,V=t.SAFE_FOR_TEMPLATES||!1,G=t.WHOLE_DOCUMENT||!1,J=t.RETURN_DOM||!1,K=t.RETURN_DOM_FRAGMENT||!1,Q=t.RETURN_TRUSTED_TYPE||!1,Z=t.FORCE_BODY||!1,tt=!1!==t.SANITIZE_DOM,et=t.SANITIZE_NAMED_PROPS||!1,rt=!1!==t.KEEP_CONTENT,nt=t.IN_PLACE||!1,q=t.ALLOWED_URI_REGEXP||Hn,gt=t.NAMESPACE||pt,j=t.CUSTOM_ELEMENT_HANDLING||{},t.CUSTOM_ELEMENT_HANDLING&&St(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(j.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&St(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(j.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(j.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),V&&(H=!1),K&&(J=!0),ot&&(N=Sn({},[...In]),z=[],!0===ot.html&&(Sn(N,Fn),Sn(z,qn)),!0===ot.svg&&(Sn(N,Ln),Sn(z,Nn),Sn(z,zn)),!0===ot.svgFilters&&(Sn(N,An),Sn(z,Nn),Sn(z,zn)),!0===ot.mathMl&&(Sn(N,Mn),Sn(z,Dn),Sn(z,zn))),t.ADD_TAGS&&(N===D&&(N=wn(N)),Sn(N,t.ADD_TAGS,kt)),t.ADD_ATTR&&(z===$&&(z=wn(z)),Sn(z,t.ADD_ATTR,kt)),t.ADD_URI_SAFE_ATTR&&Sn(ct,t.ADD_URI_SAFE_ATTR,kt),t.FORBID_CONTENTS&&(at===st&&(at=wn(at)),Sn(at,t.FORBID_CONTENTS,kt)),rt&&(N["#text"]=!0),G&&Sn(N,["html","head","body"]),N.table&&(Sn(N,["tbody"]),delete R.tbody),t.TRUSTED_TYPES_POLICY){if("function"!=typeof t.TRUSTED_TYPES_POLICY.createHTML)throw kn('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof t.TRUSTED_TYPES_POLICY.createScriptURL)throw kn('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');C=t.TRUSTED_TYPES_POLICY,x=C.createHTML("")}else void 0===C&&(C=Zn(p,n)),null!==C&&"string"==typeof x&&(x=C.createHTML(""));sn&&sn(t),vt=t}},Bt=Sn({},["mi","mo","mn","ms","mtext"]),Ft=Sn({},["foreignobject","desc","title","annotation-xml"]),Lt=Sn({},["title","style","font","a","script"]),At=Sn({},Ln);Sn(At,An),Sn(At,En);const Et=Sn({},Mn);Sn(Et,On);const Mt=function(t){let e=b(t);e&&e.tagName||(e={namespaceURI:gt,tagName:"template"});const i=gn(t.tagName),r=gn(e.tagName);return!!yt[t.namespaceURI]&&(t.namespaceURI===ft?e.namespaceURI===pt?"svg"===i:e.namespaceURI===dt?"svg"===i&&("annotation-xml"===r||Bt[r]):Boolean(At[i]):t.namespaceURI===dt?e.namespaceURI===pt?"math"===i:e.namespaceURI===ft?"math"===i&&Ft[r]:Boolean(Et[i]):t.namespaceURI===pt?!(e.namespaceURI===ft&&!Ft[r])&&(!(e.namespaceURI===dt&&!Bt[r])&&(!Et[i]&&(Lt[i]||!At[i]))):!("application/xhtml+xml"!==bt||!yt[t.namespaceURI]))},Ot=function(t){pn(i.removed,{element:t});try{t.parentNode.removeChild(t)}catch(e){t.remove()}},It=function(t,e){try{pn(i.removed,{attribute:e.getAttributeNode(t),from:e})}catch(r){pn(i.removed,{attribute:null,from:e})}if(e.removeAttribute(t),"is"===t&&!z[t])if(J||K)try{Ot(e)}catch(r){}else try{e.setAttribute(t,"")}catch(r){}},qt=function(t){let e,i;if(Z)t=""+t;else{const e=yn(t,/^[\r\n\t ]+/);i=e&&e[0]}"application/xhtml+xml"===bt&>===pt&&(t=''+t+"");const r=C?C.createHTML(t):t;if(gt===pt)try{e=(new f).parseFromString(r,bt)}catch(a){}if(!e||!e.documentElement){e=k.createDocument(gt,"template",null);try{e.documentElement.innerHTML=mt?x:r}catch(a){}}const n=e.body||e.documentElement;return t&&i&&n.insertBefore(o.createTextNode(i),n.childNodes[0]||null),gt===pt?S.call(e,G?"html":"body")[0]:G?e.documentElement:n},Nt=function(t){return v.call(t.ownerDocument||t,t,c.SHOW_ELEMENT|c.SHOW_COMMENT|c.SHOW_TEXT,null,!1)},Dt=function(t){return t instanceof d&&("string"!=typeof t.nodeName||"string"!=typeof t.textContent||"function"!=typeof t.removeChild||!(t.attributes instanceof u)||"function"!=typeof t.removeAttribute||"function"!=typeof t.setAttribute||"string"!=typeof t.namespaceURI||"function"!=typeof t.insertBefore||"function"!=typeof t.hasChildNodes)},zt=function(t){return"object"==typeof l?t instanceof l:t&&"object"==typeof t&&"number"==typeof t.nodeType&&"string"==typeof t.nodeName},$t=function(t,e,r){B[t]&&dn(B[t],(t=>{t.call(i,e,r,vt)}))},jt=function(t){let e;if($t("beforeSanitizeElements",t,null),Dt(t))return Ot(t),!0;const r=kt(t.nodeName);if($t("uponSanitizeElement",t,{tagName:r,allowedTags:N}),t.hasChildNodes()&&!zt(t.firstElementChild)&&(!zt(t.content)||!zt(t.content.firstElementChild))&&xn(/<[/\w]/g,t.innerHTML)&&xn(/<[/\w]/g,t.textContent))return Ot(t),!0;if(!N[r]||R[r]){if(!R[r]&&Pt(r)){if(j.tagNameCheck instanceof RegExp&&xn(j.tagNameCheck,r))return!1;if(j.tagNameCheck instanceof Function&&j.tagNameCheck(r))return!1}if(rt&&!at[r]){const e=b(t)||t.parentNode,i=_(t)||t.childNodes;if(i&&e){for(let r=i.length-1;r>=0;--r)e.insertBefore(m(i[r],!0),y(t))}}return Ot(t),!0}return t instanceof h&&!Mt(t)?(Ot(t),!0):"noscript"!==r&&"noembed"!==r||!xn(/<\/no(script|embed)/i,t.innerHTML)?(V&&3===t.nodeType&&(e=t.textContent,e=_n(e,F," "),e=_n(e,L," "),e=_n(e,A," "),t.textContent!==e&&(pn(i.removed,{element:t.cloneNode()}),t.textContent=e)),$t("afterSanitizeElements",t,null),!1):(Ot(t),!0)},Rt=function(t,e,i){if(tt&&("id"===e||"name"===e)&&(i in o||i in Tt))return!1;if(H&&!P[e]&&xn(E,e));else if(W&&xn(M,e));else if(!z[e]||P[e]){if(!(Pt(t)&&(j.tagNameCheck instanceof RegExp&&xn(j.tagNameCheck,t)||j.tagNameCheck instanceof Function&&j.tagNameCheck(t))&&(j.attributeNameCheck instanceof RegExp&&xn(j.attributeNameCheck,e)||j.attributeNameCheck instanceof Function&&j.attributeNameCheck(e))||"is"===e&&j.allowCustomizedBuiltInElements&&(j.tagNameCheck instanceof RegExp&&xn(j.tagNameCheck,i)||j.tagNameCheck instanceof Function&&j.tagNameCheck(i))))return!1}else if(ct[e]);else if(xn(q,_n(i,I,"")));else if("src"!==e&&"xlink:href"!==e&&"href"!==e||"script"===t||0!==bn(i,"data:")||!lt[t]){if(U&&!xn(O,_n(i,I,"")));else if(i)return!1}else;return!0},Pt=function(t){return t.indexOf("-")>0},Wt=function(t){let e,r,n,o;$t("beforeSanitizeAttributes",t,null);const{attributes:a}=t;if(!a)return;const s={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:z};for(o=a.length;o--;){e=a[o];const{name:h,namespaceURI:c}=e;if(r="value"===h?e.value:Cn(e.value),n=kt(h),s.attrName=n,s.attrValue=r,s.keepAttr=!0,s.forceKeepAttr=void 0,$t("uponSanitizeAttribute",t,s),r=s.attrValue,s.forceKeepAttr)continue;if(It(h,t),!s.keepAttr)continue;if(!Y&&xn(/\/>/i,r)){It(h,t);continue}V&&(r=_n(r,F," "),r=_n(r,L," "),r=_n(r,A," "));const u=kt(t.nodeName);if(Rt(u,n,r)){if(!et||"id"!==n&&"name"!==n||(It(h,t),r=it+r),C&&"object"==typeof p&&"function"==typeof p.getAttributeType)if(c);else switch(p.getAttributeType(u,n)){case"TrustedHTML":r=C.createHTML(r);break;case"TrustedScriptURL":r=C.createScriptURL(r)}try{c?t.setAttributeNS(c,h,r):t.setAttribute(h,r),fn(i.removed)}catch(l){}}}$t("afterSanitizeAttributes",t,null)},Ht=function t(e){let i;const r=Nt(e);for($t("beforeSanitizeShadowDOM",e,null);i=r.nextNode();)$t("uponSanitizeShadowNode",i,null),jt(i)||(i.content instanceof a&&t(i.content),Wt(i));$t("afterSanitizeShadowDOM",e,null)};return i.sanitize=function(t){let e,n,o,s,h=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(mt=!t,mt&&(t="\x3c!--\x3e"),"string"!=typeof t&&!zt(t)){if("function"!=typeof t.toString)throw kn("toString is not a function");if("string"!=typeof(t=t.toString()))throw kn("dirty is not a string, aborting")}if(!i.isSupported)return t;if(X||wt(h),i.removed=[],"string"==typeof t&&(nt=!1),nt){if(t.nodeName){const e=kt(t.nodeName);if(!N[e]||R[e])throw kn("root node is forbidden and cannot be sanitized in-place")}}else if(t instanceof l)e=qt("\x3c!----\x3e"),n=e.ownerDocument.importNode(t,!0),1===n.nodeType&&"BODY"===n.nodeName||"HTML"===n.nodeName?e=n:e.appendChild(n);else{if(!J&&!V&&!G&&-1===t.indexOf("<"))return C&&Q?C.createHTML(t):t;if(e=qt(t),!e)return J?null:Q?x:""}e&&Z&&Ot(e.firstChild);const c=Nt(nt?t:e);for(;o=c.nextNode();)jt(o)||(o.content instanceof a&&Ht(o.content),Wt(o));if(nt)return t;if(J){if(K)for(s=T.call(e.ownerDocument);e.firstChild;)s.appendChild(e.firstChild);else s=e;return(z.shadowroot||z.shadowrootmod)&&(s=w.call(r,s,!0)),s}let u=G?e.outerHTML:e.innerHTML;return G&&N["!doctype"]&&e.ownerDocument&&e.ownerDocument.doctype&&e.ownerDocument.doctype.name&&xn(Vn,e.ownerDocument.doctype.name)&&(u="\n"+u),V&&(u=_n(u,F," "),u=_n(u,L," "),u=_n(u,A," ")),C&&Q?C.createHTML(u):u},i.setConfig=function(t){wt(t),X=!0},i.clearConfig=function(){vt=null,X=!1},i.isValidAttribute=function(t,e,i){vt||wt({});const r=kt(t),n=kt(e);return Rt(r,n,i)},i.addHook=function(t,e){"function"==typeof e&&(B[t]=B[t]||[],pn(B[t],e))},i.removeHook=function(t){if(B[t])return fn(B[t])},i.removeHooks=function(t){B[t]&&(B[t]=[])},i.removeAllHooks=function(){B={}},i}();const Kn={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:t=>t>=255?255:t<0?0:t,g:t=>t>=255?255:t<0?0:t,b:t=>t>=255?255:t<0?0:t,h:t=>t%360,s:t=>t>=100?100:t<0?0:t,l:t=>t>=100?100:t<0?0:t,a:t=>t>=1?1:t<0?0:t},toLinear:t=>{const e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},hue2rgb:(t,e,i)=>(i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+(e-t)*(2/3-i)*6:t),hsl2rgb:({h:t,s:e,l:i},r)=>{if(!e)return 2.55*i;t/=360,e/=100;const n=(i/=100)<.5?i*(1+e):i+e-i*e,o=2*i-n;switch(r){case"r":return 255*Kn.hue2rgb(o,n,t+1/3);case"g":return 255*Kn.hue2rgb(o,n,t);case"b":return 255*Kn.hue2rgb(o,n,t-1/3)}},rgb2hsl:({r:t,g:e,b:i},r)=>{t/=255,e/=255,i/=255;const n=Math.max(t,e,i),o=Math.min(t,e,i),a=(n+o)/2;if("l"===r)return 100*a;if(n===o)return 0;const s=n-o;if("s"===r)return 100*(a>.5?s/(2-n-o):s/(n+o));switch(n){case t:return 60*((e-i)/s+(ee>i?Math.min(e,Math.max(i,t)):Math.min(i,Math.max(e,t)),round:t=>Math.round(1e10*t)/1e10},unit:{dec2hex:t=>{const e=Math.round(t).toString(16);return e.length>1?e:`0${e}`}}},to={};for(let Eu=0;Eu<=255;Eu++)to[Eu]=Qn.unit.dec2hex(Eu);const eo=0,io=1,ro=2;class no{constructor(){this.type=eo}get(){return this.type}set(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t}reset(){this.type=eo}is(t){return this.type===t}}const oo=new class{constructor(t,e){this.color=e,this.changed=!1,this.data=t,this.type=new no}set(t,e){return this.color=e,this.changed=!1,this.data=t,this.type.type=eo,this}_ensureHSL(){const t=this.data,{h:e,s:i,l:r}=t;void 0===e&&(t.h=Qn.channel.rgb2hsl(t,"h")),void 0===i&&(t.s=Qn.channel.rgb2hsl(t,"s")),void 0===r&&(t.l=Qn.channel.rgb2hsl(t,"l"))}_ensureRGB(){const t=this.data,{r:e,g:i,b:r}=t;void 0===e&&(t.r=Qn.channel.hsl2rgb(t,"r")),void 0===i&&(t.g=Qn.channel.hsl2rgb(t,"g")),void 0===r&&(t.b=Qn.channel.hsl2rgb(t,"b"))}get r(){const t=this.data,e=t.r;return this.type.is(ro)||void 0===e?(this._ensureHSL(),Qn.channel.hsl2rgb(t,"r")):e}get g(){const t=this.data,e=t.g;return this.type.is(ro)||void 0===e?(this._ensureHSL(),Qn.channel.hsl2rgb(t,"g")):e}get b(){const t=this.data,e=t.b;return this.type.is(ro)||void 0===e?(this._ensureHSL(),Qn.channel.hsl2rgb(t,"b")):e}get h(){const t=this.data,e=t.h;return this.type.is(io)||void 0===e?(this._ensureRGB(),Qn.channel.rgb2hsl(t,"h")):e}get s(){const t=this.data,e=t.s;return this.type.is(io)||void 0===e?(this._ensureRGB(),Qn.channel.rgb2hsl(t,"s")):e}get l(){const t=this.data,e=t.l;return this.type.is(io)||void 0===e?(this._ensureRGB(),Qn.channel.rgb2hsl(t,"l")):e}get a(){return this.data.a}set r(t){this.type.set(io),this.changed=!0,this.data.r=t}set g(t){this.type.set(io),this.changed=!0,this.data.g=t}set b(t){this.type.set(io),this.changed=!0,this.data.b=t}set h(t){this.type.set(ro),this.changed=!0,this.data.h=t}set s(t){this.type.set(ro),this.changed=!0,this.data.s=t}set l(t){this.type.set(ro),this.changed=!0,this.data.l=t}set a(t){this.changed=!0,this.data.a=t}}({r:0,g:0,b:0,a:0},"transparent"),ao={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:t=>{if(35!==t.charCodeAt(0))return;const e=t.match(ao.re);if(!e)return;const i=e[1],r=parseInt(i,16),n=i.length,o=n%4==0,a=n>4,s=a?1:17,l=a?8:4,h=o?0:-1,c=a?255:15;return oo.set({r:(r>>l*(h+3)&c)*s,g:(r>>l*(h+2)&c)*s,b:(r>>l*(h+1)&c)*s,a:o?(r&c)*s/255:1},t)},stringify:t=>{const{r:e,g:i,b:r,a:n}=t;return n<1?`#${to[Math.round(e)]}${to[Math.round(i)]}${to[Math.round(r)]}${to[Math.round(255*n)]}`:`#${to[Math.round(e)]}${to[Math.round(i)]}${to[Math.round(r)]}`}},so={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:t=>{const e=t.match(so.hueRe);if(e){const[,t,i]=e;switch(i){case"grad":return Qn.channel.clamp.h(.9*parseFloat(t));case"rad":return Qn.channel.clamp.h(180*parseFloat(t)/Math.PI);case"turn":return Qn.channel.clamp.h(360*parseFloat(t))}}return Qn.channel.clamp.h(parseFloat(t))},parse:t=>{const e=t.charCodeAt(0);if(104!==e&&72!==e)return;const i=t.match(so.re);if(!i)return;const[,r,n,o,a,s]=i;return oo.set({h:so._hue2deg(r),s:Qn.channel.clamp.s(parseFloat(n)),l:Qn.channel.clamp.l(parseFloat(o)),a:a?Qn.channel.clamp.a(s?parseFloat(a)/100:parseFloat(a)):1},t)},stringify:t=>{const{h:e,s:i,l:r,a:n}=t;return n<1?`hsla(${Qn.lang.round(e)}, ${Qn.lang.round(i)}%, ${Qn.lang.round(r)}%, ${n})`:`hsl(${Qn.lang.round(e)}, ${Qn.lang.round(i)}%, ${Qn.lang.round(r)}%)`}},lo={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:t=>{t=t.toLowerCase();const e=lo.colors[t];if(e)return ao.parse(e)},stringify:t=>{const e=ao.stringify(t);for(const i in lo.colors)if(lo.colors[i]===e)return i}},ho={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:t=>{const e=t.charCodeAt(0);if(114!==e&&82!==e)return;const i=t.match(ho.re);if(!i)return;const[,r,n,o,a,s,l,h,c]=i;return oo.set({r:Qn.channel.clamp.r(n?2.55*parseFloat(r):parseFloat(r)),g:Qn.channel.clamp.g(a?2.55*parseFloat(o):parseFloat(o)),b:Qn.channel.clamp.b(l?2.55*parseFloat(s):parseFloat(s)),a:h?Qn.channel.clamp.a(c?parseFloat(h)/100:parseFloat(h)):1},t)},stringify:t=>{const{r:e,g:i,b:r,a:n}=t;return n<1?`rgba(${Qn.lang.round(e)}, ${Qn.lang.round(i)}, ${Qn.lang.round(r)}, ${Qn.lang.round(n)})`:`rgb(${Qn.lang.round(e)}, ${Qn.lang.round(i)}, ${Qn.lang.round(r)})`}},co={format:{keyword:lo,hex:ao,rgb:ho,rgba:ho,hsl:so,hsla:so},parse:t=>{if("string"!=typeof t)return t;const e=ao.parse(t)||ho.parse(t)||so.parse(t)||lo.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},stringify:t=>!t.changed&&t.color?t.color:t.type.is(ro)||void 0===t.data.r?so.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?ho.stringify(t):ao.stringify(t)},uo=(t,e)=>{const i=co.parse(t);for(const r in e)i[r]=Qn.channel.clamp[r](e[r]);return co.stringify(i)},fo=(t,e,i=0,r=1)=>{if("number"!=typeof t)return uo(t,{a:e});const n=oo.set({r:Qn.channel.clamp.r(t),g:Qn.channel.clamp.g(e),b:Qn.channel.clamp.b(i),a:Qn.channel.clamp.a(r)});return co.stringify(n)},po=t=>(t=>{const{r:e,g:i,b:r}=co.parse(t),n=.2126*Qn.channel.toLinear(e)+.7152*Qn.channel.toLinear(i)+.0722*Qn.channel.toLinear(r);return Qn.lang.round(n)})(t)>=.5,go=t=>!po(t),mo=(t,e,i)=>{const r=co.parse(t),n=r[e],o=Qn.channel.clamp[e](n+i);return n!==o&&(r[e]=o),co.stringify(r)},yo=(t,e)=>mo(t,"l",e),_o=(t,e)=>mo(t,"l",-e),bo=(t,e)=>{const i=co.parse(t),r={};for(const n in e)e[n]&&(r[n]=i[n]+e[n]);return uo(t,r)},Co=(t,e=100)=>{const i=co.parse(t);return i.r=255-i.r,i.g=255-i.g,i.b=255-i.b,((t,e,i=50)=>{const{r:r,g:n,b:o,a:a}=co.parse(t),{r:s,g:l,b:h,a:c}=co.parse(e),u=i/100,d=2*u-1,f=a-c,p=((d*f==-1?d:(d+f)/(1+d*f))+1)/2,g=1-p;return fo(r*p+s*g,n*p+l*g,o*p+h*g,a*u+c*(1-u))})(i,t,e)};var xo="object"==typeof global&&global&&global.Object===Object&&global,ko="object"==typeof self&&self&&self.Object===Object&&self,vo=xo||ko||Function("return this")(),To=vo.Symbol,So=Object.prototype,wo=So.hasOwnProperty,Bo=So.toString,Fo=To?To.toStringTag:void 0;var Lo=Object.prototype.toString;var Ao=To?To.toStringTag:void 0;function Eo(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":Ao&&Ao in Object(t)?function(t){var e=wo.call(t,Fo),i=t[Fo];try{t[Fo]=void 0;var r=!0}catch(o){}var n=Bo.call(t);return r&&(e?t[Fo]=i:delete t[Fo]),n}(t):function(t){return Lo.call(t)}(t)}function Mo(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function Oo(t){if(!Mo(t))return!1;var e=Eo(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}var Io,qo=vo["__core-js_shared__"],No=(Io=/[^.]+$/.exec(qo&&qo.keys&&qo.keys.IE_PROTO||""))?"Symbol(src)_1."+Io:"";var Do=Function.prototype.toString;function zo(t){if(null!=t){try{return Do.call(t)}catch(e){}try{return t+""}catch(e){}}return""}var $o=/^\[object .+?Constructor\]$/,jo=Function.prototype,Ro=Object.prototype,Po=jo.toString,Wo=Ro.hasOwnProperty,Ho=RegExp("^"+Po.call(Wo).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function Uo(t){return!(!Mo(t)||function(t){return!!No&&No in t}(t))&&(Oo(t)?Ho:$o).test(zo(t))}function Yo(t,e){var i=function(t,e){return null==t?void 0:t[e]}(t,e);return Uo(i)?i:void 0}var Vo=Yo(Object,"create");var Go=Object.prototype.hasOwnProperty;var Xo=Object.prototype.hasOwnProperty;function Zo(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e-1},ta.prototype.set=function(t,e){var i=this.__data__,r=Ko(i,t);return r<0?(++this.size,i.push([t,e])):i[r][1]=e,this};var ea=Yo(vo,"Map");function ia(t,e){var i,r,n=t.__data__;return("string"==(r=typeof(i=e))||"number"==r||"symbol"==r||"boolean"==r?"__proto__"!==i:null===i)?n["string"==typeof e?"string":"hash"]:n.map}function ra(t){var e=-1,i=null==t?0:t.length;for(this.clear();++e2||wa(ba)>3?"":" "}function La(t,e){for(;--e&&ka()&&!(ba<48||ba>102||ba>57&&ba<65||ba>70&&ba<97););return Sa(t,Ta()+(e<6&&32==va()&&32==ka()))}function Aa(t){for(;ka();)switch(ba){case t:return _a;case 34:case 39:34!==t&&39!==t&&Aa(ba);break;case 40:41===t&&Aa(t);break;case 92:ka()}return _a}function Ea(t,e){for(;ka()&&t+ba!==57&&(t+ba!==84||47!==va()););return"/*"+Sa(e,_a-1)+"*"+aa(47===t?t:ka())}function Ma(t){for(;!wa(va());)ka();return Sa(t,_a)}function Oa(t){return function(t){return Ca="",t}(Ia("",null,null,null,[""],t=function(t){return ga=ma=1,ya=da(Ca=t),_a=0,[]}(t),0,[0],t))}function Ia(t,e,i,r,n,o,a,s,l){for(var h=0,c=0,u=a,d=0,f=0,p=0,g=1,m=1,y=1,_=0,b="",C=n,x=o,k=r,v=b;m;)switch(p=_,_=ka()){case 40:if(108!=p&&58==ca(v,u-1)){-1!=ha(v+=la(Ba(_),"&","&\f"),"&\f")&&(y=-1);break}case 34:case 39:case 91:v+=Ba(_);break;case 9:case 10:case 13:case 32:v+=Fa(p);break;case 92:v+=La(Ta()-1,7);continue;case 47:switch(va()){case 42:case 47:pa(Na(Ea(ka(),Ta()),e,i),l);break;default:v+="/"}break;case 123*g:s[h++]=da(v)*y;case 125*g:case 59:case 0:switch(_){case 0:case 125:m=0;case 59+c:-1==y&&(v=la(v,/\f/g,"")),f>0&&da(v)-u&&pa(f>32?Da(v+";",r,i,u-1):Da(la(v," ","")+";",r,i,u-2),l);break;case 59:v+=";";default:if(pa(k=qa(v,e,i,h,c,n,s,b,C=[],x=[],u),o),123===_)if(0===c)Ia(v,e,k,k,C,o,u,s,x);else switch(99===d&&110===ca(v,3)?100:d){case 100:case 108:case 109:case 115:Ia(t,k,k,r&&pa(qa(t,k,k,0,0,n,s,b,n,C=[],u),x),n,x,u,s,r?C:x);break;default:Ia(v,k,k,k,[""],x,0,s,x)}}h=c=f=0,g=y=1,b=v="",u=a;break;case 58:u=1+da(v),f=p;default:if(g<1)if(123==_)--g;else if(125==_&&0==g++&&125==(ba=_a>0?ca(Ca,--_a):0,ma--,10===ba&&(ma=1,ga--),ba))continue;switch(v+=aa(_),_*g){case 38:y=c>0?1:(v+="\f",-1);break;case 44:s[h++]=(da(v)-1)*y,y=1;break;case 64:45===va()&&(v+=Ba(ka())),d=va(),c=u=da(b=v+=Ma(Ta())),_++;break;case 45:45===p&&2==da(v)&&(g=0)}}return o}function qa(t,e,i,r,n,o,a,s,l,h,c){for(var u=n-1,d=0===n?o:[""],f=fa(d),p=0,g=0,m=0;p0?d[y]+" "+_:la(_,/&\f/g,d[y])))&&(l[m++]=b);return xa(t,e,i,0===n?"rule":s,l,h,c)}function Na(t,e,i){return xa(t,e,i,"comm",aa(ba),ua(t,2,-2),0)}function Da(t,e,i,r){return xa(t,e,i,"decl",ua(t,0,r),ua(t,r+1,-1),r)}function za(t,e){for(var i="",r=fa(t),n=0;n-1&&t%1==0&&t<=9007199254740991}function us(t){return null!=t&&cs(t.length)&&!Oo(t)}var ds="object"==typeof exports&&exports&&!exports.nodeType&&exports,fs=ds&&"object"==typeof module&&module&&!module.nodeType&&module,ps=fs&&fs.exports===ds?vo.Buffer:void 0,gs=(ps?ps.isBuffer:void 0)||function(){return!1},ms={};function ys(t){return function(e){return t(e)}}ms["[object Float32Array]"]=ms["[object Float64Array]"]=ms["[object Int8Array]"]=ms["[object Int16Array]"]=ms["[object Int32Array]"]=ms["[object Uint8Array]"]=ms["[object Uint8ClampedArray]"]=ms["[object Uint16Array]"]=ms["[object Uint32Array]"]=!0,ms["[object Arguments]"]=ms["[object Array]"]=ms["[object ArrayBuffer]"]=ms["[object Boolean]"]=ms["[object DataView]"]=ms["[object Date]"]=ms["[object Error]"]=ms["[object Function]"]=ms["[object Map]"]=ms["[object Number]"]=ms["[object Object]"]=ms["[object RegExp]"]=ms["[object Set]"]=ms["[object String]"]=ms["[object WeakMap]"]=!1;var _s="object"==typeof exports&&exports&&!exports.nodeType&&exports,bs=_s&&"object"==typeof module&&module&&!module.nodeType&&module,Cs=bs&&bs.exports===_s&&xo.process,xs=function(){try{var t=bs&&bs.require&&bs.require("util").types;return t||Cs&&Cs.binding&&Cs.binding("util")}catch(e){}}(),ks=xs&&xs.isTypedArray,vs=ks?ys(ks):function(t){return rs(t)&&cs(t.length)&&!!ms[Eo(t)]},Ts=Object.prototype.hasOwnProperty;function Ss(t){if(null==t)return!0;if(us(t)&&(hs(t)||"string"==typeof t||"function"==typeof t.splice||gs(t)||vs(t)||ls(t)))return!t.length;var e=is(t);if("[object Map]"==e||"[object Set]"==e)return!t.size;if(Ra(t))return!Ua(t).length;for(var i in t)if(Ts.call(t,i))return!1;return!0}const ws={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},Bs={trace:(...t)=>{},debug:(...t)=>{},info:(...t)=>{},warn:(...t)=>{},error:(...t)=>{},fatal:(...t)=>{}},Fs=function(t="fatal"){let e=ws.fatal;"string"==typeof t?(t=t.toLowerCase())in ws&&(e=ws[t]):"number"==typeof t&&(e=t),Bs.trace=()=>{},Bs.debug=()=>{},Bs.info=()=>{},Bs.warn=()=>{},Bs.error=()=>{},Bs.fatal=()=>{},e<=ws.fatal&&(Bs.fatal=console.error?console.error.bind(console,Ls("FATAL"),"color: orange"):console.log.bind(console,"",Ls("FATAL"))),e<=ws.error&&(Bs.error=console.error?console.error.bind(console,Ls("ERROR"),"color: orange"):console.log.bind(console,"",Ls("ERROR"))),e<=ws.warn&&(Bs.warn=console.warn?console.warn.bind(console,Ls("WARN"),"color: orange"):console.log.bind(console,"",Ls("WARN"))),e<=ws.info&&(Bs.info=console.info?console.info.bind(console,Ls("INFO"),"color: lightblue"):console.log.bind(console,"",Ls("INFO"))),e<=ws.debug&&(Bs.debug=console.debug?console.debug.bind(console,Ls("DEBUG"),"color: lightgreen"):console.log.bind(console,"",Ls("DEBUG"))),e<=ws.trace&&(Bs.trace=console.debug?console.debug.bind(console,Ls("TRACE"),"color: lightgreen"):console.log.bind(console,"",Ls("TRACE")))},Ls=t=>`%c${F().format("ss.SSS")} : ${t} : `,As=//gi,Es=t=>Jn.sanitize(t),Ms=(t,e)=>{var i;if(!1!==(null==(i=e.flowchart)?void 0:i.htmlLabels)){const i=e.securityLevel;"antiscript"===i||"strict"===i?t=Es(t):"loose"!==i&&(t=(t=(t=qs(t)).replace(//g,">")).replace(/=/g,"="),t=Is(t))}return t},Os=(t,e)=>t?t=e.dompurifyConfig?Jn.sanitize(Ms(t,e),e.dompurifyConfig).toString():Jn.sanitize(Ms(t,e),{FORBID_TAGS:["style"]}).toString():t,Is=t=>t.replace(/#br#/g,"
    "),qs=t=>t.replace(As,"#br#"),Ns=t=>!1!==t&&!["false","null","0"].includes(String(t).trim().toLowerCase()),Ds=function(t){let e=t;if(t.split("~").length-1>=2){let t=e;do{e=t,t=e.replace(/~([^\s,:;]+)~/,"<$1>")}while(t!=e);return Ds(t)}return e},zs={getRows:t=>{if(!t)return[""];return qs(t).replace(/\\n/g,"#br#").split("#br#")},sanitizeText:Os,sanitizeTextOrArray:(t,e)=>"string"==typeof t?Os(t,e):t.flat().map((t=>Os(t,e))),hasBreaks:t=>As.test(t),splitBreaks:t=>t.split(As),lineBreakRegex:As,removeScript:Es,getUrl:t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=e.replaceAll(/\(/g,"\\("),e=e.replaceAll(/\)/g,"\\)")),e},evaluate:Ns,getMax:function(...t){const e=t.filter((t=>!isNaN(t)));return Math.max(...e)},getMin:function(...t){const e=t.filter((t=>!isNaN(t)));return Math.min(...e)}},$s=(t,e)=>bo(t,e?{s:-40,l:10}:{s:-40,l:-10});const js=t=>{const e=new class{constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=bo(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=bo(this.primaryColor,{h:-160}),this.primaryBorderColor=$s(this.primaryColor,this.darkMode),this.secondaryBorderColor=$s(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=$s(this.tertiaryColor,this.darkMode),this.primaryTextColor=Co(this.primaryColor),this.secondaryTextColor=Co(this.secondaryColor),this.tertiaryTextColor=Co(this.tertiaryColor),this.lineColor=Co(this.background),this.textColor=Co(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=fo(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(){this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||bo(this.primaryColor,{h:30}),this.cScale4=this.cScale4||bo(this.primaryColor,{h:60}),this.cScale5=this.cScale5||bo(this.primaryColor,{h:90}),this.cScale6=this.cScale6||bo(this.primaryColor,{h:120}),this.cScale7=this.cScale7||bo(this.primaryColor,{h:150}),this.cScale8=this.cScale8||bo(this.primaryColor,{h:210}),this.cScale9=this.cScale9||bo(this.primaryColor,{h:270}),this.cScale10=this.cScale10||bo(this.primaryColor,{h:300}),this.cScale11=this.cScale11||bo(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||_o(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||_o(this.tertiaryColor,40);for(let t=0;t{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};return e.calculate(t),e};class Rs{constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=yo(this.contrast,55),this.background="#ffffff",this.tertiaryColor=bo(this.primaryColor,{h:-160}),this.primaryBorderColor=$s(this.primaryColor,this.darkMode),this.secondaryBorderColor=$s(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=$s(this.tertiaryColor,this.darkMode),this.primaryTextColor=Co(this.primaryColor),this.secondaryTextColor=Co(this.secondaryColor),this.tertiaryTextColor=Co(this.tertiaryColor),this.lineColor=Co(this.background),this.textColor=Co(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(){this.secondBkg=yo(this.contrast,55),this.border2=this.contrast,this.actorBorder=yo(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 t=0;t{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}}const Ps={base:{getThemeVariables:t=>{const e=new 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(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||bo(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||bo(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||$s(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||$s(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||$s(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||$s(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||Co(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||Co(this.tertiaryColor),this.lineColor=this.lineColor||Co(this.background),this.arrowheadColor=this.arrowheadColor||Co(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||Co(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||yo(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||bo(this.primaryColor,{h:30}),this.cScale4=this.cScale4||bo(this.primaryColor,{h:60}),this.cScale5=this.cScale5||bo(this.primaryColor,{h:90}),this.cScale6=this.cScale6||bo(this.primaryColor,{h:120}),this.cScale7=this.cScale7||bo(this.primaryColor,{h:150}),this.cScale8=this.cScale8||bo(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||bo(this.primaryColor,{h:270}),this.cScale10=this.cScale10||bo(this.primaryColor,{h:300}),this.cScale11=this.cScale11||bo(this.primaryColor,{h:330}),this.darkMode)for(let e=0;e{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};return e.calculate(t),e}},dark:{getThemeVariables:t=>{const e=new class{constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=yo(this.primaryColor,16),this.tertiaryColor=bo(this.primaryColor,{h:-160}),this.primaryBorderColor=Co(this.background),this.secondaryBorderColor=$s(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=$s(this.tertiaryColor,this.darkMode),this.primaryTextColor=Co(this.primaryColor),this.secondaryTextColor=Co(this.secondaryColor),this.tertiaryTextColor=Co(this.tertiaryColor),this.lineColor=Co(this.background),this.textColor=Co(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=yo(Co("#323D47"),10),this.lineColor="calculated",this.border1="#81B1DB",this.border2=fo(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=fo(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=fo(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(){this.secondBkg=yo(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=yo(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=yo(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=bo(this.primaryColor,{h:64}),this.fillType3=bo(this.secondaryColor,{h:64}),this.fillType4=bo(this.primaryColor,{h:-64}),this.fillType5=bo(this.secondaryColor,{h:-64}),this.fillType6=bo(this.primaryColor,{h:128}),this.fillType7=bo(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||bo(this.primaryColor,{h:30}),this.cScale4=this.cScale4||bo(this.primaryColor,{h:60}),this.cScale5=this.cScale5||bo(this.primaryColor,{h:90}),this.cScale6=this.cScale6||bo(this.primaryColor,{h:120}),this.cScale7=this.cScale7||bo(this.primaryColor,{h:150}),this.cScale8=this.cScale8||bo(this.primaryColor,{h:210}),this.cScale9=this.cScale9||bo(this.primaryColor,{h:270}),this.cScale10=this.cScale10||bo(this.primaryColor,{h:300}),this.cScale11=this.cScale11||bo(this.primaryColor,{h:330});for(let t=0;t{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};return e.calculate(t),e}},default:{getThemeVariables:js},forest:{getThemeVariables:t=>{const e=new 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=yo("#cde498",10),this.primaryBorderColor=$s(this.primaryColor,this.darkMode),this.secondaryBorderColor=$s(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=$s(this.tertiaryColor,this.darkMode),this.primaryTextColor=Co(this.primaryColor),this.secondaryTextColor=Co(this.secondaryColor),this.tertiaryTextColor=Co(this.primaryColor),this.lineColor=Co(this.background),this.textColor=Co(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(){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||bo(this.primaryColor,{h:30}),this.cScale4=this.cScale4||bo(this.primaryColor,{h:60}),this.cScale5=this.cScale5||bo(this.primaryColor,{h:90}),this.cScale6=this.cScale6||bo(this.primaryColor,{h:120}),this.cScale7=this.cScale7||bo(this.primaryColor,{h:150}),this.cScale8=this.cScale8||bo(this.primaryColor,{h:210}),this.cScale9=this.cScale9||bo(this.primaryColor,{h:270}),this.cScale10=this.cScale10||bo(this.primaryColor,{h:300}),this.cScale11=this.cScale11||bo(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||_o(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||_o(this.tertiaryColor,40);for(let t=0;t{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}};return e.calculate(t),e}},neutral:{getThemeVariables:t=>{const e=new Rs;return e.calculate(t),e}}},Ws={theme:"default",themeVariables:Ps.default.getThemeVariables(),themeCSS:void 0,maxTextSize:5e4,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize"],deterministicIds:!1,deterministicIDSeed:void 0,flowchart:{titleTopMargin:25,diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,useMaxWidth:!0,defaultRenderer:"dagre-wrapper",wrappingWidth:200},sequence:{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,useMaxWidth:!0,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,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:{titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,displayMode:"",axisFormat:"%Y-%m-%d",tickInterval:void 0,useMaxWidth:!0,topAxis:!1,useWidth:void 0},journey:{diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,useMaxWidth:!0,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"]},timeline:{diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,useMaxWidth:!0,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},class:{titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,useMaxWidth:!0,defaultRenderer:"dagre-wrapper"},state:{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,useMaxWidth:!0,defaultRenderer:"dagre-wrapper"},er:{titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,stroke:"gray",fill:"honeydew",fontSize:12,useMaxWidth:!0},pie:{useWidth:void 0,useMaxWidth:!0,textPosition:.75},quadrantChart:{chartWidth:500,chartHeight:500,titlePadding:10,titleFontSize:20,quadrantPadding:5,quadrantTextTopPadding:5,quadrantLabelFontSize:16,quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2,xAxisLabelPadding:5,xAxisLabelFontSize:16,xAxisPosition:"top",yAxisLabelPadding:5,yAxisLabelFontSize:16,yAxisPosition:"left",pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,useMaxWidth:!0},requirement:{useWidth:void 0,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},gitGraph:{titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0},c4:{useWidth:void 0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,useMaxWidth:!0,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,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}},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"},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},fontSize:16};Ws.class&&(Ws.class.arrowMarkerAbsolute=Ws.arrowMarkerAbsolute),Ws.gitGraph&&(Ws.gitGraph.arrowMarkerAbsolute=Ws.arrowMarkerAbsolute);const Hs=(t,e="")=>Object.keys(t).reduce(((i,r)=>Array.isArray(t[r])?i:"object"==typeof t[r]&&null!==t[r]?[...i,e+r,...Hs(t[r],"")]:[...i,e+r]),[]),Us=Hs(Ws,""),Ys=Ws; /*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ -function Vs(t){return null==t}var Gs={isNothing:Vs,isObject:function(t){return"object"==typeof t&&null!==t},toArray:function(t){return Array.isArray(t)?t:Vs(t)?[]:[t]},repeat:function(t,e){var i,r="";for(i=0;is&&(e=r-s+(o=" ... ").length),i-r>s&&(i=r+s-(a=" ...").length),{str:o+t.slice(e,i).replace(/\t/g,"→")+a,pos:r-e+o.length}}function Qs(t,e){return Gs.repeat(" ",e-t.length)+t}var tl=function(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),"number"!=typeof e.indent&&(e.indent=1),"number"!=typeof e.linesBefore&&(e.linesBefore=3),"number"!=typeof e.linesAfter&&(e.linesAfter=2);for(var i,r=/\r?\n|\r|\0/g,n=[0],o=[],a=-1;i=r.exec(t.buffer);)o.push(i.index),n.push(i.index+i[0].length),t.position<=i.index&&a<0&&(a=n.length-2);a<0&&(a=n.length-1);var s,l,h="",c=Math.min(t.line+e.linesAfter,o.length).toString().length,u=e.maxLength-(e.indent+c+3);for(s=1;s<=e.linesBefore&&!(a-s<0);s++)l=Ks(t.buffer,n[a-s],o[a-s],t.position-(n[a]-n[a-s]),u),h=Gs.repeat(" ",e.indent)+Qs((t.line-s+1).toString(),c)+" | "+l.str+"\n"+h;for(l=Ks(t.buffer,n[a],o[a],t.position,u),h+=Gs.repeat(" ",e.indent)+Qs((t.line+1).toString(),c)+" | "+l.str+"\n",h+=Gs.repeat("-",e.indent+c+3+l.pos)+"^\n",s=1;s<=e.linesAfter&&!(a+s>=o.length);s++)l=Ks(t.buffer,n[a+s],o[a+s],t.position-(n[a]-n[a+s]),u),h+=Gs.repeat(" ",e.indent)+Qs((t.line+s+1).toString(),c)+" | "+l.str+"\n";return h.replace(/\n$/,"")},el=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],il=["scalar","sequence","mapping"];var rl=function(t,e){var i,r;if(e=e||{},Object.keys(e).forEach((function(e){if(-1===el.indexOf(e))throw new Js('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')})),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=(i=e.styleAliases||null,r={},null!==i&&Object.keys(i).forEach((function(t){i[t].forEach((function(e){r[String(e)]=t}))})),r),-1===il.indexOf(this.kind))throw new Js('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')};function nl(t,e){var i=[];return t[e].forEach((function(t){var e=i.length;i.forEach((function(i,r){i.tag===t.tag&&i.kind===t.kind&&i.multi===t.multi&&(e=r)})),i[e]=t})),i}function ol(t){return this.extend(t)}ol.prototype.extend=function(t){var e=[],i=[];if(t instanceof rl)i.push(t);else if(Array.isArray(t))i=i.concat(t);else{if(!t||!Array.isArray(t.implicit)&&!Array.isArray(t.explicit))throw new Js("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");t.implicit&&(e=e.concat(t.implicit)),t.explicit&&(i=i.concat(t.explicit))}e.forEach((function(t){if(!(t instanceof rl))throw new Js("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(t.loadKind&&"scalar"!==t.loadKind)throw new Js("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(t.multi)throw new Js("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")})),i.forEach((function(t){if(!(t instanceof rl))throw new Js("Specified list of YAML types (or a single Type object) contains a non-Type object.")}));var r=Object.create(ol.prototype);return r.implicit=(this.implicit||[]).concat(e),r.explicit=(this.explicit||[]).concat(i),r.compiledImplicit=nl(r,"implicit"),r.compiledExplicit=nl(r,"explicit"),r.compiledTypeMap=function(){var t,e,i={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function r(t){t.multi?(i.multi[t.kind].push(t),i.multi.fallback.push(t)):i[t.kind][t.tag]=i.fallback[t.tag]=t}for(t=0,e=arguments.length;t=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},octal:function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),dl=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");var fl=/^[-+]?[0-9]+e/;var pl=new rl("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(t){return null!==t&&!(!dl.test(t)||"_"===t[t.length-1])},construct:function(t){var e,i;return i="-"===(e=t.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(e[0])>=0&&(e=e.slice(1)),".inf"===e?1===i?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:i*parseFloat(e,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&(t%1!=0||Gs.isNegativeZero(t))},represent:function(t,e){var i;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(Gs.isNegativeZero(t))return"-0.0";return i=t.toString(10),fl.test(i)?i.replace("e",".e"):i},defaultStyle:"lowercase"}),gl=al.extend({implicit:[sl,ll,ul,pl]}),ml=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),yl=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");var _l=new rl("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:function(t){return null!==t&&(null!==ml.exec(t)||null!==yl.exec(t))},construct:function(t){var e,i,r,n,o,a,s,l,h=0,c=null;if(null===(e=ml.exec(t))&&(e=yl.exec(t)),null===e)throw new Error("Date resolve error");if(i=+e[1],r=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(i,r,n));if(o=+e[4],a=+e[5],s=+e[6],e[7]){for(h=e[7].slice(0,3);h.length<3;)h+="0";h=+h}return e[9]&&(c=6e4*(60*+e[10]+ +(e[11]||0)),"-"===e[9]&&(c=-c)),l=new Date(Date.UTC(i,r,n,o,a,s,h)),c&&l.setTime(l.getTime()-c),l},instanceOf:Date,represent:function(t){return t.toISOString()}});var bl=new rl("tag:yaml.org,2002:merge",{kind:"scalar",resolve:function(t){return"<<"===t||null===t}}),Cl="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";var xl=new rl("tag:yaml.org,2002:binary",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,i,r=0,n=t.length,o=Cl;for(i=0;i64)){if(e<0)return!1;r+=6}return r%8==0},construct:function(t){var e,i,r=t.replace(/[\r\n=]/g,""),n=r.length,o=Cl,a=0,s=[];for(e=0;e>16&255),s.push(a>>8&255),s.push(255&a)),a=a<<6|o.indexOf(r.charAt(e));return 0===(i=n%4*6)?(s.push(a>>16&255),s.push(a>>8&255),s.push(255&a)):18===i?(s.push(a>>10&255),s.push(a>>2&255)):12===i&&s.push(a>>4&255),new Uint8Array(s)},predicate:function(t){return"[object Uint8Array]"===Object.prototype.toString.call(t)},represent:function(t){var e,i,r="",n=0,o=t.length,a=Cl;for(e=0;e>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]),n=(n<<8)+t[e];return 0===(i=o%3)?(r+=a[n>>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]):2===i?(r+=a[n>>10&63],r+=a[n>>4&63],r+=a[n<<2&63],r+=a[64]):1===i&&(r+=a[n>>2&63],r+=a[n<<4&63],r+=a[64],r+=a[64]),r}}),kl=Object.prototype.hasOwnProperty,vl=Object.prototype.toString;var Tl=new rl("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,i,r,n,o,a=[],s=t;for(e=0,i=s.length;e>10),56320+(t-65536&1023))}for(var Hl=new Array(256),Ul=new Array(256),Yl=0;Yl<256;Yl++)Hl[Yl]=Pl(Yl)?1:0,Ul[Yl]=Pl(Yl);function Vl(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||Ll,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function Gl(t,e){var i={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return i.snippet=tl(i),new Js(e,i)}function Xl(t,e){throw Gl(t,e)}function Zl(t,e){t.onWarning&&t.onWarning.call(null,Gl(t,e))}var Jl={YAML:function(t,e,i){var r,n,o;null!==t.version&&Xl(t,"duplication of %YAML directive"),1!==i.length&&Xl(t,"YAML directive accepts exactly one argument"),null===(r=/^([0-9]+)\.([0-9]+)$/.exec(i[0]))&&Xl(t,"ill-formed argument of the YAML directive"),n=parseInt(r[1],10),o=parseInt(r[2],10),1!==n&&Xl(t,"unacceptable YAML version of the document"),t.version=i[0],t.checkLineBreaks=o<2,1!==o&&2!==o&&Zl(t,"unsupported YAML version of the document")},TAG:function(t,e,i){var r,n;2!==i.length&&Xl(t,"TAG directive accepts exactly two arguments"),r=i[0],n=i[1],Il.test(r)||Xl(t,"ill-formed tag handle (first argument) of the TAG directive"),Al.call(t.tagMap,r)&&Xl(t,'there is a previously declared suffix for "'+r+'" tag handle'),ql.test(n)||Xl(t,"ill-formed tag prefix (second argument) of the TAG directive");try{n=decodeURIComponent(n)}catch(o){Xl(t,"tag prefix is malformed: "+n)}t.tagMap[r]=n}};function Kl(t,e,i,r){var n,o,a,s;if(e1&&(t.result+=Gs.repeat("\n",e-1))}function oh(t,e){var i,r,n=t.tag,o=t.anchor,a=[],s=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=a),r=t.input.charCodeAt(t.position);0!==r&&(-1!==t.firstTabInLine&&(t.position=t.firstTabInLine,Xl(t,"tab characters must not be used in indentation")),45===r)&&$l(t.input.charCodeAt(t.position+1));)if(s=!0,t.position++,ih(t,!0,-1)&&t.lineIndent<=e)a.push(null),r=t.input.charCodeAt(t.position);else if(i=t.line,lh(t,e,3,!1,!0),a.push(t.result),ih(t,!0,-1),r=t.input.charCodeAt(t.position),(t.line===i||t.lineIndent>e)&&0!==r)Xl(t,"bad indentation of a sequence entry");else if(t.lineIndente?p=1:t.lineIndent===e?p=0:t.lineIndente?p=1:t.lineIndent===e?p=0:t.lineIndente)&&(y&&(a=t.line,s=t.lineStart,l=t.position),lh(t,e,4,!0,n)&&(y?g=t.result:m=t.result),y||(th(t,d,f,p,g,m,a,s,l),p=g=m=null),ih(t,!0,-1),h=t.input.charCodeAt(t.position)),(t.line===o||t.lineIndent>e)&&0!==h)Xl(t,"bad indentation of a mapping entry");else if(t.lineIndent=0))break;0===n?Xl(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):h?Xl(t,"repeat of an indentation width identifier"):(c=e+n-1,h=!0)}if(zl(o)){do{o=t.input.charCodeAt(++t.position)}while(zl(o));if(35===o)do{o=t.input.charCodeAt(++t.position)}while(!Dl(o)&&0!==o)}for(;0!==o;){for(eh(t),t.lineIndent=0,o=t.input.charCodeAt(t.position);(!h||t.lineIndentc&&(c=t.lineIndent),Dl(o))u++;else{if(t.lineIndent0){for(n=a,o=0;n>0;n--)(a=Rl(s=t.input.charCodeAt(++t.position)))>=0?o=(o<<4)+a:Xl(t,"expected hexadecimal character");t.result+=Wl(o),t.position++}else Xl(t,"unknown escape sequence");i=r=t.position}else Dl(s)?(Kl(t,i,r,!0),nh(t,ih(t,!1,e)),i=r=t.position):t.position===t.lineStart&&rh(t)?Xl(t,"unexpected end of the document within a double quoted scalar"):(t.position++,r=t.position)}Xl(t,"unexpected end of the stream within a double quoted scalar")}(t,d)?m=!0:!function(t){var e,i,r;if(42!==(r=t.input.charCodeAt(t.position)))return!1;for(r=t.input.charCodeAt(++t.position),e=t.position;0!==r&&!$l(r)&&!jl(r);)r=t.input.charCodeAt(++t.position);return t.position===e&&Xl(t,"name of an alias node must contain at least one character"),i=t.input.slice(e,t.position),Al.call(t.anchorMap,i)||Xl(t,'unidentified alias "'+i+'"'),t.result=t.anchorMap[i],ih(t,!0,-1),!0}(t)?function(t,e,i){var r,n,o,a,s,l,h,c,u=t.kind,d=t.result;if($l(c=t.input.charCodeAt(t.position))||jl(c)||35===c||38===c||42===c||33===c||124===c||62===c||39===c||34===c||37===c||64===c||96===c)return!1;if((63===c||45===c)&&($l(r=t.input.charCodeAt(t.position+1))||i&&jl(r)))return!1;for(t.kind="scalar",t.result="",n=o=t.position,a=!1;0!==c;){if(58===c){if($l(r=t.input.charCodeAt(t.position+1))||i&&jl(r))break}else if(35===c){if($l(t.input.charCodeAt(t.position-1)))break}else{if(t.position===t.lineStart&&rh(t)||i&&jl(c))break;if(Dl(c)){if(s=t.line,l=t.lineStart,h=t.lineIndent,ih(t,!1,-1),t.lineIndent>=e){a=!0,c=t.input.charCodeAt(t.position);continue}t.position=o,t.line=s,t.lineStart=l,t.lineIndent=h;break}}a&&(Kl(t,n,o,!1),nh(t,t.line-s),n=o=t.position,a=!1),zl(c)||(o=t.position+1),c=t.input.charCodeAt(++t.position)}return Kl(t,n,o,!1),!!t.result||(t.kind=u,t.result=d,!1)}(t,d,1===i)&&(m=!0,null===t.tag&&(t.tag="?")):(m=!0,null===t.tag&&null===t.anchor||Xl(t,"alias node should not have any properties")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===p&&(m=s&&oh(t,f))),null===t.tag)null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);else if("?"===t.tag){for(null!==t.result&&"scalar"!==t.kind&&Xl(t,'unacceptable node kind for ! tag; it should be "scalar", not "'+t.kind+'"'),l=0,h=t.implicitTypes.length;l"),null!==t.result&&u.kind!==t.kind&&Xl(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+u.kind+'", not "'+t.kind+'"'),u.resolve(t.result,t.tag)?(t.result=u.construct(t.result,t.tag),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):Xl(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return null!==t.listener&&t.listener("close",t),null!==t.tag||null!==t.anchor||m}function hh(t){var e,i,r,n,o=t.position,a=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);0!==(n=t.input.charCodeAt(t.position))&&(ih(t,!0,-1),n=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==n));){for(a=!0,n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!$l(n);)n=t.input.charCodeAt(++t.position);for(r=[],(i=t.input.slice(e,t.position)).length<1&&Xl(t,"directive name must not be less than one character in length");0!==n;){for(;zl(n);)n=t.input.charCodeAt(++t.position);if(35===n){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&!Dl(n));break}if(Dl(n))break;for(e=t.position;0!==n&&!$l(n);)n=t.input.charCodeAt(++t.position);r.push(t.input.slice(e,t.position))}0!==n&&eh(t),Al.call(Jl,i)?Jl[i](t,i,r):Zl(t,'unknown document directive "'+i+'"')}ih(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,ih(t,!0,-1)):a&&Xl(t,"directives end mark is expected"),lh(t,t.lineIndent-1,4,!1,!0),ih(t,!0,-1),t.checkLineBreaks&&Ml.test(t.input.slice(o,t.position))&&Zl(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&rh(t)?46===t.input.charCodeAt(t.position)&&(t.position+=3,ih(t,!0,-1)):t.positionph(t,e,i))),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach((e=>{t.includes(e)||t.push(e)})),t):void 0===t||r<=0?null!=t&&"object"==typeof t&&"object"==typeof e?Object.assign(t,e):e:(void 0!==e&&"object"==typeof t&&"object"==typeof e&&Object.keys(e).forEach((i=>{"object"!=typeof e[i]||void 0!==t[i]&&"object"!=typeof t[i]?(n||"object"!=typeof t[i]&&"object"!=typeof e[i])&&(t[i]=e[i]):(void 0===t[i]&&(t[i]=Array.isArray(e[i])?[]:{}),t[i]=ph(t[i],e[i],{depth:r-1,clobber:n}))})),t)},gh=ph,mh=Object.freeze(Ys);let yh,_h=gh({},mh),bh=[],Ch=gh({},mh);const xh=(t,e)=>{let i=gh({},t),r={};for(const n of e)Sh(n),r=gh(r,n);if(i=gh(i,r),r.theme&&r.theme in Ps){const t=gh({},yh),e=gh(t.themeVariables||{},r.themeVariables);i.theme&&i.theme in Ps&&(i.themeVariables=Ps[i.theme].getThemeVariables(e))}return Ch=i,Ah(Ch),Ch},kh=()=>gh({},_h),vh=t=>(Ah(t),gh(Ch,t),Th()),Th=()=>gh({},Ch),Sh=t=>{var e;["secure",...null!=(e=_h.secure)?e:[]].forEach((e=>{void 0!==t[e]&&(Bs.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])})),Object.keys(t).forEach((e=>{0===e.indexOf("__")&&delete t[e]})),Object.keys(t).forEach((e=>{"string"==typeof t[e]&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],"object"==typeof t[e]&&Sh(t[e])}))},wh=t=>{t.fontFamily&&(t.themeVariables&&t.themeVariables.fontFamily||(t.themeVariables={fontFamily:t.fontFamily})),bh.push(t),xh(_h,bh)},Bh=(t=_h)=>{bh=[],xh(t,bh)};var Fh=(t=>(t.LAZY_LOAD_DEPRECATED="The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead.",t))(Fh||{});const Lh={},Ah=t=>{var e;t&&((t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&(Lh[e="LAZY_LOAD_DEPRECATED"]||(Bs.warn(Fh[e]),Lh[e]=!0)))},Eh=function(t,e,i,r){!function(t,e){for(let i of e)t.attr(i[0],i[1])}(t,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}(e,i,r))},Mh=function(t,e,i,r){const n=e.node().getBBox(),o=n.width,a=n.height;Bs.info(`SVG bounds: ${o}x${a}`,n);let s=0,l=0;Bs.info(`Graph bounds: ${s}x${l}`,t),s=o+2*i,l=a+2*i,Bs.info(`Calculated bounds: ${s}x${l}`),Eh(e,l,s,r);const h=`${n.x-i} ${n.y-i} ${n.width+2*i} ${n.height+2*i}`;e.attr("viewBox",h)},Oh={},Ih=(t,e,i)=>{let r="";return t in Oh&&Oh[t]?r=Oh[t](i):Bs.warn(`No theme found for ${t}`),` & {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n fill: ${i.textColor}\n }\n\n /* Classes common for multiple diagrams */\n\n & .error-icon {\n fill: ${i.errorBkgColor};\n }\n & .error-text {\n fill: ${i.errorTextColor};\n stroke: ${i.errorTextColor};\n }\n\n & .edge-thickness-normal {\n stroke-width: 2px;\n }\n & .edge-thickness-thick {\n stroke-width: 3.5px\n }\n & .edge-pattern-solid {\n stroke-dasharray: 0;\n }\n\n & .edge-pattern-dashed{\n stroke-dasharray: 3;\n }\n .edge-pattern-dotted {\n stroke-dasharray: 2;\n }\n\n & .marker {\n fill: ${i.lineColor};\n stroke: ${i.lineColor};\n }\n & .marker.cross {\n stroke: ${i.lineColor};\n }\n\n & svg {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n }\n\n ${r}\n\n ${e}\n`};let qh="",Nh="",Dh="";const zh=t=>Os(t,Th()),$h=function(){qh="",Dh="",Nh=""},jh=function(t){qh=zh(t).replace(/^\s+/g,"")},Rh=function(){return qh||Nh},Ph=function(t){Dh=zh(t).replace(/\n\s+/g,"\n")},Wh=function(){return Dh},Hh=function(t){Nh=zh(t)},Uh=function(){return Nh},Yh={getAccTitle:Rh,setAccTitle:jh,getDiagramTitle:Uh,setDiagramTitle:Hh,getAccDescription:Wh,setAccDescription:Ph,clear:$h},Vh=Object.freeze(Object.defineProperty({__proto__:null,clear:$h,default:Yh,getAccDescription:Wh,getAccTitle:Rh,getDiagramTitle:Uh,setAccDescription:Ph,setAccTitle:jh,setDiagramTitle:Hh},Symbol.toStringTag,{value:"Module"}));let Gh={};const Xh=function(t,e,i,r){Bs.debug("parseDirective is being called",e,i,r);try{if(void 0!==e)switch(e=e.trim(),i){case"open_directive":Gh={};break;case"type_directive":if(!Gh)throw new Error("currentDirective is undefined");Gh.type=e.toLowerCase();break;case"arg_directive":if(!Gh)throw new Error("currentDirective is undefined");Gh.args=JSON.parse(e);break;case"close_directive":Zh(t,Gh,r),Gh=void 0}}catch(n){Bs.error(`Error while rendering sequenceDiagram directive: ${e} jison context: ${i}`),Bs.error(n.message)}},Zh=function(t,e,i){switch(Bs.info(`Directive type=${e.type} with args:`,e.args),e.type){case"init":case"initialize":["config"].forEach((t=>{void 0!==e.args[t]&&("flowchart-v2"===i&&(i="flowchart"),e.args[i]=e.args[t],delete e.args[t])})),Bs.info("sanitize in handleDirective",e.args),Ac(e.args),Bs.info("sanitize in handleDirective (done)",e.args),wh(e.args);break;case"wrap":case"nowrap":t&&t.setWrap&&t.setWrap("wrap"===e.type);break;case"themeCss":Bs.warn("themeCss encountered");break;default:Bs.warn(`Unhandled directive: source: '%%{${e.type}: ${JSON.stringify(e.args?e.args:{})}}%%`,e)}},Jh=Bs,Kh=Fs,Qh=Th,tc=t=>Os(t,Qh()),ec=Mh,ic=(t,e,i,r)=>Xh(t,e,i,r),rc={},nc=(t,e,i)=>{if(rc[t])throw new Error(`Diagram ${t} already registered.`);var r,n;rc[t]=e,i&&dc(t,i),r=t,n=e.styles,Oh[r]=n,e.injectUtils&&e.injectUtils(Jh,Kh,Qh,tc,ec,Vh,ic)},oc=t=>{if(t in rc)return rc[t];throw new Error(`Diagram ${t} not found.`)};class ac extends Error{constructor(t){super(t),this.name="UnknownDiagramError"}}const sc=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,lc=/\s*%%.*\n/gm,hc={},cc=function(t,e){t=t.replace(fh,"").replace(sc,"").replace(lc,"\n");for(const[i,{detector:r}]of Object.entries(hc)){if(r(t,e))return i}throw new ac(`No diagram type detected matching given configuration for text: ${t}`)},uc=(...t)=>{for(const{id:e,detector:i,loader:r}of t)dc(e,i,r)},dc=(t,e,i)=>{hc[t]?Bs.error(`Detector with key ${t} already exists`):hc[t]={detector:e,loader:i},Bs.debug(`Detector with key ${t} added${i?" with loader":""}`)},fc={curveBasis:vi,curveBasisClosed:function(t){return new Ti(t)},curveBasisOpen:function(t){return new Si(t)},curveBumpX:function(t){return new bi(t,!0)},curveBumpY:function(t){return new bi(t,!1)},curveBundle:Bi,curveCardinalClosed:Mi,curveCardinalOpen:Ii,curveCardinal:Ai,curveCatmullRomClosed:$i,curveCatmullRomOpen:Ri,curveCatmullRom:Di,curveLinear:_i,curveLinearClosed:function(t){return new Pi(t)},curveMonotoneX:function(t){return new Vi(t)},curveMonotoneY:function(t){return new Gi(t)},curveNatural:function(t){return new Zi(t)},curveStep:function(t){return new Ki(t,.5)},curveStepAfter:function(t){return new Ki(t,1)},curveStepBefore:function(t){return new Ki(t,0)}},pc=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,gc=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,mc=function(t,e=null){try{const i=new RegExp(`[%]{2}(?![{]${gc.source})(?=[}][%]{2}).*\n`,"ig");let r;t=t.trim().replace(i,"").replace(/'/gm,'"'),Bs.debug(`Detecting diagram directive${null!==e?" type:"+e:""} based on the text:${t}`);const n=[];for(;null!==(r=pc.exec(t));)if(r.index===pc.lastIndex&&pc.lastIndex++,r&&!e||e&&r[1]&&r[1].match(e)||e&&r[2]&&r[2].match(e)){const t=r[1]?r[1]:r[2],e=r[3]?r[3].trim():r[4]?JSON.parse(r[4].trim()):null;n.push({type:t,args:e})}return 0===n.length&&n.push({type:t,args:null}),1===n.length?n[0]:n}catch(i){return Bs.error(`ERROR: ${i.message} - Unable to parse directive\n ${null!==e?" type:"+e:""} based on the text:${t}`),{type:null,args:null}}};function yc(t,e){if(!t)return e;const i=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return fc[i]||e}function _c(t,e){return t&&e?Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)):0}function bc(t){let e="",i="";for(const r of t)void 0!==r&&(r.startsWith("color:")||r.startsWith("text-align:")?i=i+r+";":e=e+r+";");return{style:e,labelStyle:i}}let Cc=0;const xc=()=>(Cc++,"id-"+Math.random().toString(36).substr(2,12)+"-"+Cc);const kc=t=>function(t){let e="";const i="0123456789abcdef",r=i.length;for(let n=0;n{if(!t)return t;if(i=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"
    "},i),zs.lineBreakRegex.test(t))return t;const r=t.split(" "),n=[];let o="";return r.forEach(((t,a)=>{const s=Bc(`${t} `,i),l=Bc(o,i);if(s>e){const{hyphenatedStrings:r,remainingWord:a}=Sc(t,e,"-",i);n.push(o,...r),o=a}else l+s>=e?(n.push(o),o=t):o=[o,t].filter(Boolean).join(" ");a+1===r.length&&n.push(o)})),n.filter((t=>""!==t)).join(i.joinWith)}),((t,e,i)=>`${t}${e}${i.fontSize}${i.fontWeight}${i.fontFamily}${i.joinWith}`)),Sc=na(((t,e,i="-",r)=>{r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},r);const n=[...t],o=[];let a="";return n.forEach(((t,s)=>{const l=`${a}${t}`;if(Bc(l,r)>=e){const t=s+1,e=n.length===t,r=`${l}${i}`;o.push(e?l:r),a=""}else a=l})),{hyphenatedStrings:o,remainingWord:a}}),((t,e,i="-",r)=>`${t}${e}${i}${r.fontSize}${r.fontWeight}${r.fontFamily}`));function wc(t,e){return e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:15},e),Fc(t,e).height}function Bc(t,e){return e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial"},e),Fc(t,e).width}const Fc=na(((t,e)=>{e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial"},e);const{fontSize:i,fontFamily:r,fontWeight:n}=e;if(!t)return{width:0,height:0};const[,o]=Oc(i),a=["sans-serif",r],s=t.split(zs.lineBreakRegex),l=[],h=je("body");if(!h.remove)return{width:0,height:0,lineHeight:0};const c=h.append("svg");for(const u of a){let t=0;const e={width:0,height:0,lineHeight:0};for(const i of s){const r={x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0};r.text=i;const a=vc(c,r).style("font-size",o).style("font-weight",n).style("font-family",u),s=(a._groups||a)[0][0].getBBox();if(0===s.width&&0===s.height)throw new Error("svg element not in render tree");e.width=Math.round(Math.max(e.width,s.width)),t=Math.round(s.height),e.height+=t,e.lineHeight=Math.round(Math.max(e.lineHeight,t))}l.push(e)}c.remove();return l[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]}),((t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`));let Lc;const Ac=t=>{if(Bs.debug("directiveSanitizer called with",t),"object"==typeof t&&(t.length?t.forEach((t=>Ac(t))):Object.keys(t).forEach((e=>{Bs.debug("Checking key",e),e.startsWith("__")&&(Bs.debug("sanitize deleting __ option",e),delete t[e]),e.includes("proto")&&(Bs.debug("sanitize deleting proto option",e),delete t[e]),e.includes("constr")&&(Bs.debug("sanitize deleting constr option",e),delete t[e]),e.includes("themeCSS")&&(Bs.debug("sanitizing themeCss option"),t[e]=Ec(t[e])),e.includes("fontFamily")&&(Bs.debug("sanitizing fontFamily option"),t[e]=Ec(t[e])),e.includes("altFontFamily")&&(Bs.debug("sanitizing altFontFamily option"),t[e]=Ec(t[e])),Us.includes(e)?"object"==typeof t[e]&&(Bs.debug("sanitize deleting object",e),Ac(t[e])):(Bs.debug("sanitize deleting option",e),delete t[e])}))),t.themeVariables){const e=Object.keys(t.themeVariables);for(const i of e){const e=t.themeVariables[i];e&&e.match&&!e.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[i]="")}}Bs.debug("After sanitization",t)},Ec=t=>{let e=0,i=0;for(const r of t){if(e{if("number"==typeof t)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]},Ic={assignWithDepth:gh,wrapLabel:Tc,calculateTextHeight:wc,calculateTextWidth:Bc,calculateTextDimensions:Fc,detectInit:function(t,e){const i=mc(t,/(?:init\b)|(?:initialize\b)/);let r={};if(Array.isArray(i)){const t=i.map((t=>t.args));Ac(t),r=gh(r,[...t])}else r=i.args;if(r){let i=cc(t,e);["config"].forEach((t=>{void 0!==r[t]&&("flowchart-v2"===i&&(i="flowchart"),r[i]=r[t],delete r[t])}))}return r},detectDirective:mc,isSubstringInArray:function(t,e){for(const[i,r]of e.entries())if(r.match(t))return i;return-1},interpolateToCurve:yc,calcLabelPosition:function(t){return 1===t.length?t[0]:function(t){let e,i=0;t.forEach((t=>{i+=_c(t,e),e=t}));let r,n=i/2;return e=void 0,t.forEach((t=>{if(e&&!r){const i=_c(t,e);if(i=1&&(r={x:t.x,y:t.y}),o>0&&o<1&&(r={x:(1-o)*e.x+o*t.x,y:(1-o)*e.y+o*t.y})}}e=t})),r}(t)},calcCardinalityPosition:(t,e,i)=>{let r;Bs.info(`our points ${JSON.stringify(e)}`),e[0]!==i&&(e=e.reverse());let n,o=25;r=void 0,e.forEach((t=>{if(r&&!n){const e=_c(t,r);if(e=1&&(n={x:t.x,y:t.y}),i>0&&i<1&&(n={x:(1-i)*r.x+i*t.x,y:(1-i)*r.y+i*t.y})}}r=t}));const a=t?10:5,s=Math.atan2(e[0].y-n.y,e[0].x-n.x),l={x:0,y:0};return l.x=Math.sin(s)*a+(e[0].x+n.x)/2,l.y=-Math.cos(s)*a+(e[0].y+n.y)/2,l},calcTerminalLabelPosition:function(t,e,i){let r,n=JSON.parse(JSON.stringify(i));Bs.info("our points",n),"start_left"!==e&&"start_right"!==e&&(n=n.reverse()),n.forEach((t=>{r=t}));let o,a=25+t;r=void 0,n.forEach((t=>{if(r&&!o){const e=_c(t,r);if(e=1&&(o={x:t.x,y:t.y}),i>0&&i<1&&(o={x:(1-i)*r.x+i*t.x,y:(1-i)*r.y+i*t.y})}}r=t}));const s=10+.5*t,l=Math.atan2(n[0].y-o.y,n[0].x-o.x),h={x:0,y:0};return h.x=Math.sin(l)*s+(n[0].x+o.x)/2,h.y=-Math.cos(l)*s+(n[0].y+o.y)/2,"start_left"===e&&(h.x=Math.sin(l+Math.PI)*s+(n[0].x+o.x)/2,h.y=-Math.cos(l+Math.PI)*s+(n[0].y+o.y)/2),"end_right"===e&&(h.x=Math.sin(l-Math.PI)*s+(n[0].x+o.x)/2-5,h.y=-Math.cos(l-Math.PI)*s+(n[0].y+o.y)/2-5),"end_left"===e&&(h.x=Math.sin(l)*s+(n[0].x+o.x)/2-5,h.y=-Math.cos(l)*s+(n[0].y+o.y)/2-5),h},formatUrl:function(t,e){const i=t.trim();if(i)return"loose"!==e.securityLevel?O(i):i},getStylesFromArray:bc,generateId:xc,random:kc,runFunc:(t,...e)=>{const i=t.split("."),r=i.length-1,n=i[r];let o=window;for(let a=0;a{if(!r)return;const n=t.node().getBBox();t.append("text").text(r).attr("x",n.x+n.width/2).attr("y",-i).attr("class",e)},parseFontSize:Oc},qc={id:"c4",detector:t=>null!==t.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/),loader:async()=>{const{diagram:t}=await import("./c4Diagram-4a1de0c4.bba81cd2.js");return{id:"c4",diagram:t}}},Nc={id:"flowchart",detector:(t,e)=>{var i,r;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&null!==t.match(/^\s*graph/)},loader:async()=>{const{diagram:t}=await import("./flowDiagram-702318ad.9fc2e165.js");return{id:"flowchart",diagram:t}}},Dc={id:"flowchart-v2",detector:(t,e)=>{var i,r,n;return"dagre-d3"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&(null!==t.match(/^\s*graph/)&&"dagre-wrapper"===(null==(n=null==e?void 0:e.flowchart)?void 0:n.defaultRenderer)||null!==t.match(/^\s*flowchart/))},loader:async()=>{const{diagram:t}=await import("./flowDiagram-v2-8716a26e.0519cf3e.js");return{id:"flowchart-v2",diagram:t}}},zc={id:"er",detector:t=>null!==t.match(/^\s*erDiagram/),loader:async()=>{const{diagram:t}=await import("./erDiagram-5e907343.259e9da2.js");return{id:"er",diagram:t}}},$c={id:"gitGraph",detector:t=>null!==t.match(/^\s*gitGraph/),loader:async()=>{const{diagram:t}=await import("./gitGraphDiagram-127727f3.0a7c406c.js");return{id:"gitGraph",diagram:t}}},jc={id:"gantt",detector:t=>null!==t.match(/^\s*gantt/),loader:async()=>{const{diagram:t}=await import("./ganttDiagram-3bc7fa50.538df6c0.js");return{id:"gantt",diagram:t}}},Rc={id:"info",detector:t=>null!==t.match(/^\s*info/),loader:async()=>{const{diagram:t}=await import("./infoDiagram-4374b389.2c0ba8f4.js");return{id:"info",diagram:t}}},Pc={id:"pie",detector:t=>null!==t.match(/^\s*pie/),loader:async()=>{const{diagram:t}=await import("./pieDiagram-f5e05a25.2e8e66ce.js");return{id:"pie",diagram:t}}},Wc="quadrantChart",Hc={id:Wc,detector:t=>null!==t.match(/^\s*quadrantChart/),loader:async()=>{const{diagram:t}=await import("./quadrantDiagram-652558cb.73e31ede.js");return{id:Wc,diagram:t}}},Uc={id:"requirement",detector:t=>null!==t.match(/^\s*requirement(Diagram)?/),loader:async()=>{const{diagram:t}=await import("./requirementDiagram-730b4d6e.446cee50.js");return{id:"requirement",diagram:t}}},Yc={id:"sequence",detector:t=>null!==t.match(/^\s*sequenceDiagram/),loader:async()=>{const{diagram:t}=await import("./sequenceDiagram-edd7e28f.dfd6f6b9.js");return{id:"sequence",diagram:t}}},Vc={id:"class",detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer)&&null!==t.match(/^\s*classDiagram/)},loader:async()=>{const{diagram:t}=await import("./classDiagram-62cfb02d.f8c26c1c.js");return{id:"class",diagram:t}}},Gc={id:"classDiagram",detector:(t,e)=>{var i;return null!==t.match(/^\s*classDiagram/)&&"dagre-wrapper"===(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer)||null!==t.match(/^\s*classDiagram-v2/)},loader:async()=>{const{diagram:t}=await import("./classDiagram-v2-c1dfb0e0.11f799d7.js");return{id:"classDiagram",diagram:t}}},Xc={id:"state",detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer)&&null!==t.match(/^\s*stateDiagram/)},loader:async()=>{const{diagram:t}=await import("./stateDiagram-d766d74d.21d88775.js");return{id:"state",diagram:t}}},Zc={id:"stateDiagram",detector:(t,e)=>{var i,r;return null!==t.match(/^\s*stateDiagram-v2/)||(!(!t.match(/^\s*stateDiagram/)||"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer))||!(!t.match(/^\s*stateDiagram/)||"dagre-wrapper"!==(null==(r=null==e?void 0:e.state)?void 0:r.defaultRenderer)))},loader:async()=>{const{diagram:t}=await import("./stateDiagram-v2-978d1189.2119f26f.js");return{id:"stateDiagram",diagram:t}}},Jc={id:"journey",detector:t=>null!==t.match(/^\s*journey/),loader:async()=>{const{diagram:t}=await import("./journeyDiagram-ccf0174b.f190e614.js");return{id:"journey",diagram:t}}},Kc={setConf:function(){},draw:(t,e,i)=>{try{Bs.debug("Renering svg for syntax error\n");const t=je("#"+e),r=t.append("g");r.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"),r.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"),r.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"),r.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"),r.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"),r.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"),r.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"),r.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text("mermaid version "+i),t.attr("height",100),t.attr("width",500),t.attr("viewBox","768 0 912 512")}catch(n){Bs.error("Error while rendering info diagram"),Bs.error((r=n)instanceof Error?r.message:String(r))}var r}},Qc={db:{clear:()=>{}},styles:()=>"",renderer:Kc,parser:{parser:{yy:{}},parse:()=>{}},init:()=>{}},tu="flowchart-elk",eu={id:tu,detector:(t,e)=>{var i;return!!(t.match(/^\s*flowchart-elk/)||t.match(/^\s*flowchart|graph/)&&"elk"===(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer))},loader:async()=>{const{diagram:t}=await import("./flowchart-elk-definition-206a7d68.1cfd1a2c.js");return{id:tu,diagram:t}}},iu={id:"timeline",detector:t=>null!==t.match(/^\s*timeline/),loader:async()=>{const{diagram:t}=await import("./timeline-definition-d53f6d76.1b6ff628.js");return{id:"timeline",diagram:t}}},ru="mindmap",nu={id:ru,detector:t=>null!==t.match(/^\s*mindmap/),loader:async()=>{const{diagram:t}=await import("./mindmap-definition-74e4e806.1576bedb.js");return{id:ru,diagram:t}}};let ou=!1;const au=()=>{ou||(ou=!0,nc("error",Qc,(t=>"error"===t.toLowerCase().trim())),nc("---",{db:{clear:()=>{}},styles:{},renderer:{},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("---"))),uc(qc,Gc,Vc,zc,jc,Rc,Pc,Uc,Yc,eu,Dc,Nc,nu,iu,$c,Zc,Xc,Jc,Hc))};class su{constructor(t){var e,i;this.text=t,this.type="graph",this.text+="\n";const r=Th();try{this.type=cc(t,r)}catch(a){this.type="error",this.detectError=a}const n=oc(this.type);Bs.debug("Type "+this.type),this.db=n.db,null==(i=(e=this.db).clear)||i.call(e),this.renderer=n.renderer,this.parser=n.parser;const o=this.parser.parse.bind(this.parser);this.parser.parse=t=>o((t=>t.trimStart().replace(/^\s*%%(?!{)[^\n]+\n?/gm,""))(function(t,e){var i,r;const n=t.match(fh);if(n){const o=dh(n[1],{schema:uh});return(null==o?void 0:o.title)&&(null==(i=e.setDiagramTitle)||i.call(e,o.title)),(null==o?void 0:o.displayMode)&&(null==(r=e.setDisplayMode)||r.call(e,o.displayMode)),t.slice(n[0].length)}return t}(t,this.db))),this.parser.parser.yy=this.db,n.init&&(n.init(r),Bs.info("Initialized diagram "+this.type,r)),this.parse()}parse(){var t,e;if(this.detectError)throw this.detectError;null==(e=(t=this.db).clear)||e.call(t),this.parser.parse(this.text)}async render(t,e){await this.renderer.draw(this.text,t,e,this)}getParser(){return this.parser}getType(){return this.type}}const lu=async t=>{const e=cc(t,Th());try{oc(e)}catch(i){const t=hc[e].loader;if(!t)throw new ac(`Diagram ${e} not found.`);const{id:r,diagram:n}=await t();nc(r,n)}return new su(t)};let hu=[];const cu=t=>{hu.push(t)};const uu=["graph","flowchart","flowchart-v2","flowchart-elk","stateDiagram","stateDiagram-v2"],du=["foreignobject"],fu=["dominant-baseline"];const pu=function(t){return t.replace(/fl°°/g,"&#").replace(/fl°/g,"&").replace(/¶ß/g,";")},gu=(t,e,i=[])=>`\n.${t} ${e} { ${i.join(" !important; ")} !important; }`,mu=(t,e,i,r)=>{const n=((t,e,i={})=>{var r;let n="";if(void 0!==t.themeCSS&&(n+=`\n${t.themeCSS}`),void 0!==t.fontFamily&&(n+=`\n:root { --mermaid-font-family: ${t.fontFamily}}`),void 0!==t.altFontFamily&&(n+=`\n:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),!Ss(i)&&uu.includes(e)){const e=["> *","span"],o=["rect","polygon","ellipse","circle","path"],a=t.htmlLabels||(null==(r=t.flowchart)?void 0:r.htmlLabels)?e:o;for(const t in i){const e=i[t];Ss(e.styles)||a.forEach((t=>{n+=gu(e.id,t,e.styles)})),Ss(e.textStyles)||(n+=gu(e.id,"tspan",e.textStyles))}}return n})(t,e,i);return za(Oa(`${r}{${Ih(e,n,t.themeVariables)}}`),$a)},yu=(t,e,i,r,n)=>{const o=t.append("div");o.attr("id",i),r&&o.attr("style",r);const a=o.append("svg").attr("id",e).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg");return n&&a.attr("xmlns:xlink",n),a.append("g"),t};function _u(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}const bu=Object.freeze({render:async function(t,e,i){var r,n,o,a,s;au(),Bh();const l=Ic.detectInit(e);l&&(Ac(l),wh(l));const h=Th();Bs.debug(h),e.length>(null!=(r=null==h?void 0:h.maxTextSize)?r:5e4)&&(e="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa"),e=(e=e.replace(/\r\n?/g,"\n")).replace(/<(\w+)([^>]*)>/g,((t,e,i)=>"<"+e+i.replace(/="([^"]*)"/g,"='$1'")+">"));const c="#"+t,u="i"+t,d="#"+u,f="d"+t,p="#"+f;let g=je("body");const m="sandbox"===h.securityLevel,y="loose"===h.securityLevel,_=h.fontFamily;if(void 0!==i){if(i&&(i.innerHTML=""),m){const t=_u(je(i),u);g=je(t.nodes()[0].contentDocument.body),g.node().style.margin=0}else g=je(i);yu(g,t,f,`font-family: ${_}`,"http://www.w3.org/1999/xlink")}else{if(((t,e,i,r)=>{var n,o,a;null==(n=t.getElementById(e))||n.remove(),null==(o=t.getElementById(i))||o.remove(),null==(a=t.getElementById(r))||a.remove()})(document,t,f,u),m){const t=_u(je("body"),u);g=je(t.nodes()[0].contentDocument.body),g.node().style.margin=0}else g=je("body");yu(g,t,f)}let b,C;e=function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/classDef.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/#\w+;/g,(function(t){const e=t.substring(1,t.length-1);return/^\+?\d+$/.test(e)?"fl°°"+e+"¶ß":"fl°"+e+"¶ß"})),e}(e);try{b=await lu(e)}catch(A){b=new su("error"),C=A}const x=g.select(p).node(),k=b.type,v=x.firstChild,T=v.firstChild,S=uu.includes(k)?b.renderer.getClasses(e,b):{},w=mu(h,k,S,c),B=document.createElement("style");B.innerHTML=w,v.insertBefore(B,T);try{await b.renderer.draw(e,t,"10.2.0",b)}catch(E){throw Kc.draw(e,t,"10.2.0"),E}!function(t,e,i,r){(function(t,e){t.attr("role","graphics-document document"),Ss(e)||t.attr("aria-roledescription",e)})(e,t),function(t,e,i,r){if(void 0!==t.insert&&(e||i)){if(i){const e="chart-desc-"+r;t.attr("aria-describedby",e),t.insert("desc",":first-child").attr("id",e).text(i)}if(e){const i="chart-title-"+r;t.attr("aria-labelledby",i),t.insert("title",":first-child").attr("id",i).text(e)}}}(e,i,r,e.attr("id"))}(k,g.select(`${p} svg`),null==(o=(n=b.db).getAccTitle)?void 0:o.call(n),null==(s=(a=b.db).getAccDescription)?void 0:s.call(a)),g.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns","http://www.w3.org/1999/xhtml");let F=g.select(p).node().innerHTML;if(Bs.debug("config.arrowMarkerAbsolute",h.arrowMarkerAbsolute),F=((t="",e,i)=>{let r=t;return i||e||(r=r.replace(/marker-end="url\(.*?#/g,'marker-end="url(#')),r=pu(r),r=r.replace(/
    /g,"
    "),r})(F,m,Ns(h.arrowMarkerAbsolute)),m){F=((t="",e)=>``)(F,g.select(p+" svg").node())}else y||(F=Jn.sanitize(F,{ADD_TAGS:du,ADD_ATTR:fu}));if(hu.forEach((t=>{t()})),hu=[],C)throw C;const L=je(m?d:p).node();return L&&"remove"in L&&L.remove(),{svg:F,bindFunctions:b.db.bindFunctions}},parse:async function(t,e){au();try{(await lu(t)).parse()}catch(i){if(null==e?void 0:e.suppressErrors)return!1;throw i}return!0},parseDirective:Xh,getDiagramFromText:lu,initialize:function(t={}){var e;(null==t?void 0:t.fontFamily)&&!(null==(e=t.themeVariables)?void 0:e.fontFamily)&&(t.themeVariables||(t.themeVariables={}),t.themeVariables.fontFamily=t.fontFamily),yh=gh({},t),(null==t?void 0:t.theme)&&t.theme in Ps?t.themeVariables=Ps[t.theme].getThemeVariables(t.themeVariables):t&&(t.themeVariables=Ps.default.getThemeVariables(t.themeVariables));const i="object"==typeof t?(t=>(_h=gh({},mh),_h=gh(_h,t),t.theme&&Ps[t.theme]&&(_h.themeVariables=Ps[t.theme].getThemeVariables(t.themeVariables)),xh(_h,bh),_h))(t):kh();Fs(i.logLevel),au()},getConfig:Th,setConfig:vh,getSiteConfig:kh,updateSiteConfig:t=>(_h=gh(_h,t),xh(_h,bh),_h),reset:()=>{Bh()},globalReset:()=>{Bh(mh)},defaultConfig:mh});Fs(Th().logLevel),Bh(Th());const Cu=(t,s,l)=>{var h,c;Bs.warn(t),Mc(t)?(l&&l(t.str,t.hash),s.push((h=((t,e)=>{for(var i in e||(e={}))n.call(e,i)&&a(t,i,e[i]);if(r)for(var i of r(e))o.call(e,i)&&a(t,i,e[i]);return t})({},t),c={message:t.str,error:t},e(h,i(c))))):(l&&l(t),t instanceof Error&&s.push({str:t.message,message:t.message,hash:t.name,error:t}))},xu=async function(t={querySelector:".mermaid"}){try{await ku(t)}catch(e){if(Mc(e)&&Bs.error(e.str),Lu.parseError&&Lu.parseError(e),!t.suppressErrors)throw Bs.error("Use the suppressErrors option to suppress these errors"),e}},ku=async function({postRenderCallback:t,querySelector:e,nodes:i}={querySelector:".mermaid"}){const r=bu.getConfig();let n;if(Bs.debug((t?"":"No ")+"Callback function found"),i)n=i;else{if(!e)throw new Error("Nodes and querySelector are both undefined");n=document.querySelectorAll(e)}Bs.debug(`Found ${n.length} diagrams`),void 0!==(null==r?void 0:r.startOnLoad)&&(Bs.debug("Start On Load: "+(null==r?void 0:r.startOnLoad)),bu.updateSiteConfig({startOnLoad:null==r?void 0:r.startOnLoad}));const o=new Ic.initIdGenerator(r.deterministicIds,r.deterministicIDSeed);let a;const l=[];for(const c of Array.from(n)){ +function Vs(t){return null==t}var Gs={isNothing:Vs,isObject:function(t){return"object"==typeof t&&null!==t},toArray:function(t){return Array.isArray(t)?t:Vs(t)?[]:[t]},repeat:function(t,e){var i,r="";for(i=0;is&&(e=r-s+(o=" ... ").length),i-r>s&&(i=r+s-(a=" ...").length),{str:o+t.slice(e,i).replace(/\t/g,"→")+a,pos:r-e+o.length}}function Qs(t,e){return Gs.repeat(" ",e-t.length)+t}var tl=function(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),"number"!=typeof e.indent&&(e.indent=1),"number"!=typeof e.linesBefore&&(e.linesBefore=3),"number"!=typeof e.linesAfter&&(e.linesAfter=2);for(var i,r=/\r?\n|\r|\0/g,n=[0],o=[],a=-1;i=r.exec(t.buffer);)o.push(i.index),n.push(i.index+i[0].length),t.position<=i.index&&a<0&&(a=n.length-2);a<0&&(a=n.length-1);var s,l,h="",c=Math.min(t.line+e.linesAfter,o.length).toString().length,u=e.maxLength-(e.indent+c+3);for(s=1;s<=e.linesBefore&&!(a-s<0);s++)l=Ks(t.buffer,n[a-s],o[a-s],t.position-(n[a]-n[a-s]),u),h=Gs.repeat(" ",e.indent)+Qs((t.line-s+1).toString(),c)+" | "+l.str+"\n"+h;for(l=Ks(t.buffer,n[a],o[a],t.position,u),h+=Gs.repeat(" ",e.indent)+Qs((t.line+1).toString(),c)+" | "+l.str+"\n",h+=Gs.repeat("-",e.indent+c+3+l.pos)+"^\n",s=1;s<=e.linesAfter&&!(a+s>=o.length);s++)l=Ks(t.buffer,n[a+s],o[a+s],t.position-(n[a]-n[a+s]),u),h+=Gs.repeat(" ",e.indent)+Qs((t.line+s+1).toString(),c)+" | "+l.str+"\n";return h.replace(/\n$/,"")},el=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],il=["scalar","sequence","mapping"];var rl=function(t,e){var i,r;if(e=e||{},Object.keys(e).forEach((function(e){if(-1===el.indexOf(e))throw new Js('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')})),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=(i=e.styleAliases||null,r={},null!==i&&Object.keys(i).forEach((function(t){i[t].forEach((function(e){r[String(e)]=t}))})),r),-1===il.indexOf(this.kind))throw new Js('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')};function nl(t,e){var i=[];return t[e].forEach((function(t){var e=i.length;i.forEach((function(i,r){i.tag===t.tag&&i.kind===t.kind&&i.multi===t.multi&&(e=r)})),i[e]=t})),i}function ol(t){return this.extend(t)}ol.prototype.extend=function(t){var e=[],i=[];if(t instanceof rl)i.push(t);else if(Array.isArray(t))i=i.concat(t);else{if(!t||!Array.isArray(t.implicit)&&!Array.isArray(t.explicit))throw new Js("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");t.implicit&&(e=e.concat(t.implicit)),t.explicit&&(i=i.concat(t.explicit))}e.forEach((function(t){if(!(t instanceof rl))throw new Js("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(t.loadKind&&"scalar"!==t.loadKind)throw new Js("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(t.multi)throw new Js("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")})),i.forEach((function(t){if(!(t instanceof rl))throw new Js("Specified list of YAML types (or a single Type object) contains a non-Type object.")}));var r=Object.create(ol.prototype);return r.implicit=(this.implicit||[]).concat(e),r.explicit=(this.explicit||[]).concat(i),r.compiledImplicit=nl(r,"implicit"),r.compiledExplicit=nl(r,"explicit"),r.compiledTypeMap=function(){var t,e,i={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function r(t){t.multi?(i.multi[t.kind].push(t),i.multi.fallback.push(t)):i[t.kind][t.tag]=i.fallback[t.tag]=t}for(t=0,e=arguments.length;t=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)},octal:function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)},decimal:function(t){return t.toString(10)},hexadecimal:function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),dl=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");var fl=/^[-+]?[0-9]+e/;var pl=new rl("tag:yaml.org,2002:float",{kind:"scalar",resolve:function(t){return null!==t&&!(!dl.test(t)||"_"===t[t.length-1])},construct:function(t){var e,i;return i="-"===(e=t.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(e[0])>=0&&(e=e.slice(1)),".inf"===e?1===i?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:i*parseFloat(e,10)},predicate:function(t){return"[object Number]"===Object.prototype.toString.call(t)&&(t%1!=0||Gs.isNegativeZero(t))},represent:function(t,e){var i;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(Gs.isNegativeZero(t))return"-0.0";return i=t.toString(10),fl.test(i)?i.replace("e",".e"):i},defaultStyle:"lowercase"}),gl=al.extend({implicit:[sl,ll,ul,pl]}),ml=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),yl=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");var _l=new rl("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:function(t){return null!==t&&(null!==ml.exec(t)||null!==yl.exec(t))},construct:function(t){var e,i,r,n,o,a,s,l,h=0,c=null;if(null===(e=ml.exec(t))&&(e=yl.exec(t)),null===e)throw new Error("Date resolve error");if(i=+e[1],r=+e[2]-1,n=+e[3],!e[4])return new Date(Date.UTC(i,r,n));if(o=+e[4],a=+e[5],s=+e[6],e[7]){for(h=e[7].slice(0,3);h.length<3;)h+="0";h=+h}return e[9]&&(c=6e4*(60*+e[10]+ +(e[11]||0)),"-"===e[9]&&(c=-c)),l=new Date(Date.UTC(i,r,n,o,a,s,h)),c&&l.setTime(l.getTime()-c),l},instanceOf:Date,represent:function(t){return t.toISOString()}});var bl=new rl("tag:yaml.org,2002:merge",{kind:"scalar",resolve:function(t){return"<<"===t||null===t}}),Cl="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";var xl=new rl("tag:yaml.org,2002:binary",{kind:"scalar",resolve:function(t){if(null===t)return!1;var e,i,r=0,n=t.length,o=Cl;for(i=0;i64)){if(e<0)return!1;r+=6}return r%8==0},construct:function(t){var e,i,r=t.replace(/[\r\n=]/g,""),n=r.length,o=Cl,a=0,s=[];for(e=0;e>16&255),s.push(a>>8&255),s.push(255&a)),a=a<<6|o.indexOf(r.charAt(e));return 0===(i=n%4*6)?(s.push(a>>16&255),s.push(a>>8&255),s.push(255&a)):18===i?(s.push(a>>10&255),s.push(a>>2&255)):12===i&&s.push(a>>4&255),new Uint8Array(s)},predicate:function(t){return"[object Uint8Array]"===Object.prototype.toString.call(t)},represent:function(t){var e,i,r="",n=0,o=t.length,a=Cl;for(e=0;e>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]),n=(n<<8)+t[e];return 0===(i=o%3)?(r+=a[n>>18&63],r+=a[n>>12&63],r+=a[n>>6&63],r+=a[63&n]):2===i?(r+=a[n>>10&63],r+=a[n>>4&63],r+=a[n<<2&63],r+=a[64]):1===i&&(r+=a[n>>2&63],r+=a[n<<4&63],r+=a[64],r+=a[64]),r}}),kl=Object.prototype.hasOwnProperty,vl=Object.prototype.toString;var Tl=new rl("tag:yaml.org,2002:omap",{kind:"sequence",resolve:function(t){if(null===t)return!0;var e,i,r,n,o,a=[],s=t;for(e=0,i=s.length;e>10),56320+(t-65536&1023))}for(var Hl=new Array(256),Ul=new Array(256),Yl=0;Yl<256;Yl++)Hl[Yl]=Pl(Yl)?1:0,Ul[Yl]=Pl(Yl);function Vl(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||Ll,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function Gl(t,e){var i={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return i.snippet=tl(i),new Js(e,i)}function Xl(t,e){throw Gl(t,e)}function Zl(t,e){t.onWarning&&t.onWarning.call(null,Gl(t,e))}var Jl={YAML:function(t,e,i){var r,n,o;null!==t.version&&Xl(t,"duplication of %YAML directive"),1!==i.length&&Xl(t,"YAML directive accepts exactly one argument"),null===(r=/^([0-9]+)\.([0-9]+)$/.exec(i[0]))&&Xl(t,"ill-formed argument of the YAML directive"),n=parseInt(r[1],10),o=parseInt(r[2],10),1!==n&&Xl(t,"unacceptable YAML version of the document"),t.version=i[0],t.checkLineBreaks=o<2,1!==o&&2!==o&&Zl(t,"unsupported YAML version of the document")},TAG:function(t,e,i){var r,n;2!==i.length&&Xl(t,"TAG directive accepts exactly two arguments"),r=i[0],n=i[1],Il.test(r)||Xl(t,"ill-formed tag handle (first argument) of the TAG directive"),Al.call(t.tagMap,r)&&Xl(t,'there is a previously declared suffix for "'+r+'" tag handle'),ql.test(n)||Xl(t,"ill-formed tag prefix (second argument) of the TAG directive");try{n=decodeURIComponent(n)}catch(o){Xl(t,"tag prefix is malformed: "+n)}t.tagMap[r]=n}};function Kl(t,e,i,r){var n,o,a,s;if(e1&&(t.result+=Gs.repeat("\n",e-1))}function oh(t,e){var i,r,n=t.tag,o=t.anchor,a=[],s=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=a),r=t.input.charCodeAt(t.position);0!==r&&(-1!==t.firstTabInLine&&(t.position=t.firstTabInLine,Xl(t,"tab characters must not be used in indentation")),45===r)&&$l(t.input.charCodeAt(t.position+1));)if(s=!0,t.position++,ih(t,!0,-1)&&t.lineIndent<=e)a.push(null),r=t.input.charCodeAt(t.position);else if(i=t.line,lh(t,e,3,!1,!0),a.push(t.result),ih(t,!0,-1),r=t.input.charCodeAt(t.position),(t.line===i||t.lineIndent>e)&&0!==r)Xl(t,"bad indentation of a sequence entry");else if(t.lineIndente?p=1:t.lineIndent===e?p=0:t.lineIndente?p=1:t.lineIndent===e?p=0:t.lineIndente)&&(y&&(a=t.line,s=t.lineStart,l=t.position),lh(t,e,4,!0,n)&&(y?g=t.result:m=t.result),y||(th(t,d,f,p,g,m,a,s,l),p=g=m=null),ih(t,!0,-1),h=t.input.charCodeAt(t.position)),(t.line===o||t.lineIndent>e)&&0!==h)Xl(t,"bad indentation of a mapping entry");else if(t.lineIndent=0))break;0===n?Xl(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):h?Xl(t,"repeat of an indentation width identifier"):(c=e+n-1,h=!0)}if(zl(o)){do{o=t.input.charCodeAt(++t.position)}while(zl(o));if(35===o)do{o=t.input.charCodeAt(++t.position)}while(!Dl(o)&&0!==o)}for(;0!==o;){for(eh(t),t.lineIndent=0,o=t.input.charCodeAt(t.position);(!h||t.lineIndentc&&(c=t.lineIndent),Dl(o))u++;else{if(t.lineIndent0){for(n=a,o=0;n>0;n--)(a=Rl(s=t.input.charCodeAt(++t.position)))>=0?o=(o<<4)+a:Xl(t,"expected hexadecimal character");t.result+=Wl(o),t.position++}else Xl(t,"unknown escape sequence");i=r=t.position}else Dl(s)?(Kl(t,i,r,!0),nh(t,ih(t,!1,e)),i=r=t.position):t.position===t.lineStart&&rh(t)?Xl(t,"unexpected end of the document within a double quoted scalar"):(t.position++,r=t.position)}Xl(t,"unexpected end of the stream within a double quoted scalar")}(t,d)?m=!0:!function(t){var e,i,r;if(42!==(r=t.input.charCodeAt(t.position)))return!1;for(r=t.input.charCodeAt(++t.position),e=t.position;0!==r&&!$l(r)&&!jl(r);)r=t.input.charCodeAt(++t.position);return t.position===e&&Xl(t,"name of an alias node must contain at least one character"),i=t.input.slice(e,t.position),Al.call(t.anchorMap,i)||Xl(t,'unidentified alias "'+i+'"'),t.result=t.anchorMap[i],ih(t,!0,-1),!0}(t)?function(t,e,i){var r,n,o,a,s,l,h,c,u=t.kind,d=t.result;if($l(c=t.input.charCodeAt(t.position))||jl(c)||35===c||38===c||42===c||33===c||124===c||62===c||39===c||34===c||37===c||64===c||96===c)return!1;if((63===c||45===c)&&($l(r=t.input.charCodeAt(t.position+1))||i&&jl(r)))return!1;for(t.kind="scalar",t.result="",n=o=t.position,a=!1;0!==c;){if(58===c){if($l(r=t.input.charCodeAt(t.position+1))||i&&jl(r))break}else if(35===c){if($l(t.input.charCodeAt(t.position-1)))break}else{if(t.position===t.lineStart&&rh(t)||i&&jl(c))break;if(Dl(c)){if(s=t.line,l=t.lineStart,h=t.lineIndent,ih(t,!1,-1),t.lineIndent>=e){a=!0,c=t.input.charCodeAt(t.position);continue}t.position=o,t.line=s,t.lineStart=l,t.lineIndent=h;break}}a&&(Kl(t,n,o,!1),nh(t,t.line-s),n=o=t.position,a=!1),zl(c)||(o=t.position+1),c=t.input.charCodeAt(++t.position)}return Kl(t,n,o,!1),!!t.result||(t.kind=u,t.result=d,!1)}(t,d,1===i)&&(m=!0,null===t.tag&&(t.tag="?")):(m=!0,null===t.tag&&null===t.anchor||Xl(t,"alias node should not have any properties")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===p&&(m=s&&oh(t,f))),null===t.tag)null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);else if("?"===t.tag){for(null!==t.result&&"scalar"!==t.kind&&Xl(t,'unacceptable node kind for ! tag; it should be "scalar", not "'+t.kind+'"'),l=0,h=t.implicitTypes.length;l"),null!==t.result&&u.kind!==t.kind&&Xl(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+u.kind+'", not "'+t.kind+'"'),u.resolve(t.result,t.tag)?(t.result=u.construct(t.result,t.tag),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):Xl(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return null!==t.listener&&t.listener("close",t),null!==t.tag||null!==t.anchor||m}function hh(t){var e,i,r,n,o=t.position,a=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);0!==(n=t.input.charCodeAt(t.position))&&(ih(t,!0,-1),n=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==n));){for(a=!0,n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!$l(n);)n=t.input.charCodeAt(++t.position);for(r=[],(i=t.input.slice(e,t.position)).length<1&&Xl(t,"directive name must not be less than one character in length");0!==n;){for(;zl(n);)n=t.input.charCodeAt(++t.position);if(35===n){do{n=t.input.charCodeAt(++t.position)}while(0!==n&&!Dl(n));break}if(Dl(n))break;for(e=t.position;0!==n&&!$l(n);)n=t.input.charCodeAt(++t.position);r.push(t.input.slice(e,t.position))}0!==n&&eh(t),Al.call(Jl,i)?Jl[i](t,i,r):Zl(t,'unknown document directive "'+i+'"')}ih(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,ih(t,!0,-1)):a&&Xl(t,"directives end mark is expected"),lh(t,t.lineIndent-1,4,!1,!0),ih(t,!0,-1),t.checkLineBreaks&&Ml.test(t.input.slice(o,t.position))&&Zl(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&rh(t)?46===t.input.charCodeAt(t.position)&&(t.position+=3,ih(t,!0,-1)):t.positionph(t,e,i))),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach((e=>{t.includes(e)||t.push(e)})),t):void 0===t||r<=0?null!=t&&"object"==typeof t&&"object"==typeof e?Object.assign(t,e):e:(void 0!==e&&"object"==typeof t&&"object"==typeof e&&Object.keys(e).forEach((i=>{"object"!=typeof e[i]||void 0!==t[i]&&"object"!=typeof t[i]?(n||"object"!=typeof t[i]&&"object"!=typeof e[i])&&(t[i]=e[i]):(void 0===t[i]&&(t[i]=Array.isArray(e[i])?[]:{}),t[i]=ph(t[i],e[i],{depth:r-1,clobber:n}))})),t)},gh=ph,mh=Object.freeze(Ys);let yh,_h=gh({},mh),bh=[],Ch=gh({},mh);const xh=(t,e)=>{let i=gh({},t),r={};for(const n of e)Sh(n),r=gh(r,n);if(i=gh(i,r),r.theme&&r.theme in Ps){const t=gh({},yh),e=gh(t.themeVariables||{},r.themeVariables);i.theme&&i.theme in Ps&&(i.themeVariables=Ps[i.theme].getThemeVariables(e))}return Ch=i,Ah(Ch),Ch},kh=()=>gh({},_h),vh=t=>(Ah(t),gh(Ch,t),Th()),Th=()=>gh({},Ch),Sh=t=>{var e;["secure",...null!=(e=_h.secure)?e:[]].forEach((e=>{void 0!==t[e]&&(Bs.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])})),Object.keys(t).forEach((e=>{0===e.indexOf("__")&&delete t[e]})),Object.keys(t).forEach((e=>{"string"==typeof t[e]&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],"object"==typeof t[e]&&Sh(t[e])}))},wh=t=>{t.fontFamily&&(t.themeVariables&&t.themeVariables.fontFamily||(t.themeVariables={fontFamily:t.fontFamily})),bh.push(t),xh(_h,bh)},Bh=(t=_h)=>{bh=[],xh(t,bh)};var Fh=(t=>(t.LAZY_LOAD_DEPRECATED="The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead.",t))(Fh||{});const Lh={},Ah=t=>{var e;t&&((t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&&(Lh[e="LAZY_LOAD_DEPRECATED"]||(Bs.warn(Fh[e]),Lh[e]=!0)))},Eh=function(t,e,i,r){!function(t,e){for(let i of e)t.attr(i[0],i[1])}(t,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}(e,i,r))},Mh=function(t,e,i,r){const n=e.node().getBBox(),o=n.width,a=n.height;Bs.info(`SVG bounds: ${o}x${a}`,n);let s=0,l=0;Bs.info(`Graph bounds: ${s}x${l}`,t),s=o+2*i,l=a+2*i,Bs.info(`Calculated bounds: ${s}x${l}`),Eh(e,l,s,r);const h=`${n.x-i} ${n.y-i} ${n.width+2*i} ${n.height+2*i}`;e.attr("viewBox",h)},Oh={},Ih=(t,e,i)=>{let r="";return t in Oh&&Oh[t]?r=Oh[t](i):Bs.warn(`No theme found for ${t}`),` & {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n fill: ${i.textColor}\n }\n\n /* Classes common for multiple diagrams */\n\n & .error-icon {\n fill: ${i.errorBkgColor};\n }\n & .error-text {\n fill: ${i.errorTextColor};\n stroke: ${i.errorTextColor};\n }\n\n & .edge-thickness-normal {\n stroke-width: 2px;\n }\n & .edge-thickness-thick {\n stroke-width: 3.5px\n }\n & .edge-pattern-solid {\n stroke-dasharray: 0;\n }\n\n & .edge-pattern-dashed{\n stroke-dasharray: 3;\n }\n .edge-pattern-dotted {\n stroke-dasharray: 2;\n }\n\n & .marker {\n fill: ${i.lineColor};\n stroke: ${i.lineColor};\n }\n & .marker.cross {\n stroke: ${i.lineColor};\n }\n\n & svg {\n font-family: ${i.fontFamily};\n font-size: ${i.fontSize};\n }\n\n ${r}\n\n ${e}\n`};let qh="",Nh="",Dh="";const zh=t=>Os(t,Th()),$h=function(){qh="",Dh="",Nh=""},jh=function(t){qh=zh(t).replace(/^\s+/g,"")},Rh=function(){return qh||Nh},Ph=function(t){Dh=zh(t).replace(/\n\s+/g,"\n")},Wh=function(){return Dh},Hh=function(t){Nh=zh(t)},Uh=function(){return Nh},Yh={getAccTitle:Rh,setAccTitle:jh,getDiagramTitle:Uh,setDiagramTitle:Hh,getAccDescription:Wh,setAccDescription:Ph,clear:$h},Vh=Object.freeze(Object.defineProperty({__proto__:null,clear:$h,default:Yh,getAccDescription:Wh,getAccTitle:Rh,getDiagramTitle:Uh,setAccDescription:Ph,setAccTitle:jh,setDiagramTitle:Hh},Symbol.toStringTag,{value:"Module"}));let Gh={};const Xh=function(t,e,i,r){Bs.debug("parseDirective is being called",e,i,r);try{if(void 0!==e)switch(e=e.trim(),i){case"open_directive":Gh={};break;case"type_directive":if(!Gh)throw new Error("currentDirective is undefined");Gh.type=e.toLowerCase();break;case"arg_directive":if(!Gh)throw new Error("currentDirective is undefined");Gh.args=JSON.parse(e);break;case"close_directive":Zh(t,Gh,r),Gh=void 0}}catch(n){Bs.error(`Error while rendering sequenceDiagram directive: ${e} jison context: ${i}`),Bs.error(n.message)}},Zh=function(t,e,i){switch(Bs.info(`Directive type=${e.type} with args:`,e.args),e.type){case"init":case"initialize":["config"].forEach((t=>{void 0!==e.args[t]&&("flowchart-v2"===i&&(i="flowchart"),e.args[i]=e.args[t],delete e.args[t])})),Bs.info("sanitize in handleDirective",e.args),Ac(e.args),Bs.info("sanitize in handleDirective (done)",e.args),wh(e.args);break;case"wrap":case"nowrap":t&&t.setWrap&&t.setWrap("wrap"===e.type);break;case"themeCss":Bs.warn("themeCss encountered");break;default:Bs.warn(`Unhandled directive: source: '%%{${e.type}: ${JSON.stringify(e.args?e.args:{})}}%%`,e)}},Jh=Bs,Kh=Fs,Qh=Th,tc=t=>Os(t,Qh()),ec=Mh,ic=(t,e,i,r)=>Xh(t,e,i,r),rc={},nc=(t,e,i)=>{if(rc[t])throw new Error(`Diagram ${t} already registered.`);var r,n;rc[t]=e,i&&dc(t,i),r=t,n=e.styles,Oh[r]=n,e.injectUtils&&e.injectUtils(Jh,Kh,Qh,tc,ec,Vh,ic)},oc=t=>{if(t in rc)return rc[t];throw new Error(`Diagram ${t} not found.`)};class ac extends Error{constructor(t){super(t),this.name="UnknownDiagramError"}}const sc=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,lc=/\s*%%.*\n/gm,hc={},cc=function(t,e){t=t.replace(fh,"").replace(sc,"").replace(lc,"\n");for(const[i,{detector:r}]of Object.entries(hc)){if(r(t,e))return i}throw new ac(`No diagram type detected matching given configuration for text: ${t}`)},uc=(...t)=>{for(const{id:e,detector:i,loader:r}of t)dc(e,i,r)},dc=(t,e,i)=>{hc[t]?Bs.error(`Detector with key ${t} already exists`):hc[t]={detector:e,loader:i},Bs.debug(`Detector with key ${t} added${i?" with loader":""}`)},fc={curveBasis:vi,curveBasisClosed:function(t){return new Ti(t)},curveBasisOpen:function(t){return new Si(t)},curveBumpX:function(t){return new bi(t,!0)},curveBumpY:function(t){return new bi(t,!1)},curveBundle:Bi,curveCardinalClosed:Mi,curveCardinalOpen:Ii,curveCardinal:Ai,curveCatmullRomClosed:$i,curveCatmullRomOpen:Ri,curveCatmullRom:Di,curveLinear:_i,curveLinearClosed:function(t){return new Pi(t)},curveMonotoneX:function(t){return new Vi(t)},curveMonotoneY:function(t){return new Gi(t)},curveNatural:function(t){return new Zi(t)},curveStep:function(t){return new Ki(t,.5)},curveStepAfter:function(t){return new Ki(t,1)},curveStepBefore:function(t){return new Ki(t,0)}},pc=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,gc=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,mc=function(t,e=null){try{const i=new RegExp(`[%]{2}(?![{]${gc.source})(?=[}][%]{2}).*\n`,"ig");let r;t=t.trim().replace(i,"").replace(/'/gm,'"'),Bs.debug(`Detecting diagram directive${null!==e?" type:"+e:""} based on the text:${t}`);const n=[];for(;null!==(r=pc.exec(t));)if(r.index===pc.lastIndex&&pc.lastIndex++,r&&!e||e&&r[1]&&r[1].match(e)||e&&r[2]&&r[2].match(e)){const t=r[1]?r[1]:r[2],e=r[3]?r[3].trim():r[4]?JSON.parse(r[4].trim()):null;n.push({type:t,args:e})}return 0===n.length&&n.push({type:t,args:null}),1===n.length?n[0]:n}catch(i){return Bs.error(`ERROR: ${i.message} - Unable to parse directive\n ${null!==e?" type:"+e:""} based on the text:${t}`),{type:null,args:null}}};function yc(t,e){if(!t)return e;const i=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return fc[i]||e}function _c(t,e){return t&&e?Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)):0}function bc(t){let e="",i="";for(const r of t)void 0!==r&&(r.startsWith("color:")||r.startsWith("text-align:")?i=i+r+";":e=e+r+";");return{style:e,labelStyle:i}}let Cc=0;const xc=()=>(Cc++,"id-"+Math.random().toString(36).substr(2,12)+"-"+Cc);const kc=t=>function(t){let e="";const i="0123456789abcdef",r=i.length;for(let n=0;n{if(!t)return t;if(i=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"
    "},i),zs.lineBreakRegex.test(t))return t;const r=t.split(" "),n=[];let o="";return r.forEach(((t,a)=>{const s=Bc(`${t} `,i),l=Bc(o,i);if(s>e){const{hyphenatedStrings:r,remainingWord:a}=Sc(t,e,"-",i);n.push(o,...r),o=a}else l+s>=e?(n.push(o),o=t):o=[o,t].filter(Boolean).join(" ");a+1===r.length&&n.push(o)})),n.filter((t=>""!==t)).join(i.joinWith)}),((t,e,i)=>`${t}${e}${i.fontSize}${i.fontWeight}${i.fontFamily}${i.joinWith}`)),Sc=na(((t,e,i="-",r)=>{r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},r);const n=[...t],o=[];let a="";return n.forEach(((t,s)=>{const l=`${a}${t}`;if(Bc(l,r)>=e){const t=s+1,e=n.length===t,r=`${l}${i}`;o.push(e?l:r),a=""}else a=l})),{hyphenatedStrings:o,remainingWord:a}}),((t,e,i="-",r)=>`${t}${e}${i}${r.fontSize}${r.fontWeight}${r.fontFamily}`));function wc(t,e){return e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:15},e),Fc(t,e).height}function Bc(t,e){return e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial"},e),Fc(t,e).width}const Fc=na(((t,e)=>{e=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial"},e);const{fontSize:i,fontFamily:r,fontWeight:n}=e;if(!t)return{width:0,height:0};const[,o]=Oc(i),a=["sans-serif",r],s=t.split(zs.lineBreakRegex),l=[],h=je("body");if(!h.remove)return{width:0,height:0,lineHeight:0};const c=h.append("svg");for(const u of a){let t=0;const e={width:0,height:0,lineHeight:0};for(const i of s){const r={x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0};r.text=i;const a=vc(c,r).style("font-size",o).style("font-weight",n).style("font-family",u),s=(a._groups||a)[0][0].getBBox();if(0===s.width&&0===s.height)throw new Error("svg element not in render tree");e.width=Math.round(Math.max(e.width,s.width)),t=Math.round(s.height),e.height+=t,e.lineHeight=Math.round(Math.max(e.lineHeight,t))}l.push(e)}c.remove();return l[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]}),((t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`));let Lc;const Ac=t=>{if(Bs.debug("directiveSanitizer called with",t),"object"==typeof t&&(t.length?t.forEach((t=>Ac(t))):Object.keys(t).forEach((e=>{Bs.debug("Checking key",e),e.startsWith("__")&&(Bs.debug("sanitize deleting __ option",e),delete t[e]),e.includes("proto")&&(Bs.debug("sanitize deleting proto option",e),delete t[e]),e.includes("constr")&&(Bs.debug("sanitize deleting constr option",e),delete t[e]),e.includes("themeCSS")&&(Bs.debug("sanitizing themeCss option"),t[e]=Ec(t[e])),e.includes("fontFamily")&&(Bs.debug("sanitizing fontFamily option"),t[e]=Ec(t[e])),e.includes("altFontFamily")&&(Bs.debug("sanitizing altFontFamily option"),t[e]=Ec(t[e])),Us.includes(e)?"object"==typeof t[e]&&(Bs.debug("sanitize deleting object",e),Ac(t[e])):(Bs.debug("sanitize deleting option",e),delete t[e])}))),t.themeVariables){const e=Object.keys(t.themeVariables);for(const i of e){const e=t.themeVariables[i];e&&e.match&&!e.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[i]="")}}Bs.debug("After sanitization",t)},Ec=t=>{let e=0,i=0;for(const r of t){if(e{if("number"==typeof t)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]},Ic={assignWithDepth:gh,wrapLabel:Tc,calculateTextHeight:wc,calculateTextWidth:Bc,calculateTextDimensions:Fc,detectInit:function(t,e){const i=mc(t,/(?:init\b)|(?:initialize\b)/);let r={};if(Array.isArray(i)){const t=i.map((t=>t.args));Ac(t),r=gh(r,[...t])}else r=i.args;if(r){let i=cc(t,e);["config"].forEach((t=>{void 0!==r[t]&&("flowchart-v2"===i&&(i="flowchart"),r[i]=r[t],delete r[t])}))}return r},detectDirective:mc,isSubstringInArray:function(t,e){for(const[i,r]of e.entries())if(r.match(t))return i;return-1},interpolateToCurve:yc,calcLabelPosition:function(t){return 1===t.length?t[0]:function(t){let e,i=0;t.forEach((t=>{i+=_c(t,e),e=t}));let r,n=i/2;return e=void 0,t.forEach((t=>{if(e&&!r){const i=_c(t,e);if(i=1&&(r={x:t.x,y:t.y}),o>0&&o<1&&(r={x:(1-o)*e.x+o*t.x,y:(1-o)*e.y+o*t.y})}}e=t})),r}(t)},calcCardinalityPosition:(t,e,i)=>{let r;Bs.info(`our points ${JSON.stringify(e)}`),e[0]!==i&&(e=e.reverse());let n,o=25;r=void 0,e.forEach((t=>{if(r&&!n){const e=_c(t,r);if(e=1&&(n={x:t.x,y:t.y}),i>0&&i<1&&(n={x:(1-i)*r.x+i*t.x,y:(1-i)*r.y+i*t.y})}}r=t}));const a=t?10:5,s=Math.atan2(e[0].y-n.y,e[0].x-n.x),l={x:0,y:0};return l.x=Math.sin(s)*a+(e[0].x+n.x)/2,l.y=-Math.cos(s)*a+(e[0].y+n.y)/2,l},calcTerminalLabelPosition:function(t,e,i){let r,n=JSON.parse(JSON.stringify(i));Bs.info("our points",n),"start_left"!==e&&"start_right"!==e&&(n=n.reverse()),n.forEach((t=>{r=t}));let o,a=25+t;r=void 0,n.forEach((t=>{if(r&&!o){const e=_c(t,r);if(e=1&&(o={x:t.x,y:t.y}),i>0&&i<1&&(o={x:(1-i)*r.x+i*t.x,y:(1-i)*r.y+i*t.y})}}r=t}));const s=10+.5*t,l=Math.atan2(n[0].y-o.y,n[0].x-o.x),h={x:0,y:0};return h.x=Math.sin(l)*s+(n[0].x+o.x)/2,h.y=-Math.cos(l)*s+(n[0].y+o.y)/2,"start_left"===e&&(h.x=Math.sin(l+Math.PI)*s+(n[0].x+o.x)/2,h.y=-Math.cos(l+Math.PI)*s+(n[0].y+o.y)/2),"end_right"===e&&(h.x=Math.sin(l-Math.PI)*s+(n[0].x+o.x)/2-5,h.y=-Math.cos(l-Math.PI)*s+(n[0].y+o.y)/2-5),"end_left"===e&&(h.x=Math.sin(l)*s+(n[0].x+o.x)/2-5,h.y=-Math.cos(l)*s+(n[0].y+o.y)/2-5),h},formatUrl:function(t,e){const i=t.trim();if(i)return"loose"!==e.securityLevel?O(i):i},getStylesFromArray:bc,generateId:xc,random:kc,runFunc:(t,...e)=>{const i=t.split("."),r=i.length-1,n=i[r];let o=window;for(let a=0;a{if(!r)return;const n=t.node().getBBox();t.append("text").text(r).attr("x",n.x+n.width/2).attr("y",-i).attr("class",e)},parseFontSize:Oc},qc={id:"c4",detector:t=>null!==t.match(/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/),loader:async()=>{const{diagram:t}=await import("./c4Diagram-4a1de0c4.1b52351d.js");return{id:"c4",diagram:t}}},Nc={id:"flowchart",detector:(t,e)=>{var i,r;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&null!==t.match(/^\s*graph/)},loader:async()=>{const{diagram:t}=await import("./flowDiagram-702318ad.c596a7e8.js");return{id:"flowchart",diagram:t}}},Dc={id:"flowchart-v2",detector:(t,e)=>{var i,r,n;return"dagre-d3"!==(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer)&&"elk"!==(null==(r=null==e?void 0:e.flowchart)?void 0:r.defaultRenderer)&&(null!==t.match(/^\s*graph/)&&"dagre-wrapper"===(null==(n=null==e?void 0:e.flowchart)?void 0:n.defaultRenderer)||null!==t.match(/^\s*flowchart/))},loader:async()=>{const{diagram:t}=await import("./flowDiagram-v2-8716a26e.61097f7a.js");return{id:"flowchart-v2",diagram:t}}},zc={id:"er",detector:t=>null!==t.match(/^\s*erDiagram/),loader:async()=>{const{diagram:t}=await import("./erDiagram-5e907343.ea1d1557.js");return{id:"er",diagram:t}}},$c={id:"gitGraph",detector:t=>null!==t.match(/^\s*gitGraph/),loader:async()=>{const{diagram:t}=await import("./gitGraphDiagram-127727f3.024abe5a.js");return{id:"gitGraph",diagram:t}}},jc={id:"gantt",detector:t=>null!==t.match(/^\s*gantt/),loader:async()=>{const{diagram:t}=await import("./ganttDiagram-3bc7fa50.a492c14b.js");return{id:"gantt",diagram:t}}},Rc={id:"info",detector:t=>null!==t.match(/^\s*info/),loader:async()=>{const{diagram:t}=await import("./infoDiagram-4374b389.362cabc6.js");return{id:"info",diagram:t}}},Pc={id:"pie",detector:t=>null!==t.match(/^\s*pie/),loader:async()=>{const{diagram:t}=await import("./pieDiagram-f5e05a25.e734d891.js");return{id:"pie",diagram:t}}},Wc="quadrantChart",Hc={id:Wc,detector:t=>null!==t.match(/^\s*quadrantChart/),loader:async()=>{const{diagram:t}=await import("./quadrantDiagram-652558cb.3bbba2cb.js");return{id:Wc,diagram:t}}},Uc={id:"requirement",detector:t=>null!==t.match(/^\s*requirement(Diagram)?/),loader:async()=>{const{diagram:t}=await import("./requirementDiagram-730b4d6e.e48886eb.js");return{id:"requirement",diagram:t}}},Yc={id:"sequence",detector:t=>null!==t.match(/^\s*sequenceDiagram/),loader:async()=>{const{diagram:t}=await import("./sequenceDiagram-edd7e28f.9af17a9e.js");return{id:"sequence",diagram:t}}},Vc={id:"class",detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer)&&null!==t.match(/^\s*classDiagram/)},loader:async()=>{const{diagram:t}=await import("./classDiagram-62cfb02d.b94f625b.js");return{id:"class",diagram:t}}},Gc={id:"classDiagram",detector:(t,e)=>{var i;return null!==t.match(/^\s*classDiagram/)&&"dagre-wrapper"===(null==(i=null==e?void 0:e.class)?void 0:i.defaultRenderer)||null!==t.match(/^\s*classDiagram-v2/)},loader:async()=>{const{diagram:t}=await import("./classDiagram-v2-c1dfb0e0.308507d3.js");return{id:"classDiagram",diagram:t}}},Xc={id:"state",detector:(t,e)=>{var i;return"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer)&&null!==t.match(/^\s*stateDiagram/)},loader:async()=>{const{diagram:t}=await import("./stateDiagram-d766d74d.3653d77d.js");return{id:"state",diagram:t}}},Zc={id:"stateDiagram",detector:(t,e)=>{var i,r;return null!==t.match(/^\s*stateDiagram-v2/)||(!(!t.match(/^\s*stateDiagram/)||"dagre-wrapper"!==(null==(i=null==e?void 0:e.state)?void 0:i.defaultRenderer))||!(!t.match(/^\s*stateDiagram/)||"dagre-wrapper"!==(null==(r=null==e?void 0:e.state)?void 0:r.defaultRenderer)))},loader:async()=>{const{diagram:t}=await import("./stateDiagram-v2-978d1189.6fdea536.js");return{id:"stateDiagram",diagram:t}}},Jc={id:"journey",detector:t=>null!==t.match(/^\s*journey/),loader:async()=>{const{diagram:t}=await import("./journeyDiagram-ccf0174b.5da82ccf.js");return{id:"journey",diagram:t}}},Kc={setConf:function(){},draw:(t,e,i)=>{try{Bs.debug("Renering svg for syntax error\n");const t=je("#"+e),r=t.append("g");r.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"),r.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"),r.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"),r.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"),r.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"),r.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"),r.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"),r.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text("mermaid version "+i),t.attr("height",100),t.attr("width",500),t.attr("viewBox","768 0 912 512")}catch(n){Bs.error("Error while rendering info diagram"),Bs.error((r=n)instanceof Error?r.message:String(r))}var r}},Qc={db:{clear:()=>{}},styles:()=>"",renderer:Kc,parser:{parser:{yy:{}},parse:()=>{}},init:()=>{}},tu="flowchart-elk",eu={id:tu,detector:(t,e)=>{var i;return!!(t.match(/^\s*flowchart-elk/)||t.match(/^\s*flowchart|graph/)&&"elk"===(null==(i=null==e?void 0:e.flowchart)?void 0:i.defaultRenderer))},loader:async()=>{const{diagram:t}=await import("./flowchart-elk-definition-206a7d68.4a925c35.js");return{id:tu,diagram:t}}},iu={id:"timeline",detector:t=>null!==t.match(/^\s*timeline/),loader:async()=>{const{diagram:t}=await import("./timeline-definition-d53f6d76.be0df1ae.js");return{id:"timeline",diagram:t}}},ru="mindmap",nu={id:ru,detector:t=>null!==t.match(/^\s*mindmap/),loader:async()=>{const{diagram:t}=await import("./mindmap-definition-74e4e806.83465c17.js");return{id:ru,diagram:t}}};let ou=!1;const au=()=>{ou||(ou=!0,nc("error",Qc,(t=>"error"===t.toLowerCase().trim())),nc("---",{db:{clear:()=>{}},styles:{},renderer:{},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("---"))),uc(qc,Gc,Vc,zc,jc,Rc,Pc,Uc,Yc,eu,Dc,Nc,nu,iu,$c,Zc,Xc,Jc,Hc))};class su{constructor(t){var e,i;this.text=t,this.type="graph",this.text+="\n";const r=Th();try{this.type=cc(t,r)}catch(a){this.type="error",this.detectError=a}const n=oc(this.type);Bs.debug("Type "+this.type),this.db=n.db,null==(i=(e=this.db).clear)||i.call(e),this.renderer=n.renderer,this.parser=n.parser;const o=this.parser.parse.bind(this.parser);this.parser.parse=t=>o((t=>t.trimStart().replace(/^\s*%%(?!{)[^\n]+\n?/gm,""))(function(t,e){var i,r;const n=t.match(fh);if(n){const o=dh(n[1],{schema:uh});return(null==o?void 0:o.title)&&(null==(i=e.setDiagramTitle)||i.call(e,o.title)),(null==o?void 0:o.displayMode)&&(null==(r=e.setDisplayMode)||r.call(e,o.displayMode)),t.slice(n[0].length)}return t}(t,this.db))),this.parser.parser.yy=this.db,n.init&&(n.init(r),Bs.info("Initialized diagram "+this.type,r)),this.parse()}parse(){var t,e;if(this.detectError)throw this.detectError;null==(e=(t=this.db).clear)||e.call(t),this.parser.parse(this.text)}async render(t,e){await this.renderer.draw(this.text,t,e,this)}getParser(){return this.parser}getType(){return this.type}}const lu=async t=>{const e=cc(t,Th());try{oc(e)}catch(i){const t=hc[e].loader;if(!t)throw new ac(`Diagram ${e} not found.`);const{id:r,diagram:n}=await t();nc(r,n)}return new su(t)};let hu=[];const cu=t=>{hu.push(t)};const uu=["graph","flowchart","flowchart-v2","flowchart-elk","stateDiagram","stateDiagram-v2"],du=["foreignobject"],fu=["dominant-baseline"];const pu=function(t){return t.replace(/fl°°/g,"&#").replace(/fl°/g,"&").replace(/¶ß/g,";")},gu=(t,e,i=[])=>`\n.${t} ${e} { ${i.join(" !important; ")} !important; }`,mu=(t,e,i,r)=>{const n=((t,e,i={})=>{var r;let n="";if(void 0!==t.themeCSS&&(n+=`\n${t.themeCSS}`),void 0!==t.fontFamily&&(n+=`\n:root { --mermaid-font-family: ${t.fontFamily}}`),void 0!==t.altFontFamily&&(n+=`\n:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),!Ss(i)&&uu.includes(e)){const e=["> *","span"],o=["rect","polygon","ellipse","circle","path"],a=t.htmlLabels||(null==(r=t.flowchart)?void 0:r.htmlLabels)?e:o;for(const t in i){const e=i[t];Ss(e.styles)||a.forEach((t=>{n+=gu(e.id,t,e.styles)})),Ss(e.textStyles)||(n+=gu(e.id,"tspan",e.textStyles))}}return n})(t,e,i);return za(Oa(`${r}{${Ih(e,n,t.themeVariables)}}`),$a)},yu=(t,e,i,r,n)=>{const o=t.append("div");o.attr("id",i),r&&o.attr("style",r);const a=o.append("svg").attr("id",e).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg");return n&&a.attr("xmlns:xlink",n),a.append("g"),t};function _u(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}const bu=Object.freeze({render:async function(t,e,i){var r,n,o,a,s;au(),Bh();const l=Ic.detectInit(e);l&&(Ac(l),wh(l));const h=Th();Bs.debug(h),e.length>(null!=(r=null==h?void 0:h.maxTextSize)?r:5e4)&&(e="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa"),e=(e=e.replace(/\r\n?/g,"\n")).replace(/<(\w+)([^>]*)>/g,((t,e,i)=>"<"+e+i.replace(/="([^"]*)"/g,"='$1'")+">"));const c="#"+t,u="i"+t,d="#"+u,f="d"+t,p="#"+f;let g=je("body");const m="sandbox"===h.securityLevel,y="loose"===h.securityLevel,_=h.fontFamily;if(void 0!==i){if(i&&(i.innerHTML=""),m){const t=_u(je(i),u);g=je(t.nodes()[0].contentDocument.body),g.node().style.margin=0}else g=je(i);yu(g,t,f,`font-family: ${_}`,"http://www.w3.org/1999/xlink")}else{if(((t,e,i,r)=>{var n,o,a;null==(n=t.getElementById(e))||n.remove(),null==(o=t.getElementById(i))||o.remove(),null==(a=t.getElementById(r))||a.remove()})(document,t,f,u),m){const t=_u(je("body"),u);g=je(t.nodes()[0].contentDocument.body),g.node().style.margin=0}else g=je("body");yu(g,t,f)}let b,C;e=function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/classDef.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/#\w+;/g,(function(t){const e=t.substring(1,t.length-1);return/^\+?\d+$/.test(e)?"fl°°"+e+"¶ß":"fl°"+e+"¶ß"})),e}(e);try{b=await lu(e)}catch(A){b=new su("error"),C=A}const x=g.select(p).node(),k=b.type,v=x.firstChild,T=v.firstChild,S=uu.includes(k)?b.renderer.getClasses(e,b):{},w=mu(h,k,S,c),B=document.createElement("style");B.innerHTML=w,v.insertBefore(B,T);try{await b.renderer.draw(e,t,"10.2.0",b)}catch(E){throw Kc.draw(e,t,"10.2.0"),E}!function(t,e,i,r){(function(t,e){t.attr("role","graphics-document document"),Ss(e)||t.attr("aria-roledescription",e)})(e,t),function(t,e,i,r){if(void 0!==t.insert&&(e||i)){if(i){const e="chart-desc-"+r;t.attr("aria-describedby",e),t.insert("desc",":first-child").attr("id",e).text(i)}if(e){const i="chart-title-"+r;t.attr("aria-labelledby",i),t.insert("title",":first-child").attr("id",i).text(e)}}}(e,i,r,e.attr("id"))}(k,g.select(`${p} svg`),null==(o=(n=b.db).getAccTitle)?void 0:o.call(n),null==(s=(a=b.db).getAccDescription)?void 0:s.call(a)),g.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns","http://www.w3.org/1999/xhtml");let F=g.select(p).node().innerHTML;if(Bs.debug("config.arrowMarkerAbsolute",h.arrowMarkerAbsolute),F=((t="",e,i)=>{let r=t;return i||e||(r=r.replace(/marker-end="url\(.*?#/g,'marker-end="url(#')),r=pu(r),r=r.replace(/
    /g,"
    "),r})(F,m,Ns(h.arrowMarkerAbsolute)),m){F=((t="",e)=>``)(F,g.select(p+" svg").node())}else y||(F=Jn.sanitize(F,{ADD_TAGS:du,ADD_ATTR:fu}));if(hu.forEach((t=>{t()})),hu=[],C)throw C;const L=je(m?d:p).node();return L&&"remove"in L&&L.remove(),{svg:F,bindFunctions:b.db.bindFunctions}},parse:async function(t,e){au();try{(await lu(t)).parse()}catch(i){if(null==e?void 0:e.suppressErrors)return!1;throw i}return!0},parseDirective:Xh,getDiagramFromText:lu,initialize:function(t={}){var e;(null==t?void 0:t.fontFamily)&&!(null==(e=t.themeVariables)?void 0:e.fontFamily)&&(t.themeVariables||(t.themeVariables={}),t.themeVariables.fontFamily=t.fontFamily),yh=gh({},t),(null==t?void 0:t.theme)&&t.theme in Ps?t.themeVariables=Ps[t.theme].getThemeVariables(t.themeVariables):t&&(t.themeVariables=Ps.default.getThemeVariables(t.themeVariables));const i="object"==typeof t?(t=>(_h=gh({},mh),_h=gh(_h,t),t.theme&&Ps[t.theme]&&(_h.themeVariables=Ps[t.theme].getThemeVariables(t.themeVariables)),xh(_h,bh),_h))(t):kh();Fs(i.logLevel),au()},getConfig:Th,setConfig:vh,getSiteConfig:kh,updateSiteConfig:t=>(_h=gh(_h,t),xh(_h,bh),_h),reset:()=>{Bh()},globalReset:()=>{Bh(mh)},defaultConfig:mh});Fs(Th().logLevel),Bh(Th());const Cu=(t,s,l)=>{var h,c;Bs.warn(t),Mc(t)?(l&&l(t.str,t.hash),s.push((h=((t,e)=>{for(var i in e||(e={}))n.call(e,i)&&a(t,i,e[i]);if(r)for(var i of r(e))o.call(e,i)&&a(t,i,e[i]);return t})({},t),c={message:t.str,error:t},e(h,i(c))))):(l&&l(t),t instanceof Error&&s.push({str:t.message,message:t.message,hash:t.name,error:t}))},xu=async function(t={querySelector:".mermaid"}){try{await ku(t)}catch(e){if(Mc(e)&&Bs.error(e.str),Lu.parseError&&Lu.parseError(e),!t.suppressErrors)throw Bs.error("Use the suppressErrors option to suppress these errors"),e}},ku=async function({postRenderCallback:t,querySelector:e,nodes:i}={querySelector:".mermaid"}){const r=bu.getConfig();let n;if(Bs.debug((t?"":"No ")+"Callback function found"),i)n=i;else{if(!e)throw new Error("Nodes and querySelector are both undefined");n=document.querySelectorAll(e)}Bs.debug(`Found ${n.length} diagrams`),void 0!==(null==r?void 0:r.startOnLoad)&&(Bs.debug("Start On Load: "+(null==r?void 0:r.startOnLoad)),bu.updateSiteConfig({startOnLoad:null==r?void 0:r.startOnLoad}));const o=new Ic.initIdGenerator(r.deterministicIds,r.deterministicIDSeed);let a;const l=[];for(const c of Array.from(n)){ /*! Check if previously processed */ if(Bs.info("Rendering diagram: "+c.id),c.getAttribute("data-processed"))continue;c.setAttribute("data-processed","true");const e=`mermaid-${o.next()}`;a=c.innerHTML,a=s(Ic.entityDecode(a)).trim().replace(//gi,"
    ");const i=Ic.detectInit(a);i&&Bs.debug("Detected early reinit: ",i);try{const{svg:i,bindFunctions:r}=await Fu(e,a,c);c.innerHTML=i,t&&await t(e),r&&r(c)}catch(h){Cu(h,l,Lu.parseError)}}if(l.length>0)throw l[0]},vu=function(t){bu.initialize(t)},Tu=function(){if(Lu.startOnLoad){const{startOnLoad:t}=bu.getConfig();t&&Lu.run().catch((t=>Bs.error("Mermaid failed to initialize",t)))}};"undefined"!=typeof document&& /*! diff --git a/assets/mindmap-definition-74e4e806.1576bedb.js b/assets/mindmap-definition-74e4e806.83465c17.js similarity index 99% rename from assets/mindmap-definition-74e4e806.1576bedb.js rename to assets/mindmap-definition-74e4e806.83465c17.js index 2b2c0d091..c55a26801 100644 --- a/assets/mindmap-definition-74e4e806.1576bedb.js +++ b/assets/mindmap-definition-74e4e806.83465c17.js @@ -1,4 +1,4 @@ -import{d as e,c as t,l as n,h as r,t as i,aI as a,aJ as o,aK as s}from"./mermaid.core.a66200b0.js";import{c as l}from"./createText-2f679d62.584f3edd.js";import{Y as u,Z as c}from"./app.755d843f.js";var h,d={exports:{}},p=d.exports=function(){function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);nt?1:0},Z=function(e,t){return-1*K(e,t)},Q=null!=Object.assign?Object.assign.bind(Object):function(e){for(var t=arguments,n=1;n1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var c=new RegExp("^"+H+"$").exec(e);if(c){if((n=parseInt(c[1]))<0?n=(360- -1*n%360)%360:n>360&&(n%=360),n/=360,(r=parseFloat(c[2]))<0||r>100)return;if(r/=100,(i=parseFloat(c[3]))<0||i>100)return;if(i/=100,void 0!==(a=c[4])&&((a=parseFloat(a))<0||a>1))return;if(0===r)o=s=l=Math.round(255*i);else{var h=i<.5?i*(1+r):i+r-i*r,d=2*i-h;o=Math.round(255*u(d,h,n+1/3)),s=Math.round(255*u(d,h,n)),l=Math.round(255*u(d,h,n-1/3))}t=[o,s,l,a]}return t},te=function(e){var t,n=new RegExp("^"+U+"$").exec(e);if(n){t=[];for(var r=[],i=1;i<=3;i++){var a=n[i];if("%"===a[a.length-1]&&(r[i]=!0),a=parseFloat(a),r[i]&&(a=a/100*255),a<0||a>255)return;t.push(Math.floor(a))}var o=r[1]||r[2]||r[3],s=r[1]&&r[2]&&r[3];if(o&&!s)return;var l=n[4];if(void 0!==l){if((l=parseFloat(l))<0||l>1)return;t.push(l)}}return t},ne=function(e){return ie[e.toLowerCase()]},re=function(e){return(w(e)?e:null)||ne(e)||J(e)||te(e)||ee(e)},ie={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]},ae=function(e){for(var t=e.map,n=e.keys,r=n.length,i=0;i=t||n<0||h&&e-u>=a}function y(){var e=ge();if(v(e))return m(e);s=setTimeout(y,f(e))}function m(e){return s=void 0,d&&r?p(e):(r=i=void 0,o)}function b(){void 0!==s&&clearTimeout(s),u=0,r=l=i=s=void 0}function x(){return void 0===s?o:m(ge())}function w(){var e=ge(),n=v(e);if(r=arguments,i=this,l=e,n){if(void 0===s)return g(l);if(h)return clearTimeout(s),s=setTimeout(y,t),p(l)}return void 0===s&&(s=setTimeout(y,t)),o}return t=qe(t)||0,le(n)&&(c=!!n.leading,a=(h="maxWait"in n)?$e(qe(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),w.cancel=b,w.flush=x,w}var Qe=Ze,Je=d?d.performance:null,et=Je&&Je.now?function(){return Je.now()}:function(){return Date.now()},tt=function(){if(d){if(d.requestAnimationFrame)return function(e){d.requestAnimationFrame(e)};if(d.mozRequestAnimationFrame)return function(e){d.mozRequestAnimationFrame(e)};if(d.webkitRequestAnimationFrame)return function(e){d.webkitRequestAnimationFrame(e)};if(d.msRequestAnimationFrame)return function(e){d.msRequestAnimationFrame(e)}}return function(e){e&&setTimeout((function(){e(et())}),1e3/60)}}(),nt=function(e){return tt(e)},rt=et,it=9261,at=65599,ot=5381,st=function(e){for(var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:it;!(t=e.next()).done;)n=n*at+t.value|0;return n},lt=function(e){return(arguments.length>1&&void 0!==arguments[1]?arguments[1]:it)*at+e|0},ut=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ot;return(t<<5)+t+e|0},ct=function(e,t){return 2097152*e+t},ht=function(e){return 2097152*e[0]+e[1]},dt=function(e,t){return[lt(e[0],t[0]),ut(e[1],t[1])]},pt=function(e,t){var n={value:0,done:!1},r=0,i=e.length;return st({next:function(){return r=0&&(e[r]!==t||(e.splice(r,1),!n));r--);},Rt=function(e){e.splice(0,e.length)},Bt=function(e,t){for(var n=0;n2&&void 0!==arguments[2])||arguments[2];if(void 0!==e&&void 0!==t&&S(e)){var r=t.group;if(null==r&&(r=t.data&&null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"===r||"edges"===r){this.length=1,this[0]=this;var i=this._private={cy:e,single:!0,data:t.data||{},position:t.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:r,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!t.selected,selectable:void 0===t.selectable||!!t.selectable,locked:!!t.locked,grabbed:!1,grabbable:void 0===t.grabbable||!!t.grabbable,pannable:void 0===t.pannable?"edges"===r:!!t.pannable,active:!1,classes:new Ut,animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[],parent:t.parent&&t.parent.isNode()?t.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(null==i.position.x&&(i.position.x=0),null==i.position.y&&(i.position.y=0),t.renderedPosition){var a=t.renderedPosition,o=e.pan(),s=e.zoom();i.position={x:(a.x-o.x)/s,y:(a.y-o.y)/s}}var l=[];w(t.classes)?l=t.classes:b(t.classes)&&(l=t.classes.split(/\s+/));for(var u=0,c=l.length;ut?1:0},u=function(e,t,i,a,o){var s;if(null==i&&(i=0),null==o&&(o=n),i<0)throw new Error("lo must be non-negative");for(null==a&&(a=e.length);in;0<=n?t++:t--)u.push(t);return u}.apply(this).reverse()).length;af;0<=f?++d:--d)v.push(a(e,r));return v},g=function(e,t,r,i){var a,o,s;for(null==i&&(i=n),a=e[r];r>t&&i(a,o=e[s=r-1>>1])<0;)e[r]=o,r=s;return e[r]=a},f=function(e,t,r){var i,a,o,s,l;for(null==r&&(r=n),a=e.length,l=t,o=e[t],i=2*t+1;i0;){var T=y.pop(),_=f(T),D=T.id();if(h[D]=_,_!==1/0)for(var C=T.neighborhood().intersect(p),N=0;N0)for(n.unshift(t);c[i];){var a=c[i];n.unshift(a.edge),n.unshift(a.node),i=(r=a.node).id()}return o.spawn(n)}}}},Zt={kruskal:function(e){e=e||function(e){return 1};for(var t=this.byGroup(),n=t.nodes,r=t.edges,i=n.length,a=new Array(i),o=n,s=function(e){for(var t=0;t0;){if(x(),E++,u===h){for(var T=[],_=i,D=h,C=m[D];T.unshift(_),null!=C&&T.unshift(C),null!=(_=y[D]);)C=m[D=_.id()];return{found:!0,distance:d[u],path:this.spawn(T),steps:E}}g[u]=!0;for(var N=l._private.edges,A=0;AN&&(p[C]=N,y[C]=D,m[C]=w),!i){var A=D*u+_;!i&&p[A]>N&&(p[A]=N,y[A]=_,m[A]=w)}}}for(var L=0;L1&&void 0!==arguments[1]?arguments[1]:a,r=[],i=m(e);;){if(null==i)return t.spawn();var o=y(i),l=o.edge,u=o.pred;if(r.unshift(i[0]),i.same(n)&&r.length>0)break;null!=l&&r.unshift(l),i=u}return s.spawn(r)},E=0;E=0;u--){var c=l[u],h=c[1],d=c[2];(t[h]===o&&t[d]===s||t[h]===s&&t[d]===o)&&l.splice(u,1)}for(var p=0;pr;){var i=Math.floor(Math.random()*t.length);t=on(i,e,t),n--}return t},ln={kargerStein:function(){var e=this,t=this.byGroup(),n=t.nodes,r=t.edges;r.unmergeBy((function(e){return e.isLoop()}));var i=n.length,a=r.length,o=Math.ceil(Math.pow(Math.log(i)/Math.LN2,2)),s=Math.floor(i/an);if(!(i<2)){for(var l=[],u=0;u1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=1/0,i=t;i1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=-1/0,i=t;i1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=0,i=0,a=t;a1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];arguments.length>3&&void 0!==arguments[3]&&!arguments[3]?(n0&&e.splice(0,t)):e=e.slice(t,n);for(var a=0,o=e.length-1;o>=0;o--){var s=e[o];i?isFinite(s)||(e[o]=-1/0,a++):e.splice(o,1)}r&&e.sort((function(e,t){return e-t}));var l=e.length,u=Math.floor(l/2);return l%2!=0?e[u+1+a]:(e[u-1+a]+e[u+a])/2},yn=function(e){return Math.PI*e/180},mn=function(e,t){return Math.atan2(t,e)-Math.PI/2},bn=Math.log2||function(e){return Math.log(e)/Math.log(2)},xn=function(e){return e>0?1:e<0?-1:0},wn=function(e,t){return Math.sqrt(En(e,t))},En=function(e,t){var n=t.x-e.x,r=t.y-e.y;return n*n+r*r},Tn=function(e){for(var t=e.length,n=0,r=0;r=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(null!=e.w&&null!=e.h&&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}}},Ln=function(e){return{x1:e.x1,x2:e.x2,w:e.w,y1:e.y1,y2:e.y2,h:e.h}},Sn=function(e){e.x1=1/0,e.y1=1/0,e.x2=-1/0,e.y2=-1/0,e.w=0,e.h=0},On=function(e,t){e.x1=Math.min(e.x1,t.x1),e.x2=Math.max(e.x2,t.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,t.y1),e.y2=Math.max(e.y2,t.y2),e.h=e.y2-e.y1},In=function(e,t,n){e.x1=Math.min(e.x1,t),e.x2=Math.max(e.x2,t),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},kn=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.x1-=t,e.x2+=t,e.y1-=t,e.y2+=t,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},Mn=function(e){var t,n,r,i,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[0];if(1===o.length)t=n=r=i=o[0];else if(2===o.length)t=r=o[0],i=n=o[1];else if(4===o.length){var s=a(o,4);t=s[0],n=s[1],r=s[2],i=s[3]}return e.x1-=i,e.x2+=n,e.y1-=t,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},Pn=function(e,t){e.x1=t.x1,e.y1=t.y1,e.x2=t.x2,e.y2=t.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},Rn=function(e,t){return!(e.x1>t.x2||t.x1>e.x2||e.x2t.y2||t.y1>e.y2)},Bn=function(e,t,n){return e.x1<=t&&t<=e.x2&&e.y1<=n&&n<=e.y2},Fn=function(e,t){return Bn(e,t.x,t.y)},zn=function(e,t){return Bn(e,t.x1,t.y1)&&Bn(e,t.x2,t.y2)},Gn=function(e,t,n,r,i,a,o){var s,l=ur(i,a),u=i/2,c=a/2,h=r-c-o;if((s=nr(e,t,n,r,n-u+l-o,h,n+u-l+o,h,!1)).length>0)return s;var d=n+u+o;if((s=nr(e,t,n,r,d,r-c+l-o,d,r+c-l+o,!1)).length>0)return s;var p=r+c+o;if((s=nr(e,t,n,r,n-u+l-o,p,n+u-l+o,p,!1)).length>0)return s;var g,f=n-u-o;if((s=nr(e,t,n,r,f,r-c+l-o,f,r+c-l+o,!1)).length>0)return s;var v=n-u+l,y=r-c+l;if((g=er(e,t,n,r,v,y,l+o)).length>0&&g[0]<=v&&g[1]<=y)return[g[0],g[1]];var m=n+u-l,b=r-c+l;if((g=er(e,t,n,r,m,b,l+o)).length>0&&g[0]>=m&&g[1]<=b)return[g[0],g[1]];var x=n+u-l,w=r+c-l;if((g=er(e,t,n,r,x,w,l+o)).length>0&&g[0]>=x&&g[1]>=w)return[g[0],g[1]];var E=n-u+l,T=r+c-l;return(g=er(e,t,n,r,E,T,l+o)).length>0&&g[0]<=E&&g[1]>=T?[g[0],g[1]]:[]},Yn=function(e,t,n,r,i,a,o){var s=o,l=Math.min(n,i),u=Math.max(n,i),c=Math.min(r,a),h=Math.max(r,a);return l-s<=e&&e<=u+s&&c-s<=t&&t<=h+s},Xn=function(e,t,n,r,i,a,o,s,l){var u={x1:Math.min(n,o,i)-l,x2:Math.max(n,o,i)+l,y1:Math.min(r,s,a)-l,y2:Math.max(r,s,a)+l};return!(eu.x2||tu.y2)},Vn=function(e,t,n,r){var i=t*t-4*e*(n-=r);if(i<0)return[];var a=Math.sqrt(i),o=2*e;return[(-t+a)/o,(-t-a)/o]},Un=function(e,t,n,r,i){var a,o,s,l,u,c,h,d;return 0===e&&(e=1e-5),s=-27*(r/=e)+(t/=e)*(9*(n/=e)-t*t*2),a=(o=(3*n-t*t)/9)*o*o+(s/=54)*s,i[1]=0,h=t/3,a>0?(u=(u=s+Math.sqrt(a))<0?-Math.pow(-u,1/3):Math.pow(u,1/3),c=(c=s-Math.sqrt(a))<0?-Math.pow(-c,1/3):Math.pow(c,1/3),i[0]=-h+u+c,h+=(u+c)/2,i[4]=i[2]=-h,h=Math.sqrt(3)*(-c+u)/2,i[3]=h,void(i[5]=-h)):(i[5]=i[3]=0,0===a?(d=s<0?-Math.pow(-s,1/3):Math.pow(s,1/3),i[0]=2*d-h,void(i[4]=i[2]=-(d+h))):(l=(o=-o)*o*o,l=Math.acos(s/Math.sqrt(l)),d=2*Math.sqrt(o),i[0]=-h+d*Math.cos(l/3),i[2]=-h+d*Math.cos((l+2*Math.PI)/3),void(i[4]=-h+d*Math.cos((l+4*Math.PI)/3))))},jn=function(e,t,n,r,i,a,o,s){var l=[];Un(1*n*n-4*n*i+2*n*o+4*i*i-4*i*o+o*o+r*r-4*r*a+2*r*s+4*a*a-4*a*s+s*s,9*n*i-3*n*n-3*n*o-6*i*i+3*i*o+9*r*a-3*r*r-3*r*s-6*a*a+3*a*s,3*n*n-6*n*i+n*o-n*e+2*i*i+2*i*e-o*e+3*r*r-6*r*a+r*s-r*t+2*a*a+2*a*t-s*t,1*n*i-n*n+n*e-i*e+r*a-r*r+r*t-a*t,l);for(var u=1e-7,c=[],h=0;h<6;h+=2)Math.abs(l[h+1])=0&&l[h]<=1&&c.push(l[h]);c.push(1),c.push(0);for(var d,p,g,f=-1,v=0;v=0?gl?(e-i)*(e-i)+(t-a)*(t-a):u-h},qn=function(e,t,n){for(var r,i,a,o,s=0,l=0;l=e&&e>=a||r<=e&&e<=a))continue;(e-r)/(a-r)*(o-i)+i>t&&s++}return s%2!=0},Wn=function(e,t,n,r,i,a,o,s,l){var u,c=new Array(n.length);null!=s[0]?(u=Math.atan(s[1]/s[0]),s[0]<0?u+=Math.PI/2:u=-u-Math.PI/2):u=s;for(var h,d=Math.cos(-u),p=Math.sin(-u),g=0;g0){var f=Zn(c,-l);h=Kn(f)}else h=c;return qn(e,t,h)},$n=function(e,t,n,r,i,a,o){for(var s=new Array(n.length),l=a/2,u=o/2,c=cr(a,o),h=c*c,d=0;d=0&&g<=1&&v.push(g),f>=0&&f<=1&&v.push(f),0===v.length)return[];var y=v[0]*s[0]+e,m=v[0]*s[1]+t;return v.length>1?v[0]==v[1]?[y,m]:[y,m,v[1]*s[0]+e,v[1]*s[1]+t]:[y,m]},tr=function(e,t,n){return t<=e&&e<=n||n<=e&&e<=t?e:e<=t&&t<=n||n<=t&&t<=e?t:n},nr=function(e,t,n,r,i,a,o,s,l){var u=e-i,c=n-e,h=o-i,d=t-a,p=r-t,g=s-a,f=h*d-g*u,v=c*d-p*u,y=g*c-h*p;if(0!==y){var m=f/y,b=v/y,x=.001,w=0-x,E=1+x;return w<=m&&m<=E&&w<=b&&b<=E||l?[e+m*c,t+m*p]:[]}return 0===f||0===v?tr(e,n,o)===o?[o,s]:tr(e,n,i)===i?[i,a]:tr(i,o,n)===n?[n,r]:[]:[]},rr=function(e,t,n,r,i,a,o,s){var l,u,c,h,d,p,g=[],f=new Array(n.length),v=!0;if(null==a&&(v=!1),v){for(var y=0;y0){var m=Zn(f,-s);u=Kn(m)}else u=f}else u=n;for(var b=0;b2){for(var A=[u[0],u[1]],L=Math.pow(A[0]-e,2)+Math.pow(A[1]-t,2),S=1;Su&&(u=t)},get:function(e){return l[e]}},h=0;h0?m.edgesTo(y)[0]:y.edgesTo(m)[0];var x=r(b);y=y.id(),h[y]>h[f]+x&&(h[y]=h[f]+x,d.nodes.indexOf(y)<0?d.push(y):d.updateItem(y),u[y]=0,l[y]=[]),h[y]==h[f]+x&&(u[y]=u[y]+u[f],l[y].push(f))}else for(var w=0;w0;){for(var D=n.pop(),C=0;C0&&o.push(n[s]);0!==o.length&&i.push(r.collection(o))}return i},Ir=function(e,t){for(var n=0;n5&&void 0!==arguments[5]?arguments[5]:Rr,o=r,s=0;s=2?Xr(e,t,n,0,zr,Gr):Xr(e,t,n,0,Fr)},squaredEuclidean:function(e,t,n){return Xr(e,t,n,0,zr)},manhattan:function(e,t,n){return Xr(e,t,n,0,Fr)},max:function(e,t,n){return Xr(e,t,n,-1/0,Yr)}};function Ur(e,t,n,r,i,a){var o;return o=x(e)?e:Vr[e]||Vr.euclidean,0===t&&x(e)?o(i,a):o(t,n,r,i,a)}Vr["squared-euclidean"]=Vr.squaredEuclidean,Vr.squaredeuclidean=Vr.squaredEuclidean;var jr=Mt({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),Hr=function(e){return jr(e)},qr=function(e,t,n,r,i){var a="kMedoids"!==i?function(e){return n[e]}:function(e){return r[e](n)},o=function(e){return r[e](t)},s=n,l=t;return Ur(e,r.length,a,o,s,l)},Wr=function(e,t,n){for(var r=n.length,i=new Array(r),a=new Array(r),o=new Array(t),s=null,l=0;ln)return!1;return!0},Jr=function(e,t,n){for(var r=0;ri&&(i=t[l][u],a=u);o[a].push(e[l])}for(var c=0;c=i.threshold||"dendrogram"===i.mode&&1===e.length)return!1;var p,g=t[o],f=t[r[o]];p="dendrogram"===i.mode?{left:g,right:f,key:g.key}:{value:g.value.concat(f.value),key:g.key},e[g.index]=p,e.splice(f.index,1),t[g.key]=p;for(var v=0;vn[f.key][y.key]&&(a=n[f.key][y.key])):"max"===i.linkage?(a=n[g.key][y.key],n[g.key][y.key]0&&r.push(i);return r},wi=function(e,t,n){for(var r=[],i=0;io&&(a=l,o=t[i*e+l])}a>0&&r.push(a)}for(var u=0;ul&&(s=u,l=c)}n[i]=a[s]}return r=wi(e,t,n)},Ti=function(e){for(var t,n,r,i,a,o,s=this.cy(),l=this.nodes(),u=yi(e),c={},h=0;h=C?(N=C,C=L,A=S):L>N&&(N=L);for(var O=0;O0?1:0;T[E%u.minIterations*t+B]=F,R+=F}if(R>0&&(E>=u.minIterations-1||E==u.maxIterations-1)){for(var z=0,G=0;G1)}}));var u=Object.keys(t).filter((function(e){return t[e].cutVertex})).map((function(t){return e.getElementById(t)}));return{cut:e.spawn(u),components:i}},Ni=function(){var e=this,t={},n=0,r=[],i=[],a=e.spawn(e),o=function o(s){if(i.push(s),t[s]={index:n,low:n++,explored:!1},e.getElementById(s).connectedEdges().intersection(e).forEach((function(e){var n=e.target().id();n!==s&&(n in t||o(n),t[n].explored||(t[s].low=Math.min(t[s].low,t[n].low)))})),t[s].index===t[s].low){for(var l=e.spawn();;){var u=i.pop();if(l.merge(e.getElementById(u)),t[u].low=t[s].index,t[u].explored=!0,u===s)break}var c=l.edgesWith(l),h=l.merge(c);r.push(h),a=a.difference(h)}};return e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||o(n)}})),{cut:a,components:r}},Ai={};[qt,Kt,Zt,Jt,tn,rn,ln,fr,yr,br,wr,Pr,oi,fi,_i,{hierholzer:function(e){if(!E(e)){var t=arguments;e={root:t[0],directed:t[1]}}var n,r,i,a=Di(e),o=a.root,s=a.directed,l=this,u=!1;o&&(i=b(o)?this.filter(o)[0].id():o[0].id());var c={},h={};s?l.forEach((function(e){var t=e.id();if(e.isNode()){var i=e.indegree(!0),a=e.outdegree(!0),o=i-a,s=a-i;1==o?n?u=!0:n=t:1==s?r?u=!0:r=t:(s>1||o>1)&&(u=!0),c[t]=[],e.outgoers().forEach((function(e){e.isEdge()&&c[t].push(e.id())}))}else h[t]=[void 0,e.target().id()]})):l.forEach((function(e){var t=e.id();e.isNode()?(e.degree(!0)%2&&(n?r?u=!0:r=t:n=t),c[t]=[],e.connectedEdges().forEach((function(e){return c[t].push(e.id())}))):h[t]=[e.source().id(),e.target().id()]}));var d={found:!1,trail:void 0};if(u)return d;if(r&&n)if(s){if(i&&r!=i)return d;i=r}else{if(i&&r!=i&&n!=i)return d;i||(i=r)}else i||(i=l[0].id());var p=function(e){for(var t,n,r,i=e,a=[e];c[i].length;)t=c[i].shift(),n=h[t][0],i!=(r=h[t][1])?(c[r]=c[r].filter((function(e){return e!=t})),i=r):s||i==n||(c[n]=c[n].filter((function(e){return e!=t})),i=n),a.unshift(t),a.unshift(i);return a},g=[],f=[];for(f=p(i);1!=f.length;)0==c[f[0]].length?(g.unshift(l.getElementById(f.shift())),g.unshift(l.getElementById(f.shift()))):f=p(f.shift()).concat(f);for(var v in g.unshift(l.getElementById(f.shift())),c)if(c[v].length)return d;return d.found=!0,d.trail=this.spawn(g,!0),d}},{hopcroftTarjanBiconnected:Ci,htbc:Ci,htb:Ci,hopcroftTarjanBiconnectedComponents:Ci},{tarjanStronglyConnected:Ni,tsc:Ni,tscc:Ni,tarjanStronglyConnectedComponents:Ni}].forEach((function(e){Q(Ai,e)})); +import{d as e,c as t,l as n,h as r,t as i,aI as a,aJ as o,aK as s}from"./mermaid.core.3a590193.js";import{c as l}from"./createText-2f679d62.a374f608.js";import{Y as u,Z as c}from"./app.48111a85.js";var h,d={exports:{}},p=d.exports=function(){function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);nt?1:0},Z=function(e,t){return-1*K(e,t)},Q=null!=Object.assign?Object.assign.bind(Object):function(e){for(var t=arguments,n=1;n1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var c=new RegExp("^"+H+"$").exec(e);if(c){if((n=parseInt(c[1]))<0?n=(360- -1*n%360)%360:n>360&&(n%=360),n/=360,(r=parseFloat(c[2]))<0||r>100)return;if(r/=100,(i=parseFloat(c[3]))<0||i>100)return;if(i/=100,void 0!==(a=c[4])&&((a=parseFloat(a))<0||a>1))return;if(0===r)o=s=l=Math.round(255*i);else{var h=i<.5?i*(1+r):i+r-i*r,d=2*i-h;o=Math.round(255*u(d,h,n+1/3)),s=Math.round(255*u(d,h,n)),l=Math.round(255*u(d,h,n-1/3))}t=[o,s,l,a]}return t},te=function(e){var t,n=new RegExp("^"+U+"$").exec(e);if(n){t=[];for(var r=[],i=1;i<=3;i++){var a=n[i];if("%"===a[a.length-1]&&(r[i]=!0),a=parseFloat(a),r[i]&&(a=a/100*255),a<0||a>255)return;t.push(Math.floor(a))}var o=r[1]||r[2]||r[3],s=r[1]&&r[2]&&r[3];if(o&&!s)return;var l=n[4];if(void 0!==l){if((l=parseFloat(l))<0||l>1)return;t.push(l)}}return t},ne=function(e){return ie[e.toLowerCase()]},re=function(e){return(w(e)?e:null)||ne(e)||J(e)||te(e)||ee(e)},ie={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]},ae=function(e){for(var t=e.map,n=e.keys,r=n.length,i=0;i=t||n<0||h&&e-u>=a}function y(){var e=ge();if(v(e))return m(e);s=setTimeout(y,f(e))}function m(e){return s=void 0,d&&r?p(e):(r=i=void 0,o)}function b(){void 0!==s&&clearTimeout(s),u=0,r=l=i=s=void 0}function x(){return void 0===s?o:m(ge())}function w(){var e=ge(),n=v(e);if(r=arguments,i=this,l=e,n){if(void 0===s)return g(l);if(h)return clearTimeout(s),s=setTimeout(y,t),p(l)}return void 0===s&&(s=setTimeout(y,t)),o}return t=qe(t)||0,le(n)&&(c=!!n.leading,a=(h="maxWait"in n)?$e(qe(n.maxWait)||0,t):a,d="trailing"in n?!!n.trailing:d),w.cancel=b,w.flush=x,w}var Qe=Ze,Je=d?d.performance:null,et=Je&&Je.now?function(){return Je.now()}:function(){return Date.now()},tt=function(){if(d){if(d.requestAnimationFrame)return function(e){d.requestAnimationFrame(e)};if(d.mozRequestAnimationFrame)return function(e){d.mozRequestAnimationFrame(e)};if(d.webkitRequestAnimationFrame)return function(e){d.webkitRequestAnimationFrame(e)};if(d.msRequestAnimationFrame)return function(e){d.msRequestAnimationFrame(e)}}return function(e){e&&setTimeout((function(){e(et())}),1e3/60)}}(),nt=function(e){return tt(e)},rt=et,it=9261,at=65599,ot=5381,st=function(e){for(var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:it;!(t=e.next()).done;)n=n*at+t.value|0;return n},lt=function(e){return(arguments.length>1&&void 0!==arguments[1]?arguments[1]:it)*at+e|0},ut=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:ot;return(t<<5)+t+e|0},ct=function(e,t){return 2097152*e+t},ht=function(e){return 2097152*e[0]+e[1]},dt=function(e,t){return[lt(e[0],t[0]),ut(e[1],t[1])]},pt=function(e,t){var n={value:0,done:!1},r=0,i=e.length;return st({next:function(){return r=0&&(e[r]!==t||(e.splice(r,1),!n));r--);},Rt=function(e){e.splice(0,e.length)},Bt=function(e,t){for(var n=0;n2&&void 0!==arguments[2])||arguments[2];if(void 0!==e&&void 0!==t&&S(e)){var r=t.group;if(null==r&&(r=t.data&&null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"===r||"edges"===r){this.length=1,this[0]=this;var i=this._private={cy:e,single:!0,data:t.data||{},position:t.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:r,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!t.selected,selectable:void 0===t.selectable||!!t.selectable,locked:!!t.locked,grabbed:!1,grabbable:void 0===t.grabbable||!!t.grabbable,pannable:void 0===t.pannable?"edges"===r:!!t.pannable,active:!1,classes:new Ut,animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[],parent:t.parent&&t.parent.isNode()?t.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(null==i.position.x&&(i.position.x=0),null==i.position.y&&(i.position.y=0),t.renderedPosition){var a=t.renderedPosition,o=e.pan(),s=e.zoom();i.position={x:(a.x-o.x)/s,y:(a.y-o.y)/s}}var l=[];w(t.classes)?l=t.classes:b(t.classes)&&(l=t.classes.split(/\s+/));for(var u=0,c=l.length;ut?1:0},u=function(e,t,i,a,o){var s;if(null==i&&(i=0),null==o&&(o=n),i<0)throw new Error("lo must be non-negative");for(null==a&&(a=e.length);in;0<=n?t++:t--)u.push(t);return u}.apply(this).reverse()).length;af;0<=f?++d:--d)v.push(a(e,r));return v},g=function(e,t,r,i){var a,o,s;for(null==i&&(i=n),a=e[r];r>t&&i(a,o=e[s=r-1>>1])<0;)e[r]=o,r=s;return e[r]=a},f=function(e,t,r){var i,a,o,s,l;for(null==r&&(r=n),a=e.length,l=t,o=e[t],i=2*t+1;i0;){var T=y.pop(),_=f(T),D=T.id();if(h[D]=_,_!==1/0)for(var C=T.neighborhood().intersect(p),N=0;N0)for(n.unshift(t);c[i];){var a=c[i];n.unshift(a.edge),n.unshift(a.node),i=(r=a.node).id()}return o.spawn(n)}}}},Zt={kruskal:function(e){e=e||function(e){return 1};for(var t=this.byGroup(),n=t.nodes,r=t.edges,i=n.length,a=new Array(i),o=n,s=function(e){for(var t=0;t0;){if(x(),E++,u===h){for(var T=[],_=i,D=h,C=m[D];T.unshift(_),null!=C&&T.unshift(C),null!=(_=y[D]);)C=m[D=_.id()];return{found:!0,distance:d[u],path:this.spawn(T),steps:E}}g[u]=!0;for(var N=l._private.edges,A=0;AN&&(p[C]=N,y[C]=D,m[C]=w),!i){var A=D*u+_;!i&&p[A]>N&&(p[A]=N,y[A]=_,m[A]=w)}}}for(var L=0;L1&&void 0!==arguments[1]?arguments[1]:a,r=[],i=m(e);;){if(null==i)return t.spawn();var o=y(i),l=o.edge,u=o.pred;if(r.unshift(i[0]),i.same(n)&&r.length>0)break;null!=l&&r.unshift(l),i=u}return s.spawn(r)},E=0;E=0;u--){var c=l[u],h=c[1],d=c[2];(t[h]===o&&t[d]===s||t[h]===s&&t[d]===o)&&l.splice(u,1)}for(var p=0;pr;){var i=Math.floor(Math.random()*t.length);t=on(i,e,t),n--}return t},ln={kargerStein:function(){var e=this,t=this.byGroup(),n=t.nodes,r=t.edges;r.unmergeBy((function(e){return e.isLoop()}));var i=n.length,a=r.length,o=Math.ceil(Math.pow(Math.log(i)/Math.LN2,2)),s=Math.floor(i/an);if(!(i<2)){for(var l=[],u=0;u1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=1/0,i=t;i1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=-1/0,i=t;i1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=0,i=0,a=t;a1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];arguments.length>3&&void 0!==arguments[3]&&!arguments[3]?(n0&&e.splice(0,t)):e=e.slice(t,n);for(var a=0,o=e.length-1;o>=0;o--){var s=e[o];i?isFinite(s)||(e[o]=-1/0,a++):e.splice(o,1)}r&&e.sort((function(e,t){return e-t}));var l=e.length,u=Math.floor(l/2);return l%2!=0?e[u+1+a]:(e[u-1+a]+e[u+a])/2},yn=function(e){return Math.PI*e/180},mn=function(e,t){return Math.atan2(t,e)-Math.PI/2},bn=Math.log2||function(e){return Math.log(e)/Math.log(2)},xn=function(e){return e>0?1:e<0?-1:0},wn=function(e,t){return Math.sqrt(En(e,t))},En=function(e,t){var n=t.x-e.x,r=t.y-e.y;return n*n+r*r},Tn=function(e){for(var t=e.length,n=0,r=0;r=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(null!=e.w&&null!=e.h&&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}}},Ln=function(e){return{x1:e.x1,x2:e.x2,w:e.w,y1:e.y1,y2:e.y2,h:e.h}},Sn=function(e){e.x1=1/0,e.y1=1/0,e.x2=-1/0,e.y2=-1/0,e.w=0,e.h=0},On=function(e,t){e.x1=Math.min(e.x1,t.x1),e.x2=Math.max(e.x2,t.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,t.y1),e.y2=Math.max(e.y2,t.y2),e.h=e.y2-e.y1},In=function(e,t,n){e.x1=Math.min(e.x1,t),e.x2=Math.max(e.x2,t),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},kn=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.x1-=t,e.x2+=t,e.y1-=t,e.y2+=t,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},Mn=function(e){var t,n,r,i,o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[0];if(1===o.length)t=n=r=i=o[0];else if(2===o.length)t=r=o[0],i=n=o[1];else if(4===o.length){var s=a(o,4);t=s[0],n=s[1],r=s[2],i=s[3]}return e.x1-=i,e.x2+=n,e.y1-=t,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},Pn=function(e,t){e.x1=t.x1,e.y1=t.y1,e.x2=t.x2,e.y2=t.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},Rn=function(e,t){return!(e.x1>t.x2||t.x1>e.x2||e.x2t.y2||t.y1>e.y2)},Bn=function(e,t,n){return e.x1<=t&&t<=e.x2&&e.y1<=n&&n<=e.y2},Fn=function(e,t){return Bn(e,t.x,t.y)},zn=function(e,t){return Bn(e,t.x1,t.y1)&&Bn(e,t.x2,t.y2)},Gn=function(e,t,n,r,i,a,o){var s,l=ur(i,a),u=i/2,c=a/2,h=r-c-o;if((s=nr(e,t,n,r,n-u+l-o,h,n+u-l+o,h,!1)).length>0)return s;var d=n+u+o;if((s=nr(e,t,n,r,d,r-c+l-o,d,r+c-l+o,!1)).length>0)return s;var p=r+c+o;if((s=nr(e,t,n,r,n-u+l-o,p,n+u-l+o,p,!1)).length>0)return s;var g,f=n-u-o;if((s=nr(e,t,n,r,f,r-c+l-o,f,r+c-l+o,!1)).length>0)return s;var v=n-u+l,y=r-c+l;if((g=er(e,t,n,r,v,y,l+o)).length>0&&g[0]<=v&&g[1]<=y)return[g[0],g[1]];var m=n+u-l,b=r-c+l;if((g=er(e,t,n,r,m,b,l+o)).length>0&&g[0]>=m&&g[1]<=b)return[g[0],g[1]];var x=n+u-l,w=r+c-l;if((g=er(e,t,n,r,x,w,l+o)).length>0&&g[0]>=x&&g[1]>=w)return[g[0],g[1]];var E=n-u+l,T=r+c-l;return(g=er(e,t,n,r,E,T,l+o)).length>0&&g[0]<=E&&g[1]>=T?[g[0],g[1]]:[]},Yn=function(e,t,n,r,i,a,o){var s=o,l=Math.min(n,i),u=Math.max(n,i),c=Math.min(r,a),h=Math.max(r,a);return l-s<=e&&e<=u+s&&c-s<=t&&t<=h+s},Xn=function(e,t,n,r,i,a,o,s,l){var u={x1:Math.min(n,o,i)-l,x2:Math.max(n,o,i)+l,y1:Math.min(r,s,a)-l,y2:Math.max(r,s,a)+l};return!(eu.x2||tu.y2)},Vn=function(e,t,n,r){var i=t*t-4*e*(n-=r);if(i<0)return[];var a=Math.sqrt(i),o=2*e;return[(-t+a)/o,(-t-a)/o]},Un=function(e,t,n,r,i){var a,o,s,l,u,c,h,d;return 0===e&&(e=1e-5),s=-27*(r/=e)+(t/=e)*(9*(n/=e)-t*t*2),a=(o=(3*n-t*t)/9)*o*o+(s/=54)*s,i[1]=0,h=t/3,a>0?(u=(u=s+Math.sqrt(a))<0?-Math.pow(-u,1/3):Math.pow(u,1/3),c=(c=s-Math.sqrt(a))<0?-Math.pow(-c,1/3):Math.pow(c,1/3),i[0]=-h+u+c,h+=(u+c)/2,i[4]=i[2]=-h,h=Math.sqrt(3)*(-c+u)/2,i[3]=h,void(i[5]=-h)):(i[5]=i[3]=0,0===a?(d=s<0?-Math.pow(-s,1/3):Math.pow(s,1/3),i[0]=2*d-h,void(i[4]=i[2]=-(d+h))):(l=(o=-o)*o*o,l=Math.acos(s/Math.sqrt(l)),d=2*Math.sqrt(o),i[0]=-h+d*Math.cos(l/3),i[2]=-h+d*Math.cos((l+2*Math.PI)/3),void(i[4]=-h+d*Math.cos((l+4*Math.PI)/3))))},jn=function(e,t,n,r,i,a,o,s){var l=[];Un(1*n*n-4*n*i+2*n*o+4*i*i-4*i*o+o*o+r*r-4*r*a+2*r*s+4*a*a-4*a*s+s*s,9*n*i-3*n*n-3*n*o-6*i*i+3*i*o+9*r*a-3*r*r-3*r*s-6*a*a+3*a*s,3*n*n-6*n*i+n*o-n*e+2*i*i+2*i*e-o*e+3*r*r-6*r*a+r*s-r*t+2*a*a+2*a*t-s*t,1*n*i-n*n+n*e-i*e+r*a-r*r+r*t-a*t,l);for(var u=1e-7,c=[],h=0;h<6;h+=2)Math.abs(l[h+1])=0&&l[h]<=1&&c.push(l[h]);c.push(1),c.push(0);for(var d,p,g,f=-1,v=0;v=0?gl?(e-i)*(e-i)+(t-a)*(t-a):u-h},qn=function(e,t,n){for(var r,i,a,o,s=0,l=0;l=e&&e>=a||r<=e&&e<=a))continue;(e-r)/(a-r)*(o-i)+i>t&&s++}return s%2!=0},Wn=function(e,t,n,r,i,a,o,s,l){var u,c=new Array(n.length);null!=s[0]?(u=Math.atan(s[1]/s[0]),s[0]<0?u+=Math.PI/2:u=-u-Math.PI/2):u=s;for(var h,d=Math.cos(-u),p=Math.sin(-u),g=0;g0){var f=Zn(c,-l);h=Kn(f)}else h=c;return qn(e,t,h)},$n=function(e,t,n,r,i,a,o){for(var s=new Array(n.length),l=a/2,u=o/2,c=cr(a,o),h=c*c,d=0;d=0&&g<=1&&v.push(g),f>=0&&f<=1&&v.push(f),0===v.length)return[];var y=v[0]*s[0]+e,m=v[0]*s[1]+t;return v.length>1?v[0]==v[1]?[y,m]:[y,m,v[1]*s[0]+e,v[1]*s[1]+t]:[y,m]},tr=function(e,t,n){return t<=e&&e<=n||n<=e&&e<=t?e:e<=t&&t<=n||n<=t&&t<=e?t:n},nr=function(e,t,n,r,i,a,o,s,l){var u=e-i,c=n-e,h=o-i,d=t-a,p=r-t,g=s-a,f=h*d-g*u,v=c*d-p*u,y=g*c-h*p;if(0!==y){var m=f/y,b=v/y,x=.001,w=0-x,E=1+x;return w<=m&&m<=E&&w<=b&&b<=E||l?[e+m*c,t+m*p]:[]}return 0===f||0===v?tr(e,n,o)===o?[o,s]:tr(e,n,i)===i?[i,a]:tr(i,o,n)===n?[n,r]:[]:[]},rr=function(e,t,n,r,i,a,o,s){var l,u,c,h,d,p,g=[],f=new Array(n.length),v=!0;if(null==a&&(v=!1),v){for(var y=0;y0){var m=Zn(f,-s);u=Kn(m)}else u=f}else u=n;for(var b=0;b2){for(var A=[u[0],u[1]],L=Math.pow(A[0]-e,2)+Math.pow(A[1]-t,2),S=1;Su&&(u=t)},get:function(e){return l[e]}},h=0;h0?m.edgesTo(y)[0]:y.edgesTo(m)[0];var x=r(b);y=y.id(),h[y]>h[f]+x&&(h[y]=h[f]+x,d.nodes.indexOf(y)<0?d.push(y):d.updateItem(y),u[y]=0,l[y]=[]),h[y]==h[f]+x&&(u[y]=u[y]+u[f],l[y].push(f))}else for(var w=0;w0;){for(var D=n.pop(),C=0;C0&&o.push(n[s]);0!==o.length&&i.push(r.collection(o))}return i},Ir=function(e,t){for(var n=0;n5&&void 0!==arguments[5]?arguments[5]:Rr,o=r,s=0;s=2?Xr(e,t,n,0,zr,Gr):Xr(e,t,n,0,Fr)},squaredEuclidean:function(e,t,n){return Xr(e,t,n,0,zr)},manhattan:function(e,t,n){return Xr(e,t,n,0,Fr)},max:function(e,t,n){return Xr(e,t,n,-1/0,Yr)}};function Ur(e,t,n,r,i,a){var o;return o=x(e)?e:Vr[e]||Vr.euclidean,0===t&&x(e)?o(i,a):o(t,n,r,i,a)}Vr["squared-euclidean"]=Vr.squaredEuclidean,Vr.squaredeuclidean=Vr.squaredEuclidean;var jr=Mt({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),Hr=function(e){return jr(e)},qr=function(e,t,n,r,i){var a="kMedoids"!==i?function(e){return n[e]}:function(e){return r[e](n)},o=function(e){return r[e](t)},s=n,l=t;return Ur(e,r.length,a,o,s,l)},Wr=function(e,t,n){for(var r=n.length,i=new Array(r),a=new Array(r),o=new Array(t),s=null,l=0;ln)return!1;return!0},Jr=function(e,t,n){for(var r=0;ri&&(i=t[l][u],a=u);o[a].push(e[l])}for(var c=0;c=i.threshold||"dendrogram"===i.mode&&1===e.length)return!1;var p,g=t[o],f=t[r[o]];p="dendrogram"===i.mode?{left:g,right:f,key:g.key}:{value:g.value.concat(f.value),key:g.key},e[g.index]=p,e.splice(f.index,1),t[g.key]=p;for(var v=0;vn[f.key][y.key]&&(a=n[f.key][y.key])):"max"===i.linkage?(a=n[g.key][y.key],n[g.key][y.key]0&&r.push(i);return r},wi=function(e,t,n){for(var r=[],i=0;io&&(a=l,o=t[i*e+l])}a>0&&r.push(a)}for(var u=0;ul&&(s=u,l=c)}n[i]=a[s]}return r=wi(e,t,n)},Ti=function(e){for(var t,n,r,i,a,o,s=this.cy(),l=this.nodes(),u=yi(e),c={},h=0;h=C?(N=C,C=L,A=S):L>N&&(N=L);for(var O=0;O0?1:0;T[E%u.minIterations*t+B]=F,R+=F}if(R>0&&(E>=u.minIterations-1||E==u.maxIterations-1)){for(var z=0,G=0;G1)}}));var u=Object.keys(t).filter((function(e){return t[e].cutVertex})).map((function(t){return e.getElementById(t)}));return{cut:e.spawn(u),components:i}},Ni=function(){var e=this,t={},n=0,r=[],i=[],a=e.spawn(e),o=function o(s){if(i.push(s),t[s]={index:n,low:n++,explored:!1},e.getElementById(s).connectedEdges().intersection(e).forEach((function(e){var n=e.target().id();n!==s&&(n in t||o(n),t[n].explored||(t[s].low=Math.min(t[s].low,t[n].low)))})),t[s].index===t[s].low){for(var l=e.spawn();;){var u=i.pop();if(l.merge(e.getElementById(u)),t[u].low=t[s].index,t[u].explored=!0,u===s)break}var c=l.edgesWith(l),h=l.merge(c);r.push(h),a=a.difference(h)}};return e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||o(n)}})),{cut:a,components:r}},Ai={};[qt,Kt,Zt,Jt,tn,rn,ln,fr,yr,br,wr,Pr,oi,fi,_i,{hierholzer:function(e){if(!E(e)){var t=arguments;e={root:t[0],directed:t[1]}}var n,r,i,a=Di(e),o=a.root,s=a.directed,l=this,u=!1;o&&(i=b(o)?this.filter(o)[0].id():o[0].id());var c={},h={};s?l.forEach((function(e){var t=e.id();if(e.isNode()){var i=e.indegree(!0),a=e.outdegree(!0),o=i-a,s=a-i;1==o?n?u=!0:n=t:1==s?r?u=!0:r=t:(s>1||o>1)&&(u=!0),c[t]=[],e.outgoers().forEach((function(e){e.isEdge()&&c[t].push(e.id())}))}else h[t]=[void 0,e.target().id()]})):l.forEach((function(e){var t=e.id();e.isNode()?(e.degree(!0)%2&&(n?r?u=!0:r=t:n=t),c[t]=[],e.connectedEdges().forEach((function(e){return c[t].push(e.id())}))):h[t]=[e.source().id(),e.target().id()]}));var d={found:!1,trail:void 0};if(u)return d;if(r&&n)if(s){if(i&&r!=i)return d;i=r}else{if(i&&r!=i&&n!=i)return d;i||(i=r)}else i||(i=l[0].id());var p=function(e){for(var t,n,r,i=e,a=[e];c[i].length;)t=c[i].shift(),n=h[t][0],i!=(r=h[t][1])?(c[r]=c[r].filter((function(e){return e!=t})),i=r):s||i==n||(c[n]=c[n].filter((function(e){return e!=t})),i=n),a.unshift(t),a.unshift(i);return a},g=[],f=[];for(f=p(i);1!=f.length;)0==c[f[0]].length?(g.unshift(l.getElementById(f.shift())),g.unshift(l.getElementById(f.shift()))):f=p(f.shift()).concat(f);for(var v in g.unshift(l.getElementById(f.shift())),c)if(c[v].length)return d;return d.found=!0,d.trail=this.spawn(g,!0),d}},{hopcroftTarjanBiconnected:Ci,htbc:Ci,htb:Ci,hopcroftTarjanBiconnectedComponents:Ci},{tarjanStronglyConnected:Ni,tsc:Ni,tscc:Ni,tarjanStronglyConnectedComponents:Ni}].forEach((function(e){Q(Ai,e)})); /*! 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.fd4e953c.js b/assets/mkcp.html.2fd0e63c.js similarity index 98% rename from assets/mkcp.html.fd4e953c.js rename to assets/mkcp.html.2fd0e63c.js index 68c5a5371..a8840af78 100644 --- a/assets/mkcp.html.fd4e953c.js +++ b/assets/mkcp.html.2fd0e63c.js @@ -1 +1 @@ -import{r as e,o as n,c as a,a as s,b as o,F as p,d as t,e as c}from"./app.755d843f.js";const r={},l=t('

    mKCP

    mKCP 使用 UDP 来模拟 TCP 连接。

    mKCP 牺牲带宽来降低延迟。传输同样的内容,mKCP 一般比 TCP 消耗更多的流量。

    提示

    请确定主机上的防火墙配置正确

    KcpObject

    KcpObject 对应传输配置的 kcpSettings 项。

    {\n  "mtu": 1350,\n  "tti": 20,\n  "uplinkCapacity": 5,\n  "downlinkCapacity": 20,\n  "congestion": false,\n  "readBufferSize": 1,\n  "writeBufferSize": 1,\n  "header": {\n    "type": "none"\n  },\n  "seed": "Password"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    mtu: number

    最大传输单元(maximum transmission unit) 请选择一个介于 576 - 1460 之间的值。

    默认值为 1350

    tti: number

    传输时间间隔(transmission time interval),单位毫秒(ms),mKCP 将以这个时间频率发送数据。 请选译一个介于 10 - 100 之间的值。

    默认值为 50

    uplinkCapacity: number

    上行链路容量,即主机发出数据所用的最大带宽,单位 MB/s,注意是 Byte 而非 bit。 可以设置为 0,表示一个非常小的带宽。

    默认值 5

    downlinkCapacity: number

    下行链路容量,即主机接收数据所用的最大带宽,单位 MB/s,注意是 Byte 而非 bit。 可以设置为 0,表示一个非常小的带宽。

    默认值 20

    提示

    uplinkCapacitydownlinkCapacity 决定了 mKCP 的传输速度。 以客户端发送数据为例,客户端的 uplinkCapacity 指定了发送数据的速度,而服务器端的 downlinkCapacity 指定了接收数据的速度。两者的值以较小的一个为准。

    推荐把 downlinkCapacity 设置为一个较大的值,比如 100,而 uplinkCapacity 设为实际的网络速度。当速度不够时,可以逐渐增加 uplinkCapacity 的值,直到带宽的两倍左右。

    congestion: true | false

    是否启用拥塞控制。

    开启拥塞控制之后,Xray 会自动监测网络质量,当丢包严重时,会自动降低吞吐量;当网络畅通时,也会适当增加吞吐量。

    默认值为 false

    readBufferSize: number

    单个连接的读取缓冲区大小,单位是 MB。

    默认值为 2

    writeBufferSize: number

    单个连接的写入缓冲区大小,单位是 MB。

    默认值为 2

    提示

    readBufferSizewriteBufferSize 指定了单个连接所使用的内存大小。 在需要高速传输时,指定较大的 readBufferSizewriteBufferSize 会在一定程度上提高速度,但也会使用更多的内存。

    在网速不超过 20MB/s 时,默认值 1MB 可以满足需求;超过之后,可以适当增加 readBufferSizewriteBufferSize 的值,然后手动平衡速度和内存的关系。

    header: HeaderObject

    数据包头部伪装设置

    seed: string

    可选的混淆密码,使用 AES-128-GCM 算法混淆流量数据,客户端和服务端需要保持一致。

    本混淆机制不能用于保证通信内容的安全,但可能可以对抗部分封锁。

    目前测试环境下开启此设置后没有出现原版未混淆版本的封端口现象

    HeaderObject

    {\n  "type": "none"\n}\n
    1
    2
    3

    type: string

    伪装类型,可选的值有:

    • "none":默认值,不进行伪装,发送的数据是没有特征的数据包。
    • "srtp":伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。
    • "utp":伪装成 uTP 数据包,会被识别为 BT 下载数据。
    • "wechat-video":伪装成微信视频通话的数据包。
    • "dtls":伪装成 DTLS 1.2 数据包。
    • "wireguard":伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)

    鸣谢

    ',43),u={href:"https://github.com/skywind3000",target:"_blank",rel:"noopener noreferrer"},i=c("@skywind3000"),d=c(" 发明并实现了 KCP 协议。"),b={href:"https://github.com/xtaci",target:"_blank",rel:"noopener noreferrer"},k=c("@xtaci"),m=c(" 将 KCP 由 C 语言实现翻译成 Go。"),h={href:"https://github.com/xiaokangwang",target:"_blank",rel:"noopener noreferrer"},q=c("@xiaokangwang"),f=c(" 测试 KCP 与 Xray 的整合并提交了最初的 PR。"),C=t('

    对 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 不支持这个场景。

    ',9);r.render=function(t,c){const r=e("OutboundLink");return n(),a(p,null,[l,s("ul",null,[s("li",null,[s("a",u,[i,o(r)]),d]),s("li",null,[s("a",b,[k,o(r)]),m]),s("li",null,[s("a",h,[q,o(r)]),f])]),C],64)};export default r; +import{r as e,o as a,c as n,a as s,b as o,F as p,d as t,e as c}from"./app.48111a85.js";const r={},l=t('

    mKCP

    mKCP 使用 UDP 来模拟 TCP 连接。

    mKCP 牺牲带宽来降低延迟。传输同样的内容,mKCP 一般比 TCP 消耗更多的流量。

    提示

    请确定主机上的防火墙配置正确

    KcpObject

    KcpObject 对应传输配置的 kcpSettings 项。

    {\n  "mtu": 1350,\n  "tti": 20,\n  "uplinkCapacity": 5,\n  "downlinkCapacity": 20,\n  "congestion": false,\n  "readBufferSize": 1,\n  "writeBufferSize": 1,\n  "header": {\n    "type": "none"\n  },\n  "seed": "Password"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    mtu: number

    最大传输单元(maximum transmission unit) 请选择一个介于 576 - 1460 之间的值。

    默认值为 1350

    tti: number

    传输时间间隔(transmission time interval),单位毫秒(ms),mKCP 将以这个时间频率发送数据。 请选译一个介于 10 - 100 之间的值。

    默认值为 50

    uplinkCapacity: number

    上行链路容量,即主机发出数据所用的最大带宽,单位 MB/s,注意是 Byte 而非 bit。 可以设置为 0,表示一个非常小的带宽。

    默认值 5

    downlinkCapacity: number

    下行链路容量,即主机接收数据所用的最大带宽,单位 MB/s,注意是 Byte 而非 bit。 可以设置为 0,表示一个非常小的带宽。

    默认值 20

    提示

    uplinkCapacitydownlinkCapacity 决定了 mKCP 的传输速度。 以客户端发送数据为例,客户端的 uplinkCapacity 指定了发送数据的速度,而服务器端的 downlinkCapacity 指定了接收数据的速度。两者的值以较小的一个为准。

    推荐把 downlinkCapacity 设置为一个较大的值,比如 100,而 uplinkCapacity 设为实际的网络速度。当速度不够时,可以逐渐增加 uplinkCapacity 的值,直到带宽的两倍左右。

    congestion: true | false

    是否启用拥塞控制。

    开启拥塞控制之后,Xray 会自动监测网络质量,当丢包严重时,会自动降低吞吐量;当网络畅通时,也会适当增加吞吐量。

    默认值为 false

    readBufferSize: number

    单个连接的读取缓冲区大小,单位是 MB。

    默认值为 2

    writeBufferSize: number

    单个连接的写入缓冲区大小,单位是 MB。

    默认值为 2

    提示

    readBufferSizewriteBufferSize 指定了单个连接所使用的内存大小。 在需要高速传输时,指定较大的 readBufferSizewriteBufferSize 会在一定程度上提高速度,但也会使用更多的内存。

    在网速不超过 20MB/s 时,默认值 1MB 可以满足需求;超过之后,可以适当增加 readBufferSizewriteBufferSize 的值,然后手动平衡速度和内存的关系。

    header: HeaderObject

    数据包头部伪装设置

    seed: string

    可选的混淆密码,使用 AES-128-GCM 算法混淆流量数据,客户端和服务端需要保持一致。

    本混淆机制不能用于保证通信内容的安全,但可能可以对抗部分封锁。

    目前测试环境下开启此设置后没有出现原版未混淆版本的封端口现象

    HeaderObject

    {\n  "type": "none"\n}\n
    1
    2
    3

    type: string

    伪装类型,可选的值有:

    • "none":默认值,不进行伪装,发送的数据是没有特征的数据包。
    • "srtp":伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。
    • "utp":伪装成 uTP 数据包,会被识别为 BT 下载数据。
    • "wechat-video":伪装成微信视频通话的数据包。
    • "dtls":伪装成 DTLS 1.2 数据包。
    • "wireguard":伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)

    鸣谢

    ',43),u={href:"https://github.com/skywind3000",target:"_blank",rel:"noopener noreferrer"},i=c("@skywind3000"),d=c(" 发明并实现了 KCP 协议。"),b={href:"https://github.com/xtaci",target:"_blank",rel:"noopener noreferrer"},k=c("@xtaci"),m=c(" 将 KCP 由 C 语言实现翻译成 Go。"),h={href:"https://github.com/xiaokangwang",target:"_blank",rel:"noopener noreferrer"},q=c("@xiaokangwang"),f=c(" 测试 KCP 与 Xray 的整合并提交了最初的 PR。"),C=t('

    对 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 不支持这个场景。

    ',9);r.render=function(t,c){const r=e("OutboundLink");return a(),n(p,null,[l,s("ul",null,[s("li",null,[s("a",u,[i,o(r)]),d]),s("li",null,[s("a",b,[k,o(r)]),m]),s("li",null,[s("a",h,[q,o(r)]),f])]),C],64)};export default r; diff --git a/assets/mkcp.html.0ca746da.js b/assets/mkcp.html.500d7909.js similarity index 98% rename from assets/mkcp.html.0ca746da.js rename to assets/mkcp.html.500d7909.js index ecb108380..f2b6d4a72 100644 --- a/assets/mkcp.html.0ca746da.js +++ b/assets/mkcp.html.500d7909.js @@ -1 +1 @@ -import{r as e,o as t,c as a,a as n,b as i,F as d,e as r,d as h}from"./app.755d843f.js";const s={},o=n("h1",{id:"mkcp-protocol",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#mkcp-protocol","aria-hidden":"true"},"#"),r(" mKCP Protocol")],-1),l=r("mKCP is a stream transfer protocol, modified from the "),c={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},m=r("KCP protocol"),u=r(", which can transmit any data stream in order."),p=h('

    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),b=r("fnv: "),f={href:"https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function",target:"_blank",rel:"noopener noreferrer"},y=r("FNV-1a"),g=r(" hash function "),v=n("ul",null,[n("li",null,"Takes a string of arbitrary length as input parameter;"),n("li",null,"Outputs a 32-bit unsigned integer.")],-1),C=h('

    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);s.render=function(r,h){const s=e("OutboundLink");return t(),a(d,null,[o,n("p",null,[l,n("a",c,[m,i(s)]),u]),p,n("ul",null,[n("li",null,[b,n("a",f,[y,i(s)]),g,v])]),C],64)};export default s; +import{r as e,o as t,c as a,a as n,b as i,F as d,e as r,d as h}from"./app.48111a85.js";const s={},o=n("h1",{id:"mkcp-protocol",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#mkcp-protocol","aria-hidden":"true"},"#"),r(" mKCP Protocol")],-1),l=r("mKCP is a stream transfer protocol, modified from the "),c={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},m=r("KCP protocol"),u=r(", which can transmit any data stream in order."),p=h('

    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),b=r("fnv: "),f={href:"https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function",target:"_blank",rel:"noopener noreferrer"},y=r("FNV-1a"),g=r(" hash function "),v=n("ul",null,[n("li",null,"Takes a string of arbitrary length as input parameter;"),n("li",null,"Outputs a 32-bit unsigned integer.")],-1),C=h('

    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);s.render=function(r,h){const s=e("OutboundLink");return t(),a(d,null,[o,n("p",null,[l,n("a",c,[m,i(s)]),u]),p,n("ul",null,[n("li",null,[b,n("a",f,[y,i(s)]),g,v])]),C],64)};export default s; diff --git a/assets/mkcp.html.8ecd0563.js b/assets/mkcp.html.afc1ad80.js similarity index 99% rename from assets/mkcp.html.8ecd0563.js rename to assets/mkcp.html.afc1ad80.js index 2de85900e..eaea49b6e 100644 --- a/assets/mkcp.html.8ecd0563.js +++ b/assets/mkcp.html.afc1ad80.js @@ -1 +1 @@ -import{r as e,o as n,c as a,a as t,b as s,w as o,F as i,d as c,e as r}from"./app.755d843f.js";const p={},l=c('

    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),d=t("code",null,"KcpObject",-1),u=r(" corresponds to the "),h=t("code",null,"kcpSettings",-1),m=r(" in the "),b=r("Transport Protocol"),f=r(","),k=c('
    {\n  "mtu": 1350,\n  "tti": 20,\n  "uplinkCapacity": 5,\n  "downlinkCapacity": 20,\n  "congestion": false,\n  "readBufferSize": 1,\n  "writeBufferSize": 1,\n  "header": {\n    "type": "none"\n  },\n  "seed": "Password"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    mtu: number

    Maximum transmission unit. It indicates the maxium bytes that an UDP packet can carry. Recommended value is between 576 and 1460

    The default value is 1350

    tti: number

    Transmission time interval, measured in milliseconds (ms), determines how often mKCP sends data. Please choose a value between 10 and 100

    The default value is 50

    uplinkCapacity: number

    Uplink capacity refers to the maximum bandwidth used by the host to send data, measured in MB/s (note: Byte, not bit). It can be set to 0, indicating a very small bandwidth.

    The default value is 5

    downlinkCapacity: number

    Downlink capacity refers to the maximum bandwidth used by the host to receive data, measured in MB/s (note: Byte, not bit). It can be set to 0, indicating a very small bandwidth.

    The default value is 20

    Tip

    uplinkCapacity and downlinkCapacity determine the transmission speed of mKCP. For example, when a client sends data, the client's uplinkCapacity specifies the speed of sending data, while the server's downlinkCapacity specifies the speed of receiving data. The value used is the smaller of the two.

    It is recommended to set downlinkCapacity to a larger value, such as 100, and set uplinkCapacity to the actual network speed. If the speed is insufficient, gradually increase the value of uplinkCapacity until it is about twice the bandwidth.

    congestion: true | false

    Whether or not to enable congestion control. When congestion control is enabled, Xray will detect network quality. It will send less packets when packet loss is severe, or more packets when network is not fully filled.

    The default value is false

    readBufferSize: number

    The read buffer size for a single connection, measured in MB

    The default value is 2

    writeBufferSize: number

    The write buffer size for a single connection, measured in MB

    The default value is 2

    Tip

    readBufferSize and writeBufferSize specify the memory size used by a single connection. When high-speed transmissions are required, specifying larger values for readBufferSize and writeBufferSize can improve speed to some extent, but it will also consume more memory.

    When the network speed is no more than 20 MB/s, the default value of 1MB is sufficient; after exceeding this limit, you can increase the values of readBufferSize and writeBufferSize appropriately and then manually balance the relationship between speed and memory.

    header: HeaderObject

    Configuration for packet header obfuscation.

    seed: string

    An optional obfuscation seed is used to obfuscate traffic data using the AES-128-GCM algorithm. The client and server need to use the same seed.

    This obfuscation mechanism cannot ensure the security of the content, but it may be able to resist some blocking.

    NOTE

    Currently, in the testing environment, enabling this setting has not resulted in the original unobfuscated version being blocked by ports.

    HeaderObject

    {\n  "type": "none"\n}\n
    1
    2
    3

    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

    ',36),y={href:"https://github.com/skywind3000",target:"_blank",rel:"noopener noreferrer"},g=r("@skywind3000"),q=r(" Credit for inventing and implementing the original KCP protocol in C."),w={href:"https://github.com/xtaci",target:"_blank",rel:"noopener noreferrer"},v=r("@xtaci"),C=r(" Credit for re-implementing KCP protocol in Go."),K={href:"https://github.com/xiaokangwang",target:"_blank",rel:"noopener noreferrer"},T=r("@xiaokangwang"),P=r(" Credit for testing the integration of KCP with Xray and submitting the initial PR."),x=c('

    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.

    ',9);p.render=function(c,r){const p=e("RouterLink"),B=e("OutboundLink");return n(),a(i,null,[l,t("p",null,[d,u,h,m,s(p,{to:"/en/config/transport.html"},{default:o((()=>[b])),_:1}),f]),k,t("ul",null,[t("li",null,[t("a",y,[g,s(B)]),q]),t("li",null,[t("a",w,[v,s(B)]),C]),t("li",null,[t("a",K,[T,s(B)]),P])]),x],64)};export default p; +import{r as e,o as n,c as a,a as t,b as s,w as o,F as i,d as c,e as r}from"./app.48111a85.js";const p={},l=c('

    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),d=t("code",null,"KcpObject",-1),u=r(" corresponds to the "),h=t("code",null,"kcpSettings",-1),m=r(" in the "),b=r("Transport Protocol"),f=r(","),k=c('
    {\n  "mtu": 1350,\n  "tti": 20,\n  "uplinkCapacity": 5,\n  "downlinkCapacity": 20,\n  "congestion": false,\n  "readBufferSize": 1,\n  "writeBufferSize": 1,\n  "header": {\n    "type": "none"\n  },\n  "seed": "Password"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    mtu: number

    Maximum transmission unit. It indicates the maxium bytes that an UDP packet can carry. Recommended value is between 576 and 1460

    The default value is 1350

    tti: number

    Transmission time interval, measured in milliseconds (ms), determines how often mKCP sends data. Please choose a value between 10 and 100

    The default value is 50

    uplinkCapacity: number

    Uplink capacity refers to the maximum bandwidth used by the host to send data, measured in MB/s (note: Byte, not bit). It can be set to 0, indicating a very small bandwidth.

    The default value is 5

    downlinkCapacity: number

    Downlink capacity refers to the maximum bandwidth used by the host to receive data, measured in MB/s (note: Byte, not bit). It can be set to 0, indicating a very small bandwidth.

    The default value is 20

    Tip

    uplinkCapacity and downlinkCapacity determine the transmission speed of mKCP. For example, when a client sends data, the client's uplinkCapacity specifies the speed of sending data, while the server's downlinkCapacity specifies the speed of receiving data. The value used is the smaller of the two.

    It is recommended to set downlinkCapacity to a larger value, such as 100, and set uplinkCapacity to the actual network speed. If the speed is insufficient, gradually increase the value of uplinkCapacity until it is about twice the bandwidth.

    congestion: true | false

    Whether or not to enable congestion control. When congestion control is enabled, Xray will detect network quality. It will send less packets when packet loss is severe, or more packets when network is not fully filled.

    The default value is false

    readBufferSize: number

    The read buffer size for a single connection, measured in MB

    The default value is 2

    writeBufferSize: number

    The write buffer size for a single connection, measured in MB

    The default value is 2

    Tip

    readBufferSize and writeBufferSize specify the memory size used by a single connection. When high-speed transmissions are required, specifying larger values for readBufferSize and writeBufferSize can improve speed to some extent, but it will also consume more memory.

    When the network speed is no more than 20 MB/s, the default value of 1MB is sufficient; after exceeding this limit, you can increase the values of readBufferSize and writeBufferSize appropriately and then manually balance the relationship between speed and memory.

    header: HeaderObject

    Configuration for packet header obfuscation.

    seed: string

    An optional obfuscation seed is used to obfuscate traffic data using the AES-128-GCM algorithm. The client and server need to use the same seed.

    This obfuscation mechanism cannot ensure the security of the content, but it may be able to resist some blocking.

    NOTE

    Currently, in the testing environment, enabling this setting has not resulted in the original unobfuscated version being blocked by ports.

    HeaderObject

    {\n  "type": "none"\n}\n
    1
    2
    3

    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

    ',36),y={href:"https://github.com/skywind3000",target:"_blank",rel:"noopener noreferrer"},g=r("@skywind3000"),q=r(" Credit for inventing and implementing the original KCP protocol in C."),w={href:"https://github.com/xtaci",target:"_blank",rel:"noopener noreferrer"},v=r("@xtaci"),C=r(" Credit for re-implementing KCP protocol in Go."),K={href:"https://github.com/xiaokangwang",target:"_blank",rel:"noopener noreferrer"},T=r("@xiaokangwang"),P=r(" Credit for testing the integration of KCP with Xray and submitting the initial PR."),x=c('

    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.

    ',9);p.render=function(c,r){const p=e("RouterLink"),B=e("OutboundLink");return n(),a(i,null,[l,t("p",null,[d,u,h,m,s(p,{to:"/en/config/transport.html"},{default:o((()=>[b])),_:1}),f]),k,t("ul",null,[t("li",null,[t("a",y,[g,s(B)]),q]),t("li",null,[t("a",w,[v,s(B)]),C]),t("li",null,[t("a",K,[T,s(B)]),P])]),x],64)};export default p; diff --git a/assets/mkcp.html.16d65ae7.js b/assets/mkcp.html.cc07a53d.js similarity index 98% rename from assets/mkcp.html.16d65ae7.js rename to assets/mkcp.html.cc07a53d.js index df8ee1b1e..68050548a 100644 --- a/assets/mkcp.html.16d65ae7.js +++ b/assets/mkcp.html.cc07a53d.js @@ -1 +1 @@ -import{r as t,o as d,c as a,a as h,b as i,F as l,e,d as r}from"./app.755d843f.js";const n={},o=h("h1",{id:"mkcp-协议",tabindex:"-1"},[h("a",{class:"header-anchor",href:"#mkcp-协议","aria-hidden":"true"},"#"),e(" mKCP 协议")],-1),s=e("mKCP 是流式传输协议,由 "),u={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},b=e("KCP 协议"),p=e(" 修改而来,可以按顺序传输任意的数据流。"),c=r('

    版本

    mKCP 没有版本号,不保证版本之间兼容性。

    依赖

    底层协议

    mKCP 是一个基于 UDP 的协议,所有通讯使用 UDP 传输。

    函数

    ',6),C=e("fnv: "),f={href:"https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function",target:"_blank",rel:"noopener noreferrer"},m=e("FNV-1a"),x=e(" 哈希函数 "),P=h("ul",null,[h("li",null,"输入参数为任意长度的字符串;"),h("li",null,"输入出一个 32 位无符号整数;")],-1),K=r('

    通讯过程

    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);n.render=function(e,r){const n=t("OutboundLink");return d(),a(l,null,[o,h("p",null,[s,h("a",u,[b,i(n)]),p]),c,h("ul",null,[h("li",null,[C,h("a",f,[m,i(n)]),x,P])]),K],64)};export default n; +import{r as t,o as d,c as a,a as h,b as i,F as l,e,d as r}from"./app.48111a85.js";const n={},o=h("h1",{id:"mkcp-协议",tabindex:"-1"},[h("a",{class:"header-anchor",href:"#mkcp-协议","aria-hidden":"true"},"#"),e(" mKCP 协议")],-1),s=e("mKCP 是流式传输协议,由 "),u={href:"https://github.com/skywind3000/kcp",target:"_blank",rel:"noopener noreferrer"},b=e("KCP 协议"),p=e(" 修改而来,可以按顺序传输任意的数据流。"),c=r('

    版本

    mKCP 没有版本号,不保证版本之间兼容性。

    依赖

    底层协议

    mKCP 是一个基于 UDP 的协议,所有通讯使用 UDP 传输。

    函数

    ',6),C=e("fnv: "),f={href:"https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function",target:"_blank",rel:"noopener noreferrer"},m=e("FNV-1a"),x=e(" 哈希函数 "),P=h("ul",null,[h("li",null,"输入参数为任意长度的字符串;"),h("li",null,"输入出一个 32 位无符号整数;")],-1),K=r('

    通讯过程

    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);n.render=function(e,r){const n=t("OutboundLink");return d(),a(l,null,[o,h("p",null,[s,h("a",u,[b,i(n)]),p]),c,h("ul",null,[h("li",null,[C,h("a",f,[m,i(n)]),x,P])]),K],64)};export default n; diff --git a/assets/multiple.html.c1dc1778.js b/assets/multiple.html.125c909a.js similarity index 99% rename from assets/multiple.html.c1dc1778.js rename to assets/multiple.html.125c909a.js index 7278584d1..f692efe73 100644 --- a/assets/multiple.html.c1dc1778.js +++ b/assets/multiple.html.125c909a.js @@ -1 +1 @@ -import{d as n}from"./app.755d843f.js";const s={},a=n('

    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\n
    1

    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
    {\n  "log": {},\n  "api": {},\n  "dns": {},\n  "stats": {},\n  "policy": {},\n  "transport": {},\n  "routing": {},\n  "inbounds": []\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    • outbounds.json
    {\n  "outbounds": []\n}\n
    1
    2
    3

    When starting Xray with multiple configurations, use the following command:

    $ xray run -confdir /etc/xray/confs\n
    1

    These two configuration files are equivalent to a single combined configuration. If you need to modify the outbound nodes, simply modify the content of outbounds.json.

    If you need to change the log level for debugging purposes, there is no need to modify base.json. You can add an additional configuration file:

    • debuglog.json
    {\n  "log": {\n    "loglevel": "debug"\n  }\n}\n
    1
    2
    3
    4
    5

    Start the program in sequence after base.json to output logs at the debug level.

    Arrays([]

    In the JSON configuration, inbounds and outbounds are array structures with special rules:

    • When there are two or more elements in the array, the latter overrides the former for inbounds/outbounds.
    • When there is only one element in the array, it searches for an existing element with the same tag to override. If it cannot be found:
      • For inbounds, add it to the end (the order of elements in inbounds is irrelevant).
      • For outbounds, add it to the beginning (the default first-choice outbound). However, if the filename contains "tail" (case-insensitive), add it to the end.

    With multiple configurations, it is easy to add inbound for different protocols to the original configuration without modifying the original configuration.

    The following example is not a valid configuration but is provided to demonstrate the above rules.

    • 000.json
    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 1234\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    • 001.json
    {\n  "inbounds": [\n    {\n      "protocol": "http",\n      "tag": "http"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    • 002.json
    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 4321\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    The three configurations will be combined into:

    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 4321 // < 002顺序在000后,因此覆盖tag为socks的inbound端口为4321\n    },\n    {\n      "protocol": "http",\n      "tag": "http"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    Execute:

    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\n
    1

    or

    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\n
    1
    .\n├── 00_log.json\n├── 01_api.json\n├── 02_dns.json\n├── 03_routing.json\n├── 04_policy.json\n├── 05_inbounds.json\n├── 06_outbounds.json\n├── 07_transport.json\n├── 08_stats.json\n└── 09_reverse.json\n\n0 directories, 10 files\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ',43);s.render=function(n,s){return a};export default s; +import{d as n}from"./app.48111a85.js";const s={},a=n('

    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\n
    1

    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
    {\n  "log": {},\n  "api": {},\n  "dns": {},\n  "stats": {},\n  "policy": {},\n  "transport": {},\n  "routing": {},\n  "inbounds": []\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    • outbounds.json
    {\n  "outbounds": []\n}\n
    1
    2
    3

    When starting Xray with multiple configurations, use the following command:

    $ xray run -confdir /etc/xray/confs\n
    1

    These two configuration files are equivalent to a single combined configuration. If you need to modify the outbound nodes, simply modify the content of outbounds.json.

    If you need to change the log level for debugging purposes, there is no need to modify base.json. You can add an additional configuration file:

    • debuglog.json
    {\n  "log": {\n    "loglevel": "debug"\n  }\n}\n
    1
    2
    3
    4
    5

    Start the program in sequence after base.json to output logs at the debug level.

    Arrays([]

    In the JSON configuration, inbounds and outbounds are array structures with special rules:

    • When there are two or more elements in the array, the latter overrides the former for inbounds/outbounds.
    • When there is only one element in the array, it searches for an existing element with the same tag to override. If it cannot be found:
      • For inbounds, add it to the end (the order of elements in inbounds is irrelevant).
      • For outbounds, add it to the beginning (the default first-choice outbound). However, if the filename contains "tail" (case-insensitive), add it to the end.

    With multiple configurations, it is easy to add inbound for different protocols to the original configuration without modifying the original configuration.

    The following example is not a valid configuration but is provided to demonstrate the above rules.

    • 000.json
    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 1234\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    • 001.json
    {\n  "inbounds": [\n    {\n      "protocol": "http",\n      "tag": "http"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    • 002.json
    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 4321\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    The three configurations will be combined into:

    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 4321 // < 002顺序在000后,因此覆盖tag为socks的inbound端口为4321\n    },\n    {\n      "protocol": "http",\n      "tag": "http"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    Execute:

    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\n
    1

    or

    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\n
    1
    .\n├── 00_log.json\n├── 01_api.json\n├── 02_dns.json\n├── 03_routing.json\n├── 04_policy.json\n├── 05_inbounds.json\n├── 06_outbounds.json\n├── 07_transport.json\n├── 08_stats.json\n└── 09_reverse.json\n\n0 directories, 10 files\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ',43);s.render=function(n,s){return a};export default s; diff --git a/assets/multiple.html.1f79c516.js b/assets/multiple.html.6aacfcfe.js similarity index 99% rename from assets/multiple.html.1f79c516.js rename to assets/multiple.html.6aacfcfe.js index a773faaee..e6295bdcc 100644 --- a/assets/multiple.html.1f79c516.js +++ b/assets/multiple.html.6aacfcfe.js @@ -1 +1 @@ -import{d as n}from"./app.755d843f.js";const s={},a=n('

    多文件配置

    Xray 程序支持使用多个配置文件。

    多配置文件的主要作用在于分散不同作用模块配置,便于管理和维护。

    该功能主要考虑是为了丰富 Xray 的生态链,比如对于 GUI 的客户端,一般只实现节点选择等固定的功能,对于太复杂的配置难以图形化实现;只需留一个 confdir 的自定义配置目录供配置复杂的功能;对于服务器的部署脚本,只需往 confdir 添加文件即可实现配置多种协议。

    多文件启动

    提示

    启动信息中会提示依次读入的每个配置文件,留意启动信息是否符合你预设的顺序。

    $ xray run -confdir /etc/xray/confs\n
    1

    也可使用 Xray.location.confdirXray_LOCATION_CONFDIR 指定 confdir

    参数 -confdir 的作用优先于环境变量,如果参数指定了有效的目录则不再读取环境变量中的路径。

    规则说明

    普通对象({}

    在 json 的顶级对象当中,后者覆盖或补充前者。

    比如:

    • base.json
    {\n  "log": {},\n  "api": {},\n  "dns": {},\n  "stats": {},\n  "policy": {},\n  "transport": {},\n  "routing": {},\n  "inbounds": []\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    • outbounds.json
    {\n  "outbounds": []\n}\n
    1
    2
    3

    以多配置启动 Xray:

    $ xray run -confdir /etc/xray/confs\n
    1

    这两个配置文件的就等效于合成一起的整配置。当需要修改出口节点,只需要修改 outbounds.json 内容。

    如果需要改编日志 log 的级别,也不需要改 base.json,只需后续增加一个配置:

    • debuglog.json
    {\n  "log": {\n    "loglevel": "debug"\n  }\n}\n
    1
    2
    3
    4
    5

    启动顺序放置在 base 后,即可输出 debug 级别的日志

    数组([]

    在 json 配置中的inboundsoutbounds是数组结构,他们有特殊的规则:

    • 当配置中的数组元素有 2 或以上,覆盖前者的 inbounds/oubounds;
    • 当配置中的数组元素只有 1 个时,查找原有tag相同的元素进行覆盖;若无法找到:
      • 对于 inbounds,添加至最后(inbounds 内元素顺序无关)
      • 对于 outbounds,添加至最前(outbounds 默认首选出口);但如果文件名含有 tail(大小写均可),添加至最后。

    借助多配置,可以很方便为原有的配置添加不同协议的 inbound,而不必修改原有配置。

    以下例子不是有效配置,只为展示上述规则。

    • 000.json
    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 1234\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    • 001.json
    {\n  "inbounds": [\n    {\n      "protocol": "http",\n      "tag": "http"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    • 002.json
    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 4321\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    三个配置将会合成为:

    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 4321 // < 002顺序在000后,因此覆盖tag为socks的inbound端口为4321\n    },\n    {\n      "protocol": "http",\n      "tag": "http"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    推荐的多文件列表

    执行:

    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\n
    1

    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\n
    1
    .\n├── 00_log.json\n├── 01_api.json\n├── 02_dns.json\n├── 03_routing.json\n├── 04_policy.json\n├── 05_inbounds.json\n├── 06_outbounds.json\n├── 07_transport.json\n├── 08_stats.json\n└── 09_reverse.json\n\n0 directories, 10 files\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ',43);s.render=function(n,s){return a};export default s; +import{d as n}from"./app.48111a85.js";const s={},a=n('

    多文件配置

    Xray 程序支持使用多个配置文件。

    多配置文件的主要作用在于分散不同作用模块配置,便于管理和维护。

    该功能主要考虑是为了丰富 Xray 的生态链,比如对于 GUI 的客户端,一般只实现节点选择等固定的功能,对于太复杂的配置难以图形化实现;只需留一个 confdir 的自定义配置目录供配置复杂的功能;对于服务器的部署脚本,只需往 confdir 添加文件即可实现配置多种协议。

    多文件启动

    提示

    启动信息中会提示依次读入的每个配置文件,留意启动信息是否符合你预设的顺序。

    $ xray run -confdir /etc/xray/confs\n
    1

    也可使用 Xray.location.confdirXray_LOCATION_CONFDIR 指定 confdir

    参数 -confdir 的作用优先于环境变量,如果参数指定了有效的目录则不再读取环境变量中的路径。

    规则说明

    普通对象({}

    在 json 的顶级对象当中,后者覆盖或补充前者。

    比如:

    • base.json
    {\n  "log": {},\n  "api": {},\n  "dns": {},\n  "stats": {},\n  "policy": {},\n  "transport": {},\n  "routing": {},\n  "inbounds": []\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    • outbounds.json
    {\n  "outbounds": []\n}\n
    1
    2
    3

    以多配置启动 Xray:

    $ xray run -confdir /etc/xray/confs\n
    1

    这两个配置文件的就等效于合成一起的整配置。当需要修改出口节点,只需要修改 outbounds.json 内容。

    如果需要改编日志 log 的级别,也不需要改 base.json,只需后续增加一个配置:

    • debuglog.json
    {\n  "log": {\n    "loglevel": "debug"\n  }\n}\n
    1
    2
    3
    4
    5

    启动顺序放置在 base 后,即可输出 debug 级别的日志

    数组([]

    在 json 配置中的inboundsoutbounds是数组结构,他们有特殊的规则:

    • 当配置中的数组元素有 2 或以上,覆盖前者的 inbounds/oubounds;
    • 当配置中的数组元素只有 1 个时,查找原有tag相同的元素进行覆盖;若无法找到:
      • 对于 inbounds,添加至最后(inbounds 内元素顺序无关)
      • 对于 outbounds,添加至最前(outbounds 默认首选出口);但如果文件名含有 tail(大小写均可),添加至最后。

    借助多配置,可以很方便为原有的配置添加不同协议的 inbound,而不必修改原有配置。

    以下例子不是有效配置,只为展示上述规则。

    • 000.json
    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 1234\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    • 001.json
    {\n  "inbounds": [\n    {\n      "protocol": "http",\n      "tag": "http"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    • 002.json
    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 4321\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    三个配置将会合成为:

    {\n  "inbounds": [\n    {\n      "protocol": "socks",\n      "tag": "socks",\n      "port": 4321 // < 002顺序在000后,因此覆盖tag为socks的inbound端口为4321\n    },\n    {\n      "protocol": "http",\n      "tag": "http"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    推荐的多文件列表

    执行:

    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\n
    1

    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\n
    1
    .\n├── 00_log.json\n├── 01_api.json\n├── 02_dns.json\n├── 03_routing.json\n├── 04_policy.json\n├── 05_inbounds.json\n├── 06_outbounds.json\n├── 07_transport.json\n├── 08_stats.json\n└── 09_reverse.json\n\n0 directories, 10 files\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ',43);s.render=function(n,s){return a};export default s; diff --git a/assets/muxcool.html.39cdcc2e.js b/assets/muxcool.html.07864240.js similarity index 99% rename from assets/muxcool.html.39cdcc2e.js rename to assets/muxcool.html.07864240.js index 0f41f3e40..b2e087dc7 100644 --- a/assets/muxcool.html.39cdcc2e.js +++ b/assets/muxcool.html.07864240.js @@ -1 +1 @@ -import{r as t,o as d,c as e,a,b as h,F as l,d as i,e as r}from"./app.755d843f.js";const o={},n=i('

    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),p=r("ID: 子连接的唯一标识 "),u=a("li",null,"对于一般 Mux 子连接,ID 由 1 开始累加",-1),b=r("对于 Xray 实现的 "),c={href:"https://github.com/XTLS/Xray-core/blob/main/common/xudp/xudp.go",target:"_blank",rel:"noopener noreferrer"},s=r("Single XUDP"),x=r(",ID 始终为 0"),D=a("li",null,[r("Opt: "),a("ul",null,[a("li",null,"D(0x01): 有额外数据")])],-1),f=i('

    当选项 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);o.render=function(i,r){const o=t("OutboundLink");return d(),e(l,null,[n,a("ul",null,[a("li",null,[p,a("ul",null,[u,a("li",null,[b,a("a",c,[s,h(o)]),x])])]),D]),f],64)};export default o; +import{r as t,o as d,c as e,a,b as h,F as l,d as i,e as r}from"./app.48111a85.js";const o={},n=i('

    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),p=r("ID: 子连接的唯一标识 "),u=a("li",null,"对于一般 Mux 子连接,ID 由 1 开始累加",-1),b=r("对于 Xray 实现的 "),c={href:"https://github.com/XTLS/Xray-core/blob/main/common/xudp/xudp.go",target:"_blank",rel:"noopener noreferrer"},s=r("Single XUDP"),x=r(",ID 始终为 0"),D=a("li",null,[r("Opt: "),a("ul",null,[a("li",null,"D(0x01): 有额外数据")])],-1),f=i('

    当选项 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);o.render=function(i,r){const o=t("OutboundLink");return d(),e(l,null,[n,a("ul",null,[a("li",null,[p,a("ul",null,[u,a("li",null,[b,a("a",c,[s,h(o)]),x])])]),D]),f],64)};export default o; diff --git a/assets/muxcool.html.4b83d2f6.js b/assets/muxcool.html.f1872cc3.js similarity index 99% rename from assets/muxcool.html.4b83d2f6.js rename to assets/muxcool.html.f1872cc3.js index 96e2df534..8051f9678 100644 --- a/assets/muxcool.html.4b83d2f6.js +++ b/assets/muxcool.html.f1872cc3.js @@ -1 +1 @@ -import{d as e}from"./app.755d843f.js";const t={},a=e('

    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);t.render=function(e,t){return a};export default t; +import{d as e}from"./app.48111a85.js";const t={},a=e('

    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);t.render=function(e,t){return a};export default t; diff --git a/assets/news.html.10dff9e9.js b/assets/news.html.6f2f8a15.js similarity index 99% rename from assets/news.html.10dff9e9.js rename to assets/news.html.6f2f8a15.js index 9c58b7904..9e6b116f5 100644 --- a/assets/news.html.10dff9e9.js +++ b/assets/news.html.6f2f8a15.js @@ -1 +1 @@ -import{r as e,o as l,c as r,a,b as n,w as i,F as t,d as h,e as u}from"./app.755d843f.js";const o={},d=h('

    大史记

    2021.4.6

    • VuePress Next.
    • With Dark Mode.

    2021.4.4

    • 本文档迎来的新的首页。
    • 本文档迎来了暗黑模式。
    • 当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。
    • 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
    • 🎉🎉🎉
    ',5),s={id:"_2021-4-1-v1-4-2",tabindex:"-1"},c=a("a",{class:"header-anchor",href:"#_2021-4-1-v1-4-2","aria-hidden":"true"},"#",-1),f=u(" 2021.4.1 "),_={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.2",target:"_blank",rel:"noopener noreferrer"},p=u("v1.4.2"),b=h('
    • 不是愚人节玩笑,今天更新。
    • 加入 Browser Dialer,用与改变 TLS 指纹与行为。
    • 加入 uTLS,用与改变 TLS Client Hello 的指纹。
    • 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。

    2021.3.25

    没错还在变。 -_-

    2021.3.15

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

    ',5),g={id:"_2021-3-14-v1-4-0",tabindex:"-1"},X=a("a",{class:"header-anchor",href:"#_2021-3-14-v1-4-0","aria-hidden":"true"},"#",-1),m=u(" 2021.3.14 "),x={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.0",target:"_blank",rel:"noopener noreferrer"},S=u("v1.4.0"),k=h("
    • Happy Pi-Day!
    • 这次是个大更新:
      • 为链式代理引入了传输层支持。
      • 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
      • 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
      • 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
      • 添加了 FakeDNS。
      • 还修复了系列的问题,添加了各类功能,详情请见更新日志。
    • 还是 VuePress 比较爽啊(
    ",1),y={id:"_2021-3-3-1-3-1",tabindex:"-1"},v=a("a",{class:"header-anchor",href:"#_2021-3-3-1-3-1","aria-hidden":"true"},"#",-1),T=u(" 2021.3.3 "),L={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.1",target:"_blank",rel:"noopener noreferrer"},D=u("1.3.1"),P=a("ul",null,[a("li",null,"这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。"),a("li",null,[u("同时修复了一个会导致 Panic 的 bug。"),a("s",null,"Holmium_认为这是在骗、在偷袭。")]),a("li",null,"修复了几个遗留问题。")],-1),U={id:"_2021-2-14-1-3-0",tabindex:"-1"},H=a("a",{class:"header-anchor",href:"#_2021-2-14-1-3-0","aria-hidden":"true"},"#",-1),j=u(" 2021.2.14 "),C={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.0",target:"_blank",rel:"noopener noreferrer"},B=u("1.3.0"),G=a("ul",null,[a("li",null,"Happy 🐮 Year 🎉!"),a("li",null,"v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。"),a("li",null,"OHHHHHHHHHHHH!")],-1),I={id:"_2021-01-31-1-2-4",tabindex:"-1"},N=a("a",{class:"header-anchor",href:"#_2021-01-31-1-2-4","aria-hidden":"true"},"#",-1),E=u(" 2021.01.31 "),O={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.4",target:"_blank",rel:"noopener noreferrer"},w=u("1.2.4"),F=a("ul",null,[a("li",null,"解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。"),a("li",null,"似乎这个版本没有什么改变,但这只是暴风雨前的宁静。"),a("li",null,[u("(没错我就是先知) "),a("blockquote",null,[a("p",null,"你个傻子,你拿的是 UNO 牌。")])])],-1),R=a("h2",{id:"_2021-01-25",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2021-01-25","aria-hidden":"true"},"#"),u(" 2021.01.25")],-1),V=u("全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载"),M=u("秘籍第一层"),A=u("咯..."),q=a("li",null,[a("a",{href:"../en"},"英文版文档网站"),u("逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!")],-1),W={id:"_2021-01-22-1-2-3",tabindex:"-1"},Q=a("a",{class:"header-anchor",href:"#_2021-01-22-1-2-3","aria-hidden":"true"},"#",-1),Y=u(" 2021.01.22 "),J={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.3",target:"_blank",rel:"noopener noreferrer"},z=u("1.2.3"),K=a("li",null,[u("对 SS 协议的支持"),a("strong",null,"又"),u("变强了, 支持单端口多用户!")],-1),Z=a("li",null,[u("对 trojan 协议的支持也"),a("strong",null,"又"),u("变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!")],-1),$=a("li",null,[a("em",null,"(VLESS: 嘤嘤嘤)")],-1),ee=a("li",null,'UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".',-1),le=a("li",null,"嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.",-1),re=u("向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 "),ae=a("img",{src:"https://avatars2.githubusercontent.com/u/8384161?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ne=u(),ie={href:"https://github.com/bohanyang",target:"_blank",rel:"noopener noreferrer"},te=u("@Bohan Yang"),he=u(" 致敬!"),ue=a("li",null,"其他美味小樱桃, 惯例更新品尝就对啦.",-1),oe=h('

    2021.01.19

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

    2021.01.17

    ',3),de=u("辛苦的翻译工作开始了, 感谢"),se=a("img",{src:"https://avatars2.githubusercontent.com/u/60207794?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ce=u(),fe={href:"https://github.com/jiuqi9997",target:"_blank",rel:"noopener noreferrer"},_e=u("@玖柒 Max"),pe=u("和其他所有的翻译大佬们."),be={href:"https://xtls.github.io/en/",target:"_blank",rel:"noopener noreferrer"},ge=u("English version"),Xe={id:"_2021-01-15-1-2-2",tabindex:"-1"},me=a("a",{class:"header-anchor",href:"#_2021-01-15-1-2-2","aria-hidden":"true"},"#",-1),xe=u(" 2021.01.15 "),Se={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.2",target:"_blank",rel:"noopener noreferrer"},ke=u("1.2.2"),ye=h('
    • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
    • 之前预告的 UUID 修改正式上线.(往下看往下看)
    • 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
    • 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
    • 当然还有其他各种小糖果.(更新品尝就对了)
    • 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE

    2021.01.12

    ',2),ve=a("li",null,[u("将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户. "),a("ul",null,[a("li",null,'客户端写 "id": "我爱 🍉 老师 1314",'),a("li",null,[u('服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 '),a("code",null,"我爱🍉老师1314"),u(" 的 UUID 映射)")])])],-1),Te=u("🍉 老师的"),Le=u("小小白白话文"),De=u("大结局, 撒花."),Pe={id:"_2021-01-10-1-2-1",tabindex:"-1"},Ue=a("a",{class:"header-anchor",href:"#_2021-01-10-1-2-1","aria-hidden":"true"},"#",-1),He=u(" 2021.01.10 "),je={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.1",target:"_blank",rel:"noopener noreferrer"},Ce=u("1.2.1"),Be=u("小小白白话文"),Ge=u("连载上线啦,🍉 老师呕心沥血之作, 手把手教你从什么都不会到熟练配置 Xray!"),Ie=a("li",null,"(可能是整个互联网上, 最详细最有耐心的教你从 0 开始配置的教程)",-1),Ne=u("透明代理"),Ee=u("也增加了更多文章."),Oe=a("li",null,"还有很多细节修改, 文档将会越来越规范!",-1),we=u("感谢 "),Fe={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},Re=u("@ricuhkaen"),Ve=u(" , "),Me={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},Ae=u("@BioniCosmos"),qe=u(", "),We={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},Qe=u("@kirin"),Ye=h('
    • 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
    • Google Voice 应该也可以正常使用 v2rayNG 拨打了.
    • 日志现在看起来更顺眼.

    2021.01.07

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

    2021.01.05

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

    2021.01.03

    ',6),Je=u("文档仓库第一个 PR。🎉 "),ze=u("透明代理(TProxy)配置教程 "),Ke=u(" ,感谢"),Ze=a("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32px",height:"32px",alt:"a"},null,-1),$e=u(),el={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},ll=u("@BioniCosmos"),rl=a("li",null,"tg 群突破 2500。",-1),al=a("h2",{id:"_2021-01-01",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2021-01-01","aria-hidden":"true"},"#"),u(" 2021.01.01")],-1),nl=u("【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 "),il={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},tl=u("1.2.0"),hl=a("p",null,"🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!",-1),ul=h('
  • 圣诞礼物v1.1.5后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
  • (UDP 还会继续增强!)
  • 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
  • (不,下面不是广告,是里程碑。)
  • Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
    • 一人扛起了所有!支持各大主流协议!
    • 一骑绝尘的性能!
    • 日趋完善的功能!
    • 可怕的生命力与社区亲和力!
  • ',5),ol=u("Xray 将继续保持前行! 因此 "),dl={href:"https://github.com/XTLS/Xray-core/discussions/56",target:"_blank",rel:"noopener noreferrer"},sl=u("Xray 需要更多的英雄!!"),cl=u("!"),fl=u("PS:请品,请细品"),_l={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},pl=u("release notes"),bl=u("每一句。似乎有一个小秘密小彩蛋 "),gl=a("s",null,"(啊,有人敲门...我一会和你们说)",-1),Xl=a("h2",{id:"_2020-12-29",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-29","aria-hidden":"true"},"#"),u(" 2020.12.29")],-1),ml=u("透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, "),xl={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Sl=u("TG 群"),kl=u("火热测试中"),yl={id:"_2020-12-25-1-1-5",tabindex:"-1"},vl=a("a",{class:"header-anchor",href:"#_2020-12-25-1-1-5","aria-hidden":"true"},"#",-1),Tl=u(" 2020.12.25 "),Ll={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.5",target:"_blank",rel:"noopener noreferrer"},Dl=u("1.1.5"),Pl=a("p",null,"圣诞节快乐!",-1),Ul=a("li",null,"游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone",-1),Hl=a("li",null,"你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...",-1),jl=a("li",null,"(VLESS 的 UDP fullcone 和更多增强很快就到!)",-1),Cl=a("li",null,"无须再担心证书验证被墙,OCSP stapling 已经上线!",-1),Bl=u("kirin 带来了一大波 脚本更新."),Gl={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},Il=u("脚本在此"),Nl=a("li",null,"还有更多美味小樱桃!(不用问,更新品尝就对了)",-1),El=a("h2",{id:"_2020-12-24",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-24","aria-hidden":"true"},"#"),u(" 2020.12.24")],-1),Ol=u("因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。 网址为:"),wl={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},Fl=u("没错你正在看的就是"),Rl=a("p",null,"大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)",-1),Vl=u("文档网站需要不断完善和增加内容,以及完善设计。 因此更欢迎大家一起为文档建设添砖加瓦。 "),Ml={href:"https://github.com/XTLS/XTLS.github.io",target:"_blank",rel:"noopener noreferrer"},Al=u("文档的仓库"),ql=a("p",null,"仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站. 欢迎大家查看,纠错,修改,增加心得。",-1),Wl=a("h2",{id:"_2020-12-23",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-23","aria-hidden":"true"},"#"),u(" 2020.12.23")],-1),Ql=u("Xray-core Shadowsocks UDP FullCone 测试版, "),Yl={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Jl=u("TG 群"),zl=u("火热测试中"),Kl=a("h2",{id:"_2020-12-21",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-21","aria-hidden":"true"},"#"),u(" 2020.12.21")],-1),Zl=a("ul",null,[a("li",null,"Project X 群人数 2000+"),a("li",null,"群消息(含游戏群) 日均破万")],-1),$l={id:"_2020-12-18-1-1-4",tabindex:"-1"},er=a("a",{class:"header-anchor",href:"#_2020-12-18-1-1-4","aria-hidden":"true"},"#",-1),lr=u(" 2020.12.18 "),rr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.4",target:"_blank",rel:"noopener noreferrer"},ar=u("1.1.4"),nr=a("ul",null,[a("li",null,"更低的启动内占用和内存使用优化"),a("li",null,"随意定制的 TLS 提高你的 SSL 评级"),a("li",null,"支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS"),a("li",null,"还有在您路由器上使用的 Splice 最佳使用模式建议")],-1),ir=a("h2",{id:"_2020-12-17",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-17","aria-hidden":"true"},"#"),u(" 2020.12.17")],-1),tr=u("鉴于日益增长群人数和游戏需求, 开启了"),hr={href:"https://t.me/joinchat/UO4NixbB_XDQJOUjS6mHEQ",target:"_blank",rel:"noopener noreferrer"},ur=u("TG 游戏群"),or=a("h2",{id:"_2020-12-15",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-15","aria-hidden":"true"},"#"),u(" 2020.12.15")],-1),dr={href:"https://github.com/XTLS/Xray-install/tree/dev",target:"_blank",rel:"noopener noreferrer"},sr=u("安装脚本 dev 分支"),cr=u("开启, 持续更新功能中."),fr={id:"_2020-12-11-1-1-3",tabindex:"-1"},_r=a("a",{class:"header-anchor",href:"#_2020-12-11-1-1-3","aria-hidden":"true"},"#",-1),pr=u(" 2020.12.11 "),br={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.3",target:"_blank",rel:"noopener noreferrer"},gr=u("1.1.3"),Xr=a("ul",null,[a("li",null,"完整版本的 REDIRECT 透明代理模式."),a("li",null,"软路由 splice 流控模式的优化建议.")],-1),mr={id:"_2020-12-06-1-1-2",tabindex:"-1"},xr=a("a",{class:"header-anchor",href:"#_2020-12-06-1-1-2","aria-hidden":"true"},"#",-1),Sr=u(" 2020.12.06 "),kr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.2",target:"_blank",rel:"noopener noreferrer"},yr=u("1.1.2"),vr=h('
    • 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
    • 增强了 API 兼容

    2020.12.04

    增加 splice 模式

    2020.11.27

    • Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
    • 登上了 GitHub Trending
    • Project X 群人数破千,频道订阅数 500+
    ',5),Tr={id:"_2020-11-25-1-0-0",tabindex:"-1"},Lr=a("a",{class:"header-anchor",href:"#_2020-11-25-1-0-0","aria-hidden":"true"},"#",-1),Dr=u(" 2020.11.25 "),Pr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.0.0",target:"_blank",rel:"noopener noreferrer"},Ur=u("1.0.0"),Hr=a("p",null,"Xray 的第一个版本.",-1),jr=a("ul",null,[a("li",null,"基于 v2ray-core 修改而来,改动较大"),a("li",null,"全面增强, 性能卓越, 完全兼容")],-1),Cr=a("h2",{id:"_2020-11-23",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-11-23","aria-hidden":"true"},"#"),u(" 2020.11.23")],-1),Br=a("p",null,"project X start",-1),Gr=a("blockquote",null,[a("p",null,[a("s",null,"梦开始的时候")])],-1);o.render=function(h,u){const o=e("OutboundLink"),Ir=e("Badge"),Nr=e("RouterLink");return l(),r(t,null,[d,a("h2",s,[c,f,n(Ir,null,{default:i((()=>[a("a",_,[p,n(o)])])),_:1})]),b,a("h2",g,[X,m,n(Ir,null,{default:i((()=>[a("a",x,[S,n(o)])])),_:1})]),k,a("h2",y,[v,T,n(Ir,null,{default:i((()=>[a("a",L,[D,n(o)])])),_:1})]),P,a("h2",U,[H,j,n(Ir,null,{default:i((()=>[a("a",C,[B,n(o)])])),_:1})]),G,a("h2",I,[N,E,n(Ir,null,{default:i((()=>[a("a",O,[w,n(o)])])),_:1})]),F,R,a("ul",null,[a("li",null,[V,n(Nr,{to:"/document/level-1/"},{default:i((()=>[M])),_:1}),A]),q]),a("h2",W,[Q,Y,n(Ir,null,{default:i((()=>[a("a",J,[z,n(o)])])),_:1})]),a("ul",null,[K,Z,$,ee,le,a("li",null,[re,ae,ne,a("a",ie,[te,n(o)]),he]),ue]),oe,a("ul",null,[a("li",null,[de,se,ce,a("a",fe,[_e,n(o)]),pe]),a("li",null,[a("a",be,[ge,n(o)])])]),a("h2",Xe,[me,xe,n(Ir,null,{default:i((()=>[a("a",Se,[ke,n(o)])])),_:1})]),ye,a("ul",null,[ve,a("li",null,[Te,n(Nr,{to:"/document/level-0/"},{default:i((()=>[Le])),_:1}),De])]),a("h2",Pe,[Ue,He,n(Ir,null,{default:i((()=>[a("a",je,[Ce,n(o)])])),_:1})]),a("ul",null,[a("li",null,[n(Nr,{to:"/document/level-0/"},{default:i((()=>[Be])),_:1}),Ge]),Ie,a("li",null,[n(Nr,{to:"/document/level-2/"},{default:i((()=>[Ne])),_:1}),Ee]),Oe,a("li",null,[we,a("a",Fe,[Re,n(o)]),Ve,a("a",Me,[Ae,n(o)]),qe,a("a",We,[Qe,n(o)])])]),Ye,a("ul",null,[a("li",null,[Je,n(Nr,{to:"/document/level-2/tproxy.html"},{default:i((()=>[ze])),_:1}),Ke,Ze,$e,a("a",el,[ll,n(o)])]),rl]),al,a("p",null,[nl,n(Ir,null,{default:i((()=>[a("a",il,[tl,n(o)])])),_:1})]),hl,a("ul",null,[ul,a("li",null,[ol,a("a",dl,[sl,n(o)]),cl]),a("li",null,[fl,a("a",_l,[pl,n(o)]),bl,gl])]),Xl,a("p",null,[ml,a("a",xl,[Sl,n(o)]),kl]),a("h2",yl,[vl,Tl,n(Ir,null,{default:i((()=>[a("a",Ll,[Dl,n(o)])])),_:1})]),Pl,a("ul",null,[Ul,Hl,jl,Cl,a("li",null,[Bl,a("a",Gl,[Il,n(o)])]),Nl]),El,a("p",null,[Ol,a("a",wl,[Fl,n(o)])]),Rl,a("p",null,[Vl,a("a",Ml,[Al,n(o)])]),ql,Wl,a("p",null,[Ql,a("a",Yl,[Jl,n(o)]),zl]),Kl,Zl,a("h2",$l,[er,lr,n(Ir,null,{default:i((()=>[a("a",rr,[ar,n(o)])])),_:1})]),nr,ir,a("p",null,[tr,a("a",hr,[ur,n(o)])]),or,a("p",null,[a("a",dr,[sr,n(o)]),cr]),a("h2",fr,[_r,pr,n(Ir,null,{default:i((()=>[a("a",br,[gr,n(o)])])),_:1})]),Xr,a("h2",mr,[xr,Sr,n(Ir,null,{default:i((()=>[a("a",kr,[yr,n(o)])])),_:1})]),vr,a("h2",Tr,[Lr,Dr,n(Ir,null,{default:i((()=>[a("a",Pr,[Ur,n(o)])])),_:1})]),Hr,jr,Cr,Br,Gr],64)};export default o; +import{r as e,o as l,c as r,a,b as n,w as i,F as t,d as h,e as u}from"./app.48111a85.js";const o={},d=h('

    大史记

    2021.4.6

    • VuePress Next.
    • With Dark Mode.

    2021.4.4

    • 本文档迎来的新的首页。
    • 本文档迎来了暗黑模式。
    • 当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。
    • 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
    • 🎉🎉🎉
    ',5),s={id:"_2021-4-1-v1-4-2",tabindex:"-1"},c=a("a",{class:"header-anchor",href:"#_2021-4-1-v1-4-2","aria-hidden":"true"},"#",-1),f=u(" 2021.4.1 "),_={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.2",target:"_blank",rel:"noopener noreferrer"},p=u("v1.4.2"),b=h('
    • 不是愚人节玩笑,今天更新。
    • 加入 Browser Dialer,用与改变 TLS 指纹与行为。
    • 加入 uTLS,用与改变 TLS Client Hello 的指纹。
    • 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。

    2021.3.25

    没错还在变。 -_-

    2021.3.15

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

    ',5),g={id:"_2021-3-14-v1-4-0",tabindex:"-1"},X=a("a",{class:"header-anchor",href:"#_2021-3-14-v1-4-0","aria-hidden":"true"},"#",-1),m=u(" 2021.3.14 "),x={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.0",target:"_blank",rel:"noopener noreferrer"},S=u("v1.4.0"),k=h("
    • Happy Pi-Day!
    • 这次是个大更新:
      • 为链式代理引入了传输层支持。
      • 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
      • 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
      • 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
      • 添加了 FakeDNS。
      • 还修复了系列的问题,添加了各类功能,详情请见更新日志。
    • 还是 VuePress 比较爽啊(
    ",1),y={id:"_2021-3-3-1-3-1",tabindex:"-1"},v=a("a",{class:"header-anchor",href:"#_2021-3-3-1-3-1","aria-hidden":"true"},"#",-1),T=u(" 2021.3.3 "),L={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.1",target:"_blank",rel:"noopener noreferrer"},D=u("1.3.1"),P=a("ul",null,[a("li",null,"这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。"),a("li",null,[u("同时修复了一个会导致 Panic 的 bug。"),a("s",null,"Holmium_认为这是在骗、在偷袭。")]),a("li",null,"修复了几个遗留问题。")],-1),U={id:"_2021-2-14-1-3-0",tabindex:"-1"},H=a("a",{class:"header-anchor",href:"#_2021-2-14-1-3-0","aria-hidden":"true"},"#",-1),j=u(" 2021.2.14 "),C={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.0",target:"_blank",rel:"noopener noreferrer"},B=u("1.3.0"),G=a("ul",null,[a("li",null,"Happy 🐮 Year 🎉!"),a("li",null,"v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。"),a("li",null,"OHHHHHHHHHHHH!")],-1),I={id:"_2021-01-31-1-2-4",tabindex:"-1"},N=a("a",{class:"header-anchor",href:"#_2021-01-31-1-2-4","aria-hidden":"true"},"#",-1),E=u(" 2021.01.31 "),O={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.4",target:"_blank",rel:"noopener noreferrer"},w=u("1.2.4"),F=a("ul",null,[a("li",null,"解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。"),a("li",null,"似乎这个版本没有什么改变,但这只是暴风雨前的宁静。"),a("li",null,[u("(没错我就是先知) "),a("blockquote",null,[a("p",null,"你个傻子,你拿的是 UNO 牌。")])])],-1),R=a("h2",{id:"_2021-01-25",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2021-01-25","aria-hidden":"true"},"#"),u(" 2021.01.25")],-1),V=u("全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载"),M=u("秘籍第一层"),A=u("咯..."),q=a("li",null,[a("a",{href:"../en"},"英文版文档网站"),u("逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!")],-1),W={id:"_2021-01-22-1-2-3",tabindex:"-1"},Q=a("a",{class:"header-anchor",href:"#_2021-01-22-1-2-3","aria-hidden":"true"},"#",-1),Y=u(" 2021.01.22 "),J={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.3",target:"_blank",rel:"noopener noreferrer"},z=u("1.2.3"),K=a("li",null,[u("对 SS 协议的支持"),a("strong",null,"又"),u("变强了, 支持单端口多用户!")],-1),Z=a("li",null,[u("对 trojan 协议的支持也"),a("strong",null,"又"),u("变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!")],-1),$=a("li",null,[a("em",null,"(VLESS: 嘤嘤嘤)")],-1),ee=a("li",null,'UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".',-1),le=a("li",null,"嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.",-1),re=u("向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 "),ae=a("img",{src:"https://avatars2.githubusercontent.com/u/8384161?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ne=u(),ie={href:"https://github.com/bohanyang",target:"_blank",rel:"noopener noreferrer"},te=u("@Bohan Yang"),he=u(" 致敬!"),ue=a("li",null,"其他美味小樱桃, 惯例更新品尝就对啦.",-1),oe=h('

    2021.01.19

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

    2021.01.17

    ',3),de=u("辛苦的翻译工作开始了, 感谢"),se=a("img",{src:"https://avatars2.githubusercontent.com/u/60207794?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ce=u(),fe={href:"https://github.com/jiuqi9997",target:"_blank",rel:"noopener noreferrer"},_e=u("@玖柒 Max"),pe=u("和其他所有的翻译大佬们."),be={href:"https://xtls.github.io/en/",target:"_blank",rel:"noopener noreferrer"},ge=u("English version"),Xe={id:"_2021-01-15-1-2-2",tabindex:"-1"},me=a("a",{class:"header-anchor",href:"#_2021-01-15-1-2-2","aria-hidden":"true"},"#",-1),xe=u(" 2021.01.15 "),Se={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.2",target:"_blank",rel:"noopener noreferrer"},ke=u("1.2.2"),ye=h('
    • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
    • 之前预告的 UUID 修改正式上线.(往下看往下看)
    • 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
    • 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
    • 当然还有其他各种小糖果.(更新品尝就对了)
    • 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE

    2021.01.12

    ',2),ve=a("li",null,[u("将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户. "),a("ul",null,[a("li",null,'客户端写 "id": "我爱 🍉 老师 1314",'),a("li",null,[u('服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 '),a("code",null,"我爱🍉老师1314"),u(" 的 UUID 映射)")])])],-1),Te=u("🍉 老师的"),Le=u("小小白白话文"),De=u("大结局, 撒花."),Pe={id:"_2021-01-10-1-2-1",tabindex:"-1"},Ue=a("a",{class:"header-anchor",href:"#_2021-01-10-1-2-1","aria-hidden":"true"},"#",-1),He=u(" 2021.01.10 "),je={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.1",target:"_blank",rel:"noopener noreferrer"},Ce=u("1.2.1"),Be=u("小小白白话文"),Ge=u("连载上线啦,🍉 老师呕心沥血之作, 手把手教你从什么都不会到熟练配置 Xray!"),Ie=a("li",null,"(可能是整个互联网上, 最详细最有耐心的教你从 0 开始配置的教程)",-1),Ne=u("透明代理"),Ee=u("也增加了更多文章."),Oe=a("li",null,"还有很多细节修改, 文档将会越来越规范!",-1),we=u("感谢 "),Fe={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},Re=u("@ricuhkaen"),Ve=u(" , "),Me={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},Ae=u("@BioniCosmos"),qe=u(", "),We={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},Qe=u("@kirin"),Ye=h('
    • 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
    • Google Voice 应该也可以正常使用 v2rayNG 拨打了.
    • 日志现在看起来更顺眼.

    2021.01.07

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

    2021.01.05

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

    2021.01.03

    ',6),Je=u("文档仓库第一个 PR。🎉 "),ze=u("透明代理(TProxy)配置教程 "),Ke=u(" ,感谢"),Ze=a("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32px",height:"32px",alt:"a"},null,-1),$e=u(),el={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},ll=u("@BioniCosmos"),rl=a("li",null,"tg 群突破 2500。",-1),al=a("h2",{id:"_2021-01-01",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2021-01-01","aria-hidden":"true"},"#"),u(" 2021.01.01")],-1),nl=u("【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 "),il={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},tl=u("1.2.0"),hl=a("p",null,"🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!",-1),ul=h('
  • 圣诞礼物v1.1.5后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
  • (UDP 还会继续增强!)
  • 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
  • (不,下面不是广告,是里程碑。)
  • Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
    • 一人扛起了所有!支持各大主流协议!
    • 一骑绝尘的性能!
    • 日趋完善的功能!
    • 可怕的生命力与社区亲和力!
  • ',5),ol=u("Xray 将继续保持前行! 因此 "),dl={href:"https://github.com/XTLS/Xray-core/discussions/56",target:"_blank",rel:"noopener noreferrer"},sl=u("Xray 需要更多的英雄!!"),cl=u("!"),fl=u("PS:请品,请细品"),_l={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},pl=u("release notes"),bl=u("每一句。似乎有一个小秘密小彩蛋 "),gl=a("s",null,"(啊,有人敲门...我一会和你们说)",-1),Xl=a("h2",{id:"_2020-12-29",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-29","aria-hidden":"true"},"#"),u(" 2020.12.29")],-1),ml=u("透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, "),xl={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Sl=u("TG 群"),kl=u("火热测试中"),yl={id:"_2020-12-25-1-1-5",tabindex:"-1"},vl=a("a",{class:"header-anchor",href:"#_2020-12-25-1-1-5","aria-hidden":"true"},"#",-1),Tl=u(" 2020.12.25 "),Ll={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.5",target:"_blank",rel:"noopener noreferrer"},Dl=u("1.1.5"),Pl=a("p",null,"圣诞节快乐!",-1),Ul=a("li",null,"游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone",-1),Hl=a("li",null,"你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...",-1),jl=a("li",null,"(VLESS 的 UDP fullcone 和更多增强很快就到!)",-1),Cl=a("li",null,"无须再担心证书验证被墙,OCSP stapling 已经上线!",-1),Bl=u("kirin 带来了一大波 脚本更新."),Gl={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},Il=u("脚本在此"),Nl=a("li",null,"还有更多美味小樱桃!(不用问,更新品尝就对了)",-1),El=a("h2",{id:"_2020-12-24",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-24","aria-hidden":"true"},"#"),u(" 2020.12.24")],-1),Ol=u("因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。 网址为:"),wl={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},Fl=u("没错你正在看的就是"),Rl=a("p",null,"大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)",-1),Vl=u("文档网站需要不断完善和增加内容,以及完善设计。 因此更欢迎大家一起为文档建设添砖加瓦。 "),Ml={href:"https://github.com/XTLS/XTLS.github.io",target:"_blank",rel:"noopener noreferrer"},Al=u("文档的仓库"),ql=a("p",null,"仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站. 欢迎大家查看,纠错,修改,增加心得。",-1),Wl=a("h2",{id:"_2020-12-23",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-23","aria-hidden":"true"},"#"),u(" 2020.12.23")],-1),Ql=u("Xray-core Shadowsocks UDP FullCone 测试版, "),Yl={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Jl=u("TG 群"),zl=u("火热测试中"),Kl=a("h2",{id:"_2020-12-21",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-21","aria-hidden":"true"},"#"),u(" 2020.12.21")],-1),Zl=a("ul",null,[a("li",null,"Project X 群人数 2000+"),a("li",null,"群消息(含游戏群) 日均破万")],-1),$l={id:"_2020-12-18-1-1-4",tabindex:"-1"},er=a("a",{class:"header-anchor",href:"#_2020-12-18-1-1-4","aria-hidden":"true"},"#",-1),lr=u(" 2020.12.18 "),rr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.4",target:"_blank",rel:"noopener noreferrer"},ar=u("1.1.4"),nr=a("ul",null,[a("li",null,"更低的启动内占用和内存使用优化"),a("li",null,"随意定制的 TLS 提高你的 SSL 评级"),a("li",null,"支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS"),a("li",null,"还有在您路由器上使用的 Splice 最佳使用模式建议")],-1),ir=a("h2",{id:"_2020-12-17",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-17","aria-hidden":"true"},"#"),u(" 2020.12.17")],-1),tr=u("鉴于日益增长群人数和游戏需求, 开启了"),hr={href:"https://t.me/joinchat/UO4NixbB_XDQJOUjS6mHEQ",target:"_blank",rel:"noopener noreferrer"},ur=u("TG 游戏群"),or=a("h2",{id:"_2020-12-15",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-15","aria-hidden":"true"},"#"),u(" 2020.12.15")],-1),dr={href:"https://github.com/XTLS/Xray-install/tree/dev",target:"_blank",rel:"noopener noreferrer"},sr=u("安装脚本 dev 分支"),cr=u("开启, 持续更新功能中."),fr={id:"_2020-12-11-1-1-3",tabindex:"-1"},_r=a("a",{class:"header-anchor",href:"#_2020-12-11-1-1-3","aria-hidden":"true"},"#",-1),pr=u(" 2020.12.11 "),br={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.3",target:"_blank",rel:"noopener noreferrer"},gr=u("1.1.3"),Xr=a("ul",null,[a("li",null,"完整版本的 REDIRECT 透明代理模式."),a("li",null,"软路由 splice 流控模式的优化建议.")],-1),mr={id:"_2020-12-06-1-1-2",tabindex:"-1"},xr=a("a",{class:"header-anchor",href:"#_2020-12-06-1-1-2","aria-hidden":"true"},"#",-1),Sr=u(" 2020.12.06 "),kr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.2",target:"_blank",rel:"noopener noreferrer"},yr=u("1.1.2"),vr=h('
    • 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
    • 增强了 API 兼容

    2020.12.04

    增加 splice 模式

    2020.11.27

    • Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
    • 登上了 GitHub Trending
    • Project X 群人数破千,频道订阅数 500+
    ',5),Tr={id:"_2020-11-25-1-0-0",tabindex:"-1"},Lr=a("a",{class:"header-anchor",href:"#_2020-11-25-1-0-0","aria-hidden":"true"},"#",-1),Dr=u(" 2020.11.25 "),Pr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.0.0",target:"_blank",rel:"noopener noreferrer"},Ur=u("1.0.0"),Hr=a("p",null,"Xray 的第一个版本.",-1),jr=a("ul",null,[a("li",null,"基于 v2ray-core 修改而来,改动较大"),a("li",null,"全面增强, 性能卓越, 完全兼容")],-1),Cr=a("h2",{id:"_2020-11-23",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-11-23","aria-hidden":"true"},"#"),u(" 2020.11.23")],-1),Br=a("p",null,"project X start",-1),Gr=a("blockquote",null,[a("p",null,[a("s",null,"梦开始的时候")])],-1);o.render=function(h,u){const o=e("OutboundLink"),Ir=e("Badge"),Nr=e("RouterLink");return l(),r(t,null,[d,a("h2",s,[c,f,n(Ir,null,{default:i((()=>[a("a",_,[p,n(o)])])),_:1})]),b,a("h2",g,[X,m,n(Ir,null,{default:i((()=>[a("a",x,[S,n(o)])])),_:1})]),k,a("h2",y,[v,T,n(Ir,null,{default:i((()=>[a("a",L,[D,n(o)])])),_:1})]),P,a("h2",U,[H,j,n(Ir,null,{default:i((()=>[a("a",C,[B,n(o)])])),_:1})]),G,a("h2",I,[N,E,n(Ir,null,{default:i((()=>[a("a",O,[w,n(o)])])),_:1})]),F,R,a("ul",null,[a("li",null,[V,n(Nr,{to:"/document/level-1/"},{default:i((()=>[M])),_:1}),A]),q]),a("h2",W,[Q,Y,n(Ir,null,{default:i((()=>[a("a",J,[z,n(o)])])),_:1})]),a("ul",null,[K,Z,$,ee,le,a("li",null,[re,ae,ne,a("a",ie,[te,n(o)]),he]),ue]),oe,a("ul",null,[a("li",null,[de,se,ce,a("a",fe,[_e,n(o)]),pe]),a("li",null,[a("a",be,[ge,n(o)])])]),a("h2",Xe,[me,xe,n(Ir,null,{default:i((()=>[a("a",Se,[ke,n(o)])])),_:1})]),ye,a("ul",null,[ve,a("li",null,[Te,n(Nr,{to:"/document/level-0/"},{default:i((()=>[Le])),_:1}),De])]),a("h2",Pe,[Ue,He,n(Ir,null,{default:i((()=>[a("a",je,[Ce,n(o)])])),_:1})]),a("ul",null,[a("li",null,[n(Nr,{to:"/document/level-0/"},{default:i((()=>[Be])),_:1}),Ge]),Ie,a("li",null,[n(Nr,{to:"/document/level-2/"},{default:i((()=>[Ne])),_:1}),Ee]),Oe,a("li",null,[we,a("a",Fe,[Re,n(o)]),Ve,a("a",Me,[Ae,n(o)]),qe,a("a",We,[Qe,n(o)])])]),Ye,a("ul",null,[a("li",null,[Je,n(Nr,{to:"/document/level-2/tproxy.html"},{default:i((()=>[ze])),_:1}),Ke,Ze,$e,a("a",el,[ll,n(o)])]),rl]),al,a("p",null,[nl,n(Ir,null,{default:i((()=>[a("a",il,[tl,n(o)])])),_:1})]),hl,a("ul",null,[ul,a("li",null,[ol,a("a",dl,[sl,n(o)]),cl]),a("li",null,[fl,a("a",_l,[pl,n(o)]),bl,gl])]),Xl,a("p",null,[ml,a("a",xl,[Sl,n(o)]),kl]),a("h2",yl,[vl,Tl,n(Ir,null,{default:i((()=>[a("a",Ll,[Dl,n(o)])])),_:1})]),Pl,a("ul",null,[Ul,Hl,jl,Cl,a("li",null,[Bl,a("a",Gl,[Il,n(o)])]),Nl]),El,a("p",null,[Ol,a("a",wl,[Fl,n(o)])]),Rl,a("p",null,[Vl,a("a",Ml,[Al,n(o)])]),ql,Wl,a("p",null,[Ql,a("a",Yl,[Jl,n(o)]),zl]),Kl,Zl,a("h2",$l,[er,lr,n(Ir,null,{default:i((()=>[a("a",rr,[ar,n(o)])])),_:1})]),nr,ir,a("p",null,[tr,a("a",hr,[ur,n(o)])]),or,a("p",null,[a("a",dr,[sr,n(o)]),cr]),a("h2",fr,[_r,pr,n(Ir,null,{default:i((()=>[a("a",br,[gr,n(o)])])),_:1})]),Xr,a("h2",mr,[xr,Sr,n(Ir,null,{default:i((()=>[a("a",kr,[yr,n(o)])])),_:1})]),vr,a("h2",Tr,[Lr,Dr,n(Ir,null,{default:i((()=>[a("a",Pr,[Ur,n(o)])])),_:1})]),Hr,jr,Cr,Br,Gr],64)};export default o; diff --git a/assets/news.html.531ce213.js b/assets/news.html.8c2d830a.js similarity index 99% rename from assets/news.html.531ce213.js rename to assets/news.html.8c2d830a.js index 19e03c3f3..382628788 100644 --- a/assets/news.html.531ce213.js +++ b/assets/news.html.8c2d830a.js @@ -1 +1 @@ -import{r as e,o as l,c as r,a,b as n,w as i,F as t,d as h,e as u}from"./app.755d843f.js";const o={},d=h('

    大史记

    2021.4.6

    • VuePress Next.
    • With Dark Mode.

    2021.4.4

    • 本文档迎来的新的首页。
    • 本文档迎来了暗黑模式。
    • 当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。
    • 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
    • 🎉🎉🎉
    ',5),s={id:"_2021-4-1-v1-4-2",tabindex:"-1"},c=a("a",{class:"header-anchor",href:"#_2021-4-1-v1-4-2","aria-hidden":"true"},"#",-1),f=u(" 2021.4.1 "),_={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.2",target:"_blank",rel:"noopener noreferrer"},p=u("v1.4.2"),b=h('
    • 不是愚人节玩笑,今天更新。
    • 加入 Browser Dialer,用与改变 TLS 指纹与行为。
    • 加入 uTLS,用与改变 TLS Client Hello 的指纹。
    • 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。

    2021.3.25

    没错还在变。 -_-

    2021.3.15

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

    ',5),g={id:"_2021-3-14-v1-4-0",tabindex:"-1"},X=a("a",{class:"header-anchor",href:"#_2021-3-14-v1-4-0","aria-hidden":"true"},"#",-1),m=u(" 2021.3.14 "),x={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.0",target:"_blank",rel:"noopener noreferrer"},S=u("v1.4.0"),k=h("
    • Happy Pi-Day!
    • 这次是个大更新:
      • 为链式代理引入了传输层支持。
      • 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
      • 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
      • 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
      • 添加了 FakeDNS。
      • 还修复了系列的问题,添加了各类功能,详情请见更新日志。
    • 还是 VuePress 比较爽啊(
    ",1),y={id:"_2021-3-3-1-3-1",tabindex:"-1"},v=a("a",{class:"header-anchor",href:"#_2021-3-3-1-3-1","aria-hidden":"true"},"#",-1),T=u(" 2021.3.3 "),L={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.1",target:"_blank",rel:"noopener noreferrer"},D=u("1.3.1"),P=a("ul",null,[a("li",null,"这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。"),a("li",null,[u("同时修复了一个会导致 Panic 的 bug。"),a("s",null,"Holmium_认为这是在骗、在偷袭。")]),a("li",null,"修复了几个遗留问题。")],-1),U={id:"_2021-2-14-1-3-0",tabindex:"-1"},H=a("a",{class:"header-anchor",href:"#_2021-2-14-1-3-0","aria-hidden":"true"},"#",-1),j=u(" 2021.2.14 "),C={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.0",target:"_blank",rel:"noopener noreferrer"},B=u("1.3.0"),G=a("ul",null,[a("li",null,"Happy 🐮 Year 🎉!"),a("li",null,"v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。"),a("li",null,"OHHHHHHHHHHHH!")],-1),I={id:"_2021-01-31-1-2-4",tabindex:"-1"},N=a("a",{class:"header-anchor",href:"#_2021-01-31-1-2-4","aria-hidden":"true"},"#",-1),E=u(" 2021.01.31 "),O={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.4",target:"_blank",rel:"noopener noreferrer"},w=u("1.2.4"),F=a("ul",null,[a("li",null,"解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。"),a("li",null,"似乎这个版本没有什么改变,但这只是暴风雨前的宁静。"),a("li",null,[u("(没错我就是先知) "),a("blockquote",null,[a("p",null,"你个傻子,你拿的是 UNO 牌。")])])],-1),R=a("h2",{id:"_2021-01-25",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2021-01-25","aria-hidden":"true"},"#"),u(" 2021.01.25")],-1),V=u("全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载"),M=u("秘籍第一层"),A=u("咯..."),q=a("li",null,[a("a",{href:"../en"},"英文版文档网站"),u("逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!")],-1),W={id:"_2021-01-22-1-2-3",tabindex:"-1"},Q=a("a",{class:"header-anchor",href:"#_2021-01-22-1-2-3","aria-hidden":"true"},"#",-1),Y=u(" 2021.01.22 "),J={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.3",target:"_blank",rel:"noopener noreferrer"},z=u("1.2.3"),K=a("li",null,[u("对 SS 协议的支持"),a("strong",null,"又"),u("变强了, 支持单端口多用户!")],-1),Z=a("li",null,[u("对 trojan 协议的支持也"),a("strong",null,"又"),u("变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!")],-1),$=a("li",null,[a("em",null,"(VLESS: 嘤嘤嘤)")],-1),ee=a("li",null,'UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".',-1),le=a("li",null,"嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.",-1),re=u("向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 "),ae=a("img",{src:"https://avatars2.githubusercontent.com/u/8384161?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ne=u(),ie={href:"https://github.com/bohanyang",target:"_blank",rel:"noopener noreferrer"},te=u("@Bohan Yang"),he=u(" 致敬!"),ue=a("li",null,"其他美味小樱桃, 惯例更新品尝就对啦.",-1),oe=h('

    2021.01.19

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

    2021.01.17

    ',3),de=u("辛苦的翻译工作开始了, 感谢"),se=a("img",{src:"https://avatars2.githubusercontent.com/u/60207794?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ce=u(),fe={href:"https://github.com/jiuqi9997",target:"_blank",rel:"noopener noreferrer"},_e=u("@玖柒 Max"),pe=u("和其他所有的翻译大佬们."),be={href:"https://xtls.github.io/en/",target:"_blank",rel:"noopener noreferrer"},ge=u("English version"),Xe={id:"_2021-01-15-1-2-2",tabindex:"-1"},me=a("a",{class:"header-anchor",href:"#_2021-01-15-1-2-2","aria-hidden":"true"},"#",-1),xe=u(" 2021.01.15 "),Se={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.2",target:"_blank",rel:"noopener noreferrer"},ke=u("1.2.2"),ye=h('
    • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
    • 之前预告的 UUID 修改正式上线.(往下看往下看)
    • 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
    • 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
    • 当然还有其他各种小糖果.(更新品尝就对了)
    • 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE

    2021.01.12

    ',2),ve=a("li",null,[u("将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户. "),a("ul",null,[a("li",null,'客户端写 "id": "我爱 🍉 老师 1314",'),a("li",null,[u('服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 '),a("code",null,"我爱🍉老师1314"),u(" 的 UUID 映射)")])])],-1),Te=u("🍉 老师的"),Le=u("小小白白话文"),De=u("大结局, 撒花."),Pe={id:"_2021-01-10-1-2-1",tabindex:"-1"},Ue=a("a",{class:"header-anchor",href:"#_2021-01-10-1-2-1","aria-hidden":"true"},"#",-1),He=u(" 2021.01.10 "),je={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.1",target:"_blank",rel:"noopener noreferrer"},Ce=u("1.2.1"),Be=u("小小白白话文"),Ge=u("连载上线啦,🍉 老师呕心沥血之作, 手把手教你从什么都不会到熟练配置 Xray!"),Ie=a("li",null,"(可能是整个互联网上, 最详细最有耐心的教你从 0 开始配置的教程)",-1),Ne=u("透明代理"),Ee=u("也增加了更多文章."),Oe=a("li",null,"还有很多细节修改, 文档将会越来越规范!",-1),we=u("感谢 "),Fe={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},Re=u("@ricuhkaen"),Ve=u(" , "),Me={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},Ae=u("@BioniCosmos"),qe=u(", "),We={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},Qe=u("@kirin"),Ye=h('
    • 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
    • Google Voice 应该也可以正常使用 v2rayNG 拨打了.
    • 日志现在看起来更顺眼.

    2021.01.07

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

    2021.01.05

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

    2021.01.03

    ',6),Je=u("文档仓库第一个 PR。🎉 "),ze=u("透明代理(TProxy)配置教程 "),Ke=u(" ,感谢"),Ze=a("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32px",height:"32px",alt:"a"},null,-1),$e=u(),el={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},ll=u("@BioniCosmos"),rl=a("li",null,"tg 群突破 2500。",-1),al=a("h2",{id:"_2021-01-01",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2021-01-01","aria-hidden":"true"},"#"),u(" 2021.01.01")],-1),nl=u("【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 "),il={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},tl=u("1.2.0"),hl=a("p",null,"🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!",-1),ul=h('
  • 圣诞礼物v1.1.5后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
  • (UDP 还会继续增强!)
  • 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
  • (不,下面不是广告,是里程碑。)
  • Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
    • 一人扛起了所有!支持各大主流协议!
    • 一骑绝尘的性能!
    • 日趋完善的功能!
    • 可怕的生命力与社区亲和力!
  • ',5),ol=u("Xray 将继续保持前行! 因此 "),dl={href:"https://github.com/XTLS/Xray-core/discussions/56",target:"_blank",rel:"noopener noreferrer"},sl=u("Xray 需要更多的英雄!!"),cl=u("!"),fl=u("PS:请品,请细品"),_l={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},pl=u("release notes"),bl=u("每一句。似乎有一个小秘密小彩蛋 "),gl=a("s",null,"(啊,有人敲门...我一会和你们说)",-1),Xl=a("h2",{id:"_2020-12-29",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-29","aria-hidden":"true"},"#"),u(" 2020.12.29")],-1),ml=u("透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, "),xl={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Sl=u("TG 群"),kl=u("火热测试中"),yl={id:"_2020-12-25-1-1-5",tabindex:"-1"},vl=a("a",{class:"header-anchor",href:"#_2020-12-25-1-1-5","aria-hidden":"true"},"#",-1),Tl=u(" 2020.12.25 "),Ll={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.5",target:"_blank",rel:"noopener noreferrer"},Dl=u("1.1.5"),Pl=a("p",null,"圣诞节快乐!",-1),Ul=a("li",null,"游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone",-1),Hl=a("li",null,"你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...",-1),jl=a("li",null,"(VLESS 的 UDP fullcone 和更多增强很快就到!)",-1),Cl=a("li",null,"无须再担心证书验证被墙,OCSP stapling 已经上线!",-1),Bl=u("kirin 带来了一大波 脚本更新."),Gl={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},Il=u("脚本在此"),Nl=a("li",null,"还有更多美味小樱桃!(不用问,更新品尝就对了)",-1),El=a("h2",{id:"_2020-12-24",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-24","aria-hidden":"true"},"#"),u(" 2020.12.24")],-1),Ol=u("因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。 网址为:"),wl={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},Fl=u("没错你正在看的就是"),Rl=a("p",null,"大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)",-1),Vl=u("文档网站需要不断完善和增加内容,以及完善设计。 因此更欢迎大家一起为文档建设添砖加瓦。 "),Ml={href:"https://github.com/XTLS/XTLS.github.io",target:"_blank",rel:"noopener noreferrer"},Al=u("文档的仓库"),ql=a("p",null,"仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站. 欢迎大家查看,纠错,修改,增加心得。",-1),Wl=a("h2",{id:"_2020-12-23",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-23","aria-hidden":"true"},"#"),u(" 2020.12.23")],-1),Ql=u("Xray-core Shadowsocks UDP FullCone 测试版, "),Yl={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Jl=u("TG 群"),zl=u("火热测试中"),Kl=a("h2",{id:"_2020-12-21",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-21","aria-hidden":"true"},"#"),u(" 2020.12.21")],-1),Zl=a("ul",null,[a("li",null,"Project X 群人数 2000+"),a("li",null,"群消息(含游戏群) 日均破万")],-1),$l={id:"_2020-12-18-1-1-4",tabindex:"-1"},er=a("a",{class:"header-anchor",href:"#_2020-12-18-1-1-4","aria-hidden":"true"},"#",-1),lr=u(" 2020.12.18 "),rr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.4",target:"_blank",rel:"noopener noreferrer"},ar=u("1.1.4"),nr=a("ul",null,[a("li",null,"更低的启动内占用和内存使用优化"),a("li",null,"随意定制的 TLS 提高你的 SSL 评级"),a("li",null,"支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS"),a("li",null,"还有在您路由器上使用的 Splice 最佳使用模式建议")],-1),ir=a("h2",{id:"_2020-12-17",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-17","aria-hidden":"true"},"#"),u(" 2020.12.17")],-1),tr=u("鉴于日益增长群人数和游戏需求, 开启了"),hr={href:"https://t.me/joinchat/UO4NixbB_XDQJOUjS6mHEQ",target:"_blank",rel:"noopener noreferrer"},ur=u("TG 游戏群"),or=a("h2",{id:"_2020-12-15",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-15","aria-hidden":"true"},"#"),u(" 2020.12.15")],-1),dr={href:"https://github.com/XTLS/Xray-install/tree/dev",target:"_blank",rel:"noopener noreferrer"},sr=u("安装脚本 dev 分支"),cr=u("开启, 持续更新功能中."),fr={id:"_2020-12-11-1-1-3",tabindex:"-1"},_r=a("a",{class:"header-anchor",href:"#_2020-12-11-1-1-3","aria-hidden":"true"},"#",-1),pr=u(" 2020.12.11 "),br={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.3",target:"_blank",rel:"noopener noreferrer"},gr=u("1.1.3"),Xr=a("ul",null,[a("li",null,"完整版本的 REDIRECT 透明代理模式."),a("li",null,"软路由 splice 流控模式的优化建议.")],-1),mr={id:"_2020-12-06-1-1-2",tabindex:"-1"},xr=a("a",{class:"header-anchor",href:"#_2020-12-06-1-1-2","aria-hidden":"true"},"#",-1),Sr=u(" 2020.12.06 "),kr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.2",target:"_blank",rel:"noopener noreferrer"},yr=u("1.1.2"),vr=h('
    • 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
    • 增强了 API 兼容

    2020.12.04

    增加 splice 模式

    2020.11.27

    • Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
    • 登上了 GitHub Trending
    • Project X 群人数破千,频道订阅数 500+
    ',5),Tr={id:"_2020-11-25-1-0-0",tabindex:"-1"},Lr=a("a",{class:"header-anchor",href:"#_2020-11-25-1-0-0","aria-hidden":"true"},"#",-1),Dr=u(" 2020.11.25 "),Pr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.0.0",target:"_blank",rel:"noopener noreferrer"},Ur=u("1.0.0"),Hr=a("p",null,"Xray 的第一个版本.",-1),jr=a("ul",null,[a("li",null,"基于 v2ray-core 修改而来,改动较大"),a("li",null,"全面增强, 性能卓越, 完全兼容")],-1),Cr=a("h2",{id:"_2020-11-23",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-11-23","aria-hidden":"true"},"#"),u(" 2020.11.23")],-1),Br=a("p",null,"project X start",-1),Gr=a("blockquote",null,[a("p",null,[a("s",null,"梦开始的时候")])],-1);o.render=function(h,u){const o=e("OutboundLink"),Ir=e("Badge"),Nr=e("RouterLink");return l(),r(t,null,[d,a("h2",s,[c,f,n(Ir,null,{default:i((()=>[a("a",_,[p,n(o)])])),_:1})]),b,a("h2",g,[X,m,n(Ir,null,{default:i((()=>[a("a",x,[S,n(o)])])),_:1})]),k,a("h2",y,[v,T,n(Ir,null,{default:i((()=>[a("a",L,[D,n(o)])])),_:1})]),P,a("h2",U,[H,j,n(Ir,null,{default:i((()=>[a("a",C,[B,n(o)])])),_:1})]),G,a("h2",I,[N,E,n(Ir,null,{default:i((()=>[a("a",O,[w,n(o)])])),_:1})]),F,R,a("ul",null,[a("li",null,[V,n(Nr,{to:"/en/document/level-1/"},{default:i((()=>[M])),_:1}),A]),q]),a("h2",W,[Q,Y,n(Ir,null,{default:i((()=>[a("a",J,[z,n(o)])])),_:1})]),a("ul",null,[K,Z,$,ee,le,a("li",null,[re,ae,ne,a("a",ie,[te,n(o)]),he]),ue]),oe,a("ul",null,[a("li",null,[de,se,ce,a("a",fe,[_e,n(o)]),pe]),a("li",null,[a("a",be,[ge,n(o)])])]),a("h2",Xe,[me,xe,n(Ir,null,{default:i((()=>[a("a",Se,[ke,n(o)])])),_:1})]),ye,a("ul",null,[ve,a("li",null,[Te,n(Nr,{to:"/en/document/level-0/"},{default:i((()=>[Le])),_:1}),De])]),a("h2",Pe,[Ue,He,n(Ir,null,{default:i((()=>[a("a",je,[Ce,n(o)])])),_:1})]),a("ul",null,[a("li",null,[n(Nr,{to:"/en/document/level-0/"},{default:i((()=>[Be])),_:1}),Ge]),Ie,a("li",null,[n(Nr,{to:"/en/document/level-2/"},{default:i((()=>[Ne])),_:1}),Ee]),Oe,a("li",null,[we,a("a",Fe,[Re,n(o)]),Ve,a("a",Me,[Ae,n(o)]),qe,a("a",We,[Qe,n(o)])])]),Ye,a("ul",null,[a("li",null,[Je,n(Nr,{to:"/en/document/level-2/tproxy.html"},{default:i((()=>[ze])),_:1}),Ke,Ze,$e,a("a",el,[ll,n(o)])]),rl]),al,a("p",null,[nl,n(Ir,null,{default:i((()=>[a("a",il,[tl,n(o)])])),_:1})]),hl,a("ul",null,[ul,a("li",null,[ol,a("a",dl,[sl,n(o)]),cl]),a("li",null,[fl,a("a",_l,[pl,n(o)]),bl,gl])]),Xl,a("p",null,[ml,a("a",xl,[Sl,n(o)]),kl]),a("h2",yl,[vl,Tl,n(Ir,null,{default:i((()=>[a("a",Ll,[Dl,n(o)])])),_:1})]),Pl,a("ul",null,[Ul,Hl,jl,Cl,a("li",null,[Bl,a("a",Gl,[Il,n(o)])]),Nl]),El,a("p",null,[Ol,a("a",wl,[Fl,n(o)])]),Rl,a("p",null,[Vl,a("a",Ml,[Al,n(o)])]),ql,Wl,a("p",null,[Ql,a("a",Yl,[Jl,n(o)]),zl]),Kl,Zl,a("h2",$l,[er,lr,n(Ir,null,{default:i((()=>[a("a",rr,[ar,n(o)])])),_:1})]),nr,ir,a("p",null,[tr,a("a",hr,[ur,n(o)])]),or,a("p",null,[a("a",dr,[sr,n(o)]),cr]),a("h2",fr,[_r,pr,n(Ir,null,{default:i((()=>[a("a",br,[gr,n(o)])])),_:1})]),Xr,a("h2",mr,[xr,Sr,n(Ir,null,{default:i((()=>[a("a",kr,[yr,n(o)])])),_:1})]),vr,a("h2",Tr,[Lr,Dr,n(Ir,null,{default:i((()=>[a("a",Pr,[Ur,n(o)])])),_:1})]),Hr,jr,Cr,Br,Gr],64)};export default o; +import{r as e,o as l,c as r,a,b as n,w as i,F as t,d as h,e as u}from"./app.48111a85.js";const o={},d=h('

    大史记

    2021.4.6

    • VuePress Next.
    • With Dark Mode.

    2021.4.4

    • 本文档迎来的新的首页。
    • 本文档迎来了暗黑模式。
    • 当然,暗黑模式还有各种各样的问题。具体的内容还需要慢慢调整。
    • 另:Telegram 群聊突破了 5000 人!还加入了 Anti-Spam 机器人!
    • 🎉🎉🎉
    ',5),s={id:"_2021-4-1-v1-4-2",tabindex:"-1"},c=a("a",{class:"header-anchor",href:"#_2021-4-1-v1-4-2","aria-hidden":"true"},"#",-1),f=u(" 2021.4.1 "),_={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.2",target:"_blank",rel:"noopener noreferrer"},p=u("v1.4.2"),b=h('
    • 不是愚人节玩笑,今天更新。
    • 加入 Browser Dialer,用与改变 TLS 指纹与行为。
    • 加入 uTLS,用与改变 TLS Client Hello 的指纹。
    • 顺便修复了一大堆奇妙的问题,具体的内容见更新日志。

    2021.3.25

    没错还在变。 -_-

    2021.3.15

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

    ',5),g={id:"_2021-3-14-v1-4-0",tabindex:"-1"},X=a("a",{class:"header-anchor",href:"#_2021-3-14-v1-4-0","aria-hidden":"true"},"#",-1),m=u(" 2021.3.14 "),x={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.4.0",target:"_blank",rel:"noopener noreferrer"},S=u("v1.4.0"),k=h("
    • Happy Pi-Day!
    • 这次是个大更新:
      • 为链式代理引入了传输层支持。
      • 为 Dialer 引入了 Domain Strategy,解决奇妙的 DNS 问题。
      • 添加了 gRPC 传输方式,与更快一点的 Multi Mode。
      • 添加了 WebSocket Early-Data 功能,减少了 WebSocket 的延迟。
      • 添加了 FakeDNS。
      • 还修复了系列的问题,添加了各类功能,详情请见更新日志。
    • 还是 VuePress 比较爽啊(
    ",1),y={id:"_2021-3-3-1-3-1",tabindex:"-1"},v=a("a",{class:"header-anchor",href:"#_2021-3-3-1-3-1","aria-hidden":"true"},"#",-1),T=u(" 2021.3.3 "),L={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.1",target:"_blank",rel:"noopener noreferrer"},D=u("1.3.1"),P=a("ul",null,[a("li",null,"这个版本使用了 Golang 1.16,正式原生支持 Apple Silicon。"),a("li",null,[u("同时修复了一个会导致 Panic 的 bug。"),a("s",null,"Holmium_认为这是在骗、在偷袭。")]),a("li",null,"修复了几个遗留问题。")],-1),U={id:"_2021-2-14-1-3-0",tabindex:"-1"},H=a("a",{class:"header-anchor",href:"#_2021-2-14-1-3-0","aria-hidden":"true"},"#",-1),j=u(" 2021.2.14 "),C={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.3.0",target:"_blank",rel:"noopener noreferrer"},B=u("1.3.0"),G=a("ul",null,[a("li",null,"Happy 🐮 Year 🎉!"),a("li",null,"v1.3.0 通过非常巧妙的机制实现了 V 系协议全部 FullCone,同时保证了一定的兼容性。"),a("li",null,"OHHHHHHHHHHHH!")],-1),I={id:"_2021-01-31-1-2-4",tabindex:"-1"},N=a("a",{class:"header-anchor",href:"#_2021-01-31-1-2-4","aria-hidden":"true"},"#",-1),E=u(" 2021.01.31 "),O={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.4",target:"_blank",rel:"noopener noreferrer"},w=u("1.2.4"),F=a("ul",null,[a("li",null,"解决两个“连接至标准 Socks 服务端时可能出错”的历史遗留问题。"),a("li",null,"似乎这个版本没有什么改变,但这只是暴风雨前的宁静。"),a("li",null,[u("(没错我就是先知) "),a("blockquote",null,[a("p",null,"你个傻子,你拿的是 UNO 牌。")])])],-1),R=a("h2",{id:"_2021-01-25",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2021-01-25","aria-hidden":"true"},"#"),u(" 2021.01.25")],-1),V=u("全互联网最好最详细的秘籍入门篇同学们练熟了吗? 🍉 老师开始连载"),M=u("秘籍第一层"),A=u("咯..."),q=a("li",null,[a("a",{href:"../en"},"英文版文档网站"),u("逐渐增加内容 ing, 感谢各位大佬的辛苦付出~!")],-1),W={id:"_2021-01-22-1-2-3",tabindex:"-1"},Q=a("a",{class:"header-anchor",href:"#_2021-01-22-1-2-3","aria-hidden":"true"},"#",-1),Y=u(" 2021.01.22 "),J={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.3",target:"_blank",rel:"noopener noreferrer"},z=u("1.2.3"),K=a("li",null,[u("对 SS 协议的支持"),a("strong",null,"又"),u("变强了, 支持单端口多用户!")],-1),Z=a("li",null,[u("对 trojan 协议的支持也"),a("strong",null,"又"),u("变强了, trojan 的回落也解锁 SNI 分流的新姿势啦~!")],-1),$=a("li",null,[a("em",null,"(VLESS: 嘤嘤嘤)")],-1),ee=a("li",null,'UDP 奇奇怪怪的 BUG 被干掉了, 一个字, "稳定".',-1),le=a("li",null,"嗅探可以排除你不想嗅探的域名, 可以开启一些新玩法.",-1),re=u("向发现问题->开 issue->自行测试->自行分析->自行找到问题->自行解决->然后给上下游提交 PR 的大佬 "),ae=a("img",{src:"https://avatars2.githubusercontent.com/u/8384161?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ne=u(),ie={href:"https://github.com/bohanyang",target:"_blank",rel:"noopener noreferrer"},te=u("@Bohan Yang"),he=u(" 致敬!"),ue=a("li",null,"其他美味小樱桃, 惯例更新品尝就对啦.",-1),oe=h('

    2021.01.19

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

    2021.01.17

    ',3),de=u("辛苦的翻译工作开始了, 感谢"),se=a("img",{src:"https://avatars2.githubusercontent.com/u/60207794?s=32",width:"32px",height:"32px",alt:"a"},null,-1),ce=u(),fe={href:"https://github.com/jiuqi9997",target:"_blank",rel:"noopener noreferrer"},_e=u("@玖柒 Max"),pe=u("和其他所有的翻译大佬们."),be={href:"https://xtls.github.io/en/",target:"_blank",rel:"noopener noreferrer"},ge=u("English version"),Xe={id:"_2021-01-15-1-2-2",tabindex:"-1"},me=a("a",{class:"header-anchor",href:"#_2021-01-15-1-2-2","aria-hidden":"true"},"#",-1),xe=u(" 2021.01.15 "),Se={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.2",target:"_blank",rel:"noopener noreferrer"},ke=u("1.2.2"),ye=h('
    • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 SNI 分流啦~!
    • 之前预告的 UUID 修改正式上线.(往下看往下看)
    • 日志现在看起来比上一次顺眼又更顺眼了一丢丢.
    • 远程 DOH 和其他的 DNS 模式一样学会了走路由分流.
    • 当然还有其他各种小糖果.(更新品尝就对了)
    • 啊, 还有, 世界上第一個 M1 上跑起 Xray 的男人是 Anthony TSE

    2021.01.12

    ',2),ve=a("li",null,[u("将要到来的 UUID 修改, 支持自定义字符串和 UUID 之间的映射. 这意味着你将可以这样在配置文件中写 id 来对应用户. "),a("ul",null,[a("li",null,'客户端写 "id": "我爱 🍉 老师 1314",'),a("li",null,[u('服务端写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 '),a("code",null,"我爱🍉老师1314"),u(" 的 UUID 映射)")])])],-1),Te=u("🍉 老师的"),Le=u("小小白白话文"),De=u("大结局, 撒花."),Pe={id:"_2021-01-10-1-2-1",tabindex:"-1"},Ue=a("a",{class:"header-anchor",href:"#_2021-01-10-1-2-1","aria-hidden":"true"},"#",-1),He=u(" 2021.01.10 "),je={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.1",target:"_blank",rel:"noopener noreferrer"},Ce=u("1.2.1"),Be=u("小小白白话文"),Ge=u("连载上线啦,🍉 老师呕心沥血之作, 手把手教你从什么都不会到熟练配置 Xray!"),Ie=a("li",null,"(可能是整个互联网上, 最详细最有耐心的教你从 0 开始配置的教程)",-1),Ne=u("透明代理"),Ee=u("也增加了更多文章."),Oe=a("li",null,"还有很多细节修改, 文档将会越来越规范!",-1),we=u("感谢 "),Fe={href:"https://github.com/ricuhkaen",target:"_blank",rel:"noopener noreferrer"},Re=u("@ricuhkaen"),Ve=u(" , "),Me={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},Ae=u("@BioniCosmos"),qe=u(", "),We={href:"https://github.com/kirin10000",target:"_blank",rel:"noopener noreferrer"},Qe=u("@kirin"),Ye=h('
    • 大量的 UDP 相关修复, 甚至可以在育碧的土豆服务器上玩彩虹六号!
    • Google Voice 应该也可以正常使用 v2rayNG 拨打了.
    • 日志现在看起来更顺眼.

    2021.01.07

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

    2021.01.05

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

    2021.01.03

    ',6),Je=u("文档仓库第一个 PR。🎉 "),ze=u("透明代理(TProxy)配置教程 "),Ke=u(" ,感谢"),Ze=a("img",{src:"https://avatars2.githubusercontent.com/u/41363844?s=32",width:"32px",height:"32px",alt:"a"},null,-1),$e=u(),el={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},ll=u("@BioniCosmos"),rl=a("li",null,"tg 群突破 2500。",-1),al=a("h2",{id:"_2021-01-01",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2021-01-01","aria-hidden":"true"},"#"),u(" 2021.01.01")],-1),nl=u("【祝大家新年快乐,嗨皮牛耶!】🎆🎇🎆 "),il={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},tl=u("1.2.0"),hl=a("p",null,"🎁 在元旦的最后几分钟,v1.2.0 它来了,带着周五必更的惯例,带着各位贡献大佬的心血以及 @rprxx 的黑眼圈,不负众望的来了!",-1),ul=h('
  • 圣诞礼物v1.1.5后的元旦礼物 🎁,游戏玩家大福利,全面 FullCone。
  • (UDP 还会继续增强!)
  • 如果你已经拆过圣诞礼物,这次还有比圣诞礼物更精美的包装和小糖果哦。(同样不用问,更新品尝就对了)
  • (不,下面不是广告,是里程碑。)
  • Xray 是有史以来第一个不受限制的多协议平台:只需 Xray 即可解决问题,无需借力其它实现。
    • 一人扛起了所有!支持各大主流协议!
    • 一骑绝尘的性能!
    • 日趋完善的功能!
    • 可怕的生命力与社区亲和力!
  • ',5),ol=u("Xray 将继续保持前行! 因此 "),dl={href:"https://github.com/XTLS/Xray-core/discussions/56",target:"_blank",rel:"noopener noreferrer"},sl=u("Xray 需要更多的英雄!!"),cl=u("!"),fl=u("PS:请品,请细品"),_l={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.2.0",target:"_blank",rel:"noopener noreferrer"},pl=u("release notes"),bl=u("每一句。似乎有一个小秘密小彩蛋 "),gl=a("s",null,"(啊,有人敲门...我一会和你们说)",-1),Xl=a("h2",{id:"_2020-12-29",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-29","aria-hidden":"true"},"#"),u(" 2020.12.29")],-1),ml=u("透明代理的游戏玩家利好! Xray-core tproxy 入站, socks 出站 UDP FullCone 测试版, "),xl={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Sl=u("TG 群"),kl=u("火热测试中"),yl={id:"_2020-12-25-1-1-5",tabindex:"-1"},vl=a("a",{class:"header-anchor",href:"#_2020-12-25-1-1-5","aria-hidden":"true"},"#",-1),Tl=u(" 2020.12.25 "),Ll={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.5",target:"_blank",rel:"noopener noreferrer"},Dl=u("1.1.5"),Pl=a("p",null,"圣诞节快乐!",-1),Ul=a("li",null,"游戏玩家的圣诞礼物!你可以用 xray 爽快的打游戏啦!因为有了 SS/trojan UDP fullcone",-1),Hl=a("li",null,"你可以用你喜欢的格式写配置文件了,比如 yaml,比如 toml...",-1),jl=a("li",null,"(VLESS 的 UDP fullcone 和更多增强很快就到!)",-1),Cl=a("li",null,"无须再担心证书验证被墙,OCSP stapling 已经上线!",-1),Bl=u("kirin 带来了一大波 脚本更新."),Gl={href:"https://github.com/XTLS/Xray-install",target:"_blank",rel:"noopener noreferrer"},Il=u("脚本在此"),Nl=a("li",null,"还有更多美味小樱桃!(不用问,更新品尝就对了)",-1),El=a("h2",{id:"_2020-12-24",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-24","aria-hidden":"true"},"#"),u(" 2020.12.24")],-1),Ol=u("因为某些不可描述的原因,Xray 的文档网站已在发布日前偷跑上线。 网址为:"),wl={href:"https://xtls.github.io",target:"_blank",rel:"noopener noreferrer"},Fl=u("没错你正在看的就是"),Rl=a("p",null,"大家可以查阅各种内容也欢迎纠错/提出建议(可发往文档 github 仓库的 issue 区)",-1),Vl=u("文档网站需要不断完善和增加内容,以及完善设计。 因此更欢迎大家一起为文档建设添砖加瓦。 "),Ml={href:"https://github.com/XTLS/XTLS.github.io",target:"_blank",rel:"noopener noreferrer"},Al=u("文档的仓库"),ql=a("p",null,"仓库的 readme 中有简略教程说明如何帮助 xray 改进文档网站. 欢迎大家查看,纠错,修改,增加心得。",-1),Wl=a("h2",{id:"_2020-12-23",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-23","aria-hidden":"true"},"#"),u(" 2020.12.23")],-1),Ql=u("Xray-core Shadowsocks UDP FullCone 测试版, "),Yl={href:"https://t.me/projectXray",target:"_blank",rel:"noopener noreferrer"},Jl=u("TG 群"),zl=u("火热测试中"),Kl=a("h2",{id:"_2020-12-21",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-21","aria-hidden":"true"},"#"),u(" 2020.12.21")],-1),Zl=a("ul",null,[a("li",null,"Project X 群人数 2000+"),a("li",null,"群消息(含游戏群) 日均破万")],-1),$l={id:"_2020-12-18-1-1-4",tabindex:"-1"},er=a("a",{class:"header-anchor",href:"#_2020-12-18-1-1-4","aria-hidden":"true"},"#",-1),lr=u(" 2020.12.18 "),rr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.4",target:"_blank",rel:"noopener noreferrer"},ar=u("1.1.4"),nr=a("ul",null,[a("li",null,"更低的启动内占用和内存使用优化"),a("li",null,"随意定制的 TLS 提高你的 SSL 评级"),a("li",null,"支持 XTLS 入站的 Splice 以及支持 trojan 的 XTLS"),a("li",null,"还有在您路由器上使用的 Splice 最佳使用模式建议")],-1),ir=a("h2",{id:"_2020-12-17",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-17","aria-hidden":"true"},"#"),u(" 2020.12.17")],-1),tr=u("鉴于日益增长群人数和游戏需求, 开启了"),hr={href:"https://t.me/joinchat/UO4NixbB_XDQJOUjS6mHEQ",target:"_blank",rel:"noopener noreferrer"},ur=u("TG 游戏群"),or=a("h2",{id:"_2020-12-15",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-12-15","aria-hidden":"true"},"#"),u(" 2020.12.15")],-1),dr={href:"https://github.com/XTLS/Xray-install/tree/dev",target:"_blank",rel:"noopener noreferrer"},sr=u("安装脚本 dev 分支"),cr=u("开启, 持续更新功能中."),fr={id:"_2020-12-11-1-1-3",tabindex:"-1"},_r=a("a",{class:"header-anchor",href:"#_2020-12-11-1-1-3","aria-hidden":"true"},"#",-1),pr=u(" 2020.12.11 "),br={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.3",target:"_blank",rel:"noopener noreferrer"},gr=u("1.1.3"),Xr=a("ul",null,[a("li",null,"完整版本的 REDIRECT 透明代理模式."),a("li",null,"软路由 splice 流控模式的优化建议.")],-1),mr={id:"_2020-12-06-1-1-2",tabindex:"-1"},xr=a("a",{class:"header-anchor",href:"#_2020-12-06-1-1-2","aria-hidden":"true"},"#",-1),Sr=u(" 2020.12.06 "),kr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.1.2",target:"_blank",rel:"noopener noreferrer"},yr=u("1.1.2"),vr=h('
    • 流控增加 splice 模式, Linux 限定, 性能一骑绝尘.
    • 增强了 API 兼容

    2020.12.04

    增加 splice 模式

    2020.11.27

    • Project X 的 GitHub 主仓库 Xray-core 已获 500+ stars
    • 登上了 GitHub Trending
    • Project X 群人数破千,频道订阅数 500+
    ',5),Tr={id:"_2020-11-25-1-0-0",tabindex:"-1"},Lr=a("a",{class:"header-anchor",href:"#_2020-11-25-1-0-0","aria-hidden":"true"},"#",-1),Dr=u(" 2020.11.25 "),Pr={href:"https://github.com/XTLS/Xray-core/releases/tag/v1.0.0",target:"_blank",rel:"noopener noreferrer"},Ur=u("1.0.0"),Hr=a("p",null,"Xray 的第一个版本.",-1),jr=a("ul",null,[a("li",null,"基于 v2ray-core 修改而来,改动较大"),a("li",null,"全面增强, 性能卓越, 完全兼容")],-1),Cr=a("h2",{id:"_2020-11-23",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#_2020-11-23","aria-hidden":"true"},"#"),u(" 2020.11.23")],-1),Br=a("p",null,"project X start",-1),Gr=a("blockquote",null,[a("p",null,[a("s",null,"梦开始的时候")])],-1);o.render=function(h,u){const o=e("OutboundLink"),Ir=e("Badge"),Nr=e("RouterLink");return l(),r(t,null,[d,a("h2",s,[c,f,n(Ir,null,{default:i((()=>[a("a",_,[p,n(o)])])),_:1})]),b,a("h2",g,[X,m,n(Ir,null,{default:i((()=>[a("a",x,[S,n(o)])])),_:1})]),k,a("h2",y,[v,T,n(Ir,null,{default:i((()=>[a("a",L,[D,n(o)])])),_:1})]),P,a("h2",U,[H,j,n(Ir,null,{default:i((()=>[a("a",C,[B,n(o)])])),_:1})]),G,a("h2",I,[N,E,n(Ir,null,{default:i((()=>[a("a",O,[w,n(o)])])),_:1})]),F,R,a("ul",null,[a("li",null,[V,n(Nr,{to:"/en/document/level-1/"},{default:i((()=>[M])),_:1}),A]),q]),a("h2",W,[Q,Y,n(Ir,null,{default:i((()=>[a("a",J,[z,n(o)])])),_:1})]),a("ul",null,[K,Z,$,ee,le,a("li",null,[re,ae,ne,a("a",ie,[te,n(o)]),he]),ue]),oe,a("ul",null,[a("li",null,[de,se,ce,a("a",fe,[_e,n(o)]),pe]),a("li",null,[a("a",be,[ge,n(o)])])]),a("h2",Xe,[me,xe,n(Ir,null,{default:i((()=>[a("a",Se,[ke,n(o)])])),_:1})]),ye,a("ul",null,[ve,a("li",null,[Te,n(Nr,{to:"/en/document/level-0/"},{default:i((()=>[Le])),_:1}),De])]),a("h2",Pe,[Ue,He,n(Ir,null,{default:i((()=>[a("a",je,[Ce,n(o)])])),_:1})]),a("ul",null,[a("li",null,[n(Nr,{to:"/en/document/level-0/"},{default:i((()=>[Be])),_:1}),Ge]),Ie,a("li",null,[n(Nr,{to:"/en/document/level-2/"},{default:i((()=>[Ne])),_:1}),Ee]),Oe,a("li",null,[we,a("a",Fe,[Re,n(o)]),Ve,a("a",Me,[Ae,n(o)]),qe,a("a",We,[Qe,n(o)])])]),Ye,a("ul",null,[a("li",null,[Je,n(Nr,{to:"/en/document/level-2/tproxy.html"},{default:i((()=>[ze])),_:1}),Ke,Ze,$e,a("a",el,[ll,n(o)])]),rl]),al,a("p",null,[nl,n(Ir,null,{default:i((()=>[a("a",il,[tl,n(o)])])),_:1})]),hl,a("ul",null,[ul,a("li",null,[ol,a("a",dl,[sl,n(o)]),cl]),a("li",null,[fl,a("a",_l,[pl,n(o)]),bl,gl])]),Xl,a("p",null,[ml,a("a",xl,[Sl,n(o)]),kl]),a("h2",yl,[vl,Tl,n(Ir,null,{default:i((()=>[a("a",Ll,[Dl,n(o)])])),_:1})]),Pl,a("ul",null,[Ul,Hl,jl,Cl,a("li",null,[Bl,a("a",Gl,[Il,n(o)])]),Nl]),El,a("p",null,[Ol,a("a",wl,[Fl,n(o)])]),Rl,a("p",null,[Vl,a("a",Ml,[Al,n(o)])]),ql,Wl,a("p",null,[Ql,a("a",Yl,[Jl,n(o)]),zl]),Kl,Zl,a("h2",$l,[er,lr,n(Ir,null,{default:i((()=>[a("a",rr,[ar,n(o)])])),_:1})]),nr,ir,a("p",null,[tr,a("a",hr,[ur,n(o)])]),or,a("p",null,[a("a",dr,[sr,n(o)]),cr]),a("h2",fr,[_r,pr,n(Ir,null,{default:i((()=>[a("a",br,[gr,n(o)])])),_:1})]),Xr,a("h2",mr,[xr,Sr,n(Ir,null,{default:i((()=>[a("a",kr,[yr,n(o)])])),_:1})]),vr,a("h2",Tr,[Lr,Dr,n(Ir,null,{default:i((()=>[a("a",Pr,[Ur,n(o)])])),_:1})]),Hr,jr,Cr,Br,Gr],64)};export default o; diff --git a/assets/nginx_or_haproxy_tls_tunnel.html.7190e425.js b/assets/nginx_or_haproxy_tls_tunnel.html.bbed6a21.js similarity index 99% rename from assets/nginx_or_haproxy_tls_tunnel.html.7190e425.js rename to assets/nginx_or_haproxy_tls_tunnel.html.bbed6a21.js index 268bbbd5b..34aadd10e 100644 --- a/assets/nginx_or_haproxy_tls_tunnel.html.7190e425.js +++ b/assets/nginx_or_haproxy_tls_tunnel.html.bbed6a21.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as r,F as l,d as p,e as t}from"./app.755d843f.js";const b={},u=p('

    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),i=t("服务器申请证书不再赘述,参考"),c={href:"https://xtls.github.io/document/level-0/ch06-certificates.html",target:"_blank",rel:"noopener noreferrer"},o=t("白话文"),m=p('
    stream {\n    server {\n        listen 443 ssl;\n        listen [::]:443 ssl;\n        ssl_protocols TLSv1.3;\n        ssl_certificate /path/to/cert/domain.crt; # crt 文件位置\n        ssl_certificate_key /path/to/cert/domain.key; # key 文件位置\n        proxy_pass unix:/dev/shm/vless.sock; # 使用 domain socket\n    }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    注意

    stream 部分与 http 模块并列,客户端可删除 http 部分,服务端可删除或搭建网页伪装回落

    客户端加入如下配置

    stream {\n    server {\n        listen 6666;\n        listen [::]:6666;\n        proxy_ssl on;\n        proxy_ssl_protocols TLSv1.3;\n        proxy_ssl_server_name on;\n        proxy_ssl_name yourdomain.domain; # 服务器域名\n        proxy_pass ip:443; # 服务器 ip 形如 proxy_pass 6.6.6.6:443; 或 proxy_pass [2401:0:0::1]:443;\n    }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    /etc/systemd/system 文件夹中创建 nginx.service 文件

    vim /etc/systemd/system/nginx.service

    写入如下

    [Unit]\nDescription=The NGINX HTTP and reverse proxy server\nAfter=syslog.target network-online.target remote-fs.target nss-lookup.target\nAfter=xray.service\n\n[Service]\nType=forking\nExecStartPre=/usr/local/nginx/sbin/nginx -t\nExecStart=/usr/local/nginx/sbin/nginx\nExecReload=/usr/local/nginx/sbin/nginx -s reload\nExecStop=/bin/kill -s QUIT $MAINPID\nPrivateTmp=true\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    加入开机自启

    systemctl enable nginx

    xray 配置

    服务端 xray 配置

    {\n\t"log": {\n\t\t"loglevel": "none"\n\t},\n\t"inbounds": [\n\t\t{\n\t\t\t"listen": "/dev/shm/vless.sock,0666",\n\t\t\t"protocol": "vless",\n\t\t\t"settings": {\n\t\t\t\t"clients": [\n\t\t\t\t\t{\n\t\t\t\t\t\t"id": "uuid"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t"decryption": "none"\n\t\t\t},\n\t\t\t"streamSettings": {\n\t\t\t\t"network": "tcp"\n\t\t\t},\n\t\t\t"sniffing": {\n\t\t\t\t"enabled": true,\n\t\t\t\t"destOverride": [\n\t\t\t\t\t"http",\n\t\t\t\t\t"tls"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t"outbounds": [\n\t\t{\n\t\t\t"protocol": "freedom"\n\t\t}\n\t]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    客户端 xray 配置,此处以旁路由透明代理为例

    {\n    "log": {\n        "loglevel": "none"\n    },\n    "dns": {\n        "servers": [\n            "1.1.1.1",\n            {\n                "address": "119.29.29.29",\n                "domains": [\n                    "geosite:cn"\n                ],\n                "expectIP": [\n                    "geoip:cn"\n                ]\n            }\n        ],\n        "disableFallback": true,\n        "disableFallbackIfMatch": true\n    },\n    "inbounds": [\n        {\n            "tag": "tproxy-in",\n            "port": 12345,\n            "protocol": "dokodemo-door",\n            "settings": {\n                "network": "tcp,udp",\n                "followRedirect": true\n            },\n            "sniffing": {\n                "enabled": true,\n                "destOverride": [\n                    "http",\n                    "tls"\n                ]\n            },\n            "streamSettings": {\n                "sockopt": {\n                    "tproxy": "tproxy",\n                    "mark": 255\n                }\n            }\n        },\n        {\n            "tag": "http",\n            "port": 10808,\n            "listen": "127.0.0.1",\n            "protocol": "http",\n            "sniffing": {\n                "enabled": true,\n                "destOverride": [\n                    "http",\n                    "tls"\n                ]\n            }\n        }\n    ],\n    "outbounds": [\n        {\n            "tag": "nginxtls",\n            "protocol": "vless",\n            "settings": {\n                "vnext": [\n                    {\n                        "address": "127.0.0.1",\n                        "port": 6666,\n                        "users": [\n                            {\n                                "id": "uuid",\n                                "encryption": "none"\n                            }\n                        ]\n                    }\n                ]\n            },\n            "streamSettings": {\n                "sockopt": {\n                    "mark": 255\n                },\n                "network": "tcp"\n            }\n        },\n        {\n            "tag": "direct",\n            "protocol": "freedom",\n            "streamSettings": {\n                "sockopt": {\n                    "mark": 255\n                }\n            }\n        },\n        {\n            "tag": "block",\n            "protocol": "blackhole",\n            "settings": {\n                "response": {\n                    "type": "http"\n                }\n            }\n        }\n    ],\n    "routing": {\n        "domainMatcher": "mph",\n        "domainStrategy": "AsIs",\n        "rules": [\n            {\n                "type": "field",\n                "domain": [\n                    "geosite:category-ads-all"\n                ],\n                "outboundTag": "block"\n            },\n            {\n                "type": "field",\n                "port": 123,\n                "network": "udp",\n                "outboundTag": "direct"\n            },\n            {\n                "type": "field",\n                "ip": [\n                    "1.1.1.1"\n                ],\n                "outboundTag": "proxy"\n            },\n            {\n                "type": "field",\n                "domain": [\n                    "geosite:cn"\n                ],\n                "outboundTag": "direct"\n            },\n            {\n                "type": "field",\n                "protocol": [\n                    "bittorrent"\n                ],\n                "outboundTag": "direct"\n            },\n            {\n                "type": "field",\n                "ip": [\n                    "geoip:private"\n                ],\n                "outboundTag": "direct"\n            },\n            {\n                "type": "field",\n                "inboundTag": [\n                    "tproxy-in"\n                ],\n                "outboundTag": "nginxtls"\n            }\n        ]\n    }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156

    如果使用透明代理需要在 iptables 或 ip6tables 配置中加入

    # 设置策略路由 v4\nip rule add fwmark 1 table 100\nip route add local 0.0.0.0/0 dev lo table 100\n\n# 设置策略路由 v6\nip -6 rule add fwmark 1 table 106\nip -6 route add local ::/0 dev lo table 106\n\n# VPS IP 直连\niptables -t mangle -A XRAY_MASK -d VSP_IPv4/32 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d VPS_IPv6/128 -j RETURN\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    客户端及服务端启动服务

    systemctl restart xray

    systemctl restart nginx

    结束

    双端 Haproxy 构建 HTPPS 隧道隐藏指纹

    安装 Haproxy

    pacman -Su haproxyapt install haproxy

    Haproxy 处理 ssl 需要 openssl 支持,检查 openssl 版本,必要时安装或更新

    HTTPS 隧道

    前述 Nginx HTTPS 隧道 Hproxy 同样可以简单做到

    网路结构:

    xray_client ---tcp--- haproxy_client ---HTTPS--- haproxy_sever ---tcp--- xray_server

    haproxy_client 配置 (运行前去掉注释)

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    # 隧道强制使用 TLS 1.3\n    ssl-default-server-options ssl-min-ver TLSv1.3\n\ndefaults\n    log global\n    mode tcp\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend xray\n    bind 127.0.0.1:6666 # 监听本机 6666 端口\n    default_backend tunnel\n\nbackend tunnel\n    server tunnel www.example.com:443 ssl verify none sni req.hdr(host) alpn h2,http/1.1\n    # 域名或 IP 均可以,若填域名建议在 hosts 中指定 IP 降低解析时间;alpn 与服务器协商,服务器端为 alpn h2,http1.1 时,客户端指定为 h2 则隧道为 HTTP2 方式连接,指定为 http1.1 为 HTTP 方式,双端均写优先 h2\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

    haproxy_server 配置 (运行前去掉注释)

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    # 指定安全套件并指定 ssl 版本最低 1.2 增加真实性\n    ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256\n    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n    ssl-default-bind-options ssl-min-ver TLSv1.2\n\ndefaults\n    log global\n    mode tcp\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend tls-in\n    bind :::443 ssl crt /path/to/pem alpn h2,http/1.1 # haproxy 使用 pem 进行 ssl 解密,pem 由 cat www.example.com.crt www.example.com.key > www.example.com.pem 获得\n    default_backend xray\n    tcp-request inspect-delay 5s\n    tcp-request content accept if HTTP\n    use_backend web if HTTP\n\nbackend xray\n    server xray /dev/shm/vless.sock # 支持 abstract 格式: "abns@vless.sock" ;loopback 方式:127.0.0.1:6666\n\nbackend web\n    server web /dev/shm/h1h2c.sock # 回落到网页\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33

    xray 配置

    同上 nginx 部分:最简单的 TCP 配置,可搭配任意协议,建议使用 VLESS+TCP 无需多余加密,参考文档或其他示例

    WebSocket over HTTP/2

    Haproxy 支持 HTTP/2 的 h2c 进站及出站

    然而援引 xray 文档 HTTP/2 的说明

    “由 HTTP/2 的建议,客户端和服务器必须同时开启 TLS 才可以正常使用这个传输方式。...... 当前版本的 HTTP/2 的传输方式并不强制要求入站(服务端)有 TLS 配置。”

    即入站可以使用 h2c,出站并不支持 h2c。因此无法使用 xray_client ---h2c--- haproxy_client ---HTTP/2+TLS--- haproxy_sever ---h2c--- xray_server

    但是可以通过 ws 偷个鸡,Haproxy 支持 ws over HTTP/2

    则网络结构:xray_client ---ws--- haproxy_client ---ws over HTTP/2 over HTTPS--- haproxy_sever ---ws--- xray_server

    haproxy_client 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    # 调整 HTTP/2 的性能,当遇到 HTTP/2 性能问题时都可以设置相关项,更多设置见 Haproxy 文档 tune.h2 部分 https://docs.haproxy.org/2.7/configuration.html\n    tune.h2.initial-window-size 536870912 # 初始窗口大小,建议设置,默认值 65536 单位 byte,此值在突发大流量情况下需要一定加载时间,建议根据网速调整\n    tune.h2.max-concurrent-streams 512 # 复用线路数,可根据情况设置,默认值 100,一般不用设置(官方不建议改动)\n\n    ssl-default-server-options ssl-min-ver TLSv1.3\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend xray\n    bind 127.0.0.1:6666\n    default_backend tunnel\n\nbackend tunnel\n    server tunnel www.example.com:443 ssl verify none sni req.hdr(host) ws h2 alpn h2\n    # ws over HTTP/2\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    haproxy_server 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    # 客户端配置即可,服务端配置也无妨\n    tune.h2.initial-window-size 536870912\n    tune.h2.max-concurrent-streams 512\n\n    ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256\n    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n    ssl-default-bind-options ssl-min-ver TLSv1.2\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend tls-in\n    bind :::443 ssl crt /path/to/pem alpn h2,http/1.1\n    use_backend xray if { ssl_fc_alpn -i h2 } { path_beg /tunnel }\n    use_backend server1 if { ssl_fc_alpn -i h2 } { path_beg /path1 }\n    use_backend server2 if { ssl_fc_alpn -i h2 } { path_beg /path2 }\n    use_backend server3 if { ssl_fc_alpn -i h2 } { path_beg /path3 }\n    default_backend web\n    # haproxy 使用 http 模式可以根据 path 分流\n\nbackend xray\n    server xray abns@vless.sock ws h1\n\nbackend server1\n    server server1 abns@server1.sock ws h1\n\nbackend server2\n    server server2 abns@server2.sock ws h1\n\nbackend server3\n    server server3 abns@server3.sock ws h1\n\nbackend web\n    server web /dev/shm/h1h2c.sock\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47

    xray 配置

    简单的 websocket 配置即可,无需 TLS, 配置见 xray 文档示例,配置 "path" 可以用于服务端 haproxy 分流(客户端有分流需求同样可以通过客户端 haproxy 进行,原理类似,参考服务端的 path 分流配置)

    gRPC over HTTP/2

    虽然双端的 h2c 不行,但是 gRPC 不要求必须 TLS,直接冲

    网络结构:xray_client ---gRPC h2c--- haproxy_client ---gRPC over HTTP/2 over HTTPS--- haproxy_sever ---gRPC h2c--- xray_server

    haproxy_client 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    tune.h2.initial-window-size 536870912\n    tune.h2.max-concurrent-streams 512\n\n    ssl-default-server-options ssl-min-ver TLSv1.3\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend xray\n    bind 127.0.0.1:6666 proto h2 # 指定 proto h2 使用 h2c\n    default_backend tunnel\n\nbackend tunnel\n    server tunnel www.example.com:443 ssl verify none sni req.hdr(host) alpn h2\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    haproxy_server 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    tune.h2.initial-window-size 536870912\n    tune.h2.max-concurrent-streams 512\n\n    ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256\n    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n    ssl-default-bind-options ssl-min-ver TLSv1.2\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend tls-in\n    bind :::443 ssl crt /path/to/pem alpn h2,http/1.1\n    use_backend xray if { ssl_fc_alpn -i h2 } { path_beg /tunnel } # xray gRPC 中配置的 "serviceName" 在 harpoxy 中可以使用 path 进行分流,为方便使用 "multiMode",使用 path_beg 参数匹配路径\n    use_backend server1 if { ssl_fc_alpn -i h2 } { path_beg /path1 }\n    use_backend server2 if { ssl_fc_alpn -i h2 } { path_beg /path2 }\n    use_backend server3 if { ssl_fc_alpn -i h2 } { path_beg /path3 }\n    default_backend web\n\nbackend xray\n    server xray abns@vless.sock proto h2\n\nbackend server1\n    server server1 abns@server1.sock proto h2\n\nbackend server2\n    server server2 abns@server2.sock proto h2\n\nbackend server3\n    server server3 abns@server3.sock proto h2\n\nbackend web\n    server web /dev/shm/h1h2c.sock\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45

    xray 配置

    简单的 gRPC 配置,无需 TLS,配置见文档,配置的 serviceName 可用于分流。

    Haproxy 使用自签证书进行双端认证(gRPC 示例)

    这里使用自签证书双端认证加强隧道安全性(但会牺牲一点延迟,不过使用 gRPC 后感知不强),而服务端同时处理信任的证书和自签名证书,并据此分流伪装网站和隧道流量

    其中 www.example.com 为伪装站信任证书(如白话文中申请的证书)

    tunnel.example.com 为自签证书网址,自签证书可以参考 https://learn.microsoft.com/zh-cn/azure/application-gateway/self-signed-certificates

    根证书 ca.crt 服务器证书 server.crt 服务器密钥 server.key

    至少需要生成一个 server.pem,客户端可以同样使用此证书用于双端认证;或者生成两个证书,一个 client,一个 server,用于双端认证

    需准备 fullchain.crt 用于认证( cat server.crt ca.crt > fullchain.crt ),server.pem ( cat server.crt server.key ca.crt > server.pem )用于解密

    haproxy_client 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    tune.h2.initial-window-size 536870912\n    tune.h2.max-concurrent-streams 512\n\n    ssl-default-server-options ssl-min-ver TLSv1.3\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client 300s\n    timeout server 300s\n\nfrontend xray\n    bind 127.0.0.1:6666 proto h2\n    default_backend tunnel\n\nbackend tunnel\n    server tunnel tunnel.example.com:443 tfo allow-0rtt ssl crt /path/to/client.pem verify required ca-file /path/to/fullchain.crt sni str(tunnel.example.com) alpn h2\n    # 网址自定义,和自签证书一致即可,hosts 中配置 IP 解析,sni 的 str 设定 sni,用于服务端识别\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

    haproxy_server 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    tune.h2.initial-window-size 536870912\n    tune.h2.max-concurrent-streams 512\n\n    ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256\n    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n    ssl-default-bind-options ssl-min-ver TLSv1.2\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend tls-in\n    bind :::443 tfo allow-0rtt ssl crt /path/to/server.pem verify optional ca-file /path/to/fullchain.crt crt /path/to/www.example.com.pem alpn h2,http/1.1\n    use_backend xray if { ssl_fc_sni tunnel.example.com } { ssl_c_used } { ssl_fc_alpn -i h2 } { path_beg /tunnel }\n    use_backend server1 if { ssl_fc_sni atunnel.example.com } { ssl_c_used }  { ssl_fc_alpn -i h2 } { path_beg /path2 }\n    use_backend server2 if { ssl_fc_sni btunnel.example.com } { ssl_c_used }  { ssl_fc_alpn -i h2 } { path_beg /path3 }\n    use_backend server3 if { ssl_fc_sni ctunnel.example.com } { ssl_c_used }  { ssl_fc_alpn -i h2 } { path_beg /path4 }\n    default_backend web\n    # Haproxy 支持多个 pem 解密\n    # 可根据多个客户端的不同 sni 分流,也可以 path 分流,方式多样,更多 acl 见 Haproxy 文档\n\nbackend xray\n    server xray abns@vless.sock proto h2\n\nbackend server1\n    server server1 abns@server1.sock proto h2\n\nbackend server2\n    server server2 abns@server2.sock proto h2\n\nbackend server3\n    server server3 abns@server3.sock proto h2\n\nbackend web\n    server web /dev/shm/h1h2c.sock\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47

    xray 配置

    简单的 gRPC 配置,无需 TLS,配置见文档,配置的 serviceName 可用于分流。

    ',70);b.render=function(p,t){const b=n("OutboundLink");return s(),a(l,null,[u,e("p",null,[i,e("a",c,[o,r(b)])]),m],64)};export default b; +import{r as n,o as s,c as a,a as e,b as r,F as l,d as p,e as t}from"./app.48111a85.js";const b={},u=p('

    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),i=t("服务器申请证书不再赘述,参考"),c={href:"https://xtls.github.io/document/level-0/ch06-certificates.html",target:"_blank",rel:"noopener noreferrer"},o=t("白话文"),m=p('
    stream {\n    server {\n        listen 443 ssl;\n        listen [::]:443 ssl;\n        ssl_protocols TLSv1.3;\n        ssl_certificate /path/to/cert/domain.crt; # crt 文件位置\n        ssl_certificate_key /path/to/cert/domain.key; # key 文件位置\n        proxy_pass unix:/dev/shm/vless.sock; # 使用 domain socket\n    }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    注意

    stream 部分与 http 模块并列,客户端可删除 http 部分,服务端可删除或搭建网页伪装回落

    客户端加入如下配置

    stream {\n    server {\n        listen 6666;\n        listen [::]:6666;\n        proxy_ssl on;\n        proxy_ssl_protocols TLSv1.3;\n        proxy_ssl_server_name on;\n        proxy_ssl_name yourdomain.domain; # 服务器域名\n        proxy_pass ip:443; # 服务器 ip 形如 proxy_pass 6.6.6.6:443; 或 proxy_pass [2401:0:0::1]:443;\n    }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    /etc/systemd/system 文件夹中创建 nginx.service 文件

    vim /etc/systemd/system/nginx.service

    写入如下

    [Unit]\nDescription=The NGINX HTTP and reverse proxy server\nAfter=syslog.target network-online.target remote-fs.target nss-lookup.target\nAfter=xray.service\n\n[Service]\nType=forking\nExecStartPre=/usr/local/nginx/sbin/nginx -t\nExecStart=/usr/local/nginx/sbin/nginx\nExecReload=/usr/local/nginx/sbin/nginx -s reload\nExecStop=/bin/kill -s QUIT $MAINPID\nPrivateTmp=true\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    加入开机自启

    systemctl enable nginx

    xray 配置

    服务端 xray 配置

    {\n\t"log": {\n\t\t"loglevel": "none"\n\t},\n\t"inbounds": [\n\t\t{\n\t\t\t"listen": "/dev/shm/vless.sock,0666",\n\t\t\t"protocol": "vless",\n\t\t\t"settings": {\n\t\t\t\t"clients": [\n\t\t\t\t\t{\n\t\t\t\t\t\t"id": "uuid"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t"decryption": "none"\n\t\t\t},\n\t\t\t"streamSettings": {\n\t\t\t\t"network": "tcp"\n\t\t\t},\n\t\t\t"sniffing": {\n\t\t\t\t"enabled": true,\n\t\t\t\t"destOverride": [\n\t\t\t\t\t"http",\n\t\t\t\t\t"tls"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t"outbounds": [\n\t\t{\n\t\t\t"protocol": "freedom"\n\t\t}\n\t]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    客户端 xray 配置,此处以旁路由透明代理为例

    {\n    "log": {\n        "loglevel": "none"\n    },\n    "dns": {\n        "servers": [\n            "1.1.1.1",\n            {\n                "address": "119.29.29.29",\n                "domains": [\n                    "geosite:cn"\n                ],\n                "expectIP": [\n                    "geoip:cn"\n                ]\n            }\n        ],\n        "disableFallback": true,\n        "disableFallbackIfMatch": true\n    },\n    "inbounds": [\n        {\n            "tag": "tproxy-in",\n            "port": 12345,\n            "protocol": "dokodemo-door",\n            "settings": {\n                "network": "tcp,udp",\n                "followRedirect": true\n            },\n            "sniffing": {\n                "enabled": true,\n                "destOverride": [\n                    "http",\n                    "tls"\n                ]\n            },\n            "streamSettings": {\n                "sockopt": {\n                    "tproxy": "tproxy",\n                    "mark": 255\n                }\n            }\n        },\n        {\n            "tag": "http",\n            "port": 10808,\n            "listen": "127.0.0.1",\n            "protocol": "http",\n            "sniffing": {\n                "enabled": true,\n                "destOverride": [\n                    "http",\n                    "tls"\n                ]\n            }\n        }\n    ],\n    "outbounds": [\n        {\n            "tag": "nginxtls",\n            "protocol": "vless",\n            "settings": {\n                "vnext": [\n                    {\n                        "address": "127.0.0.1",\n                        "port": 6666,\n                        "users": [\n                            {\n                                "id": "uuid",\n                                "encryption": "none"\n                            }\n                        ]\n                    }\n                ]\n            },\n            "streamSettings": {\n                "sockopt": {\n                    "mark": 255\n                },\n                "network": "tcp"\n            }\n        },\n        {\n            "tag": "direct",\n            "protocol": "freedom",\n            "streamSettings": {\n                "sockopt": {\n                    "mark": 255\n                }\n            }\n        },\n        {\n            "tag": "block",\n            "protocol": "blackhole",\n            "settings": {\n                "response": {\n                    "type": "http"\n                }\n            }\n        }\n    ],\n    "routing": {\n        "domainMatcher": "mph",\n        "domainStrategy": "AsIs",\n        "rules": [\n            {\n                "type": "field",\n                "domain": [\n                    "geosite:category-ads-all"\n                ],\n                "outboundTag": "block"\n            },\n            {\n                "type": "field",\n                "port": 123,\n                "network": "udp",\n                "outboundTag": "direct"\n            },\n            {\n                "type": "field",\n                "ip": [\n                    "1.1.1.1"\n                ],\n                "outboundTag": "proxy"\n            },\n            {\n                "type": "field",\n                "domain": [\n                    "geosite:cn"\n                ],\n                "outboundTag": "direct"\n            },\n            {\n                "type": "field",\n                "protocol": [\n                    "bittorrent"\n                ],\n                "outboundTag": "direct"\n            },\n            {\n                "type": "field",\n                "ip": [\n                    "geoip:private"\n                ],\n                "outboundTag": "direct"\n            },\n            {\n                "type": "field",\n                "inboundTag": [\n                    "tproxy-in"\n                ],\n                "outboundTag": "nginxtls"\n            }\n        ]\n    }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156

    如果使用透明代理需要在 iptables 或 ip6tables 配置中加入

    # 设置策略路由 v4\nip rule add fwmark 1 table 100\nip route add local 0.0.0.0/0 dev lo table 100\n\n# 设置策略路由 v6\nip -6 rule add fwmark 1 table 106\nip -6 route add local ::/0 dev lo table 106\n\n# VPS IP 直连\niptables -t mangle -A XRAY_MASK -d VSP_IPv4/32 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d VPS_IPv6/128 -j RETURN\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    客户端及服务端启动服务

    systemctl restart xray

    systemctl restart nginx

    结束

    双端 Haproxy 构建 HTPPS 隧道隐藏指纹

    安装 Haproxy

    pacman -Su haproxyapt install haproxy

    Haproxy 处理 ssl 需要 openssl 支持,检查 openssl 版本,必要时安装或更新

    HTTPS 隧道

    前述 Nginx HTTPS 隧道 Hproxy 同样可以简单做到

    网路结构:

    xray_client ---tcp--- haproxy_client ---HTTPS--- haproxy_sever ---tcp--- xray_server

    haproxy_client 配置 (运行前去掉注释)

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    # 隧道强制使用 TLS 1.3\n    ssl-default-server-options ssl-min-ver TLSv1.3\n\ndefaults\n    log global\n    mode tcp\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend xray\n    bind 127.0.0.1:6666 # 监听本机 6666 端口\n    default_backend tunnel\n\nbackend tunnel\n    server tunnel www.example.com:443 ssl verify none sni req.hdr(host) alpn h2,http/1.1\n    # 域名或 IP 均可以,若填域名建议在 hosts 中指定 IP 降低解析时间;alpn 与服务器协商,服务器端为 alpn h2,http1.1 时,客户端指定为 h2 则隧道为 HTTP2 方式连接,指定为 http1.1 为 HTTP 方式,双端均写优先 h2\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26

    haproxy_server 配置 (运行前去掉注释)

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    # 指定安全套件并指定 ssl 版本最低 1.2 增加真实性\n    ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256\n    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n    ssl-default-bind-options ssl-min-ver TLSv1.2\n\ndefaults\n    log global\n    mode tcp\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend tls-in\n    bind :::443 ssl crt /path/to/pem alpn h2,http/1.1 # haproxy 使用 pem 进行 ssl 解密,pem 由 cat www.example.com.crt www.example.com.key > www.example.com.pem 获得\n    default_backend xray\n    tcp-request inspect-delay 5s\n    tcp-request content accept if HTTP\n    use_backend web if HTTP\n\nbackend xray\n    server xray /dev/shm/vless.sock # 支持 abstract 格式: "abns@vless.sock" ;loopback 方式:127.0.0.1:6666\n\nbackend web\n    server web /dev/shm/h1h2c.sock # 回落到网页\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33

    xray 配置

    同上 nginx 部分:最简单的 TCP 配置,可搭配任意协议,建议使用 VLESS+TCP 无需多余加密,参考文档或其他示例

    WebSocket over HTTP/2

    Haproxy 支持 HTTP/2 的 h2c 进站及出站

    然而援引 xray 文档 HTTP/2 的说明

    “由 HTTP/2 的建议,客户端和服务器必须同时开启 TLS 才可以正常使用这个传输方式。...... 当前版本的 HTTP/2 的传输方式并不强制要求入站(服务端)有 TLS 配置。”

    即入站可以使用 h2c,出站并不支持 h2c。因此无法使用 xray_client ---h2c--- haproxy_client ---HTTP/2+TLS--- haproxy_sever ---h2c--- xray_server

    但是可以通过 ws 偷个鸡,Haproxy 支持 ws over HTTP/2

    则网络结构:xray_client ---ws--- haproxy_client ---ws over HTTP/2 over HTTPS--- haproxy_sever ---ws--- xray_server

    haproxy_client 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    # 调整 HTTP/2 的性能,当遇到 HTTP/2 性能问题时都可以设置相关项,更多设置见 Haproxy 文档 tune.h2 部分 https://docs.haproxy.org/2.7/configuration.html\n    tune.h2.initial-window-size 536870912 # 初始窗口大小,建议设置,默认值 65536 单位 byte,此值在突发大流量情况下需要一定加载时间,建议根据网速调整\n    tune.h2.max-concurrent-streams 512 # 复用线路数,可根据情况设置,默认值 100,一般不用设置(官方不建议改动)\n\n    ssl-default-server-options ssl-min-ver TLSv1.3\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend xray\n    bind 127.0.0.1:6666\n    default_backend tunnel\n\nbackend tunnel\n    server tunnel www.example.com:443 ssl verify none sni req.hdr(host) ws h2 alpn h2\n    # ws over HTTP/2\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    haproxy_server 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    # 客户端配置即可,服务端配置也无妨\n    tune.h2.initial-window-size 536870912\n    tune.h2.max-concurrent-streams 512\n\n    ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256\n    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n    ssl-default-bind-options ssl-min-ver TLSv1.2\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend tls-in\n    bind :::443 ssl crt /path/to/pem alpn h2,http/1.1\n    use_backend xray if { ssl_fc_alpn -i h2 } { path_beg /tunnel }\n    use_backend server1 if { ssl_fc_alpn -i h2 } { path_beg /path1 }\n    use_backend server2 if { ssl_fc_alpn -i h2 } { path_beg /path2 }\n    use_backend server3 if { ssl_fc_alpn -i h2 } { path_beg /path3 }\n    default_backend web\n    # haproxy 使用 http 模式可以根据 path 分流\n\nbackend xray\n    server xray abns@vless.sock ws h1\n\nbackend server1\n    server server1 abns@server1.sock ws h1\n\nbackend server2\n    server server2 abns@server2.sock ws h1\n\nbackend server3\n    server server3 abns@server3.sock ws h1\n\nbackend web\n    server web /dev/shm/h1h2c.sock\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47

    xray 配置

    简单的 websocket 配置即可,无需 TLS, 配置见 xray 文档示例,配置 "path" 可以用于服务端 haproxy 分流(客户端有分流需求同样可以通过客户端 haproxy 进行,原理类似,参考服务端的 path 分流配置)

    gRPC over HTTP/2

    虽然双端的 h2c 不行,但是 gRPC 不要求必须 TLS,直接冲

    网络结构:xray_client ---gRPC h2c--- haproxy_client ---gRPC over HTTP/2 over HTTPS--- haproxy_sever ---gRPC h2c--- xray_server

    haproxy_client 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    tune.h2.initial-window-size 536870912\n    tune.h2.max-concurrent-streams 512\n\n    ssl-default-server-options ssl-min-ver TLSv1.3\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend xray\n    bind 127.0.0.1:6666 proto h2 # 指定 proto h2 使用 h2c\n    default_backend tunnel\n\nbackend tunnel\n    server tunnel www.example.com:443 ssl verify none sni req.hdr(host) alpn h2\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27

    haproxy_server 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    tune.h2.initial-window-size 536870912\n    tune.h2.max-concurrent-streams 512\n\n    ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256\n    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n    ssl-default-bind-options ssl-min-ver TLSv1.2\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend tls-in\n    bind :::443 ssl crt /path/to/pem alpn h2,http/1.1\n    use_backend xray if { ssl_fc_alpn -i h2 } { path_beg /tunnel } # xray gRPC 中配置的 "serviceName" 在 harpoxy 中可以使用 path 进行分流,为方便使用 "multiMode",使用 path_beg 参数匹配路径\n    use_backend server1 if { ssl_fc_alpn -i h2 } { path_beg /path1 }\n    use_backend server2 if { ssl_fc_alpn -i h2 } { path_beg /path2 }\n    use_backend server3 if { ssl_fc_alpn -i h2 } { path_beg /path3 }\n    default_backend web\n\nbackend xray\n    server xray abns@vless.sock proto h2\n\nbackend server1\n    server server1 abns@server1.sock proto h2\n\nbackend server2\n    server server2 abns@server2.sock proto h2\n\nbackend server3\n    server server3 abns@server3.sock proto h2\n\nbackend web\n    server web /dev/shm/h1h2c.sock\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45

    xray 配置

    简单的 gRPC 配置,无需 TLS,配置见文档,配置的 serviceName 可用于分流。

    Haproxy 使用自签证书进行双端认证(gRPC 示例)

    这里使用自签证书双端认证加强隧道安全性(但会牺牲一点延迟,不过使用 gRPC 后感知不强),而服务端同时处理信任的证书和自签名证书,并据此分流伪装网站和隧道流量

    其中 www.example.com 为伪装站信任证书(如白话文中申请的证书)

    tunnel.example.com 为自签证书网址,自签证书可以参考 https://learn.microsoft.com/zh-cn/azure/application-gateway/self-signed-certificates

    根证书 ca.crt 服务器证书 server.crt 服务器密钥 server.key

    至少需要生成一个 server.pem,客户端可以同样使用此证书用于双端认证;或者生成两个证书,一个 client,一个 server,用于双端认证

    需准备 fullchain.crt 用于认证( cat server.crt ca.crt > fullchain.crt ),server.pem ( cat server.crt server.key ca.crt > server.pem )用于解密

    haproxy_client 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    tune.h2.initial-window-size 536870912\n    tune.h2.max-concurrent-streams 512\n\n    ssl-default-server-options ssl-min-ver TLSv1.3\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client 300s\n    timeout server 300s\n\nfrontend xray\n    bind 127.0.0.1:6666 proto h2\n    default_backend tunnel\n\nbackend tunnel\n    server tunnel tunnel.example.com:443 tfo allow-0rtt ssl crt /path/to/client.pem verify required ca-file /path/to/fullchain.crt sni str(tunnel.example.com) alpn h2\n    # 网址自定义,和自签证书一致即可,hosts 中配置 IP 解析,sni 的 str 设定 sni,用于服务端识别\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

    haproxy_server 配置

    global\n    log /dev/log local0 alert\n    log /dev/log local1 alert\n    stats socket /dev/shm/admin.sock mode 660 level admin expose-fd listeners\n    stats timeout 30s\n    user root\n    group root\n    daemon\n\n    tune.h2.initial-window-size 536870912\n    tune.h2.max-concurrent-streams 512\n\n    ssl-default-bind-ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256\n    ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n    ssl-default-bind-options ssl-min-ver TLSv1.2\n\ndefaults\n    log global\n    mode http\n    timeout connect 5s\n    timeout client  300s\n    timeout server  300s\n\nfrontend tls-in\n    bind :::443 tfo allow-0rtt ssl crt /path/to/server.pem verify optional ca-file /path/to/fullchain.crt crt /path/to/www.example.com.pem alpn h2,http/1.1\n    use_backend xray if { ssl_fc_sni tunnel.example.com } { ssl_c_used } { ssl_fc_alpn -i h2 } { path_beg /tunnel }\n    use_backend server1 if { ssl_fc_sni atunnel.example.com } { ssl_c_used }  { ssl_fc_alpn -i h2 } { path_beg /path2 }\n    use_backend server2 if { ssl_fc_sni btunnel.example.com } { ssl_c_used }  { ssl_fc_alpn -i h2 } { path_beg /path3 }\n    use_backend server3 if { ssl_fc_sni ctunnel.example.com } { ssl_c_used }  { ssl_fc_alpn -i h2 } { path_beg /path4 }\n    default_backend web\n    # Haproxy 支持多个 pem 解密\n    # 可根据多个客户端的不同 sni 分流,也可以 path 分流,方式多样,更多 acl 见 Haproxy 文档\n\nbackend xray\n    server xray abns@vless.sock proto h2\n\nbackend server1\n    server server1 abns@server1.sock proto h2\n\nbackend server2\n    server server2 abns@server2.sock proto h2\n\nbackend server3\n    server server3 abns@server3.sock proto h2\n\nbackend web\n    server web /dev/shm/h1h2c.sock\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47

    xray 配置

    简单的 gRPC 配置,无需 TLS,配置见文档,配置的 serviceName 可用于分流。

    ',70);b.render=function(p,t){const b=n("OutboundLink");return s(),a(l,null,[u,e("p",null,[i,e("a",c,[o,r(b)])]),m],64)};export default b; diff --git a/assets/nginx_tls_tunnel.html.48634e5e.js b/assets/nginx_tls_tunnel.html.2bd19916.js similarity index 99% rename from assets/nginx_tls_tunnel.html.48634e5e.js rename to assets/nginx_tls_tunnel.html.2bd19916.js index bc762da80..7566bfa46 100644 --- a/assets/nginx_tls_tunnel.html.48634e5e.js +++ b/assets/nginx_tls_tunnel.html.2bd19916.js @@ -1 +1 @@ -import{r as n,o as t,c as s,a,b as e,F as r,d as l,e as u}from"./app.755d843f.js";const p={},o=l('

    客户端服务端构建 Nginx 隧道隐藏指纹

    网路结构:

    xray_client ---tcp--- nginx_client ---tcp_TLS--- 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

    服务端加入如下配置

    ',16),b=u("服务器申请证书不再赘述,参考"),i={href:"https://xtls.github.io/document/level-0/ch06-certificates.html",target:"_blank",rel:"noopener noreferrer"},c=u("白话文"),m=l('
    stream {\n    server {\n        listen 443 ssl;\n        listen [::]:443 ssl;\n        ssl_protocols TLSv1.3;\n        ssl_certificate /path/to/cert/domain.crt; #crt文件位置\n        ssl_certificate_key /path/to/cert/domain.key; #key文件位置\n        proxy_pass unix:/dev/shm/vless.sock; #使用 domain socket\n    }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    注意

    stream 部分与 http 模块并列,客户端可删除 http 部分,服务端可删除或搭建网页伪装回落

    客户端加入如下配置

    stream {\n    server {\n        listen 6666;\n        listen [::]:6666;\n        proxy_ssl on;\n        proxy_ssl_protocols TLSv1.3;\n        proxy_ssl_server_name on;\n        proxy_ssl_name yourdomain.domain; #服务器域名\n        proxy_pass ip:443; #服务器 ip 形如 proxy_pass 6.6.6.6:443; 或 proxy_pass [2401:0:0::1]:443;\n    }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    /etc/systemd/system 文件夹中创建 nginx.service 文件

    vim /etc/systemd/system/nginx.service

    写入如下

    [Unit]\nDescription=The NGINX HTTP and reverse proxy server\nAfter=syslog.target network-online.target remote-fs.target nss-lookup.target\nAfter=xray.service\n\n[Service]\nType=forking\nExecStartPre=/usr/local/nginx/sbin/nginx -t\nExecStart=/usr/local/nginx/sbin/nginx\nExecReload=/usr/local/nginx/sbin/nginx -s reload\nExecStop=/bin/kill -s QUIT $MAINPID\nPrivateTmp=true\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    加入开机自启

    systemctl enable nginx

    xray 配置

    服务端 xray 配置

    {\n\t"log": {\n\t\t"loglevel": "none"\n\t},\n\t"inbounds": [\n\t\t{\n\t\t\t"listen": "/dev/shm/vless.sock,0666",\n\t\t\t"protocol": "vless",\n\t\t\t"settings": {\n\t\t\t\t"clients": [\n\t\t\t\t\t{\n\t\t\t\t\t\t"id": "uuid"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t"decryption": "none"\n\t\t\t},\n\t\t\t"streamSettings": {\n\t\t\t\t"network": "tcp"\n\t\t\t},\n\t\t\t"sniffing": {\n\t\t\t\t"enabled": true,\n\t\t\t\t"destOverride": [\n\t\t\t\t\t"http",\n\t\t\t\t\t"tls"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t"outbounds": [\n\t\t{\n\t\t\t"protocol": "freedom"\n\t\t}\n\t]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    客户端 xray 配置,此处以旁路由透明代理为例

    {\n\t"log": {\n\t\t"loglevel": "none"\n\t},\n\t"inbounds": [\n\t\t{\n\t\t\t"tag": "tproxy-in",\n\t\t\t"port": 12345,\n\t\t\t"protocol": "dokodemo-door",\n\t\t\t"settings": {\n\t\t\t\t"network": "tcp,udp",\n\t\t\t\t"followRedirect": true\n\t\t\t},\n\t\t\t"sniffing": {\n\t\t\t\t"enabled": true,\n\t\t\t\t"destOverride": [\n\t\t\t\t\t"http",\n\t\t\t\t\t"tls"\n\t\t\t\t],\n\t\t\t\t"routeOnly": true\n\t\t\t},\n\t\t\t"streamSettings": {\n\t\t\t\t"sockopt": {\n\t\t\t\t\t"tproxy": "tproxy",\n\t\t\t\t\t"mark": 255\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t"tag": "http",\n\t\t\t"port": 10808,\n\t\t\t"listen": "127.0.0.1",\n\t\t\t"protocol": "http",\n\t\t\t"sniffing": {\n\t\t\t\t"enabled": true,\n\t\t\t\t"destOverride": [\n\t\t\t\t\t"http",\n\t\t\t\t\t"tls"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t"outbounds": [\n\t\t{\n\t\t\t"tag": "nginxtls",\n\t\t\t"protocol": "vless",\n\t\t\t"settings": {\n\t\t\t\t"vnext": [\n\t\t\t\t\t{\n\t\t\t\t\t\t"address": "127.0.0.1",\n\t\t\t\t\t\t"port": 6666,\n\t\t\t\t\t\t"users": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t"id": "uuid",\n\t\t\t\t\t\t\t\t"encryption": "none"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t"streamSettings": {\n\t\t\t\t"sockopt": {\n\t\t\t\t\t"mark": 255\n\t\t\t\t},\n\t\t\t\t"network": "tcp"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t"tag": "direct",\n\t\t\t"protocol": "freedom",\n\t\t\t"streamSettings": {\n\t\t\t\t"sockopt": {\n\t\t\t\t\t"mark": 255\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t"tag": "block",\n\t\t\t"protocol": "blackhole",\n\t\t\t"settings": {\n\t\t\t\t"response": {\n\t\t\t\t\t"type": "http"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t],\n\t"routing": {\n\t\t"domainMatcher": "mph",\n\t\t"domainStrategy": "AsIs",\n\t\t"rules": [\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"domain": [\n\t\t\t\t\t"geosite:category-ads-all"\n\t\t\t\t],\n\t\t\t\t"outboundTag": "block"\n\t\t\t},\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"port": 123,\n\t\t\t\t"network": "udp",\n\t\t\t\t"outboundTag": "direct"\n\t\t\t},\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"domain": [\n\t\t\t\t\t"geosite:cn"\n\t\t\t\t],\n\t\t\t\t"outboundTag": "direct"\n\t\t\t},\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"protocol": [\n\t\t\t\t\t"bittorrent"\n\t\t\t\t],\n\t\t\t\t"outboundTag": "direct"\n\t\t\t},\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"ip": [\n\t\t\t\t\t"geoip:private"\n\t\t\t\t],\n\t\t\t\t"outboundTag": "direct"\n\t\t\t},\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"inboundTag": [\n\t\t\t\t\t"tproxy-in"\n\t\t\t\t],\n\t\t\t\t"outboundTag": "nginxtls"\n\t\t\t}\n\t\t]\n\t}\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134

    如果使用透明代理需要在 iptables 或 ip6tables 配置中加入

    iptables -t mangle -A XRAY_MASK -d VSP_IPv4/32 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d VPS_IPv6/128 -j RETURN\n
    1
    2

    客户端及服务端启动服务

    systemctl restart xray

    systemctl restart nginx

    后记

    客户端应该也是可以通过 domain socket 连接提高性能,但由于 xray outbound 不支持 ds 出站,想了半天没什么好的实现方法。如果 vnext 里支持 ds 就好了 (没有别的意思)。

    从客户端 nginx 开始应该可以选择 http2 grpc ws 等传输方式。

    ',23);p.render=function(l,u){const p=n("OutboundLink");return t(),s(r,null,[o,a("p",null,[b,a("a",i,[c,e(p)])]),m],64)};export default p; +import{r as n,o as t,c as s,a,b as e,F as r,d as l,e as u}from"./app.48111a85.js";const p={},o=l('

    客户端服务端构建 Nginx 隧道隐藏指纹

    网路结构:

    xray_client ---tcp--- nginx_client ---tcp_TLS--- 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

    服务端加入如下配置

    ',16),b=u("服务器申请证书不再赘述,参考"),i={href:"https://xtls.github.io/document/level-0/ch06-certificates.html",target:"_blank",rel:"noopener noreferrer"},c=u("白话文"),m=l('
    stream {\n    server {\n        listen 443 ssl;\n        listen [::]:443 ssl;\n        ssl_protocols TLSv1.3;\n        ssl_certificate /path/to/cert/domain.crt; #crt文件位置\n        ssl_certificate_key /path/to/cert/domain.key; #key文件位置\n        proxy_pass unix:/dev/shm/vless.sock; #使用 domain socket\n    }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    注意

    stream 部分与 http 模块并列,客户端可删除 http 部分,服务端可删除或搭建网页伪装回落

    客户端加入如下配置

    stream {\n    server {\n        listen 6666;\n        listen [::]:6666;\n        proxy_ssl on;\n        proxy_ssl_protocols TLSv1.3;\n        proxy_ssl_server_name on;\n        proxy_ssl_name yourdomain.domain; #服务器域名\n        proxy_pass ip:443; #服务器 ip 形如 proxy_pass 6.6.6.6:443; 或 proxy_pass [2401:0:0::1]:443;\n    }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    /etc/systemd/system 文件夹中创建 nginx.service 文件

    vim /etc/systemd/system/nginx.service

    写入如下

    [Unit]\nDescription=The NGINX HTTP and reverse proxy server\nAfter=syslog.target network-online.target remote-fs.target nss-lookup.target\nAfter=xray.service\n\n[Service]\nType=forking\nExecStartPre=/usr/local/nginx/sbin/nginx -t\nExecStart=/usr/local/nginx/sbin/nginx\nExecReload=/usr/local/nginx/sbin/nginx -s reload\nExecStop=/bin/kill -s QUIT $MAINPID\nPrivateTmp=true\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    加入开机自启

    systemctl enable nginx

    xray 配置

    服务端 xray 配置

    {\n\t"log": {\n\t\t"loglevel": "none"\n\t},\n\t"inbounds": [\n\t\t{\n\t\t\t"listen": "/dev/shm/vless.sock,0666",\n\t\t\t"protocol": "vless",\n\t\t\t"settings": {\n\t\t\t\t"clients": [\n\t\t\t\t\t{\n\t\t\t\t\t\t"id": "uuid"\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t"decryption": "none"\n\t\t\t},\n\t\t\t"streamSettings": {\n\t\t\t\t"network": "tcp"\n\t\t\t},\n\t\t\t"sniffing": {\n\t\t\t\t"enabled": true,\n\t\t\t\t"destOverride": [\n\t\t\t\t\t"http",\n\t\t\t\t\t"tls"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t"outbounds": [\n\t\t{\n\t\t\t"protocol": "freedom"\n\t\t}\n\t]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34

    客户端 xray 配置,此处以旁路由透明代理为例

    {\n\t"log": {\n\t\t"loglevel": "none"\n\t},\n\t"inbounds": [\n\t\t{\n\t\t\t"tag": "tproxy-in",\n\t\t\t"port": 12345,\n\t\t\t"protocol": "dokodemo-door",\n\t\t\t"settings": {\n\t\t\t\t"network": "tcp,udp",\n\t\t\t\t"followRedirect": true\n\t\t\t},\n\t\t\t"sniffing": {\n\t\t\t\t"enabled": true,\n\t\t\t\t"destOverride": [\n\t\t\t\t\t"http",\n\t\t\t\t\t"tls"\n\t\t\t\t],\n\t\t\t\t"routeOnly": true\n\t\t\t},\n\t\t\t"streamSettings": {\n\t\t\t\t"sockopt": {\n\t\t\t\t\t"tproxy": "tproxy",\n\t\t\t\t\t"mark": 255\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t"tag": "http",\n\t\t\t"port": 10808,\n\t\t\t"listen": "127.0.0.1",\n\t\t\t"protocol": "http",\n\t\t\t"sniffing": {\n\t\t\t\t"enabled": true,\n\t\t\t\t"destOverride": [\n\t\t\t\t\t"http",\n\t\t\t\t\t"tls"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t"outbounds": [\n\t\t{\n\t\t\t"tag": "nginxtls",\n\t\t\t"protocol": "vless",\n\t\t\t"settings": {\n\t\t\t\t"vnext": [\n\t\t\t\t\t{\n\t\t\t\t\t\t"address": "127.0.0.1",\n\t\t\t\t\t\t"port": 6666,\n\t\t\t\t\t\t"users": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t"id": "uuid",\n\t\t\t\t\t\t\t\t"encryption": "none"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t"streamSettings": {\n\t\t\t\t"sockopt": {\n\t\t\t\t\t"mark": 255\n\t\t\t\t},\n\t\t\t\t"network": "tcp"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t"tag": "direct",\n\t\t\t"protocol": "freedom",\n\t\t\t"streamSettings": {\n\t\t\t\t"sockopt": {\n\t\t\t\t\t"mark": 255\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t"tag": "block",\n\t\t\t"protocol": "blackhole",\n\t\t\t"settings": {\n\t\t\t\t"response": {\n\t\t\t\t\t"type": "http"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t],\n\t"routing": {\n\t\t"domainMatcher": "mph",\n\t\t"domainStrategy": "AsIs",\n\t\t"rules": [\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"domain": [\n\t\t\t\t\t"geosite:category-ads-all"\n\t\t\t\t],\n\t\t\t\t"outboundTag": "block"\n\t\t\t},\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"port": 123,\n\t\t\t\t"network": "udp",\n\t\t\t\t"outboundTag": "direct"\n\t\t\t},\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"domain": [\n\t\t\t\t\t"geosite:cn"\n\t\t\t\t],\n\t\t\t\t"outboundTag": "direct"\n\t\t\t},\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"protocol": [\n\t\t\t\t\t"bittorrent"\n\t\t\t\t],\n\t\t\t\t"outboundTag": "direct"\n\t\t\t},\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"ip": [\n\t\t\t\t\t"geoip:private"\n\t\t\t\t],\n\t\t\t\t"outboundTag": "direct"\n\t\t\t},\n\t\t\t{\n\t\t\t\t"type": "field",\n\t\t\t\t"inboundTag": [\n\t\t\t\t\t"tproxy-in"\n\t\t\t\t],\n\t\t\t\t"outboundTag": "nginxtls"\n\t\t\t}\n\t\t]\n\t}\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134

    如果使用透明代理需要在 iptables 或 ip6tables 配置中加入

    iptables -t mangle -A XRAY_MASK -d VSP_IPv4/32 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d VPS_IPv6/128 -j RETURN\n
    1
    2

    客户端及服务端启动服务

    systemctl restart xray

    systemctl restart nginx

    后记

    客户端应该也是可以通过 domain socket 连接提高性能,但由于 xray outbound 不支持 ds 出站,想了半天没什么好的实现方法。如果 vnext 里支持 ds 就好了 (没有别的意思)。

    从客户端 nginx 开始应该可以选择 http2 grpc ws 等传输方式。

    ',23);p.render=function(l,u){const p=n("OutboundLink");return t(),s(r,null,[o,a("p",null,[b,a("a",i,[c,e(p)])]),m],64)};export default p; diff --git a/assets/outbound.html.27f8ad33.js b/assets/outbound.html.302f540c.js similarity index 99% rename from assets/outbound.html.27f8ad33.js rename to assets/outbound.html.302f540c.js index 14f8d24a7..261b1fc87 100644 --- a/assets/outbound.html.27f8ad33.js +++ b/assets/outbound.html.302f540c.js @@ -1 +1 @@ -import{r as n,o as s,c as o,a,b as e,w as t,F as p,e as c,d as u}from"./app.755d843f.js";const r={},l=a("h1",{id:"出站代理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#出站代理","aria-hidden":"true"},"#"),c(" 出站代理")],-1),d=c("出站连接用于发送数据,可用的协议请见 "),i=c("出站协议"),b=c("。"),k=u('

    OutboundObject

    OutboundObject 对应配置文件中 outbounds 项的一个子元素。

    提示

    列表中的第一个元素作为主 outbound。当路由匹配不存在或没有匹配成功时,流量由主 outbound 发出。

    {\n  "outbounds": [\n    {\n      "sendThrough": "0.0.0.0",\n      "protocol": "协议名称",\n      "settings": {},\n      "tag": "标识",\n      "streamSettings": {},\n      "proxySettings": {\n        "tag": "another-outbound-tag"\n      },\n      "mux": {}\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    sendThrough: address

    用于发送数据的 IP 地址,当主机有多个 IP 地址时有效,默认值为 "0.0.0.0"

    protocol: string

    ',7),m=c("连接协议名称,可选的协议类型见 "),q=c("出站协议"),g=c("。"),x=u('

    settings: OutboundConfigurationObject

    具体的配置内容,视协议不同而不同。详见每个协议中的 OutboundConfigurationObject

    tag: string

    此出站连接的标识,用于在其它的配置中定位此连接。

    警告

    当其不为空时,其值必须在所有 tag唯一

    ',5),h=a("code",null,"streamSettings",-1),y=c(": "),j=c("StreamSettingsObject"),P=u('

    底层传输方式(transport)是当前 Xray 节点和其它节点对接的方式

    proxySettings: ProxySettingsObject

    出站代理配置。当出站代理生效时,此 outbound 的 streamSettings 将不起作用。

    mux: MuxObject

    Mux 相关的具体配置。

    ProxySettingsObject

    {\n  "tag": "another-outbound-tag"\n}\n
    1
    2
    3

    tag: string

    当指定另一个 outbound 的标识时,此 outbound 发出的数据,将被转发至所指定的 outbound 发出。

    ',9),f={class:"custom-container danger"},v=a("p",{class:"custom-container-title"},"警告",-1),O=c("这种转发方式"),S=a("strong",null,"不经过",-1),T=c("底层传输方式。如果需要使用支持底层传输方式的转发,请使用 "),C=c("SockOpt.dialerProxy"),M=c("。"),U=a("div",{class:"custom-container danger"},[a("p",{class:"custom-container-title"},"警告"),a("p",null,"此选项与 SockOpt.dialerProxy 不兼容")],-1),D={class:"custom-container tip"},w=a("p",{class:"custom-container-title"},"提示",-1),L=c("兼容 v2fly/v2ray-core 的配置 "),_={href:"https://www.v2fly.org/config/outbounds.html#proxysettingsobject",target:"_blank",rel:"noopener noreferrer"},I=c("transportLayer"),X=u('

    MuxObject

    Mux 功能是在一条 TCP 连接上分发多个 TCP 连接的数据。实现细节详见 Mux.Cool。Mux 是为了减少 TCP 的握手延迟而设计,而非提高连接的吞吐量。使用 Mux 看视频、下载或者测速通常都有反效果。Mux 只需要在客户端启用,服务器端自动适配。

    MuxObject 对应 OutboundObject 中的 mux 项。

    {\n  "enabled": true,\n  "concurrency": 8,\n  "xudpConcurrency": 16,\n  "xudpProxyUDP443": "reject"\n}\n
    1
    2
    3
    4
    5
    6

    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。
    ',16);r.render=function(c,u){const r=n("RouterLink"),E=n("OutboundLink");return s(),o(p,null,[l,a("p",null,[d,e(r,{to:"/config/outbounds/"},{default:t((()=>[i])),_:1}),b]),k,a("p",null,[m,e(r,{to:"/config/outbounds/"},{default:t((()=>[q])),_:1}),g]),x,a("blockquote",null,[a("p",null,[h,y,e(r,{to:"/config/transport.html#streamsettingsobject"},{default:t((()=>[j])),_:1})])]),P,a("div",f,[v,a("p",null,[O,S,T,e(r,{to:"/config/transport.html#sockoptobject"},{default:t((()=>[C])),_:1}),M])]),U,a("div",D,[w,a("p",null,[L,a("a",_,[I,e(E)])])]),X],64)};export default r; +import{r as n,o as s,c as o,a,b as e,w as t,F as p,e as c,d as u}from"./app.48111a85.js";const r={},l=a("h1",{id:"出站代理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#出站代理","aria-hidden":"true"},"#"),c(" 出站代理")],-1),d=c("出站连接用于发送数据,可用的协议请见 "),i=c("出站协议"),b=c("。"),k=u('

    OutboundObject

    OutboundObject 对应配置文件中 outbounds 项的一个子元素。

    提示

    列表中的第一个元素作为主 outbound。当路由匹配不存在或没有匹配成功时,流量由主 outbound 发出。

    {\n  "outbounds": [\n    {\n      "sendThrough": "0.0.0.0",\n      "protocol": "协议名称",\n      "settings": {},\n      "tag": "标识",\n      "streamSettings": {},\n      "proxySettings": {\n        "tag": "another-outbound-tag"\n      },\n      "mux": {}\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    sendThrough: address

    用于发送数据的 IP 地址,当主机有多个 IP 地址时有效,默认值为 "0.0.0.0"

    protocol: string

    ',7),m=c("连接协议名称,可选的协议类型见 "),q=c("出站协议"),g=c("。"),x=u('

    settings: OutboundConfigurationObject

    具体的配置内容,视协议不同而不同。详见每个协议中的 OutboundConfigurationObject

    tag: string

    此出站连接的标识,用于在其它的配置中定位此连接。

    警告

    当其不为空时,其值必须在所有 tag唯一

    ',5),h=a("code",null,"streamSettings",-1),y=c(": "),j=c("StreamSettingsObject"),P=u('

    底层传输方式(transport)是当前 Xray 节点和其它节点对接的方式

    proxySettings: ProxySettingsObject

    出站代理配置。当出站代理生效时,此 outbound 的 streamSettings 将不起作用。

    mux: MuxObject

    Mux 相关的具体配置。

    ProxySettingsObject

    {\n  "tag": "another-outbound-tag"\n}\n
    1
    2
    3

    tag: string

    当指定另一个 outbound 的标识时,此 outbound 发出的数据,将被转发至所指定的 outbound 发出。

    ',9),f={class:"custom-container danger"},v=a("p",{class:"custom-container-title"},"警告",-1),O=c("这种转发方式"),S=a("strong",null,"不经过",-1),T=c("底层传输方式。如果需要使用支持底层传输方式的转发,请使用 "),C=c("SockOpt.dialerProxy"),M=c("。"),U=a("div",{class:"custom-container danger"},[a("p",{class:"custom-container-title"},"警告"),a("p",null,"此选项与 SockOpt.dialerProxy 不兼容")],-1),D={class:"custom-container tip"},w=a("p",{class:"custom-container-title"},"提示",-1),L=c("兼容 v2fly/v2ray-core 的配置 "),_={href:"https://www.v2fly.org/config/outbounds.html#proxysettingsobject",target:"_blank",rel:"noopener noreferrer"},I=c("transportLayer"),X=u('

    MuxObject

    Mux 功能是在一条 TCP 连接上分发多个 TCP 连接的数据。实现细节详见 Mux.Cool。Mux 是为了减少 TCP 的握手延迟而设计,而非提高连接的吞吐量。使用 Mux 看视频、下载或者测速通常都有反效果。Mux 只需要在客户端启用,服务器端自动适配。

    MuxObject 对应 OutboundObject 中的 mux 项。

    {\n  "enabled": true,\n  "concurrency": 8,\n  "xudpConcurrency": 16,\n  "xudpProxyUDP443": "reject"\n}\n
    1
    2
    3
    4
    5
    6

    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。
    ',16);r.render=function(c,u){const r=n("RouterLink"),E=n("OutboundLink");return s(),o(p,null,[l,a("p",null,[d,e(r,{to:"/config/outbounds/"},{default:t((()=>[i])),_:1}),b]),k,a("p",null,[m,e(r,{to:"/config/outbounds/"},{default:t((()=>[q])),_:1}),g]),x,a("blockquote",null,[a("p",null,[h,y,e(r,{to:"/config/transport.html#streamsettingsobject"},{default:t((()=>[j])),_:1})])]),P,a("div",f,[v,a("p",null,[O,S,T,e(r,{to:"/config/transport.html#sockoptobject"},{default:t((()=>[C])),_:1}),M])]),U,a("div",D,[w,a("p",null,[L,a("a",_,[I,e(E)])])]),X],64)};export default r; diff --git a/assets/outbound.html.d2fa4921.js b/assets/outbound.html.9d0f168f.js similarity index 99% rename from assets/outbound.html.d2fa4921.js rename to assets/outbound.html.9d0f168f.js index 9aa844037..16183f50a 100644 --- a/assets/outbound.html.d2fa4921.js +++ b/assets/outbound.html.9d0f168f.js @@ -1 +1 @@ -import{r as n,o as e,c as o,a as s,b as t,w as a,F as c,e as p,d as u}from"./app.755d843f.js";const r={},i=s("h1",{id:"outbound-proxies",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#outbound-proxies","aria-hidden":"true"},"#"),p(" Outbound Proxies")],-1),l=p("Outbound connections are used for sending data and can use any of the available protocols listed in "),d=p("outbound protocols"),b=p("."),h=u('

    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.

    {\n  "outbounds": [\n    {\n      "sendThrough": "0.0.0.0",\n      "protocol": "protocol name",\n      "settings": {},\n      "tag": "identifier",\n      "streamSettings": {},\n      "proxySettings": {\n        "tag": "another-outbound-tag"\n      },\n      "mux": {}\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    sendThrough: address

    The IP address used to send data. It is effective when the host has multiple IP addresses, and the default value is "0.0.0.0".

    protocol: string

    ',7),m=p("The name of the connection protocol. The optional protocol types can be found in "),g=p("outbound protocols"),k=p("."),f=u('

    settings: OutboundConfigurationObject

    The specific configuration content varies depending on the protocol. See OutboundConfigurationObject in each protocol for details.

    tag: string

    The identifier of this outbound connection, used to locate this connection in other configurations.

    Danger

    When it is not empty, its value must be unique among all tags.

    ',5),q=s("code",null,"streamSettings",-1),y=p(": "),x=p("StreamSettingsObject"),v=u('

    The underlying transport method is the way the current Xray node and other nodes are docked.

    proxySettings: ProxySettingsObject

    The outbound proxy configuration. When the outbound proxy takes effect, the streamSettings of this outbound will not work.

    mux: MuxObject

    Specific configuration related to Mux.

    ProxySettingsObject

    {\n  "tag": "another-outbound-tag"\n}\n
    1
    2
    3

    tag: string

    When specifying the identifier of another outbound, data emitted by this outbound will be forwarded to the specified outbound.

    ',9),j={class:"custom-container danger"},T=s("p",{class:"custom-container-title"},"Danger",-1),O=p("This forwarding method does "),w=s("strong",null,"not go through",-1),P=p(" the underlying transport. If you need to use forwarding that supports the underlying transport, please use "),M=p("SockOpt.dialerProxy"),S=p("."),C=s("div",{class:"custom-container danger"},[s("p",{class:"custom-container-title"},"Danger"),s("p",null,"This option is incompatible with SockOpt.dialerProxy.")],-1),W={class:"custom-container tip"},_=s("p",{class:"custom-container-title"},"Tip",-1),I=p("Compatible with v2fly/v2ray-core's configuration "),D={href:"https://www.v2fly.org/config/outbounds.html#proxysettingsobject",target:"_blank",rel:"noopener noreferrer"},F=p("transportLayer"),L=p("."),X=u('

    MuxObject

    The Mux function distributes the data of multiple TCP connections on a single TCP connection. For implementation details, see Mux.Cool. Mux is designed to reduce the latency of TCP handshake, not to increase the throughput of connections. Using Mux for watching videos, downloading, or speed testing usually has negative effects. Mux only needs to be enabled on the client side, and the server side automatically adapts.

    MuxObject corresponds to the mux item in OutboundObject.

    {\n  "enabled": false,\n  "concurrency": 8\n}\n
    1
    2
    3
    4

    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.

    ',10);r.render=function(p,u){const r=n("RouterLink"),R=n("OutboundLink");return e(),o(c,null,[i,s("p",null,[l,t(r,{to:"/en/config/outbounds/"},{default:a((()=>[d])),_:1}),b]),h,s("p",null,[m,t(r,{to:"/en/config/outbounds/"},{default:a((()=>[g])),_:1}),k]),f,s("blockquote",null,[s("p",null,[q,y,t(r,{to:"/en/config/transport.html#streamsettingsobject"},{default:a((()=>[x])),_:1})])]),v,s("div",j,[T,s("p",null,[O,w,P,t(r,{to:"/en/config/transport.html#sockoptobject"},{default:a((()=>[M])),_:1}),S])]),C,s("div",W,[_,s("p",null,[I,s("a",D,[F,t(R)]),L])]),X],64)};export default r; +import{r as n,o as e,c as o,a as s,b as t,w as a,F as c,e as p,d as u}from"./app.48111a85.js";const r={},i=s("h1",{id:"outbound-proxies",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#outbound-proxies","aria-hidden":"true"},"#"),p(" Outbound Proxies")],-1),l=p("Outbound connections are used for sending data and can use any of the available protocols listed in "),d=p("outbound protocols"),b=p("."),h=u('

    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.

    {\n  "outbounds": [\n    {\n      "sendThrough": "0.0.0.0",\n      "protocol": "protocol name",\n      "settings": {},\n      "tag": "identifier",\n      "streamSettings": {},\n      "proxySettings": {\n        "tag": "another-outbound-tag"\n      },\n      "mux": {}\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    sendThrough: address

    The IP address used to send data. It is effective when the host has multiple IP addresses, and the default value is "0.0.0.0".

    protocol: string

    ',7),m=p("The name of the connection protocol. The optional protocol types can be found in "),g=p("outbound protocols"),k=p("."),f=u('

    settings: OutboundConfigurationObject

    The specific configuration content varies depending on the protocol. See OutboundConfigurationObject in each protocol for details.

    tag: string

    The identifier of this outbound connection, used to locate this connection in other configurations.

    Danger

    When it is not empty, its value must be unique among all tags.

    ',5),q=s("code",null,"streamSettings",-1),y=p(": "),x=p("StreamSettingsObject"),v=u('

    The underlying transport method is the way the current Xray node and other nodes are docked.

    proxySettings: ProxySettingsObject

    The outbound proxy configuration. When the outbound proxy takes effect, the streamSettings of this outbound will not work.

    mux: MuxObject

    Specific configuration related to Mux.

    ProxySettingsObject

    {\n  "tag": "another-outbound-tag"\n}\n
    1
    2
    3

    tag: string

    When specifying the identifier of another outbound, data emitted by this outbound will be forwarded to the specified outbound.

    ',9),j={class:"custom-container danger"},T=s("p",{class:"custom-container-title"},"Danger",-1),O=p("This forwarding method does "),w=s("strong",null,"not go through",-1),P=p(" the underlying transport. If you need to use forwarding that supports the underlying transport, please use "),M=p("SockOpt.dialerProxy"),S=p("."),C=s("div",{class:"custom-container danger"},[s("p",{class:"custom-container-title"},"Danger"),s("p",null,"This option is incompatible with SockOpt.dialerProxy.")],-1),W={class:"custom-container tip"},_=s("p",{class:"custom-container-title"},"Tip",-1),I=p("Compatible with v2fly/v2ray-core's configuration "),D={href:"https://www.v2fly.org/config/outbounds.html#proxysettingsobject",target:"_blank",rel:"noopener noreferrer"},F=p("transportLayer"),L=p("."),X=u('

    MuxObject

    The Mux function distributes the data of multiple TCP connections on a single TCP connection. For implementation details, see Mux.Cool. Mux is designed to reduce the latency of TCP handshake, not to increase the throughput of connections. Using Mux for watching videos, downloading, or speed testing usually has negative effects. Mux only needs to be enabled on the client side, and the server side automatically adapts.

    MuxObject corresponds to the mux item in OutboundObject.

    {\n  "enabled": false,\n  "concurrency": 8\n}\n
    1
    2
    3
    4

    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.

    ',10);r.render=function(p,u){const r=n("RouterLink"),R=n("OutboundLink");return e(),o(c,null,[i,s("p",null,[l,t(r,{to:"/en/config/outbounds/"},{default:a((()=>[d])),_:1}),b]),h,s("p",null,[m,t(r,{to:"/en/config/outbounds/"},{default:a((()=>[g])),_:1}),k]),f,s("blockquote",null,[s("p",null,[q,y,t(r,{to:"/en/config/transport.html#streamsettingsobject"},{default:a((()=>[x])),_:1})])]),v,s("div",j,[T,s("p",null,[O,w,P,t(r,{to:"/en/config/transport.html#sockoptobject"},{default:a((()=>[M])),_:1}),S])]),C,s("div",W,[_,s("p",null,[I,s("a",D,[F,t(R)]),L])]),X],64)};export default r; diff --git a/assets/pieDiagram-f5e05a25.2e8e66ce.js b/assets/pieDiagram-f5e05a25.e734d891.js similarity index 99% rename from assets/pieDiagram-f5e05a25.2e8e66ce.js rename to assets/pieDiagram-f5e05a25.e734d891.js index 6c401b890..c71eba5fb 100644 --- a/assets/pieDiagram-f5e05a25.2e8e66ce.js +++ b/assets/pieDiagram-f5e05a25.e734d891.js @@ -1 +1 @@ -import{ao as t,c as e,s as i,g as n,v as r,x as s,a,b as c,m as o,j as l,l as h,z as u,h as p,i as y,ap as d}from"./mermaid.core.a66200b0.js";import{i as f}from"./init.0b4a962a.js";import{a as g}from"./array.999c8e45.js";import{c as _}from"./constant.4f073c13.js";import{a as m}from"./arc.56fd4148.js";class v extends Map{constructor(t,e=k){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const[i,n]of t)this.set(i,n)}get(t){return super.get(b(this,t))}has(t){return super.has(b(this,t))}set(t,e){return super.set(function({_intern:t,_key:e},i){const n=e(i);return t.has(n)?t.get(n):(t.set(n,i),i)}(this,t),e)}delete(t){return super.delete(function({_intern:t,_key:e},i){const n=e(i);t.has(n)&&(i=t.get(n),t.delete(n));return i}(this,t))}}function b({_intern:t,_key:e},i){const n=e(i);return t.has(n)?t.get(n):i}function k(t){return null!==t&&"object"==typeof t?t.valueOf():t}const x=Symbol("implicit");function S(){var t=new v,e=[],i=[],n=x;function r(r){let s=t.get(r);if(void 0===s){if(n!==x)return n;t.set(r,s=e.push(r)-1)}return i[s%i.length]}return r.domain=function(i){if(!arguments.length)return e.slice();e=[],t=new v;for(const n of i)t.has(n)||t.set(n,e.push(n)-1);return r},r.range=function(t){return arguments.length?(i=Array.from(t),r):i.slice()},r.unknown=function(t){return arguments.length?(n=t,r):n},r.copy=function(){return S(e,i).unknown(n)},f.apply(r,arguments),r}function w(t,e){return et?1:e>=t?0:NaN}function A(t){return t}var E=function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,4],i=[1,5],n=[1,6],r=[1,7],s=[1,9],a=[1,11,13,15,17,19,20,26,27,28,29],c=[2,5],o=[1,6,11,13,15,17,19,20,26,27,28,29],l=[26,27,28],h=[2,8],u=[1,18],p=[1,19],y=[1,20],d=[1,21],f=[1,22],g=[1,23],_=[1,28],m=[6,26,27,28,29],v={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,PIE:6,document:7,showData:8,line:9,statement: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,openDirective:21,typeDirective:22,closeDirective:23,":":24,argDirective:25,NEWLINE:26,";":27,EOF:28,open_directive:29,type_directive:30,arg_directive:31,close_directive:32,$accept:0,$end:1},terminals_:{2:"error",6:"PIE",8:"showData",11:"txt",12:"value",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",24:":",26:"NEWLINE",27:";",28:"EOF",29:"open_directive",30:"type_directive",31:"arg_directive",32:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,3],[7,0],[7,2],[9,2],[10,0],[10,2],[10,2],[10,2],[10,2],[10,1],[10,1],[10,1],[5,3],[5,5],[4,1],[4,1],[4,1],[21,1],[22,1],[25,1],[23,1]],performAction:function(t,e,i,n,r,s,a){var c=s.length-1;switch(r){case 4:n.setShowData(!0);break;case 7:this.$=s[c-1];break;case 9:n.addSection(s[c-1],n.cleanupValue(s[c]));break;case 10:this.$=s[c].trim(),n.setDiagramTitle(this.$);break;case 11:this.$=s[c].trim(),n.setAccTitle(this.$);break;case 12:case 13:this.$=s[c].trim(),n.setAccDescription(this.$);break;case 14:n.addSection(s[c].substr(8)),this.$=s[c].substr(8);break;case 21:n.parseDirective("%%{","open_directive");break;case 22:n.parseDirective(s[c],"type_directive");break;case 23:s[c]=s[c].trim().replace(/'/g,'"'),n.parseDirective(s[c],"arg_directive");break;case 24:n.parseDirective("}%%","close_directive","pie")}},table:[{3:1,4:2,5:3,6:e,21:8,26:i,27:n,28:r,29:s},{1:[3]},{3:10,4:2,5:3,6:e,21:8,26:i,27:n,28:r,29:s},{3:11,4:2,5:3,6:e,21:8,26:i,27:n,28:r,29:s},t(a,c,{7:12,8:[1,13]}),t(o,[2,18]),t(o,[2,19]),t(o,[2,20]),{22:14,30:[1,15]},{30:[2,21]},{1:[2,1]},{1:[2,2]},t(l,h,{21:8,9:16,10:17,5:24,1:[2,3],11:u,13:p,15:y,17:d,19:f,20:g,29:s}),t(a,c,{7:25}),{23:26,24:[1,27],32:_},t([24,32],[2,22]),t(a,[2,6]),{4:29,26:i,27:n,28:r},{12:[1,30]},{14:[1,31]},{16:[1,32]},{18:[1,33]},t(l,[2,13]),t(l,[2,14]),t(l,[2,15]),t(l,h,{21:8,9:16,10:17,5:24,1:[2,4],11:u,13:p,15:y,17:d,19:f,20:g,29:s}),t(m,[2,16]),{25:34,31:[1,35]},t(m,[2,24]),t(a,[2,7]),t(l,[2,9]),t(l,[2,10]),t(l,[2,11]),t(l,[2,12]),{23:36,32:_},{32:[2,23]},t(m,[2,17])],defaultActions:{9:[2,21],10:[2,1],11:[2,2],35:[2,23]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],n=[],r=[null],s=[],a=this.table,c="",o=0,l=0,h=2,u=1,p=s.slice.call(arguments,1),y=Object.create(this.lexer),d={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(d.yy[f]=this.yy[f]);y.setInput(t,d.yy),d.yy.lexer=y,d.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var g=y.yylloc;s.push(g);var _=y.options&&y.options.ranges;function m(){var t;return"number"!=typeof(t=n.pop()||y.lex()||u)&&(t instanceof Array&&(t=(n=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var v,b,k,x,S,w,A,E,D={};;){if(b=i[i.length-1],this.defaultActions[b]?k=this.defaultActions[b]:(null==v&&(v=m()),k=a[b]&&a[b][v]),void 0===k||!k.length||!k[0]){var $="";for(S in E=[],a[b])this.terminals_[S]&&S>h&&E.push("'"+this.terminals_[S]+"'");$=y.showPosition?"Parse error on line "+(o+1)+":\n"+y.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(o+1)+": Unexpected "+(v==u?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError($,{text:y.match,token:this.terminals_[v]||v,line:y.yylineno,loc:g,expected:E})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+v);switch(k[0]){case 1:i.push(v),r.push(y.yytext),s.push(y.yylloc),i.push(k[1]),v=null,l=y.yyleng,c=y.yytext,o=y.yylineno,g=y.yylloc;break;case 2:if(w=this.productions_[k[1]][1],D.$=r[r.length-w],D._$={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},_&&(D._$.range=[s[s.length-(w||1)].range[0],s[s.length-1].range[1]]),void 0!==(x=this.performAction.apply(D,[c,l,o,d.yy,k[1],r,s].concat(p))))return x;w&&(i=i.slice(0,-1*w*2),r=r.slice(0,-1*w),s=s.slice(0,-1*w)),i.push(this.productions_[k[1]][0]),r.push(D.$),s.push(D._$),A=a[i[i.length-2]][i[i.length-1]],i.push(A);break;case 3:return!0}}return!0}},b={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,i=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 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),i.length-1&&(this.yylineno-=i.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:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[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(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var i,n,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in r)this[s]=r[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),s=0;se[0].length)){if(e=i,n=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,r[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,n){switch(i){case 0:return this.begin("open_directive"),29;case 1:return this.begin("type_directive"),30;case 2:return this.popState(),this.begin("arg_directive"),24;case 3:return this.popState(),this.popState(),32;case 4:return 31;case 5:case 6:break;case 7:return 26;case 8:case 9:break;case 10:return this.begin("title"),13;case 11:return this.popState(),"title_value";case 12:return this.begin("acc_title"),15;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),17;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:this.begin("string");break;case 20:this.popState();break;case 21:return"txt";case 22:return 6;case 23:return 8;case 24:return"value";case 25:return 28}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:[\s]+)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:pie\b)/i,/^(?:showData\b)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},title:{rules:[11],inclusive:!1},string:{rules:[20,21],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,12,14,16,19,22,23,24,25],inclusive:!0}}};function k(){this.yy={}}return v.lexer=b,k.prototype=v,v.Parser=k,new k}();E.parser=E;const D=E;let $={},T=!1;const I={parseDirective:function(t,e,i){o.parseDirective(this,t,e,i)},getConfig:()=>e().pie,addSection:function(t,i){t=l.sanitizeText(t,e()),void 0===$[t]&&($[t]=i,h.debug("Added new section :",t))},getSections:()=>$,cleanupValue:function(t){return":"===t.substring(0,1)?(t=t.substring(1).trim(),Number(t.trim())):Number(t.trim())},clear:function(){$={},T=!1,u()},setAccTitle:i,getAccTitle:n,setDiagramTitle:r,getDiagramTitle:s,setShowData:function(t){T=t},getShowData:function(){return T},getAccDescription:a,setAccDescription:c},O=t=>`\n .pieCircle{\n stroke: ${t.pieStrokeColor};\n stroke-width : ${t.pieStrokeWidth};\n opacity : ${t.pieOpacity};\n }\n .pieOuterCircle{\n stroke: ${t.pieOuterStrokeColor};\n stroke-width: ${t.pieOuterStrokeWidth};\n fill: none;\n }\n .pieTitleText {\n text-anchor: middle;\n font-size: ${t.pieTitleTextSize};\n fill: ${t.pieTitleTextColor};\n font-family: ${t.fontFamily};\n }\n .slice {\n font-family: ${t.fontFamily};\n fill: ${t.pieSectionTextColor};\n font-size:${t.pieSectionTextSize};\n // fill: white;\n }\n .legend text {\n fill: ${t.pieLegendTextColor};\n font-family: ${t.fontFamily};\n font-size: ${t.pieLegendTextSize};\n }\n`;let j,P=e();const N={parser:D,db:I,renderer:{draw:(i,n,r,s)=>{var a,c;try{P=e(),h.debug("Rendering info diagram\n"+i);const r=e().securityLevel;let I;"sandbox"===r&&(I=p("#i"+n));const O=p("sandbox"===r?I.nodes()[0].contentDocument.body:"body"),N="sandbox"===r?I.nodes()[0].contentDocument:document;s.db.clear(),s.parser.parse(i),h.debug("Parsed info diagram");const L=N.getElementById(n);j=L.parentElement.offsetWidth,void 0===j&&(j=1200),void 0!==P.useWidth&&(j=P.useWidth),void 0!==P.pie.useWidth&&(j=P.pie.useWidth);const W=O.select("#"+n);y(W,450,j,P.pie.useMaxWidth),L.setAttribute("viewBox","0 0 "+j+" 450");var o=18,l=Math.min(j,450)/2-40,u=W.append("g").attr("transform","translate("+j/2+",225)"),f=s.db.getSections(),v=0;Object.keys(f).forEach((function(t){v+=f[t]}));const z=P.themeVariables;var b=[z.pie1,z.pie2,z.pie3,z.pie4,z.pie5,z.pie6,z.pie7,z.pie8,z.pie9,z.pie10,z.pie11,z.pie12];const C=null!=(a=null==(c=P.pie)?void 0:c.textPosition)?a:.75;let[F]=d(z.pieOuterStrokeWidth);null!=F||(F=2);var k=S().range(b),x=Object.entries(f).map((function(t,e){return{order:e,name:t[0],value:t[1]}})),E=function(){var e=A,i=w,n=null,r=_(0),s=_(t),a=_(0);function c(c){var o,l,h,u,p,y=(c=g(c)).length,d=0,f=new Array(y),_=new Array(y),m=+r.apply(this,arguments),v=Math.min(t,Math.max(-t,s.apply(this,arguments)-m)),b=Math.min(Math.abs(v)/y,a.apply(this,arguments)),k=b*(v<0?-1:1);for(o=0;o0&&(d+=p);for(null!=i?f.sort((function(t,e){return i(_[t],_[e])})):null!=n&&f.sort((function(t,e){return n(c[t],c[e])})),o=0,h=d?(v-y*k)/d:0;o0?p*h:0)+k,_[l]={data:c[l],index:o,value:p,startAngle:m,endAngle:u,padAngle:b};return _}return c.value=function(t){return arguments.length?(e="function"==typeof t?t:_(+t),c):e},c.sortValues=function(t){return arguments.length?(i=t,n=null,c):i},c.sort=function(t){return arguments.length?(n=t,i=null,c):n},c.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:_(+t),c):r},c.endAngle=function(t){return arguments.length?(s="function"==typeof t?t:_(+t),c):s},c.padAngle=function(t){return arguments.length?(a="function"==typeof t?t:_(+t),c):a},c}().value((function(t){return t.value})).sort((function(t,e){return t.order-e.order}))(x),D=m().innerRadius(0).outerRadius(l),$=m().innerRadius(l*C).outerRadius(l*C);u.append("circle").attr("cx",0).attr("cy",0).attr("r",l+F/2).attr("class","pieOuterCircle"),u.selectAll("mySlices").data(E).enter().append("path").attr("d",D).attr("fill",(function(t){return k(t.data.name)})).attr("class","pieCircle"),u.selectAll("mySlices").data(E).enter().append("text").text((function(t){return(t.data.value/v*100).toFixed(0)+"%"})).attr("transform",(function(t){return"translate("+$.centroid(t)+")"})).style("text-anchor","middle").attr("class","slice"),u.append("text").text(s.db.getDiagramTitle()).attr("x",0).attr("y",-200).attr("class","pieTitleText");var T=u.selectAll(".legend").data(k.domain()).enter().append("g").attr("class","legend").attr("transform",(function(t,e){return"translate(216,"+(22*e-22*k.domain().length/2)+")"}));T.append("rect").attr("width",o).attr("height",o).style("fill",k).style("stroke",k),T.data(E).append("text").attr("x",22).attr("y",14).text((function(t){return s.db.getShowData()||P.showData||P.pie.showData?t.data.name+" ["+t.data.value+"]":t.data.name}))}catch(I){h.error("Error while rendering info diagram"),h.error(I)}}},styles:O};export{N as diagram}; +import{ao as t,c as e,s as i,g as n,v as r,x as s,a,b as c,m as o,j as l,l as h,z as u,h as p,i as y,ap as d}from"./mermaid.core.3a590193.js";import{i as f}from"./init.0b4a962a.js";import{a as g}from"./array.999c8e45.js";import{c as _}from"./constant.4f073c13.js";import{a as m}from"./arc.8a7dbfa5.js";class v extends Map{constructor(t,e=k){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const[i,n]of t)this.set(i,n)}get(t){return super.get(b(this,t))}has(t){return super.has(b(this,t))}set(t,e){return super.set(function({_intern:t,_key:e},i){const n=e(i);return t.has(n)?t.get(n):(t.set(n,i),i)}(this,t),e)}delete(t){return super.delete(function({_intern:t,_key:e},i){const n=e(i);t.has(n)&&(i=t.get(n),t.delete(n));return i}(this,t))}}function b({_intern:t,_key:e},i){const n=e(i);return t.has(n)?t.get(n):i}function k(t){return null!==t&&"object"==typeof t?t.valueOf():t}const x=Symbol("implicit");function S(){var t=new v,e=[],i=[],n=x;function r(r){let s=t.get(r);if(void 0===s){if(n!==x)return n;t.set(r,s=e.push(r)-1)}return i[s%i.length]}return r.domain=function(i){if(!arguments.length)return e.slice();e=[],t=new v;for(const n of i)t.has(n)||t.set(n,e.push(n)-1);return r},r.range=function(t){return arguments.length?(i=Array.from(t),r):i.slice()},r.unknown=function(t){return arguments.length?(n=t,r):n},r.copy=function(){return S(e,i).unknown(n)},f.apply(r,arguments),r}function w(t,e){return et?1:e>=t?0:NaN}function A(t){return t}var E=function(){var t=function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i},e=[1,4],i=[1,5],n=[1,6],r=[1,7],s=[1,9],a=[1,11,13,15,17,19,20,26,27,28,29],c=[2,5],o=[1,6,11,13,15,17,19,20,26,27,28,29],l=[26,27,28],h=[2,8],u=[1,18],p=[1,19],y=[1,20],d=[1,21],f=[1,22],g=[1,23],_=[1,28],m=[6,26,27,28,29],v={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,directive:5,PIE:6,document:7,showData:8,line:9,statement: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,openDirective:21,typeDirective:22,closeDirective:23,":":24,argDirective:25,NEWLINE:26,";":27,EOF:28,open_directive:29,type_directive:30,arg_directive:31,close_directive:32,$accept:0,$end:1},terminals_:{2:"error",6:"PIE",8:"showData",11:"txt",12:"value",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",24:":",26:"NEWLINE",27:";",28:"EOF",29:"open_directive",30:"type_directive",31:"arg_directive",32:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,3],[7,0],[7,2],[9,2],[10,0],[10,2],[10,2],[10,2],[10,2],[10,1],[10,1],[10,1],[5,3],[5,5],[4,1],[4,1],[4,1],[21,1],[22,1],[25,1],[23,1]],performAction:function(t,e,i,n,r,s,a){var c=s.length-1;switch(r){case 4:n.setShowData(!0);break;case 7:this.$=s[c-1];break;case 9:n.addSection(s[c-1],n.cleanupValue(s[c]));break;case 10:this.$=s[c].trim(),n.setDiagramTitle(this.$);break;case 11:this.$=s[c].trim(),n.setAccTitle(this.$);break;case 12:case 13:this.$=s[c].trim(),n.setAccDescription(this.$);break;case 14:n.addSection(s[c].substr(8)),this.$=s[c].substr(8);break;case 21:n.parseDirective("%%{","open_directive");break;case 22:n.parseDirective(s[c],"type_directive");break;case 23:s[c]=s[c].trim().replace(/'/g,'"'),n.parseDirective(s[c],"arg_directive");break;case 24:n.parseDirective("}%%","close_directive","pie")}},table:[{3:1,4:2,5:3,6:e,21:8,26:i,27:n,28:r,29:s},{1:[3]},{3:10,4:2,5:3,6:e,21:8,26:i,27:n,28:r,29:s},{3:11,4:2,5:3,6:e,21:8,26:i,27:n,28:r,29:s},t(a,c,{7:12,8:[1,13]}),t(o,[2,18]),t(o,[2,19]),t(o,[2,20]),{22:14,30:[1,15]},{30:[2,21]},{1:[2,1]},{1:[2,2]},t(l,h,{21:8,9:16,10:17,5:24,1:[2,3],11:u,13:p,15:y,17:d,19:f,20:g,29:s}),t(a,c,{7:25}),{23:26,24:[1,27],32:_},t([24,32],[2,22]),t(a,[2,6]),{4:29,26:i,27:n,28:r},{12:[1,30]},{14:[1,31]},{16:[1,32]},{18:[1,33]},t(l,[2,13]),t(l,[2,14]),t(l,[2,15]),t(l,h,{21:8,9:16,10:17,5:24,1:[2,4],11:u,13:p,15:y,17:d,19:f,20:g,29:s}),t(m,[2,16]),{25:34,31:[1,35]},t(m,[2,24]),t(a,[2,7]),t(l,[2,9]),t(l,[2,10]),t(l,[2,11]),t(l,[2,12]),{23:36,32:_},{32:[2,23]},t(m,[2,17])],defaultActions:{9:[2,21],10:[2,1],11:[2,2],35:[2,23]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],n=[],r=[null],s=[],a=this.table,c="",o=0,l=0,h=2,u=1,p=s.slice.call(arguments,1),y=Object.create(this.lexer),d={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(d.yy[f]=this.yy[f]);y.setInput(t,d.yy),d.yy.lexer=y,d.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var g=y.yylloc;s.push(g);var _=y.options&&y.options.ranges;function m(){var t;return"number"!=typeof(t=n.pop()||y.lex()||u)&&(t instanceof Array&&(t=(n=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var v,b,k,x,S,w,A,E,D={};;){if(b=i[i.length-1],this.defaultActions[b]?k=this.defaultActions[b]:(null==v&&(v=m()),k=a[b]&&a[b][v]),void 0===k||!k.length||!k[0]){var $="";for(S in E=[],a[b])this.terminals_[S]&&S>h&&E.push("'"+this.terminals_[S]+"'");$=y.showPosition?"Parse error on line "+(o+1)+":\n"+y.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[v]||v)+"'":"Parse error on line "+(o+1)+": Unexpected "+(v==u?"end of input":"'"+(this.terminals_[v]||v)+"'"),this.parseError($,{text:y.match,token:this.terminals_[v]||v,line:y.yylineno,loc:g,expected:E})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+v);switch(k[0]){case 1:i.push(v),r.push(y.yytext),s.push(y.yylloc),i.push(k[1]),v=null,l=y.yyleng,c=y.yytext,o=y.yylineno,g=y.yylloc;break;case 2:if(w=this.productions_[k[1]][1],D.$=r[r.length-w],D._$={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},_&&(D._$.range=[s[s.length-(w||1)].range[0],s[s.length-1].range[1]]),void 0!==(x=this.performAction.apply(D,[c,l,o,d.yy,k[1],r,s].concat(p))))return x;w&&(i=i.slice(0,-1*w*2),r=r.slice(0,-1*w),s=s.slice(0,-1*w)),i.push(this.productions_[k[1]][0]),r.push(D.$),s.push(D._$),A=a[i[i.length-2]][i[i.length-1]],i.push(A);break;case 3:return!0}}return!0}},b={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,i=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 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),i.length-1&&(this.yylineno-=i.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:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[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(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var i,n,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in r)this[s]=r[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),s=0;se[0].length)){if(e=i,n=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,r[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,n){switch(i){case 0:return this.begin("open_directive"),29;case 1:return this.begin("type_directive"),30;case 2:return this.popState(),this.begin("arg_directive"),24;case 3:return this.popState(),this.popState(),32;case 4:return 31;case 5:case 6:break;case 7:return 26;case 8:case 9:break;case 10:return this.begin("title"),13;case 11:return this.popState(),"title_value";case 12:return this.begin("acc_title"),15;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),17;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:this.begin("string");break;case 20:this.popState();break;case 21:return"txt";case 22:return 6;case 23:return 8;case 24:return"value";case 25:return 28}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:[\s]+)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:pie\b)/i,/^(?:showData\b)/i,/^(?::[\s]*[\d]+(?:\.[\d]+)?)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},title:{rules:[11],inclusive:!1},string:{rules:[20,21],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,12,14,16,19,22,23,24,25],inclusive:!0}}};function k(){this.yy={}}return v.lexer=b,k.prototype=v,v.Parser=k,new k}();E.parser=E;const D=E;let $={},T=!1;const I={parseDirective:function(t,e,i){o.parseDirective(this,t,e,i)},getConfig:()=>e().pie,addSection:function(t,i){t=l.sanitizeText(t,e()),void 0===$[t]&&($[t]=i,h.debug("Added new section :",t))},getSections:()=>$,cleanupValue:function(t){return":"===t.substring(0,1)?(t=t.substring(1).trim(),Number(t.trim())):Number(t.trim())},clear:function(){$={},T=!1,u()},setAccTitle:i,getAccTitle:n,setDiagramTitle:r,getDiagramTitle:s,setShowData:function(t){T=t},getShowData:function(){return T},getAccDescription:a,setAccDescription:c},O=t=>`\n .pieCircle{\n stroke: ${t.pieStrokeColor};\n stroke-width : ${t.pieStrokeWidth};\n opacity : ${t.pieOpacity};\n }\n .pieOuterCircle{\n stroke: ${t.pieOuterStrokeColor};\n stroke-width: ${t.pieOuterStrokeWidth};\n fill: none;\n }\n .pieTitleText {\n text-anchor: middle;\n font-size: ${t.pieTitleTextSize};\n fill: ${t.pieTitleTextColor};\n font-family: ${t.fontFamily};\n }\n .slice {\n font-family: ${t.fontFamily};\n fill: ${t.pieSectionTextColor};\n font-size:${t.pieSectionTextSize};\n // fill: white;\n }\n .legend text {\n fill: ${t.pieLegendTextColor};\n font-family: ${t.fontFamily};\n font-size: ${t.pieLegendTextSize};\n }\n`;let j,P=e();const N={parser:D,db:I,renderer:{draw:(i,n,r,s)=>{var a,c;try{P=e(),h.debug("Rendering info diagram\n"+i);const r=e().securityLevel;let I;"sandbox"===r&&(I=p("#i"+n));const O=p("sandbox"===r?I.nodes()[0].contentDocument.body:"body"),N="sandbox"===r?I.nodes()[0].contentDocument:document;s.db.clear(),s.parser.parse(i),h.debug("Parsed info diagram");const L=N.getElementById(n);j=L.parentElement.offsetWidth,void 0===j&&(j=1200),void 0!==P.useWidth&&(j=P.useWidth),void 0!==P.pie.useWidth&&(j=P.pie.useWidth);const W=O.select("#"+n);y(W,450,j,P.pie.useMaxWidth),L.setAttribute("viewBox","0 0 "+j+" 450");var o=18,l=Math.min(j,450)/2-40,u=W.append("g").attr("transform","translate("+j/2+",225)"),f=s.db.getSections(),v=0;Object.keys(f).forEach((function(t){v+=f[t]}));const z=P.themeVariables;var b=[z.pie1,z.pie2,z.pie3,z.pie4,z.pie5,z.pie6,z.pie7,z.pie8,z.pie9,z.pie10,z.pie11,z.pie12];const C=null!=(a=null==(c=P.pie)?void 0:c.textPosition)?a:.75;let[F]=d(z.pieOuterStrokeWidth);null!=F||(F=2);var k=S().range(b),x=Object.entries(f).map((function(t,e){return{order:e,name:t[0],value:t[1]}})),E=function(){var e=A,i=w,n=null,r=_(0),s=_(t),a=_(0);function c(c){var o,l,h,u,p,y=(c=g(c)).length,d=0,f=new Array(y),_=new Array(y),m=+r.apply(this,arguments),v=Math.min(t,Math.max(-t,s.apply(this,arguments)-m)),b=Math.min(Math.abs(v)/y,a.apply(this,arguments)),k=b*(v<0?-1:1);for(o=0;o0&&(d+=p);for(null!=i?f.sort((function(t,e){return i(_[t],_[e])})):null!=n&&f.sort((function(t,e){return n(c[t],c[e])})),o=0,h=d?(v-y*k)/d:0;o0?p*h:0)+k,_[l]={data:c[l],index:o,value:p,startAngle:m,endAngle:u,padAngle:b};return _}return c.value=function(t){return arguments.length?(e="function"==typeof t?t:_(+t),c):e},c.sortValues=function(t){return arguments.length?(i=t,n=null,c):i},c.sort=function(t){return arguments.length?(n=t,i=null,c):n},c.startAngle=function(t){return arguments.length?(r="function"==typeof t?t:_(+t),c):r},c.endAngle=function(t){return arguments.length?(s="function"==typeof t?t:_(+t),c):s},c.padAngle=function(t){return arguments.length?(a="function"==typeof t?t:_(+t),c):a},c}().value((function(t){return t.value})).sort((function(t,e){return t.order-e.order}))(x),D=m().innerRadius(0).outerRadius(l),$=m().innerRadius(l*C).outerRadius(l*C);u.append("circle").attr("cx",0).attr("cy",0).attr("r",l+F/2).attr("class","pieOuterCircle"),u.selectAll("mySlices").data(E).enter().append("path").attr("d",D).attr("fill",(function(t){return k(t.data.name)})).attr("class","pieCircle"),u.selectAll("mySlices").data(E).enter().append("text").text((function(t){return(t.data.value/v*100).toFixed(0)+"%"})).attr("transform",(function(t){return"translate("+$.centroid(t)+")"})).style("text-anchor","middle").attr("class","slice"),u.append("text").text(s.db.getDiagramTitle()).attr("x",0).attr("y",-200).attr("class","pieTitleText");var T=u.selectAll(".legend").data(k.domain()).enter().append("g").attr("class","legend").attr("transform",(function(t,e){return"translate(216,"+(22*e-22*k.domain().length/2)+")"}));T.append("rect").attr("width",o).attr("height",o).style("fill",k).style("stroke",k),T.data(E).append("text").attr("x",22).attr("y",14).text((function(t){return s.db.getShowData()||P.showData||P.pie.showData?t.data.name+" ["+t.data.value+"]":t.data.name}))}catch(I){h.error("Error while rendering info diagram"),h.error(I)}}},styles:O};export{N as diagram}; diff --git a/assets/policy.html.a5bb78e3.js b/assets/policy.html.0fdfc457.js similarity index 99% rename from assets/policy.html.a5bb78e3.js rename to assets/policy.html.0fdfc457.js index ef385266e..a4e72277d 100644 --- a/assets/policy.html.a5bb78e3.js +++ b/assets/policy.html.0fdfc457.js @@ -1 +1 @@ -import{d as n}from"./app.755d843f.js";const s={},a=n('

    本地策略

    本地策略,可以设置不同的用户等级和对应的策略设置,比如连接超时设置。Xray 处理的每一个连接都对应一个用户,按照用户的等级(level)应用不同的策略。

    PolicyObject

    PolicyObject 对应配置文件的 policy 项。

    {\n  "policy": {\n    "levels": {\n      "0": {\n        "handshake": 4,\n        "connIdle": 300,\n        "uplinkOnly": 2,\n        "downlinkOnly": 5,\n        "statsUserUplink": false,\n        "statsUserDownlink": false,\n        "bufferSize": 4\n      }\n    },\n    "system": {\n      "statsInboundUplink": false,\n      "statsInboundDownlink": false,\n      "statsOutboundUplink": false,\n      "statsOutboundDownlink": false\n    }\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    level: map{string: LevelPolicyObject}

    一组键值对,每个键是一个字符串形式的数字(JSON 的要求),比如 "0""1" 等,双引号不能省略,此数字对应用户等级。每一个值是一个 LevelPolicyObject.

    提示

    每个入站出站代理现在都可以设置用户等级,Xray 会根据实际的用户等级应用不同的本地策略。

    system: SystemPolicyObject

    Xray 系统级别的策略

    LevelPolicyObject

    {\n  "handshake": 4,\n  "connIdle": 300,\n  "uplinkOnly": 2,\n  "downlinkOnly": 5,\n  "statsUserUplink": false,\n  "statsUserDownlink": false,\n  "bufferSize": 10240\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    handshake: number

    连接建立时的握手时间限制。单位为秒。默认值为 4。在入站代理处理一个新连接时,在握手阶段如果使用的时间超过这个时间,则中断该连接。

    connIdle: number

    连接空闲的时间限制。单位为秒。默认值为 300。inbound/outbound 处理一个连接时,如果在 connIdle 时间内,没有任何数据被传输(包括上行和下行数据),则中断该连接。

    uplinkOnly: number

    当连接下行线路关闭后的时间限制。单位为秒。默认值为 2。当服务器(如远端网站)关闭下行连接时,出站代理会在等待 uplinkOnly 时间后中断连接。

    downlinkOnly: number

    当连接上行线路关闭后的时间限制。单位为秒。默认值为 5。当客户端(如浏览器)关闭上行连接时,入站代理会在等待 downlinkOnly 时间后中断连接。

    提示

    在 HTTP 浏览的场景中,可以将 uplinkOnlydownlinkOnly 设为 0,以提高连接关闭的效率。

    statsUserUplink: true | false

    当值为 true 时,开启当前等级的所有用户的上行流量统计。

    statsUserDownlink: true | false

    当值为 true 时,开启当前等级的所有用户的下行流量统计。

    bufferSize: number

    每个连接的内部缓存大小。单位为 kB。当值为 0 时,内部缓存被禁用。

    默认值:

    • 在 ARM、MIPS、MIPSLE 平台上,默认值为 0
    • 在 ARM64、MIPS64、MIPS64LE 平台上,默认值为 4
    • 在其它平台上,默认值为 512

    SystemPolicyObject

    {\n  "statsInboundUplink": false,\n  "statsInboundDownlink": false,\n  "statsOutboundUplink": false,\n  "statsOutboundDownlink": false\n}\n
    1
    2
    3
    4
    5
    6

    statsInboundUplink: true | false

    当值为 true 时,开启所有入站代理的上行流量统计。

    statsInboundDownlink: true | false

    当值为 true 时,开启所有入站代理的下行流量统计。

    statsOutboundUplink: true | false

    当值为 true 时,开启所有出站代理的上行流量统计。

    statsOutboundDownlink: true | false

    当值为 true 时,开启所有出站代理的下行流量统计。

    ',39);s.render=function(n,s){return a};export default s; +import{d as n}from"./app.48111a85.js";const s={},a=n('

    本地策略

    本地策略,可以设置不同的用户等级和对应的策略设置,比如连接超时设置。Xray 处理的每一个连接都对应一个用户,按照用户的等级(level)应用不同的策略。

    PolicyObject

    PolicyObject 对应配置文件的 policy 项。

    {\n  "policy": {\n    "levels": {\n      "0": {\n        "handshake": 4,\n        "connIdle": 300,\n        "uplinkOnly": 2,\n        "downlinkOnly": 5,\n        "statsUserUplink": false,\n        "statsUserDownlink": false,\n        "bufferSize": 4\n      }\n    },\n    "system": {\n      "statsInboundUplink": false,\n      "statsInboundDownlink": false,\n      "statsOutboundUplink": false,\n      "statsOutboundDownlink": false\n    }\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    level: map{string: LevelPolicyObject}

    一组键值对,每个键是一个字符串形式的数字(JSON 的要求),比如 "0""1" 等,双引号不能省略,此数字对应用户等级。每一个值是一个 LevelPolicyObject.

    提示

    每个入站出站代理现在都可以设置用户等级,Xray 会根据实际的用户等级应用不同的本地策略。

    system: SystemPolicyObject

    Xray 系统级别的策略

    LevelPolicyObject

    {\n  "handshake": 4,\n  "connIdle": 300,\n  "uplinkOnly": 2,\n  "downlinkOnly": 5,\n  "statsUserUplink": false,\n  "statsUserDownlink": false,\n  "bufferSize": 10240\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    handshake: number

    连接建立时的握手时间限制。单位为秒。默认值为 4。在入站代理处理一个新连接时,在握手阶段如果使用的时间超过这个时间,则中断该连接。

    connIdle: number

    连接空闲的时间限制。单位为秒。默认值为 300。inbound/outbound 处理一个连接时,如果在 connIdle 时间内,没有任何数据被传输(包括上行和下行数据),则中断该连接。

    uplinkOnly: number

    当连接下行线路关闭后的时间限制。单位为秒。默认值为 2。当服务器(如远端网站)关闭下行连接时,出站代理会在等待 uplinkOnly 时间后中断连接。

    downlinkOnly: number

    当连接上行线路关闭后的时间限制。单位为秒。默认值为 5。当客户端(如浏览器)关闭上行连接时,入站代理会在等待 downlinkOnly 时间后中断连接。

    提示

    在 HTTP 浏览的场景中,可以将 uplinkOnlydownlinkOnly 设为 0,以提高连接关闭的效率。

    statsUserUplink: true | false

    当值为 true 时,开启当前等级的所有用户的上行流量统计。

    statsUserDownlink: true | false

    当值为 true 时,开启当前等级的所有用户的下行流量统计。

    bufferSize: number

    每个连接的内部缓存大小。单位为 kB。当值为 0 时,内部缓存被禁用。

    默认值:

    • 在 ARM、MIPS、MIPSLE 平台上,默认值为 0
    • 在 ARM64、MIPS64、MIPS64LE 平台上,默认值为 4
    • 在其它平台上,默认值为 512

    SystemPolicyObject

    {\n  "statsInboundUplink": false,\n  "statsInboundDownlink": false,\n  "statsOutboundUplink": false,\n  "statsOutboundDownlink": false\n}\n
    1
    2
    3
    4
    5
    6

    statsInboundUplink: true | false

    当值为 true 时,开启所有入站代理的上行流量统计。

    statsInboundDownlink: true | false

    当值为 true 时,开启所有入站代理的下行流量统计。

    statsOutboundUplink: true | false

    当值为 true 时,开启所有出站代理的上行流量统计。

    statsOutboundDownlink: true | false

    当值为 true 时,开启所有出站代理的下行流量统计。

    ',39);s.render=function(n,s){return a};export default s; diff --git a/assets/policy.html.bb72f124.js b/assets/policy.html.f498427e.js similarity index 99% rename from assets/policy.html.bb72f124.js rename to assets/policy.html.f498427e.js index c41b16494..a445ee7df 100644 --- a/assets/policy.html.bb72f124.js +++ b/assets/policy.html.f498427e.js @@ -1 +1 @@ -import{d as n}from"./app.755d843f.js";const s={},e=n('

    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.

    {\n  "policy": {\n    "levels": {\n      "0": {\n        "handshake": 4,\n        "connIdle": 300,\n        "uplinkOnly": 2,\n        "downlinkOnly": 5,\n        "statsUserUplink": false,\n        "statsUserDownlink": false,\n        "bufferSize": 4\n      }\n    },\n    "system": {\n      "statsInboundUplink": false,\n      "statsInboundDownlink": false,\n      "statsOutboundUplink": false,\n      "statsOutboundDownlink": false\n    }\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    level: map{string: LevelPolicyObject}

    A set of key-value pairs, where each key is a string representation of a number (as required by JSON), such as "0", "1", etc., with the number corresponding to the user level. Each value is a LevelPolicyObject.

    Tip

    Each inbound and outbound proxy can now set the user level, and Xray will apply different local policies based on the actual user level.

    system: SystemPolicyObject

    Xray system-level policy.

    LevelPolicyObject

    {\n  "handshake": 4,\n  "connIdle": 300,\n  "uplinkOnly": 2,\n  "downlinkOnly": 5,\n  "statsUserUplink": false,\n  "statsUserDownlink": false,\n  "bufferSize": 10240\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    handshake: number

    The time limit for handshake during connection establishment. Unit: seconds. Default: 4. When processing a new inbound connection, if the time used in the handshake phase exceeds this limit, the connection will be aborted.

    connIdle: number

    The time limit for connection idle time. Unit: seconds. Default: 300. When processing an inbound/outbound connection, if no data is transferred (including upstream and downstream data) within connIdle time, the connection will be aborted.

    uplinkOnly: number

    The time limit after the downstream connection is closed. Unit: seconds. Default: 2. When the server (such as a remote website) closes the downstream connection, the outbound proxy will abort the connection after waiting for uplinkOnly time.

    downlinkOnly: number

    The time limit after the upstream connection is closed. Unit: seconds. Default: 5. When the client (such as a browser) closes the upstream connection, the inbound proxy will abort the connection after waiting for downlinkOnly time.

    Tip

    In the scenario of HTTP browsing, you can set uplinkOnly and downlinkOnly to 0 to improve the efficiency of connection closing.

    statsUserUplink: true | false

    When set to true, enables upstream traffic statistics for all users at the current level.

    statsUserDownlink: true | false

    When set to true, enables downstream traffic statistics for all users at the current level.

    bufferSize: number

    The internal buffer size of each connection. Unit: kB. When set to 0, the internal buffer is disabled.

    Default values:

    • On ARM, MIPS, and MIPSLE platforms, the default value is 0.
    • On ARM64, MIPS64, and MIPS64LE platforms, the default value is 4.
    • On other platforms, the default value is 512.

    SystemPolicyObject

    {\n  "statsInboundUplink": false,\n  "statsInboundDownlink": false,\n  "statsOutboundUplink": false,\n  "statsOutboundDownlink": false\n}\n
    1
    2
    3
    4
    5
    6

    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.

    ',39);s.render=function(n,s){return e};export default s; +import{d as n}from"./app.48111a85.js";const s={},e=n('

    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.

    {\n  "policy": {\n    "levels": {\n      "0": {\n        "handshake": 4,\n        "connIdle": 300,\n        "uplinkOnly": 2,\n        "downlinkOnly": 5,\n        "statsUserUplink": false,\n        "statsUserDownlink": false,\n        "bufferSize": 4\n      }\n    },\n    "system": {\n      "statsInboundUplink": false,\n      "statsInboundDownlink": false,\n      "statsOutboundUplink": false,\n      "statsOutboundDownlink": false\n    }\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    level: map{string: LevelPolicyObject}

    A set of key-value pairs, where each key is a string representation of a number (as required by JSON), such as "0", "1", etc., with the number corresponding to the user level. Each value is a LevelPolicyObject.

    Tip

    Each inbound and outbound proxy can now set the user level, and Xray will apply different local policies based on the actual user level.

    system: SystemPolicyObject

    Xray system-level policy.

    LevelPolicyObject

    {\n  "handshake": 4,\n  "connIdle": 300,\n  "uplinkOnly": 2,\n  "downlinkOnly": 5,\n  "statsUserUplink": false,\n  "statsUserDownlink": false,\n  "bufferSize": 10240\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    handshake: number

    The time limit for handshake during connection establishment. Unit: seconds. Default: 4. When processing a new inbound connection, if the time used in the handshake phase exceeds this limit, the connection will be aborted.

    connIdle: number

    The time limit for connection idle time. Unit: seconds. Default: 300. When processing an inbound/outbound connection, if no data is transferred (including upstream and downstream data) within connIdle time, the connection will be aborted.

    uplinkOnly: number

    The time limit after the downstream connection is closed. Unit: seconds. Default: 2. When the server (such as a remote website) closes the downstream connection, the outbound proxy will abort the connection after waiting for uplinkOnly time.

    downlinkOnly: number

    The time limit after the upstream connection is closed. Unit: seconds. Default: 5. When the client (such as a browser) closes the upstream connection, the inbound proxy will abort the connection after waiting for downlinkOnly time.

    Tip

    In the scenario of HTTP browsing, you can set uplinkOnly and downlinkOnly to 0 to improve the efficiency of connection closing.

    statsUserUplink: true | false

    When set to true, enables upstream traffic statistics for all users at the current level.

    statsUserDownlink: true | false

    When set to true, enables downstream traffic statistics for all users at the current level.

    bufferSize: number

    The internal buffer size of each connection. Unit: kB. When set to 0, the internal buffer is disabled.

    Default values:

    • On ARM, MIPS, and MIPSLE platforms, the default value is 0.
    • On ARM64, MIPS64, and MIPS64LE platforms, the default value is 4.
    • On other platforms, the default value is 512.

    SystemPolicyObject

    {\n  "statsInboundUplink": false,\n  "statsInboundDownlink": false,\n  "statsOutboundUplink": false,\n  "statsOutboundDownlink": false\n}\n
    1
    2
    3
    4
    5
    6

    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.

    ',39);s.render=function(n,s){return e};export default s; diff --git a/assets/quadrantDiagram-652558cb.73e31ede.js b/assets/quadrantDiagram-652558cb.3bbba2cb.js similarity index 99% rename from assets/quadrantDiagram-652558cb.73e31ede.js rename to assets/quadrantDiagram-652558cb.3bbba2cb.js index 15cdce70e..ba38263e6 100644 --- a/assets/quadrantDiagram-652558cb.73e31ede.js +++ b/assets/quadrantDiagram-652558cb.3bbba2cb.js @@ -1 +1 @@ -var t=Object.defineProperty,i=Object.getOwnPropertySymbols,e=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,n=(i,e,a)=>e in i?t(i,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[e]=a,r=(t,r)=>{for(var s in r||(r={}))e.call(r,s)&&n(t,s,r[s]);if(i)for(var s of i(r))a.call(r,s)&&n(t,s,r[s]);return t};"undefined"!=typeof require&&require;import{aC as s,c as o,aD as l,l as h,s as c,g as d,v as u,x,a as g,b as f,d as p,m as y,z as q,h as T,i as m}from"./mermaid.core.a66200b0.js";import{l as _}from"./linear.98f7ec84.js";import"./init.0b4a962a.js";var b=function(){var t=function(t,i,e,a){for(e=e||{},a=t.length;a--;e[t[a]]=i);return e},i=[1,3],e=[1,5],a=[1,6],n=[1,7],r=[1,8],s=[1,10],o=[1,5,14,16,18,20,21,26,28,29,30,31,32,38,39,40,41,47,48,50,51,52,53,54,55,56,57,58,59,60],l=[1,5,7,14,16,18,20,21,26,28,29,30,31,32,38,39,40,41,47,48,50,51,52,53,54,55,56,57,58,59,60],h=[38,39,40],c=[2,8],d=[1,19],u=[1,23],x=[1,24],g=[1,25],f=[1,26],p=[1,27],y=[1,29],q=[1,30],T=[1,31],m=[1,32],_=[1,33],b=[1,34],A=[1,37],S=[1,38],v=[1,39],k=[1,40],F=[1,41],P=[1,42],L=[1,43],C=[1,44],D=[1,45],z=[1,46],E=[1,47],I=[1,48],w=[1,49],B=[1,52],R=[1,67],W=[1,68],N=[5,23,27,38,39,40,50,51,52,53,54,55,56,57,58,59,60,61],U=[5,7,38,39,40,41],O={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,SPACE:5,directive:6,QUADRANT:7,document:8,line:9,statement:10,axisDetails:11,quadrantDetails:12,points: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:21,text: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,openDirective:33,typeDirective:34,closeDirective:35,":":36,argDirective:37,NEWLINE:38,SEMI:39,EOF:40,open_directive:41,type_directive:42,arg_directive:43,close_directive:44,alphaNumToken:45,textNoTagsToken:46,STR:47,MD_STR:48,alphaNum:49,PUNCTUATION:50,AMP:51,NUM:52,ALPHA:53,COMMA:54,PLUS:55,EQUALS:56,MULT:57,DOT:58,BRKT:59,UNDERSCORE:60,MINUS:61,$accept:0,$end:1},terminals_:{2:"error",5:"SPACE",7:"QUADRANT",14:"title",15:"title_value",16:"acc_title",17:"acc_title_value",18:"acc_descr",19:"acc_descr_value",20:"acc_descr_multiline_value",21:"section",23:"point_start",24:"point_x",25:"point_y",26:"X-AXIS",27:"AXIS-TEXT-DELIMITER",28:"Y-AXIS",29:"QUADRANT_1",30:"QUADRANT_2",31:"QUADRANT_3",32:"QUADRANT_4",36:":",38:"NEWLINE",39:"SEMI",40:"EOF",41:"open_directive",42:"type_directive",43:"arg_directive",44:"close_directive",47:"STR",48:"MD_STR",50:"PUNCTUATION",51:"AMP",52:"NUM",53:"ALPHA",54:"COMMA",55:"PLUS",56:"EQUALS",57:"MULT",58:"DOT",59:"BRKT",60:"UNDERSCORE",61:"MINUS"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[10,0],[10,2],[10,1],[10,1],[10,1],[10,2],[10,2],[10,2],[10,1],[10,1],[10,1],[13,4],[11,4],[11,3],[11,2],[11,4],[11,3],[11,2],[12,2],[12,2],[12,2],[12,2],[6,3],[6,5],[4,1],[4,1],[4,1],[33,1],[34,1],[37,1],[35,1],[22,1],[22,2],[22,1],[22,1],[49,1],[49,2],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[46,1],[46,1],[46,1]],performAction:function(t,i,e,a,n,r,s){var o=r.length-1;switch(n){case 13:this.$=r[o].trim(),a.setDiagramTitle(this.$);break;case 14:this.$=r[o].trim(),a.setAccTitle(this.$);break;case 15:case 16:this.$=r[o].trim(),a.setAccDescription(this.$);break;case 17:a.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 19:a.addPoint(r[o-3],r[o-1],r[o]);break;case 20:a.setXAxisLeftText(r[o-2]),a.setXAxisRightText(r[o]);break;case 21:r[o-1].text+=r[o],a.setXAxisLeftText(r[o-1]);break;case 22:a.setXAxisLeftText(r[o]);break;case 23:a.setYAxisBottomText(r[o-2]),a.setYAxisTopText(r[o]);break;case 24:r[o-1].text+=r[o],a.setYAxisBottomText(r[o-1]);break;case 25:a.setYAxisBottomText(r[o]);break;case 26:a.setQuadrant1Text(r[o]);break;case 27:a.setQuadrant2Text(r[o]);break;case 28:a.setQuadrant3Text(r[o]);break;case 29:a.setQuadrant4Text(r[o]);break;case 35:a.parseDirective("%%{","open_directive");break;case 36:a.parseDirective(r[o],"type_directive");break;case 37:r[o]=r[o].trim().replace(/'/g,'"'),a.parseDirective(r[o],"arg_directive");break;case 38:a.parseDirective("}%%","close_directive","quadrantChart");break;case 39:this.$={text:r[o],type:"text"};break;case 40:this.$={text:r[o-1].text+""+r[o],type:r[o-1].type};break;case 41:this.$={text:r[o],type:"text"};break;case 42:this.$={text:r[o],type:"markdown"};break;case 43:this.$=r[o];break;case 44:this.$=r[o-1]+""+r[o]}},table:[{3:1,4:2,5:i,6:4,7:e,33:9,38:a,39:n,40:r,41:s},{1:[3]},{3:11,4:2,5:i,6:4,7:e,33:9,38:a,39:n,40:r,41:s},{3:12,4:2,5:i,6:4,7:e,33:9,38:a,39:n,40:r,41:s},{3:13,4:2,5:i,6:4,7:e,33:9,38:a,39:n,40:r,41:s},t(o,[2,5],{8:14}),t(l,[2,32]),t(l,[2,33]),t(l,[2,34]),{34:15,42:[1,16]},{42:[2,35]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(h,c,{33:9,9:17,10:18,11:20,12:21,13:22,6:28,22:35,45:36,1:[2,4],5:d,14:u,16:x,18:g,20:f,21:p,26:y,28:q,29:T,30:m,31:_,32:b,41:s,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w}),{35:50,36:[1,51],44:B},t([36,44],[2,36]),t(o,[2,6]),{4:53,38:a,39:n,40:r},t(h,c,{33:9,11:20,12:21,13:22,6:28,22:35,45:36,10:54,5:d,14:u,16:x,18:g,20:f,21:p,26:y,28:q,29:T,30:m,31:_,32:b,41:s,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w}),t(h,[2,10]),t(h,[2,11]),t(h,[2,12]),{15:[1,55]},{17:[1,56]},{19:[1,57]},t(h,[2,16]),t(h,[2,17]),t(h,[2,18]),{22:58,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{22:59,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{22:60,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{22:61,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{22:62,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{22:63,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{5:R,23:[1,64],45:66,46:65,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W},t(N,[2,39]),t(N,[2,41]),t(N,[2,42]),t(N,[2,45]),t(N,[2,46]),t(N,[2,47]),t(N,[2,48]),t(N,[2,49]),t(N,[2,50]),t(N,[2,51]),t(N,[2,52]),t(N,[2,53]),t(N,[2,54]),t(N,[2,55]),t(U,[2,30]),{37:69,43:[1,70]},t(U,[2,38]),t(o,[2,7]),t(h,[2,9]),t(h,[2,13]),t(h,[2,14]),t(h,[2,15]),t(h,[2,22],{46:65,45:66,5:R,27:[1,71],50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,25],{46:65,45:66,5:R,27:[1,72],50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,26],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,27],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,28],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,29],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),{24:[1,73]},t(N,[2,40]),t(N,[2,56]),t(N,[2,57]),t(N,[2,58]),{35:74,44:B},{44:[2,37]},t(h,[2,21],{45:36,22:75,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w}),t(h,[2,24],{45:36,22:76,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w}),{25:[1,77]},t(U,[2,31]),t(h,[2,20],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,23],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,19])],defaultActions:{10:[2,35],11:[2,1],12:[2,2],13:[2,3],70:[2,37]},parseError:function(t,i){if(!i.recoverable){var e=new Error(t);throw e.hash=i,e}this.trace(t)},parse:function(t){var i=this,e=[0],a=[],n=[null],r=[],s=this.table,o="",l=0,h=0,c=2,d=1,u=r.slice.call(arguments,1),x=Object.create(this.lexer),g={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(g.yy[f]=this.yy[f]);x.setInput(t,g.yy),g.yy.lexer=x,g.yy.parser=this,void 0===x.yylloc&&(x.yylloc={});var p=x.yylloc;r.push(p);var y=x.options&&x.options.ranges;function q(){var t;return"number"!=typeof(t=a.pop()||x.lex()||d)&&(t instanceof Array&&(t=(a=t).pop()),t=i.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var T,m,_,b,A,S,v,k,F={};;){if(m=e[e.length-1],this.defaultActions[m]?_=this.defaultActions[m]:(null==T&&(T=q()),_=s[m]&&s[m][T]),void 0===_||!_.length||!_[0]){var P="";for(A in k=[],s[m])this.terminals_[A]&&A>c&&k.push("'"+this.terminals_[A]+"'");P=x.showPosition?"Parse error on line "+(l+1)+":\n"+x.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[T]||T)+"'":"Parse error on line "+(l+1)+": Unexpected "+(T==d?"end of input":"'"+(this.terminals_[T]||T)+"'"),this.parseError(P,{text:x.match,token:this.terminals_[T]||T,line:x.yylineno,loc:p,expected:k})}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+T);switch(_[0]){case 1:e.push(T),n.push(x.yytext),r.push(x.yylloc),e.push(_[1]),T=null,h=x.yyleng,o=x.yytext,l=x.yylineno,p=x.yylloc;break;case 2:if(S=this.productions_[_[1]][1],F.$=n[n.length-S],F._$={first_line:r[r.length-(S||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(S||1)].first_column,last_column:r[r.length-1].last_column},y&&(F._$.range=[r[r.length-(S||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply(F,[o,h,l,g.yy,_[1],n,r].concat(u))))return b;S&&(e=e.slice(0,-1*S*2),n=n.slice(0,-1*S),r=r.slice(0,-1*S)),e.push(this.productions_[_[1]][0]),n.push(F.$),r.push(F._$),v=s[e[e.length-2]][e[e.length-1]],e.push(v);break;case 3:return!0}}return!0}},Q={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,e=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 a=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),e.length-1&&(this.yylineno-=e.length-1);var n=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:e?(e.length===a.length?this.yylloc.first_column:0)+a[a.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+i+"^"},test_match:function(t,i){var e,a,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,e,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;ri[0].length)){if(i=e,a=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,n[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,n[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,e,a){switch(e){case 0:return this.begin("open_directive"),41;case 1:return this.begin("type_directive"),42;case 2:return this.popState(),this.begin("arg_directive"),36;case 3:return this.popState(),this.popState(),44;case 4:return 43;case 5:case 6:break;case 7:return 38;case 8:break;case 9:return this.begin("title"),14;case 10:return this.popState(),"title_value";case 11:return this.begin("acc_title"),16;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),18;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:return 26;case 19:return 28;case 20:return 27;case 21:return 29;case 22:return 30;case 23:return 31;case 24:return 32;case 25:this.begin("md_string");break;case 26:return"MD_STR";case 27:this.popState();break;case 28:this.begin("string");break;case 29:this.popState();break;case 30:return"STR";case 31:return this.begin("point_start"),23;case 32:return this.begin("point_x"),24;case 33:this.popState();break;case 34:this.popState(),this.begin("point_y");break;case 35:return this.popState(),25;case 36:return 7;case 37:return 53;case 38:return"COLON";case 39:return 55;case 40:return 54;case 41:case 42:return 56;case 43:return 57;case 44:return 59;case 45:return 60;case 46:return 58;case 47:return 51;case 48:return 61;case 49:return 52;case 50:return 5;case 51:return 39;case 52:return 50;case 53:return 40}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{point_y:{rules:[35],inclusive:!1},point_x:{rules:[34],inclusive:!1},point_start:{rules:[32,33],inclusive:!1},acc_descr_multiline:{rules:[16,17],inclusive:!1},acc_descr:{rules:[14],inclusive:!1},acc_title:{rules:[12],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},title:{rules:[10],inclusive:!1},md_string:{rules:[26,27],inclusive:!1},string:{rules:[29,30],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,11,13,15,18,19,20,21,22,23,24,25,28,31,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53],inclusive:!0}}};function $(){this.yy={}}return O.lexer=Q,$.prototype=O,O.Parser=$,new $}();b.parser=b;const A=b,S=s();const v=o();function k(t){return p(t.trim(),v)}const F=new class{constructor(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){var t,i,e,a,n,r,s,o,h,c,d,u,x,g,f,p,y,q;return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:(null==(t=l.quadrantChart)?void 0:t.chartWidth)||500,chartWidth:(null==(i=l.quadrantChart)?void 0:i.chartHeight)||500,titlePadding:(null==(e=l.quadrantChart)?void 0:e.titlePadding)||10,titleFontSize:(null==(a=l.quadrantChart)?void 0:a.titleFontSize)||20,quadrantPadding:(null==(n=l.quadrantChart)?void 0:n.quadrantPadding)||5,xAxisLabelPadding:(null==(r=l.quadrantChart)?void 0:r.xAxisLabelPadding)||5,yAxisLabelPadding:(null==(s=l.quadrantChart)?void 0:s.yAxisLabelPadding)||5,xAxisLabelFontSize:(null==(o=l.quadrantChart)?void 0:o.xAxisLabelFontSize)||16,yAxisLabelFontSize:(null==(h=l.quadrantChart)?void 0:h.yAxisLabelFontSize)||16,quadrantLabelFontSize:(null==(c=l.quadrantChart)?void 0:c.quadrantLabelFontSize)||16,quadrantTextTopPadding:(null==(d=l.quadrantChart)?void 0:d.quadrantTextTopPadding)||5,pointTextPadding:(null==(u=l.quadrantChart)?void 0:u.pointTextPadding)||5,pointLabelFontSize:(null==(x=l.quadrantChart)?void 0:x.pointLabelFontSize)||12,pointRadius:(null==(g=l.quadrantChart)?void 0:g.pointRadius)||5,xAxisPosition:(null==(f=l.quadrantChart)?void 0:f.xAxisPosition)||"top",yAxisPosition:(null==(p=l.quadrantChart)?void 0:p.yAxisPosition)||"left",quadrantInternalBorderStrokeWidth:(null==(y=l.quadrantChart)?void 0:y.quadrantInternalBorderStrokeWidth)||1,quadrantExternalBorderStrokeWidth:(null==(q=l.quadrantChart)?void 0:q.quadrantExternalBorderStrokeWidth)||2}}getDefaultThemeConfig(){return{quadrant1Fill:S.quadrant1Fill,quadrant2Fill:S.quadrant2Fill,quadrant3Fill:S.quadrant3Fill,quadrant4Fill:S.quadrant4Fill,quadrant1TextFill:S.quadrant1TextFill,quadrant2TextFill:S.quadrant2TextFill,quadrant3TextFill:S.quadrant3TextFill,quadrant4TextFill:S.quadrant4TextFill,quadrantPointFill:S.quadrantPointFill,quadrantPointTextFill:S.quadrantPointTextFill,quadrantXAxisTextFill:S.quadrantXAxisTextFill,quadrantYAxisTextFill:S.quadrantYAxisTextFill,quadrantTitleFill:S.quadrantTitleFill,quadrantInternalBorderStrokeFill:S.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:S.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),h.info("clear called")}setData(t){this.data=r(r({},this.data),t)}addPoints(t){this.data.points=[...t,...this.data.points]}setConfig(t){h.trace("setConfig called with: ",t),this.config=r(r({},this.config),t)}setThemeConfig(t){h.trace("setThemeConfig called with: ",t),this.themeConfig=r(r({},this.themeConfig),t)}calculateSpace(t,i,e,a){const n=2*this.config.xAxisLabelPadding+this.config.xAxisLabelFontSize,r={top:"top"===t&&i?n:0,bottom:"bottom"===t&&i?n:0},s=2*this.config.yAxisLabelPadding+this.config.yAxisLabelFontSize,o={left:"left"===this.config.yAxisPosition&&e?s:0,right:"right"===this.config.yAxisPosition&&e?s:0},l=this.config.titleFontSize+2*this.config.titlePadding,h={top:a?l:0},c=this.config.quadrantPadding+o.left,d=this.config.quadrantPadding+r.top+h.top,u=this.config.chartWidth-2*this.config.quadrantPadding-o.left-o.right,x=this.config.chartHeight-2*this.config.quadrantPadding-r.top-r.bottom-h.top;return{xAxisSpace:r,yAxisSpace:o,titleSpace:h,quadrantSpace:{quadrantLeft:c,quadrantTop:d,quadrantWidth:u,quadrantHalfWidth:u/2,quadrantHeight:x,quadrantHalfHeight:x/2}}}getAxisLabels(t,i,e,a){const{quadrantSpace:n,titleSpace:r}=a,{quadrantHalfHeight:s,quadrantHeight:o,quadrantLeft:l,quadrantHalfWidth:h,quadrantTop:c,quadrantWidth:d}=n,u=0===this.data.points.length,x=[];return this.data.xAxisLeftText&&i&&x.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:l+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+o+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&i&&x.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:l+h+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+o+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&e&&x.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+l+d+this.config.quadrantPadding,y:c+o-(u?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&e&&x.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+l+d+this.config.quadrantPadding,y:c+s-(u?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:-90}),x}getQuadrants(t){const{quadrantSpace:i}=t,{quadrantHalfHeight:e,quadrantLeft:a,quadrantHalfWidth:n,quadrantTop:r}=i,s=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r,width:n,height:e,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r,width:n,height:e,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant4Fill}];for(const o of s)o.text.x=o.x+o.width/2,0===this.data.points.length?(o.text.y=o.y+o.height/2,o.text.horizontalPos="middle"):(o.text.y=o.y+this.config.quadrantTextTopPadding,o.text.horizontalPos="top");return s}getQuadrantPoints(t){const{quadrantSpace:i}=t,{quadrantHeight:e,quadrantLeft:a,quadrantTop:n,quadrantWidth:r}=i,s=_().domain([0,1]).range([a,r+a]),o=_().domain([0,1]).range([e+n,n]);return this.data.points.map((t=>({x:s(t.x),y:o(t.y),fill:this.themeConfig.quadrantPointFill,radius:this.config.pointRadius,text:{text:t.text,fill:this.themeConfig.quadrantPointTextFill,x:s(t.x),y:o(t.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0}})))}getBorders(t){const i=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:e}=t,{quadrantHalfHeight:a,quadrantHeight:n,quadrantLeft:r,quadrantHalfWidth:s,quadrantTop:o,quadrantWidth:l}=e;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:o,x2:r+l+i,y2:o},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r+l,y1:o+i,x2:r+l,y2:o+n-i},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:o+n,x2:r+l+i,y2:o+n},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r,y1:o+i,x2:r,y2:o+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+s,y1:o+i,x2:r+s,y2:o+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+i,y1:o+a,x2:r+l-i,y2:o+a}]}getTitle(t){if(t)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){const t=this.config.showXAxis&&!(!this.data.xAxisLeftText&&!this.data.xAxisRightText),i=this.config.showYAxis&&!(!this.data.yAxisTopText&&!this.data.yAxisBottomText),e=this.config.showTitle&&!!this.data.titleText,a=this.data.points.length>0?"bottom":this.config.xAxisPosition,n=this.calculateSpace(a,t,i,e);return{points:this.getQuadrantPoints(n),quadrants:this.getQuadrants(n),axisLabels:this.getAxisLabels(a,t,i,n),borderLines:this.getBorders(n),title:this.getTitle(e)}}};const P={parser:A,db:{setWidth:function(t){F.setConfig({chartWidth:t})},setHeight:function(t){F.setConfig({chartHeight:t})},setQuadrant1Text:function(t){F.setData({quadrant1Text:k(t.text)})},setQuadrant2Text:function(t){F.setData({quadrant2Text:k(t.text)})},setQuadrant3Text:function(t){F.setData({quadrant3Text:k(t.text)})},setQuadrant4Text:function(t){F.setData({quadrant4Text:k(t.text)})},setXAxisLeftText:function(t){F.setData({xAxisLeftText:k(t.text)})},setXAxisRightText:function(t){F.setData({xAxisRightText:k(t.text)})},setYAxisTopText:function(t){F.setData({yAxisTopText:k(t.text)})},setYAxisBottomText:function(t){F.setData({yAxisBottomText:k(t.text)})},addPoint:function(t,i,e){F.addPoints([{x:i,y:e,text:k(t.text)}])},getQuadrantData:function(){const t=o(),{themeVariables:i,quadrantChart:e}=t;return e&&F.setConfig(e),F.setThemeConfig({quadrant1Fill:i.quadrant1Fill,quadrant2Fill:i.quadrant2Fill,quadrant3Fill:i.quadrant3Fill,quadrant4Fill:i.quadrant4Fill,quadrant1TextFill:i.quadrant1TextFill,quadrant2TextFill:i.quadrant2TextFill,quadrant3TextFill:i.quadrant3TextFill,quadrant4TextFill:i.quadrant4TextFill,quadrantPointFill:i.quadrantPointFill,quadrantPointTextFill:i.quadrantPointTextFill,quadrantXAxisTextFill:i.quadrantXAxisTextFill,quadrantYAxisTextFill:i.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:i.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:i.quadrantInternalBorderStrokeFill,quadrantTitleFill:i.quadrantTitleFill}),F.setData({titleText:x()}),F.build()},parseDirective:function(t,i,e){y.parseDirective(this,t,i,e)},clear:function(){F.clear(),q()},setAccTitle:c,getAccTitle:d,setDiagramTitle:u,getDiagramTitle:x,getAccDescription:g,setAccDescription:f},renderer:{draw:(t,i,e,a)=>{var n,r,s;function l(t){return"top"===t?"hanging":"middle"}function c(t){return"left"===t?"start":"middle"}function d(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}const u=o();h.debug("Rendering quadrant chart\n"+t);const x=u.securityLevel;let g;"sandbox"===x&&(g=T("#i"+i));const f=T("sandbox"===x?g.nodes()[0].contentDocument.body:"body").select(`[id="${i}"]`),p=f.append("g").attr("class","main"),y=(null==(n=u.quadrantChart)?void 0:n.chartWidth)||500,q=(null==(r=u.quadrantChart)?void 0:r.chartHeight)||500;m(f,q,y,(null==(s=u.quadrantChart)?void 0:s.useMaxWidth)||!0),f.attr("viewBox","0 0 "+y+" "+q),a.db.setHeight(q),a.db.setWidth(y);const _=a.db.getQuadrantData(),b=p.append("g").attr("class","quadrants"),A=p.append("g").attr("class","border"),S=p.append("g").attr("class","data-points"),v=p.append("g").attr("class","labels"),k=p.append("g").attr("class","title");_.title&&k.append("text").attr("x",0).attr("y",0).attr("fill",_.title.fill).attr("font-size",_.title.fontSize).attr("dominant-baseline",l(_.title.horizontalPos)).attr("text-anchor",c(_.title.verticalPos)).attr("transform",d(_.title)).text(_.title.text),_.borderLines&&A.selectAll("line").data(_.borderLines).enter().append("line").attr("x1",(t=>t.x1)).attr("y1",(t=>t.y1)).attr("x2",(t=>t.x2)).attr("y2",(t=>t.y2)).style("stroke",(t=>t.strokeFill)).style("stroke-width",(t=>t.strokeWidth));const F=b.selectAll("g.quadrant").data(_.quadrants).enter().append("g").attr("class","quadrant");F.append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)),F.append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>l(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text))).text((t=>t.text.text));v.selectAll("g.label").data(_.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text((t=>t.text)).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>l(t.horizontalPos))).attr("text-anchor",(t=>c(t.verticalPos))).attr("transform",(t=>d(t)));const P=S.selectAll("g.data-point").data(_.points).enter().append("g").attr("class","data-point");P.append("circle").attr("cx",(t=>t.x)).attr("cy",(t=>t.y)).attr("r",(t=>t.radius)).attr("fill",(t=>t.fill)),P.append("text").attr("x",0).attr("y",0).text((t=>t.text.text)).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>l(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text)))}},styles:()=>""};export{P as diagram}; +var t=Object.defineProperty,i=Object.getOwnPropertySymbols,e=Object.prototype.hasOwnProperty,a=Object.prototype.propertyIsEnumerable,n=(i,e,a)=>e in i?t(i,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[e]=a,r=(t,r)=>{for(var s in r||(r={}))e.call(r,s)&&n(t,s,r[s]);if(i)for(var s of i(r))a.call(r,s)&&n(t,s,r[s]);return t};"undefined"!=typeof require&&require;import{aC as s,c as o,aD as l,l as h,s as c,g as d,v as u,x,a as g,b as f,d as p,m as y,z as q,h as T,i as m}from"./mermaid.core.3a590193.js";import{l as _}from"./linear.98f7ec84.js";import"./init.0b4a962a.js";var b=function(){var t=function(t,i,e,a){for(e=e||{},a=t.length;a--;e[t[a]]=i);return e},i=[1,3],e=[1,5],a=[1,6],n=[1,7],r=[1,8],s=[1,10],o=[1,5,14,16,18,20,21,26,28,29,30,31,32,38,39,40,41,47,48,50,51,52,53,54,55,56,57,58,59,60],l=[1,5,7,14,16,18,20,21,26,28,29,30,31,32,38,39,40,41,47,48,50,51,52,53,54,55,56,57,58,59,60],h=[38,39,40],c=[2,8],d=[1,19],u=[1,23],x=[1,24],g=[1,25],f=[1,26],p=[1,27],y=[1,29],q=[1,30],T=[1,31],m=[1,32],_=[1,33],b=[1,34],A=[1,37],S=[1,38],v=[1,39],k=[1,40],F=[1,41],P=[1,42],L=[1,43],C=[1,44],D=[1,45],z=[1,46],E=[1,47],I=[1,48],w=[1,49],B=[1,52],R=[1,67],W=[1,68],N=[5,23,27,38,39,40,50,51,52,53,54,55,56,57,58,59,60,61],U=[5,7,38,39,40,41],O={trace:function(){},yy:{},symbols_:{error:2,start:3,eol:4,SPACE:5,directive:6,QUADRANT:7,document:8,line:9,statement:10,axisDetails:11,quadrantDetails:12,points: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:21,text: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,openDirective:33,typeDirective:34,closeDirective:35,":":36,argDirective:37,NEWLINE:38,SEMI:39,EOF:40,open_directive:41,type_directive:42,arg_directive:43,close_directive:44,alphaNumToken:45,textNoTagsToken:46,STR:47,MD_STR:48,alphaNum:49,PUNCTUATION:50,AMP:51,NUM:52,ALPHA:53,COMMA:54,PLUS:55,EQUALS:56,MULT:57,DOT:58,BRKT:59,UNDERSCORE:60,MINUS:61,$accept:0,$end:1},terminals_:{2:"error",5:"SPACE",7:"QUADRANT",14:"title",15:"title_value",16:"acc_title",17:"acc_title_value",18:"acc_descr",19:"acc_descr_value",20:"acc_descr_multiline_value",21:"section",23:"point_start",24:"point_x",25:"point_y",26:"X-AXIS",27:"AXIS-TEXT-DELIMITER",28:"Y-AXIS",29:"QUADRANT_1",30:"QUADRANT_2",31:"QUADRANT_3",32:"QUADRANT_4",36:":",38:"NEWLINE",39:"SEMI",40:"EOF",41:"open_directive",42:"type_directive",43:"arg_directive",44:"close_directive",47:"STR",48:"MD_STR",50:"PUNCTUATION",51:"AMP",52:"NUM",53:"ALPHA",54:"COMMA",55:"PLUS",56:"EQUALS",57:"MULT",58:"DOT",59:"BRKT",60:"UNDERSCORE",61:"MINUS"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[10,0],[10,2],[10,1],[10,1],[10,1],[10,2],[10,2],[10,2],[10,1],[10,1],[10,1],[13,4],[11,4],[11,3],[11,2],[11,4],[11,3],[11,2],[12,2],[12,2],[12,2],[12,2],[6,3],[6,5],[4,1],[4,1],[4,1],[33,1],[34,1],[37,1],[35,1],[22,1],[22,2],[22,1],[22,1],[49,1],[49,2],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[45,1],[46,1],[46,1],[46,1]],performAction:function(t,i,e,a,n,r,s){var o=r.length-1;switch(n){case 13:this.$=r[o].trim(),a.setDiagramTitle(this.$);break;case 14:this.$=r[o].trim(),a.setAccTitle(this.$);break;case 15:case 16:this.$=r[o].trim(),a.setAccDescription(this.$);break;case 17:a.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 19:a.addPoint(r[o-3],r[o-1],r[o]);break;case 20:a.setXAxisLeftText(r[o-2]),a.setXAxisRightText(r[o]);break;case 21:r[o-1].text+=r[o],a.setXAxisLeftText(r[o-1]);break;case 22:a.setXAxisLeftText(r[o]);break;case 23:a.setYAxisBottomText(r[o-2]),a.setYAxisTopText(r[o]);break;case 24:r[o-1].text+=r[o],a.setYAxisBottomText(r[o-1]);break;case 25:a.setYAxisBottomText(r[o]);break;case 26:a.setQuadrant1Text(r[o]);break;case 27:a.setQuadrant2Text(r[o]);break;case 28:a.setQuadrant3Text(r[o]);break;case 29:a.setQuadrant4Text(r[o]);break;case 35:a.parseDirective("%%{","open_directive");break;case 36:a.parseDirective(r[o],"type_directive");break;case 37:r[o]=r[o].trim().replace(/'/g,'"'),a.parseDirective(r[o],"arg_directive");break;case 38:a.parseDirective("}%%","close_directive","quadrantChart");break;case 39:this.$={text:r[o],type:"text"};break;case 40:this.$={text:r[o-1].text+""+r[o],type:r[o-1].type};break;case 41:this.$={text:r[o],type:"text"};break;case 42:this.$={text:r[o],type:"markdown"};break;case 43:this.$=r[o];break;case 44:this.$=r[o-1]+""+r[o]}},table:[{3:1,4:2,5:i,6:4,7:e,33:9,38:a,39:n,40:r,41:s},{1:[3]},{3:11,4:2,5:i,6:4,7:e,33:9,38:a,39:n,40:r,41:s},{3:12,4:2,5:i,6:4,7:e,33:9,38:a,39:n,40:r,41:s},{3:13,4:2,5:i,6:4,7:e,33:9,38:a,39:n,40:r,41:s},t(o,[2,5],{8:14}),t(l,[2,32]),t(l,[2,33]),t(l,[2,34]),{34:15,42:[1,16]},{42:[2,35]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(h,c,{33:9,9:17,10:18,11:20,12:21,13:22,6:28,22:35,45:36,1:[2,4],5:d,14:u,16:x,18:g,20:f,21:p,26:y,28:q,29:T,30:m,31:_,32:b,41:s,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w}),{35:50,36:[1,51],44:B},t([36,44],[2,36]),t(o,[2,6]),{4:53,38:a,39:n,40:r},t(h,c,{33:9,11:20,12:21,13:22,6:28,22:35,45:36,10:54,5:d,14:u,16:x,18:g,20:f,21:p,26:y,28:q,29:T,30:m,31:_,32:b,41:s,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w}),t(h,[2,10]),t(h,[2,11]),t(h,[2,12]),{15:[1,55]},{17:[1,56]},{19:[1,57]},t(h,[2,16]),t(h,[2,17]),t(h,[2,18]),{22:58,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{22:59,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{22:60,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{22:61,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{22:62,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{22:63,45:36,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w},{5:R,23:[1,64],45:66,46:65,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W},t(N,[2,39]),t(N,[2,41]),t(N,[2,42]),t(N,[2,45]),t(N,[2,46]),t(N,[2,47]),t(N,[2,48]),t(N,[2,49]),t(N,[2,50]),t(N,[2,51]),t(N,[2,52]),t(N,[2,53]),t(N,[2,54]),t(N,[2,55]),t(U,[2,30]),{37:69,43:[1,70]},t(U,[2,38]),t(o,[2,7]),t(h,[2,9]),t(h,[2,13]),t(h,[2,14]),t(h,[2,15]),t(h,[2,22],{46:65,45:66,5:R,27:[1,71],50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,25],{46:65,45:66,5:R,27:[1,72],50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,26],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,27],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,28],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,29],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),{24:[1,73]},t(N,[2,40]),t(N,[2,56]),t(N,[2,57]),t(N,[2,58]),{35:74,44:B},{44:[2,37]},t(h,[2,21],{45:36,22:75,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w}),t(h,[2,24],{45:36,22:76,47:A,48:S,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w}),{25:[1,77]},t(U,[2,31]),t(h,[2,20],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,23],{46:65,45:66,5:R,50:v,51:k,52:F,53:P,54:L,55:C,56:D,57:z,58:E,59:I,60:w,61:W}),t(h,[2,19])],defaultActions:{10:[2,35],11:[2,1],12:[2,2],13:[2,3],70:[2,37]},parseError:function(t,i){if(!i.recoverable){var e=new Error(t);throw e.hash=i,e}this.trace(t)},parse:function(t){var i=this,e=[0],a=[],n=[null],r=[],s=this.table,o="",l=0,h=0,c=2,d=1,u=r.slice.call(arguments,1),x=Object.create(this.lexer),g={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(g.yy[f]=this.yy[f]);x.setInput(t,g.yy),g.yy.lexer=x,g.yy.parser=this,void 0===x.yylloc&&(x.yylloc={});var p=x.yylloc;r.push(p);var y=x.options&&x.options.ranges;function q(){var t;return"number"!=typeof(t=a.pop()||x.lex()||d)&&(t instanceof Array&&(t=(a=t).pop()),t=i.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var T,m,_,b,A,S,v,k,F={};;){if(m=e[e.length-1],this.defaultActions[m]?_=this.defaultActions[m]:(null==T&&(T=q()),_=s[m]&&s[m][T]),void 0===_||!_.length||!_[0]){var P="";for(A in k=[],s[m])this.terminals_[A]&&A>c&&k.push("'"+this.terminals_[A]+"'");P=x.showPosition?"Parse error on line "+(l+1)+":\n"+x.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[T]||T)+"'":"Parse error on line "+(l+1)+": Unexpected "+(T==d?"end of input":"'"+(this.terminals_[T]||T)+"'"),this.parseError(P,{text:x.match,token:this.terminals_[T]||T,line:x.yylineno,loc:p,expected:k})}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+T);switch(_[0]){case 1:e.push(T),n.push(x.yytext),r.push(x.yylloc),e.push(_[1]),T=null,h=x.yyleng,o=x.yytext,l=x.yylineno,p=x.yylloc;break;case 2:if(S=this.productions_[_[1]][1],F.$=n[n.length-S],F._$={first_line:r[r.length-(S||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(S||1)].first_column,last_column:r[r.length-1].last_column},y&&(F._$.range=[r[r.length-(S||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply(F,[o,h,l,g.yy,_[1],n,r].concat(u))))return b;S&&(e=e.slice(0,-1*S*2),n=n.slice(0,-1*S),r=r.slice(0,-1*S)),e.push(this.productions_[_[1]][0]),n.push(F.$),r.push(F._$),v=s[e[e.length-2]][e[e.length-1]],e.push(v);break;case 3:return!0}}return!0}},Q={EOF:1,parseError:function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,e=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 a=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),e.length-1&&(this.yylineno-=e.length-1);var n=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:e?(e.length===a.length?this.yylloc.first_column:0)+a[a.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+i+"^"},test_match:function(t,i){var e,a,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,i,e,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;ri[0].length)){if(i=e,a=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,n[r])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,n[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,i,e,a){switch(e){case 0:return this.begin("open_directive"),41;case 1:return this.begin("type_directive"),42;case 2:return this.popState(),this.begin("arg_directive"),36;case 3:return this.popState(),this.popState(),44;case 4:return 43;case 5:case 6:break;case 7:return 38;case 8:break;case 9:return this.begin("title"),14;case 10:return this.popState(),"title_value";case 11:return this.begin("acc_title"),16;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),18;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:return 26;case 19:return 28;case 20:return 27;case 21:return 29;case 22:return 30;case 23:return 31;case 24:return 32;case 25:this.begin("md_string");break;case 26:return"MD_STR";case 27:this.popState();break;case 28:this.begin("string");break;case 29:this.popState();break;case 30:return"STR";case 31:return this.begin("point_start"),23;case 32:return this.begin("point_x"),24;case 33:this.popState();break;case 34:this.popState(),this.begin("point_y");break;case 35:return this.popState(),25;case 36:return 7;case 37:return 53;case 38:return"COLON";case 39:return 55;case 40:return 54;case 41:case 42:return 56;case 43:return 57;case 44:return 59;case 45:return 60;case 46:return 58;case 47:return 51;case 48:return 61;case 49:return 52;case 50:return 5;case 51:return 39;case 52:return 50;case 53:return 40}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{point_y:{rules:[35],inclusive:!1},point_x:{rules:[34],inclusive:!1},point_start:{rules:[32,33],inclusive:!1},acc_descr_multiline:{rules:[16,17],inclusive:!1},acc_descr:{rules:[14],inclusive:!1},acc_title:{rules:[12],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},title:{rules:[10],inclusive:!1},md_string:{rules:[26,27],inclusive:!1},string:{rules:[29,30],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,11,13,15,18,19,20,21,22,23,24,25,28,31,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53],inclusive:!0}}};function $(){this.yy={}}return O.lexer=Q,$.prototype=O,O.Parser=$,new $}();b.parser=b;const A=b,S=s();const v=o();function k(t){return p(t.trim(),v)}const F=new class{constructor(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){var t,i,e,a,n,r,s,o,h,c,d,u,x,g,f,p,y,q;return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:(null==(t=l.quadrantChart)?void 0:t.chartWidth)||500,chartWidth:(null==(i=l.quadrantChart)?void 0:i.chartHeight)||500,titlePadding:(null==(e=l.quadrantChart)?void 0:e.titlePadding)||10,titleFontSize:(null==(a=l.quadrantChart)?void 0:a.titleFontSize)||20,quadrantPadding:(null==(n=l.quadrantChart)?void 0:n.quadrantPadding)||5,xAxisLabelPadding:(null==(r=l.quadrantChart)?void 0:r.xAxisLabelPadding)||5,yAxisLabelPadding:(null==(s=l.quadrantChart)?void 0:s.yAxisLabelPadding)||5,xAxisLabelFontSize:(null==(o=l.quadrantChart)?void 0:o.xAxisLabelFontSize)||16,yAxisLabelFontSize:(null==(h=l.quadrantChart)?void 0:h.yAxisLabelFontSize)||16,quadrantLabelFontSize:(null==(c=l.quadrantChart)?void 0:c.quadrantLabelFontSize)||16,quadrantTextTopPadding:(null==(d=l.quadrantChart)?void 0:d.quadrantTextTopPadding)||5,pointTextPadding:(null==(u=l.quadrantChart)?void 0:u.pointTextPadding)||5,pointLabelFontSize:(null==(x=l.quadrantChart)?void 0:x.pointLabelFontSize)||12,pointRadius:(null==(g=l.quadrantChart)?void 0:g.pointRadius)||5,xAxisPosition:(null==(f=l.quadrantChart)?void 0:f.xAxisPosition)||"top",yAxisPosition:(null==(p=l.quadrantChart)?void 0:p.yAxisPosition)||"left",quadrantInternalBorderStrokeWidth:(null==(y=l.quadrantChart)?void 0:y.quadrantInternalBorderStrokeWidth)||1,quadrantExternalBorderStrokeWidth:(null==(q=l.quadrantChart)?void 0:q.quadrantExternalBorderStrokeWidth)||2}}getDefaultThemeConfig(){return{quadrant1Fill:S.quadrant1Fill,quadrant2Fill:S.quadrant2Fill,quadrant3Fill:S.quadrant3Fill,quadrant4Fill:S.quadrant4Fill,quadrant1TextFill:S.quadrant1TextFill,quadrant2TextFill:S.quadrant2TextFill,quadrant3TextFill:S.quadrant3TextFill,quadrant4TextFill:S.quadrant4TextFill,quadrantPointFill:S.quadrantPointFill,quadrantPointTextFill:S.quadrantPointTextFill,quadrantXAxisTextFill:S.quadrantXAxisTextFill,quadrantYAxisTextFill:S.quadrantYAxisTextFill,quadrantTitleFill:S.quadrantTitleFill,quadrantInternalBorderStrokeFill:S.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:S.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),h.info("clear called")}setData(t){this.data=r(r({},this.data),t)}addPoints(t){this.data.points=[...t,...this.data.points]}setConfig(t){h.trace("setConfig called with: ",t),this.config=r(r({},this.config),t)}setThemeConfig(t){h.trace("setThemeConfig called with: ",t),this.themeConfig=r(r({},this.themeConfig),t)}calculateSpace(t,i,e,a){const n=2*this.config.xAxisLabelPadding+this.config.xAxisLabelFontSize,r={top:"top"===t&&i?n:0,bottom:"bottom"===t&&i?n:0},s=2*this.config.yAxisLabelPadding+this.config.yAxisLabelFontSize,o={left:"left"===this.config.yAxisPosition&&e?s:0,right:"right"===this.config.yAxisPosition&&e?s:0},l=this.config.titleFontSize+2*this.config.titlePadding,h={top:a?l:0},c=this.config.quadrantPadding+o.left,d=this.config.quadrantPadding+r.top+h.top,u=this.config.chartWidth-2*this.config.quadrantPadding-o.left-o.right,x=this.config.chartHeight-2*this.config.quadrantPadding-r.top-r.bottom-h.top;return{xAxisSpace:r,yAxisSpace:o,titleSpace:h,quadrantSpace:{quadrantLeft:c,quadrantTop:d,quadrantWidth:u,quadrantHalfWidth:u/2,quadrantHeight:x,quadrantHalfHeight:x/2}}}getAxisLabels(t,i,e,a){const{quadrantSpace:n,titleSpace:r}=a,{quadrantHalfHeight:s,quadrantHeight:o,quadrantLeft:l,quadrantHalfWidth:h,quadrantTop:c,quadrantWidth:d}=n,u=0===this.data.points.length,x=[];return this.data.xAxisLeftText&&i&&x.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:l+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+o+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&i&&x.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:l+h+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+r.top:this.config.xAxisLabelPadding+c+o+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&e&&x.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+l+d+this.config.quadrantPadding,y:c+o-(u?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&e&&x.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+l+d+this.config.quadrantPadding,y:c+s-(u?s/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:-90}),x}getQuadrants(t){const{quadrantSpace:i}=t,{quadrantHalfHeight:e,quadrantLeft:a,quadrantHalfWidth:n,quadrantTop:r}=i,s=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r,width:n,height:e,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r,width:n,height:e,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:r+e,width:n,height:e,fill:this.themeConfig.quadrant4Fill}];for(const o of s)o.text.x=o.x+o.width/2,0===this.data.points.length?(o.text.y=o.y+o.height/2,o.text.horizontalPos="middle"):(o.text.y=o.y+this.config.quadrantTextTopPadding,o.text.horizontalPos="top");return s}getQuadrantPoints(t){const{quadrantSpace:i}=t,{quadrantHeight:e,quadrantLeft:a,quadrantTop:n,quadrantWidth:r}=i,s=_().domain([0,1]).range([a,r+a]),o=_().domain([0,1]).range([e+n,n]);return this.data.points.map((t=>({x:s(t.x),y:o(t.y),fill:this.themeConfig.quadrantPointFill,radius:this.config.pointRadius,text:{text:t.text,fill:this.themeConfig.quadrantPointTextFill,x:s(t.x),y:o(t.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0}})))}getBorders(t){const i=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:e}=t,{quadrantHalfHeight:a,quadrantHeight:n,quadrantLeft:r,quadrantHalfWidth:s,quadrantTop:o,quadrantWidth:l}=e;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:o,x2:r+l+i,y2:o},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r+l,y1:o+i,x2:r+l,y2:o+n-i},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r-i,y1:o+n,x2:r+l+i,y2:o+n},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:r,y1:o+i,x2:r,y2:o+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+s,y1:o+i,x2:r+s,y2:o+n-i},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:r+i,y1:o+a,x2:r+l-i,y2:o+a}]}getTitle(t){if(t)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){const t=this.config.showXAxis&&!(!this.data.xAxisLeftText&&!this.data.xAxisRightText),i=this.config.showYAxis&&!(!this.data.yAxisTopText&&!this.data.yAxisBottomText),e=this.config.showTitle&&!!this.data.titleText,a=this.data.points.length>0?"bottom":this.config.xAxisPosition,n=this.calculateSpace(a,t,i,e);return{points:this.getQuadrantPoints(n),quadrants:this.getQuadrants(n),axisLabels:this.getAxisLabels(a,t,i,n),borderLines:this.getBorders(n),title:this.getTitle(e)}}};const P={parser:A,db:{setWidth:function(t){F.setConfig({chartWidth:t})},setHeight:function(t){F.setConfig({chartHeight:t})},setQuadrant1Text:function(t){F.setData({quadrant1Text:k(t.text)})},setQuadrant2Text:function(t){F.setData({quadrant2Text:k(t.text)})},setQuadrant3Text:function(t){F.setData({quadrant3Text:k(t.text)})},setQuadrant4Text:function(t){F.setData({quadrant4Text:k(t.text)})},setXAxisLeftText:function(t){F.setData({xAxisLeftText:k(t.text)})},setXAxisRightText:function(t){F.setData({xAxisRightText:k(t.text)})},setYAxisTopText:function(t){F.setData({yAxisTopText:k(t.text)})},setYAxisBottomText:function(t){F.setData({yAxisBottomText:k(t.text)})},addPoint:function(t,i,e){F.addPoints([{x:i,y:e,text:k(t.text)}])},getQuadrantData:function(){const t=o(),{themeVariables:i,quadrantChart:e}=t;return e&&F.setConfig(e),F.setThemeConfig({quadrant1Fill:i.quadrant1Fill,quadrant2Fill:i.quadrant2Fill,quadrant3Fill:i.quadrant3Fill,quadrant4Fill:i.quadrant4Fill,quadrant1TextFill:i.quadrant1TextFill,quadrant2TextFill:i.quadrant2TextFill,quadrant3TextFill:i.quadrant3TextFill,quadrant4TextFill:i.quadrant4TextFill,quadrantPointFill:i.quadrantPointFill,quadrantPointTextFill:i.quadrantPointTextFill,quadrantXAxisTextFill:i.quadrantXAxisTextFill,quadrantYAxisTextFill:i.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:i.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:i.quadrantInternalBorderStrokeFill,quadrantTitleFill:i.quadrantTitleFill}),F.setData({titleText:x()}),F.build()},parseDirective:function(t,i,e){y.parseDirective(this,t,i,e)},clear:function(){F.clear(),q()},setAccTitle:c,getAccTitle:d,setDiagramTitle:u,getDiagramTitle:x,getAccDescription:g,setAccDescription:f},renderer:{draw:(t,i,e,a)=>{var n,r,s;function l(t){return"top"===t?"hanging":"middle"}function c(t){return"left"===t?"start":"middle"}function d(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}const u=o();h.debug("Rendering quadrant chart\n"+t);const x=u.securityLevel;let g;"sandbox"===x&&(g=T("#i"+i));const f=T("sandbox"===x?g.nodes()[0].contentDocument.body:"body").select(`[id="${i}"]`),p=f.append("g").attr("class","main"),y=(null==(n=u.quadrantChart)?void 0:n.chartWidth)||500,q=(null==(r=u.quadrantChart)?void 0:r.chartHeight)||500;m(f,q,y,(null==(s=u.quadrantChart)?void 0:s.useMaxWidth)||!0),f.attr("viewBox","0 0 "+y+" "+q),a.db.setHeight(q),a.db.setWidth(y);const _=a.db.getQuadrantData(),b=p.append("g").attr("class","quadrants"),A=p.append("g").attr("class","border"),S=p.append("g").attr("class","data-points"),v=p.append("g").attr("class","labels"),k=p.append("g").attr("class","title");_.title&&k.append("text").attr("x",0).attr("y",0).attr("fill",_.title.fill).attr("font-size",_.title.fontSize).attr("dominant-baseline",l(_.title.horizontalPos)).attr("text-anchor",c(_.title.verticalPos)).attr("transform",d(_.title)).text(_.title.text),_.borderLines&&A.selectAll("line").data(_.borderLines).enter().append("line").attr("x1",(t=>t.x1)).attr("y1",(t=>t.y1)).attr("x2",(t=>t.x2)).attr("y2",(t=>t.y2)).style("stroke",(t=>t.strokeFill)).style("stroke-width",(t=>t.strokeWidth));const F=b.selectAll("g.quadrant").data(_.quadrants).enter().append("g").attr("class","quadrant");F.append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)),F.append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>l(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text))).text((t=>t.text.text));v.selectAll("g.label").data(_.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text((t=>t.text)).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>l(t.horizontalPos))).attr("text-anchor",(t=>c(t.verticalPos))).attr("transform",(t=>d(t)));const P=S.selectAll("g.data-point").data(_.points).enter().append("g").attr("class","data-point");P.append("circle").attr("cx",(t=>t.x)).attr("cy",(t=>t.y)).attr("r",(t=>t.radius)).attr("fill",(t=>t.fill)),P.append("text").attr("x",0).attr("y",0).text((t=>t.text.text)).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>l(t.text.horizontalPos))).attr("text-anchor",(t=>c(t.text.verticalPos))).attr("transform",(t=>d(t.text)))}},styles:()=>""};export{P as diagram}; diff --git a/assets/quic.html.2a3227f2.js b/assets/quic.html.6ef35d12.js similarity index 98% rename from assets/quic.html.2a3227f2.js rename to assets/quic.html.6ef35d12.js index cf92d4a76..ce7711d95 100644 --- a/assets/quic.html.2a3227f2.js +++ b/assets/quic.html.6ef35d12.js @@ -1 +1 @@ -import{d as n}from"./app.755d843f.js";const e={},s=n('

    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 通讯。

    {\n  "security": "none",\n  "key": "",\n  "header": {\n    "type": "none"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7

    security: "none" | "aes-128-gcm" | "chacha20-poly1305"

    加密方式。

    此加密是对 QUIC 数据包的加密,加密后数据包无法被探测。

    默认值为不加密。

    key: string

    加密时所用的密钥。

    可以是任意字符串。当 security 不为 "none" 时有效。

    header: HeaderObject

    数据包头部伪装设置

    HeaderObject

    {\n  "type": "none"\n}\n
    1
    2
    3

    type: string

    伪装类型,可选的值有:

    • "none":默认值,不进行伪装,发送的数据是没有特征的数据包。
    • "srtp":伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。
    • "utp":伪装成 uTP 数据包,会被识别为 BT 下载数据。
    • "wechat-video":伪装成微信视频通话的数据包。
    • "dtls":伪装成 DTLS 1.2 数据包。
    • "wireguard":伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)

    提示

    当加密和伪装都不启用时,数据包即为原始的 QUIC 数据包,可以与其它的 QUIC 工具对接。 为了避免被探测,建议加密或伪装至少开启一项。

    ',24);e.render=function(n,e){return s};export default e; +import{d as n}from"./app.48111a85.js";const e={},s=n('

    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 通讯。

    {\n  "security": "none",\n  "key": "",\n  "header": {\n    "type": "none"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7

    security: "none" | "aes-128-gcm" | "chacha20-poly1305"

    加密方式。

    此加密是对 QUIC 数据包的加密,加密后数据包无法被探测。

    默认值为不加密。

    key: string

    加密时所用的密钥。

    可以是任意字符串。当 security 不为 "none" 时有效。

    header: HeaderObject

    数据包头部伪装设置

    HeaderObject

    {\n  "type": "none"\n}\n
    1
    2
    3

    type: string

    伪装类型,可选的值有:

    • "none":默认值,不进行伪装,发送的数据是没有特征的数据包。
    • "srtp":伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。
    • "utp":伪装成 uTP 数据包,会被识别为 BT 下载数据。
    • "wechat-video":伪装成微信视频通话的数据包。
    • "dtls":伪装成 DTLS 1.2 数据包。
    • "wireguard":伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)

    提示

    当加密和伪装都不启用时,数据包即为原始的 QUIC 数据包,可以与其它的 QUIC 工具对接。 为了避免被探测,建议加密或伪装至少开启一项。

    ',24);e.render=function(n,e){return s};export default e; diff --git a/assets/quic.html.f2e89cad.js b/assets/quic.html.d388262c.js similarity index 98% rename from assets/quic.html.f2e89cad.js rename to assets/quic.html.d388262c.js index 8d88f8791..67398b9b9 100644 --- a/assets/quic.html.f2e89cad.js +++ b/assets/quic.html.d388262c.js @@ -1 +1 @@ -import{r as e,o as n,c as t,a as o,b as a,w as s,F as i,e as c,d as r}from"./app.755d843f.js";const l={},u=o("h1",{id:"quic",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#quic","aria-hidden":"true"},"#"),c(" QUIC")],-1),p=o("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),d=o("li",null,"Reduced number of roundtrips in handshake phase. (1-RTT or 0-RTT)",-1),b=c("Multiplexing, and no "),h={href:"https://calendar.perfplanet.com/2020/head-of-line-blocking-in-quic-and-http-3-the-details/",target:"_blank",rel:"noopener noreferrer"},f=c("Head-of-Line blocking"),m=c(" problem."),q=o("li",null,"Connection migration, (mainly on the client side) when switching from Wifi to 4G, the connection will not be interrupted.",-1),k=o("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),g=c("Default settings: "),y=o("li",null,"12-byte Connection ID",-1),v=c("Automatically disconnect the connection if no data is transmitted for 30 seconds (which may affect the use of some "),T={href:"https://en.wikipedia.org/wiki/HTTP_persistent_connection",target:"_blank",rel:"noopener noreferrer"},w=c("persistent connections"),j=c(")."),I=o("h2",{id:"quicobject",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#quicobject","aria-hidden":"true"},"#"),c(" QuicObject")],-1),C=o("code",null,"QuicObject",-1),Q=c(" corresponds to the "),x=o("code",null,"quicSettings",-1),O=c(" item in the "),U=c("Transport Protocol"),D=c("."),P={class:"custom-container danger"},L=o("p",{class:"custom-container-title"},"Danger",-1),_=o("p",null,"The configurations of both endpoints must be identical, otherwise the connection will fail.",-1),H=c("QUIC requires TLS to be enabled and if it is not enabled in the "),R=c("Transport Protocol"),S=c(", Xray will issue a self-signed certificate for TLS communication."),W=r('
    {\n  "security": "none",\n  "key": "",\n  "header": {\n    "type": "none"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7

    security: "none" | "aes-128-gcm" | "chacha20-poly1305"

    Encryption method.

    Extra encryption over entire QUIC packet, include the frame head part. Default value is "none" for no encryption. After being encrypted, QUIC packets will not be detected as QUIC but some other unknow traffic.

    The default value is none

    key: string

    Encryption key used for encryption.

    It can be any string and is effective when "security" is not set to "none".

    header: HeaderObject

    Packet header obfuscation settings.

    HeaderObject

    {\n  "type": "none"\n}\n
    1
    2
    3

    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.

    ',16);l.render=function(c,r){const l=e("OutboundLink"),E=e("RouterLink");return n(),t(i,null,[u,p,o("ol",null,[d,o("li",null,[b,o("a",h,[f,a(l)]),m]),q]),k,o("ul",null,[o("li",null,[g,o("ul",null,[y,o("li",null,[v,o("a",T,[w,a(l)]),j])])])]),I,o("p",null,[C,Q,x,O,a(E,{to:"/en/config/transport.html"},{default:s((()=>[U])),_:1}),D]),o("div",P,[L,_,o("p",null,[H,a(E,{to:"/en/config/transport.html"},{default:s((()=>[R])),_:1}),S])]),W],64)};export default l; +import{r as e,o as n,c as t,a as o,b as a,w as s,F as i,e as c,d as r}from"./app.48111a85.js";const l={},u=o("h1",{id:"quic",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#quic","aria-hidden":"true"},"#"),c(" QUIC")],-1),p=o("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),d=o("li",null,"Reduced number of roundtrips in handshake phase. (1-RTT or 0-RTT)",-1),b=c("Multiplexing, and no "),h={href:"https://calendar.perfplanet.com/2020/head-of-line-blocking-in-quic-and-http-3-the-details/",target:"_blank",rel:"noopener noreferrer"},f=c("Head-of-Line blocking"),m=c(" problem."),q=o("li",null,"Connection migration, (mainly on the client side) when switching from Wifi to 4G, the connection will not be interrupted.",-1),k=o("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),g=c("Default settings: "),y=o("li",null,"12-byte Connection ID",-1),v=c("Automatically disconnect the connection if no data is transmitted for 30 seconds (which may affect the use of some "),T={href:"https://en.wikipedia.org/wiki/HTTP_persistent_connection",target:"_blank",rel:"noopener noreferrer"},w=c("persistent connections"),j=c(")."),I=o("h2",{id:"quicobject",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#quicobject","aria-hidden":"true"},"#"),c(" QuicObject")],-1),C=o("code",null,"QuicObject",-1),Q=c(" corresponds to the "),x=o("code",null,"quicSettings",-1),O=c(" item in the "),U=c("Transport Protocol"),D=c("."),P={class:"custom-container danger"},L=o("p",{class:"custom-container-title"},"Danger",-1),_=o("p",null,"The configurations of both endpoints must be identical, otherwise the connection will fail.",-1),H=c("QUIC requires TLS to be enabled and if it is not enabled in the "),R=c("Transport Protocol"),S=c(", Xray will issue a self-signed certificate for TLS communication."),W=r('
    {\n  "security": "none",\n  "key": "",\n  "header": {\n    "type": "none"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7

    security: "none" | "aes-128-gcm" | "chacha20-poly1305"

    Encryption method.

    Extra encryption over entire QUIC packet, include the frame head part. Default value is "none" for no encryption. After being encrypted, QUIC packets will not be detected as QUIC but some other unknow traffic.

    The default value is none

    key: string

    Encryption key used for encryption.

    It can be any string and is effective when "security" is not set to "none".

    header: HeaderObject

    Packet header obfuscation settings.

    HeaderObject

    {\n  "type": "none"\n}\n
    1
    2
    3

    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.

    ',16);l.render=function(c,r){const l=e("OutboundLink"),E=e("RouterLink");return n(),t(i,null,[u,p,o("ol",null,[d,o("li",null,[b,o("a",h,[f,a(l)]),m]),q]),k,o("ul",null,[o("li",null,[g,o("ul",null,[y,o("li",null,[v,o("a",T,[w,a(l)]),j])])])]),I,o("p",null,[C,Q,x,O,a(E,{to:"/en/config/transport.html"},{default:s((()=>[U])),_:1}),D]),o("div",P,[L,_,o("p",null,[H,a(E,{to:"/en/config/transport.html"},{default:s((()=>[R])),_:1}),S])]),W],64)};export default l; diff --git a/assets/redirect.html.8223ec28.js b/assets/redirect.html.18a443c9.js similarity index 99% rename from assets/redirect.html.8223ec28.js rename to assets/redirect.html.18a443c9.js index 1988de771..80af415a3 100644 --- a/assets/redirect.html.8223ec28.js +++ b/assets/redirect.html.18a443c9.js @@ -1 +1 @@ -import{r as n,o as s,c as a,b as e,w as t,F as p,d as l,a as o,e as r}from"./app.755d843f.js";const c={},u=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),i=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Interface"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PrivateKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v4 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v6 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"DNS"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"8.8.8.8"),r("\n"),o("span",{class:"token key attr-name"},"MTU"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"1280"),r("\n"),o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Peer"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PublicKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"::/0"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"0.0.0.0/0"),r("\n"),o("span",{class:"token key attr-name"},"Endpoint"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"ip:port"),r('"')]),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),k=o("p",null,[r("在 "),o("code",null,"[Interface]"),r(" 下添加如下命令:")],-1),b=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token key attr-name"},"Table"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"off"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add fwmark lookup "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 route add default dev <接口名称> table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 route add ::/0 dev <接口名称> table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete table main suppress_prefixlength 0"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br")])],-1),m=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"提示"),o("ul",null,[o("li",null,[r("此命令表示 IPv4 中 fwmark 为 "),o("code",null,""),r(",IPv6 中 fwmark 为"),o("code",null,""),r(",::/0 全局 v6 走 WireGuard")]),o("li",null,"可根据自己需求增删命令,mark 值要与 Xray-core 中设置为相同,table 值自定"),o("li",null,"如果不支持配置文件,可以在系统中修改路由表")])],-1),d=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Interface"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PrivateKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v4 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v6 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"DNS"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"8.8.8.8"),r("\n"),o("span",{class:"token key attr-name"},"MTU"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"1280"),r("\n"),o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Peer"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PublicKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"::/0"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"0.0.0.0/0"),r("\n"),o("span",{class:"token key attr-name"},"Endpoint"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"ip:port"),r('"')]),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),g=o("p",null,[r("在 "),o("code",null,"[Interface]"),r(" 下添加如下命令:")],-1),v=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token key attr-name"},"Table"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"off"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},'ip -4 rule add from "your wg0 v4 address" lookup
    '),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 route add default dev wg0 table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 route add ::/0 dev wg0 table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},'ip -4 rule delete from "your wg0 v4 address" lookup
    '),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete table main suppress_prefixlength 0"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),y=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"提示"),o("ul",null,[o("li",null,[r("此命令表示 IPV4 中来自 "),o("code",null,"your wg0 v4 address"),r(" 地址的走 WireGuard,IPv6 中::/0 全局 v6 走 WireGuard)")]),o("li",null,"可根据自己需求增删命令,实现 v6 分流,也可以与 fwmark 融合"),o("li",null,"如果不支持配置文件,可以在系统中修改路由表")])],-1),x=l('

    保存

    可顺手安装

    apt install openresolv\n
    1

    3、启用 WireGuard 网络接口

    加载内核模块

    modprobe wireguard\n
    1

    检查 WG 模块加载是否正常

    lsmod | grep wireguard\n
    1

    4、Xray-core 配置文件修改

    ',9),h=o("div",{class:"language-json ext-json line-numbers-mode"},[o("pre",{class:"language-json"},[o("code",null,[o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"api"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"services"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"HandlerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"LoggerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"StatsService"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"listen"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"port"'),o("span",{class:"token operator"},":"),r(" "),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"dokodemo-door"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"address"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv6"'),r("\n "),o("span",{class:"token comment"},"//设置默认用户走指定方式”UseIPv6”或者”UseIPv4”"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"streamSettings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"sockopt"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"mark"'),o("span",{class:"token operator"},":"),r(" \n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv6"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//设置fwmark为的用户走指定方式”UseIPv6””UseIPv4”"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blackhole"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"policy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"system"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"statsInboundDownlink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"statsInboundUplink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"routing"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"rules"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'""'),r("\n "),o("span",{class:"token comment"},"//需要之前在inbound中指定好Tag,我这里是api生成的,还可以添加域名等等"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"bittorrent"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"stats"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),r("\n"),o("span",{class:"token punctuation"},"}"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br"),o("span",{class:"line-number"},"14"),o("br"),o("span",{class:"line-number"},"15"),o("br"),o("span",{class:"line-number"},"16"),o("br"),o("span",{class:"line-number"},"17"),o("br"),o("span",{class:"line-number"},"18"),o("br"),o("span",{class:"line-number"},"19"),o("br"),o("span",{class:"line-number"},"20"),o("br"),o("span",{class:"line-number"},"21"),o("br"),o("span",{class:"line-number"},"22"),o("br"),o("span",{class:"line-number"},"23"),o("br"),o("span",{class:"line-number"},"24"),o("br"),o("span",{class:"line-number"},"25"),o("br"),o("span",{class:"line-number"},"26"),o("br"),o("span",{class:"line-number"},"27"),o("br"),o("span",{class:"line-number"},"28"),o("br"),o("span",{class:"line-number"},"29"),o("br"),o("span",{class:"line-number"},"30"),o("br"),o("span",{class:"line-number"},"31"),o("br"),o("span",{class:"line-number"},"32"),o("br"),o("span",{class:"line-number"},"33"),o("br"),o("span",{class:"line-number"},"34"),o("br"),o("span",{class:"line-number"},"35"),o("br"),o("span",{class:"line-number"},"36"),o("br"),o("span",{class:"line-number"},"37"),o("br"),o("span",{class:"line-number"},"38"),o("br"),o("span",{class:"line-number"},"39"),o("br"),o("span",{class:"line-number"},"40"),o("br"),o("span",{class:"line-number"},"41"),o("br"),o("span",{class:"line-number"},"42"),o("br"),o("span",{class:"line-number"},"43"),o("br"),o("span",{class:"line-number"},"44"),o("br"),o("span",{class:"line-number"},"45"),o("br"),o("span",{class:"line-number"},"46"),o("br"),o("span",{class:"line-number"},"47"),o("br"),o("span",{class:"line-number"},"48"),o("br"),o("span",{class:"line-number"},"49"),o("br"),o("span",{class:"line-number"},"50"),o("br"),o("span",{class:"line-number"},"51"),o("br"),o("span",{class:"line-number"},"52"),o("br"),o("span",{class:"line-number"},"53"),o("br"),o("span",{class:"line-number"},"54"),o("br"),o("span",{class:"line-number"},"55"),o("br"),o("span",{class:"line-number"},"56"),o("br"),o("span",{class:"line-number"},"57"),o("br"),o("span",{class:"line-number"},"58"),o("br"),o("span",{class:"line-number"},"59"),o("br"),o("span",{class:"line-number"},"60"),o("br"),o("span",{class:"line-number"},"61"),o("br"),o("span",{class:"line-number"},"62"),o("br"),o("span",{class:"line-number"},"63"),o("br"),o("span",{class:"line-number"},"64"),o("br"),o("span",{class:"line-number"},"65"),o("br"),o("span",{class:"line-number"},"66"),o("br"),o("span",{class:"line-number"},"67"),o("br"),o("span",{class:"line-number"},"68"),o("br"),o("span",{class:"line-number"},"69"),o("br"),o("span",{class:"line-number"},"70"),o("br"),o("span",{class:"line-number"},"71"),o("br"),o("span",{class:"line-number"},"72"),o("br"),o("span",{class:"line-number"},"73"),o("br"),o("span",{class:"line-number"},"74"),o("br"),o("span",{class:"line-number"},"75"),o("br"),o("span",{class:"line-number"},"76"),o("br"),o("span",{class:"line-number"},"77"),o("br"),o("span",{class:"line-number"},"78"),o("br"),o("span",{class:"line-number"},"79"),o("br"),o("span",{class:"line-number"},"80"),o("br"),o("span",{class:"line-number"},"81"),o("br")])],-1),f=o("div",{class:"language-json ext-json line-numbers-mode"},[o("pre",{class:"language-json"},[o("code",null,[o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"api"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"services"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"HandlerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"LoggerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"StatsService"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"listen"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"port"'),o("span",{class:"token operator"},":"),r(" "),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"dokodemo-door"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"address"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv4"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"sendThrough"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"your wg0 v4 address"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv4"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blackhole"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"policy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"system"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"statsInboundDownlink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"statsInboundUplink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"routing"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"rules"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'""'),r("\n "),o("span",{class:"token comment"},"//需要之前在 inbound 中指定好 Tag,我这里是 api 生成的,还可以添加域名等等"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"bittorrent"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"stats"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),r("\n"),o("span",{class:"token punctuation"},"}"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br"),o("span",{class:"line-number"},"14"),o("br"),o("span",{class:"line-number"},"15"),o("br"),o("span",{class:"line-number"},"16"),o("br"),o("span",{class:"line-number"},"17"),o("br"),o("span",{class:"line-number"},"18"),o("br"),o("span",{class:"line-number"},"19"),o("br"),o("span",{class:"line-number"},"20"),o("br"),o("span",{class:"line-number"},"21"),o("br"),o("span",{class:"line-number"},"22"),o("br"),o("span",{class:"line-number"},"23"),o("br"),o("span",{class:"line-number"},"24"),o("br"),o("span",{class:"line-number"},"25"),o("br"),o("span",{class:"line-number"},"26"),o("br"),o("span",{class:"line-number"},"27"),o("br"),o("span",{class:"line-number"},"28"),o("br"),o("span",{class:"line-number"},"29"),o("br"),o("span",{class:"line-number"},"30"),o("br"),o("span",{class:"line-number"},"31"),o("br"),o("span",{class:"line-number"},"32"),o("br"),o("span",{class:"line-number"},"33"),o("br"),o("span",{class:"line-number"},"34"),o("br"),o("span",{class:"line-number"},"35"),o("br"),o("span",{class:"line-number"},"36"),o("br"),o("span",{class:"line-number"},"37"),o("br"),o("span",{class:"line-number"},"38"),o("br"),o("span",{class:"line-number"},"39"),o("br"),o("span",{class:"line-number"},"40"),o("br"),o("span",{class:"line-number"},"41"),o("br"),o("span",{class:"line-number"},"42"),o("br"),o("span",{class:"line-number"},"43"),o("br"),o("span",{class:"line-number"},"44"),o("br"),o("span",{class:"line-number"},"45"),o("br"),o("span",{class:"line-number"},"46"),o("br"),o("span",{class:"line-number"},"47"),o("br"),o("span",{class:"line-number"},"48"),o("br"),o("span",{class:"line-number"},"49"),o("br"),o("span",{class:"line-number"},"50"),o("br"),o("span",{class:"line-number"},"51"),o("br"),o("span",{class:"line-number"},"52"),o("br"),o("span",{class:"line-number"},"53"),o("br"),o("span",{class:"line-number"},"54"),o("br"),o("span",{class:"line-number"},"55"),o("br"),o("span",{class:"line-number"},"56"),o("br"),o("span",{class:"line-number"},"57"),o("br"),o("span",{class:"line-number"},"58"),o("br"),o("span",{class:"line-number"},"59"),o("br"),o("span",{class:"line-number"},"60"),o("br"),o("span",{class:"line-number"},"61"),o("br"),o("span",{class:"line-number"},"62"),o("br"),o("span",{class:"line-number"},"63"),o("br"),o("span",{class:"line-number"},"64"),o("br"),o("span",{class:"line-number"},"65"),o("br"),o("span",{class:"line-number"},"66"),o("br"),o("span",{class:"line-number"},"67"),o("br"),o("span",{class:"line-number"},"68"),o("br"),o("span",{class:"line-number"},"69"),o("br"),o("span",{class:"line-number"},"70"),o("br"),o("span",{class:"line-number"},"71"),o("br"),o("span",{class:"line-number"},"72"),o("br"),o("span",{class:"line-number"},"73"),o("br"),o("span",{class:"line-number"},"74"),o("br"),o("span",{class:"line-number"},"75"),o("br"),o("span",{class:"line-number"},"76"),o("br"),o("span",{class:"line-number"},"77"),o("br"),o("span",{class:"line-number"},"78"),o("br")])],-1),P=l('

    提示

    可以通过修改 "domainStrategy": "UseIPv6"来控制对应用户的访问方式 实测优先级要高于系统本身的 gai.config

    5、系统设置配置

    提示

    需要打开系统的 ip_forward

    6、完成 WireGuard 相关设置

    开启隧道

    wg-quick up wg0\n
    1

    开机自启

    systemctl enable wg-quick@wg0\nsystemctl start wg-quick@wg0\n
    1
    2

    验证 IPv4/IPv6

    自行验证 Google 搜索 myip

    后记

    本文本意是可以避免的多余的流量浪费,将路由和分流的功能交给 Xray 处理。避免了维护路由表的繁琐工作。顺便技术提升 UP。

    感谢

    @Xray-core @V2ray-core @WireGuard @p3terx @w @Hiram @Luminous @Ln @JackChou

    ',14);c.render=function(l,o){const r=n("Tab"),c=n("Tabs");return s(),a(p,null,[u,e(c,{title:"if-config"},{default:t((()=>[e(r,{title:"fwmark1"},{default:t((()=>[i,k,b,m])),_:1}),e(r,{title:"sendThrough1"},{default:t((()=>[d,g,v,y])),_:1})])),_:1}),x,e(c,{title:"xray-config"},{default:t((()=>[e(r,{title:"fwmark2"},{default:t((()=>[h])),_:1}),e(r,{title:"sendThrough2"},{default:t((()=>[f])),_:1})])),_:1}),P],64)};export default c; +import{r as n,o as s,c as a,b as e,w as t,F as p,d as l,a as o,e as r}from"./app.48111a85.js";const c={},u=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),i=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Interface"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PrivateKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v4 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v6 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"DNS"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"8.8.8.8"),r("\n"),o("span",{class:"token key attr-name"},"MTU"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"1280"),r("\n"),o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Peer"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PublicKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"::/0"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"0.0.0.0/0"),r("\n"),o("span",{class:"token key attr-name"},"Endpoint"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"ip:port"),r('"')]),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),k=o("p",null,[r("在 "),o("code",null,"[Interface]"),r(" 下添加如下命令:")],-1),b=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token key attr-name"},"Table"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"off"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 route add default dev <接口名称> table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 route add ::/0 dev <接口名称> table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete table main suppress_prefixlength 0"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br")])],-1),m=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"提示"),o("ul",null,[o("li",null,[r("此命令表示 IPv4 中 fwmark 为 "),o("code",null,""),r(",IPv6 中 fwmark 为"),o("code",null,""),r(",::/0 全局 v6 走 WireGuard")]),o("li",null,"可根据自己需求增删命令,mark 值要与 Xray-core 中设置为相同,table 值自定"),o("li",null,"如果不支持配置文件,可以在系统中修改路由表")])],-1),d=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Interface"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PrivateKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v4 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v6 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"DNS"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"8.8.8.8"),r("\n"),o("span",{class:"token key attr-name"},"MTU"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"1280"),r("\n"),o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Peer"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PublicKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"::/0"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"0.0.0.0/0"),r("\n"),o("span",{class:"token key attr-name"},"Endpoint"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"ip:port"),r('"')]),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),g=o("p",null,[r("在 "),o("code",null,"[Interface]"),r(" 下添加如下命令:")],-1),v=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token key attr-name"},"Table"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"off"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},'ip -4 rule add from "your wg0 v4 address" lookup
    '),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 route add default dev wg0 table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 route add ::/0 dev wg0 table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},'ip -4 rule delete from "your wg0 v4 address" lookup
    '),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete table main suppress_prefixlength 0"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),y=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"提示"),o("ul",null,[o("li",null,[r("此命令表示 IPV4 中来自 "),o("code",null,"your wg0 v4 address"),r(" 地址的走 WireGuard,IPv6 中::/0 全局 v6 走 WireGuard)")]),o("li",null,"可根据自己需求增删命令,实现 v6 分流,也可以与 fwmark 融合"),o("li",null,"如果不支持配置文件,可以在系统中修改路由表")])],-1),x=l('

    保存

    可顺手安装

    apt install openresolv\n
    1

    3、启用 WireGuard 网络接口

    加载内核模块

    modprobe wireguard\n
    1

    检查 WG 模块加载是否正常

    lsmod | grep wireguard\n
    1

    4、Xray-core 配置文件修改

    ',9),h=o("div",{class:"language-json ext-json line-numbers-mode"},[o("pre",{class:"language-json"},[o("code",null,[o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"api"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"services"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"HandlerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"LoggerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"StatsService"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"listen"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"port"'),o("span",{class:"token operator"},":"),r(" "),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"dokodemo-door"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"address"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv6"'),r("\n "),o("span",{class:"token comment"},"//设置默认用户走指定方式”UseIPv6”或者”UseIPv4”"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"streamSettings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"sockopt"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"mark"'),o("span",{class:"token operator"},":"),r(" \n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv6"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//设置fwmark为的用户走指定方式”UseIPv6””UseIPv4”"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blackhole"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"policy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"system"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"statsInboundDownlink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"statsInboundUplink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"routing"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"rules"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'""'),r("\n "),o("span",{class:"token comment"},"//需要之前在inbound中指定好Tag,我这里是api生成的,还可以添加域名等等"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"bittorrent"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"stats"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),r("\n"),o("span",{class:"token punctuation"},"}"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br"),o("span",{class:"line-number"},"14"),o("br"),o("span",{class:"line-number"},"15"),o("br"),o("span",{class:"line-number"},"16"),o("br"),o("span",{class:"line-number"},"17"),o("br"),o("span",{class:"line-number"},"18"),o("br"),o("span",{class:"line-number"},"19"),o("br"),o("span",{class:"line-number"},"20"),o("br"),o("span",{class:"line-number"},"21"),o("br"),o("span",{class:"line-number"},"22"),o("br"),o("span",{class:"line-number"},"23"),o("br"),o("span",{class:"line-number"},"24"),o("br"),o("span",{class:"line-number"},"25"),o("br"),o("span",{class:"line-number"},"26"),o("br"),o("span",{class:"line-number"},"27"),o("br"),o("span",{class:"line-number"},"28"),o("br"),o("span",{class:"line-number"},"29"),o("br"),o("span",{class:"line-number"},"30"),o("br"),o("span",{class:"line-number"},"31"),o("br"),o("span",{class:"line-number"},"32"),o("br"),o("span",{class:"line-number"},"33"),o("br"),o("span",{class:"line-number"},"34"),o("br"),o("span",{class:"line-number"},"35"),o("br"),o("span",{class:"line-number"},"36"),o("br"),o("span",{class:"line-number"},"37"),o("br"),o("span",{class:"line-number"},"38"),o("br"),o("span",{class:"line-number"},"39"),o("br"),o("span",{class:"line-number"},"40"),o("br"),o("span",{class:"line-number"},"41"),o("br"),o("span",{class:"line-number"},"42"),o("br"),o("span",{class:"line-number"},"43"),o("br"),o("span",{class:"line-number"},"44"),o("br"),o("span",{class:"line-number"},"45"),o("br"),o("span",{class:"line-number"},"46"),o("br"),o("span",{class:"line-number"},"47"),o("br"),o("span",{class:"line-number"},"48"),o("br"),o("span",{class:"line-number"},"49"),o("br"),o("span",{class:"line-number"},"50"),o("br"),o("span",{class:"line-number"},"51"),o("br"),o("span",{class:"line-number"},"52"),o("br"),o("span",{class:"line-number"},"53"),o("br"),o("span",{class:"line-number"},"54"),o("br"),o("span",{class:"line-number"},"55"),o("br"),o("span",{class:"line-number"},"56"),o("br"),o("span",{class:"line-number"},"57"),o("br"),o("span",{class:"line-number"},"58"),o("br"),o("span",{class:"line-number"},"59"),o("br"),o("span",{class:"line-number"},"60"),o("br"),o("span",{class:"line-number"},"61"),o("br"),o("span",{class:"line-number"},"62"),o("br"),o("span",{class:"line-number"},"63"),o("br"),o("span",{class:"line-number"},"64"),o("br"),o("span",{class:"line-number"},"65"),o("br"),o("span",{class:"line-number"},"66"),o("br"),o("span",{class:"line-number"},"67"),o("br"),o("span",{class:"line-number"},"68"),o("br"),o("span",{class:"line-number"},"69"),o("br"),o("span",{class:"line-number"},"70"),o("br"),o("span",{class:"line-number"},"71"),o("br"),o("span",{class:"line-number"},"72"),o("br"),o("span",{class:"line-number"},"73"),o("br"),o("span",{class:"line-number"},"74"),o("br"),o("span",{class:"line-number"},"75"),o("br"),o("span",{class:"line-number"},"76"),o("br"),o("span",{class:"line-number"},"77"),o("br"),o("span",{class:"line-number"},"78"),o("br"),o("span",{class:"line-number"},"79"),o("br"),o("span",{class:"line-number"},"80"),o("br"),o("span",{class:"line-number"},"81"),o("br")])],-1),f=o("div",{class:"language-json ext-json line-numbers-mode"},[o("pre",{class:"language-json"},[o("code",null,[o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"api"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"services"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"HandlerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"LoggerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"StatsService"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"listen"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"port"'),o("span",{class:"token operator"},":"),r(" "),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"dokodemo-door"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"address"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv4"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"sendThrough"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"your wg0 v4 address"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv4"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blackhole"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"policy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"system"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"statsInboundDownlink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"statsInboundUplink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"routing"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"rules"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'""'),r("\n "),o("span",{class:"token comment"},"//需要之前在 inbound 中指定好 Tag,我这里是 api 生成的,还可以添加域名等等"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"bittorrent"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"stats"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),r("\n"),o("span",{class:"token punctuation"},"}"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br"),o("span",{class:"line-number"},"14"),o("br"),o("span",{class:"line-number"},"15"),o("br"),o("span",{class:"line-number"},"16"),o("br"),o("span",{class:"line-number"},"17"),o("br"),o("span",{class:"line-number"},"18"),o("br"),o("span",{class:"line-number"},"19"),o("br"),o("span",{class:"line-number"},"20"),o("br"),o("span",{class:"line-number"},"21"),o("br"),o("span",{class:"line-number"},"22"),o("br"),o("span",{class:"line-number"},"23"),o("br"),o("span",{class:"line-number"},"24"),o("br"),o("span",{class:"line-number"},"25"),o("br"),o("span",{class:"line-number"},"26"),o("br"),o("span",{class:"line-number"},"27"),o("br"),o("span",{class:"line-number"},"28"),o("br"),o("span",{class:"line-number"},"29"),o("br"),o("span",{class:"line-number"},"30"),o("br"),o("span",{class:"line-number"},"31"),o("br"),o("span",{class:"line-number"},"32"),o("br"),o("span",{class:"line-number"},"33"),o("br"),o("span",{class:"line-number"},"34"),o("br"),o("span",{class:"line-number"},"35"),o("br"),o("span",{class:"line-number"},"36"),o("br"),o("span",{class:"line-number"},"37"),o("br"),o("span",{class:"line-number"},"38"),o("br"),o("span",{class:"line-number"},"39"),o("br"),o("span",{class:"line-number"},"40"),o("br"),o("span",{class:"line-number"},"41"),o("br"),o("span",{class:"line-number"},"42"),o("br"),o("span",{class:"line-number"},"43"),o("br"),o("span",{class:"line-number"},"44"),o("br"),o("span",{class:"line-number"},"45"),o("br"),o("span",{class:"line-number"},"46"),o("br"),o("span",{class:"line-number"},"47"),o("br"),o("span",{class:"line-number"},"48"),o("br"),o("span",{class:"line-number"},"49"),o("br"),o("span",{class:"line-number"},"50"),o("br"),o("span",{class:"line-number"},"51"),o("br"),o("span",{class:"line-number"},"52"),o("br"),o("span",{class:"line-number"},"53"),o("br"),o("span",{class:"line-number"},"54"),o("br"),o("span",{class:"line-number"},"55"),o("br"),o("span",{class:"line-number"},"56"),o("br"),o("span",{class:"line-number"},"57"),o("br"),o("span",{class:"line-number"},"58"),o("br"),o("span",{class:"line-number"},"59"),o("br"),o("span",{class:"line-number"},"60"),o("br"),o("span",{class:"line-number"},"61"),o("br"),o("span",{class:"line-number"},"62"),o("br"),o("span",{class:"line-number"},"63"),o("br"),o("span",{class:"line-number"},"64"),o("br"),o("span",{class:"line-number"},"65"),o("br"),o("span",{class:"line-number"},"66"),o("br"),o("span",{class:"line-number"},"67"),o("br"),o("span",{class:"line-number"},"68"),o("br"),o("span",{class:"line-number"},"69"),o("br"),o("span",{class:"line-number"},"70"),o("br"),o("span",{class:"line-number"},"71"),o("br"),o("span",{class:"line-number"},"72"),o("br"),o("span",{class:"line-number"},"73"),o("br"),o("span",{class:"line-number"},"74"),o("br"),o("span",{class:"line-number"},"75"),o("br"),o("span",{class:"line-number"},"76"),o("br"),o("span",{class:"line-number"},"77"),o("br"),o("span",{class:"line-number"},"78"),o("br")])],-1),P=l('

    提示

    可以通过修改 "domainStrategy": "UseIPv6"来控制对应用户的访问方式 实测优先级要高于系统本身的 gai.config

    5、系统设置配置

    提示

    需要打开系统的 ip_forward

    6、完成 WireGuard 相关设置

    开启隧道

    wg-quick up wg0\n
    1

    开机自启

    systemctl enable wg-quick@wg0\nsystemctl start wg-quick@wg0\n
    1
    2

    验证 IPv4/IPv6

    自行验证 Google 搜索 myip

    后记

    本文本意是可以避免的多余的流量浪费,将路由和分流的功能交给 Xray 处理。避免了维护路由表的繁琐工作。顺便技术提升 UP。

    感谢

    @Xray-core @V2ray-core @WireGuard @p3terx @w @Hiram @Luminous @Ln @JackChou

    ',14);c.render=function(l,o){const r=n("Tab"),c=n("Tabs");return s(),a(p,null,[u,e(c,{title:"if-config"},{default:t((()=>[e(r,{title:"fwmark1"},{default:t((()=>[i,k,b,m])),_:1}),e(r,{title:"sendThrough1"},{default:t((()=>[d,g,v,y])),_:1})])),_:1}),x,e(c,{title:"xray-config"},{default:t((()=>[e(r,{title:"fwmark2"},{default:t((()=>[h])),_:1}),e(r,{title:"sendThrough2"},{default:t((()=>[f])),_:1})])),_:1}),P],64)};export default c; diff --git a/assets/redirect.html.1db13504.js b/assets/redirect.html.e4ae70df.js similarity index 99% rename from assets/redirect.html.1db13504.js rename to assets/redirect.html.e4ae70df.js index a72a815db..4b5a39514 100644 --- a/assets/redirect.html.1db13504.js +++ b/assets/redirect.html.e4ae70df.js @@ -1 +1 @@ -import{r as n,o as s,c as a,b as e,w as t,F as p,d as l,a as o,e as r}from"./app.755d843f.js";const c={},u=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),i=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Interface"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PrivateKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v4 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v6 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"DNS"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"8.8.8.8"),r("\n"),o("span",{class:"token key attr-name"},"MTU"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"1280"),r("\n"),o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Peer"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PublicKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"::/0"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"0.0.0.0/0"),r("\n"),o("span",{class:"token key attr-name"},"Endpoint"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"ip:port"),r('"')]),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),k=o("p",null,[r("在 "),o("code",null,"[Interface]"),r(" 下添加如下命令:")],-1),b=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token key attr-name"},"Table"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"off"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 route add default dev <接口名称> table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 route add ::/0 dev <接口名称> table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete table main suppress_prefixlength 0"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br")])],-1),m=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"Tip"),o("ul",null,[o("li",null,[r("此命令表示 IPv4 中 fwmark 为 "),o("code",null,""),r(",IPv6 中 fwmark 为"),o("code",null,""),r(",::/0 全局 v6 走 WireGuard")]),o("li",null,"可根据自己需求增删命令,mark 值要与 Xray-core 中设置为相同,table 值自定"),o("li",null,"如果不支持配置文件,可以在系统中修改路由表")])],-1),d=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Interface"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PrivateKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v4 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v6 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"DNS"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"8.8.8.8"),r("\n"),o("span",{class:"token key attr-name"},"MTU"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"1280"),r("\n"),o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Peer"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PublicKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"::/0"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"0.0.0.0/0"),r("\n"),o("span",{class:"token key attr-name"},"Endpoint"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"ip:port"),r('"')]),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),g=o("p",null,[r("在 "),o("code",null,"[Interface]"),r(" 下添加如下命令:")],-1),v=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token key attr-name"},"Table"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"off"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},'ip -4 rule add from "your wg0 v4 address" lookup
    '),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 route add default dev wg0 table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 route add ::/0 dev wg0 table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},'ip -4 rule delete from "your wg0 v4 address" lookup
    '),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete table main suppress_prefixlength 0"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),y=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"Tip"),o("ul",null,[o("li",null,[r("此命令表示 IPV4 中来自 "),o("code",null,"your wg0 v4 address"),r(" 地址的走 WireGuard,IPv6 中::/0 全局 v6 走 WireGuard)")]),o("li",null,"可根据自己需求增删命令,实现 v6 分流,也可以与 fwmark 融合"),o("li",null,"如果不支持配置文件,可以在系统中修改路由表")])],-1),x=l('

    保存

    可顺手安装

    apt install openresolv\n
    1

    3、启用 WireGuard 网络接口

    加载内核模块

    modprobe wireguard\n
    1

    检查 WG 模块加载是否正常

    lsmod | grep wireguard\n
    1

    4、Xray-core 配置文件修改

    ',9),h=o("div",{class:"language-json ext-json line-numbers-mode"},[o("pre",{class:"language-json"},[o("code",null,[o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"api"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"services"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"HandlerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"LoggerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"StatsService"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"listen"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"port"'),o("span",{class:"token operator"},":"),r(" "),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"dokodemo-door"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"address"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv6"'),r("\n "),o("span",{class:"token comment"},"//设置默认用户走指定方式”UseIPv6”或者”UseIPv4”"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"streamSettings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"sockopt"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"mark"'),o("span",{class:"token operator"},":"),r(" \n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv6"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//设置fwmark为的用户走指定方式”UseIPv6””UseIPv4”"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blackhole"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"policy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"system"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"statsInboundDownlink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"statsInboundUplink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"routing"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"rules"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'""'),r("\n "),o("span",{class:"token comment"},"//需要之前在inbound中指定好Tag,我这里是api生成的,还可以添加域名等等"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"bittorrent"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"stats"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),r("\n"),o("span",{class:"token punctuation"},"}"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br"),o("span",{class:"line-number"},"14"),o("br"),o("span",{class:"line-number"},"15"),o("br"),o("span",{class:"line-number"},"16"),o("br"),o("span",{class:"line-number"},"17"),o("br"),o("span",{class:"line-number"},"18"),o("br"),o("span",{class:"line-number"},"19"),o("br"),o("span",{class:"line-number"},"20"),o("br"),o("span",{class:"line-number"},"21"),o("br"),o("span",{class:"line-number"},"22"),o("br"),o("span",{class:"line-number"},"23"),o("br"),o("span",{class:"line-number"},"24"),o("br"),o("span",{class:"line-number"},"25"),o("br"),o("span",{class:"line-number"},"26"),o("br"),o("span",{class:"line-number"},"27"),o("br"),o("span",{class:"line-number"},"28"),o("br"),o("span",{class:"line-number"},"29"),o("br"),o("span",{class:"line-number"},"30"),o("br"),o("span",{class:"line-number"},"31"),o("br"),o("span",{class:"line-number"},"32"),o("br"),o("span",{class:"line-number"},"33"),o("br"),o("span",{class:"line-number"},"34"),o("br"),o("span",{class:"line-number"},"35"),o("br"),o("span",{class:"line-number"},"36"),o("br"),o("span",{class:"line-number"},"37"),o("br"),o("span",{class:"line-number"},"38"),o("br"),o("span",{class:"line-number"},"39"),o("br"),o("span",{class:"line-number"},"40"),o("br"),o("span",{class:"line-number"},"41"),o("br"),o("span",{class:"line-number"},"42"),o("br"),o("span",{class:"line-number"},"43"),o("br"),o("span",{class:"line-number"},"44"),o("br"),o("span",{class:"line-number"},"45"),o("br"),o("span",{class:"line-number"},"46"),o("br"),o("span",{class:"line-number"},"47"),o("br"),o("span",{class:"line-number"},"48"),o("br"),o("span",{class:"line-number"},"49"),o("br"),o("span",{class:"line-number"},"50"),o("br"),o("span",{class:"line-number"},"51"),o("br"),o("span",{class:"line-number"},"52"),o("br"),o("span",{class:"line-number"},"53"),o("br"),o("span",{class:"line-number"},"54"),o("br"),o("span",{class:"line-number"},"55"),o("br"),o("span",{class:"line-number"},"56"),o("br"),o("span",{class:"line-number"},"57"),o("br"),o("span",{class:"line-number"},"58"),o("br"),o("span",{class:"line-number"},"59"),o("br"),o("span",{class:"line-number"},"60"),o("br"),o("span",{class:"line-number"},"61"),o("br"),o("span",{class:"line-number"},"62"),o("br"),o("span",{class:"line-number"},"63"),o("br"),o("span",{class:"line-number"},"64"),o("br"),o("span",{class:"line-number"},"65"),o("br"),o("span",{class:"line-number"},"66"),o("br"),o("span",{class:"line-number"},"67"),o("br"),o("span",{class:"line-number"},"68"),o("br"),o("span",{class:"line-number"},"69"),o("br"),o("span",{class:"line-number"},"70"),o("br"),o("span",{class:"line-number"},"71"),o("br"),o("span",{class:"line-number"},"72"),o("br"),o("span",{class:"line-number"},"73"),o("br"),o("span",{class:"line-number"},"74"),o("br"),o("span",{class:"line-number"},"75"),o("br"),o("span",{class:"line-number"},"76"),o("br"),o("span",{class:"line-number"},"77"),o("br"),o("span",{class:"line-number"},"78"),o("br"),o("span",{class:"line-number"},"79"),o("br"),o("span",{class:"line-number"},"80"),o("br"),o("span",{class:"line-number"},"81"),o("br")])],-1),f=o("div",{class:"language-json ext-json line-numbers-mode"},[o("pre",{class:"language-json"},[o("code",null,[o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"api"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"services"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"HandlerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"LoggerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"StatsService"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"listen"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"port"'),o("span",{class:"token operator"},":"),r(" "),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"dokodemo-door"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"address"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv4"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"sendThrough"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"your wg0 v4 address"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv4"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blackhole"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"policy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"system"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"statsInboundDownlink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"statsInboundUplink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"routing"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"rules"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'""'),r("\n "),o("span",{class:"token comment"},"//需要之前在 inbound 中指定好 Tag,我这里是 api 生成的,还可以添加域名等等"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"bittorrent"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"stats"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),r("\n"),o("span",{class:"token punctuation"},"}"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br"),o("span",{class:"line-number"},"14"),o("br"),o("span",{class:"line-number"},"15"),o("br"),o("span",{class:"line-number"},"16"),o("br"),o("span",{class:"line-number"},"17"),o("br"),o("span",{class:"line-number"},"18"),o("br"),o("span",{class:"line-number"},"19"),o("br"),o("span",{class:"line-number"},"20"),o("br"),o("span",{class:"line-number"},"21"),o("br"),o("span",{class:"line-number"},"22"),o("br"),o("span",{class:"line-number"},"23"),o("br"),o("span",{class:"line-number"},"24"),o("br"),o("span",{class:"line-number"},"25"),o("br"),o("span",{class:"line-number"},"26"),o("br"),o("span",{class:"line-number"},"27"),o("br"),o("span",{class:"line-number"},"28"),o("br"),o("span",{class:"line-number"},"29"),o("br"),o("span",{class:"line-number"},"30"),o("br"),o("span",{class:"line-number"},"31"),o("br"),o("span",{class:"line-number"},"32"),o("br"),o("span",{class:"line-number"},"33"),o("br"),o("span",{class:"line-number"},"34"),o("br"),o("span",{class:"line-number"},"35"),o("br"),o("span",{class:"line-number"},"36"),o("br"),o("span",{class:"line-number"},"37"),o("br"),o("span",{class:"line-number"},"38"),o("br"),o("span",{class:"line-number"},"39"),o("br"),o("span",{class:"line-number"},"40"),o("br"),o("span",{class:"line-number"},"41"),o("br"),o("span",{class:"line-number"},"42"),o("br"),o("span",{class:"line-number"},"43"),o("br"),o("span",{class:"line-number"},"44"),o("br"),o("span",{class:"line-number"},"45"),o("br"),o("span",{class:"line-number"},"46"),o("br"),o("span",{class:"line-number"},"47"),o("br"),o("span",{class:"line-number"},"48"),o("br"),o("span",{class:"line-number"},"49"),o("br"),o("span",{class:"line-number"},"50"),o("br"),o("span",{class:"line-number"},"51"),o("br"),o("span",{class:"line-number"},"52"),o("br"),o("span",{class:"line-number"},"53"),o("br"),o("span",{class:"line-number"},"54"),o("br"),o("span",{class:"line-number"},"55"),o("br"),o("span",{class:"line-number"},"56"),o("br"),o("span",{class:"line-number"},"57"),o("br"),o("span",{class:"line-number"},"58"),o("br"),o("span",{class:"line-number"},"59"),o("br"),o("span",{class:"line-number"},"60"),o("br"),o("span",{class:"line-number"},"61"),o("br"),o("span",{class:"line-number"},"62"),o("br"),o("span",{class:"line-number"},"63"),o("br"),o("span",{class:"line-number"},"64"),o("br"),o("span",{class:"line-number"},"65"),o("br"),o("span",{class:"line-number"},"66"),o("br"),o("span",{class:"line-number"},"67"),o("br"),o("span",{class:"line-number"},"68"),o("br"),o("span",{class:"line-number"},"69"),o("br"),o("span",{class:"line-number"},"70"),o("br"),o("span",{class:"line-number"},"71"),o("br"),o("span",{class:"line-number"},"72"),o("br"),o("span",{class:"line-number"},"73"),o("br"),o("span",{class:"line-number"},"74"),o("br"),o("span",{class:"line-number"},"75"),o("br"),o("span",{class:"line-number"},"76"),o("br"),o("span",{class:"line-number"},"77"),o("br"),o("span",{class:"line-number"},"78"),o("br")])],-1),P=l('

    Tip

    可以通过修改 "domainStrategy": "UseIPv6"来控制对应用户的访问方式 实测优先级要高于系统本身的 gai.config

    5、系统设置配置

    Tip

    需要打开系统的 ip_forward

    6、完成 WireGuard 相关设置

    开启隧道

    wg-quick up wg0\n
    1

    开机自启

    systemctl enable wg-quick@wg0\nsystemctl start wg-quick@wg0\n
    1
    2

    验证 IPv4/IPv6

    自行验证 Google 搜索 myip

    后记

    本文本意是可以避免的多余的流量浪费,将路由和分流的功能交给 Xray 处理。避免了维护路由表的繁琐工作。顺便技术提升 UP。

    感谢

    @Xray-core @V2ray-core @WireGuard @p3terx @w @Hiram @Luminous @Ln @JackChou

    ',14);c.render=function(l,o){const r=n("Tab"),c=n("Tabs");return s(),a(p,null,[u,e(c,{title:"if-config"},{default:t((()=>[e(r,{title:"fwmark1"},{default:t((()=>[i,k,b,m])),_:1}),e(r,{title:"sendThrough1"},{default:t((()=>[d,g,v,y])),_:1})])),_:1}),x,e(c,{title:"xray-config"},{default:t((()=>[e(r,{title:"fwmark2"},{default:t((()=>[h])),_:1}),e(r,{title:"sendThrough2"},{default:t((()=>[f])),_:1})])),_:1}),P],64)};export default c; +import{r as n,o as s,c as a,b as e,w as t,F as p,d as l,a as o,e as r}from"./app.48111a85.js";const c={},u=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),i=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Interface"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PrivateKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v4 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v6 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"DNS"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"8.8.8.8"),r("\n"),o("span",{class:"token key attr-name"},"MTU"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"1280"),r("\n"),o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Peer"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PublicKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"::/0"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"0.0.0.0/0"),r("\n"),o("span",{class:"token key attr-name"},"Endpoint"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"ip:port"),r('"')]),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),k=o("p",null,[r("在 "),o("code",null,"[Interface]"),r(" 下添加如下命令:")],-1),b=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token key attr-name"},"Table"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"off"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 route add default dev <接口名称> table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 route add ::/0 dev <接口名称> table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete fwmark lookup
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete table main suppress_prefixlength 0"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br")])],-1),m=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"Tip"),o("ul",null,[o("li",null,[r("此命令表示 IPv4 中 fwmark 为 "),o("code",null,""),r(",IPv6 中 fwmark 为"),o("code",null,""),r(",::/0 全局 v6 走 WireGuard")]),o("li",null,"可根据自己需求增删命令,mark 值要与 Xray-core 中设置为相同,table 值自定"),o("li",null,"如果不支持配置文件,可以在系统中修改路由表")])],-1),d=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Interface"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PrivateKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v4 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"Address"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"your wg0 v6 address"),r('"')]),r("\n"),o("span",{class:"token key attr-name"},"DNS"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"8.8.8.8"),r("\n"),o("span",{class:"token key attr-name"},"MTU"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"1280"),r("\n"),o("span",{class:"token header"},[o("span",{class:"token punctuation"},"["),o("span",{class:"token section-name selector"},"Peer"),o("span",{class:"token punctuation"},"]")]),r("\n"),o("span",{class:"token key attr-name"},"PublicKey"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"xxxxxxxxxxxxxxxxxxxxx"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"::/0"),r("\n"),o("span",{class:"token key attr-name"},"AllowedIPs"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"0.0.0.0/0"),r("\n"),o("span",{class:"token key attr-name"},"Endpoint"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},[r('"'),o("span",{class:"token inner-value"},"ip:port"),r('"')]),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),g=o("p",null,[r("在 "),o("code",null,"[Interface]"),r(" 下添加如下命令:")],-1),v=o("div",{class:"language-ini ext-ini line-numbers-mode"},[o("pre",{class:"language-ini"},[o("code",null,[o("span",{class:"token key attr-name"},"Table"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"off"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},'ip -4 rule add from "your wg0 v4 address" lookup
    '),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 route add default dev wg0 table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 route add ::/0 dev wg0 table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostUP"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule add table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},'ip -4 rule delete from "your wg0 v4 address" lookup
    '),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -4 rule delete table main suppress_prefixlength 0"),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete not fwmark
    table
    "),r("\n"),o("span",{class:"token key attr-name"},"PostDown"),r(),o("span",{class:"token punctuation"},"="),r(),o("span",{class:"token value attr-value"},"ip -6 rule delete table main suppress_prefixlength 0"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br")])],-1),y=o("div",{class:"custom-container tip"},[o("p",{class:"custom-container-title"},"Tip"),o("ul",null,[o("li",null,[r("此命令表示 IPV4 中来自 "),o("code",null,"your wg0 v4 address"),r(" 地址的走 WireGuard,IPv6 中::/0 全局 v6 走 WireGuard)")]),o("li",null,"可根据自己需求增删命令,实现 v6 分流,也可以与 fwmark 融合"),o("li",null,"如果不支持配置文件,可以在系统中修改路由表")])],-1),x=l('

    保存

    可顺手安装

    apt install openresolv\n
    1

    3、启用 WireGuard 网络接口

    加载内核模块

    modprobe wireguard\n
    1

    检查 WG 模块加载是否正常

    lsmod | grep wireguard\n
    1

    4、Xray-core 配置文件修改

    ',9),h=o("div",{class:"language-json ext-json line-numbers-mode"},[o("pre",{class:"language-json"},[o("code",null,[o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"api"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"services"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"HandlerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"LoggerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"StatsService"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"listen"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"port"'),o("span",{class:"token operator"},":"),r(" "),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"dokodemo-door"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"address"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv6"'),r("\n "),o("span",{class:"token comment"},"//设置默认用户走指定方式”UseIPv6”或者”UseIPv4”"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"streamSettings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"sockopt"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"mark"'),o("span",{class:"token operator"},":"),r(" \n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv6"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//设置fwmark为的用户走指定方式”UseIPv6””UseIPv4”"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blackhole"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"policy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"system"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"statsInboundDownlink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"statsInboundUplink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"routing"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"rules"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'""'),r("\n "),o("span",{class:"token comment"},"//需要之前在inbound中指定好Tag,我这里是api生成的,还可以添加域名等等"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"bittorrent"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"stats"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),r("\n"),o("span",{class:"token punctuation"},"}"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br"),o("span",{class:"line-number"},"14"),o("br"),o("span",{class:"line-number"},"15"),o("br"),o("span",{class:"line-number"},"16"),o("br"),o("span",{class:"line-number"},"17"),o("br"),o("span",{class:"line-number"},"18"),o("br"),o("span",{class:"line-number"},"19"),o("br"),o("span",{class:"line-number"},"20"),o("br"),o("span",{class:"line-number"},"21"),o("br"),o("span",{class:"line-number"},"22"),o("br"),o("span",{class:"line-number"},"23"),o("br"),o("span",{class:"line-number"},"24"),o("br"),o("span",{class:"line-number"},"25"),o("br"),o("span",{class:"line-number"},"26"),o("br"),o("span",{class:"line-number"},"27"),o("br"),o("span",{class:"line-number"},"28"),o("br"),o("span",{class:"line-number"},"29"),o("br"),o("span",{class:"line-number"},"30"),o("br"),o("span",{class:"line-number"},"31"),o("br"),o("span",{class:"line-number"},"32"),o("br"),o("span",{class:"line-number"},"33"),o("br"),o("span",{class:"line-number"},"34"),o("br"),o("span",{class:"line-number"},"35"),o("br"),o("span",{class:"line-number"},"36"),o("br"),o("span",{class:"line-number"},"37"),o("br"),o("span",{class:"line-number"},"38"),o("br"),o("span",{class:"line-number"},"39"),o("br"),o("span",{class:"line-number"},"40"),o("br"),o("span",{class:"line-number"},"41"),o("br"),o("span",{class:"line-number"},"42"),o("br"),o("span",{class:"line-number"},"43"),o("br"),o("span",{class:"line-number"},"44"),o("br"),o("span",{class:"line-number"},"45"),o("br"),o("span",{class:"line-number"},"46"),o("br"),o("span",{class:"line-number"},"47"),o("br"),o("span",{class:"line-number"},"48"),o("br"),o("span",{class:"line-number"},"49"),o("br"),o("span",{class:"line-number"},"50"),o("br"),o("span",{class:"line-number"},"51"),o("br"),o("span",{class:"line-number"},"52"),o("br"),o("span",{class:"line-number"},"53"),o("br"),o("span",{class:"line-number"},"54"),o("br"),o("span",{class:"line-number"},"55"),o("br"),o("span",{class:"line-number"},"56"),o("br"),o("span",{class:"line-number"},"57"),o("br"),o("span",{class:"line-number"},"58"),o("br"),o("span",{class:"line-number"},"59"),o("br"),o("span",{class:"line-number"},"60"),o("br"),o("span",{class:"line-number"},"61"),o("br"),o("span",{class:"line-number"},"62"),o("br"),o("span",{class:"line-number"},"63"),o("br"),o("span",{class:"line-number"},"64"),o("br"),o("span",{class:"line-number"},"65"),o("br"),o("span",{class:"line-number"},"66"),o("br"),o("span",{class:"line-number"},"67"),o("br"),o("span",{class:"line-number"},"68"),o("br"),o("span",{class:"line-number"},"69"),o("br"),o("span",{class:"line-number"},"70"),o("br"),o("span",{class:"line-number"},"71"),o("br"),o("span",{class:"line-number"},"72"),o("br"),o("span",{class:"line-number"},"73"),o("br"),o("span",{class:"line-number"},"74"),o("br"),o("span",{class:"line-number"},"75"),o("br"),o("span",{class:"line-number"},"76"),o("br"),o("span",{class:"line-number"},"77"),o("br"),o("span",{class:"line-number"},"78"),o("br"),o("span",{class:"line-number"},"79"),o("br"),o("span",{class:"line-number"},"80"),o("br"),o("span",{class:"line-number"},"81"),o("br")])],-1),f=o("div",{class:"language-json ext-json line-numbers-mode"},[o("pre",{class:"language-json"},[o("code",null,[o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"api"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"services"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"HandlerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"LoggerService"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token string"},'"StatsService"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"listen"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"port"'),o("span",{class:"token operator"},":"),r(" "),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"dokodemo-door"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"address"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"127.0.0.1"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outbounds"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv4"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"freedom"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"sendThrough"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"your wg0 v4 address"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"domainStrategy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"UseIPv4"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token comment"},"//修改此处,可v4或者v6"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blackhole"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"settings"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"tag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"policy"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"system"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"statsInboundDownlink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"statsInboundUplink"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token boolean"},"true"),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"routing"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"rules"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"api"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"api"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"wg0"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"inboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'""'),r("\n "),o("span",{class:"token comment"},"//需要之前在 inbound 中指定好 Tag,我这里是 api 生成的,还可以添加域名等等"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token punctuation"},"{"),r("\n "),o("span",{class:"token property"},'"outboundTag"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"blocked"'),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"protocol"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"["),r("\n "),o("span",{class:"token string"},'"bittorrent"'),r("\n "),o("span",{class:"token punctuation"},"]"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"type"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token string"},'"field"'),r("\n "),o("span",{class:"token punctuation"},"}"),r("\n "),o("span",{class:"token punctuation"},"]"),r("\n "),o("span",{class:"token punctuation"},"}"),o("span",{class:"token punctuation"},","),r("\n "),o("span",{class:"token property"},'"stats"'),o("span",{class:"token operator"},":"),r(),o("span",{class:"token punctuation"},"{"),o("span",{class:"token punctuation"},"}"),r("\n"),o("span",{class:"token punctuation"},"}"),r("\n")])]),o("div",{class:"line-numbers"},[o("span",{class:"line-number"},"1"),o("br"),o("span",{class:"line-number"},"2"),o("br"),o("span",{class:"line-number"},"3"),o("br"),o("span",{class:"line-number"},"4"),o("br"),o("span",{class:"line-number"},"5"),o("br"),o("span",{class:"line-number"},"6"),o("br"),o("span",{class:"line-number"},"7"),o("br"),o("span",{class:"line-number"},"8"),o("br"),o("span",{class:"line-number"},"9"),o("br"),o("span",{class:"line-number"},"10"),o("br"),o("span",{class:"line-number"},"11"),o("br"),o("span",{class:"line-number"},"12"),o("br"),o("span",{class:"line-number"},"13"),o("br"),o("span",{class:"line-number"},"14"),o("br"),o("span",{class:"line-number"},"15"),o("br"),o("span",{class:"line-number"},"16"),o("br"),o("span",{class:"line-number"},"17"),o("br"),o("span",{class:"line-number"},"18"),o("br"),o("span",{class:"line-number"},"19"),o("br"),o("span",{class:"line-number"},"20"),o("br"),o("span",{class:"line-number"},"21"),o("br"),o("span",{class:"line-number"},"22"),o("br"),o("span",{class:"line-number"},"23"),o("br"),o("span",{class:"line-number"},"24"),o("br"),o("span",{class:"line-number"},"25"),o("br"),o("span",{class:"line-number"},"26"),o("br"),o("span",{class:"line-number"},"27"),o("br"),o("span",{class:"line-number"},"28"),o("br"),o("span",{class:"line-number"},"29"),o("br"),o("span",{class:"line-number"},"30"),o("br"),o("span",{class:"line-number"},"31"),o("br"),o("span",{class:"line-number"},"32"),o("br"),o("span",{class:"line-number"},"33"),o("br"),o("span",{class:"line-number"},"34"),o("br"),o("span",{class:"line-number"},"35"),o("br"),o("span",{class:"line-number"},"36"),o("br"),o("span",{class:"line-number"},"37"),o("br"),o("span",{class:"line-number"},"38"),o("br"),o("span",{class:"line-number"},"39"),o("br"),o("span",{class:"line-number"},"40"),o("br"),o("span",{class:"line-number"},"41"),o("br"),o("span",{class:"line-number"},"42"),o("br"),o("span",{class:"line-number"},"43"),o("br"),o("span",{class:"line-number"},"44"),o("br"),o("span",{class:"line-number"},"45"),o("br"),o("span",{class:"line-number"},"46"),o("br"),o("span",{class:"line-number"},"47"),o("br"),o("span",{class:"line-number"},"48"),o("br"),o("span",{class:"line-number"},"49"),o("br"),o("span",{class:"line-number"},"50"),o("br"),o("span",{class:"line-number"},"51"),o("br"),o("span",{class:"line-number"},"52"),o("br"),o("span",{class:"line-number"},"53"),o("br"),o("span",{class:"line-number"},"54"),o("br"),o("span",{class:"line-number"},"55"),o("br"),o("span",{class:"line-number"},"56"),o("br"),o("span",{class:"line-number"},"57"),o("br"),o("span",{class:"line-number"},"58"),o("br"),o("span",{class:"line-number"},"59"),o("br"),o("span",{class:"line-number"},"60"),o("br"),o("span",{class:"line-number"},"61"),o("br"),o("span",{class:"line-number"},"62"),o("br"),o("span",{class:"line-number"},"63"),o("br"),o("span",{class:"line-number"},"64"),o("br"),o("span",{class:"line-number"},"65"),o("br"),o("span",{class:"line-number"},"66"),o("br"),o("span",{class:"line-number"},"67"),o("br"),o("span",{class:"line-number"},"68"),o("br"),o("span",{class:"line-number"},"69"),o("br"),o("span",{class:"line-number"},"70"),o("br"),o("span",{class:"line-number"},"71"),o("br"),o("span",{class:"line-number"},"72"),o("br"),o("span",{class:"line-number"},"73"),o("br"),o("span",{class:"line-number"},"74"),o("br"),o("span",{class:"line-number"},"75"),o("br"),o("span",{class:"line-number"},"76"),o("br"),o("span",{class:"line-number"},"77"),o("br"),o("span",{class:"line-number"},"78"),o("br")])],-1),P=l('

    Tip

    可以通过修改 "domainStrategy": "UseIPv6"来控制对应用户的访问方式 实测优先级要高于系统本身的 gai.config

    5、系统设置配置

    Tip

    需要打开系统的 ip_forward

    6、完成 WireGuard 相关设置

    开启隧道

    wg-quick up wg0\n
    1

    开机自启

    systemctl enable wg-quick@wg0\nsystemctl start wg-quick@wg0\n
    1
    2

    验证 IPv4/IPv6

    自行验证 Google 搜索 myip

    后记

    本文本意是可以避免的多余的流量浪费,将路由和分流的功能交给 Xray 处理。避免了维护路由表的繁琐工作。顺便技术提升 UP。

    感谢

    @Xray-core @V2ray-core @WireGuard @p3terx @w @Hiram @Luminous @Ln @JackChou

    ',14);c.render=function(l,o){const r=n("Tab"),c=n("Tabs");return s(),a(p,null,[u,e(c,{title:"if-config"},{default:t((()=>[e(r,{title:"fwmark1"},{default:t((()=>[i,k,b,m])),_:1}),e(r,{title:"sendThrough1"},{default:t((()=>[d,g,v,y])),_:1})])),_:1}),x,e(c,{title:"xray-config"},{default:t((()=>[e(r,{title:"fwmark2"},{default:t((()=>[h])),_:1}),e(r,{title:"sendThrough2"},{default:t((()=>[f])),_:1})])),_:1}),P],64)};export default c; diff --git a/assets/requirementDiagram-730b4d6e.446cee50.js b/assets/requirementDiagram-730b4d6e.e48886eb.js similarity index 99% rename from assets/requirementDiagram-730b4d6e.446cee50.js rename to assets/requirementDiagram-730b4d6e.e48886eb.js index 3854fa083..325d755b2 100644 --- a/assets/requirementDiagram-730b4d6e.446cee50.js +++ b/assets/requirementDiagram-730b4d6e.e48886eb.js @@ -1 +1 @@ -import{c as e,s as t,g as i,b as r,a as n,m as s,l as a,z as c,h as o,i as l,j as h}from"./mermaid.core.a66200b0.js";import{G as u,l as y}from"./layout.2f099f66.js";import{l as d}from"./line.f17bed9e.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";var p=function(){var e=function(e,t,i,r){for(i=i||{},r=e.length;r--;i[e[r]]=t);return i},t=[1,3],i=[1,5],r=[1,6],n=[1,7],s=[1,8],a=[5,6,8,14,16,18,19,40,41,42,43,44,45,53,71,72],c=[1,22],o=[2,13],l=[1,26],h=[1,27],u=[1,28],y=[1,29],d=[1,30],p=[1,31],_=[1,24],g=[1,32],E=[1,33],R=[1,36],m=[71,72],f=[5,8,14,16,18,19,40,41,42,43,44,45,53,60,62,71,72],I=[1,56],b=[1,57],S=[1,58],k=[1,59],T=[1,60],N=[1,61],v=[1,62],x=[62,63],A=[1,74],q=[1,70],$=[1,71],O=[1,72],w=[1,73],C=[1,75],D=[1,79],L=[1,80],F=[1,77],M=[1,78],P=[5,8,14,16,18,19,40,41,42,43,44,45,53,71,72],V={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,openDirective:9,typeDirective:10,closeDirective:11,":":12,argDirective:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,open_directive:19,type_directive:20,arg_directive:21,close_directive:22,requirementDef:23,elementDef:24,relationshipDef:25,requirementType:26,requirementName:27,STRUCT_START:28,requirementBody:29,ID:30,COLONSEP:31,id:32,TEXT:33,text:34,RISK:35,riskLevel:36,VERIFYMTHD:37,verifyType:38,STRUCT_STOP:39,REQUIREMENT:40,FUNCTIONAL_REQUIREMENT:41,INTERFACE_REQUIREMENT:42,PERFORMANCE_REQUIREMENT:43,PHYSICAL_REQUIREMENT:44,DESIGN_CONSTRAINT:45,LOW_RISK:46,MED_RISK:47,HIGH_RISK:48,VERIFY_ANALYSIS:49,VERIFY_DEMONSTRATION:50,VERIFY_INSPECTION:51,VERIFY_TEST:52,ELEMENT:53,elementName:54,elementBody:55,TYPE:56,type:57,DOCREF:58,ref:59,END_ARROW_L:60,relationship:61,LINE:62,END_ARROW_R:63,CONTAINS:64,COPIES:65,DERIVES:66,SATISFIES:67,VERIFIES:68,REFINES:69,TRACES:70,unqString:71,qString:72,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",12:":",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"open_directive",20:"type_directive",21:"arg_directive",22:"close_directive",28:"STRUCT_START",30:"ID",31:"COLONSEP",33:"TEXT",35:"RISK",37:"VERIFYMTHD",39:"STRUCT_STOP",40:"REQUIREMENT",41:"FUNCTIONAL_REQUIREMENT",42:"INTERFACE_REQUIREMENT",43:"PERFORMANCE_REQUIREMENT",44:"PHYSICAL_REQUIREMENT",45:"DESIGN_CONSTRAINT",46:"LOW_RISK",47:"MED_RISK",48:"HIGH_RISK",49:"VERIFY_ANALYSIS",50:"VERIFY_DEMONSTRATION",51:"VERIFY_INSPECTION",52:"VERIFY_TEST",53:"ELEMENT",56:"TYPE",58:"DOCREF",60:"END_ARROW_L",62:"LINE",63:"END_ARROW_R",64:"CONTAINS",65:"COPIES",66:"DERIVES",67:"SATISFIES",68:"VERIFIES",69:"REFINES",70:"TRACES",71:"unqString",72:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,3],[4,5],[4,2],[4,2],[4,1],[9,1],[10,1],[13,1],[11,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[23,5],[29,5],[29,5],[29,5],[29,5],[29,2],[29,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[36,1],[36,1],[36,1],[38,1],[38,1],[38,1],[38,1],[24,5],[55,5],[55,5],[55,2],[55,1],[25,5],[25,5],[61,1],[61,1],[61,1],[61,1],[61,1],[61,1],[61,1],[27,1],[27,1],[32,1],[32,1],[34,1],[34,1],[54,1],[54,1],[57,1],[57,1],[59,1],[59,1]],performAction:function(e,t,i,r,n,s,a){var c=s.length-1;switch(n){case 6:this.$=s[c].trim(),r.setAccTitle(this.$);break;case 7:case 8:this.$=s[c].trim(),r.setAccDescription(this.$);break;case 9:r.parseDirective("%%{","open_directive");break;case 10:r.parseDirective(s[c],"type_directive");break;case 11:s[c]=s[c].trim().replace(/'/g,'"'),r.parseDirective(s[c],"arg_directive");break;case 12:r.parseDirective("}%%","close_directive","pie");break;case 13:this.$=[];break;case 19:r.addRequirement(s[c-3],s[c-4]);break;case 20:r.setNewReqId(s[c-2]);break;case 21:r.setNewReqText(s[c-2]);break;case 22:r.setNewReqRisk(s[c-2]);break;case 23:r.setNewReqVerifyMethod(s[c-2]);break;case 26:this.$=r.RequirementType.REQUIREMENT;break;case 27:this.$=r.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 28:this.$=r.RequirementType.INTERFACE_REQUIREMENT;break;case 29:this.$=r.RequirementType.PERFORMANCE_REQUIREMENT;break;case 30:this.$=r.RequirementType.PHYSICAL_REQUIREMENT;break;case 31:this.$=r.RequirementType.DESIGN_CONSTRAINT;break;case 32:this.$=r.RiskLevel.LOW_RISK;break;case 33:this.$=r.RiskLevel.MED_RISK;break;case 34:this.$=r.RiskLevel.HIGH_RISK;break;case 35:this.$=r.VerifyType.VERIFY_ANALYSIS;break;case 36:this.$=r.VerifyType.VERIFY_DEMONSTRATION;break;case 37:this.$=r.VerifyType.VERIFY_INSPECTION;break;case 38:this.$=r.VerifyType.VERIFY_TEST;break;case 39:r.addElement(s[c-3]);break;case 40:r.setNewElementType(s[c-2]);break;case 41:r.setNewElementDocRef(s[c-2]);break;case 44:r.addRelationship(s[c-2],s[c],s[c-4]);break;case 45:r.addRelationship(s[c-2],s[c-4],s[c]);break;case 46:this.$=r.Relationships.CONTAINS;break;case 47:this.$=r.Relationships.COPIES;break;case 48:this.$=r.Relationships.DERIVES;break;case 49:this.$=r.Relationships.SATISFIES;break;case 50:this.$=r.Relationships.VERIFIES;break;case 51:this.$=r.Relationships.REFINES;break;case 52:this.$=r.Relationships.TRACES}},table:[{3:1,4:2,6:t,9:4,14:i,16:r,18:n,19:s},{1:[3]},{3:10,4:2,5:[1,9],6:t,9:4,14:i,16:r,18:n,19:s},{5:[1,11]},{10:12,20:[1,13]},{15:[1,14]},{17:[1,15]},e(a,[2,8]),{20:[2,9]},{3:16,4:2,6:t,9:4,14:i,16:r,18:n,19:s},{1:[2,2]},{4:21,5:c,7:17,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{11:34,12:[1,35],22:R},e([12,22],[2,10]),e(a,[2,6]),e(a,[2,7]),{1:[2,1]},{8:[1,37]},{4:21,5:c,7:38,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{4:21,5:c,7:39,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{4:21,5:c,7:40,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{4:21,5:c,7:41,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{4:21,5:c,7:42,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{27:43,71:[1,44],72:[1,45]},{54:46,71:[1,47],72:[1,48]},{60:[1,49],62:[1,50]},e(m,[2,26]),e(m,[2,27]),e(m,[2,28]),e(m,[2,29]),e(m,[2,30]),e(m,[2,31]),e(f,[2,55]),e(f,[2,56]),e(a,[2,4]),{13:51,21:[1,52]},e(a,[2,12]),{1:[2,3]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{8:[2,17]},{8:[2,18]},{28:[1,53]},{28:[2,53]},{28:[2,54]},{28:[1,54]},{28:[2,59]},{28:[2,60]},{61:55,64:I,65:b,66:S,67:k,68:T,69:N,70:v},{61:63,64:I,65:b,66:S,67:k,68:T,69:N,70:v},{11:64,22:R},{22:[2,11]},{5:[1,65]},{5:[1,66]},{62:[1,67]},e(x,[2,46]),e(x,[2,47]),e(x,[2,48]),e(x,[2,49]),e(x,[2,50]),e(x,[2,51]),e(x,[2,52]),{63:[1,68]},e(a,[2,5]),{5:A,29:69,30:q,33:$,35:O,37:w,39:C},{5:D,39:L,55:76,56:F,58:M},{32:81,71:g,72:E},{32:82,71:g,72:E},e(P,[2,19]),{31:[1,83]},{31:[1,84]},{31:[1,85]},{31:[1,86]},{5:A,29:87,30:q,33:$,35:O,37:w,39:C},e(P,[2,25]),e(P,[2,39]),{31:[1,88]},{31:[1,89]},{5:D,39:L,55:90,56:F,58:M},e(P,[2,43]),e(P,[2,44]),e(P,[2,45]),{32:91,71:g,72:E},{34:92,71:[1,93],72:[1,94]},{36:95,46:[1,96],47:[1,97],48:[1,98]},{38:99,49:[1,100],50:[1,101],51:[1,102],52:[1,103]},e(P,[2,24]),{57:104,71:[1,105],72:[1,106]},{59:107,71:[1,108],72:[1,109]},e(P,[2,42]),{5:[1,110]},{5:[1,111]},{5:[2,57]},{5:[2,58]},{5:[1,112]},{5:[2,32]},{5:[2,33]},{5:[2,34]},{5:[1,113]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[2,38]},{5:[1,114]},{5:[2,61]},{5:[2,62]},{5:[1,115]},{5:[2,63]},{5:[2,64]},{5:A,29:116,30:q,33:$,35:O,37:w,39:C},{5:A,29:117,30:q,33:$,35:O,37:w,39:C},{5:A,29:118,30:q,33:$,35:O,37:w,39:C},{5:A,29:119,30:q,33:$,35:O,37:w,39:C},{5:D,39:L,55:120,56:F,58:M},{5:D,39:L,55:121,56:F,58:M},e(P,[2,20]),e(P,[2,21]),e(P,[2,22]),e(P,[2,23]),e(P,[2,40]),e(P,[2,41])],defaultActions:{8:[2,9],10:[2,2],16:[2,1],37:[2,3],38:[2,14],39:[2,15],40:[2,16],41:[2,17],42:[2,18],44:[2,53],45:[2,54],47:[2,59],48:[2,60],52:[2,11],93:[2,57],94:[2,58],96:[2,32],97:[2,33],98:[2,34],100:[2,35],101:[2,36],102:[2,37],103:[2,38],105:[2,61],106:[2,62],108:[2,63],109:[2,64]},parseError:function(e,t){if(!t.recoverable){var i=new Error(e);throw i.hash=t,i}this.trace(e)},parse:function(e){var t=this,i=[0],r=[],n=[null],s=[],a=this.table,c="",o=0,l=0,h=2,u=1,y=s.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var _ in this.yy)Object.prototype.hasOwnProperty.call(this.yy,_)&&(p.yy[_]=this.yy[_]);d.setInput(e,p.yy),p.yy.lexer=d,p.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var g=d.yylloc;s.push(g);var E=d.options&&d.options.ranges;function R(){var e;return"number"!=typeof(e=r.pop()||d.lex()||u)&&(e instanceof Array&&(e=(r=e).pop()),e=t.symbols_[e]||e),e}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var m,f,I,b,S,k,T,N,v={};;){if(f=i[i.length-1],this.defaultActions[f]?I=this.defaultActions[f]:(null==m&&(m=R()),I=a[f]&&a[f][m]),void 0===I||!I.length||!I[0]){var x="";for(S in N=[],a[f])this.terminals_[S]&&S>h&&N.push("'"+this.terminals_[S]+"'");x=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+N.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(o+1)+": Unexpected "+(m==u?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(x,{text:d.match,token:this.terminals_[m]||m,line:d.yylineno,loc:g,expected:N})}if(I[0]instanceof Array&&I.length>1)throw new Error("Parse Error: multiple actions possible at state: "+f+", token: "+m);switch(I[0]){case 1:i.push(m),n.push(d.yytext),s.push(d.yylloc),i.push(I[1]),m=null,l=d.yyleng,c=d.yytext,o=d.yylineno,g=d.yylloc;break;case 2:if(k=this.productions_[I[1]][1],v.$=n[n.length-k],v._$={first_line:s[s.length-(k||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(k||1)].first_column,last_column:s[s.length-1].last_column},E&&(v._$.range=[s[s.length-(k||1)].range[0],s[s.length-1].range[1]]),void 0!==(b=this.performAction.apply(v,[c,l,o,p.yy,I[1],n,s].concat(y))))return b;k&&(i=i.slice(0,-1*k*2),n=n.slice(0,-1*k),s=s.slice(0,-1*k)),i.push(this.productions_[I[1]][0]),n.push(v.$),s.push(v._$),T=a[i[i.length-2]][i[i.length-1]],i.push(T);break;case 3:return!0}}return!0}},U={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,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 e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,i=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;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),i.length-1&&(this.yylineno-=i.length-1);var n=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===r.length?this.yylloc.first_column:0)+r[r.length-i.length].length-i[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var i,r,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(r=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],i=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in n)this[s]=n[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,i,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),s=0;st[0].length)){if(t=i,r=s,this.options.backtrack_lexer){if(!1!==(e=this.test_match(i,n[s])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,n[r]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(e,t,i,r){switch(i){case 0:return this.begin("open_directive"),19;case 1:return this.begin("type_directive"),20;case 2:return this.popState(),this.begin("arg_directive"),12;case 3:return this.popState(),this.popState(),22;case 4:return 21;case 5:return"title";case 6:return this.begin("acc_title"),14;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),16;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 5;case 14:case 15:case 16:break;case 17:return 8;case 18:return 6;case 19:return 28;case 20:return 39;case 21:return 31;case 22:return 30;case 23:return 33;case 24:return 35;case 25:return 37;case 26:return 40;case 27:return 41;case 28:return 42;case 29:return 43;case 30:return 44;case 31:return 45;case 32:return 46;case 33:return 47;case 34:return 48;case 35:return 49;case 36:return 50;case 37:return 51;case 38:return 52;case 39:return 53;case 40:return 64;case 41:return 65;case 42:return 66;case 43:return 67;case 44:return 68;case 45:return 69;case 46:return 70;case 47:return 56;case 48:return 58;case 49:return 60;case 50:return 63;case 51:return 62;case 52:this.begin("string");break;case 53:this.popState();break;case 54:return"qString";case 55:return t.yytext=t.yytext.trim(),71}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^\r\n\{\<\>\-\=]*)/i],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},unqString:{rules:[],inclusive:!1},token:{rules:[],inclusive:!1},string:{rules:[53,54],inclusive:!1},INITIAL:{rules:[0,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,55],inclusive:!0}}};function Y(){this.yy={}}return V.lexer=U,Y.prototype=V,V.Parser=Y,new Y}();p.parser=p;let _=[],g={},E={},R={},m={};const f={CONTAINS:"contains",ARROW:"arrow"},I=f,b=(e,t)=>{let i=e.append("defs").append("marker").attr("id",f.CONTAINS+"_line_ending").attr("refX",0).attr("refY",t.line_height/2).attr("markerWidth",t.line_height).attr("markerHeight",t.line_height).attr("orient","auto").append("g");i.append("circle").attr("cx",t.line_height/2).attr("cy",t.line_height/2).attr("r",t.line_height/2).attr("fill","none"),i.append("line").attr("x1",0).attr("x2",t.line_height).attr("y1",t.line_height/2).attr("y2",t.line_height/2).attr("stroke-width",1),i.append("line").attr("y1",0).attr("y2",t.line_height).attr("x1",t.line_height/2).attr("x2",t.line_height/2).attr("stroke-width",1),e.append("defs").append("marker").attr("id",f.ARROW+"_line_ending").attr("refX",t.line_height).attr("refY",.5*t.line_height).attr("markerWidth",t.line_height).attr("markerHeight",t.line_height).attr("orient","auto").append("path").attr("d",`M0,0\n L${t.line_height},${t.line_height/2}\n M${t.line_height},${t.line_height/2}\n L0,${t.line_height}`).attr("stroke-width",1)};let S={},k=0;const T=(e,t)=>e.insert("rect","#"+t).attr("class","req reqBox").attr("x",0).attr("y",0).attr("width",S.rect_min_width+"px").attr("height",S.rect_min_height+"px"),N=(e,t,i)=>{let r=S.rect_min_width/2,n=e.append("text").attr("class","req reqLabel reqTitle").attr("id",t).attr("x",r).attr("y",S.rect_padding).attr("dominant-baseline","hanging"),s=0;i.forEach((e=>{0==s?n.append("tspan").attr("text-anchor","middle").attr("x",S.rect_min_width/2).attr("dy",0).text(e):n.append("tspan").attr("text-anchor","middle").attr("x",S.rect_min_width/2).attr("dy",.75*S.line_height).text(e),s++}));let a=1.5*S.rect_padding+s*S.line_height*.75;return e.append("line").attr("class","req-title-line").attr("x1","0").attr("x2",S.rect_min_width).attr("y1",a).attr("y2",a),{titleNode:n,y:a}},v=(e,t,i,r)=>{let n=e.append("text").attr("class","req reqLabel").attr("id",t).attr("x",S.rect_padding).attr("y",r).attr("dominant-baseline","hanging"),s=0;let a=[];return i.forEach((e=>{let t=e.length;for(;t>30&&s<3;){let i=e.substring(0,30);t=(e=e.substring(30,e.length)).length,a[a.length]=i,s++}if(3==s){let e=a[a.length-1];a[a.length-1]=e.substring(0,e.length-4)+"..."}else a[a.length]=e;s=0})),a.forEach((e=>{n.append("tspan").attr("x",S.rect_padding).attr("dy",S.line_height).text(e)})),n},x=function(e,t,i,r,n){const s=i.edge(A(t.src),A(t.dst)),a=d().x((function(e){return e.x})).y((function(e){return e.y})),c=e.insert("path","#"+r).attr("class","er relationshipLine").attr("d",a(s.points)).attr("fill","none");t.type==n.db.Relationships.CONTAINS?c.attr("marker-start","url("+h.getUrl(S.arrowMarkerAbsolute)+"#"+t.type+"_line_ending)"):(c.attr("stroke-dasharray","10,7"),c.attr("marker-end","url("+h.getUrl(S.arrowMarkerAbsolute)+"#"+I.ARROW+"_line_ending)")),((e,t,i,r)=>{const n=t.node().getTotalLength(),s=t.node().getPointAtLength(.5*n),a="rel"+k;k++;const c=e.append("text").attr("class","req relationshipLabel").attr("id",a).attr("x",s.x).attr("y",s.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(r).node().getBBox();e.insert("rect","#"+a).attr("class","req reqLabelBox").attr("x",s.x-c.width/2).attr("y",s.y-c.height/2).attr("width",c.width).attr("height",c.height).attr("fill","white").attr("fill-opacity","85%")})(e,c,0,`<<${t.type}>>`)},A=e=>e.replace(/\s/g,"").replace(/\./g,"_"),q={parser:p,db:{RequirementType:{REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"},RiskLevel:{LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"},VerifyType:{VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"},Relationships:{CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"},parseDirective:function(e,t,i){s.parseDirective(this,e,t,i)},getConfig:()=>e().req,addRequirement:(e,t)=>(void 0===E[e]&&(E[e]={name:e,type:t,id:g.id,text:g.text,risk:g.risk,verifyMethod:g.verifyMethod}),g={},E[e]),getRequirements:()=>E,setNewReqId:e=>{void 0!==g&&(g.id=e)},setNewReqText:e=>{void 0!==g&&(g.text=e)},setNewReqRisk:e=>{void 0!==g&&(g.risk=e)},setNewReqVerifyMethod:e=>{void 0!==g&&(g.verifyMethod=e)},setAccTitle:t,getAccTitle:i,setAccDescription:r,getAccDescription:n,addElement:e=>(void 0===m[e]&&(m[e]={name:e,type:R.type,docRef:R.docRef},a.info("Added new requirement: ",e)),R={},m[e]),getElements:()=>m,setNewElementType:e=>{void 0!==R&&(R.type=e)},setNewElementDocRef:e=>{void 0!==R&&(R.docRef=e)},addRelationship:(e,t,i)=>{_.push({type:e,src:t,dst:i})},getRelationships:()=>_,clear:()=>{_=[],g={},E={},R={},m={},c()}},renderer:{draw:(t,i,r,n)=>{S=e().requirement,n.db.clear(),n.parser.parse(t);const s=S.securityLevel;let c;"sandbox"===s&&(c=o("#i"+i));const h=o("sandbox"===s?c.nodes()[0].contentDocument.body:"body").select(`[id='${i}']`);b(h,S);const d=new u({multigraph:!1,compound:!1,directed:!0}).setGraph({rankdir:S.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));let p=n.db.getRequirements(),_=n.db.getElements(),g=n.db.getRelationships();var E,R,m;E=p,R=d,m=h,Object.keys(E).forEach((e=>{let t=E[e];e=A(e),a.info("Added new requirement: ",e);const i=m.append("g").attr("id",e),r=T(i,"req-"+e);let n=N(i,e+"_title",[`<<${t.type}>>`,`${t.name}`]);v(i,e+"_body",[`Id: ${t.id}`,`Text: ${t.text}`,`Risk: ${t.risk}`,`Verification: ${t.verifyMethod}`],n.y);const s=r.node().getBBox();R.setNode(e,{width:s.width,height:s.height,shape:"rect",id:e})})),((e,t,i)=>{Object.keys(e).forEach((r=>{let n=e[r];const s=A(r),a=i.append("g").attr("id",s),c="element-"+s,o=T(a,c);let l=N(a,c+"_title",["<>",`${r}`]);v(a,c+"_body",[`Type: ${n.type||"Not Specified"}`,`Doc Ref: ${n.docRef||"None"}`],l.y);const h=o.node().getBBox();t.setNode(s,{width:h.width,height:h.height,shape:"rect",id:s})}))})(_,d,h),((e,t)=>{e.forEach((function(e){let i=A(e.src),r=A(e.dst);t.setEdge(i,r,{relationship:e})}))})(g,d),y(d),function(e,t){t.nodes().forEach((function(i){void 0!==i&&void 0!==t.node(i)&&(e.select("#"+i),e.select("#"+i).attr("transform","translate("+(t.node(i).x-t.node(i).width/2)+","+(t.node(i).y-t.node(i).height/2)+" )"))}))}(h,d),g.forEach((function(e){x(h,e,d,i,n)}));const f=S.rect_padding,I=h.node().getBBox(),k=I.width+2*f,q=I.height+2*f;l(h,q,k,S.useMaxWidth),h.attr("viewBox",`${I.x-f} ${I.y-f} ${k} ${q}`)}},styles:e=>`\n\n marker {\n fill: ${e.relationColor};\n stroke: ${e.relationColor};\n }\n\n marker.cross {\n stroke: ${e.lineColor};\n }\n\n svg {\n font-family: ${e.fontFamily};\n font-size: ${e.fontSize};\n }\n\n .reqBox {\n fill: ${e.requirementBackground};\n fill-opacity: 1.0;\n stroke: ${e.requirementBorderColor};\n stroke-width: ${e.requirementBorderSize};\n }\n \n .reqTitle, .reqLabel{\n fill: ${e.requirementTextColor};\n }\n .reqLabelBox {\n fill: ${e.relationLabelBackground};\n fill-opacity: 1.0;\n }\n\n .req-title-line {\n stroke: ${e.requirementBorderColor};\n stroke-width: ${e.requirementBorderSize};\n }\n .relationshipLine {\n stroke: ${e.relationColor};\n stroke-width: 1;\n }\n .relationshipLabel {\n fill: ${e.relationLabelColor};\n }\n\n`};export{q as diagram}; +import{c as e,s as t,g as i,b as r,a as n,m as s,l as a,z as c,h as o,i as l,j as h}from"./mermaid.core.3a590193.js";import{G as u,l as y}from"./layout.02c3e151.js";import{l as d}from"./line.53b161c2.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";var p=function(){var e=function(e,t,i,r){for(i=i||{},r=e.length;r--;i[e[r]]=t);return i},t=[1,3],i=[1,5],r=[1,6],n=[1,7],s=[1,8],a=[5,6,8,14,16,18,19,40,41,42,43,44,45,53,71,72],c=[1,22],o=[2,13],l=[1,26],h=[1,27],u=[1,28],y=[1,29],d=[1,30],p=[1,31],_=[1,24],g=[1,32],E=[1,33],R=[1,36],m=[71,72],f=[5,8,14,16,18,19,40,41,42,43,44,45,53,60,62,71,72],I=[1,56],b=[1,57],S=[1,58],k=[1,59],T=[1,60],N=[1,61],v=[1,62],x=[62,63],A=[1,74],q=[1,70],$=[1,71],O=[1,72],w=[1,73],C=[1,75],D=[1,79],L=[1,80],F=[1,77],M=[1,78],P=[5,8,14,16,18,19,40,41,42,43,44,45,53,71,72],V={trace:function(){},yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,openDirective:9,typeDirective:10,closeDirective:11,":":12,argDirective:13,acc_title:14,acc_title_value:15,acc_descr:16,acc_descr_value:17,acc_descr_multiline_value:18,open_directive:19,type_directive:20,arg_directive:21,close_directive:22,requirementDef:23,elementDef:24,relationshipDef:25,requirementType:26,requirementName:27,STRUCT_START:28,requirementBody:29,ID:30,COLONSEP:31,id:32,TEXT:33,text:34,RISK:35,riskLevel:36,VERIFYMTHD:37,verifyType:38,STRUCT_STOP:39,REQUIREMENT:40,FUNCTIONAL_REQUIREMENT:41,INTERFACE_REQUIREMENT:42,PERFORMANCE_REQUIREMENT:43,PHYSICAL_REQUIREMENT:44,DESIGN_CONSTRAINT:45,LOW_RISK:46,MED_RISK:47,HIGH_RISK:48,VERIFY_ANALYSIS:49,VERIFY_DEMONSTRATION:50,VERIFY_INSPECTION:51,VERIFY_TEST:52,ELEMENT:53,elementName:54,elementBody:55,TYPE:56,type:57,DOCREF:58,ref:59,END_ARROW_L:60,relationship:61,LINE:62,END_ARROW_R:63,CONTAINS:64,COPIES:65,DERIVES:66,SATISFIES:67,VERIFIES:68,REFINES:69,TRACES:70,unqString:71,qString:72,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",12:":",14:"acc_title",15:"acc_title_value",16:"acc_descr",17:"acc_descr_value",18:"acc_descr_multiline_value",19:"open_directive",20:"type_directive",21:"arg_directive",22:"close_directive",28:"STRUCT_START",30:"ID",31:"COLONSEP",33:"TEXT",35:"RISK",37:"VERIFYMTHD",39:"STRUCT_STOP",40:"REQUIREMENT",41:"FUNCTIONAL_REQUIREMENT",42:"INTERFACE_REQUIREMENT",43:"PERFORMANCE_REQUIREMENT",44:"PHYSICAL_REQUIREMENT",45:"DESIGN_CONSTRAINT",46:"LOW_RISK",47:"MED_RISK",48:"HIGH_RISK",49:"VERIFY_ANALYSIS",50:"VERIFY_DEMONSTRATION",51:"VERIFY_INSPECTION",52:"VERIFY_TEST",53:"ELEMENT",56:"TYPE",58:"DOCREF",60:"END_ARROW_L",62:"LINE",63:"END_ARROW_R",64:"CONTAINS",65:"COPIES",66:"DERIVES",67:"SATISFIES",68:"VERIFIES",69:"REFINES",70:"TRACES",71:"unqString",72:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,3],[4,5],[4,2],[4,2],[4,1],[9,1],[10,1],[13,1],[11,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[23,5],[29,5],[29,5],[29,5],[29,5],[29,2],[29,1],[26,1],[26,1],[26,1],[26,1],[26,1],[26,1],[36,1],[36,1],[36,1],[38,1],[38,1],[38,1],[38,1],[24,5],[55,5],[55,5],[55,2],[55,1],[25,5],[25,5],[61,1],[61,1],[61,1],[61,1],[61,1],[61,1],[61,1],[27,1],[27,1],[32,1],[32,1],[34,1],[34,1],[54,1],[54,1],[57,1],[57,1],[59,1],[59,1]],performAction:function(e,t,i,r,n,s,a){var c=s.length-1;switch(n){case 6:this.$=s[c].trim(),r.setAccTitle(this.$);break;case 7:case 8:this.$=s[c].trim(),r.setAccDescription(this.$);break;case 9:r.parseDirective("%%{","open_directive");break;case 10:r.parseDirective(s[c],"type_directive");break;case 11:s[c]=s[c].trim().replace(/'/g,'"'),r.parseDirective(s[c],"arg_directive");break;case 12:r.parseDirective("}%%","close_directive","pie");break;case 13:this.$=[];break;case 19:r.addRequirement(s[c-3],s[c-4]);break;case 20:r.setNewReqId(s[c-2]);break;case 21:r.setNewReqText(s[c-2]);break;case 22:r.setNewReqRisk(s[c-2]);break;case 23:r.setNewReqVerifyMethod(s[c-2]);break;case 26:this.$=r.RequirementType.REQUIREMENT;break;case 27:this.$=r.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 28:this.$=r.RequirementType.INTERFACE_REQUIREMENT;break;case 29:this.$=r.RequirementType.PERFORMANCE_REQUIREMENT;break;case 30:this.$=r.RequirementType.PHYSICAL_REQUIREMENT;break;case 31:this.$=r.RequirementType.DESIGN_CONSTRAINT;break;case 32:this.$=r.RiskLevel.LOW_RISK;break;case 33:this.$=r.RiskLevel.MED_RISK;break;case 34:this.$=r.RiskLevel.HIGH_RISK;break;case 35:this.$=r.VerifyType.VERIFY_ANALYSIS;break;case 36:this.$=r.VerifyType.VERIFY_DEMONSTRATION;break;case 37:this.$=r.VerifyType.VERIFY_INSPECTION;break;case 38:this.$=r.VerifyType.VERIFY_TEST;break;case 39:r.addElement(s[c-3]);break;case 40:r.setNewElementType(s[c-2]);break;case 41:r.setNewElementDocRef(s[c-2]);break;case 44:r.addRelationship(s[c-2],s[c],s[c-4]);break;case 45:r.addRelationship(s[c-2],s[c-4],s[c]);break;case 46:this.$=r.Relationships.CONTAINS;break;case 47:this.$=r.Relationships.COPIES;break;case 48:this.$=r.Relationships.DERIVES;break;case 49:this.$=r.Relationships.SATISFIES;break;case 50:this.$=r.Relationships.VERIFIES;break;case 51:this.$=r.Relationships.REFINES;break;case 52:this.$=r.Relationships.TRACES}},table:[{3:1,4:2,6:t,9:4,14:i,16:r,18:n,19:s},{1:[3]},{3:10,4:2,5:[1,9],6:t,9:4,14:i,16:r,18:n,19:s},{5:[1,11]},{10:12,20:[1,13]},{15:[1,14]},{17:[1,15]},e(a,[2,8]),{20:[2,9]},{3:16,4:2,6:t,9:4,14:i,16:r,18:n,19:s},{1:[2,2]},{4:21,5:c,7:17,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{11:34,12:[1,35],22:R},e([12,22],[2,10]),e(a,[2,6]),e(a,[2,7]),{1:[2,1]},{8:[1,37]},{4:21,5:c,7:38,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{4:21,5:c,7:39,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{4:21,5:c,7:40,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{4:21,5:c,7:41,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{4:21,5:c,7:42,8:o,9:4,14:i,16:r,18:n,19:s,23:18,24:19,25:20,26:23,32:25,40:l,41:h,42:u,43:y,44:d,45:p,53:_,71:g,72:E},{27:43,71:[1,44],72:[1,45]},{54:46,71:[1,47],72:[1,48]},{60:[1,49],62:[1,50]},e(m,[2,26]),e(m,[2,27]),e(m,[2,28]),e(m,[2,29]),e(m,[2,30]),e(m,[2,31]),e(f,[2,55]),e(f,[2,56]),e(a,[2,4]),{13:51,21:[1,52]},e(a,[2,12]),{1:[2,3]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{8:[2,17]},{8:[2,18]},{28:[1,53]},{28:[2,53]},{28:[2,54]},{28:[1,54]},{28:[2,59]},{28:[2,60]},{61:55,64:I,65:b,66:S,67:k,68:T,69:N,70:v},{61:63,64:I,65:b,66:S,67:k,68:T,69:N,70:v},{11:64,22:R},{22:[2,11]},{5:[1,65]},{5:[1,66]},{62:[1,67]},e(x,[2,46]),e(x,[2,47]),e(x,[2,48]),e(x,[2,49]),e(x,[2,50]),e(x,[2,51]),e(x,[2,52]),{63:[1,68]},e(a,[2,5]),{5:A,29:69,30:q,33:$,35:O,37:w,39:C},{5:D,39:L,55:76,56:F,58:M},{32:81,71:g,72:E},{32:82,71:g,72:E},e(P,[2,19]),{31:[1,83]},{31:[1,84]},{31:[1,85]},{31:[1,86]},{5:A,29:87,30:q,33:$,35:O,37:w,39:C},e(P,[2,25]),e(P,[2,39]),{31:[1,88]},{31:[1,89]},{5:D,39:L,55:90,56:F,58:M},e(P,[2,43]),e(P,[2,44]),e(P,[2,45]),{32:91,71:g,72:E},{34:92,71:[1,93],72:[1,94]},{36:95,46:[1,96],47:[1,97],48:[1,98]},{38:99,49:[1,100],50:[1,101],51:[1,102],52:[1,103]},e(P,[2,24]),{57:104,71:[1,105],72:[1,106]},{59:107,71:[1,108],72:[1,109]},e(P,[2,42]),{5:[1,110]},{5:[1,111]},{5:[2,57]},{5:[2,58]},{5:[1,112]},{5:[2,32]},{5:[2,33]},{5:[2,34]},{5:[1,113]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[2,38]},{5:[1,114]},{5:[2,61]},{5:[2,62]},{5:[1,115]},{5:[2,63]},{5:[2,64]},{5:A,29:116,30:q,33:$,35:O,37:w,39:C},{5:A,29:117,30:q,33:$,35:O,37:w,39:C},{5:A,29:118,30:q,33:$,35:O,37:w,39:C},{5:A,29:119,30:q,33:$,35:O,37:w,39:C},{5:D,39:L,55:120,56:F,58:M},{5:D,39:L,55:121,56:F,58:M},e(P,[2,20]),e(P,[2,21]),e(P,[2,22]),e(P,[2,23]),e(P,[2,40]),e(P,[2,41])],defaultActions:{8:[2,9],10:[2,2],16:[2,1],37:[2,3],38:[2,14],39:[2,15],40:[2,16],41:[2,17],42:[2,18],44:[2,53],45:[2,54],47:[2,59],48:[2,60],52:[2,11],93:[2,57],94:[2,58],96:[2,32],97:[2,33],98:[2,34],100:[2,35],101:[2,36],102:[2,37],103:[2,38],105:[2,61],106:[2,62],108:[2,63],109:[2,64]},parseError:function(e,t){if(!t.recoverable){var i=new Error(e);throw i.hash=t,i}this.trace(e)},parse:function(e){var t=this,i=[0],r=[],n=[null],s=[],a=this.table,c="",o=0,l=0,h=2,u=1,y=s.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var _ in this.yy)Object.prototype.hasOwnProperty.call(this.yy,_)&&(p.yy[_]=this.yy[_]);d.setInput(e,p.yy),p.yy.lexer=d,p.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var g=d.yylloc;s.push(g);var E=d.options&&d.options.ranges;function R(){var e;return"number"!=typeof(e=r.pop()||d.lex()||u)&&(e instanceof Array&&(e=(r=e).pop()),e=t.symbols_[e]||e),e}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var m,f,I,b,S,k,T,N,v={};;){if(f=i[i.length-1],this.defaultActions[f]?I=this.defaultActions[f]:(null==m&&(m=R()),I=a[f]&&a[f][m]),void 0===I||!I.length||!I[0]){var x="";for(S in N=[],a[f])this.terminals_[S]&&S>h&&N.push("'"+this.terminals_[S]+"'");x=d.showPosition?"Parse error on line "+(o+1)+":\n"+d.showPosition()+"\nExpecting "+N.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(o+1)+": Unexpected "+(m==u?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(x,{text:d.match,token:this.terminals_[m]||m,line:d.yylineno,loc:g,expected:N})}if(I[0]instanceof Array&&I.length>1)throw new Error("Parse Error: multiple actions possible at state: "+f+", token: "+m);switch(I[0]){case 1:i.push(m),n.push(d.yytext),s.push(d.yylloc),i.push(I[1]),m=null,l=d.yyleng,c=d.yytext,o=d.yylineno,g=d.yylloc;break;case 2:if(k=this.productions_[I[1]][1],v.$=n[n.length-k],v._$={first_line:s[s.length-(k||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(k||1)].first_column,last_column:s[s.length-1].last_column},E&&(v._$.range=[s[s.length-(k||1)].range[0],s[s.length-1].range[1]]),void 0!==(b=this.performAction.apply(v,[c,l,o,p.yy,I[1],n,s].concat(y))))return b;k&&(i=i.slice(0,-1*k*2),n=n.slice(0,-1*k),s=s.slice(0,-1*k)),i.push(this.productions_[I[1]][0]),n.push(v.$),s.push(v._$),T=a[i[i.length-2]][i[i.length-1]],i.push(T);break;case 3:return!0}}return!0}},U={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,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 e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,i=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;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),i.length-1&&(this.yylineno-=i.length-1);var n=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===r.length?this.yylloc.first_column:0)+r[r.length-i.length].length-i[0].length:this.yylloc.first_column-t},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var i,r,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(r=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],i=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in n)this[s]=n[s];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,i,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),s=0;st[0].length)){if(t=i,r=s,this.options.backtrack_lexer){if(!1!==(e=this.test_match(i,n[s])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,n[r]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(e,t,i,r){switch(i){case 0:return this.begin("open_directive"),19;case 1:return this.begin("type_directive"),20;case 2:return this.popState(),this.begin("arg_directive"),12;case 3:return this.popState(),this.popState(),22;case 4:return 21;case 5:return"title";case 6:return this.begin("acc_title"),14;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),16;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 5;case 14:case 15:case 16:break;case 17:return 8;case 18:return 6;case 19:return 28;case 20:return 39;case 21:return 31;case 22:return 30;case 23:return 33;case 24:return 35;case 25:return 37;case 26:return 40;case 27:return 41;case 28:return 42;case 29:return 43;case 30:return 44;case 31:return 45;case 32:return 46;case 33:return 47;case 34:return 48;case 35:return 49;case 36:return 50;case 37:return 51;case 38:return 52;case 39:return 53;case 40:return 64;case 41:return 65;case 42:return 66;case 43:return 67;case 44:return 68;case 45:return 69;case 46:return 70;case 47:return 56;case 48:return 58;case 49:return 60;case 50:return 63;case 51:return 62;case 52:this.begin("string");break;case 53:this.popState();break;case 54:return"qString";case 55:return t.yytext=t.yytext.trim(),71}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^\r\n\{\<\>\-\=]*)/i],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},close_directive:{rules:[],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},open_directive:{rules:[1],inclusive:!1},unqString:{rules:[],inclusive:!1},token:{rules:[],inclusive:!1},string:{rules:[53,54],inclusive:!1},INITIAL:{rules:[0,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,55],inclusive:!0}}};function Y(){this.yy={}}return V.lexer=U,Y.prototype=V,V.Parser=Y,new Y}();p.parser=p;let _=[],g={},E={},R={},m={};const f={CONTAINS:"contains",ARROW:"arrow"},I=f,b=(e,t)=>{let i=e.append("defs").append("marker").attr("id",f.CONTAINS+"_line_ending").attr("refX",0).attr("refY",t.line_height/2).attr("markerWidth",t.line_height).attr("markerHeight",t.line_height).attr("orient","auto").append("g");i.append("circle").attr("cx",t.line_height/2).attr("cy",t.line_height/2).attr("r",t.line_height/2).attr("fill","none"),i.append("line").attr("x1",0).attr("x2",t.line_height).attr("y1",t.line_height/2).attr("y2",t.line_height/2).attr("stroke-width",1),i.append("line").attr("y1",0).attr("y2",t.line_height).attr("x1",t.line_height/2).attr("x2",t.line_height/2).attr("stroke-width",1),e.append("defs").append("marker").attr("id",f.ARROW+"_line_ending").attr("refX",t.line_height).attr("refY",.5*t.line_height).attr("markerWidth",t.line_height).attr("markerHeight",t.line_height).attr("orient","auto").append("path").attr("d",`M0,0\n L${t.line_height},${t.line_height/2}\n M${t.line_height},${t.line_height/2}\n L0,${t.line_height}`).attr("stroke-width",1)};let S={},k=0;const T=(e,t)=>e.insert("rect","#"+t).attr("class","req reqBox").attr("x",0).attr("y",0).attr("width",S.rect_min_width+"px").attr("height",S.rect_min_height+"px"),N=(e,t,i)=>{let r=S.rect_min_width/2,n=e.append("text").attr("class","req reqLabel reqTitle").attr("id",t).attr("x",r).attr("y",S.rect_padding).attr("dominant-baseline","hanging"),s=0;i.forEach((e=>{0==s?n.append("tspan").attr("text-anchor","middle").attr("x",S.rect_min_width/2).attr("dy",0).text(e):n.append("tspan").attr("text-anchor","middle").attr("x",S.rect_min_width/2).attr("dy",.75*S.line_height).text(e),s++}));let a=1.5*S.rect_padding+s*S.line_height*.75;return e.append("line").attr("class","req-title-line").attr("x1","0").attr("x2",S.rect_min_width).attr("y1",a).attr("y2",a),{titleNode:n,y:a}},v=(e,t,i,r)=>{let n=e.append("text").attr("class","req reqLabel").attr("id",t).attr("x",S.rect_padding).attr("y",r).attr("dominant-baseline","hanging"),s=0;let a=[];return i.forEach((e=>{let t=e.length;for(;t>30&&s<3;){let i=e.substring(0,30);t=(e=e.substring(30,e.length)).length,a[a.length]=i,s++}if(3==s){let e=a[a.length-1];a[a.length-1]=e.substring(0,e.length-4)+"..."}else a[a.length]=e;s=0})),a.forEach((e=>{n.append("tspan").attr("x",S.rect_padding).attr("dy",S.line_height).text(e)})),n},x=function(e,t,i,r,n){const s=i.edge(A(t.src),A(t.dst)),a=d().x((function(e){return e.x})).y((function(e){return e.y})),c=e.insert("path","#"+r).attr("class","er relationshipLine").attr("d",a(s.points)).attr("fill","none");t.type==n.db.Relationships.CONTAINS?c.attr("marker-start","url("+h.getUrl(S.arrowMarkerAbsolute)+"#"+t.type+"_line_ending)"):(c.attr("stroke-dasharray","10,7"),c.attr("marker-end","url("+h.getUrl(S.arrowMarkerAbsolute)+"#"+I.ARROW+"_line_ending)")),((e,t,i,r)=>{const n=t.node().getTotalLength(),s=t.node().getPointAtLength(.5*n),a="rel"+k;k++;const c=e.append("text").attr("class","req relationshipLabel").attr("id",a).attr("x",s.x).attr("y",s.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(r).node().getBBox();e.insert("rect","#"+a).attr("class","req reqLabelBox").attr("x",s.x-c.width/2).attr("y",s.y-c.height/2).attr("width",c.width).attr("height",c.height).attr("fill","white").attr("fill-opacity","85%")})(e,c,0,`<<${t.type}>>`)},A=e=>e.replace(/\s/g,"").replace(/\./g,"_"),q={parser:p,db:{RequirementType:{REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"},RiskLevel:{LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"},VerifyType:{VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"},Relationships:{CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"},parseDirective:function(e,t,i){s.parseDirective(this,e,t,i)},getConfig:()=>e().req,addRequirement:(e,t)=>(void 0===E[e]&&(E[e]={name:e,type:t,id:g.id,text:g.text,risk:g.risk,verifyMethod:g.verifyMethod}),g={},E[e]),getRequirements:()=>E,setNewReqId:e=>{void 0!==g&&(g.id=e)},setNewReqText:e=>{void 0!==g&&(g.text=e)},setNewReqRisk:e=>{void 0!==g&&(g.risk=e)},setNewReqVerifyMethod:e=>{void 0!==g&&(g.verifyMethod=e)},setAccTitle:t,getAccTitle:i,setAccDescription:r,getAccDescription:n,addElement:e=>(void 0===m[e]&&(m[e]={name:e,type:R.type,docRef:R.docRef},a.info("Added new requirement: ",e)),R={},m[e]),getElements:()=>m,setNewElementType:e=>{void 0!==R&&(R.type=e)},setNewElementDocRef:e=>{void 0!==R&&(R.docRef=e)},addRelationship:(e,t,i)=>{_.push({type:e,src:t,dst:i})},getRelationships:()=>_,clear:()=>{_=[],g={},E={},R={},m={},c()}},renderer:{draw:(t,i,r,n)=>{S=e().requirement,n.db.clear(),n.parser.parse(t);const s=S.securityLevel;let c;"sandbox"===s&&(c=o("#i"+i));const h=o("sandbox"===s?c.nodes()[0].contentDocument.body:"body").select(`[id='${i}']`);b(h,S);const d=new u({multigraph:!1,compound:!1,directed:!0}).setGraph({rankdir:S.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));let p=n.db.getRequirements(),_=n.db.getElements(),g=n.db.getRelationships();var E,R,m;E=p,R=d,m=h,Object.keys(E).forEach((e=>{let t=E[e];e=A(e),a.info("Added new requirement: ",e);const i=m.append("g").attr("id",e),r=T(i,"req-"+e);let n=N(i,e+"_title",[`<<${t.type}>>`,`${t.name}`]);v(i,e+"_body",[`Id: ${t.id}`,`Text: ${t.text}`,`Risk: ${t.risk}`,`Verification: ${t.verifyMethod}`],n.y);const s=r.node().getBBox();R.setNode(e,{width:s.width,height:s.height,shape:"rect",id:e})})),((e,t,i)=>{Object.keys(e).forEach((r=>{let n=e[r];const s=A(r),a=i.append("g").attr("id",s),c="element-"+s,o=T(a,c);let l=N(a,c+"_title",["<>",`${r}`]);v(a,c+"_body",[`Type: ${n.type||"Not Specified"}`,`Doc Ref: ${n.docRef||"None"}`],l.y);const h=o.node().getBBox();t.setNode(s,{width:h.width,height:h.height,shape:"rect",id:s})}))})(_,d,h),((e,t)=>{e.forEach((function(e){let i=A(e.src),r=A(e.dst);t.setEdge(i,r,{relationship:e})}))})(g,d),y(d),function(e,t){t.nodes().forEach((function(i){void 0!==i&&void 0!==t.node(i)&&(e.select("#"+i),e.select("#"+i).attr("transform","translate("+(t.node(i).x-t.node(i).width/2)+","+(t.node(i).y-t.node(i).height/2)+" )"))}))}(h,d),g.forEach((function(e){x(h,e,d,i,n)}));const f=S.rect_padding,I=h.node().getBBox(),k=I.width+2*f,q=I.height+2*f;l(h,q,k,S.useMaxWidth),h.attr("viewBox",`${I.x-f} ${I.y-f} ${k} ${q}`)}},styles:e=>`\n\n marker {\n fill: ${e.relationColor};\n stroke: ${e.relationColor};\n }\n\n marker.cross {\n stroke: ${e.lineColor};\n }\n\n svg {\n font-family: ${e.fontFamily};\n font-size: ${e.fontSize};\n }\n\n .reqBox {\n fill: ${e.requirementBackground};\n fill-opacity: 1.0;\n stroke: ${e.requirementBorderColor};\n stroke-width: ${e.requirementBorderSize};\n }\n \n .reqTitle, .reqLabel{\n fill: ${e.requirementTextColor};\n }\n .reqLabelBox {\n fill: ${e.relationLabelBackground};\n fill-opacity: 1.0;\n }\n\n .req-title-line {\n stroke: ${e.requirementBorderColor};\n stroke-width: ${e.requirementBorderSize};\n }\n .relationshipLine {\n stroke: ${e.relationColor};\n stroke-width: 1;\n }\n .relationshipLabel {\n fill: ${e.relationLabelColor};\n }\n\n`};export{q as diagram}; diff --git a/assets/reverse.html.d60fb944.js b/assets/reverse.html.85bf9d1e.js similarity index 99% rename from assets/reverse.html.d60fb944.js rename to assets/reverse.html.85bf9d1e.js index fb3c6057e..711cc9219 100644 --- a/assets/reverse.html.d60fb944.js +++ b/assets/reverse.html.85bf9d1e.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as o,w as t,F as e,d as c,e as r}from"./app.755d843f.js";const l={},u=c('

    反向代理

    反向代理可以把服务器端的流量向客户端转发,即逆向流量转发。

    反向代理的大致工作原理如下:

    • 假设在主机 A 中有一个网页服务器,这台主机没有公网 IP,无法在公网上直接访问。另有一台主机 B,它可以由公网访问。现在我们需要把 B 作为入口,把流量从 B 转发到 A。
    • 在主机 A 中配置 Xray,称为bridge,在 B 中也配置 Xray,称为 portal
    • bridge 会向 portal 主动建立连接,此连接的目标地址可以自行设定。portal 会收到两种连接,一是由 bridge 发来的连接,二是公网用户发来的连接。portal 会自动将两类连接合并。于是 bridge 就可以收到公网流量了。
    • bridge 在收到公网流量之后,会将其原封不动地发给主机 A 中的网页服务器。当然,这一步需要路由的协作。
    • bridge 会根据流量的大小进行动态的负载均衡。
    ',4),i={class:"custom-container tip"},b=p("p",{class:"custom-container-title"},"提示",-1),k=r("反向代理默认已开启 "),d=r("Mux"),q=r(",请不要在其用到的 outbound 上再次开启 Mux。"),m=c('

    注意

    反向代理功能尚处于测试阶段,可能会有一些问题。

    ReverseObject

    ReverseObject 对应配置文件的 reverse 项。

    {\n  "reverse": {\n    "bridges": [\n      {\n        "tag": "bridge",\n        "domain": "test.xray.com"\n      }\n    ],\n    "portals": [\n      {\n        "tag": "portal",\n        "domain": "test.xray.com"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    bridges: [BridgeObject]

    数组,每一项表示一个 bridge。每个 bridge 的配置是一个 BridgeObject

    portals: [PortalObject]

    数组,每一项表示一个 portal。每个 portal 的配置是一个 PortalObject

    BridgeObject

    {\n  "tag": "bridge",\n  "domain": "test.xray.com"\n}\n
    1
    2
    3
    4

    tag: string

    ',11),g=r("所有由 "),y=p("code",null,"bridge",-1),v=r(" 发出的连接,都会带有这个标识。可以在 "),j=r("路由配置"),h=r(" 中使用 "),x=p("code",null,"inboundTag",-1),f=r(" 进行识别。"),T=c('

    domain: string

    指定一个域名,bridgeportal 建立的连接,都会使用这个域名进行发送。 这个域名只作为 bridgeportal 的通信用途,不必真实存在。

    PortalObject

    {\n  "tag": "portal",\n  "domain": "test.xray.com"\n}\n
    1
    2
    3
    4

    tag: string

    ',5),O=p("code",null,"portal",-1),B=r(" 的标识。在 "),P=r("路由配置"),A=r(" 中使用 "),w=p("code",null,"outboundTag",-1),R=r(" 将流量转发到这个 "),X=p("code",null,"portal",-1),_=r("。"),I=c('

    domain: string

    一个域名。当 portal 接收到流量时,如果流量的目标域名是此域名,则 portal 认为当前连接上 bridge 发来的通信连接。而其它流量则会被当成需要转发的流量。portal 所做的工作就是把这两类连接进行识别并拼接。

    提示

    一个 Xray 既可以作为 bridge,也可以作为 portal,也可以同时两者,以适用于不同的场景需要。

    完整配置样例

    提示

    在运行过程中,建议先启用 bridge,再启用 portal

    bridge 配置

    bridge 通常需要两个 outbound,一个用于连接 portal,另一个用于发送实际的流量。也就是说,你需要用路由区分两种流量。

    反向代理配置:

    {\n  "bridges": [\n    {\n      "tag": "bridge",\n      "domain": "test.xray.com"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    outbound:

    {\n  "tag": "out",\n  "protocol": "freedom",\n  "settings": {\n    "redirect": "127.0.0.1:80" // 将所有流量转发到网页服务器\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    {\n  "protocol": "vmess",\n  "settings": {\n    "vnext": [\n      {\n        "address": "portal 的 IP 地址",\n        "port": 1024,\n        "users": [\n          {\n            "id": "5783a3e7-e373-51cd-8642-c83782b807c5"\n          }\n        ]\n      }\n    ]\n  },\n  "tag": "interconn"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    路由配置:

    {\n  "rules": [\n    {\n      "type": "field",\n      "inboundTag": ["bridge"],\n      "domain": ["full:test.xray.com"],\n      "outboundTag": "interconn"\n    },\n    {\n      "type": "field",\n      "inboundTag": ["bridge"],\n      "outboundTag": "out"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    portal 配置

    portal 通常需要两个 inbound,一个用于接收 bridge 的连接,另一个用于接收实际的流量。同时你也需要用路由区分两种流量。

    反向代理配置:

    {\n  "portals": [\n    {\n      "tag": "portal",\n      "domain": "test.xray.com" // 必须和 bridge 的配置一样\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    inbound:

    {\n  "tag": "external",\n  "port": 80,\n  "protocol": "dokodemo-door",\n  "settings": {\n    "address": "127.0.0.1",\n    "port": 80,\n    "network": "tcp"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {\n  "port": 1024,\n  "tag": "interconn",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "5783a3e7-e373-51cd-8642-c83782b807c5"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    路由配置:

    {\n  "rules": [\n    {\n      "type": "field",\n      "inboundTag": ["external"],\n      "outboundTag": "portal"\n    },\n    {\n      "type": "field",\n      "inboundTag": ["interconn"],\n      "outboundTag": "portal"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ',23);l.render=function(c,r){const l=n("RouterLink");return s(),a(e,null,[u,p("div",i,[b,p("p",null,[k,o(l,{to:"/development/protocols/muxcool/"},{default:t((()=>[d])),_:1}),q])]),m,p("p",null,[g,y,v,o(l,{to:"/config/routing.html"},{default:t((()=>[j])),_:1}),h,x,f]),T,p("p",null,[O,B,o(l,{to:"/config/routing.html"},{default:t((()=>[P])),_:1}),A,w,R,X,_]),I],64)};export default l; +import{r as n,o as s,c as a,a as p,b as o,w as t,F as e,d as c,e as r}from"./app.48111a85.js";const l={},u=c('

    反向代理

    反向代理可以把服务器端的流量向客户端转发,即逆向流量转发。

    反向代理的大致工作原理如下:

    • 假设在主机 A 中有一个网页服务器,这台主机没有公网 IP,无法在公网上直接访问。另有一台主机 B,它可以由公网访问。现在我们需要把 B 作为入口,把流量从 B 转发到 A。
    • 在主机 A 中配置 Xray,称为bridge,在 B 中也配置 Xray,称为 portal
    • bridge 会向 portal 主动建立连接,此连接的目标地址可以自行设定。portal 会收到两种连接,一是由 bridge 发来的连接,二是公网用户发来的连接。portal 会自动将两类连接合并。于是 bridge 就可以收到公网流量了。
    • bridge 在收到公网流量之后,会将其原封不动地发给主机 A 中的网页服务器。当然,这一步需要路由的协作。
    • bridge 会根据流量的大小进行动态的负载均衡。
    ',4),i={class:"custom-container tip"},b=p("p",{class:"custom-container-title"},"提示",-1),k=r("反向代理默认已开启 "),d=r("Mux"),q=r(",请不要在其用到的 outbound 上再次开启 Mux。"),m=c('

    注意

    反向代理功能尚处于测试阶段,可能会有一些问题。

    ReverseObject

    ReverseObject 对应配置文件的 reverse 项。

    {\n  "reverse": {\n    "bridges": [\n      {\n        "tag": "bridge",\n        "domain": "test.xray.com"\n      }\n    ],\n    "portals": [\n      {\n        "tag": "portal",\n        "domain": "test.xray.com"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    bridges: [BridgeObject]

    数组,每一项表示一个 bridge。每个 bridge 的配置是一个 BridgeObject

    portals: [PortalObject]

    数组,每一项表示一个 portal。每个 portal 的配置是一个 PortalObject

    BridgeObject

    {\n  "tag": "bridge",\n  "domain": "test.xray.com"\n}\n
    1
    2
    3
    4

    tag: string

    ',11),g=r("所有由 "),y=p("code",null,"bridge",-1),v=r(" 发出的连接,都会带有这个标识。可以在 "),j=r("路由配置"),h=r(" 中使用 "),x=p("code",null,"inboundTag",-1),f=r(" 进行识别。"),T=c('

    domain: string

    指定一个域名,bridgeportal 建立的连接,都会使用这个域名进行发送。 这个域名只作为 bridgeportal 的通信用途,不必真实存在。

    PortalObject

    {\n  "tag": "portal",\n  "domain": "test.xray.com"\n}\n
    1
    2
    3
    4

    tag: string

    ',5),O=p("code",null,"portal",-1),B=r(" 的标识。在 "),P=r("路由配置"),A=r(" 中使用 "),w=p("code",null,"outboundTag",-1),R=r(" 将流量转发到这个 "),X=p("code",null,"portal",-1),_=r("。"),I=c('

    domain: string

    一个域名。当 portal 接收到流量时,如果流量的目标域名是此域名,则 portal 认为当前连接上 bridge 发来的通信连接。而其它流量则会被当成需要转发的流量。portal 所做的工作就是把这两类连接进行识别并拼接。

    提示

    一个 Xray 既可以作为 bridge,也可以作为 portal,也可以同时两者,以适用于不同的场景需要。

    完整配置样例

    提示

    在运行过程中,建议先启用 bridge,再启用 portal

    bridge 配置

    bridge 通常需要两个 outbound,一个用于连接 portal,另一个用于发送实际的流量。也就是说,你需要用路由区分两种流量。

    反向代理配置:

    {\n  "bridges": [\n    {\n      "tag": "bridge",\n      "domain": "test.xray.com"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    outbound:

    {\n  "tag": "out",\n  "protocol": "freedom",\n  "settings": {\n    "redirect": "127.0.0.1:80" // 将所有流量转发到网页服务器\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    {\n  "protocol": "vmess",\n  "settings": {\n    "vnext": [\n      {\n        "address": "portal 的 IP 地址",\n        "port": 1024,\n        "users": [\n          {\n            "id": "5783a3e7-e373-51cd-8642-c83782b807c5"\n          }\n        ]\n      }\n    ]\n  },\n  "tag": "interconn"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    路由配置:

    {\n  "rules": [\n    {\n      "type": "field",\n      "inboundTag": ["bridge"],\n      "domain": ["full:test.xray.com"],\n      "outboundTag": "interconn"\n    },\n    {\n      "type": "field",\n      "inboundTag": ["bridge"],\n      "outboundTag": "out"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    portal 配置

    portal 通常需要两个 inbound,一个用于接收 bridge 的连接,另一个用于接收实际的流量。同时你也需要用路由区分两种流量。

    反向代理配置:

    {\n  "portals": [\n    {\n      "tag": "portal",\n      "domain": "test.xray.com" // 必须和 bridge 的配置一样\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    inbound:

    {\n  "tag": "external",\n  "port": 80,\n  "protocol": "dokodemo-door",\n  "settings": {\n    "address": "127.0.0.1",\n    "port": 80,\n    "network": "tcp"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {\n  "port": 1024,\n  "tag": "interconn",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "5783a3e7-e373-51cd-8642-c83782b807c5"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    路由配置:

    {\n  "rules": [\n    {\n      "type": "field",\n      "inboundTag": ["external"],\n      "outboundTag": "portal"\n    },\n    {\n      "type": "field",\n      "inboundTag": ["interconn"],\n      "outboundTag": "portal"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ',23);l.render=function(c,r){const l=n("RouterLink");return s(),a(e,null,[u,p("div",i,[b,p("p",null,[k,o(l,{to:"/development/protocols/muxcool/"},{default:t((()=>[d])),_:1}),q])]),m,p("p",null,[g,y,v,o(l,{to:"/config/routing.html"},{default:t((()=>[j])),_:1}),h,x,f]),T,p("p",null,[O,B,o(l,{to:"/config/routing.html"},{default:t((()=>[P])),_:1}),A,w,R,X,_]),I],64)};export default l; diff --git a/assets/reverse.html.82f6f6f1.js b/assets/reverse.html.f7674b35.js similarity index 99% rename from assets/reverse.html.82f6f6f1.js rename to assets/reverse.html.f7674b35.js index b72e7d193..75be1a9be 100644 --- a/assets/reverse.html.82f6f6f1.js +++ b/assets/reverse.html.f7674b35.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as o,w as t,F as p,d as r,e as c}from"./app.755d843f.js";const l={},u=r('

    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.

    {\n  "reverse": {\n    "bridges": [\n      {\n        "tag": "bridge",\n        "domain": "test.xray.com"\n      }\n    ],\n    "portals": [\n      {\n        "tag": "portal",\n        "domain": "test.xray.com"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    bridges: [BridgeObject]

    An array in which each item represents a bridge. The configuration of each bridge is a BridgeObject.

    portals: [PortalObject]

    An array in which each item represents a portal. The configuration of each portal is a PortalObject.

    BridgeObject

    {\n  "tag": "bridge",\n  "domain": "test.xray.com"\n}\n
    1
    2
    3
    4

    tag: string

    ',16),i=c("All connections initiated by "),b=e("code",null,"bridge",-1),d=c(" will have this tag. It can be used to identify the connections in "),k=c("routing configuration"),m=c("."),q=r('

    domain: string

    Specifies a domain name that will be used by bridge to send connections to portal. This domain name is only used for communication between bridge and portal, and does not need to actually exist.

    PortalObject

    {\n  "tag": "portal",\n  "domain": "test.xray.com"\n}\n
    1
    2
    3
    4

    tag: string

    ',5),g=c("The identifier for the "),h=e("code",null,"portal",-1),f=c(". Use "),y=e("code",null,"outboundTag",-1),v=c(" in "),j=c("routing configuration"),w=c(" to forward traffic to this "),x=e("code",null,"portal",-1),T=c("."),A=r('

    domain: string

    A domain name. When the portal receives traffic, if the destination domain of the traffic is this domain, the portal assumes that the current connection is a communication connection sent by the bridge. Other traffic will be considered as traffic that needs to be forwarded. The work of the portal is to identify and splice these two types of connections.

    Tip

    An Xray can act as a bridge, a portal, or both at the same time, depending on the needs of different scenarios.

    Complete Configuration Example

    ::: tip During operation, it is recommended to enable bridge first, then enable portal. :::

    Bridge Configuration

    A bridge usually requires two outbounds, one for connecting to the portal, and the other for sending actual traffic. That is, you need to use routing to distinguish between the two types of traffic.

    Reverse proxy configuration:

    {\n  "bridges": [\n    {\n      "tag": "bridge",\n      "domain": "test.xray.com"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    outbound:

    {\n  "tag": "out",\n  "protocol": "freedom",\n  "settings": {\n    "redirect": "127.0.0.1:80" // Forward all traffic to web server\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    {\n  "protocol": "vmess",\n  "settings": {\n    "vnext": [\n      {\n        "address": "portal's IP address",\n        "port": 1024,\n        "users": [\n          {\n            "id": "5783a3e7-e373-51cd-8642-c83782b807c5"\n          }\n        ]\n      }\n    ]\n  },\n  "tag": "interconn"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    Routing Configuration:

    {\n  "rules": [\n    {\n      "type": "field",\n      "inboundTag": ["bridge"],\n      "domain": ["full:test.xray.com"],\n      "outboundTag": "interconn"\n    },\n    {\n      "type": "field",\n      "inboundTag": ["bridge"],\n      "outboundTag": "out"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    Portal Configuration

    portal usually requires two inbounds, one for receiving connections from bridge, and the other for receiving actual traffic. You also need to distinguish between these two types of traffic using routing.

    Reverse proxy configuration:

    {\n  "portals": [\n    {\n      "tag": "portal",\n      "domain": "test.xray.com" // Must be the same as the bridge's configuration\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    inbound:

    {\n  "tag": "external",\n  "port": 80,\n  "protocol": "dokodemo-door",\n  "settings": {\n    "address": "127.0.0.1",\n    "port": 80,\n    "network": "tcp"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {\n  "port": 1024,\n  "tag": "interconn",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "5783a3e7-e373-51cd-8642-c83782b807c5"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    Routing Configuration:

    {\n  "rules": [\n    {\n      "type": "field",\n      "inboundTag": ["external"],\n      "outboundTag": "portal"\n    },\n    {\n      "type": "field",\n      "inboundTag": ["interconn"],\n      "outboundTag": "portal"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ',23);l.render=function(r,c){const l=n("RouterLink");return s(),a(p,null,[u,e("p",null,[i,b,d,o(l,{to:"/en/config/routing.html"},{default:t((()=>[k])),_:1}),m]),q,e("p",null,[g,h,f,y,v,o(l,{to:"/en/config/routing.html"},{default:t((()=>[j])),_:1}),w,x,T]),A],64)};export default l; +import{r as n,o as s,c as a,a as e,b as o,w as t,F as p,d as r,e as c}from"./app.48111a85.js";const l={},u=r('

    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.

    {\n  "reverse": {\n    "bridges": [\n      {\n        "tag": "bridge",\n        "domain": "test.xray.com"\n      }\n    ],\n    "portals": [\n      {\n        "tag": "portal",\n        "domain": "test.xray.com"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    bridges: [BridgeObject]

    An array in which each item represents a bridge. The configuration of each bridge is a BridgeObject.

    portals: [PortalObject]

    An array in which each item represents a portal. The configuration of each portal is a PortalObject.

    BridgeObject

    {\n  "tag": "bridge",\n  "domain": "test.xray.com"\n}\n
    1
    2
    3
    4

    tag: string

    ',16),i=c("All connections initiated by "),b=e("code",null,"bridge",-1),d=c(" will have this tag. It can be used to identify the connections in "),k=c("routing configuration"),m=c("."),q=r('

    domain: string

    Specifies a domain name that will be used by bridge to send connections to portal. This domain name is only used for communication between bridge and portal, and does not need to actually exist.

    PortalObject

    {\n  "tag": "portal",\n  "domain": "test.xray.com"\n}\n
    1
    2
    3
    4

    tag: string

    ',5),g=c("The identifier for the "),h=e("code",null,"portal",-1),f=c(". Use "),y=e("code",null,"outboundTag",-1),v=c(" in "),j=c("routing configuration"),w=c(" to forward traffic to this "),x=e("code",null,"portal",-1),T=c("."),A=r('

    domain: string

    A domain name. When the portal receives traffic, if the destination domain of the traffic is this domain, the portal assumes that the current connection is a communication connection sent by the bridge. Other traffic will be considered as traffic that needs to be forwarded. The work of the portal is to identify and splice these two types of connections.

    Tip

    An Xray can act as a bridge, a portal, or both at the same time, depending on the needs of different scenarios.

    Complete Configuration Example

    ::: tip During operation, it is recommended to enable bridge first, then enable portal. :::

    Bridge Configuration

    A bridge usually requires two outbounds, one for connecting to the portal, and the other for sending actual traffic. That is, you need to use routing to distinguish between the two types of traffic.

    Reverse proxy configuration:

    {\n  "bridges": [\n    {\n      "tag": "bridge",\n      "domain": "test.xray.com"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    outbound:

    {\n  "tag": "out",\n  "protocol": "freedom",\n  "settings": {\n    "redirect": "127.0.0.1:80" // Forward all traffic to web server\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    {\n  "protocol": "vmess",\n  "settings": {\n    "vnext": [\n      {\n        "address": "portal's IP address",\n        "port": 1024,\n        "users": [\n          {\n            "id": "5783a3e7-e373-51cd-8642-c83782b807c5"\n          }\n        ]\n      }\n    ]\n  },\n  "tag": "interconn"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    Routing Configuration:

    {\n  "rules": [\n    {\n      "type": "field",\n      "inboundTag": ["bridge"],\n      "domain": ["full:test.xray.com"],\n      "outboundTag": "interconn"\n    },\n    {\n      "type": "field",\n      "inboundTag": ["bridge"],\n      "outboundTag": "out"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    Portal Configuration

    portal usually requires two inbounds, one for receiving connections from bridge, and the other for receiving actual traffic. You also need to distinguish between these two types of traffic using routing.

    Reverse proxy configuration:

    {\n  "portals": [\n    {\n      "tag": "portal",\n      "domain": "test.xray.com" // Must be the same as the bridge's configuration\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    inbound:

    {\n  "tag": "external",\n  "port": 80,\n  "protocol": "dokodemo-door",\n  "settings": {\n    "address": "127.0.0.1",\n    "port": 80,\n    "network": "tcp"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {\n  "port": 1024,\n  "tag": "interconn",\n  "protocol": "vmess",\n  "settings": {\n    "clients": [\n      {\n        "id": "5783a3e7-e373-51cd-8642-c83782b807c5"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    Routing Configuration:

    {\n  "rules": [\n    {\n      "type": "field",\n      "inboundTag": ["external"],\n      "outboundTag": "portal"\n    },\n    {\n      "type": "field",\n      "inboundTag": ["interconn"],\n      "outboundTag": "portal"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ',23);l.render=function(r,c){const l=n("RouterLink");return s(),a(p,null,[u,e("p",null,[i,b,d,o(l,{to:"/en/config/routing.html"},{default:t((()=>[k])),_:1}),m]),q,e("p",null,[g,h,f,y,v,o(l,{to:"/en/config/routing.html"},{default:t((()=>[j])),_:1}),w,x,T]),A],64)};export default l; diff --git a/assets/routing-lv1-part1.html.f80179a7.js b/assets/routing-lv1-part1.html.3298296e.js similarity index 99% rename from assets/routing-lv1-part1.html.f80179a7.js rename to assets/routing-lv1-part1.html.3298296e.js index efa87229a..0b3b60c94 100644 --- a/assets/routing-lv1-part1.html.f80179a7.js +++ b/assets/routing-lv1-part1.html.3298296e.js @@ -1 +1 @@ -import{r as n,o as s,c as a,b as l,a as e,w as t,F as o,e as r}from"./app.755d843f.js";const c={},p=e("h1",{id:"路由-routing-功能简析-上",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#路由-routing-功能简析-上","aria-hidden":"true"},"#"),r(" 路由 (routing) 功能简析(上)")],-1),u=e("p",null,"如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),i=e("h2",{id:"_1-初识【路由】三兄弟",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_1-初识【路由】三兄弟","aria-hidden":"true"},"#"),r(" 1. 初识【路由】三兄弟")],-1),d=e("p",null,[r("要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. "),e("strong",null,"入站"),r(";2. "),e("strong",null,"路由"),r(";3. "),e("strong",null,"出站"),r("。")],-1),b=e("p",null,[e("img",{src:"/Xray-docs-next/assets/routing-lv1-img01-trio.bfd35866.png",alt:"路由三兄弟"})],-1),k=e("p",null,"三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。",-1),g=e("p",null,"所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。",-1),m=e("p",null,"因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。",-1),y=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"啰嗦君"),e("p",null,"路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。")],-1),A=e("h2",{id:"_2-基本功-兄弟一条心",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-基本功-兄弟一条心","aria-hidden":"true"},"#"),r(" 2. 基本功: “兄弟一条心”")],-1),E=e("p",null,[r("下图的示例,就是在客户端的 "),e("code",null,"Xray"),r(" 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。")],-1),h=e("p",null,"下面我们来逐个分析:",-1),f=e("h3",{id:"_2-1-入站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-1-入站","aria-hidden":"true"},"#"),r(" 2.1 入站")],-1),B=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"提示"),e("p",null,[e("strong",null,"入站:"),r(" 就是流量如何流入 "),e("code",null,"Xray")])],-1),x=e("p",null,[r("下面的入站配置示例,用大白话说就是:数据按照 "),e("code",null,"socks"),r(" 协议,通过 "),e("code",null,"10808"),r(" 端口,从本机 "),e("code",null,"127.0.0.1"),r(" 流入"),e("code",null,"Xray"),r("。同时,"),e("code",null,"Xray"),r(" 将这个入站用 "),e("code",null,"[tag]"),r(" 命名为 "),e("code",null,"inbound-10808"),r("。")],-1),D=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"inbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"inbound-10808"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"socks"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"listen"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"127.0.0.1"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"10808"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"udp"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token boolean"},"true"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br")])],-1),v=e("p",null,[e("strong",null,"2.2 出站")],-1),_=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"提示"),e("p",null,[e("strong",null,"出站:"),r(" 就是流量如何流出 "),e("code",null,"Xray")])],-1),F=e("p",null,[r("下面的出站配置示例,用大白话说就是:数据按照 "),e("code",null,"VLESS"),r(" 协议,以 "),e("code",null,"tcp + xtls"),r(" 的方式、及其他相关设置,把流量发送给对应的 VPS。同时,"),e("code",null,"Xray"),r(" 将这个出站用 "),e("code",null,"[tag]"),r(" 命名为 "),e("code",null,"proxy-out-vless"),r(":")],-1),P=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"vless"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"vnext"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"address"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"a-name.yourdomain.com"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"443"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"users"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"id"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"uuiduuid-uuid-uuid-uuid-uuiduuiduuid"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"flow"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"xtls-rprx-vision"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"encryption"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"none"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"level"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"0"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"streamSettings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"network"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"tcp"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"security"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"tls"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"tlsSettings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"serverName"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"a-name.yourdomain.com"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"allowInsecure"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token boolean"},"false"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"fingerprint"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"chrome"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br")])],-1),S=e("h3",{id:"_2-3-路由",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-3-路由","aria-hidden":"true"},"#"),r(" 2.3 路由")],-1),X=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"提示"),e("p",null,[e("strong",null,"路由:"),r(" 就是把【入站】和【出站】之间的通道,用某种【条件】串联起来")])],-1),V=e("p",null,[r("下面的路由配置示例,用大白话说就是:把所有通过 "),e("code",null,'[tag]="inbound-10808"'),r(" 入站流入 "),e("code",null,"Xray"),r(" 的流量,"),e("code",null,"100%"),r(" 全部流转导入 "),e("code",null,'[tag]="proxy-out-vless"'),r(" 的出站,没有任何分流或其他操作。")],-1),O=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"routing"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"domainStrategy"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"AsIs"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"rules"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"inboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"inbound-10808"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br")])],-1),R=e("p",null,[r("至此,我们最开始设计的极简规则【客户端的 "),e("code",null,"Xray"),r(" 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS】已经完成。")],-1),j=e("h3",{id:"_2-4-路由配置项解析之一-流量筛选的依据",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-4-路由配置项解析之一-流量筛选的依据","aria-hidden":"true"},"#"),r(" 2.4 路由配置项解析之一:流量筛选的依据")],-1),C=e("p",null,"注意观察路由配置,我们可以看到几个新名词:",-1),I=e("ol",null,[e("li",null,[e("code",null,'"domainStrategy": "AsIs"')]),e("li",null,[e("code",null,"“rules”")]),e("li",null,[e("code",null,'"type": "field"')]),e("li",null,[e("code",null,'"inboundTag": ["inbound-10808"]')]),e("li",null,[e("code",null,'"outboundTag": "proxy-out-vless"')])],-1),L=e("p",null,[r("其中 "),e("code",null,"domainStrategy"),r(" 我们暂且按下不表,先简单说明后面几个:")],-1),w=e("table",null,[e("thead",null,[e("tr",null,[e("th",{style:{"text-align":"center"}},"配置名称"),e("th",{style:{"text-align":"center"}},"配置值"),e("th",{style:{"text-align":"left"}},"配置说明")])]),e("tbody",null,[e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"“rules”")]),e("td",{style:{"text-align":"center"}},"                                                   "),e("td",{style:{"text-align":"left"}},"它的内层就是【路由规则】的明细设置")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"type"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'"field"')]),e("td",{style:{"text-align":"left"}},"该项暂时没有特别定义,但是不能省略,所以记得写上就好")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"inboundTag"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'["inbound-10808"]')]),e("td",{style:{"text-align":"left"}},[r("筛选流量的 "),e("strong",null,"【依据】"),r(" 是【入站 Tag】,具体 "),e("strong",null,"【条件】"),r(" 现在只有一个:【入站来源是 "),e("code",null,"inbound-10808"),r("】")])]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"outboundTag"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'"proxy-out-vless"')]),e("td",{style:{"text-align":"left"}},[r("当上面的筛选条件成立时(即入站"),e("code",null,'[tag]="inbound-10808"'),r("时 ),"),e("code",null,"Xray"),r(" 会将流量导入 "),e("code",null,'[tag]="proxy-out-vless"'),r(" 的出站")])])])],-1),T=e("p",null,[r("本例中,我们只有一个入站,它的"),e("code",null,'"inboundTag" = "inbound-10808"'),r(" 。我们也只有一个出站,它的 "),e("code",null,'[tag]="proxy-out-vless"'),r("。所以根据上面这个路由规则,从唯一入站端口 "),e("code",null,"10808"),r(" 流入"),e("code",null,"Xray"),r("的流量,"),e("code",null,"100%"),r(" 符合筛选条件、会被路由模块选中,然后转发给唯一的出站。")],-1),q=e("p",null,[r("至此,"),e("strong",null,"入站"),r("、"),e("strong",null,"路由"),r("、"),e("strong",null,"出站"),r(" 三兄弟就已经可以携手工作了。当然,现在这个 100%转发的工作并没有什么特别的意义。那么接下来,我们就看看这种分工合作的机制可以带来什么好处。")],-1),G=e("h2",{id:"_3-小试牛刀-三分天下-之-域名分流",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-小试牛刀-三分天下-之-域名分流","aria-hidden":"true"},"#"),r(" 3. 小试牛刀: “三分天下” 之 “域名分流”")],-1),W=e("blockquote",null,[e("p",null,[e("code",null,"[geosite.dat]")])],-1),M=e("p",null,"这个配置逻辑,其实就是最简单、最常用的(《小小白白话文》中也在用的)路由配置三件套:",-1),N=e("ol",null,[e("li",null,[r("广告流量屏蔽 "),e("code",null,"[block]")]),e("li",null,[r("国内流量直连 "),e("code",null,"[direct]")]),e("li",null,[r("国外流量转发 VPS "),e("code",null,"[proxy]")])],-1),z=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,"小小白白话文中的直连配置是包括【国内域名】、【国内 IP】、【本机内部 IP】的。这里先讲解【国内域名】。")],-1),H=e("h3",{id:"_3-1-入站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-1-入站","aria-hidden":"true"},"#"),r(" 3.1 入站")],-1),J=e("p",null,[r("保持上例的 "),e("code",null,"inbound-10808"),r(" 不变。")],-1),K=e("h3",{id:"_3-2-出站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-2-出站","aria-hidden":"true"},"#"),r(" 3.2 出站")],-1),Q=e("p",null,[r("在上例的基础上,我们已经有了 "),e("code",null,"[proxy]"),r(" 的出站 "),e("code",null,'"proxy-out-vless"'),r(",所以它保持不变。显而易见,我们需要加入两个新的出站方式:"),e("code",null,"[block]"),r(" 和 "),e("code",null,"[direct]"),r(",如下:")],-1),U=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token comment"},"// ... ..."),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"blackhole"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"freedom"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br")])],-1),Y=e("p",null,"上面的配置用大白话翻译如下:",-1),Z=e("ol",null,[e("li",null,[r("上例中的 "),e("code",null,"[proxy-out-vless]"),r(" 出站配置保持不变")]),e("li",null,[r("加入 "),e("strong",null,[e("code",null,"blackhole"),r(" 黑洞协议")]),r(",通过这个协议出站的流量,其实都被发送到了 "),e("code",null,"Xray"),r(" 内部的黑洞里,再也无法逃脱,于是效果就是屏蔽 "),e("code",null,"[block]")]),e("li",null,[r("加入 "),e("strong",null,[e("code",null,"freedom"),r(" 自由协议")]),r(",通过这个协议出站的流量,是自由的离开"),e("code",null,"Xray"),r("去寻找原定的服务器,就像从没有来过,于是效果就是直连 "),e("code",null,"[direct]"),r(" (我这里起名叫做 "),e("code",null,"[direct-out]"),r(" 是为了强调它是一个出站)")])],-1),$=e("h3",{id:"_3-3-路由",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-3-路由","aria-hidden":"true"},"#"),r(" 3.3 路由")],-1),nn=e("p",null,"接下来就是见证奇迹的时刻了,我们可以用【路由】的配置把这些连接起来!",-1),sn=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"routing"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"domainStrategy"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"AsIs"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"rules"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:category-ads-all"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:cn"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:geolocation-!cn"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br")])],-1),an=e("p",null,"为了理解这个配置文件,我们要稍微解释一下这里出现的几个新配置项:",-1),ln=e("ul",null,[e("li",null,[e("code",null,'"domain": ["geosite:category-ads-all"]')]),e("li",null,[e("code",null,'"domain": ["geosite:cn"]')]),e("li",null,[e("code",null,'"domain": ["geosite:geolocation-!cn"]')])],-1),en=e("h3",{id:"_3-4-简析域名文件-geosite-dat",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-4-简析域名文件-geosite-dat","aria-hidden":"true"},"#"),r(" 3.4 简析域名文件: "),e("code",null,"geosite.dat")],-1),tn=e("p",null,"其实,聪明的你大概可以通过这些配置项的名称猜出来个大概:",-1),on=e("ul",null,[e("li",null,[e("code",null,'"domain"'),r(":就是这次筛选流量的 "),e("strong",null,"【依据】"),r(" 是 "),e("strong",null,"【域名】"),r(" (而不再是入站 tag)")]),e("li",null,[e("code",null,'"geosite"'),r(":就是 "),e("code",null,"Xray"),r(" 会去 "),e("code",null,"geosite.dat"),r(" 文件中寻找 "),e("strong",null,"【符合条件的域名】")]),e("li",null,[e("code",null,'"category-ads-all"'),r(":就是该文件中的 "),e("strong",null,"【所有广告类域名】")]),e("li",null,[e("code",null,'"cn"'),r(":就是该文件中的 "),e("strong",null,"【中国域名】")]),e("li",null,[e("code",null,'"geolocation-!cn"'),r(":就是该文件中的 "),e("strong",null,"【非中国域名】")])],-1),rn=e("p",null,"结合这些说明,3.3 中的配置用大白话翻译就是:",-1),cn=e("ol",null,[e("li",null,[r("APP 试图访问国外域名 "),e("code",null,'"domain": "geolocation-!cn"'),r(" 的流量,通过 "),e("code",null,"[proxy-out-vless]"),r(" 出站,转发至 VPS")]),e("li",null,[r("APP 试图访问国外域名广告域名 "),e("code",null,'"domain": "geosite:category-ads-all"'),r(" 的流量,通过 "),e("code",null,"[block]"),r(" 出站,转发至黑洞进行屏蔽")]),e("li",null,[r("APP 试图访问国内域名 "),e("code",null,'"domain": "geosite:cn"'),r(" 的流量,通过 "),e("code",null,"[direct-out]"),r(" 出站,自由离开完成直连")])],-1),pn=e("p",null,"这时,才让【路由功能】的好处稍微得到了一些展现。",-1),un=e("h3",{id:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗","aria-hidden":"true"},"#"),r(" 3.5 所以 "),e("code",null,"geosite.dat"),r(" 到底是什么?不是有个 "),e("code",null,"GFWList"),r(" 吗?")],-1),dn=e("p",null,"你想,这世界上的域名何止千万,如果我们每写一个基于【域名】匹配的路由规则,都要自己收集、手动输入域名,那效率将会何其低下!",-1),bn=e("p",null,[r("而如果所有的域名都只有一个种类,"),e("code",null,"[direct], [proxy], [block]"),r(" 只能三选其一,那又是多么的不方便!")],-1),kn=e("p",null,[r("就如关羽需要他的青龙偃月刀,"),e("code",null,"geosite.dat"),r(" 文件便作为【路由功能】驱使的神兵利器横空出世了,它致力于为用户提供成熟完善的【域名分类表】。让用户可以简单的通过 "),e("code",null,"geosite:xxx"),r(" 这种格式方便的调用任何子类,定制符合自身需求的路由规则。")],-1),gn=r("这种模块化结构提供的灵活性,其实远超传统的一揽子防火墙域名列表 "),mn={href:"https://github.com/gfwlist/gfwlist",target:"_blank",rel:"noopener noreferrer"},yn=e("code",null,"GFWList",-1),An=r("。为什么这么说呢?比如,你可以指定苹果的域名 "),En=e("code",null,"geosite:apple",-1),hn=r(" 和 icloud 相关域名 "),fn=e("code",null,"geosite:icloud",-1),Bn=r(" 通过代理 "),xn=e("code",null,"[proxy]",-1),Dn=r(",但是苹果的软件域名 "),vn=e("code",null,"geosite:apple-update",-1),_n=r(" 保持直连 "),Fn=e("code",null,"[direct]",-1),Pn=r(" 来保持最大下载速度。"),Sn={class:"custom-container warning"},Xn=e("p",{class:"custom-container-title"},"注意",-1),Vn=e("p",null,[e("strong",null,"注意:"),r(" 现在,"),e("code",null,"geosite.dat"),r(" 文件其实有多种选择:")],-1),On=r("最初,从 "),Rn=e("code",null,"Victoria Raymond",-1),jn=r(" 主力维护 "),Cn=e("code",null,"Project V",-1),In=r(" 项目时期,便提供了最初的配套项目:"),Ln={href:"https://github.com/v2ray/domain-list-community",target:"_blank",rel:"noopener noreferrer"},wn=e("code",null,"domain-list-community",-1),Tn=r(",用来收集、沉淀、分类各种常用的域名类型;"),qn=r("之后,随着 V 姐突然消失导致 "),Gn=e("code",null,"Project V",-1),Wn=r(" 的原项目开发陷入停滞,"),Mn=e("code",null,"v2fly",-1),Nn=r(" 社区维护并持续更新了社区版本的 "),zn={href:"https://github.com/v2fly/domain-list-community",target:"_blank",rel:"noopener noreferrer"},Hn=e("code",null,"domain-list-community",-1),Jn=r(";"),Kn=r("同时,"),Qn=e("a",{href:"Loyalsoldier"},"@Loyalsoldier",-1),Un=r(" 维护了其个人修改增强的路由规则文件 "),Yn={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},Zn=r("v2ray-rules-dat"),$n=r(",提供了诸多不同的选择和分类逻辑;"),ns=r("另外,"),ss=e("code",null,"Project X",-1),as=r(" 也计划于未来定制维护更适合 "),ls=e("code",null,"Xray",-1),es=r(" 使用的路由规则文件 "),ts={href:"https://github.com/XTLS/Xray-rules-dat",target:"_blank",rel:"noopener noreferrer"},os=r("Xray-rules-dat"),rs=r("。"),cs=e("s",null,"(你们看,文件夹都建好了,所以快了快了)",-1),ps=e("p",null,[r("甚至,你还可以定制自己的 "),e("code",null,"geosite"),r(" 文件,外挂给 "),e("code",null,"Xray"),r(" 使用,但是这个就跑题了,本文不展开。")],-1),us=e("p",null,[r("如果你发现有些你遇到的域名没有被合理分类,请向上面的项目们提出 "),e("code",null,"issue"),r(" 甚至提交 "),e("code",null,"Pull Request"),r(" 吧!社区列表社区维护,人人为我我为人人!")],-1),is=e("h3",{id:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-6-军师锦囊藏奇兵-一条隐藏的路由规则","aria-hidden":"true"},"#"),r(" 3.6 军师锦囊藏奇兵:一条隐藏的路由规则")],-1),ds=e("p",null,[r("事实上,当你认真思考上面的规则,不难发现一个问题,我们的所有规则都只规定了【当入站流量 "),e("strong",null,"符合某种条件时"),r(" 应该被转发给哪个出站】,那么,如果 "),e("code",null,"geosite.dat"),r(" 文件不全面,我们的入站流量【"),e("strong",null,"不符合任何条件时"),r("】,"),e("code",null,"Xray"),r(" 会怎么处理呢?")],-1),bs=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,[r("如果你认为【不符合条件当然就无法连接啦!】的话,你可要重新思考一下哦。因为只有指定了 "),e("code",null,"[block]"),r(" 规则,才会被导入到 "),e("code",null,"blackhole"),r(" 黑洞协议从而阻断连接")])],-1),ks=e("p",null,[r("事实上,"),e("code",null,"Xray"),r(" 为了避免路由规则不完全导致的规则混乱,已经贴心的提供了一条隐藏的路由规则:【"),e("strong",null,"当入站流量不符合任何条件时,转发给第一个出站"),r(" 】")],-1),gs=e("p",null,"这样,就不会有任何流量被漏掉了。所以,你一定要把你最信赖的心腹大将放在【第一条出站】,让它为你守城护池。",-1),ms=e("h3",{id:"_3-7-再看-三分天下-的大地图",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-7-再看-三分天下-的大地图","aria-hidden":"true"},"#"),r(" 3.7 再看“三分天下”的大地图")],-1),ys=e("p",null,[r("因为我们在前面的示例中把 "),e("code",null,"[proxy-out-vless]"),r(" 放在了出站的第一位,所以隐藏规则生效时,流量会通过 "),e("code",null,"VLESS"),r(" 协议被转发至远端的 VPS。因此,"),e("code",null,"Xray"),r(" 此时的完整工作逻辑如下:")],-1),As=e("p",null,[r("事实上,这就是传统所谓的 "),e("strong",null,"【默认科学上网、国内网站白名单直连】"),r(" 的配置。")],-1),Es=e("h2",{id:"_4-三分天下-之-蜀魏争雄",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_4-三分天下-之-蜀魏争雄","aria-hidden":"true"},"#"),r(" 4. “三分天下” 之 “蜀魏争雄”")],-1),hs=e("p",null,[r("现在,你已经知道了隐藏的默认路由规则:【"),e("strong",null,"当入站流量不符合任何条件时,转发给第一个出站"),r(" 】。这时候,你应该能看出来,究竟是【科学上网】为王,还是【直连】称霸,全看你的第一条出站是什么!")],-1),fs=e("p",null,[r("上一步我们已经配置出了 "),e("strong",null,"【默认科学上网、国内网站白名单直连】"),r(" 的规则。那么现在只要 "),e("strong",null,"【把直连规则放在第一位】"),r(",就立即变成了正好相反的 "),e("strong",null,"【默认直连、国外网站白名单科学上网】"),r(" 规则。")],-1),Bs=e("p",null,"是不是,非常地简单?",-1),xs=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"freedom"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token comment"},"// ... ..."),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"blackhole"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br")])],-1),Ds=e("p",null,"此时,路由规则其实变成了:",-1),vs=e("p",null,"这就是路由功能的灵活之处了,你可以自由的改变它的顺序来实现不同的设计。",-1),_s=e("p",null,[r("至此,我们已经解释完了 "),e("strong",null,[r("【如何利用 "),e("code",null,"geosite.dat"),r(" 文件,通过路由规则,根据【域名】来分流网络流量】。")])],-1),Fs=e("h2",{id:"_5-攻城略池-多种路由匹配条件",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-攻城略池-多种路由匹配条件","aria-hidden":"true"},"#"),r(" 5. 攻城略池 - 多种路由匹配条件")],-1),Ps=e("p",null,"请确保你已经读懂了上面的内容,因为这样,你就已经理解了【路由】功能的工作逻辑。有了这个基础,我们就可以继续分析【路由】功能更多更详细的配置方式和匹配条件了。",-1),Ss=r("等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 "),Xs=r("《路由 (routing) 功能简析(下)》"),Vs=r(" 吧!");c.render=function(r,c){const Os=n("Mermaid"),Rs=n("OutboundLink"),js=n("RouterLink");return s(),a(o,null,[p,u,i,d,b,k,g,m,y,A,E,l(Os,{identifier:"mermaid_382ee188",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%3E%20O%5B%E5%87%BA%E7%AB%99%5D%0A%20%20%20%20end%0A%0A%20%20%20%20O%20.-%3E%20V(VPS)%0A%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE%0A%0A"}),h,f,B,x,D,v,_,F,P,S,X,V,O,R,j,C,I,L,w,T,q,G,W,l(Os,{identifier:"mermaid_64a56ee8",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),M,N,z,H,J,K,Q,U,Y,Z,$,nn,sn,an,ln,en,tn,on,rn,cn,pn,un,dn,bn,kn,e("p",null,[gn,e("a",mn,[yn,l(Rs)]),An,En,hn,fn,Bn,xn,Dn,vn,_n,Fn,Pn]),e("div",Sn,[Xn,Vn,e("p",null,[On,Rn,jn,Cn,In,e("a",Ln,[wn,l(Rs)]),Tn]),e("p",null,[qn,Gn,Wn,Mn,Nn,e("a",zn,[Hn,l(Rs)]),Jn]),e("p",null,[Kn,Qn,Un,e("a",Yn,[Zn,l(Rs)]),$n]),e("p",null,[ns,ss,as,ls,es,e("a",ts,[os,l(Rs)]),rs,cs]),ps,us]),is,ds,bs,ks,gs,ms,ys,l(Os,{identifier:"mermaid_64a55fb4",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%20%20%20%20O4%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),As,Es,hs,fs,Bs,xs,Ds,l(Os,{identifier:"mermaid_64a55a22",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%20%20%20%20O4%20.-%3E%20D%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),vs,_s,Fs,Ps,e("p",null,[Ss,l(js,{to:"/document/level-1/routing-lv1-part2.html"},{default:t((()=>[Xs])),_:1}),Vs])],64)};export default c; +import{r as n,o as s,c as a,b as l,a as e,w as t,F as o,e as r}from"./app.48111a85.js";const c={},p=e("h1",{id:"路由-routing-功能简析-上",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#路由-routing-功能简析-上","aria-hidden":"true"},"#"),r(" 路由 (routing) 功能简析(上)")],-1),u=e("p",null,"如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),i=e("h2",{id:"_1-初识【路由】三兄弟",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_1-初识【路由】三兄弟","aria-hidden":"true"},"#"),r(" 1. 初识【路由】三兄弟")],-1),d=e("p",null,[r("要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. "),e("strong",null,"入站"),r(";2. "),e("strong",null,"路由"),r(";3. "),e("strong",null,"出站"),r("。")],-1),b=e("p",null,[e("img",{src:"/Xray-docs-next/assets/routing-lv1-img01-trio.bfd35866.png",alt:"路由三兄弟"})],-1),k=e("p",null,"三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。",-1),g=e("p",null,"所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。",-1),m=e("p",null,"因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。",-1),y=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"啰嗦君"),e("p",null,"路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。")],-1),A=e("h2",{id:"_2-基本功-兄弟一条心",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-基本功-兄弟一条心","aria-hidden":"true"},"#"),r(" 2. 基本功: “兄弟一条心”")],-1),E=e("p",null,[r("下图的示例,就是在客户端的 "),e("code",null,"Xray"),r(" 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。")],-1),h=e("p",null,"下面我们来逐个分析:",-1),f=e("h3",{id:"_2-1-入站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-1-入站","aria-hidden":"true"},"#"),r(" 2.1 入站")],-1),B=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"提示"),e("p",null,[e("strong",null,"入站:"),r(" 就是流量如何流入 "),e("code",null,"Xray")])],-1),x=e("p",null,[r("下面的入站配置示例,用大白话说就是:数据按照 "),e("code",null,"socks"),r(" 协议,通过 "),e("code",null,"10808"),r(" 端口,从本机 "),e("code",null,"127.0.0.1"),r(" 流入"),e("code",null,"Xray"),r("。同时,"),e("code",null,"Xray"),r(" 将这个入站用 "),e("code",null,"[tag]"),r(" 命名为 "),e("code",null,"inbound-10808"),r("。")],-1),D=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"inbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"inbound-10808"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"socks"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"listen"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"127.0.0.1"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"10808"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"udp"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token boolean"},"true"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br")])],-1),v=e("p",null,[e("strong",null,"2.2 出站")],-1),_=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"提示"),e("p",null,[e("strong",null,"出站:"),r(" 就是流量如何流出 "),e("code",null,"Xray")])],-1),F=e("p",null,[r("下面的出站配置示例,用大白话说就是:数据按照 "),e("code",null,"VLESS"),r(" 协议,以 "),e("code",null,"tcp + xtls"),r(" 的方式、及其他相关设置,把流量发送给对应的 VPS。同时,"),e("code",null,"Xray"),r(" 将这个出站用 "),e("code",null,"[tag]"),r(" 命名为 "),e("code",null,"proxy-out-vless"),r(":")],-1),P=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"vless"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"vnext"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"address"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"a-name.yourdomain.com"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"443"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"users"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"id"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"uuiduuid-uuid-uuid-uuid-uuiduuiduuid"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"flow"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"xtls-rprx-vision"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"encryption"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"none"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"level"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"0"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"streamSettings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"network"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"tcp"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"security"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"tls"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"tlsSettings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"serverName"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"a-name.yourdomain.com"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"allowInsecure"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token boolean"},"false"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"fingerprint"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"chrome"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br")])],-1),S=e("h3",{id:"_2-3-路由",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-3-路由","aria-hidden":"true"},"#"),r(" 2.3 路由")],-1),X=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"提示"),e("p",null,[e("strong",null,"路由:"),r(" 就是把【入站】和【出站】之间的通道,用某种【条件】串联起来")])],-1),V=e("p",null,[r("下面的路由配置示例,用大白话说就是:把所有通过 "),e("code",null,'[tag]="inbound-10808"'),r(" 入站流入 "),e("code",null,"Xray"),r(" 的流量,"),e("code",null,"100%"),r(" 全部流转导入 "),e("code",null,'[tag]="proxy-out-vless"'),r(" 的出站,没有任何分流或其他操作。")],-1),O=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"routing"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"domainStrategy"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"AsIs"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"rules"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"inboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"inbound-10808"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br")])],-1),R=e("p",null,[r("至此,我们最开始设计的极简规则【客户端的 "),e("code",null,"Xray"),r(" 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS】已经完成。")],-1),j=e("h3",{id:"_2-4-路由配置项解析之一-流量筛选的依据",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-4-路由配置项解析之一-流量筛选的依据","aria-hidden":"true"},"#"),r(" 2.4 路由配置项解析之一:流量筛选的依据")],-1),C=e("p",null,"注意观察路由配置,我们可以看到几个新名词:",-1),I=e("ol",null,[e("li",null,[e("code",null,'"domainStrategy": "AsIs"')]),e("li",null,[e("code",null,"“rules”")]),e("li",null,[e("code",null,'"type": "field"')]),e("li",null,[e("code",null,'"inboundTag": ["inbound-10808"]')]),e("li",null,[e("code",null,'"outboundTag": "proxy-out-vless"')])],-1),L=e("p",null,[r("其中 "),e("code",null,"domainStrategy"),r(" 我们暂且按下不表,先简单说明后面几个:")],-1),w=e("table",null,[e("thead",null,[e("tr",null,[e("th",{style:{"text-align":"center"}},"配置名称"),e("th",{style:{"text-align":"center"}},"配置值"),e("th",{style:{"text-align":"left"}},"配置说明")])]),e("tbody",null,[e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"“rules”")]),e("td",{style:{"text-align":"center"}},"                                                   "),e("td",{style:{"text-align":"left"}},"它的内层就是【路由规则】的明细设置")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"type"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'"field"')]),e("td",{style:{"text-align":"left"}},"该项暂时没有特别定义,但是不能省略,所以记得写上就好")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"inboundTag"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'["inbound-10808"]')]),e("td",{style:{"text-align":"left"}},[r("筛选流量的 "),e("strong",null,"【依据】"),r(" 是【入站 Tag】,具体 "),e("strong",null,"【条件】"),r(" 现在只有一个:【入站来源是 "),e("code",null,"inbound-10808"),r("】")])]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"outboundTag"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'"proxy-out-vless"')]),e("td",{style:{"text-align":"left"}},[r("当上面的筛选条件成立时(即入站"),e("code",null,'[tag]="inbound-10808"'),r("时 ),"),e("code",null,"Xray"),r(" 会将流量导入 "),e("code",null,'[tag]="proxy-out-vless"'),r(" 的出站")])])])],-1),T=e("p",null,[r("本例中,我们只有一个入站,它的"),e("code",null,'"inboundTag" = "inbound-10808"'),r(" 。我们也只有一个出站,它的 "),e("code",null,'[tag]="proxy-out-vless"'),r("。所以根据上面这个路由规则,从唯一入站端口 "),e("code",null,"10808"),r(" 流入"),e("code",null,"Xray"),r("的流量,"),e("code",null,"100%"),r(" 符合筛选条件、会被路由模块选中,然后转发给唯一的出站。")],-1),q=e("p",null,[r("至此,"),e("strong",null,"入站"),r("、"),e("strong",null,"路由"),r("、"),e("strong",null,"出站"),r(" 三兄弟就已经可以携手工作了。当然,现在这个 100%转发的工作并没有什么特别的意义。那么接下来,我们就看看这种分工合作的机制可以带来什么好处。")],-1),G=e("h2",{id:"_3-小试牛刀-三分天下-之-域名分流",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-小试牛刀-三分天下-之-域名分流","aria-hidden":"true"},"#"),r(" 3. 小试牛刀: “三分天下” 之 “域名分流”")],-1),W=e("blockquote",null,[e("p",null,[e("code",null,"[geosite.dat]")])],-1),M=e("p",null,"这个配置逻辑,其实就是最简单、最常用的(《小小白白话文》中也在用的)路由配置三件套:",-1),N=e("ol",null,[e("li",null,[r("广告流量屏蔽 "),e("code",null,"[block]")]),e("li",null,[r("国内流量直连 "),e("code",null,"[direct]")]),e("li",null,[r("国外流量转发 VPS "),e("code",null,"[proxy]")])],-1),z=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,"小小白白话文中的直连配置是包括【国内域名】、【国内 IP】、【本机内部 IP】的。这里先讲解【国内域名】。")],-1),H=e("h3",{id:"_3-1-入站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-1-入站","aria-hidden":"true"},"#"),r(" 3.1 入站")],-1),J=e("p",null,[r("保持上例的 "),e("code",null,"inbound-10808"),r(" 不变。")],-1),K=e("h3",{id:"_3-2-出站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-2-出站","aria-hidden":"true"},"#"),r(" 3.2 出站")],-1),Q=e("p",null,[r("在上例的基础上,我们已经有了 "),e("code",null,"[proxy]"),r(" 的出站 "),e("code",null,'"proxy-out-vless"'),r(",所以它保持不变。显而易见,我们需要加入两个新的出站方式:"),e("code",null,"[block]"),r(" 和 "),e("code",null,"[direct]"),r(",如下:")],-1),U=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token comment"},"// ... ..."),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"blackhole"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"freedom"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br")])],-1),Y=e("p",null,"上面的配置用大白话翻译如下:",-1),Z=e("ol",null,[e("li",null,[r("上例中的 "),e("code",null,"[proxy-out-vless]"),r(" 出站配置保持不变")]),e("li",null,[r("加入 "),e("strong",null,[e("code",null,"blackhole"),r(" 黑洞协议")]),r(",通过这个协议出站的流量,其实都被发送到了 "),e("code",null,"Xray"),r(" 内部的黑洞里,再也无法逃脱,于是效果就是屏蔽 "),e("code",null,"[block]")]),e("li",null,[r("加入 "),e("strong",null,[e("code",null,"freedom"),r(" 自由协议")]),r(",通过这个协议出站的流量,是自由的离开"),e("code",null,"Xray"),r("去寻找原定的服务器,就像从没有来过,于是效果就是直连 "),e("code",null,"[direct]"),r(" (我这里起名叫做 "),e("code",null,"[direct-out]"),r(" 是为了强调它是一个出站)")])],-1),$=e("h3",{id:"_3-3-路由",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-3-路由","aria-hidden":"true"},"#"),r(" 3.3 路由")],-1),nn=e("p",null,"接下来就是见证奇迹的时刻了,我们可以用【路由】的配置把这些连接起来!",-1),sn=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"routing"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"domainStrategy"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"AsIs"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"rules"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:category-ads-all"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:cn"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:geolocation-!cn"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br")])],-1),an=e("p",null,"为了理解这个配置文件,我们要稍微解释一下这里出现的几个新配置项:",-1),ln=e("ul",null,[e("li",null,[e("code",null,'"domain": ["geosite:category-ads-all"]')]),e("li",null,[e("code",null,'"domain": ["geosite:cn"]')]),e("li",null,[e("code",null,'"domain": ["geosite:geolocation-!cn"]')])],-1),en=e("h3",{id:"_3-4-简析域名文件-geosite-dat",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-4-简析域名文件-geosite-dat","aria-hidden":"true"},"#"),r(" 3.4 简析域名文件: "),e("code",null,"geosite.dat")],-1),tn=e("p",null,"其实,聪明的你大概可以通过这些配置项的名称猜出来个大概:",-1),on=e("ul",null,[e("li",null,[e("code",null,'"domain"'),r(":就是这次筛选流量的 "),e("strong",null,"【依据】"),r(" 是 "),e("strong",null,"【域名】"),r(" (而不再是入站 tag)")]),e("li",null,[e("code",null,'"geosite"'),r(":就是 "),e("code",null,"Xray"),r(" 会去 "),e("code",null,"geosite.dat"),r(" 文件中寻找 "),e("strong",null,"【符合条件的域名】")]),e("li",null,[e("code",null,'"category-ads-all"'),r(":就是该文件中的 "),e("strong",null,"【所有广告类域名】")]),e("li",null,[e("code",null,'"cn"'),r(":就是该文件中的 "),e("strong",null,"【中国域名】")]),e("li",null,[e("code",null,'"geolocation-!cn"'),r(":就是该文件中的 "),e("strong",null,"【非中国域名】")])],-1),rn=e("p",null,"结合这些说明,3.3 中的配置用大白话翻译就是:",-1),cn=e("ol",null,[e("li",null,[r("APP 试图访问国外域名 "),e("code",null,'"domain": "geolocation-!cn"'),r(" 的流量,通过 "),e("code",null,"[proxy-out-vless]"),r(" 出站,转发至 VPS")]),e("li",null,[r("APP 试图访问国外域名广告域名 "),e("code",null,'"domain": "geosite:category-ads-all"'),r(" 的流量,通过 "),e("code",null,"[block]"),r(" 出站,转发至黑洞进行屏蔽")]),e("li",null,[r("APP 试图访问国内域名 "),e("code",null,'"domain": "geosite:cn"'),r(" 的流量,通过 "),e("code",null,"[direct-out]"),r(" 出站,自由离开完成直连")])],-1),pn=e("p",null,"这时,才让【路由功能】的好处稍微得到了一些展现。",-1),un=e("h3",{id:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗","aria-hidden":"true"},"#"),r(" 3.5 所以 "),e("code",null,"geosite.dat"),r(" 到底是什么?不是有个 "),e("code",null,"GFWList"),r(" 吗?")],-1),dn=e("p",null,"你想,这世界上的域名何止千万,如果我们每写一个基于【域名】匹配的路由规则,都要自己收集、手动输入域名,那效率将会何其低下!",-1),bn=e("p",null,[r("而如果所有的域名都只有一个种类,"),e("code",null,"[direct], [proxy], [block]"),r(" 只能三选其一,那又是多么的不方便!")],-1),kn=e("p",null,[r("就如关羽需要他的青龙偃月刀,"),e("code",null,"geosite.dat"),r(" 文件便作为【路由功能】驱使的神兵利器横空出世了,它致力于为用户提供成熟完善的【域名分类表】。让用户可以简单的通过 "),e("code",null,"geosite:xxx"),r(" 这种格式方便的调用任何子类,定制符合自身需求的路由规则。")],-1),gn=r("这种模块化结构提供的灵活性,其实远超传统的一揽子防火墙域名列表 "),mn={href:"https://github.com/gfwlist/gfwlist",target:"_blank",rel:"noopener noreferrer"},yn=e("code",null,"GFWList",-1),An=r("。为什么这么说呢?比如,你可以指定苹果的域名 "),En=e("code",null,"geosite:apple",-1),hn=r(" 和 icloud 相关域名 "),fn=e("code",null,"geosite:icloud",-1),Bn=r(" 通过代理 "),xn=e("code",null,"[proxy]",-1),Dn=r(",但是苹果的软件域名 "),vn=e("code",null,"geosite:apple-update",-1),_n=r(" 保持直连 "),Fn=e("code",null,"[direct]",-1),Pn=r(" 来保持最大下载速度。"),Sn={class:"custom-container warning"},Xn=e("p",{class:"custom-container-title"},"注意",-1),Vn=e("p",null,[e("strong",null,"注意:"),r(" 现在,"),e("code",null,"geosite.dat"),r(" 文件其实有多种选择:")],-1),On=r("最初,从 "),Rn=e("code",null,"Victoria Raymond",-1),jn=r(" 主力维护 "),Cn=e("code",null,"Project V",-1),In=r(" 项目时期,便提供了最初的配套项目:"),Ln={href:"https://github.com/v2ray/domain-list-community",target:"_blank",rel:"noopener noreferrer"},wn=e("code",null,"domain-list-community",-1),Tn=r(",用来收集、沉淀、分类各种常用的域名类型;"),qn=r("之后,随着 V 姐突然消失导致 "),Gn=e("code",null,"Project V",-1),Wn=r(" 的原项目开发陷入停滞,"),Mn=e("code",null,"v2fly",-1),Nn=r(" 社区维护并持续更新了社区版本的 "),zn={href:"https://github.com/v2fly/domain-list-community",target:"_blank",rel:"noopener noreferrer"},Hn=e("code",null,"domain-list-community",-1),Jn=r(";"),Kn=r("同时,"),Qn=e("a",{href:"Loyalsoldier"},"@Loyalsoldier",-1),Un=r(" 维护了其个人修改增强的路由规则文件 "),Yn={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},Zn=r("v2ray-rules-dat"),$n=r(",提供了诸多不同的选择和分类逻辑;"),ns=r("另外,"),ss=e("code",null,"Project X",-1),as=r(" 也计划于未来定制维护更适合 "),ls=e("code",null,"Xray",-1),es=r(" 使用的路由规则文件 "),ts={href:"https://github.com/XTLS/Xray-rules-dat",target:"_blank",rel:"noopener noreferrer"},os=r("Xray-rules-dat"),rs=r("。"),cs=e("s",null,"(你们看,文件夹都建好了,所以快了快了)",-1),ps=e("p",null,[r("甚至,你还可以定制自己的 "),e("code",null,"geosite"),r(" 文件,外挂给 "),e("code",null,"Xray"),r(" 使用,但是这个就跑题了,本文不展开。")],-1),us=e("p",null,[r("如果你发现有些你遇到的域名没有被合理分类,请向上面的项目们提出 "),e("code",null,"issue"),r(" 甚至提交 "),e("code",null,"Pull Request"),r(" 吧!社区列表社区维护,人人为我我为人人!")],-1),is=e("h3",{id:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-6-军师锦囊藏奇兵-一条隐藏的路由规则","aria-hidden":"true"},"#"),r(" 3.6 军师锦囊藏奇兵:一条隐藏的路由规则")],-1),ds=e("p",null,[r("事实上,当你认真思考上面的规则,不难发现一个问题,我们的所有规则都只规定了【当入站流量 "),e("strong",null,"符合某种条件时"),r(" 应该被转发给哪个出站】,那么,如果 "),e("code",null,"geosite.dat"),r(" 文件不全面,我们的入站流量【"),e("strong",null,"不符合任何条件时"),r("】,"),e("code",null,"Xray"),r(" 会怎么处理呢?")],-1),bs=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,[r("如果你认为【不符合条件当然就无法连接啦!】的话,你可要重新思考一下哦。因为只有指定了 "),e("code",null,"[block]"),r(" 规则,才会被导入到 "),e("code",null,"blackhole"),r(" 黑洞协议从而阻断连接")])],-1),ks=e("p",null,[r("事实上,"),e("code",null,"Xray"),r(" 为了避免路由规则不完全导致的规则混乱,已经贴心的提供了一条隐藏的路由规则:【"),e("strong",null,"当入站流量不符合任何条件时,转发给第一个出站"),r(" 】")],-1),gs=e("p",null,"这样,就不会有任何流量被漏掉了。所以,你一定要把你最信赖的心腹大将放在【第一条出站】,让它为你守城护池。",-1),ms=e("h3",{id:"_3-7-再看-三分天下-的大地图",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-7-再看-三分天下-的大地图","aria-hidden":"true"},"#"),r(" 3.7 再看“三分天下”的大地图")],-1),ys=e("p",null,[r("因为我们在前面的示例中把 "),e("code",null,"[proxy-out-vless]"),r(" 放在了出站的第一位,所以隐藏规则生效时,流量会通过 "),e("code",null,"VLESS"),r(" 协议被转发至远端的 VPS。因此,"),e("code",null,"Xray"),r(" 此时的完整工作逻辑如下:")],-1),As=e("p",null,[r("事实上,这就是传统所谓的 "),e("strong",null,"【默认科学上网、国内网站白名单直连】"),r(" 的配置。")],-1),Es=e("h2",{id:"_4-三分天下-之-蜀魏争雄",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_4-三分天下-之-蜀魏争雄","aria-hidden":"true"},"#"),r(" 4. “三分天下” 之 “蜀魏争雄”")],-1),hs=e("p",null,[r("现在,你已经知道了隐藏的默认路由规则:【"),e("strong",null,"当入站流量不符合任何条件时,转发给第一个出站"),r(" 】。这时候,你应该能看出来,究竟是【科学上网】为王,还是【直连】称霸,全看你的第一条出站是什么!")],-1),fs=e("p",null,[r("上一步我们已经配置出了 "),e("strong",null,"【默认科学上网、国内网站白名单直连】"),r(" 的规则。那么现在只要 "),e("strong",null,"【把直连规则放在第一位】"),r(",就立即变成了正好相反的 "),e("strong",null,"【默认直连、国外网站白名单科学上网】"),r(" 规则。")],-1),Bs=e("p",null,"是不是,非常地简单?",-1),xs=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"freedom"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token comment"},"// ... ..."),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"blackhole"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br")])],-1),Ds=e("p",null,"此时,路由规则其实变成了:",-1),vs=e("p",null,"这就是路由功能的灵活之处了,你可以自由的改变它的顺序来实现不同的设计。",-1),_s=e("p",null,[r("至此,我们已经解释完了 "),e("strong",null,[r("【如何利用 "),e("code",null,"geosite.dat"),r(" 文件,通过路由规则,根据【域名】来分流网络流量】。")])],-1),Fs=e("h2",{id:"_5-攻城略池-多种路由匹配条件",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-攻城略池-多种路由匹配条件","aria-hidden":"true"},"#"),r(" 5. 攻城略池 - 多种路由匹配条件")],-1),Ps=e("p",null,"请确保你已经读懂了上面的内容,因为这样,你就已经理解了【路由】功能的工作逻辑。有了这个基础,我们就可以继续分析【路由】功能更多更详细的配置方式和匹配条件了。",-1),Ss=r("等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 "),Xs=r("《路由 (routing) 功能简析(下)》"),Vs=r(" 吧!");c.render=function(r,c){const Os=n("Mermaid"),Rs=n("OutboundLink"),js=n("RouterLink");return s(),a(o,null,[p,u,i,d,b,k,g,m,y,A,E,l(Os,{identifier:"mermaid_382ee188",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%3E%20O%5B%E5%87%BA%E7%AB%99%5D%0A%20%20%20%20end%0A%0A%20%20%20%20O%20.-%3E%20V(VPS)%0A%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE%0A%0A"}),h,f,B,x,D,v,_,F,P,S,X,V,O,R,j,C,I,L,w,T,q,G,W,l(Os,{identifier:"mermaid_64a56ee8",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),M,N,z,H,J,K,Q,U,Y,Z,$,nn,sn,an,ln,en,tn,on,rn,cn,pn,un,dn,bn,kn,e("p",null,[gn,e("a",mn,[yn,l(Rs)]),An,En,hn,fn,Bn,xn,Dn,vn,_n,Fn,Pn]),e("div",Sn,[Xn,Vn,e("p",null,[On,Rn,jn,Cn,In,e("a",Ln,[wn,l(Rs)]),Tn]),e("p",null,[qn,Gn,Wn,Mn,Nn,e("a",zn,[Hn,l(Rs)]),Jn]),e("p",null,[Kn,Qn,Un,e("a",Yn,[Zn,l(Rs)]),$n]),e("p",null,[ns,ss,as,ls,es,e("a",ts,[os,l(Rs)]),rs,cs]),ps,us]),is,ds,bs,ks,gs,ms,ys,l(Os,{identifier:"mermaid_64a55fb4",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%20%20%20%20O4%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),As,Es,hs,fs,Bs,xs,Ds,l(Os,{identifier:"mermaid_64a55a22",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%20%20%20%20O4%20.-%3E%20D%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),vs,_s,Fs,Ps,e("p",null,[Ss,l(js,{to:"/document/level-1/routing-lv1-part2.html"},{default:t((()=>[Xs])),_:1}),Vs])],64)};export default c; diff --git a/assets/routing-lv1-part1.html.f622db3d.js b/assets/routing-lv1-part1.html.5b85fc64.js similarity index 99% rename from assets/routing-lv1-part1.html.f622db3d.js rename to assets/routing-lv1-part1.html.5b85fc64.js index 7991afacd..a80ee0a5c 100644 --- a/assets/routing-lv1-part1.html.f622db3d.js +++ b/assets/routing-lv1-part1.html.5b85fc64.js @@ -1 +1 @@ -import{r as n,o as s,c as a,b as l,a as e,w as t,F as o,e as r}from"./app.755d843f.js";const c={},p=e("h1",{id:"路由-routing-功能简析-上",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#路由-routing-功能简析-上","aria-hidden":"true"},"#"),r(" 路由 (routing) 功能简析(上)")],-1),u=e("p",null,"如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),i=e("h2",{id:"_1-初识【路由】三兄弟",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_1-初识【路由】三兄弟","aria-hidden":"true"},"#"),r(" 1. 初识【路由】三兄弟")],-1),d=e("p",null,[r("要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. "),e("strong",null,"入站"),r(";2. "),e("strong",null,"路由"),r(";3. "),e("strong",null,"出站"),r("。")],-1),b=e("p",null,[e("img",{src:"/Xray-docs-next/assets/routing-lv1-img01-trio.bfd35866.png",alt:"路由三兄弟"})],-1),k=e("p",null,"三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。",-1),g=e("p",null,"所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。",-1),m=e("p",null,"因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。",-1),y=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"啰嗦君"),e("p",null,"路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。")],-1),A=e("h2",{id:"_2-基本功-兄弟一条心",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-基本功-兄弟一条心","aria-hidden":"true"},"#"),r(" 2. 基本功: “兄弟一条心”")],-1),E=e("p",null,[r("下图的示例,就是在客户端的 "),e("code",null,"Xray"),r(" 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。")],-1),h=e("p",null,"下面我们来逐个分析:",-1),f=e("h3",{id:"_2-1-入站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-1-入站","aria-hidden":"true"},"#"),r(" 2.1 入站")],-1),B=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"Tip"),e("p",null,[e("strong",null,"入站:"),r(" 就是流量如何流入 "),e("code",null,"Xray")])],-1),x=e("p",null,[r("下面的入站配置示例,用大白话说就是:数据按照 "),e("code",null,"socks"),r(" 协议,通过 "),e("code",null,"10808"),r(" 端口,从本机 "),e("code",null,"127.0.0.1"),r(" 流入"),e("code",null,"Xray"),r("。同时,"),e("code",null,"Xray"),r(" 将这个入站用 "),e("code",null,"[tag]"),r(" 命名为 "),e("code",null,"inbound-10808"),r("。")],-1),D=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"inbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"inbound-10808"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"socks"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"listen"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"127.0.0.1"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"10808"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"udp"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token boolean"},"true"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br")])],-1),v=e("p",null,[e("strong",null,"2.2 出站")],-1),_=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"Tip"),e("p",null,[e("strong",null,"出站:"),r(" 就是流量如何流出 "),e("code",null,"Xray")])],-1),F=e("p",null,[r("下面的出站配置示例,用大白话说就是:数据按照 "),e("code",null,"VLESS"),r(" 协议,以 "),e("code",null,"tcp + xtls"),r(" 的方式、及其他相关设置,把流量发送给对应的 VPS。同时,"),e("code",null,"Xray"),r(" 将这个出站用 "),e("code",null,"[tag]"),r(" 命名为 "),e("code",null,"proxy-out-vless"),r(":")],-1),P=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"vless"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"vnext"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"address"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"a-name.yourdomain.com"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"443"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"users"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"id"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"uuiduuid-uuid-uuid-uuid-uuiduuiduuid"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"flow"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"xtls-rprx-vision"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"encryption"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"none"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"level"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"0"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"streamSettings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"network"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"tcp"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"security"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"tls"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"tlsSettings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"serverName"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"a-name.yourdomain.com"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"allowInsecure"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token boolean"},"false"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"fingerprint"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"chrome"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br")])],-1),S=e("h3",{id:"_2-3-路由",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-3-路由","aria-hidden":"true"},"#"),r(" 2.3 路由")],-1),X=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"Tip"),e("p",null,[e("strong",null,"路由:"),r(" 就是把【入站】和【出站】之间的通道,用某种【条件】串联起来")])],-1),V=e("p",null,[r("下面的路由配置示例,用大白话说就是:把所有通过 "),e("code",null,'[tag]="inbound-10808"'),r(" 入站流入 "),e("code",null,"Xray"),r(" 的流量,"),e("code",null,"100%"),r(" 全部流转导入 "),e("code",null,'[tag]="proxy-out-vless"'),r(" 的出站,没有任何分流或其他操作。")],-1),O=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"routing"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"domainStrategy"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"AsIs"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"rules"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"inboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"inbound-10808"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br")])],-1),R=e("p",null,[r("至此,我们最开始设计的极简规则【客户端的 "),e("code",null,"Xray"),r(" 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS】已经完成。")],-1),j=e("h3",{id:"_2-4-路由配置项解析之一-流量筛选的依据",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-4-路由配置项解析之一-流量筛选的依据","aria-hidden":"true"},"#"),r(" 2.4 路由配置项解析之一:流量筛选的依据")],-1),C=e("p",null,"注意观察路由配置,我们可以看到几个新名词:",-1),T=e("ol",null,[e("li",null,[e("code",null,'"domainStrategy": "AsIs"')]),e("li",null,[e("code",null,"“rules”")]),e("li",null,[e("code",null,'"type": "field"')]),e("li",null,[e("code",null,'"inboundTag": ["inbound-10808"]')]),e("li",null,[e("code",null,'"outboundTag": "proxy-out-vless"')])],-1),I=e("p",null,[r("其中 "),e("code",null,"domainStrategy"),r(" 我们暂且按下不表,先简单说明后面几个:")],-1),L=e("table",null,[e("thead",null,[e("tr",null,[e("th",{style:{"text-align":"center"}},"配置名称"),e("th",{style:{"text-align":"center"}},"配置值"),e("th",{style:{"text-align":"left"}},"配置说明")])]),e("tbody",null,[e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"“rules”")]),e("td",{style:{"text-align":"center"}},"                                                   "),e("td",{style:{"text-align":"left"}},"它的内层就是【路由规则】的明细设置")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"type"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'"field"')]),e("td",{style:{"text-align":"left"}},"该项暂时没有特别定义,但是不能省略,所以记得写上就好")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"inboundTag"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'["inbound-10808"]')]),e("td",{style:{"text-align":"left"}},[r("筛选流量的 "),e("strong",null,"【依据】"),r(" 是【入站 Tag】,具体 "),e("strong",null,"【条件】"),r(" 现在只有一个:【入站来源是 "),e("code",null,"inbound-10808"),r("】")])]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"outboundTag"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'"proxy-out-vless"')]),e("td",{style:{"text-align":"left"}},[r("当上面的筛选条件成立时(即入站"),e("code",null,'[tag]="inbound-10808"'),r("时 ),"),e("code",null,"Xray"),r(" 会将流量导入 "),e("code",null,'[tag]="proxy-out-vless"'),r(" 的出站")])])])],-1),w=e("p",null,[r("本例中,我们只有一个入站,它的"),e("code",null,'"inboundTag" = "inbound-10808"'),r(" 。我们也只有一个出站,它的 "),e("code",null,'[tag]="proxy-out-vless"'),r("。所以根据上面这个路由规则,从唯一入站端口 "),e("code",null,"10808"),r(" 流入"),e("code",null,"Xray"),r("的流量,"),e("code",null,"100%"),r(" 符合筛选条件、会被路由模块选中,然后转发给唯一的出站。")],-1),W=e("p",null,[r("至此,"),e("strong",null,"入站"),r("、"),e("strong",null,"路由"),r("、"),e("strong",null,"出站"),r(" 三兄弟就已经可以携手工作了。当然,现在这个 100%转发的工作并没有什么特别的意义。那么接下来,我们就看看这种分工合作的机制可以带来什么好处。")],-1),q=e("h2",{id:"_3-小试牛刀-三分天下-之-域名分流",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-小试牛刀-三分天下-之-域名分流","aria-hidden":"true"},"#"),r(" 3. 小试牛刀: “三分天下” 之 “域名分流”")],-1),G=e("blockquote",null,[e("p",null,[e("code",null,"[geosite.dat]")])],-1),M=e("p",null,"这个配置逻辑,其实就是最简单、最常用的(《小小白白话文》中也在用的)路由配置三件套:",-1),N=e("ol",null,[e("li",null,[r("广告流量屏蔽 "),e("code",null,"[block]")]),e("li",null,[r("国内流量直连 "),e("code",null,"[direct]")]),e("li",null,[r("国外流量转发 VPS "),e("code",null,"[proxy]")])],-1),z=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,"小小白白话文中的直连配置是包括【国内域名】、【国内 IP】、【本机内部 IP】的。这里先讲解【国内域名】。")],-1),H=e("h3",{id:"_3-1-入站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-1-入站","aria-hidden":"true"},"#"),r(" 3.1 入站")],-1),J=e("p",null,[r("保持上例的 "),e("code",null,"inbound-10808"),r(" 不变。")],-1),K=e("h3",{id:"_3-2-出站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-2-出站","aria-hidden":"true"},"#"),r(" 3.2 出站")],-1),Q=e("p",null,[r("在上例的基础上,我们已经有了 "),e("code",null,"[proxy]"),r(" 的出站 "),e("code",null,'"proxy-out-vless"'),r(",所以它保持不变。显而易见,我们需要加入两个新的出站方式:"),e("code",null,"[block]"),r(" 和 "),e("code",null,"[direct]"),r(",如下:")],-1),U=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token comment"},"// ... ..."),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"blackhole"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"freedom"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br")])],-1),Y=e("p",null,"上面的配置用大白话翻译如下:",-1),Z=e("ol",null,[e("li",null,[r("上例中的 "),e("code",null,"[proxy-out-vless]"),r(" 出站配置保持不变")]),e("li",null,[r("加入 "),e("strong",null,[e("code",null,"blackhole"),r(" 黑洞协议")]),r(",通过这个协议出站的流量,其实都被发送到了 "),e("code",null,"Xray"),r(" 内部的黑洞里,再也无法逃脱,于是效果就是屏蔽 "),e("code",null,"[block]")]),e("li",null,[r("加入 "),e("strong",null,[e("code",null,"freedom"),r(" 自由协议")]),r(",通过这个协议出站的流量,是自由的离开"),e("code",null,"Xray"),r("去寻找原定的服务器,就像从没有来过,于是效果就是直连 "),e("code",null,"[direct]"),r(" (我这里起名叫做 "),e("code",null,"[direct-out]"),r(" 是为了强调它是一个出站)")])],-1),$=e("h3",{id:"_3-3-路由",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-3-路由","aria-hidden":"true"},"#"),r(" 3.3 路由")],-1),nn=e("p",null,"接下来就是见证奇迹的时刻了,我们可以用【路由】的配置把这些连接起来!",-1),sn=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"routing"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"domainStrategy"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"AsIs"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"rules"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:category-ads-all"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:cn"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:geolocation-!cn"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br")])],-1),an=e("p",null,"为了理解这个配置文件,我们要稍微解释一下这里出现的几个新配置项:",-1),ln=e("ul",null,[e("li",null,[e("code",null,'"domain": ["geosite:category-ads-all"]')]),e("li",null,[e("code",null,'"domain": ["geosite:cn"]')]),e("li",null,[e("code",null,'"domain": ["geosite:geolocation-!cn"]')])],-1),en=e("h3",{id:"_3-4-简析域名文件-geosite-dat",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-4-简析域名文件-geosite-dat","aria-hidden":"true"},"#"),r(" 3.4 简析域名文件: "),e("code",null,"geosite.dat")],-1),tn=e("p",null,"其实,聪明的你大概可以通过这些配置项的名称猜出来个大概:",-1),on=e("ul",null,[e("li",null,[e("code",null,'"domain"'),r(":就是这次筛选流量的 "),e("strong",null,"【依据】"),r(" 是 "),e("strong",null,"【域名】"),r(" (而不再是入站 tag)")]),e("li",null,[e("code",null,'"geosite"'),r(":就是 "),e("code",null,"Xray"),r(" 会去 "),e("code",null,"geosite.dat"),r(" 文件中寻找 "),e("strong",null,"【符合条件的域名】")]),e("li",null,[e("code",null,'"category-ads-all"'),r(":就是该文件中的 "),e("strong",null,"【所有广告类域名】")]),e("li",null,[e("code",null,'"cn"'),r(":就是该文件中的 "),e("strong",null,"【中国域名】")]),e("li",null,[e("code",null,'"geolocation-!cn"'),r(":就是该文件中的 "),e("strong",null,"【非中国域名】")])],-1),rn=e("p",null,"结合这些说明,3.3 中的配置用大白话翻译就是:",-1),cn=e("ol",null,[e("li",null,[r("APP 试图访问国外域名 "),e("code",null,'"domain": "geolocation-!cn"'),r(" 的流量,通过 "),e("code",null,"[proxy-out-vless]"),r(" 出站,转发至 VPS")]),e("li",null,[r("APP 试图访问国外域名广告域名 "),e("code",null,'"domain": "geosite:category-ads-all"'),r(" 的流量,通过 "),e("code",null,"[block]"),r(" 出站,转发至黑洞进行屏蔽")]),e("li",null,[r("APP 试图访问国内域名 "),e("code",null,'"domain": "geosite:cn"'),r(" 的流量,通过 "),e("code",null,"[direct-out]"),r(" 出站,自由离开完成直连")])],-1),pn=e("p",null,"这时,才让【路由功能】的好处稍微得到了一些展现。",-1),un=e("h3",{id:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗","aria-hidden":"true"},"#"),r(" 3.5 所以 "),e("code",null,"geosite.dat"),r(" 到底是什么?不是有个 "),e("code",null,"GFWList"),r(" 吗?")],-1),dn=e("p",null,"你想,这世界上的域名何止千万,如果我们每写一个基于【域名】匹配的路由规则,都要自己收集、手动输入域名,那效率将会何其低下!",-1),bn=e("p",null,[r("而如果所有的域名都只有一个种类,"),e("code",null,"[direct], [proxy], [block]"),r(" 只能三选其一,那又是多么的不方便!")],-1),kn=e("p",null,[r("就如关羽需要他的青龙偃月刀,"),e("code",null,"geosite.dat"),r(" 文件便作为【路由功能】驱使的神兵利器横空出世了,它致力于为用户提供成熟完善的【域名分类表】。让用户可以简单的通过 "),e("code",null,"geosite:xxx"),r(" 这种格式方便的调用任何子类,定制符合自身需求的路由规则。")],-1),gn=r("这种模块化结构提供的灵活性,其实远超传统的一揽子防火墙域名列表 "),mn={href:"https://github.com/gfwlist/gfwlist",target:"_blank",rel:"noopener noreferrer"},yn=e("code",null,"GFWList",-1),An=r("。为什么这么说呢?比如,你可以指定苹果的域名 "),En=e("code",null,"geosite:apple",-1),hn=r(" 和 icloud 相关域名 "),fn=e("code",null,"geosite:icloud",-1),Bn=r(" 通过代理 "),xn=e("code",null,"[proxy]",-1),Dn=r(",但是苹果的软件域名 "),vn=e("code",null,"geosite:apple-update",-1),_n=r(" 保持直连 "),Fn=e("code",null,"[direct]",-1),Pn=r(" 来保持最大下载速度。"),Sn={class:"custom-container warning"},Xn=e("p",{class:"custom-container-title"},"Warning",-1),Vn=e("p",null,[e("strong",null,"注意:"),r(" 现在,"),e("code",null,"geosite.dat"),r(" 文件其实有多种选择:")],-1),On=r("最初,从 "),Rn=e("code",null,"Victoria Raymond",-1),jn=r(" 主力维护 "),Cn=e("code",null,"Project V",-1),Tn=r(" 项目时期,便提供了最初的配套项目:"),In={href:"https://github.com/v2ray/domain-list-community",target:"_blank",rel:"noopener noreferrer"},Ln=e("code",null,"domain-list-community",-1),wn=r(",用来收集、沉淀、分类各种常用的域名类型;"),Wn=r("之后,随着 V 姐突然消失导致 "),qn=e("code",null,"Project V",-1),Gn=r(" 的原项目开发陷入停滞,"),Mn=e("code",null,"v2fly",-1),Nn=r(" 社区维护并持续更新了社区版本的 "),zn={href:"https://github.com/v2fly/domain-list-community",target:"_blank",rel:"noopener noreferrer"},Hn=e("code",null,"domain-list-community",-1),Jn=r(";"),Kn=r("同时,"),Qn=e("a",{href:"Loyalsoldier"},"@Loyalsoldier",-1),Un=r(" 维护了其个人修改增强的路由规则文件 "),Yn={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},Zn=r("v2ray-rules-dat"),$n=r(",提供了诸多不同的选择和分类逻辑;"),ns=r("另外,"),ss=e("code",null,"Project X",-1),as=r(" 也计划于未来定制维护更适合 "),ls=e("code",null,"Xray",-1),es=r(" 使用的路由规则文件 "),ts={href:"https://github.com/XTLS/Xray-rules-dat",target:"_blank",rel:"noopener noreferrer"},os=r("Xray-rules-dat"),rs=r("。"),cs=e("s",null,"(你们看,文件夹都建好了,所以快了快了)",-1),ps=e("p",null,[r("甚至,你还可以定制自己的 "),e("code",null,"geosite"),r(" 文件,外挂给 "),e("code",null,"Xray"),r(" 使用,但是这个就跑题了,本文不展开。")],-1),us=e("p",null,[r("如果你发现有些你遇到的域名没有被合理分类,请向上面的项目们提出 "),e("code",null,"issue"),r(" 甚至提交 "),e("code",null,"Pull Request"),r(" 吧!社区列表社区维护,人人为我我为人人!")],-1),is=e("h3",{id:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-6-军师锦囊藏奇兵-一条隐藏的路由规则","aria-hidden":"true"},"#"),r(" 3.6 军师锦囊藏奇兵:一条隐藏的路由规则")],-1),ds=e("p",null,[r("事实上,当你认真思考上面的规则,不难发现一个问题,我们的所有规则都只规定了【当入站流量 "),e("strong",null,"符合某种条件时"),r(" 应该被转发给哪个出站】,那么,如果 "),e("code",null,"geosite.dat"),r(" 文件不全面,我们的入站流量【"),e("strong",null,"不符合任何条件时"),r("】,"),e("code",null,"Xray"),r(" 会怎么处理呢?")],-1),bs=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,[r("如果你认为【不符合条件当然就无法连接啦!】的话,你可要重新思考一下哦。因为只有指定了 "),e("code",null,"[block]"),r(" 规则,才会被导入到 "),e("code",null,"blackhole"),r(" 黑洞协议从而阻断连接")])],-1),ks=e("p",null,[r("事实上,"),e("code",null,"Xray"),r(" 为了避免路由规则不完全导致的规则混乱,已经贴心的提供了一条隐藏的路由规则:【"),e("strong",null,"当入站流量不符合任何条件时,转发给第一个出站"),r(" 】")],-1),gs=e("p",null,"这样,就不会有任何流量被漏掉了。所以,你一定要把你最信赖的心腹大将放在【第一条出站】,让它为你守城护池。",-1),ms=e("h3",{id:"_3-7-再看-三分天下-的大地图",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-7-再看-三分天下-的大地图","aria-hidden":"true"},"#"),r(" 3.7 再看“三分天下”的大地图")],-1),ys=e("p",null,[r("因为我们在前面的示例中把 "),e("code",null,"[proxy-out-vless]"),r(" 放在了出站的第一位,所以隐藏规则生效时,流量会通过 "),e("code",null,"VLESS"),r(" 协议被转发至远端的 VPS。因此,"),e("code",null,"Xray"),r(" 此时的完整工作逻辑如下:")],-1),As=e("p",null,[r("事实上,这就是传统所谓的 "),e("strong",null,"【默认科学上网、国内网站白名单直连】"),r(" 的配置。")],-1),Es=e("h2",{id:"_4-三分天下-之-蜀魏争雄",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_4-三分天下-之-蜀魏争雄","aria-hidden":"true"},"#"),r(" 4. “三分天下” 之 “蜀魏争雄”")],-1),hs=e("p",null,[r("现在,你已经知道了隐藏的默认路由规则:【"),e("strong",null,"当入站流量不符合任何条件时,转发给第一个出站"),r(" 】。这时候,你应该能看出来,究竟是【科学上网】为王,还是【直连】称霸,全看你的第一条出站是什么!")],-1),fs=e("p",null,[r("上一步我们已经配置出了 "),e("strong",null,"【默认科学上网、国内网站白名单直连】"),r(" 的规则。那么现在只要 "),e("strong",null,"【把直连规则放在第一位】"),r(",就立即变成了正好相反的 "),e("strong",null,"【默认直连、国外网站白名单科学上网】"),r(" 规则。")],-1),Bs=e("p",null,"是不是,非常地简单?",-1),xs=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"freedom"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token comment"},"// ... ..."),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"blackhole"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br")])],-1),Ds=e("p",null,"此时,路由规则其实变成了:",-1),vs=e("p",null,"这就是路由功能的灵活之处了,你可以自由的改变它的顺序来实现不同的设计。",-1),_s=e("p",null,[r("至此,我们已经解释完了 "),e("strong",null,[r("【如何利用 "),e("code",null,"geosite.dat"),r(" 文件,通过路由规则,根据【域名】来分流网络流量】。")])],-1),Fs=e("h2",{id:"_5-攻城略池-多种路由匹配条件",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-攻城略池-多种路由匹配条件","aria-hidden":"true"},"#"),r(" 5. 攻城略池 - 多种路由匹配条件")],-1),Ps=e("p",null,"请确保你已经读懂了上面的内容,因为这样,你就已经理解了【路由】功能的工作逻辑。有了这个基础,我们就可以继续分析【路由】功能更多更详细的配置方式和匹配条件了。",-1),Ss=r("等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 "),Xs=r("《路由 (routing) 功能简析(下)》"),Vs=r(" 吧!");c.render=function(r,c){const Os=n("Mermaid"),Rs=n("OutboundLink"),js=n("RouterLink");return s(),a(o,null,[p,u,i,d,b,k,g,m,y,A,E,l(Os,{identifier:"mermaid_382ee188",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%3E%20O%5B%E5%87%BA%E7%AB%99%5D%0A%20%20%20%20end%0A%0A%20%20%20%20O%20.-%3E%20V(VPS)%0A%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE%0A%0A"}),h,f,B,x,D,v,_,F,P,S,X,V,O,R,j,C,T,I,L,w,W,q,G,l(Os,{identifier:"mermaid_64a56ee8",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),M,N,z,H,J,K,Q,U,Y,Z,$,nn,sn,an,ln,en,tn,on,rn,cn,pn,un,dn,bn,kn,e("p",null,[gn,e("a",mn,[yn,l(Rs)]),An,En,hn,fn,Bn,xn,Dn,vn,_n,Fn,Pn]),e("div",Sn,[Xn,Vn,e("p",null,[On,Rn,jn,Cn,Tn,e("a",In,[Ln,l(Rs)]),wn]),e("p",null,[Wn,qn,Gn,Mn,Nn,e("a",zn,[Hn,l(Rs)]),Jn]),e("p",null,[Kn,Qn,Un,e("a",Yn,[Zn,l(Rs)]),$n]),e("p",null,[ns,ss,as,ls,es,e("a",ts,[os,l(Rs)]),rs,cs]),ps,us]),is,ds,bs,ks,gs,ms,ys,l(Os,{identifier:"mermaid_64a55fb4",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%20%20%20%20O4%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),As,Es,hs,fs,Bs,xs,Ds,l(Os,{identifier:"mermaid_64a55a22",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%20%20%20%20O4%20.-%3E%20D%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),vs,_s,Fs,Ps,e("p",null,[Ss,l(js,{to:"/en/document/level-1/routing-lv1-part2.html"},{default:t((()=>[Xs])),_:1}),Vs])],64)};export default c; +import{r as n,o as s,c as a,b as l,a as e,w as t,F as o,e as r}from"./app.48111a85.js";const c={},p=e("h1",{id:"路由-routing-功能简析-上",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#路由-routing-功能简析-上","aria-hidden":"true"},"#"),r(" 路由 (routing) 功能简析(上)")],-1),u=e("p",null,"如果说 Xray 的【强大】主要体现在它极致的速度和广泛的兼容性。那么 Xray 的【灵活】,则主要应该归功于它巧妙的【路由】功能。本文就稍微说明一下这个功能的逻辑以及使用方式。",-1),i=e("h2",{id:"_1-初识【路由】三兄弟",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_1-初识【路由】三兄弟","aria-hidden":"true"},"#"),r(" 1. 初识【路由】三兄弟")],-1),d=e("p",null,[r("要理解路由,就要理解完整的路由功能需要有三兄弟来合力完成:1. "),e("strong",null,"入站"),r(";2. "),e("strong",null,"路由"),r(";3. "),e("strong",null,"出站"),r("。")],-1),b=e("p",null,[e("img",{src:"/Xray-docs-next/assets/routing-lv1-img01-trio.bfd35866.png",alt:"路由三兄弟"})],-1),k=e("p",null,"三兄弟桃园结义,不求同年同月同日生,但求同年同月同日死。",-1),g=e("p",null,"所以谨记:任何一个元素错误,就可能导致路由功能无法正常工作。",-1),m=e("p",null,"因为路由的灵活性非常高,只看技术文档很容易把自己绕晕,所以本文我们用几个具体的示例来逐层讲解。",-1),y=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"啰嗦君"),e("p",null,"路由功能实在过于灵活,所以本文的示例,都是为了讲解对应的概念,实际使用时请根据自己的需求进行调整。")],-1),A=e("h2",{id:"_2-基本功-兄弟一条心",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-基本功-兄弟一条心","aria-hidden":"true"},"#"),r(" 2. 基本功: “兄弟一条心”")],-1),E=e("p",null,[r("下图的示例,就是在客户端的 "),e("code",null,"Xray"),r(" 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS。")],-1),h=e("p",null,"下面我们来逐个分析:",-1),f=e("h3",{id:"_2-1-入站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-1-入站","aria-hidden":"true"},"#"),r(" 2.1 入站")],-1),B=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"Tip"),e("p",null,[e("strong",null,"入站:"),r(" 就是流量如何流入 "),e("code",null,"Xray")])],-1),x=e("p",null,[r("下面的入站配置示例,用大白话说就是:数据按照 "),e("code",null,"socks"),r(" 协议,通过 "),e("code",null,"10808"),r(" 端口,从本机 "),e("code",null,"127.0.0.1"),r(" 流入"),e("code",null,"Xray"),r("。同时,"),e("code",null,"Xray"),r(" 将这个入站用 "),e("code",null,"[tag]"),r(" 命名为 "),e("code",null,"inbound-10808"),r("。")],-1),D=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"inbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"inbound-10808"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"socks"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"listen"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"127.0.0.1"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"10808"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"udp"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token boolean"},"true"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br")])],-1),v=e("p",null,[e("strong",null,"2.2 出站")],-1),_=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"Tip"),e("p",null,[e("strong",null,"出站:"),r(" 就是流量如何流出 "),e("code",null,"Xray")])],-1),F=e("p",null,[r("下面的出站配置示例,用大白话说就是:数据按照 "),e("code",null,"VLESS"),r(" 协议,以 "),e("code",null,"tcp + xtls"),r(" 的方式、及其他相关设置,把流量发送给对应的 VPS。同时,"),e("code",null,"Xray"),r(" 将这个出站用 "),e("code",null,"[tag]"),r(" 命名为 "),e("code",null,"proxy-out-vless"),r(":")],-1),P=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"vless"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"settings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"vnext"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"address"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"a-name.yourdomain.com"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"port"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"443"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"users"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"id"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"uuiduuid-uuid-uuid-uuid-uuiduuiduuid"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"flow"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"xtls-rprx-vision"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"encryption"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"none"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"level"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token number"},"0"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"streamSettings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"network"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"tcp"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"security"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"tls"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"tlsSettings"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"serverName"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"a-name.yourdomain.com"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"allowInsecure"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token boolean"},"false"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"fingerprint"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"chrome"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br"),e("span",{class:"line-number"},"23"),e("br"),e("span",{class:"line-number"},"24"),e("br"),e("span",{class:"line-number"},"25"),e("br"),e("span",{class:"line-number"},"26"),e("br"),e("span",{class:"line-number"},"27"),e("br"),e("span",{class:"line-number"},"28"),e("br"),e("span",{class:"line-number"},"29"),e("br"),e("span",{class:"line-number"},"30"),e("br"),e("span",{class:"line-number"},"31"),e("br"),e("span",{class:"line-number"},"32"),e("br"),e("span",{class:"line-number"},"33"),e("br")])],-1),S=e("h3",{id:"_2-3-路由",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-3-路由","aria-hidden":"true"},"#"),r(" 2.3 路由")],-1),X=e("div",{class:"custom-container tip"},[e("p",{class:"custom-container-title"},"Tip"),e("p",null,[e("strong",null,"路由:"),r(" 就是把【入站】和【出站】之间的通道,用某种【条件】串联起来")])],-1),V=e("p",null,[r("下面的路由配置示例,用大白话说就是:把所有通过 "),e("code",null,'[tag]="inbound-10808"'),r(" 入站流入 "),e("code",null,"Xray"),r(" 的流量,"),e("code",null,"100%"),r(" 全部流转导入 "),e("code",null,'[tag]="proxy-out-vless"'),r(" 的出站,没有任何分流或其他操作。")],-1),O=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"routing"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"domainStrategy"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"AsIs"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"rules"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"inboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"inbound-10808"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br")])],-1),R=e("p",null,[r("至此,我们最开始设计的极简规则【客户端的 "),e("code",null,"Xray"),r(" 入站接收 APP 数据、在路由 100%转发给出站,并从出站流向 VPS】已经完成。")],-1),j=e("h3",{id:"_2-4-路由配置项解析之一-流量筛选的依据",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_2-4-路由配置项解析之一-流量筛选的依据","aria-hidden":"true"},"#"),r(" 2.4 路由配置项解析之一:流量筛选的依据")],-1),C=e("p",null,"注意观察路由配置,我们可以看到几个新名词:",-1),T=e("ol",null,[e("li",null,[e("code",null,'"domainStrategy": "AsIs"')]),e("li",null,[e("code",null,"“rules”")]),e("li",null,[e("code",null,'"type": "field"')]),e("li",null,[e("code",null,'"inboundTag": ["inbound-10808"]')]),e("li",null,[e("code",null,'"outboundTag": "proxy-out-vless"')])],-1),I=e("p",null,[r("其中 "),e("code",null,"domainStrategy"),r(" 我们暂且按下不表,先简单说明后面几个:")],-1),L=e("table",null,[e("thead",null,[e("tr",null,[e("th",{style:{"text-align":"center"}},"配置名称"),e("th",{style:{"text-align":"center"}},"配置值"),e("th",{style:{"text-align":"left"}},"配置说明")])]),e("tbody",null,[e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,"“rules”")]),e("td",{style:{"text-align":"center"}},"                                                   "),e("td",{style:{"text-align":"left"}},"它的内层就是【路由规则】的明细设置")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"type"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'"field"')]),e("td",{style:{"text-align":"left"}},"该项暂时没有特别定义,但是不能省略,所以记得写上就好")]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"inboundTag"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'["inbound-10808"]')]),e("td",{style:{"text-align":"left"}},[r("筛选流量的 "),e("strong",null,"【依据】"),r(" 是【入站 Tag】,具体 "),e("strong",null,"【条件】"),r(" 现在只有一个:【入站来源是 "),e("code",null,"inbound-10808"),r("】")])]),e("tr",null,[e("td",{style:{"text-align":"center"}},[e("code",null,'"outboundTag"')]),e("td",{style:{"text-align":"center"}},[e("code",null,'"proxy-out-vless"')]),e("td",{style:{"text-align":"left"}},[r("当上面的筛选条件成立时(即入站"),e("code",null,'[tag]="inbound-10808"'),r("时 ),"),e("code",null,"Xray"),r(" 会将流量导入 "),e("code",null,'[tag]="proxy-out-vless"'),r(" 的出站")])])])],-1),w=e("p",null,[r("本例中,我们只有一个入站,它的"),e("code",null,'"inboundTag" = "inbound-10808"'),r(" 。我们也只有一个出站,它的 "),e("code",null,'[tag]="proxy-out-vless"'),r("。所以根据上面这个路由规则,从唯一入站端口 "),e("code",null,"10808"),r(" 流入"),e("code",null,"Xray"),r("的流量,"),e("code",null,"100%"),r(" 符合筛选条件、会被路由模块选中,然后转发给唯一的出站。")],-1),W=e("p",null,[r("至此,"),e("strong",null,"入站"),r("、"),e("strong",null,"路由"),r("、"),e("strong",null,"出站"),r(" 三兄弟就已经可以携手工作了。当然,现在这个 100%转发的工作并没有什么特别的意义。那么接下来,我们就看看这种分工合作的机制可以带来什么好处。")],-1),q=e("h2",{id:"_3-小试牛刀-三分天下-之-域名分流",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-小试牛刀-三分天下-之-域名分流","aria-hidden":"true"},"#"),r(" 3. 小试牛刀: “三分天下” 之 “域名分流”")],-1),G=e("blockquote",null,[e("p",null,[e("code",null,"[geosite.dat]")])],-1),M=e("p",null,"这个配置逻辑,其实就是最简单、最常用的(《小小白白话文》中也在用的)路由配置三件套:",-1),N=e("ol",null,[e("li",null,[r("广告流量屏蔽 "),e("code",null,"[block]")]),e("li",null,[r("国内流量直连 "),e("code",null,"[direct]")]),e("li",null,[r("国外流量转发 VPS "),e("code",null,"[proxy]")])],-1),z=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,"小小白白话文中的直连配置是包括【国内域名】、【国内 IP】、【本机内部 IP】的。这里先讲解【国内域名】。")],-1),H=e("h3",{id:"_3-1-入站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-1-入站","aria-hidden":"true"},"#"),r(" 3.1 入站")],-1),J=e("p",null,[r("保持上例的 "),e("code",null,"inbound-10808"),r(" 不变。")],-1),K=e("h3",{id:"_3-2-出站",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-2-出站","aria-hidden":"true"},"#"),r(" 3.2 出站")],-1),Q=e("p",null,[r("在上例的基础上,我们已经有了 "),e("code",null,"[proxy]"),r(" 的出站 "),e("code",null,'"proxy-out-vless"'),r(",所以它保持不变。显而易见,我们需要加入两个新的出站方式:"),e("code",null,"[block]"),r(" 和 "),e("code",null,"[direct]"),r(",如下:")],-1),U=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token comment"},"// ... ..."),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"blackhole"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"freedom"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br")])],-1),Y=e("p",null,"上面的配置用大白话翻译如下:",-1),Z=e("ol",null,[e("li",null,[r("上例中的 "),e("code",null,"[proxy-out-vless]"),r(" 出站配置保持不变")]),e("li",null,[r("加入 "),e("strong",null,[e("code",null,"blackhole"),r(" 黑洞协议")]),r(",通过这个协议出站的流量,其实都被发送到了 "),e("code",null,"Xray"),r(" 内部的黑洞里,再也无法逃脱,于是效果就是屏蔽 "),e("code",null,"[block]")]),e("li",null,[r("加入 "),e("strong",null,[e("code",null,"freedom"),r(" 自由协议")]),r(",通过这个协议出站的流量,是自由的离开"),e("code",null,"Xray"),r("去寻找原定的服务器,就像从没有来过,于是效果就是直连 "),e("code",null,"[direct]"),r(" (我这里起名叫做 "),e("code",null,"[direct-out]"),r(" 是为了强调它是一个出站)")])],-1),$=e("h3",{id:"_3-3-路由",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-3-路由","aria-hidden":"true"},"#"),r(" 3.3 路由")],-1),nn=e("p",null,"接下来就是见证奇迹的时刻了,我们可以用【路由】的配置把这些连接起来!",-1),sn=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"routing"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"domainStrategy"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"AsIs"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"rules"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:category-ads-all"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:cn"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"type"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"field"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"domain"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),e("span",{class:"token string"},'"geosite:geolocation-!cn"'),e("span",{class:"token punctuation"},"]"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"outboundTag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br"),e("span",{class:"line-number"},"17"),e("br"),e("span",{class:"line-number"},"18"),e("br"),e("span",{class:"line-number"},"19"),e("br"),e("span",{class:"line-number"},"20"),e("br"),e("span",{class:"line-number"},"21"),e("br"),e("span",{class:"line-number"},"22"),e("br")])],-1),an=e("p",null,"为了理解这个配置文件,我们要稍微解释一下这里出现的几个新配置项:",-1),ln=e("ul",null,[e("li",null,[e("code",null,'"domain": ["geosite:category-ads-all"]')]),e("li",null,[e("code",null,'"domain": ["geosite:cn"]')]),e("li",null,[e("code",null,'"domain": ["geosite:geolocation-!cn"]')])],-1),en=e("h3",{id:"_3-4-简析域名文件-geosite-dat",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-4-简析域名文件-geosite-dat","aria-hidden":"true"},"#"),r(" 3.4 简析域名文件: "),e("code",null,"geosite.dat")],-1),tn=e("p",null,"其实,聪明的你大概可以通过这些配置项的名称猜出来个大概:",-1),on=e("ul",null,[e("li",null,[e("code",null,'"domain"'),r(":就是这次筛选流量的 "),e("strong",null,"【依据】"),r(" 是 "),e("strong",null,"【域名】"),r(" (而不再是入站 tag)")]),e("li",null,[e("code",null,'"geosite"'),r(":就是 "),e("code",null,"Xray"),r(" 会去 "),e("code",null,"geosite.dat"),r(" 文件中寻找 "),e("strong",null,"【符合条件的域名】")]),e("li",null,[e("code",null,'"category-ads-all"'),r(":就是该文件中的 "),e("strong",null,"【所有广告类域名】")]),e("li",null,[e("code",null,'"cn"'),r(":就是该文件中的 "),e("strong",null,"【中国域名】")]),e("li",null,[e("code",null,'"geolocation-!cn"'),r(":就是该文件中的 "),e("strong",null,"【非中国域名】")])],-1),rn=e("p",null,"结合这些说明,3.3 中的配置用大白话翻译就是:",-1),cn=e("ol",null,[e("li",null,[r("APP 试图访问国外域名 "),e("code",null,'"domain": "geolocation-!cn"'),r(" 的流量,通过 "),e("code",null,"[proxy-out-vless]"),r(" 出站,转发至 VPS")]),e("li",null,[r("APP 试图访问国外域名广告域名 "),e("code",null,'"domain": "geosite:category-ads-all"'),r(" 的流量,通过 "),e("code",null,"[block]"),r(" 出站,转发至黑洞进行屏蔽")]),e("li",null,[r("APP 试图访问国内域名 "),e("code",null,'"domain": "geosite:cn"'),r(" 的流量,通过 "),e("code",null,"[direct-out]"),r(" 出站,自由离开完成直连")])],-1),pn=e("p",null,"这时,才让【路由功能】的好处稍微得到了一些展现。",-1),un=e("h3",{id:"_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-5-所以-geosite-dat-到底是什么-不是有个-gfwlist-吗","aria-hidden":"true"},"#"),r(" 3.5 所以 "),e("code",null,"geosite.dat"),r(" 到底是什么?不是有个 "),e("code",null,"GFWList"),r(" 吗?")],-1),dn=e("p",null,"你想,这世界上的域名何止千万,如果我们每写一个基于【域名】匹配的路由规则,都要自己收集、手动输入域名,那效率将会何其低下!",-1),bn=e("p",null,[r("而如果所有的域名都只有一个种类,"),e("code",null,"[direct], [proxy], [block]"),r(" 只能三选其一,那又是多么的不方便!")],-1),kn=e("p",null,[r("就如关羽需要他的青龙偃月刀,"),e("code",null,"geosite.dat"),r(" 文件便作为【路由功能】驱使的神兵利器横空出世了,它致力于为用户提供成熟完善的【域名分类表】。让用户可以简单的通过 "),e("code",null,"geosite:xxx"),r(" 这种格式方便的调用任何子类,定制符合自身需求的路由规则。")],-1),gn=r("这种模块化结构提供的灵活性,其实远超传统的一揽子防火墙域名列表 "),mn={href:"https://github.com/gfwlist/gfwlist",target:"_blank",rel:"noopener noreferrer"},yn=e("code",null,"GFWList",-1),An=r("。为什么这么说呢?比如,你可以指定苹果的域名 "),En=e("code",null,"geosite:apple",-1),hn=r(" 和 icloud 相关域名 "),fn=e("code",null,"geosite:icloud",-1),Bn=r(" 通过代理 "),xn=e("code",null,"[proxy]",-1),Dn=r(",但是苹果的软件域名 "),vn=e("code",null,"geosite:apple-update",-1),_n=r(" 保持直连 "),Fn=e("code",null,"[direct]",-1),Pn=r(" 来保持最大下载速度。"),Sn={class:"custom-container warning"},Xn=e("p",{class:"custom-container-title"},"Warning",-1),Vn=e("p",null,[e("strong",null,"注意:"),r(" 现在,"),e("code",null,"geosite.dat"),r(" 文件其实有多种选择:")],-1),On=r("最初,从 "),Rn=e("code",null,"Victoria Raymond",-1),jn=r(" 主力维护 "),Cn=e("code",null,"Project V",-1),Tn=r(" 项目时期,便提供了最初的配套项目:"),In={href:"https://github.com/v2ray/domain-list-community",target:"_blank",rel:"noopener noreferrer"},Ln=e("code",null,"domain-list-community",-1),wn=r(",用来收集、沉淀、分类各种常用的域名类型;"),Wn=r("之后,随着 V 姐突然消失导致 "),qn=e("code",null,"Project V",-1),Gn=r(" 的原项目开发陷入停滞,"),Mn=e("code",null,"v2fly",-1),Nn=r(" 社区维护并持续更新了社区版本的 "),zn={href:"https://github.com/v2fly/domain-list-community",target:"_blank",rel:"noopener noreferrer"},Hn=e("code",null,"domain-list-community",-1),Jn=r(";"),Kn=r("同时,"),Qn=e("a",{href:"Loyalsoldier"},"@Loyalsoldier",-1),Un=r(" 维护了其个人修改增强的路由规则文件 "),Yn={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},Zn=r("v2ray-rules-dat"),$n=r(",提供了诸多不同的选择和分类逻辑;"),ns=r("另外,"),ss=e("code",null,"Project X",-1),as=r(" 也计划于未来定制维护更适合 "),ls=e("code",null,"Xray",-1),es=r(" 使用的路由规则文件 "),ts={href:"https://github.com/XTLS/Xray-rules-dat",target:"_blank",rel:"noopener noreferrer"},os=r("Xray-rules-dat"),rs=r("。"),cs=e("s",null,"(你们看,文件夹都建好了,所以快了快了)",-1),ps=e("p",null,[r("甚至,你还可以定制自己的 "),e("code",null,"geosite"),r(" 文件,外挂给 "),e("code",null,"Xray"),r(" 使用,但是这个就跑题了,本文不展开。")],-1),us=e("p",null,[r("如果你发现有些你遇到的域名没有被合理分类,请向上面的项目们提出 "),e("code",null,"issue"),r(" 甚至提交 "),e("code",null,"Pull Request"),r(" 吧!社区列表社区维护,人人为我我为人人!")],-1),is=e("h3",{id:"_3-6-军师锦囊藏奇兵-一条隐藏的路由规则",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-6-军师锦囊藏奇兵-一条隐藏的路由规则","aria-hidden":"true"},"#"),r(" 3.6 军师锦囊藏奇兵:一条隐藏的路由规则")],-1),ds=e("p",null,[r("事实上,当你认真思考上面的规则,不难发现一个问题,我们的所有规则都只规定了【当入站流量 "),e("strong",null,"符合某种条件时"),r(" 应该被转发给哪个出站】,那么,如果 "),e("code",null,"geosite.dat"),r(" 文件不全面,我们的入站流量【"),e("strong",null,"不符合任何条件时"),r("】,"),e("code",null,"Xray"),r(" 会怎么处理呢?")],-1),bs=e("div",{class:"custom-container warning"},[e("p",{class:"custom-container-title"},"注意"),e("p",null,[r("如果你认为【不符合条件当然就无法连接啦!】的话,你可要重新思考一下哦。因为只有指定了 "),e("code",null,"[block]"),r(" 规则,才会被导入到 "),e("code",null,"blackhole"),r(" 黑洞协议从而阻断连接")])],-1),ks=e("p",null,[r("事实上,"),e("code",null,"Xray"),r(" 为了避免路由规则不完全导致的规则混乱,已经贴心的提供了一条隐藏的路由规则:【"),e("strong",null,"当入站流量不符合任何条件时,转发给第一个出站"),r(" 】")],-1),gs=e("p",null,"这样,就不会有任何流量被漏掉了。所以,你一定要把你最信赖的心腹大将放在【第一条出站】,让它为你守城护池。",-1),ms=e("h3",{id:"_3-7-再看-三分天下-的大地图",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_3-7-再看-三分天下-的大地图","aria-hidden":"true"},"#"),r(" 3.7 再看“三分天下”的大地图")],-1),ys=e("p",null,[r("因为我们在前面的示例中把 "),e("code",null,"[proxy-out-vless]"),r(" 放在了出站的第一位,所以隐藏规则生效时,流量会通过 "),e("code",null,"VLESS"),r(" 协议被转发至远端的 VPS。因此,"),e("code",null,"Xray"),r(" 此时的完整工作逻辑如下:")],-1),As=e("p",null,[r("事实上,这就是传统所谓的 "),e("strong",null,"【默认科学上网、国内网站白名单直连】"),r(" 的配置。")],-1),Es=e("h2",{id:"_4-三分天下-之-蜀魏争雄",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_4-三分天下-之-蜀魏争雄","aria-hidden":"true"},"#"),r(" 4. “三分天下” 之 “蜀魏争雄”")],-1),hs=e("p",null,[r("现在,你已经知道了隐藏的默认路由规则:【"),e("strong",null,"当入站流量不符合任何条件时,转发给第一个出站"),r(" 】。这时候,你应该能看出来,究竟是【科学上网】为王,还是【直连】称霸,全看你的第一条出站是什么!")],-1),fs=e("p",null,[r("上一步我们已经配置出了 "),e("strong",null,"【默认科学上网、国内网站白名单直连】"),r(" 的规则。那么现在只要 "),e("strong",null,"【把直连规则放在第一位】"),r(",就立即变成了正好相反的 "),e("strong",null,"【默认直连、国外网站白名单科学上网】"),r(" 规则。")],-1),Bs=e("p",null,"是不是,非常地简单?",-1),xs=e("div",{class:"language-json ext-json line-numbers-mode"},[e("pre",{class:"language-json"},[e("code",null,[e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"outbounds"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token punctuation"},"["),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"direct-out"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"freedom"'),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"proxy-out-vless"'),r("\n "),e("span",{class:"token comment"},"// ... ..."),r("\n "),e("span",{class:"token punctuation"},"}"),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token punctuation"},"{"),r("\n "),e("span",{class:"token property"},'"tag"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"block"'),e("span",{class:"token punctuation"},","),r("\n "),e("span",{class:"token property"},'"protocol"'),e("span",{class:"token operator"},":"),r(),e("span",{class:"token string"},'"blackhole"'),r("\n "),e("span",{class:"token punctuation"},"}"),r("\n "),e("span",{class:"token punctuation"},"]"),r("\n"),e("span",{class:"token punctuation"},"}"),r("\n")])]),e("div",{class:"line-numbers"},[e("span",{class:"line-number"},"1"),e("br"),e("span",{class:"line-number"},"2"),e("br"),e("span",{class:"line-number"},"3"),e("br"),e("span",{class:"line-number"},"4"),e("br"),e("span",{class:"line-number"},"5"),e("br"),e("span",{class:"line-number"},"6"),e("br"),e("span",{class:"line-number"},"7"),e("br"),e("span",{class:"line-number"},"8"),e("br"),e("span",{class:"line-number"},"9"),e("br"),e("span",{class:"line-number"},"10"),e("br"),e("span",{class:"line-number"},"11"),e("br"),e("span",{class:"line-number"},"12"),e("br"),e("span",{class:"line-number"},"13"),e("br"),e("span",{class:"line-number"},"14"),e("br"),e("span",{class:"line-number"},"15"),e("br"),e("span",{class:"line-number"},"16"),e("br")])],-1),Ds=e("p",null,"此时,路由规则其实变成了:",-1),vs=e("p",null,"这就是路由功能的灵活之处了,你可以自由的改变它的顺序来实现不同的设计。",-1),_s=e("p",null,[r("至此,我们已经解释完了 "),e("strong",null,[r("【如何利用 "),e("code",null,"geosite.dat"),r(" 文件,通过路由规则,根据【域名】来分流网络流量】。")])],-1),Fs=e("h2",{id:"_5-攻城略池-多种路由匹配条件",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#_5-攻城略池-多种路由匹配条件","aria-hidden":"true"},"#"),r(" 5. 攻城略池 - 多种路由匹配条件")],-1),Ps=e("p",null,"请确保你已经读懂了上面的内容,因为这样,你就已经理解了【路由】功能的工作逻辑。有了这个基础,我们就可以继续分析【路由】功能更多更详细的配置方式和匹配条件了。",-1),Ss=r("等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 "),Xs=r("《路由 (routing) 功能简析(下)》"),Vs=r(" 吧!");c.render=function(r,c){const Os=n("Mermaid"),Rs=n("OutboundLink"),js=n("RouterLink");return s(),a(o,null,[p,u,i,d,b,k,g,m,y,A,E,l(Os,{identifier:"mermaid_382ee188",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%3E%20O%5B%E5%87%BA%E7%AB%99%5D%0A%20%20%20%20end%0A%0A%20%20%20%20O%20.-%3E%20V(VPS)%0A%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE%0A%0A"}),h,f,B,x,D,v,_,F,P,S,X,V,O,R,j,C,T,I,L,w,W,q,G,l(Os,{identifier:"mermaid_64a56ee8",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),M,N,z,H,J,K,Q,U,Y,Z,$,nn,sn,an,ln,en,tn,on,rn,cn,pn,un,dn,bn,kn,e("p",null,[gn,e("a",mn,[yn,l(Rs)]),An,En,hn,fn,Bn,xn,Dn,vn,_n,Fn,Pn]),e("div",Sn,[Xn,Vn,e("p",null,[On,Rn,jn,Cn,Tn,e("a",In,[Ln,l(Rs)]),wn]),e("p",null,[Wn,qn,Gn,Mn,Nn,e("a",zn,[Hn,l(Rs)]),Jn]),e("p",null,[Kn,Qn,Un,e("a",Yn,[Zn,l(Rs)]),$n]),e("p",null,[ns,ss,as,ls,es,e("a",ts,[os,l(Rs)]),rs,cs]),ps,us]),is,ds,bs,ks,gs,ms,ys,l(Os,{identifier:"mermaid_64a55fb4",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%20%20%20%20O4%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),As,Es,hs,fs,Bs,xs,Ds,l(Os,{identifier:"mermaid_64a55a22",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%20%20%20%20O4%20.-%3E%20D%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),vs,_s,Fs,Ps,e("p",null,[Ss,l(js,{to:"/en/document/level-1/routing-lv1-part2.html"},{default:t((()=>[Xs])),_:1}),Vs])],64)};export default c; diff --git a/assets/routing-lv1-part2.html.94f43314.js b/assets/routing-lv1-part2.html.0a7a2f7d.js similarity index 99% rename from assets/routing-lv1-part2.html.94f43314.js rename to assets/routing-lv1-part2.html.0a7a2f7d.js index 93917cde5..9a550100a 100644 --- a/assets/routing-lv1-part2.html.94f43314.js +++ b/assets/routing-lv1-part2.html.0a7a2f7d.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as o,b as p,w as t,F as e,e as c,d as l}from"./app.755d843f.js";const u={},r=o("h1",{id:"路由-routing-功能简析-下",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#路由-routing-功能简析-下","aria-hidden":"true"},"#"),c(" 路由 (routing) 功能简析(下)")],-1),i=o("p",null,[c("欢迎继续学习 "),o("code",null,"Xray"),c(" 的【路由】功能!")],-1),d=c("在 "),k=c("《路由 (routing) 功能简析(上)》"),b=c(" 中,我们已经对【路由】功能的工作逻辑有了清晰的理解,也基于 "),m=o("code",null,"geosite.dat",-1),q=c(" 文件做了简单的域名分流配置。"),g=l('

    如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!

    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),y=l("
  • 如果需要匹配某个子域名,如 a-name.yourdomain.com,我们使用 full: "a-name.yourdomain.com"
  • 前面的 问题1问题2,就可以通过给 proxy.yourdomain.com 指定 [proxy-out-vless] 出站,给 direct.yourdomain.com 指定 [direct-out] 出站来解决
  • 如果需要匹配 yourdomain.com 的所有子域名,我们使用 domain: "yourdomain.com" 实现
  • 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
  • ",4),h=c("另外,"),A=o("code",null,"[domain]",-1),f=c(" 还支持正则表达式等匹配方式。详情请参考 "),E=c("《基础配置模块 - 路由》文档"),B=l('

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定子域名直连\n      {\n        "type": "field",\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      },\n      // 指定子域名转发VPS\n      {\n        "type": "field",\n        "domain": ["full:proxy.yourdomain.com"],\n        "outboundTag": "proxy-out-vless"\n      },\n      // 指定泛域名转发VPS\n      {\n        "type": "field",\n        "domain": ["yourdomain.com"],\n        "outboundTag": "proxy-out-vless"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

    5.2 基于 IP 文件分流:geoip.dat

    geosite.dat 规则文件十分类似的,我们还有 geoip.dat 这个规则文件,它致力于为用户提供成熟完善的【IP 分类表】。让用户可以简单的通过 geoip:xxx 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。

    1. 解决前面的 [问题3], [问题4],我们使用 geoip:private 类别来指定 [direct-out]
    2. 解决前面的 [问题7],我们使用 geoip:cn 类别来指定 [direct-out]
    3. 解决前面的 [问题8],由于 geoip 中没有【非中国 IP】这个分类(因为这等于要收集全世界的 IP 段),所以我们用隐藏规则代替,也就是将 [proxy-out-vless] 放在第一个出站

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 本机内部地址、局域网地址直连\n      {\n        "type": "field",\n        "ip": ["geoip:private"],\n        "outboundTag": "direct-out"\n      },\n      // 国内IP集直连\n      {\n        "type": "field",\n        "ip": ["geoip:cn"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    5.3 基于指定 IP 地址分流

    geosite.dat 规则文件十分类似的,我们还有 geoip.dat 这个规则文件,它是供【路由功能】驱使的第二个神兵利器,它致力于为用户提供成熟完善的【IP 分类表】。让用户可以简单的通过 geoip:xxx 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。

    1. 解决前面的 [问题5],我们使用 ip: "223.5.5.5" 来指定 [direct-out]
    2. 解决前面的 [问题6],我们使用 ip: "1.1.1.1" 来指定 [proxy-out-vless]

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定IP地址直连\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      // 指定IP地址转发VPS\n      {\n        "type": "field",\n        "ip": ["1.1.1.1"],\n        "outboundTag": "proxy-out-vless"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    5.4 基于协议类型分流:[protocol]

    1. 解决前面的 [问题9],我们使用 "protocol": ["bittorrent"] 类别来指定 [direct-out]

    提示

    你需要打开入站代理中的 sniffing 才能使用此种方式分流。

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定 BT 协议直连\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    5.5 基于更多条件的分流

    到目前位置,我们仍然只讲了【路由功能】分流能力的冰山一角!因为它还支持很多其他的判断条件!我在此简单罗列如下:

    本文已经讲过的:

    • inboundTag
    • domain
    • ip
    • protocol

    本文尚未讲到的:

    • port
    • sourcePort
    • network
    • source
    • user
    • attrs
    ',22),v=c("但这些内容实在是过多,全部展开就远远不是 "),x=o("code",null,"level-1",-1),D=c(" 的内容了,所以,需要这些复杂条件的朋友,请仔细阅读 "),I=c("《基础配置模块 - 路由》文档"),P=c(" 自学哦!有问题就去 TG 群里面问问吧!"),_=l('

    6. “霸业初定”:路由规则整体回顾

    到现在为止,我们已经累积出了一套战略雄伟、战术精准的路由规则,为了避免混乱,现在就对它进行一次完整的整理和回顾。

    注意

    路由生效的顺序是:【从上往下,依次判断】,所以我一般推荐的规则顺序是:

    [1-block] --> [2-direct] --> [3-proxy] --> [4-first-outbound]

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // [1-block 广告流量屏蔽]\n      // 1.1  广告域名集屏蔽\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      // [2-direct 国内流量直连]\n      // 2.1 国内域名集、指定子域名直连\n      {\n        "type": "field",\n        "domain": ["geosite:cn", "full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      },\n      // 2.2 本机内部地址+局域网、国内IP、指定IP直连\n      {\n        "type": "field",\n        "ip": ["geoip:private", "geoip:cn", "223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      // 2.3 BT协议流量直连\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct-out"\n      },\n      // [3-proxy 国外流量转发VPS]\n      // 3.1 国外域名集、指定子域名、指定泛域名转发VPS\n      {\n        "type": "field",\n        "domain": [\n          "geosite:geolocation-!cn",\n          "full:proxy.yourdomain.com",\n          "yourdomain.com"\n        ],\n        "outboundTag": "proxy-out-vless"\n      },\n      // 3.2 指定IP转发VPS\n      {\n        "type": "field",\n        "ip": ["1.1.1.1"],\n        "outboundTag": "proxy-out-vless"\n      }\n      // [4-default-routing 第一条出站]\n      // 没有匹配到任何规则的流量,默认使用第一条出站处理\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52

    此时,路由规则其实变成了:

    ',5),S=l('

    至于第一条出站是 [direct-out] 还是 [proxy-out-vless],这就全看你的需求了。

    7. 路由配置常见错误

    请大家注意看,我上面每一条路由规则,都是一个独立的匹配依据,只有这样才能确保生效。而新人在自定义路由规则时常犯的一个错误就是:在一条规则内同时匹配了多种不同的匹配依据,造成匹配无效。

    比如,他希望实现的配置是:

    1. 自己的 direct.yourdomain.com 直连
    2. 国内 DNS 查询(如 223.5.5.5)直连

    7.1 错误示范

    为了实现上面的目标,他写出了以下路由规则:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    你能看出这里面的错误吗?乍一看,似乎是对的?

    注意

    同一个规则之内,各个依据需要同时成立,才会匹配成功,逻辑关系是 ,而不是

    换言之,这条规则的意思是:【当你访问的 目标 = direct.yourdomain.com, 并且 同时还满足 目标 = 223.5.5.5 时,Xray 才会将流量转发给 [direct-out] 直连出站】

    很显然,一个目标不可能同时等于两个不同的值,所以这不但是一个永远不可能实现的无效规则,更与原本的目标风马牛不相及。

    7.2 正确示范

    正确示范,自然就是将不同的匹配依据独立出来:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      {\n        "type": "field",\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    其实,第 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. 尾注

    ',46),j=c("现在你可以重新阅读一遍 "),T=c("路由"),F=c(",看看是否有更加深刻的理解。"),O=o("li",null,"🍉🍉🍉🍉🍉 😄",-1);u.render=function(c,l){const u=n("RouterLink"),R=n("Mermaid");return s(),a(e,null,[r,i,o("p",null,[d,p(u,{to:"/document/level-1/routing-lv1-part1.html"},{default:t((()=>[k])),_:1}),b,m,q]),g,o("ol",null,[y,o("li",null,[h,A,f,p(u,{to:"/config/base/routing/"},{default:t((()=>[E])),_:1})])]),B,o("p",null,[v,x,D,p(u,{to:"/config/base/routing/"},{default:t((()=>[I])),_:1}),P]),_,p(R,{identifier:"mermaid_64a561de",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22direct.yourdomain.com%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geoip:private%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geoip:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22ip:223.5.5.5%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22protocol:bittorrent%22%20--%3E%20O2%5Bdirect%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22proxy.yourdomain.com%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22*.yourdomain.com%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22ip:1.1.1.1%22%20--%3E%20O3%5Bproxy%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),S,o("ul",null,[o("li",null,[j,p(u,{to:"/config/routing.html"},{default:t((()=>[T])),_:1}),F]),O])],64)};export default u; +import{r as n,o as s,c as a,a as o,b as p,w as t,F as e,e as c,d as l}from"./app.48111a85.js";const u={},r=o("h1",{id:"路由-routing-功能简析-下",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#路由-routing-功能简析-下","aria-hidden":"true"},"#"),c(" 路由 (routing) 功能简析(下)")],-1),i=o("p",null,[c("欢迎继续学习 "),o("code",null,"Xray"),c(" 的【路由】功能!")],-1),d=c("在 "),k=c("《路由 (routing) 功能简析(上)》"),b=c(" 中,我们已经对【路由】功能的工作逻辑有了清晰的理解,也基于 "),m=o("code",null,"geosite.dat",-1),q=c(" 文件做了简单的域名分流配置。"),g=l('

    如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!

    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),y=l("
  • 如果需要匹配某个子域名,如 a-name.yourdomain.com,我们使用 full: "a-name.yourdomain.com"
  • 前面的 问题1问题2,就可以通过给 proxy.yourdomain.com 指定 [proxy-out-vless] 出站,给 direct.yourdomain.com 指定 [direct-out] 出站来解决
  • 如果需要匹配 yourdomain.com 的所有子域名,我们使用 domain: "yourdomain.com" 实现
  • 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
  • ",4),h=c("另外,"),A=o("code",null,"[domain]",-1),f=c(" 还支持正则表达式等匹配方式。详情请参考 "),E=c("《基础配置模块 - 路由》文档"),B=l('

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定子域名直连\n      {\n        "type": "field",\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      },\n      // 指定子域名转发VPS\n      {\n        "type": "field",\n        "domain": ["full:proxy.yourdomain.com"],\n        "outboundTag": "proxy-out-vless"\n      },\n      // 指定泛域名转发VPS\n      {\n        "type": "field",\n        "domain": ["yourdomain.com"],\n        "outboundTag": "proxy-out-vless"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

    5.2 基于 IP 文件分流:geoip.dat

    geosite.dat 规则文件十分类似的,我们还有 geoip.dat 这个规则文件,它致力于为用户提供成熟完善的【IP 分类表】。让用户可以简单的通过 geoip:xxx 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。

    1. 解决前面的 [问题3], [问题4],我们使用 geoip:private 类别来指定 [direct-out]
    2. 解决前面的 [问题7],我们使用 geoip:cn 类别来指定 [direct-out]
    3. 解决前面的 [问题8],由于 geoip 中没有【非中国 IP】这个分类(因为这等于要收集全世界的 IP 段),所以我们用隐藏规则代替,也就是将 [proxy-out-vless] 放在第一个出站

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 本机内部地址、局域网地址直连\n      {\n        "type": "field",\n        "ip": ["geoip:private"],\n        "outboundTag": "direct-out"\n      },\n      // 国内IP集直连\n      {\n        "type": "field",\n        "ip": ["geoip:cn"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    5.3 基于指定 IP 地址分流

    geosite.dat 规则文件十分类似的,我们还有 geoip.dat 这个规则文件,它是供【路由功能】驱使的第二个神兵利器,它致力于为用户提供成熟完善的【IP 分类表】。让用户可以简单的通过 geoip:xxx 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。

    1. 解决前面的 [问题5],我们使用 ip: "223.5.5.5" 来指定 [direct-out]
    2. 解决前面的 [问题6],我们使用 ip: "1.1.1.1" 来指定 [proxy-out-vless]

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定IP地址直连\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      // 指定IP地址转发VPS\n      {\n        "type": "field",\n        "ip": ["1.1.1.1"],\n        "outboundTag": "proxy-out-vless"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    5.4 基于协议类型分流:[protocol]

    1. 解决前面的 [问题9],我们使用 "protocol": ["bittorrent"] 类别来指定 [direct-out]

    提示

    你需要打开入站代理中的 sniffing 才能使用此种方式分流。

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定 BT 协议直连\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    5.5 基于更多条件的分流

    到目前位置,我们仍然只讲了【路由功能】分流能力的冰山一角!因为它还支持很多其他的判断条件!我在此简单罗列如下:

    本文已经讲过的:

    • inboundTag
    • domain
    • ip
    • protocol

    本文尚未讲到的:

    • port
    • sourcePort
    • network
    • source
    • user
    • attrs
    ',22),v=c("但这些内容实在是过多,全部展开就远远不是 "),x=o("code",null,"level-1",-1),D=c(" 的内容了,所以,需要这些复杂条件的朋友,请仔细阅读 "),I=c("《基础配置模块 - 路由》文档"),P=c(" 自学哦!有问题就去 TG 群里面问问吧!"),_=l('

    6. “霸业初定”:路由规则整体回顾

    到现在为止,我们已经累积出了一套战略雄伟、战术精准的路由规则,为了避免混乱,现在就对它进行一次完整的整理和回顾。

    注意

    路由生效的顺序是:【从上往下,依次判断】,所以我一般推荐的规则顺序是:

    [1-block] --> [2-direct] --> [3-proxy] --> [4-first-outbound]

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // [1-block 广告流量屏蔽]\n      // 1.1  广告域名集屏蔽\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      // [2-direct 国内流量直连]\n      // 2.1 国内域名集、指定子域名直连\n      {\n        "type": "field",\n        "domain": ["geosite:cn", "full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      },\n      // 2.2 本机内部地址+局域网、国内IP、指定IP直连\n      {\n        "type": "field",\n        "ip": ["geoip:private", "geoip:cn", "223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      // 2.3 BT协议流量直连\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct-out"\n      },\n      // [3-proxy 国外流量转发VPS]\n      // 3.1 国外域名集、指定子域名、指定泛域名转发VPS\n      {\n        "type": "field",\n        "domain": [\n          "geosite:geolocation-!cn",\n          "full:proxy.yourdomain.com",\n          "yourdomain.com"\n        ],\n        "outboundTag": "proxy-out-vless"\n      },\n      // 3.2 指定IP转发VPS\n      {\n        "type": "field",\n        "ip": ["1.1.1.1"],\n        "outboundTag": "proxy-out-vless"\n      }\n      // [4-default-routing 第一条出站]\n      // 没有匹配到任何规则的流量,默认使用第一条出站处理\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52

    此时,路由规则其实变成了:

    ',5),S=l('

    至于第一条出站是 [direct-out] 还是 [proxy-out-vless],这就全看你的需求了。

    7. 路由配置常见错误

    请大家注意看,我上面每一条路由规则,都是一个独立的匹配依据,只有这样才能确保生效。而新人在自定义路由规则时常犯的一个错误就是:在一条规则内同时匹配了多种不同的匹配依据,造成匹配无效。

    比如,他希望实现的配置是:

    1. 自己的 direct.yourdomain.com 直连
    2. 国内 DNS 查询(如 223.5.5.5)直连

    7.1 错误示范

    为了实现上面的目标,他写出了以下路由规则:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    你能看出这里面的错误吗?乍一看,似乎是对的?

    注意

    同一个规则之内,各个依据需要同时成立,才会匹配成功,逻辑关系是 ,而不是

    换言之,这条规则的意思是:【当你访问的 目标 = direct.yourdomain.com, 并且 同时还满足 目标 = 223.5.5.5 时,Xray 才会将流量转发给 [direct-out] 直连出站】

    很显然,一个目标不可能同时等于两个不同的值,所以这不但是一个永远不可能实现的无效规则,更与原本的目标风马牛不相及。

    7.2 正确示范

    正确示范,自然就是将不同的匹配依据独立出来:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      {\n        "type": "field",\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    其实,第 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. 尾注

    ',46),j=c("现在你可以重新阅读一遍 "),T=c("路由"),F=c(",看看是否有更加深刻的理解。"),O=o("li",null,"🍉🍉🍉🍉🍉 😄",-1);u.render=function(c,l){const u=n("RouterLink"),R=n("Mermaid");return s(),a(e,null,[r,i,o("p",null,[d,p(u,{to:"/document/level-1/routing-lv1-part1.html"},{default:t((()=>[k])),_:1}),b,m,q]),g,o("ol",null,[y,o("li",null,[h,A,f,p(u,{to:"/config/base/routing/"},{default:t((()=>[E])),_:1})])]),B,o("p",null,[v,x,D,p(u,{to:"/config/base/routing/"},{default:t((()=>[I])),_:1}),P]),_,p(R,{identifier:"mermaid_64a561de",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22direct.yourdomain.com%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geoip:private%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geoip:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22ip:223.5.5.5%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22protocol:bittorrent%22%20--%3E%20O2%5Bdirect%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22proxy.yourdomain.com%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22*.yourdomain.com%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22ip:1.1.1.1%22%20--%3E%20O3%5Bproxy%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),S,o("ul",null,[o("li",null,[j,p(u,{to:"/config/routing.html"},{default:t((()=>[T])),_:1}),F]),O])],64)};export default u; diff --git a/assets/routing-lv1-part2.html.83708fd4.js b/assets/routing-lv1-part2.html.c02655ca.js similarity index 99% rename from assets/routing-lv1-part2.html.83708fd4.js rename to assets/routing-lv1-part2.html.c02655ca.js index 23209f950..4ee54ff2f 100644 --- a/assets/routing-lv1-part2.html.83708fd4.js +++ b/assets/routing-lv1-part2.html.c02655ca.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as o,b as p,w as t,F as e,e as c,d as l}from"./app.755d843f.js";const u={},r=o("h1",{id:"路由-routing-功能简析-下",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#路由-routing-功能简析-下","aria-hidden":"true"},"#"),c(" 路由 (routing) 功能简析(下)")],-1),i=o("p",null,[c("欢迎继续学习 "),o("code",null,"Xray"),c(" 的【路由】功能!")],-1),d=c("在 "),k=c("《路由 (routing) 功能简析(上)》"),b=c(" 中,我们已经对【路由】功能的工作逻辑有了清晰的理解,也基于 "),m=o("code",null,"geosite.dat",-1),q=c(" 文件做了简单的域名分流配置。"),g=l('

    如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!

    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),y=l("
  • 如果需要匹配某个子域名,如 a-name.yourdomain.com,我们使用 full: "a-name.yourdomain.com"
  • 前面的 问题1问题2,就可以通过给 proxy.yourdomain.com 指定 [proxy-out-vless] 出站,给 direct.yourdomain.com 指定 [direct-out] 出站来解决
  • 如果需要匹配 yourdomain.com 的所有子域名,我们使用 domain: "yourdomain.com" 实现
  • 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
  • ",4),h=c("另外,"),A=o("code",null,"[domain]",-1),f=c(" 还支持正则表达式等匹配方式。详情请参考 "),E=c("《基础配置模块 - 路由》文档"),B=l('

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定子域名直连\n      {\n        "type": "field",\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      },\n      // 指定子域名转发VPS\n      {\n        "type": "field",\n        "domain": ["full:proxy.yourdomain.com"],\n        "outboundTag": "proxy-out-vless"\n      },\n      // 指定泛域名转发VPS\n      {\n        "type": "field",\n        "domain": ["yourdomain.com"],\n        "outboundTag": "proxy-out-vless"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

    5.2 基于 IP 文件分流:geoip.dat

    geosite.dat 规则文件十分类似的,我们还有 geoip.dat 这个规则文件,它致力于为用户提供成熟完善的【IP 分类表】。让用户可以简单的通过 geoip:xxx 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。

    1. 解决前面的 [问题3], [问题4],我们使用 geoip:private 类别来指定 [direct-out]
    2. 解决前面的 [问题7],我们使用 geoip:cn 类别来指定 [direct-out]
    3. 解决前面的 [问题8],由于 geoip 中没有【非中国 IP】这个分类(因为这等于要收集全世界的 IP 段),所以我们用隐藏规则代替,也就是将 [proxy-out-vless] 放在第一个出站

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 本机内部地址、局域网地址直连\n      {\n        "type": "field",\n        "ip": ["geoip:private"],\n        "outboundTag": "direct-out"\n      },\n      // 国内IP集直连\n      {\n        "type": "field",\n        "ip": ["geoip:cn"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    5.3 基于指定 IP 地址分流

    geosite.dat 规则文件十分类似的,我们还有 geoip.dat 这个规则文件,它是供【路由功能】驱使的第二个神兵利器,它致力于为用户提供成熟完善的【IP 分类表】。让用户可以简单的通过 geoip:xxx 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。

    1. 解决前面的 [问题5],我们使用 ip: "223.5.5.5" 来指定 [direct-out]
    2. 解决前面的 [问题6],我们使用 ip: "1.1.1.1" 来指定 [proxy-out-vless]

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定IP地址直连\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      // 指定IP地址转发VPS\n      {\n        "type": "field",\n        "ip": ["1.1.1.1"],\n        "outboundTag": "proxy-out-vless"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    5.4 基于协议类型分流:[protocol]

    1. 解决前面的 [问题9],我们使用 "protocol": ["bittorrent"] 类别来指定 [direct-out]

    Tip

    你需要打开入站代理中的 sniffing 才能使用此种方式分流。

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定 BT 协议直连\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    5.5 基于更多条件的分流

    到目前位置,我们仍然只讲了【路由功能】分流能力的冰山一角!因为它还支持很多其他的判断条件!我在此简单罗列如下:

    本文已经讲过的:

    • inboundTag
    • domain
    • ip
    • protocol

    本文尚未讲到的:

    • port
    • sourcePort
    • network
    • source
    • user
    • attrs
    ',22),v=c("但这些内容实在是过多,全部展开就远远不是 "),x=o("code",null,"level-1",-1),D=c(" 的内容了,所以,需要这些复杂条件的朋友,请仔细阅读 "),I=c("《基础配置模块 - 路由》文档"),P=c(" 自学哦!有问题就去 TG 群里面问问吧!"),_=l('

    6. “霸业初定”:路由规则整体回顾

    到现在为止,我们已经累积出了一套战略雄伟、战术精准的路由规则,为了避免混乱,现在就对它进行一次完整的整理和回顾。

    注意

    路由生效的顺序是:【从上往下,依次判断】,所以我一般推荐的规则顺序是:

    [1-block] --> [2-direct] --> [3-proxy] --> [4-first-outbound]

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // [1-block 广告流量屏蔽]\n      // 1.1  广告域名集屏蔽\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      // [2-direct 国内流量直连]\n      // 2.1 国内域名集、指定子域名直连\n      {\n        "type": "field",\n        "domain": ["geosite:cn", "full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      },\n      // 2.2 本机内部地址+局域网、国内IP、指定IP直连\n      {\n        "type": "field",\n        "ip": ["geoip:private", "geoip:cn", "223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      // 2.3 BT协议流量直连\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct-out"\n      },\n      // [3-proxy 国外流量转发VPS]\n      // 3.1 国外域名集、指定子域名、指定泛域名转发VPS\n      {\n        "type": "field",\n        "domain": [\n          "geosite:geolocation-!cn",\n          "full:proxy.yourdomain.com",\n          "yourdomain.com"\n        ],\n        "outboundTag": "proxy-out-vless"\n      },\n      // 3.2 指定IP转发VPS\n      {\n        "type": "field",\n        "ip": ["1.1.1.1"],\n        "outboundTag": "proxy-out-vless"\n      }\n      // [4-default-routing 第一条出站]\n      // 没有匹配到任何规则的流量,默认使用第一条出站处理\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52

    此时,路由规则其实变成了:

    ',5),S=l('

    至于第一条出站是 [direct-out] 还是 [proxy-out-vless],这就全看你的需求了。

    7. 路由配置常见错误

    请大家注意看,我上面每一条路由规则,都是一个独立的匹配依据,只有这样才能确保生效。而新人在自定义路由规则时常犯的一个错误就是:在一条规则内同时匹配了多种不同的匹配依据,造成匹配无效。

    比如,他希望实现的配置是:

    1. 自己的 direct.yourdomain.com 直连
    2. 国内 DNS 查询(如 223.5.5.5)直连

    7.1 错误示范

    为了实现上面的目标,他写出了以下路由规则:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    你能看出这里面的错误吗?乍一看,似乎是对的?

    注意

    同一个规则之内,各个依据需要同时成立,才会匹配成功,逻辑关系是 ,而不是

    换言之,这条规则的意思是:【当你访问的 目标 = direct.yourdomain.com, 并且 同时还满足 目标 = 223.5.5.5 时,Xray 才会将流量转发给 [direct-out] 直连出站】

    很显然,一个目标不可能同时等于两个不同的值,所以这不但是一个永远不可能实现的无效规则,更与原本的目标风马牛不相及。

    7.2 正确示范

    正确示范,自然就是将不同的匹配依据独立出来:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      {\n        "type": "field",\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    其实,第 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. 尾注

    ',46),T=c("现在你可以重新阅读一遍 "),j=c("路由"),F=c(",看看是否有更加深刻的理解。"),O=o("li",null,"🍉🍉🍉🍉🍉 😄",-1);u.render=function(c,l){const u=n("RouterLink"),R=n("Mermaid");return s(),a(e,null,[r,i,o("p",null,[d,p(u,{to:"/en/document/level-1/routing-lv1-part1.html"},{default:t((()=>[k])),_:1}),b,m,q]),g,o("ol",null,[y,o("li",null,[h,A,f,p(u,{to:"/config/base/routing/"},{default:t((()=>[E])),_:1})])]),B,o("p",null,[v,x,D,p(u,{to:"/en/config/base/routing/"},{default:t((()=>[I])),_:1}),P]),_,p(R,{identifier:"mermaid_64a561de",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22direct.yourdomain.com%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geoip:private%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geoip:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22ip:223.5.5.5%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22protocol:bittorrent%22%20--%3E%20O2%5Bdirect%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22proxy.yourdomain.com%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22*.yourdomain.com%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22ip:1.1.1.1%22%20--%3E%20O3%5Bproxy%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),S,o("ul",null,[o("li",null,[T,p(u,{to:"/en/config/routing.html"},{default:t((()=>[j])),_:1}),F]),O])],64)};export default u; +import{r as n,o as s,c as a,a as o,b as p,w as t,F as e,e as c,d as l}from"./app.48111a85.js";const u={},r=o("h1",{id:"路由-routing-功能简析-下",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#路由-routing-功能简析-下","aria-hidden":"true"},"#"),c(" 路由 (routing) 功能简析(下)")],-1),i=o("p",null,[c("欢迎继续学习 "),o("code",null,"Xray"),c(" 的【路由】功能!")],-1),d=c("在 "),k=c("《路由 (routing) 功能简析(上)》"),b=c(" 中,我们已经对【路由】功能的工作逻辑有了清晰的理解,也基于 "),m=o("code",null,"geosite.dat",-1),q=c(" 文件做了简单的域名分流配置。"),g=l('

    如前面所说,域名分流仅仅是【路由】功能的牛刀小试而已。下面就让我们来看看除了域名之外,还什么可以用做分流依据的东西吧!

    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),y=l("
  • 如果需要匹配某个子域名,如 a-name.yourdomain.com,我们使用 full: "a-name.yourdomain.com"
  • 前面的 问题1问题2,就可以通过给 proxy.yourdomain.com 指定 [proxy-out-vless] 出站,给 direct.yourdomain.com 指定 [direct-out] 出站来解决
  • 如果需要匹配 yourdomain.com 的所有子域名,我们使用 domain: "yourdomain.com" 实现
  • 上述两个可以成为两个独立的路由规则,达到某些子域名直连,其他子域名代理的配置
  • ",4),h=c("另外,"),A=o("code",null,"[domain]",-1),f=c(" 还支持正则表达式等匹配方式。详情请参考 "),E=c("《基础配置模块 - 路由》文档"),B=l('

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定子域名直连\n      {\n        "type": "field",\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      },\n      // 指定子域名转发VPS\n      {\n        "type": "field",\n        "domain": ["full:proxy.yourdomain.com"],\n        "outboundTag": "proxy-out-vless"\n      },\n      // 指定泛域名转发VPS\n      {\n        "type": "field",\n        "domain": ["yourdomain.com"],\n        "outboundTag": "proxy-out-vless"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

    5.2 基于 IP 文件分流:geoip.dat

    geosite.dat 规则文件十分类似的,我们还有 geoip.dat 这个规则文件,它致力于为用户提供成熟完善的【IP 分类表】。让用户可以简单的通过 geoip:xxx 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。

    1. 解决前面的 [问题3], [问题4],我们使用 geoip:private 类别来指定 [direct-out]
    2. 解决前面的 [问题7],我们使用 geoip:cn 类别来指定 [direct-out]
    3. 解决前面的 [问题8],由于 geoip 中没有【非中国 IP】这个分类(因为这等于要收集全世界的 IP 段),所以我们用隐藏规则代替,也就是将 [proxy-out-vless] 放在第一个出站

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 本机内部地址、局域网地址直连\n      {\n        "type": "field",\n        "ip": ["geoip:private"],\n        "outboundTag": "direct-out"\n      },\n      // 国内IP集直连\n      {\n        "type": "field",\n        "ip": ["geoip:cn"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    5.3 基于指定 IP 地址分流

    geosite.dat 规则文件十分类似的,我们还有 geoip.dat 这个规则文件,它是供【路由功能】驱使的第二个神兵利器,它致力于为用户提供成熟完善的【IP 分类表】。让用户可以简单的通过 geoip:xxx 这种格式方便的调用任何子类,定制符合自身需求的路由规则 。

    1. 解决前面的 [问题5],我们使用 ip: "223.5.5.5" 来指定 [direct-out]
    2. 解决前面的 [问题6],我们使用 ip: "1.1.1.1" 来指定 [proxy-out-vless]

    上述配置如下:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定IP地址直连\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      // 指定IP地址转发VPS\n      {\n        "type": "field",\n        "ip": ["1.1.1.1"],\n        "outboundTag": "proxy-out-vless"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    5.4 基于协议类型分流:[protocol]

    1. 解决前面的 [问题9],我们使用 "protocol": ["bittorrent"] 类别来指定 [direct-out]

    Tip

    你需要打开入站代理中的 sniffing 才能使用此种方式分流。

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // 指定 BT 协议直连\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    5.5 基于更多条件的分流

    到目前位置,我们仍然只讲了【路由功能】分流能力的冰山一角!因为它还支持很多其他的判断条件!我在此简单罗列如下:

    本文已经讲过的:

    • inboundTag
    • domain
    • ip
    • protocol

    本文尚未讲到的:

    • port
    • sourcePort
    • network
    • source
    • user
    • attrs
    ',22),v=c("但这些内容实在是过多,全部展开就远远不是 "),x=o("code",null,"level-1",-1),D=c(" 的内容了,所以,需要这些复杂条件的朋友,请仔细阅读 "),I=c("《基础配置模块 - 路由》文档"),P=c(" 自学哦!有问题就去 TG 群里面问问吧!"),_=l('

    6. “霸业初定”:路由规则整体回顾

    到现在为止,我们已经累积出了一套战略雄伟、战术精准的路由规则,为了避免混乱,现在就对它进行一次完整的整理和回顾。

    注意

    路由生效的顺序是:【从上往下,依次判断】,所以我一般推荐的规则顺序是:

    [1-block] --> [2-direct] --> [3-proxy] --> [4-first-outbound]

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      // [1-block 广告流量屏蔽]\n      // 1.1  广告域名集屏蔽\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      // [2-direct 国内流量直连]\n      // 2.1 国内域名集、指定子域名直连\n      {\n        "type": "field",\n        "domain": ["geosite:cn", "full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      },\n      // 2.2 本机内部地址+局域网、国内IP、指定IP直连\n      {\n        "type": "field",\n        "ip": ["geoip:private", "geoip:cn", "223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      // 2.3 BT协议流量直连\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct-out"\n      },\n      // [3-proxy 国外流量转发VPS]\n      // 3.1 国外域名集、指定子域名、指定泛域名转发VPS\n      {\n        "type": "field",\n        "domain": [\n          "geosite:geolocation-!cn",\n          "full:proxy.yourdomain.com",\n          "yourdomain.com"\n        ],\n        "outboundTag": "proxy-out-vless"\n      },\n      // 3.2 指定IP转发VPS\n      {\n        "type": "field",\n        "ip": ["1.1.1.1"],\n        "outboundTag": "proxy-out-vless"\n      }\n      // [4-default-routing 第一条出站]\n      // 没有匹配到任何规则的流量,默认使用第一条出站处理\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52

    此时,路由规则其实变成了:

    ',5),S=l('

    至于第一条出站是 [direct-out] 还是 [proxy-out-vless],这就全看你的需求了。

    7. 路由配置常见错误

    请大家注意看,我上面每一条路由规则,都是一个独立的匹配依据,只有这样才能确保生效。而新人在自定义路由规则时常犯的一个错误就是:在一条规则内同时匹配了多种不同的匹配依据,造成匹配无效。

    比如,他希望实现的配置是:

    1. 自己的 direct.yourdomain.com 直连
    2. 国内 DNS 查询(如 223.5.5.5)直连

    7.1 错误示范

    为了实现上面的目标,他写出了以下路由规则:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    你能看出这里面的错误吗?乍一看,似乎是对的?

    注意

    同一个规则之内,各个依据需要同时成立,才会匹配成功,逻辑关系是 ,而不是

    换言之,这条规则的意思是:【当你访问的 目标 = direct.yourdomain.com, 并且 同时还满足 目标 = 223.5.5.5 时,Xray 才会将流量转发给 [direct-out] 直连出站】

    很显然,一个目标不可能同时等于两个不同的值,所以这不但是一个永远不可能实现的无效规则,更与原本的目标风马牛不相及。

    7.2 正确示范

    正确示范,自然就是将不同的匹配依据独立出来:

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "rules": [\n      {\n        "type": "field",\n        "ip": ["223.5.5.5"],\n        "outboundTag": "direct-out"\n      },\n      {\n        "type": "field",\n        "domain": ["full:direct.yourdomain.com"],\n        "outboundTag": "direct-out"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    其实,第 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. 尾注

    ',46),T=c("现在你可以重新阅读一遍 "),j=c("路由"),F=c(",看看是否有更加深刻的理解。"),O=o("li",null,"🍉🍉🍉🍉🍉 😄",-1);u.render=function(c,l){const u=n("RouterLink"),R=n("Mermaid");return s(),a(e,null,[r,i,o("p",null,[d,p(u,{to:"/en/document/level-1/routing-lv1-part1.html"},{default:t((()=>[k])),_:1}),b,m,q]),g,o("ol",null,[y,o("li",null,[h,A,f,p(u,{to:"/config/base/routing/"},{default:t((()=>[E])),_:1})])]),B,o("p",null,[v,x,D,p(u,{to:"/en/config/base/routing/"},{default:t((()=>[I])),_:1}),P]),_,p(R,{identifier:"mermaid_64a561de",graph:"%20%20%20%20graph%20LR;%0A%0A%20%20%20%20S(APP%E6%95%B0%E6%8D%AE)%20.-%3E%20I%5B%E5%85%A5%E7%AB%99%5D%0A%0A%20%20%20%20subgraph%20Xray%0A%20%20%20%20I%20--%3E%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:category-ads-all%22%20--%3E%20O1%5Bblock%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22direct.yourdomain.com%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geoip:private%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geoip:cn%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22ip:223.5.5.5%22%20--%3E%20O2%5Bdirect%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22protocol:bittorrent%22%20--%3E%20O2%5Bdirect%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22geosite:geolocation-!cn%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22proxy.yourdomain.com%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22*.yourdomain.com%22%20--%3E%20O3%5Bproxy%5D%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20--%20%22ip:1.1.1.1%22%20--%3E%20O3%5Bproxy%5D%0A%0A%20%20%20%20R%5B%E8%B7%AF%E7%94%B1%5D%20-.%20%22%E6%B2%A1%E6%9C%89%E5%91%BD%E4%B8%AD%E8%A7%84%E5%88%99%E7%9A%84%E6%B5%81%E9%87%8F%22%20.-%3E%20O4%5B%E7%AC%AC%E4%B8%80%E6%9D%A1%E5%87%BA%E7%AB%99%5D%0A%0A%20%20%20%20end%0A%0A%20%20%20%20O2%20.-%3E%20D(%E5%9B%BD%E5%86%85%E6%9C%8D%E5%8A%A1%E5%99%A8)%0A%20%20%20%20O3%20.-%3E%20V(VPS)%0A%0A%20%20%20%20O1:::redclass%0A%20%20%20%20V:::greyclass%0A%20%20%20%20S:::greyclass%0A%20%20%20%20R:::routingclass%0A%20%20%20%20classDef%20redclass%20fill:#FF0000%0A%20%20%20%20classDef%20greyclass%20fill:#C0C0C0%0A%20%20%20%20classDef%20routingclass%20fill:#FFFFDE,stroke:#000000%0A%0A"}),S,o("ul",null,[o("li",null,[T,p(u,{to:"/en/config/routing.html"},{default:t((()=>[j])),_:1}),F]),O])],64)};export default u; diff --git a/assets/routing.html.90ac5107.js b/assets/routing.html.69e2dbb3.js similarity index 50% rename from assets/routing.html.90ac5107.js rename to assets/routing.html.69e2dbb3.js index 74b76236f..787179154 100644 --- a/assets/routing.html.90ac5107.js +++ b/assets/routing.html.69e2dbb3.js @@ -1 +1 @@ -import{r as e,o,c as t,a as n,b as a,w as s,F as i,e as c,d as r}from"./app.755d843f.js";const l={},u=n("h1",{id:"routing",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#routing","aria-hidden":"true"},"#"),c(" Routing")],-1),p=n("p",null,"The routing module can send inbound data through different outbound connections according to different rules to achieve on-demand proxying.",-1),d=n("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),h=c("For a more detailed analysis of the routing function, please refer to "),m={href:"https://xtls.github.io/document/level-1/routing-lv1-part1.html",target:"_blank",rel:"noopener noreferrer"},q=c("Routing Function Analysis"),f=c("."),b=r('

    RoutingObject

    RoutingObject corresponds to the routing item in the configuration file.

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "domainMatcher": "hybrid",\n    "rules": [],\n    "balancers": []\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    domainStrategy: "AsIs" | "IPIfNonMatch" | "IPOnDemand"

    The domain name resolution strategy, which uses different strategies based on different settings.

    • "AsIs": Use only the domain name for routing selection. Default value.

    • "IPIfNonMatch": If the domain name does not match any rule, resolve the domain name into an IP address (A record or AAAA record) and match it again;

      • When a domain name has multiple A records, it will try to match all A records until one of them matches a rule;
      • The resolved IP only works for routing selection, and the original domain name is still used in the forwarded packets;
    • "IPOnDemand": If any IP-based rules are encountered during matching, immediately resolve the domain name into an IP address for matching;

    domainMatcher: "hybrid" | "linear"

    The domain name matching algorithm, which uses different algorithms based on different settings. This option affects all RuleObject that do not have a separately specified matching algorithm.

    • "hybrid": Use the new domain name matching algorithm, which is faster and takes up less space. Default value.
    • "linear": Use the original domain name matching algorithm.

    rules: [RuleObject]

    An array corresponding to a list of rules.

    For each connection, the routing will judge these rules from top to bottom in order. When it encounters the first effective rule, it will forward the connection to the outboundTag or balancerTag specified by the rule.

    Tip

    When no rules match, the traffic is sent out by the first outbound by default.

    balancers: [ BalancerObject ]

    An array corresponding to a list of load balancers.

    When a rule points to a load balancer, Xray selects an outbound through this load balancer, and then it forwards the traffic through it.

    RuleObject

    {\n  "domainMatcher": "hybrid",\n  "type": "field",\n  "domain": ["baidu.com", "qq.com", "geosite:cn"],\n  "ip": ["0.0.0.0/8", "10.0.0.0/8", "fc00::/7", "fe80::/10", "geoip:cn"],\n  "port": "53,443,1000-2000",\n  "sourcePort": "53,443,1000-2000",\n  "network": "tcp",\n  "source": ["10.0.0.1"],\n  "user": ["love@xray.com"],\n  "inboundTag": ["tag-vmess"],\n  "protocol": ["http", "tls", "bittorrent"],\n  "attrs": { ":method": "GET" },\n  "outboundTag": "direct",\n  "balancerTag": "balancer"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    Danger

    When multiple attributes are specified at the same time, these attributes need to be satisfied simultaneously in order for the current rule to take effect.

    domainMatcher: "hybrid" | "linear"

    The domain matching algorithm used varies depending on the settings. The option here takes priority over the domainMatcher configured in RoutingObject.

    • "hybrid": uses a new domain matching algorithm that is faster and takes up less space. This is the default value.
    • "linear": uses the original domain matching algorithm.

    type: "field"

    Currently, only the option "field" is supported.

    domain: [string]

    An array where each item is a domain match. There are several forms:

    ',26),g=r('
  • Plain string: If this string matches any part of the target domain, the rule takes effect. For example, "sina.com" can match "sina.com", "sina.com.cn", and "www.sina.com", but not "sina.cn".
  • Regular expression: Starts with "regexp:" followed by a regular expression. When this regular expression matches the target domain, the rule takes effect. For example, "regexp:\\.goo.*\\.com$" matches "www.google.com" or "fonts.googleapis.com", but not "google.com".
  • Subdomain (recommended): Starts with "domain:" followed by a domain. When this domain is the target domain or a subdomain of the target domain, the rule takes effect. For example, "domain:xray.com" matches "www.xray.com" and "xray.com", but not "wxray.com".
  • Exact match: Starts with "full:" followed by a domain. When this domain is an exact match for the target domain, the rule takes effect. For example, "full:xray.com" matches "xray.com" but not "www.xray.com".
  • Predefined domain list: Starts with "geosite:" followed by a name such as geosite:google or geosite:cn. The names and domain lists are listed in Predefined Domain List.
  • ',5),k=c("Load domains from a file: Formatted as "),y=n("code",null,'"ext:file:tag"',-1),w=c(", where the file is stored in the "),v=c("resource directory"),T=c(" and has the same format as "),x=n("code",null,"geosite.dat",-1),I=c(". The tag must exist in the file."),P=n("div",{class:"custom-container tip"},[n("p",{class:"custom-container-title"},"Tip"),n("p",null,[n("code",null,'"ext:geoip.dat:cn"'),c(" is equivalent to "),n("code",null,'"geoip:cn"')])],-1),j=n("p",null,[n("code",null,"ip"),c(": [string]")],-1),C=n("p",null,"An array where each item represents an IP range. This rule will take effect when the target IP matches any of the IP ranges in the array. There are several types of IP ranges:",-1),A=n("li",null,[n("p",null,[c("IP: In the format of "),n("code",null,'"127.0.0.1"'),c(".")])],-1),D={href:"https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing",target:"_blank",rel:"noopener noreferrer"},R=c("CIDR"),F=c(": In the format of "),O=n("code",null,'"10.0.0.0/8"',-1),S=c("."),W=r("
  • Predefined IP lists: These lists are included in every Xray installation package under the file name geoip.dat. They can be used in the format of "geoip:cn", where cn is a two-letter country code. The prefix geoip:(all lowercase) must be used, and nearly all countries that have internet access are supported.

    • Special value: "geoip:private", which includes all private addresses, such as 127.0.0.1.
  • ",1),M=c("Loading IP from a file: In the format of "),L=n("code",null,'"ext:file:tag"',-1),_=c(", where "),E=n("code",null,"file",-1),G=c(" is the file name and "),H=n("code",null,"tag",-1),N=c(" is a label that must exist in the file. The prefix "),U=n("code",null,"ext:",-1),X=c(" (all lowercase) must be used, and the file should be located in the "),B=c("resource directory"),Y=c(" with the same format as "),J=n("code",null,"geoip.dat",-1),K=c("."),$=r('

    port: number | string

    The target port range, which can take on three forms:

    • "a-b": a and b are both positive integers less than 65536. This range is a closed interval, and this rule will take effect when the target port falls within this range.
    • a: a is a positive integer less than 65536. This rule will take effect when the target port is a.
    • A mixture of the above two forms, separated by commas ",". For example: "53,443,1000-2000".

    sourcePort: number | string

    The source port, which can take on three forms:

    • "a-b": a and b are both positive integers less than 65536. This range is a closed interval, and this rule will take effect when the source port falls within this range.
    • a: a is a positive integer less than 65536. This rule will take effect when the source port is a.
    • A mixture of the above two forms, separated by commas ",". For example: "53,443,1000-2000".

    network: "tcp" | "udp" | "tcp,udp"

    This can be "tcp", "udp", or "tcp,udp". This rule will take effect when the connection method is the specified one.

    source: [string]

    An array where each item represents an IP range in the format of IP, CIDR, GeoIP, or loading IP from a file. This rule will take effect when the source IP matches any of the IP ranges in the array.

    user: [string]

    An array where each item represents an email address. This rule will take effect when the source user matches any of the email addresses in the array.

    inboundTag: [string]

    An array where each item represents an identifier. This rule will take effect when the inbound protocol matches any of the identifiers in the array.

    protocol: [ "http" | "tls" | "bittorrent" ]

    An array where each item represents a protocol. This rule will take effect when the protocol of the current connection matches any of the protocols in the array.

    Tip

    The sniffing option in the inbound proxy must be enabled to detect the protocol type used by the connection.

    attrs: object

    A json object with string keys and values, used to detect the HTTP headers of the traffic. It matches when all specified keys exist in the header and corresponding values are a substring of the header value. The key is case in-sensitive. You can use regex to match with value.

    Currently, only the inbound HTTP proxy sets this attribute.

    Examples:

    • Detect HTTP GET:{":method": "GET"}
    • Detect HTTP Path:{":path": "/test"}"
    • Detect Content Type:{"accept": "text/html"}"

    outboundTag: string

    Corresponds to the identifier of an outbound.

    balancerTag: string

    Corresponds to the identifier of a balancer.

    Tip

    balancerTag and outboundTag are mutually exclusive. When both are specified, outboundTag takes effect.

    BalancerObject

    Load balancer configuration. When a load balancer is in effect, it selects the most appropriate outbound from the specified outbound according to the configuration and forwards traffic.

    {\n  "tag": "balancer",\n  "selector": []\n}\n
    1
    2
    3
    4

    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).
    ',39),z=c("You can also find the complete list of domain names here: "),Q={href:"https://github.com/v2fly/domain-list-community",target:"_blank",rel:"noopener noreferrer"},V=c("Domain list community"),Z=c(".");l.render=function(c,r){const l=e("OutboundLink"),ee=e("RouterLink");return o(),t(i,null,[u,p,d,n("p",null,[h,n("a",m,[q,a(l)]),f]),b,n("ul",null,[g,n("li",null,[k,y,w,a(ee,{to:"/en/config/features/env.html#resource-file-path"},{default:s((()=>[v])),_:1}),T,x,I])]),P,j,C,n("ul",null,[A,n("li",null,[n("p",null,[n("a",D,[R,a(l)]),F,O,S])]),W,n("li",null,[n("p",null,[M,L,_,E,G,H,N,U,X,a(ee,{to:"/en/config/features/env.html#resource-file-path"},{default:s((()=>[B])),_:1}),Y,J,K])])]),$,n("p",null,[z,n("a",Q,[V,a(l)]),Z])],64)};export default l; +import{r as e,o,c as t,a as n,b as a,w as s,F as i,e as c,d as r}from"./app.48111a85.js";const l={},u=n("h1",{id:"routing",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#routing","aria-hidden":"true"},"#"),c(" Routing")],-1),p=n("p",null,"The routing module can send inbound data through different outbound connections according to different rules to achieve on-demand proxying.",-1),d=n("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),h=c("For a more detailed analysis of the routing function, please refer to "),m={href:"https://xtls.github.io/document/level-1/routing-lv1-part1.html",target:"_blank",rel:"noopener noreferrer"},q=c("Routing Function Analysis"),f=c("."),b=r('

    RoutingObject

    RoutingObject corresponds to the routing item in the configuration file.

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "domainMatcher": "hybrid",\n    "rules": [],\n    "balancers": []\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    domainStrategy: "AsIs" | "IPIfNonMatch" | "IPOnDemand"

    The domain name resolution strategy, which uses different strategies based on different settings.

    • "AsIs": Use only the domain name for routing selection. Default value.

    • "IPIfNonMatch": If the domain name does not match any rule, resolve the domain name into an IP address (A record or AAAA record) and match it again;

      • When a domain name has multiple A records, it will try to match all A records until one of them matches a rule;
      • The resolved IP only works for routing selection, and the original domain name is still used in the forwarded packets;
    • "IPOnDemand": If any IP-based rules are encountered during matching, immediately resolve the domain name into an IP address for matching;

    domainMatcher: "hybrid" | "linear"

    The domain name matching algorithm, which uses different algorithms based on different settings. This option affects all RuleObject that do not have a separately specified matching algorithm.

    • "hybrid": Use the new domain name matching algorithm, which is faster and takes up less space. Default value.
    • "linear": Use the original domain name matching algorithm.

    rules: [RuleObject]

    An array corresponding to a list of rules.

    For each connection, the routing will judge these rules from top to bottom in order. When it encounters the first effective rule, it will forward the connection to the outboundTag or balancerTag specified by the rule.

    Tip

    When no rules match, the traffic is sent out by the first outbound by default.

    balancers: [ BalancerObject ]

    An array corresponding to a list of load balancers.

    When a rule points to a load balancer, Xray selects an outbound through this load balancer, and then it forwards the traffic through it.

    RuleObject

    {\n  "domainMatcher": "hybrid",\n  "type": "field",\n  "domain": ["baidu.com", "qq.com", "geosite:cn"],\n  "ip": ["0.0.0.0/8", "10.0.0.0/8", "fc00::/7", "fe80::/10", "geoip:cn"],\n  "port": "53,443,1000-2000",\n  "sourcePort": "53,443,1000-2000",\n  "network": "tcp",\n  "source": ["10.0.0.1"],\n  "user": ["love@xray.com"],\n  "inboundTag": ["tag-vmess"],\n  "protocol": ["http", "tls", "bittorrent"],\n  "attrs": { ":method": "GET" },\n  "outboundTag": "direct",\n  "balancerTag": "balancer"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    Danger

    When multiple attributes are specified at the same time, these attributes need to be satisfied simultaneously in order for the current rule to take effect.

    domainMatcher: "hybrid" | "linear"

    The domain matching algorithm used varies depending on the settings. The option here takes priority over the domainMatcher configured in RoutingObject.

    • "hybrid": uses a new domain matching algorithm that is faster and takes up less space. This is the default value.
    • "linear": uses the original domain matching algorithm.

    type: "field"

    Currently, only the option "field" is supported.

    domain: [string]

    An array where each item is a domain match. There are several forms:

    ',26),g=r('
  • Plain string: If this string matches any part of the target domain, the rule takes effect. For example, "sina.com" can match "sina.com", "sina.com.cn", and "www.sina.com", but not "sina.cn".
  • Regular expression: Starts with "regexp:" followed by a regular expression. When this regular expression matches the target domain, the rule takes effect. For example, "regexp:\\\\.goo.*\\\\.com$" matches "www.google.com" or "fonts.googleapis.com", but not "google.com".
  • Subdomain (recommended): Starts with "domain:" followed by a domain. When this domain is the target domain or a subdomain of the target domain, the rule takes effect. For example, "domain:xray.com" matches "www.xray.com" and "xray.com", but not "wxray.com".
  • Exact match: Starts with "full:" followed by a domain. When this domain is an exact match for the target domain, the rule takes effect. For example, "full:xray.com" matches "xray.com" but not "www.xray.com".
  • Predefined domain list: Starts with "geosite:" followed by a name such as geosite:google or geosite:cn. The names and domain lists are listed in Predefined Domain List.
  • ',5),k=c("Load domains from a file: Formatted as "),y=n("code",null,'"ext:file:tag"',-1),w=c(", where the file is stored in the "),v=c("resource directory"),T=c(" and has the same format as "),x=n("code",null,"geosite.dat",-1),I=c(". The tag must exist in the file."),P=n("div",{class:"custom-container tip"},[n("p",{class:"custom-container-title"},"Tip"),n("p",null,[n("code",null,'"ext:geoip.dat:cn"'),c(" is equivalent to "),n("code",null,'"geoip:cn"')])],-1),j=n("p",null,[n("code",null,"ip"),c(": [string]")],-1),C=n("p",null,"An array where each item represents an IP range. This rule will take effect when the target IP matches any of the IP ranges in the array. There are several types of IP ranges:",-1),A=n("li",null,[n("p",null,[c("IP: In the format of "),n("code",null,'"127.0.0.1"'),c(".")])],-1),D={href:"https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing",target:"_blank",rel:"noopener noreferrer"},R=c("CIDR"),F=c(": In the format of "),O=n("code",null,'"10.0.0.0/8"',-1),S=c("."),W=r("
  • Predefined IP lists: These lists are included in every Xray installation package under the file name geoip.dat. They can be used in the format of "geoip:cn", where cn is a two-letter country code. The prefix geoip:(all lowercase) must be used, and nearly all countries that have internet access are supported.

    • Special value: "geoip:private", which includes all private addresses, such as 127.0.0.1.
  • ",1),M=c("Loading IP from a file: In the format of "),L=n("code",null,'"ext:file:tag"',-1),_=c(", where "),E=n("code",null,"file",-1),G=c(" is the file name and "),H=n("code",null,"tag",-1),N=c(" is a label that must exist in the file. The prefix "),U=n("code",null,"ext:",-1),X=c(" (all lowercase) must be used, and the file should be located in the "),B=c("resource directory"),Y=c(" with the same format as "),J=n("code",null,"geoip.dat",-1),K=c("."),$=r('

    port: number | string

    The target port range, which can take on three forms:

    • "a-b": a and b are both positive integers less than 65536. This range is a closed interval, and this rule will take effect when the target port falls within this range.
    • a: a is a positive integer less than 65536. This rule will take effect when the target port is a.
    • A mixture of the above two forms, separated by commas ",". For example: "53,443,1000-2000".

    sourcePort: number | string

    The source port, which can take on three forms:

    • "a-b": a and b are both positive integers less than 65536. This range is a closed interval, and this rule will take effect when the source port falls within this range.
    • a: a is a positive integer less than 65536. This rule will take effect when the source port is a.
    • A mixture of the above two forms, separated by commas ",". For example: "53,443,1000-2000".

    network: "tcp" | "udp" | "tcp,udp"

    This can be "tcp", "udp", or "tcp,udp". This rule will take effect when the connection method is the specified one.

    source: [string]

    An array where each item represents an IP range in the format of IP, CIDR, GeoIP, or loading IP from a file. This rule will take effect when the source IP matches any of the IP ranges in the array.

    user: [string]

    An array where each item represents an email address. This rule will take effect when the source user matches any of the email addresses in the array.

    inboundTag: [string]

    An array where each item represents an identifier. This rule will take effect when the inbound protocol matches any of the identifiers in the array.

    protocol: [ "http" | "tls" | "bittorrent" ]

    An array where each item represents a protocol. This rule will take effect when the protocol of the current connection matches any of the protocols in the array.

    Tip

    The sniffing option in the inbound proxy must be enabled to detect the protocol type used by the connection.

    attrs: object

    A json object with string keys and values, used to detect the HTTP headers of the traffic. It matches when all specified keys exist in the header and corresponding values are a substring of the header value. The key is case in-sensitive. You can use regex to match with value.

    Currently, only the inbound HTTP proxy sets this attribute.

    Examples:

    • Detect HTTP GET:{":method": "GET"}
    • Detect HTTP Path:{":path": "/test"}"
    • Detect Content Type:{"accept": "text/html"}"

    outboundTag: string

    Corresponds to the identifier of an outbound.

    balancerTag: string

    Corresponds to the identifier of a balancer.

    Tip

    balancerTag and outboundTag are mutually exclusive. When both are specified, outboundTag takes effect.

    BalancerObject

    Load balancer configuration. When a load balancer is in effect, it selects the most appropriate outbound from the specified outbound according to the configuration and forwards traffic.

    {\n  "tag": "balancer",\n  "selector": []\n}\n
    1
    2
    3
    4

    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).
    ',39),z=c("You can also find the complete list of domain names here: "),Q={href:"https://github.com/v2fly/domain-list-community",target:"_blank",rel:"noopener noreferrer"},V=c("Domain list community"),Z=c(".");l.render=function(c,r){const l=e("OutboundLink"),ee=e("RouterLink");return o(),t(i,null,[u,p,d,n("p",null,[h,n("a",m,[q,a(l)]),f]),b,n("ul",null,[g,n("li",null,[k,y,w,a(ee,{to:"/en/config/features/env.html#resource-file-path"},{default:s((()=>[v])),_:1}),T,x,I])]),P,j,C,n("ul",null,[A,n("li",null,[n("p",null,[n("a",D,[R,a(l)]),F,O,S])]),W,n("li",null,[n("p",null,[M,L,_,E,G,H,N,U,X,a(ee,{to:"/en/config/features/env.html#resource-file-path"},{default:s((()=>[B])),_:1}),Y,J,K])])]),$,n("p",null,[z,n("a",Q,[V,a(l)]),Z])],64)};export default l; diff --git a/assets/routing.html.72789fb7.js b/assets/routing.html.8627aedb.js similarity index 99% rename from assets/routing.html.72789fb7.js rename to assets/routing.html.8627aedb.js index 357f384cc..90857f78e 100644 --- a/assets/routing.html.72789fb7.js +++ b/assets/routing.html.8627aedb.js @@ -1 +1 @@ -import{r as o,o as n,c as t,a as s,b as a,w as e,F as c,e as p,d as u}from"./app.755d843f.js";const l={},r=s("h1",{id:"路由",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#路由","aria-hidden":"true"},"#"),p(" 路由")],-1),i=s("p",null,"路由功能模块可以将入站数据按不同规则由不同的出站连接发出,以达到按需代理的目的。",-1),d=s("p",null,"如常见用法是分流国内外流量,Xray 可以通过内部机制判断不同地区的流量,然后将它们发送到不同的出站代理。",-1),q=p("有关路由功能更详细的解析:"),b={href:"https://xtls.github.io/document/level-1/routing-lv1-part1.html",target:"_blank",rel:"noopener noreferrer"},k=p("路由 (routing) 功能简析"),g=u('

    RoutingObject

    RoutingObject 对应配置文件的 routing 项。

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "domainMatcher": "hybrid",\n    "rules": [],\n    "balancers": []\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    domainStrategy: "AsIs" | "IPIfNonMatch" | "IPOnDemand"

    域名解析策略,根据不同的设置使用不同的策略。

    • "AsIs":只使用域名进行路由选择。默认值。
    • "IPIfNonMatch":当域名没有匹配任何规则时,将域名解析成 IP(A 记录或 AAAA 记录)再次进行匹配;
      • 当一个域名有多个 A 记录时,会尝试匹配所有的 A 记录,直到其中一个与某个规则匹配为止;
      • 解析后的 IP 仅在路由选择时起作用,转发的数据包中依然使用原始域名;
    • "IPOnDemand":当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配;

    domainMatcher: "hybrid" | "linear"

    域名匹配算法,根据不同的设置使用不同的算法。此处选项会影响所有未单独指定匹配算法的 RuleObject

    • "hybrid":使用新的域名匹配算法,速度更快且占用更少。默认值。
    • "linear":使用原来的域名匹配算法。

    rules: [RuleObject]

    对应一个数组,数组中每一项是一个规则。

    对于每一个连接,路由将根据这些规则从上到下依次进行判断,当遇到第一个生效规则时,即将这个连接转发至它所指定的 outboundTagbalancerTag

    提示

    当没有匹配到任何规则时,流量默认由第一个 outbound 发出。

    balancers: [ BalancerObject ]

    一个数组,数组中每一项是一个负载均衡器的配置。

    当一个规则指向一个负载均衡器时,Xray 会通过此负载均衡器选出一个 outbound, 然后由它转发流量。

    RuleObject

    {\n  "domainMatcher": "hybrid",\n  "type": "field",\n  "domain": ["baidu.com", "qq.com", "geosite:cn"],\n  "ip": ["0.0.0.0/8", "10.0.0.0/8", "fc00::/7", "fe80::/10", "geoip:cn"],\n  "port": "53,443,1000-2000",\n  "sourcePort": "53,443,1000-2000",\n  "network": "tcp",\n  "source": ["10.0.0.1"],\n  "user": ["love@xray.com"],\n  "inboundTag": ["tag-vmess"],\n  "protocol": ["http", "tls", "bittorrent"],\n  "attrs": { ":method": "GET" },\n  "outboundTag": "direct",\n  "balancerTag": "balancer"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    警告

    当多个属性同时指定时,这些属性需要同时满足,才可以使当前规则生效。

    domainMatcher: "hybrid" | "linear"

    域名匹配算法,根据不同的设置使用不同的算法。此处选项优先级高于 RoutingObject 中配置的 domainMatcher

    • "hybrid":使用新的域名匹配算法,速度更快且占用更少。默认值。
    • "linear":使用原来的域名匹配算法。

    type: "field"

    目前只支持"field"这一个选项。

    domain: [string]

    一个数组,数组每一项是一个域名的匹配。有以下几种形式:

    ',26),m=u('
  • 纯字符串:当此字符串匹配目标域名中任意部分,该规则生效。比如 "sina.com" 可以匹配 "sina.com"、"sina.com.cn" 和 "www.sina.com",但不匹配 "sina.cn"。
  • 正则表达式:由 "regexp:" 开始,余下部分是一个正则表达式。当此正则表达式匹配目标域名时,该规则生效。例如 "regexp:\\\\.goo.*\\\\.com$" 匹配 "www.google.com" 或 "fonts.googleapis.com",但不匹配 "google.com"。
  • 子域名(推荐):由 "domain:" 开始,余下部分是一个域名。当此域名是目标域名或其子域名时,该规则生效。例如 "domain:xray.com" 匹配 "www.xray.com"、"xray.com",但不匹配 "wxray.com"。
  • 完整匹配:由 "full:" 开始,余下部分是一个域名。当此域名完整匹配目标域名时,该规则生效。例如 "full:xray.com" 匹配 "xray.com" 但不匹配 "www.xray.com"。
  • 预定义域名列表:由 "geosite:" 开头,余下部分是一个名称,如 geosite:google 或者 geosite:cn。名称及域名列表参考 预定义域名列表
  • ',5),h=p("从文件中加载域名:形如 "),y=s("code",null,'"ext:file:tag"',-1),f=p(",必须以 "),j=s("code",null,"ext:",-1),v=p("(小写)开头,后面跟文件名和标签,文件存放在 "),I=p("资源目录"),x=p(" 中,文件格式与 "),E=s("code",null,"geosite.dat",-1),P=p(" 相同,标签必须在文件中存在。"),T=s("div",{class:"custom-container tip"},[s("p",{class:"custom-container-title"},"提示"),s("p",null,[s("code",null,'"ext:geoip.dat:cn"'),p(" 等价于 "),s("code",null,'"geoip:cn"')])],-1),w=s("blockquote",null,[s("p",null,[s("code",null,"ip"),p(": [string]")])],-1),A=s("p",null,"一个数组,数组内每一项代表一个 IP 范围。当某一项匹配目标 IP 时,此规则生效。有以下几种形式:",-1),B=s("li",null,[p("IP:形如 "),s("code",null,'"127.0.0.1"'),p("。")],-1),O={href:"https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing",target:"_blank",rel:"noopener noreferrer"},R=p("CIDR"),D=p(":形如 "),M=s("code",null,'"10.0.0.0/8"',-1),_=p("。"),C=u("
  • 预定义 IP 列表:此列表预置于每一个 Xray 的安装包中,文件名为 geoip.dat。使用方式形如 "geoip:cn",必须以 geoip:(小写)开头,后面跟双字符国家代码,支持几乎所有可以上网的国家。
    • 特殊值:"geoip:private",包含所有私有地址,如 127.0.0.1
  • ",1),F=p("从文件中加载 IP:形如 "),G=s("code",null,'"ext:file:tag"',-1),N=p(",必须以 "),X=s("code",null,"ext:",-1),H=p("(小写)开头,后面跟文件名和标签,文件存放在 "),S=p("资源目录"),L=p(" 中,文件格式与 "),$=s("code",null,"geoip.dat",-1),z=p(" 相同标签必须在文件中存在。"),J=u('

    port:number | string

    目标端口范围,有三种形式:

    • "a-b":a 和 b 均为正整数,且小于 65536。这个范围是一个前后闭合区间,当目标端口落在此范围内时,此规则生效。
    • a:a 为正整数,且小于 65536。当目标端口为 a 时,此规则生效。
    • 以上两种形式的混合,以逗号 "," 分隔。形如:"53,443,1000-2000"

    sourcePort:number | string

    来源端口,有三种形式:

    • "a-b":a 和 b 均为正整数,且小于 65536。这个范围是一个前后闭合区间,当目标端口落在此范围内时,此规则生效。
    • a:a 为正整数,且小于 65536。当目标端口为 a 时,此规则生效。
    • 以上两种形式的混合,以逗号 "," 分隔。形如:"53,443,1000-2000"

    network: "tcp" | "udp" | "tcp,udp"

    可选的值有 "tcp"、"udp" 或 "tcp,udp",当连接方式是指定的方式时,此规则生效。

    source: [string]

    一个数组,数组内每一项代表一个 IP 范围,形式有 IP、CIDR、GeoIP 和从文件中加载 IP。当某一项匹配来源 IP 时,此规则生效。

    user: [string]

    一个数组,数组内每一项是一个邮箱地址。当某一项匹配来源用户时,此规则生效。

    inboundTag: [string]

    一个数组,数组内每一项是一个标识。当某一项匹配入站协议的标识时,此规则生效。

    protocol: [ "http" | "tls" | "bittorrent" ]

    一个数组,数组内每一项表示一种协议。当某一个协议匹配当前连接的协议类型时,此规则生效。

    提示

    必须开启入站代理中的 sniffing 选项, 才能嗅探出连接所使用的协议类型.

    attrs: object

    一个 json object,键名字和值皆为字符串,用于检测流量的属性值。当 HTTP headers 包含所有指定的键,并且值包含指定的子字符串,则命中此规则。键大小写不敏感。值支持使用正则表达式。

    目前只有 http 入站代理会设置这一属性。

    示例:

    • 检测 HTTP GET:{":method": "GET"}
    • 检测 HTTP Path:{":path": "/test"}"
    • 检测 Content Type:{"accept": "text/html"}"

    outboundTag: string

    对应一个 outbound 的标识。

    balancerTag: string

    对应一个 Balancer 的标识。

    提示

    balancerTagoutboundTag 须二选一。当同时指定时,outboundTag 生效。

    BalancerObject

    负载均衡器配置。当一个负载均衡器生效时,它会从指定的 outbound 中,按配置选出一个最合适的 outbound,进行流量转发。

    {\n  "tag": "balancer",\n  "selector": []\n}\n
    1
    2
    3
    4

    tag: string

    此负载均衡器的标识,用于匹配 RuleObject 中的 balancerTag

    selector: [ string ]

    一个字符串数组,其中每一个字符串将用于和 outbound 标识的前缀匹配。在以下几个 outbound 标识中:[ "a", "ab", "c", "ba" ]"selector": ["a"] 将匹配到 [ "a", "ab" ]

    如果匹配到多个 outbound,负载均衡器目前会从中随机选出一个作为最终的 outbound。

    预定义域名列表

    此列表预置于每一个 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(加拿大)等结尾的域名。
    ',39),K=p("你也可以在这里查看完整的域名列表 "),Q={href:"https://github.com/v2fly/domain-list-community",target:"_blank",rel:"noopener noreferrer"},U=p("Domain list community"),V=p("。");l.render=function(p,u){const l=o("OutboundLink"),W=o("RouterLink");return n(),t(c,null,[r,i,d,s("p",null,[q,s("a",b,[k,a(l)])]),g,s("ul",null,[m,s("li",null,[h,y,f,j,v,a(W,{to:"/config/features/env.html#%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84"},{default:e((()=>[I])),_:1}),x,E,P])]),T,w,A,s("ul",null,[B,s("li",null,[s("a",O,[R,a(l)]),D,M,_]),C,s("li",null,[F,G,N,X,H,a(W,{to:"/config/features/env.html#%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84"},{default:e((()=>[S])),_:1}),L,$,z])]),J,s("p",null,[K,s("a",Q,[U,a(l)]),V])],64)};export default l; +import{r as o,o as n,c as t,a as s,b as a,w as e,F as c,e as p,d as u}from"./app.48111a85.js";const l={},r=s("h1",{id:"路由",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#路由","aria-hidden":"true"},"#"),p(" 路由")],-1),i=s("p",null,"路由功能模块可以将入站数据按不同规则由不同的出站连接发出,以达到按需代理的目的。",-1),d=s("p",null,"如常见用法是分流国内外流量,Xray 可以通过内部机制判断不同地区的流量,然后将它们发送到不同的出站代理。",-1),q=p("有关路由功能更详细的解析:"),b={href:"https://xtls.github.io/document/level-1/routing-lv1-part1.html",target:"_blank",rel:"noopener noreferrer"},k=p("路由 (routing) 功能简析"),g=u('

    RoutingObject

    RoutingObject 对应配置文件的 routing 项。

    {\n  "routing": {\n    "domainStrategy": "AsIs",\n    "domainMatcher": "hybrid",\n    "rules": [],\n    "balancers": []\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8

    domainStrategy: "AsIs" | "IPIfNonMatch" | "IPOnDemand"

    域名解析策略,根据不同的设置使用不同的策略。

    • "AsIs":只使用域名进行路由选择。默认值。
    • "IPIfNonMatch":当域名没有匹配任何规则时,将域名解析成 IP(A 记录或 AAAA 记录)再次进行匹配;
      • 当一个域名有多个 A 记录时,会尝试匹配所有的 A 记录,直到其中一个与某个规则匹配为止;
      • 解析后的 IP 仅在路由选择时起作用,转发的数据包中依然使用原始域名;
    • "IPOnDemand":当匹配时碰到任何基于 IP 的规则,将域名立即解析为 IP 进行匹配;

    domainMatcher: "hybrid" | "linear"

    域名匹配算法,根据不同的设置使用不同的算法。此处选项会影响所有未单独指定匹配算法的 RuleObject

    • "hybrid":使用新的域名匹配算法,速度更快且占用更少。默认值。
    • "linear":使用原来的域名匹配算法。

    rules: [RuleObject]

    对应一个数组,数组中每一项是一个规则。

    对于每一个连接,路由将根据这些规则从上到下依次进行判断,当遇到第一个生效规则时,即将这个连接转发至它所指定的 outboundTagbalancerTag

    提示

    当没有匹配到任何规则时,流量默认由第一个 outbound 发出。

    balancers: [ BalancerObject ]

    一个数组,数组中每一项是一个负载均衡器的配置。

    当一个规则指向一个负载均衡器时,Xray 会通过此负载均衡器选出一个 outbound, 然后由它转发流量。

    RuleObject

    {\n  "domainMatcher": "hybrid",\n  "type": "field",\n  "domain": ["baidu.com", "qq.com", "geosite:cn"],\n  "ip": ["0.0.0.0/8", "10.0.0.0/8", "fc00::/7", "fe80::/10", "geoip:cn"],\n  "port": "53,443,1000-2000",\n  "sourcePort": "53,443,1000-2000",\n  "network": "tcp",\n  "source": ["10.0.0.1"],\n  "user": ["love@xray.com"],\n  "inboundTag": ["tag-vmess"],\n  "protocol": ["http", "tls", "bittorrent"],\n  "attrs": { ":method": "GET" },\n  "outboundTag": "direct",\n  "balancerTag": "balancer"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    警告

    当多个属性同时指定时,这些属性需要同时满足,才可以使当前规则生效。

    domainMatcher: "hybrid" | "linear"

    域名匹配算法,根据不同的设置使用不同的算法。此处选项优先级高于 RoutingObject 中配置的 domainMatcher

    • "hybrid":使用新的域名匹配算法,速度更快且占用更少。默认值。
    • "linear":使用原来的域名匹配算法。

    type: "field"

    目前只支持"field"这一个选项。

    domain: [string]

    一个数组,数组每一项是一个域名的匹配。有以下几种形式:

    ',26),m=u('
  • 纯字符串:当此字符串匹配目标域名中任意部分,该规则生效。比如 "sina.com" 可以匹配 "sina.com"、"sina.com.cn" 和 "www.sina.com",但不匹配 "sina.cn"。
  • 正则表达式:由 "regexp:" 开始,余下部分是一个正则表达式。当此正则表达式匹配目标域名时,该规则生效。例如 "regexp:\\\\.goo.*\\\\.com$" 匹配 "www.google.com" 或 "fonts.googleapis.com",但不匹配 "google.com"。
  • 子域名(推荐):由 "domain:" 开始,余下部分是一个域名。当此域名是目标域名或其子域名时,该规则生效。例如 "domain:xray.com" 匹配 "www.xray.com"、"xray.com",但不匹配 "wxray.com"。
  • 完整匹配:由 "full:" 开始,余下部分是一个域名。当此域名完整匹配目标域名时,该规则生效。例如 "full:xray.com" 匹配 "xray.com" 但不匹配 "www.xray.com"。
  • 预定义域名列表:由 "geosite:" 开头,余下部分是一个名称,如 geosite:google 或者 geosite:cn。名称及域名列表参考 预定义域名列表
  • ',5),h=p("从文件中加载域名:形如 "),y=s("code",null,'"ext:file:tag"',-1),f=p(",必须以 "),j=s("code",null,"ext:",-1),v=p("(小写)开头,后面跟文件名和标签,文件存放在 "),I=p("资源目录"),x=p(" 中,文件格式与 "),E=s("code",null,"geosite.dat",-1),P=p(" 相同,标签必须在文件中存在。"),T=s("div",{class:"custom-container tip"},[s("p",{class:"custom-container-title"},"提示"),s("p",null,[s("code",null,'"ext:geoip.dat:cn"'),p(" 等价于 "),s("code",null,'"geoip:cn"')])],-1),w=s("blockquote",null,[s("p",null,[s("code",null,"ip"),p(": [string]")])],-1),A=s("p",null,"一个数组,数组内每一项代表一个 IP 范围。当某一项匹配目标 IP 时,此规则生效。有以下几种形式:",-1),B=s("li",null,[p("IP:形如 "),s("code",null,'"127.0.0.1"'),p("。")],-1),O={href:"https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing",target:"_blank",rel:"noopener noreferrer"},R=p("CIDR"),D=p(":形如 "),M=s("code",null,'"10.0.0.0/8"',-1),_=p("。"),C=u("
  • 预定义 IP 列表:此列表预置于每一个 Xray 的安装包中,文件名为 geoip.dat。使用方式形如 "geoip:cn",必须以 geoip:(小写)开头,后面跟双字符国家代码,支持几乎所有可以上网的国家。
    • 特殊值:"geoip:private",包含所有私有地址,如 127.0.0.1
  • ",1),F=p("从文件中加载 IP:形如 "),G=s("code",null,'"ext:file:tag"',-1),N=p(",必须以 "),X=s("code",null,"ext:",-1),H=p("(小写)开头,后面跟文件名和标签,文件存放在 "),S=p("资源目录"),L=p(" 中,文件格式与 "),$=s("code",null,"geoip.dat",-1),z=p(" 相同标签必须在文件中存在。"),J=u('

    port:number | string

    目标端口范围,有三种形式:

    • "a-b":a 和 b 均为正整数,且小于 65536。这个范围是一个前后闭合区间,当目标端口落在此范围内时,此规则生效。
    • a:a 为正整数,且小于 65536。当目标端口为 a 时,此规则生效。
    • 以上两种形式的混合,以逗号 "," 分隔。形如:"53,443,1000-2000"

    sourcePort:number | string

    来源端口,有三种形式:

    • "a-b":a 和 b 均为正整数,且小于 65536。这个范围是一个前后闭合区间,当目标端口落在此范围内时,此规则生效。
    • a:a 为正整数,且小于 65536。当目标端口为 a 时,此规则生效。
    • 以上两种形式的混合,以逗号 "," 分隔。形如:"53,443,1000-2000"

    network: "tcp" | "udp" | "tcp,udp"

    可选的值有 "tcp"、"udp" 或 "tcp,udp",当连接方式是指定的方式时,此规则生效。

    source: [string]

    一个数组,数组内每一项代表一个 IP 范围,形式有 IP、CIDR、GeoIP 和从文件中加载 IP。当某一项匹配来源 IP 时,此规则生效。

    user: [string]

    一个数组,数组内每一项是一个邮箱地址。当某一项匹配来源用户时,此规则生效。

    inboundTag: [string]

    一个数组,数组内每一项是一个标识。当某一项匹配入站协议的标识时,此规则生效。

    protocol: [ "http" | "tls" | "bittorrent" ]

    一个数组,数组内每一项表示一种协议。当某一个协议匹配当前连接的协议类型时,此规则生效。

    提示

    必须开启入站代理中的 sniffing 选项, 才能嗅探出连接所使用的协议类型.

    attrs: object

    一个 json object,键名字和值皆为字符串,用于检测流量的属性值。当 HTTP headers 包含所有指定的键,并且值包含指定的子字符串,则命中此规则。键大小写不敏感。值支持使用正则表达式。

    目前只有 http 入站代理会设置这一属性。

    示例:

    • 检测 HTTP GET:{":method": "GET"}
    • 检测 HTTP Path:{":path": "/test"}"
    • 检测 Content Type:{"accept": "text/html"}"

    outboundTag: string

    对应一个 outbound 的标识。

    balancerTag: string

    对应一个 Balancer 的标识。

    提示

    balancerTagoutboundTag 须二选一。当同时指定时,outboundTag 生效。

    BalancerObject

    负载均衡器配置。当一个负载均衡器生效时,它会从指定的 outbound 中,按配置选出一个最合适的 outbound,进行流量转发。

    {\n  "tag": "balancer",\n  "selector": []\n}\n
    1
    2
    3
    4

    tag: string

    此负载均衡器的标识,用于匹配 RuleObject 中的 balancerTag

    selector: [ string ]

    一个字符串数组,其中每一个字符串将用于和 outbound 标识的前缀匹配。在以下几个 outbound 标识中:[ "a", "ab", "c", "ba" ]"selector": ["a"] 将匹配到 [ "a", "ab" ]

    如果匹配到多个 outbound,负载均衡器目前会从中随机选出一个作为最终的 outbound。

    预定义域名列表

    此列表预置于每一个 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(加拿大)等结尾的域名。
    ',39),K=p("你也可以在这里查看完整的域名列表 "),Q={href:"https://github.com/v2fly/domain-list-community",target:"_blank",rel:"noopener noreferrer"},U=p("Domain list community"),V=p("。");l.render=function(p,u){const l=o("OutboundLink"),W=o("RouterLink");return n(),t(c,null,[r,i,d,s("p",null,[q,s("a",b,[k,a(l)])]),g,s("ul",null,[m,s("li",null,[h,y,f,j,v,a(W,{to:"/config/features/env.html#%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84"},{default:e((()=>[I])),_:1}),x,E,P])]),T,w,A,s("ul",null,[B,s("li",null,[s("a",O,[R,a(l)]),D,M,_]),C,s("li",null,[F,G,N,X,H,a(W,{to:"/config/features/env.html#%E8%B5%84%E6%BA%90%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84"},{default:e((()=>[S])),_:1}),L,$,z])]),J,s("p",null,[K,s("a",Q,[U,a(l)]),V])],64)};export default l; diff --git a/assets/routing.html.d367b2ff.js b/assets/routing.html.a3a78f6c.js similarity index 54% rename from assets/routing.html.d367b2ff.js rename to assets/routing.html.a3a78f6c.js index 9acb8a258..60a9e7765 100644 --- a/assets/routing.html.d367b2ff.js +++ b/assets/routing.html.a3a78f6c.js @@ -1 +1 @@ -const e={key:"v-4bbe1d5a",path:"/en/config/routing.html",title:"Routing",lang:"en-US",frontmatter:{},excerpt:"",headers:[{level:2,title:"RoutingObject",slug:"routingobject",children:[{level:3,title:"RuleObject",slug:"ruleobject",children:[]},{level:3,title:"BalancerObject",slug:"balancerobject",children:[]},{level:3,title:"Predefined Domain Lists",slug:"predefined-domain-lists",children:[]}]}],filePathRelative:"en/config/routing.md",git:{updatedTime:1687739079e3,contributors:[{name:"yuhan6665",email:"1588741+yuhan6665@users.noreply.github.com",commits:3},{name:"Winston2084",email:"126307318+Winston2084@users.noreply.github.com",commits:1},{name:"hmol233",email:"82594500+hmol233@users.noreply.github.com",commits:1}]}};export{e as data}; +const e={key:"v-4bbe1d5a",path:"/en/config/routing.html",title:"Routing",lang:"en-US",frontmatter:{},excerpt:"",headers:[{level:2,title:"RoutingObject",slug:"routingobject",children:[{level:3,title:"RuleObject",slug:"ruleobject",children:[]},{level:3,title:"BalancerObject",slug:"balancerobject",children:[]},{level:3,title:"Predefined Domain Lists",slug:"predefined-domain-lists",children:[]}]}],filePathRelative:"en/config/routing.md",git:{updatedTime:1690627452e3,contributors:[{name:"yuhan6665",email:"1588741+yuhan6665@users.noreply.github.com",commits:3},{name:"Kobe Arthur Scofield",email:"kobearthurxc@outlook.com",commits:1},{name:"Winston2084",email:"126307318+Winston2084@users.noreply.github.com",commits:1},{name:"hmol233",email:"82594500+hmol233@users.noreply.github.com",commits:1}]}};export{e as data}; diff --git a/assets/selectAll.11c20240.js b/assets/selectAll.256eca5b.js similarity index 68% rename from assets/selectAll.11c20240.js rename to assets/selectAll.256eca5b.js index e7e6c22ef..878226260 100644 --- a/assets/selectAll.11c20240.js +++ b/assets/selectAll.256eca5b.js @@ -1 +1 @@ -import{a1 as e,a2 as t,a3 as n}from"./mermaid.core.a66200b0.js";function o(o){return"string"==typeof o?new e([document.querySelectorAll(o)],[document.documentElement]):new e([t(o)],n)}export{o as s}; +import{a1 as e,a2 as t,a3 as n}from"./mermaid.core.3a590193.js";function o(o){return"string"==typeof o?new e([document.querySelectorAll(o)],[document.documentElement]):new e([t(o)],n)}export{o as s}; diff --git a/assets/sequenceDiagram-edd7e28f.dfd6f6b9.js b/assets/sequenceDiagram-edd7e28f.9af17a9e.js similarity index 99% rename from assets/sequenceDiagram-edd7e28f.dfd6f6b9.js rename to assets/sequenceDiagram-edd7e28f.9af17a9e.js index 53194790c..04312f108 100644 --- a/assets/sequenceDiagram-edd7e28f.dfd6f6b9.js +++ b/assets/sequenceDiagram-edd7e28f.9af17a9e.js @@ -1 +1 @@ -import{g as t,x as e,v as a,c as i,s as r,b as n,a as s,m as o,z as c,l,d as h,j as d,e as p,h as g,i as u,y as x,n as y,ap as m,aE as b}from"./mermaid.core.a66200b0.js";import{d as f,a as T,b as E,g as w,c as v,e as _}from"./svgDrawCommon-f26cad39.9f4c1d32.js";import{s as P}from"./selectAll.11c20240.js";var L=function(){var t=function(t,e,a,i){for(a=a||{},i=t.length;i--;a[t[i]]=e);return a},e=[1,2],a=[1,3],i=[1,5],r=[1,7],n=[2,5],s=[1,15],o=[1,17],c=[1,19],l=[1,21],h=[1,22],d=[1,23],p=[1,29],g=[1,30],u=[1,31],x=[1,32],y=[1,33],m=[1,34],b=[1,35],f=[1,36],T=[1,37],E=[1,38],w=[1,39],v=[1,40],_=[1,41],P=[1,43],L=[1,44],k=[1,46],I=[1,47],M=[1,48],N=[1,49],A=[1,50],S=[1,51],O=[1,54],D=[1,4,5,19,21,23,26,28,34,35,36,38,40,41,42,43,44,46,48,49,51,52,53,54,55,57,58,63,64,65,66,74,84],R=[4,5,21,55,57],C=[4,5,19,21,23,26,28,34,35,36,38,40,41,42,43,44,46,48,49,51,55,57,58,63,64,65,66,74,84],$=[4,5,19,21,23,26,28,34,35,36,38,40,41,42,43,44,46,48,49,51,54,55,57,58,63,64,65,66,74,84],Y=[4,5,19,21,23,26,28,34,35,36,38,40,41,42,43,44,46,48,49,51,53,55,57,58,63,64,65,66,74,84],B=[4,5,19,21,23,26,28,34,35,36,38,40,41,42,43,44,46,48,49,51,52,55,57,58,63,64,65,66,74,84],V=[72,73,74],F=[1,128],W=[1,4,5,7,19,21,23,26,28,34,35,36,38,40,41,42,43,44,46,48,49,51,52,53,54,55,57,58,63,64,65,66,74,84],q={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,directive:6,SD:7,document:8,line:9,statement:10,box_section:11,box_line:12,participant_statement:13,openDirective:14,typeDirective:15,closeDirective:16,":":17,argDirective:18,box:19,restOfLine:20,end:21,signal:22,autonumber:23,NUM:24,off:25,activate:26,actor:27,deactivate:28,note_statement:29,links_statement:30,link_statement:31,properties_statement:32,details_statement:33,title:34,legacy_title:35,acc_title:36,acc_title_value:37,acc_descr:38,acc_descr_value:39,acc_descr_multiline_value:40,loop:41,rect:42,opt:43,alt:44,else_sections:45,par:46,par_sections:47,par_over:48,critical:49,option_sections:50,break:51,option:52,and:53,else:54,participant:55,AS:56,participant_actor:57,note:58,placement:59,text2:60,over:61,actor_pair:62,links:63,link:64,properties:65,details:66,spaceList:67,",":68,left_of:69,right_of:70,signaltype:71,"+":72,"-":73,ACTOR:74,SOLID_OPEN_ARROW:75,DOTTED_OPEN_ARROW:76,SOLID_ARROW:77,DOTTED_ARROW:78,SOLID_CROSS:79,DOTTED_CROSS:80,SOLID_POINT:81,DOTTED_POINT:82,TXT:83,open_directive:84,type_directive:85,arg_directive:86,close_directive:87,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",7:"SD",17:":",19:"box",20:"restOfLine",21:"end",23:"autonumber",24:"NUM",25:"off",26:"activate",28:"deactivate",34:"title",35:"legacy_title",36:"acc_title",37:"acc_title_value",38:"acc_descr",39:"acc_descr_value",40:"acc_descr_multiline_value",41:"loop",42:"rect",43:"opt",44:"alt",46:"par",48:"par_over",49:"critical",51:"break",52:"option",53:"and",54:"else",55:"participant",56:"AS",57:"participant_actor",58:"note",61:"over",63:"links",64:"link",65:"properties",66:"details",68:",",69:"left_of",70:"right_of",72:"+",73:"-",74:"ACTOR",75:"SOLID_OPEN_ARROW",76:"DOTTED_OPEN_ARROW",77:"SOLID_ARROW",78:"DOTTED_ARROW",79:"SOLID_CROSS",80:"DOTTED_CROSS",81:"SOLID_POINT",82:"DOTTED_POINT",83:"TXT",84:"open_directive",85:"type_directive",86:"arg_directive",87:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[9,1],[9,1],[11,0],[11,2],[12,2],[12,1],[12,1],[6,4],[6,6],[10,1],[10,4],[10,2],[10,4],[10,3],[10,3],[10,2],[10,3],[10,3],[10,2],[10,2],[10,2],[10,2],[10,2],[10,1],[10,1],[10,2],[10,2],[10,1],[10,4],[10,4],[10,4],[10,4],[10,4],[10,4],[10,4],[10,4],[10,1],[50,1],[50,4],[47,1],[47,4],[45,1],[45,4],[13,5],[13,3],[13,5],[13,3],[29,4],[29,4],[30,3],[31,3],[32,3],[33,3],[67,2],[67,1],[62,3],[62,1],[59,1],[59,1],[22,5],[22,5],[22,4],[27,1],[71,1],[71,1],[71,1],[71,1],[71,1],[71,1],[71,1],[71,1],[60,1],[14,1],[15,1],[18,1],[16,1]],performAction:function(t,e,a,i,r,n,s){var o=n.length-1;switch(r){case 4:return i.apply(n[o]),n[o];case 5:case 10:this.$=[];break;case 6:case 11:n[o-1].push(n[o]),this.$=n[o-1];break;case 7:case 8:case 12:case 13:this.$=n[o];break;case 9:case 14:this.$=[];break;case 18:n[o-1].unshift({type:"boxStart",boxData:i.parseBoxData(n[o-2])}),n[o-1].push({type:"boxEnd",boxText:n[o-2]}),this.$=n[o-1];break;case 20:this.$={type:"sequenceIndex",sequenceIndex:Number(n[o-2]),sequenceIndexStep:Number(n[o-1]),sequenceVisible:!0,signalType:i.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceIndex:Number(n[o-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:i.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:i.LINETYPE.AUTONUMBER};break;case 23:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:i.LINETYPE.AUTONUMBER};break;case 24:this.$={type:"activeStart",signalType:i.LINETYPE.ACTIVE_START,actor:n[o-1]};break;case 25:this.$={type:"activeEnd",signalType:i.LINETYPE.ACTIVE_END,actor:n[o-1]};break;case 31:i.setDiagramTitle(n[o].substring(6)),this.$=n[o].substring(6);break;case 32:i.setDiagramTitle(n[o].substring(7)),this.$=n[o].substring(7);break;case 33:this.$=n[o].trim(),i.setAccTitle(this.$);break;case 34:case 35:this.$=n[o].trim(),i.setAccDescription(this.$);break;case 36:n[o-1].unshift({type:"loopStart",loopText:i.parseMessage(n[o-2]),signalType:i.LINETYPE.LOOP_START}),n[o-1].push({type:"loopEnd",loopText:n[o-2],signalType:i.LINETYPE.LOOP_END}),this.$=n[o-1];break;case 37:n[o-1].unshift({type:"rectStart",color:i.parseMessage(n[o-2]),signalType:i.LINETYPE.RECT_START}),n[o-1].push({type:"rectEnd",color:i.parseMessage(n[o-2]),signalType:i.LINETYPE.RECT_END}),this.$=n[o-1];break;case 38:n[o-1].unshift({type:"optStart",optText:i.parseMessage(n[o-2]),signalType:i.LINETYPE.OPT_START}),n[o-1].push({type:"optEnd",optText:i.parseMessage(n[o-2]),signalType:i.LINETYPE.OPT_END}),this.$=n[o-1];break;case 39:n[o-1].unshift({type:"altStart",altText:i.parseMessage(n[o-2]),signalType:i.LINETYPE.ALT_START}),n[o-1].push({type:"altEnd",signalType:i.LINETYPE.ALT_END}),this.$=n[o-1];break;case 40:n[o-1].unshift({type:"parStart",parText:i.parseMessage(n[o-2]),signalType:i.LINETYPE.PAR_START}),n[o-1].push({type:"parEnd",signalType:i.LINETYPE.PAR_END}),this.$=n[o-1];break;case 41:n[o-1].unshift({type:"parStart",parText:i.parseMessage(n[o-2]),signalType:i.LINETYPE.PAR_OVER_START}),n[o-1].push({type:"parEnd",signalType:i.LINETYPE.PAR_END}),this.$=n[o-1];break;case 42:n[o-1].unshift({type:"criticalStart",criticalText:i.parseMessage(n[o-2]),signalType:i.LINETYPE.CRITICAL_START}),n[o-1].push({type:"criticalEnd",signalType:i.LINETYPE.CRITICAL_END}),this.$=n[o-1];break;case 43:n[o-1].unshift({type:"breakStart",breakText:i.parseMessage(n[o-2]),signalType:i.LINETYPE.BREAK_START}),n[o-1].push({type:"breakEnd",optText:i.parseMessage(n[o-2]),signalType:i.LINETYPE.BREAK_END}),this.$=n[o-1];break;case 46:this.$=n[o-3].concat([{type:"option",optionText:i.parseMessage(n[o-1]),signalType:i.LINETYPE.CRITICAL_OPTION},n[o]]);break;case 48:this.$=n[o-3].concat([{type:"and",parText:i.parseMessage(n[o-1]),signalType:i.LINETYPE.PAR_AND},n[o]]);break;case 50:this.$=n[o-3].concat([{type:"else",altText:i.parseMessage(n[o-1]),signalType:i.LINETYPE.ALT_ELSE},n[o]]);break;case 51:n[o-3].type="addParticipant",n[o-3].description=i.parseMessage(n[o-1]),this.$=n[o-3];break;case 52:n[o-1].type="addParticipant",this.$=n[o-1];break;case 53:n[o-3].type="addActor",n[o-3].description=i.parseMessage(n[o-1]),this.$=n[o-3];break;case 54:n[o-1].type="addActor",this.$=n[o-1];break;case 55:this.$=[n[o-1],{type:"addNote",placement:n[o-2],actor:n[o-1].actor,text:n[o]}];break;case 56:n[o-2]=[].concat(n[o-1],n[o-1]).slice(0,2),n[o-2][0]=n[o-2][0].actor,n[o-2][1]=n[o-2][1].actor,this.$=[n[o-1],{type:"addNote",placement:i.PLACEMENT.OVER,actor:n[o-2].slice(0,2),text:n[o]}];break;case 57:this.$=[n[o-1],{type:"addLinks",actor:n[o-1].actor,text:n[o]}];break;case 58:this.$=[n[o-1],{type:"addALink",actor:n[o-1].actor,text:n[o]}];break;case 59:this.$=[n[o-1],{type:"addProperties",actor:n[o-1].actor,text:n[o]}];break;case 60:this.$=[n[o-1],{type:"addDetails",actor:n[o-1].actor,text:n[o]}];break;case 63:this.$=[n[o-2],n[o]];break;case 64:this.$=n[o];break;case 65:this.$=i.PLACEMENT.LEFTOF;break;case 66:this.$=i.PLACEMENT.RIGHTOF;break;case 67:this.$=[n[o-4],n[o-1],{type:"addMessage",from:n[o-4].actor,to:n[o-1].actor,signalType:n[o-3],msg:n[o]},{type:"activeStart",signalType:i.LINETYPE.ACTIVE_START,actor:n[o-1]}];break;case 68:this.$=[n[o-4],n[o-1],{type:"addMessage",from:n[o-4].actor,to:n[o-1].actor,signalType:n[o-3],msg:n[o]},{type:"activeEnd",signalType:i.LINETYPE.ACTIVE_END,actor:n[o-4]}];break;case 69:this.$=[n[o-3],n[o-1],{type:"addMessage",from:n[o-3].actor,to:n[o-1].actor,signalType:n[o-2],msg:n[o]}];break;case 70:this.$={type:"addParticipant",actor:n[o]};break;case 71:this.$=i.LINETYPE.SOLID_OPEN;break;case 72:this.$=i.LINETYPE.DOTTED_OPEN;break;case 73:this.$=i.LINETYPE.SOLID;break;case 74:this.$=i.LINETYPE.DOTTED;break;case 75:this.$=i.LINETYPE.SOLID_CROSS;break;case 76:this.$=i.LINETYPE.DOTTED_CROSS;break;case 77:this.$=i.LINETYPE.SOLID_POINT;break;case 78:this.$=i.LINETYPE.DOTTED_POINT;break;case 79:this.$=i.parseMessage(n[o].trim().substring(1));break;case 80:i.parseDirective("%%{","open_directive");break;case 81:i.parseDirective(n[o],"type_directive");break;case 82:n[o]=n[o].trim().replace(/'/g,'"'),i.parseDirective(n[o],"arg_directive");break;case 83:i.parseDirective("}%%","close_directive","sequence")}},table:[{3:1,4:e,5:a,6:4,7:i,14:6,84:r},{1:[3]},{3:8,4:e,5:a,6:4,7:i,14:6,84:r},{3:9,4:e,5:a,6:4,7:i,14:6,84:r},{3:10,4:e,5:a,6:4,7:i,14:6,84:r},t([1,4,5,19,23,26,28,34,35,36,38,40,41,42,43,44,46,48,49,51,55,57,58,63,64,65,66,74,84],n,{8:11}),{15:12,85:[1,13]},{85:[2,80]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{1:[2,4],4:s,5:o,6:42,9:14,10:16,13:18,14:6,19:c,22:20,23:l,26:h,27:45,28:d,29:24,30:25,31:26,32:27,33:28,34:p,35:g,36:u,38:x,40:y,41:m,42:b,43:f,44:T,46:E,48:w,49:v,51:_,55:P,57:L,58:k,63:I,64:M,65:N,66:A,74:S,84:r},{16:52,17:[1,53],87:O},t([17,87],[2,81]),t(D,[2,6]),{6:42,10:55,13:18,14:6,19:c,22:20,23:l,26:h,27:45,28:d,29:24,30:25,31:26,32:27,33:28,34:p,35:g,36:u,38:x,40:y,41:m,42:b,43:f,44:T,46:E,48:w,49:v,51:_,55:P,57:L,58:k,63:I,64:M,65:N,66:A,74:S,84:r},t(D,[2,8]),t(D,[2,9]),t(D,[2,17]),{20:[1,56]},{5:[1,57]},{5:[1,60],24:[1,58],25:[1,59]},{27:61,74:S},{27:62,74:S},{5:[1,63]},{5:[1,64]},{5:[1,65]},{5:[1,66]},{5:[1,67]},t(D,[2,31]),t(D,[2,32]),{37:[1,68]},{39:[1,69]},t(D,[2,35]),{20:[1,70]},{20:[1,71]},{20:[1,72]},{20:[1,73]},{20:[1,74]},{20:[1,75]},{20:[1,76]},{20:[1,77]},t(D,[2,44]),{27:78,74:S},{27:79,74:S},{71:80,75:[1,81],76:[1,82],77:[1,83],78:[1,84],79:[1,85],80:[1,86],81:[1,87],82:[1,88]},{59:89,61:[1,90],69:[1,91],70:[1,92]},{27:93,74:S},{27:94,74:S},{27:95,74:S},{27:96,74:S},t([5,56,68,75,76,77,78,79,80,81,82,83],[2,70]),{5:[1,97]},{18:98,86:[1,99]},{5:[2,83]},t(D,[2,7]),t(R,[2,10],{11:100}),t(D,[2,19]),{5:[1,102],24:[1,101]},{5:[1,103]},t(D,[2,23]),{5:[1,104]},{5:[1,105]},t(D,[2,26]),t(D,[2,27]),t(D,[2,28]),t(D,[2,29]),t(D,[2,30]),t(D,[2,33]),t(D,[2,34]),t(C,n,{8:106}),t(C,n,{8:107}),t(C,n,{8:108}),t($,n,{45:109,8:110}),t(Y,n,{47:111,8:112}),t(Y,n,{8:112,47:113}),t(B,n,{50:114,8:115}),t(C,n,{8:116}),{5:[1,118],56:[1,117]},{5:[1,120],56:[1,119]},{27:123,72:[1,121],73:[1,122],74:S},t(V,[2,71]),t(V,[2,72]),t(V,[2,73]),t(V,[2,74]),t(V,[2,75]),t(V,[2,76]),t(V,[2,77]),t(V,[2,78]),{27:124,74:S},{27:126,62:125,74:S},{74:[2,65]},{74:[2,66]},{60:127,83:F},{60:129,83:F},{60:130,83:F},{60:131,83:F},t(W,[2,15]),{16:132,87:O},{87:[2,82]},{4:[1,135],5:[1,137],12:134,13:136,21:[1,133],55:P,57:L},{5:[1,138]},t(D,[2,21]),t(D,[2,22]),t(D,[2,24]),t(D,[2,25]),{4:s,5:o,6:42,9:14,10:16,13:18,14:6,19:c,21:[1,139],22:20,23:l,26:h,27:45,28:d,29:24,30:25,31:26,32:27,33:28,34:p,35:g,36:u,38:x,40:y,41:m,42:b,43:f,44:T,46:E,48:w,49:v,51:_,55:P,57:L,58:k,63:I,64:M,65:N,66:A,74:S,84:r},{4:s,5:o,6:42,9:14,10:16,13:18,14:6,19:c,21:[1,140],22:20,23:l,26:h,27:45,28:d,29:24,30:25,31:26,32:27,33:28,34:p,35:g,36:u,38:x,40:y,41:m,42:b,43:f,44:T,46:E,48:w,49:v,51:_,55:P,57:L,58:k,63:I,64:M,65:N,66:A,74:S,84:r},{4:s,5:o,6:42,9:14,10:16,13:18,14:6,19:c,21:[1,141],22:20,23:l,26:h,27:45,28:d,29:24,30:25,31:26,32:27,33:28,34:p,35:g,36:u,38:x,40:y,41:m,42:b,43:f,44:T,46:E,48:w,49:v,51:_,55:P,57:L,58:k,63:I,64:M,65:N,66:A,74:S,84:r},{21:[1,142]},{4:s,5:o,6:42,9:14,10:16,13:18,14:6,19:c,21:[2,49],22:20,23:l,26:h,27:45,28:d,29:24,30:25,31:26,32:27,33:28,34:p,35:g,36:u,38:x,40:y,41:m,42:b,43:f,44:T,46:E,48:w,49:v,51:_,54:[1,143],55:P,57:L,58:k,63:I,64:M,65:N,66:A,74:S,84:r},{21:[1,144]},{4:s,5:o,6:42,9:14,10:16,13:18,14:6,19:c,21:[2,47],22:20,23:l,26:h,27:45,28:d,29:24,30:25,31:26,32:27,33:28,34:p,35:g,36:u,38:x,40:y,41:m,42:b,43:f,44:T,46:E,48:w,49:v,51:_,53:[1,145],55:P,57:L,58:k,63:I,64:M,65:N,66:A,74:S,84:r},{21:[1,146]},{21:[1,147]},{4:s,5:o,6:42,9:14,10:16,13:18,14:6,19:c,21:[2,45],22:20,23:l,26:h,27:45,28:d,29:24,30:25,31:26,32:27,33:28,34:p,35:g,36:u,38:x,40:y,41:m,42:b,43:f,44:T,46:E,48:w,49:v,51:_,52:[1,148],55:P,57:L,58:k,63:I,64:M,65:N,66:A,74:S,84:r},{4:s,5:o,6:42,9:14,10:16,13:18,14:6,19:c,21:[1,149],22:20,23:l,26:h,27:45,28:d,29:24,30:25,31:26,32:27,33:28,34:p,35:g,36:u,38:x,40:y,41:m,42:b,43:f,44:T,46:E,48:w,49:v,51:_,55:P,57:L,58:k,63:I,64:M,65:N,66:A,74:S,84:r},{20:[1,150]},t(D,[2,52]),{20:[1,151]},t(D,[2,54]),{27:152,74:S},{27:153,74:S},{60:154,83:F},{60:155,83:F},{60:156,83:F},{68:[1,157],83:[2,64]},{5:[2,57]},{5:[2,79]},{5:[2,58]},{5:[2,59]},{5:[2,60]},{5:[1,158]},t(D,[2,18]),t(R,[2,11]),{13:159,55:P,57:L},t(R,[2,13]),t(R,[2,14]),t(D,[2,20]),t(D,[2,36]),t(D,[2,37]),t(D,[2,38]),t(D,[2,39]),{20:[1,160]},t(D,[2,40]),{20:[1,161]},t(D,[2,41]),t(D,[2,42]),{20:[1,162]},t(D,[2,43]),{5:[1,163]},{5:[1,164]},{60:165,83:F},{60:166,83:F},{5:[2,69]},{5:[2,55]},{5:[2,56]},{27:167,74:S},t(W,[2,16]),t(R,[2,12]),t($,n,{8:110,45:168}),t(Y,n,{8:112,47:169}),t(B,n,{8:115,50:170}),t(D,[2,51]),t(D,[2,53]),{5:[2,67]},{5:[2,68]},{83:[2,63]},{21:[2,50]},{21:[2,48]},{21:[2,46]}],defaultActions:{7:[2,80],8:[2,1],9:[2,2],10:[2,3],54:[2,83],91:[2,65],92:[2,66],99:[2,82],127:[2,57],128:[2,79],129:[2,58],130:[2,59],131:[2,60],154:[2,69],155:[2,55],156:[2,56],165:[2,67],166:[2,68],167:[2,63],168:[2,50],169:[2,48],170:[2,46]},parseError:function(t,e){if(!e.recoverable){var a=new Error(t);throw a.hash=e,a}this.trace(t)},parse:function(t){var e=this,a=[0],i=[],r=[null],n=[],s=this.table,o="",c=0,l=0,h=2,d=1,p=n.slice.call(arguments,1),g=Object.create(this.lexer),u={yy:{}};for(var x in this.yy)Object.prototype.hasOwnProperty.call(this.yy,x)&&(u.yy[x]=this.yy[x]);g.setInput(t,u.yy),u.yy.lexer=g,u.yy.parser=this,void 0===g.yylloc&&(g.yylloc={});var y=g.yylloc;n.push(y);var m=g.options&&g.options.ranges;function b(){var t;return"number"!=typeof(t=i.pop()||g.lex()||d)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var f,T,E,w,v,_,P,L,k={};;){if(T=a[a.length-1],this.defaultActions[T]?E=this.defaultActions[T]:(null==f&&(f=b()),E=s[T]&&s[T][f]),void 0===E||!E.length||!E[0]){var I="";for(v in L=[],s[T])this.terminals_[v]&&v>h&&L.push("'"+this.terminals_[v]+"'");I=g.showPosition?"Parse error on line "+(c+1)+":\n"+g.showPosition()+"\nExpecting "+L.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(c+1)+": Unexpected "+(f==d?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(I,{text:g.match,token:this.terminals_[f]||f,line:g.yylineno,loc:y,expected:L})}if(E[0]instanceof Array&&E.length>1)throw new Error("Parse Error: multiple actions possible at state: "+T+", token: "+f);switch(E[0]){case 1:a.push(f),r.push(g.yytext),n.push(g.yylloc),a.push(E[1]),f=null,l=g.yyleng,o=g.yytext,c=g.yylineno,y=g.yylloc;break;case 2:if(_=this.productions_[E[1]][1],k.$=r[r.length-_],k._$={first_line:n[n.length-(_||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(_||1)].first_column,last_column:n[n.length-1].last_column},m&&(k._$.range=[n[n.length-(_||1)].range[0],n[n.length-1].range[1]]),void 0!==(w=this.performAction.apply(k,[o,l,c,u.yy,E[1],r,n].concat(p))))return w;_&&(a=a.slice(0,-1*_*2),r=r.slice(0,-1*_),n=n.slice(0,-1*_)),a.push(this.productions_[E[1]][0]),r.push(k.$),n.push(k._$),P=s[a[a.length-2]][a[a.length-1]],a.push(P);break;case 3:return!0}}return!0}},z={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,a=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 i=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 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:a?(a.length===i.length?this.yylloc.first_column:0)+i[i.length-a.length].length-a[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(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var a,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],a=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a)return a;if(this._backtrack){for(var n in r)this[n]=r[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,a,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),n=0;ne[0].length)){if(e=a,i=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(a,r[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,a,i){switch(a){case 0:return this.begin("open_directive"),84;case 1:return this.begin("type_directive"),85;case 2:return this.popState(),this.begin("arg_directive"),17;case 3:return this.popState(),this.popState(),87;case 4:return 86;case 5:return 5;case 6:case 7:case 8:case 9:case 10:break;case 11:return 24;case 12:return this.begin("LINE"),19;case 13:return this.begin("ID"),55;case 14:return this.begin("ID"),57;case 15:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),74;case 16:return this.popState(),this.popState(),this.begin("LINE"),56;case 17:return this.popState(),this.popState(),5;case 18:return this.begin("LINE"),41;case 19:return this.begin("LINE"),42;case 20:return this.begin("LINE"),43;case 21:return this.begin("LINE"),44;case 22:return this.begin("LINE"),54;case 23:return this.begin("LINE"),46;case 24:return this.begin("LINE"),48;case 25:return this.begin("LINE"),53;case 26:return this.begin("LINE"),49;case 27:return this.begin("LINE"),52;case 28:return this.begin("LINE"),51;case 29:return this.popState(),20;case 30:return 21;case 31:return 69;case 32:return 70;case 33:return 63;case 34:return 64;case 35:return 65;case 36:return 66;case 37:return 61;case 38:return 58;case 39:return this.begin("ID"),26;case 40:return this.begin("ID"),28;case 41:return 34;case 42:return 35;case 43:return this.begin("acc_title"),36;case 44:return this.popState(),"acc_title_value";case 45:return this.begin("acc_descr"),38;case 46:return this.popState(),"acc_descr_value";case 47:this.begin("acc_descr_multiline");break;case 48:this.popState();break;case 49:return"acc_descr_multiline_value";case 50:return 7;case 51:return 23;case 52:return 25;case 53:return 68;case 54:return 5;case 55:return e.yytext=e.yytext.trim(),74;case 56:return 77;case 57:return 78;case 58:return 75;case 59:return 76;case 60:return 79;case 61:return 80;case 62:return 81;case 63:return 82;case 64:return 83;case 65:return 72;case 66:return 73;case 67:return 5;case 68:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[48,49],inclusive:!1},acc_descr:{rules:[46],inclusive:!1},acc_title:{rules:[44],inclusive:!1},open_directive:{rules:[1,8],inclusive:!1},type_directive:{rules:[2,3,8],inclusive:!1},arg_directive:{rules:[3,4,8],inclusive:!1},ID:{rules:[7,8,15],inclusive:!1},ALIAS:{rules:[7,8,16,17],inclusive:!1},LINE:{rules:[7,8,29],inclusive:!1},INITIAL:{rules:[0,5,6,8,9,10,11,12,13,14,18,19,20,21,22,23,24,25,26,27,28,30,31,32,33,34,35,36,37,38,39,40,41,42,43,45,47,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68],inclusive:!0}}};function H(){this.yy={}}return q.lexer=z,H.prototype=q,q.Parser=H,new H}();L.parser=L;const k=L;let I,M,N,A={},S=[],O=[],D=!1;const R=function(t,e,a,i){let r=N;const n=A[t];if(n){if(N&&n.box&&N!==n.box)throw new Error("A same participant should only be defined in one Box: "+n.name+" can't be in '"+n.box.name+"' and in '"+N.name+"' at the same time.");if(r=n.box?n.box:N,n.box=r,n&&e===n.name&&null==a)return}null!=a&&null!=a.text||(a={text:e,wrap:null,type:i}),null!=i&&null!=a.text||(a={text:e,wrap:null,type:i}),A[t]={box:r,name:e,description:a.text,wrap:void 0===a.wrap&&Y()||!!a.wrap,prevActor:I,links:{},properties:{},actorCnt:null,rectData:null,type:i||"participant"},I&&A[I]&&(A[I].nextActor=t),N&&N.actorKeys.push(t),I=t},C=function(t,e,a={text:void 0,wrap:void 0},i){if(i===B.ACTIVE_END){if((t=>{let e,a=0;for(e=0;e>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},e}}return O.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&Y()||!!a.wrap,type:i}),!0},$=function(t){return A[t]},Y=()=>void 0!==M?M:i().sequence.wrap,B={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32},V=function(t,e,a){a.text,void 0===a.wrap&&Y()||a.wrap;const i=[].concat(t,t);O.push({from:i[0],to:i[1],message:a.text,wrap:void 0===a.wrap&&Y()||!!a.wrap,type:B.NOTE,placement:e})},F=function(t,e){const a=$(t);try{let t=h(e.text,i());t=t.replace(/&/g,"&"),t=t.replace(/=/g,"=");W(a,JSON.parse(t))}catch(r){l.error("error while parsing actor link text",r)}};function W(t,e){if(null==t.links)t.links=e;else for(let a in e)t.links[a]=e[a]}const q=function(t,e){const a=$(t);try{let t=h(e.text,i());z(a,JSON.parse(t))}catch(r){l.error("error while parsing actor properties text",r)}};function z(t,e){if(null==t.properties)t.properties=e;else for(let a in e)t.properties[a]=e[a]}const H=function(t,e){const a=$(t),i=document.getElementById(e.text);try{const t=i.innerHTML,e=JSON.parse(t);e.properties&&z(a,e.properties),e.links&&W(a,e.links)}catch(r){l.error("error while parsing actor details text",r)}},U=function(t){if(Array.isArray(t))t.forEach((function(t){U(t)}));else switch(t.type){case"sequenceIndex":O.push({from:void 0,to:void 0,message:{start:t.sequenceIndex,step:t.sequenceIndexStep,visible:t.sequenceVisible},wrap:!1,type:t.signalType});break;case"addParticipant":R(t.actor,t.actor,t.description,"participant");break;case"addActor":R(t.actor,t.actor,t.description,"actor");break;case"activeStart":case"activeEnd":C(t.actor,void 0,void 0,t.signalType);break;case"addNote":V(t.actor,t.placement,t.text);break;case"addLinks":F(t.actor,t.text);break;case"addALink":!function(t,e){const a=$(t);try{const t={};let o=h(e.text,i());var r=o.indexOf("@");o=o.replace(/&/g,"&"),o=o.replace(/=/g,"=");var n=o.slice(0,r-1).trim(),s=o.slice(r+1).trim();t[n]=s,W(a,t)}catch(o){l.error("error while parsing actor link text",o)}}(t.actor,t.text);break;case"addProperties":q(t.actor,t.text);break;case"addDetails":H(t.actor,t.text);break;case"addMessage":C(t.from,t.to,t.msg,t.signalType);break;case"boxStart":e=t.boxData,S.push({name:e.text,wrap:void 0===e.wrap&&Y()||!!e.wrap,fill:e.color,actorKeys:[]}),N=S.slice(-1)[0];break;case"boxEnd":N=void 0;break;case"loopStart":C(void 0,void 0,t.loopText,t.signalType);break;case"loopEnd":C(void 0,void 0,void 0,t.signalType);break;case"rectStart":C(void 0,void 0,t.color,t.signalType);break;case"rectEnd":C(void 0,void 0,void 0,t.signalType);break;case"optStart":C(void 0,void 0,t.optText,t.signalType);break;case"optEnd":C(void 0,void 0,void 0,t.signalType);break;case"altStart":case"else":C(void 0,void 0,t.altText,t.signalType);break;case"altEnd":C(void 0,void 0,void 0,t.signalType);break;case"setAccTitle":r(t.text);break;case"parStart":case"and":C(void 0,void 0,t.parText,t.signalType);break;case"parEnd":C(void 0,void 0,void 0,t.signalType);break;case"criticalStart":C(void 0,void 0,t.criticalText,t.signalType);break;case"option":C(void 0,void 0,t.optionText,t.signalType);break;case"criticalEnd":C(void 0,void 0,void 0,t.signalType);break;case"breakStart":C(void 0,void 0,t.breakText,t.signalType);break;case"breakEnd":C(void 0,void 0,void 0,t.signalType)}var e},j={addActor:R,addMessage:function(t,e,a,i){O.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&Y()||!!a.wrap,answer:i})},addSignal:C,addLinks:F,addDetails:H,addProperties:q,autoWrap:Y,setWrap:function(t){M=t},enableSequenceNumbers:function(){D=!0},disableSequenceNumbers:function(){D=!1},showSequenceNumbers:()=>D,getMessages:function(){return O},getActors:function(){return A},getActor:$,getActorKeys:function(){return Object.keys(A)},getActorProperty:function(t,e){if(void 0!==t&&void 0!==t.properties)return t.properties[e]},getAccTitle:t,getBoxes:function(){return S},getDiagramTitle:e,setDiagramTitle:a,parseDirective:function(t,e,a){o.parseDirective(this,t,e,a)},getConfig:()=>i().sequence,clear:function(){A={},S=[],O=[],D=!1,c()},parseMessage:function(t){const e=t.trim(),a={text:e.replace(/^:?(?:no)?wrap:/,"").trim(),wrap:null!==e.match(/^:?wrap:/)||null===e.match(/^:?nowrap:/)&&void 0};return l.debug("parseMessage:",a),a},parseBoxData:function(t){const e=t.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/);let a=null!=e&&e[1]?e[1].trim():"transparent",r=null!=e&&e[2]?e[2].trim():void 0;if(window&&window.CSS)window.CSS.supports("color",a)||(a="transparent",r=t.trim());else{const e=(new Option).style;e.color=a,e.color!==a&&(a="transparent",r=t.trim())}return{color:a,text:void 0!==r?h(r.replace(/^:?(?:no)?wrap:/,""),i()):void 0,wrap:void 0!==r?null!==r.match(/^:?wrap:/)||null===r.match(/^:?nowrap:/)&&void 0:void 0}},LINETYPE:B,ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},addNote:V,setAccTitle:r,apply:U,setAccDescription:n,getAccDescription:s,hasAtLeastOneBox:function(){return S.length>0},hasAtLeastOneBoxWithTitle:function(){return S.some((t=>t.name))}},K=t=>`.actor {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n\n text.actor > tspan {\n fill: ${t.actorTextColor};\n stroke: none;\n }\n\n .actor-line {\n stroke: ${t.actorLineColor};\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ${t.signalColor};\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ${t.signalColor};\n }\n\n #arrowhead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .sequenceNumber {\n fill: ${t.sequenceNumberColor};\n }\n\n #sequencenumber {\n fill: ${t.signalColor};\n }\n\n #crosshead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .messageText {\n fill: ${t.signalTextColor};\n stroke: none;\n }\n\n .labelBox {\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBkgColor};\n }\n\n .labelText, .labelText > tspan {\n fill: ${t.labelTextColor};\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ${t.loopTextColor};\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBorderColor};\n }\n\n .note {\n //stroke: #decc93;\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n }\n\n .noteText, .noteText > tspan {\n fill: ${t.noteTextColor};\n stroke: none;\n }\n\n .activation0 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation1 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation2 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .actorPopupMenu {\n position: absolute;\n }\n\n .actorPopupMenuPanel {\n position: absolute;\n fill: ${t.actorBkg};\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));\n}\n .actor-man line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n .actor-man circle, line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n stroke-width: 2px;\n }\n`,X=function(t,e){return f(t,e)},G=(t,e)=>{b((()=>{const a=document.querySelectorAll(t);0!==a.length&&(a[0].addEventListener("mouseover",(function(){J("actor"+e+"_popup")})),a[0].addEventListener("mouseout",(function(){Q("actor"+e+"_popup")})))}))},J=function(t){var e=document.getElementById(t);null!=e&&(e.style.display="block")},Q=function(t){var e=document.getElementById(t);null!=e&&(e.style.display="none")},Z=function(t,e){let a=0,i=0;const r=e.text.split(d.lineBreakRegex),[n,s]=m(e.fontSize);let o=[],c=0,l=()=>e.y;if(void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0)switch(e.valign){case"top":case"start":l=()=>Math.round(e.y+e.textMargin);break;case"middle":case"center":l=()=>Math.round(e.y+(a+i+e.textMargin)/2);break;case"bottom":case"end":l=()=>Math.round(e.y+(a+i+2*e.textMargin)-e.textMargin)}if(void 0!==e.anchor&&void 0!==e.textMargin&&void 0!==e.width)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle"}for(let[h,d]of r.entries()){void 0!==e.textMargin&&0===e.textMargin&&void 0!==n&&(c=h*n);const r=t.append("text");if(r.attr("x",e.x),r.attr("y",l()),void 0!==e.anchor&&r.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),void 0!==e.fontFamily&&r.style("font-family",e.fontFamily),void 0!==s&&r.style("font-size",s),void 0!==e.fontWeight&&r.style("font-weight",e.fontWeight),void 0!==e.fill&&r.attr("fill",e.fill),void 0!==e.class&&r.attr("class",e.class),void 0!==e.dy?r.attr("dy",e.dy):0!==c&&r.attr("dy",c),e.tspan){const t=r.append("tspan");t.attr("x",e.x),void 0!==e.fill&&t.attr("fill",e.fill),t.text(d)}else r.text(d);void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0&&(i+=(r._groups||r)[0][0].getBBox().height,a=i),o.push(r)}return o},tt=function(t,e){const a=t.append("polygon");var i,r,n,s,o;return a.attr("points",(i=e.x,r=e.y,n=e.width,s=e.height,i+","+r+" "+(i+n)+","+r+" "+(i+n)+","+(r+s-(o=7))+" "+(i+n-1.2*o)+","+(r+s)+" "+i+","+(r+s))),a.attr("class","labelBox"),e.y=e.y+e.height/2,Z(t,e),a};let et=-1;const at=(t,e)=>{t.selectAll&&t.selectAll(".actor-line").attr("class","200").attr("y2",e-55)},it=function(t,e){E(t,e)},rt=function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},nt=function(){function t(t,e,a,r,n,s,o){i(e.append("text").attr("x",a+n/2).attr("y",r+s/2+5).style("text-anchor","middle").text(t),o)}function e(t,e,a,r,n,s,o,c){const{actorFontSize:l,actorFontFamily:h,actorFontWeight:p}=c,[g,u]=m(l),x=t.split(d.lineBreakRegex);for(let d=0;da?o.width:a;const p=l.append("rect");if(p.attr("class","actorPopupMenuPanel"+h),p.attr("x",o.x),p.attr("y",o.height),p.attr("fill",o.fill),p.attr("stroke",o.stroke),p.attr("width",d),p.attr("height",o.height),p.attr("rx",o.rx),p.attr("ry",o.ry),null!=n){var g=20;for(let t in n){var u=l.append("a"),x=y(n[t]);u.attr("xlink:href",x),u.attr("target","_blank"),st(i)(t,u,o.x+10,o.height+g,d,20,{class:"actor"},i),g+=30}}return p.attr("height",g),{height:o.height+g,width:d}},anchorElement:function(t){return t.append("g")},drawActivation:function(t,e,a,i,r){const n=w(),s=e.anchored;n.x=e.startx,n.y=e.starty,n.class="activation"+r%3,n.width=e.stopx-e.startx,n.height=a-e.starty,X(s,n)},drawLoop:function(t,e,a,i){const{boxMargin:r,boxTextMargin:n,labelBoxHeight:s,labelBoxWidth:o,messageFontFamily:c,messageFontSize:l,messageFontWeight:h}=i,d=t.append("g"),p=function(t,e,a,i){return d.append("line").attr("x1",t).attr("y1",e).attr("x2",a).attr("y2",i).attr("class","loopLine")};p(e.startx,e.starty,e.stopx,e.starty),p(e.stopx,e.starty,e.stopx,e.stopy),p(e.startx,e.stopy,e.stopx,e.stopy),p(e.startx,e.starty,e.startx,e.stopy),void 0!==e.sections&&e.sections.forEach((function(t){p(e.startx,t.y,e.stopx,t.y).style("stroke-dasharray","3, 3")}));let g=T();g.text=a,g.x=e.startx,g.y=e.starty,g.fontFamily=c,g.fontSize=l,g.fontWeight=h,g.anchor="middle",g.valign="middle",g.tspan=!1,g.width=o||50,g.height=s||20,g.textMargin=n,g.class="labelText",tt(d,g),g=rt(),g.text=e.title,g.x=e.startx+o/2+(e.stopx-e.startx)/2,g.y=e.starty+r+n,g.anchor="middle",g.valign="middle",g.textMargin=n,g.class="loopText",g.fontFamily=c,g.fontSize=l,g.fontWeight=h,g.wrap=!0;let u=Z(d,g);return void 0!==e.sectionTitles&&e.sectionTitles.forEach((function(t,a){if(t.message){g.text=t.message,g.x=e.startx+(e.stopx-e.startx)/2,g.y=e.sections[a].y+r+n,g.class="loopText",g.anchor="middle",g.valign="middle",g.tspan=!1,g.fontFamily=c,g.fontSize=l,g.fontWeight=h,g.wrap=e.wrap,u=Z(d,g);let i=Math.round(u.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));e.sections[a].height+=i-(r+n)}})),e.height=Math.round(e.stopy-e.starty),d},drawBackgroundRect:it,insertArrowHead:function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).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")},insertArrowFilledHead:function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).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")},insertSequenceNumber:function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},insertArrowCrossHead:function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},insertDatabaseIcon:function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},insertComputerIcon:function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},insertClockIcon:function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},getTextObj:rt,getNoteRect:function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},popupMenu:function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = 'block'; }"},popdownMenu:function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = 'none'; }"},fixLifeLineHeights:at,sanitizeUrl:y};let ct={};const lt={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:function(){return Math.max.apply(null,0===this.actors.length?[0]:this.actors.map((t=>t.height||0)))+(0===this.loops.length?0:this.loops.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.messages.length?0:this.messages.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.notes.length?0:this.notes.map((t=>t.height||0)).reduce(((t,e)=>t+e)))},clear:function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},addBox:function(t){this.boxes.push(t)},addActor:function(t){this.actors.push(t)},addLoop:function(t){this.loops.push(t)},addMessage:function(t){this.messages.push(t)},addNote:function(t){this.notes.push(t)},lastActor:function(){return this.actors[this.actors.length-1]},lastLoop:function(){return this.loops[this.loops.length-1]},lastMessage:function(){return this.messages[this.messages.length-1]},lastNote:function(){return this.notes[this.notes.length-1]},actors:[],boxes:[],loops:[],messages:[],notes:[]},init:function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,xt(i())},updateVal:function(t,e,a,i){void 0===t[e]?t[e]=a:t[e]=i(a,t[e])},updateBounds:function(t,e,a,i){const r=this;let n=0;function s(s){return function(o){n++;const c=r.sequenceItems.length-n+1;r.updateVal(o,"starty",e-c*ct.boxMargin,Math.min),r.updateVal(o,"stopy",i+c*ct.boxMargin,Math.max),r.updateVal(lt.data,"startx",t-c*ct.boxMargin,Math.min),r.updateVal(lt.data,"stopx",a+c*ct.boxMargin,Math.max),"activation"!==s&&(r.updateVal(o,"startx",t-c*ct.boxMargin,Math.min),r.updateVal(o,"stopx",a+c*ct.boxMargin,Math.max),r.updateVal(lt.data,"starty",e-c*ct.boxMargin,Math.min),r.updateVal(lt.data,"stopy",i+c*ct.boxMargin,Math.max))}}this.sequenceItems.forEach(s()),this.activations.forEach(s("activation"))},insert:function(t,e,a,i){const r=d.getMin(t,a),n=d.getMax(t,a),s=d.getMin(e,i),o=d.getMax(e,i);this.updateVal(lt.data,"startx",r,Math.min),this.updateVal(lt.data,"starty",s,Math.min),this.updateVal(lt.data,"stopx",n,Math.max),this.updateVal(lt.data,"stopy",o,Math.max),this.updateBounds(r,s,n,o)},newActivation:function(t,e,a){const i=a[t.from.actor],r=yt(t.from.actor).length||0,n=i.x+i.width/2+(r-1)*ct.activationWidth/2;this.activations.push({startx:n,starty:this.verticalPos+2,stopx:n+ct.activationWidth,stopy:void 0,actor:t.from.actor,anchored:ot.anchorElement(e)})},endActivation:function(t){const e=this.activations.map((function(t){return t.actor})).lastIndexOf(t.from.actor);return this.activations.splice(e,1)[0]},createLoop:function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},newLoop:function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},endLoop:function(){return this.sequenceItems.pop()},isLoopOverlap:function(){return!!this.sequenceItems.length&&this.sequenceItems[this.sequenceItems.length-1].overlap},addSectionToLoop:function(t){const e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:lt.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},saveVerticalPos:function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},resetVerticalPos:function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=d.getMax(this.data.stopy,this.verticalPos)},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return{bounds:this.data,models:this.models}}},ht=t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),dt=t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),pt=t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight});const gt=function(t,e,a,i,r,n,s){if(!0===r.hideUnusedParticipants){const t=new Set;n.forEach((e=>{t.add(e.from),t.add(e.to)})),a=a.filter((e=>t.has(e)))}let o,c=0,l=0,h=0;for(const p of a){const a=e[p],r=a.box;o&&o!=r&&(s||lt.models.addBox(o),l+=ct.boxMargin+o.margin),r&&r!=o&&(s||(r.x=c+l,r.y=i),l+=r.margin),a.width=a.width||ct.width,a.height=d.getMax(a.height||ct.height,ct.height),a.margin=a.margin||ct.actorMargin,a.x=c+l,a.y=lt.getVerticalPos();const n=ot.drawActor(t,a,ct,s);h=d.getMax(h,n),lt.insert(a.x,i,a.x+a.width,a.height),c+=a.width+l,a.box&&(a.box.width=c+r.margin-a.box.x),l=a.margin,o=a.box,lt.models.addActor(a)}o&&!s&<.models.addBox(o),lt.bumpVerticalPos(h)},ut=function(t,e,a,i){let r=0,n=0;for(const s of a){const a=e[s],o=ft(a),c=ot.drawPopup(t,a,o,ct,ct.forceMenus,i);c.height>r&&(r=c.height),c.width+a.x>n&&(n=c.width+a.x)}return{maxHeight:r,maxWidth:n}},xt=function(t){p(ct,t),t.fontFamily&&(ct.actorFontFamily=ct.noteFontFamily=ct.messageFontFamily=t.fontFamily),t.fontSize&&(ct.actorFontSize=ct.noteFontSize=ct.messageFontSize=t.fontSize),t.fontWeight&&(ct.actorFontWeight=ct.noteFontWeight=ct.messageFontWeight=t.fontWeight)},yt=function(t){return lt.activations.filter((function(e){return e.actor===t}))},mt=function(t,e){const a=e[t],i=yt(t);return[i.reduce((function(t,e){return d.getMin(t,e.startx)}),a.x+a.width/2),i.reduce((function(t,e){return d.getMax(t,e.stopx)}),a.x+a.width/2)]};function bt(t,e,a,i,r){lt.bumpVerticalPos(a);let n=i;if(e.id&&e.message&&t[e.id]){const a=t[e.id].width,r=ht(ct);e.message=x.wrapLabel(`[${e.message}]`,a-2*ct.wrapPadding,r),e.width=a,e.wrap=!0;const s=x.calculateTextDimensions(e.message,r),o=d.getMax(s.height,ct.labelBoxHeight);n=i+o,l.debug(`${o} - ${e.message}`)}r(e),lt.bumpVerticalPos(n)}const ft=function(t){let e=0;const a=pt(ct);for(const i in t.links){const t=x.calculateTextDimensions(i,a).width+2*ct.wrapPadding+2*ct.boxMargin;et.actor)).lastIndexOf(t.from.actor);delete lt.activations.splice(e,1)[0]}}void 0!==t.placement?(o=function(t,e,a){const i=e[t.from].x,r=e[t.to].x,n=t.wrap&&t.message;let s=x.calculateTextDimensions(n?x.wrapLabel(t.message,ct.width,dt(ct)):t.message,dt(ct));const o={width:n?ct.width:d.getMax(ct.width,s.width+2*ct.noteMargin),height:0,startx:e[t.from].x,stopx:0,starty:0,stopy:0,message:t.message};return t.placement===a.db.PLACEMENT.RIGHTOF?(o.width=n?d.getMax(ct.width,s.width):d.getMax(e[t.from].width/2+e[t.to].width/2,s.width+2*ct.noteMargin),o.startx=i+(e[t.from].width+ct.actorMargin)/2):t.placement===a.db.PLACEMENT.LEFTOF?(o.width=n?d.getMax(ct.width,s.width+2*ct.noteMargin):d.getMax(e[t.from].width/2+e[t.to].width/2,s.width+2*ct.noteMargin),o.startx=i-o.width+(e[t.from].width-ct.actorMargin)/2):t.to===t.from?(s=x.calculateTextDimensions(n?x.wrapLabel(t.message,d.getMax(ct.width,e[t.from].width),dt(ct)):t.message,dt(ct)),o.width=n?d.getMax(ct.width,e[t.from].width):d.getMax(e[t.from].width,ct.width,s.width+2*ct.noteMargin),o.startx=i+(e[t.from].width-o.width)/2):(o.width=Math.abs(i+e[t.from].width/2-(r+e[t.to].width/2))+ct.actorMargin,o.startx=i{s=t,s.from=d.getMin(s.from,o.startx),s.to=d.getMax(s.to,o.startx+o.width),s.width=d.getMax(s.width,Math.abs(s.from-s.to))-ct.labelBoxWidth}))):(c=function(t,e,a){let i=!1;if([a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN,a.db.LINETYPE.SOLID,a.db.LINETYPE.DOTTED,a.db.LINETYPE.SOLID_CROSS,a.db.LINETYPE.DOTTED_CROSS,a.db.LINETYPE.SOLID_POINT,a.db.LINETYPE.DOTTED_POINT].includes(t.type)&&(i=!0),!i)return{};const r=mt(t.from,e),n=mt(t.to,e),s=r[0]<=n[0]?1:0,o=r[0]0&&n.forEach((a=>{if(s=a,c.startx===c.stopx){const a=e[t.from],i=e[t.to];s.from=d.getMin(a.x-c.width/2,a.x-a.width/2,s.from),s.to=d.getMax(i.x+c.width/2,i.x+a.width/2,s.to),s.width=d.getMax(s.width,Math.abs(s.to-s.from))-ct.labelBoxWidth}else s.from=d.getMin(c.startx,s.from),s.to=d.getMax(c.stopx,s.to),s.width=d.getMax(s.width,c.width)-ct.labelBoxWidth})))})),lt.activations=[],l.debug("Loop type widths:",r),r},Et={parser:k,db:j,renderer:{bounds:lt,drawActors:gt,drawActorsPopup:ut,setConf:xt,draw:function(t,e,a,r){const{securityLevel:n,sequence:s}=i();let o;ct=s,r.db.clear(),r.parser.parse(t),"sandbox"===n&&(o=g("#i"+e));const c=g("sandbox"===n?o.nodes()[0].contentDocument.body:"body"),h="sandbox"===n?o.nodes()[0].contentDocument:document;lt.init(),l.debug(r.db);const p="sandbox"===n?c.select(`[id="${e}"]`):g(`[id="${e}"]`),y=r.db.getActors(),m=r.db.getBoxes(),b=r.db.getActorKeys(),f=r.db.getMessages(),E=r.db.getDiagramTitle(),v=r.db.hasAtLeastOneBox(),_=r.db.hasAtLeastOneBoxWithTitle(),L=function(t,e,a){const i={};return e.forEach((function(e){if(t[e.to]&&t[e.from]){const r=t[e.to];if(e.placement===a.db.PLACEMENT.LEFTOF&&!r.prevActor)return;if(e.placement===a.db.PLACEMENT.RIGHTOF&&!r.nextActor)return;const n=void 0!==e.placement,s=!n,o=n?dt(ct):ht(ct),c=e.wrap?x.wrapLabel(e.message,ct.width-2*ct.wrapPadding,o):e.message,l=x.calculateTextDimensions(c,o).width+2*ct.wrapPadding;s&&e.from===r.nextActor?i[e.to]=d.getMax(i[e.to]||0,l):s&&e.from===r.prevActor?i[e.from]=d.getMax(i[e.from]||0,l):s&&e.from===e.to?(i[e.from]=d.getMax(i[e.from]||0,l/2),i[e.to]=d.getMax(i[e.to]||0,l/2)):e.placement===a.db.PLACEMENT.RIGHTOF?i[e.from]=d.getMax(i[e.from]||0,l):e.placement===a.db.PLACEMENT.LEFTOF?i[r.prevActor]=d.getMax(i[r.prevActor]||0,l):e.placement===a.db.PLACEMENT.OVER&&(r.prevActor&&(i[r.prevActor]=d.getMax(i[r.prevActor]||0,l/2)),r.nextActor&&(i[e.from]=d.getMax(i[e.from]||0,l/2)))}})),l.debug("maxMessageWidthPerActor:",i),i}(y,f,r);ct.height=function(t,e,a){let i=0;Object.keys(t).forEach((e=>{const a=t[e];a.wrap&&(a.description=x.wrapLabel(a.description,ct.width-2*ct.wrapPadding,pt(ct)));const r=x.calculateTextDimensions(a.description,pt(ct));a.width=a.wrap?ct.width:d.getMax(ct.width,r.width+2*ct.wrapPadding),a.height=a.wrap?d.getMax(r.height,ct.height):ct.height,i=d.getMax(i,a.height)}));for(const n in e){const a=t[n];if(!a)continue;const i=t[a.nextActor];if(!i){const t=e[n]+ct.actorMargin-a.width/2;a.margin=d.getMax(t,ct.actorMargin);continue}const r=e[n]+ct.actorMargin-a.width/2-i.width/2;a.margin=d.getMax(r,ct.actorMargin)}let r=0;return a.forEach((e=>{const a=ht(ct);let i=e.actorKeys.reduce(((e,a)=>e+(t[a].width+(t[a].margin||0))),0);i-=2*ct.boxTextMargin,e.wrap&&(e.name=x.wrapLabel(e.name,i-2*ct.wrapPadding,a));const n=x.calculateTextDimensions(e.name,a);r=d.getMax(n.height,r);const s=d.getMax(i,n.width+2*ct.wrapPadding);if(e.margin=ct.boxTextMargin,it.textMaxHeight=r)),d.getMax(i,ct.height)}(y,L,m),ot.insertComputerIcon(p),ot.insertDatabaseIcon(p),ot.insertClockIcon(p),v&&(lt.bumpVerticalPos(ct.boxMargin),_&<.bumpVerticalPos(m[0].textMaxHeight)),gt(p,y,b,0,ct,f,!1);const k=Tt(f,y,L,r);ot.insertArrowHead(p),ot.insertArrowCrossHead(p),ot.insertArrowFilledHead(p),ot.insertSequenceNumber(p);let I=1,M=1;const N=[];f.forEach((function(t){let e,a,i;switch(t.type){case r.db.LINETYPE.NOTE:lt.resetVerticalPos(),a=t.noteModel,function(t,e){lt.bumpVerticalPos(ct.boxMargin),e.height=ct.boxMargin,e.starty=lt.getVerticalPos();const a=w();a.x=e.startx,a.y=e.starty,a.width=e.width||ct.width,a.class="note";const i=t.append("g"),r=ot.drawRect(i,a),n=T();n.x=e.startx,n.y=e.starty,n.width=a.width,n.dy="1em",n.text=e.message,n.class="noteText",n.fontFamily=ct.noteFontFamily,n.fontSize=ct.noteFontSize,n.fontWeight=ct.noteFontWeight,n.anchor=ct.noteAlign,n.textMargin=ct.noteMargin,n.valign="center";const s=Z(i,n),o=Math.round(s.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));r.attr("height",o+2*ct.noteMargin),e.height+=o+2*ct.noteMargin,lt.bumpVerticalPos(o+2*ct.noteMargin),e.stopy=e.starty+o+2*ct.noteMargin,e.stopx=e.startx+a.width,lt.insert(e.startx,e.starty,e.stopx,e.stopy),lt.models.addNote(e)}(p,a);break;case r.db.LINETYPE.ACTIVE_START:lt.newActivation(t,p,y);break;case r.db.LINETYPE.ACTIVE_END:!function(t,e){const a=lt.endActivation(t);a.starty+18>e&&(a.starty=e-6,e+=12),ot.drawActivation(p,a,e,ct,yt(t.from.actor).length),lt.insert(a.startx,e-10,a.stopx,e)}(t,lt.getVerticalPos());break;case r.db.LINETYPE.LOOP_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t)));break;case r.db.LINETYPE.LOOP_END:e=lt.endLoop(),ot.drawLoop(p,e,"loop",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;case r.db.LINETYPE.RECT_START:bt(k,t,ct.boxMargin,ct.boxMargin,(t=>lt.newLoop(void 0,t.message)));break;case r.db.LINETYPE.RECT_END:e=lt.endLoop(),ot.drawBackgroundRect(p,e),lt.models.addLoop(e),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos());break;case r.db.LINETYPE.OPT_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t)));break;case r.db.LINETYPE.OPT_END:e=lt.endLoop(),ot.drawLoop(p,e,"opt",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;case r.db.LINETYPE.ALT_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t)));break;case r.db.LINETYPE.ALT_ELSE:bt(k,t,ct.boxMargin+ct.boxTextMargin,ct.boxMargin,(t=>lt.addSectionToLoop(t)));break;case r.db.LINETYPE.ALT_END:e=lt.endLoop(),ot.drawLoop(p,e,"alt",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;case r.db.LINETYPE.PAR_START:case r.db.LINETYPE.PAR_OVER_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t))),lt.saveVerticalPos();break;case r.db.LINETYPE.PAR_AND:bt(k,t,ct.boxMargin+ct.boxTextMargin,ct.boxMargin,(t=>lt.addSectionToLoop(t)));break;case r.db.LINETYPE.PAR_END:e=lt.endLoop(),ot.drawLoop(p,e,"par",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;case r.db.LINETYPE.AUTONUMBER:I=t.message.start||I,M=t.message.step||M,t.message.visible?r.db.enableSequenceNumbers():r.db.disableSequenceNumbers();break;case r.db.LINETYPE.CRITICAL_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t)));break;case r.db.LINETYPE.CRITICAL_OPTION:bt(k,t,ct.boxMargin+ct.boxTextMargin,ct.boxMargin,(t=>lt.addSectionToLoop(t)));break;case r.db.LINETYPE.CRITICAL_END:e=lt.endLoop(),ot.drawLoop(p,e,"critical",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;case r.db.LINETYPE.BREAK_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t)));break;case r.db.LINETYPE.BREAK_END:e=lt.endLoop(),ot.drawLoop(p,e,"break",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;default:try{lt.resetVerticalPos(),i=t.msgModel,i.starty=lt.getVerticalPos(),i.sequenceIndex=I,i.sequenceVisible=r.db.showSequenceNumbers();const e=function(t,e){lt.bumpVerticalPos(10);const{startx:a,stopx:i,message:r}=e,n=d.splitBreaks(r).length,s=x.calculateTextDimensions(r,ht(ct)),o=s.height/n;let c;e.height+=o,lt.bumpVerticalPos(o);let l=s.height-10;const h=s.width;if(a===i){c=lt.getVerticalPos()+l,ct.rightAngles||(l+=ct.boxMargin,c=lt.getVerticalPos()+l),l+=30;const t=d.getMax(h/2,ct.width/2);lt.insert(a-t,lt.getVerticalPos()-10+l,i+t,lt.getVerticalPos()+30+l)}else l+=ct.boxMargin,c=lt.getVerticalPos()+l,lt.insert(a,c-10,i,c);return lt.bumpVerticalPos(l),e.height+=l,e.stopy=e.starty+e.height,lt.insert(e.fromBounds,e.starty,e.toBounds,e.stopy),c}(0,i);N.push({messageModel:i,lineStartY:e}),lt.models.addMessage(i)}catch(n){l.error("error while drawing message",n)}}[r.db.LINETYPE.SOLID_OPEN,r.db.LINETYPE.DOTTED_OPEN,r.db.LINETYPE.SOLID,r.db.LINETYPE.DOTTED,r.db.LINETYPE.SOLID_CROSS,r.db.LINETYPE.DOTTED_CROSS,r.db.LINETYPE.SOLID_POINT,r.db.LINETYPE.DOTTED_POINT].includes(t.type)&&(I+=M)})),N.forEach((t=>function(t,e,a,i){const{startx:r,stopx:n,starty:s,message:o,type:c,sequenceIndex:l,sequenceVisible:h}=e,p=x.calculateTextDimensions(o,ht(ct)),g=T();g.x=r,g.y=s+10,g.width=n-r,g.class="messageText",g.dy="1em",g.text=o,g.fontFamily=ct.messageFontFamily,g.fontSize=ct.messageFontSize,g.fontWeight=ct.messageFontWeight,g.anchor=ct.messageAlign,g.valign="center",g.textMargin=ct.wrapPadding,g.tspan=!1,Z(t,g);const u=p.width;let y;r===n?y=ct.rightAngles?t.append("path").attr("d",`M ${r},${a} H ${r+d.getMax(ct.width/2,u/2)} V ${a+25} H ${r}`):t.append("path").attr("d","M "+r+","+a+" C "+(r+60)+","+(a-10)+" "+(r+60)+","+(a+30)+" "+r+","+(a+20)):(y=t.append("line"),y.attr("x1",r),y.attr("y1",a),y.attr("x2",n),y.attr("y2",a)),c===i.db.LINETYPE.DOTTED||c===i.db.LINETYPE.DOTTED_CROSS||c===i.db.LINETYPE.DOTTED_POINT||c===i.db.LINETYPE.DOTTED_OPEN?(y.style("stroke-dasharray","3, 3"),y.attr("class","messageLine1")):y.attr("class","messageLine0");let m="";ct.arrowMarkerAbsolute&&(m=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,m=m.replace(/\(/g,"\\("),m=m.replace(/\)/g,"\\)")),y.attr("stroke-width",2),y.attr("stroke","none"),y.style("fill","none"),c!==i.db.LINETYPE.SOLID&&c!==i.db.LINETYPE.DOTTED||y.attr("marker-end","url("+m+"#arrowhead)"),c!==i.db.LINETYPE.SOLID_POINT&&c!==i.db.LINETYPE.DOTTED_POINT||y.attr("marker-end","url("+m+"#filled-head)"),c!==i.db.LINETYPE.SOLID_CROSS&&c!==i.db.LINETYPE.DOTTED_CROSS||y.attr("marker-end","url("+m+"#crosshead)"),(h||ct.showSequenceNumbers)&&(y.attr("marker-start","url("+m+"#sequencenumber)"),t.append("text").attr("x",r).attr("y",a+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(l))}(p,t.messageModel,t.lineStartY,r))),ct.mirrorActors&&(lt.bumpVerticalPos(2*ct.boxMargin),gt(p,y,b,lt.getVerticalPos(),ct,f,!0),lt.bumpVerticalPos(ct.boxMargin),at(p,lt.getVerticalPos())),lt.models.boxes.forEach((function(t){t.height=lt.getVerticalPos()-t.y,lt.insert(t.x,t.y,t.x+t.width,t.height),t.startx=t.x,t.starty=t.y,t.stopx=t.startx+t.width,t.stopy=t.starty+t.height,t.stroke="rgb(0,0,0, 0.5)",ot.drawBox(p,t,ct)})),v&<.bumpVerticalPos(ct.boxMargin);const A=ut(p,y,b,h),{bounds:S}=lt.getBounds();l.debug("For line height fix Querying: #"+e+" .actor-line");P("#"+e+" .actor-line").attr("y2",S.stopy);let O=S.stopy-S.starty;Oh&&L.push("'"+this.terminals_[v]+"'");I=g.showPosition?"Parse error on line "+(c+1)+":\n"+g.showPosition()+"\nExpecting "+L.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(c+1)+": Unexpected "+(f==d?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(I,{text:g.match,token:this.terminals_[f]||f,line:g.yylineno,loc:y,expected:L})}if(E[0]instanceof Array&&E.length>1)throw new Error("Parse Error: multiple actions possible at state: "+T+", token: "+f);switch(E[0]){case 1:a.push(f),r.push(g.yytext),n.push(g.yylloc),a.push(E[1]),f=null,l=g.yyleng,o=g.yytext,c=g.yylineno,y=g.yylloc;break;case 2:if(_=this.productions_[E[1]][1],k.$=r[r.length-_],k._$={first_line:n[n.length-(_||1)].first_line,last_line:n[n.length-1].last_line,first_column:n[n.length-(_||1)].first_column,last_column:n[n.length-1].last_column},m&&(k._$.range=[n[n.length-(_||1)].range[0],n[n.length-1].range[1]]),void 0!==(w=this.performAction.apply(k,[o,l,c,u.yy,E[1],r,n].concat(p))))return w;_&&(a=a.slice(0,-1*_*2),r=r.slice(0,-1*_),n=n.slice(0,-1*_)),a.push(this.productions_[E[1]][0]),r.push(k.$),n.push(k._$),P=s[a[a.length-2]][a[a.length-1]],a.push(P);break;case 3:return!0}}return!0}},z={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,a=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 i=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 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:a?(a.length===i.length?this.yylloc.first_column:0)+i[i.length-a.length].length-a[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(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var a,i,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],a=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a)return a;if(this._backtrack){for(var n in r)this[n]=r[n];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,a,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),n=0;ne[0].length)){if(e=a,i=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(a,r[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,a,i){switch(a){case 0:return this.begin("open_directive"),84;case 1:return this.begin("type_directive"),85;case 2:return this.popState(),this.begin("arg_directive"),17;case 3:return this.popState(),this.popState(),87;case 4:return 86;case 5:return 5;case 6:case 7:case 8:case 9:case 10:break;case 11:return 24;case 12:return this.begin("LINE"),19;case 13:return this.begin("ID"),55;case 14:return this.begin("ID"),57;case 15:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),74;case 16:return this.popState(),this.popState(),this.begin("LINE"),56;case 17:return this.popState(),this.popState(),5;case 18:return this.begin("LINE"),41;case 19:return this.begin("LINE"),42;case 20:return this.begin("LINE"),43;case 21:return this.begin("LINE"),44;case 22:return this.begin("LINE"),54;case 23:return this.begin("LINE"),46;case 24:return this.begin("LINE"),48;case 25:return this.begin("LINE"),53;case 26:return this.begin("LINE"),49;case 27:return this.begin("LINE"),52;case 28:return this.begin("LINE"),51;case 29:return this.popState(),20;case 30:return 21;case 31:return 69;case 32:return 70;case 33:return 63;case 34:return 64;case 35:return 65;case 36:return 66;case 37:return 61;case 38:return 58;case 39:return this.begin("ID"),26;case 40:return this.begin("ID"),28;case 41:return 34;case 42:return 35;case 43:return this.begin("acc_title"),36;case 44:return this.popState(),"acc_title_value";case 45:return this.begin("acc_descr"),38;case 46:return this.popState(),"acc_descr_value";case 47:this.begin("acc_descr_multiline");break;case 48:this.popState();break;case 49:return"acc_descr_multiline_value";case 50:return 7;case 51:return 23;case 52:return 25;case 53:return 68;case 54:return 5;case 55:return e.yytext=e.yytext.trim(),74;case 56:return 77;case 57:return 78;case 58:return 75;case 59:return 76;case 60:return 79;case 61:return 80;case 62:return 81;case 63:return 82;case 64:return 83;case 65:return 72;case 66:return 73;case 67:return 5;case 68:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:[^\->:\n,;]+?([\-]*[^\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[48,49],inclusive:!1},acc_descr:{rules:[46],inclusive:!1},acc_title:{rules:[44],inclusive:!1},open_directive:{rules:[1,8],inclusive:!1},type_directive:{rules:[2,3,8],inclusive:!1},arg_directive:{rules:[3,4,8],inclusive:!1},ID:{rules:[7,8,15],inclusive:!1},ALIAS:{rules:[7,8,16,17],inclusive:!1},LINE:{rules:[7,8,29],inclusive:!1},INITIAL:{rules:[0,5,6,8,9,10,11,12,13,14,18,19,20,21,22,23,24,25,26,27,28,30,31,32,33,34,35,36,37,38,39,40,41,42,43,45,47,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68],inclusive:!0}}};function H(){this.yy={}}return q.lexer=z,H.prototype=q,q.Parser=H,new H}();L.parser=L;const k=L;let I,M,N,A={},S=[],O=[],D=!1;const R=function(t,e,a,i){let r=N;const n=A[t];if(n){if(N&&n.box&&N!==n.box)throw new Error("A same participant should only be defined in one Box: "+n.name+" can't be in '"+n.box.name+"' and in '"+N.name+"' at the same time.");if(r=n.box?n.box:N,n.box=r,n&&e===n.name&&null==a)return}null!=a&&null!=a.text||(a={text:e,wrap:null,type:i}),null!=i&&null!=a.text||(a={text:e,wrap:null,type:i}),A[t]={box:r,name:e,description:a.text,wrap:void 0===a.wrap&&Y()||!!a.wrap,prevActor:I,links:{},properties:{},actorCnt:null,rectData:null,type:i||"participant"},I&&A[I]&&(A[I].nextActor=t),N&&N.actorKeys.push(t),I=t},C=function(t,e,a={text:void 0,wrap:void 0},i){if(i===B.ACTIVE_END){if((t=>{let e,a=0;for(e=0;e>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},e}}return O.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&Y()||!!a.wrap,type:i}),!0},$=function(t){return A[t]},Y=()=>void 0!==M?M:i().sequence.wrap,B={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32},V=function(t,e,a){a.text,void 0===a.wrap&&Y()||a.wrap;const i=[].concat(t,t);O.push({from:i[0],to:i[1],message:a.text,wrap:void 0===a.wrap&&Y()||!!a.wrap,type:B.NOTE,placement:e})},F=function(t,e){const a=$(t);try{let t=h(e.text,i());t=t.replace(/&/g,"&"),t=t.replace(/=/g,"=");W(a,JSON.parse(t))}catch(r){l.error("error while parsing actor link text",r)}};function W(t,e){if(null==t.links)t.links=e;else for(let a in e)t.links[a]=e[a]}const q=function(t,e){const a=$(t);try{let t=h(e.text,i());z(a,JSON.parse(t))}catch(r){l.error("error while parsing actor properties text",r)}};function z(t,e){if(null==t.properties)t.properties=e;else for(let a in e)t.properties[a]=e[a]}const H=function(t,e){const a=$(t),i=document.getElementById(e.text);try{const t=i.innerHTML,e=JSON.parse(t);e.properties&&z(a,e.properties),e.links&&W(a,e.links)}catch(r){l.error("error while parsing actor details text",r)}},U=function(t){if(Array.isArray(t))t.forEach((function(t){U(t)}));else switch(t.type){case"sequenceIndex":O.push({from:void 0,to:void 0,message:{start:t.sequenceIndex,step:t.sequenceIndexStep,visible:t.sequenceVisible},wrap:!1,type:t.signalType});break;case"addParticipant":R(t.actor,t.actor,t.description,"participant");break;case"addActor":R(t.actor,t.actor,t.description,"actor");break;case"activeStart":case"activeEnd":C(t.actor,void 0,void 0,t.signalType);break;case"addNote":V(t.actor,t.placement,t.text);break;case"addLinks":F(t.actor,t.text);break;case"addALink":!function(t,e){const a=$(t);try{const t={};let o=h(e.text,i());var r=o.indexOf("@");o=o.replace(/&/g,"&"),o=o.replace(/=/g,"=");var n=o.slice(0,r-1).trim(),s=o.slice(r+1).trim();t[n]=s,W(a,t)}catch(o){l.error("error while parsing actor link text",o)}}(t.actor,t.text);break;case"addProperties":q(t.actor,t.text);break;case"addDetails":H(t.actor,t.text);break;case"addMessage":C(t.from,t.to,t.msg,t.signalType);break;case"boxStart":e=t.boxData,S.push({name:e.text,wrap:void 0===e.wrap&&Y()||!!e.wrap,fill:e.color,actorKeys:[]}),N=S.slice(-1)[0];break;case"boxEnd":N=void 0;break;case"loopStart":C(void 0,void 0,t.loopText,t.signalType);break;case"loopEnd":C(void 0,void 0,void 0,t.signalType);break;case"rectStart":C(void 0,void 0,t.color,t.signalType);break;case"rectEnd":C(void 0,void 0,void 0,t.signalType);break;case"optStart":C(void 0,void 0,t.optText,t.signalType);break;case"optEnd":C(void 0,void 0,void 0,t.signalType);break;case"altStart":case"else":C(void 0,void 0,t.altText,t.signalType);break;case"altEnd":C(void 0,void 0,void 0,t.signalType);break;case"setAccTitle":r(t.text);break;case"parStart":case"and":C(void 0,void 0,t.parText,t.signalType);break;case"parEnd":C(void 0,void 0,void 0,t.signalType);break;case"criticalStart":C(void 0,void 0,t.criticalText,t.signalType);break;case"option":C(void 0,void 0,t.optionText,t.signalType);break;case"criticalEnd":C(void 0,void 0,void 0,t.signalType);break;case"breakStart":C(void 0,void 0,t.breakText,t.signalType);break;case"breakEnd":C(void 0,void 0,void 0,t.signalType)}var e},j={addActor:R,addMessage:function(t,e,a,i){O.push({from:t,to:e,message:a.text,wrap:void 0===a.wrap&&Y()||!!a.wrap,answer:i})},addSignal:C,addLinks:F,addDetails:H,addProperties:q,autoWrap:Y,setWrap:function(t){M=t},enableSequenceNumbers:function(){D=!0},disableSequenceNumbers:function(){D=!1},showSequenceNumbers:()=>D,getMessages:function(){return O},getActors:function(){return A},getActor:$,getActorKeys:function(){return Object.keys(A)},getActorProperty:function(t,e){if(void 0!==t&&void 0!==t.properties)return t.properties[e]},getAccTitle:t,getBoxes:function(){return S},getDiagramTitle:e,setDiagramTitle:a,parseDirective:function(t,e,a){o.parseDirective(this,t,e,a)},getConfig:()=>i().sequence,clear:function(){A={},S=[],O=[],D=!1,c()},parseMessage:function(t){const e=t.trim(),a={text:e.replace(/^:?(?:no)?wrap:/,"").trim(),wrap:null!==e.match(/^:?wrap:/)||null===e.match(/^:?nowrap:/)&&void 0};return l.debug("parseMessage:",a),a},parseBoxData:function(t){const e=t.match(/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/);let a=null!=e&&e[1]?e[1].trim():"transparent",r=null!=e&&e[2]?e[2].trim():void 0;if(window&&window.CSS)window.CSS.supports("color",a)||(a="transparent",r=t.trim());else{const e=(new Option).style;e.color=a,e.color!==a&&(a="transparent",r=t.trim())}return{color:a,text:void 0!==r?h(r.replace(/^:?(?:no)?wrap:/,""),i()):void 0,wrap:void 0!==r?null!==r.match(/^:?wrap:/)||null===r.match(/^:?nowrap:/)&&void 0:void 0}},LINETYPE:B,ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},addNote:V,setAccTitle:r,apply:U,setAccDescription:n,getAccDescription:s,hasAtLeastOneBox:function(){return S.length>0},hasAtLeastOneBoxWithTitle:function(){return S.some((t=>t.name))}},K=t=>`.actor {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n\n text.actor > tspan {\n fill: ${t.actorTextColor};\n stroke: none;\n }\n\n .actor-line {\n stroke: ${t.actorLineColor};\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ${t.signalColor};\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ${t.signalColor};\n }\n\n #arrowhead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .sequenceNumber {\n fill: ${t.sequenceNumberColor};\n }\n\n #sequencenumber {\n fill: ${t.signalColor};\n }\n\n #crosshead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .messageText {\n fill: ${t.signalTextColor};\n stroke: none;\n }\n\n .labelBox {\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBkgColor};\n }\n\n .labelText, .labelText > tspan {\n fill: ${t.labelTextColor};\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ${t.loopTextColor};\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBorderColor};\n }\n\n .note {\n //stroke: #decc93;\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n }\n\n .noteText, .noteText > tspan {\n fill: ${t.noteTextColor};\n stroke: none;\n }\n\n .activation0 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation1 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation2 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .actorPopupMenu {\n position: absolute;\n }\n\n .actorPopupMenuPanel {\n position: absolute;\n fill: ${t.actorBkg};\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));\n}\n .actor-man line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n .actor-man circle, line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n stroke-width: 2px;\n }\n`,X=function(t,e){return f(t,e)},G=(t,e)=>{b((()=>{const a=document.querySelectorAll(t);0!==a.length&&(a[0].addEventListener("mouseover",(function(){J("actor"+e+"_popup")})),a[0].addEventListener("mouseout",(function(){Q("actor"+e+"_popup")})))}))},J=function(t){var e=document.getElementById(t);null!=e&&(e.style.display="block")},Q=function(t){var e=document.getElementById(t);null!=e&&(e.style.display="none")},Z=function(t,e){let a=0,i=0;const r=e.text.split(d.lineBreakRegex),[n,s]=m(e.fontSize);let o=[],c=0,l=()=>e.y;if(void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0)switch(e.valign){case"top":case"start":l=()=>Math.round(e.y+e.textMargin);break;case"middle":case"center":l=()=>Math.round(e.y+(a+i+e.textMargin)/2);break;case"bottom":case"end":l=()=>Math.round(e.y+(a+i+2*e.textMargin)-e.textMargin)}if(void 0!==e.anchor&&void 0!==e.textMargin&&void 0!==e.width)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle"}for(let[h,d]of r.entries()){void 0!==e.textMargin&&0===e.textMargin&&void 0!==n&&(c=h*n);const r=t.append("text");if(r.attr("x",e.x),r.attr("y",l()),void 0!==e.anchor&&r.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),void 0!==e.fontFamily&&r.style("font-family",e.fontFamily),void 0!==s&&r.style("font-size",s),void 0!==e.fontWeight&&r.style("font-weight",e.fontWeight),void 0!==e.fill&&r.attr("fill",e.fill),void 0!==e.class&&r.attr("class",e.class),void 0!==e.dy?r.attr("dy",e.dy):0!==c&&r.attr("dy",c),e.tspan){const t=r.append("tspan");t.attr("x",e.x),void 0!==e.fill&&t.attr("fill",e.fill),t.text(d)}else r.text(d);void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0&&(i+=(r._groups||r)[0][0].getBBox().height,a=i),o.push(r)}return o},tt=function(t,e){const a=t.append("polygon");var i,r,n,s,o;return a.attr("points",(i=e.x,r=e.y,n=e.width,s=e.height,i+","+r+" "+(i+n)+","+r+" "+(i+n)+","+(r+s-(o=7))+" "+(i+n-1.2*o)+","+(r+s)+" "+i+","+(r+s))),a.attr("class","labelBox"),e.y=e.y+e.height/2,Z(t,e),a};let et=-1;const at=(t,e)=>{t.selectAll&&t.selectAll(".actor-line").attr("class","200").attr("y2",e-55)},it=function(t,e){E(t,e)},rt=function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}},nt=function(){function t(t,e,a,r,n,s,o){i(e.append("text").attr("x",a+n/2).attr("y",r+s/2+5).style("text-anchor","middle").text(t),o)}function e(t,e,a,r,n,s,o,c){const{actorFontSize:l,actorFontFamily:h,actorFontWeight:p}=c,[g,u]=m(l),x=t.split(d.lineBreakRegex);for(let d=0;da?o.width:a;const p=l.append("rect");if(p.attr("class","actorPopupMenuPanel"+h),p.attr("x",o.x),p.attr("y",o.height),p.attr("fill",o.fill),p.attr("stroke",o.stroke),p.attr("width",d),p.attr("height",o.height),p.attr("rx",o.rx),p.attr("ry",o.ry),null!=n){var g=20;for(let t in n){var u=l.append("a"),x=y(n[t]);u.attr("xlink:href",x),u.attr("target","_blank"),st(i)(t,u,o.x+10,o.height+g,d,20,{class:"actor"},i),g+=30}}return p.attr("height",g),{height:o.height+g,width:d}},anchorElement:function(t){return t.append("g")},drawActivation:function(t,e,a,i,r){const n=w(),s=e.anchored;n.x=e.startx,n.y=e.starty,n.class="activation"+r%3,n.width=e.stopx-e.startx,n.height=a-e.starty,X(s,n)},drawLoop:function(t,e,a,i){const{boxMargin:r,boxTextMargin:n,labelBoxHeight:s,labelBoxWidth:o,messageFontFamily:c,messageFontSize:l,messageFontWeight:h}=i,d=t.append("g"),p=function(t,e,a,i){return d.append("line").attr("x1",t).attr("y1",e).attr("x2",a).attr("y2",i).attr("class","loopLine")};p(e.startx,e.starty,e.stopx,e.starty),p(e.stopx,e.starty,e.stopx,e.stopy),p(e.startx,e.stopy,e.stopx,e.stopy),p(e.startx,e.starty,e.startx,e.stopy),void 0!==e.sections&&e.sections.forEach((function(t){p(e.startx,t.y,e.stopx,t.y).style("stroke-dasharray","3, 3")}));let g=T();g.text=a,g.x=e.startx,g.y=e.starty,g.fontFamily=c,g.fontSize=l,g.fontWeight=h,g.anchor="middle",g.valign="middle",g.tspan=!1,g.width=o||50,g.height=s||20,g.textMargin=n,g.class="labelText",tt(d,g),g=rt(),g.text=e.title,g.x=e.startx+o/2+(e.stopx-e.startx)/2,g.y=e.starty+r+n,g.anchor="middle",g.valign="middle",g.textMargin=n,g.class="loopText",g.fontFamily=c,g.fontSize=l,g.fontWeight=h,g.wrap=!0;let u=Z(d,g);return void 0!==e.sectionTitles&&e.sectionTitles.forEach((function(t,a){if(t.message){g.text=t.message,g.x=e.startx+(e.stopx-e.startx)/2,g.y=e.sections[a].y+r+n,g.class="loopText",g.anchor="middle",g.valign="middle",g.tspan=!1,g.fontFamily=c,g.fontSize=l,g.fontWeight=h,g.wrap=e.wrap,u=Z(d,g);let i=Math.round(u.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));e.sections[a].height+=i-(r+n)}})),e.height=Math.round(e.stopy-e.starty),d},drawBackgroundRect:it,insertArrowHead:function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).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")},insertArrowFilledHead:function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).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")},insertSequenceNumber:function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)},insertArrowCrossHead:function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")},insertDatabaseIcon:function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")},insertComputerIcon:function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")},insertClockIcon:function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")},getTextObj:rt,getNoteRect:function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}},popupMenu:function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = 'block'; }"},popdownMenu:function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = 'none'; }"},fixLifeLineHeights:at,sanitizeUrl:y};let ct={};const lt={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:function(){return Math.max.apply(null,0===this.actors.length?[0]:this.actors.map((t=>t.height||0)))+(0===this.loops.length?0:this.loops.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.messages.length?0:this.messages.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.notes.length?0:this.notes.map((t=>t.height||0)).reduce(((t,e)=>t+e)))},clear:function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]},addBox:function(t){this.boxes.push(t)},addActor:function(t){this.actors.push(t)},addLoop:function(t){this.loops.push(t)},addMessage:function(t){this.messages.push(t)},addNote:function(t){this.notes.push(t)},lastActor:function(){return this.actors[this.actors.length-1]},lastLoop:function(){return this.loops[this.loops.length-1]},lastMessage:function(){return this.messages[this.messages.length-1]},lastNote:function(){return this.notes[this.notes.length-1]},actors:[],boxes:[],loops:[],messages:[],notes:[]},init:function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,xt(i())},updateVal:function(t,e,a,i){void 0===t[e]?t[e]=a:t[e]=i(a,t[e])},updateBounds:function(t,e,a,i){const r=this;let n=0;function s(s){return function(o){n++;const c=r.sequenceItems.length-n+1;r.updateVal(o,"starty",e-c*ct.boxMargin,Math.min),r.updateVal(o,"stopy",i+c*ct.boxMargin,Math.max),r.updateVal(lt.data,"startx",t-c*ct.boxMargin,Math.min),r.updateVal(lt.data,"stopx",a+c*ct.boxMargin,Math.max),"activation"!==s&&(r.updateVal(o,"startx",t-c*ct.boxMargin,Math.min),r.updateVal(o,"stopx",a+c*ct.boxMargin,Math.max),r.updateVal(lt.data,"starty",e-c*ct.boxMargin,Math.min),r.updateVal(lt.data,"stopy",i+c*ct.boxMargin,Math.max))}}this.sequenceItems.forEach(s()),this.activations.forEach(s("activation"))},insert:function(t,e,a,i){const r=d.getMin(t,a),n=d.getMax(t,a),s=d.getMin(e,i),o=d.getMax(e,i);this.updateVal(lt.data,"startx",r,Math.min),this.updateVal(lt.data,"starty",s,Math.min),this.updateVal(lt.data,"stopx",n,Math.max),this.updateVal(lt.data,"stopy",o,Math.max),this.updateBounds(r,s,n,o)},newActivation:function(t,e,a){const i=a[t.from.actor],r=yt(t.from.actor).length||0,n=i.x+i.width/2+(r-1)*ct.activationWidth/2;this.activations.push({startx:n,starty:this.verticalPos+2,stopx:n+ct.activationWidth,stopy:void 0,actor:t.from.actor,anchored:ot.anchorElement(e)})},endActivation:function(t){const e=this.activations.map((function(t){return t.actor})).lastIndexOf(t.from.actor);return this.activations.splice(e,1)[0]},createLoop:function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}},newLoop:function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))},endLoop:function(){return this.sequenceItems.pop()},isLoopOverlap:function(){return!!this.sequenceItems.length&&this.sequenceItems[this.sequenceItems.length-1].overlap},addSectionToLoop:function(t){const e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:lt.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)},saveVerticalPos:function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)},resetVerticalPos:function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)},bumpVerticalPos:function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=d.getMax(this.data.stopy,this.verticalPos)},getVerticalPos:function(){return this.verticalPos},getBounds:function(){return{bounds:this.data,models:this.models}}},ht=t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight}),dt=t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight}),pt=t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight});const gt=function(t,e,a,i,r,n,s){if(!0===r.hideUnusedParticipants){const t=new Set;n.forEach((e=>{t.add(e.from),t.add(e.to)})),a=a.filter((e=>t.has(e)))}let o,c=0,l=0,h=0;for(const p of a){const a=e[p],r=a.box;o&&o!=r&&(s||lt.models.addBox(o),l+=ct.boxMargin+o.margin),r&&r!=o&&(s||(r.x=c+l,r.y=i),l+=r.margin),a.width=a.width||ct.width,a.height=d.getMax(a.height||ct.height,ct.height),a.margin=a.margin||ct.actorMargin,a.x=c+l,a.y=lt.getVerticalPos();const n=ot.drawActor(t,a,ct,s);h=d.getMax(h,n),lt.insert(a.x,i,a.x+a.width,a.height),c+=a.width+l,a.box&&(a.box.width=c+r.margin-a.box.x),l=a.margin,o=a.box,lt.models.addActor(a)}o&&!s&<.models.addBox(o),lt.bumpVerticalPos(h)},ut=function(t,e,a,i){let r=0,n=0;for(const s of a){const a=e[s],o=ft(a),c=ot.drawPopup(t,a,o,ct,ct.forceMenus,i);c.height>r&&(r=c.height),c.width+a.x>n&&(n=c.width+a.x)}return{maxHeight:r,maxWidth:n}},xt=function(t){p(ct,t),t.fontFamily&&(ct.actorFontFamily=ct.noteFontFamily=ct.messageFontFamily=t.fontFamily),t.fontSize&&(ct.actorFontSize=ct.noteFontSize=ct.messageFontSize=t.fontSize),t.fontWeight&&(ct.actorFontWeight=ct.noteFontWeight=ct.messageFontWeight=t.fontWeight)},yt=function(t){return lt.activations.filter((function(e){return e.actor===t}))},mt=function(t,e){const a=e[t],i=yt(t);return[i.reduce((function(t,e){return d.getMin(t,e.startx)}),a.x+a.width/2),i.reduce((function(t,e){return d.getMax(t,e.stopx)}),a.x+a.width/2)]};function bt(t,e,a,i,r){lt.bumpVerticalPos(a);let n=i;if(e.id&&e.message&&t[e.id]){const a=t[e.id].width,r=ht(ct);e.message=x.wrapLabel(`[${e.message}]`,a-2*ct.wrapPadding,r),e.width=a,e.wrap=!0;const s=x.calculateTextDimensions(e.message,r),o=d.getMax(s.height,ct.labelBoxHeight);n=i+o,l.debug(`${o} - ${e.message}`)}r(e),lt.bumpVerticalPos(n)}const ft=function(t){let e=0;const a=pt(ct);for(const i in t.links){const t=x.calculateTextDimensions(i,a).width+2*ct.wrapPadding+2*ct.boxMargin;et.actor)).lastIndexOf(t.from.actor);delete lt.activations.splice(e,1)[0]}}void 0!==t.placement?(o=function(t,e,a){const i=e[t.from].x,r=e[t.to].x,n=t.wrap&&t.message;let s=x.calculateTextDimensions(n?x.wrapLabel(t.message,ct.width,dt(ct)):t.message,dt(ct));const o={width:n?ct.width:d.getMax(ct.width,s.width+2*ct.noteMargin),height:0,startx:e[t.from].x,stopx:0,starty:0,stopy:0,message:t.message};return t.placement===a.db.PLACEMENT.RIGHTOF?(o.width=n?d.getMax(ct.width,s.width):d.getMax(e[t.from].width/2+e[t.to].width/2,s.width+2*ct.noteMargin),o.startx=i+(e[t.from].width+ct.actorMargin)/2):t.placement===a.db.PLACEMENT.LEFTOF?(o.width=n?d.getMax(ct.width,s.width+2*ct.noteMargin):d.getMax(e[t.from].width/2+e[t.to].width/2,s.width+2*ct.noteMargin),o.startx=i-o.width+(e[t.from].width-ct.actorMargin)/2):t.to===t.from?(s=x.calculateTextDimensions(n?x.wrapLabel(t.message,d.getMax(ct.width,e[t.from].width),dt(ct)):t.message,dt(ct)),o.width=n?d.getMax(ct.width,e[t.from].width):d.getMax(e[t.from].width,ct.width,s.width+2*ct.noteMargin),o.startx=i+(e[t.from].width-o.width)/2):(o.width=Math.abs(i+e[t.from].width/2-(r+e[t.to].width/2))+ct.actorMargin,o.startx=i{s=t,s.from=d.getMin(s.from,o.startx),s.to=d.getMax(s.to,o.startx+o.width),s.width=d.getMax(s.width,Math.abs(s.from-s.to))-ct.labelBoxWidth}))):(c=function(t,e,a){let i=!1;if([a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN,a.db.LINETYPE.SOLID,a.db.LINETYPE.DOTTED,a.db.LINETYPE.SOLID_CROSS,a.db.LINETYPE.DOTTED_CROSS,a.db.LINETYPE.SOLID_POINT,a.db.LINETYPE.DOTTED_POINT].includes(t.type)&&(i=!0),!i)return{};const r=mt(t.from,e),n=mt(t.to,e),s=r[0]<=n[0]?1:0,o=r[0]0&&n.forEach((a=>{if(s=a,c.startx===c.stopx){const a=e[t.from],i=e[t.to];s.from=d.getMin(a.x-c.width/2,a.x-a.width/2,s.from),s.to=d.getMax(i.x+c.width/2,i.x+a.width/2,s.to),s.width=d.getMax(s.width,Math.abs(s.to-s.from))-ct.labelBoxWidth}else s.from=d.getMin(c.startx,s.from),s.to=d.getMax(c.stopx,s.to),s.width=d.getMax(s.width,c.width)-ct.labelBoxWidth})))})),lt.activations=[],l.debug("Loop type widths:",r),r},Et={parser:k,db:j,renderer:{bounds:lt,drawActors:gt,drawActorsPopup:ut,setConf:xt,draw:function(t,e,a,r){const{securityLevel:n,sequence:s}=i();let o;ct=s,r.db.clear(),r.parser.parse(t),"sandbox"===n&&(o=g("#i"+e));const c=g("sandbox"===n?o.nodes()[0].contentDocument.body:"body"),h="sandbox"===n?o.nodes()[0].contentDocument:document;lt.init(),l.debug(r.db);const p="sandbox"===n?c.select(`[id="${e}"]`):g(`[id="${e}"]`),y=r.db.getActors(),m=r.db.getBoxes(),b=r.db.getActorKeys(),f=r.db.getMessages(),E=r.db.getDiagramTitle(),v=r.db.hasAtLeastOneBox(),_=r.db.hasAtLeastOneBoxWithTitle(),L=function(t,e,a){const i={};return e.forEach((function(e){if(t[e.to]&&t[e.from]){const r=t[e.to];if(e.placement===a.db.PLACEMENT.LEFTOF&&!r.prevActor)return;if(e.placement===a.db.PLACEMENT.RIGHTOF&&!r.nextActor)return;const n=void 0!==e.placement,s=!n,o=n?dt(ct):ht(ct),c=e.wrap?x.wrapLabel(e.message,ct.width-2*ct.wrapPadding,o):e.message,l=x.calculateTextDimensions(c,o).width+2*ct.wrapPadding;s&&e.from===r.nextActor?i[e.to]=d.getMax(i[e.to]||0,l):s&&e.from===r.prevActor?i[e.from]=d.getMax(i[e.from]||0,l):s&&e.from===e.to?(i[e.from]=d.getMax(i[e.from]||0,l/2),i[e.to]=d.getMax(i[e.to]||0,l/2)):e.placement===a.db.PLACEMENT.RIGHTOF?i[e.from]=d.getMax(i[e.from]||0,l):e.placement===a.db.PLACEMENT.LEFTOF?i[r.prevActor]=d.getMax(i[r.prevActor]||0,l):e.placement===a.db.PLACEMENT.OVER&&(r.prevActor&&(i[r.prevActor]=d.getMax(i[r.prevActor]||0,l/2)),r.nextActor&&(i[e.from]=d.getMax(i[e.from]||0,l/2)))}})),l.debug("maxMessageWidthPerActor:",i),i}(y,f,r);ct.height=function(t,e,a){let i=0;Object.keys(t).forEach((e=>{const a=t[e];a.wrap&&(a.description=x.wrapLabel(a.description,ct.width-2*ct.wrapPadding,pt(ct)));const r=x.calculateTextDimensions(a.description,pt(ct));a.width=a.wrap?ct.width:d.getMax(ct.width,r.width+2*ct.wrapPadding),a.height=a.wrap?d.getMax(r.height,ct.height):ct.height,i=d.getMax(i,a.height)}));for(const n in e){const a=t[n];if(!a)continue;const i=t[a.nextActor];if(!i){const t=e[n]+ct.actorMargin-a.width/2;a.margin=d.getMax(t,ct.actorMargin);continue}const r=e[n]+ct.actorMargin-a.width/2-i.width/2;a.margin=d.getMax(r,ct.actorMargin)}let r=0;return a.forEach((e=>{const a=ht(ct);let i=e.actorKeys.reduce(((e,a)=>e+(t[a].width+(t[a].margin||0))),0);i-=2*ct.boxTextMargin,e.wrap&&(e.name=x.wrapLabel(e.name,i-2*ct.wrapPadding,a));const n=x.calculateTextDimensions(e.name,a);r=d.getMax(n.height,r);const s=d.getMax(i,n.width+2*ct.wrapPadding);if(e.margin=ct.boxTextMargin,it.textMaxHeight=r)),d.getMax(i,ct.height)}(y,L,m),ot.insertComputerIcon(p),ot.insertDatabaseIcon(p),ot.insertClockIcon(p),v&&(lt.bumpVerticalPos(ct.boxMargin),_&<.bumpVerticalPos(m[0].textMaxHeight)),gt(p,y,b,0,ct,f,!1);const k=Tt(f,y,L,r);ot.insertArrowHead(p),ot.insertArrowCrossHead(p),ot.insertArrowFilledHead(p),ot.insertSequenceNumber(p);let I=1,M=1;const N=[];f.forEach((function(t){let e,a,i;switch(t.type){case r.db.LINETYPE.NOTE:lt.resetVerticalPos(),a=t.noteModel,function(t,e){lt.bumpVerticalPos(ct.boxMargin),e.height=ct.boxMargin,e.starty=lt.getVerticalPos();const a=w();a.x=e.startx,a.y=e.starty,a.width=e.width||ct.width,a.class="note";const i=t.append("g"),r=ot.drawRect(i,a),n=T();n.x=e.startx,n.y=e.starty,n.width=a.width,n.dy="1em",n.text=e.message,n.class="noteText",n.fontFamily=ct.noteFontFamily,n.fontSize=ct.noteFontSize,n.fontWeight=ct.noteFontWeight,n.anchor=ct.noteAlign,n.textMargin=ct.noteMargin,n.valign="center";const s=Z(i,n),o=Math.round(s.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));r.attr("height",o+2*ct.noteMargin),e.height+=o+2*ct.noteMargin,lt.bumpVerticalPos(o+2*ct.noteMargin),e.stopy=e.starty+o+2*ct.noteMargin,e.stopx=e.startx+a.width,lt.insert(e.startx,e.starty,e.stopx,e.stopy),lt.models.addNote(e)}(p,a);break;case r.db.LINETYPE.ACTIVE_START:lt.newActivation(t,p,y);break;case r.db.LINETYPE.ACTIVE_END:!function(t,e){const a=lt.endActivation(t);a.starty+18>e&&(a.starty=e-6,e+=12),ot.drawActivation(p,a,e,ct,yt(t.from.actor).length),lt.insert(a.startx,e-10,a.stopx,e)}(t,lt.getVerticalPos());break;case r.db.LINETYPE.LOOP_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t)));break;case r.db.LINETYPE.LOOP_END:e=lt.endLoop(),ot.drawLoop(p,e,"loop",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;case r.db.LINETYPE.RECT_START:bt(k,t,ct.boxMargin,ct.boxMargin,(t=>lt.newLoop(void 0,t.message)));break;case r.db.LINETYPE.RECT_END:e=lt.endLoop(),ot.drawBackgroundRect(p,e),lt.models.addLoop(e),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos());break;case r.db.LINETYPE.OPT_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t)));break;case r.db.LINETYPE.OPT_END:e=lt.endLoop(),ot.drawLoop(p,e,"opt",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;case r.db.LINETYPE.ALT_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t)));break;case r.db.LINETYPE.ALT_ELSE:bt(k,t,ct.boxMargin+ct.boxTextMargin,ct.boxMargin,(t=>lt.addSectionToLoop(t)));break;case r.db.LINETYPE.ALT_END:e=lt.endLoop(),ot.drawLoop(p,e,"alt",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;case r.db.LINETYPE.PAR_START:case r.db.LINETYPE.PAR_OVER_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t))),lt.saveVerticalPos();break;case r.db.LINETYPE.PAR_AND:bt(k,t,ct.boxMargin+ct.boxTextMargin,ct.boxMargin,(t=>lt.addSectionToLoop(t)));break;case r.db.LINETYPE.PAR_END:e=lt.endLoop(),ot.drawLoop(p,e,"par",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;case r.db.LINETYPE.AUTONUMBER:I=t.message.start||I,M=t.message.step||M,t.message.visible?r.db.enableSequenceNumbers():r.db.disableSequenceNumbers();break;case r.db.LINETYPE.CRITICAL_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t)));break;case r.db.LINETYPE.CRITICAL_OPTION:bt(k,t,ct.boxMargin+ct.boxTextMargin,ct.boxMargin,(t=>lt.addSectionToLoop(t)));break;case r.db.LINETYPE.CRITICAL_END:e=lt.endLoop(),ot.drawLoop(p,e,"critical",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;case r.db.LINETYPE.BREAK_START:bt(k,t,ct.boxMargin,ct.boxMargin+ct.boxTextMargin,(t=>lt.newLoop(t)));break;case r.db.LINETYPE.BREAK_END:e=lt.endLoop(),ot.drawLoop(p,e,"break",ct),lt.bumpVerticalPos(e.stopy-lt.getVerticalPos()),lt.models.addLoop(e);break;default:try{lt.resetVerticalPos(),i=t.msgModel,i.starty=lt.getVerticalPos(),i.sequenceIndex=I,i.sequenceVisible=r.db.showSequenceNumbers();const e=function(t,e){lt.bumpVerticalPos(10);const{startx:a,stopx:i,message:r}=e,n=d.splitBreaks(r).length,s=x.calculateTextDimensions(r,ht(ct)),o=s.height/n;let c;e.height+=o,lt.bumpVerticalPos(o);let l=s.height-10;const h=s.width;if(a===i){c=lt.getVerticalPos()+l,ct.rightAngles||(l+=ct.boxMargin,c=lt.getVerticalPos()+l),l+=30;const t=d.getMax(h/2,ct.width/2);lt.insert(a-t,lt.getVerticalPos()-10+l,i+t,lt.getVerticalPos()+30+l)}else l+=ct.boxMargin,c=lt.getVerticalPos()+l,lt.insert(a,c-10,i,c);return lt.bumpVerticalPos(l),e.height+=l,e.stopy=e.starty+e.height,lt.insert(e.fromBounds,e.starty,e.toBounds,e.stopy),c}(0,i);N.push({messageModel:i,lineStartY:e}),lt.models.addMessage(i)}catch(n){l.error("error while drawing message",n)}}[r.db.LINETYPE.SOLID_OPEN,r.db.LINETYPE.DOTTED_OPEN,r.db.LINETYPE.SOLID,r.db.LINETYPE.DOTTED,r.db.LINETYPE.SOLID_CROSS,r.db.LINETYPE.DOTTED_CROSS,r.db.LINETYPE.SOLID_POINT,r.db.LINETYPE.DOTTED_POINT].includes(t.type)&&(I+=M)})),N.forEach((t=>function(t,e,a,i){const{startx:r,stopx:n,starty:s,message:o,type:c,sequenceIndex:l,sequenceVisible:h}=e,p=x.calculateTextDimensions(o,ht(ct)),g=T();g.x=r,g.y=s+10,g.width=n-r,g.class="messageText",g.dy="1em",g.text=o,g.fontFamily=ct.messageFontFamily,g.fontSize=ct.messageFontSize,g.fontWeight=ct.messageFontWeight,g.anchor=ct.messageAlign,g.valign="center",g.textMargin=ct.wrapPadding,g.tspan=!1,Z(t,g);const u=p.width;let y;r===n?y=ct.rightAngles?t.append("path").attr("d",`M ${r},${a} H ${r+d.getMax(ct.width/2,u/2)} V ${a+25} H ${r}`):t.append("path").attr("d","M "+r+","+a+" C "+(r+60)+","+(a-10)+" "+(r+60)+","+(a+30)+" "+r+","+(a+20)):(y=t.append("line"),y.attr("x1",r),y.attr("y1",a),y.attr("x2",n),y.attr("y2",a)),c===i.db.LINETYPE.DOTTED||c===i.db.LINETYPE.DOTTED_CROSS||c===i.db.LINETYPE.DOTTED_POINT||c===i.db.LINETYPE.DOTTED_OPEN?(y.style("stroke-dasharray","3, 3"),y.attr("class","messageLine1")):y.attr("class","messageLine0");let m="";ct.arrowMarkerAbsolute&&(m=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,m=m.replace(/\(/g,"\\("),m=m.replace(/\)/g,"\\)")),y.attr("stroke-width",2),y.attr("stroke","none"),y.style("fill","none"),c!==i.db.LINETYPE.SOLID&&c!==i.db.LINETYPE.DOTTED||y.attr("marker-end","url("+m+"#arrowhead)"),c!==i.db.LINETYPE.SOLID_POINT&&c!==i.db.LINETYPE.DOTTED_POINT||y.attr("marker-end","url("+m+"#filled-head)"),c!==i.db.LINETYPE.SOLID_CROSS&&c!==i.db.LINETYPE.DOTTED_CROSS||y.attr("marker-end","url("+m+"#crosshead)"),(h||ct.showSequenceNumbers)&&(y.attr("marker-start","url("+m+"#sequencenumber)"),t.append("text").attr("x",r).attr("y",a+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(l))}(p,t.messageModel,t.lineStartY,r))),ct.mirrorActors&&(lt.bumpVerticalPos(2*ct.boxMargin),gt(p,y,b,lt.getVerticalPos(),ct,f,!0),lt.bumpVerticalPos(ct.boxMargin),at(p,lt.getVerticalPos())),lt.models.boxes.forEach((function(t){t.height=lt.getVerticalPos()-t.y,lt.insert(t.x,t.y,t.x+t.width,t.height),t.startx=t.x,t.starty=t.y,t.stopx=t.startx+t.width,t.stopy=t.starty+t.height,t.stroke="rgb(0,0,0, 0.5)",ot.drawBox(p,t,ct)})),v&<.bumpVerticalPos(ct.boxMargin);const A=ut(p,y,b,h),{bounds:S}=lt.getBounds();l.debug("For line height fix Querying: #"+e+" .actor-line");P("#"+e+" .actor-line").attr("y2",S.stopy);let O=S.stopy-S.starty;OThe current compatibility is as follows:

    • Supports TCP and UDP packet forwarding, with the option to selectively 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 or chacha20-ietf-poly1305
      • xchacha20-poly1305 or xchacha20-ietf-poly1305
      • none or plain

    The Shadowsocks 2022 new protocol format improves performance and includes complete replay protection, addressing the following security issues in the old protocol:

    ",3),m={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},g=p("Serious vulnerabilities in Shadowsocks AEAD encryption, which cannot guarantee the integrity of the communication content"),q=t("li",null,"Increasing false positive rate of the original TCP replay filter over time",-1),y=t("li",null,"Lack of UDP replay protection",-1),f=t("li",null,"TCP behaviors that can be used for active probing",-1),w=r('

    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

    {\n  "settings": {\n    "password": "password",\n    "method": "aes-256-gcm",\n    "level": 0,\n    "email": "love@xray.com",\n    "network": "tcp,udp"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    network: "tcp" | "udp" | "tcp,udp"

    The supported network protocol type. For example, when specified as "tcp", it will only handle TCP traffic. The default value is "tcp".

    ClientObject

    {\n  "password": "密码",\n  "method": "aes-256-gcm",\n  "level": 0,\n  "email": "love@xray.com"\n}\n
    1
    2
    3
    4
    5
    6

    method: string

    Required.

    password: string

    Required.

    • Shadowsocks 2022

    Use a pre-shared key similar to WireGuard as the password.

    Use openssl rand -base64 <length> to generate a compatible key with shadowsocks-rust, 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. There is no limitation 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

    ',19),v=p("The user level that the connection will use to determine the corresponding "),x=p("Local Policy"),j=p("."),T=p("The value of "),S=t("code",null,"level",-1),P=p(" corresponds to the value of "),C=t("code",null,"level",-1),D=p(" in the "),I=p("policy"),L=p(". If not specified, the default value is 0."),O=t("blockquote",null,[t("p",null,[t("code",null,"email"),p(": string")])],-1),U=t("p",null,"The user's email, used to differentiate traffic from different users (logs, statistics).",-1);i.render=function(p,r){const i=e("OutboundLink"),R=e("RouterLink");return n(),s(l,null,[c,t("p",null,[u,t("a",d,[h,o(i)]),b]),k,t("ul",null,[t("li",null,[t("a",m,[g,o(i)])]),q,y,f]),w,t("p",null,[v,o(R,{to:"/en/config/policy.html#levelpolicyobject"},{default:a((()=>[x])),_:1}),j]),t("p",null,[T,S,P,C,D,o(R,{to:"/en/config/policy.html#policyobject"},{default:a((()=>[I])),_:1}),L]),O,U],64)};export default i; +import{r as e,o as n,c as s,a as t,b as a,w as o,F as l,e as p,d as r}from"./app.48111a85.js";const i={},c=t("h1",{id:"shadowsocks",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#shadowsocks","aria-hidden":"true"},"#"),p(" Shadowsocks")],-1),u=p("The "),d={href:"https://en.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},h=p("Shadowsocks"),b=p(" protocol is compatible with most other implementations of Shadowsocks."),k=r("

    The current compatibility is as follows:

    • Supports TCP and UDP packet forwarding, with the option to selectively 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 or chacha20-ietf-poly1305
      • xchacha20-poly1305 or xchacha20-ietf-poly1305
      • none or plain

    The Shadowsocks 2022 new protocol format improves performance and includes complete replay protection, addressing the following security issues in the old protocol:

    ",3),m={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},g=p("Serious vulnerabilities in Shadowsocks AEAD encryption, which cannot guarantee the integrity of the communication content"),q=t("li",null,"Increasing false positive rate of the original TCP replay filter over time",-1),y=t("li",null,"Lack of UDP replay protection",-1),f=t("li",null,"TCP behaviors that can be used for active probing",-1),w=r('

    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

    {\n  "settings": {\n    "password": "password",\n    "method": "aes-256-gcm",\n    "level": 0,\n    "email": "love@xray.com",\n    "network": "tcp,udp"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    network: "tcp" | "udp" | "tcp,udp"

    The supported network protocol type. For example, when specified as "tcp", it will only handle TCP traffic. The default value is "tcp".

    ClientObject

    {\n  "password": "密码",\n  "method": "aes-256-gcm",\n  "level": 0,\n  "email": "love@xray.com"\n}\n
    1
    2
    3
    4
    5
    6

    method: string

    Required.

    password: string

    Required.

    • Shadowsocks 2022

    Use a pre-shared key similar to WireGuard as the password.

    Use openssl rand -base64 <length> to generate a compatible key with shadowsocks-rust, 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. There is no limitation 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

    ',19),v=p("The user level that the connection will use to determine the corresponding "),x=p("Local Policy"),j=p("."),T=p("The value of "),S=t("code",null,"level",-1),P=p(" corresponds to the value of "),C=t("code",null,"level",-1),D=p(" in the "),I=p("policy"),L=p(". If not specified, the default value is 0."),O=t("blockquote",null,[t("p",null,[t("code",null,"email"),p(": string")])],-1),U=t("p",null,"The user's email, used to differentiate traffic from different users (logs, statistics).",-1);i.render=function(p,r){const i=e("OutboundLink"),R=e("RouterLink");return n(),s(l,null,[c,t("p",null,[u,t("a",d,[h,a(i)]),b]),k,t("ul",null,[t("li",null,[t("a",m,[g,a(i)])]),q,y,f]),w,t("p",null,[v,a(R,{to:"/en/config/policy.html#levelpolicyobject"},{default:o((()=>[x])),_:1}),j]),t("p",null,[T,S,P,C,D,a(R,{to:"/en/config/policy.html#policyobject"},{default:o((()=>[I])),_:1}),L]),O,U],64)};export default i; diff --git a/assets/shadowsocks.html.def40830.js b/assets/shadowsocks.html.3fe3d4ee.js similarity index 99% rename from assets/shadowsocks.html.def40830.js rename to assets/shadowsocks.html.3fe3d4ee.js index b84c47d85..3636a614e 100644 --- a/assets/shadowsocks.html.def40830.js +++ b/assets/shadowsocks.html.3fe3d4ee.js @@ -1 +1 @@ -import{r as s,o as n,c as e,a,b as o,w as t,F as p,e as r,d as l}from"./app.755d843f.js";const c={},i=a("h1",{id:"shadowsocks",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#shadowsocks","aria-hidden":"true"},"#"),r(" Shadowsocks")],-1),u={href:"https://en.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},d=r("Shadowsocks"),b=r(" protocol is compatible with most other implementations."),h=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),k={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},m=r("Serious vulnerabilities in Shadowsocks AEAD encryption methods that compromise the integrity of communications"),q=a("li",null,"Increasing false-positive rate of TCP replay filters over time",-1),g=a("li",null,"Lack of replay protection for UDP",-1),y=a("li",null,"TCP behaviors that can be used for active probing",-1),f=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

    {\n  "servers": [\n    {\n      "email": "love@xray.com",\n      "address": "127.0.0.1",\n      "port": 1234,\n      "method": "encryption method",\n      "password": "password",\n      "uot": true,\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    servers: [ServerObject]

    An array representing a group of Shadowsocks server settings, where each item is a ServerObject.

    ServerObject

    {\n  "email": "love@xray.com",\n  "address": "127.0.0.1",\n  "port": 1234,\n  "method": "encryption method",\n  "password": "password",\n  "uot": true,\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    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

    ',27),v=r("User level. Connections will use the corresponding "),w=r("local policy"),j=r(" associated with this user level."),S=r("The "),x=a("code",null,"level",-1),P=r(" value corresponds to the "),T=a("code",null,"level",-1),O=r(" value in the "),I=r("policy"),U=r(". If not specified, the default value is 0.");c.render=function(r,l){const c=s("OutboundLink"),C=s("RouterLink");return n(),e(p,null,[i,a("p",null,[a("a",u,[d,o(c)]),b]),h,a("ul",null,[a("li",null,[a("a",k,[m,o(c)])]),q,g,y]),f,a("p",null,[v,o(C,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[w])),_:1}),j]),a("p",null,[S,x,P,T,O,o(C,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[I])),_:1}),U])],64)};export default c; +import{r as s,o as n,c as e,a,b as o,w as t,F as p,e as r,d as l}from"./app.48111a85.js";const c={},i=a("h1",{id:"shadowsocks",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#shadowsocks","aria-hidden":"true"},"#"),r(" Shadowsocks")],-1),u={href:"https://en.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},d=r("Shadowsocks"),b=r(" protocol is compatible with most other implementations."),h=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),k={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},m=r("Serious vulnerabilities in Shadowsocks AEAD encryption methods that compromise the integrity of communications"),q=a("li",null,"Increasing false-positive rate of TCP replay filters over time",-1),g=a("li",null,"Lack of replay protection for UDP",-1),y=a("li",null,"TCP behaviors that can be used for active probing",-1),f=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

    {\n  "servers": [\n    {\n      "email": "love@xray.com",\n      "address": "127.0.0.1",\n      "port": 1234,\n      "method": "encryption method",\n      "password": "password",\n      "uot": true,\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    servers: [ServerObject]

    An array representing a group of Shadowsocks server settings, where each item is a ServerObject.

    ServerObject

    {\n  "email": "love@xray.com",\n  "address": "127.0.0.1",\n  "port": 1234,\n  "method": "encryption method",\n  "password": "password",\n  "uot": true,\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    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

    ',27),v=r("User level. Connections will use the corresponding "),w=r("local policy"),j=r(" associated with this user level."),S=r("The "),x=a("code",null,"level",-1),P=r(" value corresponds to the "),T=a("code",null,"level",-1),O=r(" value in the "),I=r("policy"),U=r(". If not specified, the default value is 0.");c.render=function(r,l){const c=s("OutboundLink"),C=s("RouterLink");return n(),e(p,null,[i,a("p",null,[a("a",u,[d,o(c)]),b]),h,a("ul",null,[a("li",null,[a("a",k,[m,o(c)])]),q,g,y]),f,a("p",null,[v,o(C,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[w])),_:1}),j]),a("p",null,[S,x,P,T,O,o(C,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[I])),_:1}),U])],64)};export default c; diff --git a/assets/shadowsocks.html.cc95c58a.js b/assets/shadowsocks.html.4d363446.js similarity index 99% rename from assets/shadowsocks.html.cc95c58a.js rename to assets/shadowsocks.html.4d363446.js index d8e2cb1bb..60fbfe488 100644 --- a/assets/shadowsocks.html.cc95c58a.js +++ b/assets/shadowsocks.html.4d363446.js @@ -1 +1 @@ -import{r as s,o as n,c as a,a as o,b as t,w as e,F as l,e as p,d as c}from"./app.755d843f.js";const r={},u=o("h1",{id:"shadowsocks",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#shadowsocks","aria-hidden":"true"},"#"),p(" Shadowsocks")],-1),i={href:"https://zh.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},d=p("Shadowsocks"),b=p(" 协议,兼容大部分其它版本的实现。"),k=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),h={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},q=p("Shadowsocks AEAD 加密方式设计存在严重漏洞,无法保证通信内容的可靠性"),g=o("li",null,"原有 TCP 重放过滤器误报率随时间增加",-1),m=o("li",null,"没有 UDP 重放保护",-1),y=o("li",null,"可用于主动探测的 TCP 行为",-1),f=c('

    警告

    "none" 不加密方式下流量将明文传输。为确保安全性, 不要在公共网络上使用。

    InboundConfigurationObject

    {\n  "settings": {\n    "password": "密码",\n    "method": "aes-256-gcm",\n    "level": 0,\n    "email": "love@xray.com",\n    "network": "tcp,udp"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    network: "tcp" | "udp" | "tcp,udp"

    可接收的网络协议类型。比如当指定为 "tcp" 时,仅会接收 TCP 流量。默认值为 "tcp"

    ClientObject

    {\n  "password": "密码",\n  "method": "aes-256-gcm",\n  "level": 0,\n  "email": "love@xray.com"\n}\n
    1
    2
    3
    4
    5
    6

    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

    ',19),v=p("用户等级,连接会使用这个用户等级对应的 "),w=p("本地策略"),j=p("。"),x=o("code",null,"level",-1),P=p(" 的值, 对应 "),C=p("policy"),S=p(" 中 "),D=o("code",null,"level",-1),T=p(" 的值。 如不指定, 默认为 0。"),_=o("blockquote",null,[o("p",null,[o("code",null,"email"),p(": string")])],-1),O=o("p",null,"用户邮箱,用于区分不同用户的流量(日志、统计)。",-1);r.render=function(p,c){const r=s("OutboundLink"),U=s("RouterLink");return n(),a(l,null,[u,o("p",null,[o("a",i,[d,t(r)]),b]),k,o("ul",null,[o("li",null,[o("a",h,[q,t(r)])]),g,m,y]),f,o("p",null,[v,t(U,{to:"/config/policy.html#levelpolicyobject"},{default:e((()=>[w])),_:1}),j]),o("p",null,[x,P,t(U,{to:"/config/policy.html#levelpolicyobject"},{default:e((()=>[C])),_:1}),S,D,T]),_,O],64)};export default r; +import{r as s,o as n,c as a,a as o,b as t,w as e,F as l,e as p,d as c}from"./app.48111a85.js";const r={},u=o("h1",{id:"shadowsocks",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#shadowsocks","aria-hidden":"true"},"#"),p(" Shadowsocks")],-1),i={href:"https://zh.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},d=p("Shadowsocks"),b=p(" 协议,兼容大部分其它版本的实现。"),k=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),h={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},q=p("Shadowsocks AEAD 加密方式设计存在严重漏洞,无法保证通信内容的可靠性"),g=o("li",null,"原有 TCP 重放过滤器误报率随时间增加",-1),m=o("li",null,"没有 UDP 重放保护",-1),y=o("li",null,"可用于主动探测的 TCP 行为",-1),f=c('

    警告

    "none" 不加密方式下流量将明文传输。为确保安全性, 不要在公共网络上使用。

    InboundConfigurationObject

    {\n  "settings": {\n    "password": "密码",\n    "method": "aes-256-gcm",\n    "level": 0,\n    "email": "love@xray.com",\n    "network": "tcp,udp"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9

    network: "tcp" | "udp" | "tcp,udp"

    可接收的网络协议类型。比如当指定为 "tcp" 时,仅会接收 TCP 流量。默认值为 "tcp"

    ClientObject

    {\n  "password": "密码",\n  "method": "aes-256-gcm",\n  "level": 0,\n  "email": "love@xray.com"\n}\n
    1
    2
    3
    4
    5
    6

    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

    ',19),v=p("用户等级,连接会使用这个用户等级对应的 "),w=p("本地策略"),j=p("。"),x=o("code",null,"level",-1),P=p(" 的值, 对应 "),C=p("policy"),S=p(" 中 "),D=o("code",null,"level",-1),T=p(" 的值。 如不指定, 默认为 0。"),_=o("blockquote",null,[o("p",null,[o("code",null,"email"),p(": string")])],-1),O=o("p",null,"用户邮箱,用于区分不同用户的流量(日志、统计)。",-1);r.render=function(p,c){const r=s("OutboundLink"),U=s("RouterLink");return n(),a(l,null,[u,o("p",null,[o("a",i,[d,t(r)]),b]),k,o("ul",null,[o("li",null,[o("a",h,[q,t(r)])]),g,m,y]),f,o("p",null,[v,t(U,{to:"/config/policy.html#levelpolicyobject"},{default:e((()=>[w])),_:1}),j]),o("p",null,[x,P,t(U,{to:"/config/policy.html#levelpolicyobject"},{default:e((()=>[C])),_:1}),S,D,T]),_,O],64)};export default r; diff --git a/assets/shadowsocks.html.35c0831b.js b/assets/shadowsocks.html.7d51c0a6.js similarity index 99% rename from assets/shadowsocks.html.35c0831b.js rename to assets/shadowsocks.html.7d51c0a6.js index 5d4cfd4a3..3a199990c 100644 --- a/assets/shadowsocks.html.35c0831b.js +++ b/assets/shadowsocks.html.7d51c0a6.js @@ -1 +1 @@ -import{r as s,o as n,c as a,a as o,b as e,w as p,F as t,e as l,d as c}from"./app.755d843f.js";const r={},u=o("h1",{id:"shadowsocks",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#shadowsocks","aria-hidden":"true"},"#"),l(" Shadowsocks")],-1),i={href:"https://zh.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},d=l("Shadowsocks"),b=l(" 协议,兼容大部分其它版本的实现。"),k=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),q={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},h=l("Shadowsocks AEAD 加密方式设计存在严重漏洞,无法保证通信内容的可靠性"),m=o("li",null,"原有 TCP 重放过滤器误报率随时间增加",-1),g=o("li",null,"没有 UDP 重放保护",-1),y=o("li",null,"可用于主动探测的 TCP 行为",-1),v=c('

    警告

    "none" 不加密方式下流量将明文传输。为确保安全性, 不要在公共网络上使用。

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "email": "love@xray.com",\n      "address": "127.0.0.1",\n      "port": 1234,\n      "method": "加密方式",\n      "password": "密码",\n      "uot": true,\n      "UoTVersion": 2,\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    servers: [ServerObject]

    一个数组,代表一组 Shadowsocks 服务端设置, 其中每一项是一个 ServerObject

    ServerObject

    {\n  "email": "love@xray.com",\n  "address": "127.0.0.1",\n  "port": 1234,\n  "method": "加密方式",\n  "password": "密码",\n  "uot": true,\n  "UoTVersion": 2,\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    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

    ',30),f=l("用户等级,连接会使用这个用户等级对应的 "),w=l("本地策略"),j=l("。"),x=o("code",null,"level",-1),S=l(" 的值, 对应 "),P=l("policy"),T=l(" 中 "),U=o("code",null,"level",-1),O=l(" 的值。 如不指定, 默认为 0。");r.render=function(l,c){const r=s("OutboundLink"),C=s("RouterLink");return n(),a(t,null,[u,o("p",null,[o("a",i,[d,e(r)]),b]),k,o("ul",null,[o("li",null,[o("a",q,[h,e(r)])]),m,g,y]),v,o("p",null,[f,e(C,{to:"/config/policy.html#levelpolicyobject"},{default:p((()=>[w])),_:1}),j]),o("p",null,[x,S,e(C,{to:"/config/policy.html#policyobject"},{default:p((()=>[P])),_:1}),T,U,O])],64)};export default r; +import{r as s,o as n,c as a,a as o,b as e,w as p,F as t,e as l,d as c}from"./app.48111a85.js";const r={},u=o("h1",{id:"shadowsocks",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#shadowsocks","aria-hidden":"true"},"#"),l(" Shadowsocks")],-1),i={href:"https://zh.wikipedia.org/wiki/Shadowsocks",target:"_blank",rel:"noopener noreferrer"},d=l("Shadowsocks"),b=l(" 协议,兼容大部分其它版本的实现。"),k=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),q={href:"https://github.com/shadowsocks/shadowsocks-org/issues/183",target:"_blank",rel:"noopener noreferrer"},h=l("Shadowsocks AEAD 加密方式设计存在严重漏洞,无法保证通信内容的可靠性"),m=o("li",null,"原有 TCP 重放过滤器误报率随时间增加",-1),g=o("li",null,"没有 UDP 重放保护",-1),y=o("li",null,"可用于主动探测的 TCP 行为",-1),v=c('

    警告

    "none" 不加密方式下流量将明文传输。为确保安全性, 不要在公共网络上使用。

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "email": "love@xray.com",\n      "address": "127.0.0.1",\n      "port": 1234,\n      "method": "加密方式",\n      "password": "密码",\n      "uot": true,\n      "UoTVersion": 2,\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    servers: [ServerObject]

    一个数组,代表一组 Shadowsocks 服务端设置, 其中每一项是一个 ServerObject

    ServerObject

    {\n  "email": "love@xray.com",\n  "address": "127.0.0.1",\n  "port": 1234,\n  "method": "加密方式",\n  "password": "密码",\n  "uot": true,\n  "UoTVersion": 2,\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    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

    ',30),f=l("用户等级,连接会使用这个用户等级对应的 "),w=l("本地策略"),j=l("。"),x=o("code",null,"level",-1),S=l(" 的值, 对应 "),P=l("policy"),T=l(" 中 "),U=o("code",null,"level",-1),O=l(" 的值。 如不指定, 默认为 0。");r.render=function(l,c){const r=s("OutboundLink"),C=s("RouterLink");return n(),a(t,null,[u,o("p",null,[o("a",i,[d,e(r)]),b]),k,o("ul",null,[o("li",null,[o("a",q,[h,e(r)])]),m,g,y]),v,o("p",null,[f,e(C,{to:"/config/policy.html#levelpolicyobject"},{default:p((()=>[w])),_:1}),j]),o("p",null,[x,S,e(C,{to:"/config/policy.html#policyobject"},{default:p((()=>[P])),_:1}),T,U,O])],64)};export default r; diff --git a/assets/socks.html.00850baf.js b/assets/socks.html.1c6a0f4e.js similarity index 98% rename from assets/socks.html.00850baf.js rename to assets/socks.html.1c6a0f4e.js index 7e0b90e01..7b2b320fa 100644 --- a/assets/socks.html.00850baf.js +++ b/assets/socks.html.1c6a0f4e.js @@ -1 +1 @@ -import{r as n,o as s,c as e,a,b as o,w as t,F as p,e as c,d as r}from"./app.755d843f.js";const u={},l=a("h1",{id:"socks",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#socks","aria-hidden":"true"},"#"),c(" SOCKS")],-1),i=c("The standard SOCKS protocol implementation is compatible with "),d={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},b=c("SOCKS 4"),k=c(", SOCKS 4a, and "),h={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},q=c("SOCKS 5"),m=c("."),f=r('

    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

    {\n  "auth": "noauth",\n  "accounts": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ],\n  "udp": false,\n  "ip": "127.0.0.1",\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    auth: "noauth" | "password"

    The authentication method for the SOCKS protocol, supporting "noauth" for anonymous mode and "password" for username/password authentication.

    The default value is "noauth".

    accounts: [ AccountObject ]

    An array where each element represents a user account.

    This option is only valid when auth is set to "password".

    The default value is an empty array.

    udp: true | false

    Whether to enable UDP protocol support.

    The default value is false.

    ip: address

    When UDP is enabled, Xray needs to know the local IP address.

    The default value is "127.0.0.1".

    userLevel: number

    ',18),g=c("The user level that the connection will use to determine the corresponding "),v=c("Local Policy"),y=c("."),S=c("The value of "),j=a("code",null,"userLevel",-1),w=c(" corresponds to the value of "),O=a("code",null,"level",-1),T=c(" in the "),C=c("policy"),K=c(". If not specified, the default value is 0."),x=r('

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    The username as a string. Required.

    pass: string

    The password as a string. Required.

    ',6);u.render=function(c,r){const u=n("OutboundLink"),L=n("RouterLink");return s(),e(p,null,[l,a("p",null,[i,a("a",d,[b,o(u)]),k,a("a",h,[q,o(u)]),m]),f,a("p",null,[g,o(L,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[v])),_:1}),y]),a("p",null,[S,j,w,O,T,o(L,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[C])),_:1}),K]),x],64)};export default u; +import{r as n,o as s,c as e,a,b as o,w as t,F as p,e as c,d as r}from"./app.48111a85.js";const u={},l=a("h1",{id:"socks",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#socks","aria-hidden":"true"},"#"),c(" SOCKS")],-1),i=c("The standard SOCKS protocol implementation is compatible with "),d={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},b=c("SOCKS 4"),k=c(", SOCKS 4a, and "),h={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},q=c("SOCKS 5"),m=c("."),f=r('

    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

    {\n  "auth": "noauth",\n  "accounts": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ],\n  "udp": false,\n  "ip": "127.0.0.1",\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    auth: "noauth" | "password"

    The authentication method for the SOCKS protocol, supporting "noauth" for anonymous mode and "password" for username/password authentication.

    The default value is "noauth".

    accounts: [ AccountObject ]

    An array where each element represents a user account.

    This option is only valid when auth is set to "password".

    The default value is an empty array.

    udp: true | false

    Whether to enable UDP protocol support.

    The default value is false.

    ip: address

    When UDP is enabled, Xray needs to know the local IP address.

    The default value is "127.0.0.1".

    userLevel: number

    ',18),g=c("The user level that the connection will use to determine the corresponding "),v=c("Local Policy"),y=c("."),S=c("The value of "),j=a("code",null,"userLevel",-1),w=c(" corresponds to the value of "),O=a("code",null,"level",-1),T=c(" in the "),C=c("policy"),K=c(". If not specified, the default value is 0."),x=r('

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    The username as a string. Required.

    pass: string

    The password as a string. Required.

    ',6);u.render=function(c,r){const u=n("OutboundLink"),L=n("RouterLink");return s(),e(p,null,[l,a("p",null,[i,a("a",d,[b,o(u)]),k,a("a",h,[q,o(u)]),m]),f,a("p",null,[g,o(L,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[v])),_:1}),y]),a("p",null,[S,j,w,O,T,o(L,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[C])),_:1}),K]),x],64)};export default u; diff --git a/assets/socks.html.40f804cc.js b/assets/socks.html.865647cc.js similarity index 99% rename from assets/socks.html.40f804cc.js rename to assets/socks.html.865647cc.js index b5bfc9e33..136376e09 100644 --- a/assets/socks.html.40f804cc.js +++ b/assets/socks.html.865647cc.js @@ -1 +1 @@ -import{r as s,o as n,c as a,a as p,b as e,w as o,F as t,d as c,e as r}from"./app.755d843f.js";const l={},u=c('

    Socks

    标准 Socks 协议实现,兼容 Socks 5。

    警告

    Socks 协议没有对传输加密,不适宜经公网中传输

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "address": "127.0.0.1",\n      "port": 1234,\n      "users": [\n        {\n          "user": "test user",\n          "pass": "test pass",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    servers: [ ServerObject ]

    Socks 服务器列表,其中每一项是一个服务器配置。

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 1234,\n  "users": [\n    {\n      "user": "test user",\n      "pass": "test pass",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    address: address

    服务器地址, 必填

    提示

    仅支持连接到 Socks 5 服务器。

    port: number

    服务器端口, 必填

    users: [ UserObject ]

    一个数组表示的用户列表,数组中每个元素为一个用户配置。

    当列表不为空时,Socks 客户端会使用用户信息进行认证;如未指定,则不进行认证。

    默认值为空。

    UserObject

    {\n  "user": "test user",\n  "pass": "test pass",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    level: number

    ',25),i=r("用户等级,连接会使用这个用户等级对应的 "),b=r("本地策略"),k=r("。"),d=r("userLevel 的值, 对应 "),q=r("policy"),m=r(" 中 "),g=p("code",null,"level",-1),v=r(" 的值。 如不指定, 默认为 0。");l.render=function(c,r){const l=s("RouterLink");return n(),a(t,null,[u,p("p",null,[i,e(l,{to:"/config/policy.html#levelpolicyobject"},{default:o((()=>[b])),_:1}),k]),p("p",null,[d,e(l,{to:"/config/policy.html#policyobject"},{default:o((()=>[q])),_:1}),m,g,v])],64)};export default l; +import{r as s,o as n,c as a,a as p,b as e,w as o,F as t,d as c,e as r}from"./app.48111a85.js";const l={},u=c('

    Socks

    标准 Socks 协议实现,兼容 Socks 5。

    警告

    Socks 协议没有对传输加密,不适宜经公网中传输

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "address": "127.0.0.1",\n      "port": 1234,\n      "users": [\n        {\n          "user": "test user",\n          "pass": "test pass",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    servers: [ ServerObject ]

    Socks 服务器列表,其中每一项是一个服务器配置。

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 1234,\n  "users": [\n    {\n      "user": "test user",\n      "pass": "test pass",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    address: address

    服务器地址, 必填

    提示

    仅支持连接到 Socks 5 服务器。

    port: number

    服务器端口, 必填

    users: [ UserObject ]

    一个数组表示的用户列表,数组中每个元素为一个用户配置。

    当列表不为空时,Socks 客户端会使用用户信息进行认证;如未指定,则不进行认证。

    默认值为空。

    UserObject

    {\n  "user": "test user",\n  "pass": "test pass",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    level: number

    ',25),i=r("用户等级,连接会使用这个用户等级对应的 "),b=r("本地策略"),k=r("。"),d=r("userLevel 的值, 对应 "),q=r("policy"),m=r(" 中 "),g=p("code",null,"level",-1),v=r(" 的值。 如不指定, 默认为 0。");l.render=function(c,r){const l=s("RouterLink");return n(),a(t,null,[u,p("p",null,[i,e(l,{to:"/config/policy.html#levelpolicyobject"},{default:o((()=>[b])),_:1}),k]),p("p",null,[d,e(l,{to:"/config/policy.html#policyobject"},{default:o((()=>[q])),_:1}),m,g,v])],64)};export default l; diff --git a/assets/socks.html.ffdb6877.js b/assets/socks.html.8f599494.js similarity index 97% rename from assets/socks.html.ffdb6877.js rename to assets/socks.html.8f599494.js index a01490a3e..9d7b0e370 100644 --- a/assets/socks.html.ffdb6877.js +++ b/assets/socks.html.8f599494.js @@ -1 +1 @@ -import{r as s,o as n,c as a,a as e,b as o,w as p,F as t,e as r,d as c}from"./app.755d843f.js";const l={},u=e("h1",{id:"socks",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#socks","aria-hidden":"true"},"#"),r(" Socks")],-1),i=r("The Socks protocol is a standard protocol implementation that is compatible with "),b={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},d=r("Socks 5"),k=r("."),m=c('

    Danger

    The Socks protocol does not provide encryption for transmission and is not suitable for transmitting data over public networks.

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "address": "127.0.0.1",\n      "port": 1234,\n      "users": [\n        {\n          "user": "test user",\n          "pass": "test pass",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    servers: [ ServerObject ]

    An array representing a list of Socks servers, where each item is a server configuration.

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 1234,\n  "users": [\n    {\n      "user": "test user",\n      "pass": "test pass",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    address: address

    The server address. Required.

    Tip

    Only connections to Socks 5 servers are supported.

    port: number

    The server port. Required.

    users: [ UserObject ]

    An array representing a list of users. Each item in the array is a user configuration.

    When the list is not empty, the Socks client will authenticate using the user information. If not specified, no authentication is performed.

    The default value is an empty array.

    UserObject

    {\n  "user": "test user",\n  "pass": "test pass",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    user: string

    The username. Required.

    pass: string

    The password. Required.

    level: number

    ',23),q=r("The user level. Connections will use the corresponding "),h=r("local policy"),v=r(" associated with this user level."),g=r("The "),f=e("code",null,"level",-1),y=r(" value corresponds to the "),j=e("code",null,"level",-1),S=r(" value in the "),T=r("policy"),O=r(". If not specified, the default value is 0.");l.render=function(r,c){const l=s("OutboundLink"),w=s("RouterLink");return n(),a(t,null,[u,e("p",null,[i,e("a",b,[d,o(l)]),k]),m,e("p",null,[q,o(w,{to:"/en/config/policy.html#levelpolicyobject"},{default:p((()=>[h])),_:1}),v]),e("p",null,[g,f,y,j,S,o(w,{to:"/en/config/policy.html#policyobject"},{default:p((()=>[T])),_:1}),O])],64)};export default l; +import{r as s,o as n,c as a,a as e,b as o,w as p,F as t,e as r,d as c}from"./app.48111a85.js";const l={},u=e("h1",{id:"socks",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#socks","aria-hidden":"true"},"#"),r(" Socks")],-1),i=r("The Socks protocol is a standard protocol implementation that is compatible with "),b={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},k=r("Socks 5"),d=r("."),m=c('

    Danger

    The Socks protocol does not provide encryption for transmission and is not suitable for transmitting data over public networks.

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "address": "127.0.0.1",\n      "port": 1234,\n      "users": [\n        {\n          "user": "test user",\n          "pass": "test pass",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    servers: [ ServerObject ]

    An array representing a list of Socks servers, where each item is a server configuration.

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 1234,\n  "users": [\n    {\n      "user": "test user",\n      "pass": "test pass",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    address: address

    The server address. Required.

    Tip

    Only connections to Socks 5 servers are supported.

    port: number

    The server port. Required.

    users: [ UserObject ]

    An array representing a list of users. Each item in the array is a user configuration.

    When the list is not empty, the Socks client will authenticate using the user information. If not specified, no authentication is performed.

    The default value is an empty array.

    UserObject

    {\n  "user": "test user",\n  "pass": "test pass",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    user: string

    The username. Required.

    pass: string

    The password. Required.

    level: number

    ',23),q=r("The user level. Connections will use the corresponding "),h=r("local policy"),v=r(" associated with this user level."),g=r("The "),f=e("code",null,"level",-1),y=r(" value corresponds to the "),j=e("code",null,"level",-1),S=r(" value in the "),T=r("policy"),O=r(". If not specified, the default value is 0.");l.render=function(r,c){const l=s("OutboundLink"),w=s("RouterLink");return n(),a(t,null,[u,e("p",null,[i,e("a",b,[k,o(l)]),d]),m,e("p",null,[q,o(w,{to:"/en/config/policy.html#levelpolicyobject"},{default:p((()=>[h])),_:1}),v]),e("p",null,[g,f,y,j,S,o(w,{to:"/en/config/policy.html#policyobject"},{default:p((()=>[T])),_:1}),O])],64)};export default l; diff --git a/assets/socks.html.068a2af0.js b/assets/socks.html.9102c266.js similarity index 98% rename from assets/socks.html.068a2af0.js rename to assets/socks.html.9102c266.js index 923448cfc..929ec97ec 100644 --- a/assets/socks.html.068a2af0.js +++ b/assets/socks.html.9102c266.js @@ -1 +1 @@ -import{r as s,o as n,c as a,a as o,b as e,w as p,F as t,e as c,d as u}from"./app.755d843f.js";const r={},l=o("h1",{id:"socks",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#socks","aria-hidden":"true"},"#"),c(" Socks")],-1),i=c("标准 Socks 协议实现,兼容 "),d={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},k=c("Socks 4"),b=c("、"),q={href:"https://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4A.protocol",target:"_blank",rel:"noopener noreferrer"},m=c("Socks 4a"),h=c(" 和 Socks 5。"),g=u('

    警告

    Socks 协议没有对传输加密,不适宜经公网中传输

    Socks 入站更有意义的用法是在局域网或本机环境下监听,为其他程序提供本地服务。

    InboundConfigurationObject

    {\n  "auth": "noauth",\n  "accounts": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ],\n  "udp": false,\n  "ip": "127.0.0.1",\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    auth: "noauth" | "password"

    Socks 协议的认证方式,支持 "noauth" 匿名方式和 "password" 用户密码方式。

    默认值为 "noauth"

    accounts: [ AccountObject ]

    一个数组,数组中每个元素为一个用户帐号。

    此选项仅当 authpassword 时有效。

    默认值为空。

    udp: true | false

    是否开启 UDP 协议的支持。

    默认值为 false

    ip: address

    当开启 UDP 时,Xray 需要知道本机的 IP 地址。

    默认值为 "127.0.0.1"

    userLevel: number

    ',18),f=c("用户等级,连接会使用这个用户等级对应的 "),y=c("本地策略"),j=c("。"),v=c("userLevel 的值, 对应 "),S=c("policy"),w=c(" 中 "),x=o("code",null,"level",-1),O=c(" 的值。 如不指定, 默认为 0。"),L=u('

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    ',6);r.render=function(c,u){const r=s("OutboundLink"),_=s("RouterLink");return n(),a(t,null,[l,o("p",null,[i,o("a",d,[k,e(r)]),b,o("a",q,[m,e(r)]),h]),g,o("p",null,[f,e(_,{to:"/config/policy.html#levelpolicyobject"},{default:p((()=>[y])),_:1}),j]),o("p",null,[v,e(_,{to:"/config/policy.html#policyobject"},{default:p((()=>[S])),_:1}),w,x,O]),L],64)};export default r; +import{r as s,o as n,c as a,a as o,b as e,w as p,F as t,e as c,d as u}from"./app.48111a85.js";const r={},l=o("h1",{id:"socks",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#socks","aria-hidden":"true"},"#"),c(" Socks")],-1),i=c("标准 Socks 协议实现,兼容 "),d={href:"http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol",target:"_blank",rel:"noopener noreferrer"},k=c("Socks 4"),b=c("、"),q={href:"https://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4A.protocol",target:"_blank",rel:"noopener noreferrer"},m=c("Socks 4a"),h=c(" 和 Socks 5。"),g=u('

    警告

    Socks 协议没有对传输加密,不适宜经公网中传输

    Socks 入站更有意义的用法是在局域网或本机环境下监听,为其他程序提供本地服务。

    InboundConfigurationObject

    {\n  "auth": "noauth",\n  "accounts": [\n    {\n      "user": "my-username",\n      "pass": "my-password"\n    }\n  ],\n  "udp": false,\n  "ip": "127.0.0.1",\n  "userLevel": 0\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    auth: "noauth" | "password"

    Socks 协议的认证方式,支持 "noauth" 匿名方式和 "password" 用户密码方式。

    默认值为 "noauth"

    accounts: [ AccountObject ]

    一个数组,数组中每个元素为一个用户帐号。

    此选项仅当 authpassword 时有效。

    默认值为空。

    udp: true | false

    是否开启 UDP 协议的支持。

    默认值为 false

    ip: address

    当开启 UDP 时,Xray 需要知道本机的 IP 地址。

    默认值为 "127.0.0.1"

    userLevel: number

    ',18),f=c("用户等级,连接会使用这个用户等级对应的 "),y=c("本地策略"),j=c("。"),v=c("userLevel 的值, 对应 "),S=c("policy"),w=c(" 中 "),x=o("code",null,"level",-1),O=c(" 的值。 如不指定, 默认为 0。"),L=u('

    AccountObject

    {\n  "user": "my-username",\n  "pass": "my-password"\n}\n
    1
    2
    3
    4

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    ',6);r.render=function(c,u){const r=s("OutboundLink"),_=s("RouterLink");return n(),a(t,null,[l,o("p",null,[i,o("a",d,[k,e(r)]),b,o("a",q,[m,e(r)]),h]),g,o("p",null,[f,e(_,{to:"/config/policy.html#levelpolicyobject"},{default:p((()=>[y])),_:1}),j]),o("p",null,[v,e(_,{to:"/config/policy.html#policyobject"},{default:p((()=>[S])),_:1}),w,x,O]),L],64)};export default r; diff --git a/assets/stateDiagram-d766d74d.21d88775.js b/assets/stateDiagram-d766d74d.3653d77d.js similarity index 98% rename from assets/stateDiagram-d766d74d.21d88775.js rename to assets/stateDiagram-d766d74d.3653d77d.js index 92b509562..b9e396f2d 100644 --- a/assets/stateDiagram-d766d74d.21d88775.js +++ b/assets/stateDiagram-d766d74d.3653d77d.js @@ -1 +1 @@ -import{p as t,d as e,s as a}from"./styles-2797ae0f.8914e425.js";import{c as i,h as n,l as r,i as d,j as s,a5 as o,y as g}from"./mermaid.core.a66200b0.js";import{G as p,l as c}from"./layout.2f099f66.js";import{l as h}from"./line.f17bed9e.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";const l={},x=(t,e)=>{l[t]=e},f=(t,e)=>{const a=t.append("text").attr("x",2*i().state.padding).attr("y",i().state.textHeight+1.3*i().state.padding).attr("font-size",i().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),n=a.height,r=t.append("text").attr("x",i().state.padding).attr("y",n+.4*i().state.padding+i().state.dividerMargin+i().state.textHeight).attr("class","state-description");let d=!0,s=!0;e.descriptions.forEach((function(t){d||(!function(t,e,a){const n=t.append("tspan").attr("x",2*i().state.padding).text(e);a||n.attr("dy",i().state.textHeight)}(r,t,s),s=!1),d=!1}));const o=t.append("line").attr("x1",i().state.padding).attr("y1",i().state.padding+n+i().state.dividerMargin/2).attr("y2",i().state.padding+n+i().state.dividerMargin/2).attr("class","descr-divider"),g=r.node().getBBox(),p=Math.max(g.width,a.width);return o.attr("x2",p+3*i().state.padding),t.insert("rect",":first-child").attr("x",i().state.padding).attr("y",i().state.padding).attr("width",p+2*i().state.padding).attr("height",g.height+n+2*i().state.padding).attr("rx",i().state.radius),t},u=(t,e,a)=>{const n=i().state.padding,r=2*i().state.padding,d=t.node().getBBox(),s=d.width,o=d.x,g=t.append("text").attr("x",0).attr("y",i().state.titleShift).attr("font-size",i().state.fontSize).attr("class","state-title").text(e.id),p=g.node().getBBox().width+r;let c,h=Math.max(p,s);h===s&&(h+=r);const l=t.node().getBBox();e.doc,c=o-n,p>s&&(c=(s-h)/2+n),Math.abs(o-l.x)s&&(c=o-(p-s)/2);const x=1-i().state.textHeight;return t.insert("rect",":first-child").attr("x",c).attr("y",x).attr("class",a?"alt-composit":"composit").attr("width",h).attr("height",l.height+i().state.textHeight+i().state.titleShift+1).attr("rx","0"),g.attr("x",c+n),p<=s&&g.attr("x",o+(h-r)/2-p/2+n),t.insert("rect",":first-child").attr("x",c).attr("y",i().state.titleShift-i().state.textHeight-i().state.padding).attr("width",h).attr("height",3*i().state.textHeight).attr("rx",i().state.radius),t.insert("rect",":first-child").attr("x",c).attr("y",i().state.titleShift-i().state.textHeight-i().state.padding).attr("width",h).attr("height",l.height+3+2*i().state.textHeight).attr("rx",i().state.radius),t},y=(t,e)=>{e.attr("class","state-note");const a=e.append("rect").attr("x",0).attr("y",i().state.padding),n=e.append("g"),{textWidth:r,textHeight:d}=((t,e,a,n)=>{let r=0;const d=n.append("text");d.style("text-anchor","start"),d.attr("class","noteText");let o=t.replace(/\r\n/g,"
    ");o=o.replace(/\n/g,"
    ");const g=o.split(s.lineBreakRegex);let p=1.25*i().state.noteMargin;for(const s of g){const t=s.trim();if(t.length>0){const n=d.append("tspan");n.text(t),0===p&&(p+=n.node().getBBox().height),r+=p,n.attr("x",e+i().state.noteMargin),n.attr("y",a+r+1.25*i().state.noteMargin)}}return{textWidth:d.node().getBBox().width,textHeight:r}})(t,0,0,n);return a.attr("height",d+2*i().state.noteMargin),a.attr("width",r+2*i().state.noteMargin),a},m=function(t,e){const a=e.id,n={id:a,label:e.id,width:0,height:0},r=t.append("g").attr("id",a).attr("class","stateGroup");"start"===e.type&&(t=>{t.append("circle").attr("class","start-state").attr("r",i().state.sizeUnit).attr("cx",i().state.padding+i().state.sizeUnit).attr("cy",i().state.padding+i().state.sizeUnit)})(r),"end"===e.type&&(t=>{t.append("circle").attr("class","end-state-outer").attr("r",i().state.sizeUnit+i().state.miniPadding).attr("cx",i().state.padding+i().state.sizeUnit+i().state.miniPadding).attr("cy",i().state.padding+i().state.sizeUnit+i().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",i().state.sizeUnit).attr("cx",i().state.padding+i().state.sizeUnit+2).attr("cy",i().state.padding+i().state.sizeUnit+2)})(r),"fork"!==e.type&&"join"!==e.type||((t,e)=>{let a=i().state.forkWidth,n=i().state.forkHeight;if(e.parentId){let t=a;a=n,n=t}t.append("rect").style("stroke","black").style("fill","black").attr("width",a).attr("height",n).attr("x",i().state.padding).attr("y",i().state.padding)})(r,e),"note"===e.type&&y(e.note.text,r),"divider"===e.type&&(t=>{t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",i().state.textHeight).attr("class","divider").attr("x2",2*i().state.textHeight).attr("y1",0).attr("y2",0)})(r),"default"===e.type&&0===e.descriptions.length&&((t,e)=>{const a=t.append("text").attr("x",2*i().state.padding).attr("y",i().state.textHeight+2*i().state.padding).attr("font-size",i().state.fontSize).attr("class","state-title").text(e.id),n=a.node().getBBox();t.insert("rect",":first-child").attr("x",i().state.padding).attr("y",i().state.padding).attr("width",n.width+2*i().state.padding).attr("height",n.height+2*i().state.padding).attr("rx",i().state.radius)})(r,e),"default"===e.type&&e.descriptions.length>0&&f(r,e);const d=r.node().getBBox();return n.width=d.width+2*i().state.padding,n.height=d.height+2*i().state.padding,x(a,n),n};let w=0;let b;const B={},k=(t,a,n,d,l,x,f)=>{const y=new p({compound:!0,multigraph:!0});let N,E=!0;for(N=0;N{const e=t.parentElement;let a=0,i=0;e&&(e.parentElement&&(a=e.parentElement.getBBox().width),i=parseInt(e.getAttribute("data-x-shift"),10),Number.isNaN(i)&&(i=0)),t.setAttribute("x1",0-i+8),t.setAttribute("x2",a-i-8)}))}else r.debug("No Node "+t+": "+JSON.stringify(y.node(t)))}));let L=H.getBBox();y.edges().forEach((function(t){void 0!==t&&void 0!==y.edge(t)&&(r.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(y.edge(t))),function(t,a,n){a.points=a.points.filter((t=>!Number.isNaN(t.y)));const d=a.points,p=h().x((function(t){return t.x})).y((function(t){return t.y})).curve(o),c=t.append("path").attr("d",p(d)).attr("id","edge"+w).attr("class","transition");let l="";if(i().state.arrowMarkerAbsolute&&(l=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,l=l.replace(/\(/g,"\\("),l=l.replace(/\)/g,"\\)")),c.attr("marker-end","url("+l+"#"+function(t){switch(e.relationType.DEPENDENCY){case e.relationType.AGGREGATION:return"aggregation";case e.relationType.EXTENSION:return"extension";case e.relationType.COMPOSITION:return"composition";case e.relationType.DEPENDENCY:return"dependency"}}()+"End)"),void 0!==n.title){const e=t.append("g").attr("class","stateLabel"),{x:d,y:o}=g.calcLabelPosition(a.points),p=s.getRows(n.title);let c=0;const h=[];let l=0,x=0;for(let t=0;t<=p.length;t++){const a=e.append("text").attr("text-anchor","middle").text(p[t]).attr("x",d).attr("y",o+c),i=a.node().getBBox();if(l=Math.max(l,i.width),x=Math.min(x,i.x),r.info(i.x,d,o+c),0===c){const t=a.node().getBBox();c=t.height,r.info("Title height",c,o)}h.push(a)}let f=c*p.length;if(p.length>1){const t=(p.length-1)*c*.5;h.forEach(((e,a)=>e.attr("y",o+a*c-t))),f=c*p.length}const u=e.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",d-l/2-i().state.padding/2).attr("y",o-f/2-i().state.padding/2-3.5).attr("width",l+i().state.padding).attr("height",f+i().state.padding),r.info(u)}w++}(a,y.edge(t),y.edge(t).relation))})),L=H.getBBox();const T={id:n||"root",label:n||"root",width:0,height:0};return T.width=L.width+2*b.padding,T.height=L.height+2*b.padding,r.debug("Doc rendered",T,y),T},N={parser:t,db:e,renderer:{setConf:function(){},draw:function(t,e,a,s){b=i().state;const o=i().securityLevel;let g;"sandbox"===o&&(g=n("#i"+e));const c=n("sandbox"===o?g.nodes()[0].contentDocument.body:"body"),h="sandbox"===o?g.nodes()[0].contentDocument:document;r.debug("Rendering diagram "+t);const l=c.select(`[id='${e}']`);l.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");new p({multigraph:!0,compound:!0,rankdir:"RL"}).setDefaultEdgeLabel((function(){return{}}));const x=s.db.getRootDoc();k(x,l,void 0,!1,c,h,s);const f=b.padding,u=l.node().getBBox(),y=u.width+2*f,m=u.height+2*f;d(l,m,1.75*y,b.useMaxWidth),l.attr("viewBox",`${u.x-b.padding} ${u.y-b.padding} `+y+" "+m)}},styles:a,init:t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,e.clear()}};export{N as diagram}; +import{p as t,d as e,s as a}from"./styles-2797ae0f.76392e9d.js";import{c as i,h as n,l as r,i as d,j as s,a5 as o,y as g}from"./mermaid.core.3a590193.js";import{G as p,l as c}from"./layout.02c3e151.js";import{l as h}from"./line.53b161c2.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";const l={},x=(t,e)=>{l[t]=e},f=(t,e)=>{const a=t.append("text").attr("x",2*i().state.padding).attr("y",i().state.textHeight+1.3*i().state.padding).attr("font-size",i().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),n=a.height,r=t.append("text").attr("x",i().state.padding).attr("y",n+.4*i().state.padding+i().state.dividerMargin+i().state.textHeight).attr("class","state-description");let d=!0,s=!0;e.descriptions.forEach((function(t){d||(!function(t,e,a){const n=t.append("tspan").attr("x",2*i().state.padding).text(e);a||n.attr("dy",i().state.textHeight)}(r,t,s),s=!1),d=!1}));const o=t.append("line").attr("x1",i().state.padding).attr("y1",i().state.padding+n+i().state.dividerMargin/2).attr("y2",i().state.padding+n+i().state.dividerMargin/2).attr("class","descr-divider"),g=r.node().getBBox(),p=Math.max(g.width,a.width);return o.attr("x2",p+3*i().state.padding),t.insert("rect",":first-child").attr("x",i().state.padding).attr("y",i().state.padding).attr("width",p+2*i().state.padding).attr("height",g.height+n+2*i().state.padding).attr("rx",i().state.radius),t},u=(t,e,a)=>{const n=i().state.padding,r=2*i().state.padding,d=t.node().getBBox(),s=d.width,o=d.x,g=t.append("text").attr("x",0).attr("y",i().state.titleShift).attr("font-size",i().state.fontSize).attr("class","state-title").text(e.id),p=g.node().getBBox().width+r;let c,h=Math.max(p,s);h===s&&(h+=r);const l=t.node().getBBox();e.doc,c=o-n,p>s&&(c=(s-h)/2+n),Math.abs(o-l.x)s&&(c=o-(p-s)/2);const x=1-i().state.textHeight;return t.insert("rect",":first-child").attr("x",c).attr("y",x).attr("class",a?"alt-composit":"composit").attr("width",h).attr("height",l.height+i().state.textHeight+i().state.titleShift+1).attr("rx","0"),g.attr("x",c+n),p<=s&&g.attr("x",o+(h-r)/2-p/2+n),t.insert("rect",":first-child").attr("x",c).attr("y",i().state.titleShift-i().state.textHeight-i().state.padding).attr("width",h).attr("height",3*i().state.textHeight).attr("rx",i().state.radius),t.insert("rect",":first-child").attr("x",c).attr("y",i().state.titleShift-i().state.textHeight-i().state.padding).attr("width",h).attr("height",l.height+3+2*i().state.textHeight).attr("rx",i().state.radius),t},y=(t,e)=>{e.attr("class","state-note");const a=e.append("rect").attr("x",0).attr("y",i().state.padding),n=e.append("g"),{textWidth:r,textHeight:d}=((t,e,a,n)=>{let r=0;const d=n.append("text");d.style("text-anchor","start"),d.attr("class","noteText");let o=t.replace(/\r\n/g,"
    ");o=o.replace(/\n/g,"
    ");const g=o.split(s.lineBreakRegex);let p=1.25*i().state.noteMargin;for(const s of g){const t=s.trim();if(t.length>0){const n=d.append("tspan");n.text(t),0===p&&(p+=n.node().getBBox().height),r+=p,n.attr("x",e+i().state.noteMargin),n.attr("y",a+r+1.25*i().state.noteMargin)}}return{textWidth:d.node().getBBox().width,textHeight:r}})(t,0,0,n);return a.attr("height",d+2*i().state.noteMargin),a.attr("width",r+2*i().state.noteMargin),a},m=function(t,e){const a=e.id,n={id:a,label:e.id,width:0,height:0},r=t.append("g").attr("id",a).attr("class","stateGroup");"start"===e.type&&(t=>{t.append("circle").attr("class","start-state").attr("r",i().state.sizeUnit).attr("cx",i().state.padding+i().state.sizeUnit).attr("cy",i().state.padding+i().state.sizeUnit)})(r),"end"===e.type&&(t=>{t.append("circle").attr("class","end-state-outer").attr("r",i().state.sizeUnit+i().state.miniPadding).attr("cx",i().state.padding+i().state.sizeUnit+i().state.miniPadding).attr("cy",i().state.padding+i().state.sizeUnit+i().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",i().state.sizeUnit).attr("cx",i().state.padding+i().state.sizeUnit+2).attr("cy",i().state.padding+i().state.sizeUnit+2)})(r),"fork"!==e.type&&"join"!==e.type||((t,e)=>{let a=i().state.forkWidth,n=i().state.forkHeight;if(e.parentId){let t=a;a=n,n=t}t.append("rect").style("stroke","black").style("fill","black").attr("width",a).attr("height",n).attr("x",i().state.padding).attr("y",i().state.padding)})(r,e),"note"===e.type&&y(e.note.text,r),"divider"===e.type&&(t=>{t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",i().state.textHeight).attr("class","divider").attr("x2",2*i().state.textHeight).attr("y1",0).attr("y2",0)})(r),"default"===e.type&&0===e.descriptions.length&&((t,e)=>{const a=t.append("text").attr("x",2*i().state.padding).attr("y",i().state.textHeight+2*i().state.padding).attr("font-size",i().state.fontSize).attr("class","state-title").text(e.id),n=a.node().getBBox();t.insert("rect",":first-child").attr("x",i().state.padding).attr("y",i().state.padding).attr("width",n.width+2*i().state.padding).attr("height",n.height+2*i().state.padding).attr("rx",i().state.radius)})(r,e),"default"===e.type&&e.descriptions.length>0&&f(r,e);const d=r.node().getBBox();return n.width=d.width+2*i().state.padding,n.height=d.height+2*i().state.padding,x(a,n),n};let w=0;let b;const B={},k=(t,a,n,d,l,x,f)=>{const y=new p({compound:!0,multigraph:!0});let N,E=!0;for(N=0;N{const e=t.parentElement;let a=0,i=0;e&&(e.parentElement&&(a=e.parentElement.getBBox().width),i=parseInt(e.getAttribute("data-x-shift"),10),Number.isNaN(i)&&(i=0)),t.setAttribute("x1",0-i+8),t.setAttribute("x2",a-i-8)}))}else r.debug("No Node "+t+": "+JSON.stringify(y.node(t)))}));let L=H.getBBox();y.edges().forEach((function(t){void 0!==t&&void 0!==y.edge(t)&&(r.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(y.edge(t))),function(t,a,n){a.points=a.points.filter((t=>!Number.isNaN(t.y)));const d=a.points,p=h().x((function(t){return t.x})).y((function(t){return t.y})).curve(o),c=t.append("path").attr("d",p(d)).attr("id","edge"+w).attr("class","transition");let l="";if(i().state.arrowMarkerAbsolute&&(l=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,l=l.replace(/\(/g,"\\("),l=l.replace(/\)/g,"\\)")),c.attr("marker-end","url("+l+"#"+function(t){switch(e.relationType.DEPENDENCY){case e.relationType.AGGREGATION:return"aggregation";case e.relationType.EXTENSION:return"extension";case e.relationType.COMPOSITION:return"composition";case e.relationType.DEPENDENCY:return"dependency"}}()+"End)"),void 0!==n.title){const e=t.append("g").attr("class","stateLabel"),{x:d,y:o}=g.calcLabelPosition(a.points),p=s.getRows(n.title);let c=0;const h=[];let l=0,x=0;for(let t=0;t<=p.length;t++){const a=e.append("text").attr("text-anchor","middle").text(p[t]).attr("x",d).attr("y",o+c),i=a.node().getBBox();if(l=Math.max(l,i.width),x=Math.min(x,i.x),r.info(i.x,d,o+c),0===c){const t=a.node().getBBox();c=t.height,r.info("Title height",c,o)}h.push(a)}let f=c*p.length;if(p.length>1){const t=(p.length-1)*c*.5;h.forEach(((e,a)=>e.attr("y",o+a*c-t))),f=c*p.length}const u=e.node().getBBox();e.insert("rect",":first-child").attr("class","box").attr("x",d-l/2-i().state.padding/2).attr("y",o-f/2-i().state.padding/2-3.5).attr("width",l+i().state.padding).attr("height",f+i().state.padding),r.info(u)}w++}(a,y.edge(t),y.edge(t).relation))})),L=H.getBBox();const T={id:n||"root",label:n||"root",width:0,height:0};return T.width=L.width+2*b.padding,T.height=L.height+2*b.padding,r.debug("Doc rendered",T,y),T},N={parser:t,db:e,renderer:{setConf:function(){},draw:function(t,e,a,s){b=i().state;const o=i().securityLevel;let g;"sandbox"===o&&(g=n("#i"+e));const c=n("sandbox"===o?g.nodes()[0].contentDocument.body:"body"),h="sandbox"===o?g.nodes()[0].contentDocument:document;r.debug("Rendering diagram "+t);const l=c.select(`[id='${e}']`);l.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");new p({multigraph:!0,compound:!0,rankdir:"RL"}).setDefaultEdgeLabel((function(){return{}}));const x=s.db.getRootDoc();k(x,l,void 0,!1,c,h,s);const f=b.padding,u=l.node().getBBox(),y=u.width+2*f,m=u.height+2*f;d(l,m,1.75*y,b.useMaxWidth),l.attr("viewBox",`${u.x-b.padding} ${u.y-b.padding} `+y+" "+m)}},styles:a,init:t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,e.clear()}};export{N as diagram}; diff --git a/assets/stateDiagram-v2-978d1189.2119f26f.js b/assets/stateDiagram-v2-978d1189.6fdea536.js similarity index 74% rename from assets/stateDiagram-v2-978d1189.2119f26f.js rename to assets/stateDiagram-v2-978d1189.6fdea536.js index c1b1023b1..bb7cc8402 100644 --- a/assets/stateDiagram-v2-978d1189.2119f26f.js +++ b/assets/stateDiagram-v2-978d1189.6fdea536.js @@ -1 +1 @@ -import{p as e,d as t,s,D as a,a as r,S as o,b as i,c as n}from"./styles-2797ae0f.8914e425.js";import{G as d}from"./layout.2f099f66.js";import{l as c,c as l,h as p,y as g,i as b,j as h}from"./mermaid.core.a66200b0.js";import{r as f}from"./index-05087a90.4347f31d.js";import"./edges-97052da4.ceadb26f.js";import"./createText-2f679d62.584f3edd.js";import"./svgDraw-6750006d.4f7863f3.js";import"./line.f17bed9e.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";let y={},m=0;function u(e="",t=0,s="",a="----"){return`state-${e}${null!==s&&s.length>0?`${a}${s}`:""}-${t}`}const x=(e,t,s,o,i,n)=>{const d=s.id,p=null==(g=o[d])?"":g.classes?g.classes.join(" "):"";var g;if("root"!==d){let t="rect";!0===s.start&&(t="start"),!1===s.start&&(t="end"),s.type!==a&&(t=s.type),y[d]||(y[d]={id:d,shape:t,description:h.sanitizeText(d,l()),classes:`${p} statediagram-state`});const o=y[d];s.description&&(Array.isArray(o.description)?(o.shape="rectWithTitle",o.description.push(s.description)):o.description.length>0?(o.shape="rectWithTitle",o.description===d?o.description=[s.description]:o.description=[o.description,s.description]):(o.shape="rect",o.description=s.description),o.description=h.sanitizeTextOrArray(o.description,l())),1===o.description.length&&"rectWithTitle"===o.shape&&(o.shape="rect"),!o.type&&s.doc&&(c.info("Setting cluster for ",d,T(s)),o.type="group",o.dir=T(s),o.shape=s.type===r?"divider":"roundedWithTitle",o.classes=o.classes+" statediagram-cluster "+(n?"statediagram-cluster-alt":""));const i={labelStyle:"",shape:o.shape,labelText:o.description,classes:o.classes,style:"",id:d,dir:o.dir,domId:u(d,m),type:o.type,padding:15,centerLabel:!0};if(s.note){const t={labelStyle:"",shape:"note",labelText:s.note.text,classes:"statediagram-note",style:"",id:d+"----note-"+m,domId:u(d,m,"note"),type:o.type,padding:15},a={labelStyle:"",shape:"noteGroup",labelText:s.note.text,classes:o.classes,style:"",id:d+"----parent",domId:u(d,m,"parent"),type:"group",padding:0};m++;const r=d+"----parent";e.setNode(r,a),e.setNode(t.id,t),e.setNode(d,i),e.setParent(d,r),e.setParent(t.id,r);let n=d,c=t.id;"left of"===s.note.position&&(n=t.id,c=d),e.setEdge(n,c,{arrowhead:"none",arrowType:"",style:"fill:none",labelStyle:"",classes:"transition note-edge",arrowheadStyle:"fill: #333",labelpos:"c",labelType:"text",thickness:"normal"})}else e.setNode(d,i)}t&&"root"!==t.id&&(c.trace("Setting node ",d," to be child of its parent ",t.id),e.setParent(d,t.id)),s.doc&&(c.trace("Adding nodes children "),w(e,s,s.doc,o,i,!n))},w=(e,t,s,r,n,d)=>{c.trace("items",s),s.forEach((s=>{switch(s.stmt){case i:case a:x(e,t,s,r,n,d);break;case o:{x(e,t,s.state1,r,n,d),x(e,t,s.state2,r,n,d);const a={id:"edge"+m,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:"fill:none",labelStyle:"",label:h.sanitizeText(s.description,l()),arrowheadStyle:"fill: #333",labelpos:"c",labelType:"text",thickness:"normal",classes:"transition"};e.setEdge(s.state1.id,s.state2.id,a,m),m++}}}))},T=(e,t=n)=>{let s=t;if(e.doc)for(let a=0;a{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute,t.clear()}};export{S as diagram}; +import{p as e,d as t,s,D as a,a as r,S as o,b as i,c as n}from"./styles-2797ae0f.76392e9d.js";import{G as d}from"./layout.02c3e151.js";import{l as c,c as l,h as p,y as g,i as b,j as h}from"./mermaid.core.3a590193.js";import{r as y}from"./index-05087a90.017bdfe5.js";import"./edges-97052da4.e255927b.js";import"./createText-2f679d62.a374f608.js";import"./svgDraw-6750006d.f814d75b.js";import"./line.53b161c2.js";import"./array.999c8e45.js";import"./constant.4f073c13.js";let m={},f=0;function u(e="",t=0,s="",a="----"){return`state-${e}${null!==s&&s.length>0?`${a}${s}`:""}-${t}`}const x=(e,t,s,o,i,n)=>{const d=s.id,p=null==(g=o[d])?"":g.classes?g.classes.join(" "):"";var g;if("root"!==d){let t="rect";!0===s.start&&(t="start"),!1===s.start&&(t="end"),s.type!==a&&(t=s.type),m[d]||(m[d]={id:d,shape:t,description:h.sanitizeText(d,l()),classes:`${p} statediagram-state`});const o=m[d];s.description&&(Array.isArray(o.description)?(o.shape="rectWithTitle",o.description.push(s.description)):o.description.length>0?(o.shape="rectWithTitle",o.description===d?o.description=[s.description]:o.description=[o.description,s.description]):(o.shape="rect",o.description=s.description),o.description=h.sanitizeTextOrArray(o.description,l())),1===o.description.length&&"rectWithTitle"===o.shape&&(o.shape="rect"),!o.type&&s.doc&&(c.info("Setting cluster for ",d,T(s)),o.type="group",o.dir=T(s),o.shape=s.type===r?"divider":"roundedWithTitle",o.classes=o.classes+" statediagram-cluster "+(n?"statediagram-cluster-alt":""));const i={labelStyle:"",shape:o.shape,labelText:o.description,classes:o.classes,style:"",id:d,dir:o.dir,domId:u(d,f),type:o.type,padding:15,centerLabel:!0};if(s.note){const t={labelStyle:"",shape:"note",labelText:s.note.text,classes:"statediagram-note",style:"",id:d+"----note-"+f,domId:u(d,f,"note"),type:o.type,padding:15},a={labelStyle:"",shape:"noteGroup",labelText:s.note.text,classes:o.classes,style:"",id:d+"----parent",domId:u(d,f,"parent"),type:"group",padding:0};f++;const r=d+"----parent";e.setNode(r,a),e.setNode(t.id,t),e.setNode(d,i),e.setParent(d,r),e.setParent(t.id,r);let n=d,c=t.id;"left of"===s.note.position&&(n=t.id,c=d),e.setEdge(n,c,{arrowhead:"none",arrowType:"",style:"fill:none",labelStyle:"",classes:"transition note-edge",arrowheadStyle:"fill: #333",labelpos:"c",labelType:"text",thickness:"normal"})}else e.setNode(d,i)}t&&"root"!==t.id&&(c.trace("Setting node ",d," to be child of its parent ",t.id),e.setParent(d,t.id)),s.doc&&(c.trace("Adding nodes children "),w(e,s,s.doc,o,i,!n))},w=(e,t,s,r,n,d)=>{c.trace("items",s),s.forEach((s=>{switch(s.stmt){case i:case a:x(e,t,s,r,n,d);break;case o:{x(e,t,s.state1,r,n,d),x(e,t,s.state2,r,n,d);const a={id:"edge"+f,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:"fill:none",labelStyle:"",label:h.sanitizeText(s.description,l()),arrowheadStyle:"fill: #333",labelpos:"c",labelType:"text",thickness:"normal",classes:"transition"};e.setEdge(s.state1.id,s.state2.id,a,f),f++}}}))},T=(e,t=n)=>{let s=t;if(e.doc)for(let a=0;a{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute,t.clear()}};export{S as diagram}; diff --git a/assets/stats.html.19d97934.js b/assets/stats.html.d7a6c7c1.js similarity index 97% rename from assets/stats.html.19d97934.js rename to assets/stats.html.d7a6c7c1.js index ab64c4137..092f7a22b 100644 --- a/assets/stats.html.19d97934.js +++ b/assets/stats.html.d7a6c7c1.js @@ -1 +1 @@ -import{r as t,o as a,c as n,a as e,b as s,w as p,F as o,d as i,e as c}from"./app.755d843f.js";const l={},g=i('

    统计信息

    用于配置 Xray 流量数据的统计。

    StatsObject

    StatsObject 对应配置文件的 stats 项。

    {\n  "stats": {}\n}\n
    1
    2
    3

    目前统计信息不需要任何参数,只要 StatsObject 项存在,内部的统计即会开启。

    ',6),d=c("开启了统计以后, 只需在 "),u=c("Policy"),r=c(" 中开启对应的项,就可以统计对应的数据。"),b=i('

    获取统计信息

    可以用 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);l.render=function(i,c){const l=t("RouterLink");return a(),n(o,null,[g,e("p",null,[d,s(l,{to:"/config/policy.html"},{default:p((()=>[u])),_:1}),r]),b],64)};export default l; +import{r as t,o as a,c as n,a as e,b as s,w as p,F as o,d as i,e as c}from"./app.48111a85.js";const l={},g=i('

    统计信息

    用于配置 Xray 流量数据的统计。

    StatsObject

    StatsObject 对应配置文件的 stats 项。

    {\n  "stats": {}\n}\n
    1
    2
    3

    目前统计信息不需要任何参数,只要 StatsObject 项存在,内部的统计即会开启。

    ',6),d=c("开启了统计以后, 只需在 "),u=c("Policy"),r=c(" 中开启对应的项,就可以统计对应的数据。"),b=i('

    获取统计信息

    可以用 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);l.render=function(i,c){const l=t("RouterLink");return a(),n(o,null,[g,e("p",null,[d,s(l,{to:"/config/policy.html"},{default:p((()=>[u])),_:1}),r]),b],64)};export default l; diff --git a/assets/stats.html.fb90cc6a.js b/assets/stats.html.fb81d901.js similarity index 97% rename from assets/stats.html.fb90cc6a.js rename to assets/stats.html.fb81d901.js index a5d517152..34cd4b61a 100644 --- a/assets/stats.html.fb90cc6a.js +++ b/assets/stats.html.fb81d901.js @@ -1 +1 @@ -import{r as t,o as e,c as i,a,b as s,w as n,F as c,d as o,e as r}from"./app.755d843f.js";const p={},l=o('

    Traffic Statistics

    Used to configure traffic statistics for Xray.

    StatsObject

    The StatsObject corresponds to the stats item in the configuration file.

    {\n  "stats": {}\n}\n
    1
    2
    3

    Currently, no parameters are required for traffic statistics, and internal statistics will be enabled as long as the StatsObject item exists.

    ',6),d=r("After statistics are enabled, you only need to enable the corresponding items in the "),f=r("Policy"),g=r(" to collect the corresponding data."),u=o('

    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);p.render=function(o,r){const p=t("RouterLink");return e(),i(c,null,[l,a("p",null,[d,s(p,{to:"/en/config/policy.html"},{default:n((()=>[f])),_:1}),g]),u],64)};export default p; +import{r as t,o as e,c as i,a,b as s,w as n,F as c,d as o,e as r}from"./app.48111a85.js";const p={},l=o('

    Traffic Statistics

    Used to configure traffic statistics for Xray.

    StatsObject

    The StatsObject corresponds to the stats item in the configuration file.

    {\n  "stats": {}\n}\n
    1
    2
    3

    Currently, no parameters are required for traffic statistics, and internal statistics will be enabled as long as the StatsObject item exists.

    ',6),d=r("After statistics are enabled, you only need to enable the corresponding items in the "),f=r("Policy"),g=r(" to collect the corresponding data."),u=o('

    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);p.render=function(o,r){const p=t("RouterLink");return e(),i(c,null,[l,a("p",null,[d,s(p,{to:"/en/config/policy.html"},{default:n((()=>[f])),_:1}),g]),u],64)};export default p; diff --git a/assets/styles-237fcbdf.f2a0b31b.js b/assets/styles-237fcbdf.3c95e98b.js similarity index 99% rename from assets/styles-237fcbdf.f2a0b31b.js rename to assets/styles-237fcbdf.3c95e98b.js index 01b024d6f..28899b2a3 100644 --- a/assets/styles-237fcbdf.f2a0b31b.js +++ b/assets/styles-237fcbdf.3c95e98b.js @@ -1 +1 @@ -import{s as e,g as t,a as n,b as s,c as i,v as u,x as r,m as a,j as c,z as o,l,y as h,h as A}from"./mermaid.core.a66200b0.js";var p=function(){var e=function(e,t,n,s){for(n=n||{},s=e.length;s--;n[e[s]]=t);return n},t=[1,34],n=[1,35],s=[1,36],i=[1,37],u=[1,9],r=[1,8],a=[1,19],c=[1,20],o=[1,21],l=[1,40],h=[1,41],A=[1,27],p=[1,25],d=[1,26],E=[1,32],y=[1,33],C=[1,28],m=[1,29],k=[1,30],b=[1,31],g=[1,45],F=[1,42],f=[1,43],_=[1,44],D=[1,46],B=[1,24],T=[1,16,24],S=[1,60],N=[1,61],v=[1,62],$=[1,63],L=[1,64],I=[1,65],O=[1,66],x=[1,16,24,52],R=[1,77],P=[1,16,24,27,28,36,50,52,55,68,69,70,71,72,73,74,79,81],w=[1,16,24,27,28,34,36,50,52,55,59,68,69,70,71,72,73,74,79,81,94,96,97,98,99],G=[1,86],M=[28,94,96,97,98,99],U=[28,73,74,94,96,97,98,99],K=[28,68,69,70,71,72,94,96,97,98,99],Y=[1,99],z=[1,16,24,50,52,55],j=[1,16,24,36],Q=[8,9,10,11,19,23,44,46,48,53,57,58,60,61,63,65,75,76,78,82,94,96,97,98,99],X={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,directive:5,statements:6,direction:7,direction_tb:8,direction_bt:9,direction_rl:10,direction_lr:11,graphConfig:12,openDirective:13,typeDirective:14,closeDirective:15,NEWLINE:16,":":17,argDirective:18,open_directive:19,type_directive:20,arg_directive:21,close_directive:22,CLASS_DIAGRAM:23,EOF:24,statement:25,classLabel:26,SQS:27,STR:28,SQE:29,namespaceName:30,alphaNumToken:31,className:32,classLiteralName:33,GENERICTYPE:34,relationStatement:35,LABEL:36,namespaceStatement:37,classStatement:38,methodStatement:39,annotationStatement:40,clickStatement:41,cssClassStatement:42,noteStatement:43,acc_title:44,acc_title_value:45,acc_descr:46,acc_descr_value:47,acc_descr_multiline_value:48,namespaceIdentifier:49,STRUCT_START:50,classStatements:51,STRUCT_STOP:52,NAMESPACE:53,classIdentifier:54,STYLE_SEPARATOR:55,members:56,CLASS:57,ANNOTATION_START:58,ANNOTATION_END:59,MEMBER:60,SEPARATOR:61,relation:62,NOTE_FOR:63,noteText:64,NOTE:65,relationType:66,lineType:67,AGGREGATION:68,EXTENSION:69,COMPOSITION:70,DEPENDENCY:71,LOLLIPOP:72,LINE:73,DOTTED_LINE:74,CALLBACK:75,LINK:76,LINK_TARGET:77,CLICK:78,CALLBACK_NAME:79,CALLBACK_ARGS:80,HREF:81,CSSCLASS:82,commentToken:83,textToken:84,graphCodeTokens:85,textNoTagsToken:86,TAGSTART:87,TAGEND:88,"==":89,"--":90,PCT:91,DEFAULT:92,SPACE:93,MINUS:94,keywords:95,UNICODE_TEXT:96,NUM:97,ALPHA:98,BQUOTE_STR:99,$accept:0,$end:1},terminals_:{2:"error",8:"direction_tb",9:"direction_bt",10:"direction_rl",11:"direction_lr",16:"NEWLINE",17:":",19:"open_directive",20:"type_directive",21:"arg_directive",22:"close_directive",23:"CLASS_DIAGRAM",24:"EOF",27:"SQS",28:"STR",29:"SQE",34:"GENERICTYPE",36:"LABEL",44:"acc_title",45:"acc_title_value",46:"acc_descr",47:"acc_descr_value",48:"acc_descr_multiline_value",50:"STRUCT_START",52:"STRUCT_STOP",53:"NAMESPACE",55:"STYLE_SEPARATOR",57:"CLASS",58:"ANNOTATION_START",59:"ANNOTATION_END",60:"MEMBER",61:"SEPARATOR",63:"NOTE_FOR",65:"NOTE",68:"AGGREGATION",69:"EXTENSION",70:"COMPOSITION",71:"DEPENDENCY",72:"LOLLIPOP",73:"LINE",74:"DOTTED_LINE",75:"CALLBACK",76:"LINK",77:"LINK_TARGET",78:"CLICK",79:"CALLBACK_NAME",80:"CALLBACK_ARGS",81:"HREF",82:"CSSCLASS",85:"graphCodeTokens",87:"TAGSTART",88:"TAGEND",89:"==",90:"--",91:"PCT",92:"DEFAULT",93:"SPACE",94:"MINUS",95:"keywords",96:"UNICODE_TEXT",97:"NUM",98:"ALPHA",99:"BQUOTE_STR"},productions_:[0,[3,1],[3,2],[3,1],[7,1],[7,1],[7,1],[7,1],[4,1],[5,4],[5,6],[13,1],[14,1],[18,1],[15,1],[12,4],[6,1],[6,2],[6,3],[26,3],[30,1],[30,2],[32,1],[32,1],[32,2],[32,2],[32,2],[25,1],[25,2],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,2],[25,2],[25,1],[37,4],[37,5],[49,2],[51,1],[51,2],[51,3],[38,1],[38,3],[38,4],[38,6],[54,2],[54,3],[40,4],[56,1],[56,2],[39,1],[39,2],[39,1],[39,1],[35,3],[35,4],[35,4],[35,5],[43,3],[43,2],[62,3],[62,2],[62,2],[62,1],[66,1],[66,1],[66,1],[66,1],[66,1],[67,1],[67,1],[41,3],[41,4],[41,3],[41,4],[41,4],[41,5],[41,3],[41,4],[41,4],[41,5],[41,3],[41,4],[41,4],[41,5],[42,3],[83,1],[83,1],[84,1],[84,1],[84,1],[84,1],[84,1],[84,1],[84,1],[86,1],[86,1],[86,1],[86,1],[31,1],[31,1],[31,1],[31,1],[33,1],[64,1]],performAction:function(e,t,n,s,i,u,r){var a=u.length-1;switch(i){case 4:s.setDirection("TB");break;case 5:s.setDirection("BT");break;case 6:s.setDirection("RL");break;case 7:s.setDirection("LR");break;case 11:s.parseDirective("%%{","open_directive");break;case 12:s.parseDirective(u[a],"type_directive");break;case 13:u[a]=u[a].trim().replace(/'/g,'"'),s.parseDirective(u[a],"arg_directive");break;case 14:s.parseDirective("}%%","close_directive","class");break;case 19:this.$=u[a-1];break;case 20:case 22:case 23:this.$=u[a];break;case 21:case 24:this.$=u[a-1]+u[a];break;case 25:case 26:this.$=u[a-1]+"~"+u[a]+"~";break;case 27:s.addRelation(u[a]);break;case 28:u[a-1].title=s.cleanupLabel(u[a]),s.addRelation(u[a-1]);break;case 37:this.$=u[a].trim(),s.setAccTitle(this.$);break;case 38:case 39:this.$=u[a].trim(),s.setAccDescription(this.$);break;case 40:s.addClassesToNamespace(u[a-3],u[a-1]);break;case 41:s.addClassesToNamespace(u[a-4],u[a-1]);break;case 42:this.$=u[a],s.addNamespace(u[a]);break;case 43:this.$=[u[a]];break;case 44:this.$=[u[a-1]];break;case 45:u[a].unshift(u[a-2]),this.$=u[a];break;case 47:s.setCssClass(u[a-2],u[a]);break;case 48:s.addMembers(u[a-3],u[a-1]);break;case 49:s.setCssClass(u[a-5],u[a-3]),s.addMembers(u[a-5],u[a-1]);break;case 50:this.$=u[a],s.addClass(u[a]);break;case 51:this.$=u[a-1],s.addClass(u[a-1]),s.setClassLabel(u[a-1],u[a]);break;case 52:s.addAnnotation(u[a],u[a-2]);break;case 53:this.$=[u[a]];break;case 54:u[a].push(u[a-1]),this.$=u[a];break;case 55:break;case 56:s.addMember(u[a-1],s.cleanupLabel(u[a]));break;case 57:case 58:break;case 59:this.$={id1:u[a-2],id2:u[a],relation:u[a-1],relationTitle1:"none",relationTitle2:"none"};break;case 60:this.$={id1:u[a-3],id2:u[a],relation:u[a-1],relationTitle1:u[a-2],relationTitle2:"none"};break;case 61:this.$={id1:u[a-3],id2:u[a],relation:u[a-2],relationTitle1:"none",relationTitle2:u[a-1]};break;case 62:this.$={id1:u[a-4],id2:u[a],relation:u[a-2],relationTitle1:u[a-3],relationTitle2:u[a-1]};break;case 63:s.addNote(u[a],u[a-1]);break;case 64:s.addNote(u[a]);break;case 65:this.$={type1:u[a-2],type2:u[a],lineType:u[a-1]};break;case 66:this.$={type1:"none",type2:u[a],lineType:u[a-1]};break;case 67:this.$={type1:u[a-1],type2:"none",lineType:u[a]};break;case 68:this.$={type1:"none",type2:"none",lineType:u[a]};break;case 69:this.$=s.relationType.AGGREGATION;break;case 70:this.$=s.relationType.EXTENSION;break;case 71:this.$=s.relationType.COMPOSITION;break;case 72:this.$=s.relationType.DEPENDENCY;break;case 73:this.$=s.relationType.LOLLIPOP;break;case 74:this.$=s.lineType.LINE;break;case 75:this.$=s.lineType.DOTTED_LINE;break;case 76:case 82:this.$=u[a-2],s.setClickEvent(u[a-1],u[a]);break;case 77:case 83:this.$=u[a-3],s.setClickEvent(u[a-2],u[a-1]),s.setTooltip(u[a-2],u[a]);break;case 78:case 86:this.$=u[a-2],s.setLink(u[a-1],u[a]);break;case 79:this.$=u[a-3],s.setLink(u[a-2],u[a-1],u[a]);break;case 80:case 88:this.$=u[a-3],s.setLink(u[a-2],u[a-1]),s.setTooltip(u[a-2],u[a]);break;case 81:case 89:this.$=u[a-4],s.setLink(u[a-3],u[a-2],u[a]),s.setTooltip(u[a-3],u[a-1]);break;case 84:this.$=u[a-3],s.setClickEvent(u[a-2],u[a-1],u[a]);break;case 85:this.$=u[a-4],s.setClickEvent(u[a-3],u[a-2],u[a-1]),s.setTooltip(u[a-3],u[a]);break;case 87:this.$=u[a-3],s.setLink(u[a-2],u[a-1],u[a]);break;case 90:s.setCssClass(u[a-1],u[a])}},table:[{3:1,4:2,5:3,6:4,7:18,8:t,9:n,10:s,11:i,12:5,13:6,19:u,23:r,25:7,31:38,32:22,33:39,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,44:a,46:c,48:o,49:23,53:l,54:24,57:h,58:A,60:p,61:d,63:E,65:y,75:C,76:m,78:k,82:b,94:g,96:F,97:f,98:_,99:D},{1:[3]},{1:[2,1]},{3:47,4:2,5:3,6:4,7:18,8:t,9:n,10:s,11:i,12:5,13:6,19:u,23:r,25:7,31:38,32:22,33:39,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,44:a,46:c,48:o,49:23,53:l,54:24,57:h,58:A,60:p,61:d,63:E,65:y,75:C,76:m,78:k,82:b,94:g,96:F,97:f,98:_,99:D},{1:[2,3]},{1:[2,8]},{14:48,20:[1,49]},e(B,[2,16],{16:[1,50]}),{16:[1,51]},{20:[2,11]},e(T,[2,27],{36:[1,52]}),e(T,[2,29]),e(T,[2,30]),e(T,[2,31]),e(T,[2,32]),e(T,[2,33]),e(T,[2,34]),e(T,[2,35]),e(T,[2,36]),{45:[1,53]},{47:[1,54]},e(T,[2,39]),e(T,[2,55],{62:55,66:58,67:59,28:[1,56],36:[1,57],68:S,69:N,70:v,71:$,72:L,73:I,74:O}),{50:[1,67]},e(x,[2,46],{50:[1,69],55:[1,68]}),e(T,[2,57]),e(T,[2,58]),{31:70,94:g,96:F,97:f,98:_},{31:38,32:71,33:39,94:g,96:F,97:f,98:_,99:D},{31:38,32:72,33:39,94:g,96:F,97:f,98:_,99:D},{31:38,32:73,33:39,94:g,96:F,97:f,98:_,99:D},{28:[1,74]},{31:38,32:75,33:39,94:g,96:F,97:f,98:_,99:D},{28:R,64:76},e(T,[2,4]),e(T,[2,5]),e(T,[2,6]),e(T,[2,7]),e(P,[2,22],{31:38,33:39,32:78,34:[1,79],94:g,96:F,97:f,98:_,99:D}),e(P,[2,23],{34:[1,80]}),{30:81,31:82,94:g,96:F,97:f,98:_},{31:38,32:83,33:39,94:g,96:F,97:f,98:_,99:D},e(w,[2,104]),e(w,[2,105]),e(w,[2,106]),e(w,[2,107]),e([1,16,24,27,28,34,36,50,52,55,68,69,70,71,72,73,74,79,81],[2,108]),{1:[2,2]},{15:84,17:[1,85],22:G},e([17,22],[2,12]),e(B,[2,17],{25:7,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,7:18,32:22,49:23,54:24,31:38,33:39,6:87,8:t,9:n,10:s,11:i,44:a,46:c,48:o,53:l,57:h,58:A,60:p,61:d,63:E,65:y,75:C,76:m,78:k,82:b,94:g,96:F,97:f,98:_,99:D}),{6:88,7:18,8:t,9:n,10:s,11:i,25:7,31:38,32:22,33:39,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,44:a,46:c,48:o,49:23,53:l,54:24,57:h,58:A,60:p,61:d,63:E,65:y,75:C,76:m,78:k,82:b,94:g,96:F,97:f,98:_,99:D},e(T,[2,28]),e(T,[2,37]),e(T,[2,38]),{28:[1,90],31:38,32:89,33:39,94:g,96:F,97:f,98:_,99:D},{62:91,66:58,67:59,68:S,69:N,70:v,71:$,72:L,73:I,74:O},e(T,[2,56]),{67:92,73:I,74:O},e(M,[2,68],{66:93,68:S,69:N,70:v,71:$,72:L}),e(U,[2,69]),e(U,[2,70]),e(U,[2,71]),e(U,[2,72]),e(U,[2,73]),e(K,[2,74]),e(K,[2,75]),{16:[1,95],38:96,51:94,54:24,57:h},{31:97,94:g,96:F,97:f,98:_},{56:98,60:Y},{59:[1,100]},{28:[1,101]},{28:[1,102]},{79:[1,103],81:[1,104]},{31:105,94:g,96:F,97:f,98:_},{28:R,64:106},e(T,[2,64]),e(T,[2,109]),e(P,[2,24]),e(P,[2,25]),e(P,[2,26]),{50:[2,42]},{30:107,31:82,50:[2,20],94:g,96:F,97:f,98:_},e(z,[2,50],{26:108,27:[1,109]}),{16:[1,110]},{18:111,21:[1,112]},{16:[2,14]},e(B,[2,18]),{24:[1,113]},e(j,[2,59]),{31:38,32:114,33:39,94:g,96:F,97:f,98:_,99:D},{28:[1,116],31:38,32:115,33:39,94:g,96:F,97:f,98:_,99:D},e(M,[2,67],{66:117,68:S,69:N,70:v,71:$,72:L}),e(M,[2,66]),{52:[1,118]},{38:96,51:119,54:24,57:h},{16:[1,120],52:[2,43]},e(x,[2,47],{50:[1,121]}),{52:[1,122]},{52:[2,53],56:123,60:Y},{31:38,32:124,33:39,94:g,96:F,97:f,98:_,99:D},e(T,[2,76],{28:[1,125]}),e(T,[2,78],{28:[1,127],77:[1,126]}),e(T,[2,82],{28:[1,128],80:[1,129]}),e(T,[2,86],{28:[1,131],77:[1,130]}),e(T,[2,90]),e(T,[2,63]),{50:[2,21]},e(z,[2,51]),{28:[1,132]},e(Q,[2,9]),{15:133,22:G},{22:[2,13]},{1:[2,15]},e(j,[2,61]),e(j,[2,60]),{31:38,32:134,33:39,94:g,96:F,97:f,98:_,99:D},e(M,[2,65]),e(T,[2,40]),{52:[1,135]},{38:96,51:136,52:[2,44],54:24,57:h},{56:137,60:Y},e(x,[2,48]),{52:[2,54]},e(T,[2,52]),e(T,[2,77]),e(T,[2,79]),e(T,[2,80],{77:[1,138]}),e(T,[2,83]),e(T,[2,84],{28:[1,139]}),e(T,[2,87]),e(T,[2,88],{77:[1,140]}),{29:[1,141]},{16:[1,142]},e(j,[2,62]),e(T,[2,41]),{52:[2,45]},{52:[1,143]},e(T,[2,81]),e(T,[2,85]),e(T,[2,89]),e(z,[2,19]),e(Q,[2,10]),e(x,[2,49])],defaultActions:{2:[2,1],4:[2,3],5:[2,8],9:[2,11],47:[2,2],81:[2,42],86:[2,14],107:[2,21],112:[2,13],113:[2,15],123:[2,54],136:[2,45]},parseError:function(e,t){if(!t.recoverable){var n=new Error(e);throw n.hash=t,n}this.trace(e)},parse:function(e){var t=this,n=[0],s=[],i=[null],u=[],r=this.table,a="",c=0,o=0,l=2,h=1,A=u.slice.call(arguments,1),p=Object.create(this.lexer),d={yy:{}};for(var E in this.yy)Object.prototype.hasOwnProperty.call(this.yy,E)&&(d.yy[E]=this.yy[E]);p.setInput(e,d.yy),d.yy.lexer=p,d.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;u.push(y);var C=p.options&&p.options.ranges;function m(){var e;return"number"!=typeof(e=s.pop()||p.lex()||h)&&(e instanceof Array&&(e=(s=e).pop()),e=t.symbols_[e]||e),e}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var k,b,g,F,f,_,D,B,T={};;){if(b=n[n.length-1],this.defaultActions[b]?g=this.defaultActions[b]:(null==k&&(k=m()),g=r[b]&&r[b][k]),void 0===g||!g.length||!g[0]){var S="";for(f in B=[],r[b])this.terminals_[f]&&f>l&&B.push("'"+this.terminals_[f]+"'");S=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+B.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(c+1)+": Unexpected "+(k==h?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(S,{text:p.match,token:this.terminals_[k]||k,line:p.yylineno,loc:y,expected:B})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+k);switch(g[0]){case 1:n.push(k),i.push(p.yytext),u.push(p.yylloc),n.push(g[1]),k=null,o=p.yyleng,a=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(_=this.productions_[g[1]][1],T.$=i[i.length-_],T._$={first_line:u[u.length-(_||1)].first_line,last_line:u[u.length-1].last_line,first_column:u[u.length-(_||1)].first_column,last_column:u[u.length-1].last_column},C&&(T._$.range=[u[u.length-(_||1)].range[0],u[u.length-1].range[1]]),void 0!==(F=this.performAction.apply(T,[a,o,c,d.yy,g[1],i,u].concat(A))))return F;_&&(n=n.slice(0,-1*_*2),i=i.slice(0,-1*_),u=u.slice(0,-1*_)),n.push(this.productions_[g[1]][0]),i.push(T.$),u.push(T._$),D=r[n[n.length-2]][n[n.length-1]],n.push(D);break;case 3:return!0}}return!0}},W={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,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 e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,n=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;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 i=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-t},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var n,s,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(s=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],n=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var u in i)this[u]=i[u];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,n,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),u=0;ut[0].length)){if(t=n,s=u,this.options.backtrack_lexer){if(!1!==(e=this.test_match(n,i[u])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,i[s]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(e,t,n,s){switch(n){case 0:return this.begin("open_directive"),19;case 1:return 8;case 2:return 9;case 3:return 10;case 4:return 11;case 5:return this.begin("type_directive"),20;case 6:return this.popState(),this.begin("arg_directive"),17;case 7:return this.popState(),this.popState(),22;case 8:return 21;case 9:case 10:break;case 11:return this.begin("acc_title"),44;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),46;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:return 16;case 19:break;case 20:case 21:return 23;case 22:return"EDGE_STATE";case 23:return this.begin("namespace"),53;case 24:return this.popState(),16;case 25:break;case 26:return this.begin("namespace-body"),50;case 27:return this.popState(),52;case 28:return"EOF_IN_STRUCT";case 29:return 16;case 30:break;case 31:return"EDGE_STATE";case 32:return this.begin("class"),57;case 33:return this.popState(),16;case 34:break;case 35:return this.popState(),this.popState(),52;case 36:return this.begin("class-body"),50;case 37:return this.popState(),52;case 38:return"EOF_IN_STRUCT";case 39:return"EDGE_STATE";case 40:return"OPEN_IN_STRUCT";case 41:break;case 42:return"MEMBER";case 43:return 82;case 44:return 75;case 45:return 76;case 46:return 78;case 47:return 63;case 48:return 65;case 49:return 58;case 50:return 59;case 51:this.begin("href");break;case 52:this.popState();break;case 53:return 81;case 54:this.begin("callback_name");break;case 55:this.popState();break;case 56:this.popState(),this.begin("callback_args");break;case 57:return 79;case 58:this.popState();break;case 59:return 80;case 60:this.popState();break;case 61:return"GENERICTYPE";case 62:this.begin("generic");break;case 63:this.popState();break;case 64:return"STR";case 65:this.begin("string");break;case 66:this.popState();break;case 67:return"BQUOTE_STR";case 68:this.begin("bqstring");break;case 69:case 70:case 71:case 72:return 77;case 73:case 74:return 69;case 75:case 76:return 71;case 77:return 70;case 78:return 68;case 79:return 72;case 80:return 73;case 81:return 74;case 82:return 36;case 83:return 55;case 84:return 94;case 85:return"DOT";case 86:return"PLUS";case 87:return 91;case 88:case 89:return"EQUALS";case 90:return 98;case 91:return 27;case 92:return 29;case 93:return"PUNCTUATION";case 94:return 97;case 95:return 96;case 96:return 93;case 97:return 24}},rules:[/^(?:%%\{)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href[\s]+["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:[~])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[27,28,29,30,31,32,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},namespace:{rules:[23,24,25,26,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},"class-body":{rules:[37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},class:{rules:[33,34,35,36,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},acc_descr_multiline:{rules:[16,17,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},acc_descr:{rules:[14,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},acc_title:{rules:[12,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},arg_directive:{rules:[7,8,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},type_directive:{rules:[6,7,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},open_directive:{rules:[5,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},callback_args:{rules:[43,44,45,46,47,48,49,50,51,54,58,59,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},callback_name:{rules:[43,44,45,46,47,48,49,50,51,54,55,56,57,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},href:{rules:[43,44,45,46,47,48,49,50,51,52,53,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},struct:{rules:[43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},generic:{rules:[43,44,45,46,47,48,49,50,51,54,60,61,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},bqstring:{rules:[43,44,45,46,47,48,49,50,51,54,62,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},string:{rules:[43,44,45,46,47,48,49,50,51,54,62,63,64,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,9,10,11,13,15,18,19,20,21,22,23,32,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!0}}};function H(){this.yy={}}return X.lexer=W,H.prototype=X,X.Parser=H,new H}();p.parser=p;const d=p;let E=[],y={},C=[],m=0,k={},b=0,g=[];const F=e=>c.sanitizeText(e,i()),f=function(e){let t="",n=e;if(e.indexOf("~")>0){const s=e.split("~");n=F(s[0]),t=F(s[1])}return{className:n,type:t}},_=function(e){const t=f(e);void 0===y[t.className]&&(y[t.className]={id:t.className,type:t.type,label:t.className,cssClasses:[],methods:[],members:[],annotations:[],domId:"classId-"+t.className+"-"+m},m++)},D=function(e){if(e in y)return y[e].domId;throw new Error("Class not found: "+e)},B=function(e,t){const n=f(e).className,s=y[n];if("string"==typeof t){const e=t.trim();e.startsWith("<<")&&e.endsWith(">>")?s.annotations.push(F(e.substring(2,e.length-2))):e.indexOf(")")>0?s.methods.push(F(e)):e&&s.members.push(F(e))}},T=function(e,t){e.split(",").forEach((function(e){let n=e;e[0].match(/\d/)&&(n="classId-"+n),void 0!==y[n]&&y[n].cssClasses.push(t)}))},S=function(e,t,n){if("loose"!==i().securityLevel)return;if(void 0===t)return;const s=e;if(void 0!==y[s]){const e=D(s);let i=[];if("string"==typeof n){i=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let e=0;e")),e.classed("hover",!0)})).on("mouseout",(function(){t.transition().duration(500).style("opacity",0);A(this).classed("hover",!1)}))};g.push(N);let v="TB";const $={parseDirective:function(e,t,n){a.parseDirective(this,e,t,n)},setAccTitle:e,getAccTitle:t,getAccDescription:n,setAccDescription:s,getConfig:()=>i().class,addClass:_,bindFunctions:function(e){g.forEach((function(t){t(e)}))},clear:function(){E=[],y={},C=[],g=[],g.push(N),k={},b=0,o()},getClass:function(e){return y[e]},getClasses:function(){return y},getNotes:function(){return C},addAnnotation:function(e,t){const n=f(e).className;y[n].annotations.push(t)},addNote:function(e,t){const n={id:`note${C.length}`,class:t,text:e};C.push(n)},getRelations:function(){return E},addRelation:function(e){l.debug("Adding relation: "+JSON.stringify(e)),_(e.id1),_(e.id2),e.id1=f(e.id1).className,e.id2=f(e.id2).className,e.relationTitle1=c.sanitizeText(e.relationTitle1.trim(),i()),e.relationTitle2=c.sanitizeText(e.relationTitle2.trim(),i()),E.push(e)},getDirection:()=>v,setDirection:e=>{v=e},addMember:B,addMembers:function(e,t){Array.isArray(t)&&(t.reverse(),t.forEach((t=>B(e,t))))},cleanupLabel:function(e){return e.startsWith(":")&&(e=e.substring(1)),F(e.trim())},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4},setClickEvent:function(e,t,n){e.split(",").forEach((function(e){S(e,t,n),y[e].haveCallback=!0})),T(e,"clickable")},setCssClass:T,setLink:function(e,t,n){const s=i();e.split(",").forEach((function(e){let i=e;e[0].match(/\d/)&&(i="classId-"+i),void 0!==y[i]&&(y[i].link=h.formatUrl(t,s),"sandbox"===s.securityLevel?y[i].linkTarget="_top":y[i].linkTarget="string"==typeof n?F(n):"_blank")})),T(e,"clickable")},getTooltip:function(e,t){return t?k[t].classes[e].tooltip:y[e].tooltip},setTooltip:function(e,t){e.split(",").forEach((function(e){void 0!==t&&(y[e].tooltip=F(t))}))},lookUpDomId:D,setDiagramTitle:u,getDiagramTitle:r,setClassLabel:function(e,t){t&&(t=F(t));const{className:n}=f(e);y[n].label=t},addNamespace:function(e){void 0===k[e]&&(k[e]={id:e,classes:{},children:{},domId:"classId-"+e+"-"+b},b++)},addClassesToNamespace:function(e,t){void 0!==k[e]&&t.map((t=>{k[e].classes[t]=y[t],delete y[t],m--}))},getNamespace:function(e){return k[e]},getNamespaces:function(){return k}},L=e=>`g.classGroup text {\n fill: ${e.nodeBorder};\n fill: ${e.classText};\n stroke: none;\n font-family: ${e.fontFamily};\n font-size: 10px;\n\n .title {\n font-weight: bolder;\n }\n\n}\n\n.nodeLabel, .edgeLabel {\n color: ${e.classText};\n}\n.edgeLabel .label rect {\n fill: ${e.mainBkg};\n}\n.label text {\n fill: ${e.classText};\n}\n.edgeLabel .label span {\n background: ${e.mainBkg};\n}\n\n.classTitle {\n font-weight: bolder;\n}\n.node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n\n\n.divider {\n stroke: ${e.nodeBorder};\n stroke-width: 1;\n}\n\ng.clickable {\n cursor: pointer;\n}\n\ng.classGroup rect {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n}\n\ng.classGroup line {\n stroke: ${e.nodeBorder};\n stroke-width: 1;\n}\n\n.classLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${e.mainBkg};\n opacity: 0.5;\n}\n\n.classLabel .label {\n fill: ${e.nodeBorder};\n font-size: 10px;\n}\n\n.relation {\n stroke: ${e.lineColor};\n stroke-width: 1;\n fill: none;\n}\n\n.dashed-line{\n stroke-dasharray: 3;\n}\n\n.dotted-line{\n stroke-dasharray: 1 2;\n}\n\n#compositionStart, .composition {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#compositionEnd, .composition {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionStart, .extension {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionEnd, .extension {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationStart, .aggregation {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationEnd, .aggregation {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopStart, .lollipop {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopEnd, .lollipop {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n.edgeTerminals {\n font-size: 11px;\n}\n\n.classTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n}\n`;export{$ as d,d as p,L as s}; +import{s as e,g as t,a as n,b as s,c as i,v as u,x as r,m as a,j as c,z as o,l,y as h,h as A}from"./mermaid.core.3a590193.js";var p=function(){var e=function(e,t,n,s){for(n=n||{},s=e.length;s--;n[e[s]]=t);return n},t=[1,34],n=[1,35],s=[1,36],i=[1,37],u=[1,9],r=[1,8],a=[1,19],c=[1,20],o=[1,21],l=[1,40],h=[1,41],A=[1,27],p=[1,25],d=[1,26],E=[1,32],y=[1,33],C=[1,28],m=[1,29],k=[1,30],b=[1,31],g=[1,45],F=[1,42],f=[1,43],_=[1,44],D=[1,46],B=[1,24],T=[1,16,24],S=[1,60],N=[1,61],v=[1,62],$=[1,63],L=[1,64],I=[1,65],O=[1,66],x=[1,16,24,52],R=[1,77],P=[1,16,24,27,28,36,50,52,55,68,69,70,71,72,73,74,79,81],w=[1,16,24,27,28,34,36,50,52,55,59,68,69,70,71,72,73,74,79,81,94,96,97,98,99],G=[1,86],M=[28,94,96,97,98,99],U=[28,73,74,94,96,97,98,99],K=[28,68,69,70,71,72,94,96,97,98,99],Y=[1,99],z=[1,16,24,50,52,55],j=[1,16,24,36],Q=[8,9,10,11,19,23,44,46,48,53,57,58,60,61,63,65,75,76,78,82,94,96,97,98,99],X={trace:function(){},yy:{},symbols_:{error:2,start:3,mermaidDoc:4,directive:5,statements:6,direction:7,direction_tb:8,direction_bt:9,direction_rl:10,direction_lr:11,graphConfig:12,openDirective:13,typeDirective:14,closeDirective:15,NEWLINE:16,":":17,argDirective:18,open_directive:19,type_directive:20,arg_directive:21,close_directive:22,CLASS_DIAGRAM:23,EOF:24,statement:25,classLabel:26,SQS:27,STR:28,SQE:29,namespaceName:30,alphaNumToken:31,className:32,classLiteralName:33,GENERICTYPE:34,relationStatement:35,LABEL:36,namespaceStatement:37,classStatement:38,methodStatement:39,annotationStatement:40,clickStatement:41,cssClassStatement:42,noteStatement:43,acc_title:44,acc_title_value:45,acc_descr:46,acc_descr_value:47,acc_descr_multiline_value:48,namespaceIdentifier:49,STRUCT_START:50,classStatements:51,STRUCT_STOP:52,NAMESPACE:53,classIdentifier:54,STYLE_SEPARATOR:55,members:56,CLASS:57,ANNOTATION_START:58,ANNOTATION_END:59,MEMBER:60,SEPARATOR:61,relation:62,NOTE_FOR:63,noteText:64,NOTE:65,relationType:66,lineType:67,AGGREGATION:68,EXTENSION:69,COMPOSITION:70,DEPENDENCY:71,LOLLIPOP:72,LINE:73,DOTTED_LINE:74,CALLBACK:75,LINK:76,LINK_TARGET:77,CLICK:78,CALLBACK_NAME:79,CALLBACK_ARGS:80,HREF:81,CSSCLASS:82,commentToken:83,textToken:84,graphCodeTokens:85,textNoTagsToken:86,TAGSTART:87,TAGEND:88,"==":89,"--":90,PCT:91,DEFAULT:92,SPACE:93,MINUS:94,keywords:95,UNICODE_TEXT:96,NUM:97,ALPHA:98,BQUOTE_STR:99,$accept:0,$end:1},terminals_:{2:"error",8:"direction_tb",9:"direction_bt",10:"direction_rl",11:"direction_lr",16:"NEWLINE",17:":",19:"open_directive",20:"type_directive",21:"arg_directive",22:"close_directive",23:"CLASS_DIAGRAM",24:"EOF",27:"SQS",28:"STR",29:"SQE",34:"GENERICTYPE",36:"LABEL",44:"acc_title",45:"acc_title_value",46:"acc_descr",47:"acc_descr_value",48:"acc_descr_multiline_value",50:"STRUCT_START",52:"STRUCT_STOP",53:"NAMESPACE",55:"STYLE_SEPARATOR",57:"CLASS",58:"ANNOTATION_START",59:"ANNOTATION_END",60:"MEMBER",61:"SEPARATOR",63:"NOTE_FOR",65:"NOTE",68:"AGGREGATION",69:"EXTENSION",70:"COMPOSITION",71:"DEPENDENCY",72:"LOLLIPOP",73:"LINE",74:"DOTTED_LINE",75:"CALLBACK",76:"LINK",77:"LINK_TARGET",78:"CLICK",79:"CALLBACK_NAME",80:"CALLBACK_ARGS",81:"HREF",82:"CSSCLASS",85:"graphCodeTokens",87:"TAGSTART",88:"TAGEND",89:"==",90:"--",91:"PCT",92:"DEFAULT",93:"SPACE",94:"MINUS",95:"keywords",96:"UNICODE_TEXT",97:"NUM",98:"ALPHA",99:"BQUOTE_STR"},productions_:[0,[3,1],[3,2],[3,1],[7,1],[7,1],[7,1],[7,1],[4,1],[5,4],[5,6],[13,1],[14,1],[18,1],[15,1],[12,4],[6,1],[6,2],[6,3],[26,3],[30,1],[30,2],[32,1],[32,1],[32,2],[32,2],[32,2],[25,1],[25,2],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,2],[25,2],[25,1],[37,4],[37,5],[49,2],[51,1],[51,2],[51,3],[38,1],[38,3],[38,4],[38,6],[54,2],[54,3],[40,4],[56,1],[56,2],[39,1],[39,2],[39,1],[39,1],[35,3],[35,4],[35,4],[35,5],[43,3],[43,2],[62,3],[62,2],[62,2],[62,1],[66,1],[66,1],[66,1],[66,1],[66,1],[67,1],[67,1],[41,3],[41,4],[41,3],[41,4],[41,4],[41,5],[41,3],[41,4],[41,4],[41,5],[41,3],[41,4],[41,4],[41,5],[42,3],[83,1],[83,1],[84,1],[84,1],[84,1],[84,1],[84,1],[84,1],[84,1],[86,1],[86,1],[86,1],[86,1],[31,1],[31,1],[31,1],[31,1],[33,1],[64,1]],performAction:function(e,t,n,s,i,u,r){var a=u.length-1;switch(i){case 4:s.setDirection("TB");break;case 5:s.setDirection("BT");break;case 6:s.setDirection("RL");break;case 7:s.setDirection("LR");break;case 11:s.parseDirective("%%{","open_directive");break;case 12:s.parseDirective(u[a],"type_directive");break;case 13:u[a]=u[a].trim().replace(/'/g,'"'),s.parseDirective(u[a],"arg_directive");break;case 14:s.parseDirective("}%%","close_directive","class");break;case 19:this.$=u[a-1];break;case 20:case 22:case 23:this.$=u[a];break;case 21:case 24:this.$=u[a-1]+u[a];break;case 25:case 26:this.$=u[a-1]+"~"+u[a]+"~";break;case 27:s.addRelation(u[a]);break;case 28:u[a-1].title=s.cleanupLabel(u[a]),s.addRelation(u[a-1]);break;case 37:this.$=u[a].trim(),s.setAccTitle(this.$);break;case 38:case 39:this.$=u[a].trim(),s.setAccDescription(this.$);break;case 40:s.addClassesToNamespace(u[a-3],u[a-1]);break;case 41:s.addClassesToNamespace(u[a-4],u[a-1]);break;case 42:this.$=u[a],s.addNamespace(u[a]);break;case 43:this.$=[u[a]];break;case 44:this.$=[u[a-1]];break;case 45:u[a].unshift(u[a-2]),this.$=u[a];break;case 47:s.setCssClass(u[a-2],u[a]);break;case 48:s.addMembers(u[a-3],u[a-1]);break;case 49:s.setCssClass(u[a-5],u[a-3]),s.addMembers(u[a-5],u[a-1]);break;case 50:this.$=u[a],s.addClass(u[a]);break;case 51:this.$=u[a-1],s.addClass(u[a-1]),s.setClassLabel(u[a-1],u[a]);break;case 52:s.addAnnotation(u[a],u[a-2]);break;case 53:this.$=[u[a]];break;case 54:u[a].push(u[a-1]),this.$=u[a];break;case 55:break;case 56:s.addMember(u[a-1],s.cleanupLabel(u[a]));break;case 57:case 58:break;case 59:this.$={id1:u[a-2],id2:u[a],relation:u[a-1],relationTitle1:"none",relationTitle2:"none"};break;case 60:this.$={id1:u[a-3],id2:u[a],relation:u[a-1],relationTitle1:u[a-2],relationTitle2:"none"};break;case 61:this.$={id1:u[a-3],id2:u[a],relation:u[a-2],relationTitle1:"none",relationTitle2:u[a-1]};break;case 62:this.$={id1:u[a-4],id2:u[a],relation:u[a-2],relationTitle1:u[a-3],relationTitle2:u[a-1]};break;case 63:s.addNote(u[a],u[a-1]);break;case 64:s.addNote(u[a]);break;case 65:this.$={type1:u[a-2],type2:u[a],lineType:u[a-1]};break;case 66:this.$={type1:"none",type2:u[a],lineType:u[a-1]};break;case 67:this.$={type1:u[a-1],type2:"none",lineType:u[a]};break;case 68:this.$={type1:"none",type2:"none",lineType:u[a]};break;case 69:this.$=s.relationType.AGGREGATION;break;case 70:this.$=s.relationType.EXTENSION;break;case 71:this.$=s.relationType.COMPOSITION;break;case 72:this.$=s.relationType.DEPENDENCY;break;case 73:this.$=s.relationType.LOLLIPOP;break;case 74:this.$=s.lineType.LINE;break;case 75:this.$=s.lineType.DOTTED_LINE;break;case 76:case 82:this.$=u[a-2],s.setClickEvent(u[a-1],u[a]);break;case 77:case 83:this.$=u[a-3],s.setClickEvent(u[a-2],u[a-1]),s.setTooltip(u[a-2],u[a]);break;case 78:case 86:this.$=u[a-2],s.setLink(u[a-1],u[a]);break;case 79:this.$=u[a-3],s.setLink(u[a-2],u[a-1],u[a]);break;case 80:case 88:this.$=u[a-3],s.setLink(u[a-2],u[a-1]),s.setTooltip(u[a-2],u[a]);break;case 81:case 89:this.$=u[a-4],s.setLink(u[a-3],u[a-2],u[a]),s.setTooltip(u[a-3],u[a-1]);break;case 84:this.$=u[a-3],s.setClickEvent(u[a-2],u[a-1],u[a]);break;case 85:this.$=u[a-4],s.setClickEvent(u[a-3],u[a-2],u[a-1]),s.setTooltip(u[a-3],u[a]);break;case 87:this.$=u[a-3],s.setLink(u[a-2],u[a-1],u[a]);break;case 90:s.setCssClass(u[a-1],u[a])}},table:[{3:1,4:2,5:3,6:4,7:18,8:t,9:n,10:s,11:i,12:5,13:6,19:u,23:r,25:7,31:38,32:22,33:39,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,44:a,46:c,48:o,49:23,53:l,54:24,57:h,58:A,60:p,61:d,63:E,65:y,75:C,76:m,78:k,82:b,94:g,96:F,97:f,98:_,99:D},{1:[3]},{1:[2,1]},{3:47,4:2,5:3,6:4,7:18,8:t,9:n,10:s,11:i,12:5,13:6,19:u,23:r,25:7,31:38,32:22,33:39,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,44:a,46:c,48:o,49:23,53:l,54:24,57:h,58:A,60:p,61:d,63:E,65:y,75:C,76:m,78:k,82:b,94:g,96:F,97:f,98:_,99:D},{1:[2,3]},{1:[2,8]},{14:48,20:[1,49]},e(B,[2,16],{16:[1,50]}),{16:[1,51]},{20:[2,11]},e(T,[2,27],{36:[1,52]}),e(T,[2,29]),e(T,[2,30]),e(T,[2,31]),e(T,[2,32]),e(T,[2,33]),e(T,[2,34]),e(T,[2,35]),e(T,[2,36]),{45:[1,53]},{47:[1,54]},e(T,[2,39]),e(T,[2,55],{62:55,66:58,67:59,28:[1,56],36:[1,57],68:S,69:N,70:v,71:$,72:L,73:I,74:O}),{50:[1,67]},e(x,[2,46],{50:[1,69],55:[1,68]}),e(T,[2,57]),e(T,[2,58]),{31:70,94:g,96:F,97:f,98:_},{31:38,32:71,33:39,94:g,96:F,97:f,98:_,99:D},{31:38,32:72,33:39,94:g,96:F,97:f,98:_,99:D},{31:38,32:73,33:39,94:g,96:F,97:f,98:_,99:D},{28:[1,74]},{31:38,32:75,33:39,94:g,96:F,97:f,98:_,99:D},{28:R,64:76},e(T,[2,4]),e(T,[2,5]),e(T,[2,6]),e(T,[2,7]),e(P,[2,22],{31:38,33:39,32:78,34:[1,79],94:g,96:F,97:f,98:_,99:D}),e(P,[2,23],{34:[1,80]}),{30:81,31:82,94:g,96:F,97:f,98:_},{31:38,32:83,33:39,94:g,96:F,97:f,98:_,99:D},e(w,[2,104]),e(w,[2,105]),e(w,[2,106]),e(w,[2,107]),e([1,16,24,27,28,34,36,50,52,55,68,69,70,71,72,73,74,79,81],[2,108]),{1:[2,2]},{15:84,17:[1,85],22:G},e([17,22],[2,12]),e(B,[2,17],{25:7,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,7:18,32:22,49:23,54:24,31:38,33:39,6:87,8:t,9:n,10:s,11:i,44:a,46:c,48:o,53:l,57:h,58:A,60:p,61:d,63:E,65:y,75:C,76:m,78:k,82:b,94:g,96:F,97:f,98:_,99:D}),{6:88,7:18,8:t,9:n,10:s,11:i,25:7,31:38,32:22,33:39,35:10,37:11,38:12,39:13,40:14,41:15,42:16,43:17,44:a,46:c,48:o,49:23,53:l,54:24,57:h,58:A,60:p,61:d,63:E,65:y,75:C,76:m,78:k,82:b,94:g,96:F,97:f,98:_,99:D},e(T,[2,28]),e(T,[2,37]),e(T,[2,38]),{28:[1,90],31:38,32:89,33:39,94:g,96:F,97:f,98:_,99:D},{62:91,66:58,67:59,68:S,69:N,70:v,71:$,72:L,73:I,74:O},e(T,[2,56]),{67:92,73:I,74:O},e(M,[2,68],{66:93,68:S,69:N,70:v,71:$,72:L}),e(U,[2,69]),e(U,[2,70]),e(U,[2,71]),e(U,[2,72]),e(U,[2,73]),e(K,[2,74]),e(K,[2,75]),{16:[1,95],38:96,51:94,54:24,57:h},{31:97,94:g,96:F,97:f,98:_},{56:98,60:Y},{59:[1,100]},{28:[1,101]},{28:[1,102]},{79:[1,103],81:[1,104]},{31:105,94:g,96:F,97:f,98:_},{28:R,64:106},e(T,[2,64]),e(T,[2,109]),e(P,[2,24]),e(P,[2,25]),e(P,[2,26]),{50:[2,42]},{30:107,31:82,50:[2,20],94:g,96:F,97:f,98:_},e(z,[2,50],{26:108,27:[1,109]}),{16:[1,110]},{18:111,21:[1,112]},{16:[2,14]},e(B,[2,18]),{24:[1,113]},e(j,[2,59]),{31:38,32:114,33:39,94:g,96:F,97:f,98:_,99:D},{28:[1,116],31:38,32:115,33:39,94:g,96:F,97:f,98:_,99:D},e(M,[2,67],{66:117,68:S,69:N,70:v,71:$,72:L}),e(M,[2,66]),{52:[1,118]},{38:96,51:119,54:24,57:h},{16:[1,120],52:[2,43]},e(x,[2,47],{50:[1,121]}),{52:[1,122]},{52:[2,53],56:123,60:Y},{31:38,32:124,33:39,94:g,96:F,97:f,98:_,99:D},e(T,[2,76],{28:[1,125]}),e(T,[2,78],{28:[1,127],77:[1,126]}),e(T,[2,82],{28:[1,128],80:[1,129]}),e(T,[2,86],{28:[1,131],77:[1,130]}),e(T,[2,90]),e(T,[2,63]),{50:[2,21]},e(z,[2,51]),{28:[1,132]},e(Q,[2,9]),{15:133,22:G},{22:[2,13]},{1:[2,15]},e(j,[2,61]),e(j,[2,60]),{31:38,32:134,33:39,94:g,96:F,97:f,98:_,99:D},e(M,[2,65]),e(T,[2,40]),{52:[1,135]},{38:96,51:136,52:[2,44],54:24,57:h},{56:137,60:Y},e(x,[2,48]),{52:[2,54]},e(T,[2,52]),e(T,[2,77]),e(T,[2,79]),e(T,[2,80],{77:[1,138]}),e(T,[2,83]),e(T,[2,84],{28:[1,139]}),e(T,[2,87]),e(T,[2,88],{77:[1,140]}),{29:[1,141]},{16:[1,142]},e(j,[2,62]),e(T,[2,41]),{52:[2,45]},{52:[1,143]},e(T,[2,81]),e(T,[2,85]),e(T,[2,89]),e(z,[2,19]),e(Q,[2,10]),e(x,[2,49])],defaultActions:{2:[2,1],4:[2,3],5:[2,8],9:[2,11],47:[2,2],81:[2,42],86:[2,14],107:[2,21],112:[2,13],113:[2,15],123:[2,54],136:[2,45]},parseError:function(e,t){if(!t.recoverable){var n=new Error(e);throw n.hash=t,n}this.trace(e)},parse:function(e){var t=this,n=[0],s=[],i=[null],u=[],r=this.table,a="",c=0,o=0,l=2,h=1,A=u.slice.call(arguments,1),p=Object.create(this.lexer),d={yy:{}};for(var E in this.yy)Object.prototype.hasOwnProperty.call(this.yy,E)&&(d.yy[E]=this.yy[E]);p.setInput(e,d.yy),d.yy.lexer=p,d.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var y=p.yylloc;u.push(y);var C=p.options&&p.options.ranges;function m(){var e;return"number"!=typeof(e=s.pop()||p.lex()||h)&&(e instanceof Array&&(e=(s=e).pop()),e=t.symbols_[e]||e),e}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var k,b,g,F,f,_,D,B,T={};;){if(b=n[n.length-1],this.defaultActions[b]?g=this.defaultActions[b]:(null==k&&(k=m()),g=r[b]&&r[b][k]),void 0===g||!g.length||!g[0]){var S="";for(f in B=[],r[b])this.terminals_[f]&&f>l&&B.push("'"+this.terminals_[f]+"'");S=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+B.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(c+1)+": Unexpected "+(k==h?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(S,{text:p.match,token:this.terminals_[k]||k,line:p.yylineno,loc:y,expected:B})}if(g[0]instanceof Array&&g.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+k);switch(g[0]){case 1:n.push(k),i.push(p.yytext),u.push(p.yylloc),n.push(g[1]),k=null,o=p.yyleng,a=p.yytext,c=p.yylineno,y=p.yylloc;break;case 2:if(_=this.productions_[g[1]][1],T.$=i[i.length-_],T._$={first_line:u[u.length-(_||1)].first_line,last_line:u[u.length-1].last_line,first_column:u[u.length-(_||1)].first_column,last_column:u[u.length-1].last_column},C&&(T._$.range=[u[u.length-(_||1)].range[0],u[u.length-1].range[1]]),void 0!==(F=this.performAction.apply(T,[a,o,c,d.yy,g[1],i,u].concat(A))))return F;_&&(n=n.slice(0,-1*_*2),i=i.slice(0,-1*_),u=u.slice(0,-1*_)),n.push(this.productions_[g[1]][0]),i.push(T.$),u.push(T._$),D=r[n[n.length-2]][n[n.length-1]],n.push(D);break;case 3:return!0}}return!0}},W={EOF:1,parseError:function(e,t){if(!this.yy.parser)throw new Error(e);this.yy.parser.parseError(e,t)},setInput:function(e,t){return this.yy=t||this.yy||{},this._input=e,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 e=this._input[0];return this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e,e.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},unput:function(e){var t=e.length,n=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-t),this.offset-=t;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 i=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-t},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-t]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},less:function(e){this.unput(this.match.slice(e))},pastInput:function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var e=this.pastInput(),t=new Array(e.length+1).join("-");return e+this.upcomingInput()+"\n"+t+"^"},test_match:function(e,t){var n,s,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(s=e[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+e[0].length},this.yytext+=e[0],this.match+=e[0],this.matches=e,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(e[0].length),this.matched+=e[0],n=this.performAction.call(this,this.yy,this,t,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var u in i)this[u]=i[u];return!1}return!1},next:function(){if(this.done)return this.EOF;var e,t,n,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),u=0;ut[0].length)){if(t=n,s=u,this.options.backtrack_lexer){if(!1!==(e=this.test_match(n,i[u])))return e;if(this._backtrack){t=!1;continue}return!1}if(!this.options.flex)break}return t?!1!==(e=this.test_match(t,i[s]))&&e:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var e=this.next();return e||this.lex()},begin:function(e){this.conditionStack.push(e)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(e){return(e=this.conditionStack.length-1-Math.abs(e||0))>=0?this.conditionStack[e]:"INITIAL"},pushState:function(e){this.begin(e)},stateStackSize:function(){return this.conditionStack.length},options:{},performAction:function(e,t,n,s){switch(n){case 0:return this.begin("open_directive"),19;case 1:return 8;case 2:return 9;case 3:return 10;case 4:return 11;case 5:return this.begin("type_directive"),20;case 6:return this.popState(),this.begin("arg_directive"),17;case 7:return this.popState(),this.popState(),22;case 8:return 21;case 9:case 10:break;case 11:return this.begin("acc_title"),44;case 12:return this.popState(),"acc_title_value";case 13:return this.begin("acc_descr"),46;case 14:return this.popState(),"acc_descr_value";case 15:this.begin("acc_descr_multiline");break;case 16:this.popState();break;case 17:return"acc_descr_multiline_value";case 18:return 16;case 19:break;case 20:case 21:return 23;case 22:return"EDGE_STATE";case 23:return this.begin("namespace"),53;case 24:return this.popState(),16;case 25:break;case 26:return this.begin("namespace-body"),50;case 27:return this.popState(),52;case 28:return"EOF_IN_STRUCT";case 29:return 16;case 30:break;case 31:return"EDGE_STATE";case 32:return this.begin("class"),57;case 33:return this.popState(),16;case 34:break;case 35:return this.popState(),this.popState(),52;case 36:return this.begin("class-body"),50;case 37:return this.popState(),52;case 38:return"EOF_IN_STRUCT";case 39:return"EDGE_STATE";case 40:return"OPEN_IN_STRUCT";case 41:break;case 42:return"MEMBER";case 43:return 82;case 44:return 75;case 45:return 76;case 46:return 78;case 47:return 63;case 48:return 65;case 49:return 58;case 50:return 59;case 51:this.begin("href");break;case 52:this.popState();break;case 53:return 81;case 54:this.begin("callback_name");break;case 55:this.popState();break;case 56:this.popState(),this.begin("callback_args");break;case 57:return 79;case 58:this.popState();break;case 59:return 80;case 60:this.popState();break;case 61:return"GENERICTYPE";case 62:this.begin("generic");break;case 63:this.popState();break;case 64:return"STR";case 65:this.begin("string");break;case 66:this.popState();break;case 67:return"BQUOTE_STR";case 68:this.begin("bqstring");break;case 69:case 70:case 71:case 72:return 77;case 73:case 74:return 69;case 75:case 76:return 71;case 77:return 70;case 78:return 68;case 79:return 72;case 80:return 73;case 81:return 74;case 82:return 36;case 83:return 55;case 84:return 94;case 85:return"DOT";case 86:return"PLUS";case 87:return 91;case 88:case 89:return"EQUALS";case 90:return 98;case 91:return 27;case 92:return 29;case 93:return"PUNCTUATION";case 94:return 97;case 95:return 96;case 96:return 93;case 97:return 24}},rules:[/^(?:%%\{)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:((?:(?!\}%%)[^:.])*))/,/^(?::)/,/^(?:\}%%)/,/^(?:((?:(?!\}%%).|\n)*))/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href[\s]+["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:[~])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[27,28,29,30,31,32,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},namespace:{rules:[23,24,25,26,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},"class-body":{rules:[37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},class:{rules:[33,34,35,36,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},acc_descr_multiline:{rules:[16,17,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},acc_descr:{rules:[14,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},acc_title:{rules:[12,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},arg_directive:{rules:[7,8,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},type_directive:{rules:[6,7,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},open_directive:{rules:[5,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},callback_args:{rules:[43,44,45,46,47,48,49,50,51,54,58,59,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},callback_name:{rules:[43,44,45,46,47,48,49,50,51,54,55,56,57,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},href:{rules:[43,44,45,46,47,48,49,50,51,52,53,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},struct:{rules:[43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},generic:{rules:[43,44,45,46,47,48,49,50,51,54,60,61,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},bqstring:{rules:[43,44,45,46,47,48,49,50,51,54,62,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},string:{rules:[43,44,45,46,47,48,49,50,51,54,62,63,64,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,9,10,11,13,15,18,19,20,21,22,23,32,43,44,45,46,47,48,49,50,51,54,62,65,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!0}}};function H(){this.yy={}}return X.lexer=W,H.prototype=X,X.Parser=H,new H}();p.parser=p;const d=p;let E=[],y={},C=[],m=0,k={},b=0,g=[];const F=e=>c.sanitizeText(e,i()),f=function(e){let t="",n=e;if(e.indexOf("~")>0){const s=e.split("~");n=F(s[0]),t=F(s[1])}return{className:n,type:t}},_=function(e){const t=f(e);void 0===y[t.className]&&(y[t.className]={id:t.className,type:t.type,label:t.className,cssClasses:[],methods:[],members:[],annotations:[],domId:"classId-"+t.className+"-"+m},m++)},D=function(e){if(e in y)return y[e].domId;throw new Error("Class not found: "+e)},B=function(e,t){const n=f(e).className,s=y[n];if("string"==typeof t){const e=t.trim();e.startsWith("<<")&&e.endsWith(">>")?s.annotations.push(F(e.substring(2,e.length-2))):e.indexOf(")")>0?s.methods.push(F(e)):e&&s.members.push(F(e))}},T=function(e,t){e.split(",").forEach((function(e){let n=e;e[0].match(/\d/)&&(n="classId-"+n),void 0!==y[n]&&y[n].cssClasses.push(t)}))},S=function(e,t,n){if("loose"!==i().securityLevel)return;if(void 0===t)return;const s=e;if(void 0!==y[s]){const e=D(s);let i=[];if("string"==typeof n){i=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let e=0;e")),e.classed("hover",!0)})).on("mouseout",(function(){t.transition().duration(500).style("opacity",0);A(this).classed("hover",!1)}))};g.push(N);let v="TB";const $={parseDirective:function(e,t,n){a.parseDirective(this,e,t,n)},setAccTitle:e,getAccTitle:t,getAccDescription:n,setAccDescription:s,getConfig:()=>i().class,addClass:_,bindFunctions:function(e){g.forEach((function(t){t(e)}))},clear:function(){E=[],y={},C=[],g=[],g.push(N),k={},b=0,o()},getClass:function(e){return y[e]},getClasses:function(){return y},getNotes:function(){return C},addAnnotation:function(e,t){const n=f(e).className;y[n].annotations.push(t)},addNote:function(e,t){const n={id:`note${C.length}`,class:t,text:e};C.push(n)},getRelations:function(){return E},addRelation:function(e){l.debug("Adding relation: "+JSON.stringify(e)),_(e.id1),_(e.id2),e.id1=f(e.id1).className,e.id2=f(e.id2).className,e.relationTitle1=c.sanitizeText(e.relationTitle1.trim(),i()),e.relationTitle2=c.sanitizeText(e.relationTitle2.trim(),i()),E.push(e)},getDirection:()=>v,setDirection:e=>{v=e},addMember:B,addMembers:function(e,t){Array.isArray(t)&&(t.reverse(),t.forEach((t=>B(e,t))))},cleanupLabel:function(e){return e.startsWith(":")&&(e=e.substring(1)),F(e.trim())},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3,LOLLIPOP:4},setClickEvent:function(e,t,n){e.split(",").forEach((function(e){S(e,t,n),y[e].haveCallback=!0})),T(e,"clickable")},setCssClass:T,setLink:function(e,t,n){const s=i();e.split(",").forEach((function(e){let i=e;e[0].match(/\d/)&&(i="classId-"+i),void 0!==y[i]&&(y[i].link=h.formatUrl(t,s),"sandbox"===s.securityLevel?y[i].linkTarget="_top":y[i].linkTarget="string"==typeof n?F(n):"_blank")})),T(e,"clickable")},getTooltip:function(e,t){return t?k[t].classes[e].tooltip:y[e].tooltip},setTooltip:function(e,t){e.split(",").forEach((function(e){void 0!==t&&(y[e].tooltip=F(t))}))},lookUpDomId:D,setDiagramTitle:u,getDiagramTitle:r,setClassLabel:function(e,t){t&&(t=F(t));const{className:n}=f(e);y[n].label=t},addNamespace:function(e){void 0===k[e]&&(k[e]={id:e,classes:{},children:{},domId:"classId-"+e+"-"+b},b++)},addClassesToNamespace:function(e,t){void 0!==k[e]&&t.map((t=>{k[e].classes[t]=y[t],delete y[t],m--}))},getNamespace:function(e){return k[e]},getNamespaces:function(){return k}},L=e=>`g.classGroup text {\n fill: ${e.nodeBorder};\n fill: ${e.classText};\n stroke: none;\n font-family: ${e.fontFamily};\n font-size: 10px;\n\n .title {\n font-weight: bolder;\n }\n\n}\n\n.nodeLabel, .edgeLabel {\n color: ${e.classText};\n}\n.edgeLabel .label rect {\n fill: ${e.mainBkg};\n}\n.label text {\n fill: ${e.classText};\n}\n.edgeLabel .label span {\n background: ${e.mainBkg};\n}\n\n.classTitle {\n font-weight: bolder;\n}\n.node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n\n\n.divider {\n stroke: ${e.nodeBorder};\n stroke-width: 1;\n}\n\ng.clickable {\n cursor: pointer;\n}\n\ng.classGroup rect {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n}\n\ng.classGroup line {\n stroke: ${e.nodeBorder};\n stroke-width: 1;\n}\n\n.classLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${e.mainBkg};\n opacity: 0.5;\n}\n\n.classLabel .label {\n fill: ${e.nodeBorder};\n font-size: 10px;\n}\n\n.relation {\n stroke: ${e.lineColor};\n stroke-width: 1;\n fill: none;\n}\n\n.dashed-line{\n stroke-dasharray: 3;\n}\n\n.dotted-line{\n stroke-dasharray: 1 2;\n}\n\n#compositionStart, .composition {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#compositionEnd, .composition {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${e.lineColor} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionStart, .extension {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionEnd, .extension {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationStart, .aggregation {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationEnd, .aggregation {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopStart, .lollipop {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopEnd, .lollipop {\n fill: ${e.mainBkg} !important;\n stroke: ${e.lineColor} !important;\n stroke-width: 1;\n}\n\n.edgeTerminals {\n font-size: 11px;\n}\n\n.classTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n}\n`;export{$ as d,d as p,L as s}; diff --git a/assets/styles-2797ae0f.8914e425.js b/assets/styles-2797ae0f.76392e9d.js similarity index 99% rename from assets/styles-2797ae0f.8914e425.js rename to assets/styles-2797ae0f.76392e9d.js index 063cd2e21..276cbb836 100644 --- a/assets/styles-2797ae0f.8914e425.js +++ b/assets/styles-2797ae0f.76392e9d.js @@ -1 +1 @@ -import{c as t,g as e,s as i,a as s,b as n,v as r,x as a,m as o,l as c,j as l,z as h,aF as u}from"./mermaid.core.a66200b0.js";var d=function(){var t=function(t,e,i,s){for(i=i||{},s=t.length;s--;i[t[s]]=e);return i},e=[1,2],i=[1,3],s=[1,5],n=[1,7],r=[2,5],a=[1,15],o=[1,17],c=[1,21],l=[1,22],h=[1,23],u=[1,24],d=[1,37],p=[1,25],y=[1,26],f=[1,27],m=[1,28],g=[1,29],_=[1,32],S=[1,33],k=[1,34],b=[1,35],T=[1,36],E=[1,39],v=[1,40],x=[1,41],D=[1,42],C=[1,38],$=[1,45],A=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],L=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],I=[1,4,5,7,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],O=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],N={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,directive:6,SD:7,document:8,line:9,statement:10,classDefStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"--\x3e":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:29,notePosition:30,NOTE_TEXT:31,direction: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,openDirective:45,typeDirective:46,closeDirective:47,":":48,argDirective:49,direction_tb:50,direction_bt:51,direction_rl:52,direction_lr:53,eol:54,";":55,EDGE_STATE:56,STYLE_SEPARATOR:57,left_of:58,right_of:59,open_directive:60,type_directive:61,arg_directive:62,close_directive:63,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",7:"SD",14:"DESCR",15:"--\x3e",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"classDef",39:"CLASSDEF_ID",40:"CLASSDEF_STYLEOPTS",41:"DEFAULT",42:"class",43:"CLASSENTITY_IDS",44:"STYLECLASS",48:":",50:"direction_tb",51:"direction_bt",52:"direction_rl",53:"direction_lr",55:";",56:"EDGE_STATE",57:"STYLE_SEPARATOR",58:"left_of",59:"right_of",60:"open_directive",61:"type_directive",62:"arg_directive",63:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[9,1],[9,1],[10,1],[10,1],[10,1],[10,2],[10,3],[10,4],[10,1],[10,2],[10,1],[10,4],[10,3],[10,6],[10,1],[10,1],[10,1],[10,1],[10,4],[10,4],[10,1],[10,1],[10,2],[10,2],[10,1],[11,3],[11,3],[12,3],[6,3],[6,5],[32,1],[32,1],[32,1],[32,1],[54,1],[54,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1],[45,1],[46,1],[49,1],[47,1]],performAction:function(t,e,i,s,n,r,a){var o=r.length-1;switch(n){case 4:return s.setRootDoc(r[o]),r[o];case 5:this.$=[];break;case 6:"nl"!=r[o]&&(r[o-1].push(r[o]),this.$=r[o-1]);break;case 7:case 8:this.$=r[o];break;case 9:this.$="nl";break;case 12:this.$=r[o];break;case 13:const t=r[o-1];t.description=s.trimColon(r[o]),this.$=t;break;case 14:this.$={stmt:"relation",state1:r[o-2],state2:r[o]};break;case 15:const e=s.trimColon(r[o]);this.$={stmt:"relation",state1:r[o-3],state2:r[o-1],description:e};break;case 19:this.$={stmt:"state",id:r[o-3],type:"default",description:"",doc:r[o-1]};break;case 20:var c=r[o],l=r[o-2].trim();if(r[o].match(":")){var h=r[o].split(":");c=h[0],l=[l,h[1]]}this.$={stmt:"state",id:c,type:"default",description:l};break;case 21:this.$={stmt:"state",id:r[o-3],type:"default",description:r[o-5],doc:r[o-1]};break;case 22:this.$={stmt:"state",id:r[o],type:"fork"};break;case 23:this.$={stmt:"state",id:r[o],type:"join"};break;case 24:this.$={stmt:"state",id:r[o],type:"choice"};break;case 25:this.$={stmt:"state",id:s.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:r[o-1].trim(),note:{position:r[o-2].trim(),text:r[o].trim()}};break;case 30:this.$=r[o].trim(),s.setAccTitle(this.$);break;case 31:case 32:this.$=r[o].trim(),s.setAccDescription(this.$);break;case 33:case 34:this.$={stmt:"classDef",id:r[o-1].trim(),classes:r[o].trim()};break;case 35:this.$={stmt:"applyClass",id:r[o-1].trim(),styleClass:r[o].trim()};break;case 38:s.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 39:s.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 40:s.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 41:s.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 44:case 45:this.$={stmt:"state",id:r[o].trim(),type:"default",description:""};break;case 46:case 47:this.$={stmt:"state",id:r[o-2].trim(),classes:[r[o].trim()],type:"default",description:""};break;case 50:s.parseDirective("%%{","open_directive");break;case 51:s.parseDirective(r[o],"type_directive");break;case 52:r[o]=r[o].trim().replace(/'/g,'"'),s.parseDirective(r[o],"arg_directive");break;case 53:s.parseDirective("}%%","close_directive","state")}},table:[{3:1,4:e,5:i,6:4,7:s,45:6,60:n},{1:[3]},{3:8,4:e,5:i,6:4,7:s,45:6,60:n},{3:9,4:e,5:i,6:4,7:s,45:6,60:n},{3:10,4:e,5:i,6:4,7:s,45:6,60:n},t([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],r,{8:11}),{46:12,61:[1,13]},{61:[2,50]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{1:[2,4],4:a,5:o,6:30,9:14,10:16,11:18,12:19,13:20,16:c,17:l,19:h,22:u,24:d,25:p,26:y,27:f,28:m,29:g,32:31,33:_,35:S,37:k,38:b,42:T,45:6,50:E,51:v,52:x,53:D,56:C,60:n},{47:43,48:[1,44],63:$},t([48,63],[2,51]),t(A,[2,6]),{6:30,10:46,11:18,12:19,13:20,16:c,17:l,19:h,22:u,24:d,25:p,26:y,27:f,28:m,29:g,32:31,33:_,35:S,37:k,38:b,42:T,45:6,50:E,51:v,52:x,53:D,56:C,60:n},t(A,[2,8]),t(A,[2,9]),t(A,[2,10]),t(A,[2,11]),t(A,[2,12],{14:[1,47],15:[1,48]}),t(A,[2,16]),{18:[1,49]},t(A,[2,18],{20:[1,50]}),{23:[1,51]},t(A,[2,22]),t(A,[2,23]),t(A,[2,24]),t(A,[2,25]),{30:52,31:[1,53],58:[1,54],59:[1,55]},t(A,[2,28]),t(A,[2,29]),{34:[1,56]},{36:[1,57]},t(A,[2,32]),{39:[1,58],41:[1,59]},{43:[1,60]},t(L,[2,44],{57:[1,61]}),t(L,[2,45],{57:[1,62]}),t(A,[2,38]),t(A,[2,39]),t(A,[2,40]),t(A,[2,41]),t(I,[2,36]),{49:63,62:[1,64]},t(I,[2,53]),t(A,[2,7]),t(A,[2,13]),{13:65,24:d,56:C},t(A,[2,17]),t(O,r,{8:66}),{24:[1,67]},{24:[1,68]},{23:[1,69]},{24:[2,48]},{24:[2,49]},t(A,[2,30]),t(A,[2,31]),{40:[1,70]},{40:[1,71]},{44:[1,72]},{24:[1,73]},{24:[1,74]},{47:75,63:$},{63:[2,52]},t(A,[2,14],{14:[1,76]}),{4:a,5:o,6:30,9:14,10:16,11:18,12:19,13:20,16:c,17:l,19:h,21:[1,77],22:u,24:d,25:p,26:y,27:f,28:m,29:g,32:31,33:_,35:S,37:k,38:b,42:T,45:6,50:E,51:v,52:x,53:D,56:C,60:n},t(A,[2,20],{20:[1,78]}),{31:[1,79]},{24:[1,80]},t(A,[2,33]),t(A,[2,34]),t(A,[2,35]),t(L,[2,46]),t(L,[2,47]),t(I,[2,37]),t(A,[2,15]),t(A,[2,19]),t(O,r,{8:81}),t(A,[2,26]),t(A,[2,27]),{4:a,5:o,6:30,9:14,10:16,11:18,12:19,13:20,16:c,17:l,19:h,21:[1,82],22:u,24:d,25:p,26:y,27:f,28:m,29:g,32:31,33:_,35:S,37:k,38:b,42:T,45:6,50:E,51:v,52:x,53:D,56:C,60:n},t(A,[2,21])],defaultActions:{7:[2,50],8:[2,1],9:[2,2],10:[2,3],54:[2,48],55:[2,49],64:[2,52]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],s=[],n=[null],r=[],a=this.table,o="",c=0,l=0,h=2,u=1,d=r.slice.call(arguments,1),p=Object.create(this.lexer),y={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(y.yy[f]=this.yy[f]);p.setInput(t,y.yy),y.yy.lexer=p,y.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;r.push(m);var g=p.options&&p.options.ranges;function _(){var t;return"number"!=typeof(t=s.pop()||p.lex()||u)&&(t instanceof Array&&(t=(s=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var S,k,b,T,E,v,x,D,C={};;){if(k=i[i.length-1],this.defaultActions[k]?b=this.defaultActions[k]:(null==S&&(S=_()),b=a[k]&&a[k][S]),void 0===b||!b.length||!b[0]){var $="";for(E in D=[],a[k])this.terminals_[E]&&E>h&&D.push("'"+this.terminals_[E]+"'");$=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+D.join(", ")+", got '"+(this.terminals_[S]||S)+"'":"Parse error on line "+(c+1)+": Unexpected "+(S==u?"end of input":"'"+(this.terminals_[S]||S)+"'"),this.parseError($,{text:p.match,token:this.terminals_[S]||S,line:p.yylineno,loc:m,expected:D})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+S);switch(b[0]){case 1:i.push(S),n.push(p.yytext),r.push(p.yylloc),i.push(b[1]),S=null,l=p.yyleng,o=p.yytext,c=p.yylineno,m=p.yylloc;break;case 2:if(v=this.productions_[b[1]][1],C.$=n[n.length-v],C._$={first_line:r[r.length-(v||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(v||1)].first_column,last_column:r[r.length-1].last_column},g&&(C._$.range=[r[r.length-(v||1)].range[0],r[r.length-1].range[1]]),void 0!==(T=this.performAction.apply(C,[o,l,c,y.yy,b[1],n,r].concat(d))))return T;v&&(i=i.slice(0,-1*v*2),n=n.slice(0,-1*v),r=r.slice(0,-1*v)),i.push(this.productions_[b[1]][0]),n.push(C.$),r.push(C._$),x=a[i[i.length-2]][i[i.length-1]],i.push(x);break;case 3:return!0}}return!0}},R={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,i=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),i.length-1&&(this.yylineno-=i.length-1);var n=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===s.length?this.yylloc.first_column:0)+s[s.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var i,s,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;re[0].length)){if(e=i,s=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,n[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,s){switch(i){case 0:return 41;case 1:return 50;case 2:return 51;case 3:return 52;case 4:return 53;case 5:return this.begin("open_directive"),60;case 6:return this.begin("type_directive"),61;case 7:return this.popState(),this.begin("arg_directive"),48;case 8:return this.popState(),this.popState(),63;case 9:return 62;case 10:case 11:break;case 12:return 5;case 13:case 14:case 15:case 16:break;case 17:return this.pushState("SCALE"),17;case 18:return 18;case 19:this.popState();break;case 20:return this.begin("acc_title"),33;case 21:return this.popState(),"acc_title_value";case 22:return this.begin("acc_descr"),35;case 23:return this.popState(),"acc_descr_value";case 24:this.begin("acc_descr_multiline");break;case 25:this.popState();break;case 26:return"acc_descr_multiline_value";case 27:return this.pushState("CLASSDEF"),38;case 28:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 29:return this.popState(),this.pushState("CLASSDEFID"),39;case 30:return this.popState(),40;case 31:return this.pushState("CLASS"),42;case 32:return this.popState(),this.pushState("CLASS_STYLE"),43;case 33:return this.popState(),44;case 34:return this.pushState("SCALE"),17;case 35:return 18;case 36:this.popState();break;case 37:this.pushState("STATE");break;case 38:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 39:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),26;case 40:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),27;case 41:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 42:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),26;case 43:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),27;case 44:return 50;case 45:return 51;case 46:return 52;case 47:return 53;case 48:this.pushState("STATE_STRING");break;case 49:return this.pushState("STATE_ID"),"AS";case 50:return this.popState(),"ID";case 51:this.popState();break;case 52:return"STATE_DESCR";case 53:return 19;case 54:this.popState();break;case 55:return this.popState(),this.pushState("struct"),20;case 56:break;case 57:return this.popState(),21;case 58:break;case 59:return this.begin("NOTE"),29;case 60:return this.popState(),this.pushState("NOTE_ID"),58;case 61:return this.popState(),this.pushState("NOTE_ID"),59;case 62:this.popState(),this.pushState("FLOATING_NOTE");break;case 63:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 64:break;case 65:return"NOTE_TEXT";case 66:return this.popState(),"ID";case 67:return this.popState(),this.pushState("NOTE_TEXT"),24;case 68:return this.popState(),e.yytext=e.yytext.substr(2).trim(),31;case 69:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),31;case 70:case 71:return 7;case 72:return 16;case 73:return 56;case 74:return 24;case 75:return e.yytext=e.yytext.trim(),14;case 76:return 15;case 77:return 28;case 78:return 57;case 79:return 5;case 80:return"INVALID"}},rules:[/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[14,15],inclusive:!1},close_directive:{rules:[14,15],inclusive:!1},arg_directive:{rules:[8,9,14,15],inclusive:!1},type_directive:{rules:[7,8,14,15],inclusive:!1},open_directive:{rules:[6,14,15],inclusive:!1},struct:{rules:[14,15,27,31,37,44,45,46,47,56,57,58,59,73,74,75,76,77],inclusive:!1},FLOATING_NOTE_ID:{rules:[66],inclusive:!1},FLOATING_NOTE:{rules:[63,64,65],inclusive:!1},NOTE_TEXT:{rules:[68,69],inclusive:!1},NOTE_ID:{rules:[67],inclusive:!1},NOTE:{rules:[60,61,62],inclusive:!1},CLASS_STYLE:{rules:[33],inclusive:!1},CLASS:{rules:[32],inclusive:!1},CLASSDEFID:{rules:[30],inclusive:!1},CLASSDEF:{rules:[28,29],inclusive:!1},acc_descr_multiline:{rules:[25,26],inclusive:!1},acc_descr:{rules:[23],inclusive:!1},acc_title:{rules:[21],inclusive:!1},SCALE:{rules:[18,19,35,36],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[50],inclusive:!1},STATE_STRING:{rules:[51,52],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[14,15,38,39,40,41,42,43,48,49,53,54,55],inclusive:!1},ID:{rules:[14,15],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,10,11,12,13,15,16,17,20,22,24,27,31,34,37,55,59,70,71,72,73,74,75,76,78,79,80],inclusive:!0}}};function B(){this.yy={}}return N.lexer=R,B.prototype=N,N.Parser=B,new B}();d.parser=d;const p=d,y="TB",f="state",m="relation",g="default",_="divider";let S="LR",k=[],b={};let T={root:{relations:[],states:{},documents:{}}},E=T.root,v=0,x=0;const D=t=>JSON.parse(JSON.stringify(t)),C=(t,e,i)=>{if("relation"===e.stmt)C(t,e.state1,!0),C(t,e.state2,!1);else if("state"===e.stmt&&("[*]"===e.id?(e.id=i?t.id+"_start":t.id+"_end",e.start=i):e.id=e.id.trim()),e.doc){const t=[];let i,s=[];for(i=0;i0&&s.length>0){const i={stmt:"state",id:u(),type:"divider",doc:D(s)};t.push(D(i)),e.doc=t}e.doc.forEach((t=>C(e,t,!0)))}},$=function(e,i="default",s=null,n=null,r=null,a=null,o=null,h=null){const u=null==e?void 0:e.trim();if(void 0===E.states[u]?(c.info("Adding state ",u,n),E.states[u]={id:u,descriptions:[],type:i,doc:s,note:r,classes:[],styles:[],textStyles:[]}):(E.states[u].doc||(E.states[u].doc=s),E.states[u].type||(E.states[u].type=i)),n&&(c.info("Setting state description",u,n),"string"==typeof n&&R(u,n.trim()),"object"==typeof n&&n.forEach((t=>R(u,t.trim())))),r&&(E.states[u].note=r,E.states[u].note.text=l.sanitizeText(E.states[u].note.text,t())),a){c.info("Setting state classes",u,a);("string"==typeof a?[a]:a).forEach((t=>w(u,t.trim())))}if(o){c.info("Setting state styles",u,o);("string"==typeof o?[o]:o).forEach((t=>F(u,t.trim())))}if(h){c.info("Setting state styles",u,o);("string"==typeof h?[h]:h).forEach((t=>P(u,t.trim())))}},A=function(t){T={root:{relations:[],states:{},documents:{}}},E=T.root,v=0,b={},t||h()},L=function(t){return E.states[t]};function I(t=""){let e=t;return"[*]"===t&&(v++,e=`start${v}`),e}function O(t="",e="default"){return"[*]"===t?"start":e}const N=function(e,i,s){if("object"==typeof e)!function(e,i,s){let n=I(e.id.trim()),r=O(e.id.trim(),e.type),a=I(i.id.trim()),o=O(i.id.trim(),i.type);$(n,r,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),$(a,o,i.doc,i.description,i.note,i.classes,i.styles,i.textStyles),E.relations.push({id1:n,id2:a,relationTitle:l.sanitizeText(s,t())})}(e,i,s);else{const n=I(e.trim()),r=O(e),a=function(t=""){let e=t;return"[*]"===t&&(v++,e=`end${v}`),e}(i.trim()),o=function(t="",e="default"){return"[*]"===t?"end":e}(i);$(n,r),$(a,o),E.relations.push({id1:n,id2:a,title:l.sanitizeText(s,t())})}},R=function(e,i){const s=E.states[e],n=i.startsWith(":")?i.replace(":","").trim():i;s.descriptions.push(l.sanitizeText(n,t()))},B=function(t,e=""){void 0===b[t]&&(b[t]={id:t,styles:[],textStyles:[]});const i=b[t];null!=e&&e.split(",").forEach((t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(t.match("color")){const t=e.replace("fill","bgFill").replace("color","fill");i.textStyles.push(t)}i.styles.push(e)}))},w=function(t,e){t.split(",").forEach((function(t){let i=L(t);if(void 0===i){const e=t.trim();$(e),i=L(e)}i.classes.push(e)}))},F=function(t,e){const i=L(t);void 0!==i&&i.textStyles.push(e)},P=function(t,e){const i=L(t);void 0!==i&&i.textStyles.push(e)},G={parseDirective:function(t,e,i){o.parseDirective(this,t,e,i)},getConfig:()=>t().state,addState:$,clear:A,getState:L,getStates:function(){return E.states},getRelations:function(){return E.relations},getClasses:function(){return b},getDirection:()=>S,addRelation:N,getDividerId:()=>(x++,"divider-id-"+x),setDirection:t=>{S=t},cleanupLabel:function(t){return":"===t.substring(0,1)?t.substr(2).trim():t.trim()},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},logDocuments:function(){c.info("Documents = ",T)},getRootDoc:()=>k,setRootDoc:t=>{c.info("Setting root doc",t),k=t},getRootDocV2:()=>(C({id:"root"},{id:"root",doc:k},!0),{id:"root",doc:k}),extract:t=>{let e;e=t.doc?t.doc:t,c.info(e),A(!0),c.info("Extract",e),e.forEach((t=>{switch(t.stmt){case"state":$(t.id.trim(),t.type,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles);break;case"relation":N(t.state1,t.state2,t.description);break;case"classDef":B(t.id.trim(),t.classes);break;case"applyClass":w(t.id.trim(),t.styleClass)}}))},trimColon:t=>t&&":"===t[0]?t.substr(1).trim():t.trim(),getAccTitle:e,setAccTitle:i,getAccDescription:s,setAccDescription:n,addStyleClass:B,setCssClass:w,addDescription:R,setDiagramTitle:r,getDiagramTitle:a},j=t=>`\ndefs #statediagram-barbEnd {\n fill: ${t.transitionColor};\n stroke: ${t.transitionColor};\n }\ng.stateGroup text {\n fill: ${t.nodeBorder};\n stroke: none;\n font-size: 10px;\n}\ng.stateGroup text {\n fill: ${t.textColor};\n stroke: none;\n font-size: 10px;\n\n}\ng.stateGroup .state-title {\n font-weight: bolder;\n fill: ${t.stateLabelColor};\n}\n\ng.stateGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.stateGroup line {\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.transition {\n stroke: ${t.transitionColor};\n stroke-width: 1;\n fill: none;\n}\n\n.stateGroup .composit {\n fill: ${t.background};\n border-bottom: 1px\n}\n\n.stateGroup .alt-composit {\n fill: #e0e0e0;\n border-bottom: 1px\n}\n\n.state-note {\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n\n text {\n fill: ${t.noteTextColor};\n stroke: none;\n font-size: 10px;\n }\n}\n\n.stateLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.edgeLabel .label rect {\n fill: ${t.labelBackgroundColor};\n opacity: 0.5;\n}\n.edgeLabel .label text {\n fill: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n.label div .edgeLabel {\n color: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n\n.stateLabel text {\n fill: ${t.stateLabelColor};\n font-size: 10px;\n font-weight: bold;\n}\n\n.node circle.state-start {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node .fork-join {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node circle.state-end {\n fill: ${t.innerEndBackground};\n stroke: ${t.background};\n stroke-width: 1.5\n}\n.end-state-inner {\n fill: ${t.compositeBackground||t.background};\n // stroke: ${t.background};\n stroke-width: 1.5\n}\n\n.node rect {\n fill: ${t.stateBkg||t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n.node polygon {\n fill: ${t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};;\n stroke-width: 1px;\n}\n#statediagram-barbEnd {\n fill: ${t.lineColor};\n}\n\n.statediagram-cluster rect {\n fill: ${t.compositeTitleBackground};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n\n.cluster-label, .nodeLabel {\n color: ${t.stateLabelColor};\n}\n\n.statediagram-cluster rect.outer {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state .divider {\n stroke: ${t.stateBorder||t.nodeBorder};\n}\n\n.statediagram-state .title-state {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-cluster.statediagram-cluster .inner {\n fill: ${t.compositeBackground||t.background};\n}\n.statediagram-cluster.statediagram-cluster-alt .inner {\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.statediagram-cluster .inner {\n rx:0;\n ry:0;\n}\n\n.statediagram-state rect.basic {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state rect.divider {\n stroke-dasharray: 10,10;\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.note-edge {\n stroke-dasharray: 5;\n}\n\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n\n.statediagram-note text {\n fill: ${t.noteTextColor};\n}\n\n.statediagram-note .nodeLabel {\n color: ${t.noteTextColor};\n}\n.statediagram .edgeLabel {\n color: red; // ${t.noteTextColor};\n}\n\n#dependencyStart, #dependencyEnd {\n fill: ${t.lineColor};\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.statediagramTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`;export{g as D,m as S,_ as a,f as b,y as c,G as d,p,j as s}; +import{c as t,g as e,s as i,a as s,b as n,v as r,x as a,m as o,l as c,j as l,z as h,aF as u}from"./mermaid.core.3a590193.js";var d=function(){var t=function(t,e,i,s){for(i=i||{},s=t.length;s--;i[t[s]]=e);return i},e=[1,2],i=[1,3],s=[1,5],n=[1,7],r=[2,5],a=[1,15],o=[1,17],c=[1,21],l=[1,22],h=[1,23],u=[1,24],d=[1,37],p=[1,25],y=[1,26],f=[1,27],m=[1,28],g=[1,29],_=[1,32],S=[1,33],k=[1,34],b=[1,35],T=[1,36],E=[1,39],v=[1,40],x=[1,41],D=[1,42],C=[1,38],$=[1,45],A=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],L=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],I=[1,4,5,7,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],O=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],N={trace:function(){},yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,directive:6,SD:7,document:8,line:9,statement:10,classDefStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"--\x3e":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:29,notePosition:30,NOTE_TEXT:31,direction: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,openDirective:45,typeDirective:46,closeDirective:47,":":48,argDirective:49,direction_tb:50,direction_bt:51,direction_rl:52,direction_lr:53,eol:54,";":55,EDGE_STATE:56,STYLE_SEPARATOR:57,left_of:58,right_of:59,open_directive:60,type_directive:61,arg_directive:62,close_directive:63,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",7:"SD",14:"DESCR",15:"--\x3e",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"classDef",39:"CLASSDEF_ID",40:"CLASSDEF_STYLEOPTS",41:"DEFAULT",42:"class",43:"CLASSENTITY_IDS",44:"STYLECLASS",48:":",50:"direction_tb",51:"direction_bt",52:"direction_rl",53:"direction_lr",55:";",56:"EDGE_STATE",57:"STYLE_SEPARATOR",58:"left_of",59:"right_of",60:"open_directive",61:"type_directive",62:"arg_directive",63:"close_directive"},productions_:[0,[3,2],[3,2],[3,2],[3,2],[8,0],[8,2],[9,2],[9,1],[9,1],[10,1],[10,1],[10,1],[10,2],[10,3],[10,4],[10,1],[10,2],[10,1],[10,4],[10,3],[10,6],[10,1],[10,1],[10,1],[10,1],[10,4],[10,4],[10,1],[10,1],[10,2],[10,2],[10,1],[11,3],[11,3],[12,3],[6,3],[6,5],[32,1],[32,1],[32,1],[32,1],[54,1],[54,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1],[45,1],[46,1],[49,1],[47,1]],performAction:function(t,e,i,s,n,r,a){var o=r.length-1;switch(n){case 4:return s.setRootDoc(r[o]),r[o];case 5:this.$=[];break;case 6:"nl"!=r[o]&&(r[o-1].push(r[o]),this.$=r[o-1]);break;case 7:case 8:this.$=r[o];break;case 9:this.$="nl";break;case 12:this.$=r[o];break;case 13:const t=r[o-1];t.description=s.trimColon(r[o]),this.$=t;break;case 14:this.$={stmt:"relation",state1:r[o-2],state2:r[o]};break;case 15:const e=s.trimColon(r[o]);this.$={stmt:"relation",state1:r[o-3],state2:r[o-1],description:e};break;case 19:this.$={stmt:"state",id:r[o-3],type:"default",description:"",doc:r[o-1]};break;case 20:var c=r[o],l=r[o-2].trim();if(r[o].match(":")){var h=r[o].split(":");c=h[0],l=[l,h[1]]}this.$={stmt:"state",id:c,type:"default",description:l};break;case 21:this.$={stmt:"state",id:r[o-3],type:"default",description:r[o-5],doc:r[o-1]};break;case 22:this.$={stmt:"state",id:r[o],type:"fork"};break;case 23:this.$={stmt:"state",id:r[o],type:"join"};break;case 24:this.$={stmt:"state",id:r[o],type:"choice"};break;case 25:this.$={stmt:"state",id:s.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:r[o-1].trim(),note:{position:r[o-2].trim(),text:r[o].trim()}};break;case 30:this.$=r[o].trim(),s.setAccTitle(this.$);break;case 31:case 32:this.$=r[o].trim(),s.setAccDescription(this.$);break;case 33:case 34:this.$={stmt:"classDef",id:r[o-1].trim(),classes:r[o].trim()};break;case 35:this.$={stmt:"applyClass",id:r[o-1].trim(),styleClass:r[o].trim()};break;case 38:s.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 39:s.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 40:s.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 41:s.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 44:case 45:this.$={stmt:"state",id:r[o].trim(),type:"default",description:""};break;case 46:case 47:this.$={stmt:"state",id:r[o-2].trim(),classes:[r[o].trim()],type:"default",description:""};break;case 50:s.parseDirective("%%{","open_directive");break;case 51:s.parseDirective(r[o],"type_directive");break;case 52:r[o]=r[o].trim().replace(/'/g,'"'),s.parseDirective(r[o],"arg_directive");break;case 53:s.parseDirective("}%%","close_directive","state")}},table:[{3:1,4:e,5:i,6:4,7:s,45:6,60:n},{1:[3]},{3:8,4:e,5:i,6:4,7:s,45:6,60:n},{3:9,4:e,5:i,6:4,7:s,45:6,60:n},{3:10,4:e,5:i,6:4,7:s,45:6,60:n},t([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,42,50,51,52,53,56,60],r,{8:11}),{46:12,61:[1,13]},{61:[2,50]},{1:[2,1]},{1:[2,2]},{1:[2,3]},{1:[2,4],4:a,5:o,6:30,9:14,10:16,11:18,12:19,13:20,16:c,17:l,19:h,22:u,24:d,25:p,26:y,27:f,28:m,29:g,32:31,33:_,35:S,37:k,38:b,42:T,45:6,50:E,51:v,52:x,53:D,56:C,60:n},{47:43,48:[1,44],63:$},t([48,63],[2,51]),t(A,[2,6]),{6:30,10:46,11:18,12:19,13:20,16:c,17:l,19:h,22:u,24:d,25:p,26:y,27:f,28:m,29:g,32:31,33:_,35:S,37:k,38:b,42:T,45:6,50:E,51:v,52:x,53:D,56:C,60:n},t(A,[2,8]),t(A,[2,9]),t(A,[2,10]),t(A,[2,11]),t(A,[2,12],{14:[1,47],15:[1,48]}),t(A,[2,16]),{18:[1,49]},t(A,[2,18],{20:[1,50]}),{23:[1,51]},t(A,[2,22]),t(A,[2,23]),t(A,[2,24]),t(A,[2,25]),{30:52,31:[1,53],58:[1,54],59:[1,55]},t(A,[2,28]),t(A,[2,29]),{34:[1,56]},{36:[1,57]},t(A,[2,32]),{39:[1,58],41:[1,59]},{43:[1,60]},t(L,[2,44],{57:[1,61]}),t(L,[2,45],{57:[1,62]}),t(A,[2,38]),t(A,[2,39]),t(A,[2,40]),t(A,[2,41]),t(I,[2,36]),{49:63,62:[1,64]},t(I,[2,53]),t(A,[2,7]),t(A,[2,13]),{13:65,24:d,56:C},t(A,[2,17]),t(O,r,{8:66}),{24:[1,67]},{24:[1,68]},{23:[1,69]},{24:[2,48]},{24:[2,49]},t(A,[2,30]),t(A,[2,31]),{40:[1,70]},{40:[1,71]},{44:[1,72]},{24:[1,73]},{24:[1,74]},{47:75,63:$},{63:[2,52]},t(A,[2,14],{14:[1,76]}),{4:a,5:o,6:30,9:14,10:16,11:18,12:19,13:20,16:c,17:l,19:h,21:[1,77],22:u,24:d,25:p,26:y,27:f,28:m,29:g,32:31,33:_,35:S,37:k,38:b,42:T,45:6,50:E,51:v,52:x,53:D,56:C,60:n},t(A,[2,20],{20:[1,78]}),{31:[1,79]},{24:[1,80]},t(A,[2,33]),t(A,[2,34]),t(A,[2,35]),t(L,[2,46]),t(L,[2,47]),t(I,[2,37]),t(A,[2,15]),t(A,[2,19]),t(O,r,{8:81}),t(A,[2,26]),t(A,[2,27]),{4:a,5:o,6:30,9:14,10:16,11:18,12:19,13:20,16:c,17:l,19:h,21:[1,82],22:u,24:d,25:p,26:y,27:f,28:m,29:g,32:31,33:_,35:S,37:k,38:b,42:T,45:6,50:E,51:v,52:x,53:D,56:C,60:n},t(A,[2,21])],defaultActions:{7:[2,50],8:[2,1],9:[2,2],10:[2,3],54:[2,48],55:[2,49],64:[2,52]},parseError:function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)},parse:function(t){var e=this,i=[0],s=[],n=[null],r=[],a=this.table,o="",c=0,l=0,h=2,u=1,d=r.slice.call(arguments,1),p=Object.create(this.lexer),y={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(y.yy[f]=this.yy[f]);p.setInput(t,y.yy),y.yy.lexer=p,y.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var m=p.yylloc;r.push(m);var g=p.options&&p.options.ranges;function _(){var t;return"number"!=typeof(t=s.pop()||p.lex()||u)&&(t instanceof Array&&(t=(s=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var S,k,b,T,E,v,x,D,C={};;){if(k=i[i.length-1],this.defaultActions[k]?b=this.defaultActions[k]:(null==S&&(S=_()),b=a[k]&&a[k][S]),void 0===b||!b.length||!b[0]){var $="";for(E in D=[],a[k])this.terminals_[E]&&E>h&&D.push("'"+this.terminals_[E]+"'");$=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+D.join(", ")+", got '"+(this.terminals_[S]||S)+"'":"Parse error on line "+(c+1)+": Unexpected "+(S==u?"end of input":"'"+(this.terminals_[S]||S)+"'"),this.parseError($,{text:p.match,token:this.terminals_[S]||S,line:p.yylineno,loc:m,expected:D})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+S);switch(b[0]){case 1:i.push(S),n.push(p.yytext),r.push(p.yylloc),i.push(b[1]),S=null,l=p.yyleng,o=p.yytext,c=p.yylineno,m=p.yylloc;break;case 2:if(v=this.productions_[b[1]][1],C.$=n[n.length-v],C._$={first_line:r[r.length-(v||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(v||1)].first_column,last_column:r[r.length-1].last_column},g&&(C._$.range=[r[r.length-(v||1)].range[0],r[r.length-1].range[1]]),void 0!==(T=this.performAction.apply(C,[o,l,c,y.yy,b[1],n,r].concat(d))))return T;v&&(i=i.slice(0,-1*v*2),n=n.slice(0,-1*v),r=r.slice(0,-1*v)),i.push(this.productions_[b[1]][0]),n.push(C.$),r.push(C._$),x=a[i[i.length-2]][i[i.length-1]],i.push(x);break;case 3:return!0}}return!0}},R={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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,i=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),i.length-1&&(this.yylineno-=i.length-1);var n=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===s.length?this.yylloc.first_column:0)+s[s.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var i,s,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,i,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;re[0].length)){if(e=i,s=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,n[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,i,s){switch(i){case 0:return 41;case 1:return 50;case 2:return 51;case 3:return 52;case 4:return 53;case 5:return this.begin("open_directive"),60;case 6:return this.begin("type_directive"),61;case 7:return this.popState(),this.begin("arg_directive"),48;case 8:return this.popState(),this.popState(),63;case 9:return 62;case 10:case 11:break;case 12:return 5;case 13:case 14:case 15:case 16:break;case 17:return this.pushState("SCALE"),17;case 18:return 18;case 19:this.popState();break;case 20:return this.begin("acc_title"),33;case 21:return this.popState(),"acc_title_value";case 22:return this.begin("acc_descr"),35;case 23:return this.popState(),"acc_descr_value";case 24:this.begin("acc_descr_multiline");break;case 25:this.popState();break;case 26:return"acc_descr_multiline_value";case 27:return this.pushState("CLASSDEF"),38;case 28:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 29:return this.popState(),this.pushState("CLASSDEFID"),39;case 30:return this.popState(),40;case 31:return this.pushState("CLASS"),42;case 32:return this.popState(),this.pushState("CLASS_STYLE"),43;case 33:return this.popState(),44;case 34:return this.pushState("SCALE"),17;case 35:return 18;case 36:this.popState();break;case 37:this.pushState("STATE");break;case 38:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 39:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),26;case 40:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),27;case 41:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 42:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),26;case 43:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),27;case 44:return 50;case 45:return 51;case 46:return 52;case 47:return 53;case 48:this.pushState("STATE_STRING");break;case 49:return this.pushState("STATE_ID"),"AS";case 50:return this.popState(),"ID";case 51:this.popState();break;case 52:return"STATE_DESCR";case 53:return 19;case 54:this.popState();break;case 55:return this.popState(),this.pushState("struct"),20;case 56:break;case 57:return this.popState(),21;case 58:break;case 59:return this.begin("NOTE"),29;case 60:return this.popState(),this.pushState("NOTE_ID"),58;case 61:return this.popState(),this.pushState("NOTE_ID"),59;case 62:this.popState(),this.pushState("FLOATING_NOTE");break;case 63:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 64:break;case 65:return"NOTE_TEXT";case 66:return this.popState(),"ID";case 67:return this.popState(),this.pushState("NOTE_TEXT"),24;case 68:return this.popState(),e.yytext=e.yytext.substr(2).trim(),31;case 69:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),31;case 70:case 71:return 7;case 72:return 16;case 73:return 56;case 74:return 24;case 75:return e.yytext=e.yytext.trim(),14;case 76:return 15;case 77:return 28;case 78:return 57;case 79:return 5;case 80:return"INVALID"}},rules:[/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*<>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[14,15],inclusive:!1},close_directive:{rules:[14,15],inclusive:!1},arg_directive:{rules:[8,9,14,15],inclusive:!1},type_directive:{rules:[7,8,14,15],inclusive:!1},open_directive:{rules:[6,14,15],inclusive:!1},struct:{rules:[14,15,27,31,37,44,45,46,47,56,57,58,59,73,74,75,76,77],inclusive:!1},FLOATING_NOTE_ID:{rules:[66],inclusive:!1},FLOATING_NOTE:{rules:[63,64,65],inclusive:!1},NOTE_TEXT:{rules:[68,69],inclusive:!1},NOTE_ID:{rules:[67],inclusive:!1},NOTE:{rules:[60,61,62],inclusive:!1},CLASS_STYLE:{rules:[33],inclusive:!1},CLASS:{rules:[32],inclusive:!1},CLASSDEFID:{rules:[30],inclusive:!1},CLASSDEF:{rules:[28,29],inclusive:!1},acc_descr_multiline:{rules:[25,26],inclusive:!1},acc_descr:{rules:[23],inclusive:!1},acc_title:{rules:[21],inclusive:!1},SCALE:{rules:[18,19,35,36],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[50],inclusive:!1},STATE_STRING:{rules:[51,52],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[14,15,38,39,40,41,42,43,48,49,53,54,55],inclusive:!1},ID:{rules:[14,15],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,10,11,12,13,15,16,17,20,22,24,27,31,34,37,55,59,70,71,72,73,74,75,76,78,79,80],inclusive:!0}}};function B(){this.yy={}}return N.lexer=R,B.prototype=N,N.Parser=B,new B}();d.parser=d;const p=d,y="TB",f="state",m="relation",g="default",_="divider";let S="LR",k=[],b={};let T={root:{relations:[],states:{},documents:{}}},E=T.root,v=0,x=0;const D=t=>JSON.parse(JSON.stringify(t)),C=(t,e,i)=>{if("relation"===e.stmt)C(t,e.state1,!0),C(t,e.state2,!1);else if("state"===e.stmt&&("[*]"===e.id?(e.id=i?t.id+"_start":t.id+"_end",e.start=i):e.id=e.id.trim()),e.doc){const t=[];let i,s=[];for(i=0;i0&&s.length>0){const i={stmt:"state",id:u(),type:"divider",doc:D(s)};t.push(D(i)),e.doc=t}e.doc.forEach((t=>C(e,t,!0)))}},$=function(e,i="default",s=null,n=null,r=null,a=null,o=null,h=null){const u=null==e?void 0:e.trim();if(void 0===E.states[u]?(c.info("Adding state ",u,n),E.states[u]={id:u,descriptions:[],type:i,doc:s,note:r,classes:[],styles:[],textStyles:[]}):(E.states[u].doc||(E.states[u].doc=s),E.states[u].type||(E.states[u].type=i)),n&&(c.info("Setting state description",u,n),"string"==typeof n&&R(u,n.trim()),"object"==typeof n&&n.forEach((t=>R(u,t.trim())))),r&&(E.states[u].note=r,E.states[u].note.text=l.sanitizeText(E.states[u].note.text,t())),a){c.info("Setting state classes",u,a);("string"==typeof a?[a]:a).forEach((t=>w(u,t.trim())))}if(o){c.info("Setting state styles",u,o);("string"==typeof o?[o]:o).forEach((t=>F(u,t.trim())))}if(h){c.info("Setting state styles",u,o);("string"==typeof h?[h]:h).forEach((t=>P(u,t.trim())))}},A=function(t){T={root:{relations:[],states:{},documents:{}}},E=T.root,v=0,b={},t||h()},L=function(t){return E.states[t]};function I(t=""){let e=t;return"[*]"===t&&(v++,e=`start${v}`),e}function O(t="",e="default"){return"[*]"===t?"start":e}const N=function(e,i,s){if("object"==typeof e)!function(e,i,s){let n=I(e.id.trim()),r=O(e.id.trim(),e.type),a=I(i.id.trim()),o=O(i.id.trim(),i.type);$(n,r,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),$(a,o,i.doc,i.description,i.note,i.classes,i.styles,i.textStyles),E.relations.push({id1:n,id2:a,relationTitle:l.sanitizeText(s,t())})}(e,i,s);else{const n=I(e.trim()),r=O(e),a=function(t=""){let e=t;return"[*]"===t&&(v++,e=`end${v}`),e}(i.trim()),o=function(t="",e="default"){return"[*]"===t?"end":e}(i);$(n,r),$(a,o),E.relations.push({id1:n,id2:a,title:l.sanitizeText(s,t())})}},R=function(e,i){const s=E.states[e],n=i.startsWith(":")?i.replace(":","").trim():i;s.descriptions.push(l.sanitizeText(n,t()))},B=function(t,e=""){void 0===b[t]&&(b[t]={id:t,styles:[],textStyles:[]});const i=b[t];null!=e&&e.split(",").forEach((t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(t.match("color")){const t=e.replace("fill","bgFill").replace("color","fill");i.textStyles.push(t)}i.styles.push(e)}))},w=function(t,e){t.split(",").forEach((function(t){let i=L(t);if(void 0===i){const e=t.trim();$(e),i=L(e)}i.classes.push(e)}))},F=function(t,e){const i=L(t);void 0!==i&&i.textStyles.push(e)},P=function(t,e){const i=L(t);void 0!==i&&i.textStyles.push(e)},G={parseDirective:function(t,e,i){o.parseDirective(this,t,e,i)},getConfig:()=>t().state,addState:$,clear:A,getState:L,getStates:function(){return E.states},getRelations:function(){return E.relations},getClasses:function(){return b},getDirection:()=>S,addRelation:N,getDividerId:()=>(x++,"divider-id-"+x),setDirection:t=>{S=t},cleanupLabel:function(t){return":"===t.substring(0,1)?t.substr(2).trim():t.trim()},lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},logDocuments:function(){c.info("Documents = ",T)},getRootDoc:()=>k,setRootDoc:t=>{c.info("Setting root doc",t),k=t},getRootDocV2:()=>(C({id:"root"},{id:"root",doc:k},!0),{id:"root",doc:k}),extract:t=>{let e;e=t.doc?t.doc:t,c.info(e),A(!0),c.info("Extract",e),e.forEach((t=>{switch(t.stmt){case"state":$(t.id.trim(),t.type,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles);break;case"relation":N(t.state1,t.state2,t.description);break;case"classDef":B(t.id.trim(),t.classes);break;case"applyClass":w(t.id.trim(),t.styleClass)}}))},trimColon:t=>t&&":"===t[0]?t.substr(1).trim():t.trim(),getAccTitle:e,setAccTitle:i,getAccDescription:s,setAccDescription:n,addStyleClass:B,setCssClass:w,addDescription:R,setDiagramTitle:r,getDiagramTitle:a},j=t=>`\ndefs #statediagram-barbEnd {\n fill: ${t.transitionColor};\n stroke: ${t.transitionColor};\n }\ng.stateGroup text {\n fill: ${t.nodeBorder};\n stroke: none;\n font-size: 10px;\n}\ng.stateGroup text {\n fill: ${t.textColor};\n stroke: none;\n font-size: 10px;\n\n}\ng.stateGroup .state-title {\n font-weight: bolder;\n fill: ${t.stateLabelColor};\n}\n\ng.stateGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.stateGroup line {\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.transition {\n stroke: ${t.transitionColor};\n stroke-width: 1;\n fill: none;\n}\n\n.stateGroup .composit {\n fill: ${t.background};\n border-bottom: 1px\n}\n\n.stateGroup .alt-composit {\n fill: #e0e0e0;\n border-bottom: 1px\n}\n\n.state-note {\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n\n text {\n fill: ${t.noteTextColor};\n stroke: none;\n font-size: 10px;\n }\n}\n\n.stateLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.edgeLabel .label rect {\n fill: ${t.labelBackgroundColor};\n opacity: 0.5;\n}\n.edgeLabel .label text {\n fill: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n.label div .edgeLabel {\n color: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n\n.stateLabel text {\n fill: ${t.stateLabelColor};\n font-size: 10px;\n font-weight: bold;\n}\n\n.node circle.state-start {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node .fork-join {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node circle.state-end {\n fill: ${t.innerEndBackground};\n stroke: ${t.background};\n stroke-width: 1.5\n}\n.end-state-inner {\n fill: ${t.compositeBackground||t.background};\n // stroke: ${t.background};\n stroke-width: 1.5\n}\n\n.node rect {\n fill: ${t.stateBkg||t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n.node polygon {\n fill: ${t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};;\n stroke-width: 1px;\n}\n#statediagram-barbEnd {\n fill: ${t.lineColor};\n}\n\n.statediagram-cluster rect {\n fill: ${t.compositeTitleBackground};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n\n.cluster-label, .nodeLabel {\n color: ${t.stateLabelColor};\n}\n\n.statediagram-cluster rect.outer {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state .divider {\n stroke: ${t.stateBorder||t.nodeBorder};\n}\n\n.statediagram-state .title-state {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-cluster.statediagram-cluster .inner {\n fill: ${t.compositeBackground||t.background};\n}\n.statediagram-cluster.statediagram-cluster-alt .inner {\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.statediagram-cluster .inner {\n rx:0;\n ry:0;\n}\n\n.statediagram-state rect.basic {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state rect.divider {\n stroke-dasharray: 10,10;\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.note-edge {\n stroke-dasharray: 5;\n}\n\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n\n.statediagram-note text {\n fill: ${t.noteTextColor};\n}\n\n.statediagram-note .nodeLabel {\n color: ${t.noteTextColor};\n}\n.statediagram .edgeLabel {\n color: red; // ${t.noteTextColor};\n}\n\n#dependencyStart, #dependencyEnd {\n fill: ${t.lineColor};\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.statediagramTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`;export{g as D,m as S,_ as a,f as b,y as c,G as d,p,j as s}; diff --git a/assets/styles-40ddcbf3.5ed229ca.js b/assets/styles-40ddcbf3.551e5741.js similarity index 96% rename from assets/styles-40ddcbf3.5ed229ca.js rename to assets/styles-40ddcbf3.551e5741.js index 9f11d2da3..f93a91817 100644 --- a/assets/styles-40ddcbf3.5ed229ca.js +++ b/assets/styles-40ddcbf3.551e5741.js @@ -1 +1 @@ -import{i as e,G as t}from"./layout.2f099f66.js";import{_ as n,$ as r,X as l,p as a,l as o,q as s,c as i,j as c,r as d,o as p,h as b,y as f,t as w,a0 as u}from"./mermaid.core.a66200b0.js";import{f as g}from"./flowDb-a707052f.485b60ac.js";import{r as h}from"./index-05087a90.4347f31d.js";import{s as y}from"./selectAll.11c20240.js";const k=(e,t)=>n.lang.round(r.parse(e)[t]);function x(e,t){return!!e.children(t).length}function m(e){return S(e.v)+":"+S(e.w)+":"+S(e.name)}var v=/:/g;function S(e){return e?String(e).replace(v,"\\:"):""}function T(e,t){t&&e.attr("style",t)}function _(e,t,n){t&&e.attr("class",t).attr("class",n+" "+e.attr("class"))}function $(t,n){var r=n.graph();if(e(r)){var a=r.transition;if(l(a))return a(t)}return t}function C(e,t){var n=e.append("foreignObject").attr("width","100000"),r=n.append("xhtml:div");r.attr("xmlns","http://www.w3.org/1999/xhtml");var l=t.label;switch(typeof l){case"function":r.insert(l);break;case"object":r.insert((function(){return l}));break;default:r.html(l)}T(r,t.labelStyle),r.style("display","inline-block"),r.style("white-space","nowrap");var a=r.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}const E={},A=function(e,t,n,r,l,d){const p=r.select(`[id="${n}"]`);Object.keys(e).forEach((function(n){const r=e[n];let b="default";r.classes.length>0&&(b=r.classes.join(" ")),b+=" flowchart-label";const f=a(r.styles);let w,u=void 0!==r.text?r.text:r.id;if(o.info("vertex",r,r.labelType),"markdown"===r.labelType)o.info("vertex",r,r.labelType);else if(s(i().flowchart.htmlLabels)){const e={label:u.replace(/fa[blrs]?:fa-[\w-]+/g,(e=>``))};w=C(p,e).node(),w.parentNode.removeChild(w)}else{const e=l.createElementNS("http://www.w3.org/2000/svg","text");e.setAttribute("style",f.labelStyle.replace("color:","fill:"));const t=u.split(c.lineBreakRegex);for(const n of t){const t=l.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","1"),t.textContent=n,e.appendChild(t)}w=e}let g=0,h="";switch(r.type){case"round":g=5,h="rect";break;case"square":h="rect";break;case"diamond":h="question";break;case"hexagon":h="hexagon";break;case"odd":h="rect_left_inv_arrow";break;case"lean_right":h="lean_right";break;case"lean_left":h="lean_left";break;case"trapezoid":h="trapezoid";break;case"inv_trapezoid":h="inv_trapezoid";break;case"odd_right":h="rect_left_inv_arrow";break;case"circle":h="circle";break;case"ellipse":h="ellipse";break;case"stadium":h="stadium";break;case"subroutine":h="subroutine";break;case"cylinder":h="cylinder";break;case"group":h="rect";break;case"doublecircle":h="doublecircle";break;default:h="rect"}t.setNode(r.id,{labelStyle:f.labelStyle,shape:h,labelText:u,labelType:r.labelType,rx:g,ry:g,class:b,style:f.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:"group"===r.type?500:void 0,dir:r.dir,type:r.type,props:r.props,padding:i().flowchart.padding}),o.info("setNode",{labelStyle:f.labelStyle,labelType:r.labelType,shape:h,labelText:u,rx:g,ry:g,class:b,style:f.style,id:r.id,domId:d.db.lookUpDomId(r.id),width:"group"===r.type?500:void 0,type:r.type,dir:r.dir,props:r.props,padding:i().flowchart.padding})}))},B=function(e,t,n){o.info("abc78 edges = ",e);let r,l,s=0,i={};if(void 0!==e.defaultStyle){const t=a(e.defaultStyle);r=t.style,l=t.labelStyle}e.forEach((function(n){s++;const b="L-"+n.start+"-"+n.end;void 0===i[b]?(i[b]=0,o.info("abc78 new entry",b,i[b])):(i[b]++,o.info("abc78 new entry",b,i[b]));let f=b+"-"+i[b];o.info("abc78 new link id to be used is",b,f,i[b]);const w="LS-"+n.start,u="LE-"+n.end,g={style:"",labelStyle:""};switch(g.minlen=n.length||1,"arrow_open"===n.type?g.arrowhead="none":g.arrowhead="normal",g.arrowTypeStart="arrow_open",g.arrowTypeEnd="arrow_open",n.type){case"double_arrow_cross":g.arrowTypeStart="arrow_cross";case"arrow_cross":g.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":g.arrowTypeStart="arrow_point";case"arrow_point":g.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":g.arrowTypeStart="arrow_circle";case"arrow_circle":g.arrowTypeEnd="arrow_circle"}let h="",y="";switch(n.stroke){case"normal":h="fill:none;",void 0!==r&&(h=r),void 0!==l&&(y=l),g.thickness="normal",g.pattern="solid";break;case"dotted":g.thickness="normal",g.pattern="dotted",g.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":g.thickness="thick",g.pattern="solid",g.style="stroke-width: 3.5px;fill:none;";break;case"invisible":g.thickness="invisible",g.pattern="solid",g.style="stroke-width: 0;fill:none;"}if(void 0!==n.style){const e=a(n.style);h=e.style,y=e.labelStyle}g.style=g.style+=h,g.labelStyle=g.labelStyle+=y,void 0!==n.interpolate?g.curve=d(n.interpolate,p):void 0!==e.defaultInterpolate?g.curve=d(e.defaultInterpolate,p):g.curve=d(E.curve,p),void 0===n.text?void 0!==n.style&&(g.arrowheadStyle="fill: #333"):(g.arrowheadStyle="fill: #333",g.labelpos="c"),g.labelType=n.labelType,g.label=n.text.replace(c.lineBreakRegex,"\n"),void 0===n.style&&(g.style=g.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),g.labelStyle=g.labelStyle.replace("color:","fill:"),g.id=f,g.classes="flowchart-link "+w+" "+u,t.setEdge(n.start,n.end,g,s)}))},L={setConf:function(e){const t=Object.keys(e);for(const n of t)E[n]=e[n]},addVertices:A,addEdges:B,getClasses:function(e,t){o.info("Extracting classes"),t.db.clear();try{return t.parse(e),t.db.getClasses()}catch(n){return}},draw:async function(e,n,r,l){o.info("Drawing flowchart"),l.db.clear(),g.setGen("gen-2"),l.parser.parse(e);let a=l.db.getDirection();void 0===a&&(a="TD");const{securityLevel:s,flowchart:c}=i(),d=c.nodeSpacing||50,p=c.rankSpacing||50;let u;"sandbox"===s&&(u=b("#i"+n));const k=b("sandbox"===s?u.nodes()[0].contentDocument.body:"body"),x="sandbox"===s?u.nodes()[0].contentDocument:document,m=new t({multigraph:!0,compound:!0}).setGraph({rankdir:a,nodesep:d,ranksep:p,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let v;const S=l.db.getSubGraphs();o.info("Subgraphs - ",S);for(let t=S.length-1;t>=0;t--)v=S[t],o.info("Subgraph - ",v),l.db.addVertex(v.id,{text:v.title,type:v.labelType},"group",void 0,v.classes,v.dir);const T=l.db.getVertices(),_=l.db.getEdges();o.info("Edges",_);let $=0;for($=S.length-1;$>=0;$--){v=S[$],y("cluster").append("text");for(let e=0;e`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${((e,t)=>{const n=k,r=n(e,"r"),l=n(e,"g"),a=n(e,"b");return u(r,l,a,t)})(e.edgeLabelBackground,.5)};\n // background-color: \n }\n\n .cluster rect {\n fill: ${e.clusterBkg};\n stroke: ${e.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`;export{T as a,C as b,$ as c,_ as d,m as e,L as f,N as g,x as i}; +import{i as e,G as t}from"./layout.02c3e151.js";import{_ as n,$ as r,X as l,p as a,l as o,q as s,c as i,j as c,r as d,o as p,h as b,y as f,t as w,a0 as u}from"./mermaid.core.3a590193.js";import{f as g}from"./flowDb-a707052f.baad4ae4.js";import{r as h}from"./index-05087a90.017bdfe5.js";import{s as y}from"./selectAll.256eca5b.js";const k=(e,t)=>n.lang.round(r.parse(e)[t]);function x(e,t){return!!e.children(t).length}function m(e){return S(e.v)+":"+S(e.w)+":"+S(e.name)}var v=/:/g;function S(e){return e?String(e).replace(v,"\\:"):""}function T(e,t){t&&e.attr("style",t)}function _(e,t,n){t&&e.attr("class",t).attr("class",n+" "+e.attr("class"))}function $(t,n){var r=n.graph();if(e(r)){var a=r.transition;if(l(a))return a(t)}return t}function C(e,t){var n=e.append("foreignObject").attr("width","100000"),r=n.append("xhtml:div");r.attr("xmlns","http://www.w3.org/1999/xhtml");var l=t.label;switch(typeof l){case"function":r.insert(l);break;case"object":r.insert((function(){return l}));break;default:r.html(l)}T(r,t.labelStyle),r.style("display","inline-block"),r.style("white-space","nowrap");var a=r.node().getBoundingClientRect();return n.attr("width",a.width).attr("height",a.height),n}const E={},A=function(e,t,n,r,l,d){const p=r.select(`[id="${n}"]`);Object.keys(e).forEach((function(n){const r=e[n];let b="default";r.classes.length>0&&(b=r.classes.join(" ")),b+=" flowchart-label";const f=a(r.styles);let w,u=void 0!==r.text?r.text:r.id;if(o.info("vertex",r,r.labelType),"markdown"===r.labelType)o.info("vertex",r,r.labelType);else if(s(i().flowchart.htmlLabels)){const e={label:u.replace(/fa[blrs]?:fa-[\w-]+/g,(e=>``))};w=C(p,e).node(),w.parentNode.removeChild(w)}else{const e=l.createElementNS("http://www.w3.org/2000/svg","text");e.setAttribute("style",f.labelStyle.replace("color:","fill:"));const t=u.split(c.lineBreakRegex);for(const n of t){const t=l.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),t.setAttribute("dy","1em"),t.setAttribute("x","1"),t.textContent=n,e.appendChild(t)}w=e}let g=0,h="";switch(r.type){case"round":g=5,h="rect";break;case"square":h="rect";break;case"diamond":h="question";break;case"hexagon":h="hexagon";break;case"odd":h="rect_left_inv_arrow";break;case"lean_right":h="lean_right";break;case"lean_left":h="lean_left";break;case"trapezoid":h="trapezoid";break;case"inv_trapezoid":h="inv_trapezoid";break;case"odd_right":h="rect_left_inv_arrow";break;case"circle":h="circle";break;case"ellipse":h="ellipse";break;case"stadium":h="stadium";break;case"subroutine":h="subroutine";break;case"cylinder":h="cylinder";break;case"group":h="rect";break;case"doublecircle":h="doublecircle";break;default:h="rect"}t.setNode(r.id,{labelStyle:f.labelStyle,shape:h,labelText:u,labelType:r.labelType,rx:g,ry:g,class:b,style:f.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:"group"===r.type?500:void 0,dir:r.dir,type:r.type,props:r.props,padding:i().flowchart.padding}),o.info("setNode",{labelStyle:f.labelStyle,labelType:r.labelType,shape:h,labelText:u,rx:g,ry:g,class:b,style:f.style,id:r.id,domId:d.db.lookUpDomId(r.id),width:"group"===r.type?500:void 0,type:r.type,dir:r.dir,props:r.props,padding:i().flowchart.padding})}))},B=function(e,t,n){o.info("abc78 edges = ",e);let r,l,s=0,i={};if(void 0!==e.defaultStyle){const t=a(e.defaultStyle);r=t.style,l=t.labelStyle}e.forEach((function(n){s++;const b="L-"+n.start+"-"+n.end;void 0===i[b]?(i[b]=0,o.info("abc78 new entry",b,i[b])):(i[b]++,o.info("abc78 new entry",b,i[b]));let f=b+"-"+i[b];o.info("abc78 new link id to be used is",b,f,i[b]);const w="LS-"+n.start,u="LE-"+n.end,g={style:"",labelStyle:""};switch(g.minlen=n.length||1,"arrow_open"===n.type?g.arrowhead="none":g.arrowhead="normal",g.arrowTypeStart="arrow_open",g.arrowTypeEnd="arrow_open",n.type){case"double_arrow_cross":g.arrowTypeStart="arrow_cross";case"arrow_cross":g.arrowTypeEnd="arrow_cross";break;case"double_arrow_point":g.arrowTypeStart="arrow_point";case"arrow_point":g.arrowTypeEnd="arrow_point";break;case"double_arrow_circle":g.arrowTypeStart="arrow_circle";case"arrow_circle":g.arrowTypeEnd="arrow_circle"}let h="",y="";switch(n.stroke){case"normal":h="fill:none;",void 0!==r&&(h=r),void 0!==l&&(y=l),g.thickness="normal",g.pattern="solid";break;case"dotted":g.thickness="normal",g.pattern="dotted",g.style="fill:none;stroke-width:2px;stroke-dasharray:3;";break;case"thick":g.thickness="thick",g.pattern="solid",g.style="stroke-width: 3.5px;fill:none;";break;case"invisible":g.thickness="invisible",g.pattern="solid",g.style="stroke-width: 0;fill:none;"}if(void 0!==n.style){const e=a(n.style);h=e.style,y=e.labelStyle}g.style=g.style+=h,g.labelStyle=g.labelStyle+=y,void 0!==n.interpolate?g.curve=d(n.interpolate,p):void 0!==e.defaultInterpolate?g.curve=d(e.defaultInterpolate,p):g.curve=d(E.curve,p),void 0===n.text?void 0!==n.style&&(g.arrowheadStyle="fill: #333"):(g.arrowheadStyle="fill: #333",g.labelpos="c"),g.labelType=n.labelType,g.label=n.text.replace(c.lineBreakRegex,"\n"),void 0===n.style&&(g.style=g.style||"stroke: #333; stroke-width: 1.5px;fill:none;"),g.labelStyle=g.labelStyle.replace("color:","fill:"),g.id=f,g.classes="flowchart-link "+w+" "+u,t.setEdge(n.start,n.end,g,s)}))},L={setConf:function(e){const t=Object.keys(e);for(const n of t)E[n]=e[n]},addVertices:A,addEdges:B,getClasses:function(e,t){o.info("Extracting classes"),t.db.clear();try{return t.parse(e),t.db.getClasses()}catch(n){return}},draw:async function(e,n,r,l){o.info("Drawing flowchart"),l.db.clear(),g.setGen("gen-2"),l.parser.parse(e);let a=l.db.getDirection();void 0===a&&(a="TD");const{securityLevel:s,flowchart:c}=i(),d=c.nodeSpacing||50,p=c.rankSpacing||50;let u;"sandbox"===s&&(u=b("#i"+n));const k=b("sandbox"===s?u.nodes()[0].contentDocument.body:"body"),x="sandbox"===s?u.nodes()[0].contentDocument:document,m=new t({multigraph:!0,compound:!0}).setGraph({rankdir:a,nodesep:d,ranksep:p,marginx:0,marginy:0}).setDefaultEdgeLabel((function(){return{}}));let v;const S=l.db.getSubGraphs();o.info("Subgraphs - ",S);for(let t=S.length-1;t>=0;t--)v=S[t],o.info("Subgraph - ",v),l.db.addVertex(v.id,{text:v.title,type:v.labelType},"group",void 0,v.classes,v.dir);const T=l.db.getVertices(),_=l.db.getEdges();o.info("Edges",_);let $=0;for($=S.length-1;$>=0;$--){v=S[$],y("cluster").append("text");for(let e=0;e`.label {\n font-family: ${e.fontFamily};\n color: ${e.nodeTextColor||e.textColor};\n }\n .cluster-label text {\n fill: ${e.titleColor};\n }\n .cluster-label span,p {\n color: ${e.titleColor};\n }\n\n .label text,span,p {\n fill: ${e.nodeTextColor||e.textColor};\n color: ${e.nodeTextColor||e.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${e.mainBkg};\n stroke: ${e.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${e.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${e.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${e.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${e.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${e.edgeLabelBackground};\n fill: ${e.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${((e,t)=>{const n=k,r=n(e,"r"),l=n(e,"g"),a=n(e,"b");return u(r,l,a,t)})(e.edgeLabelBackground,.5)};\n // background-color: \n }\n\n .cluster rect {\n fill: ${e.clusterBkg};\n stroke: ${e.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${e.titleColor};\n }\n\n .cluster span,p {\n color: ${e.titleColor};\n }\n /* .cluster div {\n color: ${e.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${e.fontFamily};\n font-size: 12px;\n background: ${e.tertiaryColor};\n border: 1px solid ${e.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${e.textColor};\n }\n`;export{T as a,C as b,$ as c,_ as d,m as e,L as f,N as g,x as i}; diff --git a/assets/svgDraw-6750006d.4f7863f3.js b/assets/svgDraw-6750006d.f814d75b.js similarity index 97% rename from assets/svgDraw-6750006d.4f7863f3.js rename to assets/svgDraw-6750006d.f814d75b.js index 15b781d50..32eb4c263 100644 --- a/assets/svgDraw-6750006d.4f7863f3.js +++ b/assets/svgDraw-6750006d.f814d75b.js @@ -1 +1 @@ -import{l as t,a5 as e,y as i,a7 as a}from"./mermaid.core.a66200b0.js";import{l as n}from"./line.f17bed9e.js";let r=0;const d=function(t){let e=t.id;return t.type&&(e+="<"+t.type+">"),e},s=function(t){let e="",i="",n="",r="",d=t.substring(0,1),s=t.substring(t.length-1,t.length);d.match(/[#+~-]/)&&(r=d);let o=/[\s\w)~]/;s.match(o)||(i=l(s));const c=""===r?0:1;let p=""===i?t.length:t.length-1;const g=(t=t.substring(c,p)).indexOf("("),h=t.indexOf(")");if(g>1&&h>g&&h<=t.length){let d=t.substring(0,g).trim();const s=t.substring(g+1,h);if(e=r+d+"("+a(s.trim())+")",h0&&(T+=i.cssClasses.join(" "));const B=l.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",m.width+2*a.padding).attr("height",m.height+a.padding+.5*a.dividerMargin).attr("class",T).node().getBBox().width;return c.node().childNodes.forEach((function(t){t.setAttribute("x",(B-t.getBBox().width)/2)})),i.tooltip&&c.insert("title").text(i.tooltip),y.attr("x2",B),b.attr("x2",B),s.width=B,s.height=m.height+a.padding+.5*a.dividerMargin,s},drawEdge:function(a,d,s,o,l){const c=function(t){switch(t){case l.db.relationType.AGGREGATION:return"aggregation";case l.db.relationType.EXTENSION:return"extension";case l.db.relationType.COMPOSITION:return"composition";case l.db.relationType.DEPENDENCY:return"dependency";case l.db.relationType.LOLLIPOP:return"lollipop"}};d.points=d.points.filter((t=>!Number.isNaN(t.y)));const p=d.points,g=n().x((function(t){return t.x})).y((function(t){return t.y})).curve(e),h=a.append("path").attr("d",g(p)).attr("id","edge"+r).attr("class","relation");let x,y,u="";o.arrowMarkerAbsolute&&(u=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,u=u.replace(/\(/g,"\\("),u=u.replace(/\)/g,"\\)")),1==s.relation.lineType&&h.attr("class","relation dashed-line"),10==s.relation.lineType&&h.attr("class","relation dotted-line"),"none"!==s.relation.type1&&h.attr("marker-start","url("+u+"#"+c(s.relation.type1)+"Start)"),"none"!==s.relation.type2&&h.attr("marker-end","url("+u+"#"+c(s.relation.type2)+"End)");const f=d.points.length;let b,w,m,T,B=i.calcLabelPosition(d.points);if(x=B.x,y=B.y,f%2!=0&&f>1){let e=i.calcCardinalityPosition("none"!==s.relation.type1,d.points,d.points[0]),a=i.calcCardinalityPosition("none"!==s.relation.type2,d.points,d.points[f-1]);t.debug("cardinality_1_point "+JSON.stringify(e)),t.debug("cardinality_2_point "+JSON.stringify(a)),b=e.x,w=e.y,m=a.x,T=a.y}if(void 0!==s.title){const t=a.append("g").attr("class","classLabel"),e=t.append("text").attr("class","label").attr("x",x).attr("y",y).attr("fill","red").attr("text-anchor","middle").text(s.title);window.label=e;const i=e.node().getBBox();t.insert("rect",":first-child").attr("class","box").attr("x",i.x-o.padding/2).attr("y",i.y-o.padding/2).attr("width",i.width+o.padding).attr("height",i.height+o.padding)}if(t.info("Rendering relation "+JSON.stringify(s)),void 0!==s.relationTitle1&&"none"!==s.relationTitle1){a.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",b).attr("y",w).attr("fill","black").attr("font-size","6").text(s.relationTitle1)}if(void 0!==s.relationTitle2&&"none"!==s.relationTitle2){a.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",m).attr("y",T).attr("fill","black").attr("font-size","6").text(s.relationTitle2)}r++},drawNote:function(e,i,a,n){t.debug("Rendering note ",i,a);const r=i.id,d={id:r,text:i.text,width:0,height:0},s=e.append("g").attr("id",r).attr("class","classGroup");let o=s.append("text").attr("y",a.textHeight+a.padding).attr("x",0);const l=JSON.parse(`"${i.text}"`).split("\n");l.forEach((function(e){t.debug(`Adding line: ${e}`),o.append("tspan").text(e).attr("class","title").attr("dy",a.textHeight)}));const c=s.node().getBBox(),p=s.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",c.width+2*a.padding).attr("height",c.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin).node().getBBox().width;return o.node().childNodes.forEach((function(t){t.setAttribute("x",(p-t.getBBox().width)/2)})),d.width=p,d.height=c.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin,d},parseMember:s};export{s as p,c as s}; +import{l as t,a5 as e,y as i,a7 as a}from"./mermaid.core.3a590193.js";import{l as n}from"./line.53b161c2.js";let r=0;const d=function(t){let e=t.id;return t.type&&(e+="<"+t.type+">"),e},s=function(t){let e="",i="",n="",r="",d=t.substring(0,1),s=t.substring(t.length-1,t.length);d.match(/[#+~-]/)&&(r=d);let o=/[\s\w)~]/;s.match(o)||(i=l(s));const c=""===r?0:1;let p=""===i?t.length:t.length-1;const g=(t=t.substring(c,p)).indexOf("("),h=t.indexOf(")");if(g>1&&h>g&&h<=t.length){let d=t.substring(0,g).trim();const s=t.substring(g+1,h);if(e=r+d+"("+a(s.trim())+")",h0&&(T+=i.cssClasses.join(" "));const B=l.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",m.width+2*a.padding).attr("height",m.height+a.padding+.5*a.dividerMargin).attr("class",T).node().getBBox().width;return c.node().childNodes.forEach((function(t){t.setAttribute("x",(B-t.getBBox().width)/2)})),i.tooltip&&c.insert("title").text(i.tooltip),y.attr("x2",B),b.attr("x2",B),s.width=B,s.height=m.height+a.padding+.5*a.dividerMargin,s},drawEdge:function(a,d,s,o,l){const c=function(t){switch(t){case l.db.relationType.AGGREGATION:return"aggregation";case l.db.relationType.EXTENSION:return"extension";case l.db.relationType.COMPOSITION:return"composition";case l.db.relationType.DEPENDENCY:return"dependency";case l.db.relationType.LOLLIPOP:return"lollipop"}};d.points=d.points.filter((t=>!Number.isNaN(t.y)));const p=d.points,g=n().x((function(t){return t.x})).y((function(t){return t.y})).curve(e),h=a.append("path").attr("d",g(p)).attr("id","edge"+r).attr("class","relation");let x,y,u="";o.arrowMarkerAbsolute&&(u=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,u=u.replace(/\(/g,"\\("),u=u.replace(/\)/g,"\\)")),1==s.relation.lineType&&h.attr("class","relation dashed-line"),10==s.relation.lineType&&h.attr("class","relation dotted-line"),"none"!==s.relation.type1&&h.attr("marker-start","url("+u+"#"+c(s.relation.type1)+"Start)"),"none"!==s.relation.type2&&h.attr("marker-end","url("+u+"#"+c(s.relation.type2)+"End)");const f=d.points.length;let b,w,m,T,B=i.calcLabelPosition(d.points);if(x=B.x,y=B.y,f%2!=0&&f>1){let e=i.calcCardinalityPosition("none"!==s.relation.type1,d.points,d.points[0]),a=i.calcCardinalityPosition("none"!==s.relation.type2,d.points,d.points[f-1]);t.debug("cardinality_1_point "+JSON.stringify(e)),t.debug("cardinality_2_point "+JSON.stringify(a)),b=e.x,w=e.y,m=a.x,T=a.y}if(void 0!==s.title){const t=a.append("g").attr("class","classLabel"),e=t.append("text").attr("class","label").attr("x",x).attr("y",y).attr("fill","red").attr("text-anchor","middle").text(s.title);window.label=e;const i=e.node().getBBox();t.insert("rect",":first-child").attr("class","box").attr("x",i.x-o.padding/2).attr("y",i.y-o.padding/2).attr("width",i.width+o.padding).attr("height",i.height+o.padding)}if(t.info("Rendering relation "+JSON.stringify(s)),void 0!==s.relationTitle1&&"none"!==s.relationTitle1){a.append("g").attr("class","cardinality").append("text").attr("class","type1").attr("x",b).attr("y",w).attr("fill","black").attr("font-size","6").text(s.relationTitle1)}if(void 0!==s.relationTitle2&&"none"!==s.relationTitle2){a.append("g").attr("class","cardinality").append("text").attr("class","type2").attr("x",m).attr("y",T).attr("fill","black").attr("font-size","6").text(s.relationTitle2)}r++},drawNote:function(e,i,a,n){t.debug("Rendering note ",i,a);const r=i.id,d={id:r,text:i.text,width:0,height:0},s=e.append("g").attr("id",r).attr("class","classGroup");let o=s.append("text").attr("y",a.textHeight+a.padding).attr("x",0);const l=JSON.parse(`"${i.text}"`).split("\n");l.forEach((function(e){t.debug(`Adding line: ${e}`),o.append("tspan").text(e).attr("class","title").attr("dy",a.textHeight)}));const c=s.node().getBBox(),p=s.insert("rect",":first-child").attr("x",0).attr("y",0).attr("width",c.width+2*a.padding).attr("height",c.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin).node().getBBox().width;return o.node().childNodes.forEach((function(t){t.setAttribute("x",(p-t.getBBox().width)/2)})),d.width=p,d.height=c.height+l.length*a.textHeight+a.padding+.5*a.dividerMargin,d},parseMember:s};export{s as p,c as s}; diff --git a/assets/svgDrawCommon-f26cad39.9f4c1d32.js b/assets/svgDrawCommon-f26cad39.447236df.js similarity index 95% rename from assets/svgDrawCommon-f26cad39.9f4c1d32.js rename to assets/svgDrawCommon-f26cad39.447236df.js index e077250c7..4fdcd5488 100644 --- a/assets/svgDrawCommon-f26cad39.9f4c1d32.js +++ b/assets/svgDrawCommon-f26cad39.447236df.js @@ -1 +1 @@ -import{n as t}from"./mermaid.core.a66200b0.js";const r=function(t,r){const a=t.append("rect");if(a.attr("x",r.x),a.attr("y",r.y),a.attr("fill",r.fill),a.attr("stroke",r.stroke),a.attr("width",r.width),a.attr("height",r.height),a.attr("rx",r.rx),a.attr("ry",r.ry),"undefined"!==r.attrs&&null!==r.attrs)for(let s in r.attrs)a.attr(s,r.attrs[s]);return"undefined"!==r.class&&a.attr("class",r.class),a},a=function(t,a){r(t,{x:a.startx,y:a.starty,width:a.stopx-a.startx,height:a.stopy-a.starty,fill:a.fill,stroke:a.stroke,class:"rect"}).lower()},s=function(t,r){const a=r.text.replace(//gi," "),s=t.append("text");s.attr("x",r.x),s.attr("y",r.y),s.attr("class","legend"),s.style("text-anchor",r.anchor),void 0!==r.class&&s.attr("class",r.class);const n=s.append("tspan");return n.attr("x",r.x+2*r.textMargin),n.text(a),s},n=function(r,a,s,n){const e=r.append("image");e.attr("x",a),e.attr("y",s);var i=t(n);e.attr("xlink:href",i)},e=function(r,a,s,n){const e=r.append("use");e.attr("x",a),e.attr("y",s);const i=t(n);e.attr("xlink:href","#"+i)},i=function(){return{x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}},o=function(){return{x:0,y:0,width:100,height:100,fill:void 0,anchor:void 0,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}};export{o as a,a as b,e as c,r as d,n as e,s as f,i as g}; +import{n as t}from"./mermaid.core.3a590193.js";const r=function(t,r){const a=t.append("rect");if(a.attr("x",r.x),a.attr("y",r.y),a.attr("fill",r.fill),a.attr("stroke",r.stroke),a.attr("width",r.width),a.attr("height",r.height),a.attr("rx",r.rx),a.attr("ry",r.ry),"undefined"!==r.attrs&&null!==r.attrs)for(let s in r.attrs)a.attr(s,r.attrs[s]);return"undefined"!==r.class&&a.attr("class",r.class),a},a=function(t,a){r(t,{x:a.startx,y:a.starty,width:a.stopx-a.startx,height:a.stopy-a.starty,fill:a.fill,stroke:a.stroke,class:"rect"}).lower()},s=function(t,r){const a=r.text.replace(//gi," "),s=t.append("text");s.attr("x",r.x),s.attr("y",r.y),s.attr("class","legend"),s.style("text-anchor",r.anchor),void 0!==r.class&&s.attr("class",r.class);const n=s.append("tspan");return n.attr("x",r.x+2*r.textMargin),n.text(a),s},n=function(r,a,s,n){const e=r.append("image");e.attr("x",a),e.attr("y",s);var i=t(n);e.attr("xlink:href",i)},e=function(r,a,s,n){const e=r.append("use");e.attr("x",a),e.attr("y",s);const i=t(n);e.attr("xlink:href","#"+i)},i=function(){return{x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}},o=function(){return{x:0,y:0,width:100,height:100,fill:void 0,anchor:void 0,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}};export{o as a,a as b,e as c,r as d,n as e,s as f,i as g}; diff --git a/assets/tcp.html.24c3bffb.js b/assets/tcp.html.6bfdc869.js similarity index 99% rename from assets/tcp.html.24c3bffb.js rename to assets/tcp.html.6bfdc869.js index 140df7e7f..c1c3719f8 100644 --- a/assets/tcp.html.24c3bffb.js +++ b/assets/tcp.html.6bfdc869.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as o,F as t,d as p,e as c}from"./app.755d843f.js";const r={},u=p('

    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.

    {\n  "acceptProxyProtocol": false,\n  "header": {\n    "type": "none"\n  }\n}\n
    1
    2
    3
    4
    5
    6

    acceptProxyProtocol: true | false

    Only used for inbound, indicating whether to accept the PROXY protocol.

    ',8),l=c("The "),i={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},d=c("PROXY protocol"),b=c(" is used to transmit the real source IP and port of the request. "),k=e("strong",null,"If you are not familiar with it, please ignore this item.",-1),q=p('

    Common reverse proxy software (such as HAProxy and Nginx) can be configured to send it, and VLESS fallbacks xver can also send it.

    When filled in as true, after the underlying TCP connection is established, the requesting party must first send PROXY protocol v1 or v2, otherwise the connection will be closed.

    The default value is false

    header: NoneHeaderObject | HttpHeaderobject

    Packet header obfuscation settings, the default value is NoneHeaderObject

    Tip

    HTTP obfuscation cannot be proxied by other HTTP servers (such as Nginx), but it can be proxied by VLESS fallbacks path.

    NoneHeaderObject

    No header obfuscation

    {\n  "type": "none"\n}\n
    1
    2
    3

    type: "none"

    Disable header obfuscation.

    HttpHeaderObject

    HTTP header obfuscation. The configuration must be the same between connecting inbound and outbound.

    {\n  "type": "http",\n  "request": {},\n  "response": {}\n}\n
    1
    2
    3
    4
    5

    type: "http"

    Enable HTTP header obfuscation.

    request: HTTPRequestObject

    HTTP request template.

    response: HTTPResponseObject

    HTTP response template.

    HTTPRequestObject

    {\n  "version": "1.1",\n  "method": "GET",\n  "path": ["/"],\n  "headers": {\n    "Host": ["www.baidu.com", "www.bing.com"],\n    "User-Agent": [\n      "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",\n      "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"\n    ],\n    "Accept-Encoding": ["gzip, deflate"],\n    "Connection": ["keep-alive"],\n    "Pragma": "no-cache"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    version: string

    HTTP version, the default value is "1.1"

    method: string

    The HTTP method, the default value is "GET"

    path: [ string ]

    paths, an array of strings. The default value is ["/"]. When there are multiple values, a value is chosen randomly for each request.

    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.

    HTTPResponseObject

    {\n  "version": "1.1",\n  "status": "200",\n  "reason": "OK",\n  "headers": {\n    "Content-Type": ["application/octet-stream", "video/mpeg"],\n    "Transfer-Encoding": ["chunked"],\n    "Connection": ["keep-alive"],\n    "Pragma": "no-cache"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    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.

    ',42);r.render=function(p,c){const r=n("OutboundLink");return s(),a(t,null,[u,e("p",null,[l,e("a",i,[d,o(r)]),b,k]),q],64)};export default r; +import{r as n,o as s,c as a,a as e,b as o,F as t,d as p,e as c}from"./app.48111a85.js";const r={},u=p('

    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.

    {\n  "acceptProxyProtocol": false,\n  "header": {\n    "type": "none"\n  }\n}\n
    1
    2
    3
    4
    5
    6

    acceptProxyProtocol: true | false

    Only used for inbound, indicating whether to accept the PROXY protocol.

    ',8),l=c("The "),i={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},d=c("PROXY protocol"),b=c(" is used to transmit the real source IP and port of the request. "),k=e("strong",null,"If you are not familiar with it, please ignore this item.",-1),q=p('

    Common reverse proxy software (such as HAProxy and Nginx) can be configured to send it, and VLESS fallbacks xver can also send it.

    When filled in as true, after the underlying TCP connection is established, the requesting party must first send PROXY protocol v1 or v2, otherwise the connection will be closed.

    The default value is false

    header: NoneHeaderObject | HttpHeaderobject

    Packet header obfuscation settings, the default value is NoneHeaderObject

    Tip

    HTTP obfuscation cannot be proxied by other HTTP servers (such as Nginx), but it can be proxied by VLESS fallbacks path.

    NoneHeaderObject

    No header obfuscation

    {\n  "type": "none"\n}\n
    1
    2
    3

    type: "none"

    Disable header obfuscation.

    HttpHeaderObject

    HTTP header obfuscation. The configuration must be the same between connecting inbound and outbound.

    {\n  "type": "http",\n  "request": {},\n  "response": {}\n}\n
    1
    2
    3
    4
    5

    type: "http"

    Enable HTTP header obfuscation.

    request: HTTPRequestObject

    HTTP request template.

    response: HTTPResponseObject

    HTTP response template.

    HTTPRequestObject

    {\n  "version": "1.1",\n  "method": "GET",\n  "path": ["/"],\n  "headers": {\n    "Host": ["www.baidu.com", "www.bing.com"],\n    "User-Agent": [\n      "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",\n      "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"\n    ],\n    "Accept-Encoding": ["gzip, deflate"],\n    "Connection": ["keep-alive"],\n    "Pragma": "no-cache"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    version: string

    HTTP version, the default value is "1.1"

    method: string

    The HTTP method, the default value is "GET"

    path: [ string ]

    paths, an array of strings. The default value is ["/"]. When there are multiple values, a value is chosen randomly for each request.

    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.

    HTTPResponseObject

    {\n  "version": "1.1",\n  "status": "200",\n  "reason": "OK",\n  "headers": {\n    "Content-Type": ["application/octet-stream", "video/mpeg"],\n    "Transfer-Encoding": ["chunked"],\n    "Connection": ["keep-alive"],\n    "Pragma": "no-cache"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    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.

    ',42);r.render=function(p,c){const r=n("OutboundLink");return s(),a(t,null,[u,e("p",null,[l,e("a",i,[d,o(r)]),b,k]),q],64)};export default r; diff --git a/assets/tcp.html.24b07eda.js b/assets/tcp.html.f1af1bd1.js similarity index 99% rename from assets/tcp.html.24b07eda.js rename to assets/tcp.html.f1af1bd1.js index b34cbfa1f..4863340bc 100644 --- a/assets/tcp.html.24b07eda.js +++ b/assets/tcp.html.f1af1bd1.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as o,F as e,d as t,e as c}from"./app.755d843f.js";const r={},u=t('

    TCP

    TCP 传输模式是目前推荐使用的传输模式之一.

    可以和各种协议有多种组合模式.

    TcpObject

    TcpObject 对应传输配置的 tcpSettings 项。

    {\n  "acceptProxyProtocol": false,\n  "header": {\n    "type": "none"\n  }\n}\n
    1
    2
    3
    4
    5
    6

    acceptProxyProtocol: true | false

    仅用于 inbound,指示是否接收 PROXY protocol。

    ',8),l={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},i=c("PROXY protocol"),k=c(" 专用于传递请求的真实来源 IP 和端口,"),b=p("strong",null,"若你不了解它,请先忽略该项",-1),d=c("。"),q=t('

    常见的反代软件(如 HAProxy、Nginx)都可以配置发送它,VLESS fallbacks xver 也可以发送它。

    填写 true 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2,否则连接会被关闭。

    默认值为 false

    header: NoneHeaderObject | HttpHeaderobject

    数据包头部伪装设置,默认值为 NoneHeaderObject

    提示

    HTTP 伪装无法被其它 HTTP 服务器(如 Nginx)分流,但可以被 VLESS fallbacks path 分流。

    NoneHeaderObject

    不进行伪装

    {\n  "type": "none"\n}\n
    1
    2
    3

    type: "none"

    指定不进行伪装

    HttpHeaderObject

    HTTP 伪装配置必须在对应的入站出站连接上同时配置,且内容必须一致。

    {\n  "type": "http",\n  "request": {},\n  "response": {}\n}\n
    1
    2
    3
    4
    5

    type: "http"

    指定进行 HTTP 伪装

    request: HTTPRequestObject

    HTTP 请求

    response: HTTPResponseObject

    HTTP 响应

    HTTPRequestObject

    {\n  "version": "1.1",\n  "method": "GET",\n  "path": ["/"],\n  "headers": {\n    "Host": ["www.baidu.com", "www.bing.com"],\n    "User-Agent": [\n      "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",\n      "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"\n    ],\n    "Accept-Encoding": ["gzip, deflate"],\n    "Connection": ["keep-alive"],\n    "Pragma": "no-cache"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    version: string

    HTTP 版本,默认值为 "1.1"

    method: string

    HTTP 方法,默认值为 "GET"

    path: [ string ]

    路径,一个字符串数组。默认值为 ["/"]。当有多个值时,每次请求随机选择一个值。

    headers: map{ string, [ string ]}

    HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是一个数组。

    每次请求会附上所有的键,并随机选择一个对应的值。默认值见上方示例。

    HTTPResponseObject

    {\n  "version": "1.1",\n  "status": "200",\n  "reason": "OK",\n  "headers": {\n    "Content-Type": ["application/octet-stream", "video/mpeg"],\n    "Transfer-Encoding": ["chunked"],\n    "Connection": ["keep-alive"],\n    "Pragma": "no-cache"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    version: string

    HTTP 版本,默认值为 "1.1"

    status: string

    HTTP 状态,默认值为 "200"

    reason: string

    HTTP 状态说明,默认值为 "OK"

    headers: map {string, [ string ]}

    HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是一个数组。

    每次请求会附上所有的键,并随机选择一个对应的值。默认值见上方示例。

    ',42);r.render=function(t,c){const r=n("OutboundLink");return s(),a(e,null,[u,p("p",null,[p("a",l,[i,o(r)]),k,b,d]),q],64)};export default r; +import{r as n,o as s,c as a,a as p,b as o,F as e,d as t,e as c}from"./app.48111a85.js";const r={},u=t('

    TCP

    TCP 传输模式是目前推荐使用的传输模式之一.

    可以和各种协议有多种组合模式.

    TcpObject

    TcpObject 对应传输配置的 tcpSettings 项。

    {\n  "acceptProxyProtocol": false,\n  "header": {\n    "type": "none"\n  }\n}\n
    1
    2
    3
    4
    5
    6

    acceptProxyProtocol: true | false

    仅用于 inbound,指示是否接收 PROXY protocol。

    ',8),l={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},i=c("PROXY protocol"),k=c(" 专用于传递请求的真实来源 IP 和端口,"),b=p("strong",null,"若你不了解它,请先忽略该项",-1),d=c("。"),q=t('

    常见的反代软件(如 HAProxy、Nginx)都可以配置发送它,VLESS fallbacks xver 也可以发送它。

    填写 true 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2,否则连接会被关闭。

    默认值为 false

    header: NoneHeaderObject | HttpHeaderobject

    数据包头部伪装设置,默认值为 NoneHeaderObject

    提示

    HTTP 伪装无法被其它 HTTP 服务器(如 Nginx)分流,但可以被 VLESS fallbacks path 分流。

    NoneHeaderObject

    不进行伪装

    {\n  "type": "none"\n}\n
    1
    2
    3

    type: "none"

    指定不进行伪装

    HttpHeaderObject

    HTTP 伪装配置必须在对应的入站出站连接上同时配置,且内容必须一致。

    {\n  "type": "http",\n  "request": {},\n  "response": {}\n}\n
    1
    2
    3
    4
    5

    type: "http"

    指定进行 HTTP 伪装

    request: HTTPRequestObject

    HTTP 请求

    response: HTTPResponseObject

    HTTP 响应

    HTTPRequestObject

    {\n  "version": "1.1",\n  "method": "GET",\n  "path": ["/"],\n  "headers": {\n    "Host": ["www.baidu.com", "www.bing.com"],\n    "User-Agent": [\n      "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36",\n      "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"\n    ],\n    "Accept-Encoding": ["gzip, deflate"],\n    "Connection": ["keep-alive"],\n    "Pragma": "no-cache"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    version: string

    HTTP 版本,默认值为 "1.1"

    method: string

    HTTP 方法,默认值为 "GET"

    path: [ string ]

    路径,一个字符串数组。默认值为 ["/"]。当有多个值时,每次请求随机选择一个值。

    headers: map{ string, [ string ]}

    HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是一个数组。

    每次请求会附上所有的键,并随机选择一个对应的值。默认值见上方示例。

    HTTPResponseObject

    {\n  "version": "1.1",\n  "status": "200",\n  "reason": "OK",\n  "headers": {\n    "Content-Type": ["application/octet-stream", "video/mpeg"],\n    "Transfer-Encoding": ["chunked"],\n    "Connection": ["keep-alive"],\n    "Pragma": "no-cache"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    version: string

    HTTP 版本,默认值为 "1.1"

    status: string

    HTTP 状态,默认值为 "200"

    reason: string

    HTTP 状态说明,默认值为 "OK"

    headers: map {string, [ string ]}

    HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是一个数组。

    每次请求会附上所有的键,并随机选择一个对应的值。默认值见上方示例。

    ',42);r.render=function(t,c){const r=n("OutboundLink");return s(),a(e,null,[u,p("p",null,[p("a",l,[i,o(r)]),k,b,d]),q],64)};export default r; diff --git a/assets/timeline-definition-d53f6d76.1b6ff628.js b/assets/timeline-definition-d53f6d76.be0df1ae.js similarity index 99% rename from assets/timeline-definition-d53f6d76.1b6ff628.js rename to assets/timeline-definition-d53f6d76.be0df1ae.js index 981b7da49..f07fa1134 100644 --- a/assets/timeline-definition-d53f6d76.1b6ff628.js +++ b/assets/timeline-definition-d53f6d76.be0df1ae.js @@ -1 +1 @@ -import{aG as t,aH as e,z as n,c as i,l as s,h as r,t as a,aI as o,aJ as c,aK as l}from"./mermaid.core.a66200b0.js";import{a as h}from"./arc.56fd4148.js";import"./constant.4f073c13.js";var d=function(){var t=function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n},e=[1,2],n=[1,5],i=[6,9,11,17,18,20,22,23,26,27,28],s=[1,15],r=[1,16],a=[1,17],o=[1,18],c=[1,19],l=[1,23],h=[1,24],d=[1,27],u=[4,6,9,11,17,18,20,22,23,26,27,28],p={trace:function(){},yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,directive:7,line:8,SPACE:9,statement:10,NEWLINE:11,openDirective:12,typeDirective:13,closeDirective:14,":":15,argDirective:16,title:17,acc_title:18,acc_title_value:19,acc_descr:20,acc_descr_value:21,acc_descr_multiline_value:22,section:23,period_statement:24,event_statement:25,period:26,event:27,open_directive:28,type_directive:29,arg_directive:30,close_directive:31,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",9:"SPACE",11:"NEWLINE",15:":",17:"title",18:"acc_title",19:"acc_title_value",20:"acc_descr",21:"acc_descr_value",22:"acc_descr_multiline_value",23:"section",26:"period",27:"event",28:"open_directive",29:"type_directive",30:"arg_directive",31:"close_directive"},productions_:[0,[3,3],[3,2],[5,0],[5,2],[8,2],[8,1],[8,1],[8,1],[7,4],[7,6],[10,1],[10,2],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[24,1],[25,1],[12,1],[13,1],[16,1],[14,1]],performAction:function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 3:this.$=[];break;case 4:r[o-1].push(r[o]),this.$=r[o-1];break;case 5:case 6:this.$=r[o];break;case 7:case 8:this.$=[];break;case 11:i.getCommonDb().setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 12:this.$=r[o].trim(),i.getCommonDb().setAccTitle(this.$);break;case 13:case 14:this.$=r[o].trim(),i.getCommonDb().setAccDescription(this.$);break;case 15:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 19:i.addTask(r[o],0,""),this.$=r[o];break;case 20:i.addEvent(r[o].substr(2)),this.$=r[o];break;case 21:i.parseDirective("%%{","open_directive");break;case 22:i.parseDirective(r[o],"type_directive");break;case 23:r[o]=r[o].trim().replace(/'/g,'"'),i.parseDirective(r[o],"arg_directive");break;case 24:i.parseDirective("}%%","close_directive","timeline")}},table:[{3:1,4:e,7:3,12:4,28:n},{1:[3]},t(i,[2,3],{5:6}),{3:7,4:e,7:3,12:4,28:n},{13:8,29:[1,9]},{29:[2,21]},{6:[1,10],7:22,8:11,9:[1,12],10:13,11:[1,14],12:4,17:s,18:r,20:a,22:o,23:c,24:20,25:21,26:l,27:h,28:n},{1:[2,2]},{14:25,15:[1,26],31:d},t([15,31],[2,22]),t(i,[2,8],{1:[2,1]}),t(i,[2,4]),{7:22,10:28,12:4,17:s,18:r,20:a,22:o,23:c,24:20,25:21,26:l,27:h,28:n},t(i,[2,6]),t(i,[2,7]),t(i,[2,11]),{19:[1,29]},{21:[1,30]},t(i,[2,14]),t(i,[2,15]),t(i,[2,16]),t(i,[2,17]),t(i,[2,18]),t(i,[2,19]),t(i,[2,20]),{11:[1,31]},{16:32,30:[1,33]},{11:[2,24]},t(i,[2,5]),t(i,[2,12]),t(i,[2,13]),t(u,[2,9]),{14:34,31:d},{31:[2,23]},{11:[1,35]},t(u,[2,10])],defaultActions:{5:[2,21],7:[2,2],27:[2,24],33:[2,23]},parseError:function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)},parse:function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,o="",c=0,l=0,h=2,d=1,u=r.slice.call(arguments,1),p=Object.create(this.lexer),y={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(y.yy[g]=this.yy[g]);p.setInput(t,y.yy),y.yy.lexer=p,y.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var f=p.yylloc;r.push(f);var m=p.options&&p.options.ranges;function _(){var t;return"number"!=typeof(t=i.pop()||p.lex()||d)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;for(var b,v,x,k,S,w,$,E,I={};;){if(v=n[n.length-1],this.defaultActions[v]?x=this.defaultActions[v]:(null==b&&(b=_()),x=a[v]&&a[v][b]),void 0===x||!x.length||!x[0]){var T="";for(S in E=[],a[v])this.terminals_[S]&&S>h&&E.push("'"+this.terminals_[S]+"'");T=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(c+1)+": Unexpected "+(b==d?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(T,{text:p.match,token:this.terminals_[b]||b,line:p.yylineno,loc:f,expected:E})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+v+", token: "+b);switch(x[0]){case 1:n.push(b),s.push(p.yytext),r.push(p.yylloc),n.push(x[1]),b=null,l=p.yyleng,o=p.yytext,c=p.yylineno,f=p.yylloc;break;case 2:if(w=this.productions_[x[1]][1],I.$=s[s.length-w],I._$={first_line:r[r.length-(w||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(w||1)].first_column,last_column:r[r.length-1].last_column},m&&(I._$.range=[r[r.length-(w||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(I,[o,l,c,y.yy,x[1],s,r].concat(u))))return k;w&&(n=n.slice(0,-1*w*2),s=s.slice(0,-1*w),r=r.slice(0,-1*w)),n.push(this.productions_[x[1]][0]),s.push(I.$),r.push(I._$),$=a[n[n.length-2]][n[n.length-1]],n.push($);break;case 3:return!0}}return!0}},y={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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 i=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 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:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),28;case 1:return this.begin("type_directive"),29;case 2:return this.popState(),this.begin("arg_directive"),15;case 3:return this.popState(),this.popState(),31;case 4:return 30;case 5:case 6:break;case 7:return 11;case 8:case 9:break;case 10:return 4;case 11:return 17;case 12:return this.begin("acc_title"),18;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),20;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:return 23;case 20:return 27;case 21:return 26;case 22:return 6;case 23:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?::\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,14,16,19,20,21,22,23],inclusive:!0}}};function g(){this.yy={}}return p.lexer=y,g.prototype=p,p.Parser=g,new g}();d.parser=d;const u=d;let p="",y=0;const g=[],f=[],m=[],_=()=>t,b=(t,n,i)=>{e(globalThis,t,n,i)},v=function(){g.length=0,f.length=0,p="",m.length=0,n()},x=function(t){p=t,g.push(t)},k=function(){return g},S=function(){let t=I();let e=0;for(;!t&&e<100;)t=I(),e++;return f.push(...m),f},w=function(t,e,n){const i={id:y++,section:p,type:p,task:t,score:e||0,events:n?[n]:[]};m.push(i)},$=function(t){m.find((t=>t.id===y-1)).events.push(t)},E=function(t){const e={section:p,type:p,description:t,task:t,classes:[]};f.push(e)},I=function(){let t=!0;for(const[e,n]of m.entries())m[e].processed,t=t&&n.processed;return t},T={clear:v,getCommonDb:_,addSection:x,getSections:k,getTasks:S,addTask:w,addTaskOrg:E,addEvent:$,parseDirective:b},D=Object.freeze(Object.defineProperty({__proto__:null,addEvent:$,addSection:x,addTask:w,addTaskOrg:E,clear:v,default:T,getCommonDb:_,getSections:k,getTasks:S,parseDirective:b},Symbol.toStringTag,{value:"Module"}));!function(){function t(t,e,n,s,r,a,o,c){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,c,l){const{taskFontSize:h,taskFontFamily:d}=c,u=t.split(//gi);for(let p=0;p)/).reverse(),s=[],a=n.attr("y"),o=parseFloat(n.attr("dy")),c=n.text(null).append("tspan").attr("x",0).attr("y",a).attr("dy",o+"em");for(let r=0;re||"
    "===t)&&(s.pop(),c.text(s.join(" ").trim()),s="
    "===t?[""]:[t],c=n.append("tspan").attr("x",0).attr("y",a).attr("dy","1.1em").text(t))}))}const A=function(t,e,n){t.append("path").attr("id","node-"+e.id).attr("class","node-bkg node-"+e.type).attr("d",`M0 ${e.height-5} v${10-e.height} q0,-5 5,-5 h${e.width-10} q5,0 5,5 v${e.height-5} H0 Z`),t.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",e.height).attr("x2",e.width).attr("y2",e.height)},C=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},M=function(t,e,n,i){const s=n%12-1,r=t.append("g");e.section=s,r.attr("class",(e.class?e.class+" ":"")+"timeline-node section-"+s);const a=r.append("g"),o=r.append("g"),c=o.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(L,e.width).node().getBBox(),l=i.fontSize&&i.fontSize.replace?i.fontSize.replace("px",""):i.fontSize;return e.height=c.height+1.1*l*.5+e.padding,e.height=Math.max(e.height,e.maxHeight),e.width=e.width+2*e.padding,o.attr("transform","translate("+e.width/2+", "+e.padding/2+")"),A(a,e,s),e},O=function(t,e,n){const i=t.append("g"),s=i.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(L,e.width).node().getBBox(),r=n.fontSize&&n.fontSize.replace?n.fontSize.replace("px",""):n.fontSize;return i.remove(),s.height+1.1*r*.5+e.padding},H=function(t,e,n,i,r,a,o,c,l,h,d){var u;for(const p of e){const e={descr:p.task,section:n,number:n,width:150,padding:20,maxHeight:a};s.debug("taskNode",e);const c=t.append("g").attr("class","taskWrapper"),y=M(c,e,n,o).height;if(s.debug("taskHeight after draw",y),c.attr("transform",`translate(${i}, ${r})`),a=Math.max(a,y),p.events){const e=t.append("g").attr("class","lineWrapper");let s=a;r+=100,s+=j(t,p.events,n,i,r,o),r-=100,e.append("line").attr("x1",i+95).attr("y1",r+a).attr("x2",i+95).attr("y2",r+a+(d?a:h)+l+120).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}i+=200,d&&!(null==(u=o.timeline)?void 0:u.disableMulticolor)&&n++}r-=10},j=function(t,e,n,i,r,a){let o=0;const c=r;r+=100;for(const l of e){const e={descr:l,section:n,number:n,width:150,padding:20,maxHeight:50};s.debug("eventNode",e);const c=t.append("g").attr("class","eventWrapper"),h=M(c,e,n,a).height;o+=h,c.attr("transform",`translate(${i}, ${r})`),r=r+10+h}return r=c,o},z={db:D,renderer:{setConf:()=>{},draw:function(t,e,n,o){var c,l,h,d,u,p,y;const g=i(),f=null!=(c=g.leftMargin)?c:50;null==(u=(d=o.db).clear)||u.call(d),o.parser.parse(t+"\n"),s.debug("timeline",o.db);const m=g.securityLevel;let _;"sandbox"===m&&(_=r("#i"+e));const b=r("sandbox"===m?_.nodes()[0].contentDocument.body:"body").select("#"+e);b.append("g");const v=o.db.getTasks(),x=o.db.getCommonDb().getDiagramTitle();s.debug("task",v),C(b);const k=o.db.getSections();s.debug("sections",k);let S=0,w=0,$=0,E=0,I=50+f,T=50;E=50;let D=0,L=!0;k.forEach((function(t){const e=O(b,{number:D,descr:t,section:D,width:150,padding:20,maxHeight:S},g);s.debug("sectionHeight before draw",e),S=Math.max(S,e+20)}));let A=0,j=0;s.debug("tasks.length",v.length);for(const[i,r]of v.entries()){const t={number:i,descr:r,section:r.section,width:150,padding:20,maxHeight:w},e=O(b,t,g);s.debug("taskHeight before draw",e),w=Math.max(w,e+20),A=Math.max(A,r.events.length);let n=0;for(let i=0;i0?k.forEach((t=>{const e=v.filter((e=>e.section===t)),n={number:D,descr:t,section:D,width:200*Math.max(e.length,1)-50,padding:20,maxHeight:S};s.debug("sectionNode",n);const i=b.append("g"),r=M(i,n,D,g);s.debug("sectionNode output",r),i.attr("transform",`translate(${I}, 50)`),T+=S+50,e.length>0&&H(b,e,D,I,T,w,g,A,j,S,!1),I+=200*Math.max(e.length,1),T=50,D++})):(L=!1,H(b,v,D,I,T,w,g,A,j,S,!0));const z=b.node().getBBox();s.debug("bounds",z),x&&b.append("text").text(x).attr("x",z.width/2-f).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),$=L?S+w+150:w+100;b.append("g").attr("class","lineWrapper").append("line").attr("x1",f).attr("y1",$).attr("x2",z.width+3*f).attr("y2",$).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),a(void 0,b,null!=(l=null==(p=g.timeline)?void 0:p.padding)?l:50,null!=(h=null==(y=g.timeline)?void 0:y.useMaxWidth)&&h)}},parser:u,styles:t=>`\n .edge {\n stroke-width: 3;\n }\n ${(t=>{let e="";for(let n=0;nh&&E.push("'"+this.terminals_[S]+"'");T=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(c+1)+": Unexpected "+(b==d?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(T,{text:p.match,token:this.terminals_[b]||b,line:p.yylineno,loc:f,expected:E})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+v+", token: "+b);switch(x[0]){case 1:n.push(b),s.push(p.yytext),r.push(p.yylloc),n.push(x[1]),b=null,l=p.yyleng,o=p.yytext,c=p.yylineno,f=p.yylloc;break;case 2:if(w=this.productions_[x[1]][1],I.$=s[s.length-w],I._$={first_line:r[r.length-(w||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(w||1)].first_column,last_column:r[r.length-1].last_column},m&&(I._$.range=[r[r.length-(w||1)].range[0],r[r.length-1].range[1]]),void 0!==(k=this.performAction.apply(I,[o,l,c,y.yy,x[1],s,r].concat(u))))return k;w&&(n=n.slice(0,-1*w*2),s=s.slice(0,-1*w),r=r.slice(0,-1*w)),n.push(this.productions_[x[1]][0]),s.push(I.$),r.push(I._$),$=a[n[n.length-2]][n[n.length-1]],n.push($);break;case 3:return!0}}return!0}},y={EOF:1,parseError:function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,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];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(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 i=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 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:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this},more:function(){return this._more=!0,this},reject:function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):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).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},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()+"\n"+e+"^"},test_match:function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1},next:function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var t=this.next();return t||this.lex()},begin:function(t){this.conditionStack.push(t)},popState:function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]},_currentRules:function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules},topState:function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"},pushState:function(t){this.begin(t)},stateStackSize:function(){return this.conditionStack.length},options:{"case-insensitive":!0},performAction:function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),28;case 1:return this.begin("type_directive"),29;case 2:return this.popState(),this.begin("arg_directive"),15;case 3:return this.popState(),this.popState(),31;case 4:return 30;case 5:case 6:break;case 7:return 11;case 8:case 9:break;case 10:return 4;case 11:return 17;case 12:return this.begin("acc_title"),18;case 13:return this.popState(),"acc_title_value";case 14:return this.begin("acc_descr"),20;case 15:return this.popState(),"acc_descr_value";case 16:this.begin("acc_descr_multiline");break;case 17:this.popState();break;case 18:return"acc_descr_multiline_value";case 19:return 23;case 20:return 27;case 21:return 26;case 22:return 6;case 23:return"INVALID"}},rules:[/^(?:%%\{)/i,/^(?:((?:(?!\}%%)[^:.])*))/i,/^(?::)/i,/^(?:\}%%)/i,/^(?:((?:(?!\}%%).|\n)*))/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?::\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{open_directive:{rules:[1],inclusive:!1},type_directive:{rules:[2,3],inclusive:!1},arg_directive:{rules:[3,4],inclusive:!1},acc_descr_multiline:{rules:[17,18],inclusive:!1},acc_descr:{rules:[15],inclusive:!1},acc_title:{rules:[13],inclusive:!1},INITIAL:{rules:[0,5,6,7,8,9,10,11,12,14,16,19,20,21,22,23],inclusive:!0}}};function g(){this.yy={}}return p.lexer=y,g.prototype=p,p.Parser=g,new g}();d.parser=d;const u=d;let p="",y=0;const g=[],f=[],m=[],_=()=>t,b=(t,n,i)=>{e(globalThis,t,n,i)},v=function(){g.length=0,f.length=0,p="",m.length=0,n()},x=function(t){p=t,g.push(t)},k=function(){return g},S=function(){let t=I();let e=0;for(;!t&&e<100;)t=I(),e++;return f.push(...m),f},w=function(t,e,n){const i={id:y++,section:p,type:p,task:t,score:e||0,events:n?[n]:[]};m.push(i)},$=function(t){m.find((t=>t.id===y-1)).events.push(t)},E=function(t){const e={section:p,type:p,description:t,task:t,classes:[]};f.push(e)},I=function(){let t=!0;for(const[e,n]of m.entries())m[e].processed,t=t&&n.processed;return t},T={clear:v,getCommonDb:_,addSection:x,getSections:k,getTasks:S,addTask:w,addTaskOrg:E,addEvent:$,parseDirective:b},D=Object.freeze(Object.defineProperty({__proto__:null,addEvent:$,addSection:x,addTask:w,addTaskOrg:E,clear:v,default:T,getCommonDb:_,getSections:k,getTasks:S,parseDirective:b},Symbol.toStringTag,{value:"Module"}));!function(){function t(t,e,n,s,r,a,o,c){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,c,l){const{taskFontSize:h,taskFontFamily:d}=c,u=t.split(//gi);for(let p=0;p)/).reverse(),s=[],a=n.attr("y"),o=parseFloat(n.attr("dy")),c=n.text(null).append("tspan").attr("x",0).attr("y",a).attr("dy",o+"em");for(let r=0;re||"
    "===t)&&(s.pop(),c.text(s.join(" ").trim()),s="
    "===t?[""]:[t],c=n.append("tspan").attr("x",0).attr("y",a).attr("dy","1.1em").text(t))}))}const A=function(t,e,n){t.append("path").attr("id","node-"+e.id).attr("class","node-bkg node-"+e.type).attr("d",`M0 ${e.height-5} v${10-e.height} q0,-5 5,-5 h${e.width-10} q5,0 5,5 v${e.height-5} H0 Z`),t.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",e.height).attr("x2",e.width).attr("y2",e.height)},C=function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")},M=function(t,e,n,i){const s=n%12-1,r=t.append("g");e.section=s,r.attr("class",(e.class?e.class+" ":"")+"timeline-node section-"+s);const a=r.append("g"),o=r.append("g"),c=o.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(L,e.width).node().getBBox(),l=i.fontSize&&i.fontSize.replace?i.fontSize.replace("px",""):i.fontSize;return e.height=c.height+1.1*l*.5+e.padding,e.height=Math.max(e.height,e.maxHeight),e.width=e.width+2*e.padding,o.attr("transform","translate("+e.width/2+", "+e.padding/2+")"),A(a,e,s),e},O=function(t,e,n){const i=t.append("g"),s=i.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(L,e.width).node().getBBox(),r=n.fontSize&&n.fontSize.replace?n.fontSize.replace("px",""):n.fontSize;return i.remove(),s.height+1.1*r*.5+e.padding},H=function(t,e,n,i,r,a,o,c,l,h,d){var u;for(const p of e){const e={descr:p.task,section:n,number:n,width:150,padding:20,maxHeight:a};s.debug("taskNode",e);const c=t.append("g").attr("class","taskWrapper"),y=M(c,e,n,o).height;if(s.debug("taskHeight after draw",y),c.attr("transform",`translate(${i}, ${r})`),a=Math.max(a,y),p.events){const e=t.append("g").attr("class","lineWrapper");let s=a;r+=100,s+=j(t,p.events,n,i,r,o),r-=100,e.append("line").attr("x1",i+95).attr("y1",r+a).attr("x2",i+95).attr("y2",r+a+(d?a:h)+l+120).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}i+=200,d&&!(null==(u=o.timeline)?void 0:u.disableMulticolor)&&n++}r-=10},j=function(t,e,n,i,r,a){let o=0;const c=r;r+=100;for(const l of e){const e={descr:l,section:n,number:n,width:150,padding:20,maxHeight:50};s.debug("eventNode",e);const c=t.append("g").attr("class","eventWrapper"),h=M(c,e,n,a).height;o+=h,c.attr("transform",`translate(${i}, ${r})`),r=r+10+h}return r=c,o},z={db:D,renderer:{setConf:()=>{},draw:function(t,e,n,o){var c,l,h,d,u,p,y;const g=i(),f=null!=(c=g.leftMargin)?c:50;null==(u=(d=o.db).clear)||u.call(d),o.parser.parse(t+"\n"),s.debug("timeline",o.db);const m=g.securityLevel;let _;"sandbox"===m&&(_=r("#i"+e));const b=r("sandbox"===m?_.nodes()[0].contentDocument.body:"body").select("#"+e);b.append("g");const v=o.db.getTasks(),x=o.db.getCommonDb().getDiagramTitle();s.debug("task",v),C(b);const k=o.db.getSections();s.debug("sections",k);let S=0,w=0,$=0,E=0,I=50+f,T=50;E=50;let D=0,L=!0;k.forEach((function(t){const e=O(b,{number:D,descr:t,section:D,width:150,padding:20,maxHeight:S},g);s.debug("sectionHeight before draw",e),S=Math.max(S,e+20)}));let A=0,j=0;s.debug("tasks.length",v.length);for(const[i,r]of v.entries()){const t={number:i,descr:r,section:r.section,width:150,padding:20,maxHeight:w},e=O(b,t,g);s.debug("taskHeight before draw",e),w=Math.max(w,e+20),A=Math.max(A,r.events.length);let n=0;for(let i=0;i0?k.forEach((t=>{const e=v.filter((e=>e.section===t)),n={number:D,descr:t,section:D,width:200*Math.max(e.length,1)-50,padding:20,maxHeight:S};s.debug("sectionNode",n);const i=b.append("g"),r=M(i,n,D,g);s.debug("sectionNode output",r),i.attr("transform",`translate(${I}, 50)`),T+=S+50,e.length>0&&H(b,e,D,I,T,w,g,A,j,S,!1),I+=200*Math.max(e.length,1),T=50,D++})):(L=!1,H(b,v,D,I,T,w,g,A,j,S,!0));const z=b.node().getBBox();s.debug("bounds",z),x&&b.append("text").text(x).attr("x",z.width/2-f).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),$=L?S+w+150:w+100;b.append("g").attr("class","lineWrapper").append("line").attr("x1",f).attr("y1",$).attr("x2",z.width+3*f).attr("y2",$).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),a(void 0,b,null!=(l=null==(p=g.timeline)?void 0:p.padding)?l:50,null!=(h=null==(y=g.timeline)?void 0:y.useMaxWidth)&&h)}},parser:u,styles:t=>`\n .edge {\n stroke-width: 3;\n }\n ${(t=>{let e="";for(let n=0;n
    sudo curl -oL /usr/local/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat\nsudo curl -oL /usr/local/share/xray/geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat\n
    1
    2
    {\n  "log": {\n    "loglevel": "warning",\n    "error": "/var/log/xray/error.log",\n    "access": "/var/log/xray/access.log"\n  },\n  "inbounds": [\n    {\n      "tag": "all-in",\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy"\n        }\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "tag": "direct",\n      "protocol": "freedom",\n      "settings": {\n        "domainStrategy": "UseIPv4"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    },\n    {\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "服务端域名",\n            "port": 443,\n            "users": [\n              {\n                "id": "UUID",\n                "flow": "xtls-rprx-vision",\n                "encryption": "none"\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "xtls",\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    },\n    {\n      "tag": "block",\n      "protocol": "blackhole",\n      "settings": {\n        "response": {\n          "type": "http"\n        }\n      }\n    },\n    {\n      "tag": "dns-out",\n      "protocol": "dns",\n      "settings": {\n        "address": "8.8.8.8"\n      },\n      "proxySettings": {\n        "tag": "proxy"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    }\n  ],\n  "dns": {\n    "hosts": {\n      "服务端域名": "服务端 IP"\n    },\n    "servers": [\n      {\n        "address": "119.29.29.29",\n        "port": 53,\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      {\n        "address": "223.5.5.5",\n        "port": 53,\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      "8.8.8.8",\n      "1.1.1.1",\n      "https+local://doh.dns.sb/dns-query"\n    ]\n  },\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 53,\n        "outboundTag": "dns-out"\n      },\n      {\n        "type": "field",\n        "ip": ["8.8.8.8", "1.1.1.1"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:geolocation-!cn"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "ip": ["geoip:telegram"],\n        "outboundTag": "proxy"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144

    TIP

    本配置会劫持所有发往 53 端口的流量以解决 DNS 污染问题,所以客户端和本机的 DNS 服务器的地址可以随意配置。

    策略路由配置

    sudo ip route add local default dev lo table 100 # 添加路由表 100\nsudo ip rule add fwmark 1 table 100 # 为路由表 100 设定规则\n
    1
    2

    Netfilter 配置

    注意

    nftables 配置与 iptables 配置二选一,不可同时使用。

    ',7),j=t("div",{class:"language-nftables ext-nftables line-numbers-mode"},[t("pre",{class:"language-nftables"},[t("code",null,"#!/usr/sbin/nft -f\n\nflush ruleset\n\ndefine RESERVED_IP = {\n 10.0.0.0/8,\n 100.64.0.0/10,\n 127.0.0.0/8,\n 169.254.0.0/16,\n 172.16.0.0/12,\n 192.0.0.0/24,\n 224.0.0.0/4,\n 240.0.0.0/4,\n 255.255.255.255/32\n}\n\ntable ip xray {\n chain prerouting {\n type filter hook prerouting priority mangle; policy accept;\n ip daddr $RESERVED_IP return\n ip daddr 192.168.0.0/16 tcp dport != 53 return\n ip daddr 192.168.0.0/16 udp dport != 53 return\n ip protocol tcp tproxy to 127.0.0.1:12345 meta mark set 1\n ip protocol udp tproxy to 127.0.0.1:12345 meta mark set 1\n }\n chain output {\n type route hook output priority mangle; policy accept;\n ip daddr $RESERVED_IP return\n ip daddr 192.168.0.0/16 tcp dport != 53 return\n ip daddr 192.168.0.0/16 udp dport != 53 return\n meta mark 2 return\n ip protocol tcp meta mark set 1\n ip protocol udp meta mark set 1\n }\n}\n")]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br"),t("span",{class:"line-number"},"21"),t("br"),t("span",{class:"line-number"},"22"),t("br"),t("span",{class:"line-number"},"23"),t("br"),t("span",{class:"line-number"},"24"),t("br"),t("span",{class:"line-number"},"25"),t("br"),t("span",{class:"line-number"},"26"),t("br"),t("span",{class:"line-number"},"27"),t("br"),t("span",{class:"line-number"},"28"),t("br"),t("span",{class:"line-number"},"29"),t("br"),t("span",{class:"line-number"},"30"),t("br"),t("span",{class:"line-number"},"31"),t("br"),t("span",{class:"line-number"},"32"),t("br"),t("span",{class:"line-number"},"33"),t("br"),t("span",{class:"line-number"},"34"),t("br"),t("span",{class:"line-number"},"35"),t("br")])],-1),Y=t("div",{class:"custom-container tip"},[t("p",{class:"custom-container-title"},"使用方法"),t("p",null,[l("将上述配置写入一个文件(如 "),t("code",null,"nft.conf"),l("),之后将该文件赋予可执行权限,最后使用 root 权限执行该文件即可("),t("code",null,"# ./nft.conf"),l(")。")])],-1),U=t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[l("iptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"10.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"100.64"),l(".0.0/10 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"127.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"169.254"),l(".0.0/16 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"172.16"),l(".0.0/12 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.0"),l(".0.0/24 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"224.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"240.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"255.255"),l(".255.255/32 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p tcp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p udp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),t("span",{class:"token number"},"12345"),l(" --tproxy-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),t("span",{class:"token number"},"12345"),l(" --tproxy-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A PREROUTING -j XRAY\n\niptables -t mangle -N XRAY_SELF\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"10.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"100.64"),l(".0.0/10 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"127.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"169.254"),l(".0.0/16 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"172.16"),l(".0.0/12 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.0"),l(".0.0/24 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"224.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"240.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"255.255"),l(".255.255/32 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p tcp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p udp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -m mark --mark "),t("span",{class:"token number"},"2"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -p tcp -j MARK --set-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A XRAY_SELF -p udp -j MARK --set-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A OUTPUT -j XRAY_SELF\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br"),t("span",{class:"line-number"},"21"),t("br"),t("span",{class:"line-number"},"22"),t("br"),t("span",{class:"line-number"},"23"),t("br"),t("span",{class:"line-number"},"24"),t("br"),t("span",{class:"line-number"},"25"),t("br"),t("span",{class:"line-number"},"26"),t("br"),t("span",{class:"line-number"},"27"),t("br"),t("span",{class:"line-number"},"28"),t("br"),t("span",{class:"line-number"},"29"),t("br"),t("span",{class:"line-number"},"30"),t("br"),t("span",{class:"line-number"},"31"),t("br"),t("span",{class:"line-number"},"32"),t("br")])],-1),N=t("p",null,"配置完成后,将局域网内其它设备的默认网关改为该设备 IP,就可以直接翻墙了。在其它主机和本机皆测试成功后,可进行下一步配置。",-1),_=t("h2",{id:"配置永久化与开机自启",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#配置永久化与开机自启","aria-hidden":"true"},"#"),l(" 配置永久化与开机自启")],-1),L=t("br",null,null,-1),P=t("p",null,[l("首先将已经编辑好的 nftables 配置文件移动到 "),t("code",null,"/etc"),l(" 目录下,并重命名为 "),t("code",null,"nftables.conf"),l("。然后编辑 "),t("code",null,"/lib/systemd/system/nftables.service"),l("。")],-1),w=t("div",{class:"language-ini ext-ini line-numbers-mode"},[t("pre",{class:"language-ini"},[t("code",null,[t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Unit"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Description"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"nftables"),l("\n"),t("span",{class:"token key attr-name"},"Documentation"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"man:nft(8) http://wiki.nftables.org"),l("\n"),t("span",{class:"token key attr-name"},"Wants"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target"),l("\n"),t("span",{class:"token key attr-name"},"Before"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"Conflicts"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"DefaultDependencies"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"no"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Service"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Type"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"oneshot"),l("\n"),t("span",{class:"token key attr-name"},"RemainAfterExit"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"yes"),l("\n"),t("span",{class:"token key attr-name"},"StandardInput"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"null"),l("\n"),t("span",{class:"token key attr-name"},"ProtectSystem"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"full"),l("\n"),t("span",{class:"token key attr-name"},"ProtectHome"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"true"),l("\n"),t("span",{class:"token key attr-name"},"ExecStart"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft -f /etc/nftables.conf ; /usr/sbin/ip route add local default dev lo table 100 ; /usr/sbin/ip rule add fwmark 1 table 100"),l("\n"),t("span",{class:"token key attr-name"},"ExecReload"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft -f /etc/nftables.conf"),l("\n"),t("span",{class:"token key attr-name"},"ExecStop"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft flush ruleset ; /usr/sbin/ip route del local default dev lo table 100 ; /usr/sbin/ip rule del table 100"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Install"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"WantedBy"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"sysinit.target"),l("\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br")])],-1),I=t("p",null,"最后 enable 即可。",-1),F=t("p",null,[l("关于 iptables 的永久化,建议直接安装 "),t("code",null,"iptables-persistent"),l("。")],-1),D=t("p",null,[l("安装过程中会提示你选择“是否保存配置”,如果已经将 iptables 配置写入系统,那么此时选择“是”即可;如果尚未写入也没有关系,安装完毕后将配置写入,然后执行 "),t("code",null,"netfilter-persistent save"),l(" 即可(需要 root 权限)。")],-1),O=t("p",null,[l("之后编辑 "),t("code",null,"/lib/systemd/system/netfilter-persistent.service"),l("。")],-1),V=t("div",{class:"language-ini ext-ini line-numbers-mode"},[t("pre",{class:"language-ini"},[t("code",null,[t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Unit"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Description"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"netfilter persistent configuration"),l("\n"),t("span",{class:"token key attr-name"},"DefaultDependencies"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"no"),l("\n"),t("span",{class:"token key attr-name"},"Wants"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target systemd-modules-load.service local-fs.target"),l("\n"),t("span",{class:"token key attr-name"},"Before"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"After"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"systemd-modules-load.service local-fs.target"),l("\n"),t("span",{class:"token key attr-name"},"Conflicts"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"Documentation"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"man:netfilter-persistent(8)"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Service"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Type"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"oneshot"),l("\n"),t("span",{class:"token key attr-name"},"RemainAfterExit"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"yes"),l("\n"),t("span",{class:"token key attr-name"},"ExecStart"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/netfilter-persistent start ; /usr/sbin/ip route add local default dev lo table 100 ; /usr/sbin/ip rule add fwmark 1 table 100"),l("\n"),t("span",{class:"token key attr-name"},"ExecStop"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/netfilter-persistent stop ; /usr/sbin/ip route flush dev lo table 100 ; /usr/sbin/ip rule del table 100"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Install"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"WantedBy"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"multi-user.target"),l("\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br")])],-1);u.render=function(l,r){const u=n("OutboundLink"),B=n("Tab"),W=n("Tabs");return s(),a(o,null,[c,t("p",null,[i,t("a",b,[k,p(u)]),m]),q,d,g,t("p",null,[y,t("a",v,[f,p(u)]),R]),h,A,t("p",null,[E,t("a",x,[T,p(u)]),S]),X,p(W,{title:"netfilter"},{default:e((()=>[p(B,{title:"nftables1"},{default:e((()=>[j,Y])),_:1}),p(B,{title:"iptables1"},{default:e((()=>[U])),_:1})])),_:1}),N,_,L,p(W,{title:"netfilter2"},{default:e((()=>[p(B,{title:"nftables2"},{default:e((()=>[P,w,I])),_:1}),p(B,{title:"iptables2"},{default:e((()=>[F,D,O,V])),_:1})])),_:1})],64)};export default u; +import{r as n,o as s,c as a,a as t,b as p,w as e,F as o,e as l,d as r}from"./app.48111a85.js";const u={},c=t("h1",{id:"透明代理-tproxy-配置教程",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#透明代理-tproxy-配置教程","aria-hidden":"true"},"#"),l(" 透明代理(TProxy)配置教程")],-1),i=l("本配置基于"),b={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},k=l("TProxy 透明代理的新 V2Ray 白话文教程"),m=l(",加入了 Xray 的新特性,使用 VLESS + XTLS Vision 方案,并将旧教程中默认出站代理的分流方式改为默认出站直连,使用者请按照实际情况进行修改。"),q=t("p",null,"本文中所有配置已在 Raspberry Pi 2B、Ubuntu 20.04 环境下测试成功,如在其它环境中使用请自行调整配置。",-1),d=t("h2",{id:"开始之前",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#开始之前","aria-hidden":"true"},"#"),l(" 开始之前")],-1),g=t("p",null,"请检查您的设备是否有可用的网络连接,且服务端已经配置成功,客户端已经安装完毕。",-1),y=l("需注意的是,目前很多透明代理教程都会将 Linux 系统的 IP 转发打开,但这样会导致 Splice 性能下降。详情请参考"),v={href:"https://github.com/XTLS/Xray-core/discussions/59",target:"_blank",rel:"noopener noreferrer"},f=l("大案牍术破案纪实第三篇--我们是如何破解 Splice 性能下降甚至低于 Direct 之谜的"),R=l("。"),h=t("p",null,"这里我想要补充的是,很多透明代理教程会使用 Netfilter 进行分流,使直连流量直接发出而不经过 Xray,这时必须开启 IP 转发;也有的教程,如本文,会将所有流量导入 Xray 之中,由 Xray 的路由模块进行分流,这时无需开启 IP 转发。",-1),A=t("h2",{id:"xray-配置",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#xray-配置","aria-hidden":"true"},"#"),l(" Xray 配置")],-1),E=l("为了更好的分流体验,请替换默认路由规则文件为 "),x={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},T=l("Loyalsoldier/v2ray-rules-dat"),S=l(",否则 Xray-core 将无法加载本配置。"),X=r('
    sudo curl -oL /usr/local/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat\nsudo curl -oL /usr/local/share/xray/geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat\n
    1
    2
    {\n  "log": {\n    "loglevel": "warning",\n    "error": "/var/log/xray/error.log",\n    "access": "/var/log/xray/access.log"\n  },\n  "inbounds": [\n    {\n      "tag": "all-in",\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy"\n        }\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "tag": "direct",\n      "protocol": "freedom",\n      "settings": {\n        "domainStrategy": "UseIPv4"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    },\n    {\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "服务端域名",\n            "port": 443,\n            "users": [\n              {\n                "id": "UUID",\n                "flow": "xtls-rprx-vision",\n                "encryption": "none"\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "xtls",\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    },\n    {\n      "tag": "block",\n      "protocol": "blackhole",\n      "settings": {\n        "response": {\n          "type": "http"\n        }\n      }\n    },\n    {\n      "tag": "dns-out",\n      "protocol": "dns",\n      "settings": {\n        "address": "8.8.8.8"\n      },\n      "proxySettings": {\n        "tag": "proxy"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    }\n  ],\n  "dns": {\n    "hosts": {\n      "服务端域名": "服务端 IP"\n    },\n    "servers": [\n      {\n        "address": "119.29.29.29",\n        "port": 53,\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      {\n        "address": "223.5.5.5",\n        "port": 53,\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      "8.8.8.8",\n      "1.1.1.1",\n      "https+local://doh.dns.sb/dns-query"\n    ]\n  },\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 53,\n        "outboundTag": "dns-out"\n      },\n      {\n        "type": "field",\n        "ip": ["8.8.8.8", "1.1.1.1"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:geolocation-!cn"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "ip": ["geoip:telegram"],\n        "outboundTag": "proxy"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144

    TIP

    本配置会劫持所有发往 53 端口的流量以解决 DNS 污染问题,所以客户端和本机的 DNS 服务器的地址可以随意配置。

    策略路由配置

    sudo ip route add local default dev lo table 100 # 添加路由表 100\nsudo ip rule add fwmark 1 table 100 # 为路由表 100 设定规则\n
    1
    2

    Netfilter 配置

    注意

    nftables 配置与 iptables 配置二选一,不可同时使用。

    ',7),j=t("div",{class:"language-nftables ext-nftables line-numbers-mode"},[t("pre",{class:"language-nftables"},[t("code",null,"#!/usr/sbin/nft -f\n\nflush ruleset\n\ndefine RESERVED_IP = {\n 10.0.0.0/8,\n 100.64.0.0/10,\n 127.0.0.0/8,\n 169.254.0.0/16,\n 172.16.0.0/12,\n 192.0.0.0/24,\n 224.0.0.0/4,\n 240.0.0.0/4,\n 255.255.255.255/32\n}\n\ntable ip xray {\n chain prerouting {\n type filter hook prerouting priority mangle; policy accept;\n ip daddr $RESERVED_IP return\n ip daddr 192.168.0.0/16 tcp dport != 53 return\n ip daddr 192.168.0.0/16 udp dport != 53 return\n ip protocol tcp tproxy to 127.0.0.1:12345 meta mark set 1\n ip protocol udp tproxy to 127.0.0.1:12345 meta mark set 1\n }\n chain output {\n type route hook output priority mangle; policy accept;\n ip daddr $RESERVED_IP return\n ip daddr 192.168.0.0/16 tcp dport != 53 return\n ip daddr 192.168.0.0/16 udp dport != 53 return\n meta mark 2 return\n ip protocol tcp meta mark set 1\n ip protocol udp meta mark set 1\n }\n}\n")]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br"),t("span",{class:"line-number"},"21"),t("br"),t("span",{class:"line-number"},"22"),t("br"),t("span",{class:"line-number"},"23"),t("br"),t("span",{class:"line-number"},"24"),t("br"),t("span",{class:"line-number"},"25"),t("br"),t("span",{class:"line-number"},"26"),t("br"),t("span",{class:"line-number"},"27"),t("br"),t("span",{class:"line-number"},"28"),t("br"),t("span",{class:"line-number"},"29"),t("br"),t("span",{class:"line-number"},"30"),t("br"),t("span",{class:"line-number"},"31"),t("br"),t("span",{class:"line-number"},"32"),t("br"),t("span",{class:"line-number"},"33"),t("br"),t("span",{class:"line-number"},"34"),t("br"),t("span",{class:"line-number"},"35"),t("br")])],-1),Y=t("div",{class:"custom-container tip"},[t("p",{class:"custom-container-title"},"使用方法"),t("p",null,[l("将上述配置写入一个文件(如 "),t("code",null,"nft.conf"),l("),之后将该文件赋予可执行权限,最后使用 root 权限执行该文件即可("),t("code",null,"# ./nft.conf"),l(")。")])],-1),U=t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[l("iptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"10.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"100.64"),l(".0.0/10 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"127.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"169.254"),l(".0.0/16 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"172.16"),l(".0.0/12 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.0"),l(".0.0/24 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"224.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"240.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"255.255"),l(".255.255/32 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p tcp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p udp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),t("span",{class:"token number"},"12345"),l(" --tproxy-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),t("span",{class:"token number"},"12345"),l(" --tproxy-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A PREROUTING -j XRAY\n\niptables -t mangle -N XRAY_SELF\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"10.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"100.64"),l(".0.0/10 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"127.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"169.254"),l(".0.0/16 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"172.16"),l(".0.0/12 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.0"),l(".0.0/24 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"224.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"240.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"255.255"),l(".255.255/32 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p tcp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p udp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -m mark --mark "),t("span",{class:"token number"},"2"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -p tcp -j MARK --set-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A XRAY_SELF -p udp -j MARK --set-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A OUTPUT -j XRAY_SELF\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br"),t("span",{class:"line-number"},"21"),t("br"),t("span",{class:"line-number"},"22"),t("br"),t("span",{class:"line-number"},"23"),t("br"),t("span",{class:"line-number"},"24"),t("br"),t("span",{class:"line-number"},"25"),t("br"),t("span",{class:"line-number"},"26"),t("br"),t("span",{class:"line-number"},"27"),t("br"),t("span",{class:"line-number"},"28"),t("br"),t("span",{class:"line-number"},"29"),t("br"),t("span",{class:"line-number"},"30"),t("br"),t("span",{class:"line-number"},"31"),t("br"),t("span",{class:"line-number"},"32"),t("br")])],-1),N=t("p",null,"配置完成后,将局域网内其它设备的默认网关改为该设备 IP,就可以直接翻墙了。在其它主机和本机皆测试成功后,可进行下一步配置。",-1),_=t("h2",{id:"配置永久化与开机自启",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#配置永久化与开机自启","aria-hidden":"true"},"#"),l(" 配置永久化与开机自启")],-1),L=t("br",null,null,-1),P=t("p",null,[l("首先将已经编辑好的 nftables 配置文件移动到 "),t("code",null,"/etc"),l(" 目录下,并重命名为 "),t("code",null,"nftables.conf"),l("。然后编辑 "),t("code",null,"/lib/systemd/system/nftables.service"),l("。")],-1),w=t("div",{class:"language-ini ext-ini line-numbers-mode"},[t("pre",{class:"language-ini"},[t("code",null,[t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Unit"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Description"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"nftables"),l("\n"),t("span",{class:"token key attr-name"},"Documentation"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"man:nft(8) http://wiki.nftables.org"),l("\n"),t("span",{class:"token key attr-name"},"Wants"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target"),l("\n"),t("span",{class:"token key attr-name"},"Before"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"Conflicts"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"DefaultDependencies"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"no"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Service"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Type"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"oneshot"),l("\n"),t("span",{class:"token key attr-name"},"RemainAfterExit"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"yes"),l("\n"),t("span",{class:"token key attr-name"},"StandardInput"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"null"),l("\n"),t("span",{class:"token key attr-name"},"ProtectSystem"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"full"),l("\n"),t("span",{class:"token key attr-name"},"ProtectHome"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"true"),l("\n"),t("span",{class:"token key attr-name"},"ExecStart"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft -f /etc/nftables.conf ; /usr/sbin/ip route add local default dev lo table 100 ; /usr/sbin/ip rule add fwmark 1 table 100"),l("\n"),t("span",{class:"token key attr-name"},"ExecReload"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft -f /etc/nftables.conf"),l("\n"),t("span",{class:"token key attr-name"},"ExecStop"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft flush ruleset ; /usr/sbin/ip route del local default dev lo table 100 ; /usr/sbin/ip rule del table 100"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Install"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"WantedBy"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"sysinit.target"),l("\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br")])],-1),I=t("p",null,"最后 enable 即可。",-1),F=t("p",null,[l("关于 iptables 的永久化,建议直接安装 "),t("code",null,"iptables-persistent"),l("。")],-1),D=t("p",null,[l("安装过程中会提示你选择“是否保存配置”,如果已经将 iptables 配置写入系统,那么此时选择“是”即可;如果尚未写入也没有关系,安装完毕后将配置写入,然后执行 "),t("code",null,"netfilter-persistent save"),l(" 即可(需要 root 权限)。")],-1),O=t("p",null,[l("之后编辑 "),t("code",null,"/lib/systemd/system/netfilter-persistent.service"),l("。")],-1),V=t("div",{class:"language-ini ext-ini line-numbers-mode"},[t("pre",{class:"language-ini"},[t("code",null,[t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Unit"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Description"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"netfilter persistent configuration"),l("\n"),t("span",{class:"token key attr-name"},"DefaultDependencies"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"no"),l("\n"),t("span",{class:"token key attr-name"},"Wants"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target systemd-modules-load.service local-fs.target"),l("\n"),t("span",{class:"token key attr-name"},"Before"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"After"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"systemd-modules-load.service local-fs.target"),l("\n"),t("span",{class:"token key attr-name"},"Conflicts"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"Documentation"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"man:netfilter-persistent(8)"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Service"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Type"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"oneshot"),l("\n"),t("span",{class:"token key attr-name"},"RemainAfterExit"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"yes"),l("\n"),t("span",{class:"token key attr-name"},"ExecStart"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/netfilter-persistent start ; /usr/sbin/ip route add local default dev lo table 100 ; /usr/sbin/ip rule add fwmark 1 table 100"),l("\n"),t("span",{class:"token key attr-name"},"ExecStop"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/netfilter-persistent stop ; /usr/sbin/ip route flush dev lo table 100 ; /usr/sbin/ip rule del table 100"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Install"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"WantedBy"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"multi-user.target"),l("\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br")])],-1);u.render=function(l,r){const u=n("OutboundLink"),B=n("Tab"),W=n("Tabs");return s(),a(o,null,[c,t("p",null,[i,t("a",b,[k,p(u)]),m]),q,d,g,t("p",null,[y,t("a",v,[f,p(u)]),R]),h,A,t("p",null,[E,t("a",x,[T,p(u)]),S]),X,p(W,{title:"netfilter"},{default:e((()=>[p(B,{title:"nftables1"},{default:e((()=>[j,Y])),_:1}),p(B,{title:"iptables1"},{default:e((()=>[U])),_:1})])),_:1}),N,_,L,p(W,{title:"netfilter2"},{default:e((()=>[p(B,{title:"nftables2"},{default:e((()=>[P,w,I])),_:1}),p(B,{title:"iptables2"},{default:e((()=>[F,D,O,V])),_:1})])),_:1})],64)};export default u; diff --git a/assets/tproxy.html.e317a52f.js b/assets/tproxy.html.996e8483.js similarity index 99% rename from assets/tproxy.html.e317a52f.js rename to assets/tproxy.html.996e8483.js index 8cac5b1d2..ccb1162b8 100644 --- a/assets/tproxy.html.e317a52f.js +++ b/assets/tproxy.html.996e8483.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as t,b as p,w as e,F as o,e as l,d as r}from"./app.755d843f.js";const u={},c=t("h1",{id:"透明代理-tproxy-配置教程",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#透明代理-tproxy-配置教程","aria-hidden":"true"},"#"),l(" 透明代理(TProxy)配置教程")],-1),i=l("本配置基于"),b={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},k=l("TProxy 透明代理的新 V2Ray 白话文教程"),m=l(",加入了 Xray 的新特性,使用 VLESS + XTLS Vision 方案,并将旧教程中默认出站代理的分流方式改为默认出站直连,使用者请按照实际情况进行修改。"),q=t("p",null,"本文中所有配置已在 Raspberry Pi 2B、Ubuntu 20.04 环境下测试成功,如在其它环境中使用请自行调整配置。",-1),d=t("h2",{id:"开始之前",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#开始之前","aria-hidden":"true"},"#"),l(" 开始之前")],-1),g=t("p",null,"请检查您的设备是否有可用的网络连接,且服务端已经配置成功,客户端已经安装完毕。",-1),y=l("需注意的是,目前很多透明代理教程都会将 Linux 系统的 IP 转发打开,但这样会导致 Splice 性能下降。详情请参考"),v={href:"https://github.com/XTLS/Xray-core/discussions/59",target:"_blank",rel:"noopener noreferrer"},f=l("大案牍术破案纪实第三篇--我们是如何破解 Splice 性能下降甚至低于 Direct 之谜的"),R=l("。"),h=t("p",null,"这里我想要补充的是,很多透明代理教程会使用 Netfilter 进行分流,使直连流量直接发出而不经过 Xray,这时必须开启 IP 转发;也有的教程,如本文,会将所有流量导入 Xray 之中,由 Xray 的路由模块进行分流,这时无需开启 IP 转发。",-1),A=t("h2",{id:"xray-配置",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#xray-配置","aria-hidden":"true"},"#"),l(" Xray 配置")],-1),E=l("为了更好的分流体验,请替换默认路由规则文件为 "),x={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},T=l("Loyalsoldier/v2ray-rules-dat"),S=l(",否则 Xray-core 将无法加载本配置。"),X=r('
    sudo curl -oL /usr/local/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat\nsudo curl -oL /usr/local/share/xray/geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat\n
    1
    2
    {\n  "log": {\n    "loglevel": "warning",\n    "error": "/var/log/xray/error.log",\n    "access": "/var/log/xray/access.log"\n  },\n  "inbounds": [\n    {\n      "tag": "all-in",\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy"\n        }\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "tag": "direct",\n      "protocol": "freedom",\n      "settings": {\n        "domainStrategy": "UseIPv4"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    },\n    {\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "服务端域名",\n            "port": 443,\n            "users": [\n              {\n                "id": "UUID",\n                "flow": "xtls-rprx-vision",\n                "encryption": "none"\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "xtls",\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    },\n    {\n      "tag": "block",\n      "protocol": "blackhole",\n      "settings": {\n        "response": {\n          "type": "http"\n        }\n      }\n    },\n    {\n      "tag": "dns-out",\n      "protocol": "dns",\n      "settings": {\n        "address": "8.8.8.8"\n      },\n      "proxySettings": {\n        "tag": "proxy"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    }\n  ],\n  "dns": {\n    "hosts": {\n      "服务端域名": "服务端 IP"\n    },\n    "servers": [\n      {\n        "address": "119.29.29.29",\n        "port": 53,\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      {\n        "address": "223.5.5.5",\n        "port": 53,\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      "8.8.8.8",\n      "1.1.1.1",\n      "https+local://doh.dns.sb/dns-query"\n    ]\n  },\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 53,\n        "outboundTag": "dns-out"\n      },\n      {\n        "type": "field",\n        "ip": ["8.8.8.8", "1.1.1.1"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:geolocation-!cn"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "ip": ["geoip:telegram"],\n        "outboundTag": "proxy"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144

    TIP

    本配置会劫持所有发往 53 端口的流量以解决 DNS 污染问题,所以客户端和本机的 DNS 服务器的地址可以随意配置。

    策略路由配置

    sudo ip route add local default dev lo table 100 # 添加路由表 100\nsudo ip rule add fwmark 1 table 100 # 为路由表 100 设定规则\n
    1
    2

    Netfilter 配置

    注意

    nftables 配置与 iptables 配置二选一,不可同时使用。

    ',7),j=t("div",{class:"language-nftables ext-nftables line-numbers-mode"},[t("pre",{class:"language-nftables"},[t("code",null,"#!/usr/sbin/nft -f\n\nflush ruleset\n\ndefine RESERVED_IP = {\n 10.0.0.0/8,\n 100.64.0.0/10,\n 127.0.0.0/8,\n 169.254.0.0/16,\n 172.16.0.0/12,\n 192.0.0.0/24,\n 224.0.0.0/4,\n 240.0.0.0/4,\n 255.255.255.255/32\n}\n\ntable ip xray {\n chain prerouting {\n type filter hook prerouting priority mangle; policy accept;\n ip daddr $RESERVED_IP return\n ip daddr 192.168.0.0/16 tcp dport != 53 return\n ip daddr 192.168.0.0/16 udp dport != 53 return\n ip protocol tcp tproxy to 127.0.0.1:12345 meta mark set 1\n ip protocol udp tproxy to 127.0.0.1:12345 meta mark set 1\n }\n chain output {\n type route hook output priority mangle; policy accept;\n ip daddr $RESERVED_IP return\n ip daddr 192.168.0.0/16 tcp dport != 53 return\n ip daddr 192.168.0.0/16 udp dport != 53 return\n meta mark 2 return\n ip protocol tcp meta mark set 1\n ip protocol udp meta mark set 1\n }\n}\n")]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br"),t("span",{class:"line-number"},"21"),t("br"),t("span",{class:"line-number"},"22"),t("br"),t("span",{class:"line-number"},"23"),t("br"),t("span",{class:"line-number"},"24"),t("br"),t("span",{class:"line-number"},"25"),t("br"),t("span",{class:"line-number"},"26"),t("br"),t("span",{class:"line-number"},"27"),t("br"),t("span",{class:"line-number"},"28"),t("br"),t("span",{class:"line-number"},"29"),t("br"),t("span",{class:"line-number"},"30"),t("br"),t("span",{class:"line-number"},"31"),t("br"),t("span",{class:"line-number"},"32"),t("br"),t("span",{class:"line-number"},"33"),t("br"),t("span",{class:"line-number"},"34"),t("br"),t("span",{class:"line-number"},"35"),t("br")])],-1),Y=t("div",{class:"custom-container tip"},[t("p",{class:"custom-container-title"},"使用方法"),t("p",null,[l("将上述配置写入一个文件(如 "),t("code",null,"nft.conf"),l("),之后将该文件赋予可执行权限,最后使用 root 权限执行该文件即可("),t("code",null,"# ./nft.conf"),l(")。")])],-1),U=t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[l("iptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"10.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"100.64"),l(".0.0/10 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"127.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"169.254"),l(".0.0/16 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"172.16"),l(".0.0/12 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.0"),l(".0.0/24 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"224.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"240.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"255.255"),l(".255.255/32 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p tcp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p udp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),t("span",{class:"token number"},"12345"),l(" --tproxy-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),t("span",{class:"token number"},"12345"),l(" --tproxy-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A PREROUTING -j XRAY\n\niptables -t mangle -N XRAY_SELF\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"10.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"100.64"),l(".0.0/10 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"127.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"169.254"),l(".0.0/16 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"172.16"),l(".0.0/12 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.0"),l(".0.0/24 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"224.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"240.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"255.255"),l(".255.255/32 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p tcp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p udp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -m mark --mark "),t("span",{class:"token number"},"2"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -p tcp -j MARK --set-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A XRAY_SELF -p udp -j MARK --set-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A OUTPUT -j XRAY_SELF\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br"),t("span",{class:"line-number"},"21"),t("br"),t("span",{class:"line-number"},"22"),t("br"),t("span",{class:"line-number"},"23"),t("br"),t("span",{class:"line-number"},"24"),t("br"),t("span",{class:"line-number"},"25"),t("br"),t("span",{class:"line-number"},"26"),t("br"),t("span",{class:"line-number"},"27"),t("br"),t("span",{class:"line-number"},"28"),t("br"),t("span",{class:"line-number"},"29"),t("br"),t("span",{class:"line-number"},"30"),t("br"),t("span",{class:"line-number"},"31"),t("br"),t("span",{class:"line-number"},"32"),t("br")])],-1),N=t("p",null,"配置完成后,将局域网内其它设备的默认网关改为该设备 IP,就可以直接翻墙了。在其它主机和本机皆测试成功后,可进行下一步配置。",-1),_=t("h2",{id:"配置永久化与开机自启",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#配置永久化与开机自启","aria-hidden":"true"},"#"),l(" 配置永久化与开机自启")],-1),L=t("br",null,null,-1),P=t("p",null,[l("首先将已经编辑好的 nftables 配置文件移动到 "),t("code",null,"/etc"),l(" 目录下,并重命名为 "),t("code",null,"nftables.conf"),l("。然后编辑 "),t("code",null,"/lib/systemd/system/nftables.service"),l("。")],-1),w=t("div",{class:"language-ini ext-ini line-numbers-mode"},[t("pre",{class:"language-ini"},[t("code",null,[t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Unit"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Description"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"nftables"),l("\n"),t("span",{class:"token key attr-name"},"Documentation"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"man:nft(8) http://wiki.nftables.org"),l("\n"),t("span",{class:"token key attr-name"},"Wants"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target"),l("\n"),t("span",{class:"token key attr-name"},"Before"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"Conflicts"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"DefaultDependencies"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"no"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Service"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Type"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"oneshot"),l("\n"),t("span",{class:"token key attr-name"},"RemainAfterExit"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"yes"),l("\n"),t("span",{class:"token key attr-name"},"StandardInput"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"null"),l("\n"),t("span",{class:"token key attr-name"},"ProtectSystem"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"full"),l("\n"),t("span",{class:"token key attr-name"},"ProtectHome"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"true"),l("\n"),t("span",{class:"token key attr-name"},"ExecStart"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft -f /etc/nftables.conf ; /usr/sbin/ip route add local default dev lo table 100 ; /usr/sbin/ip rule add fwmark 1 table 100"),l("\n"),t("span",{class:"token key attr-name"},"ExecReload"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft -f /etc/nftables.conf"),l("\n"),t("span",{class:"token key attr-name"},"ExecStop"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft flush ruleset ; /usr/sbin/ip route del local default dev lo table 100 ; /usr/sbin/ip rule del table 100"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Install"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"WantedBy"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"sysinit.target"),l("\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br")])],-1),I=t("p",null,"最后 enable 即可。",-1),F=t("p",null,[l("关于 iptables 的永久化,建议直接安装 "),t("code",null,"iptables-persistent"),l("。")],-1),D=t("p",null,[l("安装过程中会提示你选择“是否保存配置”,如果已经将 iptables 配置写入系统,那么此时选择“是”即可;如果尚未写入也没有关系,安装完毕后将配置写入,然后执行 "),t("code",null,"netfilter-persistent save"),l(" 即可(需要 root 权限)。")],-1),O=t("p",null,[l("之后编辑 "),t("code",null,"/lib/systemd/system/netfilter-persistent.service"),l("。")],-1),V=t("div",{class:"language-ini ext-ini line-numbers-mode"},[t("pre",{class:"language-ini"},[t("code",null,[t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Unit"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Description"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"netfilter persistent configuration"),l("\n"),t("span",{class:"token key attr-name"},"DefaultDependencies"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"no"),l("\n"),t("span",{class:"token key attr-name"},"Wants"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target systemd-modules-load.service local-fs.target"),l("\n"),t("span",{class:"token key attr-name"},"Before"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"After"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"systemd-modules-load.service local-fs.target"),l("\n"),t("span",{class:"token key attr-name"},"Conflicts"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"Documentation"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"man:netfilter-persistent(8)"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Service"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Type"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"oneshot"),l("\n"),t("span",{class:"token key attr-name"},"RemainAfterExit"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"yes"),l("\n"),t("span",{class:"token key attr-name"},"ExecStart"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/netfilter-persistent start ; /usr/sbin/ip route add local default dev lo table 100 ; /usr/sbin/ip rule add fwmark 1 table 100"),l("\n"),t("span",{class:"token key attr-name"},"ExecStop"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/netfilter-persistent stop ; /usr/sbin/ip route flush dev lo table 100 ; /usr/sbin/ip rule del table 100"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Install"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"WantedBy"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"multi-user.target"),l("\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br")])],-1);u.render=function(l,r){const u=n("OutboundLink"),B=n("Tab"),W=n("Tabs");return s(),a(o,null,[c,t("p",null,[i,t("a",b,[k,p(u)]),m]),q,d,g,t("p",null,[y,t("a",v,[f,p(u)]),R]),h,A,t("p",null,[E,t("a",x,[T,p(u)]),S]),X,p(W,{title:"netfilter"},{default:e((()=>[p(B,{title:"nftables1"},{default:e((()=>[j,Y])),_:1}),p(B,{title:"iptables1"},{default:e((()=>[U])),_:1})])),_:1}),N,_,L,p(W,{title:"netfilter2"},{default:e((()=>[p(B,{title:"nftables2"},{default:e((()=>[P,w,I])),_:1}),p(B,{title:"iptables2"},{default:e((()=>[F,D,O,V])),_:1})])),_:1})],64)};export default u; +import{r as n,o as s,c as a,a as t,b as p,w as e,F as o,e as l,d as r}from"./app.48111a85.js";const u={},c=t("h1",{id:"透明代理-tproxy-配置教程",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#透明代理-tproxy-配置教程","aria-hidden":"true"},"#"),l(" 透明代理(TProxy)配置教程")],-1),i=l("本配置基于"),b={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},k=l("TProxy 透明代理的新 V2Ray 白话文教程"),m=l(",加入了 Xray 的新特性,使用 VLESS + XTLS Vision 方案,并将旧教程中默认出站代理的分流方式改为默认出站直连,使用者请按照实际情况进行修改。"),q=t("p",null,"本文中所有配置已在 Raspberry Pi 2B、Ubuntu 20.04 环境下测试成功,如在其它环境中使用请自行调整配置。",-1),d=t("h2",{id:"开始之前",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#开始之前","aria-hidden":"true"},"#"),l(" 开始之前")],-1),g=t("p",null,"请检查您的设备是否有可用的网络连接,且服务端已经配置成功,客户端已经安装完毕。",-1),y=l("需注意的是,目前很多透明代理教程都会将 Linux 系统的 IP 转发打开,但这样会导致 Splice 性能下降。详情请参考"),v={href:"https://github.com/XTLS/Xray-core/discussions/59",target:"_blank",rel:"noopener noreferrer"},f=l("大案牍术破案纪实第三篇--我们是如何破解 Splice 性能下降甚至低于 Direct 之谜的"),R=l("。"),h=t("p",null,"这里我想要补充的是,很多透明代理教程会使用 Netfilter 进行分流,使直连流量直接发出而不经过 Xray,这时必须开启 IP 转发;也有的教程,如本文,会将所有流量导入 Xray 之中,由 Xray 的路由模块进行分流,这时无需开启 IP 转发。",-1),A=t("h2",{id:"xray-配置",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#xray-配置","aria-hidden":"true"},"#"),l(" Xray 配置")],-1),E=l("为了更好的分流体验,请替换默认路由规则文件为 "),x={href:"https://github.com/Loyalsoldier/v2ray-rules-dat",target:"_blank",rel:"noopener noreferrer"},T=l("Loyalsoldier/v2ray-rules-dat"),S=l(",否则 Xray-core 将无法加载本配置。"),X=r('
    sudo curl -oL /usr/local/share/xray/geoip.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat\nsudo curl -oL /usr/local/share/xray/geosite.dat https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat\n
    1
    2
    {\n  "log": {\n    "loglevel": "warning",\n    "error": "/var/log/xray/error.log",\n    "access": "/var/log/xray/access.log"\n  },\n  "inbounds": [\n    {\n      "tag": "all-in",\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy"\n        }\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "tag": "direct",\n      "protocol": "freedom",\n      "settings": {\n        "domainStrategy": "UseIPv4"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    },\n    {\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "服务端域名",\n            "port": 443,\n            "users": [\n              {\n                "id": "UUID",\n                "flow": "xtls-rprx-vision",\n                "encryption": "none"\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "xtls",\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    },\n    {\n      "tag": "block",\n      "protocol": "blackhole",\n      "settings": {\n        "response": {\n          "type": "http"\n        }\n      }\n    },\n    {\n      "tag": "dns-out",\n      "protocol": "dns",\n      "settings": {\n        "address": "8.8.8.8"\n      },\n      "proxySettings": {\n        "tag": "proxy"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 2\n        }\n      }\n    }\n  ],\n  "dns": {\n    "hosts": {\n      "服务端域名": "服务端 IP"\n    },\n    "servers": [\n      {\n        "address": "119.29.29.29",\n        "port": 53,\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      {\n        "address": "223.5.5.5",\n        "port": 53,\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      "8.8.8.8",\n      "1.1.1.1",\n      "https+local://doh.dns.sb/dns-query"\n    ]\n  },\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 53,\n        "outboundTag": "dns-out"\n      },\n      {\n        "type": "field",\n        "ip": ["8.8.8.8", "1.1.1.1"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:geolocation-!cn"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "ip": ["geoip:telegram"],\n        "outboundTag": "proxy"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144

    TIP

    本配置会劫持所有发往 53 端口的流量以解决 DNS 污染问题,所以客户端和本机的 DNS 服务器的地址可以随意配置。

    策略路由配置

    sudo ip route add local default dev lo table 100 # 添加路由表 100\nsudo ip rule add fwmark 1 table 100 # 为路由表 100 设定规则\n
    1
    2

    Netfilter 配置

    注意

    nftables 配置与 iptables 配置二选一,不可同时使用。

    ',7),j=t("div",{class:"language-nftables ext-nftables line-numbers-mode"},[t("pre",{class:"language-nftables"},[t("code",null,"#!/usr/sbin/nft -f\n\nflush ruleset\n\ndefine RESERVED_IP = {\n 10.0.0.0/8,\n 100.64.0.0/10,\n 127.0.0.0/8,\n 169.254.0.0/16,\n 172.16.0.0/12,\n 192.0.0.0/24,\n 224.0.0.0/4,\n 240.0.0.0/4,\n 255.255.255.255/32\n}\n\ntable ip xray {\n chain prerouting {\n type filter hook prerouting priority mangle; policy accept;\n ip daddr $RESERVED_IP return\n ip daddr 192.168.0.0/16 tcp dport != 53 return\n ip daddr 192.168.0.0/16 udp dport != 53 return\n ip protocol tcp tproxy to 127.0.0.1:12345 meta mark set 1\n ip protocol udp tproxy to 127.0.0.1:12345 meta mark set 1\n }\n chain output {\n type route hook output priority mangle; policy accept;\n ip daddr $RESERVED_IP return\n ip daddr 192.168.0.0/16 tcp dport != 53 return\n ip daddr 192.168.0.0/16 udp dport != 53 return\n meta mark 2 return\n ip protocol tcp meta mark set 1\n ip protocol udp meta mark set 1\n }\n}\n")]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br"),t("span",{class:"line-number"},"21"),t("br"),t("span",{class:"line-number"},"22"),t("br"),t("span",{class:"line-number"},"23"),t("br"),t("span",{class:"line-number"},"24"),t("br"),t("span",{class:"line-number"},"25"),t("br"),t("span",{class:"line-number"},"26"),t("br"),t("span",{class:"line-number"},"27"),t("br"),t("span",{class:"line-number"},"28"),t("br"),t("span",{class:"line-number"},"29"),t("br"),t("span",{class:"line-number"},"30"),t("br"),t("span",{class:"line-number"},"31"),t("br"),t("span",{class:"line-number"},"32"),t("br"),t("span",{class:"line-number"},"33"),t("br"),t("span",{class:"line-number"},"34"),t("br"),t("span",{class:"line-number"},"35"),t("br")])],-1),Y=t("div",{class:"custom-container tip"},[t("p",{class:"custom-container-title"},"使用方法"),t("p",null,[l("将上述配置写入一个文件(如 "),t("code",null,"nft.conf"),l("),之后将该文件赋予可执行权限,最后使用 root 权限执行该文件即可("),t("code",null,"# ./nft.conf"),l(")。")])],-1),U=t("div",{class:"language-bash ext-sh line-numbers-mode"},[t("pre",{class:"language-bash"},[t("code",null,[l("iptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"10.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"100.64"),l(".0.0/10 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"127.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"169.254"),l(".0.0/16 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"172.16"),l(".0.0/12 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.0"),l(".0.0/24 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"224.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"240.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"255.255"),l(".255.255/32 -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p tcp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p udp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),t("span",{class:"token number"},"12345"),l(" --tproxy-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),t("span",{class:"token number"},"12345"),l(" --tproxy-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A PREROUTING -j XRAY\n\niptables -t mangle -N XRAY_SELF\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"10.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"100.64"),l(".0.0/10 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"127.0"),l(".0.0/8 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"169.254"),l(".0.0/16 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"172.16"),l(".0.0/12 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.0"),l(".0.0/24 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"224.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"240.0"),l(".0.0/4 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"255.255"),l(".255.255/32 -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p tcp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -d "),t("span",{class:"token number"},"192.168"),l(".0.0/16 -p udp "),t("span",{class:"token operator"},"!"),l(" --dport "),t("span",{class:"token number"},"53"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -m mark --mark "),t("span",{class:"token number"},"2"),l(" -j RETURN\niptables -t mangle -A XRAY_SELF -p tcp -j MARK --set-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A XRAY_SELF -p udp -j MARK --set-mark "),t("span",{class:"token number"},"1"),l("\niptables -t mangle -A OUTPUT -j XRAY_SELF\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br"),t("span",{class:"line-number"},"21"),t("br"),t("span",{class:"line-number"},"22"),t("br"),t("span",{class:"line-number"},"23"),t("br"),t("span",{class:"line-number"},"24"),t("br"),t("span",{class:"line-number"},"25"),t("br"),t("span",{class:"line-number"},"26"),t("br"),t("span",{class:"line-number"},"27"),t("br"),t("span",{class:"line-number"},"28"),t("br"),t("span",{class:"line-number"},"29"),t("br"),t("span",{class:"line-number"},"30"),t("br"),t("span",{class:"line-number"},"31"),t("br"),t("span",{class:"line-number"},"32"),t("br")])],-1),N=t("p",null,"配置完成后,将局域网内其它设备的默认网关改为该设备 IP,就可以直接翻墙了。在其它主机和本机皆测试成功后,可进行下一步配置。",-1),_=t("h2",{id:"配置永久化与开机自启",tabindex:"-1"},[t("a",{class:"header-anchor",href:"#配置永久化与开机自启","aria-hidden":"true"},"#"),l(" 配置永久化与开机自启")],-1),L=t("br",null,null,-1),P=t("p",null,[l("首先将已经编辑好的 nftables 配置文件移动到 "),t("code",null,"/etc"),l(" 目录下,并重命名为 "),t("code",null,"nftables.conf"),l("。然后编辑 "),t("code",null,"/lib/systemd/system/nftables.service"),l("。")],-1),w=t("div",{class:"language-ini ext-ini line-numbers-mode"},[t("pre",{class:"language-ini"},[t("code",null,[t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Unit"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Description"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"nftables"),l("\n"),t("span",{class:"token key attr-name"},"Documentation"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"man:nft(8) http://wiki.nftables.org"),l("\n"),t("span",{class:"token key attr-name"},"Wants"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target"),l("\n"),t("span",{class:"token key attr-name"},"Before"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"Conflicts"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"DefaultDependencies"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"no"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Service"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Type"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"oneshot"),l("\n"),t("span",{class:"token key attr-name"},"RemainAfterExit"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"yes"),l("\n"),t("span",{class:"token key attr-name"},"StandardInput"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"null"),l("\n"),t("span",{class:"token key attr-name"},"ProtectSystem"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"full"),l("\n"),t("span",{class:"token key attr-name"},"ProtectHome"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"true"),l("\n"),t("span",{class:"token key attr-name"},"ExecStart"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft -f /etc/nftables.conf ; /usr/sbin/ip route add local default dev lo table 100 ; /usr/sbin/ip rule add fwmark 1 table 100"),l("\n"),t("span",{class:"token key attr-name"},"ExecReload"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft -f /etc/nftables.conf"),l("\n"),t("span",{class:"token key attr-name"},"ExecStop"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/nft flush ruleset ; /usr/sbin/ip route del local default dev lo table 100 ; /usr/sbin/ip rule del table 100"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Install"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"WantedBy"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"sysinit.target"),l("\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br"),t("span",{class:"line-number"},"18"),t("br"),t("span",{class:"line-number"},"19"),t("br"),t("span",{class:"line-number"},"20"),t("br")])],-1),I=t("p",null,"最后 enable 即可。",-1),F=t("p",null,[l("关于 iptables 的永久化,建议直接安装 "),t("code",null,"iptables-persistent"),l("。")],-1),D=t("p",null,[l("安装过程中会提示你选择“是否保存配置”,如果已经将 iptables 配置写入系统,那么此时选择“是”即可;如果尚未写入也没有关系,安装完毕后将配置写入,然后执行 "),t("code",null,"netfilter-persistent save"),l(" 即可(需要 root 权限)。")],-1),O=t("p",null,[l("之后编辑 "),t("code",null,"/lib/systemd/system/netfilter-persistent.service"),l("。")],-1),V=t("div",{class:"language-ini ext-ini line-numbers-mode"},[t("pre",{class:"language-ini"},[t("code",null,[t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Unit"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Description"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"netfilter persistent configuration"),l("\n"),t("span",{class:"token key attr-name"},"DefaultDependencies"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"no"),l("\n"),t("span",{class:"token key attr-name"},"Wants"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target systemd-modules-load.service local-fs.target"),l("\n"),t("span",{class:"token key attr-name"},"Before"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"network-pre.target shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"After"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"systemd-modules-load.service local-fs.target"),l("\n"),t("span",{class:"token key attr-name"},"Conflicts"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"shutdown.target"),l("\n"),t("span",{class:"token key attr-name"},"Documentation"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"man:netfilter-persistent(8)"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Service"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"Type"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"oneshot"),l("\n"),t("span",{class:"token key attr-name"},"RemainAfterExit"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"yes"),l("\n"),t("span",{class:"token key attr-name"},"ExecStart"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/netfilter-persistent start ; /usr/sbin/ip route add local default dev lo table 100 ; /usr/sbin/ip rule add fwmark 1 table 100"),l("\n"),t("span",{class:"token key attr-name"},"ExecStop"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"/usr/sbin/netfilter-persistent stop ; /usr/sbin/ip route flush dev lo table 100 ; /usr/sbin/ip rule del table 100"),l("\n\n"),t("span",{class:"token header"},[t("span",{class:"token punctuation"},"["),t("span",{class:"token section-name selector"},"Install"),t("span",{class:"token punctuation"},"]")]),l("\n"),t("span",{class:"token key attr-name"},"WantedBy"),t("span",{class:"token punctuation"},"="),t("span",{class:"token value attr-value"},"multi-user.target"),l("\n")])]),t("div",{class:"line-numbers"},[t("span",{class:"line-number"},"1"),t("br"),t("span",{class:"line-number"},"2"),t("br"),t("span",{class:"line-number"},"3"),t("br"),t("span",{class:"line-number"},"4"),t("br"),t("span",{class:"line-number"},"5"),t("br"),t("span",{class:"line-number"},"6"),t("br"),t("span",{class:"line-number"},"7"),t("br"),t("span",{class:"line-number"},"8"),t("br"),t("span",{class:"line-number"},"9"),t("br"),t("span",{class:"line-number"},"10"),t("br"),t("span",{class:"line-number"},"11"),t("br"),t("span",{class:"line-number"},"12"),t("br"),t("span",{class:"line-number"},"13"),t("br"),t("span",{class:"line-number"},"14"),t("br"),t("span",{class:"line-number"},"15"),t("br"),t("span",{class:"line-number"},"16"),t("br"),t("span",{class:"line-number"},"17"),t("br")])],-1);u.render=function(l,r){const u=n("OutboundLink"),B=n("Tab"),W=n("Tabs");return s(),a(o,null,[c,t("p",null,[i,t("a",b,[k,p(u)]),m]),q,d,g,t("p",null,[y,t("a",v,[f,p(u)]),R]),h,A,t("p",null,[E,t("a",x,[T,p(u)]),S]),X,p(W,{title:"netfilter"},{default:e((()=>[p(B,{title:"nftables1"},{default:e((()=>[j,Y])),_:1}),p(B,{title:"iptables1"},{default:e((()=>[U])),_:1})])),_:1}),N,_,L,p(W,{title:"netfilter2"},{default:e((()=>[p(B,{title:"nftables2"},{default:e((()=>[P,w,I])),_:1}),p(B,{title:"iptables2"},{default:e((()=>[F,D,O,V])),_:1})])),_:1})],64)};export default u; diff --git a/assets/tproxy_ipv4_and_ipv6.html.1da96407.js b/assets/tproxy_ipv4_and_ipv6.html.05f651ce.js similarity index 99% rename from assets/tproxy_ipv4_and_ipv6.html.1da96407.js rename to assets/tproxy_ipv4_and_ipv6.html.05f651ce.js index 2e26e46cc..663e59399 100644 --- a/assets/tproxy_ipv4_and_ipv6.html.1da96407.js +++ b/assets/tproxy_ipv4_and_ipv6.html.05f651ce.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as t,F as e,e as o,d as l}from"./app.755d843f.js";const r={},c=p("h1",{id:"tproxy-透明代理-ipv4-and-ipv6-配置教程",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#tproxy-透明代理-ipv4-and-ipv6-配置教程","aria-hidden":"true"},"#"),o(" TProxy 透明代理(ipv4 and ipv6)配置教程")],-1),u=o("本配置参考了"),i={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},b=o("TProxy 透明代理的新 V2Ray 白话文教程"),k=o(","),m={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"},d=o("透明代理(TProxy)配置教程"),q=o("以及"),g={href:"https://xtls.github.io/document/level-2/iptables_gid.html",target:"_blank",rel:"noopener noreferrer"},y=o("透明代理通过 gid 规避 Xray 流量"),h=o(",加入了透明代理对 ipv6 的支持,并且使用 VLESS-TCP-XTLS-RPRX-Vision 方案对抗封锁 (推荐使用 1.7.2 及之后版本)。"),f=o("关于 Xray 的配置并不是本文重点,使用者可依实际情况进行修改,具体可以参考"),v={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},x=o("官方文档示例"),R=o("或其他优秀示例 比如"),A={href:"https://github.com/chika0801/Xray-examples",target:"_blank",rel:"noopener noreferrer"},T=o("@chika0801"),E=o(" 又如"),X={href:"https://github.com/lxhao61/integrated-examples",target:"_blank",rel:"noopener noreferrer"},S=o("@lxhao61"),P=o("。"),j=l('

    注意

    若使用其他配置,你需要着重注意客户端配置中 outboundtagproxy 的部分,其他部分不变

    服务端配置也要同时改变

    此配置意在解决例如 Netflix 等默认使用 ipv6 连接的网站无法通过旁路由进行代理的问题,或对 ipv6 代理有需要。

    本文网络结构为单臂旁路由

    本文中所有配置已在 Arch Linux (Kernel: 6.0.10) 环境下测试成功,如在其它环境中同理

    注意安装相应程序 # sudo apt install iptables ip6tables# sudo apt install nftables

    ',5),w=o("若旁路由未安装 xray 程序,可以手动下载相应 xray 程序如 "),N={href:"https://github.com/XTLS/Xray-core/releases/download/v1.7.0/Xray-linux-64.zip",target:"_blank",rel:"noopener noreferrer"},Y=o("Xray-linux-64.zip"),I=o(" ,然后复制 "),_={href:"https://github.com/XTLS/Xray-install/blob/main/install-release.sh",target:"_blank",rel:"noopener noreferrer"},U=o("install-release.sh"),M=o(" 文件到旁路由,赋予可执行权限 "),K=p("code",null,"# chmod 700 install-release.sh",-1),V=o(",然后使用 "),D=p("code",null,"# ./install-release.sh --local Xray-linux-64.zip",-1),O=o(" 根据提示进行本地安装。"),B=l('

    Xray 配置

    客户端配置

    {\n  "log": {\n    "loglevel": "warning"\n  },\n  "inbounds": [\n    {\n      "tag": "all-in",\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls", "quic"]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy",\n          "mark": 255\n        }\n      }\n    },\n    {\n      "port": 10808,\n      "protocol": "socks",\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls", "quic"]\n      },\n      "settings": {\n        "auth": "noauth",\n        "udp": true\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      //此为默认outbound,路由(routing)模块若未匹配到任何规则,则默认走此 proxy 出口,如果你希望直连国内优先请将下面 direct 出口放到 outbound 第一,看不懂可忽略\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "yourdomain.domain", //改为你自己的域名,直接填写ipv4或ipv6地址也可以\n            "port": 443,\n            "users": [\n              {\n                "id": "uuid", //填写uuid,可通过在终端中输入 xray uuid 生成;此处也支持任意字符串(https://xtls.github.io/config/inbounds/vless.html#clientobject)\n                "encryption": "none",\n                "flow": "xtls-rprx-vision"\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        },\n        "network": "tcp",\n        "security": "tls", //注意使用 xtls-rprx-vision 流控此处需为 tls\n        "tlsSettings": {\n          //注意使用 xtls-rprx-vision 流控此处需为 tlsSettings\n          "allowInsecure": false,\n          "serverName": "yourdomain.domain", //改为你自己的域名\n          "fingerprint": "chrome" //此设置建议先看下Release, https://github.com/XTLS/Xray-core/releases/tag/v1.7.3\n        }\n      }\n    },\n    {\n      "tag": "direct",\n      "protocol": "freedom",\n      "settings": {\n        "domainStrategy": "UseIP"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        }\n      }\n    },\n    {\n      "tag": "block",\n      "protocol": "blackhole",\n      "settings": {\n        "response": {\n          "type": "http"\n        }\n      }\n    },\n    {\n      "tag": "dns-out",\n      "protocol": "dns",\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        }\n      }\n    }\n  ],\n  "dns": {\n    "hosts": {\n      "domain:googleapis.cn": "googleapis.com",\n      "dns.google": "8.8.8.8",\n      "你的VPS域名": "你的VSP IP" //如果 outbound 的 proxy 里 address 填的域名:希望代理走ipv4,这里 VPS IP 填VPS的ipv4, 希望代理走ipv6,这里VPS IP 填VPS的ipv6;outbound 的 proxy 里 address 填的 IP,这行不用写。\n    },\n    "servers": [\n      "https://1.1.1.1/dns-query",\n      {\n        "address": "119.29.29.29",\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      "https://dns.google/dns-query",\n      "223.5.5.5",\n      "localhost"\n    ]\n  },\n  "routing": {\n    "domainMatcher": "mph",\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 123,\n        "network": "udp",\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 53,\n        "network": "udp",\n        "outboundTag": "dns-out"\n      },\n      {\n        "type": "field",\n        "ip": ["119.29.29.29", "223.5.5.5"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "ip": ["geoip:private", "geoip:cn"], //此处可加入 VPS IP 避免 ssh 时被代理\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:cn"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "ip": ["1.1.1.1", "8.8.8.8"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "domain": [\n          "geosite:geolocation-!cn",\n          "domain:googleapis.cn",\n          "dns.google"\n        ],\n        "outboundTag": "proxy"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180

    服务端配置

    {\n  "log": {\n    "loglevel": "warning"\n  },\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        //阻止 cnip 提高安全性,或者可以将 cn 流量导入 warp 中,详见https://xtls.github.io/document/level-2/warp.html\n        "type": "field",\n        "ip": ["geoip:cn"],\n        "outboundTag": "block"\n      }\n    ]\n  },\n  "inbounds": [\n    {\n      "port": 443,\n      "protocol": "vless",\n      "settings": {\n        "clients": [\n          {\n            "id": "uuid", //与客户端相同\n            "flow": "xtls-rprx-vision"\n          }\n        ],\n        "decryption": "none",\n        "fallbacks": [\n          {\n            "dest": 8080 //回落,需要 web 配合,参见白话文,不设置也行\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "tls",\n        "tlsSettings": {\n          "certificates": [\n            {\n              "certificateFile": "/etc/ssl/private/fullchain.crt",\n              "keyFile": "/etc/ssl/private/crt.key" //参照小小白话文将生成的 fullchain.crt 以及 cert.key证书的路径相应填于此处(https://xtls.github.io/document/level-0/ch06-certificates.html#_6-4-%E6%AD%A3%E5%BC%8F%E8%AF%81%E4%B9%A6%E7%94%B3%E8%AF%B7)\n            }\n          ]\n        }\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "freedom",\n      "tag": "direct"\n    },\n    {\n      "protocol": "blackhole",\n      "tag": "block"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62

    Netfilter 配置

    首先设置策略路由

    # 设置策略路由 v4\nip rule add fwmark 1 table 100\nip route add local 0.0.0.0/0 dev lo table 100\n\n# 设置策略路由 v6\nip -6 rule add fwmark 1 table 106\nip -6 route add local ::/0 dev lo table 106\n\n# 直连从主路由发出\nip route add default via 192.168.31.1 #写主路由 ipv4, 采用局域网设备上网设置方法一可不写此命令\nip -6 route add default via fd00:6868:6868::1 #写主路由 ipv6, 采用局域网设备上网设置方法一可不写此命令\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    使用方法

    直接将命令复制到旁路由终端执行

    关于直连从主路由发出

    在旁路由使用命令ip route show,如果使用下属方法一,则default via后应是主路由 ip,无需更改;如使用下述方法二,则default via后应是旁路由 ip,此时直连网站 DNS 解析会回环,造成直连网站无法访问,因此需指定为主路由 ip。

    如果是在路由器上指定了默认网关为旁路由(亦即下述“局域网设备上网设置方法二”),那么就需要设置上述 # 直连从主路由发出 ,除了通过 iproute2 命令行方式设置,也可以通过 dhcpcd 或者 systemctl-network 设置静态 IP,这里以 dhcpcd 为例,编辑 /etc/dhcpcd.conf 文件,在最下方加入如下配置,具体 IP 根据你的实际情况修改,其中 interface 可以通过 # ip link show 查看要设定的网口或者无线设备。

    interface enp0s25\nstatic ip_address=192.168.31.100/24\nstatic ip6_address=fd00:6868:6868::8888/64\nstatic routers=192.168.31.1\nstatic domain_name_servers=192.168.31.1 fd00:6868:6868::1\n
    1
    2
    3
    4
    5

    这样通过静态 IP 设置 IP 及网关后就无需每次开机设置 # 直连从主路由发出

    注意

    以下 nftables 配置与 iptables 配置二选一,不可同时使用。

    使用 iptables

    此处配置将 ipv4 与 ipv6 写在同一文件中。

    # 代理局域网设备 v4\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d 127.0.0.1/32 -j RETURN\niptables -t mangle -A XRAY -d 224.0.0.0/4 -j RETURN\niptables -t mangle -A XRAY -d 255.255.255.255/32 -j RETURN\niptables -t mangle -A XRAY -d 192.168.0.0/16 -p tcp -j RETURN\niptables -t mangle -A XRAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN\niptables -t mangle -A XRAY -j RETURN -m mark --mark 0xff\niptables -t mangle -A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1\niptables -t mangle -A PREROUTING -j XRAY\n\n# 代理局域网设备 v6\nip6tables -t mangle -N XRAY6\nip6tables -t mangle -A XRAY6 -d ::1/128 -j RETURN\nip6tables -t mangle -A XRAY6 -d fe80::/10 -j RETURN\nip6tables -t mangle -A XRAY6 -d fd00::/8 -p tcp -j RETURN\nip6tables -t mangle -A XRAY6 -d fd00::/8 -p udp ! --dport 53 -j RETURN\nip6tables -t mangle -A XRAY6 -j RETURN -m mark --mark 0xff\nip6tables -t mangle -A XRAY6 -p udp -j TPROXY --on-ip ::1 --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A XRAY6 -p tcp -j TPROXY --on-ip ::1 --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A PREROUTING -j XRAY6\n\n# 代理网关本机 v4\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -d 224.0.0.0/4 -j RETURN\niptables -t mangle -A XRAY_MASK -d 255.255.255.255/32 -j RETURN\niptables -t mangle -A XRAY_MASK -d 192.168.0.0/16 -p tcp -j RETURN\niptables -t mangle -A XRAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN\niptables -t mangle -A XRAY_MASK -j RETURN -m mark --mark 0xff\niptables -t mangle -A XRAY_MASK -p udp -j MARK --set-mark 1\niptables -t mangle -A XRAY_MASK -p tcp -j MARK --set-mark 1\niptables -t mangle -A OUTPUT -j XRAY_MASK\n\n# 代理网关本机 v6\nip6tables -t mangle -N XRAY6_MASK\nip6tables -t mangle -A XRAY6_MASK -d fe80::/10 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d fd00::/8 -p tcp -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d fd00::/8 -p udp ! --dport 53 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -j RETURN -m mark --mark 0xff\nip6tables -t mangle -A XRAY6_MASK -p udp -j MARK --set-mark 1\nip6tables -t mangle -A XRAY6_MASK -p tcp -j MARK --set-mark 1\nip6tables -t mangle -A OUTPUT -j XRAY6_MASK\n\n# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v4\niptables -t mangle -N DIVERT\niptables -t mangle -A DIVERT -j MARK --set-mark 1\niptables -t mangle -A DIVERT -j ACCEPT\niptables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT\n\n# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v6\nip6tables -t mangle -N DIVERT\nip6tables -t mangle -A DIVERT -j MARK --set-mark 1\nip6tables -t mangle -A DIVERT -j ACCEPT\nip6tables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56

    使用方法

    将上述配置写入一个文件(如 iptables.rules),之后将该文件赋予可执行权限# chmod 700 ./iptables.rules

    最后使用 root 权限执行该文件即可:# ./iptables.rules# source iptables.rules

    使用 nftables

    此处合并 ipv4 与 ipv6

    #!/usr/sbin/nft -f\n\nflush ruleset\n\ntable inet xray {\n        chain prerouting {\n                type filter hook prerouting priority filter; policy accept;\n                ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return\n                meta l4proto tcp ip daddr 192.168.0.0/16 return\n                ip daddr 192.168.0.0/16 udp dport != 53 return\n                ip6 daddr { ::1, fe80::/10 } return\n                meta l4proto tcp ip6 daddr fd00::/8 return\n                ip6 daddr fd00::/8 udp dport != 53 return\n                meta mark 0x000000ff return\n                meta l4proto { tcp, udp } meta mark set 0x00000001 tproxy ip to 127.0.0.1:12345 accept\n                meta l4proto { tcp, udp } meta mark set 0x00000001 tproxy ip6 to [::1]:12345 accept\n        }\n\n        chain output {\n                type route hook output priority filter; policy accept;\n                ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return\n                meta l4proto tcp ip daddr 192.168.0.0/16 return\n                ip daddr 192.168.0.0/16 udp dport != 53 return\n                ip6 daddr { ::1, fe80::/10 } return\n                meta l4proto tcp ip6 daddr fd00::/8 return\n                ip6 daddr fd00::/8 udp dport != 53 return\n                meta mark 0x000000ff return\n                meta l4proto { tcp, udp } meta mark set 0x00000001 accept\n        }\n\n        chain divert {\n                type filter hook prerouting priority mangle; policy accept;\n                meta l4proto tcp socket transparent 1 meta mark set 0x00000001 accept\n        }\n}\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    使用方法

    将上述配置写入一个文件(如 nftables.rules),之后将该文件赋予可执行权限# chmod 700 ./nftables.rules

    最后使用 root 权限执行该文件即可:# ./nftables.rules# source nftables.rules

    ',22),F=o("其中,网关地址"),C=p("code",null,"192.168.0.0/16",-1),L=o(", "),G=p("code",null,"fd00::/8",-1),W=o("等可由"),z=p("code",null,"ip address | grep -w inet | awk '{print $2}'",-1),$=o("以及"),H=p("code",null,"ip address | grep -w inet6 | awk '{print $2}'",-1),J={href:"https://xtls.github.io/document/level-2/iptables_gid.html#_4-%E8%AE%BE%E7%BD%AE-iptables-%E8%A7%84%E5%88%99",target:"_blank",rel:"noopener noreferrer"},Q=o("获得"),Z=l('

    或者在 windows 网络设置中查看。

    又或者在路由器“上网设置”中查看。

    如果前缀192.168, fd00:相同可不更改,若不同如 fc00:, fe00: 等则更改为相应值,写法可通过 Goolge 搜索得到如 fc00::/7, fe00::/9

    开机自动运行 Netfilter 配置

    首先确认已经运行过上述相应 Netfilter 命令,并且成功测试透明代理配置,以确保接下来输出正确的文件。

    若使用 iptables 配置

    1. 首先通过 # iptables-save > /root/iptables.rulesv4 # ip6tables-save > /root/iptables.rulesv6 将 iptables 配置写入 iptables.rulesv4iptables.rulesv6 文件中

    2. 然后在 /etc/systemd/system/ 目录下创建一个名为 tproxyrules.service 的文件,添加以下内容并保存

    [Unit]\nDescription=Tproxy rules\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStartPre=/bin/sh -c 'until ping -c1 192.168.31.1; do sleep 1; done;'\nExecStart=/sbin/ip rule add fwmark 1 table 100 ; \\\n/sbin/ip -6 rule add fwmark 1 table 106 ; \\\n/sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route add local ::/0 dev lo table 106 ; \\\n/sbin/ip route add default via 192.168.31.1 ; \\\n/sbin/ip -6 route add default via fd00:6868:6868::1 ; \\\n/sbin/iptables-restore /root/iptables.rulesv4 ; \\\n/sbin/ip6tables-restore /root/iptables.rulesv6\nExecStop=/sbin/ip rule del fwmark 1 table 100 ; \\\n/sbin/ip -6 rule del fwmark 1 table 106 ; \\\n/sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route del local ::/0 dev lo table 106 ; \\\n/sbin/ip route del default via 192.168.31.1 ; \\\n/sbin/ip -6 route del default via fd00:6868:6868::1 ; \\\n/sbin/iptables -t mangle -F ; \\\n/sbin/ip6tables -t mangle -F\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    1. 最后执行 systemctl enable tproxyrules 命令。

    如果使用 nftables 配置

    1. 首先通过 # nft list ruleset > /root/nftables.rulesv46 将 nftables 配置写入 nftables.rulesv46 文件中

    2. /etc/systemd/system/ 目录下创建一个名为 tproxyrules.service 的文件,然后添加以下内容并保存

    [Unit]\nDescription=Tproxy rules\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStartPre=/bin/sh -c 'until ping -c1 192.168.31.1; do sleep 1; done;'\nExecStart=/sbin/ip rule add fwmark 1 table 100 ; \\\n/sbin/ip -6 rule add fwmark 1 table 106 ; \\\n/sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route add local ::/0 dev lo table 106 ; \\\n/sbin/ip route add default via 192.168.31.1 ; \\\n/sbin/ip -6 route add default via fd00:6868:6868::1 ; \\\n/sbin/nft -f /root/nftables.rulesv46 ;\nExecStop=/sbin/ip rule del fwmark 1 table 100 ; \\\n/sbin/ip -6 rule del fwmark 1 table 106 ; \\\n/sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route del local ::/0 dev lo table 106 ; \\\n/sbin/ip route del default via 192.168.31.1 ; \\\n/sbin/ip -6 route del default via fd00:6868:6868::1 ; \\\n/sbin/nft flush ruleset\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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 的设置。

    ',33);r.render=function(o,l){const r=n("OutboundLink");return s(),a(e,null,[c,p("p",null,[u,p("a",i,[b,t(r)]),k,p("a",m,[d,t(r)]),q,p("a",g,[y,t(r)]),h]),p("p",null,[f,p("a",v,[x,t(r)]),R,p("a",A,[T,t(r)]),E,p("a",X,[S,t(r)]),P]),j,p("p",null,[w,p("a",N,[Y,t(r)]),I,p("a",_,[U,t(r)]),M,K,V,D,O]),B,p("p",null,[F,C,L,G,W,z,$,H,p("a",J,[Q,t(r)])]),Z],64)};export default r; +import{r as n,o as s,c as a,a as p,b as t,F as e,e as o,d as l}from"./app.48111a85.js";const r={},c=p("h1",{id:"tproxy-透明代理-ipv4-and-ipv6-配置教程",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#tproxy-透明代理-ipv4-and-ipv6-配置教程","aria-hidden":"true"},"#"),o(" TProxy 透明代理(ipv4 and ipv6)配置教程")],-1),u=o("本配置参考了"),i={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},b=o("TProxy 透明代理的新 V2Ray 白话文教程"),k=o(","),m={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"},d=o("透明代理(TProxy)配置教程"),q=o("以及"),g={href:"https://xtls.github.io/document/level-2/iptables_gid.html",target:"_blank",rel:"noopener noreferrer"},y=o("透明代理通过 gid 规避 Xray 流量"),h=o(",加入了透明代理对 ipv6 的支持,并且使用 VLESS-TCP-XTLS-RPRX-Vision 方案对抗封锁 (推荐使用 1.7.2 及之后版本)。"),f=o("关于 Xray 的配置并不是本文重点,使用者可依实际情况进行修改,具体可以参考"),v={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},x=o("官方文档示例"),R=o("或其他优秀示例 比如"),A={href:"https://github.com/chika0801/Xray-examples",target:"_blank",rel:"noopener noreferrer"},T=o("@chika0801"),E=o(" 又如"),X={href:"https://github.com/lxhao61/integrated-examples",target:"_blank",rel:"noopener noreferrer"},S=o("@lxhao61"),P=o("。"),j=l('

    注意

    若使用其他配置,你需要着重注意客户端配置中 outboundtagproxy 的部分,其他部分不变

    服务端配置也要同时改变

    此配置意在解决例如 Netflix 等默认使用 ipv6 连接的网站无法通过旁路由进行代理的问题,或对 ipv6 代理有需要。

    本文网络结构为单臂旁路由

    本文中所有配置已在 Arch Linux (Kernel: 6.0.10) 环境下测试成功,如在其它环境中同理

    注意安装相应程序 # sudo apt install iptables ip6tables# sudo apt install nftables

    ',5),w=o("若旁路由未安装 xray 程序,可以手动下载相应 xray 程序如 "),N={href:"https://github.com/XTLS/Xray-core/releases/download/v1.7.0/Xray-linux-64.zip",target:"_blank",rel:"noopener noreferrer"},Y=o("Xray-linux-64.zip"),I=o(" ,然后复制 "),_={href:"https://github.com/XTLS/Xray-install/blob/main/install-release.sh",target:"_blank",rel:"noopener noreferrer"},U=o("install-release.sh"),M=o(" 文件到旁路由,赋予可执行权限 "),K=p("code",null,"# chmod 700 install-release.sh",-1),V=o(",然后使用 "),D=p("code",null,"# ./install-release.sh --local Xray-linux-64.zip",-1),O=o(" 根据提示进行本地安装。"),B=l('

    Xray 配置

    客户端配置

    {\n  "log": {\n    "loglevel": "warning"\n  },\n  "inbounds": [\n    {\n      "tag": "all-in",\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls", "quic"]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy",\n          "mark": 255\n        }\n      }\n    },\n    {\n      "port": 10808,\n      "protocol": "socks",\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls", "quic"]\n      },\n      "settings": {\n        "auth": "noauth",\n        "udp": true\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      //此为默认outbound,路由(routing)模块若未匹配到任何规则,则默认走此 proxy 出口,如果你希望直连国内优先请将下面 direct 出口放到 outbound 第一,看不懂可忽略\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "yourdomain.domain", //改为你自己的域名,直接填写ipv4或ipv6地址也可以\n            "port": 443,\n            "users": [\n              {\n                "id": "uuid", //填写uuid,可通过在终端中输入 xray uuid 生成;此处也支持任意字符串(https://xtls.github.io/config/inbounds/vless.html#clientobject)\n                "encryption": "none",\n                "flow": "xtls-rprx-vision"\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        },\n        "network": "tcp",\n        "security": "tls", //注意使用 xtls-rprx-vision 流控此处需为 tls\n        "tlsSettings": {\n          //注意使用 xtls-rprx-vision 流控此处需为 tlsSettings\n          "allowInsecure": false,\n          "serverName": "yourdomain.domain", //改为你自己的域名\n          "fingerprint": "chrome" //此设置建议先看下Release, https://github.com/XTLS/Xray-core/releases/tag/v1.7.3\n        }\n      }\n    },\n    {\n      "tag": "direct",\n      "protocol": "freedom",\n      "settings": {\n        "domainStrategy": "UseIP"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        }\n      }\n    },\n    {\n      "tag": "block",\n      "protocol": "blackhole",\n      "settings": {\n        "response": {\n          "type": "http"\n        }\n      }\n    },\n    {\n      "tag": "dns-out",\n      "protocol": "dns",\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        }\n      }\n    }\n  ],\n  "dns": {\n    "hosts": {\n      "domain:googleapis.cn": "googleapis.com",\n      "dns.google": "8.8.8.8",\n      "你的VPS域名": "你的VSP IP" //如果 outbound 的 proxy 里 address 填的域名:希望代理走ipv4,这里 VPS IP 填VPS的ipv4, 希望代理走ipv6,这里VPS IP 填VPS的ipv6;outbound 的 proxy 里 address 填的 IP,这行不用写。\n    },\n    "servers": [\n      "https://1.1.1.1/dns-query",\n      {\n        "address": "119.29.29.29",\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      "https://dns.google/dns-query",\n      "223.5.5.5",\n      "localhost"\n    ]\n  },\n  "routing": {\n    "domainMatcher": "mph",\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 123,\n        "network": "udp",\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 53,\n        "network": "udp",\n        "outboundTag": "dns-out"\n      },\n      {\n        "type": "field",\n        "ip": ["119.29.29.29", "223.5.5.5"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "ip": ["geoip:private", "geoip:cn"], //此处可加入 VPS IP 避免 ssh 时被代理\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:cn"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "ip": ["1.1.1.1", "8.8.8.8"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "domain": [\n          "geosite:geolocation-!cn",\n          "domain:googleapis.cn",\n          "dns.google"\n        ],\n        "outboundTag": "proxy"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180

    服务端配置

    {\n  "log": {\n    "loglevel": "warning"\n  },\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        //阻止 cnip 提高安全性,或者可以将 cn 流量导入 warp 中,详见https://xtls.github.io/document/level-2/warp.html\n        "type": "field",\n        "ip": ["geoip:cn"],\n        "outboundTag": "block"\n      }\n    ]\n  },\n  "inbounds": [\n    {\n      "port": 443,\n      "protocol": "vless",\n      "settings": {\n        "clients": [\n          {\n            "id": "uuid", //与客户端相同\n            "flow": "xtls-rprx-vision"\n          }\n        ],\n        "decryption": "none",\n        "fallbacks": [\n          {\n            "dest": 8080 //回落,需要 web 配合,参见白话文,不设置也行\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "tls",\n        "tlsSettings": {\n          "certificates": [\n            {\n              "certificateFile": "/etc/ssl/private/fullchain.crt",\n              "keyFile": "/etc/ssl/private/crt.key" //参照小小白话文将生成的 fullchain.crt 以及 cert.key证书的路径相应填于此处(https://xtls.github.io/document/level-0/ch06-certificates.html#_6-4-%E6%AD%A3%E5%BC%8F%E8%AF%81%E4%B9%A6%E7%94%B3%E8%AF%B7)\n            }\n          ]\n        }\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "freedom",\n      "tag": "direct"\n    },\n    {\n      "protocol": "blackhole",\n      "tag": "block"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62

    Netfilter 配置

    首先设置策略路由

    # 设置策略路由 v4\nip rule add fwmark 1 table 100\nip route add local 0.0.0.0/0 dev lo table 100\n\n# 设置策略路由 v6\nip -6 rule add fwmark 1 table 106\nip -6 route add local ::/0 dev lo table 106\n\n# 直连从主路由发出\nip route add default via 192.168.31.1 #写主路由 ipv4, 采用局域网设备上网设置方法一可不写此命令\nip -6 route add default via fd00:6868:6868::1 #写主路由 ipv6, 采用局域网设备上网设置方法一可不写此命令\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    使用方法

    直接将命令复制到旁路由终端执行

    关于直连从主路由发出

    在旁路由使用命令ip route show,如果使用下属方法一,则default via后应是主路由 ip,无需更改;如使用下述方法二,则default via后应是旁路由 ip,此时直连网站 DNS 解析会回环,造成直连网站无法访问,因此需指定为主路由 ip。

    如果是在路由器上指定了默认网关为旁路由(亦即下述“局域网设备上网设置方法二”),那么就需要设置上述 # 直连从主路由发出 ,除了通过 iproute2 命令行方式设置,也可以通过 dhcpcd 或者 systemctl-network 设置静态 IP,这里以 dhcpcd 为例,编辑 /etc/dhcpcd.conf 文件,在最下方加入如下配置,具体 IP 根据你的实际情况修改,其中 interface 可以通过 # ip link show 查看要设定的网口或者无线设备。

    interface enp0s25\nstatic ip_address=192.168.31.100/24\nstatic ip6_address=fd00:6868:6868::8888/64\nstatic routers=192.168.31.1\nstatic domain_name_servers=192.168.31.1 fd00:6868:6868::1\n
    1
    2
    3
    4
    5

    这样通过静态 IP 设置 IP 及网关后就无需每次开机设置 # 直连从主路由发出

    注意

    以下 nftables 配置与 iptables 配置二选一,不可同时使用。

    使用 iptables

    此处配置将 ipv4 与 ipv6 写在同一文件中。

    # 代理局域网设备 v4\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d 127.0.0.1/32 -j RETURN\niptables -t mangle -A XRAY -d 224.0.0.0/4 -j RETURN\niptables -t mangle -A XRAY -d 255.255.255.255/32 -j RETURN\niptables -t mangle -A XRAY -d 192.168.0.0/16 -p tcp -j RETURN\niptables -t mangle -A XRAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN\niptables -t mangle -A XRAY -j RETURN -m mark --mark 0xff\niptables -t mangle -A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1\niptables -t mangle -A PREROUTING -j XRAY\n\n# 代理局域网设备 v6\nip6tables -t mangle -N XRAY6\nip6tables -t mangle -A XRAY6 -d ::1/128 -j RETURN\nip6tables -t mangle -A XRAY6 -d fe80::/10 -j RETURN\nip6tables -t mangle -A XRAY6 -d fd00::/8 -p tcp -j RETURN\nip6tables -t mangle -A XRAY6 -d fd00::/8 -p udp ! --dport 53 -j RETURN\nip6tables -t mangle -A XRAY6 -j RETURN -m mark --mark 0xff\nip6tables -t mangle -A XRAY6 -p udp -j TPROXY --on-ip ::1 --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A XRAY6 -p tcp -j TPROXY --on-ip ::1 --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A PREROUTING -j XRAY6\n\n# 代理网关本机 v4\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -d 224.0.0.0/4 -j RETURN\niptables -t mangle -A XRAY_MASK -d 255.255.255.255/32 -j RETURN\niptables -t mangle -A XRAY_MASK -d 192.168.0.0/16 -p tcp -j RETURN\niptables -t mangle -A XRAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN\niptables -t mangle -A XRAY_MASK -j RETURN -m mark --mark 0xff\niptables -t mangle -A XRAY_MASK -p udp -j MARK --set-mark 1\niptables -t mangle -A XRAY_MASK -p tcp -j MARK --set-mark 1\niptables -t mangle -A OUTPUT -j XRAY_MASK\n\n# 代理网关本机 v6\nip6tables -t mangle -N XRAY6_MASK\nip6tables -t mangle -A XRAY6_MASK -d fe80::/10 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d fd00::/8 -p tcp -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d fd00::/8 -p udp ! --dport 53 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -j RETURN -m mark --mark 0xff\nip6tables -t mangle -A XRAY6_MASK -p udp -j MARK --set-mark 1\nip6tables -t mangle -A XRAY6_MASK -p tcp -j MARK --set-mark 1\nip6tables -t mangle -A OUTPUT -j XRAY6_MASK\n\n# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v4\niptables -t mangle -N DIVERT\niptables -t mangle -A DIVERT -j MARK --set-mark 1\niptables -t mangle -A DIVERT -j ACCEPT\niptables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT\n\n# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v6\nip6tables -t mangle -N DIVERT\nip6tables -t mangle -A DIVERT -j MARK --set-mark 1\nip6tables -t mangle -A DIVERT -j ACCEPT\nip6tables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56

    使用方法

    将上述配置写入一个文件(如 iptables.rules),之后将该文件赋予可执行权限# chmod 700 ./iptables.rules

    最后使用 root 权限执行该文件即可:# ./iptables.rules# source iptables.rules

    使用 nftables

    此处合并 ipv4 与 ipv6

    #!/usr/sbin/nft -f\n\nflush ruleset\n\ntable inet xray {\n        chain prerouting {\n                type filter hook prerouting priority filter; policy accept;\n                ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return\n                meta l4proto tcp ip daddr 192.168.0.0/16 return\n                ip daddr 192.168.0.0/16 udp dport != 53 return\n                ip6 daddr { ::1, fe80::/10 } return\n                meta l4proto tcp ip6 daddr fd00::/8 return\n                ip6 daddr fd00::/8 udp dport != 53 return\n                meta mark 0x000000ff return\n                meta l4proto { tcp, udp } meta mark set 0x00000001 tproxy ip to 127.0.0.1:12345 accept\n                meta l4proto { tcp, udp } meta mark set 0x00000001 tproxy ip6 to [::1]:12345 accept\n        }\n\n        chain output {\n                type route hook output priority filter; policy accept;\n                ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return\n                meta l4proto tcp ip daddr 192.168.0.0/16 return\n                ip daddr 192.168.0.0/16 udp dport != 53 return\n                ip6 daddr { ::1, fe80::/10 } return\n                meta l4proto tcp ip6 daddr fd00::/8 return\n                ip6 daddr fd00::/8 udp dport != 53 return\n                meta mark 0x000000ff return\n                meta l4proto { tcp, udp } meta mark set 0x00000001 accept\n        }\n\n        chain divert {\n                type filter hook prerouting priority mangle; policy accept;\n                meta l4proto tcp socket transparent 1 meta mark set 0x00000001 accept\n        }\n}\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    使用方法

    将上述配置写入一个文件(如 nftables.rules),之后将该文件赋予可执行权限# chmod 700 ./nftables.rules

    最后使用 root 权限执行该文件即可:# ./nftables.rules# source nftables.rules

    ',22),F=o("其中,网关地址"),C=p("code",null,"192.168.0.0/16",-1),L=o(", "),G=p("code",null,"fd00::/8",-1),W=o("等可由"),z=p("code",null,"ip address | grep -w inet | awk '{print $2}'",-1),$=o("以及"),H=p("code",null,"ip address | grep -w inet6 | awk '{print $2}'",-1),J={href:"https://xtls.github.io/document/level-2/iptables_gid.html#_4-%E8%AE%BE%E7%BD%AE-iptables-%E8%A7%84%E5%88%99",target:"_blank",rel:"noopener noreferrer"},Q=o("获得"),Z=l('

    或者在 windows 网络设置中查看。

    又或者在路由器“上网设置”中查看。

    如果前缀192.168, fd00:相同可不更改,若不同如 fc00:, fe00: 等则更改为相应值,写法可通过 Goolge 搜索得到如 fc00::/7, fe00::/9

    开机自动运行 Netfilter 配置

    首先确认已经运行过上述相应 Netfilter 命令,并且成功测试透明代理配置,以确保接下来输出正确的文件。

    若使用 iptables 配置

    1. 首先通过 # iptables-save > /root/iptables.rulesv4 # ip6tables-save > /root/iptables.rulesv6 将 iptables 配置写入 iptables.rulesv4iptables.rulesv6 文件中

    2. 然后在 /etc/systemd/system/ 目录下创建一个名为 tproxyrules.service 的文件,添加以下内容并保存

    [Unit]\nDescription=Tproxy rules\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStartPre=/bin/sh -c 'until ping -c1 192.168.31.1; do sleep 1; done;'\nExecStart=/sbin/ip rule add fwmark 1 table 100 ; \\\n/sbin/ip -6 rule add fwmark 1 table 106 ; \\\n/sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route add local ::/0 dev lo table 106 ; \\\n/sbin/ip route add default via 192.168.31.1 ; \\\n/sbin/ip -6 route add default via fd00:6868:6868::1 ; \\\n/sbin/iptables-restore /root/iptables.rulesv4 ; \\\n/sbin/ip6tables-restore /root/iptables.rulesv6\nExecStop=/sbin/ip rule del fwmark 1 table 100 ; \\\n/sbin/ip -6 rule del fwmark 1 table 106 ; \\\n/sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route del local ::/0 dev lo table 106 ; \\\n/sbin/ip route del default via 192.168.31.1 ; \\\n/sbin/ip -6 route del default via fd00:6868:6868::1 ; \\\n/sbin/iptables -t mangle -F ; \\\n/sbin/ip6tables -t mangle -F\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    1. 最后执行 systemctl enable tproxyrules 命令。

    如果使用 nftables 配置

    1. 首先通过 # nft list ruleset > /root/nftables.rulesv46 将 nftables 配置写入 nftables.rulesv46 文件中

    2. /etc/systemd/system/ 目录下创建一个名为 tproxyrules.service 的文件,然后添加以下内容并保存

    [Unit]\nDescription=Tproxy rules\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStartPre=/bin/sh -c 'until ping -c1 192.168.31.1; do sleep 1; done;'\nExecStart=/sbin/ip rule add fwmark 1 table 100 ; \\\n/sbin/ip -6 rule add fwmark 1 table 106 ; \\\n/sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route add local ::/0 dev lo table 106 ; \\\n/sbin/ip route add default via 192.168.31.1 ; \\\n/sbin/ip -6 route add default via fd00:6868:6868::1 ; \\\n/sbin/nft -f /root/nftables.rulesv46 ;\nExecStop=/sbin/ip rule del fwmark 1 table 100 ; \\\n/sbin/ip -6 rule del fwmark 1 table 106 ; \\\n/sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route del local ::/0 dev lo table 106 ; \\\n/sbin/ip route del default via 192.168.31.1 ; \\\n/sbin/ip -6 route del default via fd00:6868:6868::1 ; \\\n/sbin/nft flush ruleset\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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 的设置。

    ',33);r.render=function(o,l){const r=n("OutboundLink");return s(),a(e,null,[c,p("p",null,[u,p("a",i,[b,t(r)]),k,p("a",m,[d,t(r)]),q,p("a",g,[y,t(r)]),h]),p("p",null,[f,p("a",v,[x,t(r)]),R,p("a",A,[T,t(r)]),E,p("a",X,[S,t(r)]),P]),j,p("p",null,[w,p("a",N,[Y,t(r)]),I,p("a",_,[U,t(r)]),M,K,V,D,O]),B,p("p",null,[F,C,L,G,W,z,$,H,p("a",J,[Q,t(r)])]),Z],64)};export default r; diff --git a/assets/tproxy_ipv4_and_ipv6.html.ce2184ec.js b/assets/tproxy_ipv4_and_ipv6.html.1eefa00d.js similarity index 99% rename from assets/tproxy_ipv4_and_ipv6.html.ce2184ec.js rename to assets/tproxy_ipv4_and_ipv6.html.1eefa00d.js index 34720a69a..d66474346 100644 --- a/assets/tproxy_ipv4_and_ipv6.html.ce2184ec.js +++ b/assets/tproxy_ipv4_and_ipv6.html.1eefa00d.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as t,F as e,e as o,d as l}from"./app.755d843f.js";const r={},c=p("h1",{id:"tproxy-透明代理-ipv4-and-ipv6-配置教程",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#tproxy-透明代理-ipv4-and-ipv6-配置教程","aria-hidden":"true"},"#"),o(" TProxy 透明代理(ipv4 and ipv6)配置教程")],-1),u=o("本配置参考了"),i={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},b=o("TProxy 透明代理的新 V2Ray 白话文教程"),k=o(","),m={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"},d=o("透明代理(TProxy)配置教程"),q=o("以及"),g={href:"https://xtls.github.io/document/level-2/iptables_gid.html",target:"_blank",rel:"noopener noreferrer"},y=o("透明代理通过 gid 规避 Xray 流量"),h=o(",加入了透明代理对 ipv6 的支持,并且使用 VLESS-TCP-XTLS-RPRX-Vision 方案对抗封锁 (推荐使用 1.7.2 及之后版本)。"),f=o("关于 Xray 的配置并不是本文重点,使用者可依实际情况进行修改,具体可以参考"),v={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},x=o("官方文档示例"),R=o("或其他优秀示例 比如"),A={href:"https://github.com/chika0801/Xray-examples",target:"_blank",rel:"noopener noreferrer"},T=o("@chika0801"),E=o(" 又如"),X={href:"https://github.com/lxhao61/integrated-examples",target:"_blank",rel:"noopener noreferrer"},S=o("@lxhao61"),P=o("。"),j=l('

    注意

    若使用其他配置,你需要着重注意客户端配置中 outboundtagproxy 的部分,其他部分不变

    服务端配置也要同时改变

    此配置意在解决例如 Netflix 等默认使用 ipv6 连接的网站无法通过旁路由进行代理的问题,或对 ipv6 代理有需要。

    本文网络结构为单臂旁路由

    本文中所有配置已在 Arch Linux (Kernel: 6.0.10) 环境下测试成功,如在其它环境中同理

    注意安装相应程序 # sudo apt install iptables ip6tables# sudo apt install nftables

    ',5),N=o("若旁路由未安装 xray 程序,可以手动下载相应 xray 程序如 "),w={href:"https://github.com/XTLS/Xray-core/releases/download/v1.7.0/Xray-linux-64.zip",target:"_blank",rel:"noopener noreferrer"},I=o("Xray-linux-64.zip"),Y=o(" ,然后复制 "),_={href:"https://github.com/XTLS/Xray-install/blob/main/install-release.sh",target:"_blank",rel:"noopener noreferrer"},U=o("install-release.sh"),M=o(" 文件到旁路由,赋予可执行权限 "),K=p("code",null,"# chmod 700 install-release.sh",-1),V=o(",然后使用 "),D=p("code",null,"# ./install-release.sh --local Xray-linux-64.zip",-1),O=o(" 根据提示进行本地安装。"),B=l('

    Xray 配置

    客户端配置

    {\n  "log": {\n    "loglevel": "warning"\n  },\n  "inbounds": [\n    {\n      "tag": "all-in",\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls", "quic"]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy"\n        }\n      }\n    },\n    {\n      "port": 10808,\n      "protocol": "socks",\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls", "quic"]\n      },\n      "settings": {\n        "auth": "noauth",\n        "udp": true\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      //此为默认outbound,路由(routing)模块若未匹配到任何规则,则默认走此 proxy 出口,如果你希望直连国内优先请将下面 direct 出口放到 outbound 第一,看不懂可忽略\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "yourdomain.domain", //改为你自己的域名,直接填写ipv4或ipv6地址也可以\n            "port": 443,\n            "users": [\n              {\n                "id": "uuid", //填写uuid,可通过在终端中输入 xray uuid 生成;此处也支持任意字符串(https://xtls.github.io/config/inbounds/vless.html#clientobject)\n                "encryption": "none",\n                "flow": "xtls-rprx-vision"\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        },\n        "network": "tcp",\n        "security": "tls", //注意使用 xtls-rprx-vision 流控此处需为 tls\n        "tlsSettings": {\n          //注意使用 xtls-rprx-vision 流控此处需为 tlsSettings\n          "allowInsecure": false,\n          "serverName": "yourdomain.domain", //改为你自己的域名\n          "fingerprint": "chrome" //此设置建议先看下Release, https://github.com/XTLS/Xray-core/releases/tag/v1.7.3\n        }\n      }\n    },\n    {\n      "tag": "direct",\n      "protocol": "freedom",\n      "settings": {\n        "domainStrategy": "UseIP"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        }\n      }\n    },\n    {\n      "tag": "block",\n      "protocol": "blackhole",\n      "settings": {\n        "response": {\n          "type": "http"\n        }\n      }\n    },\n    {\n      "tag": "dns-out",\n      "protocol": "dns",\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        }\n      }\n    }\n  ],\n  "dns": {\n    "hosts": {\n      "domain:googleapis.cn": "googleapis.com",\n      "dns.google": "8.8.8.8",\n      "你的VPS域名": "你的VSP IP" //如果 outbound 的 proxy 里 address 填的域名:希望代理走ipv4,这里 VPS IP 填VPS的ipv4, 希望代理走ipv6,这里VPS IP 填VPS的ipv6;outbound 的 proxy 里 address 填的 IP,这行不用写。\n    },\n    "servers": [\n      "https://1.1.1.1/dns-query",\n      {\n        "address": "119.29.29.29",\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      "https://dns.google/dns-query",\n      "223.5.5.5",\n      "localhost"\n    ]\n  },\n  "routing": {\n    "domainMatcher": "mph",\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 123,\n        "network": "udp",\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 53,\n        "network": "udp",\n        "outboundTag": "dns-out"\n      },\n      {\n        "type": "field",\n        "ip": ["119.29.29.29", "223.5.5.5"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "ip": ["geoip:private", "geoip:cn"], //此处可加入 VPS IP 避免 ssh 时被代理\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:cn"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "ip": ["1.1.1.1", "8.8.8.8"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "domain": [\n          "geosite:geolocation-!cn",\n          "domain:googleapis.cn",\n          "dns.google"\n        ],\n        "outboundTag": "proxy"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179

    服务端配置

    {\n  "log": {\n    "loglevel": "warning"\n  },\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        //阻止 cnip 提高安全性,或者可以将 cn 流量导入 warp 中,详见https://xtls.github.io/document/level-2/warp.html\n        "type": "field",\n        "ip": ["geoip:cn"],\n        "outboundTag": "block"\n      }\n    ]\n  },\n  "inbounds": [\n    {\n      "port": 443,\n      "protocol": "vless",\n      "settings": {\n        "clients": [\n          {\n            "id": "uuid", //与客户端相同\n            "flow": "xtls-rprx-vision"\n          }\n        ],\n        "decryption": "none",\n        "fallbacks": [\n          {\n            "dest": 8080 //回落,需要 web 配合,参见白话文,不设置也行\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "tls",\n        "tlsSettings": {\n          "certificates": [\n            {\n              "certificateFile": "/etc/ssl/private/fullchain.crt",\n              "keyFile": "/etc/ssl/private/crt.key" //参照小小白话文将生成的 fullchain.crt 以及 cert.key证书的路径相应填于此处(https://xtls.github.io/document/level-0/ch06-certificates.html#_6-4-%E6%AD%A3%E5%BC%8F%E8%AF%81%E4%B9%A6%E7%94%B3%E8%AF%B7)\n            }\n          ]\n        }\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "freedom",\n      "tag": "direct"\n    },\n    {\n      "protocol": "blackhole",\n      "tag": "block"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62

    Netfilter 配置

    首先设置策略路由

    # 设置策略路由 v4\nip rule add fwmark 1 table 100\nip route add local 0.0.0.0/0 dev lo table 100\n\n# 设置策略路由 v6\nip -6 rule add fwmark 1 table 106\nip -6 route add local ::/0 dev lo table 106\n\n# 直连从主路由发出\nip route add default via 192.168.31.1 #写主路由 ipv4, 采用局域网设备上网设置方法一可不写此命令\nip -6 route add default via fd00:6868:6868::1 #写主路由 ipv6, 采用局域网设备上网设置方法一可不写此命令\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    使用方法

    直接将命令复制到旁路由终端执行

    关于直连从主路由发出

    在旁路由使用命令ip route show,如果使用下属方法一,则default via后应是主路由 ip,无需更改;如使用下述方法二,则default via后应是旁路由 ip,此时直连网站 DNS 解析会回环,造成直连网站无法访问,因此需指定为主路由 ip。

    如果是在路由器上指定了默认网关为旁路由(亦即下述“局域网设备上网设置方法二”),那么就需要设置上述 # 直连从主路由发出 ,除了通过 iproute2 命令行方式设置,也可以通过 dhcpcd 或者 systemctl-network 设置静态 IP,这里以 dhcpcd 为例,编辑 /etc/dhcpcd.conf 文件,在最下方加入如下配置,具体 IP 根据你的实际情况修改,其中 interface 可以通过 # ip link show 查看要设定的网口或者无线设备。

    interface enp0s25\nstatic ip_address=192.168.31.100/24\nstatic ip6_address=fd00:6868:6868::8888/64\nstatic routers=192.168.31.1\nstatic domain_name_servers=192.168.31.1 fd00:6868:6868::1\n
    1
    2
    3
    4
    5

    这样通过静态 IP 设置 IP 及网关后就无需每次开机设置 # 直连从主路由发出

    注意

    以下 nftables 配置与 iptables 配置二选一,不可同时使用。

    使用 iptables

    此处配置将 ipv4 与 ipv6 写在同一文件中。

    # 代理局域网设备 v4\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d 127.0.0.1/32 -j RETURN\niptables -t mangle -A XRAY -d 224.0.0.0/4 -j RETURN\niptables -t mangle -A XRAY -d 255.255.255.255/32 -j RETURN\niptables -t mangle -A XRAY -d 192.168.0.0/16 -p tcp -j RETURN\niptables -t mangle -A XRAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN\niptables -t mangle -A XRAY -j RETURN -m mark --mark 0xff\niptables -t mangle -A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1\niptables -t mangle -A PREROUTING -j XRAY\n\n# 代理局域网设备 v6\nip6tables -t mangle -N XRAY6\nip6tables -t mangle -A XRAY6 -d ::1/128 -j RETURN\nip6tables -t mangle -A XRAY6 -d fe80::/10 -j RETURN\nip6tables -t mangle -A XRAY6 -d fd00::/8 -p tcp -j RETURN\nip6tables -t mangle -A XRAY6 -d fd00::/8 -p udp ! --dport 53 -j RETURN\nip6tables -t mangle -A XRAY6 -j RETURN -m mark --mark 0xff\nip6tables -t mangle -A XRAY6 -p udp -j TPROXY --on-ip ::1 --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A XRAY6 -p tcp -j TPROXY --on-ip ::1 --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A PREROUTING -j XRAY6\n\n# 代理网关本机 v4\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -d 224.0.0.0/4 -j RETURN\niptables -t mangle -A XRAY_MASK -d 255.255.255.255/32 -j RETURN\niptables -t mangle -A XRAY_MASK -d 192.168.0.0/16 -p tcp -j RETURN\niptables -t mangle -A XRAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN\niptables -t mangle -A XRAY_MASK -j RETURN -m mark --mark 0xff\niptables -t mangle -A XRAY_MASK -p udp -j MARK --set-mark 1\niptables -t mangle -A XRAY_MASK -p tcp -j MARK --set-mark 1\niptables -t mangle -A OUTPUT -j XRAY_MASK\n\n# 代理网关本机 v6\nip6tables -t mangle -N XRAY6_MASK\nip6tables -t mangle -A XRAY6_MASK -d fe80::/10 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d fd00::/8 -p tcp -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d fd00::/8 -p udp ! --dport 53 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -j RETURN -m mark --mark 0xff\nip6tables -t mangle -A XRAY6_MASK -p udp -j MARK --set-mark 1\nip6tables -t mangle -A XRAY6_MASK -p tcp -j MARK --set-mark 1\nip6tables -t mangle -A OUTPUT -j XRAY6_MASK\n\n# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v4\niptables -t mangle -N DIVERT\niptables -t mangle -A DIVERT -j MARK --set-mark 1\niptables -t mangle -A DIVERT -j ACCEPT\niptables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT\n\n# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v6\nip6tables -t mangle -N DIVERT\nip6tables -t mangle -A DIVERT -j MARK --set-mark 1\nip6tables -t mangle -A DIVERT -j ACCEPT\nip6tables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56

    使用方法

    将上述配置写入一个文件(如 iptables.rules),之后将该文件赋予可执行权限# chmod 700 ./iptables.rules

    最后使用 root 权限执行该文件即可:# ./iptables.rules# source iptables.rules

    使用 nftables

    此处合并 ipv4 与 ipv6

    #!/usr/sbin/nft -f\n\nflush ruleset\n\ntable inet xray {\n        chain prerouting {\n                type filter hook prerouting priority filter; policy accept;\n                ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return\n                meta l4proto tcp ip daddr 192.168.0.0/16 return\n                ip daddr 192.168.0.0/16 udp dport != 53 return\n                ip6 daddr { ::1, fe80::/10 } return\n                meta l4proto tcp ip6 daddr fd00::/8 return\n                ip6 daddr fd00::/8 udp dport != 53 return\n                meta mark 0x000000ff return\n                meta l4proto { tcp, udp } meta mark set 0x00000001 tproxy ip to 127.0.0.1:12345 accept\n                meta l4proto { tcp, udp } meta mark set 0x00000001 tproxy ip6 to [::1]:12345 accept\n        }\n\n        chain output {\n                type route hook output priority filter; policy accept;\n                ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return\n                meta l4proto tcp ip daddr 192.168.0.0/16 return\n                ip daddr 192.168.0.0/16 udp dport != 53 return\n                ip6 daddr { ::1, fe80::/10 } return\n                meta l4proto tcp ip6 daddr fd00::/8 return\n                ip6 daddr fd00::/8 udp dport != 53 return\n                meta mark 0x000000ff return\n                meta l4proto { tcp, udp } meta mark set 0x00000001 accept\n        }\n\n        chain divert {\n                type filter hook prerouting priority mangle; policy accept;\n                meta l4proto tcp socket transparent 1 meta mark set 0x00000001 accept\n        }\n}\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    使用方法

    将上述配置写入一个文件(如 nftables.rules),之后将该文件赋予可执行权限# chmod 700 ./nftables.rules

    最后使用 root 权限执行该文件即可:# ./nftables.rules# source nftables.rules

    ',22),F=o("其中,网关地址"),C=p("code",null,"192.168.0.0/16",-1),L=o(", "),G=p("code",null,"fd00::/8",-1),W=o("等可由"),z=p("code",null,"ip address | grep -w inet | awk '{print $2}'",-1),$=o("以及"),H=p("code",null,"ip address | grep -w inet6 | awk '{print $2}'",-1),J={href:"https://xtls.github.io/document/level-2/iptables_gid.html#_4-%E8%AE%BE%E7%BD%AE-iptables-%E8%A7%84%E5%88%99",target:"_blank",rel:"noopener noreferrer"},Q=o("获得"),Z=l('

    或者在 windows 网络设置中查看。

    又或者在路由器“上网设置”中查看。

    如果前缀192.168, fd00:相同可不更改,若不同如 fc00:, fe00: 等则更改为相应值,写法可通过 Goolge 搜索得到如 fc00::/7, fe00::/9

    开机自动运行 Netfilter 配置

    首先确认已经运行过上述相应 Netfilter 命令,并且成功测试透明代理配置,以确保接下来输出正确的文件。

    若使用 iptables 配置

    1. 首先通过 # iptables-save > /root/iptables.rulesv4 # ip6tables-save > /root/iptables.rulesv6 将 iptables 配置写入 iptables.rulesv4iptables.rulesv6 文件中

    2. 然后在 /etc/systemd/system/ 目录下创建一个名为 tproxyrules.service 的文件,添加以下内容并保存

    [Unit]\nDescription=Tproxy rules\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStartPre=/bin/sh -c 'until ping -c1 192.168.31.1; do sleep 1; done;'\nExecStart=/sbin/ip rule add fwmark 1 table 100 ; \\\n/sbin/ip -6 rule add fwmark 1 table 106 ; \\\n/sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route add local ::/0 dev lo table 106 ; \\\n/sbin/ip route add default via 192.168.31.1 ; \\\n/sbin/ip -6 route add default via fd00:6868:6868::1 ; \\\n/sbin/iptables-restore /root/iptables.rulesv4 ; \\\n/sbin/ip6tables-restore /root/iptables.rulesv6\nExecStop=/sbin/ip rule del fwmark 1 table 100 ; \\\n/sbin/ip -6 rule del fwmark 1 table 106 ; \\\n/sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route del local ::/0 dev lo table 106 ; \\\n/sbin/ip route del default via 192.168.31.1 ; \\\n/sbin/ip -6 route del default via fd00:6868:6868::1 ; \\\n/sbin/iptables -t mangle -F ; \\\n/sbin/ip6tables -t mangle -F\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    1. 最后执行 systemctl enable tproxyrules 命令。

    如果使用 nftables 配置

    1. 首先通过 # nft list ruleset > /root/nftables.rulesv46 将 nftables 配置写入 nftables.rulesv46 文件中

    2. /etc/systemd/system/ 目录下创建一个名为 tproxyrules.service 的文件,然后添加以下内容并保存

    [Unit]\nDescription=Tproxy rules\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStartPre=/bin/sh -c 'until ping -c1 192.168.31.1; do sleep 1; done;'\nExecStart=/sbin/ip rule add fwmark 1 table 100 ; \\\n/sbin/ip -6 rule add fwmark 1 table 106 ; \\\n/sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route add local ::/0 dev lo table 106 ; \\\n/sbin/ip route add default via 192.168.31.1 ; \\\n/sbin/ip -6 route add default via fd00:6868:6868::1 ; \\\n/sbin/nft -f /root/nftables.rulesv46 ;\nExecStop=/sbin/ip rule del fwmark 1 table 100 ; \\\n/sbin/ip -6 rule del fwmark 1 table 106 ; \\\n/sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route del local ::/0 dev lo table 106 ; \\\n/sbin/ip route del default via 192.168.31.1 ; \\\n/sbin/ip -6 route del default via fd00:6868:6868::1 ; \\\n/sbin/nft flush ruleset\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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 的设置。

    ',33);r.render=function(o,l){const r=n("OutboundLink");return s(),a(e,null,[c,p("p",null,[u,p("a",i,[b,t(r)]),k,p("a",m,[d,t(r)]),q,p("a",g,[y,t(r)]),h]),p("p",null,[f,p("a",v,[x,t(r)]),R,p("a",A,[T,t(r)]),E,p("a",X,[S,t(r)]),P]),j,p("p",null,[N,p("a",w,[I,t(r)]),Y,p("a",_,[U,t(r)]),M,K,V,D,O]),B,p("p",null,[F,C,L,G,W,z,$,H,p("a",J,[Q,t(r)])]),Z],64)};export default r; +import{r as n,o as s,c as a,a as p,b as t,F as e,e as o,d as l}from"./app.48111a85.js";const r={},c=p("h1",{id:"tproxy-透明代理-ipv4-and-ipv6-配置教程",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#tproxy-透明代理-ipv4-and-ipv6-配置教程","aria-hidden":"true"},"#"),o(" TProxy 透明代理(ipv4 and ipv6)配置教程")],-1),u=o("本配置参考了"),i={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},b=o("TProxy 透明代理的新 V2Ray 白话文教程"),k=o(","),m={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"},d=o("透明代理(TProxy)配置教程"),q=o("以及"),g={href:"https://xtls.github.io/document/level-2/iptables_gid.html",target:"_blank",rel:"noopener noreferrer"},y=o("透明代理通过 gid 规避 Xray 流量"),h=o(",加入了透明代理对 ipv6 的支持,并且使用 VLESS-TCP-XTLS-RPRX-Vision 方案对抗封锁 (推荐使用 1.7.2 及之后版本)。"),f=o("关于 Xray 的配置并不是本文重点,使用者可依实际情况进行修改,具体可以参考"),v={href:"https://github.com/XTLS/Xray-examples",target:"_blank",rel:"noopener noreferrer"},x=o("官方文档示例"),R=o("或其他优秀示例 比如"),A={href:"https://github.com/chika0801/Xray-examples",target:"_blank",rel:"noopener noreferrer"},T=o("@chika0801"),E=o(" 又如"),X={href:"https://github.com/lxhao61/integrated-examples",target:"_blank",rel:"noopener noreferrer"},S=o("@lxhao61"),P=o("。"),j=l('

    注意

    若使用其他配置,你需要着重注意客户端配置中 outboundtagproxy 的部分,其他部分不变

    服务端配置也要同时改变

    此配置意在解决例如 Netflix 等默认使用 ipv6 连接的网站无法通过旁路由进行代理的问题,或对 ipv6 代理有需要。

    本文网络结构为单臂旁路由

    本文中所有配置已在 Arch Linux (Kernel: 6.0.10) 环境下测试成功,如在其它环境中同理

    注意安装相应程序 # sudo apt install iptables ip6tables# sudo apt install nftables

    ',5),N=o("若旁路由未安装 xray 程序,可以手动下载相应 xray 程序如 "),w={href:"https://github.com/XTLS/Xray-core/releases/download/v1.7.0/Xray-linux-64.zip",target:"_blank",rel:"noopener noreferrer"},I=o("Xray-linux-64.zip"),Y=o(" ,然后复制 "),_={href:"https://github.com/XTLS/Xray-install/blob/main/install-release.sh",target:"_blank",rel:"noopener noreferrer"},U=o("install-release.sh"),M=o(" 文件到旁路由,赋予可执行权限 "),K=p("code",null,"# chmod 700 install-release.sh",-1),V=o(",然后使用 "),D=p("code",null,"# ./install-release.sh --local Xray-linux-64.zip",-1),O=o(" 根据提示进行本地安装。"),B=l('

    Xray 配置

    客户端配置

    {\n  "log": {\n    "loglevel": "warning"\n  },\n  "inbounds": [\n    {\n      "tag": "all-in",\n      "port": 12345,\n      "protocol": "dokodemo-door",\n      "settings": {\n        "network": "tcp,udp",\n        "followRedirect": true\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls", "quic"]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "tproxy": "tproxy"\n        }\n      }\n    },\n    {\n      "port": 10808,\n      "protocol": "socks",\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls", "quic"]\n      },\n      "settings": {\n        "auth": "noauth",\n        "udp": true\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      //此为默认outbound,路由(routing)模块若未匹配到任何规则,则默认走此 proxy 出口,如果你希望直连国内优先请将下面 direct 出口放到 outbound 第一,看不懂可忽略\n      "tag": "proxy",\n      "protocol": "vless",\n      "settings": {\n        "vnext": [\n          {\n            "address": "yourdomain.domain", //改为你自己的域名,直接填写ipv4或ipv6地址也可以\n            "port": 443,\n            "users": [\n              {\n                "id": "uuid", //填写uuid,可通过在终端中输入 xray uuid 生成;此处也支持任意字符串(https://xtls.github.io/config/inbounds/vless.html#clientobject)\n                "encryption": "none",\n                "flow": "xtls-rprx-vision"\n              }\n            ]\n          }\n        ]\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        },\n        "network": "tcp",\n        "security": "tls", //注意使用 xtls-rprx-vision 流控此处需为 tls\n        "tlsSettings": {\n          //注意使用 xtls-rprx-vision 流控此处需为 tlsSettings\n          "allowInsecure": false,\n          "serverName": "yourdomain.domain", //改为你自己的域名\n          "fingerprint": "chrome" //此设置建议先看下Release, https://github.com/XTLS/Xray-core/releases/tag/v1.7.3\n        }\n      }\n    },\n    {\n      "tag": "direct",\n      "protocol": "freedom",\n      "settings": {\n        "domainStrategy": "UseIP"\n      },\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        }\n      }\n    },\n    {\n      "tag": "block",\n      "protocol": "blackhole",\n      "settings": {\n        "response": {\n          "type": "http"\n        }\n      }\n    },\n    {\n      "tag": "dns-out",\n      "protocol": "dns",\n      "streamSettings": {\n        "sockopt": {\n          "mark": 255\n        }\n      }\n    }\n  ],\n  "dns": {\n    "hosts": {\n      "domain:googleapis.cn": "googleapis.com",\n      "dns.google": "8.8.8.8",\n      "你的VPS域名": "你的VSP IP" //如果 outbound 的 proxy 里 address 填的域名:希望代理走ipv4,这里 VPS IP 填VPS的ipv4, 希望代理走ipv6,这里VPS IP 填VPS的ipv6;outbound 的 proxy 里 address 填的 IP,这行不用写。\n    },\n    "servers": [\n      "https://1.1.1.1/dns-query",\n      {\n        "address": "119.29.29.29",\n        "domains": ["geosite:cn"],\n        "expectIPs": ["geoip:cn"]\n      },\n      "https://dns.google/dns-query",\n      "223.5.5.5",\n      "localhost"\n    ]\n  },\n  "routing": {\n    "domainMatcher": "mph",\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        "type": "field",\n        "domain": ["geosite:category-ads-all"],\n        "outboundTag": "block"\n      },\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 123,\n        "network": "udp",\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "inboundTag": ["all-in"],\n        "port": 53,\n        "network": "udp",\n        "outboundTag": "dns-out"\n      },\n      {\n        "type": "field",\n        "ip": ["119.29.29.29", "223.5.5.5"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "protocol": ["bittorrent"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "ip": ["geoip:private", "geoip:cn"], //此处可加入 VPS IP 避免 ssh 时被代理\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "domain": ["geosite:cn"],\n        "outboundTag": "direct"\n      },\n      {\n        "type": "field",\n        "ip": ["1.1.1.1", "8.8.8.8"],\n        "outboundTag": "proxy"\n      },\n      {\n        "type": "field",\n        "domain": [\n          "geosite:geolocation-!cn",\n          "domain:googleapis.cn",\n          "dns.google"\n        ],\n        "outboundTag": "proxy"\n      }\n    ]\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179

    服务端配置

    {\n  "log": {\n    "loglevel": "warning"\n  },\n  "routing": {\n    "domainStrategy": "IPIfNonMatch",\n    "rules": [\n      {\n        //阻止 cnip 提高安全性,或者可以将 cn 流量导入 warp 中,详见https://xtls.github.io/document/level-2/warp.html\n        "type": "field",\n        "ip": ["geoip:cn"],\n        "outboundTag": "block"\n      }\n    ]\n  },\n  "inbounds": [\n    {\n      "port": 443,\n      "protocol": "vless",\n      "settings": {\n        "clients": [\n          {\n            "id": "uuid", //与客户端相同\n            "flow": "xtls-rprx-vision"\n          }\n        ],\n        "decryption": "none",\n        "fallbacks": [\n          {\n            "dest": 8080 //回落,需要 web 配合,参见白话文,不设置也行\n          }\n        ]\n      },\n      "streamSettings": {\n        "network": "tcp",\n        "security": "tls",\n        "tlsSettings": {\n          "certificates": [\n            {\n              "certificateFile": "/etc/ssl/private/fullchain.crt",\n              "keyFile": "/etc/ssl/private/crt.key" //参照小小白话文将生成的 fullchain.crt 以及 cert.key证书的路径相应填于此处(https://xtls.github.io/document/level-0/ch06-certificates.html#_6-4-%E6%AD%A3%E5%BC%8F%E8%AF%81%E4%B9%A6%E7%94%B3%E8%AF%B7)\n            }\n          ]\n        }\n      },\n      "sniffing": {\n        "enabled": true,\n        "destOverride": ["http", "tls"]\n      }\n    }\n  ],\n  "outbounds": [\n    {\n      "protocol": "freedom",\n      "tag": "direct"\n    },\n    {\n      "protocol": "blackhole",\n      "tag": "block"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62

    Netfilter 配置

    首先设置策略路由

    # 设置策略路由 v4\nip rule add fwmark 1 table 100\nip route add local 0.0.0.0/0 dev lo table 100\n\n# 设置策略路由 v6\nip -6 rule add fwmark 1 table 106\nip -6 route add local ::/0 dev lo table 106\n\n# 直连从主路由发出\nip route add default via 192.168.31.1 #写主路由 ipv4, 采用局域网设备上网设置方法一可不写此命令\nip -6 route add default via fd00:6868:6868::1 #写主路由 ipv6, 采用局域网设备上网设置方法一可不写此命令\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    使用方法

    直接将命令复制到旁路由终端执行

    关于直连从主路由发出

    在旁路由使用命令ip route show,如果使用下属方法一,则default via后应是主路由 ip,无需更改;如使用下述方法二,则default via后应是旁路由 ip,此时直连网站 DNS 解析会回环,造成直连网站无法访问,因此需指定为主路由 ip。

    如果是在路由器上指定了默认网关为旁路由(亦即下述“局域网设备上网设置方法二”),那么就需要设置上述 # 直连从主路由发出 ,除了通过 iproute2 命令行方式设置,也可以通过 dhcpcd 或者 systemctl-network 设置静态 IP,这里以 dhcpcd 为例,编辑 /etc/dhcpcd.conf 文件,在最下方加入如下配置,具体 IP 根据你的实际情况修改,其中 interface 可以通过 # ip link show 查看要设定的网口或者无线设备。

    interface enp0s25\nstatic ip_address=192.168.31.100/24\nstatic ip6_address=fd00:6868:6868::8888/64\nstatic routers=192.168.31.1\nstatic domain_name_servers=192.168.31.1 fd00:6868:6868::1\n
    1
    2
    3
    4
    5

    这样通过静态 IP 设置 IP 及网关后就无需每次开机设置 # 直连从主路由发出

    注意

    以下 nftables 配置与 iptables 配置二选一,不可同时使用。

    使用 iptables

    此处配置将 ipv4 与 ipv6 写在同一文件中。

    # 代理局域网设备 v4\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d 127.0.0.1/32 -j RETURN\niptables -t mangle -A XRAY -d 224.0.0.0/4 -j RETURN\niptables -t mangle -A XRAY -d 255.255.255.255/32 -j RETURN\niptables -t mangle -A XRAY -d 192.168.0.0/16 -p tcp -j RETURN\niptables -t mangle -A XRAY -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN\niptables -t mangle -A XRAY -j RETURN -m mark --mark 0xff\niptables -t mangle -A XRAY -p udp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-ip 127.0.0.1 --on-port 12345 --tproxy-mark 1\niptables -t mangle -A PREROUTING -j XRAY\n\n# 代理局域网设备 v6\nip6tables -t mangle -N XRAY6\nip6tables -t mangle -A XRAY6 -d ::1/128 -j RETURN\nip6tables -t mangle -A XRAY6 -d fe80::/10 -j RETURN\nip6tables -t mangle -A XRAY6 -d fd00::/8 -p tcp -j RETURN\nip6tables -t mangle -A XRAY6 -d fd00::/8 -p udp ! --dport 53 -j RETURN\nip6tables -t mangle -A XRAY6 -j RETURN -m mark --mark 0xff\nip6tables -t mangle -A XRAY6 -p udp -j TPROXY --on-ip ::1 --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A XRAY6 -p tcp -j TPROXY --on-ip ::1 --on-port 12345 --tproxy-mark 1\nip6tables -t mangle -A PREROUTING -j XRAY6\n\n# 代理网关本机 v4\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -d 224.0.0.0/4 -j RETURN\niptables -t mangle -A XRAY_MASK -d 255.255.255.255/32 -j RETURN\niptables -t mangle -A XRAY_MASK -d 192.168.0.0/16 -p tcp -j RETURN\niptables -t mangle -A XRAY_MASK -d 192.168.0.0/16 -p udp ! --dport 53 -j RETURN\niptables -t mangle -A XRAY_MASK -j RETURN -m mark --mark 0xff\niptables -t mangle -A XRAY_MASK -p udp -j MARK --set-mark 1\niptables -t mangle -A XRAY_MASK -p tcp -j MARK --set-mark 1\niptables -t mangle -A OUTPUT -j XRAY_MASK\n\n# 代理网关本机 v6\nip6tables -t mangle -N XRAY6_MASK\nip6tables -t mangle -A XRAY6_MASK -d fe80::/10 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d fd00::/8 -p tcp -j RETURN\nip6tables -t mangle -A XRAY6_MASK -d fd00::/8 -p udp ! --dport 53 -j RETURN\nip6tables -t mangle -A XRAY6_MASK -j RETURN -m mark --mark 0xff\nip6tables -t mangle -A XRAY6_MASK -p udp -j MARK --set-mark 1\nip6tables -t mangle -A XRAY6_MASK -p tcp -j MARK --set-mark 1\nip6tables -t mangle -A OUTPUT -j XRAY6_MASK\n\n# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v4\niptables -t mangle -N DIVERT\niptables -t mangle -A DIVERT -j MARK --set-mark 1\niptables -t mangle -A DIVERT -j ACCEPT\niptables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT\n\n# 新建 DIVERT 规则,避免已有连接的包二次通过 TPROXY,理论上有一定的性能提升 v6\nip6tables -t mangle -N DIVERT\nip6tables -t mangle -A DIVERT -j MARK --set-mark 1\nip6tables -t mangle -A DIVERT -j ACCEPT\nip6tables -t mangle -I PREROUTING -p tcp -m socket -j DIVERT\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56

    使用方法

    将上述配置写入一个文件(如 iptables.rules),之后将该文件赋予可执行权限# chmod 700 ./iptables.rules

    最后使用 root 权限执行该文件即可:# ./iptables.rules# source iptables.rules

    使用 nftables

    此处合并 ipv4 与 ipv6

    #!/usr/sbin/nft -f\n\nflush ruleset\n\ntable inet xray {\n        chain prerouting {\n                type filter hook prerouting priority filter; policy accept;\n                ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return\n                meta l4proto tcp ip daddr 192.168.0.0/16 return\n                ip daddr 192.168.0.0/16 udp dport != 53 return\n                ip6 daddr { ::1, fe80::/10 } return\n                meta l4proto tcp ip6 daddr fd00::/8 return\n                ip6 daddr fd00::/8 udp dport != 53 return\n                meta mark 0x000000ff return\n                meta l4proto { tcp, udp } meta mark set 0x00000001 tproxy ip to 127.0.0.1:12345 accept\n                meta l4proto { tcp, udp } meta mark set 0x00000001 tproxy ip6 to [::1]:12345 accept\n        }\n\n        chain output {\n                type route hook output priority filter; policy accept;\n                ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return\n                meta l4proto tcp ip daddr 192.168.0.0/16 return\n                ip daddr 192.168.0.0/16 udp dport != 53 return\n                ip6 daddr { ::1, fe80::/10 } return\n                meta l4proto tcp ip6 daddr fd00::/8 return\n                ip6 daddr fd00::/8 udp dport != 53 return\n                meta mark 0x000000ff return\n                meta l4proto { tcp, udp } meta mark set 0x00000001 accept\n        }\n\n        chain divert {\n                type filter hook prerouting priority mangle; policy accept;\n                meta l4proto tcp socket transparent 1 meta mark set 0x00000001 accept\n        }\n}\n\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    使用方法

    将上述配置写入一个文件(如 nftables.rules),之后将该文件赋予可执行权限# chmod 700 ./nftables.rules

    最后使用 root 权限执行该文件即可:# ./nftables.rules# source nftables.rules

    ',22),F=o("其中,网关地址"),C=p("code",null,"192.168.0.0/16",-1),L=o(", "),G=p("code",null,"fd00::/8",-1),W=o("等可由"),z=p("code",null,"ip address | grep -w inet | awk '{print $2}'",-1),$=o("以及"),H=p("code",null,"ip address | grep -w inet6 | awk '{print $2}'",-1),J={href:"https://xtls.github.io/document/level-2/iptables_gid.html#_4-%E8%AE%BE%E7%BD%AE-iptables-%E8%A7%84%E5%88%99",target:"_blank",rel:"noopener noreferrer"},Q=o("获得"),Z=l('

    或者在 windows 网络设置中查看。

    又或者在路由器“上网设置”中查看。

    如果前缀192.168, fd00:相同可不更改,若不同如 fc00:, fe00: 等则更改为相应值,写法可通过 Goolge 搜索得到如 fc00::/7, fe00::/9

    开机自动运行 Netfilter 配置

    首先确认已经运行过上述相应 Netfilter 命令,并且成功测试透明代理配置,以确保接下来输出正确的文件。

    若使用 iptables 配置

    1. 首先通过 # iptables-save > /root/iptables.rulesv4 # ip6tables-save > /root/iptables.rulesv6 将 iptables 配置写入 iptables.rulesv4iptables.rulesv6 文件中

    2. 然后在 /etc/systemd/system/ 目录下创建一个名为 tproxyrules.service 的文件,添加以下内容并保存

    [Unit]\nDescription=Tproxy rules\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStartPre=/bin/sh -c 'until ping -c1 192.168.31.1; do sleep 1; done;'\nExecStart=/sbin/ip rule add fwmark 1 table 100 ; \\\n/sbin/ip -6 rule add fwmark 1 table 106 ; \\\n/sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route add local ::/0 dev lo table 106 ; \\\n/sbin/ip route add default via 192.168.31.1 ; \\\n/sbin/ip -6 route add default via fd00:6868:6868::1 ; \\\n/sbin/iptables-restore /root/iptables.rulesv4 ; \\\n/sbin/ip6tables-restore /root/iptables.rulesv6\nExecStop=/sbin/ip rule del fwmark 1 table 100 ; \\\n/sbin/ip -6 rule del fwmark 1 table 106 ; \\\n/sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route del local ::/0 dev lo table 106 ; \\\n/sbin/ip route del default via 192.168.31.1 ; \\\n/sbin/ip -6 route del default via fd00:6868:6868::1 ; \\\n/sbin/iptables -t mangle -F ; \\\n/sbin/ip6tables -t mangle -F\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    1. 最后执行 systemctl enable tproxyrules 命令。

    如果使用 nftables 配置

    1. 首先通过 # nft list ruleset > /root/nftables.rulesv46 将 nftables 配置写入 nftables.rulesv46 文件中

    2. /etc/systemd/system/ 目录下创建一个名为 tproxyrules.service 的文件,然后添加以下内容并保存

    [Unit]\nDescription=Tproxy rules\n\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStartPre=/bin/sh -c 'until ping -c1 192.168.31.1; do sleep 1; done;'\nExecStart=/sbin/ip rule add fwmark 1 table 100 ; \\\n/sbin/ip -6 rule add fwmark 1 table 106 ; \\\n/sbin/ip route add local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route add local ::/0 dev lo table 106 ; \\\n/sbin/ip route add default via 192.168.31.1 ; \\\n/sbin/ip -6 route add default via fd00:6868:6868::1 ; \\\n/sbin/nft -f /root/nftables.rulesv46 ;\nExecStop=/sbin/ip rule del fwmark 1 table 100 ; \\\n/sbin/ip -6 rule del fwmark 1 table 106 ; \\\n/sbin/ip route del local 0.0.0.0/0 dev lo table 100 ; \\\n/sbin/ip -6 route del local ::/0 dev lo table 106 ; \\\n/sbin/ip route del default via 192.168.31.1 ; \\\n/sbin/ip -6 route del default via fd00:6868:6868::1 ; \\\n/sbin/nft flush ruleset\n\n[Install]\nWantedBy=multi-user.target\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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 的设置。

    ',33);r.render=function(o,l){const r=n("OutboundLink");return s(),a(e,null,[c,p("p",null,[u,p("a",i,[b,t(r)]),k,p("a",m,[d,t(r)]),q,p("a",g,[y,t(r)]),h]),p("p",null,[f,p("a",v,[x,t(r)]),R,p("a",A,[T,t(r)]),E,p("a",X,[S,t(r)]),P]),j,p("p",null,[N,p("a",w,[I,t(r)]),Y,p("a",_,[U,t(r)]),M,K,V,D,O]),B,p("p",null,[F,C,L,G,W,z,$,H,p("a",J,[Q,t(r)])]),Z],64)};export default r; diff --git a/assets/traffic_stats.html.84106893.js b/assets/traffic_stats.html.28cb5cac.js similarity index 99% rename from assets/traffic_stats.html.84106893.js rename to assets/traffic_stats.html.28cb5cac.js index 4586e83a7..f43d1a7b7 100644 --- a/assets/traffic_stats.html.84106893.js +++ b/assets/traffic_stats.html.28cb5cac.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as t,F as e,e as o,d as l}from"./app.755d843f.js";const r={},c=p("h1",{id:"流量统计配置教程",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#流量统计配置教程","aria-hidden":"true"},"#"),o(" 流量统计配置教程")],-1),u=o("请熟悉"),i={href:"https://guide.v2fly.org/advanced/traffic.html",target:"_blank",rel:"noopener noreferrer"},b=o("流量统计 白话文教程"),k=o(",本文在其基础上适配了 Xray(1.5.9+)。"),m=l('

    查看流量信息

    配置方法与 v2fly 一致。 查看流量信息是 xray 命令行的其中一个功能。配置内设置的 api dokodemo-door 端口,即为 --server 参数的端口。

    xray api statsquery --server=127.0.0.1:10085 #查看所有流量\nxray help api statsquery #statsquery 查询匹配的记录\nxray help api stats #stats 查询一个记录\n
    1
    2
    3

    输出例子:

    {\n  "stat": [\n    {\n      "name": "inbound>>>vmess-quic>>>traffic>>>downlink",\n      "value": "1176"\n    },\n    {\n      "name": "user>>>love@example.com>>>traffic>>>downlink",\n      "value": "2040"\n    },\n    {\n      "name": "inbound>>>api>>>traffic>>>uplink",\n      "value": "14247"\n    },\n    {\n      "name": "user>>>love@example.com>>>traffic>>>uplink",\n      "value": "2520"\n    },\n    {\n      "name": "inbound>>>api>>>traffic>>>downlink",\n      "value": "87618"\n    },\n    {\n      "name": "outbound>>>direct>>>traffic>>>downlink",\n      "value": "0"\n    },\n    {\n      "name": "inbound>>>vmess-quic>>>traffic>>>uplink",\n      "value": "1691"\n    },\n    {\n      "name": "outbound>>>direct>>>traffic>>>uplink",\n      "value": "0"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    流量信息的处理

    把以下脚本保存到 traffic.sh,注意使用 chmod 755 traffic.sh 授予执行权限。注意调整修改 _APISERVER 一行的连接具体的端口参数。

    #!/bin/bash\n\n_APISERVER=127.0.0.1:10085\n_XRAY=/usr/local/bin/xray\n\napidata () {\n    local ARGS=\n    if [[ $1 == "reset" ]]; then\n      ARGS="-reset=true"\n    fi\n    $_XRAY api statsquery --server=$_APISERVER "${ARGS}" \\\n    | awk '{\n        if (match($1, /"name":/)) {\n            f=1; gsub(/^"|link"|,$/, "", $2);\n            split($2, p,  ">>>");\n            printf "%s:%s->%s\\t", p[1],p[2],p[4];\n        }\n        else if (match($1, /"value":/) && f){\n          f = 0;\n          gsub(/"/, "", $2);\n          printf "%.0f\\n", $2;\n        }\n        else if (match($0, /}/) && f) { f = 0; print 0; }\n    }'\n}\n\nprint_sum() {\n    local DATA="$1"\n    local PREFIX="$2"\n    local SORTED=$(echo "$DATA" | grep "^${PREFIX}" | sort -r)\n    local SUM=$(echo "$SORTED" | awk '\n        /->up/{us+=$2}\n        /->down/{ds+=$2}\n        END{\n            printf "SUM->up:\\t%.0f\\nSUM->down:\\t%.0f\\nSUM->TOTAL:\\t%.0f\\n", us, ds, us+ds;\n        }')\n    echo -e "${SORTED}\\n${SUM}" \\\n    | numfmt --field=2 --suffix=B --to=iec \\\n    | column -t\n}\n\nDATA=$(apidata $1)\necho "------------Inbound----------"\nprint_sum "$DATA" "inbound"\necho "-----------------------------"\necho "------------Outbound----------"\nprint_sum "$DATA" "outbound"\necho "-----------------------------"\necho\necho "-------------User------------"\nprint_sum "$DATA" "user"\necho "-----------------------------"\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    ',8);r.render=function(o,l){const r=n("OutboundLink");return s(),a(e,null,[c,p("p",null,[u,p("a",i,[b,t(r)]),k]),m],64)};export default r; +import{r as n,o as s,c as a,a as p,b as t,F as e,e as o,d as l}from"./app.48111a85.js";const r={},c=p("h1",{id:"流量统计配置教程",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#流量统计配置教程","aria-hidden":"true"},"#"),o(" 流量统计配置教程")],-1),u=o("请熟悉"),i={href:"https://guide.v2fly.org/advanced/traffic.html",target:"_blank",rel:"noopener noreferrer"},b=o("流量统计 白话文教程"),k=o(",本文在其基础上适配了 Xray(1.5.9+)。"),m=l('

    查看流量信息

    配置方法与 v2fly 一致。 查看流量信息是 xray 命令行的其中一个功能。配置内设置的 api dokodemo-door 端口,即为 --server 参数的端口。

    xray api statsquery --server=127.0.0.1:10085 #查看所有流量\nxray help api statsquery #statsquery 查询匹配的记录\nxray help api stats #stats 查询一个记录\n
    1
    2
    3

    输出例子:

    {\n  "stat": [\n    {\n      "name": "inbound>>>vmess-quic>>>traffic>>>downlink",\n      "value": "1176"\n    },\n    {\n      "name": "user>>>love@example.com>>>traffic>>>downlink",\n      "value": "2040"\n    },\n    {\n      "name": "inbound>>>api>>>traffic>>>uplink",\n      "value": "14247"\n    },\n    {\n      "name": "user>>>love@example.com>>>traffic>>>uplink",\n      "value": "2520"\n    },\n    {\n      "name": "inbound>>>api>>>traffic>>>downlink",\n      "value": "87618"\n    },\n    {\n      "name": "outbound>>>direct>>>traffic>>>downlink",\n      "value": "0"\n    },\n    {\n      "name": "inbound>>>vmess-quic>>>traffic>>>uplink",\n      "value": "1691"\n    },\n    {\n      "name": "outbound>>>direct>>>traffic>>>uplink",\n      "value": "0"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    流量信息的处理

    把以下脚本保存到 traffic.sh,注意使用 chmod 755 traffic.sh 授予执行权限。注意调整修改 _APISERVER 一行的连接具体的端口参数。

    #!/bin/bash\n\n_APISERVER=127.0.0.1:10085\n_XRAY=/usr/local/bin/xray\n\napidata () {\n    local ARGS=\n    if [[ $1 == "reset" ]]; then\n      ARGS="-reset=true"\n    fi\n    $_XRAY api statsquery --server=$_APISERVER "${ARGS}" \\\n    | awk '{\n        if (match($1, /"name":/)) {\n            f=1; gsub(/^"|link"|,$/, "", $2);\n            split($2, p,  ">>>");\n            printf "%s:%s->%s\\t", p[1],p[2],p[4];\n        }\n        else if (match($1, /"value":/) && f){\n          f = 0;\n          gsub(/"/, "", $2);\n          printf "%.0f\\n", $2;\n        }\n        else if (match($0, /}/) && f) { f = 0; print 0; }\n    }'\n}\n\nprint_sum() {\n    local DATA="$1"\n    local PREFIX="$2"\n    local SORTED=$(echo "$DATA" | grep "^${PREFIX}" | sort -r)\n    local SUM=$(echo "$SORTED" | awk '\n        /->up/{us+=$2}\n        /->down/{ds+=$2}\n        END{\n            printf "SUM->up:\\t%.0f\\nSUM->down:\\t%.0f\\nSUM->TOTAL:\\t%.0f\\n", us, ds, us+ds;\n        }')\n    echo -e "${SORTED}\\n${SUM}" \\\n    | numfmt --field=2 --suffix=B --to=iec \\\n    | column -t\n}\n\nDATA=$(apidata $1)\necho "------------Inbound----------"\nprint_sum "$DATA" "inbound"\necho "-----------------------------"\necho "------------Outbound----------"\nprint_sum "$DATA" "outbound"\necho "-----------------------------"\necho\necho "-------------User------------"\nprint_sum "$DATA" "user"\necho "-----------------------------"\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    ',8);r.render=function(o,l){const r=n("OutboundLink");return s(),a(e,null,[c,p("p",null,[u,p("a",i,[b,t(r)]),k]),m],64)};export default r; diff --git a/assets/traffic_stats.html.500a1693.js b/assets/traffic_stats.html.ff0f8489.js similarity index 99% rename from assets/traffic_stats.html.500a1693.js rename to assets/traffic_stats.html.ff0f8489.js index 4586e83a7..f43d1a7b7 100644 --- a/assets/traffic_stats.html.500a1693.js +++ b/assets/traffic_stats.html.ff0f8489.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as t,F as e,e as o,d as l}from"./app.755d843f.js";const r={},c=p("h1",{id:"流量统计配置教程",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#流量统计配置教程","aria-hidden":"true"},"#"),o(" 流量统计配置教程")],-1),u=o("请熟悉"),i={href:"https://guide.v2fly.org/advanced/traffic.html",target:"_blank",rel:"noopener noreferrer"},b=o("流量统计 白话文教程"),k=o(",本文在其基础上适配了 Xray(1.5.9+)。"),m=l('

    查看流量信息

    配置方法与 v2fly 一致。 查看流量信息是 xray 命令行的其中一个功能。配置内设置的 api dokodemo-door 端口,即为 --server 参数的端口。

    xray api statsquery --server=127.0.0.1:10085 #查看所有流量\nxray help api statsquery #statsquery 查询匹配的记录\nxray help api stats #stats 查询一个记录\n
    1
    2
    3

    输出例子:

    {\n  "stat": [\n    {\n      "name": "inbound>>>vmess-quic>>>traffic>>>downlink",\n      "value": "1176"\n    },\n    {\n      "name": "user>>>love@example.com>>>traffic>>>downlink",\n      "value": "2040"\n    },\n    {\n      "name": "inbound>>>api>>>traffic>>>uplink",\n      "value": "14247"\n    },\n    {\n      "name": "user>>>love@example.com>>>traffic>>>uplink",\n      "value": "2520"\n    },\n    {\n      "name": "inbound>>>api>>>traffic>>>downlink",\n      "value": "87618"\n    },\n    {\n      "name": "outbound>>>direct>>>traffic>>>downlink",\n      "value": "0"\n    },\n    {\n      "name": "inbound>>>vmess-quic>>>traffic>>>uplink",\n      "value": "1691"\n    },\n    {\n      "name": "outbound>>>direct>>>traffic>>>uplink",\n      "value": "0"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    流量信息的处理

    把以下脚本保存到 traffic.sh,注意使用 chmod 755 traffic.sh 授予执行权限。注意调整修改 _APISERVER 一行的连接具体的端口参数。

    #!/bin/bash\n\n_APISERVER=127.0.0.1:10085\n_XRAY=/usr/local/bin/xray\n\napidata () {\n    local ARGS=\n    if [[ $1 == "reset" ]]; then\n      ARGS="-reset=true"\n    fi\n    $_XRAY api statsquery --server=$_APISERVER "${ARGS}" \\\n    | awk '{\n        if (match($1, /"name":/)) {\n            f=1; gsub(/^"|link"|,$/, "", $2);\n            split($2, p,  ">>>");\n            printf "%s:%s->%s\\t", p[1],p[2],p[4];\n        }\n        else if (match($1, /"value":/) && f){\n          f = 0;\n          gsub(/"/, "", $2);\n          printf "%.0f\\n", $2;\n        }\n        else if (match($0, /}/) && f) { f = 0; print 0; }\n    }'\n}\n\nprint_sum() {\n    local DATA="$1"\n    local PREFIX="$2"\n    local SORTED=$(echo "$DATA" | grep "^${PREFIX}" | sort -r)\n    local SUM=$(echo "$SORTED" | awk '\n        /->up/{us+=$2}\n        /->down/{ds+=$2}\n        END{\n            printf "SUM->up:\\t%.0f\\nSUM->down:\\t%.0f\\nSUM->TOTAL:\\t%.0f\\n", us, ds, us+ds;\n        }')\n    echo -e "${SORTED}\\n${SUM}" \\\n    | numfmt --field=2 --suffix=B --to=iec \\\n    | column -t\n}\n\nDATA=$(apidata $1)\necho "------------Inbound----------"\nprint_sum "$DATA" "inbound"\necho "-----------------------------"\necho "------------Outbound----------"\nprint_sum "$DATA" "outbound"\necho "-----------------------------"\necho\necho "-------------User------------"\nprint_sum "$DATA" "user"\necho "-----------------------------"\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    ',8);r.render=function(o,l){const r=n("OutboundLink");return s(),a(e,null,[c,p("p",null,[u,p("a",i,[b,t(r)]),k]),m],64)};export default r; +import{r as n,o as s,c as a,a as p,b as t,F as e,e as o,d as l}from"./app.48111a85.js";const r={},c=p("h1",{id:"流量统计配置教程",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#流量统计配置教程","aria-hidden":"true"},"#"),o(" 流量统计配置教程")],-1),u=o("请熟悉"),i={href:"https://guide.v2fly.org/advanced/traffic.html",target:"_blank",rel:"noopener noreferrer"},b=o("流量统计 白话文教程"),k=o(",本文在其基础上适配了 Xray(1.5.9+)。"),m=l('

    查看流量信息

    配置方法与 v2fly 一致。 查看流量信息是 xray 命令行的其中一个功能。配置内设置的 api dokodemo-door 端口,即为 --server 参数的端口。

    xray api statsquery --server=127.0.0.1:10085 #查看所有流量\nxray help api statsquery #statsquery 查询匹配的记录\nxray help api stats #stats 查询一个记录\n
    1
    2
    3

    输出例子:

    {\n  "stat": [\n    {\n      "name": "inbound>>>vmess-quic>>>traffic>>>downlink",\n      "value": "1176"\n    },\n    {\n      "name": "user>>>love@example.com>>>traffic>>>downlink",\n      "value": "2040"\n    },\n    {\n      "name": "inbound>>>api>>>traffic>>>uplink",\n      "value": "14247"\n    },\n    {\n      "name": "user>>>love@example.com>>>traffic>>>uplink",\n      "value": "2520"\n    },\n    {\n      "name": "inbound>>>api>>>traffic>>>downlink",\n      "value": "87618"\n    },\n    {\n      "name": "outbound>>>direct>>>traffic>>>downlink",\n      "value": "0"\n    },\n    {\n      "name": "inbound>>>vmess-quic>>>traffic>>>uplink",\n      "value": "1691"\n    },\n    {\n      "name": "outbound>>>direct>>>traffic>>>uplink",\n      "value": "0"\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    流量信息的处理

    把以下脚本保存到 traffic.sh,注意使用 chmod 755 traffic.sh 授予执行权限。注意调整修改 _APISERVER 一行的连接具体的端口参数。

    #!/bin/bash\n\n_APISERVER=127.0.0.1:10085\n_XRAY=/usr/local/bin/xray\n\napidata () {\n    local ARGS=\n    if [[ $1 == "reset" ]]; then\n      ARGS="-reset=true"\n    fi\n    $_XRAY api statsquery --server=$_APISERVER "${ARGS}" \\\n    | awk '{\n        if (match($1, /"name":/)) {\n            f=1; gsub(/^"|link"|,$/, "", $2);\n            split($2, p,  ">>>");\n            printf "%s:%s->%s\\t", p[1],p[2],p[4];\n        }\n        else if (match($1, /"value":/) && f){\n          f = 0;\n          gsub(/"/, "", $2);\n          printf "%.0f\\n", $2;\n        }\n        else if (match($0, /}/) && f) { f = 0; print 0; }\n    }'\n}\n\nprint_sum() {\n    local DATA="$1"\n    local PREFIX="$2"\n    local SORTED=$(echo "$DATA" | grep "^${PREFIX}" | sort -r)\n    local SUM=$(echo "$SORTED" | awk '\n        /->up/{us+=$2}\n        /->down/{ds+=$2}\n        END{\n            printf "SUM->up:\\t%.0f\\nSUM->down:\\t%.0f\\nSUM->TOTAL:\\t%.0f\\n", us, ds, us+ds;\n        }')\n    echo -e "${SORTED}\\n${SUM}" \\\n    | numfmt --field=2 --suffix=B --to=iec \\\n    | column -t\n}\n\nDATA=$(apidata $1)\necho "------------Inbound----------"\nprint_sum "$DATA" "inbound"\necho "-----------------------------"\necho "------------Outbound----------"\nprint_sum "$DATA" "outbound"\necho "-----------------------------"\necho\necho "-------------User------------"\nprint_sum "$DATA" "user"\necho "-----------------------------"\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    ',8);r.render=function(o,l){const r=n("OutboundLink");return s(),a(e,null,[c,p("p",null,[u,p("a",i,[b,t(r)]),k]),m],64)};export default r; diff --git a/assets/transparent_proxy.html.ecc1188f.js b/assets/transparent_proxy.html.46362529.js similarity index 99% rename from assets/transparent_proxy.html.ecc1188f.js rename to assets/transparent_proxy.html.46362529.js index edb2eb304..9fe255d65 100644 --- a/assets/transparent_proxy.html.ecc1188f.js +++ b/assets/transparent_proxy.html.46362529.js @@ -1 +1 @@ -import{r as n,o as s,c as l,a,b as e,w as t,F as r,e as p,d as o}from"./app.755d843f.js";const u={},c=a("h1",{id:"透明代理入门",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理入门","aria-hidden":"true"},"#"),p(" 透明代理入门")],-1),i=a("h2",{id:"什么是透明代理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#什么是透明代理","aria-hidden":"true"},"#"),p(" 什么是透明代理")],-1),b=a("p",null,"透明代理简单地说就是不让被代理的设备感觉到自己被代理了。简单地说就是,被代理的设备上不需要运行任何代理软件(比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。",-1),d=a("p",null,"这也意味着,代理的软件运行在别的地方,比如运行在路由器中,通过路由器上网的设备就自动被代理了。",-1),m=a("h2",{id:"透明代理的实现",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理的实现","aria-hidden":"true"},"#"),p(" 透明代理的实现")],-1),k=a("p",null,"透明代理的实现目前主要有两种方式:",-1),h=a("h3",{id:"tun2socks",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#tun2socks","aria-hidden":"true"},"#"),p(" tun2socks")],-1),g=a("p",null,"可用 Windows/Linux(包括安卓)实现。因为实现过程比较简单,很少有教程,我这里简单描述一下。",-1),R=a("p",null,[a("strong",null,"Windows")],-1),A=p("安装 "),f={href:"https://github.com/NetchX/Netch/releases",target:"_blank",rel:"noopener noreferrer"},P=p("Netch"),T=p(" ,使用模式"),N=a("code",null,"[3] [TUN/TAP] 绕过局域网",-1),y=p("启动。"),X=o("
  • 开启热点

  • 打开控制面板->网络和 Internet->网络和共享中心->更改适配器设置,找到TAP-Windows AdapterMicrosoft Wi-Fi Direct Virtual Adapter

  • 鼠标右键点击TAP-Windows Adapter属性->共享,勾选允许其他网络用户通过此计算机的 Internet 连接来连接,在家庭网络连接中选择Microsoft Wi-Fi Direct Virtual Adapter的那个网络连接,点击确定。

  • ",3),E=a("p",null,[a("strong",null,"Android")],-1),x=a("ol",null,[a("li",null,[a("p",null,"配置连接 V2RayNG")]),a("li",null,[a("p",null,"开启热点")]),a("li",null,[a("p",null,"热点设置 -> 允许热点使用 VPN(部分安卓系统可能没有这个选项)")])],-1),U=a("h3",{id:"iptables-nftables",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-nftables","aria-hidden":"true"},"#"),p(" iptables/nftables")],-1),O=a("p",null,"iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。",-1),Y=a("p",null,"基于 iptables 的透明代理实现只能用于 Linux 系统(包括 openwrt/安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而广泛使用。",-1),I=p("现存的三篇白话文透明代理教程其实讲的都是基于这种方案的透明代理实现,它们是: "),j={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},_=p("新 V2Ray 白话文指南-透明代理"),v=p(" 、 "),S={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},G=p("新 V2Ray 白话文指南-透明代理(TPROXY)"),w=p(" 、 "),B=p("透明代理(TProxy)配置教程"),D=p(" 。其中第一篇是基于 iptables-redirect 模式,已经过时了,不建议使用,仅供参考。第二篇和第三篇讲的都是基于 iptables-tproxy 模式的透明代理实现。"),L=a("h2",{id:"iptables-实现透明代理原理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-实现透明代理原理","aria-hidden":"true"},"#"),p(" iptables 实现透明代理原理")],-1),W=a("p",null,[p("Linux 使用"),a("code",null,"Netfilter"),p("来管理网络,"),a("code",null,"Netfilter"),p("模型如下:")],-1),C=a("p",null,[a("img",{src:"/Xray-docs-next/assets/netfilter.ef038b15.png",alt:"Netfilter"})],-1),M=a("p",null,[a("strong",null,"假设使用路由器作为网关(即我们平时的上网方式),那么:")],-1),V=a("p",null,"局域网设备通过路由器访问互联网的流量方向:",-1),K=a("p",null,[a("code",null,"PREROUTING链->FORWARD链->POSTINGROUTING链")],-1),F=a("p",null,"局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:",-1),$=a("p",null,[a("code",null,"PREROUTING链->INPUT链->网关本机")],-1),q=a("p",null,"路由器访问互联网的流量方向:",-1),H=a("p",null,[a("code",null,"网关本机->OUTPUT链->POSTINGROUTING链")],-1),z=a("p",null,[a("strong",null,[p("通过使用 iptables 操控"),a("code",null,"PREROUTING链"),p("和"),a("code",null,"OUTPUT链"),p("的流量走向,转发到 Xray,就可以代理局域网设备和网关本机。")])],-1),J=a("h2",{id:"透明代理难在哪里",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理难在哪里","aria-hidden":"true"},"#"),p(" 透明代理难在哪里")],-1),Q=a("p",null,[p("透明代理的难点就在于路由,所谓路由,就是区分哪些流量是直连的,哪些该被代理,所以我个人认为叫做"),a("strong",null,"分流"),p("更加合适。")],-1),Z=a("p",null,"我们可以把路由由易到难分为以下几个阶段:",-1),nn=a("ol",null,[a("li",null,[a("p",null,"代理全部请求")]),a("li",null,[a("p",null,"本地局域网 IP/组播 IP 请求直连,其它请求代理")]),a("li",null,[a("p",null,"在 2 的基础上直连 Xray 发起的连接请求")]),a("li",null,[a("p",null,"在 3 的基础上直连指向中国大陆 IP 的连接请求,并对国内外域名选择国内外 DNS 服务器解析。")])],-1),sn=a("p",null,"上面说的三篇教程,都是在第四阶段。所以新手直接阅读可能显得有点难懂。",-1),ln=a("h2",{id:"从零开始一步步实现基于-iptables-tproxy-的透明代理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#从零开始一步步实现基于-iptables-tproxy-的透明代理","aria-hidden":"true"},"#"),p(" 从零开始一步步实现基于 iptables-tproxy 的透明代理")],-1),an=a("h3",{id:"在开始之前-你需要有一定的基础知识",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#在开始之前-你需要有一定的基础知识","aria-hidden":"true"},"#"),p(" 在开始之前,你需要有一定的基础知识:")],-1),en=a("ol",null,[a("li",null,[a("p",null,"大概知道什么是 TCP/IP 协议、域名和 DNS 服务器")]),a("li",null,[a("p",null,"知道什么是 WAN 口,LAN 口,LAN_IP,WAN_IP 以及 DHCP 服务器。对于旁路由,只有一个网口,这里称其为 LAN 口")]),a("li",null,[a("p",null,"对 Linux 系统有最基础的了解(知道怎么运行命令)")]),a("li",null,[a("p",null,"能够手写客户端 json 文件配置,至少要能看懂")])],-1),tn=a("h3",{id:"前期准备工作",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#前期准备工作","aria-hidden":"true"},"#"),p(" 前期准备工作")],-1),rn=a("p",null,[a("strong",null,"1. 准备一个运行 Linux 系统的网关")],-1),pn=a("p",null,"比如,刷了 OpenWRT 的路由器",-1),on=a("p",null,[a("strong",null,"2. 在网关(路由器)准备好 Xray 可执行文件以及配置文件")],-1),un=a("p",null,"配置文件监听 12345 端口,开启 tproxy:",-1),cn=a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"log"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"loglevel"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"warning"'),p("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"inbounds"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"["),p("\n "),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token number"},"12345"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"dokodemo-door"'),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"tcp,udp"'),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"followRedirect"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token boolean"},"true"),p("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"sockopt"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"tproxy"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"tproxy"'),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"outbounds"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"["),p("\n "),a("span",{class:"token punctuation"},"{"),p("\n 你的服务器配置\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"]"),p("\n"),a("span",{class:"token punctuation"},"}"),p("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br")])],-1),bn=a("p",null,"我们由易到难,不写 routing,只写一个 inbound 一个 outbound。",-1),dn=a("h3",{id:"首先-我们先试试做到第一阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#首先-我们先试试做到第一阶段","aria-hidden":"true"},"#"),p(" 首先,我们先试试做到第一阶段")],-1),mn=a("p",null,[p("将所有"),a("code",null,"PREROUTING链"),p("的流量,都转发到 Xray 中。")],-1),kn=a("p",null,"运行 Xray,执行以下指令:",-1),hn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br")])],-1),gn=a("p",null,"当你输入完之后,如果你是使用 ssh 连接到网关上的,你会发现 ssh 的连接断开了(不用紧张,断电重启即可恢复),并且透明代理无法上网;如果你是的网关是虚拟机,你会发现网关本身也无法上网,并且 Xray 日志 access_log 中出现许多源地址为目标地址,目标地址为 WAN_IP 的请求。",-1),Rn=a("p",null,[p("理论上网关本机访问公网只会经过"),a("code",null,"OUTPUT链"),p("和"),a("code",null,"POSTROUTING链"),p(",为什么操控"),a("code",null,"PREROUTING链"),p("会导致网关无法上网呢?这是因为网络通讯往往是双向的,虽然网关访问公网 IP 不需要经过"),a("code",null,"PREROUTING链"),p(",但被访问的服务器向网关返回信息时要经过"),a("code",null,"PREROUTING链"),p(",且这部分被转发到 Xray 了,因此出现了日志中的反向请求。")],-1),An=a("p",null,"我们修改一下规则,源 IP 不是来自局域网的则返回。重启网关,运行 Xray,执行以下指令:",-1),fn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\n"),a("span",{class:"token comment"},'# "网关LAN_IP地址段" 通过运行命令"ip address | grep -w "inet" | awk \'{print $2}\'"获得,是其中的一个'),p("\niptables -t mangle -A XRAY "),a("span",{class:"token operator"},"!"),p(" -s 网关LAN_IP地址段 -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br")])],-1),Pn=a("p",null,"然后你会发现,虽然 ssh 连接断开了,但是透明代理已经可用了。只要我们修改系统 dns 为公共 dns,就能正常上网了(因为现在网关访问不了,所以 dns 设置为网关是不行的)。",-1),Tn=a("p",null,"至此,第一阶段就完成了。之所以无法访问网关,是因为代理规则代理了全部流量,包括访问网关的流量。试想在 VPS 上访问你本地的网关,肯定是访问不了的,所以我们要对这部分流量直连,请看第二阶段:",-1),Nn=a("h3",{id:"第二阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第二阶段","aria-hidden":"true"},"#"),p(" 第二阶段")],-1),yn=a("p",null,"重启网关,运行 Xray,执行以下指令:",-1),Xn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\n\n"),a("span",{class:"token comment"},"# 所有目标地址在网关所在网段的请求直连"),p("\n"),a("span",{class:"token comment"},'# 通过运行命令"ip address | grep -w "inet" | awk \'{print $2}\'"获得,一般来说有多个'),p("\niptables -t mangle -A XRAY -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\n\n"),a("span",{class:"token comment"},"# 目标地址为组播IP/E类地址/广播IP的请求直连"),p("\niptables -t mangle -A XRAY -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\n\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br")])],-1),En=a("p",null,[p("使用这条规则后,上一条规则"),a("code",null,"iptables -t mangle -A XRAY ! -s 网关LAN_IP地址段 -j RETURN"),p("便成为了多余规则,可以删去。")],-1),xn=a("p",null,"至此,第二阶段完成。网关已经可以访问,ssh 不会断开。",-1),Un=a("h3",{id:"第三阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第三阶段","aria-hidden":"true"},"#"),p(" 第三阶段")],-1),On=a("p",null,"我们平时用的 DNS 一般来自路由器,但这个 iptables 规则只代理了局域网中的设备,却没有代理网关本机,这样返回的 DNS 查询结果可能是错误的或者污染的。",-1),Yn=a("p",null,[p("iptables-tproxy 不支持对"),a("code",null,"OUTPUT链"),p("操作,但是我们可以通过配置"),a("code",null,"策略路由"),p(",把"),a("code",null,"OUTPUT链"),p("中相应的包重新路由到"),a("code",null,"PREROUTING链"),p("上。")],-1),In=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token comment"},"# 添加策略路由: 标记为1的包,走路由表100"),p("\n"),a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token comment"},"# 添加路由条目到路由表100: 所有包路由到本地"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br")])],-1),jn=a("p",null,[p("通过配置上述"),a("code",null,"策略路由"),p(",我们只需要在"),a("code",null,"OUTPUT链"),p("中给包打标记为"),a("code",null,"1"),p(",相应的包就会路由到网关本机,即"),a("code",null,"PREROUTING链"),p("上。所以我们就给网关本机需要代理的请求在"),a("code",null,"OUTPUT链"),p("上标记"),a("code",null,"1"),p("即可。")],-1),_n=a("p",null,"如果要代理网关本机发出的的全部请求,就会引入一个问题,Xray 运行在网关,Xray 向代理服务端发送请求,这个请求又被代理了,就形成了回环。",-1),vn=a("p",null,"因此要代理网关本机,就要避免回环发生,即代理规则中规避 Xray 请求的流量。",-1),Sn=a("p",null,[a("strong",null,"常见的方法有三种:")],-1),Gn=a("ol",null,[a("li",null,"直连目标地址为 VPS 的流量")],-1),wn=a("p",null,"重启网关,运行 Xray,执行以下指令:",-1),Bn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token comment"},"#代理局域网设备"),p("\n"),a("span",{class:"token comment"},"#继承上一个阶段的成果"),p("\n"),a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\niptables -t mangle -A XRAY -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n\n"),a("span",{class:"token comment"},"#代理网关本机"),p("\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY_MASK -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\niptables -t mangle -A XRAY_MASK -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\niptables -t mangle -A XRAY_MASK -d VPS公网ip/32 -j RETURN\niptables -t mangle -A XRAY_MASK -j MARK --set-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK\niptables -t mangle -A OUTPUT -p udp -j XRAY_MASK\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br")])],-1),Dn=a("p",null,"但是这么配置有个缺点,如果使用 CDN 或者 VPS 很多的话,就不好写规则了。",-1),Ln=a("ol",{start:"2"},[a("li",null,"通过 mark 规避")],-1),Wn=a("p",null,"三个白话文教程都是使用这种方法规避,自行参考,这里不再赘述。",-1),Cn=a("ol",{start:"3"},[a("li",null,"通过 gid 规避(推荐)")],-1),Mn=p("参考 "),Vn=p("[透明代理]通过 gid 规避 Xray 流量"),Kn=a("p",null,"这样就完成了第三阶段的代理,也就是平时说的全局代理。但是记得把网关的 DNS 服务器设置为国外的 DNS 服务器,否则可能依然返回被污染的结果。",-1),Fn=a("h3",{id:"第四阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第四阶段","aria-hidden":"true"},"#"),p(" 第四阶段")],-1),$n=a("p",null,"其实,并不是所有人都需要实现第四阶段。全局代理对于大部分情况已经适用。",-1),qn=a("p",null,"特别是对于旁路由而言。需要代理时,将网关调成旁路由的 IP,不需要代理时,将网关换回主路由 IP。",-1),Hn=a("p",null,"至于第四阶段的具体实现,那三篇白话文教程讲的都是。在理解了上面的内容后,再去看那三篇白话文教程,就比较容易理解了。",-1),zn=a("h3",{id:"代理-ipv6",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#代理-ipv6","aria-hidden":"true"},"#"),p(" 代理 ipv6")],-1),Jn=p("上面的规则只对 ipv4 生效,如果还想要代理 ipv6 请求,则使用 ip6tables 命令,用法与 iptables 基本相同。参考 "),Qn=p("[透明代理]通过 gid 规避 Xray 流量#4-设置 iptables 规则"),Zn=a("h1",{id:"iptables-透明代理的其它注意事项",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-透明代理的其它注意事项","aria-hidden":"true"},"#"),p(" iptables 透明代理的其它注意事项")],-1),ns=a("li",null,[a("p",null,[p("如果作为代理的网关作为主路由,要在"),a("code",null,"PREROUTING链"),p("规则中加一条"),a("code",null,"iptables -t mangle -A XRAY ! -s 网关LAN_IP地址段 -j RETURN"),p(",即在第一阶段使用、第二阶段被删除的指令。如果不写,WAN 口中同网段的其它人可以将网关填写成你的 WAN_IP,从而蹭你的透明代理用,还可能带来一定的危险性。")])],-1),ss={href:"https://guide.v2fly.org/app/tproxy.html#%E8%AE%BE%E7%BD%AE%E7%BD%91%E5%85%B3",target:"_blank",rel:"noopener noreferrer"},ls=p("新 V2Ray 白话文指南-透明代理(TPROXY)#设置网关"),as=p(" 中的第三条说:"),es=a("code",null,"手动配置 PC 的网络,将默认网关指向树莓派的地址即 192.168.1.22。此时 PC 应当能正常上网(由于还没设置代理,“正常”是指可以上国内的网站)",-1),ts=p("。实际上,Ubuntu、CentOS、debian 等系统就算开启了 IP 转发,PC 也不能正常上网,这是正常的。事实上只有 OpenWRT 能做到文中所描述的那样,据 "),rs={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},ps=p("@BioniCosmos"),os=p(" 点拨,这是由于一般的 Linux 系统没有 Masquery 规则。"),us={href:"https://guide.v2fly.org/app/tproxy.html#%E8%A7%A3%E5%86%B3-too-many-open-files-%E9%97%AE%E9%A2%98",target:"_blank",rel:"noopener noreferrer"},cs=p("too many open files 问题"),is=p(" ,解决方法见 "),bs=a("strong",null,[a("a",{href:"../iptables_gid#3-%E9%85%8D%E7%BD%AE%E6%9C%80%E5%A4%A7%E6%96%87%E4%BB%B6%E5%A4%A7%E5%BC%80%E6%95%B0%E8%BF%90%E8%A1%8Cxray%E5%AE%A2%E6%88%B7%E7%AB%AF"},"[透明代理]通过 gid 规避 Xray 流量-配置最大文件大开数&运行 Xray 客户端")],-1),ds=a("li",null,[a("p",null,"关于开启 ip_forward,待补充...")],-1),ms=a("li",null,[a("p",null,"避免已有连接的包二次通过 TPROXY ,待补充...")],-1),ks=a("li",null,[a("p",null,"主路由、单臂路由与旁路由,待补充...")],-1);u.render=function(p,o){const u=n("OutboundLink"),hs=n("RouterLink");return s(),l(r,null,[c,i,b,d,m,k,h,g,R,a("ol",null,[a("li",null,[a("p",null,[A,a("strong",null,[a("a",f,[P,e(u)])]),T,N,y])]),X]),E,x,U,O,Y,a("p",null,[I,a("strong",null,[a("a",j,[_,e(u)])]),v,a("strong",null,[a("a",S,[G,e(u)])]),w,a("strong",null,[e(hs,{to:"/document/level-2/tproxy.html"},{default:t((()=>[B])),_:1})]),D]),L,W,C,M,V,K,F,$,q,H,z,J,Q,Z,nn,sn,ln,an,en,tn,rn,pn,on,un,cn,bn,dn,mn,kn,hn,gn,Rn,An,fn,Pn,Tn,Nn,yn,Xn,En,xn,Un,On,Yn,In,jn,_n,vn,Sn,Gn,wn,Bn,Dn,Ln,Wn,Cn,a("p",null,[Mn,a("strong",null,[e(hs,{to:"/document/level-2/iptables_gid.html"},{default:t((()=>[Vn])),_:1})])]),Kn,Fn,$n,qn,Hn,zn,a("p",null,[Jn,a("strong",null,[e(hs,{to:"/document/level-2/iptables_gid#4-%E8%AE%BE%E7%BD%AEiptables%E8%A7%84%E5%88%99.html"},{default:t((()=>[Qn])),_:1})])]),Zn,a("ol",null,[ns,a("li",null,[a("p",null,[a("strong",null,[a("a",ss,[ls,e(u)])]),as,es,ts,a("strong",null,[a("a",rs,[ps,e(u)])]),os])]),a("li",null,[a("p",null,[a("strong",null,[a("a",us,[cs,e(u)])]),is,bs])]),ds,ms,ks])],64)};export default u; +import{r as n,o as s,c as l,a,b as e,w as t,F as r,e as p,d as o}from"./app.48111a85.js";const u={},c=a("h1",{id:"透明代理入门",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理入门","aria-hidden":"true"},"#"),p(" 透明代理入门")],-1),i=a("h2",{id:"什么是透明代理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#什么是透明代理","aria-hidden":"true"},"#"),p(" 什么是透明代理")],-1),b=a("p",null,"透明代理简单地说就是不让被代理的设备感觉到自己被代理了。简单地说就是,被代理的设备上不需要运行任何代理软件(比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。",-1),d=a("p",null,"这也意味着,代理的软件运行在别的地方,比如运行在路由器中,通过路由器上网的设备就自动被代理了。",-1),m=a("h2",{id:"透明代理的实现",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理的实现","aria-hidden":"true"},"#"),p(" 透明代理的实现")],-1),k=a("p",null,"透明代理的实现目前主要有两种方式:",-1),h=a("h3",{id:"tun2socks",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#tun2socks","aria-hidden":"true"},"#"),p(" tun2socks")],-1),g=a("p",null,"可用 Windows/Linux(包括安卓)实现。因为实现过程比较简单,很少有教程,我这里简单描述一下。",-1),R=a("p",null,[a("strong",null,"Windows")],-1),A=p("安装 "),f={href:"https://github.com/NetchX/Netch/releases",target:"_blank",rel:"noopener noreferrer"},P=p("Netch"),T=p(" ,使用模式"),N=a("code",null,"[3] [TUN/TAP] 绕过局域网",-1),y=p("启动。"),X=o("
  • 开启热点

  • 打开控制面板->网络和 Internet->网络和共享中心->更改适配器设置,找到TAP-Windows AdapterMicrosoft Wi-Fi Direct Virtual Adapter

  • 鼠标右键点击TAP-Windows Adapter属性->共享,勾选允许其他网络用户通过此计算机的 Internet 连接来连接,在家庭网络连接中选择Microsoft Wi-Fi Direct Virtual Adapter的那个网络连接,点击确定。

  • ",3),E=a("p",null,[a("strong",null,"Android")],-1),x=a("ol",null,[a("li",null,[a("p",null,"配置连接 V2RayNG")]),a("li",null,[a("p",null,"开启热点")]),a("li",null,[a("p",null,"热点设置 -> 允许热点使用 VPN(部分安卓系统可能没有这个选项)")])],-1),U=a("h3",{id:"iptables-nftables",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-nftables","aria-hidden":"true"},"#"),p(" iptables/nftables")],-1),O=a("p",null,"iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。",-1),Y=a("p",null,"基于 iptables 的透明代理实现只能用于 Linux 系统(包括 openwrt/安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而广泛使用。",-1),I=p("现存的三篇白话文透明代理教程其实讲的都是基于这种方案的透明代理实现,它们是: "),j={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},_=p("新 V2Ray 白话文指南-透明代理"),v=p(" 、 "),S={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},G=p("新 V2Ray 白话文指南-透明代理(TPROXY)"),w=p(" 、 "),B=p("透明代理(TProxy)配置教程"),D=p(" 。其中第一篇是基于 iptables-redirect 模式,已经过时了,不建议使用,仅供参考。第二篇和第三篇讲的都是基于 iptables-tproxy 模式的透明代理实现。"),L=a("h2",{id:"iptables-实现透明代理原理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-实现透明代理原理","aria-hidden":"true"},"#"),p(" iptables 实现透明代理原理")],-1),W=a("p",null,[p("Linux 使用"),a("code",null,"Netfilter"),p("来管理网络,"),a("code",null,"Netfilter"),p("模型如下:")],-1),C=a("p",null,[a("img",{src:"/Xray-docs-next/assets/netfilter.ef038b15.png",alt:"Netfilter"})],-1),M=a("p",null,[a("strong",null,"假设使用路由器作为网关(即我们平时的上网方式),那么:")],-1),V=a("p",null,"局域网设备通过路由器访问互联网的流量方向:",-1),K=a("p",null,[a("code",null,"PREROUTING链->FORWARD链->POSTINGROUTING链")],-1),F=a("p",null,"局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:",-1),$=a("p",null,[a("code",null,"PREROUTING链->INPUT链->网关本机")],-1),q=a("p",null,"路由器访问互联网的流量方向:",-1),H=a("p",null,[a("code",null,"网关本机->OUTPUT链->POSTINGROUTING链")],-1),z=a("p",null,[a("strong",null,[p("通过使用 iptables 操控"),a("code",null,"PREROUTING链"),p("和"),a("code",null,"OUTPUT链"),p("的流量走向,转发到 Xray,就可以代理局域网设备和网关本机。")])],-1),J=a("h2",{id:"透明代理难在哪里",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理难在哪里","aria-hidden":"true"},"#"),p(" 透明代理难在哪里")],-1),Q=a("p",null,[p("透明代理的难点就在于路由,所谓路由,就是区分哪些流量是直连的,哪些该被代理,所以我个人认为叫做"),a("strong",null,"分流"),p("更加合适。")],-1),Z=a("p",null,"我们可以把路由由易到难分为以下几个阶段:",-1),nn=a("ol",null,[a("li",null,[a("p",null,"代理全部请求")]),a("li",null,[a("p",null,"本地局域网 IP/组播 IP 请求直连,其它请求代理")]),a("li",null,[a("p",null,"在 2 的基础上直连 Xray 发起的连接请求")]),a("li",null,[a("p",null,"在 3 的基础上直连指向中国大陆 IP 的连接请求,并对国内外域名选择国内外 DNS 服务器解析。")])],-1),sn=a("p",null,"上面说的三篇教程,都是在第四阶段。所以新手直接阅读可能显得有点难懂。",-1),ln=a("h2",{id:"从零开始一步步实现基于-iptables-tproxy-的透明代理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#从零开始一步步实现基于-iptables-tproxy-的透明代理","aria-hidden":"true"},"#"),p(" 从零开始一步步实现基于 iptables-tproxy 的透明代理")],-1),an=a("h3",{id:"在开始之前-你需要有一定的基础知识",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#在开始之前-你需要有一定的基础知识","aria-hidden":"true"},"#"),p(" 在开始之前,你需要有一定的基础知识:")],-1),en=a("ol",null,[a("li",null,[a("p",null,"大概知道什么是 TCP/IP 协议、域名和 DNS 服务器")]),a("li",null,[a("p",null,"知道什么是 WAN 口,LAN 口,LAN_IP,WAN_IP 以及 DHCP 服务器。对于旁路由,只有一个网口,这里称其为 LAN 口")]),a("li",null,[a("p",null,"对 Linux 系统有最基础的了解(知道怎么运行命令)")]),a("li",null,[a("p",null,"能够手写客户端 json 文件配置,至少要能看懂")])],-1),tn=a("h3",{id:"前期准备工作",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#前期准备工作","aria-hidden":"true"},"#"),p(" 前期准备工作")],-1),rn=a("p",null,[a("strong",null,"1. 准备一个运行 Linux 系统的网关")],-1),pn=a("p",null,"比如,刷了 OpenWRT 的路由器",-1),on=a("p",null,[a("strong",null,"2. 在网关(路由器)准备好 Xray 可执行文件以及配置文件")],-1),un=a("p",null,"配置文件监听 12345 端口,开启 tproxy:",-1),cn=a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"log"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"loglevel"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"warning"'),p("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"inbounds"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"["),p("\n "),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token number"},"12345"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"dokodemo-door"'),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"tcp,udp"'),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"followRedirect"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token boolean"},"true"),p("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"sockopt"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"tproxy"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"tproxy"'),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"outbounds"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"["),p("\n "),a("span",{class:"token punctuation"},"{"),p("\n 你的服务器配置\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"]"),p("\n"),a("span",{class:"token punctuation"},"}"),p("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br")])],-1),bn=a("p",null,"我们由易到难,不写 routing,只写一个 inbound 一个 outbound。",-1),dn=a("h3",{id:"首先-我们先试试做到第一阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#首先-我们先试试做到第一阶段","aria-hidden":"true"},"#"),p(" 首先,我们先试试做到第一阶段")],-1),mn=a("p",null,[p("将所有"),a("code",null,"PREROUTING链"),p("的流量,都转发到 Xray 中。")],-1),kn=a("p",null,"运行 Xray,执行以下指令:",-1),hn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br")])],-1),gn=a("p",null,"当你输入完之后,如果你是使用 ssh 连接到网关上的,你会发现 ssh 的连接断开了(不用紧张,断电重启即可恢复),并且透明代理无法上网;如果你是的网关是虚拟机,你会发现网关本身也无法上网,并且 Xray 日志 access_log 中出现许多源地址为目标地址,目标地址为 WAN_IP 的请求。",-1),Rn=a("p",null,[p("理论上网关本机访问公网只会经过"),a("code",null,"OUTPUT链"),p("和"),a("code",null,"POSTROUTING链"),p(",为什么操控"),a("code",null,"PREROUTING链"),p("会导致网关无法上网呢?这是因为网络通讯往往是双向的,虽然网关访问公网 IP 不需要经过"),a("code",null,"PREROUTING链"),p(",但被访问的服务器向网关返回信息时要经过"),a("code",null,"PREROUTING链"),p(",且这部分被转发到 Xray 了,因此出现了日志中的反向请求。")],-1),An=a("p",null,"我们修改一下规则,源 IP 不是来自局域网的则返回。重启网关,运行 Xray,执行以下指令:",-1),fn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\n"),a("span",{class:"token comment"},'# "网关LAN_IP地址段" 通过运行命令"ip address | grep -w "inet" | awk \'{print $2}\'"获得,是其中的一个'),p("\niptables -t mangle -A XRAY "),a("span",{class:"token operator"},"!"),p(" -s 网关LAN_IP地址段 -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br")])],-1),Pn=a("p",null,"然后你会发现,虽然 ssh 连接断开了,但是透明代理已经可用了。只要我们修改系统 dns 为公共 dns,就能正常上网了(因为现在网关访问不了,所以 dns 设置为网关是不行的)。",-1),Tn=a("p",null,"至此,第一阶段就完成了。之所以无法访问网关,是因为代理规则代理了全部流量,包括访问网关的流量。试想在 VPS 上访问你本地的网关,肯定是访问不了的,所以我们要对这部分流量直连,请看第二阶段:",-1),Nn=a("h3",{id:"第二阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第二阶段","aria-hidden":"true"},"#"),p(" 第二阶段")],-1),yn=a("p",null,"重启网关,运行 Xray,执行以下指令:",-1),Xn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\n\n"),a("span",{class:"token comment"},"# 所有目标地址在网关所在网段的请求直连"),p("\n"),a("span",{class:"token comment"},'# 通过运行命令"ip address | grep -w "inet" | awk \'{print $2}\'"获得,一般来说有多个'),p("\niptables -t mangle -A XRAY -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\n\n"),a("span",{class:"token comment"},"# 目标地址为组播IP/E类地址/广播IP的请求直连"),p("\niptables -t mangle -A XRAY -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\n\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br")])],-1),En=a("p",null,[p("使用这条规则后,上一条规则"),a("code",null,"iptables -t mangle -A XRAY ! -s 网关LAN_IP地址段 -j RETURN"),p("便成为了多余规则,可以删去。")],-1),xn=a("p",null,"至此,第二阶段完成。网关已经可以访问,ssh 不会断开。",-1),Un=a("h3",{id:"第三阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第三阶段","aria-hidden":"true"},"#"),p(" 第三阶段")],-1),On=a("p",null,"我们平时用的 DNS 一般来自路由器,但这个 iptables 规则只代理了局域网中的设备,却没有代理网关本机,这样返回的 DNS 查询结果可能是错误的或者污染的。",-1),Yn=a("p",null,[p("iptables-tproxy 不支持对"),a("code",null,"OUTPUT链"),p("操作,但是我们可以通过配置"),a("code",null,"策略路由"),p(",把"),a("code",null,"OUTPUT链"),p("中相应的包重新路由到"),a("code",null,"PREROUTING链"),p("上。")],-1),In=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token comment"},"# 添加策略路由: 标记为1的包,走路由表100"),p("\n"),a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token comment"},"# 添加路由条目到路由表100: 所有包路由到本地"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br")])],-1),jn=a("p",null,[p("通过配置上述"),a("code",null,"策略路由"),p(",我们只需要在"),a("code",null,"OUTPUT链"),p("中给包打标记为"),a("code",null,"1"),p(",相应的包就会路由到网关本机,即"),a("code",null,"PREROUTING链"),p("上。所以我们就给网关本机需要代理的请求在"),a("code",null,"OUTPUT链"),p("上标记"),a("code",null,"1"),p("即可。")],-1),_n=a("p",null,"如果要代理网关本机发出的的全部请求,就会引入一个问题,Xray 运行在网关,Xray 向代理服务端发送请求,这个请求又被代理了,就形成了回环。",-1),vn=a("p",null,"因此要代理网关本机,就要避免回环发生,即代理规则中规避 Xray 请求的流量。",-1),Sn=a("p",null,[a("strong",null,"常见的方法有三种:")],-1),Gn=a("ol",null,[a("li",null,"直连目标地址为 VPS 的流量")],-1),wn=a("p",null,"重启网关,运行 Xray,执行以下指令:",-1),Bn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token comment"},"#代理局域网设备"),p("\n"),a("span",{class:"token comment"},"#继承上一个阶段的成果"),p("\n"),a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\niptables -t mangle -A XRAY -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n\n"),a("span",{class:"token comment"},"#代理网关本机"),p("\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY_MASK -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\niptables -t mangle -A XRAY_MASK -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\niptables -t mangle -A XRAY_MASK -d VPS公网ip/32 -j RETURN\niptables -t mangle -A XRAY_MASK -j MARK --set-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK\niptables -t mangle -A OUTPUT -p udp -j XRAY_MASK\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br")])],-1),Dn=a("p",null,"但是这么配置有个缺点,如果使用 CDN 或者 VPS 很多的话,就不好写规则了。",-1),Ln=a("ol",{start:"2"},[a("li",null,"通过 mark 规避")],-1),Wn=a("p",null,"三个白话文教程都是使用这种方法规避,自行参考,这里不再赘述。",-1),Cn=a("ol",{start:"3"},[a("li",null,"通过 gid 规避(推荐)")],-1),Mn=p("参考 "),Vn=p("[透明代理]通过 gid 规避 Xray 流量"),Kn=a("p",null,"这样就完成了第三阶段的代理,也就是平时说的全局代理。但是记得把网关的 DNS 服务器设置为国外的 DNS 服务器,否则可能依然返回被污染的结果。",-1),Fn=a("h3",{id:"第四阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第四阶段","aria-hidden":"true"},"#"),p(" 第四阶段")],-1),$n=a("p",null,"其实,并不是所有人都需要实现第四阶段。全局代理对于大部分情况已经适用。",-1),qn=a("p",null,"特别是对于旁路由而言。需要代理时,将网关调成旁路由的 IP,不需要代理时,将网关换回主路由 IP。",-1),Hn=a("p",null,"至于第四阶段的具体实现,那三篇白话文教程讲的都是。在理解了上面的内容后,再去看那三篇白话文教程,就比较容易理解了。",-1),zn=a("h3",{id:"代理-ipv6",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#代理-ipv6","aria-hidden":"true"},"#"),p(" 代理 ipv6")],-1),Jn=p("上面的规则只对 ipv4 生效,如果还想要代理 ipv6 请求,则使用 ip6tables 命令,用法与 iptables 基本相同。参考 "),Qn=p("[透明代理]通过 gid 规避 Xray 流量#4-设置 iptables 规则"),Zn=a("h1",{id:"iptables-透明代理的其它注意事项",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-透明代理的其它注意事项","aria-hidden":"true"},"#"),p(" iptables 透明代理的其它注意事项")],-1),ns=a("li",null,[a("p",null,[p("如果作为代理的网关作为主路由,要在"),a("code",null,"PREROUTING链"),p("规则中加一条"),a("code",null,"iptables -t mangle -A XRAY ! -s 网关LAN_IP地址段 -j RETURN"),p(",即在第一阶段使用、第二阶段被删除的指令。如果不写,WAN 口中同网段的其它人可以将网关填写成你的 WAN_IP,从而蹭你的透明代理用,还可能带来一定的危险性。")])],-1),ss={href:"https://guide.v2fly.org/app/tproxy.html#%E8%AE%BE%E7%BD%AE%E7%BD%91%E5%85%B3",target:"_blank",rel:"noopener noreferrer"},ls=p("新 V2Ray 白话文指南-透明代理(TPROXY)#设置网关"),as=p(" 中的第三条说:"),es=a("code",null,"手动配置 PC 的网络,将默认网关指向树莓派的地址即 192.168.1.22。此时 PC 应当能正常上网(由于还没设置代理,“正常”是指可以上国内的网站)",-1),ts=p("。实际上,Ubuntu、CentOS、debian 等系统就算开启了 IP 转发,PC 也不能正常上网,这是正常的。事实上只有 OpenWRT 能做到文中所描述的那样,据 "),rs={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},ps=p("@BioniCosmos"),os=p(" 点拨,这是由于一般的 Linux 系统没有 Masquery 规则。"),us={href:"https://guide.v2fly.org/app/tproxy.html#%E8%A7%A3%E5%86%B3-too-many-open-files-%E9%97%AE%E9%A2%98",target:"_blank",rel:"noopener noreferrer"},cs=p("too many open files 问题"),is=p(" ,解决方法见 "),bs=a("strong",null,[a("a",{href:"../iptables_gid#3-%E9%85%8D%E7%BD%AE%E6%9C%80%E5%A4%A7%E6%96%87%E4%BB%B6%E5%A4%A7%E5%BC%80%E6%95%B0%E8%BF%90%E8%A1%8Cxray%E5%AE%A2%E6%88%B7%E7%AB%AF"},"[透明代理]通过 gid 规避 Xray 流量-配置最大文件大开数&运行 Xray 客户端")],-1),ds=a("li",null,[a("p",null,"关于开启 ip_forward,待补充...")],-1),ms=a("li",null,[a("p",null,"避免已有连接的包二次通过 TPROXY ,待补充...")],-1),ks=a("li",null,[a("p",null,"主路由、单臂路由与旁路由,待补充...")],-1);u.render=function(p,o){const u=n("OutboundLink"),hs=n("RouterLink");return s(),l(r,null,[c,i,b,d,m,k,h,g,R,a("ol",null,[a("li",null,[a("p",null,[A,a("strong",null,[a("a",f,[P,e(u)])]),T,N,y])]),X]),E,x,U,O,Y,a("p",null,[I,a("strong",null,[a("a",j,[_,e(u)])]),v,a("strong",null,[a("a",S,[G,e(u)])]),w,a("strong",null,[e(hs,{to:"/document/level-2/tproxy.html"},{default:t((()=>[B])),_:1})]),D]),L,W,C,M,V,K,F,$,q,H,z,J,Q,Z,nn,sn,ln,an,en,tn,rn,pn,on,un,cn,bn,dn,mn,kn,hn,gn,Rn,An,fn,Pn,Tn,Nn,yn,Xn,En,xn,Un,On,Yn,In,jn,_n,vn,Sn,Gn,wn,Bn,Dn,Ln,Wn,Cn,a("p",null,[Mn,a("strong",null,[e(hs,{to:"/document/level-2/iptables_gid.html"},{default:t((()=>[Vn])),_:1})])]),Kn,Fn,$n,qn,Hn,zn,a("p",null,[Jn,a("strong",null,[e(hs,{to:"/document/level-2/iptables_gid#4-%E8%AE%BE%E7%BD%AEiptables%E8%A7%84%E5%88%99.html"},{default:t((()=>[Qn])),_:1})])]),Zn,a("ol",null,[ns,a("li",null,[a("p",null,[a("strong",null,[a("a",ss,[ls,e(u)])]),as,es,ts,a("strong",null,[a("a",rs,[ps,e(u)])]),os])]),a("li",null,[a("p",null,[a("strong",null,[a("a",us,[cs,e(u)])]),is,bs])]),ds,ms,ks])],64)};export default u; diff --git a/assets/transparent_proxy.html.440228ab.js b/assets/transparent_proxy.html.aa464a57.js similarity index 99% rename from assets/transparent_proxy.html.440228ab.js rename to assets/transparent_proxy.html.aa464a57.js index 35b0bec35..d23eac100 100644 --- a/assets/transparent_proxy.html.440228ab.js +++ b/assets/transparent_proxy.html.aa464a57.js @@ -1 +1 @@ -import{r as n,o as s,c as l,a,b as e,w as t,F as r,e as p,d as o}from"./app.755d843f.js";const u={},c=a("h1",{id:"透明代理入门",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理入门","aria-hidden":"true"},"#"),p(" 透明代理入门")],-1),i=a("h2",{id:"什么是透明代理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#什么是透明代理","aria-hidden":"true"},"#"),p(" 什么是透明代理")],-1),b=a("p",null,"透明代理简单地说就是不让被代理的设备感觉到自己被代理了。简单地说就是,被代理的设备上不需要运行任何代理软件(比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。",-1),d=a("p",null,"这也意味着,代理的软件运行在别的地方,比如运行在路由器中,通过路由器上网的设备就自动被代理了。",-1),m=a("h2",{id:"透明代理的实现",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理的实现","aria-hidden":"true"},"#"),p(" 透明代理的实现")],-1),k=a("p",null,"透明代理的实现目前主要有两种方式:",-1),h=a("h3",{id:"tun2socks",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#tun2socks","aria-hidden":"true"},"#"),p(" tun2socks")],-1),g=a("p",null,"可用 Windows/Linux(包括安卓)实现。因为实现过程比较简单,很少有教程,我这里简单描述一下。",-1),R=a("p",null,[a("strong",null,"Windows")],-1),A=p("安装 "),f={href:"https://github.com/NetchX/Netch/releases",target:"_blank",rel:"noopener noreferrer"},P=p("Netch"),T=p(" ,使用模式"),N=a("code",null,"[3] [TUN/TAP] 绕过局域网",-1),y=p("启动。"),X=o("
  • 开启热点

  • 打开控制面板->网络和 Internet->网络和共享中心->更改适配器设置,找到TAP-Windows AdapterMicrosoft Wi-Fi Direct Virtual Adapter

  • 鼠标右键点击TAP-Windows Adapter属性->共享,勾选允许其他网络用户通过此计算机的 Internet 连接来连接,在家庭网络连接中选择Microsoft Wi-Fi Direct Virtual Adapter的那个网络连接,点击确定。

  • ",3),E=a("p",null,[a("strong",null,"Android")],-1),x=a("ol",null,[a("li",null,[a("p",null,"配置连接 V2RayNG")]),a("li",null,[a("p",null,"开启热点")]),a("li",null,[a("p",null,"热点设置 -> 允许热点使用 VPN(部分安卓系统可能没有这个选项)")])],-1),U=a("h3",{id:"iptables-nftables",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-nftables","aria-hidden":"true"},"#"),p(" iptables/nftables")],-1),Y=a("p",null,"iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。",-1),O=a("p",null,"基于 iptables 的透明代理实现只能用于 Linux 系统(包括 openwrt/安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而广泛使用。",-1),I=p("现存的三篇白话文透明代理教程其实讲的都是基于这种方案的透明代理实现,它们是: "),j={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},_=p("新 V2Ray 白话文指南-透明代理"),v=p(" 、 "),S={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},G=p("新 V2Ray 白话文指南-透明代理(TPROXY)"),w=p(" 、 "),B=p("透明代理(TProxy)配置教程"),D=p(" 。其中第一篇是基于 iptables-redirect 模式,已经过时了,不建议使用,仅供参考。第二篇和第三篇讲的都是基于 iptables-tproxy 模式的透明代理实现。"),L=a("h2",{id:"iptables-实现透明代理原理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-实现透明代理原理","aria-hidden":"true"},"#"),p(" iptables 实现透明代理原理")],-1),W=a("p",null,[p("Linux 使用"),a("code",null,"Netfilter"),p("来管理网络,"),a("code",null,"Netfilter"),p("模型如下:")],-1),C=a("p",null,[a("img",{src:"/Xray-docs-next/assets/netfilter.ef038b15.png",alt:"Netfilter"})],-1),M=a("p",null,[a("strong",null,"假设使用路由器作为网关(即我们平时的上网方式),那么:")],-1),V=a("p",null,"局域网设备通过路由器访问互联网的流量方向:",-1),K=a("p",null,[a("code",null,"PREROUTING链->FORWARD链->POSTINGROUTING链")],-1),F=a("p",null,"局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:",-1),$=a("p",null,[a("code",null,"PREROUTING链->INPUT链->网关本机")],-1),q=a("p",null,"路由器访问互联网的流量方向:",-1),H=a("p",null,[a("code",null,"网关本机->OUTPUT链->POSTINGROUTING链")],-1),z=a("p",null,[a("strong",null,[p("通过使用 iptables 操控"),a("code",null,"PREROUTING链"),p("和"),a("code",null,"OUTPUT链"),p("的流量走向,转发到 Xray,就可以代理局域网设备和网关本机。")])],-1),J=a("h2",{id:"透明代理难在哪里",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理难在哪里","aria-hidden":"true"},"#"),p(" 透明代理难在哪里")],-1),Q=a("p",null,[p("透明代理的难点就在于路由,所谓路由,就是区分哪些流量是直连的,哪些该被代理,所以我个人认为叫做"),a("strong",null,"分流"),p("更加合适。")],-1),Z=a("p",null,"我们可以把路由由易到难分为以下几个阶段:",-1),nn=a("ol",null,[a("li",null,[a("p",null,"代理全部请求")]),a("li",null,[a("p",null,"本地局域网 IP/组播 IP 请求直连,其它请求代理")]),a("li",null,[a("p",null,"在 2 的基础上直连 Xray 发起的连接请求")]),a("li",null,[a("p",null,"在 3 的基础上直连指向中国大陆 IP 的连接请求,并对国内外域名选择国内外 DNS 服务器解析。")])],-1),sn=a("p",null,"上面说的三篇教程,都是在第四阶段。所以新手直接阅读可能显得有点难懂。",-1),ln=a("h2",{id:"从零开始一步步实现基于-iptables-tproxy-的透明代理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#从零开始一步步实现基于-iptables-tproxy-的透明代理","aria-hidden":"true"},"#"),p(" 从零开始一步步实现基于 iptables-tproxy 的透明代理")],-1),an=a("h3",{id:"在开始之前-你需要有一定的基础知识",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#在开始之前-你需要有一定的基础知识","aria-hidden":"true"},"#"),p(" 在开始之前,你需要有一定的基础知识:")],-1),en=a("ol",null,[a("li",null,[a("p",null,"大概知道什么是 TCP/IP 协议、域名和 DNS 服务器")]),a("li",null,[a("p",null,"知道什么是 WAN 口,LAN 口,LAN_IP,WAN_IP 以及 DHCP 服务器。对于旁路由,只有一个网口,这里称其为 LAN 口")]),a("li",null,[a("p",null,"对 Linux 系统有最基础的了解(知道怎么运行命令)")]),a("li",null,[a("p",null,"能够手写客户端 json 文件配置,至少要能看懂")])],-1),tn=a("h3",{id:"前期准备工作",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#前期准备工作","aria-hidden":"true"},"#"),p(" 前期准备工作")],-1),rn=a("p",null,[a("strong",null,"1. 准备一个运行 Linux 系统的网关")],-1),pn=a("p",null,"比如,刷了 OpenWRT 的路由器",-1),on=a("p",null,[a("strong",null,"2. 在网关(路由器)准备好 Xray 可执行文件以及配置文件")],-1),un=a("p",null,"配置文件监听 12345 端口,开启 tproxy:",-1),cn=a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"log"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"loglevel"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"warning"'),p("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"inbounds"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"["),p("\n "),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token number"},"12345"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"dokodemo-door"'),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"tcp,udp"'),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"followRedirect"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token boolean"},"true"),p("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"sockopt"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"tproxy"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"tproxy"'),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"outbounds"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"["),p("\n "),a("span",{class:"token punctuation"},"{"),p("\n 你的服务器配置\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"]"),p("\n"),a("span",{class:"token punctuation"},"}"),p("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br")])],-1),bn=a("p",null,"我们由易到难,不写 routing,只写一个 inbound 一个 outbound。",-1),dn=a("h3",{id:"首先-我们先试试做到第一阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#首先-我们先试试做到第一阶段","aria-hidden":"true"},"#"),p(" 首先,我们先试试做到第一阶段")],-1),mn=a("p",null,[p("将所有"),a("code",null,"PREROUTING链"),p("的流量,都转发到 Xray 中。")],-1),kn=a("p",null,"运行 Xray,执行以下指令:",-1),hn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br")])],-1),gn=a("p",null,"当你输入完之后,如果你是使用 ssh 连接到网关上的,你会发现 ssh 的连接断开了(不用紧张,断电重启即可恢复),并且透明代理无法上网;如果你是的网关是虚拟机,你会发现网关本身也无法上网,并且 Xray 日志 access_log 中出现许多源地址为目标地址,目标地址为 WAN_IP 的请求。",-1),Rn=a("p",null,[p("理论上网关本机访问公网只会经过"),a("code",null,"OUTPUT链"),p("和"),a("code",null,"POSTROUTING链"),p(",为什么操控"),a("code",null,"PREROUTING链"),p("会导致网关无法上网呢?这是因为网络通讯往往是双向的,虽然网关访问公网 IP 不需要经过"),a("code",null,"PREROUTING链"),p(",但被访问的服务器向网关返回信息时要经过"),a("code",null,"PREROUTING链"),p(",且这部分被转发到 Xray 了,因此出现了日志中的反向请求。")],-1),An=a("p",null,"我们修改一下规则,源 IP 不是来自局域网的则返回。重启网关,运行 Xray,执行以下指令:",-1),fn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\n"),a("span",{class:"token comment"},'# "网关LAN_IP地址段" 通过运行命令"ip address | grep -w "inet" | awk \'{print $2}\'"获得,是其中的一个'),p("\niptables -t mangle -A XRAY "),a("span",{class:"token operator"},"!"),p(" -s 网关LAN_IP地址段 -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br")])],-1),Pn=a("p",null,"然后你会发现,虽然 ssh 连接断开了,但是透明代理已经可用了。只要我们修改系统 dns 为公共 dns,就能正常上网了(因为现在网关访问不了,所以 dns 设置为网关是不行的)。",-1),Tn=a("p",null,"至此,第一阶段就完成了。之所以无法访问网关,是因为代理规则代理了全部流量,包括访问网关的流量。试想在 VPS 上访问你本地的网关,肯定是访问不了的,所以我们要对这部分流量直连,请看第二阶段:",-1),Nn=a("h3",{id:"第二阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第二阶段","aria-hidden":"true"},"#"),p(" 第二阶段")],-1),yn=a("p",null,"重启网关,运行 Xray,执行以下指令:",-1),Xn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\n\n"),a("span",{class:"token comment"},"# 所有目标地址在网关所在网段的请求直连"),p("\n"),a("span",{class:"token comment"},'# 通过运行命令"ip address | grep -w "inet" | awk \'{print $2}\'"获得,一般来说有多个'),p("\niptables -t mangle -A XRAY -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\n\n"),a("span",{class:"token comment"},"# 目标地址为组播IP/E类地址/广播IP的请求直连"),p("\niptables -t mangle -A XRAY -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\n\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br")])],-1),En=a("p",null,[p("使用这条规则后,上一条规则"),a("code",null,"iptables -t mangle -A XRAY ! -s 网关LAN_IP地址段 -j RETURN"),p("便成为了多余规则,可以删去。")],-1),xn=a("p",null,"至此,第二阶段完成。网关已经可以访问,ssh 不会断开。",-1),Un=a("h3",{id:"第三阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第三阶段","aria-hidden":"true"},"#"),p(" 第三阶段")],-1),Yn=a("p",null,"我们平时用的 DNS 一般来自路由器,但这个 iptables 规则只代理了局域网中的设备,却没有代理网关本机,这样返回的 DNS 查询结果可能是错误的或者污染的。",-1),On=a("p",null,[p("iptables-tproxy 不支持对"),a("code",null,"OUTPUT链"),p("操作,但是"),a("code",null,"Netfilter"),p("有个特性,在"),a("code",null,"OUTPUT链"),p("给包打标记为"),a("code",null,"1"),p("后相应的包会重路由到"),a("code",null,"PREROUTING链"),p("上。所以我们就给网关本机需要代理的请求在"),a("code",null,"OUTPUT链"),p("上标记"),a("code",null,"1"),p("即可。")],-1),In=a("p",null,"如果要代理网关本机发出的的全部请求,就会引入一个问题,Xray 运行在网关,Xray 向代理服务端发送请求,这个请求又被代理了,就形成了回环。",-1),jn=a("p",null,"因此要代理网关本机,就要避免回环发生,即代理规则中规避 Xray 请求的流量。",-1),_n=a("p",null,[a("strong",null,"常见的方法有三种:")],-1),vn=a("ol",null,[a("li",null,"直连目标地址为 VPS 的流量")],-1),Sn=a("p",null,"重启网关,运行 Xray,执行以下指令:",-1),Gn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token comment"},"#代理局域网设备"),p("\n"),a("span",{class:"token comment"},"#继承上一个阶段的成果"),p("\n"),a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\niptables -t mangle -A XRAY -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n\n"),a("span",{class:"token comment"},"#代理网关本机"),p("\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY_MASK -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\niptables -t mangle -A XRAY_MASK -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\niptables -t mangle -A XRAY_MASK -d VPS公网ip/32 -j RETURN\niptables -t mangle -A XRAY_MASK -j MARK --set-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK\niptables -t mangle -A OUTPUT -p udp -j XRAY_MASK\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br")])],-1),wn=a("p",null,"但是这么配置有个缺点,如果使用 CDN 或者 VPS 很多的话,就不好写规则了。",-1),Bn=a("ol",{start:"2"},[a("li",null,"通过 mark 规避")],-1),Dn=a("p",null,"三个白话文教程都是使用这种方法规避,自行参考,这里不再赘述。",-1),Ln=a("ol",{start:"3"},[a("li",null,"通过 gid 规避(推荐)")],-1),Wn=p("参考 "),Cn=p("[透明代理]通过 gid 规避 Xray 流量"),Mn=a("p",null,"这样就完成了第三阶段的代理,也就是平时说的全局代理。但是记得把网关的 DNS 服务器设置为国外的 DNS 服务器,否则可能依然返回被污染的结果。",-1),Vn=a("h3",{id:"第四阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第四阶段","aria-hidden":"true"},"#"),p(" 第四阶段")],-1),Kn=a("p",null,"其实,并不是所有人都需要实现第四阶段。全局代理对于大部分情况已经适用。",-1),Fn=a("p",null,"特别是对于旁路由而言。需要代理时,将网关调成旁路由的 IP,不需要代理时,将网关换回主路由 IP。",-1),$n=a("p",null,"至于第四阶段的具体实现,那三篇白话文教程讲的都是。在理解了上面的内容后,再去看那三篇白话文教程,就比较容易理解了。",-1),qn=a("h3",{id:"代理-ipv6",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#代理-ipv6","aria-hidden":"true"},"#"),p(" 代理 ipv6")],-1),Hn=p("上面的规则只对 ipv4 生效,如果还想要代理 ipv6 请求,则使用 ip6tables 命令,用法与 iptables 基本相同。参考 "),zn=p("[透明代理]通过 gid 规避 Xray 流量#4-设置 iptables 规则"),Jn=a("h1",{id:"iptables-透明代理的其它注意事项",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-透明代理的其它注意事项","aria-hidden":"true"},"#"),p(" iptables 透明代理的其它注意事项")],-1),Qn=a("li",null,[a("p",null,[p("如果作为代理的网关作为主路由,要在"),a("code",null,"PREROUTING链"),p("规则中加一条"),a("code",null,"iptables -t mangle -A XRAY ! -s 网关LAN_IP地址段 -j RETURN"),p(",即在第一阶段使用、第二阶段被删除的指令。如果不写,WAN 口中同网段的其它人可以将网关填写成你的 WAN_IP,从而蹭你的透明代理用,还可能带来一定的危险性。")])],-1),Zn={href:"https://guide.v2fly.org/app/tproxy.html#%E8%AE%BE%E7%BD%AE%E7%BD%91%E5%85%B3",target:"_blank",rel:"noopener noreferrer"},ns=p("新 V2Ray 白话文指南-透明代理(TPROXY)#设置网关"),ss=p(" 中的第三条说:"),ls=a("code",null,"手动配置 PC 的网络,将默认网关指向树莓派的地址即 192.168.1.22。此时 PC 应当能正常上网(由于还没设置代理,“正常”是指可以上国内的网站)",-1),as=p("。实际上,Ubuntu、CentOS、debian 等系统就算开启了 IP 转发,PC 也不能正常上网,这是正常的。事实上只有 OpenWRT 能做到文中所描述的那样,据 "),es={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},ts=p("@BioniCosmos"),rs=p(" 点拨,这是由于一般的 Linux 系统没有 Masquery 规则。"),ps={href:"https://guide.v2fly.org/app/tproxy.html#%E8%A7%A3%E5%86%B3-too-many-open-files-%E9%97%AE%E9%A2%98",target:"_blank",rel:"noopener noreferrer"},os=p("too many open files 问题"),us=p(" ,解决方法见 "),cs=a("strong",null,[a("a",{href:"../iptables_gid#3-%E9%85%8D%E7%BD%AE%E6%9C%80%E5%A4%A7%E6%96%87%E4%BB%B6%E5%A4%A7%E5%BC%80%E6%95%B0%E8%BF%90%E8%A1%8Cxray%E5%AE%A2%E6%88%B7%E7%AB%AF"},"[透明代理]通过 gid 规避 Xray 流量-配置最大文件大开数&运行 Xray 客户端")],-1),is=a("li",null,[a("p",null,"关于开启 ip_forward,待补充...")],-1),bs=a("li",null,[a("p",null,"避免已有连接的包二次通过 TPROXY ,待补充...")],-1),ds=a("li",null,[a("p",null,"主路由、单臂路由与旁路由,待补充...")],-1);u.render=function(p,o){const u=n("OutboundLink"),ms=n("RouterLink");return s(),l(r,null,[c,i,b,d,m,k,h,g,R,a("ol",null,[a("li",null,[a("p",null,[A,a("strong",null,[a("a",f,[P,e(u)])]),T,N,y])]),X]),E,x,U,Y,O,a("p",null,[I,a("strong",null,[a("a",j,[_,e(u)])]),v,a("strong",null,[a("a",S,[G,e(u)])]),w,a("strong",null,[e(ms,{to:"/en/document/level-2/tproxy.html"},{default:t((()=>[B])),_:1})]),D]),L,W,C,M,V,K,F,$,q,H,z,J,Q,Z,nn,sn,ln,an,en,tn,rn,pn,on,un,cn,bn,dn,mn,kn,hn,gn,Rn,An,fn,Pn,Tn,Nn,yn,Xn,En,xn,Un,Yn,On,In,jn,_n,vn,Sn,Gn,wn,Bn,Dn,Ln,a("p",null,[Wn,a("strong",null,[e(ms,{to:"/en/document/level-2/iptables_gid.html"},{default:t((()=>[Cn])),_:1})])]),Mn,Vn,Kn,Fn,$n,qn,a("p",null,[Hn,a("strong",null,[e(ms,{to:"/en/document/level-2/iptables_gid#4-%E8%AE%BE%E7%BD%AEiptables%E8%A7%84%E5%88%99.html"},{default:t((()=>[zn])),_:1})])]),Jn,a("ol",null,[Qn,a("li",null,[a("p",null,[a("strong",null,[a("a",Zn,[ns,e(u)])]),ss,ls,as,a("strong",null,[a("a",es,[ts,e(u)])]),rs])]),a("li",null,[a("p",null,[a("strong",null,[a("a",ps,[os,e(u)])]),us,cs])]),is,bs,ds])],64)};export default u; +import{r as n,o as s,c as l,a,b as e,w as t,F as r,e as p,d as o}from"./app.48111a85.js";const u={},c=a("h1",{id:"透明代理入门",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理入门","aria-hidden":"true"},"#"),p(" 透明代理入门")],-1),i=a("h2",{id:"什么是透明代理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#什么是透明代理","aria-hidden":"true"},"#"),p(" 什么是透明代理")],-1),b=a("p",null,"透明代理简单地说就是不让被代理的设备感觉到自己被代理了。简单地说就是,被代理的设备上不需要运行任何代理软件(比如 Xray、V2RayNG 等),当你连接上网络时,你的设备已经被代理了。",-1),d=a("p",null,"这也意味着,代理的软件运行在别的地方,比如运行在路由器中,通过路由器上网的设备就自动被代理了。",-1),m=a("h2",{id:"透明代理的实现",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理的实现","aria-hidden":"true"},"#"),p(" 透明代理的实现")],-1),k=a("p",null,"透明代理的实现目前主要有两种方式:",-1),h=a("h3",{id:"tun2socks",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#tun2socks","aria-hidden":"true"},"#"),p(" tun2socks")],-1),g=a("p",null,"可用 Windows/Linux(包括安卓)实现。因为实现过程比较简单,很少有教程,我这里简单描述一下。",-1),R=a("p",null,[a("strong",null,"Windows")],-1),A=p("安装 "),f={href:"https://github.com/NetchX/Netch/releases",target:"_blank",rel:"noopener noreferrer"},P=p("Netch"),T=p(" ,使用模式"),N=a("code",null,"[3] [TUN/TAP] 绕过局域网",-1),y=p("启动。"),X=o("
  • 开启热点

  • 打开控制面板->网络和 Internet->网络和共享中心->更改适配器设置,找到TAP-Windows AdapterMicrosoft Wi-Fi Direct Virtual Adapter

  • 鼠标右键点击TAP-Windows Adapter属性->共享,勾选允许其他网络用户通过此计算机的 Internet 连接来连接,在家庭网络连接中选择Microsoft Wi-Fi Direct Virtual Adapter的那个网络连接,点击确定。

  • ",3),E=a("p",null,[a("strong",null,"Android")],-1),x=a("ol",null,[a("li",null,[a("p",null,"配置连接 V2RayNG")]),a("li",null,[a("p",null,"开启热点")]),a("li",null,[a("p",null,"热点设置 -> 允许热点使用 VPN(部分安卓系统可能没有这个选项)")])],-1),U=a("h3",{id:"iptables-nftables",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-nftables","aria-hidden":"true"},"#"),p(" iptables/nftables")],-1),Y=a("p",null,"iptables 与 nftables 实现透明代理的原理相同,下文统一使用 iptables。",-1),O=a("p",null,"基于 iptables 的透明代理实现只能用于 Linux 系统(包括 openwrt/安卓)。由于其比 tun2socks 更高效率以及适合在路由器中配置而广泛使用。",-1),I=p("现存的三篇白话文透明代理教程其实讲的都是基于这种方案的透明代理实现,它们是: "),j={href:"https://guide.v2fly.org/app/transparent_proxy.html",target:"_blank",rel:"noopener noreferrer"},_=p("新 V2Ray 白话文指南-透明代理"),v=p(" 、 "),S={href:"https://guide.v2fly.org/app/tproxy.html",target:"_blank",rel:"noopener noreferrer"},G=p("新 V2Ray 白话文指南-透明代理(TPROXY)"),w=p(" 、 "),B=p("透明代理(TProxy)配置教程"),D=p(" 。其中第一篇是基于 iptables-redirect 模式,已经过时了,不建议使用,仅供参考。第二篇和第三篇讲的都是基于 iptables-tproxy 模式的透明代理实现。"),L=a("h2",{id:"iptables-实现透明代理原理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-实现透明代理原理","aria-hidden":"true"},"#"),p(" iptables 实现透明代理原理")],-1),W=a("p",null,[p("Linux 使用"),a("code",null,"Netfilter"),p("来管理网络,"),a("code",null,"Netfilter"),p("模型如下:")],-1),C=a("p",null,[a("img",{src:"/Xray-docs-next/assets/netfilter.ef038b15.png",alt:"Netfilter"})],-1),M=a("p",null,[a("strong",null,"假设使用路由器作为网关(即我们平时的上网方式),那么:")],-1),V=a("p",null,"局域网设备通过路由器访问互联网的流量方向:",-1),K=a("p",null,[a("code",null,"PREROUTING链->FORWARD链->POSTINGROUTING链")],-1),F=a("p",null,"局域网设备访问路由器的流量(如登陆路由器 web 管理界面/ssh 连接路由器/访问路由器的 dns 服务器等)方向:",-1),$=a("p",null,[a("code",null,"PREROUTING链->INPUT链->网关本机")],-1),q=a("p",null,"路由器访问互联网的流量方向:",-1),H=a("p",null,[a("code",null,"网关本机->OUTPUT链->POSTINGROUTING链")],-1),z=a("p",null,[a("strong",null,[p("通过使用 iptables 操控"),a("code",null,"PREROUTING链"),p("和"),a("code",null,"OUTPUT链"),p("的流量走向,转发到 Xray,就可以代理局域网设备和网关本机。")])],-1),J=a("h2",{id:"透明代理难在哪里",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#透明代理难在哪里","aria-hidden":"true"},"#"),p(" 透明代理难在哪里")],-1),Q=a("p",null,[p("透明代理的难点就在于路由,所谓路由,就是区分哪些流量是直连的,哪些该被代理,所以我个人认为叫做"),a("strong",null,"分流"),p("更加合适。")],-1),Z=a("p",null,"我们可以把路由由易到难分为以下几个阶段:",-1),nn=a("ol",null,[a("li",null,[a("p",null,"代理全部请求")]),a("li",null,[a("p",null,"本地局域网 IP/组播 IP 请求直连,其它请求代理")]),a("li",null,[a("p",null,"在 2 的基础上直连 Xray 发起的连接请求")]),a("li",null,[a("p",null,"在 3 的基础上直连指向中国大陆 IP 的连接请求,并对国内外域名选择国内外 DNS 服务器解析。")])],-1),sn=a("p",null,"上面说的三篇教程,都是在第四阶段。所以新手直接阅读可能显得有点难懂。",-1),ln=a("h2",{id:"从零开始一步步实现基于-iptables-tproxy-的透明代理",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#从零开始一步步实现基于-iptables-tproxy-的透明代理","aria-hidden":"true"},"#"),p(" 从零开始一步步实现基于 iptables-tproxy 的透明代理")],-1),an=a("h3",{id:"在开始之前-你需要有一定的基础知识",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#在开始之前-你需要有一定的基础知识","aria-hidden":"true"},"#"),p(" 在开始之前,你需要有一定的基础知识:")],-1),en=a("ol",null,[a("li",null,[a("p",null,"大概知道什么是 TCP/IP 协议、域名和 DNS 服务器")]),a("li",null,[a("p",null,"知道什么是 WAN 口,LAN 口,LAN_IP,WAN_IP 以及 DHCP 服务器。对于旁路由,只有一个网口,这里称其为 LAN 口")]),a("li",null,[a("p",null,"对 Linux 系统有最基础的了解(知道怎么运行命令)")]),a("li",null,[a("p",null,"能够手写客户端 json 文件配置,至少要能看懂")])],-1),tn=a("h3",{id:"前期准备工作",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#前期准备工作","aria-hidden":"true"},"#"),p(" 前期准备工作")],-1),rn=a("p",null,[a("strong",null,"1. 准备一个运行 Linux 系统的网关")],-1),pn=a("p",null,"比如,刷了 OpenWRT 的路由器",-1),on=a("p",null,[a("strong",null,"2. 在网关(路由器)准备好 Xray 可执行文件以及配置文件")],-1),un=a("p",null,"配置文件监听 12345 端口,开启 tproxy:",-1),cn=a("div",{class:"language-json ext-json line-numbers-mode"},[a("pre",{class:"language-json"},[a("code",null,[a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"log"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"loglevel"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"warning"'),p("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"inbounds"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"["),p("\n "),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"port"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token number"},"12345"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"protocol"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"dokodemo-door"'),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"settings"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"network"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"tcp,udp"'),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"followRedirect"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token boolean"},"true"),p("\n "),a("span",{class:"token punctuation"},"}"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"streamSettings"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"sockopt"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"{"),p("\n "),a("span",{class:"token property"},'"tproxy"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token string"},'"tproxy"'),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"]"),a("span",{class:"token punctuation"},","),p("\n "),a("span",{class:"token property"},'"outbounds"'),a("span",{class:"token operator"},":"),p(),a("span",{class:"token punctuation"},"["),p("\n "),a("span",{class:"token punctuation"},"{"),p("\n 你的服务器配置\n "),a("span",{class:"token punctuation"},"}"),p("\n "),a("span",{class:"token punctuation"},"]"),p("\n"),a("span",{class:"token punctuation"},"}"),p("\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br"),a("span",{class:"line-number"},"24"),a("br"),a("span",{class:"line-number"},"25"),a("br")])],-1),bn=a("p",null,"我们由易到难,不写 routing,只写一个 inbound 一个 outbound。",-1),dn=a("h3",{id:"首先-我们先试试做到第一阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#首先-我们先试试做到第一阶段","aria-hidden":"true"},"#"),p(" 首先,我们先试试做到第一阶段")],-1),mn=a("p",null,[p("将所有"),a("code",null,"PREROUTING链"),p("的流量,都转发到 Xray 中。")],-1),kn=a("p",null,"运行 Xray,执行以下指令:",-1),hn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br")])],-1),gn=a("p",null,"当你输入完之后,如果你是使用 ssh 连接到网关上的,你会发现 ssh 的连接断开了(不用紧张,断电重启即可恢复),并且透明代理无法上网;如果你是的网关是虚拟机,你会发现网关本身也无法上网,并且 Xray 日志 access_log 中出现许多源地址为目标地址,目标地址为 WAN_IP 的请求。",-1),Rn=a("p",null,[p("理论上网关本机访问公网只会经过"),a("code",null,"OUTPUT链"),p("和"),a("code",null,"POSTROUTING链"),p(",为什么操控"),a("code",null,"PREROUTING链"),p("会导致网关无法上网呢?这是因为网络通讯往往是双向的,虽然网关访问公网 IP 不需要经过"),a("code",null,"PREROUTING链"),p(",但被访问的服务器向网关返回信息时要经过"),a("code",null,"PREROUTING链"),p(",且这部分被转发到 Xray 了,因此出现了日志中的反向请求。")],-1),An=a("p",null,"我们修改一下规则,源 IP 不是来自局域网的则返回。重启网关,运行 Xray,执行以下指令:",-1),fn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\n"),a("span",{class:"token comment"},'# "网关LAN_IP地址段" 通过运行命令"ip address | grep -w "inet" | awk \'{print $2}\'"获得,是其中的一个'),p("\niptables -t mangle -A XRAY "),a("span",{class:"token operator"},"!"),p(" -s 网关LAN_IP地址段 -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br")])],-1),Pn=a("p",null,"然后你会发现,虽然 ssh 连接断开了,但是透明代理已经可用了。只要我们修改系统 dns 为公共 dns,就能正常上网了(因为现在网关访问不了,所以 dns 设置为网关是不行的)。",-1),Tn=a("p",null,"至此,第一阶段就完成了。之所以无法访问网关,是因为代理规则代理了全部流量,包括访问网关的流量。试想在 VPS 上访问你本地的网关,肯定是访问不了的,所以我们要对这部分流量直连,请看第二阶段:",-1),Nn=a("h3",{id:"第二阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第二阶段","aria-hidden":"true"},"#"),p(" 第二阶段")],-1),yn=a("p",null,"重启网关,运行 Xray,执行以下指令:",-1),Xn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\n\n"),a("span",{class:"token comment"},"# 所有目标地址在网关所在网段的请求直连"),p("\n"),a("span",{class:"token comment"},'# 通过运行命令"ip address | grep -w "inet" | awk \'{print $2}\'"获得,一般来说有多个'),p("\niptables -t mangle -A XRAY -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\n\n"),a("span",{class:"token comment"},"# 目标地址为组播IP/E类地址/广播IP的请求直连"),p("\niptables -t mangle -A XRAY -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\n\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br")])],-1),En=a("p",null,[p("使用这条规则后,上一条规则"),a("code",null,"iptables -t mangle -A XRAY ! -s 网关LAN_IP地址段 -j RETURN"),p("便成为了多余规则,可以删去。")],-1),xn=a("p",null,"至此,第二阶段完成。网关已经可以访问,ssh 不会断开。",-1),Un=a("h3",{id:"第三阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第三阶段","aria-hidden":"true"},"#"),p(" 第三阶段")],-1),Yn=a("p",null,"我们平时用的 DNS 一般来自路由器,但这个 iptables 规则只代理了局域网中的设备,却没有代理网关本机,这样返回的 DNS 查询结果可能是错误的或者污染的。",-1),On=a("p",null,[p("iptables-tproxy 不支持对"),a("code",null,"OUTPUT链"),p("操作,但是"),a("code",null,"Netfilter"),p("有个特性,在"),a("code",null,"OUTPUT链"),p("给包打标记为"),a("code",null,"1"),p("后相应的包会重路由到"),a("code",null,"PREROUTING链"),p("上。所以我们就给网关本机需要代理的请求在"),a("code",null,"OUTPUT链"),p("上标记"),a("code",null,"1"),p("即可。")],-1),In=a("p",null,"如果要代理网关本机发出的的全部请求,就会引入一个问题,Xray 运行在网关,Xray 向代理服务端发送请求,这个请求又被代理了,就形成了回环。",-1),jn=a("p",null,"因此要代理网关本机,就要避免回环发生,即代理规则中规避 Xray 请求的流量。",-1),_n=a("p",null,[a("strong",null,"常见的方法有三种:")],-1),vn=a("ol",null,[a("li",null,"直连目标地址为 VPS 的流量")],-1),Sn=a("p",null,"重启网关,运行 Xray,执行以下指令:",-1),Gn=a("div",{class:"language-bash ext-sh line-numbers-mode"},[a("pre",{class:"language-bash"},[a("code",null,[a("span",{class:"token comment"},"#代理局域网设备"),p("\n"),a("span",{class:"token comment"},"#继承上一个阶段的成果"),p("\n"),a("span",{class:"token function"},"ip"),p(" rule "),a("span",{class:"token function"},"add"),p(" fwmark "),a("span",{class:"token number"},"1"),p(" table "),a("span",{class:"token number"},"100"),p("\n"),a("span",{class:"token function"},"ip"),p(" route "),a("span",{class:"token function"},"add"),p(),a("span",{class:"token builtin class-name"},"local"),p(),a("span",{class:"token number"},"0.0"),p(".0.0/0 dev lo table "),a("span",{class:"token number"},"100"),p("\niptables -t mangle -N XRAY\niptables -t mangle -A XRAY -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\niptables -t mangle -A XRAY -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\niptables -t mangle -A XRAY -p tcp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A XRAY -p udp -j TPROXY --on-port "),a("span",{class:"token number"},"12345"),p(" --tproxy-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A PREROUTING -j XRAY\n\n"),a("span",{class:"token comment"},"#代理网关本机"),p("\niptables -t mangle -N XRAY_MASK\niptables -t mangle -A XRAY_MASK -d 网关所在网段1 -j RETURN\niptables -t mangle -A XRAY_MASK -d 网关所在网段2 -j RETURN\n"),a("span",{class:"token punctuation"},".."),p(".\niptables -t mangle -A XRAY_MASK -d "),a("span",{class:"token number"},"224.0"),p(".0.0/3 -j RETURN\niptables -t mangle -A XRAY_MASK -d VPS公网ip/32 -j RETURN\niptables -t mangle -A XRAY_MASK -j MARK --set-mark "),a("span",{class:"token number"},"1"),p("\niptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK\niptables -t mangle -A OUTPUT -p udp -j XRAY_MASK\n")])]),a("div",{class:"line-numbers"},[a("span",{class:"line-number"},"1"),a("br"),a("span",{class:"line-number"},"2"),a("br"),a("span",{class:"line-number"},"3"),a("br"),a("span",{class:"line-number"},"4"),a("br"),a("span",{class:"line-number"},"5"),a("br"),a("span",{class:"line-number"},"6"),a("br"),a("span",{class:"line-number"},"7"),a("br"),a("span",{class:"line-number"},"8"),a("br"),a("span",{class:"line-number"},"9"),a("br"),a("span",{class:"line-number"},"10"),a("br"),a("span",{class:"line-number"},"11"),a("br"),a("span",{class:"line-number"},"12"),a("br"),a("span",{class:"line-number"},"13"),a("br"),a("span",{class:"line-number"},"14"),a("br"),a("span",{class:"line-number"},"15"),a("br"),a("span",{class:"line-number"},"16"),a("br"),a("span",{class:"line-number"},"17"),a("br"),a("span",{class:"line-number"},"18"),a("br"),a("span",{class:"line-number"},"19"),a("br"),a("span",{class:"line-number"},"20"),a("br"),a("span",{class:"line-number"},"21"),a("br"),a("span",{class:"line-number"},"22"),a("br"),a("span",{class:"line-number"},"23"),a("br")])],-1),wn=a("p",null,"但是这么配置有个缺点,如果使用 CDN 或者 VPS 很多的话,就不好写规则了。",-1),Bn=a("ol",{start:"2"},[a("li",null,"通过 mark 规避")],-1),Dn=a("p",null,"三个白话文教程都是使用这种方法规避,自行参考,这里不再赘述。",-1),Ln=a("ol",{start:"3"},[a("li",null,"通过 gid 规避(推荐)")],-1),Wn=p("参考 "),Cn=p("[透明代理]通过 gid 规避 Xray 流量"),Mn=a("p",null,"这样就完成了第三阶段的代理,也就是平时说的全局代理。但是记得把网关的 DNS 服务器设置为国外的 DNS 服务器,否则可能依然返回被污染的结果。",-1),Vn=a("h3",{id:"第四阶段",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#第四阶段","aria-hidden":"true"},"#"),p(" 第四阶段")],-1),Kn=a("p",null,"其实,并不是所有人都需要实现第四阶段。全局代理对于大部分情况已经适用。",-1),Fn=a("p",null,"特别是对于旁路由而言。需要代理时,将网关调成旁路由的 IP,不需要代理时,将网关换回主路由 IP。",-1),$n=a("p",null,"至于第四阶段的具体实现,那三篇白话文教程讲的都是。在理解了上面的内容后,再去看那三篇白话文教程,就比较容易理解了。",-1),qn=a("h3",{id:"代理-ipv6",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#代理-ipv6","aria-hidden":"true"},"#"),p(" 代理 ipv6")],-1),Hn=p("上面的规则只对 ipv4 生效,如果还想要代理 ipv6 请求,则使用 ip6tables 命令,用法与 iptables 基本相同。参考 "),zn=p("[透明代理]通过 gid 规避 Xray 流量#4-设置 iptables 规则"),Jn=a("h1",{id:"iptables-透明代理的其它注意事项",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#iptables-透明代理的其它注意事项","aria-hidden":"true"},"#"),p(" iptables 透明代理的其它注意事项")],-1),Qn=a("li",null,[a("p",null,[p("如果作为代理的网关作为主路由,要在"),a("code",null,"PREROUTING链"),p("规则中加一条"),a("code",null,"iptables -t mangle -A XRAY ! -s 网关LAN_IP地址段 -j RETURN"),p(",即在第一阶段使用、第二阶段被删除的指令。如果不写,WAN 口中同网段的其它人可以将网关填写成你的 WAN_IP,从而蹭你的透明代理用,还可能带来一定的危险性。")])],-1),Zn={href:"https://guide.v2fly.org/app/tproxy.html#%E8%AE%BE%E7%BD%AE%E7%BD%91%E5%85%B3",target:"_blank",rel:"noopener noreferrer"},ns=p("新 V2Ray 白话文指南-透明代理(TPROXY)#设置网关"),ss=p(" 中的第三条说:"),ls=a("code",null,"手动配置 PC 的网络,将默认网关指向树莓派的地址即 192.168.1.22。此时 PC 应当能正常上网(由于还没设置代理,“正常”是指可以上国内的网站)",-1),as=p("。实际上,Ubuntu、CentOS、debian 等系统就算开启了 IP 转发,PC 也不能正常上网,这是正常的。事实上只有 OpenWRT 能做到文中所描述的那样,据 "),es={href:"https://github.com/BioniCosmos",target:"_blank",rel:"noopener noreferrer"},ts=p("@BioniCosmos"),rs=p(" 点拨,这是由于一般的 Linux 系统没有 Masquery 规则。"),ps={href:"https://guide.v2fly.org/app/tproxy.html#%E8%A7%A3%E5%86%B3-too-many-open-files-%E9%97%AE%E9%A2%98",target:"_blank",rel:"noopener noreferrer"},os=p("too many open files 问题"),us=p(" ,解决方法见 "),cs=a("strong",null,[a("a",{href:"../iptables_gid#3-%E9%85%8D%E7%BD%AE%E6%9C%80%E5%A4%A7%E6%96%87%E4%BB%B6%E5%A4%A7%E5%BC%80%E6%95%B0%E8%BF%90%E8%A1%8Cxray%E5%AE%A2%E6%88%B7%E7%AB%AF"},"[透明代理]通过 gid 规避 Xray 流量-配置最大文件大开数&运行 Xray 客户端")],-1),is=a("li",null,[a("p",null,"关于开启 ip_forward,待补充...")],-1),bs=a("li",null,[a("p",null,"避免已有连接的包二次通过 TPROXY ,待补充...")],-1),ds=a("li",null,[a("p",null,"主路由、单臂路由与旁路由,待补充...")],-1);u.render=function(p,o){const u=n("OutboundLink"),ms=n("RouterLink");return s(),l(r,null,[c,i,b,d,m,k,h,g,R,a("ol",null,[a("li",null,[a("p",null,[A,a("strong",null,[a("a",f,[P,e(u)])]),T,N,y])]),X]),E,x,U,Y,O,a("p",null,[I,a("strong",null,[a("a",j,[_,e(u)])]),v,a("strong",null,[a("a",S,[G,e(u)])]),w,a("strong",null,[e(ms,{to:"/en/document/level-2/tproxy.html"},{default:t((()=>[B])),_:1})]),D]),L,W,C,M,V,K,F,$,q,H,z,J,Q,Z,nn,sn,ln,an,en,tn,rn,pn,on,un,cn,bn,dn,mn,kn,hn,gn,Rn,An,fn,Pn,Tn,Nn,yn,Xn,En,xn,Un,Yn,On,In,jn,_n,vn,Sn,Gn,wn,Bn,Dn,Ln,a("p",null,[Wn,a("strong",null,[e(ms,{to:"/en/document/level-2/iptables_gid.html"},{default:t((()=>[Cn])),_:1})])]),Mn,Vn,Kn,Fn,$n,qn,a("p",null,[Hn,a("strong",null,[e(ms,{to:"/en/document/level-2/iptables_gid#4-%E8%AE%BE%E7%BD%AEiptables%E8%A7%84%E5%88%99.html"},{default:t((()=>[zn])),_:1})])]),Jn,a("ol",null,[Qn,a("li",null,[a("p",null,[a("strong",null,[a("a",Zn,[ns,e(u)])]),ss,ls,as,a("strong",null,[a("a",es,[ts,e(u)])]),rs])]),a("li",null,[a("p",null,[a("strong",null,[a("a",ps,[os,e(u)])]),us,cs])]),is,bs,ds])],64)};export default u; diff --git a/assets/transport.html.674eebf2.js b/assets/transport.html.8d4eb4bb.js similarity index 99% rename from assets/transport.html.674eebf2.js rename to assets/transport.html.8d4eb4bb.js index 1c7e1881c..8c1f3e5ee 100644 --- a/assets/transport.html.674eebf2.js +++ b/assets/transport.html.8d4eb4bb.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as o,b as t,w as e,F as p,d as c,e as l}from"./app.755d843f.js";const u={},r=c('

    传输方式

    传输方式(transport)是当前 Xray 节点和其它节点对接的方式。

    传输方式指定了稳定的数据传输的方式。通常来说,一个网络连接的两端需要有对称的传输方式。比如一端用了 WebSocket,那么另一个端也必须使用 WebSocket,否则无法建立连接。

    传输方式(transport)配置有两部分:

    1. 全局配置(TransportObject
    2. 局部配置(StreamSettingsObject)。
    • 局部配置时,可以指定每个单独的入站或出站用怎样的方式传输。
    • 通常来说客户端和服务器对应的入站和出站需要使用同样的传输方式。当其配置指定了一种传输方式,但没有填写具体设置时,此传输方式会使用全局配置中的设置。

    TransportObject

    TransportObject 对应配置文件的 transport 项。

    {\n  "transport": {\n    "tcpSettings": {},\n    "kcpSettings": {},\n    "wsSettings": {},\n    "httpSettings": {},\n    "quicSettings": {},\n    "dsSettings": {},\n    "grpcSettings": {}\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ',9),i=o("code",null,"tcpSettings",-1),k=l(": "),b=l("TcpObject"),d=o("p",null,"针对 TCP 连接的配置。",-1),q=o("code",null,"kcpSettings",-1),m=l(": "),g=l("KcpObject"),f=o("p",null,"针对 mKCP 连接的配置。",-1),y=o("code",null,"wsSettings",-1),h=l(": "),S=l("WebSocketObject"),x=o("p",null,"针对 WebSocket 连接的配置。",-1),v=o("code",null,"httpSettings",-1),T=l(": "),A=l("HttpObject"),P=o("p",null,"针对 HTTP/2 连接的配置。",-1),j=o("code",null,"quicSettings",-1),I=l(": "),C=l("QuicObject"),L=o("p",null,"针对 QUIC 连接的配置。",-1),w=o("code",null,"grpcSettings",-1),O=l(": "),E=l("GRPCObject"),D=o("p",null,"针对 gRPC 连接的配置。",-1),N=o("code",null,"dsSettings",-1),R=l(": "),F=l("DomainSocketObject"),B=c('

    针对 Domain Socket 连接的配置。

    StreamSettingsObject

    StreamSettingsObject 对应入站或出站中的 streamSettings 项。每一个入站或出站都可以分别配置不同的传输配置,都可以设置 streamSettings 来进行一些传输的配置。

    {\n  "network": "tcp",\n  "security": "none",\n  "tlsSettings": {},\n  "tcpSettings": {},\n  "kcpSettings": {},\n  "wsSettings": {},\n  "httpSettings": {},\n  "quicSettings": {},\n  "dsSettings": {},\n  "grpcSettings": {},\n  "sockopt": {\n    "mark": 0,\n    "tcpFastOpen": false,\n    "tproxy": "off",\n    "domainStrategy": "AsIs",\n    "dialerProxy": "",\n    "acceptProxyProtocol": false,\n    "tcpKeepAliveInterval": 0\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    network: "tcp" | "kcp" | "ws" | "http" | "domainsocket" | "quic" | "grpc"

    连接的数据流所使用的传输方式类型,默认值为 "tcp"

    security: "none" | "tls" | "reality"

    是否启用传输层加密,支持的选项有

    ',8),V=o("li",null,[o("code",null,'"none"'),l(" 表示不加密(默认值)")],-1),Q=o("code",null,'"tls"',-1),U=l(" 表示使用 "),G={href:"https://en.wikipedia.org/wiki/base/transport_Layer_Security",target:"_blank",rel:"noopener noreferrer"},K=l("TLS"),X=l("。"),Y=o("li",null,[o("code",null,'"reality"'),l(" 表示使用 REALITY。")],-1),M=c('

    tlsSettings: TLSObject

    TLS 配置。TLS 由 Golang 提供,通常情况下 TLS 协商的结果为使用 TLS 1.3,不支持 DTLS。

    realitySettings: RealityObject

    Reality 配置。Reality 是 Xray 的原创黑科技。 Reality 比 TLS 的安全性更高, 配置方式也和 TLS 一致.

    提示

    Reality 是目前最安全的传输加密方案, 且外部看来流量类型和正常上网具有一致性。 启用 Reality 并且配置合适的 XTLS Vision 流控模式, 可以 达到数倍甚至十几倍的性能提升。

    ',5),_=o("code",null,"tcpSettings",-1),W=l(": "),H=l("TcpObject"),J=o("p",null,"当前连接的 TCP 配置,仅当此连接使用 TCP 时有效。配置内容与上面的全局配置相同。",-1),z=o("code",null,"kcpSettings",-1),Z=l(": "),$=l("KcpObject"),nn=o("p",null,"当前连接的 mKCP 配置,仅当此连接使用 mKCP 时有效。配置内容与上面的全局配置相同。",-1),sn=o("code",null,"wsSettings",-1),an=l(": "),on=l("WebSocketObject"),tn=o("p",null,"当前连接的 WebSocket 配置,仅当此连接使用 WebSocket 时有效。配置内容与上面的全局配置相同。",-1),en=o("code",null,"httpSettings",-1),pn=l(": "),cn=l("HttpObject"),ln=o("p",null,"当前连接的 HTTP/2 配置,仅当此连接使用 HTTP/2 时有效。配置内容与上面的全局配置相同。",-1),un=o("code",null,"quicSettings",-1),rn=l(": "),kn=l("QUICObject"),bn=o("p",null,"当前连接的 QUIC 配置,仅当此连接使用 QUIC 时有效。配置内容与上面的全局配置相同。",-1),dn=o("code",null,"grpcSettings",-1),qn=l(": "),mn=l("GRPCObject"),gn=o("p",null,"当前连接的 gRPC 配置,仅当此连接使用 gRPC 时有效。配置内容与上面的全局配置相同。",-1),fn=o("code",null,"dsSettings",-1),yn=l(": "),hn=l("DomainSocketObject"),Sn=c('

    当前连接的 Domain socket 配置,仅当此连接使用 Domain socket 时有效。配置内容与上面的全局配置相同。

    sockopt: SockoptObject

    透明代理相关的具体配置。

    TLSObject

    {\n  "serverName": "xray.com",\n  "rejectUnknownSni": false,\n  "allowInsecure": false,\n  "alpn": ["h2", "http/1.1"],\n  "minVersion": "1.2",\n  "maxVersion": "1.3",\n  "cipherSuites": "此处填写你需要的加密套件名称,每个套件名称之间用:进行分隔",\n  "certificates": [],\n  "disableSystemRoot": false,\n  "enableSessionResumption": false,\n  "fingerprint": "",\n  "pinnedPeerCertificateChainSha256": [""]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    serverName: string

    指定服务器端证书的域名,在连接由 IP 建立时有用。

    当目标连接由域名指定时,比如在 Socks 入站接收到了域名,或者由 Sniffing 功能探测出了域名,这个域名会自动用于 serverName,无须手动配置。

    rejectUnknownSni: bool

    当值为 true 时,服务端接收到的 SNI 与证书域名不匹配即拒绝 TLS 握手,默认为 false。

    alpn: [ string ]

    一个字符串数组,指定了 TLS 握手时指定的 ALPN 数值。默认值为 ["h2", "http/1.1"]

    minVersion: string

    minVersion 为可接受的最小 TLS 版本。

    maxVersion: string

    maxVersion 为可接受的最大 TLS 版本。

    cipherSuites: string

    CipherSuites 用于配置受支持的密码套件列表, 每个套件名称之间用:进行分隔.

    ',18),xn=l("你可以在 "),vn={href:"https://golang.org/src/crypto/tls/cipher_suites.go#L500",target:"_blank",rel:"noopener noreferrer"},Tn=l("这里"),An=l("或 "),Pn={href:"https://golang.org/src/crypto/tls/cipher_suites.go#L44",target:"_blank",rel:"noopener noreferrer"},jn=l("这里"),In=l(" 找到 golang 加密套件的名词和说明"),Cn=c('

    警告

    以上两项配置为非必要选项,正常情况下不影响安全性 在未配置的情况下 golang 根据设备自动选择. 若不熟悉, 请勿配置此选项, 填写不当引起的问题自行负责

    allowInsecure: true | false

    是否允许不安全连接(仅用于客户端)。默认值为 false

    当值为 true 时,Xray 不会检查远端主机所提供的 TLS 证书的有效性。

    警告

    出于安全性考虑,这个选项不应该在实际场景中选择 true,否则可能遭受中间人攻击。

    disableSystemRoot: true | false

    是否禁用操作系统自带的 CA 证书。默认值为 false

    当值为 true 时,Xray 只会使用 certificates 中指定的证书进行 TLS 握手。当值为 false 时,Xray 只会使用操作系统自带的 CA 证书进行 TLS 握手。

    enableSessionResumption: true | false

    此参数的设置为 false 时, ClientHello 里没有 session_ticket 这个扩展。 通常来讲 go 语言程序的 ClientHello 里并没有用到这个扩展, 因此建议保持默认值。 默认值为 false

    fingerprint : string

    此参数用于配置指定 TLS Client Hello 的指纹。当其值为空时,表示不启用此功能。启用后,Xray 将通过 uTLS 库 模拟 TLS 指纹,或随机生成。支持三种配置方式:

    1. 常见浏览器最新版本的 TLS 指纹 包括
    • "chrome"
    • "firefox"
    • "safari"
    • "ios"
    • "android"
    • "edge"
    • "360"
    • "qq"
    1. 在 xray 启动时自动生成一个指纹
    • "random": 在较新版本的浏览器里随机抽取一个
    • "randomized": 完全随机生成一个独一无二的指纹 (100% 支持 TLS 1.3 使用 X25519)
    ',16),Ln={start:"3"},wn=l("使用 uTLS 原生指纹变量名 例如"),On=o("code",null,'"HelloRandomizedNoALPN"',-1),En=l(),Dn=o("code",null,'"HelloChrome_106_Shuffle"',-1),Nn=l("。完整名单见 "),Rn={href:"https://github.com/refraction-networking/utls/blob/master/u_common.go#L434",target:"_blank",rel:"noopener noreferrer"},Fn=l("uTLS 库"),Bn={class:"custom-container tip"},Vn=o("p",{class:"custom-container-title"},"提示",-1),Qn=l("此功能仅 "),Un=o("strong",null,"模拟",-1),Gn=l(),Kn=o("code",null,"TLS Client Hello",-1),Xn=l(" 的指纹,行为、其他指纹与 Golang 相同。如果你希望更加完整地模拟浏览器 "),Yn=o("code",null,"TLS",-1),Mn=l(" 指纹与行为,可以使用 "),_n=l("Browser Dialer"),Wn=l("。"),Hn=c('

    pinnedPeerCertificateChainSha256: [string]

    用于指定远程服务器的证书链 SHA256 散列值,使用标准编码格式。仅有当服务器端证书链散列值符合设置项中之一时才能成功建立 TLS 连接。

    在连接因为此配置失败时,会展示远程服务器证书散列值。

    警告

    不建议使用这种方式获得证书链散列值,因为在这种情况下将没有机会验证此时服务器提供的证书是否为真实证书,进而不保证获得的证书散列值为期望的散列值。

    提示

    如果需要获得证书的散列值,应在命令行中运行 xray tls certChainHash --cert <cert.pem> 来获取,<cert.pem> 应替换为实际证书文件路径。

    certificates: [ CertificateObject ]

    证书列表,其中每一项表示一个证书(建议 fullchain)。

    ',7),Jn={class:"custom-container tip"},zn=o("p",{class:"custom-container-title"},"提示",-1),Zn=l("如果要在 ssllibs 或者 myssl 获得 A/A+ 等级的评价, 请参考 "),$n={href:"https://github.com/XTLS/Xray-core/discussions/56#discussioncomment-215600",target:"_blank",rel:"noopener noreferrer"},ns=l("这里"),ss=l("."),as=c('

    RealityObject

    {\n  "show": false,\n  "dest": "example.com:443",\n  "xver": 0,\n  "serverNames": ["example.com", "www.example.com"],\n  "privateKey": "",\n  "minClientVer": "",\n  "maxClientVer": "",\n  "maxTimeDiff": 0,\n  "shortIds": ["", "0123456789abcdef"],\n  "shortId": "",\n  "fingerprint": "chrome",\n  "serverName": "",\n  "publicKey": "",\n  "shortId": "",\n  "spiderX": ""\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    ',2),os={class:"custom-container tip"},ts=o("p",{class:"custom-container-title"},"提示",-1),es=l("更多信息请参考 "),ps={href:"https://github.com/XTLS/REALITY",target:"_blank",rel:"noopener noreferrer"},cs=l("REALITY 项目"),ls=l("."),us=c('

    show : true | false

    当值为 true 时,输出调试信息。

    提示

    以下为入站服务端)配置。

    dest : string

    ',4),rs=l("必填,格式同 VLESS "),is=o("code",null,"fallbacks",-1),ks=l(" 的 "),bs={href:"https://xtls.github.io/config/features/fallback.html#fallbackobject",target:"_blank",rel:"noopener noreferrer"},ds=l("dest"),qs=l("。"),ms=o("blockquote",null,[o("p",null,[o("code",null,"xver"),l(" : number")])],-1),gs=l("选填,格式同 VLESS "),fs=o("code",null,"fallbacks",-1),ys=l(" 的 "),hs={href:"https://xtls.github.io/config/features/fallback.html#fallbackobject",target:"_blank",rel:"noopener noreferrer"},Ss=l("xver"),xs=c('

    serverNames : [string]

    必填,客户端可用的 serverName 列表,暂不支持 * 通配符。

    privateKey : string

    必填,执行 ./xray x25519 生成。

    minClientVer : string

    选填,客户端 Xray 最低版本,格式为 x.y.z

    maxClientVer : string

    选填,客户端 Xray 最高版本,格式为 x.y.z

    maxTimeDiff : number

    选填,允许的最大时间差,单位为毫秒。

    shortIds : [string]

    必填,客户端可用的 shortId 列表,可用于区分不同的客户端。

    0 到 f,长度为 2 的倍数,长度上限为 16。

    若包含空值,客户端 shortId 可为空。

    提示

    以下为出站客户端)配置。

    serverName : string

    服务端 serverNames 之一。

    fingerprint : string

    ',18),vs=l("必填,同 "),Ts={href:"https://xtls.github.io/config/transport.html#tlsobject",target:"_blank",rel:"noopener noreferrer"},As=l("TLSObject"),Ps=l("。"),js=c('

    shortID : string

    服务端 shortIds 之一。

    0 到 f,长度为 2 的倍数,长度上限为 16。

    若服务端的 shordIDs 包含空值,客户端可为空。

    publicKey : string

    必填,服务端私钥对应的公钥。使用 ./xray x25519 -i "服务器私钥" 生成。

    spiderX : string

    爬虫初始路径与参数,建议每个客户端不同。

    CertificateObject

    {\n  "ocspStapling": 3600,\n  "oneTimeLoading": false,\n  "usage": "encipherment",\n  "certificateFile": "/path/to/certificate.crt",\n  "keyFile": "/path/to/key.key",\n  "certificate": [\n    "--BEGIN CERTIFICATE--",\n    "MIICwDCCAaigAwIBAgIRAO16JMdESAuHidFYJAR/7kAwDQYJKoZIhvcNAQELBQAw",\n    "ADAeFw0xODA0MTAxMzU1MTdaFw0xODA0MTAxNTU1MTdaMAAwggEiMA0GCSqGSIb3",\n    "DQEBAQUAA4IBDwAwggEKAoIBAQCs2PX0fFSCjOemmdm9UbOvcLctF94Ox4BpSfJ+",\n    "3lJHwZbvnOFuo56WhQJWrclKoImp/c9veL1J4Bbtam3sW3APkZVEK9UxRQ57HQuw",\n    "OzhV0FD20/0YELou85TwnkTw5l9GVCXT02NG+pGlYsFrxesUHpojdl8tIcn113M5",\n    "pypgDPVmPeeORRf7nseMC6GhvXYM4txJPyenohwegl8DZ6OE5FkSVR5wFQtAhbON",\n    "OAkIVVmw002K2J6pitPuJGOka9PxcCVWhko/W+JCGapcC7O74palwBUuXE1iH+Jp",\n    "noPjGp4qE2ognW3WH/sgQ+rvo20eXb9Um1steaYY8xlxgBsXAgMBAAGjNTAzMA4G",\n    "A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAA",\n    "MA0GCSqGSIb3DQEBCwUAA4IBAQBUd9sGKYemzwPnxtw/vzkV8Q32NILEMlPVqeJU",\n    "7UxVgIODBV6A1b3tOUoktuhmgSSaQxjhYbFAVTD+LUglMUCxNbj56luBRlLLQWo+",\n    "9BUhC/ow393tLmqKcB59qNcwbZER6XT5POYwcaKM75QVqhCJVHJNb1zSEE7Co7iO",\n    "6wIan3lFyjBfYlBEz5vyRWQNIwKfdh5cK1yAu13xGENwmtlSTHiwbjBLXfk+0A/8",\n    "r/2s+sCYUkGZHhj8xY7bJ1zg0FRalP5LrqY+r6BckT1QPDIQKYy615j1LpOtwZe/",\n    "d4q7MD/dkzRDsch7t2cIjM/PYeMuzh87admSyL6hdtK0Nm/Q",\n    "--END CERTIFICATE--"\n  ],\n  "key": [\n    "--BEGIN RSA PRIVATE KEY--",\n    "MIIEowIBAAKCAQEArNj19HxUgoznppnZvVGzr3C3LRfeDseAaUnyft5SR8GW75zh",\n    "bqOeloUCVq3JSqCJqf3Pb3i9SeAW7Wpt7FtwD5GVRCvVMUUOex0LsDs4VdBQ9tP9",\n    "GBC6LvOU8J5E8OZfRlQl09NjRvqRpWLBa8XrFB6aI3ZfLSHJ9ddzOacqYAz1Zj3n",\n    "jkUX+57HjAuhob12DOLcST8np6IcHoJfA2ejhORZElUecBULQIWzjTgJCFVZsNNN",\n    "itieqYrT7iRjpGvT8XAlVoZKP1viQhmqXAuzu+KWpcAVLlxNYh/iaZ6D4xqeKhNq",\n    "IJ1t1h/7IEPq76NtHl2/VJtbLXmmGPMZcYAbFwIDAQABAoIBAFCgG4phfGIxK9Uw",\n    "qrp+o9xQLYGhQnmOYb27OpwnRCYojSlT+mvLcqwvevnHsr9WxyA+PkZ3AYS2PLue",\n    "C4xW0pzQgdn8wENtPOX8lHkuBocw1rNsCwDwvIguIuliSjI8o3CAy+xVDFgNhWap",\n    "/CMzfQYziB7GlnrM6hH838iiy0dlv4I/HKk+3/YlSYQEvnFokTf7HxbDDmznkJTM",\n    "aPKZ5qbnV+4AcQfcLYJ8QE0ViJ8dVZ7RLwIf7+SG0b0bqloti4+oQXqGtiESUwEW",\n    "/Wzi7oyCbFJoPsFWp1P5+wD7jAGpAd9lPIwPahdr1wl6VwIx9W0XYjoZn71AEaw4",\n    "bK4xUXECgYEA3g2o9WqyrhYSax3pGEdvV2qN0VQhw7Xe+jyy98CELOO2DNbB9QNJ",\n    "8cSSU/PjkxQlgbOJc8DEprdMldN5xI/srlsbQWCj72wXxXnVnh991bI2clwt7oYi",\n    "pcGZwzCrJyFL+QaZmYzLxkxYl1tCiiuqLm+EkjxCWKTX/kKEFb6rtnMCgYEAx0WR",\n    "L8Uue3lXxhXRdBS5QRTBNklkSxtU+2yyXRpvFa7Qam+GghJs5RKfJ9lTvjfM/PxG",\n    "3vhuBliWQOKQbm1ZGLbgGBM505EOP7DikUmH/kzKxIeRo4l64mioKdDwK/4CZtS7",\n    "az0Lq3eS6bq11qL4mEdE6Gn/Y+sqB83GHZYju80CgYABFm4KbbBcW+1RKv9WSBtK",\n    "gVIagV/89moWLa/uuLmtApyEqZSfn5mAHqdc0+f8c2/Pl9KHh50u99zfKv8AsHfH",\n    "TtjuVAvZg10GcZdTQ/I41ruficYL0gpfZ3haVWWxNl+J47di4iapXPxeGWtVA+u8",\n    "eH1cvgDRMFWCgE7nUFzE8wKBgGndUomfZtdgGrp4ouLZk6W4ogD2MpsYNSixkXyW",\n    "64cIbV7uSvZVVZbJMtaXxb6bpIKOgBQ6xTEH5SMpenPAEgJoPVts816rhHdfwK5Q",\n    "8zetklegckYAZtFbqmM0xjOI6bu5rqwFLWr1xo33jF0wDYPQ8RHMJkruB1FIB8V2",\n    "GxvNAoGBAM4g2z8NTPMqX+8IBGkGgqmcYuRQxd3cs7LOSEjF9hPy1it2ZFe/yUKq",\n    "ePa2E8osffK5LBkFzhyQb0WrGC9ijM9E6rv10gyuNjlwXdFJcdqVamxwPUBtxRJR",\n    "cYTY2HRkJXDdtT0Bkc3josE6UUDvwMpO0CfAETQPto1tjNEDhQhT",\n    "--END RSA PRIVATE KEY--"\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55

    ocspStapling: number

    OCSP 装订更新,与证书热重载的时间间隔。 单位:秒。默认值为 3600,即一小时。

    oneTimeLoading: true | false

    仅加载一次。值为 true 时将关闭证书热重载功能与 ocspStapling 功能。

    注意

    当值为 true 时,将会关闭 OCSP 装订。

    usage: "encipherment" | "verify" | "issue"

    证书用途,默认值为 "encipherment"

    • "encipherment":证书用于 TLS 认证和加密。
    • "verify":证书用于验证远端 TLS 的证书。当使用此项时,当前证书必须为 CA 证书。
    • "issue":证书用于签发其它证书。当使用此项时,当前证书必须为 CA 证书。

    TIP 1

    在 Windows 平台上可以将自签名的 CA 证书安装到系统中,即可验证远端 TLS 的证书。

    TIP 2

    当有新的客户端请求时,假设所指定的 serverName"xray.com",Xray 会先从证书列表中寻找可用于 "xray.com" 的证书,如果没有找到,则使用任一 usage"issue" 的证书签发一个适用于 "xray.com" 的证书,有效期为一小时。并将新的证书加入证书列表,以供后续使用。

    TIP 3

    certificateFilecertificate 同时指定时,Xray 优先使用 certificateFilekeyFilekey 也一样。

    TIP 4

    usage"verify" 时,keyFilekey 可均为空。

    TIP 5

    使用 xray tls cert 可以生成自签名的 CA 证书。

    ',23),Is={class:"custom-container tip"},Cs=o("p",{class:"custom-container-title"},"TIP 6",-1),Ls=l("如已经拥有一个域名, 可以使用工具便捷的获取免费第三方证书,如"),ws={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},Os=l("acme.sh"),Es=c('

    certificateFile: string

    证书文件路径,如使用 OpenSSL 生成,后缀名为 .crt。

    certificate: [ string ]

    一个字符串数组,表示证书内容,格式如样例所示。certificatecertificateFile 二者选一。

    keyFile: string

    密钥文件路径,如使用 OpenSSL 生成,后缀名为 .key。目前暂不支持需要密码的 key 文件。

    key: [ string ]

    一个字符串数组,表示密钥内容,格式如样例如示。keykeyFile 二者选一。

    SockoptObject

    {\n  "mark": 0,\n  "tcpMaxSeg": 1440,\n  "tcpFastOpen": false,\n  "tproxy": "off",\n  "domainStrategy": "AsIs",\n  "dialerProxy": "",\n  "acceptProxyProtocol": false,\n  "tcpKeepAliveInterval": 0,\n  "tcpKeepAliveIdle": 300,\n  "tcpUserTimeout": 10000,\n  "tcpcongestion": "bbr",\n  "interface": "wg0"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    mark: number

    一个整数。当其值非零时,在 outbound 连接上以此数值标记 SO_MARK。

    • 仅适用于 Linux 系统。
    • 需要 CAP_NET_ADMIN 权限。

    tcpMaxSeg: number

    用于设置 TCP 数据包的最大传输单元。

    tcpFastOpen: true | false | number

    ',16),Ds=l("是否启用 "),Ns={href:"https://zh.wikipedia.org/wiki/TCP%E5%BF%AB%E9%80%9F%E6%89%93%E5%BC%80",target:"_blank",rel:"noopener noreferrer"},Rs=l("TCP Fast Open"),Fs=l("。"),Bs=o("p",null,[l("当其值为 "),o("code",null,"true"),l(" 或"),o("code",null,"正整数"),l("时,启用 TFO;当其值为 "),o("code",null,"false"),l(" 或"),o("code",null,"负数"),l("时,强制关闭 TFO;当此项不存在或为 "),o("code",null,"0"),l(" 时,使用系统默认设置。 可用于 inbound/outbound。")],-1),Vs=c("
  • 仅在以下版本(或更新版本)的操作系统中可用:

    • 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
  • ",1),Qs=l("对于 Inbound,此处所设定的"),Us=o("code",null,"正整数",-1),Gs=l("代表 "),Ks={href:"https://tools.ietf.org/html/rfc7413#section-5.1",target:"_blank",rel:"noopener noreferrer"},Xs=l("待处理的 TFO 连接请求数上限"),Ys=l(" ,"),Ms=o("strong",null,"注意并非所有操作系统都支持在此设定",-1),_s=l(":"),Ws=c("
    • Linux / FreeBSD:此处的设定的正整数值代表上限,可接受的最大值为 2147483647,为 true 时将取 256;注意在 Linux,net.core.somaxconn 会限制此值的上限,如果超过了 somaxconn,请同时提高 somaxconn
    • Mac OS:此处为 true正整数时,仅代表启用 TFO,上限需要通过内核参数 net.inet.tcp.fastopen_backlog 单独设定。
    • Windows:此处为 true正整数时,仅代表启用 TFO。
    ",1),Hs=o("li",null,[o("p",null,[l("对于 Outbound,设定为 "),o("code",null,"true"),l(" 或"),o("code",null,"正整数"),l("在任何操作系统都仅表示启用 TFO。")])],-1),Js=c("

    tproxy: "redirect" | "tproxy" | "off"

    是否开启透明代理(仅适用于 Linux)。

    • "redirect":使用 Redirect 模式的透明代理。支持所有基于 IPv4/6 的 TCP 和 UDP 连接。
    • "tproxy":使用 TProxy 模式的透明代理。支持所有基于 IPv4/6 的 TCP 和 UDP 连接。
    • "off":关闭透明代理。

    透明代理需要 Root 或 CAP\\_NET\\_ADMIN 权限。

    ",4),zs={class:"custom-container danger"},Zs=o("p",{class:"custom-container-title"},"警告",-1),$s=l("当 "),na=l("Dokodemo-door"),sa=l(" 中指定了 "),aa=o("code",null,"followRedirect",-1),oa=l("为"),ta=o("code",null,"true",-1),ea=l(",且 Sockopt 设置中的"),pa=o("code",null,"tproxy",-1),ca=l(" 为空时,Sockopt 设置中的"),la=o("code",null,"tproxy",-1),ua=l(" 的值会被设为 "),ra=o("code",null,'"redirect"',-1),ia=l("。"),ka=o("blockquote",null,[o("p",null,[o("code",null,"domainStrategy"),l(': "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"')])],-1),ba=l("在之前的版本中,当 Xray 尝试使用域名建立系统连接时,域名的解析由系统完成,不受 Xray 控制。这导致了在 "),da={href:"https://github.com/v2ray/v2ray-core/issues/1909",target:"_blank",rel:"noopener noreferrer"},qa=l("非标准 Linux 环境中无法解析域名"),ma=l(" 等问题。为此,Xray 1.3.1 为 Sockopt 引入了 Freedom 中的 domainStrategy,解决了此问题。"),ga=o("p",null,"在目标地址为域名时, 配置相应的值, SystemDialer 的行为模式如下:",-1),fa=o("li",null,[o("code",null,'"AsIs"'),l(": 通过系统 DNS 服务器解析获取 IP, 向此域名发出连接。")],-1),ya=o("code",null,'"UseIP"',-1),ha=l("、"),Sa=o("code",null,'"UseIPv4"',-1),xa=l(" 和 "),va=o("code",null,'"UseIPv6"',-1),Ta=l(": 使用"),Aa=l("内置 DNS 服务器"),Pa=l("解析获取 IP 后, 直接向此 IP 发出连接。"),ja=c('

    默认值为 "AsIs"

    警告

    启用了此功能后,不当的配置可能会导致死循环。

    一句话版本:连接到服务器,需要等待 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。

    ',7),Ia={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},Ca=l("PROXY protocol"),La=l(" 专用于传递请求的真实来源 IP 和端口,"),wa=o("strong",null,"若你不了解它,请先忽略该项",-1),Oa=l("。"),Ea=c('

    常见的反代软件(如 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

    tcpcongestion: ""

    TCP 拥塞控制算法。仅支持 Linux。 不配置此项表示使用系统默认值。

    常见的算法

    • bbr(推荐)
    • cubic
    • reno

    提示

    执行命令 sysctl net.ipv4.tcp_congestion_control 获取系统默认值。

    interface: ""

    指定绑定出口网卡名称 仅支持 linux。

    ',19);u.render=function(c,l){const u=n("RouterLink"),Da=n("OutboundLink");return s(),a(p,null,[r,o("blockquote",null,[o("p",null,[i,k,t(u,{to:"/config/transports/tcp.html"},{default:e((()=>[b])),_:1})])]),d,o("blockquote",null,[o("p",null,[q,m,t(u,{to:"/config/transports/mkcp.html"},{default:e((()=>[g])),_:1})])]),f,o("blockquote",null,[o("p",null,[y,h,t(u,{to:"/config/transports/websocket.html"},{default:e((()=>[S])),_:1})])]),x,o("blockquote",null,[o("p",null,[v,T,t(u,{to:"/config/transports/h2.html"},{default:e((()=>[A])),_:1})])]),P,o("blockquote",null,[o("p",null,[j,I,t(u,{to:"/config/transports/quic.html"},{default:e((()=>[C])),_:1})])]),L,o("blockquote",null,[o("p",null,[w,O,t(u,{to:"/config/transports/grpc.html"},{default:e((()=>[E])),_:1})])]),D,o("blockquote",null,[o("p",null,[N,R,t(u,{to:"/config/transports/domainsocket.html"},{default:e((()=>[F])),_:1})])]),B,o("ul",null,[V,o("li",null,[Q,U,o("a",G,[K,t(Da)]),X]),Y]),M,o("blockquote",null,[o("p",null,[_,W,t(u,{to:"/config/transports/tcp.html"},{default:e((()=>[H])),_:1})])]),J,o("blockquote",null,[o("p",null,[z,Z,t(u,{to:"/config/transports/mkcp.html"},{default:e((()=>[$])),_:1})])]),nn,o("blockquote",null,[o("p",null,[sn,an,t(u,{to:"/config/transports/websocket.html"},{default:e((()=>[on])),_:1})])]),tn,o("blockquote",null,[o("p",null,[en,pn,t(u,{to:"/config/transports/h2.html"},{default:e((()=>[cn])),_:1})])]),ln,o("blockquote",null,[o("p",null,[un,rn,t(u,{to:"/config/transports/quic.html"},{default:e((()=>[kn])),_:1})])]),bn,o("blockquote",null,[o("p",null,[dn,qn,t(u,{to:"/config/transports/grpc.html"},{default:e((()=>[mn])),_:1})])]),gn,o("blockquote",null,[o("p",null,[fn,yn,t(u,{to:"/config/transports/domainsocket.html"},{default:e((()=>[hn])),_:1})])]),Sn,o("p",null,[xn,o("a",vn,[Tn,t(Da)]),An,o("a",Pn,[jn,t(Da)]),In]),Cn,o("ol",Ln,[o("li",null,[wn,On,En,Dn,Nn,o("a",Rn,[Fn,t(Da)])])]),o("div",Bn,[Vn,o("p",null,[Qn,Un,Gn,Kn,Xn,Yn,Mn,t(u,{to:"/config/transports/websocket.html#browser-dialer"},{default:e((()=>[_n])),_:1}),Wn])]),Hn,o("div",Jn,[zn,o("p",null,[Zn,o("a",$n,[ns,t(Da)]),ss])]),as,o("div",os,[ts,o("p",null,[es,o("a",ps,[cs,t(Da)]),ls])]),us,o("p",null,[rs,is,ks,o("a",bs,[ds,t(Da)]),qs]),ms,o("p",null,[gs,fs,ys,o("a",hs,[Ss,t(Da)])]),xs,o("p",null,[vs,o("a",Ts,[As,t(Da)]),Ps]),js,o("div",Is,[Cs,o("p",null,[Ls,o("a",ws,[Os,t(Da)])])]),Es,o("p",null,[Ds,o("a",Ns,[Rs,t(Da)]),Fs]),Bs,o("ul",null,[Vs,o("li",null,[o("p",null,[Qs,Us,Gs,o("a",Ks,[Xs,t(Da)]),Ys,Ms,_s]),Ws]),Hs]),Js,o("div",zs,[Zs,o("p",null,[$s,t(u,{to:"/config/inbounds/dokodemo.html"},{default:e((()=>[na])),_:1}),sa,aa,oa,ta,ea,pa,ca,la,ua,ra,ia])]),ka,o("p",null,[ba,o("a",da,[qa,t(Da)]),ma]),ga,o("ul",null,[fa,o("li",null,[ya,ha,Sa,xa,va,Ta,t(u,{to:"/config/dns.html"},{default:e((()=>[Aa])),_:1}),Pa])]),ja,o("p",null,[o("a",Ia,[Ca,t(Da)]),La,wa,Oa]),Ea],64)};export default u; +import{r as n,o as s,c as a,a as o,b as t,w as e,F as p,d as c,e as l}from"./app.48111a85.js";const u={},r=c('

    传输方式

    传输方式(transport)是当前 Xray 节点和其它节点对接的方式。

    传输方式指定了稳定的数据传输的方式。通常来说,一个网络连接的两端需要有对称的传输方式。比如一端用了 WebSocket,那么另一个端也必须使用 WebSocket,否则无法建立连接。

    传输方式(transport)配置有两部分:

    1. 全局配置(TransportObject
    2. 局部配置(StreamSettingsObject)。
    • 局部配置时,可以指定每个单独的入站或出站用怎样的方式传输。
    • 通常来说客户端和服务器对应的入站和出站需要使用同样的传输方式。当其配置指定了一种传输方式,但没有填写具体设置时,此传输方式会使用全局配置中的设置。

    TransportObject

    TransportObject 对应配置文件的 transport 项。

    {\n  "transport": {\n    "tcpSettings": {},\n    "kcpSettings": {},\n    "wsSettings": {},\n    "httpSettings": {},\n    "quicSettings": {},\n    "dsSettings": {},\n    "grpcSettings": {}\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ',9),i=o("code",null,"tcpSettings",-1),k=l(": "),b=l("TcpObject"),d=o("p",null,"针对 TCP 连接的配置。",-1),q=o("code",null,"kcpSettings",-1),m=l(": "),g=l("KcpObject"),f=o("p",null,"针对 mKCP 连接的配置。",-1),y=o("code",null,"wsSettings",-1),h=l(": "),S=l("WebSocketObject"),x=o("p",null,"针对 WebSocket 连接的配置。",-1),v=o("code",null,"httpSettings",-1),T=l(": "),A=l("HttpObject"),P=o("p",null,"针对 HTTP/2 连接的配置。",-1),j=o("code",null,"quicSettings",-1),I=l(": "),C=l("QuicObject"),L=o("p",null,"针对 QUIC 连接的配置。",-1),w=o("code",null,"grpcSettings",-1),O=l(": "),E=l("GRPCObject"),D=o("p",null,"针对 gRPC 连接的配置。",-1),N=o("code",null,"dsSettings",-1),R=l(": "),F=l("DomainSocketObject"),B=c('

    针对 Domain Socket 连接的配置。

    StreamSettingsObject

    StreamSettingsObject 对应入站或出站中的 streamSettings 项。每一个入站或出站都可以分别配置不同的传输配置,都可以设置 streamSettings 来进行一些传输的配置。

    {\n  "network": "tcp",\n  "security": "none",\n  "tlsSettings": {},\n  "tcpSettings": {},\n  "kcpSettings": {},\n  "wsSettings": {},\n  "httpSettings": {},\n  "quicSettings": {},\n  "dsSettings": {},\n  "grpcSettings": {},\n  "sockopt": {\n    "mark": 0,\n    "tcpFastOpen": false,\n    "tproxy": "off",\n    "domainStrategy": "AsIs",\n    "dialerProxy": "",\n    "acceptProxyProtocol": false,\n    "tcpKeepAliveInterval": 0\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    network: "tcp" | "kcp" | "ws" | "http" | "domainsocket" | "quic" | "grpc"

    连接的数据流所使用的传输方式类型,默认值为 "tcp"

    security: "none" | "tls" | "reality"

    是否启用传输层加密,支持的选项有

    ',8),V=o("li",null,[o("code",null,'"none"'),l(" 表示不加密(默认值)")],-1),Q=o("code",null,'"tls"',-1),U=l(" 表示使用 "),G={href:"https://en.wikipedia.org/wiki/base/transport_Layer_Security",target:"_blank",rel:"noopener noreferrer"},K=l("TLS"),X=l("。"),Y=o("li",null,[o("code",null,'"reality"'),l(" 表示使用 REALITY。")],-1),M=c('

    tlsSettings: TLSObject

    TLS 配置。TLS 由 Golang 提供,通常情况下 TLS 协商的结果为使用 TLS 1.3,不支持 DTLS。

    realitySettings: RealityObject

    Reality 配置。Reality 是 Xray 的原创黑科技。 Reality 比 TLS 的安全性更高, 配置方式也和 TLS 一致.

    提示

    Reality 是目前最安全的传输加密方案, 且外部看来流量类型和正常上网具有一致性。 启用 Reality 并且配置合适的 XTLS Vision 流控模式, 可以 达到数倍甚至十几倍的性能提升。

    ',5),_=o("code",null,"tcpSettings",-1),W=l(": "),H=l("TcpObject"),J=o("p",null,"当前连接的 TCP 配置,仅当此连接使用 TCP 时有效。配置内容与上面的全局配置相同。",-1),z=o("code",null,"kcpSettings",-1),Z=l(": "),$=l("KcpObject"),nn=o("p",null,"当前连接的 mKCP 配置,仅当此连接使用 mKCP 时有效。配置内容与上面的全局配置相同。",-1),sn=o("code",null,"wsSettings",-1),an=l(": "),on=l("WebSocketObject"),tn=o("p",null,"当前连接的 WebSocket 配置,仅当此连接使用 WebSocket 时有效。配置内容与上面的全局配置相同。",-1),en=o("code",null,"httpSettings",-1),pn=l(": "),cn=l("HttpObject"),ln=o("p",null,"当前连接的 HTTP/2 配置,仅当此连接使用 HTTP/2 时有效。配置内容与上面的全局配置相同。",-1),un=o("code",null,"quicSettings",-1),rn=l(": "),kn=l("QUICObject"),bn=o("p",null,"当前连接的 QUIC 配置,仅当此连接使用 QUIC 时有效。配置内容与上面的全局配置相同。",-1),dn=o("code",null,"grpcSettings",-1),qn=l(": "),mn=l("GRPCObject"),gn=o("p",null,"当前连接的 gRPC 配置,仅当此连接使用 gRPC 时有效。配置内容与上面的全局配置相同。",-1),fn=o("code",null,"dsSettings",-1),yn=l(": "),hn=l("DomainSocketObject"),Sn=c('

    当前连接的 Domain socket 配置,仅当此连接使用 Domain socket 时有效。配置内容与上面的全局配置相同。

    sockopt: SockoptObject

    透明代理相关的具体配置。

    TLSObject

    {\n  "serverName": "xray.com",\n  "rejectUnknownSni": false,\n  "allowInsecure": false,\n  "alpn": ["h2", "http/1.1"],\n  "minVersion": "1.2",\n  "maxVersion": "1.3",\n  "cipherSuites": "此处填写你需要的加密套件名称,每个套件名称之间用:进行分隔",\n  "certificates": [],\n  "disableSystemRoot": false,\n  "enableSessionResumption": false,\n  "fingerprint": "",\n  "pinnedPeerCertificateChainSha256": [""]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    serverName: string

    指定服务器端证书的域名,在连接由 IP 建立时有用。

    当目标连接由域名指定时,比如在 Socks 入站接收到了域名,或者由 Sniffing 功能探测出了域名,这个域名会自动用于 serverName,无须手动配置。

    rejectUnknownSni: bool

    当值为 true 时,服务端接收到的 SNI 与证书域名不匹配即拒绝 TLS 握手,默认为 false。

    alpn: [ string ]

    一个字符串数组,指定了 TLS 握手时指定的 ALPN 数值。默认值为 ["h2", "http/1.1"]

    minVersion: string

    minVersion 为可接受的最小 TLS 版本。

    maxVersion: string

    maxVersion 为可接受的最大 TLS 版本。

    cipherSuites: string

    CipherSuites 用于配置受支持的密码套件列表, 每个套件名称之间用:进行分隔.

    ',18),xn=l("你可以在 "),vn={href:"https://golang.org/src/crypto/tls/cipher_suites.go#L500",target:"_blank",rel:"noopener noreferrer"},Tn=l("这里"),An=l("或 "),Pn={href:"https://golang.org/src/crypto/tls/cipher_suites.go#L44",target:"_blank",rel:"noopener noreferrer"},jn=l("这里"),In=l(" 找到 golang 加密套件的名词和说明"),Cn=c('

    警告

    以上两项配置为非必要选项,正常情况下不影响安全性 在未配置的情况下 golang 根据设备自动选择. 若不熟悉, 请勿配置此选项, 填写不当引起的问题自行负责

    allowInsecure: true | false

    是否允许不安全连接(仅用于客户端)。默认值为 false

    当值为 true 时,Xray 不会检查远端主机所提供的 TLS 证书的有效性。

    警告

    出于安全性考虑,这个选项不应该在实际场景中选择 true,否则可能遭受中间人攻击。

    disableSystemRoot: true | false

    是否禁用操作系统自带的 CA 证书。默认值为 false

    当值为 true 时,Xray 只会使用 certificates 中指定的证书进行 TLS 握手。当值为 false 时,Xray 只会使用操作系统自带的 CA 证书进行 TLS 握手。

    enableSessionResumption: true | false

    此参数的设置为 false 时, ClientHello 里没有 session_ticket 这个扩展。 通常来讲 go 语言程序的 ClientHello 里并没有用到这个扩展, 因此建议保持默认值。 默认值为 false

    fingerprint : string

    此参数用于配置指定 TLS Client Hello 的指纹。当其值为空时,表示不启用此功能。启用后,Xray 将通过 uTLS 库 模拟 TLS 指纹,或随机生成。支持三种配置方式:

    1. 常见浏览器最新版本的 TLS 指纹 包括
    • "chrome"
    • "firefox"
    • "safari"
    • "ios"
    • "android"
    • "edge"
    • "360"
    • "qq"
    1. 在 xray 启动时自动生成一个指纹
    • "random": 在较新版本的浏览器里随机抽取一个
    • "randomized": 完全随机生成一个独一无二的指纹 (100% 支持 TLS 1.3 使用 X25519)
    ',16),Ln={start:"3"},wn=l("使用 uTLS 原生指纹变量名 例如"),On=o("code",null,'"HelloRandomizedNoALPN"',-1),En=l(),Dn=o("code",null,'"HelloChrome_106_Shuffle"',-1),Nn=l("。完整名单见 "),Rn={href:"https://github.com/refraction-networking/utls/blob/master/u_common.go#L434",target:"_blank",rel:"noopener noreferrer"},Fn=l("uTLS 库"),Bn={class:"custom-container tip"},Vn=o("p",{class:"custom-container-title"},"提示",-1),Qn=l("此功能仅 "),Un=o("strong",null,"模拟",-1),Gn=l(),Kn=o("code",null,"TLS Client Hello",-1),Xn=l(" 的指纹,行为、其他指纹与 Golang 相同。如果你希望更加完整地模拟浏览器 "),Yn=o("code",null,"TLS",-1),Mn=l(" 指纹与行为,可以使用 "),_n=l("Browser Dialer"),Wn=l("。"),Hn=c('

    pinnedPeerCertificateChainSha256: [string]

    用于指定远程服务器的证书链 SHA256 散列值,使用标准编码格式。仅有当服务器端证书链散列值符合设置项中之一时才能成功建立 TLS 连接。

    在连接因为此配置失败时,会展示远程服务器证书散列值。

    警告

    不建议使用这种方式获得证书链散列值,因为在这种情况下将没有机会验证此时服务器提供的证书是否为真实证书,进而不保证获得的证书散列值为期望的散列值。

    提示

    如果需要获得证书的散列值,应在命令行中运行 xray tls certChainHash --cert <cert.pem> 来获取,<cert.pem> 应替换为实际证书文件路径。

    certificates: [ CertificateObject ]

    证书列表,其中每一项表示一个证书(建议 fullchain)。

    ',7),Jn={class:"custom-container tip"},zn=o("p",{class:"custom-container-title"},"提示",-1),Zn=l("如果要在 ssllibs 或者 myssl 获得 A/A+ 等级的评价, 请参考 "),$n={href:"https://github.com/XTLS/Xray-core/discussions/56#discussioncomment-215600",target:"_blank",rel:"noopener noreferrer"},ns=l("这里"),ss=l("."),as=c('

    RealityObject

    {\n  "show": false,\n  "dest": "example.com:443",\n  "xver": 0,\n  "serverNames": ["example.com", "www.example.com"],\n  "privateKey": "",\n  "minClientVer": "",\n  "maxClientVer": "",\n  "maxTimeDiff": 0,\n  "shortIds": ["", "0123456789abcdef"],\n  "shortId": "",\n  "fingerprint": "chrome",\n  "serverName": "",\n  "publicKey": "",\n  "shortId": "",\n  "spiderX": ""\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    ',2),os={class:"custom-container tip"},ts=o("p",{class:"custom-container-title"},"提示",-1),es=l("更多信息请参考 "),ps={href:"https://github.com/XTLS/REALITY",target:"_blank",rel:"noopener noreferrer"},cs=l("REALITY 项目"),ls=l("."),us=c('

    show : true | false

    当值为 true 时,输出调试信息。

    提示

    以下为入站服务端)配置。

    dest : string

    ',4),rs=l("必填,格式同 VLESS "),is=o("code",null,"fallbacks",-1),ks=l(" 的 "),bs={href:"https://xtls.github.io/config/features/fallback.html#fallbackobject",target:"_blank",rel:"noopener noreferrer"},ds=l("dest"),qs=l("。"),ms=o("blockquote",null,[o("p",null,[o("code",null,"xver"),l(" : number")])],-1),gs=l("选填,格式同 VLESS "),fs=o("code",null,"fallbacks",-1),ys=l(" 的 "),hs={href:"https://xtls.github.io/config/features/fallback.html#fallbackobject",target:"_blank",rel:"noopener noreferrer"},Ss=l("xver"),xs=c('

    serverNames : [string]

    必填,客户端可用的 serverName 列表,暂不支持 * 通配符。

    privateKey : string

    必填,执行 ./xray x25519 生成。

    minClientVer : string

    选填,客户端 Xray 最低版本,格式为 x.y.z

    maxClientVer : string

    选填,客户端 Xray 最高版本,格式为 x.y.z

    maxTimeDiff : number

    选填,允许的最大时间差,单位为毫秒。

    shortIds : [string]

    必填,客户端可用的 shortId 列表,可用于区分不同的客户端。

    0 到 f,长度为 2 的倍数,长度上限为 16。

    若包含空值,客户端 shortId 可为空。

    提示

    以下为出站客户端)配置。

    serverName : string

    服务端 serverNames 之一。

    fingerprint : string

    ',18),vs=l("必填,同 "),Ts={href:"https://xtls.github.io/config/transport.html#tlsobject",target:"_blank",rel:"noopener noreferrer"},As=l("TLSObject"),Ps=l("。"),js=c('

    shortID : string

    服务端 shortIds 之一。

    0 到 f,长度为 2 的倍数,长度上限为 16。

    若服务端的 shordIDs 包含空值,客户端可为空。

    publicKey : string

    必填,服务端私钥对应的公钥。使用 ./xray x25519 -i "服务器私钥" 生成。

    spiderX : string

    爬虫初始路径与参数,建议每个客户端不同。

    CertificateObject

    {\n  "ocspStapling": 3600,\n  "oneTimeLoading": false,\n  "usage": "encipherment",\n  "certificateFile": "/path/to/certificate.crt",\n  "keyFile": "/path/to/key.key",\n  "certificate": [\n    "--BEGIN CERTIFICATE--",\n    "MIICwDCCAaigAwIBAgIRAO16JMdESAuHidFYJAR/7kAwDQYJKoZIhvcNAQELBQAw",\n    "ADAeFw0xODA0MTAxMzU1MTdaFw0xODA0MTAxNTU1MTdaMAAwggEiMA0GCSqGSIb3",\n    "DQEBAQUAA4IBDwAwggEKAoIBAQCs2PX0fFSCjOemmdm9UbOvcLctF94Ox4BpSfJ+",\n    "3lJHwZbvnOFuo56WhQJWrclKoImp/c9veL1J4Bbtam3sW3APkZVEK9UxRQ57HQuw",\n    "OzhV0FD20/0YELou85TwnkTw5l9GVCXT02NG+pGlYsFrxesUHpojdl8tIcn113M5",\n    "pypgDPVmPeeORRf7nseMC6GhvXYM4txJPyenohwegl8DZ6OE5FkSVR5wFQtAhbON",\n    "OAkIVVmw002K2J6pitPuJGOka9PxcCVWhko/W+JCGapcC7O74palwBUuXE1iH+Jp",\n    "noPjGp4qE2ognW3WH/sgQ+rvo20eXb9Um1steaYY8xlxgBsXAgMBAAGjNTAzMA4G",\n    "A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAA",\n    "MA0GCSqGSIb3DQEBCwUAA4IBAQBUd9sGKYemzwPnxtw/vzkV8Q32NILEMlPVqeJU",\n    "7UxVgIODBV6A1b3tOUoktuhmgSSaQxjhYbFAVTD+LUglMUCxNbj56luBRlLLQWo+",\n    "9BUhC/ow393tLmqKcB59qNcwbZER6XT5POYwcaKM75QVqhCJVHJNb1zSEE7Co7iO",\n    "6wIan3lFyjBfYlBEz5vyRWQNIwKfdh5cK1yAu13xGENwmtlSTHiwbjBLXfk+0A/8",\n    "r/2s+sCYUkGZHhj8xY7bJ1zg0FRalP5LrqY+r6BckT1QPDIQKYy615j1LpOtwZe/",\n    "d4q7MD/dkzRDsch7t2cIjM/PYeMuzh87admSyL6hdtK0Nm/Q",\n    "--END CERTIFICATE--"\n  ],\n  "key": [\n    "--BEGIN RSA PRIVATE KEY--",\n    "MIIEowIBAAKCAQEArNj19HxUgoznppnZvVGzr3C3LRfeDseAaUnyft5SR8GW75zh",\n    "bqOeloUCVq3JSqCJqf3Pb3i9SeAW7Wpt7FtwD5GVRCvVMUUOex0LsDs4VdBQ9tP9",\n    "GBC6LvOU8J5E8OZfRlQl09NjRvqRpWLBa8XrFB6aI3ZfLSHJ9ddzOacqYAz1Zj3n",\n    "jkUX+57HjAuhob12DOLcST8np6IcHoJfA2ejhORZElUecBULQIWzjTgJCFVZsNNN",\n    "itieqYrT7iRjpGvT8XAlVoZKP1viQhmqXAuzu+KWpcAVLlxNYh/iaZ6D4xqeKhNq",\n    "IJ1t1h/7IEPq76NtHl2/VJtbLXmmGPMZcYAbFwIDAQABAoIBAFCgG4phfGIxK9Uw",\n    "qrp+o9xQLYGhQnmOYb27OpwnRCYojSlT+mvLcqwvevnHsr9WxyA+PkZ3AYS2PLue",\n    "C4xW0pzQgdn8wENtPOX8lHkuBocw1rNsCwDwvIguIuliSjI8o3CAy+xVDFgNhWap",\n    "/CMzfQYziB7GlnrM6hH838iiy0dlv4I/HKk+3/YlSYQEvnFokTf7HxbDDmznkJTM",\n    "aPKZ5qbnV+4AcQfcLYJ8QE0ViJ8dVZ7RLwIf7+SG0b0bqloti4+oQXqGtiESUwEW",\n    "/Wzi7oyCbFJoPsFWp1P5+wD7jAGpAd9lPIwPahdr1wl6VwIx9W0XYjoZn71AEaw4",\n    "bK4xUXECgYEA3g2o9WqyrhYSax3pGEdvV2qN0VQhw7Xe+jyy98CELOO2DNbB9QNJ",\n    "8cSSU/PjkxQlgbOJc8DEprdMldN5xI/srlsbQWCj72wXxXnVnh991bI2clwt7oYi",\n    "pcGZwzCrJyFL+QaZmYzLxkxYl1tCiiuqLm+EkjxCWKTX/kKEFb6rtnMCgYEAx0WR",\n    "L8Uue3lXxhXRdBS5QRTBNklkSxtU+2yyXRpvFa7Qam+GghJs5RKfJ9lTvjfM/PxG",\n    "3vhuBliWQOKQbm1ZGLbgGBM505EOP7DikUmH/kzKxIeRo4l64mioKdDwK/4CZtS7",\n    "az0Lq3eS6bq11qL4mEdE6Gn/Y+sqB83GHZYju80CgYABFm4KbbBcW+1RKv9WSBtK",\n    "gVIagV/89moWLa/uuLmtApyEqZSfn5mAHqdc0+f8c2/Pl9KHh50u99zfKv8AsHfH",\n    "TtjuVAvZg10GcZdTQ/I41ruficYL0gpfZ3haVWWxNl+J47di4iapXPxeGWtVA+u8",\n    "eH1cvgDRMFWCgE7nUFzE8wKBgGndUomfZtdgGrp4ouLZk6W4ogD2MpsYNSixkXyW",\n    "64cIbV7uSvZVVZbJMtaXxb6bpIKOgBQ6xTEH5SMpenPAEgJoPVts816rhHdfwK5Q",\n    "8zetklegckYAZtFbqmM0xjOI6bu5rqwFLWr1xo33jF0wDYPQ8RHMJkruB1FIB8V2",\n    "GxvNAoGBAM4g2z8NTPMqX+8IBGkGgqmcYuRQxd3cs7LOSEjF9hPy1it2ZFe/yUKq",\n    "ePa2E8osffK5LBkFzhyQb0WrGC9ijM9E6rv10gyuNjlwXdFJcdqVamxwPUBtxRJR",\n    "cYTY2HRkJXDdtT0Bkc3josE6UUDvwMpO0CfAETQPto1tjNEDhQhT",\n    "--END RSA PRIVATE KEY--"\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55

    ocspStapling: number

    OCSP 装订更新,与证书热重载的时间间隔。 单位:秒。默认值为 3600,即一小时。

    oneTimeLoading: true | false

    仅加载一次。值为 true 时将关闭证书热重载功能与 ocspStapling 功能。

    注意

    当值为 true 时,将会关闭 OCSP 装订。

    usage: "encipherment" | "verify" | "issue"

    证书用途,默认值为 "encipherment"

    • "encipherment":证书用于 TLS 认证和加密。
    • "verify":证书用于验证远端 TLS 的证书。当使用此项时,当前证书必须为 CA 证书。
    • "issue":证书用于签发其它证书。当使用此项时,当前证书必须为 CA 证书。

    TIP 1

    在 Windows 平台上可以将自签名的 CA 证书安装到系统中,即可验证远端 TLS 的证书。

    TIP 2

    当有新的客户端请求时,假设所指定的 serverName"xray.com",Xray 会先从证书列表中寻找可用于 "xray.com" 的证书,如果没有找到,则使用任一 usage"issue" 的证书签发一个适用于 "xray.com" 的证书,有效期为一小时。并将新的证书加入证书列表,以供后续使用。

    TIP 3

    certificateFilecertificate 同时指定时,Xray 优先使用 certificateFilekeyFilekey 也一样。

    TIP 4

    usage"verify" 时,keyFilekey 可均为空。

    TIP 5

    使用 xray tls cert 可以生成自签名的 CA 证书。

    ',23),Is={class:"custom-container tip"},Cs=o("p",{class:"custom-container-title"},"TIP 6",-1),Ls=l("如已经拥有一个域名, 可以使用工具便捷的获取免费第三方证书,如"),ws={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},Os=l("acme.sh"),Es=c('

    certificateFile: string

    证书文件路径,如使用 OpenSSL 生成,后缀名为 .crt。

    certificate: [ string ]

    一个字符串数组,表示证书内容,格式如样例所示。certificatecertificateFile 二者选一。

    keyFile: string

    密钥文件路径,如使用 OpenSSL 生成,后缀名为 .key。目前暂不支持需要密码的 key 文件。

    key: [ string ]

    一个字符串数组,表示密钥内容,格式如样例如示。keykeyFile 二者选一。

    SockoptObject

    {\n  "mark": 0,\n  "tcpMaxSeg": 1440,\n  "tcpFastOpen": false,\n  "tproxy": "off",\n  "domainStrategy": "AsIs",\n  "dialerProxy": "",\n  "acceptProxyProtocol": false,\n  "tcpKeepAliveInterval": 0,\n  "tcpKeepAliveIdle": 300,\n  "tcpUserTimeout": 10000,\n  "tcpcongestion": "bbr",\n  "interface": "wg0"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    mark: number

    一个整数。当其值非零时,在 outbound 连接上以此数值标记 SO_MARK。

    • 仅适用于 Linux 系统。
    • 需要 CAP_NET_ADMIN 权限。

    tcpMaxSeg: number

    用于设置 TCP 数据包的最大传输单元。

    tcpFastOpen: true | false | number

    ',16),Ds=l("是否启用 "),Ns={href:"https://zh.wikipedia.org/wiki/TCP%E5%BF%AB%E9%80%9F%E6%89%93%E5%BC%80",target:"_blank",rel:"noopener noreferrer"},Rs=l("TCP Fast Open"),Fs=l("。"),Bs=o("p",null,[l("当其值为 "),o("code",null,"true"),l(" 或"),o("code",null,"正整数"),l("时,启用 TFO;当其值为 "),o("code",null,"false"),l(" 或"),o("code",null,"负数"),l("时,强制关闭 TFO;当此项不存在或为 "),o("code",null,"0"),l(" 时,使用系统默认设置。 可用于 inbound/outbound。")],-1),Vs=c("
  • 仅在以下版本(或更新版本)的操作系统中可用:

    • 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
  • ",1),Qs=l("对于 Inbound,此处所设定的"),Us=o("code",null,"正整数",-1),Gs=l("代表 "),Ks={href:"https://tools.ietf.org/html/rfc7413#section-5.1",target:"_blank",rel:"noopener noreferrer"},Xs=l("待处理的 TFO 连接请求数上限"),Ys=l(" ,"),Ms=o("strong",null,"注意并非所有操作系统都支持在此设定",-1),_s=l(":"),Ws=c("
    • Linux / FreeBSD:此处的设定的正整数值代表上限,可接受的最大值为 2147483647,为 true 时将取 256;注意在 Linux,net.core.somaxconn 会限制此值的上限,如果超过了 somaxconn,请同时提高 somaxconn
    • Mac OS:此处为 true正整数时,仅代表启用 TFO,上限需要通过内核参数 net.inet.tcp.fastopen_backlog 单独设定。
    • Windows:此处为 true正整数时,仅代表启用 TFO。
    ",1),Hs=o("li",null,[o("p",null,[l("对于 Outbound,设定为 "),o("code",null,"true"),l(" 或"),o("code",null,"正整数"),l("在任何操作系统都仅表示启用 TFO。")])],-1),Js=c("

    tproxy: "redirect" | "tproxy" | "off"

    是否开启透明代理(仅适用于 Linux)。

    • "redirect":使用 Redirect 模式的透明代理。支持所有基于 IPv4/6 的 TCP 和 UDP 连接。
    • "tproxy":使用 TProxy 模式的透明代理。支持所有基于 IPv4/6 的 TCP 和 UDP 连接。
    • "off":关闭透明代理。

    透明代理需要 Root 或 CAP\\_NET\\_ADMIN 权限。

    ",4),zs={class:"custom-container danger"},Zs=o("p",{class:"custom-container-title"},"警告",-1),$s=l("当 "),na=l("Dokodemo-door"),sa=l(" 中指定了 "),aa=o("code",null,"followRedirect",-1),oa=l("为"),ta=o("code",null,"true",-1),ea=l(",且 Sockopt 设置中的"),pa=o("code",null,"tproxy",-1),ca=l(" 为空时,Sockopt 设置中的"),la=o("code",null,"tproxy",-1),ua=l(" 的值会被设为 "),ra=o("code",null,'"redirect"',-1),ia=l("。"),ka=o("blockquote",null,[o("p",null,[o("code",null,"domainStrategy"),l(': "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"')])],-1),ba=l("在之前的版本中,当 Xray 尝试使用域名建立系统连接时,域名的解析由系统完成,不受 Xray 控制。这导致了在 "),da={href:"https://github.com/v2ray/v2ray-core/issues/1909",target:"_blank",rel:"noopener noreferrer"},qa=l("非标准 Linux 环境中无法解析域名"),ma=l(" 等问题。为此,Xray 1.3.1 为 Sockopt 引入了 Freedom 中的 domainStrategy,解决了此问题。"),ga=o("p",null,"在目标地址为域名时, 配置相应的值, SystemDialer 的行为模式如下:",-1),fa=o("li",null,[o("code",null,'"AsIs"'),l(": 通过系统 DNS 服务器解析获取 IP, 向此域名发出连接。")],-1),ya=o("code",null,'"UseIP"',-1),ha=l("、"),Sa=o("code",null,'"UseIPv4"',-1),xa=l(" 和 "),va=o("code",null,'"UseIPv6"',-1),Ta=l(": 使用"),Aa=l("内置 DNS 服务器"),Pa=l("解析获取 IP 后, 直接向此 IP 发出连接。"),ja=c('

    默认值为 "AsIs"

    警告

    启用了此功能后,不当的配置可能会导致死循环。

    一句话版本:连接到服务器,需要等待 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。

    ',7),Ia={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},Ca=l("PROXY protocol"),La=l(" 专用于传递请求的真实来源 IP 和端口,"),wa=o("strong",null,"若你不了解它,请先忽略该项",-1),Oa=l("。"),Ea=c('

    常见的反代软件(如 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

    tcpcongestion: ""

    TCP 拥塞控制算法。仅支持 Linux。 不配置此项表示使用系统默认值。

    常见的算法

    • bbr(推荐)
    • cubic
    • reno

    提示

    执行命令 sysctl net.ipv4.tcp_congestion_control 获取系统默认值。

    interface: ""

    指定绑定出口网卡名称 仅支持 linux。

    ',19);u.render=function(c,l){const u=n("RouterLink"),Da=n("OutboundLink");return s(),a(p,null,[r,o("blockquote",null,[o("p",null,[i,k,t(u,{to:"/config/transports/tcp.html"},{default:e((()=>[b])),_:1})])]),d,o("blockquote",null,[o("p",null,[q,m,t(u,{to:"/config/transports/mkcp.html"},{default:e((()=>[g])),_:1})])]),f,o("blockquote",null,[o("p",null,[y,h,t(u,{to:"/config/transports/websocket.html"},{default:e((()=>[S])),_:1})])]),x,o("blockquote",null,[o("p",null,[v,T,t(u,{to:"/config/transports/h2.html"},{default:e((()=>[A])),_:1})])]),P,o("blockquote",null,[o("p",null,[j,I,t(u,{to:"/config/transports/quic.html"},{default:e((()=>[C])),_:1})])]),L,o("blockquote",null,[o("p",null,[w,O,t(u,{to:"/config/transports/grpc.html"},{default:e((()=>[E])),_:1})])]),D,o("blockquote",null,[o("p",null,[N,R,t(u,{to:"/config/transports/domainsocket.html"},{default:e((()=>[F])),_:1})])]),B,o("ul",null,[V,o("li",null,[Q,U,o("a",G,[K,t(Da)]),X]),Y]),M,o("blockquote",null,[o("p",null,[_,W,t(u,{to:"/config/transports/tcp.html"},{default:e((()=>[H])),_:1})])]),J,o("blockquote",null,[o("p",null,[z,Z,t(u,{to:"/config/transports/mkcp.html"},{default:e((()=>[$])),_:1})])]),nn,o("blockquote",null,[o("p",null,[sn,an,t(u,{to:"/config/transports/websocket.html"},{default:e((()=>[on])),_:1})])]),tn,o("blockquote",null,[o("p",null,[en,pn,t(u,{to:"/config/transports/h2.html"},{default:e((()=>[cn])),_:1})])]),ln,o("blockquote",null,[o("p",null,[un,rn,t(u,{to:"/config/transports/quic.html"},{default:e((()=>[kn])),_:1})])]),bn,o("blockquote",null,[o("p",null,[dn,qn,t(u,{to:"/config/transports/grpc.html"},{default:e((()=>[mn])),_:1})])]),gn,o("blockquote",null,[o("p",null,[fn,yn,t(u,{to:"/config/transports/domainsocket.html"},{default:e((()=>[hn])),_:1})])]),Sn,o("p",null,[xn,o("a",vn,[Tn,t(Da)]),An,o("a",Pn,[jn,t(Da)]),In]),Cn,o("ol",Ln,[o("li",null,[wn,On,En,Dn,Nn,o("a",Rn,[Fn,t(Da)])])]),o("div",Bn,[Vn,o("p",null,[Qn,Un,Gn,Kn,Xn,Yn,Mn,t(u,{to:"/config/transports/websocket.html#browser-dialer"},{default:e((()=>[_n])),_:1}),Wn])]),Hn,o("div",Jn,[zn,o("p",null,[Zn,o("a",$n,[ns,t(Da)]),ss])]),as,o("div",os,[ts,o("p",null,[es,o("a",ps,[cs,t(Da)]),ls])]),us,o("p",null,[rs,is,ks,o("a",bs,[ds,t(Da)]),qs]),ms,o("p",null,[gs,fs,ys,o("a",hs,[Ss,t(Da)])]),xs,o("p",null,[vs,o("a",Ts,[As,t(Da)]),Ps]),js,o("div",Is,[Cs,o("p",null,[Ls,o("a",ws,[Os,t(Da)])])]),Es,o("p",null,[Ds,o("a",Ns,[Rs,t(Da)]),Fs]),Bs,o("ul",null,[Vs,o("li",null,[o("p",null,[Qs,Us,Gs,o("a",Ks,[Xs,t(Da)]),Ys,Ms,_s]),Ws]),Hs]),Js,o("div",zs,[Zs,o("p",null,[$s,t(u,{to:"/config/inbounds/dokodemo.html"},{default:e((()=>[na])),_:1}),sa,aa,oa,ta,ea,pa,ca,la,ua,ra,ia])]),ka,o("p",null,[ba,o("a",da,[qa,t(Da)]),ma]),ga,o("ul",null,[fa,o("li",null,[ya,ha,Sa,xa,va,Ta,t(u,{to:"/config/dns.html"},{default:e((()=>[Aa])),_:1}),Pa])]),ja,o("p",null,[o("a",Ia,[Ca,t(Da)]),La,wa,Oa]),Ea],64)};export default u; diff --git a/assets/transport.html.83a58fcb.js b/assets/transport.html.cd444c5b.js similarity index 99% rename from assets/transport.html.83a58fcb.js rename to assets/transport.html.cd444c5b.js index f536ff5c8..fce59275b 100644 --- a/assets/transport.html.83a58fcb.js +++ b/assets/transport.html.cd444c5b.js @@ -1 +1 @@ -import{r as n,o as e,c as s,a as t,b as o,w as a,F as p,d as c,e as i}from"./app.755d843f.js";const l={},r=c('

    Transport Protocol

    Transport protocol is the way that Xray nodes communicate with each other.

    Transport protocol specifies a stable way to transmit data. Typically, both ends of a network connection need to use the same transport protocol to establish a connection. For example, if one end uses WebSocket, the other end must also use WebSocket, otherwise the connection cannot be established.

    Transport protocol configuration has two parts:

    1. Global configuration (TransportObject)
    2. Local configuration (StreamSettingsObject).
    • When configuring locally, you can specify how each individual inbound or outbound connection is transmitted.
    • Typically, the inbound and outbound connections corresponding to the client and server need to use the same transport protocol. When a transport protocol is specified but no specific settings are provided, the transport protocol will use the settings from the global configuration.

    TransportObject

    The TransportObject corresponds to the transport item in the configuration file.

    {\n  "transport": {\n    "tcpSettings": {},\n    "kcpSettings": {},\n    "wsSettings": {},\n    "httpSettings": {},\n    "quicSettings": {},\n    "dsSettings": {},\n    "grpcSettings": {}\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ',9),u=t("code",null,"tcpSettings",-1),d=i(": "),b=i("TcpObject"),h=t("p",null,"Configuration for TCP connections.",-1),k=t("code",null,"kcpSettings",-1),m=i(": "),g=i("KcpObject"),f=t("p",null,"Configuration for mKCP connections.",-1),q=t("code",null,"wsSettings",-1),y=i(": "),v=i("WebSocketObject"),S=t("p",null,"Configuration for WebSocket connections.",-1),w=t("code",null,"httpSettings",-1),T=i(": "),x=i("HttpObject"),A=t("p",null,"Configuration for HTTP/2 connections.",-1),P=t("code",null,"quicSettings",-1),I=i(": "),L=i("QuicObject"),C=t("p",null,"Configuration for QUIC connections.",-1),j=t("code",null,"grpcSettings",-1),O=i(": "),W=i("GRPCObject"),D=t("p",null,"Configuration for gRPC connections.",-1),E=t("code",null,"dsSettings",-1),F=i(": "),N=i("DomainSocketObject"),B=c('

    Configuration for Domain Socket connections.

    StreamSettingsObject

    StreamSettingsObject corresponds to the streamSettings item in inbound or outbound configuration. Each inbound or outbound can be configured with different transport settings and can use streamSettings to perform some transport configurations.

    {\n  "network": "tcp",\n  "security": "none",\n  "tlsSettings": {},\n  "tcpSettings": {},\n  "kcpSettings": {},\n  "wsSettings": {},\n  "httpSettings": {},\n  "quicSettings": {},\n  "dsSettings": {},\n  "grpcSettings": {},\n  "sockopt": {\n    "mark": 0,\n    "tcpFastOpen": false,\n    "tproxy": "off",\n    "domainStrategy": "AsIs",\n    "dialerProxy": "",\n    "acceptProxyProtocol": false,\n    "tcpKeepAliveInterval": 0\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    network: "tcp" | "kcp" | "ws" | "http" | "domainsocket" | "quic" | "grpc"

    The type of transport used by the connection's data stream, with a default value of "tcp".

    security: "none" | "tls" | "xtls"

    Whether to enable transport layer encryption, with supported options:

    ',8),R=t("li",null,[t("code",null,'"none"'),i(" means no encryption (default value).")],-1),G=t("code",null,'"tls"',-1),U=i(" means using "),Q={href:"https://en.wikipedia.org/wiki/base/transport_Layer_Security",target:"_blank",rel:"noopener noreferrer"},X=i("TLS"),V=i("."),Y=t("code",null,'"xtls"',-1),K=i(" means using "),M=i("XTLS"),H=i(". "),_=t("blockquote",null,[t("p",null,[t("code",null,"tlsSettings"),i(": "),t("a",{href:"#tlsobject"},"TLSObject")])],-1),J=t("p",null,"TLS configuration. TLS is provided by Golang, and usually the result of TLS negotiation is to use TLS 1.3, and DTLS is not supported.",-1),Z=t("code",null,"xtlsSettings",-1),z=i(": "),$=t("a",{href:"#tlsobject"},"XTLSObject",-1),nn=i(),en=c('

    XTLS configuration. XTLS is Xray's original technology, which is the core driver of Xray's outstanding performance. XTLS has the same security as TLS and uses the same configuration as TLS.

    Tip

    TLS/XTLS is currently the most secure transport encryption scheme, and its traffic appears consistent with normal web traffic to outsiders. Enabling XTLS and configuring the appropriate XTLS flow control mode can provide several times to even more than ten times the performance improvement while maintaining the same security as TLS. When changing the value of security from tls to xtls, simply modify tlsSettings to xtlsSettings.

    ',2),sn=t("code",null,"tcpSettings",-1),tn=i(": "),on=i("TcpObject"),an=t("p",null,"The TCP configuration for the current connection, only valid when TCP is used for this connection. The configuration is the same as the global configuration above.",-1),pn=t("code",null,"kcpSettings",-1),cn=i(": "),ln=i("KcpObject"),rn=t("p",null,"The mKCP configuration for the current connection, only valid when mKCP is used for this connection. The configuration is the same as the global configuration above.",-1),un=t("code",null,"wsSettings",-1),dn=i(": "),bn=i("WebSocketObject"),hn=t("p",null,"The WebSocket configuration for the current connection, only valid when WebSocket is used for this connection. The configuration is the same as the global configuration above.",-1),kn=t("code",null,"httpSettings",-1),mn=i(": "),gn=i("HttpObject"),fn=t("p",null,"The HTTP/2 configuration for the current connection, only valid when HTTP/2 is used for this connection. The configuration is the same as the global configuration above.",-1),qn=t("code",null,"quicSettings",-1),yn=i(": "),vn=i("QUICObject"),Sn=t("p",null,"The QUIC configuration for the current connection, only valid when QUIC is used for this connection. The configuration is the same as the global configuration above.",-1),wn=t("code",null,"grpcSettings",-1),Tn=i(": "),xn=i("GRPCObject"),An=t("p",null,"The gRPC configuration for the current connection, only valid when gRPC is used for this connection. The configuration is the same as the global configuration above.",-1),Pn=t("code",null,"dsSettings",-1),In=i(": "),Ln=i("DomainSocketObject"),Cn=c('

    The Domain socket configuration for the current connection, only valid when Domain socket is used for this connection. The configuration is the same as the global configuration above.

    sockopt: SockoptObject

    Specific configuration for transparent proxying.

    TLSObject

    {\n  "serverName": "xray.com",\n  "rejectUnknownSni": false,\n  "allowInsecure": false,\n  "alpn": ["h2", "http/1.1"],\n  "minVersion": "1.2",\n  "maxVersion": "1.3",\n  "cipherSuites": "Specify the names of the encryption suites you need here, separated by :",\n  "certificates": [],\n  "disableSystemRoot": false,\n  "enableSessionResumption": false,\n  "fingerprint": "",\n  "pinnedPeerCertificateChainSha256": [""]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    serverName: string

    Specifies the domain name of the server certificate, useful when the connection is established by IP.

    When the target connection is specified by domain name, such as when the domain name is received by the Socks inbound or when it is detected by the Sniffing function, this domain name is automatically used for serverName without manual configuration.

    rejectUnknownSni: bool

    When set to true, the server rejects the TLS handshake if the received SNI does not match the domain name in the certificate. The default value is false.

    alpn: [ string ]

    An array of strings that specifies the ALPN values to be used during the TLS handshake. The default value is ["h2", "http/1.1"].

    minVersion: [ string ]

    minVersion is the minimum acceptable SSL/TLS version.

    maxVersion: [ string ]

    maxVersion is the maximum acceptable SSL/TLS version.

    cipherSuites: [ string ]

    CipherSuites is used to configure the supported list of cryptographic suites, with each suite name separated by a colon.

    ',18),jn=i("You can find the names and descriptions of Golang encryption suites at "),On={href:"https://golang.org/src/crypto/tls/cipher_suites.go#L500",target:"_blank",rel:"noopener noreferrer"},Wn=i("here"),Dn=i(" or "),En={href:"https://golang.org/src/crypto/tls/cipher_suites.go#L44",target:"_blank",rel:"noopener noreferrer"},Fn=i("here"),Nn=i("."),Bn=c('

    Danger

    The above two configurations are optional and normally do not affect security. If not configured, Golang will automatically select based on the device. If you are not familiar with these options, do not configure them, and any problems caused by improper configuration are your responsibility.

    allowInsecure: true | false

    Whether to allow insecure connections (only for clients). The default value is false.

    When set to true, Xray will not verify the validity of the TLS certificate provided by the remote host.

    Danger

    For security reasons, this option should not be set to true in practical scenarios, otherwise, it may be susceptible to man-in-the-middle attacks.

    disableSystemRoot: true | false

    Whether to disable the CA certificate provided by the operating system. The default value is false.

    When set to true, Xray will only use the certificates specified in certificates for TLS handshakes. When set to false, Xray will only use the CA certificates provided by the operating system for TLS handshakes.

    enableSessionResumption: true | false

    When this parameter is set to false, the session_ticket extension is not included in the ClientHello message. Generally, the ClientHello message in Go language programs does not use this extension, so it is recommended to keep the default value. The default value is false.

    fingerprint: string

    This parameter is used to configure the fingerprint of the TLS Client Hello. When its value is empty, this feature is not enabled. After enabling it, Xray will simulate the TLS fingerprint through the uTLS library or generate it randomly. Three configuration options are supported:

    1. TLS fingerprints of the latest versions of popular browsers, including:
    • "chrome"
    • "firefox"
    • "safari"
    • "ios"
    • "android"
    • "edge"
    • "360"
    • "qq"
    1. Generate a fingerprint when xray starts
    • "random": randomly select one in newer versions of browsers
    • "randomized": generate a completely random and unique fingerprint (100% compatible with TLS 1.3 using X25519)
    ',16),Rn=i("Use uTLS native fingerprint variable names, such as "),Gn=t("code",null,'"HelloRandomizedNoALPN"',-1),Un=i(),Qn=t("code",null,'"HelloChrome_106_Shuffle"',-1),Xn=i(". See the full list in "),Vn={href:"https://github.com/refraction-networking/utls/blob/master/u_common.go#L162",target:"_blank",rel:"noopener noreferrer"},Yn=i("uTLS library"),Kn=i("."),Mn={class:"custom-container tip"},Hn=t("p",{class:"custom-container-title"},"Tip",-1),_n=i("This feature only "),Jn=t("strong",null,"simulates",-1),Zn=i(" the fingerprint of the "),zn=t("code",null,"TLS Client Hello",-1),$n=i(", and its behavior and other fingerprints are the same as Golang. If you want to simulate browser "),ne=t("code",null,"TLS",-1),ee=i(" fingerprints and behaviors more completely, you can use the "),se=i("Browser Dialer"),te=i("."),oe=c('

    pinnedPeerCertificateChainSha256: [string]

    Specifies the SHA256 hash value of the certificate chain for the remote server, using standard encoding format. Only when the hash value of the server-side certificate chain matches one of the settings can a TLS connection be successfully established.

    When the connection fails due to this configuration, the hash value of the remote server certificate will be displayed.

    Danger

    It is not recommended to use this method to obtain the hash value of the certificate chain, because in this case, there will be no opportunity to verify whether the certificate provided by the server at this time is a real certificate, and it cannot be guaranteed that the obtained certificate hash value is the expected hash value.

    Tip

    If you need to obtain the hash value of the certificate, run xray tls certChainHash --cert <cert.pem> in the command line, where <cert.pem> should be replaced with the actual certificate file path.

    certificates: [ CertificateObject ]

    A list of certificates, each representing a certificate (recommended fullchain).

    ',7),ae={class:"custom-container tip"},pe=t("p",{class:"custom-container-title"},"Tip",-1),ce=i("If you want to obtain the A/A+ rating in ssllibs or myssl evaluation, please refer to "),ie={href:"https://github.com/XTLS/Xray-core/discussions/56#discussioncomment-215600",target:"_blank",rel:"noopener noreferrer"},le=i("here"),re=i("."),ue=c('

    CertificateObject

    {\n  "ocspStapling": 3600,\n  "oneTimeLoading": false,\n  "usage": "encipherment",\n  "certificateFile": "/path/to/certificate.crt",\n  "keyFile": "/path/to/key.key",\n  "certificate": [\n    "--BEGIN CERTIFICATE--",\n    "MIICwDCCAaigAwIBAgIRAO16JMdESAuHidFYJAR/7kAwDQYJKoZIhvcNAQELBQAw",\n    "ADAeFw0xODA0MTAxMzU1MTdaFw0xODA0MTAxNTU1MTdaMAAwggEiMA0GCSqGSIb3",\n    "DQEBAQUAA4IBDwAwggEKAoIBAQCs2PX0fFSCjOemmdm9UbOvcLctF94Ox4BpSfJ+",\n    "3lJHwZbvnOFuo56WhQJWrclKoImp/c9veL1J4Bbtam3sW3APkZVEK9UxRQ57HQuw",\n    "OzhV0FD20/0YELou85TwnkTw5l9GVCXT02NG+pGlYsFrxesUHpojdl8tIcn113M5",\n    "pypgDPVmPeeORRf7nseMC6GhvXYM4txJPyenohwegl8DZ6OE5FkSVR5wFQtAhbON",\n    "OAkIVVmw002K2J6pitPuJGOka9PxcCVWhko/W+JCGapcC7O74palwBUuXE1iH+Jp",\n    "noPjGp4qE2ognW3WH/sgQ+rvo20eXb9Um1steaYY8xlxgBsXAgMBAAGjNTAzMA4G",\n    "A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAA",\n    "MA0GCSqGSIb3DQEBCwUAA4IBAQBUd9sGKYemzwPnxtw/vzkV8Q32NILEMlPVqeJU",\n    "7UxVgIODBV6A1b3tOUoktuhmgSSaQxjhYbFAVTD+LUglMUCxNbj56luBRlLLQWo+",\n    "9BUhC/ow393tLmqKcB59qNcwbZER6XT5POYwcaKM75QVqhCJVHJNb1zSEE7Co7iO",\n    "6wIan3lFyjBfYlBEz5vyRWQNIwKfdh5cK1yAu13xGENwmtlSTHiwbjBLXfk+0A/8",\n    "r/2s+sCYUkGZHhj8xY7bJ1zg0FRalP5LrqY+r6BckT1QPDIQKYy615j1LpOtwZe/",\n    "d4q7MD/dkzRDsch7t2cIjM/PYeMuzh87admSyL6hdtK0Nm/Q",\n    "--END CERTIFICATE--"\n  ],\n  "key": [\n    "--BEGIN RSA PRIVATE KEY--",\n    "MIIEowIBAAKCAQEArNj19HxUgoznppnZvVGzr3C3LRfeDseAaUnyft5SR8GW75zh",\n    "bqOeloUCVq3JSqCJqf3Pb3i9SeAW7Wpt7FtwD5GVRCvVMUUOex0LsDs4VdBQ9tP9",\n    "GBC6LvOU8J5E8OZfRlQl09NjRvqRpWLBa8XrFB6aI3ZfLSHJ9ddzOacqYAz1Zj3n",\n    "jkUX+57HjAuhob12DOLcST8np6IcHoJfA2ejhORZElUecBULQIWzjTgJCFVZsNNN",\n    "itieqYrT7iRjpGvT8XAlVoZKP1viQhmqXAuzu+KWpcAVLlxNYh/iaZ6D4xqeKhNq",\n    "IJ1t1h/7IEPq76NtHl2/VJtbLXmmGPMZcYAbFwIDAQABAoIBAFCgG4phfGIxK9Uw",\n    "qrp+o9xQLYGhQnmOYb27OpwnRCYojSlT+mvLcqwvevnHsr9WxyA+PkZ3AYS2PLue",\n    "C4xW0pzQgdn8wENtPOX8lHkuBocw1rNsCwDwvIguIuliSjI8o3CAy+xVDFgNhWap",\n    "/CMzfQYziB7GlnrM6hH838iiy0dlv4I/HKk+3/YlSYQEvnFokTf7HxbDDmznkJTM",\n    "aPKZ5qbnV+4AcQfcLYJ8QE0ViJ8dVZ7RLwIf7+SG0b0bqloti4+oQXqGtiESUwEW",\n    "/Wzi7oyCbFJoPsFWp1P5+wD7jAGpAd9lPIwPahdr1wl6VwIx9W0XYjoZn71AEaw4",\n    "bK4xUXECgYEA3g2o9WqyrhYSax3pGEdvV2qN0VQhw7Xe+jyy98CELOO2DNbB9QNJ",\n    "8cSSU/PjkxQlgbOJc8DEprdMldN5xI/srlsbQWCj72wXxXnVnh991bI2clwt7oYi",\n    "pcGZwzCrJyFL+QaZmYzLxkxYl1tCiiuqLm+EkjxCWKTX/kKEFb6rtnMCgYEAx0WR",\n    "L8Uue3lXxhXRdBS5QRTBNklkSxtU+2yyXRpvFa7Qam+GghJs5RKfJ9lTvjfM/PxG",\n    "3vhuBliWQOKQbm1ZGLbgGBM505EOP7DikUmH/kzKxIeRo4l64mioKdDwK/4CZtS7",\n    "az0Lq3eS6bq11qL4mEdE6Gn/Y+sqB83GHZYju80CgYABFm4KbbBcW+1RKv9WSBtK",\n    "gVIagV/89moWLa/uuLmtApyEqZSfn5mAHqdc0+f8c2/Pl9KHh50u99zfKv8AsHfH",\n    "TtjuVAvZg10GcZdTQ/I41ruficYL0gpfZ3haVWWxNl+J47di4iapXPxeGWtVA+u8",\n    "eH1cvgDRMFWCgE7nUFzE8wKBgGndUomfZtdgGrp4ouLZk6W4ogD2MpsYNSixkXyW",\n    "64cIbV7uSvZVVZbJMtaXxb6bpIKOgBQ6xTEH5SMpenPAEgJoPVts816rhHdfwK5Q",\n    "8zetklegckYAZtFbqmM0xjOI6bu5rqwFLWr1xo33jF0wDYPQ8RHMJkruB1FIB8V2",\n    "GxvNAoGBAM4g2z8NTPMqX+8IBGkGgqmcYuRQxd3cs7LOSEjF9hPy1it2ZFe/yUKq",\n    "ePa2E8osffK5LBkFzhyQb0WrGC9ijM9E6rv10gyuNjlwXdFJcdqVamxwPUBtxRJR",\n    "cYTY2HRkJXDdtT0Bkc3josE6UUDvwMpO0CfAETQPto1tjNEDhQhT",\n    "--END RSA PRIVATE KEY--"\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55

    ocspStapling: number

    OCSP stapling update interval in seconds for certificate hot reload. Default value is 3600, i.e. one hour.

    oneTimeLoading: true | false

    Load only once. When set to true, it will disable certificate hot reload and OCSP stapling feature.

    Warning

    When set to true, OCSP stapling will be disabled.

    usage: "encipherment" | "verify" | "issue"

    Certificate usage, default value is "encipherment".

    • "encipherment": The certificate is used for TLS authentication and encryption.
    • "verify": The certificate is used to verify the remote TLS certificate. When using this option, the current certificate must be a CA certificate.
    • "issue": The certificate is used to issue other certificates. When using this option, the current certificate must be a CA certificate.

    TIP 1

    On Windows platform, self-signed CA certificate can be installed in the system for verifying remote TLS certificates.

    TIP 2

    When a new client request comes in, assuming the specified serverName is "xray.com", Xray will first look for a certificate that can be used for "xray.com" in the certificate list. If not found, it will issue a certificate for "xray.com" using any certificate with usage set to "issue", with a validity of one hour. The new certificate is then added to the certificate list for later use.

    TIP 3

    When both certificateFile and certificate are specified, Xray will use certificateFile as the priority. The same applies to keyFile and key.

    TIP 4

    When usage is set to "verify", keyFile and key can both be empty.

    TIP 5

    Use xray tls cert to generate self-signed CA certificate.

    ',15),de={class:"custom-container tip"},be=t("p",{class:"custom-container-title"},"TIP 6",-1),he=i("If you already have a domain name, you can use tools to obtain free third-party certificates easily, such as "),ke={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},me=i("acme.sh"),ge=i("."),fe=c('

    certificateFile: string

    Path to the certificate file generated by OpenSSL, with the suffix .crt.

    certificate: [ string ]

    A string array representing the certificate content, in the format shown in the example. Either certificate or certificateFile can be used.

    keyFile: string

    Path to the key file generated by OpenSSL, with the suffix .key. Password-protected key files are not currently supported.

    key: [ string ]

    A string array representing the key content, in the format shown in the example. Either key or keyFile can be used.

    SockoptObject

    {\n  "mark": 0,\n  "tcpFastOpen": false,\n  "tproxy": "off",\n  "domainStrategy": "AsIs",\n  "dialerProxy": "",\n  "acceptProxyProtocol": false,\n  "tcpKeepAliveInterval": 0,\n  "tcpcongestion": "bbr",\n  "interface": "wg0"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    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

    ',14),qe=i("Specifies whether "),ye={href:"https://en.wikipedia.org/wiki/TCP_Fast_Open",target:"_blank",rel:"noopener noreferrer"},ve=i("TCP Fast Open"),Se=i(" is enabled."),we=c("

    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.

    ",6),Te={class:"custom-container danger"},xe=t("p",{class:"custom-container-title"},"Danger",-1),Ae=i("When "),Pe=t("code",null,"followRedirect",-1),Ie=i(" is set to "),Le=t("code",null,"true",-1),Ce=i(" in "),je=i("Dokodemo-door"),Oe=i(", and "),We=t("code",null,"tproxy",-1),De=i(" in the Sockopt settings is empty, the value of "),Ee=t("code",null,"tproxy",-1),Fe=i(" in the Sockopt settings will be set to "),Ne=t("code",null,'"redirect"',-1),Be=i("."),Re=t("blockquote",null,[t("p",null,[t("code",null,"domainStrategy"),i(': "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"')])],-1),Ge=t("p",null,[i("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 "),t("code",null,"domainStrategy"),i(" into Sockopt.")],-1),Ue=t("p",null,"When the target address is a domain name, the corresponding value is configured, and the behavior of SystemDialer is as follows:",-1),Qe=t("li",null,[t("code",null,'"AsIs"'),i(": Resolve the IP address using the system DNS server and connect to the domain name.")],-1),Xe=t("code",null,'"UseIP"',-1),Ve=i(", "),Ye=t("code",null,'"UseIPv4"',-1),Ke=i(", and "),Me=t("code",null,'"UseIPv6"',-1),He=i(": Resolve the IP address using the "),_e=i("built-in DNS server"),Je=i(" and connect to the IP address directly."),Ze=c('

    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.

    ',7),ze={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},$e=i("PROXY protocol"),ns=i(" is used to pass the true source IP and port of a request. "),es=t("strong",null,"If you are not familiar with it, please ignore this option first",-1),ss=i("."),ts=c('

    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. Only supported by Linux.

    ',12);l.render=function(c,i){const l=n("RouterLink"),os=n("OutboundLink"),as=n("Badge");return e(),s(p,null,[r,t("blockquote",null,[t("p",null,[u,d,o(l,{to:"/en/config/transports/tcp.html"},{default:a((()=>[b])),_:1})])]),h,t("blockquote",null,[t("p",null,[k,m,o(l,{to:"/en/config/transports/mkcp.html"},{default:a((()=>[g])),_:1})])]),f,t("blockquote",null,[t("p",null,[q,y,o(l,{to:"/en/config/transports/websocket.html"},{default:a((()=>[v])),_:1})])]),S,t("blockquote",null,[t("p",null,[w,T,o(l,{to:"/en/config/transports/h2.html"},{default:a((()=>[x])),_:1})])]),A,t("blockquote",null,[t("p",null,[P,I,o(l,{to:"/en/config/transports/quic.html"},{default:a((()=>[L])),_:1})])]),C,t("blockquote",null,[t("p",null,[j,O,o(l,{to:"/en/config/transports/grpc.html"},{default:a((()=>[W])),_:1})])]),D,t("blockquote",null,[t("p",null,[E,F,o(l,{to:"/en/config/transports/domainsocket.html"},{default:a((()=>[N])),_:1})])]),B,t("ul",null,[R,t("li",null,[G,U,t("a",Q,[X,o(os)]),V]),t("li",null,[Y,K,o(l,{to:"/en/config/features/xtls.html"},{default:a((()=>[M])),_:1}),H,o(as,{text:"Deprecated",type:"warning"})])]),_,J,t("blockquote",null,[t("p",null,[Z,z,$,nn,o(as,{text:"Deprecated",type:"warning"})])]),en,t("blockquote",null,[t("p",null,[sn,tn,o(l,{to:"/en/config/transports/tcp.html"},{default:a((()=>[on])),_:1})])]),an,t("blockquote",null,[t("p",null,[pn,cn,o(l,{to:"/en/config/transports/mkcp.html"},{default:a((()=>[ln])),_:1})])]),rn,t("blockquote",null,[t("p",null,[un,dn,o(l,{to:"/en/config/transports/websocket.html"},{default:a((()=>[bn])),_:1})])]),hn,t("blockquote",null,[t("p",null,[kn,mn,o(l,{to:"/en/config/transports/h2.html"},{default:a((()=>[gn])),_:1})])]),fn,t("blockquote",null,[t("p",null,[qn,yn,o(l,{to:"/en/config/transports/quic.html"},{default:a((()=>[vn])),_:1})])]),Sn,t("blockquote",null,[t("p",null,[wn,Tn,o(l,{to:"/en/config/transports/grpc.html"},{default:a((()=>[xn])),_:1})])]),An,t("blockquote",null,[t("p",null,[Pn,In,o(l,{to:"/en/config/transports/domainsocket.html"},{default:a((()=>[Ln])),_:1})])]),Cn,t("p",null,[jn,t("a",On,[Wn,o(os)]),Dn,t("a",En,[Fn,o(os)]),Nn]),Bn,t("ol",null,[t("li",null,[Rn,Gn,Un,Qn,Xn,t("a",Vn,[Yn,o(os)]),Kn])]),t("div",Mn,[Hn,t("p",null,[_n,Jn,Zn,zn,$n,ne,ee,o(l,{to:"/en/config/transports/websocket.html#browser-dialer"},{default:a((()=>[se])),_:1}),te])]),oe,t("div",ae,[pe,t("p",null,[ce,t("a",ie,[le,o(os)]),re])]),ue,t("div",de,[be,t("p",null,[he,t("a",ke,[me,o(os)]),ge])]),fe,t("p",null,[qe,t("a",ye,[ve,o(os)]),Se]),we,t("div",Te,[xe,t("p",null,[Ae,Pe,Ie,Le,Ce,o(l,{to:"/en/config/inbounds/dokodemo.html"},{default:a((()=>[je])),_:1}),Oe,We,De,Ee,Fe,Ne,Be])]),Re,Ge,Ue,t("ul",null,[Qe,t("li",null,[Xe,Ve,Ye,Ke,Me,He,o(l,{to:"/en/config/dns.html"},{default:a((()=>[_e])),_:1}),Je])]),Ze,t("p",null,[t("a",ze,[$e,o(os)]),ns,es,ss]),ts],64)};export default l; +import{r as n,o as e,c as s,a as t,b as o,w as a,F as p,d as c,e as i}from"./app.48111a85.js";const l={},r=c('

    Transport Protocol

    Transport protocol is the way that Xray nodes communicate with each other.

    Transport protocol specifies a stable way to transmit data. Typically, both ends of a network connection need to use the same transport protocol to establish a connection. For example, if one end uses WebSocket, the other end must also use WebSocket, otherwise the connection cannot be established.

    Transport protocol configuration has two parts:

    1. Global configuration (TransportObject)
    2. Local configuration (StreamSettingsObject).
    • When configuring locally, you can specify how each individual inbound or outbound connection is transmitted.
    • Typically, the inbound and outbound connections corresponding to the client and server need to use the same transport protocol. When a transport protocol is specified but no specific settings are provided, the transport protocol will use the settings from the global configuration.

    TransportObject

    The TransportObject corresponds to the transport item in the configuration file.

    {\n  "transport": {\n    "tcpSettings": {},\n    "kcpSettings": {},\n    "wsSettings": {},\n    "httpSettings": {},\n    "quicSettings": {},\n    "dsSettings": {},\n    "grpcSettings": {}\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ',9),u=t("code",null,"tcpSettings",-1),d=i(": "),b=i("TcpObject"),h=t("p",null,"Configuration for TCP connections.",-1),k=t("code",null,"kcpSettings",-1),m=i(": "),g=i("KcpObject"),f=t("p",null,"Configuration for mKCP connections.",-1),q=t("code",null,"wsSettings",-1),y=i(": "),v=i("WebSocketObject"),S=t("p",null,"Configuration for WebSocket connections.",-1),w=t("code",null,"httpSettings",-1),T=i(": "),x=i("HttpObject"),A=t("p",null,"Configuration for HTTP/2 connections.",-1),P=t("code",null,"quicSettings",-1),I=i(": "),L=i("QuicObject"),C=t("p",null,"Configuration for QUIC connections.",-1),j=t("code",null,"grpcSettings",-1),O=i(": "),W=i("GRPCObject"),D=t("p",null,"Configuration for gRPC connections.",-1),E=t("code",null,"dsSettings",-1),F=i(": "),N=i("DomainSocketObject"),B=c('

    Configuration for Domain Socket connections.

    StreamSettingsObject

    StreamSettingsObject corresponds to the streamSettings item in inbound or outbound configuration. Each inbound or outbound can be configured with different transport settings and can use streamSettings to perform some transport configurations.

    {\n  "network": "tcp",\n  "security": "none",\n  "tlsSettings": {},\n  "tcpSettings": {},\n  "kcpSettings": {},\n  "wsSettings": {},\n  "httpSettings": {},\n  "quicSettings": {},\n  "dsSettings": {},\n  "grpcSettings": {},\n  "sockopt": {\n    "mark": 0,\n    "tcpFastOpen": false,\n    "tproxy": "off",\n    "domainStrategy": "AsIs",\n    "dialerProxy": "",\n    "acceptProxyProtocol": false,\n    "tcpKeepAliveInterval": 0\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    network: "tcp" | "kcp" | "ws" | "http" | "domainsocket" | "quic" | "grpc"

    The type of transport used by the connection's data stream, with a default value of "tcp".

    security: "none" | "tls" | "xtls"

    Whether to enable transport layer encryption, with supported options:

    ',8),R=t("li",null,[t("code",null,'"none"'),i(" means no encryption (default value).")],-1),G=t("code",null,'"tls"',-1),U=i(" means using "),Q={href:"https://en.wikipedia.org/wiki/base/transport_Layer_Security",target:"_blank",rel:"noopener noreferrer"},X=i("TLS"),V=i("."),Y=t("code",null,'"xtls"',-1),K=i(" means using "),M=i("XTLS"),H=i(". "),_=t("blockquote",null,[t("p",null,[t("code",null,"tlsSettings"),i(": "),t("a",{href:"#tlsobject"},"TLSObject")])],-1),J=t("p",null,"TLS configuration. TLS is provided by Golang, and usually the result of TLS negotiation is to use TLS 1.3, and DTLS is not supported.",-1),Z=t("code",null,"xtlsSettings",-1),z=i(": "),$=t("a",{href:"#tlsobject"},"XTLSObject",-1),nn=i(),en=c('

    XTLS configuration. XTLS is Xray's original technology, which is the core driver of Xray's outstanding performance. XTLS has the same security as TLS and uses the same configuration as TLS.

    Tip

    TLS/XTLS is currently the most secure transport encryption scheme, and its traffic appears consistent with normal web traffic to outsiders. Enabling XTLS and configuring the appropriate XTLS flow control mode can provide several times to even more than ten times the performance improvement while maintaining the same security as TLS. When changing the value of security from tls to xtls, simply modify tlsSettings to xtlsSettings.

    ',2),sn=t("code",null,"tcpSettings",-1),tn=i(": "),on=i("TcpObject"),an=t("p",null,"The TCP configuration for the current connection, only valid when TCP is used for this connection. The configuration is the same as the global configuration above.",-1),pn=t("code",null,"kcpSettings",-1),cn=i(": "),ln=i("KcpObject"),rn=t("p",null,"The mKCP configuration for the current connection, only valid when mKCP is used for this connection. The configuration is the same as the global configuration above.",-1),un=t("code",null,"wsSettings",-1),dn=i(": "),bn=i("WebSocketObject"),hn=t("p",null,"The WebSocket configuration for the current connection, only valid when WebSocket is used for this connection. The configuration is the same as the global configuration above.",-1),kn=t("code",null,"httpSettings",-1),mn=i(": "),gn=i("HttpObject"),fn=t("p",null,"The HTTP/2 configuration for the current connection, only valid when HTTP/2 is used for this connection. The configuration is the same as the global configuration above.",-1),qn=t("code",null,"quicSettings",-1),yn=i(": "),vn=i("QUICObject"),Sn=t("p",null,"The QUIC configuration for the current connection, only valid when QUIC is used for this connection. The configuration is the same as the global configuration above.",-1),wn=t("code",null,"grpcSettings",-1),Tn=i(": "),xn=i("GRPCObject"),An=t("p",null,"The gRPC configuration for the current connection, only valid when gRPC is used for this connection. The configuration is the same as the global configuration above.",-1),Pn=t("code",null,"dsSettings",-1),In=i(": "),Ln=i("DomainSocketObject"),Cn=c('

    The Domain socket configuration for the current connection, only valid when Domain socket is used for this connection. The configuration is the same as the global configuration above.

    sockopt: SockoptObject

    Specific configuration for transparent proxying.

    TLSObject

    {\n  "serverName": "xray.com",\n  "rejectUnknownSni": false,\n  "allowInsecure": false,\n  "alpn": ["h2", "http/1.1"],\n  "minVersion": "1.2",\n  "maxVersion": "1.3",\n  "cipherSuites": "Specify the names of the encryption suites you need here, separated by :",\n  "certificates": [],\n  "disableSystemRoot": false,\n  "enableSessionResumption": false,\n  "fingerprint": "",\n  "pinnedPeerCertificateChainSha256": [""]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    serverName: string

    Specifies the domain name of the server certificate, useful when the connection is established by IP.

    When the target connection is specified by domain name, such as when the domain name is received by the Socks inbound or when it is detected by the Sniffing function, this domain name is automatically used for serverName without manual configuration.

    rejectUnknownSni: bool

    When set to true, the server rejects the TLS handshake if the received SNI does not match the domain name in the certificate. The default value is false.

    alpn: [ string ]

    An array of strings that specifies the ALPN values to be used during the TLS handshake. The default value is ["h2", "http/1.1"].

    minVersion: [ string ]

    minVersion is the minimum acceptable SSL/TLS version.

    maxVersion: [ string ]

    maxVersion is the maximum acceptable SSL/TLS version.

    cipherSuites: [ string ]

    CipherSuites is used to configure the supported list of cryptographic suites, with each suite name separated by a colon.

    ',18),jn=i("You can find the names and descriptions of Golang encryption suites at "),On={href:"https://golang.org/src/crypto/tls/cipher_suites.go#L500",target:"_blank",rel:"noopener noreferrer"},Wn=i("here"),Dn=i(" or "),En={href:"https://golang.org/src/crypto/tls/cipher_suites.go#L44",target:"_blank",rel:"noopener noreferrer"},Fn=i("here"),Nn=i("."),Bn=c('

    Danger

    The above two configurations are optional and normally do not affect security. If not configured, Golang will automatically select based on the device. If you are not familiar with these options, do not configure them, and any problems caused by improper configuration are your responsibility.

    allowInsecure: true | false

    Whether to allow insecure connections (only for clients). The default value is false.

    When set to true, Xray will not verify the validity of the TLS certificate provided by the remote host.

    Danger

    For security reasons, this option should not be set to true in practical scenarios, otherwise, it may be susceptible to man-in-the-middle attacks.

    disableSystemRoot: true | false

    Whether to disable the CA certificate provided by the operating system. The default value is false.

    When set to true, Xray will only use the certificates specified in certificates for TLS handshakes. When set to false, Xray will only use the CA certificates provided by the operating system for TLS handshakes.

    enableSessionResumption: true | false

    When this parameter is set to false, the session_ticket extension is not included in the ClientHello message. Generally, the ClientHello message in Go language programs does not use this extension, so it is recommended to keep the default value. The default value is false.

    fingerprint: string

    This parameter is used to configure the fingerprint of the TLS Client Hello. When its value is empty, this feature is not enabled. After enabling it, Xray will simulate the TLS fingerprint through the uTLS library or generate it randomly. Three configuration options are supported:

    1. TLS fingerprints of the latest versions of popular browsers, including:
    • "chrome"
    • "firefox"
    • "safari"
    • "ios"
    • "android"
    • "edge"
    • "360"
    • "qq"
    1. Generate a fingerprint when xray starts
    • "random": randomly select one in newer versions of browsers
    • "randomized": generate a completely random and unique fingerprint (100% compatible with TLS 1.3 using X25519)
    ',16),Rn=i("Use uTLS native fingerprint variable names, such as "),Gn=t("code",null,'"HelloRandomizedNoALPN"',-1),Un=i(),Qn=t("code",null,'"HelloChrome_106_Shuffle"',-1),Xn=i(". See the full list in "),Vn={href:"https://github.com/refraction-networking/utls/blob/master/u_common.go#L162",target:"_blank",rel:"noopener noreferrer"},Yn=i("uTLS library"),Kn=i("."),Mn={class:"custom-container tip"},Hn=t("p",{class:"custom-container-title"},"Tip",-1),_n=i("This feature only "),Jn=t("strong",null,"simulates",-1),Zn=i(" the fingerprint of the "),zn=t("code",null,"TLS Client Hello",-1),$n=i(", and its behavior and other fingerprints are the same as Golang. If you want to simulate browser "),ne=t("code",null,"TLS",-1),ee=i(" fingerprints and behaviors more completely, you can use the "),se=i("Browser Dialer"),te=i("."),oe=c('

    pinnedPeerCertificateChainSha256: [string]

    Specifies the SHA256 hash value of the certificate chain for the remote server, using standard encoding format. Only when the hash value of the server-side certificate chain matches one of the settings can a TLS connection be successfully established.

    When the connection fails due to this configuration, the hash value of the remote server certificate will be displayed.

    Danger

    It is not recommended to use this method to obtain the hash value of the certificate chain, because in this case, there will be no opportunity to verify whether the certificate provided by the server at this time is a real certificate, and it cannot be guaranteed that the obtained certificate hash value is the expected hash value.

    Tip

    If you need to obtain the hash value of the certificate, run xray tls certChainHash --cert <cert.pem> in the command line, where <cert.pem> should be replaced with the actual certificate file path.

    certificates: [ CertificateObject ]

    A list of certificates, each representing a certificate (recommended fullchain).

    ',7),ae={class:"custom-container tip"},pe=t("p",{class:"custom-container-title"},"Tip",-1),ce=i("If you want to obtain the A/A+ rating in ssllibs or myssl evaluation, please refer to "),ie={href:"https://github.com/XTLS/Xray-core/discussions/56#discussioncomment-215600",target:"_blank",rel:"noopener noreferrer"},le=i("here"),re=i("."),ue=c('

    CertificateObject

    {\n  "ocspStapling": 3600,\n  "oneTimeLoading": false,\n  "usage": "encipherment",\n  "certificateFile": "/path/to/certificate.crt",\n  "keyFile": "/path/to/key.key",\n  "certificate": [\n    "--BEGIN CERTIFICATE--",\n    "MIICwDCCAaigAwIBAgIRAO16JMdESAuHidFYJAR/7kAwDQYJKoZIhvcNAQELBQAw",\n    "ADAeFw0xODA0MTAxMzU1MTdaFw0xODA0MTAxNTU1MTdaMAAwggEiMA0GCSqGSIb3",\n    "DQEBAQUAA4IBDwAwggEKAoIBAQCs2PX0fFSCjOemmdm9UbOvcLctF94Ox4BpSfJ+",\n    "3lJHwZbvnOFuo56WhQJWrclKoImp/c9veL1J4Bbtam3sW3APkZVEK9UxRQ57HQuw",\n    "OzhV0FD20/0YELou85TwnkTw5l9GVCXT02NG+pGlYsFrxesUHpojdl8tIcn113M5",\n    "pypgDPVmPeeORRf7nseMC6GhvXYM4txJPyenohwegl8DZ6OE5FkSVR5wFQtAhbON",\n    "OAkIVVmw002K2J6pitPuJGOka9PxcCVWhko/W+JCGapcC7O74palwBUuXE1iH+Jp",\n    "noPjGp4qE2ognW3WH/sgQ+rvo20eXb9Um1steaYY8xlxgBsXAgMBAAGjNTAzMA4G",\n    "A1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAA",\n    "MA0GCSqGSIb3DQEBCwUAA4IBAQBUd9sGKYemzwPnxtw/vzkV8Q32NILEMlPVqeJU",\n    "7UxVgIODBV6A1b3tOUoktuhmgSSaQxjhYbFAVTD+LUglMUCxNbj56luBRlLLQWo+",\n    "9BUhC/ow393tLmqKcB59qNcwbZER6XT5POYwcaKM75QVqhCJVHJNb1zSEE7Co7iO",\n    "6wIan3lFyjBfYlBEz5vyRWQNIwKfdh5cK1yAu13xGENwmtlSTHiwbjBLXfk+0A/8",\n    "r/2s+sCYUkGZHhj8xY7bJ1zg0FRalP5LrqY+r6BckT1QPDIQKYy615j1LpOtwZe/",\n    "d4q7MD/dkzRDsch7t2cIjM/PYeMuzh87admSyL6hdtK0Nm/Q",\n    "--END CERTIFICATE--"\n  ],\n  "key": [\n    "--BEGIN RSA PRIVATE KEY--",\n    "MIIEowIBAAKCAQEArNj19HxUgoznppnZvVGzr3C3LRfeDseAaUnyft5SR8GW75zh",\n    "bqOeloUCVq3JSqCJqf3Pb3i9SeAW7Wpt7FtwD5GVRCvVMUUOex0LsDs4VdBQ9tP9",\n    "GBC6LvOU8J5E8OZfRlQl09NjRvqRpWLBa8XrFB6aI3ZfLSHJ9ddzOacqYAz1Zj3n",\n    "jkUX+57HjAuhob12DOLcST8np6IcHoJfA2ejhORZElUecBULQIWzjTgJCFVZsNNN",\n    "itieqYrT7iRjpGvT8XAlVoZKP1viQhmqXAuzu+KWpcAVLlxNYh/iaZ6D4xqeKhNq",\n    "IJ1t1h/7IEPq76NtHl2/VJtbLXmmGPMZcYAbFwIDAQABAoIBAFCgG4phfGIxK9Uw",\n    "qrp+o9xQLYGhQnmOYb27OpwnRCYojSlT+mvLcqwvevnHsr9WxyA+PkZ3AYS2PLue",\n    "C4xW0pzQgdn8wENtPOX8lHkuBocw1rNsCwDwvIguIuliSjI8o3CAy+xVDFgNhWap",\n    "/CMzfQYziB7GlnrM6hH838iiy0dlv4I/HKk+3/YlSYQEvnFokTf7HxbDDmznkJTM",\n    "aPKZ5qbnV+4AcQfcLYJ8QE0ViJ8dVZ7RLwIf7+SG0b0bqloti4+oQXqGtiESUwEW",\n    "/Wzi7oyCbFJoPsFWp1P5+wD7jAGpAd9lPIwPahdr1wl6VwIx9W0XYjoZn71AEaw4",\n    "bK4xUXECgYEA3g2o9WqyrhYSax3pGEdvV2qN0VQhw7Xe+jyy98CELOO2DNbB9QNJ",\n    "8cSSU/PjkxQlgbOJc8DEprdMldN5xI/srlsbQWCj72wXxXnVnh991bI2clwt7oYi",\n    "pcGZwzCrJyFL+QaZmYzLxkxYl1tCiiuqLm+EkjxCWKTX/kKEFb6rtnMCgYEAx0WR",\n    "L8Uue3lXxhXRdBS5QRTBNklkSxtU+2yyXRpvFa7Qam+GghJs5RKfJ9lTvjfM/PxG",\n    "3vhuBliWQOKQbm1ZGLbgGBM505EOP7DikUmH/kzKxIeRo4l64mioKdDwK/4CZtS7",\n    "az0Lq3eS6bq11qL4mEdE6Gn/Y+sqB83GHZYju80CgYABFm4KbbBcW+1RKv9WSBtK",\n    "gVIagV/89moWLa/uuLmtApyEqZSfn5mAHqdc0+f8c2/Pl9KHh50u99zfKv8AsHfH",\n    "TtjuVAvZg10GcZdTQ/I41ruficYL0gpfZ3haVWWxNl+J47di4iapXPxeGWtVA+u8",\n    "eH1cvgDRMFWCgE7nUFzE8wKBgGndUomfZtdgGrp4ouLZk6W4ogD2MpsYNSixkXyW",\n    "64cIbV7uSvZVVZbJMtaXxb6bpIKOgBQ6xTEH5SMpenPAEgJoPVts816rhHdfwK5Q",\n    "8zetklegckYAZtFbqmM0xjOI6bu5rqwFLWr1xo33jF0wDYPQ8RHMJkruB1FIB8V2",\n    "GxvNAoGBAM4g2z8NTPMqX+8IBGkGgqmcYuRQxd3cs7LOSEjF9hPy1it2ZFe/yUKq",\n    "ePa2E8osffK5LBkFzhyQb0WrGC9ijM9E6rv10gyuNjlwXdFJcdqVamxwPUBtxRJR",\n    "cYTY2HRkJXDdtT0Bkc3josE6UUDvwMpO0CfAETQPto1tjNEDhQhT",\n    "--END RSA PRIVATE KEY--"\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55

    ocspStapling: number

    OCSP stapling update interval in seconds for certificate hot reload. Default value is 3600, i.e. one hour.

    oneTimeLoading: true | false

    Load only once. When set to true, it will disable certificate hot reload and OCSP stapling feature.

    Warning

    When set to true, OCSP stapling will be disabled.

    usage: "encipherment" | "verify" | "issue"

    Certificate usage, default value is "encipherment".

    • "encipherment": The certificate is used for TLS authentication and encryption.
    • "verify": The certificate is used to verify the remote TLS certificate. When using this option, the current certificate must be a CA certificate.
    • "issue": The certificate is used to issue other certificates. When using this option, the current certificate must be a CA certificate.

    TIP 1

    On Windows platform, self-signed CA certificate can be installed in the system for verifying remote TLS certificates.

    TIP 2

    When a new client request comes in, assuming the specified serverName is "xray.com", Xray will first look for a certificate that can be used for "xray.com" in the certificate list. If not found, it will issue a certificate for "xray.com" using any certificate with usage set to "issue", with a validity of one hour. The new certificate is then added to the certificate list for later use.

    TIP 3

    When both certificateFile and certificate are specified, Xray will use certificateFile as the priority. The same applies to keyFile and key.

    TIP 4

    When usage is set to "verify", keyFile and key can both be empty.

    TIP 5

    Use xray tls cert to generate self-signed CA certificate.

    ',15),de={class:"custom-container tip"},be=t("p",{class:"custom-container-title"},"TIP 6",-1),he=i("If you already have a domain name, you can use tools to obtain free third-party certificates easily, such as "),ke={href:"https://github.com/acmesh-official/acme.sh",target:"_blank",rel:"noopener noreferrer"},me=i("acme.sh"),ge=i("."),fe=c('

    certificateFile: string

    Path to the certificate file generated by OpenSSL, with the suffix .crt.

    certificate: [ string ]

    A string array representing the certificate content, in the format shown in the example. Either certificate or certificateFile can be used.

    keyFile: string

    Path to the key file generated by OpenSSL, with the suffix .key. Password-protected key files are not currently supported.

    key: [ string ]

    A string array representing the key content, in the format shown in the example. Either key or keyFile can be used.

    SockoptObject

    {\n  "mark": 0,\n  "tcpFastOpen": false,\n  "tproxy": "off",\n  "domainStrategy": "AsIs",\n  "dialerProxy": "",\n  "acceptProxyProtocol": false,\n  "tcpKeepAliveInterval": 0,\n  "tcpcongestion": "bbr",\n  "interface": "wg0"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    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

    ',14),qe=i("Specifies whether "),ye={href:"https://en.wikipedia.org/wiki/TCP_Fast_Open",target:"_blank",rel:"noopener noreferrer"},ve=i("TCP Fast Open"),Se=i(" is enabled."),we=c("

    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.

    ",6),Te={class:"custom-container danger"},xe=t("p",{class:"custom-container-title"},"Danger",-1),Ae=i("When "),Pe=t("code",null,"followRedirect",-1),Ie=i(" is set to "),Le=t("code",null,"true",-1),Ce=i(" in "),je=i("Dokodemo-door"),Oe=i(", and "),We=t("code",null,"tproxy",-1),De=i(" in the Sockopt settings is empty, the value of "),Ee=t("code",null,"tproxy",-1),Fe=i(" in the Sockopt settings will be set to "),Ne=t("code",null,'"redirect"',-1),Be=i("."),Re=t("blockquote",null,[t("p",null,[t("code",null,"domainStrategy"),i(': "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"')])],-1),Ge=t("p",null,[i("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 "),t("code",null,"domainStrategy"),i(" into Sockopt.")],-1),Ue=t("p",null,"When the target address is a domain name, the corresponding value is configured, and the behavior of SystemDialer is as follows:",-1),Qe=t("li",null,[t("code",null,'"AsIs"'),i(": Resolve the IP address using the system DNS server and connect to the domain name.")],-1),Xe=t("code",null,'"UseIP"',-1),Ve=i(", "),Ye=t("code",null,'"UseIPv4"',-1),Ke=i(", and "),Me=t("code",null,'"UseIPv6"',-1),He=i(": Resolve the IP address using the "),_e=i("built-in DNS server"),Je=i(" and connect to the IP address directly."),Ze=c('

    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.

    ',7),ze={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},$e=i("PROXY protocol"),ns=i(" is used to pass the true source IP and port of a request. "),es=t("strong",null,"If you are not familiar with it, please ignore this option first",-1),ss=i("."),ts=c('

    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. Only supported by Linux.

    ',12);l.render=function(c,i){const l=n("RouterLink"),os=n("OutboundLink"),as=n("Badge");return e(),s(p,null,[r,t("blockquote",null,[t("p",null,[u,d,o(l,{to:"/en/config/transports/tcp.html"},{default:a((()=>[b])),_:1})])]),h,t("blockquote",null,[t("p",null,[k,m,o(l,{to:"/en/config/transports/mkcp.html"},{default:a((()=>[g])),_:1})])]),f,t("blockquote",null,[t("p",null,[q,y,o(l,{to:"/en/config/transports/websocket.html"},{default:a((()=>[v])),_:1})])]),S,t("blockquote",null,[t("p",null,[w,T,o(l,{to:"/en/config/transports/h2.html"},{default:a((()=>[x])),_:1})])]),A,t("blockquote",null,[t("p",null,[P,I,o(l,{to:"/en/config/transports/quic.html"},{default:a((()=>[L])),_:1})])]),C,t("blockquote",null,[t("p",null,[j,O,o(l,{to:"/en/config/transports/grpc.html"},{default:a((()=>[W])),_:1})])]),D,t("blockquote",null,[t("p",null,[E,F,o(l,{to:"/en/config/transports/domainsocket.html"},{default:a((()=>[N])),_:1})])]),B,t("ul",null,[R,t("li",null,[G,U,t("a",Q,[X,o(os)]),V]),t("li",null,[Y,K,o(l,{to:"/en/config/features/xtls.html"},{default:a((()=>[M])),_:1}),H,o(as,{text:"Deprecated",type:"warning"})])]),_,J,t("blockquote",null,[t("p",null,[Z,z,$,nn,o(as,{text:"Deprecated",type:"warning"})])]),en,t("blockquote",null,[t("p",null,[sn,tn,o(l,{to:"/en/config/transports/tcp.html"},{default:a((()=>[on])),_:1})])]),an,t("blockquote",null,[t("p",null,[pn,cn,o(l,{to:"/en/config/transports/mkcp.html"},{default:a((()=>[ln])),_:1})])]),rn,t("blockquote",null,[t("p",null,[un,dn,o(l,{to:"/en/config/transports/websocket.html"},{default:a((()=>[bn])),_:1})])]),hn,t("blockquote",null,[t("p",null,[kn,mn,o(l,{to:"/en/config/transports/h2.html"},{default:a((()=>[gn])),_:1})])]),fn,t("blockquote",null,[t("p",null,[qn,yn,o(l,{to:"/en/config/transports/quic.html"},{default:a((()=>[vn])),_:1})])]),Sn,t("blockquote",null,[t("p",null,[wn,Tn,o(l,{to:"/en/config/transports/grpc.html"},{default:a((()=>[xn])),_:1})])]),An,t("blockquote",null,[t("p",null,[Pn,In,o(l,{to:"/en/config/transports/domainsocket.html"},{default:a((()=>[Ln])),_:1})])]),Cn,t("p",null,[jn,t("a",On,[Wn,o(os)]),Dn,t("a",En,[Fn,o(os)]),Nn]),Bn,t("ol",null,[t("li",null,[Rn,Gn,Un,Qn,Xn,t("a",Vn,[Yn,o(os)]),Kn])]),t("div",Mn,[Hn,t("p",null,[_n,Jn,Zn,zn,$n,ne,ee,o(l,{to:"/en/config/transports/websocket.html#browser-dialer"},{default:a((()=>[se])),_:1}),te])]),oe,t("div",ae,[pe,t("p",null,[ce,t("a",ie,[le,o(os)]),re])]),ue,t("div",de,[be,t("p",null,[he,t("a",ke,[me,o(os)]),ge])]),fe,t("p",null,[qe,t("a",ye,[ve,o(os)]),Se]),we,t("div",Te,[xe,t("p",null,[Ae,Pe,Ie,Le,Ce,o(l,{to:"/en/config/inbounds/dokodemo.html"},{default:a((()=>[je])),_:1}),Oe,We,De,Ee,Fe,Ne,Be])]),Re,Ge,Ue,t("ul",null,[Qe,t("li",null,[Xe,Ve,Ye,Ke,Me,He,o(l,{to:"/en/config/dns.html"},{default:a((()=>[_e])),_:1}),Je])]),Ze,t("p",null,[t("a",ze,[$e,o(os)]),ns,es,ss]),ts],64)};export default l; diff --git a/assets/trojan.html.50f3922c.js b/assets/trojan.html.33f7a35e.js similarity index 98% rename from assets/trojan.html.50f3922c.js rename to assets/trojan.html.33f7a35e.js index 11b757154..0b1d991a8 100644 --- a/assets/trojan.html.50f3922c.js +++ b/assets/trojan.html.33f7a35e.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as o,w as t,F as p,e as l,d as c}from"./app.755d843f.js";const r={},u=e("h1",{id:"trojan",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trojan","aria-hidden":"true"},"#"),l(" Trojan")],-1),i={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},b=l("Trojan"),d=l(" 协议"),k=c('

    警告

    Trojan 被设计工作在正确配置的加密 TLS 隧道

    InboundConfigurationObject

    {\n  "clients": [\n    {\n      "password": "password",\n      "email": "love@xray.com",\n      "level": 0\n    }\n  ],\n  "fallbacks": [\n    {\n      "dest": 80\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    clients: [ ClientObject ]

    一个数组,代表一组服务端认可的用户.

    其中每一项是一个用户 ClientObject

    ',6),m=e("code",null,"fallbacks",-1),q=l(": [ "),f=l("FallbackObject"),j=l(" ]"),g=l("一个数组,包含一系列强大的回落分流配置(可选)。 fallbacks 的具体配置请点击"),h=l("FallbackObject"),v=c('

    提示

    Xray 的 Trojan 有完整的 fallbacks 支持,配置方式完全一致。 触发回落的条件也与 VLESS 类似:首包长度 < 58 或第 57 个字节不为 \\r(因为 Trojan 没有协议版本)或身份认证失败。

    ClientObject

    {\n  "password": "password",\n  "email": "love@xray.com",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    password: string

    必填,任意字符串。

    email: string

    邮件地址,可选,用于标识用户

    警告

    如果存在多个 ClientObject, 请注意 email 不可以重复。

    level: number

    ',9),y=l("用户等级,连接会使用这个用户等级对应的 "),x=l("本地策略"),O=l("。"),w=l("userLevel 的值, 对应 "),T=l("policy"),C=l(" 中 "),L=e("code",null,"level",-1),_=l(" 的值。 如不指定, 默认为 0。");r.render=function(l,c){const r=n("OutboundLink"),E=n("RouterLink");return s(),a(p,null,[u,e("p",null,[e("a",i,[b,o(r)]),d]),k,e("blockquote",null,[e("p",null,[m,q,o(E,{to:"/config/features/fallback.html"},{default:t((()=>[f])),_:1}),j])]),e("p",null,[g,o(E,{to:"/config/features/fallback.html#fallbacks-%E9%85%8D%E7%BD%AE"},{default:t((()=>[h])),_:1})]),v,e("p",null,[y,o(E,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[x])),_:1}),O]),e("p",null,[w,o(E,{to:"/config/policy.html#policyobject"},{default:t((()=>[T])),_:1}),C,L,_])],64)};export default r; +import{r as n,o as s,c as a,a as e,b as o,w as t,F as p,e as l,d as c}from"./app.48111a85.js";const r={},u=e("h1",{id:"trojan",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trojan","aria-hidden":"true"},"#"),l(" Trojan")],-1),i={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},b=l("Trojan"),d=l(" 协议"),k=c('

    警告

    Trojan 被设计工作在正确配置的加密 TLS 隧道

    InboundConfigurationObject

    {\n  "clients": [\n    {\n      "password": "password",\n      "email": "love@xray.com",\n      "level": 0\n    }\n  ],\n  "fallbacks": [\n    {\n      "dest": 80\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    clients: [ ClientObject ]

    一个数组,代表一组服务端认可的用户.

    其中每一项是一个用户 ClientObject

    ',6),m=e("code",null,"fallbacks",-1),q=l(": [ "),f=l("FallbackObject"),j=l(" ]"),g=l("一个数组,包含一系列强大的回落分流配置(可选)。 fallbacks 的具体配置请点击"),h=l("FallbackObject"),v=c('

    提示

    Xray 的 Trojan 有完整的 fallbacks 支持,配置方式完全一致。 触发回落的条件也与 VLESS 类似:首包长度 < 58 或第 57 个字节不为 \\r(因为 Trojan 没有协议版本)或身份认证失败。

    ClientObject

    {\n  "password": "password",\n  "email": "love@xray.com",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    password: string

    必填,任意字符串。

    email: string

    邮件地址,可选,用于标识用户

    警告

    如果存在多个 ClientObject, 请注意 email 不可以重复。

    level: number

    ',9),y=l("用户等级,连接会使用这个用户等级对应的 "),x=l("本地策略"),O=l("。"),w=l("userLevel 的值, 对应 "),T=l("policy"),C=l(" 中 "),L=e("code",null,"level",-1),_=l(" 的值。 如不指定, 默认为 0。");r.render=function(l,c){const r=n("OutboundLink"),E=n("RouterLink");return s(),a(p,null,[u,e("p",null,[e("a",i,[b,o(r)]),d]),k,e("blockquote",null,[e("p",null,[m,q,o(E,{to:"/config/features/fallback.html"},{default:t((()=>[f])),_:1}),j])]),e("p",null,[g,o(E,{to:"/config/features/fallback.html#fallbacks-%E9%85%8D%E7%BD%AE"},{default:t((()=>[h])),_:1})]),v,e("p",null,[y,o(E,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[x])),_:1}),O]),e("p",null,[w,o(E,{to:"/config/policy.html#policyobject"},{default:t((()=>[T])),_:1}),C,L,_])],64)};export default r; diff --git a/assets/trojan.html.b41a334e.js b/assets/trojan.html.3b3e33ec.js similarity index 95% rename from assets/trojan.html.b41a334e.js rename to assets/trojan.html.3b3e33ec.js index b69b63586..9217d5410 100644 --- a/assets/trojan.html.b41a334e.js +++ b/assets/trojan.html.3b3e33ec.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as o,w as t,F as p,e as r,d as l}from"./app.755d843f.js";const c={},u=e("h1",{id:"trojan",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trojan","aria-hidden":"true"},"#"),r(" Trojan")],-1),i={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},d=r("Trojan"),b=r(" protocol"),k=l('

    Danger

    Trojan is designed to work with correctly configured encrypted TLS tunnels.

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "address": "127.0.0.1",\n      "port": 1234,\n      "password": "password",\n      "email": "love@xray.com",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    servers: [ ServerObject ]

    An array representing a list of servers, where each item is a ServerObject.

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 1234,\n  "password": "password",\n  "email": "love@xray.com",\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6
    7

    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

    ',16),q=r("The user level. Connections will use the corresponding "),h=r("local policy"),m=r(" associated with this user level."),v=r("The "),g=e("code",null,"level",-1),f=r(" value corresponds to the "),j=e("code",null,"level",-1),y=r(" value in the "),w=r("policy"),T=r(". If not specified, the default value is 0.");c.render=function(r,l){const c=n("OutboundLink"),x=n("RouterLink");return s(),a(p,null,[u,e("p",null,[e("a",i,[d,o(c)]),b]),k,e("p",null,[q,o(x,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[h])),_:1}),m]),e("p",null,[v,g,f,j,y,o(x,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[w])),_:1}),T])],64)};export default c; +import{r as n,o as s,c as a,a as e,b as o,w as t,F as p,e as r,d as l}from"./app.48111a85.js";const c={},u=e("h1",{id:"trojan",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trojan","aria-hidden":"true"},"#"),r(" Trojan")],-1),i={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},d=r("Trojan"),b=r(" protocol"),k=l('

    Danger

    Trojan is designed to work with correctly configured encrypted TLS tunnels.

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "address": "127.0.0.1",\n      "port": 1234,\n      "password": "password",\n      "email": "love@xray.com",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    servers: [ ServerObject ]

    An array representing a list of servers, where each item is a ServerObject.

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 1234,\n  "password": "password",\n  "email": "love@xray.com",\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6
    7

    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

    ',16),q=r("The user level. Connections will use the corresponding "),h=r("local policy"),m=r(" associated with this user level."),v=r("The "),g=e("code",null,"level",-1),j=r(" value corresponds to the "),f=e("code",null,"level",-1),y=r(" value in the "),w=r("policy"),T=r(". If not specified, the default value is 0.");c.render=function(r,l){const c=n("OutboundLink"),x=n("RouterLink");return s(),a(p,null,[u,e("p",null,[e("a",i,[d,o(c)]),b]),k,e("p",null,[q,o(x,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[h])),_:1}),m]),e("p",null,[v,g,j,f,y,o(x,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[w])),_:1}),T])],64)};export default c; diff --git a/assets/trojan.html.17832860.js b/assets/trojan.html.3b43a173.js similarity index 98% rename from assets/trojan.html.17832860.js rename to assets/trojan.html.3b43a173.js index a33e8119f..e73d88118 100644 --- a/assets/trojan.html.17832860.js +++ b/assets/trojan.html.3b43a173.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as o,w as p,F as t,e as r,d as c}from"./app.755d843f.js";const l={},u=e("h1",{id:"trojan",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trojan","aria-hidden":"true"},"#"),r(" Trojan")],-1),i={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},b=r("Trojan"),d=r(" 协议"),k=c('

    警告

    Trojan 被设计工作在正确配置的加密 TLS 隧道

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "address": "127.0.0.1",\n      "port": 1234,\n      "password": "password",\n      "email": "love@xray.com",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    servers: [ ServerObject ]

    一个数组,其中每一项是一个 ServerObject

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 1234,\n  "password": "password",\n  "email": "love@xray.com",\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6
    7

    address: address

    服务端地址,支持 IPv4、IPv6 和域名。必填。

    port: number

    服务端端口,通常与服务端监听的端口相同。

    password: string

    密码. 必填,任意字符串。

    email: string

    邮件地址,可选,用于标识用户

    level: number

    ',16),q=r("用户等级,连接会使用这个用户等级对应的 "),m=r("本地策略"),v=r("。"),j=r("level 的值, 对应 "),g=r("policy"),h=r(" 中 "),f=e("code",null,"level",-1),y=r(" 的值。 如不指定, 默认为 0。");l.render=function(r,c){const l=n("OutboundLink"),x=n("RouterLink");return s(),a(t,null,[u,e("p",null,[e("a",i,[b,o(l)]),d]),k,e("p",null,[q,o(x,{to:"/config/policy.html#levelpolicyobject"},{default:p((()=>[m])),_:1}),v]),e("p",null,[j,o(x,{to:"/config/policy.html#policyobject"},{default:p((()=>[g])),_:1}),h,f,y])],64)};export default l; +import{r as n,o as s,c as a,a as e,b as o,w as p,F as t,e as r,d as c}from"./app.48111a85.js";const l={},u=e("h1",{id:"trojan",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trojan","aria-hidden":"true"},"#"),r(" Trojan")],-1),i={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},b=r("Trojan"),d=r(" 协议"),k=c('

    警告

    Trojan 被设计工作在正确配置的加密 TLS 隧道

    OutboundConfigurationObject

    {\n  "servers": [\n    {\n      "address": "127.0.0.1",\n      "port": 1234,\n      "password": "password",\n      "email": "love@xray.com",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    servers: [ ServerObject ]

    一个数组,其中每一项是一个 ServerObject

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 1234,\n  "password": "password",\n  "email": "love@xray.com",\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6
    7

    address: address

    服务端地址,支持 IPv4、IPv6 和域名。必填。

    port: number

    服务端端口,通常与服务端监听的端口相同。

    password: string

    密码. 必填,任意字符串。

    email: string

    邮件地址,可选,用于标识用户

    level: number

    ',16),q=r("用户等级,连接会使用这个用户等级对应的 "),m=r("本地策略"),v=r("。"),j=r("level 的值, 对应 "),g=r("policy"),h=r(" 中 "),f=e("code",null,"level",-1),y=r(" 的值。 如不指定, 默认为 0。");l.render=function(r,c){const l=n("OutboundLink"),x=n("RouterLink");return s(),a(t,null,[u,e("p",null,[e("a",i,[b,o(l)]),d]),k,e("p",null,[q,o(x,{to:"/config/policy.html#levelpolicyobject"},{default:p((()=>[m])),_:1}),v]),e("p",null,[j,o(x,{to:"/config/policy.html#policyobject"},{default:p((()=>[g])),_:1}),h,f,y])],64)};export default l; diff --git a/assets/trojan.html.ae9fa06b.js b/assets/trojan.html.ab92c9a7.js similarity index 95% rename from assets/trojan.html.ae9fa06b.js rename to assets/trojan.html.ab92c9a7.js index 8453cfbbf..7986d9cd3 100644 --- a/assets/trojan.html.ae9fa06b.js +++ b/assets/trojan.html.ab92c9a7.js @@ -1 +1 @@ -import{r as n,o as a,c as s,a as e,b as o,w as t,F as p,e as l,d as c}from"./app.755d843f.js";const r={},i=e("h1",{id:"trojan",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trojan","aria-hidden":"true"},"#"),l(" Trojan")],-1),u=l("The "),d={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},b=l("Trojan"),k=l(" protocol."),f=c('

    Danger

    Trojan is designed to work with correctly configured encrypted TLS tunnels.

    InboundConfigurationObject

    {\n  "clients": [\n    {\n      "password": "password",\n      "email": "love@xray.com",\n      "level": 0\n    }\n  ],\n  "fallbacks": [\n    {\n      "dest": 80\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    clients: [ ClientObject ]

    An array representing a group of users approved by the server.

    Each item in the array is a user ClientObject.

    ',6),h=e("code",null,"fallbacks",-1),m=l(": [ "),g=l("FallbackObject"),q=l(" ]"),j=l("An array that contains a series of powerful fallback configurations (optional). The specific configuration for "),v=e("code",null,"fallbacks",-1),y=l(" can be found in the "),T=l("FallbackObject"),w=l(" documentation."),O=c('

    Tip

    Xray's Trojan has full support for fallbacks, and the configuration is identical. The conditions triggering fallback are similar to VLESS: first packet length < 58 or the 57th byte is not \\r (because Trojan does not have a protocol version) or authentication failure.

    ClientObject

    {\n  "password": "password",\n  "email": "love@xray.com",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    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

    ',9),x=l("The user level that the connection will use to determine the corresponding "),C=l("Local Policy"),L=l("."),_=l("The value of "),A=e("code",null,"level",-1),E=l(" corresponds to the value of "),F=e("code",null,"level",-1),I=l(" in the "),S=l("policy"),D=l(". If not specified, the default value is 0.");r.render=function(l,c){const r=n("OutboundLink"),R=n("RouterLink");return a(),s(p,null,[i,e("p",null,[u,e("a",d,[b,o(r)]),k]),f,e("blockquote",null,[e("p",null,[h,m,o(R,{to:"/en/config/features/fallback.html"},{default:t((()=>[g])),_:1}),q])]),e("p",null,[j,v,y,o(R,{to:"/en/config/features/fallback.html#fallbacks-configuration"},{default:t((()=>[T])),_:1}),w]),O,e("p",null,[x,o(R,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[C])),_:1}),L]),e("p",null,[_,A,E,F,I,o(R,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[S])),_:1}),D])],64)};export default r; +import{r as n,o as a,c as s,a as e,b as o,w as t,F as p,e as l,d as c}from"./app.48111a85.js";const r={},i=e("h1",{id:"trojan",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#trojan","aria-hidden":"true"},"#"),l(" Trojan")],-1),u=l("The "),b={href:"https://trojan-gfw.github.io/trojan/protocol",target:"_blank",rel:"noopener noreferrer"},d=l("Trojan"),k=l(" protocol."),f=c('

    Danger

    Trojan is designed to work with correctly configured encrypted TLS tunnels.

    InboundConfigurationObject

    {\n  "clients": [\n    {\n      "password": "password",\n      "email": "love@xray.com",\n      "level": 0\n    }\n  ],\n  "fallbacks": [\n    {\n      "dest": 80\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    clients: [ ClientObject ]

    An array representing a group of users approved by the server.

    Each item in the array is a user ClientObject.

    ',6),h=e("code",null,"fallbacks",-1),m=l(": [ "),g=l("FallbackObject"),q=l(" ]"),j=l("An array that contains a series of powerful fallback configurations (optional). The specific configuration for "),v=e("code",null,"fallbacks",-1),y=l(" can be found in the "),T=l("FallbackObject"),w=l(" documentation."),O=c('

    Tip

    Xray's Trojan has full support for fallbacks, and the configuration is identical. The conditions triggering fallback are similar to VLESS: first packet length < 58 or the 57th byte is not \\r (because Trojan does not have a protocol version) or authentication failure.

    ClientObject

    {\n  "password": "password",\n  "email": "love@xray.com",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    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

    ',9),x=l("The user level that the connection will use to determine the corresponding "),C=l("Local Policy"),L=l("."),_=l("The value of "),A=e("code",null,"level",-1),E=l(" corresponds to the value of "),F=e("code",null,"level",-1),I=l(" in the "),S=l("policy"),D=l(". If not specified, the default value is 0.");r.render=function(l,c){const r=n("OutboundLink"),R=n("RouterLink");return a(),s(p,null,[i,e("p",null,[u,e("a",b,[d,o(r)]),k]),f,e("blockquote",null,[e("p",null,[h,m,o(R,{to:"/en/config/features/fallback.html"},{default:t((()=>[g])),_:1}),q])]),e("p",null,[j,v,y,o(R,{to:"/en/config/features/fallback.html#fallbacks-configuration"},{default:t((()=>[T])),_:1}),w]),O,e("p",null,[x,o(R,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[C])),_:1}),L]),e("p",null,[_,A,E,F,I,o(R,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[S])),_:1}),D])],64)};export default r; diff --git a/assets/vless.html.37dc66c1.js b/assets/vless.html.37dc66c1.js new file mode 100644 index 000000000..acafc3566 --- /dev/null +++ b/assets/vless.html.37dc66c1.js @@ -0,0 +1 @@ +import{r as e,o as t,c as o,a,b as n,F as i,d as r,e as s}from"./app.48111a85.js";const d={},h=r('

    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),l=s('"'),c=a("code",null,"Response authentication",-1),u=s('" has been replaced with "'),p=a("code",null,"Protocol version",-1),f=s('" 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 "'),m=a("code",null,"Additional information",-1),y=s('" (ProtoBuf) and moved forward, giving the protocol itself scalability, with minimal overhead ('),b={href:"https://github.com/gogo/protobuf",target:"_blank",rel:"noopener noreferrer"},g=s("gogo/protobuf"),w=s("). If there is no additional information, there is no relevant overhead."),v=a("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),S=a("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),T=a("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),V=a("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),I=a("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),L=s("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 "),A={href:"https://github.com/rprx/v2ray-vless/releases",target:"_blank",rel:"noopener noreferrer"},E=s("VLESS Changes"),q=s(" for details."),x=r('

    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),k={href:"https://github.com/XTLS/Xray-core/discussions/252",target:"_blank",rel:"noopener noreferrer"},P=s("XUDP: VLESS & VMess & Mux UDP FullCone NAT"),B=r('

    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),M=s("Thank you to "),U={href:"https://github.com/DuckSoft",target:"_blank",rel:"noopener noreferrer"},D=s("@DuckSoft"),C=s(" for the proposal!"),_=s("Please see "),X={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},F=s("VMessAEAD/VLESS Sharing Link Standard Proposal"),R=s(" for more details.");d.render=function(r,s){const d=e("OutboundLink");return t(),o(i,null,[h,a("p",null,[l,c,u,p,f,m,y,a("a",b,[g,n(d)]),w]),v,S,T,V,I,a("p",null,[L,a("a",A,[E,n(d)]),q]),x,a("p",null,[a("a",k,[P,n(d)])]),B,a("p",null,[M,a("a",U,[D,n(d)]),C]),a("p",null,[_,a("a",X,[F,n(d)]),R])],64)};export default d; diff --git a/assets/vless.html.ea7df066.js b/assets/vless.html.3960c3c0.js similarity index 99% rename from assets/vless.html.ea7df066.js rename to assets/vless.html.3960c3c0.js index 8a298a65e..5100f1cc0 100644 --- a/assets/vless.html.ea7df066.js +++ b/assets/vless.html.3960c3c0.js @@ -1 +1 @@ -import{r as e,o as t,c as r,a as s,b as o,F as a,d as n,e as h}from"./app.755d843f.js";const d={},l=n('

    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=h("“响应认证”被替换为“协议版本”并移至最前,使 VLESS 可以升级换代,同时消除了生成伪随机数的开销。混淆相关结构被替换为附加信息(ProtoBuf)并前移,赋予协议本身可扩展性,相关开销也极小("),u={href:"https://github.com/gogo/protobuf",target:"_blank",rel:"noopener noreferrer"},i=h("gogo/protobuf"),c=h("),若无附加信息则无相关开销。"),S=s("p",null,"我一直觉得“响应认证”不是必要的,ALPHA 时为了提升生成随机数的性能,还用 math/rand 替换 crypto/rand,而现在都不需要了。",-1),f=s("p",null,"“协议版本”不仅能起到“响应认证”的作用,还赋予了 VLESS 无痛升级协议结构的能力,带来无限的可能性。 “协议版本”在测试版本中均为 0,正式版本中为 1,以后若有不兼容的协议结构变更则应升级版本。",-1),b=s("p",null,"VLESS 服务端的设计是 switch version,即同时支持所有 VLESS 版本。若需要升级协议版本(可能到不了这一步),推荐的做法是服务端提前一个月支持,一个月后再改客户端。VMess 请求也有协议版本,但它的认证信息在外面,指令部分则高度耦合且有固定加密,导致里面的协议版本毫无意义,服务端也没有进行判断,响应则没有协议版本。Trojan 的协议结构中没有协议版本。",-1),V=s("p",null,"接下来是 UUID,我本来觉得 16 字节有点长,曾经考虑过缩短它,但后来看到 Trojan 用了 56 个可打印字符(56 字节),就彻底打消了这个念头。服务端每次都要验证 UUID,所以性能也很重要:VLESS 的 Validator 经历了多次重构/升级,相较于 VMess,它十分简洁且耗资源很少,可以同时支持非常多的用户,性能也十分强悍,验证速度极快(sync.Map)。API 动态增删用户则更高效顺滑。 https://github.com/XTLS/Xray-core/issues/158",-1),L=s("p",null,"引入 ProtoBuf 是一个创举,等下会详细讲解。“指令”到“地址”的结构目前与 VMess 完全相同,同样支持 Mux。",-1),g=h("总体上,ALPHA 2 到 BETA 主要是:结构进化、清理整合、性能提升、更加完善。这些都是一点一滴的,详见 "),E={href:"https://github.com/rprx/v2ray-vless/releases",target:"_blank",rel:"noopener noreferrer"},y=h("VLESS Changes"),A=h("。"),M=n('

    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),U=h('对比 VMess,VLESS 相当于把 security 换成 encryption,把 disableInsecureEncryption 换成 decryption,就解决了所有问题。目前 encryption 和 decryption 只接受 "none" 且不能留空(即使以后有连接安全性检查),详见 '),m={href:"https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md",target:"_blank",rel:"noopener noreferrer"},P=h("VLESS 配置文档"),T=h("。encryption 并不需要往外移一级,一是因为无法复用很多代码,二是因为会影响控制粒度,看未来的应用就明白了。"),x=s("p",null,"加密支持两类形式,一类是加密完全独立,需要额外密码,适合私用,另一类是结合已有的 UUID 来加密,适合公用。 (若用第一类加密形式,且密码是以某种形式公开的,比如多人共用,那么中间人攻击就不远了) 重新设计的动态端口可能会随加密同时推出,指令由 ProtoBuf 承载,具体实现和 VMess 的动态端口也会有很多不同。",-1),D=s("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),B=s("p",null,"并不是所有组合都需逐一尝试:VMess 的加密分为三段,第一段是认证信息,结合了 UUID、alterId、时间因素,第二段是指令部分,以固定算法加密,指令中含有数据部分使用的加密算法,第三段才是重要的数据部分。可以看出,VMess 的加解密方式实际上是多对一(服务端适配),而不仅是结合 UUID。但仅是结合 UUID 来加密也是件相对麻烦的事情,短时间内不会出,鉴于我们现在有 VMessAEAD 可用,也并不着急。若 VLESS 推出了结合 UUID 的加密方式,相当于重构了整个 VMess。",-1),k=s("h2",{id:"udp-issues",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#udp-issues","aria-hidden":"true"},"#"),h(" UDP issues")],-1),v={href:"https://github.com/XTLS/Xray-core/discussions/252",target:"_blank",rel:"noopener noreferrer"},I=h("XUDP:VLESS & VMess & Mux UDP FullCone NAT"),_=n('

    客户端开发指引

    1. VLESS 协议本身还会有不兼容升级,但客户端配置文件参数基本上是只增不减的。iOS 客户端的协议实现则需紧跟升级。
    2. 视觉标准:UI 标识请统一用 VLESS,而不是 VLess / Vless / vless,配置文件不受影响,代码内则顺其自然。
    3. encryption 应做成输入框而不是选择框,新配置的默认值应为 none,若用户置空则应代填 none

    VLESS 分享链接标准

    ',3),X=h("感谢 "),w=s("img",{src:"https://avatars2.githubusercontent.com/u/7822648?s=32",width:"32px",height:"32px",alt:"a"},null,-1),q=h(),H={href:"https://github.com/DuckSoft",target:"_blank",rel:"noopener noreferrer"},N=h("@DuckSoft"),j=h(" 的提案!"),F=h("详情请见 "),R={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},C=h("VMessAEAD / VLESS 分享链接标准提案");d.render=function(n,h){const d=e("OutboundLink");return t(),r(a,null,[l,s("blockquote",null,[s("p",null,[p,s("a",u,[i,o(d)]),c])]),S,f,b,V,L,s("p",null,[g,s("a",E,[y,o(d)]),A]),M,s("p",null,[U,s("a",m,[P,o(d)]),T]),x,D,B,k,s("p",null,[s("a",v,[I,o(d)])]),_,s("p",null,[X,w,q,s("a",H,[N,o(d)]),j]),s("p",null,[F,s("a",R,[C,o(d)])])],64)};export default d; +import{r as e,o as t,c as r,a as s,b as o,F as a,d as n,e as h}from"./app.48111a85.js";const d={},l=n('

    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=h("“响应认证”被替换为“协议版本”并移至最前,使 VLESS 可以升级换代,同时消除了生成伪随机数的开销。混淆相关结构被替换为附加信息(ProtoBuf)并前移,赋予协议本身可扩展性,相关开销也极小("),u={href:"https://github.com/gogo/protobuf",target:"_blank",rel:"noopener noreferrer"},i=h("gogo/protobuf"),c=h("),若无附加信息则无相关开销。"),S=s("p",null,"我一直觉得“响应认证”不是必要的,ALPHA 时为了提升生成随机数的性能,还用 math/rand 替换 crypto/rand,而现在都不需要了。",-1),f=s("p",null,"“协议版本”不仅能起到“响应认证”的作用,还赋予了 VLESS 无痛升级协议结构的能力,带来无限的可能性。 “协议版本”在测试版本中均为 0,正式版本中为 1,以后若有不兼容的协议结构变更则应升级版本。",-1),b=s("p",null,"VLESS 服务端的设计是 switch version,即同时支持所有 VLESS 版本。若需要升级协议版本(可能到不了这一步),推荐的做法是服务端提前一个月支持,一个月后再改客户端。VMess 请求也有协议版本,但它的认证信息在外面,指令部分则高度耦合且有固定加密,导致里面的协议版本毫无意义,服务端也没有进行判断,响应则没有协议版本。Trojan 的协议结构中没有协议版本。",-1),V=s("p",null,"接下来是 UUID,我本来觉得 16 字节有点长,曾经考虑过缩短它,但后来看到 Trojan 用了 56 个可打印字符(56 字节),就彻底打消了这个念头。服务端每次都要验证 UUID,所以性能也很重要:VLESS 的 Validator 经历了多次重构/升级,相较于 VMess,它十分简洁且耗资源很少,可以同时支持非常多的用户,性能也十分强悍,验证速度极快(sync.Map)。API 动态增删用户则更高效顺滑。 https://github.com/XTLS/Xray-core/issues/158",-1),L=s("p",null,"引入 ProtoBuf 是一个创举,等下会详细讲解。“指令”到“地址”的结构目前与 VMess 完全相同,同样支持 Mux。",-1),g=h("总体上,ALPHA 2 到 BETA 主要是:结构进化、清理整合、性能提升、更加完善。这些都是一点一滴的,详见 "),E={href:"https://github.com/rprx/v2ray-vless/releases",target:"_blank",rel:"noopener noreferrer"},y=h("VLESS Changes"),A=h("。"),M=n('

    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),U=h('对比 VMess,VLESS 相当于把 security 换成 encryption,把 disableInsecureEncryption 换成 decryption,就解决了所有问题。目前 encryption 和 decryption 只接受 "none" 且不能留空(即使以后有连接安全性检查),详见 '),m={href:"https://github.com/rprx/v2fly-github-io/blob/master/docs/config/protocols/vless.md",target:"_blank",rel:"noopener noreferrer"},P=h("VLESS 配置文档"),T=h("。encryption 并不需要往外移一级,一是因为无法复用很多代码,二是因为会影响控制粒度,看未来的应用就明白了。"),x=s("p",null,"加密支持两类形式,一类是加密完全独立,需要额外密码,适合私用,另一类是结合已有的 UUID 来加密,适合公用。 (若用第一类加密形式,且密码是以某种形式公开的,比如多人共用,那么中间人攻击就不远了) 重新设计的动态端口可能会随加密同时推出,指令由 ProtoBuf 承载,具体实现和 VMess 的动态端口也会有很多不同。",-1),D=s("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),B=s("p",null,"并不是所有组合都需逐一尝试:VMess 的加密分为三段,第一段是认证信息,结合了 UUID、alterId、时间因素,第二段是指令部分,以固定算法加密,指令中含有数据部分使用的加密算法,第三段才是重要的数据部分。可以看出,VMess 的加解密方式实际上是多对一(服务端适配),而不仅是结合 UUID。但仅是结合 UUID 来加密也是件相对麻烦的事情,短时间内不会出,鉴于我们现在有 VMessAEAD 可用,也并不着急。若 VLESS 推出了结合 UUID 的加密方式,相当于重构了整个 VMess。",-1),k=s("h2",{id:"udp-issues",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#udp-issues","aria-hidden":"true"},"#"),h(" UDP issues")],-1),v={href:"https://github.com/XTLS/Xray-core/discussions/252",target:"_blank",rel:"noopener noreferrer"},I=h("XUDP:VLESS & VMess & Mux UDP FullCone NAT"),_=n('

    客户端开发指引

    1. VLESS 协议本身还会有不兼容升级,但客户端配置文件参数基本上是只增不减的。iOS 客户端的协议实现则需紧跟升级。
    2. 视觉标准:UI 标识请统一用 VLESS,而不是 VLess / Vless / vless,配置文件不受影响,代码内则顺其自然。
    3. encryption 应做成输入框而不是选择框,新配置的默认值应为 none,若用户置空则应代填 none

    VLESS 分享链接标准

    ',3),X=h("感谢 "),w=s("img",{src:"https://avatars2.githubusercontent.com/u/7822648?s=32",width:"32px",height:"32px",alt:"a"},null,-1),q=h(),H={href:"https://github.com/DuckSoft",target:"_blank",rel:"noopener noreferrer"},N=h("@DuckSoft"),j=h(" 的提案!"),F=h("详情请见 "),R={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},C=h("VMessAEAD / VLESS 分享链接标准提案");d.render=function(n,h){const d=e("OutboundLink");return t(),r(a,null,[l,s("blockquote",null,[s("p",null,[p,s("a",u,[i,o(d)]),c])]),S,f,b,V,L,s("p",null,[g,s("a",E,[y,o(d)]),A]),M,s("p",null,[U,s("a",m,[P,o(d)]),T]),x,D,B,k,s("p",null,[s("a",v,[I,o(d)])]),_,s("p",null,[X,w,q,s("a",H,[N,o(d)]),j]),s("p",null,[F,s("a",R,[C,o(d)])])],64)};export default d; diff --git a/assets/vless.html.36b5a07d.js b/assets/vless.html.42e5667a.js similarity index 99% rename from assets/vless.html.36b5a07d.js rename to assets/vless.html.42e5667a.js index 736f3b1e0..bc94a4571 100644 --- a/assets/vless.html.36b5a07d.js +++ b/assets/vless.html.42e5667a.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as o,w as t,F as p,e as l,d as c}from"./app.755d843f.js";const u={},r=e("h1",{id:"vless",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vless","aria-hidden":"true"},"#"),l(" VLESS")],-1),i=e("div",{class:"custom-container danger"},[e("p",{class:"custom-container-title"},"警告"),e("p",null,"目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。")],-1),b=e("p",null,"VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。",-1),d=l("与 "),k=l("VMess"),q=l(" 不同,VLESS 不依赖于系统时间,认证方式同样为 UUID。"),m=c('

    InboundConfigurationObject

    {\n  "clients": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "level": 0,\n      "email": "love@xray.com",\n      "flow": "xtls-rprx-vision"\n    }\n  ],\n  "decryption": "none",\n  "fallbacks": [\n    {\n      "dest": 80\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    clients: [ ClientObject ]

    一个数组,代表一组服务端认可的用户.

    其中每一项是一个用户 ClientObject

    decryption: "none"

    现阶段需要填 "none",不能留空。 若未正确设置 decryption 的值,使用 Xray 或 -test 时会收到错误信息。

    注意这里是 decryption,和 clients 同级。 decryption 和 vmess 协议的 encryption 的位置不同,是因为若套一层约定加密,服务端需要先解密才能知道是哪个用户。

    ',8),f=e("code",null,"fallbacks",-1),y=l(": [ "),g=l("FallbackObject"),h=l(" ]"),v=l("一个数组,包含一系列强大的回落分流配置(可选)。 fallbacks 的具体配置请点击 "),j=l("FallbackObject"),S=c('

    ClientObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "level": 0,\n  "email": "love@xray.com",\n  "flow": "xtls-rprx-vision"\n}\n
    1
    2
    3
    4
    5
    6

    id: string

    VLESS 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID. 自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)
    ',5),U=l("其映射标准在 "),x={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},L=l("VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5"),D=e("p",null,[l("你可以使用命令 "),e("code",null,'xray uuid -i "自定义字符串"'),l(" 生成自定义字符串所映射的的 UUID。")],-1),I=e("blockquote",null,[e("p",null,[l("也可以使用命令 "),e("code",null,"xray uuid"),l(" 生成随机的 UUID.")])],-1),E=e("blockquote",null,[e("p",null,[e("code",null,"level"),l(": number")])],-1),O=l("用户等级,连接会使用这个用户等级对应的 "),T=l("本地策略"),V=l("。"),X=l("level 的值, 对应 "),C=l("policy"),_=l(" 中 "),w=e("code",null,"level",-1),F=l(" 的值。 如不指定, 默认为 0。"),P=c("

    email: string

    用户邮箱,用于区分不同用户的流量(会体现在日志、统计中)。

    flow: string

    流控模式,用于选择 XTLS 的算法。

    目前入站协议中有以下流控模式可选:

    • flow,空字符或者 none:使用普通 TLS 代理
    • xtls-rprx-vision:使用新 XTLS 模式 包含内层握手随机填充

    此外,目前 XTLS 仅支持 TCP、mKCP、DomainSocket 这三种传输方式。

    ",7);u.render=function(l,c){const u=n("RouterLink"),A=n("OutboundLink");return s(),a(p,null,[r,i,b,e("p",null,[d,o(u,{to:"/config/inbounds/vmess.html"},{default:t((()=>[k])),_:1}),q]),m,e("blockquote",null,[e("p",null,[f,y,o(u,{to:"/config/features/fallback.html"},{default:t((()=>[g])),_:1}),h])]),e("p",null,[v,o(u,{to:"/config/features/fallback.html#fallbacks-%E9%85%8D%E7%BD%AE"},{default:t((()=>[j])),_:1})]),S,e("p",null,[U,e("a",x,[L,o(A)])]),D,I,E,e("p",null,[O,o(u,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[T])),_:1}),V]),e("p",null,[X,o(u,{to:"/config/policy.html#policyobject"},{default:t((()=>[C])),_:1}),_,w,F]),P],64)};export default u; +import{r as n,o as s,c as a,a as e,b as o,w as t,F as p,e as l,d as c}from"./app.48111a85.js";const u={},r=e("h1",{id:"vless",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vless","aria-hidden":"true"},"#"),l(" VLESS")],-1),i=e("div",{class:"custom-container danger"},[e("p",{class:"custom-container-title"},"警告"),e("p",null,"目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。")],-1),b=e("p",null,"VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。",-1),d=l("与 "),k=l("VMess"),q=l(" 不同,VLESS 不依赖于系统时间,认证方式同样为 UUID。"),m=c('

    InboundConfigurationObject

    {\n  "clients": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "level": 0,\n      "email": "love@xray.com",\n      "flow": "xtls-rprx-vision"\n    }\n  ],\n  "decryption": "none",\n  "fallbacks": [\n    {\n      "dest": 80\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    clients: [ ClientObject ]

    一个数组,代表一组服务端认可的用户.

    其中每一项是一个用户 ClientObject

    decryption: "none"

    现阶段需要填 "none",不能留空。 若未正确设置 decryption 的值,使用 Xray 或 -test 时会收到错误信息。

    注意这里是 decryption,和 clients 同级。 decryption 和 vmess 协议的 encryption 的位置不同,是因为若套一层约定加密,服务端需要先解密才能知道是哪个用户。

    ',8),f=e("code",null,"fallbacks",-1),y=l(": [ "),g=l("FallbackObject"),h=l(" ]"),v=l("一个数组,包含一系列强大的回落分流配置(可选)。 fallbacks 的具体配置请点击 "),j=l("FallbackObject"),S=c('

    ClientObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "level": 0,\n  "email": "love@xray.com",\n  "flow": "xtls-rprx-vision"\n}\n
    1
    2
    3
    4
    5
    6

    id: string

    VLESS 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID. 自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)
    ',5),U=l("其映射标准在 "),x={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},L=l("VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5"),D=e("p",null,[l("你可以使用命令 "),e("code",null,'xray uuid -i "自定义字符串"'),l(" 生成自定义字符串所映射的的 UUID。")],-1),I=e("blockquote",null,[e("p",null,[l("也可以使用命令 "),e("code",null,"xray uuid"),l(" 生成随机的 UUID.")])],-1),E=e("blockquote",null,[e("p",null,[e("code",null,"level"),l(": number")])],-1),O=l("用户等级,连接会使用这个用户等级对应的 "),T=l("本地策略"),V=l("。"),X=l("level 的值, 对应 "),C=l("policy"),_=l(" 中 "),w=e("code",null,"level",-1),F=l(" 的值。 如不指定, 默认为 0。"),P=c("

    email: string

    用户邮箱,用于区分不同用户的流量(会体现在日志、统计中)。

    flow: string

    流控模式,用于选择 XTLS 的算法。

    目前入站协议中有以下流控模式可选:

    • flow,空字符或者 none:使用普通 TLS 代理
    • xtls-rprx-vision:使用新 XTLS 模式 包含内层握手随机填充

    此外,目前 XTLS 仅支持 TCP、mKCP、DomainSocket 这三种传输方式。

    ",7);u.render=function(l,c){const u=n("RouterLink"),A=n("OutboundLink");return s(),a(p,null,[r,i,b,e("p",null,[d,o(u,{to:"/config/inbounds/vmess.html"},{default:t((()=>[k])),_:1}),q]),m,e("blockquote",null,[e("p",null,[f,y,o(u,{to:"/config/features/fallback.html"},{default:t((()=>[g])),_:1}),h])]),e("p",null,[v,o(u,{to:"/config/features/fallback.html#fallbacks-%E9%85%8D%E7%BD%AE"},{default:t((()=>[j])),_:1})]),S,e("p",null,[U,e("a",x,[L,o(A)])]),D,I,E,e("p",null,[O,o(u,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[T])),_:1}),V]),e("p",null,[X,o(u,{to:"/config/policy.html#policyobject"},{default:t((()=>[C])),_:1}),_,w,F]),P],64)};export default u; diff --git a/assets/vless.html.a8177d4e.js b/assets/vless.html.a8177d4e.js deleted file mode 100644 index d48000254..000000000 --- a/assets/vless.html.a8177d4e.js +++ /dev/null @@ -1 +0,0 @@ -import{r as e,o as t,c as o,a as n,b as a,F as i,d as r,e as s}from"./app.755d843f.js";const d={},h=r('

    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),l=s('"'),c=n("code",null,"Response authentication",-1),u=s('" has been replaced with "'),p=n("code",null,"Protocol version",-1),f=s('" 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 "'),m=n("code",null,"Additional information",-1),y=s('" (ProtoBuf) and moved forward, giving the protocol itself scalability, with minimal overhead ('),b={href:"https://github.com/gogo/protobuf",target:"_blank",rel:"noopener noreferrer"},g=s("gogo/protobuf"),w=s("). If there is no additional information, there is no relevant overhead."),v=n("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),S=n("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),T=n("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),V=n("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),I=n("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),L=s("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 "),A={href:"https://github.com/rprx/v2ray-vless/releases",target:"_blank",rel:"noopener noreferrer"},E=s("VLESS Changes"),q=s(" for details."),x=r('

    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),k={href:"https://github.com/XTLS/Xray-core/discussions/252",target:"_blank",rel:"noopener noreferrer"},P=s("XUDP: VLESS & VMess & Mux UDP FullCone NAT"),B=r('

    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),M=s("Thank you to "),U={href:"https://github.com/DuckSoft",target:"_blank",rel:"noopener noreferrer"},D=s("@DuckSoft"),C=s(" for the proposal!"),_=s("Please see "),X={href:"https://github.com/XTLS/Xray-core/issues/91",target:"_blank",rel:"noopener noreferrer"},F=s("VMessAEAD/VLESS Sharing Link Standard Proposal"),R=s(" for more details.");d.render=function(r,s){const d=e("OutboundLink");return t(),o(i,null,[h,n("p",null,[l,c,u,p,f,m,y,n("a",b,[g,a(d)]),w]),v,S,T,V,I,n("p",null,[L,n("a",A,[E,a(d)]),q]),x,n("p",null,[n("a",k,[P,a(d)])]),B,n("p",null,[M,n("a",U,[D,a(d)]),C]),n("p",null,[_,n("a",X,[F,a(d)]),R])],64)};export default d; diff --git a/assets/vless.html.3be490f9.js b/assets/vless.html.abebf13e.js similarity index 99% rename from assets/vless.html.3be490f9.js rename to assets/vless.html.abebf13e.js index c14b68aed..52da88ddb 100644 --- a/assets/vless.html.3be490f9.js +++ b/assets/vless.html.abebf13e.js @@ -1 +1 @@ -import{r as n,o as s,c as e,a,b as o,w as t,F as p,e as r,d as l}from"./app.755d843f.js";const c={},i=a("h1",{id:"vless",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#vless","aria-hidden":"true"},"#"),r(" VLESS")],-1),u=a("div",{class:"custom-container danger"},[a("p",{class:"custom-container-title"},"Danger"),a("p",null,"Currently, VLESS does not have built-in encryption, please use it on a reliable channel, such as TLS.")],-1),d=a("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),b=r("Unlike "),h=r("VMess"),m=r(", VLESS does not rely on system time, and the authentication method is also UUID."),k=l('

    OutboundConfigurationObject

    {\n  "vnext": [\n    {\n      "address": "example.com",\n      "port": 443,\n      "users": [\n        {\n          "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n          "encryption": "none",\n          "flow": "xtls-rprx-vision",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    vnext: [ ServerObject ]

    An array, representing the VLESS server list, containing a set of configurations pointing to the server, each of which is a server configuration.

    ServerObject

    {\n  "address": "example.com",\n  "port": 443,\n  "users": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "encryption": "none",\n      "flow": "xtls-rprx-vision",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    address: address

    Server address, pointing to the server, supporting domain names, IPv4, and IPv6.

    port: number

    Server port, usually the same as the port listened by the server.

    users: [ UserObject ]

    Array, a list of users recognized by the server, each of which is a user configuration.

    UserObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "encryption": "none",\n  "flow": "xtls-rprx-vision",\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6

    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)
    ',17),q=r("The mapping standard is in "),g={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},f=r("VLESS UUID mapping standard: mapping custom strings to a UUIDv5"),y=l('

    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

    ',13),v=r("User level, the connection will use the "),w=r("local policy"),S=r(" corresponding to this user level."),x=r("The value of level corresponds to the value of "),U=a("code",null,"level",-1),T=r(" in "),j=r("policy"),I=r(". If not specified, the default is 0.");c.render=function(r,l){const c=n("RouterLink"),L=n("OutboundLink");return s(),e(p,null,[i,u,d,a("p",null,[b,o(c,{to:"/en/config/outbounds/vmess.html"},{default:t((()=>[h])),_:1}),m]),k,a("p",null,[q,a("a",g,[f,o(L)])]),y,a("p",null,[v,o(c,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[w])),_:1}),S]),a("p",null,[x,U,T,o(c,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[j])),_:1}),I])],64)};export default c; +import{r as n,o as s,c as e,a,b as o,w as t,F as p,e as r,d as l}from"./app.48111a85.js";const c={},i=a("h1",{id:"vless",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#vless","aria-hidden":"true"},"#"),r(" VLESS")],-1),u=a("div",{class:"custom-container danger"},[a("p",{class:"custom-container-title"},"Danger"),a("p",null,"Currently, VLESS does not have built-in encryption, please use it on a reliable channel, such as TLS.")],-1),d=a("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),b=r("Unlike "),h=r("VMess"),m=r(", VLESS does not rely on system time, and the authentication method is also UUID."),k=l('

    OutboundConfigurationObject

    {\n  "vnext": [\n    {\n      "address": "example.com",\n      "port": 443,\n      "users": [\n        {\n          "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n          "encryption": "none",\n          "flow": "xtls-rprx-vision",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    vnext: [ ServerObject ]

    An array, representing the VLESS server list, containing a set of configurations pointing to the server, each of which is a server configuration.

    ServerObject

    {\n  "address": "example.com",\n  "port": 443,\n  "users": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "encryption": "none",\n      "flow": "xtls-rprx-vision",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    address: address

    Server address, pointing to the server, supporting domain names, IPv4, and IPv6.

    port: number

    Server port, usually the same as the port listened by the server.

    users: [ UserObject ]

    Array, a list of users recognized by the server, each of which is a user configuration.

    UserObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "encryption": "none",\n  "flow": "xtls-rprx-vision",\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6

    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)
    ',17),q=r("The mapping standard is in "),g={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},f=r("VLESS UUID mapping standard: mapping custom strings to a UUIDv5"),y=l('

    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

    ',13),v=r("User level, the connection will use the "),w=r("local policy"),S=r(" corresponding to this user level."),x=r("The value of level corresponds to the value of "),U=a("code",null,"level",-1),T=r(" in "),j=r("policy"),I=r(". If not specified, the default is 0.");c.render=function(r,l){const c=n("RouterLink"),L=n("OutboundLink");return s(),e(p,null,[i,u,d,a("p",null,[b,o(c,{to:"/en/config/outbounds/vmess.html"},{default:t((()=>[h])),_:1}),m]),k,a("p",null,[q,a("a",g,[f,o(L)])]),y,a("p",null,[v,o(c,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[w])),_:1}),S]),a("p",null,[x,U,T,o(c,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[j])),_:1}),I])],64)};export default c; diff --git a/assets/vless.html.6731895d.js b/assets/vless.html.b352d91c.js similarity index 99% rename from assets/vless.html.6731895d.js rename to assets/vless.html.b352d91c.js index bbda182b3..93e5d77c5 100644 --- a/assets/vless.html.6731895d.js +++ b/assets/vless.html.b352d91c.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as o,w as p,F as t,e as c,d as l}from"./app.755d843f.js";const r={},u=e("h1",{id:"vless",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vless","aria-hidden":"true"},"#"),c(" VLESS")],-1),i=e("div",{class:"custom-container danger"},[e("p",{class:"custom-container-title"},"警告"),e("p",null,"目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。")],-1),d=e("p",null,"VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。",-1),b=c("与 "),k=c("VMess"),q=c(" 不同,VLESS 不依赖于系统时间,认证方式同样为 UUID。"),m=l('

    OutboundConfigurationObject

    {\n  "vnext": [\n    {\n      "address": "example.com",\n      "port": 443,\n      "users": [\n        {\n          "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n          "encryption": "none",\n          "flow": "xtls-rprx-vision",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    vnext: [ ServerObject ]

    一个数组, 表示 VLESS 服务器列表,包含一组指向服务端的配置, 其中每一项是一个服务器配置。

    ServerObject

    {\n  "address": "example.com",\n  "port": 443,\n  "users": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "encryption": "none",\n      "flow": "xtls-rprx-vision",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    address: address

    服务端地址,指向服务端,支持域名、IPv4、IPv6。

    port: number

    服务端端口,通常与服务端监听的端口相同。

    users: [ UserObject ]

    数组, 一组服务端认可的用户列表, 其中每一项是一个用户配置

    UserObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "encryption": "none",\n  "flow": "xtls-rprx-vision",\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6

    id: string

    VLESS 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID. 自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)
    ',17),v=c("其映射标准在 "),S={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},y=c("VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5"),g=l('

    你可以使用命令 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

    ',13),x=c("用户等级,连接会使用这个用户等级对应的 "),h=c("本地策略"),U=c("。"),f=c("level 的值, 对应 "),j=c("policy"),L=c(" 中 "),T=e("code",null,"level",-1),I=c(" 的值。 如不指定, 默认为 0。");r.render=function(c,l){const r=n("RouterLink"),D=n("OutboundLink");return s(),a(t,null,[u,i,d,e("p",null,[b,o(r,{to:"/config/outbounds/vmess.html"},{default:p((()=>[k])),_:1}),q]),m,e("p",null,[v,e("a",S,[y,o(D)])]),g,e("p",null,[x,o(r,{to:"/config/policy.html#levelpolicyobject"},{default:p((()=>[h])),_:1}),U]),e("p",null,[f,o(r,{to:"/config/policy.html#policyobject"},{default:p((()=>[j])),_:1}),L,T,I])],64)};export default r; +import{r as n,o as s,c as a,a as e,b as o,w as p,F as t,e as c,d as l}from"./app.48111a85.js";const r={},u=e("h1",{id:"vless",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vless","aria-hidden":"true"},"#"),c(" VLESS")],-1),i=e("div",{class:"custom-container danger"},[e("p",{class:"custom-container-title"},"警告"),e("p",null,"目前 VLESS 没有自带加密,请用于可靠信道,如 TLS。")],-1),d=e("p",null,"VLESS 是一个无状态的轻量传输协议,它分为入站和出站两部分,可以作为 Xray 客户端和服务器之间的桥梁。",-1),b=c("与 "),k=c("VMess"),q=c(" 不同,VLESS 不依赖于系统时间,认证方式同样为 UUID。"),m=l('

    OutboundConfigurationObject

    {\n  "vnext": [\n    {\n      "address": "example.com",\n      "port": 443,\n      "users": [\n        {\n          "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n          "encryption": "none",\n          "flow": "xtls-rprx-vision",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    vnext: [ ServerObject ]

    一个数组, 表示 VLESS 服务器列表,包含一组指向服务端的配置, 其中每一项是一个服务器配置。

    ServerObject

    {\n  "address": "example.com",\n  "port": 443,\n  "users": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "encryption": "none",\n      "flow": "xtls-rprx-vision",\n      "level": 0\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    address: address

    服务端地址,指向服务端,支持域名、IPv4、IPv6。

    port: number

    服务端端口,通常与服务端监听的端口相同。

    users: [ UserObject ]

    数组, 一组服务端认可的用户列表, 其中每一项是一个用户配置

    UserObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "encryption": "none",\n  "flow": "xtls-rprx-vision",\n  "level": 0\n}\n
    1
    2
    3
    4
    5
    6

    id: string

    VLESS 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID. 自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)
    ',17),v=c("其映射标准在 "),S={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},y=c("VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5"),g=l('

    你可以使用命令 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

    ',13),x=c("用户等级,连接会使用这个用户等级对应的 "),h=c("本地策略"),U=c("。"),f=c("level 的值, 对应 "),j=c("policy"),L=c(" 中 "),T=e("code",null,"level",-1),I=c(" 的值。 如不指定, 默认为 0。");r.render=function(c,l){const r=n("RouterLink"),D=n("OutboundLink");return s(),a(t,null,[u,i,d,e("p",null,[b,o(r,{to:"/config/outbounds/vmess.html"},{default:p((()=>[k])),_:1}),q]),m,e("p",null,[v,e("a",S,[y,o(D)])]),g,e("p",null,[x,o(r,{to:"/config/policy.html#levelpolicyobject"},{default:p((()=>[h])),_:1}),U]),e("p",null,[f,o(r,{to:"/config/policy.html#policyobject"},{default:p((()=>[j])),_:1}),L,T,I])],64)};export default r; diff --git a/assets/vless.html.98f0b143.js b/assets/vless.html.f8dace8d.js similarity index 99% rename from assets/vless.html.98f0b143.js rename to assets/vless.html.f8dace8d.js index e9f895d73..0992a507b 100644 --- a/assets/vless.html.98f0b143.js +++ b/assets/vless.html.f8dace8d.js @@ -1 +1 @@ -import{r as n,o as e,c as s,a,b as o,w as t,F as l,e as p,d as c}from"./app.755d843f.js";const r={},i=a("h1",{id:"vless",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#vless","aria-hidden":"true"},"#"),p(" VLESS")],-1),u=a("div",{class:"custom-container danger"},[a("p",{class:"custom-container-title"},"Danger"),a("p",null,"Currently, VLESS does not provide built-in encryption. Please use it with a reliable channel, such as TLS.")],-1),d=a("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),b=p("Unlike "),h=p("VMess"),m=p(", VLESS does not rely on system time. The authentication method is still UUID-based."),k=c('

    InboundConfigurationObject

    {\n  "clients": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "level": 0,\n      "email": "love@xray.com",\n      "flow": "xtls-rprx-vision"\n    }\n  ],\n  "decryption": "none",\n  "fallbacks": [\n    {\n      "dest": 80\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    clients: [ ClientObject ]

    An array representing a group of users approved by the server.

    Each item in the array is a user ClientObject.

    decryption: "none"

    Currently, you need to specify "none". It cannot be left empty. If the decryption value is not set correctly, you will receive an error message when using Xray or -test.

    Note that decryption is at the same level as clients. The placement of decryption is different from the encryption in the vmess protocol because if there is a layer of agreed encryption, the server needs to decrypt it first to know which user it belongs to.

    ',8),f=a("code",null,"fallbacks",-1),g=p(": [ "),q=p("FallbackObject"),y=p(" ]"),v=p("An array that contains a series of powerful fallback configurations (optional). The specific configuration for "),j=a("code",null,"fallbacks",-1),S=p(" can be found in the "),w=p("FallbackObject"),U=p(" documentation."),x=c('

    ClientObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "level": 0,\n  "email": "love@xray.com",\n  "flow": "xtls-rprx-vision"\n}\n
    1
    2
    3
    4
    5
    6

    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")
    ',5),I=p("The mapping standard is described in the "),L={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},T=p("VLESS UUID Mapping Standard: Mapping a Custom String to a UUIDv5"),C=p("."),D=a("p",null,[p("You can use the command "),a("code",null,'xray uuid -i "custom string"'),p(" to generate the UUID corresponding to a custom string.")],-1),E=a("blockquote",null,[a("p",null,[p("You can also use the command "),a("code",null,"xray uuid"),p(" to generate a random UUID.")])],-1),O=a("blockquote",null,[a("p",null,[a("code",null,"level"),p(": number")])],-1),V=p("The user level that the connection will use to determine the corresponding "),X=p("Local Policy"),_=p("."),F=p("The value of "),P=a("code",null,"level",-1),A=p(" corresponds to the value of "),M=a("code",null,"level",-1),N=p(" in the "),Y=p("policy"),K=p(". If not specified, the default value is 0."),R=c("

    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.

    ",7);r.render=function(p,c){const r=n("RouterLink"),z=n("OutboundLink");return e(),s(l,null,[i,u,d,a("p",null,[b,o(r,{to:"/en/config/inbounds/vmess.html"},{default:t((()=>[h])),_:1}),m]),k,a("blockquote",null,[a("p",null,[f,g,o(r,{to:"/en/config/features/fallback.html"},{default:t((()=>[q])),_:1}),y])]),a("p",null,[v,j,S,o(r,{to:"/en/config/features/fallback.html#fallbacks-configuration"},{default:t((()=>[w])),_:1}),U]),x,a("p",null,[I,a("a",L,[T,o(z)]),C]),D,E,O,a("p",null,[V,o(r,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[X])),_:1}),_]),a("p",null,[F,P,A,M,N,o(r,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[Y])),_:1}),K]),R],64)};export default r; +import{r as n,o as e,c as s,a,b as o,w as t,F as l,e as p,d as c}from"./app.48111a85.js";const r={},i=a("h1",{id:"vless",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#vless","aria-hidden":"true"},"#"),p(" VLESS")],-1),u=a("div",{class:"custom-container danger"},[a("p",{class:"custom-container-title"},"Danger"),a("p",null,"Currently, VLESS does not provide built-in encryption. Please use it with a reliable channel, such as TLS.")],-1),d=a("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),b=p("Unlike "),h=p("VMess"),m=p(", VLESS does not rely on system time. The authentication method is still UUID-based."),k=c('

    InboundConfigurationObject

    {\n  "clients": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "level": 0,\n      "email": "love@xray.com",\n      "flow": "xtls-rprx-vision"\n    }\n  ],\n  "decryption": "none",\n  "fallbacks": [\n    {\n      "dest": 80\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    clients: [ ClientObject ]

    An array representing a group of users approved by the server.

    Each item in the array is a user ClientObject.

    decryption: "none"

    Currently, you need to specify "none". It cannot be left empty. If the decryption value is not set correctly, you will receive an error message when using Xray or -test.

    Note that decryption is at the same level as clients. The placement of decryption is different from the encryption in the vmess protocol because if there is a layer of agreed encryption, the server needs to decrypt it first to know which user it belongs to.

    ',8),f=a("code",null,"fallbacks",-1),g=p(": [ "),q=p("FallbackObject"),y=p(" ]"),v=p("An array that contains a series of powerful fallback configurations (optional). The specific configuration for "),j=a("code",null,"fallbacks",-1),S=p(" can be found in the "),w=p("FallbackObject"),U=p(" documentation."),x=c('

    ClientObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "level": 0,\n  "email": "love@xray.com",\n  "flow": "xtls-rprx-vision"\n}\n
    1
    2
    3
    4
    5
    6

    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")
    ',5),I=p("The mapping standard is described in the "),L={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},T=p("VLESS UUID Mapping Standard: Mapping a Custom String to a UUIDv5"),C=p("."),D=a("p",null,[p("You can use the command "),a("code",null,'xray uuid -i "custom string"'),p(" to generate the UUID corresponding to a custom string.")],-1),E=a("blockquote",null,[a("p",null,[p("You can also use the command "),a("code",null,"xray uuid"),p(" to generate a random UUID.")])],-1),O=a("blockquote",null,[a("p",null,[a("code",null,"level"),p(": number")])],-1),V=p("The user level that the connection will use to determine the corresponding "),X=p("Local Policy"),_=p("."),F=p("The value of "),P=a("code",null,"level",-1),A=p(" corresponds to the value of "),M=a("code",null,"level",-1),N=p(" in the "),Y=p("policy"),K=p(". If not specified, the default value is 0."),R=c("

    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.

    ",7);r.render=function(p,c){const r=n("RouterLink"),z=n("OutboundLink");return e(),s(l,null,[i,u,d,a("p",null,[b,o(r,{to:"/en/config/inbounds/vmess.html"},{default:t((()=>[h])),_:1}),m]),k,a("blockquote",null,[a("p",null,[f,g,o(r,{to:"/en/config/features/fallback.html"},{default:t((()=>[q])),_:1}),y])]),a("p",null,[v,j,S,o(r,{to:"/en/config/features/fallback.html#fallbacks-configuration"},{default:t((()=>[w])),_:1}),U]),x,a("p",null,[I,a("a",L,[T,o(z)]),C]),D,E,O,a("p",null,[V,o(r,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[X])),_:1}),_]),a("p",null,[F,P,A,M,N,o(r,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[Y])),_:1}),K]),R],64)};export default r; diff --git a/assets/vmess.html.66039f47.js b/assets/vmess.html.66039f47.js new file mode 100644 index 000000000..14a54f622 --- /dev/null +++ b/assets/vmess.html.66039f47.js @@ -0,0 +1 @@ +import{r as e,o as n,c as s,a,b as o,w as t,F as r,e as p,d as c}from"./app.48111a85.js";const u={},i=a("h1",{id:"vmess",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#vmess","aria-hidden":"true"},"#"),p(" VMess")],-1),l=p("VMess"),d=p(" is an encrypted transport protocol commonly used as a bridge between Xray clients and servers."),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

    {\n  "vnext": [\n    {\n      "address": "127.0.0.1",\n      "port": 37192,\n      "users": [\n        {\n          "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n          "security": "auto",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    vnext:[ ServerObject ]

    An array containing a set of server configurations.

    Each item in the array is a server configuration ServerObject.

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 37192,\n  "users": []\n}\n
    1
    2
    3
    4
    5

    address: address

    The server address, which can be an IP address or domain name.

    port: number

    The port number that the server is listening on. Required.

    users: [ UserObject ]

    An array representing a group of users authorized by the server.

    Each item is a user configuration UserObject.

    UserObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "security": "auto",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    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")
    ',21),m=p("The mapping standard is described in the "),b={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},q=p("VLESS UUID Mapping Standard: Mapping a Custom String to a UUIDv5"),k=p("."),y=a("p",null,[p("You can use the command "),a("code",null,'xray uuid -i "custom string"'),p(" to generate the UUID corresponding to a custom string, or use the command "),a("code",null,"xray uuid"),p(" to generate a random UUID.")],-1),g=a("blockquote",null,[a("p",null,[a("code",null,"level"),p(": number")])],-1),v=p("The user level. Connections will use the corresponding "),f=p("local policy"),j=p(" associated with this user level."),U=p("The "),w=a("code",null,"level",-1),T=p(" value corresponds to the "),x=a("code",null,"level",-1),I=p(" value in the "),D=p("policy"),O=p(". If not specified, the default value is 0."),S=c('

    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.

    ',4);u.render=function(p,c){const u=e("RouterLink"),z=e("OutboundLink");return n(),s(r,null,[i,a("p",null,[o(u,{to:"/en/development/protocols/vmess.html"},{default:t((()=>[l])),_:1}),d]),h,a("p",null,[m,a("a",b,[q,o(z)]),k]),y,g,a("p",null,[v,o(u,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[f])),_:1}),j]),a("p",null,[U,w,T,x,I,o(u,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[D])),_:1}),O]),S],64)};export default u; diff --git a/assets/vmess.html.906abd7c.js b/assets/vmess.html.906abd7c.js deleted file mode 100644 index b0e3ca64a..000000000 --- a/assets/vmess.html.906abd7c.js +++ /dev/null @@ -1 +0,0 @@ -import{r as e,o as n,c as s,a as o,b as a,w as t,F as r,e as p,d as c}from"./app.755d843f.js";const u={},i=o("h1",{id:"vmess",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#vmess","aria-hidden":"true"},"#"),p(" VMess")],-1),l=p("VMess"),d=p(" is an encrypted transport protocol commonly used as a bridge between Xray clients and servers."),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

    {\n  "vnext": [\n    {\n      "address": "127.0.0.1",\n      "port": 37192,\n      "users": [\n        {\n          "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n          "security": "auto",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    vnext:[ ServerObject ]

    An array containing a set of server configurations.

    Each item in the array is a server configuration ServerObject.

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 37192,\n  "users": []\n}\n
    1
    2
    3
    4
    5

    address: address

    The server address, which can be an IP address or domain name.

    port: number

    The port number that the server is listening on. Required.

    users: [ UserObject ]

    An array representing a group of users authorized by the server.

    Each item is a user configuration UserObject.

    UserObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "security": "auto",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    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")
    ',21),m=p("The mapping standard is described in the "),b={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},q=p("VLESS UUID Mapping Standard: Mapping a Custom String to a UUIDv5"),k=p("."),y=o("p",null,[p("You can use the command "),o("code",null,'xray uuid -i "custom string"'),p(" to generate the UUID corresponding to a custom string, or use the command "),o("code",null,"xray uuid"),p(" to generate a random UUID.")],-1),g=o("blockquote",null,[o("p",null,[o("code",null,"level"),p(": number")])],-1),v=p("The user level. Connections will use the corresponding "),f=p("local policy"),j=p(" associated with this user level."),U=p("The "),w=o("code",null,"level",-1),T=p(" value corresponds to the "),x=o("code",null,"level",-1),I=p(" value in the "),D=p("policy"),O=p(". If not specified, the default value is 0."),S=c('

    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.

    ',4);u.render=function(p,c){const u=e("RouterLink"),z=e("OutboundLink");return n(),s(r,null,[i,o("p",null,[a(u,{to:"/en/development/protocols/vmess.html"},{default:t((()=>[l])),_:1}),d]),h,o("p",null,[m,o("a",b,[q,a(z)]),k]),y,g,o("p",null,[v,a(u,{to:"/en/config/policy.html#levelpolicyobject"},{default:t((()=>[f])),_:1}),j]),o("p",null,[U,w,T,x,I,a(u,{to:"/en/config/policy.html#policyobject"},{default:t((()=>[D])),_:1}),O]),S],64)};export default u; diff --git a/assets/vmess.html.e7af9fe7.js b/assets/vmess.html.ae1d1f20.js similarity index 99% rename from assets/vmess.html.e7af9fe7.js rename to assets/vmess.html.ae1d1f20.js index d6b04af71..2a35436c1 100644 --- a/assets/vmess.html.e7af9fe7.js +++ b/assets/vmess.html.ae1d1f20.js @@ -1 +1 @@ -import{r as s,o as n,c as a,a as e,b as o,w as t,F as p,e as c,d as u}from"./app.755d843f.js";const l={},r=e("h1",{id:"vmess",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vmess","aria-hidden":"true"},"#"),c(" VMess")],-1),i=c("VMess"),d=c(" 是一个加密传输协议,通常作为 Xray 客户端和服务器之间的桥梁。"),b=u('

    警告

    VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 120 秒之内,时区无关。在 Linux 系统中可以安装ntp服务来自动同步系统时间。

    OutboundConfigurationObject

    {\n  "vnext": [\n    {\n      "address": "127.0.0.1",\n      "port": 37192,\n      "users": [\n        {\n          "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n          "security": "auto",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    vnext:[ ServerObject ]

    一个数组,包含一组的服务端配置.

    其中每一项是一个服务端配置ServerObject

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 37192,\n  "users": []\n}\n
    1
    2
    3
    4
    5

    address: address

    服务端地址,支持 IP 地址或者域名。

    port: number

    服务端监听的端口号, 必填。

    users: [ UserObject ]

    一个数组,代表一组服务端认可的用户.

    其中每一项是一个用户UserObject

    UserObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "security": "auto",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    id:string

    Vmess 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID.

    自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)
    ',21),q=c("其映射标准在 "),k={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},m=c("VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5"),h=e("p",null,[c("你可以使用命令 "),e("code",null,'xray uuid -i "自定义字符串"'),c(" 生成自定义字符串所映射的的 UUID, 也可以使用命令 "),e("code",null,"xray uuid"),c(" 生成随机的 UUID。")],-1),v=e("blockquote",null,[e("p",null,[e("code",null,"level"),c(": number")])],-1),g=c("用户等级,连接会使用这个用户等级对应的 "),j=c("本地策略"),y=c("。"),f=c("level 的值, 对应 "),U=c("policy"),x=c(" 中 "),D=e("code",null,"level",-1),I=c(" 的值。 如不指定, 默认为 0。"),O=u('

    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 的包头都会受到加密和认证的保护。

    ',5);l.render=function(c,u){const l=s("RouterLink"),S=s("OutboundLink");return n(),a(p,null,[r,e("p",null,[o(l,{to:"/development/protocols/vmess.html"},{default:t((()=>[i])),_:1}),d]),b,e("p",null,[q,e("a",k,[m,o(S)])]),h,v,e("p",null,[g,o(l,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[j])),_:1}),y]),e("p",null,[f,o(l,{to:"/config/policy.html#policyobject"},{default:t((()=>[U])),_:1}),x,D,I]),O],64)};export default l; +import{r as s,o as n,c as a,a as e,b as o,w as t,F as p,e as c,d as u}from"./app.48111a85.js";const l={},r=e("h1",{id:"vmess",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vmess","aria-hidden":"true"},"#"),c(" VMess")],-1),i=c("VMess"),d=c(" 是一个加密传输协议,通常作为 Xray 客户端和服务器之间的桥梁。"),b=u('

    警告

    VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 120 秒之内,时区无关。在 Linux 系统中可以安装ntp服务来自动同步系统时间。

    OutboundConfigurationObject

    {\n  "vnext": [\n    {\n      "address": "127.0.0.1",\n      "port": 37192,\n      "users": [\n        {\n          "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n          "security": "auto",\n          "level": 0\n        }\n      ]\n    }\n  ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    vnext:[ ServerObject ]

    一个数组,包含一组的服务端配置.

    其中每一项是一个服务端配置ServerObject

    ServerObject

    {\n  "address": "127.0.0.1",\n  "port": 37192,\n  "users": []\n}\n
    1
    2
    3
    4
    5

    address: address

    服务端地址,支持 IP 地址或者域名。

    port: number

    服务端监听的端口号, 必填。

    users: [ UserObject ]

    一个数组,代表一组服务端认可的用户.

    其中每一项是一个用户UserObject

    UserObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "security": "auto",\n  "level": 0\n}\n
    1
    2
    3
    4
    5

    id:string

    Vmess 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID.

    自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)
    ',21),q=c("其映射标准在 "),k={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},m=c("VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5"),h=e("p",null,[c("你可以使用命令 "),e("code",null,'xray uuid -i "自定义字符串"'),c(" 生成自定义字符串所映射的的 UUID, 也可以使用命令 "),e("code",null,"xray uuid"),c(" 生成随机的 UUID。")],-1),v=e("blockquote",null,[e("p",null,[e("code",null,"level"),c(": number")])],-1),g=c("用户等级,连接会使用这个用户等级对应的 "),j=c("本地策略"),y=c("。"),f=c("level 的值, 对应 "),U=c("policy"),x=c(" 中 "),D=e("code",null,"level",-1),I=c(" 的值。 如不指定, 默认为 0。"),O=u('

    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 的包头都会受到加密和认证的保护。

    ',5);l.render=function(c,u){const l=s("RouterLink"),S=s("OutboundLink");return n(),a(p,null,[r,e("p",null,[o(l,{to:"/development/protocols/vmess.html"},{default:t((()=>[i])),_:1}),d]),b,e("p",null,[q,e("a",k,[m,o(S)])]),h,v,e("p",null,[g,o(l,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[j])),_:1}),y]),e("p",null,[f,o(l,{to:"/config/policy.html#policyobject"},{default:t((()=>[U])),_:1}),x,D,I]),O],64)};export default l; diff --git a/assets/vmess.html.39809dda.js b/assets/vmess.html.e111b233.js similarity index 99% rename from assets/vmess.html.39809dda.js rename to assets/vmess.html.e111b233.js index ec3563abf..544d03416 100644 --- a/assets/vmess.html.39809dda.js +++ b/assets/vmess.html.e111b233.js @@ -1 +1 @@ -import{r as t,o as e,c as a,a as n,b as i,F as r,d as l,e as s}from"./app.755d843f.js";const d={},h=l('

    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),o=s("An ID is equivalent to a "),c={href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",target:"_blank",rel:"noopener noreferrer"},u=s("UUID"),y=s(", which is a 16-byte long random number. Its function is similar to a token. An ID looks like: "),p=n("code",null,"de305d54-75b4-431b-adb2-eb6b9e546014",-1),m=s(", it is almost entirely random and can be generated using any UUID generator, such as "),b={href:"https://www.uuidgenerator.net/",target:"_blank",rel:"noopener noreferrer"},f=s("this one"),g=s("."),x=n("p",null,[s("User ID can be specified in the "),n("a",{href:"../../config"},"configuration file"),s(".")],-1),v=n("h3",{id:"functions",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#functions","aria-hidden":"true"},"#"),s(" Functions")],-1),k=s("MD5: "),M={href:"https://en.wikipedia.org/wiki/MD5",target:"_blank",rel:"noopener noreferrer"},B=s("MD5 Function"),I=n("ul",null,[n("li",null,"Input parameter is any length byte array"),n("li",null,"Output is a 16-byte array")],-1),w=s("HMAC: "),C={href:"https://en.wikipedia.org/wiki/Hash-based_message_authentication_code",target:"_blank",rel:"noopener noreferrer"},A=s("HMAC Function"),D=n("ul",null,[n("li",null,[s("Input parameters are: "),n("ul",null,[n("li",null,"H: Hash function"),n("li",null,"K: Key, any length byte array"),n("li",null,"M: Message, any length byte array")])])],-1),V=s("Shake: "),P={href:"https://en.wikipedia.org/wiki/SHA-3",target:"_blank",rel:"noopener noreferrer"},R=s("SHA3-Shake128 Function"),T=n("ul",null,[n("li",null,"Input parameter is any length string"),n("li",null,"Output is any length string")],-1),S=l('

    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

    其中:

    • 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);d.render=function(l,s){const d=t("OutboundLink");return e(),a(r,null,[h,n("p",null,[o,n("a",c,[u,i(d)]),y,p,m,n("a",b,[f,i(d)]),g]),x,v,n("ul",null,[n("li",null,[k,n("a",M,[B,i(d)]),I]),n("li",null,[w,n("a",C,[A,i(d)]),D]),n("li",null,[V,n("a",P,[R,i(d)]),T])]),S],64)};export default d; +import{r as t,o as e,c as a,a as n,b as i,F as r,d as l,e as s}from"./app.48111a85.js";const d={},h=l('

    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),o=s("An ID is equivalent to a "),c={href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",target:"_blank",rel:"noopener noreferrer"},u=s("UUID"),y=s(", which is a 16-byte long random number. Its function is similar to a token. An ID looks like: "),p=n("code",null,"de305d54-75b4-431b-adb2-eb6b9e546014",-1),m=s(", it is almost entirely random and can be generated using any UUID generator, such as "),b={href:"https://www.uuidgenerator.net/",target:"_blank",rel:"noopener noreferrer"},f=s("this one"),g=s("."),x=n("p",null,[s("User ID can be specified in the "),n("a",{href:"../../config"},"configuration file"),s(".")],-1),v=n("h3",{id:"functions",tabindex:"-1"},[n("a",{class:"header-anchor",href:"#functions","aria-hidden":"true"},"#"),s(" Functions")],-1),k=s("MD5: "),M={href:"https://en.wikipedia.org/wiki/MD5",target:"_blank",rel:"noopener noreferrer"},B=s("MD5 Function"),I=n("ul",null,[n("li",null,"Input parameter is any length byte array"),n("li",null,"Output is a 16-byte array")],-1),w=s("HMAC: "),C={href:"https://en.wikipedia.org/wiki/Hash-based_message_authentication_code",target:"_blank",rel:"noopener noreferrer"},A=s("HMAC Function"),D=n("ul",null,[n("li",null,[s("Input parameters are: "),n("ul",null,[n("li",null,"H: Hash function"),n("li",null,"K: Key, any length byte array"),n("li",null,"M: Message, any length byte array")])])],-1),V=s("Shake: "),P={href:"https://en.wikipedia.org/wiki/SHA-3",target:"_blank",rel:"noopener noreferrer"},R=s("SHA3-Shake128 Function"),T=n("ul",null,[n("li",null,"Input parameter is any length string"),n("li",null,"Output is any length string")],-1),S=l('

    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

    其中:

    • 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);d.render=function(l,s){const d=t("OutboundLink");return e(),a(r,null,[h,n("p",null,[o,n("a",c,[u,i(d)]),y,p,m,n("a",b,[f,i(d)]),g]),x,v,n("ul",null,[n("li",null,[k,n("a",M,[B,i(d)]),I]),n("li",null,[w,n("a",C,[A,i(d)]),D]),n("li",null,[V,n("a",P,[R,i(d)]),T])]),S],64)};export default d; diff --git a/assets/vmess.html.deaa5626.js b/assets/vmess.html.ed9311ef.js similarity index 99% rename from assets/vmess.html.deaa5626.js rename to assets/vmess.html.ed9311ef.js index 48fb3cd80..fff4ab76d 100644 --- a/assets/vmess.html.deaa5626.js +++ b/assets/vmess.html.ed9311ef.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as o,w as t,F as p,e as l,d as c}from"./app.755d843f.js";const u={},r=e("h1",{id:"vmess",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vmess","aria-hidden":"true"},"#"),l(" VMess")],-1),i=l("VMess"),d=l(" 是一个加密传输协议,通常作为 Xray 客户端和服务器之间的桥梁。"),b=c('

    警告

    VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 120 秒之内,时区无关。在 Linux 系统中可以安装ntp服务来自动同步系统时间。

    InboundConfigurationObject

    {\n  "clients": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "level": 0,\n      "email": "love@xray.com"\n    }\n  ],\n  "default": {\n    "level": 0\n  },\n  "detour": {\n    "to": "tag_to_detour"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    clients: [ ClientObject ]

    一个数组,代表一组服务端认可的用户.

    其中每一项是一个用户ClientObject

    当此配置用作动态端口时,Xray 会自动创建用户。

    detour: DetourObject

    指示对应的出站协议使用另一个服务器。

    default: DefaultObject

    可选,clients 的默认配置。仅在配合detour时有效。

    ClientObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "level": 0,\n  "email": "love@xray.com"\n}\n
    1
    2
    3
    4
    5

    id: string

    Vmess 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID.

    提示

    自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)
    ',16),k=l("其映射标准在 "),m={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},q=l("VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5"),h=e("p",null,[l("你可以使用命令 "),e("code",null,'xray uuid -i "自定义字符串"'),l(" 生成自定义字符串所映射的的 UUID。")],-1),v=e("blockquote",null,[e("p",null,[l("也可以使用命令 "),e("code",null,"xray uuid"),l(" 生成随机的 UUID.")])],-1),g=e("blockquote",null,[e("p",null,[e("code",null,"level"),l(": number")])],-1),j=l("用户等级,连接会使用这个用户等级对应的 "),f=l("本地策略"),y=l("。"),U=l("level 的值, 对应 "),x=l("policy"),D=l(" 中 "),I=e("code",null,"level",-1),_=l(" 的值。 如不指定, 默认为 0。"),O=c('

    email: string

    用户邮箱地址,用于区分不同用户的流量。

    DetourObject

    {\n  "to": "tag_to_detour"\n}\n
    1
    2
    3

    to: string

    一个 inbound 的tag, 指定的 inbound 的必须是使用 VMess 协议的 inbound.

    DefaultObject

    {\n  "level": 0\n}\n
    1
    2
    3

    level: number

    ',9),V=l("用户等级,连接会使用这个用户等级对应的 "),C=l("本地策略"),L=l("。"),X=l("level 的值, 对应 "),M=l("policy"),S=l(" 中 "),T=e("code",null,"level",-1),w=l(" 的值。 如不指定, 默认为 0。");u.render=function(l,c){const u=n("RouterLink"),E=n("OutboundLink");return s(),a(p,null,[r,e("p",null,[o(u,{to:"/development/protocols/vmess.html"},{default:t((()=>[i])),_:1}),d]),b,e("p",null,[k,e("a",m,[q,o(E)])]),h,v,g,e("p",null,[j,o(u,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[f])),_:1}),y]),e("p",null,[U,o(u,{to:"/config/policy.html#policyobject"},{default:t((()=>[x])),_:1}),D,I,_]),O,e("p",null,[V,o(u,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[C])),_:1}),L]),e("p",null,[X,o(u,{to:"/config/policy.html#policyobject"},{default:t((()=>[M])),_:1}),S,T,w])],64)};export default u; +import{r as n,o as s,c as a,a as e,b as o,w as t,F as p,e as l,d as c}from"./app.48111a85.js";const u={},r=e("h1",{id:"vmess",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#vmess","aria-hidden":"true"},"#"),l(" VMess")],-1),i=l("VMess"),d=l(" 是一个加密传输协议,通常作为 Xray 客户端和服务器之间的桥梁。"),b=c('

    警告

    VMess 依赖于系统时间,请确保使用 Xray 的系统 UTC 时间误差在 120 秒之内,时区无关。在 Linux 系统中可以安装ntp服务来自动同步系统时间。

    InboundConfigurationObject

    {\n  "clients": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "level": 0,\n      "email": "love@xray.com"\n    }\n  ],\n  "default": {\n    "level": 0\n  },\n  "detour": {\n    "to": "tag_to_detour"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    clients: [ ClientObject ]

    一个数组,代表一组服务端认可的用户.

    其中每一项是一个用户ClientObject

    当此配置用作动态端口时,Xray 会自动创建用户。

    detour: DetourObject

    指示对应的出站协议使用另一个服务器。

    default: DefaultObject

    可选,clients 的默认配置。仅在配合detour时有效。

    ClientObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "level": 0,\n  "email": "love@xray.com"\n}\n
    1
    2
    3
    4
    5

    id: string

    Vmess 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID.

    提示

    自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)
    ',16),k=l("其映射标准在 "),m={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},q=l("VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5"),h=e("p",null,[l("你可以使用命令 "),e("code",null,'xray uuid -i "自定义字符串"'),l(" 生成自定义字符串所映射的的 UUID。")],-1),v=e("blockquote",null,[e("p",null,[l("也可以使用命令 "),e("code",null,"xray uuid"),l(" 生成随机的 UUID.")])],-1),g=e("blockquote",null,[e("p",null,[e("code",null,"level"),l(": number")])],-1),j=l("用户等级,连接会使用这个用户等级对应的 "),f=l("本地策略"),y=l("。"),U=l("level 的值, 对应 "),x=l("policy"),D=l(" 中 "),I=e("code",null,"level",-1),_=l(" 的值。 如不指定, 默认为 0。"),O=c('

    email: string

    用户邮箱地址,用于区分不同用户的流量。

    DetourObject

    {\n  "to": "tag_to_detour"\n}\n
    1
    2
    3

    to: string

    一个 inbound 的tag, 指定的 inbound 的必须是使用 VMess 协议的 inbound.

    DefaultObject

    {\n  "level": 0\n}\n
    1
    2
    3

    level: number

    ',9),V=l("用户等级,连接会使用这个用户等级对应的 "),C=l("本地策略"),L=l("。"),X=l("level 的值, 对应 "),M=l("policy"),S=l(" 中 "),T=e("code",null,"level",-1),w=l(" 的值。 如不指定, 默认为 0。");u.render=function(l,c){const u=n("RouterLink"),E=n("OutboundLink");return s(),a(p,null,[r,e("p",null,[o(u,{to:"/development/protocols/vmess.html"},{default:t((()=>[i])),_:1}),d]),b,e("p",null,[k,e("a",m,[q,o(E)])]),h,v,g,e("p",null,[j,o(u,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[f])),_:1}),y]),e("p",null,[U,o(u,{to:"/config/policy.html#policyobject"},{default:t((()=>[x])),_:1}),D,I,_]),O,e("p",null,[V,o(u,{to:"/config/policy.html#levelpolicyobject"},{default:t((()=>[C])),_:1}),L]),e("p",null,[X,o(u,{to:"/config/policy.html#policyobject"},{default:t((()=>[M])),_:1}),S,T,w])],64)};export default u; diff --git a/assets/vmess.html.d7593e24.js b/assets/vmess.html.ee639091.js similarity index 99% rename from assets/vmess.html.d7593e24.js rename to assets/vmess.html.ee639091.js index 2259f3466..33868ae53 100644 --- a/assets/vmess.html.d7593e24.js +++ b/assets/vmess.html.ee639091.js @@ -1 +1 @@ -import{r as n,o as e,c as s,a,b as t,w as o,F as l,e as p,d as c}from"./app.755d843f.js";const r={},u=a("h1",{id:"vmess",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#vmess","aria-hidden":"true"},"#"),p(" VMess")],-1),i=p("VMess"),d=p(" is an encrypted transport protocol that is commonly used as a bridge between Xray clients and servers."),b=c('

    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

    {\n  "clients": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "level": 0,\n      "email": "love@xray.com"\n    }\n  ],\n  "default": {\n    "level": 0\n  },\n  "detour": {\n    "to": "tag_to_detour"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    clients: [ ClientObject ]

    An array representing a group of users approved by the server.

    Each item in the array is a user ClientObject.

    When this configuration is used for dynamic ports, Xray will automatically create users.

    detour: DetourObject

    Indicates that another server should be used for the corresponding outbound protocol.

    default: DefaultObject

    Optional. The default configuration for clients. Only effective when used with detour.

    ClientObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "level": 0,\n  "email": "love@xray.com"\n}\n
    1
    2
    3
    4
    5

    id: string

    The user ID for VMess. It can be any string less than 30 bytes or a valid UUID.

    ',15),h={class:"custom-container tip"},m=a("p",{class:"custom-container-title"},"Tip",-1),k=a("p",null,"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:",-1),f=a("ul",null,[a("li",null,[a("code",null,'"id": "我爱🍉老师1314"')]),a("li",null,[a("code",null,'"id": "5783a3e7-e373-51cd-8642-c83782b807c5"'),p(' (This UUID is the mapping of the string "我爱 🍉 老师 1314")')])],-1),g=p("The mapping standard is described in the "),q={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},v=p("VLESS UUID Mapping Standard: Mapping a Custom String to a UUIDv5"),y=p("."),j=a("p",null,[p("You can use the command "),a("code",null,'xray uuid -i "custom string"'),p(" to generate the UUID corresponding to a custom string.")],-1),x=a("p",null,[p("You can also use the command "),a("code",null,"xray uuid"),p(" to generate a random UUID. :::")],-1),U=a("blockquote",null,[a("p",null,[a("code",null,"level"),p(": number")])],-1),D=p("The user level that the connection will use to determine the corresponding "),I=p("Local Policy"),T=p("."),O=p("The value of "),w=a("code",null,"level",-1),_=p(" corresponds to the value of "),C=a("code",null,"level",-1),L=p(" in the "),M=p("policy"),V=p(". If not specified, the default value is 0."),S=c('

    email: string

    The user's email address, used to differentiate traffic from different users.

    DetourObject

    {\n  "to": "tag_to_detour"\n}\n
    1
    2
    3

    to: string

    The tag of an inbound that specifies the inbound using the VMess protocol.

    DefaultObject

    {\n  "level": 0\n}\n
    1
    2
    3

    level: number

    ',9),X=p("The user level that the connection will use to determine the corresponding "),P=p("Local Policy"),z=p("."),E=p("The value of "),Y=a("code",null,"level",-1),A=p(" corresponds to the value of "),F=a("code",null,"level",-1),R=p(" in the "),W=p("policy"),B=p(". If not specified, the default value is 0.");r.render=function(p,c){const r=n("RouterLink"),G=n("OutboundLink");return e(),s(l,null,[u,a("p",null,[t(r,{to:"/en/development/protocols/vmess.html"},{default:o((()=>[i])),_:1}),d]),b,a("div",h,[m,k,f,a("p",null,[g,a("a",q,[v,t(G)]),y]),j,x,U,a("p",null,[D,t(r,{to:"/en/config/policy.html#levelpolicyobject"},{default:o((()=>[I])),_:1}),T]),a("p",null,[O,w,_,C,L,t(r,{to:"/en/config/policy.html#policyobject"},{default:o((()=>[M])),_:1}),V]),S,a("p",null,[X,t(r,{to:"/en/config/policy.html#levelpolicyobject"},{default:o((()=>[P])),_:1}),z]),a("p",null,[E,Y,A,F,R,t(r,{to:"/en/config/policy.html#policyobject"},{default:o((()=>[W])),_:1}),B])])],64)};export default r; +import{r as n,o as e,c as s,a,b as t,w as o,F as l,e as p,d as c}from"./app.48111a85.js";const r={},u=a("h1",{id:"vmess",tabindex:"-1"},[a("a",{class:"header-anchor",href:"#vmess","aria-hidden":"true"},"#"),p(" VMess")],-1),i=p("VMess"),d=p(" is an encrypted transport protocol that is commonly used as a bridge between Xray clients and servers."),b=c('

    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

    {\n  "clients": [\n    {\n      "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n      "level": 0,\n      "email": "love@xray.com"\n    }\n  ],\n  "default": {\n    "level": 0\n  },\n  "detour": {\n    "to": "tag_to_detour"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    clients: [ ClientObject ]

    An array representing a group of users approved by the server.

    Each item in the array is a user ClientObject.

    When this configuration is used for dynamic ports, Xray will automatically create users.

    detour: DetourObject

    Indicates that another server should be used for the corresponding outbound protocol.

    default: DefaultObject

    Optional. The default configuration for clients. Only effective when used with detour.

    ClientObject

    {\n  "id": "5783a3e7-e373-51cd-8642-c83782b807c5",\n  "level": 0,\n  "email": "love@xray.com"\n}\n
    1
    2
    3
    4
    5

    id: string

    The user ID for VMess. It can be any string less than 30 bytes or a valid UUID.

    ',15),h={class:"custom-container tip"},m=a("p",{class:"custom-container-title"},"Tip",-1),k=a("p",null,"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:",-1),f=a("ul",null,[a("li",null,[a("code",null,'"id": "我爱🍉老师1314"')]),a("li",null,[a("code",null,'"id": "5783a3e7-e373-51cd-8642-c83782b807c5"'),p(' (This UUID is the mapping of the string "我爱 🍉 老师 1314")')])],-1),g=p("The mapping standard is described in the "),q={href:"https://github.com/XTLS/Xray-core/issues/158",target:"_blank",rel:"noopener noreferrer"},v=p("VLESS UUID Mapping Standard: Mapping a Custom String to a UUIDv5"),y=p("."),j=a("p",null,[p("You can use the command "),a("code",null,'xray uuid -i "custom string"'),p(" to generate the UUID corresponding to a custom string.")],-1),x=a("p",null,[p("You can also use the command "),a("code",null,"xray uuid"),p(" to generate a random UUID. :::")],-1),U=a("blockquote",null,[a("p",null,[a("code",null,"level"),p(": number")])],-1),D=p("The user level that the connection will use to determine the corresponding "),I=p("Local Policy"),T=p("."),O=p("The value of "),w=a("code",null,"level",-1),_=p(" corresponds to the value of "),C=a("code",null,"level",-1),L=p(" in the "),M=p("policy"),V=p(". If not specified, the default value is 0."),S=c('

    email: string

    The user's email address, used to differentiate traffic from different users.

    DetourObject

    {\n  "to": "tag_to_detour"\n}\n
    1
    2
    3

    to: string

    The tag of an inbound that specifies the inbound using the VMess protocol.

    DefaultObject

    {\n  "level": 0\n}\n
    1
    2
    3

    level: number

    ',9),X=p("The user level that the connection will use to determine the corresponding "),P=p("Local Policy"),z=p("."),E=p("The value of "),Y=a("code",null,"level",-1),A=p(" corresponds to the value of "),F=a("code",null,"level",-1),R=p(" in the "),W=p("policy"),B=p(". If not specified, the default value is 0.");r.render=function(p,c){const r=n("RouterLink"),G=n("OutboundLink");return e(),s(l,null,[u,a("p",null,[t(r,{to:"/en/development/protocols/vmess.html"},{default:o((()=>[i])),_:1}),d]),b,a("div",h,[m,k,f,a("p",null,[g,a("a",q,[v,t(G)]),y]),j,x,U,a("p",null,[D,t(r,{to:"/en/config/policy.html#levelpolicyobject"},{default:o((()=>[I])),_:1}),T]),a("p",null,[O,w,_,C,L,t(r,{to:"/en/config/policy.html#policyobject"},{default:o((()=>[M])),_:1}),V]),S,a("p",null,[X,t(r,{to:"/en/config/policy.html#levelpolicyobject"},{default:o((()=>[P])),_:1}),z]),a("p",null,[E,Y,A,F,R,t(r,{to:"/en/config/policy.html#policyobject"},{default:o((()=>[W])),_:1}),B])])],64)};export default r; diff --git a/assets/vmess.html.172c5ae5.js b/assets/vmess.html.f1a5f655.js similarity index 99% rename from assets/vmess.html.172c5ae5.js rename to assets/vmess.html.f1a5f655.js index 2aec41c14..b8cb30457 100644 --- a/assets/vmess.html.172c5ae5.js +++ b/assets/vmess.html.f1a5f655.js @@ -1 +1 @@ -import{r as t,o as e,c as l,a as i,b as a,F as n,d as r,e as h}from"./app.755d843f.js";const d={},s=r('

    VMess 协议

    VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

    版本

    当前版本号为 1。

    依赖

    底层协议

    VMess 是一个基于 TCP 的协议,所有数据使用 TCP 传输。

    用户 ID

    ',8),u=h("ID 等价于 "),c={href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",target:"_blank",rel:"noopener noreferrer"},y=h("UUID"),x=h(",是一个 16 字节长的随机数,它的作用相当于一个令牌(Token)。 一个 ID 形如:de305d54-75b4-431b-adb2-eb6b9e546014,几乎完全随机,可以使用任何的 UUID 生成器来生成,比如"),o={href:"https://www.uuidgenerator.net/",target:"_blank",rel:"noopener noreferrer"},p=h("这个"),g=h("。"),b=i("p",null,[h("用户 ID 可在"),i("a",{href:"../../config"},"配置文件"),h("中指定。")],-1),M=i("h3",{id:"函数",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#函数","aria-hidden":"true"},"#"),h(" 函数")],-1),f=h("MD5: "),k={href:"https://en.wikipedia.org/wiki/MD5",target:"_blank",rel:"noopener noreferrer"},V=h("MD5 函数"),I=i("ul",null,[i("li",null,"输入参数为任意长度的 byte 数组"),i("li",null,"输出为一个 16 byte 的数组")],-1),C=h("HMAC: "),D={href:"https://en.wikipedia.org/wiki/Hash-based_message_authentication_code",target:"_blank",rel:"noopener noreferrer"},P=h("HMAC 函数"),S=i("ul",null,[i("li",null,[h("输入参数为: "),i("ul",null,[i("li",null,"H:散列函数"),i("li",null,"K:密钥,任意长度的 byte 数组"),i("li",null,"M:消息,任意长度的 byte 数组")])])],-1),A=h("Shake: "),T={href:"https://en.wikipedia.org/wiki/SHA-3",target:"_blank",rel:"noopener noreferrer"},X=h("SHA3-Shake128 函数"),B=i("ul",null,[i("li",null,"输入参数为任意长度的字符串"),i("li",null,"输出为任意长度的字符串")],-1),K=r('

    通讯过程

    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);d.render=function(r,h){const d=t("OutboundLink");return e(),l(n,null,[s,i("p",null,[u,i("a",c,[y,a(d)]),x,i("a",o,[p,a(d)]),g]),b,M,i("ul",null,[i("li",null,[f,i("a",k,[V,a(d)]),I]),i("li",null,[C,i("a",D,[P,a(d)]),S]),i("li",null,[A,i("a",T,[X,a(d)]),B])]),K],64)};export default d; +import{r as t,o as e,c as l,a as i,b as a,F as n,d as r,e as h}from"./app.48111a85.js";const d={},s=r('

    VMess 协议

    VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

    版本

    当前版本号为 1。

    依赖

    底层协议

    VMess 是一个基于 TCP 的协议,所有数据使用 TCP 传输。

    用户 ID

    ',8),u=h("ID 等价于 "),c={href:"https://en.wikipedia.org/wiki/Universally_unique_identifier",target:"_blank",rel:"noopener noreferrer"},y=h("UUID"),x=h(",是一个 16 字节长的随机数,它的作用相当于一个令牌(Token)。 一个 ID 形如:de305d54-75b4-431b-adb2-eb6b9e546014,几乎完全随机,可以使用任何的 UUID 生成器来生成,比如"),o={href:"https://www.uuidgenerator.net/",target:"_blank",rel:"noopener noreferrer"},p=h("这个"),g=h("。"),b=i("p",null,[h("用户 ID 可在"),i("a",{href:"../../config"},"配置文件"),h("中指定。")],-1),M=i("h3",{id:"函数",tabindex:"-1"},[i("a",{class:"header-anchor",href:"#函数","aria-hidden":"true"},"#"),h(" 函数")],-1),f=h("MD5: "),k={href:"https://en.wikipedia.org/wiki/MD5",target:"_blank",rel:"noopener noreferrer"},V=h("MD5 函数"),I=i("ul",null,[i("li",null,"输入参数为任意长度的 byte 数组"),i("li",null,"输出为一个 16 byte 的数组")],-1),C=h("HMAC: "),D={href:"https://en.wikipedia.org/wiki/Hash-based_message_authentication_code",target:"_blank",rel:"noopener noreferrer"},P=h("HMAC 函数"),S=i("ul",null,[i("li",null,[h("输入参数为: "),i("ul",null,[i("li",null,"H:散列函数"),i("li",null,"K:密钥,任意长度的 byte 数组"),i("li",null,"M:消息,任意长度的 byte 数组")])])],-1),A=h("Shake: "),T={href:"https://en.wikipedia.org/wiki/SHA-3",target:"_blank",rel:"noopener noreferrer"},X=h("SHA3-Shake128 函数"),B=i("ul",null,[i("li",null,"输入参数为任意长度的字符串"),i("li",null,"输出为任意长度的字符串")],-1),K=r('

    通讯过程

    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);d.render=function(r,h){const d=t("OutboundLink");return e(),l(n,null,[s,i("p",null,[u,i("a",c,[y,a(d)]),x,i("a",o,[p,a(d)]),g]),b,M,i("ul",null,[i("li",null,[f,i("a",k,[V,a(d)]),I]),i("li",null,[C,i("a",D,[P,a(d)]),S]),i("li",null,[A,i("a",T,[X,a(d)]),B])]),K],64)};export default d; diff --git a/assets/warp.html.09cd5ef1.js b/assets/warp.html.63d5102a.js similarity index 99% rename from assets/warp.html.09cd5ef1.js rename to assets/warp.html.63d5102a.js index 9c4574237..1bf5c1099 100644 --- a/assets/warp.html.09cd5ef1.js +++ b/assets/warp.html.63d5102a.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as e,b as p,F as t,e as o,d as r}from"./app.755d843f.js";const l={},u=e("h1",{id:"enhancing-proxy-security-with-cloudflare-warp",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#enhancing-proxy-security-with-cloudflare-warp","aria-hidden":"true"},"#"),o(" Enhancing Proxy Security with Cloudflare Warp")],-1),c=e("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),i=o("Through recent discussions and "),b={href:"https://github.com/net4people/bbs/issues/129#issuecomment-1308102504",target:"_blank",rel:"noopener noreferrer"},k=o("experiments"),d=o(", 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."),m=e("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),q=e("li",null,"It is easy to use, and only one core is needed to complete the split, Wireguard Tun, and chain proxy settings.",-1),g=e("h2",{id:"applying-for-a-warp-account",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#applying-for-a-warp-account","aria-hidden":"true"},"#"),o(" Applying for a Warp Account")],-1),h=e("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),y=o("Use a VPS and download "),f={href:"https://github.com/ViRb3/wgcf/releases",target:"_blank",rel:"noopener noreferrer"},w=o("wgcf"),v=o("."),x=e("li",null,[o("Run "),e("code",null,"wgcf register"),o(" to generate "),e("code",null,"wgcf-account.toml"),o(".")],-1),W=e("li",null,[o("Run "),e("code",null,"wgcf generate"),o(" to generate "),e("code",null,"wgcf-profile.conf"),o(". Copy the following content:")],-1),P=r('
    [Interface]\nPrivateKey = my private key\nAddress = 172.16.0.2/32\nAddress = 2606:4700:110:8949:fed8:2642:a640:c8e1/128\nDNS = 1.1.1.1\nMTU = 1280\n[Peer]\nPublicKey = Warp public key\nAllowedIPs = 0.0.0.0/0\nAllowedIPs = ::/0\nEndpoint = engage.cloudflareclient.com:2408\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    Diverting inbound traffic to warp on the server side

    Add a new WireGuard outbound in the existing ones.

    {\n  "protocol": "wireguard",\n  "settings": {\n    "secretKey": "My private key",\n    "address": ["172.16.0.2/32", "2606:4700:110:8949:fed8:2642:a640:c8e1/128"],\n    "peers": [\n      {\n        "publicKey": "Warp public key",\n        "endpoint": "engage.cloudflareclient.com:2408"\n      }\n    ]\n  },\n  "tag": "wireguard-1"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    Recommended routing strategy is IPIfNonMatch.

    Add the following to the existing router:

                {\n                "type": "field",\n                "domain": [\n                    "geosite:cn"\n                ],\n                "outboundTag": "wireguard-1"\n            },\n            {\n                "type": "field",\n                "ip": [\n                    "geoip:cn"\n                ],\n                "outboundTag": "wireguard-1"\n            },\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    Using Warp Chain Proxy on the Client Side

    {\n   "outbounds":[\n      {\n         "protocol":"wireguard",\n         "settings":{\n            "secretKey":"My private key",\n            "peers":[\n               {\n                  "publicKey":"Warp public key",\n                  "endpoint":"engage.cloudflareclient.com:2408"\n               }\n            ]\n         },\n         "streamSettings":{\n            "sockopt":{\n               "dialerProxy":"proxy"\n            }\n         },\n         "tag":"wireguard-1"\n      },\n      {\n         "tag":"proxy",\n         "protocol":"vmess",\n         "settings":{\n            "vnext":[\n               {\n                  "address":"My IP",\n                  "port":My port,\n                  "users":[\n                     {\n                        "id":"My UUID",\n                        "security":"auto"\n                     }\n                  ]\n               }\n            ]\n         },\n         "streamSettings":{\n            "network":"tcp"\n         }\n      }\n   ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    ',9);l.render=function(o,r){const l=n("OutboundLink");return s(),a(t,null,[u,c,e("ol",null,[e("li",null,[i,e("a",b,[k,p(l)]),d]),m,q]),g,e("ol",null,[h,e("li",null,[y,e("a",f,[w,p(l)]),v]),x,W]),P],64)};export default l; +import{r as n,o as s,c as a,a as e,b as p,F as t,e as o,d as r}from"./app.48111a85.js";const l={},u=e("h1",{id:"enhancing-proxy-security-with-cloudflare-warp",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#enhancing-proxy-security-with-cloudflare-warp","aria-hidden":"true"},"#"),o(" Enhancing Proxy Security with Cloudflare Warp")],-1),c=e("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),i=o("Through recent discussions and "),b={href:"https://github.com/net4people/bbs/issues/129#issuecomment-1308102504",target:"_blank",rel:"noopener noreferrer"},k=o("experiments"),d=o(", 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."),m=e("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),q=e("li",null,"It is easy to use, and only one core is needed to complete the split, Wireguard Tun, and chain proxy settings.",-1),g=e("h2",{id:"applying-for-a-warp-account",tabindex:"-1"},[e("a",{class:"header-anchor",href:"#applying-for-a-warp-account","aria-hidden":"true"},"#"),o(" Applying for a Warp Account")],-1),h=e("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),y=o("Use a VPS and download "),f={href:"https://github.com/ViRb3/wgcf/releases",target:"_blank",rel:"noopener noreferrer"},w=o("wgcf"),v=o("."),x=e("li",null,[o("Run "),e("code",null,"wgcf register"),o(" to generate "),e("code",null,"wgcf-account.toml"),o(".")],-1),W=e("li",null,[o("Run "),e("code",null,"wgcf generate"),o(" to generate "),e("code",null,"wgcf-profile.conf"),o(". Copy the following content:")],-1),P=r('
    [Interface]\nPrivateKey = my private key\nAddress = 172.16.0.2/32\nAddress = 2606:4700:110:8949:fed8:2642:a640:c8e1/128\nDNS = 1.1.1.1\nMTU = 1280\n[Peer]\nPublicKey = Warp public key\nAllowedIPs = 0.0.0.0/0\nAllowedIPs = ::/0\nEndpoint = engage.cloudflareclient.com:2408\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    Diverting inbound traffic to warp on the server side

    Add a new WireGuard outbound in the existing ones.

    {\n  "protocol": "wireguard",\n  "settings": {\n    "secretKey": "My private key",\n    "address": ["172.16.0.2/32", "2606:4700:110:8949:fed8:2642:a640:c8e1/128"],\n    "peers": [\n      {\n        "publicKey": "Warp public key",\n        "endpoint": "engage.cloudflareclient.com:2408"\n      }\n    ]\n  },\n  "tag": "wireguard-1"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    Recommended routing strategy is IPIfNonMatch.

    Add the following to the existing router:

                {\n                "type": "field",\n                "domain": [\n                    "geosite:cn"\n                ],\n                "outboundTag": "wireguard-1"\n            },\n            {\n                "type": "field",\n                "ip": [\n                    "geoip:cn"\n                ],\n                "outboundTag": "wireguard-1"\n            },\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    Using Warp Chain Proxy on the Client Side

    {\n   "outbounds":[\n      {\n         "protocol":"wireguard",\n         "settings":{\n            "secretKey":"My private key",\n            "peers":[\n               {\n                  "publicKey":"Warp public key",\n                  "endpoint":"engage.cloudflareclient.com:2408"\n               }\n            ]\n         },\n         "streamSettings":{\n            "sockopt":{\n               "dialerProxy":"proxy"\n            }\n         },\n         "tag":"wireguard-1"\n      },\n      {\n         "tag":"proxy",\n         "protocol":"vmess",\n         "settings":{\n            "vnext":[\n               {\n                  "address":"My IP",\n                  "port":My port,\n                  "users":[\n                     {\n                        "id":"My UUID",\n                        "security":"auto"\n                     }\n                  ]\n               }\n            ]\n         },\n         "streamSettings":{\n            "network":"tcp"\n         }\n      }\n   ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    ',9);l.render=function(o,r){const l=n("OutboundLink");return s(),a(t,null,[u,c,e("ol",null,[e("li",null,[i,e("a",b,[k,p(l)]),d]),m,q]),g,e("ol",null,[h,e("li",null,[y,e("a",f,[w,p(l)]),v]),x,W]),P],64)};export default l; diff --git a/assets/warp.html.b8d62296.js b/assets/warp.html.f0c11712.js similarity index 99% rename from assets/warp.html.b8d62296.js rename to assets/warp.html.f0c11712.js index 458d4828e..e191abf11 100644 --- a/assets/warp.html.b8d62296.js +++ b/assets/warp.html.f0c11712.js @@ -1 +1 @@ -import{r as n,o as s,c as a,a as p,b as t,F as e,e as o,d as r}from"./app.755d843f.js";const l={},u=p("h1",{id:"通过-cloudflare-warp-增强代理安全性",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#通过-cloudflare-warp-增强代理安全性","aria-hidden":"true"},"#"),o(" 通过 Cloudflare Warp 增强代理安全性")],-1),c=p("p",null,"Xray(1.6.5+)新加入了 WireGuard 出站,虽然增加的代码和依赖会增大 core 体积,但是我们认为这是一个很有必要的新功能,原因有三:",-1),i=o("通过近期的一些讨论和"),b={href:"https://github.com/net4people/bbs/issues/129#issuecomment-1308102504",target:"_blank",rel:"noopener noreferrer"},k=o("实验"),q=o(",我们知道代理回国流量是不安全的。一种应对方式是将回国流量路由至黑洞,它的缺点是由于 geosite 和 geoip 更新的不及时或者新手不知道如何在客户端适当分流,结果流量进入黑洞,影响使用体验。 这时我们只需要将回国流量导入 Cloudflare Warp,可以在不影响使用体验的情况下达到同样的安全性。"),m=p("li",null,"众所周知,大部分机场会记录用户访问域名的日志,某些机场还会审计和阻断一些用户流量。保护用户私密性的一个方法,就是在客户端使用链式代理。 Warp 使用的 WireGuard 轻量级 VPN 协议会在代理层内增加一层加密。对于机场而言,用户所有流量的目标都是 Warp,从而最大程度保护自己的隐私。",-1),d=p("li",null,"方便使用,只需要一个 core 即可完成分流,Wireguard Tun,链式代理的设置。",-1),g=p("h2",{id:"申请-warp-账户",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#申请-warp-账户","aria-hidden":"true"},"#"),o(" 申请 Warp 账户")],-1),y=p("li",null,"感谢 Cloudflare 推动自由的互联网,现在你可以免费使用 Warp 服务,连接的时候会根据出口自动选择最近的服务器",-1),f=o("使用一台 vps,下载 "),h={href:"https://github.com/ViRb3/wgcf/releases",target:"_blank",rel:"noopener noreferrer"},w=o("wgcf"),v=p("li",null,[o("运行 "),p("code",null,"wgcf register"),o(" 生成 "),p("code",null,"wgcf-account.toml")],-1),x=p("li",null,[o("运行 "),p("code",null,"wgcf generate"),o(" 生成 "),p("code",null,"wgcf-profile.conf"),o(" 拷贝内容如下:")],-1),W=r('
    [Interface]\nPrivateKey = 我的私钥\nAddress = 172.16.0.2/32\nAddress = 2606:4700:110:8949:fed8:2642:a640:c8e1/128\nDNS = 1.1.1.1\nMTU = 1280\n[Peer]\nPublicKey = Warp公钥\nAllowedIPs = 0.0.0.0/0\nAllowedIPs = ::/0\nEndpoint = engage.cloudflareclient.com:2408\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    在服务端分流回国流量至 warp

    在现有出站中新增一个 WireGurad 出站

    {\n  "protocol": "wireguard",\n  "settings": {\n    "secretKey": "我的私钥",\n    "address": ["172.16.0.2/32", "2606:4700:110:8949:fed8:2642:a640:c8e1/128"],\n    "peers": [\n      {\n        "publicKey": "Warp公钥",\n        "endpoint": "engage.cloudflareclient.com:2408"\n      }\n    ]\n  },\n  "tag": "wireguard-1"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    路由策略推荐IPIfNonMatch

    在现有路由中新增以下

                {\n                "type": "field",\n                "domain": [\n                    "geosite:cn"\n                ],\n                "outboundTag": "wireguard-1"\n            },\n            {\n                "type": "field",\n                "ip": [\n                    "geoip:cn"\n                ],\n                "outboundTag": "wireguard-1"\n            },\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    客户端使用 warp 链式代理

    {\n   "outbounds":[\n      {\n         "protocol":"wireguard",\n         "settings":{\n            "secretKey":"我的私钥",\n            "peers":[\n               {\n                  "publicKey":"Warp公钥",\n                  "endpoint":"engage.cloudflareclient.com:2408"\n               }\n            ]\n         },\n         "streamSettings":{\n            "sockopt":{\n               "dialerProxy":"proxy"\n            }\n         },\n         "tag":"wireguard-1"\n      },\n      {\n         "tag":"proxy",\n         "protocol":"vmess",\n         "settings":{\n            "vnext":[\n               {\n                  "address":"我的IP",\n                  "port":我的端口,\n                  "users":[\n                     {\n                        "id":"我的UUID",\n                        "security":"auto"\n                     }\n                  ]\n               }\n            ]\n         },\n         "streamSettings":{\n            "network":"tcp"\n         }\n      }\n   ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    ',9);l.render=function(o,r){const l=n("OutboundLink");return s(),a(e,null,[u,c,p("ol",null,[p("li",null,[i,p("a",b,[k,t(l)]),q]),m,d]),g,p("ol",null,[y,p("li",null,[f,p("a",h,[w,t(l)])]),v,x]),W],64)};export default l; +import{r as n,o as s,c as a,a as p,b as t,F as e,e as o,d as r}from"./app.48111a85.js";const l={},u=p("h1",{id:"通过-cloudflare-warp-增强代理安全性",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#通过-cloudflare-warp-增强代理安全性","aria-hidden":"true"},"#"),o(" 通过 Cloudflare Warp 增强代理安全性")],-1),c=p("p",null,"Xray(1.6.5+)新加入了 WireGuard 出站,虽然增加的代码和依赖会增大 core 体积,但是我们认为这是一个很有必要的新功能,原因有三:",-1),i=o("通过近期的一些讨论和"),b={href:"https://github.com/net4people/bbs/issues/129#issuecomment-1308102504",target:"_blank",rel:"noopener noreferrer"},k=o("实验"),q=o(",我们知道代理回国流量是不安全的。一种应对方式是将回国流量路由至黑洞,它的缺点是由于 geosite 和 geoip 更新的不及时或者新手不知道如何在客户端适当分流,结果流量进入黑洞,影响使用体验。 这时我们只需要将回国流量导入 Cloudflare Warp,可以在不影响使用体验的情况下达到同样的安全性。"),m=p("li",null,"众所周知,大部分机场会记录用户访问域名的日志,某些机场还会审计和阻断一些用户流量。保护用户私密性的一个方法,就是在客户端使用链式代理。 Warp 使用的 WireGuard 轻量级 VPN 协议会在代理层内增加一层加密。对于机场而言,用户所有流量的目标都是 Warp,从而最大程度保护自己的隐私。",-1),d=p("li",null,"方便使用,只需要一个 core 即可完成分流,Wireguard Tun,链式代理的设置。",-1),g=p("h2",{id:"申请-warp-账户",tabindex:"-1"},[p("a",{class:"header-anchor",href:"#申请-warp-账户","aria-hidden":"true"},"#"),o(" 申请 Warp 账户")],-1),y=p("li",null,"感谢 Cloudflare 推动自由的互联网,现在你可以免费使用 Warp 服务,连接的时候会根据出口自动选择最近的服务器",-1),f=o("使用一台 vps,下载 "),h={href:"https://github.com/ViRb3/wgcf/releases",target:"_blank",rel:"noopener noreferrer"},w=o("wgcf"),v=p("li",null,[o("运行 "),p("code",null,"wgcf register"),o(" 生成 "),p("code",null,"wgcf-account.toml")],-1),x=p("li",null,[o("运行 "),p("code",null,"wgcf generate"),o(" 生成 "),p("code",null,"wgcf-profile.conf"),o(" 拷贝内容如下:")],-1),W=r('
    [Interface]\nPrivateKey = 我的私钥\nAddress = 172.16.0.2/32\nAddress = 2606:4700:110:8949:fed8:2642:a640:c8e1/128\nDNS = 1.1.1.1\nMTU = 1280\n[Peer]\nPublicKey = Warp公钥\nAllowedIPs = 0.0.0.0/0\nAllowedIPs = ::/0\nEndpoint = engage.cloudflareclient.com:2408\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    在服务端分流回国流量至 warp

    在现有出站中新增一个 WireGurad 出站

    {\n  "protocol": "wireguard",\n  "settings": {\n    "secretKey": "我的私钥",\n    "address": ["172.16.0.2/32", "2606:4700:110:8949:fed8:2642:a640:c8e1/128"],\n    "peers": [\n      {\n        "publicKey": "Warp公钥",\n        "endpoint": "engage.cloudflareclient.com:2408"\n      }\n    ]\n  },\n  "tag": "wireguard-1"\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    路由策略推荐IPIfNonMatch

    在现有路由中新增以下

                {\n                "type": "field",\n                "domain": [\n                    "geosite:cn"\n                ],\n                "outboundTag": "wireguard-1"\n            },\n            {\n                "type": "field",\n                "ip": [\n                    "geoip:cn"\n                ],\n                "outboundTag": "wireguard-1"\n            },\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    客户端使用 warp 链式代理

    {\n   "outbounds":[\n      {\n         "protocol":"wireguard",\n         "settings":{\n            "secretKey":"我的私钥",\n            "peers":[\n               {\n                  "publicKey":"Warp公钥",\n                  "endpoint":"engage.cloudflareclient.com:2408"\n               }\n            ]\n         },\n         "streamSettings":{\n            "sockopt":{\n               "dialerProxy":"proxy"\n            }\n         },\n         "tag":"wireguard-1"\n      },\n      {\n         "tag":"proxy",\n         "protocol":"vmess",\n         "settings":{\n            "vnext":[\n               {\n                  "address":"我的IP",\n                  "port":我的端口,\n                  "users":[\n                     {\n                        "id":"我的UUID",\n                        "security":"auto"\n                     }\n                  ]\n               }\n            ]\n         },\n         "streamSettings":{\n            "network":"tcp"\n         }\n      }\n   ]\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    ',9);l.render=function(o,r){const l=n("OutboundLink");return s(),a(e,null,[u,c,p("ol",null,[p("li",null,[i,p("a",b,[k,t(l)]),q]),m,d]),g,p("ol",null,[y,p("li",null,[f,p("a",h,[w,t(l)])]),v,x]),W],64)};export default l; diff --git a/assets/websocket.html.7e909ae6.js b/assets/websocket.html.787efee2.js similarity index 98% rename from assets/websocket.html.7e909ae6.js rename to assets/websocket.html.787efee2.js index 465fb60ab..ace159e25 100644 --- a/assets/websocket.html.7e909ae6.js +++ b/assets/websocket.html.787efee2.js @@ -1 +1 @@ -import{r as e,o,c as a,a as s,b as n,w as t,F as p,d as c,e as r}from"./app.755d843f.js";const l={},d=c('

    WebSocket

    使用标准的 WebSocket 来传输数据。

    WebSocket 连接可以被其它 HTTP 服务器(如 Nginx)分流,也可以被 VLESS fallbacks path 分流。

    提示

    Websocket 会识别 HTTP 请求的 X-Forwarded-For 头来覆写流量的源地址,优先级高于 PROXY protocol。

    WebSocketObject

    WebSocketObject 对应传输配置的 wsSettings 项。

    {\n  "acceptProxyProtocol": false,\n  "path": "/",\n  "headers": {\n    "Host": "xray.com"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7

    acceptProxyProtocol: true | false

    仅用于 inbound,指示是否接收 PROXY protocol。

    ',9),u={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},i=r("PROXY protocol"),b=r(" 专用于传递请求的真实来源 IP 和端口,"),k=s("strong",null,"若你不了解它,请先忽略该项",-1),h=r("。"),q=c('

    常见的反代软件(如 HAProxy、Nginx)都可以配置发送它,VLESS fallbacks xver 也可以发送它。

    填写 true 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2,否则连接会被关闭。

    path: string

    WebSocket 所使用的 HTTP 协议路径,默认值为 "/"

    如果路径中包含 ed 参数,将会启用 Early Data 以降低延迟,其值为首包长度阈值。如果首包长度超过此值,就不会启用 Early Data。建议的值为 2048。

    注意

    Early Data 使用 Sec-WebSocket-Protocol 头承载数据。如果你遇到兼容性问题,可以尝试调低阈值。

    headers: map {string: string}

    自定义 HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是字符串。

    默认值为空。

    Browser Dialer

    ',10),m=r("使用浏览器处理 TLS,详见 "),g=r("Browser Dialer");l.render=function(c,r){const l=e("OutboundLink"),w=e("RouterLink");return o(),a(p,null,[d,s("p",null,[s("a",u,[i,n(l)]),b,k,h]),q,s("p",null,[m,n(w,{to:"/config/features/browser_dialer.html"},{default:t((()=>[g])),_:1})])],64)};export default l; +import{r as e,o,c as a,a as s,b as n,w as t,F as p,d as c,e as r}from"./app.48111a85.js";const l={},d=c('

    WebSocket

    使用标准的 WebSocket 来传输数据。

    WebSocket 连接可以被其它 HTTP 服务器(如 Nginx)分流,也可以被 VLESS fallbacks path 分流。

    提示

    Websocket 会识别 HTTP 请求的 X-Forwarded-For 头来覆写流量的源地址,优先级高于 PROXY protocol。

    WebSocketObject

    WebSocketObject 对应传输配置的 wsSettings 项。

    {\n  "acceptProxyProtocol": false,\n  "path": "/",\n  "headers": {\n    "Host": "xray.com"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7

    acceptProxyProtocol: true | false

    仅用于 inbound,指示是否接收 PROXY protocol。

    ',9),u={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},i=r("PROXY protocol"),b=r(" 专用于传递请求的真实来源 IP 和端口,"),k=s("strong",null,"若你不了解它,请先忽略该项",-1),h=r("。"),q=c('

    常见的反代软件(如 HAProxy、Nginx)都可以配置发送它,VLESS fallbacks xver 也可以发送它。

    填写 true 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2,否则连接会被关闭。

    path: string

    WebSocket 所使用的 HTTP 协议路径,默认值为 "/"

    如果路径中包含 ed 参数,将会启用 Early Data 以降低延迟,其值为首包长度阈值。如果首包长度超过此值,就不会启用 Early Data。建议的值为 2048。

    注意

    Early Data 使用 Sec-WebSocket-Protocol 头承载数据。如果你遇到兼容性问题,可以尝试调低阈值。

    headers: map {string: string}

    自定义 HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是字符串。

    默认值为空。

    Browser Dialer

    ',10),m=r("使用浏览器处理 TLS,详见 "),g=r("Browser Dialer");l.render=function(c,r){const l=e("OutboundLink"),w=e("RouterLink");return o(),a(p,null,[d,s("p",null,[s("a",u,[i,n(l)]),b,k,h]),q,s("p",null,[m,n(w,{to:"/config/features/browser_dialer.html"},{default:t((()=>[g])),_:1})])],64)};export default l; diff --git a/assets/websocket.html.5246d66a.js b/assets/websocket.html.fa0466ec.js similarity index 98% rename from assets/websocket.html.5246d66a.js rename to assets/websocket.html.fa0466ec.js index 50f89d8be..dd9f6403b 100644 --- a/assets/websocket.html.5246d66a.js +++ b/assets/websocket.html.fa0466ec.js @@ -1 +1 @@ -import{r as e,o as a,c as t,a as o,b as s,w as n,F as r,d as c,e as p}from"./app.755d843f.js";const l={},i=c('

    WebSocket

    Use standard WebSocket to transmit data.

    WebSocket connections can be peoxied by other HTTP servers (such as Nginx) or by VLESS fallbacks path.

    Tip

    Websocket will recognize the X-Forwarded-For header of the HTTP request to override the source address of the traffic, with a higher priority than the PROXY protocol.

    WebSocketObject

    WebSocketObject corresponds to the wsSettings item of the transport configuration.

    {\n  "acceptProxyProtocol": false,\n  "path": "/",\n  "headers": {\n    "Host": "xray.com"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7

    acceptProxyProtocol: true | false

    Only used for inbound, indicating whether to accept the PROXY protocol.

    ',9),d=p("The "),u={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},h=p("PROXY protocol"),b=p(" is used to transmit the real source IP and port of the request. "),k=o("strong",null,"If you are not familiar with it, please ignore this item.",-1),m=c('

    Common reverse proxy software (such as HAProxy and Nginx) can be configured to send it, and VLESS fallbacks xver can also send it.

    When filled in as true, after the underlying TCP connection is established, the requesting party must first send PROXY protocol v1 or v2, otherwise the connection will be closed.

    path: string

    The HTTP protocol path used by WebSocket. Default is "/"

    If the path contains the ed parameter, Early Data will be enabled to reduce latency, and its value is the first packet length threshold. If the length of the first packet exceeds this value, Early Data will not be enabled. The recommended value is 2048.

    An example usage of ed parameter:

    "path": "/aabbcc" //original path\n\n"path": "/aabbcc?ed=2048" //added ed parameter\n
    1
    2
    3

    Warning

    Early Data uses the Sec-WebSocket-Protocol header to carry data. If you encounter compatibility issues, try lowering the threshold.

    headers: map {string: string}

    Custom HTTP headers, a key-value pair, where each key represents the name of an HTTP header, and the corresponding value is a string.

    The default value is empty.

    Browser Dialer

    ',12),f=p("Use the browser to handle TLS, see "),g=p("Browser Dialer");l.render=function(c,p){const l=e("OutboundLink"),q=e("RouterLink");return a(),t(r,null,[i,o("p",null,[d,o("a",u,[h,s(l)]),b,k]),m,o("p",null,[f,s(q,{to:"/en/config/features/browser_dialer.html"},{default:n((()=>[g])),_:1})])],64)};export default l; +import{r as e,o as a,c as t,a as o,b as s,w as n,F as r,d as c,e as p}from"./app.48111a85.js";const l={},i=c('

    WebSocket

    Use standard WebSocket to transmit data.

    WebSocket connections can be peoxied by other HTTP servers (such as Nginx) or by VLESS fallbacks path.

    Tip

    Websocket will recognize the X-Forwarded-For header of the HTTP request to override the source address of the traffic, with a higher priority than the PROXY protocol.

    WebSocketObject

    WebSocketObject corresponds to the wsSettings item of the transport configuration.

    {\n  "acceptProxyProtocol": false,\n  "path": "/",\n  "headers": {\n    "Host": "xray.com"\n  }\n}\n
    1
    2
    3
    4
    5
    6
    7

    acceptProxyProtocol: true | false

    Only used for inbound, indicating whether to accept the PROXY protocol.

    ',9),d=p("The "),u={href:"https://www.haproxy.org/download/2.2/doc/proxy-protocol.txt",target:"_blank",rel:"noopener noreferrer"},h=p("PROXY protocol"),b=p(" is used to transmit the real source IP and port of the request. "),k=o("strong",null,"If you are not familiar with it, please ignore this item.",-1),m=c('

    Common reverse proxy software (such as HAProxy and Nginx) can be configured to send it, and VLESS fallbacks xver can also send it.

    When filled in as true, after the underlying TCP connection is established, the requesting party must first send PROXY protocol v1 or v2, otherwise the connection will be closed.

    path: string

    The HTTP protocol path used by WebSocket. Default is "/"

    If the path contains the ed parameter, Early Data will be enabled to reduce latency, and its value is the first packet length threshold. If the length of the first packet exceeds this value, Early Data will not be enabled. The recommended value is 2048.

    An example usage of ed parameter:

    "path": "/aabbcc" //original path\n\n"path": "/aabbcc?ed=2048" //added ed parameter\n
    1
    2
    3

    Warning

    Early Data uses the Sec-WebSocket-Protocol header to carry data. If you encounter compatibility issues, try lowering the threshold.

    headers: map {string: string}

    Custom HTTP headers, a key-value pair, where each key represents the name of an HTTP header, and the corresponding value is a string.

    The default value is empty.

    Browser Dialer

    ',12),f=p("Use the browser to handle TLS, see "),g=p("Browser Dialer");l.render=function(c,p){const l=e("OutboundLink"),q=e("RouterLink");return a(),t(r,null,[i,o("p",null,[d,o("a",u,[h,s(l)]),b,k]),m,o("p",null,[f,s(q,{to:"/en/config/features/browser_dialer.html"},{default:n((()=>[g])),_:1})])],64)};export default l; diff --git a/assets/wireguard.html.d818fa5b.js b/assets/wireguard.html.51f49bce.js similarity index 99% rename from assets/wireguard.html.d818fa5b.js rename to assets/wireguard.html.51f49bce.js index fa9f95014..41656a679 100644 --- a/assets/wireguard.html.d818fa5b.js +++ b/assets/wireguard.html.51f49bce.js @@ -1 +1 @@ -import{d as n}from"./app.755d843f.js";const s={},a=n('

    Wireguard

    标准 Wireguard 协议实现。

    警告

    Wireguard 协议并非专门为翻墙而设计,若在最外层过墙,存在特征可能导致服务器被封锁

    OutboundConfigurationObject

    {\n  "secretKey": "PRIVATE_KEY",\n  "address": [\n    // optional, default ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"]\n    "IPv4_CIDR",\n    "IPv6_CIDR",\n    "and more..."\n  ],\n  "peers": [\n    {\n      "endpoint": "ENDPOINT_ADDR",\n      "publicKey": "PUBLIC_KEY"\n    }\n  ],\n  "mtu": 1420, // optional, default 1420\n  "reserved": [1, 2, 3],\n  "workers": 2 // optional, default runtime.NumCPU()\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    提示

    目前 Wireguard 协议 outbound 中不支持设置 streamSettings

    secretKey: string

    用户私钥。必填。

    address: string array

    Wireguard 会在本地开启虚拟网卡 tun。使用一个或多个 IP 地址,支持 IPv6

    mtu: int

    Wireguard 底层 tun 的分片大小。

    reserved [ number ]

    Wireguard 保留字节。

    workers: int

    Wireguard 使用线程数。

    peers: [ Peers ]

    Wireguard 服务器列表,其中每一项是一个服务器配置。

    Peers

    {\n  "endpoint": "ENDPOINT_ADDR",\n  "publicKey": "PUBLIC_KEY",\n  "preSharedKey": "PRE_SHARED_KEY", // optional, default "0000000000000000000000000000000000000000000000000000000000000000"\n  "keepAlive": 0, // optional, default 0\n  "allowedIPs": ["0.0.0.0/0"] // optional, default ["0.0.0.0/0", "::/0"]\n}\n
    1
    2
    3
    4
    5
    6
    7

    endpoint: address

    服务器地址, 必填

    提示

    使用 url:端口号 格式,形如 engage.cloudflareclient.com:2408

    publicKey: string

    服务器公钥,用于验证, 必填

    preSharedKey: string

    额外的对称加密密钥

    keepAlive: int

    心跳包时间间隔,单位为秒,默认为 0 表示无心跳

    allowedIPs: string array

    Wireguard 仅允许特定源 IP 的流量

    ',31);s.render=function(n,s){return a};export default s; +import{d as n}from"./app.48111a85.js";const s={},a=n('

    Wireguard

    标准 Wireguard 协议实现。

    警告

    Wireguard 协议并非专门为翻墙而设计,若在最外层过墙,存在特征可能导致服务器被封锁

    OutboundConfigurationObject

    {\n  "secretKey": "PRIVATE_KEY",\n  "address": [\n    // optional, default ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"]\n    "IPv4_CIDR",\n    "IPv6_CIDR",\n    "and more..."\n  ],\n  "peers": [\n    {\n      "endpoint": "ENDPOINT_ADDR",\n      "publicKey": "PUBLIC_KEY"\n    }\n  ],\n  "mtu": 1420, // optional, default 1420\n  "reserved": [1, 2, 3],\n  "workers": 2 // optional, default runtime.NumCPU()\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    提示

    目前 Wireguard 协议 outbound 中不支持设置 streamSettings

    secretKey: string

    用户私钥。必填。

    address: string array

    Wireguard 会在本地开启虚拟网卡 tun。使用一个或多个 IP 地址,支持 IPv6

    mtu: int

    Wireguard 底层 tun 的分片大小。

    reserved [ number ]

    Wireguard 保留字节。

    workers: int

    Wireguard 使用线程数。

    peers: [ Peers ]

    Wireguard 服务器列表,其中每一项是一个服务器配置。

    Peers

    {\n  "endpoint": "ENDPOINT_ADDR",\n  "publicKey": "PUBLIC_KEY",\n  "preSharedKey": "PRE_SHARED_KEY", // optional, default "0000000000000000000000000000000000000000000000000000000000000000"\n  "keepAlive": 0, // optional, default 0\n  "allowedIPs": ["0.0.0.0/0"] // optional, default ["0.0.0.0/0", "::/0"]\n}\n
    1
    2
    3
    4
    5
    6
    7

    endpoint: address

    服务器地址, 必填

    提示

    使用 url:端口号 格式,形如 engage.cloudflareclient.com:2408

    publicKey: string

    服务器公钥,用于验证, 必填

    preSharedKey: string

    额外的对称加密密钥

    keepAlive: int

    心跳包时间间隔,单位为秒,默认为 0 表示无心跳

    allowedIPs: string array

    Wireguard 仅允许特定源 IP 的流量

    ',31);s.render=function(n,s){return a};export default s; diff --git a/assets/wireguard.html.efd81cf2.js b/assets/wireguard.html.d26b82d9.js similarity index 99% rename from assets/wireguard.html.efd81cf2.js rename to assets/wireguard.html.d26b82d9.js index a363fb151..212b2c998 100644 --- a/assets/wireguard.html.efd81cf2.js +++ b/assets/wireguard.html.d26b82d9.js @@ -1 +1 @@ -import{d as n}from"./app.755d843f.js";const s={},a=n('

    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

    {\n  "secretKey": "PRIVATE_KEY",\n  "address": [\n    // optional, default ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"]\n    "IPv4_CIDR",\n    "IPv6_CIDR",\n    "and more..."\n  ],\n  "peers": [\n    {\n      "endpoint": "ENDPOINT_ADDR",\n      "publicKey": "PUBLIC_KEY"\n    }\n  ],\n  "mtu": 1420, // optional, default 1420\n  "workers": 2 // optional, default runtime.NumCPU()\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    Tip

    Currently, the Wireguard protocol outbound does not support setting streamSettings.

    secretKey: string

    The user's private key. Required.

    address: string array

    Wireguard will create a virtual network interface tun locally. Use one or more IP addresses, including IPv6.

    mtu: int

    The fragment size of the underlying tun device in Wireguard.

    workers: int

    The number of threads used by Wireguard.

    peers: [ Peers ]

    A list of Wireguard servers, where each item is a server configuration.

    Peers

    {\n  "endpoint": "ENDPOINT_ADDR",\n  "publicKey": "PUBLIC_KEY",\n  "preSharedKey": "PRE_SHARED_KEY", // optional, default "0000000000000000000000000000000000000000000000000000000000000000"\n  "keepAlive": 0, // optional, default 0\n  "allowedIPs": ["0.0.0.0/0"] // optional, default ["0.0.0.0/0", "::/0"]\n}\n
    1
    2
    3
    4
    5
    6
    7

    endpoint: address

    The server address. Required.

    Tip

    Use the format url:port, for example, engage.cloudflareclient.com: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.

    ',29);s.render=function(n,s){return a};export default s; +import{d as n}from"./app.48111a85.js";const s={},a=n('

    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

    {\n  "secretKey": "PRIVATE_KEY",\n  "address": [\n    // optional, default ["10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"]\n    "IPv4_CIDR",\n    "IPv6_CIDR",\n    "and more..."\n  ],\n  "peers": [\n    {\n      "endpoint": "ENDPOINT_ADDR",\n      "publicKey": "PUBLIC_KEY"\n    }\n  ],\n  "mtu": 1420, // optional, default 1420\n  "workers": 2 // optional, default runtime.NumCPU()\n}\n
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    Tip

    Currently, the Wireguard protocol outbound does not support setting streamSettings.

    secretKey: string

    The user's private key. Required.

    address: string array

    Wireguard will create a virtual network interface tun locally. Use one or more IP addresses, including IPv6.

    mtu: int

    The fragment size of the underlying tun device in Wireguard.

    workers: int

    The number of threads used by Wireguard.

    peers: [ Peers ]

    A list of Wireguard servers, where each item is a server configuration.

    Peers

    {\n  "endpoint": "ENDPOINT_ADDR",\n  "publicKey": "PUBLIC_KEY",\n  "preSharedKey": "PRE_SHARED_KEY", // optional, default "0000000000000000000000000000000000000000000000000000000000000000"\n  "keepAlive": 0, // optional, default 0\n  "allowedIPs": ["0.0.0.0/0"] // optional, default ["0.0.0.0/0", "::/0"]\n}\n
    1
    2
    3
    4
    5
    6
    7

    endpoint: address

    The server address. Required.

    Tip

    Use the format url:port, for example, engage.cloudflareclient.com: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.

    ',29);s.render=function(n,s){return a};export default s; diff --git a/assets/work.html.b1ae1f68.js b/assets/work.html.8cd6df61.js similarity index 98% rename from assets/work.html.b1ae1f68.js rename to assets/work.html.8cd6df61.js index ffe45ae01..8bb9c7ccc 100644 --- a/assets/work.html.b1ae1f68.js +++ b/assets/work.html.8cd6df61.js @@ -1 +1 @@ -import{r as a,o as r,c as n,b as e,F as l,a as A,e as E}from"./app.755d843f.js";const i={},u=A("h1",{id:"xray-的工作模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#xray-的工作模式","aria-hidden":"true"},"#"),E(" Xray 的工作模式")],-1),d=A("h2",{id:"单服务器模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#单服务器模式","aria-hidden":"true"},"#"),E(" 单服务器模式")],-1),h=A("p",null,"与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。",-1),o=A("p",null,"一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。",-1),t=A("h2",{id:"桥接模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#桥接模式","aria-hidden":"true"},"#"),E(" 桥接模式")],-1),D=A("p",null,"如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。",-1),s=A("h2",{id:"工作原理",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#工作原理","aria-hidden":"true"},"#"),E(" 工作原理")],-1),B=A("p",null,"在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。",-1),p=A("ul",null,[A("li",null,[E("需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。 "),A("ul",null,[A("li",null,[E("入站连接负责与客户端(如浏览器)通信: "),A("ul",null,[A("li",null,"入站连接通常可以配置用户认证,如 ID 和密码等;"),A("li",null,"入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;")])]),A("li",null,"出站连接负责将数据发给服务器,如另一台主机上的 Xray。")])]),A("li",null,[E("当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。 "),A("ul",null,[A("li",null,"路由会在必要时查询 DNS 以获取更多信息来进行判断。")])])],-1);i.render=function(A,E){const i=a("Mermaid");return r(),n(l,null,[u,d,h,e(i,{identifier:"mermaid_1a962853",graph:"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"}),o,t,D,e(i,{identifier:"mermaid_382ee14e",graph:"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"}),s,B,e(i,{identifier:"mermaid_382ee16a",graph:"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"}),p],64)};export default i; +import{r as a,o as r,c as n,b as e,F as l,a as A,e as E}from"./app.48111a85.js";const i={},u=A("h1",{id:"xray-的工作模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#xray-的工作模式","aria-hidden":"true"},"#"),E(" Xray 的工作模式")],-1),d=A("h2",{id:"单服务器模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#单服务器模式","aria-hidden":"true"},"#"),E(" 单服务器模式")],-1),h=A("p",null,"与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。",-1),o=A("p",null,"一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。",-1),t=A("h2",{id:"桥接模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#桥接模式","aria-hidden":"true"},"#"),E(" 桥接模式")],-1),D=A("p",null,"如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。",-1),s=A("h2",{id:"工作原理",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#工作原理","aria-hidden":"true"},"#"),E(" 工作原理")],-1),B=A("p",null,"在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。",-1),p=A("ul",null,[A("li",null,[E("需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。 "),A("ul",null,[A("li",null,[E("入站连接负责与客户端(如浏览器)通信: "),A("ul",null,[A("li",null,"入站连接通常可以配置用户认证,如 ID 和密码等;"),A("li",null,"入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;")])]),A("li",null,"出站连接负责将数据发给服务器,如另一台主机上的 Xray。")])]),A("li",null,[E("当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。 "),A("ul",null,[A("li",null,"路由会在必要时查询 DNS 以获取更多信息来进行判断。")])])],-1);i.render=function(A,E){const i=a("Mermaid");return r(),n(l,null,[u,d,h,e(i,{identifier:"mermaid_1a962853",graph:"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"}),o,t,D,e(i,{identifier:"mermaid_382ee14e",graph:"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"}),s,B,e(i,{identifier:"mermaid_382ee16a",graph:"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"}),p],64)};export default i; diff --git a/assets/work.html.bc8c017a.js b/assets/work.html.e38c21df.js similarity index 98% rename from assets/work.html.bc8c017a.js rename to assets/work.html.e38c21df.js index ffe45ae01..8bb9c7ccc 100644 --- a/assets/work.html.bc8c017a.js +++ b/assets/work.html.e38c21df.js @@ -1 +1 @@ -import{r as a,o as r,c as n,b as e,F as l,a as A,e as E}from"./app.755d843f.js";const i={},u=A("h1",{id:"xray-的工作模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#xray-的工作模式","aria-hidden":"true"},"#"),E(" Xray 的工作模式")],-1),d=A("h2",{id:"单服务器模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#单服务器模式","aria-hidden":"true"},"#"),E(" 单服务器模式")],-1),h=A("p",null,"与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。",-1),o=A("p",null,"一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。",-1),t=A("h2",{id:"桥接模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#桥接模式","aria-hidden":"true"},"#"),E(" 桥接模式")],-1),D=A("p",null,"如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。",-1),s=A("h2",{id:"工作原理",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#工作原理","aria-hidden":"true"},"#"),E(" 工作原理")],-1),B=A("p",null,"在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。",-1),p=A("ul",null,[A("li",null,[E("需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。 "),A("ul",null,[A("li",null,[E("入站连接负责与客户端(如浏览器)通信: "),A("ul",null,[A("li",null,"入站连接通常可以配置用户认证,如 ID 和密码等;"),A("li",null,"入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;")])]),A("li",null,"出站连接负责将数据发给服务器,如另一台主机上的 Xray。")])]),A("li",null,[E("当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。 "),A("ul",null,[A("li",null,"路由会在必要时查询 DNS 以获取更多信息来进行判断。")])])],-1);i.render=function(A,E){const i=a("Mermaid");return r(),n(l,null,[u,d,h,e(i,{identifier:"mermaid_1a962853",graph:"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"}),o,t,D,e(i,{identifier:"mermaid_382ee14e",graph:"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"}),s,B,e(i,{identifier:"mermaid_382ee16a",graph:"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"}),p],64)};export default i; +import{r as a,o as r,c as n,b as e,F as l,a as A,e as E}from"./app.48111a85.js";const i={},u=A("h1",{id:"xray-的工作模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#xray-的工作模式","aria-hidden":"true"},"#"),E(" Xray 的工作模式")],-1),d=A("h2",{id:"单服务器模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#单服务器模式","aria-hidden":"true"},"#"),E(" 单服务器模式")],-1),h=A("p",null,"与其它的网络代理工具一样,你需要一台配置了 Xray 的服务器,然后在自己的设备上安装并配置 Xray 客户端,然后即可流畅地访问互联网。",-1),o=A("p",null,"一个 Xray 服务器可同时支持多台设备使用不同的代理协议访问。同时,经过合理的配置,Xray 可以识别并区分需要代理以及不需要代理的流量,直连的流量不需要绕路。",-1),t=A("h2",{id:"桥接模式",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#桥接模式","aria-hidden":"true"},"#"),E(" 桥接模式")],-1),D=A("p",null,"如果你不想在每一台设备上都配置路由,你也可以设置一台中转服务器,用于接收客户端发来的所有流量,然后在服务器中进行转发判断。",-1),s=A("h2",{id:"工作原理",tabindex:"-1"},[A("a",{class:"header-anchor",href:"#工作原理","aria-hidden":"true"},"#"),E(" 工作原理")],-1),B=A("p",null,"在配置 Xray 之前,不妨先来看一下 Xray 的工作原理,以下是单个 Xray 进程的内部结构示意图。多个 Xray 之间相互独立,互不影响。",-1),p=A("ul",null,[A("li",null,[E("需要配置至少一个入站连接(Inbound)和一个出站连接(Outbound)才可以正常工作。 "),A("ul",null,[A("li",null,[E("入站连接负责与客户端(如浏览器)通信: "),A("ul",null,[A("li",null,"入站连接通常可以配置用户认证,如 ID 和密码等;"),A("li",null,"入站连接收到数据之后,会交给分发器(Dispatcher)进行分发;")])]),A("li",null,"出站连接负责将数据发给服务器,如另一台主机上的 Xray。")])]),A("li",null,[E("当有多个出站连接时,可以配置路由(Routing)来指定某一类流量由某一个出站连接发出。 "),A("ul",null,[A("li",null,"路由会在必要时查询 DNS 以获取更多信息来进行判断。")])])],-1);i.render=function(A,E){const i=a("Mermaid");return r(),n(l,null,[u,d,h,e(i,{identifier:"mermaid_1a962853",graph:"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"}),o,t,D,e(i,{identifier:"mermaid_382ee14e",graph:"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"}),s,B,e(i,{identifier:"mermaid_382ee16a",graph:"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"}),p],64)};export default i; diff --git a/assets/xtls.html.68940956.js b/assets/xtls.html.599a8d69.js similarity index 63% rename from assets/xtls.html.68940956.js rename to assets/xtls.html.599a8d69.js index 2d7a4d369..c183fc3bb 100644 --- a/assets/xtls.html.68940956.js +++ b/assets/xtls.html.599a8d69.js @@ -1 +1 @@ -import{r as a,o as r,c as e,b as n,F as t,a as s,e as l}from"./app.755d843f.js";const o={},d=s("h1",{id:"xtls-深度剖析",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#xtls-深度剖析","aria-hidden":"true"},"#"),l(" XTLS 深度剖析")],-1),u=s("blockquote",null,[s("p",null,[s("strong",null,"XTLS 是 Xray 的原创黑科技, 也是使 Xray 性能一骑绝尘的核心动力")])],-1);o.render=function(s,l){const o=a("Badge");return r(),e(t,null,[d,u,n(o,{text:"WIP",type:"warning"})],64)};export default o; +import{r as a,o as r,c as e,b as n,F as t,a as s,e as l}from"./app.48111a85.js";const o={},u=s("h1",{id:"xtls-深度剖析",tabindex:"-1"},[s("a",{class:"header-anchor",href:"#xtls-深度剖析","aria-hidden":"true"},"#"),l(" XTLS 深度剖析")],-1),d=s("blockquote",null,[s("p",null,[s("strong",null,"XTLS 是 Xray 的原创黑科技, 也是使 Xray 性能一骑绝尘的核心动力")])],-1);o.render=function(s,l){const o=a("Badge");return r(),e(t,null,[u,d,n(o,{text:"WIP",type:"warning"})],64)};export default o; diff --git a/assets/xtls.html.aad2ef82.js b/assets/xtls.html.e5294d93.js similarity index 66% rename from assets/xtls.html.aad2ef82.js rename to assets/xtls.html.e5294d93.js index 65033eae5..1cf2cc7b1 100644 --- a/assets/xtls.html.aad2ef82.js +++ b/assets/xtls.html.e5294d93.js @@ -1 +1 @@ -import{r as a,o as e,c as r,b as s,F as n,a as o,e as t}from"./app.755d843f.js";const l={},i=o("h1",{id:"deep-analysis-of-xtls",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#deep-analysis-of-xtls","aria-hidden":"true"},"#"),t(" Deep analysis of XTLS")],-1),d=o("blockquote",null,[o("p",null,[o("strong",null,'"XTLS is the original black technology of Xray, and also the core driving force that makes Xray\'s performance far superior."')])],-1);l.render=function(o,t){const l=a("Badge");return e(),r(n,null,[i,d,s(l,{text:"WIP",type:"warning"})],64)};export default l; +import{r as a,o as e,c as r,b as s,F as n,a as o,e as t}from"./app.48111a85.js";const l={},i=o("h1",{id:"deep-analysis-of-xtls",tabindex:"-1"},[o("a",{class:"header-anchor",href:"#deep-analysis-of-xtls","aria-hidden":"true"},"#"),t(" Deep analysis of XTLS")],-1),c=o("blockquote",null,[o("p",null,[o("strong",null,'"XTLS is the original black technology of Xray, and also the core driving force that makes Xray\'s performance far superior."')])],-1);l.render=function(o,t){const l=a("Badge");return e(),r(n,null,[i,c,s(l,{text:"WIP",type:"warning"})],64)};export default l; diff --git a/config/api.html b/config/api.html index f51f39319..f63211ad8 100644 --- a/config/api.html +++ b/config/api.html @@ -5,7 +5,7 @@ API 接口 | Project X - + @@ -44,6 +44,6 @@ xray.app.proxyman.command.HandlerService xray.app.stats.command.StatsService
    1
    2
    3
    4
    5
    6

    API 调用示例

    Xray-API-documentsopen in new window @crossfw

    - + diff --git a/config/dns.html b/config/dns.html index 469be994a..a8b2be79f 100644 --- a/config/dns.html +++ b/config/dns.html @@ -5,7 +5,7 @@ 内置 DNS 服务器 | Project X - + @@ -45,6 +45,6 @@ "clientIP": "1.2.3.4" }
    1
    2
    3
    4
    5
    6
    7
    8

    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 beaa5a261..b7069353b 100644 --- a/config/fakedns.html +++ b/config/fakedns.html @@ -5,7 +5,7 @@ FakeDNS | Project X - + @@ -111,6 +111,6 @@ ] }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    - + diff --git a/config/features/browser_dialer.html b/config/features/browser_dialer.html index 8be81f834..22b81a9e8 100644 --- a/config/features/browser_dialer.html +++ b/config/features/browser_dialer.html @@ -5,11 +5,11 @@ Browser Dialer | Project X - +

    Browser Dialer

    BETA v1.4.1+

    Background

    基于 一年前的想法open in new window ,利用原生 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 window 推荐 ?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 cc3be3d3b..a2f2c6d00 100644 --- a/config/features/env.html +++ b/config/features/env.html @@ -5,7 +5,7 @@ 环境变量 | Project X - + @@ -13,6 +13,6 @@ /usr/local/share/xray /usr/share/xray
    1
    2
    3

    配置文件位置

    • 名称: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 73903e628..32e56cf52 100644 --- a/config/features/fallback.html +++ b/config/features/fallback.html @@ -5,7 +5,7 @@ Fallback 回落 | Project X - + @@ -22,6 +22,6 @@ "xver": 0 }
    1
    2
    3
    4
    5
    6
    7

    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 window@@ 则代表带 padding 的 abstract。

    若只填 port,数字或字符串均可,形如 80"80",通常指向一个明文 http 服务(addr 会被补为 "127.0.0.1")。

    xver: number

    发送 PROXY protocolopen in new window,专用于传递请求的真实来源 IP 和端口,填版本 1 或 2,默认为 0,即不发送。若有需要建议填 1。

    目前填 1 或 2,功能完全相同,只是结构不同,且前者可打印,后者为二进制。Xray 的 TCP 和 WS 入站均已支持接收 PROXY protocol。

    注意

    若你正在 配置 Nginx 接收 PROXY protocolopen in new window,除了设置 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 8c52f7788..3107536d3 100644 --- a/config/features/multiple.html +++ b/config/features/multiple.html @@ -5,7 +5,7 @@ 多文件配置 | Project X - + @@ -84,6 +84,6 @@ 0 directories, 10 files
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    - + diff --git a/config/features/xtls.html b/config/features/xtls.html index 7f4f011df..b89ee819f 100644 --- a/config/features/xtls.html +++ b/config/features/xtls.html @@ -5,11 +5,11 @@ XTLS 深度剖析 | Project X - + - + diff --git a/config/inbound.html b/config/inbound.html index 7060b3504..0c56e655b 100644 --- a/config/inbound.html +++ b/config/inbound.html @@ -5,7 +5,7 @@ 入站代理 | Project X - + @@ -43,6 +43,6 @@ "concurrency": 3 }
    1
    2
    3
    4
    5

    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 57eb3e244..8b286b274 100644 --- a/config/inbounds/dokodemo.html +++ b/config/inbounds/dokodemo.html @@ -5,7 +5,7 @@ Dokodemo-Door | Project X - + @@ -18,6 +18,6 @@ "userLevel": 0 }
    1
    2
    3
    4
    5
    6
    7
    8

    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 d12b68960..e2ddea770 100644 --- a/config/inbounds/http.html +++ b/config/inbounds/http.html @@ -5,7 +5,7 @@ HTTP | Project X - + @@ -25,6 +25,6 @@ "pass": "my-password" }
    1
    2
    3
    4

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    - + diff --git a/config/inbounds/shadowsocks.html b/config/inbounds/shadowsocks.html index 3da5fe032..09cbf485e 100644 --- a/config/inbounds/shadowsocks.html +++ b/config/inbounds/shadowsocks.html @@ -5,7 +5,7 @@ Shadowsocks | Project X - + @@ -25,6 +25,6 @@ "email": "love@xray.com" }
    1
    2
    3
    4
    5
    6

    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 d2d9b5b86..4a47bc210 100644 --- a/config/inbounds/socks.html +++ b/config/inbounds/socks.html @@ -5,7 +5,7 @@ Socks | Project X - + @@ -26,6 +26,6 @@ "pass": "my-password" }
    1
    2
    3
    4

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    - + diff --git a/config/inbounds/trojan.html b/config/inbounds/trojan.html index aae4a0aa5..022be0cd4 100644 --- a/config/inbounds/trojan.html +++ b/config/inbounds/trojan.html @@ -5,7 +5,7 @@ Trojan | Project X - + @@ -29,6 +29,6 @@ "level": 0 }
    1
    2
    3
    4
    5

    password: string

    必填,任意字符串。

    email: string

    邮件地址,可选,用于标识用户

    警告

    如果存在多个 ClientObject, 请注意 email 不可以重复。

    level: number

    用户等级,连接会使用这个用户等级对应的 本地策略

    userLevel 的值, 对应 policylevel 的值。 如不指定, 默认为 0。

    - + diff --git a/config/inbounds/vless.html b/config/inbounds/vless.html index 5d389eec5..16a133a6a 100644 --- a/config/inbounds/vless.html +++ b/config/inbounds/vless.html @@ -5,7 +5,7 @@ VLESS | Project X - + @@ -32,6 +32,6 @@ "flow": "xtls-rprx-vision" }
    1
    2
    3
    4
    5
    6

    id: string

    VLESS 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID. 自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)

    其映射标准在 VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5open in new window

    你可以使用命令 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 9f1dbeba5..8aea093d0 100644 --- a/config/inbounds/vmess.html +++ b/config/inbounds/vmess.html @@ -5,7 +5,7 @@ VMess | Project X - + @@ -36,6 +36,6 @@ "level": 0 }
    1
    2
    3

    level: number

    用户等级,连接会使用这个用户等级对应的 本地策略

    level 的值, 对应 policylevel 的值。 如不指定, 默认为 0。

    - + diff --git a/config/index.html b/config/index.html index 36262b51e..5fd5031f5 100644 --- a/config/index.html +++ b/config/index.html @@ -5,7 +5,7 @@ 配置文件 | Project X - + @@ -23,6 +23,6 @@ "fakedns": {} }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    注意

    如果你刚接触 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 配置。可配合透明代理使用,以获取实际域名。

    - + diff --git a/config/log.html b/config/log.html index 5f1c54f71..d7c4c19e8 100644 --- a/config/log.html +++ b/config/log.html @@ -5,7 +5,7 @@ 日志配置 | Project X - + @@ -18,6 +18,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8

    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/outbound.html b/config/outbound.html index 298b6c2a6..a2e7e962f 100644 --- a/config/outbound.html +++ b/config/outbound.html @@ -5,7 +5,7 @@ 出站代理 | Project X - + @@ -34,6 +34,6 @@ "xudpProxyUDP443": "reject" }
    1
    2
    3
    4
    5
    6

    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 7dd63d2e7..7a2dd73e7 100644 --- a/config/outbounds/blackhole.html +++ b/config/outbounds/blackhole.html @@ -5,7 +5,7 @@ Blackhole | Project X - + @@ -18,6 +18,6 @@ "type": "none" }
    1
    2
    3

    type: "http" | "none"

    type"none"(默认值)时,Blackhole 将直接关闭连接。

    type"http" 时,Blackhole 会发回一个简单的 HTTP 403 数据包,然后关闭连接。

    - + diff --git a/config/outbounds/dns.html b/config/outbounds/dns.html index a1a3c4284..aed9cc5d6 100644 --- a/config/outbounds/dns.html +++ b/config/outbounds/dns.html @@ -5,7 +5,7 @@ DNS | Project X - + @@ -16,6 +16,6 @@ "nonIPQuery": "drop" }
    1
    2
    3
    4
    5
    6

    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 e393c63d7..7134eec01 100644 --- a/config/outbounds/freedom.html +++ b/config/outbounds/freedom.html @@ -5,7 +5,7 @@ Freedom | Project X - + @@ -20,6 +20,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    domainStrategy: "AsIs" | "UseIP" | "UseIPv4" | "UseIPv6"

    在目标地址为域名时, 配置相应的值, Freedom 的行为模式如下:

    • "AsIs": Freedom 通过系统 DNS 服务器解析获取 IP, 向此域名发出连接.
    • "UseIP""UseIPv4""UseIPv6": Xray 使用 内置 DNS 服务器 解析获取 IP, 向此域名发出连接. 默认值为 "AsIs"

    TIP 1

    当使用 "UseIP" 模式,并且 出站连接配置 中指定了 sendThrough 时,Freedom 会根据 sendThrough 的值自动判断所需的 IP 类型,IPv4 或 IPv6。

    TIP 2

    当使用 "UseIPv4""UseIPv6" 模式时,Freedom 会只使用对应的 IPv4 或 IPv6 地址。当 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)

    - + diff --git a/config/outbounds/http.html b/config/outbounds/http.html index 9d8bfef6f..123c726bf 100644 --- a/config/outbounds/http.html +++ b/config/outbounds/http.html @@ -5,7 +5,7 @@ HTTP | Project X - + @@ -42,6 +42,6 @@ "pass": "my-password" }
    1
    2
    3
    4

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    - + diff --git a/config/outbounds/shadowsocks.html b/config/outbounds/shadowsocks.html index fbd76823b..6fc8ce730 100644 --- a/config/outbounds/shadowsocks.html +++ b/config/outbounds/shadowsocks.html @@ -5,7 +5,7 @@ Shadowsocks | Project X - + @@ -34,6 +34,6 @@ "level": 0 }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    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 61df31c89..23516721c 100644 --- a/config/outbounds/socks.html +++ b/config/outbounds/socks.html @@ -5,7 +5,7 @@ Socks | Project X - + @@ -41,6 +41,6 @@ "level": 0 }
    1
    2
    3
    4
    5

    user: string

    用户名,字符串类型。必填。

    pass: string

    密码,字符串类型。必填。

    level: number

    用户等级,连接会使用这个用户等级对应的 本地策略

    userLevel 的值, 对应 policylevel 的值。 如不指定, 默认为 0。

    - + diff --git a/config/outbounds/trojan.html b/config/outbounds/trojan.html index 4eade3e09..35ea90f9b 100644 --- a/config/outbounds/trojan.html +++ b/config/outbounds/trojan.html @@ -5,7 +5,7 @@ Trojan | Project X - + @@ -28,6 +28,6 @@ "level": 0 }
    1
    2
    3
    4
    5
    6
    7

    address: address

    服务端地址,支持 IPv4、IPv6 和域名。必填。

    port: number

    服务端端口,通常与服务端监听的端口相同。

    password: string

    密码. 必填,任意字符串。

    email: string

    邮件地址,可选,用于标识用户

    level: number

    用户等级,连接会使用这个用户等级对应的 本地策略

    level 的值, 对应 policylevel 的值。 如不指定, 默认为 0。

    - + diff --git a/config/outbounds/vless.html b/config/outbounds/vless.html index c8fed345b..ae5d110d8 100644 --- a/config/outbounds/vless.html +++ b/config/outbounds/vless.html @@ -5,7 +5,7 @@ VLESS | Project X - + @@ -44,6 +44,6 @@ "level": 0 }
    1
    2
    3
    4
    5
    6

    id: string

    VLESS 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID. 自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)

    其映射标准在 VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5open in new window

    你可以使用命令 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 c7b1a2507..48c6f8b0e 100644 --- a/config/outbounds/vmess.html +++ b/config/outbounds/vmess.html @@ -5,7 +5,7 @@ VMess | Project X - + @@ -35,6 +35,6 @@ "level": 0 }
    1
    2
    3
    4
    5

    id:string

    Vmess 的用户 ID,可以是任意小于 30 字节的字符串, 也可以是一个合法的 UUID.

    自定义字符串和其映射的 UUID 是等价的, 这意味着你将可以这样在配置文件中写 id 来标识同一用户,即

    • "id": "我爱🍉老师1314",
    • 或写 "id": "5783a3e7-e373-51cd-8642-c83782b807c5" (此 UUID 是 我爱🍉老师1314 的 UUID 映射)

    其映射标准在 VLESS UUID 映射标准:将自定义字符串映射为一个 UUIDv5open in new window

    你可以使用命令 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 的包头都会受到加密和认证的保护。

    - + diff --git a/config/outbounds/wireguard.html b/config/outbounds/wireguard.html index a7016c15c..34504944f 100644 --- a/config/outbounds/wireguard.html +++ b/config/outbounds/wireguard.html @@ -5,7 +5,7 @@ Wireguard | Project X - + @@ -35,6 +35,6 @@ "allowedIPs": ["0.0.0.0/0"] // optional, default ["0.0.0.0/0", "::/0"] }
    1
    2
    3
    4
    5
    6
    7

    endpoint: address

    服务器地址, 必填

    提示

    使用 url:端口号 格式,形如 engage.cloudflareclient.com:2408

    publicKey: string

    服务器公钥,用于验证, 必填

    preSharedKey: string

    额外的对称加密密钥

    keepAlive: int

    心跳包时间间隔,单位为秒,默认为 0 表示无心跳

    allowedIPs: string array

    Wireguard 仅允许特定源 IP 的流量

    - + diff --git a/config/policy.html b/config/policy.html index 6b78ad707..c70808547 100644 --- a/config/policy.html +++ b/config/policy.html @@ -5,7 +5,7 @@ 本地策略 | Project X - + @@ -46,6 +46,6 @@ "statsOutboundDownlink": false }
    1
    2
    3
    4
    5
    6

    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 0e34997ff..d81f9ea42 100644 --- a/config/reverse.html +++ b/config/reverse.html @@ -5,7 +5,7 @@ 反向代理 | Project X - + @@ -125,6 +125,6 @@ ] }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    - + diff --git a/config/routing.html b/config/routing.html index d88b91172..7ce695eb0 100644 --- a/config/routing.html +++ b/config/routing.html @@ -5,7 +5,7 @@ 路由 | Project X - + @@ -38,6 +38,6 @@ "selector": [] }
    1
    2
    3
    4

    tag: string

    此负载均衡器的标识,用于匹配 RuleObject 中的 balancerTag

    selector: [ string ]

    一个字符串数组,其中每一个字符串将用于和 outbound 标识的前缀匹配。在以下几个 outbound 标识中:[ "a", "ab", "c", "ba" ]"selector": ["a"] 将匹配到 [ "a", "ab" ]

    如果匹配到多个 outbound,负载均衡器目前会从中随机选出一个作为最终的 outbound。

    预定义域名列表

    此列表预置于每一个 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 window

    - + diff --git a/config/stats.html b/config/stats.html index 447f70827..f5847fff5 100644 --- a/config/stats.html +++ b/config/stats.html @@ -5,7 +5,7 @@ 统计信息 | Project X - + @@ -13,6 +13,6 @@ "stats": {} }
    1
    2
    3

    目前统计信息不需要任何参数,只要 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 dfc3075c5..65958e96b 100644 --- a/config/transport.html +++ b/config/transport.html @@ -5,7 +5,7 @@ 传输方式 | Project X - + @@ -142,6 +142,6 @@ "interface": "wg0" }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    mark: number

    一个整数。当其值非零时,在 outbound 连接上以此数值标记 SO_MARK。

    • 仅适用于 Linux 系统。
    • 需要 CAP_NET_ADMIN 权限。

    tcpMaxSeg: number

    用于设置 TCP 数据包的最大传输单元。

    tcpFastOpen: true | false | number

    是否启用 TCP Fast Openopen in new window

    当其值为 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 window注意并非所有操作系统都支持在此设定

      • 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" | "UseIPv4" | "UseIPv6"

    在之前的版本中,当 Xray 尝试使用域名建立系统连接时,域名的解析由系统完成,不受 Xray 控制。这导致了在 非标准 Linux 环境中无法解析域名open in new window 等问题。为此,Xray 1.3.1 为 Sockopt 引入了 Freedom 中的 domainStrategy,解决了此问题。

    在目标地址为域名时, 配置相应的值, SystemDialer 的行为模式如下:

    • "AsIs": 通过系统 DNS 服务器解析获取 IP, 向此域名发出连接。
    • "UseIP""UseIPv4""UseIPv6": 使用内置 DNS 服务器解析获取 IP 后, 直接向此 IP 发出连接。

    默认值为 "AsIs"

    警告

    启用了此功能后,不当的配置可能会导致死循环。

    一句话版本:连接到服务器,需要等待 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 window 专用于传递请求的真实来源 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

    tcpcongestion: ""

    TCP 拥塞控制算法。仅支持 Linux。 不配置此项表示使用系统默认值。

    常见的算法

    • bbr(推荐)
    • cubic
    • reno

    提示

    执行命令 sysctl net.ipv4.tcp_congestion_control 获取系统默认值。

    interface: ""

    指定绑定出口网卡名称 仅支持 linux。

    最近更改: 2023/6/21 07:57:18
    Contributors: JimhHan, Jim Han, yuhan6665, xqzr, tdjnodj, Binbin Qian, Daniel Ding, Kobe Arthur Scofield, KoriIku, Winston2084, chika0801, flowerinsnow, lxsq, pvqogw, 风扇滑翔翼
    - + diff --git a/config/transports/domainsocket.html b/config/transports/domainsocket.html index 8f5bc69c5..246367d8a 100644 --- a/config/transports/domainsocket.html +++ b/config/transports/domainsocket.html @@ -5,7 +5,7 @@ Domain Socket | Project X - + @@ -15,6 +15,6 @@ "padding": false }
    1
    2
    3
    4
    5

    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 ab377ee9f..cf9467489 100644 --- a/config/transports/grpc.html +++ b/config/transports/grpc.html @@ -5,7 +5,7 @@ gRPC | Project X - + @@ -19,6 +19,6 @@ "initial_windows_size": 0 }
    1
    2
    3
    4
    5
    6
    7
    8
    9

    serviceName: string

    一个字符串,指定服务名称,类似于 HTTP/2 中的 Path。 客户端会使用此名称进行通信,服务端会验证服务名称是否匹配。

    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 dc73f2a83..ea0c99b50 100644 --- a/config/transports/h2.html +++ b/config/transports/h2.html @@ -5,7 +5,7 @@ HTTP/2 | Project X - + @@ -20,6 +20,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    host: [string]

    一个字符串数组,每一个元素是一个域名。

    客户端会随机从列表中选出一个域名进行通信,服务器会验证域名是否在列表中。

    path: string

    HTTP 路径,由 / 开头, 客户端和服务器必须一致。

    默认值为 "/"

    read_idle_timeout: number

    单位秒,当这段时间内没有接收到数据时,将会进行健康检查。

    健康检查默认不启用

    提示

    只需出站客户端)配置。

    提示

    可能会解决一些“断流”问题。

    health_check_timeout: number

    单位秒,健康检查的超时时间。如果在这段时间内没有完成健康检查,即认为健康检查失败。默认值为 15

    提示

    只需出站客户端)配置。

    method: string

    HTTP 方法。默认值为 "PUT"

    设置时应参照此处open in new window列出值。

    headers: map{ string: [string] }

    自定义 HTTP 头,一个键值对,每个键表示一个 HTTP 头名称,对应值为一个数组。

    - + diff --git a/config/transports/mkcp.html b/config/transports/mkcp.html index ce36b201e..57be40f7f 100644 --- a/config/transports/mkcp.html +++ b/config/transports/mkcp.html @@ -5,7 +5,7 @@ mKCP | Project X - + @@ -26,6 +26,6 @@ "type": "none" }
    1
    2
    3

    type: string

    伪装类型,可选的值有:

    • "none":默认值,不进行伪装,发送的数据是没有特征的数据包。
    • "srtp":伪装成 SRTP 数据包,会被识别为视频通话数据(如 FaceTime)。
    • "utp":伪装成 uTP 数据包,会被识别为 BT 下载数据。
    • "wechat-video":伪装成微信视频通话的数据包。
    • "dtls":伪装成 DTLS 1.2 数据包。
    • "wireguard":伪装成 WireGuard 数据包。(并不是真正的 WireGuard 协议)

    鸣谢

    对 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 8bb7783db..72d8b9835 100644 --- a/config/transports/quic.html +++ b/config/transports/quic.html @@ -5,7 +5,7 @@ QUIC | Project X - + @@ -20,6 +20,6 @@ "type": "none" }
    1
    2
    3

    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 5ce1211d2..ac8bcbd22 100644 --- a/config/transports/tcp.html +++ b/config/transports/tcp.html @@ -5,7 +5,7 @@ TCP | Project X - + @@ -50,6 +50,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    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 6f872a6da..36e812277 100644 --- a/config/transports/websocket.html +++ b/config/transports/websocket.html @@ -5,7 +5,7 @@ WebSocket | Project X - + @@ -17,6 +17,6 @@ } }
    1
    2
    3
    4
    5
    6
    7

    acceptProxyProtocol: true | false

    仅用于 inbound,指示是否接收 PROXY protocol。

    PROXY protocolopen in new window 专用于传递请求的真实来源 IP 和端口,若你不了解它,请先忽略该项

    常见的反代软件(如 HAProxy、Nginx)都可以配置发送它,VLESS fallbacks xver 也可以发送它。

    填写 true 时,最底层 TCP 连接建立后,请求方必须先发送 PROXY protocol v1 或 v2,否则连接会被关闭。

    path: string

    WebSocket 所使用的 HTTP 协议路径,默认值为 "/"

    如果路径中包含 ed 参数,将会启用 Early Data 以降低延迟,其值为首包长度阈值。如果首包长度超过此值,就不会启用 Early Data。建议的值为 2048。

    注意

    Early Data 使用 Sec-WebSocket-Protocol 头承载数据。如果你遇到兼容性问题,可以尝试调低阈值。

    headers: map {string: string}

    自定义 HTTP 头,一个键值对,每个键表示一个 HTTP 头的名称,对应的值是字符串。

    默认值为空。

    Browser Dialer

    使用浏览器处理 TLS,详见 Browser Dialer

    - + diff --git a/development/index.html b/development/index.html index 28cdb8cfc..0fe404bc6 100644 --- a/development/index.html +++ b/development/index.html @@ -5,11 +5,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 window修改而来,可以按顺序传输任意的数据流。

    - + diff --git a/development/intro/compile.html b/development/intro/compile.html index 8144ea92f..c54768543 100644 --- a/development/intro/compile.html +++ b/development/intro/compile.html @@ -5,7 +5,7 @@ 编译文档 | Project X - + @@ -21,6 +21,6 @@ go build -o xray -trimpath -ldflags "-s -w -buildid=" ./main
    1
    2
    3
    4
    5

    上传到服务器后,记得在服务器终端内执行 chmod +x xray

    提示

    执行 go tool dist list 查看所有支持的系统与架构。

    可复现构建:

    按照上述步骤,能够编译与 Release 中完全相同的二进制文件。

    注意

    请先确认您使用的 Golang 版本与编译 Release 的一致。

    - + diff --git a/development/intro/design.html b/development/intro/design.html index 820a9aa6f..351676c83 100644 --- a/development/intro/design.html +++ b/development/intro/design.html @@ -5,11 +5,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 7e437ee6b..0a703fb8c 100644 --- a/development/intro/guide.html +++ b/development/intro/guide.html @@ -5,7 +5,7 @@ 开发规范 | Project X - + @@ -21,6 +21,6 @@ │ ├── vmess ├── transport // 传输模块
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    编码规范

    基本与 Golang 官方所推荐做法一致,有一些例外。写在这里以方便大家熟悉 Golang。

    命名

    • 文件和目录名尽量使用单个英文单词,比如 hello.go;
      • 如果实在没办法,则目录使用连接线/文件名使用下划线连接两个(或多个单词),比如 hello-world/hello_again.go;
      • 测试代码使用 _test.go 结尾;
    • 类型使用 Pascal 命名法,比如 ConnectionHandler;
      • 对缩写不强制小写,即 HTML 不必写成 Html;
    • 公开成员变量也使用 Pascal 命名法;
    • 私有成员变量使用 小驼峰式命名法open in new window ,如 privateAttribute
    • 为了方便重构,方法建议全部使用 Pascal 命名法;
      • 完全私有的类型放入 internal

    内容组织

    • 一个文件包含一个主要类型,及其相关的私有函数等;
    • 测试相关的文件,如 Mock 等工具类,放入 testing 子目录。
    - + diff --git a/development/protocols/mkcp.html b/development/protocols/mkcp.html index c16a9ef7f..b65a8d012 100644 --- a/development/protocols/mkcp.html +++ b/development/protocols/mkcp.html @@ -5,11 +5,11 @@ mKCP 协议 | Project X - +

    mKCP 协议

    mKCP 是流式传输协议,由 KCP 协议open in new window 修改而来,可以按顺序传输任意的数据流。

    版本

    mKCP 没有版本号,不保证版本之间兼容性。

    依赖

    底层协议

    mKCP 是一个基于 UDP 的协议,所有通讯使用 UDP 传输。

    函数

    • fnv: FNV-1aopen in new window 哈希函数
      • 输入参数为任意长度的字符串;
      • 输入出一个 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 e5124fea0..df6fb527d 100644 --- a/development/protocols/muxcool.html +++ b/development/protocols/muxcool.html @@ -5,11 +5,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 101a8f875..323d4b2bc 100644 --- a/development/protocols/vless.html +++ b/development/protocols/vless.html @@ -5,11 +5,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 window),若无附加信息则无相关开销。

    我一直觉得“响应认证”不是必要的,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 window

    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 window。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 window

    客户端开发指引

    1. VLESS 协议本身还会有不兼容升级,但客户端配置文件参数基本上是只增不减的。iOS 客户端的协议实现则需紧跟升级。
    2. 视觉标准:UI 标识请统一用 VLESS,而不是 VLess / Vless / vless,配置文件不受影响,代码内则顺其自然。
    3. encryption 应做成输入框而不是选择框,新配置的默认值应为 none,若用户置空则应代填 none

    VLESS 分享链接标准

    感谢 a @DuckSoftopen in new window 的提案!

    详情请见 VMessAEAD / VLESS 分享链接标准提案open in new window

    - + diff --git a/development/protocols/vmess.html b/development/protocols/vmess.html index 181395be1..be0248665 100644 --- a/development/protocols/vmess.html +++ b/development/protocols/vmess.html @@ -5,11 +5,11 @@ VMess 协议 | Project X - +

    VMess 协议

    VMess 是一个加密传输协议,可以作为 Xray 客户端和服务器之间的桥梁。

    版本

    当前版本号为 1。

    依赖

    底层协议

    VMess 是一个基于 TCP 的协议,所有数据使用 TCP 传输。

    用户 ID

    ID 等价于 UUIDopen in new window,是一个 16 字节长的随机数,它的作用相当于一个令牌(Token)。 一个 ID 形如:de305d54-75b4-431b-adb2-eb6b9e546014,几乎完全随机,可以使用任何的 UUID 生成器来生成,比如这个open in new window

    用户 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 73f9d1857..24aab793f 100644 --- a/document/command.html +++ b/document/command.html @@ -5,7 +5,7 @@ 命令参数 | Project X - + @@ -53,6 +53,6 @@ certChainHash Calculate TLS certificates hash.
    1
    2
    3

    xray uuid

    生成 UUID。

    使用方法:

    xray uuid [-i "example"]
     
    1

    提示

    -config 没有指定时,Xray 将先后尝试从以下路径加载 config.json :

    • 工作目录(Working Directory)
    • 环境变量Xray.location.asset 所指定的路径
    - + diff --git a/document/config.html b/document/config.html index 12b2081d3..1d1ed5d2b 100644 --- a/document/config.html +++ b/document/config.html @@ -5,7 +5,7 @@ 配置运行 | Project X - + @@ -74,6 +74,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

    上述配置唯一要更改的地方是你的服务器 IP,配置中已注明。上述配置会把除局域网(比如访问路由器)以外的所有流量转发至你的服务器。

    运行

    • 在 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 f9371beba..9f6437617 100644 --- a/document/document.html +++ b/document/document.html @@ -5,7 +5,7 @@ 为 Project X 的文档贡献 | Project X - + @@ -13,6 +13,6 @@
    1
    1. 基于 main 分支创建新的分支, 如:
    git checkout -b your-branch
     
    1
    1. 在新分支上做修改。

      注:推荐 中文文案排版指北open in new window

    2. 修改完成后,请使用 Prettieropen in new window 格式化您的更改。

      注:存在格式问题的 PR,将有可能被拒绝。

    3. 提交修改,并推送到您的仓库中

    git push -u origin your-branch
     
    1
    1. 打开 GitHub, 点击 'Pull request' 向 project X 文档仓库open in new window 提交 PR。

    2. 请在 PR 的标题和正文中,概述此次 PR 新增/修改的内容等;

    3. 等待回应, 如果 PR 被 merge, 您做的修改将直接呈现在 Project X 文档网站open in new window

    发现问题?

    如果您发现文档出错,可以改进文档或提交一个 Issue。

    - + diff --git a/document/index.html b/document/index.html index b50262d37..7255e4202 100644 --- a/document/index.html +++ b/document/index.html @@ -5,11 +5,11 @@ 快速入门 | Project X - +

    快速入门

    这个章节将告诉您如何用最简单的方式获得 Xray,并且开始使用 Xray。

    下载安装

    Xray 支持各种平台,并且您可以从多种渠道和方式获得 Xray 的各种版本。

    请点击 如何下载安装 Xray 以获取 Xray

    配置运行

    下载并安装 Xray 后,只需对他进行配置即可使用。

    请点击 如何配置运行 Xray 以学习最简单的配置方式。

    命令参数

    Xray 有多种命令和参数可用,因此变得灵活和强大。

    请点击 Xray 的命令参数 查看 Xray 的更多命令和参数用法。

    改进文档

    如果你有兴趣,请点击 使用文档 帮助我们改进文档,或者点击页面下方的 帮助我们改善此页面!

    我们十分感谢每一位 Contributor 作出的贡献!是你们让 Project X 变得更加强大!

    小小白白话文

    给予新手指导的使用心得

    请点击 小小白白话文 以进行查看。

    入门技巧

    具备了基础之后,你就可以通过 入门技巧 来探索更多的使用方式了。

    进阶文档

    给予进阶用户指导的使用技巧

    点击 进阶文档 以进行查看

    感谢

    非常感谢大家无私分享使用技巧和心得, 使得 Xray 日益强大。

    - + diff --git a/document/install.html b/document/install.html index 698fa624f..5fc82212a 100644 --- a/document/install.html +++ b/document/install.html @@ -5,11 +5,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 window 中找到。

    下载对应平台的压缩包,解压后即可使用。

    验证安装包

    Xray 提供两种验证方式:

    • ZIP 压缩包的 SHA1 / SHA256 摘要
    • 可复现构建:请参照 编译 Xray

    Windows 安装方式

    macOS 安装方式

    Linux 安装方式

    安装脚本

    Arch Linux

    Arch User Repository

    需要使用 AUR helpersopen in new window,以 yayopen in new window 为例,可通过 yay -S xray 安装。

    Arch Linux CN

    首先添加 Arch Linux CN 仓库open in new window,然后在 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/local/share/xray/geoip.dat:IP 数据文件
    • /usr/local/share/xray/geosite.dat:域名数据文件

    图形化客户端

    UUID 生成器

    第三方的 UUID 生成器 uuidgenerator.netopen in new window

    - + diff --git a/document/level-0/ch01-preface.html b/document/level-0/ch01-preface.html index 0e48582fe..8b80e1a66 100644 --- a/document/level-0/ch01-preface.html +++ b/document/level-0/ch01-preface.html @@ -5,11 +5,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 3b01d1f0e..43914bedb 100644 --- a/document/level-0/ch02-preparation.html +++ b/document/level-0/ch02-preparation.html @@ -5,11 +5,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 bdac8041f..f2a2e8221 100644 --- a/document/level-0/ch03-ssh.html +++ b/document/level-0/ch03-ssh.html @@ -5,13 +5,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 window,选择适合你操作系统的版本下载。(本文以 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
       
      1
    5. 然后请输入第二条命令,并在询问是否继续安装 (Y/n) 时输入 y 并回车确认,开始安装

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

      初次软件更新流程演示

    3.4 你的进度

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

    ⬛⬛⬛⬜⬜⬜⬜⬜ 37.5%

    - + diff --git a/document/level-0/ch04-security.html b/document/level-0/ch04-security.html index 92cbe247f..53ada0d22 100644 --- a/document/level-0/ch04-security.html +++ b/document/level-0/ch04-security.html @@ -5,7 +5,7 @@ 【第 4 章】安全防护篇 | Project X - + @@ -20,6 +20,6 @@
    1
  • 修改 SSH 配置。这个我们已经用了很多次,但现在我们已经从无所不能的root变成了普通用户vpsadmin,此时的我们是没有权限直接编辑 SSH 配置的。这时候就需要使用sudo命令了:

    sudo nano /etc/ssh/sshd_config
     
    1
  • 找到(ctrl+w) PasswordAuthentication 改成 no

  • 找到(ctrl+w) PubkeyAuthentication 改成 yes,然后保存(ctrl+o)退出(ctrl+x)

  • 重启 SSH 服务。(啰嗦君:别忘了现在需要使用sudo来获得权限)

    sudo systemctl restart ssh
     
    1
  • 完整流程如下:

    SSH开启密钥验证并禁用密码验证

  • VPS 端已经设置好了公钥,现在要给 PuTTY 指定私钥位置供登录时使用(啰嗦君:别忘了保存 Session)

    PuTTY指定私钥位置

  • 至此,【密钥登录】已成功开启、【密码验证】已成功关闭、并且还给 PuTTY 保存了默认的登录用户名和私钥。未来使用 PuTTY 登录时,载入VPS-SERVER配置后,点击Open就可以一键登录了。

    如果你给私钥设置了密码保护,登录时当然还需要输入这个密码才能使用密钥,如下图:

    输入私钥密码

  • 别忘了给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 4e873fb71..849b09532 100644 --- a/document/level-0/ch05-webpage.html +++ b/document/level-0/ch05-webpage.html @@ -5,7 +5,7 @@ 【第 5 章】网站建设篇 | Project X - + @@ -56,6 +56,6 @@ }
    1
    2
    3
    4
    5
    6

    特别注意!

    如我在【第 3 步】中的提示所说,请务必确保 /home/vpsadmin/www/webpage 改成你的实际文件路径。

  • nginx 重新载入配置使其生效

    sudo systemctl reload nginx
     
    1
  • 完整的设置流程如下:

    网页设置演示

  • 此时如果你访问 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 3b49ca112..13227e3be 100644 --- a/document/level-0/ch06-certificates.html +++ b/document/level-0/ch06-certificates.html @@ -5,7 +5,7 @@ 【第 6 章】证书管理篇 | Project X - + @@ -117,6 +117,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
    1
    2
    3
    4

    6.6 你的进度

    至此,Xray 所需要的两个基础设施终于全部就位!千呼万唤始出来的 Xray 马上就要揭开面纱,我们终于要进入最激动人心章节啦!

    ⬛⬛⬛⬛⬛⬛⬜⬜ 75%

    - + diff --git a/document/level-0/ch07-xray-server.html b/document/level-0/ch07-xray-server.html index b8f840853..80e97ec32 100644 --- a/document/level-0/ch07-xray-server.html +++ b/document/level-0/ch07-xray-server.html @@ -5,7 +5,7 @@ 【第 7 章】Xray 服务器篇 | Project X - + @@ -169,6 +169,6 @@
    1
    1. 修改 Xray 的回落设置,将回落从 80 端口改为 8080 端口。(找到 "dest": 80, 并改成 "dest": 8080
    sudo nano /usr/local/etc/xray/config.json
     
    1
    1. 重启 Xray 服务,即完成了设置
    sudo systemctl restart xray
     
    1
    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 132f31c96..0f6c52903 100644 --- a/document/level-0/ch08-xray-clients.html +++ b/document/level-0/ch08-xray-clients.html @@ -5,7 +5,7 @@ 【第 8 章】Xray 客户端篇 | Project X - + @@ -162,6 +162,6 @@
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150

    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
       
      1

      说明

      这里的 -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
       
      1

      说明

      每个系统都有系统路径变量,所以写 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 window - 官方文档站
    2. 官方 Telegram 群组open in new window - 活跃而友善的官方讨论社区

    TO INFINITY AND BEYOND!

    不算后记的后记

    希望我陪你走过的这一段小小的旅程,可以成为你网络生活中的一份小小助力。

    这篇文章里的工具和信息难免会一点点的陈旧过时,但你一定会逐渐成长为大佬。未来的某个时间,若你能偶尔想起这篇教程、想起我写下本文的初衷,那我衷心希望你能够薪火相传、把最新的知识分享给后来人,让这一份小小的助力在社区里坚定的传递下去。

    这是个大雪封山乌云密布的世界,人们孤独的走在各自的路上试图寻找阳光,如果大家偶尔交汇时不能守望相助互相鼓励,那最终剩下的,恐怕只有【千山鸟飞绝 万径人踪灭】的凄凉了吧。

    - + diff --git a/document/level-0/ch09-appendix.html b/document/level-0/ch09-appendix.html index b7b59d398..c2d8d40a7 100644 --- a/document/level-0/ch09-appendix.html +++ b/document/level-0/ch09-appendix.html @@ -5,11 +5,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 79354fc84..7f45cd3be 100644 --- a/document/level-0/index.html +++ b/document/level-0/index.html @@ -5,11 +5,11 @@ 小小白白话文 | Project X - + - + diff --git a/document/level-1/fallbacks-lv1.html b/document/level-1/fallbacks-lv1.html index 78ec0c63b..1d3ca8d89 100644 --- a/document/level-1/fallbacks-lv1.html +++ b/document/level-1/fallbacks-lv1.html @@ -5,7 +5,7 @@ 回落 (fallbacks) 功能简析 | Project X - + @@ -181,6 +181,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
  • 至此,我们就能够完整的画出模板的回落路线了:

  • 6. 结语

    至此,Xray 的【回落】功能就介绍完了。希望本文能够对你理解 Xray 的强大有所帮助。

    7. 附加题

    我再无耻的留一个附加题:本文详解的 VLESS-TCP-XTLS-WHATEVERopen in new window 模板?是否有可以优化的地方?

    提示:HTTP 自动跳转 HTTPS

    - + diff --git a/document/level-1/fallbacks-with-sni.html b/document/level-1/fallbacks-with-sni.html index 0bcaa747f..11bb06435 100644 --- a/document/level-1/fallbacks-with-sni.html +++ b/document/level-1/fallbacks-with-sni.html @@ -5,7 +5,7 @@ SNI 回落 | Project X - + @@ -191,6 +191,6 @@ redir https://{host}{uri} permanent }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    参考

    1. 服务器名称指示 - 维基百科,自由的百科全书open in new window
    2. Home · acmesh-official/acme.sh Wikiopen in new window
    3. HTTP/2 - 维基百科,自由的百科全书open in new window

    引用


    1. 常见问题 - Let's Encrypt - 免费的 SSL/TLS 证书open in new window ↩︎

    2. Proxy Protocol - HAProxy Technologiesopen in new window ↩︎

    3. proxy protocol 介绍及 nginx 配置 - 简书open in new window ↩︎

    4. v2fly-github-io/vless.md at master · rprx/v2fly-github-ioopen in new window ↩︎

    - + diff --git a/document/level-1/index.html b/document/level-1/index.html index 348fc2509..7e5678405 100644 --- a/document/level-1/index.html +++ b/document/level-1/index.html @@ -5,11 +5,11 @@ 入门技巧 | Project X - + - + diff --git a/document/level-1/routing-lv1-part1.html b/document/level-1/routing-lv1-part1.html index 2ce85e6be..f0640018e 100644 --- a/document/level-1/routing-lv1-part1.html +++ b/document/level-1/routing-lv1-part1.html @@ -5,7 +5,7 @@ 路由 (routing) 功能简析(上) | Project X - + @@ -122,6 +122,6 @@ ] }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    此时,路由规则其实变成了:

    这就是路由功能的灵活之处了,你可以自由的改变它的顺序来实现不同的设计。

    至此,我们已经解释完了 【如何利用 geosite.dat 文件,通过路由规则,根据【域名】来分流网络流量】。

    5. 攻城略池 - 多种路由匹配条件

    请确保你已经读懂了上面的内容,因为这样,你就已经理解了【路由】功能的工作逻辑。有了这个基础,我们就可以继续分析【路由】功能更多更详细的配置方式和匹配条件了。

    等你看完后面的内容,就完全可以自由的定制属于自己的路由规则啦!还等什么,让我们一起进入 《路由 (routing) 功能简析(下)》 吧!

    - + diff --git a/document/level-1/routing-lv1-part2.html b/document/level-1/routing-lv1-part2.html index 96794927b..1ce162ce3 100644 --- a/document/level-1/routing-lv1-part2.html +++ b/document/level-1/routing-lv1-part2.html @@ -5,7 +5,7 @@ 路由 (routing) 功能简析(下) | Project X - + @@ -168,6 +168,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    其实,第 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 efd36dc53..5ae076963 100644 --- a/document/level-1/work.html +++ b/document/level-1/work.html @@ -5,11 +5,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 0e448b0cd..c525d65a2 100644 --- a/document/level-2/index.html +++ b/document/level-2/index.html @@ -5,11 +5,11 @@ 进阶文档 | Project X - +

    进阶文档

    这个章节包含进阶级的 Xray 使用心得分享, 如果您已经熟悉 Xray, 那么这里的经验可以让您更加发挥 Xray 的威力

    透明代理入门 by a @kirinopen in new window

    透明代理的入门篇章。

    透明代理(TProxy)配置教程 by a @BioniCosmosopen in new window

    基于 Xray 的透明代理(TProxy)配置完整教程。

    TProxy 透明代理(ipv4 and ipv6)配置教程 by a @SQLimitopen in new window

    基于 Xray 的 TProxy 透明代理(ipv4 and ipv6)配置教程

    Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹 by a @SQLimitopen in new window

    双端使用 Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹

    [透明代理]通过 gid 规避 Xray 流量 by a @kirinopen in new window

    在 iptables/nftables 实现的透明代理中,一种新的规避 Xray 流量的方式。

    通过 Xray 将特定的流量指向特定出口,实现全局路由“分流” by a @Zzz3mopen in new window

    将 Xray 玩出花:基于 fwmark 或 sendThrough 方式实现“分流”。

    通过 Cloudflare Warp 增强代理安全性 by a @yuhan6665open in new window

    Xray v1.6.5 新增 WireGuard 出站的使用介绍。

    Xray 流量统计 by a @yuhan6665open in new window

    适配 Xray 的流量统计和脚本。

    - + diff --git a/document/level-2/iptables_gid.html b/document/level-2/iptables_gid.html index d37c6451c..596e657ea 100644 --- a/document/level-2/iptables_gid.html +++ b/document/level-2/iptables_gid.html @@ -5,7 +5,7 @@ GID 透明代理 | Project X - + @@ -107,6 +107,6 @@ ip6tables -t mangle -A OUTPUT -p tcp -j XRAY6_MASK ip6tables -t mangle -A OUTPUT -p udp -j XRAY6_MASK
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    - + diff --git a/document/level-2/nginx_or_haproxy_tls_tunnel.html b/document/level-2/nginx_or_haproxy_tls_tunnel.html index 0204f26c3..f15e7d97c 100644 --- a/document/level-2/nginx_or_haproxy_tls_tunnel.html +++ b/document/level-2/nginx_or_haproxy_tls_tunnel.html @@ -5,7 +5,7 @@ Nginx 或 Haproxy 搭建 TLS 隧道隐藏指纹 | Project X - + @@ -529,6 +529,6 @@ backend web server web /dev/shm/h1h2c.sock
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47

    xray 配置

    简单的 gRPC 配置,无需 TLS,配置见文档,配置的 serviceName 可用于分流。

    - + diff --git a/document/level-2/redirect.html b/document/level-2/redirect.html index baca5b9b1..ef59325ce 100644 --- a/document/level-2/redirect.html +++ b/document/level-2/redirect.html @@ -5,7 +5,7 @@ 出站流量重定向 | Project X - + @@ -221,6 +221,6 @@
    1

    开机自启

    systemctl enable wg-quick@wg0
     systemctl start wg-quick@wg0
     
    1
    2

    验证 IPv4/IPv6

    自行验证 Google 搜索 myip

    后记

    本文本意是可以避免的多余的流量浪费,将路由和分流的功能交给 Xray 处理。避免了维护路由表的繁琐工作。顺便技术提升 UP。

    感谢

    @Xray-core @V2ray-core @WireGuard @p3terx @w @Hiram @Luminous @Ln @JackChou

    - + diff --git a/document/level-2/tproxy.html b/document/level-2/tproxy.html index 1e92ec008..9d03feeeb 100644 --- a/document/level-2/tproxy.html +++ b/document/level-2/tproxy.html @@ -5,7 +5,7 @@ TProxy 透明代理 | Project X - + @@ -262,6 +262,6 @@ [Install] WantedBy=multi-user.target
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    - + diff --git a/document/level-2/tproxy_ipv4_and_ipv6.html b/document/level-2/tproxy_ipv4_and_ipv6.html index 2a9151548..e44b81b2e 100644 --- a/document/level-2/tproxy_ipv4_and_ipv6.html +++ b/document/level-2/tproxy_ipv4_and_ipv6.html @@ -5,7 +5,7 @@ TProxy 透明代理 (ipv4 and ipv6) | Project X - + @@ -410,6 +410,6 @@ [Install] WantedBy=multi-user.target
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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 4b2ea56ad..119c347d7 100644 --- a/document/level-2/traffic_stats.html +++ b/document/level-2/traffic_stats.html @@ -5,7 +5,7 @@ 流量统计 | Project X - + @@ -101,6 +101,6 @@ print_sum "$DATA" "user" echo "-----------------------------"
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    - + diff --git a/document/level-2/transparent_proxy/transparent_proxy.html b/document/level-2/transparent_proxy/transparent_proxy.html index f82110180..f807e37c6 100644 --- a/document/level-2/transparent_proxy/transparent_proxy.html +++ b/document/level-2/transparent_proxy/transparent_proxy.html @@ -5,7 +5,7 @@ 透明代理入门 | Project X - + @@ -92,6 +92,6 @@ iptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK iptables -t mangle -A OUTPUT -p udp -j XRAY_MASK
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

    但是这么配置有个缺点,如果使用 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 window 中的第三条说:手动配置 PC 的网络,将默认网关指向树莓派的地址即 192.168.1.22。此时 PC 应当能正常上网(由于还没设置代理,“正常”是指可以上国内的网站)。实际上,Ubuntu、CentOS、debian 等系统就算开启了 IP 转发,PC 也不能正常上网,这是正常的。事实上只有 OpenWRT 能做到文中所描述的那样,据 @BioniCosmosopen in new window 点拨,这是由于一般的 Linux 系统没有 Masquery 规则。

    3. too many open files 问题open in new window ,解决方法见 [透明代理]通过 gid 规避 Xray 流量-配置最大文件大开数&运行 Xray 客户端

    4. 关于开启 ip_forward,待补充...

    5. 避免已有连接的包二次通过 TPROXY ,待补充...

    6. 主路由、单臂路由与旁路由,待补充...

    - + diff --git a/document/level-2/warp.html b/document/level-2/warp.html index 938a8b56e..2e41ca836 100644 --- a/document/level-2/warp.html +++ b/document/level-2/warp.html @@ -5,7 +5,7 @@ 通过 Cloudflare Warp 增强代理安全性 | Project X - + @@ -92,6 +92,6 @@ ] }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    - + diff --git a/en/about/news.html b/en/about/news.html index fb1b54b18..ea58400aa 100644 --- a/en/about/news.html +++ b/en/about/news.html @@ -5,11 +5,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 window

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

    2021.3.25

    没错还在变。 -_-

    2021.3.15

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

    2021.3.14 v1.4.0open in new window

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

    2021.3.3 1.3.1open in new window

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

    2021.2.14 1.3.0open in new window

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

    2021.01.31 1.2.4open in new window

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

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

    2021.01.25

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

    2021.01.22 1.2.3open in new window

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

    2021.01.19

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

    2021.01.17

    2021.01.15 1.2.2open in new window

    • 回落分流又解锁了奇怪的新姿势! 回落中可以根据 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 window

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

    2021.01.07

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

    2021.01.05

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

    2021.01.03

    2021.01.01

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

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

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

    2020.12.29

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

    2020.12.25 1.1.5open in new window

    圣诞节快乐!

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

    2020.12.24

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

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

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

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

    2020.12.23

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

    2020.12.21

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

    2020.12.18 1.1.4open in new window

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

    2020.12.17

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

    2020.12.15

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

    2020.12.11 1.1.3open in new window

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

    2020.12.06 1.1.2open in new window

    • 流控增加 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 window

    Xray 的第一个版本.

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

    2020.11.23

    project X start

    梦开始的时候

    - + diff --git a/en/config/api.html b/en/config/api.html index 2180e6c65..8756608fa 100644 --- a/en/config/api.html +++ b/en/config/api.html @@ -5,7 +5,7 @@ API Interface | Project X - + @@ -44,6 +44,6 @@ xray.app.proxyman.command.HandlerService xray.app.stats.command.StatsService
    1
    2
    3
    4
    5
    6

    API Calling Example

    Xray-API-documentsopen in new window @crossfw

    - + diff --git a/en/config/dns.html b/en/config/dns.html index f2c011d31..afa85e3ed 100644 --- a/en/config/dns.html +++ b/en/config/dns.html @@ -5,7 +5,7 @@ Built-in DNS Server | Project X - + @@ -45,6 +45,6 @@ "clientIP": "1.2.3.4" }
    1
    2
    3
    4
    5
    6
    7
    8

    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 a59af8316..1cec42fa8 100644 --- a/en/config/fakedns.html +++ b/en/config/fakedns.html @@ -5,7 +5,7 @@ FakeDNS | Project X - + @@ -111,6 +111,6 @@ ] }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    - + diff --git a/en/config/features/browser_dialer.html b/en/config/features/browser_dialer.html index 5cc7953a8..afa355df3 100644 --- a/en/config/features/browser_dialer.html +++ b/en/config/features/browser_dialer.html @@ -5,11 +5,11 @@ Browser Dialer | Project X - +

    Browser Dialer

    BETA v1.4.1+

    Background

    Based on an idea from 2020open in new window, 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 window 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 266230414..b396ab784 100644 --- a/en/config/features/env.html +++ b/en/config/features/env.html @@ -5,7 +5,7 @@ Environment Variables | Project X - + @@ -13,6 +13,6 @@ /usr/local/share/xray /usr/share/xray
    1
    2
    3

    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 391c62ef3..069d1a199 100644 --- a/en/config/features/fallback.html +++ b/en/config/features/fallback.html @@ -5,7 +5,7 @@ Fallback | Project X - + @@ -22,6 +22,6 @@ "xver": 0 }
    1
    2
    3
    4
    5
    6
    7

    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 window, 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 window 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 window, 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 5eb10dddf..562090463 100644 --- a/en/config/features/multiple.html +++ b/en/config/features/multiple.html @@ -5,7 +5,7 @@ Multi-file configuration | Project X - + @@ -84,6 +84,6 @@ 0 directories, 10 files
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    - + diff --git a/en/config/features/xtls.html b/en/config/features/xtls.html index 6740645c4..cffcb512e 100644 --- a/en/config/features/xtls.html +++ b/en/config/features/xtls.html @@ -5,11 +5,11 @@ Deep analysis of XTLS | Project X - + - + diff --git a/en/config/inbound.html b/en/config/inbound.html index e7c237c34..271f260d8 100644 --- a/en/config/inbound.html +++ b/en/config/inbound.html @@ -5,7 +5,7 @@ Inbound Proxy | Project X - + @@ -43,6 +43,6 @@ "concurrency": 3 }
    1
    2
    3
    4
    5

    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 6a7036d8c..e5d6838e4 100644 --- a/en/config/inbounds/dokodemo.html +++ b/en/config/inbounds/dokodemo.html @@ -5,7 +5,7 @@ Dokodemo-Door | Project X - + @@ -18,6 +18,6 @@ "userLevel": 0 }
    1
    2
    3
    4
    5
    6
    7
    8

    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 0d5308dca..89e865304 100644 --- a/en/config/inbounds/http.html +++ b/en/config/inbounds/http.html @@ -5,7 +5,7 @@ HTTP | Project X - + @@ -25,6 +25,6 @@ "pass": "my-password" }
    1
    2
    3
    4

    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 552d5d8da..fbbf63f65 100644 --- a/en/config/inbounds/shadowsocks.html +++ b/en/config/inbounds/shadowsocks.html @@ -5,7 +5,7 @@ Shadowsocks | Project X - + @@ -25,6 +25,6 @@ "email": "love@xray.com" }
    1
    2
    3
    4
    5
    6

    method: string

    Required.

    password: string

    Required.

    • Shadowsocks 2022

    Use a pre-shared key similar to WireGuard as the password.

    Use openssl rand -base64 <length> to generate a compatible key with shadowsocks-rust, 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. There is no limitation 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

    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 (logs, statistics).

    - + diff --git a/en/config/inbounds/socks.html b/en/config/inbounds/socks.html index 5d9d5478e..5d0158a8a 100644 --- a/en/config/inbounds/socks.html +++ b/en/config/inbounds/socks.html @@ -5,7 +5,7 @@ SOCKS | Project X - + @@ -26,6 +26,6 @@ "pass": "my-password" }
    1
    2
    3
    4

    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 4cd14fff8..961fe6034 100644 --- a/en/config/inbounds/trojan.html +++ b/en/config/inbounds/trojan.html @@ -5,7 +5,7 @@ Trojan | Project X - + @@ -29,6 +29,6 @@ "level": 0 }
    1
    2
    3
    4
    5

    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 80195c3cf..11f8b8490 100644 --- a/en/config/inbounds/vless.html +++ b/en/config/inbounds/vless.html @@ -5,7 +5,7 @@ VLESS | Project X - + @@ -32,6 +32,6 @@ "flow": "xtls-rprx-vision" }
    1
    2
    3
    4
    5
    6

    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 window.

    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 003139be5..271d8e151 100644 --- a/en/config/inbounds/vmess.html +++ b/en/config/inbounds/vmess.html @@ -5,7 +5,7 @@ VMess | Project X - + @@ -36,6 +36,6 @@ "level": 0 }
    1
    2
    3

    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 a1981a471..d2cc18820 100644 --- a/en/config/index.html +++ b/en/config/index.html @@ -5,7 +5,7 @@ Configurations | Project X - + @@ -23,6 +23,6 @@ "fakedns": {} }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    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 configuration, which controls the way Xray outputs logs.

    api:ApiObject

    Provides some API interfaces for remote calls.

    dns: DnsObject

    Built-in DNS server. If this item is not configured, the system's DNS settings will be used.

    routing: RoutingObject

    Routing function. You can set rules to route data to different outbounds.

    policy: PolicyObject

    Local policy, which can set different user levels and corresponding policy settings.

    inbounds: [ InboundObject ]

    An array, with each element being an inbound connection configuration.

    outbounds: [ OutboundObject ]

    An array, with each element being an outbound connection configuration.

    transport: TransportObject

    Used to configure the way Xray establishes and uses network connections with other servers.

    stats: StatsObject

    Used to configure traffic data statistics.

    reverse: ReverseObject

    Reverse proxy. You can forward server-side traffic to the client, that is, reverse traffic forwarding.

    fakedns: FakeDnsObject

    FakeDNS configuration. It can be used with transparent proxy to obtain the actual domain name.

    - + diff --git a/en/config/log.html b/en/config/log.html index 7443e0194..b6255968c 100644 --- a/en/config/log.html +++ b/en/config/log.html @@ -5,7 +5,7 @@ Log Configuration | Project X - + @@ -18,6 +18,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8

    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/outbound.html b/en/config/outbound.html index 25c66931a..1495f3f2c 100644 --- a/en/config/outbound.html +++ b/en/config/outbound.html @@ -5,7 +5,7 @@ Outbound Proxies | Project X - + @@ -32,6 +32,6 @@ "concurrency": 8 }
    1
    2
    3
    4

    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 aba1ceab4..f40a16026 100644 --- a/en/config/outbounds/blackhole.html +++ b/en/config/outbounds/blackhole.html @@ -5,7 +5,7 @@ Blackhole | Project X - + @@ -18,6 +18,6 @@ "type": "none" }
    1
    2
    3

    type: "http" | "none"

    When type is set to "none" (default value), the blackhole will simply close the connection.

    When type is set to "http", the blackhole will send a simple HTTP 403 packet as the response and then close the connection.

    - + diff --git a/en/config/outbounds/dns.html b/en/config/outbounds/dns.html index 302859c31..afbad4717 100644 --- a/en/config/outbounds/dns.html +++ b/en/config/outbounds/dns.html @@ -5,7 +5,7 @@ DNS | Project X - + @@ -16,6 +16,6 @@ "nonIPQuery": "drop" }
    1
    2
    3
    4
    5
    6

    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 8c51ac9e0..20e16901d 100644 --- a/en/config/outbounds/freedom.html +++ b/en/config/outbounds/freedom.html @@ -5,7 +5,7 @@ Freedom | Project X - + @@ -20,6 +20,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    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)

    - + diff --git a/en/config/outbounds/http.html b/en/config/outbounds/http.html index 424e4efa8..c4c4d2559 100644 --- a/en/config/outbounds/http.html +++ b/en/config/outbounds/http.html @@ -5,7 +5,7 @@ HTTP | Project X - + @@ -38,6 +38,6 @@ "pass": "my-password" }
    1
    2
    3
    4

    user: string

    The username. Required.

    pass: string

    The password. Required.

    - + diff --git a/en/config/outbounds/shadowsocks.html b/en/config/outbounds/shadowsocks.html index 55b65cd5e..2ea127efd 100644 --- a/en/config/outbounds/shadowsocks.html +++ b/en/config/outbounds/shadowsocks.html @@ -5,7 +5,7 @@ Shadowsocks | Project X - + @@ -32,6 +32,6 @@ "level": 0 }
    1
    2
    3
    4
    5
    6
    7
    8
    9

    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 6d1f2bc47..333b0fa6e 100644 --- a/en/config/outbounds/socks.html +++ b/en/config/outbounds/socks.html @@ -5,7 +5,7 @@ Socks | Project X - + @@ -41,6 +41,6 @@ "level": 0 }
    1
    2
    3
    4
    5

    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 537615b35..d4b153ad4 100644 --- a/en/config/outbounds/trojan.html +++ b/en/config/outbounds/trojan.html @@ -5,7 +5,7 @@ Trojan | Project X - + @@ -28,6 +28,6 @@ "level": 0 }
    1
    2
    3
    4
    5
    6
    7

    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 9277aa30b..ee9d9b4b7 100644 --- a/en/config/outbounds/vless.html +++ b/en/config/outbounds/vless.html @@ -5,7 +5,7 @@ VLESS | Project X - + @@ -44,6 +44,6 @@ "level": 0 }
    1
    2
    3
    4
    5
    6

    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 window

    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 933ef7a4a..8053f3459 100644 --- a/en/config/outbounds/vmess.html +++ b/en/config/outbounds/vmess.html @@ -5,7 +5,7 @@ VMess | Project X - + @@ -35,6 +35,6 @@ "level": 0 }
    1
    2
    3
    4
    5

    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 window.

    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 f465e0154..2f55f01b2 100644 --- a/en/config/outbounds/wireguard.html +++ b/en/config/outbounds/wireguard.html @@ -5,7 +5,7 @@ Wireguard | Project X - + @@ -34,6 +34,6 @@ "allowedIPs": ["0.0.0.0/0"] // optional, default ["0.0.0.0/0", "::/0"] }
    1
    2
    3
    4
    5
    6
    7

    endpoint: address

    The server address. Required.

    Tip

    Use the format url:port, for example, engage.cloudflareclient.com: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 3351fcddc..ccca9f234 100644 --- a/en/config/policy.html +++ b/en/config/policy.html @@ -5,7 +5,7 @@ Local Policy | Project X - + @@ -46,6 +46,6 @@ "statsOutboundDownlink": false }
    1
    2
    3
    4
    5
    6

    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 d10bc14c7..c51840afe 100644 --- a/en/config/reverse.html +++ b/en/config/reverse.html @@ -5,7 +5,7 @@ Reverse Proxy | Project X - + @@ -125,6 +125,6 @@ ] }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    - + diff --git a/en/config/routing.html b/en/config/routing.html index 6b8364d90..9f3b36b3d 100644 --- a/en/config/routing.html +++ b/en/config/routing.html @@ -5,7 +5,7 @@ Routing | Project X - + @@ -33,11 +33,11 @@ "outboundTag": "direct", "balancerTag": "balancer" } -
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    Danger

    When multiple attributes are specified at the same time, these attributes need to be satisfied simultaneously in order for the current rule to take effect.

    domainMatcher: "hybrid" | "linear"

    The domain matching algorithm used varies depending on the settings. The option here takes priority over the domainMatcher configured in RoutingObject.

    • "hybrid": uses a new domain matching algorithm that is faster and takes up less space. This is the default value.
    • "linear": uses the original domain matching algorithm.

    type: "field"

    Currently, only the option "field" is supported.

    domain: [string]

    An array where each item is a domain match. There are several forms:

    • Plain string: If this string matches any part of the target domain, the rule takes effect. For example, "sina.com" can match "sina.com", "sina.com.cn", and "www.sina.com", but not "sina.cn".
    • Regular expression: Starts with "regexp:" followed by a regular expression. When this regular expression matches the target domain, the rule takes effect. For example, "regexp:\.goo.*\.comquot; matches "www.google.com" or "fonts.googleapis.com", but not "google.com".
    • Subdomain (recommended): Starts with "domain:" followed by a domain. When this domain is the target domain or a subdomain of the target domain, the rule takes effect. For example, "domain:xray.com" matches "www.xray.com" and "xray.com", but not "wxray.com".
    • Exact match: Starts with "full:" followed by a domain. When this domain is an exact match for the target domain, the rule takes effect. For example, "full:xray.com" matches "xray.com" but not "www.xray.com".
    • Predefined domain list: Starts with "geosite:" followed by a name such as geosite:google or geosite:cn. The names and domain lists are listed in Predefined Domain List.
    • Load domains from a file: Formatted as "ext:file:tag", where the file is stored in the resource directory and has the same format as geosite.dat. The tag must exist in the file.

    Tip

    "ext:geoip.dat:cn" is equivalent to "geoip:cn"

    ip: [string]

    An array where each item represents an IP range. This rule will take effect when the target IP matches any of the IP ranges in the array. There are several types of IP ranges:

    • IP: In the format of "127.0.0.1".

    • CIDRopen in new window: In the format of "10.0.0.0/8".

    • Predefined IP lists: These lists are included in every Xray installation package under the file name geoip.dat. They can be used in the format of "geoip:cn", where cn is a two-letter country code. The prefix geoip:(all lowercase) must be used, and nearly all countries that have internet access are supported.

      • Special value: "geoip:private", which includes all private addresses, such as 127.0.0.1.
    • Loading IP from a file: In the format of "ext:file:tag", where file is the file name and tag is a label that must exist in the file. The prefix ext: (all lowercase) must be used, and the file should be located in the resource directory with the same format as geoip.dat.

    port: number | string

    The target port range, which can take on three forms:

    • "a-b": a and b are both positive integers less than 65536. This range is a closed interval, and this rule will take effect when the target port falls within this range.
    • a: a is a positive integer less than 65536. This rule will take effect when the target port is a.
    • A mixture of the above two forms, separated by commas ",". For example: "53,443,1000-2000".

    sourcePort: number | string

    The source port, which can take on three forms:

    • "a-b": a and b are both positive integers less than 65536. This range is a closed interval, and this rule will take effect when the source port falls within this range.
    • a: a is a positive integer less than 65536. This rule will take effect when the source port is a.
    • A mixture of the above two forms, separated by commas ",". For example: "53,443,1000-2000".

    network: "tcp" | "udp" | "tcp,udp"

    This can be "tcp", "udp", or "tcp,udp". This rule will take effect when the connection method is the specified one.

    source: [string]

    An array where each item represents an IP range in the format of IP, CIDR, GeoIP, or loading IP from a file. This rule will take effect when the source IP matches any of the IP ranges in the array.

    user: [string]

    An array where each item represents an email address. This rule will take effect when the source user matches any of the email addresses in the array.

    inboundTag: [string]

    An array where each item represents an identifier. This rule will take effect when the inbound protocol matches any of the identifiers in the array.

    protocol: [ "http" | "tls" | "bittorrent" ]

    An array where each item represents a protocol. This rule will take effect when the protocol of the current connection matches any of the protocols in the array.

    Tip

    The sniffing option in the inbound proxy must be enabled to detect the protocol type used by the connection.

    attrs: object

    A json object with string keys and values, used to detect the HTTP headers of the traffic. It matches when all specified keys exist in the header and corresponding values are a substring of the header value. The key is case in-sensitive. You can use regex to match with value.

    Currently, only the inbound HTTP proxy sets this attribute.

    Examples:

    • Detect HTTP GET:{":method": "GET"}
    • Detect HTTP Path:{":path": "/test"}"
    • Detect Content Type:{"accept": "text/html"}"

    outboundTag: string

    Corresponds to the identifier of an outbound.

    balancerTag: string

    Corresponds to the identifier of a balancer.

    Tip

    balancerTag and outboundTag are mutually exclusive. When both are specified, outboundTag takes effect.

    BalancerObject

    Load balancer configuration. When a load balancer is in effect, it selects the most appropriate outbound from the specified outbound according to the configuration and forwards traffic.

    {
    +
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    Danger

    When multiple attributes are specified at the same time, these attributes need to be satisfied simultaneously in order for the current rule to take effect.

    domainMatcher: "hybrid" | "linear"

    The domain matching algorithm used varies depending on the settings. The option here takes priority over the domainMatcher configured in RoutingObject.

    • "hybrid": uses a new domain matching algorithm that is faster and takes up less space. This is the default value.
    • "linear": uses the original domain matching algorithm.

    type: "field"

    Currently, only the option "field" is supported.

    domain: [string]

    An array where each item is a domain match. There are several forms:

    • Plain string: If this string matches any part of the target domain, the rule takes effect. For example, "sina.com" can match "sina.com", "sina.com.cn", and "www.sina.com", but not "sina.cn".
    • Regular expression: Starts with "regexp:" followed by a regular expression. When this regular expression matches the target domain, the rule takes effect. For example, "regexp:\\.goo.*\\.comquot; matches "www.google.com" or "fonts.googleapis.com", but not "google.com".
    • Subdomain (recommended): Starts with "domain:" followed by a domain. When this domain is the target domain or a subdomain of the target domain, the rule takes effect. For example, "domain:xray.com" matches "www.xray.com" and "xray.com", but not "wxray.com".
    • Exact match: Starts with "full:" followed by a domain. When this domain is an exact match for the target domain, the rule takes effect. For example, "full:xray.com" matches "xray.com" but not "www.xray.com".
    • Predefined domain list: Starts with "geosite:" followed by a name such as geosite:google or geosite:cn. The names and domain lists are listed in Predefined Domain List.
    • Load domains from a file: Formatted as "ext:file:tag", where the file is stored in the resource directory and has the same format as geosite.dat. The tag must exist in the file.

    Tip

    "ext:geoip.dat:cn" is equivalent to "geoip:cn"

    ip: [string]

    An array where each item represents an IP range. This rule will take effect when the target IP matches any of the IP ranges in the array. There are several types of IP ranges:

    • IP: In the format of "127.0.0.1".

    • CIDRopen in new window: In the format of "10.0.0.0/8".

    • Predefined IP lists: These lists are included in every Xray installation package under the file name geoip.dat. They can be used in the format of "geoip:cn", where cn is a two-letter country code. The prefix geoip:(all lowercase) must be used, and nearly all countries that have internet access are supported.

      • Special value: "geoip:private", which includes all private addresses, such as 127.0.0.1.
    • Loading IP from a file: In the format of "ext:file:tag", where file is the file name and tag is a label that must exist in the file. The prefix ext: (all lowercase) must be used, and the file should be located in the resource directory with the same format as geoip.dat.

    port: number | string

    The target port range, which can take on three forms:

    • "a-b": a and b are both positive integers less than 65536. This range is a closed interval, and this rule will take effect when the target port falls within this range.
    • a: a is a positive integer less than 65536. This rule will take effect when the target port is a.
    • A mixture of the above two forms, separated by commas ",". For example: "53,443,1000-2000".

    sourcePort: number | string

    The source port, which can take on three forms:

    • "a-b": a and b are both positive integers less than 65536. This range is a closed interval, and this rule will take effect when the source port falls within this range.
    • a: a is a positive integer less than 65536. This rule will take effect when the source port is a.
    • A mixture of the above two forms, separated by commas ",". For example: "53,443,1000-2000".

    network: "tcp" | "udp" | "tcp,udp"

    This can be "tcp", "udp", or "tcp,udp". This rule will take effect when the connection method is the specified one.

    source: [string]

    An array where each item represents an IP range in the format of IP, CIDR, GeoIP, or loading IP from a file. This rule will take effect when the source IP matches any of the IP ranges in the array.

    user: [string]

    An array where each item represents an email address. This rule will take effect when the source user matches any of the email addresses in the array.

    inboundTag: [string]

    An array where each item represents an identifier. This rule will take effect when the inbound protocol matches any of the identifiers in the array.

    protocol: [ "http" | "tls" | "bittorrent" ]

    An array where each item represents a protocol. This rule will take effect when the protocol of the current connection matches any of the protocols in the array.

    Tip

    The sniffing option in the inbound proxy must be enabled to detect the protocol type used by the connection.

    attrs: object

    A json object with string keys and values, used to detect the HTTP headers of the traffic. It matches when all specified keys exist in the header and corresponding values are a substring of the header value. The key is case in-sensitive. You can use regex to match with value.

    Currently, only the inbound HTTP proxy sets this attribute.

    Examples:

    • Detect HTTP GET:{":method": "GET"}
    • Detect HTTP Path:{":path": "/test"}"
    • Detect Content Type:{"accept": "text/html"}"

    outboundTag: string

    Corresponds to the identifier of an outbound.

    balancerTag: string

    Corresponds to the identifier of a balancer.

    Tip

    balancerTag and outboundTag are mutually exclusive. When both are specified, outboundTag takes effect.

    BalancerObject

    Load balancer configuration. When a load balancer is in effect, it selects the most appropriate outbound from the specified outbound according to the configuration and forwards traffic.

    {
       "tag": "balancer",
       "selector": []
     }
    -
    1
    2
    3
    4

    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 window.

    - +
    1
    2
    3
    4

    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 window.

    + diff --git a/en/config/stats.html b/en/config/stats.html index 98791f1b4..2155c7297 100644 --- a/en/config/stats.html +++ b/en/config/stats.html @@ -5,7 +5,7 @@ Traffic Statistics | Project X - + @@ -13,6 +13,6 @@ "stats": {} }
    1
    2
    3

    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 b7febaa00..72dfc0672 100644 --- a/en/config/transport.html +++ b/en/config/transport.html @@ -5,7 +5,7 @@ Transport Protocol | Project X - + @@ -122,6 +122,6 @@ "interface": "wg0" }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    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 window 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 window 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. Only supported by Linux.

    - + diff --git a/en/config/transports/domainsocket.html b/en/config/transports/domainsocket.html index 23a56e6ed..45d42af4d 100644 --- a/en/config/transports/domainsocket.html +++ b/en/config/transports/domainsocket.html @@ -5,7 +5,7 @@ Domain Socket | Project X - + @@ -15,6 +15,6 @@ "padding": false }
    1
    2
    3
    4
    5

    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 ceeb1cbfe..ff3e48d18 100644 --- a/en/config/transports/grpc.html +++ b/en/config/transports/grpc.html @@ -5,7 +5,7 @@ gRPC | Project X - + @@ -18,6 +18,6 @@ "initial_windows_size": 0 }
    1
    2
    3
    4
    5
    6
    7
    8

    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 8b7bfd27a..04d3547da 100644 --- a/en/config/transports/h2.html +++ b/en/config/transports/h2.html @@ -5,7 +5,7 @@ HTTP/2 | Project X - + @@ -20,6 +20,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    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 window 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/mkcp.html b/en/config/transports/mkcp.html index e8b64b7d8..c24e59630 100644 --- a/en/config/transports/mkcp.html +++ b/en/config/transports/mkcp.html @@ -5,7 +5,7 @@ mKCP | Project X - + @@ -26,6 +26,6 @@ "type": "none" }
    1
    2
    3

    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 17bffee9c..2ffbecebd 100644 --- a/en/config/transports/quic.html +++ b/en/config/transports/quic.html @@ -5,7 +5,7 @@ QUIC | Project X - + @@ -20,6 +20,6 @@ "type": "none" }
    1
    2
    3

    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 c276fdce4..d6e74a823 100644 --- a/en/config/transports/tcp.html +++ b/en/config/transports/tcp.html @@ -5,7 +5,7 @@ TCP | Project X - + @@ -50,6 +50,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    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 7275e50f3..b78474dc6 100644 --- a/en/config/transports/websocket.html +++ b/en/config/transports/websocket.html @@ -5,7 +5,7 @@ WebSocket | Project X - + @@ -20,6 +20,6 @@ "path": "/aabbcc?ed=2048" //added ed parameter
    1
    2
    3

    Warning

    Early Data uses the Sec-WebSocket-Protocol header to carry data. If you encounter compatibility issues, try lowering the threshold.

    headers: map {string: string}

    Custom HTTP headers, a key-value pair, where each key represents the name of an HTTP header, and the corresponding value is a string.

    The default value is 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 4ad1f2465..21535ee05 100644 --- a/en/development/index.html +++ b/en/development/index.html @@ -5,11 +5,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 window that can transmit arbitrary data streams in order.

    - + diff --git a/en/development/intro/compile.html b/en/development/intro/compile.html index 829086088..e45878408 100644 --- a/en/development/intro/compile.html +++ b/en/development/intro/compile.html @@ -5,7 +5,7 @@ Compile the document | Project X - + @@ -19,6 +19,6 @@ $env:GOOS="linux" $env:GOARCH="amd64"
    1
    2
    3

    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 d493c023f..f3e13fb4d 100644 --- a/en/development/intro/design.html +++ b/en/development/intro/design.html @@ -5,11 +5,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 235b43172..3bb4e09d6 100644 --- a/en/development/intro/guide.html +++ b/en/development/intro/guide.html @@ -5,7 +5,7 @@ Development Standards | Project X - + @@ -21,6 +21,6 @@ │ ├── vmess ├── transport // Transport module
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    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 160614d8b..e225d82e4 100644 --- a/en/development/protocols/mkcp.html +++ b/en/development/protocols/mkcp.html @@ -5,11 +5,11 @@ mKCP Protocol | Project X - +

    mKCP Protocol

    mKCP is a stream transfer protocol, modified from the KCP protocolopen in new window, 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 window 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 b9d8e64da..e4e3cf007 100644 --- a/en/development/protocols/muxcool.html +++ b/en/development/protocols/muxcool.html @@ -5,11 +5,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 c191fbfae..47578cf0b 100644 --- a/en/development/protocols/vless.html +++ b/en/development/protocols/vless.html @@ -5,11 +5,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 window). 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 window 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 window

    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 window for the proposal!

    Please see VMessAEAD/VLESS Sharing Link Standard Proposalopen in new window for more details.

    - + diff --git a/en/development/protocols/vmess.html b/en/development/protocols/vmess.html index 1c4c53cef..1e832d2eb 100644 --- a/en/development/protocols/vmess.html +++ b/en/development/protocols/vmess.html @@ -5,11 +5,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 window, 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 window.

    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

    其中:

    • 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 eda784c09..f9b4403c4 100644 --- a/en/document/command.html +++ b/en/document/command.html @@ -5,7 +5,7 @@ Command Parameters | Project X - + @@ -52,6 +52,6 @@ ping Ping the domain with TLS handshake
    1
    2

    xray uuid

    Generated UUID.

    Usage:

    xray uuid
     
    1

    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 c5cd53aa4..9df10acf3 100644 --- a/en/document/config.html +++ b/en/document/config.html @@ -5,7 +5,7 @@ Configure and Run | Project X - + @@ -74,6 +74,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

    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 777fc7480..2b82596c7 100644 --- a/en/document/document.html +++ b/en/document/document.html @@ -5,7 +5,7 @@ Contribute to Project X's Document | Project X - + @@ -13,6 +13,6 @@
    1
    1. Create a new branch based on the main branch, such as:
    git checkout -b your-branch
     
    1
    1. Make changes on the new branch.

    2. After modification, please use Prettieropen in new windowFormat 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
    1. Open GitHub, click 'Pull request' to submit a pull request to Project X Documentopen in new window.

    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 window.

    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 fbdbd3443..0e3e52e33 100644 --- a/en/document/index.html +++ b/en/document/index.html @@ -5,11 +5,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 9aaf82bea..d61d4dcc0 100644 --- a/en/document/install.html +++ b/en/document/install.html @@ -5,11 +5,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 window 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 window, yayopen in new window as an example, it can be installed via yay -S xray.

    Arch Linux CN

    First add Arch Linux CNopen in new window 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 window

    - + diff --git a/en/document/level-0/ch01-preface.html b/en/document/level-0/ch01-preface.html index 811098a9c..32d4e9afe 100644 --- a/en/document/level-0/ch01-preface.html +++ b/en/document/level-0/ch01-preface.html @@ -5,11 +5,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 1e8594717..7b3bb9f10 100644 --- a/en/document/level-0/ch02-preparation.html +++ b/en/document/level-0/ch02-preparation.html @@ -5,11 +5,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 07104af56..70283e1c3 100644 --- a/en/document/level-0/ch03-ssh.html +++ b/en/document/level-0/ch03-ssh.html @@ -5,13 +5,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 window 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
     
    1

    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
     
    1

    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 6e6569b26..681d22c73 100644 --- a/en/document/level-0/ch04-security.html +++ b/en/document/level-0/ch04-security.html @@ -5,7 +5,7 @@ [Chapter 4] Security and Protection | Project X - + @@ -20,6 +20,6 @@
    1

    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
     
    1

    (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
     
    1

    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 a07710025..334d014b7 100644 --- a/en/document/level-0/ch05-webpage.html +++ b/en/document/level-0/ch05-webpage.html @@ -5,7 +5,7 @@ Chapter 5: Website Building | Project X - + @@ -56,6 +56,6 @@ }
    1
    2
    3
    4
    5
    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.

  • Make nginx reload the configuration to take effect.

    sudo systemctl reload nginx
     
    1
  • The complete setup process is as follows:

    Web page settings demonstration

  • 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 2cac981d8..adceba628 100644 --- a/en/document/level-0/ch06-certificates.html +++ b/en/document/level-0/ch06-certificates.html @@ -5,7 +5,7 @@ [Chapter 6] Certificate Management | Project X - + @@ -120,6 +120,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
    1
    2
    3
    4

    (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 1784c5ae7..6f94e204b 100644 --- a/en/document/level-0/ch07-xray-server.html +++ b/en/document/level-0/ch07-xray-server.html @@ -5,7 +5,7 @@ 【第 7 章】Xray 服务器篇 | Project X - + @@ -169,6 +169,6 @@
    1
    1. 修改 Xray 的回落设置,将回落从 80 端口改为 8080 端口。(找到 "dest": 80, 并改成 "dest": 8080
    sudo nano /usr/local/etc/xray/config.json
     
    1
    1. 重启 Xray 服务,即完成了设置
    sudo systemctl restart xray
     
    1
    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 266713679..8221efc33 100644 --- a/en/document/level-0/ch08-xray-clients.html +++ b/en/document/level-0/ch08-xray-clients.html @@ -5,7 +5,7 @@ 【第 8 章】Xray 客户端篇 | Project X - + @@ -162,6 +162,6 @@
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150

    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
       
      1

      说明

      这里的 -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
       
      1

      说明

      每个系统都有系统路径变量,所以写 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 window - 官方文档站
    2. 官方 Telegram 群组open in new window - 活跃而友善的官方讨论社区

    TO INFINITY AND BEYOND!

    不算后记的后记

    希望我陪你走过的这一段小小的旅程,可以成为你网络生活中的一份小小助力。

    这篇文章里的工具和信息难免会一点点的陈旧过时,但你一定会逐渐成长为大佬。未来的某个时间,若你能偶尔想起这篇教程、想起我写下本文的初衷,那我衷心希望你能够薪火相传、把最新的知识分享给后来人,让这一份小小的助力在社区里坚定的传递下去。

    这是个大雪封山乌云密布的世界,人们孤独的走在各自的路上试图寻找阳光,如果大家偶尔交汇时不能守望相助互相鼓励,那最终剩下的,恐怕只有【千山鸟飞绝 万径人踪灭】的凄凉了吧。

    - + diff --git a/en/document/level-0/ch09-appendix.html b/en/document/level-0/ch09-appendix.html index a5f39f2c4..9779edf45 100644 --- a/en/document/level-0/ch09-appendix.html +++ b/en/document/level-0/ch09-appendix.html @@ -5,11 +5,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 4215fe50a..8f2d9fa85 100644 --- a/en/document/level-0/index.html +++ b/en/document/level-0/index.html @@ -5,11 +5,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 window

    【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 d85ceb98a..0b7595edd 100644 --- a/en/document/level-1/fallbacks-lv1.html +++ b/en/document/level-1/fallbacks-lv1.html @@ -5,7 +5,7 @@ 回落 (fallbacks) 功能简析 | Project X - + @@ -181,6 +181,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
  • 至此,我们就能够完整的画出模板的回落路线了:

  • 6. 结语

    至此,Xray 的【回落】功能就介绍完了。希望本文能够对你理解 Xray 的强大有所帮助。

    7. 附加题

    我再无耻的留一个附加题:本文详解的 VLESS-TCP-XTLS-WHATEVERopen in new window 模板?是否有可以优化的地方?

    提示:HTTP 自动跳转 HTTPS

    - + diff --git a/en/document/level-1/fallbacks-with-sni.html b/en/document/level-1/fallbacks-with-sni.html index 965923ffe..a07c3c79b 100644 --- a/en/document/level-1/fallbacks-with-sni.html +++ b/en/document/level-1/fallbacks-with-sni.html @@ -5,7 +5,7 @@ SNI fallback | Project X - + @@ -192,6 +192,6 @@ redir https://{host}{uri} permanent }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    Reference

    1. Server Name Indication - Wikipedia, the free encyclopediaopen in new window
    2. Home · acmesh-official/acme.sh Wikiopen in new window
    3. HTTP/2 - Wikipedia, the free encyclopediaopen in new window

    Quotation


    1. Proxy Protocol - HAProxy Technologiesopen in new window ↩︎

    2. Introduction to Proxy Protocol and Nginx Configuration - Jianshuopen in new window ↩︎

    3. v2fly-github-io/vless.md at master · rprx/v2fly-github-ioopen in new window ↩︎

    - + diff --git a/en/document/level-1/index.html b/en/document/level-1/index.html index 5140e4cb1..24553b5cb 100644 --- a/en/document/level-1/index.html +++ b/en/document/level-1/index.html @@ -5,11 +5,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 74d76a075..896c5cc16 100644 --- a/en/document/level-1/routing-lv1-part1.html +++ b/en/document/level-1/routing-lv1-part1.html @@ -5,7 +5,7 @@ 路由 (routing) 功能简析(上) | Project X - + @@ -122,6 +122,6 @@ ] }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    此时,路由规则其实变成了:

    这就是路由功能的灵活之处了,你可以自由的改变它的顺序来实现不同的设计。

    至此,我们已经解释完了 【如何利用 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 39f139bc6..1216a3aee 100644 --- a/en/document/level-1/routing-lv1-part2.html +++ b/en/document/level-1/routing-lv1-part2.html @@ -5,7 +5,7 @@ 路由 (routing) 功能简析(下) | Project X - + @@ -168,6 +168,6 @@ } }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

    其实,第 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 1e7133faa..b2ea19aca 100644 --- a/en/document/level-1/work.html +++ b/en/document/level-1/work.html @@ -5,11 +5,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 3e44b2a42..70e766b7f 100644 --- a/en/document/level-2/index.html +++ b/en/document/level-2/index.html @@ -5,11 +5,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 window

    An Introduction to Transparent Proxies.

    TProxy Configuration Tutorial by a @BioniCosmosopen in new window

    Complete tutorial on configuring transparent proxy (TProxy) based on Xray.

    TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial by a @SQLimitopen in new window

    Xray-based TProxy Transparent Proxy (IPv4 and IPv6) Configuration Tutorial

    Nginx_TLS Tunnel Hidden Fingerprint by a @SQLimitopen in new window

    Use Nginx_TLS tunnel on both ends to hide the fingerprint.

    [Transparent Proxy] Avoiding Xray Traffic Through gid by a @kirinopen in new window

    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 window

    Play Xray to the fullest: Implement "load balancing" based on fwmark or sendThrough.

    Enhancing Proxy Security with Cloudflare Warp by a @yuhan6665open in new window

    Introduction to using WireGuard for outbound traffic added in Xray v1.6.5.

    Xray Traffic Statistics by a @yuhan6665open in new window

    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 46be945b6..e431052b6 100644 --- a/en/document/level-2/iptables_gid.html +++ b/en/document/level-2/iptables_gid.html @@ -5,7 +5,7 @@ Transparent proxy via GID | Project X - + @@ -94,6 +94,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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    - + diff --git a/en/document/level-2/nginx_tls_tunnel.html b/en/document/level-2/nginx_tls_tunnel.html index bf9224ae1..428b726f4 100644 --- a/en/document/level-2/nginx_tls_tunnel.html +++ b/en/document/level-2/nginx_tls_tunnel.html @@ -5,7 +5,7 @@ Nginx_TLS隧道隐藏指纹 | Project X - + @@ -216,6 +216,6 @@
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    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
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134

    如果使用透明代理需要在 iptables 或 ip6tables 配置中加入

    iptables -t mangle -A XRAY_MASK -d VSP_IPv4/32 -j RETURN
     ip6tables -t mangle -A XRAY6_MASK -d VPS_IPv6/128 -j RETURN
     
    1
    2

    客户端及服务端启动服务

    systemctl restart xray

    systemctl restart nginx

    后记

    客户端应该也是可以通过 domain socket 连接提高性能,但由于 xray outbound 不支持 ds 出站,想了半天没什么好的实现方法。如果 vnext 里支持 ds 就好了 (没有别的意思)。

    从客户端 nginx 开始应该可以选择 http2 grpc ws 等传输方式。

    - + diff --git a/en/document/level-2/redirect.html b/en/document/level-2/redirect.html index ee35c0660..6c5dc74f0 100644 --- a/en/document/level-2/redirect.html +++ b/en/document/level-2/redirect.html @@ -5,7 +5,7 @@ 出站流量重定向 | Project X - + @@ -221,6 +221,6 @@
    1

    开机自启

    systemctl enable wg-quick@wg0
     systemctl start wg-quick@wg0
     
    1
    2

    验证 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 21c1d99f9..93f7390f3 100644 --- a/en/document/level-2/tproxy.html +++ b/en/document/level-2/tproxy.html @@ -5,7 +5,7 @@ TProxy 透明代理 | Project X - + @@ -262,6 +262,6 @@ [Install] WantedBy=multi-user.target
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    - + diff --git a/en/document/level-2/tproxy_ipv4_and_ipv6.html b/en/document/level-2/tproxy_ipv4_and_ipv6.html index 952f73c30..0eb90f9c1 100644 --- a/en/document/level-2/tproxy_ipv4_and_ipv6.html +++ b/en/document/level-2/tproxy_ipv4_and_ipv6.html @@ -5,7 +5,7 @@ TProxy 透明代理 (ipv4 and ipv6) | Project X - + @@ -411,6 +411,6 @@ [Install] WantedBy=multi-user.target
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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 b1e82d379..011cea51f 100644 --- a/en/document/level-2/traffic_stats.html +++ b/en/document/level-2/traffic_stats.html @@ -5,7 +5,7 @@ 流量统计 | Project X - + @@ -101,6 +101,6 @@ print_sum "$DATA" "user" echo "-----------------------------"
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    - + diff --git a/en/document/level-2/transparent_proxy/transparent_proxy.html b/en/document/level-2/transparent_proxy/transparent_proxy.html index 2ced1fd40..5c67f8cdc 100644 --- a/en/document/level-2/transparent_proxy/transparent_proxy.html +++ b/en/document/level-2/transparent_proxy/transparent_proxy.html @@ -5,7 +5,7 @@ 透明代理入门 | Project X - + @@ -88,6 +88,6 @@ iptables -t mangle -A OUTPUT -p tcp -j XRAY_MASK iptables -t mangle -A OUTPUT -p udp -j XRAY_MASK
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23

    但是这么配置有个缺点,如果使用 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 window 中的第三条说:手动配置 PC 的网络,将默认网关指向树莓派的地址即 192.168.1.22。此时 PC 应当能正常上网(由于还没设置代理,“正常”是指可以上国内的网站)。实际上,Ubuntu、CentOS、debian 等系统就算开启了 IP 转发,PC 也不能正常上网,这是正常的。事实上只有 OpenWRT 能做到文中所描述的那样,据 @BioniCosmosopen in new window 点拨,这是由于一般的 Linux 系统没有 Masquery 规则。

    3. too many open files 问题open in new window ,解决方法见 [透明代理]通过 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 70c93aaf8..7fcae9ab0 100644 --- a/en/document/level-2/warp.html +++ b/en/document/level-2/warp.html @@ -5,7 +5,7 @@ Enhancing Proxy Security with Cloudflare Warp | Project X - + @@ -92,6 +92,6 @@ ] }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    - + diff --git a/en/index.html b/en/index.html index 9eca14b04..94e7c61b6 100644 --- a/en/index.html +++ b/en/index.html @@ -5,7 +5,7 @@ Project X - + @@ -15,6 +15,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 window

    Stargazers over time

    Stargazers over timeopen in new window

    - + diff --git a/index.html b/index.html index 84dd61059..9533914ff 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ Project X - + @@ -15,6 +15,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 window

    Stargazers over time

    Stargazers over timeopen in new window

    - +