/* THIS IS A GENERATED/BUNDLED FILE BY ESBUILD if you want to view the source, please visit the github repository of this plugin */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod)); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // src/libs/Events.js var require_Events = __commonJS({ "src/libs/Events.js"(exports, module2) { module2.exports = class EventEmitter { constructor() { this.callbacks = {}; this.callbacks_once = {}; } on(event, cb) { if (!this.callbacks[event]) this.callbacks[event] = []; this.callbacks[event].push(cb); } off(event, cb) { if (this.callbacks[event]) { this.callbacks[event] = this.callbacks[event].filter((item) => item !== cb); } } removeListener(event, cb) { this.off(event, cb); } removeAllListeners(event) { if (event === void 0) { this.callbacks = {}; } else { delete this.callbacks[event]; } } once(event, cb) { if (!this.callbacks_once[event]) this.callbacks_once[event] = []; this.callbacks_once[event].push(cb); } emit(event, ...args) { let cbs = this.callbacks[event]; if (cbs) { cbs.forEach((cb) => cb(...args)); } cbs = this.callbacks_once[event]; if (cbs) { cbs.forEach((cb) => cb(...args)); delete this.callbacks_once[event]; } } }; } }); // node_modules/ms/index.js var require_ms = __commonJS({ "node_modules/ms/index.js"(exports, module2) { var s = 1e3; var m = s * 60; var h = m * 60; var d = h * 24; var w = d * 7; var y = d * 365.25; module2.exports = function(val, options) { options = options || {}; var type = typeof val; if (type === "string" && val.length > 0) { return parse(val); } else if (type === "number" && isFinite(val)) { return options.long ? fmtLong(val) : fmtShort(val); } throw new Error("val is not a non-empty string or a valid number. val=" + JSON.stringify(val)); }; function parse(str) { str = String(str); if (str.length > 100) { return; } var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(str); if (!match) { return; } var n = parseFloat(match[1]); var type = (match[2] || "ms").toLowerCase(); switch (type) { case "years": case "year": case "yrs": case "yr": case "y": return n * y; case "weeks": case "week": case "w": return n * w; case "days": case "day": case "d": return n * d; case "hours": case "hour": case "hrs": case "hr": case "h": return n * h; case "minutes": case "minute": case "mins": case "min": case "m": return n * m; case "seconds": case "second": case "secs": case "sec": case "s": return n * s; case "milliseconds": case "millisecond": case "msecs": case "msec": case "ms": return n; default: return void 0; } } function fmtShort(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return Math.round(ms / d) + "d"; } if (msAbs >= h) { return Math.round(ms / h) + "h"; } if (msAbs >= m) { return Math.round(ms / m) + "m"; } if (msAbs >= s) { return Math.round(ms / s) + "s"; } return ms + "ms"; } function fmtLong(ms) { var msAbs = Math.abs(ms); if (msAbs >= d) { return plural(ms, msAbs, d, "day"); } if (msAbs >= h) { return plural(ms, msAbs, h, "hour"); } if (msAbs >= m) { return plural(ms, msAbs, m, "minute"); } if (msAbs >= s) { return plural(ms, msAbs, s, "second"); } return ms + " ms"; } function plural(ms, msAbs, n, name) { var isPlural = msAbs >= n * 1.5; return Math.round(ms / n) + " " + name + (isPlural ? "s" : ""); } } }); // node_modules/debug/src/common.js var require_common = __commonJS({ "node_modules/debug/src/common.js"(exports, module2) { function setup(env) { createDebug.debug = createDebug; createDebug.default = createDebug; createDebug.coerce = coerce; createDebug.disable = disable; createDebug.enable = enable; createDebug.enabled = enabled; createDebug.humanize = require_ms(); createDebug.destroy = destroy; Object.keys(env).forEach((key) => { createDebug[key] = env[key]; }); createDebug.names = []; createDebug.skips = []; createDebug.formatters = {}; function selectColor(namespace) { let hash = 0; for (let i = 0; i < namespace.length; i++) { hash = (hash << 5) - hash + namespace.charCodeAt(i); hash |= 0; } return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; } createDebug.selectColor = selectColor; function createDebug(namespace) { let prevTime; let enableOverride = null; let namespacesCache; let enabledCache; function debug(...args) { if (!debug.enabled) { return; } const self = debug; const curr = Number(new Date()); const ms = curr - (prevTime || curr); self.diff = ms; self.prev = prevTime; self.curr = curr; prevTime = curr; args[0] = createDebug.coerce(args[0]); if (typeof args[0] !== "string") { args.unshift("%O"); } let index = 0; args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { if (match === "%%") { return "%"; } index++; const formatter = createDebug.formatters[format]; if (typeof formatter === "function") { const val = args[index]; match = formatter.call(self, val); args.splice(index, 1); index--; } return match; }); createDebug.formatArgs.call(self, args); const logFn = self.log || createDebug.log; logFn.apply(self, args); } debug.namespace = namespace; debug.useColors = createDebug.useColors(); debug.color = createDebug.selectColor(namespace); debug.extend = extend; debug.destroy = createDebug.destroy; Object.defineProperty(debug, "enabled", { enumerable: true, configurable: false, get: () => { if (enableOverride !== null) { return enableOverride; } if (namespacesCache !== createDebug.namespaces) { namespacesCache = createDebug.namespaces; enabledCache = createDebug.enabled(namespace); } return enabledCache; }, set: (v) => { enableOverride = v; } }); if (typeof createDebug.init === "function") { createDebug.init(debug); } return debug; } function extend(namespace, delimiter) { const newDebug = createDebug(this.namespace + (typeof delimiter === "undefined" ? ":" : delimiter) + namespace); newDebug.log = this.log; return newDebug; } function enable(namespaces) { createDebug.save(namespaces); createDebug.namespaces = namespaces; createDebug.names = []; createDebug.skips = []; let i; const split = (typeof namespaces === "string" ? namespaces : "").split(/[\s,]+/); const len = split.length; for (i = 0; i < len; i++) { if (!split[i]) { continue; } namespaces = split[i].replace(/\*/g, ".*?"); if (namespaces[0] === "-") { createDebug.skips.push(new RegExp("^" + namespaces.slice(1) + "$")); } else { createDebug.names.push(new RegExp("^" + namespaces + "$")); } } } function disable() { const namespaces = [ ...createDebug.names.map(toNamespace), ...createDebug.skips.map(toNamespace).map((namespace) => "-" + namespace) ].join(","); createDebug.enable(""); return namespaces; } function enabled(name) { if (name[name.length - 1] === "*") { return true; } let i; let len; for (i = 0, len = createDebug.skips.length; i < len; i++) { if (createDebug.skips[i].test(name)) { return false; } } for (i = 0, len = createDebug.names.length; i < len; i++) { if (createDebug.names[i].test(name)) { return true; } } return false; } function toNamespace(regexp) { return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, "*"); } function coerce(val) { if (val instanceof Error) { return val.stack || val.message; } return val; } function destroy() { console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); } createDebug.enable(createDebug.load()); return createDebug; } module2.exports = setup; } }); // node_modules/debug/src/browser.js var require_browser = __commonJS({ "node_modules/debug/src/browser.js"(exports, module2) { exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.storage = localstorage(); exports.destroy = (() => { let warned = false; return () => { if (!warned) { warned = true; console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."); } }; })(); exports.colors = [ "#0000CC", "#0000FF", "#0033CC", "#0033FF", "#0066CC", "#0066FF", "#0099CC", "#0099FF", "#00CC00", "#00CC33", "#00CC66", "#00CC99", "#00CCCC", "#00CCFF", "#3300CC", "#3300FF", "#3333CC", "#3333FF", "#3366CC", "#3366FF", "#3399CC", "#3399FF", "#33CC00", "#33CC33", "#33CC66", "#33CC99", "#33CCCC", "#33CCFF", "#6600CC", "#6600FF", "#6633CC", "#6633FF", "#66CC00", "#66CC33", "#9900CC", "#9900FF", "#9933CC", "#9933FF", "#99CC00", "#99CC33", "#CC0000", "#CC0033", "#CC0066", "#CC0099", "#CC00CC", "#CC00FF", "#CC3300", "#CC3333", "#CC3366", "#CC3399", "#CC33CC", "#CC33FF", "#CC6600", "#CC6633", "#CC9900", "#CC9933", "#CCCC00", "#CCCC33", "#FF0000", "#FF0033", "#FF0066", "#FF0099", "#FF00CC", "#FF00FF", "#FF3300", "#FF3333", "#FF3366", "#FF3399", "#FF33CC", "#FF33FF", "#FF6600", "#FF6633", "#FF9900", "#FF9933", "#FFCC00", "#FFCC33" ]; function useColors() { if (typeof window !== "undefined" && window.process && (window.process.type === "renderer" || window.process.__nwjs)) { return true; } if (typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { return false; } return typeof document !== "undefined" && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || typeof window !== "undefined" && window.console && (window.console.firebug || window.console.exception && window.console.table) || typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || typeof navigator !== "undefined" && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); } function formatArgs(args) { args[0] = (this.useColors ? "%c" : "") + this.namespace + (this.useColors ? " %c" : " ") + args[0] + (this.useColors ? "%c " : " ") + "+" + module2.exports.humanize(this.diff); if (!this.useColors) { return; } const c = "color: " + this.color; args.splice(1, 0, c, "color: inherit"); let index = 0; let lastC = 0; args[0].replace(/%[a-zA-Z%]/g, (match) => { if (match === "%%") { return; } index++; if (match === "%c") { lastC = index; } }); args.splice(lastC, 0, c); } exports.log = console.debug || console.log || (() => { }); function save(namespaces) { try { if (namespaces) { exports.storage.setItem("debug", namespaces); } else { exports.storage.removeItem("debug"); } } catch (error) { } } function load() { let r; try { r = exports.storage.getItem("debug"); } catch (error) { } if (!r && typeof process !== "undefined" && "env" in process) { r = process.env.DEBUG; } return r; } function localstorage() { try { return localStorage; } catch (error) { } } module2.exports = require_common()(exports); var { formatters } = module2.exports; formatters.j = function(v) { try { return JSON.stringify(v); } catch (error) { return "[UnexpectedJSONParseError]: " + error.message; } }; } }); // node_modules/anysocket/src/browser/events.js var require_events = __commonJS({ "node_modules/anysocket/src/browser/events.js"(exports, module2) { module2.exports = class EventEmitter { constructor() { this.callbacks = {}; this.callbacks_once = {}; } on(event, cb) { if (!this.callbacks[event]) this.callbacks[event] = []; this.callbacks[event].push(cb); } off(event, cb) { if (this.callbacks[event]) { this.callbacks[event] = this.callbacks[event].filter((item) => item !== cb); } } removeListener(event, cb) { this.off(event, cb); } removeAllListeners(event) { if (event === void 0) { this.callbacks = {}; } else { delete this.callbacks[event]; } } once(event, cb) { if (!this.callbacks_once[event]) this.callbacks_once[event] = []; this.callbacks_once[event].push(cb); } emit(event, ...args) { let cbs = this.callbacks[event]; if (cbs) { cbs.forEach((cb) => cb(...args)); } cbs = this.callbacks_once[event]; if (cbs) { cbs.forEach((cb) => cb(...args)); delete this.callbacks_once[event]; } } }; } }); // node_modules/anysocket/src/wrappers/events-wrapper.js var require_events_wrapper = __commonJS({ "node_modules/anysocket/src/wrappers/events-wrapper.js"(exports, module2) { if (typeof window !== "undefined" && typeof window.document !== "undefined") { module2.exports = require_events(); } else { module2.exports = require("events"); } } }); // node_modules/anysocket/src/browser/utils_buffer.js var require_utils_buffer = __commonJS({ "node_modules/anysocket/src/browser/utils_buffer.js"(exports, module2) { module2.exports = window._x = { stringToBuffer: function(str) { return btoa(str); }, bufferFromBase64: function(str) { const bytes = atob(str); const byteLength = bytes.length; const buffer = new Uint8Array(byteLength); for (let i = 0; i < byteLength; i++) { buffer[i] = bytes.charCodeAt(i); } return buffer; }, bufferToBase64: function(buf) { const uintArray = new Uint8Array(buf); const array = []; for (let i = 0; i < uintArray.length; i++) { array.push(String.fromCharCode(uintArray[i])); } return window.btoa(array.join("")); }, bufferToHex(buf) { return buf.reduce((memo, i) => { return memo + this.i2hex(i); }, ""); }, i2hex(i) { return ("0" + i.toString(16)).slice(-2); }, bufferFromHex(buf) { let view = new Uint8Array(buf.length / 2); for (let i = 0; i < buf.length; i += 2) { view[i / 2] = parseInt(buf.substring(i, i + 2), 16); } return view; }, isBuffer(buf) { return !!(buf.buffer instanceof ArrayBuffer && buf.BYTES_PER_ELEMENT); } }; } }); // node_modules/anysocket/src/browser/crypto.js var require_crypto = __commonJS({ "node_modules/anysocket/src/browser/crypto.js"(exports, module2) { var crypto2 = window.crypto || window.msCrypto; var QUOTA = 65536; if (!crypto2) throw new Error("Crypto is not supported in this browser!"); var BufferUtils = require_utils_buffer(); var ECDH_ALGORITHM = "P-521"; var encoder = new TextEncoder(); var Crypto = class { randomBytes(size) { let a = new Uint8Array(size); for (let i = 0; i < size; i += QUOTA) { crypto2.getRandomValues(a.subarray(i, i + Math.min(size - i, QUOTA))); } return a; } createECDH() { return new Promise(async (resolve, reject) => { window.crypto.subtle.generateKey({ name: "ECDH", namedCurve: ECDH_ALGORITHM }, false, ["deriveKey", "deriveBits"]).then(function(key) { resolve({ generateKeys: () => { return new Promise((resolve2, reject2) => { window.crypto.subtle.exportKey("raw", key.publicKey).then(function(keydata) { keydata = new Uint8Array(keydata); resolve2(keydata); }).catch(function(err) { reject2(err); }); }); }, computeSecret(buf) { return new Promise((resolve2, reject2) => { window.crypto.subtle.importKey("raw", buf, { name: "ECDH", namedCurve: ECDH_ALGORITHM }, false, []).then(function(keydata) { window.crypto.subtle.deriveBits({ name: "ECDH", namedCurve: ECDH_ALGORITHM, public: keydata }, key.privateKey, 512).then((keydata2) => { keydata2 = new Uint8Array(keydata2); resolve2(BufferUtils.bufferToHex(keydata2)); }); }).catch(function(err) { reject2(err); }); }); } }); }).catch(function(err) { reject(err); }); }); } pbkdf2Sync(secret, salt, iterations, length, algorithm) { let algo = { "sha256": "SHA-256" }; if (!algo[algorithm]) throw new Error("Invalid algorithm " + algorithm); algorithm = algo[algorithm]; return new Promise(async (resolve, reject) => { if (!(secret instanceof CryptoKey)) { secret = await window.crypto.subtle.importKey("raw", encoder.encode(secret), { name: "PBKDF2" }, false, ["deriveKey", "deriveBits"]); } window.crypto.subtle.deriveBits({ name: "PBKDF2", salt: encoder.encode(salt), iterations, hash: { name: algorithm } }, secret, length * 8).then(function(bits) { resolve(new Uint8Array(bits)); }).catch(function(err) { reject(err); }); }); } }; module2.exports = new Crypto(); } }); // node_modules/anysocket/src/browser/utils.js var require_utils = __commonJS({ "node_modules/anysocket/src/browser/utils.js"(exports, module2) { var crypto2 = require_crypto(); var BufferUtils = require_utils_buffer(); var encoder = new TextEncoder(); var decoder = new TextDecoder(); module2.exports = new class Utils { uuidv4() { return "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8; return v.toString(16); }); } generateAESKey() { return new Promise(async (resolve, reject) => { let ecdh = await crypto2.createECDH("secp521r1"); let publicKey = await ecdh.generateKeys(); resolve({ private: ecdh, public: BufferUtils.bufferToBase64(publicKey), nonce: BufferUtils.bufferToHex(crypto2.randomBytes(32)) }); }); } computeAESsecret(privateECDHKey, publicECDHKey) { return new Promise(async (resolve, reject) => { let result = await privateECDHKey.computeSecret(BufferUtils.bufferFromBase64(publicECDHKey), null, "hex"); result = result.substr(0, 128); resolve(result); }); } getAESSessionKey(secret, nonce, seq) { return new Promise(async (resolve, reject) => { nonce = nonce + "_" + seq; secret = await crypto2.pbkdf2Sync(secret, nonce, 1, 32, "sha256"); secret = BufferUtils.bufferToHex(secret); resolve(secret); }); } encryptAES(secret, data) { return new Promise((resolve, reject) => { window.crypto.subtle.importKey("raw", BufferUtils.bufferFromHex(secret), { name: "AES-CBC", length: 256 }, false, ["encrypt"]).then((key) => { let iv = window.crypto.getRandomValues(new Uint8Array(16)); window.crypto.subtle.encrypt({ name: "AES-CBC", iv }, key, encoder.encode(data)).then(function(encrypted) { resolve(BufferUtils.bufferToHex(iv) + BufferUtils.bufferToHex(new Uint8Array(encrypted))); }).catch(function(err) { reject(err); }); }).catch(reject); }); } decryptAES(secret, data) { return new Promise((resolve, reject) => { window.crypto.subtle.importKey("raw", BufferUtils.bufferFromHex(secret), { name: "AES-CBC", length: 256 }, false, ["decrypt"]).then((key) => { window.crypto.subtle.decrypt({ name: "AES-CBC", iv: BufferUtils.bufferFromHex(data.substr(0, 32)) }, key, BufferUtils.bufferFromHex(data.substr(32))).then(function(encrypted) { resolve(decoder.decode(encrypted)); }).catch((e) => { reject(e); }); }).catch((e) => { reject(e); }); }); } }(); } }); // node_modules/anysocket/src/libs/utils_buffer.js var require_utils_buffer2 = __commonJS({ "node_modules/anysocket/src/libs/utils_buffer.js"(exports, module2) { module2.exports = { bufferFromBase64: (str) => { return Buffer.from(str, "base64"); }, bufferToBase64: (buf) => { return buf.toString("base64"); }, bufferToHex(buf) { return buf.toString("hex"); }, bufferFromHex(buf) { return Buffer.from(buf, "hex"); }, isBuffer(buf) { return Buffer.isBuffer(buf); } }; } }); // node_modules/anysocket/src/wrappers/utils_buffer.js var require_utils_buffer3 = __commonJS({ "node_modules/anysocket/src/wrappers/utils_buffer.js"(exports, module2) { if (typeof window !== "undefined" && typeof window.document !== "undefined") { module2.exports = require_utils_buffer(); } else { module2.exports = require_utils_buffer2(); } } }); // node_modules/anysocket/src/libs/utils.js var require_utils2 = __commonJS({ "node_modules/anysocket/src/libs/utils.js"(exports, module2) { var crypto2 = require("crypto"); var BufferUtils = require_utils_buffer3(); module2.exports = new class Utils { uuidv4() { return "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function(c) { const r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8; return v.toString(16); }); } generateAESKey() { return new Promise(async (resolve, reject) => { let ecdh = await crypto2.createECDH("secp521r1"); let publicKey = await ecdh.generateKeys(); resolve({ private: ecdh, public: BufferUtils.bufferToBase64(publicKey), nonce: BufferUtils.bufferToHex(crypto2.randomBytes(32)) }); }); } computeAESsecret(privateECDHKey, publicECDHKey) { return new Promise(async (resolve, reject) => { let result = await privateECDHKey.computeSecret(BufferUtils.bufferFromBase64(publicECDHKey), null, "hex"); result = result.substr(0, 128); resolve(result); }); } getAESSessionKey(secret, nonce, seq) { return new Promise(async (resolve, reject) => { nonce = nonce + "_" + seq; secret = await crypto2.pbkdf2Sync(secret, nonce, 1, 32, "sha256"); secret = BufferUtils.bufferToHex(secret); resolve(secret); }); } encryptAES(secret, data) { return new Promise((resolve, reject) => { try { let iv = crypto2.randomBytes(16); let cipher = crypto2.createCipheriv("aes-256-cbc", BufferUtils.bufferFromHex(secret), iv); let encrypted = cipher.update(data); encrypted = Buffer.concat([encrypted, cipher.final()]); let msg = iv.toString("hex") + encrypted.toString("hex"); this.decryptAES(secret, msg); resolve(msg); } catch (e) { reject(e); } }); } decryptAES(secret, data) { return new Promise((resolve, reject) => { try { let iv = Buffer.from(data.substr(0, 32), "hex"); let encryptedText = Buffer.from(data.substr(32), "hex"); let decipher = crypto2.createDecipheriv("aes-256-cbc", BufferUtils.bufferFromHex(secret), iv); let decrypted = decipher.update(encryptedText); decrypted = Buffer.concat([decrypted, decipher.final()]); resolve(decrypted.toString()); } catch (e) { reject(e); } }); } }(); } }); // node_modules/anysocket/src/wrappers/utils.js var require_utils3 = __commonJS({ "node_modules/anysocket/src/wrappers/utils.js"(exports, module2) { if (typeof window !== "undefined" && typeof window.document !== "undefined") { module2.exports = require_utils(); } else { module2.exports = require_utils2(); } } }); // node_modules/anysocket/src/libs/_constants.js var require_constants = __commonJS({ "node_modules/anysocket/src/libs/_constants.js"(exports, module2) { var constants = { PACKET_TYPE: { AUTH: 1, INTERNAL: 2, LINK: 3, SWITCH: 4, HEARTBEAT: 5, FORWARD: 6 }, PACKET_LENGTH: { FULL: 1, PARTIAL: 2 }, INTERNAL_PACKET_TYPE: { NETWORK: 1, PROXY: 2, RPC: 3, RPC_NOTIFY: 4, SYNCED_TIME: 5 }, PROTOCOL_STATES: { ESTABLISHED: 0, AUTHING: 1, CONNECTED: 2, SWITCHING_PROTOCOL: 3, DISCONNECTED: 4 }, PROTOCOL_ENCRYPTION: { PLAIN: 1, E2EE: 2 }, MAX_PACKET_SIZE: 1024 * 1024, HTTP_CONTENT_TYPES: { txt: "text/plain;charset=utf-8", html: "text/html;charset=utf-8", htm: "text/html;charset=utf-8", css: "text/css;charset=utf-8", js: "text/javascript;charset=utf-8", md: "text/markdown;charset=utf-8", sh: "application/x-shellscript;charset=utf-8", svg: "image/svg+xml;charset=utf-8", xml: "text/xml;charset=utf-8", png: "image/png", jpeg: "image/jpeg", jpg: "image/jpeg", jpe: "image/jpeg", gif: "image/gif", ttf: "font/ttf", woff: "font/woff", woff2: "font/woff2", eot: "application/vnd.ms-fontobject", gz: "application/gzip", bz: "application/x-bzip", bz2: "application/x-bzip2", xz: "application/x-xz", zst: "application/zst" } }; for (let item in constants) { constants[item]._string = (number) => { for (let key in constants[item]) { if (constants[item][key] == number) { return key; } } return number; }; } module2.exports = constants; } }); // node_modules/anysocket/src/libs/AnyHTTPPeer.js var require_AnyHTTPPeer = __commonJS({ "node_modules/anysocket/src/libs/AnyHTTPPeer.js"(exports, module2) { var constants = require_constants(); var httpResult = Symbol("httpResult"); var reqSymbol = Symbol("req"); var resSymbol = Symbol("res"); var endSymbol = Symbol("ended"); var parseCookies = Symbol("parseCookies"); var debug = require_browser()("AnyHTTPPeer"); var url = require("url"); var fs = require("fs"); module2.exports = class AnyHTTPPeer { constructor(req, res) { let self = this; let qs = url.parse(req.url, true); self[reqSymbol] = req; self[resSymbol] = res; self[httpResult] = { _headers: {}, _body: [], _cookies: [], _url: qs.pathname, _query: { headers: req.headers, cookies: req.headers.cookie, method: req.method.toLowerCase(), body: req.body, qs: qs.query, upgrade: req.upgrade }, _status: 200 }; self[endSymbol] = false; self[parseCookies] = (cookies) => { const list = {}; cookies && cookies.split(";").forEach(function(cookie) { const parts = cookie.split("="); list[parts.shift().trim()] = decodeURI(parts.join("=")); }); self[httpResult]._cookies = list; return list; }; } get url() { return this[httpResult]._url; } get query() { return this[httpResult]._query; } get upgrade() { return this[httpResult]._query.upgrade; } get cookies() { return this[parseCookies](this.query.cookies); } serveFile(path, contentType) { fs.readFile(path, "utf8", (err, data) => { if (err) { this.status(404).end(); return false; } if (!contentType) { contentType = constants.HTTP_CONTENT_TYPES[path.split(".").pop().toLowerCase()] || "application/octet-stream"; } this.status(200).header("Content-Type", contentType).body(data).end(); }); } status(code) { if (this.isClosed()) { debug("Connection already ended!"); return this; } this[httpResult]._status = code; return this; } header(name, value) { if (this.isClosed()) { debug("Connection already ended!"); return this; } this[httpResult]._headers[name] = value; return this; } body(chunk) { if (this.isClosed()) { debug("Connection already ended!"); return this; } this[httpResult]._body.push(chunk); return this; } setCookie(key, value, expires) { this[httpResult]._cookies[key] = { value, expires }; return this; } deleteCookie(key) { this[httpResult]._cookies[key] = { value: "", expires: 1 }; return this; } end() { if (this.isClosed()) { debug("Connection already ended!"); return this; } if (Object.keys(this[httpResult]._cookies).length > 0) { let cookie = []; for (let key in this[httpResult]._cookies) { if (!this[httpResult]._cookies.hasOwnProperty(key)) continue; let c = this[httpResult]._cookies[key]; cookie.push(key + "=" + c.value + (c.expires ? ";Expires=" + new Date(c.expires).toUTCString() : "") + ";Path=/"); } if (cookie.length > 0) { this.header("Set-Cookie", cookie); } } if (this[resSymbol].writeHead) { this[resSymbol].writeHead(this[httpResult]._status, this[httpResult]._headers); } this[endSymbol] = true; if (this[httpResult]._body.length > 0) for (let i in this[httpResult]._body) { if (!this[httpResult]._body.hasOwnProperty(i)) continue; this[resSymbol].write(this[httpResult]._body[i]); } this[resSymbol].end(); } isClosed() { return this[endSymbol]; } }; } }); // node_modules/anysocket/src/libs/AnyHTTPRouter.js var require_AnyHTTPRouter = __commonJS({ "node_modules/anysocket/src/libs/AnyHTTPRouter.js"(exports, module2) { module2.exports = class AnyHTTPRouter { constructor() { this.routes = { _: [] }; this.routesRegexp = { _: [] }; this._upgradeCallback = null; this._process = this._process.bind(this); this._processUpgrade = this._processUpgrade.bind(this); } on(method, path, callback) { if (path instanceof RegExp) { if (!this.routesRegexp[method]) this.routesRegexp[method] = []; this.routesRegexp[method].push({ path, cb: callback }); } else { if (!this.routes[method]) this.routes[method] = {}; this.routes[method][path] = callback; } return this; } upgrade(callback) { this._upgradeCallback = callback; return this; } static(url, directory) { if (url[0] != "/") { url = "/" + url; } if (!directory) { directory = url; if (directory[0] == "/") { directory = "." + directory; } } return this.on("get", new RegExp("^" + url + "/(.*)$"), (peer) => { peer.serveFile(directory + peer.url.split(url).splice(1).join(url)); }); } any(path, callback) { return this.on("_", path, callback); } get(path, callback) { return this.on("get", path, callback); } post(path, callback) { return this.on("post", path, callback); } delete(path, callback) { return this.on("delete", path, callback); } error(callback) { this.onError = callback; } _processUpgrade(peer) { try { if (!this._upgradeCallback) return; this._upgradeCallback(peer); } catch (e) { return this._finish(peer, e); } } _process(peer) { try { if (this.routes._[peer.url]) { this.routes._[peer.url](peer); return true; } if (this.routes[peer.query.method] && this.routes[peer.query.method][peer.url]) { this.routes[peer.query.method][peer.url](peer); return true; } for (let item of this.routesRegexp._) { if (item.path.test(peer.url)) { item.cb(peer); return true; } } if (this.routesRegexp[peer.query.method]) { for (let item of this.routesRegexp[peer.query.method]) { if (item.path.test(peer.url)) { item.cb(peer); return true; } } } } catch (e) { return this._finish(peer, e); } this._finish(peer, new Error("No route for path: '" + peer.url + "'")); } _finish(peer, error) { if (this.onError) { this.onError(peer, error); } if (!peer.isClosed()) { peer.status(404).end(); } } }; } }); // node_modules/anysocket/src/libs/AnyPacker.js var require_AnyPacker = __commonJS({ "node_modules/anysocket/src/libs/AnyPacker.js"(exports, module2) { var BufferUtils = require_utils_buffer3(); var AnyPacker = class { packInt32(int) { const arr = new ArrayBuffer(4); const view = new DataView(arr); view.setInt32(0, int, false); return String.fromCharCode.apply(String, new Uint8Array(arr)); } unpackInt32(bytes) { const arr = new ArrayBuffer(4); const bufView = new Uint8Array(arr); for (let i in bytes) { bufView[i] = bytes.charCodeAt(i); } const view = new DataView(arr); return view.getInt32(0); } packHex(hex) { let str = ""; for (let n = 0; n < hex.length; n += 2) { str += String.fromCharCode(parseInt(hex.substr(n, 2), 16)); } return str; } unpackHex(bytes) { let str = ""; for (let n = 0; n < bytes.length; n++) { let hex = Number(bytes.charCodeAt(n)).toString(16); str += hex.length === 1 ? "0" + hex : hex; } return str; } packBytes(bytes) { if (bytes == null) { return null; } if (!(bytes instanceof ArrayBuffer || bytes instanceof Uint8Array)) throw new Error("packBytes requires ArrayBuffer or UInt8Array"); return BufferUtils.bufferToBase64(bytes); } unpackBytes(bytes) { if (bytes == null) { return null; } return BufferUtils.bufferFromBase64(bytes); } }; module2.exports = new AnyPacker(); } }); // node_modules/anysocket/src/libs/Packet.js var require_Packet = __commonJS({ "node_modules/anysocket/src/libs/Packet.js"(exports, module2) { var AnyPacker = require_AnyPacker(); var constants = require_constants(); var getSeq = (buf) => { return AnyPacker.unpackInt32(buf.substr(2, 4)); }; var getType = (buf) => { return parseInt(buf.substr(1, 1)); }; var Packet = class { constructor(data) { this.seq = 0; this.type = 0; this.buffer = []; this.data = null; if (data) this.data = data; } setType(type) { this.type = type; return this; } setSeq(seq) { this.seq = seq; return this; } setReplyTo(replyTo) { if (replyTo) this.seq = -replyTo; return this; } async serialize(max_packet_size, encryptFnc) { max_packet_size = max_packet_size || Number.MAX_SAFE_INTEGER; let packet = JSON.stringify(this.data); const count = Math.ceil(packet.length / max_packet_size); const chunks = new Array(count); for (let i = 0, o = 0; i < count; ++i, o += max_packet_size) { chunks[i] = await this.encode(i == count - 1 ? constants.PACKET_LENGTH.FULL.toString() : constants.PACKET_LENGTH.PARTIAL.toString(), packet.substr(o, max_packet_size), encryptFnc); } return chunks; } async encode(eol, packet, encryptFnc) { return eol + this.type.toString() + AnyPacker.packInt32(this.seq) + await encryptFnc(packet, Math.abs(this.seq)); } async deserialize(buf, encryptionState, decryptFnc) { decryptFnc = decryptFnc || ((packet) => Promise.resolve(packet)); const eol = buf.substr(0, 1) == constants.PACKET_LENGTH.FULL; this.type = getType(buf); this.seq = getSeq(buf); this.buffer.push(await decryptFnc(encryptionState, buf.substr(6), Math.abs(this.seq))); if (eol) { try { this.buffer = this.buffer.join(""); let packet = JSON.parse(this.buffer); this.buffer = []; this.data = packet; } catch (e) { console.log("packet error", e); this.data = null; } return true; } return false; } }; module2.exports = { data: (data) => { data = data || {}; return new Packet(data); }, buffer: () => { return new Packet(); }, getSeq: (buf) => { return getSeq(buf); }, getType: (buf) => { return getType(buf); }, isForwardPacket(buf) { return buf.substr(0, 1) == constants.PACKET_TYPE.FORWARD; }, TYPE: constants.PACKET_TYPE }; } }); // node_modules/anysocket/src/libs/AnyPacket.js var require_AnyPacket = __commonJS({ "node_modules/anysocket/src/libs/AnyPacket.js"(exports, module2) { var debug = require_browser()("AnyPacket"); var _send = Symbol("send function"); module2.exports = class AnyPacket { constructor(peer, message, sendFnc) { this.peer = peer; this.seq = message.seq; this.msg = message.data; this[_send] = sendFnc; } reply(message) { this[_send](message, this.seq); } }; } }); // node_modules/anysocket/src/libs/AnyPeer.js var require_AnyPeer = __commonJS({ "node_modules/anysocket/src/libs/AnyPeer.js"(exports, module2) { var debug = require_browser()("AnyPeer"); var constants = require_constants(); var EventEmitter2 = require_events_wrapper(); var Packet = require_Packet(); var AnyPacket = require_AnyPacket(); var AnyPacker = require_AnyPacker(); var _protocol = Symbol("private protocol"); var _packets = Symbol("packets"); var _links = Symbol("links"); var BufferUtils = require_utils_buffer3(); var isBoolean = function(obj) { return obj === true || obj === false || toString.call(obj) === "[object Boolean]"; }; module2.exports = class AnyPeer extends EventEmitter2 { constructor(protocol) { super(); this[_links] = {}; this[_protocol] = protocol; this[_packets] = {}; this.id = protocol.peerID; this.connectionID = protocol.connectionID; this.syncedTime = null; this.options = protocol.options; const handlers = { get: (target, name) => { const prop = target[name]; if (prop != null) { return prop; } if (!target.path) target.path = []; target.path.push(name); return new Proxy(target, { get: handlers.get, apply: (target2, name2, args) => { let path = target2.path; target2.path = []; return new Promise((resolve, reject) => { let binary = []; for (let item in args) { if (BufferUtils.isBuffer(args[item])) { args[item] = AnyPacker.packBytes(args[item]); binary.push(item); } } const packet = Packet.data({ type: constants.INTERNAL_PACKET_TYPE.RPC, method: path, params: args || null, bin: binary }).setType(constants.PACKET_TYPE.INTERNAL); this._send(packet, true).then((packet2) => { if (packet2.msg.error) { reject(packet2.msg); } else { let result = packet2.msg.result; if (packet2.msg.bin) result = AnyPacker.unpackBytes(result); resolve(result); } }).catch((e) => { reject(packet.msg); }); }); } }); } }; this.rpc = new Proxy(() => { }, handlers); protocol.on("internal", this.onInternalComs.bind(this)); protocol.on("message", this.onMessage.bind(this)); protocol.on("e2e", () => { this.onE2E(); }); protocol.on("disconnected", (peer, reason) => { this.emit("disconnected", peer, reason); }); } isProxy() { return this[_protocol].isProxy(); } addLink(peer) { this[_links][peer.id] = peer; } removeLink(peer) { delete this[_links][peer.id]; } getLinks() { return this[_links]; } getSyncedTime(refresh) { refresh = refresh || false; return new Promise((resolve, reject) => { if (!refresh && this.syncedTime) { resolve(Object.assign({ time: Date.now() + this.syncedTime.offset }, this.syncedTime)); } else { let clientTimestamp = Date.now(); this.sendInternal({ type: constants.INTERNAL_PACKET_TYPE.SYNCED_TIME, time: clientTimestamp }, true).then((packet) => { const T1 = packet.msg.o; const T2 = packet.msg.t; const T3 = packet.msg.t; const T4 = Date.now(); this.syncedTime = { rtt: T4 - T1 - (T3 - T2), offset: (T2 - T1 - (T4 - T3)) / 2 }; resolve(Object.assign({ time: Date.now() + this.syncedTime.offset }, this.syncedTime)); }).catch(reject); } }); } e2e() { this[_protocol].e2e(); } isE2EEnabled() { return this[_protocol].hasE2EEnabled(); } send(message, awaitReply, timeout) { const packet = Packet.data(message).setType(constants.PACKET_TYPE.LINK); return this._send(packet, awaitReply, timeout); } forward(packet) { this[_protocol].forward(packet); } sendInternal(message, awaitReply, timeout) { const packet = Packet.data(message).setType(constants.PACKET_TYPE.INTERNAL); return this._send(packet, awaitReply, timeout); } onMessage(peer, message) { if (message.seq < 0) { if (!this._resolveReply(message)) { debug("Dropped reply " + message.seq + ". Delivered after Timeout"); } return; } this.emit("message", new AnyPacket(this, message, this.send.bind(this))); } onE2E() { this.emit("e2e", this); } onInternalComs(peer, message) { if (message.seq < 0) { if (!this._resolveReply(message)) { debug("Dropped reply " + message.seq + ". Delivered after Timeout"); } return; } if (message.type == constants.PACKET_TYPE.INTERNAL) { this.emit("internal", new AnyPacket(this, message, this.sendInternal.bind(this))); } else { debug("Dropped internal packet!", message); } } disconnect(reason) { for (let seq in this[_packets]) { clearTimeout(this[_packets][seq].timeout); this[_packets][seq].reject("Peer disconnected!"); } this[_packets] = {}; this[_protocol].disconnect(reason); } _send(packet, awaitReply, timeout) { return new Promise((resolve, reject) => { if (!this[_protocol].isConnected()) { reject("Cannot send message. Peer is disconnected"); return; } if (!isBoolean(awaitReply) && awaitReply && awaitReply > 0) { packet.setReplyTo(awaitReply); } this[_protocol].send(packet); if (isBoolean(awaitReply) && awaitReply === true) { this[_packets][packet.seq] = { time: new Date().getTime(), resolve, reject, timeout: setTimeout(() => { if (this[_packets][packet.seq]) { let msg = this[_packets][packet.seq]; delete this[_packets][packet.seq]; this.disconnect("Missed reply timeout! Packet Type: " + Packet.TYPE._string(packet.type) + " - " + packet.seq); msg.reject("Timeout!"); } }, timeout || this[_protocol].options.replyTimeout) }; } }); } _recvForward(packet) { this[_protocol]._recvPacketQueue.push({ peer: this[_protocol].peer, recv: packet.msg, state: this[_protocol].ENCRYPTION_STATE }); } _resolveReply(message) { message.seq *= -1; if (this[_packets][message.seq]) { const tmp = this[_packets][message.seq]; delete this[_packets][message.seq]; clearTimeout(tmp.timeout); tmp.resolve(new AnyPacket(this, message, () => { debug("Cannot reply to a reply packet!"); })); return true; } return false; } }; } }); // node_modules/anysocket/src/libs/AnyMesh.js var require_AnyMesh = __commonJS({ "node_modules/anysocket/src/libs/AnyMesh.js"(exports, module2) { var AnyMesh = class { constructor(anysocket) { this.anysocket = anysocket; } }; module2.exports = AnyMesh; } }); // node_modules/reusify/reusify.js var require_reusify = __commonJS({ "node_modules/reusify/reusify.js"(exports, module2) { "use strict"; function reusify(Constructor) { var head = new Constructor(); var tail = head; function get() { var current = head; if (current.next) { head = current.next; } else { head = new Constructor(); tail = head; } current.next = null; return current; } function release(obj) { tail.next = obj; tail = obj; } return { get, release }; } module2.exports = reusify; } }); // node_modules/fastq/queue.js var require_queue = __commonJS({ "node_modules/fastq/queue.js"(exports, module2) { "use strict"; var reusify = require_reusify(); function fastqueue(context, worker, concurrency) { if (typeof context === "function") { concurrency = worker; worker = context; context = null; } if (concurrency < 1) { throw new Error("fastqueue concurrency must be greater than 1"); } var cache = reusify(Task); var queueHead = null; var queueTail = null; var _running = 0; var errorHandler = null; var self = { push, drain: noop, saturated: noop, pause, paused: false, concurrency, running, resume, idle, length, getQueue, unshift, empty: noop, kill, killAndDrain, error }; return self; function running() { return _running; } function pause() { self.paused = true; } function length() { var current = queueHead; var counter = 0; while (current) { current = current.next; counter++; } return counter; } function getQueue() { var current = queueHead; var tasks = []; while (current) { tasks.push(current.value); current = current.next; } return tasks; } function resume() { if (!self.paused) return; self.paused = false; for (var i = 0; i < self.concurrency; i++) { _running++; release(); } } function idle() { return _running === 0 && self.length() === 0; } function push(value, done) { var current = cache.get(); current.context = context; current.release = release; current.value = value; current.callback = done || noop; current.errorHandler = errorHandler; if (_running === self.concurrency || self.paused) { if (queueTail) { queueTail.next = current; queueTail = current; } else { queueHead = current; queueTail = current; self.saturated(); } } else { _running++; worker.call(context, current.value, current.worked); } } function unshift(value, done) { var current = cache.get(); current.context = context; current.release = release; current.value = value; current.callback = done || noop; if (_running === self.concurrency || self.paused) { if (queueHead) { current.next = queueHead; queueHead = current; } else { queueHead = current; queueTail = current; self.saturated(); } } else { _running++; worker.call(context, current.value, current.worked); } } function release(holder) { if (holder) { cache.release(holder); } var next = queueHead; if (next) { if (!self.paused) { if (queueTail === queueHead) { queueTail = null; } queueHead = next.next; next.next = null; worker.call(context, next.value, next.worked); if (queueTail === null) { self.empty(); } } else { _running--; } } else if (--_running === 0) { self.drain(); } } function kill() { queueHead = null; queueTail = null; self.drain = noop; } function killAndDrain() { queueHead = null; queueTail = null; self.drain(); self.drain = noop; } function error(handler) { errorHandler = handler; } } function noop() { } function Task() { this.value = null; this.callback = noop; this.next = null; this.release = noop; this.context = null; this.errorHandler = null; var self = this; this.worked = function worked(err, result) { var callback = self.callback; var errorHandler = self.errorHandler; var val = self.value; self.value = null; self.callback = noop; if (self.errorHandler) { errorHandler(err, val); } callback.call(self.context, err, result); self.release(self); }; } function queueAsPromised(context, worker, concurrency) { if (typeof context === "function") { concurrency = worker; worker = context; context = null; } function asyncWrapper(arg, cb) { worker.call(this, arg).then(function(res) { cb(null, res); }, cb); } var queue = fastqueue(context, asyncWrapper, concurrency); var pushCb = queue.push; var unshiftCb = queue.unshift; queue.push = push; queue.unshift = unshift; queue.drained = drained; return queue; function push(value) { var p = new Promise(function(resolve, reject) { pushCb(value, function(err, result) { if (err) { reject(err); return; } resolve(result); }); }); p.catch(noop); return p; } function unshift(value) { var p = new Promise(function(resolve, reject) { unshiftCb(value, function(err, result) { if (err) { reject(err); return; } resolve(result); }); }); p.catch(noop); return p; } function drained() { if (queue.idle()) { return new Promise(function(resolve) { resolve(); }); } var previousDrain = queue.drain; var p = new Promise(function(resolve) { queue.drain = function() { previousDrain(); resolve(); }; }); return p; } } module2.exports = fastqueue; module2.exports.promise = queueAsPromised; } }); // node_modules/anysocket/src/libs/AnyProtocol.js var require_AnyProtocol = __commonJS({ "node_modules/anysocket/src/libs/AnyProtocol.js"(exports, module2) { var debug = require_browser()("AnyProtocol"); var EventEmitter2 = require_events_wrapper(); var FastQ = require_queue(); var Packet = require_Packet(); var Utils2 = require_utils3(); var AnyPacker = require_AnyPacker(); var constants = require_constants(); var ENCRYPTION_SECRET = Symbol("secret key"); var ENCRYPTION_PRIVATE = Symbol("private key"); var ENCRYPTION_NONCE = Symbol("nonce"); var heartbeatTimer = Symbol("heartbeat timer"); var heartbeatsMissed = Symbol("heartbeats missed"); var heartbeatPonged = Symbol("heartbeat ponged"); var authTimeout = Symbol("authTimeout"); var e2eTimeout = Symbol("e2eTimeout"); module2.exports = class AnyProtocol extends EventEmitter2 { constructor(anysocket, peer, options) { super(); this._seq = 0; this[ENCRYPTION_SECRET] = null; this[ENCRYPTION_PRIVATE] = null; this[ENCRYPTION_NONCE] = null; this[heartbeatTimer] = 0; this[heartbeatsMissed] = 0; this[heartbeatPonged] = true; this[authTimeout] = false; this[e2eTimeout] = false; this.peerID = peer.id; this.peer = peer; this.options = Object.assign({ authTimeout: 5 * 1e3, e2eTimeout: 5 * 1e3, replyTimeout: 30 * 1e3, heartbeatInterval: 5 * 1e3 }, options); this.connectionID = this.peer.connectionID; this.anysocket = anysocket; this._packetQueue = FastQ(this, this.processPacketQueue.bind(this), 1); this._linkPacketQueue = FastQ(this, this.processLinkPacketQueue.bind(this), 1); this._recvPacketQueue = FastQ(this, this.processRecvPacketQueue.bind(this), 1); this._recvLinkPacketQueue = FastQ(this, this.processRecvLinkPacketQueue.bind(this), 1); this._packets = {}; this.changeState(constants.PROTOCOL_STATES.ESTABLISHED); this.ENCRYPTION_STATE = constants.PROTOCOL_ENCRYPTION.PLAIN; this.peer.on("message", (peer2, recv) => { this._heartbeat(true); this._recvPacketQueue.push({ peer: peer2, recv, state: this.ENCRYPTION_STATE }); }); if (this.peer.isClient() && !this.peerID) { this.changeState(constants.PROTOCOL_STATES.AUTHING); this.send(Packet.data({ id: this.anysocket.id, auth: this.anysocket.authPacket() }).setType(Packet.TYPE.AUTH)); } if (this.peerID) { this.changeState(constants.PROTOCOL_STATES.CONNECTED); } } isProxy() { return !!this.peer.isProxy; } isConnected() { return this.state != constants.PROTOCOL_STATES.DISCONNECTED; } send(packet) { if (packet.seq == 0) packet.setSeq(this._getSeq()); if (packet.type != Packet.TYPE.HEARTBEAT) { this._heartbeat(); } return new Promise((resolve, reject) => { const rejectFnc = (e) => { this.disconnect(e); reject(e); }; if (this.isLINKMessage(packet.type)) { this._linkPacketQueue.push({ packet, resolve, reject: rejectFnc }); } else { this._send(packet, resolve, rejectFnc); } }); } _send(packet, resolve, reject) { debug(this.peerID, ">>>>", Packet.TYPE._string(packet.type), packet.seq); packet.serialize(constants.MAX_PACKET_SIZE, this._encrypt.bind(this)).then((packet2) => { for (let i = 0; i < packet2.length; i++) { const item = { packet: packet2[i], reject }; if (i == packet2.length - 1) { item.resolve = resolve; } this._packetQueue.push(item); } }).catch(reject); } forward(packet) { return new Promise((resolve, reject) => { this._packetQueue.push({ packet: this._encodeForwardPacket(packet.to, packet.from, packet.msg), resolve, reject }); }); } hasE2EEnabled() { return !!this[ENCRYPTION_PRIVATE]; } e2e() { Utils2.generateAESKey().then((result) => { this[ENCRYPTION_PRIVATE] = result.private; this[ENCRYPTION_NONCE] = result.nonce; this.changeState(constants.PROTOCOL_STATES.SWITCHING_PROTOCOL); this.send(Packet.data({ type: constants.PROTOCOL_ENCRYPTION.E2EE, key: result.public, nonce: result.nonce }).setType(Packet.TYPE.SWITCH)); }).catch((e) => { this.disconnect(e); }); } onPacket(peer, recv, encryptionState) { return new Promise((resolve, reject) => { let invalidPacket = true; if (Packet.isForwardPacket(recv)) { this.emit("forward", this.peerID, this._decodeForwardPacket(recv)); resolve(); } else { let seq = Packet.getSeq(recv); if (!this._packets[seq]) { this._packets[seq] = Packet.buffer(); } let packet = this._packets[seq]; packet.deserialize(recv, encryptionState, this._decrypt.bind(this)).then((result) => { debug(this.peerID, "<<<<", Packet.TYPE._string(packet.type), packet.seq); if (result) { delete this._packets[seq]; switch (this.state) { case constants.PROTOCOL_STATES.ESTABLISHED: if (packet.type == Packet.TYPE.AUTH) { invalidPacket = false; if (!packet.data.id || !this.anysocket.onAuth(packet.data)) { return this.disconnect("Invalid Auth Packet!"); } this.peerID = packet.data.id; this.send(Packet.data({ id: this.anysocket.id, auth: this.anysocket.authPacket() }).setType(Packet.TYPE.AUTH)).then(() => { this.changeState(constants.PROTOCOL_STATES.CONNECTED); this.emit("ready", this); }); resolve(); } break; case constants.PROTOCOL_STATES.AUTHING: if (packet.type == Packet.TYPE.AUTH) { invalidPacket = false; this.changeState(constants.PROTOCOL_STATES.CONNECTED); if (!packet.data.id || !this.anysocket.onAuth(packet.data)) { return this.disconnect("Invalid Auth Packet!"); } this.peerID = packet.data.id; this.emit("ready", this); resolve(); } break; case constants.PROTOCOL_STATES.CONNECTED: if (packet.type == Packet.TYPE.LINK) { invalidPacket = false; this.emit("message", this, { seq: packet.seq, data: packet.data }); resolve(); } else if (packet.type == Packet.TYPE.INTERNAL) { invalidPacket = false; this.emit("internal", this, { seq: packet.seq, type: packet.type, data: packet.data }); resolve(); } else if (packet.type == Packet.TYPE.SWITCH) { invalidPacket = false; Utils2.generateAESKey().then((result2) => { this[ENCRYPTION_PRIVATE] = result2.private; this[ENCRYPTION_NONCE] = packet.data.nonce + result2.nonce; return Utils2.getAESSessionKey(this[ENCRYPTION_NONCE], this.peerID, 0).then((nonce) => { this[ENCRYPTION_NONCE] = nonce; return Utils2.computeAESsecret(this[ENCRYPTION_PRIVATE], packet.data.key).then((secret) => { this[ENCRYPTION_SECRET] = secret; this.send(Packet.data({ type: constants.PROTOCOL_ENCRYPTION.E2EE, key: result2.public, nonce: result2.nonce }).setType(Packet.TYPE.SWITCH)).then(() => { this.ENCRYPTION_STATE = constants.PROTOCOL_ENCRYPTION.E2EE; this.changeState(constants.PROTOCOL_STATES.CONNECTED); this.emit("e2e", this); resolve(); }); }); }); }).catch((e) => { this.disconnect(e); }); } else if (packet.type == Packet.TYPE.HEARTBEAT) { invalidPacket = false; this._heartbeatPong(packet.data); resolve(); } break; case constants.PROTOCOL_STATES.SWITCHING_PROTOCOL: if (packet.type == Packet.TYPE.SWITCH) { invalidPacket = false; this[ENCRYPTION_NONCE] = this[ENCRYPTION_NONCE] + packet.data.nonce; Utils2.getAESSessionKey(this[ENCRYPTION_NONCE], this.anysocket.id, 0).then((nonce) => { this[ENCRYPTION_NONCE] = nonce; return Utils2.computeAESsecret(this[ENCRYPTION_PRIVATE], packet.data.key).then((secret) => { this[ENCRYPTION_SECRET] = secret; this.ENCRYPTION_STATE = constants.PROTOCOL_ENCRYPTION.E2EE; this.changeState(constants.PROTOCOL_STATES.CONNECTED); this.emit("e2e", this); resolve(); }); }).catch((e) => { this.disconnect(e); }); } break; case constants.PROTOCOL_STATES.DISCONNECTED: invalidPacket = false; resolve(); break; } if (invalidPacket) { console.log("Invalid packet received! RECV:", packet); return this.disconnect("Invalid Packet!"); } } else { resolve(); } }); } }); } changeState(state) { this.state = state; switch (this.state) { case constants.PROTOCOL_STATES.ESTABLISHED: this[authTimeout] = setTimeout(() => { this.disconnect("auth timed out"); }, this.options.authTimeout); this._linkPacketQueue.pause(); this._recvLinkPacketQueue.pause(); break; case constants.PROTOCOL_STATES.AUTHING: clearTimeout(this[authTimeout]); this[authTimeout] = false; this._linkPacketQueue.pause(); this._recvLinkPacketQueue.pause(); break; case constants.PROTOCOL_STATES.CONNECTED: clearTimeout(this[authTimeout]); this[authTimeout] = false; clearTimeout(this[e2eTimeout]); this[e2eTimeout] = false; this._linkPacketQueue.resume(); this._recvLinkPacketQueue.resume(); break; case constants.PROTOCOL_STATES.SWITCHING_PROTOCOL: this[e2eTimeout] = setTimeout(() => { this.disconnect("e2e timed out"); }, this.options.e2eTimeout); this._linkPacketQueue.pause(); this._recvLinkPacketQueue.pause(); break; case constants.PROTOCOL_STATES.DISCONNECTED: this._packetQueue.pause(); this._packetQueue.kill(); this._linkPacketQueue.pause(); this._linkPacketQueue.kill(); this._recvPacketQueue.pause(); this._recvPacketQueue.kill(); this._recvLinkPacketQueue.pause(); this._recvLinkPacketQueue.kill(); break; } } disconnect(reason) { this.changeState(constants.PROTOCOL_STATES.DISCONNECTED); this._heartbeat(); if (this.isProxy()) { this.anysocket.unproxy(this.peer.id, this.peer.socket.id, reason); } else { this.peer.disconnect(reason); } } processPacketQueue(item, cb) { this.peer.send(item.packet).then(() => { if (item.resolve) item.resolve(); cb(null, null); }).catch((e) => { item.reject(e); this._packetQueue.kill(); cb(null, null); }); } processLinkPacketQueue(item, cb) { this._send(item.packet, item.resolve, item.reject); cb(null, null); } processRecvPacketQueue(item, cb) { if (Packet.isForwardPacket(item.recv)) { this.emit("forward", this.peerID, this._decodeForwardPacket(item.recv)); cb(null, null); } else { if (this.isLINKMessage(Packet.getType(item.recv))) { item.state = this.ENCRYPTION_STATE; this._recvLinkPacketQueue.push(item); cb(null, null); } else { this.onPacket(item.peer, item.recv, item.state).then(() => { cb(null, null); }); } } } processRecvLinkPacketQueue(item, cb) { this.onPacket(item.peer, item.recv, item.state).then(() => { cb(null, null); }); } _encrypt(packet, seq) { return new Promise((resolve) => { switch (this.ENCRYPTION_STATE) { case constants.PROTOCOL_ENCRYPTION.PLAIN: resolve(packet); break; case constants.PROTOCOL_ENCRYPTION.E2EE: Utils2.getAESSessionKey(this[ENCRYPTION_SECRET], this[ENCRYPTION_NONCE], seq).then((secretKey) => { return Utils2.encryptAES(secretKey, packet).then(resolve); }).catch((e) => { this.disconnect(e); }); break; default: throw new Error("[encrypt] Encryption state '" + this.ENCRYPTION_STATE + "' not implemented!"); } }); } _decrypt(encryptionState, packet, seq) { return new Promise((resolve) => { switch (encryptionState) { case constants.PROTOCOL_ENCRYPTION.PLAIN: resolve(packet); break; case constants.PROTOCOL_ENCRYPTION.E2EE: Utils2.getAESSessionKey(this[ENCRYPTION_SECRET], this[ENCRYPTION_NONCE], seq).then((secretKey) => { return Utils2.decryptAES(secretKey, packet).then(resolve); }).catch((e) => { this.disconnect(e); }); break; default: throw new Error("[decrypt] Encryption state '" + encryptionState + "' not implemented!"); } }); } _encodeForwardPacket(to, from, msg) { return Packet.TYPE.FORWARD + AnyPacker.packHex(to) + AnyPacker.packHex(from) + msg; } _decodeForwardPacket(recv) { recv = { to: AnyPacker.unpackHex(recv.substr(1, 16)), from: AnyPacker.unpackHex(recv.substr(17, 16)), msg: recv.substr(33) }; return recv; } _getSeq() { if (this._seq >= 2147483647) { this._seq = 0; } this._seq++; return this._seq; } _heartbeat(ponged) { ponged = ponged || false; if (this.isProxy()) return; clearTimeout(this[heartbeatTimer]); if (ponged) { this._heartbeatPong(); } if (this.state == constants.PROTOCOL_STATES.AUTHING || this.state == constants.PROTOCOL_STATES.DISCONNECTED) return; this[heartbeatTimer] = setTimeout(() => { if (!this[heartbeatPonged]) { this[heartbeatsMissed]++; if (this[heartbeatsMissed] >= 2) { this.disconnect("Missed Heartbeats"); return; } this._heartbeat(); return; } this[heartbeatsMissed] = 0; this[heartbeatPonged] = false; const packet = Packet.data(1).setType(Packet.TYPE.HEARTBEAT); this.send(packet).catch((e) => { debug("Heartbeat Error:", e); this.disconnect(e); }); }, this.options.heartbeatInterval); } _heartbeatPong(data) { if (data == 1) { const packet = Packet.data(2).setType(Packet.TYPE.HEARTBEAT); this.send(packet).catch((e) => { debug("Heartbeat Error:", e); this.disconnect(e); }); } else { this[heartbeatPonged] = true; this[heartbeatsMissed] = 0; } } isLINKMessage(type) { return [Packet.TYPE.INTERNAL, Packet.TYPE.LINK].indexOf(type) != -1; } }; } }); // node_modules/anysocket/src/modules/transports/abstract/AbstractTransport.js var require_AbstractTransport = __commonJS({ "node_modules/anysocket/src/modules/transports/abstract/AbstractTransport.js"(exports, module2) { var EventEmitter2 = require_events_wrapper(); var Utils2 = require_utils3(); var AbstractTransport = class extends EventEmitter2 { constructor(type, options) { super(); this.id = Utils2.uuidv4(); this.options = Object.assign({}, options); this.type = type; this.peers = /* @__PURE__ */ new Map(); this.started = false; } listen() { return new Promise((resolve, reject) => { if (this.started) { resolve(); return; } this.onListen().then(() => { this.started = true; resolve(); }).catch((err) => { reject(err); }); }); } connect() { return new Promise((resolve, reject) => { if (this.started) { resolve(); return; } this.onConnect().then(() => { this.started = true; resolve(); }).catch((err) => { reject(err); }); }); } stop() { return new Promise((resolve, reject) => { if (!this.started) { resolve(); return; } this.started = false; for (const peer of this.peers.values()) { peer.disconnect("Local Connection Closed"); } this.onStop().then(() => { resolve(); }).catch((err) => { reject(err); }); }); } addPeer(peer) { peer.type = this.type; peer.on("connected", () => { this.peers.set(peer.connectionID, peer); this.emit("connected", peer); }); peer.on("disconnected", (peer2, reason) => { this.peers.delete(peer2.connectionID); this.emit("disconnected", peer2, reason); }); peer.init(); } onConnect() { throw new Error("onConnect() must be implemented"); } onListen() { throw new Error("onListen() must be implemented"); } onStop() { throw new Error("onStop() must be implemented"); } }; __publicField(AbstractTransport, "scheme", () => { throw new Error("static scheme() must be implemented"); }); module2.exports = AbstractTransport; AbstractTransport.TYPE = { CLIENT: "client", SERVER: "server", HTTP: "http" }; } }); // node_modules/anysocket/src/modules/transports/abstract/AbstractPeer.js var require_AbstractPeer = __commonJS({ "node_modules/anysocket/src/modules/transports/abstract/AbstractPeer.js"(exports, module2) { var EventEmitter2 = require_events_wrapper(); var Utils2 = require_utils3(); var AbstractTransport = require_AbstractTransport(); var AbstractPeer = class extends EventEmitter2 { constructor(socket) { super(); this.connectionID = Utils2.uuidv4(); this.connected = true; this.socket = socket; this.type = AbstractTransport.TYPE.NONE; this.inited = false; } init() { if (this.inited) return; this.inited = true; this.onConnect(); this.emit("connected", this); } isClient() { if (this.type == AbstractTransport.TYPE.NONE) throw new Error("Invalid transport type!!!"); return this.type == AbstractTransport.TYPE.CLIENT; } disconnect(reason) { if (this.connected) { this.connected = false; this.onDisconnect(); this.emit("disconnected", this, reason); } } send(message) { throw new Error("send() must be implemented"); } onConnect() { throw new Error("onConnect() must be implemented"); } onDisconnect() { throw new Error("onDisconnect() must be implemented"); } }; module2.exports = AbstractPeer; } }); // node_modules/anysocket/src/libs/ProxyPeer.js var require_ProxyPeer = __commonJS({ "node_modules/anysocket/src/libs/ProxyPeer.js"(exports, module2) { var AbstractPeer = require_AbstractPeer(); var AbstractTransport = require_AbstractTransport(); module2.exports = class ProxyPeer extends AbstractPeer { constructor(isClient, anysocketID, peerID, socket) { super(socket); this.id = peerID; this.anysocketID = anysocketID; this.type = isClient ? AbstractTransport.TYPE.CLIENT : AbstractTransport.TYPE.SERVER; this.isProxy = true; this.init(); } onConnect() { } send(message) { return new Promise((resolve, reject) => { try { this.socket.forward({ to: this.id, from: this.anysocketID, msg: message }); resolve(); } catch (e) { reject(e); } }); } onDisconnect() { } }; } }); // node_modules/anysocket/src/libs/AnySocket.js var require_AnySocket = __commonJS({ "node_modules/anysocket/src/libs/AnySocket.js"(exports, module2) { var debug = require_browser()("AnySocket"); var fs = require("fs"); var EventEmitter2 = require_events_wrapper(); var Utils2 = require_utils3(); var BufferUtils = require_utils_buffer3(); var constants = require_constants(); var AnyHTTPPeer = require_AnyHTTPPeer(); var AnyRouter = require_AnyHTTPRouter(); var _private = { peersConnected: Symbol("peers connected"), peers: Symbol("ready peers"), transports: Symbol("transports"), onForward: Symbol("onForward"), onPeerConnected: Symbol("onPeerConnected"), onProtocolReady: Symbol("onPeerReady"), onPeerDisconnected: Symbol("onPeerDisconnected"), onPeerInternalMessage: Symbol("onPeerInternalMessage"), findTransport: Symbol("findTransport"), httpBundle: Symbol("http bundle js"), anymesh: Symbol("AnyMesh"), httpServer: Symbol("HTTPServer") }; var AnyPeer = require_AnyPeer(); var AnyMesh = require_AnyMesh(); var AnyProtocol = require_AnyProtocol(); var ProxyPeer = require_ProxyPeer(); var AnySocket4 = class extends EventEmitter2 { constructor() { super(); this._started = false; this.id = Utils2.uuidv4(); this.http = new AnyRouter(); debug("AnySocketID:", this.id); this.rpc = {}; this[_private.peersConnected] = {}; this[_private.peers] = {}; this[_private.transports] = {}; this[_private.httpServer] = null; this[_private.anymesh] = null; if (typeof window === "undefined") { this[_private.httpBundle] = fs.readFileSync(__dirname + "/../../dist/anysocket.browser.js"); } return this; } filter(options) { } broadcast(message, awaitReply) { awaitReply = awaitReply || false; return new Promise((resolve, reject) => { const promises = []; for (let p in this[_private.peers]) { p = this[_private.peers][p]; promises.push(p.send(message, awaitReply)); Promise.all(promises).then(resolve).catch(reject); } }); } mesh() { if (this._started) throw new Error("Cannot enable Mesh while AnySocket is running. You must first stop AnySocket!"); this[_private.anymesh] = new AnyMesh(this); } setRPC(rpc) { this.rpc = rpc; } canProxy(peerID, otherPeerID) { return false; } proxy(peerID, throughPeerID) { return new Promise((resolve, reject) => { if (peerID == throughPeerID || peerID == this.id) { reject("Cannot proxy loopback!"); return; } if (this[_private.peers][throughPeerID].isProxy()) { reject("Cannot proxy via a proxy! atm... :)"); return; } this[_private.peers][throughPeerID].sendInternal({ type: constants.INTERNAL_PACKET_TYPE.PROXY, action: "proxy", id: peerID }, true).then((packet) => { if (packet.msg.ok && !this[_private.peers][peerID]) { let protocol = new AnyProtocol(this, new ProxyPeer(true, this.id, peerID, this[_private.peers][throughPeerID]), this[_private.peers][throughPeerID].options); this[_private.onProtocolReady](protocol); resolve(this[_private.peers][peerID]); } else { reject("Cannot proxy!"); } }).catch(reject); }); } unproxy(peerID, throughPeerID, reason) { reason = reason || "Proxy Connection Closed"; if (this[_private.peers][peerID] && this[_private.peers][peerID].isProxy()) { this[_private.peers][throughPeerID].sendInternal({ type: constants.INTERNAL_PACKET_TYPE.PROXY, action: "unproxy", id: peerID }); this[_private.onPeerDisconnected](this[_private.peers][peerID], reason); } } hasPeer(id) { return !!this[_private.peers][id]; } hasDirectPeer(id) { return !!(this[_private.peers][id] && !this[_private.peers][id].isProxy()); } server(scheme, options) { return this.listen(scheme, options); } listen(scheme, options) { this._started = true; options = options || {}; if (typeof options == "number") { options = { port: options }; } options.ip = options.ip || "0.0.0.0"; if (["http", "ws"].indexOf(scheme.toLowerCase()) == -1 && !options.port) throw new Error("Invalid port!"); if (["ws"].indexOf(scheme.toLowerCase()) != -1) { if (!this[_private.httpServer]) { this.listen("http", options); } options = { server: this[_private.httpServer] }; } let transport = this[_private.findTransport](scheme); transport = new transport("server", options); this[_private.transports][transport.id] = transport; transport.on("connected", (peer) => { this[_private.onPeerConnected](peer, transport.options); }); transport.on("disconnected", (peer, reason) => { this[_private.onPeerDisconnected](peer, reason); }); let result = transport.listen(); if (scheme == "http") { this[_private.httpServer] = transport.server; } return result; } connect(scheme, ip, port, options) { return new Promise((resolve, reject) => { this._started = true; options = Object.assign(options || {}, { ip, port }); let transport = this[_private.findTransport](scheme); transport = new transport("client", options); transport.on("connected", (peer) => { this[_private.transports][transport.id] = transport; this[_private.onPeerConnected](peer, transport.options, resolve); debug("Transports Added", transport.id, Object.keys(this[_private.transports]).length); }); transport.on("disconnected", (peer, reason) => { this[_private.transports][transport.id].stop(); delete this[_private.transports][transport.id]; this[_private.onPeerDisconnected](peer, reason); debug("Transports left", transport.id, Object.keys(this[_private.transports]).length); if (!this[_private.peers][peer.id]) { reject(reason); } }); transport.connect().catch(reject); }); } stop() { this._started = false; return new Promise((resolve, reject) => { const promises = []; for (let id in this[_private.transports]) { promises.push(this[_private.transports][id].stop()); } Promise.all(promises).then(() => { this[_private.peersConnected] = {}; this[_private.peers] = {}; this[_private.transports] = {}; resolve(); }).catch((err) => { throw err; }); }); } onAuth(packet) { return true; } authPacket() { return void 0; } [_private.findTransport](scheme) { for (let name in AnySocket4.Transport) { if (!AnySocket4.Transport.hasOwnProperty(name)) continue; if (AnySocket4.Transport[name].scheme() == scheme) { return AnySocket4.Transport[name]; } } throw new Error("Invalid scheme '" + scheme + "'"); } [_private.onPeerConnected](peer, options, resolve) { debug("Peer connected"); if (peer.type == "http") { peer.on("upgrade", (req, socket) => { let httpPeer = new AnyHTTPPeer(req, socket); httpPeer.header("ANYSOCKET-ID", this.id); this.http._processUpgrade(httpPeer); this.emit("http_upgrade", httpPeer, req, socket); }); peer.on("message", (req, res) => { if (req.url == "/@anysocket") { let httpPeer = new AnyHTTPPeer(req, res); httpPeer.body(this[_private.httpBundle]); httpPeer.end(); return; } req.body = ""; req.on("error", (err) => { console.log("Err", err); }).on("data", (chunk) => { req.body += chunk; if (req.body.length > 1e7) req.connection.destroy(); }).on("end", () => { req.body = req.body.toString(); let httpPeer = new AnyHTTPPeer(req, res); httpPeer.header("ANYSOCKET-ID", this.id); this.http._process(httpPeer); this.emit("http", httpPeer, req, res); }); }); return; } const anyprotocol = new AnyProtocol(this, peer, options); this[_private.peersConnected][peer.connectionID] = anyprotocol; anyprotocol.on("forward", this[_private.onForward].bind(this)); anyprotocol.once("ready", (protocol) => { this[_private.onProtocolReady](protocol, resolve); }); } [_private.onForward](peerID, packet) { if (this.id == packet.to) { if (!this[_private.peers][packet.from]) { this[_private.peers][peerID].disconnect("Invalid forward packet! Client doesn't exist!"); return; } this[_private.peers][packet.from]._recvForward(packet); } else if (this.hasDirectPeer(packet.to)) { this[_private.peers][packet.to].forward(packet); } else { console.error("FORWARD ERROR! We do not have the peer", packet.to); } } [_private.onProtocolReady](protocol, resolve) { if (this[_private.peers][protocol.peerID]) { protocol.peerID = null; protocol.disconnect("Duplicated AnySocket ID found!"); return; } debug("Peer ready"); const anypeer = new AnyPeer(protocol); this[_private.peers][protocol.peerID] = anypeer; anypeer.on("message", (packet) => { this.emit("message", packet); }); anypeer.on("e2e", (peer) => { this.emit("e2e", peer); }); anypeer.on("internal", this[_private.onPeerInternalMessage].bind(this)); if (resolve) { resolve(anypeer); } setTimeout(() => { this.emit("connected", anypeer); }, 0); return anypeer; } [_private.onPeerDisconnected](peer, reason) { debug("Peer disconnected", reason, peer.id); let anypeerID = null; if (this[_private.peersConnected][peer.connectionID]) { anypeerID = this[_private.peersConnected][peer.connectionID].peerID; delete this[_private.peersConnected][peer.connectionID]; } if (this[_private.peers][peer.id]) { anypeerID = peer.id; } if (anypeerID) { const anypeer = this[_private.peers][anypeerID]; delete this[_private.peers][anypeerID]; const links = anypeer.getLinks(); for (let peerID in links) { links[peerID].sendInternal({ type: constants.INTERNAL_PACKET_TYPE.NETWORK, action: "disconnected", id: anypeer.id }).catch(() => { }); anypeer.removeLink(links[peerID]); if (this[_private.peers][peerID]) { this[_private.peers][peerID].removeLink(anypeer); } } anypeer.disconnect(); this.emit("disconnected", anypeer, reason); } else { peer.disconnect(); } } [_private.onPeerInternalMessage](packet) { if (packet.msg.type == constants.INTERNAL_PACKET_TYPE.NETWORK) { if (packet.msg.action == "connected") { if (!this[_private.peers][packet.msg.id]) { let protocol = new AnyProtocol(this, new ProxyPeer(false, this.id, packet.msg.id, this[_private.peers][packet.peer.id])); this[_private.onProtocolReady](protocol); } } else if (packet.msg.action == "disconnected") { if (!this[_private.peers][packet.msg.id]) { packet.peer.disconnect("Invalid proxy request!"); return; } this[_private.onPeerDisconnected](this[_private.peers][packet.msg.id], "Proxy Connection Closed"); } } else if (packet.msg.type == constants.INTERNAL_PACKET_TYPE.PROXY) { if (packet.msg.action == "proxy") { if (!this.canProxy(packet.peer.id, packet.msg.id) || !this[_private.peers][packet.msg.id]) { packet.peer.disconnect("Invalid proxy request!"); return; } if (this[_private.peers][packet.msg.id].isProxy()) { packet.reply({ ok: false }); return; } this[_private.peers][packet.msg.id].addLink(this[_private.peers][packet.peer.id]); this[_private.peers][packet.peer.id].addLink(this[_private.peers][packet.msg.id]); this[_private.peers][packet.msg.id].sendInternal({ type: constants.INTERNAL_PACKET_TYPE.NETWORK, action: "connected", id: packet.peer.id }); packet.reply({ ok: true }); } else if (packet.msg.action == "unproxy") { if (!this.canProxy(packet.peer.id, packet.msg.id) || !this[_private.peers][packet.msg.id]) { packet.peer.disconnect("Invalid proxy request!"); return; } this[_private.peers][packet.msg.id].removeLink(this[_private.peers][packet.peer.id]); this[_private.peers][packet.peer.id].removeLink(this[_private.peers][packet.msg.id]); this[_private.peers][packet.msg.id].sendInternal({ type: constants.INTERNAL_PACKET_TYPE.NETWORK, action: "disconnected", id: packet.peer.id }); } } else if (packet.msg.type == constants.INTERNAL_PACKET_TYPE.RPC) { let parent = false; let tmp = this.rpc; for (let key in packet.msg.method) { parent = tmp; tmp = tmp[packet.msg.method[key]]; if (!tmp) break; } if (!parent || !tmp || typeof tmp != "function") { packet.reply({ error: "Method not found!", details: "method: '" + packet.msg.method + "'", code: 404 }); } else { try { for (let item of packet.msg.bin) { packet.msg.params[item] = AnySocket4.Packer.unpack(packet.msg.params[item]); } Promise.resolve(tmp.apply(parent, [...packet.msg.params, packet.peer])).then((result) => { let binary = false; if (BufferUtils.isBuffer(result)) { result = AnySocket4.Packer.pack(result); binary = true; } packet.reply({ result, bin: binary }); }).catch((e) => { packet.reply({ error: e, details: "method: '" + packet.msg.method + "'", code: 500 }); }); } catch (e) { packet.reply({ error: e.message, details: "method: '" + packet.msg.method + "'", code: 500 }); } } } else if (packet.msg.type == constants.INTERNAL_PACKET_TYPE.RPC_NOTIFY) { console.log("RPC_NOTIFY", packet.msg); } else if (packet.msg.type == constants.INTERNAL_PACKET_TYPE.SYNCED_TIME) { packet.reply({ o: packet.msg.time, t: Date.now() }); } else { packet.peer.disconnect("Invalid internal message"); } } }; module2.exports = AnySocket4; } }); // node_modules/anysocket/src/browser/ws.js var require_ws = __commonJS({ "node_modules/anysocket/src/browser/ws.js"(exports, module2) { module2.exports = class BrowserWS { constructor(...args) { this.ws = new WebSocket(...args); } on(event, fnc) { switch (event) { case "open": this.ws.onopen = fnc; break; case "error": this.ws.onerror = fnc; break; case "message": this.ws.onmessage = (packet) => { fnc(packet.data); }; break; case "close": this.ws.onclose = fnc; break; default: throw new Error("Not implemented in browser! (" + event + ")"); } } send(...args) { this.ws.send(args); } close() { this.ws.close(); } terminate() { } }; } }); // node_modules/ws/browser.js var require_browser2 = __commonJS({ "node_modules/ws/browser.js"(exports, module2) { "use strict"; module2.exports = function() { throw new Error("ws does not work in the browser. Browser clients must use the native WebSocket object"); }; } }); // node_modules/anysocket/src/modules/transports/ws/peer.js var require_peer = __commonJS({ "node_modules/anysocket/src/modules/transports/ws/peer.js"(exports, module2) { var AbstractPeer = require_AbstractPeer(); module2.exports = class WSPeer extends AbstractPeer { onConnect() { this.socket.on("close", () => { this.disconnect("Remote Connection Closed"); }); this.socket.on("error", (err) => { this.emit("error", this, err); }); this.socket.on("message", (message) => { this.emit("message", this, message); }); } send(message) { return new Promise((resolve, reject) => { try { this.socket.send(message); resolve(); } catch (e) { reject(e); } }); } onDisconnect() { if (this.socket) { this.socket.close(); this.socket.terminate(); this.socket = null; } } }; } }); // node_modules/anysocket/src/modules/transports/ws/transport.js var require_transport = __commonJS({ "node_modules/anysocket/src/modules/transports/ws/transport.js"(exports, module2) { var WebSocket2; if (typeof window !== "undefined" && typeof window.document !== "undefined") { WebSocket2 = require_ws(); } else { WebSocket2 = require_browser2(); } var AbstractTransport = require_AbstractTransport(); var Peer = require_peer(); var WS = class extends AbstractTransport { constructor(type, options) { super(type, options); } static scheme() { return "ws"; } onListen() { return new Promise((resolve, reject) => { this.ws = new WebSocket2.Server({ server: this.options.server }); this.ws.on("connection", (socket) => { this.addPeer(new Peer(socket)); }); this.ws.on("error", (err) => { reject(err); }); this.ws.on("listening", () => { resolve(); }); }); } onConnect(plain) { return new Promise((resolve, reject) => { let connected = false; let opts = null; if (this.options.cookies) { opts = { headers: { Cookie: this._formatCookies(this.options.cookies) } }; } let ws = new WebSocket2((plain ? "ws" : "wss") + "://" + this.options.ip + ":" + this.options.port + "/", opts); ws.on("open", (socket) => { connected = true; this.addPeer(new Peer(ws)); resolve(); }); ws.on("error", (err) => { if (!plain && !connected) { this.onConnect(true).then(resolve).catch(reject); } else { reject(err); } connected = false; }); }); } onStop() { return new Promise((resolve, reject) => { if (this.ws) { this.ws.close(); this.ws = null; } resolve(); }); } _formatCookies(cookies) { let cookieString = []; for (let key in cookies) { cookieString.push(key + "=" + cookies[key]); } return cookieString.join("; "); } }; module2.exports = WS; } }); // node_modules/anysocket/src/modules/transports/http/peer.js var require_peer2 = __commonJS({ "node_modules/anysocket/src/modules/transports/http/peer.js"(exports, module2) { var AbstractPeer = require_AbstractPeer(); module2.exports = class HTTPPeer extends AbstractPeer { onConnect() { this.socket.connectionID = this.connectionID; this.socket.on("close", () => { this.disconnect("Remote Connection Closed"); }); this.socket.on("error", (err) => { this.disconnect(err); }); } send(message) { return new Promise((resolve, reject) => { try { this.socket.send(message); resolve(); } catch (e) { reject(e); } }); } onDisconnect() { if (this.socket) { this.socket = null; } } }; } }); // node_modules/anysocket/src/modules/transports/http/transport.js var require_transport2 = __commonJS({ "node_modules/anysocket/src/modules/transports/http/transport.js"(exports, module2) { var AbstractTransport = require_AbstractTransport(); var Peer = require_peer2(); var http = require("http"); var https = require("https"); var fs = require("fs"); var HTTP = class extends AbstractTransport { constructor(type, options) { super(type, options); this.type = AbstractTransport.TYPE.HTTP; this.server = null; this.isSecure = false; } static scheme() { return "http"; } _getSocket(req) { let socket = req.socket._parent; if (!socket) { socket = req.socket; } return socket; } _handler(req, res) { this.peers.get(this._getSocket(req).connectionID).emit("message", req, res); } onListen() { return new Promise((resolve, reject) => { if (this.options.cert && this.options.key && fs.existsSync(this.options.cert) && fs.existsSync(this.options.key)) { this.server = https.createServer({ key: fs.readFileSync(this.options.key).toString(), cert: fs.readFileSync(this.options.cert).toString() }, this._handler.bind(this)); this.isSecure = true; this.server.listen(this.options.port || 443, this.options.host || "0.0.0.0", () => { resolve(); }); } else { this.server = http.createServer(this._handler.bind(this)); this.server.listen(this.options.port || 80, this.options.host || "0.0.0.0", () => { resolve(); }); } this.server.on("connection", (socket) => { this.addPeer(new Peer(socket)); }); this.server.on("upgrade", (req, socket) => { this.peers.get(this._getSocket(req).connectionID).emit("upgrade", req, socket); }); this.server.on("error", (err) => { console.log("http err", err); reject(err); }); }); } onConnect() { throw new Error("not implemented!"); } onStop() { return new Promise((resolve) => { if (this.server) { this.server.close(); this.server = null; } resolve(); }); } }; module2.exports = HTTP; } }); // node_modules/anysocket/src/index.js var require_src = __commonJS({ "node_modules/anysocket/src/index.js"(exports, module2) { var AnySocket4 = require_AnySocket(); var AnyPacker = require_AnyPacker(); AnySocket4.Transport = { "WS": require_transport(), "HTTP": require_transport2() }; AnySocket4.Packer = { pack: AnyPacker.packBytes.bind(AnyPacker), unpack: AnyPacker.unpackBytes.bind(AnyPacker) }; module2.exports = AnySocket4; } }); // src/libs/XTimeouts.js var require_XTimeouts = __commonJS({ "src/libs/XTimeouts.js"(exports, module2) { module2.exports = class XTimeouts { constructor() { this.timeouts = {}; this.callbacks = {}; } execute(key) { if (this.callbacks[key]) { this.callbacks[key](); } } executeAll() { for (let key in this.timeouts) { this.execute(key); } } set(key, timeout, callback) { this.clear(key); this.callbacks[key] = () => { this.clear(key); callback(); }; this.timeouts[key] = setTimeout(this.callbacks[key].bind(this), timeout); } clear(key) { clearTimeout(this.timeouts[key]); delete this.timeouts[key]; delete this.callbacks[key]; } clearAll() { for (let key in this.timeouts) { this.clear(key); } } }; } }); // node_modules/ua-parser-js/src/ua-parser.js var require_ua_parser = __commonJS({ "node_modules/ua-parser-js/src/ua-parser.js"(exports, module2) { (function(window2, undefined2) { "use strict"; var LIBVERSION = "1.0.38", EMPTY = "", UNKNOWN = "?", FUNC_TYPE = "function", UNDEF_TYPE = "undefined", OBJ_TYPE = "object", STR_TYPE = "string", MAJOR = "major", MODEL = "model", NAME = "name", TYPE = "type", VENDOR = "vendor", VERSION = "version", ARCHITECTURE = "architecture", CONSOLE = "console", MOBILE = "mobile", TABLET = "tablet", SMARTTV = "smarttv", WEARABLE = "wearable", EMBEDDED = "embedded", UA_MAX_LENGTH = 500; var AMAZON = "Amazon", APPLE = "Apple", ASUS = "ASUS", BLACKBERRY = "BlackBerry", BROWSER = "Browser", CHROME = "Chrome", EDGE = "Edge", FIREFOX = "Firefox", GOOGLE = "Google", HUAWEI = "Huawei", LG = "LG", MICROSOFT = "Microsoft", MOTOROLA = "Motorola", OPERA = "Opera", SAMSUNG = "Samsung", SHARP = "Sharp", SONY = "Sony", XIAOMI = "Xiaomi", ZEBRA = "Zebra", FACEBOOK = "Facebook", CHROMIUM_OS = "Chromium OS", MAC_OS = "Mac OS"; var extend = function(regexes2, extensions) { var mergedRegexes = {}; for (var i in regexes2) { if (extensions[i] && extensions[i].length % 2 === 0) { mergedRegexes[i] = extensions[i].concat(regexes2[i]); } else { mergedRegexes[i] = regexes2[i]; } } return mergedRegexes; }, enumerize = function(arr) { var enums = {}; for (var i = 0; i < arr.length; i++) { enums[arr[i].toUpperCase()] = arr[i]; } return enums; }, has = function(str1, str2) { return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false; }, lowerize = function(str) { return str.toLowerCase(); }, majorize = function(version) { return typeof version === STR_TYPE ? version.replace(/[^\d\.]/g, EMPTY).split(".")[0] : undefined2; }, trim = function(str, len) { if (typeof str === STR_TYPE) { str = str.replace(/^\s\s*/, EMPTY); return typeof len === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH); } }; var rgxMapper = function(ua, arrays) { var i = 0, j, k, p, q, matches, match; while (i < arrays.length && !matches) { var regex = arrays[i], props = arrays[i + 1]; j = k = 0; while (j < regex.length && !matches) { if (!regex[j]) { break; } matches = regex[j++].exec(ua); if (!!matches) { for (p = 0; p < props.length; p++) { match = matches[++k]; q = props[p]; if (typeof q === OBJ_TYPE && q.length > 0) { if (q.length === 2) { if (typeof q[1] == FUNC_TYPE) { this[q[0]] = q[1].call(this, match); } else { this[q[0]] = q[1]; } } else if (q.length === 3) { if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) { this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined2; } else { this[q[0]] = match ? match.replace(q[1], q[2]) : undefined2; } } else if (q.length === 4) { this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined2; } } else { this[q] = match ? match : undefined2; } } } } i += 2; } }, strMapper = function(str, map) { for (var i in map) { if (typeof map[i] === OBJ_TYPE && map[i].length > 0) { for (var j = 0; j < map[i].length; j++) { if (has(map[i][j], str)) { return i === UNKNOWN ? undefined2 : i; } } } else if (has(map[i], str)) { return i === UNKNOWN ? undefined2 : i; } } return str; }; var oldSafariMap = { "1.0": "/8", "1.2": "/1", "1.3": "/3", "2.0": "/412", "2.0.2": "/416", "2.0.3": "/417", "2.0.4": "/419", "?": "/" }, windowsVersionMap = { "ME": "4.90", "NT 3.11": "NT3.51", "NT 4.0": "NT4.0", "2000": "NT 5.0", "XP": ["NT 5.1", "NT 5.2"], "Vista": "NT 6.0", "7": "NT 6.1", "8": "NT 6.2", "8.1": "NT 6.3", "10": ["NT 6.4", "NT 10.0"], "RT": "ARM" }; var regexes = { browser: [ [ /\b(?:crmo|crios)\/([\w\.]+)/i ], [VERSION, [NAME, "Chrome"]], [ /edg(?:e|ios|a)?\/([\w\.]+)/i ], [VERSION, [NAME, "Edge"]], [ /(opera mini)\/([-\w\.]+)/i, /(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i, /(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i ], [NAME, VERSION], [ /opios[\/ ]+([\w\.]+)/i ], [VERSION, [NAME, OPERA + " Mini"]], [ /\bop(?:rg)?x\/([\w\.]+)/i ], [VERSION, [NAME, OPERA + " GX"]], [ /\bopr\/([\w\.]+)/i ], [VERSION, [NAME, OPERA]], [ /\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i ], [VERSION, [NAME, "Baidu"]], [ /(kindle)\/([\w\.]+)/i, /(lunascape|maxthon|netfront|jasmine|blazer)[\/ ]?([\w\.]*)/i, /(avant|iemobile|slim)\s?(?:browser)?[\/ ]?([\w\.]*)/i, /(?:ms|\()(ie) ([\w\.]+)/i, /(flock|rockmelt|midori|epiphany|silk|skyfire|bolt|iron|vivaldi|iridium|phantomjs|bowser|quark|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|qq|duckduckgo)\/([-\w\.]+)/i, /(heytap|ovi)browser\/([\d\.]+)/i, /(weibo)__([\d\.]+)/i ], [NAME, VERSION], [ /\bddg\/([\w\.]+)/i ], [VERSION, [NAME, "DuckDuckGo"]], [ /(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i ], [VERSION, [NAME, "UC" + BROWSER]], [ /microm.+\bqbcore\/([\w\.]+)/i, /\bqbcore\/([\w\.]+).+microm/i, /micromessenger\/([\w\.]+)/i ], [VERSION, [NAME, "WeChat"]], [ /konqueror\/([\w\.]+)/i ], [VERSION, [NAME, "Konqueror"]], [ /trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i ], [VERSION, [NAME, "IE"]], [ /ya(?:search)?browser\/([\w\.]+)/i ], [VERSION, [NAME, "Yandex"]], [ /slbrowser\/([\w\.]+)/i ], [VERSION, [NAME, "Smart Lenovo " + BROWSER]], [ /(avast|avg)\/([\w\.]+)/i ], [[NAME, /(.+)/, "$1 Secure " + BROWSER], VERSION], [ /\bfocus\/([\w\.]+)/i ], [VERSION, [NAME, FIREFOX + " Focus"]], [ /\bopt\/([\w\.]+)/i ], [VERSION, [NAME, OPERA + " Touch"]], [ /coc_coc\w+\/([\w\.]+)/i ], [VERSION, [NAME, "Coc Coc"]], [ /dolfin\/([\w\.]+)/i ], [VERSION, [NAME, "Dolphin"]], [ /coast\/([\w\.]+)/i ], [VERSION, [NAME, OPERA + " Coast"]], [ /miuibrowser\/([\w\.]+)/i ], [VERSION, [NAME, "MIUI " + BROWSER]], [ /fxios\/([-\w\.]+)/i ], [VERSION, [NAME, FIREFOX]], [ /\bqihu|(qi?ho?o?|360)browser/i ], [[NAME, "360 " + BROWSER]], [ /(oculus|sailfish|huawei|vivo)browser\/([\w\.]+)/i ], [[NAME, /(.+)/, "$1 " + BROWSER], VERSION], [ /samsungbrowser\/([\w\.]+)/i ], [VERSION, [NAME, SAMSUNG + " Internet"]], [ /(comodo_dragon)\/([\w\.]+)/i ], [[NAME, /_/g, " "], VERSION], [ /metasr[\/ ]?([\d\.]+)/i ], [VERSION, [NAME, "Sogou Explorer"]], [ /(sogou)mo\w+\/([\d\.]+)/i ], [[NAME, "Sogou Mobile"], VERSION], [ /(electron)\/([\w\.]+) safari/i, /(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i, /m?(qqbrowser|2345Explorer)[\/ ]?([\w\.]+)/i ], [NAME, VERSION], [ /(lbbrowser)/i, /\[(linkedin)app\]/i ], [NAME], [ /((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i ], [[NAME, FACEBOOK], VERSION], [ /(Klarna)\/([\w\.]+)/i, /(kakao(?:talk|story))[\/ ]([\w\.]+)/i, /(naver)\(.*?(\d+\.[\w\.]+).*\)/i, /safari (line)\/([\w\.]+)/i, /\b(line)\/([\w\.]+)\/iab/i, /(alipay)client\/([\w\.]+)/i, /(twitter)(?:and| f.+e\/([\w\.]+))/i, /(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i ], [NAME, VERSION], [ /\bgsa\/([\w\.]+) .*safari\//i ], [VERSION, [NAME, "GSA"]], [ /musical_ly(?:.+app_?version\/|_)([\w\.]+)/i ], [VERSION, [NAME, "TikTok"]], [ /headlesschrome(?:\/([\w\.]+)| )/i ], [VERSION, [NAME, CHROME + " Headless"]], [ / wv\).+(chrome)\/([\w\.]+)/i ], [[NAME, CHROME + " WebView"], VERSION], [ /droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i ], [VERSION, [NAME, "Android " + BROWSER]], [ /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i ], [NAME, VERSION], [ /version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i ], [VERSION, [NAME, "Mobile Safari"]], [ /version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i ], [VERSION, NAME], [ /webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i ], [NAME, [VERSION, strMapper, oldSafariMap]], [ /(webkit|khtml)\/([\w\.]+)/i ], [NAME, VERSION], [ /(navigator|netscape\d?)\/([-\w\.]+)/i ], [[NAME, "Netscape"], VERSION], [ /mobile vr; rv:([\w\.]+)\).+firefox/i ], [VERSION, [NAME, FIREFOX + " Reality"]], [ /ekiohf.+(flow)\/([\w\.]+)/i, /(swiftfox)/i, /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror|klar)[\/ ]?([\w\.\+]+)/i, /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i, /(firefox)\/([\w\.]+)/i, /(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i, /(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf|sleipnir|obigo|mosaic|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i, /(links) \(([\w\.]+)/i, /panasonic;(viera)/i ], [NAME, VERSION], [ /(cobalt)\/([\w\.]+)/i ], [NAME, [VERSION, /master.|lts./, ""]] ], cpu: [ [ /(?:(amd|x(?:(?:86|64)[-_])?|wow|win)64)[;\)]/i ], [[ARCHITECTURE, "amd64"]], [ /(ia32(?=;))/i ], [[ARCHITECTURE, lowerize]], [ /((?:i[346]|x)86)[;\)]/i ], [[ARCHITECTURE, "ia32"]], [ /\b(aarch64|arm(v?8e?l?|_?64))\b/i ], [[ARCHITECTURE, "arm64"]], [ /\b(arm(?:v[67])?ht?n?[fl]p?)\b/i ], [[ARCHITECTURE, "armhf"]], [ /windows (ce|mobile); ppc;/i ], [[ARCHITECTURE, "arm"]], [ /((?:ppc|powerpc)(?:64)?)(?: mac|;|\))/i ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [ /(sun4\w)[;\)]/i ], [[ARCHITECTURE, "sparc"]], [ /((?:avr32|ia64(?=;))|68k(?=\))|\barm(?=v(?:[1-7]|[5-7]1)l?|;|eabi)|(?=atmel )avr|(?:irix|mips|sparc)(?:64)?\b|pa-risc)/i ], [[ARCHITECTURE, lowerize]] ], device: [ [ /\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [ /\b((?:s[cgp]h|gt|sm)-\w+|sc[g-]?[\d]+a?|galaxy nexus)/i, /samsung[- ]([-\w]+)/i, /sec-(sgh\w+)/i ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [ /(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [ /\((ipad);[-\w\),; ]+apple/i, /applecoremedia\/[\w\.]+ \((ipad)/i, /\b(ipad)\d\d?,\d\d?[;\]].+ios/i ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [ /(macintosh);/i ], [MODEL, [VENDOR, APPLE]], [ /\b(sh-?[altvz]?\d\d[a-ekm]?)/i ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [ /\b((?:ag[rs][23]?|bah2?|sht?|btv)-a?[lw]\d{2})\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [ /(?:huawei|honor)([-\w ]+)[;\)]/i, /\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [ /\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i, /\b; (\w+) build\/hm\1/i, /\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i, /\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i, /oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i, /\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite)?)(?: bui|\))/i ], [[MODEL, /_/g, " "], [VENDOR, XIAOMI], [TYPE, MOBILE]], [ /oid[^\)]+; (2\d{4}(283|rpbf)[cgl])( bui|\))/i, /\b(mi[-_ ]?(?:pad)(?:[\w_ ]+))(?: bui|\))/i ], [[MODEL, /_/g, " "], [VENDOR, XIAOMI], [TYPE, TABLET]], [ /; (\w+) bui.+ oppo/i, /\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i ], [MODEL, [VENDOR, "OPPO"], [TYPE, MOBILE]], [ /\b(opd2\d{3}a?) bui/i ], [MODEL, [VENDOR, "OPPO"], [TYPE, TABLET]], [ /vivo (\w+)(?: bui|\))/i, /\b(v[12]\d{3}\w?[at])(?: bui|;)/i ], [MODEL, [VENDOR, "Vivo"], [TYPE, MOBILE]], [ /\b(rmx[1-3]\d{3})(?: bui|;|\))/i ], [MODEL, [VENDOR, "Realme"], [TYPE, MOBILE]], [ /\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i, /\bmot(?:orola)?[- ](\w*)/i, /((?:moto[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [ /\b(mz60\d|xoom[2 ]{0,2}) build\//i ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [ /((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [ /(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i, /\blg[-e;\/ ]+((?!browser|netcast|android tv)\w+)/i, /\blg-?([\d\w]+) bui/i ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [ /(ideatab[-\w ]+)/i, /lenovo ?(s[56]000[-\w]+|tab(?:[\w ]+)|yt[-\d\w]{6}|tb[-\d\w]{6})/i ], [MODEL, [VENDOR, "Lenovo"], [TYPE, TABLET]], [ /(?:maemo|nokia).*(n900|lumia \d+)/i, /nokia[-_ ]?([-\w\.]*)/i ], [[MODEL, /_/g, " "], [VENDOR, "Nokia"], [TYPE, MOBILE]], [ /(pixel c)\b/i ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [ /droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [ /droid.+ (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [ /sony tablet [ps]/i, /\b(?:sony)?sgp\w+(?: bui|\))/i ], [[MODEL, "Xperia Tablet"], [VENDOR, SONY], [TYPE, TABLET]], [ / (kb2005|in20[12]5|be20[12][59])\b/i, /(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i ], [MODEL, [VENDOR, "OnePlus"], [TYPE, MOBILE]], [ /(alexa)webm/i, /(kf[a-z]{2}wi|aeo[c-r]{2})( bui|\))/i, /(kf[a-z]+)( bui|\)).+silk\//i ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [ /((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i ], [[MODEL, /(.+)/g, "Fire Phone $1"], [VENDOR, AMAZON], [TYPE, MOBILE]], [ /(playbook);[-\w\),; ]+(rim)/i ], [MODEL, VENDOR, [TYPE, TABLET]], [ /\b((?:bb[a-f]|st[hv])100-\d)/i, /\(bb10; (\w+)/i ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [ /(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [ / (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [ /(nexus 9)/i ], [MODEL, [VENDOR, "HTC"], [TYPE, TABLET]], [ /(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i, /(zte)[- ]([\w ]+?)(?: bui|\/|\))/i, /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i ], [VENDOR, [MODEL, /_/g, " "], [TYPE, MOBILE]], [ /droid.+; ([ab][1-7]-?[0178a]\d\d?)/i ], [MODEL, [VENDOR, "Acer"], [TYPE, TABLET]], [ /droid.+; (m[1-5] note) bui/i, /\bmz-([-\w]{2,})/i ], [MODEL, [VENDOR, "Meizu"], [TYPE, MOBILE]], [ /; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i ], [MODEL, [VENDOR, "Ulefone"], [TYPE, MOBILE]], [ /(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus|dell|meizu|motorola|polytron|infinix|tecno)[-_ ]?([-\w]*)/i, /(hp) ([\w ]+\w)/i, /(asus)-?(\w+)/i, /(microsoft); (lumia[\w ]+)/i, /(lenovo)[-_ ]?([-\w]+)/i, /(jolla)/i, /(oppo) ?([\w ]+) bui/i ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kobo)\s(ereader|touch)/i, /(archos) (gamepad2?)/i, /(hp).+(touchpad(?!.+tablet)|tablet)/i, /(kindle)\/([\w\.]+)/i, /(nook)[\w ]+build\/(\w+)/i, /(dell) (strea[kpr\d ]*[\dko])/i, /(le[- ]+pan)[- ]+(\w{1,9}) bui/i, /(trinity)[- ]*(t\d{3}) bui/i, /(gigaset)[- ]+(q\w{1,9}) bui/i, /(vodafone) ([\w ]+)(?:\)| bui)/i ], [VENDOR, MODEL, [TYPE, TABLET]], [ /(surface duo)/i ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [ /droid [\d\.]+; (fp\du?)(?: b|\))/i ], [MODEL, [VENDOR, "Fairphone"], [TYPE, MOBILE]], [ /(u304aa)/i ], [MODEL, [VENDOR, "AT&T"], [TYPE, MOBILE]], [ /\bsie-(\w*)/i ], [MODEL, [VENDOR, "Siemens"], [TYPE, MOBILE]], [ /\b(rct\w+) b/i ], [MODEL, [VENDOR, "RCA"], [TYPE, TABLET]], [ /\b(venue[\d ]{2,7}) b/i ], [MODEL, [VENDOR, "Dell"], [TYPE, TABLET]], [ /\b(q(?:mv|ta)\w+) b/i ], [MODEL, [VENDOR, "Verizon"], [TYPE, TABLET]], [ /\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i ], [MODEL, [VENDOR, "Barnes & Noble"], [TYPE, TABLET]], [ /\b(tm\d{3}\w+) b/i ], [MODEL, [VENDOR, "NuVision"], [TYPE, TABLET]], [ /\b(k88) b/i ], [MODEL, [VENDOR, "ZTE"], [TYPE, TABLET]], [ /\b(nx\d{3}j) b/i ], [MODEL, [VENDOR, "ZTE"], [TYPE, MOBILE]], [ /\b(gen\d{3}) b.+49h/i ], [MODEL, [VENDOR, "Swiss"], [TYPE, MOBILE]], [ /\b(zur\d{3}) b/i ], [MODEL, [VENDOR, "Swiss"], [TYPE, TABLET]], [ /\b((zeki)?tb.*\b) b/i ], [MODEL, [VENDOR, "Zeki"], [TYPE, TABLET]], [ /\b([yr]\d{2}) b/i, /\b(dragon[- ]+touch |dt)(\w{5}) b/i ], [[VENDOR, "Dragon Touch"], MODEL, [TYPE, TABLET]], [ /\b(ns-?\w{0,9}) b/i ], [MODEL, [VENDOR, "Insignia"], [TYPE, TABLET]], [ /\b((nxa|next)-?\w{0,9}) b/i ], [MODEL, [VENDOR, "NextBook"], [TYPE, TABLET]], [ /\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i ], [[VENDOR, "Voice"], MODEL, [TYPE, MOBILE]], [ /\b(lvtel\-)?(v1[12]) b/i ], [[VENDOR, "LvTel"], MODEL, [TYPE, MOBILE]], [ /\b(ph-1) /i ], [MODEL, [VENDOR, "Essential"], [TYPE, MOBILE]], [ /\b(v(100md|700na|7011|917g).*\b) b/i ], [MODEL, [VENDOR, "Envizen"], [TYPE, TABLET]], [ /\b(trio[-\w\. ]+) b/i ], [MODEL, [VENDOR, "MachSpeed"], [TYPE, TABLET]], [ /\btu_(1491) b/i ], [MODEL, [VENDOR, "Rotor"], [TYPE, TABLET]], [ /(shield[\w ]+) b/i ], [MODEL, [VENDOR, "Nvidia"], [TYPE, TABLET]], [ /(sprint) (\w+)/i ], [VENDOR, MODEL, [TYPE, MOBILE]], [ /(kin\.[onetw]{3})/i ], [[MODEL, /\./g, " "], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [ /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [ /droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [ /smart-tv.+(samsung)/i ], [VENDOR, [TYPE, SMARTTV]], [ /hbbtv.+maple;(\d+)/i ], [[MODEL, /^/, "SmartTV"], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [ /(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i ], [[VENDOR, LG], [TYPE, SMARTTV]], [ /(apple) ?tv/i ], [VENDOR, [MODEL, APPLE + " TV"], [TYPE, SMARTTV]], [ /crkey/i ], [[MODEL, CHROME + "cast"], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [ /droid.+aft(\w+)( bui|\))/i ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [ /\(dtv[\);].+(aquos)/i, /(aquos-tv[\w ]+)\)/i ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]], [ /(bravia[\w ]+)( bui|\))/i ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [ /(mitv-\w{5}) bui/i ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [ /Hbbtv.*(technisat) (.*);/i ], [VENDOR, MODEL, [TYPE, SMARTTV]], [ /\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i, /hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [ /\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i ], [[TYPE, SMARTTV]], [ /(ouya)/i, /(nintendo) ([wids3utch]+)/i ], [VENDOR, MODEL, [TYPE, CONSOLE]], [ /droid.+; (shield) bui/i ], [MODEL, [VENDOR, "Nvidia"], [TYPE, CONSOLE]], [ /(playstation [345portablevi]+)/i ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [ /\b(xbox(?: one)?(?!; xbox))[\); ]/i ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [ /((pebble))app/i ], [VENDOR, MODEL, [TYPE, WEARABLE]], [ /(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [ /droid.+; (glass) \d/i ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [ /droid.+; (wt63?0{2,3})\)/i ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [ /(quest( \d| pro)?)/i ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [ /(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i ], [VENDOR, [TYPE, EMBEDDED]], [ /(aeobc)\b/i ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [ /droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i ], [MODEL, [TYPE, MOBILE]], [ /droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i ], [MODEL, [TYPE, TABLET]], [ /\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i ], [[TYPE, TABLET]], [ /(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i ], [[TYPE, MOBILE]], [ /(android[-\w\. ]{0,9});.+buil/i ], [MODEL, [VENDOR, "Generic"]] ], engine: [ [ /windows.+ edge\/([\w\.]+)/i ], [VERSION, [NAME, EDGE + "HTML"]], [ /webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i ], [VERSION, [NAME, "Blink"]], [ /(presto)\/([\w\.]+)/i, /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna)\/([\w\.]+)/i, /ekioh(flow)\/([\w\.]+)/i, /(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i, /(icab)[\/ ]([23]\.[\d\.]+)/i, /\b(libweb)/i ], [NAME, VERSION], [ /rv\:([\w\.]{1,9})\b.+(gecko)/i ], [VERSION, NAME] ], os: [ [ /microsoft (windows) (vista|xp)/i ], [NAME, VERSION], [ /(windows (?:phone(?: os)?|mobile))[\/ ]?([\d\.\w ]*)/i ], [NAME, [VERSION, strMapper, windowsVersionMap]], [ /windows nt 6\.2; (arm)/i, /windows[\/ ]?([ntce\d\. ]+\w)(?!.+xbox)/i, /(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i ], [[VERSION, strMapper, windowsVersionMap], [NAME, "Windows"]], [ /ip[honead]{2,4}\b(?:.*os ([\w]+) like mac|; opera)/i, /(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i, /cfnetwork\/.+darwin/i ], [[VERSION, /_/g, "."], [NAME, "iOS"]], [ /(mac os x) ?([\w\. ]*)/i, /(macintosh|mac_powerpc\b)(?!.+haiku)/i ], [[NAME, MAC_OS], [VERSION, /_/g, "."]], [ /droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i ], [VERSION, NAME], [ /(android|webos|qnx|bada|rim tablet os|maemo|meego|sailfish)[-\/ ]?([\w\.]*)/i, /(blackberry)\w*\/([\w\.]*)/i, /(tizen|kaios)[\/ ]([\w\.]+)/i, /\((series40);/i ], [NAME, VERSION], [ /\(bb(10);/i ], [VERSION, [NAME, BLACKBERRY]], [ /(?:symbian ?os|symbos|s60(?=;)|series60)[-\/ ]?([\w\.]*)/i ], [VERSION, [NAME, "Symbian"]], [ /mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i ], [VERSION, [NAME, FIREFOX + " OS"]], [ /web0s;.+rt(tv)/i, /\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i ], [VERSION, [NAME, "webOS"]], [ /watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i ], [VERSION, [NAME, "watchOS"]], [ /crkey\/([\d\.]+)/i ], [VERSION, [NAME, CHROME + "cast"]], [ /(cros) [\w]+(?:\)| ([\w\.]+)\b)/i ], [[NAME, CHROMIUM_OS], VERSION], [ /panasonic;(viera)/i, /(netrange)mmh/i, /(nettv)\/(\d+\.[\w\.]+)/i, /(nintendo|playstation) ([wids345portablevuch]+)/i, /(xbox); +xbox ([^\);]+)/i, /\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i, /(mint)[\/\(\) ]?(\w*)/i, /(mageia|vectorlinux)[; ]/i, /([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i, /(hurd|linux) ?([\w\.]*)/i, /(gnu) ?([\w\.]*)/i, /\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i, /(haiku) (\w+)/i ], [NAME, VERSION], [ /(sunos) ?([\w\.\d]*)/i ], [[NAME, "Solaris"], VERSION], [ /((?:open)?solaris)[-\/ ]?([\w\.]*)/i, /(aix) ((\d)(?=\.|\)| )[\w\.])*/i, /\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i, /(unix) ?([\w\.]*)/i ], [NAME, VERSION] ] }; var UAParser2 = function(ua, extensions) { if (typeof ua === OBJ_TYPE) { extensions = ua; ua = undefined2; } if (!(this instanceof UAParser2)) { return new UAParser2(ua, extensions).getResult(); } var _navigator = typeof window2 !== UNDEF_TYPE && window2.navigator ? window2.navigator : undefined2; var _ua = ua || (_navigator && _navigator.userAgent ? _navigator.userAgent : EMPTY); var _uach = _navigator && _navigator.userAgentData ? _navigator.userAgentData : undefined2; var _rgxmap = extensions ? extend(regexes, extensions) : regexes; var _isSelfNav = _navigator && _navigator.userAgent == _ua; this.getBrowser = function() { var _browser = {}; _browser[NAME] = undefined2; _browser[VERSION] = undefined2; rgxMapper.call(_browser, _ua, _rgxmap.browser); _browser[MAJOR] = majorize(_browser[VERSION]); if (_isSelfNav && _navigator && _navigator.brave && typeof _navigator.brave.isBrave == FUNC_TYPE) { _browser[NAME] = "Brave"; } return _browser; }; this.getCPU = function() { var _cpu = {}; _cpu[ARCHITECTURE] = undefined2; rgxMapper.call(_cpu, _ua, _rgxmap.cpu); return _cpu; }; this.getDevice = function() { var _device = {}; _device[VENDOR] = undefined2; _device[MODEL] = undefined2; _device[TYPE] = undefined2; rgxMapper.call(_device, _ua, _rgxmap.device); if (_isSelfNav && !_device[TYPE] && _uach && _uach.mobile) { _device[TYPE] = MOBILE; } if (_isSelfNav && _device[MODEL] == "Macintosh" && _navigator && typeof _navigator.standalone !== UNDEF_TYPE && _navigator.maxTouchPoints && _navigator.maxTouchPoints > 2) { _device[MODEL] = "iPad"; _device[TYPE] = TABLET; } return _device; }; this.getEngine = function() { var _engine = {}; _engine[NAME] = undefined2; _engine[VERSION] = undefined2; rgxMapper.call(_engine, _ua, _rgxmap.engine); return _engine; }; this.getOS = function() { var _os = {}; _os[NAME] = undefined2; _os[VERSION] = undefined2; rgxMapper.call(_os, _ua, _rgxmap.os); if (_isSelfNav && !_os[NAME] && _uach && _uach.platform && _uach.platform != "Unknown") { _os[NAME] = _uach.platform.replace(/chrome os/i, CHROMIUM_OS).replace(/macos/i, MAC_OS); } return _os; }; this.getResult = function() { return { ua: this.getUA(), browser: this.getBrowser(), engine: this.getEngine(), os: this.getOS(), device: this.getDevice(), cpu: this.getCPU() }; }; this.getUA = function() { return _ua; }; this.setUA = function(ua2) { _ua = typeof ua2 === STR_TYPE && ua2.length > UA_MAX_LENGTH ? trim(ua2, UA_MAX_LENGTH) : ua2; return this; }; this.setUA(_ua); return this; }; UAParser2.VERSION = LIBVERSION; UAParser2.BROWSER = enumerize([NAME, VERSION, MAJOR]); UAParser2.CPU = enumerize([ARCHITECTURE]); UAParser2.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]); UAParser2.ENGINE = UAParser2.OS = enumerize([NAME, VERSION]); if (typeof exports !== UNDEF_TYPE) { if (typeof module2 !== UNDEF_TYPE && module2.exports) { exports = module2.exports = UAParser2; } exports.UAParser = UAParser2; } else { if (typeof define === FUNC_TYPE && define.amd) { define(function() { return UAParser2; }); } else if (typeof window2 !== UNDEF_TYPE) { window2.UAParser = UAParser2; } } var $ = typeof window2 !== UNDEF_TYPE && (window2.jQuery || window2.Zepto); if ($ && !$.ua) { var parser = new UAParser2(); $.ua = parser.getResult(); $.ua.get = function() { return parser.getUA(); }; $.ua.set = function(ua) { parser.setUA(ua); var result = parser.getResult(); for (var prop in result) { $.ua[prop] = result[prop]; } }; } })(typeof window === "object" ? window : exports); } }); // src/main.ts var main_exports = {}; __export(main_exports, { default: () => AnySocketSyncPlugin }); module.exports = __toCommonJS(main_exports); var import_obsidian6 = require("obsidian"); // src/XSync.ts var import_obsidian3 = require("obsidian"); // src/libs/Utils.ts var Utils_default = new class Utils { constructor() { this.binaryExtensions = [ "3dm", "3ds", "3g2", "3gp", "7z", "a", "aac", "adp", "afdesign", "afphoto", "afpub", "ai", "aif", "aiff", "alz", "ape", "apk", "appimage", "ar", "arj", "asf", "au", "avi", "bak", "baml", "bh", "bin", "bk", "bmp", "btif", "bz2", "bzip2", "cab", "caf", "cgm", "class", "cmx", "cpio", "cr2", "cur", "dat", "dcm", "deb", "dex", "djvu", "dll", "dmg", "dng", "doc", "docm", "docx", "dot", "dotm", "dra", "DS_Store", "dsk", "dts", "dtshd", "dvb", "dwg", "dxf", "ecelp4800", "ecelp7470", "ecelp9600", "egg", "eol", "eot", "epub", "exe", "f4v", "fbs", "fh", "fla", "flac", "flatpak", "fli", "flv", "fpx", "fst", "fvt", "g3", "gh", "gif", "graffle", "gz", "gzip", "h261", "h263", "h264", "icns", "ico", "ief", "img", "ipa", "iso", "jar", "jpeg", "jpg", "jpgv", "jpm", "jxr", "key", "ktx", "lha", "lib", "lvp", "lz", "lzh", "lzma", "lzo", "m3u", "m4a", "m4v", "mar", "mdi", "mht", "mid", "midi", "mj2", "mka", "mkv", "mmr", "mng", "mobi", "mov", "movie", "mp3", "mp4", "mp4a", "mpeg", "mpg", "mpga", "mxu", "nef", "npx", "numbers", "nupkg", "o", "odp", "ods", "odt", "oga", "ogg", "ogv", "otf", "ott", "pages", "pbm", "pcx", "pdb", "pdf", "pea", "pgm", "pic", "png", "pnm", "pot", "potm", "potx", "ppa", "ppam", "ppm", "pps", "ppsm", "ppsx", "ppt", "pptm", "pptx", "psd", "pya", "pyc", "pyo", "pyv", "qt", "rar", "ras", "raw", "resources", "rgb", "rip", "rlc", "rmf", "rmvb", "rpm", "rtf", "rz", "s3m", "s7z", "scpt", "sgi", "shar", "snap", "sil", "sketch", "slk", "smv", "snk", "so", "stl", "suo", "sub", "swf", "tar", "tbz", "tbz2", "tga", "tgz", "thmx", "tif", "tiff", "tlz", "ttc", "ttf", "txz", "udf", "uvh", "uvi", "uvm", "uvp", "uvs", "uvu", "viv", "vob", "war", "wav", "wax", "wbmp", "wdp", "weba", "webm", "webp", "whl", "wim", "wm", "wma", "wmv", "wmx", "woff", "woff2", "wrm", "wvx", "xbm", "xif", "xla", "xlam", "xls", "xlsb", "xlsm", "xlsx", "xlt", "xltm", "xltx", "xm", "xmind", "xpi", "xpm", "xwd", "xz", "z", "zip", "zipx" ]; } debounce(func, delay) { let timeout = null; return () => { if (timeout) clearTimeout(timeout); timeout = window.setTimeout(() => { func(); }, delay); }; } async getSHA(data) { if (!data) return null; let sha = await crypto.subtle.digest("SHA-256", new TextEncoder("utf-8").encode(data)); return Array.prototype.map.call(new Uint8Array(sha), (x) => ("00" + x.toString(16)).slice(-2)).join(""); } async getSHABinary(data) { if (!data) return null; let sha = await crypto.subtle.digest("SHA-256", data); return Array.prototype.map.call(new Uint8Array(sha), (x) => ("00" + x.toString(16)).slice(-2)).join(""); } isBinary(path) { path = path.split("."); let extension = path[path.length - 1]; return this.binaryExtensions.indexOf(extension) !== -1; } }(); // src/libs/AnysocketManager.ts var import_Events = __toESM(require_Events()); var import_anysocket = __toESM(require_src()); var NOTICE_COLOR = "#ffaa00"; var AnysocketManager = class extends import_Events.default { constructor(xSync) { super(); this.eventRefs = {}; this.isConnected = false; this.isUpdating = false; this.notifiedOfConnectError = false; this.peer = null; this.xSync = xSync; this.plugin = xSync.plugin; this.anysocket = new import_anysocket.default(); console.log("AnySocket Sync (" + this.plugin.VERSION + ") - Enabled"); if (app.isMobile) { activeWindow.onblur = () => { this.emit("unload"); }; activeWindow.onfocus = () => { this.emit("reload"); }; } } async getTime() { return Date.now(); } async init() { this.anysocket.removeAllListeners(); let password = await Utils_default.getSHA(this.anysocket.id.substring(0, 16) + this.plugin.settings.password + this.anysocket.id.substring(16)); this.anysocket.authPacket = () => { return password; }; this.anysocket.onAuth = async (packet) => { return await Utils_default.getSHA(packet.id.substring(0, 16) + this.plugin.settings.password + packet.id.substring(16)) == packet.auth; }; this.anysocket.on("message", async (packet) => { this.emit("message", packet); }); this.anysocket.on("e2e", async (peer) => { this.getTime = async () => { return Math.round((await peer.getSyncedTime()).time); }; await this.getTime(); app.workspace.onLayoutReady(async () => { await this.checkForUpdates(peer); }); }); this.anysocket.on("disconnected", (peer) => { this.isConnected = false; this.peer = null; this.emit("disconnected"); this.emit("reload"); }); this.connect(); } async checkForUpdates(peer) { this.isUpdating = false; let result = await peer.rpc.onVersionCheck(this.plugin.VERSION, this.plugin.BUILD); if (result.type == "ok") { this.peer = peer; this.isConnected = true; this.isUpdating = false; this.emit("connected", peer); } else if (result.type == "update") { this.isUpdating = true; await this.xSync.storage.updatePlugin(result.files); this.anysocket.removeAllListeners("disconnected"); this.anysocket.stop(); app.plugins.disablePlugin("anysocket-sync"); if (this.plugin.BUILD >= result.build) { this.xSync.makeNotice(NOTICE_COLOR, "Your version is ahead of the server. Downgraded fom " + this.plugin.VERSION + " to " + result.version); } else { this.xSync.makeNotice(NOTICE_COLOR, "Updated to version: " + result.version); } app.plugins.enablePlugin("anysocket-sync"); } else { this.anysocket.removeAllListeners(); this.emit("unload"); this.xSync.makeNotice(NOTICE_COLOR, "Incompatible client version " + this.plugin.VERSION); } } connect() { if (!this.isEnabled) { return; } if (!this.plugin.settings.password) { console.log("AnySocket Sync - Requires setup"); this.xSync.makeNotice(NOTICE_COLOR, "AnySocket Sync - Requires setup"); this.emit("unload"); return; } this.anysocket.connect("ws", this.plugin.settings.host, this.plugin.settings.port).then(async (peer) => { peer.e2e(); this.notifiedOfConnectError = false; }).catch((e) => { console.error("AnySocket Connect Error", e); if (!this.notifiedOfConnectError && !this.isUpdating) { this.notifiedOfConnectError = true; this.xSync.notifyStatus(NotifyType.NOT_CONNECTED); } this.isConnected = false; this.emit("reload"); }); } async send(packet, onReply) { if (!this.peer) return; if (onReply) { packet = await this.peer.send(packet, true); onReply(packet); } else { return await this.peer.send(packet); } } stop() { this.anysocket.stop(); } }; // src/libs/fs/FSAdapter.ts var import_obsidian = require("obsidian"); var FSAdapter = class { constructor(basePath) { this.basePath = basePath; } async makeFolder(path) { await app.vault.createFolder((0, import_obsidian.normalizePath)(this.basePath + path)).catch(() => { }); } async write(path, data, mtime, binary = false) { if (!await this.exists(path)) { let folder = path.split("/").slice(0, -1).join("/"); if (folder) { await this.makeFolder(folder); } } if (data != null) { let options = null; if (mtime) { options = { mtime }; } if (binary) { await app.vault.adapter.writeBinary((0, import_obsidian.normalizePath)(this.basePath + path), data, options); } else { await app.vault.adapter.write((0, import_obsidian.normalizePath)(this.basePath + path), data, options); } } return data; } async read(path, binary = false) { try { if (binary) { return await app.vault.adapter.readBinary((0, import_obsidian.normalizePath)(this.basePath + path)); } return await app.vault.adapter.read((0, import_obsidian.normalizePath)(this.basePath + path)); } catch (e) { return null; } } async exists(path) { return await app.vault.adapter.exists((0, import_obsidian.normalizePath)(this.basePath + path)); } async delete(path) { await app.fileManager.trashFile(this.getFile(path)); } async iterate(callback) { let files = app.vault.getAllLoadedFiles(); for (let file of files) { await callback(file); } } getFile(path) { return app.vault.getAbstractFileByPath((0, import_obsidian.normalizePath)(path)); } }; // src/libs/fs/Storage.ts var import_obsidian2 = require("obsidian"); var Storage = class { constructor(plugin) { this.inited = false; this.fsVault = new FSAdapter((0, import_obsidian2.normalizePath)("/")); this.fsInternal = new FSAdapter(plugin.manifest.dir + "/"); } async init() { if (this.inited) return; this.tree = {}; this.inited = true; } async write(path, data, metadata) { await this.writeMetadata(path, metadata); return await this.fsVault.write(path, data, metadata.mtime); } async writeBinary(path, data, metadata) { await this.writeMetadata(path, metadata); return await this.fsVault.write(path, data, metadata.mtime, true); } async makeFolder(path, metadata) { await this.writeMetadata(path, metadata); return await this.fsVault.makeFolder(path); } async read(path) { return await this.fsVault.read(path); } async readBinary(path) { return await this.fsVault.read(path, true); } async delete(path, metadata) { await this.writeMetadata(path, metadata); return await this.fsVault.delete(path); } async exists(path) { return await this.fsVault.exists(path); } async iterate(callback) { await this.fsVault.iterate(async (item) => { if (item.path == "/") return; await callback(item); }); } async readMetadata(path) { if (!this.tree[path]) { return null; } return this.tree[path]; } async writeMetadata(path, metadata) { if (!this.tree[path]) { this.tree[path] = {}; } for (let key in metadata) { this.tree[path][key] = metadata[key]; } return this.tree[path]; } async updatePlugin(files) { for (let item of files) { await this.fsInternal.write(item.path, item.data); } } getFileByPath(path) { if (path.substring(0, 1) == "/") { path = path.substring(1); } return this.fsVault.getFile(path); } }; Storage.tree = null; // src/XSync.ts var import_AnySocket = __toESM(require_AnySocket()); var import_XTimeouts = __toESM(require_XTimeouts()); var STATUS_OK = "#339933"; var STATUS_SYNC = "#9900ff"; var STATUS_WARN = "#ffaa00"; var STATUS_ERROR = "#cc0000"; var NotifyType = { PLUGIN_DISABLED: "Disabled", NOT_CONNECTED: "Not connected", SYNCING: "Syncing...", SYNC_COMPLETED: "Sync completed", AUTO_SYNC_DISABLED: "Auto Sync disabled", CONNECTION_LOST: "Connection lost", CONNECTED: "Connected" }; var XSync2 = class { constructor(plugin) { this.isEnabled = false; this.eventRefs = {}; this.reloadTimeout = null; this.plugin = plugin; this.unsentSessionEvents = {}; this.anysocket = new AnysocketManager(this); this.storage = new Storage(plugin); this.xTimeouts = new import_XTimeouts.default(); } async enabled(value) { if (this.isEnabled !== value) { this.isEnabled = value; if (this.isEnabled) { await this.load(false); } else { this.unload(false); } } } connectionOK() { if (!this.isEnabled) { this.notifyStatus(NotifyType.PLUGIN_DISABLED); return false; } if (!this.anysocket.isConnected) { this.notifyStatus(NotifyType.NOT_CONNECTED); return false; } return true; } async listVersionHistory(path, callback) { this.anysocket.send({ type: "file_history", data: { type: "list_versions", path } }, (packet) => { callback(packet.msg); }); } async readVersionHistory(path, timestamp, callback) { if (!this.connectionOK()) return; this.anysocket.send({ type: "file_history", data: { type: "read", binary: Utils_default.isBinary(path), path, timestamp } }, (packet) => { callback(packet.msg); }); } async listFilesHistory(deletedOnly, callback) { if (!this.connectionOK()) return; this.anysocket.send({ type: "file_history", data: { type: "list_files", mode: deletedOnly ? "deleted" : "all" } }, (packet) => { callback(packet.msg); }); } async sync() { if (!this.anysocket.isConnected) return; if (this.isSyncing) return; for (let key in this.unsentSessionEvents) { let event = this.unsentSessionEvents[key]; await this.processLocalEvent(event.action, event.file, event.args, true); } this.unsentSessionEvents = {}; this.isSyncing = true; this.notifyStatus(NotifyType.SYNCING); this.debug && console.log("sync"); let data = []; await this.storage.iterate(async (item) => { let mtime = null; if (item.children === void 0) { mtime = item.stat.mtime; } else { mtime = await this.getFolderMtime(item); if (mtime === false) { return; } } let result = await this.getMetadata("sync", item, mtime); data.push({ path: item.path, metadata: result.metadata }); }); this.anysocket.send({ type: "sync", data }); } async onSyncCompleted(peer) { this.isSyncing = false; this.notifyStatus(NotifyType.SYNC_COMPLETED); } async onFocusChanged() { this.xTimeouts.executeAll(); } async processLocalEvent(action, file, args, fromUnsent = false) { if (!this.anysocket.isConnected) { return; } if (!this.plugin.settings.autoSync && !fromUnsent) { this.unsentSessionEvents[file.path] = { action, file, args }; return; } if (action == "rename") { await this.processLocalEvent("delete", { path: args[0] }, null, fromUnsent); await this.processLocalEvent("create", file, null, fromUnsent); return; } let metadata = await this.getMetadata(action, file); if (action == "modify" && this.plugin.settings.delayedSync > 0) { this.xTimeouts.set(file.path, this.plugin.settings.delayedSync * 1e3, async () => { await this._processLocalEvent(action, file, metadata); }); } else { await this._processLocalEvent(action, file, metadata); } } async _processLocalEvent(action, file, metadata) { this.debug && console.log("anysocket sync event", action, file.path, metadata); try { let result = metadata || await this.getMetadata(action, file); if (!result.changed || !this.anysocket.isConnected) { return; } result.metadata.path = file.path; this.anysocket.send({ type: "file_event", data: result.metadata }); } catch (e) { console.error(e); } } registerEvent(type) { this.eventRefs[type] = app.vault.on(type, async (file, ...args) => { if (!this.isEnabled) return; await this.processLocalEvent(type, file, args); }); } unregisterEvent(type) { app.vault.offref(this.eventRefs[type]); } async load() { if (!this.isEnabled) return; if (this.inited == true) return; this.inited = true; this.anysocket.isEnabled = this.plugin.settings.syncEnabled; this.debug = this.plugin.settings.debug; await this.storage.init(); this.registerEvent("create"); this.registerEvent("modify"); this.registerEvent("delete"); this.registerEvent("rename"); let focusChanged = Utils_default.debounce(this.onFocusChanged.bind(this), 500); this.eventRefs["active-leaf-change"] = app.workspace.on("active-leaf-change", focusChanged); this.eventRefs["layout-change"] = app.workspace.on("layout-change", focusChanged); this.anysocket.on("connected", async (peer) => { this.notifyStatus(NotifyType.CONNECTED); let deviceName = this.plugin.settings.deviceName || null; if (deviceName != null && deviceName != "Unknown") { await peer.rpc.setDeviceId(deviceName); } if (!this.plugin.settings.autoSync) { await peer.rpc.autoSync(this.plugin.settings.autoSync); } if (this.plugin.settings.autoSync) { await this.sync(); } else { this.notifyStatus(NotifyType.AUTO_SYNC_DISABLED); } }); this.anysocket.on("message", (packet) => { switch (packet.msg.type) { case "file_data": this.onFileData(packet.msg.data, packet.peer); break; case "sync_complete": this.onSyncCompleted(packet.peer); break; } }); this.anysocket.on("reload", this.reload.bind(this)); this.anysocket.on("unload", this.unload.bind(this)); this.anysocket.on("disconnected", () => { this.notifyStatus(NotifyType.CONNECTION_LOST); this.debug && console.log("disconnected"); }); this.anysocket.init(); } unload() { clearTimeout(this.reloadTimeout); if (this.inited == false) return; this.inited = false; this.unregisterEvent("create"); this.unregisterEvent("modify"); this.unregisterEvent("delete"); this.unregisterEvent("rename"); app.workspace.offref(this.eventRefs["active-leaf-change"]); app.workspace.offref(this.eventRefs["layout-change"]); this.anysocket.stop(); this.anysocket.removeAllListeners(); } reload() { this.debug && console.log("reloaded"); this.unload(); this.reloadTimeout = setTimeout(() => { this.load(); }, 1e3); } async onFileData(data, peer) { this.debug && console.log("FileData:", data); if (!this.plugin.settings.autoSync && !this.isSyncing) { return; } if (data.type == "send") { let isBinary = Utils_default.isBinary(data.path); this.anysocket.send({ type: "file_data", data: { type: "apply", binary: isBinary, data: isBinary ? import_AnySocket.default.Packer.pack(await this.storage.readBinary(data.path)) : await this.storage.read(data.path), path: data.path, metadata: await this.storage.readMetadata(data.path) } }); } else if (data.type == "apply") { switch (data.metadata.action) { case "created": if (data.metadata.type == "folder") { await this.storage.makeFolder(data.path, data.metadata); } else { if (data.binary) { await this.storage.writeBinary(data.path, import_AnySocket.default.Packer.unpack(data.data), data.metadata); } else { await this.storage.write(data.path, data.data, data.metadata); } } break; case "deleted": await this.storage.delete(data.path, data.metadata); break; } } return true; } async getMetadata(action, file, itemTime) { let isBinary = Utils_default.isBinary(file.path); let typeToAction = { "sync": "created", "restore": "created", "create": "created", "modify": "created", "rename": "created", "delete": "deleted" }; let itemType; let itemData; if (action == "restore") { itemData = file.data; itemType = "file"; } else { itemData = isBinary ? await this.storage.readBinary(file.path) : await this.storage.read(file.path); itemType = file.stat ? "file" : "folder"; } let metadata = { action: typeToAction[action], sha1: isBinary ? await Utils_default.getSHABinary(itemData) : await Utils_default.getSHA(itemData), mtime: itemTime || await this.anysocket.getTime(), type: itemType }; if (action == "restore") { return metadata; } let storedMetadata = await this.storage.readMetadata(file.path); if (storedMetadata && metadata.action == storedMetadata.action && metadata.sha1 == storedMetadata.sha1) { return { changed: false, metadata: storedMetadata }; } await this.storage.writeMetadata(file.path, metadata); return { changed: true, metadata }; } async getFolderMtime(file) { if (file.stat) { return file.stat.mtime; } if (file.children.length <= 0) { return false; } let hasValue = false; let minMtime = await this.anysocket.getTime(); for (let child of file.children) { let mtime = await this.getFolderMtime(child); if (mtime == false) { continue; } if (minMtime > mtime) { hasValue = true; minMtime = mtime; } } return hasValue ? minMtime : false; } makeStatusBarItem(statusbar) { this.statusBarItem = statusbar; let container = this.statusBarItem.createEl("span"); container.style.verticalAlign = "middle"; container.style.display = "inline-flex"; container.style.alignItems = "center"; this.statusBarIcon = container.createEl("span"); this.statusBarIcon.style.paddingRight = "4px"; this.statusBarIcon.style.color = STATUS_ERROR; this.statusBarIcon.innerHTML = this.plugin.getSVGIcon(); this.statusBarMessage = container.createEl("span"); } setStatusMessage(message, keep = false) { this.statusBarMessage.innerText = message; clearTimeout(this.timeoutStatusMessage); if (!keep) { this.timeoutStatusMessage = setTimeout(() => { this.statusBarMessage.innerText = ""; }, 2e3); } } makeNotice(color, text) { let notice = new import_obsidian3.Notice().noticeEl; let container = notice.createEl("span"); container.style.verticalAlign = "middle"; container.style.display = "inline-flex"; container.style.alignItems = "center"; let icon = container.createEl("span"); icon.style.paddingRight = "4px"; icon.style.color = color; icon.innerHTML = this.plugin.getSVGIcon(); container.createEl("span", { text }); } notifyStatus(type) { switch (type) { case NotifyType.PLUGIN_DISABLED: if (this.settings.notifications > 0) { this.makeNotice(STATUS_ERROR, NotifyType.PLUGIN_DISABLED); } this.statusBarIcon.style.color = STATUS_ERROR; this.setStatusMessage(NotifyType.PLUGIN_DISABLED, false); break; case NotifyType.NOT_CONNECTED: if (this.plugin.settings.notifications > 0) { this.makeNotice(STATUS_ERROR, NotifyType.NOT_CONNECTED); } this.statusBarIcon.style.color = STATUS_ERROR; this.setStatusMessage(NotifyType.NOT_CONNECTED, false); break; case NotifyType.SYNCING: if (this.plugin.settings.notifications > 1) { this.makeNotice(STATUS_SYNC, NotifyType.SYNCING); } this.statusBarIcon.style.color = STATUS_SYNC; this.setStatusMessage(NotifyType.SYNCING, true); break; case NotifyType.SYNC_COMPLETED: if (this.plugin.settings.notifications > 1) { this.makeNotice(STATUS_OK, NotifyType.SYNC_COMPLETED); } this.statusBarIcon.style.color = STATUS_OK; this.setStatusMessage(NotifyType.SYNC_COMPLETED, false); break; case NotifyType.AUTO_SYNC_DISABLED: if (this.plugin.settings.notifications > 1) { this.makeNotice(STATUS_WARN, NotifyType.AUTO_SYNC_DISABLED); } this.statusBarIcon.style.color = STATUS_WARN; this.setStatusMessage(NotifyType.AUTO_SYNC_DISABLED, false); break; case NotifyType.CONNECTION_LOST: if (this.plugin.settings.notifications > 0) { this.makeNotice(STATUS_ERROR, NotifyType.CONNECTION_LOST); } this.statusBarIcon.style.color = STATUS_ERROR; this.setStatusMessage(NotifyType.CONNECTION_LOST, false); break; case NotifyType.CONNECTED: if (this.plugin.settings.notifications > 0) { this.makeNotice(STATUS_OK, NotifyType.CONNECTED); } this.statusBarIcon.style.color = STATUS_OK; this.setStatusMessage(NotifyType.CONNECTED, false); break; } } }; // src/libs/modals/VersionHistoryModal.ts var import_obsidian4 = require("obsidian"); var VersionHistoryModal = class extends import_obsidian4.Modal { constructor(plugin, path) { super(app); this.plugin = plugin; this.path = path; this.name = "Unknown"; this.versions = []; this.type = "created"; this.open(); this.setup(); } setup() { this.modalEl.addClass("anysocket-version-history"); this.elList = this.contentEl.createDiv("history-list"); this.elContainer = this.contentEl.createDiv("version-container"); let elContent = this.elContainer.createDiv("version-content"); let elTitle = elContent.createDiv("version-titlebar"); this.backButton = elTitle.createEl("button", { text: "Back", onclick: this.onBack.bind(this) }); if (!this.app.isMobile) { this.backButton.hide(); } let parts = this.path.split("/"); this.name = parts[parts.length - 1]; let fileName = elTitle.createDiv("version-filename").textContent = ""; this.titleEl.setText(this.name); window._x = this.modalEl; let actions = elTitle.createDiv("version-actions"); this.buttonRestore = actions.createEl("button", { text: "Restore", onclick: this.onRestore.bind(this) }); this.buttonRestore.disabled = true; let _originalContentEl = this.contentEl; this.contentEl = elContent; this.markdownView = new import_obsidian4.MarkdownPreviewView(this); this.contentEl = _originalContentEl; if (this.app.isMobile) { this.elContainer.hide(); } this.plugin.xSync.listVersionHistory(this.path, (data) => { this.versions = []; if (data && data.data.length <= 0) { return; } if (data.deleted) { this.type = "deleted"; } for (let timestamp of data.data) { let item = this.elList.createDiv("version-timestamp"); let versionItem = { timestamp, el: item }; item.textContent = this.formatTimestamp(timestamp); item.onclick = () => { this.internalItemSelect(versionItem); }; this.versions.push(versionItem); } if (!this.app.isMobile) { this.internalItemSelect(this.versions[0]); } }); } formatTimestamp(timestamp) { let date = new Date(timestamp); let month = date.getMonth() + 1; let day = date.getDate(); let year = date.getFullYear(); let hours = date.getHours(); let minutes = date.getMinutes(); let ampm = hours >= 12 ? "PM" : "AM"; hours = hours % 12; hours = hours ? hours : 12; minutes = minutes < 10 ? "0" + minutes : minutes; return `${month}/${day}/${year} ${hours}:${minutes} ${ampm}`; } internalItemSelect(item) { this.versions.map((v) => v.el.removeClass("active")); item.el.addClass("active"); this.plugin.xSync.readVersionHistory(this.path, item.timestamp, (data) => { if (typeof data !== "string") { data = ""; } this.markdownView.set(data, true); this.markdownView.applyScroll(0); }); this.selectedVersion = item; this.buttonRestore.textContent = "Restore"; this.buttonRestore.disabled = false; if (this.type == "created") { if (this.selectedVersion.timestamp == this.versions[0].timestamp) { this.buttonRestore.textContent = "Current"; this.buttonRestore.disabled = true; } else { this.buttonRestore.textContent = "Restore"; this.buttonRestore.disabled = false; } } if (this.app.isMobile) { this.elContainer.show(); this.backButton.show(); this.elList.hide(); } } async onBack() { if (this.app.isMobile) { this.elContainer.hide(); this.backButton.hide(); this.elList.show(); } } async onRestore() { let data = this.markdownView.get(); let metadata = await this.plugin.xSync.getMetadata("restore", { path: this.path, data }); metadata.sha1 = null; await this.plugin.xSync.storage.write(this.path, data, metadata); new import_obsidian4.Notice("Restored - " + this.name + " (" + this.formatTimestamp(this.selectedVersion.timestamp) + ")"); this.close(); } }; // src/main.ts var import_os = require("os"); // src/libs/modals/FilesHistoryModal.ts var import_obsidian5 = require("obsidian"); var import_AnySocket2 = __toESM(require_AnySocket()); var FilesHistoryModal = class extends import_obsidian5.SuggestModal { constructor(plugin, deletedOnly = false) { super(app); this.plugin = plugin; this.data = []; this.deletedOnly = deletedOnly; if (this.deletedOnly) { this.setPlaceholder("Search for deleted files..."); } else { this.setPlaceholder("Search for files..."); } this.plugin.xSync.listFilesHistory(this.deletedOnly, (data) => { this.data = data; this.open(); }); this.containerEl.addClass("anysocket-files-history"); } getSuggestions(query) { return this.data.filter((item) => item.path.toLowerCase().includes(query.toLowerCase())); } async onChooseSuggestion(item, evt) { if (Utils_default.isBinary(item.path)) { let parts = item.path.split("/"); await this.plugin.xSync.listVersionHistory(item.path, async (data) => { await this.plugin.xSync.readVersionHistory(item.path, data.data[0], async (data2) => { data2 = import_AnySocket2.default.Packer.unpack(data2); let metadata = await this.plugin.xSync.getMetadata("restore", { path: item.path, data: data2 }); metadata.sha1 = null; await this.plugin.xSync.storage.writeBinary(item.path, data2, metadata); new import_obsidian5.Notice("Restored - " + parts[parts.length - 1]); }); }); } else { new VersionHistoryModal(this.plugin, item.path); } } renderSuggestion(value, el) { el.createEl("div", { text: value.path }).addClass("item-path"); let prefix = "Modified: "; if (this.deletedOnly) { prefix = "Deleted: "; } el.createEl("div", { text: prefix + this.formatTimestamp(value.mtime) }).addClass("item-metadata"); } formatTimestamp(timestamp) { let date = new Date(timestamp); let month = date.getMonth() + 1; let day = date.getDate(); let year = date.getFullYear(); let hours = date.getHours(); let minutes = date.getMinutes(); let ampm = hours >= 12 ? "PM" : "AM"; hours = hours % 12; hours = hours ? hours : 12; minutes = minutes < 10 ? "0" + minutes : minutes; return `${month}/${day}/${year} ${hours}:${minutes} ${ampm}`; } }; // src/main.ts var import_ua_parser_js = __toESM(require_ua_parser()); var deviceInfo = new import_ua_parser_js.UAParser(navigator.userAgent).getDevice(); function getDefaultDeviceName() { return import_obsidian6.Platform.isDesktop ? (0, import_os.hostname)() : deviceInfo.model || "Unknown"; } var DEFAULT_SETTINGS = { host: "127.0.0.1", port: "3000", password: "", syncEnabled: false, delayedSync: 3, autoSync: true, notifications: 1, deviceName: getDefaultDeviceName(), debug: false }; var AnySocketSyncPlugin = class extends import_obsidian6.Plugin { constructor() { super(...arguments); this.VERSION = "1.3.3"; this.BUILD = "1730812576031"; this.isReady = false; } async onload() { await this.loadSettings(); this.registerEvent(this.app.workspace.on("file-menu", (menu, file) => { if (!file.stat) { return; } if (!Utils_default.isBinary(file.path)) { menu.addItem((item) => { item.setTitle("Version history").setIcon("history").onClick(async () => { new VersionHistoryModal(this, file.path); }); }); } menu.addItem((item) => { item.setTitle("Deleted files history").setIcon("history").onClick(async () => { new FilesHistoryModal(this, true); }); }); })); this.addCommand({ id: "files-version-history", name: "Version history", callback: async () => { new FilesHistoryModal(this, false); } }); this.addCommand({ id: "sync-now", name: "Sync Now", callback: async () => { await this.xSync.sync(); } }); this.addCommand({ id: "deleted-version-history", name: "Deleted files history", callback: async () => { new FilesHistoryModal(this, true); } }); this.addSettingTab(new AnySocketSyncSettingTab(this)); this.xSync = new XSync2(this); this.xSync.makeStatusBarItem(this.addStatusBarItem()); if (!app.workspace.layoutReady) { this.registerEvent(this.app.workspace.on("layout-ready", async () => { await this.ready(); })); } else { await this.ready(); } } async ready() { this.isReady = true; await this.xSync.enabled(true); } async onunload() { await this.xSync.enabled(false); } async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); } async saveSettings() { await this.saveData(this.settings); this.xSync.reload(); } getSVGIcon() { return ''; } }; var AnySocketSyncSettingTab = class extends import_obsidian6.PluginSettingTab { constructor(plugin) { super(app, plugin); this.plugin = plugin; } display() { const { containerEl } = this; containerEl.empty(); new import_obsidian6.Setting(containerEl).setName("Connection settings").setHeading(); new import_obsidian6.Setting(containerEl).setName("Device name").addText((text) => text.setPlaceholder(getDefaultDeviceName()).setValue(this.plugin.settings.deviceName).onChange(async (value) => { if (value == "") { value = getDefaultDeviceName(); } this.plugin.settings.deviceName = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName("Host").addText((text) => text.setPlaceholder("127.0.0.1").setValue(this.plugin.settings.host).onChange(async (value) => { this.plugin.settings.host = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName("Port").addText((text) => text.setPlaceholder("3000").setValue(this.plugin.settings.port).onChange(async (value) => { this.plugin.settings.port = value; await this.plugin.saveSettings(); })); new import_obsidian6.Setting(containerEl).setName("Password").addText((text) => { text.setPlaceholder("pass").setValue(this.plugin.settings.password).onChange(async (value) => { this.plugin.settings.password = value; await this.plugin.saveSettings(); }); text.inputEl.type = "password"; }); new import_obsidian6.Setting(containerEl).setName("Enable Connection").addToggle((toggle) => { toggle.setValue(this.plugin.settings.syncEnabled).onChange(async (value) => { this.plugin.settings.syncEnabled = value; await this.plugin.saveSettings(); }); }); new import_obsidian6.Setting(containerEl).setName("Sync settings").setHeading(); new import_obsidian6.Setting(containerEl).setName("Delayed Sync").setDesc("Delay sync until no changes for the specified duration (or focus changed)").addDropdown((dropdown) => { dropdown.addOption("0", "Instant"); dropdown.addOption("3", "3s"); dropdown.addOption("4", "4s"); dropdown.addOption("5", "5s"); dropdown.addOption("10", "10s"); dropdown.addOption("15", "15s"); dropdown.addOption("20", "20s"); dropdown.addOption("25", "25s"); dropdown.addOption("30", "30s"); dropdown.addOption("60", "1m"); dropdown.addOption("300", "5m"); dropdown.addOption("600", "10m"); dropdown.addOption("900", "15m"); dropdown.setValue(this.plugin.settings.delayedSync.toString()).onChange(async (value) => { this.plugin.settings.delayedSync = parseInt(value); await this.plugin.saveSettings(); }); }); new import_obsidian6.Setting(containerEl).setName("Auto Sync").setDesc("Automatically sync when local/remote changes are detected").addToggle((toggle) => { toggle.setValue(this.plugin.settings.autoSync).onChange(async (value) => { this.plugin.settings.autoSync = value; await this.plugin.saveSettings(); }); }); new import_obsidian6.Setting(containerEl).setName("Notifications").addDropdown((dropdown) => { dropdown.addOption("0", "Off"); dropdown.addOption("1", "Connection status"); dropdown.addOption("2", "Connection & sync status"); dropdown.setValue(this.plugin.settings.notifications.toString()).onChange(async (value) => { this.plugin.settings.notifications = parseInt(value); await this.plugin.saveSettings(); }); }); new import_obsidian6.Setting(containerEl).setName("Debug").addToggle((toggle) => toggle.setValue(this.plugin.settings.debug).onChange(async (value) => { this.plugin.settings.debug = value; await this.plugin.saveSettings(); })); } }; /* nosourcemap */