| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202 | const Protocols = {    VMESS: 'vmess',    VLESS: 'vless',    TROJAN: 'trojan',    SHADOWSOCKS: 'shadowsocks',    DOKODEMO: 'dokodemo-door',    MTPROTO: 'mtproto',    SOCKS: 'socks',    HTTP: 'http',};const VmessMethods = {    AES_128_GCM: 'aes-128-gcm',    CHACHA20_POLY1305: 'chacha20-poly1305',    AUTO: 'auto',    NONE: 'none',};const SSMethods = {	AES_128_GCM: 'aes-128-gcm',	AES_256_GCM: 'aes-256-gcm',	CHACHA20_POLY1305: 'chacha20-poly1305',	CHACHA20_IETF_POLY1305: 'chacha20-ietf-poly1305',	XCHACHA20_POLY1305: 'xchacha20-poly1305',	XCHACHA20_IETF_POLY1305: 'xchacha20-ietf-poly1305',	BLAKE3_AES_128_GCM: '2022-blake3-aes-128-gcm',	BLAKE3_AES_256_GCM: '2022-blake3-aes-256-gcm',	BLAKE3_CHACHA20_POLY1305: '2022-blake3-chacha20-poly1305',};const RULE_IP = {    PRIVATE: 'geoip:private',    CN: 'geoip:cn',};const RULE_DOMAIN = {    ADS: 'geosite:category-ads',    ADS_ALL: 'geosite:category-ads-all',    CN: 'geosite:cn',    GOOGLE: 'geosite:google',    FACEBOOK: 'geosite:facebook',    SPEEDTEST: 'geosite:speedtest',};const XTLS_FLOW_CONTROL = {    ORIGIN: "xtls-rprx-origin",    DIRECT: "xtls-rprx-direct",};const TLS_FLOW_CONTROL = {    VISION: "xtls-rprx-vision",    VISION_UDP443: "xtls-rprx-vision-udp443",};const TLS_VERSION_OPTION = {    TLS10: "1.0",    TLS11: "1.1",    TLS12: "1.2",    TLS13: "1.3",};const TLS_CIPHER_OPTION = {    RSA_AES_128_CBC: "TLS_RSA_WITH_AES_128_CBC_SHA",    RSA_AES_256_CBC: "TLS_RSA_WITH_AES_256_CBC_SHA",    RSA_AES_128_GCM: "TLS_RSA_WITH_AES_128_GCM_SHA256",    RSA_AES_256_GCM: "TLS_RSA_WITH_AES_256_GCM_SHA384",    AES_128_GCM: "TLS_AES_128_GCM_SHA256",    AES_256_GCM: "TLS_AES_256_GCM_SHA384",    CHACHA20_POLY1305: "TLS_CHACHA20_POLY1305_SHA256",    ECDHE_ECDSA_AES_128_CBC: "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",    ECDHE_ECDSA_AES_256_CBC: "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",    ECDHE_RSA_AES_128_CBC: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",    ECDHE_RSA_AES_256_CBC: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",    ECDHE_ECDSA_AES_128_GCM: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",    ECDHE_ECDSA_AES_256_GCM: "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",    ECDHE_RSA_AES_128_GCM: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",    ECDHE_RSA_AES_256_GCM: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",    ECDHE_ECDSA_CHACHA20_POLY1305: "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",    ECDHE_RSA_CHACHA20_POLY1305: "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",};const UTLS_FINGERPRINT = {    UTLS_CHROME: "chrome",    UTLS_FIREFOX: "firefox",    UTLS_SAFARI: "safari",    UTLS_IOS: "ios",    UTLS_android: "android",    UTLS_EDGE: "edge",    UTLS_360: "360",    UTLS_QQ: "qq",    UTLS_RANDOM: "random",    UTLS_RANDOMIZED: "randomized",};const ALPN_OPTION = {    H3: "h3",    H2: "h2",    HTTP1: "http/1.1",};Object.freeze(Protocols);Object.freeze(VmessMethods);Object.freeze(SSMethods);Object.freeze(RULE_IP);Object.freeze(RULE_DOMAIN);Object.freeze(XTLS_FLOW_CONTROL);Object.freeze(TLS_FLOW_CONTROL);Object.freeze(TLS_VERSION_OPTION);Object.freeze(TLS_CIPHER_OPTION);Object.freeze(ALPN_OPTION);class XrayCommonClass {    static toJsonArray(arr) {        return arr.map(obj => obj.toJson());    }    static fromJson() {        return new XrayCommonClass();    }    toJson() {        return this;    }    toString(format=true) {        return format ? JSON.stringify(this.toJson(), null, 2) : JSON.stringify(this.toJson());    }    static toHeaders(v2Headers) {        let newHeaders = [];        if (v2Headers) {            Object.keys(v2Headers).forEach(key => {                let values = v2Headers[key];                if (typeof(values) === 'string') {                    newHeaders.push({ name: key, value: values });                } else {                    for (let i = 0; i < values.length; ++i) {                        newHeaders.push({ name: key, value: values[i] });                    }                }            });        }        return newHeaders;    }    static toV2Headers(headers, arr=true) {        let v2Headers = {};        for (let i = 0; i < headers.length; ++i) {            let name = headers[i].name;            let value = headers[i].value;            if (ObjectUtil.isEmpty(name) || ObjectUtil.isEmpty(value)) {                continue;            }            if (!(name in v2Headers)) {                v2Headers[name] = arr ? [value] : value;            } else {                if (arr) {                    v2Headers[name].push(value);                } else {                    v2Headers[name] = value;                }            }        }        return v2Headers;    }}class TcpStreamSettings extends XrayCommonClass {    constructor(acceptProxyProtocol=false,                type='none',                request=new TcpStreamSettings.TcpRequest(),                response=new TcpStreamSettings.TcpResponse(),                ) {        super();        this.acceptProxyProtocol = acceptProxyProtocol;        this.type = type;        this.request = request;        this.response = response;    }    static fromJson(json={}) {        let header = json.header;        if (!header) {            header = {};        }        return new TcpStreamSettings(json.acceptProxyProtocol,            header.type,            TcpStreamSettings.TcpRequest.fromJson(header.request),            TcpStreamSettings.TcpResponse.fromJson(header.response),        );    }    toJson() {        return {            acceptProxyProtocol: this.acceptProxyProtocol,            header: {                type: this.type,                request: this.type === 'http' ? this.request.toJson() : undefined,                response: this.type === 'http' ? this.response.toJson() : undefined,            },        };    }}TcpStreamSettings.TcpRequest = class extends XrayCommonClass {    constructor(version='1.1',                method='GET',                path=['/'],                headers=[],    ) {        super();        this.version = version;        this.method = method;        this.path = path.length === 0 ? ['/'] : path;        this.headers = headers;    }    addPath(path) {        this.path.push(path);    }    removePath(index) {        this.path.splice(index, 1);    }    addHeader(name, value) {        this.headers.push({ name: name, value: value });    }    getHeader(name) {        for (const header of this.headers) {            if (header.name.toLowerCase() === name.toLowerCase()) {                return header.value;            }        }        return null;    }    removeHeader(index) {        this.headers.splice(index, 1);    }    static fromJson(json={}) {        return new TcpStreamSettings.TcpRequest(            json.version,            json.method,            json.path,            XrayCommonClass.toHeaders(json.headers),        );    }    toJson() {        return {            method: this.method,            path: ObjectUtil.clone(this.path),            headers: XrayCommonClass.toV2Headers(this.headers),        };    }};TcpStreamSettings.TcpResponse = class extends XrayCommonClass {    constructor(version='1.1',                status='200',                reason='OK',                headers=[],    ) {        super();        this.version = version;        this.status = status;        this.reason = reason;        this.headers = headers;    }    addHeader(name, value) {        this.headers.push({ name: name, value: value });    }    removeHeader(index) {        this.headers.splice(index, 1);    }    static fromJson(json={}) {        return new TcpStreamSettings.TcpResponse(            json.version,            json.status,            json.reason,            XrayCommonClass.toHeaders(json.headers),        );    }    toJson() {        return {            version: this.version,            status: this.status,            reason: this.reason,            headers: XrayCommonClass.toV2Headers(this.headers),        };    }};class KcpStreamSettings extends XrayCommonClass {    constructor(mtu=1350, tti=20,                uplinkCapacity=5,                downlinkCapacity=20,                congestion=false,                readBufferSize=2,                writeBufferSize=2,                type='none',                seed=RandomUtil.randomSeq(10),                ) {        super();        this.mtu = mtu;        this.tti = tti;        this.upCap = uplinkCapacity;        this.downCap = downlinkCapacity;        this.congestion = congestion;        this.readBuffer = readBufferSize;        this.writeBuffer = writeBufferSize;        this.type = type;        this.seed = seed;    }    static fromJson(json={}) {        return new KcpStreamSettings(            json.mtu,            json.tti,            json.uplinkCapacity,            json.downlinkCapacity,            json.congestion,            json.readBufferSize,            json.writeBufferSize,            ObjectUtil.isEmpty(json.header) ? 'none' : json.header.type,            json.seed,        );    }    toJson() {        return {            mtu: this.mtu,            tti: this.tti,            uplinkCapacity: this.upCap,            downlinkCapacity: this.downCap,            congestion: this.congestion,            readBufferSize: this.readBuffer,            writeBufferSize: this.writeBuffer,            header: {                type: this.type,            },            seed: this.seed,        };    }}class WsStreamSettings extends XrayCommonClass {    constructor(acceptProxyProtocol=false, path='/', headers=[]) {        super();        this.acceptProxyProtocol = acceptProxyProtocol;        this.path = path;        this.headers = headers;    }    addHeader(name, value) {        this.headers.push({ name: name, value: value });    }    getHeader(name) {        for (const header of this.headers) {            if (header.name.toLowerCase() === name.toLowerCase()) {                return header.value;            }        }        return null;    }    removeHeader(index) {        this.headers.splice(index, 1);    }    static fromJson(json={}) {        return new WsStreamSettings(            json.acceptProxyProtocol,            json.path,            XrayCommonClass.toHeaders(json.headers),        );    }    toJson() {        return {            acceptProxyProtocol: this.acceptProxyProtocol,            path: this.path,            headers: XrayCommonClass.toV2Headers(this.headers, false),        };    }}class HttpStreamSettings extends XrayCommonClass {    constructor(path='/', host=['']) {        super();        this.path = path;        this.host = host.length === 0 ? [''] : host;    }    addHost(host) {        this.host.push(host);    }    removeHost(index) {        this.host.splice(index, 1);    }    static fromJson(json={}) {        return new HttpStreamSettings(json.path, json.host);    }    toJson() {        let host = [];        for (let i = 0; i < this.host.length; ++i) {            if (!ObjectUtil.isEmpty(this.host[i])) {                host.push(this.host[i]);            }        }        return {            path: this.path,            host: host,        }    }}class QuicStreamSettings extends XrayCommonClass {    constructor(security=VmessMethods.NONE,                key='', type='none') {        super();        this.security = security;        this.key = key;        this.type = type;    }    static fromJson(json={}) {        return new QuicStreamSettings(            json.security,            json.key,            json.header ? json.header.type : 'none',        );    }    toJson() {        return {            security: this.security,            key: this.key,            header: {                type: this.type,            }        }    }}class GrpcStreamSettings extends XrayCommonClass {    constructor(serviceName="") {        super();        this.serviceName = serviceName;    }    static fromJson(json={}) {        return new GrpcStreamSettings(json.serviceName);    }    toJson() {        return {            serviceName: this.serviceName,        }    }}class TlsStreamSettings extends XrayCommonClass {    constructor(serverName='',                minVersion = TLS_VERSION_OPTION.TLS12,                maxVersion = TLS_VERSION_OPTION.TLS13,                cipherSuites = '',                certificates=[new TlsStreamSettings.Cert()],                alpn=[ALPN_OPTION.H2,ALPN_OPTION.HTTP1],                settings=new TlsStreamSettings.Settings()) {        super();        this.server = serverName;        this.minVersion = minVersion;        this.maxVersion = maxVersion;        this.cipherSuites = cipherSuites;        this.certs = certificates;        this.alpn = alpn;        this.settings = settings;    }    addCert(cert) {        this.certs.push(cert);    }    removeCert(index) {        this.certs.splice(index, 1);    }    static fromJson(json={}) {        let certs;        let settings;        if (!ObjectUtil.isEmpty(json.certificates)) {            certs = json.certificates.map(cert => TlsStreamSettings.Cert.fromJson(cert));        }		if (!ObjectUtil.isEmpty(json.settings)) {            settings = new TlsStreamSettings.Settings(json.settings.allowInsecure , json.settings.fingerprint, json.settings.serverName);        }        return new TlsStreamSettings(            json.serverName,            json.minVersion,            json.maxVersion,            json.cipherSuites,            certs,            json.alpn,            settings,        );    }    toJson() {        return {            serverName: this.server,            minVersion: this.minVersion,            maxVersion: this.maxVersion,            cipherSuites: this.cipherSuites,            certificates: TlsStreamSettings.toJsonArray(this.certs),            alpn: this.alpn,            settings: this.settings,        };    }}TlsStreamSettings.Cert = class extends XrayCommonClass {    constructor(useFile=true, certificateFile='', keyFile='', certificate='', key='') {        super();        this.useFile = useFile;        this.certFile = certificateFile;        this.keyFile = keyFile;        this.cert = certificate instanceof Array ? certificate.join('\n') : certificate;        this.key = key instanceof Array ? key.join('\n') : key;    }    static fromJson(json={}) {        if ('certificateFile' in json && 'keyFile' in json) {            return new TlsStreamSettings.Cert(                true,                json.certificateFile,                json.keyFile,            );        } else {            return new TlsStreamSettings.Cert(                false, '', '',                json.certificate.join('\n'),                json.key.join('\n'),            );        }    }    toJson() {        if (this.useFile) {            return {                certificateFile: this.certFile,                keyFile: this.keyFile,            };        } else {            return {                certificate: this.cert.split('\n'),                key: this.key.split('\n'),            };        }    }};TlsStreamSettings.Settings = class extends XrayCommonClass {    constructor(allowInsecure = false, fingerprint = '', serverName = '') {        super();        this.allowInsecure = allowInsecure;        this.fingerprint = fingerprint;        this.serverName = serverName;    }    static fromJson(json = {}) {        return new TlsStreamSettings.Settings(            json.allowInsecure,            json.fingerprint,            json.servername,        );    }    toJson() {        return {            allowInsecure: this.allowInsecure,            fingerprint: this.fingerprint,            serverName: this.serverName,        };    }};class XtlsStreamSettings extends XrayCommonClass {    constructor(serverName='',                certificates=[new XtlsStreamSettings.Cert()],                alpn=[ALPN_OPTION.H2,ALPN_OPTION.HTTP1],                settings=new XtlsStreamSettings.Settings()) {        super();        this.server = serverName;        this.certs = certificates;        this.alpn = alpn;        this.settings = settings;    }    addCert(cert) {        this.certs.push(cert);    }    removeCert(index) {        this.certs.splice(index, 1);    }    static fromJson(json={}) {        let certs;        let settings;        if (!ObjectUtil.isEmpty(json.certificates)) {            certs = json.certificates.map(cert => XtlsStreamSettings.Cert.fromJson(cert));        }		if (!ObjectUtil.isEmpty(json.settings)) {            settings = new XtlsStreamSettings.Settings(json.settings.allowInsecure , json.settings.serverName);        }        return new XtlsStreamSettings(            json.serverName,            certs,            json.alpn,            settings,        );    }    toJson() {        return {            serverName: this.server,            certificates: XtlsStreamSettings.toJsonArray(this.certs),            alpn: this.alpn,            settings: this.settings,        };    }}XtlsStreamSettings.Cert = class extends XrayCommonClass {    constructor(useFile=true, certificateFile='', keyFile='', certificate='', key='') {        super();        this.useFile = useFile;        this.certFile = certificateFile;        this.keyFile = keyFile;        this.cert = certificate instanceof Array ? certificate.join('\n') : certificate;        this.key = key instanceof Array ? key.join('\n') : key;    }    static fromJson(json={}) {        if ('certificateFile' in json && 'keyFile' in json) {            return new XtlsStreamSettings.Cert(                true,                json.certificateFile,                json.keyFile,            );        } else {            return new XtlsStreamSettings.Cert(                false, '', '',                json.certificate.join('\n'),                json.key.join('\n'),            );        }    }    toJson() {        if (this.useFile) {            return {                certificateFile: this.certFile,                keyFile: this.keyFile,            };        } else {            return {                certificate: this.cert.split('\n'),                key: this.key.split('\n'),            };        }    }};XtlsStreamSettings.Settings = class extends XrayCommonClass {    constructor(allowInsecure = false, serverName = '') {        super();        this.allowInsecure = allowInsecure;        this.serverName = serverName;    }    static fromJson(json = {}) {        return new XtlsStreamSettings.Settings(            json.allowInsecure,            json.servername,        );    }    toJson() {        return {            allowInsecure: this.allowInsecure,            serverName: this.serverName,        };    }};class RealityStreamSettings extends XrayCommonClass {        constructor(        show = false,xver = 0,        dest = 'yahoo.com:443',        serverNames = 'yahoo.com,www.yahoo.com',        privateKey = '',        minClient = '',        maxClient = '',        maxTimediff = 0,        shortIds = RandomUtil.randowShortId(),        settings= new RealityStreamSettings.Settings()        ){        super();        this.show = show;        this.xver = xver;        this.dest = dest;        this.serverNames = serverNames instanceof Array ? serverNames.join(",") : serverNames;        this.privateKey = privateKey;        this.minClient = minClient;        this.maxClient = maxClient;        this.maxTimediff = maxTimediff;        this.shortIds = shortIds instanceof Array ? shortIds.join(",") : shortIds;         this.settings = settings;    }    static fromJson(json = {}) {        let settings;		if (!ObjectUtil.isEmpty(json.settings)) {            settings = new RealityStreamSettings.Settings(json.settings.publicKey , json.settings.fingerprint, json.settings.serverName);        }        return new RealityStreamSettings(            json.show,            json.xver,            json.dest,            json.serverNames,            json.privateKey,            json.minClient,            json.maxClient,            json.maxTimediff,            json.shortIds,            json.settings,        );    }    toJson() {        return {            show: this.show,            xver: this.xver,            dest: this.dest,            serverNames: this.serverNames.split(","),            privateKey: this.privateKey,            minClient: this.minClient,            maxClient: this.maxClient,            maxTimediff: this.maxTimediff,            shortIds: this.shortIds.split(","),            settings: this.settings,        };    }}RealityStreamSettings.Settings = class extends XrayCommonClass {    constructor(publicKey = '', fingerprint = UTLS_FINGERPRINT.UTLS_FIREFOX, serverName = '') {        super();        this.publicKey = publicKey;        this.fingerprint = fingerprint;        this.serverName = serverName;    }    static fromJson(json = {}) {        return new RealityStreamSettings.Settings(            json.publicKey,            json.fingerprint,            json.serverName,        );    }    toJson() {        return {            publicKey: this.publicKey,            fingerprint: this.fingerprint,            serverName: this.serverName,        };    }};class StreamSettings extends XrayCommonClass {    constructor(network='tcp',        security='none',        tlsSettings=new TlsStreamSettings(),        xtlsSettings=new XtlsStreamSettings(),        realitySettings = new RealityStreamSettings(),        tcpSettings=new TcpStreamSettings(),        kcpSettings=new KcpStreamSettings(),        wsSettings=new WsStreamSettings(),        httpSettings=new HttpStreamSettings(),        quicSettings=new QuicStreamSettings(),        grpcSettings=new GrpcStreamSettings(),        ) {        super();        this.network = network;        this.security = security;        this.tls = tlsSettings;        this.xtls = xtlsSettings;        this.reality = realitySettings;        this.tcp = tcpSettings;        this.kcp = kcpSettings;        this.ws = wsSettings;        this.http = httpSettings;        this.quic = quicSettings;        this.grpc = grpcSettings;    }    get isTls() {        return this.security === "tls";    }    set isTls(isTls) {        if (isTls) {            this.security = 'tls';        } else {            this.security = 'none';        }    }    get isXtls() {        return this.security === "xtls";    }    set isXtls(isXtls) {        if (isXtls) {            this.security = 'xtls';        } else {            this.security = 'none';        }    }    //for Reality    get isReality() {        return this.security === "reality";    }    set isReality(isReality) {        if (isReality) {            this.security = 'reality';        } else {            this.security = 'none';        }    }    static fromJson(json={}) {        return new StreamSettings(            json.network,            json.security,            TlsStreamSettings.fromJson(json.tlsSettings),            XtlsStreamSettings.fromJson(json.xtlsSettings),            RealityStreamSettings.fromJson(json.realitySettings),            TcpStreamSettings.fromJson(json.tcpSettings),            KcpStreamSettings.fromJson(json.kcpSettings),            WsStreamSettings.fromJson(json.wsSettings),            HttpStreamSettings.fromJson(json.httpSettings),            QuicStreamSettings.fromJson(json.quicSettings),            GrpcStreamSettings.fromJson(json.grpcSettings),        );    }    toJson() {        const network = this.network;        return {            network: network,            security: this.security,            tlsSettings: this.isTls ? this.tls.toJson() : undefined,            xtlsSettings: this.isXtls ? this.xtls.toJson() : undefined,            realitySettings: this.isReality ? this.reality.toJson() : undefined,            tcpSettings: network === 'tcp' ? this.tcp.toJson() : undefined,            kcpSettings: network === 'kcp' ? this.kcp.toJson() : undefined,            wsSettings: network === 'ws' ? this.ws.toJson() : undefined,            httpSettings: network === 'http' ? this.http.toJson() : undefined,            quicSettings: network === 'quic' ? this.quic.toJson() : undefined,            grpcSettings: network === 'grpc' ? this.grpc.toJson() : undefined,        };    }}class Sniffing extends XrayCommonClass {    constructor(enabled=true, destOverride=['http', 'tls']) {        super();        this.enabled = enabled;        this.destOverride = destOverride;    }    static fromJson(json={}) {        let destOverride = ObjectUtil.clone(json.destOverride);        if (!ObjectUtil.isEmpty(destOverride) && !ObjectUtil.isArrEmpty(destOverride)) {            if (ObjectUtil.isEmpty(destOverride[0])) {                destOverride = ['http', 'tls'];            }        }        return new Sniffing(            !!json.enabled,            destOverride,        );    }}class Inbound extends XrayCommonClass {    constructor(port=RandomUtil.randomIntRange(10000, 60000),                listen='',                protocol=Protocols.VLESS,                settings=null,                streamSettings=new StreamSettings(),                tag='',                sniffing=new Sniffing(),                clientStats='',                ) {        super();        this.port = port;        this.listen = listen;        this._protocol = protocol;        this.settings = ObjectUtil.isEmpty(settings) ? Inbound.Settings.getSettings(protocol) : settings;        this.stream = streamSettings;        this.tag = tag;        this.sniffing = sniffing;        this.clientStats = clientStats;    }    getClientStats() {        return this.clientStats;    }    get protocol() {        return this._protocol;    }    set protocol(protocol) {        this._protocol = protocol;        this.settings = Inbound.Settings.getSettings(protocol);        if (protocol === Protocols.TROJAN) {            this.tls = true;        }    }    get tls() {        return this.stream.security === 'tls';    }    set tls(isTls) {        if (isTls) {            this.stream.security = 'tls';        } else {            this.stream.security = 'none';        }    }    get xtls() {        return this.stream.security === 'xtls';    }    set xtls(isXtls) {        if (isXtls) {            this.stream.security = 'xtls';        } else {            this.stream.security = 'none';        }    }    //for Reality    get reality() {        return this.stream.security === 'reality';    }    set reality(isReality) {        if (isReality) {            this.stream.security = 'reality';        } else {            this.stream.security = 'none';        }    }    get network() {        return this.stream.network;    }    set network(network) {        this.stream.network = network;    }    get isTcp() {        return this.network === "tcp";    }    get isWs() {        return this.network === "ws";    }    get isKcp() {        return this.network === "kcp";    }    get isQuic() {        return this.network === "quic"    }    get isGrpc() {        return this.network === "grpc";    }    get isHttp() {        return this.network === "http";    }    // VMess & VLess    get uuid() {        switch (this.protocol) {            case Protocols.VMESS:                return this.settings.vmesses[0].id;            case Protocols.VLESS:                return this.settings.vlesses[0].id;            default:                return "";        }    }    // VLess & Trojan    get flow() {        switch (this.protocol) {            case Protocols.VLESS:                return this.settings.vlesses[0].flow;            case Protocols.TROJAN:                return this.settings.trojans[0].flow;            default:                return "";        }    }    // VMess    get alterId() {        switch (this.protocol) {            case Protocols.VMESS:                return this.settings.vmesses[0].alterId;            default:                return "";        }    }    // Socks & HTTP    get username() {        switch (this.protocol) {            case Protocols.SOCKS:            case Protocols.HTTP:                return this.settings.accounts[0].user;            default:                return "";        }    }    // Trojan & Shadowsocks & Socks & HTTP    get password() {        switch (this.protocol) {            case Protocols.TROJAN:                return this.settings.trojans[0].password;            case Protocols.SHADOWSOCKS:                return this.settings.password;            case Protocols.SOCKS:            case Protocols.HTTP:                return this.settings.accounts[0].pass;            default:                return "";        }    }    // Shadowsocks    get method() {        switch (this.protocol) {            case Protocols.SHADOWSOCKS:                return this.settings.method;            default:                return "";        }    }    get serverName() {        if (this.stream.isTls || this.stream.isXtls || this.stream.isReality) {            return this.stream.tls.server;        }        return "";    }    get host() {        if (this.isTcp) {            return this.stream.tcp.request.getHeader("Host");        } else if (this.isWs) {            return this.stream.ws.getHeader("Host");        } else if (this.isHttp) {            return this.stream.http.host[0];        }        return null;    }    get path() {        if (this.isTcp) {            return this.stream.tcp.request.path[0];        } else if (this.isWs) {            return this.stream.ws.path;        } else if (this.isHttp) {            return this.stream.http.path[0];        }        return null;    }    get quicSecurity() {        return this.stream.quic.security;    }    get quicKey() {        return this.stream.quic.key;    }    get quicType() {        return this.stream.quic.type;    }    get kcpType() {        return this.stream.kcp.type;    }    get kcpSeed() {        return this.stream.kcp.seed;    }    get serviceName() {        return this.stream.grpc.serviceName;    }    isExpiry(index) {        switch (this.protocol) {            case Protocols.VMESS:                if(this.settings.vmesses[index].expiryTime > 0)                    return this.settings.vmesses[index].expiryTime < new Date().getTime();                return false            case Protocols.VLESS:                if(this.settings.vlesses[index].expiryTime > 0)                    return this.settings.vlesses[index].expiryTime < new Date().getTime();                return false                case Protocols.TROJAN:                    if(this.settings.trojans[index].expiryTime > 0)                        return this.settings.trojans[index].expiryTime < new Date().getTime();                    return false            default:                return false;        }    }    canEnableTls() {        switch (this.protocol) {            case Protocols.VMESS:            case Protocols.VLESS:            case Protocols.TROJAN:                break;            default:                return false;        }        switch (this.network) {            case "tcp":            case "ws":            case "http":            case "quic":            case "grpc":                return true;            default:                return false;        }    }    canEnableReality() {        switch (this.protocol) {            case Protocols.VLESS:            case Protocols.TROJAN:                break;            default:                return false;        }        switch (this.network) {            case "tcp":            case "http":            case "grpc":                return true;            default:                return false;        }    }    //this is used for xtls-rprx-vision    canEnableTlsFlow() {        if (((this.stream.security === 'tls') || (this.stream.security === 'reality')) && (this.network === "tcp")) {            switch (this.protocol) {                case Protocols.VLESS:                    return true;                default:                    return false;            }        }        return false;    }    canSetTls() {        return this.canEnableTls();    }    canEnableXtls() {        switch (this.protocol) {            case Protocols.VLESS:            case Protocols.TROJAN:                break;            default:                return false;        }        return this.network === "tcp";    }    canEnableStream() {        switch (this.protocol) {            case Protocols.VMESS:            case Protocols.VLESS:            case Protocols.TROJAN:            case Protocols.SHADOWSOCKS:                return true;            default:                return false;        }    }    canSniffing() {        switch (this.protocol) {            case Protocols.VMESS:            case Protocols.VLESS:            case Protocols.TROJAN:            case Protocols.SHADOWSOCKS:                return true;            default:                return false;        }    }    reset() {        this.port = RandomUtil.randomIntRange(10000, 60000);        this.listen = '';        this.protocol = Protocols.VMESS;        this.settings = Inbound.Settings.getSettings(Protocols.VMESS);        this.stream = new StreamSettings();        this.tag = '';        this.sniffing = new Sniffing();    }    genVmessLink(address='', remark='', clientIndex=0) {        if (this.protocol !== Protocols.VMESS) {            return '';        }        let network = this.stream.network;        let type = 'none';        let host = '';        let path = '';        if (network === 'tcp') {            let tcp = this.stream.tcp;            type = tcp.type;            if (type === 'http') {                let request = tcp.request;                path = request.path.join(',');                let index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');                if (index >= 0) {                    host = request.headers[index].value;                }            }        } else if (network === 'kcp') {            let kcp = this.stream.kcp;            type = kcp.type;            path = kcp.seed;        } else if (network === 'ws') {            let ws = this.stream.ws;            path = ws.path;            let index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');            if (index >= 0) {                host = ws.headers[index].value;            }        } else if (network === 'http') {            network = 'h2';            path = this.stream.http.path;            host = this.stream.http.host.join(',');        } else if (network === 'quic') {            type = this.stream.quic.type;            host = this.stream.quic.security;            path = this.stream.quic.key;        } else if (network === 'grpc') {            path = this.stream.grpc.serviceName;        }        if (this.stream.security === 'tls') {            if (!ObjectUtil.isEmpty(this.stream.tls.server)) {                address = this.stream.tls.server;            }        }                let obj = {            v: '2',            ps: remark,            add: address,            port: this.port,            id: this.settings.vmesses[clientIndex].id,            aid: this.settings.vmesses[clientIndex].alterId,            net: network,            type: type,            host: host,            path: path,            tls: this.stream.security,            sni: this.stream.tls.settings.serverName,            fp: this.stream.tls.settings.fingerprint,            alpn: this.stream.tls.alpn.join(','),            allowInsecure: this.stream.tls.settings.allowInsecure,        };        return 'vmess://' + base64(JSON.stringify(obj, null, 2));    }    genVLESSLink(address = '', remark='', clientIndex=0) {        const settings = this.settings;        const uuid = settings.vlesses[clientIndex].id;        const port = this.port;        const type = this.stream.network;        const params = new Map();        params.set("type", this.stream.network);        switch (type) {            case "tcp":                const tcp = this.stream.tcp;                if (tcp.type === 'http') {                    const request = tcp.request;                    params.set("path", request.path.join(','));                    const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');                    if (index >= 0) {                        const host = request.headers[index].value;                        params.set("host", host);                    }                    params.set("headerType", 'http');                }                break;            case "kcp":                const kcp = this.stream.kcp;                params.set("headerType", kcp.type);                params.set("seed", kcp.seed);                break;            case "ws":                const ws = this.stream.ws;                params.set("path", ws.path);                const index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');                if (index >= 0) {                    const host = ws.headers[index].value;                    params.set("host", host);                }                break;            case "http":                const http = this.stream.http;                params.set("path", http.path);                params.set("host", http.host);                break;            case "quic":                const quic = this.stream.quic;                params.set("quicSecurity", quic.security);                params.set("key", quic.key);                params.set("headerType", quic.type);                break;            case "grpc":                const grpc = this.stream.grpc;                params.set("serviceName", grpc.serviceName);                break;        }        if (this.tls) {            params.set("security", "tls");            params.set("fp" , this.stream.tls.settings.fingerprint);            params.set("alpn", this.stream.tls.alpn);            if(this.stream.tls.settings.allowInsecure){                params.set("allowInsecure", "1");            }            if (!ObjectUtil.isEmpty(this.stream.tls.server)) {                address = this.stream.tls.server;			}            if (this.stream.tls.settings.serverName !== ''){                params.set("sni", this.stream.tls.settings.serverName);            }            if (type === "tcp" && this.settings.vlesses[clientIndex].flow.length > 0) {                params.set("flow", this.settings.vlesses[clientIndex].flow);            }        }        if (this.xtls) {            params.set("security", "xtls");            params.set("alpn", this.stream.xtls.alpn);            if(this.stream.xtls.settings.allowInsecure){                params.set("allowInsecure", "1");            }            if (!ObjectUtil.isEmpty(this.stream.xtls.server)) {                address = this.stream.xtls.server;			}            params.set("flow", this.settings.vlesses[clientIndex].flow);        }        if (this.reality) {            params.set("security", "reality");            params.set("fp", this.stream.reality.settings.fingerprint);            params.set("pbk", this.stream.reality.settings.publicKey);            if (!ObjectUtil.isArrEmpty(this.stream.reality.serverNames)) {                params.set("sni", this.stream.reality.serverNames.split(",")[0]);            }            if (this.stream.network === 'tcp' && !ObjectUtil.isEmpty(this.settings.vlesses[clientIndex].flow)) {                params.set("flow", this.settings.vlesses[clientIndex].flow);            }            if (this.stream.reality.shortIds.length > 0) {                params.set("sid", this.stream.reality.shortIds.split(",")[0]);            }            if (!ObjectUtil.isEmpty(this.stream.reality.settings.serverName)) {                address = this.stream.reality.settings.serverName;            }        }        const link = `vless://${uuid}@${address}:${port}`;        const url = new URL(link);        for (const [key, value] of params) {            url.searchParams.set(key, value)        }        url.hash = encodeURIComponent(remark);        return url.toString();    }    genSSLink(address='', remark='') {        let settings = this.settings;        const server = this.stream.tls.server;        if (!ObjectUtil.isEmpty(server)) {            address = server;        }        return 'ss://' + safeBase64(settings.method + ':' + settings.password) + `@${address}:${this.port}#${encodeURIComponent(remark)}`;    }    genTrojanLink(address = '', remark = '', clientIndex = 0) {        let settings = this.settings;        const port = this.port;        const type = this.stream.network;        const params = new Map();        params.set("type", this.stream.network);        switch (type) {            case "tcp":                const tcp = this.stream.tcp;                if (tcp.type === 'http') {                    const request = tcp.request;                    params.set("path", request.path.join(','));                    const index = request.headers.findIndex(header => header.name.toLowerCase() === 'host');                    if (index >= 0) {                        const host = request.headers[index].value;                        params.set("host", host);                    }                    params.set("headerType", 'http');                }                break;            case "kcp":                const kcp = this.stream.kcp;                params.set("headerType", kcp.type);                params.set("seed", kcp.seed);                break;            case "ws":                const ws = this.stream.ws;                params.set("path", ws.path);                const index = ws.headers.findIndex(header => header.name.toLowerCase() === 'host');                if (index >= 0) {                    const host = ws.headers[index].value;                    params.set("host", host);                }                break;            case "http":                const http = this.stream.http;                params.set("path", http.path);                params.set("host", http.host);                break;            case "quic":                const quic = this.stream.quic;                params.set("quicSecurity", quic.security);                params.set("key", quic.key);                params.set("headerType", quic.type);                break;            case "grpc":                const grpc = this.stream.grpc;                params.set("serviceName", grpc.serviceName);                break;        }        if (this.tls) {            params.set("security", "tls");            params.set("fp" , this.stream.tls.settings.fingerprint);            params.set("alpn", this.stream.tls.alpn);            if(this.stream.tls.settings.allowInsecure){                params.set("allowInsecure", "1");            }            if (!ObjectUtil.isEmpty(this.stream.tls.server)) {                address = this.stream.tls.server;            }            if (this.stream.tls.settings.serverName !== ''){                params.set("sni", this.stream.tls.settings.serverName);			}        }        if (this.reality) {            params.set("security", "reality");            params.set("fp", this.stream.reality.settings.fingerprint);            params.set("pbk", this.stream.reality.settings.publicKey);            if (!ObjectUtil.isArrEmpty(this.stream.reality.serverNames)) {                params.set("sni", this.stream.reality.serverNames.split(",")[0]);            }            if (this.stream.reality.shortIds.length > 0) {                params.set("sid", this.stream.reality.shortIds.split(",")[0]);            }            if (!ObjectUtil.isEmpty(this.stream.reality.settings.serverName)) {                address = this.stream.reality.settings.serverName;            }        }		if (this.xtls) {            params.set("security", "xtls");            params.set("alpn", this.stream.xtls.alpn);            if(this.stream.xtls.settings.allowInsecure){                params.set("allowInsecure", "1");            }            if (!ObjectUtil.isEmpty(this.stream.xtls.server)) {                address = this.stream.xtls.server;			}            params.set("flow", this.settings.trojans[clientIndex].flow);        }        const link = `trojan://${settings.trojans[clientIndex].password}@${address}:${this.port}#${encodeURIComponent(remark)}`;        const url = new URL(link);        for (const [key, value] of params) {            url.searchParams.set(key, value)        }        url.hash = encodeURIComponent(remark);        return url.toString();    }    genLink(address='', remark='', clientIndex=0) {        switch (this.protocol) {            case Protocols.VMESS:                if (this.settings.vmesses[clientIndex].email != ""){                    remark += '-' + this.settings.vmesses[clientIndex].email                }                return this.genVmessLink(address, remark, clientIndex);            case Protocols.VLESS:                if (this.settings.vlesses[clientIndex].email != ""){                    remark += '-' + this.settings.vlesses[clientIndex].email                }                return this.genVLESSLink(address, remark, clientIndex);            case Protocols.SHADOWSOCKS: return this.genSSLink(address, remark);            case Protocols.TROJAN:                if (this.settings.trojans[clientIndex].email != ""){                    remark += '-' + this.settings.trojans[clientIndex].email                }                return this.genTrojanLink(address, remark, clientIndex);            default: return '';        }    }    genInboundLinks(address = '', remark = '') {        let link = '';        switch (this.protocol) {            case Protocols.VMESS:            case Protocols.VLESS:            case Protocols.TROJAN:                JSON.parse(this.settings).clients.forEach((_,index) => {                    link += this.genLink(address, remark, index) + '\r\n';                });                return link;            case Protocols.SHADOWSOCKS:                return (this.genSSLink(address, remark) + '\r\n');            default: return '';        }    }    static fromJson(json={}) {        return new Inbound(            json.port,            json.listen,            json.protocol,            Inbound.Settings.fromJson(json.protocol, json.settings),            StreamSettings.fromJson(json.streamSettings),            json.tag,            Sniffing.fromJson(json.sniffing),            json.clientStats        )    }    toJson() {        let streamSettings;        if (this.canEnableStream() || this.protocol === Protocols.TROJAN) {            streamSettings = this.stream.toJson();        }        return {            port: this.port,            listen: this.listen,            protocol: this.protocol,            settings: this.settings instanceof XrayCommonClass ? this.settings.toJson() : this.settings,            streamSettings: streamSettings,            tag: this.tag,            sniffing: this.sniffing.toJson(),            clientStats: this.clientStats        };    }}Inbound.Settings = class extends XrayCommonClass {    constructor(protocol) {        super();        this.protocol = protocol;    }    static getSettings(protocol) {        switch (protocol) {            case Protocols.VMESS: return new Inbound.VmessSettings(protocol);            case Protocols.VLESS: return new Inbound.VLESSSettings(protocol);            case Protocols.TROJAN: return new Inbound.TrojanSettings(protocol);            case Protocols.SHADOWSOCKS: return new Inbound.ShadowsocksSettings(protocol);            case Protocols.DOKODEMO: return new Inbound.DokodemoSettings(protocol);            case Protocols.MTPROTO: return new Inbound.MtprotoSettings(protocol);            case Protocols.SOCKS: return new Inbound.SocksSettings(protocol);            case Protocols.HTTP: return new Inbound.HttpSettings(protocol);            default: return null;        }    }    static fromJson(protocol, json) {        switch (protocol) {            case Protocols.VMESS: return Inbound.VmessSettings.fromJson(json);            case Protocols.VLESS: return Inbound.VLESSSettings.fromJson(json);            case Protocols.TROJAN: return Inbound.TrojanSettings.fromJson(json);            case Protocols.SHADOWSOCKS: return Inbound.ShadowsocksSettings.fromJson(json);            case Protocols.DOKODEMO: return Inbound.DokodemoSettings.fromJson(json);            case Protocols.MTPROTO: return Inbound.MtprotoSettings.fromJson(json);            case Protocols.SOCKS: return Inbound.SocksSettings.fromJson(json);            case Protocols.HTTP: return Inbound.HttpSettings.fromJson(json);            default: return null;        }    }    toJson() {        return {};    }};Inbound.VmessSettings = class extends Inbound.Settings {    constructor(protocol,                vmesses=[new Inbound.VmessSettings.Vmess()],                disableInsecureEncryption=false) {        super(protocol);        this.vmesses = vmesses;        this.disableInsecure = disableInsecureEncryption;    }    indexOfVmessById(id) {        return this.vmesses.findIndex(vmess => vmess.id === id);    }    addVmess(vmess) {        if (this.indexOfVmessById(vmess.id) >= 0) {            return false;        }        this.vmesses.push(vmess);    }    delVmess(vmess) {        const i = this.indexOfVmessById(vmess.id);        if (i >= 0) {            this.vmesses.splice(i, 1);        }    }    static fromJson(json={}) {        return new Inbound.VmessSettings(            Protocols.VMESS,            json.clients.map(client => Inbound.VmessSettings.Vmess.fromJson(client)),            ObjectUtil.isEmpty(json.disableInsecureEncryption) ? false : json.disableInsecureEncryption,        );    }    toJson() {        return {            clients: Inbound.VmessSettings.toJsonArray(this.vmesses),            disableInsecureEncryption: this.disableInsecure,        };    }};Inbound.VmessSettings.Vmess = class extends XrayCommonClass {    constructor(id=RandomUtil.randomUUID(), alterId=0, email=RandomUtil.randomText(),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId='') {        super();        this.id = id;        this.alterId = alterId;        this.email = email;        this.limitIp = limitIp;        this.totalGB = totalGB;        this.expiryTime = expiryTime;        this.enable = enable;        this.tgId = tgId;        this.subId = subId;    }    static fromJson(json={}) {        return new Inbound.VmessSettings.Vmess(            json.id,            json.alterId,            json.email,            json.limitIp,            json.totalGB,            json.expiryTime,            json.enable,            json.tgId,            json.subId,        );    }    get _expiryTime() {        if (this.expiryTime === 0 || this.expiryTime === "") {            return null;        }        if (this.expiryTime < 0){            return this.expiryTime / -86400000;        }        return moment(this.expiryTime);    }    set _expiryTime(t) {        if (t == null || t === "") {            this.expiryTime = 0;        } else {            this.expiryTime = t.valueOf();        }    }    get _totalGB() {        return toFixed(this.totalGB / ONE_GB, 2);    }    set _totalGB(gb) {        this.totalGB = toFixed(gb * ONE_GB, 0);    }};Inbound.VLESSSettings = class extends Inbound.Settings {    constructor(protocol,                vlesses=[new Inbound.VLESSSettings.VLESS()],                decryption='none',                fallbacks=[],) {        super(protocol);        this.vlesses = vlesses;        this.decryption = 'none'; // Using decryption is not implemented here        this.fallbacks = fallbacks;    }    addFallback() {        this.fallbacks.push(new Inbound.VLESSSettings.Fallback());    }    delFallback(index) {        this.fallbacks.splice(index, 1);    }    // decryption should be set to static value    static fromJson(json={}) {        return new Inbound.VLESSSettings(            Protocols.VLESS,            json.clients.map(client => Inbound.VLESSSettings.VLESS.fromJson(client)),            'none',            Inbound.VLESSSettings.Fallback.fromJson(json.fallbacks),        );    }    toJson() {        return {            clients: Inbound.VLESSSettings.toJsonArray(this.vlesses),            decryption: 'none',            fallbacks: Inbound.VLESSSettings.toJsonArray(this.fallbacks),        };    }};Inbound.VLESSSettings.VLESS = class extends XrayCommonClass {    constructor(id=RandomUtil.randomUUID(), flow='', email=RandomUtil.randomText(),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId='') {        super();        this.id = id;        this.flow = flow;        this.email = email;        this.limitIp = limitIp;        this.totalGB = totalGB;        this.expiryTime = expiryTime;        this.enable = enable;        this.tgId = tgId;        this.subId = subId;    }    static fromJson(json={}) {        return new Inbound.VLESSSettings.VLESS(            json.id,            json.flow,            json.email,            json.limitIp,            json.totalGB,            json.expiryTime,            json.enable,            json.tgId,            json.subId,        );      }    get _expiryTime() {        if (this.expiryTime === 0 || this.expiryTime === "") {            return null;        }        if (this.expiryTime < 0){            return this.expiryTime / -86400000;        }        return moment(this.expiryTime);    }    set _expiryTime(t) {        if (t == null || t === "") {            this.expiryTime = 0;        } else {            this.expiryTime = t.valueOf();        }    }    get _totalGB() {        return toFixed(this.totalGB / ONE_GB, 2);    }    set _totalGB(gb) {        this.totalGB = toFixed(gb * ONE_GB, 0);    }};Inbound.VLESSSettings.Fallback = class extends XrayCommonClass {    constructor(name="", alpn='', path='', dest='', xver=0) {        super();        this.name = name;        this.alpn = alpn;        this.path = path;        this.dest = dest;        this.xver = xver;    }    toJson() {        let xver = this.xver;        if (!Number.isInteger(xver)) {            xver = 0;        }        return {            name: this.name,            alpn: this.alpn,            path: this.path,            dest: this.dest,            xver: xver,        }    }    static fromJson(json=[]) {        const fallbacks = [];        for (let fallback of json) {            fallbacks.push(new Inbound.VLESSSettings.Fallback(                fallback.name,                fallback.alpn,                fallback.path,                fallback.dest,                fallback.xver,            ))        }        return fallbacks;    }};Inbound.TrojanSettings = class extends Inbound.Settings {    constructor(protocol,                trojans=[new Inbound.TrojanSettings.Trojan()],                fallbacks=[],) {        super(protocol);        this.trojans = trojans;        this.fallbacks = fallbacks;    }    addTrojanFallback() {        this.fallbacks.push(new Inbound.TrojanSettings.Fallback());    }    delTrojanFallback(index) {        this.fallbacks.splice(index, 1);    }    static fromJson(json={}) {        return new Inbound.TrojanSettings(            Protocols.TROJAN,            json.clients.map(client => Inbound.TrojanSettings.Trojan.fromJson(client)),            Inbound.TrojanSettings.Fallback.fromJson(json.fallbacks),);    }    toJson() {        return {            clients: Inbound.TrojanSettings.toJsonArray(this.trojans),            fallbacks: Inbound.TrojanSettings.toJsonArray(this.fallbacks),        };    }};Inbound.TrojanSettings.Trojan = class extends XrayCommonClass {    constructor(password=RandomUtil.randomSeq(10), flow='', email=RandomUtil.randomText(),limitIp=0, totalGB=0, expiryTime=0, enable=true, tgId='', subId='') {        super();        this.password = password;        this.flow = flow;        this.email = email;        this.limitIp = limitIp;        this.totalGB = totalGB;        this.expiryTime = expiryTime;        this.enable = enable;        this.tgId = tgId;        this.subId = subId;    }    toJson() {        return {            password: this.password,            flow: this.flow,            email: this.email,            limitIp: this.limitIp,            totalGB: this.totalGB,            expiryTime: this.expiryTime,            enable: this.enable,            tgId: this.tgId,            subId: this.subId,        };    }    static fromJson(json = {}) {        return new Inbound.TrojanSettings.Trojan(            json.password,            json.flow,            json.email,            json.limitIp,            json.totalGB,            json.expiryTime,            json.enable,            json.tgId,            json.subId,        );    }    get _expiryTime() {        if (this.expiryTime === 0 || this.expiryTime === "") {            return null;        }        if (this.expiryTime < 0){            return this.expiryTime / -86400000;        }        return moment(this.expiryTime);    }    set _expiryTime(t) {        if (t == null || t === "") {            this.expiryTime = 0;        } else {            this.expiryTime = t.valueOf();        }    }    get _totalGB() {        return toFixed(this.totalGB / ONE_GB, 2);    }    set _totalGB(gb) {        this.totalGB = toFixed(gb * ONE_GB, 0);    }};Inbound.TrojanSettings.Fallback = class extends XrayCommonClass {    constructor(name="", alpn='', path='', dest='', xver=0) {        super();        this.name = name;        this.alpn = alpn;        this.path = path;        this.dest = dest;        this.xver = xver;    }    toJson() {        let xver = this.xver;        if (!Number.isInteger(xver)) {            xver = 0;        }        return {            name: this.name,            alpn: this.alpn,            path: this.path,            dest: this.dest,            xver: xver,        }    }    static fromJson(json=[]) {        const fallbacks = [];        for (let fallback of json) {            fallbacks.push(new Inbound.TrojanSettings.Fallback(                fallback.name,                fallback.alpn,                fallback.path,                fallback.dest,                fallback.xver,            ))        }        return fallbacks;    }};Inbound.ShadowsocksSettings = class extends Inbound.Settings {    constructor(protocol,                method=SSMethods.BLAKE3_AES_256_GCM,                password=RandomUtil.randomSeq(44),                network='tcp,udp'    ) {        super(protocol);        this.method = method;        this.password = password;        this.network = network;    }    static fromJson(json={}) {        return new Inbound.ShadowsocksSettings(            Protocols.SHADOWSOCKS,            json.method,            json.password,            json.network,        );    }    toJson() {        return {            method: this.method,            password: this.password,            network: this.network,        };    }};Inbound.DokodemoSettings = class extends Inbound.Settings {    constructor(protocol, address, port, network='tcp,udp', followRedirect=false) {        super(protocol);        this.address = address;        this.port = port;        this.network = network;        this.followRedirect = followRedirect;    }    static fromJson(json={}) {        return new Inbound.DokodemoSettings(            Protocols.DOKODEMO,            json.address,            json.port,            json.network,            json.followRedirect,        );    }    toJson() {        return {            address: this.address,            port: this.port,            network: this.network,            followRedirect: this.followRedirect,        };    }};Inbound.MtprotoSettings = class extends Inbound.Settings {    constructor(protocol, users=[new Inbound.MtprotoSettings.MtUser()]) {        super(protocol);        this.users = users;    }    static fromJson(json={}) {        return new Inbound.MtprotoSettings(            Protocols.MTPROTO,            json.users.map(user => Inbound.MtprotoSettings.MtUser.fromJson(user)),        );    }    toJson() {        return {            users: XrayCommonClass.toJsonArray(this.users),        };    }};Inbound.MtprotoSettings.MtUser = class extends XrayCommonClass {    constructor(secret=RandomUtil.randomMTSecret()) {        super();        this.secret = secret;    }    static fromJson(json={}) {        return new Inbound.MtprotoSettings.MtUser(json.secret);    }};Inbound.SocksSettings = class extends Inbound.Settings {    constructor(protocol, auth='password', accounts=[new Inbound.SocksSettings.SocksAccount()], udp=false, ip='127.0.0.1') {        super(protocol);        this.auth = auth;        this.accounts = accounts;        this.udp = udp;        this.ip = ip;    }    addAccount(account) {        this.accounts.push(account);    }    delAccount(index) {        this.accounts.splice(index, 1);    }    static fromJson(json={}) {        let accounts;        if (json.auth === 'password') {            accounts = json.accounts.map(                account => Inbound.SocksSettings.SocksAccount.fromJson(account)            )        }        return new Inbound.SocksSettings(            Protocols.SOCKS,            json.auth,            accounts,            json.udp,            json.ip,        );    }    toJson() {        return {            auth: this.auth,            accounts: this.auth === 'password' ? this.accounts.map(account => account.toJson()) : undefined,            udp: this.udp,            ip: this.ip,        };    }};Inbound.SocksSettings.SocksAccount = class extends XrayCommonClass {    constructor(user=RandomUtil.randomSeq(10), pass=RandomUtil.randomSeq(10)) {        super();        this.user = user;        this.pass = pass;    }    static fromJson(json={}) {        return new Inbound.SocksSettings.SocksAccount(json.user, json.pass);    }};Inbound.HttpSettings = class extends Inbound.Settings {    constructor(protocol, accounts=[new Inbound.HttpSettings.HttpAccount()]) {        super(protocol);        this.accounts = accounts;    }    addAccount(account) {        this.accounts.push(account);    }    delAccount(index) {        this.accounts.splice(index, 1);    }    static fromJson(json={}) {        return new Inbound.HttpSettings(            Protocols.HTTP,            json.accounts.map(account => Inbound.HttpSettings.HttpAccount.fromJson(account)),        );    }    toJson() {        return {            accounts: Inbound.HttpSettings.toJsonArray(this.accounts),        };    }};Inbound.HttpSettings.HttpAccount = class extends XrayCommonClass {    constructor(user=RandomUtil.randomSeq(10), pass=RandomUtil.randomSeq(10)) {        super();        this.user = user;        this.pass = pass;    }    static fromJson(json={}) {        return new Inbound.HttpSettings.HttpAccount(json.user, json.pass);    }};
 |