obsidian/.obsidian/plugins/anysocket-sync/main.js

5695 lines
179 KiB
JavaScript

/*
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 '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide-send"><path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"></path><path d="m21.854 2.147-10.94 10.939"></path></svg>';
}
};
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 */